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.

1286 lines
37 KiB

  1. #include "stdafx.hxx"
  2. #include "vs_idl.hxx"
  3. #include "vswriter.h"
  4. #include "vsbackup.h"
  5. #include "vs_seh.hxx"
  6. #include "vs_trace.hxx"
  7. #include "compont.h"
  8. #include <debug.h>
  9. #include <cwriter.h>
  10. #include <lmshare.h>
  11. #include <lmaccess.h>
  12. #include <time.h>
  13. #define IID_PPV_ARG( Type, Expr ) IID_##Type, reinterpret_cast< void** >( static_cast< Type** >( Expr ) )
  14. #define SafeQI( Type, Expr ) QueryInterface( IID_PPV_ARG( Type, Expr ) )
  15. static BYTE x_rgbIcon[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  16. static unsigned x_cbIcon = 10;
  17. static VSS_ID s_WRITERID =
  18. {
  19. 0xc0577ae6, 0xd741, 0x452a,
  20. 0x8c, 0xba, 0x99, 0xd7, 0x44, 0x00, 0x8c, 0x04
  21. };
  22. static LPCWSTR s_WRITERNAME = L"BeTest Writer";
  23. LPCWSTR GetStringFromRestoreType(_VSS_RESTORE_TYPE eRestoreType)
  24. {
  25. LPCWSTR pwszRetString = L"UNDEFINED";
  26. switch(eRestoreType)
  27. {
  28. case VSS_RTYPE_BY_COPY: pwszRetString = L"ByCopy"; break;
  29. case VSS_RTYPE_IMPORT: pwszRetString = L"Import"; break;
  30. case VSS_RTYPE_OTHER:pwszRetString = L"Other"; break;
  31. default:
  32. break;
  33. }
  34. return (pwszRetString);
  35. }
  36. void CTestVssWriter::Initialize()
  37. {
  38. HRESULT hr;
  39. CHECK_SUCCESS(CVssWriter::Initialize
  40. (
  41. s_WRITERID,
  42. s_WRITERNAME,
  43. VSS_UT_USERDATA,
  44. VSS_ST_OTHER
  45. ));
  46. }
  47. bool STDMETHODCALLTYPE CTestVssWriter::OnIdentify(IN IVssCreateWriterMetadata *pMetadata)
  48. {
  49. HRESULT hr;
  50. wprintf(L"\n\n***OnIdentify***\n");
  51. if(m_bTestNewInterfaces)
  52. return DoNewInterfacesTestIdentify(pMetadata);
  53. if (m_bRestoreTest)
  54. return DoRestoreTestIdentify(pMetadata);
  55. if (m_lWait & x_bitWaitIdentify)
  56. {
  57. wprintf(L"\nWaiting 30 seconds in OnIdentify.\n\n");
  58. Sleep(30000);
  59. }
  60. CHECK_SUCCESS(pMetadata->AddExcludeFiles
  61. (
  62. L"%systemroot%\\config",
  63. L"*.tmp",
  64. true
  65. ));
  66. CHECK_SUCCESS(pMetadata->AddComponent
  67. (
  68. VSS_CT_DATABASE,
  69. L"\\mydatabases",
  70. L"db1",
  71. L"this is my main database",
  72. x_rgbIcon,
  73. x_cbIcon,
  74. true,
  75. true,
  76. true
  77. ));
  78. CHECK_SUCCESS(pMetadata->AddDatabaseFiles
  79. (
  80. L"\\mydatabases",
  81. L"db1",
  82. L"e:\\databases",
  83. L"foo1.db"
  84. ));
  85. CHECK_SUCCESS(pMetadata->AddDatabaseFiles
  86. (
  87. L"\\mydatabases",
  88. L"db1",
  89. L"e:\\databases",
  90. L"foo2.db"
  91. ));
  92. CHECK_SUCCESS(pMetadata->AddDatabaseLogFiles
  93. (
  94. L"\\mydatabases",
  95. L"db1",
  96. L"e:\\logs",
  97. L"foo.log"
  98. ));
  99. CHECK_SUCCESS(pMetadata->SetRestoreMethod
  100. (
  101. VSS_RME_RESTORE_IF_NOT_THERE,
  102. NULL,
  103. NULL,
  104. VSS_WRE_ALWAYS,
  105. true
  106. ));
  107. CHECK_SUCCESS(pMetadata->AddAlternateLocationMapping
  108. (
  109. L"c:\\databases",
  110. L"*.db",
  111. false,
  112. L"e:\\databases\\restore"
  113. ));
  114. CHECK_SUCCESS(pMetadata->AddAlternateLocationMapping
  115. (
  116. L"d:\\logs",
  117. L"*.log",
  118. false,
  119. L"e:\\databases\\restore"
  120. ));
  121. return true;
  122. }
  123. bool DoPrepareBackupDatabase(IVssComponent* pComponent)
  124. {
  125. HRESULT hr;
  126. CComBSTR bstrLogicalPath;
  127. CComBSTR bstrComponentName;
  128. CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
  129. CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
  130. wprintf
  131. (
  132. L"Backing up database %s\\%s.\n",
  133. bstrLogicalPath,
  134. bstrComponentName
  135. );
  136. WCHAR buf[100];
  137. wsprintf (buf, L"backupTime = %d\n", (INT) time(NULL));
  138. CHECK_SUCCESS(pComponent->SetBackupMetadata(buf));
  139. wprintf(L"\nBackupMetadata=%s\n", buf);
  140. CComBSTR bstrPreviousStamp;
  141. CHECK_NOFAIL(pComponent->GetPreviousBackupStamp(&bstrPreviousStamp));
  142. if (bstrPreviousStamp)
  143. wprintf(L"Previous stamp = %s\n", bstrPreviousStamp);
  144. CComBSTR bstrBackupOptions;
  145. CHECK_NOFAIL(pComponent->GetBackupOptions(&bstrBackupOptions));
  146. if (bstrBackupOptions)
  147. wprintf(L"Backup options = %s\n", bstrBackupOptions);
  148. WCHAR wszBackupStamp[32];
  149. swprintf(wszBackupStamp, L"B-%d-", clock());
  150. CHECK_SUCCESS(pComponent->SetBackupStamp(wszBackupStamp));
  151. wprintf(L"Backup stamp = %s\n\n", wszBackupStamp);
  152. return true;
  153. }
  154. bool DoPrepareBackupFilegroup(IVssComponent* pComponent)
  155. {
  156. HRESULT hr;
  157. CComBSTR bstrLogicalPath;
  158. CComBSTR bstrComponentName;
  159. CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
  160. CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
  161. wprintf
  162. (
  163. L"Backing up filegroup %s\\%s.\n",
  164. bstrLogicalPath,
  165. bstrComponentName
  166. );
  167. return true;
  168. }
  169. bool STDMETHODCALLTYPE CTestVssWriter::OnPrepareBackup(IN IVssWriterComponents *pWriterComponents)
  170. {
  171. HRESULT hr;
  172. wprintf(L"\n\n***OnPrepareBackup***\n");
  173. if (m_bRestoreTest)
  174. return DoRestoreTestPrepareBackup(pWriterComponents);
  175. if (m_lWait & x_bitWaitPrepareForBackup)
  176. {
  177. wprintf(L"\nWaiting 10 seconds in PrepareForBackup.\n\n");
  178. Sleep(10000);
  179. }
  180. unsigned cComponents;
  181. LPCWSTR wszBackupType;
  182. switch(GetBackupType())
  183. {
  184. default:
  185. wszBackupType = L"undefined";
  186. break;
  187. case VSS_BT_FULL:
  188. wszBackupType = L"full";
  189. break;
  190. case VSS_BT_INCREMENTAL:
  191. wszBackupType = L"incremental";
  192. break;
  193. case VSS_BT_DIFFERENTIAL:
  194. wszBackupType = L"differential";
  195. break;
  196. case VSS_BT_LOG:
  197. wszBackupType = L"log";
  198. break;
  199. case VSS_BT_COPY:
  200. wszBackupType = L"copy";
  201. break;
  202. case VSS_BT_OTHER:
  203. wszBackupType = L"other";
  204. break;
  205. }
  206. wprintf(L"\n\n***OnPrepareBackup****\nBackup Type = %s\n", wszBackupType);
  207. wprintf
  208. (
  209. L"AreComponentsSelected = %s\n",
  210. AreComponentsSelected() ? L"yes" : L"no"
  211. );
  212. wprintf
  213. (
  214. L"BootableSystemStateBackup = %s\n\n",
  215. IsBootableSystemStateBackedUp() ? L"yes" : L"no"
  216. );
  217. CHECK_SUCCESS(pWriterComponents->GetComponentCount(&cComponents));
  218. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  219. {
  220. CComPtr<IVssComponent> pComponent;
  221. VSS_COMPONENT_TYPE ct;
  222. CHECK_SUCCESS(pWriterComponents->GetComponent(iComponent, &pComponent));
  223. CHECK_SUCCESS(pComponent->GetComponentType(&ct));
  224. wprintf(L"Current backup context is 0x%x\n", GetContext());
  225. if (ct == VSS_CT_DATABASE)
  226. DoPrepareBackupDatabase(pComponent);
  227. else
  228. DoPrepareBackupFilegroup(pComponent);
  229. }
  230. return true;
  231. }
  232. bool STDMETHODCALLTYPE CTestVssWriter::OnPrepareSnapshot()
  233. {
  234. wprintf(L"\n\n***OnPrepareSnapshot***\n");
  235. if (m_lWait & x_bitWaitPrepareSnapshot)
  236. {
  237. wprintf(L"\nWaiting 10 seconds in PrepareSnapshot.\n\n");
  238. Sleep(10000);
  239. }
  240. if (!m_bRestoreTest)
  241. IsPathAffected(L"e:\\foobar");
  242. wprintf(L"Current backup context is 0x%x\n", GetContext());
  243. return true;
  244. }
  245. bool STDMETHODCALLTYPE CTestVssWriter::OnFreeze()
  246. {
  247. wprintf(L"\n\n***OnFreeze***\n");
  248. if (m_lWait & x_bitWaitFreeze)
  249. {
  250. wprintf(L"\nWaiting 10 seconds in Freeze.\n\n");
  251. Sleep(10000);
  252. }
  253. wprintf(L"Current backup context is 0x%x\n", GetContext());
  254. return true;
  255. }
  256. bool STDMETHODCALLTYPE CTestVssWriter::OnThaw()
  257. {
  258. wprintf(L"\n\n***OnThaw***\n");
  259. if (m_lWait & x_bitWaitThaw)
  260. {
  261. wprintf(L"\nWaiting 10 seconds in PrepareThaw.\n\n");
  262. Sleep(10000);
  263. }
  264. wprintf(L"Current backup context is 0x%x\n", GetContext());
  265. return true;
  266. }
  267. bool STDMETHODCALLTYPE CTestVssWriter::OnBackupComplete(IN IVssWriterComponents *pWriterComponents)
  268. {
  269. HRESULT hr;
  270. wprintf(L"\n\n***OnBackupComplete***\n");
  271. wprintf(L"Current backup context is 0x%x\n", GetContext());
  272. if (m_bRestoreTest)
  273. return true;
  274. if (m_lWait & x_bitWaitBackupComplete)
  275. {
  276. wprintf(L"\nWaiting 30 seconds in BackupComplete.\n\n");
  277. Sleep(30000);
  278. }
  279. unsigned cComponents;
  280. CHECK_SUCCESS(pWriterComponents->GetComponentCount(&cComponents));
  281. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  282. {
  283. CComPtr<IVssComponent> pComponent;
  284. VSS_COMPONENT_TYPE ct;
  285. CComBSTR bstrLogicalPath;
  286. CComBSTR bstrComponentName;
  287. bool bBackupSucceeded;
  288. CHECK_SUCCESS(pWriterComponents->GetComponent(iComponent, &pComponent));
  289. CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
  290. CHECK_SUCCESS(pComponent->GetComponentType(&ct));
  291. CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
  292. CHECK_SUCCESS(pComponent->GetBackupSucceeded(&bBackupSucceeded));
  293. if (ct == VSS_CT_DATABASE)
  294. wprintf(L"Database ");
  295. else
  296. wprintf(L"FileGroup ");
  297. wprintf
  298. (
  299. L"%s\\%s backup %s.\n",
  300. bstrLogicalPath,
  301. bstrComponentName,
  302. bBackupSucceeded ? L"succeeded" : L"failed"
  303. );
  304. CComBSTR bstrMetadata;
  305. CHECK_NOFAIL(pComponent->GetBackupMetadata(&bstrMetadata));
  306. wprintf(L"backupMetadata=%s\n", bstrMetadata);
  307. }
  308. return true;
  309. }
  310. bool STDMETHODCALLTYPE CTestVssWriter::OnBackupShutdown(IN VSS_ID SnapshotSetId)
  311. {
  312. if (!m_bTestNewInterfaces)
  313. return true;
  314. wprintf(L"OnBackupShutdown called for snapshot-set id " WSTR_GUID_FMT L"\n",
  315. GUID_PRINTF_ARG(SnapshotSetId));
  316. return true;
  317. }
  318. bool STDMETHODCALLTYPE CTestVssWriter::OnPreRestore(IN IVssWriterComponents *pWriter)
  319. {
  320. if (m_bTestNewInterfaces)
  321. {
  322. VSS_RESTORE_TYPE type = GetRestoreType();
  323. wprintf(L"\nRestore type is %s\n", GetStringFromRestoreType(type));
  324. }
  325. wprintf(L"\n\n***OnPreRestore***\n");
  326. if (m_bRestoreTest)
  327. return DoRestoreTestPreRestore(pWriter);
  328. if (m_lWait & x_bitWaitPreRestore)
  329. {
  330. wprintf(L"\nWaiting 10 seconds in PreRestore.\n\n");
  331. Sleep(10000);
  332. }
  333. HRESULT hr;
  334. UINT cComponents;
  335. CHECK_SUCCESS(pWriter->GetComponentCount(&cComponents));
  336. for(UINT iComponent = 0; iComponent < cComponents; iComponent++)
  337. {
  338. CComPtr<IVssComponent> pComponent;
  339. CHECK_SUCCESS(pWriter->GetComponent(iComponent, &pComponent));
  340. PrintRestoreSubcomponents(pComponent);
  341. CComBSTR bstrBackupMetadata;
  342. CHECK_NOFAIL(pComponent->GetBackupMetadata(&bstrBackupMetadata));
  343. if (bstrBackupMetadata)
  344. wprintf(L"BackupMetadata=%s\n", bstrBackupMetadata);
  345. WCHAR buf[100];
  346. wsprintf (buf, L"restoreTime = %d", (INT) time(NULL));
  347. CHECK_SUCCESS(pComponent->SetRestoreMetadata(buf));
  348. wprintf(L"\nRestoreMetadata=%s\n", buf);
  349. CComBSTR bstrRestoreOptions;
  350. bool bAdditionalRestores;
  351. bool bSelectedForRestore;
  352. CHECK_SUCCESS(pComponent->GetAdditionalRestores(&bAdditionalRestores));
  353. CHECK_SUCCESS(pComponent->IsSelectedForRestore(&bSelectedForRestore));
  354. CHECK_NOFAIL(pComponent->GetRestoreOptions(&bstrRestoreOptions));
  355. wprintf(L"SelectedForRestore=%s\n", bSelectedForRestore ? L"Yes" : L"No");
  356. wprintf(L"Additional restores=%s\n", bAdditionalRestores ? L"Yes" : L"No");
  357. if (bstrRestoreOptions)
  358. wprintf(L"Restore options=%s\n", bstrRestoreOptions);
  359. ULONG type = clock() % 47;
  360. VSS_RESTORE_TARGET rt;
  361. if (type >= 15 && type < 30 && IsPartialFileSupportEnabled())
  362. rt = VSS_RT_DIRECTED;
  363. else if (type >= 30 && type < 40)
  364. rt = VSS_RT_ORIGINAL;
  365. else
  366. rt = VSS_RT_ALTERNATE;
  367. wprintf(L"restore target = %s\n", WszFromRestoreTarget(rt));
  368. CHECK_SUCCESS(pComponent->SetRestoreTarget(rt));
  369. if (rt == VSS_RT_DIRECTED)
  370. {
  371. CHECK_SUCCESS(pComponent->AddDirectedTarget
  372. (
  373. L"e:\\databases",
  374. L"foo1.db",
  375. L"0x8000:0x10000",
  376. L"e:\\newdatabases",
  377. L"copy1.db",
  378. L"0x0000:0x10000"
  379. ));
  380. CHECK_SUCCESS(pComponent->AddDirectedTarget
  381. (
  382. L"e:\\databases",
  383. L"foo2.db",
  384. L"0x4000:0x1000",
  385. L"e:\\newdatabases",
  386. L"copy1.db",
  387. L"0x0000:0x1000"
  388. ));
  389. PrintDirectedTargets(pComponent);
  390. if (m_bTestNewInterfaces)
  391. PrintNewTargets(pComponent);
  392. }
  393. wprintf(L"\n");
  394. CHECK_SUCCESS(pComponent->SetPreRestoreFailureMsg(L"PreRestore Successfully Completed."));
  395. }
  396. return true;
  397. }
  398. bool STDMETHODCALLTYPE CTestVssWriter::OnPostRestore(IN IVssWriterComponents *pWriter)
  399. {
  400. wprintf(L"\n\n***OnPostRestore***\n");
  401. if (m_bRestoreTest)
  402. return DoRestoreTestPostRestore(pWriter);
  403. if (m_lWait & x_bitWaitPostRestore)
  404. {
  405. wprintf(L"\nWaiting 10 seconds in PostRestore.\n\n");
  406. Sleep(10000);
  407. }
  408. HRESULT hr;
  409. UINT cComponents;
  410. CHECK_SUCCESS(pWriter->GetComponentCount(&cComponents));
  411. for(UINT iComponent = 0; iComponent < cComponents; iComponent++)
  412. {
  413. CComPtr<IVssComponent> pComponent;
  414. CHECK_SUCCESS(pWriter->GetComponent(iComponent, &pComponent));
  415. VSS_RESTORE_TARGET rt;
  416. CHECK_SUCCESS(pComponent->GetRestoreTarget(&rt));
  417. wprintf(L"RestoreTarget = %s\n", WszFromRestoreTarget(rt));
  418. if (rt == VSS_RT_DIRECTED)
  419. PrintDirectedTargets(pComponent);
  420. VSS_FILE_RESTORE_STATUS rs;
  421. CHECK_SUCCESS(pComponent->GetFileRestoreStatus(&rs));
  422. wprintf(L"RestoreStatus = %s\n", WszFromFileRestoreStatus(rs));
  423. CComBSTR bstrRestoreMetadata;
  424. CComBSTR bstrBackupMetadata;
  425. CHECK_NOFAIL(pComponent->GetRestoreMetadata(&bstrRestoreMetadata));
  426. CHECK_NOFAIL(pComponent->GetBackupMetadata(&bstrBackupMetadata));
  427. if (bstrRestoreMetadata)
  428. wprintf(L"RestoreMetadata=%s\n", bstrRestoreMetadata);
  429. if (bstrBackupMetadata)
  430. wprintf(L"BackupMetadata=%s\n", bstrBackupMetadata);
  431. wprintf(L"\n");
  432. CHECK_SUCCESS(pComponent->SetPostRestoreFailureMsg(L"PostRestore Successfully Completed."));
  433. }
  434. return true;
  435. }
  436. bool STDMETHODCALLTYPE CTestVssWriter::OnAbort()
  437. {
  438. wprintf(L"\n\n***OnAbort***\n\n");
  439. if (m_lWait & x_bitWaitAbort)
  440. {
  441. wprintf(L"\nWaiting 10 seconds in Abort.\n\n");
  442. Sleep(10000);
  443. }
  444. return true;
  445. }
  446. bool STDMETHODCALLTYPE CTestVssWriter::OnPostSnapshot
  447. (
  448. IN IVssWriterComponents *pWriter
  449. )
  450. {
  451. wprintf(L"\n\n***OnPostSnapshot***\n\n");
  452. if (m_bRestoreTest)
  453. return true;
  454. if (m_lWait & x_bitWaitPostSnapshot)
  455. {
  456. wprintf(L"\nWaiting 10 seconds in PostSnapshot.\n\n");
  457. Sleep(10000);
  458. }
  459. HRESULT hr;
  460. if (IsPartialFileSupportEnabled() &&
  461. GetBackupType() == VSS_BT_DIFFERENTIAL)
  462. {
  463. UINT cComponents;
  464. CHECK_SUCCESS(pWriter->GetComponentCount(&cComponents));
  465. for(UINT iComponent = 0; iComponent < cComponents; iComponent++)
  466. {
  467. CComPtr<IVssComponent> pComponent;
  468. CHECK_SUCCESS(pWriter->GetComponent(iComponent, &pComponent));
  469. VSS_COMPONENT_TYPE ct;
  470. CHECK_SUCCESS(pComponent->GetComponentType(&ct));
  471. if (ct == VSS_CT_DATABASE)
  472. {
  473. CHECK_SUCCESS(pComponent->AddPartialFile
  474. (
  475. L"e:\\databases",
  476. L"foo1.db",
  477. L"0x8000:0x10000, 0x100000:0x2000",
  478. L"Length=0x200000"
  479. ));
  480. CHECK_SUCCESS(pComponent->AddPartialFile
  481. (
  482. L"e:\\databases",
  483. L"foo2.db",
  484. L"0x4000:0x1000",
  485. L"Length=0x100000"
  486. ));
  487. }
  488. PrintPartialFiles(pComponent);
  489. if(m_bTestNewInterfaces)
  490. {
  491. ::Sleep(1000);
  492. FILETIME time;
  493. CHECK_SUCCESS(CoFileTimeNow(&time));
  494. // add bogus files as differenced files
  495. CHECK_SUCCESS(pComponent->AddDifferencedFilesByLastModifyTime
  496. (
  497. L"C:\\",
  498. L"Foo",
  499. false,
  500. time
  501. ));
  502. CHECK_SUCCESS(pComponent->AddDifferencedFilesByLastModifyLSN
  503. (
  504. L"C:\\",
  505. L"Bar",
  506. true,
  507. L"MYLSNFORMAT"
  508. ));
  509. if (GetSnapshotDeviceName(NULL, NULL) != E_NOTIMPL)
  510. Error(1, L"GetSnapshotDeviceName should return E_NOTIMPL");
  511. }
  512. }
  513. }
  514. return true;
  515. }
  516. void CTestVssWriter::CreateDirectoryName(LPWSTR buf)
  517. {
  518. UINT cwc = ExpandEnvironmentStrings(L"%SystemDrive%", buf, 1024);
  519. if (cwc == 0)
  520. {
  521. DWORD dwErr = GetLastError();
  522. Error(HRESULT_FROM_WIN32(dwErr), L"ExpandEnvironmentStrings failed with error %d.\n", dwErr);
  523. }
  524. wcscat(buf, L"\\BETESTWRITERFILES");
  525. }
  526. bool CTestVssWriter::DoRestoreTestIdentify(IVssCreateWriterMetadata *pMetadata)
  527. {
  528. HRESULT hr;
  529. WCHAR buf[1024];
  530. CreateDirectoryName(buf);
  531. CreateDirectory(buf, NULL);
  532. CHECK_SUCCESS(pMetadata->SetRestoreMethod
  533. (
  534. (m_lRestoreTestOptions & x_RestoreTestOptions_RestoreIfNotThere) ?
  535. VSS_RME_RESTORE_IF_NOT_THERE : VSS_RME_RESTORE_IF_CAN_REPLACE,
  536. NULL,
  537. NULL,
  538. VSS_WRE_ALWAYS,
  539. false
  540. ));
  541. DoAddComponent(pMetadata, L"a", buf, NULL, L"*.a", L"ALTA", true, true, 0);
  542. DoAddComponent(pMetadata, L"b", buf, L"b", L"*", L"ALTB", false, true, 0);
  543. DoAddComponent(pMetadata, L"c", buf, NULL, L"c.*", L"ALTC", true, true, 0);
  544. return true;
  545. }
  546. bool CTestVssWriter::DoNewInterfacesTestIdentify(IVssCreateWriterMetadata* pMetadata)
  547. {
  548. HRESULT hr;
  549. WCHAR buf[1024];
  550. CreateDirectoryName(buf);
  551. CreateDirectory(buf, NULL);
  552. CHECK_SUCCESS(pMetadata->SetRestoreMethod
  553. (
  554. VSS_RME_RESTORE_IF_NOT_THERE,
  555. NULL,
  556. NULL,
  557. VSS_WRE_ALWAYS,
  558. false
  559. ));
  560. CHECK_SUCCESS(pMetadata->SetBackupSchema
  561. (VSS_BS_DIFFERENTIAL | VSS_BS_INCREMENTAL | VSS_BS_LOG |
  562. VSS_BS_COPY | VSS_BS_TIMESTAMPED | VSS_BS_TIMESTAMPED |
  563. VSS_BS_LAST_MODIFY | VSS_BS_LSN | VSS_BS_WRITER_SUPPORTS_NEW_TARGET
  564. ));
  565. DoAddComponent(pMetadata, L"a", buf, NULL, L"*.a", L"ALTA", true, true, 0);
  566. DoAddComponent(pMetadata, L"b", buf, L"b", L"*", L"ALTB", false, true, 0);
  567. DoAddComponent(pMetadata, L"c", buf, NULL, L"c.*", L"ALTC", true, true, VSS_CF_BACKUP_RECOVERY);
  568. CHECK_SUCCESS(pMetadata->AddComponentDependency(NULL, L"a", s_WRITERID, NULL, L"b"));
  569. CHECK_SUCCESS(pMetadata->AddComponentDependency(NULL, L"c", s_WRITERID, NULL, L"a"));
  570. CHECK_SUCCESS(pMetadata->AddComponent
  571. (
  572. VSS_CT_DATABASE,
  573. NULL,
  574. L"db1",
  575. NULL,
  576. NULL,
  577. 0,
  578. true,
  579. true,
  580. true,
  581. true
  582. ));
  583. CHECK_SUCCESS(pMetadata->AddComponent
  584. (
  585. VSS_CT_FILEGROUP,
  586. NULL,
  587. L"db2",
  588. NULL,
  589. NULL,
  590. 0,
  591. true,
  592. true,
  593. true,
  594. true
  595. ));
  596. CHECK_SUCCESS(pMetadata->AddDatabaseFiles
  597. (
  598. NULL,
  599. L"db1",
  600. buf,
  601. L"*.db1",
  602. VSS_FSBT_FULL_BACKUP_REQUIRED
  603. ));
  604. CHECK_SUCCESS(pMetadata->AddDatabaseLogFiles
  605. (
  606. NULL,
  607. L"db1",
  608. buf,
  609. L"*.db2",
  610. VSS_FSBT_DIFFERENTIAL_BACKUP_REQUIRED
  611. ));
  612. CHECK_SUCCESS(pMetadata->AddFilesToFileGroup
  613. (
  614. NULL,
  615. L"db2",
  616. buf,
  617. L"*.db3",
  618. true,
  619. NULL,
  620. VSS_FSBT_INCREMENTAL_BACKUP_REQUIRED
  621. ));
  622. CHECK_SUCCESS(pMetadata->AddDatabaseFiles
  623. (
  624. NULL,
  625. L"db1",
  626. buf,
  627. L"*.db4",
  628. VSS_FSBT_LOG_BACKUP_REQUIRED
  629. ));
  630. CHECK_SUCCESS(pMetadata->AddDatabaseLogFiles
  631. (
  632. NULL,
  633. L"db1",
  634. buf,
  635. L"*.db5",
  636. VSS_FSBT_FULL_SNAPSHOT_REQUIRED
  637. ));
  638. CHECK_SUCCESS(pMetadata->AddFilesToFileGroup
  639. (
  640. NULL,
  641. L"db2",
  642. buf,
  643. L"*.db6",
  644. true,
  645. NULL,
  646. VSS_FSBT_DIFFERENTIAL_SNAPSHOT_REQUIRED
  647. ));
  648. CHECK_SUCCESS(pMetadata->AddDatabaseFiles
  649. (
  650. NULL,
  651. L"db1",
  652. buf,
  653. L"*.db7",
  654. VSS_FSBT_INCREMENTAL_SNAPSHOT_REQUIRED
  655. ));
  656. CHECK_SUCCESS(pMetadata->AddDatabaseLogFiles
  657. (
  658. NULL,
  659. L"db1",
  660. buf,
  661. L"*.db8",
  662. VSS_FSBT_LOG_SNAPSHOT_REQUIRED
  663. ));
  664. CHECK_SUCCESS(pMetadata->AddFilesToFileGroup
  665. (
  666. NULL,
  667. L"db2",
  668. buf,
  669. L"*.db9",
  670. true,
  671. NULL,
  672. VSS_FSBT_ALL_BACKUP_REQUIRED
  673. ));
  674. CHECK_SUCCESS(pMetadata->AddDatabaseFiles
  675. (
  676. NULL,
  677. L"db1",
  678. buf,
  679. L"*.db10",
  680. VSS_FSBT_ALL_SNAPSHOT_REQUIRED
  681. ));
  682. return true;
  683. }
  684. void CTestVssWriter::DoAddComponent
  685. (
  686. IVssCreateWriterMetadata *pMetadata,
  687. LPCWSTR wszComponentName,
  688. LPCWSTR wszRootDirectory,
  689. LPCWSTR wszSubdirectory,
  690. LPCWSTR wszFilespec,
  691. LPCWSTR wszAlternateDirectory,
  692. bool bSelectable,
  693. bool bSelectableForRestore,
  694. LONG lFlags
  695. )
  696. {
  697. HRESULT hr;
  698. CComBSTR bstrAlternate;
  699. bstrAlternate.Append(wszRootDirectory);
  700. bstrAlternate.Append(L"\\");
  701. bstrAlternate.Append(wszAlternateDirectory);
  702. CHECK_SUCCESS(pMetadata->AddComponent
  703. (
  704. VSS_CT_FILEGROUP,
  705. NULL,
  706. wszComponentName,
  707. NULL,
  708. NULL,
  709. 0,
  710. true,
  711. true,
  712. bSelectable,
  713. bSelectableForRestore,
  714. lFlags
  715. ));
  716. if (wszSubdirectory == NULL)
  717. {
  718. CHECK_SUCCESS(pMetadata->AddFilesToFileGroup
  719. (
  720. NULL,
  721. wszComponentName,
  722. wszRootDirectory,
  723. wszFilespec,
  724. false,
  725. NULL
  726. ));
  727. CHECK_SUCCESS(pMetadata->AddAlternateLocationMapping
  728. (
  729. wszRootDirectory,
  730. wszFilespec,
  731. false,
  732. bstrAlternate
  733. ));
  734. }
  735. else
  736. {
  737. CComBSTR bstr;
  738. bstr.Append(wszRootDirectory);
  739. bstr.Append(L"\\");
  740. bstr.Append(wszSubdirectory);
  741. CHECK_SUCCESS(pMetadata->AddFilesToFileGroup
  742. (
  743. NULL,
  744. wszComponentName,
  745. bstr,
  746. wszFilespec,
  747. true,
  748. NULL
  749. ));
  750. CHECK_SUCCESS(pMetadata->AddAlternateLocationMapping
  751. (
  752. bstr,
  753. wszFilespec,
  754. true,
  755. bstrAlternate
  756. ));
  757. }
  758. }
  759. bool CTestVssWriter::DoRestoreTestPrepareBackup(IVssWriterComponents *pWriterComponents)
  760. {
  761. WCHAR buf[1024];
  762. HRESULT hr;
  763. unsigned cComponents;
  764. CreateDirectoryName(buf);
  765. CHECK_SUCCESS(pWriterComponents->GetComponentCount(&cComponents));
  766. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  767. {
  768. CComPtr<IVssComponent> pComponent;
  769. VSS_COMPONENT_TYPE ct;
  770. CComBSTR bstrLogicalPath;
  771. CComBSTR bstrComponentName;
  772. CHECK_SUCCESS(pWriterComponents->GetComponent(iComponent, &pComponent));
  773. CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
  774. CHECK_SUCCESS(pComponent->GetComponentType(&ct));
  775. CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
  776. if (ct == VSS_CT_FILEGROUP && !bstrLogicalPath && wcslen(bstrComponentName) == 1)
  777. {
  778. if (bstrComponentName[0] == L'a')
  779. CreateComponentFilesA(buf, false);
  780. else if (bstrComponentName[0] == L'b')
  781. CreateComponentFilesB(buf, false);
  782. else if (bstrComponentName[0] == L'c')
  783. CreateComponentFilesC(buf, false);
  784. }
  785. }
  786. return true;
  787. }
  788. void CTestVssWriter::CreateComponentFilesA(LPCWSTR buf, bool bKeepOpen)
  789. {
  790. DoCreateFile(buf, L"foo.a", 100, bKeepOpen);
  791. DoCreateFile(buf, L"bar.a", 1000, bKeepOpen);
  792. DoCreateFile(buf, L"xxx.a", 10000, bKeepOpen);
  793. }
  794. void CTestVssWriter::VerifyComponentFilesA(LPCWSTR buf)
  795. {
  796. CComBSTR bstr;
  797. bstr.Append(buf);
  798. bstr.Append(L"\\ALTA");
  799. DoVerifyFile(bstr, L"foo.a", 100);
  800. DoVerifyFile(bstr, L"bar.a", 1000);
  801. DoVerifyFile(bstr, L"xxx.a", 10000);
  802. wprintf(L"Component a is verified.\n");
  803. }
  804. void CTestVssWriter::CreateComponentFilesB(LPCWSTR buf, bool bKeepOpen)
  805. {
  806. CComBSTR bstr;
  807. bstr.Append(buf);
  808. bstr.Append(L"\\b");
  809. CreateDirectory(bstr, NULL);
  810. DoCreateFile(bstr, L"a.a", 1000, bKeepOpen);
  811. DoCreateFile(bstr, L"b.b", 1000, bKeepOpen);
  812. bstr.Append(L"\\a");
  813. CreateDirectory(bstr, NULL);
  814. DoCreateFile(bstr, L"a.a", 10000, bKeepOpen);
  815. DoCreateFile(bstr, L"b.b", 10000, bKeepOpen);
  816. bstr.Append(L"\\b");
  817. CreateDirectory(bstr, NULL);
  818. DoCreateFile(bstr, L"a.a", 100000, bKeepOpen);
  819. DoCreateFile(bstr, L"b.b", 100000, bKeepOpen);
  820. bstr[wcslen(bstr) - 1] = L'c';
  821. CreateDirectory(bstr, NULL);
  822. DoCreateFile(bstr, L"a.a", 10, bKeepOpen);
  823. DoCreateFile(bstr, L"b.b", 10, bKeepOpen);
  824. }
  825. void CTestVssWriter::VerifyComponentFilesB(LPCWSTR buf)
  826. {
  827. CComBSTR bstr;
  828. bstr.Append(buf);
  829. bstr.Append(L"\\ALTB");
  830. DoVerifyFile(bstr, L"a.a", 1000);
  831. DoVerifyFile(bstr, L"b.b", 1000);
  832. bstr.Append(L"\\a");
  833. DoVerifyFile(bstr, L"a.a", 10000);
  834. DoVerifyFile(bstr, L"b.b", 10000);
  835. bstr.Append(L"\\b");
  836. CreateDirectory(bstr, NULL);
  837. DoVerifyFile(bstr, L"a.a", 100000);
  838. DoVerifyFile(bstr, L"b.b", 100000);
  839. bstr[wcslen(bstr) - 1] = L'c';
  840. DoVerifyFile(bstr, L"a.a", 10);
  841. DoVerifyFile(bstr, L"b.b", 10);
  842. wprintf(L"Component b is verified.\n");
  843. }
  844. void CTestVssWriter::CreateComponentFilesC(LPCWSTR buf, bool bKeepOpen)
  845. {
  846. DoCreateFile(buf, L"c.x1", 100, bKeepOpen);
  847. DoCreateFile(buf, L"c.x2", 1000, bKeepOpen);
  848. DoCreateFile(buf, L"c.x3", 10000, bKeepOpen);
  849. }
  850. void CTestVssWriter::VerifyComponentFilesC(LPCWSTR buf)
  851. {
  852. CComBSTR bstr;
  853. bstr.Append(buf);
  854. bstr.Append(L"\\ALTC");
  855. DoVerifyFile(bstr, L"c.x1", 100);
  856. DoVerifyFile(bstr, L"c.x2", 1000);
  857. DoVerifyFile(bstr, L"c.x3", 10000);
  858. wprintf(L"Component c is verified.\n");
  859. }
  860. void CTestVssWriter::DoCreateFile
  861. (
  862. LPCWSTR wszPath,
  863. LPCWSTR wszFilename,
  864. DWORD length,
  865. bool bKeepOpen
  866. )
  867. {
  868. CComBSTR bstr;
  869. bstr.Append(wszPath);
  870. bstr.Append(L"\\");
  871. bstr.Append(wszFilename);
  872. if (bKeepOpen && m_chOpen == m_chOpenMax)
  873. {
  874. HANDLE *rghNew = new HANDLE[m_chOpen + 4];
  875. memcpy(rghNew, m_rghOpen, m_chOpen * sizeof(HANDLE));
  876. delete m_rghOpen;
  877. m_rghOpen = rghNew;
  878. m_chOpenMax = m_chOpen + 4;
  879. }
  880. BYTE *buf = new BYTE[length];
  881. if (buf == NULL)
  882. Error(E_OUTOFMEMORY, L"Out of memory.\n");
  883. UINT seed = length + wszFilename[0];
  884. for(UINT i = 0; i < length; i++, seed++)
  885. buf[i] = (BYTE) (seed & 0xff);
  886. HANDLE hFile = CreateFile
  887. (
  888. bstr,
  889. GENERIC_READ|GENERIC_WRITE,
  890. FILE_SHARE_READ,
  891. NULL,
  892. CREATE_ALWAYS,
  893. 0,
  894. NULL
  895. );
  896. if (hFile == INVALID_HANDLE_VALUE)
  897. {
  898. DWORD dwErr = GetLastError();
  899. delete buf;
  900. Error(HRESULT_FROM_WIN32(dwErr), L"CreateFile failed due to error %d.\n", dwErr);
  901. }
  902. DWORD dwWritten;
  903. if (!WriteFile(hFile, buf, length, &dwWritten, NULL) ||
  904. dwWritten != length)
  905. {
  906. DWORD dwErr = GetLastError();
  907. delete buf;
  908. CloseHandle(hFile);
  909. Error(HRESULT_FROM_WIN32(dwErr), L"Write file failed due to error %d.\n", dwErr);
  910. }
  911. delete buf;
  912. if (bKeepOpen)
  913. m_rghOpen[m_chOpen++] = hFile;
  914. else
  915. CloseHandle(hFile);
  916. }
  917. void CTestVssWriter::DoVerifyFile
  918. (
  919. LPCWSTR wszPath,
  920. LPCWSTR wszFilename,
  921. DWORD length
  922. )
  923. {
  924. CComBSTR bstr;
  925. bstr.Append(wszPath);
  926. bstr.Append(L"\\");
  927. bstr.Append(wszFilename);
  928. HANDLE hFile = CreateFile
  929. (
  930. bstr,
  931. GENERIC_READ|GENERIC_WRITE,
  932. FILE_SHARE_READ,
  933. NULL,
  934. OPEN_EXISTING,
  935. 0,
  936. NULL
  937. );
  938. if (hFile == INVALID_HANDLE_VALUE)
  939. {
  940. DWORD dwErr = GetLastError();
  941. if (dwErr == ERROR_FILE_NOT_FOUND ||
  942. dwErr == ERROR_PATH_NOT_FOUND)
  943. Error(E_UNEXPECTED, L"%s was not restored.\n", bstr);
  944. }
  945. DWORD dwSize = GetFileSize(hFile, NULL);
  946. if (dwSize == 0xffffffff)
  947. {
  948. DWORD dwErr = GetLastError();
  949. CloseHandle(hFile);
  950. Error(HRESULT_FROM_WIN32(dwErr), L"GetFileSize failed due to error %d.\n", dwErr);
  951. }
  952. if (dwSize != length)
  953. {
  954. CloseHandle(hFile);
  955. Error(E_UNEXPECTED, L"Failed to restore file %s correctly.\n", bstr);
  956. }
  957. BYTE *buf = new BYTE[length];
  958. if (buf == NULL)
  959. {
  960. CloseHandle(hFile);
  961. Error(E_OUTOFMEMORY, L"Out of memory.\n");
  962. }
  963. DWORD dwRead;
  964. if (!ReadFile(hFile, buf, length, &dwRead, NULL))
  965. {
  966. DWORD dwErr = GetLastError();
  967. delete buf;
  968. CloseHandle(hFile);
  969. Error(HRESULT_FROM_WIN32(dwErr), L"Write file failed due to error %d.\n", dwErr);
  970. }
  971. CloseHandle(hFile);
  972. UINT seed = length + wszFilename[0];
  973. for(UINT i = 0; i < length; i++, seed++)
  974. {
  975. if (buf[i] != (BYTE) (seed & 0xff))
  976. {
  977. delete buf;
  978. Error(E_UNEXPECTED, L"Failed to restore file %s correctly.\n", bstr);
  979. }
  980. }
  981. delete buf;
  982. }
  983. bool CTestVssWriter::DoRestoreTestPreRestore(IVssWriterComponents *pWriterComponents)
  984. {
  985. WCHAR buf[1024];
  986. HRESULT hr;
  987. unsigned cComponents;
  988. bool bKeepOpen = (m_lRestoreTestOptions & x_RestoreTestOptions_RestoreIfNotThere) ? false : true;
  989. CreateDirectoryName(buf);
  990. CHECK_SUCCESS(pWriterComponents->GetComponentCount(&cComponents));
  991. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  992. {
  993. CComPtr<IVssComponent> pComponent;
  994. VSS_COMPONENT_TYPE ct;
  995. CComBSTR bstrLogicalPath;
  996. CComBSTR bstrComponentName;
  997. bool bRestore;
  998. CHECK_SUCCESS(pWriterComponents->GetComponent(iComponent, &pComponent));
  999. CHECK_SUCCESS(pComponent->IsSelectedForRestore(&bRestore));
  1000. if (!bRestore)
  1001. continue;
  1002. CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
  1003. CHECK_SUCCESS(pComponent->GetComponentType(&ct));
  1004. CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
  1005. if (ct == VSS_CT_FILEGROUP && !bstrLogicalPath && wcslen(bstrComponentName) == 1)
  1006. {
  1007. if (bstrComponentName[0] == L'a')
  1008. CreateComponentFilesA(buf, bKeepOpen);
  1009. else if (bstrComponentName[0] == L'b')
  1010. CreateComponentFilesB(buf, bKeepOpen);
  1011. else if (bstrComponentName[0] == L'c')
  1012. CreateComponentFilesC(buf, bKeepOpen);
  1013. }
  1014. if (m_bTestNewInterfaces)
  1015. PrintNewTargets(pComponent);
  1016. }
  1017. return true;
  1018. }
  1019. bool CTestVssWriter::DoRestoreTestPostRestore(IVssWriterComponents *pWriterComponents)
  1020. {
  1021. WCHAR buf[1024];
  1022. HRESULT hr;
  1023. unsigned cComponents;
  1024. CreateDirectoryName(buf);
  1025. CHECK_SUCCESS(pWriterComponents->GetComponentCount(&cComponents));
  1026. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  1027. {
  1028. CComPtr<IVssComponent> pComponent;
  1029. VSS_COMPONENT_TYPE ct;
  1030. CComBSTR bstrLogicalPath;
  1031. CComBSTR bstrComponentName;
  1032. bool bRestore;
  1033. CHECK_SUCCESS(pWriterComponents->GetComponent(iComponent, &pComponent));
  1034. CHECK_SUCCESS(pComponent->IsSelectedForRestore(&bRestore));
  1035. if (!bRestore)
  1036. continue;
  1037. CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
  1038. CHECK_SUCCESS(pComponent->GetComponentType(&ct));
  1039. CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
  1040. if (ct == VSS_CT_FILEGROUP && !bstrLogicalPath && wcslen(bstrComponentName) == 1)
  1041. {
  1042. if (bstrComponentName[0] == L'a')
  1043. VerifyComponentFilesA(buf);
  1044. else if (bstrComponentName[0] == L'b')
  1045. VerifyComponentFilesB(buf);
  1046. else if (bstrComponentName[0] == L'c')
  1047. VerifyComponentFilesC(buf);
  1048. }
  1049. }
  1050. for(UINT ih = 0; ih < m_chOpen; ih++)
  1051. CloseHandle(m_rghOpen[ih]);
  1052. delete m_rghOpen;
  1053. m_chOpen = 0;
  1054. m_chOpenMax = 0;
  1055. m_rghOpen = NULL;
  1056. return true;
  1057. }