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.
 
 
 
 
 
 

854 lines
24 KiB

#include "stdafx.hxx"
#include "vss.h"
#include "vswriter.h"
#include "vsbackup.h"
#include <debug.h>
#include <time.h>
#include <ntddstor.h>
#include <vs_inc.hxx>
#include <vsevent.h>
#include <vdslun.h>
#include <vscoordint.h>
#include <vs_wmxml.hxx>
#include <vs_cmxml.hxx>
#include <vs_trace.hxx>
static VSS_ID x_idSnapSet =
{
0xD79FE5AD, 0x767F, 0x4251,
0xA9, 0x7A, 0x37, 0x37, 0xd0, 0xf9, 0xf7, 0x4f
};
static VSS_ID x_idSnap1 =
{
0x78B049FB, 0x9D12, 0x40A6,
0x82, 0x6C, 0xED, 0x8A, 0x80, 0x4E, 0xB4, 0xAA
};
static VSS_ID x_idSnap2 =
{
0xE700B0EC, 0xA993, 0x4B1B,
0xAD, 0xDA, 0xC2, 0xAA, 0x08, 0x53, 0x6F, 0x27
};
static VSS_ID x_idProv =
{
0x587E6660, 0x3FEF, 0x45D6,
0x8D, 0x91, 0xB1, 0x2E, 0x16, 0xAC, 0x5C, 0x18
};
void GetAndValidateSnapshots
(
IN IVssSnapshotSetDescription *pSnapshotSet,
OUT IVssSnapshotDescription **ppSnapshot1,
OUT IVssSnapshotDescription **ppSnapshot2,
OUT VSS_ID &idSnap1,
OUT VSS_ID &idSnap2
)
{
HRESULT hr;
UINT cSnapshots;
CHECK_SUCCESS(pSnapshotSet->GetSnapshotCount(&cSnapshots));
if (cSnapshots != 2)
{
wprintf(L"Number of snapshots %d is not correct.\n");
BS_ASSERT(FALSE);
throw(E_UNEXPECTED);
}
VSS_ID idProv;
CHECK_SUCCESS(pSnapshotSet->GetSnapshotDescription(0, ppSnapshot1));
CHECK_SUCCESS(pSnapshotSet->GetSnapshotDescription(1, ppSnapshot2));
CHECK_SUCCESS((*ppSnapshot1)->GetSnapshotId(&idSnap1));
CHECK_SUCCESS((*ppSnapshot2)->GetSnapshotId(&idSnap2));
if ((idSnap1 != x_idSnap1 || idSnap2 != x_idSnap2) &&
(idSnap1 != x_idSnap2 || idSnap2 != x_idSnap1))
Error(E_UNEXPECTED,
L"Snapshots were not added properly. Added snapshots are:\n"
WSTR_GUID_FMT L" and " WSTR_GUID_FMT
L"\nFound snapshots are" WSTR_GUID_FMT L" and "
WSTR_GUID_FMT L"\n",
GUID_PRINTF_ARG(x_idSnap1),
GUID_PRINTF_ARG(x_idSnap2),
GUID_PRINTF_ARG(idSnap1),
GUID_PRINTF_ARG(idSnap2));
CHECK_SUCCESS((*ppSnapshot1)->GetProviderId(&idProv));
if (idProv != x_idProv)
Error(E_UNEXPECTED,
L"Provider id was not correct.\n"
WSTR_GUID_FMT L" != " WSTR_GUID_FMT L".\n",
GUID_PRINTF_ARG(idProv),
GUID_PRINTF_ARG(x_idProv));
CHECK_SUCCESS((*ppSnapshot2)->GetProviderId(&idProv));
if (idProv != x_idProv)
Error(E_UNEXPECTED,
L"Provider id was not correct.\n"
WSTR_GUID_FMT L" != " WSTR_GUID_FMT L".\n",
GUID_PRINTF_ARG(idProv),
GUID_PRINTF_ARG(x_idProv));
}
void ValidateSnapshotSet(IVssSnapshotSetDescription *pSnapshotSet)
{
HRESULT hr;
VSS_ID idSnapSet;
CHECK_SUCCESS(pSnapshotSet->GetSnapshotSetId(&idSnapSet));
if (idSnapSet != x_idSnapSet)
Error(E_UNEXPECTED, L"snapshot set id does not match: "
WSTR_GUID_FMT L" != " WSTR_GUID_FMT,
GUID_PRINTF_ARG(idSnapSet),
GUID_PRINTF_ARG(x_idSnapSet));
CComBSTR bstrDescription;
CComBSTR bstrMetadata;
CHECK_SUCCESS(pSnapshotSet->GetDescription(&bstrDescription));
if (wcscmp(bstrDescription, L"This is a test snapshot set") != 0)
Error(E_UNEXPECTED, L"Snapshot description is invalid:\n%s", bstrDescription);
CHECK_SUCCESS(pSnapshotSet->GetMetadata(&bstrMetadata));
if (wcscmp(bstrMetadata, L"This is some test metadata for the snapshot set.") != 0)
Error(E_UNEXPECTED, L"Snapshot metadata is invalid:\n%s", bstrMetadata);
LONG lContext;
CHECK_SUCCESS(pSnapshotSet->GetContext(&lContext));
if (lContext != VSS_CTX_BACKUP)
Error(E_UNEXPECTED, L"Context is invalid. lContext=%d\n", lContext);
}
VSS_SNAPSHOT_PROP rgSnapshotProp[2];
static UCHAR x_DeviceType1 = 1;
static UCHAR x_DeviceType2 = 2;
static UCHAR x_DeviceTypeModifier1 = 100;
static UCHAR x_DeviceTypeModifier2 = 200;
static ULONGLONG x_rgDiskExtents1[] = {10L, 2000L, 4000L, 1000L};
static UINT x_cDiskExtents1 = 2;
static ULONGLONG x_rgDiskExtents2[] = {100L, 1000L, 2000L, 10000L, 100000L, 4000L};
static UINT x_cDiskExtents2 = 3;
static LPCSTR x_szVendorId1 = "MICROSOFT";
static LPCSTR x_szVendorId2 = "PLATFORMS";
static LPCSTR x_szProductId1 = "LVM";
static LPCSTR x_szProductId2 = "VDS";
static LPCSTR x_szProductRevision1 = "1.0";
static LPCSTR x_szProductRevision2 = "2.1";
static LPCSTR x_szSerialNumber1S = "123987";
static LPCSTR x_szSerialNumber1D = "343434";
static LPCSTR x_szSerialNumber2S = "999999-1111";
static LPCSTR x_szSerialNumber2D = "888888-2222";
static VDS_STORAGE_BUS_TYPE x_busType1 = VDSBusTypeScsi;
static VDS_STORAGE_BUS_TYPE x_busType2 = VDSBusTypeFibre;
static VSS_ID x_idDiskSignature1 =
{
0xF1CFF9EC, 0xB0A3, 0x408C,
0xB5, 0xC9, 0x0C, 0x98, 0xDF, 0xFD, 0xDA, 0xED
};
static VSS_ID x_idDiskSignature2 =
{
0xB33FF922, 0xB0A3, 0x408C,
0xB5, 0xC9, 0x0C, 0x98, 0xDF, 0xFD, 0xDA, 0xED
};
static VDS_INTERCONNECT_ADDRESS_TYPE x_rgIAType1S[] = {VDS_IA_FCFS, VDS_IA_FCFS, VDS_IA_FCFS};
static LPCSTR x_rgszAddresses1S[] = {"CAB1.BUS10.SLOT10", "CAB1.BUS20.SLOT30", "CAB20.BUS3.SLOT100"};
static UINT x_cInterconnectAddresses1S = 3;
static VDS_INTERCONNECT_ADDRESS_TYPE x_rgIAType1D[] = {VDS_IA_FCFS, VDS_IA_FCFS, VDS_IA_FCFS};
static LPCSTR x_rgszAddresses1D[] = {"CAB1.BUS1.SLOT10", "CAB1.BUS2.SLOT30", "CAB2.BUS3.SLOT10"};
static UINT x_cInterconnectAddresses1D = 3;
static VDS_INTERCONNECT_ADDRESS_TYPE rgIAType2S[] = {VDS_IA_FCPH};
static LPCSTR x_rgszAddresses2S[] = {"10.1.1.4.BUS1.SLOT10"};
static UINT x_cInterconnectAddresses2S = 1;
static VDS_INTERCONNECT_ADDRESS_TYPE rgIAType2D[] = {VDS_IA_FCPH};
static LPCSTR x_rgszAddresses2D[] = {"100.2.3.8.BUS11.SLOT10"};
static UINT x_cInterconnectAddresses2D = 1;
static STORAGE_IDENTIFIER x_storeid1 = {StorageIdCodeSetBinary, StorageIdTypeVendorId, 8, 0, StorageIdAssocDevice, 0};
static STORAGE_IDENTIFIER x_storeid2 = {StorageIdCodeSetBinary, StorageIdTypeVendorSpecific, 20, 0, StorageIdAssocDevice, 0};
static STORAGE_IDENTIFIER x_storeid3 = {StorageIdCodeSetAscii, StorageIdTypeFCPHName, 32, 0, StorageIdAssocDevice, 0};
static STORAGE_IDENTIFIER x_storeid4 = {StorageIdCodeSetBinary, StorageIdTypeEUI64, 8, 0, StorageIdAssocDevice, 0};
void AddIdentifier(BYTE **ppb, STORAGE_IDENTIFIER *pid, UINT &ib)
{
if (pid)
{
UINT cb = pid->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
memcpy(*ppb, pid, FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier));
ib += cb;
((STORAGE_IDENTIFIER *) (*ppb))->NextOffset = (USHORT) ib;
memset(*ppb + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier), 0x10, pid->IdentifierSize);
*ppb += cb;
}
}
void BuildStorageIdDescriptor
(
STORAGE_DEVICE_ID_DESCRIPTOR **ppstore,
STORAGE_IDENTIFIER *pid1,
STORAGE_IDENTIFIER *pid2,
STORAGE_IDENTIFIER *pid3,
STORAGE_IDENTIFIER *pid4
)
{
UINT cid = 0;
UINT cb = FIELD_OFFSET(STORAGE_DEVICE_ID_DESCRIPTOR, Identifiers);
if (pid1)
{
cid++;
cb += pid1->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
}
if (pid2)
{
cid++;
cb += pid2->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
}
if (pid3)
{
cid++;
cb += pid3->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
}
if (pid4)
{
cid++;
cb += pid4->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
}
BYTE *pb = new BYTE[cb];
STORAGE_DEVICE_ID_DESCRIPTOR *pstore = (STORAGE_DEVICE_ID_DESCRIPTOR *) pb;
pstore->Version = 10;
pstore->Size = cb;
pstore->NumberOfIdentifiers = cid;
pb = pstore->Identifiers;
UINT ib = FIELD_OFFSET(STORAGE_DEVICE_ID_DESCRIPTOR, Identifiers);
AddIdentifier(&pb, pid1, ib);
AddIdentifier(&pb, pid2, ib);
AddIdentifier(&pb, pid3, ib);
AddIdentifier(&pb, pid4, ib);
BS_ASSERT(ib == cb);
*ppstore = pstore;
}
typedef struct _BETEST_LUN_INFO
{
UCHAR DeviceType;
UCHAR DeviceTypeModifier;
ULONGLONG *rgDiskExtents;
UINT cDiskExtents;
LPCSTR szVendorId;
LPCSTR szProductId;
LPCSTR szProductRevision;
LPCSTR szSerialNumberSource;
LPCSTR szSerialNumberDest;
VDS_STORAGE_BUS_TYPE busType;
VSS_ID idDiskSignature;
VDS_INTERCONNECT_ADDRESS_TYPE *rgiatypeS;
VDS_INTERCONNECT_ADDRESS_TYPE *rgiatypeD;
LPCSTR *rgszIAS;
LPCSTR *rgszIAD;
UINT cIAS;
UINT cIAD;
STORAGE_DEVICE_ID_DESCRIPTOR *pstoreS;
STORAGE_DEVICE_ID_DESCRIPTOR *pstoreD;
} BETEST_LUN_INFO;
void BuildLunInfo (UINT i, BETEST_LUN_INFO &info)
{
if (i == 1)
{
info.DeviceType = x_DeviceType1;
info.DeviceTypeModifier = x_DeviceTypeModifier1;
info.rgDiskExtents = x_rgDiskExtents1;
info.cDiskExtents = x_cDiskExtents1;
info.szVendorId = x_szVendorId1;
info.szProductId = x_szProductId1;
info.szProductRevision = x_szProductRevision1;
info.szSerialNumberSource = x_szSerialNumber1S;
info.szSerialNumberDest = x_szSerialNumber1D;
info.busType = x_busType1;
info.idDiskSignature = x_idDiskSignature1;
info.rgiatypeS = x_rgIAType1S;
info.rgiatypeD = x_rgIAType1D;
info.rgszIAS = x_rgszAddresses1S;
info.rgszIAD = x_rgszAddresses1D;
info.cIAS = x_cInterconnectAddresses1S;
info.cIAD = x_cInterconnectAddresses1D;
BuildStorageIdDescriptor(&info.pstoreS, &x_storeid1, &x_storeid3, NULL, NULL);
BuildStorageIdDescriptor(&info.pstoreD, &x_storeid1, &x_storeid3, &x_storeid4, NULL);
}
else
{
info.DeviceType = x_DeviceType2;
info.DeviceTypeModifier = x_DeviceTypeModifier2;
info.rgDiskExtents = x_rgDiskExtents2;
info.cDiskExtents = x_cDiskExtents2;
info.szVendorId = x_szVendorId2;
info.szProductId = x_szProductId2;
info.szProductRevision = x_szProductRevision2;
info.szSerialNumberSource = x_szSerialNumber2S;
info.szSerialNumberDest = x_szSerialNumber2D;
info.busType = x_busType2;
info.idDiskSignature = x_idDiskSignature2;
info.rgiatypeS = rgIAType2S;
info.rgiatypeD = rgIAType2D;
info.rgszIAS = x_rgszAddresses2S;
info.rgszIAD = x_rgszAddresses2D;
info.cIAS = x_cInterconnectAddresses2S;
info.cIAD = x_cInterconnectAddresses2D;
BuildStorageIdDescriptor(&info.pstoreS, &x_storeid1, &x_storeid2, NULL, NULL);
BuildStorageIdDescriptor(&info.pstoreD, &x_storeid1, &x_storeid2, &x_storeid3, &x_storeid4);
}
}
void AddLunInfo(IVssLunMapping *pLunMapping, UINT i)
{
HRESULT hr;
CComPtr<IVssLunInformation> pSourceLun;
CComPtr<IVssLunInformation> pDestLun;
BETEST_LUN_INFO info;
BuildLunInfo(i, info);
CHECK_SUCCESS(pLunMapping->GetSourceLun(&pSourceLun));
CHECK_SUCCESS(pLunMapping->GetDestinationLun(&pDestLun));
CHECK_SUCCESS(pSourceLun->SetLunBasicType
(
info.DeviceType,
info.DeviceTypeModifier,
true,
info.szVendorId,
info.szProductId,
info.szProductRevision,
info.szSerialNumberSource,
info.busType
));
CHECK_SUCCESS(pDestLun->SetLunBasicType
(
info.DeviceType,
info.DeviceTypeModifier,
true,
info.szVendorId,
info.szProductId,
info.szProductRevision,
info.szSerialNumberDest,
info.busType
));
CHECK_SUCCESS(pSourceLun->SetDiskSignature(info.idDiskSignature));
CHECK_SUCCESS(pDestLun->SetDiskSignature(info.idDiskSignature));
for(UINT iExtent = 0; iExtent < info.cDiskExtents; iExtent++)
CHECK_SUCCESS(pLunMapping->AddDiskExtent
(
info.rgDiskExtents[iExtent * 2],
info.rgDiskExtents[iExtent * 2 + 1]
));
for(UINT iIAS = 0; iIAS < info.cIAS; iIAS++)
CHECK_SUCCESS(pSourceLun->AddInterconnectAddress
(
info.rgiatypeS[iIAS],
0,
NULL,
(UINT) (strlen(info.rgszIAS[iIAS]) + 1),
(const BYTE *) info.rgszIAS[iIAS]
));
for(UINT iIAD = 0; iIAD < info.cIAD; iIAD++)
CHECK_SUCCESS(pDestLun->AddInterconnectAddress
(
info.rgiatypeD[iIAD],
3,
(BYTE *) "foo",
(UINT) (strlen(info.rgszIAD[iIAD]) + 1),
(const BYTE *) info.rgszIAD[iIAD]
));
CHECK_SUCCESS(pSourceLun->SetStorageDeviceIdDescriptor(info.pstoreS));
CHECK_SUCCESS(pDestLun->SetStorageDeviceIdDescriptor(info.pstoreD));
}
bool cmp_str_eq(LPCSTR sz1, LPCSTR sz2)
{
return (sz1 == NULL && sz2 == NULL) ||
(sz1 != NULL && sz2 != NULL && strcmp(sz1, sz2) == 0);
}
void DoCoTaskFree
(
LPSTR &str1,
LPSTR &str2,
LPSTR &str3,
LPSTR &str4
)
{
if (str1)
{
CoTaskMemFree(str1);
str1 = NULL;
}
if (str2)
{
CoTaskMemFree(str2);
str2 = NULL;
}
if (str3)
{
CoTaskMemFree(str3);
str3 = NULL;
}
if (str4)
{
CoTaskMemFree(str4);
str4 = NULL;
}
}
void ValidateLunInfo(IVssLunMapping *pLunMapping, UINT i)
{
HRESULT hr;
CComPtr<IVssLunInformation> pSourceLun;
CComPtr<IVssLunInformation> pDestLun;
BETEST_LUN_INFO info;
BuildLunInfo(i, info);
CHECK_SUCCESS(pLunMapping->GetSourceLun(&pSourceLun));
CHECK_SUCCESS(pLunMapping->GetDestinationLun(&pDestLun));
UINT cExtents;
CHECK_SUCCESS(pLunMapping->GetDiskExtentCount(&cExtents));
if (cExtents != info.cDiskExtents)
Error(E_UNEXPECTED, L"Invalid number of extents for lun %d", i);
for(UINT iExtent = 0; iExtent < cExtents; iExtent++)
{
ULONGLONG start, length;
CHECK_SUCCESS(pLunMapping->GetDiskExtent(iExtent, &start, &length));
if (start != info.rgDiskExtents[iExtent * 2] ||
length != info.rgDiskExtents[iExtent * 2 + 1])
Error(E_UNEXPECTED, L"Invalid extent %d for lun %d", iExtent, i);
}
LPSTR strVendorId;
LPSTR strProductId;
LPSTR strProductRevision;
LPSTR strSerialNumber;
VDS_STORAGE_BUS_TYPE busTypeFound;
UCHAR DeviceTypeFound;
UCHAR DeviceTypeModifierFound;
BOOL bCommandQueueing;
CHECK_SUCCESS(pSourceLun->GetLunBasicType
(
&DeviceTypeFound,
&DeviceTypeModifierFound,
&bCommandQueueing,
&strVendorId,
&strProductId,
&strProductRevision,
&strSerialNumber,
&busTypeFound
));
if (DeviceTypeFound != info.DeviceType ||
DeviceTypeModifierFound != info.DeviceTypeModifier ||
busTypeFound != info.busType ||
!bCommandQueueing ||
!cmp_str_eq(strVendorId, info.szVendorId) ||
!cmp_str_eq(strProductId, info.szProductId) ||
!cmp_str_eq(strProductRevision, info.szProductRevision) ||
!cmp_str_eq(strSerialNumber, info.szSerialNumberSource))
{
DoCoTaskFree(strVendorId, strProductId, strProductRevision, strSerialNumber);
Error(E_UNEXPECTED, L"Problem in basic LUN information for source %d.\n", i);
}
DoCoTaskFree(strVendorId, strProductId, strProductRevision, strSerialNumber);
CHECK_SUCCESS(pDestLun->GetLunBasicType
(
&DeviceTypeFound,
&DeviceTypeModifierFound,
&bCommandQueueing,
&strVendorId,
&strProductId,
&strProductRevision,
&strSerialNumber,
&busTypeFound
));
if (DeviceTypeFound != info.DeviceType ||
DeviceTypeModifierFound != info.DeviceTypeModifier ||
busTypeFound != info.busType ||
!cmp_str_eq(strVendorId, info.szVendorId) ||
!cmp_str_eq(strProductId, info.szProductId) ||
!cmp_str_eq(strProductRevision, info.szProductRevision) ||
!cmp_str_eq(strSerialNumber, info.szSerialNumberDest))
{
DoCoTaskFree(strVendorId, strProductId, strProductRevision, strSerialNumber);
Error(E_UNEXPECTED, L"Problem in basic LUN information four destination %d.\n", i);
}
DoCoTaskFree(strVendorId, strProductId, strProductRevision, strSerialNumber);
VSS_ID idDiskSignatureFound;
CHECK_SUCCESS(pSourceLun->GetDiskSignature(&idDiskSignatureFound));
if (info.idDiskSignature != idDiskSignatureFound)
Error(E_UNEXPECTED, L"Disk signatures do not match for source %d.\n", i);
CHECK_SUCCESS(pDestLun->GetDiskSignature(&idDiskSignatureFound));
if (info.idDiskSignature != idDiskSignatureFound)
Error(E_UNEXPECTED, L"Disk signatures do not match for destination %d.\n", i);
UINT cia;
CHECK_SUCCESS(pSourceLun->GetInterconnectAddressCount(&cia));
if (cia != info.cIAS)
Error(E_UNEXPECTED, L"Interconnect address count does not match for source %d", i);
CHECK_SUCCESS(pDestLun->GetInterconnectAddressCount(&cia));
if (cia != info.cIAD)
Error(E_UNEXPECTED, L"Interconnect address count does not match for source %d", i);
for(UINT iIAS = 0; iIAS < info.cIAS; iIAS++)
{
VDS_INTERCONNECT_ADDRESS_TYPE iat;
LPBYTE pbAddress, pbPort;
ULONG cbAddress, cbPort;
CHECK_SUCCESS(pSourceLun->GetInterconnectAddress
(
iIAS,
&iat,
&cbPort,
&pbPort,
&cbAddress,
&pbAddress
));
if (iat != info.rgiatypeS[iIAS] ||
cbPort != 0 ||
pbPort != NULL ||
cbAddress != strlen(info.rgszIAS[iIAS]) + 1 ||
strcmp((char *) pbAddress, info.rgszIAS[iIAS]) != 0)
{
CoTaskMemFree(pbAddress);
Error(E_UNEXPECTED, L"Interconnect address %d does not match for source %d", iIAS, i);
}
if (pbAddress)
CoTaskMemFree(pbAddress);
if (pbPort)
CoTaskMemFree(pbPort);
}
for(UINT iIAD = 0; iIAD < info.cIAD; iIAD++)
{
VDS_INTERCONNECT_ADDRESS_TYPE iat;
LPBYTE pbAddress, pbPort;
ULONG cbAddress, cbPort;
CHECK_SUCCESS(pDestLun->GetInterconnectAddress
(
iIAD,
&iat,
&cbPort,
&pbPort,
&cbAddress,
&pbAddress
));
if (iat != info.rgiatypeD[iIAD] ||
cbPort != 3 ||
memcmp(pbPort, "foo", 3) != 0 ||
cbAddress != strlen(info.rgszIAD[iIAD]) + 1 ||
strcmp((char *) pbAddress, info.rgszIAD[iIAD]) != 0)
{
CoTaskMemFree(pbAddress);
CoTaskMemFree(pbPort);
Error(E_UNEXPECTED, L"Interconnect address %d does not match for destination %d", iIAS, i);
}
if (pbPort)
CoTaskMemFree(pbPort);
if (pbAddress)
CoTaskMemFree(pbAddress);
}
STORAGE_DEVICE_ID_DESCRIPTOR *pstoreFound;
CHECK_SUCCESS(pSourceLun->GetStorageDeviceIdDescriptor(&pstoreFound));
if (memcmp(pstoreFound, info.pstoreS, info.pstoreS->Size) != 0)
{
CoTaskMemFree(pstoreFound);
Error(E_UNEXPECTED, L"Storage device descriptor does not match for source %d", i);
}
CoTaskMemFree(pstoreFound);
CHECK_SUCCESS(pDestLun->GetStorageDeviceIdDescriptor(&pstoreFound));
if (memcmp(pstoreFound, info.pstoreD, info.pstoreD->Size) != 0)
{
CoTaskMemFree(pstoreFound);
Error(E_UNEXPECTED, L"Storage device descriptor does not match for destination %d", i);
}
CoTaskMemFree(pstoreFound);
}
void AddLunMappings(IVssSnapshotDescription *pSnapshot)
{
HRESULT hr;
CComPtr<IVssLunMapping> pLunMapping1;
CComPtr<IVssLunMapping> pLunMapping2;
CHECK_SUCCESS(pSnapshot->AddLunMapping());
CHECK_SUCCESS(pSnapshot->AddLunMapping());
CHECK_SUCCESS(pSnapshot->GetLunMapping(0, &pLunMapping1));
CHECK_SUCCESS(pSnapshot->GetLunMapping(1, &pLunMapping2));
AddLunInfo(pLunMapping1, 1);
AddLunInfo(pLunMapping2, 2);
}
void ValidateLunMappings(IVssSnapshotDescription *pSnapshot)
{
HRESULT hr;
CComPtr<IVssLunMapping> pLunMapping1;
CComPtr<IVssLunMapping> pLunMapping2;
UINT cMappings;
CHECK_SUCCESS(pSnapshot->GetLunCount(&cMappings));
if (cMappings != 2)
Error(E_UNEXPECTED, L"Lun mapping count is incorrect");
CHECK_SUCCESS(pSnapshot->GetLunMapping(0, &pLunMapping1));
CHECK_SUCCESS(pSnapshot->GetLunMapping(1, &pLunMapping2));
ValidateLunInfo(pLunMapping1, 1);
ValidateLunInfo(pLunMapping2, 2);
}
void ValidateSnapshot(IVssSnapshotDescription *pSnapshot, UINT iSnapshot)
{
HRESULT hr;
VSS_SNAPSHOT_PROP *pProp = &rgSnapshotProp[iSnapshot];
VSS_TIMESTAMP timestamp;
LONG lAttributes;
CComBSTR bstrOriginatingMachine;
CComBSTR bstrServiceMachine;
CComBSTR bstrOriginalVolumeName;
CComBSTR bstrSnapshotDevice;
CHECK_SUCCESS(pSnapshot->GetTimestamp(&timestamp));
if (timestamp != pProp->m_tsCreationTimestamp)
Error(E_UNEXPECTED, L"Timestamp mismatch on snapshot %d", iSnapshot);
CHECK_SUCCESS(pSnapshot->GetAttributes(&lAttributes))
if (lAttributes != pProp->m_lSnapshotAttributes)
Error(E_UNEXPECTED, L"Attributes mismatch on snapshot %d", iSnapshot);
CHECK_SUCCESS(pSnapshot->GetOrigin
(
&bstrOriginatingMachine,
&bstrOriginalVolumeName
));
CHECK_SUCCESS(pSnapshot->GetServiceMachine
(
&bstrServiceMachine
));
if (wcscmp(bstrOriginatingMachine, pProp->m_pwszOriginatingMachine) != 0)
Error(E_UNEXPECTED, L"Originating machine mismatch on snapshot %d.", iSnapshot);
if (wcscmp(bstrOriginalVolumeName, pProp->m_pwszOriginalVolumeName) != 0)
Error(E_UNEXPECTED, L"Original volume name mismatch on snapshot %d.", iSnapshot);
if (wcscmp(bstrServiceMachine, pProp->m_pwszServiceMachine) != 0)
Error(E_UNEXPECTED, L"Service machine mismatch on snapshot %d.", iSnapshot);
CHECK_SUCCESS(pSnapshot->GetDeviceName(&bstrSnapshotDevice));
if (wcscmp(bstrSnapshotDevice, pProp->m_pwszSnapshotDeviceObject) != 0)
Error(E_UNEXPECTED, L"Snapshot device name mismatch on snapshot %d.", iSnapshot);
if (iSnapshot == 2)
{
CComBSTR bstrExposedShare;
CComBSTR bstrExposedPath;
CHECK_SUCCESS(pSnapshot->GetExposure(&bstrExposedShare, &bstrExposedPath));
if (wcscmp(bstrExposedShare, L"exposed1") != 0)
Error(E_UNEXPECTED, L"Exposed share mismatch on snapshot %d.", iSnapshot);
if (wcscmp(bstrExposedPath, L"thePath") != 0)
Error(E_UNEXPECTED, L"Exposed path mismatch on snapshot %d.", iSnapshot);
}
ValidateLunMappings(pSnapshot);
}
void AddSnapshotData(IVssSnapshotDescription *pSnapshot, UINT iSnapshot)
{
HRESULT hr;
SYSTEMTIME time;
VSS_SNAPSHOT_PROP *pProp = &rgSnapshotProp[iSnapshot];
GetSystemTime(&time);
LONGLONG timestamp;
timestamp = time.wYear * 400 + time.wMonth * 31 + time.wDay;
timestamp *= 3600000 * 24;
timestamp += time.wMilliseconds + time.wSecond * 1000 + time.wMinute*60000+ time.wHour * 3600000;
pProp->m_tsCreationTimestamp = timestamp;
pProp->m_pwszSnapshotDeviceObject = iSnapshot == 1 ? L"Snapshot1" : L"Snapshot2";
pProp->m_pwszOriginalVolumeName = iSnapshot == 1 ? L"Disk1" : L"Disk2";
pProp->m_lSnapshotAttributes = VSS_CTX_BACKUP;
WCHAR buf[1024];
DWORD cb = 1024;
GetComputerNameEx(ComputerNameDnsFullyQualified, buf, &cb);
pProp->m_pwszOriginatingMachine = _wcsdup(buf);
pProp->m_pwszServiceMachine = _wcsdup(buf);
CHECK_SUCCESS(pSnapshot->SetTimestamp(pProp->m_tsCreationTimestamp));
CHECK_SUCCESS(pSnapshot->SetAttributes(pProp->m_lSnapshotAttributes));
CHECK_SUCCESS(pSnapshot->SetOrigin
(
pProp->m_pwszOriginatingMachine,
pProp->m_pwszOriginalVolumeName
));
CHECK_SUCCESS(pSnapshot->SetServiceMachine
(
pProp->m_pwszServiceMachine
));
CHECK_SUCCESS(pSnapshot->SetDeviceName(pProp->m_pwszSnapshotDeviceObject));
if (iSnapshot == 2)
CHECK_SUCCESS(pSnapshot->SetExposure(L"exposed1", L"thePath"));
AddLunMappings(pSnapshot);
ValidateSnapshot(pSnapshot, iSnapshot);
}
void TestSnapshotXML()
{
CVssFunctionTracer ft(VSSDBG_XML, L"TestSnapshotXML");
HRESULT hr;
try
{
CComPtr<IVssSnapshotSetDescription> pSnapshotSet;
CHECK_SUCCESS(CreateVssSnapshotSetDescription
(
x_idSnapSet,
VSS_CTX_BACKUP,
&pSnapshotSet
));
CHECK_SUCCESS(pSnapshotSet->SetDescription(L"This is a test snapshot set"));
CHECK_SUCCESS(pSnapshotSet->SetMetadata(L"This is some test metadata for the snapshot set."));
ValidateSnapshotSet(pSnapshotSet);
CHECK_SUCCESS(pSnapshotSet->AddSnapshotDescription(x_idSnap1, x_idProv));
CHECK_SUCCESS(pSnapshotSet->AddSnapshotDescription(x_idSnap2, x_idProv));
VSS_ID idSnap1, idSnap2;
CComPtr<IVssSnapshotDescription> pSnapshot1;
CComPtr<IVssSnapshotDescription> pSnapshot2;
GetAndValidateSnapshots(pSnapshotSet, &pSnapshot1, &pSnapshot2, idSnap1, idSnap2);
AddSnapshotData(pSnapshot1, idSnap1 == x_idSnap1 ? 1 : 2);
AddSnapshotData(pSnapshot2, idSnap2 == x_idSnap1 ? 1 : 2);
pSnapshot1 = NULL;
pSnapshot2 = NULL;
CComBSTR bstrXML;
CHECK_SUCCESS(pSnapshotSet->SaveAsXML(&bstrXML));
pSnapshotSet = NULL;
CHECK_SUCCESS(LoadVssSnapshotSetDescription(bstrXML, &pSnapshotSet));
ValidateSnapshotSet(pSnapshotSet);
GetAndValidateSnapshots(pSnapshotSet, &pSnapshot1, &pSnapshot2, idSnap1, idSnap2);
ValidateSnapshot(pSnapshot1, idSnap1 == x_idSnap1 ? 1 : 2);
ValidateSnapshot(pSnapshot2, idSnap2 == x_idSnap1 ? 1 : 2);
}
VSS_STANDARD_CATCH(ft)
if (ft.HrFailed())
wprintf(L"Snapshot XML test failed with hr = 0x%08lx\n", ft.hr);
else
wprintf(L"Snapshot XML test succeeded\n");
}