]> git.mxchange.org Git - simgear.git/blobdiff - simgear/misc/sg_path.cxx
Fix #1783: repeated error message on console
[simgear.git] / simgear / misc / sg_path.cxx
index 7895e68ceca21b12649cf70b878d8700d030f559..8255fa6aab742fdd11c519a64c22b39f8d820d4d 100644 (file)
@@ -56,7 +56,10 @@ static const char sgSearchPathSep = ':';
 #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)
 {
@@ -80,6 +83,42 @@ 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
@@ -704,20 +743,35 @@ SGPath SGPath::standardLocation(StandardLocation type, const SGPath& def)
   {
     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)
@@ -756,20 +810,15 @@ SGPath SGPath::fromEnv(const char* name, const SGPath& def)
   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)
@@ -800,7 +849,7 @@ std::string SGPath::realpath() const
   #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);