| 224 | } |
| 225 | |
| 226 | NTSTATUS GetDataFromIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION stack, IrpMajorCode code, PVOID buffer, ULONG size, bool output) { |
| 227 | __try { |
| 228 | switch (code) { |
| 229 | case IrpMajorCode::READ: |
| 230 | case IrpMajorCode::WRITE: |
| 231 | if (Irp->MdlAddress) { |
| 232 | auto p = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); |
| 233 | if (p) { |
| 234 | ::memcpy(buffer, p, size); |
| 235 | return STATUS_SUCCESS; |
| 236 | } |
| 237 | return STATUS_INSUFFICIENT_RESOURCES; |
| 238 | } |
| 239 | if (DeviceObject->Flags & DO_BUFFERED_IO) { |
| 240 | if (!Irp->AssociatedIrp.SystemBuffer) { |
| 241 | return STATUS_INVALID_PARAMETER; |
| 242 | } |
| 243 | ::memcpy(buffer, Irp->AssociatedIrp.SystemBuffer, size); |
| 244 | return STATUS_SUCCESS; |
| 245 | } |
| 246 | if (!Irp->UserBuffer) { |
| 247 | return STATUS_INVALID_PARAMETER; |
| 248 | } |
| 249 | ::memcpy(buffer, Irp->UserBuffer, size); |
| 250 | return STATUS_SUCCESS; |
| 251 | |
| 252 | case IrpMajorCode::DEVICE_CONTROL: |
| 253 | case IrpMajorCode::INTERNAL_DEVICE_CONTROL: |
| 254 | auto controlCode = stack->Parameters.DeviceIoControl.IoControlCode; |
| 255 | if (METHOD_FROM_CTL_CODE(controlCode) == METHOD_NEITHER) { |
| 256 | if (stack->Parameters.DeviceIoControl.Type3InputBuffer < (PVOID)(1 << 16)) { |
| 257 | ::memcpy(buffer, stack->Parameters.DeviceIoControl.Type3InputBuffer, size); |
| 258 | } |
| 259 | else { |
| 260 | return STATUS_UNSUCCESSFUL; |
| 261 | } |
| 262 | } |
| 263 | else { |
| 264 | if (!output || METHOD_FROM_CTL_CODE(controlCode) == METHOD_BUFFERED) { |
| 265 | if (!Irp->AssociatedIrp.SystemBuffer) { |
| 266 | return STATUS_INVALID_PARAMETER; |
| 267 | } |
| 268 | ::memcpy(buffer, Irp->AssociatedIrp.SystemBuffer, size); |
| 269 | } |
| 270 | else { |
| 271 | if (!Irp->MdlAddress) { |
| 272 | return STATUS_INVALID_PARAMETER; |
| 273 | } |
| 274 | auto data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); |
| 275 | if (data) { |
| 276 | ::memcpy(buffer, data, size); |
| 277 | } |
| 278 | else { |
| 279 | return STATUS_UNSUCCESSFUL; |
| 280 | } |
| 281 | } |
| 282 | } |
| 283 | return STATUS_SUCCESS; |
no outgoing calls
no test coverage detected