From c671800d551f2013042dad8fd4ac7025394dbe65 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 30 Dec 2011 14:34:07 +0000 Subject: [PATCH] [USB-BRINGUP] - Rename device extension - Implement FDO Initialization (IRP_MN_START_DEVICE) svn path=/branches/usb-bringup/; revision=54787 --- drivers/hid/hidclass/CMakeLists.txt | 1 + drivers/hid/hidclass/fdo.c | 472 ++++++++++++++++++++++++++++ drivers/hid/hidclass/hidclass.c | 187 ++++++++++- drivers/hid/hidclass/precomp.h | 52 ++- 4 files changed, 697 insertions(+), 15 deletions(-) create mode 100644 drivers/hid/hidclass/fdo.c diff --git a/drivers/hid/hidclass/CMakeLists.txt b/drivers/hid/hidclass/CMakeLists.txt index b1f14d7db07..45af00a812a 100644 --- a/drivers/hid/hidclass/CMakeLists.txt +++ b/drivers/hid/hidclass/CMakeLists.txt @@ -2,6 +2,7 @@ spec2def(hidclass.sys hidclass.spec) list(APPEND SOURCE + fdo.c hidclass.c hidclass.rc ${CMAKE_CURRENT_BINARY_DIR}/hidclass.def) diff --git a/drivers/hid/hidclass/fdo.c b/drivers/hid/hidclass/fdo.c new file mode 100644 index 00000000000..294ac37eaf2 --- /dev/null +++ b/drivers/hid/hidclass/fdo.c @@ -0,0 +1,472 @@ +/* + * 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 +NTAPI +HidClassFDO_QueryCapabilitiesCompletionRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + // + // set event + // + KeSetEvent((PRKEVENT)Context, 0, FALSE); + + // + // completion is done in the HidClassFDO_QueryCapabilities routine + // + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +HidClassFDO_QueryCapabilities( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PDEVICE_CAPABILITIES Capabilities) +{ + PIRP Irp; + KEVENT Event; + NTSTATUS Status; + PIO_STACK_LOCATION IoStack; + PHIDCLASS_FDO_EXTENSION FDODeviceExtension; + + // + // get device extension + // + FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // init event + // + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + // + // now allocte the irp + // + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!Irp) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // get next stack location + // + IoStack = IoGetNextIrpStackLocation(Irp); + + // + // init stack location + // + IoStack->MajorFunction = IRP_MJ_PNP; + IoStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES; + IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities; + + // + // set completion routine + // + IoSetCompletionRoutine(Irp, HidClassFDO_QueryCapabilitiesCompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE); + + // + // init capabilities + // + RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES)); + Capabilities->Size = sizeof(DEVICE_CAPABILITIES); + Capabilities->Version = 1; // FIXME hardcoded constant + Capabilities->Address = MAXULONG; + Capabilities->UINumber = MAXULONG; + + // + // pnp irps have default completion code + // + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + // + // call lower device + // + Status = IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp); + if (Status == STATUS_PENDING) + { + // + // wait for completion + // + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + } + + // + // get status + // + Status = Irp->IoStatus.Status; + + // + // complete request + // + IoFreeIrp(Irp); + + // + // done + // + return Status; +} + +NTSTATUS +NTAPI +HidClassFDO_DispatchRequestSynchronousCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + // + // signal event + // + KeSetEvent((PRKEVENT)Context, 0, FALSE); + + // + // done + // + return STATUS_MORE_PROCESSING_REQUIRED; +} + + +NTSTATUS +HidClassFDO_DispatchRequestSynchronous( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + KEVENT Event; + PHIDCLASS_FDO_EXTENSION FDODeviceExtension; + NTSTATUS Status; + PIO_STACK_LOCATION IoStack; + + // + // init event + // + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + // + // get device extension + // + FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // set completion routine + // + IoSetCompletionRoutine(Irp, HidClassFDO_DispatchRequestSynchronousCompletion, &Event, TRUE, TRUE, TRUE); + + ASSERT(Irp->CurrentLocation > 0); + // + // create stack location + // + IoSetNextIrpStackLocation(Irp); + + // + // get next stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // store device object + // + IoStack->DeviceObject = DeviceObject; + + + + // + // call driver + // + DPRINT1("IoStack MajorFunction %x MinorFunction %x\n", IoStack->MajorFunction, IoStack->MinorFunction); + Status = FDODeviceExtension->DriverExtension->MajorFunction[IoStack->MajorFunction](DeviceObject, Irp); + + // + // wait for the request to finish + // + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + + // + // update status + // + Status = Irp->IoStatus.Status; + } + + // + // done + // + return Status; +} + +NTSTATUS +HidClassFDO_GetDescriptors( + IN PDEVICE_OBJECT DeviceObject) +{ + PHIDCLASS_FDO_EXTENSION FDODeviceExtension; + PIRP Irp; + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + // + // get device extension + // + FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // lets allocate irp + // + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!Irp) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // get stack location + // + IoStack = IoGetNextIrpStackLocation(Irp); + + // + // init stack location + // + IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_GET_DEVICE_DESCRIPTOR; + IoStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(HID_DESCRIPTOR); + IoStack->Parameters.DeviceIoControl.InputBufferLength = 0; + IoStack->Parameters.DeviceIoControl.Type3InputBuffer = NULL; + Irp->UserBuffer = &FDODeviceExtension->HidDescriptor; + + // + // send request + // + Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp); + if (!NT_SUCCESS(Status)) + { + // + // failed to get device descriptor + // + DPRINT1("[HIDCLASS] IOCTL_HID_GET_DEVICE_DESCRIPTOR failed with %x\n", Status); + IoFreeIrp(Irp); + return Status; + } + + // + // lets get device attributes + // + IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_GET_DEVICE_ATTRIBUTES; + IoStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(HID_DEVICE_ATTRIBUTES); + Irp->UserBuffer = &FDODeviceExtension->Attributes; + + // + // send request + // + Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp); + if (!NT_SUCCESS(Status)) + { + // + // failed to get device descriptor + // + DPRINT1("[HIDCLASS] IOCTL_HID_GET_DEVICE_ATTRIBUTES failed with %x\n", Status); + IoFreeIrp(Irp); + return Status; + } + + // + // sanity checks + // + ASSERT(FDODeviceExtension->HidDescriptor.bLength == sizeof(HID_DESCRIPTOR)); + ASSERT(FDODeviceExtension->HidDescriptor.bNumDescriptors > 0); + ASSERT(FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength > 0); + ASSERT(FDODeviceExtension->HidDescriptor.DescriptorList[0].bReportType == HID_REPORT_DESCRIPTOR_TYPE); + + + // + // now allocate space for the report descriptor + // + FDODeviceExtension->ReportDescriptor = (PUCHAR)ExAllocatePool(NonPagedPool, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength); + if (!FDODeviceExtension->ReportDescriptor) + { + // + // not enough memory + // + IoFreeIrp(Irp); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // init stack location + // + IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_GET_REPORT_DESCRIPTOR; + IoStack->Parameters.DeviceIoControl.OutputBufferLength = FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength; + Irp->UserBuffer = FDODeviceExtension->ReportDescriptor; + + // + // send request + // + Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp); + if (!NT_SUCCESS(Status)) + { + // + // failed to get device descriptor + // + DPRINT1("[HIDCLASS] IOCTL_HID_GET_REPORT_DESCRIPTOR failed with %x\n", Status); + IoFreeIrp(Irp); + return Status; + } + + // + // completed successfully + // + return STATUS_SUCCESS; +} + + +NTSTATUS +HidClassFDO_StartDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + NTSTATUS Status; + PHIDCLASS_FDO_EXTENSION FDODeviceExtension; + + // + // get device extension + // + FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // query capabilities + // + Status = HidClassFDO_QueryCapabilities(DeviceObject, &FDODeviceExtension->Capabilities); + ASSERT(Status == STATUS_SUCCESS); + + // + // lets start the lower device too + // + IoCopyCurrentIrpStackLocationToNext(Irp); + Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp); + ASSERT(Status == STATUS_SUCCESS); + + // + // lets get the descriptors + // + Status = HidClassFDO_GetDescriptors(DeviceObject); + ASSERT(Status == STATUS_SUCCESS); + + // + // now get the the collection description + // + Status = HidP_GetCollectionDescription(FDODeviceExtension->ReportDescriptor, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength, NonPagedPool, &FDODeviceExtension->DeviceDescription); + ASSERT(Status == STATUS_SUCCESS); + + // + // complete request + // + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +NTSTATUS +HidClassFDO_RemoveDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +HidClassFDO_DeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +HidClassFDO_PnP( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PHIDCLASS_FDO_EXTENSION FDODeviceExtension; + + // + // get device extension + // + FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // get current irp stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + switch(IoStack->MinorFunction) + { + case IRP_MN_START_DEVICE: + { + return HidClassFDO_StartDevice(DeviceObject, Irp); + } + case IRP_MN_REMOVE_DEVICE: + { + return HidClassFDO_RemoveDevice(DeviceObject, Irp); + } + case IRP_MN_QUERY_STOP_DEVICE: + { + // + // set status to succes + // + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // forward to lower device + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp); + } + case IRP_MN_CANCEL_STOP_DEVICE: + { + // + // set status to succes + // + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // forward to lower device + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp); + } + case IRP_MN_QUERY_DEVICE_RELATIONS: + { + return HidClassFDO_DeviceRelations(DeviceObject, Irp); + } + default: + { + // + // dispatch to lower device + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp); + } + } +} diff --git a/drivers/hid/hidclass/hidclass.c b/drivers/hid/hidclass/hidclass.c index db03ad9684f..9ed5e52f080 100644 --- a/drivers/hid/hidclass/hidclass.c +++ b/drivers/hid/hidclass/hidclass.c @@ -37,7 +37,7 @@ HidClassAddDevice( NTSTATUS Status; UNICODE_STRING DeviceName; PDEVICE_OBJECT NewDeviceObject; - PHIDCLASS_DEVICE_EXTENSION DeviceExtension; + PHIDCLASS_FDO_EXTENSION FDODeviceExtension; ULONG DeviceExtensionSize; PHIDCLASS_DRIVER_EXTENSION DriverExtension; @@ -61,7 +61,7 @@ HidClassAddDevice( } /* calculate device extension size */ - DeviceExtensionSize = sizeof(HIDCLASS_DEVICE_EXTENSION) + DriverExtension->DeviceExtensionSize; + DeviceExtensionSize = sizeof(HIDCLASS_FDO_EXTENSION) + DriverExtension->DeviceExtensionSize; /* now create the device */ Status = IoCreateDevice(DriverObject, DeviceExtensionSize, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &NewDeviceObject); @@ -73,20 +73,20 @@ HidClassAddDevice( } /* get device extension */ - DeviceExtension = (PHIDCLASS_DEVICE_EXTENSION)NewDeviceObject->DeviceExtension; + FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)NewDeviceObject->DeviceExtension; /* zero device extension */ - RtlZeroMemory(DeviceExtension, sizeof(HIDCLASS_DEVICE_EXTENSION)); + RtlZeroMemory(FDODeviceExtension, sizeof(HIDCLASS_FDO_EXTENSION)); /* initialize device extension */ - DeviceExtension->HidDeviceExtension.PhysicalDeviceObject = PhysicalDeviceObject; - DeviceExtension->HidDeviceExtension.MiniDeviceExtension = (PVOID)((ULONG_PTR)DeviceExtension + sizeof(HIDCLASS_DEVICE_EXTENSION)); - DeviceExtension->HidDeviceExtension.NextDeviceObject = IoAttachDeviceToDeviceStack(NewDeviceObject, PhysicalDeviceObject); - DeviceExtension->IsFDO = TRUE; - DeviceExtension->DriverExtension = DriverExtension; + FDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject = PhysicalDeviceObject; + 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; /* sanity check */ - ASSERT(DeviceExtension->HidDeviceExtension.NextDeviceObject); + ASSERT(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject); /* increment stack size */ NewDeviceObject->StackSize++; @@ -102,7 +102,7 @@ HidClassAddDevice( { /* failed */ DPRINT1("HIDCLASS: AddDevice failed with %x\n", Status); - IoDetachDevice(DeviceExtension->HidDeviceExtension.NextDeviceObject); + IoDetachDevice(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject); IoDeleteDevice(NewDeviceObject); return Status; } @@ -122,7 +122,7 @@ HidClassDriverUnload( NTSTATUS NTAPI -HidClassDispatch( +HidClass_Create( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { @@ -131,6 +131,167 @@ HidClassDispatch( return STATUS_NOT_IMPLEMENTED; } +NTSTATUS +NTAPI +HidClass_Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +HidClass_Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +HidClass_Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +HidClass_DeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +HidClass_InternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +NTAPI +HidClass_Power( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +HidClass_PnP( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension; + + // + // get common device extension + // + CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // FIXME: support PDO + // + ASSERT(CommonDeviceExtension->IsFDO == TRUE); + + // + // handle request + // + return HidClassFDO_PnP(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +HidClass_DispatchDefault( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension; + + // + // get common device extension + // + CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // FIXME: support PDO + // + ASSERT(CommonDeviceExtension->IsFDO == TRUE); + + // + // skip current irp stack location + // + IoSkipCurrentIrpStackLocation(Irp); + + // + // dispatch to lower device object + // + return IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, Irp); +} + + +NTSTATUS +NTAPI +HidClassDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + DPRINT1("[HIDCLASS] Dispatch Major %x Minor %x\n", IoStack->MajorFunction, IoStack->MinorFunction); + + // + // dispatch request based on major function + // + switch(IoStack->MajorFunction) + { + case IRP_MJ_CREATE: + return HidClass_Create(DeviceObject, Irp); + case IRP_MJ_CLOSE: + return HidClass_Close(DeviceObject, Irp); + case IRP_MJ_READ: + return HidClass_Read(DeviceObject, Irp); + case IRP_MJ_WRITE: + return HidClass_Write(DeviceObject, Irp); + case IRP_MJ_DEVICE_CONTROL: + return HidClass_DeviceControl(DeviceObject, Irp); + case IRP_MJ_INTERNAL_DEVICE_CONTROL: + return HidClass_InternalDeviceControl(DeviceObject, Irp); + case IRP_MJ_POWER: + return HidClass_Power(DeviceObject, Irp); + case IRP_MJ_PNP: + return HidClass_PnP(DeviceObject, Irp); + default: + return HidClass_DispatchDefault(DeviceObject, Irp); + } +} + NTSTATUS NTAPI HidRegisterMinidriver( @@ -167,7 +328,7 @@ HidRegisterMinidriver( DriverExtension->DriverUnload = MinidriverRegistration->DriverObject->DriverUnload; /* copy driver dispatch routines */ - RtlCopyMemory(DriverExtension->MajorFunction, MinidriverRegistration->DriverObject->MajorFunction, sizeof(PDRIVER_DISPATCH) * IRP_MJ_MAXIMUM_FUNCTION); + RtlCopyMemory(DriverExtension->MajorFunction, MinidriverRegistration->DriverObject->MajorFunction, sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION+1)); /* initialize lock */ KeInitializeSpinLock(&DriverExtension->Lock); diff --git a/drivers/hid/hidclass/precomp.h b/drivers/hid/hidclass/precomp.h index 20f771e23ff..f099a4e0917 100644 --- a/drivers/hid/hidclass/precomp.h +++ b/drivers/hid/hidclass/precomp.h @@ -3,6 +3,7 @@ #define _HIDPI_NO_FUNCTION_MACROS_ #include #include +#include #include @@ -11,7 +12,7 @@ typedef struct PDRIVER_OBJECT DriverObject; ULONG DeviceExtensionSize; BOOLEAN DevicesArePolled; - PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION]; + PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; PDRIVER_ADD_DEVICE AddDevice; PDRIVER_UNLOAD DriverUnload; KSPIN_LOCK Lock; @@ -22,6 +23,53 @@ typedef struct { HID_DEVICE_EXTENSION HidDeviceExtension; BOOLEAN IsFDO; +}HIDCLASS_COMMON_DEVICE_EXTENSION, *PHIDCLASS_COMMON_DEVICE_EXTENSION; + + + +typedef struct +{ + // + // parts shared by fdo and pdo + // + HIDCLASS_COMMON_DEVICE_EXTENSION Common; + + // + // driver extension + // PHIDCLASS_DRIVER_EXTENSION DriverExtension; -}HIDCLASS_DEVICE_EXTENSION, *PHIDCLASS_DEVICE_EXTENSION; \ No newline at end of file + // + // device capabilities + // + DEVICE_CAPABILITIES Capabilities; + + // + // hid descriptor + // + HID_DESCRIPTOR HidDescriptor; + + // + // hid attributes + // + HID_DEVICE_ATTRIBUTES Attributes; + + // + // report descriptor + // + PUCHAR ReportDescriptor; + + // + // device description + // + HIDP_DEVICE_DESC DeviceDescription; + +}HIDCLASS_FDO_EXTENSION, *PHIDCLASS_FDO_EXTENSION; + + +/* fdo.c */ +NTSTATUS +HidClassFDO_PnP( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); +