Author: janderwald
Date: Sat Dec 31 03:33:14 2011
New Revision: 54791

URL: http://svn.reactos.org/svn/reactos?rev=54791&view=rev
Log:
[USB-BRINGUP]
- Implement HidClassFDO_DeviceRelations
- Implement IOCTL_HID_GET_COLLECTION_INFORMATION,  
IOCTL_HID_GET_COLLECTION_DESCRIPTOR
- Implement IRP_MN_QUERY_ID, IRP_MN_QUERY_CAPABILITIES, 
IRP_MN_QUERY_BUS_INFORMATION, IRP_MN_QUERY_PNP_STATE, 
IRP_MN_QUERY_DEVICE_RELATIONS, 
- HIDClass PDO is now created and starts initialization, needs 
IRP_MN_START_DEVICE request implementation
- Tested in Vbox 4.1.4 + WinXP + ReactOS hidusb,hidmou,hidclass

Added:
    branches/usb-bringup/drivers/hid/hidclass/pdo.c   (with props)
Modified:
    branches/usb-bringup/drivers/hid/hidclass/CMakeLists.txt
    branches/usb-bringup/drivers/hid/hidclass/fdo.c
    branches/usb-bringup/drivers/hid/hidclass/hidclass.c
    branches/usb-bringup/drivers/hid/hidclass/precomp.h

Modified: branches/usb-bringup/drivers/hid/hidclass/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidclass/CMakeLists.txt?rev=54791&r1=54790&r2=54791&view=diff
==============================================================================
--- branches/usb-bringup/drivers/hid/hidclass/CMakeLists.txt [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/hid/hidclass/CMakeLists.txt [iso-8859-1] Sat 
Dec 31 03:33:14 2011
@@ -5,6 +5,7 @@
     fdo.c
     hidclass.c
     hidclass.rc
+    pdo.c
     ${CMAKE_CURRENT_BINARY_DIR}/hidclass.def)
 
 add_library(hidclass SHARED ${SOURCE})

Modified: branches/usb-bringup/drivers/hid/hidclass/fdo.c
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidclass/fdo.c?rev=54791&r1=54790&r2=54791&view=diff
==============================================================================
--- branches/usb-bringup/drivers/hid/hidclass/fdo.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/hid/hidclass/fdo.c [iso-8859-1] Sat Dec 31 
03:33:14 2011
@@ -145,7 +145,7 @@
     IN PIRP Irp)
 {
     KEVENT Event;
-    PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
+    PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
     NTSTATUS Status;
     PIO_STACK_LOCATION IoStack;
 
@@ -157,8 +157,7 @@
     //
     // get device extension
     //
-    FDODeviceExtension = 
(PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
-    ASSERT(FDODeviceExtension->Common.IsFDO);
+    CommonDeviceExtension = 
(PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
     //
     // set completion routine
@@ -187,7 +186,7 @@
     // call driver
     //
     DPRINT1("IoStack MajorFunction %x MinorFunction %x\n", 
IoStack->MajorFunction, IoStack->MinorFunction);
-    Status = 
FDODeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject,
 Irp);
+    Status = 
CommonDeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject,
 Irp);
 
     //
     // wait for the request to finish
@@ -393,13 +392,132 @@
 }
 
 NTSTATUS
+HidClassFDO_CopyDeviceRelations(
+    IN PDEVICE_OBJECT DeviceObject,
+    OUT PDEVICE_RELATIONS *OutRelations)
+{
+    PDEVICE_RELATIONS DeviceRelations;
+    PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
+    ULONG Index;
+
+    //
+    // get device extension
+    //
+    FDODeviceExtension = 
(PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(FDODeviceExtension->Common.IsFDO);
+
+    //
+    // allocate result
+    //
+    DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, 
sizeof(DEVICE_RELATIONS) + (FDODeviceExtension->DeviceRelations.Count-1) * 
sizeof(PDEVICE_OBJECT));
+    if (!DeviceRelations)
+    {
+        //
+        // no memory
+        //
+        *OutRelations = NULL;
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // copy device objects
+    //
+    for(Index = 0; Index < FDODeviceExtension->DeviceRelations.Count; Index++)
+    {
+        //
+        // reference pdo
+        //
+        ObReferenceObject(FDODeviceExtension->DeviceRelations.Objects[Index]);
+
+        //
+        // store object
+        //
+        DeviceRelations->Objects[Index] = 
FDODeviceExtension->DeviceRelations.Objects[Index];
+    }
+
+    //
+    // set object count
+    //
+    DeviceRelations->Count = FDODeviceExtension->DeviceRelations.Count;
+
+
+    //
+    // store result
+    //
+    *OutRelations = DeviceRelations;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
 HidClassFDO_DeviceRelations(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-    UNIMPLEMENTED
-    ASSERT(FALSE);
-    return STATUS_NOT_IMPLEMENTED;
+    PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
+    PIO_STACK_LOCATION IoStack;
+    NTSTATUS Status;
+    PDEVICE_RELATIONS DeviceRelations;
+
+    //
+    // get device extension
+    //
+    FDODeviceExtension = 
(PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(FDODeviceExtension->Common.IsFDO);
+
+    //
+    // get current irp stack location
+    //
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    //
+    // check relations type
+    //
+    if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
+    {
+        //
+        // only bus relations are handled
+        //
+        IoSkipCurrentIrpStackLocation(Irp);
+        return 
IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, 
Irp);
+    }
+
+    if (FDODeviceExtension->DeviceRelations.Count == 0)
+    {
+        //
+        // time to create the pdos
+        //
+        Status = HidClassPDO_CreatePDO(DeviceObject);
+        if (!NT_SUCCESS(Status))
+        {
+            //
+            // failed
+            //
+            DPRINT1("[HIDCLASS] HidClassPDO_CreatePDO failed with %x\n", 
Status);
+            Irp->IoStatus.Status = Status;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_SUCCESS;
+        }
+        //
+        // sanity check
+        //
+        ASSERT(FDODeviceExtension->DeviceRelations.Count > 0);
+    }
+
+    //
+    // now copy device relations
+    //
+    Status = HidClassFDO_CopyDeviceRelations(DeviceObject, &DeviceRelations);
+    //
+    // store result
+    //
+    Irp->IoStatus.Status = Status;
+    Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
+
+    //
+    // complete request
+    //
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
 }
 
 NTSTATUS

Modified: branches/usb-bringup/drivers/hid/hidclass/hidclass.c
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidclass/hidclass.c?rev=54791&r1=54790&r2=54791&view=diff
==============================================================================
--- branches/usb-bringup/drivers/hid/hidclass/hidclass.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/hid/hidclass/hidclass.c [iso-8859-1] Sat Dec 
31 03:33:14 2011
@@ -83,7 +83,7 @@
     FDODeviceExtension->Common.HidDeviceExtension.MiniDeviceExtension = 
(PVOID)((ULONG_PTR)FDODeviceExtension + sizeof(HIDCLASS_FDO_EXTENSION));
     FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject = 
IoAttachDeviceToDeviceStack(NewDeviceObject, PhysicalDeviceObject);
     FDODeviceExtension->Common.IsFDO = TRUE;
-    FDODeviceExtension->DriverExtension = DriverExtension;
+    FDODeviceExtension->Common.DriverExtension = DriverExtension;
 
     /* sanity check */
     ASSERT(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject);
@@ -170,9 +170,105 @@
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-    UNIMPLEMENTED
-    ASSERT(FALSE);
-    return STATUS_NOT_IMPLEMENTED;
+    PIO_STACK_LOCATION IoStack;
+    PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
+    PHID_COLLECTION_INFORMATION CollectionInformation;
+    PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
+
+    //
+    // get device extension
+    //
+    CommonDeviceExtension = 
(PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(CommonDeviceExtension->IsFDO == FALSE);
+    PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)CommonDeviceExtension;
+
+    //
+    // get stack location
+    //
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
+    {
+        case IOCTL_HID_GET_COLLECTION_INFORMATION:
+        {
+            //
+            // check if output buffer is big enough
+            //
+            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < 
sizeof(HID_COLLECTION_INFORMATION))
+            {
+                //
+                // invalid buffer size
+                //
+                Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return STATUS_INVALID_BUFFER_SIZE;
+            }
+
+            //
+            // get output buffer
+            //
+            CollectionInformation = 
(PHID_COLLECTION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+            ASSERT(CollectionInformation);
+
+            //
+            // init result buffer
+            //
+            CollectionInformation->DescriptorSize = 
PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength; 
//FIXME which collection is to be retrieved for composite devices / multi 
collection devices?
+            CollectionInformation->Polled = 
CommonDeviceExtension->DriverExtension->DevicesArePolled;
+            CollectionInformation->VendorID = 
PDODeviceExtension->Attributes.VendorID;
+            CollectionInformation->ProductID = 
PDODeviceExtension->Attributes.ProductID;
+            CollectionInformation->VersionNumber = 
PDODeviceExtension->Attributes.VersionNumber;
+
+            //
+            // complete request
+            //
+            Irp->IoStatus.Information = sizeof(HID_COLLECTION_INFORMATION);
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_SUCCESS;
+        }
+        case IOCTL_HID_GET_COLLECTION_DESCRIPTOR:
+        {
+            //
+            // FIXME: which collection to use for composite / multi collection 
devices...
+            //
+
+            //
+            // check if output buffer is big enough
+            //
+            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < 
PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength)
+            {
+                //
+                // invalid buffer size
+                //
+                Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return STATUS_INVALID_BUFFER_SIZE;
+            }
+
+            //
+            // copy result
+            //
+            ASSERT(Irp->UserBuffer);
+            RtlCopyMemory(Irp->UserBuffer, 
PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedData, 
PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength);
+
+            //
+            // complete request
+            //
+            Irp->IoStatus.Information = 
PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength;
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_SUCCESS;
+        }
+        default:
+        {
+            DPRINT1("[HIDCLASS] DeviceControl IoControlCode 0x%x not 
implemented\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
+            ASSERT(FALSE);
+            Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_NOT_IMPLEMENTED;
+        }
+    }
 }
 
 NTSTATUS
@@ -212,14 +308,22 @@
     CommonDeviceExtension = 
(PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
     //
-    // FIXME: support PDO
-    //
-    ASSERT(CommonDeviceExtension->IsFDO == TRUE);
-
-    //
-    // handle request
-    //
-    return HidClassFDO_PnP(DeviceObject, Irp);
+    // check type of device object
+    //
+    if (CommonDeviceExtension->IsFDO)
+    {
+        //
+        // handle request
+        //
+        return HidClassFDO_PnP(DeviceObject, Irp);
+    }
+    else
+    {
+        //
+        // handle request
+        //
+        return HidClassPDO_PnP(DeviceObject, Irp);
+    }
 }
 
 NTSTATUS

Added: branches/usb-bringup/drivers/hid/hidclass/pdo.c
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidclass/pdo.c?rev=54791&view=auto
==============================================================================
--- branches/usb-bringup/drivers/hid/hidclass/pdo.c (added)
+++ branches/usb-bringup/drivers/hid/hidclass/pdo.c [iso-8859-1] Sat Dec 31 
03:33:14 2011
@@ -1,0 +1,566 @@
+/*
+ * PROJECT:     ReactOS Universal Serial Bus Human Interface Device Driver
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        drivers/hid/hidclass/fdo.c
+ * PURPOSE:     HID Class Driver
+ * PROGRAMMERS:
+ *              Michael Martin ([email protected])
+ *              Johannes Anderwald ([email protected])
+ */
+#include "precomp.h"
+
+NTSTATUS
+HidClassPDO_HandleQueryDeviceId(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    NTSTATUS Status;
+    LPWSTR Buffer;
+    LPWSTR NewBuffer, Ptr;
+    ULONG Length;
+
+    //
+    // copy current stack location
+    //
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+
+    //
+    // call mini-driver
+    //
+    Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed
+        //
+        return Status;
+    }
+
+    //
+    // get buffer
+    //
+    Buffer = (LPWSTR)Irp->IoStatus.Information;
+    Length = wcslen(Buffer);
+
+    //
+    // allocate new buffer
+    //
+    NewBuffer = (LPWSTR)ExAllocatePool(NonPagedPool, (Length + 1) * 
sizeof(WCHAR));
+    if (!NewBuffer)
+    {
+        //
+        // failed to allocate buffer
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // replace bus
+    //
+    wcscpy(NewBuffer, L"HID\\");
+
+    //
+    // get offset to first '\\'
+    //
+    Ptr = wcschr(Buffer, L'\\');
+    if (Ptr)
+    {
+        //
+        // append result
+        //
+        wcscat(NewBuffer, Ptr + 1);
+    }
+
+    //
+    // free old buffer
+    //
+    ExFreePool(Buffer);
+
+    //
+    // store result
+    //
+    Irp->IoStatus.Information = (ULONG_PTR)NewBuffer;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+HidClassPDO_HandleQueryHardwareId(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    NTSTATUS Status;
+    PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
+    WCHAR Buffer[100];
+    ULONG Offset = 0;
+    LPWSTR Ptr;
+
+    //
+    // get device extension
+    //
+   PDODeviceExtension = 
(PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+   ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
+
+    //
+    // copy current stack location
+    //
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+
+    //
+    // call mini-driver
+    //
+    Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed
+        //
+        return Status;
+    }
+
+    //
+    // store hardware ids
+    //
+    Offset = swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x&Rev_%04x", 
PDODeviceExtension->Attributes.VendorID, 
PDODeviceExtension->Attributes.ProductID, 
PDODeviceExtension->Attributes.VersionNumber) + 1;
+    Offset += swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x", 
PDODeviceExtension->Attributes.VendorID, 
PDODeviceExtension->Attributes.ProductID) + 1;
+
+    if 
(PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage
 == HID_USAGE_PAGE_GENERIC)
+    {
+        
switch(PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage)
+        {
+            case HID_USAGE_GENERIC_POINTER:
+            case HID_USAGE_GENERIC_MOUSE:
+                //
+                // Pointer / Mouse
+                //
+                Offset += swprintf(&Buffer[Offset], 
L"HID_DEVICE_SYSTEM_MOUSE") + 1;
+                break;
+            case HID_USAGE_GENERIC_GAMEPAD:
+            case HID_USAGE_GENERIC_JOYSTICK:
+                //
+                // Joystick / Gamepad
+                //
+                Offset += swprintf(&Buffer[Offset], L"HID_DEVICE_SYSTEM_GAME") 
+ 1;
+                break;
+            case HID_USAGE_GENERIC_KEYBOARD:
+            case HID_USAGE_GENERIC_KEYPAD:
+                //
+                // Keyboard / Keypad
+                //
+                Offset += swprintf(&Buffer[Offset], 
L"HID_DEVICE_SYSTEM_KEYBOARD") + 1;
+                break;
+            case HID_USAGE_GENERIC_SYSTEM_CTL:
+                //
+                // System Control
+                //
+                Offset += swprintf(&Buffer[Offset], 
L"HID_DEVICE_SYSTEM_CONTROL") + 1;
+                break;
+        }
+    }
+    else if 
(PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage
 == HID_USAGE_PAGE_CONSUMER && 
PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage
 == HID_USAGE_CONSUMERCTRL)
+    {
+        //
+        // Consumer Audio Control
+        //
+        Offset += swprintf(&Buffer[Offset], L"HID_DEVICE_SYSTEM_CONSUMER") + 1;
+    }
+
+    //
+    // FIXME: add 'HID_DEVICE_UP:0001_U:0002'
+    //
+
+    //
+    // add HID
+    //
+    Offset +=swprintf(&Buffer[Offset], L"HID_DEVICE") + 1;
+
+    //
+    // free old buffer
+    //
+    ExFreePool((PVOID)Irp->IoStatus.Information);
+
+    //
+    // allocate buffer
+    //
+    Ptr = (LPWSTR)ExAllocatePool(NonPagedPool, (Offset +1)* sizeof(WCHAR));
+    if (!Ptr)
+    {
+        //
+        // no memory
+        //
+        Irp->IoStatus.Information = 0;
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // copy buffer
+    //
+    RtlCopyMemory(Ptr, Buffer, Offset * sizeof(WCHAR));
+    Ptr[Offset] = UNICODE_NULL;
+
+    //
+    // store result
+    //
+    Irp->IoStatus.Information = (ULONG_PTR)Ptr;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+HidClassPDO_HandleQueryInstanceId(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    NTSTATUS Status;
+
+    //
+    // copy current stack location
+    //
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+
+    //
+    // call mini-driver
+    //
+    Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed
+        //
+        return Status;
+    }
+    DPRINT1("HidClassPDO_HandleQueryInstanceId Buffer %S\n", 
Irp->IoStatus.Information);
+    //
+    //TODO implement instance id
+    // example:
+    // HID\VID_045E&PID_0047\8&1A0700BC&0&0000
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+HidClassPDO_HandleQueryCompatibleId(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    NTSTATUS Status;
+
+    //
+    // copy current stack location
+    //
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+
+    //
+    // call mini-driver
+    //
+    Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed
+        //
+        return Status;
+    }
+
+    //
+    // FIXME: implement me
+    //
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS
+HidClassPDO_PnP(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
+    PIO_STACK_LOCATION IoStack;
+    NTSTATUS Status;
+    PPNP_BUS_INFORMATION BusInformation;
+    PDEVICE_RELATIONS DeviceRelation;
+
+    //
+    // get device extension
+    //
+    PDODeviceExtension = 
(PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
+
+    //
+    // get current irp stack location
+    //
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    //
+    // handle request
+    //
+    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;
+        }
+        case IRP_MN_QUERY_CAPABILITIES:
+        {
+            if (IoStack->Parameters.DeviceCapabilities.Capabilities == NULL)
+            {
+                //
+                // invalid request
+                //
+                Status = STATUS_DEVICE_CONFIGURATION_ERROR;
+            }
+
+            //
+            // copy capabilities
+            //
+            RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, 
&PDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
+            Status = STATUS_SUCCESS;
+            break;
+        }
+        case IRP_MN_QUERY_BUS_INFORMATION:
+        {
+            //
+            //
+            //
+            BusInformation = 
(PPNP_BUS_INFORMATION)ExAllocatePool(NonPagedPool, sizeof(PNP_BUS_INFORMATION));
+ 
+            //
+            // fill in result
+            //
+            RtlCopyMemory(&BusInformation->BusTypeGuid, &GUID_BUS_TYPE_HID, 
sizeof(GUID));
+            BusInformation->LegacyBusType = PNPBus;
+            BusInformation->BusNumber = 0; //FIXME
+
+            //
+            // store result
+            //
+            Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+        case IRP_MN_QUERY_PNP_DEVICE_STATE:
+        {
+            //
+            // FIXME set flags when driver fails / disabled
+            //
+            Status = STATUS_SUCCESS;
+            break;
+        }
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+        {
+            //
+            // only target relations are supported
+            //
+            if (IoStack->Parameters.QueryDeviceRelations.Type != 
TargetDeviceRelation)
+            {
+                //
+                // not supported
+                //
+                Status = Irp->IoStatus.Status;
+                break;
+            }
+
+            //
+            // allocate device relations
+            //
+            DeviceRelation = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, 
sizeof(DEVICE_RELATIONS));
+            if (!DeviceRelation)
+            {
+                //
+                // no memory
+                //
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            //
+            // init device relation
+            //
+            DeviceRelation->Count = 1;
+            DeviceRelation->Objects[0] = DeviceObject;
+            ObReferenceObject(DeviceRelation->Objects[0]);
+
+            //
+            // store result
+            //
+            Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+        case IRP_MN_START_DEVICE:
+        {
+            DPRINT1("[HIDCLASS] PDO PnP not implemented %x\n", 
IoStack->MinorFunction);
+            ASSERT(FALSE);
+
+            //
+            // do nothing
+            //
+            Status = Irp->IoStatus.Status;
+            break;
+        }
+        case IRP_MN_REMOVE_DEVICE:
+        {
+            DPRINT1("[HIDCLASS] PDO IRP_MN_REMOVE_DEVICE not implemented\n");
+            ASSERT(FALSE);
+
+            //
+            // do nothing
+            //
+            Status = Irp->IoStatus.Status;
+            break;
+        }
+        case IRP_MN_QUERY_INTERFACE:
+        {
+            DPRINT1("[HIDCLASS] PDO IRP_MN_QUERY_INTERFACE not implemented\n");
+            ASSERT(FALSE);
+
+            //
+            // do nothing
+            //
+            Status = Irp->IoStatus.Status;
+            break;
+        }
+        default:
+        {
+            //
+            // do nothing
+            //
+            Status = Irp->IoStatus.Status;
+            break;
+        }
+    }
+
+    //
+    // complete request
+    //
+    if (Status != STATUS_PENDING)
+    {
+        //
+        // store result
+        //
+        Irp->IoStatus.Status = Status;
+
+        //
+        // complete request
+        //
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+
+    //
+    // done processing
+    //
+    return Status;
+}
+
+NTSTATUS
+HidClassPDO_CreatePDO(
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
+    NTSTATUS Status;
+    PDEVICE_OBJECT PDODeviceObject;
+    PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
+
+    //
+    // get device extension
+    //
+    FDODeviceExtension = 
(PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(FDODeviceExtension->Common.IsFDO);
+
+    //
+    // lets 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);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to create device
+        //
+        DPRINT1("[HIDCLASS] Failed to create device %x\n", Status);
+        return Status;
+    }
+
+    //
+    // patch stack size
+    //
+    PDODeviceObject->StackSize = DeviceObject->StackSize + 1;
+
+    //
+    // get device extension
+    //
+    PDODeviceExtension = 
(PHIDCLASS_PDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
+
+    //
+    // init device extension
+    //
+    PDODeviceExtension->Common.HidDeviceExtension.MiniDeviceExtension = 
FDODeviceExtension->Common.HidDeviceExtension.MiniDeviceExtension;
+    PDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject = 
FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject;
+    PDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject = NULL;
+    PDODeviceExtension->Common.IsFDO = FALSE;
+    PDODeviceExtension->Common.DriverExtension = 
FDODeviceExtension->Common.DriverExtension;
+    RtlCopyMemory(&PDODeviceExtension->Attributes, 
&FDODeviceExtension->Attributes, sizeof(HID_DEVICE_ATTRIBUTES));
+    RtlCopyMemory(&PDODeviceExtension->DeviceDescription, 
&FDODeviceExtension->DeviceDescription, sizeof(HIDP_DEVICE_DESC));
+    RtlCopyMemory(&PDODeviceExtension->Capabilities, 
&FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
+
+    //
+    // FIXME: support composite devices
+    //
+    PDODeviceExtension->CollectionIndex = 0;
+    ASSERT(PDODeviceExtension->DeviceDescription.CollectionDescLength == 1);
+
+    //
+    // store in device relations struct
+    //
+    FDODeviceExtension->DeviceRelations.Count = 1;
+    FDODeviceExtension->DeviceRelations.Objects[0] = PDODeviceObject;
+
+    //
+    // set device flags
+    //
+    PDODeviceObject->Flags |= DO_MAP_IO_BUFFER;
+
+    //
+    // device is initialized
+    //
+    PDODeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+    ObReferenceObject(PDODeviceObject);
+
+    //
+    // done
+    //
+    return STATUS_SUCCESS;
+}

Propchange: branches/usb-bringup/drivers/hid/hidclass/pdo.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: branches/usb-bringup/drivers/hid/hidclass/precomp.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidclass/precomp.h?rev=54791&r1=54790&r2=54791&view=diff
==============================================================================
--- branches/usb-bringup/drivers/hid/hidclass/precomp.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/hid/hidclass/precomp.h [iso-8859-1] Sat Dec 31 
03:33:14 2011
@@ -4,7 +4,11 @@
 #include <ntddk.h>
 #include <hidport.h>
 #include <hidpddi.h>
+#include <stdio.h>
+#include <initguid.h>
+#include <wdmguid.h>
 #include <debug.h>
+
 
 
 typedef struct
@@ -21,11 +25,22 @@
 
 typedef struct
 {
+    //
+    // hid device extension
+    //
     HID_DEVICE_EXTENSION HidDeviceExtension;
+
+    //
+    // if it is a pdo
+    //
     BOOLEAN IsFDO;
+
+    //
+    // driver extension
+    //
+    PHIDCLASS_DRIVER_EXTENSION DriverExtension;
+
 }HIDCLASS_COMMON_DEVICE_EXTENSION, *PHIDCLASS_COMMON_DEVICE_EXTENSION;
-
-
 
 typedef struct
 {
@@ -33,11 +48,6 @@
     // parts shared by fdo and pdo
     //
     HIDCLASS_COMMON_DEVICE_EXTENSION Common;
-
-    //
-    // driver extension
-    //
-    PHIDCLASS_DRIVER_EXTENSION DriverExtension;
 
     //
     // device capabilities
@@ -64,7 +74,41 @@
     //
     HIDP_DEVICE_DESC DeviceDescription;
 
+    //
+    // device relations
+    //
+    DEVICE_RELATIONS DeviceRelations;
+
 }HIDCLASS_FDO_EXTENSION, *PHIDCLASS_FDO_EXTENSION;
+
+typedef struct
+{
+    //
+    // parts shared by fdo and pdo
+    //
+    HIDCLASS_COMMON_DEVICE_EXTENSION Common;
+
+    //
+    // device descriptor
+    //
+    HID_DEVICE_ATTRIBUTES Attributes;
+
+    //
+    // device capabilities
+    //
+    DEVICE_CAPABILITIES Capabilities;
+
+    //
+    // device description
+    //
+    HIDP_DEVICE_DESC DeviceDescription;
+
+    //
+    // collection index
+    //
+    ULONG CollectionIndex;
+
+}HIDCLASS_PDO_DEVICE_EXTENSION, *PHIDCLASS_PDO_DEVICE_EXTENSION;
 
 
 /* fdo.c */
@@ -73,3 +117,20 @@
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp);
 
+NTSTATUS
+HidClassFDO_DispatchRequestSynchronous(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp);
+
+/* pdo.c */
+NTSTATUS
+HidClassPDO_CreatePDO(
+    IN PDEVICE_OBJECT DeviceObject);
+
+NTSTATUS
+HidClassPDO_PnP(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp);
+
+
+/* eof */


Reply via email to