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.

2383 lines
79 KiB

  1. /*******************************************************************************
  2. * Copyright (c) 1997-1998 Gemplus Development
  3. *
  4. * Name : GIOCTL09.C (Gemplus IOCTL Smart card Reader module 09)
  5. *
  6. * Description : This module holds:
  7. * - the IOCTL functions for a smart card reader driver
  8. * in compliance with PC/SC.
  9. *
  10. * Release : 1.00.015
  11. *
  12. * dd/mm/yy
  13. * Last Modif : 11/02/98: V1.00.015 (GPZ)
  14. * 09/02/98: V1.00.014 (GPZ)
  15. * - GDDK_09Transmit: verify the limits.
  16. * 24/01/98: V1.00.010 (GPZ)
  17. * - GDDK_09Transmit: verify the case T=0 IsoOut with also the
  18. * initial buffer length because the SMCLIB add the P3=00
  19. * for the T=0 case 1 (IsoIn command) and this can be
  20. * interpreted like an IsoOut command.
  21. * 19/01/98: V1.00.009 (TFB)
  22. * - GDDK_09Transmit: modify case where Lexp=0 to max.
  23. * 19/12/97: V1.00.003 (TFB)
  24. * - GDDK_09Transmit: check if buffer is too small to hold
  25. * result-data.
  26. * 04/11/97: V1.00.002 (GPZ)
  27. * - GDDK_09Transmit: the status is always updated.
  28. * 03/07/97: V1.00.001 (GPZ)
  29. * - Start of development.
  30. *
  31. ********************************************************************************
  32. *
  33. * Warning :
  34. *
  35. * Remark :
  36. *
  37. *******************************************************************************/
  38. /*------------------------------------------------------------------------------
  39. Include section:
  40. ------------------------------------------------------------------------------*/
  41. /*------------------------------------------------------------------------------
  42. - ntddk.h: DDK Windows NT general definitons.
  43. - ntddser.h: DDK Windows NT serial management definitons.
  44. ------------------------------------------------------------------------------*/
  45. #include <ntddk.h>
  46. #include <ntddser.h>
  47. /*------------------------------------------------------------------------------
  48. - smclib.h: smart card library definitions.
  49. ------------------------------------------------------------------------------*/
  50. #define SMARTCARD_POOL_TAG 'cGCS'
  51. #include <smclib.h>
  52. /*------------------------------------------------------------------------------
  53. - gemcore.h: Gemplus standards definitions for the Gemcore smart card reader.
  54. - gioctl09.h: public interface definition for this module.
  55. - gntser.h: public interface definition for serial management.
  56. ------------------------------------------------------------------------------*/
  57. #include "gemcore.h"
  58. #include "gioctl09.h"
  59. #include "gntser.h"
  60. #include "gntscr09.h"
  61. #define min(a,b) (((a) < (b)) ? (a) : (b))
  62. /*------------------------------------------------------------------------------
  63. Static variables declaration section:
  64. - dataRatesSupported: holds all the supported data rates.
  65. ------------------------------------------------------------------------------*/
  66. #if SMCLIB_VERSION >= 0x0130
  67. static ULONG
  68. dataRatesSupported[] = {
  69. 9909, 13212, 14400, 15855,
  70. 19200, 19819, 26425, 28800,
  71. 31710, 38400, 39638, 52851,
  72. 57600, 76800, 79277, 105703,
  73. 115200, 158554
  74. };
  75. #endif
  76. /*------------------------------------------------------------------------------
  77. Static functions declaration section:
  78. - GDDK_09IFDExchange
  79. ------------------------------------------------------------------------------*/
  80. static NTSTATUS GDDK_09IFDExchange
  81. (
  82. PSMARTCARD_EXTENSION SmartcardExtension,
  83. ULONG BufferInLen,
  84. BYTE *BufferIn,
  85. ULONG BufferOutLen,
  86. BYTE *BufferOut,
  87. ULONG *LengthOut
  88. );
  89. /*------------------------------------------------------------------------------
  90. Function definition section:
  91. ------------------------------------------------------------------------------*/
  92. /*******************************************************************************
  93. * NTSTATUS GDDK_09ReaderPower
  94. * (
  95. * PSMARTCARD_EXTENSION SmartcardExtension
  96. * )
  97. *
  98. * Description :
  99. * -------------
  100. * This function is called by the Smart card library when a
  101. * IOCTL_SMARTCARD_POWER occurs.
  102. * This function provides 3 differents functionnality, depending of the minor
  103. * IOCTL value
  104. * - Cold reset (SCARD_COLD_RESET),
  105. * - Warm reset (SCARD_WARM_RESET),
  106. * - Power down (SCARD_POWER_DOWN).
  107. *
  108. * Remarks :
  109. * -------------
  110. * Nothing.
  111. *
  112. * In :
  113. * -------------
  114. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  115. * the current device.
  116. *
  117. * Out :
  118. * -------------
  119. * Nothing.
  120. *
  121. * Responses :
  122. * -------------
  123. * NTSTATUS
  124. *******************************************************************************/
  125. NTSTATUS GDDK_09ReaderPower
  126. (
  127. PSMARTCARD_EXTENSION SmartcardExtension
  128. )
  129. {
  130. NTSTATUS
  131. status;
  132. /*------------------------------------------------------------------------------
  133. Set the reply buffer length to 0.
  134. ------------------------------------------------------------------------------*/
  135. *SmartcardExtension->IoRequest.Information = 0;
  136. SmartcardExtension->ReaderExtension->PTSMode = IFD_DEFAULT_MODE;
  137. /*------------------------------------------------------------------------------
  138. Call the GDDK_09xxxxxSession functions
  139. ------------------------------------------------------------------------------*/
  140. switch(SmartcardExtension->MinorIoControlCode)
  141. {
  142. case SCARD_POWER_DOWN:
  143. status = GDDK_09CloseSession(SmartcardExtension);
  144. break;
  145. case SCARD_COLD_RESET:
  146. status = GDDK_09OpenSession(SmartcardExtension);
  147. break;
  148. case SCARD_WARM_RESET:
  149. status = GDDK_09SwitchSession(SmartcardExtension);
  150. break;
  151. default:
  152. status = STATUS_NOT_SUPPORTED;
  153. }
  154. return (status);
  155. }
  156. /*******************************************************************************
  157. * NTSTATUS GDDK_09SetProtocol
  158. * (
  159. * PSMARTCARD_EXTENSION SmartcardExtension
  160. * )
  161. *
  162. * Description :
  163. * -------------
  164. * This function is called by the Smart card library when a
  165. * IOCTL_SMARTCARD_SET_PROTOCOL occurs.
  166. * The minor IOCTL value holds the protocol to set.
  167. *
  168. * Remarks :
  169. * -------------
  170. * Nothing.
  171. *
  172. * In :
  173. * -------------
  174. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  175. * the current device.
  176. *
  177. * Out :
  178. * -------------
  179. * Nothing.
  180. *
  181. * Responses :
  182. * -------------
  183. * NTSTATUS
  184. *******************************************************************************/
  185. NTSTATUS GDDK_09SetProtocol
  186. (
  187. PSMARTCARD_EXTENSION SmartcardExtension
  188. )
  189. {
  190. NTSTATUS
  191. status = STATUS_NOT_SUPPORTED;
  192. /*------------------------------------------------------------------------------
  193. Check if the card is already in specific state and if the caller wants to
  194. have the already selected protocol. We return SUCCESS if this is the case.
  195. ------------------------------------------------------------------------------*/
  196. if ((SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC) &&
  197. (SmartcardExtension->CardCapabilities.Protocol.Selected &
  198. SmartcardExtension->MinorIoControlCode))
  199. {
  200. status = STATUS_SUCCESS;
  201. }
  202. /*------------------------------------------------------------------------------
  203. Else
  204. Check if the card is absent. We return NO_MEDIA if this is the case.
  205. ------------------------------------------------------------------------------*/
  206. else if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_ABSENT)
  207. {
  208. status = STATUS_NO_MEDIA;
  209. }
  210. /*------------------------------------------------------------------------------
  211. Else if the Current state is SCARD_NEGOTIABLE
  212. Check if we can support one of the specified protocols; else we
  213. return STATUS_NOT_SUPPORTED.
  214. If we want to negotiate the speed, then we set the PTS1 byte
  215. with the Fl/Dl parameters specified by the SMCLIB.
  216. Send an other reset command with the appropriate PTS request.
  217. ------------------------------------------------------------------------------*/
  218. else if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_NEGOTIABLE)
  219. {
  220. if (SmartcardExtension->MinorIoControlCode & SCARD_PROTOCOL_T0)
  221. {
  222. SmartcardExtension->ReaderExtension->PTS0 = IFD_NEGOTIATE_T0;
  223. }
  224. else if (SmartcardExtension->MinorIoControlCode & SCARD_PROTOCOL_T1)
  225. {
  226. SmartcardExtension->ReaderExtension->PTS0 = IFD_NEGOTIATE_T1;
  227. }
  228. else
  229. {
  230. status = STATUS_NOT_SUPPORTED;
  231. }
  232. if (status == STATUS_SUCCESS)
  233. {
  234. SmartcardExtension->ReaderExtension->PTSMode = IFD_NEGOTIATE_PTS_MANUALLY;
  235. SmartcardExtension->ReaderExtension->PTS2 = 0x00;
  236. SmartcardExtension->ReaderExtension->PTS3 = 0x00;
  237. #if (SMCLIB_VERSION >= 0x130)
  238. if ((SmartcardExtension->MinorIoControlCode & SCARD_PROTOCOL_DEFAULT) == 0)
  239. {
  240. SmartcardExtension->ReaderExtension->PTS0 |= IFD_NEGOTIATE_PTS1;
  241. SmartcardExtension->ReaderExtension->PTS1 =
  242. (0xF0 & (SmartcardExtension->CardCapabilities.PtsData.Fl<<4)) |
  243. (0x0F & SmartcardExtension->CardCapabilities.PtsData.Dl) ;
  244. }
  245. #endif
  246. status = GDDK_09OpenSession(SmartcardExtension);
  247. if (status != STATUS_SUCCESS)
  248. status = STATUS_NOT_SUPPORTED;
  249. }
  250. }
  251. /*------------------------------------------------------------------------------
  252. Else
  253. The mask contains no known protocol. We return INVALID_DEVICE_REQUEST if
  254. this is the case.
  255. ------------------------------------------------------------------------------*/
  256. else
  257. {
  258. status = STATUS_INVALID_DEVICE_REQUEST;
  259. }
  260. /*------------------------------------------------------------------------------
  261. Set the reply buffer length to sizeof(ULONG).
  262. Check if status SUCCESS, store the selected protocol.
  263. ------------------------------------------------------------------------------*/
  264. *SmartcardExtension->IoRequest.Information = sizeof(ULONG);
  265. if (status == STATUS_SUCCESS)
  266. {
  267. *(ULONG *)SmartcardExtension->IoRequest.ReplyBuffer =
  268. SmartcardExtension->CardCapabilities.Protocol.Selected;
  269. }
  270. /*------------------------------------------------------------------------------
  271. Else
  272. Set the selected protocol to undefined.
  273. ------------------------------------------------------------------------------*/
  274. else
  275. {
  276. *(ULONG *)SmartcardExtension->IoRequest.ReplyBuffer =
  277. SCARD_PROTOCOL_UNDEFINED;
  278. }
  279. return (status);
  280. }
  281. /*******************************************************************************
  282. * NTSTATUS GDDK_09Transmit
  283. * (
  284. * PSMARTCARD_EXTENSION SmartcardExtension
  285. * )
  286. *
  287. * Description :
  288. * -------------
  289. * This function is called by the Smart card library when a
  290. * IOCTL_SMARTCARD_TRANSMIT occurs.
  291. * This function is used to transmit a command to the card.
  292. *
  293. * Remarks :
  294. * -------------
  295. * Nothing.
  296. *
  297. * In :
  298. * -------------
  299. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  300. * the current device.
  301. *
  302. * Out :
  303. * -------------
  304. * Nothing.
  305. *
  306. * Responses :
  307. * -------------
  308. * NTSTATUS
  309. *******************************************************************************/
  310. NTSTATUS GDDK_09Transmit
  311. (
  312. PSMARTCARD_EXTENSION SmartcardExtension
  313. )
  314. {
  315. NTSTATUS
  316. status;
  317. PUCHAR
  318. requestBuffer = SmartcardExtension->SmartcardRequest.Buffer,
  319. replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
  320. PULONG
  321. requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
  322. PSCARD_IO_REQUEST scardIoRequest = (PSCARD_IO_REQUEST)
  323. SmartcardExtension->OsData->CurrentIrp->AssociatedIrp.SystemBuffer;
  324. USHORT
  325. i,
  326. buffLen,
  327. lenExp,
  328. lenIn;
  329. UCHAR
  330. *buffIn;
  331. INT16
  332. response;
  333. READER_EXTENSION
  334. *param = SmartcardExtension->ReaderExtension;
  335. WORD16
  336. rlen;
  337. BYTE
  338. rbuff[HOR3GLL_BUFFER_SIZE];
  339. /*------------------------------------------------------------------------------
  340. Set the reply buffer length to 0.
  341. ------------------------------------------------------------------------------*/
  342. *SmartcardExtension->IoRequest.Information = 0;
  343. status = STATUS_SUCCESS;
  344. /*------------------------------------------------------------------------------
  345. Verify if the protocol specified is the same than the protocol selected.
  346. <== STATUS_INVALID_DEVICE_STATE
  347. ------------------------------------------------------------------------------*/
  348. *requestLength = 0;
  349. if (SmartcardExtension->CardCapabilities.Protocol.Selected !=
  350. scardIoRequest->dwProtocol)
  351. {
  352. return (STATUS_INVALID_DEVICE_STATE);
  353. }
  354. /*------------------------------------------------------------------------------
  355. Lock the mutex to avoid a call of an other command.
  356. ------------------------------------------------------------------------------*/
  357. GDDK_09LockExchange(SmartcardExtension);
  358. /*------------------------------------------------------------------------------
  359. For the different protocols:
  360. ------------------------------------------------------------------------------*/
  361. switch (SmartcardExtension->CardCapabilities.Protocol.Selected)
  362. {
  363. /*------------------------------------------------------------------------------
  364. RAW protocol:
  365. <== STATUS_INVALID_DEVICE_STATE
  366. ------------------------------------------------------------------------------*/
  367. case SCARD_PROTOCOL_RAW:
  368. status = STATUS_INVALID_DEVICE_STATE;
  369. break;
  370. /*------------------------------------------------------------------------------
  371. T=0 PROTOCOL:
  372. Call the SmartCardT0Request which updates the SmartcardRequest struct.
  373. ------------------------------------------------------------------------------*/
  374. case SCARD_PROTOCOL_T0:
  375. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  376. status = SmartcardT0Request(SmartcardExtension);
  377. if (status == STATUS_SUCCESS)
  378. {
  379. rlen = HOR3GLL_BUFFER_SIZE;
  380. /*------------------------------------------------------------------------------
  381. If the length LEx > 0
  382. Then
  383. Is an ISO Out command.
  384. If LEx > SC_IFD_GEMCORE_T0_MAXIMUM_LEX (256)
  385. <== STATUS_BUFFER_TOO_SMALL
  386. Call the G_Oros3IsoOutput
  387. ------------------------------------------------------------------------------*/
  388. if (SmartcardExtension->T0.Le > 0)
  389. {
  390. if (SmartcardExtension->T0.Le > SC_IFD_GEMCORE_T0_MAXIMUM_LEX)
  391. {
  392. status = STATUS_BUFFER_TOO_SMALL;
  393. }
  394. if (status == STATUS_SUCCESS)
  395. {
  396. response = G_Oros3IsoOutput
  397. (
  398. param->Handle,
  399. param->APDUTimeOut,
  400. HOR3GLL_IFD_CMD_ICC_ISO_OUT,
  401. (BYTE *)SmartcardExtension->SmartcardRequest.Buffer,
  402. &rlen,
  403. rbuff
  404. );
  405. }
  406. }
  407. /*------------------------------------------------------------------------------
  408. Else
  409. Is an ISO In command.
  410. If LC > SC_IFD_GEMCORE_T0_MAXIMUM_LC (255)
  411. <== STATUS_BUFFER_TOO_SMALL
  412. Call the G_Oros3IsoInput
  413. ------------------------------------------------------------------------------*/
  414. else
  415. {
  416. if (SmartcardExtension->T0.Lc > SC_IFD_GEMCORE_T0_MAXIMUM_LC)
  417. {
  418. status = STATUS_BUFFER_TOO_SMALL;
  419. }
  420. if (status == STATUS_SUCCESS)
  421. {
  422. response = G_Oros3IsoInput(
  423. param->Handle,
  424. param->APDUTimeOut,
  425. HOR3GLL_IFD_CMD_ICC_ISO_IN,
  426. (BYTE *)SmartcardExtension->SmartcardRequest.Buffer,
  427. (BYTE *)SmartcardExtension->SmartcardRequest.Buffer + 5,
  428. &rlen,
  429. rbuff
  430. );
  431. }
  432. }
  433. }
  434. /*------------------------------------------------------------------------------
  435. If the response == G_OK
  436. GE_Translate(reader status)
  437. Call the G_DDKTranslate function
  438. ------------------------------------------------------------------------------*/
  439. if (status == STATUS_SUCCESS)
  440. {
  441. if (response == G_OK)
  442. response = GE_Translate(rbuff[0]);
  443. status = GDDK_Translate(response,RDF_TRANSMIT);
  444. }
  445. /*------------------------------------------------------------------------------
  446. If the Status is Success
  447. Copy the response in the SmartcardReply buffer. Remove the status
  448. of the reader.
  449. Call the SmartcardT0reply function to update the IORequest struct.
  450. ------------------------------------------------------------------------------*/
  451. if (status == STATUS_SUCCESS)
  452. {
  453. ASSERT(SmartcardExtension->SmartcardReply.BufferSize >=
  454. (ULONG) (rlen - 1)
  455. );
  456. RtlCopyMemory(
  457. SmartcardExtension->SmartcardReply.Buffer,
  458. rbuff + 1,
  459. rlen - 1);
  460. SmartcardExtension->SmartcardReply.BufferLength = (ULONG) (rlen - 1);
  461. status = SmartcardT0Reply(SmartcardExtension);
  462. }
  463. break;
  464. /*------------------------------------------------------------------------------
  465. T=1 PROTOCOL:
  466. We don't use the SmartCardT1Request and SmartCardT1Reply functions,
  467. then we must verify the size of the buffers and the command ourselves.
  468. ------------------------------------------------------------------------------*/
  469. case SCARD_PROTOCOL_T1:
  470. buffLen = (USHORT)SmartcardExtension->IoRequest.RequestBufferLength -
  471. sizeof(SCARD_IO_REQUEST);
  472. buffIn = (UCHAR *)SmartcardExtension->IoRequest.RequestBuffer +
  473. sizeof(SCARD_IO_REQUEST);
  474. if (buffLen > 5)
  475. {
  476. lenIn = buffIn[4];
  477. if (buffLen > (USHORT)(5 + lenIn))
  478. {
  479. lenExp =((buffIn[5+ lenIn] == 0) ? 256 : buffIn[5 + lenIn]);
  480. }
  481. else
  482. {
  483. lenExp = 0;
  484. }
  485. }
  486. else if (buffLen == 5)
  487. {
  488. lenIn = 0;
  489. lenExp = ((buffIn[4] == 0) ? 256 : buffIn[4]);
  490. }
  491. else
  492. {
  493. lenExp = 0;
  494. lenIn = 0;
  495. }
  496. /*------------------------------------------------------------------------------
  497. If LEx > SC_IFD_GEMCORE_T1_MAXIMUM_LEX (256)
  498. STATUS_BUFFER_TOO_SMALL
  499. If LC > SC_IFD_GEMCORE_T1_MAXIMUM_LC (255)
  500. STATUS_BUFFER_TOO_SMALL
  501. ------------------------------------------------------------------------------*/
  502. if (lenExp > SC_IFD_GEMCORE_T1_MAXIMUM_LEX)
  503. {
  504. status = STATUS_BUFFER_TOO_SMALL;
  505. }
  506. else if (lenIn > SC_IFD_GEMCORE_T1_MAXIMUM_LC)
  507. {
  508. status = STATUS_BUFFER_TOO_SMALL;
  509. }
  510. /*------------------------------------------------------------------------------
  511. Call the G_Oros3IsoT1
  512. ------------------------------------------------------------------------------*/
  513. if (status == STATUS_SUCCESS)
  514. {
  515. rlen = HOR3GLL_BUFFER_SIZE;
  516. response = G_Oros3IsoT1(
  517. param->Handle,
  518. param->APDUTimeOut,
  519. HOR3GLL_IFD_CMD_ICC_APDU,
  520. buffLen,
  521. buffIn,
  522. &rlen,
  523. rbuff
  524. );
  525. }
  526. /*------------------------------------------------------------------------------
  527. If the response == G_OK
  528. GE_Translate(reader status)
  529. Call the G_DDKTranslate function
  530. ------------------------------------------------------------------------------*/
  531. if (status == STATUS_SUCCESS)
  532. {
  533. if (response == G_OK)
  534. response = GE_Translate(rbuff[0]);
  535. status = GDDK_Translate(response,RDF_TRANSMIT);
  536. }
  537. /*------------------------------------------------------------------------------
  538. If the Status is Success
  539. If the length of the returned bytes is greate than the size of the
  540. reply buffer
  541. <== STATUS_BUFFER_OVERFLOW
  542. Copy the response in the IoRequest.ReplyBuffer. Remove the status
  543. of the reader.
  544. <== STATUS_SUCCESS
  545. ------------------------------------------------------------------------------*/
  546. if (status == STATUS_SUCCESS)
  547. {
  548. if ( (rlen - 1) >
  549. (WORD16) ( SmartcardExtension->IoRequest.ReplyBufferLength -
  550. sizeof(SCARD_IO_REQUEST)
  551. )
  552. )
  553. {
  554. status = STATUS_BUFFER_TOO_SMALL;
  555. }
  556. if (status == STATUS_SUCCESS)
  557. {
  558. RtlCopyMemory(
  559. SmartcardExtension->IoRequest.ReplyBuffer + sizeof(SCARD_IO_REQUEST),
  560. rbuff + 1,
  561. rlen - 1
  562. );
  563. *(SmartcardExtension->IoRequest.Information) =
  564. (ULONG) sizeof(SCARD_IO_REQUEST) + rlen - 1;
  565. }
  566. }
  567. break;
  568. default:
  569. status = STATUS_INVALID_DEVICE_REQUEST;
  570. break;
  571. }
  572. /*------------------------------------------------------------------------------
  573. Unlock the mutex.
  574. ------------------------------------------------------------------------------*/
  575. GDDK_09UnlockExchange(SmartcardExtension);
  576. return (status);
  577. }
  578. /*******************************************************************************
  579. * NTSTATUS GDDK_09CardTracking
  580. * (
  581. * PSMARTCARD_EXTENSION SmartcardExtension
  582. * )
  583. *
  584. * Description :
  585. * -------------
  586. * This function is called by the Smart card library when an
  587. * IOCTL_SMARTCARD_IS_PRESENT or IOCTL_SMARTCARD_IS_ABSENT occurs.
  588. *
  589. * Remarks :
  590. * -------------
  591. * Nothing.
  592. *
  593. * In :
  594. * -------------
  595. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  596. * the current device.
  597. *
  598. * Out :
  599. * -------------
  600. * Nothing.
  601. *
  602. * Responses :
  603. * -------------
  604. * NTSTATUS
  605. *******************************************************************************/
  606. NTSTATUS GDDK_09CardTracking
  607. (
  608. PSMARTCARD_EXTENSION SmartcardExtension
  609. )
  610. {
  611. NTSTATUS
  612. status;
  613. KIRQL
  614. oldIrql;
  615. /*------------------------------------------------------------------------------
  616. Check if the reader can support this function.
  617. ------------------------------------------------------------------------------*/
  618. if (SmartcardExtension->ReaderExtension->IFDNumber != 0)
  619. {
  620. return STATUS_PENDING;
  621. }
  622. // Set cancel routine for the notification irp
  623. IoAcquireCancelSpinLock(&oldIrql);
  624. IoSetCancelRoutine(SmartcardExtension->OsData->NotificationIrp,GDDKNT_09Cleanup);
  625. IoReleaseCancelSpinLock(oldIrql);
  626. return STATUS_PENDING;
  627. }
  628. /*******************************************************************************
  629. * NTSTATUS GDDK_09SpecificIOCTL
  630. * (
  631. * PSMARTCARD_EXTENSION SmartcardExtension,
  632. * DWORD IoControlCode,
  633. * DWORD BufferInLen,
  634. * BYTE *BufferIn,
  635. * DWORD BufferOutLen,
  636. * BYTE *BufferOut,
  637. * DWORD *LengthOut
  638. *)
  639. *
  640. * Description :
  641. * -------------
  642. * This function is called when a specific IOCTL occurs.
  643. *
  644. * Remarks :
  645. * -------------
  646. * Nothing.
  647. *
  648. * In :
  649. * -------------
  650. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  651. * the current device.
  652. * - IoControlCode holds the IOCTL value.
  653. *
  654. * Out :
  655. * -------------
  656. * Nothing.
  657. *
  658. * Responses :
  659. * -------------
  660. * NTSTATUS
  661. *******************************************************************************/
  662. NTSTATUS GDDK_09SpecificIOCTL
  663. (
  664. PSMARTCARD_EXTENSION SmartcardExtension,
  665. DWORD IoControlCode,
  666. ULONG BufferInLen,
  667. BYTE *BufferIn,
  668. DWORD BufferOutLen,
  669. BYTE *BufferOut,
  670. DWORD *LengthOut
  671. )
  672. {
  673. /*------------------------------------------------------------------------------
  674. Set the reply buffer length to 0.
  675. ------------------------------------------------------------------------------*/
  676. *LengthOut = 0;
  677. /*------------------------------------------------------------------------------
  678. Switch for the different IOCTL:
  679. ------------------------------------------------------------------------------*/
  680. switch(IoControlCode)
  681. {
  682. /*------------------------------------------------------------------------------
  683. IOCTL_SMARTCARD_IFD_EXCHANGE:
  684. <== GDDK_09IFDExchange
  685. ------------------------------------------------------------------------------*/
  686. case IOCTL_SMARTCARD_IFD_EXCHANGE:
  687. return GDDK_09IFDExchange(
  688. SmartcardExtension,
  689. BufferInLen,
  690. BufferIn,
  691. BufferOutLen,
  692. BufferOut,
  693. LengthOut
  694. );
  695. break;
  696. default:
  697. return STATUS_NOT_SUPPORTED;
  698. break;
  699. }
  700. }
  701. /*******************************************************************************
  702. * NTSTATUS GDDK_09SpecificTag
  703. * (
  704. * PSMARTCARD_EXTENSION SmartcardExtension,
  705. * DWORD IoControlCode
  706. * DWORD BufferInLen,
  707. * BYTE *BufferIn,
  708. * DWORD BufferOutLen,
  709. * BYTE *BufferOut,
  710. * DWORD *LengthOut
  711. *)
  712. *
  713. * Description :
  714. * -------------
  715. * This function is called when a specific Tag request occurs.
  716. *
  717. * Remarks :
  718. * -------------
  719. * Nothing.
  720. *
  721. * In :
  722. * -------------
  723. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  724. * the current device.
  725. * - IoControlCode holds the IOCTL value.
  726. *
  727. * Out :
  728. * -------------
  729. * Nothing.
  730. *
  731. * Responses :
  732. * -------------
  733. * NTSTATUS
  734. *******************************************************************************/
  735. NTSTATUS GDDK_09SpecificTag
  736. (
  737. PSMARTCARD_EXTENSION SmartcardExtension,
  738. DWORD IoControlCode,
  739. DWORD BufferInLen,
  740. BYTE *BufferIn,
  741. DWORD BufferOutLen,
  742. BYTE *BufferOut,
  743. DWORD *LengthOut
  744. )
  745. {
  746. ULONG
  747. i,
  748. TagValue;
  749. PREADER_EXTENSION
  750. pReaderExtension = SmartcardExtension->ReaderExtension;
  751. ASSERT(pReaderExtension != NULL);
  752. /*------------------------------------------------------------------------------
  753. Set the reply buffer length to 0.
  754. ------------------------------------------------------------------------------*/
  755. *LengthOut = 0;
  756. /*------------------------------------------------------------------------------
  757. Verify the length of the Tag
  758. <== STATUS_BUFFER_TOO_SMALL
  759. ------------------------------------------------------------------------------*/
  760. if (BufferInLen < (DWORD) sizeof(TagValue))
  761. {
  762. return(STATUS_BUFFER_TOO_SMALL);
  763. }
  764. TagValue = (ULONG) *((PULONG)BufferIn);
  765. /*------------------------------------------------------------------------------
  766. Switch for the different IOCTL:
  767. Get the value of one tag (IOCTL_SMARTCARD_GET_ATTRIBUTE)
  768. Switch for the different Tags:
  769. ------------------------------------------------------------------------------*/
  770. switch(IoControlCode)
  771. {
  772. case IOCTL_SMARTCARD_GET_ATTRIBUTE:
  773. switch (TagValue)
  774. {
  775. /*------------------------------------------------------------------------------
  776. Baud rate of the reader (SCARD_ATTR_SPEC_BAUD_RATE)
  777. Verify the length of the output buffer.
  778. <== STATUS_BUFFER_TOO_SMALL
  779. Update the output buffer and the length.
  780. <== STATUS_SUCCESS
  781. ------------------------------------------------------------------------------*/
  782. case SCARD_ATTR_SPEC_BAUD_RATE:
  783. if ( BufferOutLen <
  784. (DWORD) sizeof(pReaderExtension->IFDBaudRate)
  785. )
  786. {
  787. return(STATUS_BUFFER_TOO_SMALL);
  788. }
  789. memcpy(
  790. BufferOut,
  791. &pReaderExtension->IFDBaudRate,
  792. sizeof(pReaderExtension->IFDBaudRate)
  793. );
  794. *(LengthOut) =
  795. (ULONG) sizeof(pReaderExtension->IFDBaudRate);
  796. return (STATUS_SUCCESS);
  797. break;
  798. /*------------------------------------------------------------------------------
  799. IFD number of the reader (SCARD_ATTR_SPEC_IFD_NUMBER)
  800. Verify the length of the output buffer.
  801. <== STATUS_BUFFER_TOO_SMALL
  802. Update the output buffer and the length.
  803. <== STATUS_SUCCESS
  804. ------------------------------------------------------------------------------*/
  805. case SCARD_ATTR_SPEC_IFD_NUMBER:
  806. if ( BufferOutLen <
  807. (DWORD) sizeof(pReaderExtension->IFDNumber)
  808. )
  809. {
  810. return(STATUS_BUFFER_TOO_SMALL);
  811. }
  812. memcpy(
  813. BufferOut,
  814. &pReaderExtension->IFDNumber,
  815. sizeof(pReaderExtension->IFDNumber)
  816. );
  817. *(LengthOut) =
  818. (ULONG) sizeof(pReaderExtension->IFDNumber);
  819. return STATUS_SUCCESS;
  820. break;
  821. /*------------------------------------------------------------------------------
  822. ICC type (SCARD_ATTR_SPEC_ICC_TYPE)
  823. Verify the length of the output buffer.
  824. <== STATUS_BUFFER_TOO_SMALL
  825. Update the output buffer and the length.
  826. <== STATUS_SUCCESS
  827. ------------------------------------------------------------------------------*/
  828. case SCARD_ATTR_SPEC_ICC_TYPE:
  829. if ( BufferOutLen <
  830. (DWORD) sizeof(pReaderExtension->ICCType)
  831. )
  832. {
  833. return(STATUS_BUFFER_TOO_SMALL);
  834. }
  835. memcpy(
  836. BufferOut,
  837. &pReaderExtension->ICCType,
  838. sizeof(pReaderExtension->ICCType)
  839. );
  840. *(LengthOut) =
  841. (ULONG) sizeof(pReaderExtension->ICCType);
  842. return STATUS_SUCCESS;
  843. break;
  844. /*------------------------------------------------------------------------------
  845. Power Timeout (SCARD_ATTR_SPEC_POWER_TIMEOUT)
  846. Verify the length of the output buffer.
  847. <== STATUS_BUFFER_TOO_SMALL
  848. Update the output buffer and the length.
  849. <== STATUS_SUCCESS
  850. ------------------------------------------------------------------------------*/
  851. case SCARD_ATTR_SPEC_POWER_TIMEOUT:
  852. if ( BufferOutLen <
  853. (DWORD) sizeof(pReaderExtension->PowerTimeOut)
  854. )
  855. {
  856. return(STATUS_BUFFER_TOO_SMALL);
  857. }
  858. memcpy(
  859. BufferOut,
  860. &pReaderExtension->PowerTimeOut,
  861. sizeof(pReaderExtension->PowerTimeOut)
  862. );
  863. *(LengthOut) =
  864. (ULONG) sizeof(pReaderExtension->PowerTimeOut);
  865. return STATUS_SUCCESS;
  866. break;
  867. /*------------------------------------------------------------------------------
  868. Command Timeout (SCARD_ATTR_SPEC_CMD_TIMEOUT)
  869. Verify the length of the output buffer.
  870. <== STATUS_BUFFER_TOO_SMALL
  871. Update the output buffer and the length.
  872. <== STATUS_SUCCESS
  873. ------------------------------------------------------------------------------*/
  874. case SCARD_ATTR_SPEC_CMD_TIMEOUT:
  875. if ( BufferOutLen <
  876. (DWORD) sizeof(pReaderExtension->CmdTimeOut)
  877. )
  878. {
  879. return(STATUS_BUFFER_TOO_SMALL);
  880. }
  881. memcpy(
  882. BufferOut,
  883. &pReaderExtension->CmdTimeOut,
  884. sizeof(pReaderExtension->CmdTimeOut)
  885. );
  886. *(LengthOut) =
  887. (ULONG) sizeof(pReaderExtension->CmdTimeOut);
  888. return STATUS_SUCCESS;
  889. break;
  890. /*------------------------------------------------------------------------------
  891. APDU Timeout (SCARD_ATTR_SPEC_APDU_TIMEOUT)
  892. Verify the length of the output buffer.
  893. <== STATUS_BUFFER_TOO_SMALL
  894. Update the output buffer and the length.
  895. <== STATUS_SUCCESS
  896. ------------------------------------------------------------------------------*/
  897. case SCARD_ATTR_SPEC_APDU_TIMEOUT:
  898. if ( BufferOutLen <
  899. (DWORD) sizeof(pReaderExtension->APDUTimeOut)
  900. )
  901. {
  902. return(STATUS_BUFFER_TOO_SMALL);
  903. }
  904. memcpy(
  905. BufferOut,
  906. &pReaderExtension->APDUTimeOut,
  907. sizeof(pReaderExtension->APDUTimeOut)
  908. );
  909. *(LengthOut) =
  910. (ULONG) sizeof(pReaderExtension->APDUTimeOut);
  911. return STATUS_SUCCESS;
  912. break;
  913. /*------------------------------------------------------------------------------
  914. IFD Option (SCARD_ATTR_SPEC_IFD_OPTION)
  915. Verify the length of the output buffer.
  916. <== STATUS_BUFFER_TOO_SMALL
  917. Update the output buffer and the length.
  918. <== STATUS_SUCCESS
  919. ------------------------------------------------------------------------------*/
  920. case SCARD_ATTR_SPEC_IFD_OPTION:
  921. if ( BufferOutLen <
  922. sizeof(pReaderExtension->IFDOption)
  923. )
  924. {
  925. return(STATUS_BUFFER_TOO_SMALL);
  926. }
  927. memcpy(
  928. BufferOut,
  929. &pReaderExtension->IFDOption,
  930. sizeof(pReaderExtension->IFDOption)
  931. );
  932. *(LengthOut) =
  933. (ULONG) sizeof(pReaderExtension->IFDOption);
  934. return STATUS_SUCCESS;
  935. break;
  936. /*------------------------------------------------------------------------------
  937. IFD Option (SCARD_ATTR_SPEC_MAXIMAL_IFD)
  938. Verify the length of the output buffer.
  939. <== STATUS_BUFFER_TOO_SMALL
  940. Update the output buffer and the length.
  941. <== STATUS_SUCCESS
  942. ------------------------------------------------------------------------------*/
  943. case SCARD_ATTR_SPEC_MAXIMAL_IFD:
  944. if ( BufferOutLen <
  945. sizeof(pReaderExtension->MaximalIFD)
  946. )
  947. {
  948. return(STATUS_BUFFER_TOO_SMALL);
  949. }
  950. memcpy(
  951. BufferOut,
  952. &pReaderExtension->MaximalIFD,
  953. sizeof(pReaderExtension->MaximalIFD)
  954. );
  955. *(LengthOut) =
  956. (ULONG) sizeof(pReaderExtension->MaximalIFD);
  957. return STATUS_SUCCESS;
  958. break;
  959. /*------------------------------------------------------------------------------
  960. Unknown tag
  961. <== STATUS_NOT_SUPPORTED
  962. ------------------------------------------------------------------------------*/
  963. default:
  964. return STATUS_NOT_SUPPORTED;
  965. break;
  966. }
  967. break;
  968. /*------------------------------------------------------------------------------
  969. Set the value of one tag (IOCTL_SMARTCARD_SET_ATTRIBUTE)
  970. Switch for the different Tags:
  971. ------------------------------------------------------------------------------*/
  972. case IOCTL_SMARTCARD_SET_ATTRIBUTE:
  973. switch (TagValue)
  974. {
  975. /*------------------------------------------------------------------------------
  976. ICC type (SCARD_ATTR_SPEC_ICC_TYPE)
  977. Verify the length of the input buffer.
  978. <== STATUS_BUFFER_TOO_SMALL
  979. Update the value.
  980. <== STATUS_SUCCESS
  981. ------------------------------------------------------------------------------*/
  982. case SCARD_ATTR_SPEC_ICC_TYPE:
  983. if ( BufferInLen <
  984. (DWORD) ( sizeof(pReaderExtension->ICCType) + sizeof(TagValue))
  985. )
  986. {
  987. return(STATUS_BUFFER_TOO_SMALL);
  988. }
  989. memcpy(
  990. &pReaderExtension->ICCType,
  991. BufferIn + sizeof(TagValue),
  992. sizeof(pReaderExtension->ICCType)
  993. );
  994. return STATUS_SUCCESS;
  995. break;
  996. /*------------------------------------------------------------------------------
  997. Power Timeout (SCARD_ATTR_SPEC_POWER_TIMEOUT)
  998. Verify the length of the input buffer.
  999. <== STATUS_BUFFER_TOO_SMALL
  1000. Update the value.
  1001. <== STATUS_SUCCESS
  1002. ------------------------------------------------------------------------------*/
  1003. case SCARD_ATTR_SPEC_POWER_TIMEOUT:
  1004. if ( BufferInLen <
  1005. (DWORD) (sizeof(pReaderExtension->PowerTimeOut) + sizeof(TagValue))
  1006. )
  1007. {
  1008. return(STATUS_BUFFER_TOO_SMALL);
  1009. }
  1010. memcpy(
  1011. &pReaderExtension->PowerTimeOut,
  1012. BufferIn + sizeof(TagValue),
  1013. sizeof(pReaderExtension->PowerTimeOut)
  1014. );
  1015. return STATUS_SUCCESS;
  1016. break;
  1017. /*------------------------------------------------------------------------------
  1018. Command Timeout (SCARD_ATTR_SPEC_CMD_TIMEOUT)
  1019. Verify the length of the input buffer.
  1020. <== STATUS_BUFFER_TOO_SMALL
  1021. Update the value.
  1022. <== STATUS_SUCCESS
  1023. ------------------------------------------------------------------------------*/
  1024. case SCARD_ATTR_SPEC_CMD_TIMEOUT:
  1025. if ( BufferInLen <
  1026. (DWORD) (sizeof(pReaderExtension->CmdTimeOut) + sizeof(TagValue))
  1027. )
  1028. {
  1029. return(STATUS_BUFFER_TOO_SMALL);
  1030. }
  1031. memcpy(
  1032. &pReaderExtension->CmdTimeOut,
  1033. BufferIn + sizeof(TagValue),
  1034. sizeof(pReaderExtension->CmdTimeOut)
  1035. );
  1036. return STATUS_SUCCESS;
  1037. break;
  1038. /*------------------------------------------------------------------------------
  1039. Command Timeout (SCARD_ATTR_SPEC_APDU_TIMEOUT)
  1040. Verify the length of the input buffer.
  1041. <== STATUS_BUFFER_TOO_SMALL
  1042. Update the value.
  1043. <== STATUS_SUCCESS
  1044. ------------------------------------------------------------------------------*/
  1045. case SCARD_ATTR_SPEC_APDU_TIMEOUT:
  1046. if ( BufferInLen <
  1047. (DWORD) (sizeof(pReaderExtension->APDUTimeOut) + sizeof(TagValue))
  1048. )
  1049. {
  1050. return(STATUS_BUFFER_TOO_SMALL);
  1051. }
  1052. memcpy(
  1053. &pReaderExtension->APDUTimeOut,
  1054. BufferIn + sizeof(TagValue),
  1055. sizeof(pReaderExtension->APDUTimeOut)
  1056. );
  1057. return STATUS_SUCCESS;
  1058. break;
  1059. /*------------------------------------------------------------------------------
  1060. Unknown tag
  1061. <== STATUS_NOT_SUPPORTED
  1062. ------------------------------------------------------------------------------*/
  1063. default:
  1064. return STATUS_NOT_SUPPORTED;
  1065. }
  1066. break;
  1067. default:
  1068. return STATUS_NOT_SUPPORTED;
  1069. break;
  1070. }
  1071. }
  1072. /*******************************************************************************
  1073. * NTSTATUS GDDK_09OpenChannel
  1074. * (
  1075. * PSMARTCARD_EXTENSION SmartcardExtension,
  1076. * CONST WORD32 DeviceNumber,
  1077. * CONST WORD32 PortSerialNumber,
  1078. * CONST WORD32 IFDNumber,
  1079. * CONST WORD32 MaximalBaudRate
  1080. * )
  1081. * Description :
  1082. * -------------
  1083. * This routine try to establish a connection with a reader, and after
  1084. * update the characteristic of this reader.
  1085. *
  1086. * Remarks :
  1087. * -------------
  1088. * Nothing.
  1089. *
  1090. * In :
  1091. * -------------
  1092. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  1093. * the current device.
  1094. * - DeviceNumber holds the current device number (0 to MAX_DEVICES).
  1095. * - PortSerialNumber holds the port serial number (0 to HGTSER_MAX_PORT).
  1096. * - IFDNumber holds the numero of the IFD in the reader (0 to MAX_IFD_BY_READER)
  1097. * - MaximalBaudRate holds the maximal speed specified for the reader.
  1098. *
  1099. * Out :
  1100. * -------------
  1101. * - SmartcardExtension is updated.
  1102. *
  1103. * Responses :
  1104. * -------------
  1105. * If everything is Ok:
  1106. * G_OK
  1107. *******************************************************************************/
  1108. NTSTATUS GDDK_09OpenChannel
  1109. (
  1110. PSMARTCARD_EXTENSION SmartcardExtension,
  1111. CONST WORD32 DeviceNumber,
  1112. CONST WORD32 PortSerialNumber,
  1113. CONST WORD32 IFDNumber,
  1114. CONST WORD32 MaximalBaudRate
  1115. )
  1116. {
  1117. /*------------------------------------------------------------------------------
  1118. Local variables:
  1119. - handle holds the communication handle to associate to the channel.
  1120. - channel_nb holds the number associated to the channel.
  1121. - lmod_name and lmod_release are used to control the called library version.
  1122. - response holds the called function responses.
  1123. - os_string and os_length are used to recognized an OROS2.x IFD on the channel.
  1124. - oros_version holds the minor version value of the IFD.
  1125. - user, comm and br are used to optimizes the baudrate.
  1126. ------------------------------------------------------------------------------*/
  1127. NTSTATUS
  1128. status = STATUS_SUCCESS;
  1129. INT16
  1130. handle,
  1131. portcom,
  1132. channel_nb,
  1133. i,
  1134. oros_version,
  1135. response;
  1136. char G_FAR
  1137. *oros_info;
  1138. char
  1139. os_string[HOR3GLL_OS_STRING_SIZE];
  1140. WORD16
  1141. os_length = HOR3GLL_OS_STRING_SIZE;
  1142. WORD16
  1143. user;
  1144. TGTSER_PORT
  1145. comm;
  1146. WORD32
  1147. br;
  1148. BYTE
  1149. minorVersion,
  1150. majorVersion;
  1151. BOOL
  1152. b_compare = TRUE;
  1153. G4_CHANNEL_PARAM
  1154. g4_channel;
  1155. WORD16
  1156. rlen;
  1157. BYTE
  1158. cmd[5],
  1159. rbuff[HOR3GLL_BUFFER_SIZE];
  1160. /*------------------------------------------------------------------------------
  1161. Update the serial communication channel information:
  1162. ------------------------------------------------------------------------------*/
  1163. g4_channel.Comm.Serial.Port = PortSerialNumber + G_COM1;
  1164. g4_channel.Comm.Serial.BaudRate = MaximalBaudRate;
  1165. g4_channel.Comm.Serial.ITNumber = DEFAULT_IT;
  1166. g4_channel.pSmartcardExtension = SmartcardExtension;
  1167. /*------------------------------------------------------------------------------
  1168. Initializes a mutex object (in a high level) for the exchange commands with
  1169. the smart card reader.
  1170. ------------------------------------------------------------------------------*/
  1171. KeInitializeMutex(
  1172. &SmartcardExtension->ReaderExtension->ExchangeMutex,
  1173. 3
  1174. );
  1175. /*------------------------------------------------------------------------------
  1176. Initializes a mutex object (in a high level) for the long APDU commands with
  1177. the smart card reader.
  1178. ------------------------------------------------------------------------------*/
  1179. KeInitializeMutex(
  1180. &SmartcardExtension->ReaderExtension->LongAPDUMutex,
  1181. 3
  1182. );
  1183. /*------------------------------------------------------------------------------
  1184. Opens a serial communication channel:
  1185. Open a communication channel (G_Oros3OpenComm).
  1186. The reader baudrate is automatically detected by this function.
  1187. If the port is already opened
  1188. Then
  1189. Adds a user on this port (G_SerPortAddUser)
  1190. <= Test the last received status (>= G_OK): G_Oros3OpenComm/G_SerPortAddUser
  1191. ------------------------------------------------------------------------------*/
  1192. handle = (INT16)DeviceNumber;
  1193. response = G_Oros3OpenComm(&g4_channel,handle);
  1194. if (response == GE_HOST_PORT_OPEN)
  1195. {
  1196. response = portcom = G_SerPortAddUser((WORD16) g4_channel.Comm.Serial.Port);
  1197. if (response < G_OK)
  1198. {
  1199. return (GDDK_Translate(response,(const ULONG) NULL));
  1200. }
  1201. G_GBPOpen(handle,2,4,portcom);
  1202. }
  1203. if (response < G_OK)
  1204. {
  1205. return (GDDK_Translate(response,(const ULONG) NULL));
  1206. }
  1207. /*------------------------------------------------------------------------------
  1208. Verifies that an OROS3.x IFD is connected to the selected port.
  1209. Sets the command according to the parameters. Read OROS memory type 0x05,
  1210. 13 bytes from 0x3FE0.
  1211. <= G_Oros3Exchange status.
  1212. ------------------------------------------------------------------------------*/
  1213. cmd[0] = (BYTE) HOR3GLL_IFD_CMD_MEM_RD;
  1214. cmd[1] = (BYTE)HOR3GLL_IFD_TYP_VERSION;
  1215. cmd[2] = HIBYTE(HOR3GLL_IFD_ADD_VERSION);
  1216. cmd[3] = LOBYTE(HOR3GLL_IFD_ADD_VERSION);
  1217. cmd[4] = (BYTE)HOR3GLL_IFD_LEN_VERSION;
  1218. response = G_Oros3Exchange(
  1219. handle,
  1220. HOR3GLL_LOW_TIME,
  1221. 5,
  1222. cmd,
  1223. &os_length,
  1224. os_string
  1225. );
  1226. if (response < G_OK)
  1227. {
  1228. G_Oros3CloseComm(handle);
  1229. return (GDDK_Translate(response,(const ULONG) NULL));
  1230. }
  1231. /*------------------------------------------------------------------------------
  1232. Verify the Firmware version: this driver support only the GemCore based
  1233. readers.
  1234. Read the minor version of the reader.
  1235. ------------------------------------------------------------------------------*/
  1236. if (os_length >= (WORD16)strlen(IFD_FIRMWARE_VERSION))
  1237. {
  1238. if (memcmp(os_string + 1,IFD_FIRMWARE_VERSION,strlen(IFD_FIRMWARE_VERSION)))
  1239. {
  1240. G_Oros3CloseComm(handle);
  1241. return (GDDK_Translate(GE_IFD_UNKNOWN,(const ULONG) NULL));
  1242. }
  1243. }
  1244. else
  1245. {
  1246. G_Oros3CloseComm(handle);
  1247. return (GDDK_Translate(GE_IFD_UNKNOWN,(const ULONG) NULL));
  1248. }
  1249. majorVersion = os_string[strlen(IFD_FIRMWARE_VERSION)-1] - '0';
  1250. minorVersion = 10 * (os_string[strlen(IFD_FIRMWARE_VERSION)+1] - '0') +
  1251. os_string[strlen(IFD_FIRMWARE_VERSION)+2] - '0';
  1252. /*------------------------------------------------------------------------------
  1253. Verify if the reader can support a security module
  1254. ------------------------------------------------------------------------------*/
  1255. if (IFDNumber > 0)
  1256. {
  1257. rlen = HOR3GLL_BUFFER_SIZE;
  1258. response = G_Oros3IccPowerDown
  1259. (
  1260. handle,
  1261. HOR3GLL_DEFAULT_TIME,
  1262. &rlen,
  1263. rbuff
  1264. );
  1265. if ((response != G_OK) || (rlen != 1) || ((rbuff[0] != 0x00) && (rbuff[0] != 0xFB)))
  1266. {
  1267. G_Oros3CloseComm(handle);
  1268. return STATUS_NO_MEDIA;
  1269. }
  1270. }
  1271. /*------------------------------------------------------------------------------
  1272. Optimizes the baudrate:
  1273. Initializes the comm variable to modify the used baud rate.
  1274. The optimization start at the given baudrate, then the used value is divised
  1275. by 2 until the communication is possible or the tried baudrate is lower
  1276. than 9600.
  1277. ------------------------------------------------------------------------------*/
  1278. comm.Port = (WORD16) g4_channel.Comm.Serial.Port;
  1279. response = G_SerPortGetState(&comm,&user);
  1280. comm.BaudRate = g4_channel.Comm.Serial.BaudRate;
  1281. for(br = g4_channel.Comm.Serial.BaudRate; br >= 9600lu; br = br / 2)
  1282. {
  1283. /*------------------------------------------------------------------------------
  1284. The reader is switched to the selected value (G_Oros3SIOConfigure). The
  1285. function status is not tested because, as the IFD has switched
  1286. immediatly, it is not possible to read its response.
  1287. ------------------------------------------------------------------------------*/
  1288. comm.BaudRate = br;
  1289. rlen = HOR3GLL_BUFFER_SIZE;
  1290. G_Oros3SIOConfigure(
  1291. handle,
  1292. HOR3GLL_LOW_TIME,
  1293. 0,
  1294. 8,
  1295. comm.BaudRate,
  1296. &rlen,
  1297. rbuff
  1298. );
  1299. /*------------------------------------------------------------------------------
  1300. Host is switched to the selected value (G_SerPortSetState).
  1301. If this call is successful,
  1302. Then
  1303. The last SIO command is re-sent to read the IFD response.
  1304. response is optionnaly initialized with the translated IFD status.
  1305. ------------------------------------------------------------------------------*/
  1306. response = G_SerPortSetState(&comm);
  1307. if (response == G_OK)
  1308. {
  1309. rlen = HOR3GLL_BUFFER_SIZE;
  1310. response = G_Oros3SIOConfigure(
  1311. handle,
  1312. HOR3GLL_LOW_TIME,
  1313. 0,
  1314. 8,
  1315. comm.BaudRate,
  1316. &rlen,
  1317. rbuff
  1318. );
  1319. if (response >= G_OK)
  1320. {
  1321. response = GE_Translate(rbuff[0]);
  1322. break;
  1323. }
  1324. }
  1325. }
  1326. /*------------------------------------------------------------------------------
  1327. If the loop is ended without a good communication with IFD,
  1328. Then
  1329. The port is closed.
  1330. <= GE_HI_COMM.
  1331. ------------------------------------------------------------------------------*/
  1332. if ((br < 9600) || (response != G_OK))
  1333. {
  1334. G_Oros3CloseComm(handle);
  1335. return (GDDK_Translate(GE_HI_COMM,(const ULONG) NULL));
  1336. }
  1337. /*------------------------------------------------------------------------------
  1338. Removes the TLP compatibility mode.
  1339. <= Sends the SetMode command with parameter 0 to disable TLP compatibility.
  1340. Closes the opened port (G_Oros3CloseComm).
  1341. ------------------------------------------------------------------------------*/
  1342. rlen = HOR3GLL_BUFFER_SIZE;
  1343. response = G_Oros3SetMode(handle,HOR3GLL_LOW_TIME,0x00,&rlen,rbuff);
  1344. if (response < G_OK)
  1345. {
  1346. G_Oros3CloseComm(handle);
  1347. return (GDDK_Translate(response,(const ULONG) NULL));
  1348. }
  1349. /*------------------------------------------------------------------------------
  1350. Reader capabilities:
  1351. - the type of the reader (SCARD_READER_TYPE_SERIAL)
  1352. - the channel for the reader (PortSerialNumber)
  1353. - the protocols supported by the reader (SCARD_PROTOCOL_T0, SCARD_PROTOCOL_T1)
  1354. - the mechanical characteristic of the reader:
  1355. Verify if the reader can supports the detection of the card
  1356. insertion/removal. Only the main reader supports this functionnality.
  1357. ------------------------------------------------------------------------------*/
  1358. SmartcardExtension->ReaderCapabilities.ReaderType =
  1359. SCARD_READER_TYPE_SERIAL;
  1360. SmartcardExtension->ReaderCapabilities.Channel =
  1361. PortSerialNumber;
  1362. #if SMCLIB_VERSION >= 0x0130
  1363. SmartcardExtension->ReaderCapabilities.SupportedProtocols =
  1364. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  1365. #else
  1366. SmartcardExtension->ReaderCapabilities.SupportedProtocols.Async =
  1367. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  1368. #endif
  1369. SmartcardExtension->ReaderCapabilities.MechProperties = 0;
  1370. /*------------------------------------------------------------------------------
  1371. Reader capabilities (continue):
  1372. - the default clock frequency (SC_IFD_GEMCORE_DEFAULT_CLK_FREQUENCY)
  1373. - the maximum clock frequency (SC_IFD_GEMCORE_MAXIMUM_CLK_FREQUENCY)
  1374. - the default data rate (SC_IFD_GEMCORE_DEFAULT_DATA_RATE)
  1375. - the maximum data rate (SC_IFD_GEMCORE_MAXIMUM_DATA_RATE)
  1376. - the maximum IFSD (SC_IFD_GEMCORE_MAXIMUM_IFSD)
  1377. - the power management is set to 0.
  1378. ------------------------------------------------------------------------------*/
  1379. SmartcardExtension->ReaderCapabilities.CLKFrequency.Default =
  1380. SC_IFD_GEMCORE_DEFAULT_CLK_FREQUENCY;
  1381. SmartcardExtension->ReaderCapabilities.CLKFrequency.Max =
  1382. SC_IFD_GEMCORE_MAXIMUM_CLK_FREQUENCY;
  1383. SmartcardExtension->ReaderCapabilities.DataRate.Default =
  1384. SC_IFD_GEMCORE_DEFAULT_DATA_RATE;
  1385. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  1386. SC_IFD_GEMCORE_MAXIMUM_DATA_RATE;
  1387. SmartcardExtension->ReaderCapabilities.MaxIFSD =
  1388. SC_IFD_GEMCORE_MAXIMUM_IFSD;
  1389. SmartcardExtension->ReaderCapabilities.PowerMgmtSupport = 0;
  1390. #if SMCLIB_VERSION >= 0x0130
  1391. /*------------------------------------------------------------------------------
  1392. Reader capabilities (continue):
  1393. - List all the supported data rates
  1394. ------------------------------------------------------------------------------*/
  1395. SmartcardExtension->ReaderCapabilities.DataRatesSupported.List =
  1396. dataRatesSupported;
  1397. SmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
  1398. sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
  1399. #endif
  1400. /*------------------------------------------------------------------------------
  1401. Vendor Attributes:
  1402. - the vendor information (SC_VENDOR_NAME)
  1403. ------------------------------------------------------------------------------*/
  1404. strcpy(
  1405. SmartcardExtension->VendorAttr.VendorName.Buffer,
  1406. SC_VENDOR_NAME
  1407. );
  1408. SmartcardExtension->VendorAttr.VendorName.Length =
  1409. strlen(SmartcardExtension->VendorAttr.VendorName.Buffer);
  1410. /*------------------------------------------------------------------------------
  1411. Vendor Attributes (continue):
  1412. - the IFD Type information (SC_IFD_SAM_TYPE or SC_IFD_TYPE)
  1413. ------------------------------------------------------------------------------*/
  1414. if (IFDNumber > 0)
  1415. {
  1416. strcpy(SmartcardExtension->VendorAttr.IfdType.Buffer,SC_IFD_SAM_TYPE);
  1417. }
  1418. else
  1419. {
  1420. strcpy(SmartcardExtension->VendorAttr.IfdType.Buffer,SC_IFD_TYPE);
  1421. }
  1422. SmartcardExtension->VendorAttr.IfdType.Length =
  1423. strlen(SmartcardExtension->VendorAttr.IfdType.Buffer);
  1424. /*------------------------------------------------------------------------------
  1425. Vendor Attributes (continue):
  1426. - the UnitNo information. Is set to the device number.
  1427. - the IFD serial number (is set to a NULL string).
  1428. - the IFD version is set.
  1429. ------------------------------------------------------------------------------*/
  1430. SmartcardExtension->VendorAttr.UnitNo = DeviceNumber;
  1431. SmartcardExtension->VendorAttr.IfdSerialNo.Length = 0;
  1432. SmartcardExtension->VendorAttr.IfdVersion.VersionMajor = (UCHAR)majorVersion;
  1433. SmartcardExtension->VendorAttr.IfdVersion.VersionMinor = (UCHAR)minorVersion;
  1434. SmartcardExtension->VendorAttr.IfdVersion.BuildNumber = 0;
  1435. /*------------------------------------------------------------------------------
  1436. Reader Extension:
  1437. - the Handle of the reader.
  1438. - the IFD number of the reader.
  1439. - the ICCType (ISOCARD).
  1440. - the ICCVpp (HOR3GLL_DEFAULT_VPP).
  1441. - the ICCPresence.
  1442. - the command timeout for the reader (HOR3GLL_DEFAULT_TIME).
  1443. - the IFD baud rate.
  1444. - the power timeout (0).
  1445. - the selected VCC power supply voltage value.
  1446. - the PTS negotiate mode.
  1447. - the parameter PTS0.
  1448. - the parameter PTS1.
  1449. - the parameter PTS2.
  1450. - the parameter PTS3.
  1451. ------------------------------------------------------------------------------*/
  1452. SmartcardExtension->ReaderExtension->Handle = handle;
  1453. SmartcardExtension->ReaderExtension->IFDNumber = IFDNumber;
  1454. SmartcardExtension->ReaderExtension->ICCType = ISOCARD;
  1455. SmartcardExtension->ReaderExtension->ICCVpp = HOR3GLL_DEFAULT_VPP;
  1456. SmartcardExtension->ReaderExtension->APDUTimeOut = HOR3GLL_DEFAULT_TIME * 24;
  1457. SmartcardExtension->ReaderExtension->CmdTimeOut = HOR3GLL_DEFAULT_TIME;
  1458. SmartcardExtension->ReaderExtension->IFDBaudRate = br;
  1459. SmartcardExtension->ReaderExtension->PowerTimeOut = ICC_DEFAULT_POWER_TIMOUT;
  1460. SmartcardExtension->ReaderExtension->ICCVcc = ICC_VCC_5V;
  1461. SmartcardExtension->ReaderExtension->PTSMode = IFD_DEFAULT_MODE;
  1462. SmartcardExtension->ReaderExtension->PTS0 = 0;
  1463. SmartcardExtension->ReaderExtension->PTS1 = 0;
  1464. SmartcardExtension->ReaderExtension->PTS2 = 0;
  1465. SmartcardExtension->ReaderExtension->PTS3 = 0;
  1466. SmartcardExtension->ReaderExtension->ICCPresence = HOR3GLL_DEFAULT_PRESENCE;
  1467. /*------------------------------------------------------------------------------
  1468. Define the type of the card (ISOCARD) and set the card presence
  1469. ------------------------------------------------------------------------------*/
  1470. rlen = HOR3GLL_BUFFER_SIZE;
  1471. response = G_Oros3IccDefineType(
  1472. handle,
  1473. HOR3GLL_LOW_TIME,
  1474. ISOCARD,
  1475. HOR3GLL_DEFAULT_VPP,
  1476. SmartcardExtension->ReaderExtension->ICCPresence,
  1477. &rlen,
  1478. rbuff
  1479. );
  1480. /*------------------------------------------------------------------------------
  1481. Verify the response of the reader
  1482. ------------------------------------------------------------------------------*/
  1483. if (response == G_OK)
  1484. {
  1485. response = GE_Translate(rbuff[0]);
  1486. }
  1487. if (response != G_OK)
  1488. {
  1489. G_Oros3CloseComm(handle);
  1490. return(GDDK_Translate(response,(const ULONG) NULL));
  1491. }
  1492. /*------------------------------------------------------------------------------
  1493. Update the status of the card (only for the main reader).
  1494. If a card is inserted:
  1495. Set the detection on the remove of the card.
  1496. else
  1497. Set the detection on the insertion of the card.
  1498. ------------------------------------------------------------------------------*/
  1499. if (IFDNumber == 0)
  1500. {
  1501. GDDK_09UpdateCardStatus(SmartcardExtension);
  1502. }
  1503. else
  1504. {
  1505. /*------------------------------------------------------------------------------
  1506. <= Security Module is powered up.
  1507. The function status and the IFD status are tested.
  1508. ------------------------------------------------------------------------------*/
  1509. rlen = HOR3GLL_BUFFER_SIZE;
  1510. response = G_Oros3IccPowerUp(
  1511. SmartcardExtension->ReaderExtension->Handle,
  1512. HOR3GLL_LOW_TIME,
  1513. SmartcardExtension->ReaderExtension->ICCVcc,
  1514. SmartcardExtension->ReaderExtension->PTSMode,
  1515. SmartcardExtension->ReaderExtension->PTS0,
  1516. SmartcardExtension->ReaderExtension->PTS1,
  1517. SmartcardExtension->ReaderExtension->PTS2,
  1518. SmartcardExtension->ReaderExtension->PTS3,
  1519. &rlen,
  1520. rbuff
  1521. );
  1522. // Verify the response of the reader
  1523. if (response >= G_OK)
  1524. {
  1525. response = GE_Translate(rbuff[0]);
  1526. }
  1527. if (response < G_OK)
  1528. {
  1529. // The card is absent
  1530. SmartcardExtension->ReaderCapabilities.CurrentState =
  1531. SCARD_ABSENT;
  1532. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1533. SCARD_PROTOCOL_UNDEFINED;
  1534. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  1535. }
  1536. else
  1537. {
  1538. // The card is present for use but not powered
  1539. SmartcardExtension->ReaderCapabilities.CurrentState =
  1540. SCARD_SWALLOWED;
  1541. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1542. SCARD_PROTOCOL_UNDEFINED;
  1543. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  1544. // Security module is powered off.
  1545. rlen = HOR3GLL_BUFFER_SIZE;
  1546. response = G_Oros3IccPowerDown(
  1547. SmartcardExtension->ReaderExtension->Handle,
  1548. HOR3GLL_LOW_TIME,
  1549. &rlen,
  1550. rbuff
  1551. );
  1552. }
  1553. }
  1554. return(GDDK_Translate(G_OK,(const ULONG) NULL));
  1555. }
  1556. /*******************************************************************************
  1557. * NTSTATUS GDDK_09CloseChannel
  1558. * (
  1559. * PSMARTCARD_EXTENSION SmartcardExtension
  1560. * )
  1561. * Description :
  1562. * -------------
  1563. * This routine close a conection previously opened with a reader.
  1564. *
  1565. * Remarks :
  1566. * -------------
  1567. * Nothing.
  1568. *
  1569. * In :
  1570. * -------------
  1571. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  1572. * the current device.
  1573. *
  1574. * Out :
  1575. * -------------
  1576. * - SmartcardExtension is updated.
  1577. *
  1578. * Responses :
  1579. * -------------
  1580. * If everything is Ok:
  1581. * STATUS_SUCCESS
  1582. *******************************************************************************/
  1583. NTSTATUS GDDK_09CloseChannel
  1584. (
  1585. PSMARTCARD_EXTENSION SmartcardExtension
  1586. )
  1587. {
  1588. /*------------------------------------------------------------------------------
  1589. Local variables:
  1590. - response holds the called function responses.
  1591. ------------------------------------------------------------------------------*/
  1592. INT16
  1593. response;
  1594. READER_EXTENSION
  1595. *param = SmartcardExtension->ReaderExtension;
  1596. WORD16
  1597. rlen;
  1598. BYTE
  1599. rbuff[HOR3GLL_BUFFER_SIZE];
  1600. /*------------------------------------------------------------------------------
  1601. Call power down function:
  1602. ------------------------------------------------------------------------------*/
  1603. rlen = HOR3GLL_BUFFER_SIZE;
  1604. response = G_Oros3IccPowerDown(
  1605. param->Handle,
  1606. HOR3GLL_LOW_TIME,
  1607. &rlen,
  1608. rbuff
  1609. );
  1610. /*------------------------------------------------------------------------------
  1611. <= G_Oros3CloseComm status.
  1612. ------------------------------------------------------------------------------*/
  1613. return (GDDK_Translate(G_Oros3CloseComm(param->Handle),(const ULONG) NULL));
  1614. }
  1615. /*******************************************************************************
  1616. * NTSTATUS GDDK_09OpenSession
  1617. * (
  1618. * PSMARTCARD_EXTENSION SmartcardExtension
  1619. * )
  1620. * Description :
  1621. * -------------
  1622. * Opens a cold session with the selected ICC type.
  1623. * A power off is made on ICC before the call to power up function.
  1624. * For the ISO card, during the power up this function negotiates with the
  1625. * ICC speed and protocole in accordance with PTS mode and sets the ICC power
  1626. * supply voltage.
  1627. * The session structure is updated with values found in ATR.
  1628. *
  1629. * Remarks :
  1630. * -------------
  1631. * - The security module in OROS 3.x IFD only support the sames cards that main
  1632. * reader interface (ISO card T=0, T=1 and Synchronous card).
  1633. * - To change PTS mode and parameters used the function G4_09ICCSetPTS.
  1634. * - To change ICC power supply voltage used the function G4_09ICCSetVoltage.
  1635. * - For a specific card not supported by the OROS system, you must have
  1636. * in the GEMPLUS_LIB_PATH directory, or the current directory, the Card driver
  1637. * for this card.
  1638. * For example ICCDRV04.ORO for the GPM416 (0x04) card.
  1639. * GEMPLUS_LIB_PATH is an environnement variable used to defined the directory
  1640. * where the Card drivers are located.
  1641. * WARNING:
  1642. * - The full path name of the card driver is case sensitive in UNIX target.
  1643. * - The card driver name is in upper case.
  1644. *
  1645. * In :
  1646. * -------------
  1647. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  1648. * the current device.
  1649. *
  1650. * Out :
  1651. * -------------
  1652. * - SmartcardExtension is updated.
  1653. * - Status of the SCMLIB library.
  1654. *
  1655. * Responses :
  1656. * -------------
  1657. * If everything is Ok:
  1658. * G_OK
  1659. *******************************************************************************/
  1660. NTSTATUS GDDK_09OpenSession
  1661. (
  1662. PSMARTCARD_EXTENSION SmartcardExtension
  1663. )
  1664. {
  1665. /*------------------------------------------------------------------------------
  1666. Local variables:
  1667. - response holds the called function responses.
  1668. - ifd_type is used for ICC/SM management.
  1669. - offset, l and k are used to glance through the ATR.
  1670. - i is a counter.
  1671. - protocol memorises the ICC protocol.
  1672. It is initialized to 0 for T=0 default protocol.
  1673. - protocol_set is used to detect the first protocol byte.
  1674. It is initialized to FALSE because the first protocol byte has not been
  1675. encountered.
  1676. - end_time is used to wait for ICC to be really powered off.
  1677. - icc_type holds the ICC type translated in OROS value.
  1678. ------------------------------------------------------------------------------*/
  1679. INT16
  1680. response,
  1681. ifd_type,
  1682. icc_supported,
  1683. offset,
  1684. l;
  1685. WORD8
  1686. k;
  1687. WORD16
  1688. protocol = 0,
  1689. card_driver_version,
  1690. card_driver_protocol,
  1691. icc_type;
  1692. BOOL
  1693. protocol_set = FALSE;
  1694. WORD32
  1695. end_time;
  1696. READER_EXTENSION
  1697. *param = SmartcardExtension->ReaderExtension;
  1698. NTSTATUS
  1699. status;
  1700. WORD16
  1701. rlen;
  1702. BYTE
  1703. rbuff[HOR3GLL_BUFFER_SIZE];
  1704. KEVENT
  1705. event;
  1706. LARGE_INTEGER
  1707. timeout;
  1708. /*---------------------------------------------------------------------------------
  1709. Get the ICC type
  1710. ---------------------------------------------------------------------------------*/
  1711. icc_type = param->ICCType;
  1712. /*------------------------------------------------------------------------------
  1713. <= ICC type is defined.
  1714. The function status and the IFD status are tested.
  1715. ------------------------------------------------------------------------------*/
  1716. rlen = HOR3GLL_BUFFER_SIZE;
  1717. response = G_Oros3IccDefineType(
  1718. param->Handle,
  1719. HOR3GLL_LOW_TIME,
  1720. icc_type,
  1721. param->ICCVpp,
  1722. param->ICCPresence,
  1723. &rlen,
  1724. rbuff
  1725. );
  1726. if (response >= G_OK)
  1727. {
  1728. response = GE_Translate(rbuff[0]);
  1729. }
  1730. if (response < G_OK)
  1731. {
  1732. return (GDDK_Translate(response,RDF_CARD_POWER));
  1733. }
  1734. /*------------------------------------------------------------------------------
  1735. ICC is powered Down (G_Oros3IccPowerDown).
  1736. <= The function status and the IFD status are tested.
  1737. ------------------------------------------------------------------------------*/
  1738. rlen = HOR3GLL_BUFFER_SIZE;
  1739. response = G_Oros3IccPowerDown(
  1740. param->Handle,
  1741. HOR3GLL_LOW_TIME,
  1742. &rlen,
  1743. rbuff
  1744. );
  1745. if (response >= G_OK)
  1746. {
  1747. response = GE_Translate(rbuff[0]);
  1748. }
  1749. if (response < G_OK)
  1750. {
  1751. return (GDDK_Translate(response,RDF_CARD_POWER));
  1752. }
  1753. /*------------------------------------------------------------------------------
  1754. Waits for the Power Timeout to be elapsed.
  1755. ------------------------------------------------------------------------------*/
  1756. KeInitializeEvent(&event,NotificationEvent,FALSE);
  1757. timeout.QuadPart = -((LONGLONG) param->PowerTimeOut * 10 * 1000);
  1758. status = KeWaitForSingleObject(&event,
  1759. Suspended,
  1760. KernelMode,
  1761. FALSE,
  1762. &timeout);
  1763. /*------------------------------------------------------------------------------
  1764. ICC is powered up (G_Oros3IccPowerUp).
  1765. <= The function status and the IFD status are tested.
  1766. ------------------------------------------------------------------------------*/
  1767. rlen = HOR3GLL_BUFFER_SIZE;
  1768. response = G_Oros3IccPowerUp(
  1769. param->Handle,
  1770. param->CmdTimeOut,
  1771. param->ICCVcc,
  1772. param->PTSMode,
  1773. param->PTS0,
  1774. param->PTS1,
  1775. param->PTS2,
  1776. param->PTS3,
  1777. &rlen,
  1778. rbuff
  1779. );
  1780. if (response >= G_OK)
  1781. {
  1782. response = GE_Translate(rbuff[0]);
  1783. }
  1784. if (response < G_OK)
  1785. {
  1786. return (GDDK_Translate(response,RDF_CARD_POWER));
  1787. }
  1788. /*------------------------------------------------------------------------------
  1789. Copy ATR to smart card struct (remove the reader status byte)
  1790. The lib needs the ATR for evaluation of the card parameters
  1791. ------------------------------------------------------------------------------*/
  1792. ASSERT(SmartcardExtension->SmartcardReply.BufferSize >= (ULONG) (rlen - 1));
  1793. memcpy(
  1794. SmartcardExtension->SmartcardReply.Buffer,
  1795. rbuff + 1,
  1796. rlen - 1
  1797. );
  1798. SmartcardExtension->SmartcardReply.BufferLength = (ULONG) (rlen - 1);
  1799. ASSERT(sizeof(SmartcardExtension->CardCapabilities.ATR.Buffer) >=
  1800. (UCHAR) SmartcardExtension->SmartcardReply.BufferLength);
  1801. memcpy(
  1802. SmartcardExtension->CardCapabilities.ATR.Buffer,
  1803. SmartcardExtension->SmartcardReply.Buffer,
  1804. SmartcardExtension->SmartcardReply.BufferLength
  1805. );
  1806. SmartcardExtension->CardCapabilities.ATR.Length =
  1807. (UCHAR) SmartcardExtension->SmartcardReply.BufferLength;
  1808. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1809. SCARD_PROTOCOL_UNDEFINED;
  1810. /*------------------------------------------------------------------------------
  1811. Parse the ATR string in order to check if it as valid
  1812. and to find out if the card uses invers convention
  1813. ------------------------------------------------------------------------------*/
  1814. status = SmartcardUpdateCardCapabilities(SmartcardExtension);
  1815. if (status == STATUS_SUCCESS)
  1816. {
  1817. ASSERT(SmartcardExtension->IoRequest.ReplyBufferLength >=
  1818. SmartcardExtension->SmartcardReply.BufferLength
  1819. );
  1820. memcpy(
  1821. SmartcardExtension->IoRequest.ReplyBuffer,
  1822. SmartcardExtension->CardCapabilities.ATR.Buffer,
  1823. SmartcardExtension->CardCapabilities.ATR.Length
  1824. );
  1825. *SmartcardExtension->IoRequest.Information =
  1826. SmartcardExtension->SmartcardReply.BufferLength;
  1827. }
  1828. /*------------------------------------------------------------------------------
  1829. <= Return the last received status.
  1830. ------------------------------------------------------------------------------*/
  1831. return (status);
  1832. }
  1833. /*******************************************************************************
  1834. * NTSTATUS GDDK_09SwitchSession
  1835. * (
  1836. * PSMARTCARD_EXTENSION SmartcardExtension
  1837. * )
  1838. * Description :
  1839. * -------------
  1840. * Description :
  1841. * -------------
  1842. * Opens a warm session with the selected ICC type.
  1843. * Only a reset is sent to ICC.
  1844. * For the ISO card, during the power up this function negotiates with the
  1845. * ICC speed and protocole in accordance with PTS mode and sets the ICC power
  1846. * supply voltage.
  1847. * The session structure is updated with values found in ATR.
  1848. *
  1849. * Remarks :
  1850. * -------------
  1851. * This command is possible only if a G4_09OpenSession has been called before and
  1852. * if the ICC type is not changed.
  1853. * For the ISO card today, we assumes that only T=0, T=1 or T=0/1 are supported.
  1854. * So we memorised the first founded protocol which must be T=0 for bi-protocol
  1855. * card according to ISO standard.
  1856. *
  1857. * In :
  1858. * -------------
  1859. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  1860. * the current device.
  1861. *
  1862. * Out :
  1863. * -------------
  1864. * - SmartcardExtension is updated.
  1865. *
  1866. * Responses :
  1867. * -------------
  1868. * If everything is Ok:
  1869. * STATUS_SUCCESS
  1870. *******************************************************************************/
  1871. NTSTATUS GDDK_09SwitchSession
  1872. (
  1873. PSMARTCARD_EXTENSION SmartcardExtension
  1874. )
  1875. {
  1876. /*------------------------------------------------------------------------------
  1877. Local variables:
  1878. - response holds the called function responses.
  1879. - ifd_type is used for ICC/SM management.
  1880. - icc_type holds the ICC type translated in OROS value.
  1881. ------------------------------------------------------------------------------*/
  1882. INT16
  1883. response,
  1884. ifd_type,
  1885. icc_supported;
  1886. WORD16
  1887. icc_type;
  1888. BOOL
  1889. protocol_set = FALSE;
  1890. WORD32
  1891. end_time;
  1892. READER_EXTENSION
  1893. *param = SmartcardExtension->ReaderExtension;
  1894. NTSTATUS
  1895. status;
  1896. WORD16
  1897. rlen;
  1898. BYTE
  1899. rbuff[HOR3GLL_BUFFER_SIZE];
  1900. /*---------------------------------------------------------------------------------
  1901. Get the ICC type
  1902. ---------------------------------------------------------------------------------*/
  1903. icc_type = param->ICCType;
  1904. /*------------------------------------------------------------------------------
  1905. <= ICC is powered up.
  1906. The function status and the IFD status are tested.
  1907. ------------------------------------------------------------------------------*/
  1908. rlen = HOR3GLL_BUFFER_SIZE;
  1909. response = G_Oros3IccPowerUp(
  1910. param->Handle,
  1911. param->CmdTimeOut,
  1912. param->ICCVcc,
  1913. param->PTSMode,
  1914. param->PTS0,
  1915. param->PTS1,
  1916. param->PTS2,
  1917. param->PTS3,
  1918. &rlen,
  1919. rbuff
  1920. );
  1921. if (response >= G_OK)
  1922. {
  1923. response = GE_Translate(rbuff[0]);
  1924. }
  1925. if (response < G_OK)
  1926. {
  1927. return (GDDK_Translate(response,RDF_CARD_POWER));
  1928. }
  1929. /*------------------------------------------------------------------------------
  1930. Copy ATR to smart card struct (remove the reader status byte)
  1931. The lib needs the ATR for evaluation of the card parameters
  1932. ------------------------------------------------------------------------------*/
  1933. ASSERT(SmartcardExtension->SmartcardReply.BufferSize >= (ULONG) (rlen - 1));
  1934. memcpy(
  1935. SmartcardExtension->SmartcardReply.Buffer,
  1936. rbuff + 1,
  1937. rlen - 1
  1938. );
  1939. SmartcardExtension->SmartcardReply.BufferLength = (ULONG) (rlen - 1);
  1940. ASSERT(sizeof(SmartcardExtension->CardCapabilities.ATR.Buffer) >=
  1941. (UCHAR) SmartcardExtension->SmartcardReply.BufferLength);
  1942. memcpy(
  1943. SmartcardExtension->CardCapabilities.ATR.Buffer,
  1944. SmartcardExtension->SmartcardReply.Buffer,
  1945. SmartcardExtension->SmartcardReply.BufferLength
  1946. );
  1947. SmartcardExtension->CardCapabilities.ATR.Length =
  1948. (UCHAR) SmartcardExtension->SmartcardReply.BufferLength;
  1949. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1950. SCARD_PROTOCOL_UNDEFINED;
  1951. /*------------------------------------------------------------------------------
  1952. Parse the ATR string in order to check if it as valid
  1953. and to find out if the card uses invers convention
  1954. ------------------------------------------------------------------------------*/
  1955. status = SmartcardUpdateCardCapabilities(SmartcardExtension);
  1956. if (status == STATUS_SUCCESS)
  1957. {
  1958. ASSERT(SmartcardExtension->IoRequest.ReplyBufferLength >=
  1959. SmartcardExtension->SmartcardReply.BufferLength
  1960. );
  1961. memcpy(
  1962. SmartcardExtension->IoRequest.ReplyBuffer,
  1963. SmartcardExtension->CardCapabilities.ATR.Buffer,
  1964. SmartcardExtension->CardCapabilities.ATR.Length
  1965. );
  1966. *SmartcardExtension->IoRequest.Information =
  1967. SmartcardExtension->SmartcardReply.BufferLength;
  1968. }
  1969. /*------------------------------------------------------------------------------
  1970. <= Return the last received status.
  1971. ------------------------------------------------------------------------------*/
  1972. return (status);
  1973. }
  1974. /*******************************************************************************
  1975. * NTSTATUS GDDK_09CloseSession
  1976. * (
  1977. * PSMARTCARD_EXTENSION SmartcardExtension
  1978. * )
  1979. *
  1980. * Description :
  1981. * -------------
  1982. * Closes a session and requests IFD to remove the power from ICC.
  1983. *
  1984. * Remarks :
  1985. * -------------
  1986. * Nothing.
  1987. *
  1988. * In :
  1989. * -------------
  1990. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  1991. * the current device.
  1992. *
  1993. * Out :
  1994. * -------------
  1995. * Nothing.
  1996. *
  1997. * Responses :
  1998. * -------------
  1999. * If everything is Ok:
  2000. * STATUS_SUCCESS
  2001. *******************************************************************************/
  2002. NTSTATUS GDDK_09CloseSession
  2003. (
  2004. PSMARTCARD_EXTENSION SmartcardExtension
  2005. )
  2006. {
  2007. /*------------------------------------------------------------------------------
  2008. Local variables:
  2009. - response holds the called function responses.
  2010. ------------------------------------------------------------------------------*/
  2011. INT16
  2012. response;
  2013. READER_EXTENSION
  2014. *param = SmartcardExtension->ReaderExtension;
  2015. WORD16
  2016. rlen;
  2017. BYTE
  2018. rbuff[HOR3GLL_BUFFER_SIZE];
  2019. /*------------------------------------------------------------------------------
  2020. If the dispatcher is used to send command and the command is found
  2021. in the ORO file.
  2022. Then
  2023. Send the command Icc Power Down with the micro-code via the dispatcher.
  2024. Else
  2025. ICC is powered Down (G_Oros3IccPowerDown).
  2026. <= The function status and the IFD status are tested.
  2027. ------------------------------------------------------------------------------*/
  2028. rlen = HOR3GLL_BUFFER_SIZE;
  2029. response = G_Oros3IccPowerDown(
  2030. param->Handle,
  2031. HOR3GLL_LOW_TIME,
  2032. &rlen,
  2033. rbuff
  2034. );
  2035. if (response >= G_OK)
  2036. {
  2037. response = GE_Translate(rbuff[0]);
  2038. }
  2039. /*------------------------------------------------------------------------------
  2040. Updates card status for ICC or reset Protocol and ATR for Security Module.
  2041. ------------------------------------------------------------------------------*/
  2042. if (param->IFDNumber > 0)
  2043. {
  2044. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  2045. SmartcardExtension->CardCapabilities.Protocol.Selected =
  2046. SCARD_PROTOCOL_UNDEFINED;
  2047. }
  2048. else
  2049. {
  2050. GDDK_09UpdateCardStatus(SmartcardExtension);
  2051. }
  2052. /*------------------------------------------------------------------------------
  2053. <= Returns the last status.
  2054. ------------------------------------------------------------------------------*/
  2055. return(GDDK_Translate(response,RDF_CARD_POWER));
  2056. }
  2057. /*******************************************************************************
  2058. * void GDDK_09UpdateCardStatus
  2059. * (
  2060. * PSMARTCARD_EXTENSION pSmartcardExtension
  2061. * )
  2062. *
  2063. * Description :
  2064. * -------------
  2065. * This function send a command to the reader to known the state of the card.
  2066. * Available only for the main reader.
  2067. *
  2068. * Remarks :
  2069. * -------------
  2070. * Nothing.
  2071. *
  2072. * In :
  2073. * -------------
  2074. * - pSmartcardExtension is a pointer on the SmartCardExtension structure of
  2075. * the current device.
  2076. *
  2077. * Out :
  2078. * -------------
  2079. * - pSmartcardExtension is updated.
  2080. *
  2081. * Responses :
  2082. * -------------
  2083. * NTSTATUS
  2084. *******************************************************************************/
  2085. void GDDK_09UpdateCardStatus
  2086. (
  2087. PSMARTCARD_EXTENSION pSmartcardExtension
  2088. )
  2089. {
  2090. INT16
  2091. response;
  2092. WORD8
  2093. cmd[1];
  2094. READER_EXTENSION
  2095. *param = pSmartcardExtension->ReaderExtension;
  2096. WORD16
  2097. rlen;
  2098. BYTE
  2099. rbuff[HOR3GLL_BUFFER_SIZE];
  2100. /*------------------------------------------------------------------------------
  2101. On an OROS 3.x reader we can know the status only on the main IFD
  2102. ------------------------------------------------------------------------------*/
  2103. if (param->IFDNumber == 0)
  2104. {
  2105. /*------------------------------------------------------------------------------
  2106. Read the status of the reader
  2107. ------------------------------------------------------------------------------*/
  2108. cmd[0] = HOR3GLL_IFD_CMD_ICC_STATUS;
  2109. rlen = HOR3GLL_BUFFER_SIZE;
  2110. response = G_Oros3Exchange(
  2111. param->Handle,
  2112. HOR3GLL_LOW_TIME,
  2113. (const WORD16)1,
  2114. (const BYTE *)cmd,
  2115. &rlen,
  2116. rbuff
  2117. );
  2118. /*------------------------------------------------------------------------------
  2119. Verify the response of the reader
  2120. ------------------------------------------------------------------------------*/
  2121. if (response >= G_OK)
  2122. {
  2123. response = GE_Translate(rbuff[0]);
  2124. }
  2125. if (response < G_OK)
  2126. {
  2127. return;
  2128. }
  2129. if ((rbuff[1] & 0x04) == 0)
  2130. {
  2131. /*------------------------------------------------------------------------------
  2132. The card is absent
  2133. ------------------------------------------------------------------------------*/
  2134. pSmartcardExtension->ReaderCapabilities.CurrentState =
  2135. SCARD_ABSENT;
  2136. pSmartcardExtension->CardCapabilities.Protocol.Selected =
  2137. SCARD_PROTOCOL_UNDEFINED;
  2138. pSmartcardExtension->CardCapabilities.ATR.Length = 0;
  2139. }
  2140. else if ((rbuff[1] & 0x02) == 0)
  2141. {
  2142. /*------------------------------------------------------------------------------
  2143. The card is present
  2144. ------------------------------------------------------------------------------*/
  2145. pSmartcardExtension->ReaderCapabilities.CurrentState =
  2146. SCARD_SWALLOWED;
  2147. pSmartcardExtension->CardCapabilities.Protocol.Selected =
  2148. SCARD_PROTOCOL_UNDEFINED;
  2149. pSmartcardExtension->CardCapabilities.ATR.Length = 0;
  2150. }
  2151. }
  2152. }
  2153. /*******************************************************************************
  2154. * static NTSTATUS GDDK_09IFDExchange
  2155. * (
  2156. * PSMARTCARD_EXTENSION SmartcardExtension,
  2157. * ULONG BufferInLen,
  2158. * BYTE *BufferIn,
  2159. * ULONG BufferOutLen,
  2160. * BYTE *BufferOut,
  2161. * ULONG *LengthOut
  2162. *)
  2163. *
  2164. * Description :
  2165. * -------------
  2166. * This is the system entry point to send a command to the IFD.
  2167. * The device-specific handler is invoked to perform any validation
  2168. * necessary. The number of bytes in the request are checked against
  2169. * the maximum byte counts that the reader supports.
  2170. *
  2171. * Remarks :
  2172. * -------------
  2173. * Nothing.
  2174. *
  2175. * In :
  2176. * -------------
  2177. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  2178. * the current device.
  2179. *
  2180. * Out :
  2181. * -------------
  2182. * Nothing.
  2183. *
  2184. * Responses :
  2185. * -------------
  2186. * NTSTATUS
  2187. *******************************************************************************/
  2188. static NTSTATUS GDDK_09IFDExchange
  2189. (
  2190. PSMARTCARD_EXTENSION SmartcardExtension,
  2191. ULONG BufferInLen,
  2192. BYTE *BufferIn,
  2193. ULONG BufferOutLen,
  2194. BYTE *BufferOut,
  2195. ULONG *LengthOut
  2196. )
  2197. {
  2198. INT16
  2199. response;
  2200. NTSTATUS
  2201. status;
  2202. READER_EXTENSION
  2203. *param = SmartcardExtension->ReaderExtension;
  2204. WORD16
  2205. rlen;
  2206. BYTE
  2207. rbuff[HOR3GLL_BUFFER_SIZE];
  2208. *LengthOut = 0;
  2209. /*------------------------------------------------------------------------------
  2210. Send the command to the reader
  2211. ------------------------------------------------------------------------------*/
  2212. rlen = (USHORT) BufferOutLen;
  2213. response = G_Oros3Exchange(
  2214. param->Handle,
  2215. HOR3GLL_LOW_TIME,
  2216. (USHORT)BufferInLen,
  2217. (BYTE *)BufferIn,
  2218. &rlen,
  2219. rbuff
  2220. );
  2221. /*------------------------------------------------------------------------------
  2222. If the response <> G_OK
  2223. <== G_DDKTranslate(response)
  2224. ------------------------------------------------------------------------------*/
  2225. if (response != G_OK)
  2226. {
  2227. return(GDDK_Translate(response,RDF_IOCTL_VENDOR));
  2228. }
  2229. /*------------------------------------------------------------------------------
  2230. Copy the response of the reader in the reply buffer
  2231. ------------------------------------------------------------------------------*/
  2232. ASSERT(*LengthOut >= (ULONG)rlen);
  2233. memcpy(BufferOut,rbuff,rlen);
  2234. *(LengthOut) = (ULONG)rlen;
  2235. return(GDDK_Translate(response,RDF_IOCTL_VENDOR));
  2236. }
  2237. /*******************************************************************************
  2238. * void GDDK_09LockExchange
  2239. * (
  2240. * PSMARTCARD_EXTENSION SmartcardExtension
  2241. *)
  2242. *
  2243. * Description :
  2244. * -------------
  2245. * Wait the release of the ExchangeMutex and take this.
  2246. *
  2247. * Remarks :
  2248. * -------------
  2249. * Nothing.
  2250. *
  2251. * In :
  2252. * -------------
  2253. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  2254. * the current device.
  2255. *
  2256. * Out :
  2257. * -------------
  2258. * Nothing.
  2259. *
  2260. * Responses :
  2261. * -------------
  2262. * Nothing
  2263. *******************************************************************************/
  2264. void GDDK_09LockExchange
  2265. (
  2266. PSMARTCARD_EXTENSION SmartcardExtension
  2267. )
  2268. {
  2269. KeWaitForMutexObject(
  2270. &SmartcardExtension->ReaderExtension->LongAPDUMutex,
  2271. Executive,
  2272. KernelMode,
  2273. FALSE,
  2274. NULL
  2275. );
  2276. }
  2277. /*******************************************************************************
  2278. * void GDDK_09UnlockExchange
  2279. * (
  2280. * PSMARTCARD_EXTENSION SmartcardExtension
  2281. *)
  2282. *
  2283. * Description :
  2284. * -------------
  2285. * Release of the Exchange mutex.
  2286. *
  2287. * Remarks :
  2288. * -------------
  2289. * Nothing.
  2290. *
  2291. * In :
  2292. * -------------
  2293. * - SmartcardExtension is a pointer on the SmartCardExtension structure of
  2294. * the current device.
  2295. *
  2296. * Out :
  2297. * -------------
  2298. * Nothing.
  2299. *
  2300. * Responses :
  2301. * -------------
  2302. * Nothing
  2303. *******************************************************************************/
  2304. void GDDK_09UnlockExchange
  2305. (
  2306. PSMARTCARD_EXTENSION SmartcardExtension
  2307. )
  2308. {
  2309. KeReleaseMutex(
  2310. &SmartcardExtension->ReaderExtension->LongAPDUMutex,
  2311. FALSE
  2312. );
  2313. }