Index: runtime/bin/process_win.cc |
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc |
index 624b1f2f44f6046f3b08dd41545c1047d21d5ccc..a09692bb11cfe153b495891960866291876b8927 100644 |
--- a/runtime/bin/process_win.cc |
+++ b/runtime/bin/process_win.cc |
@@ -391,7 +391,7 @@ int Process::Start(const char* path, |
} |
// Setup info structures. |
- STARTUPINFOEX startup_info; |
+ STARTUPINFOEXW startup_info; |
ZeroMemory(&startup_info, sizeof(startup_info)); |
startup_info.StartupInfo.cb = sizeof(startup_info); |
startup_info.StartupInfo.hStdInput = stdin_handles[kReadHandle]; |
@@ -446,15 +446,16 @@ int Process::Start(const char* path, |
ZeroMemory(&process_info, sizeof(process_info)); |
// Transform input strings to system format. |
- path = StringUtils::Utf8ToConsoleString(path); |
+ const wchar_t* system_path = StringUtils::Utf8ToWide(path); |
+ wchar_t** system_arguments = new wchar_t*[arguments_length]; |
for (int i = 0; i < arguments_length; i++) { |
- arguments[i] = StringUtils::Utf8ToConsoleString(arguments[i]); |
+ system_arguments[i] = StringUtils::Utf8ToWide(arguments[i]); |
} |
// Compute command-line length. |
- int command_line_length = strlen(path); |
+ int command_line_length = wcslen(system_path); |
for (int i = 0; i < arguments_length; i++) { |
- command_line_length += strlen(arguments[i]); |
+ command_line_length += wcslen(system_arguments[i]); |
} |
// Account for null termination and one space per argument. |
command_line_length += arguments_length + 1; |
@@ -463,52 +464,56 @@ int Process::Start(const char* path, |
int error_code = SetOsErrorMessage(os_error_message); |
CloseProcessPipes( |
stdin_handles, stdout_handles, stderr_handles, exit_handles); |
- free(const_cast<char*>(path)); |
- for (int i = 0; i < arguments_length; i++) free(arguments[i]); |
+ free(const_cast<wchar_t*>(system_path)); |
+ for (int i = 0; i < arguments_length; i++) free(system_arguments[i]); |
+ delete[] system_arguments; |
DeleteProcThreadAttributeList(attribute_list); |
free(attribute_list); |
return error_code; |
} |
// Put together command-line string. |
- char* command_line = new char[command_line_length]; |
+ wchar_t* command_line = new wchar_t[command_line_length]; |
int len = 0; |
int remaining = command_line_length; |
- int written = snprintf(command_line + len, remaining, "%s", path); |
+ int written = _snwprintf(command_line + len, remaining, L"%s", system_path); |
len += written; |
remaining -= written; |
ASSERT(remaining >= 0); |
for (int i = 0; i < arguments_length; i++) { |
- written = snprintf(command_line + len, remaining, " %s", arguments[i]); |
+ written = |
+ _snwprintf(command_line + len, remaining, L" %s", system_arguments[i]); |
len += written; |
remaining -= written; |
ASSERT(remaining >= 0); |
} |
- free(const_cast<char*>(path)); |
- for (int i = 0; i < arguments_length; i++) free(arguments[i]); |
+ free(const_cast<wchar_t*>(system_path)); |
+ for (int i = 0; i < arguments_length; i++) free(system_arguments[i]); |
+ delete[] system_arguments; |
// Create environment block if an environment is supplied. |
- char* environment_block = NULL; |
+ wchar_t* environment_block = NULL; |
if (environment != NULL) { |
+ wchar_t** system_environment = new wchar_t*[environment_length]; |
// Convert environment strings to system strings. |
for (intptr_t i = 0; i < environment_length; i++) { |
- environment[i] = StringUtils::Utf8ToConsoleString(environment[i]); |
+ system_environment[i] = StringUtils::Utf8ToWide(environment[i]); |
} |
// An environment block is a sequence of zero-terminated strings |
// followed by a block-terminating zero char. |
intptr_t block_size = 1; |
for (intptr_t i = 0; i < environment_length; i++) { |
- block_size += strlen(environment[i]) + 1; |
+ block_size += wcslen(system_environment[i]) + 1; |
} |
- environment_block = new char[block_size]; |
+ environment_block = new wchar_t[block_size]; |
intptr_t block_index = 0; |
for (intptr_t i = 0; i < environment_length; i++) { |
- intptr_t len = strlen(environment[i]); |
- intptr_t result = snprintf(environment_block + block_index, |
- len, |
- "%s", |
- environment[i]); |
+ intptr_t len = wcslen(system_environment[i]); |
+ intptr_t result = _snwprintf(environment_block + block_index, |
+ len, |
+ L"%s", |
+ system_environment[i]); |
ASSERT(result == len); |
block_index += len; |
environment_block[block_index++] = '\0'; |
@@ -516,30 +521,36 @@ int Process::Start(const char* path, |
// Block-terminating zero char. |
environment_block[block_index++] = '\0'; |
ASSERT(block_index == block_size); |
- for (intptr_t i = 0; i < environment_length; i++) free(environment[i]); |
+ for (intptr_t i = 0; i < environment_length; i++) { |
+ free(system_environment[i]); |
+ } |
+ delete[] system_environment; |
} |
+ const wchar_t* system_working_directory = NULL; |
if (working_directory != NULL) { |
- working_directory = StringUtils::Utf8ToConsoleString(working_directory); |
+ system_working_directory = StringUtils::Utf8ToWide(working_directory); |
} |
// Create process. |
- BOOL result = CreateProcess(NULL, // ApplicationName |
- command_line, |
- NULL, // ProcessAttributes |
- NULL, // ThreadAttributes |
- TRUE, // InheritHandles |
- EXTENDED_STARTUPINFO_PRESENT, |
- environment_block, |
- working_directory, |
- reinterpret_cast<STARTUPINFO*>(&startup_info), |
- &process_info); |
+ DWORD creation_flags = |
+ EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT; |
+ BOOL result = CreateProcessW(NULL, // ApplicationName |
+ command_line, |
+ NULL, // ProcessAttributes |
+ NULL, // ThreadAttributes |
+ TRUE, // InheritHandles |
+ creation_flags, |
+ environment_block, |
+ system_working_directory, |
+ reinterpret_cast<STARTUPINFOW*>(&startup_info), |
+ &process_info); |
// Deallocate command-line and environment block strings. |
delete[] command_line; |
delete[] environment_block; |
- if (working_directory != NULL) { |
- free(const_cast<char*>(working_directory)); |
+ if (system_working_directory != NULL) { |
+ free(const_cast<wchar_t*>(system_working_directory)); |
} |
DeleteProcThreadAttributeList(attribute_list); |