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.

1063 lines
29 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) 2002 Microsoft Corporation. All rights reserved.
  3. // Copyright (c) 2002 OSR Open Systems Resources, Inc.
  4. //
  5. // Utils.cpp : miscellaneous useful functions
  6. //////////////////////////////////////////////////////////////////////////////
  7. #include "stdafx.h"
  8. #include <tchar.h>
  9. #include <wmistr.h>
  10. #include <initguid.h>
  11. #include <guiddef.h>
  12. extern "C" {
  13. #include <evntrace.h>
  14. #include "wppfmtstub.h"
  15. }
  16. #include <traceprt.h>
  17. #include "TraceView.h"
  18. #include "Utils.h"
  19. BOOLEAN ParsePdb(CString &PDBFileName, CString &TMFPath, BOOL bCommandLine)
  20. {
  21. CString str;
  22. CString currentDir =_T("");
  23. ULONG guidCount = 0;
  24. DWORD status;
  25. CHAR pdbName[500];
  26. CHAR path[500];
  27. if(PDBFileName.IsEmpty()) {
  28. if(bCommandLine) {
  29. _tprintf(_T("No PDB File To Parse\n"));
  30. } else {
  31. AfxMessageBox(_T("No PDB File To Parse"));
  32. }
  33. return FALSE;
  34. }
  35. if(TMFPath.IsEmpty()) {
  36. GetCurrentDirectory(500, (LPTSTR)(LPCTSTR)TMFPath);
  37. }
  38. #if defined(UNICODE)
  39. memset(pdbName, 0, 500);
  40. WideCharToMultiByte(CP_ACP,
  41. 0,
  42. (LPCTSTR)PDBFileName,
  43. PDBFileName.GetAllocLength(),
  44. (LPSTR)pdbName,
  45. 500,
  46. NULL,
  47. NULL);
  48. memset(path, 0, 500);
  49. WideCharToMultiByte(CP_ACP,
  50. 0,
  51. (LPCTSTR)TMFPath,
  52. TMFPath.GetLength(),
  53. (LPSTR)path,
  54. 500,
  55. NULL,
  56. NULL);
  57. status = BinplaceWppFmtStub(pdbName,
  58. path,
  59. "mspdb70.dll",
  60. TRUE);
  61. #else // UNICODE
  62. status = BinplaceWppFmtStub((LPSTR)(LPCTSTR)PDBFileName,
  63. (LPSTR)(LPCTSTR)TMFPath,
  64. "mspdb70.dll",
  65. TRUE);
  66. #endif // UNICODE
  67. if (status != ERROR_SUCCESS) {
  68. if(bCommandLine) {
  69. _tprintf(_T("BinplaceWppFmt Failed with status %d\n"), status);
  70. } else {
  71. AfxMessageBox(_T("BinplaceWppFmt Failed"));
  72. }
  73. }
  74. return TRUE;
  75. }
  76. void
  77. StringToGuid(
  78. IN TCHAR *str,
  79. IN OUT LPGUID guid
  80. )
  81. /*++
  82. Routine Description:
  83. Converts a string into a GUID.
  84. Arguments:
  85. str - A string in TCHAR.
  86. guid - The pointer to a GUID that will have the converted GUID.
  87. Return Value:
  88. None.
  89. --*/
  90. {
  91. TCHAR temp[10];
  92. int i;
  93. _tcsncpy(temp, str, 8);
  94. temp[8] = 0;
  95. guid->Data1 = ahextoi(temp);
  96. _tcsncpy(temp, &str[9], 4);
  97. temp[4] = 0;
  98. guid->Data2 = (USHORT) ahextoi(temp);
  99. _tcsncpy(temp, &str[14], 4);
  100. temp[4] = 0;
  101. guid->Data3 = (USHORT) ahextoi(temp);
  102. for (i=0; i<2; i++) {
  103. _tcsncpy(temp, &str[19 + (i*2)], 2);
  104. temp[2] = 0;
  105. guid->Data4[i] = (UCHAR) ahextoi(temp);
  106. }
  107. for (i=2; i<8; i++) {
  108. _tcsncpy(temp, &str[20 + (i*2)], 2);
  109. temp[2] = 0;
  110. guid->Data4[i] = (UCHAR) ahextoi(temp);
  111. }
  112. }
  113. ULONG
  114. ahextoi(
  115. IN TCHAR *s
  116. )
  117. /*++
  118. Routine Description:
  119. Converts a hex string into a number.
  120. Arguments:
  121. s - A hex string in TCHAR.
  122. Return Value:
  123. ULONG - The number in the string.
  124. --*/
  125. {
  126. int len;
  127. ULONG num, base, hex;
  128. len = _tcslen(s);
  129. hex = 0; base = 1; num = 0;
  130. while (--len >= 0) {
  131. if ( (s[len] == 'x' || s[len] == 'X') &&
  132. (s[len-1] == '0') )
  133. break;
  134. if (s[len] >= '0' && s[len] <= '9')
  135. num = s[len] - '0';
  136. else if (s[len] >= 'a' && s[len] <= 'f')
  137. num = (s[len] - 'a') + 10;
  138. else if (s[len] >= 'A' && s[len] <= 'F')
  139. num = (s[len] - 'A') + 10;
  140. else
  141. continue;
  142. hex += num * base;
  143. base = base * 16;
  144. }
  145. return hex;
  146. }
  147. #if 0
  148. LONG
  149. GetGuids(
  150. IN LPTSTR GuidFile,
  151. IN OUT LPGUID *GuidArray
  152. )
  153. /*++
  154. Routine Description:
  155. Reads GUIDs from a file and stores them in an GUID array.
  156. Arguments:
  157. GuidFile - The file containing GUIDs.
  158. GuidArray - The GUID array that will have GUIDs read from the file.
  159. Return Value:
  160. ULONG - The number of GUIDs processed.
  161. --*/
  162. {
  163. FILE *f;
  164. TCHAR line[MAXSTR], arg[MAXSTR];
  165. LPGUID Guid;
  166. int i, n;
  167. f = _tfopen((TCHAR*)GuidFile, _T("r"));
  168. if (f == NULL)
  169. return -1;
  170. n = 0;
  171. while ( _fgetts(line, MAXSTR, f) != NULL ) {
  172. if (_tcslen(line) < 36)
  173. continue;
  174. if (line[0] == ';' ||
  175. line[0] == '\0' ||
  176. line[0] == '#' ||
  177. line[0] == '/')
  178. continue;
  179. Guid = (LPGUID) GuidArray[n];
  180. n ++;
  181. StringToGuid(line, Guid);
  182. }
  183. fclose(f);
  184. return (ULONG)n;
  185. }
  186. //
  187. // GlobalLogger functions
  188. //
  189. ULONG
  190. SetGlobalLoggerSettings(
  191. IN DWORD StartValue,
  192. IN PEVENT_TRACE_PROPERTIES LoggerInfo,
  193. IN DWORD ClockType
  194. )
  195. /*++
  196. Since it is a standalone utility, there is no need for extensive comments.
  197. Routine Description:
  198. Depending on the value given in "StartValue", it sets or resets event
  199. trace registry. If the StartValue is 0 (Global logger off), it deletes
  200. all the keys (that the user may have set previsouly).
  201. Users are allowed to set or reset individual keys using this function,
  202. but only when "-start GlobalLogger" is used.
  203. The section that uses non NTAPIs is not guaranteed to work.
  204. Arguments:
  205. StartValue - The "Start" value to be set in the registry.
  206. 0: Global logger off
  207. 1: Global logger on
  208. LoggerInfo - The poniter to the resident EVENT_TRACE_PROPERTIES instance.
  209. whose members are used to set registry keys.
  210. ClockType - The type of the clock to be set.
  211. Return Value:
  212. Error Code defined in winerror.h : If the function succeeds,
  213. it returns ERROR_SUCCESS.
  214. --*/
  215. {
  216. DWORD dwValue;
  217. NTSTATUS status;
  218. HANDLE KeyHandle;
  219. OBJECT_ATTRIBUTES ObjectAttributes;
  220. UNICODE_STRING UnicodeLoggerKey, UnicodeString;
  221. ULONG Disposition, TitleIndex;
  222. RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
  223. RtlInitUnicodeString((&UnicodeLoggerKey),(cszGlobalLoggerKey));
  224. InitializeObjectAttributes(
  225. &ObjectAttributes,
  226. &UnicodeLoggerKey,
  227. OBJ_CASE_INSENSITIVE,
  228. NULL,
  229. NULL
  230. );
  231. // instead of opening, create a new key because it may not exist.
  232. // if one exists already, that handle will be passed.
  233. // if none exists, it will create one.
  234. status = NtCreateKey(&KeyHandle,
  235. KEY_QUERY_VALUE | KEY_SET_VALUE,
  236. &ObjectAttributes,
  237. 0L, // not used within this call anyway.
  238. NULL,
  239. REG_OPTION_NON_VOLATILE,
  240. &Disposition);
  241. if(!NT_SUCCESS(status)) {
  242. return RtlNtStatusToDosError(status);
  243. }
  244. TitleIndex = 0L;
  245. if (StartValue == 1) { // ACTION_START: set filename only when it is given by a user.
  246. // setting BufferSize
  247. if (LoggerInfo->BufferSize > 0) {
  248. dwValue = LoggerInfo->BufferSize;
  249. RtlInitUnicodeString((&UnicodeString),(cszBufferSizeValue));
  250. status = NtSetValueKey(
  251. KeyHandle,
  252. &UnicodeString,
  253. TitleIndex,
  254. REG_DWORD,
  255. (LPBYTE)&dwValue,
  256. sizeof(dwValue)
  257. );
  258. if (!NT_SUCCESS(status)) {
  259. NtClose(KeyHandle);
  260. return RtlNtStatusToDosError(status);
  261. }
  262. TitleIndex++;
  263. }
  264. // setting MaximumBuffers
  265. if (LoggerInfo->MaximumBuffers > 0) {
  266. dwValue = LoggerInfo->MaximumBuffers;
  267. RtlInitUnicodeString((&UnicodeString),(cszMaximumBufferValue));
  268. status = NtSetValueKey(
  269. KeyHandle,
  270. &UnicodeString,
  271. TitleIndex,
  272. REG_DWORD,
  273. (LPBYTE)&dwValue,
  274. sizeof(dwValue)
  275. );
  276. if (!NT_SUCCESS(status)) {
  277. NtClose(KeyHandle);
  278. return RtlNtStatusToDosError(status);
  279. }
  280. TitleIndex++;
  281. }
  282. // setting MinimumBuffers
  283. if (LoggerInfo->MinimumBuffers > 0) {
  284. dwValue = LoggerInfo->MinimumBuffers;
  285. RtlInitUnicodeString((&UnicodeString),(cszMinimumBufferValue));
  286. status = NtSetValueKey(
  287. KeyHandle,
  288. &UnicodeString,
  289. TitleIndex,
  290. REG_DWORD,
  291. (LPBYTE)&dwValue,
  292. sizeof(dwValue)
  293. );
  294. if (!NT_SUCCESS(status)) {
  295. NtClose(KeyHandle);
  296. return RtlNtStatusToDosError(status);
  297. }
  298. TitleIndex++;
  299. }
  300. // setting FlushTimer
  301. if (LoggerInfo->FlushTimer > 0) {
  302. dwValue = LoggerInfo->FlushTimer;
  303. RtlInitUnicodeString((&UnicodeString),(cszFlushTimerValue));
  304. status = NtSetValueKey(
  305. KeyHandle,
  306. &UnicodeString,
  307. TitleIndex,
  308. REG_DWORD,
  309. (LPBYTE)&dwValue,
  310. sizeof(dwValue)
  311. );
  312. if (!NT_SUCCESS(status)) {
  313. NtClose(KeyHandle);
  314. return RtlNtStatusToDosError(status);
  315. }
  316. TitleIndex++;
  317. }
  318. // setting EnableFlags
  319. if (LoggerInfo->EnableFlags > 0) {
  320. dwValue = LoggerInfo->EnableFlags;
  321. RtlInitUnicodeString((&UnicodeString),(cszEnableKernelValue));
  322. status = NtSetValueKey(
  323. KeyHandle,
  324. &UnicodeString,
  325. TitleIndex,
  326. REG_DWORD,
  327. (LPBYTE)&dwValue,
  328. sizeof(dwValue)
  329. );
  330. if (!NT_SUCCESS(status)) {
  331. NtClose(KeyHandle);
  332. return RtlNtStatusToDosError(status);
  333. }
  334. TitleIndex++;
  335. }
  336. dwValue = 0;
  337. if (LoggerInfo->LogFileNameOffset > 0) {
  338. UNICODE_STRING UnicodeFileName;
  339. #ifndef UNICODE
  340. WCHAR TempString[MAXSTR];
  341. MultiByteToWideChar(CP_ACP,
  342. 0,
  343. (PCHAR)(LoggerInfo->LogFileNameOffset + (PCHAR) LoggerInfo),
  344. strlen((PCHAR)(LoggerInfo->LogFileNameOffset + (PCHAR) LoggerInfo)),
  345. TempString,
  346. MAXSTR
  347. );
  348. RtlInitUnicodeString((&UnicodeFileName), TempString);
  349. #else
  350. RtlInitUnicodeString((&UnicodeFileName), (PWCHAR)(LoggerInfo->LogFileNameOffset + (PCHAR) LoggerInfo));
  351. #endif
  352. RtlInitUnicodeString((&UnicodeString),(cszFileNameValue));
  353. status = NtSetValueKey(
  354. KeyHandle,
  355. &UnicodeString,
  356. TitleIndex,
  357. REG_SZ,
  358. UnicodeFileName.Buffer,
  359. UnicodeFileName.Length + sizeof(UNICODE_NULL)
  360. );
  361. if (!NT_SUCCESS(status)) {
  362. NtClose(KeyHandle);
  363. return RtlNtStatusToDosError(status);
  364. }
  365. TitleIndex++;
  366. }
  367. }
  368. else { // if ACTION_STOP then delete the keys that users might have set previously.
  369. // delete buffer size
  370. RtlInitUnicodeString((&UnicodeString),(cszBufferSizeValue));
  371. status = NtDeleteValueKey(
  372. KeyHandle,
  373. &UnicodeString
  374. );
  375. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  376. NtClose(KeyHandle);
  377. return RtlNtStatusToDosError(status);
  378. }
  379. // delete maximum buffers
  380. RtlInitUnicodeString((&UnicodeString),(cszMaximumBufferValue));
  381. status = NtDeleteValueKey(
  382. KeyHandle,
  383. &UnicodeString
  384. );
  385. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  386. NtClose(KeyHandle);
  387. return RtlNtStatusToDosError(status);
  388. }
  389. // delete minimum buffers
  390. RtlInitUnicodeString((&UnicodeString),(cszMinimumBufferValue));
  391. status = NtDeleteValueKey(
  392. KeyHandle,
  393. &UnicodeString
  394. );
  395. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  396. NtClose(KeyHandle);
  397. return RtlNtStatusToDosError(status);
  398. }
  399. // delete flush timer
  400. RtlInitUnicodeString((&UnicodeString),(cszFlushTimerValue));
  401. status = NtDeleteValueKey(
  402. KeyHandle,
  403. &UnicodeString
  404. );
  405. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  406. NtClose(KeyHandle);
  407. return RtlNtStatusToDosError(status);
  408. }
  409. // delete enable falg
  410. RtlInitUnicodeString((&UnicodeString),(cszEnableKernelValue));
  411. status = NtDeleteValueKey(
  412. KeyHandle,
  413. &UnicodeString
  414. );
  415. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  416. NtClose(KeyHandle);
  417. return RtlNtStatusToDosError(status);
  418. }
  419. // delete filename
  420. RtlInitUnicodeString((&UnicodeString),(cszFileNameValue));
  421. status = NtDeleteValueKey(
  422. KeyHandle,
  423. &UnicodeString
  424. );
  425. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  426. NtClose(KeyHandle);
  427. return RtlNtStatusToDosError(status);
  428. }
  429. }
  430. // setting ClockType
  431. if (ClockType > 0) {
  432. dwValue = ClockType;
  433. RtlInitUnicodeString((&UnicodeString),(cszClockTypeValue));
  434. status = NtSetValueKey(
  435. KeyHandle,
  436. &UnicodeString,
  437. TitleIndex,
  438. REG_DWORD,
  439. (LPBYTE)&dwValue,
  440. sizeof(dwValue)
  441. );
  442. if (!NT_SUCCESS(status)) {
  443. NtClose(KeyHandle);
  444. return RtlNtStatusToDosError(status);
  445. }
  446. TitleIndex++;
  447. }
  448. // Setting StartValue
  449. dwValue = StartValue;
  450. RtlInitUnicodeString((&UnicodeString),(cszStartValue));
  451. status = NtSetValueKey(
  452. KeyHandle,
  453. &UnicodeString,
  454. TitleIndex,
  455. REG_DWORD,
  456. (LPBYTE)&dwValue,
  457. sizeof(dwValue)
  458. );
  459. if (!NT_SUCCESS(status)) {
  460. NtClose(KeyHandle);
  461. return RtlNtStatusToDosError(status);
  462. }
  463. TitleIndex++;
  464. NtClose(KeyHandle);
  465. return 0;
  466. }
  467. ULONG
  468. GetGlobalLoggerSettings(
  469. IN OUT PEVENT_TRACE_PROPERTIES LoggerInfo,
  470. OUT PULONG ClockType,
  471. OUT PDWORD pdwStart
  472. )
  473. /*++
  474. Routine Description:
  475. It reads registry for golbal logger and updates LoggerInfo. It uses
  476. NtEnumerateValueKey() to retrieve the values of the required subkeys.
  477. The section that uses non NTAPIs is not guaranteed to work.
  478. Arguments:
  479. LoggerInfo - The poniter to the resident EVENT_TRACE_PROPERTIES instance.
  480. whose members are updated as the result.
  481. ClockType - The type of the clock to be updated.
  482. pdwStart - The "Start" value of currently retained in the registry.
  483. Return Value:
  484. WINERROR - Error Code defined in winerror.h. If the function succeeds,
  485. it returns ERROR_SUCCESS.
  486. --*/
  487. {
  488. ULONG i, j;
  489. NTSTATUS status;
  490. HANDLE KeyHandle;
  491. WCHAR SubKeyName[MAXSTR];
  492. PVOID Buffer;
  493. ULONG BufferLength, RequiredLength, KeyNameLength, KeyDataOffset, KeyDataLength;
  494. OBJECT_ATTRIBUTES ObjectAttributes;
  495. UNICODE_STRING UnicodeLoggerKey;
  496. *pdwStart = 0;
  497. RtlInitUnicodeString((&UnicodeLoggerKey),(cszGlobalLoggerKey));
  498. RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
  499. InitializeObjectAttributes(
  500. &ObjectAttributes,
  501. &UnicodeLoggerKey,
  502. OBJ_CASE_INSENSITIVE,
  503. NULL,
  504. NULL
  505. );
  506. status = NtOpenKey(
  507. &KeyHandle,
  508. KEY_QUERY_VALUE | KEY_SET_VALUE,
  509. &ObjectAttributes
  510. );
  511. if(!NT_SUCCESS(status))
  512. return RtlNtStatusToDosError(status);
  513. // KEY_VALUE_FULL_INFORMATION + name (1 WSTR) + data.
  514. BufferLength = sizeof(KEY_VALUE_FULL_INFORMATION) + 2 * MAXSTR * sizeof(TCHAR);
  515. Buffer = (PVOID) malloc(BufferLength);
  516. if (Buffer == NULL) {
  517. NtClose(KeyHandle);
  518. return (ERROR_OUTOFMEMORY);
  519. }
  520. i = 0;
  521. do {
  522. // Using Key Enumeration
  523. status = NtEnumerateValueKey(
  524. KeyHandle,
  525. i++,
  526. KeyValueFullInformation,
  527. Buffer,
  528. BufferLength,
  529. &RequiredLength
  530. );
  531. if (!NT_SUCCESS(status)) {
  532. if (status == STATUS_NO_MORE_ENTRIES)
  533. break;
  534. else if (status == STATUS_BUFFER_OVERFLOW) {
  535. free(Buffer);
  536. Buffer = malloc(RequiredLength);
  537. if (Buffer == NULL) {
  538. NtClose(KeyHandle);
  539. return (ERROR_OUTOFMEMORY);
  540. }
  541. status = NtEnumerateValueKey(
  542. KeyHandle,
  543. i++,
  544. KeyValueFullInformation,
  545. Buffer,
  546. BufferLength,
  547. &RequiredLength
  548. );
  549. if (!NT_SUCCESS(status)) {
  550. NtClose(KeyHandle);
  551. free(Buffer);
  552. return RtlNtStatusToDosError(status);
  553. }
  554. }
  555. else {
  556. NtClose(KeyHandle);
  557. free(Buffer);
  558. return RtlNtStatusToDosError(status);
  559. }
  560. }
  561. KeyNameLength = ((PKEY_VALUE_FULL_INFORMATION)Buffer)->NameLength;
  562. RtlCopyMemory(SubKeyName,
  563. (PUCHAR)(((PKEY_VALUE_FULL_INFORMATION)Buffer)->Name),
  564. KeyNameLength
  565. );
  566. KeyNameLength /= sizeof(WCHAR);
  567. SubKeyName[KeyNameLength] = L'\0';
  568. KeyDataOffset = ((PKEY_VALUE_FULL_INFORMATION)Buffer)->DataOffset;
  569. KeyDataLength = ((PKEY_VALUE_FULL_INFORMATION)Buffer)->DataLength;
  570. // Find out what the key is
  571. if (!_wcsicmp(SubKeyName, cszStartValue)) { //StartValue
  572. RtlCopyMemory(pdwStart,
  573. (PUCHAR)Buffer + KeyDataOffset,
  574. KeyDataLength);
  575. }
  576. else if (!_wcsicmp(SubKeyName, cszBufferSizeValue)) { // BufferSizeValue
  577. RtlCopyMemory(&(LoggerInfo->BufferSize),
  578. (PUCHAR)Buffer + KeyDataOffset,
  579. KeyDataLength);
  580. }
  581. else if (!_wcsicmp(SubKeyName, cszMaximumBufferValue)) { // MaximumBufferValue
  582. RtlCopyMemory(&(LoggerInfo->MaximumBuffers),
  583. (PUCHAR)Buffer + KeyDataOffset,
  584. KeyDataLength);
  585. }
  586. else if (!_wcsicmp(SubKeyName, cszMinimumBufferValue)) { // MinimumBuffers
  587. RtlCopyMemory(&(LoggerInfo->MinimumBuffers),
  588. (PUCHAR)Buffer + KeyDataOffset,
  589. KeyDataLength);
  590. }
  591. else if (!_wcsicmp(SubKeyName, cszFlushTimerValue)) { // FlushTimer
  592. RtlCopyMemory(&(LoggerInfo->FlushTimer),
  593. (PUCHAR)Buffer + KeyDataOffset,
  594. KeyDataLength);
  595. }
  596. else if (!_wcsicmp(SubKeyName, cszEnableKernelValue)) { // EnableKernelValue
  597. RtlCopyMemory(&(LoggerInfo->EnableFlags),
  598. (PUCHAR)Buffer + KeyDataOffset,
  599. KeyDataLength);
  600. }
  601. else if (!_wcsicmp(SubKeyName, cszClockTypeValue)) { // ClockTypeValue
  602. RtlCopyMemory(ClockType,
  603. (PUCHAR)Buffer + KeyDataOffset,
  604. KeyDataLength);
  605. }
  606. else if (!_wcsicmp(SubKeyName, cszFileNameValue)) { // FileName
  607. #ifndef UNICODE
  608. WCHAR TempString[MAXSTR];
  609. RtlCopyMemory(TempString, (PUCHAR)Buffer + KeyDataOffset, KeyDataLength);
  610. WideCharToMultiByte(CP_ACP,
  611. 0,
  612. TempString,
  613. wcslen(TempString),
  614. (PUCHAR)LoggerInfo + LoggerInfo->LogFileNameOffset,
  615. KeyDataLength,
  616. NULL,
  617. NULL);
  618. #else
  619. RtlCopyMemory((PUCHAR)LoggerInfo + LoggerInfo->LogFileNameOffset,
  620. (PUCHAR)Buffer + KeyDataOffset,
  621. KeyDataLength);
  622. #endif
  623. }
  624. else { // Some other keys are in there
  625. _tprintf(_T("Warning: Unidentified Key in the trace registry: %s\n"), SubKeyName);
  626. }
  627. }
  628. while (1);
  629. NtClose(KeyHandle);
  630. free(Buffer);
  631. return 0;
  632. }
  633. #endif // 0
  634. LONG ConvertStringToNum(CString Str)
  635. {
  636. CString str;
  637. LONG retVal;
  638. if( (Str.GetLength() > 1) &&
  639. (Str[0] == '0' && Str[1] == 'x') ) {
  640. retVal = _tcstoul(Str, '\0', 16);
  641. } else {
  642. retVal = _tcstoul(Str, '\0', 10);
  643. }
  644. str.Format(_T("retVal = 0x%X"), retVal);
  645. return retVal;
  646. }
  647. BOOL ClearDirectory(LPCTSTR Directory)
  648. {
  649. CString tempDirectory;
  650. CString tempPath;
  651. CFileFind fileFind;
  652. BOOL result = TRUE;
  653. tempDirectory = (LPCTSTR)Directory;
  654. tempPath = (LPCTSTR)Directory;
  655. tempDirectory +=_T("\\*.*");
  656. //
  657. // Clear the directory first
  658. //
  659. if(fileFind.FindFile(tempDirectory)) {
  660. tempDirectory = (LPCTSTR)tempPath;
  661. while(fileFind.FindNextFile()) {
  662. tempPath = (LPCTSTR)tempDirectory;
  663. tempPath +=_T("\\");
  664. tempPath += fileFind.GetFileName();
  665. if(!DeleteFile(tempPath)) {
  666. result = FALSE;
  667. }
  668. }
  669. tempPath = (LPCTSTR)tempDirectory;
  670. tempPath +=_T("\\");
  671. tempPath += fileFind.GetFileName();
  672. if(!DeleteFile(tempPath)) {
  673. result = FALSE;
  674. }
  675. }
  676. fileFind.Close();
  677. return result;
  678. }
  679. // Our CEdit class
  680. CSubItemEdit::CSubItemEdit(int iItem, int iSubItem, CListCtrl *pListControl)
  681. {
  682. m_iItem = iItem;
  683. m_iSubItem = iSubItem;
  684. m_bESC = FALSE;
  685. m_pListControl = pListControl;
  686. }
  687. BEGIN_MESSAGE_MAP(CSubItemEdit, CEdit)
  688. //{{AFX_MSG_MAP(CSubItemEdit)
  689. ON_WM_KILLFOCUS()
  690. ON_WM_NCDESTROY()
  691. ON_WM_CHAR()
  692. ON_WM_CREATE()
  693. //}}AFX_MSG_MAP
  694. END_MESSAGE_MAP()
  695. /////////////////////////////////////////////////////////////////////////////
  696. // CSubItemEdit message handlers
  697. BOOL CSubItemEdit::PreTranslateMessage(MSG* pMsg)
  698. {
  699. if( pMsg->message == WM_KEYDOWN )
  700. {
  701. if(pMsg->wParam == VK_RETURN
  702. || pMsg->wParam == VK_DELETE
  703. || pMsg->wParam == VK_ESCAPE
  704. || GetKeyState( VK_CONTROL)
  705. )
  706. {
  707. ::TranslateMessage(pMsg);
  708. ::DispatchMessage(pMsg);
  709. return TRUE;
  710. }
  711. }
  712. return CEdit::PreTranslateMessage(pMsg);
  713. }
  714. void CSubItemEdit::OnKillFocus(CWnd* pNewWnd)
  715. {
  716. CString str;
  717. CString newValue = "0x";
  718. BOOL bIsHex = FALSE;
  719. //
  720. // if escape was hit don't do anything
  721. //
  722. if(m_bESC) {
  723. CEdit::OnKillFocus(pNewWnd);
  724. DestroyWindow();
  725. return;
  726. }
  727. GetWindowText(str);
  728. //
  729. // Skip any hex notation
  730. //
  731. if((str[0] == '0') && (str[1] == 'x')) {
  732. str = str.Right(str.GetLength() - 2);
  733. bIsHex = TRUE;
  734. }
  735. //
  736. // Validate the value
  737. //
  738. for(int ii = 0; ii < str.GetLength(); ii++) {
  739. if(str[ii] < '0' || str[ii] > '9') {
  740. if((str[ii] < 'a' || str[ii] > 'f') &&
  741. (str[ii] < 'A' || str[ii] > 'F')) {
  742. CEdit::OnKillFocus(pNewWnd);
  743. DestroyWindow();
  744. return;
  745. }
  746. bIsHex = TRUE;
  747. }
  748. }
  749. if(bIsHex) {
  750. newValue += (LPCTSTR)str;
  751. str = (LPCTSTR)newValue;
  752. }
  753. //
  754. // Send Notification to parent of ListView ctrl
  755. //
  756. LV_DISPINFO dispinfo;
  757. dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
  758. dispinfo.hdr.idFrom = GetDlgCtrlID();
  759. dispinfo.hdr.code = LVN_ENDLABELEDIT;
  760. dispinfo.item.mask = LVIF_TEXT;
  761. dispinfo.item.iItem = m_iItem;
  762. dispinfo.item.iSubItem = m_iSubItem;
  763. dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
  764. dispinfo.item.cchTextMax = str.GetLength();
  765. m_pListControl->SetItemText(m_iItem, m_iSubItem, str);
  766. GetParent()->SendMessage(WM_PARAMETER_CHANGED,
  767. m_iItem,
  768. m_iSubItem);
  769. CEdit::OnKillFocus(pNewWnd);
  770. DestroyWindow();
  771. }
  772. void CSubItemEdit::OnNcDestroy()
  773. {
  774. CEdit::OnNcDestroy();
  775. delete this;
  776. }
  777. void CSubItemEdit::OnChar(UINT Char, UINT nRepCnt, UINT nFlags)
  778. {
  779. if(Char == VK_ESCAPE || Char == VK_RETURN)
  780. {
  781. if(Char == VK_ESCAPE) {
  782. m_bESC = TRUE;
  783. }
  784. GetParent()->SetFocus();
  785. return;
  786. }
  787. CEdit::OnChar(Char, nRepCnt, nFlags);
  788. }
  789. int CSubItemEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
  790. {
  791. CString str;
  792. if (CEdit::OnCreate(lpCreateStruct) == -1)
  793. return -1;
  794. //
  795. // Set the proper font
  796. //
  797. CFont* font = GetParent()->GetFont();
  798. SetFont(font);
  799. str = m_pListControl->GetItemText(m_iItem, m_iSubItem);
  800. SetWindowText(str);
  801. SetFocus();
  802. SetSel( 0, -1 );
  803. return 0;
  804. }
  805. // Our CComboBox class
  806. CSubItemCombo::CSubItemCombo(int iItem, int iSubItem, CListCtrl *pListControl)
  807. {
  808. m_iItem = iItem;
  809. m_iSubItem = iSubItem;
  810. m_bESC = FALSE;
  811. m_pListControl = pListControl;
  812. }
  813. BEGIN_MESSAGE_MAP(CSubItemCombo, CComboBox)
  814. //{{AFX_MSG_MAP(CSubItemCombo)
  815. ON_WM_KILLFOCUS()
  816. ON_WM_NCDESTROY()
  817. ON_WM_CHAR()
  818. ON_WM_CREATE()
  819. ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
  820. //}}AFX_MSG_MAP
  821. END_MESSAGE_MAP()
  822. /////////////////////////////////////////////////////////////////////////////
  823. // CSubItemCombo message handlers
  824. BOOL CSubItemCombo::PreTranslateMessage(MSG* pMsg)
  825. {
  826. if( pMsg->message == WM_KEYDOWN ) {
  827. if(pMsg->wParam == VK_RETURN
  828. || pMsg->wParam == VK_ESCAPE) {
  829. ::TranslateMessage(pMsg);
  830. ::DispatchMessage(pMsg);
  831. return TRUE;
  832. }
  833. }
  834. return CComboBox::PreTranslateMessage(pMsg);
  835. }
  836. void CSubItemCombo::OnKillFocus(CWnd* pNewWnd)
  837. {
  838. CString str;
  839. GetWindowText(str);
  840. CComboBox::OnKillFocus(pNewWnd);
  841. //
  842. // Send Notification to parent of ListView ctrl
  843. //
  844. LV_DISPINFO dispinfo;
  845. dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
  846. dispinfo.hdr.idFrom = GetDlgCtrlID();
  847. dispinfo.hdr.code = LVN_ENDLABELEDIT;
  848. dispinfo.item.mask = LVIF_TEXT;
  849. dispinfo.item.iItem = m_iItem;
  850. dispinfo.item.iSubItem = m_iSubItem;
  851. dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
  852. dispinfo.item.cchTextMax = str.GetLength();
  853. if(!m_bESC) {
  854. m_pListControl->SetItemText(m_iItem, m_iSubItem, str);
  855. }
  856. GetParent()->GetParent()->SendMessage(WM_PARAMETER_CHANGED,
  857. m_iItem,
  858. m_iSubItem);
  859. DestroyWindow();
  860. }
  861. void CSubItemCombo::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  862. {
  863. if( nChar == VK_ESCAPE || nChar == VK_RETURN)
  864. {
  865. if( nChar == VK_ESCAPE )
  866. m_bESC = TRUE;
  867. GetParent()->SetFocus();
  868. return;
  869. }
  870. CComboBox::OnChar(nChar, nRepCnt, nFlags);
  871. }
  872. void CSubItemCombo::OnNcDestroy()
  873. {
  874. CComboBox::OnNcDestroy();
  875. delete this;
  876. }
  877. int CSubItemCombo::OnCreate(LPCREATESTRUCT lpCreateStruct)
  878. {
  879. CString str;
  880. int index;
  881. if (CComboBox::OnCreate(lpCreateStruct) == -1) {
  882. return -1;
  883. }
  884. //
  885. // Set the proper font
  886. //
  887. CFont* font = GetParent()->GetFont();
  888. SetFont(font);
  889. AddString(_T("TRUE"));
  890. AddString(_T("FALSE"));
  891. str = m_pListControl->GetItemText(m_iItem, m_iSubItem);
  892. index = FindStringExact(0, str);
  893. SetCurSel(index);
  894. SetFocus();
  895. return 0;
  896. }
  897. void CSubItemCombo::OnCloseup()
  898. {
  899. GetParent()->SetFocus();
  900. }