浏览代码

prepare for is_protected_mode

David Rose 16 年之前
父节点
当前提交
c40c8f66fe
共有 1 个文件被更改,包括 78 次插入12 次删除
  1. 78 12
      direct/src/plugin/find_root_dir.cxx

+ 78 - 12
direct/src/plugin/find_root_dir.cxx

@@ -25,18 +25,22 @@
 #include <sys/stat.h>
 #endif
 
+#include <iostream>
+using namespace std;
+
+
+#ifdef _WIN32
 ////////////////////////////////////////////////////////////////////
-//     Function: find_root_dir
-//  Description: Returns the path to the installable Panda3D directory
-//               on the user's machine.
+//     Function: get_csidl_dir
+//  Description: A wrapper around SHGetSpecialFolderPath(), to return
+//               the Panda3D directory under the indicated CSIDL
+//               folder.
 ////////////////////////////////////////////////////////////////////
-string
-find_root_dir() {
-#ifdef _WIN32
-  // e.g., c:/Documents and Settings/<username>/Application Data/Panda3D
-
-  char buffer[MAX_PATH];
-  if (SHGetSpecialFolderPath(NULL, buffer, CSIDL_APPDATA, true)) {
+static string
+get_csidl_dir(int csidl) {
+  static const int buffer_size = MAX_PATH;
+  char buffer[buffer_size];
+  if (SHGetSpecialFolderPath(NULL, buffer, csidl, true)) {
     bool isdir = false;
     DWORD results = GetFileAttributes(buffer);
     if (results != -1) {
@@ -64,14 +68,76 @@ find_root_dir() {
     }
   }
 
+  // Something went wrong.
+  return string();
+}
+#endif  // _WIN32
+
+////////////////////////////////////////////////////////////////////
+//     Function: find_root_dir
+//  Description: Returns the path to the installable Panda3D directory
+//               on the user's machine.
+////////////////////////////////////////////////////////////////////
+string
+find_root_dir() {
+#ifdef _WIN32
+  // TODO: use IEIsProtectedModeProcess() to determine if we are
+  // running in IE's "protected mode" here.
+  bool is_protected = false;
+
+  int csidl = CSIDL_APPDATA;
+  // e.g., c:/Documents and Settings/<username>/Application Data/Panda3D
+
+  if (is_protected) {
+    // In IE's "protected mode", we have to use the common directory,
+    // which has already been created for us with low-level
+    // permissions.
+
+    csidl = CSIDL_COMMON_APPDATA;
+    // e.g., c:/Documents and Settings/All Users/Application Data/Panda3D
+  }
+  string root = get_csidl_dir(csidl);
+  if (!root.empty()) {
+    return root;
+  }
+
+  // Hmm, if that failed, try the "Temporary Internet Files" folder.
+  root = get_csidl_dir(CSIDL_INTERNET_CACHE);
+  if (!root.empty()) {
+    return root;
+  }
+  
+  // If we couldn't get any of those folders, huh.  Punt and try for
+  // Temp, for lack of a better place.
+  static const int buffer_size = MAX_PATH;
+  char buffer[buffer_size];
+  if (GetTempPath(buffer_size, buffer) != 0) {
+    string root = buffer;
+    root += string("Panda3D");
+    
+    // Attempt to make it first, if possible.
+    CreateDirectory(root.c_str(), NULL);
+    
+    bool isdir = false;
+    DWORD results = GetFileAttributes(root.c_str());
+    if (results != -1) {
+      isdir = (results & FILE_ATTRIBUTE_DIRECTORY) != 0;
+    }
+    
+    if (isdir) {
+      // The directory exists!
+      return root;
+    }
+  }
+
 #else  // _WIN32
   // e.g., /home/<username>/.panda3d
 
   string root;
-  const char* uname = getlogin();
+  const char *uname = getlogin();
   if (uname == NULL) uname = getenv("USER");
 
-  const passwd* pwdata = getpwnam(uname);
+  const passwd *pwdata = getpwnam(uname);
   if (pwdata == NULL) {
     root = getenv("HOME");
   } else {