wip: support windows unicode filenames in plugin

This commit is contained in:
David Rose 2011-08-30 02:54:01 +00:00
parent 2c7f1498b3
commit 9150bd2f6c
25 changed files with 614 additions and 286 deletions

View File

@ -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
//

View File

@ -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;

View File

@ -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;
}
}

View File

@ -20,7 +20,7 @@
// otherwise.
////////////////////////////////////////////////////////////////////
inline bool
is_pathsep(char ch) {
is_pathsep(int ch) {
if (ch == '/') {
return true;
}

View File

@ -16,7 +16,7 @@
#define IS_PATHSEP_H
inline bool
is_pathsep(char ch);
is_pathsep(int ch);
#include "is_pathsep.I"

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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
}
////////////////////////////////////////////////////////////////////

View File

@ -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/";

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -110,6 +110,7 @@ protected:
int _num_tokens;
std::string m_rootDir;
std::wstring m_rootDir_w;
class ThreadedRequestData {
public:

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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);
}