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.

2100 lines
53 KiB

  1. #include <stdarg.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <conio.h>
  5. #include <afx.h>
  6. #include <afxtempl.h>
  7. #include <winioctl.h>
  8. #include <winsmcrd.h>
  9. #include "ifdtest.h"
  10. class CCardProvider *CCardProvider::s_pFirst;
  11. #define INSERT_CARD "Please insert smart card"
  12. #define REMOVE_CARD "Please remove smart card"
  13. PCHAR
  14. CAtr::GetAtrString(
  15. PCHAR in_pchBuffer
  16. )
  17. {
  18. for (ULONG i = 0; i < m_uAtrLength; i++) {
  19. sprintf(in_pchBuffer + i * 3, "%02X ", m_rgbAtr[i]);
  20. }
  21. return in_pchBuffer;
  22. }
  23. CCardProvider::CCardProvider(
  24. void
  25. )
  26. {
  27. m_pNext = NULL;
  28. m_uTestNo = 0;
  29. m_bCardTested = FALSE;
  30. m_bTestFailed = FALSE;
  31. m_pSetProtocol = NULL;
  32. m_pCardTest = NULL;
  33. }
  34. CCardProvider::CCardProvider(
  35. void (*in_pEntryFunction)(class CCardProvider&)
  36. )
  37. /*++
  38. Routine Description:
  39. Constructor for class CCardProvider.
  40. This constructor is called for every card that is to be tested.
  41. It creates a new instance and appends it to a singly linked list
  42. Arguments:
  43. Pointer to function that registers all test functions
  44. --*/
  45. {
  46. class CCardProvider *l_pCardProvider;
  47. *this = CCardProvider();
  48. if (s_pFirst == NULL) {
  49. s_pFirst = new CCardProvider;
  50. l_pCardProvider = s_pFirst;
  51. } else {
  52. l_pCardProvider = s_pFirst;
  53. while (l_pCardProvider->m_pNext) {
  54. l_pCardProvider = l_pCardProvider->m_pNext;
  55. }
  56. l_pCardProvider->m_pNext = new CCardProvider;
  57. l_pCardProvider = l_pCardProvider->m_pNext;
  58. }
  59. (*in_pEntryFunction)(*l_pCardProvider);
  60. }
  61. BOOL
  62. CCardProvider::CardsUntested(
  63. void
  64. )
  65. {
  66. class CCardProvider *l_pCCardProvider = s_pFirst;
  67. while (l_pCCardProvider) {
  68. if (l_pCCardProvider->m_bCardTested == FALSE) {
  69. return TRUE;
  70. }
  71. l_pCCardProvider = l_pCCardProvider->m_pNext;
  72. }
  73. return FALSE;
  74. }
  75. void
  76. CCardProvider::CardTest(
  77. class CReader& io_pCReader,
  78. ULONG in_uTestNo
  79. )
  80. /*++
  81. Routine Description:
  82. Calls every registered card provider in the list until one of
  83. the providers indicates that it recognized the card
  84. Arguments:
  85. io_pCReader - reference to the test structure
  86. Return Value:
  87. IFDSTATUS value
  88. --*/
  89. {
  90. class CCardProvider *l_pCCardProvider = s_pFirst;
  91. ULONG l_uStatus;
  92. while (l_pCCardProvider) {
  93. if ( l_pCCardProvider->IsValidAtr(io_pCReader.GetAtr()) ) {
  94. if (l_pCCardProvider->m_bCardTested) {
  95. // We tested this card already
  96. LogMessage("Card has been tested already. Please remove the card");
  97. return;
  98. }
  99. l_pCCardProvider->m_bCardTested = TRUE;
  100. LogMessage(
  101. "\nTesting card %s",
  102. (LPCSTR) l_pCCardProvider->m_CCardName
  103. );
  104. if (l_pCCardProvider->m_pSetProtocol == NULL) {
  105. return;
  106. }
  107. // Call card provider function
  108. l_uStatus = (*l_pCCardProvider->m_pSetProtocol)(
  109. *l_pCCardProvider,
  110. io_pCReader
  111. );
  112. if (l_uStatus == IFDSTATUS_END) {
  113. return;
  114. }
  115. if (l_uStatus != IFDSTATUS_SUCCESS) {
  116. return;
  117. }
  118. // Check if the card test function pointer exists
  119. if (l_pCCardProvider->m_pCardTest == NULL) {
  120. return;
  121. }
  122. if (in_uTestNo) {
  123. // user wants to run only a single test
  124. l_pCCardProvider->m_uTestNo = in_uTestNo;
  125. LogMessage("Test No. %2d", l_pCCardProvider->m_uTestNo);
  126. // Call card provider function
  127. l_uStatus = (*l_pCCardProvider->m_pCardTest)(
  128. *l_pCCardProvider,
  129. io_pCReader
  130. );
  131. return;
  132. }
  133. // run the whole test set
  134. for (l_pCCardProvider->m_uTestNo = 1; ;l_pCCardProvider->m_uTestNo++) {
  135. LogMessage("Test No. %2d", l_pCCardProvider->m_uTestNo);
  136. // Call card provider function
  137. l_uStatus = (*l_pCCardProvider->m_pCardTest)(
  138. *l_pCCardProvider,
  139. io_pCReader
  140. );
  141. if (l_uStatus != IFDSTATUS_SUCCESS) {
  142. return;
  143. }
  144. }
  145. }
  146. l_pCCardProvider = l_pCCardProvider->m_pNext;
  147. }
  148. PCHAR l_rgbAtrBuffer = new CHAR[256];
  149. LogMessage("Card unknown!");
  150. LogMessage(" CURRENT CARD");
  151. LogMessage(" %s", io_pCReader.GetAtrString(l_rgbAtrBuffer));
  152. for (l_pCCardProvider = s_pFirst;
  153. l_pCCardProvider;
  154. l_pCCardProvider = l_pCCardProvider->m_pNext) {
  155. if (l_pCCardProvider->m_bCardTested == FALSE) {
  156. LogMessage(" * %s", (LPCSTR) l_pCCardProvider->m_CCardName);
  157. for (int i = 0; i < MAX_NUM_ATR && l_pCCardProvider->m_CAtr[i].GetLength(); i++) {
  158. LogMessage(" %s", l_pCCardProvider->m_CAtr[i].GetAtrString(l_rgbAtrBuffer));
  159. }
  160. }
  161. }
  162. delete l_rgbAtrBuffer;
  163. LogMessage("Please remove card");
  164. }
  165. void
  166. CCardProvider::ListUntestedCards(
  167. void
  168. )
  169. /*++
  170. Routine Description:
  171. Prints a list of all cards that have not been tested
  172. --*/
  173. {
  174. class CCardProvider *l_pCCardProvider = s_pFirst;
  175. while (l_pCCardProvider) {
  176. if (l_pCCardProvider->m_bCardTested == FALSE) {
  177. LogMessage(" * %s", (LPCSTR) l_pCCardProvider->m_CCardName);
  178. }
  179. l_pCCardProvider = l_pCCardProvider->m_pNext;
  180. }
  181. }
  182. void
  183. CCardProvider::SetAtr(
  184. BYTE in_rgbAtr[],
  185. ULONG in_uAtrLength
  186. )
  187. /*++
  188. Routine Description:
  189. Sets the ATR of the card
  190. Arguments:
  191. in_rgchAtr - the atr string
  192. in_uAtrLength - length of the atr
  193. --*/
  194. {
  195. for (int i = 0; i < MAX_NUM_ATR; i++) {
  196. if (m_CAtr[i].GetLength() == 0) {
  197. m_CAtr[i] = CAtr(in_rgbAtr, in_uAtrLength);
  198. return;
  199. }
  200. }
  201. }
  202. void
  203. CCardProvider::SetCardName(
  204. CHAR in_rgchCardName[]
  205. )
  206. /*++
  207. Routine Description:
  208. Sets a friendly name for the card
  209. Arguments:
  210. in_rgchCardName - Friendly name for the card
  211. --*/
  212. {
  213. m_CCardName = in_rgchCardName;
  214. }
  215. void
  216. CheckCardMonitor(
  217. CReader &in_CReader
  218. )
  219. {
  220. ULONG l_lResult, l_uReplyLength, l_lTestNo = 1;
  221. time_t l_lStartTime;
  222. BOOL l_bResult;
  223. OVERLAPPED l_Ovr;
  224. HANDLE l_hReader = in_CReader.GetHandle();
  225. l_Ovr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  226. ResetEvent(l_Ovr.hEvent);
  227. LogMessage("=============================");
  228. LogMessage("Part A: Checking card monitor");
  229. LogMessage("=============================");
  230. LogMessage(" << %s", REMOVE_CARD);
  231. in_CReader.WaitForCardRemoval();
  232. TestStart("%2d. %s", l_lTestNo++, INSERT_CARD);
  233. l_lResult = in_CReader.WaitForCardInsertion();
  234. TEST_CHECK_SUCCESS("Reader failed card insertion monitor", l_lResult);
  235. TestEnd();
  236. TestStart("%2d. IOCTL_SMARTCARD_IS_PRESENT", l_lTestNo++);
  237. l_bResult = DeviceIoControl (
  238. l_hReader,
  239. IOCTL_SMARTCARD_IS_PRESENT,
  240. NULL,
  241. 0,
  242. NULL,
  243. 0,
  244. &l_uReplyLength,
  245. &l_Ovr
  246. );
  247. TestCheck(
  248. l_bResult == TRUE,
  249. "DeviceIoControl should return TRUE with card inserted"
  250. );
  251. TestEnd();
  252. TestStart("%2d. %s", l_lTestNo++, REMOVE_CARD);
  253. l_lResult = in_CReader.WaitForCardRemoval();
  254. TEST_CHECK_SUCCESS("Reader failed card removal monitor", l_lResult);
  255. TestEnd();
  256. TestStart("%2d. IOCTL_SMARTCARD_IS_ABSENT", l_lTestNo++);
  257. l_bResult = DeviceIoControl (
  258. l_hReader,
  259. IOCTL_SMARTCARD_IS_ABSENT,
  260. NULL,
  261. 0,
  262. NULL,
  263. 0,
  264. &l_uReplyLength,
  265. &l_Ovr
  266. );
  267. TestCheck(
  268. l_bResult == TRUE,
  269. "DeviceIoControl should return TRUE with card removed"
  270. );
  271. TestEnd();
  272. TestStart("%2d. Insert and remove a smart card repeatedly", l_lTestNo++);
  273. for (l_lStartTime = time(NULL); time(NULL) - l_lStartTime < 15;) {
  274. l_lResult = in_CReader.ColdResetCard();
  275. #ifdef insert_remove_alternate
  276. l_bResult = DeviceIoControl (
  277. l_hReader,
  278. IOCTL_SMARTCARD_IS_PRESENT,
  279. NULL,
  280. 0,
  281. NULL,
  282. 0,
  283. &l_uReplyLength,
  284. &l_Ovr
  285. );
  286. SetLastError(0);
  287. l_bResult = GetOverlappedResult(
  288. l_hReader,
  289. &l_Ovr,
  290. &l_uReplyLength,
  291. FALSE
  292. );
  293. l_lResult = GetLastError();
  294. TestCheck(
  295. l_bResult == TRUE && l_lResult == ERROR_SUCCESS ||
  296. l_bResult == FALSE &&
  297. (l_lResult == ERROR_IO_INCOMPLETE ||
  298. l_lResult == ERROR_BUSY ||
  299. l_lResult == ERROR_IO_PENDING),
  300. "Reader failed card insertion monitor.\nReturned %2lxH",
  301. l_lResult
  302. );
  303. l_bResult = DeviceIoControl (
  304. l_hReader,
  305. IOCTL_SMARTCARD_IS_ABSENT,
  306. NULL,
  307. 0,
  308. NULL,
  309. 0,
  310. &l_uReplyLength,
  311. &l_Ovr
  312. );
  313. SetLastError(0);
  314. l_bResult = GetOverlappedResult(
  315. l_hReader,
  316. &l_Ovr,
  317. &l_uReplyLength,
  318. FALSE
  319. );
  320. l_lResult = GetLastError();
  321. TestCheck(
  322. l_bResult == TRUE && l_lResult == ERROR_SUCCESS ||
  323. l_bResult == FALSE &&
  324. (l_lResult == ERROR_IO_INCOMPLETE ||
  325. l_lResult == ERROR_BUSY ||
  326. l_lResult == ERROR_IO_PENDING),
  327. "Reader failed card removal monitor:\nReturned %2lxH",
  328. l_lResult
  329. );
  330. #endif
  331. }
  332. #ifdef insert_remove_alternate
  333. l_bResult = GetOverlappedResult(
  334. l_hReader,
  335. &l_Ovr,
  336. &l_uReplyLength,
  337. TRUE
  338. );
  339. #endif
  340. TestEnd();
  341. LogMessage("Press any key to continue");
  342. _getch();
  343. if (ReaderFailed()) {
  344. exit(-1);
  345. }
  346. }
  347. void
  348. CheckReader(
  349. CReader &in_CReader
  350. )
  351. /*++
  352. Routine Description:
  353. Checks the attributes of a reader.
  354. Once with card inserted and then without
  355. Arguments:
  356. Return Value:
  357. --*/
  358. {
  359. BOOL l_bResult;
  360. ULONG l_iIndex, l_uReplyLength, l_lTestNo = 1, l_uStart, l_uEnd;
  361. OVERLAPPED l_Ovr;
  362. UCHAR l_rgbReplyBuffer[512];
  363. HANDLE l_hReader = in_CReader.GetHandle();
  364. l_Ovr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  365. ResetEvent(l_Ovr.hEvent);
  366. #define ATTR(x) #x, x
  367. struct {
  368. PCHAR m_pchName;
  369. ULONG m_uType;
  370. } l_aAttr[] = {
  371. ATTR(SCARD_ATTR_VENDOR_NAME),
  372. ATTR(SCARD_ATTR_VENDOR_IFD_TYPE),
  373. ATTR(SCARD_ATTR_DEVICE_UNIT),
  374. ATTR(SCARD_ATTR_ATR_STRING),
  375. ATTR(SCARD_ATTR_DEFAULT_CLK),
  376. ATTR(SCARD_ATTR_MAX_CLK),
  377. ATTR(SCARD_ATTR_DEFAULT_DATA_RATE),
  378. ATTR(SCARD_ATTR_MAX_DATA_RATE),
  379. ATTR(SCARD_ATTR_MAX_IFSD),
  380. ATTR(SCARD_ATTR_CURRENT_PROTOCOL_TYPE),
  381. ATTR(SCARD_ATTR_PROTOCOL_TYPES),
  382. 0, 0,
  383. ATTR(SCARD_ATTR_ATR_STRING),
  384. ATTR(SCARD_ATTR_CURRENT_PROTOCOL_TYPE)
  385. };
  386. LogMessage("=======================");
  387. LogMessage("Part B: Checking reader");
  388. LogMessage("=======================");
  389. BOOL l_bCardInserted = FALSE;
  390. LogMessage(" << %s", REMOVE_CARD);
  391. in_CReader.WaitForCardRemoval();
  392. TestStart("%2d. Device name", l_lTestNo++);
  393. CString l_COperatingSystem = GetOperatingSystem();
  394. if (l_COperatingSystem == OS_WINNT4) {
  395. TestCheck(
  396. in_CReader.GetDeviceName().Left(12) == "\\\\.\\SCReader",
  397. "Device name is not NT 4.0 compliant"
  398. );
  399. } else if (l_COperatingSystem == OS_WIN95 ||
  400. l_COperatingSystem == OS_WIN98) {
  401. // there is no special naming convention for Win9x
  402. } else {
  403. TestCheck(
  404. in_CReader.GetDeviceName().Find("{50dd5230-ba8a-11d1-bf5d-0000f805f530}") != -1,
  405. "Device name is not WDM PnP compliant"
  406. );
  407. }
  408. TestEnd();
  409. TestStart(
  410. "%2d. Null pointer check",
  411. l_lTestNo++
  412. );
  413. for (l_iIndex = 0; l_aAttr[l_iIndex].m_pchName; l_iIndex++) {
  414. // try to crash reader by using null pointers as arguments
  415. l_bResult = DeviceIoControl (
  416. l_hReader,
  417. IOCTL_SMARTCARD_GET_ATTRIBUTE,
  418. &l_aAttr[l_iIndex].m_uType,
  419. sizeof(ULONG),
  420. NULL,
  421. 1000,
  422. &l_uReplyLength,
  423. &l_Ovr
  424. );
  425. ULONG l_lResult = GetLastError();
  426. TestCheck(
  427. l_lResult == ERROR_INSUFFICIENT_BUFFER ||
  428. l_lResult == ERROR_BAD_COMMAND,
  429. "IOCTL_SMARTCARD_GET_ATTRIBUTE (%lxh) should fail\nReturned %2lxH (NTSTATUS %lxH)\nExpected %2lxH (NTSTATUS %lxH)\nor %2lxH (NTSTATUS %lxH)",
  430. l_aAttr[l_iIndex].m_uType & 0xFFFF,
  431. l_lResult,
  432. MapWinErrorToNtStatus(l_lResult),
  433. ERROR_INSUFFICIENT_BUFFER,
  434. MapWinErrorToNtStatus(ERROR_BAD_COMMAND),
  435. ERROR_BAD_COMMAND,
  436. MapWinErrorToNtStatus(ERROR_BAD_COMMAND)
  437. );
  438. }
  439. TestEnd();
  440. for (l_iIndex = 0; l_iIndex < sizeof(l_aAttr) / sizeof(l_aAttr[0]); l_iIndex++) {
  441. if (l_aAttr[l_iIndex].m_pchName == 0) {
  442. TestStart("%2d. Close driver with I/O-request still pending", l_lTestNo++);
  443. // Check if the reader correctly terminates pending io-requests
  444. l_bResult = DeviceIoControl (
  445. l_hReader,
  446. IOCTL_SMARTCARD_IS_PRESENT,
  447. NULL,
  448. 0,
  449. NULL,
  450. 0,
  451. &l_uReplyLength,
  452. &l_Ovr
  453. );
  454. TestCheck(
  455. l_bResult == FALSE,
  456. "Wait for present succeeded with no card inserted"
  457. );
  458. // With the pending i/o request close and re-open the driver
  459. in_CReader.Close();
  460. l_bResult = in_CReader.Open();
  461. TestCheck(
  462. l_bResult,
  463. "Reader failed to terminate pending i/o request"
  464. );
  465. TestEnd();
  466. if (TestFailed()) {
  467. // If the open failed we can't contiue
  468. exit(GetLastError());
  469. }
  470. l_hReader = in_CReader.GetHandle();
  471. LogMessage(" >> Please insert 'IBM PC/SC Compliance Test Card'");
  472. in_CReader.WaitForCardInsertion();
  473. l_bCardInserted = TRUE;
  474. // Cold reset
  475. TestStart("%2d. Cold reset", l_lTestNo++);
  476. l_uStart = clock();
  477. LONG l_lResult = in_CReader.ColdResetCard();
  478. l_uEnd = clock();
  479. TEST_CHECK_SUCCESS("Cold reset failed", l_lResult);
  480. TestCheck(
  481. (l_uEnd - l_uStart) / CLOCKS_PER_SEC <= 2,
  482. "Cold reset took too long.\nElapsed time %ld sec\nExpected time %ld sec",
  483. (l_uEnd - l_uStart) / CLOCKS_PER_SEC,
  484. 2
  485. );
  486. TestEnd();
  487. if (TestFailed()) {
  488. exit(l_lResult);
  489. }
  490. // Set protocol
  491. TestStart("%2d. Set protocol to T0 | T1", l_lTestNo++);
  492. l_lResult = in_CReader.SetProtocol(
  493. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1
  494. );
  495. TEST_CHECK_SUCCESS("Set protocol failed", l_lResult);
  496. TestEnd();
  497. continue;
  498. }
  499. TestStart("%2d. %s", l_lTestNo++, l_aAttr[l_iIndex].m_pchName);
  500. SetLastError(0);
  501. *(PULONG) l_rgbReplyBuffer = 0;
  502. l_bResult = DeviceIoControl (
  503. l_hReader,
  504. IOCTL_SMARTCARD_GET_ATTRIBUTE,
  505. &l_aAttr[l_iIndex].m_uType,
  506. sizeof(ULONG),
  507. l_rgbReplyBuffer,
  508. sizeof(l_rgbReplyBuffer),
  509. &l_uReplyLength,
  510. &l_Ovr
  511. );
  512. if (l_bResult == FALSE && GetLastError() == ERROR_IO_PENDING) {
  513. //
  514. // The I/O request returned pending, so
  515. // wait until the request is finished
  516. //
  517. SetLastError(0);
  518. l_bResult = GetOverlappedResult(
  519. l_hReader,
  520. &l_Ovr,
  521. &l_uReplyLength,
  522. TRUE
  523. );
  524. }
  525. if (GetLastError() != ERROR_SUCCESS) {
  526. l_bResult = FALSE;
  527. } else {
  528. l_rgbReplyBuffer[l_uReplyLength] = 0;
  529. }
  530. LONG l_lResult = GetLastError();
  531. switch (l_aAttr[l_iIndex].m_uType) {
  532. case SCARD_ATTR_VENDOR_NAME:
  533. TEST_CHECK_SUCCESS(
  534. "Ioctl SCARD_ATTR_VENDOR_NAME failed",
  535. l_lResult
  536. );
  537. TestCheck(
  538. strlen((PCHAR) l_rgbReplyBuffer) != 0,
  539. "No vendor name defined"
  540. );
  541. TestEnd();
  542. break;
  543. case SCARD_ATTR_VENDOR_IFD_TYPE:
  544. TEST_CHECK_SUCCESS(
  545. "Ioctl SCARD_ATTR_VENDOR_IFD_TYPE failed",
  546. l_lResult
  547. );
  548. TestCheck(
  549. strlen((PCHAR) l_rgbReplyBuffer) != 0,
  550. "No ifd type defined"
  551. );
  552. TestEnd();
  553. break;
  554. case SCARD_ATTR_DEVICE_UNIT:
  555. TEST_CHECK_SUCCESS(
  556. "Ioctl SCARD_ATTR_DEVICE_UNIT failed",
  557. l_lResult
  558. );
  559. TestCheck(
  560. *(PULONG) l_rgbReplyBuffer < 4,
  561. "Invalid value: %ld (0 - 3)",
  562. *(PULONG) l_rgbReplyBuffer
  563. );
  564. TestEnd();
  565. break;
  566. case SCARD_ATTR_ATR_STRING:
  567. if (l_bCardInserted) {
  568. TEST_CHECK_SUCCESS(
  569. "Ioctl SCARD_ATTR_ATR_STRING failed",
  570. l_lResult
  571. );
  572. } else {
  573. TestCheck(
  574. l_bResult == FALSE,
  575. "Reader returned ATR with no card inserted"
  576. );
  577. }
  578. TestEnd();
  579. break;
  580. case SCARD_ATTR_DEFAULT_CLK:
  581. case SCARD_ATTR_MAX_CLK:
  582. TEST_CHECK_SUCCESS(
  583. "Ioctl SCARD_ATTR_DEFAULT_CLK/SCARD_ATTR_MAX_CLK failed",
  584. l_lResult
  585. );
  586. TestCheck(
  587. *(PULONG) l_rgbReplyBuffer >= 1000 && *(PULONG) l_rgbReplyBuffer <= 20000,
  588. "Invalid value %ld (1000 - 20000)",
  589. *(PULONG) l_rgbReplyBuffer
  590. );
  591. TestEnd();
  592. break;
  593. case SCARD_ATTR_DEFAULT_DATA_RATE:
  594. case SCARD_ATTR_MAX_DATA_RATE:
  595. TEST_CHECK_SUCCESS(
  596. "Ioctl SCARD_ATTR_DEFAULT_DATA_RATE/SCARD_ATTR_MAX_DATA_RATE failed",
  597. l_lResult
  598. );
  599. TestEnd();
  600. break;
  601. case SCARD_ATTR_MAX_IFSD:
  602. TEST_CHECK_SUCCESS(
  603. "Ioctl SCARD_ATTR_MAX_IFSD failed",
  604. l_lResult
  605. );
  606. TestCheck(
  607. *(PULONG) l_rgbReplyBuffer >= 1 && *(PULONG) l_rgbReplyBuffer <= 254,
  608. "Invalid value: %ld (1 - 254)",
  609. *(PULONG) l_rgbReplyBuffer
  610. );
  611. TestEnd();
  612. break;
  613. case SCARD_ATTR_PROTOCOL_TYPES:
  614. TEST_CHECK_SUCCESS(
  615. "Ioctl SCARD_ATTR_PROTOCOL_TYPES failed",
  616. l_lResult
  617. );
  618. // check if the reader at least supports T=0 and T=1
  619. TestCheck(
  620. (*(PULONG) l_rgbReplyBuffer & SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) ==
  621. (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1),
  622. "Reader must support T=0 and T=1"
  623. );
  624. TestEnd();
  625. break;
  626. case SCARD_ATTR_CURRENT_PROTOCOL_TYPE:
  627. if (l_bCardInserted) {
  628. TEST_CHECK_SUCCESS(
  629. "Ioctl SCARD_ATTR_CURRENT_PROTOCOL_TYPE failed",
  630. l_lResult
  631. );
  632. TestCheck(
  633. *(PULONG) l_rgbReplyBuffer != 0,
  634. "Reader returned no protocol"
  635. );
  636. } else {
  637. // Check that without a card the current protocol is set to 0
  638. TestCheck(
  639. l_bResult == FALSE,
  640. "Ioctl SCARD_ATTR_CURRENT_PROTOCOL_TYPE failed should fail with no card inserted"
  641. );
  642. }
  643. TestEnd();
  644. break;
  645. default:
  646. TestCheck(
  647. l_bResult,
  648. "Ioctl returned %lxh",
  649. GetLastError()
  650. );
  651. TestEnd();
  652. break;
  653. }
  654. }
  655. LogMessage(" << %s", REMOVE_CARD);
  656. in_CReader.WaitForCardRemoval();
  657. LogMessage(" << Please insert smart card BACKWARDS");
  658. in_CReader.WaitForCardInsertion();
  659. TestStart("%2d. IOCTL_SMARTCARD_GET_STATE", l_lTestNo++);
  660. ULONG l_uState;
  661. l_bResult = DeviceIoControl (
  662. l_hReader,
  663. IOCTL_SMARTCARD_GET_STATE,
  664. NULL,
  665. 0,
  666. &l_uState,
  667. sizeof(l_uState),
  668. &l_uReplyLength,
  669. &l_Ovr
  670. );
  671. LONG l_lResult = GetLastError();
  672. TestCheck(
  673. l_bResult,
  674. "IOCTL_SMARTCARD_GET_STATE failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)",
  675. l_lResult,
  676. MapWinErrorToNtStatus(l_lResult),
  677. ERROR_SUCCESS,
  678. MapWinErrorToNtStatus(ERROR_SUCCESS)
  679. );
  680. TestCheck(
  681. l_uState <= SCARD_SWALLOWED,
  682. "Invalid reader state.\nReturned %d\nExpected <= %d",
  683. l_uState,
  684. SCARD_SWALLOWED
  685. );
  686. TestEnd();
  687. TestStart("%2d. Cold reset", l_lTestNo++);
  688. l_uStart = clock();
  689. l_lResult = in_CReader.ColdResetCard();
  690. l_uEnd = clock();
  691. TestCheck(
  692. l_lResult == ERROR_UNRECOGNIZED_MEDIA,
  693. "Cold reset failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)",
  694. l_lResult,
  695. MapWinErrorToNtStatus(l_lResult),
  696. ERROR_UNRECOGNIZED_MEDIA,
  697. MapWinErrorToNtStatus(ERROR_UNRECOGNIZED_MEDIA)
  698. );
  699. TestCheck(
  700. (l_uEnd - l_uStart) / CLOCKS_PER_SEC <= 2,
  701. "Cold reset took too long.\nElapsed time %ld sec\nExpected time %ld sec",
  702. (l_uEnd - l_uStart) / CLOCKS_PER_SEC,
  703. 2
  704. );
  705. TestEnd();
  706. }
  707. void
  708. SimulateResMngr(
  709. CReader &in_CReader
  710. )
  711. {
  712. BOOL l_bWaitForPresent = FALSE, l_bWaitForAbsent = FALSE, l_bResult;
  713. BOOL l_bMustWait = FALSE, l_bPoweredDown = FALSE;
  714. ULONG l_uState, l_uStatus, l_uReplyLength, l_uStateExpected = SCARD_ABSENT, l_lTestNo = 1;
  715. ULONG l_uMinorIoctl;
  716. OVERLAPPED l_Ovr, l_OvrWait;
  717. HANDLE l_hReader = in_CReader.GetHandle();
  718. l_Ovr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  719. ResetEvent(l_Ovr.hEvent);
  720. l_OvrWait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  721. ResetEvent(l_OvrWait.hEvent);
  722. LogMessage("===================================");
  723. LogMessage("Part C: Resource Manager Simulation");
  724. LogMessage("===================================");
  725. LogMessage(" << %s", REMOVE_CARD);
  726. in_CReader.WaitForCardRemoval();
  727. while (TRUE) {
  728. TestStart("%2d. IOCTL_SMARTCARD_GET_STATE", l_lTestNo++);
  729. l_bResult = DeviceIoControl (
  730. l_hReader,
  731. IOCTL_SMARTCARD_GET_STATE,
  732. NULL,
  733. 0,
  734. &l_uState,
  735. sizeof(l_uState),
  736. &l_uReplyLength,
  737. &l_Ovr
  738. );
  739. LONG l_lResult = GetLastError();
  740. TestCheck(
  741. l_bResult,
  742. "IOCTL_SMARTCARD_GET_STATE failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)",
  743. l_lResult,
  744. MapWinErrorToNtStatus(l_lResult),
  745. ERROR_SUCCESS,
  746. MapWinErrorToNtStatus(ERROR_SUCCESS)
  747. );
  748. TestEnd();
  749. if (l_bWaitForPresent) {
  750. TestStart("%2d. %s", l_lTestNo++, INSERT_CARD);
  751. l_bResult = GetOverlappedResult(
  752. l_hReader,
  753. &l_OvrWait,
  754. &l_uReplyLength,
  755. TRUE
  756. );
  757. l_lResult = GetLastError();
  758. TestCheck(
  759. l_bResult,
  760. "Card insertion monitor failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)",
  761. l_lResult,
  762. MapWinErrorToNtStatus(l_lResult),
  763. ERROR_SUCCESS,
  764. MapWinErrorToNtStatus(ERROR_SUCCESS)
  765. );
  766. l_lResult = GetLastError();
  767. TestEnd();
  768. l_bWaitForPresent = FALSE;
  769. continue;
  770. }
  771. if (l_bWaitForAbsent) {
  772. if (l_bMustWait) {
  773. TestStart("%2d. %s", l_lTestNo++, REMOVE_CARD);
  774. } else {
  775. TestStart("%2d. GetOverlappedResult", l_lTestNo++);
  776. }
  777. l_bResult = GetOverlappedResult(
  778. l_hReader,
  779. &l_OvrWait,
  780. &l_uReplyLength,
  781. l_bMustWait
  782. );
  783. if (l_bMustWait == FALSE) {
  784. TestCheck(
  785. l_bResult == FALSE,
  786. "Smart card not removed"
  787. );
  788. TestEnd();
  789. if (TestFailed()) {
  790. return;
  791. }
  792. } else {
  793. l_lResult = GetLastError();
  794. TestCheck(
  795. l_bResult,
  796. "Card removal monitor failed.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)",
  797. l_lResult,
  798. MapWinErrorToNtStatus(l_lResult),
  799. ERROR_SUCCESS,
  800. MapWinErrorToNtStatus(ERROR_SUCCESS)
  801. );
  802. TestEnd();
  803. if (TestFailed()) {
  804. return;
  805. }
  806. l_bWaitForAbsent = FALSE;
  807. continue;
  808. }
  809. }
  810. TestStart("%2d. Checking reader status", l_lTestNo++);
  811. switch (l_uState) {
  812. case SCARD_UNKNOWN:
  813. TestCheck(FALSE, "Reader returned illegal state SCARD_UNKNOWN");
  814. TestEnd();
  815. return;
  816. case SCARD_ABSENT:
  817. TestCheck(
  818. l_uStateExpected == SCARD_ABSENT,
  819. "Invalid reader state.\nCurrent state = %d\nExpected state = %d",
  820. l_uState,
  821. l_uStateExpected
  822. );
  823. TestEnd();
  824. if (TestFailed()) {
  825. return;
  826. }
  827. if (l_bMustWait) {
  828. return;
  829. }
  830. TestStart("%2d. IOCTL_SMARTCARD_IS_PRESENT", l_lTestNo++);
  831. l_bResult = DeviceIoControl (
  832. l_hReader,
  833. IOCTL_SMARTCARD_IS_PRESENT,
  834. NULL,
  835. 0,
  836. NULL,
  837. 0,
  838. &l_uReplyLength,
  839. &l_OvrWait
  840. );
  841. TestCheck(
  842. GetLastError() == ERROR_IO_PENDING,
  843. "Monitor is supposed to return ERROR_IO_PENDING (%lxh)",
  844. GetLastError()
  845. );
  846. TestEnd();
  847. if (TestFailed()) {
  848. return;
  849. }
  850. l_bWaitForPresent = TRUE;
  851. l_uStateExpected = SCARD_PRESENT;
  852. break;
  853. case SCARD_PRESENT:
  854. case SCARD_SWALLOWED:
  855. case SCARD_POWERED:
  856. if (l_bPoweredDown) {
  857. TestCheck(
  858. l_uStateExpected <= SCARD_POWERED,
  859. "Invalid reader state.\nCurrent state = %d\nExpected state <= %d",
  860. l_uState,
  861. l_uStateExpected
  862. );
  863. TestEnd();
  864. if (TestFailed()) {
  865. return;
  866. }
  867. l_bMustWait = TRUE;
  868. l_uStateExpected = SCARD_ABSENT;
  869. break;
  870. }
  871. TestCheck(
  872. l_uStateExpected > SCARD_ABSENT,
  873. "Invalid reader state.\nCurrent state = %d\nExpected state <= %d",
  874. l_uState,
  875. l_uStateExpected
  876. );
  877. TestEnd();
  878. if (TestFailed()) {
  879. return;
  880. }
  881. TestStart("%2d. IOCTL_SMARTCARD_IS_ABSENT", l_lTestNo++);
  882. l_bResult = DeviceIoControl (
  883. l_hReader,
  884. IOCTL_SMARTCARD_IS_ABSENT,
  885. NULL,
  886. 0,
  887. NULL,
  888. 0,
  889. &l_uReplyLength,
  890. &l_OvrWait
  891. );
  892. l_lResult = GetLastError();
  893. TestCheck(
  894. l_bResult == FALSE,
  895. "IOCTL_SMARTCARD_IS_ABSENT should fail.\nReturned %8lxH (NTSTATUS %8lxH).\nExpected %8lxH (NTSTATUS %8lxH)",
  896. l_lResult,
  897. MapWinErrorToNtStatus(l_lResult),
  898. ERROR_IO_PENDING,
  899. MapWinErrorToNtStatus(ERROR_IO_PENDING)
  900. );
  901. TestEnd();
  902. l_bWaitForAbsent = TRUE;
  903. TestStart("%2d. Cold reset card", l_lTestNo++);
  904. l_uStatus = in_CReader.ColdResetCard();
  905. TEST_CHECK_SUCCESS("ColdReset", l_uStatus)
  906. l_uStateExpected = SCARD_NEGOTIABLE;
  907. TestEnd();
  908. if (TestFailed()) {
  909. return;
  910. }
  911. break;
  912. case SCARD_NEGOTIABLE:
  913. TestCheck(
  914. l_bPoweredDown == FALSE,
  915. "Invalid reader state.\nCurrent state = %d\nExpected state = %d",
  916. l_uState,
  917. SCARD_PRESENT
  918. );
  919. TestCheck(
  920. l_uStateExpected > SCARD_ABSENT,
  921. "Invalid reader state.\nCurrent state = %d\nExpected state <= %d",
  922. l_uState,
  923. l_uStateExpected
  924. );
  925. TestEnd();
  926. if (TestFailed()) {
  927. return;
  928. }
  929. TestStart("%2d. Set protocol to T0 | T1", l_lTestNo++);
  930. l_uStatus = in_CReader.SetProtocol(
  931. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1
  932. );
  933. TestCheck(
  934. l_uStatus == ERROR_SUCCESS,
  935. "Protocol selection failed with error %lxh",
  936. GetLastError()
  937. );
  938. TestEnd();
  939. if (TestFailed()) {
  940. return;
  941. }
  942. l_uStateExpected = SCARD_SPECIFIC;
  943. break;
  944. case SCARD_SPECIFIC:
  945. TestCheck(
  946. l_bPoweredDown == FALSE,
  947. "Invalid reader state.\nCurrent state = %d\nExpected state = %d",
  948. l_uState,
  949. SCARD_PRESENT
  950. );
  951. TestCheck(
  952. l_uStateExpected > SCARD_ABSENT,
  953. "Invalid reader state.\nReturned %d\nExpected < %d",
  954. l_uState,
  955. l_uStateExpected
  956. );
  957. TestEnd();
  958. if (TestFailed()) {
  959. return;
  960. }
  961. TestStart("%2d. IOCTL_SMARTCARD_POWER (SCARD_POWER_DOWN)", l_lTestNo++);
  962. l_uMinorIoctl = SCARD_POWER_DOWN;
  963. SetLastError(0);
  964. l_bResult = DeviceIoControl (
  965. l_hReader,
  966. IOCTL_SMARTCARD_POWER,
  967. &l_uMinorIoctl,
  968. sizeof(l_uMinorIoctl),
  969. NULL,
  970. 0,
  971. &l_uReplyLength,
  972. &l_Ovr
  973. );
  974. if (l_bResult == FALSE && GetLastError() == ERROR_IO_PENDING) {
  975. SetLastError(0);
  976. l_bResult = GetOverlappedResult(
  977. l_hReader,
  978. &l_Ovr,
  979. &l_uReplyLength,
  980. TRUE
  981. );
  982. }
  983. l_lResult = GetLastError();
  984. TEST_CHECK_SUCCESS("IOCTL_SMARTCARD_POWER failed", l_lResult);
  985. TestEnd();
  986. l_uStateExpected = SCARD_PRESENT;
  987. l_bPoweredDown = TRUE;
  988. break;
  989. default:
  990. TestCheck(
  991. FALSE,
  992. "Reader returned invalid state %d",
  993. l_uState
  994. );
  995. TestEnd();
  996. return;
  997. }
  998. }
  999. }
  1000. void
  1001. PowerManagementTest(
  1002. CReader &in_CReader,
  1003. ULONG in_uWaitTime
  1004. )
  1005. {
  1006. LONG l_lResult;
  1007. ULONG l_uState, l_uPrevState, l_uRepeat;
  1008. ULONG l_uDuration = 30;
  1009. if (in_uWaitTime > 30 && in_uWaitTime < 120) {
  1010. l_uDuration = in_uWaitTime;
  1011. }
  1012. LogMessage("=============================");
  1013. LogMessage("Part E: Power Management Test");
  1014. LogMessage("=============================");
  1015. LogMessage("Note: Each test cycle takes %ld seconds!", l_uDuration);
  1016. LogMessage(" << %s", REMOVE_CARD);
  1017. in_CReader.WaitForCardRemoval();
  1018. LogMessage("Test 1: DO NOT INSERT smart card during hibernate mode");
  1019. TestStart("Card out / card out - Hibernate now");
  1020. l_lResult = in_CReader.StartWaitForCardInsertion();
  1021. l_lResult = in_CReader.GetState(&l_uPrevState);
  1022. for (l_uRepeat = 0; l_uRepeat < l_uDuration; l_uRepeat++) {
  1023. l_lResult = in_CReader.GetState(&l_uState);
  1024. LONG l_uGoal = clock() + CLOCKS_PER_SEC;
  1025. while(l_uGoal > clock())
  1026. ;
  1027. printf("\x08\x08%2ld", l_uDuration - l_uRepeat);
  1028. }
  1029. printf("\x08\x08 ");
  1030. l_lResult = in_CReader.FinishWaitForCard(FALSE);
  1031. TestCheck(
  1032. l_lResult == ERROR_IO_INCOMPLETE,
  1033. "GetOverlappedResult failed\nReturned %8lx\nExpected %8lx",
  1034. l_lResult,
  1035. ERROR_IO_INCOMPLETE
  1036. );
  1037. TestEnd();
  1038. TestStart("%s", INSERT_CARD);
  1039. l_lResult = in_CReader.FinishWaitForCard(TRUE);
  1040. TEST_CHECK_SUCCESS("Reader failed card insertion", l_lResult);
  1041. TestEnd();
  1042. TestStart("Checking reader status");
  1043. l_lResult = in_CReader.GetState(&l_uState);
  1044. TEST_CHECK_SUCCESS("Reader failed IOCTL_SMARTCARD_GET_STATE", l_lResult);
  1045. TestCheck(
  1046. l_uState > SCARD_ABSENT,
  1047. "Invalid reader state.\nReturned %d\nExpected > %d",
  1048. l_uState,
  1049. SCARD_ABSENT
  1050. );
  1051. TestEnd();
  1052. //
  1053. // Test 2
  1054. //
  1055. LogMessage("Test 2: REMOVE smart card DURING hibernate mode");
  1056. TestStart("Card in / card out - Hibernate now");
  1057. l_lResult = in_CReader.StartWaitForCardRemoval();
  1058. l_lResult = in_CReader.GetState(&l_uPrevState);
  1059. for (l_uRepeat = 0; l_uRepeat < l_uDuration; l_uRepeat++) {
  1060. l_lResult = in_CReader.GetState(&l_uState);
  1061. LONG l_uGoal = clock() + CLOCKS_PER_SEC;
  1062. while(l_uGoal > clock())
  1063. ;
  1064. printf("\x08\x08%2ld", l_uDuration - l_uRepeat);
  1065. }
  1066. printf("\x08\x08 ");
  1067. l_lResult = in_CReader.FinishWaitForCard(FALSE);
  1068. TEST_CHECK_SUCCESS(
  1069. "GetOverlappedResult failed",
  1070. l_lResult
  1071. );
  1072. TestEnd();
  1073. TestStart("Checking reader status");
  1074. l_lResult = in_CReader.GetState(&l_uState);
  1075. TEST_CHECK_SUCCESS("Reader failed IOCTL_SMARTCARD_GET_STATE", l_lResult);
  1076. TestCheck(
  1077. l_uState == SCARD_ABSENT,
  1078. "Invalid reader state.\nReturned %d\nExpected %d",
  1079. l_uState,
  1080. SCARD_ABSENT
  1081. );
  1082. TestEnd();
  1083. LogMessage(" >> %s", INSERT_CARD);
  1084. in_CReader.WaitForCardInsertion();
  1085. //
  1086. // Test 3
  1087. //
  1088. LogMessage("Test 3: DO NOT REMOVE smart card during hibernate mode");
  1089. TestStart("Card in / card in - Hibernate now");
  1090. l_lResult = in_CReader.StartWaitForCardRemoval();
  1091. l_lResult = in_CReader.GetState(&l_uPrevState);
  1092. for (l_uRepeat = 0; l_uRepeat < l_uDuration; l_uRepeat++) {
  1093. l_lResult = in_CReader.GetState(&l_uState);
  1094. LONG l_uGoal = clock() + CLOCKS_PER_SEC;
  1095. while(l_uGoal > clock())
  1096. ;
  1097. printf("\x08\x08%2ld", l_uDuration - l_uRepeat);
  1098. }
  1099. printf("\x08\x08 ");
  1100. l_lResult = in_CReader.FinishWaitForCard(FALSE);
  1101. TEST_CHECK_SUCCESS(
  1102. "GetOverlappedResult failed",
  1103. l_lResult
  1104. );
  1105. TestEnd();
  1106. TestStart("Checking reader status");
  1107. l_lResult = in_CReader.GetState(&l_uState);
  1108. TEST_CHECK_SUCCESS("Reader failed IOCTL_SMARTCARD_GET_STATE", l_lResult);
  1109. TestCheck(
  1110. l_uState >= SCARD_PRESENT,
  1111. "Invalid reader state.\nReturned %d\nExpected > %d",
  1112. l_uState,
  1113. SCARD_ABSENT
  1114. );
  1115. TestEnd();
  1116. LogMessage(" << %s", REMOVE_CARD);
  1117. in_CReader.WaitForCardRemoval();
  1118. //
  1119. // Test 4
  1120. //
  1121. LogMessage("Test 4: INSERT smart card DURING hibernate mode");
  1122. TestStart("Card out / card in - Hibernate now");
  1123. l_lResult = in_CReader.StartWaitForCardInsertion();
  1124. l_lResult = in_CReader.GetState(&l_uPrevState);
  1125. for (l_uRepeat = 0; l_uRepeat < l_uDuration; l_uRepeat++) {
  1126. l_lResult = in_CReader.GetState(&l_uState);
  1127. LONG l_uGoal = clock() + CLOCKS_PER_SEC;
  1128. while(l_uGoal > clock())
  1129. ;
  1130. printf("\x08\x08%2ld", l_uDuration - l_uRepeat);
  1131. }
  1132. printf("\x08\x08 ");
  1133. l_lResult = in_CReader.FinishWaitForCard(FALSE);
  1134. TEST_CHECK_SUCCESS(
  1135. "GetOverlappedResult failed",
  1136. l_lResult
  1137. );
  1138. TestEnd();
  1139. TestStart("Checking reader status");
  1140. l_lResult = in_CReader.GetState(&l_uState);
  1141. TEST_CHECK_SUCCESS("Reader failed IOCTL_SMARTCARD_GET_STATE", l_lResult);
  1142. TestCheck(
  1143. l_uState >= SCARD_PRESENT,
  1144. "Invalid reader state.\nReturned %d\nExpected > %d",
  1145. l_uState,
  1146. SCARD_ABSENT
  1147. );
  1148. TestEnd();
  1149. }
  1150. class CArgv {
  1151. int m_iArgc;
  1152. char **m_pArgv;
  1153. BOOL *m_pfRef;
  1154. public:
  1155. CArgv(int in_iArgc, char **in_pArgv);
  1156. int OptionExist(PCHAR);
  1157. PCHAR ParameterExist(PCHAR);
  1158. PCHAR CheckParameters(CString);
  1159. PCHAR CArgv::ParameterUnused(void);
  1160. };
  1161. CArgv::CArgv(
  1162. int in_iArgc,
  1163. char **in_pArgv
  1164. )
  1165. {
  1166. m_iArgc = in_iArgc;
  1167. m_pArgv = in_pArgv;
  1168. m_pfRef = new BOOL[in_iArgc];
  1169. memset(m_pfRef, 0, sizeof(BOOL) * in_iArgc);
  1170. }
  1171. CArgv::OptionExist(
  1172. PCHAR in_pchParameter
  1173. )
  1174. {
  1175. for (int i = 0; i < m_iArgc; i++) {
  1176. if (m_pArgv[i][0] == '-' || m_pArgv[i][0] == '/') {
  1177. int j = 1;
  1178. while (m_pArgv[i][j] && m_pArgv[i][j] != ' ') {
  1179. if (strncmp(m_pArgv[i] + j, in_pchParameter, strlen(m_pArgv[i] + j)) == 0) {
  1180. m_pfRef[i] = TRUE;
  1181. return i;
  1182. }
  1183. j++;
  1184. }
  1185. }
  1186. }
  1187. return 0;
  1188. }
  1189. PCHAR
  1190. CArgv::ParameterExist(
  1191. PCHAR in_pchParameter
  1192. )
  1193. {
  1194. if (int i = OptionExist(in_pchParameter)) {
  1195. m_pfRef[i + 1] = TRUE;
  1196. return m_pArgv[i + 1];
  1197. }
  1198. return NULL;
  1199. }
  1200. PCHAR
  1201. CArgv::CheckParameters(
  1202. CString in_CParameters
  1203. )
  1204. /*++
  1205. Routine Description:
  1206. Checks if the command line includes in invalid/unknown parameter
  1207. --*/
  1208. {
  1209. int i, l_iPos;
  1210. for (i = 1; i < m_iArgc; i++) {
  1211. if ((l_iPos = in_CParameters.Find(m_pArgv[i])) == -1) {
  1212. return m_pArgv[i];
  1213. }
  1214. if (l_iPos + 3 < in_CParameters.GetLength() &&
  1215. in_CParameters[l_iPos + 3] == '*') {
  1216. // skip the next parameter
  1217. i += 1;
  1218. }
  1219. }
  1220. return NULL;
  1221. }
  1222. PCHAR
  1223. CArgv::ParameterUnused(
  1224. void
  1225. )
  1226. {
  1227. int i;
  1228. for (i = 1; i < m_iArgc; i++) {
  1229. if (m_pfRef[i] == FALSE) {
  1230. return m_pArgv[i];
  1231. }
  1232. }
  1233. return NULL;
  1234. }
  1235. CString &
  1236. GetOperatingSystem(
  1237. void
  1238. )
  1239. {
  1240. static CString l_COperatingSystem;
  1241. OSVERSIONINFO VersionInformation;
  1242. if (l_COperatingSystem.GetLength() == 0) {
  1243. VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1244. if (GetVersionEx(&VersionInformation) == FALSE) {
  1245. l_COperatingSystem += "Unknown";
  1246. } else {
  1247. if (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
  1248. if (VersionInformation.dwMinorVersion == 0) {
  1249. l_COperatingSystem += OS_WIN95;
  1250. } else {
  1251. l_COperatingSystem += OS_WIN98;
  1252. }
  1253. } else if (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT) {
  1254. if (VersionInformation.dwMajorVersion <= 4) {
  1255. l_COperatingSystem += OS_WINNT4;
  1256. } else {
  1257. l_COperatingSystem += OS_WINNT5;
  1258. }
  1259. } else {
  1260. l_COperatingSystem += "Unknown";
  1261. }
  1262. }
  1263. }
  1264. return l_COperatingSystem;
  1265. }
  1266. CString &
  1267. SelectReader(
  1268. void
  1269. )
  1270. {
  1271. CReaderList l_CReaderList;
  1272. ULONG l_uIndex, l_uReader;
  1273. ULONG l_uNumReaders = l_CReaderList.GetNumReaders();
  1274. static CString l_CEmpty("");
  1275. if (l_uNumReaders == 0) {
  1276. return l_CEmpty;
  1277. }
  1278. if (l_uNumReaders == 1) {
  1279. return l_CReaderList.GetDeviceName(0);
  1280. }
  1281. CString l_CLetter;
  1282. printf("\n");
  1283. printf(" Vendor IfdType Type\n");
  1284. printf(" -----------------------------------------------------\n");
  1285. for (l_uIndex = 0; l_uIndex < l_uNumReaders; l_uIndex++) {
  1286. INT l_iLetterPos;
  1287. INT l_iLength = l_CReaderList.GetVendorName(l_uIndex).GetLength();
  1288. CString l_CVendorName = l_CReaderList.GetVendorName(l_uIndex);
  1289. for (l_iLetterPos = 0;
  1290. l_iLetterPos < l_CVendorName.GetLength();
  1291. l_iLetterPos++) {
  1292. CHAR l_chLetter = l_CVendorName[l_iLetterPos];
  1293. if (l_chLetter == ' ' || l_chLetter == 'x') {
  1294. continue;
  1295. }
  1296. if (l_CLetter.Find(l_chLetter) == -1) {
  1297. l_CLetter += l_chLetter;
  1298. break;
  1299. }
  1300. }
  1301. if (l_iLetterPos >= l_iLength) {
  1302. l_CVendorName += (CHAR) (l_uIndex + '0') ;
  1303. l_iLetterPos = l_iLength;
  1304. }
  1305. printf(
  1306. " %s[%c]%-*s %-20s %8s\n",
  1307. (LPCSTR) l_CVendorName.Left(l_iLetterPos),
  1308. l_CVendorName[l_iLetterPos],
  1309. 20 - l_iLetterPos,
  1310. l_CVendorName.Right(l_iLength - l_iLetterPos - 1),
  1311. (LPCSTR) l_CReaderList.GetIfdType(l_uIndex),
  1312. (LPCSTR) l_CReaderList.GetPnPType(l_uIndex)
  1313. );
  1314. }
  1315. putchar('\n');
  1316. do {
  1317. printf("\rSelect reader: \010");
  1318. CHAR l_chInput = (CHAR) _getche();
  1319. if (l_chInput == 3) {
  1320. exit(-1);
  1321. }
  1322. l_uReader = l_CLetter.Find(l_chInput);
  1323. } while(l_uReader == -1);
  1324. printf("\n");
  1325. return l_CReaderList.GetDeviceName(l_uReader);
  1326. }
  1327. CString
  1328. SelectReader(
  1329. CString &in_CVendorName
  1330. )
  1331. {
  1332. CReaderList l_CReaderList;
  1333. ULONG l_uIndex;
  1334. ULONG l_uNumReaders = l_CReaderList.GetNumReaders();
  1335. CString l_CVendorName = in_CVendorName;
  1336. l_CVendorName.MakeLower();
  1337. for (l_uIndex = 0; l_uIndex < l_uNumReaders; l_uIndex++) {
  1338. CString l_CVendorListName = l_CReaderList.GetVendorName(l_uIndex);
  1339. l_CVendorListName.MakeLower();
  1340. if (l_CVendorListName.Find(l_CVendorName) != -1) {
  1341. return l_CReaderList.GetDeviceName(l_uIndex);
  1342. }
  1343. }
  1344. return CString("");
  1345. }
  1346. //**********************************************************************
  1347. //
  1348. // StopService()
  1349. //
  1350. // PURPOSE : This function attempts to stop a service. It will fail
  1351. // the service has any dependent services.
  1352. // It also allows a timeout
  1353. // value to be passed, to prevent a scenario in which a
  1354. // service shutdown hangs, and in turn the application
  1355. // stopping the service hangs.
  1356. //
  1357. // PARAMETERS: hSCM - open handle to the service control manager
  1358. // hService - open handle to the service to be stopped
  1359. // dwTimeout - maximum time (in milliseconds) to wait
  1360. // for the service and its dependencies to stop
  1361. //
  1362. // RETURN VALUE: TRUE if the service is successfully stopped
  1363. //
  1364. //**********************************************************************
  1365. BOOL StopService( SC_HANDLE hSCM, SC_HANDLE hService,
  1366. DWORD dwTimeout ) {
  1367. SERVICE_STATUS ss;
  1368. DWORD dwStartTime = GetTickCount();
  1369. // Make sure the service is not already stopped
  1370. if ( !QueryServiceStatus( hService, &ss ) )
  1371. return FALSE;
  1372. if ( ss.dwCurrentState == SERVICE_STOPPED )
  1373. return FALSE;
  1374. // If a stop is pending, just wait for it
  1375. while ( ss.dwCurrentState == SERVICE_STOP_PENDING ) {
  1376. Sleep( 5000 );
  1377. if ( !QueryServiceStatus( hService, &ss ) )
  1378. return FALSE;
  1379. if ( ss.dwCurrentState == SERVICE_STOPPED )
  1380. return FALSE;
  1381. if ( GetTickCount() - dwStartTime > dwTimeout )
  1382. return FALSE;
  1383. }
  1384. // Send a stop code to service
  1385. if ( !ControlService( hService, SERVICE_CONTROL_STOP, &ss ) )
  1386. return FALSE;
  1387. // Wait for the service to stop
  1388. while ( ss.dwCurrentState != SERVICE_STOPPED ) {
  1389. Sleep( 5000 );
  1390. if ( !QueryServiceStatus( hService, &ss ) )
  1391. return FALSE;
  1392. if ( ss.dwCurrentState == SERVICE_STOPPED )
  1393. break;
  1394. if ( GetTickCount() - dwStartTime > dwTimeout )
  1395. return FALSE;
  1396. }
  1397. // Return success
  1398. return TRUE;
  1399. }
  1400. __cdecl
  1401. main(
  1402. int argc,
  1403. char* argv[]
  1404. )
  1405. {
  1406. CArgv l_CArgv(argc, argv);
  1407. BOOL l_bSuccess, l_fInvalidParameter = FALSE;
  1408. BOOL l_bStoppedScardsvr = FALSE; // true==> we succesfully stoped scardsvr service
  1409. SC_HANDLE l_hSCM = NULL;
  1410. SC_HANDLE l_hService = NULL;
  1411. LogMessage("Smart Card Reader Test Suite");
  1412. LogMessage("Version 2.0.5");
  1413. LogMessage("Copyright(c) Microsoft Corporation 1997 - 1999");
  1414. if(PCHAR l_pchArgv = l_CArgv.CheckParameters("-d -e -h -m -r * -sa -sb -sc -sd -se -t * -v * -w *")) {
  1415. LogMessage("Invalid Parameter '%s'", l_pchArgv);
  1416. l_fInvalidParameter = TRUE;
  1417. }
  1418. if (l_fInvalidParameter ||
  1419. l_CArgv.OptionExist("h")) {
  1420. LogMessage("IfdTest [-d] [-m] [-r name] [-sa] [-sb] [-sc] [-sd] [-se] [-ss] [-w sec] [-t test] [-v name]\n");
  1421. LogMessage(" -d dumps all i/o");
  1422. LogMessage(" -e ends (stops) scardsvr service");
  1423. LogMessage(" -m manual test");
  1424. LogMessage(" -r name opens reader using device name");
  1425. LogMessage(" -sa skips card monitor test");
  1426. LogMessage(" -sb skips general reader test");
  1427. LogMessage(" -sc skips resource manager simulation");
  1428. LogMessage(" -sd skips card tests");
  1429. LogMessage(" -se skips power management tests");
  1430. LogMessage(" -v name opens reader using vendor name");
  1431. LogMessage(" -t test runs only specific card test in part d");
  1432. LogMessage(" -w sec runs power management test using specified waiting time");
  1433. exit(-1);
  1434. }
  1435. static CReader l_CReader;
  1436. CString l_CDeviceName;
  1437. //
  1438. // sandysp 5/9/01: stop scardsvr service because open will fail if it's running
  1439. //
  1440. if (l_CArgv.OptionExist("e")) {
  1441. l_hSCM = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT );
  1442. if (l_hSCM) {
  1443. // Open the specified service
  1444. l_hService = OpenService( l_hSCM,
  1445. "scardsvr",
  1446. SERVICE_STOP | SERVICE_START | SERVICE_QUERY_STATUS );
  1447. if (l_hService) {
  1448. // Try to stop the service, specifying a 30 second timeout
  1449. l_bStoppedScardsvr = StopService( l_hSCM, l_hService, 30000 ) ;
  1450. }
  1451. }
  1452. }
  1453. if (PCHAR l_pchReader = l_CArgv.ParameterExist("r")) {
  1454. l_CDeviceName = CString("\\\\.\\") + CString(l_pchReader);
  1455. } else if (PCHAR l_pchVendorName = l_CArgv.ParameterExist("v")) {
  1456. CReaderList l_CReaderList;
  1457. l_CDeviceName = SelectReader(CString(l_pchVendorName));
  1458. } else {
  1459. CReaderList l_CReaderList;
  1460. l_CDeviceName = SelectReader();
  1461. }
  1462. if (l_CDeviceName == "") {
  1463. LogMessage("No reader found");
  1464. exit (-1);
  1465. }
  1466. l_bSuccess = l_CReader.Open(l_CDeviceName);
  1467. LogMessage(".");
  1468. if (l_bSuccess == FALSE) {
  1469. LogMessage("Can't open smart card reader");
  1470. exit (-1);
  1471. }
  1472. if (l_CArgv.OptionExist("d")) {
  1473. l_CReader.SetDump(TRUE);
  1474. }
  1475. void ManualTest(CReader &in_CReader);
  1476. if (l_CArgv.OptionExist("m")) {
  1477. ManualTest(l_CReader);
  1478. }
  1479. CCardProvider l_CCardProvider;
  1480. LogOpen("ifdtest");
  1481. time_t l_osBinaryTime;
  1482. time( &l_osBinaryTime );
  1483. CTime l_CTime( l_osBinaryTime );
  1484. LogMessage("Vendor: %s", l_CReader.GetVendorName());
  1485. LogMessage("Reader: %s", l_CReader.GetIfdType());
  1486. LogMessage(
  1487. "Date: %d/%02d/%02d",
  1488. l_CTime.GetMonth(),
  1489. l_CTime.GetDay(),
  1490. l_CTime.GetYear()
  1491. );
  1492. LogMessage(
  1493. "Time: %d:%02d",
  1494. l_CTime.GetHour(),
  1495. l_CTime.GetMinute()
  1496. );
  1497. LogMessage("OS: %s", (LPCSTR) GetOperatingSystem());
  1498. //
  1499. // Check if the reader properly supports
  1500. // card insertion and removal
  1501. //
  1502. if (l_CArgv.OptionExist("sa")) {
  1503. LogMessage("=================================");
  1504. LogMessage("Part A: Card monitor test skipped");
  1505. LogMessage("=================================");
  1506. } else {
  1507. CheckCardMonitor(l_CReader);
  1508. }
  1509. if (l_CArgv.OptionExist("sb")) {
  1510. LogMessage("===========================");
  1511. LogMessage("Part B: Reader test skipped");
  1512. LogMessage("===========================");
  1513. } else {
  1514. CheckReader(l_CReader);
  1515. }
  1516. if (l_CArgv.OptionExist("sc")) {
  1517. LogMessage("===========================================");
  1518. LogMessage("Part C: Resource Manager Simulation skipped");
  1519. LogMessage("===========================================");
  1520. } else {
  1521. // Check res manager behavior
  1522. SimulateResMngr(l_CReader);
  1523. }
  1524. if (l_CArgv.OptionExist("sd")) {
  1525. LogMessage("========================================");
  1526. LogMessage("Part D: Smart Card Provider Test skipped");
  1527. LogMessage("========================================");
  1528. } else {
  1529. ULONG l_uTestNo = 0;
  1530. PCHAR l_pchTestNo;
  1531. if (l_pchTestNo = l_CArgv.ParameterExist("t")) {
  1532. // The user wants us to run only one test
  1533. l_uTestNo = atoi(l_pchTestNo);
  1534. }
  1535. while (l_CCardProvider.CardsUntested()) {
  1536. LogMessage("================================");
  1537. LogMessage("Part D: Smart Card Provider Test");
  1538. LogMessage("================================");
  1539. LogMessage("Insert any of the following PC/SC Compliance Test Cards:");
  1540. l_CCardProvider.ListUntestedCards();
  1541. LogMessage(" >> %s", INSERT_CARD);
  1542. if (l_CReader.WaitForCardInsertion() != ERROR_SUCCESS) {
  1543. LogMessage("Reader failed card insertion monitor");
  1544. return -1;
  1545. }
  1546. // Reset the card
  1547. if (l_CReader.ColdResetCard() != ERROR_SUCCESS) {
  1548. LogMessage("Unable to reset smart card");
  1549. } else {
  1550. // Try to run tests with this card
  1551. l_CCardProvider.CardTest(l_CReader, l_uTestNo);
  1552. if (l_uTestNo != 0) {
  1553. // Quit the program if we only run one test.
  1554. return 0;
  1555. }
  1556. }
  1557. LogMessage(" << %s", REMOVE_CARD);
  1558. if (l_CReader.WaitForCardRemoval() != ERROR_SUCCESS) {
  1559. LogMessage("Reader failed card removal monitor");
  1560. return -1;
  1561. }
  1562. }
  1563. }
  1564. if (GetOperatingSystem() == OS_WINNT5) {
  1565. if (l_CArgv.OptionExist("se")) {
  1566. LogMessage("=====================================");
  1567. LogMessage("Part E: Power Management Test skipped");
  1568. LogMessage("=====================================");
  1569. } else {
  1570. ULONG l_uWaitTime = 0;
  1571. if (PCHAR l_pchWaitTime = l_CArgv.ParameterExist("w")) {
  1572. // The user wants us to run only one test
  1573. l_uWaitTime = atoi(l_pchWaitTime);
  1574. }
  1575. PowerManagementTest(l_CReader, l_uWaitTime);
  1576. }
  1577. }
  1578. //
  1579. // Sandysp 5/9/01: restart smart card reader service if we stopped it
  1580. //
  1581. if (l_bStoppedScardsvr) {
  1582. StartService( l_hService, 0, NULL );
  1583. }
  1584. if ( l_hService )
  1585. CloseServiceHandle( l_hService );
  1586. if ( l_hSCM )
  1587. CloseServiceHandle( l_hSCM );
  1588. LogMessage("Reader %s the test", (ReaderFailed() ? "failed" : "passed"));
  1589. return 0;
  1590. }