#endif
#ifdef _WIN32
-#include <ShlObj.h> // for CSIDL
+#include <ShlObj.h> // for CSIDL
+// TODO: replace this include file with the official <versionhelpers.h> header
+// included in the Windows 8.1 SDK
+#include "sgversionhelpers.hxx"
static SGPath pathForCSIDL(int csidl, const SGPath& def)
{
return 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
+ wchar_t* localFolder = 0;
+
+ if (pSHGetKnownFolderPath(folderId, KF_FLAG_DEFAULT_PATH, NULL, &localFolder) == S_OK) {
+ // copy into local memory
+ char path[MAX_PATH];
+ size_t len;
+ if (wcstombs_s(&len, path, localFolder, MAX_PATH) != S_OK) {
+ path[0] = '\0';
+ SG_LOG(SG_GENERAL, SG_WARN, "WCS to MBS failed");
+ }
+
+ SGPath folder_path = SGPath(path, def.getPermissionChecker());
+
+ // release dynamic memory
+ CoTaskMemFree(static_cast<void*>(localFolder));
+
+ return folder_path;
+ }
+ }
+
+ FreeLibrary(shellDll);
+ }
+
+ return def;
+}
+
#elif __APPLE__
// defined in CocoaHelpers.mm
{
case HOME:
return home(def);
+
#ifdef _WIN32
case DESKTOP:
- return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
+ if (IsWindowsVistaOrGreater())
+ return pathForKnownFolder(FOLDERID_Desktop, def);
+
+ return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
+
case DOWNLOADS:
- // TODO use KnownFolders
- // http://msdn.microsoft.com/en-us/library/bb776911%28v=vs.85%29.aspx
- if( !def.isNull() )
- return def;
+ if (IsWindowsVistaOrGreater())
+ return pathForKnownFolder(FOLDERID_Downloads, def);
+
+ if (!def.isNull())
+ return def;
+
+ return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
- return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
case DOCUMENTS:
- return pathForCSIDL(CSIDL_MYDOCUMENTS, def);
+ if (IsWindowsVistaOrGreater())
+ return pathForKnownFolder(FOLDERID_Documents, def);
+
+ return pathForCSIDL(CSIDL_MYDOCUMENTS, def);
+
case PICTURES:
- return pathForCSIDL(CSIDL_MYPICTURES, def);
+ if (IsWindowsVistaOrGreater())
+ return pathForKnownFolder(FOLDERID_Pictures, def);
+
+ return pathForCSIDL(CSIDL_MYPICTURES, def);
+
#elif __APPLE__
// 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)
return def;
}
-#ifdef _WIN32
//------------------------------------------------------------------------------
SGPath SGPath::home(const SGPath& def)
{
- // TODO
- return def;
-}
+#ifdef _WIN32
+ return fromEnv("USERPROFILE", def);
#else
-//------------------------------------------------------------------------------
-SGPath SGPath::home(const SGPath& def)
-{
- return fromEnv("HOME", def);
-}
+ return fromEnv("HOME", def);
#endif
+}
//------------------------------------------------------------------------------
SGPath SGPath::desktop(const SGPath& def)
#endif
if (!buf)
{
- SG_LOG(SG_IO, SG_ALERT, "ERROR: The path '" << path << "' does not exist in the file system.");
+ SG_LOG(SG_IO, SG_WARN, "ERROR: The path '" << path << "' does not exist in the file system.");
return path;
}
std::string p(buf);