summaryrefslogtreecommitdiff
path: root/lib/ShadowCopy
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ShadowCopy')
-rw-r--r--lib/ShadowCopy/Shadow_Server2003.vcxproj (renamed from lib/ShadowCopy/Shadow_2003.vcxproj)0
-rw-r--r--lib/ShadowCopy/Shadow_Windows7.vcxproj241
-rw-r--r--lib/ShadowCopy/shadow.cpp196
-rw-r--r--lib/ShadowCopy/shadow.h68
4 files changed, 361 insertions, 144 deletions
diff --git a/lib/ShadowCopy/Shadow_2003.vcxproj b/lib/ShadowCopy/Shadow_Server2003.vcxproj
index a893a389..a893a389 100644
--- a/lib/ShadowCopy/Shadow_2003.vcxproj
+++ b/lib/ShadowCopy/Shadow_Server2003.vcxproj
diff --git a/lib/ShadowCopy/Shadow_Windows7.vcxproj b/lib/ShadowCopy/Shadow_Windows7.vcxproj
new file mode 100644
index 00000000..2392fa99
--- /dev/null
+++ b/lib/ShadowCopy/Shadow_Windows7.vcxproj
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>Windows7</ProjectName>
+ <ProjectGuid>{7E217D76-90A5-4B03-A6F8-E7C3ADD22901}</ProjectGuid>
+ <RootNamespace>ShadowDll</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <UseOfAtl>false</UseOfAtl>
+ <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <BuildLog>
+ <Path>$(IntDir)Build.html</Path>
+ </BuildLog>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ProfileGuidedDatabase>
+ </ProfileGuidedDatabase>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <BuildLog>
+ <Path>$(IntDir)Build.html</Path>
+ </BuildLog>
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ProfileGuidedDatabase>
+ </ProfileGuidedDatabase>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <BuildLog>
+ <Path>$(IntDir)Build.html</Path>
+ </BuildLog>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <ProfileGuidedDatabase>
+ </ProfileGuidedDatabase>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <BuildLog>
+ <Path>$(IntDir)Build.html</Path>
+ </BuildLog>
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <ProfileGuidedDatabase>
+ </ProfileGuidedDatabase>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="dll_main.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </PrecompiledHeader>
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ </PrecompiledHeader>
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </PrecompiledHeader>
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ </PrecompiledHeader>
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
+ </ClCompile>
+ <ClCompile Include="shadow.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="shadow.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/lib/ShadowCopy/shadow.cpp b/lib/ShadowCopy/shadow.cpp
index 12e9fa60..5047a698 100644
--- a/lib/ShadowCopy/shadow.cpp
+++ b/lib/ShadowCopy/shadow.cpp
@@ -7,12 +7,9 @@
#include "shadow.h"
#include <algorithm>
#include <string>
-#include <comdef.h>
#include <zen/com_ptr.h>
#include <zen/com_error.h>
-
-#define WIN32_LEAN_AND_MEAN
-#include "windows.h"
+#include <zen/scope_guard.h>
#ifdef USE_SHADOW_XP
#include "xp/inc/vss.h"
@@ -23,13 +20,30 @@
#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
-adapt!
+#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
{
inline
@@ -45,143 +59,99 @@ void copyString(const std::wstring& input, wchar_t* buffer, size_t bufferSize)
}
}
-inline
-void writeErrorMsg(const wchar_t* input, HRESULT hr, wchar_t* output, unsigned int outputLen)
-{
- copyString(generateErrorMsg(input, hr), output, outputLen);
-}
-}
-
-bool shadow::createShadowCopy(const wchar_t* volumeName,
- wchar_t* shadowVolName,
- unsigned int shadowBufferLen,
- ShadowHandle* handle,
- wchar_t* errorMessage,
- unsigned int errorBufferLen)
+shadow::ShadowData createShadowCopy(const wchar_t* volumeName) //throw ComError
{
- //MessageBox(0, L"backup err", L"", 0); */
- *handle = 0;
- HRESULT hr = NULL;
-
ComPtr<IVssBackupComponents> backupComp;
- if (FAILED(hr = CreateVssBackupComponents(backupComp.init())))
{
- 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;
+ HRESULT hr = ::CreateVssBackupComponents(backupComp.init());
+ if (FAILED(hr))
+ {
+ if (hr == E_ACCESSDENIED)
+ throw ComError(L"The caller does not have sufficient backup privileges or is not an administrator.", hr);
+ throw ComError(L"Error calling \"CreateVssBackupComponents\".", hr);
+ }
}
- if (FAILED(hr = backupComp->InitializeForBackup()))
- {
- writeErrorMsg(L"Error calling \"InitializeForBackup\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ZEN_CHECK_COM(backupComp->InitializeForBackup()); //throw ComError
+ ZEN_CHECK_COM(backupComp->SetBackupState(false, false, VSS_BT_FULL)); //throw ComError
- if (FAILED(hr = backupComp->SetBackupState(false, false, VSS_BT_FULL)))
+ auto waitForComFuture = [](IVssAsync& fut)
{
- writeErrorMsg(L"Error calling \"SetBackupState\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ZEN_CHECK_COM(fut.Wait());
- ComPtr<IVssAsync> vssWriters;
- if (FAILED(hr = backupComp->GatherWriterMetadata(vssWriters.init())))
- {
- //this can happen if XP-version of VSS is used on Windows Vista (which needs at least VSS-Server2003 build)
- writeErrorMsg(L"Error calling \"GatherWriterMetadata\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ HRESULT hr = S_OK;
+ ZEN_CHECK_COM(fut.QueryStatus(&hr, NULL)); //check if the async operation succeeded...
+ if (FAILED(hr))
+ throw ComError(L"Error calling \"fut->QueryStatus\".", hr);
+ };
- //wait for shadow copy writers to complete
- if (FAILED(hr = vssWriters->Wait()))
- {
- writeErrorMsg(L"Error calling \"vssWriters->Wait\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ComPtr<IVssAsync> gatherAsync;
+ ZEN_CHECK_COM(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)
- vssWriters->QueryStatus(&hr, NULL); //check if the async operation succeeded...
- if (FAILED(hr))
- {
- writeErrorMsg(L"Error calling \"vssWriters->QueryStatus\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ VSS_ID snapshotSetId = {};
+ ZEN_CHECK_COM(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 snapshotSetId = {0};
- if (FAILED(hr = backupComp->StartSnapshotSet(&snapshotSetId)))
+ VSS_ID SnapShotId = {};
{
- writeErrorMsg(L"Error calling \"StartSnapshotSet\".", hr, errorMessage, errorBufferLen);
- return false;
+ HRESULT hr = backupComp->AddToSnapshotSet(const_cast<wchar_t*>(volumeName), GUID_NULL, &SnapShotId);
+ if (FAILED(hr))
+ {
+ if (hr == VSS_E_VOLUME_NOT_SUPPORTED)
+ throw ComError(L"Volume Shadow Copy Service is not supported on this volume!");
+ throw ComError(L"Error calling \"backupComp->AddToSnapshotSet\".", hr);
+ }
}
- VSS_ID SnapShotId = {0};
- if (FAILED(hr = backupComp->AddToSnapshotSet(const_cast<wchar_t*>(volumeName), GUID_NULL, &SnapShotId)))
- {
- writeErrorMsg(L"Error calling \"AddToSnapshotSet\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ComPtr<IVssAsync> prepareAsync;
+ ZEN_CHECK_COM(backupComp->PrepareForBackup(prepareAsync.init()));
+ waitForComFuture(*prepareAsync);
- ComPtr<IVssAsync> vssPrepare;
- if (FAILED(hr = backupComp->PrepareForBackup(vssPrepare.init())))
- {
- writeErrorMsg(L"Error calling \"PrepareForBackup\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ComPtr<IVssAsync> snapshotAsync;
+ ZEN_CHECK_COM(backupComp->DoSnapshotSet(snapshotAsync.init()));
+ guardSnapShot.dismiss();
+ waitForComFuture(*snapshotAsync);
- if (FAILED(hr = vssPrepare->Wait()))
- {
- writeErrorMsg(L"Error calling \"vssPrepare->Wait\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ VSS_SNAPSHOT_PROP props = {};
+ ZEN_CHECK_COM(backupComp->GetSnapshotProperties(SnapShotId, &props));
+ ZEN_ON_BLOCK_EXIT(::VssFreeSnapshotProperties(&props));
- vssPrepare->QueryStatus(&hr, NULL); //check if the async operation succeeded...
- if (FAILED(hr))
- {
- writeErrorMsg(L"Error calling \"vssPrepare->QueryStatus\".", hr, errorMessage, errorBufferLen);
- return false;
- }
-
- ComPtr<IVssAsync> vssDoShadowCopy;
- if (FAILED(hr = backupComp->DoSnapshotSet(vssDoShadowCopy.init())))
- {
- writeErrorMsg(L"Error calling \"DoSnapshotSet\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ //finally: write volume name of newly created shadow copy
+ return shadow::ShadowData(backupComp, props.m_pwszSnapshotDeviceObject);
+}
+}
- if (FAILED(hr = vssDoShadowCopy->Wait()))
- {
- writeErrorMsg(L"Error calling \"vssDoShadowCopy->Wait\".", hr, errorMessage, errorBufferLen);
- return false;
- }
- vssDoShadowCopy->QueryStatus(&hr, NULL); //check if the async operation succeeded...
- if (FAILED(hr))
+shadow::ShadowHandle shadow::createShadowCopy(const wchar_t* volumeName,
+ wchar_t* errorMessage,
+ unsigned int errorBufferLen)
+{
+ try
{
- writeErrorMsg(L"Error calling \"vssDoShadowCopy->QueryStatus\".", hr, errorMessage, errorBufferLen);
- return false;
+ ShadowData result = ::createShadowCopy(volumeName); //shadow handle owned by caller! throw ComError
+ return new ShadowData(result);
}
-
- VSS_SNAPSHOT_PROP props;
- if (FAILED(hr = backupComp->GetSnapshotProperties(SnapShotId, &props)))
+ catch (const zen::ComError& e)
{
- writeErrorMsg(L"Error calling \"GetSnapshotProperties\".", hr, errorMessage, errorBufferLen);
- return false;
+ copyString(e.toString(), errorMessage, errorBufferLen);
+ return nullptr;
}
+}
- //finally: write volume name of newly created shadow copy
- copyString(props.m_pwszSnapshotDeviceObject, shadowVolName, shadowBufferLen);
-
- VssFreeSnapshotProperties(&props);
-
- *handle = backupComp.release();
- return true;
+void shadow::getShadowVolume(shadow::ShadowHandle handle,
+ wchar_t* buffer,
+ unsigned int bufferLen)
+{
+ copyString(handle->shadowVolume_, buffer, bufferLen);
}
void shadow::releaseShadowCopy(ShadowHandle handle)
{
- if (handle)
- handle->Release();
+ delete handle;
}
diff --git a/lib/ShadowCopy/shadow.h b/lib/ShadowCopy/shadow.h
index 0dfd39a9..68b7141f 100644
--- a/lib/ShadowCopy/shadow.h
+++ b/lib/ShadowCopy/shadow.h
@@ -26,23 +26,23 @@ namespace shadow
--------------*/
//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize
+struct ShadowData;
+typedef ShadowData* ShadowHandle;
-typedef IVssBackupComponents* ShadowHandle;
-
-//volumeName must end with "\", while shadowVolName does not end with "\"
+//volumeName *must* end with "\"
SHADOWDLL_API
-bool createShadowCopy(const wchar_t* volumeName, // in
- wchar_t* shadowVolName, // out
- unsigned int shadowBufferLen, // in
- ShadowHandle* handle, // out
- wchar_t* errorMessage, // out
- unsigned int errorBufferLen); // in
-
+ShadowHandle createShadowCopy(const wchar_t* volumeName, // in Returns nullptr on failure!
+ wchar_t* errorMessage, // out
+ unsigned int errorBufferLen); // in
//don't forget to release the backupHandle after shadow copy is not needed anymore!
SHADOWDLL_API
void releaseShadowCopy(ShadowHandle handle);
+SHADOWDLL_API
+void getShadowVolume(ShadowHandle handle, //shadowVolName does *not* end with "\"
+ wchar_t* buffer,
+ unsigned int bufferLen);
//##########################################################################################
@@ -50,21 +50,24 @@ void releaseShadowCopy(ShadowHandle handle);
/*----------
|typedefs|
----------*/
-typedef bool (*CreateShadowCopyFct)(const wchar_t* volumeName,
- wchar_t* shadowVolName,
- unsigned int shadowBufferLen,
- ShadowHandle* handle,
- wchar_t* errorMessage,
- unsigned int errorBufferLen);
+typedef ShadowHandle (*CreateShadowCopyFct)(const wchar_t* volumeName,
+ wchar_t* errorMessage,
+ unsigned int errorBufferLen);
typedef void (*ReleaseShadowCopyFct)(ShadowHandle handle);
+typedef void (*GetShadowVolumeFct)(ShadowHandle handle,
+ wchar_t* buffer,
+ unsigned int bufferLen);
+
+
/*--------------
|symbol names|
--------------*/
//(use const pointers to ensure internal linkage)
-const char createShadowCopyFctName[] = "createShadowCopy";
+const char createShadowCopyFctName [] = "createShadowCopy";
const char releaseShadowCopyFctName[] = "releaseShadowCopy";
+const char getShadowVolumeFctName [] = "getShadowVolume";
/*---------------
|library names|
@@ -73,21 +76,24 @@ const char releaseShadowCopyFctName[] = "releaseShadowCopy";
inline
const wchar_t* getDllName()
{
- /*
- distinguish a bunch of VSS builds: we use XP and Server 2003 implementations...
- VSS version and compatibility overview: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx
- */
- return zen::winServer2003orLater() ?
- (zen::is64BitBuild ?
- L"Shadow_Server2003_x64.dll" :
- L"Shadow_Server2003_Win32.dll") :
-
- (zen::is64BitBuild ?
- L"Shadow_XP_x64.dll" :
- L"Shadow_XP_Win32.dll");
+ // distinguish a bunch of VSS builds: we use XP, Server 2003 and Server 2008 R2 implementations...
+ // VSS version and compatibility overview: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx
+
+ if (zen::win7OrLater()) //Windows Server 2008 R2 or Windows 7
+ return zen::is64BitBuild ?
+ L"Shadow_Windows7_x64.dll" :
+ L"Shadow_Windows7_Win32.dll";
+ //else if (vistaOrLater()) -> skip Windows Server 2008 and Windows Vista
+ // ;
+ else if (zen::winServer2003orLater()) //Windows Server 2003 and Windows Server 2003 R2
+ return zen::is64BitBuild ?
+ L"Shadow_Server2003_x64.dll" :
+ L"Shadow_Server2003_Win32.dll";
+ else //Windows XP
+ return zen::is64BitBuild ?
+ L"Shadow_XP_x64.dll" :
+ L"Shadow_XP_Win32.dll";
}
}
-
-
#endif //SHADOWCOPY_H
bgstack15