ruby-changes:44828
From: nobu <ko1@a...>
Date: Sat, 26 Nov 2016 20:37:06 +0900 (JST)
Subject: [ruby-changes:44828] nobu:r56901 (trunk): win32.c: special folders as home dir
nobu 2016-11-26 20:37:01 +0900 (Sat, 26 Nov 2016) New Revision: 56901 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56901 Log: win32.c: special folders as home dir * win32/win32.c (rb_w32_home_dir): move from win32/file.c to try special folders. Modified files: trunk/win32/file.c trunk/win32/file.h trunk/win32/win32.c Index: win32/win32.c =================================================================== --- win32/win32.c (revision 56900) +++ win32/win32.c (revision 56901) @@ -527,6 +527,70 @@ rb_w32_system_tmpdir(WCHAR *path, UINT l https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L527 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) Index: win32/file.c =================================================================== --- win32/file.c (revision 56900) +++ win32/file.c (revision 56901) @@ -44,71 +44,6 @@ replace_wchar(wchar_t *s, int find, int https://github.com/ruby/ruby/blob/trunk/win32/file.c#L44 } } -/* - 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 https://github.com/ruby/ruby/blob/trunk/win32/file.c#L295 /* 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 https://github.com/ruby/ruby/blob/trunk/win32/file.c#L376 /* tainted if expanding '~' */ tainted = 1; - whome = home_dir(); + whome = rb_w32_home_dir(); if (whome == NULL) { free(wpath); free(wdir); Index: win32/file.h =================================================================== --- win32/file.h (revision 56900) +++ win32/file.h (revision 56901) @@ -43,5 +43,6 @@ int fchmod(int fd, int mode); https://github.com/ruby/ruby/blob/trunk/win32/file.h#L43 #define HAVE_FCHMOD 0 UINT rb_w32_filecp(void); +WCHAR *rb_w32_home_dir(void); #endif /* RUBY_WIN32_FILE_H */ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/