Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

957 lines
28 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) SCM Microsystems, 1998 - 1999
  6. //
  7. // File: cbhndlr.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #if defined( SMCLIB_VXD )
  11. #include "Driver98.h"
  12. #else
  13. #include "DriverNT.h"
  14. #endif
  15. #include "SerialIF.h"
  16. #include "STCCmd.h"
  17. #include "CBHndlr.h"
  18. #include "T0Hndlr.h"
  19. NTSTATUS
  20. CBCardPower(
  21. PSMARTCARD_EXTENSION SmartcardExtension
  22. )
  23. /*++
  24. CBCardPower:
  25. callback handler for SMCLIB RDF_CARD_POWER
  26. Arguments:
  27. SmartcardExtension context of call
  28. Return Value:
  29. STATUS_SUCCESS
  30. STATUS_NO_MEDIA
  31. STATUS_TIMEOUT
  32. STATUS_BUFFER_TOO_SMALL
  33. --*/
  34. {
  35. NTSTATUS NTStatus = STATUS_SUCCESS;
  36. UCHAR ATRBuffer[ ATR_SIZE ];
  37. ULONG ATRLength;
  38. PREADER_EXTENSION ReaderExtension;
  39. KIRQL irql;
  40. SERIAL_TIMEOUTS Timeouts;
  41. SmartcardDebug( DEBUG_TRACE, ("SCMSTCS!CBCardPower Enter\n" ));
  42. ReaderExtension = SmartcardExtension->ReaderExtension;
  43. // discard old ATR
  44. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  45. SmartcardExtension->CardCapabilities.Protocol.Selected =
  46. SCARD_PROTOCOL_UNDEFINED;
  47. // set standard timeouts for the worker thread
  48. Timeouts.ReadIntervalTimeout = SR_READ_INTERVAL_TIMEOUT;
  49. Timeouts.ReadTotalTimeoutConstant = SR_READ_TOTAL_TIMEOUT_CONSTANT;
  50. Timeouts.ReadTotalTimeoutMultiplier = 0;
  51. Timeouts.WriteTotalTimeoutConstant = SR_WRITE_TOTAL_TIMEOUT_CONSTANT;
  52. Timeouts.WriteTotalTimeoutMultiplier = 0;
  53. NTStatus = IFSerialIoctl(
  54. ReaderExtension,
  55. IOCTL_SERIAL_SET_TIMEOUTS,
  56. &Timeouts,
  57. sizeof(Timeouts),
  58. NULL,
  59. 0
  60. );
  61. ASSERT(NTStatus == STATUS_SUCCESS);
  62. // set the ATR timeout in milli sec
  63. ReaderExtension->ReadTimeout = 1500;
  64. switch (SmartcardExtension->MinorIoControlCode)
  65. {
  66. case SCARD_WARM_RESET:
  67. // if the card was not powerd, fall through to cold reset
  68. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  69. &irql);
  70. if( SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_SWALLOWED )
  71. {
  72. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  73. irql);
  74. // reset the card
  75. ATRLength = ATR_SIZE;
  76. NTStatus = STCReset(
  77. ReaderExtension,
  78. 0, // not used: ReaderExtension->Device,
  79. TRUE, // warm reset
  80. ATRBuffer,
  81. &ATRLength
  82. );
  83. break;
  84. } else {
  85. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  86. irql);
  87. }
  88. // warm reset not possible because card was not powerd
  89. case SCARD_COLD_RESET:
  90. // reset the card
  91. ATRLength = ATR_SIZE;
  92. NTStatus = STCReset(
  93. ReaderExtension,
  94. 0, // not used: ReaderExtension->Device,
  95. FALSE, // cold reset
  96. ATRBuffer,
  97. &ATRLength
  98. );
  99. break;
  100. case SCARD_POWER_DOWN:
  101. // discard old card status
  102. ATRLength = 0;
  103. STCPowerOff( ReaderExtension );
  104. NTStatus = STATUS_SUCCESS;
  105. CBUpdateCardState( SmartcardExtension, SCARD_PRESENT );
  106. break;
  107. }
  108. // finish the request
  109. if( NTStatus == STATUS_SUCCESS )
  110. {
  111. // update all neccessary data if an ATR was received
  112. if( ATRLength > 2 )
  113. {
  114. // copy ATR to user buffer buffer
  115. if( ATRLength <= SmartcardExtension->IoRequest.ReplyBufferLength )
  116. {
  117. SysCopyMemory(
  118. SmartcardExtension->IoRequest.ReplyBuffer,
  119. ATRBuffer,
  120. ATRLength
  121. );
  122. *SmartcardExtension->IoRequest.Information = ATRLength;
  123. }
  124. else
  125. {
  126. NTStatus = STATUS_BUFFER_TOO_SMALL;
  127. }
  128. // copy ATR to card capability buffer
  129. if( ATRLength <= MAXIMUM_ATR_LENGTH )
  130. {
  131. SysCopyMemory(
  132. SmartcardExtension->CardCapabilities.ATR.Buffer,
  133. ATRBuffer,
  134. ATRLength
  135. );
  136. SmartcardExtension->CardCapabilities.ATR.Length =
  137. (UCHAR)ATRLength;
  138. // let the lib update the card capabilities
  139. NTStatus = SmartcardUpdateCardCapabilities(
  140. SmartcardExtension
  141. );
  142. }
  143. else
  144. {
  145. NTStatus = STATUS_BUFFER_TOO_SMALL;
  146. }
  147. if( NTStatus == STATUS_SUCCESS )
  148. {
  149. ULONG minWaitTime;
  150. // set the stc registers
  151. CBSynchronizeSTC( SmartcardExtension );
  152. // now set the new - card specific - timeouts
  153. if( SmartcardExtension->CardCapabilities.Protocol.Selected ==
  154. SCARD_PROTOCOL_T1 )
  155. {
  156. ReaderExtension->ReadTimeout =
  157. Timeouts.ReadTotalTimeoutConstant =
  158. SmartcardExtension->CardCapabilities.T1.BWT / 1000;
  159. Timeouts.ReadIntervalTimeout =
  160. SmartcardExtension->CardCapabilities.T1.CWT / 1000;
  161. }
  162. else
  163. {
  164. ReaderExtension->ReadTimeout =
  165. Timeouts.ReadIntervalTimeout =
  166. Timeouts.ReadTotalTimeoutConstant =
  167. SmartcardExtension->CardCapabilities.T0.WT / 1000 * 5;
  168. }
  169. minWaitTime = (KeQueryTimeIncrement() / 10000) * 5;
  170. if (Timeouts.ReadTotalTimeoutConstant < minWaitTime) {
  171. Timeouts.ReadTotalTimeoutConstant = minWaitTime;
  172. }
  173. if (Timeouts.ReadIntervalTimeout < minWaitTime) {
  174. Timeouts.ReadIntervalTimeout = minWaitTime;
  175. }
  176. if (ReaderExtension->ReadTimeout < minWaitTime) {
  177. ReaderExtension->ReadTimeout = minWaitTime;
  178. }
  179. // set standard timeouts for the worker thread
  180. Timeouts.ReadTotalTimeoutMultiplier = 0;
  181. NTStatus = IFSerialIoctl(
  182. ReaderExtension,
  183. IOCTL_SERIAL_SET_TIMEOUTS,
  184. &Timeouts,
  185. sizeof(Timeouts),
  186. NULL,
  187. 0
  188. );
  189. ASSERT(NTStatus == STATUS_SUCCESS);
  190. }
  191. }
  192. }
  193. SmartcardDebug(
  194. DEBUG_TRACE,
  195. ( "SCMSTCS!CBCardPower Exit: %X\n",
  196. NTStatus )
  197. );
  198. return( NTStatus );
  199. }
  200. NTSTATUS
  201. CBSetProtocol(
  202. PSMARTCARD_EXTENSION SmartcardExtension
  203. )
  204. /*++
  205. CBSetProtocol:
  206. callback handler for SMCLIB RDF_SET_PROTOCOL
  207. Arguments:
  208. SmartcardExtension context of call
  209. Return Value:
  210. STATUS_SUCCESS
  211. STATUS_NO_MEDIA
  212. STATUS_TIMEOUT
  213. STATUS_BUFFER_TOO_SMALL
  214. STATUS_INVALID_DEVICE_STATE
  215. STATUS_INVALID_DEVICE_REQUEST
  216. --*/
  217. {
  218. NTSTATUS NTStatus = STATUS_PENDING;
  219. UCHAR PTSRequest[5], PTSReply[5];
  220. ULONG NewProtocol;
  221. PREADER_EXTENSION ReaderExtension;
  222. KIRQL irql;
  223. SmartcardDebug( DEBUG_TRACE, ("SCMSTCS!CBSetProtocol Enter\n" ));
  224. ReaderExtension = SmartcardExtension->ReaderExtension;
  225. NewProtocol = SmartcardExtension->MinorIoControlCode;
  226. // check if the card is already in specific state
  227. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  228. &irql);
  229. if( ( SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC ) &&
  230. ( SmartcardExtension->CardCapabilities.Protocol.Selected & NewProtocol ))
  231. {
  232. NTStatus = STATUS_SUCCESS;
  233. }
  234. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  235. irql);
  236. // protocol supported?
  237. if( !( SmartcardExtension->CardCapabilities.Protocol.Supported & NewProtocol ) ||
  238. !( SmartcardExtension->ReaderCapabilities.SupportedProtocols & NewProtocol ))
  239. {
  240. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  241. }
  242. // send PTS
  243. while( NTStatus == STATUS_PENDING )
  244. {
  245. // set initial character of PTS
  246. PTSRequest[0] = 0xFF;
  247. // set the format character
  248. if( NewProtocol & SCARD_PROTOCOL_T1 )
  249. {
  250. PTSRequest[1] = 0x11;
  251. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;
  252. }
  253. else
  254. {
  255. PTSRequest[1] = 0x10;
  256. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  257. }
  258. // PTS1 codes Fl and Dl
  259. PTSRequest[2] =
  260. SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  261. SmartcardExtension->CardCapabilities.PtsData.Dl;
  262. // check character
  263. PTSRequest[3] = PTSRequest[0] ^ PTSRequest[1] ^ PTSRequest[2];
  264. // write PTSRequest
  265. NTStatus = STCWriteICC1( ReaderExtension, PTSRequest, 4 );
  266. // get response
  267. if( NTStatus == STATUS_SUCCESS )
  268. {
  269. ULONG BufferLength = sizeof(PTSReply);
  270. NTStatus = STCReadICC1(
  271. ReaderExtension,
  272. PTSReply,
  273. &BufferLength,
  274. 4
  275. );
  276. if(( NTStatus == STATUS_SUCCESS ) && !SysCompareMemory( PTSRequest, PTSReply, 4))
  277. {
  278. // set the stc registers
  279. SmartcardExtension->CardCapabilities.Dl =
  280. SmartcardExtension->CardCapabilities.PtsData.Dl;
  281. SmartcardExtension->CardCapabilities.Fl =
  282. SmartcardExtension->CardCapabilities.PtsData.Fl;
  283. CBSynchronizeSTC( SmartcardExtension );
  284. // the card replied correctly to the PTS-request
  285. break;
  286. }
  287. }
  288. //
  289. // The card did either NOT reply or it replied incorrectly
  290. // so try default values
  291. //
  292. SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_DEFAULT;
  293. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  294. NTStatus = CBCardPower( SmartcardExtension );
  295. if( NTStatus == STATUS_SUCCESS )
  296. {
  297. NTStatus = STATUS_PENDING;
  298. }
  299. else
  300. {
  301. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  302. }
  303. }
  304. if( NTStatus == STATUS_TIMEOUT )
  305. {
  306. NTStatus = STATUS_IO_TIMEOUT;
  307. }
  308. if( NTStatus == STATUS_SUCCESS )
  309. {
  310. ULONG minWaitTime;
  311. SERIAL_TIMEOUTS Timeouts;
  312. if( SmartcardExtension->CardCapabilities.Protocol.Selected ==
  313. SCARD_PROTOCOL_T1 )
  314. {
  315. ReaderExtension->ReadTimeout =
  316. Timeouts.ReadTotalTimeoutConstant =
  317. SmartcardExtension->CardCapabilities.T1.BWT / 1000;
  318. Timeouts.ReadIntervalTimeout =
  319. SmartcardExtension->CardCapabilities.T1.CWT / 1000;
  320. }
  321. else
  322. {
  323. ReaderExtension->ReadTimeout =
  324. Timeouts.ReadIntervalTimeout =
  325. Timeouts.ReadTotalTimeoutConstant =
  326. SmartcardExtension->CardCapabilities.T0.WT / 1000 * 5;
  327. }
  328. minWaitTime = (KeQueryTimeIncrement() / 10000) * 5;
  329. if (Timeouts.ReadTotalTimeoutConstant < minWaitTime) {
  330. Timeouts.ReadTotalTimeoutConstant = minWaitTime;
  331. }
  332. if (Timeouts.ReadIntervalTimeout < minWaitTime) {
  333. Timeouts.ReadIntervalTimeout = minWaitTime;
  334. }
  335. if (ReaderExtension->ReadTimeout < minWaitTime) {
  336. ReaderExtension->ReadTimeout = minWaitTime;
  337. }
  338. Timeouts.WriteTotalTimeoutConstant = SR_WRITE_TOTAL_TIMEOUT_CONSTANT;
  339. Timeouts.WriteTotalTimeoutMultiplier = 0;
  340. Timeouts.ReadTotalTimeoutMultiplier = 0;
  341. NTStatus = IFSerialIoctl(
  342. ReaderExtension,
  343. IOCTL_SERIAL_SET_TIMEOUTS,
  344. &Timeouts,
  345. sizeof(Timeouts),
  346. NULL,
  347. 0
  348. );
  349. ASSERT(NTStatus == STATUS_SUCCESS);
  350. // indicate that the card is in specific mode
  351. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  352. &irql);
  353. SmartcardExtension->ReaderCapabilities.CurrentState =
  354. SCARD_SPECIFIC;
  355. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  356. irql);
  357. // return the selected protocol to the caller
  358. *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer =
  359. SmartcardExtension->CardCapabilities.Protocol.Selected;
  360. *SmartcardExtension->IoRequest.Information =
  361. sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
  362. }
  363. else
  364. {
  365. SmartcardExtension->CardCapabilities.Protocol.Selected =
  366. SCARD_PROTOCOL_UNDEFINED;
  367. *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer = 0;
  368. *SmartcardExtension->IoRequest.Information = 0;
  369. }
  370. SmartcardDebug( DEBUG_TRACE, ("SCMSTCS!CBSetProtocol: Exit %X\n", NTStatus ));
  371. return( NTStatus );
  372. }
  373. NTSTATUS
  374. CBTransmit(
  375. PSMARTCARD_EXTENSION SmartcardExtension
  376. )
  377. /*++
  378. CBTransmit:
  379. callback handler for SMCLIB RDF_TRANSMIT
  380. Arguments:
  381. SmartcardExtension context of call
  382. Return Value:
  383. STATUS_SUCCESS
  384. STATUS_NO_MEDIA
  385. STATUS_TIMEOUT
  386. STATUS_INVALID_DEVICE_REQUEST
  387. --*/
  388. {
  389. NTSTATUS NTStatus = STATUS_SUCCESS;
  390. SmartcardDebug( DEBUG_TRACE, ("SCMSTCS!CBTransmit Enter\n" ));
  391. // dispatch on the selected protocol
  392. switch( SmartcardExtension->CardCapabilities.Protocol.Selected )
  393. {
  394. case SCARD_PROTOCOL_T0:
  395. NTStatus = CBT0Transmit( SmartcardExtension );
  396. break;
  397. case SCARD_PROTOCOL_T1:
  398. NTStatus = CBT1Transmit( SmartcardExtension );
  399. break;
  400. case SCARD_PROTOCOL_RAW:
  401. NTStatus = CBRawTransmit( SmartcardExtension );
  402. break;
  403. default:
  404. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  405. break;
  406. }
  407. SmartcardDebug( DEBUG_TRACE, ("SCMSTCS!CBTransmit Exit: %X\n", NTStatus ));
  408. return( NTStatus );
  409. }
  410. NTSTATUS
  411. CBT0Transmit(
  412. PSMARTCARD_EXTENSION SmartcardExtension
  413. )
  414. /*++
  415. CBT0Transmit:
  416. finishes the callback RDF_TRANSMIT for the T0 protocol
  417. Arguments:
  418. SmartcardExtension context of call
  419. Return Value:
  420. STATUS_SUCCESS
  421. STATUS_NO_MEDIA
  422. STATUS_TIMEOUT
  423. STATUS_INVALID_DEVICE_REQUEST
  424. --*/
  425. {
  426. NTSTATUS NTStatus = STATUS_SUCCESS;
  427. SmartcardDebug( DEBUG_TRACE, ("SCMSTCS!CBT0Transmit Enter\n" ));
  428. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  429. SmartcardExtension->SmartcardReply.BufferLength =
  430. SmartcardExtension->SmartcardReply.BufferSize;
  431. // let the lib setup the T=1 APDU & check for errors
  432. NTStatus = SmartcardT0Request( SmartcardExtension );
  433. if( NTStatus == STATUS_SUCCESS )
  434. {
  435. NTStatus = T0_ExchangeData(
  436. SmartcardExtension->ReaderExtension,
  437. SmartcardExtension->SmartcardRequest.Buffer,
  438. SmartcardExtension->SmartcardRequest.BufferLength,
  439. SmartcardExtension->SmartcardReply.Buffer,
  440. &SmartcardExtension->SmartcardReply.BufferLength
  441. );
  442. if( NTStatus == STATUS_SUCCESS )
  443. {
  444. // let the lib evaluate the result & tansfer the data
  445. NTStatus = SmartcardT0Reply( SmartcardExtension );
  446. }
  447. }
  448. SmartcardDebug( DEBUG_TRACE,("SCMSTCS!CBT0Transmit Exit: %X\n", NTStatus ));
  449. return( NTStatus );
  450. }
  451. NTSTATUS
  452. CBT1Transmit(
  453. PSMARTCARD_EXTENSION SmartcardExtension
  454. )
  455. /*++
  456. CBT1Transmit:
  457. finishes the callback RDF_TRANSMIT for the T1 protocol
  458. Arguments:
  459. SmartcardExtension context of call
  460. Return Value:
  461. STATUS_SUCCESS
  462. STATUS_NO_MEDIA
  463. STATUS_TIMEOUT
  464. STATUS_INVALID_DEVICE_REQUEST
  465. --*/
  466. {
  467. NTSTATUS NTStatus = STATUS_SUCCESS;
  468. ULONG BufferLength,AlreadyRead;
  469. SmartcardDebug( DEBUG_TRACE, ("SCMSTCS!CBT1Transmit Enter\n" ));
  470. //KJ
  471. RtlZeroMemory( SmartcardExtension->SmartcardReply.Buffer,
  472. sizeof(SmartcardExtension->SmartcardReply.Buffer));
  473. // use the lib support to construct the T=1 packets
  474. do {
  475. // no header for the T=1 protocol
  476. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  477. SmartcardExtension->T1.NAD = 0;
  478. // let the lib setup the T=1 APDU & check for errors
  479. NTStatus = SmartcardT1Request( SmartcardExtension );
  480. if( NTStatus == STATUS_SUCCESS )
  481. {
  482. // send command (don't calculate LRC because CRC may be used!)
  483. NTStatus = STCWriteICC1(
  484. SmartcardExtension->ReaderExtension,
  485. SmartcardExtension->SmartcardRequest.Buffer,
  486. SmartcardExtension->SmartcardRequest.BufferLength
  487. );
  488. //
  489. // extend the timeout if a Wtx request was sent by the card. if the
  490. // card responds before the waiting time extension expires, the data are
  491. // buffered in the reader. A delay without polling the reader status
  492. // slows down the performance of the driver, but wtx is an exeption,
  493. // not the rule.
  494. //
  495. if (SmartcardExtension->T1.Wtx)
  496. {
  497. SysDelay(
  498. (( SmartcardExtension->T1.Wtx *
  499. SmartcardExtension->CardCapabilities.T1.BWT + 999L )/
  500. 1000L)
  501. );
  502. }
  503. // get response
  504. SmartcardExtension->SmartcardReply.BufferLength = 0;
  505. if( NTStatus == STATUS_SUCCESS )
  506. {
  507. BufferLength = SmartcardExtension->SmartcardReply.BufferSize;
  508. NTStatus = STCReadICC1(
  509. SmartcardExtension->ReaderExtension,
  510. SmartcardExtension->SmartcardReply.Buffer,
  511. &BufferLength,
  512. 3
  513. );
  514. // if we have read more then 3 bytes
  515. if(BufferLength > 3)
  516. {
  517. AlreadyRead = BufferLength - 3;
  518. }
  519. else
  520. {
  521. AlreadyRead = 0;
  522. }
  523. if( NTStatus == STATUS_SUCCESS )
  524. {
  525. ULONG Length;
  526. Length = (ULONG)SmartcardExtension->SmartcardReply.Buffer[ LEN_IDX ] + 1;
  527. if( Length + 3 < MIN_BUFFER_SIZE )
  528. {
  529. BufferLength =
  530. SmartcardExtension->SmartcardReply.BufferSize -
  531. AlreadyRead - DATA_IDX;
  532. NTStatus = STCReadICC1(
  533. SmartcardExtension->ReaderExtension,
  534. (&SmartcardExtension->SmartcardReply.Buffer[ DATA_IDX ]) + AlreadyRead,
  535. &BufferLength,
  536. Length-AlreadyRead
  537. );
  538. SmartcardExtension->SmartcardReply.BufferLength = Length + 3;
  539. }
  540. else
  541. {
  542. NTStatus = STATUS_BUFFER_TOO_SMALL;
  543. }
  544. }
  545. //
  546. // if STCRead detects an LRC error, ignore it (maybe CRC used). Timeouts will
  547. // be detected by the lib if len=0
  548. //
  549. if(( NTStatus == STATUS_CRC_ERROR ) || ( NTStatus == STATUS_IO_TIMEOUT ))
  550. {
  551. NTStatus = STATUS_SUCCESS;
  552. }
  553. if( NTStatus == STATUS_SUCCESS )
  554. {
  555. // let the lib evaluate the result & setup the next APDU
  556. NTStatus = SmartcardT1Reply( SmartcardExtension );
  557. }
  558. }
  559. }
  560. // continue if the lib wants to send the next packet
  561. } while( NTStatus == STATUS_MORE_PROCESSING_REQUIRED );
  562. if( NTStatus == STATUS_IO_TIMEOUT )
  563. {
  564. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  565. }
  566. SmartcardDebug( DEBUG_TRACE,( "SCMSTCS!CBT1Transmit Exit: %X\n", NTStatus ));
  567. return ( NTStatus );
  568. }
  569. NTSTATUS
  570. CBRawTransmit(
  571. PSMARTCARD_EXTENSION SmartcardExtension
  572. )
  573. /*++
  574. CBRawTransmit:
  575. finishes the callback RDF_TRANSMIT for the RAW protocol
  576. Arguments:
  577. SmartcardExtension context of call
  578. Return Value:
  579. STATUS_SUCCESS
  580. STATUS_NO_MEDIA
  581. STATUS_TIMEOUT
  582. STATUS_INVALID_DEVICE_REQUEST
  583. --*/
  584. {
  585. NTSTATUS NTStatus = STATUS_SUCCESS;
  586. NTStatus = STATUS_UNSUCCESSFUL;
  587. SmartcardDebug( DEBUG_TRACE, ("SCMSTCS!CBRawTransmit Exit: %X\n", NTStatus ));
  588. return ( NTStatus );
  589. }
  590. NTSTATUS
  591. CBCardTracking(
  592. PSMARTCARD_EXTENSION SmartcardExtension
  593. )
  594. /*++
  595. CBCardTracking:
  596. callback handler for SMCLIB RDF_CARD_TRACKING. the requested event was
  597. validated by the smclib (i.e. a card removal request will only be passed
  598. if a card is present).
  599. for a win95 build STATUS_PENDING will be returned without any other action.
  600. for NT the cancel routine for the irp will be set to the drivers cancel
  601. routine.
  602. Arguments:
  603. SmartcardExtension context of call
  604. Return Value:
  605. STATUS_PENDING
  606. --*/
  607. {
  608. SmartcardDebug( DEBUG_TRACE, ("SCMSTCS!CBCardTracking Enter\n" ));
  609. #if defined( SMCLIB_VXD )
  610. #else
  611. {
  612. KIRQL CurrentIrql;
  613. // set cancel routine
  614. IoAcquireCancelSpinLock( &CurrentIrql );
  615. IoSetCancelRoutine(
  616. SmartcardExtension->OsData->NotificationIrp,
  617. DrvCancel
  618. );
  619. IoReleaseCancelSpinLock( CurrentIrql );
  620. }
  621. #endif
  622. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!CBCardTracking Exit\n" ));
  623. return( STATUS_PENDING );
  624. }
  625. VOID
  626. CBUpdateCardState(
  627. PSMARTCARD_EXTENSION SmartcardExtension,
  628. ULONG RequestedState
  629. )
  630. /*++
  631. CBUpdateCardState:
  632. updates the variable CurrentState in SmartcardExtension
  633. Arguments:
  634. SmartcardExtension context of call
  635. Return Value:
  636. STATUS_SUCCESS
  637. --*/
  638. {
  639. NTSTATUS NTStatus = STATUS_SUCCESS;
  640. UCHAR Status;
  641. KIRQL Irql;
  642. BOOLEAN StateChanged = FALSE;
  643. ULONG NewState = RequestedState;
  644. if (RequestedState == SCARD_UNKNOWN) {
  645. // read card state from reader
  646. NTStatus = STCReadSTCRegister(
  647. SmartcardExtension->ReaderExtension,
  648. ADR_IO_CONFIG,
  649. 1,
  650. &Status
  651. );
  652. ASSERT(NTStatus == STATUS_SUCCESS);
  653. if (NTStatus == STATUS_SUCCESS) {
  654. if ((Status & M_SD) == 0) {
  655. NewState = SCARD_ABSENT;
  656. } else {
  657. NewState = SCARD_SWALLOWED;
  658. }
  659. }
  660. }
  661. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock, &Irql);
  662. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_UNKNOWN ||
  663. SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT &&
  664. NewState <= SCARD_ABSENT ||
  665. SmartcardExtension->ReaderCapabilities.CurrentState <= SCARD_ABSENT &&
  666. NewState > SCARD_ABSENT) {
  667. StateChanged = TRUE;
  668. }
  669. if(RequestedState != SCARD_UNKNOWN ||
  670. NTStatus == STATUS_SUCCESS && StateChanged)
  671. {
  672. SmartcardExtension->ReaderCapabilities.CurrentState = NewState;
  673. }
  674. if(StateChanged && SmartcardExtension->OsData->NotificationIrp != NULL)
  675. {
  676. KIRQL CurrentIrql;
  677. IoAcquireCancelSpinLock( &CurrentIrql );
  678. IoSetCancelRoutine( SmartcardExtension->OsData->NotificationIrp, NULL );
  679. IoReleaseCancelSpinLock( CurrentIrql );
  680. SmartcardExtension->OsData->NotificationIrp->IoStatus.Status =
  681. STATUS_SUCCESS;
  682. SmartcardExtension->OsData->NotificationIrp->IoStatus.Information = 0;
  683. IoCompleteRequest(
  684. SmartcardExtension->OsData->NotificationIrp,
  685. IO_NO_INCREMENT
  686. );
  687. SmartcardExtension->OsData->NotificationIrp = NULL;
  688. }
  689. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock, Irql);
  690. }
  691. NTSTATUS
  692. CBSynchronizeSTC(
  693. PSMARTCARD_EXTENSION SmartcardExtension
  694. )
  695. /*++
  696. CBSynchronizeSTC:
  697. updates the card dependend data of the stc (wait times, ETU...)
  698. Arguments:
  699. SmartcardExtension context of call
  700. Return Value:
  701. STATUS_SUCCESS
  702. --*/
  703. {
  704. NTSTATUS NTStatus = STATUS_SUCCESS;
  705. PREADER_EXTENSION ReaderExtension;
  706. ULONG CWT,
  707. BWT,
  708. CGT,
  709. ETU;
  710. UCHAR Dl,
  711. Fl,
  712. N;
  713. PCLOCK_RATE_CONVERSION ClockRateConversion;
  714. PBIT_RATE_ADJUSTMENT BitRateAdjustment;
  715. ReaderExtension = SmartcardExtension->ReaderExtension;
  716. ClockRateConversion = SmartcardExtension->CardCapabilities.ClockRateConversion;
  717. BitRateAdjustment = SmartcardExtension->CardCapabilities.BitRateAdjustment;
  718. // cycle length
  719. Dl = SmartcardExtension->CardCapabilities.Dl;
  720. Fl = SmartcardExtension->CardCapabilities.Fl;
  721. ETU = ClockRateConversion[Fl & 0x0F].F;
  722. ETU /= BitRateAdjustment[ Dl & 0x0F ].DNumerator;
  723. ETU *= BitRateAdjustment[ Dl & 0x0F ].DDivisor;
  724. // ETU += (ETU % 2 == 0) ? 0 : 1;
  725. // a extra guard time of 0xFF means minimum delay in both directions
  726. N = SmartcardExtension->CardCapabilities.N;
  727. if( N == 0xFF )
  728. {
  729. N = 0;
  730. }
  731. // set character waiting & guard time
  732. switch ( SmartcardExtension->CardCapabilities.Protocol.Selected )
  733. {
  734. case SCARD_PROTOCOL_T0:
  735. CWT = 960 * SmartcardExtension->CardCapabilities.T0.WI;
  736. CGT = 14 + N;
  737. break;
  738. case SCARD_PROTOCOL_T1:
  739. CWT = 1000 + ( 0x01 << SmartcardExtension->CardCapabilities.T1.CWI );
  740. BWT = 11 + ( 0x01 << SmartcardExtension->CardCapabilities.T1.BWI ) * 960;
  741. CGT = 15 + N; // 12 + N; sicrypt error
  742. NTStatus = STCSetBWT( ReaderExtension, BWT * ETU );
  743. break;
  744. default:
  745. NTStatus = STATUS_UNSUCCESSFUL;
  746. break;
  747. }
  748. if(( NTStatus == STATUS_SUCCESS ) && ETU )
  749. {
  750. NTStatus = STCSetETU( ReaderExtension, ETU );
  751. if( NTStatus == STATUS_SUCCESS )
  752. {
  753. NTStatus = STCSetCGT( ReaderExtension, CGT );
  754. if( NTStatus == STATUS_SUCCESS )
  755. {
  756. NTStatus = STCSetCWT( ReaderExtension, CWT * ETU );
  757. }
  758. }
  759. }
  760. return( NTStatus );
  761. }