summaryrefslogtreecommitdiff
path: root/lib/shadow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/shadow.cpp')
-rw-r--r--lib/shadow.cpp69
1 files changed, 32 insertions, 37 deletions
diff --git a/lib/shadow.cpp b/lib/shadow.cpp
index 0a34ae5a..f4d7f3af 100644
--- a/lib/shadow.cpp
+++ b/lib/shadow.cpp
@@ -40,53 +40,49 @@ bool runningWOW64() //test if process is running under WOW64 (reference http://m
class ShadowCopy::ShadowVolume
{
public:
- ShadowVolume(const Zstring& volumeNameFormatted) : //throw(FileError)
- createShadowCopy (getDllName(), createShadowCopyFctName),
- releaseShadowCopy(getDllName(), releaseShadowCopyFctName),
- getShadowVolume (getDllName(), getShadowVolumeFctName),
+ ShadowVolume(const Zstring& volumeNamePf) : //throw(FileError)
+ createShadowCopy (getDllName(), funName_createShadowCopy),
+ releaseShadowCopy(getDllName(), funName_releaseShadowCopy),
+ getShadowVolume (getDllName(), funName_getShadowVolume),
+ getLastError (getDllName(), funName_getLastError),
backupHandle(nullptr)
{
//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)
if (runningWOW64())
- throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" +
- _("Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version."));
+ throw FileError(_("Cannot access Volume Shadow Copy Service.") + L"\n" +
+ _("Please use FreeFileSync 64-bit version to create shadow copies on this system."));
//check if shadow copy dll was loaded correctly
- if (!createShadowCopy || !releaseShadowCopy || !getShadowVolume)
- throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" +
- replaceCpy(_("Cannot load file %x."), L"%x", std::wstring(L"\"") + getDllName() + L"\""));
+ if (!createShadowCopy || !releaseShadowCopy || !getShadowVolume || !getLastError)
+ throw FileError(_("Cannot access Volume Shadow Copy Service.") + L"\n" +
+ replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(getDllName())));
//---------------------------------------------------------------------------------------------------------
//start shadow volume copy service:
- const unsigned int BUFFER_SIZE = 10000;
- std::vector<wchar_t> msgBuffer(BUFFER_SIZE);
- backupHandle = createShadowCopy(volumeNameFormatted.c_str(),
- &msgBuffer[0], BUFFER_SIZE);
+ backupHandle = createShadowCopy(volumeNamePf.c_str());
if (!backupHandle)
- throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" +
- &msgBuffer[0] + L" Volume: \"" + volumeNameFormatted + L"\"");
+ throw FileError(_("Cannot access Volume Shadow Copy Service.") + L"\n" +
+ getLastError() + L" Volume: " + fmtFileName(volumeNamePf));
- std::vector<wchar_t> volBuffer(BUFFER_SIZE);
- getShadowVolume(backupHandle, &volBuffer[0], BUFFER_SIZE);
- shadowVol = Zstring(&volBuffer[0]) + FILE_NAME_SEPARATOR; //shadowVolName NEVER has a trailing backslash
+ shadowVolPf = appendSeparator(getShadowVolume(backupHandle)); //shadowVolName NEVER has a trailing backslash
}
~ShadowVolume() { releaseShadowCopy(backupHandle); } //fast! no performance optimization necessary
- Zstring getShadowVolumeName() const { return shadowVol; } //with trailing path separator
+ Zstring geNamePf() const { return shadowVolPf; } //with trailing path separator
private:
ShadowVolume(const ShadowVolume&);
ShadowVolume& operator=(const ShadowVolume&);
- const DllFun<CreateShadowCopyFct> createShadowCopy;
- const DllFun<ReleaseShadowCopyFct> releaseShadowCopy;
- const DllFun<GetShadowVolumeFct> getShadowVolume;
-
- Zstring shadowVol;
+ const DllFun<FunType_createShadowCopy> createShadowCopy;
+ const DllFun<FunType_releaseShadowCopy> releaseShadowCopy;
+ const DllFun<FunType_getShadowVolume> getShadowVolume;
+ const DllFun<FunType_getLastError> getLastError;
+ Zstring shadowVolPf;
ShadowHandle backupHandle;
};
//#############################################################################################################
@@ -94,34 +90,33 @@ private:
Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
{
- std::vector<wchar_t> volBuffer(1000);
+ DWORD bufferSize = 10000;
+ std::vector<wchar_t> volBuffer(bufferSize);
if (!::GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName,
&volBuffer[0], //__out LPTSTR lpszVolumePathName,
- static_cast<DWORD>(volBuffer.size()))) //__in DWORD cchBufferLength
- throw FileError(_("Cannot determine volume name for file:") + L"\n\"" + inputFile + L"\"");
+ bufferSize)) //__in DWORD cchBufferLength
+ throw FileError(replaceCpy(_("Path %x does not contain a volume name."), L"%x", fmtFileName(inputFile)));
- Zstring volumeNameFormatted = &volBuffer[0];
- if (!endsWith(volumeNameFormatted, FILE_NAME_SEPARATOR))
- volumeNameFormatted += FILE_NAME_SEPARATOR;
+ const Zstring volumeNamePf = appendSeparator(&volBuffer[0]);
//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!
+ const size_t pos = inputFile.find(volumeNamePf); //inputFile needs NOT to begin with volumeNamePf: consider for example \\?\ prefix!
if (pos == Zstring::npos)
{
std::wstring msg = _("Volume name %x not part of file name %y!");
- replace(msg, L"%x", std::wstring(L"\"") + volumeNameFormatted + L"\"", false);
- replace(msg, L"%y", std::wstring(L"\"") + inputFile + L"\"", false);
+ replace(msg, L"%x", fmtFileName(volumeNamePf), false);
+ replace(msg, L"%y", fmtFileName(inputFile), false);
throw FileError(msg);
}
//get or create instance of shadow volume
- VolNameShadowMap::const_iterator iter = shadowVol.find(volumeNameFormatted);
+ VolNameShadowMap::const_iterator iter = shadowVol.find(volumeNamePf);
if (iter == shadowVol.end())
{
- auto newEntry = std::make_shared<ShadowVolume>(volumeNameFormatted);
- iter = shadowVol.insert(std::make_pair(volumeNameFormatted, newEntry)).first;
+ auto newEntry = std::make_shared<ShadowVolume>(volumeNamePf);
+ iter = shadowVol.insert(std::make_pair(volumeNamePf, newEntry)).first;
}
//return filename alias on shadow copy volume
- return iter->second->getShadowVolumeName() + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length());
+ return iter->second->geNamePf() + Zstring(inputFile.c_str() + pos + volumeNamePf.length());
}
bgstack15