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.

2570 lines
77 KiB

  1. #include "usbsc.h"
  2. #include "usbsccb.h"
  3. #include "usbcom.h"
  4. #include "usbutil.h"
  5. #include "usbscnt.h"
  6. #pragma warning( disable : 4242 4244)
  7. CHAR* InMessages[] = {
  8. "RDR_to_PC_DataBlock",
  9. "RDR_to_PC_SlotStatus",
  10. "RDR_to_PC_Parameters",
  11. "RDR_to_PC_Escape",
  12. "RDR_to_PC_DataRateAndClockFrequency",
  13. "INVALID MESSAGE"
  14. };
  15. CHAR* OutMessages[] = {
  16. "INVALID MESSAGE", // 0x60
  17. "PC_to_RDR_SetParameters", // 0x61
  18. "PC_to_RDR_IccPowerOn", // 0x62
  19. "PC_to_RDR_IccPowerOff", // 0x63
  20. "INVALID MESSAGE", // 0x64
  21. "PC_to_RDR_GetSlotStatus", // 0x65
  22. "INVALID MESSAGE", // 0x66
  23. "INVALID MESSAGE", // 0x67
  24. "INVALID MESSAGE", // 0x68
  25. "INVALID MESSAGE", // 0x69
  26. "PC_to_RDR_Secure", // 0x6a
  27. "PC_to_RDR_Escape", // 0x6b
  28. "PC_to_RDR_GetParameters", // 0x6c
  29. "PC_to_RDR_ResetParameters", // 0x6d
  30. "PC_to_RDR_IccClock", // 0x6e
  31. "PC_to_RDR_XfrBlock", // 0x6f
  32. "INVALID MESSAGE", // 0x70
  33. "PC_to_RDR_Mechanical", // 0x71
  34. "PC_to_RDR_Abort", // 0x72
  35. "PC_to_RDR_SetDataRateAndClockFrequency" // 0x73
  36. };
  37. UINT VoltMask[] = {
  38. 0, // Auto
  39. 1, // 5.0V
  40. 2, // 3.0V
  41. 4 // 1.8V
  42. };
  43. CHAR*
  44. GetMessageName(
  45. BYTE MessageType
  46. )
  47. {
  48. CHAR* name;
  49. if (MessageType & 0x80) {
  50. // IN message
  51. MessageType -= 0x80;
  52. if (MessageType > 5) {
  53. MessageType = 5;
  54. }
  55. name = InMessages[MessageType];
  56. } else {
  57. MessageType -= 0x60;
  58. if (MessageType >= 20) {
  59. MessageType = 0;
  60. }
  61. name = OutMessages[MessageType];
  62. }
  63. return name;
  64. }
  65. NTSTATUS
  66. UsbScTransmit(
  67. PSMARTCARD_EXTENSION SmartcardExtension
  68. )
  69. /*++
  70. Routine Description:
  71. RDF_TRANSMIT Callback function
  72. Called from smclib
  73. Arguments:
  74. SmartcardExtension
  75. Return Value:
  76. NT Status value
  77. --*/
  78. {
  79. NTSTATUS status = STATUS_SUCCESS;
  80. __try
  81. {
  82. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScTransmit Enter\n",DRIVER_NAME ));
  83. switch( SmartcardExtension->CardCapabilities.Protocol.Selected ) {
  84. case SCARD_PROTOCOL_T0:
  85. status = UsbScT0Transmit( SmartcardExtension );
  86. break;
  87. case SCARD_PROTOCOL_T1:
  88. status = UsbScT1Transmit( SmartcardExtension );
  89. break;
  90. default:
  91. status = STATUS_INVALID_DEVICE_REQUEST;
  92. break;
  93. }
  94. }
  95. __finally
  96. {
  97. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScTransmit Exit : 0x%x\n",DRIVER_NAME, status ));
  98. }
  99. return status;
  100. }
  101. NTSTATUS
  102. UsbScSetProtocol(
  103. PSMARTCARD_EXTENSION SmartcardExtension
  104. )
  105. /*++
  106. Routine Description:
  107. RDF_SET_PROTOCOL callback
  108. called from smclib
  109. Arguments:
  110. Return Value:
  111. --*/
  112. {
  113. NTSTATUS status = STATUS_UNSUCCESSFUL;
  114. UINT protocolMask;
  115. UINT protocol;
  116. PUSBSC_OUT_MESSAGE_HEADER message = NULL;
  117. PROTOCOL_DATA_T0 *dataT0;
  118. PROTOCOL_DATA_T1 *dataT1;
  119. PSCARD_CARD_CAPABILITIES cardCaps = NULL;
  120. PCLOCK_AND_DATA_RATE cadData = NULL;
  121. PUCHAR response = NULL;
  122. PPPS_REQUEST pPPS = NULL;
  123. PPS_REQUEST pps;
  124. UINT bytesToRead;
  125. KIRQL irql;
  126. __try
  127. {
  128. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSetProtocol Enter\n",DRIVER_NAME ));
  129. protocolMask = SmartcardExtension->MinorIoControlCode;
  130. cardCaps = &SmartcardExtension->CardCapabilities;
  131. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Setting Protocol\n",DRIVER_NAME ));
  132. // Modify protocolMask to those protocols that the reader and the card
  133. // support.
  134. protocolMask = protocolMask &
  135. SmartcardExtension->CardCapabilities.Protocol.Supported &
  136. SmartcardExtension->ReaderExtension->ClassDescriptor.dwProtocols;
  137. //
  138. // If the reader supports automatic parameter configuration, then just
  139. // check for the selected protocol
  140. //
  141. if (SmartcardExtension->ReaderExtension->ClassDescriptor.dwFeatures & AUTO_PARAMETER_NEGOTIATION) {
  142. message = ExAllocatePool(NonPagedPool,
  143. sizeof(USBSC_OUT_MESSAGE_HEADER));
  144. if (!message) {
  145. status = STATUS_INSUFFICIENT_RESOURCES;
  146. __leave;
  147. }
  148. RtlZeroMemory(message,
  149. sizeof( USBSC_OUT_MESSAGE_HEADER ));
  150. response = ExAllocatePool(NonPagedPool,
  151. sizeof(USBSC_IN_MESSAGE_HEADER)
  152. + sizeof(PROTOCOL_DATA_T1));
  153. if (!response) {
  154. status = STATUS_INSUFFICIENT_RESOURCES;
  155. __leave;
  156. }
  157. message->bMessageType = PC_to_RDR_GetParameters;
  158. message->dwLength = 0;
  159. message->bSlot = 0;
  160. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Reader supports auto parameter negotiation\n",DRIVER_NAME ));
  161. status = UsbScReadWrite(SmartcardExtension,
  162. message,
  163. response,
  164. sizeof(PROTOCOL_DATA_T1),
  165. NULL,
  166. FALSE);
  167. if (!NT_SUCCESS(status)) {
  168. __leave;
  169. }
  170. if ((((PUSBSC_IN_MESSAGE_HEADER) response)->bProtocolNum+1) & protocolMask) {
  171. *SmartcardExtension->IoRequest.ReplyBuffer = ((PUSBSC_IN_MESSAGE_HEADER) response)->bProtocolNum + 1;
  172. *SmartcardExtension->IoRequest.Information = sizeof(ULONG);
  173. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  174. &irql);
  175. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  176. SmartcardExtension->CardCapabilities.Protocol.Selected = *SmartcardExtension->IoRequest.ReplyBuffer;
  177. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  178. irql);
  179. } else {
  180. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Reader has not selected desired protocol\n",DRIVER_NAME ));
  181. status = STATUS_INVALID_DEVICE_REQUEST;
  182. }
  183. __leave;
  184. }
  185. //
  186. // Check if the card has already selected the right protocol
  187. //
  188. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  189. &irql);
  190. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC &&
  191. (SmartcardExtension->CardCapabilities.Protocol.Selected &
  192. SmartcardExtension->MinorIoControlCode)) {
  193. protocolMask = SmartcardExtension->CardCapabilities.Protocol.Selected;
  194. status = STATUS_SUCCESS;
  195. }
  196. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  197. irql);
  198. //
  199. // Check if PPS request needs to be sent
  200. //
  201. if (!(NT_SUCCESS(status)) && !(SmartcardExtension->ReaderExtension->ClassDescriptor.dwFeatures & (AUTO_PARAMETER_NEGOTIATION | AUTO_PPS))) {
  202. PUCHAR replyPos;
  203. //
  204. // Must send PPS request
  205. //
  206. message = ExAllocatePool(NonPagedPool,
  207. sizeof(USBSC_OUT_MESSAGE_HEADER)
  208. + sizeof(PPS_REQUEST));
  209. if (!message) {
  210. status = STATUS_INSUFFICIENT_RESOURCES;
  211. __leave;
  212. }
  213. RtlZeroMemory(message,
  214. sizeof( USBSC_OUT_MESSAGE_HEADER )
  215. + sizeof(PPS_REQUEST));
  216. response = ExAllocatePool(NonPagedPool,
  217. sizeof(USBSC_IN_MESSAGE_HEADER)
  218. + sizeof(PPS_REQUEST));
  219. if (!response) {
  220. status = STATUS_INSUFFICIENT_RESOURCES;
  221. __leave;
  222. }
  223. while (TRUE) {
  224. pPPS = (PPPS_REQUEST) ((PUCHAR) message + sizeof(USBSC_OUT_MESSAGE_HEADER));
  225. pPPS->bPPSS = 0xff;
  226. if (protocolMask & SCARD_PROTOCOL_T1) {
  227. pPPS->bPPS0 = 0x11;
  228. } else if (protocolMask & SCARD_PROTOCOL_T0) {
  229. pPPS->bPPS0 = 0x10;
  230. } else {
  231. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSetProtocol Invalid protocol\n",DRIVER_NAME ));
  232. status = STATUS_INVALID_DEVICE_REQUEST;
  233. __leave;
  234. }
  235. pPPS->bPPS1 = (cardCaps->PtsData.Fl << 4)
  236. | cardCaps->PtsData.Dl;
  237. pPPS->bPCK = (pPPS->bPPSS ^ pPPS->bPPS0 ^ pPPS->bPPS1);
  238. SmartcardDebug( DEBUG_PROTOCOL,
  239. ("%s : Sending PPS request (0x%x 0x%x 0x%x 0x%x)\n",
  240. DRIVER_NAME,
  241. pPPS->bPPSS,
  242. pPPS->bPPS0,
  243. pPPS->bPPS1,
  244. pPPS->bPCK ));
  245. message->bMessageType = PC_to_RDR_XfrBlock;
  246. message->bSlot = 0;
  247. message->dwLength = sizeof(PPS_REQUEST);
  248. switch (SmartcardExtension->ReaderExtension->ExchangeLevel) {
  249. case TPDU_LEVEL:
  250. message->wLevelParameter = 0;
  251. bytesToRead = sizeof(PPS_REQUEST);
  252. status = UsbScReadWrite(SmartcardExtension,
  253. message,
  254. response,
  255. bytesToRead,
  256. &pps,
  257. FALSE);
  258. break;
  259. case CHARACTER_LEVEL:
  260. replyPos = (PUCHAR) &pps;
  261. bytesToRead = 4;
  262. message->wLevelParameter = 2;
  263. while (bytesToRead) {
  264. status = UsbScReadWrite(SmartcardExtension,
  265. message,
  266. response,
  267. message->wLevelParameter,
  268. replyPos,
  269. FALSE);
  270. bytesToRead -= 2;
  271. replyPos += 2;
  272. message->dwLength = 0;
  273. if (!NT_SUCCESS(status)) {
  274. break;
  275. }
  276. }
  277. break;
  278. }
  279. if (!NT_SUCCESS(status) || (memcmp(&pps, pPPS, sizeof(PPS_REQUEST)) != 0)) {
  280. // The card failed with the current settings
  281. // If PtsData.Type is not PTS_TYPE_DEFAULT, then try that.
  282. if (cardCaps->PtsData.Type == PTS_TYPE_DEFAULT) {
  283. SmartcardDebug( DEBUG_PROTOCOL, ("%s : The card failed PPS request\n",DRIVER_NAME ));
  284. ASSERT(FALSE);
  285. status = STATUS_DEVICE_PROTOCOL_ERROR;
  286. __leave;
  287. }
  288. SmartcardDebug( DEBUG_PROTOCOL, ("%s : The card failed PPS request, trying default PPS\n",DRIVER_NAME ));
  289. cardCaps->PtsData.Type = PTS_TYPE_DEFAULT;
  290. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  291. status = UsbScCardPower(SmartcardExtension);
  292. } else {
  293. break;
  294. }
  295. }
  296. if (message != NULL) {
  297. ExFreePool(message);
  298. message = NULL;
  299. }
  300. if (response != NULL) {
  301. ExFreePool(response);
  302. response = NULL;
  303. }
  304. }
  305. //
  306. // Send set protocol request to the reader
  307. //
  308. if (protocolMask & SCARD_PROTOCOL_T1) { // T=1
  309. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Setting protocol T=1\n",DRIVER_NAME ));
  310. protocol = 1;
  311. message = ExAllocatePool(NonPagedPool,
  312. sizeof( USBSC_OUT_MESSAGE_HEADER )
  313. + sizeof(PROTOCOL_DATA_T1));
  314. if (!message) {
  315. status = STATUS_INSUFFICIENT_RESOURCES;
  316. __leave;
  317. }
  318. RtlZeroMemory(message,
  319. sizeof( USBSC_OUT_MESSAGE_HEADER )
  320. + sizeof(PROTOCOL_DATA_T1));
  321. dataT1 = (PPROTOCOL_DATA_T1) ((PUCHAR) message + sizeof(USBSC_OUT_MESSAGE_HEADER));
  322. //
  323. // 7 4 3 0
  324. // ----------------------------
  325. // | FI | DI |
  326. // ----------------------------
  327. //
  328. dataT1->bmFindexDindex = (cardCaps->PtsData.Fl << 4)
  329. | cardCaps->PtsData.Dl;
  330. //
  331. // B7-2 = 000100b
  332. // B0 = Checksum type (0=LRC, 1=CRC)
  333. // B1 = Convention used (0=direct, 1=inverse)
  334. //
  335. dataT1->bmTCCKST1 = 0x10 | (cardCaps->T1.EDC & 0x01);
  336. if (cardCaps->InversConvention) {
  337. dataT1->bmTCCKST1 |= 2;
  338. }
  339. dataT1->bGuardTimeT1 = cardCaps->N;
  340. //
  341. // 7 4 3 0
  342. // ----------------------------
  343. // | BWI | CWI |
  344. // ----------------------------
  345. //
  346. dataT1->bmWaitingIntegersT1 = (cardCaps->T1.BWI << 4)
  347. | (cardCaps->T1.CWI & 0xf);
  348. dataT1->bClockStop = 0;
  349. dataT1->bIFSC = cardCaps->T1.IFSC;
  350. dataT1->bNadValue = 0;
  351. message->dwLength = sizeof(PROTOCOL_DATA_T1);
  352. } else if (protocolMask & SCARD_PROTOCOL_T0) {
  353. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Setting protocol T=0\n",DRIVER_NAME ));
  354. protocol = 0;
  355. message = ExAllocatePool(NonPagedPool,
  356. sizeof( USBSC_OUT_MESSAGE_HEADER )
  357. + sizeof(PROTOCOL_DATA_T0));
  358. if (!message) {
  359. status = STATUS_INSUFFICIENT_RESOURCES;
  360. __leave;
  361. }
  362. RtlZeroMemory(message,
  363. sizeof( USBSC_OUT_MESSAGE_HEADER )
  364. + sizeof(PROTOCOL_DATA_T0));
  365. dataT0 = (PROTOCOL_DATA_T0 *) (((UCHAR *) message) + sizeof(USBSC_OUT_MESSAGE_HEADER));
  366. //
  367. // 7 4 3 0
  368. // ----------------------------
  369. // | FI | DI |
  370. // ----------------------------
  371. //
  372. dataT0->bmFindexDindex = (cardCaps->PtsData.Fl << 4)
  373. | cardCaps->PtsData.Dl;
  374. //
  375. // B7-2 = 000000b
  376. // B0 = 0
  377. // B1 = Convention used (0=direct, 1=inverse)
  378. //
  379. dataT0->bmTCCKST0 = 0;
  380. if (cardCaps->InversConvention) {
  381. dataT0->bmTCCKST0 |= 2;
  382. }
  383. dataT0->bGuardTimeT0 = cardCaps->N;
  384. dataT0->bWaitingIntegerT0 = cardCaps->T0.WI;
  385. dataT0->bClockStop = 0;
  386. message->dwLength = sizeof(PROTOCOL_DATA_T0);
  387. } else {
  388. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSetProtocol Invalid protocol\n",DRIVER_NAME ));
  389. status = STATUS_INVALID_DEVICE_REQUEST;
  390. __leave;
  391. }
  392. message->bMessageType = PC_to_RDR_SetParameters;
  393. message->bSlot = 0;
  394. message->bProtocolNum = protocol;
  395. status = UsbScReadWrite(SmartcardExtension,
  396. message,
  397. (PVOID) message,
  398. message->dwLength,
  399. NULL,
  400. FALSE);
  401. if (!NT_SUCCESS(status)) {
  402. __leave;
  403. }
  404. //
  405. // See if reader supports auto clock/baud rate configuration
  406. //
  407. if ((SmartcardExtension->ReaderExtension->ClassDescriptor.dwFeatures & (AUTO_BAUD_RATE | AUTO_CLOCK_FREQ)) != (AUTO_BAUD_RATE | AUTO_CLOCK_FREQ)) {
  408. // Set ClockFrequency and DataRate
  409. RtlZeroMemory(message,
  410. sizeof(USBSC_OUT_MESSAGE_HEADER)
  411. + sizeof(CLOCK_AND_DATA_RATE));
  412. message->bMessageType = PC_to_RDR_SetDataRateAndClockFrequency;
  413. message->dwLength = 8;
  414. message->bSlot = 0;
  415. cadData = (PCLOCK_AND_DATA_RATE) ((PUCHAR)message+sizeof(USBSC_OUT_MESSAGE_HEADER));
  416. cadData->dwClockFrequency = SmartcardExtension->CardCapabilities.PtsData.CLKFrequency;
  417. cadData->dwDataRate = SmartcardExtension->CardCapabilities.PtsData.DataRate;
  418. status = UsbScReadWrite(SmartcardExtension,
  419. message,
  420. (PVOID) message,
  421. sizeof(CLOCK_AND_DATA_RATE),
  422. NULL,
  423. FALSE);
  424. if (!NT_SUCCESS(status)) {
  425. __leave;
  426. }
  427. }
  428. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  429. &irql);
  430. if (SmartcardExtension->ReaderCapabilities.CurrentState != SCARD_SPECIFIC) {
  431. // This was a call from UsbScCardPower, so don't fill in the buffer.
  432. *SmartcardExtension->IoRequest.ReplyBuffer = protocol + 1;
  433. *SmartcardExtension->IoRequest.Information = sizeof(ULONG);
  434. }
  435. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  436. SmartcardExtension->CardCapabilities.Protocol.Selected = protocol + 1;
  437. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  438. irql);
  439. }
  440. __finally
  441. {
  442. if (message != NULL) {
  443. ExFreePool(message);
  444. message = NULL;
  445. }
  446. if (response != NULL) {
  447. ExFreePool(response);
  448. response = NULL;
  449. }
  450. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSetProtocol Exit : 0x%x\n",DRIVER_NAME, status ));
  451. }
  452. return status;
  453. }
  454. NTSTATUS
  455. UsbScCardPower(
  456. PSMARTCARD_EXTENSION SmartcardExtension
  457. )
  458. /*++
  459. Routine Description:
  460. RDF_CARD_POWER callback
  461. called from smclib
  462. Arguments:
  463. Return Value:
  464. --*/
  465. {
  466. NTSTATUS status = STATUS_SUCCESS;
  467. PREADER_EXTENSION readerExtension;
  468. UCHAR atr[sizeof(USBSC_IN_MESSAGE_HEADER) + ATR_SIZE];
  469. USBSC_OUT_MESSAGE_HEADER powerMessage;
  470. PUSBSC_IN_MESSAGE_HEADER replyHeader;
  471. BYTE voltage;
  472. LARGE_INTEGER waitTime;
  473. KIRQL irql;
  474. BOOLEAN callSetProtocol = FALSE;
  475. __try
  476. {
  477. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCardPower Enter\n",DRIVER_NAME ));
  478. replyHeader = (PUSBSC_IN_MESSAGE_HEADER) atr;
  479. readerExtension = SmartcardExtension->ReaderExtension;
  480. *SmartcardExtension->IoRequest.Information = 0;
  481. switch (SmartcardExtension->MinorIoControlCode) {
  482. case SCARD_WARM_RESET:
  483. RtlZeroMemory(&powerMessage, sizeof(USBSC_OUT_MESSAGE_HEADER));
  484. powerMessage.bMessageType = PC_to_RDR_IccPowerOn;
  485. powerMessage.bPowerSelect = readerExtension->CurrentVoltage;
  486. powerMessage.dwLength = 0;
  487. powerMessage.bSlot = 0;
  488. SmartcardDebug( DEBUG_PROTOCOL, ("%s : SCARD_WARM_RESET (bPowerSelect = 0x%x)\n",DRIVER_NAME, readerExtension->CurrentVoltage ));
  489. status = UsbScReadWrite(SmartcardExtension,
  490. &powerMessage,
  491. atr,
  492. ATR_SIZE,
  493. SmartcardExtension->IoRequest.ReplyBuffer,
  494. FALSE);
  495. if (!NT_SUCCESS(status)) {
  496. SmartcardDebug( DEBUG_ERROR, ("%s : PC_to_RDR_IccPowerOn failed with status = 0x%x\n",DRIVER_NAME, status ));
  497. __leave;
  498. }
  499. if (replyHeader->dwLength > ATR_SIZE) {
  500. SmartcardDebug( DEBUG_ERROR, ("%s :Invalid ATR size returned\n",DRIVER_NAME, status ));
  501. status = STATUS_DEVICE_PROTOCOL_ERROR;
  502. __leave;
  503. }
  504. *SmartcardExtension->IoRequest.Information = replyHeader->dwLength;
  505. RtlCopyMemory(SmartcardExtension->CardCapabilities.ATR.Buffer,
  506. SmartcardExtension->IoRequest.ReplyBuffer,
  507. *SmartcardExtension->IoRequest.Information);
  508. SmartcardExtension->CardCapabilities.ATR.Length = *SmartcardExtension->IoRequest.Information;
  509. status = SmartcardUpdateCardCapabilities(SmartcardExtension);
  510. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  511. &irql);
  512. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC) {
  513. callSetProtocol = TRUE;
  514. }
  515. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  516. irql);
  517. break;
  518. case SCARD_COLD_RESET:
  519. SmartcardDebug( DEBUG_PROTOCOL, ("%s : SCARD_COLD_RESET\n",DRIVER_NAME ));
  520. RtlZeroMemory(&powerMessage, sizeof(USBSC_OUT_MESSAGE_HEADER));
  521. powerMessage.dwLength = 0;
  522. powerMessage.bSlot = 0;
  523. // Need to first power off card before selecting another
  524. // voltage.
  525. powerMessage.bMessageType = PC_to_RDR_IccPowerOff;
  526. status = UsbScReadWrite(SmartcardExtension,
  527. &powerMessage,
  528. atr,
  529. 0,
  530. NULL,
  531. FALSE);
  532. if (!NT_SUCCESS(status)) {
  533. SmartcardDebug( DEBUG_ERROR, ("%s : PC_to_RDR_IccPowerOff failed with status = 0x%x\n",DRIVER_NAME, status ));
  534. __leave;
  535. }
  536. // We need to iterate through the possible voltages, moving from low voltage to high
  537. // until we find one that works
  538. for (voltage = 3; voltage > 0 && voltage <= 3; voltage--) {
  539. if (readerExtension->ClassDescriptor.dwFeatures & AUTO_VOLTAGE_SELECTION) {
  540. // reader supports auto voltage selection
  541. voltage = 0;
  542. } else if (!(readerExtension->ClassDescriptor.bVoltageSupport & VoltMask[voltage])) {
  543. // Reader doesn't support this voltage.
  544. continue;
  545. }
  546. // Wait 10ms per spec
  547. waitTime.HighPart = -1;
  548. waitTime.LowPart = -100; // 10ms
  549. KeDelayExecutionThread(KernelMode,
  550. FALSE,
  551. &waitTime);
  552. // Now we can power back on
  553. RtlZeroMemory(&powerMessage, sizeof(USBSC_OUT_MESSAGE_HEADER));
  554. powerMessage.bMessageType = PC_to_RDR_IccPowerOn;
  555. powerMessage.bPowerSelect = voltage;
  556. powerMessage.dwLength = 0;
  557. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Selecting voltage = 0x%x\n",DRIVER_NAME, voltage ));
  558. status = UsbScReadWrite(SmartcardExtension,
  559. &powerMessage,
  560. atr,
  561. ATR_SIZE,
  562. SmartcardExtension->IoRequest.ReplyBuffer,
  563. FALSE);
  564. if (NT_SUCCESS(status)) {
  565. // everything worked. We found the correct voltage
  566. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Voltage set to 0x%x\n",DRIVER_NAME, voltage ));
  567. *SmartcardExtension->IoRequest.Information = replyHeader->dwLength;
  568. readerExtension->CurrentVoltage = voltage;
  569. break;
  570. }
  571. //
  572. // If card or reader doesn't support selected voltage, it will
  573. // either timeout, return ICC_CLASS_NOT_SUPPORTED or
  574. // report that parameter 7 (bPowerselect) is not supported
  575. //
  576. if (((replyHeader->bStatus == 0x41) && (replyHeader->bError == ICC_MUTE))
  577. || (replyHeader->bError == ICC_CLASS_NOT_SUPPORTED)
  578. || (replyHeader->bError == 7)) {
  579. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Reader did not support voltage = 0x%x\n",DRIVER_NAME, voltage ));
  580. // We are going to try another voltage
  581. } else {
  582. //
  583. // We have a bigger problem that we can't handle
  584. // Let's just ignore it for now and see if it is
  585. // due to insufficient voltage
  586. //
  587. SmartcardDebug( DEBUG_ERROR, ("%s!UsbScCardPower Unhandled error (probably due to insufficient voltage)\n",DRIVER_NAME ));
  588. }
  589. }
  590. // Save the ATR so smclib can parse it
  591. if (*SmartcardExtension->IoRequest.Information > ATR_SIZE) {
  592. SmartcardDebug( DEBUG_ERROR, ("%s : Invalid ATR size returned\n",DRIVER_NAME ));
  593. status = STATUS_DEVICE_PROTOCOL_ERROR;
  594. __leave;
  595. }
  596. RtlCopyMemory(SmartcardExtension->CardCapabilities.ATR.Buffer,
  597. SmartcardExtension->IoRequest.ReplyBuffer,
  598. *SmartcardExtension->IoRequest.Information);
  599. SmartcardExtension->CardCapabilities.ATR.Length = *SmartcardExtension->IoRequest.Information;
  600. status = SmartcardUpdateCardCapabilities(SmartcardExtension);
  601. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  602. &irql);
  603. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC) {
  604. callSetProtocol = TRUE;
  605. }
  606. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  607. irql);
  608. break;
  609. case SCARD_POWER_DOWN:
  610. SmartcardDebug( DEBUG_PROTOCOL, ("%s : SCARD_POWER_DOWN\n",DRIVER_NAME ));
  611. RtlZeroMemory(&powerMessage, sizeof(USBSC_OUT_MESSAGE_HEADER));
  612. powerMessage.bSlot = 0;
  613. powerMessage.bMessageType = PC_to_RDR_IccPowerOff;
  614. powerMessage.dwLength = 0;
  615. status = UsbScReadWrite(SmartcardExtension,
  616. &powerMessage,
  617. atr,
  618. 0,
  619. NULL,
  620. FALSE);
  621. if (!NT_SUCCESS(status)) {
  622. SmartcardDebug( DEBUG_ERROR, ("%s : PC_to_RDR_IccPowerOff failed with status = 0x%x\n",DRIVER_NAME, status ));
  623. __leave;
  624. }
  625. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  626. &irql);
  627. if (SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_PRESENT) {
  628. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_PRESENT;
  629. }
  630. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  631. irql);
  632. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  633. break;
  634. }
  635. }
  636. __finally
  637. {
  638. if (callSetProtocol) {
  639. ULONG minorIoctl;
  640. // SetProtocol will not be called in this case, so call it now.
  641. // Select best possible PTS data
  642. SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_OPTIMAL;
  643. status = SmartcardUpdateCardCapabilities(SmartcardExtension);
  644. minorIoctl = SmartcardExtension->MinorIoControlCode;
  645. SmartcardExtension->MinorIoControlCode = SmartcardExtension->CardCapabilities.Protocol.Selected;
  646. UsbScSetProtocol(SmartcardExtension);
  647. SmartcardExtension->MinorIoControlCode = minorIoctl;
  648. }
  649. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCardPower Exit : 0x%x\n",DRIVER_NAME, status ));
  650. }
  651. return status;
  652. }
  653. NTSTATUS
  654. UsbScCardTracking(
  655. PSMARTCARD_EXTENSION SmartcardExtension
  656. )
  657. /*++
  658. Routine Description:
  659. RDF_CARD_TRACKING callback
  660. called from smclib
  661. Arguments:
  662. Return Value:
  663. --*/
  664. {
  665. NTSTATUS status = STATUS_SUCCESS;
  666. KIRQL ioIrql, keIrql;
  667. __try
  668. {
  669. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCardTracking Enter\n",DRIVER_NAME ));
  670. // set cancel routine
  671. IoAcquireCancelSpinLock( &ioIrql );
  672. IoSetCancelRoutine(
  673. SmartcardExtension->OsData->NotificationIrp,
  674. ScUtil_Cancel);
  675. IoReleaseCancelSpinLock( ioIrql );
  676. status = STATUS_PENDING;
  677. }
  678. __finally
  679. {
  680. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCardTracking Exit : 0x%x\n",DRIVER_NAME, status ));
  681. }
  682. return status;
  683. }
  684. NTSTATUS
  685. UsbScCardSwallow(
  686. PSMARTCARD_EXTENSION SmartcardExtension
  687. )
  688. /*++
  689. Routine Description:
  690. RDF_READER_SWALLOW callback
  691. called from smclib
  692. Arguments:
  693. Return Value:
  694. --*/
  695. {
  696. NTSTATUS status = STATUS_SUCCESS;
  697. __try
  698. {
  699. USBSC_OUT_MESSAGE_HEADER header;
  700. USBSC_IN_MESSAGE_HEADER reply;
  701. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCardSwallow Enter\n",DRIVER_NAME ));
  702. header.bMessageType = PC_to_RDR_Mechanical;
  703. header.dwLength = 0;
  704. header.bSlot = 0;
  705. header.bFunction = 4; // lock
  706. status = UsbScReadWrite(SmartcardExtension,
  707. &header,
  708. (PUCHAR) &reply,
  709. 0,
  710. NULL,
  711. FALSE);
  712. }
  713. __finally
  714. {
  715. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCardSwallow Exit : 0x%x\n",DRIVER_NAME, status ));
  716. }
  717. return status;
  718. }
  719. NTSTATUS
  720. UsbScCardEject(
  721. PSMARTCARD_EXTENSION SmartcardExtension
  722. )
  723. /*++
  724. Routine Description:
  725. RDF_CARD_EJECT callback
  726. called from smclib
  727. Arguments:
  728. Return Value:
  729. --*/
  730. {
  731. NTSTATUS status = STATUS_SUCCESS;
  732. __try
  733. {
  734. USBSC_OUT_MESSAGE_HEADER header;
  735. USBSC_IN_MESSAGE_HEADER reply;
  736. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCardEject Enter\n",DRIVER_NAME ));
  737. header.bMessageType = PC_to_RDR_Mechanical;
  738. header.dwLength = 0;
  739. header.bSlot = 0;
  740. header.bFunction = 5; // unlock
  741. status = UsbScReadWrite(SmartcardExtension,
  742. &header,
  743. (PUCHAR) &reply,
  744. 0,
  745. NULL,
  746. FALSE);
  747. }
  748. __finally
  749. {
  750. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCardEject Exit : 0x%x\n",DRIVER_NAME, status ));
  751. }
  752. return status;
  753. }
  754. NTSTATUS
  755. UsbScT0Transmit(
  756. PSMARTCARD_EXTENSION SmartcardExtension
  757. )
  758. /*++
  759. Routine Description:
  760. Handles transmitting data to/from reader using the T=0 protocol
  761. Arguments:
  762. SmartcardExtension
  763. Return Value:
  764. NT status value
  765. --*/
  766. {
  767. NTSTATUS status = STATUS_SUCCESS;
  768. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  769. ULONG bytesToSend;
  770. ULONG requestLength;
  771. ULONG bytesToRead;
  772. PUCHAR currentHeaderPos;
  773. PUCHAR currentData;
  774. ULONG maxDataLen = 0;
  775. USBSC_OUT_MESSAGE_HEADER header;
  776. PUSBSC_IN_MESSAGE_HEADER replyHeader;
  777. PUCHAR responseBuffer = NULL;
  778. PUCHAR replyPos;
  779. LONG timeout = 0;
  780. UCHAR ins;
  781. ULONG initialRequestLength = 0;
  782. __try
  783. {
  784. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT0Transmit Enter\n",DRIVER_NAME ));
  785. // Tell the lib to allocate space for the header
  786. SmartcardExtension->SmartcardRequest.BufferLength = sizeof(USBSC_OUT_MESSAGE_HEADER);
  787. SmartcardExtension->SmartcardReply.BufferLength = 0;
  788. initialRequestLength = SmartcardExtension->IoRequest.RequestBufferLength -
  789. sizeof(SCARD_IO_REQUEST);
  790. status = SmartcardT0Request(SmartcardExtension);
  791. if (!NT_SUCCESS(status)) {
  792. __leave;
  793. }
  794. bytesToSend = SmartcardExtension->SmartcardRequest.BufferLength - sizeof(USBSC_OUT_MESSAGE_HEADER);
  795. bytesToRead = SmartcardExtension->T0.Le + 2; // Le + SW2 and SW2
  796. replyPos = SmartcardExtension->SmartcardReply.Buffer;
  797. if ((SmartcardExtension->T0.Le == 0)
  798. && (SmartcardExtension->T0.Lc == 0)
  799. && (initialRequestLength == 4)
  800. && ReaderExtension->ExchangeLevel != CHARACTER_LEVEL) {
  801. // Case 1 APDU. Only want to send 4 byte APDU in this case but smclib
  802. // expanded it to 5 bytes by setting P3 to 0. For CCID, strip off P3.
  803. bytesToSend--;
  804. }
  805. // allocate buffer to hold message header and data.
  806. responseBuffer = ExAllocatePool(NonPagedPool,
  807. sizeof( USBSC_OUT_MESSAGE_HEADER ) + bytesToRead);
  808. if (!responseBuffer) {
  809. status = STATUS_INSUFFICIENT_RESOURCES;
  810. __leave;
  811. }
  812. replyHeader = (PUSBSC_IN_MESSAGE_HEADER) responseBuffer;
  813. currentHeaderPos = SmartcardExtension->SmartcardRequest.Buffer;
  814. // Set parameters that are common to all ExchangeLevels.
  815. header.bMessageType = PC_to_RDR_XfrBlock;
  816. header.bSlot = 0;
  817. header.bBWI = 0;
  818. switch (ReaderExtension->ExchangeLevel) {
  819. case SHORT_APDU_LEVEL:
  820. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT0Transmit SHORT_APDU_LEVEL\n",DRIVER_NAME ));
  821. // Fall through since short APDU is an extended APDU with bytesToSend <= MaxMessageLength-10
  822. case EXTENDED_APDU_LEVEL:
  823. if (ReaderExtension->ExchangeLevel == EXTENDED_APDU_LEVEL) {
  824. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT0Transmit EXTENDED_APDU_LEVEL\n",DRIVER_NAME ));
  825. }
  826. if (bytesToSend <= (ReaderExtension->MaxMessageLength - sizeof(USBSC_OUT_MESSAGE_HEADER))) {
  827. // this is basically just like a short APDU
  828. header.wLevelParameter = 0;
  829. requestLength = bytesToSend;
  830. } else {
  831. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT0Transmit multi-packet message\n",DRIVER_NAME ));
  832. requestLength = ReaderExtension->MaxMessageLength - sizeof(USBSC_OUT_MESSAGE_HEADER);
  833. header.wLevelParameter = 1;
  834. }
  835. while (bytesToSend || ((replyHeader->bChainParameter & 0x01) == 0x01)) {
  836. header.dwLength = requestLength;
  837. *(PUSBSC_OUT_MESSAGE_HEADER)currentHeaderPos = header;
  838. status = UsbScReadWrite(SmartcardExtension,
  839. currentHeaderPos,
  840. responseBuffer,
  841. bytesToRead,
  842. replyPos,
  843. FALSE);
  844. if (!NT_SUCCESS(status)) {
  845. __leave;
  846. }
  847. SmartcardDebug( DEBUG_PROTOCOL, ("%s!UsbScT0Transmit SW1=0x%x, SW2=0x%x\n",DRIVER_NAME, replyPos[replyHeader->dwLength-2], replyPos[replyHeader->dwLength-1] ));
  848. if (bytesToSend < requestLength) {
  849. // this should NEVER happen
  850. status = STATUS_DEVICE_PROTOCOL_ERROR;
  851. __leave;
  852. }
  853. bytesToSend -= requestLength;
  854. currentHeaderPos += requestLength;
  855. if ((bytesToSend <= (ReaderExtension->MaxMessageLength - sizeof(USBSC_OUT_MESSAGE_HEADER))) && (bytesToSend > 0)) {
  856. // Last part of APDU
  857. requestLength = bytesToSend;
  858. header.wLevelParameter = 2;
  859. } else if (bytesToSend > 0) {
  860. // Still more APDU to come
  861. header.wLevelParameter = 3;
  862. } else {
  863. // Expect more data
  864. header.wLevelParameter = 0x10;
  865. }
  866. if (bytesToRead < replyHeader->dwLength) {
  867. status = STATUS_DEVICE_PROTOCOL_ERROR;
  868. __leave;
  869. }
  870. bytesToRead -= replyHeader->dwLength;
  871. replyPos += replyHeader->dwLength;
  872. SmartcardExtension->SmartcardReply.BufferLength += replyHeader->dwLength;
  873. }
  874. break;
  875. case TPDU_LEVEL:
  876. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT0Transmit TPDU_LEVEL\n",DRIVER_NAME ));
  877. header.wLevelParameter = 0;
  878. header.dwLength = bytesToSend;
  879. *(PUSBSC_OUT_MESSAGE_HEADER)currentHeaderPos = header;
  880. status = UsbScReadWrite(SmartcardExtension,
  881. currentHeaderPos,
  882. responseBuffer,
  883. bytesToRead,
  884. replyPos,
  885. FALSE);
  886. if (!NT_SUCCESS(status)) {
  887. __leave;
  888. }
  889. bytesToSend = 0;
  890. bytesToRead -= replyHeader->dwLength;
  891. replyPos += replyHeader->dwLength;
  892. SmartcardExtension->SmartcardReply.BufferLength += replyHeader->dwLength;
  893. break;
  894. case CHARACTER_LEVEL:
  895. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT0Transmit CHARACTER_LEVEL\n",DRIVER_NAME ));
  896. //
  897. // Send T0 command header
  898. //
  899. requestLength = 5;
  900. currentHeaderPos = SmartcardExtension->SmartcardRequest.Buffer;
  901. ins = currentHeaderPos[sizeof(USBSC_OUT_MESSAGE_HEADER)+1];
  902. header.dwLength = requestLength;
  903. while (bytesToSend || bytesToRead) {
  904. BOOL restartWorkingTime = TRUE;
  905. header.wLevelParameter = 1;
  906. *(PUSBSC_OUT_MESSAGE_HEADER)currentHeaderPos = header;
  907. status = UsbScReadWrite(SmartcardExtension,
  908. currentHeaderPos,
  909. responseBuffer,
  910. header.wLevelParameter,
  911. replyPos,
  912. FALSE);
  913. if (!NT_SUCCESS(status)) {
  914. __leave;
  915. }
  916. bytesToSend -= header.dwLength;
  917. currentHeaderPos += header.dwLength;
  918. currentData = responseBuffer + sizeof( USBSC_IN_MESSAGE_HEADER );
  919. if ((*currentData) == 0x60) {
  920. // this is a NULL byte.
  921. header.wLevelParameter = 1;
  922. header.dwLength = 0;
  923. continue;
  924. } else if (((*currentData & 0xF0) == 0x60) || ((*currentData & 0xF0) == 0x90)) {
  925. // Got SW1
  926. //
  927. // data has already been coppied to request buffer
  928. // just increment replyPos to prevent overwriting
  929. //
  930. replyPos++;
  931. SmartcardExtension->SmartcardReply.BufferLength++;
  932. //Get SW2
  933. header.dwLength = 0;
  934. header.wLevelParameter = 1;
  935. *(PUSBSC_OUT_MESSAGE_HEADER)currentHeaderPos = header;
  936. UsbScReadWrite(SmartcardExtension,
  937. currentHeaderPos,
  938. responseBuffer,
  939. header.wLevelParameter,
  940. replyPos,
  941. FALSE);
  942. if (!NT_SUCCESS(status)) {
  943. __leave;
  944. }
  945. bytesToRead = 0;
  946. bytesToSend = 0;
  947. replyPos++;
  948. SmartcardExtension->SmartcardReply.BufferLength++;
  949. continue;
  950. }
  951. if ((*currentData & 0xFE) == (ins & 0xFE)) {
  952. //
  953. //Transfer all bytes
  954. //
  955. header.dwLength = bytesToSend;
  956. header.wLevelParameter = bytesToRead;
  957. if (bytesToSend) {
  958. continue;
  959. }
  960. } else if ((*currentData & 0xFE) == ((~ins) & 0xFE)) {
  961. //
  962. // Transfer next byte
  963. //
  964. header.dwLength = bytesToSend ? 1 : 0;
  965. header.wLevelParameter = bytesToRead ? 1 : 0;
  966. if (bytesToSend) {
  967. continue;
  968. }
  969. } else {
  970. status = STATUS_UNSUCCESSFUL;
  971. __leave;
  972. }
  973. *(PUSBSC_OUT_MESSAGE_HEADER)currentHeaderPos = header;
  974. status = UsbScReadWrite(SmartcardExtension,
  975. currentHeaderPos,
  976. responseBuffer,
  977. header.wLevelParameter,
  978. replyPos,
  979. FALSE);
  980. if (!NT_SUCCESS(status)) {
  981. __leave;
  982. }
  983. if (bytesToRead < replyHeader->dwLength) {
  984. status = STATUS_DEVICE_PROTOCOL_ERROR;
  985. __leave;
  986. }
  987. bytesToSend -= header.dwLength;
  988. currentHeaderPos += header.dwLength;
  989. bytesToRead -= replyHeader->dwLength;
  990. replyPos += replyHeader->dwLength;
  991. SmartcardExtension->SmartcardReply.BufferLength += replyHeader->dwLength;
  992. }
  993. break;
  994. }
  995. status = SmartcardT0Reply(SmartcardExtension);
  996. }
  997. __finally
  998. {
  999. if (responseBuffer) {
  1000. ExFreePool(responseBuffer);
  1001. responseBuffer = NULL;
  1002. }
  1003. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT0Transmit Exit : 0x%x\n",DRIVER_NAME, status ));
  1004. }
  1005. return status;
  1006. }
  1007. NTSTATUS
  1008. UsbScT1Transmit(
  1009. PSMARTCARD_EXTENSION SmartcardExtension
  1010. )
  1011. /*++
  1012. Routine Description:
  1013. Handles transmitting data to/from reader using the T=1 protocol
  1014. Arguments:
  1015. SmartcardExtension
  1016. Return Value:
  1017. NT status value
  1018. --*/
  1019. {
  1020. NTSTATUS status = STATUS_SUCCESS;
  1021. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  1022. USBSC_OUT_MESSAGE_HEADER header;
  1023. PUSBSC_IN_MESSAGE_HEADER replyHeader;
  1024. PUCHAR currentHeaderPos;
  1025. PUCHAR responseBuffer = NULL;
  1026. PUCHAR requestBuffer = NULL;
  1027. PUCHAR replyPos;
  1028. ULONG bytesToSend;
  1029. ULONG requestLength;
  1030. ULONG bytesToRead;
  1031. LONG timeout = 0;
  1032. __try
  1033. {
  1034. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT1Transmit Enter\n",DRIVER_NAME ));
  1035. // allocate buffer to hold message header and data.
  1036. responseBuffer = ExAllocatePool(NonPagedPool,
  1037. SmartcardExtension->IoRequest.ReplyBufferLength + sizeof(USBSC_OUT_MESSAGE_HEADER));
  1038. if (!responseBuffer) {
  1039. status = STATUS_INSUFFICIENT_RESOURCES;
  1040. __leave;
  1041. }
  1042. replyPos = SmartcardExtension->SmartcardReply.Buffer;
  1043. replyHeader = (PUSBSC_IN_MESSAGE_HEADER) responseBuffer;
  1044. currentHeaderPos = SmartcardExtension->SmartcardRequest.Buffer;
  1045. SmartcardExtension->SmartcardReply.BufferLength = 0;
  1046. bytesToRead = SmartcardExtension->ReaderCapabilities.MaxIFSD + 5; // Set to MAX possible so we allocate enough
  1047. // With the APDU exchange levels, we don't use smclib to manage the
  1048. // protocol. We just shovel the data and the reader handles the details
  1049. if ((ReaderExtension->ExchangeLevel == SHORT_APDU_LEVEL)
  1050. || (ReaderExtension->ExchangeLevel == EXTENDED_APDU_LEVEL)) {
  1051. PIO_HEADER IoHeader = (PIO_HEADER) SmartcardExtension->IoRequest.RequestBuffer;
  1052. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT1Transmit APDU_LEVEL\n",DRIVER_NAME ));
  1053. if (SmartcardExtension->IoRequest.ReplyBufferLength <
  1054. IoHeader->ScardIoRequest.cbPciLength + 2) {
  1055. //
  1056. // We should at least be able to store
  1057. // the io-header plus SW1 and SW2
  1058. //
  1059. status = STATUS_BUFFER_TOO_SMALL;
  1060. __leave;
  1061. }
  1062. bytesToSend = SmartcardExtension->IoRequest.RequestBufferLength -
  1063. IoHeader->ScardIoRequest.cbPciLength;
  1064. // Need to allocate buffer for write data
  1065. requestBuffer = ExAllocatePool(NonPagedPool,
  1066. bytesToSend + sizeof(USBSC_OUT_MESSAGE_HEADER));
  1067. if (requestBuffer == NULL) {
  1068. status = STATUS_INSUFFICIENT_RESOURCES;
  1069. __leave;
  1070. }
  1071. replyPos = SmartcardExtension->IoRequest.ReplyBuffer;
  1072. currentHeaderPos = requestBuffer;
  1073. *SmartcardExtension->IoRequest.Information = 0;
  1074. // Copy over the data to write to the reader so we have room for the message header
  1075. RtlCopyMemory(&requestBuffer[sizeof(USBSC_OUT_MESSAGE_HEADER)],
  1076. &SmartcardExtension->IoRequest.RequestBuffer[sizeof(SCARD_IO_REQUEST)],
  1077. SmartcardExtension->IoRequest.RequestBufferLength - sizeof(SCARD_IO_REQUEST));
  1078. // Copy over the SCARD_IO)REQUEST structure from the request buffer to the
  1079. // reply buffer
  1080. RtlCopyMemory(replyPos,
  1081. IoHeader,
  1082. sizeof(SCARD_IO_REQUEST ));
  1083. replyPos += sizeof(SCARD_IO_REQUEST);
  1084. header.bMessageType = PC_to_RDR_XfrBlock;
  1085. header.bSlot = 0;
  1086. header.bBWI = 0;
  1087. if (bytesToSend <= (ReaderExtension->MaxMessageLength - sizeof(USBSC_OUT_MESSAGE_HEADER))) {
  1088. // this is basically just like a short APDU
  1089. header.wLevelParameter = 0;
  1090. requestLength = bytesToSend;
  1091. } else {
  1092. requestLength = ReaderExtension->MaxMessageLength - sizeof(USBSC_OUT_MESSAGE_HEADER);
  1093. header.wLevelParameter = 1;
  1094. }
  1095. while (bytesToSend || ((replyHeader->bChainParameter & 0x01) == 0x01)) {
  1096. header.dwLength = requestLength;
  1097. *(PUSBSC_OUT_MESSAGE_HEADER)currentHeaderPos = header;
  1098. status = UsbScReadWrite(SmartcardExtension,
  1099. currentHeaderPos,
  1100. responseBuffer,
  1101. bytesToRead,
  1102. replyPos,
  1103. FALSE);
  1104. if (!NT_SUCCESS(status)) {
  1105. __leave;
  1106. }
  1107. bytesToSend -= requestLength;
  1108. currentHeaderPos += requestLength;
  1109. if ((bytesToSend <= (ReaderExtension->MaxMessageLength - sizeof(USBSC_OUT_MESSAGE_HEADER))) && (bytesToSend > 0)) {
  1110. // Last part of APDU
  1111. requestLength = bytesToSend;
  1112. header.wLevelParameter = 2;
  1113. } else if (bytesToSend > 0) {
  1114. // Still more APDU to come
  1115. header.wLevelParameter = 3;
  1116. } else {
  1117. // Expect more data
  1118. header.wLevelParameter = 0x10;
  1119. }
  1120. replyPos += replyHeader->dwLength;
  1121. *SmartcardExtension->IoRequest.Information += replyHeader->dwLength;
  1122. }
  1123. *SmartcardExtension->IoRequest.Information += IoHeader->ScardIoRequest.cbPciLength;
  1124. __leave; // Finished transmitting data
  1125. }
  1126. // TPDU and Character levels
  1127. // Run this loop as long as he protocol requires to send data
  1128. do {
  1129. // Tell the lib to allocate space for the header
  1130. SmartcardExtension->SmartcardRequest.BufferLength = sizeof(USBSC_OUT_MESSAGE_HEADER);
  1131. SmartcardExtension->SmartcardReply.BufferLength = 0;
  1132. status = SmartcardT1Request(SmartcardExtension);
  1133. if (!NT_SUCCESS(status)) {
  1134. __leave;
  1135. }
  1136. replyPos = SmartcardExtension->SmartcardReply.Buffer;
  1137. bytesToSend = SmartcardExtension->SmartcardRequest.BufferLength - sizeof(USBSC_OUT_MESSAGE_HEADER);
  1138. // Set parameters that are common to all ExchangeLevels.
  1139. header.bMessageType = PC_to_RDR_XfrBlock;
  1140. header.bSlot = 0;
  1141. switch (ReaderExtension->ExchangeLevel) {
  1142. case TPDU_LEVEL:
  1143. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT1Transmit TPDU_LEVEL\n",DRIVER_NAME ));
  1144. header.wLevelParameter = 0;
  1145. header.dwLength = bytesToSend;
  1146. header.bBWI = SmartcardExtension->T1.Wtx;
  1147. *(PUSBSC_OUT_MESSAGE_HEADER)currentHeaderPos = header;
  1148. status = UsbScReadWrite(SmartcardExtension,
  1149. currentHeaderPos,
  1150. responseBuffer,
  1151. bytesToRead,
  1152. replyPos,
  1153. FALSE);
  1154. //
  1155. // smclib will detect timeout errors, so we set status
  1156. // to success
  1157. //
  1158. if (status == STATUS_IO_TIMEOUT) {
  1159. status = STATUS_SUCCESS;
  1160. }
  1161. if (!NT_SUCCESS(status)) {
  1162. __leave;
  1163. }
  1164. bytesToSend = 0;
  1165. SmartcardExtension->SmartcardReply.BufferLength = replyHeader->dwLength;
  1166. break;
  1167. case CHARACTER_LEVEL:
  1168. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT1Transmit CHARACTER_LEVEL\n",DRIVER_NAME ));
  1169. currentHeaderPos = SmartcardExtension->SmartcardRequest.Buffer;
  1170. header.dwLength = bytesToSend;
  1171. header.wLevelParameter = 3; // response is just the prologue field
  1172. header.bBWI = SmartcardExtension->T1.Wtx;
  1173. *(PUSBSC_OUT_MESSAGE_HEADER)currentHeaderPos = header;
  1174. status = UsbScReadWrite(SmartcardExtension,
  1175. currentHeaderPos,
  1176. responseBuffer,
  1177. header.wLevelParameter,
  1178. replyPos,
  1179. FALSE);
  1180. //
  1181. // smclib will detect timeout errors, so we set status to
  1182. // success
  1183. //
  1184. if (status == STATUS_IO_TIMEOUT) {
  1185. status = STATUS_SUCCESS;
  1186. SmartcardExtension->SmartcardReply.BufferLength += replyHeader->dwLength;
  1187. break;
  1188. }
  1189. if (!NT_SUCCESS(status)) {
  1190. ASSERT(FALSE);
  1191. __leave;
  1192. }
  1193. SmartcardExtension->SmartcardReply.BufferLength += replyHeader->dwLength;
  1194. bytesToSend = 0;
  1195. bytesToRead = replyPos[2] +
  1196. (SmartcardExtension->CardCapabilities.T1.EDC & 0x01 ? 2 : 1);
  1197. header.dwLength = 0;
  1198. header.wLevelParameter = bytesToRead;
  1199. *(PUSBSC_OUT_MESSAGE_HEADER)currentHeaderPos = header;
  1200. replyPos += replyHeader->dwLength;
  1201. status = UsbScReadWrite(SmartcardExtension,
  1202. currentHeaderPos,
  1203. responseBuffer,
  1204. header.wLevelParameter,
  1205. replyPos,
  1206. FALSE);
  1207. //
  1208. // smclib will detect timeout errors, so we set status to
  1209. // success
  1210. //
  1211. if (status == STATUS_IO_TIMEOUT) {
  1212. status = STATUS_SUCCESS;
  1213. }
  1214. if (!NT_SUCCESS(status)) {
  1215. __leave;
  1216. }
  1217. SmartcardExtension->SmartcardReply.BufferLength += replyHeader->dwLength;
  1218. break;
  1219. }
  1220. status = SmartcardT1Reply(SmartcardExtension);
  1221. } while (status == STATUS_MORE_PROCESSING_REQUIRED);
  1222. }
  1223. __finally
  1224. {
  1225. if (requestBuffer) {
  1226. ExFreePool(requestBuffer);
  1227. requestBuffer = NULL;
  1228. }
  1229. if (responseBuffer) {
  1230. ExFreePool(responseBuffer);
  1231. responseBuffer = NULL;
  1232. }
  1233. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScT1Transmit Exit : 0x%x\n",DRIVER_NAME, status ));
  1234. }
  1235. return status;
  1236. }
  1237. NTSTATUS
  1238. UsbScReadWrite(
  1239. PSMARTCARD_EXTENSION SmartcardExtension,
  1240. PVOID WriteBuffer,
  1241. PUCHAR ReadBuffer,
  1242. WORD ReadLength,
  1243. PVOID ResponseBuffer,
  1244. BOOL NullByte)
  1245. /*++
  1246. Routine Description:
  1247. Writes data to the reader, and then reads response from reader.
  1248. Handles the bSeq value, checking the slot number, any time extension requests
  1249. Also converts errors into NTSTATUS codes
  1250. Arguments:
  1251. SmartcardExtension -
  1252. WriteBuffer - Data to be written to the reader
  1253. ReaderBuffer - Caller allocated buffer to hold the response
  1254. ReadLength - Number of bytes expected (excluding header)
  1255. ResponseBuffer - optional buffer to copy response data only (no header)
  1256. NullByte - Look for NULL byte (used in T=0 protocol)
  1257. Return Value:
  1258. NTSTATUS value
  1259. --*/
  1260. {
  1261. NTSTATUS status = STATUS_SUCCESS;
  1262. PUSBSC_OUT_MESSAGE_HEADER header;
  1263. PUSBSC_IN_MESSAGE_HEADER replyHeader;
  1264. WORD writeLength;
  1265. ULONG timeout = 0;
  1266. __try
  1267. {
  1268. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScReadWrite Enter\n",DRIVER_NAME ));
  1269. header = (PUSBSC_OUT_MESSAGE_HEADER) WriteBuffer;
  1270. replyHeader = (PUSBSC_IN_MESSAGE_HEADER) ReadBuffer;
  1271. writeLength = header->dwLength + sizeof( USBSC_OUT_MESSAGE_HEADER);
  1272. ReadLength += sizeof( USBSC_IN_MESSAGE_HEADER );
  1273. header->bSeq = InterlockedIncrement(&SmartcardExtension->ReaderExtension->SequenceNumber);
  1274. //
  1275. // Send the data to the device
  1276. //
  1277. status = UsbWrite(SmartcardExtension->ReaderExtension,
  1278. WriteBuffer,
  1279. writeLength,
  1280. timeout);
  1281. if (!NT_SUCCESS(status)) {
  1282. __leave;
  1283. }
  1284. SmartcardDebug( DEBUG_PROTOCOL,
  1285. ("%s!UsbScReadWrite Wrote %s, 0x%x bytes (header + 0x%x)\n",
  1286. DRIVER_NAME,
  1287. GetMessageName(header->bMessageType),
  1288. writeLength, header->dwLength ));
  1289. if (SmartcardExtension->CardCapabilities.Protocol.Selected == SCARD_PROTOCOL_T1) {
  1290. if (SmartcardExtension->T1.Wtx) {
  1291. SmartcardDebug( DEBUG_PROTOCOL, ("%s!UsbScReadWrite Wait time extension. Wtx=0x%x, bBWI=0x%x\n",DRIVER_NAME, SmartcardExtension->T1.Wtx, header->bBWI));
  1292. }
  1293. }
  1294. // We want to loop here if the reader requests a time extension
  1295. while (1) {
  1296. status = UsbRead(SmartcardExtension->ReaderExtension,
  1297. ReadBuffer,
  1298. ReadLength,
  1299. timeout);
  1300. if (!NT_SUCCESS(status)) {
  1301. __leave;
  1302. }
  1303. SmartcardDebug( DEBUG_PROTOCOL,
  1304. ("%s!UsbScReadWrite Read %s, 0x%x bytes (header + 0x%x)\n",
  1305. DRIVER_NAME,
  1306. GetMessageName(replyHeader->bMessageType),
  1307. ReadLength, replyHeader->dwLength ));
  1308. if ((replyHeader->bSlot != header->bSlot) || (replyHeader->bSeq != header->bSeq)) {
  1309. // This is not ours. Who knows where this came from (probably a different slot that we don't support)
  1310. SmartcardDebug( DEBUG_PROTOCOL, ("%s!UsbScReadWrite Someone else's message received\n\t\tSlot %x (%x), Seq %x (%x)\n",
  1311. DRIVER_NAME,
  1312. replyHeader->bSlot,
  1313. header->bSlot,
  1314. replyHeader->bSeq,
  1315. header->bSeq ));
  1316. continue;
  1317. } else if (replyHeader->bStatus & COMMAND_STATUS_FAILED) {
  1318. // Doh we have a problem
  1319. SmartcardDebug( DEBUG_PROTOCOL,
  1320. ("%s!UsbScReadWrite COMMAND_STATUS_FAILED\n\tbmICCStatus = 0x%x\n\tbmCommandStatus = 0x%x\n\tbError = 0x%x\n",
  1321. DRIVER_NAME,
  1322. replyHeader->bStatus & ICC_STATUS_MASK,
  1323. (replyHeader->bStatus & COMMAND_STATUS_MASK) >> 6,
  1324. replyHeader->bError));
  1325. status = UsbScErrorConvert(replyHeader);
  1326. } else if (replyHeader->bStatus & COMMAND_STATUS_TIME_EXT) {
  1327. // Time extension requested
  1328. // We should sleep for a bit while the reader prepares the data
  1329. UINT wi = replyHeader->bError;
  1330. LARGE_INTEGER delayTime;
  1331. SmartcardDebug( DEBUG_PROTOCOL, ("%s!UsbScReadWrite Time extension requested\n",DRIVER_NAME ));
  1332. delayTime.HighPart = -1;
  1333. if (SmartcardExtension->CardCapabilities.Protocol.Selected == SCARD_PROTOCOL_T1) {
  1334. delayTime.LowPart =
  1335. (-1) *
  1336. SmartcardExtension->CardCapabilities.T1.BWT *
  1337. wi *
  1338. 10;
  1339. } else {
  1340. delayTime.LowPart =
  1341. (-1) * // relative
  1342. SmartcardExtension->CardCapabilities.T0.WT *
  1343. wi *
  1344. 10; // 100 nanosecond units
  1345. }
  1346. // KeDelayExecutionThread(KernelMode,
  1347. // FALSE,
  1348. // &delayTime);
  1349. continue;
  1350. } else if (NullByte && (ReadBuffer[sizeof(USBSC_IN_MESSAGE_HEADER)] == 0x60)) {
  1351. // NULL byte, wait for another response
  1352. SmartcardDebug( DEBUG_PROTOCOL, ("%s!UsbScReadWrite Received NULL byte, waiting for next response\n",DRIVER_NAME ));
  1353. continue;
  1354. } else {
  1355. // SUCCESS!!
  1356. SmartcardDebug( DEBUG_PROTOCOL,
  1357. ("%s!UsbScReadWrite Read %s, 0x%x bytes (header + 0x%x)\n",
  1358. DRIVER_NAME,
  1359. GetMessageName(replyHeader->bMessageType),
  1360. ReadLength, replyHeader->dwLength ));
  1361. }
  1362. break;
  1363. }
  1364. //
  1365. // copy data to request buffer
  1366. //
  1367. if (ResponseBuffer) {
  1368. RtlCopyMemory(ResponseBuffer,
  1369. ReadBuffer + sizeof(USBSC_IN_MESSAGE_HEADER),
  1370. replyHeader->dwLength);
  1371. }
  1372. }
  1373. __finally
  1374. {
  1375. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScReadWrite Exit : 0x%x\n",DRIVER_NAME, status ));
  1376. }
  1377. return status;
  1378. }
  1379. NTSTATUS
  1380. UsbScErrorConvert(
  1381. PUSBSC_IN_MESSAGE_HEADER ReplyHeader
  1382. )
  1383. /*++
  1384. Routine Description:
  1385. Converts the errors returned by the reader into
  1386. valid NTSTATUS codes
  1387. Arguments:
  1388. ReplyHeader - reply header recieved from reader
  1389. Return Value:
  1390. NTSTATUS code corresponding to the reader error
  1391. --*/
  1392. {
  1393. NTSTATUS status = STATUS_UNSUCCESSFUL;
  1394. __try
  1395. {
  1396. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScErrorConvert Enter\n",DRIVER_NAME ));
  1397. SmartcardDebug( DEBUG_TRACE, ("bmICCStatus = 0x%x\n",ReplyHeader->bStatus & ICC_STATUS_MASK ));
  1398. SmartcardDebug( DEBUG_TRACE, ("bmCommandStatus = 0x%x\n", (ReplyHeader->bStatus & COMMAND_STATUS_MASK) >> 6 ));
  1399. SmartcardDebug( DEBUG_TRACE, ("bError = 0x%x\n",ReplyHeader->bError ));
  1400. switch (ReplyHeader->bError) {
  1401. case CMD_ABORTED:
  1402. status = STATUS_CANCELLED;
  1403. break;
  1404. case ICC_MUTE:
  1405. if ((ReplyHeader->bStatus & ICC_STATUS_MASK) == 2) {
  1406. status = STATUS_NO_MEDIA;
  1407. } else {
  1408. status = STATUS_IO_TIMEOUT;
  1409. }
  1410. break;
  1411. case XFR_PARITY_ERROR:
  1412. status = STATUS_PARITY_ERROR;
  1413. break;
  1414. case XFR_OVERRUN:
  1415. status = STATUS_DATA_OVERRUN;
  1416. break;
  1417. case HW_ERROR:
  1418. status = STATUS_IO_DEVICE_ERROR;
  1419. break;
  1420. case BAD_ATR_TS:
  1421. status = STATUS_DEVICE_PROTOCOL_ERROR;
  1422. break;
  1423. case BAD_ATR_TCK:
  1424. status = STATUS_DEVICE_PROTOCOL_ERROR;
  1425. break;
  1426. case ICC_PROTOCOL_NOT_SUPPORTED:
  1427. status = STATUS_INVALID_DEVICE_REQUEST;
  1428. break;
  1429. case ICC_CLASS_NOT_SUPPORTED:
  1430. status = STATUS_INVALID_DEVICE_REQUEST;
  1431. break;
  1432. case PROCEDURE_BYTE_CONFLICT:
  1433. status = STATUS_DEVICE_PROTOCOL_ERROR;
  1434. break;
  1435. case DEACTIVATED_PROTOCOL:
  1436. status = STATUS_INVALID_DEVICE_REQUEST;
  1437. break;
  1438. case BUSY_WITH_AUTO_SEQUENCE:
  1439. status = STATUS_DEVICE_BUSY;
  1440. break;
  1441. case PIN_TIMEOUT:
  1442. break;
  1443. case PIN_CANCELLED:
  1444. break;
  1445. case CMD_SLOT_BUSY:
  1446. status = STATUS_DEVICE_BUSY;
  1447. break;
  1448. case 0:
  1449. case 1:
  1450. case 2:
  1451. case 3:
  1452. case 4:
  1453. case 5:
  1454. case 6:
  1455. case 7:
  1456. case 8:
  1457. case 9:
  1458. case 10:
  1459. case 11:
  1460. case 12:
  1461. case 13:
  1462. case 14:
  1463. case 15:
  1464. case 16:
  1465. status = STATUS_INVALID_DEVICE_REQUEST;
  1466. break;
  1467. }
  1468. }
  1469. __finally
  1470. {
  1471. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScErrorConvert Exit : 0x%x\n",DRIVER_NAME, status ));
  1472. }
  1473. return status;
  1474. }
  1475. NTSTATUS
  1476. UsbScTrackingISR(
  1477. PVOID Context,
  1478. PVOID Buffer,
  1479. ULONG BufferLength,
  1480. ULONG NotificationType,
  1481. PBOOLEAN QueueData)
  1482. /*++
  1483. Routine Description:
  1484. Callback function that is called when there is a slot change notification or
  1485. a reader error. This handles completing card tracking irps.
  1486. Arguments:
  1487. Return Value:
  1488. --*/
  1489. {
  1490. NTSTATUS status = STATUS_SUCCESS;
  1491. PSMARTCARD_EXTENSION SmartcardExtension = (PSMARTCARD_EXTENSION) Context;
  1492. PUSBSC_SLOT_CHANGE_HEADER header;
  1493. PUSBSC_HWERROR_HEADER errorHeader;
  1494. ULONG oldState;
  1495. UCHAR slotState;
  1496. KIRQL irql;
  1497. __try
  1498. {
  1499. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScTrackingISR Enter\n",DRIVER_NAME ));
  1500. // We don't need this data to be saved
  1501. *QueueData = FALSE;
  1502. // Make sure that we got enough data
  1503. if (BufferLength < sizeof(USBSC_SLOT_CHANGE_HEADER)) {
  1504. status = STATUS_INVALID_PARAMETER;
  1505. __leave;
  1506. }
  1507. header = (PUSBSC_SLOT_CHANGE_HEADER) Buffer;
  1508. switch (header->bMessageType) {
  1509. case RDR_to_PC_NotifySlotChange:
  1510. slotState = header->bmSlotICCState & SLOT0_MASK;
  1511. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  1512. &irql);
  1513. oldState = SmartcardExtension->ReaderCapabilities.CurrentState;
  1514. if (slotState & 0x2) {
  1515. // State changed
  1516. if (slotState & 0x1) {
  1517. SmartcardDebug( DEBUG_PROTOCOL, ("%s: RDR_to_PC_NotifySlotChange - Card Inserted (0x%x)\n",DRIVER_NAME, slotState));
  1518. // Card is inserted
  1519. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SWALLOWED;
  1520. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1521. irql);
  1522. if (SmartcardExtension->OsData->NotificationIrp && (oldState <= SCARD_ABSENT)) {
  1523. UsbScCompleteCardTracking(SmartcardExtension);
  1524. }
  1525. } else {
  1526. SmartcardDebug( DEBUG_PROTOCOL, ("%s: RDR_to_PC_NotifySlotChange - Card Removed (0x%x)\n",DRIVER_NAME, slotState));
  1527. // Card is removed
  1528. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  1529. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1530. irql);
  1531. if (SmartcardExtension->OsData->NotificationIrp && (oldState > SCARD_ABSENT)) {
  1532. UsbScCompleteCardTracking(SmartcardExtension);
  1533. }
  1534. }
  1535. } else {
  1536. SmartcardDebug( DEBUG_PROTOCOL, ("%s: RDR_to_PC_NotifySlotChange - No change (0x%x)\n",DRIVER_NAME, slotState));
  1537. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1538. irql);
  1539. }
  1540. break;
  1541. case RDR_to_PC_HardwareError:
  1542. errorHeader = (PUSBSC_HWERROR_HEADER) Buffer;
  1543. SmartcardDebug( DEBUG_PROTOCOL, ("%s: RDR_to_PC_HardwareError - 0x%x\n",DRIVER_NAME, errorHeader->bHardwareErrorCode));
  1544. // Lets just ignore hardware errors for now and see what happens.
  1545. break;
  1546. default:
  1547. ASSERT(FALSE);
  1548. break;
  1549. }
  1550. }
  1551. __finally
  1552. {
  1553. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScTrackingISR Exit : 0x%x\n",DRIVER_NAME, status ));
  1554. }
  1555. return status;
  1556. }
  1557. VOID
  1558. UsbScCompleteCardTracking(
  1559. IN PSMARTCARD_EXTENSION SmartcardExtension
  1560. )
  1561. /*++
  1562. Routine Description:
  1563. Checks to see if there is a pending card tracking irp, and completes it if
  1564. necessary.
  1565. Arguments:
  1566. Return Value:
  1567. --*/
  1568. {
  1569. KIRQL ioIrql,
  1570. keIrql;
  1571. PIRP notificationIrp;
  1572. KIRQL cancelIrql;
  1573. __try
  1574. {
  1575. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCompleteCardTracking Enter\n",DRIVER_NAME ));
  1576. // Grab the NotificationIrp
  1577. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  1578. &keIrql);
  1579. notificationIrp = SmartcardExtension->OsData->NotificationIrp;
  1580. SmartcardExtension->OsData->NotificationIrp = NULL;
  1581. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1582. keIrql);
  1583. if (notificationIrp) {
  1584. // Complete the irp
  1585. if (notificationIrp->Cancel) {
  1586. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCompleteCardTracking Irp CANCELLED\n",DRIVER_NAME ));
  1587. notificationIrp->IoStatus.Status = STATUS_CANCELLED;
  1588. } else {
  1589. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScCompleteCardTracking Completing Irp\n",DRIVER_NAME ));
  1590. notificationIrp->IoStatus.Status = STATUS_SUCCESS;
  1591. }
  1592. notificationIrp->IoStatus.Information = 0;
  1593. IoAcquireCancelSpinLock(&cancelIrql);
  1594. // reset the cancel function so that it won't be called anymore
  1595. IoSetCancelRoutine(notificationIrp,
  1596. NULL);
  1597. IoReleaseCancelSpinLock(cancelIrql);
  1598. IoCompleteRequest(notificationIrp,
  1599. IO_NO_INCREMENT);
  1600. }
  1601. }
  1602. __finally
  1603. {
  1604. SmartcardDebug( DEBUG_TRACE, ("%s!TLP3CompleteCardTracking Exit\n",DRIVER_NAME ));
  1605. }
  1606. }
  1607. NTSTATUS
  1608. UsbScVendorIoctl(
  1609. PSMARTCARD_EXTENSION SmartcardExtension
  1610. )
  1611. {
  1612. /*++
  1613. Routine Description:
  1614. Handles vendor specific ioctls, specifically the support for PC_to_RDR_Escape
  1615. Which allows reader vendors to implement their own features and still
  1616. utilize this driver. There is no parameter checking since this is a
  1617. generic pass through, so it is up to the vendor to have a rock-solid
  1618. design.
  1619. Arguments:
  1620. Return Value:
  1621. --*/
  1622. NTSTATUS status = STATUS_UNSUCCESSFUL;
  1623. PUSBSC_OUT_MESSAGE_HEADER header = NULL;
  1624. PUSBSC_IN_MESSAGE_HEADER replyHeader = NULL;
  1625. ULONG replySize;
  1626. ULONG requestSize;
  1627. __try
  1628. {
  1629. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScVendorIoclt Enter\n", DRIVER_NAME ));
  1630. switch (SmartcardExtension->MajorIoControlCode) {
  1631. case IOCTL_CCID_ESCAPE:
  1632. if (!SmartcardExtension->ReaderExtension->EscapeCommandEnabled) {
  1633. SmartcardDebug( DEBUG_ERROR, ("%s!UsbScVendorIoclt Escape Command Not Enabled\n", DRIVER_NAME ));
  1634. status = STATUS_INVALID_DEVICE_REQUEST;
  1635. __leave;
  1636. }
  1637. if ((MAXULONG - sizeof(USBSC_OUT_MESSAGE_HEADER)) < SmartcardExtension->IoRequest.RequestBufferLength) {
  1638. SmartcardDebug( DEBUG_ERROR, ("%s!UsbScVendorIoclt Request Buffer Length is too large\n", DRIVER_NAME ));
  1639. status = STATUS_INVALID_DEVICE_REQUEST;
  1640. __leave;
  1641. }
  1642. if ((MAXULONG - sizeof(USBSC_IN_MESSAGE_HEADER)) < SmartcardExtension->IoRequest.ReplyBufferLength) {
  1643. SmartcardDebug( DEBUG_ERROR, ("%s!UsbScVendorIoclt Reply Buffer Length is too large\n", DRIVER_NAME ));
  1644. status = STATUS_INVALID_DEVICE_REQUEST;
  1645. __leave;
  1646. }
  1647. requestSize = SmartcardExtension->IoRequest.RequestBufferLength + sizeof(USBSC_OUT_MESSAGE_HEADER);
  1648. replySize = SmartcardExtension->IoRequest.ReplyBufferLength + sizeof(USBSC_IN_MESSAGE_HEADER);
  1649. header = ExAllocatePool(NonPagedPool,
  1650. requestSize);
  1651. if (!header) {
  1652. status = STATUS_INSUFFICIENT_RESOURCES;
  1653. __leave;
  1654. }
  1655. RtlZeroMemory(header,
  1656. sizeof(USBSC_OUT_MESSAGE_HEADER));
  1657. replyHeader = ExAllocatePool(NonPagedPool,
  1658. replySize);
  1659. if (!replyHeader) {
  1660. status = STATUS_INSUFFICIENT_RESOURCES;
  1661. __leave;
  1662. }
  1663. header->bMessageType = PC_to_RDR_Escape;
  1664. header->dwLength = SmartcardExtension->IoRequest.RequestBufferLength;
  1665. header->bSlot = 0;
  1666. RtlCopyMemory(&header[1],
  1667. SmartcardExtension->IoRequest.RequestBuffer,
  1668. SmartcardExtension->IoRequest.RequestBufferLength);
  1669. status = UsbScReadWrite(SmartcardExtension,
  1670. header,
  1671. (PUCHAR) replyHeader,
  1672. replySize,
  1673. SmartcardExtension->IoRequest.ReplyBuffer,
  1674. FALSE);
  1675. if (!NT_SUCCESS(status)) {
  1676. __leave;
  1677. }
  1678. if (replyHeader->bMessageType != RDR_to_PC_Escape) {
  1679. SmartcardDebug( DEBUG_ERROR, ("%s!UsbScVendorIoclt reader returned the wrong message type\n", DRIVER_NAME ));
  1680. status = STATUS_DEVICE_PROTOCOL_ERROR;
  1681. __leave;
  1682. }
  1683. *SmartcardExtension->IoRequest.Information = replyHeader->dwLength;
  1684. break;
  1685. default:
  1686. SmartcardDebug( DEBUG_ERROR, ("%s!UsbScVendorIoclt Unsupported Vendor IOCTL\n", DRIVER_NAME ));
  1687. status = STATUS_INVALID_DEVICE_REQUEST;
  1688. break;
  1689. }
  1690. }
  1691. __finally
  1692. {
  1693. if (header) {
  1694. ExFreePool(header);
  1695. }
  1696. if (replyHeader) {
  1697. ExFreePool(replyHeader);
  1698. }
  1699. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScVendorIoclt Exit (0x%x)\n", DRIVER_NAME, status ));
  1700. }
  1701. return status;
  1702. }