[PATCH 1/4] winebus.sys: Create devices using a struct device_desc descriptor.

Rémi Bernon rbernon at codeweavers.com
Fri Sep 3 02:30:48 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus.h       |  5 +--
 dlls/winebus.sys/bus_iohid.c | 34 ++++++++-------
 dlls/winebus.sys/bus_sdl.c   | 44 +++++++++----------
 dlls/winebus.sys/bus_udev.c  | 73 +++++++++++++++----------------
 dlls/winebus.sys/main.c      | 84 ++++++++++++------------------------
 dlls/winebus.sys/unixlib.c   | 16 +++++++
 dlls/winebus.sys/unixlib.h   | 22 ++++++++++
 7 files changed, 143 insertions(+), 135 deletions(-)

diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
index 8f36959d4e1..05f53daab3c 100644
--- a/dlls/winebus.sys/bus.h
+++ b/dlls/winebus.sys/bus.h
@@ -45,9 +45,8 @@ typedef struct
 struct unix_device *get_unix_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
 
 /* HID Plug and Play Bus */
-DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WORD input,
-                                     DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad,
-                                     const platform_vtbl *vtbl, struct unix_device *unix_device) DECLSPEC_HIDDEN;
+DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vtbl *vtbl,
+                                     struct unix_device *unix_device) DECLSPEC_HIDDEN;
 DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev) DECLSPEC_HIDDEN;
 void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length) DECLSPEC_HIDDEN;
 DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function, void *context) DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c
index 9531607f16d..6256e0d7f80 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -294,25 +294,26 @@ static const platform_vtbl iohid_vtbl =
 
 static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef IOHIDDevice)
 {
+    struct device_desc desc =
+    {
+        .busid = busidW,
+        .input = -1,
+        .serial = {'0','0','0','0',0},
+    };
     struct platform_private *private;
     DEVICE_OBJECT *device;
-    DWORD vid, pid, version, uid;
     CFStringRef str = NULL;
-    WCHAR serial_string[256];
-    BOOL is_gamepad = FALSE;
-
-    TRACE("OS/X IOHID Device Added %p\n", IOHIDDevice);
 
-    vid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDVendorIDKey)));
-    pid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductIDKey)));
-    version = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDVersionNumberKey)));
+    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, serial_string, ARRAY_SIZE(serial_string));
-    uid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDLocationIDKey)));
+    if (str) CFStringToWSTR(str, desc.serial, ARRAY_SIZE(desc.serial));
+    desc.uid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDLocationIDKey)));
 
     if (IOHIDDeviceOpen(IOHIDDevice, 0) != kIOReturnSuccess)
     {
-        ERR("Failed to open HID device %p (vid %04x, pid %04x)\n", IOHIDDevice, vid, pid);
+        ERR("Failed to open HID device %p (vid %04x, pid %04x)\n", IOHIDDevice, desc.vid, desc.pid);
         return;
     }
     IOHIDDeviceScheduleWithRunLoop(IOHIDDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
@@ -320,8 +321,8 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
     if (IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad) ||
        IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
     {
-        if (is_xbox_gamepad(vid, pid))
-            is_gamepad = TRUE;
+        if (is_xbox_gamepad(desc.vid, desc.pid))
+            desc.is_gamepad = TRUE;
         else
         {
             int axes=0, buttons=0;
@@ -358,15 +359,16 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
                 }
                 CFRelease(element_array);
             }
-            is_gamepad = (axes == 6  && buttons >= 14);
+            desc.is_gamepad = (axes == 6  && buttons >= 14);
         }
     }
 
+    TRACE("dev %p, desc %s.\n", IOHIDDevice, debugstr_device_desc(&desc));
+
     if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private))))
         return;
 
-    device = bus_create_hid_device(busidW, vid, pid, -1, version, uid, str ? serial_string : NULL,
-                                   is_gamepad, &iohid_vtbl, &private->unix_device);
+    device = bus_create_hid_device(&desc, &iohid_vtbl, &private->unix_device);
     if (!device) HeapFree(GetProcessHeap(), 0, private);
     else
     {
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index e8ae69633c0..120b7a2d966 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -731,14 +731,17 @@ static BOOL set_mapped_report_from_event(DEVICE_OBJECT *device, SDL_Event *event
     return FALSE;
 }
 
-static void try_add_device(unsigned int index)
+static void sdl_add_device(unsigned int index)
 {
-    DWORD vid = 0, pid = 0, version = 0;
+    struct device_desc desc =
+    {
+        .busid = sdl_busidW,
+        .input = -1,
+        .serial = {'0','0','0','0',0},
+    };
     struct platform_private *private;
     DEVICE_OBJECT *device = NULL;
-    WCHAR serial[34] = {0};
     char guid_str[34];
-    BOOL is_xbox_gamepad;
 
     SDL_Joystick* joystick;
     SDL_JoystickID id;
@@ -757,43 +760,36 @@ static void try_add_device(unsigned int index)
     id = pSDL_JoystickInstanceID(joystick);
 
     if (pSDL_JoystickGetProductVersion != NULL) {
-        vid = pSDL_JoystickGetVendor(joystick);
-        pid = pSDL_JoystickGetProduct(joystick);
-        version = pSDL_JoystickGetProductVersion(joystick);
+        desc.vid = pSDL_JoystickGetVendor(joystick);
+        desc.pid = pSDL_JoystickGetProduct(joystick);
+        desc.version = pSDL_JoystickGetProductVersion(joystick);
     }
     else
     {
-        vid = 0x01;
-        pid = pSDL_JoystickInstanceID(joystick) + 1;
-        version = 0;
+        desc.vid = 0x01;
+        desc.pid = pSDL_JoystickInstanceID(joystick) + 1;
+        desc.version = 0;
     }
 
     guid = pSDL_JoystickGetGUID(joystick);
     pSDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));
-    MultiByteToWideChar(CP_ACP, 0, guid_str, -1, serial, sizeof(guid_str));
+    MultiByteToWideChar(CP_ACP, 0, guid_str, -1, desc.serial, sizeof(guid_str));
 
-    if (controller)
-    {
-        TRACE("Found sdl game controller %i (vid %04x, pid %04x, version %u, serial %s)\n",
-              id, vid, pid, version, debugstr_w(serial));
-        is_xbox_gamepad = TRUE;
-    }
+    if (controller) desc.is_gamepad = TRUE;
     else
     {
         int button_count, axis_count;
 
-        TRACE("Found sdl device %i (vid %04x, pid %04x, version %u, serial %s)\n",
-              id, vid, pid, version, debugstr_w(serial));
-
         axis_count = pSDL_JoystickNumAxes(joystick);
         button_count = pSDL_JoystickNumButtons(joystick);
-        is_xbox_gamepad = (axis_count == 6  && button_count >= 14);
+        desc.is_gamepad = (axis_count == 6  && button_count >= 14);
     }
 
+    TRACE("%s id %d, desc %s.\n", controller ? "controller" : "joystick", id, debugstr_device_desc(&desc));
+
     if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*private)))) return;
 
-    device = bus_create_hid_device(sdl_busidW, vid, pid, -1, version, index, serial, is_xbox_gamepad,
-                                   &sdl_vtbl, &private->unix_device);
+    device = bus_create_hid_device(&desc, &sdl_vtbl, &private->unix_device);
     if (!device) HeapFree(GetProcessHeap(), 0, private);
     else
     {
@@ -812,7 +808,7 @@ static void process_device_event(SDL_Event *event)
     TRACE_(hid_report)("Received action %x\n", event->type);
 
     if (event->type == SDL_JOYDEVICEADDED)
-        try_add_device(((SDL_JoyDeviceEvent*)event)->which);
+        sdl_add_device(((SDL_JoyDeviceEvent *)event)->which);
     else if (event->type == SDL_JOYDEVICEREMOVED)
     {
         id = ((SDL_JoyDeviceEvent *)event)->which;
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index c954e6b2128..4329e54a0b9 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -1014,8 +1014,7 @@ static int check_device_syspath(DEVICE_OBJECT *device, void* context)
     return strcmp(get_device_syspath(private->udev_device), context);
 }
 
-static void get_device_subsystem_info(struct udev_device *dev, char const *subsystem, DWORD *vendor_id,
-                                      DWORD *product_id, DWORD *input, DWORD *version, WCHAR **serial_number)
+static void get_device_subsystem_info(struct udev_device *dev, char const *subsystem, struct device_desc *desc)
 {
     struct udev_device *parent = NULL;
     const char *ptr, *next, *tmp;
@@ -1035,41 +1034,42 @@ 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 (!*serial_number) *serial_number = strdupAtoW(buffer);
+                if (!desc->serial[0]) MultiByteToWideChar(CP_UNIXCP, 0, buffer, -1, desc->serial, ARRAY_SIZE(desc->serial));
             }
             if (!strncmp(ptr, "HID_PHYS=", 9) || !strncmp(ptr, "PHYS=\"", 6))
             {
                 if (!(tmp = strstr(ptr, "/input")) || tmp >= next) continue;
-                if (*input == -1) sscanf(tmp, "/input%d\n", input);
+                if (desc->input == -1) sscanf(tmp, "/input%d\n", &desc->input);
             }
             if (!strncmp(ptr, "HID_ID=", 7))
             {
-                if (bus || *vendor_id || *product_id) continue;
-                sscanf(ptr, "HID_ID=%x:%x:%x\n", &bus, vendor_id, product_id);
+                if (bus || desc->vid || desc->pid) continue;
+                sscanf(ptr, "HID_ID=%x:%x:%x\n", &bus, &desc->vid, &desc->pid);
             }
             if (!strncmp(ptr, "PRODUCT=", 8))
             {
-                if (*version) continue;
+                if (desc->version) continue;
                 if (!strcmp(subsystem, "usb"))
-                    sscanf(ptr, "PRODUCT=%x/%x/%x\n", vendor_id, product_id, version);
+                    sscanf(ptr, "PRODUCT=%x/%x/%x\n", &desc->vid, &desc->pid, &desc->version);
                 else
-                    sscanf(ptr, "PRODUCT=%x/%x/%x/%x\n", &bus, vendor_id, product_id, version);
+                    sscanf(ptr, "PRODUCT=%x/%x/%x/%x\n", &bus, &desc->vid, &desc->pid, &desc->version);
             }
         }
     }
 }
 
-static void try_add_device(struct udev_device *dev)
+static void udev_add_device(struct udev_device *dev)
 {
-    DWORD vid = 0, pid = 0, version = 0, input = -1;
+    static const WCHAR base_serial[] = {'0','0','0','0',0};
+    struct device_desc desc =
+    {
+        .input = -1,
+    };
     struct platform_private *private;
     DEVICE_OBJECT *device = NULL;
     const char *subsystem;
     const char *devnode;
-    WCHAR *serial = NULL;
-    BOOL is_gamepad = FALSE;
     int fd;
-    static const CHAR *base_serial = "0000";
 
     if (!(devnode = udev_device_get_devnode(dev)))
         return;
@@ -1093,55 +1093,59 @@ static void try_add_device(struct udev_device *dev)
     }
 #endif
 
-    get_device_subsystem_info(dev, "hid", &vid, &pid, &input, &version, &serial);
-    get_device_subsystem_info(dev, "input", &vid, &pid, &input, &version, &serial);
-    get_device_subsystem_info(dev, "usb", &vid, &pid, &input, &version, &serial);
+    get_device_subsystem_info(dev, "hid", &desc);
+    get_device_subsystem_info(dev, "input", &desc);
+    get_device_subsystem_info(dev, "usb", &desc);
 
     subsystem = udev_device_get_subsystem(dev);
+    if (!strcmp(subsystem, "hidraw"))
+    {
+        desc.busid = hidraw_busidW;
+    }
 #ifdef HAS_PROPER_INPUT_HEADER
-    if (!strcmp(subsystem, "input"))
+    else if (!strcmp(subsystem, "input"))
     {
         struct input_id device_id = {0};
         char device_uid[255];
 
+        desc.busid = lnxev_busidW;
+
         if (ioctl(fd, EVIOCGID, &device_id) < 0)
             WARN("ioctl(EVIOCGID) failed: %d %s\n", errno, strerror(errno));
         else
         {
-            vid = device_id.vendor;
-            pid = device_id.product;
-            version = device_id.version;
+            desc.vid = device_id.vendor;
+            desc.pid = device_id.product;
+            desc.version = device_id.version;
         }
 
         device_uid[0] = 0;
         if (ioctl(fd, EVIOCGUNIQ(254), device_uid) >= 0 && device_uid[0])
-            serial = strdupAtoW(device_uid);
+            MultiByteToWideChar(CP_UNIXCP, 0, device_uid, -1, desc.serial, ARRAY_SIZE(desc.serial));
     }
 #endif
 
-    if (serial == NULL) serial = strdupAtoW(base_serial);
+    if (!desc.serial[0]) lstrcpyW(desc.serial, base_serial);
 
-    if (is_xbox_gamepad(vid, pid))
-        is_gamepad = TRUE;
+    if (is_xbox_gamepad(desc.vid, desc.pid))
+        desc.is_gamepad = TRUE;
 #ifdef HAS_PROPER_INPUT_HEADER
     else
     {
         int axes=0, buttons=0;
         axes = count_abs_axis(fd);
         buttons = count_buttons(fd, NULL);
-        is_gamepad = (axes == 6  && buttons >= 14);
+        desc.is_gamepad = (axes == 6 && buttons >= 14);
     }
 #endif
 
-    TRACE("Found udev device %s (vid %04x, pid %04x, version %04x, input %d, serial %s)\n",
-          debugstr_a(devnode), vid, pid, version, input, debugstr_w(serial));
+    TRACE("dev %p, node %s, desc %s.\n", dev, debugstr_a(devnode), debugstr_device_desc(&desc));
 
     if (strcmp(subsystem, "hidraw") == 0)
     {
         if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private))))
             return;
-        device = bus_create_hid_device(hidraw_busidW, vid, pid, input, version, 0, serial,
-                                       is_gamepad, &hidraw_vtbl, &private->unix_device);
+        device = bus_create_hid_device(&desc, &hidraw_vtbl, &private->unix_device);
         if (!device) HeapFree(GetProcessHeap(), 0, private);
     }
 #ifdef HAS_PROPER_INPUT_HEADER
@@ -1149,8 +1153,7 @@ static void try_add_device(struct udev_device *dev)
     {
         if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wine_input_private))))
             return;
-        device = bus_create_hid_device(lnxev_busidW, vid, pid, input, version, 0, serial,
-                                       is_gamepad, &lnxev_vtbl, &private->unix_device);
+        device = bus_create_hid_device(&desc, &lnxev_vtbl, &private->unix_device);
         if (!device) HeapFree(GetProcessHeap(), 0, private);
     }
 #endif
@@ -1166,8 +1169,6 @@ static void try_add_device(struct udev_device *dev)
         WARN("Ignoring device %s with subsystem %s\n", debugstr_a(devnode), subsystem);
         close(fd);
     }
-
-    HeapFree(GetProcessHeap(), 0, serial);
 }
 
 static void try_remove_device(struct udev_device *dev)
@@ -1213,7 +1214,7 @@ static void build_initial_deviceset(void)
         path = udev_list_entry_get_name(dev_list_entry);
         if ((dev = udev_device_new_from_syspath(udev_context, path)))
         {
-            try_add_device(dev);
+            udev_add_device(dev);
             udev_device_unref(dev);
         }
     }
@@ -1286,7 +1287,7 @@ static void process_monitor_event(struct udev_monitor *monitor)
     if (!action)
         WARN("No action received\n");
     else if (strcmp(action, "add") == 0)
-        try_add_device(dev);
+        udev_add_device(dev);
     else if (strcmp(action, "remove") == 0)
         try_remove_device(dev);
     else
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 0f92f64dea2..4727c4b043d 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -118,11 +118,8 @@ struct device_extension
     CRITICAL_SECTION cs;
     enum device_state state;
 
-    WORD vid, pid, input;
-    DWORD uid, version, index;
-    BOOL is_gamepad;
-    WCHAR *serial;
-    const WCHAR *busid;  /* Expected to be a static constant */
+    struct device_desc desc;
+    DWORD index;
 
     const platform_vtbl *vtbl;
 
@@ -146,36 +143,25 @@ static CRITICAL_SECTION device_list_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
 
 static struct list device_list = LIST_INIT(device_list);
 
-static const WCHAR zero_serialW[]= {'0','0','0','0',0};
-
 static NTSTATUS winebus_call(unsigned int code, void *args)
 {
     return __wine_unix_call_funcs[code]( args );
 }
 
-static inline WCHAR *strdupW(const WCHAR *src)
-{
-    WCHAR *dst;
-    if (!src) return NULL;
-    dst = HeapAlloc(GetProcessHeap(), 0, (strlenW(src) + 1)*sizeof(WCHAR));
-    if (dst) strcpyW(dst, src);
-    return dst;
-}
-
 struct unix_device *get_unix_device(DEVICE_OBJECT *device)
 {
     struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
     return ext->unix_device;
 }
 
-static DWORD get_device_index(WORD vid, WORD pid, WORD input)
+static DWORD get_device_index(struct device_desc *desc)
 {
     struct device_extension *ext;
     DWORD index = 0;
 
     LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry)
     {
-        if (ext->vid == vid && ext->pid == pid && ext->input == input)
+        if (ext->desc.vid == desc->vid && ext->desc.pid == desc->pid && ext->desc.input == desc->input)
             index = max(ext->index + 1, index);
     }
 
@@ -186,12 +172,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;
-    const WCHAR *serial = ext->serial ? ext->serial : zero_serialW;
-    DWORD len = strlenW(serial) + 33;
+    DWORD len = strlenW(ext->desc.serial) + 33;
     WCHAR *dst;
 
     if ((dst = ExAllocatePool(PagedPool, len * sizeof(WCHAR))))
-        sprintfW(dst, formatW, ext->version, serial, ext->uid, ext->index);
+        sprintfW(dst, formatW, ext->desc.version, ext->desc.serial, ext->desc.uid, ext->index);
 
     return dst;
 }
@@ -202,13 +187,13 @@ static WCHAR *get_device_id(DEVICE_OBJECT *device)
     static const WCHAR formatW[] = {'%','s','\\','v','i','d','_','%','0','4','x',
             '&','p','i','d','_','%','0','4','x',0};
     struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
-    DWORD len = strlenW(ext->busid) + 34;
+    DWORD len = strlenW(ext->desc.busid) + 34;
     WCHAR *dst, *tmp;
 
     if ((dst = ExAllocatePool(PagedPool, len * sizeof(WCHAR))))
     {
-        tmp = dst + sprintfW(dst, formatW, ext->busid, ext->vid, ext->pid);
-        if (ext->input != (WORD)-1) sprintfW(tmp, input_formatW, ext->input);
+        tmp = dst + sprintfW(dst, formatW, ext->desc.busid, ext->desc.vid, ext->desc.pid);
+        if (ext->desc.input != -1) sprintfW(tmp, input_formatW, ext->desc.input);
     }
 
     return dst;
@@ -219,9 +204,9 @@ static WCHAR *get_hardware_ids(DEVICE_OBJECT *device)
     struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
     WCHAR *dst;
 
-    if ((dst = ExAllocatePool(PagedPool, (strlenW(ext->busid) + 2) * sizeof(WCHAR))))
+    if ((dst = ExAllocatePool(PagedPool, (strlenW(ext->desc.busid) + 2) * sizeof(WCHAR))))
     {
-        strcpyW(dst, ext->busid);
+        strcpyW(dst, ext->desc.busid);
         dst[strlenW(dst) + 1] = 0;
     }
 
@@ -242,11 +227,11 @@ static WCHAR *get_compatible_ids(DEVICE_OBJECT *device)
     DWORD size = sizeof(hid_compat);
     WCHAR *dst;
 
-    if (ext->is_gamepad) size += sizeof(xinput_compat);
+    if (ext->desc.is_gamepad) size += sizeof(xinput_compat);
 
     if ((dst = ExAllocatePool(PagedPool, size + sizeof(WCHAR))))
     {
-        if (ext->is_gamepad) memcpy(dst, xinput_compat, sizeof(xinput_compat));
+        if (ext->desc.is_gamepad) memcpy(dst, xinput_compat, sizeof(xinput_compat));
         memcpy((char *)dst + size - sizeof(hid_compat), hid_compat, sizeof(hid_compat));
         dst[size / sizeof(WCHAR)] = 0;
     }
@@ -268,9 +253,8 @@ static void remove_pending_irps(DEVICE_OBJECT *device)
     }
 }
 
-DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WORD input,
-                                     DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad,
-                                     const platform_vtbl *vtbl, struct unix_device *unix_device)
+DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vtbl *vtbl,
+                                     struct unix_device *unix_device)
 {
     static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0};
     struct device_extension *ext;
@@ -279,11 +263,9 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WO
     WCHAR dev_name[256];
     NTSTATUS status;
 
-    TRACE("bus_id %s, vid %04x, pid %04x, input %04x, version %u, uid %u, serial %s, "
-          "is_gamepad %u, vtbl %p, unix_device %p\n", debugstr_w(busidW), vid, pid, input,
-           version, uid, debugstr_w(serialW), is_gamepad, vtbl, unix_device);
+    TRACE("desc %s, vtbl %p, unix_device %p\n", debugstr_device_desc(desc), vtbl, unix_device);
 
-    sprintfW(dev_name, device_name_fmtW, busidW, unix_device);
+    sprintfW(dev_name, device_name_fmtW, desc->busid, unix_device);
     RtlInitUnicodeString(&nameW, dev_name);
     status = IoCreateDevice(driver_obj, sizeof(struct device_extension), &nameW, 0, 0, FALSE, &device);
     if (status)
@@ -297,15 +279,8 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WO
     /* fill out device_extension struct */
     ext = (struct device_extension *)device->DeviceExtension;
     ext->device             = device;
-    ext->vid                = vid;
-    ext->pid                = pid;
-    ext->input              = input;
-    ext->uid                = uid;
-    ext->version            = version;
-    ext->index              = get_device_index(vid, pid, input);
-    ext->is_gamepad         = is_gamepad;
-    ext->serial             = strdupW(serialW);
-    ext->busid              = busidW;
+    ext->desc               = *desc;
+    ext->index              = get_device_index(desc);
     ext->vtbl               = vtbl;
     ext->last_report        = NULL;
     ext->last_report_size   = 0;
@@ -334,7 +309,7 @@ DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev)
     EnterCriticalSection(&device_list_cs);
     LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry)
     {
-        if (strcmpW(ext->busid, bus_id)) continue;
+        if (strcmpW(ext->desc.busid, bus_id)) continue;
         if (ext->vtbl->compare_platform_device(ext->device, platform_dev) == 0)
         {
             ret = ext->device;
@@ -358,7 +333,7 @@ DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function
     EnterCriticalSection(&device_list_cs);
     LIST_FOR_EACH_ENTRY_SAFE(ext, next, &device_list, struct device_extension, entry)
     {
-        if (strcmpW(ext->busid, bus_id)) continue;
+        if (strcmpW(ext->desc.busid, bus_id)) continue;
         LeaveCriticalSection(&device_list_cs);
         cont = function(ext->device, context);
         EnterCriticalSection(&device_list_cs);
@@ -483,21 +458,19 @@ static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp)
 
 static void mouse_device_create(void)
 {
-    static const WCHAR busidW[] = {'W','I','N','E','M','O','U','S','E',0};
     struct device_create_params params = {0};
 
     if (winebus_call(mouse_create, &params)) return;
-    mouse_obj = bus_create_hid_device(busidW, 0, 0, -1, 0, 0, busidW, FALSE, &mouse_vtbl, params.device);
+    mouse_obj = bus_create_hid_device(&params.desc, &mouse_vtbl, params.device);
     IoInvalidateDeviceRelations(bus_pdo, BusRelations);
 }
 
 static void keyboard_device_create(void)
 {
-    static const WCHAR busidW[] = {'W','I','N','E','K','E','Y','B','O','A','R','D',0};
     struct device_create_params params = {0};
 
     if (winebus_call(keyboard_create, &params)) return;
-    keyboard_obj = bus_create_hid_device(busidW, 0, 0, -1, 0, 0, busidW, FALSE, &keyboard_vtbl, params.device);
+    keyboard_obj = bus_create_hid_device(&params.desc, &keyboard_vtbl, params.device);
     IoInvalidateDeviceRelations(bus_pdo, BusRelations);
 }
 
@@ -737,7 +710,6 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
             ext->cs.DebugInfo->Spare[0] = 0;
             DeleteCriticalSection(&ext->cs);
 
-            HeapFree(GetProcessHeap(), 0, ext->serial);
             HeapFree(GetProcessHeap(), 0, ext->last_report);
 
             irp->IoStatus.Status = STATUS_SUCCESS;
@@ -788,7 +760,7 @@ static NTSTATUS hid_get_native_string(DEVICE_OBJECT *device, DWORD index, WCHAR
     const struct product_desc *vendor_products;
     unsigned int i, vendor_products_size = 0;
 
-    if (ext->vid == VID_MICROSOFT)
+    if (ext->desc.vid == VID_MICROSOFT)
     {
         vendor_products = XBOX_CONTROLLERS;
         vendor_products_size = ARRAY_SIZE(XBOX_CONTROLLERS);
@@ -796,7 +768,7 @@ static NTSTATUS hid_get_native_string(DEVICE_OBJECT *device, DWORD index, WCHAR
 
     for (i = 0; i < vendor_products_size; i++)
     {
-        if (ext->pid == vendor_products[i].pid)
+        if (ext->desc.pid == vendor_products[i].pid)
             break;
     }
 
@@ -871,9 +843,9 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
 
             memset(attr, 0, sizeof(*attr));
             attr->Size = sizeof(*attr);
-            attr->VendorID = ext->vid;
-            attr->ProductID = ext->pid;
-            attr->VersionNumber = ext->version;
+            attr->VendorID = ext->desc.vid;
+            attr->ProductID = ext->desc.pid;
+            attr->VersionNumber = ext->desc.version;
 
             irp->IoStatus.Status = STATUS_SUCCESS;
             irp->IoStatus.Information = sizeof(*attr);
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index fdfdcc52dcb..9759bf9d911 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -108,11 +108,19 @@ const platform_vtbl mouse_vtbl =
     .set_feature_report = mouse_set_feature_report,
 };
 
+static const WCHAR mouse_bus_id[] = {'W','I','N','E','M','O','U','S','E',0};
+static const struct device_desc mouse_device_desc =
+{
+    .busid = mouse_bus_id,
+    .input = -1,
+    .serial = {'0','0','0','0',0},
+};
 static struct unix_device mouse_device;
 
 static NTSTATUS mouse_device_create(void *args)
 {
     struct device_create_params *params = args;
+    params->desc = mouse_device_desc;
     params->device = &mouse_device;
     return STATUS_SUCCESS;
 }
@@ -187,11 +195,19 @@ const platform_vtbl keyboard_vtbl =
     .set_feature_report = keyboard_set_feature_report,
 };
 
+static const WCHAR keyboard_bus_id[] = {'W','I','N','E','K','E','Y','B','O','A','R','D',0};
+static const struct device_desc keyboard_device_desc =
+{
+    .busid = keyboard_bus_id,
+    .input = -1,
+    .serial = {'0','0','0','0',0},
+};
 static struct unix_device keyboard_device;
 
 static NTSTATUS keyboard_device_create(void *args)
 {
     struct device_create_params *params = args;
+    params->desc = keyboard_device_desc;
     params->device = &keyboard_device;
     return STATUS_SUCCESS;
 }
diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h
index d70dedecb2c..d321c208885 100644
--- a/dlls/winebus.sys/unixlib.h
+++ b/dlls/winebus.sys/unixlib.h
@@ -27,9 +27,22 @@
 #include <ddk/wdm.h>
 #include <hidusage.h>
 
+#include "wine/debug.h"
 #include "wine/list.h"
 #include "wine/unixlib.h"
 
+struct device_desc
+{
+    const WCHAR *busid;
+    DWORD vid;
+    DWORD pid;
+    DWORD version;
+    DWORD input;
+    DWORD uid;
+    WCHAR serial[256];
+    BOOL is_gamepad;
+};
+
 struct sdl_bus_options
 {
     BOOL map_controllers;
@@ -70,6 +83,7 @@ struct bus_event
 
 struct device_create_params
 {
+    struct device_desc desc;
     struct unix_device *device;
 };
 
@@ -90,4 +104,12 @@ enum unix_funcs
 
 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}",
+                            debugstr_w(desc->busid), desc->vid, desc->pid, desc->version,
+                            desc->input, desc->uid, debugstr_w(desc->serial), desc->is_gamepad);
+}
+
 #endif /* __WINEBUS_UNIXLIB_H */
-- 
2.33.0




More information about the wine-devel mailing list