Create process with wide chars on Windows
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 <https://github.com/Genymobile/scrcpy/issues/422>
This commit is contained in:
parent
c0b65b14df
commit
477c0a2cab
3 changed files with 40 additions and 2 deletions
|
@ -3,6 +3,11 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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 xstrncpy(char *dest, const char *src, size_t n) {
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < n - 1 && src[i] != '\0'; ++i)
|
for (i = 0; i < n - 1 && src[i] != '\0'; ++i)
|
||||||
|
@ -47,3 +52,22 @@ char *strquote(const char *src) {
|
||||||
quoted[len + 2] = '\0';
|
quoted[len + 2] = '\0';
|
||||||
return quoted;
|
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
|
||||||
|
|
|
@ -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
|
// returns the new allocated string, to be freed by the caller
|
||||||
char *strquote(const char *src);
|
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
|
#endif
|
||||||
|
|
|
@ -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) {
|
enum process_result cmd_execute(const char *path, const char *const argv[], HANDLE *handle) {
|
||||||
STARTUPINFO si;
|
STARTUPINFOW si;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
memset(&si, 0, sizeof(si));
|
memset(&si, 0, sizeof(si));
|
||||||
si.cb = sizeof(si);
|
si.cb = sizeof(si);
|
||||||
|
@ -29,12 +29,19 @@ enum process_result cmd_execute(const char *path, const char *const argv[], HAND
|
||||||
return PROCESS_ERROR_GENERIC;
|
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
|
#ifdef WINDOWS_NOCONSOLE
|
||||||
int flags = CREATE_NO_WINDOW;
|
int flags = CREATE_NO_WINDOW;
|
||||||
#else
|
#else
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
#endif
|
#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;
|
*handle = NULL;
|
||||||
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
|
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
|
||||||
return PROCESS_ERROR_MISSING_BINARY;
|
return PROCESS_ERROR_MISSING_BINARY;
|
||||||
|
@ -42,6 +49,7 @@ enum process_result cmd_execute(const char *path, const char *const argv[], HAND
|
||||||
return PROCESS_ERROR_GENERIC;
|
return PROCESS_ERROR_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(wide);
|
||||||
*handle = pi.hProcess;
|
*handle = pi.hProcess;
|
||||||
return PROCESS_SUCCESS;
|
return PROCESS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue