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.

3303 lines
103 KiB

  1. /*****************************************************************************
  2. @doc INT EXT
  3. ******************************************************************************
  4. * $ProjectName: $
  5. * $ProjectRevision: $
  6. *-----------------------------------------------------------------------------
  7. * $Source: z:/pr/cmbp0/sw/cmbp0.ms/rcs/cmbp0scr.c $
  8. * $Revision: 1.7 $
  9. *-----------------------------------------------------------------------------
  10. * $Author: WFrischauf $
  11. *-----------------------------------------------------------------------------
  12. * History: see EOF
  13. *-----------------------------------------------------------------------------
  14. *
  15. * Copyright 2000 OMNIKEY AG
  16. ******************************************************************************/
  17. #include <cmbp0wdm.h>
  18. #include <cmbp0scr.h>
  19. #include <cmbp0log.h>
  20. // this is a FI / Fi assignment
  21. const ULONG Fi[] = { 372, 372, 588, 744, 1116, 1488, 1860, 372,
  22. 372, 512, 768, 1024, 1536, 2048, 372, 372};
  23. // this is a DI / Di assignment
  24. const ULONG Di[] = { 1, 1, 2, 4, 8, 16, 32, 1,
  25. 12, 20, 1, 1, 1, 1, 1, 1};
  26. /*****************************************************************************
  27. CMMOB_CorrectAtr
  28. Routine Description:
  29. This function checks if the received ATR is valid.
  30. Arguments:
  31. Return Value:
  32. *****************************************************************************/
  33. VOID CMMOB_CorrectAtr(
  34. PUCHAR pbBuffer,
  35. ULONG ulBufferSize
  36. )
  37. {
  38. UCHAR bNumberHistoricalBytes;
  39. UCHAR bXorChecksum;
  40. ULONG i;
  41. if (ulBufferSize < 0x09) // mininmum length of a modified ATR
  42. return ; // ATR is ok
  43. // variant 1
  44. if (pbBuffer[0] == 0x3b &&
  45. pbBuffer[1] == 0xb4 &&
  46. pbBuffer[2] == 0x11 &&
  47. pbBuffer[3] == 0x00 &&
  48. pbBuffer[4] == 0x81 &&
  49. pbBuffer[5] == 0x31 &&
  50. pbBuffer[6] == 0x90 &&
  51. pbBuffer[7] == 0x73 &&
  52. ulBufferSize == 13 )
  53. {
  54. // correct checksum byte
  55. bXorChecksum = pbBuffer[1];
  56. for (i=2;i<ulBufferSize-1;i++)
  57. bXorChecksum ^= pbBuffer[i];
  58. if (pbBuffer[ulBufferSize -1 ] != bXorChecksum )
  59. {
  60. pbBuffer[ulBufferSize -1 ] = bXorChecksum;
  61. SmartcardDebug(DEBUG_ATR,
  62. ("%s!CorrectAtr: Correcting SAMOS ATR (variant 1)\n", DRIVER_NAME));
  63. }
  64. }
  65. // variant 2
  66. if (pbBuffer[0] == 0x3b &&
  67. pbBuffer[1] == 0xbf &&
  68. pbBuffer[2] == 0x11 &&
  69. pbBuffer[3] == 0x00 &&
  70. pbBuffer[4] == 0x81 &&
  71. pbBuffer[5] == 0x31 &&
  72. pbBuffer[6] == 0x90 &&
  73. pbBuffer[7] == 0x73 &&
  74. ulBufferSize == 13 )
  75. {
  76. // correct number of historical bytes
  77. bNumberHistoricalBytes = 4;
  78. pbBuffer[1] &= 0xf0;
  79. pbBuffer[1] |= bNumberHistoricalBytes;
  80. // correct checksum byte
  81. bXorChecksum = pbBuffer[1];
  82. for (i=2;i<ulBufferSize-1;i++)
  83. bXorChecksum ^= pbBuffer[i];
  84. pbBuffer[ulBufferSize -1 ] = bXorChecksum;
  85. SmartcardDebug(DEBUG_ATR,
  86. ("%s!CorrectAtr: Correcting SAMOS ATR (variant 2)\n", DRIVER_NAME));
  87. }
  88. // variant 3
  89. if (pbBuffer[0] == 0x3b &&
  90. pbBuffer[1] == 0xbf &&
  91. pbBuffer[2] == 0x11 &&
  92. pbBuffer[3] == 0x00 &&
  93. pbBuffer[4] == 0x81 &&
  94. pbBuffer[5] == 0x31 &&
  95. pbBuffer[6] == 0x90 &&
  96. pbBuffer[7] == 0x73 &&
  97. ulBufferSize == 9 )
  98. {
  99. // correct number of historical bytes
  100. bNumberHistoricalBytes = 0;
  101. pbBuffer[1] &= 0xf0;
  102. pbBuffer[1] |= bNumberHistoricalBytes;
  103. // correct checksum byte
  104. bXorChecksum = pbBuffer[1];
  105. for (i=2;i<ulBufferSize-1;i++)
  106. bXorChecksum ^= pbBuffer[i];
  107. pbBuffer[ulBufferSize -1 ] = bXorChecksum;
  108. SmartcardDebug(DEBUG_ATR,
  109. ("%s!CorrectAtr: Correcting SAMOS ATR (variant 3)\n",DRIVER_NAME));
  110. }
  111. }
  112. /*****************************************************************************
  113. CMMOB_CardPower:
  114. callback handler for SMCLIB RDF_CARD_POWER
  115. Arguments:
  116. SmartcardExtension context of call
  117. Return Value:
  118. STATUS_SUCCESS
  119. STATUS_NO_MEDIA
  120. STATUS_TIMEOUT
  121. STATUS_BUFFER_TOO_SMALL
  122. ******************************************************************************/
  123. NTSTATUS CMMOB_CardPower (
  124. PSMARTCARD_EXTENSION SmartcardExtension
  125. )
  126. {
  127. NTSTATUS NTStatus = STATUS_SUCCESS;
  128. PREADER_EXTENSION ReaderExtension;
  129. UCHAR pbAtrBuffer[MAXIMUM_ATR_LENGTH];
  130. ULONG ulAtrLength;
  131. BOOLEAN fMaxWaitTime=FALSE;
  132. #if DBG || DEBUG
  133. static PCHAR request[] = { "PowerDown", "ColdReset", "WarmReset"};
  134. #endif
  135. SmartcardDebug(DEBUG_TRACE,
  136. ("%s!CardPower: Enter, Request = %s\n",
  137. DRIVER_NAME,request[SmartcardExtension->MinorIoControlCode]));
  138. ReaderExtension = SmartcardExtension->ReaderExtension;
  139. #ifdef IOCARD
  140. ReaderExtension->fTActive=TRUE;
  141. NTStatus = CMMOB_SetFlags1(ReaderExtension);
  142. if (NTStatus != STATUS_SUCCESS)
  143. {
  144. goto ExitCardPower;
  145. }
  146. #endif
  147. switch (SmartcardExtension->MinorIoControlCode)
  148. {
  149. case SCARD_WARM_RESET:
  150. case SCARD_COLD_RESET:
  151. // try asynchronous cards first
  152. // because some asynchronous cards
  153. // do not return 0xFF in the first byte
  154. NTStatus = CMMOB_PowerOnCard(SmartcardExtension,
  155. pbAtrBuffer,
  156. fMaxWaitTime,
  157. &ulAtrLength);
  158. if (NTStatus != STATUS_SUCCESS)
  159. {
  160. // try a second time, with maximum waiting time
  161. fMaxWaitTime=TRUE;
  162. NTStatus = CMMOB_PowerOnCard(SmartcardExtension,
  163. pbAtrBuffer,
  164. fMaxWaitTime,
  165. &ulAtrLength);
  166. }
  167. /*
  168. if (NTStatus != STATUS_SUCCESS && NTStatus!= STATUS_NO_MEDIA)
  169. {
  170. NTStatus = CMMOB_PowerOnSynchronousCard(SmartcardExtension,
  171. pbAtrBuffer,
  172. &ulAtrLength);
  173. }
  174. */
  175. if (NTStatus != STATUS_SUCCESS)
  176. {
  177. goto ExitCardPower;
  178. }
  179. // correct ATR in case of old Samos cards, with wrong number of historical bytes / checksum
  180. CMMOB_CorrectAtr(pbAtrBuffer, ulAtrLength);
  181. if (ReaderExtension->CardParameters.fSynchronousCard == FALSE)
  182. {
  183. // copy ATR to smart card structure
  184. // the lib needs the ATR for evaluation of the card parameters
  185. RtlCopyBytes((PVOID)SmartcardExtension->CardCapabilities.ATR.Buffer,
  186. (PVOID)pbAtrBuffer,
  187. ulAtrLength);
  188. SmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)ulAtrLength;
  189. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_NEGOTIABLE;
  190. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  191. NTStatus = SmartcardUpdateCardCapabilities(SmartcardExtension);
  192. if (NTStatus != STATUS_SUCCESS)
  193. {
  194. if (!fMaxWaitTime)
  195. {
  196. // try a second time, with maximum waiting time
  197. fMaxWaitTime=TRUE;
  198. NTStatus = CMMOB_PowerOnCard(SmartcardExtension,
  199. pbAtrBuffer,
  200. fMaxWaitTime,
  201. &ulAtrLength);
  202. if (NTStatus != STATUS_SUCCESS)
  203. {
  204. goto ExitCardPower;
  205. }
  206. RtlCopyBytes((PVOID)SmartcardExtension->CardCapabilities.ATR.Buffer,
  207. (PVOID)pbAtrBuffer,
  208. ulAtrLength);
  209. SmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)ulAtrLength;
  210. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_NEGOTIABLE;
  211. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  212. NTStatus = SmartcardUpdateCardCapabilities(SmartcardExtension);
  213. if (NTStatus != STATUS_SUCCESS)
  214. {
  215. goto ExitCardPower;
  216. }
  217. }
  218. else
  219. goto ExitCardPower;
  220. }
  221. // -----------------------
  222. // set parameters
  223. // -----------------------
  224. if (SmartcardExtension->CardCapabilities.N != 0xff)
  225. {
  226. // 0 <= N <= 254
  227. ReaderExtension->CardParameters.bStopBits = 2 + SmartcardExtension->CardCapabilities.N;
  228. }
  229. else
  230. {
  231. // N = 255
  232. if (SmartcardExtension->CardCapabilities.Protocol.Selected & SCARD_PROTOCOL_T0)
  233. {
  234. // 12 etu for T=0;
  235. ReaderExtension->CardParameters.bStopBits = 2;
  236. }
  237. else
  238. {
  239. // 11 etu for T=1
  240. ReaderExtension->CardParameters.bStopBits = 1;
  241. }
  242. }
  243. if (SmartcardExtension->CardCapabilities.InversConvention)
  244. {
  245. ReaderExtension->CardParameters.fInversRevers = TRUE;
  246. SmartcardDebug(DEBUG_ATR,
  247. ("%s!Card with invers convention !\n",DRIVER_NAME ));
  248. }
  249. CMMOB_SetCardParameters (ReaderExtension);
  250. #if DBG
  251. {
  252. ULONG i;
  253. SmartcardDebug(DEBUG_ATR,("%s!ATR : ",DRIVER_NAME));
  254. for (i = 0;i < ulAtrLength;i++)
  255. SmartcardDebug(DEBUG_ATR,("%2.2x ",SmartcardExtension->CardCapabilities.ATR.Buffer[i]));
  256. SmartcardDebug(DEBUG_ATR,("\n"));
  257. }
  258. #endif
  259. }
  260. else
  261. {
  262. SmartcardExtension->CardCapabilities.ATR.Buffer[0] = 0x3B;
  263. SmartcardExtension->CardCapabilities.ATR.Buffer[1] = 0x04;
  264. RtlCopyBytes((PVOID)&SmartcardExtension->CardCapabilities.ATR.Buffer[2],
  265. (PVOID)pbAtrBuffer,
  266. ulAtrLength);
  267. ulAtrLength += 2;
  268. SmartcardExtension->CardCapabilities.ATR.Length = (UCHAR)ulAtrLength;
  269. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  270. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  271. NTStatus = SmartcardUpdateCardCapabilities(SmartcardExtension);
  272. if (NTStatus != STATUS_SUCCESS)
  273. {
  274. goto ExitCardPower;
  275. }
  276. SmartcardDebug(DEBUG_ATR,("ATR of synchronous smart card : %2.2x %2.2x %2.2x %2.2x\n",
  277. pbAtrBuffer[0],pbAtrBuffer[1],pbAtrBuffer[2],pbAtrBuffer[3]));
  278. }
  279. // copy ATR to user space
  280. if (SmartcardExtension->IoRequest.ReplyBufferLength >=
  281. SmartcardExtension->CardCapabilities.ATR.Length)
  282. {
  283. RtlCopyBytes((PVOID)SmartcardExtension->IoRequest.ReplyBuffer,
  284. (PVOID)SmartcardExtension->CardCapabilities.ATR.Buffer,
  285. SmartcardExtension->CardCapabilities.ATR.Length);
  286. *SmartcardExtension->IoRequest.Information = SmartcardExtension->CardCapabilities.ATR.Length;
  287. }
  288. else
  289. {
  290. NTStatus = STATUS_BUFFER_TOO_SMALL;
  291. *SmartcardExtension->IoRequest.Information = 0;
  292. }
  293. break;
  294. case SCARD_POWER_DOWN:
  295. NTStatus = CMMOB_PowerOffCard(SmartcardExtension);
  296. if (NTStatus != STATUS_SUCCESS)
  297. {
  298. goto ExitCardPower;
  299. }
  300. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  301. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  302. break;
  303. }
  304. ExitCardPower:
  305. #ifdef IOCARD
  306. ReaderExtension->fTActive=FALSE;
  307. CMMOB_SetFlags1(ReaderExtension);
  308. #endif
  309. SmartcardDebug(DEBUG_TRACE,
  310. ("%s!CardPower: Exit %X\n",DRIVER_NAME,NTStatus ));
  311. return( NTStatus );
  312. }
  313. /*****************************************************************************
  314. Routine Description:
  315. CMMOB_PowerOnCard
  316. Arguments:
  317. Return Value:
  318. *****************************************************************************/
  319. NTSTATUS CMMOB_PowerOnCard (
  320. IN PSMARTCARD_EXTENSION SmartcardExtension,
  321. IN PUCHAR pbATR,
  322. IN BOOLEAN fMaxWaitTime,
  323. OUT PULONG pulATRLength
  324. )
  325. {
  326. NTSTATUS NTStatus = STATUS_SUCCESS;
  327. KTIMER TimerWait;
  328. UCHAR bPowerCmd;
  329. ULONG ulCardType;
  330. ULONG ulBytesReceived;
  331. UCHAR bFirstByte;
  332. LONG lWaitTime;
  333. LARGE_INTEGER liWaitTime;
  334. BOOLEAN fTimeExpired;
  335. SmartcardDebug(DEBUG_TRACE,
  336. ("%s!PowerOnCard: Enter\n",DRIVER_NAME));
  337. SmartcardExtension->ReaderExtension->CardParameters.bStopBits=2;
  338. SmartcardExtension->ReaderExtension->CardParameters.fSynchronousCard=FALSE;
  339. SmartcardExtension->ReaderExtension->CardParameters.fInversRevers=FALSE;
  340. SmartcardExtension->ReaderExtension->CardParameters.bClockFrequency=4;
  341. SmartcardExtension->ReaderExtension->CardParameters.fT0Mode=FALSE;
  342. SmartcardExtension->ReaderExtension->CardParameters.fT0Write=FALSE;
  343. SmartcardExtension->ReaderExtension->fReadCIS = FALSE;
  344. // reset the state machine of the reader
  345. NTStatus = CMMOB_ResetReader (SmartcardExtension->ReaderExtension);
  346. if (NTStatus!=STATUS_SUCCESS)
  347. goto ExitPowerOnCard;
  348. if (CMMOB_CardInserted (SmartcardExtension->ReaderExtension))
  349. {
  350. //initialize Timer
  351. KeInitializeTimer(&TimerWait);
  352. //we have to differentiate between cold and warm reset
  353. if (SmartcardExtension->MinorIoControlCode == SCARD_WARM_RESET &&
  354. CMMOB_CardPowered (SmartcardExtension->ReaderExtension))
  355. {
  356. //warm reset
  357. bPowerCmd=CMD_POWERON_WARM;
  358. }
  359. else
  360. {
  361. //cold reset
  362. bPowerCmd=CMD_POWERON_COLD;
  363. //if card is powerde we have to turn it off for cold reset
  364. if (CMMOB_CardPowered (SmartcardExtension->ReaderExtension))
  365. CMMOB_PowerOffCard (SmartcardExtension);
  366. }
  367. #define MAX_CARD_TYPE 2
  368. for (ulCardType = 0; ulCardType < MAX_CARD_TYPE; ulCardType++)
  369. {
  370. switch (ulCardType)
  371. {
  372. case 0:
  373. // BaudRate divider 372 - 1
  374. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateHigh = 0x01;
  375. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateLow = 0x73;
  376. if (fMaxWaitTime)
  377. lWaitTime=1000;
  378. else
  379. lWaitTime=100;
  380. SmartcardDebug(DEBUG_ATR,
  381. ("%s!trying 3.57 Mhz smart card, waiting time %ims\n",DRIVER_NAME,lWaitTime));
  382. break;
  383. case 1:
  384. // BaudRate divider 512 - 1
  385. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateHigh = 0x01;
  386. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateLow = 0xFF;
  387. if (fMaxWaitTime)
  388. lWaitTime=1400;
  389. else
  390. lWaitTime=140;
  391. SmartcardDebug(DEBUG_ATR,
  392. ("%s!trying 4.92 Mhz smart card, waiting time %ims\n",DRIVER_NAME,lWaitTime));
  393. break;
  394. }
  395. //set baud rate
  396. NTStatus=CMMOB_SetCardParameters(SmartcardExtension->ReaderExtension);
  397. if (NTStatus!=STATUS_SUCCESS)
  398. goto ExitPowerOnCard;
  399. //issue power on command
  400. NTStatus=CMMOB_WriteRegister(SmartcardExtension->ReaderExtension,
  401. ADDR_WRITEREG_FLAGS0, bPowerCmd);
  402. if (NTStatus!=STATUS_SUCCESS)
  403. goto ExitPowerOnCard;
  404. // maximum wait for power on first byte 100 ms
  405. liWaitTime = RtlConvertLongToLargeInteger(100L * -10000L);
  406. KeSetTimer(&TimerWait,liWaitTime,NULL);
  407. do
  408. {
  409. fTimeExpired = KeReadStateTimer(&TimerWait);
  410. NTStatus=CMMOB_BytesReceived (SmartcardExtension->ReaderExtension,&ulBytesReceived);
  411. if (NTStatus!=STATUS_SUCCESS)
  412. goto ExitPowerOnCard;
  413. // wait 1 ms, so that processor is not blocked
  414. SysDelay(1);
  415. }
  416. while (fTimeExpired==FALSE && ulBytesReceived == 0x00);
  417. if (fTimeExpired)
  418. {
  419. NTStatus = STATUS_IO_TIMEOUT;
  420. }
  421. else
  422. {
  423. ULONG ulBytesReceivedPrevious;
  424. KeCancelTimer(&TimerWait);
  425. // maximum wait for power on last byte 1 s for 3.58 card
  426. // and 1.4 seconds for 4.91 cards
  427. liWaitTime = RtlConvertLongToLargeInteger(lWaitTime * -10000L);
  428. do
  429. {
  430. KeSetTimer(&TimerWait,liWaitTime,NULL);
  431. NTStatus=CMMOB_BytesReceived (SmartcardExtension->ReaderExtension,&ulBytesReceivedPrevious);
  432. if (NTStatus!=STATUS_SUCCESS)
  433. goto ExitPowerOnCard;
  434. do
  435. {
  436. fTimeExpired = KeReadStateTimer(&TimerWait);
  437. NTStatus=CMMOB_BytesReceived (SmartcardExtension->ReaderExtension,&ulBytesReceived);
  438. if (NTStatus!=STATUS_SUCCESS)
  439. goto ExitPowerOnCard;
  440. // wait 1 ms, so that processor is not blocked
  441. SysDelay(1);
  442. }
  443. while (fTimeExpired==FALSE && ulBytesReceivedPrevious == ulBytesReceived);
  444. if (!fTimeExpired)
  445. {
  446. KeCancelTimer(&TimerWait);
  447. }
  448. }
  449. while (!fTimeExpired);
  450. //now we should have received an ATR
  451. NTStatus=CMMOB_ResetReader (SmartcardExtension->ReaderExtension);
  452. if (NTStatus!=STATUS_SUCCESS)
  453. goto ExitPowerOnCard;
  454. NTStatus=CMMOB_ReadBuffer(SmartcardExtension->ReaderExtension, 0, 1, &bFirstByte);
  455. if (NTStatus!=STATUS_SUCCESS)
  456. goto ExitPowerOnCard;
  457. if ((bFirstByte != 0x3B &&
  458. bFirstByte != 0x03 )||
  459. ulBytesReceived > MAXIMUM_ATR_LENGTH)
  460. {
  461. NTStatus=STATUS_UNRECOGNIZED_MEDIA;
  462. }
  463. else
  464. {
  465. pbATR[0]=bFirstByte;
  466. NTStatus=CMMOB_ReadBuffer(SmartcardExtension->ReaderExtension,
  467. 1, ulBytesReceived, &pbATR[1]);
  468. if (NTStatus!=STATUS_SUCCESS)
  469. goto ExitPowerOnCard;
  470. *pulATRLength = ulBytesReceived;
  471. // success leave the loop
  472. break;
  473. }
  474. }
  475. // if not the last time in the loop power off
  476. // the card to get a well defined condition
  477. // (after the last pass the power off is
  478. // done outside the loop if necessary)
  479. if (ulCardType < MAX_CARD_TYPE-1)
  480. {
  481. CMMOB_PowerOffCard(SmartcardExtension);
  482. }
  483. }
  484. }
  485. else
  486. {
  487. NTStatus=STATUS_NO_MEDIA;
  488. }
  489. ExitPowerOnCard:
  490. if (NTStatus!=STATUS_SUCCESS)
  491. {
  492. if (NTStatus != STATUS_NO_MEDIA)
  493. {
  494. NTStatus = STATUS_UNRECOGNIZED_MEDIA;
  495. }
  496. CMMOB_PowerOffCard(SmartcardExtension);
  497. }
  498. SmartcardDebug(DEBUG_TRACE,
  499. ("%s!PowerOnCard: Exit %lx\n",DRIVER_NAME,NTStatus));
  500. return NTStatus;
  501. }
  502. /*****************************************************************************
  503. Routine Description:
  504. CMMOB_PowerOffCard
  505. Arguments:
  506. Return Value:
  507. *****************************************************************************/
  508. NTSTATUS CMMOB_PowerOffCard (
  509. IN PSMARTCARD_EXTENSION SmartcardExtension
  510. )
  511. {
  512. NTSTATUS NTStatus = STATUS_SUCCESS;
  513. BYTE* pbRegsBase;
  514. KTIMER TimerWait;
  515. LARGE_INTEGER liWaitTime;
  516. BOOLEAN fTimeExpired;
  517. SmartcardDebug(DEBUG_TRACE,
  518. ("%s!PowerOffCard: Enter\n",DRIVER_NAME));
  519. NTStatus = CMMOB_ResetReader (SmartcardExtension->ReaderExtension);
  520. if (NTStatus!=STATUS_SUCCESS)
  521. goto ExitPowerOffCard;
  522. pbRegsBase=SmartcardExtension->ReaderExtension->pbRegsBase;
  523. if (CMMOB_CardInserted (SmartcardExtension->ReaderExtension))
  524. {
  525. // set card state for update thread
  526. // otherwise a card removal/insertion would be recognized
  527. if (SmartcardExtension->ReaderExtension->ulOldCardState == POWERED)
  528. SmartcardExtension->ReaderExtension->ulOldCardState = INSERTED;
  529. //issue power off command
  530. CMMOB_WriteRegister(SmartcardExtension->ReaderExtension,
  531. ADDR_WRITEREG_FLAGS0, CMD_POWEROFF);
  532. KeInitializeTimer(&TimerWait);
  533. // maximum wait for power down 1 second
  534. liWaitTime = RtlConvertLongToLargeInteger(1000L * -10000L);
  535. KeSetTimer(&TimerWait,liWaitTime,NULL);
  536. do
  537. {
  538. fTimeExpired = KeReadStateTimer(&TimerWait);
  539. // wait 1 ms, so that processor is not blocked
  540. SysDelay(1);
  541. }
  542. while (fTimeExpired==FALSE && CMMOB_CardPowered (SmartcardExtension->ReaderExtension));
  543. if (fTimeExpired)
  544. {
  545. NTStatus = STATUS_IO_TIMEOUT;
  546. }
  547. else
  548. {
  549. KeCancelTimer(&TimerWait);
  550. }
  551. }
  552. else
  553. {
  554. NTStatus=STATUS_NO_MEDIA;
  555. }
  556. ExitPowerOffCard:
  557. CMMOB_ResetReader (SmartcardExtension->ReaderExtension);
  558. SmartcardDebug(DEBUG_TRACE,
  559. ("%s!PowerOffCard: Exit %lx\n",DRIVER_NAME,NTStatus));
  560. return NTStatus;
  561. }
  562. /*****************************************************************************
  563. CMMOB_SetProtocol:
  564. callback handler for SMCLIB RDF_SET_PROTOCOL
  565. Arguments:
  566. SmartcardExtension context of call
  567. Return Value:
  568. STATUS_SUCCESS
  569. STATUS_NO_MEDIA
  570. STATUS_TIMEOUT
  571. STATUS_BUFFER_TOO_SMALL
  572. STATUS_INVALID_DEVICE_STATE
  573. STATUS_INVALID_DEVICE_REQUEST
  574. ******************************************************************************/
  575. NTSTATUS CMMOB_SetProtocol(
  576. PSMARTCARD_EXTENSION SmartcardExtension
  577. )
  578. {
  579. NTSTATUS NTStatus;
  580. PREADER_EXTENSION ReaderExtension;
  581. USHORT usSCLibProtocol;
  582. UCHAR abPTSRequest[4];
  583. UCHAR abPTSReply [4];
  584. ULONG ulBytesRead;
  585. ULONG ulBaudRateDivider;
  586. ULONG ulWaitTime;
  587. UCHAR bTemp;
  588. ULONG i;
  589. SmartcardDebug(DEBUG_TRACE,
  590. ("%s!SetProtocol: Enter\n",DRIVER_NAME ));
  591. ReaderExtension = SmartcardExtension->ReaderExtension;
  592. #ifdef IOCARD
  593. ReaderExtension->fTActive=TRUE;
  594. NTStatus = CMMOB_SetFlags1(ReaderExtension);
  595. if (NTStatus != STATUS_SUCCESS)
  596. {
  597. goto ExitSetProtocol;
  598. }
  599. #endif
  600. NTStatus = STATUS_PENDING;
  601. usSCLibProtocol = ( USHORT )( SmartcardExtension->MinorIoControlCode );
  602. //
  603. // check card insertion
  604. //
  605. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_ABSENT)
  606. {
  607. NTStatus = STATUS_NO_MEDIA;
  608. }
  609. else
  610. {
  611. //
  612. // Check if the card is already in specific state and if the caller
  613. // wants to have the selected protocol
  614. //
  615. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC)
  616. {
  617. if (SmartcardExtension->CardCapabilities.Protocol.Selected == usSCLibProtocol)
  618. {
  619. NTStatus = STATUS_SUCCESS;
  620. }
  621. }
  622. }
  623. if (NTStatus == STATUS_PENDING)
  624. {
  625. //
  626. // reset the state machine of the reader
  627. //
  628. NTStatus=CMMOB_ResetReader(ReaderExtension);
  629. if (NTStatus==STATUS_SUCCESS)
  630. {
  631. // try 2 times,
  632. // 0 - optimal
  633. // 1 - default
  634. for (i=0; i<2; i++)
  635. {
  636. // set initial character of PTS
  637. abPTSRequest[0] = 0xFF;
  638. // set the format character (PTS0)
  639. if (SmartcardExtension->CardCapabilities.Protocol.Supported &
  640. usSCLibProtocol & SCARD_PROTOCOL_T1)
  641. {
  642. // select T=1 and indicate that PTS1 follows
  643. abPTSRequest[1] = 0x11;
  644. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;
  645. }
  646. else if (SmartcardExtension->CardCapabilities.Protocol.Supported &
  647. usSCLibProtocol & SCARD_PROTOCOL_T0)
  648. {
  649. // select T=0 and indicate that PTS1 follows
  650. abPTSRequest[1] = 0x10;
  651. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  652. }
  653. else
  654. {
  655. // we do not support other protocols
  656. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  657. goto ExitSetProtocol;
  658. }
  659. if (i==0)
  660. {
  661. // optimal
  662. bTemp = (BYTE) (SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  663. SmartcardExtension->CardCapabilities.PtsData.Dl);
  664. SmartcardDebug(DEBUG_PROTOCOL,
  665. ("%s! from library suggested PTS1(0x%x)\n",DRIVER_NAME,bTemp));
  666. SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_OPTIMAL;
  667. SmartcardExtension->CardCapabilities.PtsData.Fl=SmartcardExtension->CardCapabilities.Fl;
  668. SmartcardExtension->CardCapabilities.PtsData.Dl=SmartcardExtension->CardCapabilities.Dl;
  669. }
  670. else
  671. {
  672. // default
  673. // we don�t know if it is correct to set 4.91Mhz cards to 0x11
  674. // but we have no card to try now
  675. SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_DEFAULT;
  676. SmartcardExtension->CardCapabilities.PtsData.Fl=1;
  677. SmartcardExtension->CardCapabilities.PtsData.Dl=1;
  678. }
  679. bTemp = (BYTE) (SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  680. SmartcardExtension->CardCapabilities.PtsData.Dl);
  681. SmartcardDebug(DEBUG_PROTOCOL,
  682. ("%s! trying PTS1(0x%x)\n",DRIVER_NAME,bTemp));
  683. switch (SmartcardExtension->CardCapabilities.PtsData.Fl)
  684. {
  685. case 1:
  686. // here we can handle all baudrates
  687. break;
  688. case 2:
  689. case 3:
  690. if (SmartcardExtension->CardCapabilities.PtsData.Dl == 1)
  691. {
  692. SmartcardDebug(DEBUG_PROTOCOL,
  693. ("%s! overwriting PTS1(0x%x)\n",DRIVER_NAME,bTemp));
  694. // we must correct Fl/Dl
  695. SmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  696. SmartcardExtension->CardCapabilities.PtsData.Fl = 0x01;
  697. }
  698. break;
  699. case 4:
  700. case 5:
  701. case 6:
  702. if (SmartcardExtension->CardCapabilities.PtsData.Dl == 1 ||
  703. SmartcardExtension->CardCapabilities.PtsData.Dl == 2)
  704. {
  705. SmartcardDebug(DEBUG_PROTOCOL,
  706. ("%s! overwriting PTS1(0x%x)\n",DRIVER_NAME,bTemp));
  707. // we must correct Fl/Dl
  708. SmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  709. SmartcardExtension->CardCapabilities.PtsData.Fl = 0x01;
  710. }
  711. break;
  712. case 9:
  713. // here we can handle all baudrates
  714. break;
  715. case 10:
  716. case 11:
  717. if (SmartcardExtension->CardCapabilities.PtsData.Dl == 1)
  718. {
  719. SmartcardDebug(DEBUG_PROTOCOL,
  720. ("%s! overwriting PTS1(0x%x)\n",DRIVER_NAME,bTemp));
  721. // we must correct Fl/Dl
  722. SmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  723. SmartcardExtension->CardCapabilities.PtsData.Fl = 0x09;
  724. }
  725. break;
  726. case 12:
  727. case 13:
  728. if (SmartcardExtension->CardCapabilities.PtsData.Dl == 1 ||
  729. SmartcardExtension->CardCapabilities.PtsData.Dl == 2)
  730. {
  731. SmartcardDebug(DEBUG_PROTOCOL,
  732. ("%s! overwriting PTS1(0x%x)\n",DRIVER_NAME,bTemp));
  733. // we must correct Fl/Dl
  734. SmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  735. SmartcardExtension->CardCapabilities.PtsData.Fl = 0x09;
  736. }
  737. break;
  738. default:
  739. // this are the RFUs
  740. SmartcardDebug(DEBUG_PROTOCOL,
  741. ("%s! overwriting PTS1(0x%x)\n",DRIVER_NAME,bTemp));
  742. // we must correct Fl/Dl
  743. SmartcardExtension->CardCapabilities.PtsData.Dl = 0x01;
  744. SmartcardExtension->CardCapabilities.PtsData.Fl = 0x01;
  745. break;
  746. }
  747. // set PTS1 with codes Fl and Dl
  748. abPTSRequest[2] = (BYTE) (SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  749. SmartcardExtension->CardCapabilities.PtsData.Dl);
  750. // set PCK (check character)
  751. abPTSRequest[3] = (BYTE)(abPTSRequest[0] ^ abPTSRequest[1] ^ abPTSRequest[2]);
  752. if (ReaderExtension->CardParameters.fInversRevers)
  753. {
  754. SmartcardDebug(DEBUG_PROTOCOL,
  755. ("%s! PTS request for InversConvention\n",DRIVER_NAME));
  756. CMMOB_InverseBuffer (abPTSRequest,4);
  757. }
  758. #if DBG
  759. {
  760. ULONG k;
  761. SmartcardDebug(DEBUG_PROTOCOL,("%s! writing PTS request: ",DRIVER_NAME));
  762. for (k = 0;k < 4;k++)
  763. SmartcardDebug(DEBUG_PROTOCOL,("%2.2x ",abPTSRequest[k]));
  764. SmartcardDebug(DEBUG_PROTOCOL,("\n"));
  765. }
  766. #endif
  767. NTStatus = CMMOB_WriteT1(ReaderExtension,4,abPTSRequest);
  768. if (NTStatus != STATUS_SUCCESS)
  769. {
  770. SmartcardDebug(DEBUG_ERROR,
  771. ("%s! writing PTS request failed\n", DRIVER_NAME));
  772. goto ExitSetProtocol;
  773. }
  774. // read back PTS data
  775. ulWaitTime=1000;
  776. if (SmartcardExtension->CardCapabilities.PtsData.Fl >= 8)
  777. ulWaitTime=1400;
  778. NTStatus = CMMOB_ReadT1(ReaderExtension,4,
  779. ulWaitTime,ulWaitTime,
  780. abPTSReply,&ulBytesRead);
  781. // in case of an short PTS reply an timeout will occur,
  782. // but that's not the standard case
  783. if (NTStatus != STATUS_SUCCESS && NTStatus != STATUS_IO_TIMEOUT)
  784. {
  785. SmartcardDebug(DEBUG_ERROR,
  786. ("%s! reading PTS reply: failed\n",DRIVER_NAME));
  787. goto ExitSetProtocol;
  788. }
  789. #if DBG
  790. {
  791. ULONG k;
  792. SmartcardDebug(DEBUG_PROTOCOL,("%s! reading PTS reply: ",DRIVER_NAME));
  793. for (k = 0;k < ulBytesRead;k++)
  794. SmartcardDebug(DEBUG_PROTOCOL,("%2.2x ",abPTSReply[k]));
  795. SmartcardDebug(DEBUG_PROTOCOL,("\n"));
  796. }
  797. #endif
  798. if (ulBytesRead == 4 &&
  799. abPTSReply[0] == abPTSRequest[0] &&
  800. abPTSReply[1] == abPTSRequest[1] &&
  801. abPTSReply[2] == abPTSRequest[2] &&
  802. abPTSReply[3] == abPTSRequest[3] )
  803. {
  804. SmartcardDebug(DEBUG_PROTOCOL,
  805. ("%s! PTS request and reply match\n",DRIVER_NAME));
  806. if ((SmartcardExtension->CardCapabilities.PtsData.Fl >= 3 &&
  807. SmartcardExtension->CardCapabilities.PtsData.Fl < 8) ||
  808. (SmartcardExtension->CardCapabilities.PtsData.Fl >= 11 &&
  809. SmartcardExtension->CardCapabilities.PtsData.Fl < 16))
  810. {
  811. ReaderExtension->CardParameters.bClockFrequency=8;
  812. }
  813. ulBaudRateDivider = Fi[SmartcardExtension->CardCapabilities.PtsData.Fl] /
  814. Di[SmartcardExtension->CardCapabilities.PtsData.Dl];
  815. // decrease by 1, because these values have to be written to CardMan
  816. ulBaudRateDivider--;
  817. if (ulBaudRateDivider < 512)
  818. {
  819. ReaderExtension->CardParameters.bBaudRateLow=(UCHAR)(ulBaudRateDivider & 0xFF);
  820. if (ulBaudRateDivider>255)
  821. {
  822. ReaderExtension->CardParameters.bBaudRateHigh=1;
  823. }
  824. else
  825. {
  826. ReaderExtension->CardParameters.bBaudRateHigh=0;
  827. }
  828. NTStatus = CMMOB_SetCardParameters (ReaderExtension);
  829. if (NTStatus == STATUS_SUCCESS)
  830. {
  831. //
  832. // we had success, leave the loop
  833. //
  834. break;
  835. }
  836. }
  837. }
  838. if (ulBytesRead == 3 &&
  839. abPTSReply[0] == abPTSRequest[0] &&
  840. (abPTSReply[1] & 0x7F) == (abPTSRequest[1] & 0x0F) &&
  841. abPTSReply[2] == (BYTE)(abPTSReply[0] ^ abPTSReply[1] ))
  842. {
  843. SmartcardDebug(DEBUG_PROTOCOL,
  844. ("%s! Short PTS reply received\n",DRIVER_NAME));
  845. if (SmartcardExtension->CardCapabilities.PtsData.Fl >= 9)
  846. {
  847. ulBaudRateDivider = 512;
  848. }
  849. else
  850. {
  851. ulBaudRateDivider = 372;
  852. }
  853. // decrease by 1, because these values have to be written to CardMan
  854. ulBaudRateDivider--;
  855. NTStatus = CMMOB_SetCardParameters (ReaderExtension);
  856. if (NTStatus == STATUS_SUCCESS)
  857. {
  858. //
  859. // we had success, leave the loop
  860. //
  861. break;
  862. }
  863. }
  864. if (i==0)
  865. {
  866. // this was the first try
  867. // we have a second with default values
  868. SmartcardDebug(DEBUG_PROTOCOL,
  869. ("%s! PTS failed : Trying default parameters\n",DRIVER_NAME));
  870. // the card did either not reply or it replied incorrectly
  871. // so try default values
  872. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  873. NTStatus = CMMOB_CardPower(SmartcardExtension);
  874. }
  875. else
  876. {
  877. // the card failed the PTS request
  878. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  879. }
  880. }
  881. }
  882. }
  883. ExitSetProtocol:
  884. //
  885. // if protocol selection failed, prevent from calling invalid protocols
  886. //
  887. if (NTStatus==STATUS_SUCCESS)
  888. {
  889. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  890. }
  891. else
  892. {
  893. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  894. }
  895. //
  896. // Return the selected protocol to the caller.
  897. //
  898. *(PULONG) (SmartcardExtension->IoRequest.ReplyBuffer) = SmartcardExtension->CardCapabilities.Protocol.Selected;
  899. *SmartcardExtension->IoRequest.Information = sizeof( ULONG );
  900. #ifdef IOCARD
  901. ReaderExtension->fTActive=FALSE;
  902. CMMOB_SetFlags1(ReaderExtension);
  903. #endif
  904. SmartcardDebug(DEBUG_TRACE,
  905. ("%s!SetProtocol: Exit %X\n",DRIVER_NAME,NTStatus ));
  906. return( NTStatus );
  907. }
  908. /*****************************************************************************
  909. CMMOB_Transmit:
  910. callback handler for SMCLIB RDF_TRANSMIT
  911. Arguments:
  912. SmartcardExtension context of call
  913. Return Value:
  914. STATUS_SUCCESS
  915. STATUS_NO_MEDIA
  916. STATUS_TIMEOUT
  917. STATUS_INVALID_DEVICE_REQUEST
  918. ******************************************************************************/
  919. NTSTATUS CMMOB_Transmit (
  920. PSMARTCARD_EXTENSION SmartcardExtension
  921. )
  922. {
  923. NTSTATUS NTStatus = STATUS_SUCCESS;
  924. SmartcardDebug(DEBUG_TRACE,
  925. ("%s!Transmit: Enter\n",DRIVER_NAME ));
  926. //
  927. // dispatch on the selected protocol
  928. //
  929. switch (SmartcardExtension->CardCapabilities.Protocol.Selected)
  930. {
  931. case SCARD_PROTOCOL_T0:
  932. NTStatus = CMMOB_TransmitT0(SmartcardExtension);
  933. break;
  934. case SCARD_PROTOCOL_T1:
  935. NTStatus = CMMOB_TransmitT1(SmartcardExtension);
  936. break;
  937. /*
  938. case SCARD_PROTOCOL_RAW:
  939. break;
  940. */
  941. default:
  942. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  943. break;
  944. }
  945. SmartcardDebug(DEBUG_TRACE,
  946. ("%s!Transmit: Exit %X\n",DRIVER_NAME,NTStatus ));
  947. return( NTStatus );
  948. }
  949. /*****************************************************************************
  950. CMMOB_TransmitT0:
  951. callback handler for SMCLIB RDF_TRANSMIT
  952. Arguments:
  953. SmartcardExtension context of call
  954. Return Value:
  955. STATUS_SUCCESS
  956. STATUS_NO_MEDIA
  957. STATUS_TIMEOUT
  958. STATUS_INVALID_DEVICE_REQUEST
  959. ******************************************************************************/
  960. NTSTATUS CMMOB_TransmitT0 (
  961. PSMARTCARD_EXTENSION SmartcardExtension
  962. )
  963. {
  964. NTSTATUS NTStatus;
  965. UCHAR abWriteBuffer[MIN_BUFFER_SIZE];
  966. UCHAR abReadBuffer[MIN_BUFFER_SIZE];
  967. ULONG ulBytesToWrite; //length written to card
  968. ULONG ulBytesToReceive; //length expected from card
  969. ULONG ulBytesToRead; //length expected from reader
  970. ULONG ulBytesRead; //length received from reader
  971. //(without length written)
  972. ULONG ulCWTWaitTime;
  973. BOOLEAN fDataSent; //data longer than T0_HEADER
  974. #ifdef IOCARD
  975. SmartcardExtension->ReaderExtension->fTActive=TRUE;
  976. NTStatus = CMMOB_SetFlags1(SmartcardExtension->ReaderExtension);
  977. if (NTStatus != STATUS_SUCCESS)
  978. {
  979. goto ExitTransmitT0;
  980. }
  981. #endif
  982. // reset the state machine of the reader
  983. NTStatus = CMMOB_ResetReader (SmartcardExtension->ReaderExtension);
  984. if (NTStatus!=STATUS_SUCCESS)
  985. {
  986. // there must be severe error
  987. goto ExitTransmitT0;
  988. }
  989. // set T0 mode
  990. SmartcardExtension->ReaderExtension->CardParameters.fT0Mode=TRUE;
  991. // increase timeout for T0 Transmission
  992. ulCWTWaitTime = SmartcardExtension->CardCapabilities.T0.WT/1000 + 1500;
  993. //
  994. // Let the lib build a T=0 packet
  995. //
  996. // no bytes additionally needed
  997. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  998. NTStatus = SmartcardT0Request(SmartcardExtension);
  999. if (NTStatus != STATUS_SUCCESS)
  1000. {
  1001. // the lib detected an error in the data to send.
  1002. goto ExitTransmitT0;
  1003. }
  1004. // copy data to the write buffer
  1005. ulBytesToWrite = T0_HEADER_LEN + SmartcardExtension->T0.Lc;
  1006. RtlCopyMemory(abWriteBuffer,SmartcardExtension->SmartcardRequest.Buffer,ulBytesToWrite);
  1007. ulBytesToReceive = SmartcardExtension->T0.Le;
  1008. #if DBG
  1009. {
  1010. ULONG i;
  1011. SmartcardDebug(DEBUG_PROTOCOL,("%s!TransmitT0: Request ",DRIVER_NAME));
  1012. for (i = 0;i < ulBytesToWrite;i++)
  1013. SmartcardDebug(DEBUG_PROTOCOL,("%2.2x ",abWriteBuffer[i]));
  1014. SmartcardDebug(DEBUG_PROTOCOL,("\n"));
  1015. }
  1016. #endif
  1017. // set T0 write flag correctly
  1018. if (ulBytesToReceive == 0)
  1019. {
  1020. SmartcardExtension->ReaderExtension->CardParameters.fT0Write=TRUE;
  1021. }
  1022. else
  1023. {
  1024. SmartcardExtension->ReaderExtension->CardParameters.fT0Write=FALSE;
  1025. }
  1026. NTStatus=CMMOB_SetCardParameters(SmartcardExtension->ReaderExtension);
  1027. if (NTStatus != STATUS_SUCCESS)
  1028. goto ExitTransmitT0;
  1029. NTStatus = CMMOB_WriteT0 (SmartcardExtension->ReaderExtension,
  1030. ulBytesToWrite,
  1031. ulBytesToReceive,
  1032. abWriteBuffer);
  1033. if (NTStatus != STATUS_SUCCESS)
  1034. {
  1035. goto ExitTransmitT0;
  1036. }
  1037. // bytes to write + answer + SW2
  1038. ulBytesToRead = ulBytesToWrite + ulBytesToReceive + 1;
  1039. NTStatus = CMMOB_ReadT0 (SmartcardExtension->ReaderExtension,
  1040. ulBytesToRead,
  1041. ulBytesToWrite,
  1042. ulCWTWaitTime,
  1043. abReadBuffer,
  1044. &ulBytesRead,
  1045. &fDataSent);
  1046. #if DBG
  1047. {
  1048. ULONG i;
  1049. SmartcardDebug(DEBUG_PROTOCOL,("%s!TransmitT0: Reply ",DRIVER_NAME));
  1050. for (i = 0;i < ulBytesRead;i++)
  1051. SmartcardDebug(DEBUG_PROTOCOL,("%2.2x ",abReadBuffer[i]));
  1052. SmartcardDebug(DEBUG_PROTOCOL,("\n"));
  1053. }
  1054. #endif
  1055. if (NTStatus != STATUS_SUCCESS)
  1056. {
  1057. SmartcardDebug(DEBUG_PROTOCOL,("%s!TransmitT0: Read failed!\n",DRIVER_NAME));
  1058. goto ExitTransmitT0;
  1059. }
  1060. // copy received bytes
  1061. if (ulBytesRead <= SmartcardExtension->SmartcardReply.BufferSize)
  1062. {
  1063. RtlCopyBytes((PVOID)SmartcardExtension->SmartcardReply.Buffer,
  1064. (PVOID) abReadBuffer,
  1065. ulBytesRead);
  1066. SmartcardExtension->SmartcardReply.BufferLength = ulBytesRead;
  1067. }
  1068. else
  1069. {
  1070. NTStatus=STATUS_BUFFER_OVERFLOW;
  1071. goto ExitTransmitT0;
  1072. }
  1073. // let the lib copy the received bytes to the user buffer
  1074. NTStatus = SmartcardT0Reply(SmartcardExtension);
  1075. if (NTStatus != STATUS_SUCCESS)
  1076. {
  1077. goto ExitTransmitT0;
  1078. }
  1079. ExitTransmitT0:
  1080. // ------------------------------------------
  1081. // ITSEC E2 requirements: clear write buffers
  1082. // ------------------------------------------
  1083. RtlFillMemory((PVOID)abWriteBuffer,sizeof(abWriteBuffer),0x00);
  1084. RtlFillMemory((PVOID)SmartcardExtension->SmartcardRequest.Buffer,
  1085. SmartcardExtension->SmartcardRequest.BufferSize,0x00);
  1086. // set T0 mode back
  1087. SmartcardExtension->ReaderExtension->CardParameters.fT0Mode=FALSE;
  1088. SmartcardExtension->ReaderExtension->CardParameters.fT0Write=FALSE;
  1089. CMMOB_SetCardParameters(SmartcardExtension->ReaderExtension);
  1090. #ifdef IOCARD
  1091. SmartcardExtension->ReaderExtension->fTActive=FALSE;
  1092. CMMOB_SetFlags1(SmartcardExtension->ReaderExtension);
  1093. #endif
  1094. return NTStatus;
  1095. }
  1096. /*****************************************************************************
  1097. CMMOB_TransmitT1:
  1098. callback handler for SMCLIB RDF_TRANSMIT
  1099. Arguments:
  1100. SmartcardExtension context of call
  1101. Return Value:
  1102. STATUS_SUCCESS
  1103. STATUS_NO_MEDIA
  1104. STATUS_TIMEOUT
  1105. STATUS_INVALID_DEVICE_REQUEST
  1106. ******************************************************************************/
  1107. NTSTATUS CMMOB_TransmitT1 (
  1108. PSMARTCARD_EXTENSION SmartcardExtension
  1109. )
  1110. {
  1111. NTSTATUS NTStatus;
  1112. UCHAR abReadBuffer[CMMOB_MAXBUFFER];
  1113. LONG lBytesToRead;
  1114. ULONG ulBytesRead;
  1115. ULONG ulCurrentWaitTime;
  1116. ULONG ulCWTWaitTime;
  1117. ULONG ulBWTWaitTime;
  1118. ULONG ulWTXWaitTime;
  1119. ULONG ulTemp;
  1120. SmartcardDebug(DEBUG_PROTOCOL,
  1121. ("%s!TransmitT1 CWT = %ld(ms)\n",DRIVER_NAME,
  1122. SmartcardExtension->CardCapabilities.T1.CWT/1000));
  1123. SmartcardDebug(DEBUG_PROTOCOL,
  1124. ("%s!TransmitT1 BWT = %ld(ms)\n",DRIVER_NAME,
  1125. SmartcardExtension->CardCapabilities.T1.BWT/1000));
  1126. ulCWTWaitTime = (ULONG)(100 + 32*(SmartcardExtension->CardCapabilities.T1.CWT/1000));
  1127. ulBWTWaitTime = (ULONG)(1000 + SmartcardExtension->CardCapabilities.T1.BWT/1000);
  1128. ulWTXWaitTime = 0;
  1129. #ifdef IOCARD
  1130. SmartcardExtension->ReaderExtension->fTActive=TRUE;
  1131. NTStatus = CMMOB_SetFlags1(SmartcardExtension->ReaderExtension);
  1132. if (NTStatus != STATUS_SUCCESS)
  1133. {
  1134. goto ExitTransmitT1;
  1135. }
  1136. #endif
  1137. // reset the state machine of the reader
  1138. NTStatus = CMMOB_ResetReader (SmartcardExtension->ReaderExtension);
  1139. if (NTStatus!=STATUS_SUCCESS)
  1140. {
  1141. // there must be severe error
  1142. goto ExitTransmitT1;
  1143. }
  1144. do
  1145. {
  1146. // no bytes additionally needed
  1147. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  1148. NTStatus = SmartcardT1Request(SmartcardExtension);
  1149. if (NTStatus != STATUS_SUCCESS)
  1150. {
  1151. // this should never happen, so we return immediately
  1152. goto ExitTransmitT1;
  1153. }
  1154. #if DBG
  1155. {
  1156. ULONG i;
  1157. SmartcardDebug(DEBUG_PROTOCOL,("%s!TransmitT1: Request ",DRIVER_NAME));
  1158. for (i = 0;i < SmartcardExtension->SmartcardRequest.BufferLength;i++)
  1159. SmartcardDebug(DEBUG_PROTOCOL,("%2.2x ",SmartcardExtension->SmartcardRequest.Buffer[i]));
  1160. SmartcardDebug(DEBUG_PROTOCOL,("\n"));
  1161. }
  1162. #endif
  1163. // write to the reader
  1164. NTStatus = CMMOB_WriteT1 (SmartcardExtension->ReaderExtension,
  1165. SmartcardExtension->SmartcardRequest.BufferLength,
  1166. SmartcardExtension->SmartcardRequest.Buffer);
  1167. if (NTStatus == STATUS_SUCCESS)
  1168. {
  1169. if (ulWTXWaitTime == 0 ) // use BWT
  1170. {
  1171. /*
  1172. SmartcardDebug(DEBUG_TRACE,
  1173. ("%s!ulCurrentWaitTime = %ld\n",DRIVER_NAME,ulCurrentWaitTime));
  1174. */
  1175. ulCurrentWaitTime = ulBWTWaitTime;
  1176. }
  1177. else // use WTX time
  1178. {
  1179. /*
  1180. SmartcardDebug(DEBUG_TRACE,
  1181. ("%s!ulCurrentWaitTime = %ld\n",DRIVER_NAME,ulWTXWaitTime));
  1182. */
  1183. ulCurrentWaitTime = ulWTXWaitTime;
  1184. }
  1185. if (SmartcardExtension->CardCapabilities.T1.EDC == T1_CRC_CHECK)
  1186. {
  1187. // in case of card with CRC check read reply + 5 bytes
  1188. // a negative value indicates a relative number of bytes to read
  1189. lBytesToRead=-5;
  1190. }
  1191. else
  1192. {
  1193. // in case of card with CRC check read reply + 4 bytes
  1194. // a negative value indicates a relative number of bytes to read
  1195. lBytesToRead=-4;
  1196. }
  1197. NTStatus = CMMOB_ReadT1(SmartcardExtension->ReaderExtension,lBytesToRead,
  1198. ulCurrentWaitTime,ulCWTWaitTime,abReadBuffer,&ulBytesRead);
  1199. if (NTStatus == STATUS_SUCCESS)
  1200. {
  1201. if (abReadBuffer[1] == T1_WTX_REQUEST)
  1202. {
  1203. ulWTXWaitTime = (ULONG)(1000 +((SmartcardExtension->CardCapabilities.T1.BWT*abReadBuffer[3])/1000));
  1204. SmartcardDebug(DEBUG_PROTOCOL,
  1205. ("%s!TransmitT1 WTX = %ld(ms)\n",DRIVER_NAME,ulWTXWaitTime));
  1206. }
  1207. else
  1208. {
  1209. ulWTXWaitTime = 0;
  1210. }
  1211. #if DBG
  1212. {
  1213. ULONG i;
  1214. SmartcardDebug(DEBUG_PROTOCOL,("%s!TransmitT1: Reply ",DRIVER_NAME));
  1215. for (i = 0;i < ulBytesRead;i++)
  1216. SmartcardDebug(DEBUG_PROTOCOL,("%2.2x ",abReadBuffer[i]));
  1217. SmartcardDebug(DEBUG_PROTOCOL,("\n"));
  1218. }
  1219. #endif
  1220. // copy received bytes
  1221. if (ulBytesRead <= SmartcardExtension->SmartcardReply.BufferSize)
  1222. {
  1223. RtlCopyBytes((PVOID)SmartcardExtension->SmartcardReply.Buffer,
  1224. (PVOID)abReadBuffer,
  1225. ulBytesRead);
  1226. SmartcardExtension->SmartcardReply.BufferLength = ulBytesRead;
  1227. }
  1228. else
  1229. {
  1230. NTStatus=STATUS_BUFFER_OVERFLOW;
  1231. goto ExitTransmitT1;
  1232. }
  1233. }
  1234. }
  1235. if (NTStatus != STATUS_SUCCESS)
  1236. {
  1237. SmartcardExtension->SmartcardReply.BufferLength = 0L;
  1238. }
  1239. // bug fix for smclib
  1240. if (SmartcardExtension->T1.State == T1_IFS_RESPONSE &&
  1241. SmartcardExtension->T1.OriginalState == T1_I_BLOCK)
  1242. {
  1243. SmartcardExtension->T1.State = T1_I_BLOCK;
  1244. }
  1245. NTStatus = SmartcardT1Reply(SmartcardExtension);
  1246. }
  1247. while (NTStatus == STATUS_MORE_PROCESSING_REQUIRED);
  1248. ExitTransmitT1:
  1249. // ------------------------------------------
  1250. // ITSEC E2 requirements: clear write buffers
  1251. // ------------------------------------------
  1252. RtlFillMemory((PVOID)SmartcardExtension->SmartcardRequest.Buffer,
  1253. SmartcardExtension->SmartcardRequest.BufferSize,0x00);
  1254. #ifdef IOCARD
  1255. SmartcardExtension->ReaderExtension->fTActive=FALSE;
  1256. CMMOB_SetFlags1(SmartcardExtension->ReaderExtension);
  1257. #endif
  1258. return NTStatus;
  1259. }
  1260. /*****************************************************************************
  1261. CMMOB_IoCtlVendor:
  1262. Performs generic callbacks to the reader
  1263. Arguments:
  1264. SmartcardExtension context of the call
  1265. Return Value:
  1266. STATUS_SUCCESS
  1267. ******************************************************************************/
  1268. NTSTATUS CMMOB_IoCtlVendor(
  1269. PSMARTCARD_EXTENSION SmartcardExtension
  1270. )
  1271. {
  1272. NTSTATUS NTStatus=STATUS_SUCCESS;
  1273. PIRP Irp;
  1274. PIO_STACK_LOCATION IrpStack;
  1275. SmartcardDebug(DEBUG_TRACE,
  1276. ("%s!IoCtlVendor: Enter\n",DRIVER_NAME ));
  1277. //
  1278. // get pointer to current IRP stack location
  1279. //
  1280. Irp = SmartcardExtension->OsData->CurrentIrp;
  1281. IrpStack = IoGetCurrentIrpStackLocation( Irp );
  1282. Irp->IoStatus.Information = 0;
  1283. //
  1284. // dispatch IOCTL
  1285. //
  1286. switch (IrpStack->Parameters.DeviceIoControl.IoControlCode)
  1287. {
  1288. case CM_IOCTL_GET_FW_VERSION:
  1289. NTStatus = CMMOB_GetFWVersion(SmartcardExtension);
  1290. break;
  1291. case CM_IOCTL_CR80S_SAMOS_SET_HIGH_SPEED:
  1292. NTStatus = CMMOB_SetHighSpeed_CR80S_SAMOS(SmartcardExtension);
  1293. break;
  1294. case CM_IOCTL_SET_READER_9600_BAUD:
  1295. NTStatus = CMMOB_SetReader_9600Baud(SmartcardExtension);
  1296. break;
  1297. case CM_IOCTL_SET_READER_38400_BAUD:
  1298. NTStatus = CMMOB_SetReader_38400Baud(SmartcardExtension);
  1299. break;
  1300. case CM_IOCTL_READ_DEVICE_DESCRIPTION:
  1301. NTStatus = CMMOB_ReadDeviceDescription(SmartcardExtension);
  1302. break;
  1303. default:
  1304. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  1305. break;
  1306. }
  1307. //
  1308. // set NTStatus of the packet
  1309. //
  1310. Irp->IoStatus.Status = NTStatus;
  1311. SmartcardDebug(DEBUG_TRACE,
  1312. ("%s!IoCtlVendor: Exit %X\n",DRIVER_NAME,NTStatus ));
  1313. return( NTStatus );
  1314. }
  1315. /*****************************************************************************
  1316. Routine Description:
  1317. Arguments:
  1318. Return Value: STATUS_UNSUCCESSFUL
  1319. STATUS_SUCCESS
  1320. *****************************************************************************/
  1321. NTSTATUS CMMOB_SetReader_9600Baud (
  1322. IN PSMARTCARD_EXTENSION SmartcardExtension
  1323. )
  1324. {
  1325. NTSTATUS NTStatus = STATUS_SUCCESS;;
  1326. SmartcardDebug(DEBUG_TRACE,
  1327. ("%s!SetReader_9600Baud: Enter\n",DRIVER_NAME));
  1328. // check if card is already in specific mode
  1329. if (SmartcardExtension->ReaderCapabilities.CurrentState != SCARD_SPECIFIC)
  1330. {
  1331. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  1332. goto ExitSetReader9600;
  1333. }
  1334. // set 9600 Baud for 3.58 MHz
  1335. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateHigh=0x01;
  1336. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateLow=0x73;
  1337. NTStatus = CMMOB_SetCardParameters (SmartcardExtension->ReaderExtension);
  1338. ExitSetReader9600:
  1339. *SmartcardExtension->IoRequest.Information = 0L;
  1340. SmartcardDebug(DEBUG_TRACE,
  1341. ("%s!SetReader_9600Baud: Exit %lx\n",DRIVER_NAME,NTStatus));
  1342. return(NTStatus);
  1343. }
  1344. /*****************************************************************************
  1345. Routine Description:
  1346. Arguments:
  1347. Return Value: STATUS_UNSUCCESSFUL
  1348. STATUS_SUCCESS
  1349. *****************************************************************************/
  1350. NTSTATUS CMMOB_SetReader_38400Baud (
  1351. IN PSMARTCARD_EXTENSION SmartcardExtension
  1352. )
  1353. {
  1354. NTSTATUS NTStatus = STATUS_SUCCESS;;
  1355. SmartcardDebug(DEBUG_TRACE,
  1356. ("%s!SetReader_38400Baud: Enter\n",DRIVER_NAME));
  1357. // check if card is already in specific mode
  1358. if (SmartcardExtension->ReaderCapabilities.CurrentState != SCARD_SPECIFIC)
  1359. {
  1360. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  1361. goto ExitSetReader38400;
  1362. }
  1363. // set 384000 Baud for 3.58 MHz card
  1364. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateHigh=0x00;
  1365. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateLow=0x5D;
  1366. NTStatus = CMMOB_SetCardParameters (SmartcardExtension->ReaderExtension);
  1367. ExitSetReader38400:
  1368. *SmartcardExtension->IoRequest.Information = 0L;
  1369. SmartcardDebug(DEBUG_TRACE,
  1370. ("%s!SetReader_38400Baud: Exit %lx\n",DRIVER_NAME,NTStatus));
  1371. return(NTStatus);
  1372. }
  1373. /*****************************************************************************
  1374. Routine Description:
  1375. Arguments:
  1376. Return Value: STATUS_UNSUCCESSFUL
  1377. STATUS_SUCCESS
  1378. *****************************************************************************/
  1379. NTSTATUS CMMOB_SetHighSpeed_CR80S_SAMOS (
  1380. IN PSMARTCARD_EXTENSION SmartcardExtension
  1381. )
  1382. {
  1383. NTSTATUS NTStatus;
  1384. UCHAR abCR80S_SAMOS_SET_HIGH_SPEED[4] = {0xFF,0x11,0x94,0x7A};
  1385. SmartcardDebug(DEBUG_TRACE,
  1386. ("%s!SetHighSpeed_CR80S_SAMOS: Enter\n",DRIVER_NAME));
  1387. NTStatus = CMMOB_SetSpeed (SmartcardExtension,
  1388. abCR80S_SAMOS_SET_HIGH_SPEED);
  1389. SmartcardDebug(DEBUG_TRACE,
  1390. ("%s!SetHighSpeed_CR80S_SAMOS: Exit %lx\n",DRIVER_NAME,NTStatus));
  1391. return(NTStatus);
  1392. }
  1393. /*****************************************************************************
  1394. Routine Description:
  1395. Arguments:
  1396. Return Value: STATUS_UNSUCCESSFUL
  1397. STATUS_SUCCESS
  1398. *****************************************************************************/
  1399. NTSTATUS CMMOB_SetSpeed (
  1400. IN PSMARTCARD_EXTENSION SmartcardExtension,
  1401. IN PUCHAR abFIDICommand
  1402. )
  1403. {
  1404. NTSTATUS NTStatus;
  1405. NTSTATUS DebugStatus;
  1406. UCHAR abReadBuffer[16];
  1407. ULONG ulBytesRead;
  1408. ULONG ulWaitTime;
  1409. SmartcardDebug(DEBUG_TRACE,
  1410. ("%s!SetSpeed: Enter\n",DRIVER_NAME));
  1411. #ifdef IOCARD
  1412. SmartcardExtension->ReaderExtension->fTActive=TRUE;
  1413. NTStatus = CMMOB_SetFlags1(SmartcardExtension->ReaderExtension);
  1414. if (NTStatus != STATUS_SUCCESS)
  1415. {
  1416. goto ExitSetSpeed;
  1417. }
  1418. #endif
  1419. #if DBG
  1420. {
  1421. ULONG k;
  1422. SmartcardDebug(DEBUG_PROTOCOL,("%s!SetSpeed: writing: ",DRIVER_NAME));
  1423. for (k = 0;k < 4;k++)
  1424. SmartcardDebug(DEBUG_PROTOCOL,("%2.2x ",abFIDICommand[k]));
  1425. SmartcardDebug(DEBUG_PROTOCOL,("\n"));
  1426. }
  1427. #endif
  1428. NTStatus = CMMOB_WriteT1(SmartcardExtension->ReaderExtension,4,
  1429. abFIDICommand);
  1430. if (NTStatus != STATUS_SUCCESS)
  1431. {
  1432. SmartcardDebug(DEBUG_ERROR,
  1433. ("%s!SetSpeed: writing high speed command failed\n",DRIVER_NAME));
  1434. goto ExitSetSpeed;
  1435. }
  1436. // read back pts data
  1437. // maximim initial waiting time is 9600 * etu
  1438. // clock divider of this card 512 => 1.4 sec is sufficient
  1439. ulWaitTime = 1400;
  1440. NTStatus = CMMOB_ReadT1(SmartcardExtension->ReaderExtension,4,
  1441. ulWaitTime,ulWaitTime,abReadBuffer,&ulBytesRead);
  1442. SmartcardDebug(DEBUG_PROTOCOL,
  1443. ("%s!SetSpeed: reading echo: ",DRIVER_NAME));
  1444. if (NTStatus != STATUS_SUCCESS)
  1445. {
  1446. SmartcardDebug(DEBUG_PROTOCOL,("failed\n"));
  1447. goto ExitSetSpeed;
  1448. }
  1449. #if DBG
  1450. {
  1451. ULONG k;
  1452. for (k = 0;k < ulBytesRead;k++)
  1453. SmartcardDebug(DEBUG_PROTOCOL,("%2.2x ",abReadBuffer[k]));
  1454. SmartcardDebug(DEBUG_PROTOCOL,("\n"));
  1455. }
  1456. #endif
  1457. // if the card has accepted this string , the string is echoed
  1458. if (abReadBuffer[0] == abFIDICommand[0] &&
  1459. abReadBuffer[1] == abFIDICommand[1] &&
  1460. abReadBuffer[2] == abFIDICommand[2] &&
  1461. abReadBuffer[3] == abFIDICommand[3] )
  1462. {
  1463. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateLow=63;
  1464. SmartcardExtension->ReaderExtension->CardParameters.bBaudRateHigh=0;
  1465. NTStatus = CMMOB_SetCardParameters (SmartcardExtension->ReaderExtension);
  1466. }
  1467. else
  1468. {
  1469. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  1470. CMMOB_CardPower(SmartcardExtension);
  1471. NTStatus = STATUS_UNSUCCESSFUL;
  1472. }
  1473. ExitSetSpeed:
  1474. *SmartcardExtension->IoRequest.Information = 0L;
  1475. if (NTStatus != STATUS_SUCCESS)
  1476. {
  1477. NTStatus = STATUS_UNSUCCESSFUL;
  1478. }
  1479. #ifdef IOCARD
  1480. SmartcardExtension->ReaderExtension->fTActive=FALSE;
  1481. CMMOB_SetFlags1(SmartcardExtension->ReaderExtension);
  1482. #endif
  1483. SmartcardDebug(DEBUG_TRACE,
  1484. ("%s!SetSpeed: Exit %lx\n",DRIVER_NAME,NTStatus));
  1485. return NTStatus;
  1486. }
  1487. /*****************************************************************************
  1488. Routine Description:
  1489. This function always returns 'CardManMobile'.
  1490. Arguments: pointer to SMARTCARD_EXTENSION
  1491. Return Value: NT status
  1492. *****************************************************************************/
  1493. NTSTATUS CMMOB_ReadDeviceDescription(
  1494. IN PSMARTCARD_EXTENSION SmartcardExtension
  1495. )
  1496. {
  1497. NTSTATUS NTStatus = STATUS_SUCCESS;
  1498. BYTE abDeviceDescription[] = "CardManMobile";
  1499. SmartcardDebug(DEBUG_TRACE,
  1500. ("%s!ReadDeviceDescription : Enter\n",DRIVER_NAME));
  1501. if (SmartcardExtension->IoRequest.ReplyBufferLength < sizeof(abDeviceDescription))
  1502. {
  1503. NTStatus = STATUS_BUFFER_OVERFLOW;
  1504. *SmartcardExtension->IoRequest.Information = 0L;
  1505. goto ExitReadDeviceDescription;
  1506. }
  1507. else
  1508. {
  1509. RtlCopyBytes((PVOID)SmartcardExtension->IoRequest.ReplyBuffer,
  1510. (PVOID)abDeviceDescription,sizeof(abDeviceDescription));
  1511. *SmartcardExtension->IoRequest.Information = sizeof(abDeviceDescription);
  1512. }
  1513. ExitReadDeviceDescription:
  1514. SmartcardDebug(DEBUG_TRACE,
  1515. ("%s!ReadDeviceDescription : Exit %lx\n",DRIVER_NAME,NTStatus));
  1516. return NTStatus;
  1517. }
  1518. /*****************************************************************************
  1519. Routine Description:
  1520. Arguments:
  1521. Return Value:
  1522. *****************************************************************************/
  1523. NTSTATUS CMMOB_GetFWVersion (
  1524. IN PSMARTCARD_EXTENSION SmartcardExtension
  1525. )
  1526. {
  1527. NTSTATUS NTStatus = STATUS_SUCCESS;
  1528. SmartcardDebug(DEBUG_TRACE,
  1529. ("%s!GetFWVersion : Enter\n",DRIVER_NAME));
  1530. if (SmartcardExtension->IoRequest.ReplyBufferLength < sizeof (ULONG))
  1531. {
  1532. NTStatus = STATUS_BUFFER_OVERFLOW;
  1533. *SmartcardExtension->IoRequest.Information = 0;
  1534. }
  1535. else
  1536. {
  1537. *(PULONG)(SmartcardExtension->IoRequest.ReplyBuffer) =
  1538. SmartcardExtension->ReaderExtension->ulFWVersion;
  1539. *SmartcardExtension->IoRequest.Information = sizeof(ULONG);
  1540. }
  1541. SmartcardDebug(DEBUG_TRACE,
  1542. ("%s!GetFWVersion : Exit %lx\n",DRIVER_NAME,NTStatus));
  1543. return NTStatus;
  1544. }
  1545. /*****************************************************************************
  1546. CMMOB_CardTracking:
  1547. callback handler for SMCLIB RDF_CARD_TRACKING. the requested event was
  1548. validated by the smclib (i.e. a card removal request will only be passed
  1549. if a card is present).
  1550. for a win95 build STATUS_PENDING will be returned without any other action.
  1551. for NT the cancel routine for the irp will be set to the drivers cancel
  1552. routine.
  1553. Arguments:
  1554. SmartcardExtension context of call
  1555. Return Value:
  1556. STATUS_PENDING
  1557. ******************************************************************************/
  1558. NTSTATUS CMMOB_CardTracking(
  1559. PSMARTCARD_EXTENSION SmartcardExtension
  1560. )
  1561. {
  1562. KIRQL CurrentIrql;
  1563. SmartcardDebug(DEBUG_TRACE,
  1564. ("%s!CardTracking: Enter\n",DRIVER_NAME ));
  1565. //
  1566. // set cancel routine
  1567. //
  1568. IoAcquireCancelSpinLock( &CurrentIrql );
  1569. IoSetCancelRoutine(SmartcardExtension->OsData->NotificationIrp,
  1570. CMMOB_CancelCardTracking);
  1571. IoReleaseCancelSpinLock( CurrentIrql );
  1572. //
  1573. // Mark notification irp pending
  1574. //
  1575. IoMarkIrpPending(SmartcardExtension->OsData->NotificationIrp);
  1576. SmartcardDebug(DEBUG_TRACE,
  1577. ("%s!CardTracking: Exit\n",DRIVER_NAME ));
  1578. return( STATUS_PENDING );
  1579. }
  1580. /*****************************************************************************
  1581. CMMOB_CompleteCardTracking:
  1582. finishes a pending tracking request if the device will be unloaded
  1583. Arguments:
  1584. DeviceObject context of the request
  1585. NTStatus NTStatus to report to the calling process
  1586. Return Value:
  1587. ******************************************************************************/
  1588. VOID CMMOB_CompleteCardTracking(
  1589. PSMARTCARD_EXTENSION SmartcardExtension
  1590. )
  1591. {
  1592. KIRQL ioIrql, keIrql;
  1593. PIRP NotificationIrp;
  1594. IoAcquireCancelSpinLock(&ioIrql);
  1595. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  1596. &keIrql);
  1597. NotificationIrp = SmartcardExtension->OsData->NotificationIrp;
  1598. SmartcardExtension->OsData->NotificationIrp = NULL;
  1599. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1600. keIrql);
  1601. if (NotificationIrp!=NULL)
  1602. {
  1603. IoSetCancelRoutine(NotificationIrp, NULL);
  1604. }
  1605. IoReleaseCancelSpinLock(ioIrql);
  1606. if (NotificationIrp!=NULL)
  1607. {
  1608. //finish the request
  1609. if (NotificationIrp->Cancel)
  1610. {
  1611. NotificationIrp->IoStatus.Status = STATUS_CANCELLED;
  1612. }
  1613. else
  1614. {
  1615. NotificationIrp->IoStatus.Status = STATUS_SUCCESS;
  1616. }
  1617. NotificationIrp->IoStatus.Information = 0;
  1618. SmartcardDebug(DEBUG_DRIVER,
  1619. ("%s!CompleteCardTracking: Completing Irp %lx Status=%lx\n",
  1620. DRIVER_NAME, NotificationIrp,NotificationIrp->IoStatus.Status));
  1621. IoCompleteRequest(NotificationIrp, IO_NO_INCREMENT );
  1622. }
  1623. }
  1624. /*****************************************************************************
  1625. CMMOB_CancelCardTracking
  1626. This routine is called by the I/O system
  1627. when the irp should be cancelled
  1628. Arguments:
  1629. DeviceObject - Pointer to device object for this miniport
  1630. Irp - IRP involved.
  1631. Return Value:
  1632. STATUS_CANCELLED
  1633. ******************************************************************************/
  1634. NTSTATUS CMMOB_CancelCardTracking(
  1635. IN PDEVICE_OBJECT DeviceObject,
  1636. IN PIRP Irp
  1637. )
  1638. {
  1639. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  1640. PSMARTCARD_EXTENSION SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1641. SmartcardDebug(DEBUG_TRACE,
  1642. ("%s!CancelCardTracking: Enter\n",DRIVER_NAME));
  1643. ASSERT(Irp == SmartcardExtension->OsData->NotificationIrp);
  1644. IoReleaseCancelSpinLock(Irp->CancelIrql);
  1645. CMMOB_CompleteCardTracking(SmartcardExtension);
  1646. SmartcardDebug(DEBUG_TRACE,
  1647. ("%s!CancelCardTracking: Exit\n",DRIVER_NAME));
  1648. return STATUS_CANCELLED;
  1649. }
  1650. /*****************************************************************************
  1651. CMMOB_StartCardTracking:
  1652. Arguments:
  1653. DeviceObject context of call
  1654. Return Value:
  1655. STATUS_SUCCESS
  1656. NTStatus returned by LowLevel routines
  1657. ******************************************************************************/
  1658. NTSTATUS CMMOB_StartCardTracking(
  1659. IN PDEVICE_OBJECT DeviceObject
  1660. )
  1661. {
  1662. NTSTATUS NTStatus = STATUS_SUCCESS;
  1663. HANDLE hThread;
  1664. PDEVICE_EXTENSION DeviceExtension;
  1665. PSMARTCARD_EXTENSION SmartcardExtension;
  1666. DeviceExtension = DeviceObject->DeviceExtension;
  1667. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1668. SmartcardDebug(DEBUG_TRACE,
  1669. ( "%s!StartCardTracking: Enter\n",DRIVER_NAME));
  1670. SmartcardDebug(DEBUG_DRIVER,
  1671. ( "%s!StartCardTracking: IRQL %i\n",DRIVER_NAME,KeGetCurrentIrql()));
  1672. KeWaitForSingleObject(&SmartcardExtension->ReaderExtension->CardManIOMutex,
  1673. Executive,
  1674. KernelMode,
  1675. FALSE,
  1676. NULL);
  1677. // settings for thread synchronization
  1678. SmartcardExtension->ReaderExtension->fTerminateUpdateThread = FALSE;
  1679. // create thread for updating current state
  1680. NTStatus = PsCreateSystemThread(&hThread,
  1681. THREAD_ALL_ACCESS,
  1682. NULL,
  1683. NULL,
  1684. NULL,
  1685. CMMOB_UpdateCurrentStateThread,
  1686. DeviceObject);
  1687. if (NT_SUCCESS(NTStatus))
  1688. {
  1689. //
  1690. // We've got the thread. Now get a pointer to it.
  1691. //
  1692. NTStatus = ObReferenceObjectByHandle(hThread,
  1693. THREAD_ALL_ACCESS,
  1694. NULL,
  1695. KernelMode,
  1696. &SmartcardExtension->ReaderExtension->ThreadObjectPointer,
  1697. NULL);
  1698. if (NT_ERROR(NTStatus))
  1699. {
  1700. SmartcardExtension->ReaderExtension->fTerminateUpdateThread = TRUE;
  1701. }
  1702. else
  1703. {
  1704. //
  1705. // Now that we have a reference to the thread
  1706. // we can simply close the handle.
  1707. //
  1708. ZwClose(hThread);
  1709. SmartcardExtension->ReaderExtension->fUpdateThreadRunning = TRUE;
  1710. }
  1711. }
  1712. SmartcardDebug(DEBUG_DRIVER,
  1713. ("%s!-----------------------------------------------------------\n",DRIVER_NAME));
  1714. SmartcardDebug(DEBUG_DRIVER,
  1715. ("%s!STARTING THREAD\n",DRIVER_NAME));
  1716. SmartcardDebug(DEBUG_DRIVER,
  1717. ("%s!-----------------------------------------------------------\n",DRIVER_NAME));
  1718. KeReleaseMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  1719. SmartcardDebug(DEBUG_TRACE,
  1720. ( "%s!CMMOB_StartCardTracking: Exit %lx\n",DRIVER_NAME,NTStatus));
  1721. return NTStatus;
  1722. }
  1723. /*****************************************************************************
  1724. CMMOB_StopCardTracking:
  1725. Arguments:
  1726. DeviceObject context of call
  1727. Return Value:
  1728. ******************************************************************************/
  1729. VOID CMMOB_StopCardTracking(
  1730. IN PDEVICE_OBJECT DeviceObject
  1731. )
  1732. {
  1733. PDEVICE_EXTENSION DeviceExtension;
  1734. PSMARTCARD_EXTENSION SmartcardExtension;
  1735. SmartcardDebug(DEBUG_TRACE,
  1736. ( "%s!StopCardTracking: Enter\n",DRIVER_NAME));
  1737. SmartcardDebug(DEBUG_DRIVER,
  1738. ( "%s!StopCardTracking: IRQL %i\n",DRIVER_NAME,KeGetCurrentIrql()));
  1739. DeviceExtension = DeviceObject->DeviceExtension;
  1740. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1741. if (SmartcardExtension->ReaderExtension->fUpdateThreadRunning)
  1742. {
  1743. // kill thread
  1744. KeWaitForSingleObject(&SmartcardExtension->ReaderExtension->CardManIOMutex,
  1745. Executive,
  1746. KernelMode,
  1747. FALSE,
  1748. NULL );
  1749. SmartcardExtension->ReaderExtension->fTerminateUpdateThread = TRUE;
  1750. KeReleaseMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  1751. /* this doesn't work with Win98
  1752. //
  1753. // Wait on the thread handle, when the wait is satisfied, the
  1754. // thread has gone away.
  1755. //
  1756. KeWaitForSingleObject(SmartcardExtension->ReaderExtension->ThreadObjectPointer,
  1757. Executive,
  1758. KernelMode,
  1759. FALSE,
  1760. NULL);
  1761. */
  1762. while (SmartcardExtension->ReaderExtension->fUpdateThreadRunning==TRUE)
  1763. {
  1764. SysDelay(1);
  1765. }
  1766. }
  1767. SmartcardDebug(DEBUG_TRACE,
  1768. ( "%s!StopCardTracking: Exit\n",DRIVER_NAME));
  1769. return;
  1770. }
  1771. /*****************************************************************************
  1772. CMMOB_UpdateCurrentStateThread:
  1773. Arguments:
  1774. DeviceObject context of call
  1775. Return Value:
  1776. ******************************************************************************/
  1777. VOID CMMOB_UpdateCurrentStateThread(
  1778. IN PVOID Context
  1779. )
  1780. {
  1781. NTSTATUS NTStatus = STATUS_SUCCESS;
  1782. PDEVICE_OBJECT DeviceObject = Context;
  1783. PDEVICE_EXTENSION DeviceExtension;
  1784. PSMARTCARD_EXTENSION SmartcardExtension;
  1785. ULONG ulInterval;
  1786. DeviceExtension = DeviceObject->DeviceExtension;
  1787. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1788. KeWaitForSingleObject(&DeviceExtension->CanRunUpdateThread,
  1789. Executive,
  1790. KernelMode,
  1791. FALSE,
  1792. NULL);
  1793. SmartcardDebug(DEBUG_DRIVER,
  1794. ( "%s!UpdateCurrentStateThread: started\n",DRIVER_NAME));
  1795. while (TRUE)
  1796. {
  1797. // every 500 ms the NTStatus request is sent
  1798. ulInterval = 500;
  1799. KeWaitForSingleObject(&SmartcardExtension->ReaderExtension->CardManIOMutex,
  1800. Executive,
  1801. KernelMode,
  1802. FALSE,
  1803. NULL);
  1804. /*
  1805. SmartcardDebug(DEBUG_TRACE,
  1806. ("%s!UpdateCurrentStateThread executed\n",DRIVER_NAME));
  1807. */
  1808. if (SmartcardExtension->ReaderExtension->fTerminateUpdateThread)
  1809. {
  1810. SmartcardDebug(DEBUG_DRIVER,
  1811. ("%s!-----------------------------------------------------------\n",DRIVER_NAME));
  1812. SmartcardDebug(DEBUG_DRIVER,
  1813. ("%s!UpdateCurrentStateThread: STOPPING THREAD\n",DRIVER_NAME));
  1814. SmartcardDebug(DEBUG_DRIVER,
  1815. ("%s!-----------------------------------------------------------\n",DRIVER_NAME));
  1816. KeReleaseMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  1817. SmartcardExtension->ReaderExtension->fUpdateThreadRunning = FALSE;
  1818. PsTerminateSystemThread( STATUS_SUCCESS );
  1819. }
  1820. //
  1821. // get current card state
  1822. //
  1823. NTStatus = CMMOB_UpdateCurrentState(SmartcardExtension);
  1824. if (NTStatus == STATUS_DEVICE_DATA_ERROR)
  1825. {
  1826. SmartcardDebug(DEBUG_DRIVER,
  1827. ("%s!UpdateCurrentStateThread: setting update interval to 1ms\n",DRIVER_NAME));
  1828. ulInterval = 1;
  1829. }
  1830. else if (NTStatus != STATUS_SUCCESS &&
  1831. NTStatus != STATUS_NO_SUCH_DEVICE)
  1832. {
  1833. SmartcardDebug(DEBUG_DRIVER,
  1834. ("%s!UpdateCurrentStateThread: UpdateCurrentState failed!\n",DRIVER_NAME));
  1835. }
  1836. KeReleaseMutex(&SmartcardExtension->ReaderExtension->CardManIOMutex,FALSE);
  1837. SysDelay (ulInterval);
  1838. }
  1839. }
  1840. /*****************************************************************************
  1841. CMMOB_UpdateCurrentState:
  1842. Arguments:
  1843. DeviceObject context of call
  1844. Return Value:
  1845. ******************************************************************************/
  1846. NTSTATUS CMMOB_UpdateCurrentState(
  1847. IN PSMARTCARD_EXTENSION SmartcardExtension
  1848. )
  1849. {
  1850. NTSTATUS NTStatus = STATUS_SUCCESS;
  1851. BOOL fCardStateChanged = FALSE;
  1852. /*
  1853. SmartcardDebug(DEBUG_TRACE,
  1854. ("%s!UpdateCurrentState executed\n",DRIVER_NAME));
  1855. */
  1856. //
  1857. // get card state from cardman
  1858. //
  1859. NTStatus = CMMOB_ResetReader(SmartcardExtension->ReaderExtension);
  1860. if (NTStatus == STATUS_SUCCESS ||
  1861. NTStatus == STATUS_NO_SUCH_DEVICE)
  1862. {
  1863. if (NTStatus == STATUS_SUCCESS)
  1864. {
  1865. if (CMMOB_CardInserted(SmartcardExtension->ReaderExtension))
  1866. {
  1867. if (CMMOB_CardPowered(SmartcardExtension->ReaderExtension))
  1868. SmartcardExtension->ReaderExtension->ulNewCardState = POWERED;
  1869. else
  1870. SmartcardExtension->ReaderExtension->ulNewCardState = INSERTED;
  1871. }
  1872. else
  1873. SmartcardExtension->ReaderExtension->ulNewCardState = REMOVED;
  1874. }
  1875. else
  1876. SmartcardExtension->ReaderExtension->ulNewCardState = REMOVED;
  1877. if (SmartcardExtension->ReaderExtension->ulNewCardState == INSERTED &&
  1878. SmartcardExtension->ReaderExtension->ulOldCardState == POWERED )
  1879. {
  1880. // card has been removed and reinserted
  1881. SmartcardExtension->ReaderExtension->ulNewCardState = REMOVED;
  1882. }
  1883. if ((SmartcardExtension->ReaderExtension->ulNewCardState == INSERTED &&
  1884. (SmartcardExtension->ReaderExtension->ulOldCardState == UNKNOWN ||
  1885. SmartcardExtension->ReaderExtension->ulOldCardState == REMOVED )) ||
  1886. (SmartcardExtension->ReaderExtension->ulNewCardState == POWERED &&
  1887. SmartcardExtension->ReaderExtension->ulOldCardState == UNKNOWN ))
  1888. {
  1889. // card has been inserted
  1890. SmartcardDebug(DEBUG_DRIVER,
  1891. ("%s!UpdateCurrentState: smartcard inserted\n",DRIVER_NAME));
  1892. SmartcardExtension->ReaderExtension->ulOldCardState = SmartcardExtension->ReaderExtension->ulNewCardState;
  1893. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  1894. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1895. fCardStateChanged = TRUE;
  1896. }
  1897. if (SmartcardExtension->ReaderExtension->ulNewCardState == REMOVED &&
  1898. (SmartcardExtension->ReaderExtension->ulOldCardState == UNKNOWN ||
  1899. SmartcardExtension->ReaderExtension->ulOldCardState == INSERTED ||
  1900. SmartcardExtension->ReaderExtension->ulOldCardState == POWERED ))
  1901. {
  1902. // card has been removed
  1903. SmartcardDebug(DEBUG_DRIVER,
  1904. ("%s!UpdateCurrentState: smartcard removed\n",DRIVER_NAME));
  1905. SmartcardExtension->ReaderExtension->ulOldCardState = SmartcardExtension->ReaderExtension->ulNewCardState;
  1906. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  1907. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1908. fCardStateChanged = TRUE;
  1909. // clear any cardspecific data
  1910. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  1911. RtlFillMemory((PVOID)&SmartcardExtension->ReaderExtension->CardParameters,
  1912. sizeof(CARD_PARAMETERS), 0x00);
  1913. }
  1914. // complete IOCTL_SMARTCARD_IS_ABSENT or IOCTL_SMARTCARD_IS_PRESENT
  1915. if (fCardStateChanged == TRUE &&
  1916. SmartcardExtension->OsData->NotificationIrp )
  1917. {
  1918. SmartcardDebug(DEBUG_DRIVER,("%s!UpdateCurrentState: completing IRP\n",DRIVER_NAME));
  1919. CMMOB_CompleteCardTracking(SmartcardExtension);
  1920. }
  1921. }
  1922. return NTStatus;
  1923. }
  1924. /*****************************************************************************
  1925. CMMOB_ResetReader:
  1926. Resets the reader
  1927. Arguments:
  1928. ReaderExtension context of the call
  1929. Return Value:
  1930. none
  1931. ******************************************************************************/
  1932. NTSTATUS CMMOB_ResetReader(
  1933. PREADER_EXTENSION ReaderExtension
  1934. )
  1935. {
  1936. NTSTATUS NTStatus;
  1937. BOOLEAN fToggle;
  1938. UCHAR bFlags1;
  1939. NTStatus = CMMOB_WriteRegister(ReaderExtension,ADDR_WRITEREG_FLAGS0,CMD_RESET_SM);
  1940. if (NTStatus != STATUS_SUCCESS)
  1941. return NTStatus;
  1942. #ifdef IOCARD
  1943. // check for reader presence
  1944. bFlags1 = ReaderExtension->bPreviousFlags1;
  1945. bFlags1 |= FLAG_CHECK_PRESENCE;
  1946. NTStatus = CMMOB_WriteRegister(ReaderExtension, ADDR_WRITEREG_FLAGS1, bFlags1);
  1947. // don't check for status because
  1948. // we have to set back fCheckPresence for proper working
  1949. fToggle = CMMOB_GetReceiveFlag(ReaderExtension);
  1950. bFlags1 = ReaderExtension->bPreviousFlags1;
  1951. NTStatus = CMMOB_WriteRegister(ReaderExtension, ADDR_WRITEREG_FLAGS1, bFlags1);
  1952. if (NTStatus != STATUS_SUCCESS)
  1953. return NTStatus;
  1954. if (fToggle == CMMOB_GetReceiveFlag(ReaderExtension))
  1955. {
  1956. SmartcardDebug(DEBUG_DRIVER,
  1957. ("%s!ResetReader: CardMan Mobile removed!\n",DRIVER_NAME));
  1958. return STATUS_NO_SUCH_DEVICE;
  1959. }
  1960. #endif
  1961. return NTStatus;
  1962. }
  1963. /*****************************************************************************
  1964. CMMOB_BytesReceived:
  1965. Reads how many bytes are already received from the card by the reader
  1966. Arguments:
  1967. ReaderExtension context of the call
  1968. Return Value:
  1969. NTStatus
  1970. ******************************************************************************/
  1971. NTSTATUS CMMOB_BytesReceived(
  1972. PREADER_EXTENSION ReaderExtension,
  1973. PULONG pulBytesReceived
  1974. )
  1975. {
  1976. NTSTATUS NTStatus = STATUS_SUCCESS;
  1977. ULONG ulBytesReceived;
  1978. ULONG ulBytesReceivedCheck;
  1979. UCHAR bReg;
  1980. /*
  1981. SmartcardDebug(DEBUG_TRACE,
  1982. ( "%s!BytesReceived Enter\n",DRIVER_NAME));
  1983. */
  1984. *pulBytesReceived=0;
  1985. if (CMMOB_GetReceiveFlag(ReaderExtension) ||
  1986. ReaderExtension->CardParameters.fT0Mode)
  1987. {
  1988. do
  1989. {
  1990. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_BYTES_RECEIVED,&bReg);
  1991. if (NTStatus!=STATUS_SUCCESS)
  1992. return NTStatus;
  1993. ulBytesReceived=bReg;
  1994. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_FLAGS0,&bReg);
  1995. if (NTStatus!=STATUS_SUCCESS)
  1996. return NTStatus;
  1997. if ((bReg & FLAG_BYTES_RECEIVED_B9) == FLAG_BYTES_RECEIVED_B9)
  1998. {
  1999. ulBytesReceived+=0x100;
  2000. }
  2001. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_BYTES_RECEIVED,&bReg);
  2002. if (NTStatus!=STATUS_SUCCESS)
  2003. return NTStatus;
  2004. ulBytesReceivedCheck=bReg;
  2005. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_FLAGS0,&bReg);
  2006. if (NTStatus!=STATUS_SUCCESS)
  2007. return NTStatus;
  2008. if ((bReg & FLAG_BYTES_RECEIVED_B9) == FLAG_BYTES_RECEIVED_B9)
  2009. {
  2010. ulBytesReceivedCheck+=0x100;
  2011. }
  2012. }
  2013. while (ulBytesReceived!=ulBytesReceivedCheck);
  2014. *pulBytesReceived=ulBytesReceived;
  2015. }
  2016. /*
  2017. SmartcardDebug(DEBUG_TRACE,
  2018. ( "%s!BytesReceived Exit\n",DRIVER_NAME));
  2019. */
  2020. return NTStatus;
  2021. }
  2022. /*****************************************************************************
  2023. CMMOB_SetFlags1:
  2024. Sets register Flags1
  2025. Arguments:
  2026. ReaderExtension context of the call
  2027. Return Value:
  2028. none
  2029. ******************************************************************************/
  2030. NTSTATUS CMMOB_SetFlags1 (
  2031. PREADER_EXTENSION ReaderExtension
  2032. )
  2033. {
  2034. NTSTATUS NTStatus = STATUS_SUCCESS;
  2035. UCHAR bFlags1;
  2036. bFlags1 = ReaderExtension->CardParameters.bBaudRateHigh;
  2037. if (ReaderExtension->CardParameters.fInversRevers)
  2038. bFlags1 |= FLAG_INVERS_PARITY;
  2039. if (ReaderExtension->CardParameters.bClockFrequency==8)
  2040. bFlags1 |= FLAG_CLOCK_8MHZ;
  2041. if (ReaderExtension->CardParameters.fT0Write)
  2042. bFlags1 |= FLAG_T0_WRITE;
  2043. #ifdef IOCARD
  2044. if (ReaderExtension->bAddressHigh == 1)
  2045. bFlags1 |= FLAG_BUFFER_ADDR_B9;
  2046. if (ReaderExtension->fTActive)
  2047. bFlags1 |= FLAG_TACTIVE;
  2048. if (ReaderExtension->fReadCIS)
  2049. bFlags1 |= FLAG_READ_CIS;
  2050. #endif
  2051. ReaderExtension->bPreviousFlags1=bFlags1;
  2052. NTStatus = CMMOB_WriteRegister(ReaderExtension, ADDR_WRITEREG_FLAGS1, bFlags1);
  2053. return NTStatus;
  2054. }
  2055. /*****************************************************************************
  2056. CMMOB_SetCardParameters:
  2057. Sets card parameters (baudrate, stopbits)
  2058. Arguments:
  2059. ReaderExtension context of the call
  2060. Return Value:
  2061. none
  2062. ******************************************************************************/
  2063. NTSTATUS CMMOB_SetCardParameters (
  2064. PREADER_EXTENSION ReaderExtension
  2065. )
  2066. {
  2067. NTSTATUS NTStatus = STATUS_SUCCESS;
  2068. NTStatus = CMMOB_SetFlags1 (ReaderExtension);
  2069. if (NTStatus!=STATUS_SUCCESS)
  2070. return NTStatus;
  2071. NTStatus = CMMOB_WriteRegister(ReaderExtension, ADDR_WRITEREG_BAUDRATE,
  2072. ReaderExtension->CardParameters.bBaudRateLow);
  2073. if (NTStatus!=STATUS_SUCCESS)
  2074. return NTStatus;
  2075. NTStatus = CMMOB_WriteRegister(ReaderExtension, ADDR_WRITEREG_STOPBITS,
  2076. ReaderExtension->CardParameters.bStopBits);
  2077. return NTStatus;
  2078. }
  2079. /*****************************************************************************
  2080. CMMOB_CardInserted:
  2081. Sets card parameters (baudrate, stopbits)
  2082. Arguments:
  2083. ReaderExtension context of the call
  2084. Return Value:
  2085. TRUE if card is inserted
  2086. ******************************************************************************/
  2087. BOOLEAN CMMOB_CardInserted(
  2088. IN PREADER_EXTENSION ReaderExtension
  2089. )
  2090. {
  2091. NTSTATUS NTStatus=STATUS_SUCCESS;
  2092. UCHAR bReg;
  2093. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_FLAGS0,&bReg);
  2094. if (NTStatus!=STATUS_SUCCESS)
  2095. return FALSE;
  2096. /*
  2097. SmartcardDebug(DEBUG_TRACE,
  2098. ("%s!CardInserted: ReadReg Flags0 = %x\n",DRIVER_NAME, (ULONG)bReg));
  2099. */
  2100. if ((bReg & FLAG_INSERTED)==FLAG_INSERTED)
  2101. {
  2102. return TRUE;
  2103. }
  2104. return FALSE;
  2105. }
  2106. /*****************************************************************************
  2107. CMMOB_CardPowered:
  2108. Sets card parameters (baudrate, stopbits)
  2109. Arguments:
  2110. ReaderExtension context of the call
  2111. Return Value:
  2112. TRUE if card is powered
  2113. ******************************************************************************/
  2114. BOOLEAN CMMOB_CardPowered(
  2115. IN PREADER_EXTENSION ReaderExtension
  2116. )
  2117. {
  2118. NTSTATUS NTStatus=STATUS_SUCCESS;
  2119. UCHAR bReg;
  2120. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_FLAGS0,&bReg);
  2121. if (NTStatus!=STATUS_SUCCESS)
  2122. return FALSE;
  2123. if ((bReg & FLAG_POWERED)==FLAG_POWERED)
  2124. {
  2125. return TRUE;
  2126. }
  2127. return FALSE;
  2128. }
  2129. /*****************************************************************************
  2130. CMMOB_ProcedureReceived:
  2131. Arguments:
  2132. ReaderExtension context of the call
  2133. Return Value:
  2134. TRUE if a procedure byte has been received
  2135. ******************************************************************************/
  2136. BOOLEAN CMMOB_ProcedureReceived(
  2137. IN PREADER_EXTENSION ReaderExtension
  2138. )
  2139. {
  2140. NTSTATUS NTStatus=STATUS_SUCCESS;
  2141. UCHAR bReg;
  2142. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_FLAGS1,&bReg);
  2143. if (NTStatus!=STATUS_SUCCESS)
  2144. return FALSE;
  2145. if ((bReg & FLAG_NOPROCEDURE_RECEIVED)!=FLAG_NOPROCEDURE_RECEIVED)
  2146. {
  2147. return TRUE;
  2148. }
  2149. return FALSE;
  2150. }
  2151. /*****************************************************************************
  2152. CMMOB_GetReceiveFlag:
  2153. Arguments:
  2154. ReaderExtension context of the call
  2155. Return Value:
  2156. TRUE if a receive flag is set
  2157. ******************************************************************************/
  2158. BOOLEAN CMMOB_GetReceiveFlag(
  2159. IN PREADER_EXTENSION ReaderExtension
  2160. )
  2161. {
  2162. NTSTATUS NTStatus=STATUS_SUCCESS;
  2163. UCHAR bReg;
  2164. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_FLAGS0,&bReg);
  2165. /*
  2166. SmartcardDebug(DEBUG_TRACE,
  2167. ("%s!GetReceiveFlag: ReadReg Flags0 = %x\n",DRIVER_NAME, (ULONG)bReg));
  2168. */
  2169. if (NTStatus!=STATUS_SUCCESS)
  2170. return FALSE;
  2171. if ((bReg & FLAG_RECEIVE)==FLAG_RECEIVE)
  2172. {
  2173. return TRUE;
  2174. }
  2175. return FALSE;
  2176. }
  2177. /*****************************************************************************
  2178. CMMOB_GetProcedureByte:
  2179. Reads how many bytes are already received from the card by the reader
  2180. Arguments:
  2181. ReaderExtension context of the call
  2182. Return Value:
  2183. NTStatus
  2184. ******************************************************************************/
  2185. NTSTATUS CMMOB_GetProcedureByte(
  2186. IN PREADER_EXTENSION ReaderExtension,
  2187. OUT PUCHAR pbProcedureByte
  2188. )
  2189. {
  2190. NTSTATUS NTStatus = STATUS_SUCCESS;
  2191. UCHAR bReg;
  2192. UCHAR bRegPrevious;
  2193. do
  2194. {
  2195. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_LASTPROCEDURE_T0,&bRegPrevious);
  2196. if (NTStatus!=STATUS_SUCCESS)
  2197. return NTStatus;
  2198. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_LASTPROCEDURE_T0,&bReg);
  2199. if (NTStatus!=STATUS_SUCCESS)
  2200. return NTStatus;
  2201. }
  2202. while (bReg!=bRegPrevious);
  2203. *pbProcedureByte=bReg;
  2204. return NTStatus;
  2205. }
  2206. /*****************************************************************************
  2207. CMMOB_WriteT0:
  2208. Writes T0 request to card
  2209. Arguments:
  2210. ReaderExtension context of the call
  2211. Return Value:
  2212. NT STATUS
  2213. ******************************************************************************/
  2214. NTSTATUS CMMOB_WriteT0(
  2215. IN PREADER_EXTENSION ReaderExtension,
  2216. IN ULONG ulBytesToWrite,
  2217. IN ULONG ulBytesToReceive,
  2218. IN PUCHAR pbData
  2219. )
  2220. {
  2221. NTSTATUS NTStatus = STATUS_SUCCESS;
  2222. UCHAR bFlags0;
  2223. UCHAR bReg;
  2224. if (ulBytesToWrite > CMMOB_MAXBUFFER)
  2225. {
  2226. NTStatus = STATUS_BUFFER_OVERFLOW;
  2227. return NTStatus;
  2228. }
  2229. // dummy read, to reset flag procedure received
  2230. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_FLAGS1,&bReg);
  2231. NTStatus = CMMOB_WriteBuffer(ReaderExtension,ulBytesToWrite,pbData);
  2232. if (NTStatus != STATUS_SUCCESS)
  2233. return NTStatus;
  2234. // write instruction byte to register
  2235. NTStatus = CMMOB_WriteRegister(ReaderExtension,ADDR_WRITEREG_PROCEDURE_T0,pbData[1]);
  2236. if (NTStatus != STATUS_SUCCESS)
  2237. return NTStatus;
  2238. // write message length
  2239. NTStatus = CMMOB_WriteRegister(ReaderExtension,ADDR_WRITEREG_MESSAGE_LENGTH,
  2240. (UCHAR)((ulBytesToWrite+ulBytesToReceive) & 0xFF));
  2241. if (NTStatus != STATUS_SUCCESS)
  2242. return NTStatus;
  2243. if ((ulBytesToWrite+ulBytesToReceive) > 0xFF)
  2244. {
  2245. bFlags0=1;
  2246. }
  2247. else
  2248. {
  2249. bFlags0=0;
  2250. }
  2251. bFlags0 |= CMD_WRITE_T0;
  2252. NTStatus = CMMOB_WriteRegister(ReaderExtension,ADDR_WRITEREG_FLAGS0,bFlags0);
  2253. return NTStatus;
  2254. }
  2255. /*****************************************************************************
  2256. CMMOB_WriteT1:
  2257. Writes T1 request to card
  2258. Arguments:
  2259. ReaderExtension context of the call
  2260. Return Value:
  2261. NT STATUS
  2262. ******************************************************************************/
  2263. NTSTATUS CMMOB_WriteT1(
  2264. IN PREADER_EXTENSION ReaderExtension,
  2265. IN ULONG ulBytesToWrite,
  2266. IN PUCHAR pbData
  2267. )
  2268. {
  2269. NTSTATUS NTStatus = STATUS_SUCCESS;
  2270. UCHAR bFlags0;
  2271. if (ulBytesToWrite > CMMOB_MAXBUFFER)
  2272. {
  2273. NTStatus = STATUS_BUFFER_OVERFLOW;
  2274. return NTStatus;
  2275. }
  2276. NTStatus = CMMOB_WriteBuffer(ReaderExtension,ulBytesToWrite,pbData);
  2277. if (NTStatus != STATUS_SUCCESS)
  2278. return NTStatus;
  2279. NTStatus = CMMOB_WriteRegister(ReaderExtension,ADDR_WRITEREG_MESSAGE_LENGTH,
  2280. (UCHAR)(ulBytesToWrite & 0xFF));
  2281. if (NTStatus != STATUS_SUCCESS)
  2282. return NTStatus;
  2283. if (ulBytesToWrite > 0xFF)
  2284. {
  2285. bFlags0=1;
  2286. }
  2287. else
  2288. {
  2289. bFlags0=0;
  2290. }
  2291. bFlags0 |= CMD_WRITE_T1;
  2292. NTStatus = CMMOB_WriteRegister(ReaderExtension,ADDR_WRITEREG_FLAGS0,bFlags0);
  2293. return NTStatus;
  2294. }
  2295. /*****************************************************************************
  2296. CMMOB_ReadT0:
  2297. Reads T0 reply from card
  2298. Arguments:
  2299. ReaderExtension context of the call
  2300. Return Value:
  2301. NT STATUS
  2302. ******************************************************************************/
  2303. NTSTATUS CMMOB_ReadT0(
  2304. IN PREADER_EXTENSION ReaderExtension,
  2305. IN ULONG ulBytesToRead,
  2306. IN ULONG ulBytesSent,
  2307. IN ULONG ulCWT,
  2308. OUT PUCHAR pbData,
  2309. OUT PULONG pulBytesRead,
  2310. OUT PBOOLEAN pfDataSent
  2311. )
  2312. {
  2313. NTSTATUS NTStatus = STATUS_SUCCESS;
  2314. KTIMER TimerWait;
  2315. ULONG ulBytesReceived;
  2316. ULONG ulBytesReceivedPrevious;
  2317. LARGE_INTEGER liWaitTime;
  2318. BOOLEAN fTimeExpired;
  2319. BOOLEAN fProcedureReceived;
  2320. BOOLEAN fTransmissionFinished;
  2321. UCHAR bProcedureByte=0;
  2322. SmartcardDebug(DEBUG_TRACE,
  2323. ("%s!ReadT0: Enter BytesToRead = %li\n",DRIVER_NAME,ulBytesToRead));
  2324. //initialize Timer
  2325. KeInitializeTimer(&TimerWait);
  2326. liWaitTime = RtlConvertLongToLargeInteger(ulCWT * -10000L);
  2327. *pulBytesRead = 0;
  2328. *pfDataSent = FALSE;
  2329. do
  2330. {
  2331. KeSetTimer(&TimerWait,liWaitTime,NULL);
  2332. NTStatus=CMMOB_BytesReceived (ReaderExtension,&ulBytesReceivedPrevious);
  2333. if (NTStatus!=STATUS_SUCCESS)
  2334. goto ExitReadT0;
  2335. do
  2336. {
  2337. fTimeExpired = KeReadStateTimer(&TimerWait);
  2338. fTransmissionFinished=CMMOB_GetReceiveFlag(ReaderExtension);
  2339. fProcedureReceived=CMMOB_ProcedureReceived(ReaderExtension);
  2340. NTStatus=CMMOB_BytesReceived (ReaderExtension,&ulBytesReceived);
  2341. if (NTStatus!=STATUS_SUCCESS)
  2342. goto ExitReadT0;
  2343. // wait 1 ms, so that processor is not blocked
  2344. SysDelay(1);
  2345. }
  2346. while (fTimeExpired==FALSE &&
  2347. fProcedureReceived==FALSE &&
  2348. ulBytesReceivedPrevious == ulBytesReceived &&
  2349. fTransmissionFinished==FALSE);
  2350. if (fProcedureReceived)
  2351. {
  2352. NTStatus=CMMOB_GetProcedureByte (ReaderExtension,&bProcedureByte);
  2353. if (NTStatus!=STATUS_SUCCESS)
  2354. goto ExitReadT0;
  2355. // check for SW1
  2356. if (ReaderExtension->CardParameters.fInversRevers)
  2357. {
  2358. CMMOB_InverseBuffer(&bProcedureByte,1);
  2359. }
  2360. }
  2361. if (!fTimeExpired)
  2362. {
  2363. KeCancelTimer(&TimerWait);
  2364. }
  2365. #ifdef DBG
  2366. else
  2367. {
  2368. SmartcardDebug(DEBUG_PROTOCOL,( "%s!----------------------------------------------\n",DRIVER_NAME));
  2369. SmartcardDebug(DEBUG_PROTOCOL,( "%s!Read T0 timed out\n",DRIVER_NAME));
  2370. SmartcardDebug(DEBUG_PROTOCOL,( "%s!----------------------------------------------\n",DRIVER_NAME));
  2371. }
  2372. #endif
  2373. }
  2374. while (fTimeExpired==FALSE &&
  2375. fTransmissionFinished==FALSE);
  2376. // read once more ulBytesReceived
  2377. // this value could have changed in the meantime
  2378. NTStatus=CMMOB_BytesReceived (ReaderExtension,&ulBytesReceived);
  2379. if (NTStatus!=STATUS_SUCCESS)
  2380. goto ExitReadT0;
  2381. SmartcardDebug(DEBUG_PROTOCOL,
  2382. ("%s!ReadT0: BytesReceived = %li\n",DRIVER_NAME,ulBytesReceived));
  2383. //now we should have received a reply
  2384. NTStatus=CMMOB_ResetReader (ReaderExtension);
  2385. if (NTStatus!=STATUS_SUCCESS)
  2386. goto ExitReadT0;
  2387. // check for valid SW1
  2388. if ((bProcedureByte > 0x60 && bProcedureByte <= 0x6F) ||
  2389. (bProcedureByte >= 0x90 && bProcedureByte <= 0x9F))
  2390. {
  2391. if (ReaderExtension->CardParameters.fInversRevers)
  2392. {
  2393. CMMOB_InverseBuffer(&bProcedureByte,1);
  2394. }
  2395. if (ulBytesReceived > ulBytesSent)
  2396. {
  2397. NTStatus=CMMOB_ReadBuffer(ReaderExtension, ulBytesSent,
  2398. ulBytesReceived-ulBytesSent, pbData);
  2399. if (NTStatus==STATUS_SUCCESS)
  2400. {
  2401. // we have to insert the procedure byte (SW1)
  2402. pbData[ulBytesReceived-ulBytesSent]=pbData[ulBytesReceived-ulBytesSent-1];
  2403. pbData[ulBytesReceived-ulBytesSent-1]=bProcedureByte;
  2404. *pulBytesRead=ulBytesReceived-ulBytesSent+1;
  2405. }
  2406. if (ulBytesSent > T0_HEADER_LEN)
  2407. {
  2408. *pfDataSent = TRUE;
  2409. }
  2410. }
  2411. else
  2412. {
  2413. if (ulBytesReceived > T0_HEADER_LEN)
  2414. {
  2415. // it seems not all bytes were accepted by the card
  2416. // but we got SW1 SW2 - return only SW1 SW2
  2417. pbData[0]=bProcedureByte;
  2418. NTStatus=CMMOB_ReadBuffer(ReaderExtension, ulBytesReceived-1,
  2419. 1, &pbData[1]);
  2420. *pulBytesRead=2;
  2421. }
  2422. else
  2423. {
  2424. NTStatus = STATUS_IO_TIMEOUT;
  2425. }
  2426. }
  2427. }
  2428. else
  2429. {
  2430. NTStatus = STATUS_IO_TIMEOUT;
  2431. }
  2432. ExitReadT0:
  2433. SmartcardDebug(DEBUG_TRACE,
  2434. ("%s!ReadT0: Exit\n",DRIVER_NAME ));
  2435. return NTStatus;
  2436. }
  2437. /*****************************************************************************
  2438. CMMOB_ReadT1:
  2439. Reads T1 reply from card
  2440. Arguments:
  2441. ReaderExtension context of the call
  2442. Return Value:
  2443. NT STATUS
  2444. ******************************************************************************/
  2445. NTSTATUS CMMOB_ReadT1(
  2446. IN PREADER_EXTENSION ReaderExtension,
  2447. IN LONG lBytesToRead,
  2448. IN ULONG ulBWT,
  2449. IN ULONG ulCWT,
  2450. OUT PUCHAR pbData,
  2451. OUT PULONG pulBytesRead
  2452. )
  2453. // a negative value of ulBytesToRead indicates a relative number of bytes to read
  2454. {
  2455. NTSTATUS NTStatus = STATUS_SUCCESS;
  2456. KTIMER TimerWait;
  2457. ULONG ulBytesReceived;
  2458. LARGE_INTEGER liWaitTime;
  2459. BOOLEAN fTimeExpired;
  2460. ULONG ulBytesReceivedPrevious;
  2461. /*
  2462. SmartcardDebug(DEBUG_TRACE,
  2463. ("%s!ReadT1: Enter\n",DRIVER_NAME ));
  2464. */
  2465. //initialize Timer
  2466. KeInitializeTimer(&TimerWait);
  2467. *pulBytesRead = 0;
  2468. // first wait BWT (block waiting time)
  2469. liWaitTime = RtlConvertLongToLargeInteger(ulBWT * -10000L);
  2470. do
  2471. {
  2472. KeSetTimer(&TimerWait,liWaitTime,NULL);
  2473. NTStatus=CMMOB_BytesReceived (ReaderExtension,&ulBytesReceivedPrevious);
  2474. if (NTStatus!=STATUS_SUCCESS)
  2475. goto ExitReadT1;
  2476. do
  2477. {
  2478. fTimeExpired = KeReadStateTimer(&TimerWait);
  2479. NTStatus=CMMOB_BytesReceived (ReaderExtension,&ulBytesReceived);
  2480. if (NTStatus!=STATUS_SUCCESS)
  2481. goto ExitReadT1;
  2482. // wait 1 ms, so that processor is not blocked
  2483. SysDelay(1);
  2484. // make an adjustment of lBytesToRead (only one time)
  2485. if (lBytesToRead<= 0 && ulBytesReceived >= 3)
  2486. {
  2487. // get number of bytes to receive from reader
  2488. UCHAR bReg;
  2489. UCHAR bRegPrevious;
  2490. lBytesToRead = -lBytesToRead;
  2491. do
  2492. {
  2493. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_BYTESTORECEIVE_T1,&bRegPrevious);
  2494. if (NTStatus!=STATUS_SUCCESS)
  2495. goto ExitReadT1;
  2496. NTStatus=CMMOB_ReadRegister(ReaderExtension,ADDR_READREG_BYTESTORECEIVE_T1,&bReg);
  2497. if (NTStatus!=STATUS_SUCCESS)
  2498. goto ExitReadT1;
  2499. }
  2500. while (bReg!=bRegPrevious);
  2501. lBytesToRead += bReg;
  2502. }
  2503. }
  2504. while (fTimeExpired==FALSE &&
  2505. ulBytesReceivedPrevious == ulBytesReceived &&
  2506. (lBytesToRead<=0 || ulBytesReceived!=(ULONG)lBytesToRead));
  2507. if (!fTimeExpired)
  2508. {
  2509. KeCancelTimer(&TimerWait);
  2510. liWaitTime = RtlConvertLongToLargeInteger(ulCWT * -10000L);
  2511. // now wait only CWT (character waiting time)
  2512. }
  2513. #ifdef DBG
  2514. else
  2515. {
  2516. SmartcardDebug(DEBUG_PROTOCOL,( "%s!----------------------------------------------\n",DRIVER_NAME));
  2517. SmartcardDebug(DEBUG_PROTOCOL,( "%s!Read T1 timed out\n",DRIVER_NAME));
  2518. SmartcardDebug(DEBUG_PROTOCOL,( "%s!----------------------------------------------\n",DRIVER_NAME));
  2519. }
  2520. #endif
  2521. }
  2522. while (!fTimeExpired &&
  2523. (lBytesToRead<=0 || ulBytesReceived!=(ULONG)lBytesToRead));
  2524. //now we should have received a reply
  2525. NTStatus=CMMOB_ResetReader (ReaderExtension);
  2526. if (NTStatus!=STATUS_SUCCESS)
  2527. goto ExitReadT1;
  2528. if (ulBytesReceived==(ULONG)lBytesToRead && lBytesToRead > 0)
  2529. {
  2530. NTStatus=CMMOB_ReadBuffer(ReaderExtension, 0, (ULONG)lBytesToRead, pbData);
  2531. if (NTStatus==STATUS_SUCCESS)
  2532. {
  2533. *pulBytesRead=(ULONG)lBytesToRead;
  2534. }
  2535. }
  2536. else
  2537. {
  2538. NTStatus=CMMOB_ReadBuffer(ReaderExtension, 0, ulBytesReceived, pbData);
  2539. if (NTStatus==STATUS_SUCCESS)
  2540. {
  2541. *pulBytesRead=ulBytesReceived;
  2542. }
  2543. NTStatus = STATUS_IO_TIMEOUT;
  2544. }
  2545. ExitReadT1:
  2546. /*
  2547. SmartcardDebug(DEBUG_TRACE,
  2548. ("%s!ReadT1: Exit\n",DRIVER_NAME ));
  2549. */
  2550. return NTStatus;
  2551. }
  2552. /*****************************************************************************
  2553. CMMOB_ReadRegister:
  2554. Sets card parameters (baudrate, stopbits)
  2555. Arguments:
  2556. ReaderExtension context of the call
  2557. Return Value:
  2558. NT STATUS
  2559. ******************************************************************************/
  2560. NTSTATUS CMMOB_ReadRegister(
  2561. IN PREADER_EXTENSION ReaderExtension,
  2562. IN USHORT usAddress,
  2563. OUT PUCHAR pbData
  2564. )
  2565. {
  2566. #ifdef MEMORYCARD
  2567. *pbData = READ_REGISTER_UCHAR(ReaderExtension->pbRegsBase+usAddress);
  2568. #endif
  2569. #ifdef IOCARD
  2570. *pbData = READ_PORT_UCHAR(ReaderExtension->pbRegsBase+usAddress);
  2571. #endif
  2572. return STATUS_SUCCESS;
  2573. }
  2574. /*****************************************************************************
  2575. CMMOB_WriteRegister:
  2576. Sets card parameters (baudrate, stopbits)
  2577. Arguments:
  2578. ReaderExtension context of the call
  2579. Return Value:
  2580. NT STATUS
  2581. ******************************************************************************/
  2582. NTSTATUS CMMOB_WriteRegister(
  2583. IN PREADER_EXTENSION ReaderExtension,
  2584. IN USHORT usAddress,
  2585. IN UCHAR bData
  2586. )
  2587. {
  2588. #ifdef MEMORYCARD
  2589. WRITE_REGISTER_UCHAR(ReaderExtension->pbRegsBase+usAddress,bData);
  2590. #endif
  2591. #ifdef IOCARD
  2592. WRITE_PORT_UCHAR(ReaderExtension->pbRegsBase+usAddress,bData);
  2593. #endif
  2594. return STATUS_SUCCESS;
  2595. }
  2596. /*****************************************************************************
  2597. CMMOB_ReadBuffer:
  2598. Sets card parameters (baudrate, stopbits)
  2599. Arguments:
  2600. ReaderExtension context of the call
  2601. Return Value:
  2602. NT STATUS
  2603. ******************************************************************************/
  2604. NTSTATUS CMMOB_ReadBuffer(
  2605. IN PREADER_EXTENSION ReaderExtension,
  2606. IN ULONG ulOffset,
  2607. IN ULONG ulLength,
  2608. OUT PUCHAR pbData
  2609. )
  2610. {
  2611. NTSTATUS NTStatus = STATUS_SUCCESS;
  2612. ULONG i;
  2613. #ifdef IOCARD
  2614. if ((ulOffset & 0x100) == 0x100)
  2615. {
  2616. ReaderExtension->bAddressHigh=1;
  2617. }
  2618. else
  2619. {
  2620. ReaderExtension->bAddressHigh=0;
  2621. }
  2622. NTStatus = CMMOB_SetFlags1(ReaderExtension);
  2623. if (NTStatus!=STATUS_SUCCESS)
  2624. {
  2625. goto ExitReadBuffer;
  2626. }
  2627. #endif
  2628. for (i=0; i<ulLength; i++)
  2629. {
  2630. #ifdef MEMORYCARD
  2631. *(pbData+i)=READ_REGISTER_UCHAR(ReaderExtension->pbDataBase+(2*(i+ulOffset)));
  2632. // erase buffer - required for certification
  2633. WRITE_REGISTER_UCHAR(ReaderExtension->pbDataBase+(2*(i+ulOffset)),0);
  2634. #endif
  2635. #ifdef IOCARD
  2636. WRITE_PORT_UCHAR(ReaderExtension->pbRegsBase+ADDR_WRITEREG_BUFFER_ADDR,
  2637. (BYTE)((ulOffset+i)&0xFF));
  2638. // because we are counting up in a loop we have to set
  2639. // bit 9 of address only once
  2640. if (ulOffset+i == 0x100)
  2641. {
  2642. ReaderExtension->bAddressHigh=1;
  2643. NTStatus = CMMOB_SetFlags1(ReaderExtension);
  2644. if (NTStatus!=STATUS_SUCCESS)
  2645. {
  2646. goto ExitReadBuffer;
  2647. }
  2648. }
  2649. *(pbData+i)=READ_PORT_UCHAR(ReaderExtension->pbRegsBase+ADDR_WRITEREG_BUFFER_DATA);
  2650. // erase buffer - required for certification
  2651. WRITE_PORT_UCHAR(ReaderExtension->pbRegsBase+ADDR_WRITEREG_BUFFER_DATA,0);
  2652. #endif
  2653. }
  2654. ExitReadBuffer:
  2655. return NTStatus;
  2656. }
  2657. /*****************************************************************************
  2658. CMMOB_WriteBuffer:
  2659. Sets card parameters (baudrate, stopbits)
  2660. Arguments:
  2661. ReaderExtension context of the call
  2662. Return Value:
  2663. NT STATUS
  2664. ******************************************************************************/
  2665. NTSTATUS CMMOB_WriteBuffer(
  2666. IN PREADER_EXTENSION ReaderExtension,
  2667. IN ULONG ulLength,
  2668. IN PUCHAR pbData
  2669. )
  2670. {
  2671. NTSTATUS NTStatus = STATUS_SUCCESS;
  2672. ULONG i;
  2673. #ifdef IOCARD
  2674. ReaderExtension->bAddressHigh=0;
  2675. NTStatus = CMMOB_SetFlags1(ReaderExtension);
  2676. if (NTStatus!=STATUS_SUCCESS)
  2677. {
  2678. goto ExitWriteBuffer;
  2679. }
  2680. #endif
  2681. for (i=0; i<ulLength; i++)
  2682. {
  2683. #ifdef MEMORYCARD
  2684. WRITE_REGISTER_UCHAR(ReaderExtension->pbDataBase+(2*i),*(pbData+i));
  2685. #endif
  2686. #ifdef IOCARD
  2687. WRITE_PORT_UCHAR(ReaderExtension->pbRegsBase+ADDR_WRITEREG_BUFFER_ADDR,
  2688. (BYTE)(i & 0xFF));
  2689. // because we are counting up in a loop we have to set
  2690. // bit 9 of address only once
  2691. if (i == 0x100)
  2692. {
  2693. ReaderExtension->bAddressHigh=1;
  2694. NTStatus = CMMOB_SetFlags1(ReaderExtension);
  2695. if (NTStatus!=STATUS_SUCCESS)
  2696. {
  2697. goto ExitWriteBuffer;
  2698. }
  2699. }
  2700. WRITE_PORT_UCHAR(ReaderExtension->pbRegsBase+ADDR_WRITEREG_BUFFER_DATA,*(pbData+i));
  2701. #endif
  2702. }
  2703. ExitWriteBuffer:
  2704. return NTStatus;
  2705. }
  2706. /*****************************************************************************
  2707. Routine Description:
  2708. This routine inverts the buffer
  2709. Bit0 -> Bit 7
  2710. Bit1 -> Bit 6
  2711. Bit2 -> Bit 5
  2712. Bit3 -> Bit 4
  2713. Bit4 -> Bit 3
  2714. Bit5 -> Bit 2
  2715. Bit6 -> Bit 1
  2716. Bit7 -> Bit 0
  2717. Arguments: pbBuffer ... pointer to buffer
  2718. ulBufferSize ... size of buffer
  2719. Return Value: none
  2720. *****************************************************************************/
  2721. VOID CMMOB_InverseBuffer (
  2722. PUCHAR pbBuffer,
  2723. ULONG ulBufferSize
  2724. )
  2725. {
  2726. ULONG i,j;
  2727. UCHAR bRevers;
  2728. UCHAR bTemp;
  2729. for (i=0; i<ulBufferSize; i++)
  2730. {
  2731. bRevers = 0;
  2732. for (j=0; j<8; j++)
  2733. {
  2734. bTemp = pbBuffer[i] << j;
  2735. bTemp &= 0x80;
  2736. bRevers |= bTemp >> (7-j);
  2737. }
  2738. pbBuffer[i] = ~bRevers;
  2739. }
  2740. return;
  2741. }
  2742. /*****************************************************************************
  2743. * History:
  2744. * $Log: cmbp0scr.c $
  2745. * Revision 1.7 2001/01/22 07:12:36 WFrischauf
  2746. * No comment given
  2747. *
  2748. * Revision 1.6 2000/09/25 14:24:31 WFrischauf
  2749. * No comment given
  2750. *
  2751. * Revision 1.5 2000/08/24 09:05:13 TBruendl
  2752. * No comment given
  2753. *
  2754. * Revision 1.4 2000/08/09 12:45:57 WFrischauf
  2755. * No comment given
  2756. *
  2757. * Revision 1.3 2000/07/27 13:53:03 WFrischauf
  2758. * No comment given
  2759. *
  2760. *
  2761. ******************************************************************************/