From aa85b2cdbbcda3bfd0455793d67ea2c938725c6c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 25 Mar 2024 12:57:00 -0700 Subject: [PATCH] correctly pass unicode environments to launched child processes; also treat unicode command line arguments correctly --- src/demon/win32/demon_core_win32.c | 5 ++-- src/os/core/win32/os_core_win32.c | 38 +++++++++++++++--------------- src/raddbg/raddbg_main.cpp | 12 +++++++++- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 297ddd7c..cb9ee117 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1087,7 +1087,7 @@ dmn_init(void) // rjf: setup environment variables { - CHAR *this_proc_env = GetEnvironmentStrings(); + WCHAR *this_proc_env = GetEnvironmentStringsW(); U64 start_idx = 0; for(U64 idx = 0;; idx += 1) { @@ -1099,7 +1099,8 @@ dmn_init(void) } else { - String8 string = str8((U8 *)this_proc_env + start_idx, idx - start_idx); + String16 string16 = str16((U16 *)this_proc_env + start_idx, idx - start_idx); + String8 string = str8_from_16(dmn_w32_shared->arena, string16); str8_list_push(dmn_w32_shared->arena, &dmn_w32_shared->env_strings, string); start_idx = idx+1; } diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index 32e6b094..87f2f154 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -217,7 +217,7 @@ os_init(void) // rjf: setup environment variables { - CHAR *this_proc_env = GetEnvironmentStrings(); + WCHAR *this_proc_env = GetEnvironmentStringsW(); U64 start_idx = 0; for(U64 idx = 0;; idx += 1) { @@ -229,7 +229,8 @@ os_init(void) } else { - String8 string = str8((U8 *)this_proc_env + start_idx, idx - start_idx); + String16 string16 = str16((U16 *)this_proc_env + start_idx, idx - start_idx); + String8 string = str8_from_16(w32_perm_arena, string16); str8_list_push(w32_perm_arena, &w32_environment, string); start_idx = idx+1; } @@ -1223,7 +1224,7 @@ os_launch_process(OS_LaunchOptions *options, OS_Handle *handle_out){ env16 = str16_from_8(scratch.arena, env); } - DWORD creation_flags = 0; + DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT; if(options->consoleless) { creation_flags |= CREATE_NO_WINDOW; @@ -1760,36 +1761,35 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs) #undef OS_WINDOWS // shlwapi uses its own OS_WINDOWS include inside #define OS_WINDOWS 1 -#if BUILD_CONSOLE_INTERFACE -int main(int argc, char **argv) +internal void +w32_entry_point_caller(int argc, WCHAR **wargv) { SetUnhandledExceptionFilter(&win32_exception_filter); + Arena *args_arena = arena_alloc__sized(MB(1), KB(32)); + char **argv = push_array(args_arena, char *, argc); for(int i = 0; i < argc; i += 1) { - String8 arg8 = str8_cstring(argv[i]); + String16 arg16 = str16_cstring((U16 *)wargv[i]); + String8 arg8 = str8_from_16(args_arena, arg16); if(str8_match(arg8, str8_lit("--quiet"), StringMatchFlag_CaseInsensitive)) { win32_g_is_quiet = 1; } + argv[i] = (char *)arg8.str; } main_thread_base_entry_point(entry_point, argv, (U64)argc); +} + +#if BUILD_CONSOLE_INTERFACE +int wmain(int argc, WCHAR **argv) +{ + w32_entry_point_caller(argc, argv); return 0; } #else -int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) { - SetUnhandledExceptionFilter(&win32_exception_filter); - char **argv = __argv; - int argc = __argc; - for(int i = 0; i < argc; i += 1) - { - String8 arg8 = str8_cstring(argv[i]); - if(str8_match(arg8, str8_lit("--quiet"), StringMatchFlag_CaseInsensitive)) - { - win32_g_is_quiet = 1; - } - } - main_thread_base_entry_point(entry_point, argv, (U64)argc); + w32_entry_point_caller(__argc, __wargv); return 0; } #endif diff --git a/src/raddbg/raddbg_main.cpp b/src/raddbg/raddbg_main.cpp index 888aea56..cac25614 100644 --- a/src/raddbg/raddbg_main.cpp +++ b/src/raddbg/raddbg_main.cpp @@ -205,11 +205,21 @@ entry_point(CmdLine *cmd_line) str8_list_push(scratch.arena, &passthrough_args_list, n->string); } + // rjf: get current path + String8 current_path = os_string_from_system_path(scratch.arena, OS_SystemPath_Current); + // rjf: equip exe if(args.first->string.size != 0) { + String8 exe_name = args.first->string; DF_Entity *exe = df_entity_alloc(0, target, DF_EntityKind_Executable); - df_entity_equip_name(0, exe, args.first->string); + PathStyle style = path_style_from_str8(exe_name); + if(style == PathStyle_Relative) + { + exe_name = push_str8f(scratch.arena, "%S/%S", current_path, exe_name); + exe_name = path_normalized_from_string(scratch.arena, exe_name); + } + df_entity_equip_name(0, exe, exe_name); } // rjf: equip path