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.
640 lines
14 KiB
640 lines
14 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
vs_wmxml.cxx
|
|
|
|
Abstract:
|
|
|
|
Implementation of CVssMetadataHelper class
|
|
|
|
Brian Berkowitz [brianb] 3/13/2000
|
|
|
|
TBD:
|
|
|
|
Add comments.
|
|
|
|
Revision History:
|
|
|
|
Name Date Comments
|
|
brianb 03/30/2000 Created
|
|
|
|
--*/
|
|
|
|
#include "stdafx.hxx"
|
|
#include "vs_inc.hxx"
|
|
|
|
#include "vs_idl.hxx"
|
|
|
|
#include "vswriter.h"
|
|
#include "vsbackup.h"
|
|
#include "vs_wmxml.hxx"
|
|
#include "vssmsg.h"
|
|
|
|
|
|
#include "rpcdce.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Standard foo for file name aliasing. This code block must be after
|
|
// all includes of VSS header files.
|
|
//
|
|
#ifdef VSS_FILE_ALIAS
|
|
#undef VSS_FILE_ALIAS
|
|
#endif
|
|
#define VSS_FILE_ALIAS "BUEHELPC"
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// boolean type string values
|
|
static LPCWSTR x_wszYes = L"yes";
|
|
static LPCWSTR x_wszNo = L"no";
|
|
|
|
// usage type string values
|
|
static LPCWSTR x_wszBOOTABLESYSTEMSTATE = L"BOOTABLE_SYSTEM_STATE";
|
|
static LPCWSTR x_wszSYSTEMSERVICE = L"SYSTEM_SERVICE";
|
|
static LPCWSTR x_wszUSERDATA = L"USER_DATA";
|
|
static LPCWSTR x_wszOTHER = L"OTHER";
|
|
|
|
// source type string values
|
|
static LPCWSTR x_wszTRANSACTEDDB = L"TRANSACTION_DB";
|
|
static LPCWSTR x_wszNONTRANSACTEDDB = L"NONTRANSACTIONAL_DB";
|
|
|
|
// component ELEMENT type strings
|
|
static LPCWSTR x_wszElementDatabase = L"DATABASE";
|
|
static LPCWSTR x_wszElementFilegroup = L"FILE_GROUP";
|
|
|
|
// component value type strings
|
|
static LPCWSTR x_wszValueDatabase = L"database";
|
|
static LPCWSTR x_wszValueFilegroup = L"filegroup";
|
|
|
|
// writerRestore value type strings
|
|
static LPCWSTR x_wszNever = L"never";
|
|
static LPCWSTR x_wszAlways = L"always";
|
|
static LPCWSTR x_wszIfReplaceFails = L"ifReplaceFails";
|
|
|
|
// string restore methods
|
|
static LPCWSTR x_wszRESTOREIFNOTTHERE = L"RESTORE_IF_NONE_THERE";
|
|
static LPCWSTR x_wszRESTOREIFCANREPLACE = L"RESTORE_IF_CAN_BE_REPLACED";
|
|
static LPCWSTR x_wszSTOPRESTORESTART = L"STOP_RESTART_SERVICE";
|
|
static LPCWSTR x_wszRESTORETOALTERNATE = L"RESTORE_TO_ALTERNATE_LOCATION";
|
|
static LPCWSTR x_wszRESTOREATREBOOT = L"REPLACE_AT_REBOOT";
|
|
static LPCWSTR x_wszCUSTOM = L"CUSTOM";
|
|
|
|
// string backup types
|
|
static LPCWSTR x_wszValueFull = L"full";
|
|
static LPCWSTR x_wszValueDifferential = L"differential";
|
|
static LPCWSTR x_wszValueIncremental = L"incremental";
|
|
static LPCWSTR x_wszValueOther = L"other";
|
|
|
|
|
|
|
|
|
|
// convert boolean value to "yes" or "no"
|
|
LPCWSTR CVssMetadataHelper::WszFromBoolean(IN bool b)
|
|
{
|
|
return b ? x_wszYes : x_wszNo;
|
|
}
|
|
|
|
// convert from "yes", "no" to a boolean value
|
|
bool CVssMetadataHelper::ConvertToBoolean
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN BSTR bstr
|
|
) throw(HRESULT)
|
|
{
|
|
if (wcscmp(bstr, x_wszYes) == 0)
|
|
return true;
|
|
else if (wcscmp(bstr, x_wszNo) == 0)
|
|
return false;
|
|
else
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"Value %s is neither yes nor no.",
|
|
bstr
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
// convert a string to a VSS_ID value
|
|
void CVssMetadataHelper::ConvertToVSS_ID
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN BSTR bstr,
|
|
OUT VSS_ID *pId
|
|
) throw(HRESULT)
|
|
{
|
|
RPC_STATUS status = UuidFromString(bstr, pId);
|
|
if (status != RPC_S_OK)
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"Value %s is not a valid guid.",
|
|
bstr
|
|
);
|
|
}
|
|
|
|
// convert from VSS_USAGE_TYPE to string value
|
|
LPCWSTR CVssMetadataHelper::WszFromUsageType
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN VSS_USAGE_TYPE usage
|
|
) throw(HRESULT)
|
|
{
|
|
switch(usage)
|
|
{
|
|
default:
|
|
ft.Throw(VSSDBG_XML, E_INVALIDARG, L"Invalid usage type");
|
|
|
|
case VSS_UT_OTHER:
|
|
return(x_wszOTHER);
|
|
|
|
case VSS_UT_BOOTABLESYSTEMSTATE:
|
|
return(x_wszBOOTABLESYSTEMSTATE);
|
|
|
|
case VSS_UT_SYSTEMSERVICE:
|
|
return(x_wszSYSTEMSERVICE);
|
|
|
|
case VSS_UT_USERDATA:
|
|
return(x_wszUSERDATA);
|
|
}
|
|
}
|
|
|
|
|
|
// convert from string to VSS_USAGE_TYPE
|
|
VSS_USAGE_TYPE CVssMetadataHelper::ConvertToUsageType
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN BSTR bstr
|
|
) throw(HRESULT)
|
|
{
|
|
if (wcscmp(bstr, x_wszBOOTABLESYSTEMSTATE) == 0)
|
|
return(VSS_UT_BOOTABLESYSTEMSTATE);
|
|
else if (wcscmp(bstr, x_wszSYSTEMSERVICE) == 0)
|
|
return(VSS_UT_SYSTEMSERVICE);
|
|
else if (wcscmp(bstr, x_wszUSERDATA) == 0)
|
|
return(VSS_UT_USERDATA);
|
|
else if (wcscmp(bstr, x_wszOTHER) == 0)
|
|
return(VSS_UT_OTHER);
|
|
else
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"The string %s is not a valid usage type",
|
|
bstr
|
|
);
|
|
|
|
return VSS_UT_UNDEFINED;
|
|
}
|
|
|
|
// convert from a VSS_SOURCE_TYPE value to a string
|
|
LPCWSTR CVssMetadataHelper::WszFromSourceType
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN VSS_SOURCE_TYPE source
|
|
) throw(HRESULT)
|
|
{
|
|
switch(source)
|
|
{
|
|
default:
|
|
ft.Throw(VSSDBG_XML, E_INVALIDARG, L"Invalid data source type");
|
|
|
|
case VSS_ST_OTHER:
|
|
return(x_wszOTHER);
|
|
|
|
case VSS_ST_TRANSACTEDDB:
|
|
return(x_wszTRANSACTEDDB);
|
|
|
|
case VSS_ST_NONTRANSACTEDDB:
|
|
return(x_wszNONTRANSACTEDDB);
|
|
}
|
|
}
|
|
|
|
// convert from a string to a VSS_SOURCE_TYPE value
|
|
VSS_SOURCE_TYPE CVssMetadataHelper::ConvertToSourceType
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN BSTR bstr
|
|
)
|
|
{
|
|
if (wcscmp(bstr, x_wszTRANSACTEDDB) == 0)
|
|
return(VSS_ST_TRANSACTEDDB);
|
|
else if (wcscmp(bstr, x_wszNONTRANSACTEDDB) == 0)
|
|
return(VSS_ST_NONTRANSACTEDDB);
|
|
else if (wcscmp(bstr, x_wszOTHER) == 0)
|
|
return(VSS_ST_OTHER);
|
|
else
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"The string %s is not a valid source type.",
|
|
bstr
|
|
);
|
|
|
|
return VSS_ST_UNDEFINED;
|
|
}
|
|
|
|
|
|
// convert from VSS_COMPONENT_TYPE to string value
|
|
LPCWSTR CVssMetadataHelper::WszFromComponentType
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
VSS_COMPONENT_TYPE ct,
|
|
bool bValue
|
|
) throw(HRESULT)
|
|
{
|
|
switch(ct)
|
|
{
|
|
default:
|
|
ft.Throw(VSSDBG_XML, E_INVALIDARG, L"Invalid component type");
|
|
|
|
case VSS_CT_DATABASE:
|
|
return (bValue ? x_wszValueDatabase : x_wszElementDatabase);
|
|
|
|
case VSS_CT_FILEGROUP:
|
|
return(bValue ? x_wszValueDatabase : x_wszElementFilegroup);
|
|
}
|
|
}
|
|
|
|
// convert from string value to VSS_COMPONENT_TYPE
|
|
VSS_COMPONENT_TYPE CVssMetadataHelper::ConvertToComponentType
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN BSTR bstrName,
|
|
bool bValue
|
|
)
|
|
{
|
|
LPCWSTR wszDatabase = bValue ? x_wszValueDatabase : x_wszElementDatabase;
|
|
LPCWSTR wszFilegroup = bValue ? x_wszValueFilegroup : x_wszElementFilegroup;
|
|
if (wcscmp(bstrName, wszDatabase) == 0)
|
|
return VSS_CT_DATABASE;
|
|
else if (wcscmp(bstrName, wszFilegroup) == 0)
|
|
return VSS_CT_FILEGROUP;
|
|
else
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"The string %s is not a valid component type",
|
|
bstrName
|
|
);
|
|
|
|
return VSS_CT_UNDEFINED;
|
|
}
|
|
|
|
|
|
// convert from restore method to string
|
|
LPCWSTR CVssMetadataHelper::WszFromRestoreMethod
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN VSS_RESTOREMETHOD_ENUM method
|
|
)
|
|
{
|
|
switch(method)
|
|
{
|
|
default:
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"Invalid method type %d",
|
|
method
|
|
);
|
|
|
|
case VSS_RME_RESTORE_IF_NOT_THERE:
|
|
return (x_wszRESTOREIFNOTTHERE);
|
|
|
|
case VSS_RME_RESTORE_IF_CAN_REPLACE:
|
|
return(x_wszRESTOREIFCANREPLACE);
|
|
|
|
case VSS_RME_STOP_RESTORE_START:
|
|
return(x_wszSTOPRESTORESTART);
|
|
|
|
case VSS_RME_RESTORE_TO_ALTERNATE_LOCATION:
|
|
return(x_wszRESTORETOALTERNATE);
|
|
|
|
case VSS_RME_RESTORE_AT_REBOOT:
|
|
return(x_wszRESTOREATREBOOT);
|
|
|
|
case VSS_RME_CUSTOM:
|
|
return(x_wszCUSTOM);
|
|
}
|
|
}
|
|
|
|
|
|
// convert from string to VSS_RESTOREMETHOD_ENUM
|
|
VSS_RESTOREMETHOD_ENUM CVssMetadataHelper::ConvertToRestoreMethod
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN BSTR bstr
|
|
)
|
|
{
|
|
if (wcscmp(bstr, x_wszRESTOREIFNOTTHERE) == 0)
|
|
return(VSS_RME_RESTORE_IF_NOT_THERE);
|
|
else if (wcscmp(bstr, x_wszRESTOREIFCANREPLACE) == 0)
|
|
return(VSS_RME_RESTORE_IF_CAN_REPLACE);
|
|
else if (wcscmp(bstr, x_wszSTOPRESTORESTART) == 0)
|
|
return(VSS_RME_STOP_RESTORE_START);
|
|
else if (wcscmp(bstr, x_wszRESTORETOALTERNATE) == 0)
|
|
return(VSS_RME_RESTORE_TO_ALTERNATE_LOCATION);
|
|
else if (wcscmp(bstr, x_wszRESTOREATREBOOT) == 0)
|
|
return(VSS_RME_RESTORE_AT_REBOOT);
|
|
else if (wcscmp(bstr, x_wszCUSTOM) == 0)
|
|
return(VSS_RME_CUSTOM);
|
|
else
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"The string %s is not a valid restore method.",
|
|
bstr
|
|
);
|
|
|
|
return VSS_RME_UNDEFINED;
|
|
}
|
|
|
|
// convert from restore method to string
|
|
LPCWSTR CVssMetadataHelper::WszFromWriterRestore
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN VSS_WRITERRESTORE_ENUM method
|
|
)
|
|
{
|
|
switch(method)
|
|
{
|
|
default:
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"Invalid writerRestore type %d",
|
|
method
|
|
);
|
|
|
|
case VSS_WRE_NEVER:
|
|
return x_wszNever;
|
|
|
|
case VSS_WRE_IF_REPLACE_FAILS:
|
|
return x_wszIfReplaceFails;
|
|
|
|
case VSS_WRE_ALWAYS:
|
|
return x_wszAlways;
|
|
}
|
|
}
|
|
|
|
|
|
// convert from string to VSS_RESTOREMETHOD_ENUM
|
|
VSS_WRITERRESTORE_ENUM CVssMetadataHelper::ConvertToWriterRestore
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN BSTR bstr
|
|
)
|
|
{
|
|
if (wcscmp(bstr, x_wszNever) == 0)
|
|
return VSS_WRE_NEVER;
|
|
else if (wcscmp(bstr, x_wszIfReplaceFails) == 0)
|
|
return VSS_WRE_IF_REPLACE_FAILS;
|
|
else if (wcscmp(bstr, x_wszAlways) == 0)
|
|
return VSS_WRE_ALWAYS;
|
|
else
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"The string %s is not a valid restore method.",
|
|
bstr
|
|
);
|
|
|
|
return VSS_WRE_UNDEFINED;
|
|
}
|
|
|
|
|
|
// convert VSS_BACKUP_TYPE to string
|
|
LPCWSTR CVssMetadataHelper::WszFromBackupType
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN VSS_BACKUP_TYPE bt
|
|
)
|
|
{
|
|
switch(bt)
|
|
{
|
|
default:
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"Invalid backupType %d",
|
|
bt
|
|
);
|
|
|
|
case VSS_BT_INCREMENTAL:
|
|
return x_wszValueIncremental;
|
|
|
|
case VSS_BT_DIFFERENTIAL:
|
|
return x_wszValueDifferential;
|
|
|
|
case VSS_BT_FULL:
|
|
return x_wszValueFull;
|
|
|
|
case VSS_BT_OTHER:
|
|
return x_wszValueOther;
|
|
}
|
|
}
|
|
|
|
// convert from string to backup type
|
|
VSS_BACKUP_TYPE CVssMetadataHelper::ConvertToBackupType
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN BSTR bstr
|
|
)
|
|
{
|
|
if (wcscmp(bstr, x_wszValueIncremental) == 0)
|
|
return VSS_BT_INCREMENTAL;
|
|
else if (wcscmp(bstr, x_wszValueDifferential) == 0)
|
|
return VSS_BT_DIFFERENTIAL;
|
|
else if (wcscmp(bstr, x_wszValueFull) == 0)
|
|
return VSS_BT_FULL;
|
|
else if (wcscmp(bstr, x_wszValueOther) == 0)
|
|
return VSS_BT_OTHER;
|
|
else
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
E_INVALIDARG,
|
|
L"The string %s is not a valid backup type.",
|
|
bstr
|
|
);
|
|
|
|
return VSS_BT_UNDEFINED;
|
|
}
|
|
|
|
|
|
|
|
// obtain the value of a string valued attribute. Returns S_FALSE if
|
|
// attribute doesn't exist
|
|
HRESULT CVssMetadataHelper::GetStringAttributeValue
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN LPCWSTR wszAttrName,
|
|
IN bool bRequired,
|
|
OUT BSTR *pbstrValue
|
|
)
|
|
{
|
|
try
|
|
{
|
|
// check output parameter
|
|
if (pbstrValue == NULL)
|
|
ft.Throw(VSSDBG_XML, E_INVALIDARG, L"NULL output pointer");
|
|
|
|
// null output parameter
|
|
*pbstrValue = NULL;
|
|
|
|
// find attribute value
|
|
if (m_doc.FindAttribute(wszAttrName, pbstrValue))
|
|
return S_OK;
|
|
else
|
|
{
|
|
if (bRequired)
|
|
MissingAttribute(ft, wszAttrName);
|
|
else
|
|
return S_FALSE;
|
|
}
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|
|
// obtain the value of a boolean ("yes", "no") attribute. Return S_FALSE if
|
|
// attribute is not assigned a value.
|
|
HRESULT CVssMetadataHelper::GetBooleanAttributeValue
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN LPCWSTR wszAttrName,
|
|
IN bool bRequired,
|
|
OUT bool *pbValue
|
|
)
|
|
{
|
|
try
|
|
{
|
|
// check output parameter
|
|
if (pbValue == NULL)
|
|
ft.Throw(VSSDBG_XML, E_INVALIDARG, L"NULL output pointer");
|
|
|
|
// initialize output paramter
|
|
*pbValue = false;
|
|
|
|
CComBSTR bstrVal = NULL;
|
|
// obtain string value of attribute
|
|
if (!m_doc.FindAttribute(wszAttrName, &bstrVal))
|
|
{
|
|
if (bRequired)
|
|
MissingAttribute(ft, wszAttrName);
|
|
else
|
|
return S_FALSE;
|
|
}
|
|
|
|
// convert attribute to a boolean value
|
|
*pbValue = ConvertToBoolean(ft, bstrVal);
|
|
return S_OK;
|
|
}
|
|
VSS_STANDARD_CATCH(ft)
|
|
|
|
return ft.hr;
|
|
}
|
|
|
|
bool CVssMetadataHelper::get_stringValue
|
|
(
|
|
IN LPCWSTR wszAttrName,
|
|
OUT BSTR *pbstrValue
|
|
)
|
|
{
|
|
// iniitialize value to null
|
|
*pbstrValue = NULL;
|
|
|
|
// obtain string value if exists
|
|
return m_doc.FindAttribute(wszAttrName, pbstrValue);
|
|
}
|
|
|
|
void CVssMetadataHelper::get_VSS_IDValue
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN LPCWSTR wszAttrName,
|
|
OUT VSS_ID *pidValue
|
|
) throw(HRESULT)
|
|
{
|
|
// initialize id value to GUID_NULL
|
|
*pidValue = GUID_NULL;
|
|
|
|
CComBSTR bstrVal = NULL;
|
|
|
|
// obtain string value if it exists and convert it to GUID
|
|
if (m_doc.FindAttribute(wszAttrName, &bstrVal))
|
|
ConvertToVSS_ID(ft, bstrVal, pidValue);
|
|
else
|
|
MissingAttribute(ft, wszAttrName);
|
|
}
|
|
|
|
|
|
bool CVssMetadataHelper::get_boolValue
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN LPCWSTR wszAttrName,
|
|
OUT bool *pb
|
|
)
|
|
{
|
|
// initialize boolean value
|
|
*pb = FALSE;
|
|
|
|
CComBSTR bstrVal = NULL;
|
|
|
|
// find attribute if it exists and convert its value to a boolean
|
|
if (!m_doc.FindAttribute( wszAttrName, &bstrVal))
|
|
return false;
|
|
|
|
*pb = ConvertToBoolean(ft, bstrVal);
|
|
return true;
|
|
}
|
|
|
|
void CVssMetadataHelper::MissingElement
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN LPCWSTR wszElement
|
|
)
|
|
{
|
|
ft.LogError(VSS_ERROR_CORRUPTXMLDOCUMENT_MISSING_ELEMENT, VSSDBG_XML << wszElement);
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
VSS_E_CORRUPT_XML_DOCUMENT,
|
|
L"The %s element is missing.",
|
|
wszElement
|
|
);
|
|
}
|
|
|
|
void CVssMetadataHelper::MissingAttribute
|
|
(
|
|
IN CVssFunctionTracer &ft,
|
|
IN LPCWSTR wszAttribute
|
|
)
|
|
{
|
|
ft.LogError(VSS_ERROR_CORRUPTXMLDOCUMENT_MISSING_ATTRIBUTE, VSSDBG_XML << wszAttribute);
|
|
ft.Throw
|
|
(
|
|
VSSDBG_XML,
|
|
VSS_E_CORRUPT_XML_DOCUMENT,
|
|
L"The %s attribute is missing.",
|
|
wszAttribute
|
|
);
|
|
}
|
|
|
|
|
|
|
|
|