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.

997 lines
33 KiB

  1. #include "smartcard.h"
  2. #include "usbreader.h"
  3. #pragma PAGEDCODE
  4. CSmartCard::CSmartCard()
  5. {
  6. debug = kernel->createDebug();
  7. memory = kernel->createMemory();
  8. irp = kernel->createIrp();
  9. lock = kernel->createLock();
  10. system = kernel->createSystem();
  11. if(lock) lock->initializeSpinLock(&CardLock);
  12. poolingIrp = NULL;
  13. };
  14. #pragma PAGEDCODE
  15. CSmartCard::~CSmartCard()
  16. {
  17. TRACE("Destroing SmartCard...\n");
  18. if(memory) memory->dispose();
  19. if(irp) irp->dispose();
  20. if(lock) lock->dispose();
  21. if(system) system->dispose();
  22. if(debug) debug->dispose();
  23. };
  24. #pragma PAGEDCODE
  25. BOOL CSmartCard::smartCardConnect(CUSBReader* reader)
  26. {
  27. TRACE(" Connecting smartcard system...\n");
  28. if(reader)
  29. { // Check if smartCard was already initialized...
  30. if(!reader->isSmartCardInitialized())
  31. {
  32. PSMARTCARD_EXTENSION Smartcard;
  33. NTSTATUS Status;
  34. USHORT Len;
  35. if(isWin98())
  36. {// At this time string should be already initialized
  37. Status = SmartcardCreateLink(&DosDeviceName,&reader->getDeviceName()->m_String);
  38. TRACE("Gemplus USB reader registered with name %ws, status %X\n",DosDeviceName.Buffer,Status);
  39. if(!NT_SUCCESS(Status))
  40. {
  41. TRACE("#### Failed to create Device link! Status %X\n", Status);
  42. return FALSE;
  43. }
  44. }
  45. else
  46. {
  47. TRACE("Registering reader interface at system...\n");
  48. if(!reader->registerDeviceInterface(&GUID_CLASS_SMARTCARD))
  49. {
  50. TRACE("#### Failed to register device interface...\n");
  51. return FALSE;
  52. }
  53. }
  54. Smartcard = reader->getCardExtention();
  55. TRACE("*** Reader reports Smartcard 0x%x\n",Smartcard);
  56. this->reader = reader;
  57. memory->zero(Smartcard,sizeof(SMARTCARD_EXTENSION));
  58. Smartcard->ReaderExtension = (PREADER_EXTENSION)reader;
  59. Smartcard->Version = SMCLIB_VERSION;
  60. // Read the name from reader object!!!!!!!
  61. Len = MAXIMUM_ATTR_STRING_LENGTH;
  62. reader->getVendorName(Smartcard->VendorAttr.VendorName.Buffer,&Len);
  63. Smartcard->VendorAttr.VendorName.Length = Len;
  64. TRACE(" VENDOR NAME - %s\n",Smartcard->VendorAttr.VendorName.Buffer);
  65. Len = MAXIMUM_ATTR_STRING_LENGTH;
  66. reader->getDeviceType(Smartcard->VendorAttr.IfdType.Buffer,&Len);
  67. Smartcard->VendorAttr.IfdType.Length = Len;
  68. TRACE(" DEVICE TYPE - %s\n",Smartcard->VendorAttr.IfdType.Buffer);
  69. // Clk frequency in KHz encoded as little endian integer
  70. Smartcard->ReaderCapabilities.CLKFrequency.Default = SC_IFD_DEFAULT_CLK_FREQUENCY;
  71. Smartcard->ReaderCapabilities.CLKFrequency.Max = SC_IFD_MAXIMUM_CLK_FREQUENCY;
  72. Smartcard->ReaderCapabilities.DataRate.Default = SC_IFD_DEFAULT_DATA_RATE;
  73. Smartcard->ReaderCapabilities.DataRate.Max = SC_IFD_MAXIMUM_DATA_RATE;
  74. // reader could support higher data rates
  75. Smartcard->ReaderCapabilities.DataRatesSupported.List = dataRatesSupported;
  76. Smartcard->ReaderCapabilities.DataRatesSupported.Entries =
  77. sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
  78. Smartcard->VendorAttr.IfdVersion.BuildNumber = 0;
  79. // store firmware revision in ifd version
  80. Smartcard->VendorAttr.IfdVersion.VersionMajor = 0x01;
  81. Smartcard->VendorAttr.IfdVersion.VersionMinor = 0x00;
  82. Smartcard->VendorAttr.IfdSerialNo.Length = 0;
  83. Smartcard->ReaderCapabilities.MaxIFSD = SC_IFD_MAXIMUM_IFSD;
  84. // Now setup information in our deviceExtension
  85. Smartcard->ReaderCapabilities.CurrentState = (ULONG) SCARD_UNKNOWN;
  86. // TODO: get reader type from reader object!!!!!!!!!!!!!!
  87. // Type of Reader - USB
  88. Smartcard->ReaderCapabilities.ReaderType = SCARD_READER_TYPE_USB;
  89. // This reader supports T=0 and T=1
  90. Smartcard->ReaderCapabilities.SupportedProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  91. Smartcard->ReaderCapabilities.MechProperties = 0;
  92. Smartcard->SmartcardRequest.BufferSize = MIN_BUFFER_SIZE;
  93. Smartcard->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
  94. Status = SmartcardInitialize(Smartcard);
  95. if(NT_SUCCESS(Status))
  96. {
  97. // It looks like SmartcardInitialize() resets DeviceObject field,
  98. // So, we have to do it after the call.
  99. Smartcard->VendorAttr.UnitNo = reader->getDeviceNumber();
  100. Smartcard->OsData->DeviceObject = reader->getSystemDeviceObject();
  101. TRACE(" Registered device %d with DeviceObject 0x%x\n",Smartcard->VendorAttr.UnitNo,Smartcard->OsData->DeviceObject);
  102. // (note: RDF_CARD_EJECT and RDF_READER_SWALLOW are not supported)
  103. // Well... Actually I could define methods at smartcard object as
  104. // statics and make a link to them. It will work.
  105. // The reason I created extenal C linkage functions - to
  106. // separate smartcard system and our driver.
  107. // I think driver actually may not care about smartcard extention and all
  108. // settings required by smclib can be done inside our C wrappers and not
  109. // inside driver objects...
  110. Smartcard->ReaderFunction[RDF_TRANSMIT] = smartCard_Transmit;
  111. Smartcard->ReaderFunction[RDF_SET_PROTOCOL] = smartCard_SetProtocol;
  112. Smartcard->ReaderFunction[RDF_CARD_POWER] = smartCard_Power;
  113. Smartcard->ReaderFunction[RDF_CARD_TRACKING] = smartCard_Tracking;
  114. Smartcard->ReaderFunction[RDF_IOCTL_VENDOR] = smartCard_VendorIoctl;
  115. reader->setSmartCardInitialized(TRUE);
  116. TRACE(" ***** SmartCard system was initialized correctly! *****\n\n");
  117. return TRUE;
  118. }
  119. else
  120. {
  121. TRACE(" ##### FAILED to initialize smartcard system...\n");
  122. }
  123. }
  124. else
  125. {
  126. TRACE(" ##### Smartcard system already active...\n");
  127. }
  128. }
  129. else
  130. {
  131. TRACE(" ###### Invalid reader object...\n");
  132. }
  133. return FALSE;
  134. };
  135. #pragma PAGEDCODE
  136. BOOL CSmartCard::smartCardStart()
  137. {
  138. return TRUE;
  139. };
  140. #pragma PAGEDCODE
  141. VOID CSmartCard::smartCardDisconnect()
  142. {
  143. TRACE(" Disconnecting smartcard system...\n");
  144. if(reader)
  145. {
  146. PSMARTCARD_EXTENSION Smartcard;
  147. Smartcard = reader->getCardExtention();
  148. if(Smartcard->OsData && Smartcard->OsData->NotificationIrp)
  149. {
  150. KIRQL keIrql;
  151. PIRP poolingIrp = Smartcard->OsData->NotificationIrp;
  152. TRACE("====== COMPLETING NOTIFICATION IRP %8.8lX \n\n",poolingIrp);
  153. // Guard by spin lock!
  154. lock->acquireSpinLock(&Smartcard->OsData->SpinLock, &keIrql);
  155. Smartcard->OsData->NotificationIrp = NULL;
  156. lock->releaseSpinLock(&Smartcard->OsData->SpinLock, keIrql);
  157. lock->acquireCancelSpinLock(&keIrql);
  158. irp->setCancelRoutine(poolingIrp, NULL);
  159. lock->releaseCancelSpinLock(keIrql);
  160. if (poolingIrp->Cancel) poolingIrp->IoStatus.Status = STATUS_CANCELLED;
  161. else poolingIrp->IoStatus.Status = STATUS_SUCCESS;
  162. poolingIrp->IoStatus.Information = 0;
  163. irp->completeRequest(poolingIrp, IO_NO_INCREMENT);
  164. }
  165. //Unregister the device
  166. if(isWin98())
  167. {
  168. TRACE("****** Removing device object name %ws \n",DosDeviceName.Buffer);
  169. system->deleteSymbolicLink(&DosDeviceName);
  170. }
  171. else
  172. {
  173. TRACE("Setting reader interface state to FALSE...\n");
  174. reader->unregisterDeviceInterface(reader->getDeviceInterfaceName());
  175. }
  176. SmartcardExit(Smartcard);
  177. Smartcard->ReaderExtension = NULL;
  178. reader->setSmartCardInitialized(FALSE);
  179. reader = NULL;
  180. TRACE(" SmartCard system was disconnected...\n");
  181. }
  182. };
  183. // Declare Smclib system callbacks...
  184. #pragma LOCKEDCODE
  185. NTSTATUS smartCard_Transmit(PSMARTCARD_EXTENSION SmartcardExtension)
  186. {
  187. NTSTATUS Status = STATUS_SUCCESS;;
  188. BOOL Read = FALSE;
  189. CUSBReader* Reader = (CUSBReader*) SmartcardExtension->ReaderExtension;
  190. PSCARD_CARD_CAPABILITIES cardCapabilities = &SmartcardExtension->CardCapabilities;
  191. ULONG selectedProtocol = cardCapabilities->Protocol.Selected;
  192. ULONG protocolRequested = ((PSCARD_IO_REQUEST) SmartcardExtension->OsData->CurrentIrp->AssociatedIrp.SystemBuffer)->dwProtocol;
  193. BYTE * pRequest = (BYTE *)SmartcardExtension->SmartcardRequest.Buffer;
  194. BYTE * pReply = (BYTE *)SmartcardExtension->SmartcardReply.Buffer;
  195. ULONG RequestLength = 0;
  196. ULONG ReplyLength = 0;
  197. PAGED_CODE();
  198. DBG_PRINT ("smartCard_Transmit()\n");
  199. if (!Reader || (selectedProtocol != protocolRequested))
  200. {
  201. DBG_PRINT (" smartCard_Transmit requested with invalid device state...\n");
  202. return (STATUS_INVALID_DEVICE_STATE);
  203. }
  204. if (!NT_SUCCESS(Reader->acquireRemoveLock())) return STATUS_INVALID_DEVICE_STATE;
  205. __try
  206. {
  207. //Set the reply buffer length to 0.
  208. *SmartcardExtension->IoRequest.Information = 0;
  209. switch (selectedProtocol)
  210. {
  211. case SCARD_PROTOCOL_T0:
  212. Status = SmartcardT0Request(SmartcardExtension);
  213. RequestLength = SmartcardExtension->SmartcardRequest.BufferLength;
  214. DBG_PRINT("T0 PROTOCOL: request length %d\n",RequestLength);
  215. if (!NT_SUCCESS(Status))
  216. {
  217. DBG_PRINT ("smartCard_Transmit: SmartcardT0Request reports error 0x%x...\n",Status);
  218. __leave;
  219. }
  220. if (SmartcardExtension->T0.Le > 0)
  221. {
  222. if (SmartcardExtension->T0.Le > SC_IFD_T0_MAXIMUM_LEX)
  223. {
  224. DBG_PRINT ("smartCard_Transmit:Expected length is too big - %d\n",SmartcardExtension->T0.Le);
  225. Status = STATUS_BUFFER_TOO_SMALL;
  226. __leave;
  227. }
  228. ReplyLength = SmartcardExtension->SmartcardReply.BufferSize;
  229. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  230. {
  231. __leave;
  232. }
  233. Status = Reader->reader_Read(pRequest,RequestLength,pReply,&ReplyLength);
  234. Reader->reader_set_Idle();
  235. if(!NT_SUCCESS(Status))
  236. {
  237. DBG_PRINT ("smartCard_Transmit: reader_Read() reports error 0x%x\n",Status);
  238. __leave;
  239. }
  240. }
  241. else
  242. {
  243. if (SmartcardExtension->T0.Lc > SC_IFD_T0_MAXIMUM_LC)
  244. {
  245. DBG_PRINT ("smartCard_Transmit:Command length is too big - %d\n",SmartcardExtension->T0.Lc);
  246. Status = STATUS_BUFFER_TOO_SMALL;
  247. __leave;
  248. }
  249. ReplyLength = SmartcardExtension->SmartcardReply.BufferSize;
  250. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  251. {
  252. DBG_PRINT ("smartCard_Transmit:Failed to get idle state...\n");
  253. __leave;
  254. }
  255. if(!pRequest || ! RequestLength)
  256. {
  257. DBG_PRINT("\n Transmit: cardWrite() Buffer %x length %d\n",pRequest,RequestLength);
  258. }
  259. Status = Reader->reader_Write(pRequest,RequestLength,pReply,&ReplyLength);
  260. Reader->reader_set_Idle();
  261. if(!NT_SUCCESS(Status))
  262. {
  263. DBG_PRINT ("smartCard_Transmit: reader_Write() reports error 0x%x\n",Status);
  264. __leave;
  265. }
  266. }
  267. SmartcardExtension->SmartcardReply.BufferLength = ReplyLength;
  268. DBG_PRINT ("T0 Reply length 0x%x\n",ReplyLength);
  269. if(NT_SUCCESS(Status))
  270. {
  271. Status = SmartcardT0Reply(SmartcardExtension);
  272. }
  273. if(!NT_SUCCESS(Status))
  274. {
  275. DBG_PRINT ("smartCard_Transmit: SmartcardT0Reply reports error 0x%x\n",Status);
  276. }
  277. break;
  278. case SCARD_PROTOCOL_T1:
  279. // Loop for the T=1 management
  280. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  281. {
  282. DBG_PRINT ("smartCard_Transmit:Failed to get idle state...\n");
  283. __leave;
  284. }
  285. do
  286. {
  287. // Tell the lib function how many bytes I need for the prologue
  288. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  289. Status = SmartcardT1Request(SmartcardExtension);
  290. RequestLength = SmartcardExtension->SmartcardRequest.BufferLength;
  291. ReplyLength = SmartcardExtension->SmartcardReply.BufferSize;
  292. DBG_PRINT("T1 PROTOCOL: request, expected reply length %d, %d\n",RequestLength,ReplyLength);
  293. if (!NT_SUCCESS(Status))
  294. {
  295. DBG_PRINT ("smartCard_Transmit: SmartcardT1Request reports error 0x%x...\n",Status);
  296. Reader->reader_set_Idle();
  297. __leave;
  298. }
  299. Status = Reader->reader_translate_request(pRequest,RequestLength,pReply,&ReplyLength, cardCapabilities, SmartcardExtension->T1.Wtx);
  300. if(!NT_SUCCESS(Status))
  301. {
  302. DBG_PRINT ("smartCard_Transmit: reader_translate_request() reports error 0x%x\n",Status);
  303. //return Status; no let smartcard assign proper status
  304. }
  305. if (SmartcardExtension->T1.Wtx)
  306. {
  307. // Set the reader BWI to the default value
  308. Reader->setTransparentConfig(cardCapabilities,0);
  309. }
  310. // copy buffer(pass by ptr) n length
  311. SmartcardExtension->SmartcardReply.BufferLength = ReplyLength;
  312. Status = SmartcardT1Reply(SmartcardExtension);
  313. if ((Status != STATUS_MORE_PROCESSING_REQUIRED) && (Status != STATUS_SUCCESS) )
  314. {
  315. DBG_PRINT ("smartCard_Transmit: SmartcardT1Reply reports error 0x%x\n",Status);
  316. }
  317. } while (Status == STATUS_MORE_PROCESSING_REQUIRED);
  318. Reader->reader_set_Idle();
  319. break;
  320. default:
  321. Status = STATUS_DEVICE_PROTOCOL_ERROR;
  322. __leave;
  323. }
  324. }// Try block
  325. __finally
  326. {
  327. Reader->releaseRemoveLock();
  328. }
  329. return Status;
  330. };
  331. #pragma LOCKEDCODE
  332. NTSTATUS smartCard_VendorIoctl(PSMARTCARD_EXTENSION SmartcardExtension)
  333. {
  334. NTSTATUS Status = STATUS_SUCCESS;;
  335. CUSBReader* Reader = (CUSBReader*) SmartcardExtension->ReaderExtension;
  336. ULONG ControlCode = SmartcardExtension->MajorIoControlCode;
  337. PUCHAR pRequest = (PUCHAR) SmartcardExtension->IoRequest.RequestBuffer;
  338. ULONG RequestLength = SmartcardExtension->IoRequest.RequestBufferLength;
  339. PUCHAR pReply = (PUCHAR)SmartcardExtension->IoRequest.ReplyBuffer;
  340. ULONG ReplyLength = SmartcardExtension->IoRequest.ReplyBufferLength;
  341. PAGED_CODE();
  342. DBG_PRINT ("smartCard_VendorIoctl()\n");
  343. if (!Reader)
  344. {
  345. DBG_PRINT ("smartCard_VendorIoctl: Reader is not ready...\n");
  346. return (STATUS_INVALID_DEVICE_STATE);
  347. }
  348. if (!NT_SUCCESS(Reader->acquireRemoveLock())) return STATUS_INVALID_DEVICE_STATE;
  349. *SmartcardExtension->IoRequest.Information = 0;
  350. __try
  351. {
  352. switch(ControlCode)
  353. {
  354. // For IOCTL_SMARTCARD_VENDOR_GET_ATTRIBUTE and IOCTL_VENDOR_SMARTCARD_SET_ATTRIBUTE
  355. // Vendor attribut use by the device
  356. case IOCTL_SMARTCARD_VENDOR_GET_ATTRIBUTE:
  357. case IOCTL_SMARTCARD_VENDOR_SET_ATTRIBUTE:
  358. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  359. {
  360. DBG_PRINT ("smartCard_VendorIoctl:Failed to get idle state...\n");
  361. __leave;
  362. }
  363. Status = Reader->reader_VendorAttribute(ControlCode,pRequest,RequestLength,pReply,&ReplyLength);
  364. Reader->reader_set_Idle();
  365. if(!NT_SUCCESS(Status))
  366. {
  367. DBG_PRINT ("smartCard_VendorIoctl: reader_Attibute reports error 0x%x ...\n", Status);
  368. ReplyLength = 0;
  369. }
  370. *SmartcardExtension->IoRequest.Information = ReplyLength;
  371. break;
  372. // For IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE
  373. // Send a GemCore command to the reader
  374. case IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE:
  375. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  376. {
  377. DBG_PRINT ("smartCard_VendorIoctl:Failed to get idle state...\n");
  378. __leave;
  379. }
  380. Status = Reader->reader_Ioctl(ControlCode,pRequest,RequestLength,pReply,&ReplyLength);
  381. Reader->reader_set_Idle();
  382. if(!NT_SUCCESS(Status))
  383. {
  384. DBG_PRINT ("smartCard_VendorIoctl: cardIoctl reports error 0x%x ...\n", Status);
  385. ReplyLength = 0;
  386. }
  387. *SmartcardExtension->IoRequest.Information = ReplyLength;
  388. break;
  389. // For IOCTL_SMARTCARD_VENDOR_SWITCH_SPEED
  390. // Change reader speed manually
  391. case IOCTL_SMARTCARD_VENDOR_SWITCH_SPEED:
  392. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  393. {
  394. DBG_PRINT ("smartCard_VendorIoctl:Failed to get idle state...\n");
  395. __leave;
  396. }
  397. Status = Reader->reader_SwitchSpeed(ControlCode,pRequest,RequestLength,pReply,&ReplyLength);
  398. Reader->reader_set_Idle();
  399. if(!NT_SUCCESS(Status))
  400. {
  401. DBG_PRINT ("smartCard_VendorIoctl: reader_SwitchSpeed reports error 0x%x ...\n", Status);
  402. ReplyLength = 0;
  403. }
  404. else
  405. {
  406. // Set value inside CardCabilities
  407. BYTE NewTA1 = pRequest[0];
  408. SmartcardExtension->CardCapabilities.Fl = NewTA1 >> 4;
  409. SmartcardExtension->CardCapabilities.Dl = NewTA1 & 0x0F;
  410. // Do not touch ClockRateConversion and BitRateAdjustment!
  411. }
  412. *SmartcardExtension->IoRequest.Information = ReplyLength;
  413. break;
  414. default:
  415. Status = STATUS_NOT_SUPPORTED;
  416. break;
  417. }
  418. }
  419. __finally
  420. {
  421. Reader->releaseRemoveLock();
  422. }
  423. DBG_PRINT ("smartCard_VendorIoctl Exit Status=%x\n", Status);
  424. return Status;
  425. };
  426. #pragma PAGEDCODE
  427. // Examine if ATR identifies a specific mode (presence of TA2).
  428. BOOLEAN CSmartCard::CheckSpecificMode(BYTE* ATR, DWORD ATRLength)
  429. {
  430. DWORD pos, len;
  431. // ATR[1] is T0. Examine precense of TD1.
  432. if (ATR[1] & 0x80)
  433. {
  434. // Find position of TD1.
  435. pos = 2;
  436. if (ATR[1] & 0x10)
  437. pos++;
  438. if (ATR[1] & 0x20)
  439. pos++;
  440. if (ATR[1] & 0x40)
  441. pos++;
  442. // Here ATR[pos] is TD1. Examine presence of TA2.
  443. if (ATR[pos] & 0x10)
  444. {
  445. // To be of any interest an ATR must contains at least
  446. // TS, T0, TA1, TD1, TA2 [+ T1 .. TK] [+ TCK]
  447. // Find the maximum length of uninteresting ATR.
  448. if (ATR[pos] & 0x0F)
  449. len = 5 + (ATR[1] & 0x0F);
  450. else
  451. len = 4 + (ATR[1] & 0x0F); // In protocol T=0 there is no TCK.
  452. if (ATRLength > len) // Interface bytes requires changes.
  453. {
  454. if ((ATR[pos+1] & 0x10) == 0) // TA2 asks to use interface bytes.
  455. {
  456. return TRUE;
  457. }
  458. }
  459. }
  460. }
  461. return FALSE;
  462. } // CheckSpecificMode
  463. #pragma LOCKEDCODE
  464. NTSTATUS smartCard_Power(PSMARTCARD_EXTENSION SmartcardExtension)
  465. {
  466. NTSTATUS Status = STATUS_SUCCESS;;
  467. CUSBReader* Reader = (CUSBReader*) SmartcardExtension->ReaderExtension; //TO CHANGE LATER...
  468. ULONG ControlCode = SmartcardExtension->MinorIoControlCode;
  469. PUCHAR pReply = (PUCHAR)SmartcardExtension->IoRequest.ReplyBuffer;
  470. ULONG ReplyLength = SmartcardExtension->IoRequest.ReplyBufferLength;
  471. KIRQL oldirql;
  472. ULONG State;
  473. CSmartCard* smartcard = NULL;
  474. DBG_PRINT ("smartCard_Power()\n");
  475. if (!Reader)
  476. {
  477. DBG_PRINT ("smartCard_ReaderPower(): Reader is not ready...\n");
  478. return STATUS_INVALID_DEVICE_STATE;
  479. }
  480. if (!NT_SUCCESS(Reader->acquireRemoveLock())) return STATUS_INVALID_DEVICE_STATE;
  481. smartcard = Reader->getSmartCard();
  482. *SmartcardExtension->IoRequest.Information = 0;
  483. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  484. {
  485. DBG_PRINT ("smartCard_Power:Failed to get idle state...\n");
  486. Reader->releaseRemoveLock();
  487. return Status;
  488. }
  489. Status = Reader->reader_Power(ControlCode,pReply,&ReplyLength, FALSE);
  490. Reader->reader_set_Idle();
  491. switch(ControlCode)
  492. {
  493. case SCARD_POWER_DOWN:
  494. {
  495. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  496. {
  497. DBG_PRINT ("smartCard_Power:Failed to get idle state...\n");
  498. Reader->releaseRemoveLock();
  499. return Status;
  500. }
  501. State = Reader->reader_UpdateCardState();
  502. if(smartcard)
  503. {
  504. KeAcquireSpinLock(smartcard->getCardLock(), &oldirql);
  505. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  506. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  507. SmartcardExtension->ReaderCapabilities.CurrentState = State;
  508. KeReleaseSpinLock(smartcard->getCardLock(), oldirql);
  509. }
  510. Reader->reader_set_Idle();
  511. if(!NT_SUCCESS(Status))
  512. {
  513. DBG_PRINT ("smartCard_ReaderPower: cardPower down reports error 0x%x ...\n", Status);
  514. }
  515. Reader->releaseRemoveLock();
  516. return Status;
  517. }
  518. break;
  519. case SCARD_COLD_RESET:
  520. case SCARD_WARM_RESET:
  521. if(!NT_SUCCESS(Status))
  522. {
  523. DBG_PRINT ("smartCard_ReaderPower: cardPower up reports error 0x%x ...\n", Status);
  524. *SmartcardExtension->IoRequest.Information = 0;
  525. KeAcquireSpinLock(smartcard->getCardLock(), &oldirql);
  526. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  527. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  528. if(Status==STATUS_NO_MEDIA)
  529. {
  530. DBG_PRINT("############# Reporting CARD ABSENT!... #############\n");
  531. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  532. }
  533. KeReleaseSpinLock(smartcard->getCardLock(), oldirql);
  534. Reader->releaseRemoveLock();
  535. return Status;
  536. }
  537. if(pReply && ReplyLength && (pReply[0]==0x3B || pReply[0]==0x3F) )
  538. {
  539. if ((SmartcardExtension->SmartcardReply.BufferSize>=ReplyLength) &&
  540. (sizeof(SmartcardExtension->CardCapabilities.ATR.Buffer)>=ReplyLength))
  541. {
  542. DBG_PRINT("Setting SMCLIB info...\n");
  543. // Set information...
  544. *SmartcardExtension->IoRequest.Information = ReplyLength;
  545. // Set reply...
  546. RtlCopyMemory(SmartcardExtension->SmartcardReply.Buffer,pReply,ReplyLength);
  547. SmartcardExtension->SmartcardReply.BufferLength = ReplyLength;
  548. // Set ATR...
  549. RtlCopyMemory(SmartcardExtension->CardCapabilities.ATR.Buffer,pReply,ReplyLength);
  550. SmartcardExtension->CardCapabilities.ATR.Length = (UCHAR) ReplyLength;
  551. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  552. // Parse the ATR string in order to check if it as valid
  553. // and to find out if the card uses invers convention
  554. Status = SmartcardUpdateCardCapabilities(SmartcardExtension);
  555. if(!NT_SUCCESS(Status))
  556. {
  557. DBG_PRINT("UpdateCardCaps() reports error 0x%x\n", Status);
  558. Status = 0;
  559. }
  560. // Check if Specific mode is present in TA2
  561. DBG_PRINT("=========== Checking specific mode....\n");
  562. if(smartcard->CheckSpecificMode(SmartcardExtension->CardCapabilities.ATR.Buffer,
  563. SmartcardExtension->CardCapabilities.ATR.Length))
  564. { // Use automatic protocol switching!
  565. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  566. {
  567. DBG_PRINT ("smartCard_Power:Failed to get idle state...\n");
  568. Reader->releaseRemoveLock();
  569. return Status;
  570. }
  571. Status = Reader->reader_Power(ControlCode,pReply,&ReplyLength, TRUE);
  572. Reader->reader_set_Idle();
  573. }
  574. }
  575. else
  576. {
  577. // ERROR!!!!!
  578. Status = STATUS_BUFFER_TOO_SMALL;
  579. *SmartcardExtension->IoRequest.Information = 0;
  580. DBG_PRINT ("smartCard_ReaderPower: Failed to copy ATR because of short ATR or Reply buffer...\n");
  581. }
  582. }
  583. else
  584. {
  585. //ERROR!!!!
  586. Status = STATUS_UNRECOGNIZED_MEDIA;
  587. *SmartcardExtension->IoRequest.Information = 0;
  588. DBG_PRINT ("smartCard_ReaderPower: Failed to get card ATR...\n");
  589. KeAcquireSpinLock(smartcard->getCardLock(), &oldirql);
  590. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  591. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  592. KeReleaseSpinLock(smartcard->getCardLock(), oldirql);
  593. }
  594. Reader->releaseRemoveLock();
  595. return Status;
  596. break;
  597. }
  598. Reader->releaseRemoveLock();
  599. return STATUS_INVALID_PARAMETER;
  600. };
  601. #pragma LOCKEDCODE
  602. NTSTATUS smartCard_SetProtocol(PSMARTCARD_EXTENSION SmartcardExtension)
  603. {
  604. NTSTATUS Status = STATUS_SUCCESS;;
  605. CUSBReader* Reader = (CUSBReader*) SmartcardExtension->ReaderExtension;
  606. ULONG ProtocolMask = SmartcardExtension->MinorIoControlCode;
  607. PAGED_CODE();
  608. DBG_PRINT ("smartCard_SetProtocol()\n");
  609. *SmartcardExtension->IoRequest.Information = 0;
  610. if (!Reader)
  611. {
  612. DBG_PRINT ("######## smartCard_SetProtocol: Reader is not ready...\n");
  613. return (STATUS_INVALID_DEVICE_STATE);
  614. }
  615. if (!NT_SUCCESS(Reader->acquireRemoveLock())) return STATUS_INVALID_DEVICE_STATE;
  616. if(SmartcardExtension->CardCapabilities.Protocol.Supported & ProtocolMask & SCARD_PROTOCOL_T1)
  617. DBG_PRINT ("******* T1 PROTOCOL REQUESTED ******\n");
  618. if(SmartcardExtension->CardCapabilities.Protocol.Supported & ProtocolMask & SCARD_PROTOCOL_T0)
  619. DBG_PRINT ("******* T0 PROTOCOL REQUESTED ******\n");
  620. // Check if the card is already in specific state
  621. // and if the caller wants to have the already selected protocol.
  622. // We return success if this is the case.
  623. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC &&
  624. (SmartcardExtension->CardCapabilities.Protocol.Selected & ProtocolMask))
  625. {
  626. DBG_PRINT ("Requested protocol %d already was setted.\n",SmartcardExtension->CardCapabilities.Protocol.Selected);
  627. Reader->releaseRemoveLock();
  628. return STATUS_SUCCESS;
  629. }
  630. if(!NT_SUCCESS(Status = Reader->reader_WaitForIdleAndBlock()))
  631. {
  632. Reader->releaseRemoveLock();
  633. return Status;
  634. }
  635. do {
  636. // Select T=1 or T=0 and indicate that pts1 follows
  637. // What is the protocol selected
  638. DBG_PRINT ("Smartcard: SetProtocol Loop\n");
  639. if(SmartcardExtension->CardCapabilities.Protocol.Supported & ProtocolMask & SCARD_PROTOCOL_T1)
  640. {
  641. DBG_PRINT ("******* SETTING T1 PROTOCOL ******\n");
  642. Status = Reader->reader_SetProtocol(SCARD_PROTOCOL_T1, PROTOCOL_MODE_MANUALLY);
  643. if(NT_SUCCESS(Status))
  644. {
  645. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;
  646. DBG_PRINT ("******* T1 PROTOCOL WAS SET ******\n");
  647. }
  648. } else if(SmartcardExtension->CardCapabilities.Protocol.Supported & ProtocolMask & SCARD_PROTOCOL_T0)
  649. {
  650. // T0 selection
  651. DBG_PRINT ("******* SETTING T0 PROTOCOL ******\n");
  652. Status = Reader->reader_SetProtocol(SCARD_PROTOCOL_T0, PROTOCOL_MODE_MANUALLY);
  653. if(NT_SUCCESS(Status))
  654. {
  655. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
  656. DBG_PRINT ("******* T0 PROTOCOL WAS SET ******\n");
  657. }
  658. }
  659. else
  660. {
  661. Status = STATUS_INVALID_DEVICE_REQUEST;
  662. DBG_PRINT ("smartCard_SetProtocol: BAD protocol selection...\n");
  663. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  664. // close only once
  665. Reader->reader_set_Idle();
  666. Reader->releaseRemoveLock();
  667. return Status;
  668. }
  669. // Fail to negociate PPS, try PTS_TYPE_DEFAULT
  670. if( ! NT_SUCCESS(Status))
  671. {
  672. if (SmartcardExtension->CardCapabilities.PtsData.Type != PTS_TYPE_DEFAULT)
  673. {
  674. DBG_PRINT ("Smartcard: SetProtocol: PPS failed. Trying default parameters...\n");
  675. //
  676. // The card did either NOT reply or it replied incorrectly
  677. // so try default values.
  678. // Set PtsData Type to Default and do a cold reset
  679. //
  680. SmartcardExtension->CardCapabilities.PtsData.Type = PTS_TYPE_DEFAULT;
  681. Status = Reader->reader_SetProtocol(ProtocolMask, PROTOCOL_MODE_DEFAULT);
  682. if(NT_SUCCESS(Status))
  683. {
  684. Status = SmartcardUpdateCardCapabilities(SmartcardExtension);
  685. }
  686. if(NT_SUCCESS(Status))
  687. {
  688. DBG_PRINT ("Smartcard: SetProtocol PPS default succeed, TRY AGAIN\n");
  689. Status = STATUS_MORE_PROCESSING_REQUIRED;
  690. }
  691. }
  692. }
  693. } while ( Status == STATUS_MORE_PROCESSING_REQUIRED );
  694. if(NT_SUCCESS(Status))
  695. {
  696. DBG_PRINT ("smartCard_SetProtocol: SUCCCESS Finish transaction\n");
  697. // Now indicate that we're in specific mode
  698. // and return the selected protocol to the caller
  699. //
  700. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
  701. *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer =
  702. SmartcardExtension->CardCapabilities.Protocol.Selected;
  703. *SmartcardExtension->IoRequest.Information =
  704. sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
  705. }
  706. else
  707. {
  708. Status = STATUS_DEVICE_PROTOCOL_ERROR;
  709. // We failed to connect at any protocol. Just report error.
  710. DBG_PRINT ("smartCard_SetProtocol: Failed to set any protocol...\n");
  711. SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
  712. }
  713. // Unblock set protocol
  714. Reader->reader_set_Idle();
  715. Reader->releaseRemoveLock();
  716. return Status;
  717. };
  718. // Callback function to cancel tracking Irp
  719. #pragma LOCKEDCODE
  720. NTSTATUS smartCard_CancelTracking(PDEVICE_OBJECT DeviceObject, PIRP Irp)
  721. { // OnCancelPendingIoctl
  722. CUSBReader* Reader = (CUSBReader*)DeviceObject->DeviceExtension;
  723. PIRP notificationIrp;
  724. CSmartCard* card = NULL;
  725. PSMARTCARD_EXTENSION SmartcardExtention = NULL;
  726. KIRQL ioIrql;
  727. KIRQL keIrql;
  728. DBG_PRINT ("######### SmartCard: Cancelling card tracking...\n");
  729. DBG_PRINT ("######### SmartCard: DeviceObject reported - 0x%x, IRP - 0x%x\n",DeviceObject,Irp);
  730. DBG_PRINT ("######### SmartCard: Reader reported - 0x%x\n",Reader);
  731. if (!NT_SUCCESS(Reader->acquireRemoveLock())) return STATUS_INVALID_DEVICE_STATE;
  732. notificationIrp = NULL;
  733. card = Reader->getSmartCard();
  734. notificationIrp = card->getPoolingIrp();
  735. SmartcardExtention = Reader->getCardExtention();
  736. ASSERT(Irp == notificationIrp);
  737. IoReleaseCancelSpinLock(Irp->CancelIrql);
  738. DBG_PRINT("######### SmartCard: notificationIrp - 0x%x\n",Irp);
  739. KeAcquireSpinLock(&SmartcardExtention->OsData->SpinLock,&keIrql);
  740. notificationIrp = SmartcardExtention->OsData->NotificationIrp;
  741. SmartcardExtention->OsData->NotificationIrp = NULL;
  742. KeReleaseSpinLock(&SmartcardExtention->OsData->SpinLock,keIrql);
  743. if (notificationIrp)
  744. {
  745. DBG_PRINT("####### CancelTracking: Completing NotificationIrp %lxh\n",notificationIrp);
  746. IoAcquireCancelSpinLock(&ioIrql);
  747. IoSetCancelRoutine(notificationIrp, NULL);
  748. IoReleaseCancelSpinLock(ioIrql);
  749. // finish the request
  750. notificationIrp->IoStatus.Status = STATUS_CANCELLED;
  751. notificationIrp->IoStatus.Information = 0;
  752. IoCompleteRequest(notificationIrp, IO_NO_INCREMENT);
  753. }
  754. Reader->releaseRemoveLock();
  755. return STATUS_CANCELLED;
  756. }
  757. #pragma LOCKEDCODE
  758. NTSTATUS smartCard_Tracking(PSMARTCARD_EXTENSION Smartcard)
  759. {
  760. KIRQL oldIrql;
  761. CUSBReader* Reader = (CUSBReader*) Smartcard->ReaderExtension;
  762. DBG_PRINT ("SmartCard: Card tracking...\n");
  763. if (!Reader) return STATUS_INVALID_DEVICE_STATE;
  764. if (!NT_SUCCESS(Reader->acquireRemoveLock())) return STATUS_INVALID_DEVICE_STATE;
  765. if(Smartcard->MajorIoControlCode == IOCTL_SMARTCARD_IS_PRESENT)
  766. {
  767. Reader->setNotificationState(SCARD_SWALLOWED);
  768. DBG_PRINT ("SmartCard: WAITING FOR INSERTION!\n");
  769. }
  770. else
  771. {
  772. Reader->setNotificationState(SCARD_ABSENT);
  773. DBG_PRINT ("SmartCard: WAITING FOR REMOVAL!\n");
  774. }
  775. if(!Smartcard->OsData || !Smartcard->OsData->NotificationIrp)
  776. {
  777. DBG_PRINT ("SmartCard: ========== CARD TRACKING CALLED WITH ZERO IRP!!!!!\n");
  778. Reader->releaseRemoveLock();
  779. return STATUS_INVALID_DEVICE_STATE;
  780. }
  781. DBG_PRINT("######### SmartCard: POOLING IRP - %8.8lX \n",Smartcard->OsData->NotificationIrp);
  782. CSmartCard* card = Reader->getSmartCard();
  783. IoAcquireCancelSpinLock(&oldIrql);
  784. IoSetCancelRoutine(Smartcard->OsData->NotificationIrp, smartCard_CancelTracking);
  785. IoReleaseCancelSpinLock(oldIrql);
  786. if(card) card->setPoolingIrp(Smartcard->OsData->NotificationIrp);
  787. Reader->releaseRemoveLock();
  788. return STATUS_PENDING;
  789. };
  790. #pragma PAGEDCODE
  791. VOID CSmartCard::completeCardTracking()
  792. {
  793. PSMARTCARD_EXTENSION Smartcard;
  794. ULONG CurrentState;
  795. ULONG ExpectedState;
  796. KIRQL ioIrql;
  797. KIRQL keIrql;
  798. PIRP poolingIrp;
  799. //DEBUG_START();//Force to debug even if thread disabled it...
  800. TRACE("SmartCard: completeCardTracking() ...\n");
  801. Smartcard = reader->getCardExtention();
  802. CurrentState = reader->getCardState();
  803. ExpectedState = reader->getNotificationState();
  804. TRACE("SMCLIB Card state is %x\n",Smartcard->ReaderCapabilities.CurrentState);
  805. TRACE("Current Card state is %x\n",CurrentState);
  806. TRACE("ExpectedState is %x\n",ExpectedState);
  807. if(Smartcard && Smartcard->OsData)
  808. {
  809. lock->acquireSpinLock(&Smartcard->OsData->SpinLock, &keIrql);
  810. if(CurrentState < SCARD_SWALLOWED)
  811. {
  812. Smartcard->ReaderCapabilities.CurrentState = CurrentState;
  813. }
  814. else
  815. {
  816. if(Smartcard->ReaderCapabilities.CurrentState<=SCARD_SWALLOWED)
  817. {
  818. Smartcard->ReaderCapabilities.CurrentState = CurrentState;
  819. }
  820. }
  821. TRACE("NEW SMCLIB card state is %x\n",Smartcard->ReaderCapabilities.CurrentState);
  822. lock->releaseSpinLock(&Smartcard->OsData->SpinLock, keIrql);
  823. }
  824. poolingIrp = NULL;
  825. if((ExpectedState!= SCARD_UNKNOWN) && (ExpectedState == CurrentState))
  826. {
  827. DEBUG_START();//Force to debug even if thread disabled it...
  828. TRACE("\n=======Expected state %d is reached=====\n\n",ExpectedState);
  829. // Desired state reached...
  830. if(Smartcard->OsData && Smartcard->OsData->NotificationIrp)
  831. {
  832. setPoolingIrp(NULL);
  833. reader->setNotificationState(SCARD_UNKNOWN);
  834. TRACE("====== COMPLETING NOTIFICATION =========\n");
  835. // Finish requested notification!.....
  836. lock->acquireSpinLock(&Smartcard->OsData->SpinLock, &keIrql);
  837. poolingIrp = Smartcard->OsData->NotificationIrp;
  838. lock->releaseSpinLock(&Smartcard->OsData->SpinLock, keIrql);
  839. if(poolingIrp)
  840. {
  841. TRACE("====== COMPLETING NOTIFICATION IRP %8.8lX \n\n",poolingIrp);
  842. lock->acquireCancelSpinLock(&ioIrql);
  843. irp->setCancelRoutine(poolingIrp, NULL);
  844. lock->releaseCancelSpinLock(ioIrql);
  845. if(poolingIrp->Cancel)
  846. poolingIrp->IoStatus.Status = STATUS_CANCELLED;
  847. else
  848. poolingIrp->IoStatus.Status = STATUS_SUCCESS;
  849. poolingIrp->IoStatus.Information = 0;
  850. lock->acquireSpinLock(&Smartcard->OsData->SpinLock, &keIrql);
  851. Smartcard->OsData->NotificationIrp = NULL;
  852. lock->releaseSpinLock(&Smartcard->OsData->SpinLock, keIrql);
  853. irp->completeRequest(poolingIrp,IO_NO_INCREMENT);
  854. }
  855. }
  856. }
  857. }