/* * The way windows takes environment variables is different than what C does; * Windows wants a contiguous block of null-terminated strings, terminated * with an additional null. * * Windows has a few "essential" environment variables. winsock will fail * to initialize if SYSTEMROOT is not defined; some APIs make reference to * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that * these get defined if the input environment block does not contain any * values for them. */ WCHAR* make_program_env(char** env_block) { WCHAR* dst; WCHAR* ptr; char** env; int env_len = 1 * sizeof(WCHAR); /* room for closing null */ int len; int i; DWORD var_size; env_var_t required_vars[] = { E_V("SYSTEMROOT"), E_V("SYSTEMDRIVE"), E_V("TEMP"), }; for (env = env_block; *env; env++) { check_required_vars_contains_var(required_vars, ARRAY_SIZE(required_vars), *env); env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(WCHAR)); } for (i = 0; i < ARRAY_SIZE(required_vars); ++i) { if (!required_vars[i].supplied) { env_len += required_vars[i].len * sizeof(WCHAR); var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0); if (var_size == 0) { uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); } required_vars[i].value_len = (int)var_size; env_len += (int)var_size * sizeof(WCHAR); } } dst = malloc(env_len); if (!dst) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } ptr = dst; for (env = env_block; *env; env++, ptr += len) { len = uv_utf8_to_utf16(*env, ptr, (size_t)(env_len - (ptr - dst))); if (!len) { free(dst); return NULL; } } for (i = 0; i < ARRAY_SIZE(required_vars); ++i) { if (!required_vars[i].supplied) { wcscpy(ptr, required_vars[i].wide); ptr += required_vars[i].len - 1; *ptr++ = L'='; var_size = GetEnvironmentVariableW(required_vars[i].wide, ptr, required_vars[i].value_len); if (var_size == 0) { uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); } ptr += required_vars[i].value_len; } } *ptr = L'\0'; return dst; }
/* * The way windows takes environment variables is different than what C does; * Windows wants a contiguous block of null-terminated strings, terminated * with an additional null. * * Windows has a few "essential" environment variables. winsock will fail * to initialize if SYSTEMROOT is not defined; some APIs make reference to * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that * these get defined if the input environment block does not contain any * values for them. */ uv_err_t make_program_env(char* env_block[], WCHAR** dst_ptr) { WCHAR* dst; WCHAR* ptr; char** env; size_t env_len = 1; /* room for closing null */ int len; int i; DWORD var_size; env_var_t required_vars[] = {E_V("SYSTEMROOT"), E_V("SYSTEMDRIVE"), E_V("TEMP"), }; for (env = env_block; *env; env++) { int len; check_required_vars_contains_var(required_vars, ARRAY_SIZE(required_vars), *env); len = MultiByteToWideChar(CP_UTF8, 0, *env, -1, NULL, 0); if (len <= 0) { return uv__new_sys_error(GetLastError()); } env_len += len; } for (i = 0; i < ARRAY_SIZE(required_vars); ++i) { if (!required_vars[i].supplied) { env_len += required_vars[i].len; var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0); if (var_size == 0) { return uv__new_sys_error(GetLastError()); } required_vars[i].value_len = var_size; env_len += var_size; } } dst = malloc(env_len * sizeof(WCHAR)); if (!dst) { return uv__new_artificial_error(UV_ENOMEM); } ptr = dst; for (env = env_block; *env; env++, ptr += len) { len = MultiByteToWideChar(CP_UTF8, 0, *env, -1, ptr, (int)(env_len - (ptr - dst))); if (len <= 0) { JX_FREE(process, dst); return uv__new_sys_error(GetLastError()); } } for (i = 0; i < ARRAY_SIZE(required_vars); ++i) { if (!required_vars[i].supplied) { wcscpy(ptr, required_vars[i].wide); ptr += required_vars[i].len - 1; *ptr++ = L'='; var_size = GetEnvironmentVariableW(required_vars[i].wide, ptr, required_vars[i].value_len); if (var_size == 0) { uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); } ptr += required_vars[i].value_len; } } /* Terminate with an extra NULL. */ *ptr = L'\0'; *dst_ptr = dst; return uv_ok_; }