mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
wip: support windows unicode filenames in plugin
This commit is contained in:
parent
2c7f1498b3
commit
9150bd2f6c
@ -34,6 +34,7 @@
|
||||
handleStreamBuf.cxx handleStreamBuf.h handleStreamBuf.I \
|
||||
mkdir_complete.cxx mkdir_complete.h \
|
||||
parse_color.cxx parse_color.h \
|
||||
wstring_encode.cxx wstring_encode.h \
|
||||
p3d_lock.h p3d_plugin.h \
|
||||
p3d_plugin_config.h \
|
||||
p3d_plugin_common.h \
|
||||
@ -172,6 +173,11 @@
|
||||
#endif
|
||||
#define TARGET p3dcert
|
||||
|
||||
#define SOURCES $[SOURCES] \
|
||||
is_pathsep.h is_pathsep.I \
|
||||
wstring_encode.cxx wstring_encode.h \
|
||||
mkdir_complete.cxx mkdir_complete.h
|
||||
|
||||
#define OSX_SYS_FRAMEWORKS Carbon
|
||||
|
||||
#end bin_target
|
||||
@ -185,7 +191,9 @@
|
||||
is_pathsep.h is_pathsep.I \
|
||||
mkdir_complete.cxx mkdir_complete.h \
|
||||
get_twirl_data.cxx get_twirl_data.h \
|
||||
parse_color.cxx parse_color.h
|
||||
parse_color.cxx parse_color.h \
|
||||
wstring_encode.cxx wstring_encode.h
|
||||
|
||||
|
||||
#begin static_lib_target
|
||||
//
|
||||
|
@ -13,6 +13,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "fileSpec.h"
|
||||
#include "wstring_encode.h"
|
||||
#include "openssl/md5.h"
|
||||
|
||||
#include <fstream>
|
||||
@ -26,8 +27,6 @@
|
||||
#ifdef _WIN32
|
||||
#include <sys/utime.h>
|
||||
#include <direct.h>
|
||||
#define stat _stat
|
||||
#define utime _utime
|
||||
#define utimbuf _utimbuf
|
||||
|
||||
#else
|
||||
@ -137,7 +136,7 @@ store_xml(TiXmlElement *xelement) {
|
||||
xelement->SetAttribute("size", _size);
|
||||
}
|
||||
if (_timestamp != 0) {
|
||||
xelement->SetAttribute("timestamp", _timestamp);
|
||||
xelement->SetAttribute("timestamp", (int)_timestamp);
|
||||
}
|
||||
if (_got_hash) {
|
||||
char hash[hash_size * 2 + 1];
|
||||
@ -177,8 +176,19 @@ quick_verify_pathname(const string &pathname) {
|
||||
_actual_file = NULL;
|
||||
}
|
||||
|
||||
int result = 1;
|
||||
#ifdef _WIN32
|
||||
struct _stat st;
|
||||
wstring pathname_w;
|
||||
if (string_to_wstring(pathname_w, pathname)) {
|
||||
result = _wstat(pathname_w.c_str(), &st);
|
||||
}
|
||||
#else // _WIN32
|
||||
struct stat st;
|
||||
if (stat(pathname.c_str(), &st) != 0) {
|
||||
result = stat(pathname.c_str(), &st);
|
||||
#endif // _WIN32
|
||||
|
||||
if (result != 0) {
|
||||
//cerr << "file not found: " << _filename << "\n";
|
||||
return false;
|
||||
}
|
||||
@ -213,7 +223,12 @@ quick_verify_pathname(const string &pathname) {
|
||||
utimbuf utb;
|
||||
utb.actime = st.st_atime;
|
||||
utb.modtime = _timestamp;
|
||||
|
||||
#ifdef _WIN32
|
||||
_wutime(pathname_w.c_str(), &utb);
|
||||
#else // _WIN32
|
||||
utime(pathname.c_str(), &utb);
|
||||
#endif // _WIN32
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -237,8 +252,19 @@ full_verify(const string &package_dir) {
|
||||
}
|
||||
|
||||
string pathname = get_pathname(package_dir);
|
||||
int result = 1;
|
||||
#ifdef _WIN32
|
||||
struct _stat st;
|
||||
wstring pathname_w;
|
||||
if (string_to_wstring(pathname_w, pathname)) {
|
||||
result = _wstat(pathname_w.c_str(), &st);
|
||||
}
|
||||
#else // _WIN32
|
||||
struct stat st;
|
||||
if (stat(pathname.c_str(), &st) != 0) {
|
||||
result = stat(pathname.c_str(), &st);
|
||||
#endif // _WIN32
|
||||
|
||||
if (result != 0) {
|
||||
//cerr << "file not found: " << _filename << "\n";
|
||||
return false;
|
||||
}
|
||||
@ -265,7 +291,11 @@ full_verify(const string &package_dir) {
|
||||
utimbuf utb;
|
||||
utb.actime = st.st_atime;
|
||||
utb.modtime = _timestamp;
|
||||
#ifdef _WIN32
|
||||
_wutime(pathname_w.c_str(), &utb);
|
||||
#else // _WIN32
|
||||
utime(pathname.c_str(), &utb);
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -298,7 +328,16 @@ read_hash(const string &pathname) {
|
||||
memset(_hash, 0, hash_size);
|
||||
_got_hash = false;
|
||||
|
||||
ifstream stream(pathname.c_str(), ios::in | ios::binary);
|
||||
ifstream stream;
|
||||
#ifdef _WIN32
|
||||
wstring pathname_w;
|
||||
if (string_to_wstring(pathname_w, pathname)) {
|
||||
stream.open(pathname_w.c_str(), ios::in | ios::binary);
|
||||
}
|
||||
#else // _WIN32
|
||||
stream.open(pathname.c_str(), ios::in | ios::binary);
|
||||
#endif // _WIN32
|
||||
|
||||
if (!stream) {
|
||||
//cerr << "unable to read " << pathname << "\n";
|
||||
return false;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "find_root_dir.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "get_tinyxml.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@ -39,68 +40,41 @@ DEFINE_KNOWN_FOLDER(FOLDERID_InternetCache, 0x352481E8, 0x33BE, 0x4251, 0xBA, 0x
|
||||
|
||||
#ifdef _WIN32
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_csidl_dir
|
||||
// Function: get_csidl_dir_w
|
||||
// Description: A wrapper around SHGetSpecialFolderPath(), to return
|
||||
// the Panda3D directory under the indicated CSIDL
|
||||
// folder.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static string
|
||||
get_csidl_dir(int csidl) {
|
||||
static wstring
|
||||
get_csidl_dir_w(int csidl) {
|
||||
static const int buffer_size = MAX_PATH;
|
||||
char buffer[buffer_size];
|
||||
if (SHGetSpecialFolderPath(NULL, buffer, csidl, true)) {
|
||||
string root = buffer;
|
||||
root += string("/Panda3D");
|
||||
wchar_t buffer[buffer_size];
|
||||
if (SHGetSpecialFolderPathW(NULL, buffer, csidl, true)) {
|
||||
wstring root = buffer;
|
||||
root += wstring(L"/Panda3D");
|
||||
|
||||
if (mkdir_complete(root, cerr)) {
|
||||
if (mkdir_complete_w(root, cerr)) {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
// Something went wrong.
|
||||
return string();
|
||||
return wstring();
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef _WIN32
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wstr_to_string
|
||||
// Description: Converts Windows' LPWSTR to a std::string.
|
||||
// Function: find_root_dir_default_w
|
||||
// Description: Wide-character implementation of
|
||||
// find_root_dir_default(), only needed for Windows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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_default
|
||||
// Description: Returns the path to the system-default for the root
|
||||
// directory. This is where we look first.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static string
|
||||
find_root_dir_default() {
|
||||
#ifdef _WIN32
|
||||
static wstring
|
||||
find_root_dir_default_w() {
|
||||
// First, use IEIsProtectedModeProcess() to determine if we are
|
||||
// running in IE's "protected mode" under Vista.
|
||||
|
||||
string root;
|
||||
wstring root;
|
||||
bool is_protected = false;
|
||||
HMODULE ieframe = LoadLibrary("ieframe.dll");
|
||||
if (ieframe != NULL) {
|
||||
@ -139,18 +113,14 @@ find_root_dir_default() {
|
||||
HRESULT hr = (*func)(FOLDERID_LocalAppDataLow, 0, NULL, &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 = cache_path;
|
||||
CoTaskMemFree(cache_path);
|
||||
|
||||
root += string("/Panda3D");
|
||||
if (mkdir_complete(root, cerr)) {
|
||||
FreeLibrary(shell32);
|
||||
FreeLibrary(ieframe);
|
||||
return root;
|
||||
}
|
||||
root += wstring(L"/Panda3D");
|
||||
if (mkdir_complete_w(root, cerr)) {
|
||||
FreeLibrary(shell32);
|
||||
FreeLibrary(ieframe);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,16 +144,12 @@ find_root_dir_default() {
|
||||
}
|
||||
|
||||
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");
|
||||
if (mkdir_complete(root, cerr)) {
|
||||
FreeLibrary(ieframe);
|
||||
return root;
|
||||
}
|
||||
root = cache_path;
|
||||
CoTaskMemFree(cache_path);
|
||||
root += wstring(L"/Panda3D");
|
||||
if (mkdir_complete_w(root, cerr)) {
|
||||
FreeLibrary(ieframe);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -196,7 +162,7 @@ find_root_dir_default() {
|
||||
// also the normal XP codepath.
|
||||
|
||||
// e.g., c:/Documents and Settings/<username>/Local Settings/Application Data/Panda3D
|
||||
root = get_csidl_dir(CSIDL_LOCAL_APPDATA);
|
||||
root = get_csidl_dir_w(CSIDL_LOCAL_APPDATA);
|
||||
if (!root.empty()) {
|
||||
return root;
|
||||
}
|
||||
@ -205,7 +171,7 @@ find_root_dir_default() {
|
||||
// back to the cache folder.
|
||||
|
||||
// e.g. c:/Documents and Settings/<username>/Local Settings/Temporary Internet Files/Panda3D
|
||||
root = get_csidl_dir(CSIDL_INTERNET_CACHE);
|
||||
root = get_csidl_dir_w(CSIDL_INTERNET_CACHE);
|
||||
if (!root.empty()) {
|
||||
return root;
|
||||
}
|
||||
@ -213,11 +179,32 @@ find_root_dir_default() {
|
||||
// If we couldn't get any of those folders, huh. Punt and try for
|
||||
// the old standby GetTempPath, for lack of anything better.
|
||||
static const int buffer_size = MAX_PATH;
|
||||
char buffer[buffer_size];
|
||||
if (GetTempPath(buffer_size, buffer) != 0) {
|
||||
wchar_t buffer[buffer_size];
|
||||
if (GetTempPathW(buffer_size, buffer) != 0) {
|
||||
root = buffer;
|
||||
root += string("Panda3D");
|
||||
if (mkdir_complete(root, cerr)) {
|
||||
root += wstring(L"Panda3D");
|
||||
if (mkdir_complete_w(root, cerr)) {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
return wstring();
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: find_root_dir_default
|
||||
// Description: Returns the path to the system-default for the root
|
||||
// directory. This is where we look first.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static string
|
||||
find_root_dir_default() {
|
||||
#ifdef _WIN32
|
||||
wstring root_w = find_root_dir_default_w();
|
||||
if (!root_w.empty()) {
|
||||
string root;
|
||||
if (wstring_to_string(root, root_w)) {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool
|
||||
is_pathsep(char ch) {
|
||||
is_pathsep(int ch) {
|
||||
if (ch == '/') {
|
||||
return true;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define IS_PATHSEP_H
|
||||
|
||||
inline bool
|
||||
is_pathsep(char ch);
|
||||
is_pathsep(int ch);
|
||||
|
||||
#include "is_pathsep.I"
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "load_plugin.h"
|
||||
#include "p3d_plugin_config.h"
|
||||
#include "is_pathsep.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
@ -168,7 +169,10 @@ load_plugin(const string &p3d_plugin_filename,
|
||||
}
|
||||
|
||||
SetErrorMode(0);
|
||||
module = LoadLibrary(filename.c_str());
|
||||
wstring filename_w;
|
||||
if (string_to_wstring(filename_w, filename)) {
|
||||
module = LoadLibraryW(filename_w.c_str());
|
||||
}
|
||||
dso_needs_unload = true;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "mkdir_complete.h"
|
||||
#include "is_pathsep.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@ -46,6 +47,26 @@ get_dirname(const string &filename) {
|
||||
return string();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_dirname_w
|
||||
// Description: The wide-character implementation of get_dirname().
|
||||
// Only implemented (and needed) on Windows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static wstring
|
||||
get_dirname_w(const wstring &filename) {
|
||||
size_t p = filename.length();
|
||||
while (p > 0) {
|
||||
--p;
|
||||
if (is_pathsep(filename[p])) {
|
||||
return filename.substr(0, p);
|
||||
}
|
||||
}
|
||||
|
||||
return wstring();
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -58,32 +79,11 @@ get_dirname(const string &filename) {
|
||||
bool
|
||||
mkdir_complete(const string &dirname, ostream &logfile) {
|
||||
#ifdef _WIN32
|
||||
if (CreateDirectory(dirname.c_str(), NULL) != 0) {
|
||||
// Success!
|
||||
return true;
|
||||
wstring dirname_w;
|
||||
if (!string_to_wstring(dirname_w, dirname)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Failed.
|
||||
DWORD last_error = GetLastError();
|
||||
if (last_error == ERROR_ALREADY_EXISTS) {
|
||||
// Not really an error: the directory is already there.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (last_error == ERROR_PATH_NOT_FOUND) {
|
||||
// We need to make the parent directory first.
|
||||
string parent = get_dirname(dirname);
|
||||
if (!parent.empty() && mkdir_complete(parent, logfile)) {
|
||||
// Parent successfully created. Try again to make the child.
|
||||
if (CreateDirectory(dirname.c_str(), NULL) != 0) {
|
||||
// Got it!
|
||||
return true;
|
||||
}
|
||||
logfile
|
||||
<< "Couldn't create " << dirname << "\n";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return mkdir_complete_w(dirname_w, logfile);
|
||||
|
||||
#else //_WIN32
|
||||
if (mkdir(dirname.c_str(), 0755) == 0) {
|
||||
@ -125,36 +125,16 @@ mkdir_complete(const string &dirname, ostream &logfile) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
mkfile_complete(const string &filename, ostream &logfile) {
|
||||
// Make sure we delete any previously-existing file first.
|
||||
#ifdef _WIN32
|
||||
// Windows can't delete a file if it's read-only. Weird.
|
||||
chmod(filename.c_str(), 0644);
|
||||
#endif
|
||||
wstring filename_w;
|
||||
if (!string_to_wstring(filename_w, filename)) {
|
||||
return false;
|
||||
}
|
||||
return mkfile_complete_w(filename_w, logfile);
|
||||
#else // _WIN32
|
||||
// Make sure we delete any previously-existing file first.
|
||||
unlink(filename.c_str());
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE file = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
// Try to make the parent directory first.
|
||||
string parent = get_dirname(filename);
|
||||
if (!parent.empty() && mkdir_complete(parent, logfile)) {
|
||||
// Parent successfully created. Try again to make the file.
|
||||
file = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
logfile
|
||||
<< "Couldn't create " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
return true;
|
||||
|
||||
#else // _WIN32
|
||||
int fd = creat(filename.c_str(), 0755);
|
||||
if (fd == -1) {
|
||||
// Try to make the parent directory first.
|
||||
@ -174,3 +154,80 @@ mkfile_complete(const string &filename, ostream &logfile) {
|
||||
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: mkdir_complete_w
|
||||
// Description: The wide-character implementation of
|
||||
// mkdir_complete(). Only implemented (and needed) on
|
||||
// Windows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
mkdir_complete_w(const wstring &dirname, ostream &logfile) {
|
||||
if (CreateDirectoryW(dirname.c_str(), NULL) != 0) {
|
||||
// Success!
|
||||
return true;
|
||||
}
|
||||
|
||||
// Failed.
|
||||
DWORD last_error = GetLastError();
|
||||
if (last_error == ERROR_ALREADY_EXISTS) {
|
||||
// Not really an error: the directory is already there.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (last_error == ERROR_PATH_NOT_FOUND) {
|
||||
// We need to make the parent directory first.
|
||||
wstring parent = get_dirname_w(dirname);
|
||||
if (!parent.empty() && mkdir_complete_w(parent, logfile)) {
|
||||
// Parent successfully created. Try again to make the child.
|
||||
if (CreateDirectoryW(dirname.c_str(), NULL) != 0) {
|
||||
// Got it!
|
||||
return true;
|
||||
}
|
||||
logfile
|
||||
<< "Couldn't create " << dirname << "\n";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef _WIN32
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: mkfile_complete_w
|
||||
// Description: The wide-character implementation of
|
||||
// mkfile_complete(). Only implemented (and needed) on
|
||||
// Windows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
mkfile_complete_w(const wstring &filename, ostream &logfile) {
|
||||
// Make sure we delete any previously-existing file first.
|
||||
|
||||
// Windows can't delete a file if it's read-only. Weird.
|
||||
_wchmod(filename.c_str(), 0644);
|
||||
_wunlink(filename.c_str());
|
||||
|
||||
HANDLE file = CreateFileW(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
// Try to make the parent directory first.
|
||||
wstring parent = get_dirname_w(filename);
|
||||
if (!parent.empty() && mkdir_complete_w(parent, logfile)) {
|
||||
// Parent successfully created. Try again to make the file.
|
||||
file = CreateFileW(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
logfile
|
||||
<< "Couldn't create " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
return true;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
@ -22,6 +22,11 @@ using namespace std;
|
||||
bool mkdir_complete(const string &dirname, ostream &logfile);
|
||||
bool mkfile_complete(const string &dirname, ostream &logfile);
|
||||
|
||||
#ifdef _WIN32
|
||||
bool mkdir_complete_w(const wstring &dirname, ostream &logfile);
|
||||
bool mkfile_complete_w(const wstring &dirname, ostream &logfile);
|
||||
#endif // _WIN32
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "p3dMultifileReader.h"
|
||||
#include "p3d_plugin_config.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@ -331,15 +332,18 @@ win_create_process() {
|
||||
// Make sure we see an error dialog if there is a missing DLL.
|
||||
SetErrorMode(0);
|
||||
|
||||
STARTUPINFO startup_info;
|
||||
ZeroMemory(&startup_info, sizeof(STARTUPINFO));
|
||||
STARTUPINFOW startup_info;
|
||||
ZeroMemory(&startup_info, sizeof(startup_info));
|
||||
startup_info.cb = sizeof(startup_info);
|
||||
|
||||
// Make sure the initial window is *shown* for this graphical app.
|
||||
startup_info.wShowWindow = SW_SHOW;
|
||||
startup_info.dwFlags |= STARTF_USESHOWWINDOW;
|
||||
|
||||
const char *start_dir_cstr = _start_dir.c_str();
|
||||
const wchar_t *start_dir_cstr;
|
||||
wstring start_dir_w;
|
||||
string_to_wstring(start_dir_w, _start_dir);
|
||||
start_dir_cstr = start_dir_w.c_str();
|
||||
|
||||
// Construct the command-line string, containing the quoted
|
||||
// command-line arguments.
|
||||
@ -351,14 +355,17 @@ win_create_process() {
|
||||
// I'm not sure why CreateProcess wants a non-const char pointer for
|
||||
// its command-line string, but I'm not taking chances. It gets a
|
||||
// non-const char array that it can modify.
|
||||
string command_line_str = stream.str();
|
||||
nout << "command is: " << command_line_str << "\n";
|
||||
char *command_line = new char[command_line_str.size() + 1];
|
||||
strcpy(command_line, command_line_str.c_str());
|
||||
wstring command_line_str;
|
||||
string_to_wstring(command_line_str, stream.str());
|
||||
wchar_t *command_line = new wchar_t[command_line_str.size() + 1];
|
||||
memcpy(command_line, command_line_str.c_str(), sizeof(wchar_t) * command_line_str.size() + 1);
|
||||
|
||||
wstring p3dcert_exe_w;
|
||||
string_to_wstring(p3dcert_exe_w, _p3dcert_exe);
|
||||
|
||||
PROCESS_INFORMATION process_info;
|
||||
BOOL result = CreateProcess
|
||||
(_p3dcert_exe.c_str(), command_line, NULL, NULL, TRUE, 0,
|
||||
BOOL result = CreateProcessW
|
||||
(p3dcert_exe_w.c_str(), command_line, NULL, NULL, TRUE, 0,
|
||||
(void *)_env.c_str(), start_dir_cstr,
|
||||
&startup_info, &process_info);
|
||||
bool started_program = (result != 0);
|
||||
|
@ -13,6 +13,8 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "p3dCert.h"
|
||||
#include "wstring_encode.h"
|
||||
#include "mkdir_complete.h"
|
||||
|
||||
#include <Fl/Fl_Box.H>
|
||||
#include <Fl/Fl_Button.H>
|
||||
@ -198,21 +200,26 @@ approve_cert() {
|
||||
assert(_cert != NULL);
|
||||
|
||||
// Make sure the directory exists.
|
||||
#ifdef _WIN32
|
||||
mkdir(_cert_dir.c_str());
|
||||
#else
|
||||
mkdir(_cert_dir.c_str(), 0755);
|
||||
#endif
|
||||
mkdir_complete(_cert_dir, cerr);
|
||||
|
||||
// Look for an unused filename.
|
||||
int i = 1;
|
||||
char buf [PATH_MAX];
|
||||
size_t buf_length = _cert_dir.length() + 100;
|
||||
char *buf = new char[buf_length];
|
||||
#ifdef _WIN32
|
||||
wstring buf_w;
|
||||
#endif // _WIN32
|
||||
|
||||
while (true) {
|
||||
sprintf(buf, "%s/p%d.crt", _cert_dir.c_str(), i);
|
||||
assert(strlen(buf) < buf_length);
|
||||
|
||||
// Check if it already exists. If not, take it.
|
||||
#ifdef _WIN32
|
||||
DWORD results = GetFileAttributes(buf);
|
||||
DWORD results = 0;
|
||||
if (string_to_wstring(buf_w, buf)) {
|
||||
results = GetFileAttributesW(buf_w.c_str());
|
||||
}
|
||||
if (results == -1) {
|
||||
break;
|
||||
}
|
||||
@ -227,11 +234,17 @@ approve_cert() {
|
||||
|
||||
// Sure, there's a slight race condition right now: another process
|
||||
// might attempt to create the same filename. So what.
|
||||
FILE *fp = fopen(buf, "w");
|
||||
FILE *fp = NULL;
|
||||
#ifdef _WIN32
|
||||
fp = _wfopen(buf_w.c_str(), L"w");
|
||||
#else // _WIN32
|
||||
fp = fopen(buf, "w");
|
||||
#endif // _WIN32
|
||||
if (fp != NULL) {
|
||||
PEM_write_X509(fp, _cert);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
hide();
|
||||
}
|
||||
|
||||
@ -243,7 +256,16 @@ approve_cert() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AuthDialog::
|
||||
read_cert_file(const string &cert_filename) {
|
||||
FILE *fp = fopen(cert_filename.c_str(), "r");
|
||||
FILE *fp = NULL;
|
||||
#ifdef _WIN32
|
||||
wstring cert_filename_w;
|
||||
if (string_to_wstring(cert_filename_w, cert_filename)) {
|
||||
fp = _wfopen(cert_filename_w.c_str(), L"r");
|
||||
}
|
||||
#else // _WIN32
|
||||
fp = fopen(cert_filename.c_str(), "r");
|
||||
#endif // _WIN32
|
||||
|
||||
if (fp == NULL) {
|
||||
cerr << "Couldn't read " << cert_filename.c_str() << "\n";
|
||||
return;
|
||||
|
@ -13,6 +13,9 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "p3dCert_wx.h"
|
||||
#include "wstring_encode.h"
|
||||
#include "mkdir_complete.h"
|
||||
|
||||
#include "wx/cmdline.h"
|
||||
#include "wx/filename.h"
|
||||
|
||||
@ -229,26 +232,52 @@ approve_cert() {
|
||||
assert(_cert != NULL);
|
||||
|
||||
// Make sure the directory exists.
|
||||
wxFileName::Mkdir(_cert_dir, 0777, wxPATH_MKDIR_FULL);
|
||||
string cert_dir_str = (const char *)_cert_dir.mb_str();
|
||||
mkdir_complete(cert_dir_str, cerr);
|
||||
|
||||
// Look for an unused filename.
|
||||
wxString pathname;
|
||||
int i = 1;
|
||||
size_t buf_length = _cert_dir.length() + 100;
|
||||
char *buf = new char[buf_length];
|
||||
#ifdef _WIN32
|
||||
wstring buf_w;
|
||||
#endif // _WIN32
|
||||
|
||||
while (true) {
|
||||
pathname.Printf(wxT("%s/p%d.crt"), _cert_dir.c_str(), i);
|
||||
if (!wxFileName::FileExists(pathname)) {
|
||||
sprintf(buf, "%s/p%d.crt", _cert_dir.c_str(), i);
|
||||
assert(strlen(buf) < buf_length);
|
||||
|
||||
// Check if it already exists. If not, take it.
|
||||
#ifdef _WIN32
|
||||
DWORD results = 0;
|
||||
if (string_to_wstring(buf_w, buf)) {
|
||||
results = GetFileAttributesW(buf_w.c_str());
|
||||
}
|
||||
if (results == -1) {
|
||||
break;
|
||||
}
|
||||
#else
|
||||
struct stat statbuf;
|
||||
if (stat(buf, &statbuf) != 0) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
++i;
|
||||
}
|
||||
|
||||
// Sure, there's a slight race condition right now: another process
|
||||
// might attempt to create the same filename. So what.
|
||||
FILE *fp = fopen(pathname.mb_str(), "w");
|
||||
FILE *fp = NULL;
|
||||
#ifdef _WIN32
|
||||
fp = _wfopen(buf_w.c_str(), L"w");
|
||||
#else // _WIN32
|
||||
fp = fopen(buf, "w");
|
||||
#endif // _WIN32
|
||||
if (fp != NULL) {
|
||||
PEM_write_X509(fp, _cert);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
||||
@ -260,7 +289,16 @@ approve_cert() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AuthDialog::
|
||||
read_cert_file(const wxString &cert_filename) {
|
||||
FILE *fp = fopen(cert_filename.mb_str(), "r");
|
||||
FILE *fp = NULL;
|
||||
#ifdef _WIN32
|
||||
wstring cert_filename_w;
|
||||
if (string_to_wstring(cert_filename_w, (const char *)cert_filename.mb_str())) {
|
||||
fp = _wfopen(cert_filename_w.c_str(), L"r");
|
||||
}
|
||||
#else // _WIN32
|
||||
fp = fopen(cert_filename.mb_str(), "r");
|
||||
#endif // _WIN32
|
||||
|
||||
if (fp == NULL) {
|
||||
cerr << "Couldn't read " << cert_filename.mb_str() << "\n";
|
||||
return;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "p3dFileDownload.h"
|
||||
#include "p3dInstanceManager.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DFileDownload::Constructor
|
||||
@ -64,7 +65,14 @@ open_file() {
|
||||
}
|
||||
|
||||
_file.clear();
|
||||
#ifdef _WIN32
|
||||
wstring filename_w;
|
||||
if (string_to_wstring(filename_w, _filename)) {
|
||||
_file.open(filename_w.c_str(), ios::out | ios::trunc | ios::binary);
|
||||
}
|
||||
#else // _WIN32
|
||||
_file.open(_filename.c_str(), ios::out | ios::trunc | ios::binary);
|
||||
#endif // _WIN32
|
||||
if (!_file) {
|
||||
nout << "Failed to open " << _filename << " in write mode\n";
|
||||
return false;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "p3dInstanceManager.h"
|
||||
#include "p3dPackage.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "wstring_encode.h"
|
||||
#include "openssl/md5.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -772,7 +773,12 @@ standardize_filename(const string &filename) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DHost::
|
||||
copy_file(const string &from_filename, const string &to_filename) {
|
||||
ifstream in(from_filename.c_str(), ios::in | ios::binary);
|
||||
#ifdef _WIN32
|
||||
ifstream in;
|
||||
wstring from_filename_w;
|
||||
if (string_to_wstring(from_filename_w, from_filename)) {
|
||||
in.open(from_filename_w.c_str(), ios::in | ios::binary);
|
||||
}
|
||||
|
||||
// Copy to a temporary file first, in case (a) the filenames
|
||||
// actually refer to the same file, or (b) in case we have different
|
||||
@ -780,13 +786,66 @@ copy_file(const string &from_filename, const string &to_filename) {
|
||||
// partially overwriting the file should something go wrong.
|
||||
ostringstream strm;
|
||||
strm << to_filename << ".t";
|
||||
#ifdef _WIN32
|
||||
strm << GetCurrentProcessId() << "_" << GetCurrentThreadId();
|
||||
#else
|
||||
strm << getpid();
|
||||
#endif
|
||||
string temp_filename = strm.str();
|
||||
ofstream out(temp_filename.c_str(), ios::out | ios::binary);
|
||||
ofstream out;
|
||||
wstring temp_filename_w;
|
||||
if (string_to_wstring(temp_filename_w, temp_filename)) {
|
||||
out.open(temp_filename_w.c_str(), ios::out | ios::binary);
|
||||
}
|
||||
|
||||
static const size_t buffer_size = 4096;
|
||||
char buffer[buffer_size];
|
||||
|
||||
in.read(buffer, buffer_size);
|
||||
size_t count = in.gcount();
|
||||
while (count != 0) {
|
||||
out.write(buffer, count);
|
||||
if (out.fail()) {
|
||||
unlink(temp_filename.c_str());
|
||||
return false;
|
||||
}
|
||||
in.read(buffer, buffer_size);
|
||||
count = in.gcount();
|
||||
}
|
||||
out.close();
|
||||
|
||||
wstring to_filename_w;
|
||||
string_to_wstring(to_filename_w, to_filename);
|
||||
|
||||
if (!in.eof()) {
|
||||
_wunlink(temp_filename_w.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_wrename(temp_filename_w.c_str(), to_filename_w.c_str()) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_wunlink(to_filename_w.c_str());
|
||||
if (_wrename(temp_filename_w.c_str(), to_filename_w.c_str()) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_wunlink(temp_filename_w.c_str());
|
||||
return false;
|
||||
|
||||
#else // _WIN32
|
||||
|
||||
ifstream in;
|
||||
in.open(from_filename.c_str(), ios::in | ios::binary);
|
||||
|
||||
// Copy to a temporary file first, in case (a) the filenames
|
||||
// actually refer to the same file, or (b) in case we have different
|
||||
// processes writing to the same file, and (c) to prevent
|
||||
// partially overwriting the file should something go wrong.
|
||||
ostringstream strm;
|
||||
strm << to_filename << ".t";
|
||||
strm << getpid();
|
||||
|
||||
string temp_filename = strm.str();
|
||||
ofstream out;
|
||||
out.open(temp_filename.c_str(), ios::out | ios::binary);
|
||||
|
||||
static const size_t buffer_size = 4096;
|
||||
char buffer[buffer_size];
|
||||
@ -820,6 +879,7 @@ copy_file(const string &from_filename, const string &to_filename) {
|
||||
|
||||
unlink(temp_filename.c_str());
|
||||
return false;
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -833,13 +893,39 @@ save_xml_file(TiXmlDocument *doc, const string &to_filename) {
|
||||
// Save to a temporary file first, in case (a) we have different
|
||||
// processes writing to the same file, and (b) to prevent partially
|
||||
// overwriting the file should something go wrong.
|
||||
|
||||
#ifdef _WIN32
|
||||
ostringstream strm;
|
||||
strm << to_filename << ".t";
|
||||
#ifdef _WIN32
|
||||
strm << GetCurrentProcessId() << "_" << GetCurrentThreadId();
|
||||
#else
|
||||
string temp_filename = strm.str();
|
||||
|
||||
wstring temp_filename_w;
|
||||
string_to_wstring(temp_filename_w, temp_filename);
|
||||
wstring to_filename_w;
|
||||
string_to_wstring(to_filename_w, to_filename);
|
||||
|
||||
if (!doc->SaveFile(temp_filename.c_str())) {
|
||||
_wunlink(temp_filename_w.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_wrename(temp_filename_w.c_str(), to_filename_w.c_str()) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_wunlink(to_filename_w.c_str());
|
||||
if (_wrename(temp_filename_w.c_str(), to_filename_w.c_str()) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_wunlink(temp_filename_w.c_str());
|
||||
return false;
|
||||
|
||||
#else // _WIN32
|
||||
ostringstream strm;
|
||||
strm << to_filename << ".t";
|
||||
strm << getpid();
|
||||
#endif
|
||||
string temp_filename = strm.str();
|
||||
|
||||
if (!doc->SaveFile(temp_filename.c_str())) {
|
||||
@ -858,6 +944,7 @@ save_xml_file(TiXmlDocument *doc, const string &to_filename) {
|
||||
|
||||
unlink(temp_filename.c_str());
|
||||
return false;
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "get_tinyxml.h"
|
||||
#include "binaryXml.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
// We can include this header file to get the DTOOL_PLATFORM
|
||||
// definition, even though we don't link with dtool.
|
||||
@ -1034,9 +1035,12 @@ scan_directory(const string &dirname, vector<string> &contents) {
|
||||
size_t orig_size = contents.size();
|
||||
|
||||
string match = dirname + "\\*.*";
|
||||
WIN32_FIND_DATA find_data;
|
||||
WIN32_FIND_DATAW find_data;
|
||||
|
||||
HANDLE handle = FindFirstFile(match.c_str(), &find_data);
|
||||
wstring match_w;
|
||||
string_to_wstring(match_w, match);
|
||||
|
||||
HANDLE handle = FindFirstFileW(match_w.c_str(), &find_data);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
if (GetLastError() == ERROR_NO_MORE_FILES) {
|
||||
// No matching files is not an error.
|
||||
@ -1046,11 +1050,12 @@ scan_directory(const string &dirname, vector<string> &contents) {
|
||||
}
|
||||
|
||||
do {
|
||||
string filename = find_data.cFileName;
|
||||
string filename;
|
||||
wstring_to_string(filename, find_data.cFileName);
|
||||
if (filename != "." && filename != "..") {
|
||||
contents.push_back(filename);
|
||||
}
|
||||
} while (FindNextFile(handle, &find_data));
|
||||
} while (FindNextFileW(handle, &find_data));
|
||||
|
||||
bool scan_ok = (GetLastError() == ERROR_NO_MORE_FILES);
|
||||
FindClose(handle);
|
||||
@ -1146,14 +1151,23 @@ delete_directory_recursively(const string &root_dir) {
|
||||
if (!scan_directory_recursively(root_dir, contents, dirname_contents)) {
|
||||
// Maybe it's just a single file, not a directory. Delete it.
|
||||
#ifdef _WIN32
|
||||
wstring root_dir_w;
|
||||
string_to_wstring(root_dir_w, root_dir);
|
||||
// Windows can't delete a file if it's read-only.
|
||||
chmod(root_dir.c_str(), 0644);
|
||||
#endif
|
||||
_wchmod(root_dir_w.c_str(), 0644);
|
||||
int result = _wunlink(root_dir_w.c_str());
|
||||
#else // _WIN32
|
||||
int result = unlink(root_dir.c_str());
|
||||
#endif // _WIN32
|
||||
if (result == 0) {
|
||||
nout << "Deleted " << root_dir << "\n";
|
||||
} else {
|
||||
if (access(root_dir.c_str(), 0) == 0) {
|
||||
#ifdef _WIN32
|
||||
result = _waccess(root_dir_w.c_str(), 0);
|
||||
#else // _WIN32
|
||||
result = access(root_dir.c_str(), 0);
|
||||
#endif // _WIN32
|
||||
if (result == 0) {
|
||||
nout << "Could not delete " << root_dir << "\n";
|
||||
}
|
||||
}
|
||||
@ -1166,10 +1180,14 @@ delete_directory_recursively(const string &root_dir) {
|
||||
string pathname = root_dir + "/" + filename;
|
||||
|
||||
#ifdef _WIN32
|
||||
wstring pathname_w;
|
||||
string_to_wstring(pathname_w, pathname);
|
||||
// Windows can't delete a file if it's read-only.
|
||||
chmod(pathname.c_str(), 0644);
|
||||
#endif
|
||||
_wchmod(pathname_w.c_str(), 0644);
|
||||
int result = _wunlink(pathname_w.c_str());
|
||||
#else // _WIN32
|
||||
int result = unlink(pathname.c_str());
|
||||
#endif // _WIN32
|
||||
if (result == 0) {
|
||||
nout << " Deleted " << filename << "\n";
|
||||
} else {
|
||||
@ -1184,9 +1202,13 @@ delete_directory_recursively(const string &root_dir) {
|
||||
string pathname = root_dir + "/" + filename;
|
||||
|
||||
#ifdef _WIN32
|
||||
chmod(pathname.c_str(), 0755);
|
||||
#endif
|
||||
wstring pathname_w;
|
||||
string_to_wstring(pathname_w, pathname);
|
||||
_wchmod(pathname_w.c_str(), 0755);
|
||||
int result = _wrmdir(pathname_w.c_str());
|
||||
#else // _WIN32
|
||||
int result = rmdir(pathname.c_str());
|
||||
#endif // _WIN32
|
||||
if (result == 0) {
|
||||
nout << " Removed directory " << filename << "\n";
|
||||
} else {
|
||||
@ -1197,13 +1219,22 @@ delete_directory_recursively(const string &root_dir) {
|
||||
// Finally, delete the root directory itself.
|
||||
string pathname = root_dir;
|
||||
#ifdef _WIN32
|
||||
chmod(pathname.c_str(), 0755);
|
||||
#endif
|
||||
wstring pathname_w;
|
||||
string_to_wstring(pathname_w, pathname);
|
||||
_wchmod(pathname_w.c_str(), 0755);
|
||||
int result = _wrmdir(pathname_w.c_str());
|
||||
#else // _WIN32
|
||||
int result = rmdir(pathname.c_str());
|
||||
#endif // _WIN32
|
||||
if (result == 0) {
|
||||
nout << "Removed directory " << root_dir << "\n";
|
||||
} else {
|
||||
if (access(pathname.c_str(), 0) == 0) {
|
||||
#ifdef _WIN32
|
||||
result = _waccess(pathname_w.c_str(), 0);
|
||||
#else // _WIN32
|
||||
result = access(pathname.c_str(), 0);
|
||||
#endif // _WIN32
|
||||
if (result == 0) {
|
||||
nout << "Could not remove directory " << root_dir << "\n";
|
||||
}
|
||||
}
|
||||
@ -1295,7 +1326,13 @@ create_runtime_environment() {
|
||||
|
||||
logfile.close();
|
||||
logfile.clear();
|
||||
#ifdef _WIN32
|
||||
wstring log_pathname_w;
|
||||
string_to_wstring(log_pathname_w, _log_pathname);
|
||||
logfile.open(log_pathname_w.c_str(), ios::out | ios::trunc);
|
||||
#else
|
||||
logfile.open(_log_pathname.c_str(), ios::out | ios::trunc);
|
||||
#endif // _WIN32
|
||||
if (logfile) {
|
||||
logfile.setf(ios::unitbuf);
|
||||
nout_stream = &logfile;
|
||||
@ -1303,7 +1340,8 @@ create_runtime_environment() {
|
||||
|
||||
// Determine the temporary directory.
|
||||
#ifdef _WIN32
|
||||
char buffer_1[MAX_PATH];
|
||||
wchar_t buffer_1[MAX_PATH];
|
||||
wstring temp_directory_w;
|
||||
|
||||
// Figuring out the correct path for temporary files is a real mess
|
||||
// on Windows. We should be able to use GetTempPath(), but that
|
||||
@ -1328,23 +1366,23 @@ create_runtime_environment() {
|
||||
// SHGetSpecialFolderPath().
|
||||
|
||||
if (getenv("TEMP") != NULL || getenv("TMP") != NULL) {
|
||||
if (GetTempPath(MAX_PATH, buffer_1) != 0) {
|
||||
_temp_directory = buffer_1;
|
||||
if (GetTempPathW(MAX_PATH, buffer_1) != 0) {
|
||||
temp_directory_w = buffer_1;
|
||||
}
|
||||
}
|
||||
if (_temp_directory.empty()) {
|
||||
if (SHGetSpecialFolderPath(NULL, buffer_1, CSIDL_INTERNET_CACHE, true)) {
|
||||
_temp_directory = buffer_1;
|
||||
if (temp_directory_w.empty()) {
|
||||
if (SHGetSpecialFolderPathW(NULL, buffer_1, CSIDL_INTERNET_CACHE, true)) {
|
||||
temp_directory_w = buffer_1;
|
||||
|
||||
// That just *might* return a non-writable folder, if we're in
|
||||
// Protected Mode. We'll test this with GetTempFileName().
|
||||
char temp_buffer[MAX_PATH];
|
||||
if (!GetTempFileName(_temp_directory.c_str(), "p3d", 0, temp_buffer)) {
|
||||
nout << "GetTempFileName failed on " << _temp_directory
|
||||
wchar_t temp_buffer[MAX_PATH];
|
||||
if (!GetTempFileNameW(temp_directory_w.c_str(), L"p3d", 0, temp_buffer)) {
|
||||
nout << "GetTempFileName failed on " << temp_directory_w
|
||||
<< ", switching to GetTempPath\n";
|
||||
_temp_directory.clear();
|
||||
temp_directory_w.clear();
|
||||
} else {
|
||||
DeleteFile(temp_buffer);
|
||||
DeleteFileW(temp_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1352,22 +1390,23 @@ create_runtime_environment() {
|
||||
// If both of the above failed, we'll fall back to GetTempPath()
|
||||
// once again as a last resort, which is supposed to return
|
||||
// *something* that works, even if $TEMP and $TMP are undefined.
|
||||
if (_temp_directory.empty()) {
|
||||
if (GetTempPath(MAX_PATH, buffer_1) != 0) {
|
||||
_temp_directory = buffer_1;
|
||||
if (temp_directory_w.empty()) {
|
||||
if (GetTempPathW(MAX_PATH, buffer_1) != 0) {
|
||||
temp_directory_w = buffer_1;
|
||||
}
|
||||
}
|
||||
|
||||
// Also insist that the temp directory is fully specified.
|
||||
size_t needs_size_2 = GetFullPathName(_temp_directory.c_str(), 0, NULL, NULL);
|
||||
char *buffer_2 = new char[needs_size_2];
|
||||
if (GetFullPathName(_temp_directory.c_str(), needs_size_2, buffer_2, NULL) != 0) {
|
||||
_temp_directory = buffer_2;
|
||||
size_t needs_size_2 = GetFullPathNameW(temp_directory_w.c_str(), 0, NULL, NULL);
|
||||
wchar_t *buffer_2 = new wchar_t[needs_size_2];
|
||||
if (GetFullPathNameW(temp_directory_w.c_str(), needs_size_2, buffer_2, NULL) != 0) {
|
||||
temp_directory_w = buffer_2;
|
||||
}
|
||||
delete[] buffer_2;
|
||||
|
||||
// And make sure the directory actually exists.
|
||||
mkdir_complete(_temp_directory, nout);
|
||||
mkdir_complete_w(temp_directory_w, nout);
|
||||
wstring_to_string(_temp_directory, temp_directory_w);
|
||||
|
||||
#else
|
||||
_temp_directory = "/tmp/";
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "p3dMultifileReader.h"
|
||||
#include "p3dPackage.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@ -108,7 +109,15 @@ extract_all(const string &to_dir, P3DPackage *package,
|
||||
return false;
|
||||
}
|
||||
|
||||
ofstream out(output_pathname.c_str(), ios::out | ios::binary);
|
||||
ofstream out;
|
||||
#ifdef _WIN32
|
||||
wstring output_pathname_w;
|
||||
if (string_to_wstring(output_pathname_w, output_pathname)) {
|
||||
out.open(output_pathname_w.c_str(), ios::out | ios::binary);
|
||||
}
|
||||
#else // _WIN32
|
||||
out.open(output_pathname.c_str(), ios::out | ios::binary);
|
||||
#endif // _WIN32
|
||||
if (!out) {
|
||||
nout << "Unable to write to " << output_pathname << "\n";
|
||||
return false;
|
||||
@ -217,7 +226,14 @@ read_header(const string &pathname) {
|
||||
_cert_special.clear();
|
||||
_signatures.clear();
|
||||
|
||||
#ifdef _WIN32
|
||||
wstring pathname_w;
|
||||
if (string_to_wstring(pathname_w, pathname)) {
|
||||
_in.open(pathname_w.c_str(), ios::in | ios::binary);
|
||||
}
|
||||
#else // _WIN32
|
||||
_in.open(pathname.c_str(), ios::in | ios::binary);
|
||||
#endif // _WIN32
|
||||
if (!_in) {
|
||||
nout << "Couldn't open " << pathname << "\n";
|
||||
return false;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "p3dTemporaryFile.h"
|
||||
#include "p3dPatchFinder.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
@ -1851,7 +1852,15 @@ thread_step() {
|
||||
string source_pathname = _package->get_package_dir() + "/" + _source.get_filename();
|
||||
string target_pathname = _package->get_package_dir() + "/" + _target.get_filename();
|
||||
|
||||
ifstream source(source_pathname.c_str(), ios::in | ios::binary);
|
||||
ifstream source;
|
||||
#ifdef _WIN32
|
||||
wstring source_pathname_w;
|
||||
if (string_to_wstring(source_pathname_w, source_pathname)) {
|
||||
source.open(source_pathname_w.c_str(), ios::in | ios::binary);
|
||||
}
|
||||
#else // _WIN32
|
||||
source.open(source_pathname.c_str(), ios::in | ios::binary);
|
||||
#endif // _WIN32
|
||||
if (!source) {
|
||||
nout << "Couldn't open " << source_pathname << "\n";
|
||||
return IT_step_failed;
|
||||
@ -1861,7 +1870,15 @@ thread_step() {
|
||||
return IT_step_failed;
|
||||
}
|
||||
|
||||
ofstream target(target_pathname.c_str(), ios::out | ios::binary);
|
||||
ofstream target;
|
||||
#ifdef _WIN32
|
||||
wstring target_pathname_w;
|
||||
if (string_to_wstring(target_pathname_w, target_pathname)) {
|
||||
target.open(target_pathname_w.c_str(), ios::out | ios::binary);
|
||||
}
|
||||
#else // _WIN32
|
||||
target.open(target_pathname.c_str(), ios::out | ios::binary);
|
||||
#endif // _WIN32
|
||||
if (!target) {
|
||||
nout << "Couldn't write to " << target_pathname << "\n";
|
||||
return IT_step_failed;
|
||||
|
@ -13,6 +13,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "p3dPatchfileReader.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPatchfileReader::Constructor
|
||||
@ -62,15 +63,36 @@ open_read() {
|
||||
|
||||
string patch_pathname = _patchfile.get_pathname(_package_dir);
|
||||
_patch_in.clear();
|
||||
#ifdef _WIN32
|
||||
wstring patch_pathname_w;
|
||||
if (string_to_wstring(patch_pathname_w, patch_pathname)) {
|
||||
_patch_in.open(patch_pathname_w.c_str(), ios::in | ios::binary);
|
||||
}
|
||||
#else // _WIN32
|
||||
_patch_in.open(patch_pathname.c_str(), ios::in | ios::binary);
|
||||
#endif // _WIN32
|
||||
|
||||
string source_pathname = _source.get_pathname(_package_dir);
|
||||
_source_in.clear();
|
||||
#ifdef _WIN32
|
||||
wstring source_pathname_w;
|
||||
if (string_to_wstring(source_pathname_w, source_pathname)) {
|
||||
_source_in.open(source_pathname_w.c_str(), ios::in | ios::binary);
|
||||
}
|
||||
#else // _WIN32
|
||||
_source_in.open(source_pathname.c_str(), ios::in | ios::binary);
|
||||
#endif // _WIN32
|
||||
|
||||
mkfile_complete(_output_pathname, nout);
|
||||
_target_out.clear();
|
||||
_target_out.open(_output_pathname.c_str(), ios::out | ios::binary);
|
||||
#ifdef _WIN32
|
||||
wstring output_pathname_w;
|
||||
if (string_to_wstring(output_pathname_w, _output_pathname)) {
|
||||
_target_out.open(output_pathname_w.c_str(), ios::in | ios::binary);
|
||||
}
|
||||
#else // _WIN32
|
||||
_target_out.open(_output_pathname.c_str(), ios::in | ios::binary);
|
||||
#endif // _WIN32
|
||||
|
||||
_is_open = true;
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "p3dConcreteStruct.h"
|
||||
#include "binaryXml.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "wstring_encode.h"
|
||||
#include "run_p3dpython.h"
|
||||
|
||||
#include <ctype.h>
|
||||
@ -1481,8 +1482,10 @@ win_create_process() {
|
||||
HANDLE error_handle = GetStdHandle(STD_ERROR_HANDLE);
|
||||
bool got_error_handle = false;
|
||||
if (!_log_pathname.empty()) {
|
||||
HANDLE handle = CreateFile
|
||||
(_log_pathname.c_str(), GENERIC_WRITE,
|
||||
wstring log_pathname_w;
|
||||
string_to_wstring(log_pathname_w, _log_pathname);
|
||||
HANDLE handle = CreateFileW
|
||||
(log_pathname_w.c_str(), GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL, CREATE_ALWAYS, 0, NULL);
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
@ -1494,8 +1497,8 @@ win_create_process() {
|
||||
}
|
||||
}
|
||||
|
||||
STARTUPINFO startup_info;
|
||||
ZeroMemory(&startup_info, sizeof(STARTUPINFO));
|
||||
STARTUPINFOW startup_info;
|
||||
ZeroMemory(&startup_info, sizeof(startup_info));
|
||||
startup_info.cb = sizeof(startup_info);
|
||||
|
||||
// Set up the I/O handles. We send stderr and stdout to our
|
||||
@ -1512,13 +1515,15 @@ win_create_process() {
|
||||
// If _keep_user_env is true, meaning not to change the current
|
||||
// directory, then pass NULL in to CreateProcess(). Otherwise pass
|
||||
// in _start_dir.
|
||||
const char *start_dir_cstr;
|
||||
const wchar_t *start_dir_cstr;
|
||||
wstring start_dir_w;
|
||||
if (_keep_user_env) {
|
||||
start_dir_cstr = NULL;
|
||||
nout << "Not changing working directory.\n";
|
||||
} else {
|
||||
start_dir_cstr = _start_dir.c_str();
|
||||
nout << "Setting working directory: " << start_dir_cstr << "\n";
|
||||
string_to_wstring(start_dir_w, _start_dir);
|
||||
start_dir_cstr = start_dir_w.c_str();
|
||||
nout << "Setting working directory: " << _start_dir << "\n";
|
||||
}
|
||||
|
||||
// Construct the command-line string, containing the quoted
|
||||
@ -1531,13 +1536,17 @@ win_create_process() {
|
||||
// I'm not sure why CreateProcess wants a non-const char pointer for
|
||||
// its command-line string, but I'm not taking chances. It gets a
|
||||
// non-const char array that it can modify.
|
||||
string command_line_str = stream.str();
|
||||
char *command_line = new char[command_line_str.size() + 1];
|
||||
strcpy(command_line, command_line_str.c_str());
|
||||
wstring command_line_str;
|
||||
string_to_wstring(command_line_str, stream.str());
|
||||
wchar_t *command_line = new wchar_t[command_line_str.size() + 1];
|
||||
memcpy(command_line, command_line_str.c_str(), sizeof(wchar_t) * command_line_str.size() + 1);
|
||||
|
||||
wstring p3dpython_exe_w;
|
||||
string_to_wstring(p3dpython_exe_w, _p3dpython_exe);
|
||||
|
||||
PROCESS_INFORMATION process_info;
|
||||
BOOL result = CreateProcess
|
||||
(_p3dpython_exe.c_str(), command_line, NULL, NULL, TRUE, 0,
|
||||
BOOL result = CreateProcessW
|
||||
(p3dpython_exe_w.c_str(), command_line, NULL, NULL, TRUE, 0,
|
||||
(void *)_env.c_str(), start_dir_cstr,
|
||||
&startup_info, &process_info);
|
||||
bool started_program = (result != 0);
|
||||
|
@ -13,6 +13,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "p3dSplashWindow.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
// Stuff to use libpng.
|
||||
#include <png.h>
|
||||
@ -259,7 +260,16 @@ read_image_data(ImageData &image, string &data,
|
||||
}
|
||||
|
||||
// We only support JPEG or PNG images.
|
||||
FILE *fp = fopen(image_filename.c_str(), "rb");
|
||||
FILE *fp = NULL;
|
||||
#ifdef _WIN32
|
||||
wstring image_filename_w;
|
||||
if (string_to_wstring(image_filename_w, image_filename)) {
|
||||
fp = _wfopen(image_filename_w.c_str(), L"rb");
|
||||
}
|
||||
#else // _WIN32
|
||||
fp = fopen(image_filename.c_str(), "rb");
|
||||
#endif // _WIN32
|
||||
|
||||
if (fp == NULL) {
|
||||
nout << "Couldn't open splash file image: " << image_filename << "\n";
|
||||
return false;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "PPDownloadRequest.h"
|
||||
#include "PPInstance.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
bool PPDownloadRequest::Begin( )
|
||||
{
|
||||
@ -54,7 +55,9 @@ bool PPDownloadRequest::DataNotify( size_t expectedDataSize, const void* data, s
|
||||
{
|
||||
if ( m_hFile == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
m_hFile = ::CreateFile( m_fileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
wstring filename_w;
|
||||
string_to_wstring(filename_w, m_fileName);
|
||||
m_hFile = ::CreateFileW( filename_w.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
if ( m_hFile == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
return ret;
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "find_root_dir.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "parse_color.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
// We can include this header file to get the DTOOL_PLATFORM
|
||||
// definition, even though we don't link with dtool.
|
||||
@ -79,6 +80,7 @@ PPInstance::PPInstance( CP3DActiveXCtrl& parentCtrl ) :
|
||||
{
|
||||
// We need the root dir first.
|
||||
m_rootDir = find_root_dir( );
|
||||
string_to_wstring(m_rootDir_w, m_rootDir);
|
||||
|
||||
// Then open the logfile.
|
||||
m_logger.Open( m_rootDir );
|
||||
@ -452,13 +454,14 @@ int PPInstance::DownloadP3DComponents( std::string& p3dDllFilename )
|
||||
if (!already_got) {
|
||||
// OK, we need to download a new contents.xml file. Start off
|
||||
// by downloading it into a local temporary file.
|
||||
TCHAR tempFileName[ MAX_PATH ];
|
||||
if (!::GetTempFileName( m_rootDir.c_str(), "p3d", 0, tempFileName )) {
|
||||
WCHAR local_filename_w[ MAX_PATH ];
|
||||
if (!::GetTempFileNameW( m_rootDir_w.c_str(), L"p3d", 0, local_filename_w )) {
|
||||
nout << "GetTempFileName failed (folder is " << m_rootDir << ")\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string localContentsFileName( tempFileName );
|
||||
std::string local_filename;
|
||||
wstring_to_string(local_filename, local_filename_w);
|
||||
|
||||
std::string hostUrl( PANDA_PACKAGE_HOST_URL );
|
||||
if (!hostUrl.empty() && hostUrl[hostUrl.size() - 1] != '/') {
|
||||
@ -471,9 +474,9 @@ int PPInstance::DownloadP3DComponents( std::string& p3dDllFilename )
|
||||
strm << hostUrl << P3D_CONTENTS_FILENAME << "?" << time(NULL);
|
||||
std::string remoteContentsUrl( strm.str() );
|
||||
|
||||
error = DownloadFile( remoteContentsUrl, localContentsFileName );
|
||||
error = DownloadFile( remoteContentsUrl, local_filename );
|
||||
if ( !error ) {
|
||||
if ( !read_contents_file( localContentsFileName, true ) )
|
||||
if ( !read_contents_file( local_filename, true ) )
|
||||
error = 1;
|
||||
}
|
||||
|
||||
@ -485,7 +488,7 @@ int PPInstance::DownloadP3DComponents( std::string& p3dDllFilename )
|
||||
}
|
||||
|
||||
// We don't need the temporary file any more.
|
||||
::DeleteFile( localContentsFileName.c_str() );
|
||||
::DeleteFileW( local_filename_w );
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
|
@ -110,6 +110,7 @@ protected:
|
||||
int _num_tokens;
|
||||
|
||||
std::string m_rootDir;
|
||||
std::wstring m_rootDir_w;
|
||||
|
||||
class ThreadedRequestData {
|
||||
public:
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "windows.h"
|
||||
#include "PPLogger.h"
|
||||
#include "mkdir_complete.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
std::ofstream PPLogger::m_logfile;
|
||||
bool PPLogger::m_isOpen = false;
|
||||
@ -29,67 +30,6 @@ PPLogger::~PPLogger( )
|
||||
{
|
||||
}
|
||||
|
||||
int PPLogger::CreateNewFolder( const std::string& dirname )
|
||||
{
|
||||
int error( 0 );
|
||||
if ( CreateDirectory( dirname.c_str( ), NULL ) != 0 )
|
||||
{
|
||||
// Success!
|
||||
return error;
|
||||
}
|
||||
// Failed.
|
||||
DWORD lastError = GetLastError( );
|
||||
if ( lastError == ERROR_ALREADY_EXISTS )
|
||||
{
|
||||
// Not really an error: the directory is already there.
|
||||
return error;
|
||||
}
|
||||
if ( lastError == ERROR_PATH_NOT_FOUND )
|
||||
{
|
||||
// We need to make the parent directory first.
|
||||
std::string parent = dirname;
|
||||
if ( !parent.empty() && CreateNewFolder( parent ) )
|
||||
{
|
||||
// Parent successfully created. Try again to make the child.
|
||||
if ( CreateDirectory( dirname.c_str(), NULL ) != 0)
|
||||
{
|
||||
// Got it!
|
||||
return error;
|
||||
}
|
||||
m_logfile << "Couldn't create " << dirname << "\n";
|
||||
}
|
||||
}
|
||||
return ( error = 1 );
|
||||
}
|
||||
|
||||
int PPLogger::CreateNewFile(const std::string& dirname, const std::string& filename)
|
||||
{
|
||||
int error( 0 );
|
||||
std::string logfilename = dirname + filename;
|
||||
HANDLE file = CreateFile( logfilename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
if ( file == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
// Try to make the parent directory first.
|
||||
std::string parent = dirname;
|
||||
if ( !parent.empty( ) && CreateNewFolder( parent ) )
|
||||
{
|
||||
// Parent successfully created. Try again to make the file.
|
||||
file = CreateFile( logfilename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
}
|
||||
if ( file == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
m_logfile << "Couldn't create " << filename << "\n";
|
||||
return ( error = 1 );
|
||||
}
|
||||
}
|
||||
CloseHandle( file );
|
||||
return error;
|
||||
}
|
||||
|
||||
void PPLogger::Open( const std::string &rootDir )
|
||||
{
|
||||
if (!m_isOpen) {
|
||||
@ -137,7 +77,9 @@ void PPLogger::Open( const std::string &rootDir )
|
||||
|
||||
m_logfile.close();
|
||||
m_logfile.clear();
|
||||
m_logfile.open(log_pathname.c_str(), std::ios::out | std::ios::trunc);
|
||||
wstring log_pathname_w;
|
||||
string_to_wstring(log_pathname_w, log_pathname);
|
||||
m_logfile.open(log_pathname_w.c_str(), std::ios::out | std::ios::trunc);
|
||||
m_logfile.setf(std::ios::unitbuf);
|
||||
}
|
||||
|
||||
|
@ -30,9 +30,6 @@ public:
|
||||
static std::ofstream& Log( ) { return m_logfile; }
|
||||
|
||||
protected:
|
||||
int CreateNewFile(const std::string& dirname, const std::string& filename );
|
||||
int CreateNewFolder( const std::string& dirname );
|
||||
|
||||
static bool m_isOpen;
|
||||
static std::ofstream m_logfile;
|
||||
};
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "p3d_plugin_config.h"
|
||||
#include "p3d_lock.h"
|
||||
#include "ppBrowserObject.h"
|
||||
#include "wstring_encode.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <shlobj.h>
|
||||
@ -90,7 +91,13 @@ open_logfile() {
|
||||
|
||||
logfile.close();
|
||||
logfile.clear();
|
||||
#ifdef _WIN32
|
||||
wstring log_pathname_w;
|
||||
string_to_wstring(log_pathname_w, log_pathname);
|
||||
logfile.open(log_pathname_w.c_str(), ios::out | ios::trunc);
|
||||
#else
|
||||
logfile.open(log_pathname.c_str(), ios::out | ios::trunc);
|
||||
#endif // _WIN32
|
||||
logfile.setf(ios::unitbuf);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user