Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1354 lines
28 KiB

  1. // StructureWapperHelpers.cpp
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. //***************************************************************************
  5. //
  6. // judyp May 1999
  7. //
  8. //***************************************************************************
  9. #include "stdafx.h"
  10. #pragma warning (disable : 4786)
  11. #pragma warning (disable : 4275)
  12. #include <iostream>
  13. #include <strstream>
  14. #include <fstream>
  15. #include <string>
  16. #include <sstream>
  17. #include <map>
  18. #include <list>
  19. using namespace std;
  20. #include <tchar.h>
  21. #include <windows.h>
  22. #ifdef NONNT5
  23. typedef unsigned long ULONG_PTR;
  24. #endif
  25. #include <wmistr.h>
  26. #include <guiddef.h>
  27. #include <initguid.h>
  28. #include <evntrace.h>
  29. #include <WTYPES.H>
  30. #include "t_string.h"
  31. #include "Persistor.h"
  32. #include "Logger.h"
  33. #include "TCOData.h"
  34. #include "Utilities.h"
  35. #include "StructureWrappers.h"
  36. #include "StructureWapperHelpers.h"
  37. #include "ConstantMap.h"
  38. extern CConstantMap g_ConstantMap;
  39. static TCHAR g_tcNl = _T('\n');
  40. static TCHAR g_tcCR = 0x0d;
  41. static TCHAR g_tcLF = 0x0a;
  42. #ifdef _UNICODE
  43. static TCHAR g_tcDQuote[] = _T("\"");
  44. static TCHAR g_atcNL[] = {0x0d, 0x0a, 0x00};
  45. #else
  46. static TCHAR g_atcNL[] = {g_tcNl};
  47. static TCHAR g_tcDQuote = _T('"');
  48. #endif
  49. // Why we are not using formatted input:
  50. #if 0
  51. From: Phil Lucido (Exchange)
  52. Sent: Friday, April 16, 1999 10:34 AM
  53. To: Judy Powell
  54. Cc: Visual C++ Special Interest Group
  55. Subject: RE: Wide character output via wfstream from the "Standard Library"
  56. using VC 6 Enterprise Edition SP2 on NT4 SP4
  57. It looks like our iostreams implementation for wide-char streams is actually wide-char
  58. in memory, multibyte chars on disk. The reason you get an empty file is because wctomb
  59. is failing on 0xfeff.
  60. This should work more like the stdio stuff, where a text mode wide-char stream writes
  61. multibyte chars to a file, but binary mode writes the raw unicode.
  62. We get our C++ Library implementation from Dinkumware (P.J. Plauger). I'll check with
  63. him to see about changing this implementation so binary mode wide-char iostream is
  64. compatible with wide-char stdio.
  65. ...Phil
  66. #endif
  67. //////////////////////////////////////////////////////////////////////
  68. // Helpers
  69. //////////////////////////////////////////////////////////////////////
  70. void LogFileModeOut(t_ostream &ros, ULONG LogFileMode)
  71. {
  72. // EVENT_TRACE_FILE_MODE_NONE 0x0000 // logfile is off
  73. // EVENT_TRACE_FILE_MODE_SEQUENTIAL 0x0001 // log sequentially
  74. // EVENT_TRACE_FILE_MODE_CIRCULAR 0x0002 // log in circular manner
  75. // EVENT_TRACE_FILE_MODE_NEWFILE 0x0004 // log to new file if full
  76. // EVENT_TRACE_REAL_TIME_MODE 0x0100 // real time mode on
  77. // EVENT_TRACE_DELAY_OPEN_FILE_MODE 0x0200 // delay opening file
  78. // EVENT_TRACE_BUFFERING_MODE 0x0400 // buffering mode only
  79. t_string tsOut;
  80. // @#$ENUM: says that we are not storing a literal value.
  81. tsOut = _T("\"LogFileMode:@#$ENUM:");
  82. PutALine(ros, tsOut.c_str());
  83. bool bFirstOut = true;
  84. // Values we anticipate.
  85. if (LogFileMode == 0)
  86. {
  87. tsOut = _T("0");
  88. PutALine(ros, tsOut.c_str());
  89. bFirstOut = false;
  90. }
  91. if (LogFileMode & EVENT_TRACE_FILE_MODE_NONE)
  92. {
  93. tsOut = _T("EVENT_TRACE_FILE_MODE_NONE");
  94. PutALine(ros, tsOut.c_str());
  95. bFirstOut = false;
  96. }
  97. if (LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL)
  98. {
  99. if (bFirstOut)
  100. {
  101. tsOut = _T("EVENT_TRACE_FILE_MODE_SEQUENTIAL");
  102. PutALine(ros, tsOut.c_str());
  103. bFirstOut = false;
  104. }
  105. else
  106. {
  107. tsOut = _T("|EVENT_TRACE_FILE_MODE_SEQUENTIAL");
  108. PutALine(ros, tsOut.c_str());
  109. }
  110. }
  111. if (LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR)
  112. {
  113. if (bFirstOut)
  114. {
  115. tsOut = _T("EVENT_TRACE_FILE_MODE_CIRCULAR");
  116. PutALine(ros, tsOut.c_str());
  117. bFirstOut = false;
  118. }
  119. else
  120. {
  121. tsOut = _T("|EVENT_TRACE_FILE_MODE_CIRCULAR");
  122. PutALine(ros, tsOut.c_str());
  123. }
  124. }
  125. if (LogFileMode & EVENT_TRACE_FILE_MODE_NEWFILE)
  126. {
  127. if (bFirstOut)
  128. {
  129. tsOut = _T("EVENT_TRACE_FILE_MODE_NEWFILE");
  130. PutALine(ros, tsOut.c_str());
  131. bFirstOut = false;
  132. }
  133. else
  134. {
  135. tsOut = _T("|EVENT_TRACE_FILE_MODE_NEWFILE");
  136. PutALine(ros, tsOut.c_str());
  137. }
  138. }
  139. if (LogFileMode & EVENT_TRACE_REAL_TIME_MODE)
  140. {
  141. if (bFirstOut)
  142. {
  143. tsOut = _T("EVENT_TRACE_REAL_TIME_MODE");
  144. PutALine(ros, tsOut.c_str());
  145. bFirstOut = false;
  146. }
  147. else
  148. {
  149. tsOut = _T("|EVENT_TRACE_REAL_TIME_MODE");
  150. PutALine(ros, tsOut.c_str());
  151. }
  152. }
  153. if (LogFileMode & EVENT_TRACE_DELAY_OPEN_FILE_MODE)
  154. {
  155. if (bFirstOut)
  156. {
  157. tsOut = _T("EVENT_TRACE_DELAY_OPEN_FILE_MODE");
  158. PutALine(ros, tsOut.c_str());
  159. bFirstOut = false;
  160. }
  161. else
  162. {
  163. tsOut = _T("|EVENT_TRACE_DELAY_OPEN_FILE_MODE");
  164. PutALine(ros, tsOut.c_str());
  165. }
  166. }
  167. if (LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE)
  168. {
  169. if (bFirstOut)
  170. {
  171. tsOut = _T("EVENT_TRACE_PRIVATE_LOGGER_MODE");
  172. PutALine(ros, tsOut.c_str());
  173. bFirstOut = false;
  174. }
  175. else
  176. {
  177. tsOut = _T("|EVENT_TRACE_PRIVATE_LOGGER_MODE");
  178. PutALine(ros, tsOut.c_str());
  179. }
  180. }
  181. if (LogFileMode & EVENT_TRACE_BUFFERING_MODE)
  182. {
  183. if (bFirstOut)
  184. {
  185. tsOut = _T("EVENT_TRACE_BUFFERING_MODE");
  186. PutALine(ros, tsOut.c_str());
  187. bFirstOut = false;
  188. }
  189. else
  190. {
  191. tsOut = _T("|EVENT_TRACE_BUFFERING_MODE");
  192. PutALine(ros, tsOut.c_str());
  193. }
  194. }
  195. // A value we did not anticipate.
  196. ULONG uExpected =
  197. EVENT_TRACE_FILE_MODE_NONE |
  198. EVENT_TRACE_FILE_MODE_SEQUENTIAL |
  199. EVENT_TRACE_FILE_MODE_CIRCULAR |
  200. EVENT_TRACE_FILE_MODE_NEWFILE |
  201. EVENT_TRACE_REAL_TIME_MODE |
  202. EVENT_TRACE_DELAY_OPEN_FILE_MODE |
  203. EVENT_TRACE_BUFFERING_MODE |
  204. EVENT_TRACE_PRIVATE_LOGGER_MODE;
  205. if ((uExpected | LogFileMode) != uExpected)
  206. {
  207. if (bFirstOut)
  208. {
  209. tsOut = _T("@#$UNKNOWNVALUE:0x");
  210. PutALine(ros, tsOut.c_str());
  211. PutAULONGVar(ros, ~uExpected & LogFileMode, true);
  212. }
  213. else
  214. {
  215. tsOut = _T("|@#$UNKNOWNVALUE:0x");
  216. PutALine(ros, tsOut.c_str());
  217. PutAULONGVar(ros, ~uExpected & LogFileMode, true);
  218. }
  219. }
  220. tsOut = g_tcDQuote;
  221. tsOut += g_atcNL;
  222. PutALine(ros, tsOut.c_str());
  223. }
  224. void EnableFlagsOut(t_ostream &ros, ULONG EnableFlags)
  225. {
  226. // EVENT_TRACE_FLAG_PROCESS 0x00000001 // process start & end
  227. // EVENT_TRACE_FLAG_THREAD 0x00000002 // thread start & end
  228. // EVENT_TRACE_FLAG_IMAGE_LOAD 0x00000004 // image load
  229. // EVENT_TRACE_FLAG_DISK_IO 0x00000100 // physical disk IO
  230. // EVENT_TRACE_FLAG_DISK_FILE_IO 0x00000200 // requires disk IO
  231. // EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS 0x00001000 // all page faults
  232. // EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS 0x00002000 // hard faults only
  233. // EVENT_TRACE_FLAG_NETWORK_TCPIP 0x00010000 // tcpip send & receive
  234. //
  235. // Pre-defined Enable flags for everybody else
  236. //
  237. // EVENT_TRACE_FLAG_PRIVATE 0xC0000000 // Private buffering
  238. // EVENT_TRACE_FLAG_EXTENSION 0x80000000 // indicates more flags
  239. // EVENT_TRACE_FLAG_FORWARD_WMI 0x40000000 // Can forward to WMI
  240. // EVENT_TRACE_FLAG_ENABLE_RESERVE1 0x20000000 // Reserved
  241. // EVENT_TRACE_FLAG_ENABLE_RESERVE2 0x10000000 // Reserved
  242. t_string tsOut;
  243. // @#$ENUM: says that we are not storing a literal value.
  244. tsOut = _T("\"EnableFlags:@#$ENUM:");
  245. PutALine(ros, tsOut.c_str());
  246. bool bFirstOut = true;
  247. if (EnableFlags == 0)
  248. {
  249. tsOut = _T("0");
  250. PutALine(ros, tsOut.c_str());
  251. bFirstOut = false;
  252. }
  253. if (EnableFlags & EVENT_TRACE_FLAG_PROCESS)
  254. {
  255. tsOut = _T("EVENT_TRACE_FLAG_PROCESS");
  256. PutALine(ros, tsOut.c_str());
  257. bFirstOut = false;
  258. }
  259. if (EnableFlags & EVENT_TRACE_FLAG_THREAD)
  260. {
  261. if (bFirstOut)
  262. {
  263. tsOut = _T("EVENT_TRACE_FLAG_THREAD");
  264. PutALine(ros, tsOut.c_str());
  265. bFirstOut = false;
  266. }
  267. else
  268. {
  269. tsOut = _T("|EVENT_TRACE_FLAG_THREAD");
  270. PutALine(ros, tsOut.c_str());
  271. }
  272. }
  273. if (EnableFlags & EVENT_TRACE_FLAG_THREAD)
  274. {
  275. if (bFirstOut)
  276. {
  277. tsOut = _T("EVENT_TRACE_FLAG_THREAD");
  278. PutALine(ros, tsOut.c_str());
  279. bFirstOut = false;
  280. }
  281. else
  282. {
  283. tsOut = _T("|EVENT_TRACE_FLAG_THREAD");
  284. PutALine(ros, tsOut.c_str());
  285. }
  286. }
  287. if (EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
  288. {
  289. if (bFirstOut)
  290. {
  291. tsOut = _T("EVENT_TRACE_FLAG_IMAGE_LOAD");
  292. PutALine(ros, tsOut.c_str());
  293. bFirstOut = false;
  294. }
  295. else
  296. {
  297. tsOut = _T("|EVENT_TRACE_FLAG_IMAGE_LOAD");
  298. PutALine(ros, tsOut.c_str());
  299. }
  300. }
  301. if (EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
  302. {
  303. if (bFirstOut)
  304. {
  305. tsOut = _T("EVENT_TRACE_FLAG_DISK_IO");
  306. PutALine(ros, tsOut.c_str());
  307. bFirstOut = false;
  308. }
  309. else
  310. {
  311. tsOut = _T("|EVENT_TRACE_FLAG_DISK_IO");
  312. PutALine(ros, tsOut.c_str());
  313. }
  314. }
  315. if (EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
  316. {
  317. if (bFirstOut)
  318. {
  319. tsOut = _T("EVENT_TRACE_FLAG_DISK_FILE_IO");
  320. PutALine(ros, tsOut.c_str());
  321. bFirstOut = false;
  322. }
  323. else
  324. {
  325. tsOut = _T("|EVENT_TRACE_FLAG_DISK_FILE_IO");
  326. PutALine(ros, tsOut.c_str());
  327. }
  328. }
  329. if (EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
  330. {
  331. if (bFirstOut)
  332. {
  333. tsOut = _T("EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS");
  334. PutALine(ros, tsOut.c_str());
  335. bFirstOut = false;
  336. }
  337. else
  338. {
  339. tsOut = _T("|EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS");
  340. PutALine(ros, tsOut.c_str());
  341. }
  342. }
  343. if (EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
  344. {
  345. if (bFirstOut)
  346. {
  347. tsOut = _T("EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS");
  348. PutALine(ros, tsOut.c_str());
  349. bFirstOut = false;
  350. }
  351. else
  352. {
  353. tsOut = _T("|EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS");
  354. PutALine(ros, tsOut.c_str());
  355. }
  356. }
  357. if (EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
  358. {
  359. if (bFirstOut)
  360. {
  361. tsOut = _T("EVENT_TRACE_FLAG_NETWORK_TCPIP");
  362. PutALine(ros, tsOut.c_str());
  363. bFirstOut = false;
  364. }
  365. else
  366. {
  367. tsOut = _T("|EVENT_TRACE_FLAG_NETWORK_TCPIP");
  368. PutALine(ros, tsOut.c_str());
  369. }
  370. }
  371. #if 0
  372. if (EnableFlags & EVENT_TRACE_FLAG_PRIVATE)
  373. {
  374. if (bFirstOut)
  375. {
  376. tsOut = _T("EVENT_TRACE_FLAG_PRIVATE");
  377. PutALine(ros, tsOut.c_str());
  378. bFirstOut = false;
  379. }
  380. else
  381. {
  382. tsOut = _T("|EVENT_TRACE_FLAG_PRIVATE");
  383. PutALine(ros, tsOut.c_str());
  384. }
  385. }
  386. #endif
  387. if (EnableFlags & EVENT_TRACE_FLAG_EXTENSION)
  388. {
  389. if (bFirstOut)
  390. {
  391. tsOut = _T("EVENT_TRACE_FLAG_EXTENSION");
  392. PutALine(ros, tsOut.c_str());
  393. bFirstOut = false;
  394. }
  395. else
  396. {
  397. tsOut = _T("|EVENT_TRACE_FLAG_EXTENSION");
  398. PutALine(ros, tsOut.c_str());
  399. }
  400. }
  401. if (EnableFlags & EVENT_TRACE_FLAG_FORWARD_WMI)
  402. {
  403. if (bFirstOut)
  404. {
  405. tsOut = _T("EVENT_TRACE_FLAG_FORWARD_WMI");
  406. PutALine(ros, tsOut.c_str());
  407. bFirstOut = false;
  408. }
  409. else
  410. {
  411. tsOut = _T("|EVENT_TRACE_FLAG_FORWARD_WMI");
  412. PutALine(ros, tsOut.c_str());
  413. }
  414. }
  415. #if 0
  416. if (EnableFlags & EVENT_TRACE_FLAG_ENABLE_RESERVE1)
  417. {
  418. if (bFirstOut)
  419. {
  420. tsOut = _T("EVENT_TRACE_FLAG_ENABLE_RESERVE1");
  421. PutALine(ros, tsOut.c_str());
  422. bFirstOut = false;
  423. }
  424. else
  425. {
  426. tsOut = _T("|EVENT_TRACE_FLAG_ENABLE_RESERVE1");
  427. PutALine(ros, tsOut.c_str());
  428. }
  429. }
  430. if (EnableFlags & EVENT_TRACE_FLAG_ENABLE_RESERVE2)
  431. {
  432. if (bFirstOut)
  433. {
  434. tsOut = _T("EVENT_TRACE_FLAG_ENABLE_RESERVE2");
  435. PutALine(ros, tsOut.c_str());
  436. bFirstOut = false;
  437. }
  438. else
  439. {
  440. tsOut = _T("|EVENT_TRACE_FLAG_ENABLE_RESERVE2");
  441. PutALine(ros, tsOut.c_str());
  442. }
  443. }
  444. #endif
  445. ULONG uExpected =
  446. EVENT_TRACE_FLAG_PROCESS |
  447. EVENT_TRACE_FLAG_THREAD |
  448. EVENT_TRACE_FLAG_IMAGE_LOAD |
  449. EVENT_TRACE_FLAG_DISK_IO |
  450. EVENT_TRACE_FLAG_DISK_FILE_IO |
  451. EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS |
  452. EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS |
  453. EVENT_TRACE_FLAG_NETWORK_TCPIP |
  454. EVENT_TRACE_FLAG_EXTENSION |
  455. EVENT_TRACE_FLAG_FORWARD_WMI;
  456. if ((uExpected | EnableFlags) != uExpected)
  457. {
  458. if (bFirstOut)
  459. {
  460. tsOut = _T("@#$UNKNOWNVALUE:0x");
  461. PutALine(ros, tsOut.c_str());
  462. PutAULONGVar(ros, ~uExpected & EnableFlags, true);
  463. }
  464. else
  465. {
  466. tsOut = _T("|@#$UNKNOWNVALUE:0x");
  467. PutALine(ros, tsOut.c_str());
  468. PutAULONGVar(ros, ~uExpected & EnableFlags, true);
  469. }
  470. }
  471. tsOut = g_tcDQuote;
  472. tsOut += g_atcNL;
  473. PutALine(ros, tsOut.c_str());
  474. }
  475. // "Wnode.Flags:@#$ENUM:WNODE_FLAG_ALL_DATA"
  476. void WnodeFlagsOut(t_ostream &ros, ULONG WnodeFlags)
  477. {
  478. t_string tsOut;
  479. // @#$ENUM: says that we are not storing a literal value.
  480. tsOut = _T("\"Wnode.Flags:@#$ENUM:");
  481. PutALine(ros, tsOut.c_str());
  482. bool bFirstOut = true;
  483. if (WnodeFlags & WNODE_FLAG_TRACED_GUID)
  484. {
  485. if (bFirstOut)
  486. {
  487. tsOut = _T("WNODE_FLAG_TRACED_GUID");
  488. PutALine(ros, tsOut.c_str());
  489. bFirstOut = false;
  490. }
  491. else
  492. {
  493. tsOut = _T("|WNODE_FLAG_TRACED_GUID");
  494. PutALine(ros, tsOut.c_str());
  495. }
  496. }
  497. ULONG uExpected =
  498. WNODE_FLAG_TRACED_GUID;
  499. if ((uExpected | WnodeFlags) != uExpected)
  500. {
  501. if (bFirstOut)
  502. {
  503. tsOut = _T("@#$UNKNOWNVALUE:0x");
  504. PutALine(ros, tsOut.c_str());
  505. PutAULONGVar(ros, ~uExpected & WnodeFlags, true);
  506. }
  507. else
  508. {
  509. tsOut = _T("|@#$UNKNOWNVALUE:0x");
  510. PutALine(ros, tsOut.c_str());
  511. PutAULONGVar(ros, ~uExpected & WnodeFlags, true);
  512. }
  513. }
  514. tsOut = g_tcDQuote;
  515. tsOut += g_atcNL;
  516. PutALine(ros, tsOut.c_str());
  517. }
  518. // We print out a GUID in the form:
  519. // "{0000cbd1-0011-11d0-0d00-00aa006d010a}"
  520. // typedef struct _GUID
  521. // {
  522. // DWORD Data1;
  523. // WORD Data2;
  524. // WORD Data3;
  525. // BYTE Data4[8];
  526. // } GUID;
  527. // Data4 specifies an array of 8 bytes. The first 2 bytes contain
  528. // the third group of 4 hexadecimal digits. The remaining 6 bytes
  529. // contain the final 12 hexadecimal digits. We have separate
  530. // logic for acsii and unicode for Data4.
  531. void GUIDOut(t_ostream &ros, GUID Guid)
  532. {
  533. t_string tsOut;
  534. t_strstream strStream;
  535. strStream << _T("{");
  536. strStream.fill(_T('0'));
  537. strStream.width(8);
  538. strStream.flags(ros.flags() | ios_base::right);
  539. strStream << hex << Guid.Data1;
  540. strStream << _T("-");
  541. strStream.width(4);
  542. strStream << hex << Guid.Data2;
  543. strStream << _T("-");
  544. strStream << hex << Guid.Data3;
  545. strStream << _T("-");
  546. // Data4 specifies an array of 8 bytes. The first 2 bytes contain
  547. // the third group of 4 hexadecimal digits. The remaining 6 bytes
  548. // contain the final 12 hexadecimal digits.
  549. #ifndef _UNICODE
  550. int i;
  551. strStream.width(1);
  552. BYTE Byte;
  553. int Int;
  554. for (i = 0; i < 2; i++)
  555. {
  556. Byte = Guid.Data4[i];
  557. Byte = Byte >> 4;
  558. Int = Byte;
  559. strStream << hex << Int;
  560. Byte = Guid.Data4[i];
  561. Byte = 0x0f & Byte;
  562. Int = Byte;
  563. strStream << hex << Int;
  564. }
  565. strStream << _T("-");
  566. strStream.width(1);
  567. for (i = 2; i < 8; i++)
  568. {
  569. BYTE Byte = Guid.Data4[i];
  570. Byte = Byte >> 4;
  571. Int = Byte;
  572. strStream << hex << Int;
  573. Byte = Guid.Data4[i];
  574. Byte = 0x0f & Byte;
  575. Int = Byte;
  576. strStream << hex << Int;
  577. }
  578. #else
  579. int i;
  580. for (i = 0; i < 2; i++)
  581. {
  582. TCHAR tc = Guid.Data4[i];
  583. // For some reason the width is reset each time through the
  584. // loop to be one.
  585. strStream.width(2);
  586. strStream << hex << tc;
  587. }
  588. strStream << _T("-");
  589. BYTE Byte;
  590. strStream.width(1);
  591. for (i = 2; i < 8; i++)
  592. {
  593. Byte = Guid.Data4[i];
  594. Byte = Byte >> 4;
  595. strStream << hex << Byte;
  596. Byte = Guid.Data4[i];
  597. Byte = 0x0f & Byte;
  598. strStream << hex << Byte;
  599. }
  600. #endif
  601. strStream << _T("}");
  602. strStream >> tsOut;
  603. PutALine(ros, tsOut.c_str() , -1);
  604. }
  605. void LARGE_INTEGEROut(t_ostream &ros, LARGE_INTEGER Large)
  606. {
  607. t_string tsOut;
  608. tsOut = _T("{0x");
  609. PutALine(ros, tsOut.c_str() , -1);
  610. LONG Long = Large.u.HighPart;
  611. PutALONGVar(ros, Large.u.HighPart,true);
  612. DWORD DWord = Large.u.LowPart;
  613. PutADWORDVar(ros, DWord);
  614. tsOut = _T("}");
  615. PutALine(ros, tsOut.c_str() , -1);
  616. }
  617. void InitializeTCHARVar(t_string &rtsValue , void *pVar)
  618. {
  619. TCHAR **pTCHAR = reinterpret_cast<TCHAR **> (pVar);
  620. if (rtsValue.length() > 0)
  621. {
  622. // Null string.
  623. if (case_insensitive_compare(rtsValue,_T("@#$STRING_NULL")) == 0)
  624. {
  625. *pTCHAR = NULL;
  626. }
  627. // Empty string.
  628. else if (case_insensitive_compare(rtsValue,_T("@#$STRING_EMPTY")) == 0)
  629. {
  630. *pTCHAR = NewTCHAR(_T(""));
  631. }
  632. else // Just a string.
  633. {
  634. *pTCHAR = NewTCHAR(rtsValue.c_str());
  635. }
  636. }
  637. else // Empty string.
  638. {
  639. *pTCHAR = NewTCHAR(_T(""));
  640. }
  641. }
  642. //"EVENT_TRACE_FILE_MODE_NEWFILE|EVENT_TRACE_REAL_TIME_MODE|@#$UNKNOWNVALUE:0x20"
  643. //"EVENT_TRACE_FLAG_IMAGE_LOAD|EVENT_TRACE_FLAG_DISK_IO|@#$UNKNOWNVALUE:0x20"
  644. void InitializeEnumVar(t_string &rtsValue , void *pVar)
  645. {
  646. ULONG *pULong = reinterpret_cast<ULONG *> (pVar);
  647. *pULong = 0;
  648. int nEndPos;
  649. int nBegPos = 0;
  650. int nSubstrLen;
  651. t_string tsTemp;
  652. CONSTMAP::iterator Iterator;
  653. bool bDone = false;
  654. while (!bDone)
  655. {
  656. nEndPos = rtsValue.find(_T("|"), nBegPos);
  657. if (nEndPos == t_string::npos)
  658. {
  659. bDone = true;
  660. nEndPos = rtsValue.length();
  661. }
  662. nSubstrLen = nEndPos - nBegPos;
  663. tsTemp = rtsValue.substr(nBegPos, nSubstrLen);
  664. Iterator = g_ConstantMap.m_Map.find(tsTemp);
  665. if (Iterator == g_ConstantMap.m_Map.end())
  666. {
  667. // Had better be @#$UNKNOWNVALUE:0x
  668. if (tsTemp.compare(0, 18, _T("@#$UNKNOWNVALUE:0x")) == 0)
  669. {
  670. tsTemp = rtsValue.substr(nBegPos + 18);
  671. ULONG ulTemp;
  672. InitializeULONGVar(tsTemp , (void *) &ulTemp, true);
  673. *pULong |= ulTemp;
  674. }
  675. }
  676. else
  677. {
  678. *pULong |= (*Iterator).second;
  679. }
  680. nBegPos = nEndPos + 1;
  681. }
  682. }
  683. // Expect HANDLEs to be in the form 0xnnnnnnnn
  684. void InitializeHandleVar(t_string &rtsValue , void *pVar)
  685. {
  686. HANDLE *pHandle = reinterpret_cast<HANDLE *> (pVar);
  687. HANDLE handle;
  688. t_strstream strStream;
  689. t_string tsTemp;
  690. tsTemp = rtsValue.substr(2);
  691. strStream << tsTemp;
  692. strStream >> handle;
  693. *pHandle = handle;
  694. }
  695. void InitializeULONGVar(t_string &rtsValue , void *pVar, bool bHex )
  696. {
  697. ULONG *pULong = reinterpret_cast<ULONG *> (pVar);
  698. ULONG uLong;
  699. t_strstream strStream;
  700. strStream << rtsValue;
  701. if (bHex)
  702. {
  703. strStream >> hex >> uLong;
  704. }
  705. else
  706. {
  707. strStream >> uLong;
  708. }
  709. *pULong = uLong;
  710. }
  711. void InitializeLONGVar(t_string &rtsValue , void *pVar)
  712. {
  713. LONG *pLong = reinterpret_cast<LONG *> (pVar);
  714. LONG Long;
  715. t_strstream strStream;
  716. strStream << rtsValue;
  717. strStream >> Long;
  718. *pLong = Long;
  719. }
  720. t_istream &GetAChar(t_istream &ris,TCHAR &tc)
  721. {
  722. #ifndef _UNICODE
  723. tc = ris.get();
  724. return ris;
  725. #else
  726. char *pChar = (char *) &tc;
  727. pChar[0] = ris.get();
  728. pChar[1] = ris.get();
  729. return ris;
  730. #endif
  731. }
  732. // See note at top of this file to understand why we are not using
  733. // formatted input.
  734. // We are reading in a wide character file one byte at a time and
  735. // creating our two byte characters from each two byte sequence.
  736. t_istream &GetALine(t_istream &ris,TCHAR *tcBuffer, int nBufferSize)
  737. {
  738. #ifndef _UNICODE
  739. t_istream &r = ris.getline(tcBuffer,nBufferSize - 1,_T('\n'));
  740. // Docs for getline say that it sould eat the new line. It does
  741. // not, and it does even worse. It returns a 0x0d which we delete.
  742. // This should work even when getline does
  743. // what the docs say it will.
  744. int n = _tcsclen(tcBuffer) - 1;
  745. if (tcBuffer[n] == 0x0d)
  746. {
  747. tcBuffer[n] = _T('\0');
  748. }
  749. return r;
  750. #else
  751. char *pChar = (char *) tcBuffer;
  752. bool bSkipNext = false;
  753. bool bEOL = false;
  754. int intIn1;
  755. int intIn2;
  756. int i = 0;
  757. int count = 0;
  758. while (1)
  759. {
  760. intIn1 = ris.get();
  761. if (ris.eof())
  762. {
  763. break;
  764. }
  765. intIn2 = ris.get();
  766. if (intIn1 == 0x0d && intIn2 == 0x0)
  767. {
  768. // Found 0x0d so eat the 0x0a.
  769. intIn1 = ris.get();
  770. intIn2 = ris.get();
  771. tcBuffer[i / 2] = _T('\0');
  772. break;
  773. }
  774. else
  775. {
  776. pChar[i++] = intIn1;
  777. pChar[i++] = intIn2;
  778. }
  779. }
  780. if (i == 0)
  781. {
  782. tcBuffer[0] = _T('\0');
  783. }
  784. return ris;
  785. #endif
  786. }
  787. // See note at top of this file to understand why we are not using
  788. // formatted input.
  789. // We are writing out a wide character file one byte at a time.
  790. // nBufferSize is the number of TCHARS not size in bytes.
  791. // if nBufferSize == -1 tcBuffer better be a null terminated string.
  792. // Will handle a unicode string with "proper" and "inproper" newlines.
  793. t_ostream &PutALine(t_ostream &ros,const TCHAR *tcBuffer, int nBufferSize)
  794. {
  795. #ifndef _UNICODE
  796. // return ros << tcBuffer;
  797. const char *pBuffer = tcBuffer;
  798. int nSize = nBufferSize;
  799. if (nBufferSize == -1)
  800. {
  801. nSize = _tcsclen(tcBuffer);
  802. }
  803. for (int i = 0; i < nSize; i++)
  804. {
  805. int intOut = pBuffer[i];
  806. if (intOut == 0x0a && pBuffer[i - 1] != 0x0d)
  807. {
  808. ros.put(0x0d);
  809. }
  810. ros.put(intOut);
  811. }
  812. return ros;
  813. #else
  814. char *pBuffer = (char *) tcBuffer;
  815. int nSize = nBufferSize;
  816. if (nBufferSize == -1)
  817. {
  818. nSize = _tcsclen(tcBuffer);
  819. }
  820. for (int i = 0; i < nSize * 2; i++)
  821. {
  822. int intOut = pBuffer[i];
  823. if (intOut == 0x0a && pBuffer[i - 2] != 0x0d)
  824. {
  825. ros.put(0x0d);
  826. ros.put(0x0);
  827. }
  828. ros.put(intOut);
  829. }
  830. return ros;
  831. #endif
  832. }
  833. // Hex flavor not tested for non-unicode.
  834. t_ostream &PutALONGVar(t_ostream &ros, LONG l, bool bHex)
  835. {
  836. #ifndef _UNICODE
  837. if (bHex)
  838. {
  839. TCHAR f = ros.fill(_T('0'));
  840. int w = ros.width(8);
  841. int fl = ros.flags(ros.flags() | ios_base::right);
  842. ros << hex << l;
  843. ros.fill(f);
  844. ros.width(w);
  845. ros.flags(fl);
  846. return ros << dec;
  847. }
  848. else
  849. {
  850. return ros << l;
  851. }
  852. #else
  853. t_string tsTemp;
  854. t_strstream strStream;
  855. if (bHex)
  856. {
  857. strStream.width(8);
  858. strStream.fill('0');
  859. strStream.flags(ios_base::right);
  860. strStream << hex << l;
  861. }
  862. else
  863. {
  864. strStream << l;
  865. }
  866. strStream >> tsTemp;
  867. PutALine(ros, tsTemp.c_str() , -1);
  868. return ros;
  869. #endif
  870. }
  871. t_ostream &PutAULONG64Var(t_ostream &ros, ULONG64 ul64)
  872. {
  873. ULONG *lArray = (ULONG *) &ul64;
  874. PutAULONGVar( ros, lArray[0], true);
  875. PutAULONGVar( ros, lArray[1], true);
  876. return ros;
  877. }
  878. t_ostream &PutAULONGVar(t_ostream &ros, ULONG ul, bool bHex)
  879. {
  880. #ifndef _UNICODE
  881. if (bHex)
  882. {
  883. TCHAR f = ros.fill(_T('0'));
  884. int w = ros.width(8);
  885. int fl = ros.flags(ros.flags() | ios_base::right);
  886. ros << hex << ul;
  887. ros.fill(f);
  888. ros.width(w);
  889. ros.flags(fl);
  890. return ros << dec;
  891. }
  892. else
  893. {
  894. return ros << ul;
  895. }
  896. #else
  897. t_string tsTemp;
  898. t_strstream strStream;
  899. if (bHex)
  900. {
  901. strStream.width(8);
  902. strStream.fill('0');
  903. strStream.flags(ios_base::right);
  904. strStream << hex << ul;
  905. }
  906. else
  907. {
  908. strStream << ul;
  909. }
  910. strStream >> tsTemp;
  911. PutALine(ros, tsTemp.c_str() , -1);
  912. return ros;
  913. #endif
  914. }
  915. t_ostream &PutADWORDVar(t_ostream &ros, DWORD dw)
  916. {
  917. #ifndef _UNICODE
  918. TCHAR f = ros.fill(_T('0'));
  919. int w = ros.width(8);
  920. int fl = ros.flags(ros.flags() | ios_base::right);
  921. ros << hex << dw;
  922. ros.fill(f);
  923. ros.width(w);
  924. ros.flags(fl);
  925. return ros << dec;
  926. #else
  927. t_string tsTemp;
  928. t_strstream strStream;
  929. strStream.width(8);
  930. strStream.fill('0');
  931. strStream.flags(ios_base::right);
  932. strStream << hex << dw;
  933. strStream >> tsTemp;
  934. PutALine(ros, tsTemp.c_str() , -1);
  935. return ros;
  936. #endif
  937. }
  938. void InitializeGUIDVar(t_string &rtsValue , void *pVar)
  939. {
  940. GUID *pGUID = reinterpret_cast<GUID *> (pVar);
  941. if (rtsValue.length() > 0 && case_insensitive_compare(rtsValue,_T("@#$NA")) != 0)
  942. {
  943. wGUIDFromString(rtsValue.c_str(), pGUID);
  944. }
  945. else
  946. {
  947. RtlZeroMemory(pGUID, sizeof(GUID));
  948. }
  949. }
  950. // *** Following routine copied from WMI\MofCheck. to convert
  951. // a guid string to a GUID.
  952. // The routines below were blantenly stolen without remorse from the ole
  953. // sources in \nt\private\ole32\com\class\compapi.cxx. They are copied here
  954. // so that WMI doesn't need to load in ole32 only to convert a guid string
  955. // into its binary representation.
  956. //
  957. //+-------------------------------------------------------------------------
  958. //
  959. // Function: HexStringToDword (private)
  960. //
  961. // Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz
  962. // return value in Value; check for chDelim;
  963. //
  964. // Arguments: [lpsz] - the hex string to convert
  965. // [Value] - the returned value
  966. // [cDigits] - count of digits
  967. //
  968. // Returns: TRUE for success
  969. //
  970. //--------------------------------------------------------------------------
  971. BOOL HexStringToDword(LPCTSTR lpsz, DWORD * RetValue,
  972. int cDigits, WCHAR chDelim)
  973. {
  974. int Count;
  975. DWORD Value;
  976. Value = 0;
  977. for (Count = 0; Count < cDigits; Count++, lpsz++)
  978. {
  979. if (*lpsz >= '0' && *lpsz <= '9')
  980. Value = (Value << 4) + *lpsz - '0';
  981. else if (*lpsz >= 'A' && *lpsz <= 'F')
  982. Value = (Value << 4) + *lpsz - 'A' + 10;
  983. else if (*lpsz >= 'a' && *lpsz <= 'f')
  984. Value = (Value << 4) + *lpsz - 'a' + 10;
  985. else
  986. return(FALSE);
  987. }
  988. *RetValue = Value;
  989. if (chDelim != 0)
  990. return *lpsz++ == chDelim;
  991. else
  992. return TRUE;
  993. }
  994. //+-------------------------------------------------------------------------
  995. //
  996. // Function: wUUIDFromString (internal)
  997. //
  998. // Synopsis: Parse UUID such as 00000000-0000-0000-0000-000000000000
  999. //
  1000. // Arguments: [lpsz] - Supplies the UUID string to convert
  1001. // [pguid] - Returns the GUID.
  1002. //
  1003. // Returns: TRUE if successful
  1004. //
  1005. //--------------------------------------------------------------------------
  1006. BOOL wUUIDFromString(LPCTSTR lpsz, LPGUID pguid)
  1007. {
  1008. DWORD dw;
  1009. if (!HexStringToDword(lpsz, &pguid->Data1, sizeof(DWORD)*2, '-'))
  1010. return FALSE;
  1011. lpsz += sizeof(DWORD)*2 + 1;
  1012. if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
  1013. return FALSE;
  1014. lpsz += sizeof(WORD)*2 + 1;
  1015. pguid->Data2 = (WORD)dw;
  1016. if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
  1017. return FALSE;
  1018. lpsz += sizeof(WORD)*2 + 1;
  1019. pguid->Data3 = (WORD)dw;
  1020. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1021. return FALSE;
  1022. lpsz += sizeof(BYTE)*2;
  1023. pguid->Data4[0] = (BYTE)dw;
  1024. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, '-'))
  1025. return FALSE;
  1026. lpsz += sizeof(BYTE)*2+1;
  1027. pguid->Data4[1] = (BYTE)dw;
  1028. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1029. return FALSE;
  1030. lpsz += sizeof(BYTE)*2;
  1031. pguid->Data4[2] = (BYTE)dw;
  1032. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1033. return FALSE;
  1034. lpsz += sizeof(BYTE)*2;
  1035. pguid->Data4[3] = (BYTE)dw;
  1036. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1037. return FALSE;
  1038. lpsz += sizeof(BYTE)*2;
  1039. pguid->Data4[4] = (BYTE)dw;
  1040. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1041. return FALSE;
  1042. lpsz += sizeof(BYTE)*2;
  1043. pguid->Data4[5] = (BYTE)dw;
  1044. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1045. return FALSE;
  1046. lpsz += sizeof(BYTE)*2;
  1047. pguid->Data4[6] = (BYTE)dw;
  1048. if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
  1049. return FALSE;
  1050. lpsz += sizeof(BYTE)*2;
  1051. pguid->Data4[7] = (BYTE)dw;
  1052. return TRUE;
  1053. }
  1054. //+-------------------------------------------------------------------------
  1055. //
  1056. // Function: wGUIDFromString (internal)
  1057. //
  1058. // Synopsis: Parse GUID such as {00000000-0000-0000-0000-000000000000}
  1059. //
  1060. // Arguments: [lpsz] - the guid string to convert
  1061. // [pguid] - guid to return
  1062. //
  1063. // Returns: TRUE if successful
  1064. //
  1065. //--------------------------------------------------------------------------
  1066. BOOL wGUIDFromString(LPCTSTR lpsz, LPGUID pguid)
  1067. {
  1068. if (*lpsz == '{' )
  1069. lpsz++;
  1070. if(wUUIDFromString(lpsz, pguid) != TRUE)
  1071. return FALSE;
  1072. lpsz +=36;
  1073. if (*lpsz == '}' )
  1074. lpsz++;
  1075. if (*lpsz != '\0') // check for zero terminated string - test bug #18307
  1076. {
  1077. return FALSE;
  1078. }
  1079. return TRUE;
  1080. }
  1081. int case_insensitive_compare(t_string &r1, t_string &r2)
  1082. {
  1083. t_string tsTemp1;
  1084. t_string tsTemp2;
  1085. tsTemp1 = r1.c_str();
  1086. tsTemp2 = r2.c_str();
  1087. int i;
  1088. for (i = 0; i < tsTemp1.length(); i++)
  1089. {
  1090. tsTemp1.replace(i,1,1, toupper(tsTemp1[i]));
  1091. }
  1092. for (i = 0; i < tsTemp2.length(); i++)
  1093. {
  1094. tsTemp2.replace(i,1,1, toupper(tsTemp2[i]));
  1095. }
  1096. return tsTemp1.compare(tsTemp2);
  1097. }
  1098. int case_insensitive_compare(TCHAR *p, t_string &r2)
  1099. {
  1100. if (p == NULL)
  1101. {
  1102. return -1;
  1103. }
  1104. t_string tsTemp;
  1105. tsTemp = p;
  1106. return case_insensitive_compare(tsTemp, r2);
  1107. }
  1108. int case_insensitive_compare(t_string &r1,TCHAR *p )
  1109. {
  1110. if (p == NULL)
  1111. {
  1112. return 1;
  1113. }
  1114. t_string tsTemp;
  1115. tsTemp = p;
  1116. return case_insensitive_compare(r1, tsTemp);
  1117. }
  1118. int case_insensitive_compare(TCHAR *p1,TCHAR *p2)
  1119. {
  1120. if (!p1 && !p2)
  1121. {
  1122. return 0;
  1123. }
  1124. else if (!p1)
  1125. {
  1126. return -1;
  1127. } else if (!p2)
  1128. {
  1129. return 1;
  1130. }
  1131. int l1 = _tcslen(p1);
  1132. int l2 = _tcslen(p2);
  1133. int nCompare = _tcsnicmp(p1,p2,_MIN(l1,l2));
  1134. if (nCompare == 0)
  1135. {
  1136. if (l1 == l2)
  1137. {
  1138. return 0;
  1139. }
  1140. else if (l1 < l2)
  1141. {
  1142. return -1;
  1143. }
  1144. else
  1145. {
  1146. return 1;
  1147. }
  1148. }
  1149. else
  1150. {
  1151. return nCompare;
  1152. }
  1153. }