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.

514 lines
16 KiB

  1. /*
  2. **++
  3. **
  4. ** Copyright (c) 2000-2001 Microsoft Corporation
  5. **
  6. **
  7. ** Module Name:
  8. **
  9. ** vsreq.cpp
  10. **
  11. **
  12. ** Abstract:
  13. **
  14. ** Sample program to
  15. ** - obtain and display the Writer metadata.
  16. ** - create a snapshot set
  17. **
  18. ** Author:
  19. **
  20. ** Adi Oltean [aoltean] 05-Dec-2000
  21. **
  22. ** The sample is based on the Metasnap test program written by Michael C. Johnson.
  23. **
  24. **
  25. ** Revision History:
  26. **
  27. **--
  28. */
  29. ///////////////////////////////////////////////////////////////////////////////
  30. // Includes
  31. #include "vsreq.h"
  32. ///////////////////////////////////////////////////////////////////////////////
  33. // Processing functions
  34. CVssSampleRequestor::CVssSampleRequestor()
  35. {
  36. // Initialize data members
  37. m_bCoInitializeSucceeded = false;
  38. m_bBootableSystemState = false;
  39. m_bComponentSelectionEnabled = false;
  40. m_pBackupComponents = NULL;
  41. m_nVolumesCount = 0;
  42. m_hr = S_OK;
  43. m_pwszXmlFile = NULL;
  44. m_pXmlFile = NULL;
  45. // For safety
  46. for (int nIndex=0; nIndex<MAX_VOLUMES; nIndex++) {
  47. m_ppwszVolumesList[nIndex] = NULL;
  48. m_ppwszVolumeNamesList[nIndex] = NULL;
  49. }
  50. // Print display header
  51. wprintf(L"\nVSS Requestor Sample application, version 1.0\n");
  52. }
  53. CVssSampleRequestor::~CVssSampleRequestor()
  54. {
  55. // Deallocate some internal strings
  56. delete m_pwszXmlFile;
  57. // delete the allocated volumes
  58. for (int nIndex=0; nIndex<m_nVolumesCount; nIndex++) {
  59. free(m_ppwszVolumesList[nIndex]);
  60. free(m_ppwszVolumeNamesList[nIndex]);
  61. }
  62. // Close the Xml file
  63. if (m_pXmlFile)
  64. fclose(m_pXmlFile);
  65. // Releasing backup components prior to the CoUninitialize call
  66. m_pBackupComponents = NULL;
  67. // Unloading the COM library
  68. if (m_bCoInitializeSucceeded)
  69. CoUninitialize();
  70. }
  71. void CVssSampleRequestor::Initialize()
  72. {
  73. wprintf (L"\n----------------- Initializing ---------------------\n");
  74. // Initialize COM library
  75. CHECK_NOFAIL(CoInitializeEx (NULL, COINIT_MULTITHREADED));
  76. m_bCoInitializeSucceeded = true;
  77. wprintf (L"COM library initialized.\n");
  78. // Initialize COM security
  79. CHECK_SUCCESS
  80. (
  81. CoInitializeSecurity
  82. (
  83. NULL, // IN PSECURITY_DESCRIPTOR pSecDesc,
  84. -1, // IN LONG cAuthSvc,
  85. NULL, // IN SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
  86. NULL, // IN void *pReserved1,
  87. RPC_C_AUTHN_LEVEL_CONNECT, // IN DWORD dwAuthnLevel,
  88. RPC_C_IMP_LEVEL_IMPERSONATE, // IN DWORD dwImpLevel,
  89. NULL, // IN void *pAuthList,
  90. EOAC_NONE, // IN DWORD dwCapabilities,
  91. NULL // IN void *pReserved3
  92. )
  93. );
  94. wprintf (L"COM security initialized.\n");
  95. // Open the Xml file
  96. if (m_pwszXmlFile) {
  97. m_pXmlFile = _wfopen( m_pwszXmlFile, L"w");
  98. if (!m_pXmlFile)
  99. Error(1, L"\nError creating/opening the file %s\n", m_pwszXmlFile);
  100. wprintf (L"XML results file created: %s\n", m_pwszXmlFile);
  101. }
  102. // Create the Backup components object
  103. CHECK_NOFAIL(CreateVssBackupComponents(&m_pBackupComponents));
  104. wprintf (L"Backup components object created.\n");
  105. // Initialize the backup components object for backup
  106. CHECK_NOFAIL(m_pBackupComponents->InitializeForBackup());
  107. CHECK_SUCCESS(m_pBackupComponents->SetBackupState(
  108. m_bComponentSelectionEnabled, m_bBootableSystemState, VSS_BT_FULL));
  109. wprintf (L"Backup components object initialized for backup operations.\n");
  110. }
  111. void CVssSampleRequestor::CreateSnapshotSet()
  112. {
  113. CComPtr<IVssAsync> pAsync;
  114. VSS_ID SnapshotsArray[MAX_VOLUMES];
  115. VSS_ID SnapshotSetId = GUID_NULL;
  116. wprintf (L"\n---------- Starting backup/snapshot ----------------\n");
  117. // Starting a new snapshot set
  118. wprintf(L"Starting a new Snapshot Set\n");
  119. CHECK_SUCCESS(m_pBackupComponents->StartSnapshotSet(&SnapshotSetId));
  120. wprintf(L"Snapshot Set created with ID = " WSTR_GUID_FMT L"\n", GUID_PRINTF_ARG(SnapshotSetId));
  121. // Add volumes to the snapshot set
  122. wprintf(L"Adding volumes to the Snapshot Set: \n");
  123. for (INT nIndex = 0; nIndex < m_nVolumesCount; nIndex++)
  124. {
  125. // Get the volume containing the path
  126. wprintf(L"\t- Adding volume containing %s ... ", m_ppwszVolumesList[nIndex] );
  127. // Add the volume to the snapshot set
  128. CHECK_SUCCESS(m_pBackupComponents->AddToSnapshotSet(m_ppwszVolumesList[nIndex],
  129. GUID_NULL, &(SnapshotsArray[nIndex])));
  130. wprintf( L"OK\n");
  131. }
  132. wprintf (L"\n------------ Creating the snapshot -----------------\n");
  133. // Prepare for backup
  134. wprintf(L"Starting asynchronous PrepareForBackup. Please wait...\n");
  135. HRESULT hr = S_OK;
  136. CHECK_SUCCESS(m_pBackupComponents->PrepareForBackup(&pAsync));
  137. CHECK_SUCCESS(pAsync->Wait());
  138. CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
  139. CHECK_NOFAIL((hr));
  140. wprintf(L"Asynchronous PrepareForBackup finished.\n");
  141. pAsync = NULL;
  142. // Gather writer status
  143. GatherWriterStatus(L"after PrepareForBackup");
  144. // Create the snapshot
  145. wprintf(L"\nStarting asynchronous DoSnapshotSet. Please wait...\n");
  146. hr = S_OK;
  147. CHECK_SUCCESS(m_pBackupComponents->DoSnapshotSet(&pAsync));
  148. CHECK_SUCCESS(pAsync->Wait());
  149. CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
  150. CHECK_NOFAIL((hr));
  151. wprintf(L"Asynchronous DoSnapshotSet finished.\n");
  152. pAsync = NULL;
  153. // Gather writer status
  154. GatherWriterStatus(L"after DoSnapshotSet");
  155. wprintf(L"Snapshot set created\n");
  156. for (INT nIndex = 0; nIndex < m_nVolumesCount; nIndex++)
  157. {
  158. VSS_SNAPSHOT_PROP prop;
  159. CHECK_SUCCESS(m_pBackupComponents->GetSnapshotProperties(SnapshotsArray[nIndex], &prop));
  160. wprintf(L"\t- The snapshot on volume %s resides at %s\n",
  161. m_ppwszVolumesList[nIndex], prop.m_pwszSnapshotDeviceObject);
  162. VssFreeSnapshotProperties(&prop);
  163. }
  164. }
  165. void CVssSampleRequestor::BackupComplete()
  166. {
  167. unsigned cWriterComponents;
  168. CComPtr<IVssAsync> pAsync;
  169. wprintf (L"\n------------ Completing backup phase ---------------\n");
  170. CHECK_SUCCESS(m_pBackupComponents->GetWriterComponentsCount(&cWriterComponents));
  171. // If component selection enabled,
  172. if (m_bComponentSelectionEnabled)
  173. {
  174. wprintf(L"Setting the succeeded state for the following components:\n");
  175. // For each component, mark the completion state as succeeded
  176. for(unsigned iWriter = 0; iWriter < cWriterComponents; iWriter++)
  177. {
  178. CComPtr<IVssWriterComponentsExt> pWriter;
  179. CHECK_SUCCESS(m_pBackupComponents->GetWriterComponents(iWriter, &pWriter));
  180. unsigned cComponents;
  181. CHECK_SUCCESS(pWriter->GetComponentCount(&cComponents));
  182. VSS_ID idWriter, idInstance;
  183. CHECK_SUCCESS(pWriter->GetWriterInfo(&idInstance, &idWriter));
  184. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  185. {
  186. CComPtr<IVssComponent> pComponent;
  187. CHECK_SUCCESS(pWriter->GetComponent(iComponent, &pComponent));
  188. VSS_COMPONENT_TYPE ct;
  189. CComBSTR bstrLogicalPath;
  190. CComBSTR bstrComponentName;
  191. CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
  192. CHECK_SUCCESS(pComponent->GetComponentType(&ct));
  193. CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
  194. wprintf(L"\t- %s\n", (LPWSTR)bstrComponentName);
  195. CHECK_SUCCESS(m_pBackupComponents->SetBackupSucceeded (idInstance,
  196. idWriter,
  197. ct,
  198. bstrLogicalPath,
  199. bstrComponentName,
  200. true));
  201. }
  202. }
  203. wprintf(L"\n");
  204. }
  205. // Save the XML file, if needed
  206. // The contents will be needed at restore, in the InitializeForRestore method.
  207. if (m_pXmlFile) {
  208. CComBSTR bstrXML;
  209. CHECK_SUCCESS(m_pBackupComponents->SaveAsXML(&bstrXML));
  210. fwprintf( m_pXmlFile, L"%s", (WCHAR*)bstrXML);
  211. wprintf(L"XML results written in %s\n", m_pwszXmlFile);
  212. }
  213. // Send the BackupComplete event
  214. wprintf(L"\nStarting asynchronous BackupComplete. Please wait...\n");
  215. HRESULT hr = S_OK;
  216. CHECK_SUCCESS(m_pBackupComponents->BackupComplete(&pAsync));
  217. CHECK_SUCCESS(pAsync->Wait());
  218. CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
  219. CHECK_NOFAIL((hr));
  220. wprintf(L"Asynchronous BackupComplete finished.\n");
  221. pAsync = NULL;
  222. // Gather writer status
  223. GatherWriterStatus(L"after BackupComplete");
  224. }
  225. // Gather writera metadata and select components for backup, if needed
  226. void CVssSampleRequestor::GatherWriterMetadata()
  227. {
  228. unsigned cWriters;
  229. CComPtr<IVssAsync> pAsync;
  230. wprintf (L"\n---------- Gathering writer metadata ---------------\n");
  231. wprintf(L"Starting asynchronous GatherWriterMetadata. Please wait...\n");
  232. HRESULT hr = S_OK;
  233. CHECK_SUCCESS(m_pBackupComponents->GatherWriterMetadata(&pAsync));
  234. CHECK_SUCCESS(pAsync->Wait());
  235. CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
  236. CHECK_NOFAIL((hr));
  237. wprintf(L"Asynchronous GatherWriterMetadata finished.\n");
  238. pAsync = NULL;
  239. CHECK_NOFAIL (m_pBackupComponents->GetWriterMetadataCount (&cWriters));
  240. wprintf(L"Number of writers that responded: %u\n", cWriters);
  241. for (unsigned iWriter = 0; iWriter < cWriters; iWriter++)
  242. {
  243. CComPtr<IVssExamineWriterMetadata> pMetadata;
  244. VSS_ID idInstance;
  245. VSS_ID idInstanceT;
  246. VSS_ID idWriter;
  247. CComBSTR bstrWriterName;
  248. VSS_USAGE_TYPE usage;
  249. VSS_SOURCE_TYPE source;
  250. unsigned cIncludeFiles, cExcludeFiles, cComponents;
  251. CComBSTR bstrPath;
  252. CComBSTR bstrFilespec;
  253. CComBSTR bstrAlternate;
  254. CComBSTR bstrDestination;
  255. CHECK_SUCCESS (m_pBackupComponents->GetWriterMetadata(iWriter, &idInstance, &pMetadata));
  256. CHECK_SUCCESS (pMetadata->GetIdentity (&idInstanceT,
  257. &idWriter,
  258. &bstrWriterName,
  259. &usage,
  260. &source));
  261. wprintf (L"\n*** WriterName = %s\n\n"
  262. L" WriterId = "WSTR_GUID_FMT L"\n"
  263. L" InstanceId = "WSTR_GUID_FMT L"\n"
  264. L" UsageType = %d (%s)\n"
  265. L" SourceType = %d (%s)\n",
  266. bstrWriterName,
  267. GUID_PRINTF_ARG(idWriter),
  268. GUID_PRINTF_ARG(idInstance),
  269. usage,
  270. GetStringFromUsageType (usage),
  271. source,
  272. GetStringFromSourceType (source));
  273. CHECK_SUCCESS(pMetadata->GetFileCounts (&cIncludeFiles,
  274. &cExcludeFiles,
  275. &cComponents));
  276. for(unsigned i = 0; i < cIncludeFiles; i++)
  277. {
  278. CComPtr<IVssWMFiledesc> pFiledesc;
  279. CHECK_SUCCESS (pMetadata->GetIncludeFile (i, &pFiledesc));
  280. PrintFiledesc(pFiledesc, L"\n Include File");
  281. }
  282. for(i = 0; i < cExcludeFiles; i++)
  283. {
  284. CComPtr<IVssWMFiledesc> pFiledesc;
  285. CHECK_SUCCESS (pMetadata->GetExcludeFile (i, &pFiledesc));
  286. PrintFiledesc (pFiledesc, L"\n Exclude File");
  287. }
  288. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  289. {
  290. CComPtr<IVssWMComponent> pComponent;
  291. PVSSCOMPONENTINFO pInfo;
  292. CHECK_SUCCESS (pMetadata->GetComponent (iComponent, &pComponent));
  293. CHECK_SUCCESS (pComponent->GetComponentInfo (&pInfo));
  294. wprintf (L"\n"
  295. L" Component %d, type = %d (%s)\n"
  296. L" LogicalPath = %s\n"
  297. L" Name = %s\n"
  298. L" Caption = %s\n",
  299. iComponent,
  300. pInfo->type,
  301. GetStringFromComponentType (pInfo->type),
  302. pInfo->bstrLogicalPath,
  303. pInfo->bstrComponentName,
  304. pInfo->bstrCaption);
  305. wprintf (L" RestoreMetadata = %s\n"
  306. L" NotifyOnBackupComplete = %s\n"
  307. L" Selectable = %s\n",
  308. pInfo->bRestoreMetadata ? L"yes" : L"no",
  309. pInfo->bNotifyOnBackupComplete ? L"yes" : L"no",
  310. pInfo->bSelectable ? L"yes" : L"no");
  311. // If specified, add this component to the backup
  312. // Remark: A real backup app will first get from the user the list of components to be added
  313. if (m_bComponentSelectionEnabled) {
  314. CHECK_SUCCESS(m_pBackupComponents->AddComponent(idInstance,
  315. idWriter,
  316. pInfo->type,
  317. pInfo->bstrLogicalPath,
  318. pInfo->bstrComponentName));
  319. wprintf (L" [Component %d was added to the backup]\n", iComponent);
  320. }
  321. for(i = 0; i < pInfo->cFileCount; i++)
  322. {
  323. CComPtr<IVssWMFiledesc> pFiledesc;
  324. CHECK_SUCCESS (pComponent->GetFile (i, &pFiledesc));
  325. PrintFiledesc (pFiledesc, L" FileGroupFile");
  326. // If we add the component, snapshot also the volume on which the file reside
  327. if (m_bComponentSelectionEnabled)
  328. AddVolumeForComponent(pFiledesc);
  329. }
  330. for(i = 0; i < pInfo->cDatabases; i++)
  331. {
  332. CComPtr<IVssWMFiledesc> pFiledesc;
  333. CHECK_SUCCESS (pComponent->GetDatabaseFile (i, &pFiledesc));
  334. PrintFiledesc (pFiledesc, L" DatabaseFile");
  335. // If we add the component, snapshot also the volume on which the file reside
  336. if (m_bComponentSelectionEnabled)
  337. AddVolumeForComponent(pFiledesc);
  338. }
  339. for(i = 0; i < pInfo->cLogFiles; i++)
  340. {
  341. CComPtr<IVssWMFiledesc> pFiledesc;
  342. CHECK_SUCCESS (pComponent->GetDatabaseLogFile (i, &pFiledesc));
  343. PrintFiledesc (pFiledesc, L" DatabaseLogFile");
  344. // If we add the component, snapshot also the volume on which the file reside
  345. if (m_bComponentSelectionEnabled)
  346. AddVolumeForComponent(pFiledesc);
  347. }
  348. pComponent->FreeComponentInfo (pInfo);
  349. }
  350. VSS_RESTOREMETHOD_ENUM method;
  351. CComBSTR bstrUserProcedure;
  352. CComBSTR bstrService;
  353. VSS_WRITERRESTORE_ENUM writerRestore;
  354. unsigned cMappings;
  355. bool bRebootRequired;
  356. CHECK_NOFAIL (pMetadata->GetRestoreMethod (&method,
  357. &bstrService,
  358. &bstrUserProcedure,
  359. &writerRestore,
  360. &bRebootRequired,
  361. &cMappings));
  362. wprintf (L"\n"
  363. L" Restore method = %d (%s)\n"
  364. L" Service = %d\n"
  365. L" User Procedure = %s\n"
  366. L" WriterRestore = %d (%s)\n"
  367. L" RebootRequired = %s\n",
  368. method,
  369. GetStringFromRestoreMethod (method),
  370. bstrService,
  371. bstrUserProcedure,
  372. writerRestore,
  373. GetStringFromWriterRestoreMethod (writerRestore),
  374. bRebootRequired ? L"yes" : L"no");
  375. for(i = 0; i < cMappings; i++)
  376. {
  377. CComPtr<IVssWMFiledesc> pFiledesc;
  378. CHECK_SUCCESS (pMetadata->GetAlternateLocationMapping (i, &pFiledesc));
  379. PrintFiledesc (pFiledesc, L" AlternateMapping");
  380. }
  381. }
  382. // Gather writer status
  383. GatherWriterStatus(L"after GatherWriterMetadata");
  384. CHECK_SUCCESS (m_pBackupComponents->FreeWriterMetadata());
  385. }
  386. void CVssSampleRequestor::GatherWriterStatus(
  387. IN LPCWSTR wszWhen
  388. )
  389. {
  390. unsigned cWriters;
  391. CComPtr<IVssAsync> pAsync;
  392. wprintf (L"\nGathering writer status %s... ", wszWhen);
  393. HRESULT hr = S_OK;
  394. CHECK_SUCCESS(m_pBackupComponents->GatherWriterStatus(&pAsync));
  395. CHECK_SUCCESS(pAsync->Wait());
  396. CHECK_SUCCESS(pAsync->QueryStatus(&hr, NULL));
  397. CHECK_NOFAIL((hr));
  398. CHECK_NOFAIL(m_pBackupComponents->GetWriterStatusCount(&cWriters));
  399. wprintf (L"%d writers responded\n", cWriters);
  400. for(unsigned iWriter = 0; iWriter < cWriters; iWriter++)
  401. {
  402. VSS_ID idInstance;
  403. VSS_ID idWriter;
  404. VSS_WRITER_STATE eWriterStatus;
  405. CComBSTR bstrWriter;
  406. HRESULT hrWriterFailure;
  407. CHECK_SUCCESS(m_pBackupComponents->GetWriterStatus (iWriter,
  408. &idInstance,
  409. &idWriter,
  410. &bstrWriter,
  411. &eWriterStatus,
  412. &hrWriterFailure));
  413. WCHAR wszWriterFailure[MAX_TEXT_BUFFER];
  414. if (hrWriterFailure)
  415. swprintf(wszWriterFailure, L" Writer error code: %s [0x%08lx]",
  416. GetStringFromFailureType(hrWriterFailure), hrWriterFailure);
  417. else
  418. wszWriterFailure[0] = L'\0';
  419. wprintf (L"\t- %s status for writer '%s'. %s\n",
  420. GetStringFromWriterStatus(eWriterStatus), bstrWriter, wszWriterFailure);
  421. }
  422. m_pBackupComponents->FreeWriterStatus();
  423. }