kernel32: Make GetEnvironmentStringsW returns a copy of the environment.

There are certain applications which try to traverse the environement
being returned, but this is problematic since they cannot acquire the
PEB Lock (i.e cl.exe on Visual Studio 14.15) .

Signed-off-by: Jon Doron <arilou@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jon Doron 2019-03-18 07:20:42 +02:00 committed by Alexandre Julliard
parent 42683dd159
commit be25d225ad
2 changed files with 31 additions and 2 deletions

View File

@ -139,7 +139,21 @@ LPSTR WINAPI GetEnvironmentStringsA(void)
*/
LPWSTR WINAPI GetEnvironmentStringsW(void)
{
return NtCurrentTeb()->Peb->ProcessParameters->Environment;
LPWSTR ret, ptrW;
unsigned len;
RtlAcquirePebLock();
ptrW = NtCurrentTeb()->Peb->ProcessParameters->Environment;
while (*ptrW) ptrW += strlenW(ptrW) + 1;
ptrW++;
len = (ptrW - NtCurrentTeb()->Peb->ProcessParameters->Environment) * sizeof(WCHAR);
ret = HeapAlloc(GetProcessHeap(), 0, len);
if (ret) memcpy(ret, NtCurrentTeb()->Peb->ProcessParameters->Environment, len);
RtlReleasePebLock();
return ret;
}
@ -157,7 +171,7 @@ BOOL WINAPI FreeEnvironmentStringsA( LPSTR ptr )
*/
BOOL WINAPI FreeEnvironmentStringsW( LPWSTR ptr )
{
return TRUE;
return HeapFree( GetProcessHeap(), 0, ptr );
}

View File

@ -554,6 +554,20 @@ static void test_GetComputerNameExW(void)
HeapFree(GetProcessHeap(), 0, nameW);
}
static void test_GetEnvironmentStringsW(void)
{
PWCHAR env1;
PWCHAR env2;
env1 = GetEnvironmentStringsW();
env2 = GetEnvironmentStringsW();
ok(env1 != env2 ||
broken(env1 == env2), /* NT <= 5.1 */
"should return different copies\n");
FreeEnvironmentStringsW(env1);
FreeEnvironmentStringsW(env2);
}
START_TEST(environ)
{
init_functionpointers();
@ -565,4 +579,5 @@ START_TEST(environ)
test_GetComputerName();
test_GetComputerNameExA();
test_GetComputerNameExW();
test_GetEnvironmentStringsW();
}