[USB-BRINGUP]

- Create PDO for each top level collection found
- Use the specified collection index instead of the first
- add collection id to hardware id when the device has more than one top level collection, see http://msdn.microsoft.com/en-us/windows/hardware/gg487473 for details

svn path=/branches/usb-bringup/; revision=54808
This commit is contained in:
Johannes Anderwald 2012-01-02 12:00:51 +00:00
parent 842fe995ce
commit 07ae01f96c
4 changed files with 277 additions and 94 deletions

View file

@ -180,8 +180,6 @@ HidClassFDO_DispatchRequestSynchronous(
// //
IoStack->DeviceObject = DeviceObject; IoStack->DeviceObject = DeviceObject;
// //
// call driver // call driver
// //
@ -409,7 +407,7 @@ HidClassFDO_CopyDeviceRelations(
// //
// allocate result // allocate result
// //
DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS) + (FDODeviceExtension->DeviceRelations.Count-1) * sizeof(PDEVICE_OBJECT)); DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS) + (FDODeviceExtension->DeviceRelations->Count-1) * sizeof(PDEVICE_OBJECT));
if (!DeviceRelations) if (!DeviceRelations)
{ {
// //
@ -422,24 +420,23 @@ HidClassFDO_CopyDeviceRelations(
// //
// copy device objects // copy device objects
// //
for(Index = 0; Index < FDODeviceExtension->DeviceRelations.Count; Index++) for(Index = 0; Index < FDODeviceExtension->DeviceRelations->Count; Index++)
{ {
// //
// reference pdo // reference pdo
// //
ObReferenceObject(FDODeviceExtension->DeviceRelations.Objects[Index]); ObReferenceObject(FDODeviceExtension->DeviceRelations->Objects[Index]);
// //
// store object // store object
// //
DeviceRelations->Objects[Index] = FDODeviceExtension->DeviceRelations.Objects[Index]; DeviceRelations->Objects[Index] = FDODeviceExtension->DeviceRelations->Objects[Index];
} }
// //
// set object count // set object count
// //
DeviceRelations->Count = FDODeviceExtension->DeviceRelations.Count; DeviceRelations->Count = FDODeviceExtension->DeviceRelations->Count;
// //
// store result // store result
@ -481,12 +478,12 @@ HidClassFDO_DeviceRelations(
return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp); return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
} }
if (FDODeviceExtension->DeviceRelations.Count == 0) if (FDODeviceExtension->DeviceRelations == NULL)
{ {
// //
// time to create the pdos // time to create the pdos
// //
Status = HidClassPDO_CreatePDO(DeviceObject); Status = HidClassPDO_CreatePDO(DeviceObject, &FDODeviceExtension->DeviceRelations);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// //
@ -500,7 +497,7 @@ HidClassFDO_DeviceRelations(
// //
// sanity check // sanity check
// //
ASSERT(FDODeviceExtension->DeviceRelations.Count > 0); ASSERT(FDODeviceExtension->DeviceRelations->Count > 0);
} }
// //

View file

@ -304,8 +304,8 @@ HidClass_ReadCompleteIrp(
KIRQL OldLevel; KIRQL OldLevel;
PUCHAR Address; PUCHAR Address;
ULONG Offset; ULONG Offset;
PHIDP_DEVICE_DESC DeviceDescription; PHIDP_COLLECTION_DESC CollectionDescription;
ULONG CollectionIndex; PHIDP_REPORT_IDS ReportDescription;
// //
// get irp context // get irp context
@ -328,20 +328,34 @@ HidClass_ReadCompleteIrp(
// //
// get address // get address
// //
Address = HidClass_GetSystemAddress(IrpContext->OriginalIrp->MdlAddress); Address = (PUCHAR)HidClass_GetSystemAddress(IrpContext->OriginalIrp->MdlAddress);
if (Address) if (Address)
{ {
// //
// reports may have a report id prepended // reports may have a report id prepended
// //
CollectionIndex = IrpContext->FileOp->DeviceExtension->CollectionIndex; Offset = 0;
DeviceDescription = &IrpContext->FileOp->DeviceExtension->Common.DeviceDescription;
// //
// calculate offset // get collection description
// //
ASSERT(DeviceDescription->CollectionDesc[CollectionIndex].InputLength >= DeviceDescription->ReportIDs[CollectionIndex].InputLength); CollectionDescription = HidClassPDO_GetCollectionDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
Offset = DeviceDescription->CollectionDesc[CollectionIndex].InputLength - DeviceDescription->ReportIDs[CollectionIndex].InputLength; ASSERT(CollectionDescription);
//
// get report description
//
ReportDescription = HidClassPDO_GetReportDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
ASSERT(ReportDescription);
if (CollectionDescription && ReportDescription)
{
//
// calculate offset
//
ASSERT(CollectionDescription->InputLength >= ReportDescription->InputLength);
Offset = CollectionDescription->InputLength - ReportDescription->InputLength;
}
// //
// copy result // copy result
@ -451,6 +465,8 @@ HidClass_BuildIrp(
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PHIDCLASS_IRP_CONTEXT IrpContext; PHIDCLASS_IRP_CONTEXT IrpContext;
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension; PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
PHIDP_COLLECTION_DESC CollectionDescription;
PHIDP_REPORT_IDS ReportDescription;
// //
// get an irp from fresh list // get an irp from fresh list
@ -497,22 +513,35 @@ HidClass_BuildIrp(
PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
//
// sanity checks
//
ASSERT(PDODeviceExtension->CollectionIndex < PDODeviceExtension->Common.DeviceDescription.CollectionDescLength);
ASSERT(PDODeviceExtension->CollectionIndex < PDODeviceExtension->Common.DeviceDescription.ReportIDsLength);
ASSERT(PDODeviceExtension->Common.DeviceDescription.ReportIDs[PDODeviceExtension->CollectionIndex].InputLength > 0);
ASSERT(PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].InputLength == BufferLength);
// //
// init irp context // init irp context
// //
RtlZeroMemory(IrpContext, sizeof(HIDCLASS_IRP_CONTEXT)); RtlZeroMemory(IrpContext, sizeof(HIDCLASS_IRP_CONTEXT));
IrpContext->InputReportBufferLength = PDODeviceExtension->Common.DeviceDescription.ReportIDs[PDODeviceExtension->CollectionIndex].InputLength;
IrpContext->OriginalIrp = RequestIrp; IrpContext->OriginalIrp = RequestIrp;
IrpContext->FileOp = Context; IrpContext->FileOp = Context;
//
// get collection description
//
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);
ASSERT(ReportDescription);
//
// sanity check
//
ASSERT(CollectionDescription->InputLength >= ReportDescription->InputLength);
//
// store report length
//
IrpContext->InputReportBufferLength = ReportDescription->InputLength;
// //
// allocate buffer // allocate buffer
// //
@ -677,11 +706,19 @@ HidClass_DeviceControl(
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension; PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
PHID_COLLECTION_INFORMATION CollectionInformation; PHID_COLLECTION_INFORMATION CollectionInformation;
PHIDP_COLLECTION_DESC CollectionDescription;
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
// //
// get device extension // get device extension
// //
CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(CommonDeviceExtension->IsFDO == FALSE);
//
// get pdo device extension
//
PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// //
// get stack location // get stack location
@ -711,10 +748,16 @@ HidClass_DeviceControl(
CollectionInformation = (PHID_COLLECTION_INFORMATION)Irp->AssociatedIrp.SystemBuffer; CollectionInformation = (PHID_COLLECTION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
ASSERT(CollectionInformation); ASSERT(CollectionInformation);
//
// get collection description
//
CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription, PDODeviceExtension->CollectionNumber);
ASSERT(CollectionDescription);
// //
// init result buffer // init result buffer
// //
CollectionInformation->DescriptorSize = CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength; //FIXME which collection is to be retrieved for composite devices / multi collection devices? CollectionInformation->DescriptorSize = CollectionDescription->PreparsedDataLength;
CollectionInformation->Polled = CommonDeviceExtension->DriverExtension->DevicesArePolled; CollectionInformation->Polled = CommonDeviceExtension->DriverExtension->DevicesArePolled;
CollectionInformation->VendorID = CommonDeviceExtension->Attributes.VendorID; CollectionInformation->VendorID = CommonDeviceExtension->Attributes.VendorID;
CollectionInformation->ProductID = CommonDeviceExtension->Attributes.ProductID; CollectionInformation->ProductID = CommonDeviceExtension->Attributes.ProductID;
@ -731,13 +774,15 @@ HidClass_DeviceControl(
case IOCTL_HID_GET_COLLECTION_DESCRIPTOR: case IOCTL_HID_GET_COLLECTION_DESCRIPTOR:
{ {
// //
// FIXME: which collection to use for composite / multi collection devices... // get collection description
// //
CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription, PDODeviceExtension->CollectionNumber);
ASSERT(CollectionDescription);
// //
// check if output buffer is big enough // check if output buffer is big enough
// //
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength) if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < CollectionDescription->PreparsedDataLength)
{ {
// //
// invalid buffer size // invalid buffer size
@ -751,12 +796,12 @@ HidClass_DeviceControl(
// copy result // copy result
// //
ASSERT(Irp->UserBuffer); ASSERT(Irp->UserBuffer);
RtlCopyMemory(Irp->UserBuffer, CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedData, CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength); RtlCopyMemory(Irp->UserBuffer, CollectionDescription->PreparsedData, CollectionDescription->PreparsedDataLength);
// //
// complete request // complete request
// //
Irp->IoStatus.Information = CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength; Irp->IoStatus.Information = CollectionDescription->PreparsedDataLength;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;

View file

@ -9,6 +9,58 @@
*/ */
#include "precomp.h" #include "precomp.h"
PHIDP_COLLECTION_DESC
HidClassPDO_GetCollectionDescription(
PHIDP_DEVICE_DESC DeviceDescription,
ULONG CollectionNumber)
{
ULONG Index;
for(Index = 0; Index < DeviceDescription->CollectionDescLength; Index++)
{
if (DeviceDescription->CollectionDesc[Index].CollectionNumber == CollectionNumber)
{
//
// found collection
//
return &DeviceDescription->CollectionDesc[Index];
}
}
//
// failed to find collection
//
DPRINT1("[HIDCLASS] GetCollectionDescription CollectionNumber %x not found\n", CollectionNumber);
ASSERT(FALSE);
return NULL;
}
PHIDP_REPORT_IDS
HidClassPDO_GetReportDescription(
PHIDP_DEVICE_DESC DeviceDescription,
ULONG CollectionNumber)
{
ULONG Index;
for(Index = 0; Index < DeviceDescription->ReportIDsLength; Index++)
{
if (DeviceDescription->ReportIDs[Index].CollectionNumber == CollectionNumber)
{
//
// found collection
//
return &DeviceDescription->ReportIDs[Index];
}
}
//
// failed to find collection
//
DPRINT1("[HIDCLASS] GetReportDescription CollectionNumber %x not found\n", CollectionNumber);
ASSERT(FALSE);
return NULL;
}
NTSTATUS NTSTATUS
HidClassPDO_HandleQueryDeviceId( HidClassPDO_HandleQueryDeviceId(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
@ -93,6 +145,7 @@ HidClassPDO_HandleQueryHardwareId(
WCHAR Buffer[100]; WCHAR Buffer[100];
ULONG Offset = 0; ULONG Offset = 0;
LPWSTR Ptr; LPWSTR Ptr;
PHIDP_COLLECTION_DESC CollectionDescription;
// //
// get device extension // get device extension
@ -117,15 +170,32 @@ HidClassPDO_HandleQueryHardwareId(
return Status; return Status;
} }
// if (PDODeviceExtension->Common.DeviceDescription.CollectionDescLength > 1)
// store hardware ids
//
Offset = swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x&Rev_%04x", PDODeviceExtension->Common.Attributes.VendorID, PDODeviceExtension->Common.Attributes.ProductID, PDODeviceExtension->Common.Attributes.VersionNumber) + 1;
Offset += swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x", PDODeviceExtension->Common.Attributes.VendorID, PDODeviceExtension->Common.Attributes.ProductID) + 1;
if (PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage == HID_USAGE_PAGE_GENERIC)
{ {
switch(PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage) //
// multi-tlc device
//
Offset = swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x&Rev_%04x&Col%02x", PDODeviceExtension->Common.Attributes.VendorID, PDODeviceExtension->Common.Attributes.ProductID, PDODeviceExtension->Common.Attributes.VersionNumber, PDODeviceExtension->CollectionNumber) + 1;
Offset += swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x&Col%02x", PDODeviceExtension->Common.Attributes.VendorID, PDODeviceExtension->Common.Attributes.ProductID, PDODeviceExtension->CollectionNumber) + 1;
}
else
{
//
// single tlc device
//
Offset = swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x&Rev_%04x", PDODeviceExtension->Common.Attributes.VendorID, PDODeviceExtension->Common.Attributes.ProductID, PDODeviceExtension->Common.Attributes.VersionNumber) + 1;
Offset += swprintf(&Buffer[Offset], L"HID\\Vid_%04x&Pid_%04x", PDODeviceExtension->Common.Attributes.VendorID, PDODeviceExtension->Common.Attributes.ProductID) + 1;
}
//
// get collection description
//
CollectionDescription = HidClassPDO_GetCollectionDescription(&PDODeviceExtension->Common.DeviceDescription, PDODeviceExtension->CollectionNumber);
ASSERT(CollectionDescription);
if (CollectionDescription->UsagePage == HID_USAGE_PAGE_GENERIC)
{
switch(CollectionDescription->Usage)
{ {
case HID_USAGE_GENERIC_POINTER: case HID_USAGE_GENERIC_POINTER:
case HID_USAGE_GENERIC_MOUSE: case HID_USAGE_GENERIC_MOUSE:
@ -156,7 +226,7 @@ HidClassPDO_HandleQueryHardwareId(
break; break;
} }
} }
else if (PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage == HID_USAGE_PAGE_CONSUMER && PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage == HID_USAGE_CONSUMERCTRL) else if (CollectionDescription->UsagePage == HID_USAGE_PAGE_CONSUMER && CollectionDescription->Usage == HID_USAGE_CONSUMERCTRL)
{ {
// //
// Consumer Audio Control // Consumer Audio Control
@ -501,12 +571,16 @@ HidClassPDO_PnP(
NTSTATUS NTSTATUS
HidClassPDO_CreatePDO( HidClassPDO_CreatePDO(
IN PDEVICE_OBJECT DeviceObject) IN PDEVICE_OBJECT DeviceObject,
OUT PDEVICE_RELATIONS *OutDeviceRelations)
{ {
PHIDCLASS_FDO_EXTENSION FDODeviceExtension; PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
NTSTATUS Status; NTSTATUS Status;
PDEVICE_OBJECT PDODeviceObject; PDEVICE_OBJECT PDODeviceObject;
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension; PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
ULONG Index;
PDEVICE_RELATIONS DeviceRelations;
ULONG Length;
// //
// get device extension // get device extension
@ -515,64 +589,121 @@ HidClassPDO_CreatePDO(
ASSERT(FDODeviceExtension->Common.IsFDO); ASSERT(FDODeviceExtension->Common.IsFDO);
// //
// lets create the device object // first allocate device relations
//
Length = sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * FDODeviceExtension->Common.DeviceDescription.CollectionDescLength;
DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, Length);
if (!DeviceRelations)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// zero device relations
//
RtlZeroMemory(DeviceRelations, Length);
//
// lets create a PDO for top level collection
//
Index = 0;
do
{
//
// 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 PDO %x\n", Status);
break;
}
//
// 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 = FDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject;
PDODeviceExtension->Common.IsFDO = FALSE;
PDODeviceExtension->FDODeviceObject = DeviceObject;
PDODeviceExtension->Common.DriverExtension = FDODeviceExtension->Common.DriverExtension;
PDODeviceExtension->CollectionNumber = FDODeviceExtension->Common.DeviceDescription.CollectionDesc[Index].CollectionNumber;
//
// copy device data
//
RtlCopyMemory(&PDODeviceExtension->Common.Attributes, &FDODeviceExtension->Common.Attributes, sizeof(HID_DEVICE_ATTRIBUTES));
RtlCopyMemory(&PDODeviceExtension->Common.DeviceDescription, &FDODeviceExtension->Common.DeviceDescription, sizeof(HIDP_DEVICE_DESC));
RtlCopyMemory(&PDODeviceExtension->Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
//
// set device flags
//
PDODeviceObject->Flags |= DO_MAP_IO_BUFFER;
//
// device is initialized
//
PDODeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
//
// store device object in device relations
//
DeviceRelations->Objects[Index] = PDODeviceObject;
DeviceRelations->Count++;
//
// move to next
//
Index++;
}while(Index < FDODeviceExtension->Common.DeviceDescription.CollectionDescLength);
//
// check if creating succeeded
// //
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)) if (!NT_SUCCESS(Status))
{ {
// //
// failed to create device // failed
// //
DPRINT1("[HIDCLASS] Failed to create device %x\n", Status); for(Index = 0; Index < DeviceRelations->Count; Index++)
{
//
// delete device
//
IoDeleteDevice(DeviceRelations->Objects[Index]);
}
//
// free device relations
//
ExFreePool(DeviceRelations);
return Status; return Status;
} }
// //
// patch stack size // store device relations
// //
PDODeviceObject->StackSize = DeviceObject->StackSize + 1; *OutDeviceRelations = DeviceRelations;
//
// 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 = FDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject;
PDODeviceExtension->Common.IsFDO = FALSE;
PDODeviceExtension->FDODeviceObject = DeviceObject;
PDODeviceExtension->Common.DriverExtension = FDODeviceExtension->Common.DriverExtension;
RtlCopyMemory(&PDODeviceExtension->Common.Attributes, &FDODeviceExtension->Common.Attributes, sizeof(HID_DEVICE_ATTRIBUTES));
RtlCopyMemory(&PDODeviceExtension->Common.DeviceDescription, &FDODeviceExtension->Common.DeviceDescription, sizeof(HIDP_DEVICE_DESC));
RtlCopyMemory(&PDODeviceExtension->Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
//
// FIXME: support composite devices
//
PDODeviceExtension->CollectionIndex = 0;
ASSERT(PDODeviceExtension->Common.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 // done

View file

@ -76,7 +76,7 @@ typedef struct
// //
// device relations // device relations
// //
DEVICE_RELATIONS DeviceRelations; PDEVICE_RELATIONS DeviceRelations;
}HIDCLASS_FDO_EXTENSION, *PHIDCLASS_FDO_EXTENSION; }HIDCLASS_FDO_EXTENSION, *PHIDCLASS_FDO_EXTENSION;
@ -95,7 +95,7 @@ typedef struct
// //
// collection index // collection index
// //
ULONG CollectionIndex; ULONG CollectionNumber;
// //
// device interface // device interface
@ -176,12 +176,22 @@ HidClassFDO_DispatchRequestSynchronous(
/* pdo.c */ /* pdo.c */
NTSTATUS NTSTATUS
HidClassPDO_CreatePDO( HidClassPDO_CreatePDO(
IN PDEVICE_OBJECT DeviceObject); IN PDEVICE_OBJECT DeviceObject,
OUT PDEVICE_RELATIONS *OutDeviceRelations);
NTSTATUS NTSTATUS
HidClassPDO_PnP( HidClassPDO_PnP(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp); IN PIRP Irp);
PHIDP_COLLECTION_DESC
HidClassPDO_GetCollectionDescription(
PHIDP_DEVICE_DESC DeviceDescription,
ULONG CollectionNumber);
PHIDP_REPORT_IDS
HidClassPDO_GetReportDescription(
PHIDP_DEVICE_DESC DeviceDescription,
ULONG CollectionNumber);
/* eof */ /* eof */