Skip to content

Commit

Permalink
[WINMM] PlaySound: Fix user environment variables handling
Browse files Browse the repository at this point in the history
Correctly retrieve user environment variables when impersonating.
Addendum to commit f18111b.
CORE-13951
  • Loading branch information
TAN-Gaming committed Dec 5, 2024
1 parent c569aee commit f058da2
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
2 changes: 1 addition & 1 deletion dll/win32/winmm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
60 changes: 58 additions & 2 deletions dll/win32/winmm/playsound.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "winemm.h"

#include <winternl.h>
#include <userenv.h>

WINE_DEFAULT_DEBUG_CHANNEL(winmm);

Expand All @@ -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;
Expand Down Expand Up @@ -158,15 +214,15 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)

if (type == REG_EXPAND_SZ)
{
count = ExpandEnvironmentStringsW(str, NULL, 0);
count = PlaySound_ExpandEnvironmentStrings(str, NULL, 0);
if (count == 0)
goto None;

pszSnd = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR));
if (!pszSnd)
goto None;

if (ExpandEnvironmentStringsW(str, pszSnd, count) == 0)
if (PlaySound_ExpandEnvironmentStrings(str, pszSnd, count) == 0)
{
HeapFree(GetProcessHeap(), 0, pszSnd);
goto None;
Expand Down

0 comments on commit f058da2

Please sign in to comment.