-- v2: 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 b1b178e00a5..4c85cf5d29e 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; + BOOLEAN 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;
Huw Davies (@huw) commented about dlls/mmdevapi/client.c:
}
+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;
- BOOLEAN found = FALSE;
Could we avoid making unnecessary changes like `BOOL` -> `BOOLEAN`? It makes looking for real changes using e.g. `--color-moved` more difficult.
Huw Davies (@huw) commented about dlls/mmdevapi/client.c:
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) {
Likewise `i++` -> `++i` (I personally prefer the former anyway, but in any case there's no need to change it from the original).
However, I don't mind if brace placements are fixed up so that the function is consistent.
On Fri Jun 16 06:20:16 2023 +0000, Huw Davies wrote:
Likewise `i++` -> `++i` (I personally prefer the former anyway, but in any case there's no need to change it from the original). However, I don't mind if brace placements are fixed up so that the function is consistent.
Oh, sorry, I didn't know you preferred the former... I've always been using the latter, also in already merged MRs.
On Fri Jun 16 06:24:41 2023 +0000, Davide Beatrici wrote:
Oh, sorry, I didn't know you preferred the former... I've always been using the latter, also in already merged MRs.
Well it's more about not making unnecessary changes rather than my personal preferences.
On Fri Jun 16 06:26:37 2023 +0000, Huw Davies wrote:
Well it's more about not making unnecessary changes rather than my personal preferences.
Sure, I understand.