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.

971 lines
22 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. controller.cpp
  5. Abstract:
  6. main module of controller exe
  7. Brian Berkowitz [brianb] 05/23/2000
  8. TBD:
  9. Revision History:
  10. Name Date Comments
  11. brianb 05/23/2000 Created
  12. --*/
  13. #include <stdafx.h>
  14. #include <bsstring.hxx>
  15. #include <vststmsg.hxx>
  16. #include <tstiniconfig.hxx>
  17. #include <vststmsghandler.hxx>
  18. #include <vststprocess.hxx>
  19. #include <winsvc.h>
  20. #include <vss.h>
  21. #include <vscoordint.h>
  22. #include <vststutil.hxx>
  23. #ifdef _DEBUG
  24. #pragma warning(disable: 4701) // local variable *may* be used without init
  25. #endif
  26. CVsTstNtLog *g_pcTstNtLog = NULL;
  27. void LogUnexpectedFailure(LPCWSTR, ...);
  28. static LPCWSTR x_wszVssTestController = L"VssTestController.";
  29. static LPCWSTR x_wszVssTestRequestor = L"VssTestRequestor.";
  30. static LPCWSTR x_wszVssTestWriter = L"VssTestWriter.";
  31. static LPCWSTR x_wszProcessExecutable = L"ProcessExecutable";
  32. static LPCWSTR x_wszMaxTestTime = L"MaxTestTime";
  33. static LPCWSTR x_wszProcessesToStart = L"ProcessesToStart";
  34. static LPCWSTR x_wszProcessCommandLine = L"ProcessCommandLine";
  35. static LPCWSTR x_wszConformingExecutable = L"ConformingExecutable";
  36. static LPCWSTR x_wszCoordinatorStart = L"CoordinatorStart";
  37. static LPCWSTR x_wszNo = L"No";
  38. static LPCWSTR x_wszStart = L"Start";
  39. static LPCWSTR x_wszStop = L"Stop";
  40. static LPCWSTR x_wszRestart = L"Restart";
  41. static LPCWSTR x_wszDeleteExistingSnapshots = L"DeleteExistingSnapshots";
  42. // name of volume snapshot service
  43. static LPCWSTR x_wszVSS = L"VSS";
  44. BOOL EnableDebugPriv(VOID)
  45. /*++
  46. Routine Description:
  47. Changes the process's privilege so that controller works properly.
  48. Arguments:
  49. Return Value:
  50. TRUE - success
  51. FALSE - failure
  52. --*/
  53. {
  54. HANDLE hToken;
  55. LUID DebugValue;
  56. TOKEN_PRIVILEGES tkp;
  57. //
  58. // Enable the SE_DEBUG_NAME privilege
  59. //
  60. if (!LookupPrivilegeValue
  61. (
  62. NULL,
  63. SE_DEBUG_NAME,
  64. &DebugValue
  65. ))
  66. {
  67. LogUnexpectedFailure(L"LookupPrivilegeValue failed with %d\n", GetLastError());
  68. return FALSE;
  69. }
  70. //
  71. // Retrieve a handle of the access token
  72. //
  73. if (!OpenProcessToken
  74. (
  75. GetCurrentProcess(),
  76. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  77. &hToken
  78. ))
  79. {
  80. LogUnexpectedFailure(L"OpenProcessToken failed with %d\n", GetLastError());
  81. return FALSE;
  82. }
  83. tkp.PrivilegeCount = 1;
  84. tkp.Privileges[0].Luid = DebugValue;
  85. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  86. AdjustTokenPrivileges
  87. (
  88. hToken,
  89. FALSE,
  90. &tkp,
  91. sizeof(TOKEN_PRIVILEGES),
  92. (PTOKEN_PRIVILEGES) NULL,
  93. (PDWORD) NULL
  94. );
  95. DWORD dwErr = GetLastError();
  96. CloseHandle(hToken);
  97. //
  98. // The return value of AdjustTokenPrivileges can't be tested
  99. //
  100. if (dwErr != ERROR_SUCCESS)
  101. {
  102. LogUnexpectedFailure(L"AdjustTokenPrivileges failed with %d\n", dwErr);
  103. return FALSE;
  104. }
  105. return TRUE;
  106. }
  107. // stop and possibly restart the service
  108. // if bTerminateIfCantStop is true, then try terminating the process
  109. // if bRestart is true, then try restarting the process if it was
  110. // able to be stopped or terminated.
  111. HRESULT StartStopVssService
  112. (
  113. bool bStop,
  114. bool bTerminateIfCantStop,
  115. bool bRestart
  116. )
  117. {
  118. SC_HANDLE hSCM = NULL;
  119. SC_HANDLE hService = NULL;
  120. HANDLE hProcess = NULL;
  121. HRESULT hr = S_OK;
  122. try
  123. {
  124. SERVICE_STATUS_PROCESS info;
  125. DWORD cbNeeded;
  126. hSCM = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
  127. if (hSCM == NULL)
  128. {
  129. DWORD dwErr = GetLastError();
  130. LogUnexpectedFailure(L"OpenSCManager failed with error code %d.", dwErr);
  131. throw(HRESULT_FROM_WIN32(dwErr));
  132. }
  133. hService = OpenService(hSCM, x_wszVSS, SERVICE_START|SERVICE_STOP|SERVICE_QUERY_STATUS);
  134. if (hService == NULL)
  135. {
  136. DWORD dwErr = GetLastError();
  137. LogUnexpectedFailure(L"OpenService failed with error code %d.", dwErr);
  138. throw(HRESULT_FROM_WIN32(dwErr));
  139. }
  140. if (bStop)
  141. {
  142. for(UINT i = 0; i < 10; i++)
  143. {
  144. if (!QueryServiceStatusEx
  145. (
  146. hService,
  147. SC_STATUS_PROCESS_INFO,
  148. (LPBYTE) &info,
  149. sizeof(info),
  150. &cbNeeded
  151. ))
  152. {
  153. DWORD dwErr = GetLastError();
  154. LogUnexpectedFailure(L"QueryServiceStatusEx failed with error code %d.", dwErr);
  155. throw(HRESULT_FROM_WIN32(dwErr));
  156. }
  157. if (info.dwCurrentState == SERVICE_STOPPED)
  158. break;
  159. if (info.dwCurrentState != SERVICE_STOP_PENDING)
  160. {
  161. SERVICE_STATUS status;
  162. if (!ControlService
  163. (
  164. hService,
  165. SERVICE_CONTROL_STOP,
  166. &status
  167. ))
  168. {
  169. DWORD dwErr = GetLastError();
  170. if (dwErr != ERROR_SERVICE_NOT_ACTIVE &&
  171. dwErr != ERROR_SERVICE_CANNOT_ACCEPT_CTRL)
  172. {
  173. LogUnexpectedFailure(L"ServiceControl failed with error %d", dwErr);
  174. throw(HRESULT_FROM_WIN32(dwErr));
  175. }
  176. }
  177. }
  178. Sleep(6000);
  179. }
  180. if (info.dwCurrentState != SERVICE_STOPPED &&
  181. bTerminateIfCantStop)
  182. {
  183. if (info.dwServiceType != SERVICE_WIN32_OWN_PROCESS)
  184. {
  185. LogUnexpectedFailure(L"Service %s is not running in its own process", x_wszVSS);
  186. throw(E_FAIL);
  187. }
  188. hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, info.dwProcessId);
  189. if (hProcess == NULL)
  190. {
  191. DWORD dwErr = GetLastError();
  192. if (dwErr != ERROR_PROCESS_ABORTED)
  193. {
  194. LogUnexpectedFailure(L"OpenProcess failed with error %d", dwErr);
  195. throw(HRESULT_FROM_WIN32(dwErr));
  196. }
  197. }
  198. else
  199. {
  200. if (!TerminateProcess(hProcess, 0xffffffff))
  201. {
  202. DWORD dwErr = GetLastError();
  203. if (dwErr != ERROR_PROCESS_ABORTED)
  204. {
  205. LogUnexpectedFailure(L"TerminateProcess failed with error %d", dwErr);
  206. throw(HRESULT_FROM_WIN32(dwErr));
  207. }
  208. }
  209. }
  210. }
  211. }
  212. if (bRestart)
  213. {
  214. bool bStopped = true;
  215. if (!bStop)
  216. {
  217. if (!QueryServiceStatusEx
  218. (
  219. hService,
  220. SC_STATUS_PROCESS_INFO,
  221. (LPBYTE) &info,
  222. sizeof(info),
  223. &cbNeeded
  224. ))
  225. {
  226. DWORD dwErr = GetLastError();
  227. LogUnexpectedFailure(L"QueryServiceStatusEx failed with error code %d.", dwErr);
  228. throw(HRESULT_FROM_WIN32(dwErr));
  229. }
  230. if (info.dwCurrentState == SERVICE_RUNNING ||
  231. info.dwCurrentState == SERVICE_START_PENDING)
  232. bStopped = false;
  233. }
  234. if (bStopped)
  235. {
  236. if (!StartService(hService, 0, NULL))
  237. {
  238. DWORD dwErr = GetLastError();
  239. LogUnexpectedFailure(L"ServiceStart failed with error %d.", dwErr);
  240. throw(HRESULT_FROM_WIN32(dwErr));
  241. }
  242. }
  243. for(UINT i = 0; i < 10; i++)
  244. {
  245. if (!QueryServiceStatusEx
  246. (
  247. hService,
  248. SC_STATUS_PROCESS_INFO,
  249. (LPBYTE) &info,
  250. sizeof(info),
  251. &cbNeeded
  252. ))
  253. {
  254. DWORD dwErr = GetLastError();
  255. LogUnexpectedFailure(L"QueryServiceStatusEx failed with error code %d.", dwErr);
  256. throw(HRESULT_FROM_WIN32(dwErr));
  257. }
  258. if (info.dwCurrentState == SERVICE_RUNNING)
  259. break;
  260. else if (info.dwCurrentState != SERVICE_START_PENDING)
  261. {
  262. LogUnexpectedFailure(L"Cannot start service %s.", x_wszVSS);
  263. throw(E_FAIL);
  264. }
  265. Sleep(6000);
  266. }
  267. }
  268. }
  269. catch(HRESULT hrFailure)
  270. {
  271. hr = hrFailure;
  272. }
  273. catch(...)
  274. {
  275. hr = E_UNEXPECTED;
  276. }
  277. if (hProcess)
  278. CloseHandle(hProcess);
  279. if (hService)
  280. CloseServiceHandle(hService);
  281. if (hSCM)
  282. CloseServiceHandle(hSCM);
  283. return hr;
  284. }
  285. void StartupProcess
  286. (
  287. CVsTstProcessList &processList,
  288. LPCWSTR wszSectionName,
  289. UINT maxTestTime,
  290. LPCWSTR wszScenarioFile
  291. )
  292. {
  293. ULONGLONG processId;
  294. LPCWSTR wszQualifier;
  295. EVsTstINISectionType sectionType;
  296. VSTST_PROCESS_TYPE processType;
  297. if (memcmp(wszSectionName, x_wszVssTestWriter, wcslen(x_wszVssTestWriter) * sizeof(WCHAR)) == 0)
  298. {
  299. sectionType = eVsTstSectionType_TestWriter;
  300. processType = VSTST_PT_WRITER;
  301. wszQualifier = wszSectionName + wcslen(x_wszVssTestWriter);
  302. }
  303. else if (memcmp(wszSectionName, x_wszVssTestRequestor, wcslen(x_wszVssTestRequestor)) == 0)
  304. {
  305. sectionType = eVsTstSectionType_TestRequesterApp;
  306. wszQualifier = wszSectionName + wcslen(x_wszVssTestRequestor);
  307. processType = VSTST_PT_BACKUP;
  308. }
  309. CVsTstINIConfig config
  310. (
  311. sectionType,
  312. wszQualifier,
  313. false,
  314. wszScenarioFile
  315. );
  316. CBsString bssExeName;
  317. config.GetOptionValue(x_wszProcessExecutable, &bssExeName);
  318. EVsTstINIBoolType boolVal;
  319. config.GetOptionValue(x_wszConformingExecutable, &boolVal);
  320. CBsString bssCmdLine;
  321. config.GetOptionValue(x_wszProcessCommandLine, &bssCmdLine);
  322. bool bConforming = boolVal == eVsTstBool_True;
  323. if (bConforming)
  324. {
  325. processType = (processType == VSTST_PT_WRITER)
  326. ? VSTST_PT_TESTWRITER : VSTST_PT_TESTBACKUP;
  327. g_pcTstNtLog->Log( eSevLev_Info, L"Controller: Conforming exe: '%s', cmdline: '%s'",
  328. bssExeName.c_str(), bssCmdLine.c_str() );
  329. processList.CreateConformingExe
  330. (
  331. processType,
  332. VSTST_AT_ADMIN,
  333. bssExeName,
  334. wszScenarioFile,
  335. wszSectionName,
  336. (UINT) -1,
  337. maxTestTime,
  338. false,
  339. NULL,
  340. processId
  341. );
  342. if(processType == VSTST_PT_WRITER || processType == VSTST_PT_TESTWRITER)
  343. Sleep(10000);
  344. }
  345. else
  346. processList.CreateNonConformingExe
  347. (
  348. processType,
  349. VSTST_AT_ADMIN,
  350. bssCmdLine,
  351. maxTestTime,
  352. NULL,
  353. processId
  354. );
  355. }
  356. void DeleteExistingSnapshots()
  357. {
  358. CComPtr<IVssCoordinator> pCoord;
  359. HRESULT hrResult = S_OK;
  360. HRESULT hr = CoCreateInstance
  361. (
  362. CLSID_VSSCoordinator,
  363. NULL,
  364. CLSCTX_LOCAL_SERVER,
  365. IID_IVssCoordinator,
  366. (void **) &pCoord
  367. );
  368. if (FAILED(hr))
  369. {
  370. LogUnexpectedFailure(L"CoCreating the coordinator failed. hr = 0x%08lx", hr);
  371. throw(hr);
  372. }
  373. WCHAR bufVolume[MAX_PATH];
  374. HANDLE hVolumes = FindFirstVolume(bufVolume, sizeof(bufVolume));
  375. if (hVolumes == INVALID_HANDLE_VALUE)
  376. {
  377. DWORD dwErr = GetLastError();
  378. LogUnexpectedFailure(L"FindFirstVolume failed with error %d", dwErr);
  379. throw(HRESULT_FROM_WIN32(dwErr));
  380. }
  381. try
  382. {
  383. do
  384. {
  385. WCHAR wszVolume[MAX_PATH];
  386. if (!GetVolumeNameForVolumeMountPoint
  387. (
  388. bufVolume,
  389. wszVolume,
  390. sizeof(wszVolume)/sizeof(WCHAR)
  391. ))
  392. {
  393. DWORD dwErr = GetLastError();
  394. LogUnexpectedFailure(L"GetVolumeNameFromVolumeMountPoint failed with error %d", dwErr);
  395. throw(HRESULT_FROM_WIN32(dwErr));
  396. }
  397. if (wszVolume[wcslen(wszVolume) - 1] == L'\\')
  398. wszVolume[wcslen(wszVolume) - 1] = L'\0';
  399. VSTST_ASSERT(memcmp(wszVolume, L"\\\\?\\Volume{", 22) == 0);
  400. LPCWSTR wsz = wszVolume + 10;
  401. VSTST_ASSERT(wsz[wcslen(wsz) - 1] == L'}');
  402. CVssID id;
  403. id.Initialize(wsz, E_OUTOFMEMORY);
  404. LONG lDeletedSnapshots;
  405. VSS_ID SnapshotIDNotDeleted;
  406. hr = pCoord->DeleteSnapshots
  407. (
  408. id,
  409. VSS_OBJECT_VOLUME,
  410. false,
  411. &lDeletedSnapshots,
  412. &SnapshotIDNotDeleted
  413. );
  414. } while(FindNextVolume(hVolumes, bufVolume, sizeof(bufVolume)));
  415. DWORD dwErr = GetLastError();
  416. if (dwErr != ERROR_NO_MORE_FILES)
  417. {
  418. LogUnexpectedFailure(L"FindNextVolume failed with error %d", GetLastError());
  419. throw(HRESULT_FROM_WIN32(dwErr));
  420. }
  421. }
  422. catch(HRESULT hr)
  423. {
  424. hrResult = hr;
  425. }
  426. catch(...)
  427. {
  428. LogUnexpectedFailure(L"DeleteExistingSnapshots got unexpected exception");
  429. hrResult = E_UNEXPECTED;
  430. }
  431. FindVolumeClose(hVolumes);
  432. if (FAILED(hrResult))
  433. throw(hrResult);
  434. }
  435. void RunScenario(LPCWSTR wszScenarioFile, LPCWSTR wszSectionName)
  436. {
  437. try
  438. {
  439. CVsTstINIConfig config
  440. (
  441. eVsTstSectionType_TestCoordinator,
  442. wszSectionName,
  443. FALSE,
  444. wszScenarioFile
  445. );
  446. EVsTstINIBoolType boolVal;
  447. config.GetOptionValue(x_wszDeleteExistingSnapshots, &boolVal);
  448. if (boolVal == eVsTstBool_True)
  449. DeleteExistingSnapshots();
  450. LONGLONG llTestTime, llMaxTestTime;
  451. CBsString bssProcesses;
  452. CBsString bssCoordinatorStart;
  453. config.GetOptionValue(x_wszMaxTestTime, &llTestTime, &llMaxTestTime);
  454. // stop, start, or restart coordinator service based on
  455. // configuration
  456. config.GetOptionValue(x_wszCoordinatorStart, &bssCoordinatorStart);
  457. if (wcscmp(bssCoordinatorStart, x_wszStop) == 0)
  458. StartStopVssService(true, true, false);
  459. else if (wcscmp(bssCoordinatorStart, x_wszStart) == 0)
  460. StartStopVssService(false, false, true);
  461. else if (wcscmp(bssCoordinatorStart, x_wszRestart) == 0)
  462. StartStopVssService(true, true, true);
  463. config.GetOptionValue(x_wszProcessesToStart, &bssProcesses);
  464. bssProcesses.CopyBeforeWrite();
  465. CVsTstProcessList processList;
  466. HANDLE hevtDone = CreateEvent(NULL, TRUE, FALSE, NULL);
  467. if (hevtDone == NULL)
  468. {
  469. LogUnexpectedFailure(L"Cannot create termination event for reason %d", GetLastError());
  470. exit(-1);
  471. }
  472. processList.Initialize((UINT) llTestTime, hevtDone);
  473. LPCWSTR wsz = bssProcesses;
  474. LPCWSTR wszTop = wsz;
  475. if (wsz == NULL || *wsz == L'\0')
  476. {
  477. LogUnexpectedFailure(L"no processes to start");
  478. exit(-1);
  479. }
  480. bool fMoreToRun = true;
  481. while(fMoreToRun)
  482. {
  483. while(*wsz == L' ')
  484. wsz++;
  485. LPCWSTR pwc = wsz;
  486. while(*pwc != L'\0' && *pwc != L',')
  487. pwc++;
  488. if (*pwc == L'\0')
  489. fMoreToRun = false;
  490. else
  491. bssProcesses.SetAt((UINT) (pwc - wszTop), L'\0');
  492. g_pcTstNtLog->Log( eSevLev_Info, L"Controller: Starting process '%s'", wsz );
  493. StartupProcess
  494. (
  495. processList,
  496. wsz,
  497. (UINT) llTestTime,
  498. wszScenarioFile
  499. );
  500. wsz = pwc + 1;
  501. }
  502. WaitForSingleObject(hevtDone, INFINITE);
  503. }
  504. catch(...)
  505. {
  506. LogUnexpectedFailure(L"Failure running scenario %s.%s.", wszScenarioFile, wszSectionName);
  507. }
  508. }
  509. class CSeriesReader
  510. {
  511. public:
  512. CSeriesReader(HANDLE hFile, LPCWSTR wszFile) :
  513. m_hFile(hFile),
  514. m_pch((char *) m_buf),
  515. m_pchEnd((char *) m_buf),
  516. m_fMoreToRead(true),
  517. m_wszFile(wszFile)
  518. {
  519. }
  520. ~CSeriesReader()
  521. {
  522. CloseHandle(m_hFile);
  523. }
  524. bool FillBuffer();
  525. bool TrimSpaces(bool fStopAtEol);
  526. bool ReadToComma(LPSTR *pszRead);
  527. private:
  528. // buffer
  529. BYTE m_buf[1024];
  530. // current position
  531. char *m_pch;
  532. // end of buffer
  533. char *m_pchEnd;
  534. // where to preserve from when filling buffer
  535. char *m_pchPreserve;
  536. // is there more to read
  537. bool m_fMoreToRead;
  538. // handle to file
  539. HANDLE m_hFile;
  540. // file name
  541. LPCWSTR m_wszFile;
  542. };
  543. bool CSeriesReader::FillBuffer()
  544. {
  545. if (!m_fMoreToRead)
  546. return false;
  547. DWORD cbPreserved = m_pch - m_pchPreserve;
  548. DWORD cbRead;
  549. memmove(m_buf, m_pchPreserve, cbPreserved);
  550. if (!ReadFile
  551. (
  552. m_hFile,
  553. m_buf + cbPreserved,
  554. // allow trailing null to be placed in buffer
  555. sizeof(m_buf) - cbPreserved - 1,
  556. &cbRead,
  557. NULL
  558. ))
  559. LogUnexpectedFailure(L"Failure to read %s due to error %d", m_wszFile, GetLastError());
  560. m_pch = (char *) m_buf + cbPreserved;
  561. m_pchEnd = (char *) m_buf + cbPreserved + cbRead;
  562. if (cbRead == 0)
  563. {
  564. DWORD dwErr = GetLastError();
  565. if (dwErr == ERROR_HANDLE_EOF)
  566. m_fMoreToRead = false;
  567. else
  568. LogUnexpectedFailure(L"Read failure %d.", dwErr);
  569. return false;
  570. }
  571. else if (cbRead + cbPreserved < sizeof(m_buf) - 1)
  572. m_fMoreToRead = false;
  573. return true;
  574. }
  575. bool CSeriesReader::TrimSpaces(bool fStopAtEol)
  576. {
  577. while(TRUE)
  578. {
  579. if (m_pch >= m_pchEnd)
  580. {
  581. m_pchPreserve = m_pch;
  582. if (!FillBuffer())
  583. return false;
  584. }
  585. if (*m_pch == ' ' ||
  586. *m_pch == '\t')
  587. m_pch++;
  588. else if (*m_pch == '\r' ||
  589. *m_pch == '\n')
  590. {
  591. if (fStopAtEol)
  592. return false;
  593. else
  594. m_pch++;
  595. }
  596. else
  597. break;
  598. }
  599. return true;
  600. }
  601. bool CSeriesReader::ReadToComma(LPSTR *psz)
  602. {
  603. if (!TrimSpaces(true))
  604. return(false);
  605. m_pchPreserve = m_pch;
  606. while (TRUE)
  607. {
  608. if (m_pch >= m_pchEnd)
  609. {
  610. if (!FillBuffer())
  611. {
  612. if (m_pch - m_pchPreserve > 0)
  613. break;
  614. else
  615. return false;
  616. }
  617. }
  618. else if (*m_pch == ',' || *m_pch == '\r' || *m_pch == '\n')
  619. break;
  620. m_pch++;
  621. }
  622. *m_pch++ = '\0';
  623. *psz = m_pchPreserve;
  624. return true;
  625. }
  626. void ProcessTestSeriesFile(LPCWSTR wszFile)
  627. {
  628. HANDLE hFile;
  629. hFile = CreateFile
  630. (
  631. wszFile,
  632. GENERIC_READ,
  633. FILE_SHARE_READ,
  634. NULL,
  635. OPEN_EXISTING,
  636. 0,
  637. NULL
  638. );
  639. if (hFile == INVALID_HANDLE_VALUE)
  640. {
  641. LogUnexpectedFailure(L"Cannot open file %s due to error %d", wszFile, GetLastError());
  642. return;
  643. }
  644. CSeriesReader reader(hFile, wszFile);
  645. while(TRUE)
  646. {
  647. if(!reader.TrimSpaces(false))
  648. // no more data in file
  649. break;
  650. LPSTR szScenarioFile;
  651. if (!reader.ReadToComma(&szScenarioFile))
  652. break;
  653. WCHAR wszScenarioFile[1024];
  654. mbstowcs(wszScenarioFile, szScenarioFile, sizeof(wszScenarioFile)/sizeof(WCHAR));
  655. bool fSectionFound = false;
  656. while(TRUE)
  657. {
  658. LPSTR szSection;
  659. if (!reader.ReadToComma(&szSection))
  660. break;
  661. WCHAR wszSection[257];
  662. mbstowcs(wszSection, szSection, sizeof(wszSection)/sizeof(WCHAR));
  663. RunScenario(wszScenarioFile, wszSection);
  664. fSectionFound = true;
  665. }
  666. if (!fSectionFound)
  667. RunScenario(wszScenarioFile, L"Default");
  668. }
  669. }
  670. extern "C" __cdecl wmain(int argc, WCHAR **argv)
  671. {
  672. bool bCoInitializeSucceeded = false;
  673. try
  674. {
  675. HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  676. if (FAILED(hr))
  677. {
  678. LogUnexpectedFailure(L"CoInitialize Failed hr = 0x%08lx", hr);
  679. throw hr;
  680. }
  681. CVsTstParams params;
  682. params.ParseCommandLine(argv, argc);
  683. if (!EnableDebugPriv())
  684. exit(-1);
  685. CVsTstMsgHandler handler;
  686. g_pcTstNtLog = handler.GetTstNtLogP();
  687. handler.Initialize(1024);
  688. handler.LaunchReader();
  689. handler.StartProcessingMessages();
  690. LPCWSTR wszScenarioFile;
  691. LPCWSTR wszSectionName;
  692. LPCWSTR wszTestSeriesFile;
  693. if (params.GetTestSeries(&wszTestSeriesFile))
  694. ProcessTestSeriesFile(wszTestSeriesFile);
  695. else if (params.GetScenarioFileName(&wszScenarioFile) &&
  696. params.GetSectionName(&wszSectionName))
  697. RunScenario(wszScenarioFile, wszSectionName);
  698. else
  699. LogUnexpectedFailure(L"Bad Input parameters");
  700. handler.StopProcessingMessages();
  701. g_pcTstNtLog = NULL;
  702. }
  703. catch( HRESULT hr )
  704. {
  705. LogUnexpectedFailure( L"Caught HRESULT: 0x%08x", hr );
  706. }
  707. catch(...)
  708. {
  709. LogUnexpectedFailure( L"Caught an unexpected exception" );
  710. }
  711. if (bCoInitializeSucceeded)
  712. CoUninitialize();
  713. return 0;
  714. }
  715. void CVsTstMsgHandlerRoutines::PrintMessage(VSTST_MSG_HDR *phdr, VOID *pPrivateData)
  716. {
  717. VSTST_ASSERT(phdr->type == VSTST_MT_TEXT || phdr->type == VSTST_MT_IMMEDIATETEXT);
  718. CVsTstNtLog *pcTestLog = (CVsTstNtLog *)pPrivateData;
  719. VSTST_TEXTMSG *pmsg = (VSTST_TEXTMSG *) phdr->rgb;
  720. printf("%d: %s\n", (UINT) phdr->sequence, pmsg->pch);
  721. pcTestLog->Log( eSevLev_Info, L"(%I64u) %S", phdr->processId, pmsg->pch );
  722. }
  723. void CVsTstMsgHandlerRoutines::HandleUnexpectedException(VSTST_MSG_HDR *phdr, VOID *pPrivateData)
  724. {
  725. VSTST_ASSERT(phdr->type == VSTST_MT_UNEXPECTEDEXCEPTION);
  726. CVsTstNtLog *pcTestLog = (CVsTstNtLog *)pPrivateData;
  727. VSTST_UNEXPECTEDEXCEPTIONMSG *pmsg = (VSTST_UNEXPECTEDEXCEPTIONMSG *) phdr->rgb;
  728. printf("!!!Unexpected Exception caught in routine %s\n", pmsg->szFailedRoutine);
  729. pcTestLog->Log( eSevLev_Severe,
  730. L"(%I64u) !!!Unexpected Exception caught in routine %S", phdr->processId, pmsg->szFailedRoutine );
  731. }
  732. void CVsTstMsgHandlerRoutines::HandleFailure(VSTST_MSG_HDR *phdr, VOID *pPrivateData)
  733. {
  734. VSTST_ASSERT(phdr->type == VSTST_MT_FAILURE);
  735. CVsTstNtLog *pcTestLog = (CVsTstNtLog *)pPrivateData;
  736. VSTST_FAILUREMSG *pmsg = (VSTST_FAILUREMSG *) phdr->rgb;
  737. printf("!!!FAILURE: %s\n", pmsg->szFailure);
  738. pcTestLog->Log( eSevLev_Severe,
  739. L"(%I64u) !!!FAILURE: %S", phdr->processId, pmsg->szFailure);
  740. }
  741. void CVsTstMsgHandlerRoutines::HandleSuccess(VSTST_MSG_HDR *phdr, VOID *pPrivateData)
  742. {
  743. VSTST_ASSERT(phdr->type == VSTST_MT_SUCCESS);
  744. CVsTstNtLog *pcTestLog = (CVsTstNtLog *)pPrivateData;
  745. VSTST_SUCCESSMSG *pmsg = (VSTST_SUCCESSMSG *) phdr->rgb;
  746. printf("SUCCESS: %s\n", phdr->processId, pmsg->szMsg);
  747. pcTestLog->Log( eSevLev_Pass,
  748. L"(%I64u) Success: %S", pmsg->szMsg);
  749. }
  750. void CVsTstMsgHandlerRoutines::HandleOperationFailure(VSTST_MSG_HDR *phdr, VOID *pPrivateData)
  751. {
  752. VSTST_ASSERT(phdr->type == VSTST_MT_OPERATIONFAILURE);
  753. CVsTstNtLog *pcTestLog = (CVsTstNtLog *)pPrivateData;
  754. VSTST_OPERATIONFAILUREMSG *pmsg = (VSTST_OPERATIONFAILUREMSG *) phdr->rgb;
  755. printf("!!!Operation %s failed. hr = 0x%08lx\n", pmsg->szFailedOperation, pmsg->hr);
  756. pcTestLog->Log( eSevLev_Severe,
  757. L"(%I64u) !!!Operation %S failed. hr = 0x%08lx\n", phdr->processId, pmsg->szFailedOperation, pmsg->hr);
  758. }
  759. void LogInvalidMessage(VSTST_MSG_HDR *phdr)
  760. {
  761. UNREFERENCED_PARAMETER(phdr);
  762. VSTST_ASSERT(FALSE);
  763. printf( "Controller: !!! Invalid harness message\n" );
  764. if ( g_pcTstNtLog != NULL )
  765. g_pcTstNtLog->Log( eSevLev_Severe, L"Controller: !!! Invalid harness message" );
  766. }
  767. void ReadPipeError(DWORD dwErr)
  768. {
  769. UNREFERENCED_PARAMETER(dwErr);
  770. VSTST_ASSERT(FALSE);
  771. printf( "Controller: !!! Pipe read error\n" );
  772. if ( g_pcTstNtLog != NULL )
  773. g_pcTstNtLog->Log( eSevLev_Severe, L"Controller: !!! Pipe read error" );
  774. }
  775. void LogUnexpectedFailure(LPCWSTR wsz, ...)
  776. {
  777. va_list args;
  778. va_start(args, wsz);
  779. VSTST_ASSERT( "In LogUnexpectedFailure" && FALSE);
  780. CBsString cwsErrorMessage;
  781. cwsErrorMessage.FormatV( wsz, args );
  782. wprintf( L"Controller: %s\n", cwsErrorMessage.c_str() );
  783. if ( g_pcTstNtLog != NULL )
  784. g_pcTstNtLog->Log( eSevLev_Severe, L"Controller: %s", cwsErrorMessage.c_str() );
  785. va_end( args );
  786. }