2025-11-28 00:35:46 +09:00

898 lines
26 KiB
C++

/////////////////////////////////////////////////////////////////////////
// Copyright © Microsoft Corporation. All rights reserved.
//
// This file may contain preliminary information or inaccuracies,
// and may not correctly represent any associated Microsoft
// Product as commercially released. All Materials are provided entirely
// “AS IS.” To the extent permitted by law, MICROSOFT MAKES NO
// WARRANTY OF ANY KIND, DISCLAIMS ALL EXPRESS, IMPLIED AND STATUTORY
// WARRANTIES, AND ASSUMES NO LIABILITY TO YOU FOR ANY DAMAGES OF
// ANY TYPE IN CONNECTION WITH THESE MATERIALS OR ANY INTELLECTUAL PROPERTY IN THEM.
//
// Main header
#include "stdafx.h"
////////////////////////////////////////////////////////////////////////////////////
// Main routines forwriter metadata/status gathering.
//
// Gather writers metadata
void VssClient::GatherWriterMetadata()
{
FunctionTracer ft(DBG_INFO);
ft.WriteLine(L"(Gathering writer metadata...)");
// Gathers writer metadata
// WARNING: this call can be performed only once per IVssBackupComponents instance!
CComPtr<IVssAsync> pAsync;
CHECK_COM(m_pVssObject->GatherWriterMetadata(&pAsync));
// Waits for the async operation to finish and checks the result
WaitAndCheckForAsyncOperation(pAsync);
ft.WriteLine(L"Initialize writer metadata ...");
// Initialize the internal metadata data structures
InitializeWriterMetadata();
}
void VssClient::GatherWriterMetadataToScreen()
{
FunctionTracer ft(DBG_INFO);
ft.WriteLine(L"(Gathering writer metadata...)");
// Gathers writer metadata
// WARNING: this call can be performed only once per IVssBackupComponents instance!
CComPtr<IVssAsync> pAsync;
CHECK_COM(m_pVssObject->GatherWriterMetadata(&pAsync));
// Waits for the async operation to finish and checks the result
WaitAndCheckForAsyncOperation(pAsync);
// Get the list of writers in the metadata
unsigned cWriters = 0;
CHECK_COM(m_pVssObject->GetWriterMetadataCount(&cWriters));
// Enumerate writers
for (unsigned iWriter = 0; iWriter < cWriters; iWriter++)
{
CComBSTR bstrXML;
// Get the metadata for this particular writer
VSS_ID idInstance = GUID_NULL;
CComPtr<IVssExamineWriterMetadata> pMetadata;
CHECK_COM(m_pVssObject->GetWriterMetadata(iWriter, &idInstance, &pMetadata));
CHECK_COM(pMetadata->SaveAsXML(&bstrXML));
wprintf(L"\n--[Writer %u]--\n%s\n", iWriter, (LPCWSTR)(bstrXML));
}
wprintf(L"--[end of data]--\n");
}
// Gather writers status
void VssClient::GatherWriterStatus()
{
FunctionTracer ft(DBG_INFO);
// Gathers writer status
// WARNING: GatherWriterMetadata must be called before
CComPtr<IVssAsync> pAsync;
CHECK_COM(m_pVssObject->GatherWriterStatus(&pAsync));
// Waits for the async operation to finish and checks the result
WaitAndCheckForAsyncOperation(pAsync);
}
void VssClient::InitializeWriterMetadata()
{
FunctionTracer ft(DBG_INFO);
// Get the list of writers in the metadata
unsigned cWriters = 0;
CHECK_COM(m_pVssObject->GetWriterMetadataCount (&cWriters));
// Enumerate writers
for (unsigned iWriter = 0; iWriter < cWriters; iWriter++)
{
// Get the metadata for this particular writer
VSS_ID idInstance = GUID_NULL;
CComPtr<IVssExamineWriterMetadata> pMetadata;
CHECK_COM(m_pVssObject->GetWriterMetadata(iWriter, &idInstance, &pMetadata));
VssWriter writer;
writer.Initialize(pMetadata);
// Add this writer to the list
m_writerList.push_back(writer);
}
}
// Initialize the list of writers and components for restore
void VssClient::InitializeWriterComponentsForRestore()
{
FunctionTracer ft(DBG_INFO);
ft.WriteLine(L"Initializing writer components for restore ...");
// Get the list of writers in the metadata
unsigned cWriters = 0;
CHECK_COM(m_pVssObject->GetWriterComponentsCount(&cWriters));
// Enumerate writers
for (unsigned iWriter = 0; iWriter < cWriters; iWriter++)
{
// Get the selected components for this particular writer
CComPtr<IVssWriterComponentsExt> pWriterComponents;
CHECK_COM(m_pVssObject->GetWriterComponents(iWriter, &pWriterComponents));
// Get writer identity.
// Ignore this writer if the real writer is not present in the system
VSS_ID idInstance = GUID_NULL;
VSS_ID idWriter = GUID_NULL;
CHECK_COM(pWriterComponents->GetWriterInfo(
&idInstance,
&idWriter
));
wstring id = Guid2WString(idWriter);
wstring instanceId = Guid2WString(idInstance);
// Try to discover the name based on an existing writer (identical ID and instance ID).
// Otherwise, ignore it!
bool bFound = false;
for (unsigned i = 0; i < m_writerList.size(); i++)
{
// Do Not check for instance ID ...
if (id != m_writerList[i].id)
continue;
// Copy the information from the existing writer in the system
VssWriter writer = m_writerList[i];
ft.WriteLine(L"- Writer %s is present in the Backup Components document and on the system. Considering for restore ...",
writer.name.c_str());
// Adding components
writer.InitializeComponentsForRestore(pWriterComponents);
// Add this writer object to the writer components list
m_writerComponentsForRestore.push_back(writer);
// We found the writer!
bFound = true;
}
if (!bFound)
{
ft.WriteLine(L"- Writer with ID %s is not present in the system! Ignoring ...", id.c_str());
}
}
}
// Lists the writer metadata
void VssClient::ListWriterMetadata(bool bListDetailedInfo)
{
FunctionTracer ft(DBG_INFO);
ft.WriteLine(L"Listing writer metadata ...");
// Enumerate writers
for (unsigned iWriter = 0; iWriter < m_writerList.size(); iWriter++)
m_writerList[iWriter].Print(bListDetailedInfo);
}
// Lists the status for all writers
void VssClient::ListWriterStatus()
{
FunctionTracer ft(DBG_INFO);
ft.WriteLine(L"Listing writer status ...");
// Gets the number of writers in the gathered status info
// (WARNING: GatherWriterStatus must be called before)
unsigned cWriters = 0;
CHECK_COM(m_pVssObject->GetWriterStatusCount(&cWriters));
ft.WriteLine(L"- Number of writers that responded: %u", cWriters);
// Enumerate each writer
for(unsigned iWriter = 0; iWriter < cWriters; iWriter++)
{
VSS_ID idInstance = GUID_NULL;
VSS_ID idWriter= GUID_NULL;
VSS_WRITER_STATE eWriterStatus = VSS_WS_UNKNOWN;
CComBSTR bstrWriterName;
HRESULT hrWriterFailure = S_OK;
// Get writer status
CHECK_COM(m_pVssObject->GetWriterStatus(iWriter,
&idInstance,
&idWriter,
&bstrWriterName,
&eWriterStatus,
&hrWriterFailure));
// Print writer status
ft.WriteLine(L"\n"
L"* WRITER \"%s\"\n"
L" - Status: %d (%s)\n"
L" - Writer Failure code: 0x%08lx (%s)\n"
L" - Writer ID: " WSTR_GUID_FMT L"\n"
L" - Instance ID: " WSTR_GUID_FMT L"\n",
(PWCHAR)bstrWriterName,
eWriterStatus, GetStringFromWriterStatus(eWriterStatus).c_str(),
hrWriterFailure, FunctionTracer::HResult2String(hrWriterFailure).c_str(),
GUID_PRINTF_ARG(idWriter),
GUID_PRINTF_ARG(idInstance)
);
}
}
// Pre-restore
void VssClient::PreRestore()
{
FunctionTracer ft(DBG_INFO);
ft.WriteLine(L"\nSending the PreRestore event ... \n");
// Gathers writer status
// WARNING: GatherWriterMetadata must be called before
CComPtr<IVssAsync> pAsync;
CHECK_COM(m_pVssObject->PreRestore(&pAsync));
// Waits for the async operation to finish and checks the result
WaitAndCheckForAsyncOperation(pAsync);
}
// Post-restore
void VssClient::PostRestore()
{
FunctionTracer ft(DBG_INFO);
ft.WriteLine(L"\nSending the PostRestore event ... \n");
// Gathers writer status
// WARNING: GatherWriterMetadata must be called before
CComPtr<IVssAsync> pAsync;
CHECK_COM(m_pVssObject->PostRestore(&pAsync));
// Waits for the async operation to finish and checks the result
WaitAndCheckForAsyncOperation(pAsync);
}
// Convert a writer status into a string
wstring VssClient::GetStringFromWriterStatus(VSS_WRITER_STATE eWriterStatus)
{
FunctionTracer ft(DBG_INFO);
ft.Trace(DBG_INFO, L"Interpreting constant %d", (int)eWriterStatus);
switch (eWriterStatus)
{
CHECK_CASE_FOR_CONSTANT(VSS_WS_STABLE);
CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_FREEZE);
CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_THAW);
CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_POST_SNAPSHOT);
CHECK_CASE_FOR_CONSTANT(VSS_WS_WAITING_FOR_BACKUP_COMPLETE);
CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_IDENTIFY);
CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_PREPARE_BACKUP);
CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_PREPARE_SNAPSHOT);
CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_FREEZE);
CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_THAW);
CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_POST_SNAPSHOT);
CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_BACKUP_COMPLETE);
CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_PRE_RESTORE);
CHECK_CASE_FOR_CONSTANT(VSS_WS_FAILED_AT_POST_RESTORE);
default:
ft.WriteLine(L"Unknown constant: %d",eWriterStatus);
_ASSERTE(false);
return wstring(L"Undefined");
}
}
////////////////////////////////////////////////////////////////////////////////////
// VssWriter
//
// Initialize from a IVssWMFiledesc
void VssWriter::Initialize(IVssExamineWriterMetadata * pMetadata)
{
FunctionTracer ft(DBG_INFO);
// Get writer identity information
VSS_ID idInstance = GUID_NULL;
VSS_ID idWriter = GUID_NULL;
CComBSTR bstrWriterName;
VSS_USAGE_TYPE usage = VSS_UT_UNDEFINED;
VSS_SOURCE_TYPE source= VSS_ST_UNDEFINED;
CComBSTR bstrService;
CComBSTR bstrUserProcedure;
UINT iMappings;
// Get writer identity
CHECK_COM(pMetadata->GetIdentity (
&idInstance,
&idWriter,
&bstrWriterName,
&usage,
&source
));
// Get the restore method
CHECK_COM(pMetadata->GetRestoreMethod(
&restoreMethod,
&bstrService,
&bstrUserProcedure,
&writerRestoreConditions,
&rebootRequiredAfterRestore,
&iMappings
));
// Initialize local members
name = (LPWSTR)bstrWriterName;
id = Guid2WString(idWriter);
instanceId = Guid2WString(idInstance);
supportsRestore = (writerRestoreConditions != VSS_WRE_NEVER);
// Get file counts
unsigned cIncludeFiles = 0;
unsigned cExcludeFiles = 0;
unsigned cComponents = 0;
CHECK_COM(pMetadata->GetFileCounts(&cIncludeFiles, &cExcludeFiles, &cComponents));
// Get exclude files
for(unsigned i = 0; i < cExcludeFiles; i++)
{
CComPtr<IVssWMFiledesc> pFileDesc;
CHECK_COM(pMetadata->GetExcludeFile(i, &pFileDesc));
// Add this descriptor to the list of excluded files
VssFileDescriptor excludedFile;
excludedFile.Initialize(pFileDesc, VSS_FDT_EXCLUDE_FILES);
excludedFiles.push_back(excludedFile);
}
// Enumerate components
for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
{
// Get component
CComPtr<IVssWMComponent> pComponent;
CHECK_COM(pMetadata->GetComponent(iComponent, &pComponent));
// Add this component to the list of components
VssComponent component;
component.Initialize(name, pComponent);
components.push_back(component);
}
// Discover toplevel components
for(unsigned i = 0; i < cComponents; i++)
{
components[i].isTopLevel = true;
for(unsigned j = 0; j < cComponents; j++)
if (components[j].IsAncestorOf(components[i]))
components[i].isTopLevel = false;
}
}
// Initialize from a IVssWriterComponentsExt
void VssWriter::InitializeComponentsForRestore(IVssWriterComponentsExt * pWriterComponents)
{
FunctionTracer ft(DBG_INFO);
// Erase the current list of components for this writer
components.clear();
// Enumerate the components from the BC document
unsigned cComponents = 0;
CHECK_COM(pWriterComponents->GetComponentCount(&cComponents));
// Enumerate components
for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
{
// Get component
CComPtr<IVssComponent> pComponent;
CHECK_COM(pWriterComponents->GetComponent(iComponent, &pComponent));
// Add this component to the list of components
VssComponent component;
component.Initialize(name, pComponent);
ft.WriteLine(L"- Found component available for restore: \"%s\"", component.fullPath.c_str());
components.push_back(component);
}
}
// Prints the writer to the console
void VssWriter::Print(bool bListDetailedInfo)
{
FunctionTracer ft(DBG_INFO);
// Print writer identity information
ft.WriteLine(L"\n"
L"* WRITER \"%s\"\n"
L" - WriterId = %s\n"
L" - InstanceId = %s\n"
L" - Supports restore events = %s\n"
L" - Writer restore conditions = %s\n"
L" - Restore method = %s\n"
L" - Requires reboot after restore = %s\n",
name.c_str(),
id.c_str(),
instanceId.c_str(),
BOOL2TXT(supportsRestore),
GetStringFromRestoreConditions(writerRestoreConditions).c_str(),
GetStringFromRestoreMethod(restoreMethod).c_str(),
BOOL2TXT(rebootRequiredAfterRestore)
);
// Print exclude files
ft.WriteLine(L" - Excluded files:");
for(unsigned i = 0; i < excludedFiles.size(); i++)
excludedFiles[i].Print();
// Enumerate components
for(unsigned i = 0; i < components.size(); i++)
components[i].Print(bListDetailedInfo);
}
// Convert a component type into a string
inline wstring VssWriter::GetStringFromRestoreMethod(VSS_RESTOREMETHOD_ENUM eRestoreMethod)
{
FunctionTracer ft(DBG_INFO);
ft.Trace(DBG_INFO, L"Interpreting constant %d", (int)eRestoreMethod);
switch (eRestoreMethod)
{
CHECK_CASE_FOR_CONSTANT(VSS_RME_UNDEFINED);
CHECK_CASE_FOR_CONSTANT(VSS_RME_RESTORE_IF_NOT_THERE);
CHECK_CASE_FOR_CONSTANT(VSS_RME_RESTORE_IF_CAN_REPLACE);
CHECK_CASE_FOR_CONSTANT(VSS_RME_STOP_RESTORE_START);
CHECK_CASE_FOR_CONSTANT(VSS_RME_RESTORE_TO_ALTERNATE_LOCATION);
CHECK_CASE_FOR_CONSTANT(VSS_RME_RESTORE_AT_REBOOT);
#ifdef VSS_SERVER
CHECK_CASE_FOR_CONSTANT(VSS_RME_RESTORE_AT_REBOOT_IF_CANNOT_REPLACE);
#endif
CHECK_CASE_FOR_CONSTANT(VSS_RME_CUSTOM);
CHECK_CASE_FOR_CONSTANT(VSS_RME_RESTORE_STOP_START);
default:
ft.WriteLine(L"Unknown constant: %d",eRestoreMethod);
_ASSERTE(false);
return wstring(L"Undefined");
}
}
// Convert a component type into a string
inline wstring VssWriter::GetStringFromRestoreConditions(VSS_WRITERRESTORE_ENUM eRestoreEnum)
{
FunctionTracer ft(DBG_INFO);
ft.Trace(DBG_INFO, L"Interpreting constant %d", (int)eRestoreEnum);
switch (eRestoreEnum)
{
CHECK_CASE_FOR_CONSTANT(VSS_WRE_UNDEFINED);
CHECK_CASE_FOR_CONSTANT(VSS_WRE_NEVER);
CHECK_CASE_FOR_CONSTANT(VSS_WRE_IF_REPLACE_FAILS);
CHECK_CASE_FOR_CONSTANT(VSS_WRE_ALWAYS);
default:
ft.WriteLine(L"Unknown constant: %d",eRestoreEnum);
_ASSERTE(false);
return wstring(L"Undefined");
}
}
////////////////////////////////////////////////////////////////////////////////////
// VssComponent
//
// Initialize from a IVssWMComponent
void VssComponent::Initialize(wstring writerNameParam, IVssWMComponent * pComponent)
{
FunctionTracer ft(DBG_INFO);
writerName = writerNameParam;
// Get the component info
PVSSCOMPONENTINFO pInfo = NULL;
CHECK_COM(pComponent->GetComponentInfo (&pInfo));
// Initialize local members
name = BSTR2WString(pInfo->bstrComponentName);
logicalPath = BSTR2WString(pInfo->bstrLogicalPath);
caption = BSTR2WString(pInfo->bstrCaption);
type = pInfo->type;
isSelectable = pInfo->bSelectable;
notifyOnBackupComplete = pInfo->bNotifyOnBackupComplete;
// Compute the full path
fullPath = AppendBackslash(logicalPath) + name;
if (fullPath[0] != L'\\')
fullPath = wstring(L"\\") + fullPath;
// Get file list descriptors
for(unsigned i = 0; i < pInfo->cFileCount; i++)
{
CComPtr<IVssWMFiledesc> pFileDesc;
CHECK_COM(pComponent->GetFile (i, &pFileDesc));
VssFileDescriptor desc;
desc.Initialize(pFileDesc, VSS_FDT_FILELIST);
descriptors.push_back(desc);
}
// Get database descriptors
for(unsigned i = 0; i < pInfo->cDatabases; i++)
{
CComPtr<IVssWMFiledesc> pFileDesc;
CHECK_COM(pComponent->GetDatabaseFile (i, &pFileDesc));
VssFileDescriptor desc;
desc.Initialize(pFileDesc, VSS_FDT_DATABASE);
descriptors.push_back(desc);
}
// Get log descriptors
for(unsigned i = 0; i < pInfo->cLogFiles; i++)
{
CComPtr<IVssWMFiledesc> pFileDesc;
CHECK_COM(pComponent->GetDatabaseLogFile (i, &pFileDesc));
VssFileDescriptor desc;
desc.Initialize(pFileDesc, VSS_FDT_DATABASE_LOG);
descriptors.push_back(desc);
}
#ifdef VSS_SERVER
// Get dependencies
for(unsigned i = 0; i < pInfo->cDependencies; i++)
{
CComPtr<IVssWMDependency> pDependency;
CHECK_COM(pComponent->GetDependency(i, &pDependency));
VssDependency dependency;
dependency.Initialize(pDependency);
dependencies.push_back(dependency);
}
#endif
pComponent->FreeComponentInfo (pInfo);
// Compute the affected paths and volumes
for(unsigned i = 0; i < descriptors.size(); i++)
{
if (!FindStringInList(descriptors[i].expandedPath, affectedPaths))
affectedPaths.push_back(descriptors[i].expandedPath);
if (!FindStringInList(descriptors[i].affectedVolume, affectedVolumes))
affectedVolumes.push_back(descriptors[i].affectedVolume);
}
sort( affectedPaths.begin( ), affectedPaths.end( ) );
}
// Initialize from a IVssComponent
void VssComponent::Initialize(wstring writerNameParam, IVssComponent * pComponent)
{
FunctionTracer ft(DBG_INFO);
writerName = writerNameParam;
// Get component type
CHECK_COM(pComponent->GetComponentType(&type));
// Get component name
CComBSTR bstrComponentName;
CHECK_COM(pComponent->GetComponentName(&bstrComponentName));
name = BSTR2WString(bstrComponentName);
// Get component logical path
CComBSTR bstrLogicalPath;
CHECK_COM(pComponent->GetLogicalPath(&bstrLogicalPath));
logicalPath = BSTR2WString(bstrLogicalPath);
// Compute the full path
fullPath = AppendBackslash(logicalPath) + name;
if (fullPath[0] != L'\\')
fullPath = wstring(L"\\") + fullPath;
}
// Print summary/detalied information about this component
void VssComponent::Print(bool bListDetailedInfo)
{
FunctionTracer ft(DBG_INFO);
// Print writer identity information
ft.WriteLine(L" - Component \"%s\"\n"
L" - Name: '%s'\n"
L" - Logical Path: '%s'\n"
L" - Full Path: '%s'\n"
L" - Caption: '%s'\n"
L" - Type: %s [%d]\n"
L" - Is Selectable: '%s'\n"
L" - Is top level: '%s'\n"
L" - Notify on backup complete: '%s'",
(writerName + L":" + fullPath).c_str(),
name.c_str(),
logicalPath.c_str(),
fullPath.c_str(),
caption.c_str(),
GetStringFromComponentType(type).c_str(), type,
BOOL2TXT(isSelectable),
BOOL2TXT(isTopLevel),
BOOL2TXT(notifyOnBackupComplete)
);
// Compute the affected paths and volumes
if (bListDetailedInfo)
{
ft.WriteLine(L" - Components:");
for(unsigned i = 0; i < descriptors.size(); i++)
descriptors[i].Print();
}
// Print the affected paths and volumes
ft.WriteLine(L" - Affected paths by this component:");
for(unsigned i = 0; i < affectedPaths.size(); i++)
ft.WriteLine(L" - %s", affectedPaths[i].c_str());
ft.WriteLine(L" - Affected volumes by this component:");
for(unsigned i = 0; i < affectedVolumes.size(); i++)
{
wstring wsLocalVolume;
if (GetDisplayNameForVolumeNoThrow(affectedVolumes[i], wsLocalVolume))
ft.WriteLine(L" - %s [%s]", affectedVolumes[i].c_str(), wsLocalVolume.c_str());
else
ft.WriteLine(L" - %s [Not valid for local machine]", affectedVolumes[i].c_str());
}
// Print dependencies on Windows Server 2003
#ifdef VSS_SERVER
ft.WriteLine(L" - Component Dependencies:");
for(unsigned i = 0; i < dependencies.size(); i++)
dependencies[i].Print();
#endif
}
// Convert a component type into a string
inline wstring VssComponent::GetStringFromComponentType(VSS_COMPONENT_TYPE eComponentType)
{
FunctionTracer ft(DBG_INFO);
ft.Trace(DBG_INFO, L"Interpreting constant %d", (int)eComponentType);
switch (eComponentType)
{
CHECK_CASE_FOR_CONSTANT(VSS_CT_DATABASE);
CHECK_CASE_FOR_CONSTANT(VSS_CT_FILEGROUP);
default:
ft.WriteLine(L"Unknown constant: %d",eComponentType);
_ASSERTE(false);
return wstring(L"Undefined");
}
}
// Return TRUE if the current component is parent of the given component
bool VssComponent::IsAncestorOf(VssComponent & descendent)
{
// The child must have a longer full path
if (descendent.fullPath.length() <= fullPath.length())
return false;
wstring fullPathAppendedWithBackslash = AppendBackslash(fullPath);
wstring descendentPathAppendedWithBackslash = AppendBackslash(descendent.fullPath);
// Return TRUE if the current full path is a prefix of the child full path
return IsEqual(fullPathAppendedWithBackslash,
descendentPathAppendedWithBackslash.substr(0,
fullPathAppendedWithBackslash.length()));
}
// Return TRUE if the current component is parent of the given component
bool VssComponent::CanBeExplicitlyIncluded()
{
if (isExcluded)
return false;
// selectable can be explictly included
if (isSelectable)
return true;
// Non-selectable top level can be explictly included
if (isTopLevel)
return true;
return false;
}
////////////////////////////////////////////////////////////////////////////////////
// VssFileDescriptor
//
// Initialize a file descriptor from a
void VssFileDescriptor::Initialize(
IVssWMFiledesc * pFileDesc,
VSS_DESCRIPTOR_TYPE typeParam
)
{
FunctionTracer ft(DBG_INFO);
// Set the type
type = typeParam;
CComBSTR bstrPath;
CHECK_COM(pFileDesc->GetPath(&bstrPath));
CComBSTR bstrFilespec;
CHECK_COM(pFileDesc->GetFilespec (&bstrFilespec));
bool bRecursive = false;
CHECK_COM(pFileDesc->GetRecursive(&bRecursive));
CComBSTR bstrAlternate;
CHECK_COM(pFileDesc->GetAlternateLocation(&bstrAlternate));
// Initialize local data members
path = BSTR2WString(bstrPath);
filespec = BSTR2WString(bstrFilespec);
expandedPath = bRecursive;
path = BSTR2WString(bstrPath);
// Get the expanded path
expandedPath.resize(MAX_PATH, L'\0');
_ASSERTE(bstrPath && bstrPath[0]);
CHECK_WIN32(ExpandEnvironmentStringsW(bstrPath, (PWCHAR)expandedPath.c_str(), (DWORD)expandedPath.length()));
expandedPath = AppendBackslash(expandedPath);
// Get the affected volume
if (!GetUniqueVolumeNameForPathNoThrow(expandedPath, affectedVolume))
{
affectedVolume = expandedPath;
}
}
// Print a file description object
inline void VssFileDescriptor::Print()
{
FunctionTracer ft(DBG_INFO);
wstring alternateDisplayPath;
if (alternatePath.length() > 0)
alternateDisplayPath = wstring(L", Alternate Location = ") + alternatePath;
ft.WriteLine(L" - %s: Path = %s, Filespec = %s%s%s",
GetStringFromFileDescriptorType(type).c_str(),
path.c_str(),
filespec.c_str(),
isRecursive? L", Recursive": L"",
alternateDisplayPath.c_str());
}
// Convert a component type into a string
wstring VssFileDescriptor::GetStringFromFileDescriptorType(VSS_DESCRIPTOR_TYPE eType)
{
FunctionTracer ft(DBG_INFO);
ft.Trace(DBG_INFO, L"Interpreting constant %d", (int)eType);
switch (eType)
{
case VSS_FDT_UNDEFINED: return L"Undefined";
case VSS_FDT_EXCLUDE_FILES: return L"Exclude";
case VSS_FDT_FILELIST: return L"File List";
case VSS_FDT_DATABASE: return L"Database";
case VSS_FDT_DATABASE_LOG: return L"Database Log";
default:
ft.WriteLine(L"Unknown constant: %d",eType);
_ASSERTE(false);
return wstring(L"Undefined");
}
}
////////////////////////////////////////////////////////////////////////////////////
// VssDependency
//
#ifdef VSS_SERVER
// Initialize a file descriptor from a
void VssDependency::Initialize(
IVssWMDependency * pDependency
)
{
FunctionTracer ft(DBG_INFO);
VSS_ID guidWriterId;
CHECK_COM(pDependency->GetWriterId(&guidWriterId));
CComBSTR bstrLogicalPath;
CHECK_COM(pDependency->GetLogicalPath(&bstrLogicalPath));
CComBSTR bstrComponentName;
CHECK_COM(pDependency->GetComponentName(&bstrComponentName));
// Initialize local data members
writerId = Guid2WString(guidWriterId);
logicalPath = BSTR2WString(bstrLogicalPath);
componentName = BSTR2WString(bstrComponentName);
// Compute the full path
fullPath = AppendBackslash(logicalPath) + componentName;
if (fullPath[0] != L'\\')
fullPath = wstring(L"\\") + fullPath;
}
// Print a file description object
inline void VssDependency::Print()
{
FunctionTracer ft(DBG_INFO);
ft.WriteLine(L" - Dependency to \"%s:%s%s\"",
writerId.c_str(),
fullPath.c_str());
}
#endif