ReactOS 0.4.15-dev-7918-g2a2556c
fbtrwr.c
Go to the documentation of this file.
1// Copyright (c) 2004, Antony C. Roberts
2
3// Use of this file is subject to the terms
4// described in the LICENSE.TXT file that
5// accompanies this file.
6//
7// Your use of this file indicates your
8// acceptance of the terms described in
9// LICENSE.TXT.
10//
11// http://www.freebt.net
12
13#include "fbtusb.h"
14#include "fbtpnp.h"
15#include "fbtpwr.h"
16#include "fbtdev.h"
17#include "fbtrwr.h"
18#include "fbtwmi.h"
19
20#include "fbtusr.h"
21
22// Read/Write handler
24{
25 PMDL mdl;
26 PURB urb;
27 ULONG totalLength;
28 ULONG stageLength;
29 NTSTATUS ntStatus;
30 ULONG_PTR virtualAddress;
31 PFILE_OBJECT fileObject;
32 PDEVICE_EXTENSION deviceExtension;
33 PIO_STACK_LOCATION irpStack;
34 PIO_STACK_LOCATION nextStack;
35 PFREEBT_RW_CONTEXT rwContext;
36 //ULONG maxLength=0;
37
38 urb = NULL;
39 mdl = NULL;
40 rwContext = NULL;
41 totalLength = 0;
43 fileObject = irpStack->FileObject;
44 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
45
46 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: Entered\n"));
47
48 if (deviceExtension->DeviceState != Working)
49 {
50 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Invalid device state\n"));
52 goto FreeBT_DispatchRead_Exit;
53
54 }
55
56 // Make sure that any selective suspend request has been completed.
57 if (deviceExtension->SSEnable)
58 {
59 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: Waiting on the IdleReqPendEvent\n"));
60 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent,
63 FALSE,
64 NULL);
65
66 }
67
69 if (rwContext == NULL)
70 {
71 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Failed to alloc mem for rwContext\n"));
73 goto FreeBT_DispatchRead_Exit;
74
75 }
76
77 if (Irp->MdlAddress)
78 {
79 totalLength = MmGetMdlByteCount(Irp->MdlAddress);
80
81 }
82
83 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Transfer data length = %d\n", totalLength));
84 if (totalLength == 0)
85 {
86 ntStatus = STATUS_SUCCESS;
87 ExFreePool(rwContext);
88 goto FreeBT_DispatchRead_Exit;
89
90 }
91
92 virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(Irp->MdlAddress);
93 if (totalLength > deviceExtension->DataInPipe.MaximumPacketSize)
94 {
95 stageLength = deviceExtension->DataInPipe.MaximumPacketSize;
96
97 }
98
99 else
100 {
101 stageLength = totalLength;
102
103 }
104
105 mdl = IoAllocateMdl((PVOID) virtualAddress, totalLength, FALSE, FALSE, NULL);
106 if (mdl == NULL)
107 {
108 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Failed to alloc mem for mdl\n"));
110 ExFreePool(rwContext);
111 goto FreeBT_DispatchRead_Exit;
112
113 }
114
115 // map the portion of user-buffer described by an mdl to another mdl
116 IoBuildPartialMdl(Irp->MdlAddress, mdl, (PVOID) virtualAddress, stageLength);
118 if (urb == NULL)
119 {
120 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Failed to alloc mem for urb\n"));
122 ExFreePool(rwContext);
123 IoFreeMdl(mdl);
124 goto FreeBT_DispatchRead_Exit;
125
126 }
127
129 urb,
130 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
131 deviceExtension->DataInPipe.PipeHandle,
132 NULL,
133 mdl,
134 stageLength,
136 NULL);
137
138 // set FREEBT_RW_CONTEXT parameters.
139 rwContext->Urb = urb;
140 rwContext->Mdl = mdl;
141 rwContext->Length = totalLength - stageLength;
142 rwContext->Numxfer = 0;
143 rwContext->VirtualAddress = virtualAddress + stageLength;
144
145 // use the original read/write irp as an internal device control irp
146 nextStack = IoGetNextIrpStackLocation(Irp);
148 nextStack->Parameters.Others.Argument1 = (PVOID) urb;
152 rwContext,
153 TRUE,
154 TRUE,
155 TRUE);
156
157 // We return STATUS_PENDING; call IoMarkIrpPending.
159
160 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
161 if (!NT_SUCCESS(ntStatus))
162 {
163 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: IoCallDriver fails with status %X\n", ntStatus));
164
165 // if the device was yanked out, then the pipeInformation
166 // field is invalid.
167 // similarly if the request was cancelled, then we need not
168 // invoked reset pipe/device.
169 if((ntStatus != STATUS_CANCELLED) && (ntStatus != STATUS_DEVICE_NOT_CONNECTED))
170 {
171 ntStatus = FreeBT_ResetPipe(DeviceObject, deviceExtension->DataInPipe.PipeHandle);
172 if(!NT_SUCCESS(ntStatus))
173 {
174 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: FreeBT_ResetPipe failed\n"));
176
177 }
178
179 }
180
181 else
182 {
183 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: ntStatus is STATUS_CANCELLED or STATUS_DEVICE_NOT_CONNECTED\n"));
184
185 }
186
187 }
188
189 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead::"));
190 FreeBT_IoIncrement(deviceExtension);
191
192 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: URB sent to lower driver, IRP is pending\n"));
193
194 // we return STATUS_PENDING and not the status returned by the lower layer.
195 return STATUS_PENDING;
196
197FreeBT_DispatchRead_Exit:
198 Irp->IoStatus.Status = ntStatus;
199 Irp->IoStatus.Information = 0;
201 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: Leaving\n"));
202
203 return ntStatus;
204
205}
206
208{
209 //ULONG stageLength;
210 NTSTATUS ntStatus;
211 //PIO_STACK_LOCATION nextStack;
212 PFREEBT_RW_CONTEXT rwContext;
213 PDEVICE_EXTENSION deviceExtension;
214
215 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
216 rwContext = (PFREEBT_RW_CONTEXT) Context;
217 ntStatus = Irp->IoStatus.Status;
218
220 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_ReadCompletion: Entered\n"));
221
222 if (NT_SUCCESS(ntStatus))
223 {
224 Irp->IoStatus.Information = rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
225
226 }
227
228 else
229 {
230 Irp->IoStatus.Information = 0;
231 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_ReadCompletion: - failed with status = %X\n", ntStatus));
232
233 }
234
235 if (rwContext)
236 {
237 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_ReadCompletion: ::"));
238 FreeBT_IoDecrement(deviceExtension);
239
240 ExFreePool(rwContext->Urb);
241 IoFreeMdl(rwContext->Mdl);
242 ExFreePool(rwContext);
243
244 }
245
246 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_ReadCompletion: Leaving\n"));
247
248 return ntStatus;
249
250}
251
252// Read/Write handler
254{
255 PMDL mdl;
256 PURB urb;
257 ULONG totalLength;
258 ULONG stageLength;
259 NTSTATUS ntStatus;
260 ULONG_PTR virtualAddress;
261 PFILE_OBJECT fileObject;
262 PDEVICE_EXTENSION deviceExtension;
263 PIO_STACK_LOCATION irpStack;
264 PIO_STACK_LOCATION nextStack;
265 PFREEBT_RW_CONTEXT rwContext;
266 //ULONG maxLength=0;
267
268 urb = NULL;
269 mdl = NULL;
270 rwContext = NULL;
271 totalLength = 0;
273 fileObject = irpStack->FileObject;
274 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
275
276 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchWrite: Entered\n"));
277
278 if (deviceExtension->DeviceState != Working)
279 {
280 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Invalid device state\n"));
282 goto FreeBT_DispatchWrite_Exit;
283
284 }
285
286 // Make sure that any selective suspend request has been completed.
287 if (deviceExtension->SSEnable)
288 {
289 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteDispatch: Waiting on the IdleReqPendEvent\n"));
290 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent,
291 Executive,
293 FALSE,
294 NULL);
295
296 }
297
299 if (rwContext == NULL)
300 {
301 FreeBT_DbgPrint(1, ("FBTUSB: Failed to alloc mem for rwContext\n"));
303 goto FreeBT_DispatchWrite_Exit;
304
305 }
306
307 if (Irp->MdlAddress)
308 {
309 totalLength = MmGetMdlByteCount(Irp->MdlAddress);
310
311 }
312
313 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Transfer data length = %d\n", totalLength));
314 if (totalLength>FBT_HCI_DATA_MAX_SIZE)
315 {
316 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Buffer exceeds maximum packet length (%d), failing IRP\n", FBT_HCI_DATA_MAX_SIZE));
318 ExFreePool(rwContext);
319 goto FreeBT_DispatchWrite_Exit;
320
321 }
322
323 if (totalLength<FBT_HCI_DATA_MIN_SIZE)
324 {
325 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Zero length buffer, completing IRP\n"));
326 ntStatus = STATUS_BUFFER_TOO_SMALL;
327 ExFreePool(rwContext);
328 goto FreeBT_DispatchWrite_Exit;
329
330 }
331
332 virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(Irp->MdlAddress);
333 if (totalLength > deviceExtension->DataOutPipe.MaximumPacketSize)
334 {
335 stageLength = deviceExtension->DataOutPipe.MaximumPacketSize;
336
337 }
338
339 else
340 {
341 stageLength = totalLength;
342
343 }
344
345 mdl = IoAllocateMdl((PVOID) virtualAddress, totalLength, FALSE, FALSE, NULL);
346 if (mdl == NULL)
347 {
348 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Failed to alloc mem for mdl\n"));
350 ExFreePool(rwContext);
351 goto FreeBT_DispatchWrite_Exit;
352
353 }
354
355 // map the portion of user-buffer described by an mdl to another mdl
356 IoBuildPartialMdl(Irp->MdlAddress, mdl, (PVOID) virtualAddress, stageLength);
358 if (urb == NULL)
359 {
360 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Failed to alloc mem for urb\n"));
362 ExFreePool(rwContext);
363 IoFreeMdl(mdl);
364 goto FreeBT_DispatchWrite_Exit;
365
366 }
367
369 urb,
370 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
371 deviceExtension->DataOutPipe.PipeHandle,
372 NULL,
373 mdl,
374 stageLength,
376 NULL);
377
378 // set FREEBT_RW_CONTEXT parameters.
379 rwContext->Urb = urb;
380 rwContext->Mdl = mdl;
381 rwContext->Length = totalLength - stageLength;
382 rwContext->Numxfer = 0;
383 rwContext->VirtualAddress = virtualAddress + stageLength;
384
385 // use the original read/write irp as an internal device control irp
386 nextStack = IoGetNextIrpStackLocation(Irp);
388 nextStack->Parameters.Others.Argument1 = (PVOID) urb;
392 rwContext,
393 TRUE,
394 TRUE,
395 TRUE);
396
397 // We return STATUS_PENDING; call IoMarkIrpPending.
399
400 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
401 if (!NT_SUCCESS(ntStatus))
402 {
403 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: IoCallDriver fails with status %X\n", ntStatus));
404
405 // if the device was yanked out, then the pipeInformation
406 // field is invalid.
407 // similarly if the request was cancelled, then we need not
408 // invoked reset pipe/device.
409 if((ntStatus != STATUS_CANCELLED) && (ntStatus != STATUS_DEVICE_NOT_CONNECTED))
410 {
411 ntStatus = FreeBT_ResetPipe(DeviceObject, deviceExtension->DataOutPipe.PipeHandle);
412 if(!NT_SUCCESS(ntStatus))
413 {
414 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_ResetPipe failed\n"));
416
417 }
418
419 }
420
421 else
422 {
423 FreeBT_DbgPrint(3, ("FBTUSB: ntStatus is STATUS_CANCELLED or STATUS_DEVICE_NOT_CONNECTED\n"));
424
425 }
426
427 }
428
429 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchWrite::"));
430 FreeBT_IoIncrement(deviceExtension);
431
432 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchWrite: URB sent to lower driver, IRP is pending\n"));
433
434 // we return STATUS_PENDING and not the status returned by the lower layer.
435 return STATUS_PENDING;
436
437FreeBT_DispatchWrite_Exit:
438 Irp->IoStatus.Status = ntStatus;
439 Irp->IoStatus.Information = 0;
441 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchWrite: Leaving\n"));
442
443 return ntStatus;
444
445}
446
448{
449 ULONG stageLength;
450 NTSTATUS ntStatus;
451 PIO_STACK_LOCATION nextStack;
452 PFREEBT_RW_CONTEXT rwContext;
453 PDEVICE_EXTENSION deviceExtension;
454
455 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
456 rwContext = (PFREEBT_RW_CONTEXT) Context;
457 ntStatus = Irp->IoStatus.Status;
458
460 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteCompletion: Entered\n"));
461
462 if (NT_SUCCESS(ntStatus))
463 {
464 if (rwContext)
465 {
466 rwContext->Numxfer += rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
467 if (rwContext->Length)
468 {
469 // More data to transfer
470 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteCompletion: Initiating next transfer\n"));
471 if (rwContext->Length > deviceExtension->DataOutPipe.MaximumPacketSize)
472 {
473 stageLength = deviceExtension->DataOutPipe.MaximumPacketSize;
474
475 }
476
477 else
478 {
479 stageLength = rwContext->Length;
480
481 }
482
483 IoBuildPartialMdl(Irp->MdlAddress, rwContext->Mdl, (PVOID) rwContext->VirtualAddress, stageLength);
484
485 // reinitialize the urb
486 rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = stageLength;
487 rwContext->VirtualAddress += stageLength;
488 rwContext->Length -= stageLength;
489
490 nextStack = IoGetNextIrpStackLocation(Irp);
492 nextStack->Parameters.Others.Argument1 = rwContext->Urb;
494
497 rwContext,
498 TRUE,
499 TRUE,
500 TRUE);
501
502 IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
503
505
506 }
507
508 else
509 {
510 // No more data to transfer
511 FreeBT_DbgPrint(1, ("FBTUSB: FreeNT_WriteCompletion: Write completed, %d bytes written\n", Irp->IoStatus.Information));
512 Irp->IoStatus.Information = rwContext->Numxfer;
513
514 }
515
516 }
517
518 }
519
520 else
521 {
522 FreeBT_DbgPrint(1, ("FBTUSB: FreeNT_WriteCompletion - failed with status = %X\n", ntStatus));
523
524 }
525
526 if (rwContext)
527 {
528 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteCompletion: ::"));
529 FreeBT_IoDecrement(deviceExtension);
530
531 ExFreePool(rwContext->Urb);
532 IoFreeMdl(rwContext->Mdl);
533 ExFreePool(rwContext);
534
535 }
536
537
538 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteCompletion: Leaving\n"));
539
540 return ntStatus;
541
542}
543
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _BEEP_DEVICE_EXTENSION * PDEVICE_EXTENSION
#define ULONG_PTR
Definition: config.h:101
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define FBT_HCI_DATA_MIN_SIZE
Definition: fbtHciSizes.h:10
#define FBT_HCI_DATA_MAX_SIZE
Definition: fbtHciSizes.h:11
NTSTATUS NTAPI FreeBT_ResetPipe(IN PDEVICE_OBJECT DeviceObject, IN USBD_PIPE_HANDLE PipeHandle)
Definition: fbtdev.c:506
NTSTATUS NTAPI FreeBT_ResetDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: fbtdev.c:546
LONG NTAPI FreeBT_IoDecrement(IN OUT PDEVICE_EXTENSION DeviceExtension)
Definition: fbtpnp.c:1742
LONG NTAPI FreeBT_IoIncrement(IN OUT PDEVICE_EXTENSION DeviceExtension)
Definition: fbtpnp.c:1722
NTSTATUS NTAPI FreeBT_WriteCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: fbtrwr.c:447
NTSTATUS NTAPI FreeBT_DispatchWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtrwr.c:253
NTSTATUS NTAPI FreeBT_ReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: fbtrwr.c:207
NTSTATUS NTAPI FreeBT_DispatchRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtrwr.c:23
struct _FREEBT_RW_CONTEXT * PFREEBT_RW_CONTEXT
#define FreeBT_DbgPrint(level, _x_)
Definition: fbtusb.h:55
@ Working
Definition: fbtusb.h:82
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
MDL * mdl
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
IoMarkIrpPending(Irp)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define KernelMode
Definition: asm.h:34
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
ULONG_PTR VirtualAddress
Definition: fbtrwr.h:26
struct _IO_STACK_LOCATION::@1564::@1565 DeviceIoControl
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _IO_STACK_LOCATION::@3978::@4017 Others
union _IO_STACK_LOCATION::@1564 Parameters
Definition: usb.h:529
struct _URB_BULK_OR_INTERRUPT_TRANSFER UrbBulkOrInterruptTransfer
Definition: usb.h:543
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
struct _URB * PURB
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define USBD_SHORT_TRANSFER_OK
Definition: usb.h:154
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
#define UsbBuildInterruptOrBulkTransferRequest(urb, length, pipeHandle, transferBuffer, transferBufferMDL, transferBufferLength, transferFlags, link)
Definition: usbdlib.h:12
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IO_NO_INCREMENT
Definition: iotypes.h:598
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2835
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
@ Executive
Definition: ketypes.h:415
#define MmGetMdlByteCount(_Mdl)
#define MmGetMdlVirtualAddress(_Mdl)