[PATCH v5 4/5] winepulse.drv: Fetch actual application name, if possible.
Andrew Eikum
aeikum at codeweavers.com
Mon Feb 21 14:23:35 CST 2022
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
On Fri, Feb 18, 2022 at 08:38:02PM +0200, Gabriel Ivăncescu wrote:
> From: Mark Harmstone <mark at harmstone.com>
>
> Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
> ---
> dlls/winepulse.drv/Makefile.in | 2 +-
> dlls/winepulse.drv/mmdevdrv.c | 106 +++++++++++++++++++++++++++++++--
> 2 files changed, 103 insertions(+), 5 deletions(-)
>
> diff --git a/dlls/winepulse.drv/Makefile.in b/dlls/winepulse.drv/Makefile.in
> index c71b283..d4b40e6 100644
> --- a/dlls/winepulse.drv/Makefile.in
> +++ b/dlls/winepulse.drv/Makefile.in
> @@ -1,7 +1,7 @@
> EXTRADEFS = -DWINE_NO_LONG_TYPES
> MODULE = winepulse.drv
> UNIXLIB = winepulse.so
> -IMPORTS = dxguid uuid winmm user32 advapi32 ole32
> +IMPORTS = dxguid uuid winmm user32 advapi32 ole32 version
> EXTRALIBS = $(PULSE_LIBS) $(PTHREAD_LIBS) -lm
> EXTRAINCL = $(PULSE_CFLAGS)
>
> diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c
> index a07253a..49fafb6 100644
> --- a/dlls/winepulse.drv/mmdevdrv.c
> +++ b/dlls/winepulse.drv/mmdevdrv.c
> @@ -30,6 +30,7 @@
> #include "wine/list.h"
>
> #include "ole2.h"
> +#include "mimeole.h"
> #include "dshow.h"
> #include "dsound.h"
> #include "propsys.h"
> @@ -243,13 +244,110 @@ static DWORD CALLBACK pulse_mainloop_thread(void *event)
> return 0;
> }
>
> -static char *get_application_name(void)
> +typedef struct tagLANGANDCODEPAGE
> +{
> + WORD wLanguage;
> + WORD wCodePage;
> +} LANGANDCODEPAGE;
> +
> +static BOOL query_productname(void *data, LANGANDCODEPAGE *lang, LPVOID *buffer, DWORD *len)
> +{
> + WCHAR pn[37];
> + swprintf(pn, ARRAY_SIZE(pn), L"\\StringFileInfo\\%04x%04x\\ProductName", lang->wLanguage, lang->wCodePage);
> + return VerQueryValueW(data, pn, buffer, len) && *len;
> +}
> +
> +static char *get_application_name(BOOL query_app_name)
> {
> WCHAR path[MAX_PATH], *name;
> + char *str = NULL;
> size_t len;
> - char *str;
>
> GetModuleFileNameW(NULL, path, ARRAY_SIZE(path));
> +
> + if (query_app_name)
> + {
> + UINT translate_size, productname_size;
> + LANGANDCODEPAGE *translate;
> + LPVOID productname;
> + BOOL found = FALSE;
> + void *data = NULL;
> + unsigned int i;
> + LCID locale;
> + DWORD size;
> +
> + size = GetFileVersionInfoSizeW(path, NULL);
> + if (!size)
> + goto skip;
> +
> + data = malloc(size);
> + if (!data)
> + goto skip;
> +
> + if (!GetFileVersionInfoW(path, 0, size, data))
> + goto skip;
> +
> + if (!VerQueryValueW(data, L"\\VarFileInfo\\Translation", (LPVOID *)&translate, &translate_size))
> + goto skip;
> +
> + /* no translations found */
> + if (translate_size < sizeof(LANGANDCODEPAGE))
> + goto skip;
> +
> + /* The following code will try to find the best translation. We first search for an
> + * exact match of the language, then a match of the language PRIMARYLANGID, then we
> + * search for a LANG_NEUTRAL match, and if that still doesn't work we pick the
> + * first entry which contains a proper productname. */
> + locale = GetThreadLocale();
> +
> + for (i = 0; i < translate_size / sizeof(LANGANDCODEPAGE); i++) {
> + if (translate[i].wLanguage == locale &&
> + query_productname(data, &translate[i], &productname, &productname_size)) {
> + found = TRUE;
> + break;
> + }
> + }
> +
> + if (!found) {
> + for (i = 0; i < translate_size / sizeof(LANGANDCODEPAGE); i++) {
> + if (PRIMARYLANGID(translate[i].wLanguage) == PRIMARYLANGID(locale) &&
> + query_productname(data, &translate[i], &productname, &productname_size)) {
> + found = TRUE;
> + break;
> + }
> + }
> + }
> +
> + if (!found) {
> + for (i = 0; i < translate_size / sizeof(LANGANDCODEPAGE); i++) {
> + if (PRIMARYLANGID(translate[i].wLanguage) == LANG_NEUTRAL &&
> + query_productname(data, &translate[i], &productname, &productname_size)) {
> + found = TRUE;
> + break;
> + }
> + }
> + }
> +
> + if (!found) {
> + for (i = 0; i < translate_size / sizeof(LANGANDCODEPAGE); i++) {
> + if (query_productname(data, &translate[i], &productname, &productname_size)) {
> + found = TRUE;
> + break;
> + }
> + }
> + }
> +
> + if (found) {
> + len = WideCharToMultiByte(CP_UTF8, 0, productname, -1, NULL, 0, NULL, NULL);
> + str = malloc(len);
> + if (str) WideCharToMultiByte(CP_UTF8, 0, productname, -1, str, len, NULL, NULL);
> + }
> +
> + skip:
> + free(data);
> + if (str) return str;
> + }
> +
> name = wcsrchr(path, '\\');
> if (!name)
> name = path;
> @@ -390,7 +488,7 @@ int WINAPI AUDDRV_GetPriority(void)
> struct test_connect_params params;
> char *name;
>
> - params.name = name = get_application_name();
> + params.name = name = get_application_name(FALSE);
> params.config = &pulse_config;
> pulse_call(test_connect, ¶ms);
> free(name);
> @@ -776,7 +874,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
> CloseHandle(event);
> }
>
> - params.name = name = get_application_name();
> + params.name = name = get_application_name(TRUE);
> params.pulse_name = This->pulse_name;
> params.dataflow = This->dataflow;
> params.mode = mode;
> --
> 2.34.1
>
>
More information about the wine-devel
mailing list