From 0bfb9478094b83f49b0595efd3989db8cb5528b4 Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 26 Nov 2016 11:37:01 +0000 Subject: win32.c: special folders as home dir * win32/win32.c (rb_w32_home_dir): move from win32/file.c to try special folders. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56901 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- win32/file.c | 69 ++--------------------------------------------------------- win32/file.h | 1 + win32/win32.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 67 deletions(-) (limited to 'win32') diff --git a/win32/file.c b/win32/file.c index 29bf3dfe95..c0efb7b091 100644 --- a/win32/file.c +++ b/win32/file.c @@ -44,71 +44,6 @@ replace_wchar(wchar_t *s, int find, int replace) } } -/* - Return user's home directory using environment variables combinations. - Memory allocated by this function should be manually freed afterwards. - - Try: - HOME, HOMEDRIVE + HOMEPATH and USERPROFILE environment variables - TODO: Special Folders - Profile and Personal -*/ -static wchar_t * -home_dir(void) -{ - wchar_t *buffer = NULL; - size_t buffer_len = 0, len = 0; - enum { - HOME_NONE, ENV_HOME, ENV_DRIVEPATH, ENV_USERPROFILE - } home_type = HOME_NONE; - - /* - GetEnvironmentVariableW when used with NULL will return the required - buffer size and its terminating character. - http://msdn.microsoft.com/en-us/library/windows/desktop/ms683188(v=vs.85).aspx - */ - - if ((len = GetEnvironmentVariableW(L"HOME", NULL, 0)) != 0) { - buffer_len = len; - home_type = ENV_HOME; - } - else if ((len = GetEnvironmentVariableW(L"HOMEDRIVE", NULL, 0)) != 0) { - buffer_len = len; - if ((len = GetEnvironmentVariableW(L"HOMEPATH", NULL, 0)) != 0) { - buffer_len += len; - home_type = ENV_DRIVEPATH; - } - } - else if ((len = GetEnvironmentVariableW(L"USERPROFILE", NULL, 0)) != 0) { - buffer_len = len; - home_type = ENV_USERPROFILE; - } - - if (!home_type) return NULL; - - /* allocate buffer */ - buffer = ALLOC_N(wchar_t, buffer_len); - - switch (home_type) { - case ENV_HOME: - GetEnvironmentVariableW(L"HOME", buffer, buffer_len); - break; - case ENV_DRIVEPATH: - len = GetEnvironmentVariableW(L"HOMEDRIVE", buffer, buffer_len); - GetEnvironmentVariableW(L"HOMEPATH", buffer + len, buffer_len - len); - break; - case ENV_USERPROFILE: - GetEnvironmentVariableW(L"USERPROFILE", buffer, buffer_len); - break; - default: - break; - } - - /* sanitize backslashes with forwardslashes */ - replace_wchar(buffer, L'\\', L'/'); - - return buffer; -} - /* Remove trailing invalid ':$DATA' of the path. */ static inline size_t remove_invalid_alternative_data(wchar_t *wfullpath, size_t size) @@ -360,7 +295,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na /* tainted if expanding '~' */ tainted = 1; - whome = home_dir(); + whome = rb_w32_home_dir(); if (whome == NULL) { free(wpath); rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'"); @@ -441,7 +376,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na /* tainted if expanding '~' */ tainted = 1; - whome = home_dir(); + whome = rb_w32_home_dir(); if (whome == NULL) { free(wpath); free(wdir); diff --git a/win32/file.h b/win32/file.h index dd448269d4..f3ce244f5d 100644 --- a/win32/file.h +++ b/win32/file.h @@ -43,5 +43,6 @@ int fchmod(int fd, int mode); #define HAVE_FCHMOD 0 UINT rb_w32_filecp(void); +WCHAR *rb_w32_home_dir(void); #endif /* RUBY_WIN32_FILE_H */ diff --git a/win32/win32.c b/win32/win32.c index a0efcbcbd8..1fb72b3bb2 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -527,6 +527,70 @@ rb_w32_system_tmpdir(WCHAR *path, UINT len) return (UINT)(p - path + numberof(temp) - 1); } +/* + Return user's home directory using environment variables combinations. + Memory allocated by this function should be manually freed + afterwards with xfree. + + Try: + HOME, HOMEDRIVE + HOMEPATH and USERPROFILE environment variables + Special Folders - Profile and Personal +*/ +WCHAR * +rb_w32_home_dir(void) +{ + WCHAR *buffer = NULL; + size_t buffer_len = MAX_PATH, len = 0; + enum { + HOME_NONE, ENV_HOME, ENV_DRIVEPATH, ENV_USERPROFILE + } home_type = HOME_NONE; + + if ((len = GetEnvironmentVariableW(L"HOME", NULL, 0)) != 0) { + buffer_len = len; + home_type = ENV_HOME; + } + else if ((len = GetEnvironmentVariableW(L"HOMEDRIVE", NULL, 0)) != 0) { + buffer_len = len; + if ((len = GetEnvironmentVariableW(L"HOMEPATH", NULL, 0)) != 0) { + buffer_len += len; + home_type = ENV_DRIVEPATH; + } + } + else if ((len = GetEnvironmentVariableW(L"USERPROFILE", NULL, 0)) != 0) { + buffer_len = len; + home_type = ENV_USERPROFILE; + } + + /* allocate buffer */ + buffer = ALLOC_N(WCHAR, buffer_len); + + switch (home_type) { + case ENV_HOME: + GetEnvironmentVariableW(L"HOME", buffer, buffer_len); + break; + case ENV_DRIVEPATH: + len = GetEnvironmentVariableW(L"HOMEDRIVE", buffer, buffer_len); + GetEnvironmentVariableW(L"HOMEPATH", buffer + len, buffer_len - len); + break; + case ENV_USERPROFILE: + GetEnvironmentVariableW(L"USERPROFILE", buffer, buffer_len); + break; + default: + if (!get_special_folder(CSIDL_PROFILE, buffer, buffer_len) && + !get_special_folder(CSIDL_PERSONAL, buffer, buffer_len)) { + xfree(buffer); + return NULL; + } + buffer = REALLOC_N(buffer, WCHAR, lstrlenW(buffer) + 1); + break; + } + + /* sanitize backslashes with forwardslashes */ + regulate_path(buffer); + + return buffer; +} + /* License: Ruby's */ static void init_env(void) -- cgit v1.2.3