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

1711 lines
55 KiB

  1. /*++
  2. Copyright (C) 1997, 98 Microsoft Corporation
  3. Module Name:
  4. tlp3cb.c
  5. Abstract:
  6. Callback functions for smart card library
  7. Author:
  8. Klaus U. Schutz
  9. Environment:
  10. Kernel mode
  11. --*/
  12. #include <stdio.h>
  13. #include "bulltlp3.h"
  14. #pragma alloc_text(PAGEABLE, TLP3TransmitT0)
  15. #pragma alloc_text(PAGEABLE, TLP3Transmit)
  16. #pragma alloc_text(PAGEABLE, TLP3VendorIoctl)
  17. NTSTATUS
  18. TLP3ReaderPower(
  19. PSMARTCARD_EXTENSION SmartcardExtension
  20. )
  21. /*++
  22. Routine Description:
  23. The smart card lib requires to have this function. It is called
  24. for certain power requests to the card. We do nothing here, because
  25. this action is performed in the StartIo function.
  26. --*/
  27. {
  28. ULONG step, waitTime, TdIndex, numTry = 0, minWaitTime;
  29. NTSTATUS status = STATUS_SUCCESS;
  30. PSERIAL_STATUS serialStatus;
  31. KIRQL oldIrql, irql;
  32. PUCHAR requestBuffer;
  33. PSERIAL_READER_CONFIG serialConfigData =
  34. &SmartcardExtension->ReaderExtension->SerialConfigData;
  35. SmartcardDebug(
  36. DEBUG_TRACE,
  37. ("%s!TLP3ReaderPower: Enter (%lx)\n",
  38. DRIVER_NAME,
  39. SmartcardExtension->MinorIoControlCode)
  40. );
  41. _try {
  42. #if defined (DEBUG) && defined (DETECT_SERIAL_OVERRUNS)
  43. // we have to call GetCommStatus to reset the error condition
  44. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  45. IOCTL_SERIAL_GET_COMMSTATUS;
  46. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  47. SmartcardExtension->SmartcardReply.BufferLength =
  48. sizeof(SERIAL_STATUS);
  49. status = TLP3SerialIo(SmartcardExtension);
  50. ASSERT(status == STATUS_SUCCESS);
  51. #endif
  52. //
  53. // Set standard parameters for serial port
  54. //
  55. serialConfigData->LineControl.Parity = EVEN_PARITY;
  56. serialConfigData->LineControl.StopBits = STOP_BITS_2;
  57. serialConfigData->BaudRate.BaudRate =
  58. SmartcardExtension->ReaderCapabilities.DataRate.Default;
  59. // we set very short timeouts to get the ATR as fast as possible
  60. serialConfigData->Timeouts.ReadIntervalTimeout =
  61. READ_INTERVAL_TIMEOUT_ATR;
  62. serialConfigData->Timeouts.ReadTotalTimeoutConstant =
  63. READ_TOTAL_TIMEOUT_CONSTANT_ATR;
  64. status = TLP3ConfigureSerialPort(SmartcardExtension);
  65. ASSERT(status == STATUS_SUCCESS);
  66. if (status != STATUS_SUCCESS) {
  67. leave;
  68. }
  69. // We don't send data to the reader, so set Number of bytes to send = 0
  70. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  71. // Default number of bytes we expect to get back
  72. SmartcardExtension->SmartcardReply.BufferLength = 0;
  73. //
  74. // Since power down triggers the UpdateSerialStatus function, we have
  75. // to inform it that we forced the change of the status and not the user
  76. // (who might have removed and inserted a card)
  77. //
  78. // SmartcardExtension->ReaderExtension->PowerRequest = TRUE;
  79. // purge the serial buffer (it can contain the pnp id of the reader)
  80. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  81. IOCTL_SERIAL_PURGE;
  82. *(PULONG) SmartcardExtension->SmartcardRequest.Buffer =
  83. SERIAL_PURGE_RXCLEAR | SERIAL_PURGE_TXCLEAR;;
  84. SmartcardExtension->SmartcardRequest.BufferLength =
  85. sizeof(ULONG);
  86. status = TLP3SerialIo(SmartcardExtension);
  87. ASSERT(status == STATUS_SUCCESS);
  88. if (status != STATUS_SUCCESS) {
  89. leave;
  90. }
  91. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  92. for (step = 0; NT_SUCCESS(status); step++) {
  93. if (SmartcardExtension->MinorIoControlCode ==
  94. SCARD_WARM_RESET &&
  95. step == 0) {
  96. step = 4;
  97. }
  98. switch (step) {
  99. case 0:
  100. // RTS = 0 means reader is in command mode
  101. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  102. IOCTL_SERIAL_CLR_RTS;
  103. //
  104. // This is the minimum wait time we have to wait before
  105. // we can send commands to the microcontroller.
  106. //
  107. waitTime = 1000;
  108. break;
  109. case 1:
  110. // write power down command to the reader
  111. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  112. SMARTCARD_WRITE;
  113. SmartcardExtension->SmartcardRequest.BufferLength = 1;
  114. SmartcardExtension->SmartcardRequest.Buffer[0] =
  115. READER_CMD_POWER_DOWN;
  116. waitTime = 100;
  117. break;
  118. case 2:
  119. // Read back the echo of the reader
  120. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  121. SMARTCARD_READ;
  122. SmartcardExtension->SmartcardReply.BufferLength = 1;
  123. // Wait the recovery time for the microcontroller
  124. waitTime = 1000;
  125. break;
  126. case 3:
  127. // set RTS again so the microcontroller can execute the command
  128. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  129. IOCTL_SERIAL_SET_RTS;
  130. waitTime = 10000;
  131. break;
  132. case 4:
  133. if (SmartcardExtension->MinorIoControlCode == SCARD_POWER_DOWN) {
  134. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  135. &irql);
  136. if (SmartcardExtension->ReaderCapabilities.CurrentState >
  137. SCARD_PRESENT) {
  138. SmartcardExtension->ReaderCapabilities.CurrentState =
  139. SCARD_PRESENT;
  140. }
  141. SmartcardExtension->CardCapabilities.Protocol.Selected =
  142. SCARD_PROTOCOL_UNDEFINED;
  143. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  144. irql);
  145. status = STATUS_SUCCESS;
  146. leave;
  147. }
  148. // clear RTS to switch to command mode
  149. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  150. IOCTL_SERIAL_CLR_RTS;
  151. // Wait the recovery time for the microcontroller
  152. waitTime = 1000;
  153. break;
  154. case 5:
  155. // write the appropriate reset command to the reader
  156. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  157. SMARTCARD_WRITE;
  158. SmartcardExtension->SmartcardRequest.BufferLength = 1;
  159. switch (SmartcardExtension->MinorIoControlCode) {
  160. case SCARD_COLD_RESET:
  161. SmartcardExtension->SmartcardRequest.Buffer[0] =
  162. READER_CMD_COLD_RESET;
  163. break;
  164. case SCARD_WARM_RESET:
  165. SmartcardExtension->SmartcardRequest.Buffer[0] =
  166. READER_CMD_WARM_RESET;
  167. break;
  168. }
  169. waitTime = 100;
  170. break;
  171. case 6:
  172. // Read back the echo of the reader
  173. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  174. SMARTCARD_READ;
  175. SmartcardExtension->SmartcardReply.BufferLength = 1;
  176. //
  177. // This is the time we need to wait for the microcontroller
  178. // to recover before we can set RTS again
  179. //
  180. waitTime = 1000;
  181. break;
  182. case 7:
  183. // set RTS again so the microcontroller can execute the command
  184. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  185. IOCTL_SERIAL_SET_RTS;
  186. waitTime = 10000;
  187. break;
  188. case 8:
  189. //
  190. // We now try to get the ATR as fast as possible.
  191. // Therefor we prev. set a very short read timeout and
  192. // 'hope' that the card delivered its ATR within this
  193. // short time. To verify the correctness of the ATR we call
  194. // SmartcardUpdateCardCapabilities(). If this call returns
  195. // with STATUS_SUCCESS we know that the ATR is complete.
  196. // Otherwise we read again and append the new data to the
  197. // ATR buffer in the CardCapabilities and try again.
  198. //
  199. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  200. SMARTCARD_READ;
  201. SmartcardExtension->SmartcardReply.BufferLength =
  202. MAXIMUM_ATR_LENGTH -
  203. SmartcardExtension->CardCapabilities.ATR.Length;
  204. waitTime = 0;
  205. break;
  206. case 9:
  207. if (SmartcardExtension->SmartcardReply.BufferLength != 0) {
  208. ASSERT(
  209. SmartcardExtension->CardCapabilities.ATR.Length +
  210. SmartcardExtension->SmartcardReply.BufferLength <
  211. MAXIMUM_ATR_LENGTH
  212. );
  213. if( SmartcardExtension->CardCapabilities.ATR.Length +
  214. SmartcardExtension->SmartcardReply.BufferLength >=
  215. MAXIMUM_ATR_LENGTH) {
  216. status = STATUS_UNRECOGNIZED_MEDIA;
  217. leave;
  218. }
  219. // we got some ATR bytes.
  220. RtlCopyMemory(
  221. SmartcardExtension->CardCapabilities.ATR.Buffer +
  222. SmartcardExtension->CardCapabilities.ATR.Length,
  223. SmartcardExtension->SmartcardReply.Buffer,
  224. SmartcardExtension->SmartcardReply.BufferLength
  225. );
  226. SmartcardExtension->CardCapabilities.ATR.Length +=
  227. (UCHAR) SmartcardExtension->SmartcardReply.BufferLength;
  228. status = SmartcardUpdateCardCapabilities(
  229. SmartcardExtension
  230. );
  231. }
  232. if (status != STATUS_SUCCESS && numTry < 25) {
  233. if (SmartcardExtension->SmartcardReply.BufferLength != 0) {
  234. // Because we received some data, we reset our counter
  235. numTry = 0;
  236. } else {
  237. // ATR is incomplete. Try again to get ATR bytes.
  238. numTry += 1;
  239. }
  240. // continue with step 8
  241. step = 7;
  242. status = STATUS_TIMEOUT;
  243. continue;
  244. }
  245. if (status != STATUS_SUCCESS) {
  246. leave;
  247. }
  248. // No break
  249. case 10:
  250. KeAcquireSpinLock(
  251. &SmartcardExtension->OsData->SpinLock,
  252. &oldIrql
  253. );
  254. if (SmartcardExtension->ReaderCapabilities.CurrentState <=
  255. SCARD_ABSENT) {
  256. status = STATUS_MEDIA_CHANGED;
  257. }
  258. KeReleaseSpinLock(
  259. &SmartcardExtension->OsData->SpinLock,
  260. oldIrql
  261. );
  262. if (status != STATUS_SUCCESS) {
  263. leave;
  264. }
  265. #ifdef SIMULATION
  266. if (SmartcardExtension->ReaderExtension->SimulationLevel &
  267. SIM_ATR_TRASH) {
  268. ULONG index;
  269. LARGE_INTEGER tickCount;
  270. KeQueryTickCount(
  271. &tickCount
  272. );
  273. SmartcardExtension->CardCapabilities.ATR.Length =
  274. (UCHAR) tickCount.LowPart % MAXIMUM_ATR_LENGTH;
  275. for (index = 0;
  276. index < SmartcardExtension->CardCapabilities.ATR.Length;
  277. index++) {
  278. SmartcardExtension->CardCapabilities.ATR.Buffer[index] *=
  279. (UCHAR) tickCount.LowPart;
  280. }
  281. SmartcardDebug(
  282. DEBUG_SIMULATION,
  283. ("%s!TLP3ReaderPower: SIM ATR trash\n",
  284. DRIVER_NAME)
  285. );
  286. }
  287. #endif
  288. // Copy ATR to user space
  289. if (SmartcardExtension->IoRequest.ReplyBuffer) {
  290. RtlCopyMemory(
  291. SmartcardExtension->IoRequest.ReplyBuffer,
  292. SmartcardExtension->CardCapabilities.ATR.Buffer,
  293. SmartcardExtension->CardCapabilities.ATR.Length
  294. );
  295. // Tell user length of ATR
  296. *SmartcardExtension->IoRequest.Information =
  297. SmartcardExtension->CardCapabilities.ATR.Length;
  298. }
  299. //
  300. // If the card uses invers convention we need to switch
  301. // the serial driver to odd paritiy
  302. //
  303. if (SmartcardExtension->CardCapabilities.InversConvention) {
  304. serialConfigData->LineControl.Parity = ODD_PARITY;
  305. }
  306. //
  307. // If the extra guard time is 255 it means that our
  308. // frame we have to expect from the card has only
  309. // 1 instead of 2 stop bits
  310. // 1start bit + 8data bits + 1parity + 1stop == 11 etu
  311. // see iso 7816-3 6.1.4.4 Extra Guard Time N
  312. //
  313. if (SmartcardExtension->CardCapabilities.PtsData.StopBits == 1) {
  314. serialConfigData->LineControl.StopBits = STOP_BIT_1;
  315. }
  316. // Change data rate according to the new settings
  317. serialConfigData->BaudRate.BaudRate =
  318. SmartcardExtension->CardCapabilities.PtsData.DataRate;
  319. // depending on the protocol set the timeout values
  320. if (SmartcardExtension->CardCapabilities.Protocol.Selected &
  321. SCARD_PROTOCOL_T1) {
  322. // set timeouts
  323. serialConfigData->Timeouts.ReadTotalTimeoutConstant =
  324. SmartcardExtension->CardCapabilities.T1.BWT / 1000;
  325. serialConfigData->Timeouts.ReadIntervalTimeout =
  326. SmartcardExtension->CardCapabilities.T1.CWT / 1000;
  327. } else if (SmartcardExtension->CardCapabilities.Protocol.Selected &
  328. SCARD_PROTOCOL_T0) {
  329. // set timeouts
  330. serialConfigData->Timeouts.ReadTotalTimeoutConstant =
  331. serialConfigData->Timeouts.ReadIntervalTimeout =
  332. SmartcardExtension->CardCapabilities.T0.WT / 1000;
  333. }
  334. // Now make some adjustments depending on the system speed
  335. minWaitTime = (KeQueryTimeIncrement() / 10000) * 5;
  336. if (serialConfigData->Timeouts.ReadTotalTimeoutConstant <
  337. minWaitTime) {
  338. serialConfigData->Timeouts.ReadTotalTimeoutConstant =
  339. minWaitTime;
  340. }
  341. if (serialConfigData->Timeouts.ReadIntervalTimeout <
  342. minWaitTime) {
  343. serialConfigData->Timeouts.ReadIntervalTimeout =
  344. minWaitTime;
  345. }
  346. status = TLP3ConfigureSerialPort(SmartcardExtension);
  347. ASSERT(status == STATUS_SUCCESS);
  348. // We're done anyway, so leave
  349. leave;
  350. }
  351. status = TLP3SerialIo(SmartcardExtension);
  352. if (!NT_SUCCESS(status)) {
  353. leave;
  354. }
  355. if (waitTime) {
  356. LARGE_INTEGER delayPeriod;
  357. delayPeriod.HighPart = -1;
  358. delayPeriod.LowPart = waitTime * (-10);
  359. KeDelayExecutionThread(
  360. KernelMode,
  361. FALSE,
  362. &delayPeriod
  363. );
  364. }
  365. }
  366. }
  367. _finally {
  368. if (status == STATUS_TIMEOUT) {
  369. status = STATUS_UNRECOGNIZED_MEDIA;
  370. }
  371. SmartcardExtension->ReaderExtension->PowerRequest = FALSE;
  372. #ifdef SIMULATION
  373. if (SmartcardExtension->ReaderExtension->SimulationLevel &
  374. SIM_WRONG_STATE) {
  375. // inject a wrong state after warm/cold reset
  376. SmartcardExtension->ReaderCapabilities.CurrentState =
  377. SCARD_PRESENT;
  378. SmartcardDebug(
  379. DEBUG_SIMULATION,
  380. ("%s!TLP3ReaderPower: SIM wrong state\n",
  381. DRIVER_NAME)
  382. );
  383. } else if (SmartcardExtension->ReaderExtension->SimulationLevel &
  384. SIM_INVALID_STATE) {
  385. // inject completely invalid state after reset.
  386. LARGE_INTEGER tickCount;
  387. KeQueryTickCount(
  388. &tickCount
  389. );
  390. SmartcardExtension->ReaderCapabilities.CurrentState =
  391. (UCHAR) tickCount.LowPart;
  392. SmartcardDebug(
  393. DEBUG_SIMULATION,
  394. ("%s!TLP3ReaderPower: SIM invalid state %ls\n",
  395. DRIVER_NAME,
  396. SmartcardExtension->ReaderCapabilities.CurrentState)
  397. );
  398. }
  399. if (SmartcardExtension->ReaderExtension->SimulationLevel &
  400. SIM_LONG_RESET_TIMEOUT) {
  401. // inject a random timeout of max 60 sec.
  402. LARGE_INTEGER tickCount;
  403. KeQueryTickCount(
  404. &tickCount
  405. );
  406. tickCount.LowPart %= 60;
  407. SmartcardDebug(
  408. DEBUG_SIMULATION,
  409. ("%s!TLP3ReaderPower: SIM reset wait %ld\n",
  410. DRIVER_NAME,
  411. tickCount.LowPart)
  412. );
  413. tickCount.QuadPart *= -10000000;
  414. KeDelayExecutionThread(
  415. KernelMode,
  416. FALSE,
  417. &tickCount
  418. );
  419. }
  420. #endif
  421. }
  422. SmartcardDebug(
  423. DEBUG_TRACE,
  424. ("%s!TLP3ReaderPower: Exit (%lx)\n",
  425. DRIVER_NAME,
  426. status)
  427. );
  428. return status;
  429. }
  430. NTSTATUS
  431. TLP3SetProtocol(
  432. PSMARTCARD_EXTENSION SmartcardExtension
  433. )
  434. /*++
  435. Routine Description:
  436. The smart card lib requires to have this function. It is called
  437. to set a the transmission protocol and parameters. If this function
  438. is called with a protocol mask (which means the caller doesn't card
  439. about a particular protocol to be set) we first look if we can
  440. set T=1 and the T=0
  441. Arguments:
  442. SmartcardExtension - Pointer to smart card data struct.
  443. Return Value:
  444. NTSTATUS
  445. --*/
  446. {
  447. NTSTATUS status;
  448. KIRQL irql;
  449. PAGED_CODE();
  450. SmartcardDebug(
  451. DEBUG_TRACE,
  452. ("%s!TLP3SetProtocol: Enter\n",
  453. DRIVER_NAME)
  454. );
  455. try {
  456. PUCHAR ptsRequest = SmartcardExtension->SmartcardRequest.Buffer;
  457. PUCHAR ptsReply = SmartcardExtension->SmartcardReply.Buffer;
  458. PSERIAL_READER_CONFIG serialConfigData =
  459. &SmartcardExtension->ReaderExtension->SerialConfigData;
  460. ULONG minWaitTime, newProtocol;
  461. //
  462. // Check if the card is already in specific state
  463. // and if the caller wants to have the already selected protocol.
  464. // We return success if this is the case.
  465. //
  466. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  467. &irql);
  468. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC &&
  469. (SmartcardExtension->CardCapabilities.Protocol.Selected &
  470. SmartcardExtension->MinorIoControlCode)) {
  471. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  472. irql);
  473. status = STATUS_SUCCESS;
  474. leave;
  475. }
  476. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  477. irql);
  478. // set normal timeout
  479. serialConfigData->Timeouts.ReadIntervalTimeout =
  480. READ_INTERVAL_TIMEOUT_DEFAULT;
  481. serialConfigData->Timeouts.ReadTotalTimeoutConstant =
  482. READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;
  483. status = TLP3ConfigureSerialPort(SmartcardExtension);
  484. ASSERT(status == STATUS_SUCCESS);
  485. if (status != STATUS_SUCCESS) {
  486. leave;
  487. }
  488. //
  489. // Assemble and send a pts selection
  490. //
  491. newProtocol = SmartcardExtension->MinorIoControlCode;
  492. while(TRUE) {
  493. // set initial character of PTS
  494. ptsRequest[0] = 0xff;
  495. // set the format character
  496. if (SmartcardExtension->CardCapabilities.Protocol.Supported &
  497. newProtocol &
  498. SCARD_PROTOCOL_T1) {
  499. // select T=1 and indicate that pts1 follows
  500. ptsRequest[1] = 0x11;
  501. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;
  502. } else if (SmartcardExtension->CardCapabilities.Protocol.Supported &
  503. newProtocol &
  504. SCARD_PROTOCOL_T0) {
  505. // select T=0 and indicate that pts1 follows
  506. ptsRequest[1] = 0x10;
  507. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  508. } else {
  509. status = STATUS_INVALID_DEVICE_REQUEST;
  510. leave;
  511. }
  512. // set pts1 which codes Fl and Dl
  513. ptsRequest[2] =
  514. SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
  515. SmartcardExtension->CardCapabilities.PtsData.Dl;
  516. // set pck (check character)
  517. ptsRequest[3] = ptsRequest[0] ^ ptsRequest[1] ^ ptsRequest[2];
  518. SmartcardExtension->SmartcardRequest.BufferLength = 4;
  519. SmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_WRITE;
  520. status = TLP3SerialIo(SmartcardExtension);
  521. if (status != STATUS_SUCCESS) {
  522. leave;
  523. }
  524. // read back the echo of the reader
  525. SmartcardExtension->SmartcardReply.BufferLength = 4;
  526. SmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_READ;
  527. status = TLP3SerialIo(SmartcardExtension);
  528. if (status != STATUS_SUCCESS) {
  529. leave;
  530. }
  531. // read back the pts data
  532. status = TLP3SerialIo(SmartcardExtension);
  533. if (status != STATUS_SUCCESS &&
  534. status != STATUS_TIMEOUT) {
  535. leave;
  536. }
  537. if (status != STATUS_TIMEOUT &&
  538. memcmp(ptsRequest, ptsReply, 4) == 0) {
  539. // the card replied correctly to our pts-request
  540. break;
  541. }
  542. if (SmartcardExtension->CardCapabilities.PtsData.Type !=
  543. PTS_TYPE_DEFAULT) {
  544. SmartcardDebug(
  545. DEBUG_TRACE,
  546. ("%s!TLP3SetProtocol: PTS failed. Trying default parameters...\n",
  547. DRIVER_NAME,
  548. status)
  549. );
  550. //
  551. // The card did either NOT reply or it replied incorrectly
  552. // so try default values
  553. //
  554. SmartcardExtension->CardCapabilities.PtsData.Type =
  555. PTS_TYPE_DEFAULT;
  556. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  557. &irql);
  558. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  559. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  560. irql);
  561. status = TLP3ReaderPower(SmartcardExtension);
  562. continue;
  563. }
  564. // the card failed the pts-request
  565. status = STATUS_DEVICE_PROTOCOL_ERROR;
  566. leave;
  567. }
  568. //
  569. // The card replied correctly to the pts request
  570. // Set the appropriate parameters for the port
  571. //
  572. if (SmartcardExtension->CardCapabilities.Protocol.Selected &
  573. SCARD_PROTOCOL_T1) {
  574. // set timeouts
  575. serialConfigData->Timeouts.ReadTotalTimeoutConstant =
  576. SmartcardExtension->CardCapabilities.T1.BWT / 1000;
  577. serialConfigData->Timeouts.ReadIntervalTimeout =
  578. SmartcardExtension->CardCapabilities.T1.CWT / 1000;
  579. } else if (SmartcardExtension->CardCapabilities.Protocol.Selected &
  580. SCARD_PROTOCOL_T0) {
  581. // set timeouts
  582. serialConfigData->Timeouts.ReadTotalTimeoutConstant =
  583. serialConfigData->Timeouts.ReadIntervalTimeout =
  584. SmartcardExtension->CardCapabilities.T0.WT / 1000;
  585. }
  586. // Now make some adjustments depending on the system speed
  587. minWaitTime = (KeQueryTimeIncrement() / 10000) * 5;
  588. if (serialConfigData->Timeouts.ReadTotalTimeoutConstant < minWaitTime) {
  589. serialConfigData->Timeouts.ReadTotalTimeoutConstant = minWaitTime;
  590. }
  591. if (serialConfigData->Timeouts.ReadIntervalTimeout < minWaitTime) {
  592. serialConfigData->Timeouts.ReadIntervalTimeout = minWaitTime;
  593. }
  594. // Change data rate according to the new settings
  595. serialConfigData->BaudRate.BaudRate =
  596. SmartcardExtension->CardCapabilities.PtsData.DataRate;
  597. status = TLP3ConfigureSerialPort(SmartcardExtension);
  598. ASSERT(status == STATUS_SUCCESS);
  599. // now indicate that we're in specific mode
  600. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  601. // return the selected protocol to the caller
  602. *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer =
  603. SmartcardExtension->CardCapabilities.Protocol.Selected;
  604. *SmartcardExtension->IoRequest.Information =
  605. sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
  606. }
  607. finally {
  608. if (status == STATUS_TIMEOUT) {
  609. // STATUS_TIMEOUT is not mapped to a Win32 error code
  610. status = STATUS_IO_TIMEOUT;
  611. *SmartcardExtension->IoRequest.Information = 0;
  612. } else if (status != STATUS_SUCCESS) {
  613. SmartcardExtension->CardCapabilities.Protocol.Selected =
  614. SCARD_PROTOCOL_UNDEFINED;
  615. *SmartcardExtension->IoRequest.Information = 0;
  616. }
  617. }
  618. SmartcardDebug(
  619. DEBUG_TRACE,
  620. ("%s!TLP3SetProtocol: Exit(%lx)\n",
  621. DRIVER_NAME,
  622. status)
  623. );
  624. return status;
  625. }
  626. NTSTATUS
  627. TLP3TransmitT0(
  628. PSMARTCARD_EXTENSION SmartcardExtension
  629. )
  630. /*++
  631. Routine Description:
  632. This function performs a T=0 transmission.
  633. Arguments:
  634. SmartcardExtension - Pointer to smart card data struct.
  635. Return Value:
  636. NTSTATUS
  637. --*/
  638. {
  639. PUCHAR requestBuffer = SmartcardExtension->SmartcardRequest.Buffer;
  640. PUCHAR replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
  641. PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
  642. PULONG replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
  643. PULONG serialIoControlCode = &SmartcardExtension->ReaderExtension->SerialIoControlCode;
  644. ULONG bytesToSend, bytesToRead, currentByte = 0;
  645. BOOLEAN restartWorkWaitingTime = FALSE;
  646. NTSTATUS status;
  647. PAGED_CODE();
  648. SmartcardDebug(
  649. DEBUG_TRACE,
  650. ("%s!TLP3TransmitT0: Enter\n",
  651. DRIVER_NAME)
  652. );
  653. try {
  654. // Let the lib build a T=0 packet
  655. status = SmartcardT0Request(SmartcardExtension);
  656. if (status != STATUS_SUCCESS)
  657. leave;
  658. //
  659. // The number of bytes we expect from the card
  660. // is Le + 2 status bytes
  661. //
  662. bytesToSend = *requestLength;
  663. bytesToRead = SmartcardExtension->T0.Le + 2;
  664. //
  665. // Send the first 5 bytes to the card
  666. //
  667. *requestLength = 5;
  668. do {
  669. UCHAR procByte;
  670. //
  671. // According to ISO 7816 a procedure byte of
  672. // 60 should be treated as a request for a one time wait.
  673. // In this case we do not write anything to the card
  674. //
  675. if (restartWorkWaitingTime == FALSE) {
  676. SmartcardDebug(
  677. DEBUG_PROTOCOL,
  678. ("%s!TLP3TransmitT0: -> Sending %s (%ld bytes)\n",
  679. DRIVER_NAME,
  680. (currentByte == 0 ? "header" : "data"),
  681. *requestLength)
  682. );
  683. //
  684. // Write to the card
  685. //
  686. *serialIoControlCode = SMARTCARD_WRITE;
  687. SmartcardExtension->SmartcardRequest.Buffer = &requestBuffer[currentByte];
  688. status = TLP3SerialIo(SmartcardExtension);
  689. if (status != STATUS_SUCCESS) {
  690. SmartcardDebug(
  691. DEBUG_ERROR,
  692. ("%s!TLP3TransmitT0: TLP3SerialIo(SMARTCARD_WRITE) returned %lx\n",
  693. DRIVER_NAME,
  694. status)
  695. );
  696. leave;
  697. }
  698. //
  699. // The TLP3 echos all sent bytes. We read the echo
  700. // back into our send buffer
  701. //
  702. *serialIoControlCode = SMARTCARD_READ;
  703. *replyLength = *requestLength;
  704. SmartcardExtension->SmartcardReply.Buffer = &requestBuffer[currentByte];
  705. status = TLP3SerialIo(SmartcardExtension);
  706. if (status != STATUS_SUCCESS) {
  707. SmartcardDebug(
  708. DEBUG_ERROR,
  709. ("%s!TLP3TransmitT0: TLP3SerialIo(SMARTCARD_READ) returned %lx\n",
  710. DRIVER_NAME,
  711. status)
  712. );
  713. leave;
  714. }
  715. currentByte += *requestLength;
  716. bytesToSend -= *requestLength;
  717. }
  718. // Read the 'Procedure byte'.
  719. SmartcardExtension->SmartcardReply.Buffer = &procByte;
  720. *serialIoControlCode = SMARTCARD_READ;
  721. *replyLength = 1;
  722. status = TLP3SerialIo(SmartcardExtension);
  723. if (status != STATUS_SUCCESS) {
  724. SmartcardDebug(
  725. DEBUG_ERROR,
  726. ("%s!TLP3TransmitT0: TLP3SerialIo(SMARTCARD_READ) returned %lx\n",
  727. DRIVER_NAME,
  728. status)
  729. );
  730. leave;
  731. }
  732. restartWorkWaitingTime = FALSE;
  733. //
  734. // Check the procedure byte.
  735. // Please take a look at ISO 7816 Part 3 Section 8.2.2
  736. //
  737. if (procByte == requestBuffer[1] ||
  738. procByte == requestBuffer[1] + 1) {
  739. SmartcardDebug(
  740. DEBUG_PROTOCOL,
  741. ("%s!TLP3TransmitT0: <- ACK (send all)\n",
  742. DRIVER_NAME)
  743. );
  744. // All remaining data bytes can be sent at once
  745. *requestLength = bytesToSend;
  746. } else if (procByte == (UCHAR) ~requestBuffer[1] ||
  747. procByte == (UCHAR) ~(requestBuffer[1] + 1)) {
  748. SmartcardDebug(
  749. DEBUG_PROTOCOL,
  750. ("%s!TLP3TransmitT0: <- ACK (send single)\n",
  751. DRIVER_NAME)
  752. );
  753. // We can send only one byte
  754. *requestLength = 1;
  755. } else if (procByte == 0x60 ||
  756. SmartcardExtension->CardCapabilities.InversConvention &&
  757. procByte == 0xf9) {
  758. //
  759. // We have to reset the wait time and try again to read
  760. //
  761. ULONG TimeRes;
  762. LARGE_INTEGER delayTime;
  763. SmartcardDebug(
  764. DEBUG_PROTOCOL,
  765. ("%s!TLP3TransmitT0: <- NULL (%ldms)\n",
  766. DRIVER_NAME,
  767. SmartcardExtension->CardCapabilities.T0.WT / 1000)
  768. );
  769. TimeRes = KeQueryTimeIncrement();
  770. delayTime.HighPart = -1;
  771. delayTime.LowPart =
  772. (-1) *
  773. TimeRes *
  774. ((SmartcardExtension->CardCapabilities.T0.WT * 10l / TimeRes) + 1);
  775. KeDelayExecutionThread(
  776. KernelMode,
  777. FALSE,
  778. &delayTime
  779. );
  780. //
  781. // Set flag that we only should read the proc byte
  782. // without writing data to the card
  783. //
  784. restartWorkWaitingTime = TRUE;
  785. } else {
  786. //
  787. // The card returned a status byte.
  788. // Status bytes are always two bytes long.
  789. // Store this byte first and then read the next
  790. //
  791. replyBuffer[0] = procByte;
  792. *serialIoControlCode = SMARTCARD_READ;
  793. *replyLength = 1;
  794. bytesToSend = 0;
  795. bytesToRead = 0;
  796. //
  797. // Read in the second status byte
  798. //
  799. SmartcardExtension->SmartcardReply.Buffer =
  800. &replyBuffer[1];
  801. status = TLP3SerialIo(SmartcardExtension);
  802. SmartcardExtension->SmartcardReply.BufferLength = 2;
  803. SmartcardDebug(
  804. (status == STATUS_SUCCESS ? DEBUG_PROTOCOL : DEBUG_ERROR),
  805. ("%s!TLP3TransmitT0: <- SW1=%02x SW2=%02x (%lx)\n",
  806. DRIVER_NAME,
  807. replyBuffer[0],
  808. replyBuffer[1],
  809. status)
  810. );
  811. }
  812. } while(bytesToSend || restartWorkWaitingTime);
  813. if (status != STATUS_SUCCESS)
  814. leave;
  815. if (bytesToRead != 0) {
  816. *serialIoControlCode = SMARTCARD_READ;
  817. *replyLength = bytesToRead;
  818. SmartcardExtension->SmartcardReply.Buffer =
  819. replyBuffer;
  820. status = TLP3SerialIo(SmartcardExtension);
  821. SmartcardDebug(
  822. (status == STATUS_SUCCESS ? DEBUG_PROTOCOL : DEBUG_ERROR),
  823. ("%s!TLP3TransmitT0: <- Data %ld bytes, SW1=%02x SW2=%02x (%lx)\n",
  824. DRIVER_NAME,
  825. bytesToRead,
  826. replyBuffer[bytesToRead - 2],
  827. replyBuffer[bytesToRead - 1],
  828. status)
  829. );
  830. }
  831. }
  832. finally {
  833. // Restore pointers to their original location
  834. SmartcardExtension->SmartcardRequest.Buffer =
  835. requestBuffer;
  836. SmartcardExtension->SmartcardReply.Buffer =
  837. replyBuffer;
  838. if (status == STATUS_TIMEOUT) {
  839. // STATUS_TIMEOUT is not mapped to a Win32 error code
  840. status = STATUS_IO_TIMEOUT;
  841. }
  842. if (status == STATUS_SUCCESS) {
  843. status = SmartcardT0Reply(SmartcardExtension);
  844. }
  845. }
  846. SmartcardDebug(
  847. (status == STATUS_SUCCESS ? DEBUG_TRACE : DEBUG_ERROR),
  848. ("%s!TLP3TransmitT0: Exit(%lx)\n",
  849. DRIVER_NAME,
  850. status)
  851. );
  852. return status;
  853. }
  854. NTSTATUS
  855. TLP3Transmit(
  856. PSMARTCARD_EXTENSION SmartcardExtension
  857. )
  858. /*++
  859. Routine Description:
  860. This function is called by the smart card library whenever a transmission
  861. is required.
  862. Arguments:
  863. SmartcardExtension - Pointer to smart card data struct.
  864. Return Value:
  865. NTSTATUS
  866. --*/
  867. {
  868. NTSTATUS status;
  869. PAGED_CODE();
  870. SmartcardDebug(
  871. DEBUG_TRACE,
  872. ("%s!TLP3Transmit: Enter\n",
  873. DRIVER_NAME)
  874. );
  875. _try {
  876. do {
  877. PUCHAR requestBuffer = SmartcardExtension->SmartcardRequest.Buffer;
  878. PUCHAR replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
  879. PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
  880. PULONG replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
  881. PULONG serialIoControlCode = &SmartcardExtension->ReaderExtension->SerialIoControlCode;
  882. //
  883. // Tell the lib function how many bytes I need for the prologue
  884. //
  885. *requestLength = 0;
  886. switch (SmartcardExtension->CardCapabilities.Protocol.Selected) {
  887. case SCARD_PROTOCOL_RAW:
  888. status = SmartcardRawRequest(SmartcardExtension);
  889. break;
  890. case SCARD_PROTOCOL_T0:
  891. //
  892. // T=0 requires a bit more work.
  893. // So we do this in a seperate function.
  894. //
  895. status = TLP3TransmitT0(SmartcardExtension);
  896. leave;
  897. case SCARD_PROTOCOL_T1:
  898. status = SmartcardT1Request(SmartcardExtension);
  899. break;
  900. default:
  901. status = STATUS_INVALID_DEVICE_REQUEST;
  902. leave;
  903. }
  904. if (status != STATUS_SUCCESS) {
  905. leave;
  906. }
  907. //
  908. // Write the command to the card
  909. //
  910. *replyLength = 0;
  911. *serialIoControlCode = SMARTCARD_WRITE;
  912. status = TLP3SerialIo(SmartcardExtension);
  913. if (status != STATUS_SUCCESS) {
  914. leave;
  915. }
  916. //
  917. // The Bull reader always echos the bytes sent, so read that echo back
  918. //
  919. *serialIoControlCode = SMARTCARD_READ;
  920. *replyLength = *requestLength;
  921. status = TLP3SerialIo(SmartcardExtension);
  922. if (status != STATUS_SUCCESS) {
  923. leave;
  924. }
  925. switch (SmartcardExtension->CardCapabilities.Protocol.Selected) {
  926. case SCARD_PROTOCOL_RAW:
  927. status = SmartcardRawReply(SmartcardExtension);
  928. break;
  929. case SCARD_PROTOCOL_T1:
  930. //
  931. // Check if the card requested a waiting time extension
  932. //
  933. if (SmartcardExtension->T1.Wtx) {
  934. LARGE_INTEGER waitTime;
  935. waitTime.HighPart = -1;
  936. waitTime.LowPart =
  937. SmartcardExtension->T1.Wtx *
  938. SmartcardExtension->CardCapabilities.T1.BWT *
  939. (-10);
  940. KeDelayExecutionThread(
  941. KernelMode,
  942. FALSE,
  943. &waitTime
  944. );
  945. }
  946. //
  947. // Read NAD, PCB and LEN fields
  948. //
  949. *replyLength = 3;
  950. status = TLP3SerialIo(SmartcardExtension);
  951. //
  952. // Check for timeout first. If the card did not reply
  953. // we need to send a resend request
  954. //
  955. if (status != STATUS_TIMEOUT) {
  956. if (status != STATUS_SUCCESS) {
  957. leave;
  958. }
  959. //
  960. // The third byte contains the length of the data in the packet
  961. // and we additinally want to have the EDC bytes which
  962. // is one for LRC and 2 for CRC
  963. //
  964. *replyLength =
  965. replyBuffer[2] +
  966. (SmartcardExtension->CardCapabilities.T1.EDC & 0x01 ? 2 : 1);
  967. // We want to have the remaining bytes just after the first 3
  968. SmartcardExtension->SmartcardReply.Buffer += 3;
  969. status = TLP3SerialIo(SmartcardExtension);
  970. SmartcardExtension->SmartcardReply.Buffer -= 3;
  971. SmartcardExtension->SmartcardReply.BufferLength += 3;
  972. if (status != STATUS_SUCCESS && status != STATUS_TIMEOUT) {
  973. leave;
  974. }
  975. }
  976. if (status == STATUS_TIMEOUT) {
  977. //
  978. // Since the card did not reply we set the number of
  979. // bytes received to 0. This will trigger a resend
  980. // request
  981. //
  982. SmartcardDebug(
  983. DEBUG_PROTOCOL,
  984. ("%s!TLP3TransmitT1: Timeout\n",
  985. DRIVER_NAME)
  986. );
  987. SmartcardExtension->SmartcardReply.BufferLength = 0;
  988. }
  989. status = SmartcardT1Reply(SmartcardExtension);
  990. break;
  991. default:
  992. status = STATUS_INVALID_DEVICE_REQUEST;
  993. leave;
  994. }
  995. } while (status == STATUS_MORE_PROCESSING_REQUIRED);
  996. }
  997. _finally {
  998. if (status == STATUS_TIMEOUT) {
  999. // STATUS_TIMEOUT is not mapped to a Win32 error code
  1000. status = STATUS_IO_TIMEOUT;
  1001. }
  1002. }
  1003. #if defined (DEBUG) && defined (DETECT_SERIAL_OVERRUNS)
  1004. if (status != STATUS_SUCCESS) {
  1005. NTSTATUS status;
  1006. PSERIALPERF_STATS perfData =
  1007. (PSERIALPERF_STATS) SmartcardExtension->SmartcardReply.Buffer;
  1008. // we have to call GetCommStatus to reset the error condition
  1009. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1010. IOCTL_SERIAL_GET_COMMSTATUS;
  1011. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  1012. SmartcardExtension->SmartcardReply.BufferLength =
  1013. sizeof(SERIAL_STATUS);
  1014. status = TLP3SerialIo(SmartcardExtension);
  1015. ASSERT(status == STATUS_SUCCESS);
  1016. // now get the reason for the transmission error
  1017. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1018. IOCTL_SERIAL_GET_STATS;
  1019. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  1020. SmartcardExtension->SmartcardReply.BufferLength =
  1021. sizeof(SERIALPERF_STATS);
  1022. status = TLP3SerialIo(SmartcardExtension);
  1023. ASSERT(status == STATUS_SUCCESS);
  1024. SmartcardDebug(
  1025. DEBUG_ERROR,
  1026. ("%s!TLP3Transmit: Serial error statistics:\n FrameErrors: %ld\n SerialOverrunErrors: %ld\n BufferOverrunErrors: %ld\n ParityErrors: %ld\n",
  1027. DRIVER_NAME,
  1028. perfData->FrameErrorCount,
  1029. perfData->SerialOverrunErrorCount,
  1030. perfData->BufferOverrunErrorCount,
  1031. perfData->ParityErrorCount)
  1032. );
  1033. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1034. IOCTL_SERIAL_CLEAR_STATS;
  1035. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  1036. SmartcardExtension->SmartcardReply.BufferLength = 0;
  1037. status = TLP3SerialIo(SmartcardExtension);
  1038. ASSERT(status == STATUS_SUCCESS);
  1039. }
  1040. #if DEBUG && TIMEOUT_TEST
  1041. else {
  1042. // inject some timeout errors
  1043. LARGE_INTEGER Ticks;
  1044. UCHAR RandomVal;
  1045. KeQueryTickCount(&Ticks);
  1046. RandomVal = (UCHAR) Ticks.LowPart % 4;
  1047. if (RandomVal == 0) {
  1048. status = STATUS_IO_TIMEOUT;
  1049. SmartcardDebug(
  1050. DEBUG_ERROR,
  1051. ("%s!TLP3Transmit: Simulating timeout\n",
  1052. DRIVER_NAME)
  1053. );
  1054. }
  1055. }
  1056. #endif
  1057. #endif
  1058. #ifdef SIMULATION
  1059. if (SmartcardExtension->ReaderExtension->SimulationLevel &
  1060. SIM_IO_TIMEOUT) {
  1061. status = STATUS_IO_TIMEOUT;
  1062. SmartcardDebug(
  1063. DEBUG_SIMULATION,
  1064. ("%s!TLP3Transmit: SIM STATUS_IO_TIMEOUT\n",
  1065. DRIVER_NAME)
  1066. );
  1067. }
  1068. #endif
  1069. SmartcardDebug(
  1070. DEBUG_TRACE,
  1071. ("%s!TLP3Transmit: Exit(%lx)\n",
  1072. DRIVER_NAME,
  1073. status)
  1074. );
  1075. return status;
  1076. }
  1077. NTSTATUS
  1078. TLP3CardTracking(
  1079. PSMARTCARD_EXTENSION SmartcardExtension
  1080. )
  1081. /*++
  1082. Routine Description:
  1083. The smart card lib requires to have this function. It is called
  1084. to setup event tracking for card insertion and removal events.
  1085. Arguments:
  1086. SmartcardExtension - pointer to the smart card data struct.
  1087. Return Value:
  1088. NTSTATUS
  1089. --*/
  1090. {
  1091. KIRQL ioIrql, keIrql;
  1092. //
  1093. // Set cancel routine for the notification irp
  1094. //
  1095. KeAcquireSpinLock(
  1096. &SmartcardExtension->OsData->SpinLock,
  1097. &keIrql
  1098. );
  1099. IoAcquireCancelSpinLock(&ioIrql);
  1100. if (SmartcardExtension->OsData->NotificationIrp) {
  1101. IoSetCancelRoutine(
  1102. SmartcardExtension->OsData->NotificationIrp,
  1103. TLP3Cancel
  1104. );
  1105. }
  1106. IoReleaseCancelSpinLock(ioIrql);
  1107. KeReleaseSpinLock(
  1108. &SmartcardExtension->OsData->SpinLock,
  1109. keIrql
  1110. );
  1111. return STATUS_PENDING;
  1112. }
  1113. NTSTATUS
  1114. TLP3VendorIoctl(
  1115. PSMARTCARD_EXTENSION SmartcardExtension
  1116. )
  1117. {
  1118. NTSTATUS status;
  1119. static char answer[] = "Vendor IOCTL";
  1120. PAGED_CODE();
  1121. SmartcardDebug(
  1122. DEBUG_PROTOCOL,
  1123. ("%s!TLP3VendorIoctl: Enter\n",
  1124. DRIVER_NAME)
  1125. );
  1126. if (SmartcardExtension->IoRequest.ReplyBuffer != NULL &&
  1127. SmartcardExtension->IoRequest.ReplyBufferLength >= strlen(answer) + 1) {
  1128. strcpy(SmartcardExtension->IoRequest.ReplyBuffer, answer);
  1129. *SmartcardExtension->IoRequest.Information = strlen(answer);
  1130. status = STATUS_SUCCESS;
  1131. } else {
  1132. status = STATUS_BUFFER_TOO_SMALL;
  1133. }
  1134. SmartcardDebug(
  1135. DEBUG_PROTOCOL,
  1136. ("%s!TLP3VendorIoctl: Exit(%lx)\n",
  1137. DRIVER_NAME,
  1138. status)
  1139. );
  1140. return status;
  1141. }
  1142. NTSTATUS
  1143. TLP3SerialIo(
  1144. PSMARTCARD_EXTENSION SmartcardExtension
  1145. )
  1146. /*++
  1147. Routine Description:
  1148. This routine sends IOCTL's to the serial driver. It waits on for their
  1149. completion, and then returns.
  1150. Arguments:
  1151. Return Value:
  1152. NTSTATUS
  1153. --*/
  1154. {
  1155. NTSTATUS status;
  1156. ULONG currentByte = 0;
  1157. if (KeReadStateEvent(&READER_EXTENSION(SerialCloseDone))) {
  1158. //
  1159. // we have no connection to serial, fail the call
  1160. // this could be the case if the reader was removed
  1161. // during stand by / hibernation
  1162. //
  1163. return STATUS_UNSUCCESSFUL;
  1164. }
  1165. // Check if the buffers are large enough
  1166. ASSERT(SmartcardExtension->SmartcardReply.BufferLength <=
  1167. SmartcardExtension->SmartcardReply.BufferSize);
  1168. ASSERT(SmartcardExtension->SmartcardRequest.BufferLength <=
  1169. SmartcardExtension->SmartcardRequest.BufferSize);
  1170. if (SmartcardExtension->SmartcardReply.BufferLength >
  1171. SmartcardExtension->SmartcardReply.BufferSize ||
  1172. SmartcardExtension->SmartcardRequest.BufferLength >
  1173. SmartcardExtension->SmartcardRequest.BufferSize) {
  1174. SmartcardLogError(
  1175. SmartcardExtension->OsData->DeviceObject,
  1176. TLP3_BUFFER_TOO_SMALL,
  1177. NULL,
  1178. 0
  1179. );
  1180. return STATUS_BUFFER_TOO_SMALL;
  1181. }
  1182. do {
  1183. IO_STATUS_BLOCK ioStatus;
  1184. KEVENT event;
  1185. PIRP irp;
  1186. PIO_STACK_LOCATION irpNextStack;
  1187. PUCHAR requestBuffer = NULL;
  1188. PUCHAR replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
  1189. ULONG requestBufferLength = SmartcardExtension->SmartcardRequest.BufferLength;
  1190. ULONG replyBufferLength = SmartcardExtension->SmartcardReply.BufferLength;
  1191. KeInitializeEvent(
  1192. &event,
  1193. NotificationEvent,
  1194. FALSE
  1195. );
  1196. if (READER_EXTENSION(SerialIoControlCode) == SMARTCARD_WRITE) {
  1197. if (SmartcardExtension->CardCapabilities.GT != 0) {
  1198. //
  1199. // If the guardtime isn't 0 and we write data to the smart card
  1200. // we only write byte by byte, because we have to insert a delay
  1201. // between every sent byte
  1202. //
  1203. requestBufferLength = 1;
  1204. }
  1205. requestBuffer =
  1206. &SmartcardExtension->SmartcardRequest.Buffer[currentByte++];
  1207. replyBuffer = NULL;
  1208. replyBufferLength = 0;
  1209. } else {
  1210. requestBuffer =
  1211. (requestBufferLength ?
  1212. SmartcardExtension->SmartcardRequest.Buffer : NULL);
  1213. }
  1214. // Build irp to be sent to serial driver
  1215. irp = IoBuildDeviceIoControlRequest(
  1216. READER_EXTENSION(SerialIoControlCode),
  1217. SmartcardExtension->ReaderExtension->AttachedDeviceObject,
  1218. requestBuffer,
  1219. requestBufferLength,
  1220. replyBuffer,
  1221. replyBufferLength,
  1222. FALSE,
  1223. &event,
  1224. &ioStatus
  1225. );
  1226. ASSERT(irp != NULL);
  1227. if (irp == NULL) {
  1228. return STATUS_INSUFFICIENT_RESOURCES;
  1229. }
  1230. irpNextStack = IoGetNextIrpStackLocation(irp);
  1231. switch (SmartcardExtension->ReaderExtension->SerialIoControlCode) {
  1232. //
  1233. // The serial driver trasfers data from/to irp->AssociatedIrp.SystemBuffer
  1234. //
  1235. case SMARTCARD_WRITE:
  1236. //
  1237. // Since we 'manually' change parameters, the io-manager
  1238. // does not really know if this is an input or an ouput operation
  1239. // unless the reply buffer is 0. We do the assertion here, because
  1240. // if the reply buffer is not NULL, the io-manager will copy
  1241. // data back to the reply buffer.
  1242. //
  1243. ASSERT(replyBuffer == NULL);
  1244. irpNextStack->MajorFunction = IRP_MJ_WRITE;
  1245. irpNextStack->Parameters.Write.Length = requestBufferLength;
  1246. irpNextStack->Parameters.Write.ByteOffset.QuadPart = 0;
  1247. break;
  1248. case SMARTCARD_READ:
  1249. irpNextStack->MajorFunction = IRP_MJ_READ;
  1250. irpNextStack->Parameters.Read.Length = replyBufferLength;
  1251. irpNextStack->Parameters.Read.ByteOffset.QuadPart = 0;
  1252. break;
  1253. default:
  1254. ASSERT(irpNextStack->MajorFunction = IRP_MJ_DEVICE_CONTROL);
  1255. ASSERT(
  1256. DEVICE_TYPE_FROM_CTL_CODE(READER_EXTENSION(SerialIoControlCode)) ==
  1257. FILE_DEVICE_SERIAL_PORT
  1258. );
  1259. }
  1260. status = IoCallDriver(
  1261. SmartcardExtension->ReaderExtension->AttachedDeviceObject,
  1262. irp
  1263. );
  1264. if (status == STATUS_PENDING) {
  1265. KeWaitForSingleObject(
  1266. &event,
  1267. Executive,
  1268. KernelMode,
  1269. FALSE,
  1270. NULL
  1271. );
  1272. status = ioStatus.Status;
  1273. // save the number of bytes received
  1274. SmartcardExtension->SmartcardReply.BufferLength =
  1275. (ULONG) ioStatus.Information;
  1276. }
  1277. // Check if we have to write more bytes to the reader
  1278. if (SmartcardExtension->ReaderExtension->SerialIoControlCode ==
  1279. SMARTCARD_WRITE &&
  1280. SmartcardExtension->CardCapabilities.GT != 0 &&
  1281. currentByte <
  1282. SmartcardExtension->SmartcardRequest.BufferLength) {
  1283. // Now wait the required guard time
  1284. KeStallExecutionProcessor(SmartcardExtension->CardCapabilities.GT);
  1285. status = STATUS_MORE_PROCESSING_REQUIRED;
  1286. }
  1287. } while (status == STATUS_MORE_PROCESSING_REQUIRED);
  1288. return status;
  1289. }