[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

svn path=/branches/usb-bringup/; revision=54791
This commit is contained in:
Johannes Anderwald 2011-12-31 03:33:14 +00:00
parent ef72bc2d72
commit a64411cfbf
5 changed files with 875 additions and 25 deletions

View file

@ -5,6 +5,7 @@ list(APPEND SOURCE
fdo.c
hidclass.c
hidclass.rc
pdo.c
${CMAKE_CURRENT_BINARY_DIR}/hidclass.def)
add_library(hidclass SHARED ${SOURCE})

View file

@ -145,7 +145,7 @@ HidClassFDO_DispatchRequestSynchronous(
IN PIRP Irp)
{
KEVENT Event;
PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
@ -157,8 +157,7 @@ HidClassFDO_DispatchRequestSynchronous(
//
// 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 @@ HidClassFDO_DispatchRequestSynchronous(
// 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
@ -392,14 +391,133 @@ HidClassFDO_RemoveDevice(
return STATUS_NOT_IMPLEMENTED;
}
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

View file

@ -83,7 +83,7 @@ HidClassAddDevice(
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 @@ HidClass_DeviceControl(
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 @@ HidClass_PnP(
CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// FIXME: support PDO
// check type of device object
//
ASSERT(CommonDeviceExtension->IsFDO == TRUE);
//
// handle request
//
return HidClassFDO_PnP(DeviceObject, Irp);
if (CommonDeviceExtension->IsFDO)
{
//
// handle request
//
return HidClassFDO_PnP(DeviceObject, Irp);
}
else
{
//
// handle request
//
return HidClassPDO_PnP(DeviceObject, Irp);
}
}
NTSTATUS

566
drivers/hid/hidclass/pdo.c Normal file
View file

@ -0,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 (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#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;
}

View file

@ -4,9 +4,13 @@
#include <ntddk.h>
#include <hidport.h>
#include <hidpddi.h>
#include <stdio.h>
#include <initguid.h>
#include <wdmguid.h>
#include <debug.h>
typedef struct
{
PDRIVER_OBJECT DriverObject;
@ -21,12 +25,23 @@ typedef struct
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
{
//
@ -34,11 +49,6 @@ typedef struct
//
HIDCLASS_COMMON_DEVICE_EXTENSION Common;
//
// driver extension
//
PHIDCLASS_DRIVER_EXTENSION DriverExtension;
//
// device capabilities
//
@ -64,8 +74,42 @@ typedef struct
//
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 */
NTSTATUS
@ -73,3 +117,20 @@ HidClassFDO_PnP(
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 */