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

  1. #include "stdafx.hxx"
  2. #include "vss.h"
  3. #include "vswriter.h"
  4. #include "vsbackup.h"
  5. #include <debug.h>
  6. #include <time.h>
  7. #include <ntddstor.h>
  8. #include <vs_inc.hxx>
  9. #include <vsevent.h>
  10. #include <vdslun.h>
  11. #include <vscoordint.h>
  12. #include <vs_wmxml.hxx>
  13. #include <vs_cmxml.hxx>
  14. #include <vs_trace.hxx>
  15. static VSS_ID x_idSnapSet =
  16. {
  17. 0xD79FE5AD, 0x767F, 0x4251,
  18. 0xA9, 0x7A, 0x37, 0x37, 0xd0, 0xf9, 0xf7, 0x4f
  19. };
  20. static VSS_ID x_idSnap1 =
  21. {
  22. 0x78B049FB, 0x9D12, 0x40A6,
  23. 0x82, 0x6C, 0xED, 0x8A, 0x80, 0x4E, 0xB4, 0xAA
  24. };
  25. static VSS_ID x_idSnap2 =
  26. {
  27. 0xE700B0EC, 0xA993, 0x4B1B,
  28. 0xAD, 0xDA, 0xC2, 0xAA, 0x08, 0x53, 0x6F, 0x27
  29. };
  30. static VSS_ID x_idProv =
  31. {
  32. 0x587E6660, 0x3FEF, 0x45D6,
  33. 0x8D, 0x91, 0xB1, 0x2E, 0x16, 0xAC, 0x5C, 0x18
  34. };
  35. void GetAndValidateSnapshots
  36. (
  37. IN IVssSnapshotSetDescription *pSnapshotSet,
  38. OUT IVssSnapshotDescription **ppSnapshot1,
  39. OUT IVssSnapshotDescription **ppSnapshot2,
  40. OUT VSS_ID &idSnap1,
  41. OUT VSS_ID &idSnap2
  42. )
  43. {
  44. HRESULT hr;
  45. UINT cSnapshots;
  46. CHECK_SUCCESS(pSnapshotSet->GetSnapshotCount(&cSnapshots));
  47. if (cSnapshots != 2)
  48. {
  49. wprintf(L"Number of snapshots %d is not correct.\n");
  50. BS_ASSERT(FALSE);
  51. throw(E_UNEXPECTED);
  52. }
  53. VSS_ID idProv;
  54. CHECK_SUCCESS(pSnapshotSet->GetSnapshotDescription(0, ppSnapshot1));
  55. CHECK_SUCCESS(pSnapshotSet->GetSnapshotDescription(1, ppSnapshot2));
  56. CHECK_SUCCESS((*ppSnapshot1)->GetSnapshotId(&idSnap1));
  57. CHECK_SUCCESS((*ppSnapshot2)->GetSnapshotId(&idSnap2));
  58. if ((idSnap1 != x_idSnap1 || idSnap2 != x_idSnap2) &&
  59. (idSnap1 != x_idSnap2 || idSnap2 != x_idSnap1))
  60. Error(E_UNEXPECTED,
  61. L"Snapshots were not added properly. Added snapshots are:\n"
  62. WSTR_GUID_FMT L" and " WSTR_GUID_FMT
  63. L"\nFound snapshots are" WSTR_GUID_FMT L" and "
  64. WSTR_GUID_FMT L"\n",
  65. GUID_PRINTF_ARG(x_idSnap1),
  66. GUID_PRINTF_ARG(x_idSnap2),
  67. GUID_PRINTF_ARG(idSnap1),
  68. GUID_PRINTF_ARG(idSnap2));
  69. CHECK_SUCCESS((*ppSnapshot1)->GetProviderId(&idProv));
  70. if (idProv != x_idProv)
  71. Error(E_UNEXPECTED,
  72. L"Provider id was not correct.\n"
  73. WSTR_GUID_FMT L" != " WSTR_GUID_FMT L".\n",
  74. GUID_PRINTF_ARG(idProv),
  75. GUID_PRINTF_ARG(x_idProv));
  76. CHECK_SUCCESS((*ppSnapshot2)->GetProviderId(&idProv));
  77. if (idProv != x_idProv)
  78. Error(E_UNEXPECTED,
  79. L"Provider id was not correct.\n"
  80. WSTR_GUID_FMT L" != " WSTR_GUID_FMT L".\n",
  81. GUID_PRINTF_ARG(idProv),
  82. GUID_PRINTF_ARG(x_idProv));
  83. }
  84. void ValidateSnapshotSet(IVssSnapshotSetDescription *pSnapshotSet)
  85. {
  86. HRESULT hr;
  87. VSS_ID idSnapSet;
  88. CHECK_SUCCESS(pSnapshotSet->GetSnapshotSetId(&idSnapSet));
  89. if (idSnapSet != x_idSnapSet)
  90. Error(E_UNEXPECTED, L"snapshot set id does not match: "
  91. WSTR_GUID_FMT L" != " WSTR_GUID_FMT,
  92. GUID_PRINTF_ARG(idSnapSet),
  93. GUID_PRINTF_ARG(x_idSnapSet));
  94. CComBSTR bstrDescription;
  95. CComBSTR bstrMetadata;
  96. CHECK_SUCCESS(pSnapshotSet->GetDescription(&bstrDescription));
  97. if (wcscmp(bstrDescription, L"This is a test snapshot set") != 0)
  98. Error(E_UNEXPECTED, L"Snapshot description is invalid:\n%s", bstrDescription);
  99. CHECK_SUCCESS(pSnapshotSet->GetMetadata(&bstrMetadata));
  100. if (wcscmp(bstrMetadata, L"This is some test metadata for the snapshot set.") != 0)
  101. Error(E_UNEXPECTED, L"Snapshot metadata is invalid:\n%s", bstrMetadata);
  102. LONG lContext;
  103. CHECK_SUCCESS(pSnapshotSet->GetContext(&lContext));
  104. if (lContext != VSS_CTX_BACKUP)
  105. Error(E_UNEXPECTED, L"Context is invalid. lContext=%d\n", lContext);
  106. }
  107. VSS_SNAPSHOT_PROP rgSnapshotProp[2];
  108. static UCHAR x_DeviceType1 = 1;
  109. static UCHAR x_DeviceType2 = 2;
  110. static UCHAR x_DeviceTypeModifier1 = 100;
  111. static UCHAR x_DeviceTypeModifier2 = 200;
  112. static ULONGLONG x_rgDiskExtents1[] = {10L, 2000L, 4000L, 1000L};
  113. static UINT x_cDiskExtents1 = 2;
  114. static ULONGLONG x_rgDiskExtents2[] = {100L, 1000L, 2000L, 10000L, 100000L, 4000L};
  115. static UINT x_cDiskExtents2 = 3;
  116. static LPCSTR x_szVendorId1 = "MICROSOFT";
  117. static LPCSTR x_szVendorId2 = "PLATFORMS";
  118. static LPCSTR x_szProductId1 = "LVM";
  119. static LPCSTR x_szProductId2 = "VDS";
  120. static LPCSTR x_szProductRevision1 = "1.0";
  121. static LPCSTR x_szProductRevision2 = "2.1";
  122. static LPCSTR x_szSerialNumber1S = "123987";
  123. static LPCSTR x_szSerialNumber1D = "343434";
  124. static LPCSTR x_szSerialNumber2S = "999999-1111";
  125. static LPCSTR x_szSerialNumber2D = "888888-2222";
  126. static VDS_STORAGE_BUS_TYPE x_busType1 = VDSBusTypeScsi;
  127. static VDS_STORAGE_BUS_TYPE x_busType2 = VDSBusTypeFibre;
  128. static VSS_ID x_idDiskSignature1 =
  129. {
  130. 0xF1CFF9EC, 0xB0A3, 0x408C,
  131. 0xB5, 0xC9, 0x0C, 0x98, 0xDF, 0xFD, 0xDA, 0xED
  132. };
  133. static VSS_ID x_idDiskSignature2 =
  134. {
  135. 0xB33FF922, 0xB0A3, 0x408C,
  136. 0xB5, 0xC9, 0x0C, 0x98, 0xDF, 0xFD, 0xDA, 0xED
  137. };
  138. static VDS_INTERCONNECT_ADDRESS_TYPE x_rgIAType1S[] = {VDS_IA_FCFS, VDS_IA_FCFS, VDS_IA_FCFS};
  139. static LPCSTR x_rgszAddresses1S[] = {"CAB1.BUS10.SLOT10", "CAB1.BUS20.SLOT30", "CAB20.BUS3.SLOT100"};
  140. static UINT x_cInterconnectAddresses1S = 3;
  141. static VDS_INTERCONNECT_ADDRESS_TYPE x_rgIAType1D[] = {VDS_IA_FCFS, VDS_IA_FCFS, VDS_IA_FCFS};
  142. static LPCSTR x_rgszAddresses1D[] = {"CAB1.BUS1.SLOT10", "CAB1.BUS2.SLOT30", "CAB2.BUS3.SLOT10"};
  143. static UINT x_cInterconnectAddresses1D = 3;
  144. static VDS_INTERCONNECT_ADDRESS_TYPE rgIAType2S[] = {VDS_IA_FCPH};
  145. static LPCSTR x_rgszAddresses2S[] = {"10.1.1.4.BUS1.SLOT10"};
  146. static UINT x_cInterconnectAddresses2S = 1;
  147. static VDS_INTERCONNECT_ADDRESS_TYPE rgIAType2D[] = {VDS_IA_FCPH};
  148. static LPCSTR x_rgszAddresses2D[] = {"100.2.3.8.BUS11.SLOT10"};
  149. static UINT x_cInterconnectAddresses2D = 1;
  150. static STORAGE_IDENTIFIER x_storeid1 = {StorageIdCodeSetBinary, StorageIdTypeVendorId, 8, 0, StorageIdAssocDevice, 0};
  151. static STORAGE_IDENTIFIER x_storeid2 = {StorageIdCodeSetBinary, StorageIdTypeVendorSpecific, 20, 0, StorageIdAssocDevice, 0};
  152. static STORAGE_IDENTIFIER x_storeid3 = {StorageIdCodeSetAscii, StorageIdTypeFCPHName, 32, 0, StorageIdAssocDevice, 0};
  153. static STORAGE_IDENTIFIER x_storeid4 = {StorageIdCodeSetBinary, StorageIdTypeEUI64, 8, 0, StorageIdAssocDevice, 0};
  154. void AddIdentifier(BYTE **ppb, STORAGE_IDENTIFIER *pid, UINT &ib)
  155. {
  156. if (pid)
  157. {
  158. UINT cb = pid->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
  159. memcpy(*ppb, pid, FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier));
  160. ib += cb;
  161. ((STORAGE_IDENTIFIER *) (*ppb))->NextOffset = (USHORT) ib;
  162. memset(*ppb + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier), 0x10, pid->IdentifierSize);
  163. *ppb += cb;
  164. }
  165. }
  166. void BuildStorageIdDescriptor
  167. (
  168. STORAGE_DEVICE_ID_DESCRIPTOR **ppstore,
  169. STORAGE_IDENTIFIER *pid1,
  170. STORAGE_IDENTIFIER *pid2,
  171. STORAGE_IDENTIFIER *pid3,
  172. STORAGE_IDENTIFIER *pid4
  173. )
  174. {
  175. UINT cid = 0;
  176. UINT cb = FIELD_OFFSET(STORAGE_DEVICE_ID_DESCRIPTOR, Identifiers);
  177. if (pid1)
  178. {
  179. cid++;
  180. cb += pid1->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
  181. }
  182. if (pid2)
  183. {
  184. cid++;
  185. cb += pid2->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
  186. }
  187. if (pid3)
  188. {
  189. cid++;
  190. cb += pid3->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
  191. }
  192. if (pid4)
  193. {
  194. cid++;
  195. cb += pid4->IdentifierSize + FIELD_OFFSET(STORAGE_IDENTIFIER, Identifier);
  196. }
  197. BYTE *pb = new BYTE[cb];
  198. STORAGE_DEVICE_ID_DESCRIPTOR *pstore = (STORAGE_DEVICE_ID_DESCRIPTOR *) pb;
  199. pstore->Version = 10;
  200. pstore->Size = cb;
  201. pstore->NumberOfIdentifiers = cid;
  202. pb = pstore->Identifiers;
  203. UINT ib = FIELD_OFFSET(STORAGE_DEVICE_ID_DESCRIPTOR, Identifiers);
  204. AddIdentifier(&pb, pid1, ib);
  205. AddIdentifier(&pb, pid2, ib);
  206. AddIdentifier(&pb, pid3, ib);
  207. AddIdentifier(&pb, pid4, ib);
  208. BS_ASSERT(ib == cb);
  209. *ppstore = pstore;
  210. }
  211. typedef struct _BETEST_LUN_INFO
  212. {
  213. UCHAR DeviceType;
  214. UCHAR DeviceTypeModifier;
  215. ULONGLONG *rgDiskExtents;
  216. UINT cDiskExtents;
  217. LPCSTR szVendorId;
  218. LPCSTR szProductId;
  219. LPCSTR szProductRevision;
  220. LPCSTR szSerialNumberSource;
  221. LPCSTR szSerialNumberDest;
  222. VDS_STORAGE_BUS_TYPE busType;
  223. VSS_ID idDiskSignature;
  224. VDS_INTERCONNECT_ADDRESS_TYPE *rgiatypeS;
  225. VDS_INTERCONNECT_ADDRESS_TYPE *rgiatypeD;
  226. LPCSTR *rgszIAS;
  227. LPCSTR *rgszIAD;
  228. UINT cIAS;
  229. UINT cIAD;
  230. STORAGE_DEVICE_ID_DESCRIPTOR *pstoreS;
  231. STORAGE_DEVICE_ID_DESCRIPTOR *pstoreD;
  232. } BETEST_LUN_INFO;
  233. void BuildLunInfo (UINT i, BETEST_LUN_INFO &info)
  234. {
  235. if (i == 1)
  236. {
  237. info.DeviceType = x_DeviceType1;
  238. info.DeviceTypeModifier = x_DeviceTypeModifier1;
  239. info.rgDiskExtents = x_rgDiskExtents1;
  240. info.cDiskExtents = x_cDiskExtents1;
  241. info.szVendorId = x_szVendorId1;
  242. info.szProductId = x_szProductId1;
  243. info.szProductRevision = x_szProductRevision1;
  244. info.szSerialNumberSource = x_szSerialNumber1S;
  245. info.szSerialNumberDest = x_szSerialNumber1D;
  246. info.busType = x_busType1;
  247. info.idDiskSignature = x_idDiskSignature1;
  248. info.rgiatypeS = x_rgIAType1S;
  249. info.rgiatypeD = x_rgIAType1D;
  250. info.rgszIAS = x_rgszAddresses1S;
  251. info.rgszIAD = x_rgszAddresses1D;
  252. info.cIAS = x_cInterconnectAddresses1S;
  253. info.cIAD = x_cInterconnectAddresses1D;
  254. BuildStorageIdDescriptor(&info.pstoreS, &x_storeid1, &x_storeid3, NULL, NULL);
  255. BuildStorageIdDescriptor(&info.pstoreD, &x_storeid1, &x_storeid3, &x_storeid4, NULL);
  256. }
  257. else
  258. {
  259. info.DeviceType = x_DeviceType2;
  260. info.DeviceTypeModifier = x_DeviceTypeModifier2;
  261. info.rgDiskExtents = x_rgDiskExtents2;
  262. info.cDiskExtents = x_cDiskExtents2;
  263. info.szVendorId = x_szVendorId2;
  264. info.szProductId = x_szProductId2;
  265. info.szProductRevision = x_szProductRevision2;
  266. info.szSerialNumberSource = x_szSerialNumber2S;
  267. info.szSerialNumberDest = x_szSerialNumber2D;
  268. info.busType = x_busType2;
  269. info.idDiskSignature = x_idDiskSignature2;
  270. info.rgiatypeS = rgIAType2S;
  271. info.rgiatypeD = rgIAType2D;
  272. info.rgszIAS = x_rgszAddresses2S;
  273. info.rgszIAD = x_rgszAddresses2D;
  274. info.cIAS = x_cInterconnectAddresses2S;
  275. info.cIAD = x_cInterconnectAddresses2D;
  276. BuildStorageIdDescriptor(&info.pstoreS, &x_storeid1, &x_storeid2, NULL, NULL);
  277. BuildStorageIdDescriptor(&info.pstoreD, &x_storeid1, &x_storeid2, &x_storeid3, &x_storeid4);
  278. }
  279. }
  280. void AddLunInfo(IVssLunMapping *pLunMapping, UINT i)
  281. {
  282. HRESULT hr;
  283. CComPtr<IVssLunInformation> pSourceLun;
  284. CComPtr<IVssLunInformation> pDestLun;
  285. BETEST_LUN_INFO info;
  286. BuildLunInfo(i, info);
  287. CHECK_SUCCESS(pLunMapping->GetSourceLun(&pSourceLun));
  288. CHECK_SUCCESS(pLunMapping->GetDestinationLun(&pDestLun));
  289. CHECK_SUCCESS(pSourceLun->SetLunBasicType
  290. (
  291. info.DeviceType,
  292. info.DeviceTypeModifier,
  293. true,
  294. info.szVendorId,
  295. info.szProductId,
  296. info.szProductRevision,
  297. info.szSerialNumberSource,
  298. info.busType
  299. ));
  300. CHECK_SUCCESS(pDestLun->SetLunBasicType
  301. (
  302. info.DeviceType,
  303. info.DeviceTypeModifier,
  304. true,
  305. info.szVendorId,
  306. info.szProductId,
  307. info.szProductRevision,
  308. info.szSerialNumberDest,
  309. info.busType
  310. ));
  311. CHECK_SUCCESS(pSourceLun->SetDiskSignature(info.idDiskSignature));
  312. CHECK_SUCCESS(pDestLun->SetDiskSignature(info.idDiskSignature));
  313. for(UINT iExtent = 0; iExtent < info.cDiskExtents; iExtent++)
  314. CHECK_SUCCESS(pLunMapping->AddDiskExtent
  315. (
  316. info.rgDiskExtents[iExtent * 2],
  317. info.rgDiskExtents[iExtent * 2 + 1]
  318. ));
  319. for(UINT iIAS = 0; iIAS < info.cIAS; iIAS++)
  320. CHECK_SUCCESS(pSourceLun->AddInterconnectAddress
  321. (
  322. info.rgiatypeS[iIAS],
  323. 0,
  324. NULL,
  325. (UINT) (strlen(info.rgszIAS[iIAS]) + 1),
  326. (const BYTE *) info.rgszIAS[iIAS]
  327. ));
  328. for(UINT iIAD = 0; iIAD < info.cIAD; iIAD++)
  329. CHECK_SUCCESS(pDestLun->AddInterconnectAddress
  330. (
  331. info.rgiatypeD[iIAD],
  332. 3,
  333. (BYTE *) "foo",
  334. (UINT) (strlen(info.rgszIAD[iIAD]) + 1),
  335. (const BYTE *) info.rgszIAD[iIAD]
  336. ));
  337. CHECK_SUCCESS(pSourceLun->SetStorageDeviceIdDescriptor(info.pstoreS));
  338. CHECK_SUCCESS(pDestLun->SetStorageDeviceIdDescriptor(info.pstoreD));
  339. }
  340. bool cmp_str_eq(LPCSTR sz1, LPCSTR sz2)
  341. {
  342. return (sz1 == NULL && sz2 == NULL) ||
  343. (sz1 != NULL && sz2 != NULL && strcmp(sz1, sz2) == 0);
  344. }
  345. void DoCoTaskFree
  346. (
  347. LPSTR &str1,
  348. LPSTR &str2,
  349. LPSTR &str3,
  350. LPSTR &str4
  351. )
  352. {
  353. if (str1)
  354. {
  355. CoTaskMemFree(str1);
  356. str1 = NULL;
  357. }
  358. if (str2)
  359. {
  360. CoTaskMemFree(str2);
  361. str2 = NULL;
  362. }
  363. if (str3)
  364. {
  365. CoTaskMemFree(str3);
  366. str3 = NULL;
  367. }
  368. if (str4)
  369. {
  370. CoTaskMemFree(str4);
  371. str4 = NULL;
  372. }
  373. }
  374. void ValidateLunInfo(IVssLunMapping *pLunMapping, UINT i)
  375. {
  376. HRESULT hr;
  377. CComPtr<IVssLunInformation> pSourceLun;
  378. CComPtr<IVssLunInformation> pDestLun;
  379. BETEST_LUN_INFO info;
  380. BuildLunInfo(i, info);
  381. CHECK_SUCCESS(pLunMapping->GetSourceLun(&pSourceLun));
  382. CHECK_SUCCESS(pLunMapping->GetDestinationLun(&pDestLun));
  383. UINT cExtents;
  384. CHECK_SUCCESS(pLunMapping->GetDiskExtentCount(&cExtents));
  385. if (cExtents != info.cDiskExtents)
  386. Error(E_UNEXPECTED, L"Invalid number of extents for lun %d", i);
  387. for(UINT iExtent = 0; iExtent < cExtents; iExtent++)
  388. {
  389. ULONGLONG start, length;
  390. CHECK_SUCCESS(pLunMapping->GetDiskExtent(iExtent, &start, &length));
  391. if (start != info.rgDiskExtents[iExtent * 2] ||
  392. length != info.rgDiskExtents[iExtent * 2 + 1])
  393. Error(E_UNEXPECTED, L"Invalid extent %d for lun %d", iExtent, i);
  394. }
  395. LPSTR strVendorId;
  396. LPSTR strProductId;
  397. LPSTR strProductRevision;
  398. LPSTR strSerialNumber;
  399. VDS_STORAGE_BUS_TYPE busTypeFound;
  400. UCHAR DeviceTypeFound;
  401. UCHAR DeviceTypeModifierFound;
  402. BOOL bCommandQueueing;
  403. CHECK_SUCCESS(pSourceLun->GetLunBasicType
  404. (
  405. &DeviceTypeFound,
  406. &DeviceTypeModifierFound,
  407. &bCommandQueueing,
  408. &strVendorId,
  409. &strProductId,
  410. &strProductRevision,
  411. &strSerialNumber,
  412. &busTypeFound
  413. ));
  414. if (DeviceTypeFound != info.DeviceType ||
  415. DeviceTypeModifierFound != info.DeviceTypeModifier ||
  416. busTypeFound != info.busType ||
  417. !bCommandQueueing ||
  418. !cmp_str_eq(strVendorId, info.szVendorId) ||
  419. !cmp_str_eq(strProductId, info.szProductId) ||
  420. !cmp_str_eq(strProductRevision, info.szProductRevision) ||
  421. !cmp_str_eq(strSerialNumber, info.szSerialNumberSource))
  422. {
  423. DoCoTaskFree(strVendorId, strProductId, strProductRevision, strSerialNumber);
  424. Error(E_UNEXPECTED, L"Problem in basic LUN information for source %d.\n", i);
  425. }
  426. DoCoTaskFree(strVendorId, strProductId, strProductRevision, strSerialNumber);
  427. CHECK_SUCCESS(pDestLun->GetLunBasicType
  428. (
  429. &DeviceTypeFound,
  430. &DeviceTypeModifierFound,
  431. &bCommandQueueing,
  432. &strVendorId,
  433. &strProductId,
  434. &strProductRevision,
  435. &strSerialNumber,
  436. &busTypeFound
  437. ));
  438. if (DeviceTypeFound != info.DeviceType ||
  439. DeviceTypeModifierFound != info.DeviceTypeModifier ||
  440. busTypeFound != info.busType ||
  441. !cmp_str_eq(strVendorId, info.szVendorId) ||
  442. !cmp_str_eq(strProductId, info.szProductId) ||
  443. !cmp_str_eq(strProductRevision, info.szProductRevision) ||
  444. !cmp_str_eq(strSerialNumber, info.szSerialNumberDest))
  445. {
  446. DoCoTaskFree(strVendorId, strProductId, strProductRevision, strSerialNumber);
  447. Error(E_UNEXPECTED, L"Problem in basic LUN information four destination %d.\n", i);
  448. }
  449. DoCoTaskFree(strVendorId, strProductId, strProductRevision, strSerialNumber);
  450. VSS_ID idDiskSignatureFound;
  451. CHECK_SUCCESS(pSourceLun->GetDiskSignature(&idDiskSignatureFound));
  452. if (info.idDiskSignature != idDiskSignatureFound)
  453. Error(E_UNEXPECTED, L"Disk signatures do not match for source %d.\n", i);
  454. CHECK_SUCCESS(pDestLun->GetDiskSignature(&idDiskSignatureFound));
  455. if (info.idDiskSignature != idDiskSignatureFound)
  456. Error(E_UNEXPECTED, L"Disk signatures do not match for destination %d.\n", i);
  457. UINT cia;
  458. CHECK_SUCCESS(pSourceLun->GetInterconnectAddressCount(&cia));
  459. if (cia != info.cIAS)
  460. Error(E_UNEXPECTED, L"Interconnect address count does not match for source %d", i);
  461. CHECK_SUCCESS(pDestLun->GetInterconnectAddressCount(&cia));
  462. if (cia != info.cIAD)
  463. Error(E_UNEXPECTED, L"Interconnect address count does not match for source %d", i);
  464. for(UINT iIAS = 0; iIAS < info.cIAS; iIAS++)
  465. {
  466. VDS_INTERCONNECT_ADDRESS_TYPE iat;
  467. LPBYTE pbAddress, pbPort;
  468. ULONG cbAddress, cbPort;
  469. CHECK_SUCCESS(pSourceLun->GetInterconnectAddress
  470. (
  471. iIAS,
  472. &iat,
  473. &cbPort,
  474. &pbPort,
  475. &cbAddress,
  476. &pbAddress
  477. ));
  478. if (iat != info.rgiatypeS[iIAS] ||
  479. cbPort != 0 ||
  480. pbPort != NULL ||
  481. cbAddress != strlen(info.rgszIAS[iIAS]) + 1 ||
  482. strcmp((char *) pbAddress, info.rgszIAS[iIAS]) != 0)
  483. {
  484. CoTaskMemFree(pbAddress);
  485. Error(E_UNEXPECTED, L"Interconnect address %d does not match for source %d", iIAS, i);
  486. }
  487. if (pbAddress)
  488. CoTaskMemFree(pbAddress);
  489. if (pbPort)
  490. CoTaskMemFree(pbPort);
  491. }
  492. for(UINT iIAD = 0; iIAD < info.cIAD; iIAD++)
  493. {
  494. VDS_INTERCONNECT_ADDRESS_TYPE iat;
  495. LPBYTE pbAddress, pbPort;
  496. ULONG cbAddress, cbPort;
  497. CHECK_SUCCESS(pDestLun->GetInterconnectAddress
  498. (
  499. iIAD,
  500. &iat,
  501. &cbPort,
  502. &pbPort,
  503. &cbAddress,
  504. &pbAddress
  505. ));
  506. if (iat != info.rgiatypeD[iIAD] ||
  507. cbPort != 3 ||
  508. memcmp(pbPort, "foo", 3) != 0 ||
  509. cbAddress != strlen(info.rgszIAD[iIAD]) + 1 ||
  510. strcmp((char *) pbAddress, info.rgszIAD[iIAD]) != 0)
  511. {
  512. CoTaskMemFree(pbAddress);
  513. CoTaskMemFree(pbPort);
  514. Error(E_UNEXPECTED, L"Interconnect address %d does not match for destination %d", iIAS, i);
  515. }
  516. if (pbPort)
  517. CoTaskMemFree(pbPort);
  518. if (pbAddress)
  519. CoTaskMemFree(pbAddress);
  520. }
  521. STORAGE_DEVICE_ID_DESCRIPTOR *pstoreFound;
  522. CHECK_SUCCESS(pSourceLun->GetStorageDeviceIdDescriptor(&pstoreFound));
  523. if (memcmp(pstoreFound, info.pstoreS, info.pstoreS->Size) != 0)
  524. {
  525. CoTaskMemFree(pstoreFound);
  526. Error(E_UNEXPECTED, L"Storage device descriptor does not match for source %d", i);
  527. }
  528. CoTaskMemFree(pstoreFound);
  529. CHECK_SUCCESS(pDestLun->GetStorageDeviceIdDescriptor(&pstoreFound));
  530. if (memcmp(pstoreFound, info.pstoreD, info.pstoreD->Size) != 0)
  531. {
  532. CoTaskMemFree(pstoreFound);
  533. Error(E_UNEXPECTED, L"Storage device descriptor does not match for destination %d", i);
  534. }
  535. CoTaskMemFree(pstoreFound);
  536. }
  537. void AddLunMappings(IVssSnapshotDescription *pSnapshot)
  538. {
  539. HRESULT hr;
  540. CComPtr<IVssLunMapping> pLunMapping1;
  541. CComPtr<IVssLunMapping> pLunMapping2;
  542. CHECK_SUCCESS(pSnapshot->AddLunMapping());
  543. CHECK_SUCCESS(pSnapshot->AddLunMapping());
  544. CHECK_SUCCESS(pSnapshot->GetLunMapping(0, &pLunMapping1));
  545. CHECK_SUCCESS(pSnapshot->GetLunMapping(1, &pLunMapping2));
  546. AddLunInfo(pLunMapping1, 1);
  547. AddLunInfo(pLunMapping2, 2);
  548. }
  549. void ValidateLunMappings(IVssSnapshotDescription *pSnapshot)
  550. {
  551. HRESULT hr;
  552. CComPtr<IVssLunMapping> pLunMapping1;
  553. CComPtr<IVssLunMapping> pLunMapping2;
  554. UINT cMappings;
  555. CHECK_SUCCESS(pSnapshot->GetLunCount(&cMappings));
  556. if (cMappings != 2)
  557. Error(E_UNEXPECTED, L"Lun mapping count is incorrect");
  558. CHECK_SUCCESS(pSnapshot->GetLunMapping(0, &pLunMapping1));
  559. CHECK_SUCCESS(pSnapshot->GetLunMapping(1, &pLunMapping2));
  560. ValidateLunInfo(pLunMapping1, 1);
  561. ValidateLunInfo(pLunMapping2, 2);
  562. }
  563. void ValidateSnapshot(IVssSnapshotDescription *pSnapshot, UINT iSnapshot)
  564. {
  565. HRESULT hr;
  566. VSS_SNAPSHOT_PROP *pProp = &rgSnapshotProp[iSnapshot];
  567. VSS_TIMESTAMP timestamp;
  568. LONG lAttributes;
  569. CComBSTR bstrOriginatingMachine;
  570. CComBSTR bstrServiceMachine;
  571. CComBSTR bstrOriginalVolumeName;
  572. CComBSTR bstrSnapshotDevice;
  573. CHECK_SUCCESS(pSnapshot->GetTimestamp(&timestamp));
  574. if (timestamp != pProp->m_tsCreationTimestamp)
  575. Error(E_UNEXPECTED, L"Timestamp mismatch on snapshot %d", iSnapshot);
  576. CHECK_SUCCESS(pSnapshot->GetAttributes(&lAttributes))
  577. if (lAttributes != pProp->m_lSnapshotAttributes)
  578. Error(E_UNEXPECTED, L"Attributes mismatch on snapshot %d", iSnapshot);
  579. CHECK_SUCCESS(pSnapshot->GetOrigin
  580. (
  581. &bstrOriginatingMachine,
  582. &bstrOriginalVolumeName
  583. ));
  584. CHECK_SUCCESS(pSnapshot->GetServiceMachine
  585. (
  586. &bstrServiceMachine
  587. ));
  588. if (wcscmp(bstrOriginatingMachine, pProp->m_pwszOriginatingMachine) != 0)
  589. Error(E_UNEXPECTED, L"Originating machine mismatch on snapshot %d.", iSnapshot);
  590. if (wcscmp(bstrOriginalVolumeName, pProp->m_pwszOriginalVolumeName) != 0)
  591. Error(E_UNEXPECTED, L"Original volume name mismatch on snapshot %d.", iSnapshot);
  592. if (wcscmp(bstrServiceMachine, pProp->m_pwszServiceMachine) != 0)
  593. Error(E_UNEXPECTED, L"Service machine mismatch on snapshot %d.", iSnapshot);
  594. CHECK_SUCCESS(pSnapshot->GetDeviceName(&bstrSnapshotDevice));
  595. if (wcscmp(bstrSnapshotDevice, pProp->m_pwszSnapshotDeviceObject) != 0)
  596. Error(E_UNEXPECTED, L"Snapshot device name mismatch on snapshot %d.", iSnapshot);
  597. if (iSnapshot == 2)
  598. {
  599. CComBSTR bstrExposedShare;
  600. CComBSTR bstrExposedPath;
  601. CHECK_SUCCESS(pSnapshot->GetExposure(&bstrExposedShare, &bstrExposedPath));
  602. if (wcscmp(bstrExposedShare, L"exposed1") != 0)
  603. Error(E_UNEXPECTED, L"Exposed share mismatch on snapshot %d.", iSnapshot);
  604. if (wcscmp(bstrExposedPath, L"thePath") != 0)
  605. Error(E_UNEXPECTED, L"Exposed path mismatch on snapshot %d.", iSnapshot);
  606. }
  607. ValidateLunMappings(pSnapshot);
  608. }
  609. void AddSnapshotData(IVssSnapshotDescription *pSnapshot, UINT iSnapshot)
  610. {
  611. HRESULT hr;
  612. SYSTEMTIME time;
  613. VSS_SNAPSHOT_PROP *pProp = &rgSnapshotProp[iSnapshot];
  614. GetSystemTime(&time);
  615. LONGLONG timestamp;
  616. timestamp = time.wYear * 400 + time.wMonth * 31 + time.wDay;
  617. timestamp *= 3600000 * 24;
  618. timestamp += time.wMilliseconds + time.wSecond * 1000 + time.wMinute*60000+ time.wHour * 3600000;
  619. pProp->m_tsCreationTimestamp = timestamp;
  620. pProp->m_pwszSnapshotDeviceObject = iSnapshot == 1 ? L"Snapshot1" : L"Snapshot2";
  621. pProp->m_pwszOriginalVolumeName = iSnapshot == 1 ? L"Disk1" : L"Disk2";
  622. pProp->m_lSnapshotAttributes = VSS_CTX_BACKUP;
  623. WCHAR buf[1024];
  624. DWORD cb = 1024;
  625. GetComputerNameEx(ComputerNameDnsFullyQualified, buf, &cb);
  626. pProp->m_pwszOriginatingMachine = _wcsdup(buf);
  627. pProp->m_pwszServiceMachine = _wcsdup(buf);
  628. CHECK_SUCCESS(pSnapshot->SetTimestamp(pProp->m_tsCreationTimestamp));
  629. CHECK_SUCCESS(pSnapshot->SetAttributes(pProp->m_lSnapshotAttributes));
  630. CHECK_SUCCESS(pSnapshot->SetOrigin
  631. (
  632. pProp->m_pwszOriginatingMachine,
  633. pProp->m_pwszOriginalVolumeName
  634. ));
  635. CHECK_SUCCESS(pSnapshot->SetServiceMachine
  636. (
  637. pProp->m_pwszServiceMachine
  638. ));
  639. CHECK_SUCCESS(pSnapshot->SetDeviceName(pProp->m_pwszSnapshotDeviceObject));
  640. if (iSnapshot == 2)
  641. CHECK_SUCCESS(pSnapshot->SetExposure(L"exposed1", L"thePath"));
  642. AddLunMappings(pSnapshot);
  643. ValidateSnapshot(pSnapshot, iSnapshot);
  644. }
  645. void TestSnapshotXML()
  646. {
  647. CVssFunctionTracer ft(VSSDBG_XML, L"TestSnapshotXML");
  648. HRESULT hr;
  649. try
  650. {
  651. CComPtr<IVssSnapshotSetDescription> pSnapshotSet;
  652. CHECK_SUCCESS(CreateVssSnapshotSetDescription
  653. (
  654. x_idSnapSet,
  655. VSS_CTX_BACKUP,
  656. &pSnapshotSet
  657. ));
  658. CHECK_SUCCESS(pSnapshotSet->SetDescription(L"This is a test snapshot set"));
  659. CHECK_SUCCESS(pSnapshotSet->SetMetadata(L"This is some test metadata for the snapshot set."));
  660. ValidateSnapshotSet(pSnapshotSet);
  661. CHECK_SUCCESS(pSnapshotSet->AddSnapshotDescription(x_idSnap1, x_idProv));
  662. CHECK_SUCCESS(pSnapshotSet->AddSnapshotDescription(x_idSnap2, x_idProv));
  663. VSS_ID idSnap1, idSnap2;
  664. CComPtr<IVssSnapshotDescription> pSnapshot1;
  665. CComPtr<IVssSnapshotDescription> pSnapshot2;
  666. GetAndValidateSnapshots(pSnapshotSet, &pSnapshot1, &pSnapshot2, idSnap1, idSnap2);
  667. AddSnapshotData(pSnapshot1, idSnap1 == x_idSnap1 ? 1 : 2);
  668. AddSnapshotData(pSnapshot2, idSnap2 == x_idSnap1 ? 1 : 2);
  669. pSnapshot1 = NULL;
  670. pSnapshot2 = NULL;
  671. CComBSTR bstrXML;
  672. CHECK_SUCCESS(pSnapshotSet->SaveAsXML(&bstrXML));
  673. pSnapshotSet = NULL;
  674. CHECK_SUCCESS(LoadVssSnapshotSetDescription(bstrXML, &pSnapshotSet));
  675. ValidateSnapshotSet(pSnapshotSet);
  676. GetAndValidateSnapshots(pSnapshotSet, &pSnapshot1, &pSnapshot2, idSnap1, idSnap2);
  677. ValidateSnapshot(pSnapshot1, idSnap1 == x_idSnap1 ? 1 : 2);
  678. ValidateSnapshot(pSnapshot2, idSnap2 == x_idSnap1 ? 1 : 2);
  679. }
  680. VSS_STANDARD_CATCH(ft)
  681. if (ft.HrFailed())
  682. wprintf(L"Snapshot XML test failed with hr = 0x%08lx\n", ft.hr);
  683. else
  684. wprintf(L"Snapshot XML test succeeded\n");
  685. }