Esempio n. 1
0
File: process.c Progetto: Ankso/node
/*
 * 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;
}
Esempio n. 2
0
/*
 * 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_;
}