1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
nobu 2016-11-26 11:37:01 +00:00
parent 8c08d2de53
commit 58742627af
3 changed files with 67 additions and 67 deletions

View file

@ -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);

View file

@ -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 */

View file

@ -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)