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.

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