[PATCH v2 6/7] winebus.sys: Allocate private device data separately.

Rémi Bernon rbernon at codeweavers.com
Mon Aug 23 02:55:24 CDT 2021


And use an opaque struct unix_device as private data.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus.h          |  8 ++++----
 dlls/winebus.sys/bus_iohid.c    | 23 ++++++++++++++++-------
 dlls/winebus.sys/bus_sdl.c      | 25 ++++++++++++++++---------
 dlls/winebus.sys/bus_udev.c     | 31 ++++++++++++++++++++++++-------
 dlls/winebus.sys/main.c         | 25 +++++++++++--------------
 dlls/winebus.sys/unix_private.h |  4 ++++
 dlls/winebus.sys/unixlib.h      |  2 ++
 7 files changed, 77 insertions(+), 41 deletions(-)

diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
index 1e4f37ae896..803ffaad132 100644
--- a/dlls/winebus.sys/bus.h
+++ b/dlls/winebus.sys/bus.h
@@ -40,12 +40,12 @@ typedef struct
     void (*set_feature_report)(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
 } platform_vtbl;
 
-void *get_platform_private(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
+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, DWORD platform_data_size) DECLSPEC_HIDDEN;
+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_find_hid_device(const WCHAR *bus_id, void *platform_dev) DECLSPEC_HIDDEN;
 void bus_unlink_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
 void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length) DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c
index 18d9dc2dbe9..eb5eddd60fa 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -103,13 +103,19 @@ static struct iohid_bus_options options;
 
 struct platform_private
 {
+    struct unix_device unix_device;
     IOHIDDeviceRef device;
     uint8_t *buffer;
 };
 
+static inline struct platform_private *impl_from_unix_device(struct unix_device *iface)
+{
+    return CONTAINING_RECORD(iface, struct platform_private, unix_device);
+}
+
 static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
 {
-    return (struct platform_private *)get_platform_private(device);
+    return impl_from_unix_device(get_unix_device(device));
 }
 
 static void CFStringToWSTR(CFStringRef cstr, LPWSTR wstr, int length)
@@ -137,6 +143,8 @@ static void handle_IOHIDDeviceIOHIDReportCallback(void *context,
 
 static void free_device(DEVICE_OBJECT *device)
 {
+    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    HeapFree(GetProcessHeap(), 0, private);
 }
 
 static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
@@ -285,6 +293,7 @@ static const platform_vtbl iohid_vtbl =
 
 static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef IOHIDDevice)
 {
+    struct platform_private *private;
     DEVICE_OBJECT *device;
     DWORD vid, pid, version, uid;
     CFStringRef str = NULL;
@@ -355,14 +364,14 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
     if (is_gamepad)
         input = 0;
 
-    device = bus_create_hid_device(busidW, vid, pid, input,
-            version, uid, str ? serial_string : NULL, is_gamepad,
-            &iohid_vtbl, sizeof(struct platform_private));
-    if (!device)
-        ERR("Failed to create device\n");
+    if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private))))
+        return;
+
+    device = bus_create_hid_device(busidW, vid, pid, input, version, uid, str ? serial_string : NULL,
+                                   is_gamepad, &iohid_vtbl, &private->unix_device);
+    if (!device) HeapFree(GetProcessHeap(), 0, private);
     else
     {
-        struct platform_private *private = impl_from_DEVICE_OBJECT(device);
         private->device = IOHIDDevice;
         private->buffer = NULL;
         IoInvalidateDeviceRelations(bus_pdo, BusRelations);
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index cc0bafa89ba..61d1240e05d 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -110,6 +110,8 @@ static Uint16 (*pSDL_JoystickGetVendor)(SDL_Joystick * joystick);
 
 struct platform_private
 {
+    struct unix_device unix_device;
+
     SDL_Joystick *sdl_joystick;
     SDL_GameController *sdl_controller;
     SDL_JoystickID id;
@@ -128,9 +130,14 @@ struct platform_private
     int haptic_effect_id;
 };
 
+static inline struct platform_private *impl_from_unix_device(struct unix_device *iface)
+{
+    return CONTAINING_RECORD(iface, struct platform_private, unix_device);
+}
+
 static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
 {
-    return (struct platform_private *)get_platform_private(device);
+    return impl_from_unix_device(get_unix_device(device));
 }
 
 #define CONTROLLER_NUM_BUTTONS 11
@@ -479,6 +486,8 @@ static void free_device(DEVICE_OBJECT *device)
         pSDL_GameControllerClose(ext->sdl_controller);
     if (ext->sdl_haptic)
         pSDL_HapticClose(ext->sdl_haptic);
+
+    HeapFree(GetProcessHeap(), 0, ext);
 }
 
 static int compare_platform_device(DEVICE_OBJECT *device, void *context)
@@ -730,6 +739,7 @@ static void try_remove_device(DEVICE_OBJECT *device)
 static void try_add_device(unsigned int index)
 {
     DWORD vid = 0, pid = 0, version = 0;
+    struct platform_private *private;
     DEVICE_OBJECT *device = NULL;
     WCHAR serial[34] = {0};
     char guid_str[34];
@@ -788,21 +798,18 @@ static void try_add_device(unsigned int index)
     if (is_xbox_gamepad)
         input = 0;
 
-    device = bus_create_hid_device(sdl_busidW, vid, pid, input, version, index,
-            serial, is_xbox_gamepad, &sdl_vtbl, sizeof(struct platform_private));
+    if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*private)))) return;
 
-    if (device)
+    device = bus_create_hid_device(sdl_busidW, vid, pid, input, version, index, serial, is_xbox_gamepad,
+                                   &sdl_vtbl, &private->unix_device);
+    if (!device) HeapFree(GetProcessHeap(), 0, private);
+    else
     {
-        struct platform_private *private = impl_from_DEVICE_OBJECT(device);
         private->sdl_joystick = joystick;
         private->sdl_controller = controller;
         private->id = id;
         IoInvalidateDeviceRelations(bus_pdo, BusRelations);
     }
-    else
-    {
-        WARN("Ignoring device %i\n", id);
-    }
 }
 
 static void process_device_event(SDL_Event *event)
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 953d1d9436c..bd70a66f2cd 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -99,6 +99,8 @@ static struct udev_bus_options options;
 
 struct platform_private
 {
+    struct unix_device unix_device;
+
     struct udev_device *udev_device;
     int device_fd;
 
@@ -106,9 +108,14 @@ struct platform_private
     int control_pipe[2];
 };
 
+static inline struct platform_private *impl_from_unix_device(struct unix_device *iface)
+{
+    return CONTAINING_RECORD(iface, struct platform_private, unix_device);
+}
+
 static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
 {
-    return (struct platform_private *)get_platform_private(device);
+    return impl_from_unix_device(get_unix_device(device));
 }
 
 #ifdef HAS_PROPER_INPUT_HEADER
@@ -550,6 +557,8 @@ static void hidraw_free_device(DEVICE_OBJECT *device)
 
     close(private->device_fd);
     udev_device_unref(private->udev_device);
+
+    HeapFree(GetProcessHeap(), 0, private);
 }
 
 static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
@@ -833,7 +842,7 @@ static const platform_vtbl hidraw_vtbl =
 
 static inline struct wine_input_private *input_impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
 {
-    return (struct wine_input_private*)get_platform_private(device);
+    return CONTAINING_RECORD(impl_from_DEVICE_OBJECT(device), struct wine_input_private, base);
 }
 
 static void lnxev_free_device(DEVICE_OBJECT *device)
@@ -855,6 +864,8 @@ static void lnxev_free_device(DEVICE_OBJECT *device)
 
     close(ext->base.device_fd);
     udev_device_unref(ext->base.udev_device);
+
+    HeapFree(GetProcessHeap(), 0, ext);
 }
 
 static DWORD CALLBACK lnxev_device_report_thread(void *args);
@@ -1050,6 +1061,7 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
 static void try_add_device(struct udev_device *dev)
 {
     DWORD vid = 0, pid = 0, version = 0, input = -1;
+    struct platform_private *private;
     DEVICE_OBJECT *device = NULL;
     const char *subsystem;
     const char *devnode;
@@ -1127,20 +1139,25 @@ static void try_add_device(struct udev_device *dev)
 
     if (strcmp(subsystem, "hidraw") == 0)
     {
-        device = bus_create_hid_device(hidraw_busidW, vid, pid, input, version, 0, serial, is_gamepad,
-                                       &hidraw_vtbl, sizeof(struct platform_private));
+        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);
+        if (!device) HeapFree(GetProcessHeap(), 0, private);
     }
 #ifdef HAS_PROPER_INPUT_HEADER
     else if (strcmp(subsystem, "input") == 0)
     {
-        device = bus_create_hid_device(lnxev_busidW, vid, pid, input, version, 0, serial, is_gamepad,
-                                       &lnxev_vtbl, sizeof(struct wine_input_private));
+        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);
+        if (!device) HeapFree(GetProcessHeap(), 0, private);
     }
 #endif
 
     if (device)
     {
-        struct platform_private *private = impl_from_DEVICE_OBJECT(device);
         private->udev_device = udev_device_ref(dev);
         private->device_fd = fd;
         IoInvalidateDeviceRelations(bus_pdo, BusRelations);
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 63c1b57b186..5dd6cb98acc 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -139,7 +139,7 @@ struct device_extension
     DWORD buffer_size;
     LIST_ENTRY irp_queue;
 
-    BYTE platform_private[1];
+    struct unix_device *unix_device;
 };
 
 static CRITICAL_SECTION device_list_cs;
@@ -173,10 +173,10 @@ static inline WCHAR *strdupW(const WCHAR *src)
     return dst;
 }
 
-void *get_platform_private(DEVICE_OBJECT *device)
+struct unix_device *get_unix_device(DEVICE_OBJECT *device)
 {
     struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
-    return ext->platform_private;
+    return ext->unix_device;
 }
 
 static DWORD get_device_index(WORD vid, WORD pid, WORD input)
@@ -262,9 +262,9 @@ 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, DWORD platform_data_size)
+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)
 {
     static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0};
     struct device_extension *ext;
@@ -273,19 +273,17 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid,
     UNICODE_STRING nameW;
     WCHAR dev_name[256];
     NTSTATUS status;
-    DWORD length;
 
-    TRACE("(%s, %04x, %04x, %04x, %u, %u, %s, %u, %p, %u)\n",
-            debugstr_w(busidW), vid, pid, input, version, uid, debugstr_w(serialW),
-            is_gamepad, vtbl, platform_data_size);
+    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);
 
     if (!(pnp_dev = HeapAlloc(GetProcessHeap(), 0, sizeof(*pnp_dev))))
         return NULL;
 
     sprintfW(dev_name, device_name_fmtW, busidW, pnp_dev);
     RtlInitUnicodeString(&nameW, dev_name);
-    length = FIELD_OFFSET(struct device_extension, platform_private[platform_data_size]);
-    status = IoCreateDevice(driver_obj, length, &nameW, 0, 0, FALSE, &device);
+    status = IoCreateDevice(driver_obj, sizeof(struct device_extension), &nameW, 0, 0, FALSE, &device);
     if (status)
     {
         FIXME("failed to create device error %x\n", status);
@@ -312,8 +310,7 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid,
     ext->last_report_size   = 0;
     ext->last_report_read   = TRUE;
     ext->buffer_size        = 0;
-
-    memset(ext->platform_private, 0, platform_data_size);
+    ext->unix_device        = unix_device;
 
     InitializeListHead(&ext->irp_queue);
     InitializeCriticalSection(&ext->cs);
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index 9468cac45e9..aff1e86263a 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -27,6 +27,10 @@
 
 #include "unixlib.h"
 
+struct unix_device
+{
+};
+
 extern NTSTATUS sdl_bus_init(void *) DECLSPEC_HIDDEN;
 extern NTSTATUS sdl_bus_wait(void *) DECLSPEC_HIDDEN;
 extern NTSTATUS sdl_bus_stop(void *) DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h
index abd9c8a1d81..84391733852 100644
--- a/dlls/winebus.sys/unixlib.h
+++ b/dlls/winebus.sys/unixlib.h
@@ -42,6 +42,8 @@ struct iohid_bus_options
 {
 };
 
+struct unix_device;
+
 enum unix_funcs
 {
     sdl_init,
-- 
2.33.0




More information about the wine-devel mailing list