Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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