diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index 660b43f361..7ef85d1757 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -91,7 +91,7 @@ #define INSTALL_HEADERS \ p3d_plugin.h - #define WIN_SYS_LIBS user32.lib gdi32.lib shell32.lib comctl32.lib msimg32.lib + #define WIN_SYS_LIBS user32.lib gdi32.lib shell32.lib comctl32.lib msimg32.lib ole32.lib #end lib_target diff --git a/direct/src/plugin/find_root_dir.cxx b/direct/src/plugin/find_root_dir.cxx index a615f7474c..e67c633d25 100755 --- a/direct/src/plugin/find_root_dir.cxx +++ b/direct/src/plugin/find_root_dir.cxx @@ -25,9 +25,6 @@ #include #endif -#include -using namespace std; - #ifdef _WIN32 //////////////////////////////////////////////////////////////////// @@ -73,17 +70,60 @@ get_csidl_dir(int csidl) { } #endif // _WIN32 +#ifdef _WIN32 +//////////////////////////////////////////////////////////////////// +// Function: wstr_to_string +// Description: Converts Windows' LPWSTR to a std::string. +//////////////////////////////////////////////////////////////////// +static bool +wstr_to_string(string &result, const LPWSTR wstr) { + bool success = false; + int size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, + NULL, 0, NULL, NULL); + if (size > 0) { + char *buffer = new char[size]; + int rc = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, + buffer, size, NULL, NULL); + if (rc != 0) { + buffer[size - 1] = 0; + result = buffer; + success = true; + } + delete[] buffer; + } + + return success; +} +#endif // _WIN32 + //////////////////////////////////////////////////////////////////// // Function: find_root_dir // Description: Returns the path to the installable Panda3D directory // on the user's machine. //////////////////////////////////////////////////////////////////// string -find_root_dir() { +find_root_dir(ostream &logfile) { #ifdef _WIN32 - // TODO: use IEIsProtectedModeProcess() to determine if we are - // running in IE's "protected mode" here. + // First, use IEIsProtectedModeProcess() to determine if we are + // running in IE's "protected mode". + bool is_protected = false; + HMODULE module = LoadLibrary("ieframe.dll"); + if (module != NULL) { + typedef HRESULT STDAPICALLTYPE IEIsProtectedModeProcess(BOOL *pbResult); + IEIsProtectedModeProcess *func = (IEIsProtectedModeProcess *)GetProcAddress(module, "IEIsProtectedModeProcess"); + if (func != NULL) { + BOOL result = false; + HRESULT hr = (*func)(&result); + if (hr == S_OK) { + is_protected = (result != 0); + logfile << "IEIsProtectedModeProcess indicates: " << is_protected << "\n"; + } + // Any other return value means some error, especially + // E_NOTIMPL, which means we're not running under Vista. In + // this case we can assume we're not running in protected mode. + } + } int csidl = CSIDL_APPDATA; // e.g., c:/Documents and Settings//Application Data/Panda3D @@ -98,10 +138,60 @@ find_root_dir() { } string root = get_csidl_dir(csidl); if (!root.empty()) { + if (module != NULL) { + FreeLibrary(module); + } return root; } - // Hmm, if that failed, try the "Temporary Internet Files" folder. + // All right, couldn't get a writable pointer to our APPDATA folder. + // We're in fallback mode now. Start by asking for a "writeable + // path" to a temporary folder. + if (module != NULL) { + typedef HRESULT STDAPICALLTYPE IEGetWriteableFolderPath(REFGUID clsidFolderID, LPWSTR* lppwstrPath); + IEGetWriteableFolderPath *func = (IEGetWriteableFolderPath *)GetProcAddress(module, "IEGetWriteableFolderPath"); + if (func != NULL) { + // From KnownFolders.h (part of Vista SDK): +#define DEFINE_KNOWN_FOLDER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + DEFINE_KNOWN_FOLDER(FOLDERID_InternetCache, 0x352481E8, 0x33BE, 0x4251, 0xBA, 0x85, 0x60, 0x07, 0xCA, 0xED, 0xCF, 0x9D); + + LPWSTR cache_path = NULL; + HRESULT hr = (*func)(FOLDERID_InternetCache, &cache_path); + if (SUCCEEDED(hr)) { + if (!wstr_to_string(root, cache_path)) { + // Couldn't decode the LPWSTR. + CoTaskMemFree(cache_path); + } else { + CoTaskMemFree(cache_path); + 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! + FreeLibrary(module); + return root; + } + } + } + } + } + + // We're done with the HMODULE now. + if (module != NULL) { + FreeLibrary(module); + } + + // All right, GetWriteableFolderPath failed; fall back to the XP-era + // way of asking for the "Temporary Internet Files". root = get_csidl_dir(CSIDL_INTERNET_CACHE); if (!root.empty()) { return root; diff --git a/direct/src/plugin/find_root_dir.h b/direct/src/plugin/find_root_dir.h index d4e093c633..f05602672e 100755 --- a/direct/src/plugin/find_root_dir.h +++ b/direct/src/plugin/find_root_dir.h @@ -16,8 +16,9 @@ #define FIND_ROOT_DIR_H #include +#include using namespace std; -string find_root_dir(); +string find_root_dir(ostream &logfile); #endif diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index 0fdd06c206..23acccba3d 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/direct/src/plugin/p3dInstanceManager.cxx @@ -170,7 +170,6 @@ initialize(const string &contents_filename, const string &download_url, const string &platform, const string &log_directory, const string &log_basename, bool trusted_environment) { _trusted_environment = trusted_environment; - _root_dir = find_root_dir(); _verify_contents = verify_contents; _platform = platform; if (_platform.empty()) { @@ -247,14 +246,19 @@ initialize(const string &contents_filename, const string &download_url, _log_pathname = _log_directory; _log_pathname += _log_basename; _log_pathname += ".log"; + cerr << "_log_pathname = " << _log_pathname << "\n"; + logfile.clear(); logfile.open(_log_pathname.c_str(), ios::out | ios::trunc); if (logfile) { logfile.setf(ios::unitbuf); nout_stream = &logfile; + cerr << "log correct\n"; } } + _root_dir = find_root_dir(nout); + nout << "_root_dir = " << _root_dir << ", platform = " << _platform << ", contents_filename = " << contents_filename diff --git a/direct/src/plugin_npapi/Sources.pp b/direct/src/plugin_npapi/Sources.pp index 35b72ad611..3c047bf1d4 100644 --- a/direct/src/plugin_npapi/Sources.pp +++ b/direct/src/plugin_npapi/Sources.pp @@ -36,7 +36,7 @@ #if $[WINDOWS_PLATFORM] #define WIN_RESOURCE_FILE nppanda3d.rc #define LINKER_DEF_FILE nppanda3d.def - #define WIN_SYS_LIBS user32.lib shell32.lib + #define WIN_SYS_LIBS user32.lib shell32.lib ole32.lib #endif // Mac-specific options. diff --git a/direct/src/plugin_npapi/ppInstance.cxx b/direct/src/plugin_npapi/ppInstance.cxx index e237837673..6f2388d762 100644 --- a/direct/src/plugin_npapi/ppInstance.cxx +++ b/direct/src/plugin_npapi/ppInstance.cxx @@ -61,7 +61,7 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode, _tokens.push_back(token); } - _root_dir = find_root_dir(); + _root_dir = find_root_dir(nout); _got_instance_url = false; _got_window = false; diff --git a/direct/src/plugin_npapi/startup.cxx b/direct/src/plugin_npapi/startup.cxx index dd3006310b..07d5829729 100644 --- a/direct/src/plugin_npapi/startup.cxx +++ b/direct/src/plugin_npapi/startup.cxx @@ -61,6 +61,7 @@ open_logfile() { log_pathname += log_basename; log_pathname += ".log"; + logfile.clear(); logfile.open(log_pathname.c_str()); logfile.setf(ios::unitbuf); } diff --git a/direct/src/plugin_standalone/Sources.pp b/direct/src/plugin_standalone/Sources.pp index aa18233d22..af17f234d6 100644 --- a/direct/src/plugin_standalone/Sources.pp +++ b/direct/src/plugin_standalone/Sources.pp @@ -19,6 +19,6 @@ #define SOURCES \ panda3d.cxx panda3d.h panda3d.I - #define WIN_SYS_LIBS user32.lib gdi32.lib shell32.lib + #define WIN_SYS_LIBS user32.lib gdi32.lib shell32.lib ole32.lib #end bin_target diff --git a/direct/src/plugin_standalone/panda3d.cxx b/direct/src/plugin_standalone/panda3d.cxx index 0dc7b5abc9..73efbd5ee2 100644 --- a/direct/src/plugin_standalone/panda3d.cxx +++ b/direct/src/plugin_standalone/panda3d.cxx @@ -48,7 +48,7 @@ static const double wait_cycle = 0.2; //////////////////////////////////////////////////////////////////// Panda3D:: Panda3D() { - _root_dir = find_root_dir(); + _root_dir = find_root_dir(nout); _reporting_download = false; }