Sync with trunk r63270.
[reactos.git] / drivers / hid / hidclass / hidclass.c
index 39c31c4..3011482 100644 (file)
 
 #include "precomp.h"
 
+#define NDEBUG
+#include <debug.h>
+
 static LPWSTR ClientIdentificationAddress = L"HIDCLASS";
 static ULONG HidClassDeviceNumber = 0;
 
-ULONG
+NTSTATUS
 NTAPI
-DllInitialize(ULONG Unknown)
+DllInitialize(
+    IN PUNICODE_STRING RegistryPath)
 {
-    return 0;
+    return STATUS_SUCCESS;
 }
 
-ULONG
+NTSTATUS
 NTAPI
-DllUnload()
+DllUnload(VOID)
 {
-    return 0;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -41,7 +45,6 @@ HidClassAddDevice(
     ULONG DeviceExtensionSize;
     PHIDCLASS_DRIVER_EXTENSION DriverExtension;
 
-
     /* increment device number */
     InterlockedIncrement((PLONG)&HidClassDeviceNumber);
 
@@ -52,7 +55,7 @@ HidClassAddDevice(
     RtlInitUnicodeString(&DeviceName, CharDeviceName);
 
     /* get driver object extension */
-    DriverExtension = (PHIDCLASS_DRIVER_EXTENSION) IoGetDriverObjectExtension(DriverObject, ClientIdentificationAddress);
+    DriverExtension = IoGetDriverObjectExtension(DriverObject, ClientIdentificationAddress);
     if (!DriverExtension)
     {
         /* device removed */
@@ -73,7 +76,7 @@ HidClassAddDevice(
     }
 
     /* get device extension */
-    FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)NewDeviceObject->DeviceExtension;
+    FDODeviceExtension = NewDeviceObject->DeviceExtension;
 
     /* zero device extension */
     RtlZeroMemory(FDODeviceExtension, sizeof(HIDCLASS_FDO_EXTENSION));
@@ -140,7 +143,7 @@ HidClass_Create(
     //
     // get device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
     if (CommonDeviceExtension->IsFDO)
     {
 #ifndef __REACTOS__
@@ -170,21 +173,21 @@ HidClass_Create(
     //
     // get device extension
     //
-    PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)CommonDeviceExtension;
+    PDODeviceExtension = DeviceObject->DeviceExtension;
 
     //
     // get stack location
     //
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    DPRINT1("ShareAccess %x\n", IoStack->Parameters.Create.ShareAccess);
-    DPRINT1("Options %x\n", IoStack->Parameters.Create.Options);
-    DPRINT1("DesiredAccess %x\n", IoStack->Parameters.Create.SecurityContext->DesiredAccess);
+    DPRINT("ShareAccess %x\n", IoStack->Parameters.Create.ShareAccess);
+    DPRINT("Options %x\n", IoStack->Parameters.Create.Options);
+    DPRINT("DesiredAccess %x\n", IoStack->Parameters.Create.SecurityContext->DesiredAccess);
 
     //
     // allocate context
     //
-    Context = (PHIDCLASS_FILEOP_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(HIDCLASS_FILEOP_CONTEXT));
+    Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(HIDCLASS_FILEOP_CONTEXT), HIDCLASS_TAG);
     if (!Context)
     {
         //
@@ -203,12 +206,13 @@ HidClass_Create(
     KeInitializeSpinLock(&Context->Lock);
     InitializeListHead(&Context->ReadPendingIrpListHead);
     InitializeListHead(&Context->IrpCompletedListHead);
+    KeInitializeEvent(&Context->IrpReadComplete, NotificationEvent, FALSE);
 
     //
     // store context
     //
     ASSERT(IoStack->FileObject);
-    IoStack->FileObject->FsContext = (PVOID)Context;
+    IoStack->FileObject->FsContext = Context;
 
     //
     // done
@@ -226,12 +230,16 @@ HidClass_Close(
 {
     PIO_STACK_LOCATION IoStack;
     PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
-    PHIDCLASS_IRP_CONTEXT IrpContext;
+    PHIDCLASS_FILEOP_CONTEXT IrpContext;
+    BOOLEAN IsRequestPending = FALSE;
+    KIRQL OldLevel;
+    PLIST_ENTRY Entry;
+    PIRP ListIrp;
 
     //
     // get device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
 
     //
     // is it a FDO request
@@ -260,54 +268,93 @@ HidClass_Close(
     //
     // get irp context
     //
-    IrpContext = (PHIDCLASS_IRP_CONTEXT)IoStack->FileObject->FsContext;
+    IrpContext = IoStack->FileObject->FsContext;
+    ASSERT(IrpContext);
 
     //
-    // cancel pending irps
+    // acquire lock
     //
-    UNIMPLEMENTED
+    KeAcquireSpinLock(&IrpContext->Lock, &OldLevel);
+
+    if (!IsListEmpty(&IrpContext->ReadPendingIrpListHead))
+    {
+        //
+        // FIXME cancel irp
+        //
+        IsRequestPending = TRUE;
+    }
 
     //
-    // remove context
+    // signal stop
     //
-    IoStack->FileObject->FsContext = NULL;
+    IrpContext->StopInProgress = TRUE;
 
     //
-    // free context
+    // release lock
     //
-    ExFreePool(IrpContext);
+    KeReleaseSpinLock(&IrpContext->Lock, OldLevel);
+
+    if (IsRequestPending)
+    {
+        //
+        // wait for request to complete
+        //
+        DPRINT1("[HIDCLASS] Waiting for read irp completion...\n");
+        KeWaitForSingleObject(&IrpContext->IrpReadComplete, Executive, KernelMode, FALSE, NULL);
+    }
 
     //
-    // complete request
+    // acquire lock
     //
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return STATUS_SUCCESS;
-}
+    KeAcquireSpinLock(&IrpContext->Lock, &OldLevel);
 
-PVOID
-HidClass_GetSystemAddress(
-    IN PMDL ReportMDL)
-{
     //
     // sanity check
     //
-    ASSERT(ReportMDL);
+    ASSERT(IsListEmpty(&IrpContext->ReadPendingIrpListHead));
 
-    if (ReportMDL->MdlFlags & (MDL_SOURCE_IS_NONPAGED_POOL | MDL_MAPPED_TO_SYSTEM_VA))
-    {
-       //
-       // buffer is non paged pool
-       //
-       return ReportMDL->MappedSystemVa;
-    }
-    else
+    //
+    // now free all irps
+    //
+    while (!IsListEmpty(&IrpContext->IrpCompletedListHead))
     {
-       //
-       // map mdl
-       //
-       return MmMapLockedPages(ReportMDL, KernelMode);
+        //
+        // remove head irp
+        //
+        Entry = RemoveHeadList(&IrpContext->IrpCompletedListHead);
+
+        //
+        // get irp
+        //
+        ListIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
+
+        //
+        // free the irp
+        //
+        IoFreeIrp(ListIrp);
     }
+
+    //
+    // release lock
+    //
+    KeReleaseSpinLock(&IrpContext->Lock, OldLevel);
+
+    //
+    // remove context
+    //
+    IoStack->FileObject->FsContext = NULL;
+
+    //
+    // free context
+    //
+    ExFreePoolWithTag(IrpContext, HIDCLASS_TAG);
+
+    //
+    // complete request
+    //
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -323,11 +370,12 @@ HidClass_ReadCompleteIrp(
     ULONG Offset;
     PHIDP_COLLECTION_DESC CollectionDescription;
     PHIDP_REPORT_IDS ReportDescription;
+    BOOLEAN IsEmpty;
 
     //
     // get irp context
     //
-    IrpContext = (PHIDCLASS_IRP_CONTEXT)Ctx;
+    IrpContext = Ctx;
 
     DPRINT("HidClass_ReadCompleteIrp Irql %lu\n", KeGetCurrentIrql());
     DPRINT("HidClass_ReadCompleteIrp Status %lx\n", Irp->IoStatus.Status);
@@ -345,7 +393,7 @@ HidClass_ReadCompleteIrp(
         //
         // get address
         //
-        Address = (PUCHAR)HidClass_GetSystemAddress(IrpContext->OriginalIrp->MdlAddress);
+        Address = MmGetSystemAddressForMdlSafe(IrpContext->OriginalIrp->MdlAddress, NormalPagePriority);
         if (Address)
         {
             //
@@ -356,13 +404,15 @@ HidClass_ReadCompleteIrp(
             //
             // get collection description
             //
-            CollectionDescription = HidClassPDO_GetCollectionDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
+            CollectionDescription = HidClassPDO_GetCollectionDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription,
+                                                                         IrpContext->FileOp->DeviceExtension->CollectionNumber);
             ASSERT(CollectionDescription);
 
             //
             // get report description
             //
-            ReportDescription = HidClassPDO_GetReportDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
+            ReportDescription = HidClassPDO_GetReportDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription,
+                                                                 IrpContext->FileOp->DeviceExtension->CollectionNumber);
             ASSERT(ReportDescription);
 
             if (CollectionDescription && ReportDescription)
@@ -385,12 +435,12 @@ HidClass_ReadCompleteIrp(
     // copy result status
     //
     IrpContext->OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
-    Irp->IoStatus.Information = Irp->IoStatus.Information;
+    IrpContext->OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;
 
     //
     // free input report buffer
     //
-    ExFreePool(IrpContext->InputReportBuffer);
+    ExFreePoolWithTag(IrpContext->InputReportBuffer, HIDCLASS_TAG);
 
     //
     // remove us from pending list
@@ -402,6 +452,11 @@ HidClass_ReadCompleteIrp(
     //
     RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
 
+    //
+    // is list empty
+    //
+    IsEmpty = IsListEmpty(&IrpContext->FileOp->ReadPendingIrpListHead);
+
     //
     // insert into completed list
     //
@@ -417,10 +472,30 @@ HidClass_ReadCompleteIrp(
     //
     IoCompleteRequest(IrpContext->OriginalIrp, IO_NO_INCREMENT);
 
+
+    DPRINT("StopInProgress %x IsEmpty %x\n", IrpContext->FileOp->StopInProgress, IsEmpty);
+    if (IrpContext->FileOp->StopInProgress && IsEmpty)
+    {
+        //
+        // last pending irp
+        //
+        DPRINT1("[HIDCLASS] LastPendingTransfer Signalling\n");
+        KeSetEvent(&IrpContext->FileOp->IrpReadComplete, 0, FALSE);
+    }
+
+    if (IrpContext->FileOp->StopInProgress && IsEmpty)
+    {
+        //
+        // last pending irp
+        //
+        DPRINT1("[HIDCLASS] LastPendingTransfer Signalling\n");
+        KeSetEvent(&IrpContext->FileOp->IrpReadComplete, 0, FALSE);
+    }
+
     //
     // free irp context
     //
-    ExFreePool(IrpContext);
+    ExFreePoolWithTag(IrpContext, HIDCLASS_TAG);
 
     //
     // done
@@ -454,7 +529,7 @@ HidClass_GetIrp(
         //
         // get irp
         //
-        Irp = (PIRP)CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
+        Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
     }
 
     //
@@ -514,7 +589,7 @@ HidClass_BuildIrp(
     //
     // allocate completion context
     //
-    IrpContext = (PHIDCLASS_IRP_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(HIDCLASS_IRP_CONTEXT));
+    IrpContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(HIDCLASS_IRP_CONTEXT), HIDCLASS_TAG);
     if (!IrpContext)
     {
         //
@@ -527,7 +602,7 @@ HidClass_BuildIrp(
     //
     // get device extension
     //
-    PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    PDODeviceExtension = DeviceObject->DeviceExtension;
     ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
 
     //
@@ -540,13 +615,15 @@ HidClass_BuildIrp(
     //
     // get collection description
     //
-    CollectionDescription = HidClassPDO_GetCollectionDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
+    CollectionDescription = HidClassPDO_GetCollectionDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription,
+                                                                 IrpContext->FileOp->DeviceExtension->CollectionNumber);
     ASSERT(CollectionDescription);
 
     //
     // get report description
     //
-    ReportDescription = HidClassPDO_GetReportDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
+    ReportDescription = HidClassPDO_GetReportDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription,
+                                                         IrpContext->FileOp->DeviceExtension->CollectionNumber);
     ASSERT(ReportDescription);
 
     //
@@ -554,6 +631,18 @@ HidClass_BuildIrp(
     //
     ASSERT(CollectionDescription->InputLength >= ReportDescription->InputLength);
 
+    if (Context->StopInProgress)
+    {
+         //
+         // stop in progress
+         //
+         DPRINT1("[HIDCLASS] Stop In Progress\n");
+         Irp->IoStatus.Status = STATUS_CANCELLED;
+         IoCompleteRequest(Irp, IO_NO_INCREMENT);
+         return STATUS_CANCELLED;
+
+    }
+
     //
     // store report length
     //
@@ -562,14 +651,14 @@ HidClass_BuildIrp(
     //
     // allocate buffer
     //
-    IrpContext->InputReportBuffer = ExAllocatePool(NonPagedPool, IrpContext->InputReportBufferLength);
+    IrpContext->InputReportBuffer = ExAllocatePoolWithTag(NonPagedPool, IrpContext->InputReportBufferLength, HIDCLASS_TAG);
     if (!IrpContext->InputReportBuffer)
     {
         //
         // no memory
         //
         IoFreeIrp(Irp);
-        ExFreePool(IrpContext);
+        ExFreePoolWithTag(IrpContext, HIDCLASS_TAG);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -601,7 +690,6 @@ HidClass_BuildIrp(
     return STATUS_SUCCESS;
 }
 
-
 NTSTATUS
 NTAPI
 HidClass_Read(
@@ -624,7 +712,7 @@ HidClass_Read(
     //
     // get device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
     ASSERT(CommonDeviceExtension->IsFDO == FALSE);
 
     //
@@ -636,7 +724,7 @@ HidClass_Read(
     //
     // get context
     //
-    Context = (PHIDCLASS_FILEOP_CONTEXT)IoStack->FileObject->FsContext;
+    Context = IoStack->FileObject->FsContext;
     ASSERT(Context);
 
     //
@@ -644,10 +732,27 @@ HidClass_Read(
     //
     ASSERT(Context->DeviceExtension->Common.DriverExtension->DevicesArePolled == FALSE);
 
+    if (Context->StopInProgress)
+    {
+        //
+        // stop in progress
+        //
+        DPRINT1("[HIDCLASS] Stop In Progress\n");
+        Irp->IoStatus.Status = STATUS_CANCELLED;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_CANCELLED;
+    }
+
     //
     // build irp request
     //
-    Status = HidClass_BuildIrp(DeviceObject, Irp, Context, IOCTL_HID_READ_REPORT, IoStack->Parameters.Read.Length, &NewIrp, &NewIrpContext);
+    Status = HidClass_BuildIrp(DeviceObject,
+                               Irp,
+                               Context,
+                               IOCTL_HID_READ_REPORT,
+                               IoStack->Parameters.Read.Length,
+                               &NewIrp,
+                               &NewIrpContext);
     if (!NT_SUCCESS(Status))
     {
         //
@@ -690,7 +795,7 @@ HidClass_Read(
     IoMarkIrpPending(Irp);
 
     //
-    // lets dispatch the request
+    // let's dispatch the request
     //
     ASSERT(Context->DeviceExtension);
     Status = Context->DeviceExtension->Common.DriverExtension->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL](Context->DeviceExtension->FDODeviceObject, NewIrp);
@@ -729,7 +834,7 @@ HidClass_DeviceControl(
     //
     // get device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
 
     //
     // only PDO are supported
@@ -740,7 +845,7 @@ HidClass_DeviceControl(
         // invalid request
         //
         DPRINT1("[HIDCLASS] DeviceControl Irp for FDO arrived\n");
-        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER_1;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_INVALID_PARAMETER_1;
     }
@@ -750,14 +855,14 @@ HidClass_DeviceControl(
     //
     // get pdo device extension
     //
-    PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    PDODeviceExtension = DeviceObject->DeviceExtension;
 
     //
     // get stack location
     //
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
+    switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
     {
         case IOCTL_HID_GET_COLLECTION_INFORMATION:
         {
@@ -777,13 +882,14 @@ HidClass_DeviceControl(
             //
             // get output buffer
             //
-            CollectionInformation = (PHID_COLLECTION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+            CollectionInformation = Irp->AssociatedIrp.SystemBuffer;
             ASSERT(CollectionInformation);
 
             //
             // get collection description
             //
-            CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription, PDODeviceExtension->CollectionNumber);
+            CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription,
+                                                                         PDODeviceExtension->CollectionNumber);
             ASSERT(CollectionDescription);
 
             //
@@ -808,7 +914,8 @@ HidClass_DeviceControl(
             //
             // get collection description
             //
-            CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription, PDODeviceExtension->CollectionNumber);
+            CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription,
+                                                                         PDODeviceExtension->CollectionNumber);
             ASSERT(CollectionDescription);
 
             //
@@ -861,15 +968,27 @@ HidClass_InternalDeviceControl(
     return STATUS_NOT_IMPLEMENTED;
 }
 
-
 NTSTATUS
 NTAPI
 HidClass_Power(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
+    if (CommonDeviceExtension->IsFDO)
+    {
+        IoCopyCurrentIrpStackLocationToNext(Irp);
+        return HidClassFDO_DispatchRequest(DeviceObject, Irp);
+    }
+    else
+    {
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        PoStartNextPowerIrp(Irp);
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+    }
 }
 
 NTSTATUS
@@ -883,7 +1002,7 @@ HidClass_PnP(
     //
     // get common device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
 
     //
     // check type of device object
@@ -915,7 +1034,7 @@ HidClass_DispatchDefault(
     //
     // get common device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
 
     //
     // FIXME: support PDO
@@ -933,7 +1052,6 @@ HidClass_DispatchDefault(
     return IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, Irp);
 }
 
-
 NTSTATUS
 NTAPI
 HidClassDispatch(
@@ -951,7 +1069,7 @@ HidClassDispatch(
     //
     // dispatch request based on major function
     //
-    switch(IoStack->MajorFunction)
+    switch (IoStack->MajorFunction)
     {
         case IRP_MJ_CREATE:
             return HidClass_Create(DeviceObject, Irp);
@@ -991,7 +1109,10 @@ HidRegisterMinidriver(
     }
 
     /* now allocate the driver object extension */
-    Status = IoAllocateDriverObjectExtension(MinidriverRegistration->DriverObject, (PVOID)ClientIdentificationAddress, sizeof(HIDCLASS_DRIVER_EXTENSION), (PVOID*)&DriverExtension);
+    Status = IoAllocateDriverObjectExtension(MinidriverRegistration->DriverObject,
+                                             ClientIdentificationAddress,
+                                             sizeof(HIDCLASS_DRIVER_EXTENSION),
+                                             (PVOID *)&DriverExtension);
     if (!NT_SUCCESS(Status))
     {
         /* failed to allocate driver extension */
@@ -1010,7 +1131,9 @@ HidRegisterMinidriver(
     DriverExtension->DriverUnload = MinidriverRegistration->DriverObject->DriverUnload;
 
     /* copy driver dispatch routines */
-    RtlCopyMemory(DriverExtension->MajorFunction, MinidriverRegistration->DriverObject->MajorFunction, sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION+1));
+    RtlCopyMemory(DriverExtension->MajorFunction,
+                  MinidriverRegistration->DriverObject->MajorFunction,
+                  sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1));
 
     /* initialize lock */
     KeInitializeSpinLock(&DriverExtension->Lock);