[BTRFS] Fix booting with runtime checks
[reactos.git] / drivers / hid / hidclass / hidclass.c
index 870ec2c..6d21f14 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,17 +76,24 @@ HidClassAddDevice(
     }
 
     /* get device extension */
-    FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)NewDeviceObject->DeviceExtension;
+    FDODeviceExtension = NewDeviceObject->DeviceExtension;
 
     /* zero device extension */
     RtlZeroMemory(FDODeviceExtension, sizeof(HIDCLASS_FDO_EXTENSION));
 
     /* initialize device extension */
+    FDODeviceExtension->Common.IsFDO = TRUE;
+    FDODeviceExtension->Common.DriverExtension = DriverExtension;
     FDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject = PhysicalDeviceObject;
     FDODeviceExtension->Common.HidDeviceExtension.MiniDeviceExtension = (PVOID)((ULONG_PTR)FDODeviceExtension + sizeof(HIDCLASS_FDO_EXTENSION));
     FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject = IoAttachDeviceToDeviceStack(NewDeviceObject, PhysicalDeviceObject);
-    FDODeviceExtension->Common.IsFDO = TRUE;
-    FDODeviceExtension->Common.DriverExtension = DriverExtension;
+    if (FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject == NULL)
+    {
+        /* no PDO */
+        IoDeleteDevice(NewDeviceObject);
+        DPRINT1("[HIDCLASS] failed to attach to device stack\n");
+        return STATUS_DEVICE_REMOVED;
+    }
 
     /* sanity check */
     ASSERT(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject);
@@ -116,7 +126,7 @@ NTAPI
 HidClassDriverUnload(
     IN PDRIVER_OBJECT DriverObject)
 {
-    UNIMPLEMENTED
+    UNIMPLEMENTED;
 }
 
 NTSTATUS
@@ -133,26 +143,15 @@ HidClass_Create(
     //
     // get device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
     if (CommonDeviceExtension->IsFDO)
     {
-#ifndef __REACTOS__
-
          //
          // only supported for PDO
          //
          Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
          IoCompleteRequest(Irp, IO_NO_INCREMENT);
          return STATUS_UNSUCCESSFUL;
-#else
-         //
-         // ReactOS PnP manager [...]
-         //
-         DPRINT1("[HIDCLASS] PnP HACK\n");
-         Irp->IoStatus.Status = STATUS_SUCCESS;
-         IoCompleteRequest(Irp, IO_NO_INCREMENT);
-         return STATUS_SUCCESS;
-#endif
     }
 
     //
@@ -163,21 +162,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)
     {
         //
@@ -196,12 +195,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
@@ -219,12 +219,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
@@ -253,54 +257,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
@@ -316,11 +359,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);
@@ -338,7 +382,7 @@ HidClass_ReadCompleteIrp(
         //
         // get address
         //
-        Address = (PUCHAR)HidClass_GetSystemAddress(IrpContext->OriginalIrp->MdlAddress);
+        Address = MmGetSystemAddressForMdlSafe(IrpContext->OriginalIrp->MdlAddress, NormalPagePriority);
         if (Address)
         {
             //
@@ -349,13 +393,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)
@@ -378,12 +424,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
@@ -395,6 +441,11 @@ HidClass_ReadCompleteIrp(
     //
     RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
 
+    //
+    // is list empty
+    //
+    IsEmpty = IsListEmpty(&IrpContext->FileOp->ReadPendingIrpListHead);
+
     //
     // insert into completed list
     //
@@ -410,10 +461,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
@@ -447,7 +518,7 @@ HidClass_GetIrp(
         //
         // get irp
         //
-        Irp = (PIRP)CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
+        Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
     }
 
     //
@@ -507,7 +578,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)
     {
         //
@@ -520,7 +591,7 @@ HidClass_BuildIrp(
     //
     // get device extension
     //
-    PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    PDODeviceExtension = DeviceObject->DeviceExtension;
     ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
 
     //
@@ -533,13 +604,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);
 
     //
@@ -547,6 +620,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
     //
@@ -555,14 +640,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;
     }
 
@@ -594,7 +679,6 @@ HidClass_BuildIrp(
     return STATUS_SUCCESS;
 }
 
-
 NTSTATUS
 NTAPI
 HidClass_Read(
@@ -617,7 +701,7 @@ HidClass_Read(
     //
     // get device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
     ASSERT(CommonDeviceExtension->IsFDO == FALSE);
 
     //
@@ -629,7 +713,7 @@ HidClass_Read(
     //
     // get context
     //
-    Context = (PHIDCLASS_FILEOP_CONTEXT)IoStack->FileObject->FsContext;
+    Context = IoStack->FileObject->FsContext;
     ASSERT(Context);
 
     //
@@ -637,10 +721,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))
     {
         //
@@ -683,7 +784,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);
@@ -700,7 +801,7 @@ HidClass_Write(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-    UNIMPLEMENTED
+    UNIMPLEMENTED;
     ASSERT(FALSE);
     Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -722,20 +823,35 @@ HidClass_DeviceControl(
     //
     // get device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
+
+    //
+    // only PDO are supported
+    //
+    if (CommonDeviceExtension->IsFDO)
+    {
+        //
+        // invalid request
+        //
+        DPRINT1("[HIDCLASS] DeviceControl Irp for FDO arrived\n");
+        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER_1;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_INVALID_PARAMETER_1;
+    }
+
     ASSERT(CommonDeviceExtension->IsFDO == FALSE);
 
     //
     // 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:
         {
@@ -755,13 +871,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);
 
             //
@@ -786,7 +903,8 @@ HidClass_DeviceControl(
             //
             // get collection description
             //
-            CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription, PDODeviceExtension->CollectionNumber);
+            CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription,
+                                                                         PDODeviceExtension->CollectionNumber);
             ASSERT(CollectionDescription);
 
             //
@@ -832,22 +950,34 @@ HidClass_InternalDeviceControl(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-    UNIMPLEMENTED
+    UNIMPLEMENTED;
     ASSERT(FALSE);
     Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
     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
@@ -861,7 +991,7 @@ HidClass_PnP(
     //
     // get common device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
 
     //
     // check type of device object
@@ -893,7 +1023,7 @@ HidClass_DispatchDefault(
     //
     // get common device extension
     //
-    CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    CommonDeviceExtension = DeviceObject->DeviceExtension;
 
     //
     // FIXME: support PDO
@@ -911,7 +1041,6 @@ HidClass_DispatchDefault(
     return IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, Irp);
 }
 
-
 NTSTATUS
 NTAPI
 HidClassDispatch(
@@ -929,7 +1058,7 @@ HidClassDispatch(
     //
     // dispatch request based on major function
     //
-    switch(IoStack->MajorFunction)
+    switch (IoStack->MajorFunction)
     {
         case IRP_MJ_CREATE:
             return HidClass_Create(DeviceObject, Irp);
@@ -969,7 +1098,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 */
@@ -988,7 +1120,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);