Source code of Windows XP (NT5)
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.

2498 lines
53 KiB

  1. // CollectionControl.cpp : Defines the entry point for the DLL application.
  2. //
  3. //***************************************************************************
  4. //
  5. // judyp May 1999
  6. //
  7. //***************************************************************************
  8. #include "stdafx.h"
  9. #pragma warning (disable : 4786)
  10. #pragma warning (disable : 4275)
  11. #include <iostream>
  12. #include <strstream>
  13. #include <fstream>
  14. #include <string>
  15. #include <sstream>
  16. #include <map>
  17. #include <list>
  18. using namespace std;
  19. #include <tchar.h>
  20. #include <process.h>
  21. #include <windows.h>
  22. #ifdef NONNT5
  23. typedef unsigned long ULONG_PTR;
  24. #endif
  25. #include <wmistr.h>
  26. #include <guiddef.h>
  27. #include <initguid.h>
  28. #include <evntrace.h>
  29. #include <WTYPES.H>
  30. #include "t_string.h"
  31. #include "Persistor.h"
  32. #include "Logger.h"
  33. #include "StructureWrappers.h"
  34. #include "StructureWapperHelpers.h"
  35. #include "ConstantMap.h"
  36. #include "TCOData.h"
  37. #include "Utilities.h"
  38. #include "CollectionControl.h"
  39. extern CConstantMap g_ConstantMap;
  40. #if 0
  41. Command line arguments:
  42. Must provide at least -action, and -file.
  43. -action is one of start, stop, enable, query, update or queryall
  44. -file is a single data file.
  45. Examples:
  46. -file E:\EventTrace\TCODataFiles\ANSI\1-1-1-2.txt
  47. -detail E:\EventTrace\TCOLogFiles\ANSI\TestRuns
  48. If you are using this framework to drive non-collection control tests
  49. use -action scenario.
  50. #endif
  51. #define ERROR_COULD_NOT_CREATE_PROCESS 10
  52. #define ERROR_COULD_NOT_GET_PROCESS_RETURN 11
  53. #define ERROR_WAIT_FAILED 12
  54. struct ProcessData
  55. {
  56. // Passed from caller.
  57. LPTSTR m_lptstrExePath;
  58. LPTSTR m_lptstrCmdLine;
  59. LPTSTR m_lptstrTCOId;
  60. LPTSTR m_lptstrLogFile;
  61. int m_nGuids;
  62. LPGUID m_lpguidArray;
  63. HANDLE m_hEventContinue;
  64. HANDLE m_hEventProcessCompleted;
  65. // Filled in by thread that starts the process
  66. DWORD m_dwThreadReturn;
  67. HANDLE m_hProcess;
  68. DWORD m_dwProcessReturn;
  69. int m_nSystemError;
  70. };
  71. struct StartTraceWithProviderData
  72. {
  73. TCOData *m_pstructTCOData;
  74. TCOFunctionalData *m_pstructTCOFunctionalData;
  75. LPTSTR m_lptstrAction;
  76. LPTSTR m_lptstrDataFile;
  77. LPTSTR m_lptstrDetailPath;
  78. LPTSTR m_lptstrTCOTestError;
  79. ProcessData *m_pstructProcessData;
  80. bool m_bStartConsumers;
  81. ProcessData **m_pstructConsumerDataArray;
  82. HANDLE *m_handleConsmers;
  83. };
  84. void FreeStartTraceWithProviderData(StartTraceWithProviderData *p);
  85. void FreeStartTraceWithProviderDataArray(StartTraceWithProviderData **p, int nP);
  86. ProcessData *InitializeProcessData
  87. (
  88. TCOData *pstructTCOData,
  89. TCOFunctionalData *pstructTCOFunctionalData,
  90. LPTSTR lptstrDetailPath,
  91. int nProcessIndex,
  92. bool bProvider
  93. );
  94. void FreeProcessData(ProcessData *pProcessData);
  95. void FreeProcessDataArray(ProcessData **pProcessData, int nProcessData);
  96. void InitializeExeAndCmdLine
  97. (
  98. ProcessData *&pstructProcessData,
  99. TCOData *pstructTCOData,
  100. TCOFunctionalData *pstructTCOFunctionalData,
  101. LPTSTR lptstrDetailPath,
  102. int nProcessIndex,
  103. bool bProvider
  104. );
  105. // Just allows the test to be driven programatically in addition to from
  106. // the command line. Dispatches based upon lptstrAction.
  107. int BeginTCOTest
  108. (
  109. LPTSTR lptstrAction,
  110. LPTSTR lptstrDataFile,
  111. LPTSTR lptstrDetailPath,
  112. LPTSTR lptstrUpdateDataFile,
  113. LPTSTR lptstrProviderExe,
  114. bool bLogExpected,
  115. bool bUseTraceHandle
  116. );
  117. // List of files or single file.
  118. int ActionScenario
  119. (
  120. LPTSTR lptstrAction,
  121. LPTSTR lptstrDataFile,
  122. LPTSTR lptstrDetailPath,
  123. bool bLogExpected
  124. );
  125. int ActionStartTrace
  126. (
  127. LPTSTR lptstrAction,
  128. LPTSTR lptstrDataFile,
  129. LPTSTR lptstrDetailPath,
  130. bool bLogExpected
  131. );
  132. int ActionStopTrace
  133. (
  134. LPTSTR lptstrAction,
  135. LPTSTR lptstrDataFile,
  136. LPTSTR lptstrDetailPath,
  137. bool bLogExpected,
  138. bool bUseTraceHandle
  139. );
  140. int ActionEnableTrace
  141. (
  142. LPTSTR lptstrAction,
  143. LPTSTR lptstrDataFile,
  144. LPTSTR lptstrDetailPath,
  145. bool bLogExpected
  146. );
  147. int ActionQueryTrace
  148. (
  149. LPTSTR lptstrAction,
  150. LPTSTR lptstrDataFile,
  151. LPTSTR lptstrDetailPath,
  152. bool bLogExpected,
  153. bool bUseTraceHandle
  154. );
  155. int ActionUpdateTrace
  156. (
  157. LPTSTR lptstrAction,
  158. LPTSTR lptstrDataFile,
  159. LPTSTR lptstrDetailPath,
  160. LPTSTR lptstrUpdateDataFile,
  161. bool bLogExpected,
  162. bool bUseTraceHandle
  163. );
  164. int ActionQueryAllTraces
  165. (
  166. LPTSTR lptstrAction,
  167. LPTSTR lptstrDetailPath
  168. );
  169. int ActionStartProvider
  170. (
  171. LPTSTR lptstrAction,
  172. LPTSTR lptstrProviderExe
  173. );
  174. int RunActionScenarioWithProvider
  175. (
  176. TCOData *pstructTCOData,
  177. TCOFunctionalData *pstructTCOFunctionalData,
  178. LPTSTR &lptstrAction,
  179. LPTSTR &lpctstrDataFile,
  180. LPTSTR &lptstrDetailPath,
  181. LPTSTR &lptstrTCOTestError
  182. );
  183. unsigned int __stdcall RunActionScenarioWithProvider(void *pVoid);
  184. int GetArgs
  185. (
  186. t_string tsCommandLine,
  187. LPTSTR &lptstrAction,
  188. LPTSTR &lptstrDataFile,
  189. LPTSTR &lptstrDetailPath,
  190. LPTSTR &lptstrUpdateDataFile,
  191. LPTSTR &lptstrProviderExe,
  192. bool &bLogExpected,
  193. bool &bUseTraceHandle // QueryTrace, EnableTrace, UpdateTrace, and StopTrace
  194. );
  195. int FreeArgs
  196. (
  197. LPTSTR &lptstrAction,
  198. LPTSTR &lptstrDataFile,
  199. LPTSTR &lptstrDetailPath,
  200. LPTSTR &lptstrUpdateDataFile,
  201. LPTSTR &lptstrProviderExe
  202. );
  203. t_string GetTestName(LPTSTR lptstrDataFile);
  204. unsigned int __stdcall RunProcess (void * pVoid);
  205. void ThreadLogger
  206. (int nState, LPCTSTR lptstrFunction, LPCTSTR lptstrMsg, bool bUseULONGValue, ULONG ulValue);
  207. CLogger g_ThreadLogger(_T("E:\\EventTrace\\TCOLogFiles\\ThreadLog.txt"), false);
  208. // Command line
  209. // -action starttrace -file E:\EventTrace\TCODataFiles\unicode\1-1-1-2.txt -detail E:\EventTrace\TCOLogFiles\ANSI\TestRuns
  210. #ifdef NT5BUILD
  211. __cdecl
  212. #else
  213. int
  214. #endif
  215. main(int argc, char* argv[])
  216. {
  217. LPTSTR lptstrAction = NULL;
  218. LPTSTR lptstrDataFile = NULL;
  219. LPTSTR lptstrDetailPath = NULL;
  220. LPTSTR lptstrUpdateDataFile = NULL;
  221. LPTSTR lptstrProviderExe = NULL;
  222. bool bLogExpected = true;
  223. bool bUseTraceHandle = false;
  224. t_string tsCommandLine;
  225. LPTSTR lptstrCommandLine = NewTCHAR (GetCommandLine());
  226. tsCommandLine = lptstrCommandLine;
  227. free(lptstrCommandLine);
  228. lptstrCommandLine = NULL;
  229. int nReturn =
  230. GetArgs
  231. (
  232. tsCommandLine,
  233. lptstrAction,
  234. lptstrDataFile,
  235. lptstrDetailPath,
  236. lptstrUpdateDataFile,
  237. lptstrProviderExe,
  238. bLogExpected,
  239. bUseTraceHandle
  240. );
  241. if (nReturn != 0)
  242. {
  243. t_cout << _T("Command line error with: \n") << tsCommandLine.c_str() << _T(".\n");
  244. FreeArgs
  245. (
  246. lptstrAction,
  247. lptstrDataFile,
  248. lptstrDetailPath,
  249. lptstrUpdateDataFile,
  250. lptstrProviderExe
  251. );
  252. return nReturn;
  253. }
  254. if (!lptstrDataFile &&
  255. !(case_insensitive_compare(lptstrAction,_T("queryalltraces")) == 0 ||
  256. case_insensitive_compare(lptstrAction,_T("providerexe")) == 0 ||
  257. case_insensitive_compare(lptstrAction,_T("line")) == 0 ||
  258. case_insensitive_compare(lptstrAction,_T("sleep")) == 0)
  259. )
  260. {
  261. t_cout << _T("Must provide a data file!\n");
  262. FreeArgs
  263. (
  264. lptstrAction,
  265. lptstrDataFile,
  266. lptstrDetailPath,
  267. lptstrUpdateDataFile,
  268. lptstrProviderExe
  269. );
  270. return -1;
  271. }
  272. nReturn =
  273. BeginTCOTest
  274. (
  275. lptstrAction,
  276. lptstrDataFile,
  277. lptstrDetailPath,
  278. lptstrUpdateDataFile,
  279. lptstrProviderExe,
  280. bLogExpected,
  281. bUseTraceHandle
  282. );
  283. FreeArgs
  284. (
  285. lptstrAction,
  286. lptstrDataFile,
  287. lptstrDetailPath,
  288. lptstrUpdateDataFile,
  289. lptstrProviderExe
  290. );
  291. return nReturn;
  292. }
  293. int BeginTCOTest
  294. (
  295. LPTSTR lptstrAction,
  296. LPTSTR lptstrDataFile,
  297. LPTSTR lptstrDetailPath,
  298. LPTSTR lptstrUpdateDataFile,
  299. LPTSTR lptstrProviderExe,
  300. bool bLogExpected,
  301. bool bUseTraceHandle
  302. )
  303. {
  304. int nReturn = ERROR_SUCCESS;
  305. if (case_insensitive_compare(lptstrAction,_T("scenario")) == 0)
  306. {
  307. nReturn =
  308. ActionScenario
  309. (
  310. lptstrAction,
  311. lptstrDataFile,
  312. lptstrDetailPath,
  313. bLogExpected
  314. );
  315. }
  316. else if (case_insensitive_compare(lptstrAction,_T("starttrace")) == 0)
  317. {
  318. nReturn =
  319. ActionStartTrace
  320. (
  321. lptstrAction,
  322. lptstrDataFile,
  323. lptstrDetailPath,
  324. bLogExpected
  325. );
  326. }
  327. else if (case_insensitive_compare(lptstrAction,_T("stoptrace")) == 0)
  328. {
  329. nReturn =
  330. ActionStopTrace
  331. (
  332. lptstrAction,
  333. lptstrDataFile,
  334. lptstrDetailPath,
  335. bLogExpected,
  336. bUseTraceHandle
  337. );
  338. }
  339. else if (case_insensitive_compare(lptstrAction,_T("enabletrace")) == 0)
  340. {
  341. nReturn =
  342. ActionEnableTrace
  343. (
  344. lptstrAction,
  345. lptstrDataFile,
  346. lptstrDetailPath,
  347. bLogExpected
  348. );
  349. }
  350. else if (case_insensitive_compare(lptstrAction,_T("querytrace")) == 0)
  351. {
  352. nReturn =
  353. ActionQueryTrace
  354. (
  355. lptstrAction,
  356. lptstrDataFile,
  357. lptstrDetailPath,
  358. bLogExpected,
  359. bUseTraceHandle
  360. );
  361. }
  362. else if (case_insensitive_compare(lptstrAction,_T("updatetrace")) == 0)
  363. {
  364. // If bUseTraceHandle is true we will start things with the
  365. // lptstrDataFile and update with the lptstrUpdateDataFile.
  366. // If bUseTraceHandle is false we will update with the
  367. // lptstrDataFile.
  368. nReturn =
  369. ActionUpdateTrace
  370. (
  371. lptstrAction,
  372. lptstrDataFile,
  373. lptstrDetailPath,
  374. lptstrUpdateDataFile,
  375. bLogExpected,
  376. bUseTraceHandle
  377. );
  378. }
  379. else if (case_insensitive_compare(lptstrAction,_T("queryalltraces")) == 0)
  380. {
  381. nReturn =
  382. ActionQueryAllTraces
  383. (
  384. lptstrAction,
  385. lptstrDetailPath
  386. );
  387. }
  388. else if (case_insensitive_compare(lptstrAction,_T("providerexe")) == 0)
  389. {
  390. nReturn =
  391. ActionStartProvider
  392. (
  393. lptstrAction,
  394. lptstrProviderExe
  395. );
  396. }
  397. else if (case_insensitive_compare(lptstrAction,_T("sleep")) == 0)
  398. {
  399. nReturn = ERROR_SUCCESS;
  400. Sleep(5000);
  401. }
  402. else if (case_insensitive_compare(lptstrAction,_T("line")) == 0)
  403. {
  404. t_cout << _T("\n");
  405. }
  406. return nReturn;
  407. }
  408. int ActionStartTrace
  409. (
  410. LPTSTR lptstrAction,
  411. LPTSTR lptstrDataFile,
  412. LPTSTR lptstrDetailPath,
  413. bool bLogExpected
  414. )
  415. {
  416. int nResult = ERROR_SUCCESS;
  417. LPTSTR lptstrTCOTestError = NULL;
  418. TCOData *pstructTCOData = NULL;
  419. TCOFunctionalData *pstructTCOFunctionalData = NULL;
  420. int nAPICallResult = 0;
  421. t_string tsDetailFile;
  422. nResult =
  423. GetAllTCOData
  424. (
  425. lptstrDataFile ,
  426. &pstructTCOData,
  427. &pstructTCOFunctionalData,
  428. &lptstrTCOTestError
  429. );
  430. if (nResult != ERROR_SUCCESS)
  431. {
  432. t_cout << _T("Could not get TCO Data: ") << lptstrTCOTestError << _T("\n");
  433. FreeTCOData(pstructTCOData);
  434. pstructTCOData = NULL;
  435. FreeTCOFunctionalData(pstructTCOFunctionalData);
  436. pstructTCOFunctionalData = NULL;
  437. free(lptstrTCOTestError);
  438. lptstrTCOTestError = NULL;
  439. return nResult;
  440. }
  441. tsDetailFile = lptstrDetailPath;
  442. tsDetailFile += _T("\\");
  443. tsDetailFile += GetTestName(lptstrDataFile);
  444. nResult =
  445. StartTraceAPI
  446. (
  447. lptstrAction,
  448. lptstrDataFile,
  449. tsDetailFile.c_str(),
  450. bLogExpected,
  451. pstructTCOData,
  452. &nAPICallResult
  453. );
  454. tsDetailFile.erase();
  455. FreeTCOData(pstructTCOData);
  456. FreeTCOFunctionalData(pstructTCOFunctionalData);
  457. return nResult;
  458. }
  459. int ActionStopTrace
  460. (
  461. LPTSTR lptstrAction,
  462. LPTSTR lptstrDataFile,
  463. LPTSTR lptstrDetailPath,
  464. bool bLogExpected,
  465. bool bUseTraceHandle
  466. )
  467. {
  468. int nResult = ERROR_SUCCESS;
  469. LPTSTR lptstrTCOTestError = NULL;
  470. TCOData *pstructTCOData = NULL;
  471. TCOFunctionalData *pstructTCOFunctionalData = NULL;
  472. int nAPICallResult = 0;
  473. t_string tsDetailFile;
  474. nResult =
  475. GetAllTCOData
  476. (
  477. lptstrDataFile ,
  478. &pstructTCOData,
  479. &pstructTCOFunctionalData,
  480. &lptstrTCOTestError
  481. );
  482. if (nResult != ERROR_SUCCESS)
  483. {
  484. t_cout << _T("Could not get TCO Data: ") << lptstrTCOTestError << _T("\n");
  485. FreeTCOData(pstructTCOData);
  486. pstructTCOData = NULL;
  487. FreeTCOFunctionalData(pstructTCOFunctionalData);
  488. pstructTCOFunctionalData = NULL;
  489. free(lptstrTCOTestError);
  490. lptstrTCOTestError = NULL;
  491. return nResult;
  492. }
  493. tsDetailFile = lptstrDetailPath;
  494. tsDetailFile += _T("\\");
  495. tsDetailFile += GetTestName(lptstrDataFile);
  496. t_string tsError;
  497. // If bUseTraceHandle is true we will start the logger.
  498. if (bUseTraceHandle)
  499. {
  500. nResult =
  501. StartTraceAPI
  502. (
  503. lptstrAction,
  504. lptstrDataFile,
  505. tsDetailFile.c_str(),
  506. false,
  507. pstructTCOData,
  508. &nAPICallResult
  509. );
  510. if (nResult != ERROR_SUCCESS)
  511. {
  512. FreeTCOData(pstructTCOData);
  513. FreeTCOFunctionalData(pstructTCOFunctionalData);
  514. return nResult;
  515. }
  516. Sleep(2000);
  517. int nResult2 =
  518. EnableTraceAPI
  519. (
  520. lptstrAction,
  521. lptstrDataFile,
  522. tsDetailFile.c_str(),
  523. false,
  524. pstructTCOData,
  525. &nAPICallResult
  526. );
  527. Sleep(5000);
  528. // Restore this.
  529. nAPICallResult = ERROR_SUCCESS;
  530. }
  531. nResult =
  532. StopTraceAPI
  533. (
  534. lptstrAction,
  535. lptstrDataFile,
  536. tsDetailFile.c_str(),
  537. bLogExpected,
  538. bUseTraceHandle,
  539. pstructTCOData,
  540. &nAPICallResult
  541. );
  542. tsDetailFile.erase();
  543. FreeTCOData(pstructTCOData);
  544. FreeTCOFunctionalData(pstructTCOFunctionalData);
  545. return nResult;
  546. }
  547. int ActionEnableTrace
  548. (
  549. LPTSTR lptstrAction,
  550. LPTSTR lptstrDataFile,
  551. LPTSTR lptstrDetailPath,
  552. bool bLogExpected
  553. )
  554. {
  555. int nResult = ERROR_SUCCESS;
  556. LPTSTR lptstrTCOTestError = NULL;
  557. TCOData *pstructTCOData = NULL;
  558. TCOFunctionalData *pstructTCOFunctionalData = NULL;
  559. int nAPICallResult = 0;
  560. t_string tsDetailFile;
  561. t_string tsError;
  562. nResult =
  563. GetAllTCOData
  564. (
  565. lptstrDataFile ,
  566. &pstructTCOData,
  567. &pstructTCOFunctionalData,
  568. &lptstrTCOTestError
  569. );
  570. if (nResult != ERROR_SUCCESS)
  571. {
  572. t_cout << _T("Could not get TCO Data: ") << lptstrTCOTestError << _T("\n");
  573. FreeTCOData(pstructTCOData);
  574. pstructTCOData = NULL;
  575. FreeTCOFunctionalData(pstructTCOFunctionalData);
  576. pstructTCOFunctionalData = NULL;
  577. free(lptstrTCOTestError);
  578. lptstrTCOTestError = NULL;
  579. return nResult;
  580. }
  581. tsDetailFile = lptstrDetailPath;
  582. tsDetailFile += _T("\\");
  583. tsDetailFile += GetTestName(lptstrDataFile);
  584. nResult =
  585. StartTraceAPI
  586. (
  587. lptstrAction,
  588. lptstrDataFile,
  589. tsDetailFile.c_str(),
  590. false,
  591. pstructTCOData,
  592. &nAPICallResult
  593. );
  594. // We have a problem here if nResult != ERROR_SUCCESS and nAPICallResult == ERROR_SUCCESS
  595. // we need to call EnableTrace so that the provider can be stopped via a StopTrace
  596. // call.
  597. if (nResult != ERROR_SUCCESS && nAPICallResult == ERROR_SUCCESS)
  598. {
  599. Sleep(2000);
  600. // Do not really care what result is!
  601. int nResult2 =
  602. EnableTraceAPI
  603. (
  604. lptstrAction,
  605. lptstrDataFile,
  606. tsDetailFile.c_str(),
  607. false,
  608. pstructTCOData,
  609. &nAPICallResult
  610. );
  611. Sleep(5000);
  612. // Restore this.
  613. nAPICallResult = ERROR_SUCCESS;
  614. }
  615. if (nResult == ERROR_SUCCESS)
  616. {
  617. Sleep(2000);
  618. nResult =
  619. EnableTraceAPI
  620. (
  621. lptstrAction,
  622. lptstrDataFile,
  623. tsDetailFile.c_str(),
  624. bLogExpected,
  625. pstructTCOData,
  626. &nAPICallResult
  627. );
  628. Sleep(5000);
  629. }
  630. tsDetailFile.erase();
  631. FreeTCOData(pstructTCOData);
  632. FreeTCOFunctionalData(pstructTCOFunctionalData);
  633. return nResult;
  634. }
  635. int ActionQueryTrace
  636. (
  637. LPTSTR lptstrAction,
  638. LPTSTR lptstrDataFile,
  639. LPTSTR lptstrDetailPath,
  640. bool bLogExpected,
  641. bool bUseTraceHandle
  642. )
  643. {
  644. int nResult = ERROR_SUCCESS;
  645. LPTSTR lptstrTCOTestError = NULL;
  646. TCOData *pstructTCOData = NULL;
  647. TCOFunctionalData *pstructTCOFunctionalData = NULL;
  648. int nAPICallResult = 0;
  649. t_string tsDetailFile;
  650. nResult =
  651. GetAllTCOData
  652. (
  653. lptstrDataFile ,
  654. &pstructTCOData,
  655. &pstructTCOFunctionalData,
  656. &lptstrTCOTestError
  657. );
  658. if (nResult != ERROR_SUCCESS)
  659. {
  660. t_cout << _T("Could not get TCO Data: ") << lptstrTCOTestError << _T("\n");
  661. FreeTCOData(pstructTCOData);
  662. pstructTCOData = NULL;
  663. FreeTCOFunctionalData(pstructTCOFunctionalData);
  664. pstructTCOFunctionalData = NULL;
  665. free(lptstrTCOTestError);
  666. lptstrTCOTestError = NULL;
  667. return nResult;
  668. }
  669. tsDetailFile = lptstrDetailPath;
  670. tsDetailFile += _T("\\");
  671. tsDetailFile += GetTestName(lptstrDataFile);
  672. // If bUseTraceHandle is true we will start the logger.
  673. if (bUseTraceHandle)
  674. {
  675. nResult =
  676. StartTraceAPI
  677. (
  678. lptstrAction,
  679. lptstrDataFile,
  680. tsDetailFile.c_str(),
  681. false,
  682. pstructTCOData,
  683. &nAPICallResult
  684. );
  685. t_string tsError;
  686. if (nAPICallResult != ERROR_SUCCESS)
  687. {
  688. FreeTCOData(pstructTCOData);
  689. FreeTCOFunctionalData(pstructTCOFunctionalData);
  690. return nAPICallResult;
  691. }
  692. Sleep(2000);
  693. int nResult2 =
  694. EnableTraceAPI
  695. (
  696. lptstrAction,
  697. lptstrDataFile,
  698. tsDetailFile.c_str(),
  699. false,
  700. pstructTCOData,
  701. &nAPICallResult
  702. );
  703. if (nAPICallResult != ERROR_SUCCESS)
  704. {
  705. FreeTCOData(pstructTCOData);
  706. FreeTCOFunctionalData(pstructTCOFunctionalData);
  707. return nAPICallResult;
  708. }
  709. Sleep(5000);
  710. }
  711. nResult =
  712. QueryTraceAPI
  713. (
  714. lptstrAction,
  715. lptstrDataFile,
  716. tsDetailFile.c_str(),
  717. bLogExpected,
  718. bUseTraceHandle,
  719. pstructTCOData,
  720. &nAPICallResult
  721. );
  722. tsDetailFile.erase();
  723. FreeTCOData(pstructTCOData);
  724. FreeTCOFunctionalData(pstructTCOFunctionalData);
  725. return nResult;
  726. }
  727. int ActionUpdateTrace
  728. (
  729. LPTSTR lptstrAction,
  730. LPTSTR lptstrDataFile,
  731. LPTSTR lptstrDetailPath,
  732. LPTSTR lptstrUpdateDataFile,
  733. bool bLogExpected,
  734. bool bUseTraceHandle
  735. )
  736. {
  737. int nResult = ERROR_SUCCESS;
  738. LPTSTR lptstrTCOTestError = NULL;
  739. TCOData *pstructTCOData = NULL;
  740. TCOData *pstructUpdateData = NULL; // Remember to free!
  741. TCOFunctionalData *pstructTCOFunctionalData = NULL;
  742. int nAPICallResult = 0;
  743. t_string tsDetailFile;
  744. if (bUseTraceHandle && !lptstrUpdateDataFile)
  745. {
  746. t_cout << _T("Error in ActionUpdateTrace: If -usetracehandle 1 is true you must provide an -updatedata argument.\n");
  747. return -1;
  748. }
  749. if (bUseTraceHandle && lptstrUpdateDataFile)
  750. {
  751. nResult =
  752. GetAllTCOData
  753. (
  754. lptstrUpdateDataFile ,
  755. &pstructUpdateData,
  756. NULL,
  757. &lptstrTCOTestError,
  758. false
  759. );
  760. }
  761. nResult =
  762. GetAllTCOData
  763. (
  764. lptstrDataFile ,
  765. &pstructTCOData,
  766. &pstructTCOFunctionalData,
  767. &lptstrTCOTestError
  768. );
  769. if (nResult != ERROR_SUCCESS)
  770. {
  771. t_cout << _T("Could not get TCO Data: ") << lptstrTCOTestError << _T("\n");
  772. FreeTCOData(pstructTCOData);
  773. pstructTCOData = NULL;
  774. FreeTCOFunctionalData(pstructTCOFunctionalData);
  775. pstructTCOFunctionalData = NULL;
  776. free(lptstrTCOTestError);
  777. lptstrTCOTestError = NULL;
  778. return nResult;
  779. }
  780. tsDetailFile = lptstrDetailPath;
  781. tsDetailFile += _T("\\");
  782. tsDetailFile += GetTestName(lptstrDataFile);
  783. // If bUseTraceHandle is true we will start the logger.
  784. if (bUseTraceHandle)
  785. {
  786. nResult =
  787. StartTraceAPI
  788. (
  789. lptstrAction,
  790. lptstrDataFile,
  791. tsDetailFile.c_str(),
  792. false,
  793. pstructTCOData,
  794. &nAPICallResult
  795. );
  796. t_string tsError;
  797. if (nAPICallResult != ERROR_SUCCESS)
  798. {
  799. FreeTCOData(pstructTCOData);
  800. FreeTCOFunctionalData(pstructTCOFunctionalData);
  801. return nAPICallResult;
  802. }
  803. Sleep(2000);
  804. int nResult2 =
  805. EnableTraceAPI
  806. (
  807. lptstrAction,
  808. lptstrDataFile,
  809. tsDetailFile.c_str(),
  810. false,
  811. pstructTCOData,
  812. &nAPICallResult
  813. );
  814. if (nAPICallResult != ERROR_SUCCESS)
  815. {
  816. FreeTCOData(pstructTCOData);
  817. FreeTCOFunctionalData(pstructTCOFunctionalData);
  818. return nAPICallResult;
  819. }
  820. Sleep(5000);
  821. }
  822. if (bUseTraceHandle)
  823. {
  824. pstructUpdateData->m_pTraceHandle =
  825. (TRACEHANDLE *) malloc (sizeof(TRACEHANDLE));
  826. *pstructUpdateData->m_pTraceHandle = *pstructTCOData->m_pTraceHandle;
  827. }
  828. nResult =
  829. UpdateTraceAPI
  830. (
  831. lptstrAction,
  832. lptstrDataFile,
  833. tsDetailFile.c_str(),
  834. bLogExpected,
  835. bUseTraceHandle,
  836. bUseTraceHandle ? pstructUpdateData : pstructTCOData,
  837. &nAPICallResult
  838. );
  839. tsDetailFile.erase();
  840. FreeTCOData(pstructTCOData);
  841. FreeTCOFunctionalData(pstructTCOFunctionalData);
  842. FreeTCOData(pstructUpdateData);
  843. return nResult;
  844. }
  845. int ActionQueryAllTraces
  846. (
  847. LPTSTR lptstrAction,
  848. LPTSTR lptstrDetailPath
  849. )
  850. {
  851. int nAPICallResult = ERROR_SUCCESS;
  852. int nResult =
  853. QueryAllTracesAPI
  854. (
  855. lptstrAction,
  856. &nAPICallResult
  857. );
  858. t_string tsError;
  859. if (nResult != ERROR_SUCCESS)
  860. {
  861. tsError = ULONGVarToTString(nResult, true);
  862. LPTSTR lptstrError = DecodeStatus(nResult);
  863. t_cout << _T("ActionQueryAllTraces Failure: ") << tsError;
  864. if (lptstrError)
  865. {
  866. t_cout << _T(" - ") << lptstrError << _T("\n");
  867. }
  868. else
  869. {
  870. t_cout << _T(".\n");
  871. }
  872. free (lptstrError);
  873. lptstrError = NULL;
  874. }
  875. return nResult;
  876. }
  877. int ActionStartProvider
  878. (
  879. LPTSTR lptstrAction,
  880. LPTSTR lptstrProviderExe
  881. )
  882. {
  883. t_string tsExeAndCmdLine;
  884. tsExeAndCmdLine = lptstrProviderExe;
  885. int nEndExe = tsExeAndCmdLine.find(_T(".exe"));
  886. nEndExe += 4;
  887. t_string tsExe;
  888. tsExe = tsExeAndCmdLine.substr(0,nEndExe);
  889. t_string tsCmdLine;
  890. if (nEndExe + 1 < tsExeAndCmdLine.length())
  891. {
  892. tsCmdLine = tsExeAndCmdLine.substr(nEndExe + 1,t_string::npos);
  893. }
  894. PROCESS_INFORMATION pinfoProvider;
  895. RtlZeroMemory(&pinfoProvider, sizeof(PROCESS_INFORMATION));
  896. STARTUPINFO sinfoProvider;
  897. RtlZeroMemory(&sinfoProvider, sizeof(STARTUPINFO));
  898. sinfoProvider.cb = sizeof(sinfoProvider);
  899. sinfoProvider.lpReserved = NULL;
  900. sinfoProvider.lpDesktop = NULL;
  901. sinfoProvider.lpTitle = NULL;
  902. sinfoProvider.dwFlags = 0;
  903. sinfoProvider.cbReserved2 = 0;
  904. sinfoProvider.lpReserved2 = NULL;
  905. sinfoProvider.hStdInput = NULL;
  906. sinfoProvider.hStdOutput = NULL;
  907. sinfoProvider.hStdError = NULL;
  908. BOOL bReturn =
  909. CreateProcess(
  910. tsExe.c_str(),
  911. (TCHAR *) tsCmdLine.c_str(),
  912. NULL,
  913. NULL,
  914. NULL,
  915. DETACHED_PROCESS,
  916. NULL,
  917. NULL,
  918. &sinfoProvider,
  919. &pinfoProvider);
  920. if (!bReturn)
  921. {
  922. DWORD dwError = GetLastError();
  923. t_cout << _T("\nCreateProcess failed for provider ") << tsExe << _T("\n");
  924. t_cout << _T("with command line ") << tsCmdLine << _T(".\n");
  925. LPTSTR lpstrReturnedError = DecodeStatus(dwError);
  926. t_cout << _T("Error: ") << lpstrReturnedError << _T("\n");
  927. free(lpstrReturnedError);
  928. return ERROR_COULD_NOT_CREATE_PROCESS;
  929. }
  930. t_cout << _T("\nCreateProcess succeeded for provider ") << tsExe << _T("\n");
  931. t_cout << _T("with command line ") << tsCmdLine << _T(".\n");
  932. // Do not need to hold on to this!
  933. CloseHandle(pinfoProvider.hProcess);
  934. CloseHandle(pinfoProvider.hThread);
  935. // Give the process 5 seconds to get going.
  936. Sleep(5000);
  937. return ERROR_SUCCESS;
  938. }
  939. int ActionScenario
  940. (
  941. LPTSTR lptstrAction,
  942. LPTSTR lptstrDataFile,
  943. LPTSTR lptstrDetailPath,
  944. bool bLogExpected
  945. )
  946. {
  947. int nResult = ERROR_SUCCESS;
  948. LPTSTR lptstrTCOTestError = NULL;
  949. TCOData *pstructTCOData = NULL;
  950. TCOFunctionalData *pstructTCOFunctionalData = NULL;
  951. nResult =
  952. GetAllTCOData
  953. (
  954. lptstrDataFile ,
  955. &pstructTCOData,
  956. &pstructTCOFunctionalData,
  957. &lptstrTCOTestError
  958. );
  959. if (nResult != ERROR_SUCCESS)
  960. {
  961. t_cout << _T("Could not get TCO Data: ") << lptstrTCOTestError << _T("\n");
  962. FreeTCOData(pstructTCOData);
  963. pstructTCOData = NULL;
  964. FreeTCOFunctionalData(pstructTCOFunctionalData);
  965. pstructTCOFunctionalData = NULL;
  966. free(lptstrTCOTestError);
  967. lptstrTCOTestError = NULL;
  968. return nResult;
  969. }
  970. nResult =
  971. RunActionScenarioWithProvider
  972. (
  973. pstructTCOData,
  974. pstructTCOFunctionalData,
  975. lptstrAction,
  976. lptstrDataFile,
  977. lptstrDetailPath,
  978. lptstrTCOTestError
  979. );
  980. FreeTCOData(pstructTCOData);
  981. FreeTCOFunctionalData(pstructTCOFunctionalData);
  982. t_string tsError;
  983. if (nResult != ERROR_SUCCESS)
  984. {
  985. tsError = ULONGVarToTString(nResult, true);
  986. LPTSTR lptstrError = DecodeStatus(nResult);
  987. t_cout << _T("ActionScenario Failure: ") << tsError;
  988. if (lptstrError)
  989. {
  990. t_cout << _T(" - ") << lptstrError << _T("\n");
  991. }
  992. else
  993. {
  994. t_cout << _T(".\n");
  995. }
  996. free (lptstrError);
  997. lptstrError = NULL;
  998. }
  999. return nResult;
  1000. }
  1001. int RunActionScenarioWithProvider
  1002. (
  1003. TCOData *pstructTCOData,
  1004. TCOFunctionalData *pstructTCOFunctionalData,
  1005. LPTSTR &lptstrAction,
  1006. LPTSTR &lptstrDataFile,
  1007. LPTSTR &lptstrDetailPath,
  1008. LPTSTR &lptstrTCOTestError
  1009. )
  1010. {
  1011. bool bLast = false;
  1012. int nResult = ERROR_SUCCESS;
  1013. int i;
  1014. ProcessData **pstructProviderDataArray = NULL;
  1015. StartTraceWithProviderData **pstructStartTraceData = NULL;
  1016. HANDLE *phandleProviderThreads = NULL;
  1017. // Here we want to build up array of provider ProcessData./
  1018. // Start a thread for each.
  1019. // Wait for all of the provider threads to complete.
  1020. if (pstructTCOFunctionalData->m_nProviders > 0)
  1021. {
  1022. pstructStartTraceData =
  1023. (StartTraceWithProviderData **) malloc
  1024. (sizeof (StartTraceWithProviderData *) *
  1025. pstructTCOFunctionalData->m_nProviders);
  1026. RtlZeroMemory
  1027. (pstructStartTraceData,
  1028. sizeof (StartTraceWithProviderData *) *
  1029. pstructTCOFunctionalData->m_nProviders);
  1030. for (i = 0; i < pstructTCOFunctionalData->m_nProviders; i++)
  1031. {
  1032. pstructStartTraceData[i] =
  1033. (StartTraceWithProviderData *) malloc (sizeof(StartTraceWithProviderData));
  1034. RtlZeroMemory
  1035. (pstructStartTraceData[i],
  1036. sizeof (StartTraceWithProviderData));
  1037. }
  1038. pstructProviderDataArray =
  1039. (ProcessData **) malloc
  1040. (sizeof (ProcessData *) *
  1041. pstructTCOFunctionalData->m_nProviders);
  1042. RtlZeroMemory
  1043. (pstructProviderDataArray,
  1044. sizeof (ProcessData *) *
  1045. pstructTCOFunctionalData->m_nProviders);
  1046. phandleProviderThreads =
  1047. (HANDLE *) malloc (sizeof (HANDLE) *
  1048. pstructTCOFunctionalData->m_nProviders);
  1049. RtlZeroMemory
  1050. (phandleProviderThreads,
  1051. sizeof (HANDLE) *
  1052. pstructTCOFunctionalData->m_nProviders);
  1053. for (int n = 0; n < pstructTCOFunctionalData->m_nProviders; n++)
  1054. {
  1055. pstructProviderDataArray[n] =
  1056. InitializeProcessData
  1057. (
  1058. pstructTCOData,
  1059. pstructTCOFunctionalData,
  1060. lptstrDetailPath,
  1061. n, // 0 index gets the first provider or consumer.
  1062. true // bProvider, if false we get Consumer.
  1063. );
  1064. if (!pstructProviderDataArray[n]->m_hEventContinue ||
  1065. !pstructProviderDataArray[n]->m_hEventProcessCompleted)
  1066. {
  1067. lptstrTCOTestError =
  1068. NewTCHAR(_T("Provider Data Array: Could not create events."));
  1069. FreeProcessDataArray
  1070. (pstructProviderDataArray,pstructTCOFunctionalData->m_nProviders);
  1071. return -1;
  1072. }
  1073. }
  1074. }
  1075. ProcessData **pstructConsumerDataArray = NULL;
  1076. int npstructStartTraceDataWithConsumers = -1;
  1077. for (i = 0; i < pstructTCOFunctionalData->m_nProviders; i++)
  1078. {
  1079. if (i == pstructTCOFunctionalData->m_nProviders - 1)
  1080. {
  1081. bLast = true;
  1082. }
  1083. bool bStartConsumers =
  1084. (!pstructTCOData->m_pProps)
  1085. ? false
  1086. :
  1087. (pstructTCOData->m_pProps->LogFileMode == EVENT_TRACE_REAL_TIME_MODE && i == 0)
  1088. ? true
  1089. : (pstructTCOData->m_pProps->LogFileMode != EVENT_TRACE_REAL_TIME_MODE && bLast)
  1090. ?
  1091. true:
  1092. false;
  1093. pstructStartTraceData[i]->m_pstructTCOData = pstructTCOData;
  1094. pstructStartTraceData[i]->m_pstructTCOFunctionalData = pstructTCOFunctionalData;
  1095. pstructStartTraceData[i]->m_lptstrAction = lptstrAction;
  1096. pstructStartTraceData[i]->m_lptstrDataFile = lptstrDataFile;
  1097. pstructStartTraceData[i]->m_lptstrDetailPath = lptstrDetailPath;
  1098. pstructStartTraceData[i]->m_pstructProcessData = pstructProviderDataArray[i];
  1099. pstructStartTraceData[i]->m_bStartConsumers = bStartConsumers;
  1100. pstructStartTraceData[i]->m_pstructConsumerDataArray = pstructConsumerDataArray;
  1101. if (bStartConsumers)
  1102. {
  1103. pstructStartTraceData[i]->m_handleConsmers =
  1104. (HANDLE *) malloc (sizeof(HANDLE) * pstructTCOFunctionalData->m_nConsumers);
  1105. RtlZeroMemory(pstructStartTraceData[i]->m_handleConsmers,
  1106. sizeof(HANDLE) * pstructTCOFunctionalData->m_nConsumers);
  1107. npstructStartTraceDataWithConsumers = i;
  1108. }
  1109. // Start the provider processes via a thread. The thread will become
  1110. // the surogate for thr process.
  1111. UINT uiThreadId = NULL;
  1112. phandleProviderThreads[i] =
  1113. (HANDLE) _beginthreadex
  1114. (NULL, 0, RunActionScenarioWithProvider,
  1115. (void *) pstructStartTraceData[i], 0 , &uiThreadId);
  1116. HANDLE hTemp = phandleProviderThreads[i];
  1117. ThreadLogger(3,_T("RunActionScenarioWithProvider"),
  1118. _T("Just created thread with handle"),true,
  1119. (ULONG)hTemp);
  1120. if (phandleProviderThreads[i] == 0)
  1121. {
  1122. int nError = errno;
  1123. lptstrTCOTestError =
  1124. NewTCHAR(_T("Could not start RunActionScenarioWithProvider thread."));
  1125. nResult = nError;
  1126. break;
  1127. }
  1128. }
  1129. // Big logic here. This is where we wait for all of the
  1130. // conusmer processes to complete if we have consumers and
  1131. // all of the provider threads. The provider threads wait for the
  1132. // provider processes to complete so we just wait on the threads.
  1133. // One of the provider threads starts the consumer processes but
  1134. // does not wait on them. So we wait on them here. Again, we
  1135. // wait on the consumer threads.
  1136. // After the threads complete we will call StopTrace.
  1137. // Create an array to hold the handles
  1138. HANDLE *phandleAllThreads =
  1139. (HANDLE *) malloc (sizeof (HANDLE) *
  1140. (pstructTCOFunctionalData->m_nProviders +
  1141. pstructTCOFunctionalData->m_nConsumers));
  1142. RtlZeroMemory
  1143. (phandleAllThreads,
  1144. sizeof (HANDLE) *
  1145. (pstructTCOFunctionalData->m_nProviders +
  1146. pstructTCOFunctionalData->m_nConsumers));
  1147. int nHandles = 0;
  1148. // Copy handles into it.
  1149. for (i = 0; i < pstructTCOFunctionalData->m_nProviders; i++)
  1150. {
  1151. if (phandleProviderThreads[i])
  1152. {
  1153. phandleAllThreads[nHandles++] = phandleProviderThreads[i];
  1154. }
  1155. }
  1156. for (i = 0; i < pstructTCOFunctionalData->m_nConsumers; i++)
  1157. {
  1158. if (pstructStartTraceData[npstructStartTraceDataWithConsumers]->m_handleConsmers[i])
  1159. {
  1160. phandleAllThreads[nHandles++] =
  1161. pstructStartTraceData[npstructStartTraceDataWithConsumers]->m_handleConsmers[i];
  1162. }
  1163. }
  1164. Sleep (5000);
  1165. // Wait for the provider and consumer threads to complete.
  1166. DWORD dwWait =
  1167. WaitForMultipleObjects
  1168. (
  1169. nHandles,
  1170. phandleAllThreads,
  1171. TRUE,
  1172. 10000
  1173. );
  1174. free(phandleAllThreads); // Just free storage the handles get closed elsewhere.
  1175. int nAPICallResult = 0;
  1176. if (pstructStartTraceData[0]->m_pstructTCOData->m_pProps->LoggerName &&
  1177. pstructStartTraceData[0]->m_pstructTCOData->m_pProps)
  1178. {
  1179. nResult = StopTraceAPI
  1180. (
  1181. lptstrAction,
  1182. NULL, // Only use name.
  1183. NULL, // If valid we will log to it, can be NULL.
  1184. false,
  1185. true,
  1186. pstructStartTraceData[0]->m_pstructTCOData,
  1187. &nAPICallResult
  1188. );
  1189. if (nAPICallResult != ERROR_SUCCESS)
  1190. {
  1191. LPTSTR lptstrError =
  1192. DecodeStatus(nAPICallResult);
  1193. t_string tsError;
  1194. tsError = _T("StopTraceAPI failed with error: ");
  1195. tsError += lptstrError;
  1196. lptstrTCOTestError =
  1197. NewTCHAR(tsError.c_str());
  1198. free (lptstrError);
  1199. lptstrError = NULL;
  1200. nResult = nAPICallResult;
  1201. }
  1202. }
  1203. // Need to CloseHandle(); before we free these guys!
  1204. for (i = 0; i < pstructTCOFunctionalData->m_nProviders; i++)
  1205. {
  1206. if (phandleProviderThreads[i])
  1207. {
  1208. if (phandleProviderThreads[i])
  1209. {
  1210. CloseHandle(phandleProviderThreads[i]);
  1211. }
  1212. }
  1213. }
  1214. free (phandleProviderThreads);
  1215. FreeProcessDataArray
  1216. (pstructProviderDataArray,pstructTCOFunctionalData->m_nProviders);
  1217. FreeProcessDataArray
  1218. (pstructConsumerDataArray,pstructTCOFunctionalData->m_nConsumers);
  1219. FreeStartTraceWithProviderDataArray
  1220. (pstructStartTraceData,pstructTCOFunctionalData->m_nProviders);
  1221. return nResult;
  1222. }
  1223. // This gets started in its own thread and its caller waits for it to complete.
  1224. unsigned int __stdcall RunActionScenarioWithProvider(void *pVoid)
  1225. {
  1226. StartTraceWithProviderData *pData =
  1227. (StartTraceWithProviderData *) pVoid;
  1228. t_string tsLogMsg;
  1229. tsLogMsg = _T("RunActionScenarioWithProvider");
  1230. ThreadLogger(1,tsLogMsg.c_str(),_T(""),false,0);
  1231. pData->m_pstructConsumerDataArray = NULL;
  1232. // We do not exit this function until the process has failed to be
  1233. // created or has completed. We can not free things in the ProcessData
  1234. // structure until we are sure that the thread has exited one way or
  1235. // another.
  1236. UINT uiThreadId = NULL;
  1237. HANDLE hThreadProvider =
  1238. (HANDLE) _beginthreadex
  1239. (NULL, 0, RunProcess, (void *) pData->m_pstructProcessData, 0 , &uiThreadId);
  1240. if (hThreadProvider == 0)
  1241. {
  1242. int nError = errno;
  1243. pData->m_lptstrTCOTestError =
  1244. NewTCHAR(_T("Could not start RunProcesss thread."));
  1245. ThreadLogger(3,_T("RunActionScenarioWithProvider"),
  1246. pData->m_lptstrTCOTestError,true, nError);
  1247. _endthreadex(nError);
  1248. return nError;
  1249. }
  1250. DWORD dwReturn =
  1251. WaitForSingleObject
  1252. (pData->m_pstructProcessData->m_hEventContinue, 6000);
  1253. // Give the thread 1 second to get going.
  1254. Sleep(3000);
  1255. // If the thread is not active there was a problem getting it
  1256. // started so we will bail.
  1257. DWORD dwExitCode;
  1258. GetExitCodeThread(hThreadProvider, &dwExitCode);
  1259. if (dwExitCode != STILL_ACTIVE ||
  1260. pData->m_pstructProcessData->m_dwThreadReturn == ERROR_COULD_NOT_CREATE_PROCESS)
  1261. {
  1262. CloseHandle(hThreadProvider);
  1263. if (pData->m_pstructProcessData->m_dwThreadReturn == ERROR_COULD_NOT_CREATE_PROCESS)
  1264. {
  1265. pData->m_lptstrTCOTestError = NewTCHAR(_T("Could not create process."));
  1266. }
  1267. else
  1268. {
  1269. pData->m_lptstrTCOTestError = NewTCHAR(_T("Error in RunProcesss thread."));
  1270. }
  1271. if(pData->m_pstructProcessData->m_hProcess)
  1272. {
  1273. CloseHandle(pData->m_pstructProcessData->m_hProcess);
  1274. pData->m_pstructProcessData->m_hProcess = NULL;
  1275. }
  1276. ThreadLogger(2,_T("RunActionScenarioWithProvider"),
  1277. pData->m_lptstrTCOTestError,false, 0);
  1278. _endthreadex(-1);
  1279. return -1;
  1280. }
  1281. t_string tsDetailFile;
  1282. if (pData->m_lptstrDetailPath)
  1283. {
  1284. tsDetailFile = pData->m_lptstrDetailPath;
  1285. tsDetailFile += _T("\\");
  1286. tsDetailFile += GetTestName(pData->m_lptstrDataFile);
  1287. }
  1288. // nAPICallResult is what the StartTrace call returned.
  1289. // If the call does not succeed we have to clean up the
  1290. // process. If the call does succeed we need to call
  1291. // EnableTrace to get the provider going.
  1292. int nAPICallResult = ERROR_SUCCESS;
  1293. int nResult =
  1294. StartTraceAPI
  1295. (
  1296. pData->m_lptstrAction,
  1297. pData->m_lptstrDataFile,
  1298. pData->m_lptstrDetailPath ? tsDetailFile.c_str() : NULL,
  1299. false,
  1300. pData->m_pstructTCOData,
  1301. &nAPICallResult
  1302. );
  1303. // Big assumption here!
  1304. // If nAPICallResult == 0x000000a1 we assume that multiple StartTraces and that
  1305. // the first one succeeded!
  1306. if (nAPICallResult == ERROR_BAD_PATHNAME)
  1307. {
  1308. ThreadLogger(3,_T("RunActionScenarioWithProvider"),
  1309. _T("StartTraceAPI function returned ERROR_BAD_PATHNAME. Proceeding."),false, 0);
  1310. nAPICallResult = ERROR_SUCCESS;
  1311. nResult = ERROR_SUCCESS;
  1312. }
  1313. else
  1314. {
  1315. ThreadLogger(3,_T("RunActionScenarioWithProvider"),
  1316. _T("StartTraceAPI function returned "),true, nResult);
  1317. ThreadLogger(3,_T("RunActionScenarioWithProvider"),
  1318. _T("StartTrace API call returned "),true, nAPICallResult);
  1319. }
  1320. if (nAPICallResult != ERROR_SUCCESS)
  1321. {
  1322. // Here we must cleanup process because
  1323. // provider is running and we must stop it!
  1324. BOOL bResult =
  1325. TerminateProcess(pData->m_pstructProcessData->m_hProcess,0);
  1326. if (!bResult)
  1327. {
  1328. int nError = GetLastError();
  1329. ThreadLogger(3,_T("RunActionScenarioWithProvider"),
  1330. _T("Could not terminate process "),true, nError);
  1331. }
  1332. // Do not want to free the data structures until process
  1333. // terminates. Use thread as surrogate for process.
  1334. GetExitCodeThread(hThreadProvider, &dwExitCode);
  1335. while (dwExitCode == STILL_ACTIVE)
  1336. {
  1337. Sleep(500);
  1338. GetExitCodeThread(hThreadProvider, &dwExitCode);
  1339. }
  1340. }
  1341. // If we were able to call StartTrace successfully we must call
  1342. // EnableTrace to get the provider going so it can complete.
  1343. // If we do not successfully call EnableTrace we need to
  1344. // clean up the thread and the process.
  1345. if (nAPICallResult == ERROR_SUCCESS)
  1346. {
  1347. // If we cannot start the provider using the GUID in
  1348. // Wnode.Guid we give up. Also, we do not care
  1349. // if EnableTrace fails for the other GUIDs.
  1350. ULONG ulStatus = EnableTraceAPI
  1351. (
  1352. pData->m_lptstrAction,
  1353. NULL,
  1354. NULL,
  1355. false,
  1356. -1,
  1357. pData->m_pstructTCOData,
  1358. &nAPICallResult
  1359. );
  1360. // Exit here after we clean up!
  1361. if (nAPICallResult != ERROR_SUCCESS)
  1362. {
  1363. pData->m_lptstrTCOTestError = NewTCHAR(_T("Could not EnableTrace to start provider."));
  1364. // Here we must cleanup thread and process because
  1365. // EnableTrace failed.
  1366. TerminateProcess(pData->m_pstructProcessData->m_hProcess,0);
  1367. // Do not want to free the data structures until process
  1368. // terminates. Use thread as surrogate for process.
  1369. GetExitCodeThread(hThreadProvider, &dwExitCode);
  1370. while (dwExitCode == STILL_ACTIVE)
  1371. {
  1372. Sleep(500);
  1373. }
  1374. CloseHandle(hThreadProvider);
  1375. if(pData->m_pstructProcessData->m_hProcess)
  1376. {
  1377. CloseHandle(pData->m_pstructProcessData->m_hProcess);
  1378. pData->m_pstructProcessData->m_hProcess = NULL;
  1379. }
  1380. ThreadLogger(2,_T("RunActionScenarioWithProvider"),
  1381. pData->m_lptstrTCOTestError,true,ulStatus);
  1382. _endthreadex(nAPICallResult);
  1383. return nAPICallResult;
  1384. }
  1385. if (pData->m_bStartConsumers)
  1386. {
  1387. if (pData->m_pstructTCOFunctionalData->m_nConsumers > 0)
  1388. {
  1389. pData->m_pstructConsumerDataArray =
  1390. (ProcessData **) malloc
  1391. (sizeof (ProcessData *) *
  1392. pData->m_pstructTCOFunctionalData->m_nConsumers);
  1393. RtlZeroMemory
  1394. (pData->m_pstructConsumerDataArray,
  1395. sizeof (ProcessData *) *
  1396. pData->m_pstructTCOFunctionalData->m_nConsumers);
  1397. int n;
  1398. for (n = 0; n < pData->m_pstructTCOFunctionalData->m_nConsumers; n++)
  1399. {
  1400. pData->m_pstructConsumerDataArray[n] =
  1401. InitializeProcessData
  1402. (
  1403. pData->m_pstructTCOData,
  1404. pData->m_pstructTCOFunctionalData,
  1405. pData->m_lptstrDetailPath,
  1406. n, // 0 index gets the first provider or consumer.
  1407. false // bProvider, if false we get Consumer.
  1408. );
  1409. if (!pData->m_pstructConsumerDataArray[n]->m_hEventContinue ||
  1410. !pData->m_pstructConsumerDataArray[n]->m_hEventProcessCompleted)
  1411. {
  1412. pData->m_lptstrTCOTestError =
  1413. NewTCHAR(_T("Could not create events."));
  1414. CloseHandle(hThreadProvider);
  1415. if(pData->m_pstructProcessData->m_hProcess)
  1416. {
  1417. CloseHandle(pData->m_pstructProcessData->m_hProcess);
  1418. pData->m_pstructProcessData->m_hProcess = NULL;
  1419. }
  1420. ThreadLogger(2,_T("RunActionScenarioWithProvider"),
  1421. pData->m_lptstrTCOTestError,false,0);
  1422. _endthreadex(-1);
  1423. return -1;
  1424. }
  1425. }
  1426. for (n = 0; n < pData->m_pstructTCOFunctionalData->m_nConsumers; n++)
  1427. {
  1428. UINT uiThreadId = NULL;
  1429. pData->m_handleConsmers[n] =
  1430. (HANDLE) _beginthreadex
  1431. (NULL,
  1432. 0,
  1433. RunProcess,
  1434. (void *) pData->m_pstructConsumerDataArray[n],
  1435. 0 ,
  1436. &uiThreadId);
  1437. // We use the thread as the surrogate for the process because
  1438. // we do not exit the thread until the process ends or is
  1439. // terminated.
  1440. if (pData->m_handleConsmers[n] == 0)
  1441. {
  1442. int nError = errno;
  1443. pData->m_lptstrTCOTestError =
  1444. NewTCHAR(_T("Could not start RunProcesss thread for consumer."));
  1445. CloseHandle(hThreadProvider);
  1446. if(pData->m_pstructProcessData->m_hProcess)
  1447. {
  1448. CloseHandle(pData->m_pstructProcessData->m_hProcess);
  1449. pData->m_pstructProcessData->m_hProcess = NULL;
  1450. }
  1451. ThreadLogger(2,_T("RunActionScenarioWithProvider"),
  1452. pData->m_lptstrTCOTestError,true,errno);
  1453. _endthreadex(errno);
  1454. return nError;
  1455. }
  1456. Sleep(3000);
  1457. // We do not need the handle to the process.
  1458. if (pData->m_pstructConsumerDataArray[n]->m_hProcess)
  1459. {
  1460. CloseHandle(pData->m_pstructConsumerDataArray[n]->m_hProcess);
  1461. pData->m_pstructConsumerDataArray[n]->m_hProcess = 0;
  1462. }
  1463. }
  1464. }
  1465. }
  1466. // Enable the other GUIDS for provider. We do not check
  1467. // the return code.
  1468. for (int i = 0; i < pData->m_pstructTCOData->m_nGuids; i++)
  1469. {
  1470. EnableTraceAPI
  1471. (
  1472. pData->m_lptstrAction,
  1473. NULL,
  1474. NULL,
  1475. false,
  1476. i,
  1477. pData->m_pstructTCOData,
  1478. &nAPICallResult
  1479. );
  1480. Sleep(3000);
  1481. }
  1482. }
  1483. // Do not need this.
  1484. CloseHandle(hThreadProvider);
  1485. if (nAPICallResult == ERROR_SUCCESS)
  1486. {
  1487. ThreadLogger(3,_T("RunActionScenarioWithProvider"),
  1488. _T("About to wait for process to complete "),false, 0);
  1489. dwReturn =
  1490. WaitForSingleObject
  1491. (pData->m_pstructProcessData->m_hEventProcessCompleted, 6000);
  1492. ThreadLogger(3,_T("RunActionScenarioWithProvider"),
  1493. _T("After wait for process to complete "),false, 0);
  1494. }
  1495. if (nResult != ERROR_SUCCESS)
  1496. {
  1497. t_string tsError;
  1498. tsError = _T("Failure in RunActionScenarioWithProvider: StartTraceAPI failed.");
  1499. pData->m_lptstrTCOTestError = NewTCHAR(tsError.c_str());
  1500. if (nAPICallResult != ERROR_SUCCESS)
  1501. {
  1502. if(pData->m_pstructProcessData->m_hProcess)
  1503. {
  1504. CloseHandle(pData->m_pstructProcessData->m_hProcess);
  1505. pData->m_pstructProcessData->m_hProcess = NULL;
  1506. }
  1507. ThreadLogger(2,_T("RunActionScenarioWithProvider"),
  1508. pData->m_lptstrTCOTestError,true,nResult);
  1509. _endthreadex(nResult);
  1510. return nResult;
  1511. }
  1512. }
  1513. if(pData->m_pstructProcessData->m_hProcess)
  1514. {
  1515. CloseHandle(pData->m_pstructProcessData->m_hProcess);
  1516. pData->m_pstructProcessData->m_hProcess = NULL;
  1517. }
  1518. ThreadLogger(2,_T("RunActionScenarioWithProvider"),
  1519. _T("Normal exit"),true,nResult);
  1520. _endthreadex(nResult);
  1521. return nResult;
  1522. }
  1523. // This can deal with command line arguments in double quotes and
  1524. // you must double quote command line arguments which contain spaces.
  1525. t_string FindValue(t_string tsCommandLine, int nPos)
  1526. {
  1527. int nLen = tsCommandLine.length();
  1528. TCHAR tc = tsCommandLine[nPos];
  1529. bool bQuote = false;
  1530. while ((nPos < nLen) && tc == _T(' ') || tc == _T('\t') || tc == _T('"'))
  1531. {
  1532. if (tc == _T('"'))
  1533. {
  1534. // Quotes allow embedded white spaces.
  1535. bQuote = true;
  1536. }
  1537. ++nPos;
  1538. tc = tsCommandLine[nPos];
  1539. }
  1540. if (nPos == nLen)
  1541. {
  1542. return _T(""); // Empty string means failure.
  1543. }
  1544. int nEnd = nPos;
  1545. tc = tsCommandLine[nEnd];
  1546. while ((nEnd < nLen) &&
  1547. ( (!bQuote && (tc != _T(' ') && tc != _T('\t')))
  1548. ||
  1549. (bQuote && tc != _T('"'))
  1550. )
  1551. )
  1552. {
  1553. ++nEnd;
  1554. tc = tsCommandLine[nEnd];
  1555. }
  1556. t_string tsReturn;
  1557. tsReturn = tsCommandLine.substr(nPos,nEnd - nPos);
  1558. return tsReturn;
  1559. }
  1560. int GetArgs
  1561. (
  1562. t_string tsCommandLine,
  1563. LPTSTR &lptstrAction,
  1564. LPTSTR &lptstrDataFile,
  1565. LPTSTR &lptstrDetailPath,
  1566. LPTSTR &lptstrUpdateDataFile,
  1567. LPTSTR &lptstrProviderExe,
  1568. bool &bLogExpected,
  1569. bool &bUseTraceHandle
  1570. )
  1571. {
  1572. int nFind;
  1573. nFind = tsCommandLine.find(_T("-action"));
  1574. t_string tsValue;
  1575. if (nFind != t_string::npos)
  1576. {
  1577. nFind += 7;
  1578. tsValue= FindValue(tsCommandLine,nFind);
  1579. if (tsValue.empty())
  1580. {
  1581. return -1;
  1582. }
  1583. else
  1584. {
  1585. lptstrAction = NewTCHAR(tsValue.c_str());
  1586. }
  1587. tsValue.erase();
  1588. }
  1589. nFind = tsCommandLine.find(_T("-file"));
  1590. if (nFind != t_string::npos)
  1591. {
  1592. nFind += 5;
  1593. tsValue= FindValue(tsCommandLine,nFind);
  1594. if (tsValue.empty())
  1595. {
  1596. return -1;
  1597. }
  1598. else
  1599. {
  1600. lptstrDataFile = NewTCHAR(tsValue.c_str());
  1601. }
  1602. tsValue.erase();
  1603. }
  1604. nFind = tsCommandLine.find(_T("-detail"));
  1605. if (nFind == t_string::npos)
  1606. {
  1607. nFind += 7;
  1608. tsValue= FindValue(tsCommandLine,nFind);
  1609. if (tsValue.empty())
  1610. {
  1611. return -1;
  1612. }
  1613. }
  1614. else
  1615. {
  1616. nFind += 7;
  1617. tsValue= FindValue(tsCommandLine,nFind);
  1618. if (tsValue.empty())
  1619. {
  1620. return -1;
  1621. }
  1622. else
  1623. {
  1624. lptstrDetailPath = NewTCHAR(tsValue.c_str());
  1625. }
  1626. tsValue.erase();
  1627. }
  1628. nFind = tsCommandLine.find(_T("-logexpected"));
  1629. if (nFind != t_string::npos)
  1630. {
  1631. nFind += 12;
  1632. tsValue= FindValue(tsCommandLine,nFind);
  1633. if (tsValue.empty())
  1634. {
  1635. return -1;
  1636. }
  1637. else
  1638. {
  1639. int nComp = tsValue.compare(_T("0"));
  1640. if (nComp == 0)
  1641. {
  1642. bLogExpected = false;
  1643. }
  1644. else
  1645. {
  1646. bLogExpected = true;
  1647. }
  1648. }
  1649. tsValue.erase();
  1650. }
  1651. nFind = tsCommandLine.find(_T("-usetracehandle"));
  1652. if (nFind != t_string::npos)
  1653. {
  1654. nFind += 15;
  1655. tsValue= FindValue(tsCommandLine,nFind);
  1656. if (tsValue.empty())
  1657. {
  1658. return -1;
  1659. }
  1660. else
  1661. {
  1662. int nComp = tsValue.compare(_T("0"));
  1663. if (nComp == 0)
  1664. {
  1665. bUseTraceHandle = false;
  1666. }
  1667. else
  1668. {
  1669. bUseTraceHandle = true;
  1670. }
  1671. }
  1672. tsValue.erase();
  1673. }
  1674. nFind = tsCommandLine.find(_T("-providerexe"));
  1675. if (nFind != t_string::npos)
  1676. {
  1677. nFind += 12;
  1678. tsValue= FindValue(tsCommandLine,nFind);
  1679. if (tsValue.empty())
  1680. {
  1681. return -1;
  1682. }
  1683. else
  1684. {
  1685. lptstrProviderExe = NewTCHAR(tsValue.c_str());
  1686. }
  1687. tsValue.erase();
  1688. }
  1689. nFind = tsCommandLine.find(_T("-updatedata"));
  1690. if (nFind != t_string::npos)
  1691. {
  1692. nFind += 11;
  1693. tsValue= FindValue(tsCommandLine,nFind);
  1694. if (tsValue.empty())
  1695. {
  1696. return -1;
  1697. }
  1698. else
  1699. {
  1700. lptstrUpdateDataFile = NewTCHAR(tsValue.c_str());
  1701. }
  1702. tsValue.erase();
  1703. }
  1704. return 0;
  1705. }
  1706. int FreeArgs
  1707. (
  1708. LPTSTR &lptstrAction,
  1709. LPTSTR &lptstrDataFile,
  1710. LPTSTR &lptstrDetailPath,
  1711. LPTSTR &lptstrUpdateDataFile,
  1712. LPTSTR &lptstrProviderExe
  1713. )
  1714. {
  1715. free (lptstrAction);
  1716. free (lptstrDataFile);
  1717. free (lptstrDetailPath);
  1718. free (lptstrUpdateDataFile);
  1719. free (lptstrProviderExe);
  1720. lptstrAction = NULL;
  1721. lptstrDataFile = NULL;
  1722. lptstrDetailPath = NULL;
  1723. lptstrUpdateDataFile = NULL;
  1724. lptstrProviderExe = NULL;
  1725. return 0;
  1726. }
  1727. unsigned int __stdcall RunProcess(void * pVoid)
  1728. {
  1729. ProcessData *pProcessData = (ProcessData *) pVoid;
  1730. pProcessData->m_dwProcessReturn = 0;
  1731. pProcessData->m_dwThreadReturn = 0;
  1732. pProcessData->m_nSystemError = 0;
  1733. PROCESS_INFORMATION pinfoProvider;
  1734. RtlZeroMemory(&pinfoProvider, sizeof(PROCESS_INFORMATION));
  1735. STARTUPINFO sinfoProvider;
  1736. RtlZeroMemory(&sinfoProvider, sizeof(STARTUPINFO));
  1737. sinfoProvider.cb = sizeof(sinfoProvider);
  1738. sinfoProvider.lpReserved = NULL;
  1739. sinfoProvider.lpDesktop = NULL;
  1740. sinfoProvider.lpTitle = NULL;
  1741. sinfoProvider.dwFlags = 0;
  1742. sinfoProvider.cbReserved2 = 0;
  1743. sinfoProvider.lpReserved2 = NULL;
  1744. sinfoProvider.hStdInput = NULL;
  1745. sinfoProvider.hStdOutput = NULL;
  1746. sinfoProvider.hStdError = NULL;
  1747. BOOL bReturn =
  1748. CreateProcess(
  1749. pProcessData->m_lptstrExePath,
  1750. pProcessData->m_lptstrCmdLine,
  1751. NULL,
  1752. NULL,
  1753. NULL,
  1754. DETACHED_PROCESS,
  1755. NULL,
  1756. NULL,
  1757. &sinfoProvider,
  1758. &pinfoProvider);
  1759. if (!bReturn)
  1760. {
  1761. pProcessData->m_nSystemError = GetLastError();
  1762. pProcessData->m_dwThreadReturn = ERROR_COULD_NOT_CREATE_PROCESS;
  1763. SetEvent(pProcessData->m_hEventContinue);
  1764. _endthreadex(ERROR_COULD_NOT_CREATE_PROCESS);
  1765. return ERROR_COULD_NOT_CREATE_PROCESS;
  1766. }
  1767. pProcessData->m_hProcess = pinfoProvider.hProcess;
  1768. // Do not need to hold on to this!
  1769. CloseHandle(pinfoProvider.hThread);
  1770. // Give the process 5 seconds to get going.
  1771. Sleep(5000);
  1772. SetEvent(pProcessData->m_hEventContinue);
  1773. pProcessData->m_dwProcessReturn =
  1774. WaitForSingleObject(pinfoProvider.hProcess,6000);
  1775. if (pProcessData->m_dwProcessReturn != WAIT_OBJECT_0)
  1776. {
  1777. pProcessData->m_nSystemError = GetLastError();
  1778. pProcessData->m_dwThreadReturn = ERROR_WAIT_FAILED;
  1779. SetEvent(pProcessData->m_hEventProcessCompleted);
  1780. _endthreadex(ERROR_WAIT_FAILED);
  1781. return (ERROR_WAIT_FAILED);
  1782. }
  1783. bReturn =
  1784. GetExitCodeProcess
  1785. (pinfoProvider.hProcess, &pProcessData->m_dwProcessReturn);
  1786. if (!bReturn)
  1787. {
  1788. pProcessData->m_nSystemError = GetLastError();
  1789. pProcessData->m_dwThreadReturn =
  1790. ERROR_COULD_NOT_GET_PROCESS_RETURN;
  1791. SetEvent(pProcessData->m_hEventProcessCompleted);
  1792. _endthreadex(ERROR_COULD_NOT_GET_PROCESS_RETURN);
  1793. return (ERROR_COULD_NOT_GET_PROCESS_RETURN);
  1794. }
  1795. bReturn = SetEvent(pProcessData->m_hEventProcessCompleted);
  1796. if (!bReturn)
  1797. {
  1798. int n = GetLastError();
  1799. }
  1800. _endthreadex(0);
  1801. return (0);
  1802. }
  1803. t_string GetTestName(LPTSTR lptstrDataFile)
  1804. {
  1805. t_string tsTemp;
  1806. tsTemp = lptstrDataFile;
  1807. t_string tsPath;
  1808. int nBeg = tsTemp.find_last_of(_T('\\'));
  1809. ++nBeg;
  1810. int nEnd = tsTemp.find_last_of(_T('.'));
  1811. if (nEnd == t_string::npos)
  1812. {
  1813. nEnd = tsTemp.length();
  1814. }
  1815. int nNum = nEnd - nBeg;
  1816. tsTemp = tsTemp.substr(nBeg, nNum);
  1817. tsTemp += _T("Detail.txt");
  1818. return tsTemp;
  1819. }
  1820. ProcessData *InitializeProcessData
  1821. (
  1822. TCOData *pstructTCOData,
  1823. TCOFunctionalData *pstructTCOFunctionalData,
  1824. LPTSTR lptstrDetailPath,
  1825. int nProcessIndex,
  1826. bool bProvider
  1827. )
  1828. {
  1829. ProcessData *pstructProcessData = (ProcessData *) malloc(sizeof(ProcessData));
  1830. RtlZeroMemory(pstructProcessData, sizeof(ProcessData));
  1831. InitializeExeAndCmdLine
  1832. (
  1833. pstructProcessData,
  1834. pstructTCOData,
  1835. pstructTCOFunctionalData,
  1836. lptstrDetailPath,
  1837. nProcessIndex,
  1838. bProvider
  1839. );
  1840. pstructProcessData->m_lptstrTCOId =
  1841. NewTCHAR(pstructTCOData->m_lptstrShortDesc);
  1842. pstructProcessData->m_lptstrLogFile =
  1843. NewTCHAR(lptstrDetailPath);
  1844. // First Guid is in the properties.
  1845. int nGuids;
  1846. int nDelta;
  1847. if (pstructTCOData->m_pProps != NULL)
  1848. {
  1849. nGuids= pstructTCOData->m_nGuids + 1;
  1850. pstructProcessData->m_lpguidArray =
  1851. (GUID *) malloc (sizeof (GUID) * nGuids);
  1852. pstructProcessData->m_lpguidArray[0] = pstructTCOData->m_pProps->Wnode.Guid;
  1853. nDelta = 1;
  1854. }
  1855. else
  1856. {
  1857. nGuids= pstructTCOData->m_nGuids;
  1858. if (nGuids > 0)
  1859. {
  1860. pstructProcessData->m_lpguidArray =
  1861. (GUID *) malloc (sizeof (GUID) * nGuids);
  1862. }
  1863. else
  1864. {
  1865. pstructProcessData->m_lpguidArray = NULL;
  1866. }
  1867. nDelta = 0;
  1868. }
  1869. for (int i = 0; i < pstructTCOData->m_nGuids; i++)
  1870. {
  1871. pstructProcessData->m_lpguidArray[i + nDelta] =
  1872. pstructTCOData->m_lpguidArray[i];
  1873. }
  1874. pstructProcessData->m_hEventContinue = CreateEvent(NULL,FALSE,FALSE,NULL);;
  1875. pstructProcessData->m_hEventProcessCompleted = CreateEvent(NULL,FALSE,FALSE,NULL);;
  1876. pstructProcessData->m_hProcess = NULL;
  1877. pstructProcessData->m_dwProcessReturn = 0;
  1878. pstructProcessData->m_dwThreadReturn = 0;
  1879. pstructProcessData->m_nSystemError = 0;
  1880. return pstructProcessData;
  1881. }
  1882. void InitializeExeAndCmdLine
  1883. (
  1884. ProcessData *&pstructProcessData,
  1885. TCOData *pstructTCOData,
  1886. TCOFunctionalData *pstructTCOFunctionalData,
  1887. LPTSTR lptstrDetailPath,
  1888. int nProcessIndex,
  1889. bool bProvider
  1890. )
  1891. {
  1892. t_string tsProcess;
  1893. if (bProvider)
  1894. {
  1895. tsProcess = pstructTCOFunctionalData->m_lptstrProviderArray[nProcessIndex];
  1896. }
  1897. else
  1898. {
  1899. tsProcess = pstructTCOFunctionalData->m_lptstrConsumerArray[nProcessIndex];
  1900. }
  1901. t_string tsExe;
  1902. t_string tsCmdLine;
  1903. int nEndExe = tsProcess.find(_T(".exe"));
  1904. nEndExe += 4;
  1905. tsExe = tsProcess.substr(0,nEndExe);
  1906. if (nEndExe + 1 < tsExe.length())
  1907. {
  1908. tsCmdLine = tsProcess.substr(nEndExe + 1,t_string::npos);
  1909. }
  1910. tsCmdLine += _T(" -TESTID ");
  1911. tsCmdLine += pstructTCOData->m_lptstrShortDesc;
  1912. if (lptstrDetailPath)
  1913. {
  1914. tsCmdLine += _T("-TESTLOGPATH ");
  1915. tsCmdLine += lptstrDetailPath;
  1916. }
  1917. tsCmdLine += _T("-GUIDS ");
  1918. LPTSTR lptstrGuid = NULL;
  1919. if (pstructTCOData->m_pProps != 0 &&
  1920. pstructTCOData->m_pProps->Wnode.Guid.Data1 != 0 &&
  1921. pstructTCOData->m_pProps->Wnode.Guid.Data2 != 0 &&
  1922. pstructTCOData->m_pProps->Wnode.Guid.Data3 != 0)
  1923. {
  1924. lptstrGuid = LPTSTRFromGuid(pstructTCOData->m_pProps->Wnode.Guid);
  1925. tsCmdLine += lptstrGuid;
  1926. free (lptstrGuid);
  1927. lptstrGuid = NULL;
  1928. if (pstructTCOData->m_nGuids > 0)
  1929. {
  1930. tsCmdLine += _T(",");
  1931. }
  1932. }
  1933. if (pstructTCOData->m_pProps != 0)
  1934. {
  1935. for (int i = 0; i < pstructTCOData->m_nGuids; i++)
  1936. {
  1937. lptstrGuid = LPTSTRFromGuid(pstructTCOData->m_lpguidArray[i]);
  1938. tsCmdLine += lptstrGuid;
  1939. free (lptstrGuid);
  1940. lptstrGuid = NULL;
  1941. if (pstructTCOData->m_nGuids > 1
  1942. && i < pstructTCOData->m_nGuids - 1)
  1943. {
  1944. tsCmdLine += _T(",");
  1945. }
  1946. }
  1947. }
  1948. t_string tsTemp;
  1949. if (bProvider)
  1950. {
  1951. tsCmdLine += _T(" -EnableFlag ");
  1952. tsTemp = ULONGVarToTString(pstructTCOData->m_ulEnableFlag ,true);
  1953. tsCmdLine += tsTemp;
  1954. tsCmdLine += _T(" -EnableLevel ");
  1955. tsTemp = ULONGVarToTString(pstructTCOData->m_ulEnableLevel ,true);
  1956. tsCmdLine += tsTemp;
  1957. }
  1958. else
  1959. {
  1960. if (pstructTCOData->m_pProps != 0)
  1961. {
  1962. tsCmdLine += _T(" -LogFile ");
  1963. tsCmdLine += pstructTCOData->m_pProps->LogFileName;
  1964. tsCmdLine += _T(" -Logger ");
  1965. tsCmdLine += pstructTCOData->m_pProps->LoggerName;
  1966. }
  1967. }
  1968. pstructProcessData->m_lptstrExePath = NewTCHAR(tsExe.c_str());
  1969. pstructProcessData->m_lptstrCmdLine = NewTCHAR(tsCmdLine.c_str());
  1970. }
  1971. void FreeProcessDataArray(ProcessData **pProcessData, int nProcessData)
  1972. {
  1973. if (pProcessData == NULL)
  1974. {
  1975. return;
  1976. }
  1977. for (int i = 0; i < nProcessData; i++)
  1978. {
  1979. if (pProcessData[i])
  1980. {
  1981. FreeProcessData(pProcessData[i]);
  1982. }
  1983. }
  1984. free (pProcessData);
  1985. }
  1986. void FreeProcessData(ProcessData *pProcessData)
  1987. {
  1988. free (pProcessData->m_lptstrExePath);
  1989. free (pProcessData->m_lptstrCmdLine);
  1990. free (pProcessData->m_lptstrTCOId);
  1991. free (pProcessData->m_lptstrLogFile);
  1992. free (pProcessData->m_lpguidArray);
  1993. pProcessData->m_nGuids = 0;
  1994. if (pProcessData->m_hEventContinue)
  1995. {
  1996. if (pProcessData->m_hEventContinue)
  1997. {
  1998. CloseHandle(pProcessData->m_hEventContinue);
  1999. }
  2000. }
  2001. if (pProcessData->m_hEventProcessCompleted)
  2002. {
  2003. if (pProcessData->m_hEventProcessCompleted)
  2004. {
  2005. CloseHandle(pProcessData->m_hEventProcessCompleted);
  2006. }
  2007. }
  2008. if (pProcessData->m_hProcess)
  2009. {
  2010. if (pProcessData->m_hProcess)
  2011. {
  2012. CloseHandle(pProcessData->m_hProcess);
  2013. }
  2014. }
  2015. pProcessData->m_lptstrExePath = NULL;
  2016. pProcessData->m_lptstrCmdLine = NULL;
  2017. pProcessData->m_lptstrTCOId = NULL;
  2018. pProcessData->m_lptstrLogFile = NULL;
  2019. pProcessData->m_lpguidArray = NULL;
  2020. pProcessData->m_hEventContinue = NULL;
  2021. pProcessData->m_hEventProcessCompleted = NULL;
  2022. pProcessData->m_hProcess = NULL;
  2023. free (pProcessData);
  2024. }
  2025. void FreeStartTraceWithProviderData(StartTraceWithProviderData *p)
  2026. {
  2027. if (!p)
  2028. {
  2029. return;
  2030. }
  2031. free (p->m_lptstrTCOTestError);
  2032. p->m_lptstrTCOTestError = NULL;
  2033. int nConsumers = p->m_pstructTCOFunctionalData->m_nConsumers;
  2034. if (p->m_handleConsmers)
  2035. {
  2036. for (int i = 0; i < nConsumers; i++)
  2037. {
  2038. CloseHandle(p->m_handleConsmers[i]);
  2039. }
  2040. free(p->m_handleConsmers);
  2041. }
  2042. free(p);
  2043. // All other data is shared and freed elsewhere!
  2044. }
  2045. void FreeStartTraceWithProviderDataArray(StartTraceWithProviderData **p, int nP)
  2046. {
  2047. if (!p)
  2048. {
  2049. return;
  2050. }
  2051. for (int i = 0; i < nP; i++)
  2052. {
  2053. if (p[i])
  2054. {
  2055. FreeStartTraceWithProviderData(p[i]);
  2056. }
  2057. }
  2058. free(p);
  2059. }
  2060. // nState 1 = entering, 2 - leaving, 3 = none of the above.
  2061. void ThreadLogger
  2062. (int nState, LPCTSTR lptstrFunction, LPCTSTR lptstrMsg, bool bUseULONGValue, ULONG ulValue)
  2063. {
  2064. CRITICAL_SECTION csMyCriticalSection;
  2065. InitializeCriticalSection (&csMyCriticalSection);
  2066. __try
  2067. {
  2068. EnterCriticalSection (&csMyCriticalSection);
  2069. g_ThreadLogger.LogTCHAR(_T("\n"));
  2070. g_ThreadLogger.LogTCHAR(_T("Thread ID: "));
  2071. g_ThreadLogger.LogULONG((ULONG) GetCurrentThreadId());
  2072. g_ThreadLogger.LogTCHAR(_T(".\n"));
  2073. if (nState == 1)
  2074. {
  2075. g_ThreadLogger.LogTCHAR(_T("Entering - "));
  2076. }
  2077. else if (nState == 2)
  2078. {
  2079. g_ThreadLogger.LogTCHAR(_T("Leaving - "));
  2080. }
  2081. g_ThreadLogger.LogTCHAR(lptstrFunction);
  2082. if (_tcslen(lptstrMsg) > 0)
  2083. {
  2084. g_ThreadLogger.LogTCHAR(_T(":\n"));
  2085. g_ThreadLogger.LogTCHAR(lptstrMsg);
  2086. }
  2087. if (bUseULONGValue)
  2088. {
  2089. g_ThreadLogger.LogTCHAR(_T(" - "));
  2090. g_ThreadLogger.LogULONG(ulValue);
  2091. }
  2092. g_ThreadLogger.LogTCHAR(_T(".\n"));
  2093. }
  2094. __finally
  2095. {
  2096. // Release ownership of the critical section
  2097. LeaveCriticalSection (&csMyCriticalSection);
  2098. }
  2099. }