From: Rémi Bernon rbernon@codeweavers.com
--- dlls/hidclass.sys/device.c | 18 +++++++++--------- dlls/hidclass.sys/hid.h | 9 +++++++-- dlls/hidclass.sys/pnp.c | 24 ++++++++++++------------ 3 files changed, 28 insertions(+), 23 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 8725ca7bba9..8fda73ff8f5 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -218,7 +218,7 @@ static struct hid_report *hid_queue_pop_report( struct hid_queue *queue )
static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *packet, BOOL polled ) { - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; ULONG size, report_len = polled ? packet->reportBufferLen : desc->InputLength; struct hid_report *last_report, *report; @@ -315,7 +315,7 @@ static HIDP_REPORT_IDS *find_report_with_type_and_id( HIDP_DEVICE_DESC *desc, UC DWORD CALLBACK hid_device_thread(void *args) { DEVICE_OBJECT *device = (DEVICE_OBJECT*)args; - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; ULONG i, input_length = 0, report_id = 0; HIDP_REPORT_IDS *report; HID_XFER_PACKET *packet; @@ -456,11 +456,11 @@ static NTSTATUS CALLBACK xfer_completion( DEVICE_OBJECT *device, IRP *irp, void return STATUS_SUCCESS; }
-static NTSTATUS hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP *irp ) +static NTSTATUS hid_device_xfer_report( struct device *ext, ULONG code, IRP *irp ) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); ULONG offset, report_len = 0, buffer_len = 0, collection = ext->u.pdo.collection_desc->CollectionNumber; - BASE_DEVICE_EXTENSION *fdo_ext = ext->u.pdo.parent_fdo->DeviceExtension; + struct device *fdo_ext = ext->u.pdo.parent_fdo->DeviceExtension; HIDP_DEVICE_DESC *desc = &fdo_ext->u.fdo.device_desc; struct completion_params *params; HIDP_REPORT_IDS *report = NULL; @@ -544,7 +544,7 @@ static NTSTATUS hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; NTSTATUS status = irp->IoStatus.Status; ULONG code, index; const WCHAR *str; @@ -710,7 +710,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) NTSTATUS WINAPI pdo_read(DEVICE_OBJECT *device, IRP *irp) { struct hid_queue *queue = irp->Tail.Overlay.OriginalFileObject->FsContext; - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); struct hid_report *report; @@ -753,7 +753,7 @@ NTSTATUS WINAPI pdo_read(DEVICE_OBJECT *device, IRP *irp)
NTSTATUS WINAPI pdo_write(DEVICE_OBJECT *device, IRP *irp) { - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; NTSTATUS status = hid_device_xfer_report( ext, IOCTL_HID_WRITE_REPORT, irp ); if (status != STATUS_PENDING) { @@ -765,7 +765,7 @@ NTSTATUS WINAPI pdo_write(DEVICE_OBJECT *device, IRP *irp)
NTSTATUS WINAPI pdo_create(DEVICE_OBJECT *device, IRP *irp) { - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; struct hid_queue *queue; BOOL removed; KIRQL irql; @@ -801,7 +801,7 @@ NTSTATUS WINAPI pdo_create(DEVICE_OBJECT *device, IRP *irp) NTSTATUS WINAPI pdo_close(DEVICE_OBJECT *device, IRP *irp) { struct hid_queue *queue = irp->Tail.Overlay.OriginalFileObject->FsContext; - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; BOOL removed; KIRQL irql;
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index 3924c72dcc3..4ca44c0a425 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -39,7 +39,7 @@ /* Ring buffer functions */ struct ReportRingBuffer;
-typedef struct _BASE_DEVICE_EXTENSION +struct device { union { @@ -89,7 +89,12 @@ typedef struct _BASE_DEVICE_EXTENSION const GUID *class_guid;
BOOL is_fdo; -} BASE_DEVICE_EXTENSION; +}; + +static inline struct device *impl_from_DEVICE_OBJECT( DEVICE_OBJECT *device ) +{ + return (struct device *)device->DeviceExtension; +}
struct hid_report { diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index 156b9a65f9f..92f42585ac1 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -111,7 +111,7 @@ static UINT32 alloc_rawinput_handle(void) /* make sure bRawData can hold UsagePage and Usage without requiring additional allocation */ C_ASSERT(offsetof(RAWINPUT, data.hid.bRawData[2 * sizeof(USAGE)]) < sizeof(RAWINPUT));
-static void send_wm_input_device_change(BASE_DEVICE_EXTENSION *ext, LPARAM param) +static void send_wm_input_device_change(struct device *ext, LPARAM param) { HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; INPUT input = {.type = INPUT_HARDWARE}; @@ -133,7 +133,7 @@ static void send_wm_input_device_change(BASE_DEVICE_EXTENSION *ext, LPARAM param static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *bus_pdo) { WCHAR device_id[MAX_DEVICE_ID_LEN], instance_id[MAX_DEVICE_ID_LEN]; - BASE_DEVICE_EXTENSION *ext; + struct device *ext; BOOL is_xinput_class; DEVICE_OBJECT *fdo; NTSTATUS status; @@ -217,7 +217,7 @@ static NTSTATUS get_hid_device_desc( minidriver *minidriver, DEVICE_OBJECT *devi
static NTSTATUS initialize_device( minidriver *minidriver, DEVICE_OBJECT *device ) { - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; ULONG index = HID_STRING_ID_ISERIALNUMBER; IO_STATUS_BLOCK io; NTSTATUS status; @@ -257,7 +257,7 @@ static NTSTATUS initialize_device( minidriver *minidriver, DEVICE_OBJECT *device
static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device ) { - BASE_DEVICE_EXTENSION *fdo_ext = device->DeviceExtension, *pdo_ext; + struct device *fdo_ext = device->DeviceExtension, *pdo_ext; DEVICE_OBJECT *child_pdo; UNICODE_STRING string; WCHAR pdo_name[255]; @@ -332,7 +332,7 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) { minidriver *minidriver = find_minidriver(device->DriverObject); IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; NTSTATUS status;
TRACE("irp %p, minor function %#x.\n", irp, stack->MinorFunction); @@ -404,7 +404,7 @@ static WCHAR *query_hardware_ids(DEVICE_OBJECT *device) static const WCHAR usage_format[] = L"HID_DEVICE_UP:%04X_U:%04X"; static const WCHAR hid_format[] = L"HID_DEVICE";
- BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; HID_COLLECTION_INFORMATION *info = &ext->u.pdo.information; WCHAR *dst; @@ -437,7 +437,7 @@ static WCHAR *query_compatible_ids(DEVICE_OBJECT *device)
static WCHAR *query_device_id(DEVICE_OBJECT *device) { - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; DWORD size = (wcslen(ext->device_id) + 1) * sizeof(WCHAR); WCHAR *dst;
@@ -449,7 +449,7 @@ static WCHAR *query_device_id(DEVICE_OBJECT *device)
static WCHAR *query_instance_id(DEVICE_OBJECT *device) { - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; DWORD size = (wcslen(ext->instance_id) + 1) * sizeof(WCHAR); WCHAR *dst;
@@ -461,7 +461,7 @@ static WCHAR *query_instance_id(DEVICE_OBJECT *device)
static WCHAR *query_container_id(DEVICE_OBJECT *device) { - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; DWORD size = (wcslen(ext->container_id) + 1) * sizeof(WCHAR); WCHAR *dst;
@@ -474,7 +474,7 @@ static WCHAR *query_container_id(DEVICE_OBJECT *device) static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension; HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; NTSTATUS status = irp->IoStatus.Status; struct hid_queue *queue, *next; @@ -606,7 +606,7 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp)
static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp) { - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension;
if (ext->is_fdo) return fdo_pnp(device, irp); @@ -616,7 +616,7 @@ static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp)
static NTSTATUS WINAPI driver_create(DEVICE_OBJECT *device, IRP *irp) { - BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + struct device *ext = device->DeviceExtension;
if (ext->is_fdo) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/hidclass.sys/hid.h | 5 ++--- dlls/hidclass.sys/pnp.c | 17 +++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index 4ca44c0a425..a18ae5f7a92 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -41,13 +41,12 @@ struct ReportRingBuffer;
struct device { + HID_DEVICE_EXTENSION hid; /* must be first */ + union { struct { - /* this must be the first member */ - HID_DEVICE_EXTENSION hid_ext; - HID_DEVICE_ATTRIBUTES attrs; HIDP_DEVICE_DESC device_desc; WCHAR serial[256]; diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index 92f42585ac1..41228d2628b 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -162,9 +162,9 @@ static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *b } ext = fdo->DeviceExtension; ext->is_fdo = TRUE; - ext->u.fdo.hid_ext.MiniDeviceExtension = ext + 1; - ext->u.fdo.hid_ext.PhysicalDeviceObject = bus_pdo; - ext->u.fdo.hid_ext.NextDeviceObject = bus_pdo; + ext->hid.MiniDeviceExtension = ext + 1; + ext->hid.PhysicalDeviceObject = bus_pdo; + ext->hid.NextDeviceObject = bus_pdo; swprintf(ext->device_id, ARRAY_SIZE(ext->device_id), L"HID\%s", wcsrchr(device_id, '\') + 1); wcscpy(ext->instance_id, instance_id);
@@ -269,10 +269,10 @@ static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device { if (fdo_ext->u.fdo.device_desc.CollectionDescLength > 1) swprintf( pdo_name, ARRAY_SIZE(pdo_name), L"\Device\HID#%p&%p&%d", device->DriverObject, - fdo_ext->u.fdo.hid_ext.PhysicalDeviceObject, i ); + fdo_ext->hid.PhysicalDeviceObject, i ); else swprintf( pdo_name, ARRAY_SIZE(pdo_name), L"\Device\HID#%p&%p", device->DriverObject, - fdo_ext->u.fdo.hid_ext.PhysicalDeviceObject ); + fdo_ext->hid.PhysicalDeviceObject );
RtlInitUnicodeString(&string, pdo_name); if ((status = IoCreateDevice( device->DriverObject, sizeof(*pdo_ext), &string, 0, 0, FALSE, &child_pdo ))) @@ -285,6 +285,7 @@ static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device fdo_ext->u.fdo.child_count++;
pdo_ext = child_pdo->DeviceExtension; + pdo_ext->hid = fdo_ext->hid; pdo_ext->u.pdo.parent_fdo = device; list_init( &pdo_ext->u.pdo.queues ); KeInitializeSpinLock( &pdo_ext->u.pdo.lock ); @@ -324,7 +325,7 @@ static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device TRACE( "created device %p, rawinput handle %#x\n", pdo_ext, pdo_ext->u.pdo.rawinput_handle ); }
- IoInvalidateDeviceRelations( fdo_ext->u.fdo.hid_ext.PhysicalDeviceObject, BusRelations ); + IoInvalidateDeviceRelations( fdo_ext->hid.PhysicalDeviceObject, BusRelations ); return STATUS_SUCCESS; }
@@ -364,7 +365,7 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) irp->IoStatus.Information = (ULONG_PTR)devices; irp->IoStatus.Status = STATUS_SUCCESS; IoSkipCurrentIrpStackLocation(irp); - return IoCallDriver(ext->u.fdo.hid_ext.NextDeviceObject, irp); + return IoCallDriver(ext->hid.NextDeviceObject, irp); }
case IRP_MN_START_DEVICE: @@ -384,7 +385,7 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) status = minidriver->PNPDispatch( device, irp ); HidP_FreeCollectionDescription( &ext->u.fdo.device_desc ); free( ext->u.fdo.child_pdos ); - IoDetachDevice( ext->u.fdo.hid_ext.NextDeviceObject ); + IoDetachDevice( ext->hid.NextDeviceObject ); IoDeleteDevice( device ); return status;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/hidclass.sys/device.c | 105 +++++++++++++++--------------- dlls/hidclass.sys/hid.h | 46 ++++++------- dlls/hidclass.sys/pnp.c | 129 ++++++++++++++++++------------------- 3 files changed, 140 insertions(+), 140 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 8fda73ff8f5..da641aedca9 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -216,10 +216,9 @@ static struct hid_report *hid_queue_pop_report( struct hid_queue *queue ) return report; }
-static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *packet, BOOL polled ) +static void hid_device_queue_input( struct phys_device *pdo, HID_XFER_PACKET *packet, BOOL polled ) { - struct device *ext = device->DeviceExtension; - HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; + HIDP_COLLECTION_DESC *desc = pdo->collection_desc; ULONG size, report_len = polled ? packet->reportBufferLen : desc->InputLength; struct hid_report *last_report, *report; struct hid_queue *queue; @@ -227,9 +226,9 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack KIRQL irql; IRP *irp;
- TRACE("device %p, packet %p\n", device, packet); + TRACE( "pdo %p, packet %p\n", pdo, packet );
- if (IsEqualGUID( ext->class_guid, &GUID_DEVINTERFACE_HID )) + if (IsEqualGUID( pdo->base.class_guid, &GUID_DEVINTERFACE_HID )) { struct hid_packet *hid;
@@ -243,7 +242,7 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack input.hi.wParamH = HIWORD(RIM_INPUT); input.hi.wParamL = LOWORD(RIM_INPUT);
- hid->head.device = ext->u.pdo.rawinput_handle; + hid->head.device = pdo->rawinput_handle; hid->head.usage = MAKELONG(desc->Usage, desc->UsagePage);
hid->head.count = 1; @@ -264,9 +263,9 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack
InitializeListHead( &completed );
- KeAcquireSpinLock( &ext->u.pdo.lock, &irql ); - if (ext->u.pdo.removed) WARN( "Device has been removed, dropping report\n" ); - else LIST_FOR_EACH_ENTRY( queue, &ext->u.pdo.queues, struct hid_queue, entry ) + KeAcquireSpinLock( &pdo->lock, &irql ); + if (pdo->removed) WARN( "Device has been removed, dropping report\n" ); + else LIST_FOR_EACH_ENTRY( queue, &pdo->queues, struct hid_queue, entry ) { if (!polled) hid_queue_push_report( queue, last_report );
@@ -284,7 +283,7 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack } while (polled); } - KeReleaseSpinLock( &ext->u.pdo.lock, irql ); + KeReleaseSpinLock( &pdo->lock, irql );
while ((entry = RemoveHeadList( &completed )) != &completed) { @@ -375,7 +374,7 @@ DWORD CALLBACK hid_device_thread(void *args) ERR( "dropping report for unknown child %u\n", report->CollectionNumber ); else { - DEVICE_OBJECT *pdo = ext->u.fdo.child_pdos[report->CollectionNumber - 1]; + struct phys_device *pdo = pdo_from_DEVICE_OBJECT( ext->u.fdo.child_pdos[report->CollectionNumber - 1] ); packet->reportId = buffer[0]; packet->reportBuffer = buffer; packet->reportBufferLen = io.Information; @@ -456,11 +455,11 @@ static NTSTATUS CALLBACK xfer_completion( DEVICE_OBJECT *device, IRP *irp, void return STATUS_SUCCESS; }
-static NTSTATUS hid_device_xfer_report( struct device *ext, ULONG code, IRP *irp ) +static NTSTATUS hid_device_xfer_report( struct phys_device *pdo, ULONG code, IRP *irp ) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); - ULONG offset, report_len = 0, buffer_len = 0, collection = ext->u.pdo.collection_desc->CollectionNumber; - struct device *fdo_ext = ext->u.pdo.parent_fdo->DeviceExtension; + ULONG offset, report_len = 0, buffer_len = 0, collection = pdo->collection_desc->CollectionNumber; + struct device *fdo_ext = pdo->parent_fdo->DeviceExtension; HIDP_DEVICE_DESC *desc = &fdo_ext->u.fdo.device_desc; struct completion_params *params; HIDP_REPORT_IDS *report = NULL; @@ -515,7 +514,7 @@ static NTSTATUS hid_device_xfer_report( struct device *ext, ULONG code, IRP *irp case IOCTL_HID_GET_FEATURE: case IOCTL_HID_GET_INPUT_REPORT: params->packet.reportBufferLen = buffer_len - offset; - irp = IoBuildDeviceIoControlRequest( code, ext->u.pdo.parent_fdo, NULL, 0, ¶ms->packet, + irp = IoBuildDeviceIoControlRequest( code, pdo->parent_fdo, NULL, 0, ¶ms->packet, sizeof(params->packet), TRUE, NULL, NULL ); break; case IOCTL_HID_WRITE_REPORT: @@ -524,7 +523,7 @@ static NTSTATUS hid_device_xfer_report( struct device *ext, ULONG code, IRP *irp case IOCTL_HID_SET_FEATURE: case IOCTL_HID_SET_OUTPUT_REPORT: params->packet.reportBufferLen = report_len - offset; - irp = IoBuildDeviceIoControlRequest( code, ext->u.pdo.parent_fdo, NULL, sizeof(params->packet), + irp = IoBuildDeviceIoControlRequest( code, pdo->parent_fdo, NULL, sizeof(params->packet), ¶ms->packet, 0, TRUE, NULL, NULL ); break; } @@ -537,14 +536,14 @@ static NTSTATUS hid_device_xfer_report( struct device *ext, ULONG code, IRP *irp
IoMarkIrpPending( params->irp ); IoSetCompletionRoutine( irp, xfer_completion, params, TRUE, TRUE, TRUE ); - IoCallDriver( ext->u.pdo.parent_fdo, irp ); + IoCallDriver( pdo->parent_fdo, irp ); return STATUS_PENDING; }
-NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) +NTSTATUS WINAPI pdo_ioctl( DEVICE_OBJECT *device, IRP *irp ) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); - struct device *ext = device->DeviceExtension; + struct phys_device *pdo = pdo_from_DEVICE_OBJECT( device ); NTSTATUS status = irp->IoStatus.Status; ULONG code, index; const WCHAR *str; @@ -555,9 +554,9 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
TRACE( "device %p code %#lx\n", device, irpsp->Parameters.DeviceIoControl.IoControlCode );
- KeAcquireSpinLock(&ext->u.pdo.lock, &irql); - removed = ext->u.pdo.removed; - KeReleaseSpinLock(&ext->u.pdo.lock, irql); + KeAcquireSpinLock( &pdo->lock, &irql ); + removed = pdo->removed; + KeReleaseSpinLock( &pdo->lock, irql );
if (removed) { @@ -573,6 +572,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) status = STATUS_BUFFER_OVERFLOW; else { + struct device *ext = pdo->parent_fdo->DeviceExtension; *(ULONG *)irp->AssociatedIrp.SystemBuffer = ext->u.fdo.poll_interval; irp->IoStatus.Information = sizeof(ULONG); status = STATUS_SUCCESS; @@ -585,6 +585,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) status = STATUS_BUFFER_TOO_SMALL; else { + struct device *ext = pdo->parent_fdo->DeviceExtension; poll_interval = *(ULONG *)irp->AssociatedIrp.SystemBuffer; if (poll_interval) ext->u.fdo.poll_interval = min( poll_interval, MAX_POLL_INTERVAL_MSEC ); status = STATUS_SUCCESS; @@ -602,7 +603,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) if (code == IOCTL_HID_GET_SERIALNUMBER_STRING) index = HID_STRING_ID_ISERIALNUMBER; if (code == IOCTL_HID_GET_MANUFACTURER_STRING) index = HID_STRING_ID_IMANUFACTURER;
- if ((str = find_device_string( ext->device_id, index ))) + if ((str = find_device_string( pdo->base.device_id, index ))) { irp->IoStatus.Information = (wcslen( str ) + 1) * sizeof(WCHAR); if (irp->IoStatus.Information > output_len) @@ -615,7 +616,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) break; }
- call_minidriver( IOCTL_HID_GET_STRING, ext->u.pdo.parent_fdo, ULongToPtr( index ), + call_minidriver( IOCTL_HID_GET_STRING, pdo->parent_fdo, ULongToPtr( index ), sizeof(index), output_buf, output_len, &irp->IoStatus ); status = irp->IoStatus.Status; break; @@ -627,7 +628,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) status = STATUS_BUFFER_OVERFLOW; else { - memcpy( irp->AssociatedIrp.SystemBuffer, &ext->u.pdo.information, + memcpy( irp->AssociatedIrp.SystemBuffer, &pdo->information, sizeof(HID_COLLECTION_INFORMATION) ); status = STATUS_SUCCESS; } @@ -635,7 +636,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) } case IOCTL_HID_GET_COLLECTION_DESCRIPTOR: { - HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; + HIDP_COLLECTION_DESC *desc = pdo->collection_desc;
irp->IoStatus.Information = desc->PreparsedDataLength; if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < desc->PreparsedDataLength) @@ -675,7 +676,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) case IOCTL_HID_SET_FEATURE: case IOCTL_HID_GET_INPUT_REPORT: case IOCTL_HID_SET_OUTPUT_REPORT: - status = hid_device_xfer_report( ext, code, irp ); + status = hid_device_xfer_report( pdo, code, irp ); break;
case IOCTL_HID_GET_WINE_RAWINPUT_HANDLE: @@ -683,7 +684,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) status = STATUS_BUFFER_OVERFLOW; else { - *(ULONG *)irp->AssociatedIrp.SystemBuffer = ext->u.pdo.rawinput_handle; + *(ULONG *)irp->AssociatedIrp.SystemBuffer = pdo->rawinput_handle; irp->IoStatus.Information = sizeof(ULONG); status = STATUS_SUCCESS; } @@ -707,19 +708,19 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) return status; }
-NTSTATUS WINAPI pdo_read(DEVICE_OBJECT *device, IRP *irp) +NTSTATUS WINAPI pdo_read( DEVICE_OBJECT *device, IRP *irp ) { struct hid_queue *queue = irp->Tail.Overlay.OriginalFileObject->FsContext; - struct device *ext = device->DeviceExtension; - HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; + struct phys_device *pdo = pdo_from_DEVICE_OBJECT( device ); + HIDP_COLLECTION_DESC *desc = pdo->collection_desc; IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); struct hid_report *report; BOOL removed; KIRQL irql;
- KeAcquireSpinLock(&ext->u.pdo.lock, &irql); - removed = ext->u.pdo.removed; - KeReleaseSpinLock(&ext->u.pdo.lock, irql); + KeAcquireSpinLock( &pdo->lock, &irql ); + removed = pdo->removed; + KeReleaseSpinLock( &pdo->lock, irql );
if (removed) { @@ -751,10 +752,10 @@ NTSTATUS WINAPI pdo_read(DEVICE_OBJECT *device, IRP *irp)
}
-NTSTATUS WINAPI pdo_write(DEVICE_OBJECT *device, IRP *irp) +NTSTATUS WINAPI pdo_write( DEVICE_OBJECT *device, IRP *irp ) { - struct device *ext = device->DeviceExtension; - NTSTATUS status = hid_device_xfer_report( ext, IOCTL_HID_WRITE_REPORT, irp ); + struct phys_device *pdo = pdo_from_DEVICE_OBJECT( device ); + NTSTATUS status = hid_device_xfer_report( pdo, IOCTL_HID_WRITE_REPORT, irp ); if (status != STATUS_PENDING) { irp->IoStatus.Status = status; @@ -763,18 +764,18 @@ NTSTATUS WINAPI pdo_write(DEVICE_OBJECT *device, IRP *irp) return status; }
-NTSTATUS WINAPI pdo_create(DEVICE_OBJECT *device, IRP *irp) +NTSTATUS WINAPI pdo_create( DEVICE_OBJECT *device, IRP *irp ) { - struct device *ext = device->DeviceExtension; + struct phys_device *pdo = pdo_from_DEVICE_OBJECT( device ); struct hid_queue *queue; BOOL removed; KIRQL irql;
TRACE("Open handle on device %p\n", device);
- KeAcquireSpinLock( &ext->u.pdo.lock, &irql ); - removed = ext->u.pdo.removed; - KeReleaseSpinLock( &ext->u.pdo.lock, irql ); + KeAcquireSpinLock( &pdo->lock, &irql ); + removed = pdo->removed; + KeReleaseSpinLock( &pdo->lock, irql );
if (removed) { @@ -786,9 +787,9 @@ NTSTATUS WINAPI pdo_create(DEVICE_OBJECT *device, IRP *irp) if (!(queue = hid_queue_create())) irp->IoStatus.Status = STATUS_NO_MEMORY; else { - KeAcquireSpinLock( &ext->u.pdo.lock, &irql ); - list_add_tail( &ext->u.pdo.queues, &queue->entry ); - KeReleaseSpinLock( &ext->u.pdo.lock, irql ); + KeAcquireSpinLock( &pdo->lock, &irql ); + list_add_tail( &pdo->queues, &queue->entry ); + KeReleaseSpinLock( &pdo->lock, irql );
irp->Tail.Overlay.OriginalFileObject->FsContext = queue; irp->IoStatus.Status = STATUS_SUCCESS; @@ -798,18 +799,18 @@ NTSTATUS WINAPI pdo_create(DEVICE_OBJECT *device, IRP *irp) return STATUS_SUCCESS; }
-NTSTATUS WINAPI pdo_close(DEVICE_OBJECT *device, IRP *irp) +NTSTATUS WINAPI pdo_close( DEVICE_OBJECT *device, IRP *irp ) { struct hid_queue *queue = irp->Tail.Overlay.OriginalFileObject->FsContext; - struct device *ext = device->DeviceExtension; + struct phys_device *pdo = pdo_from_DEVICE_OBJECT( device ); BOOL removed; KIRQL irql;
TRACE("Close handle on device %p\n", device);
- KeAcquireSpinLock( &ext->u.pdo.lock, &irql ); - removed = ext->u.pdo.removed; - KeReleaseSpinLock( &ext->u.pdo.lock, irql ); + KeAcquireSpinLock( &pdo->lock, &irql ); + removed = pdo->removed; + KeReleaseSpinLock( &pdo->lock, irql );
if (removed) { @@ -820,9 +821,9 @@ NTSTATUS WINAPI pdo_close(DEVICE_OBJECT *device, IRP *irp)
if (queue) { - KeAcquireSpinLock( &ext->u.pdo.lock, &irql ); + KeAcquireSpinLock( &pdo->lock, &irql ); list_remove( &queue->entry ); - KeReleaseSpinLock( &ext->u.pdo.lock, irql ); + KeReleaseSpinLock( &pdo->lock, irql ); hid_queue_destroy( queue ); }
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index a18ae5f7a92..5acac117224 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -58,26 +58,6 @@ struct device DEVICE_OBJECT **child_pdos; UINT child_count; } fdo; - - struct - { - DEVICE_OBJECT *parent_fdo; - - HIDP_COLLECTION_DESC *collection_desc; - HID_COLLECTION_INFORMATION information; - - UINT32 rawinput_handle; - UNICODE_STRING link_name; - - KSPIN_LOCK lock; - struct list queues; - BOOL removed; - - BOOL is_mouse; - UNICODE_STRING mouse_link_name; - BOOL is_keyboard; - UNICODE_STRING keyboard_link_name; - } pdo; } u;
/* These are unique to the parent FDO, but stored in the children as well @@ -90,9 +70,31 @@ struct device BOOL is_fdo; };
-static inline struct device *impl_from_DEVICE_OBJECT( DEVICE_OBJECT *device ) +struct phys_device +{ + struct device base; + DEVICE_OBJECT *parent_fdo; + + HIDP_COLLECTION_DESC *collection_desc; + HID_COLLECTION_INFORMATION information; + + UINT32 rawinput_handle; + UNICODE_STRING link_name; + + KSPIN_LOCK lock; + struct list queues; + BOOL removed; + + BOOL is_mouse; + UNICODE_STRING mouse_link_name; + BOOL is_keyboard; + UNICODE_STRING keyboard_link_name; +}; + +static inline struct phys_device *pdo_from_DEVICE_OBJECT( DEVICE_OBJECT *device ) { - return (struct device *)device->DeviceExtension; + struct device *impl = device->DeviceExtension; + return CONTAINING_RECORD( impl, struct phys_device, base ); }
struct hid_report diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index 41228d2628b..f033f45805f 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -111,21 +111,21 @@ static UINT32 alloc_rawinput_handle(void) /* make sure bRawData can hold UsagePage and Usage without requiring additional allocation */ C_ASSERT(offsetof(RAWINPUT, data.hid.bRawData[2 * sizeof(USAGE)]) < sizeof(RAWINPUT));
-static void send_wm_input_device_change(struct device *ext, LPARAM param) +static void send_wm_input_device_change( struct phys_device *pdo, LPARAM param ) { - HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; + HIDP_COLLECTION_DESC *desc = pdo->collection_desc; INPUT input = {.type = INPUT_HARDWARE}; struct hid_packet hid = {0};
- TRACE("ext %p, lparam %p\n", ext, (void *)param); + TRACE( "pdo %p, lparam %p\n", pdo, (void *)param );
- if (!IsEqualGUID( ext->class_guid, &GUID_DEVINTERFACE_HID )) return; + if (!IsEqualGUID( pdo->base.class_guid, &GUID_DEVINTERFACE_HID )) return;
input.hi.uMsg = WM_INPUT_DEVICE_CHANGE; input.hi.wParamH = HIWORD(param); input.hi.wParamL = LOWORD(param);
- hid.head.device = ext->u.pdo.rawinput_handle; + hid.head.device = pdo->rawinput_handle; hid.head.usage = MAKELONG(desc->Usage, desc->UsagePage); NtUserSendHardwareInput(0, 0, &input, (LPARAM)&hid); } @@ -257,8 +257,9 @@ static NTSTATUS initialize_device( minidriver *minidriver, DEVICE_OBJECT *device
static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device ) { - struct device *fdo_ext = device->DeviceExtension, *pdo_ext; - DEVICE_OBJECT *child_pdo; + struct device *fdo_ext = device->DeviceExtension; + DEVICE_OBJECT *child_device; + struct phys_device *pdo; UNICODE_STRING string; WCHAR pdo_name[255]; USAGE page, usage; @@ -275,54 +276,54 @@ static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device fdo_ext->hid.PhysicalDeviceObject );
RtlInitUnicodeString(&string, pdo_name); - if ((status = IoCreateDevice( device->DriverObject, sizeof(*pdo_ext), &string, 0, 0, FALSE, &child_pdo ))) + if ((status = IoCreateDevice( device->DriverObject, sizeof(*pdo), &string, 0, 0, FALSE, &child_device ))) { ERR( "Failed to create child PDO, status %#lx.\n", status ); return status; }
- fdo_ext->u.fdo.child_pdos[i] = child_pdo; + fdo_ext->u.fdo.child_pdos[i] = child_device; fdo_ext->u.fdo.child_count++;
- pdo_ext = child_pdo->DeviceExtension; - pdo_ext->hid = fdo_ext->hid; - pdo_ext->u.pdo.parent_fdo = device; - list_init( &pdo_ext->u.pdo.queues ); - KeInitializeSpinLock( &pdo_ext->u.pdo.lock ); + pdo = pdo_from_DEVICE_OBJECT( child_device ); + pdo->base.hid = fdo_ext->hid; + pdo->parent_fdo = device; + list_init( &pdo->queues ); + KeInitializeSpinLock( &pdo->lock );
- pdo_ext->u.pdo.collection_desc = fdo_ext->u.fdo.device_desc.CollectionDesc + i; + pdo->collection_desc = fdo_ext->u.fdo.device_desc.CollectionDesc + i;
if (fdo_ext->u.fdo.device_desc.CollectionDescLength > 1) { - swprintf( pdo_ext->device_id, ARRAY_SIZE(pdo_ext->device_id), L"%s&Col%02d", - fdo_ext->device_id, pdo_ext->u.pdo.collection_desc->CollectionNumber ); - swprintf( pdo_ext->instance_id, ARRAY_SIZE(pdo_ext->instance_id), L"%u&%s&%x&%u&%04u", + swprintf( pdo->base.device_id, ARRAY_SIZE(pdo->base.device_id), L"%s&Col%02d", + fdo_ext->device_id, pdo->collection_desc->CollectionNumber ); + swprintf( pdo->base.instance_id, ARRAY_SIZE(pdo->base.instance_id), L"%u&%s&%x&%u&%04u", fdo_ext->u.fdo.attrs.VersionNumber, fdo_ext->u.fdo.serial, 0, 0, i ); } else { - wcscpy( pdo_ext->device_id, fdo_ext->device_id ); - wcscpy( pdo_ext->instance_id, fdo_ext->instance_id ); + wcscpy( pdo->base.device_id, fdo_ext->device_id ); + wcscpy( pdo->base.instance_id, fdo_ext->instance_id ); } - wcscpy(pdo_ext->container_id, fdo_ext->container_id); - pdo_ext->class_guid = fdo_ext->class_guid; + wcscpy( pdo->base.container_id, fdo_ext->container_id ); + pdo->base.class_guid = fdo_ext->class_guid;
- pdo_ext->u.pdo.information.VendorID = fdo_ext->u.fdo.attrs.VendorID; - pdo_ext->u.pdo.information.ProductID = fdo_ext->u.fdo.attrs.ProductID; - pdo_ext->u.pdo.information.VersionNumber = fdo_ext->u.fdo.attrs.VersionNumber; - pdo_ext->u.pdo.information.Polled = minidriver->minidriver.DevicesArePolled; - pdo_ext->u.pdo.information.DescriptorSize = pdo_ext->u.pdo.collection_desc->PreparsedDataLength; + pdo->information.VendorID = fdo_ext->u.fdo.attrs.VendorID; + pdo->information.ProductID = fdo_ext->u.fdo.attrs.ProductID; + pdo->information.VersionNumber = fdo_ext->u.fdo.attrs.VersionNumber; + pdo->information.Polled = minidriver->minidriver.DevicesArePolled; + pdo->information.DescriptorSize = pdo->collection_desc->PreparsedDataLength;
- page = pdo_ext->u.pdo.collection_desc->UsagePage; - usage = pdo_ext->u.pdo.collection_desc->Usage; + page = pdo->collection_desc->UsagePage; + usage = pdo->collection_desc->Usage; if (page == HID_USAGE_PAGE_GENERIC && usage == HID_USAGE_GENERIC_MOUSE) - pdo_ext->u.pdo.rawinput_handle = WINE_MOUSE_HANDLE; + pdo->rawinput_handle = WINE_MOUSE_HANDLE; else if (page == HID_USAGE_PAGE_GENERIC && usage == HID_USAGE_GENERIC_KEYBOARD) - pdo_ext->u.pdo.rawinput_handle = WINE_KEYBOARD_HANDLE; + pdo->rawinput_handle = WINE_KEYBOARD_HANDLE; else - pdo_ext->u.pdo.rawinput_handle = alloc_rawinput_handle(); + pdo->rawinput_handle = alloc_rawinput_handle();
- TRACE( "created device %p, rawinput handle %#x\n", pdo_ext, pdo_ext->u.pdo.rawinput_handle ); + TRACE( "created pdo %p, rawinput handle %#x\n", pdo, pdo->rawinput_handle ); }
IoInvalidateDeviceRelations( fdo_ext->hid.PhysicalDeviceObject, BusRelations ); @@ -405,9 +406,9 @@ static WCHAR *query_hardware_ids(DEVICE_OBJECT *device) static const WCHAR usage_format[] = L"HID_DEVICE_UP:%04X_U:%04X"; static const WCHAR hid_format[] = L"HID_DEVICE";
- struct device *ext = device->DeviceExtension; - HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; - HID_COLLECTION_INFORMATION *info = &ext->u.pdo.information; + struct phys_device *pdo = pdo_from_DEVICE_OBJECT( device ); + HIDP_COLLECTION_DESC *desc = pdo->collection_desc; + HID_COLLECTION_INFORMATION *info = &pdo->information; WCHAR *dst; DWORD size;
@@ -472,11 +473,11 @@ static WCHAR *query_container_id(DEVICE_OBJECT *device) return dst; }
-static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp) +static NTSTATUS pdo_pnp( DEVICE_OBJECT *device, IRP *irp ) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); - struct device *ext = device->DeviceExtension; - HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc; + struct phys_device *pdo = pdo_from_DEVICE_OBJECT( device ); + HIDP_COLLECTION_DESC *desc = pdo->collection_desc; NTSTATUS status = irp->IoStatus.Status; struct hid_queue *queue, *next; KIRQL irql; @@ -511,7 +512,7 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp) else status = STATUS_SUCCESS; break; case BusQueryContainerID: - if (ext->container_id[0]) + if (pdo->base.container_id[0]) { irp->IoStatus.Information = (ULONG_PTR)query_container_id(device); if (!irp->IoStatus.Information) status = STATUS_NO_MEMORY; @@ -535,9 +536,9 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp) }
case IRP_MN_START_DEVICE: - send_wm_input_device_change(ext, GIDC_ARRIVAL); + send_wm_input_device_change( pdo, GIDC_ARRIVAL );
- if ((status = IoRegisterDeviceInterface(device, ext->class_guid, NULL, &ext->u.pdo.link_name))) + if ((status = IoRegisterDeviceInterface( device, pdo->base.class_guid, NULL, &pdo->link_name ))) { ERR( "Failed to register interface, status %#lx.\n", status ); break; @@ -546,40 +547,36 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp) /* FIXME: This should probably be done in mouhid.sys. */ if (desc->UsagePage == HID_USAGE_PAGE_GENERIC && desc->Usage == HID_USAGE_GENERIC_MOUSE) { - if (!IoRegisterDeviceInterface(device, &GUID_DEVINTERFACE_MOUSE, NULL, &ext->u.pdo.mouse_link_name)) - ext->u.pdo.is_mouse = TRUE; + if (!IoRegisterDeviceInterface( device, &GUID_DEVINTERFACE_MOUSE, NULL, &pdo->mouse_link_name )) + pdo->is_mouse = TRUE; } if (desc->UsagePage == HID_USAGE_PAGE_GENERIC && desc->Usage == HID_USAGE_GENERIC_KEYBOARD) { - if (!IoRegisterDeviceInterface(device, &GUID_DEVINTERFACE_KEYBOARD, NULL, &ext->u.pdo.keyboard_link_name)) - ext->u.pdo.is_keyboard = TRUE; + if (!IoRegisterDeviceInterface( device, &GUID_DEVINTERFACE_KEYBOARD, NULL, &pdo->keyboard_link_name )) + pdo->is_keyboard = TRUE; }
- IoSetDeviceInterfaceState(&ext->u.pdo.link_name, TRUE); - if (ext->u.pdo.is_mouse) - IoSetDeviceInterfaceState(&ext->u.pdo.mouse_link_name, TRUE); - if (ext->u.pdo.is_keyboard) - IoSetDeviceInterfaceState(&ext->u.pdo.keyboard_link_name, TRUE); + IoSetDeviceInterfaceState( &pdo->link_name, TRUE ); + if (pdo->is_mouse) IoSetDeviceInterfaceState( &pdo->mouse_link_name, TRUE ); + if (pdo->is_keyboard) IoSetDeviceInterfaceState( &pdo->keyboard_link_name, TRUE );
- ext->u.pdo.removed = FALSE; + pdo->removed = FALSE; status = STATUS_SUCCESS; break;
case IRP_MN_REMOVE_DEVICE: - send_wm_input_device_change(ext, GIDC_REMOVAL); + send_wm_input_device_change( pdo, GIDC_REMOVAL );
- IoSetDeviceInterfaceState(&ext->u.pdo.link_name, FALSE); - if (ext->u.pdo.is_mouse) - IoSetDeviceInterfaceState(&ext->u.pdo.mouse_link_name, FALSE); - if (ext->u.pdo.is_keyboard) - IoSetDeviceInterfaceState(&ext->u.pdo.keyboard_link_name, FALSE); + IoSetDeviceInterfaceState( &pdo->link_name, FALSE ); + if (pdo->is_mouse) IoSetDeviceInterfaceState( &pdo->mouse_link_name, FALSE ); + if (pdo->is_keyboard) IoSetDeviceInterfaceState( &pdo->keyboard_link_name, FALSE );
- KeAcquireSpinLock( &ext->u.pdo.lock, &irql ); - LIST_FOR_EACH_ENTRY_SAFE( queue, next, &ext->u.pdo.queues, struct hid_queue, entry ) + KeAcquireSpinLock( &pdo->lock, &irql ); + LIST_FOR_EACH_ENTRY_SAFE( queue, next, &pdo->queues, struct hid_queue, entry ) hid_queue_destroy( queue ); - KeReleaseSpinLock( &ext->u.pdo.lock, irql ); + KeReleaseSpinLock( &pdo->lock, irql );
- RtlFreeUnicodeString(&ext->u.pdo.link_name); + RtlFreeUnicodeString( &pdo->link_name );
irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(irp, IO_NO_INCREMENT); @@ -587,11 +584,11 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp) return STATUS_SUCCESS;
case IRP_MN_SURPRISE_REMOVAL: - KeAcquireSpinLock(&ext->u.pdo.lock, &irql); - ext->u.pdo.removed = TRUE; - LIST_FOR_EACH_ENTRY_SAFE( queue, next, &ext->u.pdo.queues, struct hid_queue, entry ) + KeAcquireSpinLock( &pdo->lock, &irql ); + pdo->removed = TRUE; + LIST_FOR_EACH_ENTRY_SAFE( queue, next, &pdo->queues, struct hid_queue, entry ) hid_queue_remove_pending_irps( queue ); - KeReleaseSpinLock( &ext->u.pdo.lock, irql ); + KeReleaseSpinLock( &pdo->lock, irql );
status = STATUS_SUCCESS; break;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/hidclass.sys/device.c | 34 +++++------ dlls/hidclass.sys/hid.h | 41 +++++++------ dlls/hidclass.sys/pnp.c | 122 ++++++++++++++++++------------------- 3 files changed, 100 insertions(+), 97 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index da641aedca9..a1bd6ff3c24 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -314,7 +314,7 @@ static HIDP_REPORT_IDS *find_report_with_type_and_id( HIDP_DEVICE_DESC *desc, UC DWORD CALLBACK hid_device_thread(void *args) { DEVICE_OBJECT *device = (DEVICE_OBJECT*)args; - struct device *ext = device->DeviceExtension; + struct func_device *fdo = fdo_from_DEVICE_OBJECT( device ); ULONG i, input_length = 0, report_id = 0; HIDP_REPORT_IDS *report; HID_XFER_PACKET *packet; @@ -324,23 +324,23 @@ DWORD CALLBACK hid_device_thread(void *args) BYTE *buffer; IRP *irp;
- for (i = 0; i < ext->u.fdo.device_desc.CollectionDescLength; i++) + for (i = 0; i < fdo->device_desc.CollectionDescLength; i++) { - HIDP_COLLECTION_DESC *desc = ext->u.fdo.device_desc.CollectionDesc + i; + HIDP_COLLECTION_DESC *desc = fdo->device_desc.CollectionDesc + i; input_length = max(input_length, desc->InputLength); }
packet = malloc( sizeof(*packet) + input_length ); buffer = (BYTE *)(packet + 1);
- desc = &ext->u.fdo.device_desc; + desc = &fdo->device_desc; report = find_report_with_type_and_id( desc, 0, HidP_Input, 0, TRUE ); if (!report) WARN("no input report found.\n"); else report_id = report->ReportID;
do { - LARGE_INTEGER delay = {.QuadPart = (LONGLONG)ext->u.fdo.poll_interval * -10000}; + LARGE_INTEGER delay = {.QuadPart = (LONGLONG)fdo->poll_interval * -10000}; KEVENT irp_event;
packet->reportId = buffer[0] = report_id; @@ -358,7 +358,7 @@ DWORD CALLBACK hid_device_thread(void *args) packet->reportBufferLen, TRUE, &irp_event, &io ); if (IoCallDriver( device, irp ) == STATUS_PENDING) { - void *events[2] = {&irp_event, &ext->u.fdo.halt_event}; + void *events[2] = {&irp_event, &fdo->halt_event}; status = KeWaitForMultipleObjects( 2, events, WaitAny, Executive, KernelMode, FALSE, NULL, NULL ); if (status) break; } @@ -368,21 +368,21 @@ DWORD CALLBACK hid_device_thread(void *args) if (!report_id) io.Information++; if (!(report = find_report_with_type_and_id( desc, 0, HidP_Input, buffer[0], FALSE ))) ERR( "dropping unknown input id %u\n", buffer[0] ); - else if (!ext->u.fdo.poll_interval && io.Information < report->InputLength) + else if (!fdo->poll_interval && io.Information < report->InputLength) ERR( "dropping short report, len %Iu expected %u\n", io.Information, report->InputLength ); - else if (!report->CollectionNumber || report->CollectionNumber > ext->u.fdo.child_count) + else if (!report->CollectionNumber || report->CollectionNumber > fdo->child_count) ERR( "dropping report for unknown child %u\n", report->CollectionNumber ); else { - struct phys_device *pdo = pdo_from_DEVICE_OBJECT( ext->u.fdo.child_pdos[report->CollectionNumber - 1] ); + struct phys_device *pdo = pdo_from_DEVICE_OBJECT( fdo->child_pdos[report->CollectionNumber - 1] ); packet->reportId = buffer[0]; packet->reportBuffer = buffer; packet->reportBufferLen = io.Information; - hid_device_queue_input( pdo, packet, !!ext->u.fdo.poll_interval ); + hid_device_queue_input( pdo, packet, !!fdo->poll_interval ); } }
- status = KeWaitForSingleObject( &ext->u.fdo.halt_event, Executive, KernelMode, FALSE, &delay ); + status = KeWaitForSingleObject( &fdo->halt_event, Executive, KernelMode, FALSE, &delay ); } while (status == STATUS_TIMEOUT);
if (status) WARN( "device thread exiting with status %#lx\n", status ); @@ -459,8 +459,8 @@ static NTSTATUS hid_device_xfer_report( struct phys_device *pdo, ULONG code, IRP { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); ULONG offset, report_len = 0, buffer_len = 0, collection = pdo->collection_desc->CollectionNumber; - struct device *fdo_ext = pdo->parent_fdo->DeviceExtension; - HIDP_DEVICE_DESC *desc = &fdo_ext->u.fdo.device_desc; + struct func_device *fdo = fdo_from_DEVICE_OBJECT( pdo->parent_fdo ); + HIDP_DEVICE_DESC *desc = &fdo->device_desc; struct completion_params *params; HIDP_REPORT_IDS *report = NULL; BYTE *buffer = NULL; @@ -572,8 +572,8 @@ NTSTATUS WINAPI pdo_ioctl( DEVICE_OBJECT *device, IRP *irp ) status = STATUS_BUFFER_OVERFLOW; else { - struct device *ext = pdo->parent_fdo->DeviceExtension; - *(ULONG *)irp->AssociatedIrp.SystemBuffer = ext->u.fdo.poll_interval; + struct func_device *fdo = fdo_from_DEVICE_OBJECT( pdo->parent_fdo ); + *(ULONG *)irp->AssociatedIrp.SystemBuffer = fdo->poll_interval; irp->IoStatus.Information = sizeof(ULONG); status = STATUS_SUCCESS; } @@ -585,9 +585,9 @@ NTSTATUS WINAPI pdo_ioctl( DEVICE_OBJECT *device, IRP *irp ) status = STATUS_BUFFER_TOO_SMALL; else { - struct device *ext = pdo->parent_fdo->DeviceExtension; + struct func_device *fdo = fdo_from_DEVICE_OBJECT( pdo->parent_fdo ); poll_interval = *(ULONG *)irp->AssociatedIrp.SystemBuffer; - if (poll_interval) ext->u.fdo.poll_interval = min( poll_interval, MAX_POLL_INTERVAL_MSEC ); + if (poll_interval) fdo->poll_interval = min( poll_interval, MAX_POLL_INTERVAL_MSEC ); status = STATUS_SUCCESS; } break; diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index 5acac117224..403102e8d88 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -43,25 +43,6 @@ struct device { HID_DEVICE_EXTENSION hid; /* must be first */
- union - { - struct - { - HID_DEVICE_ATTRIBUTES attrs; - HIDP_DEVICE_DESC device_desc; - WCHAR serial[256]; - - ULONG poll_interval; - KEVENT halt_event; - HANDLE thread; - - DEVICE_OBJECT **child_pdos; - UINT child_count; - } fdo; - } u; - - /* These are unique to the parent FDO, but stored in the children as well - * for convenience. */ WCHAR device_id[MAX_DEVICE_ID_LEN]; WCHAR instance_id[MAX_DEVICE_ID_LEN]; WCHAR container_id[MAX_GUID_STRING_LEN]; @@ -70,6 +51,21 @@ struct device BOOL is_fdo; };
+struct func_device +{ + struct device base; + HID_DEVICE_ATTRIBUTES attrs; + HIDP_DEVICE_DESC device_desc; + WCHAR serial[256]; + + ULONG poll_interval; + KEVENT halt_event; + HANDLE thread; + + DEVICE_OBJECT **child_pdos; + UINT child_count; +}; + struct phys_device { struct device base; @@ -97,6 +93,13 @@ static inline struct phys_device *pdo_from_DEVICE_OBJECT( DEVICE_OBJECT *device return CONTAINING_RECORD( impl, struct phys_device, base ); }
+static inline struct func_device *fdo_from_DEVICE_OBJECT( DEVICE_OBJECT *device ) +{ + struct device *impl = device->DeviceExtension; + if (!impl->is_fdo) impl = pdo_from_DEVICE_OBJECT( device )->parent_fdo->DeviceExtension; + return CONTAINING_RECORD( impl, struct func_device, base ); +} + struct hid_report { LONG ref; diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index f033f45805f..e4e64a92bbc 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -133,9 +133,9 @@ static void send_wm_input_device_change( struct phys_device *pdo, LPARAM param ) static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *bus_pdo) { WCHAR device_id[MAX_DEVICE_ID_LEN], instance_id[MAX_DEVICE_ID_LEN]; - struct device *ext; + struct func_device *fdo; BOOL is_xinput_class; - DEVICE_OBJECT *fdo; + DEVICE_OBJECT *device; NTSTATUS status; minidriver *minidriver;
@@ -154,37 +154,37 @@ static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *b TRACE("Adding device to PDO %p, id %s\%s.\n", bus_pdo, debugstr_w(device_id), debugstr_w(instance_id)); minidriver = find_minidriver(driver);
- if ((status = IoCreateDevice(driver, sizeof(*ext) + minidriver->minidriver.DeviceExtensionSize, - NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &fdo))) + if ((status = IoCreateDevice( driver, sizeof(*fdo) + minidriver->minidriver.DeviceExtensionSize, + NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &device ))) { ERR( "Failed to create bus FDO, status %#lx.\n", status ); return status; } - ext = fdo->DeviceExtension; - ext->is_fdo = TRUE; - ext->hid.MiniDeviceExtension = ext + 1; - ext->hid.PhysicalDeviceObject = bus_pdo; - ext->hid.NextDeviceObject = bus_pdo; - swprintf(ext->device_id, ARRAY_SIZE(ext->device_id), L"HID\%s", wcsrchr(device_id, '\') + 1); - wcscpy(ext->instance_id, instance_id); + fdo = device->DeviceExtension; + fdo->base.is_fdo = TRUE; + fdo->base.hid.MiniDeviceExtension = fdo + 1; + fdo->base.hid.PhysicalDeviceObject = bus_pdo; + fdo->base.hid.NextDeviceObject = bus_pdo; + swprintf( fdo->base.device_id, ARRAY_SIZE(fdo->base.device_id), L"HID\%s", wcsrchr( device_id, '\' ) + 1 ); + wcscpy( fdo->base.instance_id, instance_id );
- if (get_device_id(bus_pdo, BusQueryContainerID, ext->container_id)) - ext->container_id[0] = 0; + if (get_device_id( bus_pdo, BusQueryContainerID, fdo->base.container_id )) + fdo->base.container_id[0] = 0;
is_xinput_class = !wcsncmp(device_id, L"WINEXINPUT\", 7) && wcsstr(device_id, L"&XI_") != NULL; - if (is_xinput_class) ext->class_guid = &GUID_DEVINTERFACE_WINEXINPUT; - else ext->class_guid = &GUID_DEVINTERFACE_HID; + if (is_xinput_class) fdo->base.class_guid = &GUID_DEVINTERFACE_WINEXINPUT; + else fdo->base.class_guid = &GUID_DEVINTERFACE_HID;
- status = minidriver->AddDevice(minidriver->minidriver.DriverObject, fdo); + status = minidriver->AddDevice( minidriver->minidriver.DriverObject, device ); if (status != STATUS_SUCCESS) { ERR( "Minidriver AddDevice failed (%lx)\n", status ); - IoDeleteDevice(fdo); + IoDeleteDevice( device ); return status; }
- IoAttachDeviceToDeviceStack(fdo, bus_pdo); - fdo->Flags &= ~DO_DEVICE_INITIALIZING; + IoAttachDeviceToDeviceStack( device, bus_pdo ); + device->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS; } @@ -217,13 +217,13 @@ static NTSTATUS get_hid_device_desc( minidriver *minidriver, DEVICE_OBJECT *devi
static NTSTATUS initialize_device( minidriver *minidriver, DEVICE_OBJECT *device ) { - struct device *ext = device->DeviceExtension; + struct func_device *fdo = fdo_from_DEVICE_OBJECT( device ); ULONG index = HID_STRING_ID_ISERIALNUMBER; IO_STATUS_BLOCK io; NTSTATUS status;
- call_minidriver( IOCTL_HID_GET_DEVICE_ATTRIBUTES, device, NULL, 0, &ext->u.fdo.attrs, - sizeof(ext->u.fdo.attrs), &io ); + call_minidriver( IOCTL_HID_GET_DEVICE_ATTRIBUTES, device, NULL, 0, &fdo->attrs, + sizeof(fdo->attrs), &io ); if (io.Status != STATUS_SUCCESS) { ERR( "Minidriver failed to get attributes, status %#lx.\n", io.Status ); @@ -231,33 +231,33 @@ static NTSTATUS initialize_device( minidriver *minidriver, DEVICE_OBJECT *device }
call_minidriver( IOCTL_HID_GET_STRING, device, ULongToPtr(index), sizeof(index), - &ext->u.fdo.serial, sizeof(ext->u.fdo.serial), &io ); + &fdo->serial, sizeof(fdo->serial), &io ); if (io.Status != STATUS_SUCCESS) { ERR( "Minidriver failed to get serial number, status %#lx.\n", io.Status ); return io.Status; }
- if ((status = get_hid_device_desc( minidriver, device, &ext->u.fdo.device_desc ))) + if ((status = get_hid_device_desc( minidriver, device, &fdo->device_desc ))) { ERR( "Failed to get HID device description, status %#lx\n", status ); return status; }
- if (!(ext->u.fdo.child_pdos = malloc( ext->u.fdo.device_desc.CollectionDescLength * sizeof(*ext->u.fdo.child_pdos) ))) + if (!(fdo->child_pdos = malloc( fdo->device_desc.CollectionDescLength * sizeof(*fdo->child_pdos) ))) { ERR( "Cannot allocate child PDOs array\n" ); return STATUS_NO_MEMORY; }
- ext->u.fdo.poll_interval = minidriver->minidriver.DevicesArePolled ? DEFAULT_POLL_INTERVAL : 0; - KeInitializeEvent( &ext->u.fdo.halt_event, NotificationEvent, FALSE ); + fdo->poll_interval = minidriver->minidriver.DevicesArePolled ? DEFAULT_POLL_INTERVAL : 0; + KeInitializeEvent( &fdo->halt_event, NotificationEvent, FALSE ); return STATUS_SUCCESS; }
static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device ) { - struct device *fdo_ext = device->DeviceExtension; + struct func_device *fdo = fdo_from_DEVICE_OBJECT( device ); DEVICE_OBJECT *child_device; struct phys_device *pdo; UNICODE_STRING string; @@ -266,14 +266,14 @@ static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device NTSTATUS status; INT i;
- for (i = 0; i < fdo_ext->u.fdo.device_desc.CollectionDescLength; ++i) + for (i = 0; i < fdo->device_desc.CollectionDescLength; ++i) { - if (fdo_ext->u.fdo.device_desc.CollectionDescLength > 1) + if (fdo->device_desc.CollectionDescLength > 1) swprintf( pdo_name, ARRAY_SIZE(pdo_name), L"\Device\HID#%p&%p&%d", device->DriverObject, - fdo_ext->hid.PhysicalDeviceObject, i ); + fdo->base.hid.PhysicalDeviceObject, i ); else swprintf( pdo_name, ARRAY_SIZE(pdo_name), L"\Device\HID#%p&%p", device->DriverObject, - fdo_ext->hid.PhysicalDeviceObject ); + fdo->base.hid.PhysicalDeviceObject );
RtlInitUnicodeString(&string, pdo_name); if ((status = IoCreateDevice( device->DriverObject, sizeof(*pdo), &string, 0, 0, FALSE, &child_device ))) @@ -282,35 +282,35 @@ static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device return status; }
- fdo_ext->u.fdo.child_pdos[i] = child_device; - fdo_ext->u.fdo.child_count++; + fdo->child_pdos[i] = child_device; + fdo->child_count++;
pdo = pdo_from_DEVICE_OBJECT( child_device ); - pdo->base.hid = fdo_ext->hid; + pdo->base.hid = fdo->base.hid; pdo->parent_fdo = device; list_init( &pdo->queues ); KeInitializeSpinLock( &pdo->lock );
- pdo->collection_desc = fdo_ext->u.fdo.device_desc.CollectionDesc + i; + pdo->collection_desc = fdo->device_desc.CollectionDesc + i;
- if (fdo_ext->u.fdo.device_desc.CollectionDescLength > 1) + if (fdo->device_desc.CollectionDescLength > 1) { swprintf( pdo->base.device_id, ARRAY_SIZE(pdo->base.device_id), L"%s&Col%02d", - fdo_ext->device_id, pdo->collection_desc->CollectionNumber ); + fdo->base.device_id, pdo->collection_desc->CollectionNumber ); swprintf( pdo->base.instance_id, ARRAY_SIZE(pdo->base.instance_id), L"%u&%s&%x&%u&%04u", - fdo_ext->u.fdo.attrs.VersionNumber, fdo_ext->u.fdo.serial, 0, 0, i ); + fdo->attrs.VersionNumber, fdo->serial, 0, 0, i ); } else { - wcscpy( pdo->base.device_id, fdo_ext->device_id ); - wcscpy( pdo->base.instance_id, fdo_ext->instance_id ); + wcscpy( pdo->base.device_id, fdo->base.device_id ); + wcscpy( pdo->base.instance_id, fdo->base.instance_id ); } - wcscpy( pdo->base.container_id, fdo_ext->container_id ); - pdo->base.class_guid = fdo_ext->class_guid; + wcscpy( pdo->base.container_id, fdo->base.container_id ); + pdo->base.class_guid = fdo->base.class_guid;
- pdo->information.VendorID = fdo_ext->u.fdo.attrs.VendorID; - pdo->information.ProductID = fdo_ext->u.fdo.attrs.ProductID; - pdo->information.VersionNumber = fdo_ext->u.fdo.attrs.VersionNumber; + pdo->information.VendorID = fdo->attrs.VendorID; + pdo->information.ProductID = fdo->attrs.ProductID; + pdo->information.VersionNumber = fdo->attrs.VersionNumber; pdo->information.Polled = minidriver->minidriver.DevicesArePolled; pdo->information.DescriptorSize = pdo->collection_desc->PreparsedDataLength;
@@ -326,7 +326,7 @@ static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device TRACE( "created pdo %p, rawinput handle %#x\n", pdo, pdo->rawinput_handle ); }
- IoInvalidateDeviceRelations( fdo_ext->hid.PhysicalDeviceObject, BusRelations ); + IoInvalidateDeviceRelations( fdo->base.hid.PhysicalDeviceObject, BusRelations ); return STATUS_SUCCESS; }
@@ -334,7 +334,7 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) { minidriver *minidriver = find_minidriver(device->DriverObject); IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); - struct device *ext = device->DeviceExtension; + struct func_device *fdo = fdo_from_DEVICE_OBJECT( device ); NTSTATUS status;
TRACE("irp %p, minor function %#x.\n", irp, stack->MinorFunction); @@ -349,49 +349,49 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) if (stack->Parameters.QueryDeviceRelations.Type != BusRelations) return minidriver->PNPDispatch(device, irp);
- if (!(devices = ExAllocatePool(PagedPool, offsetof(DEVICE_RELATIONS, Objects[ext->u.fdo.child_count])))) + if (!(devices = ExAllocatePool( PagedPool, offsetof( DEVICE_RELATIONS, Objects[fdo->child_count] ) ))) { irp->IoStatus.Status = STATUS_NO_MEMORY; IoCompleteRequest(irp, IO_NO_INCREMENT); return STATUS_NO_MEMORY; }
- for (i = 0, devices->Count = 0; i < ext->u.fdo.child_count; ++i) + for (i = 0, devices->Count = 0; i < fdo->child_count; ++i) { - devices->Objects[i] = ext->u.fdo.child_pdos[i]; - call_fastcall_func1(ObfReferenceObject, ext->u.fdo.child_pdos[i]); + devices->Objects[i] = fdo->child_pdos[i]; + call_fastcall_func1( ObfReferenceObject, fdo->child_pdos[i] ); devices->Count++; }
irp->IoStatus.Information = (ULONG_PTR)devices; irp->IoStatus.Status = STATUS_SUCCESS; IoSkipCurrentIrpStackLocation(irp); - return IoCallDriver(ext->hid.NextDeviceObject, irp); + return IoCallDriver( fdo->base.hid.NextDeviceObject, irp ); }
case IRP_MN_START_DEVICE: status = minidriver->PNPDispatch( device, irp ); if (!status) status = initialize_device( minidriver, device ); if (!status) status = create_child_pdos( minidriver, device ); - if (!status) ext->u.fdo.thread = CreateThread(NULL, 0, hid_device_thread, device, 0, NULL); + if (!status) fdo->thread = CreateThread( NULL, 0, hid_device_thread, device, 0, NULL ); return status;
case IRP_MN_REMOVE_DEVICE: - if (ext->u.fdo.thread) + if (fdo->thread) { - KeSetEvent( &ext->u.fdo.halt_event, IO_NO_INCREMENT, FALSE ); - WaitForSingleObject(ext->u.fdo.thread, INFINITE); + KeSetEvent( &fdo->halt_event, IO_NO_INCREMENT, FALSE ); + WaitForSingleObject( fdo->thread, INFINITE ); }
status = minidriver->PNPDispatch( device, irp ); - HidP_FreeCollectionDescription( &ext->u.fdo.device_desc ); - free( ext->u.fdo.child_pdos ); - IoDetachDevice( ext->hid.NextDeviceObject ); + HidP_FreeCollectionDescription( &fdo->device_desc ); + free( fdo->child_pdos ); + IoDetachDevice( fdo->base.hid.NextDeviceObject ); IoDeleteDevice( device ); return status;
case IRP_MN_SURPRISE_REMOVAL: - KeSetEvent( &ext->u.fdo.halt_event, IO_NO_INCREMENT, FALSE ); + KeSetEvent( &fdo->halt_event, IO_NO_INCREMENT, FALSE ); return STATUS_SUCCESS;
default:
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/hidclass.sys/device.c | 48 +++++++++++--------------------------- dlls/hidclass.sys/hid.h | 3 +++ dlls/hidclass.sys/pnp.c | 29 +++++++++++++++++++++-- 3 files changed, 44 insertions(+), 36 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index a1bd6ff3c24..9f686683cfa 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -294,7 +294,7 @@ static void hid_device_queue_input( struct phys_device *pdo, HID_XFER_PACKET *pa hid_report_decref( last_report ); }
-static HIDP_REPORT_IDS *find_report_with_type_and_id( HIDP_DEVICE_DESC *desc, UCHAR collection, BYTE type, BYTE id, BOOL any_id ) +HIDP_REPORT_IDS *find_report_with_type_and_id( HIDP_DEVICE_DESC *desc, UCHAR collection, BYTE type, BYTE id, BOOL any_id ) { HIDP_REPORT_IDS *report, *reports = desc->ReportIDs; ULONG report_count = desc->ReportIDsLength; @@ -315,47 +315,27 @@ DWORD CALLBACK hid_device_thread(void *args) { DEVICE_OBJECT *device = (DEVICE_OBJECT*)args; struct func_device *fdo = fdo_from_DEVICE_OBJECT( device ); - ULONG i, input_length = 0, report_id = 0; HIDP_REPORT_IDS *report; - HID_XFER_PACKET *packet; - HIDP_DEVICE_DESC *desc; IO_STATUS_BLOCK io; NTSTATUS status; - BYTE *buffer; IRP *irp;
- for (i = 0; i < fdo->device_desc.CollectionDescLength; i++) - { - HIDP_COLLECTION_DESC *desc = fdo->device_desc.CollectionDesc + i; - input_length = max(input_length, desc->InputLength); - } - - packet = malloc( sizeof(*packet) + input_length ); - buffer = (BYTE *)(packet + 1); - - desc = &fdo->device_desc; - report = find_report_with_type_and_id( desc, 0, HidP_Input, 0, TRUE ); - if (!report) WARN("no input report found.\n"); - else report_id = report->ReportID; - do { LARGE_INTEGER delay = {.QuadPart = (LONGLONG)fdo->poll_interval * -10000}; + HID_XFER_PACKET packet = *fdo->io_packet; + BYTE *buffer = packet.reportBuffer; KEVENT irp_event;
- packet->reportId = buffer[0] = report_id; - packet->reportBuffer = buffer; - packet->reportBufferLen = input_length; - - if (!report_id) + if (!(packet.reportBuffer[0] = packet.reportId)) { - packet->reportBuffer++; - packet->reportBufferLen--; + packet.reportBuffer++; + packet.reportBufferLen--; }
KeInitializeEvent( &irp_event, NotificationEvent, FALSE ); - irp = IoBuildDeviceIoControlRequest( IOCTL_HID_READ_REPORT, device, NULL, 0, packet->reportBuffer, - packet->reportBufferLen, TRUE, &irp_event, &io ); + irp = IoBuildDeviceIoControlRequest( IOCTL_HID_READ_REPORT, device, NULL, 0, packet.reportBuffer, + packet.reportBufferLen, TRUE, &irp_event, &io ); if (IoCallDriver( device, irp ) == STATUS_PENDING) { void *events[2] = {&irp_event, &fdo->halt_event}; @@ -365,8 +345,8 @@ DWORD CALLBACK hid_device_thread(void *args)
if (io.Status == STATUS_SUCCESS) { - if (!report_id) io.Information++; - if (!(report = find_report_with_type_and_id( desc, 0, HidP_Input, buffer[0], FALSE ))) + if (!packet.reportId) io.Information++; + if (!(report = find_report_with_type_and_id( &fdo->device_desc, 0, HidP_Input, buffer[0], FALSE ))) ERR( "dropping unknown input id %u\n", buffer[0] ); else if (!fdo->poll_interval && io.Information < report->InputLength) ERR( "dropping short report, len %Iu expected %u\n", io.Information, report->InputLength ); @@ -375,10 +355,10 @@ DWORD CALLBACK hid_device_thread(void *args) else { struct phys_device *pdo = pdo_from_DEVICE_OBJECT( fdo->child_pdos[report->CollectionNumber - 1] ); - packet->reportId = buffer[0]; - packet->reportBuffer = buffer; - packet->reportBufferLen = io.Information; - hid_device_queue_input( pdo, packet, !!fdo->poll_interval ); + packet.reportId = buffer[0]; + packet.reportBuffer = buffer; + packet.reportBufferLen = io.Information; + hid_device_queue_input( pdo, &packet, !!fdo->poll_interval ); } }
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index 403102e8d88..7a6dccae336 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -62,6 +62,7 @@ struct func_device KEVENT halt_event; HANDLE thread;
+ HID_XFER_PACKET *io_packet; DEVICE_OBJECT **child_pdos; UINT child_count; }; @@ -132,6 +133,8 @@ typedef struct _minidriver
void call_minidriver( ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG in_size, void *out_buff, ULONG out_size, IO_STATUS_BLOCK *io ); +HIDP_REPORT_IDS *find_report_with_type_and_id( HIDP_DEVICE_DESC *desc, UCHAR collection, + BYTE type, BYTE id, BOOL any_id );
/* Internal device functions */ DWORD CALLBACK hid_device_thread(void *args); diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index e4e64a92bbc..c8d11cf43ba 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -330,6 +330,29 @@ static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device return STATUS_SUCCESS; }
+static NTSTATUS create_device_thread( DEVICE_OBJECT *device ) +{ + struct func_device *fdo = fdo_from_DEVICE_OBJECT( device ); + ULONG i, input_length = 0; + HIDP_REPORT_IDS *report; + + for (i = 0; i < fdo->device_desc.CollectionDescLength; i++) + { + HIDP_COLLECTION_DESC *desc = fdo->device_desc.CollectionDesc + i; + input_length = max( input_length, desc->InputLength ); + } + + if (!(fdo->io_packet = malloc( sizeof(*fdo->io_packet) + input_length ))) return STATUS_NO_MEMORY; + + if (!(report = find_report_with_type_and_id( &fdo->device_desc, 0, HidP_Input, 0, TRUE ))) WARN( "no input report found.\n" ); + fdo->io_packet->reportId = report ? report->ReportID : 0; + fdo->io_packet->reportBuffer = (BYTE *)(fdo->io_packet + 1); + fdo->io_packet->reportBufferLen = input_length; + + if (!(fdo->thread = CreateThread( NULL, 0, hid_device_thread, device, 0, NULL ))) return STATUS_UNSUCCESSFUL; + return STATUS_SUCCESS; +} + static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) { minidriver *minidriver = find_minidriver(device->DriverObject); @@ -373,7 +396,7 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) status = minidriver->PNPDispatch( device, irp ); if (!status) status = initialize_device( minidriver, device ); if (!status) status = create_child_pdos( minidriver, device ); - if (!status) fdo->thread = CreateThread( NULL, 0, hid_device_thread, device, 0, NULL ); + if (!status) status = create_device_thread( device ); return status;
case IRP_MN_REMOVE_DEVICE: @@ -383,7 +406,9 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) WaitForSingleObject( fdo->thread, INFINITE ); }
- status = minidriver->PNPDispatch( device, irp ); + if ((status = minidriver->PNPDispatch( device, irp ))) return status; + free( fdo->io_packet ); + HidP_FreeCollectionDescription( &fdo->device_desc ); free( fdo->child_pdos ); IoDetachDevice( fdo->base.hid.NextDeviceObject );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winexinput.sys/main.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/dlls/winexinput.sys/main.c b/dlls/winexinput.sys/main.c index 5a5c6ca8f00..45c6835bfe7 100644 --- a/dlls/winexinput.sys/main.c +++ b/dlls/winexinput.sys/main.c @@ -461,6 +461,24 @@ static WCHAR *query_compatible_ids(DEVICE_OBJECT *device) return dst; }
+static void remove_pending_irps(DEVICE_OBJECT *device) +{ + struct func_device *fdo = fdo_from_DEVICE_OBJECT(device); + IRP *pending; + + RtlEnterCriticalSection(&fdo->cs); + pending = fdo->pending_read; + fdo->pending_read = NULL; + RtlLeaveCriticalSection(&fdo->cs); + + if (pending) + { + pending->IoStatus.Status = STATUS_DELETE_PENDING; + pending->IoStatus.Information = 0; + IoCompleteRequest(pending, IO_NO_INCREMENT); + } +} + static NTSTATUS WINAPI pdo_pnp(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); @@ -468,7 +486,6 @@ static NTSTATUS WINAPI pdo_pnp(DEVICE_OBJECT *device, IRP *irp) struct device *impl = impl_from_DEVICE_OBJECT(device); UCHAR code = stack->MinorFunction; NTSTATUS status; - IRP *pending;
TRACE("device %p, irp %p, code %#x, bus_device %p.\n", device, irp, code, fdo->bus_device);
@@ -481,21 +498,11 @@ static NTSTATUS WINAPI pdo_pnp(DEVICE_OBJECT *device, IRP *irp) case IRP_MN_SURPRISE_REMOVAL: status = STATUS_SUCCESS; if (InterlockedExchange(&impl->removed, TRUE)) break; - - RtlEnterCriticalSection(&fdo->cs); - pending = fdo->pending_read; - fdo->pending_read = NULL; - RtlLeaveCriticalSection(&fdo->cs); - - if (pending) - { - pending->IoStatus.Status = STATUS_DELETE_PENDING; - pending->IoStatus.Information = 0; - IoCompleteRequest(pending, IO_NO_INCREMENT); - } + remove_pending_irps(device); break;
case IRP_MN_REMOVE_DEVICE: + remove_pending_irps(device); irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(irp, IO_NO_INCREMENT); IoDeleteDevice(device);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/hidclass.sys/pnp.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index c8d11cf43ba..aa58b8e288c 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -416,6 +416,7 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) return status;
case IRP_MN_SURPRISE_REMOVAL: + if ((status = minidriver->PNPDispatch( device, irp ))) return status; KeSetEvent( &fdo->halt_event, IO_NO_INCREMENT, FALSE ); return STATUS_SUCCESS;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/hidclass.sys/device.c | 26 +++++++++++++------------- dlls/hidclass.sys/hid.h | 4 ++++ dlls/hidclass.sys/pnp.c | 1 + 3 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 9f686683cfa..c884d4622e0 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -316,16 +316,15 @@ DWORD CALLBACK hid_device_thread(void *args) DEVICE_OBJECT *device = (DEVICE_OBJECT*)args; struct func_device *fdo = fdo_from_DEVICE_OBJECT( device ); HIDP_REPORT_IDS *report; - IO_STATUS_BLOCK io; NTSTATUS status; - IRP *irp;
do { LARGE_INTEGER delay = {.QuadPart = (LONGLONG)fdo->poll_interval * -10000}; HID_XFER_PACKET packet = *fdo->io_packet; BYTE *buffer = packet.reportBuffer; - KEVENT irp_event; + KEVENT *io_event = &fdo->io_event; + IO_STATUS_BLOCK *io = &fdo->io;
if (!(packet.reportBuffer[0] = packet.reportId)) { @@ -333,23 +332,24 @@ DWORD CALLBACK hid_device_thread(void *args) packet.reportBufferLen--; }
- KeInitializeEvent( &irp_event, NotificationEvent, FALSE ); - irp = IoBuildDeviceIoControlRequest( IOCTL_HID_READ_REPORT, device, NULL, 0, packet.reportBuffer, - packet.reportBufferLen, TRUE, &irp_event, &io ); - if (IoCallDriver( device, irp ) == STATUS_PENDING) + KeInitializeEvent( io_event, NotificationEvent, FALSE ); + fdo->io_irp = IoBuildDeviceIoControlRequest( IOCTL_HID_READ_REPORT, device, NULL, 0, packet.reportBuffer, + packet.reportBufferLen, TRUE, io_event, io ); + if (IoCallDriver( device, fdo->io_irp ) == STATUS_PENDING) { - void *events[2] = {&irp_event, &fdo->halt_event}; + void *events[2] = {io_event, &fdo->halt_event}; status = KeWaitForMultipleObjects( 2, events, WaitAny, Executive, KernelMode, FALSE, NULL, NULL ); if (status) break; } + fdo->io_irp = NULL;
- if (io.Status == STATUS_SUCCESS) + if (io->Status == STATUS_SUCCESS) { - if (!packet.reportId) io.Information++; + if (!packet.reportId) io->Information++; if (!(report = find_report_with_type_and_id( &fdo->device_desc, 0, HidP_Input, buffer[0], FALSE ))) ERR( "dropping unknown input id %u\n", buffer[0] ); - else if (!fdo->poll_interval && io.Information < report->InputLength) - ERR( "dropping short report, len %Iu expected %u\n", io.Information, report->InputLength ); + else if (!fdo->poll_interval && io->Information < report->InputLength) + ERR( "dropping short report, len %Iu expected %u\n", io->Information, report->InputLength ); else if (!report->CollectionNumber || report->CollectionNumber > fdo->child_count) ERR( "dropping report for unknown child %u\n", report->CollectionNumber ); else @@ -357,7 +357,7 @@ DWORD CALLBACK hid_device_thread(void *args) struct phys_device *pdo = pdo_from_DEVICE_OBJECT( fdo->child_pdos[report->CollectionNumber - 1] ); packet.reportId = buffer[0]; packet.reportBuffer = buffer; - packet.reportBufferLen = io.Information; + packet.reportBufferLen = io->Information; hid_device_queue_input( pdo, &packet, !!fdo->poll_interval ); } } diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index 7a6dccae336..f47402efbd9 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -63,6 +63,10 @@ struct func_device HANDLE thread;
HID_XFER_PACKET *io_packet; + IO_STATUS_BLOCK io; + KEVENT io_event; + IRP *io_irp; + DEVICE_OBJECT **child_pdos; UINT child_count; }; diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index aa58b8e288c..8356c646f50 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -407,6 +407,7 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) }
if ((status = minidriver->PNPDispatch( device, irp ))) return status; + if (fdo->io_irp) KeWaitForSingleObject( &fdo->io_event, Executive, KernelMode, FALSE, NULL ); free( fdo->io_packet );
HidP_FreeCollectionDescription( &fdo->device_desc );