From: Aric Stewart Subject: [13/13](resend)Add wine specific IOCTLs Message-Id: <55E6E56D.4080908@codeweavers.com> Date: Wed, 2 Sep 2015 07:02:53 -0500 --- dlls/hidclass.sys/pnp.c | 80 +++++++++++++++++++++++++++++-------------------- include/ddk/hidport.h | 9 ++++++ 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index 9634d9a..411abe5 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -114,9 +114,7 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, void *native) DWORD index = HID_STRING_ID_ISERIALNUMBER; NATIVE_DEVICE *tracked_device, *ptr; INT interface_index = 1; - HID_DESCRIPTOR descriptor; - BYTE *reportDescriptor; - INT i; + INT size; static const WCHAR ig_fmtW[] = {'I','G','_','%','i',0}; static const WCHAR im_fmtW[] = {'I','M','_','%','i',0}; @@ -177,42 +175,60 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, void *native) list_add_tail(&tracked_devices, &tracked_device->entry); - status = call_minidriver(IOCTL_HID_GET_DEVICE_DESCRIPTOR, device, NULL, 0, - &descriptor, sizeof(descriptor)); - if (status != STATUS_SUCCESS) - { - ERR("Cannot get Device Descriptor(%x)\n",status); - PNP_SendPnPIRP(device, IRP_MN_REMOVE_DEVICE); - HID_DeleteDevice(&minidriver->minidriver, device); - return status; - } - for (i = 0; i < descriptor.bNumDescriptors; i++) - if (descriptor.DescriptorList[i].bReportType == HID_REPORT_DESCRIPTOR_TYPE) - break; + status = call_minidriver(IOCTL_WINE_HID_GET_PREPARSED_SIZE, device, + NULL, 0, &size, sizeof(size)); - if (i >= descriptor.bNumDescriptors) + if (status == STATUS_SUCCESS) { - ERR("No Report Descriptor found in reply\n"); - PNP_SendPnPIRP(device, IRP_MN_REMOVE_DEVICE); - HID_DeleteDevice(&minidriver->minidriver, device); - return status; + ext->information.DescriptorSize = size; + ext->preparseData = HeapAlloc(GetProcessHeap(), 0, ext->information.DescriptorSize); + status = call_minidriver(IOCTL_WINE_HID_GET_PREPARSED, device, + NULL, 0, ext->preparseData, size); } - - reportDescriptor = HeapAlloc(GetProcessHeap(), 0, descriptor.DescriptorList[i].wReportLength); - status = call_minidriver(IOCTL_HID_GET_REPORT_DESCRIPTOR, device, NULL, 0, - reportDescriptor, descriptor.DescriptorList[i].wReportLength); - if (status != STATUS_SUCCESS) + else { - ERR("Cannot get Report Descriptor(%x)\n",status); - HID_DeleteDevice(&minidriver->minidriver, device); + HID_DESCRIPTOR descriptor; + BYTE *reportDescriptor; + INT i; + + status = call_minidriver(IOCTL_HID_GET_DEVICE_DESCRIPTOR, device, NULL, 0, + &descriptor, sizeof(descriptor)); + if (status != STATUS_SUCCESS) + { + ERR("Cannot get Device Descriptor(%x)\n",status); + PNP_SendPnPIRP(device, IRP_MN_REMOVE_DEVICE); + HID_DeleteDevice(&minidriver->minidriver, device); + return status; + } + for (i = 0; i < descriptor.bNumDescriptors; i++) + if (descriptor.DescriptorList[i].bReportType == HID_REPORT_DESCRIPTOR_TYPE) + break; + + if (i >= descriptor.bNumDescriptors) + { + ERR("No Report Descriptor found in reply\n"); + PNP_SendPnPIRP(device, IRP_MN_REMOVE_DEVICE); + HID_DeleteDevice(&minidriver->minidriver, device); + return status; + } + + reportDescriptor = HeapAlloc(GetProcessHeap(), 0, descriptor.DescriptorList[i].wReportLength); + status = call_minidriver(IOCTL_HID_GET_REPORT_DESCRIPTOR, device, NULL, 0, + reportDescriptor, descriptor.DescriptorList[i].wReportLength); + if (status != STATUS_SUCCESS) + { + ERR("Cannot get Report Descriptor(%x)\n",status); + PNP_SendPnPIRP(device, IRP_MN_REMOVE_DEVICE); + HID_DeleteDevice(&minidriver->minidriver, device); + HeapFree(GetProcessHeap(), 0, reportDescriptor); + return status; + } + + ext->preparseData = ParseDescriptor(reportDescriptor, descriptor.DescriptorList[0].wReportLength); + ext->information.DescriptorSize = ext->preparseData->dwSize; HeapFree(GetProcessHeap(), 0, reportDescriptor); - return status; } - ext->preparseData = ParseDescriptor(reportDescriptor, descriptor.DescriptorList[0].wReportLength); - ext->information.DescriptorSize = ext->preparseData->dwSize; - HeapFree(GetProcessHeap(), 0, reportDescriptor); - status = call_minidriver(IOCTL_HID_GET_STRING, device, (void*)index, sizeof(DWORD), serial, sizeof(serial)); diff --git a/include/ddk/hidport.h b/include/ddk/hidport.h index 3ebe2735..cdb1fb1 100644 --- a/include/ddk/hidport.h +++ b/include/ddk/hidport.h @@ -76,4 +76,13 @@ typedef struct _HID_DESCRIPTOR #define IOCTL_HID_GET_DEVICE_ATTRIBUTES HID_CTL_CODE(9) #define IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST HID_CTL_CODE(10) +/* A few WINE custom ioctls */ +/* These are provided to allow a route around doing USB HID Device Descriptor + parsing If a WINE minidriver does not have access to the underlying HID + Device descriptor or the HID reports then instead of having to hand build + a HID descriptor the minidriver can simply hand build the preparse data + instead */ +#define IOCTL_WINE_HID_GET_PREPARSED_SIZE HID_CTL_CODE(20) +#define IOCTL_WINE_HID_GET_PREPARSED HID_CTL_CODE(21) + #endif /* __HIDPORT_H__ */