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.

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