mirror of
https://github.com/reactos/reactos.git
synced 2025-04-29 01:48:42 +00:00
[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:
parent
842fe995ce
commit
07ae01f96c
4 changed files with 277 additions and 94 deletions
|
@ -180,8 +180,6 @@ HidClassFDO_DispatchRequestSynchronous(
|
|||
//
|
||||
IoStack->DeviceObject = DeviceObject;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// call driver
|
||||
//
|
||||
|
@ -409,7 +407,7 @@ HidClassFDO_CopyDeviceRelations(
|
|||
//
|
||||
// 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)
|
||||
{
|
||||
//
|
||||
|
@ -422,24 +420,23 @@ HidClassFDO_CopyDeviceRelations(
|
|||
//
|
||||
// copy device objects
|
||||
//
|
||||
for(Index = 0; Index < FDODeviceExtension->DeviceRelations.Count; Index++)
|
||||
for(Index = 0; Index < FDODeviceExtension->DeviceRelations->Count; Index++)
|
||||
{
|
||||
//
|
||||
// reference pdo
|
||||
//
|
||||
ObReferenceObject(FDODeviceExtension->DeviceRelations.Objects[Index]);
|
||||
ObReferenceObject(FDODeviceExtension->DeviceRelations->Objects[Index]);
|
||||
|
||||
//
|
||||
// store object
|
||||
//
|
||||
DeviceRelations->Objects[Index] = FDODeviceExtension->DeviceRelations.Objects[Index];
|
||||
DeviceRelations->Objects[Index] = FDODeviceExtension->DeviceRelations->Objects[Index];
|
||||
}
|
||||
|
||||
//
|
||||
// set object count
|
||||
//
|
||||
DeviceRelations->Count = FDODeviceExtension->DeviceRelations.Count;
|
||||
|
||||
DeviceRelations->Count = FDODeviceExtension->DeviceRelations->Count;
|
||||
|
||||
//
|
||||
// store result
|
||||
|
@ -481,12 +478,12 @@ HidClassFDO_DeviceRelations(
|
|||
return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
|
||||
}
|
||||
|
||||
if (FDODeviceExtension->DeviceRelations.Count == 0)
|
||||
if (FDODeviceExtension->DeviceRelations == NULL)
|
||||
{
|
||||
//
|
||||
// time to create the pdos
|
||||
//
|
||||
Status = HidClassPDO_CreatePDO(DeviceObject);
|
||||
Status = HidClassPDO_CreatePDO(DeviceObject, &FDODeviceExtension->DeviceRelations);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
|
@ -500,7 +497,7 @@ HidClassFDO_DeviceRelations(
|
|||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(FDODeviceExtension->DeviceRelations.Count > 0);
|
||||
ASSERT(FDODeviceExtension->DeviceRelations->Count > 0);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -304,8 +304,8 @@ HidClass_ReadCompleteIrp(
|
|||
KIRQL OldLevel;
|
||||
PUCHAR Address;
|
||||
ULONG Offset;
|
||||
PHIDP_DEVICE_DESC DeviceDescription;
|
||||
ULONG CollectionIndex;
|
||||
PHIDP_COLLECTION_DESC CollectionDescription;
|
||||
PHIDP_REPORT_IDS ReportDescription;
|
||||
|
||||
//
|
||||
// get irp context
|
||||
|
@ -328,20 +328,34 @@ HidClass_ReadCompleteIrp(
|
|||
//
|
||||
// get address
|
||||
//
|
||||
Address = HidClass_GetSystemAddress(IrpContext->OriginalIrp->MdlAddress);
|
||||
Address = (PUCHAR)HidClass_GetSystemAddress(IrpContext->OriginalIrp->MdlAddress);
|
||||
if (Address)
|
||||
{
|
||||
//
|
||||
// reports may have a report id prepended
|
||||
//
|
||||
CollectionIndex = IrpContext->FileOp->DeviceExtension->CollectionIndex;
|
||||
DeviceDescription = &IrpContext->FileOp->DeviceExtension->Common.DeviceDescription;
|
||||
Offset = 0;
|
||||
|
||||
//
|
||||
// calculate offset
|
||||
// get collection description
|
||||
//
|
||||
ASSERT(DeviceDescription->CollectionDesc[CollectionIndex].InputLength >= DeviceDescription->ReportIDs[CollectionIndex].InputLength);
|
||||
Offset = DeviceDescription->CollectionDesc[CollectionIndex].InputLength - DeviceDescription->ReportIDs[CollectionIndex].InputLength;
|
||||
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);
|
||||
|
||||
if (CollectionDescription && ReportDescription)
|
||||
{
|
||||
//
|
||||
// calculate offset
|
||||
//
|
||||
ASSERT(CollectionDescription->InputLength >= ReportDescription->InputLength);
|
||||
Offset = CollectionDescription->InputLength - ReportDescription->InputLength;
|
||||
}
|
||||
|
||||
//
|
||||
// copy result
|
||||
|
@ -451,6 +465,8 @@ HidClass_BuildIrp(
|
|||
PIO_STACK_LOCATION IoStack;
|
||||
PHIDCLASS_IRP_CONTEXT IrpContext;
|
||||
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PHIDP_COLLECTION_DESC CollectionDescription;
|
||||
PHIDP_REPORT_IDS ReportDescription;
|
||||
|
||||
//
|
||||
// get an irp from fresh list
|
||||
|
@ -497,22 +513,35 @@ HidClass_BuildIrp(
|
|||
PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
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
|
||||
//
|
||||
RtlZeroMemory(IrpContext, sizeof(HIDCLASS_IRP_CONTEXT));
|
||||
IrpContext->InputReportBufferLength = PDODeviceExtension->Common.DeviceDescription.ReportIDs[PDODeviceExtension->CollectionIndex].InputLength;
|
||||
IrpContext->OriginalIrp = RequestIrp;
|
||||
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
|
||||
//
|
||||
|
@ -677,11 +706,19 @@ HidClass_DeviceControl(
|
|||
PIO_STACK_LOCATION IoStack;
|
||||
PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
|
||||
PHID_COLLECTION_INFORMATION CollectionInformation;
|
||||
PHIDP_COLLECTION_DESC CollectionDescription;
|
||||
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
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
|
||||
|
@ -711,10 +748,16 @@ HidClass_DeviceControl(
|
|||
CollectionInformation = (PHID_COLLECTION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
|
||||
ASSERT(CollectionInformation);
|
||||
|
||||
//
|
||||
// get collection description
|
||||
//
|
||||
CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription, PDODeviceExtension->CollectionNumber);
|
||||
ASSERT(CollectionDescription);
|
||||
|
||||
//
|
||||
// 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->VendorID = CommonDeviceExtension->Attributes.VendorID;
|
||||
CollectionInformation->ProductID = CommonDeviceExtension->Attributes.ProductID;
|
||||
|
@ -731,13 +774,15 @@ HidClass_DeviceControl(
|
|||
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
|
||||
//
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength)
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < CollectionDescription->PreparsedDataLength)
|
||||
{
|
||||
//
|
||||
// invalid buffer size
|
||||
|
@ -751,12 +796,12 @@ HidClass_DeviceControl(
|
|||
// copy result
|
||||
//
|
||||
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
|
||||
//
|
||||
Irp->IoStatus.Information = CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength;
|
||||
Irp->IoStatus.Information = CollectionDescription->PreparsedDataLength;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -9,6 +9,58 @@
|
|||
*/
|
||||
#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
|
||||
HidClassPDO_HandleQueryDeviceId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -93,6 +145,7 @@ HidClassPDO_HandleQueryHardwareId(
|
|||
WCHAR Buffer[100];
|
||||
ULONG Offset = 0;
|
||||
LPWSTR Ptr;
|
||||
PHIDP_COLLECTION_DESC CollectionDescription;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
|
@ -117,15 +170,32 @@ HidClassPDO_HandleQueryHardwareId(
|
|||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// 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)
|
||||
if (PDODeviceExtension->Common.DeviceDescription.CollectionDescLength > 1)
|
||||
{
|
||||
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_MOUSE:
|
||||
|
@ -156,7 +226,7 @@ HidClassPDO_HandleQueryHardwareId(
|
|||
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
|
||||
|
@ -501,12 +571,16 @@ HidClassPDO_PnP(
|
|||
|
||||
NTSTATUS
|
||||
HidClassPDO_CreatePDO(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT PDEVICE_RELATIONS *OutDeviceRelations)
|
||||
{
|
||||
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
|
||||
NTSTATUS Status;
|
||||
PDEVICE_OBJECT PDODeviceObject;
|
||||
PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
ULONG Index;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
ULONG Length;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
|
@ -515,64 +589,121 @@ HidClassPDO_CreatePDO(
|
|||
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))
|
||||
{
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
//
|
||||
// patch stack size
|
||||
// store device relations
|
||||
//
|
||||
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;
|
||||
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);
|
||||
*OutDeviceRelations = DeviceRelations;
|
||||
|
||||
//
|
||||
// done
|
||||
|
|
|
@ -76,7 +76,7 @@ typedef struct
|
|||
//
|
||||
// device relations
|
||||
//
|
||||
DEVICE_RELATIONS DeviceRelations;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
|
||||
}HIDCLASS_FDO_EXTENSION, *PHIDCLASS_FDO_EXTENSION;
|
||||
|
||||
|
@ -95,7 +95,7 @@ typedef struct
|
|||
//
|
||||
// collection index
|
||||
//
|
||||
ULONG CollectionIndex;
|
||||
ULONG CollectionNumber;
|
||||
|
||||
//
|
||||
// device interface
|
||||
|
@ -176,12 +176,22 @@ HidClassFDO_DispatchRequestSynchronous(
|
|||
/* pdo.c */
|
||||
NTSTATUS
|
||||
HidClassPDO_CreatePDO(
|
||||
IN PDEVICE_OBJECT DeviceObject);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT PDEVICE_RELATIONS *OutDeviceRelations);
|
||||
|
||||
NTSTATUS
|
||||
HidClassPDO_PnP(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue