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.

2365 lines
84 KiB

  1. // begin_sdk
  2. /*++
  3. Copyright (c) 1997-1999 Microsoft Corporation
  4. Module Name:
  5. tracelog.c
  6. Abstract:
  7. Sample trace control program. Allows user to start, stop event tracing
  8. // end_sdk
  9. Author:
  10. Jee Fung Pang (jeepang) 03-Dec-1997
  11. Revision History:
  12. Insung Park (insungp) 28-Nov-2000
  13. Now tracelog can be used to set the registry keys to start or stop
  14. GlobalLogger. Other options also works except a few (such as -enable).
  15. e.g.
  16. tracelog -start GlobalLogger
  17. tracelog -stop GlobalLogger
  18. tracelog -q GlobalLogger
  19. However, "-start" option does not start GlobalLogger immediately. The
  20. machine must be rebooted. "-stop" option resets the registry keys and
  21. stop GlobalLogger.
  22. Users can use other options to customize the GlobalLogger sessions
  23. such as minimum and maximum buffers, buffer size, flush timer, and so on.
  24. One catch is, if any of the enable flags is set, GlobalLogger turns into
  25. NT Kernel Logger and its instance vanishes. Any attempt to access
  26. GlobalLogger with its name will fail with ERROR_WMI_INSTANCE_NOT_FOUND.
  27. "-stop" option will still reset registry keys so that the next time the
  28. machine boots GlobalLogger will not start.
  29. If any of the flags is set, users should access NT Kernel Logger to
  30. control it.
  31. Modified/updated functions include GetGlobalLoggerSettings,
  32. SetGlobalLoggerSettings, main, PrintLoggerStatus.
  33. Insung Park (insungp) 19-Dec-2000
  34. Changed trace function calls so that tracelog can be used on Win2K.
  35. FlushTrace and EnumTraceGuids are not implemented on Win2K, but they do
  36. not stop the execution of tracelog. An attempt to use FlushTrace or
  37. EnumTraceGuids on W2K will generate an error message.
  38. Fixed "-flags -1" bug. tracelog does not accept any flag with MSB=1.
  39. Insung Park (insungp) 21-Dec-2000
  40. Added a version display.
  41. Fixed PrintHelpMessage() so that options not available on Win2K will
  42. not be printed. ("-paged", "-flush", "-enumguid", "-append", "-newfile",
  43. "-eflag", "-ls", "-gs")
  44. Cleaned up the if blocks in main() so that tracelog frees allocated
  45. space properly before exiting regardless of error status.
  46. // begin_sdk
  47. --*/
  48. #ifndef UNICODE
  49. #define UNICODE
  50. #endif
  51. #ifndef _UNICODE
  52. #define _UNICODE
  53. #endif
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. // end_sdk
  57. #include <nt.h>
  58. #include <ntrtl.h>
  59. #include <nturtl.h>
  60. // begin_sdk
  61. #include <windows.h>
  62. #include <shellapi.h>
  63. #include <tchar.h>
  64. #include <wmistr.h>
  65. #include <initguid.h>
  66. #include <guiddef.h>
  67. #include <evntrace.h>
  68. #include <wmiguid.h>
  69. // end_sdk
  70. #include <ntwmi.h>
  71. // begin_sdk
  72. #define MAXSTR 1024
  73. #define DEFAULT_LOGFILE_NAME _T("C:\\LogFile.Etl")
  74. // end_sdk
  75. #define GLOBAL_LOGGER _T("GlobalLogger")
  76. #define EVENT_LOGGER _T("WMI Event Logger")
  77. #define MAXENABLEFLAGS 10
  78. // begin_sdk
  79. #define MAXIMUM_LOGGERS 32
  80. #define MAXGUIDS 128
  81. #define ACTION_QUERY 0
  82. #define ACTION_START 1
  83. #define ACTION_STOP 2
  84. #define ACTION_UPDATE 3
  85. #define ACTION_LIST 4
  86. #define ACTION_ENABLE 5
  87. #define ACTION_HELP 6
  88. #define ACTION_FLUSH 7
  89. #define ACTION_ENUM_GUID 8
  90. // end_sdk
  91. #define ACTION_REMOVE 9
  92. // begin_sdk
  93. #define ACTION_UNDEFINED 10
  94. #define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
  95. #define WSTRSIZE(str) (ULONG) ( (str) ? ((PCHAR) &str[wcslen(str)] - (PCHAR)str) + sizeof(UNICODE_NULL) : 0 )
  96. // Functions not implemented on Win2K need to be searched and loaded separately.
  97. // To make further accesses easy, an array of function pointers will be used.
  98. // The following list serves as indices to that array.
  99. //
  100. // If new functions are added to evntrace.h, the following list should be updated
  101. // as well as the array initialization routine at the beginning of main().
  102. #define FUNC_FLUSH_TRACE 0
  103. #define FUNC_ENUM_TRACE_GUIDS 1
  104. // Funtion pointer array for unimplemented functions on Win2K.
  105. // Note: This may not work if this code is ported to C++, because
  106. // all the function pointers may be typedefed differently.
  107. #define MAXFUNC 10
  108. FARPROC FuncArray[MAXFUNC];
  109. HINSTANCE advapidll;
  110. BOOLEAN Whistler;
  111. void
  112. PrintLoggerStatus(
  113. IN PEVENT_TRACE_PROPERTIES LoggerInfo,
  114. // end_sdk
  115. IN ULONG GlobalLoggerStartValue,
  116. // begin_sdk
  117. IN ULONG Status,
  118. IN BOOL PrintStatus
  119. );
  120. #define PRINTSTATUS TRUE
  121. #define NOPRINTSTATUS FALSE
  122. LPTSTR
  123. DecodeStatus(
  124. IN ULONG Status
  125. );
  126. LONG
  127. GetGuids(
  128. IN LPTSTR GuidFile,
  129. OUT LPGUID *GuidArray
  130. );
  131. ULONG
  132. ahextoi(
  133. IN TCHAR *s
  134. );
  135. void
  136. StringToGuid(
  137. IN TCHAR *str,
  138. OUT LPGUID guid
  139. );
  140. PTCHAR
  141. GuidToString(
  142. IN OUT PTCHAR s,
  143. IN LPGUID piid
  144. );
  145. TCHAR ErrorMsg[MAXSTR];
  146. void
  147. PrintHelpMessage();
  148. // end_sdk
  149. ULONG
  150. SetGlobalLoggerSettings(
  151. IN DWORD StartValue,
  152. IN PEVENT_TRACE_PROPERTIES LoggerInfo,
  153. IN DWORD ClockType
  154. );
  155. ULONG
  156. GetGlobalLoggerSettings(
  157. IN OUT PEVENT_TRACE_PROPERTIES LoggerInfo,
  158. OUT PULONG ClockType,
  159. OUT PDWORD pdwStart
  160. );
  161. // begin_sdk
  162. //
  163. // main function
  164. //
  165. __cdecl main(argc, argv)
  166. int argc;
  167. char **argv;
  168. /*++
  169. Routine Description:
  170. It is the main function.
  171. Arguments:
  172. Return Value:
  173. Error Code defined in winerror.h : If the function succeeds,
  174. it returns ERROR_SUCCESS (== 0).
  175. --*/{
  176. ULONG i, j;
  177. LONG GuidCount;
  178. USHORT Action = ACTION_UNDEFINED;
  179. ULONG Status = 0;
  180. LPTSTR LoggerName;
  181. LPTSTR LogFileName;
  182. TCHAR GuidFile[MAXSTR];
  183. PEVENT_TRACE_PROPERTIES pLoggerInfo;
  184. TRACEHANDLE LoggerHandle = 0;
  185. LPTSTR *targv, *utargv = NULL;
  186. LPGUID *GuidArray;
  187. char *Space;
  188. char *save;
  189. BOOL bKill = FALSE;
  190. BOOL bForceKill = FALSE ;
  191. BOOL bEnable = TRUE;
  192. ULONG iLevel = 0;
  193. ULONG iFlags = 0;
  194. ULONG SizeNeeded = 0;
  195. ULONG specialLogger = 0;
  196. ULONG GlobalLoggerStartValue = 0;
  197. PULONG pFlags = NULL;
  198. BOOL bProcess = TRUE;
  199. BOOL bThread = TRUE;
  200. BOOL bDisk = TRUE;
  201. BOOL bNetwork = TRUE;
  202. TCHAR tstrLogFileName[MAXSTR];
  203. OSVERSIONINFO OSVersion;
  204. OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  205. Whistler = FALSE;
  206. if (GetVersionEx(&OSVersion))
  207. Whistler = (OSVersion.dwMajorVersion > 5) ||
  208. ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion > 0));
  209. // Load functions that are not implemented on Win2K
  210. for (i = 0; i < MAXFUNC; ++i)
  211. FuncArray[i] = NULL;
  212. if (Whistler) {
  213. advapidll = LoadLibrary(_T("advapi32.dll"));
  214. if (advapidll != NULL) {
  215. #ifdef UNICODE
  216. FuncArray[FUNC_FLUSH_TRACE] = GetProcAddress(advapidll, "FlushTraceW");
  217. #else
  218. FuncArray[FUNC_FLUSH_TRACE] = GetProcAddress(advapidll, "FlushTraceA");
  219. #endif
  220. FuncArray[FUNC_ENUM_TRACE_GUIDS] = GetProcAddress(advapidll, "EnumerateTraceGuids");
  221. }
  222. }
  223. // Initialize structure first
  224. SizeNeeded = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAXSTR * sizeof(TCHAR);
  225. // end_sdk
  226. SizeNeeded += MAXENABLEFLAGS * sizeof(ULONG); // for extension enable flags
  227. // begin_sdk
  228. pLoggerInfo = (PEVENT_TRACE_PROPERTIES) malloc(SizeNeeded);
  229. if (pLoggerInfo == NULL) {
  230. if (advapidll != NULL)
  231. FreeLibrary(advapidll);
  232. return (ERROR_OUTOFMEMORY);
  233. }
  234. RtlZeroMemory(pLoggerInfo, SizeNeeded);
  235. pLoggerInfo->Wnode.BufferSize = SizeNeeded;
  236. pLoggerInfo->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  237. pLoggerInfo->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  238. pLoggerInfo->LogFileNameOffset = pLoggerInfo->LoggerNameOffset + MAXSTR * sizeof(TCHAR);
  239. LoggerName = (LPTSTR)((char*)pLoggerInfo + pLoggerInfo->LoggerNameOffset);
  240. LogFileName = (LPTSTR)((char*)pLoggerInfo + pLoggerInfo->LogFileNameOffset);
  241. _tcscpy(LoggerName, KERNEL_LOGGER_NAME);
  242. Space = (char*) malloc( (MAXGUIDS * sizeof(GuidArray)) +
  243. (MAXGUIDS * sizeof(GUID) ));
  244. if (Space == NULL) {
  245. free(pLoggerInfo);
  246. if (advapidll != NULL)
  247. FreeLibrary(advapidll);
  248. return(ERROR_OUTOFMEMORY);
  249. }
  250. save = Space;
  251. GuidArray = (LPGUID *) Space;
  252. Space += MAXGUIDS * sizeof(GuidArray);
  253. for (GuidCount=0; GuidCount<MAXGUIDS; GuidCount++) {
  254. GuidArray[GuidCount] = (LPGUID) Space;
  255. Space += sizeof(GUID);
  256. }
  257. GuidCount = 0;
  258. #ifdef UNICODE
  259. if ((targv = CommandLineToArgvW(
  260. GetCommandLineW(), // pointer to a command-line string
  261. &argc // receives the argument count
  262. )) == NULL) {
  263. free(pLoggerInfo);
  264. free(save);
  265. if (advapidll != NULL)
  266. FreeLibrary(advapidll);
  267. return (GetLastError());
  268. };
  269. utargv = targv;
  270. #else
  271. targv = argv;
  272. #endif
  273. pFlags = &pLoggerInfo->EnableFlags;
  274. //
  275. // Add default flags. Should consider options to control this independently
  276. //
  277. while (--argc > 0) {
  278. ++targv;
  279. if (**targv == '-' || **targv == '/') { // argument found
  280. if(targv[0][0] == '/' ) targv[0][0] = '-';
  281. if (!_tcsicmp(targv[0], _T("-start"))) {
  282. Action = ACTION_START;
  283. if (argc > 1) {
  284. if (targv[1][0] != '-' && targv[1][0] != '/') {
  285. ++targv; --argc;
  286. _tcscpy(LoggerName, targv[0]);
  287. }
  288. }
  289. }
  290. else if (!_tcsicmp(targv[0], _T("-enable"))) {
  291. Action = ACTION_ENABLE;
  292. if (argc > 1) {
  293. if (targv[1][0] != '-' && targv[1][0] != '/') {
  294. ++targv; --argc;
  295. _tcscpy(LoggerName, targv[0]);
  296. }
  297. }
  298. }
  299. else if (!_tcsicmp(targv[0], _T("-disable"))) {
  300. Action = ACTION_ENABLE;
  301. bEnable = FALSE;
  302. if (argc > 1) {
  303. if (targv[1][0] != '-' && targv[1][0] != '/') {
  304. ++targv; --argc;
  305. _tcscpy(LoggerName, targv[0]);
  306. }
  307. }
  308. }
  309. else if (!_tcsicmp(targv[0], _T("-stop"))) {
  310. Action = ACTION_STOP;
  311. if (argc > 1) {
  312. if (targv[1][0] != '-' && targv[1][0] != '/') {
  313. ++targv; --argc;
  314. _tcscpy(LoggerName, targv[0]);
  315. }
  316. }
  317. }
  318. else if (!_tcsicmp(targv[0], _T("-update"))) {
  319. Action = ACTION_UPDATE;
  320. if (argc > 1) {
  321. if (targv[1][0] != '-' && targv[1][0] != '/') {
  322. ++targv; --argc;
  323. _tcscpy(LoggerName, targv[0]);
  324. }
  325. }
  326. }
  327. // end_sdk
  328. else if (!_tcsicmp(targv[0], _T("-remove"))) {
  329. Action = ACTION_REMOVE;
  330. if (argc > 1) {
  331. if (targv[1][0] != '-' && targv[1][0] != '/') {
  332. ++targv; --argc;
  333. _tcscpy(LoggerName, targv[0]);
  334. }
  335. }
  336. // if it is not GlobalLogger, nothing happens.
  337. }
  338. // begin_sdk
  339. else if (!_tcsicmp(targv[0], _T("-q"))) {
  340. Action = ACTION_QUERY;
  341. if (argc > 1) {
  342. if (targv[1][0] != '-' && targv[1][0] != '/') {
  343. ++targv; --argc;
  344. _tcscpy(LoggerName, targv[0]);
  345. }
  346. }
  347. }
  348. else if (!_tcsicmp(targv[0], _T("-flush"))) {
  349. Action = ACTION_FLUSH;
  350. if (argc > 1) {
  351. if (targv[1][0] != '-' && targv[1][0] != '/') {
  352. ++targv; --argc;
  353. _tcscpy(LoggerName, targv[0]);
  354. }
  355. }
  356. }
  357. else if (!_tcsicmp(targv[0], _T("-enumguid"))) {
  358. Action = ACTION_ENUM_GUID;
  359. }
  360. else if (!_tcsicmp(targv[0], _T("-f"))) {
  361. if (argc > 1) {
  362. if (Whistler)
  363. _tcscpy(LogFileName, targv[1]);
  364. else
  365. _tfullpath(LogFileName, targv[1], MAXSTR);
  366. _tcscpy(tstrLogFileName, targv[1]);
  367. ++targv; --argc;
  368. // _tprintf(_T("Setting log file to: %s\n"), LogFileName);
  369. }
  370. }
  371. else if (!_tcsicmp(targv[0], _T("-append"))) {
  372. // _tprintf(_T("Appending log file: %s\n"), LogFileName);
  373. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_APPEND;
  374. }
  375. else if (!_tcsicmp(targv[0], _T("-prealloc"))) {
  376. // _tprintf(_T("Preallocating log file: %s\n"), LogFileName);
  377. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_PREALLOCATE;
  378. }
  379. else if (!_tcsicmp(targv[0], _T("-guid"))) {
  380. if (argc > 1) {
  381. if (targv[1][0] == _T('#')) {
  382. StringToGuid(&targv[1][1], GuidArray[0]);
  383. ++targv; --argc;
  384. GuidCount = 1;
  385. }
  386. else if (targv[1][0] != '-' && targv[1][0] != '/') {
  387. _tfullpath(GuidFile, targv[1], MAXSTR);
  388. ++targv; --argc;
  389. // _tprintf(_T("Getting guids from %s\n"), GuidFile);
  390. GuidCount = GetGuids(GuidFile, GuidArray);
  391. if (GuidCount < 0) {
  392. _tprintf( _T("Error: %s does no exist\n"), GuidFile );
  393. }
  394. else if (GuidCount == 0){
  395. _tprintf( _T("Error: %s is invalid\n"), GuidFile );
  396. Status = ERROR_INVALID_PARAMETER;
  397. goto CleanupExit;
  398. }
  399. }
  400. }
  401. }
  402. // end_sdk
  403. else if (!_tcsicmp(targv[0], _T("-UsePerfCounter"))) {
  404. pLoggerInfo->Wnode.ClientContext = 1;
  405. }
  406. else if (!_tcsicmp(targv[0], _T("-UseSystemTime"))) {
  407. pLoggerInfo->Wnode.ClientContext = 2;
  408. }
  409. else if (!_tcsicmp(targv[0], _T("-UseCPUCycle"))) {
  410. pLoggerInfo->Wnode.ClientContext = 3;
  411. }
  412. // begin_sdk
  413. else if (!_tcsicmp(targv[0], _T("-seq"))) {
  414. if (argc > 1) {
  415. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_SEQUENTIAL;
  416. pLoggerInfo->MaximumFileSize = _ttoi(targv[1]);
  417. ++targv; --argc;
  418. // _tprintf(_T("Setting maximum sequential logfile size to: %d\n"),
  419. // pLoggerInfo->MaximumFileSize);
  420. }
  421. }
  422. else if (!_tcsicmp(targv[0], _T("-newfile"))) {
  423. if (argc > 1) {
  424. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_NEWFILE;
  425. pLoggerInfo->MaximumFileSize = _ttoi(targv[1]);
  426. ++targv; --argc;
  427. // _tprintf(_T("Setting maximum logfile size to: %d\n"),
  428. // pLoggerInfo->MaximumFileSize);
  429. }
  430. }
  431. else if (!_tcsicmp(targv[0], _T("-cir"))) {
  432. if (argc > 1) {
  433. pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_CIRCULAR;
  434. pLoggerInfo->MaximumFileSize = _ttoi(targv[1]);
  435. ++targv; --argc;
  436. // _tprintf(_T("Setting maximum circular logfile size to: %d\n"),
  437. // pLoggerInfo->MaximumFileSize);
  438. }
  439. }
  440. else if (!_tcsicmp(targv[0], _T("-b"))) {
  441. if (argc > 1) {
  442. pLoggerInfo->BufferSize = _ttoi(targv[1]);
  443. ++targv; --argc;
  444. // _tprintf(_T("Changing buffer size to %d\n"),
  445. // pLoggerInfo->BufferSize);
  446. }
  447. }
  448. else if (!_tcsicmp(targv[0], _T("-flag")) || !_tcsicmp(targv[0], _T("-flags"))) {
  449. if (argc > 1) {
  450. if (targv[1][1] == _T('x') || targv[1][1] == _T('X')) {
  451. pLoggerInfo->EnableFlags |= ahextoi(targv[1]);
  452. } else {
  453. pLoggerInfo->EnableFlags |= _ttoi(targv[1]);
  454. }
  455. iFlags = pLoggerInfo->EnableFlags ; // Copy for EnableTrace
  456. ++targv; --argc;
  457. // Do not accept flags with MSB = 1.
  458. if (0x80000000 & pLoggerInfo->EnableFlags) {
  459. _tprintf(_T("Invalid Flags: 0x%0X(%d.)\n"),
  460. pLoggerInfo->EnableFlags, pLoggerInfo->EnableFlags);
  461. Status = ERROR_INVALID_PARAMETER;
  462. goto CleanupExit;
  463. }
  464. // _tprintf(_T("Setting logger flags to 0x%0X(%d.)\n"),
  465. // pLoggerInfo->EnableFlags, pLoggerInfo->EnableFlags );
  466. }
  467. }
  468. // end_sdk
  469. else if (!_tcsicmp(targv[0], _T("-eflag"))) {
  470. if (argc > 2) {
  471. USHORT nFlag = (USHORT) _ttoi(targv[1]);
  472. USHORT i, offset;
  473. PTRACE_ENABLE_FLAG_EXTENSION FlagExt;
  474. ++targv; --argc;
  475. if (nFlag > MAXENABLEFLAGS || nFlag < 1) {
  476. _tprintf(_T("Error: Invalid number of enable flags\n"));
  477. Status = ERROR_INVALID_PARAMETER;
  478. goto CleanupExit;
  479. }
  480. offset = (USHORT)
  481. (SizeNeeded - (sizeof(ULONG) * MAXENABLEFLAGS));
  482. pLoggerInfo->EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
  483. FlagExt = (PTRACE_ENABLE_FLAG_EXTENSION)
  484. &pLoggerInfo->EnableFlags;
  485. FlagExt->Offset = offset;
  486. FlagExt->Length = (UCHAR) nFlag;
  487. pFlags = (PULONG) ( offset + (PCHAR) pLoggerInfo );
  488. for (i=0; i<nFlag && argc > 1; i++) {
  489. if (targv[1][0] == '/' || targv[1][0] == '-') {
  490. // Correct the number of eflags when the user
  491. // types an incorrect number.
  492. // However, this does not work if the next
  493. // argument is Logger Name.
  494. break;
  495. }
  496. pFlags[i] = ahextoi(targv[1]);
  497. ++targv; --argc;
  498. // _tprintf(_T("Setting logger flags to 0x%0X(%d.)\n"),
  499. // pFlags[i], pFlags[i] );
  500. }
  501. nFlag = i;
  502. for ( ; i < MAXENABLEFLAGS; i++) {
  503. pFlags[i] = 0;
  504. }
  505. if (FlagExt->Length != (UCHAR)nFlag) {
  506. // _tprintf(_T("Correcting the number of eflags to %d\n"), i),
  507. FlagExt->Length = (UCHAR)nFlag;
  508. }
  509. }
  510. }
  511. else if (!_tcsicmp(targv[0], _T("-pids"))) {
  512. if (argc > 2) {
  513. USHORT nFlag = (USHORT) _ttoi(targv[1]);
  514. USHORT i, offset;
  515. PTRACE_ENABLE_FLAG_EXTENSION FlagExt;
  516. ++targv; --argc;
  517. if (nFlag > MAXENABLEFLAGS || nFlag < 1) {
  518. _tprintf(_T("Error: Invalid number of enable flags\n"));
  519. Status = ERROR_INVALID_PARAMETER;
  520. goto CleanupExit;
  521. }
  522. offset = (USHORT)
  523. (SizeNeeded - (sizeof(ULONG) * MAXENABLEFLAGS));
  524. pLoggerInfo->EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
  525. FlagExt = (PTRACE_ENABLE_FLAG_EXTENSION)
  526. &pLoggerInfo->EnableFlags;
  527. FlagExt->Offset = offset;
  528. FlagExt->Length = (UCHAR) nFlag;
  529. pFlags = (PULONG) ( offset + (PCHAR) pLoggerInfo );
  530. for (i=0; i<nFlag && argc > 1; i++) {
  531. if (targv[1][0] == '/' || targv[1][0] == '-') {
  532. // Correct the number of eflags when the user
  533. // types an incorrect number.
  534. // However, this does not work if the next
  535. // argument is Logger Name.
  536. break;
  537. }
  538. pFlags[i] = _ttol((PTCHAR)targv[1]);
  539. ++targv; --argc;
  540. // _tprintf(_T("Setting logger flags to 0x%0X(%d.)\n"),
  541. // pFlags[i], pFlags[i] );
  542. }
  543. nFlag = i;
  544. for ( ; i < MAXENABLEFLAGS; i++) {
  545. pFlags[i] = 0;
  546. }
  547. if (FlagExt->Length != (UCHAR)nFlag) {
  548. // _tprintf(_T("Correcting the number of eflags to %d\n"), i),
  549. FlagExt->Length = (UCHAR)nFlag;
  550. }
  551. }
  552. }
  553. else if (!_tcsicmp(targv[0],_T("-ls"))) {
  554. pLoggerInfo->LogFileMode |= EVENT_TRACE_USE_LOCAL_SEQUENCE ;
  555. }
  556. else if (!_tcsicmp(targv[0],_T("-gs"))) {
  557. pLoggerInfo->LogFileMode |= EVENT_TRACE_USE_GLOBAL_SEQUENCE ;
  558. }
  559. // begin_sdk
  560. else if (!_tcsicmp(targv[0], _T("-min"))) {
  561. if (argc > 1) {
  562. pLoggerInfo->MinimumBuffers = _ttoi(targv[1]);
  563. ++targv; --argc;
  564. // _tprintf(_T("Changing Minimum Number of Buffers to %d\n"),
  565. // pLoggerInfo->MinimumBuffers);
  566. }
  567. }
  568. else if (!_tcsicmp(targv[0], _T("-max"))) {
  569. if (argc > 1) {
  570. pLoggerInfo->MaximumBuffers = _ttoi(targv[1]);
  571. ++targv; --argc;
  572. // _tprintf(_T("Changing Maximum Number of Buffers to %d\n"),
  573. // pLoggerInfo->MaximumBuffers);
  574. }
  575. }
  576. else if (!_tcsicmp(targv[0], _T("-level"))) {
  577. if (argc > 1) {
  578. iLevel = _ttoi(targv[1]);
  579. ++targv; --argc;
  580. // _tprintf(_T("Setting tracing level to %d\n"), iLevel);
  581. }
  582. }
  583. else if (!_tcsicmp(targv[0], _T("-ft"))) {
  584. if (argc > 1) {
  585. pLoggerInfo->FlushTimer = _ttoi(targv[1]);
  586. ++targv; --argc;
  587. // _tprintf(_T("Setting buffer flush timer to %d seconds\n"),
  588. // pLoggerInfo->FlushTimer);
  589. }
  590. }
  591. else if (!_tcsicmp(targv[0], _T("-um"))) {
  592. pLoggerInfo->LogFileMode |= EVENT_TRACE_PRIVATE_LOGGER_MODE;
  593. // _tprintf(_T("Setting Private Logger Flags\n"));
  594. }
  595. else if (!_tcsicmp(targv[0], _T("-paged"))) {
  596. pLoggerInfo->LogFileMode |= EVENT_TRACE_USE_PAGED_MEMORY;
  597. // _tprintf(_T("Setting Paged Memory Flag\n"));
  598. }
  599. else if (!_tcsicmp(targv[0], _T("-rt"))) {
  600. pLoggerInfo->LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
  601. // _tprintf(_T("Setting real time mode\n"));
  602. // end_sdk
  603. if (argc > 1) {
  604. if (targv[1][0] != '-' && targv[1][0] != '/') {
  605. ++targv; --argc;
  606. if (targv[0][0] == 'b')
  607. pLoggerInfo->LogFileMode |= EVENT_TRACE_BUFFERING_MODE;
  608. }
  609. }
  610. // begin_sdk
  611. }
  612. else if (!_tcsicmp(targv[0], _T("-age"))) {
  613. if (argc > 1) {
  614. pLoggerInfo->AgeLimit = _ttoi(targv[1]);
  615. ++targv; --argc;
  616. // _tprintf(_T("Changing Aging Decay Time to %d\n"),
  617. // pLoggerInfo->AgeLimit);
  618. }
  619. }
  620. else if (!_tcsicmp(targv[0], _T("-l"))) {
  621. Action = ACTION_LIST;
  622. bKill = FALSE;
  623. }
  624. else if (!_tcsicmp(targv[0], _T("-x"))) {
  625. Action = ACTION_LIST;
  626. bKill = TRUE;
  627. }
  628. else if (!_tcsicmp(targv[0], _T("-xf"))) {
  629. Action = ACTION_LIST;
  630. bKill = TRUE;
  631. bForceKill = TRUE ;
  632. }
  633. else if (!_tcsicmp(targv[0], _T("-noprocess"))) {
  634. bProcess = FALSE;
  635. }
  636. else if (!_tcsicmp(targv[0], _T("-nothread"))) {
  637. bThread = FALSE;
  638. }
  639. else if (!_tcsicmp(targv[0], _T("-nodisk"))) {
  640. bDisk = FALSE;
  641. }
  642. else if (!_tcsicmp(targv[0], _T("-nonet"))) {
  643. bNetwork = FALSE;
  644. }
  645. else if (!_tcsicmp(targv[0], _T("-fio"))) {
  646. if (pFlags == &pLoggerInfo->EnableFlags) {
  647. *pFlags |= EVENT_TRACE_FLAG_DISK_FILE_IO;
  648. }
  649. else {
  650. _tprintf(_T("Option -fio cannot be used with -eflags. Ignored\n"));
  651. }
  652. }
  653. else if (!_tcsicmp(targv[0], _T("-pf"))) {
  654. if (pFlags == &pLoggerInfo->EnableFlags) {
  655. *pFlags |= EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS;
  656. }
  657. else {
  658. _tprintf(_T("Option -pf cannot be used with -eflags. Ignored\n"));
  659. }
  660. }
  661. else if (!_tcsicmp(targv[0], _T("-hf"))) {
  662. if (pFlags == &pLoggerInfo->EnableFlags) {
  663. *pFlags |= EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS;
  664. }
  665. else {
  666. _tprintf(_T("Option -hf cannot be used with -eflags. Ignored\n"));
  667. }
  668. }
  669. else if (!_tcsicmp(targv[0], _T("-img"))) {
  670. if (pFlags == &pLoggerInfo->EnableFlags) {
  671. *pFlags |= EVENT_TRACE_FLAG_IMAGE_LOAD;
  672. }
  673. else {
  674. _tprintf(_T("Option -img cannot be used with -eflags. Ignored\n"));
  675. }
  676. }
  677. else if (!_tcsicmp(targv[0], _T("-cm"))) {
  678. if (pFlags == &pLoggerInfo->EnableFlags) {
  679. *pFlags |= EVENT_TRACE_FLAG_REGISTRY;
  680. }
  681. else {
  682. _tprintf(_T("Option -cm cannot be used with -eflags. Ignored\n"));
  683. }
  684. }
  685. else if ( targv[0][1] == 'h' || targv[0][1] == 'H' || targv[0][1] == '?'){
  686. Action = ACTION_HELP;
  687. PrintHelpMessage();
  688. goto CleanupExit;
  689. }
  690. else Action = ACTION_UNDEFINED;
  691. }
  692. else { // get here if "-" or "/" given
  693. _tprintf(_T("Invalid option given: %s\n"), targv[0]);
  694. Status = ERROR_INVALID_PARAMETER;
  695. goto CleanupExit;
  696. }
  697. }
  698. if (!_tcscmp(LoggerName, KERNEL_LOGGER_NAME)) {
  699. if (pFlags == &pLoggerInfo->EnableFlags) {
  700. if (bProcess)
  701. *pFlags |= EVENT_TRACE_FLAG_PROCESS;
  702. if (bThread)
  703. *pFlags |= EVENT_TRACE_FLAG_THREAD;
  704. if (bDisk)
  705. *pFlags |= EVENT_TRACE_FLAG_DISK_IO;
  706. if (bNetwork)
  707. *pFlags |= EVENT_TRACE_FLAG_NETWORK_TCPIP;
  708. }
  709. pLoggerInfo->Wnode.Guid = SystemTraceControlGuid; // defaults to OS
  710. specialLogger = 1;
  711. }
  712. // end_sdk
  713. if (!_tcscmp(LoggerName, GLOBAL_LOGGER)) {
  714. pLoggerInfo->Wnode.Guid = GlobalLoggerGuid;
  715. specialLogger = 3;
  716. }
  717. else if (!_tcscmp(LoggerName, EVENT_LOGGER)) {
  718. pLoggerInfo->Wnode.Guid = WmiEventLoggerGuid;
  719. specialLogger = 2;
  720. }
  721. // begin_sdk
  722. if ( !(pLoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) ) {
  723. if (specialLogger != 3 && _tcslen(LogFileName) <= 0 && Action == ACTION_START) {
  724. _tcscpy(LogFileName, DEFAULT_LOGFILE_NAME); // for now...
  725. _tcscpy(tstrLogFileName, DEFAULT_LOGFILE_NAME);
  726. }
  727. }
  728. switch (Action) {
  729. case ACTION_START:
  730. {
  731. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  732. if (GuidCount != 1) {
  733. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  734. Status = ERROR_INVALID_PARAMETER;
  735. break;
  736. }
  737. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  738. }
  739. if (pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_PREALLOCATE &&
  740. pLoggerInfo->MaximumFileSize == 0) {
  741. _tprintf(_T("Need file size for preallocated log file\n"));
  742. Status = ERROR_INVALID_PARAMETER;
  743. break;
  744. }
  745. // end_sdk
  746. if (specialLogger == 3) { // Global Logger
  747. Status = SetGlobalLoggerSettings(1L, pLoggerInfo, pLoggerInfo->Wnode.ClientContext);
  748. if (Status != ERROR_SUCCESS)
  749. break;
  750. Status = GetGlobalLoggerSettings(pLoggerInfo, &pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
  751. break;
  752. }
  753. // begin_sdk
  754. if(pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_EXTENSION){
  755. if(IsEqualGUID(&CritSecGuid,GuidArray[0]) ||
  756. IsEqualGUID(&HeapGuid,GuidArray[0])){
  757. pLoggerInfo->Wnode.HistoricalContext = iLevel;
  758. }
  759. }
  760. Status = StartTrace(&LoggerHandle, LoggerName, pLoggerInfo);
  761. if (Status != ERROR_SUCCESS) {
  762. _tprintf(_T("Could not start logger: %s\n")
  763. _T("Operation Status: %uL\n")
  764. _T("%s\n"),
  765. LoggerName,
  766. Status,
  767. DecodeStatus(Status));
  768. break;
  769. }
  770. _tprintf(_T("Logger Started...\n"));
  771. case ACTION_ENABLE:
  772. if (Action == ACTION_ENABLE ){
  773. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE)
  774. {
  775. if (GuidCount != 1)
  776. {
  777. _tprintf(_T("Need one GUID for PRIVATE loggers\n"));
  778. Status = ERROR_INVALID_PARAMETER;
  779. break;
  780. }
  781. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  782. }
  783. Status = ControlTrace((TRACEHANDLE) 0, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  784. if( Status != ERROR_SUCCESS ){
  785. if( Status != ERROR_SUCCESS ){
  786. if( IsEqualGUID(&HeapGuid,&pLoggerInfo->Wnode.Guid)
  787. || IsEqualGUID(&CritSecGuid,&pLoggerInfo->Wnode.Guid)
  788. ){
  789. //do nothing
  790. } else {
  791. _tprintf( _T("ERROR: Logger not started\n")
  792. _T("Operation Status: %uL\n")
  793. _T("%s\n"),
  794. Status,
  795. DecodeStatus(Status));
  796. break;
  797. }
  798. }
  799. }
  800. LoggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  801. }
  802. if ( (GuidCount > 0) && (specialLogger == 0)) {
  803. _tprintf(_T("Enabling trace to logger %d\n"), LoggerHandle);
  804. for (i=0; i<(ULONG)GuidCount; i++) {
  805. Status = EnableTrace (
  806. bEnable,
  807. iFlags,
  808. iLevel,
  809. GuidArray[i],
  810. LoggerHandle);
  811. //
  812. // If the Guid can not be enabled, it is a benign
  813. // failure. Print Warning message and continue.
  814. //
  815. if (Status == 4317) {
  816. _tprintf(_T("WARNING: Could not enable some guids.\n"));
  817. _tprintf(_T("Check your Guids file\n"));
  818. Status = ERROR_SUCCESS;
  819. }
  820. if (Status != ERROR_SUCCESS) {
  821. _tprintf(_T("ERROR: Failed to enable Guid [%d]...\n"), i);
  822. _tprintf(_T("Operation Status: %uL\n"), Status);
  823. _tprintf(_T("%s\n"),DecodeStatus(Status));
  824. break;
  825. }
  826. }
  827. }
  828. else {
  829. if (GuidCount > 0) {
  830. _tprintf(_T("ERROR: System Logger does not accept application guids...\n"));
  831. Status = ERROR_INVALID_PARAMETER;
  832. }
  833. }
  834. break;
  835. }
  836. case ACTION_STOP :
  837. LoggerHandle = (TRACEHANDLE) 0;
  838. Status = ERROR_SUCCESS;
  839. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  840. if (GuidCount != 1) {
  841. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  842. Status = ERROR_INVALID_PARAMETER;
  843. break;
  844. }
  845. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  846. }
  847. // end_sdk
  848. if (specialLogger == 3)
  849. Status = GetGlobalLoggerSettings(pLoggerInfo, &pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
  850. // begin_sdk
  851. if (specialLogger != 0) {
  852. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  853. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  854. if (Status != ERROR_SUCCESS)
  855. break;
  856. LoggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  857. Status = EnableTrace( FALSE,
  858. EVENT_TRACE_PRIVATE_LOGGER_MODE,
  859. 0,
  860. GuidArray[0],
  861. LoggerHandle );
  862. }
  863. else {
  864. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  865. if (Status == ERROR_WMI_INSTANCE_NOT_FOUND)
  866. break;
  867. LoggerHandle = pLoggerInfo->Wnode.HistoricalContext;
  868. for (i=0; i<(ULONG)GuidCount; i++) {
  869. Status = EnableTrace( FALSE,
  870. 0,
  871. 0,
  872. GuidArray[i],
  873. LoggerHandle);
  874. }
  875. }
  876. }
  877. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_STOP);
  878. break;
  879. // end_sdk
  880. case ACTION_REMOVE :
  881. if (specialLogger == 3) { // Global Logger
  882. Status = SetGlobalLoggerSettings(0L, pLoggerInfo, pLoggerInfo->Wnode.ClientContext);
  883. if (Status != ERROR_SUCCESS)
  884. break;
  885. Status = GetGlobalLoggerSettings(pLoggerInfo, &pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
  886. if (Status != ERROR_SUCCESS)
  887. break;
  888. }
  889. break;
  890. // begin_sdk
  891. case ACTION_LIST :
  892. {
  893. ULONG i, returnCount ;
  894. ULONG SizeNeeded;
  895. PEVENT_TRACE_PROPERTIES pLoggerInfo[MAXIMUM_LOGGERS];
  896. PEVENT_TRACE_PROPERTIES pStorage;
  897. PVOID Storage;
  898. SizeNeeded = MAXIMUM_LOGGERS * (sizeof(EVENT_TRACE_PROPERTIES)
  899. + 2 * MAXSTR * sizeof(TCHAR));
  900. Storage = malloc(SizeNeeded);
  901. if (Storage == NULL) {
  902. Status = ERROR_OUTOFMEMORY;
  903. break;
  904. }
  905. RtlZeroMemory(Storage, SizeNeeded);
  906. pStorage = (PEVENT_TRACE_PROPERTIES)Storage;
  907. for (i=0; i<MAXIMUM_LOGGERS; i++) {
  908. pStorage->Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES)
  909. + 2 * MAXSTR * sizeof(TCHAR);
  910. pStorage->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES)
  911. + MAXSTR * sizeof(TCHAR);
  912. pStorage->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  913. pLoggerInfo[i] = pStorage;
  914. pStorage = (PEVENT_TRACE_PROPERTIES) (
  915. (char*)pStorage +
  916. pStorage->Wnode.BufferSize);
  917. }
  918. Status = QueryAllTraces(pLoggerInfo,
  919. MAXIMUM_LOGGERS,
  920. & returnCount);
  921. if (Status == ERROR_SUCCESS)
  922. {
  923. for (j= 0; j < returnCount; j++)
  924. {
  925. LPTSTR LoggerName;
  926. TCHAR asked = _T('?') ;
  927. BOOL StatusPrint = FALSE ;
  928. if (bKill)
  929. {
  930. LoggerName = (LPTSTR) ((char*)pLoggerInfo[j] +
  931. pLoggerInfo[j]->LoggerNameOffset);
  932. if (!bForceKill) {
  933. while (!(asked == _T('y')) && !(asked == _T('n'))) {
  934. _tprintf(_T("Do you want to kill Logger \"%s\" (Y or N)?"),LoggerName);
  935. _tscanf(_T(" %c"),&asked);
  936. if (asked == _T('Y')) {
  937. asked = _T('y') ;
  938. } else if (asked == _T('N')) {
  939. asked = _T('n') ;
  940. }
  941. }
  942. } else {
  943. asked = _T('y');
  944. }
  945. if (asked == _T('y')) {
  946. if (!IsEqualGUID(& pLoggerInfo[j]->Wnode.Guid,
  947. & SystemTraceControlGuid))
  948. {
  949. LoggerHandle = pLoggerInfo[j]->Wnode.HistoricalContext;
  950. Status = EnableTrace(
  951. FALSE,
  952. (pLoggerInfo[j]->LogFileMode &
  953. EVENT_TRACE_PRIVATE_LOGGER_MODE)
  954. ? (EVENT_TRACE_PRIVATE_LOGGER_MODE)
  955. : (0),
  956. 0,
  957. & pLoggerInfo[j]->Wnode.Guid,
  958. LoggerHandle);
  959. }
  960. Status = ControlTrace((TRACEHANDLE) 0,
  961. LoggerName,
  962. pLoggerInfo[j],
  963. EVENT_TRACE_CONTROL_STOP);
  964. _tprintf(_T("Logger \"%s\" has been killed\n"),LoggerName);
  965. StatusPrint = TRUE ;
  966. } else {
  967. _tprintf(_T("Logger \"%s\" has not been killed, current Status is\n"),LoggerName);
  968. StatusPrint = FALSE ;
  969. }
  970. }
  971. PrintLoggerStatus(pLoggerInfo[j],
  972. // end_sdk
  973. 0,
  974. // begin_sdk
  975. Status,
  976. StatusPrint);
  977. _tprintf(_T("\n"));
  978. }
  979. }
  980. i = 0;
  981. free(Storage);
  982. break;
  983. }
  984. case ACTION_UPDATE :
  985. case ACTION_FLUSH :
  986. case ACTION_QUERY :
  987. if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
  988. if (GuidCount != 1) {
  989. _tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
  990. Status = ERROR_INVALID_PARAMETER;
  991. break;
  992. }
  993. pLoggerInfo->Wnode.Guid = *GuidArray[0];
  994. }
  995. if (Action == ACTION_QUERY) {
  996. // end_sdk
  997. if (specialLogger == 3) {
  998. Status = GetGlobalLoggerSettings(pLoggerInfo, &pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
  999. }
  1000. // begin_sdk
  1001. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
  1002. }
  1003. else if (Action == ACTION_UPDATE) {
  1004. // end_sdk
  1005. if (specialLogger == 3) {
  1006. Status = GetGlobalLoggerSettings(pLoggerInfo, &pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
  1007. }
  1008. // begin_sdk
  1009. Status = ControlTrace(LoggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_UPDATE);
  1010. }
  1011. else if (Action == ACTION_FLUSH) {
  1012. // Since FlushTrace is not implemented on Win2K, use the function pointer
  1013. // loaded from advapi32.dll separately.
  1014. // Originally, this block had one line:
  1015. // Status = FlushTrace(LoggerHandle, LoggerName, pLoggerInfo);
  1016. if (FuncArray[FUNC_FLUSH_TRACE] == NULL) {
  1017. _tprintf(_T("Flush Trace is not supported on this system\n"));
  1018. Status = ERROR_INVALID_PARAMETER;
  1019. break;
  1020. }
  1021. Status = (ULONG)(*FuncArray[FUNC_FLUSH_TRACE])(LoggerHandle, LoggerName, pLoggerInfo);
  1022. }
  1023. break;
  1024. case ACTION_ENUM_GUID:
  1025. {
  1026. ULONG i;
  1027. ULONG PropertyArrayCount=10;
  1028. PTRACE_GUID_PROPERTIES *GuidPropertiesArray;
  1029. ULONG GuidCount;
  1030. ULONG SizeStorage;
  1031. PVOID StorageNeeded;
  1032. PTRACE_GUID_PROPERTIES CleanStorage;
  1033. TCHAR str[MAXSTR];
  1034. // Since EnumTraceGuids is not implemented on Win2K, use the function pointer
  1035. // loaded from advapi32.dll separately.
  1036. if (FuncArray[FUNC_ENUM_TRACE_GUIDS] == NULL) {
  1037. _tprintf(_T("Enumerating trace GUIDS is not supported on this system\n"));
  1038. Status = ERROR_INVALID_PARAMETER;
  1039. break;
  1040. }
  1041. Retry:
  1042. SizeStorage = PropertyArrayCount * (sizeof(TRACE_GUID_PROPERTIES) + sizeof(PTRACE_GUID_PROPERTIES));
  1043. StorageNeeded = malloc(SizeStorage);
  1044. if (StorageNeeded== NULL) {
  1045. Status = ERROR_OUTOFMEMORY;
  1046. break;
  1047. }
  1048. RtlZeroMemory(StorageNeeded, SizeStorage);
  1049. GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)StorageNeeded;
  1050. CleanStorage = (PTRACE_GUID_PROPERTIES)((char*)StorageNeeded + PropertyArrayCount * sizeof(PTRACE_GUID_PROPERTIES));
  1051. for (i=0; i < PropertyArrayCount; i++) {
  1052. GuidPropertiesArray[i] = CleanStorage;
  1053. CleanStorage = (PTRACE_GUID_PROPERTIES) (
  1054. (char*)CleanStorage + sizeof(TRACE_GUID_PROPERTIES)
  1055. );
  1056. }
  1057. // Use function pointer for EnumTraceGuids
  1058. Status = (ULONG)(*FuncArray[FUNC_ENUM_TRACE_GUIDS])(GuidPropertiesArray,PropertyArrayCount,&GuidCount);
  1059. if(Status == ERROR_MORE_DATA)
  1060. {
  1061. PropertyArrayCount=GuidCount;
  1062. free(StorageNeeded);
  1063. goto Retry;
  1064. }
  1065. //
  1066. // print the GUID_PROPERTIES and Free Strorage
  1067. //
  1068. _tprintf(_T(" Guid Enabled LoggerId Level Flags\n"));
  1069. _tprintf(_T("------------------------------------------------------------\n"));
  1070. for (i=0; i < GuidCount; i++) {
  1071. _tprintf(_T("%s %5s %d %d %d\n"),
  1072. GuidToString(&str[0],&GuidPropertiesArray[i]->Guid),
  1073. (GuidPropertiesArray[i]->IsEnable) ? _T("TRUE") : _T("FALSE"),
  1074. GuidPropertiesArray[i]->LoggerId,
  1075. GuidPropertiesArray[i]->EnableLevel,
  1076. GuidPropertiesArray[i]->EnableFlags
  1077. );
  1078. }
  1079. free(StorageNeeded);
  1080. }
  1081. break;
  1082. case ACTION_HELP:
  1083. PrintHelpMessage();
  1084. break;
  1085. default :
  1086. _tprintf(_T("Error: no action specified\n"));
  1087. PrintHelpMessage();
  1088. break;
  1089. }
  1090. if ((Action != ACTION_HELP) && (Action != ACTION_ENUM_GUID)
  1091. && (Action != ACTION_UNDEFINED) && (Action != ACTION_LIST))
  1092. PrintLoggerStatus(pLoggerInfo,
  1093. // end_sdk
  1094. GlobalLoggerStartValue,
  1095. // begin_sdk
  1096. Status,
  1097. PRINTSTATUS);
  1098. CleanupExit:
  1099. SetLastError(Status);
  1100. if (utargv != NULL) {
  1101. GlobalFree(utargv);
  1102. }
  1103. free(pLoggerInfo);
  1104. free(save);
  1105. if (advapidll != NULL)
  1106. FreeLibrary(advapidll);
  1107. return(Status);
  1108. }
  1109. void
  1110. PrintLoggerStatus(
  1111. IN PEVENT_TRACE_PROPERTIES LoggerInfo,
  1112. // end_sdk
  1113. IN ULONG GlobalLoggerStartValue,
  1114. // begin_sdk
  1115. IN ULONG Status,
  1116. IN BOOL PrintStatus
  1117. )
  1118. /*++
  1119. Routine Description:
  1120. Prints out the status of the specified logger.
  1121. Arguments:
  1122. LoggerInfo - The pointer to the resident EVENT_TRACE_PROPERTIES that has
  1123. the information about the current logger.
  1124. // end_sdk
  1125. GlobalLoggerStartValue - The Start value for GlobalLogger (not used if it is
  1126. not GlobalLogger).
  1127. // begin_sdk
  1128. Status - The returned status of the last executed command
  1129. or
  1130. the operation status of the current logger.
  1131. PrintStatus - Determines which type of status it is using.
  1132. Return Value:
  1133. None
  1134. --*/
  1135. {
  1136. LPTSTR LoggerName, LogFileName;
  1137. if ((LoggerInfo->LoggerNameOffset > 0) &&
  1138. (LoggerInfo->LoggerNameOffset < LoggerInfo->Wnode.BufferSize)) {
  1139. LoggerName = (LPTSTR) ((char*)LoggerInfo +
  1140. LoggerInfo->LoggerNameOffset);
  1141. }
  1142. else LoggerName = NULL;
  1143. if ((LoggerInfo->LogFileNameOffset > 0) &&
  1144. (LoggerInfo->LogFileNameOffset < LoggerInfo->Wnode.BufferSize)) {
  1145. LogFileName = (LPTSTR) ((char*)LoggerInfo +
  1146. LoggerInfo->LogFileNameOffset);
  1147. }
  1148. else LogFileName = NULL;
  1149. if (PrintStatus) {
  1150. _tprintf(_T("Operation Status: %uL\t"), Status);
  1151. _tprintf(_T("%s\n"), DecodeStatus(Status));
  1152. }
  1153. _tprintf(_T("Logger Name: %s\n"),
  1154. (LoggerName == NULL) ?
  1155. _T(" ") : LoggerName);
  1156. // end_sdk
  1157. if (LoggerName == NULL || !_tcscmp(LoggerName, GLOBAL_LOGGER)) {
  1158. // Logger ID
  1159. _tprintf(_T("Status: %s\n"),
  1160. GlobalLoggerStartValue ?
  1161. _T("Registry set to start") : _T("Registry set to stop"));
  1162. _tprintf(_T("Logger Id: %I64x\n"), LoggerInfo->Wnode.HistoricalContext);
  1163. _tprintf(_T("Logger Thread Id: %p\n"), LoggerInfo->LoggerThreadId);
  1164. if (LoggerInfo->BufferSize == 0)
  1165. _tprintf(_T("Buffer Size: default value\n"));
  1166. else
  1167. _tprintf(_T("Buffer Size: %d Kb\n"), LoggerInfo->BufferSize);
  1168. if (LoggerInfo->MaximumBuffers == 0)
  1169. _tprintf(_T("Maximum Buffers: default value\n"));
  1170. else
  1171. _tprintf(_T("Maximum Buffers: %d\n"), LoggerInfo->MaximumBuffers);
  1172. if (LoggerInfo->MinimumBuffers == 0)
  1173. _tprintf(_T("Minimum Buffers: default value\n"));
  1174. else
  1175. _tprintf(_T("Minimum Buffers: %d\n"), LoggerInfo->MinimumBuffers);
  1176. _tprintf(_T("Number of Buffers: %d\n"), LoggerInfo->NumberOfBuffers);
  1177. _tprintf(_T("Free Buffers: %d\n"), LoggerInfo->FreeBuffers);
  1178. _tprintf(_T("Buffers Written: %d\n"), LoggerInfo->BuffersWritten);
  1179. _tprintf(_T("Events Lost: %d\n"), LoggerInfo->EventsLost);
  1180. _tprintf(_T("Log Buffers Lost: %d\n"), LoggerInfo->LogBuffersLost);
  1181. _tprintf(_T("Real Time Buffers Lost: %d\n"), LoggerInfo->RealTimeBuffersLost);
  1182. _tprintf(_T("AgeLimit: %d\n"), LoggerInfo->AgeLimit);
  1183. if (LogFileName == NULL) {
  1184. _tprintf(_T("Buffering Mode: "));
  1185. }
  1186. else {
  1187. _tprintf(_T("Log File Mode: "));
  1188. }
  1189. if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_APPEND) {
  1190. _tprintf(_T("Append "));
  1191. }
  1192. if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
  1193. _tprintf(_T("Circular\n"));
  1194. }
  1195. else if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  1196. _tprintf(_T("Sequential\n"));
  1197. }
  1198. else {
  1199. _tprintf(_T("Sequential\n"));
  1200. }
  1201. if (LoggerInfo->MaximumFileSize > 0)
  1202. _tprintf(_T("Maximum File Size: %d Mb\n"), LoggerInfo->MaximumFileSize);
  1203. if (LoggerInfo->FlushTimer > 0)
  1204. _tprintf(_T("Buffer Flush Timer: %d secs\n"), LoggerInfo->FlushTimer);
  1205. if (LoggerInfo->EnableFlags != 0) {
  1206. _tprintf(_T("Enabled tracing: "));
  1207. if ((LoggerName != NULL) && (!_tcscmp(LoggerName, KERNEL_LOGGER_NAME))) {
  1208. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
  1209. _tprintf(_T("Process "));
  1210. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
  1211. _tprintf(_T("Thread "));
  1212. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
  1213. _tprintf(_T("Disk "));
  1214. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
  1215. _tprintf(_T("File "));
  1216. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
  1217. _tprintf(_T("PageFaults "));
  1218. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
  1219. _tprintf(_T("HardFaults "));
  1220. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
  1221. _tprintf(_T("ImageLoad "));
  1222. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
  1223. _tprintf(_T("TcpIp "));
  1224. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_REGISTRY)
  1225. _tprintf(_T("Registry "));
  1226. }
  1227. else {
  1228. _tprintf(_T("0x%08x"), LoggerInfo->EnableFlags );
  1229. }
  1230. _tprintf(_T("\n"));
  1231. }
  1232. if (LogFileName == NULL || _tcslen(LogFileName) == 0) {
  1233. _tprintf(_T("Log Filename: default location\n"));
  1234. _tprintf(_T(" %%SystemRoot%%\\System32\\LogFiles\\WMI\\trace.log\n"));
  1235. }
  1236. else
  1237. _tprintf(_T("Log Filename: %s\n"), LogFileName);
  1238. if (LoggerInfo->LogFileMode & EVENT_TRACE_USE_LOCAL_SEQUENCE) {
  1239. _tprintf(_T("Local Sequence numbers in use\n"));
  1240. }
  1241. else if (LoggerInfo->LogFileMode & EVENT_TRACE_USE_GLOBAL_SEQUENCE) {
  1242. _tprintf(_T("Global Sequence numbers in use\n"));
  1243. }
  1244. }
  1245. else {
  1246. // begin_sdk
  1247. _tprintf(_T("Logger Id: %I64x\n"), LoggerInfo->Wnode.HistoricalContext);
  1248. _tprintf(_T("Logger Thread Id: %p\n"), LoggerInfo->LoggerThreadId);
  1249. if (Status != 0)
  1250. return;
  1251. _tprintf(_T("Buffer Size: %d Kb"), LoggerInfo->BufferSize);
  1252. if (LoggerInfo->LogFileMode & EVENT_TRACE_USE_PAGED_MEMORY) {
  1253. _tprintf(_T(" using paged memory\n"));
  1254. }
  1255. else {
  1256. _tprintf(_T("\n"));
  1257. }
  1258. _tprintf(_T("Maximum Buffers: %d\n"), LoggerInfo->MaximumBuffers);
  1259. _tprintf(_T("Minimum Buffers: %d\n"), LoggerInfo->MinimumBuffers);
  1260. _tprintf(_T("Number of Buffers: %d\n"), LoggerInfo->NumberOfBuffers);
  1261. _tprintf(_T("Free Buffers: %d\n"), LoggerInfo->FreeBuffers);
  1262. _tprintf(_T("Buffers Written: %d\n"), LoggerInfo->BuffersWritten);
  1263. _tprintf(_T("Events Lost: %d\n"), LoggerInfo->EventsLost);
  1264. _tprintf(_T("Log Buffers Lost: %d\n"), LoggerInfo->LogBuffersLost);
  1265. _tprintf(_T("Real Time Buffers Lost: %d\n"), LoggerInfo->RealTimeBuffersLost);
  1266. _tprintf(_T("AgeLimit: %d\n"), LoggerInfo->AgeLimit);
  1267. if (LogFileName == NULL) {
  1268. _tprintf(_T("Buffering Mode: "));
  1269. }
  1270. else {
  1271. _tprintf(_T("Log File Mode: "));
  1272. }
  1273. if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_APPEND) {
  1274. _tprintf(_T("Append "));
  1275. }
  1276. if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
  1277. _tprintf(_T("Circular\n"));
  1278. }
  1279. else if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  1280. _tprintf(_T("Sequential\n"));
  1281. }
  1282. else {
  1283. _tprintf(_T("Sequential\n"));
  1284. }
  1285. if (LoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) {
  1286. _tprintf(_T("Real Time mode enabled"));
  1287. // end_sdk
  1288. if (LoggerInfo->LogFileMode & EVENT_TRACE_BUFFERING_MODE) {
  1289. _tprintf(_T(": buffering only"));
  1290. }
  1291. // begin_sdk
  1292. _tprintf(_T("\n"));
  1293. }
  1294. if (LoggerInfo->MaximumFileSize > 0)
  1295. _tprintf(_T("Maximum File Size: %d Mb\n"), LoggerInfo->MaximumFileSize);
  1296. if (LoggerInfo->FlushTimer > 0)
  1297. _tprintf(_T("Buffer Flush Timer: %d secs\n"), LoggerInfo->FlushTimer);
  1298. if (LoggerInfo->EnableFlags != 0) {
  1299. _tprintf(_T("Enabled tracing: "));
  1300. if ((LoggerName != NULL) && (!_tcscmp(LoggerName, KERNEL_LOGGER_NAME))) {
  1301. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
  1302. _tprintf(_T("Process "));
  1303. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
  1304. _tprintf(_T("Thread "));
  1305. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
  1306. _tprintf(_T("Disk "));
  1307. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
  1308. _tprintf(_T("File "));
  1309. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
  1310. _tprintf(_T("PageFaults "));
  1311. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
  1312. _tprintf(_T("HardFaults "));
  1313. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
  1314. _tprintf(_T("ImageLoad "));
  1315. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
  1316. _tprintf(_T("TcpIp "));
  1317. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_REGISTRY)
  1318. _tprintf(_T("Registry "));
  1319. }else{
  1320. _tprintf(_T("0x%08x"), LoggerInfo->EnableFlags );
  1321. }
  1322. _tprintf(_T("\n"));
  1323. }
  1324. if (LogFileName != NULL) {
  1325. _tprintf(_T("Log Filename: %s\n"), LogFileName);
  1326. }
  1327. // end_sdk
  1328. if (LoggerInfo->LogFileMode & EVENT_TRACE_USE_LOCAL_SEQUENCE) {
  1329. _tprintf(_T("Local Sequence numbers in use\n"));
  1330. }
  1331. else if (LoggerInfo->LogFileMode & EVENT_TRACE_USE_GLOBAL_SEQUENCE) {
  1332. _tprintf(_T("Global Sequence numbers in use\n"));
  1333. }
  1334. }
  1335. // begin_sdk
  1336. }
  1337. LPTSTR
  1338. DecodeStatus(
  1339. IN ULONG Status
  1340. )
  1341. /*++
  1342. Routine Description:
  1343. Decodes WIN32 error into a string in the default language.
  1344. Arguments:
  1345. Status - The error status from the last executed command
  1346. or
  1347. the operation status of the current logger.
  1348. Return Value:
  1349. LPTSTR - String containing the decoded message.
  1350. --*/
  1351. {
  1352. memset( ErrorMsg, 0, MAXSTR );
  1353. FormatMessage(
  1354. FORMAT_MESSAGE_FROM_SYSTEM |
  1355. FORMAT_MESSAGE_IGNORE_INSERTS,
  1356. NULL,
  1357. Status,
  1358. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  1359. (LPTSTR) ErrorMsg,
  1360. MAXSTR,
  1361. NULL );
  1362. return ErrorMsg;
  1363. }
  1364. LONG
  1365. GetGuids(
  1366. IN LPTSTR GuidFile,
  1367. IN OUT LPGUID *GuidArray
  1368. )
  1369. /*++
  1370. Routine Description:
  1371. Reads GUIDs from a file and stores them in an GUID array.
  1372. Arguments:
  1373. GuidFile - The file containing GUIDs.
  1374. GuidArray - The GUID array that will have GUIDs read from the file.
  1375. Return Value:
  1376. ULONG - The number of GUIDs processed.
  1377. --*/
  1378. {
  1379. FILE *f;
  1380. TCHAR line[MAXSTR], arg[MAXSTR];
  1381. LPGUID Guid;
  1382. int i, n;
  1383. f = _tfopen((TCHAR*)GuidFile, _T("r"));
  1384. if (f == NULL)
  1385. return -1;
  1386. n = 0;
  1387. while ( _fgetts(line, MAXSTR, f) != NULL ) {
  1388. if (_tcslen(line) < 36)
  1389. continue;
  1390. if (line[0] == ';' ||
  1391. line[0] == '\0' ||
  1392. line[0] == '#' ||
  1393. line[0] == '/')
  1394. continue;
  1395. Guid = (LPGUID) GuidArray[n];
  1396. n ++;
  1397. _tcsncpy(arg, line, 8);
  1398. arg[8] = 0;
  1399. Guid->Data1 = ahextoi(arg);
  1400. _tcsncpy(arg, &line[9], 4);
  1401. arg[4] = 0;
  1402. Guid->Data2 = (USHORT) ahextoi(arg);
  1403. _tcsncpy(arg, &line[14], 4);
  1404. arg[4] = 0;
  1405. Guid->Data3 = (USHORT) ahextoi(arg);
  1406. for (i=0; i<2; i++) {
  1407. _tcsncpy(arg, &line[19 + (i*2)], 2);
  1408. arg[2] = 0;
  1409. Guid->Data4[i] = (UCHAR) ahextoi(arg);
  1410. }
  1411. for (i=2; i<8; i++) {
  1412. _tcsncpy(arg, &line[20 + (i*2)], 2);
  1413. arg[2] = 0;
  1414. Guid->Data4[i] = (UCHAR) ahextoi(arg);
  1415. }
  1416. }
  1417. return (ULONG)n;
  1418. }
  1419. ULONG
  1420. ahextoi(
  1421. IN TCHAR *s
  1422. )
  1423. /*++
  1424. Routine Description:
  1425. Converts a hex string into a number.
  1426. Arguments:
  1427. s - A hex string in TCHAR.
  1428. Return Value:
  1429. ULONG - The number in the string.
  1430. --*/
  1431. {
  1432. int len;
  1433. ULONG num, base, hex;
  1434. len = _tcslen(s);
  1435. hex = 0; base = 1; num = 0;
  1436. while (--len >= 0) {
  1437. if ( (s[len] == 'x' || s[len] == 'X') &&
  1438. (s[len-1] == '0') )
  1439. break;
  1440. if (s[len] >= '0' && s[len] <= '9')
  1441. num = s[len] - '0';
  1442. else if (s[len] >= 'a' && s[len] <= 'f')
  1443. num = (s[len] - 'a') + 10;
  1444. else if (s[len] >= 'A' && s[len] <= 'F')
  1445. num = (s[len] - 'A') + 10;
  1446. else
  1447. continue;
  1448. hex += num * base;
  1449. base = base * 16;
  1450. }
  1451. return hex;
  1452. }
  1453. void
  1454. StringToGuid(
  1455. IN TCHAR *str,
  1456. IN OUT LPGUID guid
  1457. )
  1458. /*++
  1459. Routine Description:
  1460. Converts a string into a GUID.
  1461. Arguments:
  1462. str - A string in TCHAR.
  1463. guid - The pointer to a GUID that will have the converted GUID.
  1464. Return Value:
  1465. None.
  1466. --*/
  1467. {
  1468. TCHAR temp[10];
  1469. int i, n;
  1470. temp[8]=_T('\0');
  1471. _tcsncpy(temp, str, 8);
  1472. _stscanf(temp, _T("%x"), &(guid->Data1));
  1473. temp[4]=_T('\0');
  1474. _tcsncpy(temp, &str[9], 4);
  1475. _stscanf(temp, _T("%x"), &(guid->Data2));
  1476. _tcsncpy(temp, &str[14], 4);
  1477. _stscanf(temp, _T("%x"), &(guid->Data3));
  1478. temp[2]='\0';
  1479. for(i=0;i<8;i++)
  1480. {
  1481. temp[0]=str[19+((i<2)?2*i:2*i+1)]; // to accomodate the minus sign after
  1482. temp[1]=str[20+((i<2)?2*i:2*i+1)]; // the first two chars
  1483. _stscanf(temp, _T("%x"), &n); // if used more than byte alloc
  1484. guid->Data4[i]=(unsigned char)n; // causes overrun of memory
  1485. }
  1486. }
  1487. void
  1488. DisplayVersionInfo()
  1489. /*++
  1490. Routine Description:
  1491. prints out a version information.
  1492. Arguments:
  1493. None.
  1494. Return Value:
  1495. None.
  1496. --*/
  1497. {
  1498. TCHAR buffer[512];
  1499. TCHAR strProgram[MAXSTR];
  1500. DWORD dw;
  1501. BYTE* pVersionInfo;
  1502. LPTSTR pVersion = NULL;
  1503. LPTSTR pProduct = NULL;
  1504. LPTSTR pCopyRight = NULL;
  1505. dw = GetModuleFileName(NULL, strProgram, MAXSTR);
  1506. if( dw>0 ){
  1507. dw = GetFileVersionInfoSize( strProgram, &dw );
  1508. if( dw > 0 ){
  1509. pVersionInfo = (BYTE*)malloc(dw);
  1510. if( NULL != pVersionInfo ){
  1511. if(GetFileVersionInfo( strProgram, 0, dw, pVersionInfo )){
  1512. LPDWORD lptr = NULL;
  1513. VerQueryValue( pVersionInfo, _T("\\VarFileInfo\\Translation"), (void**)&lptr, (UINT*)&dw );
  1514. if( lptr != NULL ){
  1515. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("ProductVersion") );
  1516. VerQueryValue( pVersionInfo, buffer, (void**)&pVersion, (UINT*)&dw );
  1517. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("OriginalFilename") );
  1518. VerQueryValue( pVersionInfo, buffer, (void**)&pProduct, (UINT*)&dw );
  1519. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("LegalCopyright") );
  1520. VerQueryValue( pVersionInfo, buffer, (void**)&pCopyRight, (UINT*)&dw );
  1521. }
  1522. if( pProduct != NULL && pVersion != NULL && pCopyRight != NULL ){
  1523. _tprintf( _T("\nMicrosoft (R) %s (%s)\n%s\n\n"), pProduct, pVersion, pCopyRight );
  1524. }
  1525. }
  1526. free( pVersionInfo );
  1527. }
  1528. }
  1529. }
  1530. }
  1531. void PrintHelpMessage()
  1532. /*++
  1533. Routine Description:
  1534. prints out a help message.
  1535. Arguments:
  1536. None.
  1537. Return Value:
  1538. None.
  1539. --*/
  1540. {
  1541. // end_sdk
  1542. DisplayVersionInfo();
  1543. // begin_sdk
  1544. _tprintf(_T("Usage: tracelog [actions] [options] | [-h | -help | -?]\n"));
  1545. _tprintf(_T("\n actions:\n"));
  1546. _tprintf(_T("\t-start [LoggerName] Starts up the [LoggerName] trace session\n"));
  1547. _tprintf(_T("\t-stop [LoggerName] Stops the [LoggerName] trace session\n"));
  1548. _tprintf(_T("\t-update [LoggerName] Updates the [LoggerName] trace session\n"));
  1549. _tprintf(_T("\t-enable [LoggerName] Enables providers for the [LoggerName] session\n"));
  1550. _tprintf(_T("\t-disable [LoggerName] Disables providers for the [LoggerName] session\n"));
  1551. if (Whistler)
  1552. _tprintf(_T("\t-flush [LoggerName] Flushes the [LoggerName] active buffers\n"));
  1553. // end_sdk
  1554. _tprintf(_T("\t-remove GlobalLogger Removes registry keys that activate GlobalLogger\n"));
  1555. // begin_sdk
  1556. if (Whistler)
  1557. _tprintf(_T("\t-enumguid Enumerate Registered Trace Guids\n"));
  1558. _tprintf(_T("\t-q [LoggerName] Query status of [LoggerName] trace session\n"));
  1559. _tprintf(_T("\t-l List all trace sessions\n"));
  1560. _tprintf(_T("\t-x Stops all active trace sessions\n"));
  1561. _tprintf(_T("\n options:\n"));
  1562. _tprintf(_T("\t-b <n> Sets buffer size to <n> Kbytes\n"));
  1563. _tprintf(_T("\t-min <n> Sets minimum buffers\n"));
  1564. _tprintf(_T("\t-max <n> Sets maximum buffers\n"));
  1565. _tprintf(_T("\t-f <name> Log to file <name>\n"));
  1566. if (Whistler) {
  1567. _tprintf(_T("\t-append Append to file\n"));
  1568. _tprintf(_T("\t-prealloc Pre-allocate\n"));
  1569. }
  1570. _tprintf(_T("\t-seq <n> Sequential logfile of up to n Mbytes\n"));
  1571. _tprintf(_T("\t-cir <n> Circular logfile of n Mbytes\n"));
  1572. if (Whistler)
  1573. _tprintf(_T("\t-newfile <n> Log to a new file after every n Mbytes\n"));
  1574. _tprintf(_T("\t-ft <n> Set flush timer to n seconds\n"));
  1575. if (Whistler)
  1576. _tprintf(_T("\t-paged Use pageable memory for buffers\n"));
  1577. _tprintf(_T("\t-noprocess Disable Process Start/End tracing\n"));
  1578. _tprintf(_T("\t-nothread Disable Thread Start/End tracing\n"));
  1579. _tprintf(_T("\t-nodisk Disable Disk I/O tracing\n"));
  1580. _tprintf(_T("\t-nonet Disable Network TCP/IP tracing\n"));
  1581. _tprintf(_T("\t-fio Enable file I/O tracing\n"));
  1582. _tprintf(_T("\t-pf Enable page faults tracing\n"));
  1583. _tprintf(_T("\t-hf Enable hard faults tracing\n"));
  1584. _tprintf(_T("\t-img Enable image load tracing\n"));
  1585. _tprintf(_T("\t-cm Enable registry calls tracing\n"));
  1586. _tprintf(_T("\t-um Enable Process Private tracing\n"));
  1587. _tprintf(_T("\t-guid <file> Start tracing for providers in file\n"));
  1588. _tprintf(_T("\t-rt Enable tracing in real time mode\n"));
  1589. _tprintf(_T("\t-age <n> Modify aging decay time to n minutes\n"));
  1590. _tprintf(_T("\t-level <n> Enable Level passed to the providers\n"));
  1591. _tprintf(_T("\t-flag <n> Enable Flags passed to the providers\n"));
  1592. // end_sdk
  1593. if (Whistler) {
  1594. _tprintf(_T("\t-eflag <n> <flag...> Enable flags (several) to providers\n"));
  1595. _tprintf(_T("\t-ls Generate Local Sequence Numbers\n"));
  1596. _tprintf(_T("\t-gs Generate Global Squence Numbers\n"));
  1597. _tprintf(_T("\t-pids <n> <pid1 pid2 ... >\n"));
  1598. _tprintf(_T("\t Tracing for Heap and Crit Sect for different process\n"));
  1599. }
  1600. // begin_sdk
  1601. _tprintf(_T("\n"));
  1602. _tprintf(_T("\t-h\n"));
  1603. _tprintf(_T("\t-help\n"));
  1604. _tprintf(_T("\t-? Display usage information\n"));
  1605. }
  1606. PTCHAR
  1607. GuidToString(
  1608. IN OUT PTCHAR s,
  1609. LPGUID piid
  1610. )
  1611. /*++
  1612. Routine Description:
  1613. Converts a GUID into a string.
  1614. Arguments:
  1615. s - A string in TCHAR that will have the converted GUID.
  1616. piid - The pointer to a GUID.
  1617. Return Value:
  1618. PTCHAR - The string containig the convereted GUID.
  1619. --*/
  1620. {
  1621. _stprintf(s, _T("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
  1622. piid->Data1, piid->Data2,
  1623. piid->Data3,
  1624. piid->Data4[0], piid->Data4[1],
  1625. piid->Data4[2], piid->Data4[3],
  1626. piid->Data4[4], piid->Data4[5],
  1627. piid->Data4[6], piid->Data4[7]);
  1628. return(s);
  1629. }
  1630. // end_sdk
  1631. LPCWSTR cszGlobalLoggerKey = L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\WMI\\GlobalLogger";
  1632. LPCWSTR cszStartValue = L"Start";
  1633. LPCWSTR cszBufferSizeValue = L"BufferSize";
  1634. LPCWSTR cszMaximumBufferValue = L"MaximumBuffers";
  1635. LPCWSTR cszMinimumBufferValue = L"MinimumBuffers";
  1636. LPCWSTR cszFlushTimerValue = L"FlushTimer";
  1637. LPCWSTR cszFileNameValue = L"FileName";
  1638. LPCWSTR cszEnableKernelValue = L"EnableKernelFlags";
  1639. LPCWSTR cszClockTypeValue = L"ClockType";
  1640. //
  1641. // GlobalLogger functions
  1642. //
  1643. ULONG
  1644. SetGlobalLoggerSettings(
  1645. IN DWORD StartValue,
  1646. IN PEVENT_TRACE_PROPERTIES LoggerInfo,
  1647. IN DWORD ClockType
  1648. )
  1649. /*++
  1650. Since it is a standalone utility, there is no need for extensive comments.
  1651. Routine Description:
  1652. Depending on the value given in "StartValue", it sets or resets event
  1653. trace registry. If the StartValue is 0 (Global logger off), it deletes
  1654. all the keys (that the user may have set previsouly).
  1655. Users are allowed to set or reset individual keys using this function,
  1656. but only when "-start GlobalLogger" is used.
  1657. The section that uses non NTAPIs is not guaranteed to work.
  1658. Arguments:
  1659. StartValue - The "Start" value to be set in the registry.
  1660. 0: Global logger off
  1661. 1: Global logger on
  1662. LoggerInfo - The poniter to the resident EVENT_TRACE_PROPERTIES instance.
  1663. whose members are used to set registry keys.
  1664. ClockType - The type of the clock to be set.
  1665. Return Value:
  1666. Error Code defined in winerror.h : If the function succeeds,
  1667. it returns ERROR_SUCCESS.
  1668. --*/
  1669. {
  1670. DWORD dwValue;
  1671. NTSTATUS status;
  1672. HANDLE KeyHandle;
  1673. OBJECT_ATTRIBUTES ObjectAttributes;
  1674. UNICODE_STRING UnicodeLoggerKey, UnicodeString;
  1675. ULONG Disposition, TitleIndex;
  1676. RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
  1677. RtlInitUnicodeString((&UnicodeLoggerKey),(cszGlobalLoggerKey));
  1678. InitializeObjectAttributes(
  1679. &ObjectAttributes,
  1680. &UnicodeLoggerKey,
  1681. OBJ_CASE_INSENSITIVE,
  1682. NULL,
  1683. NULL
  1684. );
  1685. // instead of opening, create a new key because it may not exist.
  1686. // if one exists already, that handle will be passed.
  1687. // if none exists, it will create one.
  1688. status = NtCreateKey(&KeyHandle,
  1689. KEY_QUERY_VALUE | KEY_SET_VALUE,
  1690. &ObjectAttributes,
  1691. 0L, // not used within this call anyway.
  1692. NULL,
  1693. REG_OPTION_NON_VOLATILE,
  1694. &Disposition);
  1695. RtlFreeUnicodeString(&UnicodeLoggerKey);
  1696. if(!NT_SUCCESS(status)) {
  1697. return RtlNtStatusToDosError(status);
  1698. }
  1699. TitleIndex = 0L;
  1700. if (StartValue == 1) { // ACTION_START: set filename only when it is given by a user.
  1701. // setting BufferSize
  1702. if (LoggerInfo->BufferSize > 0) {
  1703. dwValue = LoggerInfo->BufferSize;
  1704. RtlInitUnicodeString((&UnicodeString),(cszBufferSizeValue));
  1705. status = NtSetValueKey(
  1706. KeyHandle,
  1707. &UnicodeString,
  1708. TitleIndex,
  1709. REG_DWORD,
  1710. (LPBYTE)&dwValue,
  1711. sizeof(dwValue)
  1712. );
  1713. RtlFreeUnicodeString(&UnicodeString);
  1714. if (!NT_SUCCESS(status)) {
  1715. NtClose(KeyHandle);
  1716. return RtlNtStatusToDosError(status);
  1717. }
  1718. TitleIndex++;
  1719. }
  1720. // setting MaximumBuffers
  1721. if (LoggerInfo->MaximumBuffers > 0) {
  1722. dwValue = LoggerInfo->MaximumBuffers;
  1723. RtlInitUnicodeString((&UnicodeString),(cszMaximumBufferValue));
  1724. status = NtSetValueKey(
  1725. KeyHandle,
  1726. &UnicodeString,
  1727. TitleIndex,
  1728. REG_DWORD,
  1729. (LPBYTE)&dwValue,
  1730. sizeof(dwValue)
  1731. );
  1732. RtlFreeUnicodeString(&UnicodeString);
  1733. if (!NT_SUCCESS(status)) {
  1734. NtClose(KeyHandle);
  1735. return RtlNtStatusToDosError(status);
  1736. }
  1737. TitleIndex++;
  1738. }
  1739. // setting MinimumBuffers
  1740. if (LoggerInfo->MinimumBuffers > 0) {
  1741. dwValue = LoggerInfo->MinimumBuffers;
  1742. RtlInitUnicodeString((&UnicodeString),(cszMinimumBufferValue));
  1743. status = NtSetValueKey(
  1744. KeyHandle,
  1745. &UnicodeString,
  1746. TitleIndex,
  1747. REG_DWORD,
  1748. (LPBYTE)&dwValue,
  1749. sizeof(dwValue)
  1750. );
  1751. RtlFreeUnicodeString(&UnicodeString);
  1752. if (!NT_SUCCESS(status)) {
  1753. NtClose(KeyHandle);
  1754. return RtlNtStatusToDosError(status);
  1755. }
  1756. TitleIndex++;
  1757. }
  1758. // setting FlushTimer
  1759. if (LoggerInfo->FlushTimer > 0) {
  1760. dwValue = LoggerInfo->FlushTimer;
  1761. RtlInitUnicodeString((&UnicodeString),(cszFlushTimerValue));
  1762. status = NtSetValueKey(
  1763. KeyHandle,
  1764. &UnicodeString,
  1765. TitleIndex,
  1766. REG_DWORD,
  1767. (LPBYTE)&dwValue,
  1768. sizeof(dwValue)
  1769. );
  1770. RtlFreeUnicodeString(&UnicodeString);
  1771. if (!NT_SUCCESS(status)) {
  1772. NtClose(KeyHandle);
  1773. return RtlNtStatusToDosError(status);
  1774. }
  1775. TitleIndex++;
  1776. }
  1777. // setting EnableFlags
  1778. if (LoggerInfo->EnableFlags > 0) {
  1779. dwValue = LoggerInfo->EnableFlags;
  1780. RtlInitUnicodeString((&UnicodeString),(cszEnableKernelValue));
  1781. status = NtSetValueKey(
  1782. KeyHandle,
  1783. &UnicodeString,
  1784. TitleIndex,
  1785. REG_DWORD,
  1786. (LPBYTE)&dwValue,
  1787. sizeof(dwValue)
  1788. );
  1789. RtlFreeUnicodeString(&UnicodeString);
  1790. if (!NT_SUCCESS(status)) {
  1791. NtClose(KeyHandle);
  1792. return RtlNtStatusToDosError(status);
  1793. }
  1794. TitleIndex++;
  1795. }
  1796. dwValue = 0;
  1797. if (LoggerInfo->LogFileNameOffset > 0) {
  1798. UNICODE_STRING UnicodeFileName;
  1799. #ifndef UNICODE
  1800. WCHAR TempString[MAXSTR];
  1801. MultiByteToWideChar(CP_ACP,
  1802. 0,
  1803. (PCHAR)(LoggerInfo->LogFileNameOffset + (PCHAR) LoggerInfo),
  1804. strlen((PCHAR)(LoggerInfo->LogFileNameOffset + (PCHAR) LoggerInfo)),
  1805. TempString,
  1806. MAXSTR
  1807. );
  1808. RtlInitUnicodeString((&UnicodeFileName), TempString);
  1809. #else
  1810. RtlInitUnicodeString((&UnicodeFileName), (PWCHAR)(LoggerInfo->LogFileNameOffset + (PCHAR) LoggerInfo));
  1811. #endif
  1812. RtlInitUnicodeString((&UnicodeString),(cszFileNameValue));
  1813. status = NtSetValueKey(
  1814. KeyHandle,
  1815. &UnicodeString,
  1816. TitleIndex,
  1817. REG_SZ,
  1818. UnicodeFileName.Buffer,
  1819. UnicodeFileName.Length + sizeof(UNICODE_NULL)
  1820. );
  1821. RtlFreeUnicodeString(&UnicodeString);
  1822. RtlFreeUnicodeString(&UnicodeFileName);
  1823. if (!NT_SUCCESS(status)) {
  1824. NtClose(KeyHandle);
  1825. return RtlNtStatusToDosError(status);
  1826. }
  1827. TitleIndex++;
  1828. }
  1829. }
  1830. else { // if ACTION_STOP then delete the keys that users might have set previously.
  1831. // delete buffer size
  1832. RtlInitUnicodeString((&UnicodeString),(cszBufferSizeValue));
  1833. status = NtDeleteValueKey(
  1834. KeyHandle,
  1835. &UnicodeString
  1836. );
  1837. RtlFreeUnicodeString(&UnicodeString);
  1838. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  1839. NtClose(KeyHandle);
  1840. return RtlNtStatusToDosError(status);
  1841. }
  1842. // delete maximum buffers
  1843. RtlInitUnicodeString((&UnicodeString),(cszMaximumBufferValue));
  1844. status = NtDeleteValueKey(
  1845. KeyHandle,
  1846. &UnicodeString
  1847. );
  1848. RtlFreeUnicodeString(&UnicodeString);
  1849. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  1850. NtClose(KeyHandle);
  1851. return RtlNtStatusToDosError(status);
  1852. }
  1853. // delete minimum buffers
  1854. RtlInitUnicodeString((&UnicodeString),(cszMinimumBufferValue));
  1855. status = NtDeleteValueKey(
  1856. KeyHandle,
  1857. &UnicodeString
  1858. );
  1859. RtlFreeUnicodeString(&UnicodeString);
  1860. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  1861. NtClose(KeyHandle);
  1862. return RtlNtStatusToDosError(status);
  1863. }
  1864. // delete flush timer
  1865. RtlInitUnicodeString((&UnicodeString),(cszFlushTimerValue));
  1866. status = NtDeleteValueKey(
  1867. KeyHandle,
  1868. &UnicodeString
  1869. );
  1870. RtlFreeUnicodeString(&UnicodeString);
  1871. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  1872. NtClose(KeyHandle);
  1873. return RtlNtStatusToDosError(status);
  1874. }
  1875. // delete enable falg
  1876. RtlInitUnicodeString((&UnicodeString),(cszEnableKernelValue));
  1877. status = NtDeleteValueKey(
  1878. KeyHandle,
  1879. &UnicodeString
  1880. );
  1881. RtlFreeUnicodeString(&UnicodeString);
  1882. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  1883. NtClose(KeyHandle);
  1884. return RtlNtStatusToDosError(status);
  1885. }
  1886. // delete filename
  1887. RtlInitUnicodeString((&UnicodeString),(cszFileNameValue));
  1888. status = NtDeleteValueKey(
  1889. KeyHandle,
  1890. &UnicodeString
  1891. );
  1892. RtlFreeUnicodeString(&UnicodeString);
  1893. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  1894. NtClose(KeyHandle);
  1895. return RtlNtStatusToDosError(status);
  1896. }
  1897. }
  1898. // setting ClockType
  1899. if (ClockType > 0) {
  1900. dwValue = ClockType;
  1901. RtlInitUnicodeString((&UnicodeString),(cszClockTypeValue));
  1902. status = NtSetValueKey(
  1903. KeyHandle,
  1904. &UnicodeString,
  1905. TitleIndex,
  1906. REG_DWORD,
  1907. (LPBYTE)&dwValue,
  1908. sizeof(dwValue)
  1909. );
  1910. RtlFreeUnicodeString(&UnicodeString);
  1911. if (!NT_SUCCESS(status)) {
  1912. NtClose(KeyHandle);
  1913. return RtlNtStatusToDosError(status);
  1914. }
  1915. TitleIndex++;
  1916. }
  1917. // Setting StartValue
  1918. dwValue = StartValue;
  1919. RtlInitUnicodeString((&UnicodeString),(cszStartValue));
  1920. status = NtSetValueKey(
  1921. KeyHandle,
  1922. &UnicodeString,
  1923. TitleIndex,
  1924. REG_DWORD,
  1925. (LPBYTE)&dwValue,
  1926. sizeof(dwValue)
  1927. );
  1928. RtlFreeUnicodeString(&UnicodeString);
  1929. if (!NT_SUCCESS(status)) {
  1930. NtClose(KeyHandle);
  1931. return RtlNtStatusToDosError(status);
  1932. }
  1933. TitleIndex++;
  1934. NtClose(KeyHandle);
  1935. return 0;
  1936. }
  1937. ULONG
  1938. GetGlobalLoggerSettings(
  1939. IN OUT PEVENT_TRACE_PROPERTIES LoggerInfo,
  1940. OUT PULONG ClockType,
  1941. OUT PDWORD pdwStart
  1942. )
  1943. /*++
  1944. Routine Description:
  1945. It reads registry for golbal logger and updates LoggerInfo. It uses
  1946. NtEnumerateValueKey() to retrieve the values of the required subkeys.
  1947. The section that uses non NTAPIs is not guaranteed to work.
  1948. Arguments:
  1949. LoggerInfo - The poniter to the resident EVENT_TRACE_PROPERTIES instance.
  1950. whose members are updated as the result.
  1951. ClockType - The type of the clock to be updated.
  1952. pdwStart - The "Start" value of currently retained in the registry.
  1953. Return Value:
  1954. WINERROR - Error Code defined in winerror.h. If the function succeeds,
  1955. it returns ERROR_SUCCESS.
  1956. --*/
  1957. {
  1958. ULONG i, j;
  1959. NTSTATUS status;
  1960. HANDLE KeyHandle;
  1961. WCHAR SubKeyName[MAXSTR];
  1962. PVOID Buffer;
  1963. ULONG BufferLength, RequiredLength, KeyNameLength, KeyDataOffset, KeyDataLength;
  1964. OBJECT_ATTRIBUTES ObjectAttributes;
  1965. UNICODE_STRING UnicodeLoggerKey;
  1966. *pdwStart = 0;
  1967. RtlInitUnicodeString((&UnicodeLoggerKey),(cszGlobalLoggerKey));
  1968. RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
  1969. InitializeObjectAttributes(
  1970. &ObjectAttributes,
  1971. &UnicodeLoggerKey,
  1972. OBJ_CASE_INSENSITIVE,
  1973. NULL,
  1974. NULL
  1975. );
  1976. status = NtOpenKey(
  1977. &KeyHandle,
  1978. KEY_QUERY_VALUE | KEY_SET_VALUE,
  1979. &ObjectAttributes
  1980. );
  1981. RtlFreeUnicodeString(&UnicodeLoggerKey);
  1982. if(!NT_SUCCESS(status))
  1983. return RtlNtStatusToDosError(status);
  1984. // KEY_VALUE_FULL_INFORMATION + name (1 WSTR) + data.
  1985. BufferLength = sizeof(KEY_VALUE_FULL_INFORMATION) + 2 * MAXSTR * sizeof(TCHAR);
  1986. Buffer = (PVOID) malloc(BufferLength);
  1987. if (Buffer == NULL) {
  1988. NtClose(KeyHandle);
  1989. return (ERROR_OUTOFMEMORY);
  1990. }
  1991. i = 0;
  1992. do {
  1993. // Using Key Enumeration
  1994. status = NtEnumerateValueKey(
  1995. KeyHandle,
  1996. i++,
  1997. KeyValueFullInformation,
  1998. Buffer,
  1999. BufferLength,
  2000. &RequiredLength
  2001. );
  2002. if (!NT_SUCCESS(status)) {
  2003. if (status == STATUS_NO_MORE_ENTRIES)
  2004. break;
  2005. else if (status == STATUS_BUFFER_OVERFLOW) {
  2006. Buffer = realloc(Buffer, RequiredLength);
  2007. if (Buffer == NULL) {
  2008. NtClose(KeyHandle);
  2009. return (ERROR_OUTOFMEMORY);
  2010. }
  2011. status = NtEnumerateValueKey(
  2012. KeyHandle,
  2013. i++,
  2014. KeyValueFullInformation,
  2015. Buffer,
  2016. BufferLength,
  2017. &RequiredLength
  2018. );
  2019. if (!NT_SUCCESS(status)) {
  2020. NtClose(KeyHandle);
  2021. free(Buffer);
  2022. return RtlNtStatusToDosError(status);
  2023. }
  2024. }
  2025. else {
  2026. NtClose(KeyHandle);
  2027. free(Buffer);
  2028. return RtlNtStatusToDosError(status);
  2029. }
  2030. }
  2031. KeyNameLength = ((PKEY_VALUE_FULL_INFORMATION)Buffer)->NameLength;
  2032. RtlCopyMemory(SubKeyName,
  2033. (PUCHAR)(((PKEY_VALUE_FULL_INFORMATION)Buffer)->Name),
  2034. KeyNameLength
  2035. );
  2036. KeyNameLength /= sizeof(WCHAR);
  2037. SubKeyName[KeyNameLength] = L'\0';
  2038. KeyDataOffset = ((PKEY_VALUE_FULL_INFORMATION)Buffer)->DataOffset;
  2039. KeyDataLength = ((PKEY_VALUE_FULL_INFORMATION)Buffer)->DataLength;
  2040. // Find out what the key is
  2041. if (!_wcsicmp(SubKeyName, cszStartValue)) { //StartValue
  2042. RtlCopyMemory(pdwStart,
  2043. (PUCHAR)Buffer + KeyDataOffset,
  2044. KeyDataLength);
  2045. }
  2046. else if (!_wcsicmp(SubKeyName, cszBufferSizeValue)) { // BufferSizeValue
  2047. RtlCopyMemory(&(LoggerInfo->BufferSize),
  2048. (PUCHAR)Buffer + KeyDataOffset,
  2049. KeyDataLength);
  2050. }
  2051. else if (!_wcsicmp(SubKeyName, cszMaximumBufferValue)) { // MaximumBufferValue
  2052. RtlCopyMemory(&(LoggerInfo->MaximumBuffers),
  2053. (PUCHAR)Buffer + KeyDataOffset,
  2054. KeyDataLength);
  2055. }
  2056. else if (!_wcsicmp(SubKeyName, cszMinimumBufferValue)) { // MinimumBuffers
  2057. RtlCopyMemory(&(LoggerInfo->MinimumBuffers),
  2058. (PUCHAR)Buffer + KeyDataOffset,
  2059. KeyDataLength);
  2060. }
  2061. else if (!_wcsicmp(SubKeyName, cszFlushTimerValue)) { // FlushTimer
  2062. RtlCopyMemory(&(LoggerInfo->FlushTimer),
  2063. (PUCHAR)Buffer + KeyDataOffset,
  2064. KeyDataLength);
  2065. }
  2066. else if (!_wcsicmp(SubKeyName, cszEnableKernelValue)) { // EnableKernelValue
  2067. RtlCopyMemory(&(LoggerInfo->EnableFlags),
  2068. (PUCHAR)Buffer + KeyDataOffset,
  2069. KeyDataLength);
  2070. }
  2071. else if (!_wcsicmp(SubKeyName, cszClockTypeValue)) { // ClockTypeValue
  2072. RtlCopyMemory(ClockType,
  2073. (PUCHAR)Buffer + KeyDataOffset,
  2074. KeyDataLength);
  2075. }
  2076. else if (!_wcsicmp(SubKeyName, cszFileNameValue)) { // FileName
  2077. #ifndef UNICODE
  2078. WCHAR TempString[MAXSTR];
  2079. RtlCopyMemory(TempString, (PUCHAR)Buffer + KeyDataOffset, KeyDataLength);
  2080. WideCharToMultiByte(CP_ACP,
  2081. 0,
  2082. TempString,
  2083. wcslen(TempString),
  2084. (PUCHAR)LoggerInfo + LoggerInfo->LogFileNameOffset,
  2085. KeyDataLength,
  2086. NULL,
  2087. NULL);
  2088. #else
  2089. RtlCopyMemory((PUCHAR)LoggerInfo + LoggerInfo->LogFileNameOffset,
  2090. (PUCHAR)Buffer + KeyDataOffset,
  2091. KeyDataLength);
  2092. #endif
  2093. }
  2094. else { // Some other keys are in there
  2095. _tprintf(_T("Warning: Unidentified Key in the trace registry: %s\n"), SubKeyName);
  2096. }
  2097. }
  2098. while (1);
  2099. NtClose(KeyHandle);
  2100. free(Buffer);
  2101. return 0;
  2102. }