diff options
| author | Vicent Marti <vicent@github.com> | 2014-04-23 07:13:49 -0700 |
|---|---|---|
| committer | Vicent Marti <vicent@github.com> | 2014-04-23 07:13:49 -0700 |
| commit | 5ca410b9a9bc30a65ed0125646b3702d5943100b (patch) | |
| tree | 7c352c4382def6eaee007745f3f932659b10d827 /src/win32/findfile.c | |
| parent | 5b58d6f78cf8346445374eaf5cde0f54be5c5796 (diff) | |
| parent | 7110000dd5b82c86863633ee37f72ac876a44476 (diff) | |
| download | libgit2-5ca410b9a9bc30a65ed0125646b3702d5943100b.tar.gz | |
Merge pull request #2283 from phkelley/win32_fs
Win32: UTF-8 <-> WCHAR conversion overhaul
Diffstat (limited to 'src/win32/findfile.c')
| -rw-r--r-- | src/win32/findfile.c | 93 |
1 files changed, 37 insertions, 56 deletions
diff --git a/src/win32/findfile.c b/src/win32/findfile.c index a9e812e28..86d4ef5bd 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -17,54 +17,34 @@ #define REG_MSYSGIT_INSTALL L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" #endif -int git_win32__expand_path(struct git_win32__path *s_root, const wchar_t *templ) -{ - s_root->len = ExpandEnvironmentStringsW(templ, s_root->path, MAX_PATH); - return s_root->len ? 0 : -1; -} +typedef struct { + git_win32_path path; + DWORD len; +} _findfile_path; -static int win32_path_to_8(git_buf *path_utf8, const wchar_t *path) +static int git_win32__expand_path(_findfile_path *dest, const wchar_t *src) { - char temp_utf8[GIT_PATH_MAX]; + dest->len = ExpandEnvironmentStringsW(src, dest->path, ARRAY_SIZE(dest->path)); - git__utf16_to_8(temp_utf8, GIT_PATH_MAX, path); - git_path_mkposix(temp_utf8); + if (!dest->len || dest->len > ARRAY_SIZE(dest->path)) + return -1; - return git_buf_sets(path_utf8, temp_utf8); + return 0; } -int git_win32__find_file( - git_buf *path, const struct git_win32__path *root, const char *filename) +static int win32_path_to_8(git_buf *dest, const wchar_t *src) { - size_t len, alloc_len; - wchar_t *file_utf16 = NULL; - - if (!root || !filename || (len = strlen(filename)) == 0) - return GIT_ENOTFOUND; - - /* allocate space for wchar_t path to file */ - alloc_len = root->len + len + 2; - file_utf16 = git__calloc(alloc_len, sizeof(wchar_t)); - GITERR_CHECK_ALLOC(file_utf16); + git_win32_utf8_path utf8_path; - /* append root + '\\' + filename as wchar_t */ - memcpy(file_utf16, root->path, root->len * sizeof(wchar_t)); - - if (*filename == '/' || *filename == '\\') - filename++; - - git__utf8_to_16(file_utf16 + root->len - 1, alloc_len - root->len, filename); - - /* check access */ - if (_waccess(file_utf16, F_OK) < 0) { - git__free(file_utf16); - return GIT_ENOTFOUND; + if (git_win32_path_to_utf8(utf8_path, src) < 0) { + giterr_set(GITERR_OS, "Unable to convert path to UTF-8"); + return -1; } - win32_path_to_8(path, file_utf16); - git__free(file_utf16); + /* Convert backslashes to forward slashes */ + git_path_mkposix(utf8_path); - return 0; + return git_buf_sets(dest, utf8_path); } static wchar_t* win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) @@ -89,7 +69,7 @@ static wchar_t* win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) static int win32_find_git_in_path(git_buf *buf, const wchar_t *gitexe, const wchar_t *subdir) { wchar_t *env = _wgetenv(L"PATH"), lastch; - struct git_win32__path root; + _findfile_path root; size_t gitexe_len = wcslen(gitexe); if (!env) @@ -122,43 +102,44 @@ static int win32_find_git_in_path(git_buf *buf, const wchar_t *gitexe, const wch } static int win32_find_git_in_registry( - git_buf *buf, const HKEY hieve, const wchar_t *key, const wchar_t *subdir) + git_buf *buf, const HKEY hive, const wchar_t *key, const wchar_t *subdir) { HKEY hKey; - DWORD dwType = REG_SZ; - struct git_win32__path path16; + int error = GIT_ENOTFOUND; assert(buf); - path16.len = MAX_PATH; + if (!RegOpenKeyExW(hive, key, 0, KEY_READ, &hKey)) { + DWORD dwType, cbData; + git_win32_path path; - if (RegOpenKeyExW(hieve, key, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { - if (RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType, - (LPBYTE)&path16.path, &path16.len) == ERROR_SUCCESS) - { - /* InstallLocation points to the root of the git directory */ + /* Ensure that the buffer is big enough to have the suffix attached + * after we receive the result. */ + cbData = (DWORD)(sizeof(path) - wcslen(subdir) * sizeof(wchar_t)); - if (path16.len + 4 > MAX_PATH) { /* 4 = wcslen(L"etc\\") */ - giterr_set(GITERR_OS, "Cannot locate git - path too long"); - return -1; - } + /* InstallLocation points to the root of the git directory */ + if (!RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType, (LPBYTE)path, &cbData) && + dwType == REG_SZ) { - wcscat(path16.path, subdir); - path16.len += 4; + /* Append the suffix */ + wcscat(path, subdir); - win32_path_to_8(buf, path16.path); + /* Convert to UTF-8, with forward slashes, and output the path + * to the provided buffer */ + if (!win32_path_to_8(buf, path)) + error = 0; } RegCloseKey(hKey); } - return path16.len ? 0 : GIT_ENOTFOUND; + return error; } static int win32_find_existing_dirs( git_buf *out, const wchar_t *tmpl[]) { - struct git_win32__path path16; + _findfile_path path16; git_buf buf = GIT_BUF_INIT; git_buf_clear(out); |
