From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/dir.c | 29 +++++++++++++---------------- dlls/msvcrt/msvcrt.h | 17 +++++++++++++++++ dlls/ucrtbase/tests/file.c | 8 ++++++++ 3 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index d574a4ae22e..abb3bc21388 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -787,24 +787,21 @@ int CDECL _wfindnext64i32(intptr_t hand, struct _wfinddata64i32_t * ft) */ char* CDECL _getcwd(char * buf, int size) { - char dir[MAX_PATH]; - int dir_len = GetCurrentDirectoryA(MAX_PATH,dir); + wchar_t dirW[MAX_PATH]; + int len;
- if (dir_len < 1) - return NULL; /* FIXME: Real return value untested */ + if (!_wgetcwd(dirW, ARRAY_SIZE(dirW))) return NULL;
- if (!buf) - { - if (size <= dir_len) size = dir_len + 1; - if (!(buf = malloc( size ))) return NULL; - } - else if (dir_len >= size) - { - *_errno() = ERANGE; - return NULL; /* buf too small */ - } - strcpy(buf,dir); - return buf; + if (!buf) return astrdupw_utf8(dirW); + len = convert_wcs_to_acp_utf8(dirW, NULL, 0); + if (!len) return NULL; + if (len > size) + { + *_errno() = ERANGE; + return NULL; + } + convert_wcs_to_acp_utf8(dirW, buf, size); + return buf; }
/********************************************************************* diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 71b0f9039f1..39349345de0 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -417,6 +417,11 @@ static inline int convert_acp_utf8_to_wcs(const char *str, wchar_t *wstr, int le return MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, len); }
+static inline int convert_wcs_to_acp_utf8(const wchar_t *wstr, char *str, int len) +{ + return WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); +} + static inline wchar_t* wstrdupa_utf8(const char *str) { int len = convert_acp_utf8_to_wcs(str, NULL, 0); @@ -429,4 +434,16 @@ static inline wchar_t* wstrdupa_utf8(const char *str) return wstr; }
+static inline char* astrdupw_utf8(const wchar_t *wstr) +{ + int len = convert_wcs_to_acp_utf8(wstr, NULL, 0); + char *str; + + if (!len) return NULL; + str = malloc(len * sizeof(char)); + if (!str) return NULL; + convert_wcs_to_acp_utf8(wstr, str, len); + return str; +} + #endif /* __WINE_MSVCRT_H */ diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index bb01a8a7b8f..1bae5e4263d 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -223,6 +223,7 @@ static void test_utf8(void) const char dir[] = "dir\xc4\x99\xc5\x9b\xc4\x87"; const WCHAR dirW[] = L"dir\x0119\x015b\x0107";
+ char buf[256], *p; int ret;
if (!setlocale(LC_ALL, ".utf8")) @@ -241,6 +242,13 @@ static void test_utf8(void)
ret = _chdir(dir); ok(!ret, "_chdir returned %d, error %d\n", ret, errno); + + p = _getcwd(buf, sizeof(buf)); + ok(p == buf, "_getcwd returned %p, errno %d\n", p, errno); + p = strrchr(p, '\'); + ok(!!p, "strrchr returned NULL, buf = %s\n", debugstr_a(buf)); + ok(!strcmp(p + 1, dir), "unexpected working directory: %s\n", debugstr_a(buf)); + ret = _chdir(".."); ok(!ret, "_chdir returned %d, error %d\n", ret, errno);