From 997579bed1806f217c910da05092ffdf9f4523b4 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Tue, 2 Oct 2012 17:55:29 +0200 Subject: [PATCH] Move win32 specific stuff to win32/findfile.c Signed-off-by: Sven Strickroth --- src/fileops.c | 148 +----------------------------------------- src/win32/findfile.c | 149 +++++++++++++++++++++++++++++++++++++++++++ src/win32/findfile.h | 23 +++++++ 3 files changed, 175 insertions(+), 145 deletions(-) create mode 100644 src/win32/findfile.c create mode 100644 src/win32/findfile.h diff --git a/src/fileops.c b/src/fileops.c index d99e117bd..763537a46 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -7,6 +7,9 @@ #include "common.h" #include "fileops.h" #include +#if GIT_WIN32 +#include "win32/findfile.h" +#endif int git_futils_mkpath2file(const char *file_path, const mode_t mode) { @@ -371,151 +374,6 @@ int git_futils_rmdir_r(const char *path, git_directory_removal_type removal_type return error; } -#ifdef GIT_WIN32 -struct win32_path { - wchar_t path[MAX_PATH]; - DWORD len; -}; - -static int win32_expand_path(struct win32_path *s_root, const wchar_t *templ) -{ - s_root->len = ExpandEnvironmentStringsW(templ, s_root->path, MAX_PATH); - return s_root->len ? 0 : -1; -} - -static int win32_find_file(git_buf *path, const struct win32_path *root, const char *filename) -{ - size_t len, alloc_len; - wchar_t *file_utf16 = NULL; - char file_utf8[GIT_PATH_MAX]; - - 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); - - /* 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, filename); - - /* check access */ - if (_waccess(file_utf16, F_OK) < 0) { - git__free(file_utf16); - return GIT_ENOTFOUND; - } - - git__utf16_to_8(file_utf8, file_utf16); - git_path_mkposix(file_utf8); - git_buf_sets(path, file_utf8); - - git__free(file_utf16); - return 0; -} -static wchar_t* win32_nextpath(wchar_t *path, wchar_t *buf, size_t buflen) -{ - wchar_t term, *base = path; - - assert(path && buf && buflen); - - term = (*path == L'"') ? *path++ : L';'; - - for (buflen--; *path && *path != term && buflen; buflen--) - *buf++ = *path++; - - *buf = L'\0'; /* reserved a byte via initial subtract */ - - while (*path == term || *path == L';') - path++; - - return (path != base) ? path : NULL; -} - -static int win32_find_system_file_using_path(git_buf *path, const char *filename) -{ - wchar_t * env = NULL; - struct win32_path root; - - env = _wgetenv(L"PATH"); - if (!env) - return -1; - - // search in all paths defined in PATH - while ((env = win32_nextpath(env, root.path, MAX_PATH - 1)) != NULL && *root.path) - { - wchar_t * pfin = root.path + wcslen(root.path) - 1; // last char of the current path entry - - // ensure trailing slash - if (*pfin != L'/' && *pfin != L'\\') - wcscpy(++pfin, L"\\"); // we have enough space left, MAX_PATH - 1 is used in nextpath above - - root.len = (DWORD)wcslen(root.path) + 1; - - if (win32_find_file(path, &root, "git.cmd") == 0 || win32_find_file(path, &root, "git.exe") == 0) { - // we found the cmd or bin directory of a git installaton - if (root.len > 5) { - wcscpy(root.path + wcslen(root.path) - 4, L"etc\\"); - if (win32_find_file(path, &root, filename) == 0) - return 0; - } - } - } - - return GIT_ENOTFOUND; -} - -static int win32_find_system_file_using_registry(git_buf *path, const char *filename) -{ -#ifndef _WIN64 -#define REG_MSYSGIT_INSTALL L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" -#else -#define REG_MSYSGIT_INSTALL L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" -#endif - - struct win32_path root; - - HKEY hKey; - DWORD dwType = REG_SZ; - DWORD dwSize = MAX_PATH; - - root.len = 0; - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) - { - if (RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType,(LPBYTE)&root.path, &dwSize) == ERROR_SUCCESS) - { - // InstallLocation points to the root of the msysgit directory - if (dwSize + 4 > MAX_PATH) // 4 = wcslen(L"etc\\") - { - giterr_set(GITERR_OS, "Cannot locate the system's msysgit directory - path too long"); - return -1; - } - wcscat(root.path, L"etc\\"); - root.len = (DWORD)wcslen(root.path) + 1; - } - } - RegCloseKey(hKey); - - if (!root.len) { - giterr_set(GITERR_OS, "Cannot locate the system's msysgit directory"); - return -1; - } - - if (win32_find_file(path, &root, filename) < 0) { - giterr_set(GITERR_OS, "The system file '%s' doesn't exist", filename); - git_buf_clear(path); - return GIT_ENOTFOUND; - } - - return 0; -} -#endif - int git_futils_find_system_file(git_buf *path, const char *filename) { #ifdef GIT_WIN32 diff --git a/src/win32/findfile.c b/src/win32/findfile.c new file mode 100644 index 000000000..de9373cbb --- /dev/null +++ b/src/win32/findfile.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "utf-conv.h" +#include "path.h" +#include "findfile.h" + +#ifndef _WIN64 +#define REG_MSYSGIT_INSTALL L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" +#else +#define REG_MSYSGIT_INSTALL L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" +#endif + +int win32_expand_path(struct win32_path *s_root, const wchar_t *templ) +{ + s_root->len = ExpandEnvironmentStringsW(templ, s_root->path, MAX_PATH); + return s_root->len ? 0 : -1; +} + +int win32_find_file(git_buf *path, const struct win32_path *root, const char *filename) +{ + size_t len, alloc_len; + wchar_t *file_utf16 = NULL; + char file_utf8[GIT_PATH_MAX]; + + 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); + + /* 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, filename); + + /* check access */ + if (_waccess(file_utf16, F_OK) < 0) { + git__free(file_utf16); + return GIT_ENOTFOUND; + } + + git__utf16_to_8(file_utf8, file_utf16); + git_path_mkposix(file_utf8); + git_buf_sets(path, file_utf8); + + git__free(file_utf16); + return 0; +} + +wchar_t* win32_nextpath(wchar_t *path, wchar_t *buf, size_t buflen) +{ + wchar_t term, *base = path; + + assert(path && buf && buflen); + + term = (*path == L'"') ? *path++ : L';'; + + for (buflen--; *path && *path != term && buflen; buflen--) + *buf++ = *path++; + + *buf = L'\0'; /* reserved a byte via initial subtract */ + + while (*path == term || *path == L';') + path++; + + return (path != base) ? path : NULL; +} + +int win32_find_system_file_using_path(git_buf *path, const char *filename) +{ + wchar_t * env = NULL; + struct win32_path root; + + env = _wgetenv(L"PATH"); + if (!env) + return -1; + + // search in all paths defined in PATH + while ((env = win32_nextpath(env, root.path, MAX_PATH - 1)) != NULL && *root.path) + { + wchar_t * pfin = root.path + wcslen(root.path) - 1; // last char of the current path entry + + // ensure trailing slash + if (*pfin != L'/' && *pfin != L'\\') + wcscpy(++pfin, L"\\"); // we have enough space left, MAX_PATH - 1 is used in nextpath above + + root.len = (DWORD)wcslen(root.path) + 1; + + if (win32_find_file(path, &root, "git.cmd") == 0 || win32_find_file(path, &root, "git.exe") == 0) { + // we found the cmd or bin directory of a git installaton + if (root.len > 5) { + wcscpy(root.path + wcslen(root.path) - 4, L"etc\\"); + if (win32_find_file(path, &root, filename) == 0) + return 0; + } + } + } + + return GIT_ENOTFOUND; +} + +int win32_find_system_file_using_registry(git_buf *path, const char *filename) +{ + struct win32_path root; + + HKEY hKey; + DWORD dwType = REG_SZ; + DWORD dwSize = MAX_PATH; + + root.len = 0; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) + { + if (RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType,(LPBYTE)&root.path, &dwSize) == ERROR_SUCCESS) + { + // InstallLocation points to the root of the msysgit directory + if (dwSize + 4 > MAX_PATH) // 4 = wcslen(L"etc\\") + { + giterr_set(GITERR_OS, "Cannot locate the system's msysgit directory - path too long"); + return -1; + } + wcscat(root.path, L"etc\\"); + root.len = (DWORD)wcslen(root.path) + 1; + } + } + RegCloseKey(hKey); + + if (!root.len) { + giterr_set(GITERR_OS, "Cannot locate the system's msysgit directory"); + return -1; + } + + if (win32_find_file(path, &root, filename) < 0) { + giterr_set(GITERR_OS, "The system file '%s' doesn't exist", filename); + git_buf_clear(path); + return GIT_ENOTFOUND; + } + + return 0; +} diff --git a/src/win32/findfile.h b/src/win32/findfile.h new file mode 100644 index 000000000..8751b7391 --- /dev/null +++ b/src/win32/findfile.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#ifndef INCLUDE_git_findfile_h__ +#define INCLUDE_git_findfile_h__ + +struct win32_path { + wchar_t path[MAX_PATH]; + DWORD len; +}; + +int win32_expand_path(struct win32_path *s_root, const wchar_t *templ); + +int win32_find_file(git_buf *path, const struct win32_path *root, const char *filename); +int win32_find_system_file_using_path(git_buf *path, const char *filename); +int win32_find_system_file_using_registry(git_buf *path, const char *filename); + +#endif +