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.

1334 lines
45 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. tracelog.c
  5. Abstract:
  6. Sample trace control program. Allows user to start, update, query, stop
  7. event tracing, etc.
  8. --*/
  9. #ifndef UNICODE
  10. #define UNICODE
  11. #endif
  12. #ifndef _UNICODE
  13. #define _UNICODE
  14. #endif
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <windows.h>
  18. #include <shellapi.h>
  19. #include <tchar.h>
  20. #include <wmistr.h>
  21. #include <initguid.h>
  22. #include <guiddef.h>
  23. #include <evntrace.h>
  24. #define MAXSTR 1024
  25. #define DEFAULT_LOGFILE_NAME _T("C:\\LogFile.Etl")
  26. #define NT_LOGGER _T("NT Kernel Logger")
  27. #define MAXIMUM_LOGGERS 32
  28. #define MAXGUIDS 128
  29. #define ACTION_QUERY 0
  30. #define ACTION_START 1
  31. #define ACTION_STOP 2
  32. #define ACTION_UPDATE 3
  33. #define ACTION_LIST 4
  34. #define ACTION_ENABLE 5
  35. #define ACTION_HELP 6
  36. #define ACTION_FLUSH 7
  37. #define ACTION_ENUM_GUID 8
  38. #define ACTION_UNDEFINED 10
  39. #define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
  40. //
  41. // Functions not implemented on Win2K need to be searched and loaded separately.
  42. // To make further accesses easy, an array of function pointers will be used.
  43. // The following list serves as indices to that array.
  44. //
  45. #define FUNC_FLUSH_TRACE 0
  46. #define FUNC_ENUM_TRACE_GUIDS 1
  47. // Funtion pointer array for unimplemented functions on Win2K.
  48. // Note: This may not work if this code is ported to C++, because
  49. // all the function pointers may be typedefed differently.
  50. #define MAXFUNC 10
  51. FARPROC FuncArray[MAXFUNC];
  52. HINSTANCE advapidll;
  53. BOOLEAN XP;
  54. void
  55. PrintLoggerStatus(
  56. IN PEVENT_TRACE_PROPERTIES LoggerInfo,
  57. IN ULONG Status,
  58. IN BOOL PrintStatus
  59. );
  60. #define PRINTSTATUS TRUE
  61. #define NOPRINTSTATUS FALSE
  62. LPTSTR
  63. DecodeStatus(
  64. IN ULONG Status
  65. );
  66. LONG
  67. GetGuids(
  68. IN LPTSTR GuidFile,
  69. OUT LPGUID *GuidArray
  70. );
  71. ULONG
  72. ahextoi(
  73. IN TCHAR *s
  74. );
  75. void
  76. StringToGuid(
  77. IN TCHAR *str,
  78. OUT LPGUID guid
  79. );
  80. PTCHAR
  81. GuidToString(
  82. IN OUT PTCHAR s,
  83. IN LPGUID piid
  84. );
  85. TCHAR ErrorMsg[MAXSTR];
  86. void
  87. PrintHelpMessage();
  88. //
  89. // main function
  90. //
  91. __cdecl main(argc, argv)
  92. int argc;
  93. char **argv;
  94. /*++
  95. Routine Description:
  96. It is the main function.
  97. Arguments:
  98. Return Value:
  99. Error Code defined in winerror.h : If the function succeeds,
  100. it returns ERROR_SUCCESS (== 0).
  101. --*/{
  102. ULONG i, j;
  103. LONG GuidCount;
  104. USHORT Action = ACTION_UNDEFINED;
  105. ULONG Status = 0;
  106. LPTSTR LoggerName;
  107. LPTSTR LogFileName;
  108. TCHAR GuidFile[MAXSTR];
  109. PEVENT_TRACE_PROPERTIES pLoggerInfo;
  110. TRACEHANDLE LoggerHandle = 0;
  111. LPTSTR *targv, *utargv = NULL;
  112. LPGUID *GuidArray;
  113. char *Space;
  114. char *save;
  115. BOOL bKill = FALSE;
  116. BOOL bForceKill = FALSE ;
  117. BOOL bEnable = TRUE;
  118. ULONG iLevel = 0;
  119. ULONG iFlags = 0;
  120. ULONG SizeNeeded = 0;
  121. ULONG specialLogger = 0;
  122. ULONG GlobalLoggerStartValue = 0;
  123. PULONG pFlags = NULL;
  124. BOOL bProcess = TRUE;
  125. BOOL bThread = TRUE;
  126. BOOL bDisk = TRUE;
  127. BOOL bNetwork = TRUE;
  128. TCHAR tstrLogFileName[MAXSTR];
  129. OSVERSIONINFO OSVersion;
  130. OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  131. XP = FALSE;
  132. if (GetVersionEx(&OSVersion)) {
  133. XP = (OSVersion.dwMajorVersion > 5) ||
  134. ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion > 0));
  135. }
  136. // Load functions that are not implemented on Win2K
  137. for (i = 0; i < MAXFUNC; ++i)
  138. FuncArray[i] = NULL;
  139. if (XP) {
  140. advapidll = LoadLibrary(_T("advapi32.dll"));
  141. if (advapidll != NULL) {
  142. #ifdef UNICODE
  143. FuncArray[FUNC_FLUSH_TRACE] = GetProcAddress(advapidll, "FlushTraceW");
  144. #else
  145. FuncArray[FUNC_FLUSH_TRACE] = GetProcAddress(advapidll, "FlushTraceA");
  146. #endif
  147. FuncArray[FUNC_ENUM_TRACE_GUIDS] = GetProcAddress(advapidll, "EnumerateTraceGuids");
  148. }
  149. }
  150. // Initialize structure first
  151. SizeNeeded = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAXSTR * sizeof(TCHAR);
  152. pLoggerInfo = (PEVENT_TRACE_PROPERTIES) malloc(SizeNeeded);
  153. if (pLoggerInfo == NULL) {
  154. if (advapidll != NULL)
  155. FreeLibrary(advapidll);
  156. return (ERROR_OUTOFMEMORY);
  157. }
  158. RtlZeroMemory(pLoggerInfo, SizeNeeded);
  159. pLoggerInfo->Wnode.BufferSize = SizeNeeded;
  160. pLoggerInfo->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  161. pLoggerInfo->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  162. pLoggerInfo->LogFileNameOffset = pLoggerInfo->LoggerNameOffset + MAXSTR * sizeof(TCHAR);
  163. LoggerName = (LPTSTR)((char*)pLoggerInfo + pLoggerInfo->LoggerNameOffset);
  164. LogFileName = (LPTSTR)((char*)pLoggerInfo + pLoggerInfo->LogFileNameOffset);
  165. _tcscpy(LoggerName, NT_LOGGER);
  166. Space = (char*) malloc( (MAXGUIDS * sizeof(GuidArray)) +
  167. (MAXGUIDS * sizeof(GUID) ));
  168. if (Space == NULL) {
  169. free(pLoggerInfo);
  170. if (advapidll != NULL)
  171. FreeLibrary(advapidll);
  172. return(ERROR_OUTOFMEMORY);
  173. }
  174. save = Space;
  175. GuidArray = (LPGUID *) Space;
  176. Space += MAXGUIDS * sizeof(GuidArray);
  177. for (GuidCount=0; GuidCount<MAXGUIDS; GuidCount++) {
  178. GuidArray[GuidCount] = (LPGUID) Space;
  179. Space += sizeof(GUID);
  180. }
  181. GuidCount = 0;
  182. #ifdef UNICODE
  183. if ((targv = CommandLineToArgvW(
  184. GetCommandLineW(), // pointer to a command-line string
  185. &argc // receives the argument count
  186. )) == NULL) {
  187. free(pLoggerInfo);
  188. free(save);
  189. if (advapidll != NULL)
  190. FreeLibrary(advapidll);
  191. return (GetLastError());
  192. };
  193. utargv = targv;
  194. #else
  195. targv = argv;
  196. #endif
  197. pFlags = &pLoggerInfo->EnableFlags;
  198. //
  199. // Add default flags.
  200. //
  201. while (--argc > 0) {
  202. ++targv;
  203. if (**targv == '-' || **targv == '/') { // argument found
  204. if(targv[0][0] == '/' ) targv[0][0] = '-';
  205. if (!_tcsicmp(targv[0], _T("-start"))) {
  206. Action = ACTION_START;
  207. if (argc > 1) {
  208. if (targv[1][0] != '-' && targv[1][0] != '/') {
  209. ++targv; --argc;
  210. _tcscpy(LoggerName, targv[0]);
  211. }
  212. }
  213. }
  214. else if (!_tcsicmp(targv[0], _T("-enable"))) {
  215. Action = ACTION_ENABLE;
  216. if (argc > 1) {
  217. if (targv[1][0] != '-' && targv[1][0] != '/') {
  218. ++targv; --argc;
  219. _tcscpy(LoggerName, targv[0]);
  220. }
  221. }
  222. }
  223. else if (!_tcsicmp(targv[0], _T("-disable"))) {
  224. Action = ACTION_ENABLE;
  225. bEnable = FALSE;
  226. if (argc > 1) {
  227. if (targv[1][0] != '-' && targv[1][0] != '/') {
  228. ++targv; --argc;
  229. _tcscpy(LoggerName, targv[0]);
  230. }
  231. }
  232. }
  233. else if (!_tcsicmp(targv[0], _T("-stop"))) {
  234. Action = ACTION_STOP;
  235. if (argc > 1) {
  236. if (targv[1][0] != '-' && targv[1][0] != '/') {
  237. ++targv; --argc;
  238. _tcscpy(LoggerName, targv[0]);
  239. }
  240. }
  241. }
  242. else if (!_tcsicmp(targv[0], _T("-update"))) {
  243. Action = ACTION_UPDATE;
  244. if (argc > 1) {
  245. if (targv[1][0] != '-' && targv[1][0] != '/') {
  246. ++targv; --argc;
  247. _tcscpy(LoggerName, targv[0]);
  248. }
  249. }
  250. }
  251. else if (!_tcsicmp(targv[0], _T("-q"))) {
  252. Action = ACTION_QUERY;
  253. if (argc > 1) {
  254. if (targv[1][0] != '-' && targv[1][0] != '/') {
  255. ++targv; --argc;
  256. _tcscpy(LoggerName, targv[0]);
  257. }
  258. }
  259. }
  260. else if (!_tcsicmp(targv[0], _T("-flush"))) {
  261. Action = ACTION_FLUSH;
  262. if (argc > 1) {
  263. if (targv[1][0] != '-' && targv[1][0] != '/') {
  264. ++targv; --argc;
  265. _tcscpy(LoggerName, targv[0]);
  266. }
  267. }
  268. }
  269. else if (!_tcsicmp(targv[0], _T("-enumguid"))) {
  270. Action = ACTION_ENUM_GUID;
  271. }
  272. else if (!_tcsicmp(targv[0], _T("-f"))) {
  273. if (argc > 1) {
  274. _tcscpy(LogFileName, targv[1]);
  275. _tcscpy(tstrLogFileName, targv[1]);
  276. ++targv; --argc;
  277. }
  278. }
  279. else if (!_tcsicmp(targv[0], _T("-append"))) {
  280. if (argc > 1) {
  281. _tfullpath(LogFileName, targv[1], MAXSTR);
  282. _tcscpy(tstrLogFileName, LogFileName);
  283. ++targv; --argc;
  284. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_APPEND;
  285. }
  286. }
  287. else if (!_tcsicmp(targv[0], _T("-guid"))) {
  288. if (argc > 1) {
  289. if (targv[1][0] == _T('#')) {
  290. StringToGuid(&targv[1][1], GuidArray[0]);
  291. ++targv; --argc;
  292. GuidCount = 1;
  293. }
  294. else if (targv[1][0] != '-' && targv[1][0] != '/') {
  295. _tfullpath(GuidFile, targv[1], MAXSTR);
  296. ++targv; --argc;
  297. GuidCount = GetGuids(GuidFile, GuidArray);
  298. if (GuidCount < 0) {
  299. _tprintf( _T("Error: %s does no exist\n"), GuidFile );
  300. Status = ERROR_INVALID_PARAMETER;
  301. goto CleanupExit;
  302. }
  303. else if (GuidCount == 0){
  304. _tprintf( _T("Error: %s is invalid\n"), GuidFile );
  305. Status = ERROR_INVALID_PARAMETER;
  306. goto CleanupExit;
  307. }
  308. }
  309. }
  310. }
  311. else if (!_tcsicmp(targv[0], _T("-seq"))) {
  312. if (argc > 1) {
  313. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_SEQUENTIAL;
  314. pLoggerInfo->MaximumFileSize = _ttoi(targv[1]);
  315. ++targv; --argc;
  316. }
  317. }
  318. else if (!_tcsicmp(targv[0], _T("-newfile"))) {
  319. if (argc > 1) {
  320. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_NEWFILE;
  321. pLoggerInfo->MaximumFileSize = _ttoi(targv[1]);
  322. ++targv; --argc;
  323. }
  324. }
  325. else if (!_tcsicmp(targv[0], _T("-cir"))) {
  326. if (argc > 1) {
  327. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_CIRCULAR;
  328. pLoggerInfo->MaximumFileSize = _ttoi(targv[1]);
  329. ++targv; --argc;
  330. }
  331. }
  332. else if (!_tcsicmp(targv[0], _T("-b"))) {
  333. if (argc > 1) {
  334. pLoggerInfo->BufferSize = _ttoi(targv[1]);
  335. ++targv; --argc;
  336. }
  337. }
  338. else if (!_tcsicmp(targv[0], _T("-flag")) || !_tcsicmp(targv[0], _T("-flags"))) {
  339. if (argc > 1) {
  340. if (targv[1][1] == _T('x') || targv[1][1] == _T('X')) {
  341. pLoggerInfo->EnableFlags |= ahextoi(targv[1]);
  342. } else {
  343. pLoggerInfo->EnableFlags |= _ttoi(targv[1]);
  344. }
  345. iFlags = pLoggerInfo->EnableFlags ; // Copy for EnableTrace
  346. ++targv; --argc;
  347. // Do not accept flags with MSB = 1.
  348. if (0x80000000 & pLoggerInfo->EnableFlags) {
  349. _tprintf(_T("Invalid Flags: 0x%0X(%d.)\n"),
  350. pLoggerInfo->EnableFlags, pLoggerInfo->EnableFlags);
  351. Status = ERROR_INVALID_PARAMETER;
  352. goto CleanupExit;
  353. }
  354. }
  355. }
  356. else if (!_tcsicmp(targv[0], _T("-min"))) {
  357. if (argc > 1) {
  358. pLoggerInfo->MinimumBuffers = _ttoi(targv[1]);
  359. ++targv; --argc;
  360. }
  361. }
  362. else if (!_tcsicmp(targv[0], _T("-max"))) {
  363. if (argc > 1) {
  364. pLoggerInfo->MaximumBuffers = _ttoi(targv[1]);
  365. ++targv; --argc;
  366. }
  367. }
  368. else if (!_tcsicmp(targv[0], _T("-level"))) {
  369. if (argc > 1) {
  370. iLevel = _ttoi(targv[1]);
  371. ++targv; --argc;
  372. }
  373. }
  374. else if (!_tcsicmp(targv[0], _T("-ft"))) {
  375. if (argc > 1) {
  376. pLoggerInfo->FlushTimer = _ttoi(targv[1]);
  377. ++targv; --argc;
  378. }
  379. }
  380. else if (!_tcsicmp(targv[0], _T("-um"))) {
  381. pLoggerInfo->LogFileMode |= EVENT_TRACE_PRIVATE_LOGGER_MODE;
  382. }
  383. else if (!_tcsicmp(targv[0], _T("-paged"))) {
  384. pLoggerInfo->LogFileMode |= EVENT_TRACE_USE_PAGED_MEMORY;
  385. }
  386. else if (!_tcsicmp(targv[0], _T("-rt"))) {
  387. pLoggerInfo->LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
  388. }
  389. else if (!_tcsicmp(targv[0], _T("-age"))) {
  390. if (argc > 1) {
  391. pLoggerInfo->AgeLimit = _ttoi(targv[1]);
  392. ++targv; --argc;
  393. }
  394. }
  395. else if (!_tcsicmp(targv[0], _T("-l"))) {
  396. Action = ACTION_LIST;
  397. bKill = FALSE;
  398. }
  399. else if (!_tcsicmp(targv[0], _T("-x"))) {
  400. Action = ACTION_LIST;
  401. bKill = TRUE;
  402. }
  403. else if (!_tcsicmp(targv[0], _T("-xf"))) {
  404. Action = ACTION_LIST;
  405. bKill = TRUE;
  406. bForceKill = TRUE ;
  407. }
  408. else if (!_tcsicmp(targv[0], _T("-noprocess"))) {
  409. bProcess = FALSE;
  410. }
  411. else if (!_tcsicmp(targv[0], _T("-nothread"))) {
  412. bThread = FALSE;
  413. }
  414. else if (!_tcsicmp(targv[0], _T("-nodisk"))) {
  415. bDisk = FALSE;
  416. }
  417. else if (!_tcsicmp(targv[0], _T("-nonet"))) {
  418. bNetwork = FALSE;
  419. }
  420. else if (!_tcsicmp(targv[0], _T("-fio"))) {
  421. if (pFlags == &pLoggerInfo->EnableFlags) {
  422. *pFlags |= EVENT_TRACE_FLAG_DISK_FILE_IO;
  423. }
  424. else {
  425. _tprintf(_T("Option -fio cannot be used with -eflags. Ignored\n"));
  426. }
  427. }
  428. else if (!_tcsicmp(targv[0], _T("-pf"))) {
  429. if (pFlags == &pLoggerInfo->EnableFlags) {
  430. *pFlags |= EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS;
  431. }
  432. else {
  433. _tprintf(_T("Option -pf cannot be used with -eflags. Ignored\n"));
  434. }
  435. }
  436. else if (!_tcsicmp(targv[0], _T("-hf"))) {
  437. if (pFlags == &pLoggerInfo->EnableFlags) {
  438. *pFlags |= EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS;
  439. }
  440. else {
  441. _tprintf(_T("Option -hf cannot be used with -eflags. Ignored\n"));
  442. }
  443. }
  444. else if (!_tcsicmp(targv[0], _T("-img"))) {
  445. if (pFlags == &pLoggerInfo->EnableFlags) {
  446. *pFlags |= EVENT_TRACE_FLAG_IMAGE_LOAD;
  447. }
  448. else {
  449. _tprintf(_T("Option -img cannot be used with -eflags. Ignored\n"));
  450. }
  451. }
  452. else if (!_tcsicmp(targv[0], _T("-cm"))) {
  453. if (pFlags == &pLoggerInfo->EnableFlags) {
  454. *pFlags |= EVENT_TRACE_FLAG_REGISTRY;
  455. }
  456. else {
  457. _tprintf(_T("Option -cm cannot be used with -eflags. Ignored\n"));
  458. }
  459. }
  460. else if ( targv[0][1] == 'h' || targv[0][1] == 'H' || targv[0][1] == '?'){
  461. Action = ACTION_HELP;
  462. PrintHelpMessage();
  463. goto CleanupExit;
  464. }
  465. else Action = ACTION_UNDEFINED;
  466. }
  467. else {
  468. _tprintf(_T("Invalid option given: %s\n"), targv[0]);
  469. Status = ERROR_INVALID_PARAMETER;
  470. goto CleanupExit;
  471. }
  472. }
  473. if (!_tcscmp(LoggerName, NT_LOGGER)) {
  474. if (pFlags == &pLoggerInfo->EnableFlags) {
  475. if (bProcess)
  476. *pFlags |= EVENT_TRACE_FLAG_PROCESS;
  477. if (bThread)
  478. *pFlags |= EVENT_TRACE_FLAG_THREAD;
  479. if (bDisk)
  480. *pFlags |= EVENT_TRACE_FLAG_DISK_IO;
  481. if (bNetwork)
  482. *pFlags |= EVENT_TRACE_FLAG_NETWORK_TCPIP;
  483. }
  484. pLoggerInfo->Wnode.Guid = SystemTraceControlGuid; // defaults to OS
  485. specialLogger = 1;
  486. }
  487. if ( !(pLoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) ) {
  488. if (specialLogger != 3 && _tcslen(LogFileName) <= 0 && Action == ACTION_START) {
  489. _tcscpy(LogFileName, DEFAULT_LOGFILE_NAME); // for now...
  490. _tcscpy(tstrLogFileName, DEFAULT_LOGFILE_NAME);
  491. }
  492. }
  493. switch (Action) {
  494. case ACTION_START:
  495. {
  496. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  497. if (GuidCount != 1) {
  498. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  499. Status = ERROR_INVALID_PARAMETER;
  500. break;
  501. }
  502. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  503. }
  504. Status = StartTrace(&LoggerHandle, LoggerName, pLoggerInfo);
  505. if (Status != ERROR_SUCCESS) {
  506. _tprintf(_T("Could not start logger: %s\n")
  507. _T("Operation Status: %uL\n")
  508. _T("%s\n"),
  509. LoggerName,
  510. Status,
  511. DecodeStatus(Status));
  512. break;
  513. }
  514. _tprintf(_T("Logger Started...\n"));
  515. case ACTION_ENABLE:
  516. if (Action == ACTION_ENABLE ){
  517. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE)
  518. {
  519. if (GuidCount != 1)
  520. {
  521. _tprintf(_T("Need one GUID for PRIVATE loggers\n"));
  522. Status = ERROR_INVALID_PARAMETER;
  523. break;
  524. }
  525. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  526. }
  527. Status = ControlTrace((TRACEHANDLE) 0, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  528. if( Status != ERROR_SUCCESS ){
  529. _tprintf( _T("ERROR: Logger not started\n")
  530. _T("Operation Status: %uL\n")
  531. _T("%s\n"),
  532. Status,
  533. DecodeStatus(Status));
  534. break;
  535. }
  536. LoggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  537. }
  538. if ( (GuidCount > 0) && (specialLogger == 0)) {
  539. _tprintf(_T("Enabling trace to logger %d\n"), LoggerHandle);
  540. for (i = 0; i < (ULONG)GuidCount; i++) {
  541. Status = EnableTrace (
  542. bEnable,
  543. iFlags,
  544. iLevel,
  545. GuidArray[i],
  546. LoggerHandle);
  547. //
  548. // If some of the Guids can not be enabled, consider it a benign
  549. // failure. Print a warning message and continue.
  550. //
  551. if (Status == ERROR_INVALID_OPERATION) {
  552. _tprintf(_T("WARNING: Could not enable some guids.\n"));
  553. _tprintf(_T("Check your Guids file\n"));
  554. Status = ERROR_SUCCESS;
  555. }
  556. if (Status != ERROR_SUCCESS) {
  557. _tprintf(_T("ERROR: Failed to enable Guid [%d]...\n"), i);
  558. _tprintf(_T("Operation Status: %uL\n"), Status);
  559. _tprintf(_T("%s\n"),DecodeStatus(Status));
  560. break;
  561. }
  562. }
  563. }
  564. else {
  565. if (GuidCount > 0) {
  566. _tprintf(_T("ERROR: System Logger does not accept application guids...\n"));
  567. Status = ERROR_INVALID_PARAMETER;
  568. }
  569. }
  570. break;
  571. }
  572. case ACTION_STOP :
  573. LoggerHandle = (TRACEHANDLE) 0;
  574. Status = ERROR_SUCCESS;
  575. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  576. if (GuidCount != 1) {
  577. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  578. Status = ERROR_INVALID_PARAMETER;
  579. break;
  580. }
  581. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  582. }
  583. if (specialLogger != 0) {
  584. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  585. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  586. if (Status != ERROR_SUCCESS)
  587. break;
  588. LoggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  589. Status = EnableTrace( FALSE,
  590. EVENT_TRACE_PRIVATE_LOGGER_MODE,
  591. 0,
  592. GuidArray[0],
  593. LoggerHandle );
  594. }
  595. else {
  596. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  597. if (Status == ERROR_WMI_INSTANCE_NOT_FOUND)
  598. break;
  599. LoggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  600. for (i = 0; i < (ULONG)GuidCount; i++) {
  601. Status = EnableTrace( FALSE,
  602. 0,
  603. 0,
  604. GuidArray[i],
  605. LoggerHandle);
  606. }
  607. }
  608. }
  609. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_STOP);
  610. break;
  611. case ACTION_LIST :
  612. {
  613. ULONG i, returnCount ;
  614. ULONG SizeNeeded;
  615. PEVENT_TRACE_PROPERTIES pLoggerInfo[MAXIMUM_LOGGERS];
  616. PEVENT_TRACE_PROPERTIES pStorage;
  617. PVOID Storage;
  618. SizeNeeded = MAXIMUM_LOGGERS * (sizeof(EVENT_TRACE_PROPERTIES)
  619. + 2 * MAXSTR * sizeof(TCHAR));
  620. Storage = malloc(SizeNeeded);
  621. if (Storage == NULL) {
  622. Status = ERROR_OUTOFMEMORY;
  623. break;
  624. }
  625. RtlZeroMemory(Storage, SizeNeeded);
  626. pStorage = (PEVENT_TRACE_PROPERTIES)Storage;
  627. for (i=0; i<MAXIMUM_LOGGERS; i++) {
  628. pStorage->Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES)
  629. + 2 * MAXSTR * sizeof(TCHAR);
  630. pStorage->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES)
  631. + MAXSTR * sizeof(TCHAR);
  632. pStorage->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  633. pLoggerInfo[i] = pStorage;
  634. pStorage = (PEVENT_TRACE_PROPERTIES) (
  635. (char*)pStorage +
  636. pStorage->Wnode.BufferSize);
  637. }
  638. Status = QueryAllTraces(pLoggerInfo,
  639. MAXIMUM_LOGGERS,
  640. & returnCount);
  641. if (Status == ERROR_SUCCESS)
  642. {
  643. for (j= 0; j < returnCount; j++)
  644. {
  645. LPTSTR LoggerName;
  646. TCHAR asked = _T('?') ;
  647. BOOL StatusPrint = FALSE ;
  648. if (bKill)
  649. {
  650. LoggerName = (LPTSTR) ((char*)pLoggerInfo[j] +
  651. pLoggerInfo[j]->LoggerNameOffset);
  652. if (!bForceKill) {
  653. while (!(asked == _T('y')) && !(asked == _T('n'))) {
  654. _tprintf(_T("Do you want to kill Logger \"%s\" (Y or N)?"),LoggerName);
  655. _tscanf(_T(" %c"),&asked);
  656. if (asked == _T('Y')) {
  657. asked = _T('y') ;
  658. } else if (asked == _T('N')) {
  659. asked = _T('n') ;
  660. }
  661. }
  662. } else {
  663. asked = _T('y');
  664. }
  665. if (asked == _T('y')) {
  666. if (!IsEqualGUID(& pLoggerInfo[j]->Wnode.Guid,
  667. & SystemTraceControlGuid))
  668. {
  669. LoggerHandle = pLoggerInfo[j]->Wnode.HistoricalContext;
  670. Status = EnableTrace(
  671. FALSE,
  672. (pLoggerInfo[j]->LogFileMode &
  673. EVENT_TRACE_PRIVATE_LOGGER_MODE)
  674. ? (EVENT_TRACE_PRIVATE_LOGGER_MODE)
  675. : (0),
  676. 0,
  677. & pLoggerInfo[j]->Wnode.Guid,
  678. LoggerHandle);
  679. }
  680. Status = ControlTrace((TRACEHANDLE) 0,
  681. LoggerName,
  682. pLoggerInfo[j],
  683. EVENT_TRACE_CONTROL_STOP);
  684. _tprintf(_T("Logger \"%s\" has been killed\n"),LoggerName);
  685. StatusPrint = TRUE ;
  686. } else {
  687. _tprintf(_T("Logger \"%s\" has not been killed, current Status is\n"),LoggerName);
  688. StatusPrint = FALSE ;
  689. }
  690. }
  691. PrintLoggerStatus(pLoggerInfo[j],
  692. Status,
  693. StatusPrint);
  694. _tprintf(_T("\n"));
  695. }
  696. }
  697. i = 0;
  698. free(Storage);
  699. break;
  700. }
  701. case ACTION_UPDATE :
  702. case ACTION_FLUSH :
  703. case ACTION_QUERY :
  704. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  705. if (GuidCount != 1) {
  706. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  707. Status = ERROR_INVALID_PARAMETER;
  708. break;
  709. }
  710. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  711. }
  712. if (Action == ACTION_QUERY) {
  713. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  714. }
  715. else if (Action == ACTION_UPDATE) {
  716. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_UPDATE);
  717. }
  718. else if (Action == ACTION_FLUSH) {
  719. // Since FlushTrace is not implemented on Win2K, use the function pointer
  720. // loaded from advapi32.dll separately.
  721. // Originally, this block had one line:
  722. // Status = FlushTrace(LoggerHandle, LoggerName, pLoggerInfo);
  723. if (FuncArray[FUNC_FLUSH_TRACE] == NULL) {
  724. _tprintf(_T("Flush Trace is not supported on this system\n"));
  725. Status = ERROR_INVALID_PARAMETER;
  726. break;
  727. }
  728. Status = (ULONG)(*FuncArray[FUNC_FLUSH_TRACE])(LoggerHandle, LoggerName, pLoggerInfo);
  729. }
  730. break;
  731. case ACTION_ENUM_GUID:
  732. {
  733. ULONG i;
  734. ULONG PropertyArrayCount=10;
  735. PTRACE_GUID_PROPERTIES *GuidPropertiesArray;
  736. ULONG GuidCount;
  737. ULONG SizeStorage;
  738. PVOID StorageNeeded;
  739. PTRACE_GUID_PROPERTIES CleanStorage;
  740. TCHAR str[MAXSTR];
  741. // Since EnumTraceGuids is not implemented on Win2K, use the function pointer
  742. // loaded from advapi32.dll separately.
  743. if (FuncArray[FUNC_ENUM_TRACE_GUIDS] == NULL) {
  744. _tprintf(_T("Enumerating trace GUIDS is not supported on this system\n"));
  745. Status = ERROR_INVALID_PARAMETER;
  746. break;
  747. }
  748. Retry:
  749. SizeStorage = PropertyArrayCount * (sizeof(TRACE_GUID_PROPERTIES) + sizeof(PTRACE_GUID_PROPERTIES));
  750. StorageNeeded = malloc(SizeStorage);
  751. if (StorageNeeded== NULL) {
  752. Status = ERROR_OUTOFMEMORY;
  753. break;
  754. }
  755. RtlZeroMemory(StorageNeeded, SizeStorage);
  756. GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)StorageNeeded;
  757. CleanStorage = (PTRACE_GUID_PROPERTIES)((char*)StorageNeeded + PropertyArrayCount * sizeof(PTRACE_GUID_PROPERTIES));
  758. for (i=0; i < PropertyArrayCount; i++) {
  759. GuidPropertiesArray[i] = CleanStorage;
  760. CleanStorage = (PTRACE_GUID_PROPERTIES) (
  761. (char*)CleanStorage + sizeof(TRACE_GUID_PROPERTIES)
  762. );
  763. }
  764. // Use function pointer for EnumTraceGuids
  765. Status = (ULONG)(*FuncArray[FUNC_ENUM_TRACE_GUIDS])(GuidPropertiesArray,PropertyArrayCount,&GuidCount);
  766. if(Status == ERROR_MORE_DATA)
  767. {
  768. PropertyArrayCount=GuidCount;
  769. free(StorageNeeded);
  770. goto Retry;
  771. }
  772. //
  773. // print the GUID_PROPERTIES and Free Strorage
  774. //
  775. _tprintf(_T(" Guid Enabled LoggerId Level Flags\n"));
  776. _tprintf(_T("------------------------------------------------------------\n"));
  777. for (i=0; i < GuidCount; i++) {
  778. _tprintf(_T("%s %5s %d %d %d\n"),
  779. GuidToString(&str[0],&GuidPropertiesArray[i]->Guid),
  780. (GuidPropertiesArray[i]->IsEnable) ? _T("TRUE") : _T("FALSE"),
  781. GuidPropertiesArray[i]->LoggerId,
  782. GuidPropertiesArray[i]->EnableLevel,
  783. GuidPropertiesArray[i]->EnableFlags
  784. );
  785. }
  786. free(StorageNeeded);
  787. }
  788. break;
  789. case ACTION_HELP:
  790. PrintHelpMessage();
  791. break;
  792. default :
  793. _tprintf(_T("Error: no action specified\n"));
  794. PrintHelpMessage();
  795. break;
  796. }
  797. if ((Action != ACTION_HELP) && (Action != ACTION_ENUM_GUID)
  798. && (Action != ACTION_UNDEFINED) && (Action != ACTION_LIST))
  799. PrintLoggerStatus(pLoggerInfo,
  800. Status,
  801. PRINTSTATUS);
  802. CleanupExit:
  803. SetLastError(Status);
  804. if (utargv != NULL) {
  805. GlobalFree(utargv);
  806. }
  807. free(pLoggerInfo);
  808. free(save);
  809. if (advapidll != NULL)
  810. FreeLibrary(advapidll);
  811. return(Status);
  812. }
  813. void
  814. PrintLoggerStatus(
  815. IN PEVENT_TRACE_PROPERTIES LoggerInfo,
  816. IN ULONG Status,
  817. IN BOOL PrintStatus
  818. )
  819. /*++
  820. Routine Description:
  821. Prints out the status of the specified logger.
  822. Arguments:
  823. LoggerInfo - The pointer to the resident EVENT_TRACE_PROPERTIES that has
  824. the information about the current logger.
  825. Status - The returned status of the last executed command
  826. or
  827. the operation status of the current logger.
  828. PrintStatus - Determines which type of status it is using.
  829. Return Value:
  830. None
  831. --*/
  832. {
  833. LPTSTR LoggerName, LogFileName;
  834. if ((LoggerInfo->LoggerNameOffset > 0) &&
  835. (LoggerInfo->LoggerNameOffset < LoggerInfo->Wnode.BufferSize)) {
  836. LoggerName = (LPTSTR) ((char*)LoggerInfo +
  837. LoggerInfo->LoggerNameOffset);
  838. }
  839. else LoggerName = NULL;
  840. if ((LoggerInfo->LogFileNameOffset > 0) &&
  841. (LoggerInfo->LogFileNameOffset < LoggerInfo->Wnode.BufferSize)) {
  842. LogFileName = (LPTSTR) ((char*)LoggerInfo +
  843. LoggerInfo->LogFileNameOffset);
  844. }
  845. else LogFileName = NULL;
  846. if (PrintStatus) {
  847. _tprintf(_T("Operation Status: %uL\t"), Status);
  848. _tprintf(_T("%s\n"), DecodeStatus(Status));
  849. }
  850. _tprintf(_T("Logger Name: %s\n"),
  851. (LoggerName == NULL) ?
  852. _T(" ") : LoggerName);
  853. _tprintf(_T("Logger Id: %I64x\n"), LoggerInfo->Wnode.HistoricalContext);
  854. _tprintf(_T("Logger Thread Id: %d\n"), LoggerInfo->LoggerThreadId);
  855. if (Status != 0)
  856. return;
  857. _tprintf(_T("Buffer Size: %d Kb"), LoggerInfo->BufferSize);
  858. if (LoggerInfo->LogFileMode & EVENT_TRACE_USE_PAGED_MEMORY) {
  859. _tprintf(_T(" using paged memory\n"));
  860. }
  861. else {
  862. _tprintf(_T("\n"));
  863. }
  864. _tprintf(_T("Maximum Buffers: %d\n"), LoggerInfo->MaximumBuffers);
  865. _tprintf(_T("Minimum Buffers: %d\n"), LoggerInfo->MinimumBuffers);
  866. _tprintf(_T("Number of Buffers: %d\n"), LoggerInfo->NumberOfBuffers);
  867. _tprintf(_T("Free Buffers: %d\n"), LoggerInfo->FreeBuffers);
  868. _tprintf(_T("Buffers Written: %d\n"), LoggerInfo->BuffersWritten);
  869. _tprintf(_T("Events Lost: %d\n"), LoggerInfo->EventsLost);
  870. _tprintf(_T("Log Buffers Lost: %d\n"), LoggerInfo->LogBuffersLost);
  871. _tprintf(_T("Real Time Buffers Lost: %d\n"), LoggerInfo->RealTimeBuffersLost);
  872. _tprintf(_T("AgeLimit: %d\n"), LoggerInfo->AgeLimit);
  873. if (LogFileName == NULL) {
  874. _tprintf(_T("Buffering Mode: "));
  875. }
  876. else {
  877. _tprintf(_T("Log File Mode: "));
  878. }
  879. if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_APPEND) {
  880. _tprintf(_T("Append "));
  881. }
  882. if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
  883. _tprintf(_T("Circular\n"));
  884. }
  885. else if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  886. _tprintf(_T("Sequential\n"));
  887. }
  888. else {
  889. _tprintf(_T("Sequential\n"));
  890. }
  891. if (LoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) {
  892. _tprintf(_T("Real Time mode enabled"));
  893. _tprintf(_T("\n"));
  894. }
  895. if (LoggerInfo->MaximumFileSize > 0)
  896. _tprintf(_T("Maximum File Size: %d Mb\n"), LoggerInfo->MaximumFileSize);
  897. if (LoggerInfo->FlushTimer > 0)
  898. _tprintf(_T("Buffer Flush Timer: %d secs\n"), LoggerInfo->FlushTimer);
  899. if (LoggerInfo->EnableFlags != 0) {
  900. _tprintf(_T("Enabled tracing: "));
  901. if ((LoggerName != NULL) && (!_tcscmp(LoggerName,NT_LOGGER))) {
  902. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
  903. _tprintf(_T("Process "));
  904. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
  905. _tprintf(_T("Thread "));
  906. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
  907. _tprintf(_T("Disk "));
  908. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
  909. _tprintf(_T("File "));
  910. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
  911. _tprintf(_T("PageFaults "));
  912. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
  913. _tprintf(_T("HardFaults "));
  914. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
  915. _tprintf(_T("ImageLoad "));
  916. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
  917. _tprintf(_T("TcpIp "));
  918. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_REGISTRY)
  919. _tprintf(_T("Registry "));
  920. }else{
  921. _tprintf(_T("0x%08x"), LoggerInfo->EnableFlags );
  922. }
  923. _tprintf(_T("\n"));
  924. }
  925. if (LogFileName != NULL) {
  926. _tprintf(_T("Log Filename: %s\n"), LogFileName);
  927. }
  928. }
  929. LPTSTR
  930. DecodeStatus(
  931. IN ULONG Status
  932. )
  933. /*++
  934. Routine Description:
  935. Decodes WIN32 error into a string in the default language.
  936. Arguments:
  937. Status - The error status from the last executed command
  938. or
  939. the operation status of the current logger.
  940. Return Value:
  941. LPTSTR - String containing the decoded message.
  942. --*/
  943. {
  944. memset( ErrorMsg, 0, MAXSTR );
  945. FormatMessage(
  946. FORMAT_MESSAGE_FROM_SYSTEM |
  947. FORMAT_MESSAGE_IGNORE_INSERTS,
  948. NULL,
  949. Status,
  950. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  951. (LPTSTR) ErrorMsg,
  952. MAXSTR,
  953. NULL );
  954. return ErrorMsg;
  955. }
  956. LONG
  957. GetGuids(
  958. IN LPTSTR GuidFile,
  959. IN OUT LPGUID *GuidArray
  960. )
  961. /*++
  962. Routine Description:
  963. Reads GUIDs from a file and stores them in an GUID array.
  964. Arguments:
  965. GuidFile - The file containing GUIDs.
  966. GuidArray - The GUID array that will have GUIDs read from the file.
  967. Return Value:
  968. ULONG - The number of GUIDs processed.
  969. --*/
  970. {
  971. FILE *f;
  972. TCHAR line[MAXSTR], arg[MAXSTR];
  973. LPGUID Guid;
  974. int i, n;
  975. f = _tfopen((TCHAR*)GuidFile, _T("r"));
  976. if (f == NULL)
  977. return -1;
  978. n = 0;
  979. while ( _fgetts(line, MAXSTR, f) != NULL ) {
  980. if (_tcslen(line) < 36)
  981. continue;
  982. if (line[0] == ';' ||
  983. line[0] == '\0' ||
  984. line[0] == '#' ||
  985. line[0] == '/')
  986. continue;
  987. Guid = (LPGUID) GuidArray[n];
  988. n ++;
  989. _tcsncpy(arg, line, 8);
  990. arg[8] = 0;
  991. Guid->Data1 = ahextoi(arg);
  992. _tcsncpy(arg, &line[9], 4);
  993. arg[4] = 0;
  994. Guid->Data2 = (USHORT) ahextoi(arg);
  995. _tcsncpy(arg, &line[14], 4);
  996. arg[4] = 0;
  997. Guid->Data3 = (USHORT) ahextoi(arg);
  998. for (i=0; i<2; i++) {
  999. _tcsncpy(arg, &line[19 + (i*2)], 2);
  1000. arg[2] = 0;
  1001. Guid->Data4[i] = (UCHAR) ahextoi(arg);
  1002. }
  1003. for (i=2; i<8; i++) {
  1004. _tcsncpy(arg, &line[20 + (i*2)], 2);
  1005. arg[2] = 0;
  1006. Guid->Data4[i] = (UCHAR) ahextoi(arg);
  1007. }
  1008. }
  1009. return (ULONG)n;
  1010. }
  1011. ULONG
  1012. ahextoi(
  1013. IN TCHAR *s
  1014. )
  1015. /*++
  1016. Routine Description:
  1017. Converts a hex string into a number.
  1018. Arguments:
  1019. s - A hex string in TCHAR.
  1020. Return Value:
  1021. ULONG - The number in the string.
  1022. --*/
  1023. {
  1024. int len;
  1025. ULONG num, base, hex;
  1026. len = _tcslen(s);
  1027. hex = 0; base = 1; num = 0;
  1028. while (--len >= 0) {
  1029. if ( (s[len] == 'x' || s[len] == 'X') &&
  1030. (s[len-1] == '0') )
  1031. break;
  1032. if (s[len] >= '0' && s[len] <= '9')
  1033. num = s[len] - '0';
  1034. else if (s[len] >= 'a' && s[len] <= 'f')
  1035. num = (s[len] - 'a') + 10;
  1036. else if (s[len] >= 'A' && s[len] <= 'F')
  1037. num = (s[len] - 'A') + 10;
  1038. else
  1039. continue;
  1040. hex += num * base;
  1041. base = base * 16;
  1042. }
  1043. return hex;
  1044. }
  1045. void
  1046. StringToGuid(
  1047. IN TCHAR *str,
  1048. IN OUT LPGUID guid
  1049. )
  1050. /*++
  1051. Routine Description:
  1052. Converts a string into a GUID.
  1053. Arguments:
  1054. str - A string in TCHAR.
  1055. guid - The pointer to a GUID that will have the converted GUID.
  1056. Return Value:
  1057. None.
  1058. --*/
  1059. {
  1060. TCHAR temp[10];
  1061. int i, n;
  1062. temp[8]=_T('\0');
  1063. _tcsncpy(temp, str, 8);
  1064. _stscanf(temp, _T("%x"), &(guid->Data1));
  1065. temp[4]=_T('\0');
  1066. _tcsncpy(temp, &str[9], 4);
  1067. _stscanf(temp, _T("%x"), &(guid->Data2));
  1068. _tcsncpy(temp, &str[14], 4);
  1069. _stscanf(temp, _T("%x"), &(guid->Data3));
  1070. temp[2]='\0';
  1071. for(i=0;i<8;i++)
  1072. {
  1073. temp[0]=str[19+((i<2)?2*i:2*i+1)]; // to accomodate the minus sign after
  1074. temp[1]=str[20+((i<2)?2*i:2*i+1)]; // the first two chars
  1075. _stscanf(temp, _T("%x"), &n); // if used more than byte alloc
  1076. guid->Data4[i]=(unsigned char)n; // causes overrun of memory
  1077. }
  1078. }
  1079. void PrintHelpMessage()
  1080. /*++
  1081. Routine Description:
  1082. prints out a help message.
  1083. Arguments:
  1084. None.
  1085. Return Value:
  1086. None.
  1087. --*/
  1088. {
  1089. _tprintf(_T("Usage: tracelog [actions] [options] | [-h | -help | -?]\n"));
  1090. _tprintf(_T("\n actions:\n"));
  1091. _tprintf(_T("\t-start [LoggerName] Starts up the [LoggerName] trace session\n"));
  1092. _tprintf(_T("\t-stop [LoggerName] Stops the [LoggerName] trace session\n"));
  1093. _tprintf(_T("\t-update [LoggerName] Updates the [LoggerName] trace session\n"));
  1094. _tprintf(_T("\t-enable [LoggerName] Enables providers for the [LoggerName] session\n"));
  1095. _tprintf(_T("\t-disable [LoggerName] Disables providers for the [LoggerName] session\n"));
  1096. if (XP) {
  1097. _tprintf(_T("\t-flush [LoggerName] Flushes the [LoggerName] active buffers\n"));
  1098. _tprintf(_T("\t-enumguid Enumerate Registered Trace Guids\n"));
  1099. }
  1100. _tprintf(_T("\t-q [LoggerName] Query status of [LoggerName] trace session\n"));
  1101. _tprintf(_T("\t-l List all trace sessions\n"));
  1102. _tprintf(_T("\t-x Stops all active trace sessions\n"));
  1103. _tprintf(_T("\n options:\n"));
  1104. _tprintf(_T("\t-b <n> Sets buffer size to <n> Kbytes\n"));
  1105. _tprintf(_T("\t-min <n> Sets minimum buffers\n"));
  1106. _tprintf(_T("\t-max <n> Sets maximum buffers\n"));
  1107. _tprintf(_T("\t-f <name> Log to file <name>\n"));
  1108. if (XP) {
  1109. _tprintf(_T("\t-append <name> Append to file <name>\n"));
  1110. }
  1111. _tprintf(_T("\t-seq <n> Sequential logfile of up to n Mbytes\n"));
  1112. _tprintf(_T("\t-cir <n> Circular logfile of n Mbytes\n"));
  1113. if (XP) {
  1114. _tprintf(_T("\t-newfile <n> Log to a new file after every n Mbytes\n"));
  1115. }
  1116. _tprintf(_T("\t-ft <n> Set flush timer to n seconds\n"));
  1117. if (XP) {
  1118. _tprintf(_T("\t-paged Use pageable memory for buffers\n"));
  1119. }
  1120. _tprintf(_T("\t-noprocess Disable Process Start/End tracing\n"));
  1121. _tprintf(_T("\t-nothread Disable Thread Start/End tracing\n"));
  1122. _tprintf(_T("\t-nodisk Disable Disk I/O tracing\n"));
  1123. _tprintf(_T("\t-nonet Disable Network TCP/IP tracing\n"));
  1124. _tprintf(_T("\t-fio Enable file I/O tracing\n"));
  1125. _tprintf(_T("\t-pf Enable page faults tracing\n"));
  1126. _tprintf(_T("\t-hf Enable hard faults tracing\n"));
  1127. _tprintf(_T("\t-img Enable image load tracing\n"));
  1128. _tprintf(_T("\t-cm Enable registry calls tracing\n"));
  1129. _tprintf(_T("\t-um Enable Process Private tracing\n"));
  1130. _tprintf(_T("\t-guid <file> Start tracing for providers in file\n"));
  1131. _tprintf(_T("\t-rt Enable tracing in real time mode\n"));
  1132. _tprintf(_T("\t-age <n> Modify aging decay time to n minutes\n"));
  1133. _tprintf(_T("\t-level <n> Enable Level passed to the providers\n"));
  1134. _tprintf(_T("\t-flag <n> Enable Flags passed to the providers\n"));
  1135. _tprintf(_T("\n"));
  1136. _tprintf(_T("\t-h\n"));
  1137. _tprintf(_T("\t-help\n"));
  1138. _tprintf(_T("\t-? Display usage information\n"));
  1139. }
  1140. PTCHAR
  1141. GuidToString(
  1142. IN OUT PTCHAR s,
  1143. LPGUID piid
  1144. )
  1145. /*++
  1146. Routine Description:
  1147. Converts a GUID into a string.
  1148. Arguments:
  1149. s - A string in TCHAR that will have the converted GUID.
  1150. piid - The pointer to a GUID.
  1151. Return Value:
  1152. PTCHAR - The string containig the convereted GUID.
  1153. --*/
  1154. {
  1155. _stprintf(s, _T("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
  1156. piid->Data1, piid->Data2,
  1157. piid->Data3,
  1158. piid->Data4[0], piid->Data4[1],
  1159. piid->Data4[2], piid->Data4[3],
  1160. piid->Data4[4], piid->Data4[5],
  1161. piid->Data4[6], piid->Data4[7]);
  1162. return(s);
  1163. }