Skip to content

Commit

Permalink
Create process with wide chars on Windows
Browse files Browse the repository at this point in the history
Windows does not support UTF-8, so pushing a file with non-ASCII
characters failed.

Convert the UTF-8 command line to a wide characters string and call
CreateProcessW().

Fixes <#422>
  • Loading branch information
rom1v committed Feb 10, 2019
1 parent c0b65b1 commit 477c0a2
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
24 changes: 24 additions & 0 deletions app/src/str_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
# include <windows.h>
# include <tchar.h>
#endif

size_t xstrncpy(char *dest, const char *src, size_t n) {
size_t i;
for (i = 0; i < n - 1 && src[i] != '\0'; ++i)
Expand Down Expand Up @@ -47,3 +52,22 @@ char *strquote(const char *src) {
quoted[len + 2] = '\0';
return quoted;
}

#ifdef _WIN32

wchar_t *utf8_to_wide_char(const char *utf8) {
int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
if (!len) {
return NULL;
}

wchar_t *wide = malloc(len * sizeof(wchar_t));
if (!wide) {
return NULL;
}

MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wide, len);
return wide;
}

#endif
6 changes: 6 additions & 0 deletions app/src/str_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@ size_t xstrjoin(char *dst, const char *const tokens[], char sep, size_t n);
// returns the new allocated string, to be freed by the caller
char *strquote(const char *src);

#ifdef _WIN32
// convert a UTF-8 string to a wchar_t string
// returns the new allocated string, to be freed by the caller
wchar_t *utf8_to_wide_char(const char *utf8);
#endif

#endif
12 changes: 10 additions & 2 deletions app/src/sys/win/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static int build_cmd(char *cmd, size_t len, const char *const argv[]) {
}

enum process_result cmd_execute(const char *path, const char *const argv[], HANDLE *handle) {
STARTUPINFO si;
STARTUPINFOW si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
Expand All @@ -29,19 +29,27 @@ enum process_result cmd_execute(const char *path, const char *const argv[], HAND
return PROCESS_ERROR_GENERIC;
}

wchar_t *wide = utf8_to_wide_char(cmd);
if (!wide) {
LOGC("Cannot allocate wide char string");
return PROCESS_ERROR_GENERIC;
}

#ifdef WINDOWS_NOCONSOLE
int flags = CREATE_NO_WINDOW;
#else
int flags = 0;
#endif
if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, flags, NULL, NULL, &si, &pi)) {
if (!CreateProcessW(NULL, wide, NULL, NULL, FALSE, flags, NULL, NULL, &si, &pi)) {
free(wide);
*handle = NULL;
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
return PROCESS_ERROR_MISSING_BINARY;
}
return PROCESS_ERROR_GENERIC;
}

free(wide);
*handle = pi.hProcess;
return PROCESS_SUCCESS;
}
Expand Down

0 comments on commit 477c0a2

Please sign in to comment.