diff options
Diffstat (limited to 'lib/shadow.cpp')
-rw-r--r-- | lib/shadow.cpp | 69 |
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()); } |