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.

685 lines
17 KiB

  1. /*
  2. **++
  3. **
  4. ** Copyright (c) 2000-2001 Microsoft Corporation
  5. **
  6. **
  7. ** Module Name:
  8. **
  9. ** waitsnap.cpp
  10. **
  11. **
  12. ** Abstract:
  13. **
  14. ** Test program that starts a VSS writer and waits upon receiving a specific event
  15. **
  16. ** Author:
  17. **
  18. ** Charles Chung [cchung] 04-Dec-2001
  19. **
  20. **
  21. ** Revision History:
  22. ** 1.0 Altered from Failsnap.cpp
  23. **
  24. **--
  25. */
  26. /*
  27. ** Defines
  28. **
  29. **
  30. ** C4290: C++ Exception Specification ignored
  31. ** warning C4511: 'CVssCOMApplication' : copy constructor could not be generated
  32. ** warning C4127: conditional expression is constant
  33. */
  34. #pragma warning(disable:4290)
  35. #pragma warning(disable:4511)
  36. #pragma warning(disable:4127)
  37. /*
  38. ** Includes
  39. */
  40. #include <windows.h>
  41. #include <wtypes.h>
  42. #include <stddef.h>
  43. #include <stdlib.h>
  44. #include <stdio.h>
  45. #include <time.h>
  46. #include <assert.h>
  47. #include <vss.h>
  48. #include <vswriter.h>
  49. #define GET_STATUS_FROM_BOOL(_bSucceeded) ((_bSucceeded) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
  50. #define GET_STATUS_FROM_HANDLE(_handle) ((NULL != (_handle)) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
  51. #define GET_STATUS_FROM_POINTER(_ptr) ((NULL != (_ptr)) ? NOERROR : E_OUTOFMEMORY)
  52. #define SIZEOF_ARRAY(_aBase) (sizeof (_aBase) / sizeof ((_aBase)[0]))
  53. typedef enum FAIL_PHASE
  54. {
  55. PHASE_UNDEFINED = 0,
  56. PHASE_IDENTIFY,
  57. PHASE_PREPARE_FOR_BACKUP,
  58. PHASE_PREPARE_FOR_SNAPSHOT,
  59. PHASE_FREEZE,
  60. PHASE_THAW,
  61. PHASE_ABORT,
  62. PHASE_BACKUP_COMPLETE,
  63. PHASE_RESTORE
  64. } FAIL_PHASE;
  65. HRESULT SelectFailureStatus (VOID)
  66. {
  67. HRESULT hrStatus;
  68. switch (rand () / (RAND_MAX / 5))
  69. {
  70. case 0: hrStatus = VSS_E_WRITERERROR_INCONSISTENTSNAPSHOT; break;
  71. case 1: hrStatus = VSS_E_WRITERERROR_OUTOFRESOURCES; break;
  72. case 2: hrStatus = VSS_E_WRITERERROR_TIMEOUT; break;
  73. case 3: hrStatus = VSS_E_WRITERERROR_NONRETRYABLE; break;
  74. case 4: hrStatus = VSS_E_WRITERERROR_RETRYABLE; break;
  75. default:
  76. assert (FALSE);
  77. break;
  78. }
  79. return (hrStatus);
  80. }
  81. void ForceSleep(INT sec)
  82. {
  83. wprintf(L"\tGoing to sleep for %d seconds...\n", sec) ;
  84. while(sec>0) {
  85. Sleep(1000) ;
  86. sec-- ;
  87. if(sec%10==0) {
  88. wprintf(L"\tSeconds left=%d\n", sec) ;
  89. }
  90. }
  91. wprintf(L"\tAwaken!\n") ;
  92. }
  93. LPCWSTR GetStringFromFailureType (HRESULT hrStatus)
  94. {
  95. LPCWSTR pwszFailureType;
  96. switch (hrStatus)
  97. {
  98. case NOERROR: pwszFailureType = L""; break;
  99. case VSS_E_WRITERERROR_INCONSISTENTSNAPSHOT: pwszFailureType = L"InconsistentSnapshot"; break;
  100. case VSS_E_WRITERERROR_OUTOFRESOURCES: pwszFailureType = L"OutOfResources"; break;
  101. case VSS_E_WRITERERROR_TIMEOUT: pwszFailureType = L"Timeout"; break;
  102. case VSS_E_WRITERERROR_NONRETRYABLE: pwszFailureType = L"Non-Retryable"; break;
  103. case VSS_E_WRITERERROR_RETRYABLE: pwszFailureType = L"Retryable"; break;
  104. default: pwszFailureType = L"UNDEFINED"; break;
  105. }
  106. return (pwszFailureType);
  107. }
  108. LPCWSTR GetStringFromWriterType (VSS_USAGE_TYPE wtWriterType)
  109. {
  110. LPCWSTR pwszWriterType;
  111. switch (wtWriterType)
  112. {
  113. case VSS_UT_BOOTABLESYSTEMSTATE: pwszWriterType = L"BootableSystemState"; break;
  114. case VSS_UT_SYSTEMSERVICE: pwszWriterType = L"SystemServiceState"; break;
  115. case VSS_UT_USERDATA: pwszWriterType = L"UserData"; break;
  116. case VSS_UT_OTHER: pwszWriterType = L"Other"; break;
  117. default: pwszWriterType = L"UNDEFINED"; break;
  118. }
  119. return (pwszWriterType);
  120. }
  121. LPCWSTR GetStringFromWaitPhase (FAIL_PHASE fpWaitPhase)
  122. {
  123. LPCWSTR pwszWaitPhase;
  124. switch (fpWaitPhase)
  125. {
  126. case PHASE_IDENTIFY: pwszWaitPhase = L"Identify"; break;
  127. case PHASE_PREPARE_FOR_BACKUP: pwszWaitPhase = L"PrepareForBackup"; break;
  128. case PHASE_PREPARE_FOR_SNAPSHOT: pwszWaitPhase = L"PrepareForSnapshot"; break;
  129. case PHASE_FREEZE: pwszWaitPhase = L"Freeze"; break;
  130. case PHASE_THAW: pwszWaitPhase = L"Thaw"; break;
  131. case PHASE_ABORT: pwszWaitPhase = L"Abort"; break;
  132. case PHASE_BACKUP_COMPLETE: pwszWaitPhase = L"BackupComplete"; break;
  133. case PHASE_RESTORE: pwszWaitPhase = L"Restore"; break;
  134. default: pwszWaitPhase = L"UNDEFINED"; break;
  135. }
  136. return (pwszWaitPhase);
  137. }
  138. static volatile BOOL bContinue = TRUE;
  139. static volatile FAIL_PHASE fpWaitPhase = PHASE_FREEZE;
  140. static volatile INT nWaitTime = 10 ;
  141. class CVssWriterWaitsnap : 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 CVssWriterWaitsnap::OnIdentify (IVssCreateWriterMetadata *pIVssCreateWriterMetadata)
  154. {
  155. bool bPhaseSucceeded = (PHASE_IDENTIFY != fpWaitPhase);
  156. HRESULT hrStatus = SelectFailureStatus ();
  157. if (bPhaseSucceeded)
  158. {
  159. hrStatus = pIVssCreateWriterMetadata->AddComponent (VSS_CT_FILEGROUP,
  160. NULL,
  161. L"Waitsnap Writer Component",
  162. L"Waitsnap 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\n",
  171. GetCurrentThreadId (),
  172. bPhaseSucceeded ? L"" : L" - FAILED ",
  173. GetStringFromFailureType (hrStatus));
  174. if (!bPhaseSucceeded)
  175. {
  176. ForceSleep(nWaitTime) ;
  177. }
  178. return (TRUE);
  179. }
  180. bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnPrepareBackup (IVssWriterComponents *pIVssWriterComponents)
  181. {
  182. bool bPhaseSucceeded = (PHASE_PREPARE_FOR_BACKUP != fpWaitPhase);
  183. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  184. wprintf (L"\nThreadId 0x%04x - Received event - OnPrepareBackup ()%s%s\n",
  185. GetCurrentThreadId (),
  186. bPhaseSucceeded ? L"" : L" - FAILED ",
  187. GetStringFromFailureType (hrStatus));
  188. if (!bPhaseSucceeded)
  189. {
  190. ForceSleep(nWaitTime) ;
  191. }
  192. return (TRUE);
  193. }
  194. bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnPrepareSnapshot ()
  195. {
  196. bool bPhaseSucceeded = (PHASE_PREPARE_FOR_SNAPSHOT != fpWaitPhase);
  197. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  198. wprintf (L"\nThreadId 0x%04x - Received event - OnPrepareSnapshot ()%s%s\n",
  199. GetCurrentThreadId (),
  200. bPhaseSucceeded ? L"" : L" - FAILED ",
  201. GetStringFromFailureType (hrStatus));
  202. if (!bPhaseSucceeded)
  203. {
  204. ForceSleep(nWaitTime) ;
  205. }
  206. return (TRUE);
  207. }
  208. bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnFreeze ()
  209. {
  210. bool bPhaseSucceeded = (PHASE_FREEZE != fpWaitPhase);
  211. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  212. wprintf (L"\nThreadId 0x%04x - Received event - OnFreeze ()%s%s\n",
  213. GetCurrentThreadId (),
  214. bPhaseSucceeded ? L"" : L" - FAILED ",
  215. GetStringFromFailureType (hrStatus));
  216. if (!bPhaseSucceeded)
  217. {
  218. ForceSleep(nWaitTime) ;
  219. }
  220. return (TRUE);
  221. }
  222. bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnThaw ()
  223. {
  224. bool bPhaseSucceeded = (PHASE_THAW != fpWaitPhase);
  225. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  226. wprintf (L"\nThreadId 0x%04x - Received event - OnThaw ()%s%s\n",
  227. GetCurrentThreadId (),
  228. bPhaseSucceeded ? L"" : L" - FAILED ",
  229. GetStringFromFailureType (hrStatus));
  230. if (!bPhaseSucceeded)
  231. {
  232. ForceSleep(nWaitTime) ;
  233. }
  234. return (TRUE);
  235. }
  236. bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnAbort ()
  237. {
  238. bool bPhaseSucceeded = (PHASE_ABORT != fpWaitPhase);
  239. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  240. wprintf (L"\nThreadId 0x%04x - Received event - OnAbort ()%s%s\n",
  241. GetCurrentThreadId (),
  242. bPhaseSucceeded ? L"" : L" - FAILED ",
  243. GetStringFromFailureType (hrStatus));
  244. if (!bPhaseSucceeded)
  245. {
  246. ForceSleep(nWaitTime) ;
  247. }
  248. return (TRUE);
  249. }
  250. bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnBackupComplete (IVssWriterComponents *pIVssWriterComponents)
  251. {
  252. bool bPhaseSucceeded = (PHASE_BACKUP_COMPLETE != fpWaitPhase);
  253. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  254. wprintf (L"\nThreadId 0x%04x - Received event - OnBackupComplete ()%s%s\n",
  255. GetCurrentThreadId (),
  256. bPhaseSucceeded ? L"" : L" - FAILED ",
  257. GetStringFromFailureType (hrStatus));
  258. if (!bPhaseSucceeded)
  259. {
  260. ForceSleep(nWaitTime) ;
  261. }
  262. return (TRUE);
  263. }
  264. bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnPostRestore (IVssWriterComponents *pIVssWriterComponents)
  265. {
  266. bool bPhaseSucceeded = (PHASE_RESTORE != fpWaitPhase);
  267. HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
  268. wprintf (L"\nThreadId 0x%04x - Received event - OnPostRestore ()%s%s\n",
  269. GetCurrentThreadId (),
  270. bPhaseSucceeded ? L"" : L" - FAILED ",
  271. GetStringFromFailureType (hrStatus));
  272. if (!bPhaseSucceeded)
  273. {
  274. ForceSleep(nWaitTime) ;
  275. }
  276. return (TRUE);
  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. CVssWriterWaitsnap *pCVssWriterWaitsnap = 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. //get the stage which the writer is to fail
  346. switch (*argv[1])
  347. {
  348. case L'I': case L'i': fpWaitPhase = PHASE_IDENTIFY; break;
  349. case L'B': case L'b': fpWaitPhase = PHASE_PREPARE_FOR_BACKUP; break;
  350. case L'S': case L's': fpWaitPhase = PHASE_PREPARE_FOR_SNAPSHOT; break;
  351. case L'F': case L'f': fpWaitPhase = PHASE_FREEZE; break;
  352. case L'T': case L't': fpWaitPhase = PHASE_THAW; break;
  353. case L'A': case L'a': fpWaitPhase = PHASE_ABORT; break;
  354. case L'C': case L'c': fpWaitPhase = PHASE_BACKUP_COMPLETE; break;
  355. case L'R': case L'r': fpWaitPhase = PHASE_RESTORE; break;
  356. default:
  357. wprintf (L"\nWAITSNAP [phase] [writer type] [sec to wait]"
  358. L"\n\n\tWaitPhases"
  359. L"\n\t\ti - Identify"
  360. L"\n\t\tb - PrepareForBackup"
  361. L"\n\t\ts - PrepareForSnapshot"
  362. L"\n\t\tf - Freeze (default)"
  363. L"\n\t\tt - Thaw"
  364. L"\n\t\ta - Abort"
  365. L"\n\t\tc - BackupComplete"
  366. L"\n\t\tr - PostRestore"
  367. L"\n\n\tWriterTypes"
  368. L"\n\t\tb - BootableState writer"
  369. L"\n\t\ts - ServiceState writer"
  370. L"\n\t\tu - UserData writer (default)"
  371. L"\n\t\to - Other writer"
  372. L"\n");
  373. bContinue = FALSE;
  374. break;
  375. }
  376. //get the amount of time the stage is to wait
  377. }
  378. if ((argc >= 3) && (wcslen (argv[2]) > 0))
  379. {
  380. switch (*argv[2])
  381. {
  382. case L'B': case L'b': wtWriterType = VSS_UT_BOOTABLESYSTEMSTATE; break;
  383. case L'S': case L's': wtWriterType = VSS_UT_SYSTEMSERVICE; break;
  384. case L'U': case L'u': wtWriterType = VSS_UT_USERDATA; break;
  385. case L'O': case L'o': wtWriterType = VSS_UT_OTHER; break;
  386. default:
  387. bContinue = FALSE;
  388. break;
  389. }
  390. }
  391. //get the amount of seconds to wait
  392. if ((argc >= 4) && (wcslen (argv[3]) > 0))
  393. {
  394. nWaitTime=_wtoi(argv[3]) ;
  395. }
  396. if (bContinue)
  397. {
  398. wprintf (L"\nSetting up %s writer to wait %s requests (ProcessId 0x%04x) for %d seconds",
  399. GetStringFromWriterType (wtWriterType),
  400. GetStringFromWaitPhase (fpWaitPhase),
  401. GetCurrentProcessId (),
  402. nWaitTime);
  403. wprintf (L"\nChecking privileges");
  404. bSubscribed = AssertPrivilege (SE_BACKUP_NAME);
  405. hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
  406. if (FAILED (hrStatus))
  407. {
  408. wprintf (L"\nAssertPrivilege returned error 0x%08X", hrStatus);
  409. }
  410. }
  411. if (bContinue && SUCCEEDED (hrStatus))
  412. {
  413. wprintf (L"\nInitializing COM");
  414. hrStatus = CoInitializeEx (NULL, COINIT_MULTITHREADED);
  415. if (FAILED (hrStatus))
  416. {
  417. wprintf (L"\nCoInitialize() returned error 0x%08X", hrStatus);
  418. }
  419. else
  420. {
  421. bComInitialized = TRUE;
  422. }
  423. }
  424. if (bContinue && SUCCEEDED (hrStatus))
  425. {
  426. wprintf (L"\nConstructing Writer");
  427. pCVssWriterWaitsnap = new CVssWriterWaitsnap;
  428. if (NULL == pCVssWriterWaitsnap)
  429. {
  430. hrStatus = HRESULT_FROM_WIN32 (ERROR_NOT_ENOUGH_MEMORY);
  431. wprintf (L"\nFailed to allocate CVssWriterWaitsnap : 0x%08X", hrStatus);
  432. }
  433. }
  434. if (bContinue && SUCCEEDED (hrStatus))
  435. {
  436. WCHAR awchWriterName [256];
  437. wprintf (L"\nInitialising the writer");
  438. _snwprintf (awchWriterName,
  439. SIZEOF_ARRAY (awchWriterName),
  440. L"Microsoft Test Writer - Waitsnap (%s/%s/0x%04x)",
  441. GetStringFromWriterType (wtWriterType),
  442. GetStringFromWaitPhase (fpWaitPhase),
  443. GetCurrentProcessId ());
  444. hrStatus = pCVssWriterWaitsnap->Initialize (guidIdWriter,
  445. awchWriterName,
  446. wtWriterType,
  447. VSS_ST_OTHER);
  448. if (FAILED (hrStatus))
  449. {
  450. wprintf (L"\nFailed to initialize the writer : 0x%08X", hrStatus);
  451. }
  452. }
  453. if (bContinue && SUCCEEDED (hrStatus))
  454. {
  455. wprintf (L"\nSubscribing to snapshot events");
  456. hrStatus = pCVssWriterWaitsnap->Subscribe ();
  457. if (FAILED (hrStatus))
  458. {
  459. wprintf (L"\nFailed to subscribe to snapshot events : 0x%08X", hrStatus);
  460. }
  461. else
  462. {
  463. bSubscribed = TRUE;
  464. }
  465. }
  466. if (bContinue && SUCCEEDED (hrStatus))
  467. {
  468. wprintf (L"\nWaiting for snapshot events (or Ctrl-C)");
  469. while (bContinue)
  470. {
  471. Sleep (100);
  472. }
  473. }
  474. if (bSubscribed)
  475. {
  476. wprintf (L"\nUn-Subscribing from snapshot events");
  477. pCVssWriterWaitsnap->Unsubscribe ();
  478. }
  479. if (NULL != pCVssWriterWaitsnap)
  480. {
  481. wprintf (L"\nDeconstructing Writer");
  482. delete pCVssWriterWaitsnap;
  483. }
  484. if (bComInitialized)
  485. {
  486. wprintf (L"\nUnInitialising COM");
  487. CoUninitialize();
  488. }
  489. return (hrStatus);
  490. }