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