[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