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.

757 lines
22 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1998 - 1999
  3. Module Name:
  4. tclTrace
  5. Abstract:
  6. This module implements the CSP Tracing interpretation
  7. Author:
  8. Doug Barlow (dbarlow) 5/27/1998
  9. Notes:
  10. ?Notes?
  11. --*/
  12. #ifndef WIN32_LEAN_AND_MEAN
  13. #define WIN32_LEAN_AND_MEAN
  14. #endif
  15. #include <windows.h>
  16. #ifndef _WIN32_WINNT
  17. #define _WIN32_WINNT 0x0400
  18. #endif
  19. #include <wincrypt.h>
  20. #include <stdlib.h>
  21. #include <iostream.h>
  22. #include <iomanip.h>
  23. #include <tchar.h>
  24. #include <stdio.h>
  25. #include <SCardLib.h>
  26. #include "cspTrace.h"
  27. static void
  28. ShowBuf(
  29. LogBuffer &lb,
  30. ostream &outStr);
  31. static LPCTSTR
  32. ShowString(
  33. LogBuffer &lb);
  34. static void
  35. dump(
  36. const BYTE *pbData,
  37. DWORD cbLen,
  38. ostream &outStr);
  39. LPCTSTR
  40. MapValue(
  41. DWORD dwValue,
  42. const ValueMap *rgMap);
  43. LPCTSTR
  44. MaskValue(
  45. DWORD dwValue,
  46. const ValueMap *rgMap);
  47. static LPBYTE l_pbLogData = NULL;
  48. static DWORD l_cbLogData = 0;
  49. /*++
  50. DoTclTrace:
  51. This routine interprets the given binary file, writing the output to stdout.
  52. Arguments:
  53. szInFile supplies the file name to be parsed.
  54. Return Value:
  55. None
  56. Remarks:
  57. ?Remarks?
  58. Author:
  59. Doug Barlow (dbarlow) 5/16/1998
  60. --*/
  61. void
  62. DoTclTrace(
  63. IN LPCTSTR szInFile)
  64. {
  65. HANDLE hLogFile = NULL;
  66. DWORD cbStructLen = 0;
  67. LPBYTE pbStruct = NULL;
  68. LogHeader *pLogObj;
  69. DWORD dwLen, dwRead;
  70. BOOL fSts;
  71. //
  72. // Open the log file.
  73. //
  74. hLogFile = CreateFile(
  75. szInFile,
  76. GENERIC_READ,
  77. FILE_SHARE_READ | FILE_SHARE_WRITE,
  78. NULL,
  79. OPEN_EXISTING,
  80. FILE_ATTRIBUTE_NORMAL,
  81. NULL);
  82. if (INVALID_HANDLE_VALUE == hLogFile)
  83. {
  84. cerr << TEXT("Can't open file ")
  85. << szInFile
  86. << ": "
  87. << CErrorString(GetLastError())
  88. << endl;
  89. goto ErrorExit;
  90. }
  91. //
  92. // Parse the file contents.
  93. //
  94. for (;;)
  95. {
  96. fSts = ReadFile(
  97. hLogFile,
  98. &dwLen,
  99. sizeof(DWORD),
  100. &dwRead,
  101. NULL);
  102. if ((!fSts) || (0 == dwRead))
  103. goto ErrorExit;
  104. if (cbStructLen < dwLen)
  105. {
  106. if (NULL != pbStruct)
  107. LocalFree(pbStruct);
  108. pbStruct = (LPBYTE)LocalAlloc(LPTR, dwLen);
  109. cbStructLen = dwLen;
  110. }
  111. fSts = ReadFile(
  112. hLogFile,
  113. &pbStruct[sizeof(DWORD)],
  114. dwLen - sizeof(DWORD),
  115. &dwRead,
  116. NULL);
  117. if (!fSts)
  118. {
  119. cerr << "File read error: " << CErrorString(GetLastError()) << endl;
  120. goto ErrorExit;
  121. }
  122. //
  123. // Parse the structure into bytesize chunks.
  124. //
  125. pLogObj = (LogHeader *)pbStruct;
  126. pLogObj->cbLength = dwLen;
  127. l_pbLogData = pbStruct + pLogObj->cbDataOffset;
  128. l_cbLogData = pLogObj->cbLength - pLogObj->cbDataOffset;
  129. //
  130. // We've got the structure, now display the contents.
  131. //
  132. switch (pLogObj->id)
  133. {
  134. case AcquireContext:
  135. {
  136. struct TmpLog {
  137. LogHeader lh;
  138. LogBuffer bfContainer;
  139. DWORD dwFlags;
  140. LogBuffer bfVTable;
  141. HCRYPTPROV hProv;
  142. } *pld = (struct TmpLog *)pLogObj;
  143. cout << TEXT("set hProv ^\n")
  144. << TEXT(" [crypt acquire ^\n")
  145. << TEXT(" provider $prov ^\n");
  146. if ((DWORD)(-1) != pld->bfContainer.cbOffset)
  147. cout << TEXT(" container {") << ShowString(pld->bfContainer) << TEXT("} ^\n");
  148. if (0 != pld->dwFlags)
  149. cout << TEXT(" flags {" << MaskValue(pld->dwFlags, rgMapAcquireFlags)) << TEXT("} ^\n");
  150. cout << TEXT(" ]\n") << endl;
  151. break;
  152. }
  153. case GetProvParam:
  154. {
  155. struct TmpLog {
  156. LogHeader lh;
  157. HCRYPTPROV hProv;
  158. DWORD dwParam;
  159. DWORD dwDataLen;
  160. DWORD dwFlags;
  161. LogBuffer bfData;
  162. } *pld = (struct TmpLog *)pLogObj;
  163. cout << TEXT("set param ^\n")
  164. << TEXT(" [crypt $hProv parameter ") << MapValue(pld->dwParam, rgMapGetProvParam) << TEXT(" ^\n");
  165. if (0 != pld->dwFlags)
  166. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, rgMapGetProvFlags) << TEXT("} ^\n");
  167. cout << TEXT(" ]\n") << endl;
  168. break;
  169. }
  170. case ReleaseContext:
  171. {
  172. struct TmpLog {
  173. LogHeader lh;
  174. HCRYPTPROV hProv;
  175. DWORD dwFlags;
  176. } *pld = (struct TmpLog *)pLogObj;
  177. cout << TEXT("crypt $hProv release ^\n");
  178. if (0 != pld->dwFlags)
  179. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("}]\n");
  180. cout << TEXT(" \n") << endl;
  181. break;
  182. }
  183. case SetProvParam:
  184. {
  185. struct TmpLog {
  186. LogHeader lh;
  187. HCRYPTPROV hProv;
  188. DWORD dwParam;
  189. LogBuffer bfData;
  190. DWORD dwFlags;
  191. } *pld = (struct TmpLog *)pLogObj;
  192. cout << TEXT("crypt $hProv parameter ") << MapValue(pld->dwParam, rgMapSetProvParam) << TEXT(" ^\n");
  193. if (0 != pld->dwFlags)
  194. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  195. ShowBuf(pld->bfData, cout);
  196. cout << TEXT(" \n") << endl;
  197. break;
  198. }
  199. case DeriveKey:
  200. {
  201. struct TmpLog {
  202. LogHeader lh;
  203. HCRYPTPROV hProv;
  204. ALG_ID Algid;
  205. HCRYPTHASH hHash;
  206. DWORD dwFlags;
  207. HCRYPTKEY hKey;
  208. } *pld = (struct TmpLog *)pLogObj;
  209. cout << TEXT("set hKey ^\n")
  210. << TEXT(" [crypt $hProv create key ^\n")
  211. << TEXT(" algorithm ") << MapValue(pld->Algid, rgMapAlgId) << TEXT(" ^\n")
  212. << TEXT(" hash $hHash ^\n");
  213. if (0 != pld->dwFlags)
  214. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, rgMapDeriveKeyFlags) << TEXT("} ^\n");
  215. cout << TEXT(" ]\n") << endl;
  216. break;
  217. }
  218. case DestroyKey:
  219. {
  220. struct TmpLog {
  221. LogHeader lh;
  222. HCRYPTPROV hProv;
  223. HCRYPTKEY hKey;
  224. } *pld = (struct TmpLog *)pLogObj;
  225. cout << TEXT("crypt $hKey release\n")
  226. << endl;
  227. break;
  228. }
  229. case ExportKey:
  230. {
  231. struct TmpLog {
  232. LogHeader lh;
  233. HCRYPTPROV hProv;
  234. HCRYPTKEY hKey;
  235. HCRYPTKEY hPubKey;
  236. DWORD dwBlobType;
  237. DWORD dwFlags;
  238. DWORD dwDataLen;
  239. LogBuffer bfData;
  240. } *pld = (struct TmpLog *)pLogObj;
  241. cout << TEXT("set expKey ^\n")
  242. << TEXT(" [crypt $hKey export ^\n")
  243. << TEXT(" key $hPubKey ^\n")
  244. << TEXT(" type ") << MapValue(pld->dwBlobType, rgMapBlobType) << TEXT(" ^\n");
  245. if (0 != pld->dwFlags)
  246. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, rgMapExportKeyFlags) << TEXT("} ^\n");
  247. cout << TEXT(" ]\n") << endl;
  248. break;
  249. }
  250. case GenKey:
  251. {
  252. struct TmpLog {
  253. LogHeader lh;
  254. HCRYPTPROV hProv;
  255. ALG_ID Algid;
  256. DWORD dwFlags;
  257. HCRYPTKEY hKey;
  258. } *pld = (struct TmpLog *)pLogObj;
  259. cout << TEXT("set hKey ^\n")
  260. << TEXT(" [crypt $hProv create key ^\n")
  261. << TEXT(" algorithm ") << MapValue(pld->Algid, rgMapAlgId) << TEXT(" ^\n");
  262. if (0 != pld->dwFlags)
  263. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, rgMapGenKeyFlags) << TEXT("} ^\n");
  264. cout << TEXT(" ]\n") << endl;
  265. break;
  266. }
  267. case GetKeyParam:
  268. {
  269. struct TmpLog {
  270. LogHeader lh;
  271. HCRYPTPROV hProv;
  272. HCRYPTKEY hKey;
  273. DWORD dwParam;
  274. DWORD dwDataLen;
  275. DWORD dwFlags;
  276. LogBuffer bfData;
  277. } *pld = (struct TmpLog *)pLogObj;
  278. cout << TEXT("set param ^\n")
  279. << TEXT(" [crypt $hKey parameter ") << MapValue(pld->dwParam, rgMapKeyParam) << TEXT(" ^\n");
  280. if (0 != pld->dwFlags)
  281. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  282. cout << TEXT(" ]\n") << endl;
  283. break;
  284. }
  285. case GenRandom:
  286. {
  287. struct TmpLog {
  288. LogHeader lh;
  289. HCRYPTPROV hProv;
  290. DWORD dwLen;
  291. LogBuffer bfBuffer;
  292. } *pld = (struct TmpLog *)pLogObj;
  293. cout << TEXT("set rnd ^\n")
  294. << TEXT(" [crypt $hProv get random ") << pld->dwLen << TEXT("]\n")
  295. << endl;
  296. break;
  297. }
  298. case GetUserKey:
  299. {
  300. struct TmpLog {
  301. LogHeader lh;
  302. HCRYPTPROV hProv;
  303. DWORD dwKeySpec;
  304. HCRYPTKEY hUserKey;
  305. } *pld = (struct TmpLog *)pLogObj;
  306. cout << TEXT("set hKey ^\n")
  307. << TEXT(" [crypt $hProv get key ") << MapValue(pld->dwKeySpec, rgMapKeyId) << TEXT("]\n")
  308. << endl;
  309. break;
  310. }
  311. case ImportKey:
  312. {
  313. struct TmpLog {
  314. LogHeader lh;
  315. HCRYPTPROV hProv;
  316. LogBuffer bfData;
  317. HCRYPTKEY hPubKey;
  318. DWORD dwFlags;
  319. HCRYPTKEY hKey;
  320. } *pld = (struct TmpLog *)pLogObj;
  321. cout << TEXT("set hKey ^\n")
  322. << TEXT(" [crypt $hProv import ^\n");
  323. if (0 != pld->hPubKey)
  324. cout << TEXT(" key $hPubKey ^\n");
  325. if (0 != pld->dwFlags)
  326. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  327. ShowBuf(pld->bfData, cout);
  328. cout << TEXT(" ]\n") << endl;
  329. break;
  330. }
  331. case SetKeyParam:
  332. {
  333. struct TmpLog {
  334. LogHeader lh;
  335. HCRYPTPROV hProv;
  336. HCRYPTKEY hKey;
  337. DWORD dwParam;
  338. LogBuffer bfData;
  339. DWORD dwFlags;
  340. } *pld = (struct TmpLog *)pLogObj;
  341. cout << TEXT("crypt $hKey parameter ") << MapValue(pld->dwParam, rgMapKeyParam) << TEXT(" ^\n");
  342. if (0 != pld->dwFlags)
  343. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  344. ShowBuf(pld->bfData, cout);
  345. cout << TEXT(" ]\n") << endl;
  346. break;
  347. }
  348. case Encrypt:
  349. {
  350. struct TmpLog {
  351. LogHeader lh;
  352. HCRYPTPROV hProv;
  353. HCRYPTKEY hKey;
  354. HCRYPTHASH hHash;
  355. BOOL Final;
  356. DWORD dwFlags;
  357. LogBuffer bfInData;
  358. DWORD dwBufLen;
  359. LogBuffer bfOutData;
  360. } *pld = (struct TmpLog *)pLogObj;
  361. cout << TEXT("set ciphertext ^\n")
  362. << TEXT(" [crypt $hKey encrypt ^\n");
  363. if (NULL != pld->hHash)
  364. cout << TEXT(" hash $hHash ^\n");
  365. if (0 != pld->dwFlags)
  366. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  367. if (pld->Final)
  368. cout << TEXT(" final ^\n");
  369. else
  370. cout << TEXT(" more ^\n");
  371. ShowBuf(pld->bfInData, cout);
  372. cout << TEXT(" ]\n") << endl;
  373. break;
  374. }
  375. case Decrypt:
  376. {
  377. struct TmpLog {
  378. LogHeader lh;
  379. HCRYPTPROV hProv;
  380. HCRYPTKEY hKey;
  381. HCRYPTHASH hHash;
  382. BOOL Final;
  383. DWORD dwFlags;
  384. LogBuffer bfInData;
  385. LogBuffer bfOutData;
  386. } *pld = (struct TmpLog *)pLogObj;
  387. cout << TEXT("set cleartext ^\n")
  388. << TEXT(" [crypt $hKey decrypt ^\n");
  389. if (NULL != pld->hHash)
  390. cout << TEXT(" hash $hHash ^\n");
  391. if (0 != pld->dwFlags)
  392. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  393. if (pld->Final)
  394. cout << TEXT(" final ^\n");
  395. else
  396. cout << TEXT(" more ^\n");
  397. ShowBuf(pld->bfInData, cout);
  398. cout << TEXT(" ]\n") << endl;
  399. break;
  400. }
  401. case CreateHash:
  402. {
  403. struct TmpLog {
  404. LogHeader lh;
  405. HCRYPTPROV hProv;
  406. ALG_ID Algid;
  407. HCRYPTKEY hKey;
  408. DWORD dwFlags;
  409. HCRYPTHASH hHash;
  410. } *pld = (struct TmpLog *)pLogObj;
  411. cout << TEXT("set hHash ^\n")
  412. << TEXT(" [crypt $hProv create hash ^\n")
  413. << TEXT(" algorithm ") << MapValue(pld->Algid, rgMapAlgId) << TEXT(" ^\n");
  414. if (0 != pld->dwFlags)
  415. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  416. cout << TEXT(" ]\n") << endl;
  417. break;
  418. }
  419. case DestroyHash:
  420. {
  421. struct TmpLog {
  422. LogHeader lh;
  423. HCRYPTPROV hProv;
  424. HCRYPTHASH hHash;
  425. } *pld = (struct TmpLog *)pLogObj;
  426. cout << TEXT("crypt $hHash release\n") << endl;
  427. break;
  428. }
  429. case GetHashParam:
  430. {
  431. struct TmpLog {
  432. LogHeader lh;
  433. HCRYPTPROV hProv;
  434. HCRYPTHASH hHash;
  435. DWORD dwParam;
  436. DWORD dwDataLen;
  437. DWORD dwFlags;
  438. LogBuffer bfData;
  439. } *pld = (struct TmpLog *)pLogObj;
  440. cout << TEXT("set param ^\n")
  441. << TEXT(" [crypt $hKey parameter ") << MapValue(pld->dwParam, rgMapHashParam) << TEXT(" ^\n");
  442. if (0 != pld->dwFlags)
  443. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  444. cout << TEXT(" ]\n") << endl;
  445. break;
  446. }
  447. case HashData:
  448. {
  449. struct TmpLog {
  450. LogHeader lh;
  451. HCRYPTPROV hProv;
  452. HCRYPTHASH hHash;
  453. LogBuffer bfData;
  454. DWORD dwFlags;
  455. } *pld = (struct TmpLog *)pLogObj;
  456. cout << TEXT("crypt $hHash hash ^\n");
  457. if (0 != pld->dwFlags)
  458. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  459. ShowBuf(pld->bfData, cout);
  460. cout << endl;
  461. break;
  462. }
  463. case HashSessionKey:
  464. {
  465. struct TmpLog {
  466. LogHeader lh;
  467. HCRYPTPROV hProv;
  468. HCRYPTHASH hHash;
  469. HCRYPTKEY hKey;
  470. DWORD dwFlags;
  471. } *pld = (struct TmpLog *)pLogObj;
  472. cout << TEXT("crypt $hHash hash ^\n")
  473. << TEXT(" key $hKey ^\n");
  474. if (0 != pld->dwFlags)
  475. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  476. cout << TEXT(" ]\n") << endl;
  477. break;
  478. }
  479. case SetHashParam:
  480. {
  481. struct TmpLog {
  482. LogHeader lh;
  483. HCRYPTPROV hProv;
  484. HCRYPTHASH hHash;
  485. DWORD dwParam;
  486. LogBuffer bfData;
  487. DWORD dwFlags;
  488. } *pld = (struct TmpLog *)pLogObj;
  489. cout << TEXT("crypt $hHash parameter ") << MapValue(pld->dwParam, rgMapHashParam) << TEXT(" ^\n");
  490. if (0 != pld->dwFlags)
  491. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("} ^\n");
  492. ShowBuf(pld->bfData, cout);
  493. cout << TEXT(" ]\n") << endl;
  494. break;
  495. }
  496. case SignHash:
  497. {
  498. struct TmpLog {
  499. LogHeader lh;
  500. HCRYPTPROV hProv;
  501. HCRYPTHASH hHash;
  502. DWORD dwKeySpec;
  503. LogBuffer bfDescription;
  504. DWORD dwFlags;
  505. DWORD dwSigLen;
  506. LogBuffer bfSignature;
  507. } *pld = (struct TmpLog *)pLogObj;
  508. cout << TEXT("set sig ^\n")
  509. << TEXT(" [crypt $hHash sign ^\n")
  510. << TEXT(" key ") << MapValue(pld->dwKeySpec, rgMapKeyId) << TEXT(" ^\n");
  511. if ((DWORD)(-1) != pld->bfDescription.cbOffset)
  512. cout << TEXT(" description {") << ShowString(pld->bfDescription) << TEXT("} ^\n");
  513. if (0 != pld->dwFlags)
  514. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("}]\n");
  515. cout << TEXT(" ]\n") << endl;
  516. break;
  517. }
  518. case VerifySignature:
  519. {
  520. struct TmpLog {
  521. LogHeader lh;
  522. HCRYPTPROV hProv;
  523. HCRYPTHASH hHash;
  524. LogBuffer bfSignature;
  525. DWORD dwSigLen;
  526. HCRYPTKEY hPubKey;
  527. LogBuffer bfDescription;
  528. DWORD dwFlags;
  529. } *pld = (struct TmpLog *)pLogObj;
  530. cout << TEXT("crypt $hHash verify ^\n")
  531. << TEXT(" key $hKey ^\n");
  532. if ((DWORD)(-1) != pld->bfDescription.cbOffset)
  533. cout << TEXT(" description {") << ShowString(pld->bfDescription) << TEXT("} ^\n");
  534. if (0 != pld->dwFlags)
  535. cout << TEXT(" flags {") << MaskValue(pld->dwFlags, NULL) << TEXT("}\n");
  536. ShowBuf(pld->bfSignature, cout);
  537. cout << TEXT(" ]\n") << endl;
  538. break;
  539. }
  540. default:
  541. cerr << TEXT("Internal error") << endl;
  542. goto ErrorExit;
  543. break;
  544. }
  545. }
  546. ErrorExit:
  547. if (NULL == hLogFile)
  548. CloseHandle(hLogFile);
  549. }
  550. //
  551. ///////////////////////////////////////////////////////////////////////////////
  552. //
  553. // Suport routines
  554. //
  555. static void
  556. dump(
  557. const BYTE *pbData,
  558. DWORD cbLen,
  559. ostream &outStr)
  560. {
  561. unsigned long int
  562. b, i, lc;
  563. char
  564. buffer[32];
  565. lc = 0;
  566. while (0 < cbLen)
  567. {
  568. b = min(sizeof(buffer), cbLen);
  569. memcpy(buffer, pbData, b);
  570. pbData += b;
  571. cbLen -= b;
  572. if (0 < b)
  573. {
  574. outStr << TEXT(" ");
  575. for (i = 0; i < b; i += 1)
  576. outStr
  577. << setw(2) << setfill('0') << hex
  578. << ((unsigned int)buffer[i] & 0xff);
  579. outStr << endl;
  580. lc += b;
  581. }
  582. }
  583. }
  584. static LPCTSTR
  585. MapValue(
  586. DWORD dwValue,
  587. const ValueMap *rgMap)
  588. {
  589. static TCHAR szReturn[128];
  590. DWORD dwIndex;
  591. if (NULL != rgMap)
  592. {
  593. for (dwIndex = 0; NULL != rgMap[dwIndex].szValue; dwIndex += 1)
  594. if (rgMap[dwIndex].dwValue == dwValue)
  595. break;
  596. if (NULL != rgMap[dwIndex].szValue)
  597. lstrcpy(szReturn, rgMap[dwIndex].szValue);
  598. else
  599. _stprintf(szReturn, TEXT("0x%08x"), dwValue);
  600. }
  601. else
  602. _stprintf(szReturn, TEXT("0x%08x"), dwValue);
  603. return szReturn;
  604. }
  605. static LPCTSTR
  606. MaskValue(
  607. DWORD dwValue,
  608. const ValueMap *rgMap)
  609. {
  610. static TCHAR szReturn[1024];
  611. TCHAR szNumeric[16];
  612. DWORD dwIndex;
  613. BOOL fSpace = FALSE;
  614. szReturn[0] = 0;
  615. if (NULL != rgMap)
  616. {
  617. for (dwIndex = 0; NULL != rgMap[dwIndex].szValue; dwIndex += 1)
  618. {
  619. if (rgMap[dwIndex].dwValue == (rgMap[dwIndex].dwValue & dwValue))
  620. {
  621. if (fSpace)
  622. lstrcat(szReturn, TEXT(" "));
  623. else
  624. fSpace = TRUE;
  625. lstrcat(szReturn, rgMap[dwIndex].szValue);
  626. dwValue &= ~rgMap[dwIndex].dwValue;
  627. }
  628. }
  629. if (0 != dwValue)
  630. {
  631. if (fSpace)
  632. {
  633. lstrcat(szReturn, TEXT(" "));
  634. fSpace = TRUE;
  635. }
  636. _stprintf(szNumeric, TEXT("0x%08x"), dwValue);
  637. lstrcat(szReturn, szNumeric);
  638. }
  639. else if (!fSpace)
  640. _stprintf(szReturn, TEXT("0x%08x"), dwValue);
  641. }
  642. else
  643. _stprintf(szReturn, TEXT("0x%08x"), dwValue);
  644. return szReturn;
  645. }
  646. static void
  647. ShowBuf(
  648. LogBuffer &lb,
  649. ostream &outStr)
  650. {
  651. if ((DWORD)(-1) == lb.cbOffset)
  652. outStr << TEXT(" ") << TEXT("<NULL>") << endl;
  653. else if (0 == lb.cbLength)
  654. outStr << TEXT(" {}") << endl;
  655. else if (l_cbLogData < lb.cbOffset + lb.cbLength)
  656. outStr << TEXT(" ") << TEXT("<BufferOverrun>") << endl;
  657. else
  658. dump(&l_pbLogData[lb.cbOffset], lb.cbLength, outStr);
  659. }
  660. static LPCTSTR
  661. ShowString(
  662. LogBuffer &lb)
  663. {
  664. LPCTSTR szReturn;
  665. if ((DWORD)(-1) == lb.cbOffset)
  666. szReturn = TEXT("<NULL>");
  667. else if (0 == lb.cbLength)
  668. szReturn = TEXT("{}");
  669. else if (l_cbLogData < lb.cbOffset + lb.cbLength)
  670. szReturn = TEXT("<bufferOverrun>");
  671. else if (TEXT('\000') != (LPCTSTR)(l_pbLogData[lb.cbOffset + lb.cbLength - sizeof(TCHAR)]))
  672. szReturn = TEXT("<UnterminatedString>");
  673. else
  674. szReturn = (LPCTSTR)&l_pbLogData[lb.cbOffset];
  675. return szReturn;
  676. }