Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

809 lines
26 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. traceformat.c
  5. Abstract:
  6. Formats trace entries into messages based on the original sample trace
  7. consumer program (tracedmp).
  8. Author:
  9. Jee Fung Pang (jeepang) 03-Dec-1997
  10. Revision History:
  11. Ian Service (ianserv) 1999 - converted to message formatting
  12. --*/
  13. #ifdef __cplusplus
  14. extern "C"{
  15. #endif
  16. #define UNICODE
  17. #define _UNICODE
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <nt.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <windows.h>
  24. #include <shellapi.h>
  25. #include <tchar.h>
  26. #include <wmistr.h>
  27. #include <initguid.h>
  28. #include <evntrace.h>
  29. #define POBJECT_ATTRIBUTES PVOID
  30. #include <ntwmi.h>
  31. #include "traceprt.h"
  32. #define DUMP_FILE_NAME _T("FmtFile.txt")
  33. #define SUMMARY_FILE_NAME _T("FmtSum.txt")
  34. #define DEFAULT_LOGFILE_NAME _T("C:\\Logfile.Etl")
  35. FILE* DumpFile = NULL;
  36. FILE* SummaryFile = NULL;
  37. BOOL fDebugDisplay = FALSE ;
  38. BOOL fDisplayOnly = FALSE ;
  39. BOOL fSummaryOnly = FALSE ;
  40. BOOL fNoSummary = FALSE ;
  41. BOOL fVerbose = FALSE ;
  42. BOOL fFixUp = FALSE ;
  43. BOOL fODSOutput = FALSE ;
  44. BOOL fTMFSpecified = FALSE ;
  45. #define SIZESUMMARYBLOCK 16384
  46. TCHAR SummaryBlock[SIZESUMMARYBLOCK];
  47. static FILETIME lastTime ;
  48. static ULONG TotalBuffersRead = 0;
  49. static ULONG TotalEventsLost = 0;
  50. static ULONG TotalEventCount = 0;
  51. static ULONG TimerResolution = 10;
  52. static ULONG BufferWrap = 0 ;
  53. __int64 ElapseTime;
  54. PLIST_ENTRY EventListHead = NULL;
  55. void
  56. DumpMofList();
  57. void
  58. PrintMofInfo();
  59. BOOL
  60. CheckFile(
  61. LPTSTR fileName
  62. );
  63. ULONG
  64. BufferCallback(
  65. PEVENT_TRACE_LOGFILE pLog
  66. );
  67. void
  68. AddMofFromWbem(
  69. LPTSTR EventGuid,
  70. LPTSTR PropName,
  71. DWORD PropType
  72. );
  73. void
  74. DumpEvent(
  75. PEVENT_TRACE pEvent
  76. );
  77. PEVENT_TRACE_LOGFILE EvmFile[MAXLOGFILES];
  78. ULONG LogFileCount = 0;
  79. ULONG UserMode = FALSE; // TODO: Pick this up from the stream itself.
  80. TCHAR * szTraceMask = NULL;
  81. void DisplayVersionInfo();
  82. int
  83. __cdecl main (argc, argv)
  84. int argc;
  85. char **argv;
  86. {
  87. TCHAR GuidFileName[MAXSTR];
  88. TCHAR DumpFileName[MAXSTR];
  89. TCHAR SummaryFileName[MAXSTR];
  90. LPTSTR *commandLine;
  91. LPTSTR *targv, *cmdargv;
  92. PEVENT_TRACE_LOGFILE pLogFile;
  93. ULONG Action = 0;
  94. ULONG Status;
  95. ULONG GuidCount = 0;
  96. ULONG i, j;
  97. int targc;
  98. TRACEHANDLE HandleArray[MAXLOGFILES];
  99. if ((cmdargv = CommandLineToArgvW(
  100. GetCommandLineW(),
  101. &argc
  102. )) == NULL)
  103. {
  104. return (GetLastError());
  105. }
  106. targv = cmdargv;
  107. _tcscpy(DumpFileName, DUMP_FILE_NAME);
  108. _tcscpy(SummaryFileName, SUMMARY_FILE_NAME);
  109. // By default look for Define.guid in the image location
  110. Status = GetModuleFileName(NULL, GuidFileName, MAXSTR);
  111. if( Status != 0 ){
  112. TCHAR drive[10];
  113. TCHAR path[MAXSTR];
  114. TCHAR file[MAXSTR];
  115. TCHAR ext[MAXSTR];
  116. _tsplitpath( GuidFileName, drive, path, file, ext );
  117. _tcscpy(ext, GUID_EXT );
  118. _tcscpy(file, GUID_FILE );
  119. _tmakepath( GuidFileName, drive, path, file, ext );
  120. }else{
  121. _tcscpy( GuidFileName, GUID_FILE );
  122. _tcscat( GuidFileName, _T(".") );
  123. _tcscat( GuidFileName, GUID_EXT );
  124. }
  125. while (--argc > 0) {
  126. ++targv;
  127. if (**targv == '-' || **targv == '/') { // argument found
  128. if( **targv == '/' ){
  129. **targv = '-';
  130. }
  131. if (targv[0][1] == 'h' || targv[0][1] == 'H'
  132. || targv[0][1] == '?')
  133. {
  134. DisplayVersionInfo();
  135. _tprintf(
  136. _T("Usage: traceformat [options] <evmfile>| [-h | -?]\n")
  137. _T("\t-o <file> Output file\n")
  138. _T("\t-tmf <file> Format definition file\n")
  139. _T("\t-rt Realtime formatting\n")
  140. _T("\t-h Display this information\n")
  141. _T("\t-display Display output\n")
  142. _T("\t-displayonly Display output. Don't write to the file\n")
  143. _T("\t-nosummary Don't create the summary file\n")
  144. _T("\t-ods do Display output using OutputDebugString\n")
  145. _T("\t-summaryonly Don't create the listing file.\n")
  146. _T("\t-v Verbose Display\n")
  147. _T("\t-? Display this information\n")
  148. _T("\n")
  149. _T("\tDefault evmfile is ") DEFAULT_LOGFILE_NAME _T("\n")
  150. _T("\tDefault outputfile is ") DUMP_FILE_NAME _T("\n")
  151. _T("\tDefault TMF file is ") GUID_FILE _T(".") GUID_EXT _T("\n")
  152. _T("\n")
  153. _T("\tTMF file search path is read from environment variable\n")
  154. _T("\t\tTRACE_FORMAT_SEARCH_PATH\n")
  155. );
  156. return 0;
  157. }
  158. else if (!_tcsicmp(targv[0], _T("-debug"))) {
  159. fDebugDisplay = TRUE;
  160. }
  161. else if (!_tcsicmp(targv[0], _T("-display"))) {
  162. fDebugDisplay = TRUE ;
  163. }
  164. else if (!_tcsicmp(targv[0], _T("-displayonly"))) {
  165. fDisplayOnly = TRUE ;
  166. }
  167. else if (!_tcsicmp(targv[0], _T("-fixup"))) {
  168. fFixUp = TRUE;
  169. }
  170. else if (!_tcsicmp(targv[0], _T("-summary"))) {
  171. fSummaryOnly = TRUE;
  172. }
  173. else if (!_tcsicmp(targv[0], _T("-seq"))) {
  174. SetTraceFormatParameter(ParameterSEQUENCE, ULongToPtr(1));
  175. }
  176. else if (!_tcsicmp(targv[0], _T("-gmt"))) {
  177. SetTraceFormatParameter(ParameterGMT, ULongToPtr(1));
  178. }
  179. else if (!_tcsicmp(targv[0], _T("-nosummary"))) {
  180. fNoSummary = TRUE;
  181. }
  182. else if (!_tcsicmp(targv[0], _T("-rt"))) {
  183. TCHAR LoggerName[MAXSTR];
  184. _tcscpy(LoggerName, KERNEL_LOGGER_NAME);
  185. if (argc > 1) {
  186. if (targv[1][0] != '-' && targv[1][0] != '/') {
  187. ++targv; --argc;
  188. _tcscpy(LoggerName, targv[0]);
  189. }
  190. }
  191. pLogFile = malloc(sizeof(EVENT_TRACE_LOGFILE));
  192. if (pLogFile == NULL){
  193. _tprintf(_T("Allocation Failure\n"));
  194. goto cleanup;
  195. }
  196. RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
  197. EvmFile[LogFileCount] = pLogFile;
  198. EvmFile[LogFileCount]->LogFileName = NULL;
  199. EvmFile[LogFileCount]->LoggerName =
  200. (LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
  201. if ( EvmFile[LogFileCount]->LoggerName == NULL ) {
  202. _tprintf(_T("Allocation Failure\n"));
  203. goto cleanup;
  204. }
  205. _tcscpy(EvmFile[LogFileCount]->LoggerName, LoggerName);
  206. _tprintf(_T("Setting RealTime mode for %s\n"),
  207. EvmFile[LogFileCount]->LoggerName);
  208. EvmFile[LogFileCount]->Context = NULL;
  209. EvmFile[LogFileCount]->BufferCallback = (PEVENT_TRACE_BUFFER_CALLBACKW)BufferCallback;
  210. EvmFile[LogFileCount]->BuffersRead = 0;
  211. EvmFile[LogFileCount]->CurrentTime = 0;
  212. EvmFile[LogFileCount]->EventCallback = (PEVENT_CALLBACK)&DumpEvent;
  213. EvmFile[LogFileCount]->LogFileMode =
  214. EVENT_TRACE_REAL_TIME_MODE;
  215. LogFileCount++;
  216. }
  217. else if ( !_tcsicmp(targv[0], _T("-guid")) ) { // maintain for compatabillity
  218. if (argc > 1) {
  219. if (targv[1][0] != '-' && targv[1][0] != '/') {
  220. _tcscpy(GuidFileName, targv[1]);
  221. ++targv; --argc;
  222. fTMFSpecified = TRUE ;
  223. }
  224. }
  225. }
  226. else if ( !_tcsicmp(targv[0], _T("-tmf")) ) {
  227. if (argc > 1) {
  228. if (targv[1][0] != '-' && targv[1][0] != '/') {
  229. _tcscpy(GuidFileName, targv[1]);
  230. ++targv; --argc;
  231. fTMFSpecified = TRUE ;
  232. }
  233. }
  234. }
  235. else if ( !_tcsicmp(targv[0], _T("-v")) ) {
  236. fVerbose = TRUE ;
  237. }
  238. else if ( !_tcsicmp(targv[0], _T("-ods")) ) {
  239. fODSOutput = TRUE ;
  240. }
  241. else if ( !_tcsicmp(targv[0], _T("-onlyshow")) ) {
  242. if (argc > 1) {
  243. szTraceMask = malloc((_tcslen(targv[1])+1) * sizeof(TCHAR));
  244. _tcscpy(szTraceMask,targv[1]);
  245. ++targv; --argc;
  246. }
  247. }
  248. else if ( !_tcsicmp(targv[0], _T("-o")) ) {
  249. if (argc > 1) {
  250. if (targv[1][0] != '-' && targv[1][0] != '/') {
  251. TCHAR drive[10];
  252. TCHAR path[MAXSTR];
  253. TCHAR file[MAXSTR];
  254. TCHAR ext[MAXSTR];
  255. ++targv; --argc;
  256. _tfullpath(DumpFileName, targv[0], MAXSTR);
  257. _tsplitpath( DumpFileName, drive, path, file, ext );
  258. _tcscat(ext,_T(".sum"));
  259. _tmakepath( SummaryFileName, drive, path, file, ext );
  260. }
  261. }
  262. }
  263. }
  264. else {
  265. pLogFile = malloc(sizeof(EVENT_TRACE_LOGFILE));
  266. if (pLogFile == NULL){
  267. _tprintf(_T("Allocation Failure(EVENT_TRACE_LOGFILE)\n")); // Need to cleanup better.
  268. goto cleanup;
  269. }
  270. RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
  271. EvmFile[LogFileCount] = pLogFile;
  272. EvmFile[LogFileCount]->LoggerName = NULL;
  273. EvmFile[LogFileCount]->LogFileName =
  274. (LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
  275. if (EvmFile[LogFileCount]->LogFileName == NULL) {
  276. _tprintf(_T("Allocation Failure (LogFileName)\n"));
  277. goto cleanup;
  278. }
  279. _tfullpath(EvmFile[LogFileCount]->LogFileName, targv[0], MAXSTR);
  280. _tprintf(_T("Setting log file to: %s\n"),
  281. EvmFile[LogFileCount]->LogFileName);
  282. if (!CheckFile(EvmFile[LogFileCount]->LogFileName)) {
  283. _tprintf(_T("Cannot open logfile for reading\n"));
  284. goto cleanup;
  285. }
  286. EvmFile[LogFileCount]->Context = NULL;
  287. EvmFile[LogFileCount]->BufferCallback = (PEVENT_TRACE_BUFFER_CALLBACKW)BufferCallback;
  288. EvmFile[LogFileCount]->BuffersRead = 0;
  289. EvmFile[LogFileCount]->CurrentTime = 0;
  290. EvmFile[LogFileCount]->EventCallback = (PEVENT_CALLBACK)&DumpEvent;
  291. LogFileCount++;
  292. }
  293. }
  294. if( _tcslen( GuidFileName ) ){
  295. TCHAR str[MAXSTR];
  296. _tfullpath( str, GuidFileName, MAXSTR);
  297. _tcscpy( GuidFileName, str );
  298. _tprintf(_T("Getting guids from %s\n"), GuidFileName);
  299. GuidCount = GetTraceGuids(GuidFileName, (PLIST_ENTRY *) &EventListHead);
  300. if ((GuidCount <= 0) && fTMFSpecified)
  301. {
  302. _tprintf(_T("GetTraceGuids returned %d, GetLastError=%d, for %s\n"),
  303. GuidCount,
  304. GetLastError(),
  305. GuidFileName);
  306. }
  307. }
  308. if (LogFileCount <= 0) {
  309. pLogFile = malloc(sizeof(EVENT_TRACE_LOGFILE));
  310. if (pLogFile == NULL){
  311. _tprintf(_T("Allocation Failure\n")); // Need to cleanup better.
  312. goto cleanup;
  313. }
  314. RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
  315. EvmFile[0] = pLogFile;
  316. EvmFile[0]->LoggerName = NULL;
  317. LogFileCount = 1;
  318. EvmFile[0]->LogFileName = (LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
  319. if (EvmFile[0]->LogFileName == NULL) {
  320. _tprintf(_T("Allocation Failure\n"));
  321. goto cleanup;
  322. }
  323. _tcscpy(EvmFile[0]->LogFileName, DEFAULT_LOGFILE_NAME);
  324. EvmFile[0]->EventCallback = (PEVENT_CALLBACK)&DumpEvent;
  325. }
  326. for (i = 0; i < LogFileCount; i++) {
  327. TRACEHANDLE x;
  328. x = OpenTrace(EvmFile[i]);
  329. HandleArray[i] = x;
  330. if (HandleArray[i] == 0) {
  331. _tprintf(_T("Error Opening Trace %d with status=%d\n"),
  332. i, GetLastError());
  333. for (j = 0; j < i; j++)
  334. CloseTrace(HandleArray[j]);
  335. goto cleanup;
  336. }
  337. }
  338. if (!fDisplayOnly) {
  339. DumpFile = _tfopen(DumpFileName, _T("w"));
  340. if (DumpFile == NULL) {
  341. _tprintf(_T("Format File \"%s\" Could not be opened for writing 0X%X\n"),
  342. DumpFileName,GetLastError());
  343. goto cleanup;
  344. }
  345. SummaryFile = NULL ;
  346. if (!fNoSummary) {
  347. SummaryFile = _tfopen(SummaryFileName, _T("w"));
  348. if (SummaryFile == NULL) {
  349. _tprintf(_T("Summary File \"%s\" could not be opened for writing 0X%X\n"),
  350. SummaryFileName,GetLastError());
  351. goto cleanup;
  352. }
  353. }
  354. } else {
  355. DumpFile = stdout;
  356. SummaryFile = stdout;
  357. }
  358. Status = ProcessTrace(HandleArray,
  359. LogFileCount,
  360. NULL, NULL);
  361. if (Status != ERROR_SUCCESS) {
  362. _tprintf(_T("Error processing trace entry with status=0x%x (GetLastError=0x%x)\n"),
  363. Status, GetLastError());
  364. }
  365. for (j = 0; j < LogFileCount; j++){
  366. Status = CloseTrace(HandleArray[j]);
  367. if (Status != ERROR_SUCCESS) {
  368. _tprintf(_T("Error Closing Trace %d with status=%d\n"), j, Status);
  369. }
  370. }
  371. if (!fNoSummary) {
  372. _ftprintf(SummaryFile,_T("Files Processed:\n"));
  373. for (i=0; i<LogFileCount; i++) {
  374. _ftprintf(SummaryFile,_T("\t%s\n"),EvmFile[i]->LogFileName);
  375. }
  376. GetTraceElapseTime(&ElapseTime);
  377. _ftprintf(SummaryFile,
  378. _T("Total Buffers Processed %d\n")
  379. _T("Total Events Processed %d\n")
  380. _T("Total Events Lost %d\n")
  381. _T("Elapsed Time %I64d sec\n"),
  382. TotalBuffersRead,
  383. TotalEventCount,
  384. TotalEventsLost,
  385. (ElapseTime / 10000000) );
  386. _ftprintf(SummaryFile,
  387. _T("+-----------------------------------------------------------------------------------+\n")
  388. _T("|%10s %-20s %-10s %-36s|\n")
  389. _T("+-----------------------------------------------------------------------------------+\n"),
  390. _T("EventCount"),
  391. _T("EventName"),
  392. _T("EventType"),
  393. _T("Guid")
  394. );
  395. SummaryTraceEventList(SummaryBlock, SIZESUMMARYBLOCK, EventListHead);
  396. _ftprintf(SummaryFile,
  397. _T("%s+-----------------------------------------------------------------------------------+\n"),
  398. SummaryBlock);
  399. }
  400. cleanup:
  401. CleanupTraceEventList(EventListHead);
  402. if (fVerbose) {
  403. _tprintf(_T("\n")); // need a newline after the block updates
  404. }
  405. if (DumpFile != NULL) {
  406. _tprintf(_T("Event traces dumped to %s\n"), DumpFileName);
  407. fclose(DumpFile);
  408. }
  409. if(SummaryFile != NULL){
  410. _tprintf(_T("Event Summary dumped to %s\n"), SummaryFileName);
  411. fclose(SummaryFile);
  412. }
  413. for (i = 0; i < LogFileCount; i ++)
  414. {
  415. if (EvmFile[i]->LoggerName != NULL)
  416. {
  417. free(EvmFile[i]->LoggerName);
  418. EvmFile[i]->LoggerName = NULL;
  419. }
  420. if (EvmFile[i]->LogFileName != NULL)
  421. {
  422. free(EvmFile[i]->LogFileName);
  423. EvmFile[i]->LogFileName = NULL;
  424. }
  425. free(EvmFile[i]);
  426. }
  427. GlobalFree(cmdargv);
  428. Status = GetLastError();
  429. if(Status != ERROR_SUCCESS ){
  430. _tprintf(_T("Exit Status: %d\n"), Status );
  431. }
  432. return 0;
  433. }
  434. void DisplayVersionInfo()
  435. {
  436. TCHAR buffer[512];
  437. TCHAR strProgram[MAXSTR];
  438. DWORD dw;
  439. BYTE* pVersionInfo;
  440. LPTSTR pVersion = NULL;
  441. LPTSTR pProduct = NULL;
  442. LPTSTR pCopyRight = NULL;
  443. dw = GetModuleFileName(NULL, strProgram, MAXSTR);
  444. if( dw>0 ){
  445. dw = GetFileVersionInfoSize( strProgram, &dw );
  446. if( dw > 0 ){
  447. pVersionInfo = (BYTE*)malloc(dw);
  448. if( NULL != pVersionInfo ){
  449. if(GetFileVersionInfo( strProgram, 0, dw, pVersionInfo )){
  450. LPDWORD lptr = NULL;
  451. VerQueryValue( pVersionInfo, _T("\\VarFileInfo\\Translation"), (void**)&lptr, (UINT*)&dw );
  452. if( lptr != NULL ){
  453. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("ProductVersion") );
  454. VerQueryValue( pVersionInfo, buffer, (void**)&pVersion, (UINT*)&dw );
  455. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("OriginalFilename") );
  456. VerQueryValue( pVersionInfo, buffer, (void**)&pProduct, (UINT*)&dw );
  457. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("LegalCopyright") );
  458. VerQueryValue( pVersionInfo, buffer, (void**)&pCopyRight, (UINT*)&dw );
  459. }
  460. if( pProduct != NULL && pVersion != NULL && pCopyRight != NULL ){
  461. _tprintf( _T("\nMicrosoft (R) %s (%s)\n%s\n\n"), pProduct, pVersion, pCopyRight );
  462. }
  463. }
  464. free( pVersionInfo );
  465. }
  466. }
  467. }
  468. }
  469. ULONG
  470. BufferCallback(
  471. PEVENT_TRACE_LOGFILE pLog
  472. )
  473. {
  474. ULONG i;
  475. ULONG Status;
  476. EVENT_TRACE_PROPERTIES LoggerProp;
  477. TotalBuffersRead++;
  478. TotalEventsLost += pLog->EventsLost;
  479. if (fVerbose) {
  480. FILETIME stdTime, localTime;
  481. SYSTEMTIME sysTime;
  482. RtlCopyMemory(&stdTime , &pLog->CurrentTime, sizeof(FILETIME));
  483. FileTimeToSystemTime(&stdTime, &sysTime);
  484. _tprintf(_T("%02d/%02d/%04d-%02d:%02d:%02d.%03d :: %8d: Filled=%8d, Lost=%3d"),
  485. sysTime.wMonth,
  486. sysTime.wDay,
  487. sysTime.wYear,
  488. sysTime.wHour,
  489. sysTime.wMinute,
  490. sysTime.wSecond,
  491. sysTime.wMilliseconds,
  492. TotalBuffersRead,
  493. pLog->Filled,
  494. pLog->EventsLost);
  495. _tprintf(_T(" TotalLost= %d\r"), TotalEventsLost);
  496. if (CompareFileTime(&lastTime,&stdTime) == 1) {
  497. _tprintf(_T("\nWARNING: time appears to have wrapped here (Block = %d)!\n"),TotalBuffersRead);
  498. BufferWrap = TotalBuffersRead;
  499. }
  500. lastTime = stdTime ;
  501. }
  502. return (TRUE);
  503. }
  504. #define DEFAULT_LOG_BUFFER_SIZE 1024
  505. BOOL
  506. CheckFile(
  507. LPTSTR fileName
  508. )
  509. {
  510. HANDLE hFile;
  511. BYTE LogHeaderBuffer[DEFAULT_LOG_BUFFER_SIZE];
  512. ULONG nBytesRead ;
  513. ULONG hResult ;
  514. PEVENT_TRACE pEvent;
  515. PTRACE_LOGFILE_HEADER logfileHeader ;
  516. LARGE_INTEGER lFileSize ;
  517. LARGE_INTEGER lFileSizeMB ;
  518. DWORD dwDesiredAccess , dwShareMode ;
  519. FILETIME stdTime, localTime, endlocalTime, endTime;
  520. SYSTEMTIME sysTime, endsysTime;
  521. PEVENT_TRACE_LOGFILE pLogBuffer ;
  522. if (fFixUp) {
  523. dwShareMode = 0 ;
  524. dwDesiredAccess = GENERIC_READ | GENERIC_WRITE ;
  525. } else {
  526. dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ;
  527. dwDesiredAccess = GENERIC_READ ;
  528. }
  529. hFile = CreateFile(
  530. fileName,
  531. dwDesiredAccess,
  532. dwShareMode,
  533. NULL,
  534. OPEN_EXISTING,
  535. FILE_ATTRIBUTE_NORMAL,
  536. NULL
  537. );
  538. if (hFile == INVALID_HANDLE_VALUE) {
  539. if (fFixUp) {
  540. _tprintf(_T("ERROR: Fixup could not open file, Error = 0x%X\n"),GetLastError());
  541. exit(GetLastError());
  542. }
  543. return(FALSE);
  544. }
  545. // While we are here we will look to see if the file is ok and fix up
  546. // Circular buffer anomolies
  547. if (((hResult = ReadFile(hFile,
  548. (LPVOID)&LogHeaderBuffer,
  549. DEFAULT_LOG_BUFFER_SIZE,
  550. &nBytesRead,
  551. NULL)) == 0) || nBytesRead < DEFAULT_LOG_BUFFER_SIZE) {
  552. _tprintf(_T("ERROR: Fixup could not read file, Error = 0x%X, bytes read = %d(of %d)\n"),
  553. GetLastError(),nBytesRead,DEFAULT_LOG_BUFFER_SIZE);
  554. exit(ERROR_BAD_ARGUMENTS);
  555. }
  556. pEvent = (PEVENT_TRACE)&LogHeaderBuffer ;
  557. logfileHeader = (PTRACE_LOGFILE_HEADER)&LogHeaderBuffer[sizeof(WMI_BUFFER_HEADER) +
  558. sizeof(SYSTEM_TRACE_HEADER)];
  559. if (fVerbose) {
  560. _tprintf(_T("Dumping Logfile Header\n"));
  561. RtlCopyMemory(&stdTime , &(logfileHeader->StartTime), sizeof(FILETIME));
  562. FileTimeToLocalFileTime(&stdTime, &localTime);
  563. FileTimeToSystemTime(&localTime, &sysTime);
  564. RtlCopyMemory(&endTime , &(logfileHeader->EndTime), sizeof(FILETIME));
  565. FileTimeToLocalFileTime(&endTime, &endlocalTime);
  566. FileTimeToSystemTime(&endlocalTime, &endsysTime);
  567. _tprintf(_T("\tStart Time %02d/%02d/%04d-%02d:%02d:%02d.%03d\n"),
  568. sysTime.wMonth,
  569. sysTime.wDay,
  570. sysTime.wYear,
  571. sysTime.wHour,
  572. sysTime.wMinute,
  573. sysTime.wSecond,
  574. sysTime.wMilliseconds);
  575. _tprintf(_T("\tBufferSize %d\n"),
  576. logfileHeader->BufferSize);
  577. _tprintf(_T("\tVersion %d\n"),
  578. logfileHeader->Version);
  579. _tprintf(_T("\tProviderVersion %d\n"),
  580. logfileHeader->ProviderVersion);
  581. _tprintf(_T("\tEnd Time %02d/%02d/%04d-%02d:%02d:%02d.%03d\n"),
  582. endsysTime.wMonth,
  583. endsysTime.wDay,
  584. endsysTime.wYear,
  585. endsysTime.wHour,
  586. endsysTime.wMinute,
  587. endsysTime.wSecond,
  588. endsysTime.wMilliseconds);
  589. _tprintf(_T("\tTimer Resolution %d\n"),
  590. logfileHeader->TimerResolution);
  591. _tprintf(_T("\tMaximum File Size %d\n"),
  592. logfileHeader->MaximumFileSize);
  593. _tprintf(_T("\tBuffers Written %d\n"),
  594. logfileHeader->BuffersWritten);
  595. /*
  596. _tprintf(_T("\tLogger Name %ls\n"),
  597. logfileHeader->LoggerName);
  598. _tprintf(_T("\tLogfile Name %ls\n"),
  599. logfileHeader->LogFileName);
  600. */
  601. _tprintf(_T("\tTimezone is %s (Bias is %dmins)\n"),
  602. logfileHeader->TimeZone.StandardName,logfileHeader->TimeZone.Bias);
  603. _tprintf(_T("\tLogfile Mode %X "),
  604. logfileHeader->LogFileMode);
  605. if (logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_NONE) {
  606. _tprintf(_T("Logfile is off(?)\n"));
  607. } else if (logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  608. _tprintf(_T("Logfile is sequential\n"));
  609. } else if (logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_CIRCULAR) {
  610. _tprintf(_T("Logfile is circular\n"));
  611. }
  612. _tprintf(_T("\tProcessorCount %d\n"),
  613. logfileHeader->NumberOfProcessors);
  614. }
  615. if (GetFileSizeEx(hFile, &lFileSize) == 0) {
  616. _tprintf(_T("WARNING: Could not get file size, continuing\n"));
  617. } else {
  618. lFileSizeMB.QuadPart = lFileSize.QuadPart / (1024*1024) ;
  619. if (lFileSizeMB.QuadPart > logfileHeader->MaximumFileSize) {
  620. _tprintf(_T("WARNING: File size given as %dMB, should be %dMB\n"),
  621. logfileHeader->MaximumFileSize,lFileSizeMB.QuadPart);
  622. if (lFileSize.HighPart != 0) {
  623. _tprintf(_T("WARNING: Log file is TOO big"));
  624. }
  625. if (fFixUp) {
  626. logfileHeader->MaximumFileSize = lFileSizeMB.LowPart + 1 ;
  627. }
  628. }
  629. }
  630. if ((logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_CIRCULAR) &&
  631. (logfileHeader->BuffersWritten== 0 )) {
  632. _tprintf(_T("WARNING: Circular Trace File did not have 'wrap' address\n"));
  633. if (fFixUp) {
  634. // Figure out the wrap address
  635. INT LowBuff = 1, HighBuff, CurrentBuff, MaxBuff ;
  636. FILETIME LowTime, HighTime, CurrentTime, MaxTime ;
  637. if (lFileSize.HighPart != 0) {
  638. _tprintf(_T("ERROR: File TOO big\n"));
  639. exit(-1);
  640. }
  641. MaxBuff = (LONG)(lFileSize.QuadPart / logfileHeader->BufferSize) - 1 ;
  642. _tprintf(_T("MaxBuff=%d\n"),MaxBuff);
  643. pLogBuffer = malloc(logfileHeader->BufferSize);
  644. if (SetFilePointer(hFile,0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
  645. _tprintf(_T("ERROR: Could not reset file to beginning for FixUp, Error = 0x%X"),
  646. GetLastError());
  647. exit(GetLastError());
  648. }
  649. for (CurrentBuff = 1 ; CurrentBuff <= MaxBuff; CurrentBuff++) {
  650. if (SetFilePointer(hFile,logfileHeader->BufferSize, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) {
  651. _tprintf(_T("ERROR: Could not set file to next buffer for FixUp, Error = 0x%X"),
  652. GetLastError());
  653. exit(GetLastError());
  654. }
  655. hResult = ReadFile(hFile,
  656. (LPVOID)pLogBuffer,
  657. logfileHeader->BufferSize,
  658. &nBytesRead,
  659. NULL);
  660. BufferCallback((PEVENT_TRACE_LOGFILE)pLogBuffer);
  661. }
  662. }
  663. }
  664. if (fFixUp) {
  665. if (SetFilePointer(hFile,0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
  666. _tprintf(_T("ERROR: Could not reset file to beginning for FixUp, Error = 0x%X"),
  667. GetLastError());
  668. exit(GetLastError());
  669. }
  670. logfileHeader->BuffersWritten= BufferWrap ;
  671. if (!WriteFile(hFile,(LPVOID)LogHeaderBuffer,DEFAULT_LOG_BUFFER_SIZE,&nBytesRead, NULL)) {
  672. _tprintf(_T("ERROR: Could not Write file for FixUp, Error = 0x%X"),
  673. GetLastError());
  674. exit(GetLastError());
  675. }
  676. _tprintf(_T("INFO: Buffer Wrap reset to %d\n"),BufferWrap);
  677. }
  678. CloseHandle(hFile);
  679. return (TRUE);
  680. }
  681. #define SIZEEVENTBUF 8192
  682. TCHAR EventBuf[SIZEEVENTBUF];
  683. void
  684. DumpEvent(
  685. PEVENT_TRACE pEvent
  686. )
  687. {
  688. TotalEventCount++;
  689. if (pEvent == NULL) {
  690. _tprintf(_T("pEvent is NULL\n"));
  691. return;
  692. }
  693. // DumpEvent() is only a wrapper, it calls FormatTraceEvent() in TracePrt.
  694. //
  695. if (FormatTraceEvent(EventListHead,pEvent,EventBuf,SIZEEVENTBUF,NULL) > 0)
  696. {
  697. if (!fSummaryOnly && !fDisplayOnly) {
  698. _ftprintf(DumpFile, _T("%s\n"),EventBuf);
  699. }
  700. if (fDebugDisplay || fDisplayOnly) {
  701. if (fODSOutput) {
  702. OutputDebugString(EventBuf);
  703. OutputDebugString(_T("\n"));
  704. } else {
  705. _tprintf(_T("%s\n"),EventBuf);
  706. }
  707. }
  708. }
  709. }
  710. #ifdef __cplusplus
  711. }
  712. #endif