diff options
Diffstat (limited to 'shared/shadow.cpp')
-rw-r--r-- | shared/shadow.cpp | 122 |
1 files changed, 55 insertions, 67 deletions
diff --git a/shared/shadow.cpp b/shared/shadow.cpp index 29eec53b..7e3b34c0 100644 --- a/shared/shadow.cpp +++ b/shared/shadow.cpp @@ -2,6 +2,10 @@ #include <wx/msw/wrapwin.h> //includes "windows.h" #include <wx/intl.h> #include "systemConstants.h" +#include "dllLoader.h" +#include <stdexcept> +#include "staticAssert.h" +#include "buildInfo.h" using FreeFileSync::ShadowCopy; @@ -12,7 +16,6 @@ bool newerThanXP() ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - //symbolic links are supported starting with Vista if (GetVersionEx(&osvi)) return osvi.dwMajorVersion > 5 || (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion > 1) ; @@ -42,93 +45,78 @@ bool runningWOW64() //test if process is running under WOW64 (reference http://m } -class ShadowCopy::ShadowlDllHandler //dynamically load windows API functions +const wxString& getShadowDllName() { - typedef bool (*CreateShadowCopyFct)( //volumeName must end with "\", while shadowVolName does not end with "\" - const wchar_t* volumeName, - wchar_t* shadowVolName, - unsigned int shadowBufferLen, - void** backupHandle, - wchar_t* errorMessage, - unsigned int errorBufferLen); + /* + distinguish a bunch of VSS builds: we use XP and Server 2003 implementations... + VSS version and compatibility overview: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx + */ - typedef void (*ReleaseShadowCopyFct)(void* backupHandle); + static const wxString filename( + Utility::is64BitBuild ? + (newerThanXP() ? + wxT("Shadow_Server2003_x64.dll") : + wxT("Shadow_XP_x64.dll")) : -public: - static const wxString& getShadowDllName() - { - /* - distinguish a bunch of VSS builds: we use XP and Server 2003 implementations... - VSS version and compatibility overview: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx - */ -#if defined _WIN64 //note: _WIN32 is defined for 64-bit compilations, too, while _WIN64 only for 64-bit - static const wxString filename(newerThanXP() ? - wxT("Shadow_Server2003_x64.dll") : - wxT("Shadow_XP_x64.dll")); -#elif defined(_WIN32) - static const wxString filename(newerThanXP() ? - wxT("Shadow_Server2003_win32.dll") : - wxT("Shadow_XP_win32.dll")); -#else - Are we at 128 bit already? -#endif - return filename; - } + (newerThanXP() ? + wxT("Shadow_Server2003_Win32.dll") : + wxT("Shadow_XP_Win32.dll"))); - ShadowlDllHandler() : - createShadowCopy(NULL), - releaseShadowCopy(NULL), - hShadow(NULL) - { - //get a handle to the DLL module containing the required functionality - hShadow = ::LoadLibrary(getShadowDllName().c_str()); - if (hShadow) - { - createShadowCopy = reinterpret_cast<CreateShadowCopyFct>(::GetProcAddress(hShadow, "createShadowCopy")); - releaseShadowCopy = reinterpret_cast<ReleaseShadowCopyFct>(::GetProcAddress(hShadow, "releaseShadowCopy")); - } - } + assert_static(Utility::is32BitBuild || Utility::is64BitBuild); - ~ShadowlDllHandler() - { - if (hShadow) ::FreeLibrary(hShadow); - } - - CreateShadowCopyFct createShadowCopy; - ReleaseShadowCopyFct releaseShadowCopy; + return filename; +} -private: - HINSTANCE hShadow; -}; //############################################################################################################# ShadowCopy::ShadowCopy() : - backupHandle(NULL) -{ - shadowDll = new ShadowlDllHandler; -} + backupHandle(NULL) {} ShadowCopy::~ShadowCopy() { if (backupHandle != NULL) - shadowDll->releaseShadowCopy(backupHandle); + { + typedef void (*ReleaseShadowCopyFct)(void* backupHandle); + static const ReleaseShadowCopyFct releaseShadowCopy = + Utility::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName().c_str(), "releaseShadowCopy"); + + if (releaseShadowCopy == NULL) + throw std::logic_error("Could not load \"releaseShadowCopy\"!"); //shouldn't arrive here! - delete shadowDll; + releaseShadowCopy(backupHandle); + } } Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) { + typedef bool (*CreateShadowCopyFct)( //volumeName must end with "\", while shadowVolName does not end with "\" + const wchar_t* volumeName, + wchar_t* shadowVolName, + unsigned int shadowBufferLen, + void** backupHandle, + wchar_t* errorMessage, + unsigned int errorBufferLen); + static const CreateShadowCopyFct createShadowCopy = + Utility::loadDllFunction<CreateShadowCopyFct>(getShadowDllName().c_str(), "createShadowCopy"); + + + typedef void (*ReleaseShadowCopyFct)(void* backupHandle); + static const ReleaseShadowCopyFct releaseShadowCopy = + Utility::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName().c_str(), "releaseShadowCopy"); + + + //check if shadow copy dll was loaded correctly - if ( shadowDll->createShadowCopy == NULL || - shadowDll->releaseShadowCopy == NULL) + if ( createShadowCopy == NULL || + releaseShadowCopy == NULL) { wxString errorMsg = _("Error copying locked file %x!"); errorMsg.Replace(wxT("%x"), wxString(wxT("\"")) + inputFile.c_str() + wxT("\"")); throw FileError(errorMsg + wxT("\n\n") + _("Error starting Volume Shadow Copy Service!") + wxT("\n") + - _("Could not load a required DLL:") + wxT(" \"") + ShadowlDllHandler::getShadowDllName() + wxT("\"")); + _("Could not load a required DLL:") + wxT(" \"") + getShadowDllName() + wxT("\"")); } //VSS does not support running under WOW64 except for Windows XP and Windows Server 2003 @@ -146,7 +134,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) //--------------------------------------------------------------------------------------------------------- wchar_t volumeNameRaw[1000]; - if (!GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName, + if (!::GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName, volumeNameRaw, //__out LPTSTR lpszVolumePathName, 1000)) //__in DWORD cchBufferLength { @@ -164,7 +152,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) //release old shadow copy if (backupHandle != NULL) { - shadowDll->releaseShadowCopy(backupHandle); + releaseShadowCopy(backupHandle); backupHandle = NULL; } realVolumeLast.clear(); //...if next call fails... @@ -175,7 +163,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) void* backupHandleTmp = NULL; wchar_t errorMessage[1000]; - if (!shadowDll->createShadowCopy( + if (!createShadowCopy( volumeNameFormatted.c_str(), shadowVolName, 1000, @@ -194,7 +182,8 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) backupHandle = backupHandleTmp; } - const size_t pos = inputFile.find(volumeNameFormatted); + //input file is always absolute! directory formatting takes care of this! Therefore volume name can always be found. + const size_t pos = inputFile.find(volumeNameFormatted); //inputFile needs NOT to begin with volumeNameFormatted: consider for example \\?\ prefix! if (pos == Zstring::npos) { wxString errorMsg = _("Error copying locked file %x!"); @@ -209,4 +198,3 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) return shadowVolumeLast + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length()); } - |