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/win32.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'win32/win32.c') 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