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.

670 lines
17 KiB

  1. /*
  2. **++
  3. **
  4. ** Copyright (c) 2000-2001 Microsoft Corporation
  5. **
  6. **
  7. ** Module Name:
  8. **
  9. ** simsnap.cpp
  10. **
  11. **
  12. ** Abstract:
  13. **
  14. ** Test program to drive the VSS Writer Shim contained in VssAPI.DLL
  15. **
  16. **
  17. ** Author:
  18. **
  19. ** Michael C. Johnson [mikejohn] 24-May-2000
  20. **
  21. **
  22. ** Revision History:
  23. **
  24. ** X-5 MCJ Michael C. Johnson 18-Sep-2000
  25. ** 176860: Add the missing calling convention specifiers
  26. **
  27. ** X-4 MCJ Michael C. Johnson 23-Jun-2000
  28. ** Set the writer failure status.
  29. **
  30. ** X-3 MCJ Michael C. Johnson 15-Jun-2000
  31. ** Add some additional event routines and the ability to act
  32. ** as various types of writer.
  33. **
  34. ** X-2 MCJ Michael C. Johnson 26-May-2000
  35. ** Add some extra tests to validate shim is properly sensitive
  36. ** to volume name array contents.
  37. **--
  38. */
  39. /*
  40. ** Defines
  41. **
  42. **
  43. ** C4290: C++ Exception Specification ignored
  44. ** warning C4511: 'CVssCOMApplication' : copy constructor could not be generated
  45. ** warning C4127: conditional expression is constant
  46. */
  47. #pragma warning(disable:4290)
  48. #pragma warning(disable:4511)
  49. #pragma warning(disable:4127)
  50. /*
  51. ** Includes
  52. */
  53. #include <windows.h>
  54. #include <wtypes.h>
  55. #include <stddef.h>
  56. #include <stdlib.h>
  57. #include <stdio.h>
  58. #include <time.h>
  59. #include <assert.h>
  60. #include <vss.h>
  61. #include <vswriter.h>
  62. #define GET_STATUS_FROM_BOOL(_bSucceeded) ((_bSucceeded) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
  63. #define GET_STATUS_FROM_HANDLE(_handle) ((NULL != (_handle)) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
  64. #define GET_STATUS_FROM_POINTER(_ptr) ((NULL != (_ptr)) ? NOERROR : E_OUTOFMEMORY)
  65. #define SIZEOF_ARRAY(_aBase) (sizeof (_aBase) / sizeof ((_aBase)[0]))
  66. typedef enum FAIL_PHASE
  67. {
  68. PHASE_UNDEFINED = 0,
  69. PHASE_IDENTIFY,
  70. PHASE_PREPARE_FOR_BACKUP,
  71. PHASE_PREPARE_FOR_SNAPSHOT,
  72. PHASE_FREEZE,
  73. PHASE_THAW,
  74. PHASE_ABORT,
  75. PHASE_BACKUP_COMPLETE,
  76. PHASE_RESTORE
  77. } FAIL_PHASE;
  78. HRESULT SelectFailureStatus (VOID)
  79. {
  80. HRESULT hrStatus;
  81. switch (rand () / (RAND_MAX / 5))
  82. {
  83. case 0: hrStatus = VSS_E_WRITERERROR_INCONSISTENTSNAPSHOT; break;
  84. case 1: hrStatus = VSS_E_WRITERERROR_OUTOFRESOURCES; break;
  85. case 2: hrStatus = VSS_E_WRITERERROR_TIMEOUT; break;
  86. case 3: hrStatus = VSS_E_WRITERERROR_NONRETRYABLE; break;
  87. case 4: hrStatus = VSS_E_WRITERERROR_RETRYABLE; break;
  88. default:
  89. assert (FALSE);
  90. break;
  91. }
  92. return (hrStatus);
  93. }
  94. LPCWSTR GetStringFromFailureType (HRESULT hrStatus)
  95. {
  96. LPCWSTR pwszFailureType;
  97. switch (hrStatus)
  98. {
  99. case NOERROR: pwszFailureType = L""; break;
  100. case VSS_E_WRITERERROR_INCONSISTENTSNAPSHOT: pwszFailureType = L"InconsistentSnapshot"; break;
  101. case VSS_E_WRITERERROR_OUTOFRESOURCES: pwszFailureType = L"OutOfResources"; break;
  102. case VSS_E_WRITERERROR_TIMEOUT: pwszFailureType = L"Timeout"; break;
  103. case VSS_E_WRITERERROR_NONRETRYABLE: pwszFailureType = L"Non-Retryable"; break;
  104. case VSS_E_WRITERERROR_RETRYABLE: pwszFailureType = L"Retryable"; break;
  105. default: pwszFailureType = L"UNDEFINED"; break;
  106. }
  107. return (pwszFailureType);
  108. }
  109. LPCWSTR GetStringFromWriterType (VSS_USAGE_TYPE wtWriterType)
  110. {
  111. LPCWSTR pwszWriterType;
  112. switch (wtWriterType)
  113. {
  114. case VSS_UT_BOOTABLESYSTEMSTATE: pwszWriterType = L"BootableSystemState"; break;
  115. case VSS_UT_SYSTEMSERVICE: pwszWriterType = L"SystemServiceState"; break;
  116. case VSS_UT_USERDATA: pwszWriterType = L"UserData"; break;
  117. case VSS_UT_OTHER: pwszWriterType = L"Other"; break;
  118. default: pwszWriterType = L"UNDEFINED"; break;
  119. }
  120. return (pwszWriterType);
  121. }
  122. LPCWSTR GetStringFromFailPhase (FAIL_PHASE fpFailPhase)
  123. {
  124. LPCWSTR pwszFailPhase;
  125. switch (fpFailPhase)
  126. {
  127. case PHASE_IDENTIFY: pwszFailPhase = L"Identify"; break;
  128. case PHASE_PREPARE_FOR_BACKUP: pwszFailPhase = L"PrepareForBackup"; break;
  129. case PHASE_PREPARE_FOR_SNAPSHOT: pwszFailPhase = L"PrepareForSnapshot"; break;
  130. case PHASE_FREEZE: pwszFailPhase = L"Freeze"; break;
  131. case PHASE_THAW: pwszFailPhase = L"Thaw"; break;
  132. case PHASE_ABORT: pwszFailPhase = L"Abort"; break;
  133. case PHASE_BACKUP_COMPLETE: pwszFailPhase = L"BackupComplete"; break;
  134. case PHASE_RESTORE: pwszFailPhase = L"Restore"; break;
  135. default: pwszFailPhase = L"UNDEFINED"; break;
  136. }
  137. return (pwszFailPhase);
  138. }
  139. static volatile BOOL bContinue = TRUE;
  140. static volatile FAIL_PHASE fpFailPhase = PHASE_FREEZE;
  141. class CVssWriterFailSnap : public CVssWriter
  142. {
  143. public:
  144. bool STDMETHODCALLTYPE OnIdentify (IVssCreateWriterMetadata *pIVssCreateWriterMetadata);
  145. bool STDMETHODCALLTYPE OnPrepareBackup (IVssWriterComponents *pIVssWriterComponents);
  146. bool STDMETHODCALLTYPE OnPrepareSnapshot ();
  147. bool STDMETHODCALLTYPE OnFreeze ();
  148. bool STDMETHODCALLTYPE OnThaw ();
  149. bool STDMETHODCALLTYPE OnAbort ();
  150. bool STDMETHODCALLTYPE OnBackupComplete (IVssWriterComponents *pIVssWriterComponents);
  151. bool STDMETHODCALLTYPE OnPostRestore (IVssWriterComponents *pIVssWriterComponents);
  152. };
  153. bool STDMETHODCALLTYPE CVssWriterFailSnap::OnIdentify (IVssCreateWriterMetadata *pIVssCreateWriterMetadata)
  154. {
  155. bool bPhaseSucceeded = (PHASE_IDENTIFY != fpFailPhase);
  156. HRESULT hrStatus = SelectFailureStatus ();
  157. if (bPhaseSucceeded)
  158. {
  159. hrStatus = pIVssCreateWriterMetadata->AddComponent (VSS_CT_FILEGROUP,
  160. NULL,
  161. L"Failsnap Writer Component",
  162. L"Failsnap Writer Caption",
  163. NULL, // icon
  164. 0,
  165. true,
  166. false,
  167. false);
  168. bPhaseSucceeded = SUCCEEDED (hrStatus);
  169. }
  170. wprintf (L"\nThreadId 0x%04x - Received event - OnIdentify ()%s%s",
  171. GetCurrentThreadId (),
  172. bPhaseSucceeded ? L"" : L" - FAILED ",
  173. GetStringFromFailureType (hrStatus));
  174. if (!bPhaseSucceeded)
  175. {
  176. SetWriterFailure (hrStatus);
  177. }
  178. return (bPhaseSucceeded);
  179. }
  180. bool STDMETHODCALLTYPE CVssWriterFailSnap::OnPrepareBackup (IVssWriterComponents *pIVssWriterComponents)
  181. {
  182. bool bPhaseSucceeded = (PHASE_PREPARE_FOR_BACKUP != fpFailPhase);
  183. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  184. wprintf (L"\nThreadId 0x%04x - Received event - OnPrepareBackup ()%s%s",
  185. GetCurrentThreadId (),
  186. bPhaseSucceeded ? L"" : L" - FAILED ",
  187. GetStringFromFailureType (hrStatus));
  188. if (!bPhaseSucceeded)
  189. {
  190. SetWriterFailure (hrStatus);
  191. }
  192. return (bPhaseSucceeded);
  193. }
  194. bool STDMETHODCALLTYPE CVssWriterFailSnap::OnPrepareSnapshot ()
  195. {
  196. bool bPhaseSucceeded = (PHASE_PREPARE_FOR_SNAPSHOT != fpFailPhase);
  197. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  198. wprintf (L"\nThreadId 0x%04x - Received event - OnPrepareSnapshot ()%s%s",
  199. GetCurrentThreadId (),
  200. bPhaseSucceeded ? L"" : L" - FAILED ",
  201. GetStringFromFailureType (hrStatus));
  202. if (!bPhaseSucceeded)
  203. {
  204. SetWriterFailure (hrStatus);
  205. }
  206. return (bPhaseSucceeded);
  207. }
  208. bool STDMETHODCALLTYPE CVssWriterFailSnap::OnFreeze ()
  209. {
  210. bool bPhaseSucceeded = (PHASE_FREEZE != fpFailPhase);
  211. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  212. wprintf (L"\nThreadId 0x%04x - Received event - OnFreeze ()%s%s",
  213. GetCurrentThreadId (),
  214. bPhaseSucceeded ? L"" : L" - FAILED ",
  215. GetStringFromFailureType (hrStatus));
  216. if (!bPhaseSucceeded)
  217. {
  218. SetWriterFailure (hrStatus);
  219. }
  220. return (bPhaseSucceeded);
  221. }
  222. bool STDMETHODCALLTYPE CVssWriterFailSnap::OnThaw ()
  223. {
  224. bool bPhaseSucceeded = (PHASE_THAW != fpFailPhase);
  225. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  226. wprintf (L"\nThreadId 0x%04x - Received event - OnThaw ()%s%s",
  227. GetCurrentThreadId (),
  228. bPhaseSucceeded ? L"" : L" - FAILED ",
  229. GetStringFromFailureType (hrStatus));
  230. if (!bPhaseSucceeded)
  231. {
  232. SetWriterFailure (hrStatus);
  233. }
  234. return (bPhaseSucceeded);
  235. }
  236. bool STDMETHODCALLTYPE CVssWriterFailSnap::OnAbort ()
  237. {
  238. bool bPhaseSucceeded = (PHASE_ABORT != fpFailPhase);
  239. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  240. wprintf (L"\nThreadId 0x%04x - Received event - OnAbort ()%s%s",
  241. GetCurrentThreadId (),
  242. bPhaseSucceeded ? L"" : L" - FAILED ",
  243. GetStringFromFailureType (hrStatus));
  244. if (!bPhaseSucceeded)
  245. {
  246. SetWriterFailure (hrStatus);
  247. }
  248. return (bPhaseSucceeded);
  249. }
  250. bool STDMETHODCALLTYPE CVssWriterFailSnap::OnBackupComplete (IVssWriterComponents *pIVssWriterComponents)
  251. {
  252. bool bPhaseSucceeded = (PHASE_BACKUP_COMPLETE != fpFailPhase);
  253. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  254. wprintf (L"\nThreadId 0x%04x - Received event - OnBackupComplete ()%s%s",
  255. GetCurrentThreadId (),
  256. bPhaseSucceeded ? L"" : L" - FAILED ",
  257. GetStringFromFailureType (hrStatus));
  258. if (!bPhaseSucceeded)
  259. {
  260. SetWriterFailure (hrStatus);
  261. }
  262. return (bPhaseSucceeded);
  263. }
  264. bool STDMETHODCALLTYPE CVssWriterFailSnap::OnPostRestore (IVssWriterComponents *pIVssWriterComponents)
  265. {
  266. bool bPhaseSucceeded = (PHASE_RESTORE != fpFailPhase);
  267. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  268. wprintf (L"\nThreadId 0x%04x - Received event - OnPostRestore ()%s%s",
  269. GetCurrentThreadId (),
  270. bPhaseSucceeded ? L"" : L" - FAILED ",
  271. GetStringFromFailureType (hrStatus));
  272. if (!bPhaseSucceeded)
  273. {
  274. SetWriterFailure (hrStatus);
  275. }
  276. return (bPhaseSucceeded);
  277. }
  278. static BOOL AssertPrivilege (LPCWSTR privName)
  279. {
  280. HANDLE tokenHandle;
  281. BOOL stat = FALSE;
  282. if (OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, &tokenHandle))
  283. {
  284. LUID value;
  285. if (LookupPrivilegeValue (NULL, privName, &value))
  286. {
  287. TOKEN_PRIVILEGES newState;
  288. DWORD error;
  289. newState.PrivilegeCount = 1;
  290. newState.Privileges[0].Luid = value;
  291. newState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  292. /*
  293. ** We will always call GetLastError below, so clear
  294. ** any prior error values on this thread.
  295. */
  296. SetLastError (ERROR_SUCCESS);
  297. stat = AdjustTokenPrivileges (tokenHandle,
  298. FALSE,
  299. &newState,
  300. (DWORD)0,
  301. NULL,
  302. NULL);
  303. /*
  304. ** Supposedly, AdjustTokenPriveleges always returns TRUE
  305. ** (even when it fails). So, call GetLastError to be
  306. ** extra sure everything's cool.
  307. */
  308. if ((error = GetLastError()) != ERROR_SUCCESS)
  309. {
  310. stat = FALSE;
  311. }
  312. if (!stat)
  313. {
  314. wprintf (L"AdjustTokenPrivileges for %s failed with 0x%08X",
  315. privName,
  316. error);
  317. }
  318. }
  319. CloseHandle (tokenHandle);
  320. }
  321. return stat;
  322. }
  323. BOOL WINAPI CtrlC_HandlerRoutine (IN DWORD /* dwType */)
  324. {
  325. bContinue = FALSE;
  326. // Mark that the break was handled.
  327. return TRUE;
  328. }
  329. extern "C" int __cdecl wmain (int argc, WCHAR *argv[])
  330. {
  331. HRESULT hrStatus = NOERROR;
  332. CVssWriterFailSnap *pCVssWriterFailSnap = NULL;
  333. BOOL bSucceeded = FALSE;
  334. BOOL bComInitialized = FALSE;
  335. BOOL bSubscribed = FALSE;
  336. VSS_USAGE_TYPE wtWriterType = VSS_UT_USERDATA;
  337. const GUID guidIdWriter = {0xd335a99e,
  338. 0x57fb,
  339. 0x4b80,
  340. {0x85, 0xb1, 0x15, 0xda, 0xa7, 0xc7, 0x4e, 0x14}};
  341. srand ((unsigned)time (NULL));
  342. SetConsoleCtrlHandler(CtrlC_HandlerRoutine, TRUE);
  343. if ((argc >= 2) && (wcslen (argv[1]) > 0))
  344. {
  345. switch (*argv[1])
  346. {
  347. case L'I': case L'i': fpFailPhase = PHASE_IDENTIFY; break;
  348. case L'B': case L'b': fpFailPhase = PHASE_PREPARE_FOR_BACKUP; break;
  349. case L'S': case L's': fpFailPhase = PHASE_PREPARE_FOR_SNAPSHOT; break;
  350. case L'F': case L'f': fpFailPhase = PHASE_FREEZE; break;
  351. case L'T': case L't': fpFailPhase = PHASE_THAW; break;
  352. case L'A': case L'a': fpFailPhase = PHASE_ABORT; break;
  353. case L'C': case L'c': fpFailPhase = PHASE_BACKUP_COMPLETE; break;
  354. case L'R': case L'r': fpFailPhase = PHASE_RESTORE; break;
  355. default:
  356. wprintf (L"\nFAILSNAP [phase] [writer type]"
  357. L"\n\n\tFailPhases"
  358. L"\n\t\ti - Identify"
  359. L"\n\t\tb - PrepareForBackup"
  360. L"\n\t\ts - PrepareForSnapshot"
  361. L"\n\t\tf - Freeze (default)"
  362. L"\n\t\tt - Thaw"
  363. L"\n\t\ta - Abort"
  364. L"\n\t\tc - BackupComplete"
  365. L"\n\t\tr - PostRestore"
  366. L"\n\n\tWriterTypes"
  367. L"\n\t\tb - BootableState writer"
  368. L"\n\t\ts - ServiceState writer"
  369. L"\n\t\tu - UserData writer (default)"
  370. L"\n\t\to - Other writer"
  371. L"\n");
  372. bContinue = FALSE;
  373. break;
  374. }
  375. }
  376. if ((argc >= 3) && (wcslen (argv[2]) > 0))
  377. {
  378. switch (*argv[2])
  379. {
  380. case L'B': case L'b': wtWriterType = VSS_UT_BOOTABLESYSTEMSTATE; break;
  381. case L'S': case L's': wtWriterType = VSS_UT_SYSTEMSERVICE; break;
  382. case L'U': case L'u': wtWriterType = VSS_UT_USERDATA; break;
  383. case L'O': case L'o': wtWriterType = VSS_UT_OTHER; break;
  384. default:
  385. bContinue = FALSE;
  386. break;
  387. }
  388. }
  389. if (bContinue)
  390. {
  391. wprintf (L"\nSetting up %s writer to fail %s requests (ProcessId 0x%04x)",
  392. GetStringFromWriterType (wtWriterType),
  393. GetStringFromFailPhase (fpFailPhase),
  394. GetCurrentProcessId ());
  395. wprintf (L"\nChecking privileges");
  396. bSubscribed = AssertPrivilege (SE_BACKUP_NAME);
  397. hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
  398. if (FAILED (hrStatus))
  399. {
  400. wprintf (L"\nAssertPrivilege returned error 0x%08X", hrStatus);
  401. }
  402. }
  403. if (bContinue && SUCCEEDED (hrStatus))
  404. {
  405. wprintf (L"\nInitializing COM");
  406. hrStatus = CoInitializeEx (NULL, COINIT_MULTITHREADED);
  407. if (FAILED (hrStatus))
  408. {
  409. wprintf (L"\nCoInitialize() returned error 0x%08X", hrStatus);
  410. }
  411. else
  412. {
  413. bComInitialized = TRUE;
  414. }
  415. }
  416. if (bContinue && SUCCEEDED (hrStatus))
  417. {
  418. wprintf (L"\nConstructing Writer");
  419. pCVssWriterFailSnap = new CVssWriterFailSnap;
  420. if (NULL == pCVssWriterFailSnap)
  421. {
  422. hrStatus = HRESULT_FROM_WIN32 (ERROR_NOT_ENOUGH_MEMORY);
  423. wprintf (L"\nFailed to allocate CVssWriterFailSnap : 0x%08X", hrStatus);
  424. }
  425. }
  426. if (bContinue && SUCCEEDED (hrStatus))
  427. {
  428. WCHAR awchWriterName [256];
  429. wprintf (L"\nInitialising the writer");
  430. _snwprintf (awchWriterName,
  431. SIZEOF_ARRAY (awchWriterName),
  432. L"Microsoft Test Writer - FailSnap (%s/%s/0x%04x)",
  433. GetStringFromWriterType (wtWriterType),
  434. GetStringFromFailPhase (fpFailPhase),
  435. GetCurrentProcessId ());
  436. hrStatus = pCVssWriterFailSnap->Initialize (guidIdWriter,
  437. awchWriterName,
  438. wtWriterType,
  439. VSS_ST_OTHER);
  440. if (FAILED (hrStatus))
  441. {
  442. wprintf (L"\nFailed to initialize the writer : 0x%08X", hrStatus);
  443. }
  444. }
  445. if (bContinue && SUCCEEDED (hrStatus))
  446. {
  447. wprintf (L"\nSubscribing to snapshot events");
  448. hrStatus = pCVssWriterFailSnap->Subscribe ();
  449. if (FAILED (hrStatus))
  450. {
  451. wprintf (L"\nFailed to subscribe to snapshot events : 0x%08X", hrStatus);
  452. }
  453. else
  454. {
  455. bSubscribed = TRUE;
  456. }
  457. }
  458. if (bContinue && SUCCEEDED (hrStatus))
  459. {
  460. wprintf (L"\nWaiting for snapshot events (or Ctrl-C)");
  461. while (bContinue)
  462. {
  463. Sleep (100);
  464. }
  465. }
  466. if (bSubscribed)
  467. {
  468. wprintf (L"\nUn-Subscribing from snapshot events");
  469. pCVssWriterFailSnap->Unsubscribe ();
  470. }
  471. if (NULL != pCVssWriterFailSnap)
  472. {
  473. wprintf (L"\nDeconstructing Writer");
  474. delete pCVssWriterFailSnap;
  475. }
  476. if (bComInitialized)
  477. {
  478. wprintf (L"\nUnInitialising COM");
  479. CoUninitialize();
  480. }
  481. return (hrStatus);
  482. }