Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

514 lines
16 KiB

/*
**++
**
** Copyright (c) 2000-2001 Microsoft Corporation
**
**
** Module Name:
**
** vsreq.cpp
**
**
** Abstract:
**
** Sample program to
** - obtain and display the Writer metadata.
** - create a snapshot set
**
** Author:
**
** Adi Oltean [aoltean] 05-Dec-2000
**
** The sample is based on the Metasnap test program written by Michael C. Johnson.
**
**
** Revision History:
**
**--
*/
///////////////////////////////////////////////////////////////////////////////
// Includes
#include "vsreq.h"
///////////////////////////////////////////////////////////////////////////////
// Processing functions
CVssSampleRequestor::CVssSampleRequestor()
{
// Initialize data members
m_bCoInitializeSucceeded = false;
m_bBootableSystemState = false;
m_bComponentSelectionEnabled = false;
m_pBackupComponents = NULL;
m_nVolumesCount = 0;
m_hr = S_OK;
m_pwszXmlFile = NULL;
m_pXmlFile = NULL;
// For safety
for (int nIndex=0; nIndex<MAX_VOLUMES; nIndex++) {
m_ppwszVolumesList[nIndex] = NULL;
m_ppwszVolumeNamesList[nIndex] = NULL;
}
// Print display header
wprintf(L"\nVSS Requestor Sample application, version 1.0\n");
}
CVssSampleRequestor::~CVssSampleRequestor()
{
// Deallocate some internal strings
delete m_pwszXmlFile;
// delete the allocated volumes
for (int nIndex=0; nIndex<m_nVolumesCount; nIndex++) {
free(m_ppwszVolumesList[nIndex]);
free(m_ppwszVolumeNamesList[nIndex]);
}
// Close the Xml file
if (m_pXmlFile)
fclose(m_pXmlFile);
// Releasing backup components prior to the CoUninitialize call
m_pBackupComponents = NULL;
// Unloading the COM library
if (m_bCoInitializeSucceeded)
CoUninitialize();
}
void CVssSampleRequestor::Initialize()
{
wprintf (L"\n----------------- Initializing ---------------------\n");
// Initialize COM library
CHECK_NOFAIL(CoInitializeEx (NULL, COINIT_MULTITHREADED));
m_bCoInitializeSucceeded = true;
wprintf (L"COM library initialized.\n");
// Initialize COM security
CHECK_SUCCESS
(
CoInitializeSecurity
(
NULL, // IN PSECURITY_DESCRIPTOR pSecDesc,
-1, // IN LONG cAuthSvc,
NULL, // IN SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
NULL, // IN void *pReserved1,
RPC_C_AUTHN_LEVEL_CONNECT, // IN DWORD dwAuthnLevel,
RPC_C_IMP_LEVEL_IMPERSONATE, // IN DWORD dwImpLevel,
NULL, // IN void *pAuthList,
EOAC_NONE, // IN DWORD dwCapabilities,
NULL // IN void *pReserved3
)
);
wprintf (L"COM security initialized.\n");
// Open the Xml file
if (m_pwszXmlFile) {
m_pXmlFile = _wfopen( m_pwszXmlFile, L"w");
if (!m_pXmlFile)
Error(1, L"\nError creating/opening the file %s\n", m_pwszXmlFile);
wprintf (L"XML results file created: %s\n", m_pwszXmlFile);
}
// Create the Backup components object
CHECK_NOFAIL(CreateVssBackupComponents(&m_pBackupComponents));
wprintf (L"Backup components object created.\n");
// Initialize the backup components object for backup
CHECK_NOFAIL(m_pBackupComponents->InitializeForBackup());
CHECK_SUCCESS(m_pBackupComponents->SetBackupState(
m_bComponentSelectionEnabled, m_bBootableSystemState, VSS_BT_FULL));
wprintf (L"Backup components object initialized for backup operations.\n");
}
void CVssSampleRequestor::CreateSnapshotSet()
{
CComPtr<IVssAsync> pAsync;
VSS_ID SnapshotsArray[MAX_VOLUMES];
VSS_ID SnapshotSetId = GUID_NULL;
wprintf (L"\n---------- Starting backup/snapshot ----------------\n");
// Starting a new snapshot set
wprintf(L"Starting a new Snapshot Set\n");
CHECK_SUCCESS(m_pBackupComponents->StartSnapshotSet(&SnapshotSetId));
wprintf(L"Snapshot Set created with ID = " WSTR_GUID_FMT L"\n", GUID_PRINTF_ARG(SnapshotSetId));
// Add volumes to the snapshot set
wprintf(L"Adding volumes to the Snapshot Set: \n");
for (INT nIndex = 0; nIndex < m_nVolumesCount; nIndex++)
{
// Get the volume containing the path
wprintf(L"\t- Adding volume containing %s ... ", m_ppwszVolumesList[nIndex] );
// Add the volume to the snapshot set
CHECK_SUCCESS(m_pBackupComponents->AddToSnapshotSet(m_ppwszVolumesList[nIndex],
GUID_NULL, &(SnapshotsArray[nIndex])));
wprintf( L"OK\n");
}
wprintf (L"\n------------ Creating the snapshot -----------------\n");
// Prepare for backup
wprintf(L"Starting asynchronous PrepareForBackup. Please wait...\n");
HRESULT hr = S_OK;
CHECK_SUCCESS(m_pBackupComponents->PrepareForBackup(&pAsync));
CHECK_SUCCESS(pAsync->Wait());
CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
CHECK_NOFAIL((hr));
wprintf(L"Asynchronous PrepareForBackup finished.\n");
pAsync = NULL;
// Gather writer status
GatherWriterStatus(L"after PrepareForBackup");
// Create the snapshot
wprintf(L"\nStarting asynchronous DoSnapshotSet. Please wait...\n");
hr = S_OK;
CHECK_SUCCESS(m_pBackupComponents->DoSnapshotSet(&pAsync));
CHECK_SUCCESS(pAsync->Wait());
CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
CHECK_NOFAIL((hr));
wprintf(L"Asynchronous DoSnapshotSet finished.\n");
pAsync = NULL;
// Gather writer status
GatherWriterStatus(L"after DoSnapshotSet");
wprintf(L"Snapshot set created\n");
for (INT nIndex = 0; nIndex < m_nVolumesCount; nIndex++)
{
VSS_SNAPSHOT_PROP prop;
CHECK_SUCCESS(m_pBackupComponents->GetSnapshotProperties(SnapshotsArray[nIndex], &prop));
wprintf(L"\t- The snapshot on volume %s resides at %s\n",
m_ppwszVolumesList[nIndex], prop.m_pwszSnapshotDeviceObject);
VssFreeSnapshotProperties(&prop);
}
}
void CVssSampleRequestor::BackupComplete()
{
unsigned cWriterComponents;
CComPtr<IVssAsync> pAsync;
wprintf (L"\n------------ Completing backup phase ---------------\n");
CHECK_SUCCESS(m_pBackupComponents->GetWriterComponentsCount(&cWriterComponents));
// If component selection enabled,
if (m_bComponentSelectionEnabled)
{
wprintf(L"Setting the succeeded state for the following components:\n");
// For each component, mark the completion state as succeeded
for(unsigned iWriter = 0; iWriter < cWriterComponents; iWriter++)
{
CComPtr<IVssWriterComponentsExt> pWriter;
CHECK_SUCCESS(m_pBackupComponents->GetWriterComponents(iWriter, &pWriter));
unsigned cComponents;
CHECK_SUCCESS(pWriter->GetComponentCount(&cComponents));
VSS_ID idWriter, idInstance;
CHECK_SUCCESS(pWriter->GetWriterInfo(&idInstance, &idWriter));
for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
{
CComPtr<IVssComponent> pComponent;
CHECK_SUCCESS(pWriter->GetComponent(iComponent, &pComponent));
VSS_COMPONENT_TYPE ct;
CComBSTR bstrLogicalPath;
CComBSTR bstrComponentName;
CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
CHECK_SUCCESS(pComponent->GetComponentType(&ct));
CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
wprintf(L"\t- %s\n", (LPWSTR)bstrComponentName);
CHECK_SUCCESS(m_pBackupComponents->SetBackupSucceeded (idInstance,
idWriter,
ct,
bstrLogicalPath,
bstrComponentName,
true));
}
}
wprintf(L"\n");
}
// Save the XML file, if needed
// The contents will be needed at restore, in the InitializeForRestore method.
if (m_pXmlFile) {
CComBSTR bstrXML;
CHECK_SUCCESS(m_pBackupComponents->SaveAsXML(&bstrXML));
fwprintf( m_pXmlFile, L"%s", (WCHAR*)bstrXML);
wprintf(L"XML results written in %s\n", m_pwszXmlFile);
}
// Send the BackupComplete event
wprintf(L"\nStarting asynchronous BackupComplete. Please wait...\n");
HRESULT hr = S_OK;
CHECK_SUCCESS(m_pBackupComponents->BackupComplete(&pAsync));
CHECK_SUCCESS(pAsync->Wait());
CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
CHECK_NOFAIL((hr));
wprintf(L"Asynchronous BackupComplete finished.\n");
pAsync = NULL;
// Gather writer status
GatherWriterStatus(L"after BackupComplete");
}
// Gather writera metadata and select components for backup, if needed
void CVssSampleRequestor::GatherWriterMetadata()
{
unsigned cWriters;
CComPtr<IVssAsync> pAsync;
wprintf (L"\n---------- Gathering writer metadata ---------------\n");
wprintf(L"Starting asynchronous GatherWriterMetadata. Please wait...\n");
HRESULT hr = S_OK;
CHECK_SUCCESS(m_pBackupComponents->GatherWriterMetadata(&pAsync));
CHECK_SUCCESS(pAsync->Wait());
CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
CHECK_NOFAIL((hr));
wprintf(L"Asynchronous GatherWriterMetadata finished.\n");
pAsync = NULL;
CHECK_NOFAIL (m_pBackupComponents->GetWriterMetadataCount (&cWriters));
wprintf(L"Number of writers that responded: %u\n", cWriters);
for (unsigned iWriter = 0; iWriter < cWriters; iWriter++)
{
CComPtr<IVssExamineWriterMetadata> pMetadata;
VSS_ID idInstance;
VSS_ID idInstanceT;
VSS_ID idWriter;
CComBSTR bstrWriterName;
VSS_USAGE_TYPE usage;
VSS_SOURCE_TYPE source;
unsigned cIncludeFiles, cExcludeFiles, cComponents;
CComBSTR bstrPath;
CComBSTR bstrFilespec;
CComBSTR bstrAlternate;
CComBSTR bstrDestination;
CHECK_SUCCESS (m_pBackupComponents->GetWriterMetadata(iWriter, &idInstance, &pMetadata));
CHECK_SUCCESS (pMetadata->GetIdentity (&idInstanceT,
&idWriter,
&bstrWriterName,
&usage,
&source));
wprintf (L"\n*** WriterName = %s\n\n"
L" WriterId = "WSTR_GUID_FMT L"\n"
L" InstanceId = "WSTR_GUID_FMT L"\n"
L" UsageType = %d (%s)\n"
L" SourceType = %d (%s)\n",
bstrWriterName,
GUID_PRINTF_ARG(idWriter),
GUID_PRINTF_ARG(idInstance),
usage,
GetStringFromUsageType (usage),
source,
GetStringFromSourceType (source));
CHECK_SUCCESS(pMetadata->GetFileCounts (&cIncludeFiles,
&cExcludeFiles,
&cComponents));
for(unsigned i = 0; i < cIncludeFiles; i++)
{
CComPtr<IVssWMFiledesc> pFiledesc;
CHECK_SUCCESS (pMetadata->GetIncludeFile (i, &pFiledesc));
PrintFiledesc(pFiledesc, L"\n Include File");
}
for(i = 0; i < cExcludeFiles; i++)
{
CComPtr<IVssWMFiledesc> pFiledesc;
CHECK_SUCCESS (pMetadata->GetExcludeFile (i, &pFiledesc));
PrintFiledesc (pFiledesc, L"\n Exclude File");
}
for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
{
CComPtr<IVssWMComponent> pComponent;
PVSSCOMPONENTINFO pInfo;
CHECK_SUCCESS (pMetadata->GetComponent (iComponent, &pComponent));
CHECK_SUCCESS (pComponent->GetComponentInfo (&pInfo));
wprintf (L"\n"
L" Component %d, type = %d (%s)\n"
L" LogicalPath = %s\n"
L" Name = %s\n"
L" Caption = %s\n",
iComponent,
pInfo->type,
GetStringFromComponentType (pInfo->type),
pInfo->bstrLogicalPath,
pInfo->bstrComponentName,
pInfo->bstrCaption);
wprintf (L" RestoreMetadata = %s\n"
L" NotifyOnBackupComplete = %s\n"
L" Selectable = %s\n",
pInfo->bRestoreMetadata ? L"yes" : L"no",
pInfo->bNotifyOnBackupComplete ? L"yes" : L"no",
pInfo->bSelectable ? L"yes" : L"no");
// If specified, add this component to the backup
// Remark: A real backup app will first get from the user the list of components to be added
if (m_bComponentSelectionEnabled) {
CHECK_SUCCESS(m_pBackupComponents->AddComponent(idInstance,
idWriter,
pInfo->type,
pInfo->bstrLogicalPath,
pInfo->bstrComponentName));
wprintf (L" [Component %d was added to the backup]\n", iComponent);
}
for(i = 0; i < pInfo->cFileCount; i++)
{
CComPtr<IVssWMFiledesc> pFiledesc;
CHECK_SUCCESS (pComponent->GetFile (i, &pFiledesc));
PrintFiledesc (pFiledesc, L" FileGroupFile");
// If we add the component, snapshot also the volume on which the file reside
if (m_bComponentSelectionEnabled)
AddVolumeForComponent(pFiledesc);
}
for(i = 0; i < pInfo->cDatabases; i++)
{
CComPtr<IVssWMFiledesc> pFiledesc;
CHECK_SUCCESS (pComponent->GetDatabaseFile (i, &pFiledesc));
PrintFiledesc (pFiledesc, L" DatabaseFile");
// If we add the component, snapshot also the volume on which the file reside
if (m_bComponentSelectionEnabled)
AddVolumeForComponent(pFiledesc);
}
for(i = 0; i < pInfo->cLogFiles; i++)
{
CComPtr<IVssWMFiledesc> pFiledesc;
CHECK_SUCCESS (pComponent->GetDatabaseLogFile (i, &pFiledesc));
PrintFiledesc (pFiledesc, L" DatabaseLogFile");
// If we add the component, snapshot also the volume on which the file reside
if (m_bComponentSelectionEnabled)
AddVolumeForComponent(pFiledesc);
}
pComponent->FreeComponentInfo (pInfo);
}
VSS_RESTOREMETHOD_ENUM method;
CComBSTR bstrUserProcedure;
CComBSTR bstrService;
VSS_WRITERRESTORE_ENUM writerRestore;
unsigned cMappings;
bool bRebootRequired;
CHECK_NOFAIL (pMetadata->GetRestoreMethod (&method,
&bstrService,
&bstrUserProcedure,
&writerRestore,
&bRebootRequired,
&cMappings));
wprintf (L"\n"
L" Restore method = %d (%s)\n"
L" Service = %d\n"
L" User Procedure = %s\n"
L" WriterRestore = %d (%s)\n"
L" RebootRequired = %s\n",
method,
GetStringFromRestoreMethod (method),
bstrService,
bstrUserProcedure,
writerRestore,
GetStringFromWriterRestoreMethod (writerRestore),
bRebootRequired ? L"yes" : L"no");
for(i = 0; i < cMappings; i++)
{
CComPtr<IVssWMFiledesc> pFiledesc;
CHECK_SUCCESS (pMetadata->GetAlternateLocationMapping (i, &pFiledesc));
PrintFiledesc (pFiledesc, L" AlternateMapping");
}
}
// Gather writer status
GatherWriterStatus(L"after GatherWriterMetadata");
CHECK_SUCCESS (m_pBackupComponents->FreeWriterMetadata());
}
void CVssSampleRequestor::GatherWriterStatus(
IN LPCWSTR wszWhen
)
{
unsigned cWriters;
CComPtr<IVssAsync> pAsync;
wprintf (L"\nGathering writer status %s... ", wszWhen);
HRESULT hr = S_OK;
CHECK_SUCCESS(m_pBackupComponents->GatherWriterStatus(&pAsync));
CHECK_SUCCESS(pAsync->Wait());
CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
CHECK_NOFAIL((hr));
CHECK_NOFAIL(m_pBackupComponents->GetWriterStatusCount(&cWriters));
wprintf (L"%d writers responded\n", cWriters);
for(unsigned iWriter = 0; iWriter < cWriters; iWriter++)
{
VSS_ID idInstance;
VSS_ID idWriter;
VSS_WRITER_STATE eWriterStatus;
CComBSTR bstrWriter;
HRESULT hrWriterFailure;
CHECK_SUCCESS(m_pBackupComponents->GetWriterStatus (iWriter,
&idInstance,
&idWriter,
&bstrWriter,
&eWriterStatus,
&hrWriterFailure));
WCHAR wszWriterFailure[MAX_TEXT_BUFFER];
if (hrWriterFailure)
swprintf(wszWriterFailure, L" Writer error code: %s [0x%08lx]",
GetStringFromFailureType(hrWriterFailure), hrWriterFailure);
else
wszWriterFailure[0] = L'\0';
wprintf (L"\t- %s status for writer '%s'. %s\n",
GetStringFromWriterStatus(eWriterStatus), bstrWriter, wszWriterFailure);
}
m_pBackupComponents->FreeWriterStatus();
}