summaryrefslogtreecommitdiff
path: root/shared/ShadowCopy/shadow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'shared/ShadowCopy/shadow.cpp')
-rw-r--r--shared/ShadowCopy/shadow.cpp71
1 files changed, 46 insertions, 25 deletions
diff --git a/shared/ShadowCopy/shadow.cpp b/shared/ShadowCopy/shadow.cpp
index b15bd4f9..1fb78769 100644
--- a/shared/ShadowCopy/shadow.cpp
+++ b/shared/ShadowCopy/shadow.cpp
@@ -15,7 +15,7 @@
#include "xp/inc/vsbackup.h"
#elif defined USE_SHADOW_2003
-#include "Server 2003/inc/vss.h"
+#include "Server 2003/inc/vss.h"
#include "Server 2003/inc/vswriter.h"
#include "Server 2003/inc/vsbackup.h"
#else
@@ -30,6 +30,37 @@ adapt!
//typedef GUID VSS_ID;
+
+//IShellItem resource management: better handled with boost::shared_ptr or CComPtr, but we avoid dependency with boost and ATL in this case
+template <class T>
+class ItemHolder
+{
+public:
+ ItemHolder(T* item) : item_(item) {}
+ ~ItemHolder()
+ {
+ if (item_)
+ item_->Release();
+ }
+
+ T* release()
+{
+T* rv = item_;
+item_ = 0;
+ return rv;
+ }
+
+ T* operator->() const
+{
+ return item_;
+ }
+private:
+ ItemHolder(const ItemHolder&);
+ ItemHolder& operator=(const ItemHolder&);
+ T* item_;
+};
+
+
void writeString(const wchar_t* input, wchar_t* output, unsigned int outputBufferLen)
{
const size_t newSize = min(wcslen(input) + 1, outputBufferLen); //including null-termination
@@ -59,7 +90,7 @@ void writeErrorMsg(const wchar_t* input, HRESULT hr, wchar_t* output, unsigned i
}
-bool shadow::createShadowCopy(const wchar_t* volumeName,
+bool Shadow::createShadowCopy(const wchar_t* volumeName,
wchar_t* shadowVolName,
unsigned int shadowBufferLen,
void** backupHandle,
@@ -70,8 +101,8 @@ bool shadow::createShadowCopy(const wchar_t* volumeName,
*backupHandle = NULL;
HRESULT hr = NULL;
- IVssBackupComponents* pBackupComponents = NULL;
- if (FAILED(hr = CreateVssBackupComponents(&pBackupComponents)))
+ IVssBackupComponents* pBackupPtr = NULL;
+ if (FAILED(hr = CreateVssBackupComponents(&pBackupPtr)))
{
if (hr == E_ACCESSDENIED)
writeErrorMsg(L"The caller does not have sufficient backup privileges or is not an administrator.", hr, errorMessage, errorBufferLen);
@@ -80,19 +111,25 @@ bool shadow::createShadowCopy(const wchar_t* volumeName,
return false;
}
+ ItemHolder<IVssBackupComponents> pBackupComponents(pBackupPtr);
if (FAILED(hr = pBackupComponents->InitializeForBackup()))
{
- releaseShadowCopy(pBackupComponents);
writeErrorMsg(L"Error calling \"InitializeForBackup\".", hr, errorMessage, errorBufferLen);
return false;
}
+ if (FAILED(hr = pBackupComponents->SetBackupState(false, false, VSS_BT_FULL)))
+ {
+ writeErrorMsg(L"Error calling \"SetBackupState\".", 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;
}
@@ -105,7 +142,6 @@ bool shadow::createShadowCopy(const wchar_t* volumeName,
pWriteMetaData->Release();
if (FAILED(hr))
{
- releaseShadowCopy(pBackupComponents);
writeErrorMsg(L"Error calling \"ppWriteMetaData->Wait\".", hr, errorMessage, errorBufferLen);
return false;
}
@@ -114,7 +150,6 @@ bool shadow::createShadowCopy(const wchar_t* volumeName,
VSS_ID snapshotSetId = {0};
if (FAILED(hr = pBackupComponents->StartSnapshotSet( &snapshotSetId )))
{
- releaseShadowCopy(pBackupComponents);
writeErrorMsg(L"Error calling \"StartSnapshotSet\".", hr, errorMessage, errorBufferLen);
return false;
}
@@ -123,24 +158,14 @@ bool shadow::createShadowCopy(const wchar_t* volumeName,
VSS_ID SnapShotId = {0};
if (FAILED(hr = pBackupComponents->AddToSnapshotSet(const_cast<wchar_t*>(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;
}
@@ -152,16 +177,14 @@ bool shadow::createShadowCopy(const wchar_t* volumeName,
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 )))
+ if (FAILED(hr = pBackupComponents->DoSnapshotSet(&pDoShadowCopy)))
{
- releaseShadowCopy(pBackupComponents);
writeErrorMsg(L"Error calling \"DoSnapshotSet\".", hr, errorMessage, errorBufferLen);
return false;
}
@@ -173,7 +196,6 @@ bool shadow::createShadowCopy(const wchar_t* volumeName,
pDoShadowCopy->Release();
if (FAILED(hr))
{
- releaseShadowCopy(pBackupComponents);
writeErrorMsg(L"Error calling \"pPrepare->Wait\".", hr, errorMessage, errorBufferLen);
return false;
}
@@ -181,7 +203,6 @@ bool shadow::createShadowCopy(const wchar_t* volumeName,
VSS_SNAPSHOT_PROP props;
if (FAILED(hr = pBackupComponents->GetSnapshotProperties( SnapShotId, &props )))
{
- releaseShadowCopy(pBackupComponents);
writeErrorMsg(L"Error calling \"GetSnapshotProperties\".", hr, errorMessage, errorBufferLen);
return false;
}
@@ -191,13 +212,13 @@ bool shadow::createShadowCopy(const wchar_t* volumeName,
VssFreeSnapshotProperties(&props);
- *backupHandle = pBackupComponents;
+ *backupHandle = pBackupComponents.release(); //release ownership
return true;
}
-void shadow::releaseShadowCopy(void* backupHandle)
+void Shadow::releaseShadowCopy(void* backupHandle)
{
if (backupHandle != NULL)
static_cast<IVssBackupComponents*>(backupHandle)->Release();
bgstack15