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.

505 lines
12 KiB

  1. #include "stdafx.hxx"
  2. #include "vs_idl.hxx"
  3. #include "vswriter.h"
  4. #include "vsbackup.h"
  5. #include <debug.h>
  6. #include <vsswprv.h>
  7. CComModule _Module;
  8. static LPCWSTR s_rgwszStates[] =
  9. {
  10. NULL,
  11. L"STABLE",
  12. L"WAIT_FOR_FREEZE",
  13. L"WAIT_FOR_THAW",
  14. L"WAIT_FOR_COMPLETION",
  15. L"FAILED_AT_IDENTIFY",
  16. L"FAILED_AT_PREPARE_BACKUP",
  17. L"FAILED_AT_PREPARE_SNAPSHOT",
  18. L"FAILED_AT_FREEZE",
  19. L"FAILED_AT_THAW"
  20. };
  21. void CheckStatus(IVssBackupComponents *pvbc, LPCWSTR wszWhen)
  22. {
  23. unsigned cWriters;
  24. CComPtr<IVssAsync> pAsync;
  25. CHECK_NOFAIL(pvbc->GatherWriterStatus(&pAsync));
  26. CHECK_NOFAIL(pAsync->Wait());
  27. CHECK_NOFAIL(pvbc->GetWriterStatusCount(&cWriters));
  28. wprintf(L"status %s\n%d writers\n\n", wszWhen, cWriters);
  29. for(unsigned iWriter = 0; iWriter < cWriters; iWriter++)
  30. {
  31. VSS_ID idInstance;
  32. VSS_ID idWriter;
  33. CComBSTR bstrWriter;
  34. VSS_WRITER_STATE status;
  35. HRESULT hrWriterFailure;
  36. CHECK_SUCCESS(pvbc->GetWriterStatus
  37. (
  38. iWriter,
  39. &idInstance,
  40. &idWriter,
  41. &bstrWriter,
  42. &status,
  43. &hrWriterFailure
  44. ));
  45. wprintf
  46. (
  47. L"Status for writer %s: %s(0x%08lx)\n",
  48. bstrWriter,
  49. s_rgwszStates[status],
  50. hrWriterFailure
  51. );
  52. }
  53. pvbc->FreeWriterStatus();
  54. }
  55. void PrintFiledesc(IVssWMFiledesc *pFiledesc, LPCWSTR wszDescription)
  56. {
  57. CComBSTR bstrPath;
  58. CComBSTR bstrFilespec;
  59. CComBSTR bstrAlternate;
  60. CComBSTR bstrDestination;
  61. bool bRecursive;
  62. CHECK_SUCCESS(pFiledesc->GetPath(&bstrPath));
  63. CHECK_SUCCESS(pFiledesc->GetFilespec(&bstrFilespec));
  64. CHECK_NOFAIL(pFiledesc->GetRecursive(&bRecursive));
  65. CHECK_NOFAIL(pFiledesc->GetAlternateLocation(&bstrAlternate));
  66. CHECK_NOFAIL(pFiledesc->GetAlternateLocation(&bstrDestination));
  67. wprintf
  68. (
  69. L"%s\nPath=%s,Filespec=%s, Recursive=%s\n",
  70. wszDescription,
  71. bstrPath,
  72. bstrFilespec,
  73. bRecursive ? L"yes" : L"no"
  74. );
  75. if (bstrAlternate && wcslen(bstrAlternate) > 0)
  76. wprintf(L"Alternate Location = %s\n", bstrAlternate);
  77. if (bstrDestination && wcslen(bstrDestination) > 0)
  78. wprintf(L"Destination Location = %s\n", bstrDestination);
  79. }
  80. HANDLE LaunchWriterProcess()
  81. {
  82. HANDLE hEventW = CreateEvent(NULL, TRUE, FALSE, L"TESTWRITEREVENT");
  83. if (hEventW == NULL)
  84. {
  85. wprintf(L"CreateEvent failed with error %d.\n", GetLastError());
  86. DebugBreak();
  87. }
  88. HANDLE hEventB = CreateEvent(NULL, TRUE, FALSE, L"TESTBACKUPEVENT");
  89. if (hEventB == NULL)
  90. {
  91. wprintf(L"CreateEvent failed with error %d.\n", GetLastError());
  92. DebugBreak();
  93. }
  94. WaitForSingleObject(hEventB, INFINITE);
  95. return hEventW;
  96. }
  97. void DoAddToSnapshotSet
  98. (
  99. IN IVssBackupComponents *pvbc,
  100. IN BSTR bstrPath,
  101. IN LPWSTR wszVolumes
  102. )
  103. {
  104. WCHAR wszVolume[100];
  105. WCHAR *pwc = bstrPath;
  106. WCHAR *pwcDest = wszVolume;
  107. for(; *pwc != ':'; pwc++, pwcDest++)
  108. *pwcDest = *pwc;
  109. *pwcDest++ = L':';
  110. *pwcDest++ = L'\\';
  111. *pwcDest++ = L'\0';
  112. pwc = wszVolumes;
  113. while(*pwc != '\0')
  114. {
  115. if (wcsncmp(pwc, wszVolume, wcslen(wszVolume)) == 0)
  116. return;
  117. pwc = wcschr(pwc, L';');
  118. if (pwc == NULL)
  119. break;
  120. }
  121. pwc = wszVolumes + wcslen(wszVolumes);
  122. wcscpy(pwc, wszVolume);
  123. VSS_ID SnapshotId;
  124. CHECK_SUCCESS(pvbc->AddToSnapshotSet
  125. (
  126. wszVolume,
  127. VSS_SWPRV_ProviderId,
  128. &SnapshotId
  129. ));
  130. }
  131. extern "C" __cdecl wmain(int argc, WCHAR **argv)
  132. {
  133. HANDLE hEvent = NULL;
  134. HRESULT hr = S_OK;
  135. try
  136. {
  137. WCHAR wszVolumes[100];
  138. CHECK_SUCCESS(CoInitializeEx(NULL, COINIT_MULTITHREADED));
  139. hEvent = LaunchWriterProcess();
  140. CComBSTR strSnapshotSetId = "12345678-1234-1234-1234-1234567890ab";
  141. CComPtr<IVssBackupComponents> pvbc;
  142. CHECK_SUCCESS(CreateVssBackupComponents(&pvbc));
  143. CHECK_SUCCESS(pvbc->InitializeForBackup());
  144. CHECK_SUCCESS(pvbc->SetBackupState
  145. (
  146. true,
  147. false,
  148. VSS_BT_INCREMENTAL
  149. ));
  150. unsigned cWriters;
  151. CComPtr<IVssAsync> pAsync;
  152. CHECK_NOFAIL(pvbc->GatherWriterMetadata(&pAsync));
  153. CHECK_NOFAIL(pAsync->Wait());
  154. CHECK_NOFAIL(pvbc->GetWriterMetadataCount(&cWriters));
  155. VSS_ID id;
  156. CHECK_SUCCESS(pvbc->StartSnapshotSet(&id));
  157. for(unsigned iWriter = 0; iWriter < cWriters; iWriter++)
  158. {
  159. CComPtr<IVssExamineWriterMetadata> pMetadata;
  160. VSS_ID idInstance;
  161. CHECK_SUCCESS(pvbc->GetWriterMetadata(iWriter, &idInstance, &pMetadata));
  162. VSS_ID idInstanceT;
  163. VSS_ID idWriter;
  164. CComBSTR bstrWriterName;
  165. VSS_USAGE_TYPE usage;
  166. VSS_SOURCE_TYPE source;
  167. CHECK_SUCCESS(pMetadata->GetIdentity
  168. (
  169. &idInstanceT,
  170. &idWriter,
  171. &bstrWriterName,
  172. &usage,
  173. &source
  174. ));
  175. if (memcmp(&idInstance, &idInstanceT, sizeof(VSS_ID)) != 0)
  176. {
  177. wprintf(L"Instance id mismatch\n");
  178. DebugBreak();
  179. }
  180. WCHAR *pwszInstanceId;
  181. WCHAR *pwszWriterId;
  182. UuidToString(&idInstance, &pwszInstanceId);
  183. UuidToString(&idWriter, &pwszWriterId);
  184. wprintf
  185. (
  186. L"InstanceId=%s\nWriterId=%s\nWriterName=%s\nUsageType=%d\nSourceType=%d\n",
  187. pwszInstanceId,
  188. pwszWriterId,
  189. bstrWriterName,
  190. usage,
  191. source
  192. );
  193. RpcStringFree(&pwszInstanceId);
  194. RpcStringFree(&pwszWriterId);
  195. unsigned cIncludeFiles, cExcludeFiles, cComponents;
  196. CHECK_SUCCESS(pMetadata->GetFileCounts
  197. (
  198. &cIncludeFiles,
  199. &cExcludeFiles,
  200. &cComponents
  201. ));
  202. CComBSTR bstrPath;
  203. CComBSTR bstrFilespec;
  204. CComBSTR bstrAlternate;
  205. CComBSTR bstrDestination;
  206. bool bRecursive;
  207. for(unsigned i = 0; i < cIncludeFiles; i++)
  208. {
  209. CComPtr<IVssWMFiledesc> pFiledesc;
  210. CHECK_SUCCESS(pMetadata->GetIncludeFile(i, &pFiledesc));
  211. PrintFiledesc(pFiledesc, L"Include File");
  212. }
  213. for(i = 0; i < cExcludeFiles; i++)
  214. {
  215. CComPtr<IVssWMFiledesc> pFiledesc;
  216. CHECK_SUCCESS(pMetadata->GetExcludeFile(i, &pFiledesc));
  217. PrintFiledesc(pFiledesc, L"Exclude File");
  218. }
  219. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  220. {
  221. CComPtr<IVssWMComponent> pComponent;
  222. PVSSCOMPONENTINFO pInfo;
  223. CHECK_SUCCESS(pMetadata->GetComponent(iComponent, &pComponent));
  224. CHECK_SUCCESS(pComponent->GetComponentInfo(&pInfo));
  225. wprintf
  226. (
  227. L"Component %d, type=%d\nLogicalPath=%s,Name=%s\nCaption=%s\n",
  228. i,
  229. pInfo->type,
  230. pInfo->bstrLogicalPath,
  231. pInfo->bstrComponentName,
  232. pInfo->bstrCaption
  233. );
  234. wprintf
  235. (
  236. L"RestoreMetadata=%s,NotifyOnBackupComplete=%s,Selectable=%s\n",
  237. pInfo->bRestoreMetadata ? L"yes" : L"no",
  238. pInfo->bNotifyOnBackupComplete ? L"yes" : L"no",
  239. pInfo->bSelectable ? L"yes" : L"no"
  240. );
  241. CHECK_SUCCESS(pvbc->AddComponent
  242. (
  243. idInstance,
  244. idWriter,
  245. pInfo->type,
  246. pInfo->bstrLogicalPath,
  247. pInfo->bstrComponentName
  248. ));
  249. if (pInfo->cFileCount > 0)
  250. {
  251. for(i = 0; i < pInfo->cFileCount; i++)
  252. {
  253. CComPtr<IVssWMFiledesc> pFiledesc;
  254. CHECK_SUCCESS(pComponent->GetFile(i, &pFiledesc));
  255. CComBSTR bstrPath;
  256. CHECK_SUCCESS(pFiledesc->GetPath(&bstrPath));
  257. DoAddToSnapshotSet(pvbc, bstrPath, wszVolumes);
  258. PrintFiledesc(pFiledesc, L"FileGroupFile");
  259. }
  260. }
  261. if (pInfo->cDatabases > 0)
  262. {
  263. for(i = 0; i < pInfo->cDatabases; i++)
  264. {
  265. CComPtr<IVssWMFiledesc> pFiledesc;
  266. CHECK_SUCCESS(pComponent->GetDatabaseFile(i, &pFiledesc));
  267. CComBSTR bstrPath;
  268. CHECK_SUCCESS(pFiledesc->GetPath(&bstrPath));
  269. DoAddToSnapshotSet(pvbc, bstrPath, wszVolumes);
  270. PrintFiledesc(pFiledesc, L"DatabaseFile");
  271. }
  272. }
  273. if (pInfo->cLogFiles > 0)
  274. {
  275. for(i = 0; i < pInfo->cLogFiles; i++)
  276. {
  277. CComPtr<IVssWMFiledesc> pFiledesc;
  278. CHECK_SUCCESS(pComponent->GetDatabaseLogFile(i, &pFiledesc));
  279. CComBSTR bstrPath;
  280. CHECK_SUCCESS(pFiledesc->GetPath(&bstrPath));
  281. DoAddToSnapshotSet(pvbc, bstrPath, wszVolumes);
  282. PrintFiledesc(pFiledesc, L"DatabaseLogFile");
  283. }
  284. }
  285. pComponent->FreeComponentInfo(pInfo);
  286. }
  287. VSS_RESTOREMETHOD_ENUM method;
  288. CComBSTR bstrUserProcedure;
  289. CComBSTR bstrService;
  290. VSS_WRITERRESTORE_ENUM writerRestore;
  291. unsigned cMappings;
  292. bool bRebootRequired;
  293. CHECK_SUCCESS(pMetadata->GetRestoreMethod
  294. (
  295. &method,
  296. &bstrService,
  297. &bstrUserProcedure,
  298. &writerRestore,
  299. &bRebootRequired,
  300. &cMappings
  301. ));
  302. wprintf
  303. (
  304. L"Restore method=%d\nService=%s\nUser Procedure=%s\nwriterRestore=%d\nrebootRequired=%s\n\n",
  305. method,
  306. bstrService,
  307. bstrUserProcedure,
  308. writerRestore,
  309. bRebootRequired ? L"yes" : L"no"
  310. );
  311. for(i = 0; i < cMappings; i++)
  312. {
  313. CComPtr<IVssWMFiledesc> pFiledesc;
  314. CHECK_SUCCESS(pMetadata->GetAlternateLocationMapping(i, &pFiledesc));
  315. PrintFiledesc(pFiledesc, L"AlternateMapping");
  316. }
  317. }
  318. CHECK_SUCCESS(pvbc->FreeWriterMetadata());
  319. {
  320. CComPtr<IVssAsync> pAsync;
  321. HRESULT hr;
  322. INT nPercentDone;
  323. CHECK_SUCCESS(pvbc->PrepareForBackup(&pAsync));
  324. CHECK_SUCCESS(pAsync->Wait());
  325. CHECK_SUCCESS(pAsync->QueryStatus(&hr, &nPercentDone));
  326. CHECK_NOFAIL(hr);
  327. }
  328. CheckStatus(pvbc, L"After Prepare Backup");
  329. unsigned cWriterComponents;
  330. CHECK_SUCCESS(pvbc->GetWriterComponentsCount(&cWriterComponents));
  331. for(iWriter = 0; iWriter < cWriterComponents; iWriter++)
  332. {
  333. CComPtr<IVssWriterComponentsExt> pWriter;
  334. CHECK_SUCCESS(pvbc->GetWriterComponents(iWriter, &pWriter));
  335. unsigned cComponents;
  336. CHECK_SUCCESS(pWriter->GetComponentCount(&cComponents));
  337. VSS_ID idWriter, idInstance;
  338. CHECK_SUCCESS(pWriter->GetWriterInfo(&idInstance, &idWriter));
  339. for(unsigned iComponent = 0; iComponent < cComponents; iComponent++)
  340. {
  341. CComPtr<IVssComponent> pComponent;
  342. CHECK_SUCCESS(pWriter->GetComponent(iComponent, &pComponent));
  343. VSS_COMPONENT_TYPE ct;
  344. CComBSTR bstrLogicalPath;
  345. CComBSTR bstrComponentName;
  346. bool bBackupSucceeded;
  347. CHECK_NOFAIL(pComponent->GetLogicalPath(&bstrLogicalPath));
  348. CHECK_SUCCESS(pComponent->GetComponentType(&ct));
  349. CHECK_SUCCESS(pComponent->GetComponentName(&bstrComponentName));
  350. CHECK_SUCCESS(pvbc->SetBackupSucceeded
  351. (
  352. idInstance,
  353. idWriter,
  354. ct,
  355. bstrLogicalPath,
  356. bstrComponentName,
  357. true
  358. ));
  359. }
  360. }
  361. {
  362. CComPtr<IVssAsync> pAsync;
  363. INT nPercentDone;
  364. CHECK_SUCCESS(pvbc->DoSnapshotSet
  365. (
  366. &pAsync
  367. ));
  368. CHECK_SUCCESS(pAsync->Wait());
  369. CHECK_SUCCESS(pAsync->QueryStatus(&hr, &nPercentDone));
  370. }
  371. if (FAILED(hr))
  372. {
  373. wprintf(L"Creating the snapshot failed. hr = 0x%08lx\n", hr);
  374. CheckStatus(pvbc, L"After Do Snapshot");
  375. }
  376. else
  377. {
  378. CheckStatus(pvbc, L"After Do Snapshot");
  379. LONG lSnapshotsNotDeleted;
  380. VSS_ID rgSnapshotsNotDeleted[10];
  381. {
  382. CComPtr<IVssAsync> pAsync;
  383. HRESULT hr;
  384. INT nPercentDone;
  385. CHECK_SUCCESS(pvbc->BackupComplete(&pAsync));
  386. CHECK_SUCCESS(pAsync->Wait());
  387. CHECK_SUCCESS(pAsync->QueryStatus(&hr, &nPercentDone));
  388. CHECK_NOFAIL(hr);
  389. }
  390. CheckStatus(pvbc, L"After Backup Complete");
  391. hr = pvbc->DeleteSnapshots
  392. (
  393. id,
  394. VSS_OBJECT_SNAPSHOT_SET,
  395. false,
  396. &lSnapshotsNotDeleted,
  397. rgSnapshotsNotDeleted
  398. );
  399. if (FAILED(hr))
  400. wprintf(L"Deletion of Snapshots failed. hr = 0x%08lx\n", hr);
  401. }
  402. }
  403. catch(...)
  404. {
  405. hr = E_UNEXPECTED;
  406. }
  407. if (hEvent)
  408. SetEvent(hEvent);
  409. if (FAILED(hr))
  410. wprintf(L"Failed with %08x.\n", hr);
  411. return(0);
  412. }