From: Robert Gerigk <Robert-Gerigk@online.de> Wine's shcore.dll had Set/GetCurrentProcessExplicitAppUserModelID as stubs. SetCurrentProcessExplicitAppUserModelID returned S_OK but discarded the value, and GetCurrentProcessExplicitAppUserModelID always returned NULL with E_NOTIMPL. This broke applications that set an AppUserModelID and later retrieve it, causing "String argument cannot be null or empty" crashes in .NET WPF applications. Implement both functions using a process-wide static variable protected by a critical section. SetCurrentProcessExplicitAppUserModelID validates the input (rejects NULL and strings longer than 128 characters) and stores a CoTaskMemAlloc'd copy. GetCurrentProcessExplicitAppUserModelID returns a CoTaskMemAlloc'd copy to the caller. Signed-off-by: Jan Robert Gerigk <Robert-Gerigk@online.de> --- dlls/shcore/main.c | 54 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c index f04853cb9f5..7a14113eacb 100644 --- a/dlls/shcore/main.c +++ b/dlls/shcore/main.c @@ -30,6 +30,7 @@ #include "featurestagingapi.h" #include "shellscalingapi.h" #include "shcore.h" +#include "appmodel.h" #define WINSHLWAPI #include "shlwapi.h" @@ -249,17 +250,64 @@ HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site) return hr; } +static WCHAR *explicit_app_user_model_id; +static CRITICAL_SECTION appid_cs; +static CRITICAL_SECTION_DEBUG appid_cs_debug = +{ + 0, 0, &appid_cs, + { &appid_cs_debug.ProcessLocksList, &appid_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": appid_cs") } +}; +static CRITICAL_SECTION appid_cs = { &appid_cs_debug, -1, 0, 0, 0, 0 }; + HRESULT WINAPI SetCurrentProcessExplicitAppUserModelID(const WCHAR *appid) { - FIXME("%s: stub\n", debugstr_w(appid)); + WCHAR *new_id = NULL; + DWORD len; + + TRACE("%s\n", debugstr_w(appid)); + + if (!appid) + return E_INVALIDARG; + + len = lstrlenW(appid); + if (len > APPLICATION_USER_MODEL_ID_MAX_LENGTH - 2) + return E_INVALIDARG; + + new_id = CoTaskMemAlloc((len + 1) * sizeof(WCHAR)); + if (!new_id) return E_OUTOFMEMORY; + memcpy(new_id, appid, (len + 1) * sizeof(WCHAR)); + + EnterCriticalSection(&appid_cs); + CoTaskMemFree(explicit_app_user_model_id); + explicit_app_user_model_id = new_id; + LeaveCriticalSection(&appid_cs); + return S_OK; } HRESULT WINAPI GetCurrentProcessExplicitAppUserModelID(const WCHAR **appid) { - FIXME("%p: stub\n", appid); + TRACE("%p\n", appid); + + if (!appid) return E_INVALIDARG; + *appid = NULL; - return E_NOTIMPL; + + EnterCriticalSection(&appid_cs); + if (explicit_app_user_model_id) + { + DWORD len = (lstrlenW(explicit_app_user_model_id) + 1) * sizeof(WCHAR); + WCHAR *copy = CoTaskMemAlloc(len); + if (copy) + { + memcpy(copy, explicit_app_user_model_id, len); + *appid = copy; + } + } + LeaveCriticalSection(&appid_cs); + + return *appid ? S_OK : E_FAIL; } /************************************************************************* -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10565