[PATCH] winebus.sys: Convert the product strings to unicode on the unix-side.
Huw Davies
huw at codeweavers.com
Tue Oct 5 03:55:50 CDT 2021
This avoids keeping two copies of each string.
It also fixes a regression on macOS from commit 9d4b70473c147b
that incorrectly treated a CFStringRef as a char ptr.
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/winebus.sys/bus_iohid.c | 17 +++++++++++-----
dlls/winebus.sys/bus_sdl.c | 15 +++++++++-----
dlls/winebus.sys/bus_udev.c | 38 ++++++++++++++++++++++++------------
dlls/winebus.sys/main.c | 24 ++++++++---------------
dlls/winebus.sys/unixlib.c | 12 ++++++------
dlls/winebus.sys/unixlib.h | 6 +++---
6 files changed, 64 insertions(+), 48 deletions(-)
diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c
index a450402e87b..4412a4bf6dd 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -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))
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 33386a80a34..4e4f275fbc9 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -51,6 +51,7 @@
#include "wine/debug.h"
#include "wine/hid.h"
+#include "wine/unixlib.h"
#include "unix_private.h"
@@ -589,8 +590,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;
@@ -598,6 +599,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)
{
@@ -608,8 +611,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);
@@ -626,7 +630,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
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 3db261b2404..90213b7cd5b 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -73,6 +73,7 @@
#include "wine/debug.h"
#include "wine/hid.h"
+#include "wine/unixlib.h"
#ifdef HAS_PROPER_INPUT_HEADER
# include "hidusage.h"
@@ -945,8 +946,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))
{
@@ -970,13 +973,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)
@@ -1017,17 +1020,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));
@@ -1038,17 +1046,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;
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index b5130a7908e..6a4695cd3be 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -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;
}
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 29537170df7..d14fb30d917 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -114,9 +114,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)
@@ -184,9 +184,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)
diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h
index 317599571c2..e3996838c61 100644
--- a/dlls/winebus.sys/unixlib.h
+++ b/dlls/winebus.sys/unixlib.h
@@ -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
--
2.25.1
More information about the wine-devel
mailing list