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

Rémi Bernon rbernon at codeweavers.com
Thu Aug 19 02:10:03 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 e21c58b7c84..55e4880a88b 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -105,13 +105,19 @@ static const WCHAR busidW[] = {'I','O','H','I','D',0};
 
 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)
@@ -139,6 +145,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)
@@ -287,6 +295,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;
@@ -357,14 +366,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 0cec6e4d981..7f392cd14e4 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -112,6 +112,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;
@@ -130,9 +132,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
@@ -481,6 +488,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)
@@ -732,6 +741,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];
@@ -790,21 +800,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 51d846b3bed..a0e92bbc692 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -100,6 +100,8 @@ static const WCHAR lnxev_busidW[] = {'L','N','X','E','V',0};
 
 struct platform_private
 {
+    struct unix_device unix_device;
+
     struct udev_device *udev_device;
     int device_fd;
 
@@ -107,9 +109,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
@@ -551,6 +558,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)
@@ -834,7 +843,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)
@@ -856,6 +865,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);
@@ -1051,6 +1062,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;
@@ -1128,20 +1140,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 2b7566d25df..bd486e36058 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -141,7 +141,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;
@@ -168,10 +168,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)
@@ -257,9 +257,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;
@@ -268,19 +268,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);
@@ -307,8 +305,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 24e42e78aa6..8adbd819bfe 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 WINAPI sdl_bus_init(void *args) DECLSPEC_HIDDEN;
 extern NTSTATUS WINAPI sdl_bus_wait(void) DECLSPEC_HIDDEN;
 extern NTSTATUS WINAPI sdl_bus_stop(void) DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h
index df634ad4cc3..4c66aabff88 100644
--- a/dlls/winebus.sys/unixlib.h
+++ b/dlls/winebus.sys/unixlib.h
@@ -42,6 +42,8 @@ struct iohid_bus_options
 {
 };
 
+struct unix_device;
+
 struct unix_funcs
 {
     NTSTATUS (WINAPI *sdl_bus_init)(void *);
-- 
2.32.0




More information about the wine-devel mailing list