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@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
On 10/5/21 10:55 AM, Huw Davies wrote:
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@codeweavers.com
Argh, so much for getting rid of wide strings on the unix side... I guess dropping IOHID is not an option :)