winebus.sys: Convert the product strings to Unicode on the Unix-side.
This avoids keeping two copies of each string.
It also fixes a regression on macOS from commit 9d4b70473c
that incorrectly treated a CFStringRef as a char ptr.
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e9178864a7
commit
43cd5d8a2d
|
@ -130,6 +130,13 @@ static struct iohid_device *find_device_from_iohid(IOHIDDeviceRef IOHIDDevice)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void CFStringToWSTR(CFStringRef cstr, LPWSTR wstr, int length)
|
||||
{
|
||||
int len = min(CFStringGetLength(cstr), length - 1);
|
||||
CFStringGetCharacters(cstr, CFRangeMake(0, len), (UniChar*)wstr);
|
||||
wstr[len] = 0;
|
||||
}
|
||||
|
||||
static DWORD CFNumberToDWORD(CFNumberRef num)
|
||||
{
|
||||
int dwNum = 0;
|
||||
|
@ -265,10 +272,10 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
|
|||
struct device_desc desc =
|
||||
{
|
||||
.input = -1,
|
||||
.serialnumber = {"0000"},
|
||||
.serialnumber = {'0','0','0','0',0},
|
||||
};
|
||||
struct iohid_device *impl;
|
||||
CFStringRef str = NULL;
|
||||
CFStringRef str;
|
||||
|
||||
desc.vid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDVendorIDKey)));
|
||||
desc.pid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductIDKey)));
|
||||
|
@ -283,11 +290,11 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
|
|||
IOHIDDeviceScheduleWithRunLoop(IOHIDDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
|
||||
str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDManufacturerKey));
|
||||
if (str) lstrcpynA(desc.manufacturer, str, sizeof(desc.manufacturer));
|
||||
if (str) CFStringToWSTR(str, desc.manufacturer, ARRAY_SIZE(desc.manufacturer));
|
||||
str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductKey));
|
||||
if (str) lstrcpynA(desc.product, str, sizeof(desc.product));
|
||||
if (str) CFStringToWSTR(str, desc.product, ARRAY_SIZE(desc.product));
|
||||
str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDSerialNumberKey));
|
||||
if (str) lstrcpynA(desc.serialnumber, str, sizeof(desc.serialnumber));
|
||||
if (str) CFStringToWSTR(str, desc.serialnumber, ARRAY_SIZE(desc.serialnumber));
|
||||
|
||||
if (IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad) ||
|
||||
IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/hid.h"
|
||||
#include "wine/unixlib.h"
|
||||
|
||||
#include "unix_private.h"
|
||||
|
||||
|
@ -693,8 +694,8 @@ static void sdl_add_device(unsigned int index)
|
|||
struct device_desc desc =
|
||||
{
|
||||
.input = -1,
|
||||
.manufacturer = {"SDL"},
|
||||
.serialnumber = {"0000"},
|
||||
.manufacturer = {'S','D','L',0},
|
||||
.serialnumber = {'0','0','0','0',0},
|
||||
};
|
||||
struct sdl_device *impl;
|
||||
|
||||
|
@ -702,6 +703,8 @@ static void sdl_add_device(unsigned int index)
|
|||
SDL_JoystickID id;
|
||||
SDL_JoystickGUID guid;
|
||||
SDL_GameController *controller = NULL;
|
||||
const char *str;
|
||||
char guid_str[33];
|
||||
|
||||
if ((joystick = pSDL_JoystickOpen(index)) == NULL)
|
||||
{
|
||||
|
@ -712,8 +715,9 @@ static void sdl_add_device(unsigned int index)
|
|||
if (options.map_controllers && pSDL_IsGameController(index))
|
||||
controller = pSDL_GameControllerOpen(index);
|
||||
|
||||
if (controller) lstrcpynA(desc.product, pSDL_GameControllerName(controller), sizeof(desc.product));
|
||||
else lstrcpynA(desc.product, pSDL_JoystickName(joystick), sizeof(desc.product));
|
||||
if (controller) str = pSDL_GameControllerName(controller);
|
||||
else str = pSDL_JoystickName(joystick);
|
||||
if (str) ntdll_umbstowcs(str, strlen(str) + 1, desc.product, ARRAY_SIZE(desc.product));
|
||||
|
||||
id = pSDL_JoystickInstanceID(joystick);
|
||||
|
||||
|
@ -730,7 +734,8 @@ static void sdl_add_device(unsigned int index)
|
|||
}
|
||||
|
||||
guid = pSDL_JoystickGetGUID(joystick);
|
||||
pSDL_JoystickGetGUIDString(guid, desc.serialnumber, sizeof(desc.serialnumber));
|
||||
pSDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));
|
||||
ntdll_umbstowcs(guid_str, strlen(guid_str) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber));
|
||||
|
||||
if (controller) desc.is_gamepad = TRUE;
|
||||
else
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/hid.h"
|
||||
#include "wine/unixlib.h"
|
||||
|
||||
#ifdef HAS_PROPER_INPUT_HEADER
|
||||
# include "hidusage.h"
|
||||
|
@ -1061,8 +1062,10 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
|
|||
|
||||
if (!strncmp(ptr, "HID_UNIQ=", 9))
|
||||
{
|
||||
char buffer[MAX_PATH];
|
||||
if (desc->serialnumber[0]) continue;
|
||||
sscanf(ptr, "HID_UNIQ=%256s\n", desc->serialnumber);
|
||||
if (sscanf(ptr, "HID_UNIQ=%256s\n", buffer) == 1)
|
||||
ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc->serialnumber, ARRAY_SIZE(desc->serialnumber));
|
||||
}
|
||||
if (!strncmp(ptr, "HID_PHYS=", 9) || !strncmp(ptr, "PHYS=\"", 6))
|
||||
{
|
||||
|
@ -1086,13 +1089,13 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
|
|||
}
|
||||
|
||||
if (!desc->manufacturer[0] && (tmp = udev_device_get_sysattr_value(dev, "manufacturer")))
|
||||
lstrcpynA(desc->manufacturer, tmp, sizeof(desc->manufacturer));
|
||||
ntdll_umbstowcs(tmp, strlen(tmp) + 1, desc->manufacturer, ARRAY_SIZE(desc->manufacturer));
|
||||
|
||||
if (!desc->product[0] && (tmp = udev_device_get_sysattr_value(dev, "product")))
|
||||
lstrcpynA(desc->product, tmp, sizeof(desc->product));
|
||||
ntdll_umbstowcs(tmp, strlen(tmp) + 1, desc->product, ARRAY_SIZE(desc->product));
|
||||
|
||||
if (!desc->serialnumber[0] && (tmp = udev_device_get_sysattr_value(dev, "serial")))
|
||||
lstrcpynA(desc->serialnumber, tmp, sizeof(desc->serialnumber));
|
||||
ntdll_umbstowcs(tmp, strlen(tmp) + 1, desc->serialnumber, ARRAY_SIZE(desc->serialnumber));
|
||||
}
|
||||
|
||||
static void udev_add_device(struct udev_device *dev)
|
||||
|
@ -1133,17 +1136,22 @@ static void udev_add_device(struct udev_device *dev)
|
|||
subsystem = udev_device_get_subsystem(dev);
|
||||
if (!strcmp(subsystem, "hidraw"))
|
||||
{
|
||||
if (!desc.manufacturer[0]) strcpy(desc.manufacturer, "hidraw");
|
||||
static const WCHAR hidraw[] = {'h','i','d','r','a','w',0};
|
||||
char product[MAX_PATH];
|
||||
|
||||
if (!desc.manufacturer[0]) memcpy(desc.manufacturer, hidraw, sizeof(hidraw));
|
||||
|
||||
#ifdef HAVE_LINUX_HIDRAW_H
|
||||
if (!desc.product[0] && ioctl(fd, HIDIOCGRAWNAME(sizeof(desc.product) - 1), desc.product) < 0)
|
||||
desc.product[0] = 0;
|
||||
if (!desc.product[0] && ioctl(fd, HIDIOCGRAWNAME(sizeof(product) - 1), product) >= 0)
|
||||
ntdll_umbstowcs(product, strlen(product) + 1, desc.product, ARRAY_SIZE(desc.product));
|
||||
#endif
|
||||
}
|
||||
#ifdef HAS_PROPER_INPUT_HEADER
|
||||
else if (!strcmp(subsystem, "input"))
|
||||
{
|
||||
static const WCHAR evdev[] = {'e','v','d','e','v',0};
|
||||
struct input_id device_id = {0};
|
||||
char buffer[MAX_PATH];
|
||||
|
||||
if (ioctl(fd, EVIOCGID, &device_id) < 0)
|
||||
WARN("ioctl(EVIOCGID) failed: %d %s\n", errno, strerror(errno));
|
||||
|
@ -1154,17 +1162,21 @@ static void udev_add_device(struct udev_device *dev)
|
|||
desc.version = device_id.version;
|
||||
}
|
||||
|
||||
if (!desc.manufacturer[0]) strcpy(desc.manufacturer, "evdev");
|
||||
if (!desc.manufacturer[0]) memcpy(desc.manufacturer, evdev, sizeof(evdev));
|
||||
|
||||
if (!desc.product[0] && ioctl(fd, EVIOCGNAME(sizeof(desc.product) - 1), desc.product) <= 0)
|
||||
desc.product[0] = 0;
|
||||
if (!desc.product[0] && ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), buffer) > 0)
|
||||
ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.product, ARRAY_SIZE(desc.product));
|
||||
|
||||
if (!desc.serialnumber[0] && ioctl(fd, EVIOCGUNIQ(sizeof(desc.serialnumber)), desc.serialnumber) < 0)
|
||||
desc.serialnumber[0] = 0;
|
||||
if (!desc.serialnumber[0] && ioctl(fd, EVIOCGUNIQ(sizeof(buffer)), buffer) >= 0)
|
||||
ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!desc.serialnumber[0]) strcpy(desc.serialnumber, "0000");
|
||||
if (!desc.serialnumber[0])
|
||||
{
|
||||
static const WCHAR zeros[] = {'0','0','0','0',0};
|
||||
memcpy(desc.serialnumber, zeros, sizeof(zeros));
|
||||
}
|
||||
|
||||
if (is_xbox_gamepad(desc.vid, desc.pid))
|
||||
desc.is_gamepad = TRUE;
|
||||
|
|
|
@ -70,10 +70,6 @@ struct device_extension
|
|||
struct device_desc desc;
|
||||
DWORD index;
|
||||
|
||||
WCHAR manufacturer[MAX_PATH];
|
||||
WCHAR product[MAX_PATH];
|
||||
WCHAR serialnumber[MAX_PATH];
|
||||
|
||||
BYTE *last_report;
|
||||
DWORD last_report_size;
|
||||
BOOL last_report_read;
|
||||
|
@ -180,11 +176,11 @@ static DWORD get_device_index(struct device_desc *desc)
|
|||
static WCHAR *get_instance_id(DEVICE_OBJECT *device)
|
||||
{
|
||||
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
|
||||
DWORD len = wcslen(ext->serialnumber) + 33;
|
||||
DWORD len = wcslen(ext->desc.serialnumber) + 33;
|
||||
WCHAR *dst;
|
||||
|
||||
if ((dst = ExAllocatePool(PagedPool, len * sizeof(WCHAR))))
|
||||
swprintf(dst, len, L"%i&%s&%x&%i", ext->desc.version, ext->serialnumber, ext->desc.uid, ext->index);
|
||||
swprintf(dst, len, L"%i&%s&%x&%i", ext->desc.version, ext->desc.serialnumber, ext->desc.uid, ext->index);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
@ -299,10 +295,6 @@ static DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, struct uni
|
|||
ext->buffer_size = 0;
|
||||
ext->unix_device = unix_device;
|
||||
|
||||
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);
|
||||
ext->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");
|
||||
|
@ -894,19 +886,19 @@ static NTSTATUS hid_get_device_string(DEVICE_OBJECT *device, DWORD index, WCHAR
|
|||
switch (index)
|
||||
{
|
||||
case HID_STRING_ID_IMANUFACTURER:
|
||||
len = (wcslen(ext->manufacturer) + 1) * sizeof(WCHAR);
|
||||
len = (wcslen(ext->desc.manufacturer) + 1) * sizeof(WCHAR);
|
||||
if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
|
||||
else memcpy(buffer, ext->manufacturer, len);
|
||||
else memcpy(buffer, ext->desc.manufacturer, len);
|
||||
return STATUS_SUCCESS;
|
||||
case HID_STRING_ID_IPRODUCT:
|
||||
len = (wcslen(ext->product) + 1) * sizeof(WCHAR);
|
||||
len = (wcslen(ext->desc.product) + 1) * sizeof(WCHAR);
|
||||
if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
|
||||
else memcpy(buffer, ext->product, len);
|
||||
else memcpy(buffer, ext->desc.product, len);
|
||||
return STATUS_SUCCESS;
|
||||
case HID_STRING_ID_ISERIALNUMBER:
|
||||
len = (wcslen(ext->serialnumber) + 1) * sizeof(WCHAR);
|
||||
len = (wcslen(ext->desc.serialnumber) + 1) * sizeof(WCHAR);
|
||||
if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
|
||||
else memcpy(buffer, ext->serialnumber, len);
|
||||
else memcpy(buffer, ext->desc.serialnumber, len);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -125,9 +125,9 @@ static const struct device_desc mouse_device_desc =
|
|||
.vid = 0x845e,
|
||||
.pid = 0x0001,
|
||||
.input = -1,
|
||||
.manufacturer = {"The Wine Project"},
|
||||
.product = {"Wine HID mouse"},
|
||||
.serialnumber = {"0000"},
|
||||
.manufacturer = {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0},
|
||||
.product = {'W','i','n','e',' ','H','I','D',' ','m','o','u','s','e',0},
|
||||
.serialnumber = {'0','0','0','0',0},
|
||||
};
|
||||
|
||||
static NTSTATUS mouse_device_create(void *args)
|
||||
|
@ -202,9 +202,9 @@ static const struct device_desc keyboard_device_desc =
|
|||
.vid = 0x845e,
|
||||
.pid = 0x0002,
|
||||
.input = -1,
|
||||
.manufacturer = {"The Wine Project"},
|
||||
.product = {"Wine HID keyboard"},
|
||||
.serialnumber = {"0000"},
|
||||
.manufacturer = {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0},
|
||||
.product = {'W','i','n','e',' ','H','I','D',' ','k','e','y','b','o','a','r','d',0},
|
||||
.serialnumber = {'0','0','0','0',0},
|
||||
};
|
||||
|
||||
static NTSTATUS keyboard_device_create(void *args)
|
||||
|
|
|
@ -39,9 +39,9 @@ struct device_desc
|
|||
DWORD uid;
|
||||
BOOL is_gamepad;
|
||||
|
||||
char manufacturer[MAX_PATH];
|
||||
char product[MAX_PATH];
|
||||
char serialnumber[MAX_PATH];
|
||||
WCHAR manufacturer[MAX_PATH];
|
||||
WCHAR product[MAX_PATH];
|
||||
WCHAR serialnumber[MAX_PATH];
|
||||
};
|
||||
|
||||
struct sdl_bus_options
|
||||
|
|
Loading…
Reference in New Issue