[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