From: Mark Harmstone mark@harmstone.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@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 d7434ba..88924d1 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" @@ -242,13 +243,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; @@ -395,7 +493,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); @@ -777,7 +875,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, CloseHandle(event); }
- params.name = name = get_application_name(); + params.name = name = get_application_name(TRUE); params.device = This->device; params.dataflow = This->dataflow; params.mode = mode;