summaryrefslogtreecommitdiff
path: root/shared/shadow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'shared/shadow.cpp')
-rw-r--r--shared/shadow.cpp204
1 files changed, 103 insertions, 101 deletions
diff --git a/shared/shadow.cpp b/shared/shadow.cpp
index 3909c37b..b38103de 100644
--- a/shared/shadow.cpp
+++ b/shared/shadow.cpp
@@ -7,16 +7,21 @@
#include "shadow.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include <wx/intl.h>
-#include "systemConstants.h"
-#include "dllLoader.h"
+#include "system_constants.h"
+#include "dll_loader.h"
#include <stdexcept>
-#include "staticAssert.h"
-#include "buildInfo.h"
+#include "assert_static.h"
+#include "build_info.h"
#include "ShadowCopy\shadow.h"
+#include "string_conv.h"
-using FreeFileSync::ShadowCopy;
+using shadow::ShadowCopy;
+using shadow::WaitingForShadow;
+using ffs3::FileError;
+namespace
+{
bool newerThanXP()
{
OSVERSIONINFO osvi;
@@ -41,7 +46,7 @@ bool runningWOW64() //test if process is running under WOW64 (reference http://m
PBOOL Wow64Process);
static const IsWow64ProcessFunc isWow64Process =
- Utility::loadDllFunction<IsWow64ProcessFunc>(L"kernel32.dll", "IsWow64Process");
+ util::loadDllFunction<IsWow64ProcessFunc>(L"kernel32.dll", "IsWow64Process");
if (isWow64Process)
{
@@ -54,148 +59,145 @@ bool runningWOW64() //test if process is running under WOW64 (reference http://m
}
-const wxString& getShadowDllName()
+const std::wstring& 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
*/
- static const wxString filename(
+ assert_static(util::is32BitBuild || util::is64BitBuild);
+
+ static const std::wstring filename(
newerThanXP() ?
- (Utility::is64BitBuild ?
- wxT("Shadow_Server2003_x64.dll") :
- wxT("Shadow_Server2003_Win32.dll")) :
+ (util::is64BitBuild ?
+ L"Shadow_Server2003_x64.dll" :
+ L"Shadow_Server2003_Win32.dll") :
- (Utility::is64BitBuild ?
- wxT("Shadow_XP_x64.dll") :
- wxT("Shadow_XP_Win32.dll")));
+ (util::is64BitBuild ?
+ L"Shadow_XP_x64.dll" :
+ L"Shadow_XP_Win32.dll"));
- assert_static(Utility::is32BitBuild || Utility::is64BitBuild);
return filename;
}
-
+}
//#############################################################################################################
-ShadowCopy::ShadowCopy() :
- backupHandle(NULL) {}
+ShadowCopy::ShadowCopy(WaitingForShadow* callback) : callback_(callback) {}
+ShadowCopy::~ShadowCopy() {} //std::auto_ptr: keep non-inline
+//#############################################################################################################
-ShadowCopy::~ShadowCopy()
+class ShadowCopy::ShadowVolume
{
- if (backupHandle != NULL)
+public:
+ ShadowVolume(const Zstring& volumeNameFormatted) : //throw(FileError)
+ realVol(volumeNameFormatted),
+ backupHandle(NULL)
{
- using namespace Shadow;
+ using namespace shadow;
- static const ReleaseShadowCopyFct releaseShadowCopy =
- Utility::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName().c_str(), releaseShadowCopyFctName);
+ if (!createShadowCopy)
+ createShadowCopy = util::loadDllFunction<CreateShadowCopyFct>(getShadowDllName(), createShadowCopyFctName);
- if (releaseShadowCopy == NULL)
- throw std::logic_error("Could not load \"releaseShadowCopy\"!"); //shouldn't arrive here!
+ if (!releaseShadowCopy)
+ releaseShadowCopy = util::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName(), releaseShadowCopyFctName);
- releaseShadowCopy(backupHandle);
- }
-}
+ //check if shadow copy dll was loaded correctly
+ if ( createShadowCopy == NULL ||
+ releaseShadowCopy == NULL)
+ throw FileError(wxString(_("Error starting Volume Shadow Copy Service!")) + wxT("\n") +
+ _("Could not load a required DLL:") + wxT(" \"") + getShadowDllName().c_str() + wxT("\""));
+ //VSS does not support running under WOW64 except for Windows XP and Windows Server 2003
+ //(Reference: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx)
+ static const bool wow64Active = runningWOW64();
+ if (wow64Active)
+ throw FileError(wxString(_("Error starting Volume Shadow Copy Service!")) + wxT("\n") +
+ _("Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version."));
-Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
-{
- using namespace Shadow;
+//---------------------------------------------------------------------------------------------------------
+ //start shadow volume copy service:
+ wchar_t shadowVolName[1000];
+ wchar_t errorMessage[1000];
+
+ if (!createShadowCopy(
+ volumeNameFormatted.c_str(),
+ shadowVolName,
+ 1000,
+ &backupHandle,
+ errorMessage,
+ 1000))
+ throw FileError(wxString(_("Error starting Volume Shadow Copy Service!")) + wxT("\n") +
+ wxT("(") + errorMessage + wxT(" Volume: \"") + volumeNameFormatted.c_str() + wxT("\")"));
- static const CreateShadowCopyFct createShadowCopy =
- Utility::loadDllFunction<CreateShadowCopyFct>(getShadowDllName().c_str(), createShadowCopyFctName);
+ shadowVol = Zstring(shadowVolName) + common::FILE_NAME_SEPARATOR; //shadowVolName NEVER has a trailing backslash
+ }
- static const ReleaseShadowCopyFct releaseShadowCopy =
- Utility::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName().c_str(), releaseShadowCopyFctName);
+ ~ShadowVolume()
+ {
+ releaseShadowCopy(backupHandle);
+ }
- //check if shadow copy dll was loaded correctly
- if ( createShadowCopy == NULL ||
- releaseShadowCopy == NULL)
+ Zstring getShadowVolume() const //trailing path separator
{
- 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(" \"") + getShadowDllName() + wxT("\""));
+ return shadowVol;
}
- //VSS does not support running under WOW64 except for Windows XP and Windows Server 2003
- //(Reference: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx)
- static const bool wow64Active = runningWOW64();
- if (wow64Active)
+ Zstring getRealVolume() const //trailing path separator
{
- 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") +
- _("Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version."));
+ return realVol;
}
+private:
+ ShadowVolume(const ShadowVolume&);
+ ShadowVolume& operator=(const ShadowVolume&);
+
+ static shadow::CreateShadowCopyFct createShadowCopy;
+ static shadow::ReleaseShadowCopyFct releaseShadowCopy;
+
+ Zstring shadowVol;
+ const Zstring realVol;
+
+ void* backupHandle;
+};
+
+
+shadow::CreateShadowCopyFct ShadowCopy::ShadowVolume::createShadowCopy;
+shadow::ReleaseShadowCopyFct ShadowCopy::ShadowVolume::releaseShadowCopy;
+//#############################################################################################################
+
+
+Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
+{
+ using namespace ffs3;
-//---------------------------------------------------------------------------------------------------------
wchar_t volumeNameRaw[1000];
if (!::GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName,
volumeNameRaw, //__out LPTSTR lpszVolumePathName,
1000)) //__in DWORD cchBufferLength
- {
- wxString errorMsg = _("Error copying locked file %x!");
- errorMsg.Replace(wxT("%x"), wxString(wxT("\"")) + inputFile.c_str() + wxT("\""));
- throw FileError(errorMsg + wxT("\n\n") + _("Could not determine volume name for file:") + wxT("\n\"") + inputFile.c_str() + wxT("\""));
- }
+ throw FileError(wxString(_("Could not determine volume name for file:")) + wxT("\n\"") + zToWx(inputFile) + wxT("\""));
Zstring volumeNameFormatted = volumeNameRaw;
- if (!volumeNameFormatted.EndsWith(globalFunctions::FILE_NAME_SEPARATOR))
- volumeNameFormatted += globalFunctions::FILE_NAME_SEPARATOR;
-
- if (volumeNameFormatted != realVolumeLast)
- {
- //release old shadow copy
- if (backupHandle != NULL)
- {
- releaseShadowCopy(backupHandle);
- backupHandle = NULL;
- }
- realVolumeLast.clear(); //...if next call fails...
- shadowVolumeLast.clear(); //...if next call fails...
-
- //start shadow volume copy service:
- wchar_t shadowVolName[1000];
- void* backupHandleTmp = NULL;
- wchar_t errorMessage[1000];
-
- if (!createShadowCopy(
- volumeNameFormatted.c_str(),
- shadowVolName,
- 1000,
- &backupHandleTmp,
- errorMessage,
- 1000))
- {
- wxString errorMsg = _("Error copying locked file %x!");
- errorMsg.Replace(wxT("%x"), Zstring(wxT("\"")) + inputFile + wxT("\""));
- throw FileError(errorMsg + wxT("\n\n") + _("Error starting Volume Shadow Copy Service!") + wxT("\n") +
- wxT("(") + errorMessage + wxT(" Volume: \"") + volumeNameFormatted.c_str() + wxT("\")"));
- }
-
- realVolumeLast = volumeNameFormatted;
- shadowVolumeLast = Zstring(shadowVolName) + globalFunctions::FILE_NAME_SEPARATOR; //shadowVolName NEVER has a trailing backslash
- backupHandle = backupHandleTmp;
- }
+ if (!volumeNameFormatted.EndsWith(common::FILE_NAME_SEPARATOR))
+ volumeNameFormatted += common::FILE_NAME_SEPARATOR;
//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!");
- errorMsg.Replace(wxT("%x"), Zstring(wxT("\"")) + inputFile + wxT("\""));
-
wxString msg = _("Volume name %x not part of filename %y!");
- msg.Replace(wxT("%x"), wxString(wxT("\"")) + volumeNameFormatted.c_str() + wxT("\""), false);
- msg.Replace(wxT("%y"), wxString(wxT("\"")) + inputFile.c_str() + wxT("\""), false);
- throw FileError(errorMsg + wxT("\n\n") + msg);
+ msg.Replace(wxT("%x"), wxString(wxT("\"")) + zToWx(volumeNameFormatted) + wxT("\""), false);
+ msg.Replace(wxT("%y"), wxString(wxT("\"")) + zToWx(inputFile) + wxT("\""), false);
+ throw FileError(msg);
}
+
+ if (!shadowVol.get() || shadowVol->getRealVolume() != volumeNameFormatted)
+ shadowVol.reset(new ShadowVolume(volumeNameFormatted)); //throw (FileError)
+
//return filename alias on shadow copy volume
- return shadowVolumeLast + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length());
+ return shadowVol->getShadowVolume() + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length());
}
-
bgstack15