Signed-off-by: Rémi Bernon rbernon@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, ¶ms)) 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(¶ms.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, ¶ms)) 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(¶ms.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 */
And name the callbacks a bit more consistently.
Signed-off-by: Rémi Bernon rbernon@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, ¶ms); +} + +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, ¶ms); +} + +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, ¶ms); +} + +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, ¶ms); +} + +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, ¶ms); +} + +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, ¶ms); +} + +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, ¶ms); +} + 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, ¶ms)) return; - mouse_obj = bus_create_hid_device(¶ms.desc, &mouse_vtbl, params.device); + mouse_obj = bus_create_hid_device(¶ms.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, ¶ms)) return; - keyboard_obj = bus_create_hid_device(¶ms.desc, &keyboard_vtbl, params.device); + keyboard_obj = bus_create_hid_device(¶ms.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;
Devices are only added from a single thread but they may be destroyed concurrently so we need to guard the list against race conditions.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_udev.c | 73 +++++++++++++++++++++++---------- dlls/winebus.sys/unix_private.h | 1 + 2 files changed, 52 insertions(+), 22 deletions(-)
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index d87ee2c043e..cca1bf5e168 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -88,11 +88,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
WINE_DECLARE_DEBUG_CHANNEL(hid_report);
+static CRITICAL_SECTION udev_cs; +static CRITICAL_SECTION_DEBUG udev_cs_debug = +{ + 0, 0, &udev_cs, + { &udev_cs_debug.ProcessLocksList, &udev_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": udev_cs") } +}; +static CRITICAL_SECTION udev_cs = { &udev_cs_debug, -1, 0, 0, 0, 0 }; + static struct udev *udev_context = NULL; static struct udev_monitor *udev_monitor; static int deviceloop_control[2]; static int udev_monitor_fd; static struct list event_queue = LIST_INIT(event_queue); +static struct list device_list = LIST_INIT(device_list);
static const WCHAR hidraw_busidW[] = {'H','I','D','R','A','W',0}; static const WCHAR lnxev_busidW[] = {'L','N','X','E','V',0}; @@ -119,6 +129,29 @@ static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *de return impl_from_unix_device(get_unix_device(device)); }
+static const char *get_device_syspath(struct udev_device *dev) +{ + struct udev_device *parent; + + if ((parent = udev_device_get_parent_with_subsystem_devtype(dev, "hid", NULL))) + return udev_device_get_syspath(parent); + + if ((parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"))) + return udev_device_get_syspath(parent); + + return ""; +} + +static struct platform_private *find_device_from_syspath(const char *path) +{ + struct platform_private *device; + + LIST_FOR_EACH_ENTRY(device, &device_list, struct platform_private, unix_device.entry) + if (!strcmp(get_device_syspath(device->udev_device), path)) return device; + + return NULL; +} + #ifdef HAS_PROPER_INPUT_HEADER
static const BYTE ABS_TO_HID_MAP[][2] = { @@ -547,6 +580,10 @@ static void hidraw_device_destroy(struct unix_device *iface) { struct platform_private *private = impl_from_unix_device(iface);
+ EnterCriticalSection(&udev_cs); + list_remove(&private->unix_device.entry); + LeaveCriticalSection(&udev_cs); + if (private->report_thread) { write(private->control_pipe[1], "q", 1); @@ -858,6 +895,10 @@ static void lnxev_device_destroy(struct unix_device *iface) { struct wine_input_private *ext = input_impl_from_unix_device(iface);
+ EnterCriticalSection(&udev_cs); + list_remove(&ext->base.unix_device.entry); + LeaveCriticalSection(&udev_cs); + if (ext->base.report_thread) { write(ext->base.control_pipe[1], "q", 1); @@ -1005,25 +1046,6 @@ static const struct unix_device_vtbl lnxev_device_vtbl = }; #endif
-static const char *get_device_syspath(struct udev_device *dev) -{ - struct udev_device *parent; - - if ((parent = udev_device_get_parent_with_subsystem_devtype(dev, "hid", NULL))) - return udev_device_get_syspath(parent); - - if ((parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"))) - return udev_device_get_syspath(parent); - - return ""; -} - -static int check_device_syspath(DEVICE_OBJECT *device, void* context) -{ - struct platform_private *private = impl_from_DEVICE_OBJECT(device); - return strcmp(get_device_syspath(private->udev_device), context); -} - static void get_device_subsystem_info(struct udev_device *dev, char const *subsystem, struct device_desc *desc) { struct udev_device *parent = NULL; @@ -1093,9 +1115,10 @@ static void udev_add_device(struct udev_device *dev) TRACE("udev %s syspath %s\n", debugstr_a(devnode), udev_device_get_syspath(dev));
#ifdef HAS_PROPER_INPUT_HEADER - device = bus_enumerate_hid_devices(lnxev_busidW, check_device_syspath, (void *)get_device_syspath(dev)); - if (!device) device = bus_enumerate_hid_devices(hidraw_busidW, check_device_syspath, (void *)get_device_syspath(dev)); - if (device) + EnterCriticalSection(&udev_cs); + private = find_device_from_syspath(get_device_syspath(dev)); + LeaveCriticalSection(&udev_cs); + if (private) { TRACE("duplicate device found, not adding the new one\n"); close(fd); @@ -1156,6 +1179,9 @@ static void udev_add_device(struct udev_device *dev) if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct platform_private)))) return; private->unix_device.vtbl = &hidraw_device_vtbl; + EnterCriticalSection(&udev_cs); + list_add_tail(&device_list, &private->unix_device.entry); + LeaveCriticalSection(&udev_cs);
device = bus_create_hid_device(&desc, &private->unix_device); if (!device) HeapFree(GetProcessHeap(), 0, private); @@ -1166,6 +1192,9 @@ static void udev_add_device(struct udev_device *dev) if (!(private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wine_input_private)))) return; private->unix_device.vtbl = &lnxev_device_vtbl; + EnterCriticalSection(&udev_cs); + list_add_tail(&device_list, &private->unix_device.entry); + LeaveCriticalSection(&udev_cs);
device = bus_create_hid_device(&desc, &private->unix_device); if (!device) HeapFree(GetProcessHeap(), 0, private); diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h index 874a837deff..81c4658068b 100644 --- a/dlls/winebus.sys/unix_private.h +++ b/dlls/winebus.sys/unix_private.h @@ -44,6 +44,7 @@ struct unix_device_vtbl struct unix_device { const struct unix_device_vtbl *vtbl; + struct list entry; };
extern NTSTATUS sdl_bus_init(void *) DECLSPEC_HIDDEN;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus.h | 3 --- dlls/winebus.sys/main.c | 25 ------------------------- 2 files changed, 28 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index a5615bb31b5..15238538328 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -27,15 +27,12 @@
#include "unixlib.h"
-typedef int(*enum_func)(DEVICE_OBJECT *device, void *context); - 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, 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;
/* General Bus Functions */ BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 520475744d7..8dad037c906 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -408,31 +408,6 @@ DEVICE_OBJECT *bus_find_hid_device(const WCHAR *bus_id, void *platform_dev) return ret; }
-DEVICE_OBJECT *bus_enumerate_hid_devices(const WCHAR *bus_id, enum_func function, void *context) -{ - struct device_extension *ext, *next; - DEVICE_OBJECT *ret = NULL; - int cont; - - TRACE("bus_id %s\n", debugstr_w(bus_id)); - - EnterCriticalSection(&device_list_cs); - LIST_FOR_EACH_ENTRY_SAFE(ext, next, &device_list, struct device_extension, entry) - { - if (strcmpW(ext->desc.busid, bus_id)) continue; - LeaveCriticalSection(&device_list_cs); - cont = function(ext->device, context); - EnterCriticalSection(&device_list_cs); - if (!cont) - { - ret = ext->device; - break; - } - } - LeaveCriticalSection(&device_list_cs); - return ret; -} - static void bus_unlink_hid_device(DEVICE_OBJECT *device) { struct device_extension *ext = (struct device_extension *)device->DeviceExtension;