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.

1326 lines
27 KiB

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