[PATCH 2/4] winebus.sys: Move device vtable to the struct unix_device side.

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


And name the callbacks a bit more consistently.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winebus.sys/bus.h          |  19 +----
 dlls/winebus.sys/bus_iohid.c    |  61 +++++++-------
 dlls/winebus.sys/bus_sdl.c      |  53 ++++++------
 dlls/winebus.sys/bus_udev.c     | 108 +++++++++++++-----------
 dlls/winebus.sys/main.c         | 120 ++++++++++++++++++++++----
 dlls/winebus.sys/unix_private.h |  13 +++
 dlls/winebus.sys/unixlib.c      | 144 ++++++++++++++++++++++++--------
 dlls/winebus.sys/unixlib.h      |  44 ++++++++++
 8 files changed, 390 insertions(+), 172 deletions(-)

diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
index 05f53daab3c..a5615bb31b5 100644
--- a/dlls/winebus.sys/bus.h
+++ b/dlls/winebus.sys/bus.h
@@ -29,24 +29,10 @@
 
 typedef int(*enum_func)(DEVICE_OBJECT *device, void *context);
 
-/* Native device function table */
-typedef struct
-{
-    void (*free_device)(DEVICE_OBJECT *device);
-    int (*compare_platform_device)(DEVICE_OBJECT *device, void *platform_dev);
-    NTSTATUS (*start_device)(DEVICE_OBJECT *device);
-    NTSTATUS (*get_reportdescriptor)(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length);
-    NTSTATUS (*get_string)(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length);
-    void (*set_output_report)(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
-    void (*get_feature_report)(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
-    void (*set_feature_report)(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
-} platform_vtbl;
-
 struct unix_device *get_unix_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
 
 /* HID Plug and Play Bus */
-DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vtbl *vtbl,
-                                     struct unix_device *unix_device) DECLSPEC_HIDDEN;
+DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, 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;
@@ -56,6 +42,3 @@ BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
 
 extern HANDLE driver_key DECLSPEC_HIDDEN;
 extern DEVICE_OBJECT *bus_pdo DECLSPEC_HIDDEN;
-
-extern const platform_vtbl mouse_vtbl DECLSPEC_HIDDEN;
-extern const platform_vtbl keyboard_vtbl DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c
index 6256e0d7f80..9a2a6f1ec8b 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -114,11 +114,6 @@ static inline struct platform_private *impl_from_unix_device(struct unix_device
     return CONTAINING_RECORD(iface, struct platform_private, unix_device);
 }
 
-static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
-{
-    return impl_from_unix_device(get_unix_device(device));
-}
-
 static void CFStringToWSTR(CFStringRef cstr, LPWSTR wstr, int length)
 {
     int len = min(CFStringGetLength(cstr), length-1);
@@ -142,26 +137,26 @@ static void handle_IOHIDDeviceIOHIDReportCallback(void *context,
     process_hid_report(device, report, report_length);
 }
 
-static void free_device(DEVICE_OBJECT *device)
+static void iohid_device_destroy(struct unix_device *iface)
 {
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
     HeapFree(GetProcessHeap(), 0, private);
 }
 
-static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
+static int iohid_device_compare(struct unix_device *iface, void *context)
 {
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
-    IOHIDDeviceRef dev2 = (IOHIDDeviceRef)platform_dev;
+    struct platform_private *private = impl_from_unix_device(iface);
+    IOHIDDeviceRef dev2 = (IOHIDDeviceRef)context;
     if (private->device != dev2)
         return 1;
     else
         return 0;
 }
 
-static NTSTATUS start_device(DEVICE_OBJECT *device)
+static NTSTATUS iohid_device_start(struct unix_device *iface, DEVICE_OBJECT *device)
 {
     DWORD length;
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
     CFNumberRef num;
 
     num = IOHIDDeviceGetProperty(private->device, CFSTR(kIOHIDMaxInputReportSizeKey));
@@ -172,9 +167,10 @@ static NTSTATUS start_device(DEVICE_OBJECT *device)
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length)
+static NTSTATUS iohid_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
+                                                   DWORD length, DWORD *out_length)
 {
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
     CFDataRef data = IOHIDDeviceGetProperty(private->device, CFSTR(kIOHIDReportDescriptorKey));
     int data_length = CFDataGetLength(data);
     const UInt8 *ptr;
@@ -188,9 +184,9 @@ static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length)
+static NTSTATUS iohid_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
 {
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
     CFStringRef str;
     switch (index)
     {
@@ -223,10 +219,10 @@ static NTSTATUS get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DW
     return STATUS_SUCCESS;
 }
 
-static void set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void iohid_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     IOReturn result;
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
     result = IOHIDDeviceSetReport(private->device, kIOHIDReportTypeOutput, packet->reportId,
                                   packet->reportBuffer, packet->reportBufferLen);
     if (result == kIOReturnSuccess)
@@ -241,11 +237,11 @@ static void set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO
     }
 }
 
-static void get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void iohid_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     IOReturn ret;
     CFIndex report_length = packet->reportBufferLen;
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
 
     ret = IOHIDDeviceGetReport(private->device, kIOHIDReportTypeFeature, packet->reportId,
                                packet->reportBuffer, &report_length);
@@ -261,10 +257,10 @@ static void get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, I
     }
 }
 
-static void set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void iohid_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     IOReturn result;
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
 
     result = IOHIDDeviceSetReport(private->device, kIOHIDReportTypeFeature, packet->reportId,
                                   packet->reportBuffer, packet->reportBufferLen);
@@ -280,16 +276,16 @@ static void set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, I
     }
 }
 
-static const platform_vtbl iohid_vtbl =
+static const struct unix_device_vtbl iohid_device_vtbl =
 {
-    free_device,
-    compare_platform_device,
-    start_device,
-    get_reportdescriptor,
-    get_string,
-    set_output_report,
-    get_feature_report,
-    set_feature_report,
+    iohid_device_destroy,
+    iohid_device_compare,
+    iohid_device_start,
+    iohid_device_get_report_descriptor,
+    iohid_device_get_string,
+    iohid_device_set_output_report,
+    iohid_device_get_feature_report,
+    iohid_device_set_feature_report,
 };
 
 static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *sender, IOHIDDeviceRef IOHIDDevice)
@@ -367,8 +363,9 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
 
     if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private))))
         return;
+    private->unix_device.vtbl = &iohid_device_vtbl;
 
-    device = bus_create_hid_device(&desc, &iohid_vtbl, &private->unix_device);
+    device = bus_create_hid_device(&desc, &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 120b7a2d966..1f7cf237e25 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -478,9 +478,9 @@ failed:
     return STATUS_NO_MEMORY;
 }
 
-static void free_device(DEVICE_OBJECT *device)
+static void sdl_device_destroy(struct unix_device *iface)
 {
-    struct platform_private *ext = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *ext = impl_from_unix_device(iface);
 
     pSDL_JoystickClose(ext->sdl_joystick);
     if (ext->sdl_controller)
@@ -491,21 +491,22 @@ static void free_device(DEVICE_OBJECT *device)
     HeapFree(GetProcessHeap(), 0, ext);
 }
 
-static int compare_platform_device(DEVICE_OBJECT *device, void *context)
+static int sdl_device_compare(struct unix_device *iface, void *context)
 {
-    return impl_from_DEVICE_OBJECT(device)->id - PtrToUlong(context);
+    return impl_from_unix_device(iface)->id - PtrToUlong(context);
 }
 
-static NTSTATUS start_device(DEVICE_OBJECT *device)
+static NTSTATUS sdl_device_start(struct unix_device *iface, DEVICE_OBJECT *device)
 {
-    struct platform_private *ext = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *ext = impl_from_unix_device(iface);
     if (ext->sdl_controller) return build_mapped_report_descriptor(ext);
     return build_report_descriptor(ext);
 }
 
-static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length)
+static NTSTATUS sdl_device_get_reportdescriptor(struct unix_device *iface, BYTE *buffer,
+                                                DWORD length, DWORD *out_length)
 {
-    struct platform_private *ext = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *ext = impl_from_unix_device(iface);
 
     *out_length = ext->desc.size;
     if (length < ext->desc.size) return STATUS_BUFFER_TOO_SMALL;
@@ -514,9 +515,9 @@ static NTSTATUS get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length)
+static NTSTATUS sdl_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
 {
-    struct platform_private *ext = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *ext = impl_from_unix_device(iface);
     const char* str = NULL;
 
     switch (index)
@@ -545,9 +546,9 @@ static NTSTATUS get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DW
     return STATUS_SUCCESS;
 }
 
-static void set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void sdl_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
-    struct platform_private *ext = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *ext = impl_from_unix_device(iface);
 
     if (ext->sdl_haptic && packet->reportId == 0)
     {
@@ -592,28 +593,28 @@ static void set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO
     }
 }
 
-static void get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void sdl_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static void set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void sdl_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static const platform_vtbl sdl_vtbl =
+static const struct unix_device_vtbl sdl_device_vtbl =
 {
-    free_device,
-    compare_platform_device,
-    start_device,
-    get_reportdescriptor,
-    get_string,
-    set_output_report,
-    get_feature_report,
-    set_feature_report,
+    sdl_device_destroy,
+    sdl_device_compare,
+    sdl_device_start,
+    sdl_device_get_reportdescriptor,
+    sdl_device_get_string,
+    sdl_device_set_output_report,
+    sdl_device_get_feature_report,
+    sdl_device_set_feature_report,
 };
 
 static BOOL set_report_from_event(DEVICE_OBJECT *device, SDL_Event *event)
@@ -787,9 +788,11 @@ static void sdl_add_device(unsigned int index)
 
     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;
+    if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*private))))
+        return;
+    private->unix_device.vtbl = &sdl_device_vtbl;
 
-    device = bus_create_hid_device(&desc, &sdl_vtbl, &private->unix_device);
+    device = bus_create_hid_device(&desc, &private->unix_device);
     if (!device) HeapFree(GetProcessHeap(), 0, private);
     else
     {
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 4329e54a0b9..d87ee2c043e 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -543,9 +543,9 @@ static WCHAR *get_sysattr_string(struct udev_device *dev, const char *sysattr)
     return strdupAtoW(attr);
 }
 
-static void hidraw_free_device(DEVICE_OBJECT *device)
+static void hidraw_device_destroy(struct unix_device *iface)
 {
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
 
     if (private->report_thread)
     {
@@ -562,18 +562,18 @@ static void hidraw_free_device(DEVICE_OBJECT *device)
     HeapFree(GetProcessHeap(), 0, private);
 }
 
-static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
+static int udev_device_compare(struct unix_device *iface, void *platform_dev)
 {
-    struct udev_device *dev1 = impl_from_DEVICE_OBJECT(device)->udev_device;
+    struct udev_device *dev1 = impl_from_unix_device(iface)->udev_device;
     struct udev_device *dev2 = platform_dev;
     return strcmp(udev_device_get_syspath(dev1), udev_device_get_syspath(dev2));
 }
 
 static DWORD CALLBACK device_report_thread(void *args);
 
-static NTSTATUS hidraw_start_device(DEVICE_OBJECT *device)
+static NTSTATUS hidraw_device_start(struct unix_device *iface, DEVICE_OBJECT *device)
 {
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
 
     if (pipe(private->control_pipe) != 0)
     {
@@ -593,11 +593,12 @@ static NTSTATUS hidraw_start_device(DEVICE_OBJECT *device)
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS hidraw_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length)
+static NTSTATUS hidraw_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
+                                                    DWORD length, DWORD *out_length)
 {
 #ifdef HAVE_LINUX_HIDRAW_H
     struct hidraw_report_descriptor descriptor;
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
 
     if (ioctl(private->device_fd, HIDIOCGRDESCSIZE, &descriptor.size) == -1)
     {
@@ -625,10 +626,10 @@ static NTSTATUS hidraw_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer,
 #endif
 }
 
-static NTSTATUS hidraw_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length)
+static NTSTATUS hidraw_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
 {
     struct udev_device *usbdev;
-    struct platform_private *private = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *private = impl_from_unix_device(iface);
     WCHAR *str = NULL;
 
     usbdev = udev_device_get_parent_with_subsystem_devtype(private->udev_device, "usb", "usb_device");
@@ -727,9 +728,9 @@ static DWORD CALLBACK device_report_thread(void *args)
     return 0;
 }
 
-static void hidraw_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void hidraw_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
-    struct platform_private* ext = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *ext = impl_from_unix_device(iface);
     ULONG length = packet->reportBufferLen;
     BYTE buffer[8192];
     int count = 0;
@@ -757,10 +758,11 @@ static void hidraw_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *pac
     }
 }
 
-static void hidraw_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void hidraw_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet,
+                                             IO_STATUS_BLOCK *io)
 {
 #if defined(HAVE_LINUX_HIDRAW_H) && defined(HIDIOCGFEATURE)
-    struct platform_private* ext = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *ext = impl_from_unix_device(iface);
     ULONG length = packet->reportBufferLen;
     BYTE buffer[8192];
     int count = 0;
@@ -792,10 +794,11 @@ static void hidraw_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *pa
 #endif
 }
 
-static void hidraw_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void hidraw_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet,
+                                             IO_STATUS_BLOCK *io)
 {
 #if defined(HAVE_LINUX_HIDRAW_H) && defined(HIDIOCSFEATURE)
-    struct platform_private* ext = impl_from_DEVICE_OBJECT(device);
+    struct platform_private *ext = impl_from_unix_device(iface);
     ULONG length = packet->reportBufferLen;
     BYTE buffer[8192];
     int count = 0;
@@ -827,28 +830,33 @@ static void hidraw_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *pa
 #endif
 }
 
-static const platform_vtbl hidraw_vtbl =
+static const struct unix_device_vtbl hidraw_device_vtbl =
 {
-    hidraw_free_device,
-    compare_platform_device,
-    hidraw_start_device,
-    hidraw_get_reportdescriptor,
-    hidraw_get_string,
-    hidraw_set_output_report,
-    hidraw_get_feature_report,
-    hidraw_set_feature_report,
+    hidraw_device_destroy,
+    udev_device_compare,
+    hidraw_device_start,
+    hidraw_device_get_report_descriptor,
+    hidraw_device_get_string,
+    hidraw_device_set_output_report,
+    hidraw_device_get_feature_report,
+    hidraw_device_set_feature_report,
 };
 
 #ifdef HAS_PROPER_INPUT_HEADER
 
+static inline struct wine_input_private *input_impl_from_unix_device(struct unix_device *iface)
+{
+    return CONTAINING_RECORD(impl_from_unix_device(iface), struct wine_input_private, base);
+}
+
 static inline struct wine_input_private *input_impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device)
 {
     return CONTAINING_RECORD(impl_from_DEVICE_OBJECT(device), struct wine_input_private, base);
 }
 
-static void lnxev_free_device(DEVICE_OBJECT *device)
+static void lnxev_device_destroy(struct unix_device *iface)
 {
-    struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device);
+    struct wine_input_private *ext = input_impl_from_unix_device(iface);
 
     if (ext->base.report_thread)
     {
@@ -871,9 +879,9 @@ static void lnxev_free_device(DEVICE_OBJECT *device)
 
 static DWORD CALLBACK lnxev_device_report_thread(void *args);
 
-static NTSTATUS lnxev_start_device(DEVICE_OBJECT *device)
+static NTSTATUS lnxev_device_start(struct unix_device *iface, DEVICE_OBJECT *device)
 {
-    struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device);
+    struct wine_input_private *ext = input_impl_from_unix_device(iface);
     NTSTATUS status;
 
     if ((status = build_report_descriptor(ext, ext->base.udev_device)))
@@ -897,9 +905,10 @@ static NTSTATUS lnxev_start_device(DEVICE_OBJECT *device)
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS lnxev_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length)
+static NTSTATUS lnxev_device_get_report_descriptor(struct unix_device *iface, BYTE *buffer,
+                                                   DWORD length, DWORD *out_length)
 {
-    struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device);
+    struct wine_input_private *ext = input_impl_from_unix_device(iface);
 
     *out_length = ext->desc.size;
     if (length < ext->desc.size) return STATUS_BUFFER_TOO_SMALL;
@@ -908,9 +917,9 @@ static NTSTATUS lnxev_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer,
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS lnxev_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length)
+static NTSTATUS lnxev_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
 {
-    struct wine_input_private *ext = input_impl_from_DEVICE_OBJECT(device);
+    struct wine_input_private *ext = input_impl_from_unix_device(iface);
     char str[255];
 
     str[0] = 0;
@@ -965,33 +974,34 @@ static DWORD CALLBACK lnxev_device_report_thread(void *args)
     return 0;
 }
 
-static void lnxev_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void lnxev_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static void lnxev_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void lnxev_device_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static void lnxev_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void lnxev_device_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static const platform_vtbl lnxev_vtbl = {
-    lnxev_free_device,
-    compare_platform_device,
-    lnxev_start_device,
-    lnxev_get_reportdescriptor,
-    lnxev_get_string,
-    lnxev_set_output_report,
-    lnxev_get_feature_report,
-    lnxev_set_feature_report,
+static const struct unix_device_vtbl lnxev_device_vtbl =
+{
+    lnxev_device_destroy,
+    udev_device_compare,
+    lnxev_device_start,
+    lnxev_device_get_report_descriptor,
+    lnxev_device_get_string,
+    lnxev_device_set_output_report,
+    lnxev_device_get_feature_report,
+    lnxev_device_set_feature_report,
 };
 #endif
 
@@ -1145,7 +1155,9 @@ static void udev_add_device(struct udev_device *dev)
     {
         if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private))))
             return;
-        device = bus_create_hid_device(&desc, &hidraw_vtbl, &private->unix_device);
+        private->unix_device.vtbl = &hidraw_device_vtbl;
+
+        device = bus_create_hid_device(&desc, &private->unix_device);
         if (!device) HeapFree(GetProcessHeap(), 0, private);
     }
 #ifdef HAS_PROPER_INPUT_HEADER
@@ -1153,7 +1165,9 @@ static void udev_add_device(struct udev_device *dev)
     {
         if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wine_input_private))))
             return;
-        device = bus_create_hid_device(&desc, &lnxev_vtbl, &private->unix_device);
+        private->unix_device.vtbl = &lnxev_device_vtbl;
+
+        device = bus_create_hid_device(&desc, &private->unix_device);
         if (!device) HeapFree(GetProcessHeap(), 0, private);
     }
 #endif
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 4727c4b043d..520475744d7 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -121,8 +121,6 @@ struct device_extension
     struct device_desc desc;
     DWORD index;
 
-    const platform_vtbl *vtbl;
-
     BYTE *last_report;
     DWORD last_report_size;
     BOOL last_report_read;
@@ -148,6 +146,96 @@ static NTSTATUS winebus_call(unsigned int code, void *args)
     return __wine_unix_call_funcs[code]( args );
 }
 
+static void unix_device_remove(DEVICE_OBJECT *device)
+{
+    struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
+    winebus_call(device_remove, ext->unix_device);
+}
+
+static int unix_device_compare(DEVICE_OBJECT *device, void *context)
+{
+    struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
+    struct device_compare_params params =
+    {
+        .iface = ext->unix_device,
+        .context = context
+    };
+    return winebus_call(device_compare, &params);
+}
+
+static NTSTATUS unix_device_start(DEVICE_OBJECT *device)
+{
+    struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
+    struct device_start_params params =
+    {
+        .iface = ext->unix_device,
+        .device = device
+    };
+    return winebus_call(device_start, &params);
+}
+
+static NTSTATUS unix_device_get_report_descriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *out_length)
+{
+    struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
+    struct device_descriptor_params params =
+    {
+        .iface = ext->unix_device,
+        .buffer = buffer,
+        .length = length,
+        .out_length = out_length
+    };
+    return winebus_call(device_get_report_descriptor, &params);
+}
+
+static NTSTATUS unix_device_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length)
+{
+    struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
+    struct device_string_params params =
+    {
+        .iface = ext->unix_device,
+        .index = index,
+        .buffer = buffer,
+        .length = length,
+    };
+    return winebus_call(device_get_string, &params);
+}
+
+static void unix_device_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+{
+    struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
+    struct device_report_params params =
+    {
+        .iface = ext->unix_device,
+        .packet = packet,
+        .io = io,
+    };
+    winebus_call(device_set_output_report, &params);
+}
+
+static void unix_device_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+{
+    struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
+    struct device_report_params params =
+    {
+        .iface = ext->unix_device,
+        .packet = packet,
+        .io = io,
+    };
+    winebus_call(device_get_feature_report, &params);
+}
+
+static void unix_device_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+{
+    struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
+    struct device_report_params params =
+    {
+        .iface = ext->unix_device,
+        .packet = packet,
+        .io = io,
+    };
+    winebus_call(device_set_feature_report, &params);
+}
+
 struct unix_device *get_unix_device(DEVICE_OBJECT *device)
 {
     struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
@@ -253,8 +341,7 @@ static void remove_pending_irps(DEVICE_OBJECT *device)
     }
 }
 
-DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vtbl *vtbl,
-                                     struct unix_device *unix_device)
+DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, struct unix_device *unix_device)
 {
     static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0};
     struct device_extension *ext;
@@ -263,7 +350,7 @@ DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vt
     WCHAR dev_name[256];
     NTSTATUS status;
 
-    TRACE("desc %s, vtbl %p, unix_device %p\n", debugstr_device_desc(desc), vtbl, unix_device);
+    TRACE("desc %s, unix_device %p\n", debugstr_device_desc(desc), unix_device);
 
     sprintfW(dev_name, device_name_fmtW, desc->busid, unix_device);
     RtlInitUnicodeString(&nameW, dev_name);
@@ -281,7 +368,6 @@ DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, const platform_vt
     ext->device             = device;
     ext->desc               = *desc;
     ext->index              = get_device_index(desc);
-    ext->vtbl               = vtbl;
     ext->last_report        = NULL;
     ext->last_report_size   = 0;
     ext->last_report_read   = TRUE;
@@ -310,7 +396,7 @@ DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev)
     LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry)
     {
         if (strcmpW(ext->desc.busid, bus_id)) continue;
-        if (ext->vtbl->compare_platform_device(ext->device, platform_dev) == 0)
+        if (unix_device_compare(ext->device, platform_dev) == 0)
         {
             ret = ext->device;
             break;
@@ -461,7 +547,7 @@ static void mouse_device_create(void)
     struct device_create_params params = {0};
 
     if (winebus_call(mouse_create, &params)) return;
-    mouse_obj = bus_create_hid_device(&params.desc, &mouse_vtbl, params.device);
+    mouse_obj = bus_create_hid_device(&params.desc, params.device);
     IoInvalidateDeviceRelations(bus_pdo, BusRelations);
 }
 
@@ -470,7 +556,7 @@ static void keyboard_device_create(void)
     struct device_create_params params = {0};
 
     if (winebus_call(keyboard_create, &params)) return;
-    keyboard_obj = bus_create_hid_device(&params.desc, &keyboard_vtbl, params.device);
+    keyboard_obj = bus_create_hid_device(&params.desc, params.device);
     IoInvalidateDeviceRelations(bus_pdo, BusRelations);
 }
 
@@ -688,7 +774,7 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
             EnterCriticalSection(&ext->cs);
             if (ext->state != DEVICE_STATE_STOPPED) status = STATUS_SUCCESS;
             else if (ext->state == DEVICE_STATE_REMOVED) status = STATUS_DELETE_PENDING;
-            else if (!(status = ext->vtbl->start_device(device))) ext->state = DEVICE_STATE_STARTED;
+            else if (!(status = unix_device_start(device))) ext->state = DEVICE_STATE_STARTED;
             else ERR("failed to start device %p, status %#x\n", device, status);
             LeaveCriticalSection(&ext->cs);
             break;
@@ -705,7 +791,7 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
             remove_pending_irps(device);
 
             bus_unlink_hid_device(device);
-            ext->vtbl->free_device(device);
+            unix_device_remove(device);
 
             ext->cs.DebugInfo->Spare[0] = 0;
             DeleteCriticalSection(&ext->cs);
@@ -863,7 +949,7 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
                 break;
             }
 
-            irp->IoStatus.Status = ext->vtbl->get_reportdescriptor(device, NULL, 0, &length);
+            irp->IoStatus.Status = unix_device_get_report_descriptor(device, NULL, 0, &length);
             if (irp->IoStatus.Status != STATUS_SUCCESS &&
                 irp->IoStatus.Status != STATUS_BUFFER_TOO_SMALL)
             {
@@ -886,7 +972,7 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
         }
         case IOCTL_HID_GET_REPORT_DESCRIPTOR:
             TRACE("IOCTL_HID_GET_REPORT_DESCRIPTOR\n");
-            irp->IoStatus.Status = ext->vtbl->get_reportdescriptor(device, irp->UserBuffer, buffer_len, &buffer_len);
+            irp->IoStatus.Status = unix_device_get_report_descriptor(device, irp->UserBuffer, buffer_len, &buffer_len);
             irp->IoStatus.Information = buffer_len;
             break;
         case IOCTL_HID_GET_STRING:
@@ -896,7 +982,7 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
 
             irp->IoStatus.Status = hid_get_native_string(device, index, (WCHAR *)irp->UserBuffer, buffer_len / sizeof(WCHAR));
             if (irp->IoStatus.Status != STATUS_SUCCESS)
-                irp->IoStatus.Status = ext->vtbl->get_string(device, index, (WCHAR *)irp->UserBuffer, buffer_len / sizeof(WCHAR));
+                irp->IoStatus.Status = unix_device_get_string(device, index, (WCHAR *)irp->UserBuffer, buffer_len / sizeof(WCHAR));
             if (irp->IoStatus.Status == STATUS_SUCCESS)
                 irp->IoStatus.Information = (strlenW((WCHAR *)irp->UserBuffer) + 1) * sizeof(WCHAR);
             break;
@@ -934,21 +1020,21 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
         {
             HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
             TRACE_(hid_report)("IOCTL_HID_WRITE_REPORT / IOCTL_HID_SET_OUTPUT_REPORT\n");
-            ext->vtbl->set_output_report(device, packet, &irp->IoStatus);
+            unix_device_set_output_report(device, packet, &irp->IoStatus);
             break;
         }
         case IOCTL_HID_GET_FEATURE:
         {
             HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
             TRACE_(hid_report)("IOCTL_HID_GET_FEATURE\n");
-            ext->vtbl->get_feature_report(device, packet, &irp->IoStatus);
+            unix_device_get_feature_report(device, packet, &irp->IoStatus);
             break;
         }
         case IOCTL_HID_SET_FEATURE:
         {
             HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
             TRACE_(hid_report)("IOCTL_HID_SET_FEATURE\n");
-            ext->vtbl->set_feature_report(device, packet, &irp->IoStatus);
+            unix_device_set_feature_report(device, packet, &irp->IoStatus);
             break;
         }
         default:
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index 56194503090..874a837deff 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -29,8 +29,21 @@
 
 #include "wine/list.h"
 
+struct unix_device_vtbl
+{
+    void (*destroy)(struct unix_device *iface);
+    int (*compare)(struct unix_device *iface, void *platform_dev);
+    NTSTATUS (*start)(struct unix_device *iface, DEVICE_OBJECT *device);
+    NTSTATUS (*get_report_descriptor)(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *out_length);
+    NTSTATUS (*get_string)(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length);
+    void (*set_output_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
+    void (*get_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
+    void (*set_feature_report)(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io);
+};
+
 struct unix_device
 {
+    const struct unix_device_vtbl *vtbl;
 };
 
 extern NTSTATUS sdl_bus_init(void *) DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 9759bf9d911..2337cb3706d 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -30,7 +30,6 @@
 #include "wine/list.h"
 #include "wine/unixlib.h"
 
-#include "bus.h"
 #include "unix_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
@@ -38,11 +37,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
 static struct hid_descriptor mouse_desc;
 static struct hid_descriptor keyboard_desc;
 
-static void mouse_free_device(DEVICE_OBJECT *device)
+static void mouse_remove(struct unix_device *iface)
 {
 }
 
-static NTSTATUS mouse_start_device(DEVICE_OBJECT *device)
+static int mouse_compare(struct unix_device *iface, void *context)
+{
+    return 0;
+}
+
+static NTSTATUS mouse_start(struct unix_device *iface, DEVICE_OBJECT *device)
 {
     if (!hid_descriptor_begin(&mouse_desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_MOUSE))
         return STATUS_NO_MEMORY;
@@ -54,7 +58,7 @@ static NTSTATUS mouse_start_device(DEVICE_OBJECT *device)
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS mouse_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *ret_length)
+static NTSTATUS mouse_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
 {
     TRACE("buffer %p, length %u.\n", buffer, length);
 
@@ -65,7 +69,7 @@ static NTSTATUS mouse_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer,
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS mouse_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length)
+static NTSTATUS mouse_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
 {
     static const WCHAR nameW[] = {'W','i','n','e',' ','H','I','D',' ','m','o','u','s','e',0};
     if (index != HID_STRING_ID_IPRODUCT)
@@ -76,36 +80,37 @@ static NTSTATUS mouse_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buff
     return STATUS_SUCCESS;
 }
 
-static void mouse_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void mouse_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     FIXME("id %u, stub!\n", packet->reportId);
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static void mouse_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void mouse_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     FIXME("id %u, stub!\n", packet->reportId);
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static void mouse_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void mouse_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     FIXME("id %u, stub!\n", packet->reportId);
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-const platform_vtbl mouse_vtbl =
+static const struct unix_device_vtbl mouse_vtbl =
 {
-    .free_device = mouse_free_device,
-    .start_device = mouse_start_device,
-    .get_reportdescriptor = mouse_get_reportdescriptor,
-    .get_string = mouse_get_string,
-    .set_output_report = mouse_set_output_report,
-    .get_feature_report = mouse_get_feature_report,
-    .set_feature_report = mouse_set_feature_report,
+    mouse_remove,
+    mouse_compare,
+    mouse_start,
+    mouse_get_report_descriptor,
+    mouse_get_string,
+    mouse_set_output_report,
+    mouse_get_feature_report,
+    mouse_set_feature_report,
 };
 
 static const WCHAR mouse_bus_id[] = {'W','I','N','E','M','O','U','S','E',0};
@@ -115,7 +120,7 @@ static const struct device_desc mouse_device_desc =
     .input = -1,
     .serial = {'0','0','0','0',0},
 };
-static struct unix_device mouse_device;
+static struct unix_device mouse_device = {.vtbl = &mouse_vtbl};
 
 static NTSTATUS mouse_device_create(void *args)
 {
@@ -125,11 +130,16 @@ static NTSTATUS mouse_device_create(void *args)
     return STATUS_SUCCESS;
 }
 
-static void keyboard_free_device(DEVICE_OBJECT *device)
+static void keyboard_remove(struct unix_device *iface)
 {
 }
 
-static NTSTATUS keyboard_start_device(DEVICE_OBJECT *device)
+static int keyboard_compare(struct unix_device *iface, void *context)
+{
+    return 0;
+}
+
+static NTSTATUS keyboard_start(struct unix_device *iface, DEVICE_OBJECT *device)
 {
     if (!hid_descriptor_begin(&keyboard_desc, HID_USAGE_PAGE_GENERIC, HID_USAGE_GENERIC_KEYBOARD))
         return STATUS_NO_MEMORY;
@@ -141,7 +151,7 @@ static NTSTATUS keyboard_start_device(DEVICE_OBJECT *device)
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS keyboard_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffer, DWORD length, DWORD *ret_length)
+static NTSTATUS keyboard_get_report_descriptor(struct unix_device *iface, BYTE *buffer, DWORD length, DWORD *ret_length)
 {
     TRACE("buffer %p, length %u.\n", buffer, length);
 
@@ -152,7 +162,7 @@ static NTSTATUS keyboard_get_reportdescriptor(DEVICE_OBJECT *device, BYTE *buffe
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS keyboard_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *buffer, DWORD length)
+static NTSTATUS keyboard_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
 {
     static const WCHAR nameW[] = {'W','i','n','e',' ','H','I','D',' ','k','e','y','b','o','a','r','d',0};
     if (index != HID_STRING_ID_IPRODUCT)
@@ -163,36 +173,37 @@ static NTSTATUS keyboard_get_string(DEVICE_OBJECT *device, DWORD index, WCHAR *b
     return STATUS_SUCCESS;
 }
 
-static void keyboard_set_output_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void keyboard_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     FIXME("id %u, stub!\n", packet->reportId);
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static void keyboard_get_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void keyboard_get_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     FIXME("id %u, stub!\n", packet->reportId);
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-static void keyboard_set_feature_report(DEVICE_OBJECT *device, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
+static void keyboard_set_feature_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
 {
     FIXME("id %u, stub!\n", packet->reportId);
     io->Information = 0;
     io->Status = STATUS_NOT_IMPLEMENTED;
 }
 
-const platform_vtbl keyboard_vtbl =
+static const struct unix_device_vtbl keyboard_vtbl =
 {
-    .free_device = keyboard_free_device,
-    .start_device = keyboard_start_device,
-    .get_reportdescriptor = keyboard_get_reportdescriptor,
-    .get_string = keyboard_get_string,
-    .set_output_report = keyboard_set_output_report,
-    .get_feature_report = keyboard_get_feature_report,
-    .set_feature_report = keyboard_set_feature_report,
+    keyboard_remove,
+    keyboard_compare,
+    keyboard_start,
+    keyboard_get_report_descriptor,
+    keyboard_get_string,
+    keyboard_set_output_report,
+    keyboard_get_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};
@@ -202,7 +213,7 @@ static const struct device_desc keyboard_device_desc =
     .input = -1,
     .serial = {'0','0','0','0',0},
 };
-static struct unix_device keyboard_device;
+static struct unix_device keyboard_device = {.vtbl = &keyboard_vtbl};
 
 static NTSTATUS keyboard_device_create(void *args)
 {
@@ -212,6 +223,65 @@ static NTSTATUS keyboard_device_create(void *args)
     return STATUS_SUCCESS;
 }
 
+static NTSTATUS unix_device_remove(void *args)
+{
+    struct unix_device *iface = args;
+    iface->vtbl->destroy(iface);
+    return STATUS_SUCCESS;
+}
+
+static NTSTATUS unix_device_compare(void *args)
+{
+    struct device_compare_params *params = args;
+    struct unix_device *iface = params->iface;
+    return iface->vtbl->compare(iface, params->context);
+}
+
+static NTSTATUS unix_device_start(void *args)
+{
+    struct device_start_params *params = args;
+    struct unix_device *iface = params->iface;
+    return iface->vtbl->start(iface, params->device);
+}
+
+static NTSTATUS unix_device_get_report_descriptor(void *args)
+{
+    struct device_descriptor_params *params = args;
+    struct unix_device *iface = params->iface;
+    return iface->vtbl->get_report_descriptor(iface, params->buffer, params->length, params->out_length);
+}
+
+static NTSTATUS unix_device_get_string(void *args)
+{
+    struct device_string_params *params = args;
+    struct unix_device *iface = params->iface;
+    return iface->vtbl->get_string(iface, params->index, params->buffer, params->length);
+}
+
+static NTSTATUS unix_device_set_output_report(void *args)
+{
+    struct device_report_params *params = args;
+    struct unix_device *iface = params->iface;
+    iface->vtbl->set_output_report(iface, params->packet, params->io);
+    return STATUS_SUCCESS;
+}
+
+static NTSTATUS unix_device_get_feature_report(void *args)
+{
+    struct device_report_params *params = args;
+    struct unix_device *iface = params->iface;
+    iface->vtbl->get_feature_report(iface, params->packet, params->io);
+    return STATUS_SUCCESS;
+}
+
+static NTSTATUS unix_device_set_feature_report(void *args)
+{
+    struct device_report_params *params = args;
+    struct unix_device *iface = params->iface;
+    iface->vtbl->set_feature_report(iface, params->packet, params->io);
+    return STATUS_SUCCESS;
+}
+
 const unixlib_entry_t __wine_unix_call_funcs[] =
 {
     sdl_bus_init,
@@ -225,6 +295,14 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
     iohid_bus_stop,
     mouse_device_create,
     keyboard_device_create,
+    unix_device_remove,
+    unix_device_compare,
+    unix_device_start,
+    unix_device_get_report_descriptor,
+    unix_device_get_string,
+    unix_device_set_output_report,
+    unix_device_get_feature_report,
+    unix_device_set_feature_report,
 };
 
 void bus_event_queue_destroy(struct list *queue)
diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h
index d321c208885..96671de0cac 100644
--- a/dlls/winebus.sys/unixlib.h
+++ b/dlls/winebus.sys/unixlib.h
@@ -25,6 +25,7 @@
 #include <winbase.h>
 #include <winternl.h>
 #include <ddk/wdm.h>
+#include <ddk/hidclass.h>
 #include <hidusage.h>
 
 #include "wine/debug.h"
@@ -87,6 +88,41 @@ struct device_create_params
     struct unix_device *device;
 };
 
+struct device_compare_params
+{
+    struct unix_device *iface;
+    void *context;
+};
+
+struct device_start_params
+{
+    struct unix_device *iface;
+    DEVICE_OBJECT *device;
+};
+
+struct device_descriptor_params
+{
+    struct unix_device *iface;
+    BYTE *buffer;
+    DWORD length;
+    DWORD *out_length;
+};
+
+struct device_string_params
+{
+    struct unix_device *iface;
+    DWORD index;
+    WCHAR *buffer;
+    DWORD length;
+};
+
+struct device_report_params
+{
+    struct unix_device *iface;
+    HID_XFER_PACKET *packet;
+    IO_STATUS_BLOCK *io;
+};
+
 enum unix_funcs
 {
     sdl_init,
@@ -100,6 +136,14 @@ enum unix_funcs
     iohid_stop,
     mouse_create,
     keyboard_create,
+    device_remove,
+    device_compare,
+    device_start,
+    device_get_report_descriptor,
+    device_get_string,
+    device_set_output_report,
+    device_get_feature_report,
+    device_set_feature_report,
 };
 
 extern const unixlib_entry_t __wine_unix_call_funcs[] DECLSPEC_HIDDEN;
-- 
2.33.0




More information about the wine-devel mailing list