Use wide version of Windows APIs (#1531)
* Use wide version of Windows APIs in subprocess functions * Use `wmain` on Windows to get UTF16 arguments * Use wide version of APIs in `rz_cons` * Always try to set console codepage to UTF8 Co-authored-by: Riccardo Schirone <ret2libc@users.noreply.github.com>
This commit is contained in:
parent
4972af951f
commit
d7e7bae79e
21 changed files with 193 additions and 93 deletions
|
|
@ -4,13 +4,15 @@
|
|||
#include <rz_main.h>
|
||||
#include <rz_util.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int rc = 1;
|
||||
const char *prog_name = rz_file_basename(argv[0]);
|
||||
const char *prog_name = rz_file_basename(utf8_argv[0]);
|
||||
RzMain *m = rz_main_new(prog_name);
|
||||
if (m) {
|
||||
rc = rz_main_run(m, argc, argv);
|
||||
rc = rz_main_run(m, argc, (const char **)utf8_argv);
|
||||
rz_main_free(m);
|
||||
}
|
||||
UTF8_ARGV_FREE(argc, utf8_argv);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,14 @@ static int rz_main_rzpipe(int argc, const char **argv) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
if (argc > 0 && strstr(argv[0], "rzp")) {
|
||||
return rz_main_rzpipe(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret;
|
||||
if (argc > 0 && strstr(utf8_argv[0], "rzp")) {
|
||||
ret = rz_main_rzpipe(argc, (const char **)utf8_argv);
|
||||
} else {
|
||||
ret = rz_main_rizin(argc, (const char **)utf8_argv);
|
||||
}
|
||||
return rz_main_rizin(argc, argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
return rz_main_rz_agent(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_agent(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
return rz_main_rz_asm(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_asm(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
return rz_main_rz_ax(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_ax(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
return rz_main_rz_bin(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_bin(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
return rz_main_rz_diff(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_diff(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
return rz_main_rz_find(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_find(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
return rz_main_rz_gg(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_gg(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
return rz_main_rz_hash(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_hash(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
return rz_main_rz_run(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_run(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_main.h>
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
return rz_main_rz_sign(argc, argv);
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_main_rz_sign(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "rz_test.h"
|
||||
#include <assert.h>
|
||||
#include <rz_cons.h>
|
||||
#include <rz_main.h>
|
||||
|
||||
#define Color_INSERT Color_BGREEN
|
||||
#define Color_DELETE Color_BRED
|
||||
|
|
@ -169,7 +170,7 @@ static bool rz_test_chdir_fromtest(const char *test_path) {
|
|||
return found;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int rz_test_main(int argc, const char **argv) {
|
||||
int workers_count = WORKERS_DEFAULT;
|
||||
bool verbose = false;
|
||||
bool nothing = false;
|
||||
|
|
@ -1082,3 +1083,10 @@ static void interact_commands(RzTestResultInfo *result, RzPVector *fixup_results
|
|||
free(name);
|
||||
free(newcmds);
|
||||
}
|
||||
|
||||
int MAIN_NAME(int argc, const ARGV_TYPE **argv) {
|
||||
char **utf8_argv = ARGV_TYPE_TO_UTF8(argc, argv);
|
||||
int ret = rz_test_main(argc, (const char **)utf8_argv);
|
||||
FREE_UTF8_ARGV(argc, utf8_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -528,6 +528,30 @@ RZ_API bool rz_cons_enable_mouse(const bool enable) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if __WINDOWS__
|
||||
static void set_console_codepage_to_utf8(void) {
|
||||
if (IsValidCodePage(CP_UTF8)) {
|
||||
if (!SetConsoleOutputCP(CP_UTF8)) {
|
||||
rz_sys_perror("SetConsoleCP");
|
||||
}
|
||||
if (!SetConsoleCP(CP_UTF8)) {
|
||||
rz_sys_perror("SetConsoleCP");
|
||||
}
|
||||
} else {
|
||||
RZ_LOG_INFO("UTF-8 Codepage not installed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void restore_console_codepage(void) {
|
||||
if (!SetConsoleCP(I.old_cp)) {
|
||||
rz_sys_perror("SetConsoleCP");
|
||||
}
|
||||
if (!SetConsoleOutputCP(I.old_ocp)) {
|
||||
rz_sys_perror("SetConsoleOutputCP");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Stub function that cb_main_output gets pointed to in util/log.c by rz_cons_new
|
||||
// This allows Cutter to set per-task logging redirection
|
||||
RZ_API RzCons *rz_cons_new(void) {
|
||||
|
|
@ -563,8 +587,10 @@ RZ_API RzCons *rz_cons_new(void) {
|
|||
I.num = NULL;
|
||||
I.null = 0;
|
||||
#if __WINDOWS__
|
||||
I.old_cp = GetConsoleOutputCP();
|
||||
I.old_cp = GetConsoleCP();
|
||||
I.old_ocp = GetConsoleOutputCP();
|
||||
I.vtmode = rz_cons_is_vtcompat();
|
||||
set_console_codepage_to_utf8();
|
||||
#else
|
||||
I.vtmode = 2;
|
||||
#endif
|
||||
|
|
@ -601,11 +627,7 @@ RZ_API RzCons *rz_cons_new(void) {
|
|||
RZ_API RzCons *rz_cons_free(void) {
|
||||
#if __WINDOWS__
|
||||
rz_cons_enable_mouse(false);
|
||||
if (I.old_cp) {
|
||||
(void)SetConsoleOutputCP(I.old_cp);
|
||||
// chcp doesn't pick up the code page switch for some reason
|
||||
(void)rz_sys_cmdf("chcp %u > NUL", I.old_cp);
|
||||
}
|
||||
restore_console_codepage();
|
||||
#endif
|
||||
I.refcnt--;
|
||||
if (I.refcnt != 0) {
|
||||
|
|
@ -1600,30 +1622,6 @@ RZ_API void rz_cons_set_raw(bool is_raw) {
|
|||
|
||||
RZ_API void rz_cons_set_utf8(bool b) {
|
||||
I.use_utf8 = b;
|
||||
#if __WINDOWS__
|
||||
if (b) {
|
||||
if (IsValidCodePage(CP_UTF8)) {
|
||||
if (!SetConsoleOutputCP(CP_UTF8)) {
|
||||
rz_sys_perror("rz_cons_set_utf8");
|
||||
}
|
||||
#if UNICODE
|
||||
UINT inCP = CP_UTF8;
|
||||
#else
|
||||
UINT inCP = GetACP();
|
||||
#endif
|
||||
if (!SetConsoleCP(inCP)) {
|
||||
rz_sys_perror("rz_cons_set_utf8");
|
||||
}
|
||||
} else {
|
||||
RZ_LOG_WARN("UTF-8 Codepage not installed.\n");
|
||||
}
|
||||
} else {
|
||||
UINT acp = GetACP();
|
||||
if (!SetConsoleCP(acp) || !SetConsoleOutputCP(acp)) {
|
||||
rz_sys_perror("rz_cons_set_utf8");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RZ_API void rz_cons_invert(int set, int color) {
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ do_it_again:
|
|||
if (rz_cons_singleton()->term_xterm) {
|
||||
ret = ReadFile(h, buf, 1, &out, NULL);
|
||||
} else {
|
||||
ret = ReadConsoleInput(h, &irInBuf, 1, &out);
|
||||
ret = ReadConsoleInputW(h, &irInBuf, 1, &out);
|
||||
}
|
||||
rz_cons_sleep_end(bed);
|
||||
if (ret < 1) {
|
||||
|
|
@ -252,7 +252,7 @@ do_it_again:
|
|||
if (irInBuf.EventType == KEY_EVENT) {
|
||||
if (irInBuf.Event.KeyEvent.bKeyDown) {
|
||||
if (irInBuf.Event.KeyEvent.uChar.UnicodeChar) {
|
||||
char *tmp = rz_sys_conv_win_to_utf8_l((PTCHAR)&irInBuf.Event.KeyEvent.uChar, 1);
|
||||
char *tmp = rz_utf16_to_utf8_l(&irInBuf.Event.KeyEvent.uChar.UnicodeChar, 1);
|
||||
if (!tmp) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1531,15 +1531,11 @@ RZ_API const char *rz_line_readline_cb(RzLineReadCallback cb, void *user) {
|
|||
HANDLE hClipBoard;
|
||||
PTCHAR clipText;
|
||||
if (OpenClipboard(NULL)) {
|
||||
#if UNICODE
|
||||
hClipBoard = GetClipboardData(CF_UNICODETEXT);
|
||||
#else
|
||||
hClipBoard = GetClipboardData(CF_TEXT);
|
||||
#endif
|
||||
if (hClipBoard) {
|
||||
clipText = GlobalLock(hClipBoard);
|
||||
if (clipText) {
|
||||
char *txt = rz_sys_conv_win_to_utf8(clipText);
|
||||
char *txt = rz_utf16_to_utf8(clipText);
|
||||
if (!txt) {
|
||||
RZ_LOG_ERROR("Failed to allocate memory\n");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -462,7 +462,7 @@ static int __cons_readchar_w32(ut32 usec) {
|
|||
return ch;
|
||||
}
|
||||
} else {
|
||||
ret = ReadConsoleInput(h, &irInBuf, 1, &out);
|
||||
ret = ReadConsoleInputW(h, &irInBuf, 1, &out);
|
||||
}
|
||||
rz_cons_sleep_end(bed);
|
||||
if (ret) {
|
||||
|
|
@ -504,9 +504,15 @@ static int __cons_readchar_w32(ut32 usec) {
|
|||
|
||||
if (irInBuf.EventType == KEY_EVENT) {
|
||||
if (irInBuf.Event.KeyEvent.bKeyDown) {
|
||||
ch = irInBuf.Event.KeyEvent.uChar.AsciiChar;
|
||||
bCtrl = irInBuf.Event.KeyEvent.dwControlKeyState & 8;
|
||||
if (irInBuf.Event.KeyEvent.uChar.AsciiChar == 0) {
|
||||
if (irInBuf.Event.KeyEvent.uChar.UnicodeChar) {
|
||||
char *tmp = rz_utf16_to_utf8_l(&irInBuf.Event.KeyEvent.uChar.UnicodeChar, 1);
|
||||
if (tmp) {
|
||||
int len = strlen(tmp);
|
||||
memcpy(&ch, tmp, R_MIN(len, sizeof(ch)));
|
||||
free(tmp);
|
||||
}
|
||||
} else {
|
||||
switch (irInBuf.Event.KeyEvent.wVirtualKeyCode) {
|
||||
case VK_DOWN: // key down
|
||||
case VK_RIGHT: // key right
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ extern "C" {
|
|||
#include <rz_util/rz_str.h>
|
||||
#include <rz_util/rz_str_constpool.h>
|
||||
#include <rz_util/rz_sys.h>
|
||||
#include <rz_util/rz_utf8.h>
|
||||
#include <rz_util/rz_file.h>
|
||||
#include <rz_vector.h>
|
||||
#include <sdb.h>
|
||||
|
|
@ -520,6 +521,7 @@ typedef struct rz_cons_t {
|
|||
#elif __WINDOWS__
|
||||
DWORD term_raw, term_buf, term_xterm;
|
||||
UINT old_cp;
|
||||
UINT old_ocp;
|
||||
#endif
|
||||
RNum *num;
|
||||
/* Pager (like more or less) to use if the output doesn't fit on the
|
||||
|
|
|
|||
|
|
@ -15,6 +15,18 @@ typedef struct rz_main_t {
|
|||
// stdin/stdout
|
||||
} RzMain;
|
||||
|
||||
#if __WINDOWS__
|
||||
#define MAIN_NAME wmain
|
||||
#define ARGV_TYPE wchar_t
|
||||
#define ARGV_TYPE_TO_UTF8(argc, argv) rz_sys_utf8_argv_new(argc, argv)
|
||||
#define FREE_UTF8_ARGV(argc, utf8_argv) rz_sys_utf8_argv_free(argc, utf8_argv)
|
||||
#else
|
||||
#define MAIN_NAME main
|
||||
#define ARGV_TYPE char
|
||||
#define ARGV_TYPE_TO_UTF8(argc, argv) (char **)argv
|
||||
#define FREE_UTF8_ARGV(argc, utf8_argv)
|
||||
#endif
|
||||
|
||||
typedef int (*RzMainCallback)(int argc, const char **argv);
|
||||
|
||||
RZ_API RzMain *rz_main_new(const char *name);
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ RZ_API int rz_sys_cmd_str_full(const char *cmd, const char *input, char **output
|
|||
RZ_API char *rz_sys_get_src_dir_w32(void);
|
||||
RZ_API bool rz_sys_cmd_str_full_w32(const char *cmd, const char *input, char **output, int *outlen, char **sterr);
|
||||
RZ_API bool rz_sys_create_child_proc_w32(const char *cmdline, HANDLE in, HANDLE out, HANDLE err);
|
||||
RZ_API char **rz_sys_utf8_argv_new(int argc, const wchar_t **argv);
|
||||
RZ_API void rz_sys_utf8_argv_free(int argc, char **utf8_argv);
|
||||
#endif
|
||||
RZ_API int rz_sys_open_perms(int rizin_perms);
|
||||
RZ_API int rz_sys_open(const char *path, int perm, int mode);
|
||||
|
|
|
|||
|
|
@ -25,19 +25,19 @@ static bool create_pipe_overlap(HANDLE *pipe_read, HANDLE *pipe_write, LPSECURIT
|
|||
if (!sz) {
|
||||
sz = 4096;
|
||||
}
|
||||
char name[MAX_PATH];
|
||||
snprintf(name, sizeof(name), "\\\\.\\pipe\\rz-pipe-subproc.%d.%ld", (int)GetCurrentProcessId(), (long)InterlockedIncrement(&pipe_id));
|
||||
*pipe_read = CreateNamedPipeA(name, PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, sz, sz, 120 * 1000, attrs);
|
||||
WCHAR name[MAX_PATH];
|
||||
_snwprintf_s(name, _countof(name), sizeof(name), L"\\\\.\\pipe\\rz-pipe-subproc.%d.%ld", (int)GetCurrentProcessId(), (long)InterlockedIncrement(&pipe_id));
|
||||
*pipe_read = CreateNamedPipeW(name, PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, sz, sz, 120 * 1000, attrs);
|
||||
if (!*pipe_read) {
|
||||
return FALSE;
|
||||
}
|
||||
*pipe_write = CreateFileA(name, GENERIC_WRITE, 0, attrs, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | write_mode, NULL);
|
||||
*pipe_write = CreateFileW(name, GENERIC_WRITE, 0, attrs, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | write_mode, NULL);
|
||||
if (*pipe_write == INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(*pipe_read);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SetEnvironmentVariable(TEXT("RZ_PIPE_PATH"), name);
|
||||
SetEnvironmentVariableW(L"RZ_PIPE_PATH", name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ RZ_API bool rz_subprocess_init(void) {
|
|||
return true;
|
||||
}
|
||||
RZ_API void rz_subprocess_fini(void) {
|
||||
SetEnvironmentVariable(TEXT("RZ_PIPE_PATH"), NULL);
|
||||
SetEnvironmentVariableW(L"RZ_PIPE_PATH", NULL);
|
||||
}
|
||||
|
||||
// Create an env block that inherits the current vars but overrides the given ones
|
||||
|
|
@ -141,18 +141,31 @@ RZ_API RzSubprocess *rz_subprocess_start_opt(RzSubprocessOpt *opt) {
|
|||
HANDLE stdin_read = GetStdHandle(STD_INPUT_HANDLE);
|
||||
HANDLE stdout_write = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
HANDLE stderr_write = GetStdHandle(STD_ERROR_HANDLE);
|
||||
LPSTR lpFilePart;
|
||||
char cmd_exe[MAX_PATH];
|
||||
LPWSTR lpFilePart;
|
||||
WCHAR cmd_exe[MAX_PATH];
|
||||
|
||||
if (!rz_file_exists(opt->file) && NeedCurrentDirectoryForExePathA(opt->file)) {
|
||||
PWCHAR file = rz_utf8_to_utf16(opt->file);
|
||||
if (!file) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!rz_file_exists(opt->file) && NeedCurrentDirectoryForExePathW(file)) {
|
||||
DWORD len;
|
||||
if ((len = SearchPath(NULL, opt->file, ".exe", sizeof(cmd_exe), cmd_exe, &lpFilePart)) < 1) {
|
||||
if ((len = SearchPathW(NULL, file, L".exe", _countof(cmd_exe), cmd_exe, &lpFilePart)) < 1) {
|
||||
RZ_LOG_DEBUG("SearchPath failed for %s\n", opt->file);
|
||||
free(file);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
snprintf(cmd_exe, sizeof(cmd_exe), "%s", opt->file);
|
||||
WCHAR *tmp = rz_utf8_to_utf16(opt->file);
|
||||
if (!tmp) {
|
||||
free(file);
|
||||
return NULL;
|
||||
}
|
||||
_snwprintf_s(cmd_exe, _countof(cmd_exe), sizeof(cmd_exe), L"%s", tmp);
|
||||
free(tmp);
|
||||
}
|
||||
free(file);
|
||||
|
||||
char **argv = calloc(opt->args_size + 1, sizeof(char *));
|
||||
if (!argv) {
|
||||
|
|
@ -162,11 +175,23 @@ RZ_API RzSubprocess *rz_subprocess_start_opt(RzSubprocessOpt *opt) {
|
|||
if (opt->args_size) {
|
||||
memcpy(argv + 1, opt->args, sizeof(char *) * opt->args_size);
|
||||
}
|
||||
char *cmdline = rz_str_format_msvc_argv(opt->args_size + 1, argv);
|
||||
char *cmd = rz_str_format_msvc_argv(opt->args_size + 1, argv);
|
||||
free(argv);
|
||||
if (!cmdline) {
|
||||
if (!cmd) {
|
||||
return NULL;
|
||||
}
|
||||
PWCHAR cmdline = rz_utf8_to_utf16(cmd);
|
||||
if (!cmdline) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
{
|
||||
char *log_executable = rz_utf16_to_utf8(cmd_exe);
|
||||
if (log_executable) {
|
||||
RZ_LOG_DEBUG("%s%s\n", log_executable, cmd);
|
||||
free(log_executable);
|
||||
}
|
||||
}
|
||||
|
||||
proc = RZ_NEW0(RzSubprocess);
|
||||
if (!proc) {
|
||||
|
|
@ -215,7 +240,7 @@ RZ_API RzSubprocess *rz_subprocess_start_opt(RzSubprocessOpt *opt) {
|
|||
}
|
||||
|
||||
PROCESS_INFORMATION proc_info = { 0 };
|
||||
STARTUPINFOA start_info = { 0 };
|
||||
STARTUPINFOW start_info = { 0 };
|
||||
start_info.cb = sizeof(start_info);
|
||||
start_info.hStdError = stderr_write;
|
||||
start_info.hStdOutput = stdout_write;
|
||||
|
|
@ -223,8 +248,7 @@ RZ_API RzSubprocess *rz_subprocess_start_opt(RzSubprocessOpt *opt) {
|
|||
start_info.dwFlags = STARTF_USESTDHANDLES;
|
||||
|
||||
LPWSTR env = override_env(opt->envvars, opt->envvals, opt->env_size);
|
||||
RZ_LOG_DEBUG("%s%s\n", cmd_exe, cmdline);
|
||||
if (!CreateProcessA(
|
||||
if (!CreateProcessW(
|
||||
cmd_exe, // exe
|
||||
cmdline, // command line
|
||||
NULL, // process security attributes
|
||||
|
|
@ -236,12 +260,7 @@ RZ_API RzSubprocess *rz_subprocess_start_opt(RzSubprocessOpt *opt) {
|
|||
&start_info, // STARTUPINFO pointer
|
||||
&proc_info)) { // receives PROCESS_INFORMATION
|
||||
free(env);
|
||||
char err_msg[256];
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
err_msg, sizeof(err_msg), NULL);
|
||||
|
||||
RZ_LOG_ERROR("CreateProcess failed: %#x %s\n", (int)GetLastError(), err_msg);
|
||||
rz_sys_perror("CreateProcess");
|
||||
goto error;
|
||||
}
|
||||
free(env);
|
||||
|
|
@ -251,13 +270,13 @@ RZ_API RzSubprocess *rz_subprocess_start_opt(RzSubprocessOpt *opt) {
|
|||
|
||||
beach:
|
||||
|
||||
if (stdin_read != GetStdHandle(STD_INPUT_HANDLE)) {
|
||||
if (stdin_read && stdin_read != GetStdHandle(STD_INPUT_HANDLE)) {
|
||||
CloseHandle(stdin_read);
|
||||
}
|
||||
if (stderr_write != GetStdHandle(STD_ERROR_HANDLE) && stderr_write != stdout_write) {
|
||||
if (stderr_write && stderr_write != GetStdHandle(STD_ERROR_HANDLE) && stderr_write != stdout_write) {
|
||||
CloseHandle(stderr_write);
|
||||
}
|
||||
if (stdout_write != GetStdHandle(STD_OUTPUT_HANDLE)) {
|
||||
if (stdout_write && stdout_write != GetStdHandle(STD_OUTPUT_HANDLE)) {
|
||||
CloseHandle(stdout_write);
|
||||
}
|
||||
free(cmdline);
|
||||
|
|
|
|||
|
|
@ -200,4 +200,24 @@ char *ReadFromPipe(HANDLE fh, int *outlen) {
|
|||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
RZ_API char **rz_sys_utf8_argv_new(int argc, const wchar_t **argv) {
|
||||
char **utf8_argv = calloc(argc + 1, sizeof(wchar_t *));
|
||||
if (!utf8_argv) {
|
||||
return NULL;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
utf8_argv[i] = rz_utf16_to_utf8(argv[i]);
|
||||
}
|
||||
return utf8_argv;
|
||||
}
|
||||
|
||||
RZ_API void rz_sys_utf8_argv_free(int argc, char **utf8_argv) {
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
free(utf8_argv[i]);
|
||||
}
|
||||
free(utf8_argv);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue