[Wine-patches] [eterhack 2/5] usbhub.sys: Add wine-specific IOCTL_USB_GET_DEVICE_INFO.
Alexander Morozov
amorozov на etersoft.ru
Вт Июн 23 16:16:49 MSD 2009
---
dlls/usbhub.sys/usbhub.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
include/ddk/usbioctl.h | 15 ++++++++++
include/ddk/usbiodef.h | 4 ++
3 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/dlls/usbhub.sys/usbhub.c b/dlls/usbhub.sys/usbhub.c
index 34d7b11..ca3a537 100644
--- a/dlls/usbhub.sys/usbhub.c
+++ b/dlls/usbhub.sys/usbhub.c
@@ -45,6 +45,7 @@
#include "cfgmgr32.h"
#include "devguid.h"
#include "ddk/ntddk.h"
+#define WINE_USBHUB_EXTENSIONS
#include "ddk/usbdrivr.h"
#include "ddk/usbioctl.h"
#include "wine/unicode.h"
@@ -96,6 +97,12 @@ static void add_data( unsigned char **dst, ULONG *dst_size, const void *src, ULO
static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
{
+ static const WCHAR device_idW[] = {'U','S','B','\\',
+ 'V','i','d','_','%','0','4','x','&',
+ 'P','i','d','_','%','0','4','x','\\',0};
+ static const WCHAR root_hub_idW[] = {'U','S','B','\\',
+ 'R','O','O','T','_','H','U','B','\\',0};
+
IO_STACK_LOCATION *irpsp;
NTSTATUS status = STATUS_UNSUCCESSFUL;
struct DeviceInstance *inst;
@@ -179,6 +186,69 @@ static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
info = sizeof(*conn_info);
break;
}
+ case IOCTL_USB_GET_DEVICE_INFO:
+ {
+ struct usb_device_info *dev_info = irp->AssociatedIrp.SystemBuffer;
+ struct DeviceInstance *instance;
+ ULONG len, index = 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(*dev_info))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ if (!dev_info->connection_index || dev_info->connection_index > NUMBER_OF_PORTS)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ RtlZeroMemory( (ULONG *)dev_info + 1, sizeof(*dev_info) - sizeof(ULONG) );
+ memcpy( dev_info->root_hub_id, root_hub_idW, sizeof(root_hub_idW) );
+ len = strlenW(root_hub_idW);
+ RtlMultiByteToUnicodeN( dev_info->root_hub_id + len,
+ (MAX_DEVICE_ID_LEN - len) * sizeof(WCHAR), NULL,
+ inst->instance_id, strlen(inst->instance_id) + 1 );
+#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 == dev_info->connection_index)
+ {
+ dev_info->device_address = libusb_get_device_address( instance->dev );
+ break;
+ }
+ }
+#else
+ for (dev = inst->dev->next; dev; dev = dev->next)
+ if (++index == dev_info->connection_index)
+ {
+ dev_info->device_address = dev->devnum;
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev == dev) break;
+ }
+ break;
+ }
+#endif
+ if (dev_info->device_address)
+ {
+ snprintfW( dev_info->device_id, MAX_DEVICE_ID_LEN, device_idW,
+ instance->vid, instance->pid );
+ len = strlenW(dev_info->device_id);
+ RtlMultiByteToUnicodeN( dev_info->device_id + len,
+ (MAX_DEVICE_ID_LEN - len) * sizeof(WCHAR), NULL,
+ instance->instance_id, strlen(instance->instance_id) + 1 );
+ }
+ status = STATUS_SUCCESS;
+ info = sizeof(*dev_info);
+ break;
+ }
default:
FIXME( "IOCTL %08x is not implemented\n",
irpsp->Parameters.DeviceIoControl.IoControlCode );
diff --git a/include/ddk/usbioctl.h b/include/ddk/usbioctl.h
index 5083491..9fe9203 100644
--- a/include/ddk/usbioctl.h
+++ b/include/ddk/usbioctl.h
@@ -25,6 +25,21 @@
#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)
+/* Wine extensions */
+#ifdef WINE_USBHUB_EXTENSIONS
+
+#define IOCTL_USB_GET_DEVICE_INFO CTL_CODE(FILE_DEVICE_USB, USB_GET_DEVICE_INFO, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+struct usb_device_info
+{
+ ULONG connection_index;
+ ULONG device_address;
+ WCHAR device_id[MAX_DEVICE_ID_LEN];
+ WCHAR root_hub_id[MAX_DEVICE_ID_LEN];
+};
+
+#endif
+
#include <pshpack1.h>
typedef enum _USB_HUB_NODE {
diff --git a/include/ddk/usbiodef.h b/include/ddk/usbiodef.h
index 67d6e7a..9370e24 100644
--- a/include/ddk/usbiodef.h
+++ b/include/ddk/usbiodef.h
@@ -24,6 +24,10 @@
#define USB_GET_NODE_INFORMATION 258
#define USB_GET_NODE_CONNECTION_INFORMATION 259
+#ifdef WINE_USBHUB_EXTENSIONS
+#define USB_GET_DEVICE_INFO 280
+#endif
+
DEFINE_GUID( GUID_DEVINTERFACE_USB_HUB,
0xF18A0E88, 0xC30C, 0x11D0, 0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8 );
--
1.6.3.2
Подробная информация о списке рассылки Wine-patches