[PATCH v4 1/3] winepulse: Try to obtain shorter device names if it exceeds 62 chars.
Andrew Eikum
aeikum at codeweavers.com
Thu May 26 11:37:15 CDT 2022
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
On Thu, May 26, 2022 at 07:06:37PM +0300, Gabriel Ivăncescu wrote:
> If the device desc is longer than the limit, we try to obtain product name
> or alsa name (if product name does not fit in the limit), as otherwise
> there is no point to do it anyway. Then the profile desc is appended if it
> doesn't cause us to exceed the limit.
>
> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53010
> Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
> ---
>
> v4: Forgot to change commit message...
>
> dlls/winepulse.drv/pulse.c | 92 +++++++++++++++++++++++++++++++++-----
> 1 file changed, 80 insertions(+), 12 deletions(-)
>
> diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c
> index 1254509..0e504b6 100644
> --- a/dlls/winepulse.drv/pulse.c
> +++ b/dlls/winepulse.drv/pulse.c
> @@ -426,6 +426,81 @@ static UINT pulse_channel_map_to_channel_mask(const pa_channel_map *map)
> return mask;
> }
>
> +#define MAX_DEVICE_NAME_LEN 62
> +
> +static WCHAR *get_device_name(const char *desc, pa_proplist *proplist)
> +{
> + /*
> + Some broken apps (e.g. Split/Second with fmodex) can't handle names that
> + are too long and crash even on native. If the device desc is too long,
> + we'll attempt to incrementally build it to try to stay under the limit.
> + ( + 1 is to check against truncated buffer after ntdll_umbstowcs )
> + */
> + WCHAR buf[MAX_DEVICE_NAME_LEN + 1];
> +
> + /* For monitors of sinks; this does not seem to be localized in PA either */
> + static const WCHAR monitor_of[] = {'M','o','n','i','t','o','r',' ','o','f',' '};
> +
> + size_t len = strlen(desc);
> + WCHAR *name, *tmp;
> +
> + if (!(name = malloc((len + 1) * sizeof(WCHAR))))
> + return NULL;
> + if (!(len = ntdll_umbstowcs(desc, len, name, len))) {
> + free(name);
> + return NULL;
> + }
> +
> + if (len > MAX_DEVICE_NAME_LEN && proplist) {
> + const char *prop = pa_proplist_gets(proplist, PA_PROP_DEVICE_CLASS);
> + unsigned prop_len, rem = ARRAY_SIZE(buf);
> + BOOL monitor = FALSE;
> +
> + if (prop && !strcmp(prop, "monitor")) {
> + rem -= ARRAY_SIZE(monitor_of);
> + monitor = TRUE;
> + }
> +
> + prop = pa_proplist_gets(proplist, PA_PROP_DEVICE_PRODUCT_NAME);
> + if (!prop || !prop[0] ||
> + !(prop_len = ntdll_umbstowcs(prop, strlen(prop), buf, rem)) || prop_len == rem) {
> + prop = pa_proplist_gets(proplist, "alsa.card_name");
> + if (!prop || !prop[0] ||
> + !(prop_len = ntdll_umbstowcs(prop, strlen(prop), buf, rem)) || prop_len == rem)
> + prop = NULL;
> + }
> +
> + if (prop) {
> + /* We know we have a name that fits within the limit now */
> + WCHAR *p = name;
> +
> + if (monitor) {
> + memcpy(p, monitor_of, sizeof(monitor_of));
> + p += ARRAY_SIZE(monitor_of);
> + }
> + len = ntdll_umbstowcs(prop, strlen(prop), p, rem);
> + rem -= len;
> + p += len;
> +
> + if (rem > 2) {
> + rem--; /* space */
> +
> + prop = pa_proplist_gets(proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION);
> + if (prop && prop[0] && (len = ntdll_umbstowcs(prop, strlen(prop), p + 1, rem)) && len != rem) {
> + *p++ = ' ';
> + p += len;
> + }
> + }
> + len = p - name;
> + }
> + }
> + name[len] = '\0';
> +
> + if ((tmp = realloc(name, (len + 1) * sizeof(WCHAR))))
> + name = tmp;
> + return name;
> +}
> +
> static void fill_device_info(PhysDevice *dev, pa_proplist *p)
> {
> const char *buffer;
> @@ -452,27 +527,18 @@ static void fill_device_info(PhysDevice *dev, pa_proplist *p)
> }
>
> static void pulse_add_device(struct list *list, pa_proplist *proplist, int index, EndpointFormFactor form,
> - UINT channel_mask, const char *pulse_name, const char *name)
> + UINT channel_mask, const char *pulse_name, const char *desc)
> {
> - size_t len = strlen(pulse_name), name_len = strlen(name);
> + size_t len = strlen(pulse_name);
> PhysDevice *dev = malloc(FIELD_OFFSET(PhysDevice, pulse_name[len + 1]));
> - WCHAR *wname;
>
> if (!dev)
> return;
>
> - if (!(wname = malloc((name_len + 1) * sizeof(WCHAR)))) {
> + if (!(dev->name = get_device_name(desc, proplist))) {
> free(dev);
> return;
> }
> -
> - if (!(name_len = ntdll_umbstowcs(name, name_len, wname, name_len)) ||
> - !(dev->name = realloc(wname, (name_len + 1) * sizeof(WCHAR)))) {
> - free(wname);
> - free(dev);
> - return;
> - }
> - dev->name[name_len] = 0;
> dev->form = form;
> dev->index = index;
> dev->channel_mask = channel_mask;
> @@ -480,6 +546,8 @@ static void pulse_add_device(struct list *list, pa_proplist *proplist, int index
> memcpy(dev->pulse_name, pulse_name, len + 1);
>
> list_add_tail(list, &dev->entry);
> +
> + TRACE("%s\n", debugstr_w(dev->name));
> }
>
> static void pulse_phys_speakers_cb(pa_context *c, const pa_sink_info *i, int eol, void *userdata)
> --
> 2.34.1
>
>
More information about the wine-devel
mailing list