summaryrefslogtreecommitdiff
path: root/shared/shadow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'shared/shadow.cpp')
-rw-r--r--shared/shadow.cpp122
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());
}
-
bgstack15