[HIDCLASS] Implement IOCTL_HID_GET_FEATURE/IOCTL_HID_SET_FEATURE
[reactos.git] / drivers / hid / hidclass / pdo.c
index cc29a00..f629ebd 100644 (file)
@@ -7,8 +7,14 @@
  *              Michael Martin (michael.martin@reactos.org)
  *              Johannes Anderwald (johannes.anderwald@reactos.org)
  */
+
 #include "precomp.h"
 
+#include <wdmguid.h>
+
+#define NDEBUG
+#include <debug.h>
+
 PHIDP_COLLECTION_DESC
 HidClassPDO_GetCollectionDescription(
     PHIDP_DEVICE_DESC DeviceDescription,
@@ -42,7 +48,7 @@ HidClassPDO_GetReportDescription(
 {
     ULONG Index;
 
-    for(Index = 0; Index < DeviceDescription->ReportIDsLength; Index++)
+    for (Index = 0; Index < DeviceDescription->ReportIDsLength; Index++)
     {
         if (DeviceDescription->ReportIDs[Index].CollectionNumber == CollectionNumber)
         {
@@ -61,6 +67,32 @@ HidClassPDO_GetReportDescription(
     return NULL;
 }
 
+PHIDP_REPORT_IDS
+HidClassPDO_GetReportDescriptionByReportID(
+    PHIDP_DEVICE_DESC DeviceDescription,
+    UCHAR ReportID)
+{
+    ULONG Index;
+
+    for (Index = 0; Index < DeviceDescription->ReportIDsLength; Index++)
+    {
+        if (DeviceDescription->ReportIDs[Index].ReportID == ReportID)
+        {
+            //
+            // found report id
+            //
+            return &DeviceDescription->ReportIDs[Index];
+        }
+    }
+
+    //
+    // failed to find report id
+    //
+    DPRINT1("[HIDCLASS] GetReportDescriptionByReportID ReportID %x not found\n", ReportID);
+    ASSERT(FALSE);
+    return NULL;
+}
+
 NTSTATUS
 HidClassPDO_HandleQueryDeviceId(
     IN PDEVICE_OBJECT DeviceObject,
@@ -97,7 +129,7 @@ HidClassPDO_HandleQueryDeviceId(
     //
     // allocate new buffer
     //
-    NewBuffer = (LPWSTR)ExAllocatePool(NonPagedPool, (Length + 1) * sizeof(WCHAR));
+    NewBuffer = ExAllocatePoolWithTag(NonPagedPool, (Length + 1) * sizeof(WCHAR), HIDCLASS_TAG);
     if (!NewBuffer)
     {
         //
@@ -126,7 +158,7 @@ HidClassPDO_HandleQueryDeviceId(
     //
     // free old buffer
     //
-    ExFreePool(Buffer);
+    ExFreePoolWithTag(Buffer, 0);
 
     //
     // store result
@@ -151,8 +183,8 @@ HidClassPDO_HandleQueryHardwareId(
     //
     // get device extension
     //
-   PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-   ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
+    PDODeviceExtension = DeviceObject->DeviceExtension;
+    ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
 
     //
     // copy current stack location
@@ -196,7 +228,7 @@ HidClassPDO_HandleQueryHardwareId(
 
     if (CollectionDescription->UsagePage == HID_USAGE_PAGE_GENERIC)
     {
-        switch(CollectionDescription->Usage)
+        switch (CollectionDescription->Usage)
         {
             case HID_USAGE_GENERIC_POINTER:
             case HID_USAGE_GENERIC_MOUSE:
@@ -248,12 +280,12 @@ HidClassPDO_HandleQueryHardwareId(
     //
     // free old buffer
     //
-    ExFreePool((PVOID)Irp->IoStatus.Information);
+    ExFreePoolWithTag((PVOID)Irp->IoStatus.Information, 0);
 
     //
     // allocate buffer
     //
-    Ptr = (LPWSTR)ExAllocatePool(NonPagedPool, (Offset +1)* sizeof(WCHAR));
+    Ptr = ExAllocatePoolWithTag(NonPagedPool, (Offset + 1) * sizeof(WCHAR), HIDCLASS_TAG);
     if (!Ptr)
     {
         //
@@ -287,14 +319,13 @@ HidClassPDO_HandleQueryInstanceId(
     //
     // get device extension
     //
-   PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-   ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
-
+    PDODeviceExtension = DeviceObject->DeviceExtension;
+    ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
 
     //
     // allocate buffer
     //
-    Buffer = ExAllocatePool(NonPagedPool, 5 * sizeof(WCHAR));
+    Buffer = ExAllocatePoolWithTag(NonPagedPool, 5 * sizeof(WCHAR), HIDCLASS_TAG);
     if (!Buffer)
     {
         //
@@ -322,7 +353,7 @@ HidClassPDO_HandleQueryCompatibleId(
 {
     LPWSTR Buffer;
 
-    Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
+    Buffer = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), HIDCLASS_TAG);
     if (!Buffer)
     {
         //
@@ -359,7 +390,7 @@ HidClassPDO_PnP(
     //
     // get device extension
     //
-    PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    PDODeviceExtension = DeviceObject->DeviceExtension;
     ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
 
     //
@@ -370,47 +401,47 @@ HidClassPDO_PnP(
     //
     // handle request
     //
-    switch(IoStack->MinorFunction)
+    switch (IoStack->MinorFunction)
     {
         case IRP_MN_QUERY_ID:
         {
-           if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
-           {
-               //
-               // handle query device id
-               //
-               Status = HidClassPDO_HandleQueryDeviceId(DeviceObject, Irp);
-               break;
-           }
-           else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
-           {
-               //
-               // handle instance id
-               //
-               Status = HidClassPDO_HandleQueryHardwareId(DeviceObject, Irp);
-               break;
-           }
-           else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
-           {
-               //
-               // handle instance id
-               //
-               Status = HidClassPDO_HandleQueryInstanceId(DeviceObject, Irp);
-               break;
-           }
-           else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
-           {
-               //
-               // handle instance id
-               //
-               Status = HidClassPDO_HandleQueryCompatibleId(DeviceObject, Irp);
-               break;
-           }
-
-           DPRINT1("[HIDCLASS]: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType);
-           Status = STATUS_NOT_SUPPORTED;
-           Irp->IoStatus.Information = 0;
-           break;
+            if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
+            {
+                //
+                // handle query device id
+                //
+                Status = HidClassPDO_HandleQueryDeviceId(DeviceObject, Irp);
+                break;
+            }
+            else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
+            {
+                //
+                // handle instance id
+                //
+                Status = HidClassPDO_HandleQueryHardwareId(DeviceObject, Irp);
+                break;
+            }
+            else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
+            {
+                //
+                // handle instance id
+                //
+                Status = HidClassPDO_HandleQueryInstanceId(DeviceObject, Irp);
+                break;
+            }
+            else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
+            {
+                //
+                // handle instance id
+                //
+                Status = HidClassPDO_HandleQueryCompatibleId(DeviceObject, Irp);
+                break;
+            }
+
+            DPRINT1("[HIDCLASS]: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType);
+            Status = STATUS_NOT_SUPPORTED;
+            Irp->IoStatus.Information = 0;
+            break;
         }
         case IRP_MN_QUERY_CAPABILITIES:
         {
@@ -426,7 +457,9 @@ HidClassPDO_PnP(
             //
             // copy capabilities
             //
-            RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &PDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
+            RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities,
+                          &PDODeviceExtension->Capabilities,
+                          sizeof(DEVICE_CAPABILITIES));
             Status = STATUS_SUCCESS;
             break;
         }
@@ -435,8 +468,8 @@ HidClassPDO_PnP(
             //
             //
             //
-            BusInformation = (PPNP_BUS_INFORMATION)ExAllocatePool(NonPagedPool, sizeof(PNP_BUS_INFORMATION));
+            BusInformation = ExAllocatePoolWithTag(NonPagedPool, sizeof(PNP_BUS_INFORMATION), HIDCLASS_TAG);
+
             //
             // fill in result
             //
@@ -476,7 +509,7 @@ HidClassPDO_PnP(
             //
             // allocate device relations
             //
-            DeviceRelation = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS));
+            DeviceRelation = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS), HIDCLASS_TAG);
             if (!DeviceRelation)
             {
                 //
@@ -510,7 +543,10 @@ HidClassPDO_PnP(
             //
             // now register the device interface
             //
-            Status = IoRegisterDeviceInterface(PDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject, &GUID_DEVINTERFACE_HID, NULL, &PDODeviceExtension->DeviceInterface);
+            Status = IoRegisterDeviceInterface(PDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject,
+                                               &GUID_DEVINTERFACE_HID,
+                                               NULL,
+                                               &PDODeviceExtension->DeviceInterface);
             DPRINT("[HIDCLASS] IoRegisterDeviceInterfaceState Status %x\n", Status);
             if (NT_SUCCESS(Status))
             {
@@ -533,22 +569,22 @@ HidClassPDO_PnP(
             if (PDODeviceExtension->DeviceInterface.Length != 0)
                 IoSetDeviceInterfaceState(&PDODeviceExtension->DeviceInterface, FALSE);
 
-           //
-           // remove us from the fdo's pdo list
-           //
-           bFound = FALSE;
-           for(Index = 0; Index < PDODeviceExtension->FDODeviceExtension->DeviceRelations->Count; Index++)
-           {
-               if (PDODeviceExtension->FDODeviceExtension->DeviceRelations->Objects[Index] == DeviceObject)
-               {
-                   //
-                   // remove us
-                   //
-                   bFound = TRUE;
-                   PDODeviceExtension->FDODeviceExtension->DeviceRelations->Objects[Index] = NULL;
-                   break;
-               }
-           }
+            //
+            // remove us from the fdo's pdo list
+            //
+            bFound = FALSE;
+            for (Index = 0; Index < PDODeviceExtension->FDODeviceExtension->DeviceRelations->Count; Index++)
+            {
+                if (PDODeviceExtension->FDODeviceExtension->DeviceRelations->Objects[Index] == DeviceObject)
+                {
+                    //
+                    // remove us
+                    //
+                    bFound = TRUE;
+                    PDODeviceExtension->FDODeviceExtension->DeviceRelations->Objects[Index] = NULL;
+                    break;
+                }
+            }
 
             /* Complete the IRP */
             Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -565,7 +601,6 @@ HidClassPDO_PnP(
         case IRP_MN_QUERY_INTERFACE:
         {
             DPRINT1("[HIDCLASS] PDO IRP_MN_QUERY_INTERFACE not implemented\n");
-            ASSERT(FALSE);
 
             //
             // do nothing
@@ -627,7 +662,7 @@ HidClassPDO_CreatePDO(
     OUT PDEVICE_RELATIONS *OutDeviceRelations)
 {
     PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
     PDEVICE_OBJECT PDODeviceObject;
     PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
     ULONG Index;
@@ -637,14 +672,14 @@ HidClassPDO_CreatePDO(
     //
     // get device extension
     //
-    FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
+    FDODeviceExtension = DeviceObject->DeviceExtension;
     ASSERT(FDODeviceExtension->Common.IsFDO);
 
     //
     // first allocate device relations
     //
-    Length = sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * FDODeviceExtension->Common.DeviceDescription.CollectionDescLength;
-    DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, Length);
+    Length = FIELD_OFFSET(DEVICE_RELATIONS, Objects) + sizeof(PDEVICE_OBJECT) * FDODeviceExtension->Common.DeviceDescription.CollectionDescLength;
+    DeviceRelations = ExAllocatePoolWithTag(PagedPool, Length, HIDCLASS_TAG);
     if (!DeviceRelations)
     {
         //
@@ -659,15 +694,21 @@ HidClassPDO_CreatePDO(
     RtlZeroMemory(DeviceRelations, Length);
 
     //
-    // lets create a PDO for top level collection
+    // let's create a PDO for top level collection
     //
     Index = 0;
-    do
+    while (Index < FDODeviceExtension->Common.DeviceDescription.CollectionDescLength)
     {
         //
-        // lets create the device object
+        // let's create the device object
         //
-        Status = IoCreateDevice(FDODeviceExtension->Common.DriverExtension->DriverObject, sizeof(HIDCLASS_PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &PDODeviceObject);
+        Status = IoCreateDevice(FDODeviceExtension->Common.DriverExtension->DriverObject,
+                                sizeof(HIDCLASS_PDO_DEVICE_EXTENSION),
+                                NULL,
+                                FILE_DEVICE_UNKNOWN,
+                                FILE_AUTOGENERATED_DEVICE_NAME,
+                                FALSE,
+                                &PDODeviceObject);
         if (!NT_SUCCESS(Status))
         {
             //
@@ -685,7 +726,7 @@ HidClassPDO_CreatePDO(
         //
         // get device extension
         //
-        PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
+        PDODeviceExtension = PDODeviceObject->DeviceExtension;
 
         //
         // init device extension
@@ -724,10 +765,10 @@ HidClassPDO_CreatePDO(
 
         //
         // move to next
-        // 
+        //
         Index++;
 
-    }while(Index < FDODeviceExtension->Common.DeviceDescription.CollectionDescLength);
+    }
 
 
     //
@@ -738,7 +779,7 @@ HidClassPDO_CreatePDO(
         //
         // failed
         //
-        for(Index = 0; Index < DeviceRelations->Count; Index++)
+        for (Index = 0; Index < DeviceRelations->Count; Index++)
         {
             //
             // delete device
@@ -749,7 +790,7 @@ HidClassPDO_CreatePDO(
         //
         // free device relations
         //
-        ExFreePool(DeviceRelations);
+        ExFreePoolWithTag(DeviceRelations, HIDCLASS_TAG);
         return Status;
     }
 
@@ -762,4 +803,4 @@ HidClassPDO_CreatePDO(
     // done
     //
     return STATUS_SUCCESS;
-}
\ No newline at end of file
+}