summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/libuv/src/win/util.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/libuv/src/win/util.c')
-rw-r--r--3rdparty/libuv/src/win/util.c254
1 files changed, 207 insertions, 47 deletions
diff --git a/3rdparty/libuv/src/win/util.c b/3rdparty/libuv/src/win/util.c
index cb247513046..1788b1780e9 100644
--- a/3rdparty/libuv/src/win/util.c
+++ b/3rdparty/libuv/src/win/util.c
@@ -87,30 +87,6 @@ void uv__util_init() {
}
-int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
- char* utf8Buffer, size_t utf8Size) {
- return WideCharToMultiByte(CP_UTF8,
- 0,
- utf16Buffer,
- utf16Size,
- utf8Buffer,
- utf8Size,
- NULL,
- NULL);
-}
-
-
-int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
- size_t utf16Size) {
- return MultiByteToWideChar(CP_UTF8,
- 0,
- utf8Buffer,
- -1,
- utf16Buffer,
- utf16Size);
-}
-
-
int uv_exepath(char* buffer, size_t* size_ptr) {
int utf8_len, utf16_buffer_len, utf16_len;
WCHAR* utf16_buffer;
@@ -210,7 +186,7 @@ int uv_cwd(char* buffer, size_t* size) {
if (r == 0) {
return uv_translate_sys_error(GetLastError());
} else if (r > (int) *size) {
- *size = r -1;
+ *size = r;
return UV_ENOBUFS;
}
@@ -384,7 +360,7 @@ int uv_set_process_title(const char* title) {
uv__once_init();
/* Find out how big the buffer for the wide-char title must be */
- length = uv_utf8_to_utf16(title, NULL, 0);
+ length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
if (!length) {
err = GetLastError();
goto done;
@@ -396,7 +372,7 @@ int uv_set_process_title(const char* title) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
- length = uv_utf8_to_utf16(title, title_w, length);
+ length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length);
if (!length) {
err = GetLastError();
goto done;
@@ -434,7 +410,7 @@ static int uv__get_process_title() {
}
/* Find out what the size of the buffer is that we need */
- length = uv_utf16_to_utf8(title_w, -1, NULL, 0);
+ length = WideCharToMultiByte(CP_UTF8, 0, title_w, -1, NULL, 0, NULL, NULL);
if (!length) {
return -1;
}
@@ -446,7 +422,14 @@ static int uv__get_process_title() {
}
/* Do utf16 -> utf8 conversion here */
- if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) {
+ if (!WideCharToMultiByte(CP_UTF8,
+ 0,
+ title_w,
+ -1,
+ process_title,
+ length,
+ NULL,
+ NULL)) {
uv__free(process_title);
return -1;
}
@@ -1169,7 +1152,7 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
int uv_os_homedir(char* buffer, size_t* size) {
- HANDLE token;
+ uv_passwd_t pwd;
wchar_t path[MAX_PATH];
DWORD bufsize;
size_t len;
@@ -1183,6 +1166,7 @@ int uv_os_homedir(char* buffer, size_t* size) {
if (len == 0) {
r = GetLastError();
+
/* Don't return an error if USERPROFILE was not found */
if (r != ERROR_ENVVAR_NOT_FOUND)
return uv_translate_sys_error(r);
@@ -1190,43 +1174,219 @@ int uv_os_homedir(char* buffer, size_t* size) {
/* This should not be possible */
return UV_EIO;
} else {
- goto convert_buffer;
+ /* Check how much space we need */
+ bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
+
+ if (bufsize == 0) {
+ return uv_translate_sys_error(GetLastError());
+ } else if (bufsize > *size) {
+ *size = bufsize;
+ return UV_ENOBUFS;
+ }
+
+ /* Convert to UTF-8 */
+ bufsize = WideCharToMultiByte(CP_UTF8,
+ 0,
+ path,
+ -1,
+ buffer,
+ *size,
+ NULL,
+ NULL);
+
+ if (bufsize == 0)
+ return uv_translate_sys_error(GetLastError());
+
+ *size = bufsize - 1;
+ return 0;
}
- /* USERPROFILE is not set, so call GetUserProfileDirectoryW() */
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
- return uv_translate_sys_error(GetLastError());
+ /* USERPROFILE is not set, so call uv__getpwuid_r() */
+ r = uv__getpwuid_r(&pwd);
- bufsize = MAX_PATH;
- if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
- r = GetLastError();
- CloseHandle(token);
+ if (r != 0) {
+ return r;
+ }
- /* This should not be possible */
- if (r == ERROR_INSUFFICIENT_BUFFER)
- return UV_EIO;
+ len = strlen(pwd.homedir);
- return uv_translate_sys_error(r);
+ if (len >= *size) {
+ *size = len + 1;
+ uv_os_free_passwd(&pwd);
+ return UV_ENOBUFS;
}
- CloseHandle(token);
+ memcpy(buffer, pwd.homedir, len + 1);
+ *size = len;
+ uv_os_free_passwd(&pwd);
+
+ return 0;
+}
-convert_buffer:
+
+int uv_os_tmpdir(char* buffer, size_t* size) {
+ wchar_t path[MAX_PATH + 1];
+ DWORD bufsize;
+ size_t len;
+
+ if (buffer == NULL || size == NULL || *size == 0)
+ return UV_EINVAL;
+
+ len = GetTempPathW(MAX_PATH + 1, path);
+
+ if (len == 0) {
+ return uv_translate_sys_error(GetLastError());
+ } else if (len > MAX_PATH + 1) {
+ /* This should not be possible */
+ return UV_EIO;
+ }
+
+ /* The returned directory should not have a trailing slash, unless it */
+ /* points at a drive root, like c:\. Remove it if needed.*/
+ if (path[len - 1] == L'\\' &&
+ !(len == 3 && path[1] == L':')) {
+ len--;
+ path[len] = L'\0';
+ }
/* Check how much space we need */
- bufsize = uv_utf16_to_utf8(path, -1, NULL, 0);
+ bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
+
if (bufsize == 0) {
return uv_translate_sys_error(GetLastError());
} else if (bufsize > *size) {
- *size = bufsize - 1;
+ *size = bufsize;
return UV_ENOBUFS;
}
/* Convert to UTF-8 */
- bufsize = uv_utf16_to_utf8(path, -1, buffer, *size);
+ bufsize = WideCharToMultiByte(CP_UTF8,
+ 0,
+ path,
+ -1,
+ buffer,
+ *size,
+ NULL,
+ NULL);
+
if (bufsize == 0)
return uv_translate_sys_error(GetLastError());
*size = bufsize - 1;
return 0;
}
+
+
+void uv_os_free_passwd(uv_passwd_t* pwd) {
+ if (pwd == NULL)
+ return;
+
+ uv__free(pwd->username);
+ uv__free(pwd->homedir);
+ pwd->username = NULL;
+ pwd->homedir = NULL;
+}
+
+
+int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8) {
+ DWORD bufsize;
+
+ if (utf16 == NULL)
+ return UV_EINVAL;
+
+ /* Check how much space we need */
+ bufsize = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL);
+
+ if (bufsize == 0)
+ return uv_translate_sys_error(GetLastError());
+
+ /* Allocate the destination buffer */
+ *utf8 = uv__malloc(bufsize);
+
+ if (*utf8 == NULL)
+ return UV_ENOMEM;
+
+ /* Convert to UTF-8 */
+ bufsize = WideCharToMultiByte(CP_UTF8,
+ 0,
+ utf16,
+ -1,
+ *utf8,
+ bufsize,
+ NULL,
+ NULL);
+
+ if (bufsize == 0) {
+ uv__free(*utf8);
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ return 0;
+}
+
+
+int uv__getpwuid_r(uv_passwd_t* pwd) {
+ HANDLE token;
+ wchar_t username[UNLEN + 1];
+ wchar_t path[MAX_PATH];
+ DWORD bufsize;
+ int r;
+
+ if (pwd == NULL)
+ return UV_EINVAL;
+
+ /* Get the home directory using GetUserProfileDirectoryW() */
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
+ return uv_translate_sys_error(GetLastError());
+
+ bufsize = sizeof(path);
+ if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
+ r = GetLastError();
+ CloseHandle(token);
+
+ /* This should not be possible */
+ if (r == ERROR_INSUFFICIENT_BUFFER)
+ return UV_ENOMEM;
+
+ return uv_translate_sys_error(r);
+ }
+
+ CloseHandle(token);
+
+ /* Get the username using GetUserNameW() */
+ bufsize = sizeof(username);
+ if (!GetUserNameW(username, &bufsize)) {
+ r = GetLastError();
+
+ /* This should not be possible */
+ if (r == ERROR_INSUFFICIENT_BUFFER)
+ return UV_ENOMEM;
+
+ return uv_translate_sys_error(r);
+ }
+
+ pwd->homedir = NULL;
+ r = uv__convert_utf16_to_utf8(path, &pwd->homedir);
+
+ if (r != 0)
+ return r;
+
+ pwd->username = NULL;
+ r = uv__convert_utf16_to_utf8(username, &pwd->username);
+
+ if (r != 0) {
+ uv__free(pwd->homedir);
+ return r;
+ }
+
+ pwd->shell = NULL;
+ pwd->uid = -1;
+ pwd->gid = -1;
+
+ return 0;
+}
+
+
+int uv_os_get_passwd(uv_passwd_t* pwd) {
+ return uv__getpwuid_r(pwd);
+}