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.

915 lines
28 KiB

  1. /*++
  2. Copyright (c) 1997 - 1999 SCM Microsystems, Inc.
  3. Module Name:
  4. PscrCB.c
  5. Abstract:
  6. callback handler for PSCR.xxx driver
  7. Author:
  8. Andreas Straub
  9. Environment:
  10. Win 95 Sys... calls are resolved by Pscr95Wrap.asm functions and
  11. Pscr95Wrap.h macros, resp.
  12. NT 4.0 Sys... functions resolved by PscrNTWrap.c functions and
  13. PscrNTWrap.h macros, resp.
  14. Revision History:
  15. Andreas Straub 8/18/1997 1.00 Initial Version
  16. Andreas Straub 9/24/1997 1.02 Flush Interface if card tracking
  17. requested
  18. --*/
  19. #if defined( SMCLIB_VXD )
  20. #include <Pscr95.h>
  21. #else // SMCLIB_VXD
  22. #include <PscrNT.h>
  23. #endif // SMCLIB_VXD
  24. #include <PscrRdWr.h>
  25. #include <PscrCmd.h>
  26. #include <PscrCB.h>
  27. NTSTATUS
  28. CBCardPower(
  29. PSMARTCARD_EXTENSION SmartcardExtension
  30. )
  31. /*++
  32. CBCardPower:
  33. callback handler for SMCLIB RDF_CARD_POWER
  34. Arguments:
  35. SmartcardExtension context of call
  36. Return Value:
  37. STATUS_SUCCESS
  38. STATUS_NO_MEDIA
  39. STATUS_TIMEOUT
  40. STATUS_BUFFER_TOO_SMALL
  41. --*/
  42. {
  43. NTSTATUS NTStatus = STATUS_SUCCESS;
  44. UCHAR ATRBuffer[ ATR_SIZE ], TLVList[16];
  45. ULONG Command,
  46. ATRLength;
  47. PREADER_EXTENSION ReaderExtension;
  48. BYTE CardState;
  49. KIRQL irql;
  50. #if DBG || DEBUG
  51. static PCHAR request[] = { "PowerDown", "ColdReset", "WarmReset"};
  52. #endif
  53. SmartcardDebug(
  54. DEBUG_TRACE,
  55. ( "PSCR!CBCardPower: Enter, Request = %s\n",
  56. request[SmartcardExtension->MinorIoControlCode])
  57. );
  58. ReaderExtension = SmartcardExtension->ReaderExtension;
  59. //
  60. // update actual power state
  61. //
  62. Command = SmartcardExtension->MinorIoControlCode;
  63. switch ( Command ) {
  64. case SCARD_WARM_RESET:
  65. // if the card was not powerd, fall thru to cold reset
  66. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  67. &irql);
  68. if ( SmartcardExtension->ReaderCapabilities.CurrentState >
  69. SCARD_SWALLOWED ) {
  70. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  71. irql);
  72. // reset the card
  73. ATRLength = ATR_SIZE;
  74. NTStatus = CmdReset(
  75. ReaderExtension,
  76. ReaderExtension->Device,
  77. TRUE, // warm reset
  78. ATRBuffer,
  79. &ATRLength
  80. );
  81. break;
  82. } else {
  83. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  84. irql);
  85. }
  86. // warm reset not possible because card was not powerd
  87. case SCARD_COLD_RESET:
  88. // reset the card
  89. ATRLength = ATR_SIZE;
  90. NTStatus = CmdReset(
  91. ReaderExtension,
  92. ReaderExtension->Device,
  93. FALSE, // cold reset
  94. ATRBuffer,
  95. &ATRLength
  96. );
  97. break;
  98. case SCARD_POWER_DOWN:
  99. ATRLength = 0;
  100. NTStatus = CmdDeactivate(
  101. ReaderExtension,
  102. ReaderExtension->Device
  103. );
  104. // discard old card status
  105. CardState = CBGetCardState(SmartcardExtension);
  106. CBUpdateCardState(SmartcardExtension, CardState, FALSE);
  107. break;
  108. }
  109. if (NT_SUCCESS(NTStatus)) {
  110. //
  111. // Set the 'restart of work waiting time' counter for T=0
  112. // This will send a WTX request for n NULL bytes received
  113. //
  114. TLVList[0] = TAG_SET_NULL_BYTES;
  115. TLVList[1] = 1;
  116. TLVList[2] = 0x05;
  117. NTStatus = CmdSetInterfaceParameter(
  118. ReaderExtension,
  119. DEVICE_READER,
  120. TLVList,
  121. 3
  122. );
  123. }
  124. ASSERT(NT_SUCCESS(NTStatus));
  125. // finish the request
  126. if ( NT_SUCCESS( NTStatus )) {
  127. // update all neccessary data if an ATR was received
  128. if ( ATRLength > 2 ) {
  129. //
  130. // the lib expects only the ATR, so we skip the
  131. // 900x from the reader
  132. //
  133. ATRLength -= 2;
  134. // copy ATR to user buffer buffer
  135. if ( ATRLength <= SmartcardExtension->IoRequest.ReplyBufferLength ) {
  136. SysCopyMemory(
  137. SmartcardExtension->IoRequest.ReplyBuffer,
  138. ATRBuffer,
  139. ATRLength
  140. );
  141. *SmartcardExtension->IoRequest.Information = ATRLength;
  142. } else {
  143. NTStatus = STATUS_BUFFER_TOO_SMALL;
  144. }
  145. // copy ATR to card capability buffer
  146. if ( ATRLength <= MAXIMUM_ATR_LENGTH ) {
  147. SysCopyMemory(
  148. SmartcardExtension->CardCapabilities.ATR.Buffer,
  149. ATRBuffer,
  150. ATRLength
  151. );
  152. SmartcardExtension->CardCapabilities.ATR.Length =
  153. ( UCHAR )ATRLength;
  154. // let the lib update the card capabilities
  155. NTStatus = SmartcardUpdateCardCapabilities(
  156. SmartcardExtension
  157. );
  158. } else {
  159. NTStatus = STATUS_BUFFER_TOO_SMALL;
  160. }
  161. }
  162. }
  163. if ( !NT_SUCCESS( NTStatus )) {
  164. switch ( NTStatus ) {
  165. case STATUS_NO_MEDIA:
  166. case STATUS_BUFFER_TOO_SMALL:
  167. break;
  168. case STATUS_TIMEOUT:
  169. NTStatus = STATUS_IO_TIMEOUT;
  170. break;
  171. default:
  172. NTStatus = STATUS_UNRECOGNIZED_MEDIA;
  173. break;
  174. }
  175. }
  176. SmartcardDebug(
  177. DEBUG_TRACE,
  178. ( "PSCR!CBCardPower: Exit (%lx)\n", NTStatus )
  179. );
  180. return( NTStatus );
  181. }
  182. NTSTATUS
  183. CBSetProtocol(
  184. PSMARTCARD_EXTENSION SmartcardExtension
  185. )
  186. /*++
  187. CBSetProtocol:
  188. callback handler for SMCLIB RDF_SET_PROTOCOL
  189. Arguments:
  190. SmartcardExtension context of call
  191. Return Value:
  192. STATUS_SUCCESS
  193. STATUS_NO_MEDIA
  194. STATUS_TIMEOUT
  195. STATUS_BUFFER_TOO_SMALL
  196. STATUS_INVALID_DEVICE_STATE
  197. STATUS_INVALID_DEVICE_REQUEST
  198. --*/
  199. {
  200. NTSTATUS NTStatus = STATUS_PENDING;
  201. USHORT SCLibProtocol;
  202. UCHAR TLVList[ TLV_BUFFER_SIZE ];
  203. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  204. KIRQL irql;
  205. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  206. &irql);
  207. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC) {
  208. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  209. irql);
  210. return STATUS_SUCCESS;
  211. } else {
  212. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  213. irql);
  214. }
  215. SmartcardDebug(
  216. DEBUG_TRACE,
  217. ( "PSCR!CBSetProtocol: Enter\n" )
  218. );
  219. SCLibProtocol = ( USHORT )( SmartcardExtension->MinorIoControlCode );
  220. if (SCLibProtocol & (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)) {
  221. //
  222. // setup the TLV list for the Set Interface Parameter List
  223. //
  224. TLVList[ 0 ] = TAG_ICC_PROTOCOLS;
  225. TLVList[ 1 ] = 0x01;
  226. TLVList[ 2 ] =
  227. (SCLibProtocol & SCARD_PROTOCOL_T1 ? PSCR_PROTOCOL_T1 : PSCR_PROTOCOL_T0);
  228. // do the PTS
  229. NTStatus = CmdSetInterfaceParameter(
  230. ReaderExtension,
  231. ReaderExtension->Device,
  232. TLVList,
  233. 3 // size of list
  234. );
  235. } else {
  236. // we don't support other modi
  237. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  238. }
  239. // if protocol selection failed, prevent from calling invalid protocols
  240. if ( NT_SUCCESS( NTStatus )) {
  241. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  242. &irql);
  243. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  244. SCLibProtocol = (SCLibProtocol & SCARD_PROTOCOL_T1 &
  245. SmartcardExtension->CardCapabilities.Protocol.Supported) ?
  246. SCARD_PROTOCOL_T1 :
  247. SCARD_PROTOCOL_T0;
  248. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  249. irql);
  250. } else {
  251. SCLibProtocol = SCARD_PROTOCOL_UNDEFINED;
  252. }
  253. // Return the selected protocol to the caller.
  254. SmartcardExtension->CardCapabilities.Protocol.Selected = SCLibProtocol;
  255. *( PULONG )( SmartcardExtension->IoRequest.ReplyBuffer ) = SCLibProtocol;
  256. *( SmartcardExtension->IoRequest.Information ) = sizeof( ULONG );
  257. SmartcardDebug(
  258. DEBUG_TRACE,
  259. ( "PSCR!CBSetProtocol: Exit (%lx)\n", NTStatus )
  260. );
  261. return( NTStatus );
  262. }
  263. NTSTATUS
  264. CBTransmit(
  265. PSMARTCARD_EXTENSION SmartcardExtension
  266. )
  267. /*++
  268. CBTransmit:
  269. callback handler for SMCLIB RDF_TRANSMIT
  270. Arguments:
  271. SmartcardExtension context of call
  272. Return Value:
  273. STATUS_SUCCESS
  274. STATUS_NO_MEDIA
  275. STATUS_TIMEOUT
  276. STATUS_INVALID_DEVICE_REQUEST
  277. --*/
  278. {
  279. NTSTATUS NTStatus = STATUS_SUCCESS;
  280. SmartcardDebug(
  281. DEBUG_TRACE,
  282. ( "PSCR!CBTransmit: Enter\n" )
  283. );
  284. // dispatch on the selected protocol
  285. switch ( SmartcardExtension->CardCapabilities.Protocol.Selected ) {
  286. case SCARD_PROTOCOL_T0:
  287. NTStatus = CBT0Transmit( SmartcardExtension );
  288. break;
  289. case SCARD_PROTOCOL_T1:
  290. NTStatus = CBT1Transmit( SmartcardExtension );
  291. break;
  292. case SCARD_PROTOCOL_RAW:
  293. NTStatus = CBRawTransmit( SmartcardExtension );
  294. break;
  295. default:
  296. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  297. break;
  298. }
  299. SmartcardDebug(
  300. DEBUG_TRACE,
  301. ( "PSCR!CBTransmit: Exit (%lx)\n", NTStatus )
  302. );
  303. return( NTStatus );
  304. }
  305. NTSTATUS
  306. CBRawTransmit(
  307. PSMARTCARD_EXTENSION SmartcardExtension
  308. )
  309. /*++
  310. CBRawTransmit:
  311. finishes the callback RDF_TRANSMIT for the RAW protocol
  312. Arguments:
  313. SmartcardExtension context of call
  314. Return Value:
  315. STATUS_SUCCESS
  316. STATUS_NO_MEDIA
  317. STATUS_TIMEOUT
  318. STATUS_INVALID_DEVICE_REQUEST
  319. --*/
  320. {
  321. NTSTATUS NTStatus = STATUS_SUCCESS;
  322. UCHAR TLVList[ TLV_BUFFER_SIZE ],
  323. Val,
  324. Len;
  325. ULONG TLVListLen;
  326. PREADER_EXTENSION ReaderExtension;
  327. SmartcardDebug(
  328. DEBUG_TRACE,
  329. ( "PSCR!CBRawTransmit: Enter\n" )
  330. );
  331. ReaderExtension = SmartcardExtension->ReaderExtension;
  332. //
  333. // read the status file of ICC1 from the reader
  334. //
  335. TLVListLen = TLV_BUFFER_SIZE;
  336. NTStatus = CmdReadStatusFile(
  337. ReaderExtension,
  338. ReaderExtension->Device,
  339. TLVList,
  340. &TLVListLen
  341. );
  342. //
  343. // check the active protocol of the reader
  344. //
  345. if ( NT_SUCCESS( NTStatus )) {
  346. Len = sizeof(Val);
  347. NTStatus = CmdGetTagValue(
  348. TAG_ICC_PROTOCOLS,
  349. TLVList,
  350. TLVListLen,
  351. &Len,
  352. ( PVOID ) &Val
  353. );
  354. // execute the active protocol
  355. if ( NT_SUCCESS( NTStatus )) {
  356. // translate the actual protocol to a value the lib can understand
  357. switch ( Val ) {
  358. case PSCR_PROTOCOL_T0:
  359. NTStatus = CBT0Transmit( SmartcardExtension );
  360. break;
  361. case PSCR_PROTOCOL_T1:
  362. NTStatus = CBT1Transmit( SmartcardExtension );
  363. break;
  364. default:
  365. NTStatus = STATUS_UNSUCCESSFUL;
  366. break;
  367. }
  368. }
  369. }
  370. SmartcardDebug(
  371. DEBUG_TRACE,
  372. ( "PSCR!CBRawTransmit: Exit (%lx)\n", NTStatus )
  373. );
  374. return( NTStatus );
  375. }
  376. NTSTATUS
  377. CBT1Transmit(
  378. PSMARTCARD_EXTENSION SmartcardExtension
  379. )
  380. /*++
  381. CBT1Transmit:
  382. finishes the callback RDF_TRANSMIT for the T1 protocol
  383. Arguments:
  384. SmartcardExtension context of call
  385. Return Value:
  386. STATUS_SUCCESS
  387. STATUS_NO_MEDIA
  388. STATUS_TIMEOUT
  389. STATUS_INVALID_DEVICE_REQUEST
  390. --*/
  391. {
  392. NTSTATUS NTStatus = STATUS_SUCCESS;
  393. ULONG IOBytes;
  394. SmartcardDebug(
  395. DEBUG_TRACE,
  396. ( "PSCR!CBT1Transmit: Enter\n" )
  397. );
  398. //
  399. // use the lib support to construct the T=1 packets
  400. //
  401. do {
  402. //
  403. // no header for the T=1 protocol
  404. //
  405. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  406. //
  407. // SCM-TM: Siemens 4440 accepts only NAD=0!!!
  408. //
  409. SmartcardExtension->T1.NAD = 0;
  410. //
  411. // let the lib setup the T=1 APDU & check for errors
  412. //
  413. NTStatus = SmartcardT1Request( SmartcardExtension );
  414. if ( NT_SUCCESS( NTStatus )) {
  415. // send command (don't calculate LRC because CRC may be used!)
  416. IOBytes = 0;
  417. NTStatus = PscrWriteDirect(
  418. SmartcardExtension->ReaderExtension,
  419. SmartcardExtension->SmartcardRequest.Buffer,
  420. SmartcardExtension->SmartcardRequest.BufferLength,
  421. &IOBytes
  422. );
  423. //
  424. // extend the timeout if a Wtx request was sent by the card. if the
  425. // card responds before the waiting time extension expires, the data are
  426. // buffered in the reader. A delay without polling the reader status
  427. // slows down the performance of the driver, but wtx is an exeption,
  428. // not the rule.
  429. //
  430. if (SmartcardExtension->T1.Wtx) {
  431. SysDelay(
  432. (( SmartcardExtension->T1.Wtx *
  433. SmartcardExtension->CardCapabilities.T1.BWT + 999L )/
  434. 1000L)
  435. );
  436. }
  437. // get response
  438. SmartcardExtension->SmartcardReply.BufferLength = 0;
  439. NTStatus = PscrRead(
  440. SmartcardExtension->ReaderExtension,
  441. SmartcardExtension->SmartcardReply.Buffer,
  442. MAX_T1_BLOCK_SIZE,
  443. &SmartcardExtension->SmartcardReply.BufferLength
  444. );
  445. // if PscrRead detects an LRC error, ignore it (maybe CRC used)
  446. if ( NTStatus == STATUS_CRC_ERROR ) {
  447. NTStatus = STATUS_SUCCESS;
  448. }
  449. //
  450. // We even continue if the prev. read failed.
  451. // We let the smart card library continue, because it might
  452. // send a resynch. request in case of a timeout
  453. //
  454. NTStatus = SmartcardT1Reply( SmartcardExtension );
  455. }
  456. // continue if the lib wants to send the next packet
  457. } while ( NTStatus == STATUS_MORE_PROCESSING_REQUIRED );
  458. SmartcardDebug(
  459. DEBUG_TRACE,
  460. ( "PSCR!CBT1Transmit: Exit (%lx)\n", NTStatus )
  461. );
  462. return( NTStatus );
  463. }
  464. NTSTATUS
  465. CBT0Transmit(
  466. PSMARTCARD_EXTENSION SmartcardExtension
  467. )
  468. /*++
  469. CBT0Transmit:
  470. finishes the callback RDF_TRANSMIT for the T0 protocol
  471. Arguments:
  472. SmartcardExtension context of call
  473. Return Value:
  474. STATUS_SUCCESS
  475. STATUS_NO_MEDIA
  476. STATUS_TIMEOUT
  477. STATUS_INVALID_DEVICE_REQUEST
  478. --*/
  479. {
  480. NTSTATUS NTStatus = STATUS_SUCCESS;
  481. PUCHAR pRequest,pReply;
  482. ULONG IOBytes, APDULength, RequestLength;
  483. UCHAR IOData[ MAX_T1_BLOCK_SIZE ];
  484. UCHAR WtxReply[16];
  485. SmartcardDebug(
  486. DEBUG_TRACE,
  487. ( "PSCR!CBT0Transmit: Enter\n" )
  488. );
  489. pRequest = SmartcardExtension->SmartcardRequest.Buffer;
  490. pReply = SmartcardExtension->SmartcardReply.Buffer;
  491. // setup the command header
  492. pRequest[ PSCR_NAD ] =
  493. ( SmartcardExtension->ReaderExtension->Device == DEVICE_ICC1 ) ?
  494. NAD_TO_ICC1 : NAD_TO_ICC1;
  495. pRequest[ PSCR_PCB ] = PCB_DEFAULT;
  496. //
  497. // get the length of the user data packet & set the appropriate LEN
  498. // information the complete user packet consists of a SCARD_IO_REQUEST
  499. // structure followed by the APDU. the length of SCARD_IO_REQUEST is
  500. // transferred in the member cbPciLength of the structure
  501. //
  502. APDULength = SmartcardExtension->IoRequest.RequestBufferLength;
  503. APDULength -= ((PSCARD_IO_REQUEST) SmartcardExtension->
  504. IoRequest.RequestBuffer)->cbPciLength;
  505. //
  506. // a 4 byte APDU will be patched to a 5 byte TPDU by the lib; see
  507. // annex of the ISO
  508. //
  509. if ( APDULength == 4 ) APDULength++;
  510. //
  511. // if the total length of the T1 (reader) packet is larger than 0xFF
  512. // the extended length notation will be used
  513. //
  514. if ( APDULength >= 0xFF ) {
  515. pRequest[ PSCR_LEN ] = 0xFF;
  516. pRequest[ PSCR_LEN+1 ] = HIBYTE( APDULength );
  517. pRequest[ PSCR_LEN+2 ] = LOBYTE( APDULength );
  518. SmartcardExtension->SmartcardRequest.BufferLength =
  519. PSCR_EXT_PROLOGUE_LENGTH;
  520. } else {
  521. pRequest[ PSCR_LEN ] = ( UCHAR ) APDULength;
  522. SmartcardExtension->SmartcardRequest.BufferLength =
  523. PSCR_PROLOGUE_LENGTH;
  524. }
  525. // let the lib setup the T=1 APDU & check for errors
  526. NTStatus = SmartcardT0Request( SmartcardExtension );
  527. RequestLength = SmartcardExtension->SmartcardRequest.BufferLength;
  528. while ( NT_SUCCESS( NTStatus )) {
  529. // send command
  530. IOBytes = 0;
  531. NTStatus = PscrWrite(
  532. SmartcardExtension->ReaderExtension,
  533. pRequest,
  534. RequestLength,
  535. &IOBytes
  536. );
  537. // get response
  538. if ( NT_SUCCESS( NTStatus )) {
  539. IOBytes = 0;
  540. NTStatus = PscrRead(
  541. SmartcardExtension->ReaderExtension,
  542. IOData,
  543. MAX_T1_BLOCK_SIZE,
  544. &IOBytes
  545. );
  546. // extract APDU from T=1 transport packet
  547. if ( NT_SUCCESS( NTStatus )) {
  548. if (IOBytes < 4) {
  549. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  550. break;
  551. }
  552. if (IOData[ PSCR_PCB ] == WTX_REQUEST) {
  553. WtxReply[PSCR_NAD] = NAD_TO_PSCR;
  554. WtxReply[PSCR_PCB] = WTX_REPLY;
  555. WtxReply[PSCR_LEN] = 1;
  556. WtxReply[PSCR_INF] = IOData[PSCR_INF];
  557. RequestLength = 4;
  558. pRequest = WtxReply;
  559. continue;
  560. }
  561. if ( IOData[ PSCR_LEN ] == 0xFF ) {
  562. //
  563. // extended length byte used
  564. //
  565. APDULength = IOData[ PSCR_LEN + 1 ] << 8;
  566. APDULength += IOData[ PSCR_LEN + 2 ];
  567. SmartcardExtension->SmartcardReply.BufferLength = APDULength ;
  568. SysCopyMemory( pReply, &IOData[ PSCR_APDU + 2 ], APDULength );
  569. } else {
  570. if ((IOData[PSCR_LEN] > SmartcardExtension->SmartcardReply.BufferSize) ||
  571. (IOData[PSCR_LEN] > MAX_T1_BLOCK_SIZE + PSCR_APDU)) {
  572. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  573. break;
  574. }
  575. SmartcardExtension->SmartcardReply.BufferLength =
  576. IOData[ PSCR_LEN ];
  577. SysCopyMemory(
  578. pReply,
  579. &IOData[ PSCR_APDU ],
  580. IOData[ PSCR_LEN ]
  581. );
  582. }
  583. // let the lib evaluate the result & tansfer the data
  584. NTStatus = SmartcardT0Reply( SmartcardExtension );
  585. break;
  586. }
  587. }
  588. }
  589. SmartcardDebug(
  590. DEBUG_TRACE,
  591. ( "PSCR!CBT0Transmit: Exit (%lx)\n", NTStatus )
  592. );
  593. return( NTStatus );
  594. }
  595. NTSTATUS
  596. CBCardTracking(
  597. PSMARTCARD_EXTENSION SmartcardExtension
  598. )
  599. /*++
  600. CBCardTracking:
  601. callback handler for SMCLIB RDF_CARD_TRACKING. the requested event was
  602. validated by the smclib (i.e. a card removal request will only be passed
  603. if a card is present).
  604. for a win95 build STATUS_PENDING will be returned without any other action.
  605. for NT the cancel routine for the irp will be set to the drivers cancel
  606. routine.
  607. Arguments:
  608. SmartcardExtension context of call
  609. Return Value:
  610. STATUS_PENDING
  611. --*/
  612. {
  613. KIRQL CancelIrql;
  614. SmartcardDebug(
  615. DEBUG_TRACE,
  616. ( "PSCR!CBCardTracking: Enter\n" )
  617. );
  618. // set cancel routine
  619. IoAcquireCancelSpinLock( &CancelIrql );
  620. IoSetCancelRoutine(
  621. SmartcardExtension->OsData->NotificationIrp,
  622. PscrCancel
  623. );
  624. IoReleaseCancelSpinLock( CancelIrql );
  625. SmartcardDebug(
  626. DEBUG_TRACE,
  627. ( "PSCR!CBCardTracking: Exit \n" )
  628. );
  629. return( STATUS_PENDING );
  630. }
  631. VOID
  632. CBUpdateCardState(
  633. PSMARTCARD_EXTENSION SmartcardExtension,
  634. UCHAR IccState,
  635. BOOLEAN SystemWakeUp
  636. )
  637. {
  638. ULONG oldState;
  639. KIRQL currentIrql, irql;
  640. KeAcquireSpinLock(
  641. &SmartcardExtension->OsData->SpinLock,
  642. &irql
  643. );
  644. SmartcardDebug(
  645. DEBUG_TRACE,
  646. ( "PSCR!CBUpdateCardState: Enter \n" )
  647. );
  648. oldState =
  649. (SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT ?
  650. SCARD_PRESENT : SCARD_ABSENT);
  651. SmartcardExtension->ReaderCapabilities.CurrentState =
  652. (IccState == PSCR_ICC_PRESENT ? SCARD_PRESENT : SCARD_ABSENT);
  653. SmartcardDebug(
  654. DEBUG_DRIVER,
  655. ( "PSCR!CBUpdateCardState: Smart card %s\n",
  656. IccState == PSCR_ICC_PRESENT ? "inserted" : "removed")
  657. );
  658. IoAcquireCancelSpinLock( &currentIrql );
  659. if ( SmartcardExtension->OsData->NotificationIrp != NULL &&
  660. (SystemWakeUp &&
  661. (oldState == SCARD_PRESENT ||
  662. SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_PRESENT) ||
  663. SmartcardExtension->ReaderCapabilities.CurrentState != oldState)) {
  664. PIRP notificationIrp = InterlockedExchangePointer(
  665. &(SmartcardExtension->OsData->NotificationIrp),
  666. NULL
  667. );
  668. IoSetCancelRoutine(
  669. notificationIrp,
  670. NULL
  671. );
  672. IoReleaseCancelSpinLock( currentIrql );
  673. if (notificationIrp->Cancel == FALSE) {
  674. // finish the request
  675. notificationIrp->IoStatus.Status = STATUS_SUCCESS;
  676. notificationIrp->IoStatus.Information = 0;
  677. SmartcardDebug(
  678. DEBUG_DRIVER,
  679. ( "PSCR!CBUpdateCardState: Completing Irp %lx\n",
  680. notificationIrp)
  681. );
  682. IoCompleteRequest(notificationIrp, IO_NO_INCREMENT );
  683. }
  684. } else {
  685. IoReleaseCancelSpinLock( currentIrql );
  686. }
  687. SmartcardDebug(
  688. DEBUG_TRACE,
  689. ( "PSCR!CBUpdateCardState: Exit \n" )
  690. );
  691. KeReleaseSpinLock(
  692. &SmartcardExtension->OsData->SpinLock,
  693. irql
  694. );
  695. }
  696. UCHAR
  697. CBGetCardState(
  698. PSMARTCARD_EXTENSION SmartcardExtension
  699. )
  700. /*++
  701. CBUpdateCardState:
  702. updates the variable CurrentState in SmartcardExtension
  703. Arguments:
  704. SmartcardExtension context of call
  705. Return Value:
  706. STATUS_SUCCESS
  707. --*/
  708. {
  709. NTSTATUS NTStatus = STATUS_SUCCESS;
  710. UCHAR TLVList[ TLV_BUFFER_SIZE ], Val, Len;
  711. ULONG TLVListLen;
  712. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  713. // read the status file of ICC1 from the reader
  714. TLVListLen = TLV_BUFFER_SIZE;
  715. if ( NT_SUCCESS( CmdReadStatusFile(
  716. ReaderExtension,
  717. ReaderExtension->Device,
  718. TLVList,
  719. &TLVListLen
  720. ))) {
  721. // get reader status value
  722. Len = sizeof(Val);
  723. CmdGetTagValue(
  724. TAG_READER_STATUS,
  725. TLVList,
  726. TLVListLen,
  727. &Len,
  728. ( PVOID ) &Val
  729. );
  730. } else {
  731. // IO-error is interpreted as card absent
  732. Val = PSCR_ICC_ABSENT;
  733. }
  734. return Val;
  735. }
  736. // -------------------------------- END OF FILE ------------------------------