[3/5] mountmgr.sys: detect USB devices and notify usbhub.sys

Damjan Jovanovic damjan.jov at gmail.com
Sun Apr 18 03:28:29 CDT 2010


Changelog:
* mountmgr.sys: detect USB devices and notify usbhub.sys

Damjan Jovanovic
-------------- next part --------------
diff --git a/dlls/mountmgr.sys/hal.c b/dlls/mountmgr.sys/hal.c
index 82a70e9..3ca1b54 100644
--- a/dlls/mountmgr.sys/hal.c
+++ b/dlls/mountmgr.sys/hal.c
@@ -34,6 +34,7 @@
 #include "wine/library.h"
 #include "wine/exception.h"
 #include "wine/debug.h"
+#include "wine/wine_ioctl.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mountmgr);
 
@@ -60,6 +61,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mountmgr);
     DO_FUNC(libhal_ctx_set_device_removed); \
     DO_FUNC(libhal_ctx_shutdown); \
     DO_FUNC(libhal_device_get_property_bool); \
+    DO_FUNC(libhal_device_get_property_int); \
     DO_FUNC(libhal_device_get_property_string); \
     DO_FUNC(libhal_device_add_property_watch); \
     DO_FUNC(libhal_device_remove_property_watch); \
@@ -133,6 +135,73 @@ static GUID *parse_uuid( GUID *guid, const char *str )
     return NULL;
 }
 
+static void process_usb_device( LibHalContext *ctx, const char *udi )
+{
+    static const WCHAR wine_usb_masterW[] = {'\\','\\','.','\\','W','I','N','E','_','U','S','B','_','M','A','S','T','E','R',0};
+    DBusError error;
+    char *subsystem = NULL;
+    char *serial = NULL;
+    WINE_USBHUB_NEW_DEVICE_INFO *newdev = NULL;
+    int retries;
+
+    p_dbus_error_init( &error );
+
+    if (!(subsystem = p_libhal_device_get_property_string( ctx, udi, "info.subsystem", &error )))
+        goto done;
+    if (strcmp( subsystem, "usb_device" ))
+        goto done;
+
+    serial = p_libhal_device_get_property_string( ctx, udi, "usb_device.serial", NULL );
+
+    newdev = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_USBHUB_NEW_DEVICE_INFO) + (serial ? lstrlenA(serial) : 0));
+    if (!newdev)
+        goto done;
+    if (serial)
+    {
+        strcpy(newdev->serial, serial);
+        newdev->has_serial = TRUE;
+    }
+    else
+        newdev->has_serial = FALSE;
+
+    newdev->vendor_id = p_libhal_device_get_property_int( ctx, udi, "usb_device.vendor_id", &error );
+    if (p_dbus_error_is_set( &error ))
+        goto done;
+
+    newdev->product_id = p_libhal_device_get_property_int( ctx, udi, "usb_device.product_id", &error );
+    if (p_dbus_error_is_set( &error ))
+        goto done;
+
+    newdev->bus_number = p_libhal_device_get_property_int( ctx, udi, "usb_device.bus_number", &error );
+    if (p_dbus_error_is_set( &error ))
+        goto done;
+
+    /* Give usbhub.sys some time to start */
+    for (retries = 0; retries < 5; retries++)
+    {
+        HANDLE handle = CreateFileW(wine_usb_masterW, GENERIC_ALL, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+        if (handle != INVALID_HANDLE_VALUE)
+        {
+            DWORD bytesReturned;
+            WINE_TRACE("Submitting new USB device with VendorId=0x%04X ProductId=0x%04X Serial=%s Bus=%d to usbhub.sys\n",
+                newdev->vendor_id, newdev->product_id, newdev->has_serial ? wine_dbgstr_a(newdev->serial) : "", newdev->bus_number);
+            DeviceIoControl(handle, WINE_USBHUB_DEVICE_ADDED,
+                            newdev, sizeof(WINE_USBHUB_NEW_DEVICE_INFO) + (serial ? lstrlenA(serial) : 0),
+                            NULL, 0,
+                            &bytesReturned, NULL);
+            CloseHandle(handle);
+            break;
+        }
+        Sleep(1000);
+    }
+
+done:
+    HeapFree(GetProcessHeap(), 0, newdev);
+    if (serial) p_libhal_free_string( serial );
+    if (subsystem) p_libhal_free_string( subsystem );
+    p_dbus_error_free( &error );
+}
+
 /* HAL callback for new device */
 static void new_device( LibHalContext *ctx, const char *udi )
 {
@@ -148,7 +217,10 @@ static void new_device( LibHalContext *ctx, const char *udi )
     p_dbus_error_init( &error );
 
     if (!(device = p_libhal_device_get_property_string( ctx, udi, "block.device", &error )))
+    {
+        process_usb_device( ctx, udi );
         goto done;
+    }
 
     if (!(mount_point = p_libhal_device_get_property_string( ctx, udi, "volume.mount_point", &error )))
         goto done;


More information about the wine-patches mailing list