[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    Re: [v2 2/2] winejoystick.drv: Disable joysticks via wine registry on Mac
From:       Ken Thomases <ken () codeweavers ! com>
Date:       2016-08-29 20:02:29
Message-ID: 06805873-DC16-414A-AB77-FE94A228DE4D () codeweavers ! com
[Download RAW message or body]

Hi,

On Aug 29, 2016, at 6:03 AM, David Lawrie <david.dljunk@gmail.com> wrote:
> 
> +static void char_device_name_length(IOHIDDeviceRef device, char *name, int \
> max_length) +{
> +    CFStringRef str = copy_device_name(device);
> +    CFIndex len = CFStringGetLength(str);
> +
> +    if (name)
> +        name[0] = 0;
> +
> +    if (max_length >= len)
> +    {
> +        CFStringGetCString(str,name,max_length,kCFStringEncodingASCII);
> +        CFRelease(str);
> +    }
> +    else
> +    {
> +        CFStringRef substr = CFStringCreateWithSubstring(kCFAllocatorDefault, str, \
> CFRangeMake(0, max_length)); +        CFRelease(str);
> +        CFStringGetCString(substr,name,max_length,kCFStringEncodingASCII);
> +        CFRelease(substr);
> +    }
> +}

I realize you based this function on code from DInput.  Unfortunately, that code is \
pretty badly broken.  CFStringGetLength() returns the length of the string in UTF-16 \
code units, which is basically the same as WCHARs.  It's not meaningful to compare \
that to a buffer size that's in ASCII chars.

Using ASCII is wrong, too.  If the name has any non-ASCII characters in it, the \
conversion will just fail.  Second, it's potentially unnecessarily restrictive.  Your \
device_disabled_registry() function, by virtue of using the "A" variant \
RegQueryValueEx(), uses the ANSI code page, not ASCII.  The ANSI code page could \
maybe handle more names than ASCII would.

You could get a wide string and then use WideCharToMultiByte() to convert it to \
CP_ACP, but since you control all of the relevant code, it's just better to work with \
wide strings throughout.  Change your device_disabled_registry() and get_config_key() \
functions to accept a wide string.  Then, you can safely use CFStringGetLength() and \
CFStringGetCharacters() to acquire the WCHAR-based wide string from the CFString.  \
You can just cast a WCHAR* to a UniChar*.

-Ken


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic