Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/win32/findfile.c')
-rw-r--r--src/win32/findfile.c93
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);