[Wine-patches] [eterhack 11/23] usbhub.sys: Create interfaces for root hubs.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Пт Июн 5 13:00:11 MSD 2009


---
 dlls/usbhub.sys/usbhub.c |   61 ++++++++++++++++++++++++++++++++++++++++++----
 include/ddk/usbiodef.h   |    3 ++
 2 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/dlls/usbhub.sys/usbhub.c b/dlls/usbhub.sys/usbhub.c
index 94d8b33..fb3f860 100644
--- a/dlls/usbhub.sys/usbhub.c
+++ b/dlls/usbhub.sys/usbhub.c
@@ -30,6 +30,7 @@
 
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+#define INITGUID
 
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
@@ -42,6 +43,7 @@
 #include "winuser.h"
 #include "setupapi.h"
 #include "cfgmgr32.h"
+#include "devguid.h"
 #include "ddk/ntddk.h"
 #include "ddk/usbdrivr.h"
 #include "wine/unicode.h"
@@ -54,6 +56,8 @@ extern NTSTATUS CDECL __wine_add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT *d
 extern DRIVER_OBJECT * CDECL __wine_get_driver_object( const WCHAR *service );
 extern NTSTATUS CDECL __wine_start_device( DEVICE_OBJECT *device );
 
+static const WCHAR usbW[] = {'U','S','B',0};
+
 static struct list Devices = LIST_INIT(Devices);
 
 struct DeviceInstance
@@ -951,6 +955,50 @@ static DEVICE_OBJECT *create_pdo( struct DeviceInstance *inst, DRIVER_OBJECT *hu
     return usbdev;
 }
 
+static void register_root_hub_device( DEVICE_OBJECT *dev, unsigned int instance_id )
+{
+    static const WCHAR root_hub_idW[] = {'U','S','B',
+                                         '\\','R','O','O','T','_','H','U','B',
+                                         '\\','%','u',0};
+
+    HDEVINFO set;
+    SP_DEVINFO_DATA devInfo;
+    WCHAR *devnameW;
+    ULONG size;
+    BOOL ret;
+    UNICODE_STRING link;
+    NTSTATUS status;
+
+    size = sizeof(root_hub_idW) + 16 * sizeof(WCHAR);
+    devnameW = HeapAlloc( GetProcessHeap(), 0, size );
+    if (devnameW == NULL) return;
+    snprintfW( devnameW, size / sizeof(WCHAR), root_hub_idW, instance_id );
+
+    set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
+    if (set == INVALID_HANDLE_VALUE) goto done;
+    devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
+    ret = SetupDiCreateDeviceInfoW( set, devnameW, &GUID_DEVCLASS_USB,
+            NULL, NULL, 0, &devInfo );
+    if (ret)
+    {
+        ret = SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL );
+        if (!ret) goto done;
+    }
+    else if (ERROR_DEVINST_ALREADY_EXISTS != GetLastError()) goto done;
+
+    status = IoRegisterDeviceInterface( dev, &GUID_DEVINTERFACE_USB_HUB,
+            NULL, &link );
+    if (status == STATUS_SUCCESS)
+    {
+        IoSetDeviceInterfaceState( &link, TRUE );
+        RtlFreeUnicodeString( &link );
+    }
+done:
+    if (set != INVALID_HANDLE_VALUE)
+        SetupDiDestroyDeviceInfoList( set );
+    HeapFree( GetProcessHeap(), 0, devnameW );
+}
+
 static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
         DRIVER_OBJECT *hubdrv )
 {
@@ -973,11 +1021,12 @@ static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
     if (IoCreateDevice( hubdrv, sizeof(struct PdoExtension), &pdo_name,
         0, 0, FALSE, &hubdev ) != STATUS_SUCCESS) goto fail;
 
-    ++instance_id;
     list_add_tail( &Devices, &instance->entry );
     ((struct PdoExtension *)hubdev->DeviceExtension)->instance = instance;
     hubdev->Flags |= DO_POWER_PAGABLE;
     hubdev->Flags &= ~DO_DEVICE_INITIALIZING;
+    register_root_hub_device( hubdev, instance_id );
+    ++instance_id;
     return;
 fail:
     if (instance->instance_id)
@@ -989,8 +1038,6 @@ fail:
 
 static BOOL enum_reg_usb_devices(void)
 {
-    static const WCHAR usb[] = {'U','S','B',0};
-
     SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
     char *instance_id = NULL;
     struct DeviceInstance *instance, *instance2;
@@ -1000,7 +1047,7 @@ static BOOL enum_reg_usb_devices(void)
     char *str, *buf;
     BOOL ret;
 
-    set = SetupDiGetClassDevsW( NULL, usb, 0, DIGCF_ALLCLASSES );
+    set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
     if (set == INVALID_HANDLE_VALUE) return FALSE;
 
     while (SetupDiEnumDeviceInfo( set, i++, &devInfo ))
@@ -1012,7 +1059,11 @@ static BOOL enum_reg_usb_devices(void)
         if (buf == NULL) goto fail;
         ret = SetupDiGetDeviceRegistryPropertyA( set, &devInfo, SPDRP_HARDWAREID,
                 NULL, (BYTE *)buf, size, NULL );
-        if (!ret) goto fail;
+        if (!ret)
+        {
+            HeapFree( GetProcessHeap(), 0, buf );
+            continue;
+        }
         str = strstr( buf, "Vid_" );
         if (str != NULL)
         {
diff --git a/include/ddk/usbiodef.h b/include/ddk/usbiodef.h
index 15a54fa..6865adc 100644
--- a/include/ddk/usbiodef.h
+++ b/include/ddk/usbiodef.h
@@ -21,6 +21,9 @@
 
 #define USB_SUBMIT_URB           0
 
+DEFINE_GUID( GUID_DEVINTERFACE_USB_HUB,
+  0xF18A0E88, 0xC30C, 0x11D0, 0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8 );
+
 #define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN
 
 #endif  /* __USBIODEF_H__ */
-- 
1.6.3.1



Подробная информация о списке рассылки Wine-patches