diff --git a/Server.cpp b/Server.cpp index a55f33b5..2ea54017 100644 --- a/Server.cpp +++ b/Server.cpp @@ -132,6 +132,10 @@ void CServer::setup(void) #endif CQuery::init_mutex(); + +#ifdef MODE_WIN + File::init_mutex(); +#endif } void CServer::destroyAllDatabases(void) @@ -269,6 +273,10 @@ CServer::~CServer() CDatabase::destroyMutex(); #endif +#ifdef MODE_WIN + File::destroy_mutex(); +#endif + std::cout << "Server cleanup done..." << std::endl; } diff --git a/file.h b/file.h index 099dd6eb..5ce270c7 100644 --- a/file.h +++ b/file.h @@ -20,6 +20,7 @@ const int MODE_TEMP=4; #endif #ifdef MODE_WIN # include +# include "Interface/Mutex.h" #endif #ifdef MODE_LIN #ifndef _LARGEFILE64_SOURCE @@ -47,6 +48,11 @@ public: bool Seek(_i64 spos); _i64 Size(void); void Close(); + +#ifdef _WIN32 + static void init_mutex(); + static void destroy_mutex(); +#endif std::string getFilename(void); std::wstring getFilenameW(void); @@ -61,6 +67,12 @@ private: int fd; #endif std::wstring fn; + +#ifdef _WIN32 + static size_t tmp_file_index; + static IMutex* index_mutex; + static std::wstring random_prefix; +#endif }; bool DeleteFileInt(std::string pFilename); diff --git a/file_win.cpp b/file_win.cpp index 2562ed79..1fd52164 100644 --- a/file_win.cpp +++ b/file_win.cpp @@ -22,9 +22,14 @@ #include "file.h" #include "types.h" #include "stringtools.h" +#include #ifdef MODE_WIN +size_t File::tmp_file_index = 0; +IMutex* File::index_mutex = NULL; +std::wstring File::random_prefix; + File::File() : hfile(INVALID_HANDLE_VALUE) { @@ -51,12 +56,16 @@ bool File::Open(std::wstring pfn, int mode) dwCreationDisposition=CREATE_NEW; dwDesiredAccess=GENERIC_WRITE; } - else if( mode==MODE_APPEND - || mode==MODE_TEMP ) + else if( mode==MODE_APPEND ) { dwCreationDisposition=OPEN_EXISTING; dwDesiredAccess=GENERIC_WRITE | GENERIC_READ; } + else if( mode==MODE_TEMP ) + { + dwCreationDisposition=CREATE_NEW; + dwDesiredAccess=GENERIC_WRITE | GENERIC_READ; + } else if( mode==MODE_RW || mode==MODE_RW_SEQUENTIAL || mode==MODE_RW_CREATE @@ -111,6 +120,8 @@ bool File::Open(std::wstring pfn, int mode) bool File::OpenTemporaryFile(const std::wstring &tmpdir) { + std::wostringstream filename; + if(tmpdir.empty()) { wchar_t tmpp[MAX_PATH]; @@ -119,29 +130,29 @@ bool File::OpenTemporaryFile(const std::wstring &tmpdir) { wcscpy_s(tmpp,L"C:\\"); } - - wchar_t filename[MAX_PATH]; - if( GetTempFileNameW(tmpp, L"urbackup.t", 0, filename)==0 ) - { - hfile=NULL; - int err=GetLastError(); - return false; - } - - return Open(filename, MODE_TEMP); + + filename << tmpp; } else { - wchar_t filename[MAX_PATH]; - if( GetTempFileNameW(tmpdir.c_str(), L"urbackup.t", 0, filename)==0 ) - { - hfile=NULL; - int err=GetLastError(); - return false; - } + filename << tmpdir; - return Open(filename, MODE_TEMP); + if(tmpdir[tmpdir.size()-1]!='\\') + { + filename << L"\\"; + } } + + filename << L"urb" << random_prefix << L"-" << std::hex; + + { + IScopedLock lock(index_mutex); + filename << ++tmp_file_index; + } + + filename << L".tmp"; + + return Open(filename.str(), MODE_TEMP); } bool File::Open(void *handle) @@ -229,4 +240,20 @@ void File::Close() } } +void File::init_mutex() +{ + index_mutex = Server->createMutex(); + + std::string rnd; + rnd.resize(5); + Server->randomFill(&rnd[0], rnd.size()); + + random_prefix = widen(bytesToHex(reinterpret_cast(&rnd[0]), rnd.size())); +} + +void File::destroy_mutex() +{ + Server->destroy(index_mutex); +} + #endif