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.

959 lines
36 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. tracelog.c
  5. Abstract:
  6. Sample trace control program. Allows user to start, stop event tracing
  7. Author:
  8. Jee Fung Pang (jeepang) 03-Dec-1997
  9. Revision History:
  10. --*/
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <windows.h>
  14. #include <tchar.h>
  15. #include <wmistr.h>
  16. #include <initguid.h>
  17. #include <guiddef.h>
  18. #include <evntrace.h>
  19. #define MAXSTR 1024
  20. #define DEFAULT_LOGFILE_NAME _T("C:\\LogFile.Evm")
  21. #define NT_LOGGER _T("NT Kernel Logger")
  22. #define MAXIMUM_LOGGERS 16
  23. #define MAXGUIDS 128
  24. #define ACTION_QUERY 0
  25. #define ACTION_START 1
  26. #define ACTION_STOP 2
  27. #define ACTION_UPDATE 3
  28. #define ACTION_LIST 4
  29. #define ACTION_ENABLE 5
  30. #define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
  31. void
  32. SplitCommandLine(
  33. LPTSTR CommandLine,
  34. LPTSTR* pArgv
  35. );
  36. void
  37. PrintLoggerStatus(
  38. IN PEVENT_TRACE_PROPERTIES LoggerInfo,
  39. IN ULONG Status
  40. );
  41. LPTSTR
  42. DecodeStatus(
  43. IN ULONG Status
  44. );
  45. ULONG
  46. GetGuids(LPTSTR GuidFile, LPGUID *GuidArray);
  47. void StringToGuid(TCHAR *str, LPGUID guid);
  48. ULONG ahextoi(TCHAR *s);
  49. TCHAR ErrorMsg[MAXSTR];
  50. FILE *fp;
  51. int __cdecl _tmain(int argc, _TCHAR ** argv)
  52. {
  53. ULONG GuidCount, i, j;
  54. USHORT Action = 0;
  55. ULONG Status = 0;
  56. LPTSTR LoggerName;
  57. LPTSTR LogFileName;
  58. TCHAR GuidFile[MAXSTR];
  59. PEVENT_TRACE_PROPERTIES pLoggerInfo;
  60. TRACEHANDLE LoggerHandle = 0;
  61. LPTSTR *commandLine;
  62. LPTSTR *targv;
  63. int targc;
  64. LPGUID *GuidArray;
  65. char *Space;
  66. char *save;
  67. BOOL bKill = FALSE;
  68. BOOL bEnable = TRUE;
  69. ULONG iLevel = 0;
  70. ULONG iFlags = 0;
  71. ULONG SizeNeeded = 0;
  72. // Very important!!!
  73. // Initialize structure first
  74. //
  75. SizeNeeded = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAXSTR * sizeof(TCHAR);
  76. pLoggerInfo = (PEVENT_TRACE_PROPERTIES) malloc(SizeNeeded);
  77. if (pLoggerInfo == NULL) {
  78. exit(ERROR_OUTOFMEMORY);
  79. }
  80. fp = _tfopen(_T("evntrace.log"), _T("a+"));
  81. if (fp == NULL) {
  82. _tprintf(_T("evntrace.log file open failed. quit!\n"));
  83. return (1);
  84. }
  85. _ftprintf(fp, _T("\n----------Start evntrace.exe--------\n\n"));
  86. _tprintf(_T("\n----------Start evntrace.exe--------\n\n"));
  87. #ifdef DEBUG
  88. for(i=0; i<(ULONG)argc; i++) {
  89. _tprintf(_T("argv[%d]=%s\n"), i, argv[i]);
  90. _ftprintf(fp, _T("argv[%d]=%s\n"), i, argv[i]);
  91. }
  92. _tprintf(_T("\n"));
  93. _ftprintf(fp, _T("\n"));
  94. #endif
  95. RtlZeroMemory(pLoggerInfo, SizeNeeded);
  96. pLoggerInfo->Wnode.BufferSize = SizeNeeded;
  97. pLoggerInfo->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  98. pLoggerInfo->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  99. pLoggerInfo->LogFileNameOffset = pLoggerInfo->LoggerNameOffset
  100. + MAXSTR * sizeof(TCHAR);
  101. LoggerName = (LPTSTR)((char*)pLoggerInfo + pLoggerInfo->LoggerNameOffset);
  102. LogFileName = (LPTSTR)((char*)pLoggerInfo + pLoggerInfo->LogFileNameOffset);
  103. _tcscpy(LoggerName, NT_LOGGER);
  104. Space = (char*) malloc( (MAXGUIDS * sizeof(GuidArray)) +
  105. (MAXGUIDS * sizeof(GUID) ));
  106. if (Space == NULL) {
  107. free(pLoggerInfo);
  108. exit(ERROR_OUTOFMEMORY);
  109. }
  110. save = Space;
  111. GuidArray = (LPGUID *) Space;
  112. Space += MAXGUIDS * sizeof(GuidArray);
  113. for (GuidCount=0; GuidCount<MAXGUIDS; GuidCount++) {
  114. GuidArray[GuidCount] = (LPGUID) Space;
  115. Space += sizeof(GUID);
  116. }
  117. GuidCount = 0;
  118. targc = argc;
  119. commandLine = (LPTSTR*)malloc( argc * sizeof(LPTSTR) );
  120. if (commandLine == NULL) {
  121. free(Space);
  122. free(pLoggerInfo);
  123. exit(ERROR_OUTOFMEMORY);
  124. }
  125. for(i=0;i<(ULONG)argc;i++){
  126. commandLine[i] = (LPTSTR)malloc(MAXSTR * sizeof(TCHAR));
  127. if (commandLine[i] == NULL) {
  128. for (j=0; j < i; j++)
  129. free(commandLine[j]);
  130. free(commandLine);
  131. free(pLoggerInfo);
  132. free(Space);
  133. }
  134. }
  135. SplitCommandLine( GetCommandLine(), commandLine );
  136. targv = commandLine;
  137. //
  138. // Add default flags. Should consider options to control this independently
  139. //
  140. while (--argc > 0) {
  141. ++targv;
  142. if (**targv == '-' || **targv == '/') { // argument found
  143. if(targv[0][0] == '/' ) targv[0][0] = '-';
  144. if (!_tcsicmp(targv[0], _T("-start"))) {
  145. Action = ACTION_START;
  146. if (argc > 1) {
  147. if (targv[1][0] != '-' && targv[1][0] != '/') {
  148. ++targv; --argc;
  149. _tcscpy(LoggerName, targv[0]);
  150. }
  151. }
  152. }
  153. else if (!_tcsicmp(targv[0], _T("-enable"))) {
  154. Action = ACTION_ENABLE;
  155. if (argc > 1) {
  156. if (targv[1][0] != '-' && targv[1][0] != '/') {
  157. ++targv; --argc;
  158. _tcscpy(LoggerName, targv[0]);
  159. }
  160. }
  161. }
  162. else if (!_tcsicmp(targv[0], _T("-disable"))) {
  163. Action = ACTION_ENABLE;
  164. bEnable = FALSE;
  165. if (argc > 1) {
  166. if (targv[1][0] != '-' && targv[1][0] != '/') {
  167. ++targv; --argc;
  168. _tcscpy(LoggerName, targv[0]);
  169. }
  170. }
  171. }
  172. else if (!_tcsicmp(targv[0], _T("-stop"))) {
  173. Action = ACTION_STOP;
  174. if (argc > 1) {
  175. if (targv[1][0] != '-' && targv[1][0] != '/') {
  176. ++targv; --argc;
  177. _tcscpy(LoggerName, targv[0]);
  178. }
  179. }
  180. }
  181. else if (!_tcsicmp(targv[0], _T("-update"))) {
  182. Action = ACTION_UPDATE;
  183. if (argc > 1) {
  184. if (targv[1][0] != '-' && targv[1][0] != '/') {
  185. ++targv; --argc;
  186. _tcscpy(LoggerName, targv[0]);
  187. }
  188. }
  189. }
  190. else if (!_tcsicmp(targv[0], _T("-q"))) {
  191. Action = ACTION_QUERY;
  192. if (argc > 1) {
  193. if (targv[1][0] != '-' && targv[1][0] != '/') {
  194. ++targv; --argc;
  195. _tcscpy(LoggerName, targv[0]);
  196. }
  197. }
  198. }
  199. else if (!_tcsicmp(targv[0], _T("-f"))) {
  200. if (argc > 1) {
  201. _tfullpath(LogFileName, targv[1], MAXSTR);
  202. ++targv; --argc;
  203. _ftprintf(fp, _T("Setting log file to: '%s'\n"),
  204. LogFileName);
  205. _tprintf(_T("Setting log file to: %s\n"), LogFileName);
  206. }
  207. }
  208. else if (!_tcsicmp(targv[0], _T("-guid"))) {
  209. if (argc > 1) {
  210. if (targv[1][0] != '-' && targv[1][0] != '/') {
  211. StringToGuid(targv[1], GuidArray[0]);
  212. ++targv; --argc;
  213. GuidCount=1;
  214. }
  215. }
  216. }
  217. else if (!_tcsicmp(targv[0], _T("-seq"))) {
  218. if (argc > 1) {
  219. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_SEQUENTIAL;
  220. pLoggerInfo->MaximumFileSize = _ttoi(targv[1]);
  221. ++targv; --argc;
  222. _ftprintf(fp, _T("Setting maximum sequential logfile size to: %d Mbytes\n"), pLoggerInfo->MaximumFileSize);
  223. _tprintf(_T("Setting maximum sequential logfile size to: %d\n"),
  224. pLoggerInfo->MaximumFileSize);
  225. }
  226. }
  227. else if (!_tcsicmp(targv[0], _T("-cir"))) {
  228. if (argc > 1) {
  229. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_CIRCULAR;
  230. pLoggerInfo->MaximumFileSize = _ttoi(targv[1]);
  231. ++targv; --argc;
  232. _ftprintf(fp, _T("Setting maximum circular logfile size to: %d Mbytes\n"), pLoggerInfo->MaximumFileSize);
  233. _tprintf(_T("Setting maximum circular logfile size to: %d\n"),
  234. pLoggerInfo->MaximumFileSize);
  235. }
  236. }
  237. else if (!_tcsicmp(targv[0], _T("-b"))) {
  238. if (argc > 1) {
  239. pLoggerInfo->BufferSize = _ttoi(targv[1]);
  240. ++targv; --argc;
  241. _ftprintf(fp, _T("Changing buffer size to %d\n"), pLoggerInfo->BufferSize);
  242. _tprintf(_T("Changing buffer size to %d\n"),
  243. pLoggerInfo->BufferSize);
  244. }
  245. }
  246. else if (!_tcsicmp(targv[0], _T("-flag"))) {
  247. if (argc > 1) {
  248. pLoggerInfo->EnableFlags |= _ttoi(targv[1]);
  249. ++targv; --argc;
  250. _tprintf(_T("Setting logger flags to %d\n"),
  251. pLoggerInfo->EnableFlags );
  252. }
  253. }
  254. else if (!_tcsicmp(targv[0], _T("-min"))) {
  255. if (argc > 1) {
  256. pLoggerInfo->MinimumBuffers = _ttoi(targv[1]);
  257. ++targv; --argc;
  258. _ftprintf(fp, _T("Changing Minimum Number of Buffers to %d\n "), pLoggerInfo->MinimumBuffers);
  259. _tprintf(_T("Changing Minimum Number of Buffers to %d\n"),
  260. pLoggerInfo->MinimumBuffers);
  261. }
  262. }
  263. else if (!_tcsicmp(targv[0], _T("-max"))) {
  264. if (argc > 1) {
  265. pLoggerInfo->MaximumBuffers = _ttoi(targv[1]);
  266. ++targv; --argc;
  267. _ftprintf(fp, _T("Changing Maximum Number of Buffers to %d\n "),pLoggerInfo->MaximumBuffers);
  268. _tprintf(_T("Changing Maximum Number of Buffers to %d\n"),
  269. pLoggerInfo->MaximumBuffers);
  270. }
  271. }
  272. else if (!_tcsicmp(targv[0], _T("-level"))) {
  273. if (argc > 1) {
  274. iLevel = _ttoi(targv[1]);
  275. ++targv; --argc;
  276. _tprintf(_T("Setting tracing level to %d\n"), iLevel);
  277. }
  278. }
  279. else if (!_tcsicmp(targv[0], _T("-flags"))) {
  280. if (argc > 1) {
  281. iFlags = _ttoi(targv[1]);
  282. ++targv; --argc;
  283. _tprintf(_T("Setting command to %d\n"), iFlags);
  284. }
  285. }
  286. else if (!_tcsicmp(targv[0], _T("-ft"))) {
  287. if (argc > 1) {
  288. pLoggerInfo->FlushTimer = _ttoi(targv[1]);
  289. ++targv; --argc;
  290. _tprintf(_T("Setting buffer flush timer to %d seconds\n"),
  291. pLoggerInfo->FlushTimer);
  292. }
  293. }
  294. else if (!_tcsicmp(targv[0], _T("-um"))) {
  295. pLoggerInfo->LogFileMode |= EVENT_TRACE_PRIVATE_LOGGER_MODE;
  296. _ftprintf(fp, _T("Setting Private Logger Flags\n"));
  297. _tprintf(_T("Setting Private Logger Flags\n"));
  298. }
  299. else if (!_tcsicmp(targv[0], _T("-rt"))) {
  300. pLoggerInfo->LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
  301. _ftprintf(fp, _T("Setting real time mode\n"));
  302. _tprintf(_T("Setting real time mode\n"));
  303. if (argc > 1) {
  304. if (targv[1][0] != '-' && targv[1][0] != '/') {
  305. ++targv; --argc;
  306. if (targv[1][0] == 'b')
  307. pLoggerInfo->LogFileMode |= EVENT_TRACE_BUFFERING_MODE;
  308. }
  309. }
  310. }
  311. else if (!_tcsicmp(targv[0], _T("-age"))) {
  312. if (argc > 1) {
  313. pLoggerInfo->AgeLimit = _ttoi(targv[1]);
  314. ++targv; --argc;
  315. _tprintf(_T("Changing Aging Decay Time to %d\n"),
  316. pLoggerInfo->AgeLimit);
  317. }
  318. }
  319. else if (!_tcsicmp(targv[0], _T("-l"))) {
  320. Action = ACTION_LIST;
  321. }
  322. else if (!_tcsicmp(targv[0], _T("-x"))) {
  323. Action = ACTION_LIST;
  324. bKill = TRUE;
  325. }
  326. else if (!_tcsicmp(targv[0], _T("-fio"))) {
  327. pLoggerInfo->EnableFlags |= EVENT_TRACE_FLAG_DISK_FILE_IO;
  328. }
  329. else if (!_tcsicmp(targv[0], _T("-pf"))) {
  330. pLoggerInfo->EnableFlags |= EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS;
  331. }
  332. else if (!_tcsicmp(targv[0], _T("-hf"))) {
  333. pLoggerInfo->EnableFlags |= EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS;
  334. }
  335. else if (!_tcsicmp(targv[0], _T("-img"))) {
  336. pLoggerInfo->EnableFlags |= EVENT_TRACE_FLAG_IMAGE_LOAD;
  337. }
  338. else if ( targv[0][1] == 'h' || targv[0][1] == 'H' || targv[0][1] == '?'){
  339. _tprintf(
  340. _T("Usage: tracelog [options] | [-h | -help | -?]\n")
  341. _T("\t-start Starts up a trace session\n")
  342. _T("\t-stop Stops a trace session\n")
  343. _T("\t-update Updates a trace session\n")
  344. _T("\t-b <n> Sets buffer size to <n> Kbytes\n")
  345. _T("\t-min <n> Sets minimum buffers\n")
  346. _T("\t-max <n> Sets maximum buffers\n")
  347. _T("\t-x Stops all active trace sessions\n")
  348. _T("\t-q Queries the status of trace session\n")
  349. _T("\t-f name Log to file <name>\n")
  350. _T("\t-seq [n] Sequential logfile of up to n Mbytes\n")
  351. _T("\t-cir n Circular logfile of n Mbytes\n")
  352. _T("\t-nf n Sequentially to new file every n Mb\n")
  353. _T("\t-ft n Set flush timer to n seconds\n")
  354. _T("\t-fio Enable file I/O tracing\n")
  355. _T("\t-pf Enable page faults tracing\n")
  356. _T("\t-hf Enable hard faults tracing\n")
  357. _T("\t-img Enable image load tracing\n")
  358. _T("\t-um Enable Process Private tracing\n")
  359. _T("\t-guid <file> Start tracing for providers in file\n")
  360. _T("\t-rt [b] Enable tracing in real time mode\n")
  361. _T("\t-age n Modify aging decay time\n")
  362. _T("\t-level n\n")
  363. _T("\t-flags n\n")
  364. _T("\t-h\n")
  365. _T("\t-help\n")
  366. _T("\t-? Prints this information\n")
  367. _T("NOTE: The default with no options is -q\n")
  368. );
  369. return 0;
  370. }
  371. else Action = 0;
  372. }
  373. else { // get here if "-" or "/" given
  374. _tprintf(_T("Invalid option given: %s\n"), targv[0]);
  375. return 0;
  376. }
  377. }
  378. if (!_tcscmp(LoggerName, NT_LOGGER)) {
  379. pLoggerInfo->EnableFlags |= (EVENT_TRACE_FLAG_PROCESS |
  380. EVENT_TRACE_FLAG_THREAD |
  381. EVENT_TRACE_FLAG_DISK_IO |
  382. EVENT_TRACE_FLAG_NETWORK_TCPIP);
  383. pLoggerInfo->Wnode.Guid = SystemTraceControlGuid; // default to OS tracing
  384. }
  385. if ( !(pLoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) ) {
  386. if ( _tcslen(LogFileName) <= 0 &&
  387. ((Action == ACTION_START) || (Action == ACTION_UPDATE))) {
  388. _tcscpy(LogFileName, DEFAULT_LOGFILE_NAME); // for now...
  389. }
  390. }
  391. switch (Action) {
  392. case ACTION_START:
  393. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  394. if (GuidCount != 1) {
  395. _ftprintf(fp, _T("Need exactly one GUID for PRIVATE loggers\n"));
  396. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  397. return 0;
  398. }
  399. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  400. }
  401. Status = StartTrace(&LoggerHandle, LoggerName, pLoggerInfo);
  402. if (Status != ERROR_SUCCESS) {
  403. _ftprintf(fp, _T("Could not start logger: %s\nOperation Status = %uL, %s"), LoggerName, Status, DecodeStatus(Status));
  404. _tprintf(_T("Could not start logger: %s\n")
  405. _T("Operation Status: %uL\n")
  406. _T("%s\n"),
  407. LoggerName,
  408. Status,
  409. DecodeStatus(Status));
  410. return Status;
  411. }
  412. _ftprintf(fp, _T("Logger %s Started...\n"), LoggerName);
  413. _tprintf(_T("Logger Started...\n"));
  414. case ACTION_ENABLE:
  415. if (Action == ACTION_ENABLE) {
  416. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE)
  417. {
  418. if (GuidCount != 1) {
  419. _ftprintf(fp, _T("Need exactly one GUID for PRIVATE loggers\n"));
  420. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  421. return 0;
  422. }
  423. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  424. }
  425. Status = QueryTrace( (TRACEHANDLE)0, LoggerName, pLoggerInfo );
  426. if (Status != ERROR_SUCCESS) {
  427. _ftprintf(fp,
  428. _T("ERROR: Logger %s not started\nOperation Status= %d, %s"),
  429. LoggerName,
  430. Status,
  431. DecodeStatus(Status));
  432. _tprintf( _T("ERROR: Logger not started\n")
  433. _T("Operation Status: %uL\n")
  434. _T("%s\n"),
  435. Status,
  436. DecodeStatus(Status));
  437. exit(0);
  438. }
  439. LoggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  440. }
  441. if ((GuidCount > 0) &&
  442. (!IsEqualGUID(&pLoggerInfo->Wnode.Guid, &SystemTraceControlGuid)))
  443. {
  444. _ftprintf(fp, _T("Enabling trace to logger %d\n"), LoggerHandle);
  445. _tprintf(_T("Enabling trace to logger %d\n"), LoggerHandle);
  446. for (i = 0; i < GuidCount; i ++) {
  447. Status = EnableTrace (
  448. bEnable,
  449. iFlags,
  450. iLevel,
  451. GuidArray[i],
  452. LoggerHandle);
  453. if (Status != ERROR_SUCCESS && Status != 4317) {
  454. _ftprintf(fp, _T("ERROR: Failed to enable Guid [%d]...\n Operation Status= %d, %s"), i, Status, DecodeStatus(Status));
  455. _tprintf(_T("ERROR: Failed to enable Guid [%d]...\n"), i);
  456. _tprintf(_T("Operation Status: %uL\n"), Status);
  457. _tprintf(_T("%s\n"),DecodeStatus(Status));
  458. return Status;
  459. }
  460. }
  461. }
  462. else {
  463. if (GuidCount > 0)
  464. _ftprintf(fp, _T("ERROR: System Logger does not accept application guids...GuidCount=%d\n"), GuidCount);
  465. _tprintf(_T("ERROR: System Logger does not accept application guids...\n"));
  466. }
  467. break;
  468. case ACTION_STOP :
  469. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  470. if (GuidCount != 1) {
  471. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  472. return 0;
  473. }
  474. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  475. }
  476. if (!IsEqualGUID(&pLoggerInfo->Wnode.Guid, &SystemTraceControlGuid)) {
  477. if ((pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE)) {
  478. Status = QueryTrace(
  479. (TRACEHANDLE) 0, LoggerName, pLoggerInfo);
  480. LoggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  481. Status = EnableTrace( FALSE,
  482. EVENT_TRACE_PRIVATE_LOGGER_MODE,
  483. 0,
  484. GuidArray[0],
  485. LoggerHandle );
  486. }
  487. else {
  488. Status = QueryTrace( (TRACEHANDLE)0, LoggerName, pLoggerInfo );
  489. LoggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  490. for (i=0; i<GuidCount; i++) {
  491. Status = EnableTrace( FALSE,
  492. 0,
  493. 0,
  494. GuidArray[i],
  495. LoggerHandle);
  496. }
  497. }
  498. }
  499. Status = StopTrace((TRACEHANDLE)0, LoggerName, pLoggerInfo);
  500. break;
  501. case ACTION_UPDATE :
  502. case ACTION_QUERY:
  503. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  504. if (GuidCount != 1) {
  505. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  506. return 0;
  507. }
  508. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  509. }
  510. if (Action == ACTION_UPDATE)
  511. Status = UpdateTrace(LoggerHandle, LoggerName, pLoggerInfo);
  512. else
  513. Status = QueryTrace(LoggerHandle, LoggerName, pLoggerInfo);
  514. break;
  515. case ACTION_LIST :
  516. {
  517. ULONG i, returnCount ;
  518. ULONG SizeNeeded;
  519. PEVENT_TRACE_PROPERTIES pLoggerInfo[MAXIMUM_LOGGERS];
  520. PEVENT_TRACE_PROPERTIES pStorage;
  521. PVOID Storage;
  522. SizeNeeded = MAXIMUM_LOGGERS * (sizeof(EVENT_TRACE_PROPERTIES)
  523. + 2 * MAXSTR * sizeof(TCHAR));
  524. Storage = malloc(SizeNeeded);
  525. if (Storage == NULL)
  526. return ERROR_OUTOFMEMORY;
  527. RtlZeroMemory(Storage, SizeNeeded);
  528. pStorage = (PEVENT_TRACE_PROPERTIES)Storage;
  529. for (i=0; i<MAXIMUM_LOGGERS; i++) {
  530. pStorage->Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES)
  531. + 2 * MAXSTR * sizeof(TCHAR);
  532. pStorage->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES)
  533. + MAXSTR * sizeof(TCHAR);
  534. pStorage->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  535. pLoggerInfo[i] = pStorage;
  536. pStorage = (PEVENT_TRACE_PROPERTIES) (
  537. (char*)pStorage +
  538. pStorage->Wnode.BufferSize);
  539. }
  540. Status = QueryAllTraces(pLoggerInfo,
  541. MAXIMUM_LOGGERS,
  542. & returnCount);
  543. if (Status == ERROR_SUCCESS)
  544. {
  545. for (j= 0; j < returnCount; j++)
  546. {
  547. if (bKill)
  548. {
  549. LPTSTR LoggerName;
  550. LoggerName = (LPTSTR) ((char*)pLoggerInfo[j] +
  551. pLoggerInfo[j]->LoggerNameOffset);
  552. if (!IsEqualGUID(& pLoggerInfo[j]->Wnode.Guid,
  553. & SystemTraceControlGuid))
  554. {
  555. LoggerHandle = pLoggerInfo[j]->Wnode.HistoricalContext;
  556. Status = EnableTrace(
  557. FALSE,
  558. (pLoggerInfo[j]->LogFileMode &
  559. EVENT_TRACE_PRIVATE_LOGGER_MODE)
  560. ? (EVENT_TRACE_PRIVATE_LOGGER_MODE)
  561. : (0),
  562. 0,
  563. & pLoggerInfo[j]->Wnode.Guid,
  564. LoggerHandle);
  565. }
  566. Status = StopTrace((TRACEHANDLE) 0,
  567. LoggerName,
  568. pLoggerInfo[j]);
  569. }
  570. PrintLoggerStatus(pLoggerInfo[j], Status);
  571. }
  572. }
  573. else
  574. printf("Error: Query failed with Status %d\n", Status);
  575. i = 0;
  576. free(Storage);
  577. return 0;
  578. }
  579. default :
  580. Status = QueryTrace(LoggerHandle, LoggerName, pLoggerInfo);
  581. break;
  582. }
  583. PrintLoggerStatus(pLoggerInfo, Status);
  584. for(i=0;i<(ULONG)targc;i++){
  585. free(commandLine[i]);
  586. }
  587. free(commandLine);
  588. free(pLoggerInfo);
  589. free(save);
  590. _ftprintf(fp, _T("\nEnd evntrace.exe, status = %d, %s\n"), Status, DecodeStatus(Status));
  591. fclose(fp);
  592. exit(Status);
  593. }
  594. void
  595. SplitCommandLine( LPTSTR CommandLine, LPTSTR* pArgv )
  596. {
  597. LPTSTR arg;
  598. int i = 0;
  599. arg = _tcstok( CommandLine, _T(" \t"));
  600. while( arg != NULL ){
  601. _tcscpy(pArgv[i++], arg);
  602. arg = _tcstok(NULL, _T(" \t"));
  603. }
  604. }
  605. void
  606. PrintLoggerStatus(
  607. IN PEVENT_TRACE_PROPERTIES LoggerInfo,
  608. IN ULONG Status
  609. )
  610. {
  611. LPTSTR LoggerName, LogFileName;
  612. if ((LoggerInfo->LoggerNameOffset > 0) &&
  613. (LoggerInfo->LoggerNameOffset < LoggerInfo->Wnode.BufferSize)) {
  614. LoggerName = (LPTSTR) ((char*)LoggerInfo +
  615. LoggerInfo->LoggerNameOffset);
  616. }
  617. else LoggerName = NULL;
  618. if ((LoggerInfo->LogFileNameOffset > 0) &&
  619. (LoggerInfo->LogFileNameOffset < LoggerInfo->Wnode.BufferSize)) {
  620. LogFileName = (LPTSTR) ((char*)LoggerInfo +
  621. LoggerInfo->LogFileNameOffset);
  622. }
  623. else LogFileName = NULL;
  624. //write to log file
  625. _ftprintf(fp, _T("Operation Status: %uL, %s"), Status, DecodeStatus(Status));
  626. _ftprintf(fp, _T("Logger Name: %s\n"),
  627. (LoggerName == NULL) ?
  628. _T(" ") : LoggerName);
  629. _ftprintf(fp, _T("Logger Id: %d\n"), LoggerInfo->Wnode.Linkage);
  630. _ftprintf(fp, _T("Logger Thread Id: %d\n"), LoggerInfo->Wnode.ProviderId);
  631. if (Status != 0)
  632. {
  633. _ftprintf(fp, _T("Logger status error: check messages above\n"));
  634. return;
  635. }
  636. _ftprintf(fp, _T("Buffer Size: %d Kb\n"), LoggerInfo->BufferSize);
  637. _ftprintf(fp, _T("Maximum Buffers: %d\n"), LoggerInfo->MaximumBuffers);
  638. _ftprintf(fp, _T("Minimum Buffers: %d\n"), LoggerInfo->MinimumBuffers);
  639. _ftprintf(fp, _T("Number of Buffers: %d\n"), LoggerInfo->NumberOfBuffers);
  640. _ftprintf(fp, _T("Free Buffers: %d\n"), LoggerInfo->FreeBuffers);
  641. _ftprintf(fp, _T("Buffers Written: %d\n"), LoggerInfo->BuffersWritten );
  642. _ftprintf(fp, _T("Events Lost: %d\n"), LoggerInfo->EventsLost);
  643. _ftprintf(fp, _T("Log Buffers Lost: %d\n"), LoggerInfo->LogBuffersLost );
  644. _ftprintf(fp, _T("Real Time Buffers Lost: %d\n"), LoggerInfo->RealTimeBuffersLost);
  645. if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
  646. _ftprintf(fp, _T("Log File Mode: Circular\n"));
  647. }
  648. else if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  649. _ftprintf(fp, _T("Log File Mode: Sequential\n"));
  650. }
  651. else {
  652. _ftprintf(fp, _T("Log File Mode: \n"));
  653. }
  654. if (LoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) {
  655. _ftprintf(fp, _T("Real Time mode enabled\n"));
  656. }
  657. if (LoggerInfo->MaximumFileSize > 0)
  658. _ftprintf(fp, _T("Maximum File Size: %d Mb\n"), LoggerInfo->MaximumFileSize);
  659. if (LoggerInfo->FlushTimer > 0)
  660. _ftprintf(fp, _T("Buffer Flush Timer: %d secs\n"), LoggerInfo->FlushTimer);
  661. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
  662. _ftprintf(fp, _T("Enabled tracing: Process\n"));
  663. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
  664. _ftprintf(fp, _T("Enabled tracing: Thread\n"));
  665. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
  666. _ftprintf(fp, _T("Enabled tracing: ImageLoad\n"));
  667. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
  668. _ftprintf(fp, _T("Enabled tracing: Disk\n"));
  669. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
  670. _ftprintf(fp, _T("Enabled tracing: File\n"));
  671. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
  672. _ftprintf(fp, _T("Enabled tracing: SoftFaults\n"));
  673. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
  674. _ftprintf(fp, _T("Enabled tracing: HardFaults\n"));
  675. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
  676. _ftprintf(fp, _T("Enabled tracing: TcpIp\n"));
  677. _ftprintf(fp, _T("EnableFlags: 0x%08x\n"), LoggerInfo->EnableFlags);
  678. _ftprintf(fp, _T("Log Filename: %s\n"),
  679. (LogFileName == NULL) ?
  680. _T(" ") : LogFileName);
  681. _tprintf(_T("Operation Status: %uL\n"), Status);
  682. _tprintf(_T("%s\n"), DecodeStatus(Status));
  683. _tprintf(_T("Logger Name: %s\n"),
  684. (LoggerName == NULL) ?
  685. _T(" ") : LoggerName);
  686. _tprintf(_T("Logger Id: %I64x\n"), LoggerInfo->Wnode.HistoricalContext);
  687. _tprintf(_T("Logger Thread Id: %d\n"), HandleToUlong(LoggerInfo->LoggerThreadId));
  688. if (Status != 0)
  689. return;
  690. _tprintf(_T("Buffer Size: %d Kb\n"), LoggerInfo->BufferSize);
  691. _tprintf(_T("Maximum Buffers: %d\n"), LoggerInfo->MaximumBuffers);
  692. _tprintf(_T("Minimum Buffers: %d\n"), LoggerInfo->MinimumBuffers);
  693. _tprintf(_T("Number of Buffers: %d\n"), LoggerInfo->NumberOfBuffers);
  694. _tprintf(_T("Free Buffers: %d\n"), LoggerInfo->FreeBuffers);
  695. _tprintf(_T("Buffers Written: %d\n"), LoggerInfo->BuffersWritten);
  696. _tprintf(_T("Events Lost: %d\n"), LoggerInfo->EventsLost);
  697. _tprintf(_T("Log Buffers Lost: %d\n"), LoggerInfo->LogBuffersLost);
  698. _tprintf(_T("Real Time Buffers Lost: %d\n"), LoggerInfo->RealTimeBuffersLost);
  699. _tprintf(_T("Log File Mode: "));
  700. if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
  701. _tprintf(_T("Circular\n"));
  702. }
  703. else if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  704. _tprintf(_T("Sequential\n"));
  705. }
  706. else {
  707. _tprintf(_T("\n"));
  708. }
  709. if (LoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) {
  710. _tprintf(_T("Real Time mode enabled\n"));
  711. }
  712. if (LoggerInfo->MaximumFileSize > 0)
  713. _tprintf(_T("Maximum File Size: %d Mb\n"), LoggerInfo->MaximumFileSize);
  714. if (LoggerInfo->FlushTimer > 0)
  715. _tprintf(_T("Buffer Flush Timer: %d secs\n"), LoggerInfo->FlushTimer);
  716. if (LoggerInfo->EnableFlags != 0) {
  717. _tprintf(_T("Enabled tracing: "));
  718. if ((LoggerName != NULL) && (!_tcscmp(LoggerName,NT_LOGGER))) {
  719. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
  720. _tprintf(_T("Process "));
  721. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
  722. _tprintf(_T("Thread "));
  723. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
  724. _tprintf(_T("Disk "));
  725. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
  726. _tprintf(_T("File "));
  727. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
  728. _tprintf(_T("PageFaults "));
  729. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
  730. _tprintf(_T("HardFaults "));
  731. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
  732. _tprintf(_T("ImageLoad "));
  733. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
  734. _tprintf(_T("TcpIp "));
  735. }else{
  736. _tprintf(_T("0x%08x"), LoggerInfo->EnableFlags );
  737. }
  738. _tprintf(_T("\n"));
  739. }
  740. _tprintf(_T("Log Filename: %s\n"),
  741. (LogFileName == NULL) ?
  742. _T(" ") : LogFileName);
  743. }
  744. LPTSTR
  745. DecodeStatus(
  746. IN ULONG Status
  747. )
  748. {
  749. memset( ErrorMsg, 0, MAXSTR );
  750. FormatMessage(
  751. FORMAT_MESSAGE_FROM_SYSTEM |
  752. FORMAT_MESSAGE_IGNORE_INSERTS,
  753. NULL,
  754. Status,
  755. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  756. (LPTSTR) ErrorMsg,
  757. MAXSTR,
  758. NULL );
  759. return ErrorMsg;
  760. }
  761. ULONG
  762. GetGuids(LPTSTR GuidFile, LPGUID *GuidArray)
  763. {
  764. FILE *f;
  765. TCHAR line[MAXSTR], arg[MAXSTR];
  766. LPGUID Guid;
  767. int i, n;
  768. f = _tfopen((TCHAR*)GuidFile, _T("r"));
  769. if (f == NULL)
  770. return 0;
  771. n = 0;
  772. while ( _fgetts(line, MAXSTR, f) != NULL ) {
  773. if (_tcslen(line) < 36)
  774. continue;
  775. if (line[0] == ';' ||
  776. line[0] == '\0' ||
  777. line[0] == '#' ||
  778. line[0] == '/')
  779. continue;
  780. Guid = (LPGUID) GuidArray[n];
  781. n ++;
  782. _tcsncpy(arg, line, 8);
  783. arg[8] = 0;
  784. Guid->Data1 = ahextoi(arg);
  785. _tcsncpy(arg, &line[9], 4);
  786. arg[4] = 0;
  787. Guid->Data2 = (USHORT) ahextoi(arg);
  788. _tcsncpy(arg, &line[14], 4);
  789. arg[4] = 0;
  790. Guid->Data3 = (USHORT) ahextoi(arg);
  791. for (i=0; i<2; i++) {
  792. _tcsncpy(arg, &line[19 + (i*2)], 2);
  793. arg[2] = 0;
  794. Guid->Data4[i] = (UCHAR) ahextoi(arg);
  795. }
  796. for (i=2; i<8; i++) {
  797. _tcsncpy(arg, &line[20 + (i*2)], 2);
  798. arg[2] = 0;
  799. Guid->Data4[i] = (UCHAR) ahextoi(arg);
  800. }
  801. }
  802. return (ULONG)n;
  803. }
  804. ULONG ahextoi(TCHAR *s)
  805. {
  806. int len;
  807. ULONG num, base, hex;
  808. len = _tcslen(s);
  809. hex = 0; base = 1; num = 0;
  810. while (--len >= 0) {
  811. if ( (s[len] == 'x' || s[len] == 'X') &&
  812. (s[len-1] == '0') )
  813. break;
  814. if (s[len] >= '0' && s[len] <= '9')
  815. num = s[len] - '0';
  816. else if (s[len] >= 'a' && s[len] <= 'f')
  817. num = (s[len] - 'a') + 10;
  818. else if (s[len] >= 'A' && s[len] <= 'F')
  819. num = (s[len] - 'A') + 10;
  820. else
  821. continue;
  822. hex += num * base;
  823. base = base * 16;
  824. }
  825. return hex;
  826. }
  827. void StringToGuid(TCHAR *str, LPGUID guid)
  828. {
  829. TCHAR temp[10];
  830. int i, n;
  831. temp[8]=_T('\0');
  832. _tcsncpy(temp, str, 8);
  833. _stscanf(temp, _T("%x"), &(guid->Data1));
  834. temp[4]=_T('\0');
  835. _tcsncpy(temp, &str[9], 4);
  836. _stscanf(temp, _T("%x"), &(guid->Data2));
  837. _tcsncpy(temp, &str[14], 4);
  838. _stscanf(temp, _T("%x"), &(guid->Data3));
  839. temp[2]='\0';
  840. for(i=0;i<8;i++)
  841. {
  842. temp[0]=str[19+((i<2)?2*i:2*i+1)]; // to accomodate the minus sign after
  843. temp[1]=str[20+((i<2)?2*i:2*i+1)]; // the first two chars
  844. _stscanf(temp, _T("%x"), &n); // if directly used more than byte alloc
  845. guid->Data4[i]=(unsigned char)n; // causes overrun of memory
  846. }
  847. }