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.

2163 lines
65 KiB

  1. /*++
  2. Copyright (c) 1998 Gemplus Development
  3. Name:
  4. GIOCTL0A.C (Gemplus IOCTL Smart card Reader module 0A)
  5. Description:
  6. This module holds the IOCTL functions for a smart card reader driver
  7. in compliance with PC/SC.
  8. Environment:
  9. Kernel mode
  10. Revision History :
  11. dd/mm/yy
  12. 13/03/98: V1.00.001 (GPZ)
  13. - Start of development.
  14. 26/04/98: V1.00.002 (GPZ)
  15. - Add the RestoreCommunication function for the Power Management.
  16. 18/06/98: V1.00.003 (GPZ)
  17. - Send a classic PowerUp command (0x12 only) for a Warm reset
  18. in case of the Transparent protocol is selected.
  19. - The functions which use KeAcquireSpinLock/KeAcquireCancelSpinlock
  20. must be NOT PAGEABLE.
  21. 28/08/98: V1.00.004 (GPZ)
  22. - Check the size of the output buffers before a RtlCopyMemory.
  23. 22/01/99: V1.00.005 (YN)
  24. - Change the way to increase com port speed
  25. --*/
  26. #include "gntscr.h"
  27. #include "gntser.h"
  28. #include "gntscr0a.h"
  29. //#pragma alloc_text(PAGEABLE, GDDK_0ASetProtocol)
  30. //#pragma alloc_text(PAGEABLE, GDDK_0ATransmit)
  31. //#pragma alloc_text(PAGEABLE, GDDK_0AVendorIoctl)
  32. //
  33. // Static functions declaration section:
  34. //
  35. static void GDDK_0ASetTransparentConfig(PSMARTCARD_EXTENSION,BYTE);
  36. //
  37. // Static variables declaration section:
  38. // - dataRatesSupported: holds all the supported data rates.
  39. //
  40. static ULONG
  41. dataRatesSupported[] = {
  42. 9909, 13212, 14400, 15855,
  43. 19200, 19819, 26425, 28800,
  44. 31710, 38400, 39638, 52851,
  45. 57600, 76800, 79277, 105703,
  46. 115200, 158554
  47. };
  48. NTSTATUS
  49. GDDK_0AReaderPower(
  50. PSMARTCARD_EXTENSION SmartcardExtension
  51. )
  52. /*++
  53. Routine Description:
  54. This function is called by the Smart card library when a
  55. IOCTL_SMARTCARD_POWER occurs.
  56. This function provides 3 differents functionnality, depending of the minor
  57. IOCTL value
  58. - Cold reset (SCARD_COLD_RESET),
  59. - Warm reset (SCARD_WARM_RESET),
  60. - Power down (SCARD_POWER_DOWN).
  61. Arguments:
  62. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  63. the current device.
  64. Return Value:
  65. STATUS_SUCCESS - We could execute the request.
  66. STATUS_NOT_SUPPORTED - We could not support the minor Ioctl.
  67. --*/
  68. {
  69. NTSTATUS status;
  70. BYTE cmd[5],rbuff[HOR3GLL_BUFFER_SIZE];
  71. USHORT rlen;
  72. KIRQL irql;
  73. READER_EXTENSION
  74. *param = SmartcardExtension->ReaderExtension;
  75. SmartcardDebug(
  76. DEBUG_IOCTL,
  77. ("%s!GDDK_0AReaderPower: Enter\n",
  78. SC_DRIVER_NAME)
  79. );
  80. //
  81. // Since power down triggers the UpdateSerialStatus function, we have
  82. // to inform it that we forced the change of the status and not the user
  83. // (who might have removed and inserted a card)
  84. //
  85. SmartcardExtension->ReaderExtension->PowerRequest = TRUE;
  86. // Lock the mutex to avoid a call of an other command.
  87. GDDK_0ALockExchange(SmartcardExtension);
  88. switch(SmartcardExtension->MinorIoControlCode) {
  89. case SCARD_POWER_DOWN:
  90. SmartcardDebug(
  91. DEBUG_IOCTL,
  92. ("%s!GDDK_0AReaderPower: SCARD_POWER_DOWN\n",
  93. SC_DRIVER_NAME)
  94. );
  95. //
  96. // ICC is powered Down
  97. //
  98. rlen = HOR3GLL_BUFFER_SIZE;
  99. cmd[0] = HOR3GLL_IFD_CMD_ICC_POWER_DOWN;
  100. status = GDDK_Oros3Exchange(
  101. param->Handle,
  102. HOR3GLL_LOW_TIME,
  103. 1,
  104. cmd,
  105. &rlen,
  106. rbuff
  107. );
  108. if (status == STATUS_SUCCESS) {
  109. status = GDDK_Translate(rbuff[0],RDF_CARD_POWER);
  110. }
  111. //
  112. // Set the card CurrentState
  113. //
  114. SmartcardExtension->CardCapabilities.Protocol.Selected =
  115. SCARD_PROTOCOL_UNDEFINED;
  116. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  117. rlen = HOR3GLL_BUFFER_SIZE;
  118. cmd[0] = HOR3GLL_IFD_CMD_ICC_STATUS;
  119. status = GDDK_Oros3Exchange(
  120. param->Handle,
  121. HOR3GLL_LOW_TIME,
  122. 1,
  123. cmd,
  124. &rlen,
  125. rbuff
  126. );
  127. if (status == STATUS_SUCCESS) {
  128. status = GDDK_Translate(rbuff[0],0);
  129. }
  130. if (status == STATUS_SUCCESS) {
  131. KeAcquireSpinLock(
  132. &SmartcardExtension->OsData->SpinLock,
  133. &irql
  134. );
  135. if ((rbuff[1] & 0x04) == 0) {
  136. SmartcardExtension->ReaderCapabilities.CurrentState =
  137. SCARD_ABSENT;
  138. } else if ((rbuff[1] & 0x02) == 0) {
  139. SmartcardExtension->ReaderCapabilities.CurrentState =
  140. SCARD_SWALLOWED;
  141. }
  142. KeReleaseSpinLock(
  143. &SmartcardExtension->OsData->SpinLock,
  144. irql
  145. );
  146. }
  147. break;
  148. case SCARD_COLD_RESET:
  149. case SCARD_WARM_RESET:
  150. SmartcardDebug(
  151. DEBUG_IOCTL,
  152. ("%s!GDDK_0AReaderPower: SCARD_COLD_RESET or SCARD_WARM_RESET\n",
  153. SC_DRIVER_NAME)
  154. );
  155. status = GDDK_0AIccReset(
  156. SmartcardExtension,
  157. SmartcardExtension->MinorIoControlCode
  158. );
  159. if (status == STATUS_SUCCESS) {
  160. //
  161. // Check if we have a reply buffer.
  162. // smclib makes sure that it is big enough
  163. // if there is a buffer
  164. //
  165. if (SmartcardExtension->IoRequest.ReplyBuffer) {
  166. RtlCopyMemory(
  167. SmartcardExtension->IoRequest.ReplyBuffer,
  168. SmartcardExtension->CardCapabilities.ATR.Buffer,
  169. SmartcardExtension->CardCapabilities.ATR.Length
  170. );
  171. *SmartcardExtension->IoRequest.Information =
  172. SmartcardExtension->CardCapabilities.ATR.Length;
  173. } else {
  174. status = STATUS_BUFFER_TOO_SMALL;
  175. }
  176. }
  177. break;
  178. default:
  179. SmartcardDebug(
  180. DEBUG_ERROR,
  181. ("%s!GDDK_0AReaderPower: Minor IOCTL not supported!\n",
  182. SC_DRIVER_NAME)
  183. );
  184. status = STATUS_NOT_SUPPORTED;
  185. }
  186. SmartcardExtension->ReaderExtension->PowerRequest = FALSE;
  187. SmartcardDebug(
  188. DEBUG_IOCTL,
  189. ("%s!GDDK_0AReaderPower: Exit=%X(hex)\n",
  190. SC_DRIVER_NAME,
  191. status)
  192. );
  193. // Unlock the mutex.
  194. GDDK_0AUnlockExchange(SmartcardExtension);
  195. return (status);
  196. }
  197. NTSTATUS
  198. GDDK_0AIccReset(
  199. PSMARTCARD_EXTENSION SmartcardExtension,
  200. ULONG ResetType
  201. )
  202. /*++
  203. Routine Description:
  204. This function provides 2 differents functionnality
  205. - Cold reset (SCARD_COLD_RESET),
  206. - Warm reset (SCARD_WARM_RESET),
  207. Arguments:
  208. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  209. the current device.
  210. ResetType - type of the reset (SCARD_COLD_RESET or SCARD_WARM_RESET)
  211. Return Value:
  212. STATUS_SUCCESS - We could execute the request.
  213. STATUS_NOT_SUPPORTED - We could not support the minor Ioctl.
  214. --*/
  215. {
  216. NTSTATUS status;
  217. BYTE cmd[5],
  218. rbuff[HOR3GLL_BUFFER_SIZE];
  219. USHORT rlen;
  220. KEVENT event;
  221. LARGE_INTEGER timeout;
  222. READER_EXTENSION *param = SmartcardExtension->ReaderExtension;
  223. SmartcardExtension->ReaderExtension->IccConfig.PTSMode = IFD_WITHOUT_PTS_REQUEST;
  224. switch(ResetType) {
  225. case SCARD_COLD_RESET:
  226. if (param->IccConfig.ICCType != ISOCARD) {
  227. //
  228. // Defines the type of the card (ISOCARD) and set the card presence
  229. //
  230. param->IccConfig.ICCType = ISOCARD;
  231. rlen = HOR3GLL_BUFFER_SIZE;
  232. cmd[0] = HOR3GLL_IFD_CMD_ICC_DEFINE_TYPE;
  233. cmd[1] = (BYTE) param->IccConfig.ICCType;
  234. cmd[2] = (BYTE) param->IccConfig.ICCVpp;
  235. cmd[3] = (BYTE) param->IccConfig.ICCPresence;
  236. status = GDDK_Oros3Exchange(
  237. param->Handle,
  238. HOR3GLL_LOW_TIME,
  239. 4,
  240. cmd,
  241. &rlen,
  242. rbuff
  243. );
  244. if (status == STATUS_SUCCESS) {
  245. status = GDDK_Translate(rbuff[0],RDF_CARD_POWER);
  246. }
  247. if (status != STATUS_SUCCESS) {
  248. return(status);
  249. }
  250. }
  251. //
  252. // ICC is powered Down
  253. //
  254. rlen = HOR3GLL_BUFFER_SIZE;
  255. cmd[0] = HOR3GLL_IFD_CMD_ICC_POWER_DOWN;
  256. status = GDDK_Oros3Exchange(
  257. param->Handle,
  258. HOR3GLL_LOW_TIME,
  259. 1,
  260. cmd,
  261. &rlen,
  262. rbuff
  263. );
  264. if (status == STATUS_SUCCESS) {
  265. status = GDDK_Translate(rbuff[0],RDF_CARD_POWER);
  266. }
  267. if (status != STATUS_SUCCESS) {
  268. return(status);
  269. }
  270. if (param->PowerTimeOut) {
  271. //
  272. // Waits for the Power Timeout to be elapsed.
  273. //
  274. KeInitializeEvent(&event,NotificationEvent,FALSE);
  275. timeout.QuadPart = -((LONGLONG) param->PowerTimeOut * 10 * 1000);
  276. KeWaitForSingleObject(&event,
  277. Suspended,
  278. KernelMode,
  279. FALSE,
  280. &timeout);
  281. }
  282. case SCARD_WARM_RESET:
  283. //
  284. // ICC is powered up (GDDK_Oros3IccPowerUp).
  285. //
  286. rlen = HOR3GLL_BUFFER_SIZE;
  287. if (param->IccConfig.ICCType == TRANSPARENT_PROTOCOL) {
  288. status = GDDK_Oros3IccPowerUp(
  289. param->Handle,
  290. param->CmdTimeOut,
  291. 0xFF,
  292. IFD_DEFAULT_MODE,
  293. 0,
  294. 0,
  295. 0,
  296. 0,
  297. &rlen,
  298. rbuff
  299. );
  300. } else {
  301. status = GDDK_Oros3IccPowerUp(
  302. param->Handle,
  303. param->CmdTimeOut,
  304. param->IccConfig.ICCVcc,
  305. param->IccConfig.PTSMode,
  306. param->IccConfig.PTS0,
  307. param->IccConfig.PTS1,
  308. param->IccConfig.PTS2,
  309. param->IccConfig.PTS3,
  310. &rlen,
  311. rbuff
  312. );
  313. }
  314. if (status == STATUS_SUCCESS) {
  315. status = GDDK_Translate(rbuff[0],RDF_CARD_POWER);
  316. }
  317. if (status != STATUS_SUCCESS) {
  318. return(status);
  319. }
  320. //
  321. // Copy ATR to smart card struct (remove the reader status byte)
  322. // The lib needs the ATR for evaluation of the card parameters
  323. //
  324. if (
  325. (SmartcardExtension->SmartcardReply.BufferSize >= (ULONG) (rlen - 1))
  326. &&
  327. (sizeof(SmartcardExtension->CardCapabilities.ATR.Buffer) >= (ULONG)(rlen - 1))
  328. ) {
  329. RtlCopyMemory(
  330. SmartcardExtension->SmartcardReply.Buffer,
  331. rbuff + 1,
  332. rlen - 1
  333. );
  334. SmartcardExtension->SmartcardReply.BufferLength = (ULONG) (rlen - 1);
  335. RtlCopyMemory(
  336. SmartcardExtension->CardCapabilities.ATR.Buffer,
  337. SmartcardExtension->SmartcardReply.Buffer,
  338. SmartcardExtension->SmartcardReply.BufferLength
  339. );
  340. SmartcardExtension->CardCapabilities.ATR.Length =
  341. (UCHAR) SmartcardExtension->SmartcardReply.BufferLength;
  342. SmartcardExtension->CardCapabilities.Protocol.Selected =
  343. SCARD_PROTOCOL_UNDEFINED;
  344. //
  345. // Parse the ATR string in order to check if it as valid
  346. // and to find out if the card uses invers convention
  347. //
  348. status = SmartcardUpdateCardCapabilities(SmartcardExtension);
  349. } else {
  350. status = STATUS_BUFFER_TOO_SMALL;
  351. }
  352. break;
  353. default:
  354. status = STATUS_NOT_SUPPORTED;
  355. }
  356. return (status);
  357. }
  358. NTSTATUS
  359. GDDK_0ASetProtocol(
  360. PSMARTCARD_EXTENSION SmartcardExtension
  361. )
  362. /*++
  363. Routine Description:
  364. The smart card lib requires to have this function. It is called
  365. to set a the transmission protocol and parameters. If this function
  366. is called with a protocol mask (which means the caller doesn't card
  367. about a particular protocol to be set) we first look if we can
  368. set T=1 and the T=0
  369. Arguments:
  370. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  371. the current device.
  372. Return Value:
  373. STATUS_SUCCESS - We could execute the request.
  374. STATUS_DEVICE_PROTOCOL_ERROR - We could not support the protocol requested.
  375. --*/
  376. {
  377. NTSTATUS status;
  378. BYTE rbuff[HOR3GLL_BUFFER_SIZE];
  379. USHORT rlen;
  380. READER_EXTENSION *param = SmartcardExtension->ReaderExtension;
  381. PSERIAL_READER_CONFIG serialConfigData =
  382. &SmartcardExtension->ReaderExtension->SerialConfigData;
  383. PAGED_CODE();
  384. SmartcardDebug(
  385. DEBUG_TRACE,
  386. ("%s!GDDK_0ASetProtocol: Enter\n",
  387. SC_DRIVER_NAME)
  388. );
  389. // Lock the mutex to avoid a call of an other command.
  390. GDDK_0ALockExchange(SmartcardExtension);
  391. __try {
  392. //
  393. // Check if the card is already in specific state
  394. // and if the caller wants to have the already selected protocol.
  395. // We return success if this is the case.
  396. //
  397. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC &&
  398. (SmartcardExtension->CardCapabilities.Protocol.Selected &
  399. SmartcardExtension->MinorIoControlCode)
  400. ) {
  401. status = STATUS_SUCCESS;
  402. __leave;
  403. }
  404. while(TRUE) {
  405. //
  406. // Select T=1 or T=0 and indicate that pts1 follows
  407. //
  408. if ( SmartcardExtension->CardCapabilities.Protocol.Supported &
  409. SmartcardExtension->MinorIoControlCode &
  410. SCARD_PROTOCOL_T1
  411. ) {
  412. SmartcardExtension->ReaderExtension->IccConfig.PTS0 = IFD_NEGOTIATE_T1 | IFD_NEGOTIATE_PTS1;
  413. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;
  414. } else if ( SmartcardExtension->CardCapabilities.Protocol.Supported &
  415. SmartcardExtension->MinorIoControlCode &
  416. SCARD_PROTOCOL_T0
  417. ) {
  418. SmartcardExtension->ReaderExtension->IccConfig.PTS0 = IFD_NEGOTIATE_T0 | IFD_NEGOTIATE_PTS1;
  419. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  420. } else {
  421. status = STATUS_INVALID_DEVICE_REQUEST;
  422. __leave;
  423. }
  424. //
  425. // Set pts1 which codes Fl and Dl
  426. //
  427. SmartcardExtension->ReaderExtension->IccConfig.PTS1 =
  428. SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  429. SmartcardExtension->CardCapabilities.PtsData.Dl;
  430. param->IccConfig.PTSMode = IFD_NEGOTIATE_PTS_MANUALLY;
  431. rlen = HOR3GLL_BUFFER_SIZE;
  432. status = GDDK_Oros3IccPowerUp(
  433. param->Handle,
  434. param->CmdTimeOut,
  435. param->IccConfig.ICCVcc,
  436. param->IccConfig.PTSMode,
  437. param->IccConfig.PTS0,
  438. param->IccConfig.PTS1,
  439. param->IccConfig.PTS2,
  440. param->IccConfig.PTS3,
  441. &rlen,
  442. rbuff
  443. );
  444. if (status == STATUS_SUCCESS) {
  445. status = GDDK_Translate(rbuff[0],RDF_CARD_POWER);
  446. }
  447. if (status == STATUS_SUCCESS ) {
  448. //The card replied correctly to our pts-request
  449. SmartcardDebug(
  450. DEBUG_TRACE,
  451. ("%s!GDDK_0ASetProtocol: PTS Request OK\n",
  452. SC_DRIVER_NAME)
  453. );
  454. break;
  455. } else if (SmartcardExtension->CardCapabilities.PtsData.Type !=
  456. PTS_TYPE_DEFAULT
  457. ) {
  458. SmartcardDebug(
  459. DEBUG_TRACE,
  460. ("%s!GDDK_0ASetProtocol: PTS failed. Trying default parameters...\n",
  461. SC_DRIVER_NAME)
  462. );
  463. //
  464. // The card did either NOT reply or it replied incorrectly
  465. // so try default values.
  466. // Set PtsData Type to Default and do a cold reset
  467. //
  468. SmartcardExtension->CardCapabilities.PtsData.Type =
  469. PTS_TYPE_DEFAULT;
  470. status = GDDK_0AIccReset(SmartcardExtension,SCARD_COLD_RESET);
  471. continue;
  472. }
  473. //
  474. // The card failed the pts-request
  475. //
  476. status = STATUS_DEVICE_PROTOCOL_ERROR;
  477. __leave;
  478. } //End of the while
  479. //
  480. // The card replied correctly to the pts request
  481. // Set the appropriate parameters for the port
  482. //
  483. if ( SmartcardExtension->CardCapabilities.Protocol.Selected &
  484. SCARD_PROTOCOL_T1
  485. ) {
  486. serialConfigData->Timeouts.ReadIntervalTimeout = 10 +
  487. SmartcardExtension->CardCapabilities.T1.CWT / 1000;
  488. }
  489. else if ( SmartcardExtension->CardCapabilities.Protocol.Selected &
  490. SCARD_PROTOCOL_T0
  491. ) {
  492. serialConfigData->Timeouts.ReadIntervalTimeout = 10 +
  493. SmartcardExtension->CardCapabilities.T0.WT / 1000;
  494. }
  495. //
  496. // Now indicate that we're in specific mode
  497. // and return the selected protocol to the caller
  498. //
  499. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  500. *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer =
  501. SmartcardExtension->CardCapabilities.Protocol.Selected;
  502. *SmartcardExtension->IoRequest.Information =
  503. sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
  504. }
  505. __finally
  506. {
  507. if (status != STATUS_SUCCESS) {
  508. SmartcardExtension->CardCapabilities.Protocol.Selected =
  509. SCARD_PROTOCOL_UNDEFINED;
  510. *SmartcardExtension->IoRequest.Information = 0;
  511. }
  512. }
  513. SmartcardDebug(
  514. DEBUG_TRACE,
  515. ("%s!GDDK_0ASetProtocol: Exit=%lX(hex)\n",
  516. SC_DRIVER_NAME,
  517. status)
  518. );
  519. // Unlock the mutex.
  520. GDDK_0AUnlockExchange(SmartcardExtension);
  521. return status;
  522. }
  523. NTSTATUS
  524. GDDK_0ATransmit(
  525. PSMARTCARD_EXTENSION SmartcardExtension
  526. )
  527. /*++
  528. Routine Description:
  529. This function is called by the Smart card library when a
  530. IOCTL_SMARTCARD_TRANSMIT occurs.
  531. This function is used to transmit a command to the card.
  532. Arguments:
  533. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  534. the current device.
  535. Return Value:
  536. STATUS_SUCCESS - We could execute the request.
  537. STATUS_INVALID_DEVICE_STATE - If the protocol specified is different from
  538. the protocol selected
  539. STATUS_INVALID_DEVICE_REQUEST - We could not support the protocol specified.
  540. --*/
  541. {
  542. NTSTATUS status;
  543. PUCHAR requestBuffer = SmartcardExtension->SmartcardRequest.Buffer,
  544. replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
  545. PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
  546. PSCARD_IO_REQUEST scardIoRequest = (PSCARD_IO_REQUEST)
  547. SmartcardExtension->OsData->CurrentIrp->AssociatedIrp.SystemBuffer;
  548. READER_EXTENSION *param = SmartcardExtension->ReaderExtension;
  549. USHORT rlen,
  550. rlenCmd;
  551. BYTE cmd[5],
  552. rbuff[HOR3GLL_BUFFER_SIZE],
  553. rbuffCmd[HOR3GLL_BUFFER_SIZE];
  554. ULONG t1Timeout;
  555. PAGED_CODE();
  556. SmartcardDebug(
  557. DEBUG_IOCTL,
  558. ("%s!GDDK_0ATransmit: Enter\n",
  559. SC_DRIVER_NAME)
  560. );
  561. //Set the reply buffer length to 0.
  562. *SmartcardExtension->IoRequest.Information = 0;
  563. status = STATUS_SUCCESS;
  564. //
  565. // Verify if the protocol specified is the same than the protocol selected.
  566. //
  567. *requestLength = 0;
  568. if (SmartcardExtension->CardCapabilities.Protocol.Selected !=
  569. scardIoRequest->dwProtocol) {
  570. return (STATUS_INVALID_DEVICE_STATE);
  571. }
  572. // Lock the mutex to avoid a call of an other command.
  573. GDDK_0ALockExchange(SmartcardExtension);
  574. switch (SmartcardExtension->CardCapabilities.Protocol.Selected) {
  575. // For RAW protocol we return STATUS_INVALID_DEVICE_STATE
  576. case SCARD_PROTOCOL_RAW:
  577. status = STATUS_INVALID_DEVICE_STATE;
  578. break;
  579. //
  580. // T=0 PROTOCOL:
  581. // Call the SmartCardT0Request which updates the SmartcardRequest struct.
  582. //
  583. case SCARD_PROTOCOL_T0:
  584. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  585. status = SmartcardT0Request(SmartcardExtension);
  586. if (status == STATUS_SUCCESS) {
  587. rlen = HOR3GLL_BUFFER_SIZE;
  588. //
  589. // If the length LEx > 0
  590. // Then
  591. // Is an ISO Out command.
  592. // If LEx > SC_IFD_T0_MAXIMUM_LEX (256) we return STATUS_BUFFER_TOO_SMALL
  593. // Call the GDDK_Oros3IsoOutput
  594. //
  595. if (SmartcardExtension->T0.Le > 0) {
  596. if (SmartcardExtension->T0.Le > SC_IFD_T0_MAXIMUM_LEX) {
  597. status = STATUS_BUFFER_TOO_SMALL;
  598. }
  599. if (status == STATUS_SUCCESS) {
  600. status = GDDK_Oros3IsoOutput(
  601. param->Handle,
  602. param->APDUTimeOut,
  603. HOR3GLL_IFD_CMD_ICC_ISO_OUT,
  604. (BYTE *)SmartcardExtension->SmartcardRequest.Buffer,
  605. &rlen,
  606. rbuff
  607. );
  608. }
  609. } else {
  610. //
  611. // Else Is an ISO In command.
  612. // If LC > SC_IFD_T0_MAXIMUM_LC (255) we return STATUS_BUFFER_TOO_SMALL
  613. // Call the GDDK_Oros3IsoInput
  614. //
  615. if (SmartcardExtension->T0.Lc > SC_IFD_T0_MAXIMUM_LC) {
  616. status = STATUS_BUFFER_TOO_SMALL;
  617. }
  618. if (status == STATUS_SUCCESS) {
  619. status = GDDK_Oros3IsoInput(
  620. param->Handle,
  621. param->APDUTimeOut,
  622. HOR3GLL_IFD_CMD_ICC_ISO_IN,
  623. (BYTE *)SmartcardExtension->SmartcardRequest.Buffer,
  624. (BYTE *)SmartcardExtension->SmartcardRequest.Buffer + 5,
  625. &rlen,
  626. rbuff
  627. );
  628. }
  629. }
  630. }
  631. if (status == STATUS_SUCCESS) {
  632. status = GDDK_Translate(rbuff[0],RDF_TRANSMIT);
  633. }
  634. //
  635. // If the Status is Success
  636. // Copy the response in the SmartcardReply buffer. Remove the status
  637. // of the reader.
  638. // Call the SmartcardT0reply function to update the IORequest struct.
  639. //
  640. if (status == STATUS_SUCCESS){
  641. ASSERT(SmartcardExtension->SmartcardReply.BufferSize >= (ULONG) (rlen - 1));
  642. RtlCopyMemory(
  643. SmartcardExtension->SmartcardReply.Buffer,
  644. rbuff + 1,
  645. rlen - 1
  646. );
  647. SmartcardExtension->SmartcardReply.BufferLength = (ULONG) (rlen - 1);
  648. status = SmartcardT0Reply(SmartcardExtension);
  649. }
  650. break;
  651. //
  652. // T=1 PROTOCOL:
  653. //
  654. case SCARD_PROTOCOL_T1:
  655. //
  656. // If the current card type <> TRANSPARENT_PROTOCOL,
  657. //
  658. if (param->IccConfig.ICCType != TRANSPARENT_PROTOCOL) {
  659. // We read the status of the card to known the current voltage and the TA1
  660. rlenCmd = HOR3GLL_BUFFER_SIZE;
  661. cmd[0] = HOR3GLL_IFD_CMD_ICC_STATUS;
  662. status = GDDK_Oros3Exchange(
  663. param->Handle,
  664. HOR3GLL_LOW_TIME,
  665. 1,
  666. cmd,
  667. &rlenCmd,
  668. rbuffCmd
  669. );
  670. param->TransparentConfig.CFG = rbuffCmd[1] & 0x01; //Vcc
  671. param->TransparentConfig.Fi = rbuffCmd[3] >>4; //Fi
  672. param->TransparentConfig.Di = 0x0F & rbuffCmd[3]; //Di
  673. //We define the type of the card.
  674. rlenCmd = HOR3GLL_BUFFER_SIZE;
  675. param->IccConfig.ICCType = TRANSPARENT_PROTOCOL;
  676. cmd[0] = HOR3GLL_IFD_CMD_ICC_DEFINE_TYPE;
  677. cmd[1] = (BYTE) param->IccConfig.ICCType;
  678. cmd[2] = (BYTE) param->IccConfig.ICCVpp;
  679. cmd[3] = (BYTE) param->IccConfig.ICCPresence ;
  680. status = GDDK_Oros3Exchange(
  681. param->Handle,
  682. HOR3GLL_LOW_TIME,
  683. 4,
  684. cmd,
  685. &rlenCmd,
  686. rbuffCmd
  687. );
  688. if (status == STATUS_SUCCESS) {
  689. status = GDDK_Translate(rbuffCmd[0],RDF_TRANSMIT);
  690. }
  691. if (status != STATUS_SUCCESS) {
  692. break;
  693. }
  694. // Set the transparent configuration
  695. GDDK_0ASetTransparentConfig(SmartcardExtension,SmartcardExtension->T1.Wtx);
  696. }
  697. //
  698. // Loop for the T=1 management
  699. //
  700. do {
  701. PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
  702. // Tell the lib function how many bytes I need for the prologue
  703. //
  704. *requestLength = 0;
  705. status = SmartcardT1Request(SmartcardExtension);
  706. if (status != STATUS_SUCCESS) {
  707. break;
  708. }
  709. if (SmartcardExtension->T1.Wtx) {
  710. // Compute the timeout for the Oros3Exchange (WTX * BWT)
  711. t1Timeout = SmartcardExtension->CardCapabilities.T1.BWT / 1000;
  712. t1Timeout *= SmartcardExtension->T1.Wtx;
  713. t1Timeout += 500;
  714. GDDK_0ASetTransparentConfig(SmartcardExtension,SmartcardExtension->T1.Wtx);
  715. } else {
  716. t1Timeout = SmartcardExtension->CardCapabilities.T1.BWT / 1000;
  717. t1Timeout += 500;
  718. }
  719. SER_SetPortTimeout(param->Handle, t1Timeout);
  720. rlen = HOR3GLL_BUFFER_SIZE;
  721. status = GDDK_Oros3TransparentExchange(
  722. param->Handle,
  723. t1Timeout,
  724. (USHORT) SmartcardExtension->SmartcardRequest.BufferLength,
  725. SmartcardExtension->SmartcardRequest.Buffer,
  726. &rlen,
  727. rbuff
  728. );
  729. if (status == STATUS_SUCCESS) {
  730. status = GDDK_Translate(rbuff[0],RDF_TRANSMIT);
  731. }
  732. if (status != STATUS_SUCCESS) {
  733. rlen = 1;
  734. }
  735. if (SmartcardExtension->T1.Wtx) {
  736. // Set the reader BWI to the default value
  737. GDDK_0ASetTransparentConfig(SmartcardExtension,0);
  738. }
  739. // Copy the response in the reply buffer
  740. if (SmartcardExtension->SmartcardReply.BufferSize >= (ULONG) (rlen -1)) {
  741. SmartcardExtension->SmartcardReply.BufferLength = (ULONG) (rlen - 1);
  742. if (SmartcardExtension->SmartcardReply.BufferLength > 0) {
  743. RtlCopyMemory(
  744. SmartcardExtension->SmartcardReply.Buffer,
  745. rbuff + 1,
  746. rlen - 1
  747. );
  748. }
  749. }
  750. status = SmartcardT1Reply(SmartcardExtension);
  751. } while (status == STATUS_MORE_PROCESSING_REQUIRED);
  752. break;
  753. default:
  754. status = STATUS_INVALID_DEVICE_REQUEST;
  755. break;
  756. }
  757. SER_SetPortTimeout(param->Handle, HOR3COMM_CHAR_TIMEOUT);
  758. // Unlock the mutex.
  759. GDDK_0AUnlockExchange(SmartcardExtension);
  760. SmartcardDebug(
  761. DEBUG_IOCTL,
  762. ("%s!GDDK_0ATransmit: Exit=%X(hex)\n",
  763. SC_DRIVER_NAME,
  764. status)
  765. );
  766. if (status != STATUS_SUCCESS) {
  767. SmartcardDebug(
  768. DEBUG_ERROR,
  769. ("%s!GDDK_0ATransmit: failed! status=%X(hex)\n",
  770. SC_DRIVER_NAME,
  771. status)
  772. );
  773. }
  774. return (status);
  775. }
  776. NTSTATUS
  777. GDDK_0ACardTracking(
  778. PSMARTCARD_EXTENSION SmartcardExtension
  779. )
  780. /*++
  781. Routine Description:
  782. This function is called by the Smart card library when an
  783. IOCTL_SMARTCARD_IS_PRESENT or IOCTL_SMARTCARD_IS_ABSENT occurs.
  784. Arguments:
  785. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  786. the current device.
  787. Return Value:
  788. STATUS_PENDING - The request is in a pending mode.
  789. --*/
  790. {
  791. KIRQL oldIrql;
  792. //
  793. // Set cancel routine for the notification irp
  794. //
  795. IoAcquireCancelSpinLock(&oldIrql);
  796. IoSetCancelRoutine(
  797. SmartcardExtension->OsData->NotificationIrp,
  798. GCR410PCancel
  799. );
  800. IoReleaseCancelSpinLock(oldIrql);
  801. return STATUS_PENDING;
  802. }
  803. NTSTATUS
  804. GDDK_0AVendorIoctl(
  805. PSMARTCARD_EXTENSION SmartcardExtension
  806. )
  807. /*++
  808. Routine Description:
  809. This routine is called when a vendor IOCTL_SMARTCARD_ is send to the driver.
  810. Arguments:
  811. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  812. the current device.
  813. Return Value:
  814. STATUS_SUCCESS - We could execute the request.
  815. STATUS_BUFFER_TOO_SMALL - The output buffer is to small.
  816. STATUS_NOT_SUPPORTED - We could not support the Ioctl specified.
  817. --*/
  818. {
  819. NTSTATUS status = STATUS_SUCCESS;
  820. READER_EXTENSION *param = SmartcardExtension->ReaderExtension;
  821. USHORT rlen;
  822. BYTE rbuff[HOR3GLL_BUFFER_SIZE];
  823. PAGED_CODE();
  824. ASSERT(SmartcardExtension != NULL);
  825. SmartcardDebug(
  826. DEBUG_IOCTL,
  827. ("%s!GDDK_0AVendorIoctl: Enter, IoControlCode=%lX(hex)\n",
  828. SC_DRIVER_NAME,
  829. SmartcardExtension->MajorIoControlCode)
  830. );
  831. // Lock the mutex to avoid a call of an other command.
  832. GDDK_0ALockExchange(SmartcardExtension);
  833. // Set the reply buffer length to 0.
  834. *SmartcardExtension->IoRequest.Information = 0;
  835. switch(SmartcardExtension->MajorIoControlCode) {
  836. //
  837. // For IOCTL_SMARTCARD_VENDOR_GET_ATTRIBUTE and IOCTL_VENDOR_SMARTCARD_SET_ATTRIBUTE
  838. // Call the GDDK_0AVendorTag function
  839. //
  840. case IOCTL_SMARTCARD_VENDOR_GET_ATTRIBUTE:
  841. case IOCTL_SMARTCARD_VENDOR_SET_ATTRIBUTE:
  842. status = GDDK_0AVendorTag(
  843. SmartcardExtension,
  844. (ULONG) SmartcardExtension->MajorIoControlCode,
  845. (ULONG) SmartcardExtension->IoRequest.RequestBufferLength,
  846. (PUCHAR) SmartcardExtension->IoRequest.RequestBuffer,
  847. (ULONG) SmartcardExtension->IoRequest.ReplyBufferLength,
  848. (PUCHAR) SmartcardExtension->IoRequest.ReplyBuffer,
  849. (PULONG) SmartcardExtension->IoRequest.Information
  850. );
  851. break;
  852. //
  853. // For IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE
  854. // Send the command to the reader
  855. //
  856. case IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE:
  857. rlen = (USHORT) HOR3GLL_BUFFER_SIZE;
  858. status = GDDK_Oros3Exchange(
  859. param->Handle,
  860. HOR3GLL_LOW_TIME,
  861. (USHORT) SmartcardExtension->IoRequest.RequestBufferLength,
  862. (BYTE *) SmartcardExtension->IoRequest.RequestBuffer,
  863. &rlen,
  864. rbuff
  865. );
  866. if (status != STATUS_SUCCESS) {
  867. break;
  868. }
  869. if (SmartcardExtension->IoRequest.ReplyBufferLength < (ULONG) rlen) {
  870. status = STATUS_BUFFER_TOO_SMALL;
  871. break;
  872. }
  873. RtlCopyMemory(
  874. SmartcardExtension->IoRequest.ReplyBuffer,
  875. rbuff,
  876. rlen
  877. );
  878. *(SmartcardExtension->IoRequest.Information) = (ULONG) rlen;
  879. status = STATUS_SUCCESS;
  880. break;
  881. default:
  882. status = STATUS_NOT_SUPPORTED;
  883. break;
  884. }
  885. // Unlock the mutex.
  886. GDDK_0AUnlockExchange(SmartcardExtension);
  887. SmartcardDebug(
  888. DEBUG_IOCTL,
  889. ("%s!GDDK_0AVendorIoctl: Exit=%X(hex)\n",
  890. SC_DRIVER_NAME,
  891. status)
  892. );
  893. return status;
  894. }
  895. NTSTATUS
  896. GDDK_0AVendorTag(
  897. PSMARTCARD_EXTENSION SmartcardExtension,
  898. ULONG IoControlCode,
  899. ULONG BufferInLen,
  900. PUCHAR BufferIn,
  901. ULONG BufferOutLen,
  902. PUCHAR BufferOut,
  903. PULONG LengthOut
  904. )
  905. /*++
  906. Routine Description:
  907. This function is called when a specific Tag request occurs.
  908. Arguments:
  909. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  910. the current device.
  911. IoControlCode - holds the Ioctl value.
  912. BufferInLen - holds the length of the input data.
  913. BufferIn - holds the input data.
  914. BufferOutLen - holds the size of the output buffer.
  915. BufferOut - the output buffer.
  916. LengthOut - holds the length of the output data.
  917. Return Value:
  918. STATUS_SUCCESS - We could execute the request.
  919. STATUS_BUFFER_TOO_SMALL - The output buffer is to small.
  920. STATUS_NOT_SUPPORTED - We could not support the Ioctl specified.
  921. --*/
  922. {
  923. ULONG TagValue;
  924. PREADER_EXTENSION pReaderExtension = SmartcardExtension->ReaderExtension;
  925. ASSERT(pReaderExtension != NULL);
  926. // Set the reply buffer length to 0.
  927. *LengthOut = 0l;
  928. // Verify the length of the Tag
  929. if (BufferInLen < sizeof(TagValue)) {
  930. return(STATUS_BUFFER_TOO_SMALL);
  931. }
  932. TagValue = (ULONG) *((PULONG)BufferIn);
  933. // Switch for the different IOCTL:
  934. // Get the value of one tag (IOCTL_SMARTCARD_VENDOR_GET_ATTRIBUTE)
  935. // Switch for the different Tags:
  936. switch(IoControlCode) {
  937. // Get an attribute
  938. case IOCTL_SMARTCARD_VENDOR_GET_ATTRIBUTE:
  939. switch (TagValue) {
  940. // Baud rate of the reader (SCARD_ATTR_SPEC_BAUD_RATE)
  941. case SCARD_ATTR_SPEC_BAUD_RATE:
  942. if (BufferOutLen < (ULONG) sizeof(pReaderExtension->IFDBaudRate)) {
  943. return(STATUS_BUFFER_TOO_SMALL);
  944. }
  945. RtlCopyMemory(
  946. BufferOut,
  947. &pReaderExtension->IFDBaudRate,
  948. sizeof(pReaderExtension->IFDBaudRate)
  949. );
  950. *(LengthOut) = (ULONG) sizeof(pReaderExtension->IFDBaudRate);
  951. return (STATUS_SUCCESS);
  952. break;
  953. // Power Timeout (SCARD_ATTR_SPEC_POWER_TIMEOUT)
  954. case SCARD_ATTR_SPEC_POWER_TIMEOUT:
  955. if (BufferOutLen < (ULONG) sizeof(pReaderExtension->PowerTimeOut)) {
  956. return(STATUS_BUFFER_TOO_SMALL);
  957. }
  958. RtlCopyMemory(
  959. BufferOut,
  960. &pReaderExtension->PowerTimeOut,
  961. sizeof(pReaderExtension->PowerTimeOut)
  962. );
  963. *(LengthOut) = (ULONG) sizeof(pReaderExtension->PowerTimeOut);
  964. return STATUS_SUCCESS;
  965. break;
  966. // Command Timeout (SCARD_ATTR_SPEC_CMD_TIMEOUT)
  967. case SCARD_ATTR_SPEC_CMD_TIMEOUT:
  968. if (BufferOutLen < (ULONG) sizeof(pReaderExtension->CmdTimeOut)) {
  969. return(STATUS_BUFFER_TOO_SMALL);
  970. }
  971. RtlCopyMemory(
  972. BufferOut,
  973. &pReaderExtension->CmdTimeOut,
  974. sizeof(pReaderExtension->CmdTimeOut)
  975. );
  976. *(LengthOut) = (ULONG) sizeof(pReaderExtension->CmdTimeOut);
  977. return STATUS_SUCCESS;
  978. break;
  979. // APDU Timeout (SCARD_ATTR_SPEC_APDU_TIMEOUT)
  980. case SCARD_ATTR_SPEC_APDU_TIMEOUT:
  981. if (BufferOutLen < (ULONG) sizeof(pReaderExtension->APDUTimeOut)) {
  982. return(STATUS_BUFFER_TOO_SMALL);
  983. }
  984. RtlCopyMemory(
  985. BufferOut,
  986. &pReaderExtension->APDUTimeOut,
  987. sizeof(pReaderExtension->APDUTimeOut)
  988. );
  989. *(LengthOut) = (ULONG) sizeof(pReaderExtension->APDUTimeOut);
  990. return STATUS_SUCCESS;
  991. break;
  992. // Unknown tag, we return STATUS_NOT_SUPPORTED
  993. default:
  994. return STATUS_NOT_SUPPORTED;
  995. break;
  996. }
  997. break;
  998. // Set the value of one tag (IOCTL_SMARTCARD_VENDOR_SET_ATTRIBUTE)
  999. case IOCTL_SMARTCARD_VENDOR_SET_ATTRIBUTE:
  1000. switch (TagValue) {
  1001. // Power Timeout (SCARD_ATTR_SPEC_POWER_TIMEOUT)
  1002. case SCARD_ATTR_SPEC_POWER_TIMEOUT:
  1003. if (BufferInLen <(ULONG) (sizeof(pReaderExtension->PowerTimeOut) + sizeof(TagValue))) {
  1004. return(STATUS_BUFFER_TOO_SMALL);
  1005. }
  1006. RtlCopyMemory(
  1007. &pReaderExtension->PowerTimeOut,
  1008. BufferIn + sizeof(TagValue),
  1009. sizeof(pReaderExtension->PowerTimeOut)
  1010. );
  1011. return STATUS_SUCCESS;
  1012. break;
  1013. // Command Timeout (SCARD_ATTR_SPEC_CMD_TIMEOUT)
  1014. case SCARD_ATTR_SPEC_CMD_TIMEOUT:
  1015. if (BufferInLen <(ULONG) (sizeof(pReaderExtension->CmdTimeOut) + sizeof(TagValue))) {
  1016. return(STATUS_BUFFER_TOO_SMALL);
  1017. }
  1018. RtlCopyMemory(
  1019. &pReaderExtension->CmdTimeOut,
  1020. BufferIn + sizeof(TagValue),
  1021. sizeof(pReaderExtension->CmdTimeOut)
  1022. );
  1023. return STATUS_SUCCESS;
  1024. break;
  1025. // Command Timeout (SCARD_ATTR_SPEC_APDU_TIMEOUT)
  1026. case SCARD_ATTR_SPEC_APDU_TIMEOUT:
  1027. if (BufferInLen <(ULONG) (sizeof(pReaderExtension->APDUTimeOut) + sizeof(TagValue))) {
  1028. return(STATUS_BUFFER_TOO_SMALL);
  1029. }
  1030. RtlCopyMemory(
  1031. &pReaderExtension->APDUTimeOut,
  1032. BufferIn + sizeof(TagValue),
  1033. sizeof(pReaderExtension->APDUTimeOut)
  1034. );
  1035. return STATUS_SUCCESS;
  1036. break;
  1037. // Unknown tag, we return STATUS_NOT_SUPPORTED
  1038. default:
  1039. return STATUS_NOT_SUPPORTED;
  1040. }
  1041. break;
  1042. default:
  1043. return STATUS_NOT_SUPPORTED;
  1044. break;
  1045. }
  1046. }
  1047. NTSTATUS
  1048. GDDK_0AOpenChannel(
  1049. PSMARTCARD_EXTENSION SmartcardExtension,
  1050. CONST ULONG DeviceNumber,
  1051. CONST ULONG PortSerialNumber,
  1052. CONST ULONG MaximalBaudRate
  1053. )
  1054. /*++
  1055. Routine Description:
  1056. This routine try to establish a connection with a reader, and after
  1057. update the characteristic of this reader.
  1058. Arguments:
  1059. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  1060. the current device.
  1061. DeviceNumber - holds the current device number (0 to MAX_DEVICES).
  1062. PortSerialNumber - holds the port serial number (0 to HGTSER_MAX_PORT).
  1063. MaximalBaudRate - holds the maximal speed specified for the reader.
  1064. Return Value:
  1065. STATUS_SUCCESS - We could execute the request.
  1066. --*/
  1067. {
  1068. NTSTATUS status = STATUS_SUCCESS;
  1069. short handle,portcom;
  1070. char os_string[HOR3GLL_OS_STRING_SIZE];
  1071. USHORT os_length = HOR3GLL_OS_STRING_SIZE;
  1072. USHORT user;
  1073. TGTSER_PORT comm;
  1074. ULONG br;
  1075. BYTE minorVersion,majorVersion;
  1076. COM_SERIAL serial_channel;
  1077. USHORT rlen;
  1078. BYTE cmd[5],rbuff[HOR3GLL_BUFFER_SIZE];
  1079. LARGE_INTEGER timeout;
  1080. // Update the serial communication channel information:
  1081. serial_channel.Port = PortSerialNumber + G_COM1;
  1082. serial_channel.BaudRate = MaximalBaudRate;
  1083. serial_channel.pSmartcardExtension = SmartcardExtension;
  1084. // Initializes a mutex object (in a high level) for the exchange commands with
  1085. // the smart card reader.
  1086. KeInitializeMutex(
  1087. &SmartcardExtension->ReaderExtension->ExchangeMutex,
  1088. 3
  1089. );
  1090. // Initializes a mutex object (in a high level) for the long APDU commands with
  1091. // the smart card reader.
  1092. KeInitializeMutex(
  1093. &SmartcardExtension->ReaderExtension->LongAPDUMutex,
  1094. 3
  1095. );
  1096. // Open a communication channel (GDDK_Oros3OpenComm).
  1097. // The reader baudrate is automatically detected by this function.
  1098. handle = (short)DeviceNumber;
  1099. status = GDDK_Oros3OpenComm(&serial_channel,handle);
  1100. if (status == STATUS_DEVICE_ALREADY_ATTACHED) {
  1101. status = GDDK_SerPortAddUser((USHORT) serial_channel.Port,&portcom);
  1102. if (status != STATUS_SUCCESS) {
  1103. return (status);
  1104. }
  1105. GDDK_GBPOpen(handle,2,4,portcom);
  1106. }
  1107. if (status != STATUS_SUCCESS) {
  1108. return (status);
  1109. }
  1110. //
  1111. // Verify the Firmware version: this driver support only the PnP GemCore based
  1112. // readers
  1113. //
  1114. cmd[0] = (BYTE) HOR3GLL_IFD_CMD_MEM_RD;
  1115. cmd[1] = (BYTE)HOR3GLL_IFD_TYP_VERSION;
  1116. cmd[2] = HIBYTE(HOR3GLL_IFD_ADD_VERSION);
  1117. cmd[3] = LOBYTE(HOR3GLL_IFD_ADD_VERSION);
  1118. cmd[4] = (BYTE)HOR3GLL_IFD_LEN_VERSION;
  1119. status = GDDK_Oros3Exchange(
  1120. handle,
  1121. HOR3GLL_LOW_TIME,
  1122. 5,
  1123. cmd,
  1124. &os_length,
  1125. os_string
  1126. );
  1127. if (status != STATUS_SUCCESS) {
  1128. GDDK_Oros3CloseComm(handle);
  1129. return (status);
  1130. }
  1131. if (os_length >= (USHORT)strlen(IFD_FIRMWARE_VERSION)) {
  1132. if (memcmp(os_string + 1,IFD_FIRMWARE_VERSION,strlen(IFD_FIRMWARE_VERSION))) {
  1133. GDDK_Oros3CloseComm(handle);
  1134. return (STATUS_INVALID_DEVICE_STATE);
  1135. }
  1136. } else {
  1137. GDDK_Oros3CloseComm(handle);
  1138. return (STATUS_INVALID_DEVICE_STATE);
  1139. }
  1140. // GemCore Rx.yy-yz
  1141. // x = major version
  1142. // y = minor version
  1143. // z = M if masked version
  1144. majorVersion = os_string[strlen(IFD_FIRMWARE_VERSION) + 1] - '0';
  1145. minorVersion = 100 * (os_string[strlen(IFD_FIRMWARE_VERSION) + 3] - '0');
  1146. minorVersion += 10 * (os_string[strlen(IFD_FIRMWARE_VERSION) + 4] - '0');
  1147. minorVersion += (os_string[strlen(IFD_FIRMWARE_VERSION) + 6] - '0');
  1148. SmartcardDebug(
  1149. DEBUG_TRACE,
  1150. ("%s!GDDK_0AOpenChannel: GemCore version = %d.%d\n",
  1151. SC_DRIVER_NAME,
  1152. majorVersion,
  1153. minorVersion)
  1154. );
  1155. if ((majorVersion < IFD_VERSION_MAJOR) || (minorVersion < IFD_VERSION_MINOR)) {
  1156. GDDK_Oros3CloseComm(handle);
  1157. SmartcardDebug(
  1158. DEBUG_ERROR,
  1159. ("%s!GDDK_0AOpenChannel: The firmware version is not supported by the driver!\n",
  1160. SC_DRIVER_NAME)
  1161. );
  1162. return (STATUS_BAD_DEVICE_TYPE);
  1163. }
  1164. // Optimizes the baudrate:
  1165. // Initializes the comm variable to modify the used baud rate.
  1166. status = GDDK_GBPChannelToPortComm(handle,&portcom);
  1167. if (status != STATUS_SUCCESS) {
  1168. GDDK_Oros3CloseComm(handle);
  1169. return status;
  1170. }
  1171. status = GDDK_SerPortGetState(
  1172. portcom,
  1173. &comm,
  1174. &user
  1175. );
  1176. if (status != STATUS_SUCCESS) {
  1177. GDDK_Oros3CloseComm(handle);
  1178. return status;
  1179. }
  1180. //ISV
  1181. // Connection was established
  1182. // Now try to connect at max speed!
  1183. comm.BaudRate = serial_channel.BaudRate;
  1184. SmartcardDebug(
  1185. DEBUG_TRACE,
  1186. ("%s!GDDK_0AOpenChannel: Connection established at %d baud rate\n",
  1187. SC_DRIVER_NAME,comm.BaudRate));
  1188. // Unsupported baud rate
  1189. if(comm.BaudRate >= 38400)
  1190. {
  1191. SmartcardDebug(DEBUG_ERROR,("GDDK_0AOpenChannel: ###### UNSUPPORTED BAUD RATE %d\n", comm.BaudRate));
  1192. GDDK_Oros3CloseComm(handle);
  1193. return (STATUS_INVALID_DEVICE_STATE);
  1194. }
  1195. // Maximum baud rate is already set - nothing to do
  1196. if(comm.BaudRate==38400)
  1197. {
  1198. SmartcardDebug(DEBUG_DRIVER,("GDDK_0AOpenChannel: MAX SPEED SET TO 38400!\n"));
  1199. }
  1200. else
  1201. {
  1202. // Try to negotiate a better baud rate.
  1203. int i=0;
  1204. BOOLEAN bBetterBaudRate=FALSE;
  1205. ULONG brList[3] = {38400, 19200, 9600};
  1206. USHORT brListLength = 3;
  1207. ULONG previousBaudRate = 0;
  1208. KEVENT event;
  1209. previousBaudRate = comm.BaudRate;
  1210. i = 0;
  1211. while ( (i < brListLength) &&
  1212. (bBetterBaudRate == FALSE) )
  1213. {
  1214. br = brList[i];
  1215. // The reader is switched to the selected value (GDDK_Oros3SIOConfigure). The
  1216. // function status is not tested because, as the IFD has switched
  1217. // immediatly, it is not possible to read its response.
  1218. comm.BaudRate = br;
  1219. rlen = 0;
  1220. rbuff[0]=0x0;
  1221. GDDK_Oros3SIOConfigure(
  1222. handle,
  1223. HOR3GLL_LOW_TIME,
  1224. 0,
  1225. 8,
  1226. comm.BaudRate,
  1227. &rlen,
  1228. rbuff,
  1229. FALSE
  1230. );
  1231. //
  1232. // Waits for the fisrt command is processed by the reader
  1233. // 500 ms is enought
  1234. //
  1235. KeInitializeEvent(&event,NotificationEvent,FALSE);
  1236. timeout.QuadPart = -((LONGLONG) 500 * 1000);
  1237. KeWaitForSingleObject(&event,
  1238. Suspended,
  1239. KernelMode,
  1240. FALSE,
  1241. &timeout);
  1242. // Host is switched to the selected value (GDDK_SerPortSetState).
  1243. // If this call is successful,
  1244. // Then
  1245. // The last command is re-sent to read the IFD response.
  1246. // response is optionnaly initialized with the translated IFD status.
  1247. status = GDDK_SerPortSetState(
  1248. portcom,
  1249. &comm
  1250. );
  1251. if (status == STATUS_SUCCESS)
  1252. {
  1253. rlen = HOR3GLL_BUFFER_SIZE;
  1254. rbuff[0]=0x0;
  1255. status = GDDK_Oros3SIOConfigure(
  1256. handle,
  1257. HOR3GLL_LOW_TIME,
  1258. 0,
  1259. 8,
  1260. comm.BaudRate,
  1261. &rlen,
  1262. rbuff,
  1263. TRUE
  1264. );
  1265. if (status == STATUS_SUCCESS)
  1266. {
  1267. bBetterBaudRate = TRUE;
  1268. }
  1269. }
  1270. } // endwhile
  1271. // Check if a better baudrate was negotiated
  1272. if (bBetterBaudRate==FALSE)
  1273. {
  1274. //*** Can come back to the previous one
  1275. // return an error message right now.
  1276. GDDK_Oros3CloseComm(handle);
  1277. return (STATUS_INVALID_DEVICE_STATE);
  1278. }
  1279. }
  1280. SmartcardDebug(
  1281. DEBUG_TRACE,
  1282. ("%s!GDDK_0AOpenChannel: Reader speed was set to %d baud rate\n",
  1283. SC_DRIVER_NAME,comm.BaudRate));
  1284. // Sends the SetMode command with parameter 0 to disable TLP compatibility.
  1285. rlen = HOR3GLL_BUFFER_SIZE;
  1286. cmd[0] = (BYTE) HOR3GLL_IFD_CMD_MODE_SET;
  1287. cmd[1] = (BYTE) 0x00;
  1288. cmd[2] = (BYTE) 0x00;
  1289. status = GDDK_Oros3Exchange(
  1290. handle,
  1291. HOR3GLL_LOW_TIME,
  1292. 3,
  1293. cmd,
  1294. &rlen,
  1295. rbuff
  1296. );
  1297. if (status != STATUS_SUCCESS) {
  1298. GDDK_Oros3CloseComm(handle);
  1299. return (status);
  1300. }
  1301. // Reader capabilities:
  1302. // - the type of the reader (SCARD_READER_TYPE_SERIAL)
  1303. // - the channel for the reader (PortSerialNumber)
  1304. // - the protocols supported by the reader (SCARD_PROTOCOL_T0, SCARD_PROTOCOL_T1)
  1305. // - the mechanical characteristic of the reader:
  1306. SmartcardExtension->ReaderCapabilities.ReaderType =
  1307. SCARD_READER_TYPE_SERIAL;
  1308. SmartcardExtension->ReaderCapabilities.Channel =
  1309. PortSerialNumber;
  1310. SmartcardExtension->ReaderCapabilities.SupportedProtocols =
  1311. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  1312. SmartcardExtension->ReaderCapabilities.MechProperties = 0;
  1313. // Reader capabilities (continue):
  1314. // - the default clock frequency (SC_IFD_DEFAULT_CLK_FREQUENCY)
  1315. // - the maximum clock frequency (SC_IFD_MAXIMUM_CLK_FREQUENCY)
  1316. // - the default data rate (SC_IFD_DEFAULT_DATA_RATE)
  1317. // - the maximum data rate (SC_IFD_MAXIMUM_DATA_RATE)
  1318. // - the maximum IFSD (SC_IFD_MAXIMUM_IFSD)
  1319. // - the power management is set to 0.
  1320. SmartcardExtension->ReaderCapabilities.CLKFrequency.Default =
  1321. SC_IFD_DEFAULT_CLK_FREQUENCY;
  1322. SmartcardExtension->ReaderCapabilities.CLKFrequency.Max =
  1323. SC_IFD_MAXIMUM_CLK_FREQUENCY;
  1324. SmartcardExtension->ReaderCapabilities.DataRate.Default =
  1325. SC_IFD_DEFAULT_DATA_RATE;
  1326. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  1327. SC_IFD_MAXIMUM_DATA_RATE;
  1328. SmartcardExtension->ReaderCapabilities.MaxIFSD =
  1329. SC_IFD_MAXIMUM_IFSD;
  1330. SmartcardExtension->ReaderCapabilities.PowerMgmtSupport = 0;
  1331. // Reader capabilities (continue):
  1332. // - List all the supported data rates
  1333. SmartcardExtension->ReaderCapabilities.DataRatesSupported.List =
  1334. dataRatesSupported;
  1335. SmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
  1336. sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
  1337. // Vendor Attributes:
  1338. // - the vendor information (SC_VENDOR_NAME)
  1339. strcpy(
  1340. SmartcardExtension->VendorAttr.VendorName.Buffer,
  1341. SC_VENDOR_NAME
  1342. );
  1343. SmartcardExtension->VendorAttr.VendorName.Length =
  1344. (USHORT) strlen(SmartcardExtension->VendorAttr.VendorName.Buffer);
  1345. // Vendor Attributes (continue):
  1346. // - the UnitNo information. Is set to the device number.
  1347. // - the IFD serial number (is set to a NULL string).
  1348. // - the IFD version is set.
  1349. strcpy(SmartcardExtension->VendorAttr.IfdType.Buffer,SC_IFD_TYPE);
  1350. SmartcardExtension->VendorAttr.IfdType.Length =
  1351. (USHORT) strlen(SmartcardExtension->VendorAttr.IfdType.Buffer);
  1352. SmartcardExtension->VendorAttr.UnitNo = DeviceNumber;
  1353. SmartcardExtension->VendorAttr.IfdSerialNo.Length = 0;
  1354. SmartcardExtension->VendorAttr.IfdVersion.VersionMajor = (UCHAR)majorVersion;
  1355. SmartcardExtension->VendorAttr.IfdVersion.VersionMinor = (UCHAR)minorVersion;
  1356. SmartcardExtension->VendorAttr.IfdVersion.BuildNumber = 0;
  1357. // Reader Extension:
  1358. // - the Handle of the reader.
  1359. // - the IFD number of the reader.
  1360. // - the ICCType (ISOCARD).
  1361. // - the ICCVpp (HOR3GLL_DEFAULT_VPP).
  1362. // - the ICCPresence.
  1363. // - the command timeout for the reader (HOR3GLL_DEFAULT_TIME).
  1364. // - the IFD baud rate.
  1365. // - the power timeout (0).
  1366. // - the selected VCC power supply voltage value.
  1367. // - the PTS negotiate mode.
  1368. // - the parameter PTS0.
  1369. // - the parameter PTS1.
  1370. // - the parameter PTS2.
  1371. // - the parameter PTS3.
  1372. SmartcardExtension->ReaderExtension->Handle = handle;
  1373. SmartcardExtension->ReaderExtension->APDUTimeOut = HOR3GLL_APDU_TIMEOUT;
  1374. SmartcardExtension->ReaderExtension->CmdTimeOut = HOR3GLL_DEFAULT_TIME;
  1375. SmartcardExtension->ReaderExtension->IFDBaudRate = br;
  1376. SmartcardExtension->ReaderExtension->PowerTimeOut = ICC_DEFAULT_POWER_TIMOUT;
  1377. SmartcardExtension->ReaderExtension->MaximalBaudRate = MaximalBaudRate;
  1378. SmartcardExtension->ReaderExtension->IccConfig.ICCType = ISOCARD;
  1379. SmartcardExtension->ReaderExtension->IccConfig.ICCVpp = HOR3GLL_DEFAULT_VPP;
  1380. SmartcardExtension->ReaderExtension->IccConfig.ICCVcc = ICC_VCC_5V;
  1381. SmartcardExtension->ReaderExtension->IccConfig.PTSMode = IFD_DEFAULT_MODE;
  1382. SmartcardExtension->ReaderExtension->IccConfig.PTS0 = 0;
  1383. SmartcardExtension->ReaderExtension->IccConfig.PTS1 = 0;
  1384. SmartcardExtension->ReaderExtension->IccConfig.PTS2 = 0;
  1385. SmartcardExtension->ReaderExtension->IccConfig.PTS3 = 0;
  1386. SmartcardExtension->ReaderExtension->IccConfig.ICCPresence = 0x0D;
  1387. // Define the type of the card (ISOCARD) and set the card presence
  1388. rlen = HOR3GLL_BUFFER_SIZE;
  1389. cmd[0] = HOR3GLL_IFD_CMD_ICC_DEFINE_TYPE;
  1390. cmd[1] = (BYTE) SmartcardExtension->ReaderExtension->IccConfig.ICCType;
  1391. cmd[2] = (BYTE) SmartcardExtension->ReaderExtension->IccConfig.ICCVpp;
  1392. cmd[3] = (BYTE) SmartcardExtension->ReaderExtension->IccConfig.ICCPresence ;
  1393. status = GDDK_Oros3Exchange(
  1394. handle,
  1395. HOR3GLL_LOW_TIME,
  1396. 4,
  1397. cmd,
  1398. &rlen,
  1399. rbuff
  1400. );
  1401. if (status == STATUS_SUCCESS) {
  1402. status = GDDK_Translate(rbuff[0],0);
  1403. }
  1404. if (status != STATUS_SUCCESS) {
  1405. GDDK_Oros3CloseComm(handle);
  1406. return(status);
  1407. }
  1408. // Update the status of the card
  1409. GDDK_0AUpdateCardStatus(SmartcardExtension);
  1410. return(STATUS_SUCCESS);
  1411. }
  1412. NTSTATUS
  1413. GDDK_0ACloseChannel(
  1414. PSMARTCARD_EXTENSION SmartcardExtension
  1415. )
  1416. /*++
  1417. Routine Description:
  1418. This routine close a conection previously opened with a reader.
  1419. Arguments:
  1420. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  1421. the current device.
  1422. Return Value:
  1423. STATUS_SUCCESS - We could execute the request.
  1424. --*/
  1425. {
  1426. READER_EXTENSION *param = SmartcardExtension->ReaderExtension;
  1427. USHORT rlen;
  1428. BYTE cmd[1],rbuff[HOR3GLL_BUFFER_SIZE];
  1429. // Call power down function:
  1430. rlen = HOR3GLL_BUFFER_SIZE;
  1431. cmd[0] = HOR3GLL_IFD_CMD_ICC_POWER_DOWN;
  1432. return(
  1433. GDDK_Oros3Exchange(
  1434. param->Handle,
  1435. HOR3GLL_LOW_TIME,
  1436. 1,
  1437. cmd,
  1438. &rlen,
  1439. rbuff
  1440. )
  1441. );
  1442. }
  1443. NTSTATUS
  1444. GDDK_0AUpdateCardStatus(
  1445. PSMARTCARD_EXTENSION pSmartcardExtension
  1446. )
  1447. /*++
  1448. Routine Description:
  1449. This function send a command to the reader to known the state of the card.
  1450. Arguments:
  1451. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  1452. the current device.
  1453. Return Value:
  1454. STATUS_SUCCESS - We could execute the request.
  1455. --*/
  1456. {
  1457. BYTE cmd[1];
  1458. READER_EXTENSION *param = pSmartcardExtension->ReaderExtension;
  1459. USHORT rlen;
  1460. BYTE rbuff[HOR3GLL_BUFFER_SIZE];
  1461. KIRQL irql;
  1462. NTSTATUS status;
  1463. // Read the status of the reader
  1464. cmd[0] = HOR3GLL_IFD_CMD_ICC_STATUS;
  1465. rlen = HOR3GLL_BUFFER_SIZE;
  1466. status = GDDK_Oros3Exchange(
  1467. param->Handle,
  1468. HOR3GLL_LOW_TIME,
  1469. (const USHORT)1,
  1470. (const BYTE *)cmd,
  1471. &rlen,
  1472. rbuff
  1473. );
  1474. if (status == STATUS_SUCCESS) {
  1475. status = GDDK_Translate(rbuff[0],0);
  1476. }
  1477. if (status != STATUS_SUCCESS) {
  1478. return status;
  1479. }
  1480. KeAcquireSpinLock(
  1481. &pSmartcardExtension->OsData->SpinLock,
  1482. &irql
  1483. );
  1484. if ((rbuff[1] & 0x04) == 0) {
  1485. // The card is absent
  1486. pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  1487. pSmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1488. pSmartcardExtension->CardCapabilities.ATR.Length = 0;
  1489. SmartcardDebug(
  1490. DEBUG_TRACE,
  1491. ("%s!GDDK_0AUpdateCardStatus: Card removed\n",
  1492. SC_DRIVER_NAME)
  1493. );
  1494. } else if ((rbuff[1] & 0x02) == 0) {
  1495. // The card is present
  1496. pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  1497. pSmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  1498. pSmartcardExtension->CardCapabilities.ATR.Length = 0;
  1499. SmartcardDebug(
  1500. DEBUG_TRACE,
  1501. ("%s!GDDK_0AUpdateCardStatus: Card inserted\n",
  1502. SC_DRIVER_NAME)
  1503. );
  1504. }
  1505. KeReleaseSpinLock(
  1506. &pSmartcardExtension->OsData->SpinLock,
  1507. irql
  1508. );
  1509. return status;
  1510. }
  1511. VOID
  1512. GDDK_0ALockExchange(
  1513. PSMARTCARD_EXTENSION SmartcardExtension
  1514. )
  1515. /*++
  1516. Routine Description:
  1517. Wait the release of the ExchangeMutex and take this.
  1518. Arguments:
  1519. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  1520. the current device.
  1521. Return Value:
  1522. STATUS_SUCCESS - We could execute the request.
  1523. --*/
  1524. {
  1525. KeWaitForMutexObject(
  1526. &SmartcardExtension->ReaderExtension->LongAPDUMutex,
  1527. Executive,
  1528. KernelMode,
  1529. FALSE,
  1530. NULL
  1531. );
  1532. }
  1533. VOID
  1534. GDDK_0AUnlockExchange(
  1535. PSMARTCARD_EXTENSION SmartcardExtension
  1536. )
  1537. /*++
  1538. Routine Description:
  1539. Release of the Exchange mutex.
  1540. Arguments:
  1541. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  1542. the current device.
  1543. --*/
  1544. {
  1545. KeReleaseMutex(
  1546. &SmartcardExtension->ReaderExtension->LongAPDUMutex,
  1547. FALSE
  1548. );
  1549. }
  1550. static VOID
  1551. GDDK_0ASetTransparentConfig(
  1552. PSMARTCARD_EXTENSION SmartcardExtension,
  1553. BYTE NewWtx
  1554. )
  1555. /*++
  1556. Routine Description:
  1557. Set the parameters of the transparent mode.
  1558. Arguments:
  1559. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  1560. the current device.
  1561. NewWtx - holds the value (ms) of the new Wtx
  1562. --*/
  1563. {
  1564. READER_EXTENSION *param = SmartcardExtension->ReaderExtension;
  1565. LONG etu;
  1566. BYTE temp,mask,index;
  1567. USHORT rlen;
  1568. BYTE cmd[6],rbuff[HOR3GLL_BUFFER_SIZE];
  1569. NTSTATUS status;
  1570. // Inverse or direct conversion
  1571. if (SmartcardExtension->CardCapabilities.InversConvention)
  1572. param->TransparentConfig.CFG |= 0x20;
  1573. else
  1574. param->TransparentConfig.CFG &= 0xDF;
  1575. // Transparent T=1 like (with 1 byte for the length).
  1576. param->TransparentConfig.CFG |= 0x08;
  1577. // ETU = ((F[Fi]/D[Di]) - 1) / 3
  1578. etu = SmartcardExtension->CardCapabilities.ClockRateConversion[
  1579. (BYTE) param->TransparentConfig.Fi].F;
  1580. if (SmartcardExtension->CardCapabilities.BitRateAdjustment[
  1581. (BYTE) param->TransparentConfig.Fi].DNumerator) {
  1582. etu /= SmartcardExtension->CardCapabilities.BitRateAdjustment[
  1583. (BYTE) param->TransparentConfig.Fi].DNumerator;
  1584. }
  1585. etu -= 1;
  1586. etu /= 3;
  1587. param->TransparentConfig.ETU = (BYTE) ( 0x000000FF & etu);
  1588. if (SmartcardExtension->CardCapabilities.N == 0xFF) {
  1589. param->TransparentConfig.EGT = (BYTE) 0x00;
  1590. } else {
  1591. param->TransparentConfig.EGT = (BYTE) SmartcardExtension->CardCapabilities.N;
  1592. }
  1593. param->TransparentConfig.CWT = (BYTE) SmartcardExtension->CardCapabilities.T1.CWI;
  1594. if (NewWtx) {
  1595. for (mask = 0x80,index = 8; index !=0x00; index--) {
  1596. temp = NewWtx & mask;
  1597. if (temp == mask)
  1598. break;
  1599. mask = mask/2;
  1600. }
  1601. param->TransparentConfig.BWI = SmartcardExtension->CardCapabilities.T1.BWI + index;
  1602. } else {
  1603. param->TransparentConfig.BWI = SmartcardExtension->CardCapabilities.T1.BWI;
  1604. }
  1605. // Now we send the configuration command
  1606. rlen = HOR3GLL_BUFFER_SIZE;
  1607. cmd[0] = HOR3GLL_IFD_CMD_TRANS_CONFIG;
  1608. cmd[1] = param->TransparentConfig.CFG;
  1609. cmd[2] = param->TransparentConfig.ETU;
  1610. cmd[3] = param->TransparentConfig.EGT;
  1611. cmd[4] = param->TransparentConfig.CWT;
  1612. cmd[5] = param->TransparentConfig.BWI;
  1613. status = GDDK_Oros3Exchange(
  1614. param->Handle,
  1615. HOR3GLL_LOW_TIME,
  1616. 6,
  1617. cmd,
  1618. &rlen,
  1619. rbuff
  1620. );
  1621. }
  1622. NTSTATUS
  1623. GDDK_0ARestoreCommunication(
  1624. PSMARTCARD_EXTENSION SmartcardExtension
  1625. )
  1626. /*++
  1627. Routine Description:
  1628. Restore the communication with the reader at the good speed.
  1629. Arguments:
  1630. SmartcardExtension - is a pointer on the SmartCardExtension structure of
  1631. the current device.
  1632. --*/
  1633. {
  1634. TGTSER_PORT comm;
  1635. BYTE cmd[10],rbuff[HOR3GLL_BUFFER_SIZE];
  1636. USHORT user,rlen;
  1637. ULONG br;
  1638. SHORT portcom;
  1639. KEVENT event;
  1640. LARGE_INTEGER timeout;
  1641. NTSTATUS status;
  1642. READER_EXTENSION *param = SmartcardExtension->ReaderExtension;
  1643. // Loop while a right response has not been received. We start at 9600
  1644. status = GDDK_GBPChannelToPortComm(param->Handle,&portcom);
  1645. if (status != STATUS_SUCCESS) {
  1646. return status;
  1647. }
  1648. status = GDDK_SerPortGetState(portcom,&comm,&user);
  1649. if (status != STATUS_SUCCESS) {
  1650. return status;
  1651. }
  1652. comm.BaudRate = 9600;
  1653. GDDK_SerPortSetState(portcom,&comm);
  1654. GDDK_0ALockExchange(SmartcardExtension);
  1655. __try {
  1656. do {
  1657. // Wait for HOR3COMM_CHAR_TIME ms before any command for IFD to forget any
  1658. // previous received byte.
  1659. KeInitializeEvent(&event,NotificationEvent,FALSE);
  1660. timeout.QuadPart = -((LONGLONG) HOR3COMM_CHAR_TIME*10*1000);
  1661. KeWaitForSingleObject(
  1662. &event,
  1663. Suspended,
  1664. KernelMode,
  1665. FALSE,
  1666. &timeout
  1667. );
  1668. SmartcardDebug(
  1669. DEBUG_TRACE,
  1670. ("%s!GDDK_0ARestoreCommunication: Try at baud rate = %d\n",
  1671. SC_DRIVER_NAME,
  1672. comm.BaudRate)
  1673. );
  1674. // Define the type of the card (ISOCARD) and set the card presence
  1675. rlen = HOR3GLL_BUFFER_SIZE;
  1676. SmartcardExtension->ReaderExtension->IccConfig.ICCType = ISOCARD;
  1677. cmd[0] = HOR3GLL_IFD_CMD_ICC_DEFINE_TYPE;
  1678. cmd[1] = (BYTE) SmartcardExtension->ReaderExtension->IccConfig.ICCType;
  1679. cmd[2] = (BYTE) SmartcardExtension->ReaderExtension->IccConfig.ICCVpp;
  1680. cmd[3] = (BYTE) SmartcardExtension->ReaderExtension->IccConfig.ICCPresence ;
  1681. status = GDDK_Oros3Exchange(
  1682. param->Handle,
  1683. HOR3GLL_LOW_TIME,
  1684. 4,
  1685. cmd,
  1686. &rlen,
  1687. rbuff
  1688. );
  1689. if (status != STATUS_SUCCESS) {
  1690. if (comm.BaudRate == 9600lu) {
  1691. comm.BaudRate = 38400lu;
  1692. } else if (comm.BaudRate == 38400lu) {
  1693. comm.BaudRate = 19200lu;
  1694. } else {
  1695. status = STATUS_INVALID_DEVICE_STATE;
  1696. __leave;
  1697. }
  1698. // The new baud rate configuration is set.
  1699. GDDK_SerPortSetState(portcom,&comm);
  1700. } else {
  1701. break;
  1702. }
  1703. } while (status != STATUS_SUCCESS);
  1704. SmartcardDebug(
  1705. DEBUG_ERROR,
  1706. ("%s!GDDK_0ARestoreCommunication: Baud rate = %d\n",
  1707. SC_DRIVER_NAME,
  1708. comm.BaudRate)
  1709. );
  1710. // Optimizes the baudrate:
  1711. if(param->MaximalBaudRate > comm.BaudRate) {
  1712. br = comm.BaudRate;
  1713. for(;br < param->MaximalBaudRate;) {
  1714. br = br * 2;
  1715. // The reader is switched to the selected value (GDDK_Oros3SIOConfigure). The
  1716. // function status is not tested because, as the IFD has switched
  1717. // immediatly, it is not possible to read its response.
  1718. SmartcardDebug(
  1719. DEBUG_TRACE,
  1720. ("%s!GDDK_0ARestoreCommunication: Optimize baud rate = %d\n",
  1721. SC_DRIVER_NAME,
  1722. comm.BaudRate)
  1723. );
  1724. comm.BaudRate = br;
  1725. rlen = 0;
  1726. GDDK_Oros3SIOConfigure(
  1727. param->Handle,
  1728. HOR3GLL_LOW_TIME,
  1729. 0,
  1730. 8,
  1731. comm.BaudRate,
  1732. &rlen,
  1733. rbuff,
  1734. FALSE
  1735. );
  1736. //
  1737. // Waits for the fisrt command is process by the reader
  1738. // 500 ms is enought
  1739. //
  1740. KeInitializeEvent(&event,NotificationEvent,FALSE);
  1741. timeout.QuadPart = -((LONGLONG) 500 * 1000);
  1742. KeWaitForSingleObject(&event,
  1743. Suspended,
  1744. KernelMode,
  1745. FALSE,
  1746. &timeout);
  1747. // Host is switched to the selected value (GDDK_SerPortSetState).
  1748. // If this call is successful,
  1749. // Then
  1750. // The last command is re-sent to read the IFD response.
  1751. // response is optionnaly initialized with the translated IFD status.
  1752. status = GDDK_SerPortSetState(portcom,&comm);
  1753. SmartcardDebug(
  1754. DEBUG_TRACE,
  1755. ("%s!GDDK_0ARestoreCommunication: Set baud rate = %d\n",
  1756. SC_DRIVER_NAME,
  1757. comm.BaudRate)
  1758. );
  1759. if (status == STATUS_SUCCESS) {
  1760. rlen = HOR3GLL_BUFFER_SIZE;
  1761. status = GDDK_Oros3SIOConfigure(
  1762. param->Handle,
  1763. HOR3GLL_LOW_TIME,
  1764. 0,
  1765. 8,
  1766. comm.BaudRate,
  1767. &rlen,
  1768. rbuff,
  1769. TRUE
  1770. );
  1771. if (status == STATUS_SUCCESS) {
  1772. status = GDDK_Translate(rbuff[0],0);
  1773. }
  1774. if (status != STATUS_SUCCESS) {
  1775. break;
  1776. }
  1777. }
  1778. }
  1779. if ((br > 38400) || (status != STATUS_SUCCESS)) {
  1780. status = STATUS_INVALID_DEVICE_STATE;
  1781. __leave;
  1782. }
  1783. }
  1784. SmartcardDebug(
  1785. DEBUG_TRACE,
  1786. ("%s!GDDK_0ARestoreCommunication: Current baud rate = %d\n",
  1787. SC_DRIVER_NAME,
  1788. comm.BaudRate)
  1789. );
  1790. // Send the SetMode command with parameter 0 to disable TLP compatibility.
  1791. rlen = HOR3GLL_BUFFER_SIZE;
  1792. cmd[0] = (BYTE) HOR3GLL_IFD_CMD_MODE_SET;
  1793. cmd[1] = (BYTE) 0x00;
  1794. cmd[2] = (BYTE) 0x00;
  1795. status = GDDK_Oros3Exchange(
  1796. param->Handle,
  1797. HOR3GLL_LOW_TIME,
  1798. 3,
  1799. cmd,
  1800. &rlen,
  1801. rbuff
  1802. );
  1803. if (status != STATUS_SUCCESS) {
  1804. __leave;
  1805. }
  1806. // Update the status of the card
  1807. GDDK_0AUpdateCardStatus(SmartcardExtension);
  1808. }
  1809. __finally {
  1810. if (status != STATUS_SUCCESS) {
  1811. SmartcardDebug(
  1812. DEBUG_ERROR,
  1813. ("%s!GDDK_0ARestoreCommunication: Failed\n",
  1814. SC_DRIVER_NAME,
  1815. comm.BaudRate)
  1816. );
  1817. }
  1818. }
  1819. GDDK_0AUnlockExchange(SmartcardExtension);
  1820. SmartcardDebug(
  1821. DEBUG_TRACE,
  1822. ("%s!GDDK_0ARestoreCommunication: Exit=%X(hex)\n",
  1823. SC_DRIVER_NAME,
  1824. status)
  1825. );
  1826. return status;
  1827. }