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.

3649 lines
125 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) 2002 Microsoft Corporation. All rights reserved.
  3. // Copyright (c) 2002 OSR Open Systems Resources, Inc.
  4. //
  5. // TraceView.cpp : Defines the class behaviors for the application.
  6. //////////////////////////////////////////////////////////////////////////////
  7. #include "stdafx.h"
  8. #include <tchar.h>
  9. #include <wmistr.h>
  10. #include <initguid.h>
  11. #include <objbase.h>
  12. #include <io.h>
  13. #include <new.h>
  14. #include <fcntl.h>
  15. extern "C" {
  16. #include <evntrace.h>
  17. }
  18. #include <traceprt.h>
  19. #include <guiddef.h>
  20. #include <wmiguid.h>
  21. #include <iostream.h>
  22. #include <ios>
  23. #include <conio.h>
  24. #include "TraceView.h"
  25. #include "DockDialogBar.h"
  26. #include "LogSession.h"
  27. #include "DisplayDlg.h"
  28. #include "ListCtrlEx.h"
  29. #include "LogSessionDlg.h"
  30. #include "MainFrm.h"
  31. #include "htmlhelp.h"
  32. #include "utils.h"
  33. extern "C" {
  34. #ifdef UNICODE
  35. typedef
  36. ULONG
  37. (*PFLUSH_TRACE_FUNC)(
  38. IN TRACEHANDLE TraceHandle,
  39. IN LPCWSTR InstanceName,
  40. IN OUT PEVENT_TRACE_PROPERTIES Properties
  41. );
  42. #else
  43. typedef
  44. ULONG
  45. (*PFLUSH_TRACE_FUNC)(
  46. IN TRACEHANDLE TraceHandle,
  47. IN LPCSTR InstanceName,
  48. IN OUT PEVENT_TRACE_PROPERTIES Properties
  49. );
  50. #endif
  51. typedef
  52. ULONG
  53. (*PENUMERATE_TRACE_GUIDS_FUNC)(
  54. IN OUT PTRACE_GUID_PROPERTIES *GuidPropertiesArray,
  55. IN ULONG PropertyArrayCount,
  56. OUT PULONG GuidCount
  57. );
  58. PENUMERATE_TRACE_GUIDS_FUNC EnumerateTraceGuidsFunction = NULL;
  59. PFLUSH_TRACE_FUNC FlushTraceFunction = NULL;
  60. }
  61. #ifdef _DEBUG
  62. #define new DEBUG_NEW
  63. #endif
  64. //
  65. // Global to this module
  66. //
  67. HINSTANCE advapidll=NULL;
  68. // CTraceViewApp
  69. BEGIN_MESSAGE_MAP(CTraceViewApp, CWinApp)
  70. ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  71. ON_COMMAND(ID_HELP_HELPTOPICS, OnHelpHelpTopics)
  72. ON_COMMAND(ID_HELP, OnHelpHelpTopics)
  73. END_MESSAGE_MAP()
  74. // CTraceViewApp construction
  75. CTraceViewApp::CTraceViewApp()
  76. {
  77. m_globalLoggerStartValue = 0;
  78. }
  79. CTraceViewApp::~CTraceViewApp()
  80. {
  81. }
  82. // The one and only CTraceViewApp object
  83. CTraceViewApp theApp;
  84. // CTraceViewApp initialization
  85. BOOL CTraceViewApp::InitInstance()
  86. {
  87. ULONG length;
  88. CString temp;
  89. GUID directoryGuid;
  90. CString str;
  91. STARTUPINFO startupInfo;
  92. //
  93. // Get the temp directory and save it
  94. //
  95. length = GetTempPath(0, NULL);
  96. m_traceDirectory.GetBuffer(MAX_PATH);
  97. if(length < GetTempPath(length, (LPTSTR)(LPCTSTR)m_traceDirectory)) {
  98. AfxMessageBox(_T("Failed To Create Temp Directory\nApplication Will Exit"));
  99. return FALSE;
  100. }
  101. //
  102. // make sure the directory exists
  103. //
  104. CreateDirectory(m_traceDirectory, NULL);
  105. //
  106. // I have to do this cast here
  107. // to get the string to allocate a new buffer
  108. // or the += operation below overwrites the
  109. // existing buffer??
  110. //
  111. m_traceDirectory = (LPCTSTR)m_traceDirectory;
  112. //
  113. // create our own unique directory under the temp directory
  114. //
  115. if(S_OK != CoCreateGuid(&directoryGuid)) {
  116. AfxMessageBox(_T("Failed To Create Temp Directory\nApplication Will Exit"));
  117. return FALSE;
  118. }
  119. GuidToString(directoryGuid, temp);
  120. m_traceDirectory += (LPCTSTR)temp;
  121. m_traceDirectory += (LPCTSTR)_T("\\");
  122. if(!CreateDirectory(m_traceDirectory, NULL) && (GetLastError() != ERROR_ALREADY_EXISTS)) {
  123. AfxMessageBox(_T("Failed To Create Temp Directory\nApplication Will Exit"));
  124. return FALSE;
  125. }
  126. //
  127. // Initialize the trace block ready array mutex
  128. //
  129. m_hTraceBlockMutex = CreateMutex(NULL,TRUE,NULL);
  130. if(m_hTraceBlockMutex == NULL) {
  131. DWORD error = GetLastError();
  132. str.Format(_T("CreateMutex Error %d %x"),error,error);
  133. AfxMessageBox(str);
  134. return FALSE;
  135. }
  136. ReleaseMutex(m_hTraceBlockMutex);
  137. advapidll = LoadLibrary(_T("advapi32.dll"));
  138. if (advapidll != NULL) {
  139. #ifdef UNICODE
  140. FlushTraceFunction = (PFLUSH_TRACE_FUNC)GetProcAddress(advapidll, "FlushTraceW");
  141. #else
  142. FlushTraceFunction = GetProcAddress(advapidll, "FlushTraceA");
  143. #endif
  144. EnumerateTraceGuidsFunction = (PENUMERATE_TRACE_GUIDS_FUNC)GetProcAddress(advapidll, "EnumerateTraceGuids");
  145. }
  146. //
  147. // Determine if this is a command line instance or a GUI instance
  148. //
  149. if(__argc > 1) {
  150. //
  151. // Hook up stdout, stdin, and stderr
  152. //
  153. InitializeConsole();
  154. CommandLine();
  155. return FALSE;
  156. }
  157. //
  158. // InitCommonControls() is required on Windows XP if an application
  159. // manifest specifies use of ComCtl32.dll version 6 or later to enable
  160. // visual styles. Otherwise, any window creation will fail.
  161. //
  162. InitCommonControls();
  163. CWinApp::InitInstance();
  164. //
  165. // Initialize OLE libraries
  166. //
  167. if (!AfxOleInit())
  168. {
  169. AfxMessageBox(IDP_OLE_INIT_FAILED);
  170. return FALSE;
  171. }
  172. AfxEnableControlContainer();
  173. //
  174. // Standard initialization
  175. // If you are not using these features and wish to reduce the size
  176. // of your final executable, you should remove from the following
  177. // the specific initialization routines you do not need
  178. // Change the registry key under which our settings are stored
  179. // TODO: You should modify this string to be something appropriate
  180. // such as the name of your company or organization
  181. //
  182. SetRegistryKey(_T("Local AppWizard-Generated Applications"));
  183. //
  184. // To create the main window, this code creates a new frame window
  185. // object and then sets it as the application's main window object
  186. //
  187. CMainFrame* pFrame = new CMainFrame;
  188. m_pMainWnd = pFrame;
  189. //
  190. // create and load the frame with its resources
  191. //
  192. if (!pFrame->LoadFrame(IDR_MAINFRAME)) {
  193. return FALSE;
  194. }
  195. //
  196. // The one and only window has been initialized, so show and update it
  197. //
  198. pFrame->ShowWindow(SW_SHOW);
  199. pFrame->UpdateWindow();
  200. //
  201. // Set the icon
  202. //
  203. AfxGetMainWnd()->SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE);
  204. //
  205. // call DragAcceptFiles only if there's a suffix
  206. // In an SDI app, this should occur after ProcessShellCommand
  207. //
  208. return TRUE;
  209. }
  210. int CTraceViewApp::ExitInstance()
  211. {
  212. CTraceMessage *pTraceMessage = NULL;
  213. LONG itemCount;
  214. //
  215. // Free the library we loaded earlier
  216. //
  217. FreeLibrary(advapidll);
  218. //
  219. // Free the trace block array
  220. //
  221. //
  222. // Get the free array protection
  223. //
  224. WaitForSingleObject(m_hTraceBlockMutex, INFINITE);
  225. itemCount = m_traceBlockArray.GetSize();
  226. ASSERT(itemCount == 0);
  227. for(LONG ii = 0; ii < itemCount; ii++) {
  228. //
  229. // delete the next entry in the list
  230. //
  231. delete m_traceBlockArray.GetAt(ii);
  232. }
  233. m_traceBlockArray.RemoveAll();
  234. //
  235. // Release the free array protection
  236. //
  237. ReleaseMutex(m_hTraceBlockMutex);
  238. //
  239. // Remove our temporary directory
  240. //
  241. if(!m_traceDirectory.IsEmpty()) {
  242. RemoveDirectory(m_traceDirectory);
  243. }
  244. return CWinApp::ExitInstance();
  245. }
  246. BOOL CTraceViewApp::InitializeConsole()
  247. {
  248. BOOL connected = FALSE;
  249. TCHAR outputPipeName[256];
  250. TCHAR inputPipeName[256];
  251. TCHAR errorPipeName[256];
  252. //
  253. // Initialize our console creation flag
  254. //
  255. m_bCreatedConsole = FALSE;
  256. //
  257. // construct named pipe names
  258. //
  259. _stprintf(outputPipeName,
  260. _T("\\\\.\\pipe\\%dcout"),
  261. GetCurrentProcessId());
  262. _stprintf(inputPipeName,
  263. _T("\\\\.\\pipe\\%dcin"),
  264. GetCurrentProcessId() );
  265. _stprintf(errorPipeName,
  266. _T("\\\\.\\pipe\\%dcerr"),
  267. GetCurrentProcessId() );
  268. //
  269. // attach named pipes to stdin/stdout/stderr
  270. //
  271. connected = (_tfreopen( outputPipeName, _T("a"), stdout ) != NULL) &&
  272. (_tfreopen( inputPipeName, _T("r"), stdin ) != NULL) &&
  273. (_tfreopen( errorPipeName, _T("a"), stderr ) != NULL);
  274. //
  275. // if unsuccessful, i.e. no console was available
  276. // we need to create a new console
  277. //
  278. if (!connected) {
  279. connected = AllocConsole();
  280. if (connected) {
  281. connected = (_tfreopen( _T("CONOUT$"), _T("a"), stdout ) != NULL) &&
  282. (_tfreopen( _T("CONIN$"), _T("r"), stdin ) != NULL) &&
  283. (_tfreopen( _T("CONERR$"), _T("a"), stderr ) != NULL);
  284. //
  285. // Indicate that we created a new console
  286. //
  287. m_bCreatedConsole = TRUE;
  288. }
  289. }
  290. //
  291. // synchronize iostreams with standard io
  292. //
  293. if(connected) {
  294. std::ios_base::sync_with_stdio();
  295. }
  296. return connected;
  297. }
  298. LONG CTraceViewApp::CommandLine()
  299. {
  300. CString str;
  301. LONG argc = __argc;
  302. LPTSTR loggerName;
  303. LONG sizeNeeded;
  304. LONG status = ERROR_INVALID_PARAMETER;
  305. //
  306. // dump all arguments
  307. //
  308. //for(LONG ii = 0; ii < argc; ii++) {
  309. // str.Format(_T("%ls"), __wargv[ii]);
  310. // AfxMessageBox(str);
  311. //}
  312. //AfxMessageBox(m_lpCmdLine);
  313. //
  314. // Initialize structure first
  315. //
  316. sizeNeeded = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAX_STR_LENGTH * sizeof(TCHAR);
  317. sizeNeeded += MAX_ENABLE_FLAGS * sizeof(ULONG); // for extension enable flags
  318. m_pLoggerInfo = (PEVENT_TRACE_PROPERTIES) new char[sizeNeeded];
  319. if (m_pLoggerInfo == NULL) {
  320. return (ERROR_OUTOFMEMORY);
  321. }
  322. RtlZeroMemory(m_pLoggerInfo, sizeNeeded);
  323. m_pLoggerInfo->Wnode.BufferSize = sizeNeeded;
  324. m_pLoggerInfo->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  325. m_pLoggerInfo->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  326. m_pLoggerInfo->LogFileNameOffset = m_pLoggerInfo->LoggerNameOffset + (MAX_STR_LENGTH * sizeof(TCHAR));
  327. loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
  328. _tcscpy(loggerName, KERNEL_LOGGER_NAME);
  329. if(!_tcscmp(__wargv[1], _T("-start") )) {
  330. status = StartSession();
  331. }
  332. if(!_tcscmp(__wargv[1], _T("-stop") )) {
  333. status = StopSession();
  334. }
  335. if(!_tcscmp(__wargv[1], _T("-update") )) {
  336. status = UpdateActiveSession();
  337. }
  338. if(!_tcscmp(__wargv[1], _T("-enable") )) {
  339. status = EnableProvider(TRUE);
  340. }
  341. if(!_tcscmp(__wargv[1], _T("-disable") )) {
  342. status = EnableProvider(FALSE);
  343. }
  344. if(!_tcscmp(__wargv[1], _T("-flush") )) {
  345. status = FlushActiveBuffers();
  346. }
  347. if(!_tcscmp(__wargv[1], _T("-enumguid") )) {
  348. status = EnumerateRegisteredGuids();
  349. }
  350. if(!_tcscmp(__wargv[1], _T("-q") )) {
  351. status = QueryActiveSession();
  352. }
  353. if(!_tcscmp(__wargv[1], _T("-l") )) {
  354. status = ListActiveSessions(FALSE);
  355. }
  356. if(!_tcscmp(__wargv[1], _T("-x") )) {
  357. status = ListActiveSessions(TRUE);
  358. }
  359. if(!_tcscmp(__wargv[1], _T("-process") )) {
  360. status = ConsumeTraceEvents();
  361. }
  362. if(!_tcscmp(__wargv[1], _T("-parsepdb") )) {
  363. status = ExtractPdbInfo();
  364. }
  365. if(status == ERROR_INVALID_PARAMETER) {
  366. DisplayHelp();
  367. }
  368. if(m_bCreatedConsole) {
  369. //
  370. // Prompt user for input so that the console doesn't
  371. // disappear before the user sees what it displays
  372. //
  373. _tprintf(_T("\n\nPress any key to exit\n"));
  374. _getch();
  375. }
  376. return status;
  377. }
  378. LONG CTraceViewApp::StartSession()
  379. {
  380. CString str;
  381. LPTSTR loggerName = NULL;
  382. LPTSTR logFileName;
  383. LONG start = 2;
  384. LONG status;
  385. TRACEHANDLE loggerHandle = 0;
  386. CString guidFile;
  387. CString pdbFile;
  388. CString tmcPath;
  389. GUID guid;
  390. LONG guidCount = 0;
  391. ULONG enableFlags = 0;
  392. ULONG traceLevel = 0;
  393. ULONG specialLogger = 0;
  394. USHORT numberOfFlags = 0;
  395. USHORT offset;
  396. PTRACE_ENABLE_FLAG_EXTENSION flagExt;
  397. PULONG pFlags = NULL;
  398. LONG i;
  399. CFileFind fileFind;
  400. TCHAR drive[10];
  401. TCHAR path[MAXSTR];
  402. TCHAR file[MAXSTR];
  403. TCHAR ext[MAXSTR];
  404. pFlags = &m_pLoggerInfo->EnableFlags;
  405. loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
  406. logFileName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LogFileNameOffset);
  407. if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
  408. _tcscpy(loggerName, __wargv[2]);
  409. start = 3;
  410. }
  411. for(LONG ii = start; ii < __argc; ii++) {
  412. //
  413. // Set the buffer size
  414. //
  415. if(!_tcscmp(__wargv[ii], _T("-b"))) {
  416. if((ii + 1) < __argc) {
  417. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  418. m_pLoggerInfo->BufferSize = _ttoi(__wargv[ii + 1]);
  419. /*BUGBUG
  420. if (kdOn && m_pLoggerInfo->BufferSize > 3) {
  421. _tprintf(_T("Kernel Debugging has been enabled: Buffer size has been set to 3kBytes\n"));
  422. m_pLoggerInfo->BufferSize = 3;
  423. }
  424. */
  425. ii++;
  426. }
  427. }
  428. }
  429. //
  430. // Set the minimum number of buffers
  431. //
  432. if(!_tcscmp(__wargv[ii], _T("-min"))) {
  433. if((ii + 1) < __argc) {
  434. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  435. m_pLoggerInfo->MinimumBuffers = _ttoi(__wargv[ii + 1]);
  436. ii++;
  437. }
  438. }
  439. }
  440. //
  441. // Set the maximum number of buffers
  442. //
  443. if(!_tcscmp(__wargv[ii], _T("-max"))) {
  444. if((ii + 1) < __argc) {
  445. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  446. m_pLoggerInfo->MaximumBuffers = _ttoi(__wargv[ii + 1]);
  447. ii++;
  448. }
  449. }
  450. }
  451. //
  452. // Set the log file name
  453. //
  454. if(!_tcscmp(__wargv[ii], _T("-f"))) {
  455. if((ii + 1) < __argc) {
  456. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  457. _tfullpath(logFileName, __wargv[ii + 1], MAX_STR_LENGTH);
  458. ii++;
  459. }
  460. }
  461. }
  462. //
  463. // Set the log file append setting
  464. //
  465. if(!_tcscmp(__wargv[ii], _T("-append"))) {
  466. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_APPEND;
  467. }
  468. //
  469. // Set the preallocate setting
  470. //
  471. if(!_tcscmp(__wargv[ii], _T("-prealloc"))) {
  472. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_PREALLOCATE;
  473. }
  474. //
  475. // Set the sequential log file setting
  476. //
  477. if(!_tcscmp(__wargv[ii], _T("-seq"))) {
  478. if((ii + 1) < __argc) {
  479. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  480. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_SEQUENTIAL;
  481. m_pLoggerInfo->MaximumFileSize = _ttoi(__wargv[ii + 1]);
  482. ii++;
  483. }
  484. }
  485. }
  486. //
  487. // Set the sequential log file setting
  488. //
  489. if(!_tcscmp(__wargv[ii], _T("-cir"))) {
  490. if((ii + 1) < __argc) {
  491. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  492. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_CIRCULAR;
  493. m_pLoggerInfo->MaximumFileSize = _ttoi(__wargv[ii + 1]);
  494. ii++;
  495. }
  496. }
  497. }
  498. //
  499. // Set the new log file size setting
  500. //
  501. if(!_tcscmp(__wargv[ii], _T("-newfile"))) {
  502. if((ii + 1) < __argc) {
  503. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  504. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_NEWFILE;
  505. m_pLoggerInfo->MaximumFileSize = _ttoi(__wargv[ii + 1]);
  506. ii++;
  507. }
  508. }
  509. }
  510. //
  511. // Set the flush time setting
  512. //
  513. if(!_tcscmp(__wargv[ii], _T("-ft"))) {
  514. if((ii + 1) < __argc) {
  515. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  516. m_pLoggerInfo->FlushTimer = _ttoi(__wargv[ii + 1]);
  517. ii++;
  518. }
  519. }
  520. }
  521. //
  522. // Set the paged setting
  523. //
  524. if(!_tcscmp(__wargv[ii], _T("-paged"))) {
  525. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_USE_PAGED_MEMORY;
  526. }
  527. //
  528. // Get the control guid(s)
  529. //
  530. if(!_tcscmp(__wargv[ii], _T("-guid"))) {
  531. if((ii + 1) < __argc) {
  532. if(__wargv[ii + 1][0] == _T('#')) {
  533. m_guidArray.Add(__wargv[ii + 1][1]);
  534. guidCount++;
  535. } else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  536. _tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  537. // _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
  538. guidCount += GetGuids(guidFile);
  539. if (guidCount < 0) {
  540. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  541. } else if (guidCount == 0){
  542. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  543. status = ERROR_INVALID_PARAMETER;
  544. return status;
  545. }
  546. }
  547. ii++;
  548. }
  549. }
  550. //
  551. // Get the control guid(s) from a PDB file
  552. //
  553. if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
  554. if(((ii + 1) < __argc) &&
  555. ((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
  556. _tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  557. pdbFile = (LPCTSTR)pdbFile;
  558. ParsePdb(pdbFile, m_traceDirectory, TRUE);
  559. _tprintf(_T("\n\n"));
  560. tmcPath = (LPCTSTR)m_traceDirectory;
  561. tmcPath +=_T("\\*.tmc");
  562. if(!fileFind.FindFile(tmcPath)) {
  563. _tprintf(_T("Failed To Get Control GUID From PDB"));
  564. return ERROR_INVALID_PARAMETER;
  565. }
  566. while(fileFind.FindNextFile()) {
  567. tmcPath = fileFind.GetFileName();
  568. _tsplitpath(tmcPath, drive, path, file, ext );
  569. m_guidArray.Add(file);
  570. guidCount++;
  571. }
  572. tmcPath = fileFind.GetFileName();
  573. _tsplitpath(tmcPath, drive, path, file, ext );
  574. m_guidArray.Add(file);
  575. guidCount++;
  576. if (guidCount < 0) {
  577. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  578. } else if (guidCount == 0){
  579. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  580. status = ERROR_INVALID_PARAMETER;
  581. return status;
  582. }
  583. ii++;
  584. }
  585. }
  586. //
  587. // Check for real-time setting
  588. //
  589. if(!_tcscmp(__wargv[ii], _T("-rt"))) {
  590. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
  591. //
  592. // Did the user specify buffering only?
  593. //
  594. if ((ii + 1) < __argc) {
  595. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  596. if (__wargv[ii + 1][0] == 'b')
  597. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_BUFFERING_MODE;
  598. ii++;
  599. }
  600. }
  601. }
  602. //
  603. // Set the debug output setting
  604. //
  605. if(!_tcscmp(__wargv[ii], _T("-kd"))) {
  606. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_KD_FILTER_MODE;
  607. m_pLoggerInfo->BufferSize = 3;
  608. }
  609. //
  610. // Set the age (decay time) setting
  611. //
  612. if(!_tcscmp(__wargv[ii], _T("-age"))) {
  613. if((ii + 1) < __argc) {
  614. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  615. m_pLoggerInfo->AgeLimit = _ttoi(__wargv[ii + 1]);
  616. ii++;
  617. }
  618. }
  619. }
  620. //
  621. // Set the level
  622. //
  623. if(!_tcscmp(__wargv[ii], _T("-level"))) {
  624. if((ii + 1) < __argc) {
  625. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  626. traceLevel = _ttoi(__wargv[ii + 1]);
  627. ii++;
  628. }
  629. }
  630. }
  631. //
  632. // Set the flags
  633. //
  634. if((!_tcscmp(__wargv[ii], _T("-flag"))) || (!_tcscmp(__wargv[ii], _T("-flags")))) {
  635. if((ii + 1) < __argc) {
  636. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  637. //
  638. // Get the flags specified, convert from hex if necessary
  639. //
  640. if(__wargv[ii + 1][1] == _T('x') || __wargv[ii + 1][1] == _T('X')) {
  641. m_pLoggerInfo->EnableFlags |= ahextoi(__wargv[ii + 1]);
  642. } else {
  643. m_pLoggerInfo->EnableFlags |= _ttoi(__wargv[ii + 1]);
  644. }
  645. //
  646. // Copy flags for EnableTrace
  647. //
  648. enableFlags = m_pLoggerInfo->EnableFlags;
  649. //
  650. // Do not accept flags with MSB = 1.
  651. //
  652. if (0x80000000 & m_pLoggerInfo->EnableFlags) {
  653. _tprintf(_T("Invalid Flags: 0x%0X(%d.)\n"),
  654. m_pLoggerInfo->EnableFlags, m_pLoggerInfo->EnableFlags);
  655. status = ERROR_INVALID_PARAMETER;
  656. return status;
  657. }
  658. ii++;
  659. }
  660. }
  661. }
  662. //
  663. // Set the eflags
  664. //
  665. if(!_tcscmp(__wargv[ii], _T("-eflag"))) {
  666. if((ii + 2) < __argc) {
  667. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  668. numberOfFlags = (USHORT)_ttoi(__wargv[ii + 1]);
  669. ii++;
  670. if((numberOfFlags > MAX_ENABLE_FLAGS) || (numberOfFlags < 1)) {
  671. _tprintf(_T("Error: Invalid number of enable flags\n"));
  672. status = ERROR_INVALID_PARAMETER;
  673. return status;
  674. }
  675. offset = (USHORT) sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAX_STR_LENGTH * sizeof(TCHAR);
  676. m_pLoggerInfo->EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
  677. flagExt = (PTRACE_ENABLE_FLAG_EXTENSION)
  678. &m_pLoggerInfo->EnableFlags;
  679. flagExt->Offset = offset;
  680. flagExt->Length = (UCHAR)numberOfFlags;
  681. pFlags = (PULONG)(offset + (PCHAR) m_pLoggerInfo);
  682. for (i = 0; ((i < numberOfFlags) && ((ii + 1) < __argc)); i++) {
  683. if ((__wargv[ii + 1][0] == '-') || (__wargv[ii + 1][0] == '/')) {
  684. //
  685. // Correct the number of eflags when the user
  686. // types an incorrect number.
  687. // However, this does not work if the next
  688. // argument is Logger Name.
  689. //
  690. break;
  691. }
  692. pFlags[i] = ahextoi(__wargv[ii + 1]);
  693. ii++;
  694. // _tprintf(_T("Setting logger flags to 0x%0X(%d.)\n"),
  695. // pFlags[i], pFlags[i] );
  696. }
  697. numberOfFlags = (USHORT)i;
  698. for ( ; i < MAX_ENABLE_FLAGS; i++) {
  699. pFlags[i] = 0;
  700. }
  701. if (flagExt->Length != (UCHAR)numberOfFlags) {
  702. // _tprintf(_T("Correcting the number of eflags to %d\n"), i),
  703. flagExt->Length = (UCHAR)numberOfFlags;
  704. }
  705. }
  706. }
  707. }
  708. }
  709. /*
  710. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  711. if (GuidCount != 1) {
  712. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  713. return ERROR_INVALID_PARAMETER;
  714. }
  715. m_pLoggerInfo->Wnode.Guid = *GuidArray[0];
  716. }
  717. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_PREALLOCATE &&
  718. m_pLoggerInfo->MaximumFileSize == 0) {
  719. _tprintf(_T("Need file size for preallocated log file\n"));
  720. return ERROR_INVALID_PARAMETER;
  721. }
  722. // end_sdk
  723. if (specialLogger == 3) { // Global Logger
  724. status = SetGlobalLoggerSettings(1L, m_pLoggerInfo, m_pLoggerInfo->Wnode.ClientContext);
  725. if (status != ERROR_SUCCESS)
  726. break;
  727. status = GetGlobalLoggerSettings(m_pLoggerInfo, &m_pLoggerInfo->Wnode.ClientContext, &m_globalLoggerStartValue);
  728. break;
  729. }
  730. // begin_sdk
  731. if(m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_EXTENSION){
  732. if(IsEqualGUID(&CritSecGuid,GuidArray[0]) ||
  733. IsEqualGUID(&HeapGuid,GuidArray[0])){
  734. m_pLoggerInfo->Wnode.HistoricalContext = traceLevel;
  735. }
  736. }
  737. */
  738. if (!_tcscmp(loggerName, _T("NT Kernel Logger"))) {
  739. if (pFlags == &m_pLoggerInfo->EnableFlags) {
  740. *pFlags |= EVENT_TRACE_FLAG_PROCESS;
  741. *pFlags |= EVENT_TRACE_FLAG_THREAD;
  742. *pFlags |= EVENT_TRACE_FLAG_DISK_IO;
  743. *pFlags |= EVENT_TRACE_FLAG_NETWORK_TCPIP;
  744. }
  745. m_pLoggerInfo->Wnode.Guid = SystemTraceControlGuid; // defaults to OS
  746. }
  747. //
  748. // Set the default log file name if necessary
  749. //
  750. if(!(m_pLoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE)) {
  751. _tcscpy(logFileName, _T("C:\\LogFile.Etl"));
  752. }
  753. status = StartTrace(&loggerHandle, loggerName, m_pLoggerInfo);
  754. if (status != ERROR_SUCCESS) {
  755. _tprintf(_T("Could not start logger: %s\n")
  756. _T("Operation Status: %uL\n"),
  757. loggerName,
  758. status);
  759. } else {
  760. _tprintf(_T("Logger Started...\n"));
  761. }
  762. PrintLoggerStatus(status);
  763. if((guidCount > 0) && (specialLogger == 0)) {
  764. _tprintf(_T("Enabling trace to logger %d\n"), loggerHandle);
  765. for(ULONG ii = 0; ii < (ULONG)guidCount; ii++) {
  766. //
  767. // Convert the guid string to a guid
  768. //
  769. StringToGuid(m_guidArray[ii].GetBuffer(0), &guid);
  770. //
  771. // Enable the provider
  772. //
  773. status = EnableTrace (
  774. TRUE,
  775. enableFlags,
  776. traceLevel,
  777. &guid,
  778. loggerHandle);
  779. //
  780. // If the Guid can not be enabled, it is a benign
  781. // failure. Print Warning message and continue.
  782. //
  783. if (status == 4317) {
  784. _tprintf(_T("WARNING: Could not enable some guids.\n"));
  785. _tprintf(_T("Check your Guids file\n"));
  786. status = ERROR_SUCCESS;
  787. }
  788. if (status != ERROR_SUCCESS) {
  789. _tprintf(_T("ERROR: Failed to enable Guid [%d]...\n"), ii);
  790. _tprintf(_T("Operation Status: %uL\n"), status);
  791. _tprintf(_T("%s\n"),DecodeStatus(status));
  792. break;
  793. }
  794. }
  795. } else if (guidCount > 0) {
  796. _tprintf(_T("ERROR: System Logger does not accept application guids...\n"));
  797. status = ERROR_INVALID_PARAMETER;
  798. }
  799. return status;
  800. }
  801. LONG CTraceViewApp::StopSession()
  802. {
  803. TRACEHANDLE loggerHandle = 0;
  804. LPTSTR loggerName = NULL;
  805. LONG start = 2;
  806. LONG guidCount = 0;
  807. CString guidFile;
  808. GUID guid;
  809. LONG status;
  810. CString pdbFile;
  811. CString tmcPath;
  812. CFileFind fileFind;
  813. TCHAR drive[10];
  814. TCHAR path[MAXSTR];
  815. TCHAR file[MAXSTR];
  816. TCHAR ext[MAXSTR];
  817. //
  818. // Get the logger name string
  819. //
  820. loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
  821. if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
  822. loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
  823. _tcscpy(loggerName, __wargv[2]);
  824. start = 3;
  825. }
  826. for(LONG ii = start; ii < __argc; ii++) {
  827. //
  828. // Get the control guid(s)
  829. //
  830. if(!_tcscmp(__wargv[ii], _T("-guid"))) {
  831. if((ii + 1) < __argc) {
  832. if(__wargv[ii + 1][0] == _T('#')) {
  833. m_guidArray.Add(__wargv[ii + 1][1]);
  834. guidCount++;
  835. } else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  836. _tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  837. // _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
  838. guidCount += GetGuids(guidFile);
  839. if (guidCount < 0) {
  840. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  841. } else if (guidCount == 0){
  842. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  843. status = ERROR_INVALID_PARAMETER;
  844. return status;
  845. }
  846. }
  847. ii++;
  848. }
  849. }
  850. //
  851. // Get the control guid(s) from a PDB file
  852. //
  853. if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
  854. if(((ii + 1) < __argc) &&
  855. ((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
  856. _tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  857. pdbFile = (LPCTSTR)pdbFile;
  858. ParsePdb(pdbFile, m_traceDirectory, TRUE);
  859. _tprintf(_T("\n\n"));
  860. tmcPath = (LPCTSTR)m_traceDirectory;
  861. tmcPath +=_T("\\*.tmc");
  862. if(!fileFind.FindFile(tmcPath)) {
  863. _tprintf(_T("Failed To Get Control GUID From PDB"));
  864. return ERROR_INVALID_PARAMETER;
  865. }
  866. while(fileFind.FindNextFile()) {
  867. tmcPath = fileFind.GetFileName();
  868. _tsplitpath(tmcPath, drive, path, file, ext );
  869. m_guidArray.Add(file);
  870. guidCount++;
  871. }
  872. tmcPath = fileFind.GetFileName();
  873. _tsplitpath(tmcPath, drive, path, file, ext );
  874. m_guidArray.Add(file);
  875. guidCount++;
  876. if (guidCount < 0) {
  877. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  878. } else if (guidCount == 0){
  879. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  880. status = ERROR_INVALID_PARAMETER;
  881. return status;
  882. }
  883. ii++;
  884. }
  885. }
  886. }
  887. /*
  888. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  889. if (guidCount != 1) {
  890. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  891. Status = ERROR_INVALID_PARAMETER;
  892. break;
  893. }
  894. pLoggerInfo->Wnode.Guid = *m_guidArray[0];
  895. }
  896. if (specialLogger == 3)
  897. Status = GetGlobalLoggerSettings(pLoggerInfo, &pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
  898. */
  899. if(guidCount > 0) {
  900. /*
  901. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  902. Status = ControlTrace(loggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  903. if (Status != ERROR_SUCCESS)
  904. break;
  905. loggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  906. Status = EnableTrace( FALSE,
  907. EVENT_TRACE_PRIVATE_LOGGER_MODE,
  908. 0,
  909. m_guidArray[0],
  910. loggerHandle );
  911. }
  912. else {
  913. */
  914. status = ControlTrace(loggerHandle,
  915. loggerName,
  916. m_pLoggerInfo,
  917. EVENT_TRACE_CONTROL_QUERY);
  918. if(status == ERROR_WMI_INSTANCE_NOT_FOUND) {
  919. return status;
  920. }
  921. loggerHandle = m_pLoggerInfo->Wnode.HistoricalContext;
  922. for(ULONG i = 0; i < (ULONG)guidCount; i++) {
  923. //
  924. // Convert the string to a GUID
  925. //
  926. StringToGuid(m_guidArray[i].GetBuffer(0), &guid);
  927. EnableTrace(FALSE,
  928. 0,
  929. 0,
  930. &guid,
  931. loggerHandle);
  932. }
  933. // }
  934. }
  935. status = ControlTrace(loggerHandle,
  936. loggerName,
  937. m_pLoggerInfo,
  938. EVENT_TRACE_CONTROL_STOP);
  939. PrintLoggerStatus(status);
  940. return status;
  941. }
  942. LONG CTraceViewApp::ListActiveSessions(BOOL bKill)
  943. {
  944. ULONG returnCount ;
  945. ULONG listSizeNeeded;
  946. PEVENT_TRACE_PROPERTIES pListLoggerInfo[MAX_LOG_SESSIONS];
  947. PEVENT_TRACE_PROPERTIES pStorage;
  948. PVOID storage;
  949. LONG status;
  950. TRACEHANDLE loggerHandle = 0;
  951. listSizeNeeded = MAX_LOG_SESSIONS * (sizeof(EVENT_TRACE_PROPERTIES)
  952. + 2 * MAX_STR_LENGTH * sizeof(TCHAR));
  953. storage = malloc(listSizeNeeded);
  954. if (storage == NULL) {
  955. status = ERROR_OUTOFMEMORY;
  956. return status;
  957. }
  958. RtlZeroMemory(storage, listSizeNeeded);
  959. pStorage = (PEVENT_TRACE_PROPERTIES)storage;
  960. for (ULONG i = 0; i < MAX_LOG_SESSIONS; i++) {
  961. pStorage->Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES)
  962. + 2 * MAX_STR_LENGTH * sizeof(TCHAR);
  963. pStorage->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES)
  964. + MAX_STR_LENGTH * sizeof(TCHAR);
  965. pStorage->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  966. pListLoggerInfo[i] = pStorage;
  967. pStorage = (PEVENT_TRACE_PROPERTIES) (
  968. (char*)pStorage +
  969. pStorage->Wnode.BufferSize);
  970. }
  971. // if (XP) {
  972. status = QueryAllTraces(pListLoggerInfo,
  973. MAX_LOG_SESSIONS,
  974. &returnCount);
  975. /*
  976. }
  977. else {
  978. status = QueryAllTraces(pListLoggerInfo,
  979. 32,
  980. &returnCount);
  981. }
  982. */
  983. if (status == ERROR_SUCCESS)
  984. {
  985. for (ULONG j = 0; j < returnCount; j++)
  986. {
  987. LPTSTR ListLoggerName;
  988. TCHAR asked = _T('?') ;
  989. BOOL StatusPrint = FALSE ;
  990. if (bKill)
  991. {
  992. ListLoggerName = (LPTSTR) ((char*)pListLoggerInfo[j] +
  993. pListLoggerInfo[j]->LoggerNameOffset);
  994. /*
  995. if (!bForceKill) {
  996. while (!(asked == _T('y')) && !(asked == _T('n'))) {
  997. ULONG ReadChars = 0;
  998. _tprintf(_T("Do you want to kill Logger \"%s\" (Y or N)?"), ListLoggerName);
  999. ReadChars = _tscanf(_T(" %c"), &asked);
  1000. if (ReadChars == 0 || ReadChars == EOF) {
  1001. continue;
  1002. }
  1003. if (asked == _T('Y')) {
  1004. asked = _T('y') ;
  1005. } else if (asked == _T('N')) {
  1006. asked = _T('n') ;
  1007. }
  1008. }
  1009. } else {
  1010. */
  1011. asked = _T('y');
  1012. // }
  1013. if (asked == _T('y')) {
  1014. if (!IsEqualGUID(pListLoggerInfo[j]->Wnode.Guid,
  1015. SystemTraceControlGuid))
  1016. {
  1017. loggerHandle = pListLoggerInfo[j]->Wnode.HistoricalContext;
  1018. status = EnableTrace(
  1019. FALSE,
  1020. (pListLoggerInfo[j]->LogFileMode &
  1021. EVENT_TRACE_PRIVATE_LOGGER_MODE)
  1022. ? (EVENT_TRACE_PRIVATE_LOGGER_MODE)
  1023. : (0),
  1024. 0,
  1025. & pListLoggerInfo[j]->Wnode.Guid,
  1026. loggerHandle);
  1027. }
  1028. status = ControlTrace((TRACEHANDLE) 0,
  1029. ListLoggerName,
  1030. pListLoggerInfo[j],
  1031. EVENT_TRACE_CONTROL_STOP);
  1032. _tprintf(_T("Logger \"%s\" has been killed\n"), ListLoggerName);
  1033. StatusPrint = TRUE ;
  1034. } else {
  1035. _tprintf(_T("Logger \"%s\" has not been killed, current Status is\n"), ListLoggerName);
  1036. StatusPrint = FALSE ;
  1037. }
  1038. }
  1039. m_pLoggerInfo = pListLoggerInfo[j];
  1040. PrintLoggerStatus(status);
  1041. _tprintf(_T("\n"));
  1042. }
  1043. }
  1044. free(storage);
  1045. return status;
  1046. }
  1047. LONG CTraceViewApp::QueryActiveSession()
  1048. {
  1049. TRACEHANDLE loggerHandle = 0;
  1050. LPTSTR loggerName = NULL;
  1051. LONG start = 2;
  1052. LONG guidCount = 0;
  1053. CString guidFile;
  1054. GUID guid;
  1055. LONG status;
  1056. CString pdbFile;
  1057. CString tmcPath;
  1058. CFileFind fileFind;
  1059. TCHAR drive[10];
  1060. TCHAR path[MAXSTR];
  1061. TCHAR file[MAXSTR];
  1062. TCHAR ext[MAXSTR];
  1063. //
  1064. // Get the logger name string
  1065. //
  1066. loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
  1067. if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
  1068. _tcscpy(loggerName, __wargv[2]);
  1069. start = 3;
  1070. }
  1071. for(LONG ii = start; ii < __argc; ii++) {
  1072. //
  1073. // Get the control guid(s)
  1074. //
  1075. if(!_tcscmp(__wargv[ii], _T("-guid"))) {
  1076. if((ii + 1) < __argc) {
  1077. if(__wargv[ii + 1][0] == _T('#')) {
  1078. m_guidArray.Add(__wargv[ii + 1][1]);
  1079. guidCount++;
  1080. } else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1081. _tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  1082. // _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
  1083. guidCount += GetGuids(guidFile);
  1084. if (guidCount < 0) {
  1085. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  1086. } else if (guidCount == 0){
  1087. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  1088. status = ERROR_INVALID_PARAMETER;
  1089. return status;
  1090. }
  1091. }
  1092. ii++;
  1093. }
  1094. }
  1095. //
  1096. // Get the control guid(s) from a PDB file
  1097. //
  1098. if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
  1099. if(((ii + 1) < __argc) &&
  1100. ((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
  1101. _tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  1102. pdbFile = (LPCTSTR)pdbFile;
  1103. ParsePdb(pdbFile, m_traceDirectory, TRUE);
  1104. _tprintf(_T("\n\n"));
  1105. tmcPath = (LPCTSTR)m_traceDirectory;
  1106. tmcPath +=_T("\\*.tmc");
  1107. if(!fileFind.FindFile(tmcPath)) {
  1108. _tprintf(_T("Failed To Get Control GUID From PDB"));
  1109. return ERROR_INVALID_PARAMETER;
  1110. }
  1111. while(fileFind.FindNextFile()) {
  1112. tmcPath = fileFind.GetFileName();
  1113. _tsplitpath(tmcPath, drive, path, file, ext );
  1114. m_guidArray.Add(file);
  1115. guidCount++;
  1116. }
  1117. tmcPath = fileFind.GetFileName();
  1118. _tsplitpath(tmcPath, drive, path, file, ext );
  1119. m_guidArray.Add(file);
  1120. guidCount++;
  1121. if (guidCount < 0) {
  1122. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  1123. } else if (guidCount == 0){
  1124. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  1125. status = ERROR_INVALID_PARAMETER;
  1126. return status;
  1127. }
  1128. ii++;
  1129. }
  1130. }
  1131. }
  1132. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  1133. if (guidCount != 1) {
  1134. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  1135. status = ERROR_INVALID_PARAMETER;
  1136. return status;
  1137. }
  1138. StringToGuid(m_guidArray[0].GetBuffer(0), &guid);
  1139. m_pLoggerInfo->Wnode.Guid = guid;
  1140. }
  1141. /*
  1142. if (specialLogger == 3) {
  1143. status = GetGlobalLoggerSettings(m_pLoggerInfo, &m_pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
  1144. }
  1145. */
  1146. status = ControlTrace(loggerHandle, loggerName, m_pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  1147. PrintLoggerStatus(status);
  1148. return status;
  1149. }
  1150. LONG CTraceViewApp::FlushActiveBuffers()
  1151. {
  1152. TRACEHANDLE loggerHandle = 0;
  1153. LPTSTR loggerName = NULL;
  1154. LONG start = 2;
  1155. LONG guidCount = 0;
  1156. CString guidFile;
  1157. GUID guid;
  1158. LONG status;
  1159. CString pdbFile;
  1160. CString tmcPath;
  1161. CFileFind fileFind;
  1162. TCHAR drive[10];
  1163. TCHAR path[MAXSTR];
  1164. TCHAR file[MAXSTR];
  1165. TCHAR ext[MAXSTR];
  1166. //
  1167. // Get the logger name string
  1168. //
  1169. loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
  1170. if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
  1171. _tcscpy(loggerName, __wargv[2]);
  1172. start = 3;
  1173. }
  1174. for(LONG ii = start; ii < __argc; ii++) {
  1175. //
  1176. // Get the control guid(s)
  1177. //
  1178. if(!_tcscmp(__wargv[ii], _T("-guid"))) {
  1179. if((ii + 1) < __argc) {
  1180. if(__wargv[ii + 1][0] == _T('#')) {
  1181. m_guidArray.Add(__wargv[ii + 1][1]);
  1182. guidCount++;
  1183. } else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1184. _tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  1185. // _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
  1186. guidCount += GetGuids(guidFile);
  1187. if (guidCount < 0) {
  1188. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  1189. } else if (guidCount == 0){
  1190. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  1191. status = ERROR_INVALID_PARAMETER;
  1192. return status;
  1193. }
  1194. }
  1195. ii++;
  1196. }
  1197. }
  1198. //
  1199. // Get the control guid(s) from a PDB file
  1200. //
  1201. if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
  1202. if(((ii + 1) < __argc) &&
  1203. ((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
  1204. _tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  1205. pdbFile = (LPCTSTR)pdbFile;
  1206. ParsePdb(pdbFile, m_traceDirectory, TRUE);
  1207. _tprintf(_T("\n\n"));
  1208. tmcPath = (LPCTSTR)m_traceDirectory;
  1209. tmcPath +=_T("\\*.tmc");
  1210. if(!fileFind.FindFile(tmcPath)) {
  1211. _tprintf(_T("Failed To Get Control GUID From PDB"));
  1212. return ERROR_INVALID_PARAMETER;
  1213. }
  1214. while(fileFind.FindNextFile()) {
  1215. tmcPath = fileFind.GetFileName();
  1216. _tsplitpath(tmcPath, drive, path, file, ext );
  1217. m_guidArray.Add(file);
  1218. guidCount++;
  1219. }
  1220. tmcPath = fileFind.GetFileName();
  1221. _tsplitpath(tmcPath, drive, path, file, ext );
  1222. m_guidArray.Add(file);
  1223. guidCount++;
  1224. if (guidCount < 0) {
  1225. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  1226. } else if (guidCount == 0){
  1227. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  1228. status = ERROR_INVALID_PARAMETER;
  1229. return status;
  1230. }
  1231. ii++;
  1232. }
  1233. }
  1234. }
  1235. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  1236. if(guidCount != 1) {
  1237. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  1238. status = ERROR_INVALID_PARAMETER;
  1239. return status;
  1240. }
  1241. StringToGuid(m_guidArray[0].GetBuffer(0), &guid);
  1242. m_pLoggerInfo->Wnode.Guid = guid;
  1243. }
  1244. // status = (ULONG)FlushTrace(loggerHandle, loggerName, m_pLoggerInfo);
  1245. status = 1;
  1246. if(FlushTraceFunction) {
  1247. status = (ULONG)(FlushTraceFunction)(loggerHandle, loggerName, m_pLoggerInfo);
  1248. PrintLoggerStatus(status);
  1249. }
  1250. return status;
  1251. }
  1252. LONG CTraceViewApp::UpdateActiveSession()
  1253. {
  1254. TRACEHANDLE loggerHandle = 0;
  1255. LPTSTR loggerName = NULL;
  1256. LPTSTR logFileName = NULL;
  1257. LONG start = 2;
  1258. LONG guidCount = 0;
  1259. CString guidFile;
  1260. GUID guid;
  1261. LONG status;
  1262. ULONG enableFlags = 0;
  1263. ULONG specialLogger = 0;
  1264. USHORT numberOfFlags = 0;
  1265. USHORT offset;
  1266. PTRACE_ENABLE_FLAG_EXTENSION flagExt;
  1267. PULONG pFlags = NULL;
  1268. LONG i;
  1269. CString pdbFile;
  1270. CString tmcPath;
  1271. CFileFind fileFind;
  1272. TCHAR drive[10];
  1273. TCHAR path[MAXSTR];
  1274. TCHAR file[MAXSTR];
  1275. TCHAR ext[MAXSTR];
  1276. //
  1277. // Get the logger name string
  1278. //
  1279. loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
  1280. logFileName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LogFileNameOffset);
  1281. //
  1282. // Get the logger name
  1283. //
  1284. if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
  1285. _tcscpy(loggerName, __wargv[2]);
  1286. start = 3;
  1287. }
  1288. for(LONG ii = start; ii < __argc; ii++) {
  1289. //
  1290. // Set the maximum number of buffers
  1291. //
  1292. if(!_tcscmp(__wargv[ii], _T("-max"))) {
  1293. if((ii + 1) < __argc) {
  1294. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1295. m_pLoggerInfo->MaximumBuffers = _ttoi(__wargv[ii + 1]);
  1296. ii++;
  1297. }
  1298. }
  1299. }
  1300. //
  1301. // Set the log file name
  1302. //
  1303. if(!_tcscmp(__wargv[ii], _T("-f"))) {
  1304. if((ii + 1) < __argc) {
  1305. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1306. _tfullpath(logFileName, __wargv[ii + 1], MAX_STR_LENGTH);
  1307. ii++;
  1308. }
  1309. }
  1310. }
  1311. //
  1312. // Set the flush time setting
  1313. //
  1314. if(!_tcscmp(__wargv[ii], _T("-ft"))) {
  1315. if((ii + 1) < __argc) {
  1316. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1317. m_pLoggerInfo->FlushTimer = _ttoi(__wargv[ii + 1]);
  1318. ii++;
  1319. }
  1320. }
  1321. }
  1322. //
  1323. // Get the control guid(s)
  1324. //
  1325. if(!_tcscmp(__wargv[ii], _T("-guid"))) {
  1326. if((ii + 1) < __argc) {
  1327. if(__wargv[ii + 1][0] == _T('#')) {
  1328. m_guidArray.Add(__wargv[ii + 1][1]);
  1329. guidCount++;
  1330. } else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1331. _tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  1332. // _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
  1333. guidCount += GetGuids(guidFile);
  1334. if (guidCount < 0) {
  1335. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  1336. } else if (guidCount == 0){
  1337. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  1338. status = ERROR_INVALID_PARAMETER;
  1339. return status;
  1340. }
  1341. }
  1342. ii++;
  1343. }
  1344. }
  1345. //
  1346. // Get the control guid(s) from a PDB file
  1347. //
  1348. if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
  1349. if(((ii + 1) < __argc) &&
  1350. ((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
  1351. _tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  1352. pdbFile = (LPCTSTR)pdbFile;
  1353. ParsePdb(pdbFile, m_traceDirectory, TRUE);
  1354. _tprintf(_T("\n\n"));
  1355. tmcPath = (LPCTSTR)m_traceDirectory;
  1356. tmcPath +=_T("\\*.tmc");
  1357. if(!fileFind.FindFile(tmcPath)) {
  1358. _tprintf(_T("Failed To Get Control GUID From PDB"));
  1359. return ERROR_INVALID_PARAMETER;
  1360. }
  1361. while(fileFind.FindNextFile()) {
  1362. tmcPath = fileFind.GetFileName();
  1363. _tsplitpath(tmcPath, drive, path, file, ext );
  1364. m_guidArray.Add(file);
  1365. guidCount++;
  1366. }
  1367. tmcPath = fileFind.GetFileName();
  1368. _tsplitpath(tmcPath, drive, path, file, ext );
  1369. m_guidArray.Add(file);
  1370. guidCount++;
  1371. if (guidCount < 0) {
  1372. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  1373. } else if (guidCount == 0){
  1374. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  1375. status = ERROR_INVALID_PARAMETER;
  1376. return status;
  1377. }
  1378. ii++;
  1379. }
  1380. }
  1381. //
  1382. // Check for real-time setting
  1383. //
  1384. if(!_tcscmp(__wargv[ii], _T("-rt"))) {
  1385. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
  1386. //
  1387. // Did the user specify buffering only?
  1388. //
  1389. if ((ii + 1) < __argc) {
  1390. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1391. if (__wargv[ii + 1][0] == 'b')
  1392. m_pLoggerInfo->LogFileMode |= EVENT_TRACE_BUFFERING_MODE;
  1393. ii++;
  1394. }
  1395. }
  1396. }
  1397. //
  1398. // Set the flags
  1399. //
  1400. if((!_tcscmp(__wargv[ii], _T("-flag"))) || (!_tcscmp(__wargv[ii], _T("-flags")))) {
  1401. if((ii + 1) < __argc) {
  1402. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1403. //
  1404. // Get the flags specified, convert from hex if necessary
  1405. //
  1406. if(__wargv[ii + 1][1] == _T('x') || __wargv[ii + 1][1] == _T('X')) {
  1407. m_pLoggerInfo->EnableFlags |= ahextoi(__wargv[ii + 1]);
  1408. } else {
  1409. m_pLoggerInfo->EnableFlags |= _ttoi(__wargv[ii + 1]);
  1410. }
  1411. //
  1412. // Copy flags for EnableTrace
  1413. //
  1414. enableFlags = m_pLoggerInfo->EnableFlags;
  1415. //
  1416. // Do not accept flags with MSB = 1.
  1417. //
  1418. if (0x80000000 & m_pLoggerInfo->EnableFlags) {
  1419. _tprintf(_T("Invalid Flags: 0x%0X(%d.)\n"),
  1420. m_pLoggerInfo->EnableFlags, m_pLoggerInfo->EnableFlags);
  1421. status = ERROR_INVALID_PARAMETER;
  1422. return status;
  1423. }
  1424. ii++;
  1425. }
  1426. }
  1427. }
  1428. //
  1429. // Set the eflags
  1430. //
  1431. if(!_tcscmp(__wargv[ii], _T("-eflag"))) {
  1432. if((ii + 2) < __argc) {
  1433. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1434. numberOfFlags = (USHORT)_ttoi(__wargv[ii + 1]);
  1435. ii++;
  1436. if((numberOfFlags > MAX_ENABLE_FLAGS) || (numberOfFlags < 1)) {
  1437. _tprintf(_T("Error: Invalid number of enable flags\n"));
  1438. status = ERROR_INVALID_PARAMETER;
  1439. return status;
  1440. }
  1441. offset = (USHORT) sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAX_STR_LENGTH * sizeof(TCHAR);
  1442. m_pLoggerInfo->EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
  1443. flagExt = (PTRACE_ENABLE_FLAG_EXTENSION)
  1444. &m_pLoggerInfo->EnableFlags;
  1445. flagExt->Offset = offset;
  1446. flagExt->Length = (UCHAR)numberOfFlags;
  1447. pFlags = (PULONG)(offset + (PCHAR) m_pLoggerInfo);
  1448. for (i = 0; ((i < numberOfFlags) && ((ii + 1) < __argc)); i++) {
  1449. if ((__wargv[ii + 1][0] == '-') || (__wargv[ii + 1][0] == '/')) {
  1450. //
  1451. // Correct the number of eflags when the user
  1452. // types an incorrect number.
  1453. // However, this does not work if the next
  1454. // argument is Logger Name.
  1455. //
  1456. break;
  1457. }
  1458. pFlags[i] = ahextoi(__wargv[ii + 1]);
  1459. ii++;
  1460. // _tprintf(_T("Setting logger flags to 0x%0X(%d.)\n"),
  1461. // pFlags[i], pFlags[i] );
  1462. }
  1463. numberOfFlags = (USHORT)i;
  1464. for ( ; i < MAX_ENABLE_FLAGS; i++) {
  1465. pFlags[i] = 0;
  1466. }
  1467. if (flagExt->Length != (UCHAR)numberOfFlags) {
  1468. // _tprintf(_T("Correcting the number of eflags to %d\n"), i),
  1469. flagExt->Length = (UCHAR)numberOfFlags;
  1470. }
  1471. }
  1472. }
  1473. }
  1474. }
  1475. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  1476. if (guidCount != 1) {
  1477. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  1478. status = ERROR_INVALID_PARAMETER;
  1479. return status;
  1480. }
  1481. StringToGuid(m_guidArray[0].GetBuffer(0), &guid);
  1482. m_pLoggerInfo->Wnode.Guid = guid;
  1483. }
  1484. /*
  1485. if (specialLogger == 3) {
  1486. status = GetGlobalLoggerSettings(m_pLoggerInfo, &m_pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
  1487. }
  1488. */
  1489. status = ControlTrace(loggerHandle, loggerName, m_pLoggerInfo, EVENT_TRACE_CONTROL_UPDATE);
  1490. PrintLoggerStatus(status);
  1491. return status;
  1492. }
  1493. LONG CTraceViewApp::EnumerateRegisteredGuids()
  1494. {
  1495. ULONG propertyArrayCount = 10;
  1496. PTRACE_GUID_PROPERTIES *guidPropertiesArray;
  1497. ULONG enumGuidCount;
  1498. ULONG sizeStorage;
  1499. PVOID storageNeeded;
  1500. PTRACE_GUID_PROPERTIES cleanStorage;
  1501. CString str;
  1502. LONG status;
  1503. ULONG i;
  1504. Retry:
  1505. sizeStorage = propertyArrayCount * (sizeof(TRACE_GUID_PROPERTIES) + sizeof(PTRACE_GUID_PROPERTIES));
  1506. storageNeeded = malloc(sizeStorage);
  1507. if(storageNeeded == NULL) {
  1508. status = ERROR_OUTOFMEMORY;
  1509. return status;
  1510. }
  1511. RtlZeroMemory(storageNeeded, sizeStorage);
  1512. guidPropertiesArray = (PTRACE_GUID_PROPERTIES *)storageNeeded;
  1513. cleanStorage = (PTRACE_GUID_PROPERTIES)((char*)storageNeeded + propertyArrayCount * sizeof(PTRACE_GUID_PROPERTIES));
  1514. for(i = 0; i < propertyArrayCount; i++) {
  1515. guidPropertiesArray[i] = cleanStorage;
  1516. cleanStorage = (PTRACE_GUID_PROPERTIES) (
  1517. (char*)cleanStorage + sizeof(TRACE_GUID_PROPERTIES)
  1518. );
  1519. }
  1520. //
  1521. // V1.0 Note: We are deliberately "breaking" things here, so that
  1522. // TraceView will NOT be able to load in Windows 2000. This is because
  1523. // very last minute testing indicated that TraceView did not work
  1524. // properly on Win2K. This will take some investigating, so the
  1525. // work to support Win2K is deferred to a later release.
  1526. // (see companion "V1.0 NOTE" in the code below)
  1527. //
  1528. status = EnumerateTraceGuids(guidPropertiesArray,
  1529. propertyArrayCount,
  1530. &enumGuidCount);
  1531. //
  1532. // See V1.0 NOTE, above
  1533. //
  1534. // if(EnumerateTraceGuidsFunction) {
  1535. //
  1536. // status = (EnumerateTraceGuidsFunction)(guidPropertiesArray,
  1537. // propertyArrayCount,
  1538. // &enumGuidCount);
  1539. if(status == ERROR_MORE_DATA)
  1540. {
  1541. propertyArrayCount = enumGuidCount;
  1542. free(storageNeeded);
  1543. goto Retry;
  1544. }
  1545. //
  1546. // (see V1.0 NOTE above)
  1547. //
  1548. // } else {
  1549. //
  1550. // _tprintf(_T("not supported on Win2K\n"));
  1551. // status = 1;
  1552. //
  1553. // return status;
  1554. // }
  1555. //
  1556. // print the GUID_PROPERTIES and Free Strorage
  1557. //
  1558. _tprintf(_T(" Guid Enabled LoggerId Level Flags\n"));
  1559. _tprintf(_T("----------------------------------------------------------\n"));
  1560. for (i=0; i < enumGuidCount; i++) {
  1561. GuidToString(guidPropertiesArray[i]->Guid, str);
  1562. _tprintf(_T("%s %5s %d %d %d\n"),
  1563. (LPCTSTR)str,
  1564. (guidPropertiesArray[i]->IsEnable) ? _T("TRUE") : _T("FALSE"),
  1565. guidPropertiesArray[i]->LoggerId,
  1566. guidPropertiesArray[i]->EnableLevel,
  1567. guidPropertiesArray[i]->EnableFlags);
  1568. }
  1569. free(storageNeeded);
  1570. return status;
  1571. }
  1572. LONG CTraceViewApp::EnableProvider(BOOL bEnable)
  1573. {
  1574. TRACEHANDLE loggerHandle = 0;
  1575. LPTSTR loggerName = NULL;
  1576. LPTSTR logFileName = NULL;
  1577. LONG start = 2;
  1578. LONG guidCount = 0;
  1579. CString guidFile;
  1580. GUID guid;
  1581. LONG status;
  1582. ULONG enableFlags = 0;
  1583. ULONG traceLevel = 0;
  1584. ULONG specialLogger = 0;
  1585. USHORT numberOfFlags = 0;
  1586. USHORT offset;
  1587. PTRACE_ENABLE_FLAG_EXTENSION flagExt;
  1588. PULONG pFlags = NULL;
  1589. LONG i;
  1590. CString pdbFile;
  1591. CString tmcPath;
  1592. CFileFind fileFind;
  1593. TCHAR drive[10];
  1594. TCHAR path[MAXSTR];
  1595. TCHAR file[MAXSTR];
  1596. TCHAR ext[MAXSTR];
  1597. //
  1598. // Get the logger name string
  1599. //
  1600. loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
  1601. //
  1602. // Get the logger name
  1603. //
  1604. if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
  1605. _tcscpy(loggerName, __wargv[2]);
  1606. start = 3;
  1607. }
  1608. for(LONG ii = start; ii < __argc; ii++) {
  1609. //
  1610. // Get the control guid(s)
  1611. //
  1612. if(!_tcscmp(__wargv[ii], _T("-guid"))) {
  1613. if((ii + 1) < __argc) {
  1614. if(__wargv[ii + 1][0] == _T('#')) {
  1615. m_guidArray.Add(__wargv[ii + 1][1]);
  1616. guidCount++;
  1617. } else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1618. _tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  1619. // _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
  1620. guidCount += GetGuids(guidFile);
  1621. if (guidCount < 0) {
  1622. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  1623. } else if (guidCount == 0){
  1624. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  1625. status = ERROR_INVALID_PARAMETER;
  1626. return status;
  1627. }
  1628. }
  1629. ii++;
  1630. }
  1631. }
  1632. //
  1633. // Get the control guid(s) from a PDB file
  1634. //
  1635. if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
  1636. if(((ii + 1) < __argc) &&
  1637. ((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
  1638. _tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
  1639. pdbFile = (LPCTSTR)pdbFile;
  1640. ParsePdb(pdbFile, m_traceDirectory, TRUE);
  1641. _tprintf(_T("\n\n"));
  1642. tmcPath = (LPCTSTR)m_traceDirectory;
  1643. tmcPath +=_T("\\*.tmc");
  1644. if(!fileFind.FindFile(tmcPath)) {
  1645. _tprintf(_T("Failed To Get Control GUID From PDB"));
  1646. return ERROR_INVALID_PARAMETER;
  1647. }
  1648. while(fileFind.FindNextFile()) {
  1649. tmcPath = fileFind.GetFileName();
  1650. _tsplitpath(tmcPath, drive, path, file, ext );
  1651. m_guidArray.Add(file);
  1652. guidCount++;
  1653. }
  1654. tmcPath = fileFind.GetFileName();
  1655. _tsplitpath(tmcPath, drive, path, file, ext );
  1656. m_guidArray.Add(file);
  1657. guidCount++;
  1658. if (guidCount < 0) {
  1659. _tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
  1660. } else if (guidCount == 0){
  1661. _tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
  1662. status = ERROR_INVALID_PARAMETER;
  1663. return status;
  1664. }
  1665. ii++;
  1666. }
  1667. }
  1668. //
  1669. // Set the level
  1670. //
  1671. if(!_tcscmp(__wargv[ii], _T("-level"))) {
  1672. if((ii + 1) < __argc) {
  1673. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1674. traceLevel = _ttoi(__wargv[ii + 1]);
  1675. ii++;
  1676. }
  1677. }
  1678. }
  1679. //
  1680. // Set the flags
  1681. //
  1682. if((!_tcscmp(__wargv[ii], _T("-flag"))) || (!_tcscmp(__wargv[ii], _T("-flags")))) {
  1683. if((ii + 1) < __argc) {
  1684. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1685. //
  1686. // Get the flags specified, convert from hex if necessary
  1687. //
  1688. if(__wargv[ii + 1][1] == _T('x') || __wargv[ii + 1][1] == _T('X')) {
  1689. m_pLoggerInfo->EnableFlags |= ahextoi(__wargv[ii + 1]);
  1690. } else {
  1691. m_pLoggerInfo->EnableFlags |= _ttoi(__wargv[ii + 1]);
  1692. }
  1693. //
  1694. // Copy flags for EnableTrace
  1695. //
  1696. enableFlags = m_pLoggerInfo->EnableFlags;
  1697. //
  1698. // Do not accept flags with MSB = 1.
  1699. //
  1700. if (0x80000000 & m_pLoggerInfo->EnableFlags) {
  1701. _tprintf(_T("Invalid Flags: 0x%0X(%d.)\n"),
  1702. m_pLoggerInfo->EnableFlags, m_pLoggerInfo->EnableFlags);
  1703. status = ERROR_INVALID_PARAMETER;
  1704. return status;
  1705. }
  1706. ii++;
  1707. }
  1708. }
  1709. }
  1710. //
  1711. // Set the eflags
  1712. //
  1713. if(!_tcscmp(__wargv[ii], _T("-eflag"))) {
  1714. if((ii + 2) < __argc) {
  1715. if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
  1716. numberOfFlags = (USHORT)_ttoi(__wargv[ii + 1]);
  1717. ii++;
  1718. if((numberOfFlags > MAX_ENABLE_FLAGS) || (numberOfFlags < 1)) {
  1719. _tprintf(_T("Error: Invalid number of enable flags\n"));
  1720. status = ERROR_INVALID_PARAMETER;
  1721. return status;
  1722. }
  1723. offset = (USHORT) sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAX_STR_LENGTH * sizeof(TCHAR);
  1724. m_pLoggerInfo->EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
  1725. flagExt = (PTRACE_ENABLE_FLAG_EXTENSION)
  1726. &m_pLoggerInfo->EnableFlags;
  1727. flagExt->Offset = offset;
  1728. flagExt->Length = (UCHAR)numberOfFlags;
  1729. pFlags = (PULONG)(offset + (PCHAR) m_pLoggerInfo);
  1730. for (i = 0; ((i < numberOfFlags) && ((ii + 1) < __argc)); i++) {
  1731. if ((__wargv[ii + 1][0] == '-') || (__wargv[ii + 1][0] == '/')) {
  1732. //
  1733. // Correct the number of eflags when the user
  1734. // types an incorrect number.
  1735. // However, this does not work if the next
  1736. // argument is Logger Name.
  1737. //
  1738. break;
  1739. }
  1740. pFlags[i] = ahextoi(__wargv[ii + 1]);
  1741. ii++;
  1742. // _tprintf(_T("Setting logger flags to 0x%0X(%d.)\n"),
  1743. // pFlags[i], pFlags[i] );
  1744. }
  1745. numberOfFlags = (USHORT)i;
  1746. for ( ; i < MAX_ENABLE_FLAGS; i++) {
  1747. pFlags[i] = 0;
  1748. }
  1749. if (flagExt->Length != (UCHAR)numberOfFlags) {
  1750. // _tprintf(_T("Correcting the number of eflags to %d\n"), i),
  1751. flagExt->Length = (UCHAR)numberOfFlags;
  1752. }
  1753. }
  1754. }
  1755. }
  1756. }
  1757. if(m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  1758. if(guidCount != 1) {
  1759. _tprintf(_T("Need one GUID for PRIVATE loggers\n"));
  1760. status = ERROR_INVALID_PARAMETER;
  1761. return status;
  1762. }
  1763. StringToGuid(m_guidArray[0].GetBuffer(0), &guid);
  1764. m_pLoggerInfo->Wnode.Guid = guid;
  1765. }
  1766. status = ControlTrace((TRACEHANDLE) 0, loggerName, m_pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  1767. if(status != ERROR_SUCCESS) {
  1768. /*
  1769. if( IsEqualGUID(&HeapGuid,&m_pLoggerInfo->Wnode.Guid)
  1770. || IsEqualGUID(&CritSecGuid,&m_pLoggerInfo->Wnode.Guid)
  1771. ){
  1772. //do nothing
  1773. } else {
  1774. */
  1775. _tprintf( _T("ERROR: Logger not started\n")
  1776. _T("Operation Status: %uL\n")
  1777. _T("%s\n"),
  1778. status,
  1779. DecodeStatus(status));
  1780. return status;
  1781. // }
  1782. }
  1783. loggerHandle = m_pLoggerInfo->Wnode.HistoricalContext;
  1784. if((guidCount > 0) && (specialLogger == 0)) {
  1785. _tprintf(_T("Enabling trace to logger %d\n"), loggerHandle);
  1786. for(i = 0; i < (ULONG)guidCount; i++) {
  1787. StringToGuid(m_guidArray[i].GetBuffer(0), &guid);
  1788. status = EnableTrace (
  1789. bEnable,
  1790. enableFlags,
  1791. traceLevel,
  1792. &guid,
  1793. loggerHandle);
  1794. //
  1795. // If the Guid can not be enabled, it is a benign
  1796. // failure. Print Warning message and continue.
  1797. //
  1798. if(status == 4317) {
  1799. _tprintf(_T("WARNING: Could not enable some guids.\n"));
  1800. _tprintf(_T("Check your Guids file\n"));
  1801. status = ERROR_SUCCESS;
  1802. }
  1803. if(status != ERROR_SUCCESS) {
  1804. _tprintf(_T("ERROR: Failed to enable Guid [%d]...\n"), i);
  1805. _tprintf(_T("Operation Status: %uL\n"), status);
  1806. _tprintf(_T("%s\n"),DecodeStatus(status));
  1807. return status;
  1808. }
  1809. }
  1810. } else if(guidCount > 0) {
  1811. _tprintf(_T("ERROR: System Logger does not accept application guids...\n"));
  1812. status = ERROR_INVALID_PARAMETER;
  1813. }
  1814. PrintLoggerStatus(status);
  1815. return status;
  1816. }
  1817. LONG CTraceViewApp::ConsumeTraceEvents()
  1818. {
  1819. TCHAR guidFileName[MAXSTR];
  1820. TCHAR dumpFileName[MAXSTR];
  1821. TCHAR summaryFileName[MAXSTR];
  1822. LPTSTR *commandLine;
  1823. LPTSTR *targv;
  1824. LPTSTR *cmdargv;
  1825. LONG argc;
  1826. PEVENT_TRACE_LOGFILE pLogFile;
  1827. ULONG status;
  1828. ULONG guidCount = 0;
  1829. ULONG i;
  1830. ULONG j;
  1831. TRACEHANDLE handleArray[MAXLOGFILES];
  1832. CString pdbFile;
  1833. CString formatOptions;
  1834. //
  1835. // initialize member variables
  1836. //
  1837. m_pDumpFile = NULL;
  1838. m_pSummaryFile = NULL;
  1839. m_bDebugDisplay = FALSE ;
  1840. m_bDisplayOnly = FALSE ;
  1841. m_bSummaryOnly = FALSE ;
  1842. m_bNoSummary = FALSE ;
  1843. m_bVerbose = FALSE ;
  1844. m_bFixUp = FALSE ;
  1845. m_bODSOutput = FALSE ;
  1846. m_bTMFSpecified = FALSE ;
  1847. m_bCSVMode = FALSE ;
  1848. m_bNoCSVHeader = TRUE ;
  1849. m_bCSVHeader = FALSE ;
  1850. m_totalBuffersRead = 0;
  1851. m_totalEventsLost = 0;
  1852. m_totalEventCount = 0;
  1853. m_timerResolution = 10;
  1854. m_bufferWrap = 0 ;
  1855. m_eventListHead = NULL;
  1856. m_logFileCount = 0;
  1857. m_userMode = FALSE; // TODO: Pick this up from the stream itself.
  1858. m_traceMask = NULL;
  1859. targv = __wargv;
  1860. argc = __argc;
  1861. _tcscpy(dumpFileName, _T("FmtFile.txt"));
  1862. _tcscpy(summaryFileName, _T("FmtSum.txt"));
  1863. // By default look for Define.guid in the image location
  1864. if ((status = GetModuleFileName(NULL, guidFileName, MAXSTR)) == MAXSTR) {
  1865. guidFileName[MAXSTR-1] = _T('\0');
  1866. }
  1867. if( status != 0 ){
  1868. TCHAR drive[10];
  1869. TCHAR path[MAXSTR];
  1870. TCHAR file[MAXSTR];
  1871. TCHAR ext[MAXSTR];
  1872. _tsplitpath( guidFileName, drive, path, file, ext );
  1873. _tcscpy(ext, GUID_EXT );
  1874. _tcscpy(file, GUID_FILE );
  1875. _tmakepath( guidFileName, drive, path, file, ext );
  1876. }else{
  1877. _tcscpy( guidFileName, GUID_FILE );
  1878. _tcscat( guidFileName, _T(".") );
  1879. _tcscat( guidFileName, GUID_EXT );
  1880. }
  1881. while (--argc > 0) {
  1882. ++targv;
  1883. if (**targv == '-' || **targv == '/') { // argument found
  1884. if( **targv == '/' ){
  1885. **targv = '-';
  1886. }
  1887. else if (!_tcsicmp(targv[0], _T("-debug"))) {
  1888. m_bDebugDisplay = TRUE;
  1889. }
  1890. else if (!_tcsicmp(targv[0], _T("-display"))) {
  1891. m_bDebugDisplay = TRUE ;
  1892. }
  1893. else if (!_tcsicmp(targv[0], _T("-displayonly"))) {
  1894. m_bDisplayOnly = TRUE ;
  1895. }
  1896. else if (!_tcsicmp(targv[0], _T("-fixup"))) {
  1897. m_bFixUp = TRUE;
  1898. }
  1899. else if (!_tcsicmp(targv[0], _T("-summary"))) {
  1900. m_bSummaryOnly = TRUE;
  1901. }
  1902. else if (!_tcsicmp(targv[0], _T("-seq"))) {
  1903. SetTraceFormatParameter(ParameterSEQUENCE, ULongToPtr(1));
  1904. }
  1905. else if (!_tcsicmp(targv[0], _T("-gmt"))) {
  1906. SetTraceFormatParameter(ParameterGMT, ULongToPtr(1));
  1907. }
  1908. else if (!_tcsicmp(targv[0], _T("-utc"))) {
  1909. SetTraceFormatParameter(ParameterGMT, ULongToPtr(1));
  1910. } else if (!_tcsicmp(targv[0], _T("-nosummary"))) {
  1911. m_bNoSummary = TRUE;
  1912. } else if (!_tcsicmp(targv[0], _T("-csv"))) {
  1913. m_bCSVMode = TRUE ;
  1914. m_bCSVHeader = TRUE ;
  1915. SetTraceFormatParameter(ParameterStructuredFormat,UlongToPtr(1));
  1916. } else if (!_tcsicmp(targv[0], _T("-nocsvheader"))) {
  1917. m_bNoCSVHeader = FALSE ;
  1918. }
  1919. else if (!_tcsicmp(targv[0], _T("-noprefix"))) {
  1920. SetTraceFormatParameter(ParameterUsePrefix,UlongToPtr(0));
  1921. }
  1922. else if (!_tcsicmp(targv[0], _T("-rt"))) {
  1923. TCHAR LoggerName[MAXSTR];
  1924. _tcscpy(LoggerName, KERNEL_LOGGER_NAME);
  1925. if (argc > 1) {
  1926. if (targv[1][0] != '-' && targv[1][0] != '/') {
  1927. ++targv;
  1928. --argc;
  1929. _tcscpy(LoggerName, targv[0]);
  1930. }
  1931. }
  1932. pLogFile = (PEVENT_TRACE_LOGFILE)malloc(sizeof(EVENT_TRACE_LOGFILE));
  1933. if (pLogFile == NULL){
  1934. _tprintf(_T("Allocation Failure\n"));
  1935. goto cleanup;
  1936. }
  1937. RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
  1938. m_evmFile[m_logFileCount] = pLogFile;
  1939. m_evmFile[m_logFileCount]->LogFileName = NULL;
  1940. m_evmFile[m_logFileCount]->LoggerName =
  1941. (LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
  1942. if ( m_evmFile[m_logFileCount]->LoggerName == NULL ) {
  1943. _tprintf(_T("Allocation Failure\n"));
  1944. goto cleanup;
  1945. }
  1946. _tcscpy(m_evmFile[m_logFileCount]->LoggerName, LoggerName);
  1947. _tprintf(_T("Setting RealTime mode for %s\n"),
  1948. m_evmFile[m_logFileCount]->LoggerName);
  1949. m_evmFile[m_logFileCount]->Context = NULL;
  1950. m_evmFile[m_logFileCount]->BufferCallback = (PEVENT_TRACE_BUFFER_CALLBACKW)BufferCallback;
  1951. m_evmFile[m_logFileCount]->BuffersRead = 0;
  1952. m_evmFile[m_logFileCount]->CurrentTime = 0;
  1953. m_evmFile[m_logFileCount]->EventCallback = (PEVENT_CALLBACK)&DumpEvent;
  1954. m_evmFile[m_logFileCount]->LogFileMode =
  1955. EVENT_TRACE_REAL_TIME_MODE;
  1956. m_logFileCount++;
  1957. }
  1958. else if ( !_tcsicmp(targv[0], _T("-guid")) ) { // maintain for compatabillity
  1959. if (argc > 1) {
  1960. if (targv[1][0] != '-' && targv[1][0] != '/') {
  1961. _tcscpy(guidFileName, targv[1]);
  1962. ++targv; --argc;
  1963. m_bTMFSpecified = TRUE ;
  1964. }
  1965. }
  1966. }
  1967. else if ( !_tcsicmp(targv[0], _T("-tmf")) ) {
  1968. if (argc > 1) {
  1969. if (targv[1][0] != '-' && targv[1][0] != '/') {
  1970. _tcscpy(guidFileName, targv[1]);
  1971. ++targv; --argc;
  1972. m_bTMFSpecified = TRUE ;
  1973. }
  1974. }
  1975. }
  1976. else if ( !_tcsicmp(targv[0], _T("-pdb")) ) {
  1977. if (argc > 1) {
  1978. if (targv[1][0] != '-' && targv[1][0] != '/') {
  1979. _tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), targv[1], MAX_STR_LENGTH);
  1980. pdbFile = (LPCTSTR)pdbFile;
  1981. if(ParsePdb(pdbFile, m_traceDirectory, TRUE)) {
  1982. SetTraceFormatParameter(ParameterTraceFormatSearchPath,
  1983. m_traceDirectory.GetBuffer(0));
  1984. }
  1985. ++targv;
  1986. --argc;
  1987. }
  1988. }
  1989. }
  1990. else if ( !_tcsicmp(targv[0], _T("-p")) ){
  1991. if (argc > 1) {
  1992. if (targv[1][0] != '-' && targv[1][0] != '/') {
  1993. SetTraceFormatParameter(ParameterTraceFormatSearchPath, targv[1]);
  1994. ++targv; --argc;
  1995. }
  1996. }
  1997. }
  1998. else if ( !_tcsicmp(targv[0], _T("-format")) ) {
  1999. if (argc > 1) {
  2000. if (targv[1][0] != '-' && targv[1][0] != '/') {
  2001. for(LONG ii = 0; ii < _tcslen(targv[1]); ii++) {
  2002. switch(targv[1][ii]) {
  2003. case 'n':
  2004. formatOptions += _T("%1!s! ");
  2005. break;
  2006. case 'w':
  2007. formatOptions += _T("%2!s! ");
  2008. break;
  2009. case 't':
  2010. formatOptions += _T("%3!04X! ");
  2011. break;
  2012. case 's':
  2013. formatOptions += _T("%4!s! ");
  2014. break;
  2015. case 'k':
  2016. formatOptions += _T("%5!s! ");
  2017. break;
  2018. case 'u':
  2019. formatOptions += _T("%6!s! ");
  2020. break;
  2021. case 'q':
  2022. formatOptions += _T("%7!d! ");
  2023. break;
  2024. case 'p':
  2025. formatOptions += _T("%8!04X! ");
  2026. break;
  2027. case 'c':
  2028. formatOptions += _T("%9!d! ");
  2029. break;
  2030. case 'f':
  2031. formatOptions += _T("%!FUNC! ");
  2032. break;
  2033. default:
  2034. break;
  2035. }
  2036. }
  2037. SetEnvironmentVariable(_T("TRACE_FORMAT_PREFIX"),
  2038. formatOptions);
  2039. ++targv; --argc;
  2040. }
  2041. }
  2042. }
  2043. else if ( !_tcsicmp(targv[0], _T("-v")) ) {
  2044. m_bVerbose = TRUE ;
  2045. }
  2046. else if ( !_tcsicmp(targv[0], _T("-ods")) ) {
  2047. m_bODSOutput = TRUE ;
  2048. }
  2049. else if ( !_tcsicmp(targv[0], _T("-onlyshow")) ) {
  2050. if (argc > 1) {
  2051. m_traceMask = (TCHAR *)malloc((_tcslen(targv[1])+1) * sizeof(TCHAR));
  2052. _tcscpy(m_traceMask, targv[1]);
  2053. ++targv; --argc;
  2054. }
  2055. }
  2056. else if ( !_tcsicmp(targv[0], _T("-o")) ) {
  2057. if (argc > 1) {
  2058. if (targv[1][0] != '-' && targv[1][0] != '/') {
  2059. TCHAR drive[10];
  2060. TCHAR path[MAXSTR];
  2061. TCHAR file[MAXSTR];
  2062. TCHAR ext[MAXSTR];
  2063. ++targv; --argc;
  2064. _tfullpath(dumpFileName, targv[0], MAXSTR);
  2065. _tsplitpath( dumpFileName, drive, path, file, ext );
  2066. _tcscat(ext,_T(".sum"));
  2067. _tmakepath( summaryFileName, drive, path, file, ext );
  2068. }
  2069. }
  2070. }
  2071. }
  2072. else {
  2073. pLogFile = (PEVENT_TRACE_LOGFILE)malloc(sizeof(EVENT_TRACE_LOGFILE));
  2074. if (pLogFile == NULL){
  2075. _tprintf(_T("Allocation Failure(EVENT_TRACE_LOGFILE)\n")); // Need to cleanup better.
  2076. goto cleanup;
  2077. }
  2078. RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
  2079. m_evmFile[m_logFileCount] = pLogFile;
  2080. m_evmFile[m_logFileCount]->LoggerName = NULL;
  2081. m_evmFile[m_logFileCount]->LogFileName =
  2082. (LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
  2083. if (m_evmFile[m_logFileCount]->LogFileName == NULL) {
  2084. _tprintf(_T("Allocation Failure (LogFileName)\n"));
  2085. goto cleanup;
  2086. }
  2087. _tfullpath(m_evmFile[m_logFileCount]->LogFileName, targv[0], MAXSTR);
  2088. _tprintf(_T("Setting log file to: %s\n"),
  2089. m_evmFile[m_logFileCount]->LogFileName);
  2090. if (!CheckFile(m_evmFile[m_logFileCount]->LogFileName)) {
  2091. _tprintf(_T("Cannot open logfile for reading\n"));
  2092. goto cleanup;
  2093. }
  2094. m_evmFile[m_logFileCount]->Context = NULL;
  2095. m_evmFile[m_logFileCount]->BufferCallback = (PEVENT_TRACE_BUFFER_CALLBACKW)BufferCallback;
  2096. m_evmFile[m_logFileCount]->BuffersRead = 0;
  2097. m_evmFile[m_logFileCount]->CurrentTime = 0;
  2098. m_evmFile[m_logFileCount]->EventCallback = (PEVENT_CALLBACK)&DumpEvent;
  2099. m_logFileCount++;
  2100. }
  2101. }
  2102. if( _tcslen( guidFileName ) ){
  2103. TCHAR str[MAXSTR];
  2104. _tfullpath( str, guidFileName, MAXSTR);
  2105. _tcscpy( guidFileName, str );
  2106. _tprintf(_T("Getting guids from %s\n"), guidFileName);
  2107. guidCount = GetTraceGuids(guidFileName, (PLIST_ENTRY *) &m_eventListHead);
  2108. if ((guidCount <= 0) && m_bTMFSpecified)
  2109. {
  2110. _tprintf(_T("GetTraceGuids returned %d, GetLastError=%d, for %s\n"),
  2111. guidCount,
  2112. GetLastError(),
  2113. guidFileName);
  2114. }
  2115. }
  2116. if (m_logFileCount <= 0) {
  2117. pLogFile = (PEVENT_TRACE_LOGFILE)malloc(sizeof(EVENT_TRACE_LOGFILE));
  2118. if (pLogFile == NULL){
  2119. _tprintf(_T("Allocation Failure\n")); // Need to cleanup better.
  2120. goto cleanup;
  2121. }
  2122. RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
  2123. m_evmFile[0] = pLogFile;
  2124. m_evmFile[0]->LoggerName = NULL;
  2125. m_logFileCount = 1;
  2126. m_evmFile[0]->LogFileName = (LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
  2127. if (m_evmFile[0]->LogFileName == NULL) {
  2128. _tprintf(_T("Allocation Failure\n"));
  2129. goto cleanup;
  2130. }
  2131. _tcscpy(m_evmFile[0]->LogFileName, _T("C:\\Logfile.Etl"));
  2132. m_evmFile[0]->EventCallback = (PEVENT_CALLBACK)&DumpEvent;
  2133. }
  2134. for (i = 0; i < m_logFileCount; i++) {
  2135. TRACEHANDLE x;
  2136. x = OpenTrace(m_evmFile[i]);
  2137. handleArray[i] = x;
  2138. if (handleArray[i] == 0) {
  2139. _tprintf(_T("Error Opening Trace %d with status=%d\n"),
  2140. i, GetLastError());
  2141. for (j = 0; j < i; j++)
  2142. CloseTrace(handleArray[j]);
  2143. goto cleanup;
  2144. }
  2145. }
  2146. if (!m_bDisplayOnly) {
  2147. m_pDumpFile = _tfopen(dumpFileName, _T("w"));
  2148. if (m_pDumpFile == NULL) {
  2149. _tprintf(_T("Format File \"%s\" Could not be opened for writing 0X%X\n"),
  2150. dumpFileName,GetLastError());
  2151. goto cleanup;
  2152. }
  2153. m_pSummaryFile = NULL ;
  2154. if (!m_bNoSummary) {
  2155. m_pSummaryFile = _tfopen(summaryFileName, _T("w"));
  2156. if (m_pSummaryFile == NULL) {
  2157. _tprintf(_T("Summary File \"%s\" could not be opened for writing 0X%X\n"),
  2158. summaryFileName,GetLastError());
  2159. goto cleanup;
  2160. }
  2161. }
  2162. } else {
  2163. m_pDumpFile = stdout;
  2164. m_pSummaryFile = stdout;
  2165. }
  2166. status = ProcessTrace(handleArray,
  2167. m_logFileCount,
  2168. NULL, NULL);
  2169. if (status != ERROR_SUCCESS) {
  2170. _tprintf(_T("Error processing trace entry with status=0x%x (GetLastError=0x%x)\n"),
  2171. status, GetLastError());
  2172. }
  2173. for (j = 0; j < m_logFileCount; j++){
  2174. status = CloseTrace(handleArray[j]);
  2175. if (status != ERROR_SUCCESS) {
  2176. _tprintf(_T("Error Closing Trace %d with status=%d\n"), j, status);
  2177. }
  2178. }
  2179. if (!m_bNoSummary) {
  2180. _ftprintf(m_pSummaryFile,_T("Files Processed:\n"));
  2181. for (i=0; i<m_logFileCount; i++) {
  2182. _ftprintf(m_pSummaryFile,_T("\t%s\n"),m_evmFile[i]->LogFileName);
  2183. }
  2184. GetTraceElapseTime(&m_elapseTime);
  2185. _ftprintf(m_pSummaryFile,
  2186. _T("Total Buffers Processed %d\n")
  2187. _T("Total Events Processed %d\n")
  2188. _T("Total Events Lost %d\n")
  2189. _T("Elapsed Time %I64d sec\n"),
  2190. m_totalBuffersRead,
  2191. m_totalEventCount,
  2192. m_totalEventsLost,
  2193. (m_elapseTime / 10000000) );
  2194. _ftprintf(m_pSummaryFile,
  2195. _T("+-----------------------------------------------------------------------------------+\n")
  2196. _T("|%10s %-20s %-10s %-36s|\n")
  2197. _T("+-----------------------------------------------------------------------------------+\n"),
  2198. _T("EventCount"),
  2199. _T("EventName"),
  2200. _T("EventType"),
  2201. _T("Guid")
  2202. );
  2203. SummaryTraceEventList(m_summaryBlock, SIZESUMMARYBLOCK, m_eventListHead);
  2204. _ftprintf(m_pSummaryFile,
  2205. _T("%s+-----------------------------------------------------------------------------------+\n"),
  2206. m_summaryBlock);
  2207. }
  2208. cleanup:
  2209. CleanupTraceEventList(m_eventListHead);
  2210. if (m_bVerbose) {
  2211. _tprintf(_T("\n")); // need a newline after the block updates
  2212. }
  2213. if (m_pDumpFile != NULL) {
  2214. _tprintf(_T("Event traces dumped to %s\n"), dumpFileName);
  2215. fclose(m_pDumpFile);
  2216. }
  2217. if(m_pSummaryFile != NULL){
  2218. _tprintf(_T("Event Summary dumped to %s\n"), summaryFileName);
  2219. fclose(m_pSummaryFile);
  2220. }
  2221. for (i = 0; i < m_logFileCount; i ++)
  2222. {
  2223. if (m_evmFile[i]->LoggerName != NULL)
  2224. {
  2225. free(m_evmFile[i]->LoggerName);
  2226. m_evmFile[i]->LoggerName = NULL;
  2227. }
  2228. if (m_evmFile[i]->LogFileName != NULL)
  2229. {
  2230. free(m_evmFile[i]->LogFileName);
  2231. m_evmFile[i]->LogFileName = NULL;
  2232. }
  2233. free(m_evmFile[i]);
  2234. }
  2235. status = GetLastError();
  2236. if(status != ERROR_SUCCESS ){
  2237. _tprintf(_T("Exit Status: %d\n"), status );
  2238. }
  2239. return 0;
  2240. }
  2241. LONG CTraceViewApp::ExtractPdbInfo()
  2242. {
  2243. DWORD status;
  2244. CString path;
  2245. CString pdbName;
  2246. CHAR pdbNameStr[500];
  2247. CHAR pathStr[500];
  2248. INT len;
  2249. INT targv = 0;
  2250. BOOL bPDBName = FALSE ;
  2251. LPTSTR dllToLoad = NULL;
  2252. /*
  2253. TCHAR helptext[] = "Usage: TracePDB -f <pdbname> [-p <path>] [-v]\n"
  2254. " Options:\n"
  2255. // " -r recurse into subdirectories\n"
  2256. " -f specifies the PDBName from which to extract tmf's\n"
  2257. " -p specifies the path to create the tmf's,\n"
  2258. " by default the current directory.\n"
  2259. " -v verbose, displays actions taken \n" ;
  2260. */
  2261. if (GetCurrentDirectory(MAX_PATH, path.GetBuffer(MAX_PATH)) == 0 ) {
  2262. _fputts(_T("TracePDB: no current directory\n"), stdout);
  2263. return ERROR_PATH_NOT_FOUND;
  2264. }
  2265. path = (LPCTSTR)path;
  2266. //
  2267. // Get the PDB file name
  2268. //
  2269. if((__argc > 2) &&
  2270. ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
  2271. if((_tcslen(__wargv[2]) + 1) > MAX_PATH) {
  2272. _fputts(_T("TracePDB: PDBname too large\n"), stdout);
  2273. return ERROR_INVALID_PARAMETER;
  2274. }
  2275. pdbName.GetBuffer(_tcslen(__wargv[2]) + 1);
  2276. pdbName = __wargv[2];
  2277. bPDBName = TRUE ;
  2278. }
  2279. for(LONG ii = 3; ii < __argc; ii++) {
  2280. if((__argc > 3) && ((__wargv[ii][0] == '-') || (__wargv[ii][0] == '/'))) {
  2281. if(__wargv[ii][1] == 'p') {
  2282. if(((ii + 1) < __argc) &&
  2283. ((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
  2284. if((_tcslen(__wargv[ii + 1]) + 1) > MAX_PATH) {
  2285. fputs("TracePDB: Path larger than MAX_PATH\n", stdout);
  2286. return ERROR_INVALID_PARAMETER;
  2287. }
  2288. _tcsncpy(path.GetBuffer(_tcslen(__wargv[ii + 1]) + 1),
  2289. __wargv[ii + 1],
  2290. _tcslen(__wargv[ii + 1]) + 1);
  2291. ii++;
  2292. }
  2293. } else {
  2294. return ERROR_INVALID_PARAMETER;
  2295. }
  2296. }
  2297. }
  2298. if (!bPDBName) {
  2299. _tprintf(_T("TracePDB: No PDB specified?\n\n"));
  2300. return ERROR_INVALID_PARAMETER;
  2301. }
  2302. if((dllToLoad = (LPTSTR) malloc(MAX_PATH + 1)) == NULL) {
  2303. _fputts(_T("TracePDB: malloc failed\n"), stdout);
  2304. return ERROR_OUTOFMEMORY;
  2305. }
  2306. _tcscpy(dllToLoad, _T("mspdb70.dll"));
  2307. if(!ParsePdb(pdbName, path, TRUE)) {
  2308. status = ERROR_INVALID_PARAMETER;
  2309. _tprintf(_T("TracePDB: failed with error %d\n"), status);
  2310. }
  2311. return status;
  2312. }
  2313. void CTraceViewApp::DisplayHelp()
  2314. {
  2315. _fputts(
  2316. _T("\n")
  2317. _T("\n")
  2318. _T("\n")
  2319. _T("Control:\n")
  2320. _T("Usage: traceview [action] [options] | [-h | -help | -?]\n")
  2321. _T("\n")
  2322. _T("Control Actions:\n")
  2323. _T("\t-start [LoggerName] Starts up the [LoggerName] trace session\n")
  2324. _T("\t-stop [LoggerName] Stops the [LoggerName] trace session\n")
  2325. _T("\t-update [LoggerName] Updates the [LoggerName] trace session\n")
  2326. _T("\t-enable [LoggerName] Enables providers for the [LoggerName] session\n")
  2327. _T("\t-disable [LoggerName] Disables providers for the [LoggerName] session\n")
  2328. _T("\t-flush [LoggerName] Flushes the [LoggerName] active buffers\n")
  2329. _T("\t-enumguid Enumerate Registered Trace Guids\n")
  2330. _T("\t-q [LoggerName] Query status of [LoggerName] trace session\n")
  2331. _T("\t-l List all trace sessions\n")
  2332. _T("\t-x Stops all active trace sessions\n")
  2333. _T("\n")
  2334. _T("Control Options:\n")
  2335. _T("\t-b <n> Sets buffer size to <n> Kbytes\n")
  2336. _T("\t-min <n> Sets minimum buffers\n")
  2337. _T("\t-max <n> Sets maximum buffers\n")
  2338. _T("\t-f <name> Log to file <name>\n")
  2339. _T("\t-append Append to file\n")
  2340. _T("\t-prealloc Pre-allocate\n")
  2341. _T("\t-seq <n> Sequential logfile of up to n Mbytes\n")
  2342. _T("\t-cir <n> Circular logfile of n Mbytes\n")
  2343. _T("\t-newfile <n> Log to a new file after every n Mbytes\n")
  2344. _T("\t-ft <n> Set flush timer to n seconds\n")
  2345. _T("\t-paged Use pageable memory for buffers\n")
  2346. _T("\t-guid <file> Start tracing for providers in file\n")
  2347. _T("\t-pdb <file> Start tracing for provider related to PDB file\n")
  2348. _T("\t-rt Enable tracing in real time mode\n")
  2349. _T("\t-kd Enable tracing in kernel debugger\n")
  2350. _T("\t-age <n> Modify aging decay time to n minutes\n")
  2351. _T("\t-level <n> Enable Level passed to the providers\n")
  2352. _T("\t-flag <n> Enable Flags passed to the providers\n")
  2353. _T("\t-eflag <n> <flag...> Enable flags (several) to providers\n")
  2354. _T("\n")
  2355. _T("\n")
  2356. _T("Consumption:\n")
  2357. _T("Usage: traceview [action] [options] <evmfile> | [-h | -help | -?]\n")
  2358. _T("\n")
  2359. _T("Consumption Actions:\n")
  2360. _T("\t-process Setup trace event processing for consumer\n")
  2361. _T("\n")
  2362. _T("Consumption Options:\n")
  2363. _T("\t-o <file> Output file\n")
  2364. _T("\t-csv Format the output as a comma seperated file\n")
  2365. _T("\t-tmf <file> Format definition file\n")
  2366. _T("\t-pdb <file> Retrieve format information from PDB file\n")
  2367. _T("\t-p <path> TMF file search path\n")
  2368. _T("\t-rt [loggername] Realtime formatting\n")
  2369. _T("\t-h Display this information\n")
  2370. _T("\t-display Display output\n")
  2371. _T("\t-displayonly Display output. Don't write to the file\n")
  2372. _T("\t-nosummary Don't create the summary file\n")
  2373. _T("\t-noprefix Suppress any defined TRACE_FORMAT_PREFIX")
  2374. _T("\t-ods do Display output using OutputDebugString\n")
  2375. _T("\t-summaryonly Don't create the listing file.\n")
  2376. _T("\t-v Verbose Display\n")
  2377. _T("\n")
  2378. _T("\tDefault evmfile is ") _T("C:\\Logfile.Etl") _T("\n")
  2379. _T("\tDefault outputfile is ") _T("FmtFile.txt") _T("\n")
  2380. _T("\tDefault TMF file is ") GUID_FILE _T(".") GUID_EXT _T("\n")
  2381. _T("\n")
  2382. _T("\n")
  2383. _T("Parsing:\n")
  2384. _T("Usage: traceview [action] <pdbname> [-p <path>] | [-h | -help | -?]\n")
  2385. _T("\n")
  2386. _T("Parsing Actions:\n")
  2387. _T("\t-parsepdb <pdbname> Extract TMF(s) from <pdbname>\n")
  2388. _T("\n")
  2389. _T("Parsing Options:\n")
  2390. _T("\t-p specifies the path to create the tmf's,\n")
  2391. _T("\t by default the current directory.\n")
  2392. _T("\n")
  2393. _T("\n")
  2394. _T("\n")
  2395. _T("Examples:\n")
  2396. _T("\n")
  2397. _T("Start a log session named foo with the following properties:\n")
  2398. _T(" - real-time\n")
  2399. _T(" - flags set to 0x7\n")
  2400. _T(" - flush time equal to 1\n")
  2401. _T(" - control GUID information stored in foo.pdb\n")
  2402. _T("\n")
  2403. _T("traceview -start foo -rt - flag 0x7 -ft 1 -pdb foo.pdb\n")
  2404. _T("\n")
  2405. _T("\n")
  2406. _T("Consume trace events from a logger named bar with the\n")
  2407. _T(" following options:\n")
  2408. _T(" - process events in real-time from real-time logger bar\n")
  2409. _T(" - display to screen only, no listing file generated\n")
  2410. _T(" - display process ID, CPU number, and function name\n")
  2411. _T(" ahead of event message \n")
  2412. _T(" - extract event format information from bar.pdb\n")
  2413. _T("\n")
  2414. _T("traceview -process -pdb bar.pdb -displayonly -rt bar -format pcf\n")
  2415. _T("\n")
  2416. _T("\n")
  2417. _T("Extract the TMF files from a PDB file and place them in \n")
  2418. _T(" a directory named c:\\foobar\n")
  2419. _T("\n")
  2420. _T("traceview -parsepdb bar.pdb -p c:\\foobar\n"),
  2421. stdout
  2422. );
  2423. }
  2424. // CTraceViewApp message handlers
  2425. // CAboutDlg dialog used for App About
  2426. class CAboutDlg : public CDialog
  2427. {
  2428. public:
  2429. CAboutDlg();
  2430. // Dialog Data
  2431. enum { IDD = IDD_ABOUTBOX };
  2432. protected:
  2433. virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  2434. // Implementation
  2435. protected:
  2436. DECLARE_MESSAGE_MAP()
  2437. public:
  2438. };
  2439. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  2440. {
  2441. }
  2442. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  2443. {
  2444. CDialog::DoDataExchange(pDX);
  2445. }
  2446. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  2447. END_MESSAGE_MAP()
  2448. // App command to run the dialog
  2449. void CTraceViewApp::OnAppAbout()
  2450. {
  2451. CAboutDlg aboutDlg;
  2452. aboutDlg.DoModal();
  2453. }
  2454. // CTraceViewApp message handlers
  2455. CTraceMessage * CTraceViewApp::AllocateTraceEventBlock()
  2456. {
  2457. CTraceMessage *pTraceMessage = NULL;
  2458. //
  2459. // Get the array protection
  2460. //
  2461. WaitForSingleObject(m_hTraceBlockMutex, INFINITE);
  2462. if(m_traceBlockArray.GetSize()) {
  2463. ASSERT(FALSE);
  2464. pTraceMessage = m_traceBlockArray.GetAt(0);
  2465. m_traceBlockArray.RemoveAt(0);
  2466. } else {
  2467. pTraceMessage = new CTraceMessage();
  2468. }
  2469. //
  2470. // Release the array protection
  2471. //
  2472. ReleaseMutex(m_hTraceBlockMutex);
  2473. return pTraceMessage;
  2474. }
  2475. void CTraceViewApp::FreeTraceEventBlocks(CArray<CTraceMessage*, CTraceMessage*> &TraceArray)
  2476. {
  2477. //
  2478. // Get the free array protection
  2479. //
  2480. WaitForSingleObject(m_hTraceBlockMutex, INFINITE);
  2481. m_traceBlockArray.Append(TraceArray);
  2482. TraceArray.RemoveAll();
  2483. //
  2484. // Release the free array protection
  2485. //
  2486. ReleaseMutex(m_hTraceBlockMutex);
  2487. }
  2488. BOOL CTraceViewApp::OnIdle(LONG lCount)
  2489. {
  2490. CTraceMessage *pTraceMessage = NULL;
  2491. //
  2492. // Get the free array protection
  2493. //
  2494. WaitForSingleObject(m_hTraceBlockMutex, INFINITE);
  2495. for(LONG ii = 0; ii < 1000; ii++) {
  2496. if(m_traceBlockArray.GetSize() < 100) {
  2497. break;
  2498. }
  2499. //
  2500. // Get the next entry from the list
  2501. //
  2502. pTraceMessage = m_traceBlockArray.GetAt(0);
  2503. m_traceBlockArray.RemoveAt(0);
  2504. delete pTraceMessage;
  2505. }
  2506. //
  2507. // Release the free array protection
  2508. //
  2509. ReleaseMutex(m_hTraceBlockMutex);
  2510. return CWinApp::OnIdle(lCount);
  2511. }
  2512. void CTraceViewApp::PrintLoggerStatus(ULONG Status)
  2513. {
  2514. LPTSTR loggerName;
  2515. LPTSTR LogFileName;
  2516. CString errorMsg;
  2517. if ((m_pLoggerInfo->LoggerNameOffset > 0) &&
  2518. (m_pLoggerInfo->LoggerNameOffset < m_pLoggerInfo->Wnode.BufferSize)) {
  2519. loggerName = (LPTSTR) ((char*)m_pLoggerInfo +
  2520. m_pLoggerInfo->LoggerNameOffset);
  2521. }
  2522. else loggerName = NULL;
  2523. if ((m_pLoggerInfo->LogFileNameOffset > 0) &&
  2524. (m_pLoggerInfo->LogFileNameOffset < m_pLoggerInfo->Wnode.BufferSize)) {
  2525. LogFileName = (LPTSTR) ((char*)m_pLoggerInfo +
  2526. m_pLoggerInfo->LogFileNameOffset);
  2527. }
  2528. else LogFileName = NULL;
  2529. _tprintf(_T("Operation Status: %uL\t"), Status);
  2530. _tprintf(_T("%s\n"), DecodeStatus(Status));
  2531. _tprintf(_T("Logger Name: %s\n"),
  2532. (loggerName == NULL) ?
  2533. _T(" ") : loggerName);
  2534. // end_sdk
  2535. if (loggerName == NULL || !_tcscmp(loggerName, _T("GlobalLogger"))) {
  2536. // Logger ID
  2537. _tprintf(_T("Status: %s\n"),
  2538. m_globalLoggerStartValue ?
  2539. _T("Registry set to start") : _T("Registry set to stop"));
  2540. _tprintf(_T("Logger Id: %I64x\n"), m_pLoggerInfo->Wnode.HistoricalContext);
  2541. _tprintf(_T("Logger Thread Id: %p\n"), m_pLoggerInfo->LoggerThreadId);
  2542. if (m_pLoggerInfo->BufferSize == 0)
  2543. _tprintf(_T("Buffer Size: default value\n"));
  2544. else
  2545. _tprintf(_T("Buffer Size: %d Kb\n"), m_pLoggerInfo->BufferSize);
  2546. if (m_pLoggerInfo->MaximumBuffers == 0)
  2547. _tprintf(_T("Maximum Buffers: default value\n"));
  2548. else
  2549. _tprintf(_T("Maximum Buffers: %d\n"), m_pLoggerInfo->MaximumBuffers);
  2550. if (m_pLoggerInfo->MinimumBuffers == 0)
  2551. _tprintf(_T("Minimum Buffers: default value\n"));
  2552. else
  2553. _tprintf(_T("Minimum Buffers: %d\n"), m_pLoggerInfo->MinimumBuffers);
  2554. _tprintf(_T("Number of Buffers: %d\n"), m_pLoggerInfo->NumberOfBuffers);
  2555. _tprintf(_T("Free Buffers: %d\n"), m_pLoggerInfo->FreeBuffers);
  2556. _tprintf(_T("Buffers Written: %d\n"), m_pLoggerInfo->BuffersWritten);
  2557. _tprintf(_T("Events Lost: %d\n"), m_pLoggerInfo->EventsLost);
  2558. _tprintf(_T("Log Buffers Lost: %d\n"), m_pLoggerInfo->LogBuffersLost);
  2559. _tprintf(_T("Real Time Buffers Lost: %d\n"), m_pLoggerInfo->RealTimeBuffersLost);
  2560. _tprintf(_T("AgeLimit: %d\n"), m_pLoggerInfo->AgeLimit);
  2561. if (LogFileName == NULL) {
  2562. _tprintf(_T("Buffering Mode: "));
  2563. }
  2564. else {
  2565. _tprintf(_T("Log File Mode: "));
  2566. }
  2567. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_APPEND) {
  2568. _tprintf(_T("Append "));
  2569. }
  2570. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
  2571. _tprintf(_T("Circular\n"));
  2572. }
  2573. else if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  2574. _tprintf(_T("Sequential\n"));
  2575. }
  2576. else {
  2577. _tprintf(_T("Sequential\n"));
  2578. }
  2579. if (m_pLoggerInfo->MaximumFileSize > 0) {
  2580. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_KBYTES_FOR_SIZE)
  2581. _tprintf(_T("Maximum File Size: %d Kb\n"), m_pLoggerInfo->MaximumFileSize);
  2582. else
  2583. _tprintf(_T("Maximum File Size: %d Mb\n"), m_pLoggerInfo->MaximumFileSize);
  2584. }
  2585. if (m_pLoggerInfo->FlushTimer > 0)
  2586. _tprintf(_T("Buffer Flush Timer: %d secs\n"), m_pLoggerInfo->FlushTimer);
  2587. if (m_pLoggerInfo->EnableFlags != 0) {
  2588. _tprintf(_T("Enabled tracing: "));
  2589. if ((loggerName != NULL) && (!_tcscmp(loggerName, KERNEL_LOGGER_NAME))) {
  2590. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
  2591. _tprintf(_T("Process "));
  2592. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
  2593. _tprintf(_T("Thread "));
  2594. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
  2595. _tprintf(_T("Disk "));
  2596. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
  2597. _tprintf(_T("File "));
  2598. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
  2599. _tprintf(_T("PageFaults "));
  2600. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
  2601. _tprintf(_T("HardFaults "));
  2602. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
  2603. _tprintf(_T("ImageLoad "));
  2604. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
  2605. _tprintf(_T("TcpIp "));
  2606. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_REGISTRY)
  2607. _tprintf(_T("Registry "));
  2608. }
  2609. else {
  2610. _tprintf(_T("0x%08x"), m_pLoggerInfo->EnableFlags );
  2611. }
  2612. _tprintf(_T("\n"));
  2613. }
  2614. if (LogFileName == NULL || _tcslen(LogFileName) == 0) {
  2615. _tprintf(_T("Log Filename: default location\n"));
  2616. _tprintf(_T(" %%SystemRoot%%\\System32\\LogFiles\\WMI\\trace.log\n"));
  2617. }
  2618. else
  2619. _tprintf(_T("Log Filename: %s\n"), LogFileName);
  2620. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_LOCAL_SEQUENCE) {
  2621. _tprintf(_T("Local Sequence numbers in use\n"));
  2622. }
  2623. else if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_GLOBAL_SEQUENCE) {
  2624. _tprintf(_T("Global Sequence numbers in use\n"));
  2625. }
  2626. }
  2627. else {
  2628. // begin_sdk
  2629. _tprintf(_T("Logger Id: %I64x\n"), m_pLoggerInfo->Wnode.HistoricalContext);
  2630. _tprintf(_T("Logger Thread Id: %p\n"), m_pLoggerInfo->LoggerThreadId);
  2631. if (Status != 0)
  2632. return;
  2633. _tprintf(_T("Buffer Size: %d Kb"), m_pLoggerInfo->BufferSize);
  2634. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_PAGED_MEMORY) {
  2635. _tprintf(_T(" using paged memory\n"));
  2636. }
  2637. else {
  2638. _tprintf(_T("\n"));
  2639. }
  2640. _tprintf(_T("Maximum Buffers: %d\n"), m_pLoggerInfo->MaximumBuffers);
  2641. _tprintf(_T("Minimum Buffers: %d\n"), m_pLoggerInfo->MinimumBuffers);
  2642. _tprintf(_T("Number of Buffers: %d\n"), m_pLoggerInfo->NumberOfBuffers);
  2643. _tprintf(_T("Free Buffers: %d\n"), m_pLoggerInfo->FreeBuffers);
  2644. _tprintf(_T("Buffers Written: %d\n"), m_pLoggerInfo->BuffersWritten);
  2645. _tprintf(_T("Events Lost: %d\n"), m_pLoggerInfo->EventsLost);
  2646. _tprintf(_T("Log Buffers Lost: %d\n"), m_pLoggerInfo->LogBuffersLost);
  2647. _tprintf(_T("Real Time Buffers Lost: %d\n"), m_pLoggerInfo->RealTimeBuffersLost);
  2648. _tprintf(_T("AgeLimit: %d\n"), m_pLoggerInfo->AgeLimit);
  2649. if (LogFileName == NULL) {
  2650. _tprintf(_T("Buffering Mode: "));
  2651. }
  2652. else {
  2653. _tprintf(_T("Log File Mode: "));
  2654. }
  2655. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_APPEND) {
  2656. _tprintf(_T("Append "));
  2657. }
  2658. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
  2659. _tprintf(_T("Circular\n"));
  2660. }
  2661. else if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  2662. _tprintf(_T("Sequential\n"));
  2663. }
  2664. else {
  2665. _tprintf(_T("Sequential\n"));
  2666. }
  2667. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) {
  2668. _tprintf(_T("Real Time mode enabled"));
  2669. // end_sdk
  2670. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_BUFFERING_MODE) {
  2671. _tprintf(_T(": buffering only"));
  2672. }
  2673. // begin_sdk
  2674. _tprintf(_T("\n"));
  2675. }
  2676. if (m_pLoggerInfo->MaximumFileSize > 0) {
  2677. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_KBYTES_FOR_SIZE)
  2678. _tprintf(_T("Maximum File Size: %d Kb\n"), m_pLoggerInfo->MaximumFileSize);
  2679. else
  2680. _tprintf(_T("Maximum File Size: %d Mb\n"), m_pLoggerInfo->MaximumFileSize);
  2681. }
  2682. if (m_pLoggerInfo->FlushTimer > 0)
  2683. _tprintf(_T("Buffer Flush Timer: %d secs\n"), m_pLoggerInfo->FlushTimer);
  2684. if (m_pLoggerInfo->EnableFlags != 0) {
  2685. _tprintf(_T("Enabled tracing: "));
  2686. if ((loggerName != NULL) && (!_tcscmp(loggerName, KERNEL_LOGGER_NAME))) {
  2687. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
  2688. _tprintf(_T("Process "));
  2689. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
  2690. _tprintf(_T("Thread "));
  2691. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
  2692. _tprintf(_T("Disk "));
  2693. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
  2694. _tprintf(_T("File "));
  2695. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
  2696. _tprintf(_T("PageFaults "));
  2697. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
  2698. _tprintf(_T("HardFaults "));
  2699. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
  2700. _tprintf(_T("ImageLoad "));
  2701. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
  2702. _tprintf(_T("TcpIp "));
  2703. if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_REGISTRY)
  2704. _tprintf(_T("Registry "));
  2705. }else{
  2706. _tprintf(_T("0x%08x"), m_pLoggerInfo->EnableFlags );
  2707. }
  2708. _tprintf(_T("\n"));
  2709. }
  2710. if (LogFileName != NULL) {
  2711. _tprintf(_T("Log Filename: %s\n"), LogFileName);
  2712. }
  2713. // end_sdk
  2714. if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_LOCAL_SEQUENCE) {
  2715. _tprintf(_T("Local Sequence numbers in use\n"));
  2716. }
  2717. else if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_GLOBAL_SEQUENCE) {
  2718. _tprintf(_T("Global Sequence numbers in use\n"));
  2719. }
  2720. }
  2721. // begin_sdk
  2722. }
  2723. LPCTSTR CTraceViewApp::DecodeStatus(ULONG Status)
  2724. {
  2725. FormatMessage(
  2726. FORMAT_MESSAGE_FROM_SYSTEM |
  2727. FORMAT_MESSAGE_IGNORE_INSERTS,
  2728. NULL,
  2729. Status,
  2730. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  2731. m_errorMsg.GetBuffer(MAX_STR_LENGTH),
  2732. MAX_STR_LENGTH,
  2733. NULL );
  2734. return m_errorMsg;
  2735. }
  2736. LONG CTraceViewApp::GetGuids(LPCTSTR GuidFile)
  2737. {
  2738. FILE *f;
  2739. TCHAR line[MAX_STR_LENGTH];
  2740. TCHAR arg[MAX_STR_LENGTH];
  2741. LPGUID guid;
  2742. int i;
  2743. int n;
  2744. f = _tfopen(GuidFile, _T("r"));
  2745. if(f == NULL) {
  2746. return -1;
  2747. }
  2748. n = 0;
  2749. while(_fgetts(line, MAX_STR_LENGTH, f) != NULL) {
  2750. if (_tcslen(line) < 36)
  2751. continue;
  2752. if (line[0] == ';' ||
  2753. line[0] == '\0' ||
  2754. line[0] == '#' ||
  2755. line[0] == '/')
  2756. continue;
  2757. n ++;
  2758. m_guidArray.Add(line);
  2759. }
  2760. fclose(f);
  2761. return (ULONG)n;
  2762. }
  2763. void CTraceViewApp::DisplayVersionInfo()
  2764. {
  2765. TCHAR buffer[512];
  2766. TCHAR strProgram[MAXSTR];
  2767. DWORD dw;
  2768. BYTE* pVersionInfo;
  2769. LPTSTR pVersion = NULL;
  2770. LPTSTR pProduct = NULL;
  2771. LPTSTR pCopyRight = NULL;
  2772. if ((dw = GetModuleFileName(NULL, strProgram, MAXSTR)) == MAXSTR) {
  2773. strProgram[MAXSTR-1] = _T('\0');
  2774. }
  2775. if( dw>0 ){
  2776. dw = GetFileVersionInfoSize( strProgram, &dw );
  2777. if( dw > 0 ){
  2778. pVersionInfo = (BYTE*)malloc(dw);
  2779. if( NULL != pVersionInfo ){
  2780. if(GetFileVersionInfo( strProgram, 0, dw, pVersionInfo )){
  2781. LPDWORD lptr = NULL;
  2782. VerQueryValue( pVersionInfo, _T("\\VarFileInfo\\Translation"), (void**)&lptr, (UINT*)&dw );
  2783. if( lptr != NULL ){
  2784. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("ProductVersion") );
  2785. VerQueryValue( pVersionInfo, buffer, (void**)&pVersion, (UINT*)&dw );
  2786. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("OriginalFilename") );
  2787. VerQueryValue( pVersionInfo, buffer, (void**)&pProduct, (UINT*)&dw );
  2788. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("LegalCopyright") );
  2789. VerQueryValue( pVersionInfo, buffer, (void**)&pCopyRight, (UINT*)&dw );
  2790. }
  2791. if( pProduct != NULL && pVersion != NULL && pCopyRight != NULL ){
  2792. _tprintf( _T("\nMicrosoft (R) %s (%s)\n%s\n\n"), pProduct, pVersion, pCopyRight );
  2793. }
  2794. }
  2795. free( pVersionInfo );
  2796. }
  2797. }
  2798. }
  2799. }
  2800. BOOL CTraceViewApp::CheckFile(LPTSTR fileName)
  2801. {
  2802. HANDLE hFile;
  2803. BYTE LogHeaderBuffer[DEFAULT_LOG_BUFFER_SIZE];
  2804. ULONG nBytesRead ;
  2805. ULONG hResult ;
  2806. PEVENT_TRACE pEvent;
  2807. PTRACE_LOGFILE_HEADER logfileHeader ;
  2808. LARGE_INTEGER lFileSize ;
  2809. LARGE_INTEGER lFileSizeMB ;
  2810. DWORD dwDesiredAccess , dwShareMode ;
  2811. FILETIME stdTime, localTime, endlocalTime, endTime;
  2812. SYSTEMTIME sysTime, endsysTime;
  2813. PEVENT_TRACE_LOGFILE pLogBuffer ;
  2814. if (m_bFixUp) {
  2815. dwShareMode = 0 ;
  2816. dwDesiredAccess = GENERIC_READ | GENERIC_WRITE ;
  2817. } else {
  2818. dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ;
  2819. dwDesiredAccess = GENERIC_READ ;
  2820. }
  2821. hFile = CreateFile(
  2822. fileName,
  2823. dwDesiredAccess,
  2824. dwShareMode,
  2825. NULL,
  2826. OPEN_EXISTING,
  2827. FILE_ATTRIBUTE_NORMAL,
  2828. NULL
  2829. );
  2830. if (hFile == INVALID_HANDLE_VALUE) {
  2831. if (m_bFixUp) {
  2832. _tprintf(_T("ERROR: Fixup could not open file, Error = 0x%X\n"),GetLastError());
  2833. exit(GetLastError());
  2834. }
  2835. return(FALSE);
  2836. }
  2837. // While we are here we will look to see if the file is ok and fix up
  2838. // Circular buffer anomolies
  2839. if (((hResult = ReadFile(hFile,
  2840. (LPVOID)LogHeaderBuffer,
  2841. DEFAULT_LOG_BUFFER_SIZE,
  2842. &nBytesRead,
  2843. NULL)) == 0) || nBytesRead < DEFAULT_LOG_BUFFER_SIZE) {
  2844. _tprintf(_T("ERROR: Fixup could not read file, Error = 0x%X, bytes read = %d(of %d)\n"),
  2845. GetLastError(),nBytesRead,DEFAULT_LOG_BUFFER_SIZE);
  2846. exit(ERROR_BAD_ARGUMENTS);
  2847. }
  2848. pEvent = (PEVENT_TRACE)LogHeaderBuffer ;
  2849. logfileHeader = (PTRACE_LOGFILE_HEADER)&LogHeaderBuffer[sizeof(WMI_BUFFER_HEADER) +
  2850. sizeof(SYSTEM_TRACE_HEADER)];
  2851. if (m_bVerbose) {
  2852. _tprintf(_T("Dumping Logfile Header\n"));
  2853. RtlCopyMemory(&stdTime , &(logfileHeader->StartTime), sizeof(FILETIME));
  2854. FileTimeToLocalFileTime(&stdTime, &localTime);
  2855. FileTimeToSystemTime(&localTime, &sysTime);
  2856. RtlCopyMemory(&endTime , &(logfileHeader->EndTime), sizeof(FILETIME));
  2857. FileTimeToLocalFileTime(&endTime, &endlocalTime);
  2858. FileTimeToSystemTime(&endlocalTime, &endsysTime);
  2859. _tprintf(_T("\tStart Time %02d/%02d/%04d-%02d:%02d:%02d.%03d\n"),
  2860. sysTime.wMonth,
  2861. sysTime.wDay,
  2862. sysTime.wYear,
  2863. sysTime.wHour,
  2864. sysTime.wMinute,
  2865. sysTime.wSecond,
  2866. sysTime.wMilliseconds);
  2867. _tprintf(_T("\tBufferSize %d\n"),
  2868. logfileHeader->BufferSize);
  2869. _tprintf(_T("\tVersion %d\n"),
  2870. logfileHeader->Version);
  2871. _tprintf(_T("\tProviderVersion %d\n"),
  2872. logfileHeader->ProviderVersion);
  2873. _tprintf(_T("\tEnd Time %02d/%02d/%04d-%02d:%02d:%02d.%03d\n"),
  2874. endsysTime.wMonth,
  2875. endsysTime.wDay,
  2876. endsysTime.wYear,
  2877. endsysTime.wHour,
  2878. endsysTime.wMinute,
  2879. endsysTime.wSecond,
  2880. endsysTime.wMilliseconds);
  2881. _tprintf(_T("\tTimer Resolution %d\n"),
  2882. logfileHeader->TimerResolution);
  2883. _tprintf(_T("\tMaximum File Size %d\n"),
  2884. logfileHeader->MaximumFileSize);
  2885. _tprintf(_T("\tBuffers Written %d\n"),
  2886. logfileHeader->BuffersWritten);
  2887. /*
  2888. _tprintf(_T("\tLogger Name %ls\n"),
  2889. logfileHeader->LoggerName);
  2890. _tprintf(_T("\tLogfile Name %ls\n"),
  2891. logfileHeader->LogFileName);
  2892. */
  2893. _tprintf(_T("\tTimezone is %s (Bias is %dmins)\n"),
  2894. logfileHeader->TimeZone.StandardName,logfileHeader->TimeZone.Bias);
  2895. _tprintf(_T("\tLogfile Mode %X "),
  2896. logfileHeader->LogFileMode);
  2897. if (logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_NONE) {
  2898. _tprintf(_T("Logfile is off(?)\n"));
  2899. } else if (logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  2900. _tprintf(_T("Logfile is sequential\n"));
  2901. } else if (logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_CIRCULAR) {
  2902. _tprintf(_T("Logfile is circular\n"));
  2903. }
  2904. _tprintf(_T("\tProcessorCount %d\n"),
  2905. logfileHeader->NumberOfProcessors);
  2906. }
  2907. if (GetFileSizeEx(hFile, &lFileSize) == 0) {
  2908. _tprintf(_T("WARNING: Could not get file size, continuing\n"));
  2909. } else {
  2910. lFileSizeMB.QuadPart = lFileSize.QuadPart / (1024*1024) ;
  2911. if (lFileSizeMB.QuadPart > logfileHeader->MaximumFileSize) {
  2912. _tprintf(_T("WARNING: File size given as %dMB, should be %dMB\n"),
  2913. logfileHeader->MaximumFileSize,lFileSizeMB.QuadPart);
  2914. if (lFileSize.HighPart != 0) {
  2915. _tprintf(_T("WARNING: Log file is TOO big"));
  2916. }
  2917. if (m_bFixUp) {
  2918. logfileHeader->MaximumFileSize = lFileSizeMB.LowPart + 1 ;
  2919. }
  2920. }
  2921. }
  2922. if ((logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_CIRCULAR) &&
  2923. (logfileHeader->BuffersWritten== 0 )) {
  2924. _tprintf(_T("WARNING: Circular Trace File did not have 'wrap' address\n"));
  2925. if (m_bFixUp) {
  2926. // Figure out the wrap address
  2927. INT LowBuff = 1, HighBuff, CurrentBuff, MaxBuff ;
  2928. FILETIME LowTime, HighTime, CurrentTime, MaxTime ;
  2929. if (lFileSize.HighPart != 0) {
  2930. _tprintf(_T("ERROR: File TOO big\n"));
  2931. exit(-1);
  2932. }
  2933. MaxBuff = (LONG)(lFileSize.QuadPart / logfileHeader->BufferSize) - 1 ;
  2934. _tprintf(_T("MaxBuff=%d\n"),MaxBuff);
  2935. pLogBuffer = (PEVENT_TRACE_LOGFILE)malloc(logfileHeader->BufferSize);
  2936. if (SetFilePointer(hFile,0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
  2937. _tprintf(_T("ERROR: Could not reset file to beginning for FixUp, Error = 0x%X"),
  2938. GetLastError());
  2939. exit(GetLastError());
  2940. }
  2941. for (CurrentBuff = 1 ; CurrentBuff <= MaxBuff; CurrentBuff++) {
  2942. if (SetFilePointer(hFile,logfileHeader->BufferSize, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) {
  2943. _tprintf(_T("ERROR: Could not set file to next buffer for FixUp, Error = 0x%X"),
  2944. GetLastError());
  2945. exit(GetLastError());
  2946. }
  2947. hResult = ReadFile(hFile,
  2948. (LPVOID)pLogBuffer,
  2949. logfileHeader->BufferSize,
  2950. &nBytesRead,
  2951. NULL);
  2952. BufferCallback((PEVENT_TRACE_LOGFILE)pLogBuffer);
  2953. }
  2954. }
  2955. }
  2956. if (m_bFixUp) {
  2957. if (SetFilePointer(hFile,0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
  2958. _tprintf(_T("ERROR: Could not reset file to beginning for FixUp, Error = 0x%X"),
  2959. GetLastError());
  2960. exit(GetLastError());
  2961. }
  2962. logfileHeader->BuffersWritten = m_bufferWrap;
  2963. if (!WriteFile(hFile,(LPVOID)LogHeaderBuffer,DEFAULT_LOG_BUFFER_SIZE,&nBytesRead, NULL)) {
  2964. _tprintf(_T("ERROR: Could not Write file for FixUp, Error = 0x%X"),
  2965. GetLastError());
  2966. exit(GetLastError());
  2967. }
  2968. _tprintf(_T("INFO: Buffer Wrap reset to %d\n"), m_bufferWrap);
  2969. }
  2970. CloseHandle(hFile);
  2971. return (TRUE);
  2972. }
  2973. ULONG CTraceViewApp::BufferCallback(PEVENT_TRACE_LOGFILE pLog)
  2974. {
  2975. ULONG i;
  2976. ULONG Status;
  2977. EVENT_TRACE_PROPERTIES LoggerProp;
  2978. CTraceViewApp *pApp = (CTraceViewApp *)AfxGetApp();
  2979. pApp->m_totalBuffersRead++;
  2980. pApp->m_totalEventsLost += pLog->EventsLost;
  2981. if (pApp->m_bVerbose) {
  2982. FILETIME stdTime, localTime;
  2983. SYSTEMTIME sysTime;
  2984. RtlCopyMemory(&stdTime , &pLog->CurrentTime, sizeof(FILETIME));
  2985. FileTimeToSystemTime(&stdTime, &sysTime);
  2986. _tprintf(_T("%02d/%02d/%04d-%02d:%02d:%02d.%03d :: %8d: Filled=%8d, Lost=%3d"),
  2987. sysTime.wMonth,
  2988. sysTime.wDay,
  2989. sysTime.wYear,
  2990. sysTime.wHour,
  2991. sysTime.wMinute,
  2992. sysTime.wSecond,
  2993. sysTime.wMilliseconds,
  2994. pApp->m_totalBuffersRead,
  2995. pLog->Filled,
  2996. pLog->EventsLost);
  2997. _tprintf(_T(" TotalLost= %d\r"), pApp->m_totalEventsLost);
  2998. if (CompareFileTime(&pApp->m_lastTime,&stdTime) == 1) {
  2999. _tprintf(_T("\nWARNING: time appears to have wrapped here (Block = %d)!\n"), pApp->m_totalBuffersRead);
  3000. pApp->m_bufferWrap = pApp->m_totalBuffersRead;
  3001. }
  3002. pApp->m_lastTime = stdTime ;
  3003. }
  3004. return (TRUE);
  3005. }
  3006. void CTraceViewApp::DumpEvent(PEVENT_TRACE pEvent)
  3007. {
  3008. CTraceViewApp *pApp = (CTraceViewApp *)AfxGetApp();
  3009. pApp->m_totalEventCount++;
  3010. if (pEvent == NULL) {
  3011. _tprintf(_T("pEvent is NULL\n"));
  3012. return;
  3013. }
  3014. // DumpEvent() is only a wrapper, it calls FormatTraceEvent() in TracePrt.
  3015. //
  3016. if (FormatTraceEvent(pApp->m_eventListHead, pEvent, pApp->m_eventBuf, SIZEEVENTBUF, NULL) > 0)
  3017. {
  3018. TCHAR * eventBufWork = &pApp->m_eventBuf[0] ;
  3019. #ifdef UNICODE
  3020. //sprintf(_T("Name,\"SubName(File+line#)\",ThreadID,ProcessId,SequenceNumber,CPUNumber,Indent,Function,Component,TraceLevel,TraceFlags,Text\n"));
  3021. if (pApp->m_bCSVMode) {
  3022. PSTRUCTUREDMESSAGE pStructuredMessage = (PSTRUCTUREDMESSAGE)&pApp->m_eventBuf[0];
  3023. /* if (fCSVHeader && fNoCSVHeader) {
  3024. fCSVHeader = FALSE ;
  3025. _stprintf((TCHAR *)pApp->m_eventBufCSV,_T("GUIDname,TypeName,ThreadId,ProcessId,SequenceNum,CpuNumber,Indent,CompnentName,SubComponentName,FunctionName,LevelName,FlagsName, String"));
  3026. } */
  3027. _stprintf((TCHAR *)pApp->m_eventBufCSV,_T("%s,%s,%08X,%08X,%d,%d,%d,%s,%s,%s,%s,%s,\"%s\""),
  3028. (pStructuredMessage->GuidName?&pApp->m_eventBuf[pStructuredMessage->GuidName/sizeof(TCHAR)]:_T("")),
  3029. (pStructuredMessage->GuidTypeName?&pApp->m_eventBuf[pStructuredMessage->GuidTypeName/sizeof(TCHAR)]:_T("")),
  3030. pStructuredMessage->ThreadId,
  3031. pStructuredMessage->ProcessId,
  3032. pStructuredMessage->SequenceNum,
  3033. pStructuredMessage->CpuNumber,
  3034. pStructuredMessage->Indent,
  3035. (pStructuredMessage->ComponentName?&pApp->m_eventBuf[pStructuredMessage->ComponentName/sizeof(TCHAR)]:_T("")),
  3036. (pStructuredMessage->SubComponentName?&pApp->m_eventBuf[pStructuredMessage->SubComponentName/sizeof(TCHAR)]:_T("")),
  3037. (pStructuredMessage->FunctionName?&pApp->m_eventBuf[pStructuredMessage->FunctionName/sizeof(TCHAR)]:_T("")),
  3038. (pStructuredMessage->LevelName?&pApp->m_eventBuf[pStructuredMessage->LevelName/sizeof(TCHAR)]:_T("")),
  3039. (pStructuredMessage->FlagsName?&pApp->m_eventBuf[pStructuredMessage->FlagsName/sizeof(TCHAR)]:_T("")),
  3040. (pStructuredMessage->FormattedString?&pApp->m_eventBuf[pStructuredMessage->FormattedString/sizeof(TCHAR)]:_T("")));
  3041. eventBufWork = (TCHAR *)&pApp->m_eventBufCSV[0] ;
  3042. }
  3043. //
  3044. // Convert Unicode to MultiByte
  3045. //
  3046. if (WideCharToMultiByte(GetConsoleOutputCP(),
  3047. 0,
  3048. eventBufWork,
  3049. -1,
  3050. pApp->m_eventBufA,
  3051. SIZEEVENTBUF * sizeof(WCHAR),
  3052. NULL,
  3053. NULL ) == 0 )
  3054. {
  3055. //
  3056. // do nothing, let the _ftprintf handle it.
  3057. //
  3058. }
  3059. else
  3060. {
  3061. if (!pApp->m_bSummaryOnly && !pApp->m_bDisplayOnly) {
  3062. fprintf(pApp->m_pDumpFile, "%s\n", pApp->m_eventBufA);
  3063. }
  3064. if (pApp->m_bDebugDisplay || pApp->m_bDisplayOnly) {
  3065. if (pApp->m_bODSOutput) {
  3066. OutputDebugStringA(pApp->m_eventBufA);
  3067. OutputDebugStringA("\n");
  3068. } else {
  3069. printf("%s\n", pApp->m_eventBufA);
  3070. }
  3071. }
  3072. return ;
  3073. }
  3074. #endif
  3075. if (!pApp->m_bSummaryOnly && !pApp->m_bDisplayOnly) {
  3076. _ftprintf(pApp->m_pDumpFile, _T("%s\n"),pApp->m_eventBuf);
  3077. }
  3078. if (pApp->m_bDebugDisplay || pApp->m_bDisplayOnly) {
  3079. if (pApp->m_bODSOutput) {
  3080. OutputDebugString(pApp->m_eventBuf);
  3081. OutputDebugString(_T("\n"));
  3082. } else {
  3083. _tprintf(_T("%s\n"),pApp->m_eventBuf);
  3084. }
  3085. }
  3086. }
  3087. }
  3088. void CTraceViewApp::OnHelpHelpTopics()
  3089. {
  3090. ::HtmlHelp(
  3091. 0,
  3092. _T("traceview.chm"),
  3093. HH_DISPLAY_TOC,
  3094. NULL);
  3095. }