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.

1928 lines
63 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. scTrace
  5. Abstract:
  6. This program performs analysis on a Calais I/O trace.
  7. Author:
  8. Doug Barlow (dbarlow) 10/30/1997
  9. Environment:
  10. Win32
  11. Notes:
  12. ?Notes?
  13. --*/
  14. #ifndef WIN32_LEAN_AND_MEAN
  15. #define WIN32_LEAN_AND_MEAN
  16. #endif
  17. #include <windows.h>
  18. #include <stdlib.h>
  19. #include <iostream.h>
  20. #include <iomanip.h>
  21. #include <calcom.h>
  22. //
  23. // This structure must match the one used by SCardSvr.
  24. //
  25. typedef struct {
  26. DWORD dwStructLen; // Actual structure length
  27. SYSTEMTIME StartTime; // Time request was posted
  28. SYSTEMTIME EndTime; // Time request completed
  29. DWORD dwProcId; // Process Id
  30. DWORD dwThreadId; // Thread Id
  31. HANDLE hDevice; // I/O handle
  32. DWORD dwIoControlCode; // I/O control code issued
  33. DWORD nInBuffer; // Offset to input buffer
  34. DWORD nInBufferSize; // Input buffer size
  35. DWORD nOutBuffer; // Offset to output buffer
  36. DWORD nOutBufferSize; // Size of user's receive buffer
  37. DWORD nBytesReturned; // Actual size of returned data
  38. DWORD dwStatus; // Returned status code
  39. // InBuffer and OutBuffer follow.
  40. } RequestTrace;
  41. typedef struct {
  42. DWORD dwValue;
  43. LPCTSTR szValue;
  44. } ValueMap;
  45. typedef struct
  46. {
  47. SYSTEMTIME stLogTime;
  48. DWORD dwProcId;
  49. DWORD dwThreadId;
  50. } LogStamp;
  51. HANDLE g_hCalaisShutdown = NULL;
  52. static void
  53. ShowDriverLog(
  54. IN LPCTSTR szFile);
  55. static void
  56. ShowApiLog(
  57. IN LPCTSTR szFile);
  58. static void
  59. dump(
  60. const BYTE *pbData,
  61. DWORD cbLen,
  62. ostream &outStr);
  63. static void
  64. GeneralDump(
  65. ostream &outStr,
  66. const RequestTrace *prqTrace);
  67. static void
  68. SendDump(
  69. ostream &outStr,
  70. const RequestTrace *prqTrace);
  71. static void
  72. RecvDump(
  73. ostream &outStr,
  74. const RequestTrace *prqTrace);
  75. static void
  76. MapValue(
  77. ostream &outStr,
  78. DWORD dwValue,
  79. LPCTSTR szLeader,
  80. const ValueMap *rgMap);
  81. static void
  82. MaskValue(
  83. ostream &outStr,
  84. DWORD dwValue,
  85. LPCTSTR szLeader,
  86. const ValueMap *rgMap);
  87. static void
  88. MapInput(
  89. ostream &outStr,
  90. const RequestTrace *prqTrace,
  91. const ValueMap *rgMap);
  92. static void
  93. MapOutput(
  94. ostream &outStr,
  95. const RequestTrace *prqTrace,
  96. const ValueMap *rgMap);
  97. static void
  98. ShowSyntax(
  99. ostream &outStr);
  100. CComObject *
  101. ReceiveComObject(
  102. HANDLE hFile);
  103. #define PHex(x) TEXT("0x") << hex << setw(8) << setfill(TEXT('0')) << (DWORD)(x)
  104. #define PDec(x) dec << setw(0) << setfill(TEXT(' ')) << (x)
  105. #define MAP(x) { x, TEXT(#x) }
  106. #define PTime(x) dec \
  107. << setw(2) << setfill(TEXT('0')) << (x).wHour << TEXT(":") \
  108. << setw(2) << setfill(TEXT('0')) << (x).wMinute << TEXT(":") \
  109. << setw(2) << setfill(TEXT('0')) << (x).wSecond << TEXT(".") \
  110. << setw(3) << setfill(TEXT('0')) << (x).wMilliseconds
  111. static const ValueMap rgMapProto[]
  112. = { MAP(SCARD_PROTOCOL_UNDEFINED), MAP(SCARD_PROTOCOL_T0),
  113. MAP(SCARD_PROTOCOL_T1), MAP(SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1),
  114. MAP(SCARD_PROTOCOL_RAW), MAP(SCARD_PROTOCOL_DEFAULT),
  115. { 0, NULL } };
  116. static const ValueMap rgMapIoctl[]
  117. = { MAP(IOCTL_SMARTCARD_POWER), MAP(IOCTL_SMARTCARD_GET_ATTRIBUTE),
  118. MAP(IOCTL_SMARTCARD_SET_ATTRIBUTE), MAP(IOCTL_SMARTCARD_CONFISCATE),
  119. MAP(IOCTL_SMARTCARD_TRANSMIT), MAP(IOCTL_SMARTCARD_EJECT),
  120. MAP(IOCTL_SMARTCARD_SWALLOW), MAP(IOCTL_SMARTCARD_IS_PRESENT),
  121. MAP(IOCTL_SMARTCARD_IS_ABSENT), MAP(IOCTL_SMARTCARD_SET_PROTOCOL),
  122. MAP(IOCTL_SMARTCARD_GET_STATE), MAP(IOCTL_SMARTCARD_GET_LAST_ERROR),
  123. { 0, NULL } };
  124. static const ValueMap rgMapAttr[]
  125. = { MAP(SCARD_ATTR_VENDOR_NAME), MAP(SCARD_ATTR_VENDOR_IFD_TYPE),
  126. MAP(SCARD_ATTR_VENDOR_IFD_VERSION), MAP(SCARD_ATTR_VENDOR_IFD_SERIAL_NO),
  127. MAP(SCARD_ATTR_CHANNEL_ID), MAP(SCARD_ATTR_DEFAULT_CLK),
  128. MAP(SCARD_ATTR_MAX_CLK), MAP(SCARD_ATTR_DEFAULT_DATA_RATE),
  129. MAP(SCARD_ATTR_MAX_DATA_RATE), MAP(SCARD_ATTR_MAX_IFSD),
  130. MAP(SCARD_ATTR_POWER_MGMT_SUPPORT), MAP(SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE),
  131. MAP(SCARD_ATTR_USER_AUTH_INPUT_DEVICE), MAP(SCARD_ATTR_CHARACTERISTICS),
  132. MAP(SCARD_ATTR_CURRENT_PROTOCOL_TYPE), MAP(SCARD_ATTR_CURRENT_CLK),
  133. MAP(SCARD_ATTR_CURRENT_F), MAP(SCARD_ATTR_CURRENT_D),
  134. MAP(SCARD_ATTR_CURRENT_N), MAP(SCARD_ATTR_CURRENT_W),
  135. MAP(SCARD_ATTR_CURRENT_IFSC), MAP(SCARD_ATTR_CURRENT_IFSD),
  136. MAP(SCARD_ATTR_CURRENT_BWT), MAP(SCARD_ATTR_CURRENT_CWT),
  137. MAP(SCARD_ATTR_CURRENT_EBC_ENCODING), MAP(SCARD_ATTR_EXTENDED_BWT),
  138. MAP(SCARD_ATTR_ICC_PRESENCE), MAP(SCARD_ATTR_ICC_INTERFACE_STATUS),
  139. MAP(SCARD_ATTR_CURRENT_IO_STATE), MAP(SCARD_ATTR_ATR_STRING),
  140. MAP(SCARD_ATTR_ICC_TYPE_PER_ATR), MAP(SCARD_ATTR_ESC_RESET),
  141. MAP(SCARD_ATTR_ESC_CANCEL), MAP(SCARD_ATTR_ESC_AUTHREQUEST),
  142. MAP(SCARD_ATTR_MAXINPUT), MAP(SCARD_ATTR_DEVICE_UNIT),
  143. MAP(SCARD_ATTR_DEVICE_IN_USE), MAP(SCARD_ATTR_DEVICE_FRIENDLY_NAME_A),
  144. MAP(SCARD_ATTR_DEVICE_SYSTEM_NAME_A), MAP(SCARD_ATTR_DEVICE_FRIENDLY_NAME_W),
  145. MAP(SCARD_ATTR_DEVICE_SYSTEM_NAME_W), MAP(SCARD_ATTR_SUPRESS_T1_IFS_REQUEST),
  146. { 0, NULL } };
  147. static DWORD
  148. l_dwPid = 0,
  149. l_dwTid = 0;
  150. /*++
  151. main:
  152. This is the main entry point for the program.
  153. Arguments:
  154. dwArgCount supplies the number of arguments.
  155. szrgArgs supplies the argument strings.
  156. Return Value:
  157. None
  158. Author:
  159. Doug Barlow (dbarlow) 10/30/1997
  160. --*/
  161. void _cdecl
  162. main(
  163. IN DWORD dwArgCount,
  164. IN LPCTSTR szrgArgs[])
  165. {
  166. LPCTSTR szInFile = NULL;
  167. LPTSTR szEnd;
  168. DWORD dwArgIndex = 0;
  169. enum TraceAction {
  170. Undefined = 0,
  171. ClearLog,
  172. ShowApiTrace,
  173. ShowDriverTrace
  174. } nTraceAction = Undefined;
  175. //
  176. // Check for command line options
  177. //
  178. while (NULL != szrgArgs[++dwArgIndex])
  179. {
  180. switch (SelectString(szrgArgs[dwArgIndex],
  181. TEXT("CLEAR"), TEXT("RESET"),
  182. TEXT("DRIVER"), TEXT("API"),
  183. TEXT("-FILE"), TEXT("-PID"), TEXT("-TID"),
  184. NULL))
  185. {
  186. case 1: // clear
  187. case 2: // reset
  188. if (Undefined != nTraceAction)
  189. ShowSyntax(cerr);
  190. nTraceAction = ClearLog;
  191. break;
  192. case 3: // driver
  193. if (Undefined != nTraceAction)
  194. ShowSyntax(cerr);
  195. nTraceAction = ShowDriverTrace;
  196. break;
  197. case 4: // api
  198. if (Undefined != nTraceAction)
  199. ShowSyntax(cerr);
  200. nTraceAction = ShowApiTrace;
  201. break;
  202. case 5: // -file
  203. if (NULL != szInFile)
  204. ShowSyntax(cerr);
  205. szInFile = szrgArgs[++dwArgIndex];
  206. if (NULL == szInFile)
  207. ShowSyntax(cerr);
  208. break;
  209. case 6: // -pid <n>
  210. if (0 != l_dwPid)
  211. ShowSyntax(cerr);
  212. dwArgIndex += 1;
  213. l_dwPid = strtoul(szrgArgs[dwArgIndex], &szEnd, 0);
  214. if ((0 == l_dwPid) || (0 != *szEnd))
  215. ShowSyntax(cerr);
  216. break;
  217. case 7: // -tid <n>
  218. if (0 != l_dwTid)
  219. ShowSyntax(cerr);
  220. dwArgIndex += 1;
  221. l_dwTid = strtoul(szrgArgs[dwArgIndex], &szEnd, 0);
  222. if ((0 == l_dwTid) || (0 != *szEnd))
  223. ShowSyntax(cerr);
  224. break;
  225. default:
  226. ShowSyntax(cerr);
  227. }
  228. }
  229. //
  230. // Perform the request.
  231. //
  232. switch (nTraceAction)
  233. {
  234. case ClearLog:
  235. {
  236. HANDLE hLogFile;
  237. if (NULL == szInFile)
  238. {
  239. hLogFile = CreateFile(
  240. TEXT("C:\\Calais.log"),
  241. GENERIC_WRITE,
  242. 0,
  243. NULL,
  244. TRUNCATE_EXISTING,
  245. FILE_ATTRIBUTE_NORMAL,
  246. NULL);
  247. if (INVALID_HANDLE_VALUE != hLogFile)
  248. CloseHandle(hLogFile);
  249. hLogFile = CreateFile(
  250. TEXT("C:\\SCard.log"),
  251. GENERIC_WRITE,
  252. 0,
  253. NULL,
  254. TRUNCATE_EXISTING,
  255. FILE_ATTRIBUTE_NORMAL,
  256. NULL);
  257. if (INVALID_HANDLE_VALUE != hLogFile)
  258. CloseHandle(hLogFile);
  259. }
  260. else
  261. {
  262. hLogFile = CreateFile(
  263. szInFile,
  264. GENERIC_WRITE,
  265. 0,
  266. NULL,
  267. CREATE_ALWAYS,
  268. FILE_ATTRIBUTE_NORMAL,
  269. NULL);
  270. if (INVALID_HANDLE_VALUE == hLogFile)
  271. {
  272. DWORD dwError = GetLastError();
  273. cerr << TEXT("Failed to initialize file ")
  274. << szInFile << TEXT(": ")
  275. << CErrorString(dwError) << endl;
  276. }
  277. else
  278. CloseHandle(hLogFile);
  279. }
  280. break;
  281. }
  282. case Undefined:
  283. case ShowApiTrace:
  284. ShowApiLog(szInFile);
  285. break;
  286. case ShowDriverTrace:
  287. ShowDriverLog(szInFile);
  288. break;
  289. default:
  290. cerr << TEXT("Internal error") << endl;
  291. }
  292. exit(0);
  293. }
  294. /*++
  295. ShowDriverLog:
  296. Explain the contents of the driver log.
  297. Arguments:
  298. szFile supplies the name of the file to parse. If this is NULL, the file
  299. C:\Calais.log is used.
  300. Return Value:
  301. None
  302. Throws:
  303. None
  304. Author:
  305. Doug Barlow (dbarlow) 8/5/1998
  306. --*/
  307. static void
  308. ShowDriverLog(
  309. IN LPCTSTR szFile)
  310. {
  311. static const ValueMap rgMapPower[]
  312. = { MAP(SCARD_POWER_DOWN),
  313. MAP(SCARD_COLD_RESET),
  314. MAP(SCARD_WARM_RESET),
  315. { 0, NULL } };
  316. HANDLE hLogFile = NULL;
  317. DWORD cbStructLen = 0;
  318. LPBYTE pbStruct = NULL;
  319. LPCTSTR szInFile = TEXT("C:\\Calais.log");
  320. DWORD dwLen, dwRead;
  321. BOOL fSts;
  322. RequestTrace *prqTrace;
  323. LPBYTE pbInBuffer, pbOutBuffer;
  324. LPDWORD pdwInValue, pdwOutValue;
  325. //
  326. // Open the log file.
  327. //
  328. if (NULL != szFile)
  329. szInFile = szFile;
  330. hLogFile = CreateFile(
  331. szInFile,
  332. GENERIC_READ,
  333. FILE_SHARE_READ | FILE_SHARE_WRITE,
  334. NULL,
  335. OPEN_EXISTING,
  336. FILE_ATTRIBUTE_NORMAL,
  337. NULL);
  338. if (INVALID_HANDLE_VALUE == hLogFile)
  339. {
  340. cerr << TEXT("Can't open file ")
  341. << szInFile
  342. << ": "
  343. << ErrorString(GetLastError())
  344. << endl;
  345. goto ErrorExit;
  346. }
  347. //
  348. // Parse the file contents.
  349. //
  350. for (;;)
  351. {
  352. fSts = ReadFile(
  353. hLogFile,
  354. &dwLen,
  355. sizeof(DWORD),
  356. &dwRead,
  357. NULL);
  358. if ((!fSts) || (0 == dwRead))
  359. goto ErrorExit;
  360. if (cbStructLen < dwLen)
  361. {
  362. if (NULL != pbStruct)
  363. LocalFree(pbStruct);
  364. pbStruct = (LPBYTE)LocalAlloc(LPTR, dwLen);
  365. cbStructLen = dwLen;
  366. }
  367. prqTrace = (RequestTrace *)pbStruct;
  368. prqTrace->dwStructLen = dwLen;
  369. fSts = ReadFile(
  370. hLogFile,
  371. &pbStruct[sizeof(DWORD)],
  372. dwLen - sizeof(DWORD),
  373. &dwRead,
  374. NULL);
  375. if (!fSts)
  376. {
  377. cerr << "File read error: " << ErrorString(GetLastError()) << endl;
  378. goto ErrorExit;
  379. }
  380. if ((l_dwPid != 0) && (l_dwPid != prqTrace->dwProcId))
  381. continue;
  382. if ((l_dwTid != 0) && (l_dwTid != prqTrace->dwThreadId))
  383. continue;
  384. //
  385. // Parse the structure into bytesize chunks.
  386. //
  387. pbInBuffer = 0 != prqTrace->nInBufferSize
  388. ? (LPBYTE)prqTrace + prqTrace->nInBuffer
  389. : NULL;
  390. pbOutBuffer = 0 != prqTrace->nBytesReturned
  391. ? (LPBYTE)prqTrace + prqTrace->nOutBuffer
  392. : NULL;
  393. pdwInValue = sizeof(DWORD) <= prqTrace->nInBufferSize
  394. ? (LPDWORD)pbInBuffer
  395. : NULL;
  396. pdwOutValue = sizeof(DWORD) <= prqTrace->nBytesReturned
  397. ? (LPDWORD)pbOutBuffer
  398. : NULL;
  399. //
  400. // We've got the structure, now display the contents.
  401. //
  402. cout
  403. << TEXT("-----------------------------------------------------\n")
  404. << TEXT("P/T: ") << PHex(prqTrace->dwProcId) << TEXT("/") << PHex(prqTrace->dwThreadId) << TCHAR('\n')
  405. << TEXT("Time: ") << PTime(prqTrace->StartTime) << TEXT(" - ") << PTime(prqTrace->EndTime) << TCHAR('\n')
  406. << TEXT("Device: ") << PHex((ULONG)prqTrace->hDevice) << TCHAR('\n')
  407. << TEXT("Status: ") << ErrorString(prqTrace->dwStatus) << TCHAR('\n')
  408. << TEXT("RecLen: ") << PDec(prqTrace->nOutBufferSize) << TCHAR('\n')
  409. << flush;
  410. MapValue(cout, prqTrace->dwIoControlCode, TEXT("IOCTL: "), rgMapIoctl);
  411. cout << flush;
  412. switch (prqTrace->dwIoControlCode)
  413. {
  414. case IOCTL_SMARTCARD_POWER:
  415. MapInput(cout, prqTrace, rgMapPower);
  416. cout << flush;
  417. MapOutput(cout, prqTrace, NULL);
  418. break;
  419. case IOCTL_SMARTCARD_GET_ATTRIBUTE:
  420. MapInput(cout, prqTrace, rgMapAttr);
  421. cout << flush;
  422. MapOutput(cout, prqTrace, NULL);
  423. break;
  424. case IOCTL_SMARTCARD_SET_ATTRIBUTE:
  425. {
  426. GeneralDump(cout, prqTrace);
  427. break;
  428. }
  429. case IOCTL_SMARTCARD_CONFISCATE:
  430. GeneralDump(cout, prqTrace);
  431. break;
  432. case IOCTL_SMARTCARD_TRANSMIT:
  433. {
  434. LPCSCARD_IO_REQUEST pIo;
  435. LPCBYTE pbPci, pbSdu;
  436. DWORD cbPci, cbSdu;
  437. if (sizeof(SCARD_IO_REQUEST) <= prqTrace->nInBufferSize)
  438. {
  439. pIo = (LPCSCARD_IO_REQUEST)pbInBuffer;
  440. pbPci = pbInBuffer + sizeof(LPCSCARD_IO_REQUEST);
  441. cbPci = min(pIo->cbPciLength, prqTrace->nInBufferSize);
  442. pbSdu = pbInBuffer + pIo->cbPciLength;
  443. cbSdu = prqTrace->nInBufferSize - cbPci;
  444. cbPci -= sizeof(SCARD_IO_REQUEST);
  445. MapValue(cout, pIo->dwProtocol, TEXT("Proto: "), rgMapProto);
  446. if (0 < cbPci)
  447. {
  448. cout
  449. << TEXT("In PCI: (") << PDec(cbPci) << TEXT(" bytes)\n")
  450. << flush;
  451. dump(pbPci, cbPci, cout);
  452. }
  453. cout
  454. << TEXT("Sent: (") << PDec(cbSdu) << TEXT(" bytes)\n")
  455. << flush;
  456. dump(pbSdu, cbSdu, cout);
  457. }
  458. else
  459. SendDump(cout, prqTrace);
  460. if (sizeof(SCARD_IO_REQUEST) <= prqTrace->nBytesReturned)
  461. {
  462. pIo = (LPCSCARD_IO_REQUEST)pbOutBuffer;
  463. pbPci = pbOutBuffer + sizeof(LPCSCARD_IO_REQUEST);
  464. cbPci = min(pIo->cbPciLength, prqTrace->nBytesReturned);
  465. pbSdu = pbOutBuffer + pIo->cbPciLength;
  466. cbSdu = prqTrace->nBytesReturned - cbPci;
  467. cbPci -= sizeof(SCARD_IO_REQUEST);
  468. MapValue(cout, pIo->dwProtocol, TEXT("Proto: "), rgMapProto);
  469. if (0 < cbPci)
  470. {
  471. cout
  472. << TEXT("Out PCI: (") << PDec(cbPci) << TEXT(" bytes)\n")
  473. << flush;
  474. dump(pbPci, cbPci, cout);
  475. }
  476. cout
  477. << TEXT("Recd: (") << PDec(cbSdu) << TEXT(" bytes)\n")
  478. << flush;
  479. dump(pbSdu, cbSdu, cout);
  480. }
  481. else
  482. RecvDump(cout, prqTrace);
  483. break;
  484. }
  485. case IOCTL_SMARTCARD_EJECT:
  486. GeneralDump(cout, prqTrace);
  487. break;
  488. case IOCTL_SMARTCARD_SWALLOW:
  489. GeneralDump(cout, prqTrace);
  490. break;
  491. case IOCTL_SMARTCARD_IS_PRESENT:
  492. GeneralDump(cout, prqTrace);
  493. break;
  494. case IOCTL_SMARTCARD_IS_ABSENT:
  495. GeneralDump(cout, prqTrace);
  496. break;
  497. case IOCTL_SMARTCARD_SET_PROTOCOL:
  498. MapInput(cout, prqTrace, rgMapProto);
  499. cout << flush;
  500. MapOutput(cout, prqTrace, rgMapProto);
  501. break;
  502. case IOCTL_SMARTCARD_GET_STATE:
  503. {
  504. GeneralDump(cout, prqTrace);
  505. break;
  506. }
  507. case IOCTL_SMARTCARD_GET_LAST_ERROR:
  508. {
  509. GeneralDump(cout, prqTrace);
  510. break;
  511. }
  512. default:
  513. GeneralDump(cout, prqTrace);
  514. break;
  515. }
  516. cout << flush;
  517. }
  518. ErrorExit:
  519. if (NULL == hLogFile)
  520. CloseHandle(hLogFile);
  521. }
  522. static void
  523. dump(
  524. const BYTE *pbData,
  525. DWORD cbLen,
  526. ostream &outStr)
  527. {
  528. unsigned long int
  529. b, i, lc;
  530. char
  531. buffer[8];
  532. lc = 0;
  533. while (0 < cbLen)
  534. {
  535. b = min(sizeof(buffer), cbLen);
  536. memcpy(buffer, pbData, b);
  537. pbData += b;
  538. cbLen -= b;
  539. if (0 < b)
  540. {
  541. outStr << TEXT(" ") << setw(8) << setfill(TEXT('0')) << hex << lc;
  542. for (i = 0; i < b; i += 1)
  543. outStr
  544. << " "
  545. << setw(2) << setfill('0') << hex
  546. << ((unsigned int)buffer[i] & 0xff);
  547. for (; i < sizeof(buffer) + 1; i += 1)
  548. outStr << " ";
  549. for (i = 0; i < b; i += 1)
  550. outStr
  551. << setw(0) << setfill(' ') << dec
  552. << ((0 != iscntrl((int)(0x7f & buffer[i])))
  553. ? TEXT('.')
  554. : buffer[i]);
  555. outStr << endl;
  556. lc += b;
  557. }
  558. }
  559. }
  560. static void
  561. GeneralDump(
  562. ostream &outStr,
  563. const RequestTrace *prqTrace)
  564. {
  565. SendDump(outStr, prqTrace);
  566. outStr << flush;
  567. RecvDump(outStr, prqTrace);
  568. }
  569. static void
  570. SendDump(
  571. ostream &outStr,
  572. const RequestTrace *prqTrace)
  573. {
  574. outStr
  575. << TEXT("Sent: (") << PDec(prqTrace->nInBufferSize) << TEXT(" bytes)\n")
  576. << flush;
  577. dump(
  578. (LPBYTE)prqTrace + prqTrace->nInBuffer,
  579. prqTrace->nInBufferSize,
  580. outStr);
  581. }
  582. static void
  583. RecvDump(
  584. ostream &outStr,
  585. const RequestTrace *prqTrace)
  586. {
  587. outStr
  588. << TEXT("Recd: (") << PDec(prqTrace->nBytesReturned) << TEXT(" bytes)\n")
  589. << flush;
  590. dump(
  591. (LPBYTE)prqTrace + prqTrace->nOutBuffer,
  592. prqTrace->nBytesReturned,
  593. outStr);
  594. }
  595. static void
  596. MapValue(
  597. ostream &outStr,
  598. DWORD dwValue,
  599. LPCTSTR szLeader,
  600. const ValueMap *rgMap)
  601. {
  602. DWORD dwIndex;
  603. if (NULL != rgMap)
  604. {
  605. for (dwIndex = 0; NULL != rgMap[dwIndex].szValue; dwIndex += 1)
  606. if (rgMap[dwIndex].dwValue == dwValue)
  607. break;
  608. if (NULL != rgMap[dwIndex].szValue)
  609. outStr << szLeader << rgMap[dwIndex].szValue << TEXT('\n');
  610. else
  611. outStr << szLeader << PHex(dwValue) << TEXT('\n');
  612. }
  613. else
  614. outStr << szLeader << PHex(dwValue) << TEXT('\n');
  615. }
  616. static void
  617. MaskValue(
  618. ostream &outStr,
  619. DWORD dwValue,
  620. LPCTSTR szLeader,
  621. const ValueMap *rgMap)
  622. {
  623. DWORD dwIndex;
  624. BOOL fSpace = FALSE;
  625. if (NULL != rgMap)
  626. {
  627. if (NULL != szLeader)
  628. outStr << szLeader;
  629. for (dwIndex = 0; NULL != rgMap[dwIndex].szValue; dwIndex += 1)
  630. {
  631. if (rgMap[dwIndex].dwValue == (rgMap[dwIndex].dwValue & dwValue))
  632. {
  633. if (fSpace)
  634. outStr << TEXT(' ');
  635. else
  636. fSpace = TRUE;
  637. outStr << rgMap[dwIndex].szValue;
  638. dwValue &= ~rgMap[dwIndex].dwValue;
  639. }
  640. }
  641. if (0 != dwValue)
  642. {
  643. if (fSpace)
  644. {
  645. outStr << TEXT(' ');
  646. fSpace = TRUE;
  647. }
  648. outStr << PHex(dwValue);
  649. }
  650. else if (!fSpace)
  651. outStr << PHex(dwValue);
  652. outStr << endl;
  653. }
  654. else
  655. outStr << szLeader << PHex(dwValue) << endl;
  656. }
  657. static void
  658. MapInput(
  659. ostream &outStr,
  660. const RequestTrace *prqTrace,
  661. const ValueMap *rgMap)
  662. {
  663. DWORD dwValue;
  664. switch (prqTrace->nInBufferSize)
  665. {
  666. case 0:
  667. break;
  668. case sizeof(DWORD):
  669. dwValue = *(LPDWORD)((LPBYTE)prqTrace + prqTrace->nInBuffer);
  670. MapValue(outStr, dwValue, TEXT("Sent: "), rgMap);
  671. break;
  672. default:
  673. SendDump(outStr, prqTrace);
  674. }
  675. }
  676. static void
  677. MapOutput(
  678. ostream &outStr,
  679. const RequestTrace *prqTrace,
  680. const ValueMap *rgMap)
  681. {
  682. DWORD dwValue;
  683. switch (prqTrace->nBytesReturned)
  684. {
  685. case 0:
  686. break;
  687. case sizeof(DWORD):
  688. dwValue = *(LPDWORD)((LPBYTE)prqTrace + prqTrace->nOutBuffer);
  689. MapValue(outStr, dwValue, TEXT("Recd: "), rgMap);
  690. break;
  691. default:
  692. RecvDump(outStr, prqTrace);
  693. }
  694. }
  695. /*++
  696. ShowSyntax:
  697. Display the command line usage model.
  698. Arguments:
  699. None
  700. Return Value:
  701. This routine calls exit(0), so it never returns.
  702. Author:
  703. Doug Barlow (dbarlow) 5/16/1998
  704. --*/
  705. static void
  706. ShowSyntax(
  707. ostream &outStr)
  708. {
  709. outStr << TEXT("Usage:\n")
  710. << TEXT("------------------------\n")
  711. << TEXT("clear [-file <logFile>]\n")
  712. << TEXT("api [-file <logFile>] [-pid <pid>] [-tid <tid>]\n")
  713. << TEXT("driver [-file <logFile>] [-pid <pid>] [-tid <tid>]\n")
  714. << TEXT("------------------------\n")
  715. << TEXT("DRIVER logs to C:\\Calais.log\n")
  716. << TEXT("API logs to C:\\SCard.log\n")
  717. << endl;
  718. exit(1);
  719. }
  720. /*++
  721. ShowApiLog:
  722. Explain the contents of the API log.
  723. Arguments:
  724. szFile supplies the name of the file to parse. If this is NULL, the file
  725. C:\SCard.log is used.
  726. Return Value:
  727. None
  728. Throws:
  729. None
  730. Author:
  731. Doug Barlow (dbarlow) 8/5/1998
  732. --*/
  733. static void
  734. ShowApiLog(
  735. IN LPCTSTR szFile)
  736. {
  737. static const ValueMap rgMapStates[]
  738. = { MAP(SCARD_STATE_IGNORE),
  739. MAP(SCARD_STATE_CHANGED),
  740. MAP(SCARD_STATE_UNKNOWN),
  741. MAP(SCARD_STATE_UNAVAILABLE),
  742. MAP(SCARD_STATE_EMPTY),
  743. MAP(SCARD_STATE_PRESENT),
  744. MAP(SCARD_STATE_ATRMATCH),
  745. MAP(SCARD_STATE_EXCLUSIVE),
  746. MAP(SCARD_STATE_INUSE),
  747. MAP(SCARD_STATE_MUTE),
  748. MAP(SCARD_STATE_UNPOWERED),
  749. {0, NULL} };
  750. static const ValueMap rgMapDriverStates[]
  751. = {
  752. MAP(SCARD_UNKNOWN),
  753. MAP(SCARD_ABSENT),
  754. MAP(SCARD_PRESENT),
  755. MAP(SCARD_SWALLOWED),
  756. MAP(SCARD_POWERED),
  757. MAP(SCARD_NEGOTIABLE),
  758. MAP(SCARD_SPECIFIC),
  759. {0, NULL} };
  760. static const ValueMap rgMapShare[]
  761. = {
  762. MAP(SCARD_SHARE_EXCLUSIVE),
  763. MAP(SCARD_SHARE_SHARED),
  764. MAP(SCARD_SHARE_DIRECT),
  765. {0, NULL} };
  766. static const ValueMap rgMapDisposition[]
  767. = { MAP(SCARD_LEAVE_CARD),
  768. MAP(SCARD_RESET_CARD),
  769. MAP(SCARD_UNPOWER_CARD),
  770. MAP(SCARD_EJECT_CARD),
  771. {0, NULL} };
  772. HANDLE hLogFile = NULL;
  773. LPCTSTR szInFile = TEXT("C:\\SCard.log");
  774. CComObject *pCom = NULL;
  775. DWORD dwLen;
  776. //
  777. // Open the log file.
  778. //
  779. if (NULL != szFile)
  780. szInFile = szFile;
  781. hLogFile = CreateFile(
  782. szInFile,
  783. GENERIC_READ,
  784. FILE_SHARE_READ | FILE_SHARE_WRITE,
  785. NULL,
  786. OPEN_EXISTING,
  787. 0,
  788. NULL);
  789. if (INVALID_HANDLE_VALUE == hLogFile)
  790. {
  791. cerr << TEXT("Can't open file ") << szInFile << ": "
  792. << ErrorString(GetLastError()) << endl;
  793. goto ErrorExit;
  794. }
  795. //
  796. // Parse the file contents.
  797. //
  798. try
  799. {
  800. for (;;)
  801. {
  802. LogStamp stamp;
  803. BOOL fSts;
  804. fSts = ReadFile(
  805. hLogFile,
  806. &stamp,
  807. sizeof(stamp),
  808. &dwLen,
  809. NULL);
  810. ASSERT(fSts);
  811. pCom = ReceiveComObject(hLogFile);
  812. if (NULL == pCom)
  813. break;
  814. if ((l_dwPid != 0) && (l_dwPid != stamp.dwProcId))
  815. continue;
  816. if ((l_dwTid != 0) && (l_dwTid != stamp.dwProcId))
  817. continue;
  818. cout
  819. << TEXT("------------------------------------------------------------\n")
  820. << TEXT("Process/Thread: ") << PHex(stamp.dwProcId) << TEXT("/") << PHex(stamp.dwThreadId) << TEXT("\n")
  821. << TEXT("Time: ") << PTime(stamp.stLogTime) << endl;
  822. switch (pCom->Type())
  823. {
  824. case CComObject::EstablishContext_request:
  825. {
  826. ComEstablishContext::CObjEstablishContext_request *pReq
  827. = (ComEstablishContext::CObjEstablishContext_request *)pCom->Request();
  828. cout
  829. << TEXT("Establish Context request\n")
  830. << TEXT("Requesting Process: ") << PHex(pReq->dwProcId) << TEXT("\n")
  831. << flush;
  832. break;
  833. }
  834. case CComObject::ReleaseContext_request:
  835. {
  836. ComReleaseContext::CObjReleaseContext_request *pReq =
  837. (ComReleaseContext::CObjReleaseContext_request *)pCom->Request();
  838. cout
  839. << TEXT("Release Context request\n")
  840. << flush;
  841. break;
  842. }
  843. case CComObject::IsValidContext_request:
  844. {
  845. ComIsValidContext::CObjIsValidContext_request *pReq =
  846. (ComIsValidContext::CObjIsValidContext_request *)pCom->Request();
  847. cout
  848. << TEXT("Is Valid Context request\n")
  849. << flush;
  850. break;
  851. }
  852. case CComObject::LocateCards_request:
  853. {
  854. DWORD cbTotAtrs, cbTotMasks, dwStateCount, dwIndex;
  855. LPCTSTR szReader;
  856. ComLocateCards::CObjLocateCards_request *pReq =
  857. (ComLocateCards::CObjLocateCards_request *)pCom->Request();
  858. LPCBYTE pbAtrs = (LPCBYTE)pCom->Parse(pReq->dscAtrs, &cbTotAtrs);
  859. LPCBYTE pbMasks = (LPCBYTE)pCom->Parse(pReq->dscAtrMasks, &cbTotMasks);
  860. LPCTSTR mszReaders = (LPCTSTR)pCom->Parse(pReq->dscReaders);
  861. LPDWORD rgdwStates = (LPDWORD)pCom->Parse(pReq->dscReaderStates, &dwStateCount);
  862. cout
  863. << TEXT("Locate Cards request\n")
  864. << flush;
  865. if (0 == cbTotAtrs)
  866. {
  867. cout << TEXT("ERROR -- Invalid ATR array") << endl;
  868. continue;
  869. }
  870. else if (0 == cbTotMasks)
  871. {
  872. cout << TEXT("ERROR -- Invalid Mask array") << endl;
  873. continue;
  874. }
  875. else if (0 == dwStateCount)
  876. {
  877. cout << TEXT("ERROR -- Invalid State array") << endl;
  878. continue;
  879. }
  880. else if (0 != dwStateCount % sizeof(DWORD))
  881. {
  882. cout << TEXT("ERROR -- Invalid State array length") << endl;
  883. continue;
  884. }
  885. else if (0 == *mszReaders)
  886. {
  887. cout << TEXT("ERROR -- Invalid Reader Name String") << endl;
  888. continue;
  889. }
  890. dwStateCount /= sizeof(DWORD);
  891. cout
  892. << TEXT("Looking for ATRs:\n")
  893. << flush;
  894. while (0 < cbTotAtrs)
  895. {
  896. DWORD cbLength;
  897. cbLength = *pbAtrs++;
  898. cout << TEXT("ATR:\n") << flush;
  899. dump(pbAtrs, cbLength, cout);
  900. pbAtrs += cbLength;
  901. cbTotAtrs -= cbLength + 1;
  902. cbLength = *pbMasks++;
  903. cout << TEXT("Mask:\n") << flush;
  904. dump(pbMasks, cbLength, cout);
  905. pbMasks += cbLength;
  906. }
  907. cout
  908. << TEXT("Looking in readers:\n")
  909. << flush;
  910. for (dwIndex = 0, szReader = FirstString(mszReaders);
  911. dwIndex < dwStateCount;
  912. dwIndex += 1, szReader = NextString(szReader))
  913. {
  914. cout
  915. << TEXT(" ") << szReader << TEXT(":\n")
  916. << TEXT(" ")
  917. << flush;
  918. if (0 == rgdwStates[dwIndex])
  919. cout << TEXT("SCARD_STATE_UNAWARE\n") << flush;
  920. else
  921. MaskValue(cout, rgdwStates[dwIndex], NULL, rgMapStates);
  922. }
  923. break;
  924. }
  925. case CComObject::GetStatusChange_request:
  926. {
  927. DWORD dwIndex;
  928. LPCTSTR szReader;
  929. ComGetStatusChange::CObjGetStatusChange_request *pReq =
  930. (ComGetStatusChange::CObjGetStatusChange_request *)pCom->Request();
  931. LPCTSTR mszReaders = (LPCTSTR)pCom->Parse(pReq->dscReaders);
  932. LPDWORD rgdwStates = (LPDWORD)pCom->Parse(pReq->dscReaderStates, &dwLen);
  933. cout
  934. << TEXT("Get Status Change request\n")
  935. << flush;
  936. if (0 == dwLen)
  937. {
  938. cout << TEXT("ERROR -- Invalid State array") << endl;
  939. continue;
  940. }
  941. else if (0 != dwLen % sizeof(DWORD))
  942. {
  943. cout << TEXT("ERROR -- Invalid State array length") << endl;
  944. continue;
  945. }
  946. else if (0 == *mszReaders)
  947. {
  948. cout << TEXT("ERROR -- Invalid Reader Name String") << endl;
  949. continue;
  950. }
  951. cout
  952. << TEXT("Timeout: ") << PDec(pReq->dwTimeout) << TEXT(" Milliseconds\n")
  953. << TEXT("Monitoring readers:\n")
  954. << flush;
  955. for (dwIndex = 0, szReader = FirstString(mszReaders);
  956. NULL != szReader;
  957. dwIndex += 1, szReader = NextString(szReader))
  958. {
  959. cout
  960. << TEXT(" ") << szReader << TEXT(":\n")
  961. << flush;
  962. if (0 == rgdwStates[dwIndex])
  963. cout << TEXT(" SCARD_STATE_UNAWARE") << endl;
  964. else
  965. MaskValue(cout, rgdwStates[dwIndex], TEXT(" "), rgMapStates);
  966. }
  967. break;
  968. }
  969. case CComObject::ListReaders_request:
  970. {
  971. LPCTSTR szReader;
  972. ComListReaders::CObjListReaders_request *pReq =
  973. (ComListReaders::CObjListReaders_request *)pCom->Request();
  974. LPCTSTR mszQueryReaders = (LPCTSTR)pCom->Parse(pReq->dscReaders);
  975. cout
  976. << TEXT("List Readers request\n")
  977. << TEXT("Readers:\n")
  978. << flush;
  979. for (szReader = FirstString(mszQueryReaders);
  980. NULL != szReader;
  981. szReader = NextString(szReader))
  982. {
  983. cout << TEXT(" ") << szReader << endl;
  984. }
  985. break;
  986. }
  987. case CComObject::Connect_request:
  988. {
  989. ComConnect::CObjConnect_request *pReq
  990. = (ComConnect::CObjConnect_request *)pCom->Request();
  991. LPCTSTR szReader = (LPCTSTR)pCom->Parse(pReq->dscReader);
  992. cout
  993. << TEXT("Connect request\n")
  994. << TEXT("Reader: ") << szReader << endl;
  995. MapValue(cout, pReq->dwPreferredProtocols,
  996. TEXT("Protocols: "), rgMapProto);
  997. MapValue(cout, pReq->dwShareMode,
  998. TEXT("Sharing Mode: "), rgMapShare);
  999. break;
  1000. }
  1001. case CComObject::Reconnect_request:
  1002. {
  1003. ComReconnect::CObjReconnect_request *pReq
  1004. = (ComReconnect::CObjReconnect_request *)pCom->Request();
  1005. cout
  1006. << TEXT("Reconnect request\n")
  1007. << TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
  1008. << flush;
  1009. MapValue(cout, pReq->dwInitialization,
  1010. TEXT("Disposition: "), rgMapDisposition);
  1011. MapValue(cout, pReq->dwPreferredProtocols,
  1012. TEXT("Protocols: "), rgMapProto);
  1013. MapValue(cout, pReq->dwShareMode,
  1014. TEXT("Sharing Mode: "), rgMapShare);
  1015. break;
  1016. }
  1017. case CComObject::Disconnect_request:
  1018. {
  1019. ComDisconnect::CObjDisconnect_request *pReq
  1020. = (ComDisconnect::CObjDisconnect_request *)pCom->Request();
  1021. cout
  1022. << TEXT("Disconnect request\n")
  1023. << TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
  1024. << flush;
  1025. MapValue(cout, pReq->dwDisposition,
  1026. TEXT("Disposition: "), rgMapDisposition);
  1027. break;
  1028. }
  1029. case CComObject::BeginTransaction_request:
  1030. {
  1031. ComBeginTransaction::CObjBeginTransaction_request *pReq
  1032. = (ComBeginTransaction::CObjBeginTransaction_request *)
  1033. pCom->Request();
  1034. cout
  1035. << TEXT("Begin Transaction request\n")
  1036. << TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
  1037. << flush;
  1038. break;
  1039. }
  1040. case CComObject::EndTransaction_request:
  1041. {
  1042. ComEndTransaction::CObjEndTransaction_request *pReq
  1043. = (ComEndTransaction::CObjEndTransaction_request *)pCom->Request();
  1044. cout
  1045. << TEXT("End Transaction request\n")
  1046. << TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
  1047. << flush;
  1048. MapValue(cout, pReq->dwDisposition,
  1049. TEXT("Disposition: "), rgMapDisposition);
  1050. break;
  1051. }
  1052. case CComObject::Status_request:
  1053. {
  1054. ComStatus::CObjStatus_request *pReq
  1055. = (ComStatus::CObjStatus_request *)pCom->Request();
  1056. cout
  1057. << TEXT("Status request\n")
  1058. << TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
  1059. << flush;
  1060. break;
  1061. }
  1062. case CComObject::Transmit_request:
  1063. {
  1064. DWORD cbPci, cbData;
  1065. ComTransmit::CObjTransmit_request *pReq
  1066. = (ComTransmit::CObjTransmit_request *)pCom->Request();
  1067. SCARD_IO_REQUEST *pioReq = (SCARD_IO_REQUEST *)pCom->Parse(pReq->dscSendPci, &cbPci);
  1068. LPCBYTE pbSendData = (LPCBYTE)pCom->Parse(pReq->dscSendBuffer, &cbData);
  1069. cout
  1070. << TEXT("Transmit request\n")
  1071. << TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
  1072. << TEXT("PCI:\n")
  1073. << flush;
  1074. dump((LPCBYTE)pioReq, cbPci, cout);
  1075. cout
  1076. << TEXT("Data:\n")
  1077. << flush;
  1078. dump(pbSendData, cbData, cout);
  1079. cout
  1080. << TEXT("Return PCI Length: ") << PDec(pReq->dwPciLength) << TEXT("\n")
  1081. << TEXT("Return Data Length: ") << PDec(pReq->dwRecvLength) << TEXT("\n")
  1082. << flush;
  1083. break;
  1084. }
  1085. case CComObject::Control_request:
  1086. {
  1087. ComControl::CObjControl_request *pReq
  1088. = (ComControl::CObjControl_request *)pCom->Request();
  1089. LPCBYTE pbInData = (LPCBYTE)pCom->Parse(pReq->dscInBuffer, &dwLen);
  1090. cout
  1091. << TEXT("Control request\n")
  1092. << TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
  1093. << flush;
  1094. MapValue(cout, pReq->dwControlCode,
  1095. TEXT("Control Code: "), rgMapIoctl);
  1096. cout << TEXT("Control Data:\n") << flush;
  1097. dump(pbInData, dwLen, cout);
  1098. cout
  1099. << TEXT("Return Data Length: ") << PDec(pReq->dwOutLength) << TEXT("\n")
  1100. << flush;
  1101. break;
  1102. }
  1103. case CComObject::GetAttrib_request:
  1104. {
  1105. ComGetAttrib::CObjGetAttrib_request *pReq
  1106. = (ComGetAttrib::CObjGetAttrib_request *)pCom->Request();
  1107. cout
  1108. << TEXT("Get Attribute request\n")
  1109. << TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
  1110. << flush;
  1111. MapValue(cout, pReq->dwAttrId,
  1112. TEXT("Attribute: "), rgMapAttr);
  1113. cout
  1114. << TEXT("Return Data Length: ") << PDec(pReq->dwOutLength) << TEXT("\n")
  1115. << flush;
  1116. break;
  1117. }
  1118. case CComObject::SetAttrib_request:
  1119. {
  1120. ComSetAttrib::CObjSetAttrib_request *pReq
  1121. = (ComSetAttrib::CObjSetAttrib_request *)pCom->Request();
  1122. LPCBYTE pbAttr = (LPCBYTE)pCom->Parse(pReq->dscAttr, &dwLen);
  1123. cout
  1124. << TEXT("Set Attribute request\n")
  1125. << TEXT("Handle: ") << PHex(pReq->hCard) << TEXT("\n")
  1126. << flush;
  1127. MapValue(cout, pReq->dwAttrId,
  1128. TEXT("Attribute: "), rgMapAttr);
  1129. cout << TEXT("Data:") << endl;
  1130. dump(pbAttr, dwLen, cout);
  1131. break;
  1132. }
  1133. case CComObject::EstablishContext_response:
  1134. {
  1135. ComEstablishContext::CObjEstablishContext_response *pRsp
  1136. = (ComEstablishContext::CObjEstablishContext_response *)pCom->Response();
  1137. cout
  1138. << TEXT("Establish Context response\n")
  1139. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1140. << flush;
  1141. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1142. {
  1143. LPCTSTR szCancelEvent = (LPCTSTR)pCom->Parse(pRsp->dscCancelEvent);
  1144. cout
  1145. << TEXT("Alt Event Name: ") << szCancelEvent << TEXT("\n")
  1146. << flush;
  1147. }
  1148. break;
  1149. }
  1150. case CComObject::ReleaseContext_response:
  1151. {
  1152. ComReleaseContext::CObjReleaseContext_response *pRsp =
  1153. (ComReleaseContext::CObjReleaseContext_response *)pCom->Response();
  1154. cout
  1155. << TEXT("Release Context response\n")
  1156. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1157. << flush;
  1158. break;
  1159. }
  1160. case CComObject::IsValidContext_response:
  1161. {
  1162. ComIsValidContext::CObjIsValidContext_response *pRsp =
  1163. (ComIsValidContext::CObjIsValidContext_response *)pCom->Response();
  1164. cout
  1165. << TEXT("Is Valid Context response\n")
  1166. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1167. << flush;
  1168. break;
  1169. }
  1170. case CComObject::LocateCards_response:
  1171. {
  1172. DWORD dwIndex, dwAtrLen;
  1173. ComLocateCards::CObjLocateCards_response *pRsp =
  1174. (ComLocateCards::CObjLocateCards_response *)pCom->Response();
  1175. cout
  1176. << TEXT("Locate Cards response\n")
  1177. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1178. << flush;
  1179. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1180. {
  1181. LPDWORD rgdwStates = (LPDWORD)pCom->Parse(pRsp->dscReaderStates, &dwLen);
  1182. LPCBYTE pbAtrs = (LPCBYTE)pCom->Parse(pRsp->dscAtrs);
  1183. dwLen /= sizeof(DWORD);
  1184. for (dwIndex = 0; dwIndex < dwLen; dwIndex += 1)
  1185. {
  1186. cout << TEXT("Mask:\n ") << flush;
  1187. if (0 == rgdwStates[dwIndex])
  1188. cout << TEXT("SCARD_STATE_UNAWARE") << endl;
  1189. MaskValue(cout, rgdwStates[dwIndex], NULL, rgMapStates);
  1190. cout << TEXT("ATR:\n") << flush;
  1191. dwAtrLen = *pbAtrs++;
  1192. dump(pbAtrs, dwAtrLen, cout);
  1193. pbAtrs += dwAtrLen;
  1194. }
  1195. }
  1196. break;
  1197. }
  1198. case CComObject::GetStatusChange_response:
  1199. {
  1200. DWORD dwIndex, dwAtrLen;
  1201. ComGetStatusChange::CObjGetStatusChange_response *pRsp =
  1202. (ComGetStatusChange::CObjGetStatusChange_response *)pCom->Response();
  1203. cout
  1204. << TEXT("Get Status Change response\n")
  1205. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1206. << flush;
  1207. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1208. {
  1209. LPDWORD rgdwStates = (LPDWORD)pCom->Parse(pRsp->dscReaderStates, &dwLen);
  1210. LPCBYTE pbAtrs = (LPCBYTE)pCom->Parse(pRsp->dscAtrs);
  1211. dwLen /= sizeof(DWORD);
  1212. for (dwIndex = 0; dwIndex < dwLen; dwIndex += 1)
  1213. {
  1214. cout << TEXT("Mask:\n") << flush;
  1215. if (0 == rgdwStates[dwIndex])
  1216. cout << TEXT(" SCARD_STATE_UNAWARE") << endl;
  1217. else
  1218. MaskValue(cout, rgdwStates[dwIndex], TEXT(" "), rgMapStates);
  1219. cout << TEXT("ATR:\n") << flush;
  1220. dwAtrLen = *pbAtrs++;
  1221. dump(pbAtrs, dwAtrLen, cout);
  1222. pbAtrs += dwAtrLen;
  1223. }
  1224. }
  1225. break;
  1226. }
  1227. case CComObject::ListReaders_response:
  1228. {
  1229. DWORD dwIndex;
  1230. ComListReaders::CObjListReaders_response *pRsp =
  1231. (ComListReaders::CObjListReaders_response *)pCom->Response();
  1232. cout
  1233. << TEXT("List Readers response\n")
  1234. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1235. << flush;
  1236. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1237. {
  1238. LPDWORD pdwReaders = (LPDWORD)pCom->Parse(pRsp->dscReaders, &dwLen);
  1239. cout
  1240. << TEXT("Readers:\n")
  1241. << flush;
  1242. dwLen /= sizeof(DWORD);
  1243. for (dwIndex = 0; dwIndex < dwLen; dwIndex += 1)
  1244. {
  1245. if (0 != pdwReaders[dwIndex])
  1246. cout << TEXT(" Present") << endl;
  1247. else
  1248. cout << TEXT(" Offline") << endl;
  1249. }
  1250. }
  1251. break;
  1252. }
  1253. case CComObject::Connect_response:
  1254. {
  1255. ComConnect::CObjConnect_response *pRsp
  1256. = (ComConnect::CObjConnect_response *)pCom->Response();
  1257. cout
  1258. << TEXT("Connect response\n")
  1259. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1260. << flush;
  1261. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1262. {
  1263. cout
  1264. << TEXT("SCARDHANDLE: ") << PHex(pRsp->hCard) << TEXT("\n")
  1265. << flush;
  1266. MapValue(cout, pRsp->dwActiveProtocol,
  1267. TEXT("Protocol: "), rgMapProto);
  1268. }
  1269. break;
  1270. }
  1271. case CComObject::Reconnect_response:
  1272. {
  1273. ComReconnect::CObjReconnect_response *pRsp
  1274. = (ComReconnect::CObjReconnect_response *)pCom->Response();
  1275. cout
  1276. << TEXT("Reconnect response\n")
  1277. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1278. << flush;
  1279. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1280. {
  1281. MapValue(cout, pRsp->dwActiveProtocol,
  1282. TEXT("Protocol: "), rgMapProto);
  1283. }
  1284. break;
  1285. }
  1286. case CComObject::Disconnect_response:
  1287. {
  1288. ComDisconnect::CObjDisconnect_response *pRsp
  1289. = (ComDisconnect::CObjDisconnect_response *)pCom->Response();
  1290. cout
  1291. << TEXT("Disconnect response\n")
  1292. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1293. << flush;
  1294. break;
  1295. }
  1296. case CComObject::BeginTransaction_response:
  1297. {
  1298. ComBeginTransaction::CObjBeginTransaction_response *pRsp
  1299. = (ComBeginTransaction::CObjBeginTransaction_response *)
  1300. pCom->Response();
  1301. cout
  1302. << TEXT("Begin Transaction response\n")
  1303. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1304. << flush;
  1305. break;
  1306. }
  1307. case CComObject::EndTransaction_response:
  1308. {
  1309. ComEndTransaction::CObjEndTransaction_response *pRsp
  1310. = (ComEndTransaction::CObjEndTransaction_response *)pCom->Response();
  1311. cout
  1312. << TEXT("End Transaction response\n")
  1313. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1314. << flush;
  1315. break;
  1316. }
  1317. case CComObject::Status_response:
  1318. {
  1319. DWORD cbAtrLen;
  1320. ComStatus::CObjStatus_response *pRsp
  1321. = (ComStatus::CObjStatus_response *)pCom->Response();
  1322. cout
  1323. << TEXT("Status response\n")
  1324. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1325. << flush;
  1326. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1327. {
  1328. LPCBYTE pbAtr = (LPCBYTE)pCom->Parse(pRsp->dscAtr, &cbAtrLen);
  1329. LPCTSTR szRdr = (LPCTSTR)pCom->Parse(pRsp->dscSysName);
  1330. MapValue(cout, pRsp->dwState,
  1331. TEXT("State: "), rgMapDriverStates);
  1332. MapValue(cout, pRsp->dwProtocol,
  1333. TEXT("Protocol: "), rgMapProto);
  1334. cout
  1335. << TEXT("ATR:\n")
  1336. << flush;
  1337. dump(pbAtr, cbAtrLen, cout);
  1338. cout
  1339. << TEXT("Reader Sys Name: ") << szRdr << endl;
  1340. }
  1341. break;
  1342. }
  1343. case CComObject::Transmit_response:
  1344. {
  1345. DWORD cbPci, cbData;
  1346. ComTransmit::CObjTransmit_response *pRsp
  1347. = (ComTransmit::CObjTransmit_response *)pCom->Response();
  1348. cout
  1349. << TEXT("Transmit response\n")
  1350. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1351. << flush;
  1352. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1353. {
  1354. SCARD_IO_REQUEST *pioRsp = (SCARD_IO_REQUEST *)pCom->Parse(pRsp->dscRecvPci, &cbPci);
  1355. LPCBYTE pbRecvData = (LPCBYTE)pCom->Parse(pRsp->dscRecvBuffer, &cbData);
  1356. cout
  1357. << TEXT("PCI:\n")
  1358. << flush;
  1359. dump((LPCBYTE)pioRsp, cbPci, cout);
  1360. cout
  1361. << TEXT("Data:\n")
  1362. << flush;
  1363. dump(pbRecvData, cbData, cout);
  1364. }
  1365. break;
  1366. }
  1367. case CComObject::Control_response:
  1368. {
  1369. ComControl::CObjControl_response *pRsp
  1370. = (ComControl::CObjControl_response *)pCom->Response();
  1371. LPCBYTE pbData = (LPCBYTE)pCom->Parse(pRsp->dscOutBuffer, &dwLen);
  1372. cout
  1373. << TEXT("Control response\n")
  1374. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1375. << flush;
  1376. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1377. {
  1378. LPCBYTE pbData = (LPCBYTE)pCom->Parse(pRsp->dscOutBuffer, &dwLen);
  1379. cout
  1380. << TEXT("Data:\n")
  1381. << flush;
  1382. dump(pbData, dwLen, cout);
  1383. }
  1384. break;
  1385. }
  1386. case CComObject::GetAttrib_response:
  1387. {
  1388. ComGetAttrib::CObjGetAttrib_response *pRsp
  1389. = (ComGetAttrib::CObjGetAttrib_response *)pCom->Response();
  1390. cout
  1391. << TEXT("Get Attribute response\n")
  1392. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1393. << flush;
  1394. if (SCARD_S_SUCCESS == pRsp->dwStatus)
  1395. {
  1396. LPCBYTE pbData = (LPCBYTE)pCom->Parse(pRsp->dscAttr, &dwLen);
  1397. cout
  1398. << TEXT("Data:\n")
  1399. << flush;
  1400. dump(pbData, dwLen, cout);
  1401. }
  1402. break;
  1403. }
  1404. case CComObject::SetAttrib_response:
  1405. {
  1406. ComSetAttrib::CObjSetAttrib_response *pRsp
  1407. = (ComSetAttrib::CObjSetAttrib_response *)pCom->Response();
  1408. cout
  1409. << TEXT("Set Attribute response\n")
  1410. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1411. << flush;
  1412. break;
  1413. }
  1414. default:
  1415. if (0 == (1 & pCom->Type()))
  1416. {
  1417. CComObject::CObjGeneric_request *pReq
  1418. = (CComObject::CObjGeneric_request *)pCom->Request();
  1419. cout
  1420. << TEXT("Unrecognized request\n")
  1421. << flush;
  1422. }
  1423. else
  1424. {
  1425. CComObject::CObjGeneric_response *pRsp
  1426. = (CComObject::CObjGeneric_response *)pCom->Response();
  1427. cout
  1428. << TEXT("Unrecognized response\n")
  1429. << TEXT("Status: ") << ErrorString(pRsp->dwStatus) << TEXT("\n")
  1430. << flush;
  1431. }
  1432. }
  1433. delete pCom;
  1434. pCom = NULL;
  1435. }
  1436. }
  1437. catch (...)
  1438. {
  1439. if (NULL != pCom)
  1440. delete pCom;
  1441. cerr << TEXT("\n*** ERROR *** Exception parsing log file") << endl;
  1442. }
  1443. ErrorExit:
  1444. if (NULL != hLogFile)
  1445. CloseHandle(hLogFile);
  1446. }
  1447. /*++
  1448. ReceiveComObject:
  1449. This routine creates the proper CComObject child object for the data
  1450. coming in from a log file.
  1451. Arguments:
  1452. hFile supplies the file handle from which the data is to be extracted.
  1453. Return Value:
  1454. The newly created CComObject child object. This object must be cleaned up
  1455. via the delete command.
  1456. Throws:
  1457. ?exceptions?
  1458. Author:
  1459. Doug Barlow (dbarlow) 11/13/1996
  1460. --*/
  1461. CComObject *
  1462. ReceiveComObject(
  1463. HANDLE hFile)
  1464. {
  1465. CComObject *pCom = NULL;
  1466. try
  1467. {
  1468. DWORD rgdwInData[2];
  1469. DWORD dwLen;
  1470. BOOL fSts;
  1471. //
  1472. // See what's coming.
  1473. //
  1474. fSts = ReadFile(
  1475. hFile,
  1476. rgdwInData,
  1477. sizeof(rgdwInData),
  1478. &dwLen,
  1479. NULL);
  1480. if (!fSts)
  1481. {
  1482. DWORD dwSts = GetLastError();
  1483. switch (dwSts)
  1484. {
  1485. case ERROR_HANDLE_EOF:
  1486. throw dwSts;
  1487. break;
  1488. default:
  1489. cerr << TEXT("Can't read input file: ")
  1490. << ErrorString(dwSts);
  1491. throw dwSts;
  1492. }
  1493. }
  1494. else if (0 == dwLen)
  1495. throw (DWORD)ERROR_HANDLE_EOF;
  1496. else if (dwLen != sizeof(rgdwInData))
  1497. throw (DWORD)SCARD_F_COMM_ERROR;
  1498. switch (rgdwInData[0]) // dwCommndId
  1499. {
  1500. case CComObject::EstablishContext_request:
  1501. pCom = new ComEstablishContext;
  1502. break;
  1503. case CComObject::EstablishContext_response:
  1504. pCom = new ComEstablishContext;
  1505. break;
  1506. case CComObject::ReleaseContext_request:
  1507. pCom = new ComReleaseContext;
  1508. break;
  1509. case CComObject::ReleaseContext_response:
  1510. pCom = new ComReleaseContext;
  1511. break;
  1512. case CComObject::IsValidContext_request:
  1513. pCom = new ComIsValidContext;
  1514. break;
  1515. case CComObject::IsValidContext_response:
  1516. pCom = new ComIsValidContext;
  1517. break;
  1518. case CComObject::ListReaders_request:
  1519. pCom = new ComListReaders;
  1520. break;
  1521. case CComObject::ListReaders_response:
  1522. pCom = new ComListReaders;
  1523. break;
  1524. #if 0
  1525. case CComObject::ListReaderGroups_request:
  1526. pCom = new ComListReaderGroups;
  1527. break;
  1528. case CComObject::ListReaderGroups_response:
  1529. pCom = new ComListReaderGroups;
  1530. break;
  1531. case CComObject::ListCards_request:
  1532. pCom = new ComListCards;
  1533. break;
  1534. case CComObject::ListCards_response:
  1535. pCom = new ComListCards;
  1536. break;
  1537. case CComObject::ListInterfaces_request:
  1538. pCom = new ComListInterfaces;
  1539. break;
  1540. case CComObject::ListInterfaces_response:
  1541. pCom = new ComListInterfaces;
  1542. break;
  1543. case CComObject::GetProviderId_request:
  1544. pCom = new ComGetProviderId;
  1545. break;
  1546. case CComObject::GetProviderId_response:
  1547. pCom = new ComGetProviderId;
  1548. break;
  1549. case CComObject::IntroduceReaderGroup_request:
  1550. pCom = new ComIntroduceReaderGroup;
  1551. break;
  1552. case CComObject::IntroduceReaderGroup_response:
  1553. pCom = new ComIntroduceReaderGroup;
  1554. break;
  1555. case CComObject::ForgetReaderGroup_request:
  1556. pCom = new ComForgetReaderGroup;
  1557. break;
  1558. case CComObject::ForgetReaderGroup_response:
  1559. pCom = new ComForgetReaderGroup;
  1560. break;
  1561. case CComObject::IntroduceReader_request:
  1562. pCom = new ComIntroduceReader;
  1563. break;
  1564. case CComObject::IntroduceReader_response:
  1565. pCom = new ComIntroduceReader;
  1566. break;
  1567. case CComObject::ForgetReader_request:
  1568. pCom = new ComForgetReader;
  1569. break;
  1570. case CComObject::ForgetReader_response:
  1571. pCom = new ComForgetReader;
  1572. break;
  1573. case CComObject::AddReaderToGroup_request:
  1574. pCom = new ComAddReaderToGroup;
  1575. break;
  1576. case CComObject::AddReaderToGroup_response:
  1577. pCom = new ComAddReaderToGroup;
  1578. break;
  1579. case CComObject::RemoveReaderFromGroup_request:
  1580. pCom = new ComRemoveReaderFromGroup;
  1581. break;
  1582. case CComObject::RemoveReaderFromGroup_response:
  1583. pCom = new ComRemoveReaderFromGroup;
  1584. break;
  1585. case CComObject::IntroduceCardType_request:
  1586. pCom = new ComIntroduceCardType;
  1587. break;
  1588. case CComObject::IntroduceCardType_response:
  1589. pCom = new ComIntroduceCardType;
  1590. break;
  1591. case CComObject::ForgetCardType_request:
  1592. pCom = new ComForgetCardType;
  1593. break;
  1594. case CComObject::ForgetCardType_response:
  1595. pCom = new ComForgetCardType;
  1596. break;
  1597. case CComObject::FreeMemory_request:
  1598. pCom = new ComFreeMemory;
  1599. break;
  1600. case CComObject::FreeMemory_response:
  1601. pCom = new ComFreeMemory;
  1602. break;
  1603. case CComObject::Cancel_request:
  1604. pCom = new ComCancel;
  1605. break;
  1606. case CComObject::Cancel_response:
  1607. pCom = new ComCancel;
  1608. break;
  1609. #endif
  1610. case CComObject::LocateCards_request:
  1611. pCom = new ComLocateCards;
  1612. break;
  1613. case CComObject::LocateCards_response:
  1614. pCom = new ComLocateCards;
  1615. break;
  1616. case CComObject::GetStatusChange_request:
  1617. pCom = new ComGetStatusChange;
  1618. break;
  1619. case CComObject::GetStatusChange_response:
  1620. pCom = new ComGetStatusChange;
  1621. break;
  1622. case CComObject::Connect_request:
  1623. pCom = new ComConnect;
  1624. break;
  1625. case CComObject::Connect_response:
  1626. pCom = new ComConnect;
  1627. break;
  1628. case CComObject::Reconnect_request:
  1629. pCom = new ComReconnect;
  1630. break;
  1631. case CComObject::Reconnect_response:
  1632. pCom = new ComReconnect;
  1633. break;
  1634. case CComObject::Disconnect_request:
  1635. pCom = new ComDisconnect;
  1636. break;
  1637. case CComObject::Disconnect_response:
  1638. pCom = new ComDisconnect;
  1639. break;
  1640. case CComObject::BeginTransaction_request:
  1641. pCom = new ComBeginTransaction;
  1642. break;
  1643. case CComObject::BeginTransaction_response:
  1644. pCom = new ComBeginTransaction;
  1645. break;
  1646. case CComObject::EndTransaction_request:
  1647. pCom = new ComEndTransaction;
  1648. break;
  1649. case CComObject::EndTransaction_response:
  1650. pCom = new ComEndTransaction;
  1651. break;
  1652. case CComObject::Status_request:
  1653. pCom = new ComStatus;
  1654. break;
  1655. case CComObject::Status_response:
  1656. pCom = new ComStatus;
  1657. break;
  1658. case CComObject::Transmit_request:
  1659. pCom = new ComTransmit;
  1660. break;
  1661. case CComObject::Transmit_response:
  1662. pCom = new ComTransmit;
  1663. break;
  1664. case CComObject::OpenReader_request:
  1665. pCom = new ComOpenReader;
  1666. break;
  1667. case CComObject::OpenReader_response:
  1668. pCom = new ComOpenReader;
  1669. break;
  1670. case CComObject::Control_request:
  1671. pCom = new ComControl;
  1672. break;
  1673. case CComObject::Control_response:
  1674. pCom = new ComControl;
  1675. break;
  1676. case CComObject::GetAttrib_request:
  1677. pCom = new ComGetAttrib;
  1678. break;
  1679. case CComObject::GetAttrib_response:
  1680. pCom = new ComGetAttrib;
  1681. break;
  1682. case CComObject::SetAttrib_request:
  1683. pCom = new ComSetAttrib;
  1684. break;
  1685. case CComObject::SetAttrib_response:
  1686. pCom = new ComSetAttrib;
  1687. break;
  1688. default:
  1689. CalaisWarning(
  1690. DBGT("ReceiveComObject"),
  1691. DBGT("Invalid Comm Object Id on pipe"));
  1692. throw (DWORD)SCARD_F_COMM_ERROR;
  1693. }
  1694. if (0 == (rgdwInData[0] & 0x01)) // Request or response?
  1695. pCom->m_pbfActive = &pCom->m_bfRequest;
  1696. else
  1697. pCom->m_pbfActive = &pCom->m_bfResponse;
  1698. //
  1699. // Pull it in.
  1700. //
  1701. pCom->m_pbfActive->Resize(rgdwInData[1]);
  1702. CopyMemory(
  1703. pCom->m_pbfActive->Access(),
  1704. rgdwInData,
  1705. sizeof(rgdwInData));
  1706. fSts = ReadFile(
  1707. hFile,
  1708. pCom->m_pbfActive->Access(sizeof(rgdwInData)),
  1709. rgdwInData[1] - sizeof(rgdwInData),
  1710. &dwLen,
  1711. NULL);
  1712. if (!fSts)
  1713. {
  1714. DWORD dwSts = GetLastError();
  1715. cerr << TEXT("Can't read input file: ")
  1716. << ErrorString(dwSts);
  1717. throw dwSts;
  1718. }
  1719. }
  1720. catch (...)
  1721. {
  1722. if (NULL != pCom)
  1723. {
  1724. delete pCom;
  1725. pCom = NULL;
  1726. }
  1727. }
  1728. return pCom;
  1729. }