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.

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