winebus.sys: Query serialnumber string on device creation.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-09-13 13:01:48 +02:00 committed by Alexandre Julliard
parent 093c13e333
commit ff0d402efa
6 changed files with 28 additions and 61 deletions

View file

@ -190,9 +190,6 @@ static NTSTATUS iohid_device_get_string(struct unix_device *iface, DWORD index,
CFStringRef str;
switch (index)
{
case HID_STRING_ID_ISERIALNUMBER:
str = IOHIDDeviceGetProperty(private->device, CFSTR(kIOHIDSerialNumberKey));
break;
default:
ERR("Unknown string index\n");
return STATUS_NOT_IMPLEMENTED;
@ -288,7 +285,7 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
{
.busid = busidW,
.input = -1,
.serial = {'0','0','0','0',0},
.serialnumber = {"0000"},
};
struct platform_private *private;
CFStringRef str = NULL;
@ -296,8 +293,6 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
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, desc.serial, ARRAY_SIZE(desc.serial));
desc.uid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDLocationIDKey)));
if (IOHIDDeviceOpen(IOHIDDevice, 0) != kIOReturnSuccess)
@ -311,6 +306,8 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
if (str) lstrcpynA(desc.manufacturer, str, sizeof(desc.manufacturer));
str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductKey));
if (str) lstrcpynA(desc.product, str, sizeof(desc.product));
str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDSerialNumberKey));
if (str) lstrcpynA(desc.serialnumber, str, sizeof(desc.serialnumber));
if (IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad) ||
IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))

View file

@ -521,9 +521,6 @@ static NTSTATUS sdl_device_get_string(struct unix_device *iface, DWORD index, WC
switch (index)
{
case HID_STRING_ID_ISERIALNUMBER:
str = "000000";
break;
default:
ERR("Unhandled string index %i\n", index);
}
@ -728,11 +725,10 @@ static void sdl_add_device(unsigned int index)
{
.busid = sdl_busidW,
.input = -1,
.serial = {'0','0','0','0',0},
.manufacturer = {"SDL"},
.serialnumber = {"0000"},
};
struct platform_private *private;
char guid_str[34];
SDL_Joystick* joystick;
SDL_JoystickID id;
@ -766,8 +762,7 @@ static void sdl_add_device(unsigned int index)
}
guid = pSDL_JoystickGetGUID(joystick);
pSDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));
MultiByteToWideChar(CP_ACP, 0, guid_str, -1, desc.serial, sizeof(guid_str));
pSDL_JoystickGetGUIDString(guid, desc.serialnumber, sizeof(desc.serialnumber));
if (controller) desc.is_gamepad = TRUE;
else

View file

@ -554,28 +554,6 @@ static BOOL set_report_from_event(struct wine_input_private *ext, struct input_e
}
#endif
static inline WCHAR *strdupAtoW(const char *src)
{
WCHAR *dst;
DWORD len;
if (!src) return NULL;
len = MultiByteToWideChar(CP_UNIXCP, 0, src, -1, NULL, 0);
if ((dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
MultiByteToWideChar(CP_UNIXCP, 0, src, -1, dst, len);
return dst;
}
static WCHAR *get_sysattr_string(struct udev_device *dev, const char *sysattr)
{
const char *attr = udev_device_get_sysattr_value(dev, sysattr);
if (!attr)
{
WARN("Could not get %s from device\n", sysattr);
return NULL;
}
return strdupAtoW(attr);
}
static void hidraw_device_destroy(struct unix_device *iface)
{
struct platform_private *private = impl_from_unix_device(iface);
@ -674,9 +652,6 @@ static NTSTATUS hidraw_device_get_string(struct unix_device *iface, DWORD index,
{
switch (index)
{
case HID_STRING_ID_ISERIALNUMBER:
str = get_sysattr_string(usbdev, "serial");
break;
default:
ERR("Unhandled string index %08x\n", index);
return STATUS_NOT_IMPLEMENTED;
@ -687,8 +662,6 @@ static NTSTATUS hidraw_device_get_string(struct unix_device *iface, DWORD index,
#ifdef HAVE_LINUX_HIDRAW_H
switch (index)
{
case HID_STRING_ID_ISERIALNUMBER:
break;
default:
ERR("Unhandled string index %08x\n", index);
return STATUS_NOT_IMPLEMENTED;
@ -943,15 +916,11 @@ static NTSTATUS lnxev_device_get_report_descriptor(struct unix_device *iface, BY
static NTSTATUS lnxev_device_get_string(struct unix_device *iface, DWORD index, WCHAR *buffer, DWORD length)
{
struct wine_input_private *ext = input_impl_from_unix_device(iface);
char str[255];
str[0] = 0;
switch (index)
{
case HID_STRING_ID_ISERIALNUMBER:
ioctl(ext->base.device_fd, EVIOCGUNIQ(sizeof(str)), str);
break;
default:
ERR("Unhandled string index %i\n", index);
}
@ -1027,7 +996,6 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
{
struct udev_device *parent = NULL;
const char *ptr, *next, *tmp;
char buffer[256];
DWORD bus = 0;
if (!(parent = udev_device_get_parent_with_subsystem_devtype(dev, subsystem, NULL))) return;
@ -1042,8 +1010,8 @@ 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 (!desc->serial[0]) MultiByteToWideChar(CP_UNIXCP, 0, buffer, -1, desc->serial, ARRAY_SIZE(desc->serial));
if (desc->serialnumber[0]) continue;
sscanf(ptr, "HID_UNIQ=%256s\n", desc->serialnumber);
}
if (!strncmp(ptr, "HID_PHYS=", 9) || !strncmp(ptr, "PHYS=\"", 6))
{
@ -1071,11 +1039,13 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
if (!desc->product[0] && (tmp = udev_device_get_sysattr_value(dev, "product")))
lstrcpynA(desc->product, tmp, sizeof(desc->product));
if (!desc->serialnumber[0] && (tmp = udev_device_get_sysattr_value(dev, "serial")))
lstrcpynA(desc->serialnumber, tmp, sizeof(desc->serialnumber));
}
static void udev_add_device(struct udev_device *dev)
{
static const WCHAR base_serial[] = {'0','0','0','0',0};
struct device_desc desc =
{
.input = -1,
@ -1127,7 +1097,6 @@ static void udev_add_device(struct udev_device *dev)
else if (!strcmp(subsystem, "input"))
{
struct input_id device_id = {0};
char device_uid[255];
desc.busid = lnxev_busidW;
@ -1140,18 +1109,17 @@ static void udev_add_device(struct udev_device *dev)
desc.version = device_id.version;
}
device_uid[0] = 0;
if (ioctl(fd, EVIOCGUNIQ(254), device_uid) >= 0 && device_uid[0])
MultiByteToWideChar(CP_UNIXCP, 0, device_uid, -1, desc.serial, ARRAY_SIZE(desc.serial));
if (!desc.manufacturer[0]) strcpy(desc.manufacturer, "evdev");
if (!desc.product[0] && ioctl(fd, EVIOCGNAME(sizeof(desc.product) - 1), desc.product) <= 0)
desc.product[0] = 0;
if (!desc.serialnumber[0] && ioctl(fd, EVIOCGUNIQ(sizeof(desc.serialnumber)), desc.serialnumber) < 0)
desc.serialnumber[0] = 0;
}
#endif
if (!desc.serial[0]) lstrcpyW(desc.serial, base_serial);
if (!desc.serialnumber[0]) strcpy(desc.serialnumber, "0000");
if (is_xbox_gamepad(desc.vid, desc.pid))
desc.is_gamepad = TRUE;

View file

@ -113,6 +113,7 @@ struct device_extension
WCHAR manufacturer[MAX_PATH];
WCHAR product[MAX_PATH];
WCHAR serialnumber[MAX_PATH];
BYTE *last_report;
DWORD last_report_size;
@ -253,11 +254,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;
DWORD len = strlenW(ext->desc.serial) + 33;
DWORD len = strlenW(ext->serialnumber) + 33;
WCHAR *dst;
if ((dst = ExAllocatePool(PagedPool, len * sizeof(WCHAR))))
sprintfW(dst, formatW, ext->desc.version, ext->desc.serial, ext->desc.uid, ext->index);
sprintfW(dst, formatW, ext->desc.version, ext->serialnumber, ext->desc.uid, ext->index);
return dst;
}
@ -369,6 +370,7 @@ static DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, struct uni
MultiByteToWideChar(CP_UNIXCP, 0, ext->desc.manufacturer, -1, ext->manufacturer, MAX_PATH);
MultiByteToWideChar(CP_UNIXCP, 0, ext->desc.product, -1, ext->product, MAX_PATH);
MultiByteToWideChar(CP_UNIXCP, 0, ext->desc.serialnumber, -1, ext->serialnumber, MAX_PATH);
InitializeListHead(&ext->irp_queue);
InitializeCriticalSection(&ext->cs);
@ -838,6 +840,11 @@ static NTSTATUS hid_get_device_string(DEVICE_OBJECT *device, DWORD index, WCHAR
if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
else memcpy(buffer, ext->product, len);
return STATUS_SUCCESS;
case HID_STRING_ID_ISERIALNUMBER:
len = (strlenW(ext->serialnumber) + 1) * sizeof(WCHAR);
if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
else memcpy(buffer, ext->serialnumber, len);
return STATUS_SUCCESS;
}
return STATUS_NOT_IMPLEMENTED;

View file

@ -112,9 +112,9 @@ static const struct device_desc mouse_device_desc =
{
.busid = mouse_bus_id,
.input = -1,
.serial = {'0','0','0','0',0},
.manufacturer = {"The Wine Project"},
.product = {"Wine HID mouse"},
.serialnumber = {"0000"},
};
static struct unix_device mouse_device = {.vtbl = &mouse_vtbl};
@ -201,9 +201,9 @@ static const struct device_desc keyboard_device_desc =
{
.busid = keyboard_bus_id,
.input = -1,
.serial = {'0','0','0','0',0},
.manufacturer = {"The Wine Project"},
.product = {"Wine HID keyboard"},
.serialnumber = {"0000"},
};
static struct unix_device keyboard_device = {.vtbl = &keyboard_vtbl};

View file

@ -40,11 +40,11 @@ struct device_desc
DWORD version;
DWORD input;
DWORD uid;
WCHAR serial[256];
BOOL is_gamepad;
char manufacturer[MAX_PATH];
char product[MAX_PATH];
char serialnumber[MAX_PATH];
};
struct sdl_bus_options
@ -161,9 +161,9 @@ 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}",
return wine_dbg_sprintf("{busid %s, vid %04x, pid %04x, version %04x, input %d, uid %08x, is_gamepad %u}",
debugstr_w(desc->busid), desc->vid, desc->pid, desc->version,
desc->input, desc->uid, debugstr_w(desc->serial), desc->is_gamepad);
desc->input, desc->uid, desc->is_gamepad);
}
#endif /* __WINEBUS_UNIXLIB_H */