diff options
Diffstat (limited to 'lib/ShadowCopy/shadow.cpp')
-rw-r--r-- | lib/ShadowCopy/shadow.cpp | 199 |
1 files changed, 0 insertions, 199 deletions
diff --git a/lib/ShadowCopy/shadow.cpp b/lib/ShadowCopy/shadow.cpp deleted file mode 100644 index adc7c5c2..00000000 --- a/lib/ShadowCopy/shadow.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// ************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * -// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * -// ************************************************************************** - -#include "shadow.h" -#include <algorithm> -#include <string> -#include <zen/com_ptr.h> -#include <zen/com_error.h> -#include <zen/scope_guard.h> -#include <boost/thread/tss.hpp> - -#ifdef USE_SHADOW_XP -#include "xp/inc/vss.h" -#include "xp/inc/vswriter.h" -#include "xp/inc/vsbackup.h" - -#elif defined USE_SHADOW_2003 -#include "Server 2003/inc/vss.h" -#include "Server 2003/inc/vswriter.h" -#include "Server 2003/inc/vsbackup.h" - -#elif defined USE_SHADOW_WINDOWS7 -#include <vss.h> // -#include <vswriter.h> //part of Windows SDK for Windows 7 -#include <vsbackup.h> // -#pragma comment(lib, "VssApi.lib") - -#else -#error adapt! -#endif - -using namespace zen; - - -struct shadow::ShadowData -{ - ShadowData(const ComPtr<IVssBackupComponents>& backupComp, - const std::wstring& shadowVolume) : backupComp_(backupComp), shadowVolume_(shadowVolume) {} - - ComPtr<IVssBackupComponents> backupComp_; - std::wstring shadowVolume_; -}; - - -namespace -{ -std::wstring formatVssError(HRESULT hr) //at least the one's from IVssBackupComponents::AddToSnapshotSet; return empty if no format found -{ - switch (hr) - { - case VSS_E_BAD_STATE: - return L"VSS_E_BAD_STATE"; - case VSS_E_MAXIMUM_NUMBER_OF_VOLUMES_REACHED: - return L"VSS_E_MAXIMUM_NUMBER_OF_VOLUMES_REACHED"; - case VSS_E_MAXIMUM_NUMBER_OF_SNAPSHOTS_REACHED: - return L"VSS_E_MAXIMUM_NUMBER_OF_SNAPSHOTS_REACHED"; - case VSS_E_OBJECT_NOT_FOUND: - return L"VSS_E_OBJECT_NOT_FOUND"; - case VSS_E_PROVIDER_NOT_REGISTERED: - return L"VSS_E_PROVIDER_NOT_REGISTERED"; - case VSS_E_PROVIDER_VETO: - return L"VSS_E_PROVIDER_VETO"; - case VSS_E_VOLUME_NOT_SUPPORTED: - return L"VSS_E_VOLUME_NOT_SUPPORTED"; - case VSS_E_VOLUME_NOT_SUPPORTED_BY_PROVIDER: - return L"VSS_E_VOLUME_NOT_SUPPORTED_BY_PROVIDER"; - case VSS_E_UNEXPECTED_PROVIDER_ERROR: - return L"VSS_E_UNEXPECTED_PROVIDER_ERROR"; - default: - return std::wstring(); - } -} - - -shadow::ShadowData createShadowCopy(const wchar_t* volumeName) //throw SysError -{ - ComPtr<IVssBackupComponents> backupComp; - { - HRESULT hr = ::CreateVssBackupComponents(backupComp.init()); - if (FAILED(hr)) - { - if (hr == E_ACCESSDENIED) - throw SysError(formatComError(L"The caller does not have sufficient backup privileges or is not an administrator.", hr)); - throw SysError(formatComError(L"Error calling \"CreateVssBackupComponents\".", hr)); - } - } - - ZEN_COM_CHECK(backupComp->InitializeForBackup()); //throw SysError - - //SetContext() only required if different than the default, VSS_CTX_BACKUP; not implemented on XP!!! - //ZEN_COM_CHECK(backupComp->SetContext(VSS_CTX_BACKUP)); //throw SysError - - ZEN_COM_CHECK(backupComp->SetBackupState(false, false, VSS_BT_FULL)); //throw SysError - - - //the Shadow Copy Optimization Writer removes items it considers non-essential, - //http://msdn.microsoft.com/en-US/library/bb968827#shadow_copy_optimization_writer - //like the exclusions in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot - //http://msdn.microsoft.com/en-us/library/aa819132%28v=vs.85%29.aspx - //Outlook *.ost files in particular: - //https://sourceforge.net/p/freefilesync/discussion/help/thread/722dcbfb - const VSS_ID disabledWriters[] = { { 0x4dc3bdd4, 0xab48, 0x4d07, { 0xad, 0xb0, 0x3b, 0xee, 0x29, 0x26, 0xfd, 0x7f } } }; //Shadow Copy Optimization Writer - { - HRESULT hr = backupComp->DisableWriterClasses(disabledWriters, 1); - if (FAILED(hr) && hr != E_NOTIMPL) //DisableWriterClasses() is not implemented on Windows XP, although MSDN documented otherwise! - throw SysError(formatComError(L"Error calling \"backupComp->DisableWriterClasses\".", hr)); - } - - - auto waitForComFuture = [](IVssAsync& fut) - { - ZEN_COM_CHECK(fut.Wait()); - - HRESULT hr = S_OK; - ZEN_COM_CHECK(fut.QueryStatus(&hr, nullptr)); //check if the async operation succeeded... - if (FAILED(hr)) - throw SysError(formatComError(L"Error calling \"fut->QueryStatus\".", hr)); - }; - - ComPtr<IVssAsync> gatherAsync; - ZEN_COM_CHECK(backupComp->GatherWriterMetadata(gatherAsync.init())); - waitForComFuture(*gatherAsync); //failure can happen if XP-version of VSS is used on Windows Vista (which needs at least VSS-Server2003 build) - - VSS_ID snapshotSetId = {}; - ZEN_COM_CHECK(backupComp->StartSnapshotSet(&snapshotSetId)); - ScopeGuard guardSnapShot = makeGuard([&] { backupComp->AbortBackup(); }); - //Quote: "This method must be called if a backup operation terminates after the creation of a - //shadow copy set with "StartSnapshotSet" and before "DoSnapshotSet" returns." - - VSS_ID SnapShotId = {}; - { - HRESULT hr = backupComp->AddToSnapshotSet(const_cast<wchar_t*>(volumeName), GUID_NULL, &SnapShotId); - if (FAILED(hr)) - { - if (hr == VSS_E_VOLUME_NOT_SUPPORTED) - throw SysError(L"Volume Shadow Copy Service is not supported on this volume!"); - const std::wstring vssError = formatVssError(hr); - if (!vssError.empty()) - throw SysError(L"Error calling \"backupComp->AddToSnapshotSet\": " + vssError); - else - throw SysError(formatComError(L"Error calling \"backupComp->AddToSnapshotSet\".", hr)); - } - } - - ComPtr<IVssAsync> prepareAsync; - ZEN_COM_CHECK(backupComp->PrepareForBackup(prepareAsync.init())); - waitForComFuture(*prepareAsync); - - ComPtr<IVssAsync> snapshotAsync; - ZEN_COM_CHECK(backupComp->DoSnapshotSet(snapshotAsync.init())); - guardSnapShot.dismiss(); - waitForComFuture(*snapshotAsync); - - VSS_SNAPSHOT_PROP props = {}; - ZEN_COM_CHECK(backupComp->GetSnapshotProperties(SnapShotId, &props)); - ZEN_ON_SCOPE_EXIT(::VssFreeSnapshotProperties(&props)); - - //finally: write volume name of newly created shadow copy - return shadow::ShadowData(backupComp, props.m_pwszSnapshotDeviceObject); -} - -boost::thread_specific_ptr<std::wstring> lastErrorMessage; //use "thread_local" in C++11 -} - - -shadow::ShadowHandle shadow::createShadowCopy(const wchar_t* volumeName) -{ - try - { - ShadowData result = ::createShadowCopy(volumeName); //throw SysError - return new ShadowData(result); //shadow handle owned by caller! std::bad_alloc? - } - catch (const zen::SysError& e) - { - lastErrorMessage.reset(new std::wstring(e.toString())); - return nullptr; - } -} - - -const wchar_t* shadow::getShadowVolume(shadow::ShadowHandle handle) -{ - return handle ? handle->shadowVolume_.c_str() : nullptr; //better fail in client code than here! -} - - -void shadow::releaseShadowCopy(ShadowHandle handle) -{ - delete handle; -} - - -const wchar_t* shadow::getLastError() -{ - return !lastErrorMessage.get() ? L"" : lastErrorMessage->c_str(); -} |