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.

1308 lines
36 KiB

  1. /*++
  2. Copyright (c) 1998 SCM Microsystems, Inc.
  3. Module Name:
  4. StcCb.c
  5. Abstract:
  6. Declaration of callback functions - WDM Version
  7. Revision History:
  8. PP 1.01 01/19/1998
  9. PP 1.00 12/18/1998 Initial Version
  10. --*/
  11. // Include
  12. #include "common.h"
  13. #include "stccmd.h"
  14. #include "stccb.h"
  15. #include "stcusbnt.h"
  16. #include "usbcom.h"
  17. NTSTATUS
  18. CBCardPower(
  19. PSMARTCARD_EXTENSION SmartcardExtension)
  20. /*++
  21. CBCardPower:
  22. callback handler for SMCLIB RDF_CARD_POWER
  23. Arguments:
  24. SmartcardExtension context of call
  25. Return Value:
  26. STATUS_SUCCESS
  27. STATUS_NO_MEDIA
  28. STATUS_TIMEOUT
  29. STATUS_BUFFER_TOO_SMALL
  30. --*/
  31. {
  32. NTSTATUS NTStatus = STATUS_SUCCESS;
  33. UCHAR ATRBuffer[ ATR_SIZE ];
  34. ULONG Command,
  35. ATRLength;
  36. PREADER_EXTENSION ReaderExtension;
  37. KIRQL irql;
  38. SmartcardDebug( DEBUG_TRACE, ("%s!CBCardPower Enter\n",DRIVER_NAME ));
  39. ReaderExtension = SmartcardExtension->ReaderExtension;
  40. // discard old ATR
  41. SysFillMemory( SmartcardExtension->CardCapabilities.ATR.Buffer, 0x00, 0x40 );
  42. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  43. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  44. Command = SmartcardExtension->MinorIoControlCode;
  45. switch ( Command )
  46. {
  47. case SCARD_WARM_RESET:
  48. // if the card was not powerd, fall through to cold reset
  49. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  50. &irql);
  51. if( SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_SWALLOWED )
  52. {
  53. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  54. irql);
  55. // reset the card
  56. ATRLength = ATR_SIZE;
  57. NTStatus = STCReset(
  58. ReaderExtension,
  59. 0, // not used: ReaderExtension->Device,
  60. TRUE, // warm reset
  61. ATRBuffer,
  62. &ATRLength);
  63. break;
  64. } else {
  65. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  66. irql);
  67. }
  68. // warm reset not possible because card was not powerd
  69. case SCARD_COLD_RESET:
  70. // reset the card
  71. ATRLength = ATR_SIZE;
  72. NTStatus = STCReset(
  73. ReaderExtension,
  74. 0, // not used: ReaderExtension->Device,
  75. FALSE, // cold reset
  76. ATRBuffer,
  77. &ATRLength);
  78. break;
  79. case SCARD_POWER_DOWN:
  80. // discard old card status
  81. ATRLength = 0;
  82. NTStatus = STCPowerOff( ReaderExtension );
  83. if(NTStatus == STATUS_SUCCESS)
  84. {
  85. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  86. &irql);
  87. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_PRESENT;
  88. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  89. irql);
  90. }
  91. break;
  92. }
  93. // finish the request
  94. if( NTStatus == STATUS_SUCCESS )
  95. {
  96. // update all neccessary data if an ATR was received
  97. if( ATRLength >= 2 )
  98. {
  99. // copy ATR to user buffer
  100. if( ATRLength <= SmartcardExtension->IoRequest.ReplyBufferLength )
  101. {
  102. SysCopyMemory(
  103. SmartcardExtension->IoRequest.ReplyBuffer,
  104. ATRBuffer,
  105. ATRLength);
  106. *SmartcardExtension->IoRequest.Information = ATRLength;
  107. }
  108. else
  109. {
  110. NTStatus = STATUS_BUFFER_TOO_SMALL;
  111. }
  112. // copy ATR to card capability buffer
  113. if( ATRLength <= MAXIMUM_ATR_LENGTH )
  114. {
  115. SysCopyMemory(
  116. SmartcardExtension->CardCapabilities.ATR.Buffer,
  117. ATRBuffer,
  118. ATRLength);
  119. SmartcardExtension->CardCapabilities.ATR.Length = ( UCHAR )ATRLength;
  120. // let the lib update the card capabilities
  121. NTStatus = SmartcardUpdateCardCapabilities( SmartcardExtension );
  122. }
  123. else
  124. {
  125. NTStatus = STATUS_BUFFER_TOO_SMALL;
  126. }
  127. if( NTStatus == STATUS_SUCCESS )
  128. {
  129. // set the stc registers
  130. CBSynchronizeSTC( SmartcardExtension );
  131. // set read timeout
  132. if( SmartcardExtension->CardCapabilities.Protocol.Selected == SCARD_PROTOCOL_T1 )
  133. {
  134. ReaderExtension->ReadTimeout =
  135. (ULONG) (SmartcardExtension->CardCapabilities.T1.BWT / 1000);
  136. }
  137. else
  138. {
  139. ReaderExtension->ReadTimeout =
  140. (ULONG) (SmartcardExtension->CardCapabilities.T0.WT / 1000);
  141. if(ReaderExtension->ReadTimeout < 50)
  142. {
  143. ReaderExtension->ReadTimeout = 50; // 50 ms minimum timeout
  144. }
  145. }
  146. }
  147. }
  148. }
  149. SmartcardDebug( DEBUG_TRACE,( "%s!CBCardPower Exit: %X\n", DRIVER_NAME,NTStatus ));
  150. return( NTStatus );
  151. }
  152. NTSTATUS
  153. CBSetProtocol(
  154. PSMARTCARD_EXTENSION SmartcardExtension
  155. )
  156. /*++
  157. CBSetProtocol:
  158. callback handler for SMCLIB RDF_SET_PROTOCOL
  159. Arguments:
  160. SmartcardExtension context of call
  161. Return Value:
  162. STATUS_SUCCESS
  163. STATUS_NO_MEDIA
  164. STATUS_TIMEOUT
  165. STATUS_BUFFER_TOO_SMALL
  166. STATUS_INVALID_DEVICE_STATE
  167. STATUS_INVALID_DEVICE_REQUEST
  168. --*/
  169. {
  170. NTSTATUS NTStatus = STATUS_PENDING;
  171. UCHAR PTSRequest[5],
  172. PTSReply[5];
  173. ULONG NewProtocol;
  174. PREADER_EXTENSION ReaderExtension;
  175. KIRQL irql;
  176. SmartcardDebug( DEBUG_TRACE, ("%s!CBSetProtocol Enter\n",DRIVER_NAME ));
  177. ReaderExtension = SmartcardExtension->ReaderExtension;
  178. NewProtocol = SmartcardExtension->MinorIoControlCode;
  179. // check if the card is already in specific state
  180. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  181. &irql);
  182. if( ( SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC ) &&
  183. ( SmartcardExtension->CardCapabilities.Protocol.Selected & NewProtocol ))
  184. {
  185. NTStatus = STATUS_SUCCESS;
  186. }
  187. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  188. irql);
  189. // protocol supported?
  190. if( !( SmartcardExtension->CardCapabilities.Protocol.Supported & NewProtocol ) ||
  191. !( SmartcardExtension->ReaderCapabilities.SupportedProtocols & NewProtocol ))
  192. {
  193. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  194. }
  195. // send PTS
  196. while( NTStatus == STATUS_PENDING )
  197. {
  198. // set initial character of PTS
  199. PTSRequest[0] = 0xFF;
  200. // set the format character
  201. if(( NewProtocol & SCARD_PROTOCOL_T1 )&&
  202. (SmartcardExtension->CardCapabilities.Protocol.Supported & SCARD_PROTOCOL_T1 ))
  203. {
  204. PTSRequest[1] = 0x11;
  205. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;
  206. }
  207. else
  208. {
  209. PTSRequest[1] = 0x10;
  210. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  211. }
  212. // PTS1 codes Fl and Dl
  213. PTSRequest[2] =
  214. SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  215. SmartcardExtension->CardCapabilities.PtsData.Dl;
  216. // check character
  217. PTSRequest[3] = PTSRequest[0] ^ PTSRequest[1] ^ PTSRequest[2];
  218. // write PTSRequest
  219. NTStatus = IFWriteSTCData( ReaderExtension, PTSRequest, 4 );
  220. // get response
  221. if( NTStatus == STATUS_SUCCESS )
  222. {
  223. NTStatus = IFReadSTCData( ReaderExtension, PTSReply, 4 );
  224. if(( NTStatus == STATUS_SUCCESS ) && !SysCompareMemory( PTSRequest, PTSReply, 4))
  225. {
  226. // set the stc registers
  227. SmartcardExtension->CardCapabilities.Dl =
  228. SmartcardExtension->CardCapabilities.PtsData.Dl;
  229. SmartcardExtension->CardCapabilities.Fl =
  230. SmartcardExtension->CardCapabilities.PtsData.Fl;
  231. CBSynchronizeSTC( SmartcardExtension );
  232. // the card replied correctly to the PTS-request
  233. break;
  234. }
  235. }
  236. //
  237. // The card did either NOT reply or it replied incorrectly
  238. // so try default values
  239. //
  240. if( SmartcardExtension->CardCapabilities.PtsData.Type != PTS_TYPE_DEFAULT )
  241. {
  242. SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_DEFAULT;
  243. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  244. NTStatus = CBCardPower( SmartcardExtension );
  245. if( NTStatus == STATUS_SUCCESS )
  246. {
  247. NTStatus = STATUS_PENDING;
  248. }
  249. else
  250. {
  251. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  252. }
  253. }
  254. }
  255. if( NTStatus == STATUS_TIMEOUT )
  256. {
  257. NTStatus = STATUS_IO_TIMEOUT;
  258. }
  259. if( NTStatus == STATUS_SUCCESS )
  260. {
  261. // card replied correctly to the PTS request
  262. if( SmartcardExtension->CardCapabilities.Protocol.Selected & SCARD_PROTOCOL_T1 )
  263. {
  264. ReaderExtension->ReadTimeout = SmartcardExtension->CardCapabilities.T1.BWT / 1000;
  265. }
  266. else
  267. {
  268. ULONG ClockRateFactor =
  269. SmartcardExtension->CardCapabilities.ClockRateConversion[SmartcardExtension->CardCapabilities.PtsData.Fl].F;
  270. // check for RFU value, and replace by default value
  271. if( !ClockRateFactor )
  272. ClockRateFactor = 372;
  273. ReaderExtension->ReadTimeout = 960
  274. * SmartcardExtension->CardCapabilities.T0.WI
  275. * ClockRateFactor
  276. / SmartcardExtension->CardCapabilities.PtsData.CLKFrequency;
  277. // We need to have a minimum timeout anyway
  278. if(ReaderExtension->ReadTimeout <50)
  279. {
  280. ReaderExtension->ReadTimeout =50; // 50 ms minimum timeout
  281. }
  282. }
  283. // indicate that the card is in specific mode
  284. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  285. &irql);
  286. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  287. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  288. irql);
  289. // return the selected protocol to the caller
  290. *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer = SmartcardExtension->CardCapabilities.Protocol.Selected;
  291. *SmartcardExtension->IoRequest.Information = sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
  292. }
  293. else
  294. {
  295. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  296. *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer = 0;
  297. *SmartcardExtension->IoRequest.Information = 0;
  298. }
  299. SmartcardDebug( DEBUG_TRACE, ("%d!CBSetProtocol: Exit %X\n",DRIVER_NAME, NTStatus ));
  300. return( NTStatus );
  301. }
  302. NTSTATUS
  303. CBGenericIOCTL(
  304. PSMARTCARD_EXTENSION SmartcardExtension)
  305. /*++
  306. Description:
  307. Performs generic callbacks to the reader
  308. Arguments:
  309. SmartcardExtension context of the call
  310. Return Value:
  311. STATUS_SUCCESS
  312. --*/
  313. {
  314. NTSTATUS NTStatus;
  315. SmartcardDebug(
  316. DEBUG_TRACE,
  317. ( "%s!CBGenericIOCTL: Enter\n",
  318. DRIVER_NAME));
  319. //
  320. // get pointer to current IRP stack location
  321. //
  322. //
  323. // assume error
  324. //
  325. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  326. //
  327. // dispatch IOCTL
  328. //
  329. switch( SmartcardExtension->MajorIoControlCode )
  330. {
  331. case IOCTL_WRITE_STC_REGISTER:
  332. NTStatus = IFWriteSTCRegister(
  333. SmartcardExtension->ReaderExtension,
  334. *(SmartcardExtension->IoRequest.RequestBuffer), // Address
  335. (ULONG)(*(SmartcardExtension->IoRequest.RequestBuffer + 1)), // Size
  336. SmartcardExtension->IoRequest.RequestBuffer + 2); // Data
  337. *SmartcardExtension->IoRequest.Information = 1;
  338. if(NTStatus == STATUS_SUCCESS)
  339. {
  340. *(SmartcardExtension->IoRequest.ReplyBuffer) = 0;
  341. }
  342. else
  343. {
  344. *(SmartcardExtension->IoRequest.ReplyBuffer) = 1;
  345. }
  346. break;
  347. case IOCTL_READ_STC_REGISTER:
  348. NTStatus = IFReadSTCRegister(
  349. SmartcardExtension->ReaderExtension,
  350. *(SmartcardExtension->IoRequest.RequestBuffer), // Address
  351. (ULONG)(*(SmartcardExtension->IoRequest.RequestBuffer + 1)), // Size
  352. SmartcardExtension->IoRequest.ReplyBuffer); // Data
  353. if(NTStatus ==STATUS_SUCCESS)
  354. {
  355. *SmartcardExtension->IoRequest.Information =
  356. (ULONG)(*(SmartcardExtension->IoRequest.RequestBuffer + 1));
  357. }
  358. else
  359. {
  360. SmartcardExtension->IoRequest.Information = 0;
  361. }
  362. break;
  363. case IOCTL_WRITE_STC_DATA:
  364. NTStatus = IFWriteSTCData(
  365. SmartcardExtension->ReaderExtension,
  366. SmartcardExtension->IoRequest.RequestBuffer + 1, // Data
  367. (ULONG)(*(SmartcardExtension->IoRequest.RequestBuffer))); // Size
  368. *SmartcardExtension->IoRequest.Information = 1;
  369. if(NTStatus == STATUS_SUCCESS)
  370. {
  371. *(SmartcardExtension->IoRequest.ReplyBuffer) = 0;
  372. }
  373. else
  374. {
  375. *(SmartcardExtension->IoRequest.ReplyBuffer) = 1;
  376. }
  377. break;
  378. case IOCTL_READ_STC_DATA:
  379. NTStatus = IFReadSTCData(
  380. SmartcardExtension->ReaderExtension,
  381. SmartcardExtension->IoRequest.ReplyBuffer, // Data
  382. (ULONG)(*(SmartcardExtension->IoRequest.RequestBuffer))); // Size
  383. if(NTStatus ==STATUS_SUCCESS)
  384. {
  385. *SmartcardExtension->IoRequest.Information =
  386. (ULONG)(*(SmartcardExtension->IoRequest.RequestBuffer));
  387. }
  388. else
  389. {
  390. SmartcardExtension->IoRequest.Information = 0;
  391. }
  392. break;
  393. default:
  394. break;
  395. }
  396. SmartcardDebug(
  397. DEBUG_TRACE,
  398. ( "%s!CBGenericIOCTL: Exit\n",
  399. DRIVER_NAME));
  400. return( NTStatus );
  401. }
  402. NTSTATUS
  403. CBTransmit(
  404. PSMARTCARD_EXTENSION SmartcardExtension
  405. )
  406. /*++
  407. CBTransmit:
  408. callback handler for SMCLIB RDF_TRANSMIT
  409. Arguments:
  410. SmartcardExtension context of call
  411. Return Value:
  412. STATUS_SUCCESS
  413. STATUS_NO_MEDIA
  414. STATUS_TIMEOUT
  415. STATUS_INVALID_DEVICE_REQUEST
  416. --*/
  417. {
  418. NTSTATUS NTStatus = STATUS_SUCCESS;
  419. SmartcardDebug( DEBUG_TRACE, ("%s!CBTransmit Enter\n",DRIVER_NAME ));
  420. // dispatch on the selected protocol
  421. switch( SmartcardExtension->CardCapabilities.Protocol.Selected )
  422. {
  423. case SCARD_PROTOCOL_T0:
  424. NTStatus = CBT0Transmit( SmartcardExtension );
  425. break;
  426. case SCARD_PROTOCOL_T1:
  427. NTStatus = CBT1Transmit( SmartcardExtension );
  428. break;
  429. case SCARD_PROTOCOL_RAW:
  430. NTStatus = CBRawTransmit( SmartcardExtension );
  431. break;
  432. default:
  433. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  434. break;
  435. }
  436. SmartcardDebug( DEBUG_TRACE, ("%s!CBTransmit Exit: %X\n",DRIVER_NAME, NTStatus ));
  437. return( NTStatus );
  438. }
  439. NTSTATUS
  440. T0_ExchangeData(
  441. PREADER_EXTENSION ReaderExtension,
  442. PUCHAR pRequest,
  443. ULONG RequestLen,
  444. PUCHAR pReply,
  445. PULONG pReplyLen)
  446. /*++
  447. Routine Description:
  448. T=0 management
  449. Arguments:
  450. ReaderExtension Context of the call
  451. pRequest Request buffer
  452. RequestLen Request buffer length
  453. pReply Reply buffer
  454. pReplyLen Reply buffer length
  455. Return Value:
  456. STATUS_SUCCESS
  457. Status returned by IFReadSTCData or IFWriteSTCData
  458. --*/
  459. {
  460. NTSTATUS NTStatus = STATUS_SUCCESS;
  461. BOOLEAN Direction;
  462. UCHAR Ins,
  463. Pcb = 0;
  464. ULONG Len,
  465. DataIdx;
  466. KPRIORITY PreviousPriority;
  467. BOOLEAN PriorityBoost = FALSE;
  468. if (ReaderExtension->Chosen_Priority > KeQueryPriorityThread(KeGetCurrentThread())) {
  469. SmartcardDebug(
  470. DEBUG_TRACE,
  471. ( "%s!T0_ExchangeData: Setting priority: 0x%x\n",
  472. DRIVER_NAME,
  473. ReaderExtension->Chosen_Priority));
  474. PriorityBoost = TRUE;
  475. PreviousPriority = KeSetPriorityThread(KeGetCurrentThread(),
  476. ReaderExtension->Chosen_Priority);
  477. }
  478. // get direction
  479. Ins = pRequest[ INS_IDX ] & 0xFE;
  480. Len = pRequest[ P3_IDX ];
  481. if( RequestLen == 5 )
  482. {
  483. Direction = ISO_OUT;
  484. DataIdx = 0;
  485. // For an ISO OUT command Len=0 means that the host expect an
  486. // 256 byte answer
  487. if( !Len )
  488. {
  489. Len = 0x100;
  490. }
  491. // Add 2 for SW1 SW2
  492. Len+=2;
  493. }
  494. else
  495. {
  496. Direction = ISO_IN;
  497. DataIdx = 5;
  498. }
  499. // send header CLASS,INS,P1,P2,P3
  500. NTStatus = IFWriteSTCData( ReaderExtension, pRequest, 5 );
  501. if( NTStatus == STATUS_SUCCESS )
  502. {
  503. NTStatus = STATUS_MORE_PROCESSING_REQUIRED;
  504. }
  505. while( NTStatus == STATUS_MORE_PROCESSING_REQUIRED )
  506. {
  507. // PCB reading
  508. NTStatus = IFReadSTCData( ReaderExtension, &Pcb, 1 );
  509. if( NTStatus == STATUS_SUCCESS )
  510. {
  511. if( Pcb == 0x60 )
  512. {
  513. // null byte?
  514. NTStatus = STATUS_MORE_PROCESSING_REQUIRED;
  515. continue;
  516. }
  517. else if( ( Pcb & 0xFE ) == Ins )
  518. {
  519. // transfer all
  520. if( Direction == ISO_IN )
  521. {
  522. // write remaining data
  523. NTStatus = IFWriteSTCData( ReaderExtension, pRequest + DataIdx, Len );
  524. if( NTStatus == STATUS_SUCCESS )
  525. {
  526. // if all data successful written the status word is expected
  527. NTStatus = STATUS_MORE_PROCESSING_REQUIRED;
  528. Direction = ISO_OUT;
  529. DataIdx = 0;
  530. Len = 2;
  531. }
  532. }
  533. else
  534. {
  535. // read remaining data
  536. NTStatus = IFReadSTCData( ReaderExtension, pReply + DataIdx, Len );
  537. DataIdx += Len;
  538. }
  539. }
  540. else if( (( Pcb & 0xFE ) ^ Ins ) == 0xFE )
  541. {
  542. // transfer next
  543. if( Direction == ISO_IN )
  544. {
  545. // write next
  546. NTStatus = IFWriteSTCData( ReaderExtension, pRequest + DataIdx, 1 );
  547. if( NTStatus == STATUS_SUCCESS )
  548. {
  549. DataIdx++;
  550. // if all data successful written the status word is expected
  551. if( --Len == 0 )
  552. {
  553. Direction = ISO_OUT;
  554. DataIdx = 0;
  555. Len = 2;
  556. }
  557. NTStatus = STATUS_MORE_PROCESSING_REQUIRED;
  558. }
  559. }
  560. else
  561. {
  562. // read next
  563. NTStatus = IFReadSTCData( ReaderExtension, pReply + DataIdx, 1 );
  564. if( NTStatus == STATUS_SUCCESS )
  565. {
  566. NTStatus = STATUS_MORE_PROCESSING_REQUIRED;
  567. if (Len == 0) {
  568. // we should have be done reading by now.
  569. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  570. break;
  571. }
  572. Len--;
  573. DataIdx++;
  574. }
  575. }
  576. }
  577. else if( (( Pcb & 0x60 ) == 0x60 ) || (( Pcb & 0x90 ) == 0x90 ) )
  578. {
  579. if( Direction == ISO_IN )
  580. {
  581. Direction = ISO_OUT;
  582. DataIdx = 0;
  583. }
  584. // SW1
  585. *pReply = Pcb;
  586. // read SW2 and leave
  587. NTStatus = IFReadSTCData( ReaderExtension, &Pcb, 1 );
  588. *(pReply + 1) = Pcb;
  589. DataIdx += 2;
  590. }
  591. else
  592. {
  593. NTStatus = STATUS_UNSUCCESSFUL;
  594. }
  595. }
  596. }
  597. if(( NTStatus == STATUS_SUCCESS ) && ( pReplyLen != NULL ))
  598. {
  599. *pReplyLen = DataIdx;
  600. }
  601. if (PriorityBoost) {
  602. SmartcardDebug(
  603. DEBUG_TRACE,
  604. ( "%s!T0_ExchangeData: Setting priority: 0x%x\n",
  605. DRIVER_NAME,
  606. PreviousPriority));
  607. PreviousPriority = KeSetPriorityThread(KeGetCurrentThread(),
  608. PreviousPriority);
  609. }
  610. return( NTStatus );
  611. }
  612. NTSTATUS
  613. CBT0Transmit(
  614. PSMARTCARD_EXTENSION SmartcardExtension)
  615. /*++
  616. CBT0Transmit:
  617. finishes the callback RDF_TRANSMIT for the T0 protocol
  618. Arguments:
  619. SmartcardExtension context of call
  620. Return Value:
  621. STATUS_SUCCESS
  622. STATUS_NO_MEDIA
  623. STATUS_TIMEOUT
  624. STATUS_INVALID_DEVICE_REQUEST
  625. --*/
  626. {
  627. NTSTATUS NTStatus = STATUS_SUCCESS;
  628. SmartcardDebug( DEBUG_TRACE, ("%s!CBT0Transmit Enter\n",DRIVER_NAME ));
  629. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  630. // let the lib setup the T=1 APDU & check for errors
  631. NTStatus = SmartcardT0Request( SmartcardExtension );
  632. if( NTStatus == STATUS_SUCCESS )
  633. {
  634. NTStatus = T0_ExchangeData(
  635. SmartcardExtension->ReaderExtension,
  636. SmartcardExtension->SmartcardRequest.Buffer,
  637. SmartcardExtension->SmartcardRequest.BufferLength,
  638. SmartcardExtension->SmartcardReply.Buffer,
  639. &SmartcardExtension->SmartcardReply.BufferLength);
  640. if( NTStatus == STATUS_SUCCESS )
  641. {
  642. // let the lib evaluate the result & tansfer the data
  643. NTStatus = SmartcardT0Reply( SmartcardExtension );
  644. }
  645. }
  646. SmartcardDebug( DEBUG_TRACE,("%s!CBT0Transmit Exit: %X\n",DRIVER_NAME, NTStatus ));
  647. return( NTStatus );
  648. }
  649. NTSTATUS
  650. CBT1Transmit(
  651. PSMARTCARD_EXTENSION SmartcardExtension)
  652. /*++
  653. CBT1Transmit:
  654. finishes the callback RDF_TRANSMIT for the T1 protocol
  655. Arguments:
  656. SmartcardExtension context of call
  657. Return Value:
  658. STATUS_SUCCESS
  659. STATUS_NO_MEDIA
  660. STATUS_TIMEOUT
  661. STATUS_INVALID_DEVICE_REQUEST
  662. --*/
  663. {
  664. NTSTATUS NTStatus = STATUS_SUCCESS;
  665. KPRIORITY PreviousPriority;
  666. BOOLEAN PriorityBoost = FALSE;
  667. SmartcardDebug( DEBUG_TRACE, ("%s!CBT1Transmit Enter\n",DRIVER_NAME ));
  668. // smclib workaround
  669. *(PULONG)&SmartcardExtension->IoRequest.ReplyBuffer[0] = 0x02;
  670. *(PULONG)&SmartcardExtension->IoRequest.ReplyBuffer[4] = sizeof( SCARD_IO_REQUEST );
  671. // use the lib support to construct the T=1 packets
  672. do {
  673. // no header for the T=1 protocol
  674. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  675. SmartcardExtension->T1.NAD = 0;
  676. // let the lib setup the T=1 APDU & check for errors
  677. NTStatus = SmartcardT1Request( SmartcardExtension );
  678. if( NTStatus == STATUS_SUCCESS )
  679. {
  680. if (SmartcardExtension->ReaderExtension->Chosen_Priority > KeQueryPriorityThread(KeGetCurrentThread())) {
  681. SmartcardDebug(
  682. DEBUG_TRACE,
  683. ( "%s!CBT1Transmit: Setting priority: 0x%x\n",
  684. DRIVER_NAME,
  685. SmartcardExtension->ReaderExtension->Chosen_Priority));
  686. PriorityBoost = TRUE;
  687. PreviousPriority = KeSetPriorityThread(KeGetCurrentThread(),
  688. SmartcardExtension->ReaderExtension->Chosen_Priority);
  689. }
  690. // send command (don't calculate LRC because CRC may be used!)
  691. NTStatus = IFWriteSTCData(
  692. SmartcardExtension->ReaderExtension,
  693. SmartcardExtension->SmartcardRequest.Buffer,
  694. SmartcardExtension->SmartcardRequest.BufferLength);
  695. if (PriorityBoost) {
  696. SmartcardDebug(
  697. DEBUG_TRACE,
  698. ( "%s!CBT1Transmit: Setting priority: 0x%x\n",
  699. DRIVER_NAME,
  700. PreviousPriority));
  701. PriorityBoost = FALSE;
  702. PreviousPriority = KeSetPriorityThread(KeGetCurrentThread(),
  703. PreviousPriority);
  704. }
  705. // extend read timeout if the card issued a WTX request
  706. if (SmartcardExtension->T1.Wtx)
  707. {
  708. SmartcardExtension->ReaderExtension->ReadTimeout =
  709. ( SmartcardExtension->T1.Wtx *
  710. SmartcardExtension->CardCapabilities.T1.BWT + 999L )/
  711. 1000L;
  712. }
  713. else
  714. {
  715. // restore timeout
  716. SmartcardExtension->ReaderExtension->ReadTimeout =
  717. (ULONG) (SmartcardExtension->CardCapabilities.T1.BWT / 1000);
  718. }
  719. // get response
  720. SmartcardExtension->SmartcardReply.BufferLength = 0;
  721. if( NTStatus == STATUS_SUCCESS )
  722. {
  723. if (SmartcardExtension->ReaderExtension->Chosen_Priority > KeQueryPriorityThread(KeGetCurrentThread())) {
  724. SmartcardDebug(
  725. DEBUG_TRACE,
  726. ( "%s!CBT1Transmit: Setting priority: 0x%x\n",
  727. DRIVER_NAME,
  728. SmartcardExtension->ReaderExtension->Chosen_Priority));
  729. PriorityBoost = TRUE;
  730. PreviousPriority = KeSetPriorityThread(KeGetCurrentThread(),
  731. SmartcardExtension->ReaderExtension->Chosen_Priority);
  732. }
  733. NTStatus = IFReadSTCData(
  734. SmartcardExtension->ReaderExtension,
  735. SmartcardExtension->SmartcardReply.Buffer,
  736. 3);
  737. if( NTStatus == STATUS_SUCCESS )
  738. {
  739. ULONG Length;
  740. Length = (ULONG)SmartcardExtension->SmartcardReply.Buffer[ LEN_IDX ] + 1;
  741. if( Length + 3 < MIN_BUFFER_SIZE )
  742. {
  743. NTStatus = IFReadSTCData(
  744. SmartcardExtension->ReaderExtension,
  745. &SmartcardExtension->SmartcardReply.Buffer[ DATA_IDX ],
  746. Length);
  747. SmartcardExtension->SmartcardReply.BufferLength = Length + 3;
  748. }
  749. else
  750. {
  751. NTStatus = STATUS_BUFFER_TOO_SMALL;
  752. }
  753. }
  754. if (PriorityBoost) {
  755. SmartcardDebug(
  756. DEBUG_TRACE,
  757. ( "%s!CBT1Transmit: Setting priority: 0x%x\n",
  758. DRIVER_NAME,
  759. PreviousPriority));
  760. PriorityBoost = FALSE;
  761. PreviousPriority = KeSetPriorityThread(KeGetCurrentThread(),
  762. PreviousPriority);
  763. }
  764. //
  765. // if STCRead detects an LRC error, ignore it (maybe CRC used). Timeouts will
  766. // be detected by the lib if len=0
  767. //
  768. if(( NTStatus == STATUS_CRC_ERROR ) || ( NTStatus == STATUS_IO_TIMEOUT ))
  769. {
  770. NTStatus = STATUS_SUCCESS;
  771. }
  772. if( NTStatus == STATUS_SUCCESS )
  773. {
  774. // let the lib evaluate the result & setup the next APDU
  775. NTStatus = SmartcardT1Reply( SmartcardExtension );
  776. }
  777. }
  778. }
  779. // continue if the lib wants to send the next packet
  780. } while( NTStatus == STATUS_MORE_PROCESSING_REQUIRED );
  781. if( NTStatus == STATUS_IO_TIMEOUT )
  782. {
  783. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  784. }
  785. SmartcardDebug( DEBUG_TRACE,( "%s!CBT1Transmit Exit: %X\n",DRIVER_NAME, NTStatus ));
  786. return ( NTStatus );
  787. }
  788. NTSTATUS
  789. CBRawTransmit(
  790. PSMARTCARD_EXTENSION SmartcardExtension)
  791. /*++
  792. CBRawTransmit:
  793. finishes the callback RDF_TRANSMIT for the RAW protocol
  794. Arguments:
  795. SmartcardExtension context of call
  796. Return Value:
  797. STATUS_UNSUCCESSFUL
  798. --*/
  799. {
  800. NTSTATUS NTStatus = STATUS_UNSUCCESSFUL;
  801. SmartcardDebug( DEBUG_TRACE, ("%s!CBRawTransmit Exit: %X\n",DRIVER_NAME, NTStatus ));
  802. return ( NTStatus );
  803. }
  804. NTSTATUS
  805. CBCardTracking(
  806. PSMARTCARD_EXTENSION SmartcardExtension)
  807. /*++
  808. CBCardTracking:
  809. callback handler for SMCLIB RDF_CARD_TRACKING. the requested event was
  810. validated by the smclib (i.e. a card removal request will only be passed
  811. if a card is present).
  812. for a win95 build STATUS_PENDING will be returned without any other action.
  813. for NT the cancel routine for the irp will be set to the drivers cancel
  814. routine.
  815. Arguments:
  816. SmartcardExtension context of call
  817. Return Value:
  818. STATUS_PENDING
  819. --*/
  820. {
  821. KIRQL CurrentIrql;
  822. SmartcardDebug(
  823. DEBUG_TRACE,
  824. ("%s!CBCardTracking Enter\n",
  825. DRIVER_NAME));
  826. // set cancel routine
  827. IoAcquireCancelSpinLock( &CurrentIrql );
  828. IoSetCancelRoutine(
  829. SmartcardExtension->OsData->NotificationIrp,
  830. StcUsbCancel);
  831. IoReleaseCancelSpinLock( CurrentIrql );
  832. SmartcardDebug(
  833. DEBUG_TRACE,
  834. ("%s!CBCardTracking Exit\n",
  835. DRIVER_NAME));
  836. return( STATUS_PENDING );
  837. }
  838. NTSTATUS
  839. CBUpdateCardState(
  840. PSMARTCARD_EXTENSION SmartcardExtension
  841. )
  842. /*++
  843. CBUpdateCardState:
  844. updates the variable CurrentState in SmartcardExtension
  845. Arguments:
  846. SmartcardExtension context of call
  847. Return Value:
  848. STATUS_SUCCESS
  849. --*/
  850. {
  851. NTSTATUS status = STATUS_SUCCESS;
  852. UCHAR cardStatus = 0;
  853. KIRQL irql;
  854. BOOLEAN stateChanged = FALSE;
  855. ULONG oldState;
  856. // read card state
  857. status = IFReadSTCRegister(
  858. SmartcardExtension->ReaderExtension,
  859. ADR_IO_CONFIG,
  860. 1,
  861. &cardStatus
  862. );
  863. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  864. &irql);
  865. oldState = SmartcardExtension->ReaderCapabilities.CurrentState;
  866. switch(status)
  867. {
  868. case STATUS_NO_MEDIA:
  869. SmartcardExtension->ReaderExtension->ErrorCounter = 0;
  870. SmartcardExtension->ReaderCapabilities.CurrentState =
  871. SCARD_ABSENT;
  872. break;
  873. case STATUS_MEDIA_CHANGED:
  874. SmartcardExtension->ReaderExtension->ErrorCounter = 0;
  875. SmartcardExtension->ReaderCapabilities.CurrentState =
  876. SCARD_PRESENT;
  877. break;
  878. case STATUS_SUCCESS:
  879. SmartcardExtension->ReaderExtension->ErrorCounter = 0;
  880. cardStatus &= M_SD;
  881. if( cardStatus == 0 )
  882. {
  883. SmartcardExtension->ReaderCapabilities.CurrentState =
  884. SCARD_ABSENT;
  885. }
  886. else if( SmartcardExtension->ReaderCapabilities.CurrentState <=
  887. SCARD_ABSENT )
  888. {
  889. SmartcardExtension->ReaderCapabilities.CurrentState =
  890. SCARD_PRESENT;
  891. }
  892. break;
  893. default:
  894. if( ++SmartcardExtension->ReaderExtension->ErrorCounter < ERROR_COUNTER_TRESHOLD )
  895. {
  896. // a unknown status was reported from the reader, so use the previous state
  897. SmartcardExtension->ReaderCapabilities.CurrentState = oldState;
  898. }
  899. else
  900. {
  901. SmartcardLogError(
  902. SmartcardExtension->OsData->DeviceObject,
  903. STCUSB_TOO_MANY_ERRORS,
  904. NULL,
  905. 0);
  906. // a report of SCARD_UNKNOWN will force the resource manager to
  907. // disconnect the reader
  908. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_UNKNOWN;
  909. }
  910. break;
  911. }
  912. //
  913. // we need to update the card state if there was a card before hibernate
  914. // stand / by or when the current state has changed.
  915. //
  916. if (SmartcardExtension->ReaderExtension->CardPresent ||
  917. oldState <= SCARD_ABSENT &&
  918. SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT ||
  919. oldState > SCARD_ABSENT &&
  920. SmartcardExtension->ReaderCapabilities.CurrentState <= SCARD_ABSENT) {
  921. stateChanged = TRUE;
  922. SmartcardExtension->ReaderExtension->CardPresent = FALSE;
  923. }
  924. if (stateChanged && SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT) {
  925. PoSetSystemState (ES_USER_PRESENT);
  926. }
  927. if(stateChanged && SmartcardExtension->OsData->NotificationIrp != NULL)
  928. {
  929. KIRQL CurrentIrql;
  930. PIRP pIrp;
  931. IoAcquireCancelSpinLock( &CurrentIrql );
  932. IoSetCancelRoutine( SmartcardExtension->OsData->NotificationIrp, NULL );
  933. IoReleaseCancelSpinLock( CurrentIrql );
  934. SmartcardExtension->OsData->NotificationIrp->IoStatus.Status =
  935. STATUS_SUCCESS;
  936. SmartcardExtension->OsData->NotificationIrp->IoStatus.Information = 0;
  937. SmartcardDebug(
  938. DEBUG_DRIVER,
  939. ("%s!CBUpdateCardState: Completing notification irp %lx\n",
  940. DRIVER_NAME,
  941. SmartcardExtension->OsData->NotificationIrp));
  942. pIrp = SmartcardExtension->OsData->NotificationIrp;
  943. SmartcardExtension->OsData->NotificationIrp = NULL;
  944. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock, irql);
  945. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  946. } else {
  947. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock, irql);
  948. }
  949. return status;
  950. }
  951. NTSTATUS
  952. CBSynchronizeSTC(
  953. PSMARTCARD_EXTENSION SmartcardExtension )
  954. /*++
  955. CBSynchronizeSTC:
  956. updates the card dependend data of the stc (wait times, ETU...)
  957. Arguments:
  958. SmartcardExtension context of call
  959. Return Value:
  960. STATUS_SUCCESS
  961. --*/
  962. {
  963. NTSTATUS NTStatus = STATUS_SUCCESS;
  964. PREADER_EXTENSION ReaderExtension;
  965. ULONG CWT,
  966. BWT,
  967. CGT,
  968. ETU;
  969. UCHAR Dl,
  970. Fl,
  971. N;
  972. PCLOCK_RATE_CONVERSION ClockRateConversion;
  973. PBIT_RATE_ADJUSTMENT BitRateAdjustment;
  974. ReaderExtension = SmartcardExtension->ReaderExtension;
  975. ClockRateConversion = SmartcardExtension->CardCapabilities.ClockRateConversion;
  976. BitRateAdjustment = SmartcardExtension->CardCapabilities.BitRateAdjustment;
  977. // cycle length
  978. Dl = SmartcardExtension->CardCapabilities.Dl;
  979. Fl = SmartcardExtension->CardCapabilities.Fl;
  980. ETU = ClockRateConversion[Fl & 0x0F].F;
  981. ETU /= BitRateAdjustment[ Dl & 0x0F ].DNumerator;
  982. ETU *= BitRateAdjustment[ Dl & 0x0F ].DDivisor;
  983. // ETU += (ETU % 2 == 0) ? 0 : 1;
  984. // a extra guard time of 0xFF means minimum delay in both directions
  985. N = SmartcardExtension->CardCapabilities.N;
  986. if( N == 0xFF )
  987. {
  988. N = 0;
  989. }
  990. // set character waiting & guard time
  991. switch ( SmartcardExtension->CardCapabilities.Protocol.Selected )
  992. {
  993. case SCARD_PROTOCOL_T0:
  994. CWT = 960 * SmartcardExtension->CardCapabilities.T0.WI;
  995. CGT = 14 + N; // 13 + N; cryptoflex error
  996. break;
  997. case SCARD_PROTOCOL_T1:
  998. CWT = 11 + ( 0x01 << SmartcardExtension->CardCapabilities.T1.CWI );
  999. BWT = 11 + ( 0x01 << SmartcardExtension->CardCapabilities.T1.BWI ) * 960;
  1000. CGT = 15 + N ;//13 + N; // 12 + N; sicrypt error
  1001. NTStatus = STCSetBWT( ReaderExtension, BWT * ETU );
  1002. break;
  1003. default:
  1004. // restore default CGT
  1005. CGT=13;
  1006. STCSetCGT( ReaderExtension, CGT);
  1007. NTStatus = STATUS_UNSUCCESSFUL;
  1008. break;
  1009. }
  1010. if(( NTStatus == STATUS_SUCCESS ) && ETU )
  1011. {
  1012. NTStatus = STCSetETU( ReaderExtension, ETU );
  1013. if( NTStatus == STATUS_SUCCESS )
  1014. {
  1015. NTStatus = STCSetCGT( ReaderExtension, CGT );
  1016. if( NTStatus == STATUS_SUCCESS )
  1017. {
  1018. NTStatus = STCSetCWT( ReaderExtension, CWT * ETU );
  1019. }
  1020. }
  1021. }
  1022. return( NTStatus );
  1023. }