-- v3: wineoss: Call mmdevapi's get_application_name. winecoreaudio: Call mmdevapi's get_application_name. winealsa: Call mmdevapi's get_application_name. winepulse: Move get_application_name into mmdevapi. winepulse: Move AudioClient's Initialize's exclusive mode check into unixlib.
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winepulse.drv/mmdevdrv.c | 2 -- dlls/winepulse.drv/pulse.c | 9 +++++++-- 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index f15fa88c15e..5a276c40f4c 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -698,8 +698,6 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE) return E_INVALIDARG; - if (mode == AUDCLNT_SHAREMODE_EXCLUSIVE) - return AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED;
if (flags & ~(AUDCLNT_STREAMFLAGS_CROSSPROCESS | AUDCLNT_STREAMFLAGS_LOOPBACK | diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index be540a4da2c..ab49a4cc320 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -1116,12 +1116,17 @@ static NTSTATUS pulse_create_stream(void *args) struct pulse_stream *stream; unsigned int i, bufsize_bytes; HRESULT hr; - char *name = wstr_to_str(params->name); + char *name; + + if (params->share == AUDCLNT_SHAREMODE_EXCLUSIVE) { + params->result = AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED; + return STATUS_SUCCESS; + }
pulse_lock();
+ name = wstr_to_str(params->name); params->result = pulse_connect(name); - free(name);
if (FAILED(params->result))
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/mmdevapi/Makefile.in | 2 +- dlls/mmdevapi/client.c | 107 +++++++++++++++++++++++++++ dlls/winealsa.drv/Makefile.in | 2 +- dlls/winecoreaudio.drv/Makefile.in | 2 +- dlls/wineoss.drv/Makefile.in | 2 +- dlls/winepulse.drv/mmdevdrv.c | 113 +---------------------------- 6 files changed, 114 insertions(+), 114 deletions(-)
diff --git a/dlls/mmdevapi/Makefile.in b/dlls/mmdevapi/Makefile.in index ee2848ff2de..027854ea97b 100644 --- a/dlls/mmdevapi/Makefile.in +++ b/dlls/mmdevapi/Makefile.in @@ -1,5 +1,5 @@ MODULE = mmdevapi.dll -IMPORTS = uuid ole32 oleaut32 user32 advapi32 +IMPORTS = uuid ole32 oleaut32 user32 advapi32 version
C_SRCS = \ audiosessionmanager.c \ diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index 8eb6d6867dc..a0a2b225c0b 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -21,6 +21,8 @@
#define COBJMACROS
+#include <wchar.h> + #include <audiopolicy.h> #include <mmdeviceapi.h> #include <winternl.h> @@ -33,6 +35,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
+typedef struct tagLANGANDCODEPAGE +{ + WORD wLanguage; + WORD wCodePage; +} LANGANDCODEPAGE; + extern void sessions_lock(void) DECLSPEC_HIDDEN; extern void sessions_unlock(void) DECLSPEC_HIDDEN;
@@ -169,6 +177,105 @@ static DWORD CALLBACK timer_loop_func(void *user) return 0; }
+static BOOL query_productname(void *data, LANGANDCODEPAGE *lang, LPVOID *buffer, UINT *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; +} + +WCHAR *get_application_name(void) +{ + WCHAR path[MAX_PATH], *name; + UINT translate_size, productname_size; + LANGANDCODEPAGE *translate; + LPVOID productname; + BOOL found = FALSE; + void *data = NULL; + unsigned int i; + LCID locale; + DWORD size; + + GetModuleFileNameW(NULL, path, ARRAY_SIZE(path)); + + 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; + } + } + } +skip: + if (found) { + name = wcsdup(productname); + free(data); + return name; + } + + free(data); + + name = wcsrchr(path, '\'); + if (!name) + name = path; + else + name++; + + return wcsdup(name); +} + static HRESULT WINAPI capture_QueryInterface(IAudioCaptureClient *iface, REFIID riid, void **ppv) { struct audio_client *This = impl_from_IAudioCaptureClient(iface); diff --git a/dlls/winealsa.drv/Makefile.in b/dlls/winealsa.drv/Makefile.in index 9494858c4dd..d1387520742 100644 --- a/dlls/winealsa.drv/Makefile.in +++ b/dlls/winealsa.drv/Makefile.in @@ -1,6 +1,6 @@ MODULE = winealsa.drv UNIXLIB = winealsa.so -IMPORTS = uuid ole32 advapi32 +IMPORTS = uuid ole32 advapi32 version PARENTSRC = ../mmdevapi DELAYIMPORTS = winmm UNIX_LIBS = $(ALSA_LIBS) $(PTHREAD_LIBS) diff --git a/dlls/winecoreaudio.drv/Makefile.in b/dlls/winecoreaudio.drv/Makefile.in index 01c5a3d0073..ecf85cffda4 100644 --- a/dlls/winecoreaudio.drv/Makefile.in +++ b/dlls/winecoreaudio.drv/Makefile.in @@ -1,6 +1,6 @@ MODULE = winecoreaudio.drv UNIXLIB = winecoreaudio.so -IMPORTS = uuid ole32 user32 advapi32 +IMPORTS = uuid ole32 user32 advapi32 version PARENTSRC = ../mmdevapi DELAYIMPORTS = winmm UNIX_LIBS = $(COREAUDIO_LIBS) diff --git a/dlls/wineoss.drv/Makefile.in b/dlls/wineoss.drv/Makefile.in index 121595a7c6c..f571397257b 100644 --- a/dlls/wineoss.drv/Makefile.in +++ b/dlls/wineoss.drv/Makefile.in @@ -1,6 +1,6 @@ MODULE = wineoss.drv UNIXLIB = wineoss.so -IMPORTS = uuid ole32 user32 advapi32 +IMPORTS = uuid ole32 user32 advapi32 version PARENTSRC = ../mmdevapi DELAYIMPORTS = winmm UNIX_LIBS = $(OSS4_LIBS) $(PTHREAD_LIBS) diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 5a276c40f4c..6221856481d 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -133,6 +133,8 @@ extern HRESULT main_loop_start(void) DECLSPEC_HIDDEN; extern struct audio_session_wrapper *session_wrapper_create( struct audio_client *client) DECLSPEC_HIDDEN;
+extern WCHAR *get_application_name(void); + static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface) { return CONTAINING_RECORD(iface, ACImpl, IAudioClient3_iface); @@ -153,115 +155,6 @@ static void pulse_release_stream(stream_handle stream, HANDLE timer) pulse_call(release_stream, ¶ms); }
-typedef struct tagLANGANDCODEPAGE -{ - WORD wLanguage; - WORD wCodePage; -} LANGANDCODEPAGE; - -static BOOL query_productname(void *data, LANGANDCODEPAGE *lang, LPVOID *buffer, UINT *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 WCHAR *get_application_name(BOOL query_app_name) -{ - WCHAR path[MAX_PATH], *name; - - 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; - } - } - } - - skip: - if (found) - { - name = wcsdup(productname); - free(data); - return name; - } - free(data); - } - - name = wcsrchr(path, '\'); - if (!name) - name = path; - else - name++; - return wcsdup(name); -} - static void set_stream_volumes(ACImpl *This) { struct set_volumes_params params; @@ -726,7 +619,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, return hr; }
- params.name = name = get_application_name(TRUE); + params.name = name = get_application_name(); params.device = This->device_name; params.flow = This->dataflow; params.share = mode;
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winealsa.drv/mmdevdrv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c index d2681fc8e9c..916e04ff047 100644 --- a/dlls/winealsa.drv/mmdevdrv.c +++ b/dlls/winealsa.drv/mmdevdrv.c @@ -81,6 +81,8 @@ extern HRESULT main_loop_start(void) DECLSPEC_HIDDEN; extern struct audio_session_wrapper *session_wrapper_create( struct audio_client *client) DECLSPEC_HIDDEN;
+extern WCHAR *get_application_name(void); + void DECLSPEC_HIDDEN sessions_lock(void) { EnterCriticalSection(&g_sessions_lock); @@ -569,6 +571,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, struct create_stream_params params; stream_handle stream; unsigned int i; + WCHAR *name;
TRACE("(%p)->(%x, %lx, %s, %s, %p, %s)\n", This, mode, flags, wine_dbgstr_longlong(duration), wine_dbgstr_longlong(period), fmt, debugstr_guid(sessionguid)); @@ -607,7 +610,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
dump_fmt(fmt);
- params.name = NULL; + params.name = name = get_application_name(); params.device = This->device_name; params.flow = This->dataflow; params.share = mode; @@ -619,6 +622,9 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, params.stream = &stream;
ALSA_CALL(create_stream, ¶ms); + + free(name); + if(FAILED(params.result)){ sessions_unlock(); return params.result;
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winecoreaudio.drv/mmdevdrv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index 300d2a8223a..93a9b4422f2 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -75,6 +75,8 @@ extern HRESULT main_loop_start(void) DECLSPEC_HIDDEN; extern struct audio_session_wrapper *session_wrapper_create( struct audio_client *client) DECLSPEC_HIDDEN;
+extern WCHAR *get_application_name(void); + void DECLSPEC_HIDDEN sessions_lock(void) { EnterCriticalSection(&g_sessions_lock); @@ -556,6 +558,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, struct create_stream_params params; stream_handle stream; UINT32 i; + WCHAR *name;
TRACE("(%p)->(%x, %lx, %s, %s, %p, %s)\n", This, mode, flags, wine_dbgstr_longlong(duration), wine_dbgstr_longlong(period), fmt, debugstr_guid(sessionguid)); @@ -594,7 +597,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, return params.result; }
- params.name = NULL; + params.name = name = get_application_name(); params.device = This->device_name; params.flow = This->dataflow; params.share = mode; @@ -606,6 +609,9 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, params.stream = &stream;
UNIX_CALL(create_stream, ¶ms); + + free(name); + if(FAILED(params.result)){ sessions_unlock(); return params.result;
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/wineoss.drv/mmdevdrv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c index 038dcecd07f..c1d9cc6d1a9 100644 --- a/dlls/wineoss.drv/mmdevdrv.c +++ b/dlls/wineoss.drv/mmdevdrv.c @@ -87,6 +87,8 @@ extern HRESULT main_loop_start(void) DECLSPEC_HIDDEN; extern struct audio_session_wrapper *session_wrapper_create( struct audio_client *client) DECLSPEC_HIDDEN;
+extern WCHAR *get_application_name(void); + void DECLSPEC_HIDDEN sessions_lock(void) { EnterCriticalSection(&g_sessions_lock); @@ -544,6 +546,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, struct create_stream_params params; stream_handle stream; unsigned int i; + WCHAR *name;
TRACE("(%p)->(%x, %lx, %s, %s, %p, %s)\n", This, mode, flags, wine_dbgstr_longlong(duration), wine_dbgstr_longlong(period), fmt, debugstr_guid(sessionguid)); @@ -582,7 +585,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, return params.result; }
- params.name = NULL; + params.name = name = get_application_name(); params.device = This->device_name; params.flow = This->dataflow; params.share = mode; @@ -594,6 +597,9 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, params.stream = &stream;
OSS_CALL(create_stream, ¶ms); + + free(name); + if(FAILED(params.result)){ sessions_unlock(); return params.result;
On Fri Jun 16 06:32:41 2023 +0000, Davide Beatrici wrote:
changed this line in [version 3 of the diff](/wine/wine/-/merge_requests/3062/diffs?diff_id=52151&start_sha=644adf5f43e06c0d8dcec6f24eab9f005e0d93df#99913733944fc35298a259705e992a42b21541f5_225_225)
I also reverted `++name` to `name++`.
This merge request was approved by Huw Davies.