WindowsXP workaround for SHGetKnowwFolder

Fix from xDraconian after a bug report from Aleesandro.
This commit is contained in:
James Turner
2015-04-09 15:33:56 +01:00
parent 72ae14227e
commit 089fc5ea0a
+29 -14
View File
@@ -57,7 +57,7 @@ static const char sgSearchPathSep = ':';
#ifdef _WIN32 #ifdef _WIN32
#include <ShlObj.h> // for CSIDL #include <ShlObj.h> // for CSIDL
#include <Knownfolders.h> // for Standard Folder GUIDs #include <versionhelpers.h>
static SGPath pathForCSIDL(int csidl, const SGPath& def) static SGPath pathForCSIDL(int csidl, const SGPath& def)
{ {
@@ -84,9 +84,16 @@ static SGPath pathForCSIDL(int csidl, const SGPath& def)
static SGPath pathForKnownFolder(REFKNOWNFOLDERID folderId, const SGPath& def) static SGPath pathForKnownFolder(REFKNOWNFOLDERID folderId, const SGPath& def)
{ {
typedef HRESULT (WINAPI*PSHGKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*);
HINSTANCE shellDll = LoadLibrary(TEXT("shell32"));
if (shellDll != NULL) {
PSHGKFP pSHGetKnownFolderPath = (PSHGKFP) GetProcAddress(shellDll, "SHGetKnownFolderPath");
if (pSHGetKnownFolderPath != NULL) {
// system call will allocate dynamic memory... which we must release when done // system call will allocate dynamic memory... which we must release when done
wchar_t* localFolder = 0; wchar_t* localFolder = 0;
if (SHGetKnownFolderPath(folderId, KF_FLAG_DEFAULT_PATH, NULL, &localFolder) == S_OK) {
if (pSHGetKnownFolderPath(folderId, KF_FLAG_DEFAULT_PATH, NULL, &localFolder) == S_OK) {
// copy into local memory // copy into local memory
char path[MAX_PATH]; char path[MAX_PATH];
size_t len; size_t len;
@@ -102,6 +109,10 @@ static SGPath pathForKnownFolder(REFKNOWNFOLDERID folderId, const SGPath& def)
return folder_path; return folder_path;
} }
}
FreeLibrary(shellDll);
}
return def; return def;
} }
@@ -730,31 +741,35 @@ SGPath SGPath::standardLocation(StandardLocation type, const SGPath& def)
{ {
case HOME: case HOME:
return home(def); return home(def);
#ifdef _WIN32 #ifdef _WIN32
# if (WINVER > 0x0501)
case DESKTOP: case DESKTOP:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Desktop, def); return pathForKnownFolder(FOLDERID_Desktop, def);
case DOWNLOADS:
return pathForKnownFolder(FOLDERID_Downloads, def);
case DOCUMENTS:
return pathForKnownFolder(FOLDERID_Documents, def);
case PICTURES:
return pathForKnownFolder(FOLDERID_Pictures, def);
# else
case DESKTOP:
return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def); return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
case DOWNLOADS: case DOWNLOADS:
// TODO use KnownFolders if (IsWindowsVistaOrGreater())
// http://msdn.microsoft.com/en-us/library/bb776911%28v=vs.85%29.aspx return pathForKnownFolder(FOLDERID_Downloads, def);
if (!def.isNull()) if (!def.isNull())
return def; return def;
return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def); return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
case DOCUMENTS: case DOCUMENTS:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Documents, def);
return pathForCSIDL(CSIDL_MYDOCUMENTS, def); return pathForCSIDL(CSIDL_MYDOCUMENTS, def);
case PICTURES: case PICTURES:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Pictures, def);
return pathForCSIDL(CSIDL_MYPICTURES, def); return pathForCSIDL(CSIDL_MYPICTURES, def);
# endif
#elif __APPLE__ #elif __APPLE__
// since this is C++, we can't include NSPathUtilities.h to access the enum // since this is C++, we can't include NSPathUtilities.h to access the enum
// values, so hard-coding them here (they are stable, don't worry) // values, so hard-coding them here (they are stable, don't worry)