BOOL WINAPI CreateEnvironmentBlock(OUT LPVOID *lpEnvironment, IN HANDLE hToken, IN BOOL bInherit) { NTSTATUS Status; LONG lError; PWSTR* Environment = (PWSTR*)lpEnvironment; DWORD Length; DWORD dwType; HKEY hKey; HKEY hKeyUser; LPWSTR lpUserName = NULL; LPWSTR lpDomainName = NULL; WCHAR Buffer[MAX_PATH]; WCHAR szValue[1024]; DPRINT("CreateEnvironmentBlock() called\n"); if (lpEnvironment == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } Status = RtlCreateEnvironment((BOOLEAN)bInherit, Environment); if (!NT_SUCCESS(Status)) { DPRINT1("RtlCreateEnvironment() failed (Status %lx)\n", Status); SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } /* Set 'SystemRoot' variable */ Length = ARRAYSIZE(Buffer); if (GetEnvironmentVariableW(L"SystemRoot", Buffer, Length)) { SetUserEnvironmentVariable(Environment, L"SystemRoot", Buffer, FALSE); } /* Set 'SystemDrive' variable */ if (GetEnvironmentVariableW(L"SystemDrive", Buffer, Length)) { SetUserEnvironmentVariable(Environment, L"SystemDrive", Buffer, FALSE); } /* Set variables from Session Manager */ if (!SetSystemEnvironment(Environment)) { RtlDestroyEnvironment(*Environment); return FALSE; } /* Set 'COMPUTERNAME' variable */ Length = ARRAYSIZE(Buffer); if (GetComputerNameW(Buffer, &Length)) { SetUserEnvironmentVariable(Environment, L"COMPUTERNAME", Buffer, FALSE); } /* Set 'ALLUSERSPROFILE' variable */ Length = ARRAYSIZE(Buffer); if (GetAllUsersProfileDirectoryW(Buffer, &Length)) { SetUserEnvironmentVariable(Environment, L"ALLUSERSPROFILE", Buffer, FALSE); } /* Set 'USERPROFILE' variable to the default users profile */ Length = ARRAYSIZE(Buffer); if (GetDefaultUserProfileDirectoryW(Buffer, &Length)) { SetUserEnvironmentVariable(Environment, L"USERPROFILE", Buffer, TRUE); } lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, &hKey); if (lError == ERROR_SUCCESS) { Length = sizeof(szValue); lError = RegQueryValueExW(hKey, L"ProgramFilesDir", NULL, &dwType, (LPBYTE)szValue, &Length); if (lError == ERROR_SUCCESS) { SetUserEnvironmentVariable(Environment, L"ProgramFiles", szValue, FALSE); } Length = sizeof(szValue); lError = RegQueryValueExW(hKey, L"CommonFilesDir", NULL, &dwType, (LPBYTE)szValue, &Length); if (lError == ERROR_SUCCESS) { SetUserEnvironmentVariable(Environment, L"CommonProgramFiles", szValue, FALSE); } RegCloseKey(hKey); } /* * If no user token is specified, the system environment variables are set * and we stop here, otherwise continue setting the user-specific variables. */ if (hToken == NULL) return TRUE; hKeyUser = GetCurrentUserKey(hToken); if (hKeyUser == NULL) { DPRINT1("GetCurrentUserKey() failed\n"); RtlDestroyEnvironment(*Environment); return FALSE; } /* Set 'USERPROFILE' variable */ Length = ARRAYSIZE(Buffer); if (GetUserProfileDirectoryW(hToken, Buffer, &Length)) { DWORD MinLen = 2; SetUserEnvironmentVariable(Environment, L"USERPROFILE", Buffer, FALSE); // FIXME: Strangely enough the following two environment variables // are not set by userenv.dll in Windows... See r68284 / CORE-9875 // FIXME2: This is done by msgina.dll !! /* At least <drive letter>:<path> */ if (Length > MinLen) { /* Set 'HOMEDRIVE' variable */ StringCchCopyNW(szValue, ARRAYSIZE(Buffer), Buffer, MinLen); SetUserEnvironmentVariable(Environment, L"HOMEDRIVE", szValue, FALSE); /* Set 'HOMEPATH' variable */ StringCchCopyNW(szValue, ARRAYSIZE(Buffer), Buffer + MinLen, Length - MinLen); SetUserEnvironmentVariable(Environment, L"HOMEPATH", szValue, FALSE); } } else { DPRINT1("GetUserProfileDirectoryW failed with error %lu\n", GetLastError()); } if (GetUserAndDomainName(hToken, &lpUserName, &lpDomainName)) { /* Set 'USERNAME' variable */ SetUserEnvironmentVariable(Environment, L"USERNAME", lpUserName, FALSE); /* Set 'USERDOMAIN' variable */ SetUserEnvironmentVariable(Environment, L"USERDOMAIN", lpDomainName, FALSE); if (lpUserName != NULL) LocalFree(lpUserName); if (lpDomainName != NULL) LocalFree(lpDomainName); } /* Set user environment variables */ SetUserEnvironment(Environment, hKeyUser, L"Environment"); /* Set user volatile environment variables */ SetUserEnvironment(Environment, hKeyUser, L"Volatile Environment"); RegCloseKey(hKeyUser); return TRUE; }
BOOL NTAPI BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment, IN PANSI_STRING AnsiEnv, IN PUNICODE_STRING UnicodeEnv) { BOOL Result; ULONG RegionSize, EnvironmentSize = 0; PWCHAR p, Environment, NewEnvironment; NTSTATUS Status; /* Make sure we have both strings */ if (!(AnsiEnv) || !(UnicodeEnv)) { /* Fail */ SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } /* Check if an environment was passed in */ if (!lpEnvironment) { /* Nope, create one */ Status = RtlCreateEnvironment(TRUE, (PWCHAR*)&Environment); if (!NT_SUCCESS(Status)) goto Quickie; } else { /* Use the one we got */ Environment = lpEnvironment; } /* Do we have something now ? */ if (!Environment) { /* Still not, fail out */ SetLastError(ERROR_BAD_ENVIRONMENT); goto Quickie; } /* Count how much space the whole environment takes */ p = Environment; while ((*p++ != UNICODE_NULL) && (*p != UNICODE_NULL)) EnvironmentSize++; EnvironmentSize += sizeof(UNICODE_NULL); /* Allocate a new copy */ RegionSize = (EnvironmentSize + MAX_PATH) * sizeof(WCHAR); if (!NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&NewEnvironment, 0, &RegionSize, MEM_COMMIT, PAGE_READWRITE))) { /* We failed, bail out */ SetLastError(ERROR_NOT_ENOUGH_MEMORY); NewEnvironment = NULL; goto Quickie; } /* Begin parsing the new environment */ p = NewEnvironment; /* FIXME: Code here */ /* Terminate it */ *p++ = UNICODE_NULL; /* Initialize the unicode string to hold it */ EnvironmentSize = (p - NewEnvironment) * sizeof(WCHAR); RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment, EnvironmentSize); UnicodeEnv->Length = EnvironmentSize; /* Create the ASCII version of it */ Status = RtlUnicodeStringToAnsiString(AnsiEnv, UnicodeEnv, TRUE); if (!NT_SUCCESS(Status)) { /* Set last error if conversion failure */ BaseSetLastNTError(Status); } else { /* Everything went okay, so return success */ Result = TRUE; NewEnvironment = NULL; } Quickie: /* Cleanup path starts here, start by destroying the envrionment copy */ if (!(lpEnvironment) && (Environment)) RtlDestroyEnvironment(Environment); /* See if we are here due to failure */ if (NewEnvironment) { /* Initialize the paths to be empty */ RtlInitEmptyUnicodeString(UnicodeEnv, NULL, 0); RtlInitEmptyAnsiString(AnsiEnv, NULL, 0); /* Free the environment copy */ RegionSize = 0; Status = NtFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&NewEnvironment, &RegionSize, MEM_RELEASE); ASSERT(NT_SUCCESS(Status)); } /* Return the result */ return Result; }
BOOL WINAPI CreateEnvironmentBlock( LPVOID* lpEnvironment, HANDLE hToken, BOOL bInherit ) { 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 ); if (!lpEnvironment) return FALSE; if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, env_keyW, 0, KEY_READ, &hkey) != ERROR_SUCCESS) 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; }