From f687f32e693cd55f3173476fbc7f9a8989f50337 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 31 Dec 2011 19:09:26 +0000 Subject: [PATCH] [USB-BRINGUP] - Move attributes / device description to common struct - Partly implement IRP_MJ_CREATE, IRP_MJ_CLOSE, IRP_MJ_READ svn path=/branches/usb-bringup/; revision=54798 --- drivers/hid/hidclass/fdo.c | 6 +- drivers/hid/hidclass/hidclass.c | 414 ++++++++++++++++++++++++++++++-- drivers/hid/hidclass/pdo.c | 16 +- drivers/hid/hidclass/precomp.h | 85 +++++-- 4 files changed, 465 insertions(+), 56 deletions(-) diff --git a/drivers/hid/hidclass/fdo.c b/drivers/hid/hidclass/fdo.c index 80157b71d79..5f5463d5fb1 100644 --- a/drivers/hid/hidclass/fdo.c +++ b/drivers/hid/hidclass/fdo.c @@ -268,7 +268,7 @@ HidClassFDO_GetDescriptors( // IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_GET_DEVICE_ATTRIBUTES; IoStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(HID_DEVICE_ATTRIBUTES); - Irp->UserBuffer = &FDODeviceExtension->Attributes; + Irp->UserBuffer = &FDODeviceExtension->Common.Attributes; // // send request @@ -357,7 +357,7 @@ HidClassFDO_StartDevice( // // lets start the lower device too // - IoCopyCurrentIrpStackLocationToNext(Irp); + IoSkipCurrentIrpStackLocation(Irp); Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp); ASSERT(Status == STATUS_SUCCESS); @@ -370,7 +370,7 @@ HidClassFDO_StartDevice( // // now get the the collection description // - Status = HidP_GetCollectionDescription(FDODeviceExtension->ReportDescriptor, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength, NonPagedPool, &FDODeviceExtension->DeviceDescription); + Status = HidP_GetCollectionDescription(FDODeviceExtension->ReportDescriptor, FDODeviceExtension->HidDescriptor.DescriptorList[0].wReportLength, NonPagedPool, &FDODeviceExtension->Common.DeviceDescription); ASSERT(Status == STATUS_SUCCESS); // diff --git a/drivers/hid/hidclass/hidclass.c b/drivers/hid/hidclass/hidclass.c index 9b3c3610d77..caf6052544c 100644 --- a/drivers/hid/hidclass/hidclass.c +++ b/drivers/hid/hidclass/hidclass.c @@ -126,11 +126,80 @@ HidClass_Create( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED - ASSERT(FALSE); - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + PIO_STACK_LOCATION IoStack; + PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension; + PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension; + PHIDCLASS_FILEOP_CONTEXT Context; + + // + // get device extension + // + CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + if (CommonDeviceExtension->IsFDO) + { + // + // only supported for PDO + // + DPRINT1("[HIDCLASS] IRP_MJ_CREATE for FDO\n"); + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + + // + // must be a PDO + // + ASSERT(CommonDeviceExtension->IsFDO == FALSE); + + // + // get device extension + // + PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)CommonDeviceExtension; + + // + // get stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT1("ShareAccess %x\n", IoStack->Parameters.Create.ShareAccess); + DPRINT1("Options %x\n", IoStack->Parameters.Create.Options); + DPRINT1("DesiredAccess %x\n", IoStack->Parameters.Create.SecurityContext->DesiredAccess); + + // + // allocate context + // + Context = (PHIDCLASS_FILEOP_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(HIDCLASS_FILEOP_CONTEXT)); + if (!Context) + { + // + // no memory + // + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // init context + // + RtlZeroMemory(Context, sizeof(HIDCLASS_FILEOP_CONTEXT)); + Context->DeviceExtension = PDODeviceExtension; + KeInitializeSpinLock(&Context->Lock); + InitializeListHead(&Context->ReadPendingIrpListHead); + InitializeListHead(&Context->IrpCompletedListHead); + + // + // store context + // + ASSERT(IoStack->FileObject); + IoStack->FileObject->FsContext = (PVOID)Context; + + // + // done + // + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; + return STATUS_SUCCESS; } NTSTATUS @@ -139,24 +208,327 @@ HidClass_Close( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + PIO_STACK_LOCATION IoStack; + PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension; + PHIDCLASS_IRP_CONTEXT IrpContext; + + // + // get device extension + // + CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // is it a FDO request + // + if (CommonDeviceExtension->IsFDO) + { + // + // how did the request get there + // + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER_1; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INVALID_PARAMETER_1; + } + + // + // get stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // sanity checks + // + ASSERT(IoStack->FileObject); + ASSERT(IoStack->FileObject->FsContext); + + // + // get irp context + // + IrpContext = (PHIDCLASS_IRP_CONTEXT)IoStack->FileObject->FsContext; + + // + // cancel pending irps + // UNIMPLEMENTED - ASSERT(FALSE); - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + + // + // remove context + // + IoStack->FileObject->FsContext = NULL; + + // + // free context + // + ExFreePool(IrpContext); + + // + // complete request + // + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; + return STATUS_SUCCESS; } +NTSTATUS +NTAPI +HidClass_ReadCompleteIrp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Ctx) +{ + PHIDCLASS_IRP_CONTEXT IrpContext; + KIRQL OldLevel; + + // + // get irp context + // + IrpContext = (PHIDCLASS_IRP_CONTEXT)Ctx; + + DPRINT1("HidClass_ReadCompleteIrp Irql %lu\n", KeGetCurrentIrql()); + DPRINT1("HidClass_ReadCompleteIrp Status %lx\n", Irp->IoStatus.Status); + DPRINT1("HidClass_ReadCompleteIrp Length %lu\n", Irp->IoStatus.Information); + DPRINT1("HidClass_ReadCompleteIrp Irp %p\n", Irp); + DPRINT1("HidClass_ReadCompleteIrp InputReportBuffer %p\n", IrpContext->InputReportBuffer); + DPRINT1("HidClass_ReadCompleteIrp InputReportBufferLength %li\n", IrpContext->InputReportBufferLength); + DPRINT1("HidClass_ReadCompleteIrp OriginalIrp %p\n", IrpContext->OriginalIrp); + + // + // copy result + // + if (Irp->IoStatus.Information) + { + // + // copy result + // + RtlCopyMemory(IrpContext->OriginalIrp->UserBuffer, IrpContext->InputReportBuffer, IrpContext->InputReportBufferLength); + } + + // + // copy result status + // + IrpContext->OriginalIrp->IoStatus.Status = Irp->IoStatus.Status; + Irp->IoStatus.Information = Irp->IoStatus.Information; + + // + // free input report buffer + // + ExFreePool(IrpContext->InputReportBuffer); + + // + // complete original request + // + IoCompleteRequest(IrpContext->OriginalIrp, IO_NO_INCREMENT); + + // + // remove us from pending list + // + KeAcquireSpinLock(&IrpContext->FileOp->Lock, &OldLevel); + + // + // remove from pending list + // + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + + // + // release lock + // + KeReleaseSpinLock(&IrpContext->FileOp->Lock, OldLevel); + + // + // free irp context + // + ExFreePool(IrpContext); + + // + // done + // + return STATUS_SUCCESS; +} + +NTSTATUS +HidClass_BuildIrp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP RequestIrp, + IN PHIDCLASS_FILEOP_CONTEXT Context, + IN ULONG DeviceIoControlCode, + IN ULONG BufferLength, + OUT PIRP *OutIrp, + OUT PHIDCLASS_IRP_CONTEXT *OutIrpContext) +{ + PIRP Irp; + PIO_STACK_LOCATION IoStack; + PHIDCLASS_IRP_CONTEXT IrpContext; + + // + // build new irp + // + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!Irp) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // allocate completion context + // + IrpContext = (PHIDCLASS_IRP_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(HIDCLASS_IRP_CONTEXT)); + if (!IrpContext) + { + // + // no memory + // + IoFreeIrp(Irp); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // init irp context + // + RtlZeroMemory(IrpContext, sizeof(HIDCLASS_IRP_CONTEXT)); + IrpContext->InputReportBufferLength = BufferLength; + IrpContext->OriginalIrp = RequestIrp; + IrpContext->FileOp = Context; + + // + // allocate buffer + // + IrpContext->InputReportBuffer = ExAllocatePool(NonPagedPool, BufferLength); + if (!IrpContext->InputReportBuffer) + { + // + // no memory + // + IoFreeIrp(Irp); + ExFreePool(IrpContext); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // get stack location + // + IoStack = IoGetNextIrpStackLocation(Irp); + + // + // init stack location + // + IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IoStack->Parameters.DeviceIoControl.IoControlCode = DeviceIoControlCode; + IoStack->Parameters.DeviceIoControl.OutputBufferLength = IrpContext->InputReportBufferLength; + IoStack->Parameters.DeviceIoControl.InputBufferLength = 0; + IoStack->Parameters.DeviceIoControl.Type3InputBuffer = NULL; + Irp->UserBuffer = IrpContext->InputReportBuffer; + IoStack->DeviceObject = DeviceObject; + + // + // store result + // + *OutIrp = Irp; + *OutIrpContext = IrpContext; + + DPRINT1("IRP %p Buffer %p\n", Irp, Irp->UserBuffer); + + // + // done + // + return STATUS_SUCCESS; +} + + NTSTATUS NTAPI HidClass_Read( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED - ASSERT(FALSE); - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; + PIO_STACK_LOCATION IoStack; + PHIDCLASS_FILEOP_CONTEXT Context; + KIRQL OldLevel; + NTSTATUS Status; + PIRP NewIrp; + PHIDCLASS_IRP_CONTEXT NewIrpContext; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // sanity check + // + ASSERT(IoStack->FileObject); + ASSERT(IoStack->FileObject->FsContext); + + // + // get context + // + Context = (PHIDCLASS_FILEOP_CONTEXT)IoStack->FileObject->FsContext; + ASSERT(Context); + + // + // FIXME support polled devices + // + ASSERT(Context->DeviceExtension->Common.DriverExtension->DevicesArePolled == FALSE); + + DPRINT1("[HIDCLASS] IRP_MJ_READ\n"); + + // + // build irp request + // + Status = HidClass_BuildIrp(DeviceObject, Irp, Context, IOCTL_HID_READ_REPORT, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &NewIrp, &NewIrpContext); + if (!NT_SUCCESS(Status)) + { + // + // failed + // + DPRINT1("HidClass_BuildIrp failed with %x\n", Status); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + // + // acquire lock + // + KeAcquireSpinLock(&Context->Lock, &OldLevel); + + // + // insert irp into pending list + // + InsertTailList(&Context->ReadPendingIrpListHead, &NewIrp->Tail.Overlay.ListEntry); + + // + // set completion routine + // + IoSetCompletionRoutine(NewIrp, HidClass_ReadCompleteIrp, NewIrpContext, TRUE, TRUE, TRUE); + + // + // make next location current + // + IoSetNextIrpStackLocation(NewIrp); + + // + // release spin lock + // + KeReleaseSpinLock(&Context->Lock, OldLevel); + + // + // mark irp pending + // + IoMarkIrpPending(Irp); + + // + // lets dispatch the request + // + ASSERT(Context->DeviceExtension); + Status = Context->DeviceExtension->Common.DriverExtension->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL](DeviceObject, NewIrp); + + // + // complete + // + return Status; } NTSTATUS @@ -181,14 +553,11 @@ HidClass_DeviceControl( 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 @@ -221,11 +590,11 @@ HidClass_DeviceControl( // // init result buffer // - CollectionInformation->DescriptorSize = PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength; //FIXME which collection is to be retrieved for composite devices / multi collection devices? + CollectionInformation->DescriptorSize = CommonDeviceExtension->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; + CollectionInformation->VendorID = CommonDeviceExtension->Attributes.VendorID; + CollectionInformation->ProductID = CommonDeviceExtension->Attributes.ProductID; + CollectionInformation->VersionNumber = CommonDeviceExtension->Attributes.VersionNumber; // // complete request @@ -244,7 +613,7 @@ HidClass_DeviceControl( // // check if output buffer is big enough // - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength) + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength) { // // invalid buffer size @@ -258,12 +627,12 @@ HidClass_DeviceControl( // copy result // ASSERT(Irp->UserBuffer); - RtlCopyMemory(Irp->UserBuffer, PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedData, PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength); + RtlCopyMemory(Irp->UserBuffer, CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedData, CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength); // // complete request // - Irp->IoStatus.Information = PDODeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength; + Irp->IoStatus.Information = CommonDeviceExtension->DeviceDescription.CollectionDesc[0].PreparsedDataLength; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; @@ -271,7 +640,6 @@ HidClass_DeviceControl( 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; diff --git a/drivers/hid/hidclass/pdo.c b/drivers/hid/hidclass/pdo.c index 469e37a57f3..aa72daac63a 100644 --- a/drivers/hid/hidclass/pdo.c +++ b/drivers/hid/hidclass/pdo.c @@ -120,12 +120,12 @@ HidClassPDO_HandleQueryHardwareId( // // 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; + 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->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage == HID_USAGE_PAGE_GENERIC) + if (PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage == HID_USAGE_PAGE_GENERIC) { - switch(PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage) + switch(PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage) { case HID_USAGE_GENERIC_POINTER: case HID_USAGE_GENERIC_MOUSE: @@ -156,7 +156,7 @@ HidClassPDO_HandleQueryHardwareId( break; } } - else if (PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage == HID_USAGE_PAGE_CONSUMER && PDODeviceExtension->DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage == HID_USAGE_CONSUMERCTRL) + else if (PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].UsagePage == HID_USAGE_PAGE_CONSUMER && PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].Usage == HID_USAGE_CONSUMERCTRL) { // // Consumer Audio Control @@ -545,15 +545,15 @@ HidClassPDO_CreatePDO( PDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject = FDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject; 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->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->DeviceDescription.CollectionDescLength == 1); + ASSERT(PDODeviceExtension->Common.DeviceDescription.CollectionDescLength == 1); // // store in device relations struct diff --git a/drivers/hid/hidclass/precomp.h b/drivers/hid/hidclass/precomp.h index 6babfb75fdc..20b8e927370 100644 --- a/drivers/hid/hidclass/precomp.h +++ b/drivers/hid/hidclass/precomp.h @@ -9,8 +9,6 @@ #include #include - - typedef struct { PDRIVER_OBJECT DriverObject; @@ -40,6 +38,17 @@ typedef struct // PHIDCLASS_DRIVER_EXTENSION DriverExtension; + // + // device description + // + HIDP_DEVICE_DESC DeviceDescription; + + // + // hid attributes + // + HID_DEVICE_ATTRIBUTES Attributes; + + }HIDCLASS_COMMON_DEVICE_EXTENSION, *PHIDCLASS_COMMON_DEVICE_EXTENSION; typedef struct @@ -59,21 +68,11 @@ typedef struct // HID_DESCRIPTOR HidDescriptor; - // - // hid attributes - // - HID_DEVICE_ATTRIBUTES Attributes; - // // report descriptor // PUCHAR ReportDescriptor; - // - // device description - // - HIDP_DEVICE_DESC DeviceDescription; - // // device relations // @@ -88,21 +87,11 @@ typedef struct // HIDCLASS_COMMON_DEVICE_EXTENSION Common; - // - // device descriptor - // - HID_DEVICE_ATTRIBUTES Attributes; - // // device capabilities // DEVICE_CAPABILITIES Capabilities; - // - // device description - // - HIDP_DEVICE_DESC DeviceDescription; - // // collection index // @@ -114,6 +103,58 @@ typedef struct UNICODE_STRING DeviceInterface; }HIDCLASS_PDO_DEVICE_EXTENSION, *PHIDCLASS_PDO_DEVICE_EXTENSION; +typedef struct __HIDCLASS_FILEOP_CONTEXT__ +{ + // + // device extension + // + PHIDCLASS_PDO_DEVICE_EXTENSION DeviceExtension; + + // + // spin lock + // + KSPIN_LOCK Lock; + + // + // read irp pending list + // + LIST_ENTRY ReadPendingIrpListHead; + + // + // completed irp list + // + LIST_ENTRY IrpCompletedListHead; + +}HIDCLASS_FILEOP_CONTEXT, *PHIDCLASS_FILEOP_CONTEXT; + +typedef struct +{ + // + // original request + // + PIRP OriginalIrp; + + // + // file op + // + PHIDCLASS_FILEOP_CONTEXT FileOp; + + // + // buffer for reading report + // + PVOID InputReportBuffer; + + // + // buffer length + // + ULONG InputReportBufferLength; + + // + // work item + // + PIO_WORKITEM CompletionWorkItem; + +}HIDCLASS_IRP_CONTEXT, *PHIDCLASS_IRP_CONTEXT; /* fdo.c */ NTSTATUS