[Wine-patches] [eterhack 3/5] usbhub.sys: Implement IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME.
Alexander Morozov
amorozov на etersoft.ru
Вт Июн 23 16:16:50 MSD 2009
---
dlls/usbhub.sys/usbhub.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++
include/ddk/usbioctl.h | 11 ++++-
include/ddk/usbiodef.h | 5 +-
3 files changed, 115 insertions(+), 4 deletions(-)
diff --git a/dlls/usbhub.sys/usbhub.c b/dlls/usbhub.sys/usbhub.c
index ca3a537..b468625 100644
--- a/dlls/usbhub.sys/usbhub.c
+++ b/dlls/usbhub.sys/usbhub.c
@@ -186,6 +186,109 @@ static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
info = sizeof(*conn_info);
break;
}
+ case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
+ {
+ USB_NODE_CONNECTION_DRIVERKEY_NAME *driver_key_name =
+ irp->AssociatedIrp.SystemBuffer;
+ WCHAR *dev_instance_idW, *bufW;
+ struct DeviceInstance *instance;
+ HDEVINFO set;
+ SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
+ ULONG len, index = 0, found = 0;
+#ifdef HAVE_LIBUSB_H
+ uint8_t bus_number = libusb_get_bus_number( inst->dev );
+#else
+ struct usb_device *dev;
+#endif
+
+ if (irpsp->Parameters.DeviceIoControl.OutputBufferLength <
+ sizeof(*driver_key_name))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+#ifdef HAVE_LIBUSB_H
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev && instance->dev != inst->dev &&
+ libusb_get_bus_number( instance->dev ) == bus_number &&
+ ++index == driver_key_name->ConnectionIndex)
+ {
+ found = 1;
+ break;
+ }
+ }
+#else
+ for (dev = inst->dev->next; dev; dev = dev->next)
+ if (++index == driver_key_name->ConnectionIndex)
+ {
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev == dev)
+ {
+ found = 1;
+ break;
+ }
+ }
+ break;
+ }
+#endif
+ if (!found)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ bufW = HeapAlloc( GetProcessHeap(), 0,
+ 2 * MAX_DEVICE_ID_LEN * sizeof(WCHAR) );
+ if (bufW == NULL)
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+ dev_instance_idW = bufW + MAX_DEVICE_ID_LEN;
+ snprintfW( dev_instance_idW, MAX_DEVICE_ID_LEN, device_idW,
+ instance->vid, instance->pid );
+ len = strlenW(dev_instance_idW);
+ RtlMultiByteToUnicodeN( dev_instance_idW + len,
+ (MAX_DEVICE_ID_LEN - len) * sizeof(WCHAR), NULL,
+ instance->instance_id, strlen(instance->instance_id) + 1 );
+ set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
+ if (set == INVALID_HANDLE_VALUE)
+ {
+ HeapFree( GetProcessHeap(), 0, bufW );
+ break;
+ }
+ index = 0;
+ while (SetupDiEnumDeviceInfo( set, index++, &devInfo ))
+ {
+ if (!SetupDiGetDeviceInstanceIdW( set, &devInfo, bufW,
+ MAX_DEVICE_ID_LEN, NULL ))
+ break;
+ if (!strcmpiW( dev_instance_idW, bufW ))
+ {
+ SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_DRIVER,
+ NULL, NULL, 0, &len );
+ driver_key_name->ActualLength = 2 * sizeof(ULONG) + len;
+ if (irpsp->Parameters.DeviceIoControl.OutputBufferLength <
+ driver_key_name->ActualLength)
+ {
+ status = STATUS_SUCCESS;
+ info = sizeof(*driver_key_name);
+ }
+ else if (SetupDiGetDeviceRegistryPropertyW( set, &devInfo,
+ SPDRP_DRIVER, NULL, (BYTE *)driver_key_name->DriverKeyName,
+ len, NULL ))
+ {
+ status = STATUS_SUCCESS;
+ info = driver_key_name->ActualLength;
+ }
+ break;
+ }
+ }
+ SetupDiDestroyDeviceInfoList( set );
+ HeapFree( GetProcessHeap(), 0, bufW );
+ break;
+ }
case IOCTL_USB_GET_DEVICE_INFO:
{
struct usb_device_info *dev_info = irp->AssociatedIrp.SystemBuffer;
diff --git a/include/ddk/usbioctl.h b/include/ddk/usbioctl.h
index 9fe9203..fd80b11 100644
--- a/include/ddk/usbioctl.h
+++ b/include/ddk/usbioctl.h
@@ -22,8 +22,9 @@
#include <ddk/usb100.h>
#include <ddk/usbiodef.h>
-#define IOCTL_USB_GET_NODE_INFORMATION CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_USB_GET_NODE_INFORMATION CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* Wine extensions */
#ifdef WINE_USBHUB_EXTENSIONS
@@ -93,6 +94,12 @@ typedef struct _USB_NODE_CONNECTION_INFORMATION {
USB_PIPE_INFO PipeList[0];
} USB_NODE_CONNECTION_INFORMATION, *PUSB_NODE_CONNECTION_INFORMATION;
+typedef struct _USB_NODE_CONNECTION_DRIVERKEY_NAME {
+ ULONG ConnectionIndex;
+ ULONG ActualLength;
+ WCHAR DriverKeyName[1];
+} USB_NODE_CONNECTION_DRIVERKEY_NAME, *PUSB_NODE_CONNECTION_DRIVERKEY_NAME;
+
#include <poppack.h>
#endif /* __USBIOCTL_H__ */
diff --git a/include/ddk/usbiodef.h b/include/ddk/usbiodef.h
index 9370e24..7d26f48 100644
--- a/include/ddk/usbiodef.h
+++ b/include/ddk/usbiodef.h
@@ -21,8 +21,9 @@
#define USB_SUBMIT_URB 0
-#define USB_GET_NODE_INFORMATION 258
-#define USB_GET_NODE_CONNECTION_INFORMATION 259
+#define USB_GET_NODE_INFORMATION 258
+#define USB_GET_NODE_CONNECTION_INFORMATION 259
+#define USB_GET_NODE_CONNECTION_DRIVERKEY_NAME 264
#ifdef WINE_USBHUB_EXTENSIONS
#define USB_GET_DEVICE_INFO 280
--
1.6.3.2
Подробная информация о списке рассылки Wine-patches