From 8318453bf9d4fd50b137ff6c6fc8d1fd22aa6395 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:07:15 +0200 Subject: 3.7 --- shared/ShadowCopy/Shadow_2003.vcproj | 413 +++++++++++++++++++++++++++++++++++ shared/ShadowCopy/Shadow_XP.vcproj | 413 +++++++++++++++++++++++++++++++++++ shared/ShadowCopy/dllmain.cpp | 27 +++ shared/ShadowCopy/shadow.cpp | 204 +++++++++++++++++ shared/ShadowCopy/shadow.h | 55 +++++ 5 files changed, 1112 insertions(+) create mode 100644 shared/ShadowCopy/Shadow_2003.vcproj create mode 100644 shared/ShadowCopy/Shadow_XP.vcproj create mode 100644 shared/ShadowCopy/dllmain.cpp create mode 100644 shared/ShadowCopy/shadow.cpp create mode 100644 shared/ShadowCopy/shadow.h (limited to 'shared/ShadowCopy') diff --git a/shared/ShadowCopy/Shadow_2003.vcproj b/shared/ShadowCopy/Shadow_2003.vcproj new file mode 100644 index 00000000..49730440 --- /dev/null +++ b/shared/ShadowCopy/Shadow_2003.vcproj @@ -0,0 +1,413 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shared/ShadowCopy/Shadow_XP.vcproj b/shared/ShadowCopy/Shadow_XP.vcproj new file mode 100644 index 00000000..74b231de --- /dev/null +++ b/shared/ShadowCopy/Shadow_XP.vcproj @@ -0,0 +1,413 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shared/ShadowCopy/dllmain.cpp b/shared/ShadowCopy/dllmain.cpp new file mode 100644 index 00000000..7db39bff --- /dev/null +++ b/shared/ShadowCopy/dllmain.cpp @@ -0,0 +1,27 @@ +// ************************************************************************** +// * 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) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// + +#define WIN32_LEAN_AND_MEAN +#include + + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/shared/ShadowCopy/shadow.cpp b/shared/ShadowCopy/shadow.cpp new file mode 100644 index 00000000..b15bd4f9 --- /dev/null +++ b/shared/ShadowCopy/shadow.cpp @@ -0,0 +1,204 @@ +// ************************************************************************** +// * 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) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#include "shadow.h" + +#define WIN32_LEAN_AND_MEAN +#include "windows.h" + +#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" +#else +adapt! +#endif + +#include +#include +#include +#include + +//typedef GUID VSS_ID; + + +void writeString(const wchar_t* input, wchar_t* output, unsigned int outputBufferLen) +{ + const size_t newSize = min(wcslen(input) + 1, outputBufferLen); //including null-termination + memcpy(output, input, newSize * sizeof(wchar_t)); + output[newSize-1] = 0; //if output buffer is too small... +} + + +std::wstring numberToHexString(const long number) +{ + wchar_t result[100]; + swprintf(result, 100, L"0x%08x", number); + return std::wstring(result); +} + + +void writeErrorMsg(const wchar_t* input, HRESULT hr, wchar_t* output, unsigned int outputBufferLen) +{ + std::wstring formattedMsg(input); + formattedMsg += L" ("; + formattedMsg += numberToHexString(hr); + formattedMsg += L": "; + formattedMsg += _com_error(hr).ErrorMessage(); + formattedMsg += L")"; + + writeString(formattedMsg.c_str(), output, outputBufferLen); +} + + +bool shadow::createShadowCopy(const wchar_t* volumeName, + wchar_t* shadowVolName, + unsigned int shadowBufferLen, + void** backupHandle, + wchar_t* errorMessage, + unsigned int errorBufferLen) +{ + //MessageBox(0, L"backup err", L"", 0); */ + *backupHandle = NULL; + HRESULT hr = NULL; + + IVssBackupComponents* pBackupComponents = NULL; + if (FAILED(hr = CreateVssBackupComponents(&pBackupComponents))) + { + if (hr == E_ACCESSDENIED) + writeErrorMsg(L"The caller does not have sufficient backup privileges or is not an administrator.", hr, errorMessage, errorBufferLen); + else + writeErrorMsg(L"Error calling \"CreateVssBackupComponents\".", hr, errorMessage, errorBufferLen); + return false; + } + + + if (FAILED(hr = pBackupComponents->InitializeForBackup())) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"InitializeForBackup\".", hr, errorMessage, errorBufferLen); + return false; + } + + + IVssAsync* pWriteMetaData = NULL; + if (FAILED(hr = pBackupComponents->GatherWriterMetadata( &pWriteMetaData ))) + { //this can happen if XP-version of VSS is used on Windows Vista (which needs at least VSS-Server2003 build) + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"GatherWriterMetadata\".", hr, errorMessage, errorBufferLen); + return false; + } + + //wait for shadow copy writers to complete + hr = pWriteMetaData->Wait(); + if (SUCCEEDED(hr)) + pWriteMetaData->QueryStatus(&hr, NULL); //check if the async operation succeeded... + + pWriteMetaData->Release(); + if (FAILED(hr)) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"ppWriteMetaData->Wait\".", hr, errorMessage, errorBufferLen); + return false; + } + + + VSS_ID snapshotSetId = {0}; + if (FAILED(hr = pBackupComponents->StartSnapshotSet( &snapshotSetId ))) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"StartSnapshotSet\".", hr, errorMessage, errorBufferLen); + return false; + } + + + VSS_ID SnapShotId = {0}; + if (FAILED(hr = pBackupComponents->AddToSnapshotSet(const_cast(volumeName), GUID_NULL, &SnapShotId))) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"AddToSnapshotSet\".", hr, errorMessage, errorBufferLen); + return false; + } + + + if (FAILED(hr = pBackupComponents->SetBackupState( false, false, VSS_BT_FULL ))) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"SetBackupState\".", hr, errorMessage, errorBufferLen); + return false; + } + + + IVssAsync* pPrepare = NULL; + if (FAILED(hr = pBackupComponents->PrepareForBackup( &pPrepare ))) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"PrepareForBackup\".", hr, errorMessage, errorBufferLen); + return false; + } + + hr = pPrepare->Wait(); + if (SUCCEEDED(hr)) + pPrepare->QueryStatus(&hr, NULL); //check if the async operation succeeded... + + pPrepare->Release(); + if (FAILED(hr)) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"pPrepare->Wait\".", hr, errorMessage, errorBufferLen); + return false; + } + + + IVssAsync* pDoShadowCopy = NULL; + if (FAILED(hr = pBackupComponents->DoSnapshotSet( &pDoShadowCopy ))) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"DoSnapshotSet\".", hr, errorMessage, errorBufferLen); + return false; + } + + hr = pDoShadowCopy->Wait(); + if (SUCCEEDED(hr)) + pDoShadowCopy->QueryStatus(&hr, NULL); //check if the async operation succeeded... + + pDoShadowCopy->Release(); + if (FAILED(hr)) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"pPrepare->Wait\".", hr, errorMessage, errorBufferLen); + return false; + } + + VSS_SNAPSHOT_PROP props; + if (FAILED(hr = pBackupComponents->GetSnapshotProperties( SnapShotId, &props ))) + { + releaseShadowCopy(pBackupComponents); + writeErrorMsg(L"Error calling \"GetSnapshotProperties\".", hr, errorMessage, errorBufferLen); + return false; + } + + //finally: write volume name of newly created shadow copy + writeString(props.m_pwszSnapshotDeviceObject, shadowVolName, shadowBufferLen); + + VssFreeSnapshotProperties(&props); + + *backupHandle = pBackupComponents; + + return true; +} + + +void shadow::releaseShadowCopy(void* backupHandle) +{ + if (backupHandle != NULL) + static_cast(backupHandle)->Release(); +} diff --git a/shared/ShadowCopy/shadow.h b/shared/ShadowCopy/shadow.h new file mode 100644 index 00000000..61d6ae7e --- /dev/null +++ b/shared/ShadowCopy/shadow.h @@ -0,0 +1,55 @@ +// ************************************************************************** +// * 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) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#ifndef SHADOWCOPY_H +#define SHADOWCOPY_H + +#ifdef SHADOWDLL_EXPORTS +#define SHADOWDLL_API extern "C" __declspec(dllexport) +#else +#define SHADOWDLL_API extern "C" __declspec(dllimport) +#endif + + +namespace Shadow +{ +//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize + + +//volumeName must end with "\", while shadowVolName does not end with "\" +SHADOWDLL_API +bool createShadowCopy(const wchar_t* volumeName, + wchar_t* shadowVolName, + unsigned int shadowBufferLen, + void** backupHandle, + wchar_t* errorMessage, + unsigned int errorBufferLen); + + +//don't forget to release the backupHandle after shadow copy is not needed anymore! +SHADOWDLL_API +void releaseShadowCopy(void* backupHandle); + + + +//function typedefs +typedef bool (*CreateShadowCopyFct)(const wchar_t* volumeName, + wchar_t* shadowVolName, + unsigned int shadowBufferLen, + void** backupHandle, + wchar_t* errorMessage, + unsigned int errorBufferLen); + +typedef void (*ReleaseShadowCopyFct)(void* backupHandle); + +//function names +const char* const createShadowCopyFctName = "createShadowCopy"; +const char* const releaseShadowCopyFctName = "releaseShadowCopy"; +} + + + +#endif //SHADOWCOPY_H -- cgit