userenv: Improved CreateEnvironmentBlock implementation.
This commit is contained in:
parent
2429ef905c
commit
f0d8c3383e
|
@ -35,10 +35,11 @@
|
||||||
#define expect_env(EXPECTED,GOT,VAR) ok((GOT)==(EXPECTED), "Expected %d, got %d for %s (%d)\n", (EXPECTED), (GOT), (VAR), j)
|
#define expect_env(EXPECTED,GOT,VAR) ok((GOT)==(EXPECTED), "Expected %d, got %d for %s (%d)\n", (EXPECTED), (GOT), (VAR), j)
|
||||||
#define expect_gle(EXPECTED) ok(GetLastError() == (EXPECTED), "Expected %d, got %d\n", (EXPECTED), GetLastError())
|
#define expect_gle(EXPECTED) ok(GetLastError() == (EXPECTED), "Expected %d, got %d\n", (EXPECTED), GetLastError())
|
||||||
|
|
||||||
|
static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
|
||||||
|
|
||||||
struct profile_item
|
struct profile_item
|
||||||
{
|
{
|
||||||
const char * name;
|
const char * name;
|
||||||
const int todo[4];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Helper function for retrieving environment variables */
|
/* Helper function for retrieving environment variables */
|
||||||
|
@ -74,40 +75,48 @@ static BOOL get_env(const WCHAR * env, const char * var, char ** result)
|
||||||
|
|
||||||
static void test_create_env(void)
|
static void test_create_env(void)
|
||||||
{
|
{
|
||||||
BOOL r;
|
BOOL r, is_wow64 = FALSE;
|
||||||
HANDLE htok;
|
HANDLE htok;
|
||||||
WCHAR * env[4];
|
WCHAR * env[4];
|
||||||
char * st;
|
char * st, systemroot[100];
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
static const struct profile_item common_vars[] = {
|
static const struct profile_item common_vars[] = {
|
||||||
{ "ComSpec", { 1, 1, 0, 0 } },
|
{ "ComSpec" },
|
||||||
{ "COMPUTERNAME", { 1, 1, 1, 1 } },
|
{ "COMPUTERNAME" },
|
||||||
{ "NUMBER_OF_PROCESSORS", { 1, 1, 0, 0 } },
|
{ "NUMBER_OF_PROCESSORS" },
|
||||||
{ "OS", { 1, 1, 0, 0 } },
|
{ "OS" },
|
||||||
{ "PROCESSOR_ARCHITECTURE", { 1, 1, 0, 0 } },
|
{ "PROCESSOR_ARCHITECTURE" },
|
||||||
{ "PROCESSOR_IDENTIFIER", { 1, 1, 0, 0 } },
|
{ "PROCESSOR_IDENTIFIER" },
|
||||||
{ "PROCESSOR_LEVEL", { 1, 1, 0, 0 } },
|
{ "PROCESSOR_LEVEL" },
|
||||||
{ "PROCESSOR_REVISION", { 1, 1, 0, 0 } },
|
{ "PROCESSOR_REVISION" },
|
||||||
{ "SystemDrive", { 1, 1, 0, 0 } },
|
{ "SystemDrive" },
|
||||||
{ "SystemRoot", { 1, 1, 0, 0 } },
|
{ "SystemRoot" },
|
||||||
{ "windir", { 1, 1, 0, 0 } }
|
{ "windir" }
|
||||||
};
|
};
|
||||||
static const struct profile_item common_post_nt4_vars[] = {
|
static const struct profile_item common_post_nt4_vars[] = {
|
||||||
{ "ALLUSERSPROFILE", { 1, 1, 0, 0 } },
|
{ "ALLUSERSPROFILE" },
|
||||||
{ "TEMP", { 1, 1, 0, 0 } },
|
{ "TEMP" },
|
||||||
{ "TMP", { 1, 1, 0, 0 } },
|
{ "TMP" },
|
||||||
{ "CommonProgramFiles", { 1, 1, 0, 0 } },
|
{ "CommonProgramFiles" },
|
||||||
{ "ProgramFiles", { 1, 1, 0, 0 } }
|
{ "ProgramFiles" },
|
||||||
|
{ "PATH" },
|
||||||
|
{ "USERPROFILE" }
|
||||||
};
|
};
|
||||||
static const struct profile_item htok_vars[] = {
|
static const struct profile_item common_win64_vars[] = {
|
||||||
{ "PATH", { 1, 1, 0, 0 } },
|
{ "ProgramW6432" },
|
||||||
{ "USERPROFILE", { 1, 1, 0, 0 } }
|
{ "CommonProgramW6432" }
|
||||||
};
|
};
|
||||||
|
|
||||||
r = SetEnvironmentVariableA("WINE_XYZZY", "ZZYZX");
|
r = SetEnvironmentVariableA("WINE_XYZZY", "ZZYZX");
|
||||||
expect(TRUE, r);
|
expect(TRUE, r);
|
||||||
|
|
||||||
|
r = GetEnvironmentVariableA("SystemRoot", systemroot, sizeof(systemroot));
|
||||||
|
ok(r != 0, "GetEnvironmentVariable failed (%d)\n", GetLastError());
|
||||||
|
|
||||||
|
r = SetEnvironmentVariableA("SystemRoot", "overwrite");
|
||||||
|
expect(TRUE, r);
|
||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
/* Crashes on NT4 */
|
/* Crashes on NT4 */
|
||||||
|
@ -137,16 +146,23 @@ static void test_create_env(void)
|
||||||
r = CreateEnvironmentBlock((LPVOID) &env[3], htok, TRUE);
|
r = CreateEnvironmentBlock((LPVOID) &env[3], htok, TRUE);
|
||||||
expect(TRUE, r);
|
expect(TRUE, r);
|
||||||
|
|
||||||
|
r = SetEnvironmentVariableA("SystemRoot", systemroot);
|
||||||
|
expect(TRUE, r);
|
||||||
|
|
||||||
|
for(i=0; i<4; i++)
|
||||||
|
{
|
||||||
|
r = get_env(env[i], "SystemRoot", &st);
|
||||||
|
ok(!strcmp(st, "SystemRoot=overwrite"), "%s\n", st);
|
||||||
|
expect(TRUE, r);
|
||||||
|
}
|
||||||
|
|
||||||
/* Test for common environment variables (NT4 and higher) */
|
/* Test for common environment variables (NT4 and higher) */
|
||||||
for (i = 0; i < sizeof(common_vars)/sizeof(common_vars[0]); i++)
|
for (i = 0; i < sizeof(common_vars)/sizeof(common_vars[0]); i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++)
|
||||||
{
|
{
|
||||||
r = get_env(env[j], common_vars[i].name, &st);
|
r = get_env(env[j], common_vars[i].name, &st);
|
||||||
if (common_vars[i].todo[j])
|
expect_env(TRUE, r, common_vars[i].name);
|
||||||
todo_wine expect_env(TRUE, r, common_vars[i].name);
|
|
||||||
else
|
|
||||||
expect_env(TRUE, r, common_vars[i].name);
|
|
||||||
if (r) HeapFree(GetProcessHeap(), 0, st);
|
if (r) HeapFree(GetProcessHeap(), 0, st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,26 +179,24 @@ static void test_create_env(void)
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++)
|
||||||
{
|
{
|
||||||
r = get_env(env[j], common_post_nt4_vars[i].name, &st);
|
r = get_env(env[j], common_post_nt4_vars[i].name, &st);
|
||||||
if (common_post_nt4_vars[i].todo[j])
|
expect_env(TRUE, r, common_post_nt4_vars[i].name);
|
||||||
todo_wine expect_env(TRUE, r, common_post_nt4_vars[i].name);
|
|
||||||
else
|
|
||||||
expect_env(TRUE, r, common_post_nt4_vars[i].name);
|
|
||||||
if (r) HeapFree(GetProcessHeap(), 0, st);
|
if (r) HeapFree(GetProcessHeap(), 0, st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test for environment variables with values that depends on htok */
|
if(pIsWow64Process)
|
||||||
for (i = 0; i < sizeof(htok_vars)/sizeof(htok_vars[0]); i++)
|
pIsWow64Process(GetCurrentProcess(), &is_wow64);
|
||||||
|
if (sizeof(void*)==8 || is_wow64)
|
||||||
{
|
{
|
||||||
for (j = 0; j < 4; j++)
|
for (i = 0; i < sizeof(common_win64_vars)/sizeof(common_win64_vars[0]); i++)
|
||||||
{
|
{
|
||||||
r = get_env(env[j], htok_vars[i].name, &st);
|
for (j=0; j<4; j++)
|
||||||
if (htok_vars[i].todo[j])
|
{
|
||||||
todo_wine expect_env(TRUE, r, htok_vars[i].name);
|
r = get_env(env[j], common_win64_vars[i].name, &st);
|
||||||
else
|
ok(r || broken(!r)/* Vista,2k3,XP */, "Expected 1, got 0 for %s\n", common_win64_vars[i].name);
|
||||||
expect_env(TRUE, r, htok_vars[i].name);
|
if (r) HeapFree(GetProcessHeap(), 0, st);
|
||||||
if (r) HeapFree(GetProcessHeap(), 0, st);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,6 +402,8 @@ static void test_get_user_profile_dir(void)
|
||||||
|
|
||||||
START_TEST(userenv)
|
START_TEST(userenv)
|
||||||
{
|
{
|
||||||
|
pIsWow64Process = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
|
||||||
|
|
||||||
test_create_env();
|
test_create_env();
|
||||||
test_get_profiles_dir();
|
test_get_profiles_dir();
|
||||||
test_get_user_profile_dir();
|
test_get_user_profile_dir();
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
|
#include "sddl.h"
|
||||||
#include "userenv.h"
|
#include "userenv.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
@ -51,20 +52,384 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL get_reg_value(WCHAR *env, HKEY hkey, const WCHAR *name, WCHAR *val, DWORD size)
|
||||||
|
{
|
||||||
|
DWORD type, res_size=0;
|
||||||
|
|
||||||
|
if (RegQueryValueExW(hkey, name, 0, &type, NULL, &res_size) != ERROR_SUCCESS)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (type == REG_SZ)
|
||||||
|
{
|
||||||
|
if (res_size > size)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return RegQueryValueExW(hkey, name, 0, NULL, (BYTE*)val, &size) == ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (type == REG_EXPAND_SZ)
|
||||||
|
{
|
||||||
|
UNICODE_STRING us_buf, us_expanded;
|
||||||
|
WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, res_size);
|
||||||
|
if (!buf)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (RegQueryValueExW(hkey, name, 0, NULL, (BYTE*)buf, &res_size) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, buf);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&us_buf, buf);
|
||||||
|
us_expanded.Buffer = val;
|
||||||
|
us_expanded.MaximumLength = size;
|
||||||
|
if (RtlExpandEnvironmentStrings_U(env, &us_buf, &us_expanded, &size) != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, buf);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, buf);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_registry_variables(WCHAR **env, HKEY hkey, DWORD type, BOOL set_path)
|
||||||
|
{
|
||||||
|
static const WCHAR SystemRootW[] = {'S','y','s','t','e','m','R','o','o','t',0};
|
||||||
|
static const WCHAR SystemDriveW[] = {'S','y','s','t','e','m','D','r','i','v','e',0};
|
||||||
|
static const WCHAR PATHW[] = {'P','A','T','H'};
|
||||||
|
|
||||||
|
UNICODE_STRING us_name, us_value;
|
||||||
|
WCHAR name[1024], value[1024];
|
||||||
|
DWORD ret, index, size;
|
||||||
|
|
||||||
|
for (index = 0; ; index++)
|
||||||
|
{
|
||||||
|
size = sizeof(name)/sizeof(WCHAR);
|
||||||
|
ret = RegEnumValueW(hkey, index, name, &size, NULL, NULL, NULL, NULL);
|
||||||
|
if (ret != ERROR_SUCCESS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!memicmpW(name, SystemRootW, sizeof(SystemRootW)/sizeof(WCHAR)))
|
||||||
|
continue;
|
||||||
|
if (!memicmpW(name, SystemDriveW, sizeof(SystemDriveW)/sizeof(WCHAR)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&us_name, name);
|
||||||
|
us_value.Buffer = value;
|
||||||
|
us_value.MaximumLength = sizeof(value);
|
||||||
|
if (!memicmpW(name, PATHW, sizeof(PATHW)/sizeof(WCHAR)) &&
|
||||||
|
!RtlQueryEnvironmentVariable_U(*env, &us_name, &us_value))
|
||||||
|
{
|
||||||
|
if (!set_path)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
size = strlenW(value)+1;
|
||||||
|
if (!get_reg_value(*env, hkey, name, value+size,
|
||||||
|
sizeof(value)-size*sizeof(WCHAR)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
value[size] = ';';
|
||||||
|
RtlInitUnicodeString(&us_value, value);
|
||||||
|
RtlSetEnvironmentVariable(env, &us_name, &us_value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!get_reg_value(*env, hkey, name, value, sizeof(value)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!value[0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&us_value, value);
|
||||||
|
RtlSetEnvironmentVariable(env, &us_name, &us_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_wow64_environment(WCHAR **env)
|
||||||
|
{
|
||||||
|
static const WCHAR versionW[] = {'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
|
||||||
|
static const WCHAR progdirW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0};
|
||||||
|
static const WCHAR progdir86W[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0};
|
||||||
|
static const WCHAR progfilesW[] = {'P','r','o','g','r','a','m','F','i','l','e','s',0};
|
||||||
|
static const WCHAR progw6432W[] = {'P','r','o','g','r','a','m','W','6','4','3','2',0};
|
||||||
|
static const WCHAR commondirW[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',0};
|
||||||
|
static const WCHAR commondir86W[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0};
|
||||||
|
static const WCHAR commonfilesW[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','F','i','l','e','s',0};
|
||||||
|
static const WCHAR commonw6432W[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','W','6','4','3','2',0};
|
||||||
|
|
||||||
|
UNICODE_STRING nameW, valueW;
|
||||||
|
WCHAR buf[64];
|
||||||
|
HKEY hkey;
|
||||||
|
BOOL is_win64 = (sizeof(void *) > sizeof(int));
|
||||||
|
BOOL is_wow64;
|
||||||
|
|
||||||
|
IsWow64Process( GetCurrentProcess(), &is_wow64 );
|
||||||
|
|
||||||
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, versionW, 0,
|
||||||
|
KEY_READ|KEY_WOW64_64KEY, &hkey))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set the ProgramFiles variables */
|
||||||
|
|
||||||
|
if (get_reg_value(*env, hkey, progdirW, buf, sizeof(buf)))
|
||||||
|
{
|
||||||
|
if (is_win64 || is_wow64)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&nameW, progw6432W);
|
||||||
|
RtlInitUnicodeString(&valueW, buf);
|
||||||
|
RtlSetEnvironmentVariable(env, &nameW, &valueW);
|
||||||
|
}
|
||||||
|
if (is_win64 || !is_wow64)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&nameW, progfilesW);
|
||||||
|
RtlInitUnicodeString(&valueW, buf);
|
||||||
|
RtlSetEnvironmentVariable(env, &nameW, &valueW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_wow64 && get_reg_value(*env, hkey, progdir86W, buf, sizeof(buf)))
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&nameW, progfilesW);
|
||||||
|
RtlInitUnicodeString(&valueW, buf);
|
||||||
|
RtlSetEnvironmentVariable(env, &nameW, &valueW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the CommonProgramFiles variables */
|
||||||
|
|
||||||
|
if (get_reg_value(*env, hkey, commondirW, buf, sizeof(buf)))
|
||||||
|
{
|
||||||
|
if (is_win64 || is_wow64)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&nameW, commonw6432W);
|
||||||
|
RtlInitUnicodeString(&valueW, buf);
|
||||||
|
RtlSetEnvironmentVariable(env, &nameW, &valueW);
|
||||||
|
}
|
||||||
|
if (is_win64 || !is_wow64)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&nameW, commonfilesW);
|
||||||
|
RtlInitUnicodeString(&valueW, buf);
|
||||||
|
RtlSetEnvironmentVariable(env, &nameW, &valueW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_wow64 && get_reg_value(*env, hkey, commondir86W, buf, sizeof(buf)))
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&nameW, commonfilesW);
|
||||||
|
RtlInitUnicodeString(&valueW, buf);
|
||||||
|
RtlSetEnvironmentVariable(env, &nameW, &valueW);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WINAPI CreateEnvironmentBlock( LPVOID* lpEnvironment,
|
BOOL WINAPI CreateEnvironmentBlock( LPVOID* lpEnvironment,
|
||||||
HANDLE hToken, BOOL bInherit )
|
HANDLE hToken, BOOL bInherit )
|
||||||
{
|
{
|
||||||
NTSTATUS r;
|
static const WCHAR env_keyW[] = {'S','y','s','t','e','m','\\',
|
||||||
|
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
|
||||||
|
'C','o','n','t','r','o','l','\\',
|
||||||
|
'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
|
||||||
|
'E','n','v','i','r','o','n','m','e','n','t',0};
|
||||||
|
static const WCHAR profile_keyW[] = {'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s',' ','N','T','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'P','r','o','f','i','l','e','L','i','s','t',0};
|
||||||
|
static const WCHAR envW[] = {'E','n','v','i','r','o','n','m','e','n','t',0};
|
||||||
|
static const WCHAR volatile_envW[] = {'V','o','l','a','t','i','l','e',' ','E','n','v','i','r','o','n','m','e','n','t',0};
|
||||||
|
static const WCHAR ProfilesDirectoryW[] = {'P','r','o','f','i','l','e','s','D','i','r','e','c','t','o','r','y',0};
|
||||||
|
|
||||||
|
static const WCHAR SystemRootW[] = {'S','y','s','t','e','m','R','o','o','t',0};
|
||||||
|
static const WCHAR SystemDriveW[] = {'S','y','s','t','e','m','D','r','i','v','e',0};
|
||||||
|
static const WCHAR AllUsersProfileW[] = {'A','l','l','U','s','e','r','s','P','r','o','f','i','l','e',0};
|
||||||
|
static const WCHAR ALLUSERSPROFILEW[] = {'A','L','L','U','S','E','R','S','P','R','O','F','I','L','E',0};
|
||||||
|
static const WCHAR USERNAMEW[] = {'U','S','E','R','N','A','M','E',0};
|
||||||
|
static const WCHAR USERPROFILEW[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
|
||||||
|
static const WCHAR DefaultW[] = {'D','e','f','a','u','l','t',0};
|
||||||
|
static const WCHAR COMPUTERNAMEW[] = {'C','O','M','P','U','T','E','R','N','A','M','E',0};
|
||||||
|
|
||||||
|
WCHAR *env, buf[UNICODE_STRING_MAX_CHARS], profiles_dir[MAX_PATH];
|
||||||
|
UNICODE_STRING us_name, us_val;
|
||||||
|
DWORD len;
|
||||||
|
HKEY hkey, hsubkey;
|
||||||
|
|
||||||
TRACE("%p %p %d\n", lpEnvironment, hToken, bInherit );
|
TRACE("%p %p %d\n", lpEnvironment, hToken, bInherit );
|
||||||
|
|
||||||
if (!lpEnvironment)
|
if (!lpEnvironment)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
r = RtlCreateEnvironment(bInherit, (WCHAR **)lpEnvironment);
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, env_keyW, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||||
if (r == STATUS_SUCCESS)
|
return FALSE;
|
||||||
return TRUE;
|
|
||||||
return FALSE;
|
if (RtlCreateEnvironment(bInherit, &env) != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetEnvironmentVariableW(SystemRootW, buf, UNICODE_STRING_MAX_CHARS))
|
||||||
|
{
|
||||||
|
if (!get_reg_value(env, hkey, SystemRootW, buf, UNICODE_STRING_MAX_CHARS))
|
||||||
|
{
|
||||||
|
buf[0] = 0;
|
||||||
|
WARN("SystemRoot variable not set\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RtlInitUnicodeString(&us_name, SystemRootW);
|
||||||
|
RtlInitUnicodeString(&us_val, buf);
|
||||||
|
RtlSetEnvironmentVariable(&env, &us_name, &us_val);
|
||||||
|
|
||||||
|
if (!GetEnvironmentVariableW(SystemDriveW, buf, UNICODE_STRING_MAX_CHARS))
|
||||||
|
{
|
||||||
|
if (!get_reg_value(env, hkey, SystemRootW, buf, UNICODE_STRING_MAX_CHARS))
|
||||||
|
{
|
||||||
|
buf[0] = 0;
|
||||||
|
WARN("SystemDrive variable not set\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RtlInitUnicodeString(&us_name, SystemDriveW);
|
||||||
|
RtlInitUnicodeString(&us_val, buf);
|
||||||
|
RtlSetEnvironmentVariable(&env, &us_name, &us_val);
|
||||||
|
|
||||||
|
set_registry_variables(&env, hkey, REG_SZ, !bInherit);
|
||||||
|
set_registry_variables(&env, hkey, REG_EXPAND_SZ, !bInherit);
|
||||||
|
|
||||||
|
if (RegOpenKeyExW(hkey, envW, 0, KEY_READ, &hsubkey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
set_registry_variables(&env, hsubkey, REG_SZ, !bInherit);
|
||||||
|
set_registry_variables(&env, hsubkey, REG_EXPAND_SZ, !bInherit);
|
||||||
|
RegCloseKey(hsubkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RegOpenKeyExW(hkey, volatile_envW, 0, KEY_READ, &hsubkey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
set_registry_variables(&env, hsubkey, REG_SZ, !bInherit);
|
||||||
|
set_registry_variables(&env, hsubkey, REG_EXPAND_SZ, !bInherit);
|
||||||
|
RegCloseKey(hsubkey);
|
||||||
|
}
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
|
||||||
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, profile_keyW, 0, KEY_READ, &hkey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (get_reg_value(env, hkey, ProfilesDirectoryW, profiles_dir, MAX_PATH-sizeof(WCHAR)))
|
||||||
|
{
|
||||||
|
len = strlenW(profiles_dir);
|
||||||
|
if (profiles_dir[len-1] != '\\')
|
||||||
|
{
|
||||||
|
profiles_dir[len++] = '\\';
|
||||||
|
profiles_dir[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf, profiles_dir, len*sizeof(WCHAR));
|
||||||
|
if (get_reg_value(env, hkey, AllUsersProfileW, buf+len, UNICODE_STRING_MAX_CHARS-len))
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&us_name, ALLUSERSPROFILEW);
|
||||||
|
RtlInitUnicodeString(&us_val, buf);
|
||||||
|
RtlSetEnvironmentVariable(&env, &us_name, &us_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
profiles_dir[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = sizeof(buf)/sizeof(WCHAR);
|
||||||
|
if (GetComputerNameW(buf, &len))
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&us_name, COMPUTERNAMEW);
|
||||||
|
RtlInitUnicodeString(&us_val, buf);
|
||||||
|
RtlSetEnvironmentVariable(&env, &us_name, &us_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_wow64_environment(&env);
|
||||||
|
|
||||||
|
if (!hToken)
|
||||||
|
{
|
||||||
|
if (profiles_dir[0])
|
||||||
|
{
|
||||||
|
len = strlenW(profiles_dir);
|
||||||
|
if (len*sizeof(WCHAR)+sizeof(DefaultW) < sizeof(buf))
|
||||||
|
{
|
||||||
|
memcpy(buf, profiles_dir, len*sizeof(WCHAR));
|
||||||
|
memcpy(buf+len, DefaultW, sizeof(DefaultW));
|
||||||
|
RtlInitUnicodeString(&us_name, USERPROFILEW);
|
||||||
|
RtlInitUnicodeString(&us_val, buf);
|
||||||
|
RtlSetEnvironmentVariable(&env, &us_name, &us_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = '.';
|
||||||
|
memcpy(buf+1, DefaultW, sizeof(DefaultW));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TOKEN_USER *token_user = NULL;
|
||||||
|
SID_NAME_USE use;
|
||||||
|
WCHAR *sidW;
|
||||||
|
DWORD size, tmp=0;
|
||||||
|
|
||||||
|
if (GetTokenInformation(hToken, TokenUser, NULL, 0, &len) ||
|
||||||
|
GetLastError()!=ERROR_INSUFFICIENT_BUFFER ||
|
||||||
|
!(token_user = HeapAlloc(GetProcessHeap(), 0, len)) ||
|
||||||
|
!GetTokenInformation(hToken, TokenUser, token_user, len, &len) ||
|
||||||
|
!ConvertSidToStringSidW(token_user->User.Sid, &sidW))
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, token_user);
|
||||||
|
RtlDestroyEnvironment(env);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlenW(profiles_dir);
|
||||||
|
memcpy(buf, profiles_dir, len*sizeof(WCHAR));
|
||||||
|
|
||||||
|
size = UNICODE_STRING_MAX_CHARS-len;
|
||||||
|
if (LookupAccountSidW(NULL, token_user->User.Sid,
|
||||||
|
buf+len, &size, NULL, &tmp, &use))
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&us_name, USERNAMEW);
|
||||||
|
RtlInitUnicodeString(&us_val, buf+len);
|
||||||
|
RtlSetEnvironmentVariable(&env, &us_name, &us_val);
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&us_name, USERPROFILEW);
|
||||||
|
RtlInitUnicodeString(&us_val, buf);
|
||||||
|
RtlSetEnvironmentVariable(&env, &us_name, &us_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, token_user);
|
||||||
|
strcpyW(buf, sidW);
|
||||||
|
LocalFree(sidW);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RegOpenKeyExW(HKEY_USERS, buf, 0, KEY_READ, &hkey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (RegOpenKeyExW(hkey, envW, 0, KEY_READ, &hsubkey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
set_registry_variables(&env, hsubkey, REG_SZ, !bInherit);
|
||||||
|
set_registry_variables(&env, hsubkey, REG_EXPAND_SZ, !bInherit);
|
||||||
|
RegCloseKey(hsubkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RegOpenKeyExW(hkey, volatile_envW, 0, KEY_READ, &hsubkey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
set_registry_variables(&env, hsubkey, REG_SZ, !bInherit);
|
||||||
|
set_registry_variables(&env, hsubkey, REG_EXPAND_SZ, !bInherit);
|
||||||
|
RegCloseKey(hsubkey);
|
||||||
|
}
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
*lpEnvironment = env;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI DestroyEnvironmentBlock(LPVOID lpEnvironment)
|
BOOL WINAPI DestroyEnvironmentBlock(LPVOID lpEnvironment)
|
||||||
|
|
Loading…
Reference in New Issue