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.

920 lines
27 KiB

  1. #include "stdafx.hxx"
  2. #include "vs_idl.hxx"
  3. #include "vswriter.h"
  4. #include "vsbackup.h"
  5. #include <debug.h>
  6. #include <cwriter.h>
  7. #include <lmshare.h>
  8. #include <lmaccess.h>
  9. #include <time.h>
  10. BOOL AssertPrivilege( LPCWSTR privName )
  11. {
  12. HANDLE tokenHandle;
  13. BOOL stat = FALSE;
  14. if ( OpenProcessToken (GetCurrentProcess(),
  15. TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
  16. &tokenHandle))
  17. {
  18. LUID value;
  19. if ( LookupPrivilegeValue( NULL, privName, &value ) )
  20. {
  21. TOKEN_PRIVILEGES newState;
  22. DWORD error;
  23. newState.PrivilegeCount = 1;
  24. newState.Privileges[0].Luid = value;
  25. newState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
  26. /*
  27. * We will always call GetLastError below, so clear
  28. * any prior error values on this thread.
  29. */
  30. SetLastError( ERROR_SUCCESS );
  31. stat = AdjustTokenPrivileges (tokenHandle,
  32. FALSE,
  33. &newState,
  34. (DWORD)0,
  35. NULL,
  36. NULL );
  37. /*
  38. * Supposedly, AdjustTokenPriveleges always returns TRUE
  39. * (even when it fails). So, call GetLastError to be
  40. * extra sure everything's cool.
  41. */
  42. if ( (error = GetLastError()) != ERROR_SUCCESS )
  43. {
  44. stat = FALSE;
  45. }
  46. if ( !stat )
  47. {
  48. wprintf( L"AdjustTokenPrivileges for %s failed with %d",
  49. privName,
  50. error );
  51. }
  52. }
  53. DWORD cbTokens;
  54. GetTokenInformation (tokenHandle,
  55. TokenPrivileges,
  56. NULL,
  57. 0,
  58. &cbTokens);
  59. TOKEN_PRIVILEGES *pTokens = (TOKEN_PRIVILEGES *) new BYTE[cbTokens];
  60. GetTokenInformation (tokenHandle,
  61. TokenPrivileges,
  62. pTokens,
  63. cbTokens,
  64. &cbTokens);
  65. delete pTokens;
  66. CloseHandle( tokenHandle );
  67. }
  68. return stat;
  69. }
  70. LPCWSTR GetStringFromUsageType (VSS_USAGE_TYPE eUsageType)
  71. {
  72. LPCWSTR pwszRetString = L"UNDEFINED";
  73. switch (eUsageType)
  74. {
  75. case VSS_UT_BOOTABLESYSTEMSTATE: pwszRetString = L"BootableSystemState"; break;
  76. case VSS_UT_SYSTEMSERVICE: pwszRetString = L"SystemService"; break;
  77. case VSS_UT_USERDATA: pwszRetString = L"UserData"; break;
  78. case VSS_UT_OTHER: pwszRetString = L"Other"; break;
  79. default:
  80. break;
  81. }
  82. return (pwszRetString);
  83. }
  84. LPCWSTR GetStringFromSourceType (VSS_SOURCE_TYPE eSourceType)
  85. {
  86. LPCWSTR pwszRetString = L"UNDEFINED";
  87. switch (eSourceType)
  88. {
  89. case VSS_ST_TRANSACTEDDB: pwszRetString = L"TransactionDb"; break;
  90. case VSS_ST_NONTRANSACTEDDB: pwszRetString = L"NonTransactionDb"; break;
  91. case VSS_ST_OTHER: pwszRetString = L"Other"; break;
  92. default:
  93. break;
  94. }
  95. return (pwszRetString);
  96. }
  97. LPCWSTR GetStringFromRestoreMethod (VSS_RESTOREMETHOD_ENUM eRestoreMethod)
  98. {
  99. LPCWSTR pwszRetString = L"UNDEFINED";
  100. switch (eRestoreMethod)
  101. {
  102. case VSS_RME_RESTORE_IF_NOT_THERE: pwszRetString = L"RestoreIfNotThere"; break;
  103. case VSS_RME_RESTORE_IF_CAN_REPLACE: pwszRetString = L"RestoreIfCanReplace"; break;
  104. case VSS_RME_STOP_RESTORE_START: pwszRetString = L"StopRestoreStart"; break;
  105. case VSS_RME_RESTORE_TO_ALTERNATE_LOCATION: pwszRetString = L"RestoreToAlternateLocation"; break;
  106. case VSS_RME_RESTORE_AT_REBOOT: pwszRetString = L"RestoreAtReboot"; break;
  107. case VSS_RME_CUSTOM: pwszRetString = L"Custom"; break;
  108. default:
  109. break;
  110. }
  111. return (pwszRetString);
  112. }
  113. LPCWSTR GetStringFromWriterRestoreMethod (VSS_WRITERRESTORE_ENUM eWriterRestoreMethod)
  114. {
  115. LPCWSTR pwszRetString = L"UNDEFINED";
  116. switch (eWriterRestoreMethod)
  117. {
  118. case VSS_WRE_NEVER: pwszRetString = L"RestoreNever"; break;
  119. case VSS_WRE_IF_REPLACE_FAILS: pwszRetString = L"RestoreIfReplaceFailsI"; break;
  120. case VSS_WRE_ALWAYS: pwszRetString = L"RestoreAlways"; break;
  121. default:
  122. break;
  123. }
  124. return (pwszRetString);
  125. }
  126. LPCWSTR GetStringFromComponentType (VSS_COMPONENT_TYPE eComponentType)
  127. {
  128. LPCWSTR pwszRetString = L"UNDEFINED";
  129. switch (eComponentType)
  130. {
  131. case VSS_CT_DATABASE: pwszRetString = L"Database"; break;
  132. case VSS_CT_FILEGROUP: pwszRetString = L"FileGroup"; break;
  133. default:
  134. break;
  135. }
  136. return (pwszRetString);
  137. }
  138. void PrintFiledesc(IVssWMFiledesc *pFiledesc, LPCWSTR wszDescription)
  139. {
  140. CComBSTR bstrPath;
  141. CComBSTR bstrFilespec;
  142. CComBSTR bstrAlternate;
  143. CComBSTR bstrDestination;
  144. bool bRecursive;
  145. HRESULT hr;
  146. CHECK_SUCCESS(pFiledesc->GetPath(&bstrPath));
  147. CHECK_SUCCESS(pFiledesc->GetFilespec(&bstrFilespec));
  148. CHECK_NOFAIL(pFiledesc->GetRecursive(&bRecursive));
  149. CHECK_NOFAIL(pFiledesc->GetAlternateLocation(&bstrAlternate));
  150. CHECK_NOFAIL(pFiledesc->GetAlternateLocation(&bstrDestination));
  151. wprintf (L"%s\n Path = %s, Filespec = %s, Recursive = %s\n",
  152. wszDescription,
  153. bstrPath,
  154. bstrFilespec,
  155. bRecursive ? L"yes" : L"no");
  156. if (bstrAlternate && wcslen(bstrAlternate) > 0)
  157. wprintf(L" Alternate Location = %s\n", bstrAlternate);
  158. if (bstrDestination && wcslen(bstrDestination) > 0)
  159. wprintf(L" Destination Location = %s\n", bstrDestination);
  160. }
  161. /*
  162. void AddShares(IVssSnapshot **rgpSnapshot, UINT cSnapshot)
  163. {
  164. VSS_PWSZ wszDeviceName = NULL;
  165. try
  166. {
  167. for(UINT iSnapshot = 0; iSnapshot < cSnapshot; iSnapshot++)
  168. {
  169. SHARE_INFO_502 info;
  170. CHECK_SUCCESS(rgpSnapshot[iSnapshot]->GetDevice(&wszDeviceName));
  171. WCHAR *wszPath = new WCHAR[wcslen(wszDeviceName) + 2];
  172. if (wszPath != NULL)
  173. {
  174. wcscpy(wszPath, wszDeviceName);
  175. wcscat(wszPath, L"\\");
  176. memset(&info, 0, sizeof(info));
  177. WCHAR wszName[20];
  178. swprintf(wszName, L"Snapshot%d", iSnapshot);
  179. info.shi502_netname = wszName;
  180. info.shi502_type = STYPE_DISKTREE;
  181. info.shi502_permissions = ACCESS_READ;
  182. info.shi502_max_uses = 10;
  183. info.shi502_path = wszDeviceName;
  184. NET_API_STATUS status;
  185. DWORD parm_err;
  186. status = NetShareAdd(NULL, 502, (LPBYTE) &info, &parm_err);
  187. }
  188. CoTaskMemFree(wszDeviceName);
  189. wszDeviceName = NULL;
  190. }
  191. }
  192. catch(...)
  193. {
  194. }
  195. if (wszDeviceName)
  196. CoTaskMemFree(wszDeviceName);
  197. }
  198. */
  199. void DoAddToSnapshotSet
  200. (
  201. IN IVssBackupComponents *pvbc,
  202. IN BSTR bstrPath,
  203. IN LPWSTR wszVolumes,
  204. OUT VSS_ID * rgpSnapshotId,
  205. UINT *pcSnapshot
  206. )
  207. {
  208. PWCHAR pwszPath = NULL;
  209. PWCHAR pwszMountPointName = NULL;
  210. WCHAR wszVolumeName [50];
  211. ULONG ulPathLength;
  212. ULONG ulMountpointBufferLength;
  213. HRESULT hr;
  214. ulPathLength = ExpandEnvironmentStringsW (bstrPath, NULL, 0);
  215. pwszPath = (PWCHAR) malloc (ulPathLength * sizeof (WCHAR));
  216. ulPathLength = ExpandEnvironmentStringsW (bstrPath, pwszPath, ulPathLength);
  217. ulMountpointBufferLength = GetFullPathName (pwszPath, 0, NULL, NULL);
  218. pwszMountPointName = (PWCHAR) malloc (ulMountpointBufferLength * sizeof (WCHAR));
  219. bool fSuccess = false;
  220. if (wcslen(pwszPath) >= 3 && pwszPath[1] == L':' && pwszPath[2] == L'\\')
  221. {
  222. wcsncpy(pwszMountPointName, pwszPath, 3);
  223. pwszMountPointName[3] = L'\0';
  224. fSuccess = true;
  225. }
  226. else
  227. {
  228. if (GetVolumePathNameW (pwszPath, pwszMountPointName, ulMountpointBufferLength))
  229. fSuccess = true;
  230. else
  231. printf("GetVolumeMountPointW failed with error %d\npath=%s\n", GetLastError(), pwszPath);
  232. }
  233. if (fSuccess)
  234. {
  235. if (!GetVolumeNameForVolumeMountPointW (pwszMountPointName, wszVolumeName, sizeof (wszVolumeName) / sizeof (WCHAR)))
  236. printf("GetVolumeNameForVolumeMountPointW failed with error %d", GetLastError());
  237. else
  238. {
  239. if (NULL == wcsstr (wszVolumes, wszVolumeName))
  240. {
  241. if (L'\0' != wszVolumes [0])
  242. wcscat (wszVolumes, L";");
  243. wcscat (wszVolumes, wszVolumeName);
  244. CHECK_SUCCESS
  245. (
  246. pvbc->AddToSnapshotSet
  247. (
  248. wszVolumeName,
  249. GUID_NULL,
  250. &rgpSnapshotId[*pcSnapshot]
  251. )
  252. );
  253. *pcSnapshot += 1;
  254. }
  255. }
  256. }
  257. if (NULL != pwszPath) free (pwszPath);
  258. if (NULL != pwszMountPointName) free (pwszMountPointName);
  259. }
  260. static LPCWSTR s_rgwszStates[] =
  261. {
  262. NULL,
  263. L"STABLE",
  264. L"WAIT_FOR_FREEZE",
  265. L"WAIT_FOR_THAW",
  266. L"WAIT_FOR_POST_SNAPSHOT",
  267. L"WAIT_FOR_BACKUP_COMPLETE",
  268. L"FAILED_AT_IDENTIFY",
  269. L"FAILED_AT_PREPARE_BACKUP",
  270. L"FAILED_AT_PREPARE_SNAPSHOT",
  271. L"FAILED_AT_FREEZE",
  272. L"FAILED_AT_THAW",
  273. L"FAILED_AT_BACKUP_COMPLETE",
  274. L"FAILED_AT_PRE_RESTORE",
  275. L"FAILED_AT_POST_RESTORE"
  276. };
  277. void CheckStatus(IVssBackupComponents *pvbc, LPCWSTR wszWhen)
  278. {
  279. unsigned cWriters;
  280. CComPtr<IVssAsync> pAsync;
  281. HRESULT hr;
  282. HRESULT hrResult;
  283. CHECK_NOFAIL(pvbc->GatherWriterStatus(&pAsync));
  284. CHECK_NOFAIL(pAsync->Wait());
  285. CHECK_SUCCESS(pAsync->QueryStatus(&hrResult, NULL));
  286. CHECK_NOFAIL(hrResult);
  287. CHECK_NOFAIL(pvbc->GetWriterStatusCount(&cWriters));
  288. wprintf(L"\n\nstatus %s (%d writers)\n\n", wszWhen, cWriters);
  289. for(unsigned iWriter = 0; iWriter < cWriters; iWriter++)
  290. {
  291. VSS_ID idInstance;
  292. VSS_ID idWriter;
  293. VSS_WRITER_STATE status;
  294. CComBSTR bstrWriter;
  295. HRESULT hrWriterFailure;
  296. CHECK_SUCCESS(pvbc->GetWriterStatus (iWriter,
  297. &idInstance,
  298. &idWriter,
  299. &bstrWriter,
  300. &status,
  301. &hrWriterFailure));
  302. wprintf (L"Status for writer %s: %s(0x%08lx%s%s)\n",
  303. bstrWriter,
  304. s_rgwszStates[status],
  305. hrWriterFailure,
  306. SUCCEEDED (hrWriterFailure) ? L"" : L" - ",
  307. GetStringFromFailureType (hrWriterFailure));
  308. }
  309. pvbc->FreeWriterStatus();
  310. }
  311. // wait a maximum number of seconds before cancelling the operation
  312. void LoopWait
  313. (
  314. IVssAsync *pAsync,
  315. LONG seconds,
  316. LPCWSTR wszOperation
  317. )
  318. {
  319. clock_t start = clock();
  320. HRESULT hr, hrStatus;
  321. while(TRUE)
  322. {
  323. Sleep(1000);
  324. CHECK_SUCCESS(pAsync->QueryStatus(&hrStatus, NULL));
  325. if (hrStatus != VSS_S_ASYNC_PENDING)
  326. break;
  327. if (((clock() - start)/CLOCKS_PER_SEC) >= seconds)
  328. break;
  329. }
  330. if (hrStatus == VSS_S_ASYNC_PENDING)
  331. {
  332. CHECK_NOFAIL(pAsync->Cancel());
  333. wprintf(L"Called cancelled for %s.\n", wszOperation);
  334. }
  335. CHECK_SUCCESS(pAsync->QueryStatus(&hrStatus, NULL));
  336. CHECK_NOFAIL(hrStatus);
  337. }
  338. extern "C" __cdecl wmain(int argc, WCHAR **argv)
  339. {
  340. WCHAR wszVolumes[2048];
  341. wszVolumes[0] = L'\0';
  342. UINT cSnapshot = 0;
  343. VSS_ID rgpSnapshotId[64];
  344. CTestVssWriter *pInstance = NULL;
  345. bool bCreated = false;
  346. bool bSubscribed = false;
  347. HRESULT hr = S_OK;
  348. bool bCoInitializeSucceeded = false;
  349. try
  350. {
  351. HRESULT hr;
  352. CComBSTR bstrXML;
  353. CComBSTR bstrXMLOut;
  354. LONG lWait = 0;
  355. if (argc == 2 &&
  356. wcslen(argv[1]) == 3 &&
  357. argv[1][0] == L'-' &&
  358. argv[1][1] == L'w' &&
  359. (argv[1][2] >= L'0' && argv[1][2] <= L'9'||
  360. argv[1][2] >= L'a' && argv[1][2] <= L'f'))
  361. {
  362. if (argv[1][2] >= L'0' && argv[1][2] <= L'9')
  363. lWait = argv[1][2] - L'0';
  364. else
  365. lWait = argv[1][2] - L'a' + 10;
  366. wprintf(L"wait parameter=%d.\n", lWait);
  367. }
  368. CHECK_SUCCESS(CoInitializeEx(NULL, COINIT_MULTITHREADED));
  369. CComPtr<IGlobalOptions> ptrIGLB;
  370. CHECK_SUCCESS( ptrIGLB.CoCreateInstance(CLSID_GlobalOptions) );
  371. CHECK_SUCCESS( ptrIGLB->Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE));
  372. // Initialize COM security
  373. CHECK_SUCCESS
  374. (
  375. CoInitializeSecurity
  376. (
  377. NULL, // IN PSECURITY_DESCRIPTOR pSecDesc,
  378. -1, // IN LONG cAuthSvc,
  379. NULL, // IN SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
  380. NULL, // IN void *pReserved1,
  381. RPC_C_AUTHN_LEVEL_CONNECT, // IN DWORD dwAuthnLevel,
  382. RPC_C_IMP_LEVEL_IMPERSONATE, // IN DWORD dwImpLevel,
  383. NULL, // IN void *pAuthList,
  384. EOAC_NONE, // IN DWORD dwCapabilities,
  385. NULL // IN void *pReserved3
  386. )
  387. );
  388. bCoInitializeSucceeded = true;
  389. if ( !AssertPrivilege( SE_BACKUP_NAME ) )
  390. {
  391. wprintf( L"AssertPrivilege returned error, rc:%d\n", GetLastError() );
  392. return 2;
  393. }
  394. pInstance = new CTestVssWriter(lWait);
  395. if (pInstance == NULL)
  396. {
  397. wprintf(L"allocation failure\n");
  398. DebugBreak();
  399. }
  400. bCreated = true;
  401. pInstance->Initialize();
  402. CHECK_SUCCESS(pInstance->Subscribe());
  403. bSubscribed = true;
  404. CComBSTR strSnapshotSetId = "12345678-1234-1234-1234-1234567890ab";
  405. CComPtr<IVssBackupComponents> pvbc;
  406. CHECK_SUCCESS(CreateVssBackupComponents(&pvbc));
  407. CHECK_SUCCESS(pvbc->InitializeForBackup());
  408. CHECK_SUCCESS(pvbc->SetBackupState (true,
  409. false,
  410. VSS_BT_FULL));
  411. unsigned cWriters;
  412. CComPtr<IVssAsync> pAsync;
  413. CHECK_NOFAIL(pvbc->GatherWriterMetadata(&pAsync));
  414. LoopWait(pAsync, 15, L"GatherWriterMetadata");
  415. CHECK_NOFAIL(pvbc->GetWriterMetadataCount(&cWriters));
  416. VSS_ID id;
  417. while(TRUE)
  418. {
  419. hr = pvbc->StartSnapshotSet(&id);
  420. if (hr == S_OK)
  421. break;
  422. if (hr == VSS_E_SNAPSHOT_SET_IN_PROGRESS)
  423. Sleep(1000);
  424. else
  425. CHECK_SUCCESS(hr);
  426. }
  427. for(unsigned iWriter = 0; iWriter < cWriters; iWriter++)
  428. {
  429. CComPtr<IVssExamineWriterMetadata> pMetadata;
  430. VSS_ID idInstance;
  431. CHECK_SUCCESS(pvbc->GetWriterMetadata(iWriter, &idInstance, &pMetadata));
  432. VSS_ID idInstanceT;
  433. VSS_ID idWriter;
  434. CComBSTR bstrWriterName;
  435. VSS_USAGE_TYPE usage;
  436. VSS_SOURCE_TYPE source;
  437. CHECK_SUCCESS(pMetadata->GetIdentity (&idInstanceT,
  438. &idWriter,
  439. &bstrWriterName,
  440. &usage,
  441. &source));
  442. wprintf (L"\n\n");
  443. if (memcmp(&idInstance, &idInstanceT, sizeof(VSS_ID)) != 0)
  444. {
  445. wprintf(L"Instance id mismatch\n");
  446. DebugBreak();
  447. }
  448. WCHAR *pwszInstanceId;
  449. WCHAR *pwszWriterId;
  450. UuidToString(&idInstance, &pwszInstanceId);
  451. UuidToString(&idWriter, &pwszWriterId);
  452. wprintf (L"WriterName = %s\n\n"
  453. L" WriterId = %s\n"
  454. L" InstanceId = %s\n"
  455. L" UsageType = %d (%s)\n"
  456. L" SourceType = %d (%s)\n",
  457. bstrWriterName,
  458. pwszWriterId,
  459. pwszInstanceId,
  460. usage,
  461. GetStringFromUsageType (usage),
  462. source,
  463. GetStringFromSourceType (source));
  464. RpcStringFree(&pwszInstanceId);
  465. RpcStringFree(&pwszWriterId);
  466. unsigned cIncludeFiles, cExcludeFiles, cComponents;
  467. CHECK_SUCCESS(pMetadata->GetFileCounts (&cIncludeFiles,
  468. &cExcludeFiles,
  469. &cComponents));
  470. CComBSTR bstrPath;
  471. CComBSTR bstrFilespec;
  472. CComBSTR bstrAlternate;
  473. CComBSTR bstrDestination;
  474. for(unsigned i = 0; i < cIncludeFiles; i++)
  475. {
  476. CComPtr<IVssWMFiledesc> pFiledesc;
  477. CHECK_SUCCESS(pMetadata->GetIncludeFile(i, &pFiledesc));
  478. PrintFiledesc(pFiledesc, L"\n Include File");
  479. }
  480. for(i = 0; i < cExcludeFiles; i++)
  481. {
  482. CComPtr<IVssWMFiledesc> pFiledesc;
  483. CHECK_SUCCESS(pMetadata->GetExcludeFile(i, &pFiledesc));
  484. PrintFiledesc(pFiledesc, L"\n Exclude File");
  485. }
  486. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  487. {
  488. CComPtr<IVssWMComponent> pComponent;
  489. PVSSCOMPONENTINFO pInfo;
  490. CHECK_SUCCESS(pMetadata->GetComponent(iComponent, &pComponent));
  491. CHECK_SUCCESS(pComponent->GetComponentInfo(&pInfo));
  492. wprintf (L"\n"
  493. L" Component %d, type = %d (%s)\n"
  494. L" LogicalPath = %s\n"
  495. L" Name = %s\n"
  496. L" Caption = %s\n"
  497. L" Icon size = %u\n",
  498. iComponent,
  499. pInfo->type,
  500. GetStringFromComponentType (pInfo->type),
  501. pInfo->bstrLogicalPath,
  502. pInfo->bstrComponentName,
  503. pInfo->bstrCaption,
  504. pInfo->cbIcon );
  505. wprintf (L" RestoreMetadata = %s\n"
  506. L" NotifyOnBackupComplete = %s\n"
  507. L" Selectable = %s\n",
  508. pInfo->bRestoreMetadata ? L"yes" : L"no",
  509. pInfo->bNotifyOnBackupComplete ? L"yes" : L"no",
  510. pInfo->bSelectable ? L"yes" : L"no");
  511. CHECK_SUCCESS(pvbc->AddComponent (idInstance,
  512. idWriter,
  513. pInfo->type,
  514. pInfo->bstrLogicalPath,
  515. pInfo->bstrComponentName));
  516. if (pInfo->cFileCount > 0)
  517. {
  518. for(i = 0; i < pInfo->cFileCount; i++)
  519. {
  520. CComPtr<IVssWMFiledesc> pFiledesc;
  521. CHECK_SUCCESS(pComponent->GetFile(i, &pFiledesc));
  522. CComBSTR bstrPath;
  523. CHECK_SUCCESS(pFiledesc->GetPath(&bstrPath));
  524. DoAddToSnapshotSet(pvbc, bstrPath, wszVolumes, rgpSnapshotId, &cSnapshot);
  525. PrintFiledesc(pFiledesc, L" FileGroupFile");
  526. }
  527. }
  528. if (pInfo->cDatabases > 0)
  529. {
  530. for(i = 0; i < pInfo->cDatabases; i++)
  531. {
  532. CComPtr<IVssWMFiledesc> pFiledesc;
  533. CHECK_SUCCESS(pComponent->GetDatabaseFile(i, &pFiledesc));
  534. CComBSTR bstrPath;
  535. CHECK_SUCCESS(pFiledesc->GetPath(&bstrPath));
  536. DoAddToSnapshotSet(pvbc, bstrPath, wszVolumes, rgpSnapshotId, &cSnapshot);
  537. PrintFiledesc(pFiledesc, L" DatabaseFile");
  538. }
  539. }
  540. if (pInfo->cLogFiles > 0)
  541. {
  542. for(i = 0; i < pInfo->cLogFiles; i++)
  543. {
  544. CComPtr<IVssWMFiledesc> pFiledesc;
  545. CHECK_SUCCESS(pComponent->GetDatabaseLogFile(i, &pFiledesc));
  546. CComBSTR bstrPath;
  547. CHECK_SUCCESS(pFiledesc->GetPath(&bstrPath));
  548. DoAddToSnapshotSet(pvbc, bstrPath, wszVolumes, rgpSnapshotId, &cSnapshot);
  549. PrintFiledesc(pFiledesc, L" DatabaseLogFile");
  550. }
  551. }
  552. pComponent->FreeComponentInfo(pInfo);
  553. }
  554. VSS_RESTOREMETHOD_ENUM method;
  555. CComBSTR bstrUserProcedure;
  556. CComBSTR bstrService;
  557. VSS_WRITERRESTORE_ENUM writerRestore;
  558. unsigned cMappings;
  559. bool bRebootRequired;
  560. CHECK_NOFAIL(pMetadata->GetRestoreMethod (&method,
  561. &bstrService,
  562. &bstrUserProcedure,
  563. &writerRestore,
  564. &bRebootRequired,
  565. &cMappings));
  566. wprintf (L"\n"
  567. L" Restore method = %d (%s)\n"
  568. L" Service = %s\n"
  569. L" User Procedure = %s\n"
  570. L" WriterRestore = %d (%s)\n"
  571. L" RebootRequired = %s\n",
  572. method,
  573. GetStringFromRestoreMethod (method),
  574. bstrService,
  575. bstrUserProcedure,
  576. writerRestore,
  577. GetStringFromWriterRestoreMethod (writerRestore),
  578. bRebootRequired ? L"yes" : L"no");
  579. for(i = 0; i < cMappings; i++)
  580. {
  581. CComPtr<IVssWMFiledesc> pFiledesc;
  582. CHECK_SUCCESS(pMetadata->GetAlternateLocationMapping(i, &pFiledesc));
  583. PrintFiledesc(pFiledesc, L"AlternateMapping");
  584. }
  585. CComBSTR bstrMetadata;
  586. CHECK_SUCCESS(pMetadata->SaveAsXML(&bstrMetadata));
  587. CComPtr<IVssExamineWriterMetadata> pMetadataNew;
  588. CHECK_SUCCESS(CreateVssExamineWriterMetadata(bstrMetadata, &pMetadataNew));
  589. CHECK_SUCCESS(pMetadataNew->GetIdentity (&idInstanceT,
  590. &idWriter,
  591. &bstrWriterName,
  592. &usage,
  593. &source));
  594. wprintf (L"\n\n");
  595. if (memcmp(&idInstance, &idInstanceT, sizeof(VSS_ID)) != 0)
  596. {
  597. wprintf(L"Instance id mismatch\n");
  598. DebugBreak();
  599. }
  600. UuidToString(&idInstance, &pwszInstanceId);
  601. UuidToString(&idWriter, &pwszWriterId);
  602. wprintf (L"WriterName = %s\n\n"
  603. L" WriterId = %s\n"
  604. L" InstanceId = %s\n"
  605. L" UsageType = %d (%s)\n"
  606. L" SourceType = %d (%s)\n",
  607. bstrWriterName,
  608. pwszWriterId,
  609. pwszInstanceId,
  610. usage,
  611. GetStringFromUsageType (usage),
  612. source,
  613. GetStringFromSourceType (source));
  614. RpcStringFree(&pwszInstanceId);
  615. RpcStringFree(&pwszWriterId);
  616. }
  617. CHECK_SUCCESS(pvbc->FreeWriterMetadata());
  618. {
  619. CComPtr<IVssAsync> pAsync;
  620. HRESULT hr;
  621. CHECK_SUCCESS(pvbc->PrepareForBackup(&pAsync));
  622. LoopWait(pAsync, 5, L"PrepareForBackup");
  623. }
  624. CheckStatus(pvbc, L"After Prepare Backup");
  625. unsigned cWriterComponents;
  626. CHECK_SUCCESS(pvbc->GetWriterComponentsCount(&cWriterComponents));
  627. for(iWriter = 0; iWriter < cWriterComponents; iWriter++)
  628. {
  629. CComPtr<IVssWriterComponentsExt> pWriter;
  630. CHECK_SUCCESS(pvbc->GetWriterComponents(iWriter, &pWriter));
  631. unsigned cComponents;
  632. CHECK_SUCCESS(pWriter->GetComponentCount(&cComponents));
  633. VSS_ID idWriter, idInstance;
  634. CHECK_SUCCESS(pWriter->GetWriterInfo(&idInstance, &idWriter));
  635. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  636. {
  637. CComPtr<IVssComponent> pComponent;
  638. CHECK_SUCCESS(pWriter->GetComponent(iComponent, &pComponent));
  639. VSS_COMPONENT_TYPE ct;
  640. CComBSTR bstrLogicalPath;
  641. CComBSTR bstrComponentName;
  642. CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
  643. CHECK_SUCCESS(pComponent->GetComponentType(&ct));
  644. CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
  645. CHECK_SUCCESS(pvbc->SetBackupSucceeded (idInstance,
  646. idWriter,
  647. ct,
  648. bstrLogicalPath,
  649. bstrComponentName,
  650. true));
  651. }
  652. }
  653. {
  654. CComPtr<IVssAsync> pAsync;
  655. INT nPercentDone;
  656. CHECK_SUCCESS(pvbc->DoSnapshotSet (&pAsync));
  657. CHECK_SUCCESS(pAsync->Wait());
  658. CHECK_SUCCESS(pAsync->QueryStatus(&hr, &nPercentDone));
  659. }
  660. if (FAILED(hr))
  661. {
  662. wprintf(L"Creating the snapshot failed. hr = 0x%08lx\n", hr);
  663. CheckStatus(pvbc, L"After Do Snapshot");
  664. }
  665. else
  666. {
  667. CheckStatus(pvbc, L"After Do Snapshot");
  668. CComBSTR bstrXML;
  669. CComPtr<IVssBackupComponents> pvbcRestore;
  670. CHECK_SUCCESS(pvbc->SaveAsXML(&bstrXML));
  671. CHECK_SUCCESS(CreateVssBackupComponents(&pvbcRestore));
  672. CHECK_SUCCESS(pvbcRestore->InitializeForRestore(bstrXML));
  673. wprintf(L"InitializeForRestore succeeded.\n");
  674. LONG lSnapshotsNotDeleted;
  675. VSS_ID rgSnapshotsNotDeleted[10];
  676. {
  677. CComPtr<IVssAsync> pAsync;
  678. HRESULT hr;
  679. CHECK_SUCCESS(pvbc->BackupComplete(&pAsync));
  680. LoopWait(pAsync, 5, L"BackupComplete");
  681. }
  682. CheckStatus(pvbc, L"After Backup Complete");
  683. hr = pvbc->DeleteSnapshots (id,
  684. VSS_OBJECT_SNAPSHOT_SET,
  685. false,
  686. &lSnapshotsNotDeleted,
  687. rgSnapshotsNotDeleted);
  688. if (FAILED(hr))
  689. wprintf(L"Deletion of Snapshots failed. hr = 0x%08lx\n", hr);
  690. {
  691. CComPtr<IVssAsync> pAsync;
  692. HRESULT hr;
  693. pvbcRestore->GatherWriterMetadata(&pAsync);
  694. CHECK_SUCCESS(pAsync->Wait());
  695. CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
  696. CHECK_NOFAIL(hr);
  697. CHECK_SUCCESS(pvbcRestore->GetWriterMetadataCount(&cWriters));
  698. for(iWriter = 0; iWriter < cWriters; iWriter++)
  699. {
  700. CComPtr<IVssExamineWriterMetadata> pMetadata;
  701. VSS_ID idInstance;
  702. CHECK_SUCCESS(pvbcRestore->GetWriterMetadata(iWriter, &idInstance, &pMetadata));
  703. }
  704. pAsync = NULL;
  705. pvbcRestore->PostRestore(&pAsync);
  706. LoopWait(pAsync, 5, L"PostRetore");
  707. CHECK_NOFAIL(hr);
  708. }
  709. }
  710. }
  711. catch(...)
  712. {
  713. BS_ASSERT(FALSE);
  714. hr = E_UNEXPECTED;
  715. }
  716. if (bSubscribed)
  717. pInstance->Unsubscribe();
  718. if (bCreated)
  719. delete pInstance;
  720. if (FAILED(hr))
  721. wprintf(L"Failed with %08x.\n", hr);
  722. if (bCoInitializeSucceeded)
  723. CoUninitialize();
  724. return(0);
  725. }