Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2006 lines
49 KiB

  1. /*++
  2. Copyright (c) 1998 SCM Microsystems, Inc.
  3. Module Name:
  4. StcUsbNT.c
  5. Abstract:
  6. Main Driver Module - WDM Version
  7. Revision History:
  8. PP 1.01 01/19/1998 Initial Version
  9. PP 1.00 12/18/1998 Initial Version
  10. --*/
  11. #include <ntstatus.h>
  12. #include <wdm.h>
  13. #include <usbdi.h>
  14. #include <usbdlib.h>
  15. #include <usb100.h>
  16. #include <common.h>
  17. #include <stcCmd.h>
  18. #include <stcCB.h>
  19. #include <stcusblg.h>
  20. #include <usbcom.h>
  21. #include <stcusbnt.h>
  22. #pragma alloc_text(INIT, DriverEntry)
  23. #pragma alloc_text(PAGEABLE, StcUsbAddDevice)
  24. #pragma alloc_text(PAGEABLE, StcUsbCreateDevice)
  25. #pragma alloc_text(PAGEABLE, StcUsbStartDevice)
  26. #pragma alloc_text(PAGEABLE, StcUsbUnloadDriver)
  27. #pragma alloc_text(PAGEABLE, StcUsbCreateClose)
  28. extern const STC_REGISTER STCInitialize[];
  29. extern const STC_REGISTER STCClose[];
  30. NTSTATUS
  31. DriverEntry(
  32. PDRIVER_OBJECT DriverObject,
  33. PUNICODE_STRING RegistryPath )
  34. /*++
  35. DriverEntry:
  36. entry function of the driver. setup the callbacks for the OS and try to
  37. initialize a device object for every device in the system
  38. Arguments:
  39. DriverObject context of the driver
  40. RegistryPath path to the registry entry for the driver
  41. Return Value:
  42. STATUS_SUCCESS
  43. STATUS_UNSUCCESSFUL
  44. --*/
  45. {
  46. // SmartcardSetDebugLevel( DEBUG_DRIVER | DEBUG_TRACE );
  47. SmartcardDebug(
  48. DEBUG_DRIVER,
  49. ("------------------------------------------------------------------\n" )
  50. );
  51. SmartcardDebug(
  52. DEBUG_DRIVER,
  53. ("%s!DriverEntry: Enter - %s %s\n",
  54. DRIVER_NAME,
  55. __DATE__,
  56. __TIME__));
  57. SmartcardDebug(
  58. DEBUG_DRIVER,
  59. ("------------------------------------------------------------------\n" )
  60. );
  61. // tell the system our entry points
  62. DriverObject->MajorFunction[IRP_MJ_CREATE] = StcUsbCreateClose;
  63. DriverObject->MajorFunction[IRP_MJ_CLOSE] = StcUsbCreateClose;
  64. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = StcUsbDeviceIoControl;
  65. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = StcUsbSystemControl;
  66. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = StcUsbCleanup;
  67. DriverObject->MajorFunction[IRP_MJ_PNP] = StcUsbPnP;
  68. DriverObject->MajorFunction[IRP_MJ_POWER] = StcUsbPower;
  69. DriverObject->DriverExtension->AddDevice = StcUsbAddDevice;
  70. DriverObject->DriverUnload = StcUsbUnloadDriver;
  71. SmartcardDebug(
  72. DEBUG_TRACE,
  73. ("%s!DriverEntry: Exit\n",
  74. DRIVER_NAME));
  75. return STATUS_SUCCESS;;
  76. }
  77. NTSTATUS
  78. StcUsbAddDevice(
  79. IN PDRIVER_OBJECT DriverObject,
  80. IN PDEVICE_OBJECT PhysicalDeviceObject)
  81. /*++
  82. Routine Description:
  83. creates a new device object for the driver, allocates & initializes all
  84. neccessary structures (i.e. SmartcardExtension & ReaderExtension).
  85. Arguments:
  86. DriverObject context of call
  87. DeviceObject ptr to the created device object
  88. Return Value:
  89. STATUS_SUCCESS
  90. STATUS_INSUFFICIENT_RESOURCES
  91. status returned by smclib.sys
  92. --*/
  93. {
  94. NTSTATUS status;
  95. UNICODE_STRING DriverID;
  96. PDEVICE_OBJECT DeviceObject = NULL;
  97. PDEVICE_EXTENSION DeviceExtension = NULL;
  98. PREADER_EXTENSION ReaderExtension = NULL;
  99. PSMARTCARD_EXTENSION SmartcardExtension = NULL;
  100. UNICODE_STRING vendorNameU, ifdTypeU;
  101. ANSI_STRING vendorNameA, ifdTypeA;
  102. HANDLE regKey = NULL;
  103. // this is a list of our supported data rates
  104. static ULONG dataRatesSupported[] = { 9600, 19200, 38400, 55800, 115200 };
  105. PAGED_CODE();
  106. SmartcardDebug(
  107. DEBUG_TRACE,
  108. ( "%s!StcUsbAddDevice: Enter\n",
  109. DRIVER_NAME));
  110. try
  111. {
  112. ULONG deviceInstance;
  113. RTL_QUERY_REGISTRY_TABLE parameters[3];
  114. RtlZeroMemory(parameters, sizeof(parameters));
  115. RtlZeroMemory(&vendorNameU, sizeof(vendorNameU));
  116. RtlZeroMemory(&ifdTypeU, sizeof(ifdTypeU));
  117. RtlZeroMemory(&vendorNameA, sizeof(vendorNameA));
  118. RtlZeroMemory(&ifdTypeA, sizeof(ifdTypeA));
  119. // Create the device object
  120. status = IoCreateDevice(
  121. DriverObject,
  122. sizeof(DEVICE_EXTENSION),
  123. NULL,
  124. FILE_DEVICE_SMARTCARD,
  125. 0,
  126. TRUE,
  127. &DeviceObject);
  128. if (status != STATUS_SUCCESS)
  129. {
  130. SmartcardLogError(
  131. DriverObject,
  132. STCUSB_INSUFFICIENT_RESOURCES,
  133. NULL,
  134. 0);
  135. __leave;
  136. }
  137. // set up the device extension.
  138. DeviceExtension = DeviceObject->DeviceExtension;
  139. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  140. SmartcardExtension->VendorAttr.UnitNo = MAXULONG;
  141. for (deviceInstance = 0; deviceInstance < MAXULONG; deviceInstance++) {
  142. PDEVICE_OBJECT devObj;
  143. for (devObj = DeviceObject;
  144. devObj != NULL;
  145. devObj = devObj->NextDevice) {
  146. PDEVICE_EXTENSION devExt = devObj->DeviceExtension;
  147. PSMARTCARD_EXTENSION smcExt = &devExt->SmartcardExtension;
  148. if (deviceInstance == smcExt->VendorAttr.UnitNo) {
  149. break;
  150. }
  151. }
  152. if (devObj == NULL) {
  153. SmartcardExtension->VendorAttr.UnitNo = deviceInstance;
  154. SmartcardExtension->ReaderCapabilities.Channel = deviceInstance;
  155. break;
  156. }
  157. }
  158. // Used to synchonize the smartcard detection polling
  159. // with the the IO Control routine
  160. KeInitializeMutex(
  161. &DeviceExtension->hMutex,
  162. 1);
  163. // Used for stop / start notification
  164. KeInitializeEvent(
  165. &DeviceExtension->ReaderStarted,
  166. NotificationEvent,
  167. FALSE);
  168. // Used to control the poll thread
  169. KeInitializeEvent(
  170. &DeviceExtension->FinishPollThread,
  171. NotificationEvent,
  172. FALSE
  173. );
  174. KeInitializeEvent(
  175. &DeviceExtension->PollThreadStopped,
  176. NotificationEvent,
  177. FALSE
  178. );
  179. DeviceExtension->PollWorkItem = IoAllocateWorkItem( DeviceObject );
  180. if( DeviceExtension->PollWorkItem == NULL )
  181. {
  182. status = STATUS_INSUFFICIENT_RESOURCES;
  183. __leave;
  184. }
  185. // allocate the reader extension
  186. ReaderExtension = ExAllocatePool(
  187. NonPagedPool,
  188. sizeof( READER_EXTENSION ));
  189. if( ReaderExtension == NULL )
  190. {
  191. SmartcardLogError(
  192. DriverObject,
  193. STCUSB_INSUFFICIENT_RESOURCES,
  194. NULL,
  195. 0);
  196. status = STATUS_INSUFFICIENT_RESOURCES;
  197. __leave;
  198. }
  199. RtlZeroMemory( ReaderExtension, sizeof( READER_EXTENSION ));
  200. SmartcardExtension->ReaderExtension = ReaderExtension;
  201. SmartcardExtension->ReaderExtension->DeviceObject = DeviceObject;
  202. // setup smartcard extension - callback's
  203. SmartcardExtension->ReaderFunction[RDF_CARD_POWER] = CBCardPower;
  204. SmartcardExtension->ReaderFunction[RDF_TRANSMIT] = CBTransmit;
  205. SmartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = CBCardTracking;
  206. SmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = CBSetProtocol;
  207. // setup smartcard extension - vendor attribute
  208. RtlCopyMemory(
  209. SmartcardExtension->VendorAttr.VendorName.Buffer,
  210. STCUSB_VENDOR_NAME,
  211. sizeof( STCUSB_VENDOR_NAME ));
  212. SmartcardExtension->VendorAttr.VendorName.Length =
  213. sizeof( STCUSB_VENDOR_NAME );
  214. RtlCopyMemory(
  215. SmartcardExtension->VendorAttr.IfdType.Buffer,
  216. STCUSB_PRODUCT_NAME,
  217. sizeof( STCUSB_PRODUCT_NAME ));
  218. SmartcardExtension->VendorAttr.IfdType.Length =
  219. sizeof( STCUSB_PRODUCT_NAME );
  220. SmartcardExtension->VendorAttr.IfdVersion.BuildNumber = 0;
  221. // store firmware revision in ifd version
  222. SmartcardExtension->VendorAttr.IfdVersion.VersionMajor =
  223. ReaderExtension->FirmwareMajor;
  224. SmartcardExtension->VendorAttr.IfdVersion.VersionMinor =
  225. ReaderExtension->FirmwareMinor;
  226. SmartcardExtension->VendorAttr.IfdSerialNo.Length = 0;
  227. // setup smartcard extension - reader capabilities
  228. SmartcardExtension->ReaderCapabilities.SupportedProtocols =
  229. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  230. SmartcardExtension->ReaderCapabilities.ReaderType =
  231. SCARD_READER_TYPE_USB;
  232. SmartcardExtension->ReaderCapabilities.MechProperties = 0;
  233. // Clk frequency in KHz encoded as little endian integer
  234. SmartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3571;
  235. SmartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3571;
  236. SmartcardExtension->ReaderCapabilities.DataRate.Default =
  237. SmartcardExtension->ReaderCapabilities.DataRate.Max = dataRatesSupported[0];
  238. // reader could support higher data rates
  239. SmartcardExtension->ReaderCapabilities.DataRatesSupported.List =
  240. dataRatesSupported;
  241. SmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
  242. sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
  243. // enter correct version of the lib
  244. SmartcardExtension->Version = SMCLIB_VERSION;
  245. SmartcardExtension->SmartcardRequest.BufferSize = MIN_BUFFER_SIZE;
  246. SmartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
  247. SmartcardExtension->ReaderCapabilities.MaxIFSD = 128; // 254 does not work. SCM should figure out why.
  248. SmartcardExtension->ReaderExtension->ReaderPowerState =
  249. PowerReaderWorking;
  250. status = SmartcardInitialize(SmartcardExtension);
  251. if (status != STATUS_SUCCESS)
  252. {
  253. SmartcardLogError(
  254. DriverObject,
  255. STCUSB_INSUFFICIENT_RESOURCES,
  256. NULL,
  257. 0);
  258. __leave;
  259. }
  260. // tell the lib our device object
  261. SmartcardExtension->OsData->DeviceObject = DeviceObject;
  262. DeviceExtension->AttachedPDO = IoAttachDeviceToDeviceStack(
  263. DeviceObject,
  264. PhysicalDeviceObject);
  265. ASSERT(DeviceExtension->AttachedPDO != NULL);
  266. if (DeviceExtension->AttachedPDO == NULL)
  267. {
  268. status = STATUS_UNSUCCESSFUL;
  269. __leave;
  270. }
  271. // register our new device
  272. status = IoRegisterDeviceInterface(
  273. PhysicalDeviceObject,
  274. &SmartCardReaderGuid,
  275. NULL,
  276. &DeviceExtension->DeviceName);
  277. ASSERT(status == STATUS_SUCCESS);
  278. DeviceObject->Flags |= DO_BUFFERED_IO;
  279. DeviceObject->Flags |= DO_POWER_PAGABLE;
  280. DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  281. //
  282. // try to read the reader name from the registry
  283. // if that does not work, we will use the default
  284. // (hardcoded) name
  285. //
  286. if (IoOpenDeviceRegistryKey(
  287. PhysicalDeviceObject,
  288. PLUGPLAY_REGKEY_DEVICE,
  289. KEY_READ,
  290. &regKey
  291. ) != STATUS_SUCCESS) {
  292. __leave;
  293. }
  294. parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  295. parameters[0].Name = L"VendorName";
  296. parameters[0].EntryContext = &vendorNameU;
  297. parameters[0].DefaultType = REG_SZ;
  298. parameters[0].DefaultData = &vendorNameU;
  299. parameters[0].DefaultLength = 0;
  300. parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  301. parameters[1].Name = L"IfdType";
  302. parameters[1].EntryContext = &ifdTypeU;
  303. parameters[1].DefaultType = REG_SZ;
  304. parameters[1].DefaultData = &ifdTypeU;
  305. parameters[1].DefaultLength = 0;
  306. if (RtlQueryRegistryValues(
  307. RTL_REGISTRY_HANDLE,
  308. (PWSTR) regKey,
  309. parameters,
  310. NULL,
  311. NULL
  312. ) != STATUS_SUCCESS) {
  313. __leave;
  314. }
  315. if (RtlUnicodeStringToAnsiString(
  316. &vendorNameA,
  317. &vendorNameU,
  318. TRUE
  319. ) != STATUS_SUCCESS) {
  320. __leave;
  321. }
  322. if (RtlUnicodeStringToAnsiString(
  323. &ifdTypeA,
  324. &ifdTypeU,
  325. TRUE
  326. ) != STATUS_SUCCESS) {
  327. __leave;
  328. }
  329. if (vendorNameA.Length == 0 ||
  330. vendorNameA.Length > MAXIMUM_ATTR_STRING_LENGTH ||
  331. ifdTypeA.Length == 0 ||
  332. ifdTypeA.Length > MAXIMUM_ATTR_STRING_LENGTH) {
  333. __leave;
  334. }
  335. RtlCopyMemory(
  336. SmartcardExtension->VendorAttr.VendorName.Buffer,
  337. vendorNameA.Buffer,
  338. vendorNameA.Length
  339. );
  340. SmartcardExtension->VendorAttr.VendorName.Length =
  341. vendorNameA.Length;
  342. RtlCopyMemory(
  343. SmartcardExtension->VendorAttr.IfdType.Buffer,
  344. ifdTypeA.Buffer,
  345. ifdTypeA.Length
  346. );
  347. SmartcardExtension->VendorAttr.IfdType.Length =
  348. ifdTypeA.Length;
  349. }
  350. __finally
  351. {
  352. if (vendorNameU.Buffer) {
  353. RtlFreeUnicodeString(&vendorNameU);
  354. }
  355. if (ifdTypeU.Buffer) {
  356. RtlFreeUnicodeString(&ifdTypeU);
  357. }
  358. if (vendorNameA.Buffer) {
  359. RtlFreeAnsiString(&vendorNameA);
  360. }
  361. if (ifdTypeA.Buffer) {
  362. RtlFreeAnsiString(&ifdTypeA);
  363. }
  364. if (regKey != NULL) {
  365. ZwClose(regKey);
  366. }
  367. if (status != STATUS_SUCCESS)
  368. {
  369. StcUsbUnloadDevice(DeviceObject);
  370. }
  371. SmartcardDebug(
  372. DEBUG_TRACE,
  373. ( "%s!StcUsbAddDevice: Exit %x\n",
  374. DRIVER_NAME,
  375. status ));
  376. }
  377. return status;
  378. }
  379. NTSTATUS
  380. StcUsbStartDevice(
  381. PDEVICE_OBJECT DeviceObject
  382. )
  383. /*++
  384. Routine Description:
  385. get the actual configuration from the USB communication layer
  386. and initializes the reader hardware
  387. Arguments:
  388. DeviceObject context of call
  389. Return Value:
  390. STATUS_SUCCESS
  391. status returned by LowLevel routines
  392. --*/
  393. {
  394. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  395. PSMARTCARD_EXTENSION SmartcardExtension = &DeviceExtension->SmartcardExtension;
  396. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  397. NTSTATUS NtStatus = STATUS_NO_MEMORY;
  398. PURB pUrb = NULL;
  399. SmartcardDebug(
  400. DEBUG_TRACE,
  401. ("%s!StcUsbStartDevice: Enter\n",
  402. DRIVER_NAME));
  403. __try {
  404. // Initialize the USB interface
  405. pUrb = ExAllocatePool(
  406. NonPagedPool,
  407. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)
  408. );
  409. if(pUrb == NULL)
  410. {
  411. __leave;
  412. }
  413. DeviceExtension->DeviceDescriptor = ExAllocatePool(
  414. NonPagedPool,
  415. sizeof(USB_DEVICE_DESCRIPTOR)
  416. );
  417. if(DeviceExtension->DeviceDescriptor == NULL)
  418. {
  419. __leave;
  420. }
  421. UsbBuildGetDescriptorRequest(
  422. pUrb,
  423. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  424. USB_DEVICE_DESCRIPTOR_TYPE,
  425. 0,
  426. 0,
  427. DeviceExtension->DeviceDescriptor,
  428. NULL,
  429. sizeof(USB_DEVICE_DESCRIPTOR),
  430. NULL
  431. );
  432. // Send the urb to the USB driver
  433. NtStatus = UsbCallUSBD(DeviceObject, pUrb);
  434. if(NtStatus != STATUS_SUCCESS)
  435. {
  436. __leave;
  437. }
  438. UsbConfigureDevice(DeviceObject);
  439. ReaderExtension->ulReadBufferLen = 0;
  440. // setup the STC registers
  441. NtStatus = STCConfigureSTC(
  442. SmartcardExtension->ReaderExtension,
  443. ( PSTC_REGISTER ) STCInitialize
  444. );
  445. if (NtStatus != STATUS_SUCCESS)
  446. {
  447. SmartcardLogError(
  448. DeviceObject,
  449. STCUSB_CANT_INITIALIZE_READER,
  450. NULL,
  451. 0);
  452. __leave;
  453. }
  454. UsbGetFirmwareRevision(SmartcardExtension->ReaderExtension);
  455. // store firmware revision in ifd version
  456. SmartcardExtension->VendorAttr.IfdVersion.VersionMajor =
  457. ReaderExtension->FirmwareMajor;
  458. SmartcardExtension->VendorAttr.IfdVersion.VersionMinor =
  459. ReaderExtension->FirmwareMinor;
  460. // CBUpdateCardState(SmartcardExtension );
  461. // start polling the device for card movement detection
  462. StcUsbStartPollThread( DeviceExtension );
  463. NtStatus = IoSetDeviceInterfaceState(
  464. &DeviceExtension->DeviceName,
  465. TRUE
  466. );
  467. if (NtStatus == STATUS_OBJECT_NAME_EXISTS)
  468. {
  469. // We tried to re-enable the device which is ok
  470. // This can happen after a stop - start sequence
  471. NtStatus = STATUS_SUCCESS;
  472. }
  473. // signal that the reader has been started
  474. KeSetEvent(&DeviceExtension->ReaderStarted, 0, FALSE);
  475. ASSERT(NtStatus == STATUS_SUCCESS);
  476. }
  477. finally
  478. {
  479. if (pUrb != NULL)
  480. {
  481. ExFreePool(pUrb);
  482. }
  483. if (NtStatus != STATUS_SUCCESS)
  484. {
  485. StcUsbStopDevice(DeviceObject);
  486. }
  487. SmartcardDebug(
  488. DEBUG_TRACE,
  489. ( "%s!StcUsbStartDevice: Exit %x\n",
  490. DRIVER_NAME,
  491. NtStatus ));
  492. }
  493. return NtStatus;
  494. }
  495. VOID
  496. StcUsbStopDevice(
  497. PDEVICE_OBJECT DeviceObject)
  498. /*++
  499. Routine Description:
  500. Finishes card tracking requests and closes the connection to the
  501. Usb port.
  502. --*/
  503. {
  504. PDEVICE_EXTENSION DeviceExtension;
  505. NTSTATUS status;
  506. LARGE_INTEGER delayPeriod;
  507. if (DeviceObject == NULL)
  508. {
  509. return;
  510. }
  511. SmartcardDebug(
  512. DEBUG_TRACE,
  513. ( "%s!StcUsbStopDevice: Enter\n",
  514. DRIVER_NAME));
  515. DeviceExtension = DeviceObject->DeviceExtension;
  516. KeClearEvent(&DeviceExtension->ReaderStarted);
  517. // stop polling the reader
  518. StcUsbStopPollThread( DeviceExtension );
  519. if (DeviceExtension->DeviceDescriptor)
  520. {
  521. ExFreePool(DeviceExtension->DeviceDescriptor);
  522. DeviceExtension->DeviceDescriptor = NULL;
  523. }
  524. if (DeviceExtension->Interface)
  525. {
  526. ExFreePool(DeviceExtension->Interface);
  527. DeviceExtension->Interface = NULL;
  528. }
  529. SmartcardDebug(
  530. DEBUG_TRACE,
  531. ( "%s!StcUsbStopDevice: Exit\n",
  532. DRIVER_NAME));
  533. }
  534. NTSTATUS
  535. StcUsbSystemControl(
  536. PDEVICE_OBJECT DeviceObject,
  537. PIRP Irp
  538. )
  539. {
  540. PDEVICE_EXTENSION DeviceExtension;
  541. NTSTATUS status = STATUS_SUCCESS;
  542. DeviceExtension = DeviceObject->DeviceExtension;
  543. IoSkipCurrentIrpStackLocation(Irp);
  544. status = IoCallDriver(DeviceExtension->AttachedPDO, Irp);
  545. return status;
  546. }
  547. NTSTATUS
  548. StcUsbDeviceIoControl(
  549. PDEVICE_OBJECT DeviceObject,
  550. PIRP Irp)
  551. /*++
  552. StcUsbDeviceIoControl:
  553. all IRP's requiring IO are queued to the StartIo routine, other requests
  554. are served immediately
  555. --*/
  556. {
  557. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  558. NTSTATUS status;
  559. KIRQL irql;
  560. LARGE_INTEGER timeout;
  561. PSMARTCARD_EXTENSION SmartcardExtension = &deviceExtension->SmartcardExtension;
  562. PREADER_EXTENSION ReaderExtension= SmartcardExtension->ReaderExtension;
  563. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  564. if (deviceExtension->IoCount < 0)
  565. {
  566. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  567. status = KeWaitForSingleObject(
  568. &deviceExtension->ReaderStarted,
  569. Executive,
  570. KernelMode,
  571. FALSE,
  572. NULL);
  573. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  574. }
  575. ASSERT(deviceExtension->IoCount >= 0);
  576. deviceExtension->IoCount++;
  577. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  578. status = SmartcardAcquireRemoveLock(&deviceExtension->SmartcardExtension);
  579. if (status != STATUS_SUCCESS)
  580. {
  581. // the device has been removed. Fail the call
  582. Irp->IoStatus.Information = 0;
  583. Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
  584. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  585. return STATUS_DEVICE_REMOVED;
  586. }
  587. KeWaitForMutexObject(
  588. &deviceExtension->hMutex,
  589. Executive,
  590. KernelMode,
  591. FALSE,
  592. NULL);
  593. status = SmartcardDeviceControl(
  594. &(deviceExtension->SmartcardExtension),
  595. Irp);
  596. KeReleaseMutex(
  597. &deviceExtension->hMutex,
  598. FALSE);
  599. SmartcardReleaseRemoveLock(&deviceExtension->SmartcardExtension);
  600. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  601. deviceExtension->IoCount--;
  602. ASSERT(deviceExtension->IoCount >= 0);
  603. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  604. return status;
  605. }
  606. NTSTATUS
  607. StcUsbCallComplete (
  608. IN PDEVICE_OBJECT DeviceObject,
  609. IN PIRP Irp,
  610. IN PKEVENT Event)
  611. /*++
  612. Routine Description:
  613. Completion routine for an Irp sent to the Usb driver. The event will
  614. be set to notify that the Usb driver is done. The routine will not
  615. 'complete' the Irp, so the caller of CallUsbDriver can continue.
  616. --*/
  617. {
  618. UNREFERENCED_PARAMETER (DeviceObject);
  619. if (Irp->Cancel)
  620. {
  621. Irp->IoStatus.Status = STATUS_CANCELLED;
  622. }
  623. KeSetEvent (Event, 0, FALSE);
  624. return STATUS_MORE_PROCESSING_REQUIRED;
  625. }
  626. NTSTATUS
  627. StcUsbCallUsbDriver(
  628. IN PDEVICE_OBJECT AttachedPDO,
  629. IN PIRP Irp)
  630. /*++
  631. Routine Description:
  632. Send an Irp to the Usb driver.
  633. --*/
  634. {
  635. NTSTATUS NtStatus = STATUS_SUCCESS;
  636. KEVENT Event;
  637. // Copy our stack location to the next.
  638. IoCopyCurrentIrpStackLocationToNext(Irp);
  639. //
  640. // initialize an event for process synchronization. the event is passed
  641. // to our completion routine and will be set if the pcmcia driver is done
  642. //
  643. KeInitializeEvent(
  644. &Event,
  645. NotificationEvent,
  646. FALSE);
  647. // Our IoCompletionRoutine sets only our event
  648. IoSetCompletionRoutine (
  649. Irp,
  650. StcUsbCallComplete,
  651. &Event,
  652. TRUE,
  653. TRUE,
  654. TRUE);
  655. if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_POWER)
  656. {
  657. NtStatus = PoCallDriver(AttachedPDO, Irp);
  658. }
  659. else
  660. {
  661. NtStatus = IoCallDriver(AttachedPDO, Irp);
  662. }
  663. // Wait until the usb driver has processed the Irp
  664. if (NtStatus == STATUS_PENDING)
  665. {
  666. NtStatus = KeWaitForSingleObject(
  667. &Event,
  668. Executive,
  669. KernelMode,
  670. FALSE,
  671. NULL);
  672. if (NtStatus == STATUS_SUCCESS)
  673. {
  674. NtStatus = Irp->IoStatus.Status;
  675. }
  676. }
  677. return(NtStatus);
  678. }
  679. NTSTATUS
  680. StcUsbPnP(
  681. IN PDEVICE_OBJECT DeviceObject,
  682. IN PIRP Irp)
  683. /*++
  684. Routine Description:
  685. driver callback for pnp manager
  686. All other requests will be passed to the usb driver to ensure correct processing.
  687. --*/
  688. {
  689. NTSTATUS status = STATUS_SUCCESS;
  690. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  691. PSMARTCARD_EXTENSION SmartcardExtension = &DeviceExtension->SmartcardExtension;
  692. PIO_STACK_LOCATION IrpStack;
  693. PDEVICE_OBJECT AttachedPDO;
  694. BOOLEAN deviceRemoved = FALSE;
  695. KIRQL irql;
  696. PAGED_CODE();
  697. SmartcardDebug(
  698. DEBUG_TRACE,
  699. ( "%s!StcUsbPnP: Enter\n",
  700. DRIVER_NAME));
  701. status = SmartcardAcquireRemoveLock(SmartcardExtension);
  702. if (status != STATUS_SUCCESS)
  703. {
  704. Irp->IoStatus.Information = 0;
  705. Irp->IoStatus.Status = status;
  706. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  707. return status;
  708. }
  709. AttachedPDO = DeviceExtension->AttachedPDO;
  710. // Irp->IoStatus.Information = 0;
  711. IrpStack = IoGetCurrentIrpStackLocation(Irp);
  712. // Now look what the PnP manager wants...
  713. switch(IrpStack->MinorFunction)
  714. {
  715. case IRP_MN_START_DEVICE:
  716. // Now we should connect to our resources (Irql, Io etc.)
  717. SmartcardDebug(
  718. DEBUG_DRIVER,
  719. ("%s!StcUsbPnP: IRP_MN_START_DEVICE\n",
  720. DRIVER_NAME));
  721. // We have to call the underlying driver first
  722. status = StcUsbCallUsbDriver(AttachedPDO, Irp);
  723. if (NT_SUCCESS(status))
  724. {
  725. status = StcUsbStartDevice(DeviceObject);
  726. }
  727. break;
  728. case IRP_MN_QUERY_STOP_DEVICE:
  729. SmartcardDebug(
  730. DEBUG_DRIVER,
  731. ("%s!StcUsbPnP: IRP_MN_QUERY_STOP_DEVICE\n",
  732. DRIVER_NAME));
  733. KeAcquireSpinLock(&DeviceExtension->SpinLock, &irql);
  734. if (DeviceExtension->IoCount > 0)
  735. {
  736. // we refuse to stop if we have pending io
  737. KeReleaseSpinLock(&DeviceExtension->SpinLock, irql);
  738. status = STATUS_DEVICE_BUSY;
  739. }
  740. else
  741. {
  742. // stop processing requests
  743. DeviceExtension->IoCount = -1;
  744. KeClearEvent(&DeviceExtension->ReaderStarted);
  745. KeReleaseSpinLock(&DeviceExtension->SpinLock, irql);
  746. status = StcUsbCallUsbDriver(AttachedPDO, Irp);
  747. }
  748. break;
  749. case IRP_MN_CANCEL_STOP_DEVICE:
  750. SmartcardDebug(
  751. DEBUG_DRIVER,
  752. ("%s!StcUsbPnP: IRP_MN_CANCEL_STOP_DEVICE\n",
  753. DRIVER_NAME));
  754. status = StcUsbCallUsbDriver(AttachedPDO, Irp);
  755. // we can continue to process requests
  756. DeviceExtension->IoCount = 0;
  757. KeSetEvent(&DeviceExtension->ReaderStarted, 0, FALSE);
  758. break;
  759. case IRP_MN_STOP_DEVICE:
  760. SmartcardDebug(
  761. DEBUG_DRIVER,
  762. ("%s!StcUsbPnP: IRP_MN_STOP_DEVICE\n",
  763. DRIVER_NAME));
  764. StcUsbStopDevice(DeviceObject);
  765. status = StcUsbCallUsbDriver(AttachedPDO, Irp);
  766. break;
  767. case IRP_MN_QUERY_REMOVE_DEVICE:
  768. // Remove our device
  769. SmartcardDebug(
  770. DEBUG_DRIVER,
  771. ("%s!StcUsbPnP: IRP_MN_QUERY_REMOVE_DEVICE\n",
  772. DRIVER_NAME));
  773. // disable the reader
  774. status = IoSetDeviceInterfaceState(
  775. &DeviceExtension->DeviceName,
  776. FALSE);
  777. ASSERT(status == STATUS_SUCCESS);
  778. if (status != STATUS_SUCCESS)
  779. {
  780. break;
  781. }
  782. // check if the reader has been opened
  783. if (DeviceExtension->ReaderOpen)
  784. {
  785. // someone is connected, enable the reader and fail the call
  786. IoSetDeviceInterfaceState(
  787. &DeviceExtension->DeviceName,
  788. TRUE);
  789. status = STATUS_UNSUCCESSFUL;
  790. break;
  791. }
  792. // pass the call to the next driver in the stack
  793. status = StcUsbCallUsbDriver(AttachedPDO, Irp);
  794. break;
  795. case IRP_MN_CANCEL_REMOVE_DEVICE:
  796. // Removal of device has been cancelled
  797. SmartcardDebug(
  798. DEBUG_DRIVER,
  799. ("%s!StcUsbPnP: IRP_MN_CANCEL_REMOVE_DEVICE\n",
  800. DRIVER_NAME));
  801. // pass the call to the next driver in the stack
  802. status = StcUsbCallUsbDriver(AttachedPDO, Irp);
  803. if (status == STATUS_SUCCESS)
  804. {
  805. status = IoSetDeviceInterfaceState(
  806. &DeviceExtension->DeviceName,
  807. TRUE);
  808. }
  809. break;
  810. case IRP_MN_REMOVE_DEVICE:
  811. // Remove our device
  812. SmartcardDebug(
  813. DEBUG_DRIVER,
  814. ("%s!StcUsbPnP: IRP_MN_REMOVE_DEVICE\n",
  815. DRIVER_NAME));
  816. StcUsbStopDevice(DeviceObject);
  817. StcUsbUnloadDevice(DeviceObject);
  818. status = StcUsbCallUsbDriver(AttachedPDO, Irp);
  819. deviceRemoved = TRUE;
  820. break;
  821. default:
  822. SmartcardDebug(
  823. DEBUG_DRIVER,
  824. ("%s!StcUsbPnP: IRP_MN_...%lx\n",
  825. DRIVER_NAME,
  826. IrpStack->MinorFunction));
  827. // This is an Irp that is only useful for underlying drivers
  828. status = StcUsbCallUsbDriver(AttachedPDO, Irp);
  829. break;
  830. }
  831. Irp->IoStatus.Status = status;
  832. IoCompleteRequest(
  833. Irp,
  834. IO_NO_INCREMENT);
  835. if (deviceRemoved == FALSE)
  836. {
  837. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  838. }
  839. SmartcardDebug(
  840. DEBUG_TRACE,
  841. ( "%s!StcUsbPnP: Exit %x\n",
  842. DRIVER_NAME,
  843. status));
  844. return status;
  845. }
  846. VOID
  847. StcUsbSystemPowerCompletion(
  848. IN PDEVICE_OBJECT DeviceObject,
  849. IN UCHAR MinorFunction,
  850. IN POWER_STATE PowerState,
  851. IN PKEVENT Event,
  852. IN PIO_STATUS_BLOCK IoStatus
  853. )
  854. /*++
  855. Routine Description:
  856. This function is called when the underlying stacks
  857. completed the power transition.
  858. --*/
  859. {
  860. UNREFERENCED_PARAMETER (DeviceObject);
  861. UNREFERENCED_PARAMETER (MinorFunction);
  862. UNREFERENCED_PARAMETER (PowerState);
  863. UNREFERENCED_PARAMETER (IoStatus);
  864. KeSetEvent(Event, 0, FALSE);
  865. }
  866. NTSTATUS
  867. StcUsbDevicePowerCompletion (
  868. IN PDEVICE_OBJECT DeviceObject,
  869. IN PIRP Irp,
  870. IN PSMARTCARD_EXTENSION SmartcardExtension)
  871. /*++
  872. Routine Description:
  873. This routine is called after the underlying stack powered
  874. UP the Usb port, so it can be used again.
  875. --*/
  876. {
  877. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  878. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  879. NTSTATUS status;
  880. UCHAR state;
  881. BOOLEAN CardPresent;
  882. //
  883. // setup the STC registers
  884. //
  885. status = STCConfigureSTC(
  886. SmartcardExtension->ReaderExtension,
  887. ( PSTC_REGISTER ) STCInitialize
  888. );
  889. // get the current state of the card
  890. CBUpdateCardState(SmartcardExtension);
  891. // save the current power state of the reader
  892. SmartcardExtension->ReaderExtension->ReaderPowerState =
  893. PowerReaderWorking;
  894. SmartcardReleaseRemoveLock(SmartcardExtension);
  895. // inform the power manager of our state.
  896. PoSetPowerState (
  897. DeviceObject,
  898. DevicePowerState,
  899. irpStack->Parameters.Power.State);
  900. PoStartNextPowerIrp(Irp);
  901. // restart the polling thread
  902. StcUsbStartPollThread( deviceExtension );
  903. return STATUS_SUCCESS;
  904. }
  905. typedef enum _ACTION {
  906. Undefined = 0,
  907. SkipRequest,
  908. WaitForCompletion,
  909. CompleteRequest,
  910. MarkPending
  911. } ACTION;
  912. NTSTATUS
  913. StcUsbPower (
  914. IN PDEVICE_OBJECT DeviceObject,
  915. IN PIRP Irp)
  916. /*++
  917. Routine Description:
  918. The power dispatch routine.
  919. This driver is the power policy owner of the device stack,
  920. because this driver knows about the connected reader.
  921. Therefor this driver will translate system power states
  922. to device power states.
  923. Arguments:
  924. DeviceObject - pointer to a device object.
  925. Irp - pointer to an I/O Request Packet.
  926. Return Value:
  927. NT status code
  928. --*/
  929. {
  930. NTSTATUS status = STATUS_SUCCESS;
  931. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  932. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  933. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  934. ACTION action;
  935. POWER_STATE powerState;
  936. KEVENT event;
  937. PAGED_CODE();
  938. SmartcardDebug(
  939. DEBUG_DRIVER,
  940. ("%s!StcUsbPower: Enter\n",
  941. DRIVER_NAME));
  942. status = SmartcardAcquireRemoveLock(smartcardExtension);
  943. if (!NT_SUCCESS(status))
  944. {
  945. PoStartNextPowerIrp(Irp);
  946. Irp->IoStatus.Status = status;
  947. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  948. return status;
  949. }
  950. switch (irpStack->Parameters.Power.Type) {
  951. case DevicePowerState:
  952. if (irpStack->MinorFunction == IRP_MN_SET_POWER) {
  953. switch (irpStack->Parameters.Power.State.DeviceState) {
  954. case PowerDeviceD0:
  955. // Turn on the reader
  956. SmartcardDebug(
  957. DEBUG_DRIVER,
  958. ("%s!StcUsbPower: PowerDevice D0\n",
  959. DRIVER_NAME));
  960. //
  961. // First, we send down the request to the bus, in order
  962. // to power on the port. When the request completes,
  963. // we turn on the reader
  964. //
  965. IoCopyCurrentIrpStackLocationToNext(Irp);
  966. IoSetCompletionRoutine (
  967. Irp,
  968. StcUsbDevicePowerCompletion,
  969. smartcardExtension,
  970. TRUE,
  971. TRUE,
  972. TRUE);
  973. action = WaitForCompletion;
  974. break;
  975. case PowerDeviceD3:
  976. // Turn off the reader
  977. SmartcardDebug(
  978. DEBUG_DRIVER,
  979. ("%s!StcUsbPower: PowerDevice D3\n",
  980. DRIVER_NAME));
  981. KeClearEvent(&deviceExtension->ReaderStarted);
  982. StcUsbStopPollThread( deviceExtension );
  983. PoSetPowerState (
  984. DeviceObject,
  985. DevicePowerState,
  986. irpStack->Parameters.Power.State);
  987. // save the current card state
  988. smartcardExtension->ReaderExtension->CardPresent =
  989. smartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT;
  990. // power down the card
  991. if (smartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT ) {
  992. smartcardExtension->MinorIoControlCode = SCARD_POWER_DOWN;
  993. status = CBCardPower(smartcardExtension);
  994. //
  995. // This will trigger the card monitor, since we do not really
  996. // know if the user will remove / re-insert a card while the
  997. // system is asleep
  998. //
  999. }
  1000. status = STCConfigureSTC(
  1001. smartcardExtension->ReaderExtension,
  1002. ( PSTC_REGISTER ) STCClose
  1003. );
  1004. // save the current power state of the reader
  1005. smartcardExtension->ReaderExtension->ReaderPowerState =
  1006. PowerReaderOff;
  1007. action = SkipRequest;
  1008. break;
  1009. default:
  1010. action = SkipRequest;
  1011. break;
  1012. }
  1013. } else {
  1014. action = SkipRequest;
  1015. }
  1016. break;
  1017. case SystemPowerState: {
  1018. //
  1019. // The system wants to change the power state.
  1020. // We need to translate the system power state to
  1021. // a corresponding device power state.
  1022. //
  1023. POWER_STATE_TYPE powerType = DevicePowerState;
  1024. KIRQL irql;
  1025. ASSERT(smartcardExtension->ReaderExtension->ReaderPowerState !=
  1026. PowerReaderUnspecified);
  1027. switch (irpStack->MinorFunction) {
  1028. case IRP_MN_QUERY_POWER:
  1029. SmartcardDebug(
  1030. DEBUG_DRIVER,
  1031. ("%s!StcUsbPower: Query Power\n",
  1032. DRIVER_NAME));
  1033. //
  1034. // By default we succeed and pass down
  1035. //
  1036. action = SkipRequest;
  1037. Irp->IoStatus.Status = STATUS_SUCCESS;
  1038. switch (irpStack->Parameters.Power.State.SystemState) {
  1039. case PowerSystemMaximum:
  1040. case PowerSystemWorking:
  1041. break;
  1042. case PowerSystemSleeping1:
  1043. case PowerSystemSleeping2:
  1044. case PowerSystemSleeping3:
  1045. case PowerSystemHibernate:
  1046. case PowerSystemShutdown:
  1047. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  1048. if (deviceExtension->IoCount == 0) {
  1049. // Block any further ioctls
  1050. // KeClearEvent(&deviceExtension->ReaderStarted);
  1051. } else {
  1052. // can't go to sleep mode since the reader is busy.
  1053. status = STATUS_DEVICE_BUSY;
  1054. action = CompleteRequest;
  1055. }
  1056. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  1057. break;
  1058. }
  1059. break;
  1060. case IRP_MN_SET_POWER:
  1061. SmartcardDebug(
  1062. DEBUG_DRIVER,
  1063. ("%s!StcUsbPower: PowerSystem S%d\n",
  1064. DRIVER_NAME,
  1065. irpStack->Parameters.Power.State.SystemState - 1));
  1066. switch (irpStack->Parameters.Power.State.SystemState) {
  1067. case PowerSystemMaximum:
  1068. case PowerSystemWorking:
  1069. if (smartcardExtension->ReaderExtension->ReaderPowerState ==
  1070. PowerReaderWorking) {
  1071. // We're already in the right state
  1072. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  1073. action = SkipRequest;
  1074. break;
  1075. }
  1076. powerState.DeviceState = PowerDeviceD0;
  1077. action = MarkPending;
  1078. break;
  1079. case PowerSystemSleeping1:
  1080. case PowerSystemSleeping2:
  1081. case PowerSystemSleeping3:
  1082. case PowerSystemHibernate:
  1083. case PowerSystemShutdown:
  1084. if (smartcardExtension->ReaderExtension->ReaderPowerState ==
  1085. PowerReaderOff) {
  1086. // We're already in the right state
  1087. action = SkipRequest;
  1088. break;
  1089. }
  1090. powerState.DeviceState = PowerDeviceD3;
  1091. // first, inform the power manager of our new state.
  1092. PoSetPowerState (
  1093. DeviceObject,
  1094. SystemPowerState,
  1095. powerState);
  1096. action = MarkPending;
  1097. break;
  1098. default:
  1099. action = SkipRequest;
  1100. break;
  1101. }
  1102. break;
  1103. default:
  1104. action = SkipRequest;
  1105. break;
  1106. }
  1107. }
  1108. break;
  1109. default:
  1110. action = SkipRequest;
  1111. break;
  1112. }
  1113. switch (action)
  1114. {
  1115. case CompleteRequest:
  1116. Irp->IoStatus.Status = status;
  1117. Irp->IoStatus.Information = 0;
  1118. SmartcardReleaseRemoveLock(smartcardExtension);
  1119. PoStartNextPowerIrp(Irp);
  1120. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1121. break;
  1122. case MarkPending:
  1123. // initialize the event we need in the completion function
  1124. KeInitializeEvent(
  1125. &event,
  1126. NotificationEvent,
  1127. FALSE
  1128. );
  1129. // request the device power irp
  1130. status = PoRequestPowerIrp (
  1131. DeviceObject,
  1132. IRP_MN_SET_POWER,
  1133. powerState,
  1134. StcUsbSystemPowerCompletion,
  1135. &event,
  1136. NULL
  1137. );
  1138. if (status == STATUS_PENDING) {
  1139. // wait until the device power irp completed
  1140. status = KeWaitForSingleObject(
  1141. &event,
  1142. Executive,
  1143. KernelMode,
  1144. FALSE,
  1145. NULL
  1146. );
  1147. SmartcardReleaseRemoveLock(smartcardExtension);
  1148. if (powerState.SystemState == PowerSystemWorking) {
  1149. PoSetPowerState (
  1150. DeviceObject,
  1151. SystemPowerState,
  1152. powerState
  1153. );
  1154. }
  1155. PoStartNextPowerIrp(Irp);
  1156. IoSkipCurrentIrpStackLocation(Irp);
  1157. status = PoCallDriver(deviceExtension->AttachedPDO, Irp);
  1158. } else {
  1159. SmartcardReleaseRemoveLock(smartcardExtension);
  1160. Irp->IoStatus.Status = status;
  1161. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1162. }
  1163. break;
  1164. case SkipRequest:
  1165. SmartcardReleaseRemoveLock(smartcardExtension);
  1166. PoStartNextPowerIrp(Irp);
  1167. IoSkipCurrentIrpStackLocation(Irp);
  1168. status = PoCallDriver(deviceExtension->AttachedPDO, Irp);
  1169. break;
  1170. case WaitForCompletion:
  1171. status = PoCallDriver(deviceExtension->AttachedPDO, Irp);
  1172. break;
  1173. default:
  1174. break;
  1175. }
  1176. return status;
  1177. }
  1178. NTSTATUS
  1179. StcUsbCreateClose(
  1180. PDEVICE_OBJECT DeviceObject,
  1181. PIRP Irp
  1182. )
  1183. /*++
  1184. Routine Description:
  1185. This routine is called by the I/O system when the device is opened or closed.
  1186. Arguments:
  1187. DeviceObject context of device
  1188. Irp context of call
  1189. Return Value:
  1190. STATUS_SUCCESS
  1191. STATUS_DEVICE_BUSY
  1192. --*/
  1193. {
  1194. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1195. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  1196. NTSTATUS status = STATUS_SUCCESS;
  1197. SmartcardDebug(
  1198. DEBUG_DRIVER,
  1199. ("%s!StcCreateClose: Enter\n",
  1200. DRIVER_NAME));
  1201. __try {
  1202. if (irpStack->MajorFunction == IRP_MJ_CREATE) {
  1203. status = SmartcardAcquireRemoveLockWithTag(
  1204. &deviceExtension->SmartcardExtension,
  1205. 'lCrC'
  1206. );
  1207. if (status != STATUS_SUCCESS) {
  1208. status = STATUS_DEVICE_REMOVED;
  1209. __leave;
  1210. }
  1211. // test if the device has been opened already
  1212. if (InterlockedCompareExchange(
  1213. &deviceExtension->ReaderOpen,
  1214. TRUE,
  1215. FALSE) == FALSE) {
  1216. SmartcardDebug(
  1217. DEBUG_DRIVER,
  1218. ("%s!StcCreateClose: Open\n",
  1219. DRIVER_NAME)
  1220. );
  1221. } else {
  1222. // the device is already in use
  1223. status = STATUS_UNSUCCESSFUL;
  1224. // release the lock
  1225. SmartcardReleaseRemoveLockWithTag(
  1226. &deviceExtension->SmartcardExtension,
  1227. 'lCrC'
  1228. );
  1229. }
  1230. } else {
  1231. SmartcardDebug(
  1232. DEBUG_DRIVER,
  1233. ("%s!StcCreateClose: Close\n",
  1234. DRIVER_NAME)
  1235. );
  1236. SmartcardReleaseRemoveLockWithTag(
  1237. &deviceExtension->SmartcardExtension,
  1238. 'lCrC'
  1239. );
  1240. deviceExtension->ReaderOpen = FALSE;
  1241. }
  1242. }
  1243. __finally {
  1244. Irp->IoStatus.Status = status;
  1245. Irp->IoStatus.Information = 0;
  1246. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1247. }
  1248. SmartcardDebug(
  1249. DEBUG_DRIVER,
  1250. ("%s!StcCreateClose: Exit (%lx)\n",
  1251. DRIVER_NAME,
  1252. status));
  1253. return status;
  1254. }
  1255. NTSTATUS
  1256. StcUsbCancel(
  1257. IN PDEVICE_OBJECT DeviceObject,
  1258. IN PIRP Irp
  1259. )
  1260. /*++
  1261. Routine Description:
  1262. This routine is called by the I/O system
  1263. when the irp should be cancelled
  1264. Arguments:
  1265. DeviceObject - Pointer to device object for this miniport
  1266. Irp - IRP involved.
  1267. Return Value:
  1268. STATUS_CANCELLED
  1269. --*/
  1270. {
  1271. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1272. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  1273. SmartcardDebug(
  1274. DEBUG_TRACE,
  1275. ("%s!StcUsbCancel: Enter\n",
  1276. DRIVER_NAME));
  1277. ASSERT(Irp == smartcardExtension->OsData->NotificationIrp);
  1278. Irp->IoStatus.Information = 0;
  1279. Irp->IoStatus.Status = STATUS_CANCELLED;
  1280. smartcardExtension->OsData->NotificationIrp = NULL;
  1281. IoReleaseCancelSpinLock(
  1282. Irp->CancelIrql);
  1283. IoCompleteRequest(
  1284. Irp,
  1285. IO_NO_INCREMENT);
  1286. SmartcardDebug(
  1287. DEBUG_TRACE,
  1288. ("%s!StcUsbCancel: Exit\n",
  1289. DRIVER_NAME));
  1290. return STATUS_CANCELLED;
  1291. }
  1292. NTSTATUS
  1293. StcUsbCleanup(
  1294. IN PDEVICE_OBJECT DeviceObject,
  1295. IN PIRP Irp
  1296. )
  1297. /*++
  1298. Routine Description:
  1299. This routine is called by the I/O system when the calling thread terminates
  1300. Arguments:
  1301. DeviceObject - Pointer to device object for this miniport
  1302. Irp - IRP involved.
  1303. Return Value:
  1304. STATUS_CANCELLED
  1305. --*/
  1306. {
  1307. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1308. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  1309. NTSTATUS status = STATUS_SUCCESS;
  1310. KIRQL CancelIrql;
  1311. SmartcardDebug(
  1312. DEBUG_TRACE,
  1313. ("%s!StcUsbCleanup: Enter\n",
  1314. DRIVER_NAME));
  1315. IoAcquireCancelSpinLock(&CancelIrql);
  1316. // cancel pending notification irps
  1317. if( smartcardExtension->OsData->NotificationIrp )
  1318. {
  1319. // reset the cancel function so that it won't be called anymore
  1320. IoSetCancelRoutine(
  1321. smartcardExtension->OsData->NotificationIrp,
  1322. NULL
  1323. );
  1324. smartcardExtension->OsData->NotificationIrp->CancelIrql =
  1325. CancelIrql;
  1326. StcUsbCancel(
  1327. DeviceObject,
  1328. smartcardExtension->OsData->NotificationIrp);
  1329. } else {
  1330. IoReleaseCancelSpinLock(CancelIrql);
  1331. }
  1332. SmartcardDebug(
  1333. DEBUG_DRIVER,
  1334. ("%s!StcUsbCleanup: Completing IRP %lx\n",
  1335. DRIVER_NAME,
  1336. Irp));
  1337. Irp->IoStatus.Information = 0;
  1338. Irp->IoStatus.Status = STATUS_SUCCESS;
  1339. IoCompleteRequest(
  1340. Irp,
  1341. IO_NO_INCREMENT);
  1342. SmartcardDebug(
  1343. DEBUG_TRACE,
  1344. ("%s!StcUsbCleanup: Exit\n",
  1345. DRIVER_NAME));
  1346. return STATUS_SUCCESS;
  1347. }
  1348. VOID
  1349. StcUsbUnloadDevice(
  1350. PDEVICE_OBJECT DeviceObject
  1351. )
  1352. /*++
  1353. Routine Description:
  1354. close connections to smclib.sys and the usb driver, delete symbolic
  1355. link and mark the slot as unused.
  1356. Arguments:
  1357. DeviceObject device to unload
  1358. Return Value:
  1359. void
  1360. --*/
  1361. {
  1362. PDEVICE_EXTENSION DeviceExtension;
  1363. PSMARTCARD_EXTENSION SmartcardExtension;
  1364. NTSTATUS status;
  1365. if (DeviceObject == NULL)
  1366. {
  1367. return;
  1368. }
  1369. DeviceExtension= DeviceObject->DeviceExtension;
  1370. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1371. SmartcardDebug(
  1372. DEBUG_TRACE,
  1373. ( "%s!StcUsbUnloadDevice: Enter\n",
  1374. DRIVER_NAME));
  1375. KeWaitForMutexObject(
  1376. &DeviceExtension->hMutex,
  1377. Executive,
  1378. KernelMode,
  1379. FALSE,
  1380. NULL);
  1381. KeReleaseMutex(
  1382. &DeviceExtension->hMutex,
  1383. FALSE);
  1384. // free polling resources
  1385. if( DeviceExtension->PollWorkItem == NULL )
  1386. {
  1387. IoFreeWorkItem( DeviceExtension->PollWorkItem );
  1388. }
  1389. // disable our device so no one can open it
  1390. IoSetDeviceInterfaceState(
  1391. &DeviceExtension->DeviceName,
  1392. FALSE);
  1393. // report to the lib that the device will be unloaded
  1394. if(SmartcardExtension->OsData != NULL)
  1395. {
  1396. ASSERT(SmartcardExtension->OsData->NotificationIrp == NULL);
  1397. SmartcardReleaseRemoveLockAndWait(SmartcardExtension);
  1398. }
  1399. // delete the symbolic link
  1400. if( DeviceExtension->DeviceName.Buffer != NULL )
  1401. {
  1402. RtlFreeUnicodeString(&DeviceExtension->DeviceName);
  1403. DeviceExtension->DeviceName.Buffer = NULL;
  1404. }
  1405. if( SmartcardExtension->OsData != NULL )
  1406. {
  1407. SmartcardExit( SmartcardExtension );
  1408. }
  1409. if (DeviceExtension->SmartcardExtension.ReaderExtension != NULL)
  1410. {
  1411. ExFreePool(DeviceExtension->SmartcardExtension.ReaderExtension);
  1412. DeviceExtension->SmartcardExtension.ReaderExtension = NULL;
  1413. }
  1414. // Detach from the usb driver
  1415. if (DeviceExtension->AttachedPDO)
  1416. {
  1417. IoDetachDevice(DeviceExtension->AttachedPDO);
  1418. DeviceExtension->AttachedPDO = NULL;
  1419. }
  1420. // delete the device object
  1421. IoDeleteDevice(DeviceObject);
  1422. SmartcardDebug(
  1423. DEBUG_TRACE,
  1424. ( "%s!StcUsbUnloadDevice: Exit\n",
  1425. DRIVER_NAME));
  1426. }
  1427. VOID
  1428. StcUsbUnloadDriver(
  1429. PDRIVER_OBJECT DriverObject)
  1430. /*++
  1431. Description:
  1432. unloads all devices for a given driver object
  1433. Arguments:
  1434. DriverObject context of driver
  1435. --*/
  1436. {
  1437. SmartcardDebug(
  1438. DEBUG_TRACE,
  1439. ( "%s!StcUsbUnloadDriver\n",
  1440. DRIVER_NAME));
  1441. }
  1442. void
  1443. SysDelay(
  1444. ULONG Timeout
  1445. )
  1446. /*++
  1447. SysDelay:
  1448. performs a required delay.
  1449. Arguments:
  1450. Timeout delay in milli seconds
  1451. Return Value:
  1452. void
  1453. --*/
  1454. {
  1455. LARGE_INTEGER SysTimeout;
  1456. SysTimeout.QuadPart = (LONGLONG)-10 * 1000 * Timeout;
  1457. // KeDelayExecutionThread: counted in 100 ns
  1458. KeDelayExecutionThread( KernelMode, FALSE, &SysTimeout );
  1459. }
  1460. VOID
  1461. StcUsbCardDetectionThread(
  1462. PDEVICE_OBJECT DeviceObject,
  1463. PDEVICE_EXTENSION DeviceExtension)
  1464. /*++
  1465. StcUsbCardDetectionThread:
  1466. create the card detection thread
  1467. Arguments:
  1468. SmartcardExtension context of call
  1469. Return Value:
  1470. -
  1471. --*/
  1472. {
  1473. NTSTATUS NTStatus = STATUS_SUCCESS;
  1474. PSMARTCARD_EXTENSION SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1475. LARGE_INTEGER Timeout;
  1476. SmartcardDebug(
  1477. DEBUG_TRACE,
  1478. ("%s!StcUsbCardDetectionThread\n",
  1479. DRIVER_NAME));
  1480. __try
  1481. {
  1482. NTStatus = SmartcardAcquireRemoveLock(SmartcardExtension);
  1483. if( NTStatus == STATUS_DELETE_PENDING )
  1484. __leave;
  1485. // wait for the mutex shared with the deviceiocontrol routine
  1486. NTStatus = KeWaitForMutexObject(
  1487. &DeviceExtension->hMutex,
  1488. Executive,
  1489. KernelMode,
  1490. FALSE,
  1491. NULL);
  1492. if( NTStatus != STATUS_SUCCESS )
  1493. __leave;
  1494. CBUpdateCardState(SmartcardExtension);
  1495. KeReleaseMutex( &DeviceExtension->hMutex, FALSE );
  1496. SmartcardReleaseRemoveLock(SmartcardExtension);
  1497. Timeout.QuadPart = -10000 * POLLING_PERIOD;
  1498. NTStatus = KeWaitForSingleObject(
  1499. &DeviceExtension->FinishPollThread,
  1500. Executive,
  1501. KernelMode,
  1502. FALSE,
  1503. &Timeout
  1504. );
  1505. // thread stopped?
  1506. if( NTStatus == STATUS_SUCCESS )
  1507. __leave;
  1508. // queue the work item again
  1509. IoQueueWorkItem(
  1510. DeviceExtension->PollWorkItem,
  1511. StcUsbCardDetectionThread,
  1512. DelayedWorkQueue,
  1513. DeviceExtension
  1514. );
  1515. }
  1516. __finally
  1517. {
  1518. if( NTStatus != STATUS_TIMEOUT )
  1519. {
  1520. SmartcardDebug(
  1521. DEBUG_TRACE,
  1522. ("%s!StcUsbCardDetectionThread Terminate polling thread\n",
  1523. DRIVER_NAME));
  1524. KeSetEvent( &DeviceExtension->PollThreadStopped, 0, FALSE);
  1525. }
  1526. }
  1527. return;
  1528. }
  1529. NTSTATUS
  1530. StcUsbStartPollThread( PDEVICE_EXTENSION DeviceExtension )
  1531. {
  1532. NTSTATUS NTStatus = STATUS_SUCCESS;
  1533. KeClearEvent( &DeviceExtension->FinishPollThread );
  1534. KeClearEvent( &DeviceExtension->PollThreadStopped );
  1535. // queue the work item again
  1536. IoQueueWorkItem(
  1537. DeviceExtension->PollWorkItem,
  1538. StcUsbCardDetectionThread,
  1539. DelayedWorkQueue,
  1540. DeviceExtension
  1541. );
  1542. return( NTStatus );
  1543. }
  1544. VOID
  1545. StcUsbStopPollThread( PDEVICE_EXTENSION DeviceExtension )
  1546. {
  1547. NTSTATUS NTStatus = STATUS_SUCCESS;
  1548. if( DeviceExtension->PollWorkItem )
  1549. {
  1550. // notify the card detection thread to finish. This will kick the thread out of the wait
  1551. KeSetEvent( &DeviceExtension->FinishPollThread, 0, FALSE );
  1552. KeWaitForSingleObject(
  1553. &DeviceExtension->PollThreadStopped,
  1554. Executive,
  1555. KernelMode,
  1556. FALSE,
  1557. 0
  1558. );
  1559. }
  1560. return;
  1561. }