https://git.reactos.org/?p=reactos.git;a=commitdiff;h=92231340ec071bd7a461d…
commit 92231340ec071bd7a461d8a941b4cd82b865bc81
Author: Thamatip Chitpong <thamatip.chitpong(a)reactos.org>
AuthorDate: Sat Dec 7 09:15:11 2024 +0700
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Dec 7 09:15:11 2024 +0700
[WINMM] PlaySound: Fix user-specific environment variables handling (#7536)
Correctly retrieve user-specific environment variables when impersonating.
Addendum to commit f18111b64120806529e93404f21b6320f211ec39.
CORE-13951
---
dll/win32/winmm/CMakeLists.txt | 2 +-
dll/win32/winmm/playsound.c | 60 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/dll/win32/winmm/CMakeLists.txt b/dll/win32/winmm/CMakeLists.txt
index aca0942d4be..2566277f94d 100644
--- a/dll/win32/winmm/CMakeLists.txt
+++ b/dll/win32/winmm/CMakeLists.txt
@@ -30,7 +30,7 @@ endif()
set_module_type(winmm win32dll)
target_link_libraries(winmm wine ${PSEH_LIB} oldnames)
-add_importlibs(winmm advapi32 user32 msvcrt kernel32 ntdll)
+add_importlibs(winmm userenv advapi32 user32 msvcrt kernel32 ntdll)
add_pch(winmm winemm.h SOURCE)
add_cd_file(TARGET winmm DESTINATION reactos/system32 FOR all)
diff --git a/dll/win32/winmm/playsound.c b/dll/win32/winmm/playsound.c
index df532f05cfd..991299a0a7f 100644
--- a/dll/win32/winmm/playsound.c
+++ b/dll/win32/winmm/playsound.c
@@ -26,6 +26,7 @@
#include "winemm.h"
#include <winternl.h>
+#include <userenv.h>
WINE_DEFAULT_DEBUG_CHANNEL(winmm);
@@ -39,6 +40,61 @@ typedef struct tagWINE_PLAYSOUND
static WINE_PLAYSOUND *PlaySoundCurrent;
static BOOL bPlaySoundStop;
+/* An impersonation-aware equivalent of ExpandEnvironmentStringsW */
+static DWORD PlaySound_ExpandEnvironmentStrings(LPCWSTR lpSrc, LPWSTR lpDst, DWORD
nSize)
+{
+ HANDLE hToken;
+ DWORD dwError;
+ DWORD dwLength = 0;
+
+ if (!OpenThreadToken(GetCurrentThread(),
+ TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
+ TRUE,
+ &hToken))
+ {
+ dwError = GetLastError();
+
+ if (dwError == ERROR_NO_TOKEN)
+ {
+ /* We are not impersonating, forward this to ExpandEnvironmentStrings */
+ return ExpandEnvironmentStringsW(lpSrc, lpDst, nSize);
+ }
+
+ ERR("OpenThreadToken failed (0x%x)\n", dwError);
+ return 0;
+ }
+
+ if (!ExpandEnvironmentStringsForUserW(hToken, lpSrc, lpDst, nSize))
+ {
+ dwError = GetLastError();
+
+ if (dwError == ERROR_INSUFFICIENT_BUFFER || nSize == 0)
+ {
+ /* The buffer is too small, find the required buffer size.
+ * NOTE: ExpandEnvironmentStringsForUser doesn't support retrieving
buffer size. */
+ WCHAR szExpanded[1024];
+
+ if (ExpandEnvironmentStringsForUserW(hToken, lpSrc, szExpanded,
ARRAY_SIZE(szExpanded)))
+ {
+ /* We success, return the required buffer size */
+ dwLength = lstrlenW(szExpanded) + 1;
+ goto Cleanup;
+ }
+ }
+
+ ERR("ExpandEnvironmentStringsForUser failed (0x%x)\n", dwError);
+ }
+ else
+ {
+ /* We success, return the size of the string */
+ dwLength = lstrlenW(lpDst) + 1;
+ }
+
+Cleanup:
+ CloseHandle(hToken);
+ return dwLength;
+}
+
static HMMIO get_mmioFromFile(LPCWSTR lpszName)
{
HMMIO ret;
@@ -158,7 +214,7 @@ Next:
if (type == REG_EXPAND_SZ)
{
- count = ExpandEnvironmentStringsW(str, NULL, 0);
+ count = PlaySound_ExpandEnvironmentStrings(str, NULL, 0);
if (count == 0)
goto None;
@@ -166,7 +222,7 @@ Next:
if (!pszSnd)
goto None;
- if (ExpandEnvironmentStringsW(str, pszSnd, count) == 0)
+ if (PlaySound_ExpandEnvironmentStrings(str, pszSnd, count) == 0)
{
HeapFree(GetProcessHeap(), 0, pszSnd);
goto None;