You need to sign in or sign up before continuing.
提交 85f2f528 编写于 作者: U uta

6519127: user.home property not set correctly

Summary: Registry-based approach was changed to SHGetKnownFolderPath/SHGetFolderPathW
Reviewed-by: alanb, anthony
上级 7de24bcc
...@@ -23,6 +23,11 @@ ...@@ -23,6 +23,11 @@
* questions. * questions.
*/ */
/* Access APIs for Windows Vista and above */
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
#endif
#include <windows.h> #include <windows.h>
#include <shlobj.h> #include <shlobj.h>
#include <objidl.h> #include <objidl.h>
...@@ -49,8 +54,6 @@ typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); ...@@ -49,8 +54,6 @@ typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
static void SetupI18nProps(LCID lcid, char** language, char** script, char** country, static void SetupI18nProps(LCID lcid, char** language, char** script, char** country,
char** variant, char** encoding); char** variant, char** encoding);
#define SHELL_KEY "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
#define PROPSIZE 9 // eight-letter + null terminator #define PROPSIZE 9 // eight-letter + null terminator
#define SNAMESIZE 86 // max number of chars for LOCALE_SNAME is 85 #define SNAMESIZE 86 // max number of chars for LOCALE_SNAME is 85
...@@ -173,76 +176,54 @@ getJavaIDFromLangID(LANGID langID) ...@@ -173,76 +176,54 @@ getJavaIDFromLangID(LANGID langID)
return ret; return ret;
} }
/*
* Code to figure out the user's home directory using the registry
*/
static WCHAR*
getHomeFromRegistry()
{
HKEY key;
int rc;
DWORD type;
WCHAR *p;
WCHAR path[MAX_PATH+1];
int size = MAX_PATH+1;
rc = RegOpenKeyEx(HKEY_CURRENT_USER, SHELL_KEY, 0, KEY_READ, &key);
if (rc != ERROR_SUCCESS) {
// Shell folder doesn't exist??!!
return NULL;
}
path[0] = 0;
rc = RegQueryValueExW(key, L"Desktop", 0, &type, (LPBYTE)path, &size);
if (rc != ERROR_SUCCESS || type != REG_SZ) {
return NULL;
}
RegCloseKey(key);
/* Get the parent of Desktop directory */
p = wcsrchr(path, L'\\');
if (p == NULL) {
return NULL;
}
*p = L'\0';
return _wcsdup(path);
}
/* /*
* Code to figure out the user's home directory using shell32.dll * Code to figure out the user's home directory using shell32.dll
*/ */
WCHAR* WCHAR*
getHomeFromShell32() getHomeFromShell32()
{ {
HRESULT rc; /*
LPITEMIDLIST item_list = 0; * Note that we don't free the memory allocated
WCHAR *p; * by getHomeFromShell32.
WCHAR path[MAX_PATH+1]; */
int size = MAX_PATH+1; static WCHAR *u_path = NULL;
if (u_path == NULL) {
rc = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &item_list); HRESULT hr;
if (!SUCCEEDED(rc)) {
// we can't find the shell folder.
return NULL;
}
path[0] = 0; /*
SHGetPathFromIDListW(item_list, (LPWSTR)path); * SHELL32 DLL is delay load DLL and we can use the trick with
* __try/__except block.
*/
__try {
/*
* For Windows Vista and later (or patched MS OS) we need to use
* [SHGetKnownFolderPath] call to avoid MAX_PATH length limitation.
* Shell32.dll (version 6.0.6000 or later)
*/
hr = SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DONT_VERIFY, NULL, &u_path);
} __except(EXCEPTION_EXECUTE_HANDLER) {
/* Exception: no [SHGetKnownFolderPath] entry */
hr = E_FAIL;
}
/* Get the parent of Desktop directory */ if (FAILED(hr)) {
p = wcsrchr(path, L'\\'); WCHAR path[MAX_PATH+1];
if (p) {
*p = 0;
}
/* /* fallback solution for WinXP and Windows 2000 */
* We've been successful. Note that we don't free the memory allocated hr = SHGetFolderPathW(NULL, CSIDL_FLAG_DONT_VERIFY | CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, path);
* by ShGetSpecialFolderLocation. We only ever come through here once, if (FAILED(hr)) {
* and only if the registry lookup failed, so it's just not worth it. /* we can't find the shell folder. */
* u_path = NULL;
* We also don't unload the SHELL32 DLL. We've paid the hit for loading } else {
* it and we may need it again later. /* Just to be sure about the path length until Windows Vista approach.
*/ * [S_FALSE] could not be returned due to [CSIDL_FLAG_DONT_VERIFY] flag and UNICODE version.
return _wcsdup(path); */
path[MAX_PATH] = 0;
u_path = _wcsdup(path);
}
}
}
return u_path;
} }
static boolean static boolean
...@@ -336,7 +317,7 @@ GetJavaProperties(JNIEnv* env) ...@@ -336,7 +317,7 @@ GetJavaProperties(JNIEnv* env)
OSVERSIONINFOEX ver; OSVERSIONINFOEX ver;
if (sprops.user_dir) { if (sprops.line_separator) {
return &sprops; return &sprops;
} }
...@@ -538,15 +519,7 @@ GetJavaProperties(JNIEnv* env) ...@@ -538,15 +519,7 @@ GetJavaProperties(JNIEnv* env)
} }
/* /*
* Home directory/ * Home directory
*
* We first look under a standard registry key. If that fails we
* fall back on using a SHELL32.DLL API. If that fails we use a
* default value.
*
* Note: To save space we want to avoid loading SHELL32.DLL
* unless really necessary. However if we do load it, we leave it
* in memory, as it may be needed again later.
* *
* The normal result is that for a given user name XXX: * The normal result is that for a given user name XXX:
* On multi-user NT, user.home gets set to c:\winnt\profiles\XXX. * On multi-user NT, user.home gets set to c:\winnt\profiles\XXX.
...@@ -554,13 +527,11 @@ GetJavaProperties(JNIEnv* env) ...@@ -554,13 +527,11 @@ GetJavaProperties(JNIEnv* env)
* On single-user Win95, user.home gets set to c:\windows. * On single-user Win95, user.home gets set to c:\windows.
*/ */
{ {
WCHAR *homep = getHomeFromRegistry(); WCHAR *homep = getHomeFromShell32();
if (homep == NULL) { if (homep == NULL) {
homep = getHomeFromShell32(); homep = L"C:\\";
if (homep == NULL)
homep = L"C:\\";
} }
sprops.user_home = _wcsdup(homep); sprops.user_home = homep;
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册