[PATCH 5/6] winebus.sys: Query serialnumber string on device creation.

Rémi Bernon rbernon at codeweavers.com
Mon Sep 13 06:01:48 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus_iohid.c |  9 +++----
 dlls/winebus.sys/bus_sdl.c   |  9 ++-----
 dlls/winebus.sys/bus_udev.c  | 50 +++++++-----------------------------
 dlls/winebus.sys/main.c      | 11 ++++++--
 dlls/winebus.sys/unixlib.c   |  4 +--
 dlls/winebus.sys/unixlib.h   |  6 ++---
 6 files changed, 28 insertions(+), 61 deletions(-)

diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c
index 274d104e1f4..d80c7b3aad5 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -190,9 +190,6 @@ static NTSTATUS iohid_device_get_string(struct unix_device *iface, DWORD index,
     CFStringRef str;
     switch (index)
     {
-        case HID_STRING_ID_ISERIALNUMBER:
-            str = IOHIDDeviceGetProperty(private->device, CFSTR(kIOHIDSerialNumberKey));
-            break;
         default:
             ERR("Unknown string index\n");
             return STATUS_NOT_IMPLEMENTED;
@@ -288,7 +285,7 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
     {
         .busid = busidW,
         .input = -1,
-        .serial = {'0','0','0','0',0},
+        .serialnumber = {"0000"},
     };
     struct platform_private *private;
     CFStringRef str = NULL;
@@ -296,8 +293,6 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
     desc.vid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDVendorIDKey)));
     desc.pid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductIDKey)));
     desc.version = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDVersionNumberKey)));
-    str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDSerialNumberKey));
-    if (str) CFStringToWSTR(str, desc.serial, ARRAY_SIZE(desc.serial));
     desc.uid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDLocationIDKey)));
 
     if (IOHIDDeviceOpen(IOHIDDevice, 0) != kIOReturnSuccess)
@@ -311,6 +306,8 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
     if (str) lstrcpynA(desc.manufacturer, str, sizeof(desc.manufacturer));
     str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductKey));
     if (str) lstrcpynA(desc.product, str, sizeof(desc.product));
+    str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDSerialNumberKey));
+    if (str) lstrcpynA(desc.serialnumber, str, sizeof(desc.serialnumber));
 
     if (IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad) ||
        IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 534cb5da6f5..78c22f0e139 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -521,9 +521,6 @@ static NTSTATUS sdl_device_get_string(struct unix_device *iface, DWORD index, WC
 
     switch (index)
     {
-        case HID_STRING_ID_ISERIALNUMBER:
-            str = "000000";
-            break;
         default:
             ERR("Unhandled string index %i\n", index);
     }
@@ -728,11 +725,10 @@ static void sdl_add_device(unsigned int index)
     {
         .busid = sdl_busidW,
         .input = -1,
-        .serial = {'0','0','0','0',0},
         .manufacturer = {"SDL"},
+        .serialnumber = {"0000"},
     };
     struct platform_private *private;
-    char guid_str[34];
 
     SDL_Joystick* joystick;
     SDL_JoystickID id;
@@ -766,8 +762,7 @@ static void sdl_add_device(unsigned int index)
     }
 
     guid = pSDL_JoystickGetGUID(joystick);
-    pSDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));
-    MultiByteToWideChar(CP_ACP, 0, guid_str, -1, desc.serial, sizeof(guid_str));
+    pSDL_JoystickGetGUIDString(guid, desc.serialnumber, sizeof(desc.serialnumber));
 
     if (controller) desc.is_gamepad = TRUE;
     else
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 859363512dc..6cfd4e7fb38 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -554,28 +554,6 @@ static BOOL set_report_from_event(struct wine_input_private *ext, struct input_e
 }
 #endif
 
-static inline WCHAR *strdupAtoW(const char *src)
-{
-    WCHAR *dst;
-    DWORD len;
-    if (!src) return NULL;
-    len = MultiByteToWideChar(CP_UNIXCP, 0, src, -1, NULL, 0);
-    if ((dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
-        MultiByteToWideChar(CP_UNIXCP, 0, src, -1, dst, len);
-    return dst;
-}
-
-static WCHAR *get_sysattr_string(struct udev_device *dev, const char *sysattr)
-{
-    const char *attr = udev_device_get_sysattr_value(dev, sysattr);
-    if (!attr)
-    {
-        WARN("Could not get %s from device\n", sysattr);
-        return NULL;
-    }
-    return strdupAtoW(attr);
-}
-
 static void hidraw_device_destroy(struct unix_device *iface)
 {
     struct platform_private *private = impl_from_unix_device(iface);
@@ -674,9 +652,6 @@ static NTSTATUS hidraw_device_get_string(struct unix_device *iface, DWORD index,
     {
         switch (index)
         {
-            case HID_STRING_ID_ISERIALNUMBER:
-                str = get_sysattr_string(usbdev, "serial");
-                break;
             default:
                 ERR("Unhandled string index %08x\n", index);
                 return STATUS_NOT_IMPLEMENTED;
@@ -687,8 +662,6 @@ static NTSTATUS hidraw_device_get_string(struct unix_device *iface, DWORD index,
 #ifdef HAVE_LINUX_HIDRAW_H
         switch (index)
         {
-            case HID_STRING_ID_ISERIALNUMBER:
-                break;
             default:
                 ERR("Unhandled string index %08x\n", index);
                 return STATUS_NOT_IMPLEMENTED;
@@ -943,15 +916,11 @@ static NTSTATUS lnxev_device_get_report_descriptor(struct unix_device *iface, BY
 
 static NTSTATUS lnxev_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
 {
-    struct wine_input_private *ext = input_impl_from_unix_device(iface);
     char str[255];
 
     str[0] = 0;
     switch (index)
     {
-        case HID_STRING_ID_ISERIALNUMBER:
-            ioctl(ext->base.device_fd, EVIOCGUNIQ(sizeof(str)), str);
-            break;
         default:
             ERR("Unhandled string index %i\n", index);
     }
@@ -1027,7 +996,6 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
 {
     struct udev_device *parent = NULL;
     const char *ptr, *next, *tmp;
-    char buffer[256];
     DWORD bus = 0;
 
     if (!(parent = udev_device_get_parent_with_subsystem_devtype(dev, subsystem, NULL))) return;
@@ -1042,8 +1010,8 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
 
             if (!strncmp(ptr, "HID_UNIQ=", 9))
             {
-                if (sscanf(ptr, "HID_UNIQ=%256s\n", buffer) != 1 || !*buffer) continue;
-                if (!desc->serial[0]) MultiByteToWideChar(CP_UNIXCP, 0, buffer, -1, desc->serial, ARRAY_SIZE(desc->serial));
+                if (desc->serialnumber[0]) continue;
+                sscanf(ptr, "HID_UNIQ=%256s\n", desc->serialnumber);
             }
             if (!strncmp(ptr, "HID_PHYS=", 9) || !strncmp(ptr, "PHYS=\"", 6))
             {
@@ -1071,11 +1039,13 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
 
     if (!desc->product[0] && (tmp = udev_device_get_sysattr_value(dev, "product")))
         lstrcpynA(desc->product, tmp, sizeof(desc->product));
+
+    if (!desc->serialnumber[0] && (tmp = udev_device_get_sysattr_value(dev, "serial")))
+        lstrcpynA(desc->serialnumber, tmp, sizeof(desc->serialnumber));
 }
 
 static void udev_add_device(struct udev_device *dev)
 {
-    static const WCHAR base_serial[] = {'0','0','0','0',0};
     struct device_desc desc =
     {
         .input = -1,
@@ -1127,7 +1097,6 @@ static void udev_add_device(struct udev_device *dev)
     else if (!strcmp(subsystem, "input"))
     {
         struct input_id device_id = {0};
-        char device_uid[255];
 
         desc.busid = lnxev_busidW;
 
@@ -1140,18 +1109,17 @@ static void udev_add_device(struct udev_device *dev)
             desc.version = device_id.version;
         }
 
-        device_uid[0] = 0;
-        if (ioctl(fd, EVIOCGUNIQ(254), device_uid) >= 0 && device_uid[0])
-            MultiByteToWideChar(CP_UNIXCP, 0, device_uid, -1, desc.serial, ARRAY_SIZE(desc.serial));
-
         if (!desc.manufacturer[0]) strcpy(desc.manufacturer, "evdev");
 
         if (!desc.product[0] && ioctl(fd, EVIOCGNAME(sizeof(desc.product) - 1), desc.product) <= 0)
             desc.product[0] = 0;
+
+        if (!desc.serialnumber[0] && ioctl(fd, EVIOCGUNIQ(sizeof(desc.serialnumber)), desc.serialnumber) < 0)
+            desc.serialnumber[0] = 0;
     }
 #endif
 
-    if (!desc.serial[0]) lstrcpyW(desc.serial, base_serial);
+    if (!desc.serialnumber[0]) strcpy(desc.serialnumber, "0000");
 
     if (is_xbox_gamepad(desc.vid, desc.pid))
         desc.is_gamepad = TRUE;
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 9da2c83082a..79367989c63 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -113,6 +113,7 @@ struct device_extension
 
     WCHAR manufacturer[MAX_PATH];
     WCHAR product[MAX_PATH];
+    WCHAR serialnumber[MAX_PATH];
 
     BYTE *last_report;
     DWORD last_report_size;
@@ -253,11 +254,11 @@ static WCHAR *get_instance_id(DEVICE_OBJECT *device)
 {
     static const WCHAR formatW[] =  {'%','i','&','%','s','&','%','x','&','%','i',0};
     struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
-    DWORD len = strlenW(ext->desc.serial) + 33;
+    DWORD len = strlenW(ext->serialnumber) + 33;
     WCHAR *dst;
 
     if ((dst = ExAllocatePool(PagedPool, len * sizeof(WCHAR))))
-        sprintfW(dst, formatW, ext->desc.version, ext->desc.serial, ext->desc.uid, ext->index);
+        sprintfW(dst, formatW, ext->desc.version, ext->serialnumber, ext->desc.uid, ext->index);
 
     return dst;
 }
@@ -369,6 +370,7 @@ static DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, struct uni
 
     MultiByteToWideChar(CP_UNIXCP, 0, ext->desc.manufacturer, -1, ext->manufacturer, MAX_PATH);
     MultiByteToWideChar(CP_UNIXCP, 0, ext->desc.product, -1, ext->product, MAX_PATH);
+    MultiByteToWideChar(CP_UNIXCP, 0, ext->desc.serialnumber, -1, ext->serialnumber, MAX_PATH);
 
     InitializeListHead(&ext->irp_queue);
     InitializeCriticalSection(&ext->cs);
@@ -838,6 +840,11 @@ static NTSTATUS hid_get_device_string(DEVICE_OBJECT *device, DWORD index, WCHAR
         if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
         else memcpy(buffer, ext->product, len);
         return STATUS_SUCCESS;
+    case HID_STRING_ID_ISERIALNUMBER:
+        len = (strlenW(ext->serialnumber) + 1) * sizeof(WCHAR);
+        if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
+        else memcpy(buffer, ext->serialnumber, len);
+        return STATUS_SUCCESS;
     }
 
     return STATUS_NOT_IMPLEMENTED;
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 80d42ab278d..dc0f3e4e608 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -112,9 +112,9 @@ static const struct device_desc mouse_device_desc =
 {
     .busid = mouse_bus_id,
     .input = -1,
-    .serial = {'0','0','0','0',0},
     .manufacturer = {"The Wine Project"},
     .product = {"Wine HID mouse"},
+    .serialnumber = {"0000"},
 };
 static struct unix_device mouse_device = {.vtbl = &mouse_vtbl};
 
@@ -201,9 +201,9 @@ static const struct device_desc keyboard_device_desc =
 {
     .busid = keyboard_bus_id,
     .input = -1,
-    .serial = {'0','0','0','0',0},
     .manufacturer = {"The Wine Project"},
     .product = {"Wine HID keyboard"},
+    .serialnumber = {"0000"},
 };
 static struct unix_device keyboard_device = {.vtbl = &keyboard_vtbl};
 
diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h
index 142ef13f6b9..164a7984938 100644
--- a/dlls/winebus.sys/unixlib.h
+++ b/dlls/winebus.sys/unixlib.h
@@ -40,11 +40,11 @@ struct device_desc
     DWORD version;
     DWORD input;
     DWORD uid;
-    WCHAR serial[256];
     BOOL is_gamepad;
 
     char manufacturer[MAX_PATH];
     char product[MAX_PATH];
+    char serialnumber[MAX_PATH];
 };
 
 struct sdl_bus_options
@@ -161,9 +161,9 @@ extern const unixlib_entry_t __wine_unix_call_funcs[] DECLSPEC_HIDDEN;
 static inline const char *debugstr_device_desc(struct device_desc *desc)
 {
     if (!desc) return "(null)";
-    return wine_dbg_sprintf("{busid %s, vid %04x, pid %04x, version %04x, input %d, uid %08x, serial %s, is_gamepad %u}",
+    return wine_dbg_sprintf("{busid %s, vid %04x, pid %04x, version %04x, input %d, uid %08x, is_gamepad %u}",
                             debugstr_w(desc->busid), desc->vid, desc->pid, desc->version,
-                            desc->input, desc->uid, debugstr_w(desc->serial), desc->is_gamepad);
+                            desc->input, desc->uid, desc->is_gamepad);
 }
 
 #endif /* __WINEBUS_UNIXLIB_H */
-- 
2.33.0




More information about the wine-devel mailing list