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.

1971 lines
51 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation and Litronic, 1998 - 1999
  3. Module Name:
  4. L220pnp.c
  5. Abstract:
  6. This module contains the functions for the PnP and Power management.
  7. Environment:
  8. Kernel mode only.
  9. Notes:
  10. Revision History:
  11. - Created Febuary 1998 by Brian Manahan for use with
  12. the 220 reader.
  13. --*/
  14. #include <ntddk.h>
  15. #include "L220SCR.h"
  16. #include <stdio.h>
  17. // Next statement so memory for DriverEntry is released when finished
  18. #pragma alloc_text (INIT, DriverEntry)
  19. #pragma alloc_text(PAGEABLE, Lit220RemoveDevice)
  20. #pragma alloc_text(PAGEABLE, Lit220StopDevice)
  21. #pragma alloc_text(PAGEABLE, Lit220StartDevice)
  22. #include <initguid.h>
  23. NTSTATUS
  24. DriverEntry(
  25. IN PDRIVER_OBJECT DriverObject,
  26. IN PUNICODE_STRING RegistryPath
  27. )
  28. /*++
  29. Routine Description:
  30. This routine is called at system initialization time to initialize
  31. this driver.
  32. Arguments:
  33. DriverObject - Supplies the driver object.
  34. RegistryPath - Supplies the registry path for this driver.
  35. Return Value:
  36. STATUS_SUCCESS - We could initialize at least one device.
  37. STATUS_NO_SUCH_DEVICE - We could not initialize even one device.
  38. --*/
  39. {
  40. SmartcardDebug(
  41. DEBUG_DRIVER,
  42. ("%s!DriverEntry: Enter - %s %s\n",
  43. DRIVER_NAME,
  44. __DATE__,
  45. __TIME__)
  46. );
  47. //
  48. // Initialize the Driver Object with driver's entry points
  49. //
  50. DriverObject->DriverUnload = Lit220Unload;
  51. DriverObject->MajorFunction[IRP_MJ_CREATE] = Lit220CreateClose;
  52. DriverObject->MajorFunction[IRP_MJ_CLOSE] = Lit220CreateClose;
  53. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Lit220Cleanup;
  54. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Lit220DeviceControl;
  55. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = Lit220SystemControl;
  56. //
  57. // Init PNP entries
  58. //
  59. DriverObject->DriverExtension->AddDevice = Lit220AddDevice;
  60. // Power functionality temporarily removed
  61. DriverObject->MajorFunction[IRP_MJ_PNP] = Lit220PnP;
  62. // Power
  63. // Power functionality temporarily removed
  64. DriverObject->MajorFunction[IRP_MJ_POWER] = Lit220DispatchPower;
  65. // Always return STATUS_SUCCESS
  66. return STATUS_SUCCESS;
  67. }
  68. NTSTATUS
  69. Lit220AddDevice(
  70. IN PDRIVER_OBJECT DriverObject,
  71. IN PDEVICE_OBJECT PhysicalDeviceObject
  72. )
  73. /*++
  74. Routine Description:
  75. This routine is called by the Operating System to create a new
  76. instance of a Litronic 220 Smartcard Reader. Still can't touch hardware
  77. at this point, or submit requests to the serial driver. But at
  78. least at this point we get a handle to the serial bus driver, which
  79. we'll use in submitting requests in the future.
  80. Arguments:
  81. DriverObject - Pointer to our driver object
  82. PhysicalDeviceObject - Pointer to Device Object created by parent
  83. Return Value:
  84. Status is returned.
  85. --*/
  86. {
  87. NTSTATUS status = STATUS_SUCCESS;
  88. PDEVICE_OBJECT DeviceObject = NULL;
  89. PSMARTCARD_EXTENSION SmartcardExtension = NULL;
  90. PDEVICE_EXTENSION deviceExtension = NULL;
  91. PREADER_EXTENSION ReaderExtension = NULL;
  92. static BYTE devUnitNo = 0;
  93. BOOLEAN smclibInitialized = FALSE;
  94. BOOLEAN symbolicLinkCreated = FALSE;
  95. BOOLEAN deviceInterfaceStateSet = FALSE;
  96. KIRQL oldIrql;
  97. SmartcardDebug(
  98. DEBUG_DRIVER,
  99. ("%s!Lit220AddDevice: enter\n",
  100. DRIVER_NAME)
  101. );
  102. try {
  103. //
  104. // Create our device object with a our own specific device
  105. // extension.
  106. //
  107. status = IoCreateDevice(
  108. DriverObject,
  109. sizeof(DEVICE_EXTENSION),
  110. NULL,
  111. FILE_DEVICE_SMARTCARD,
  112. 0,
  113. TRUE,
  114. &DeviceObject
  115. );
  116. if (!NT_SUCCESS(status)) {
  117. if (status == STATUS_INSUFFICIENT_RESOURCES) {
  118. SmartcardLogError(
  119. DriverObject,
  120. LIT220_INSUFFICIENT_RESOURCES,
  121. NULL,
  122. 0
  123. );
  124. } else {
  125. SmartcardLogError(
  126. DriverObject,
  127. LIT220_NAME_CONFLICT,
  128. NULL,
  129. 0
  130. );
  131. }
  132. leave;
  133. }
  134. //
  135. // Allocate data struct space for smart card reader
  136. //
  137. SmartcardExtension = DeviceObject->DeviceExtension;
  138. deviceExtension = DeviceObject->DeviceExtension;
  139. SmartcardExtension->ReaderExtension = ExAllocatePool(
  140. NonPagedPool,
  141. sizeof(READER_EXTENSION)
  142. );
  143. if (SmartcardExtension->ReaderExtension == NULL) {
  144. SmartcardLogError(
  145. DriverObject,
  146. LIT220_INSUFFICIENT_RESOURCES,
  147. NULL,
  148. 0
  149. );
  150. status = STATUS_INSUFFICIENT_RESOURCES;
  151. leave;
  152. }
  153. ReaderExtension = SmartcardExtension->ReaderExtension;
  154. // Zero the contents of the ReaderExtension
  155. RtlZeroMemory(
  156. SmartcardExtension->ReaderExtension,
  157. sizeof(READER_EXTENSION)
  158. );
  159. //
  160. // Attach ourself into the driver stack on top of our parent (serial).
  161. //
  162. ReaderExtension->BusDeviceObject = IoAttachDeviceToDeviceStack(
  163. DeviceObject,
  164. PhysicalDeviceObject
  165. );
  166. if (!ReaderExtension->BusDeviceObject) {
  167. status = STATUS_NO_SUCH_DEVICE;
  168. SmartcardLogError(
  169. DriverObject,
  170. LIT220_SERIAL_CONNECTION_FAILURE,
  171. NULL,
  172. 0
  173. );
  174. leave;
  175. }
  176. // Set flag so if something fails we know to disable the interface
  177. deviceInterfaceStateSet = TRUE;
  178. //
  179. // Initialize Smartcard Library
  180. //
  181. //
  182. // Write the version of the lib we use to the smartcard extension
  183. //
  184. SmartcardExtension->Version = SMCLIB_VERSION;
  185. SmartcardExtension->SmartcardReply.BufferSize =
  186. MIN_BUFFER_SIZE;
  187. SmartcardExtension->SmartcardRequest.BufferSize =
  188. MIN_BUFFER_SIZE;
  189. //
  190. // Now let the lib allocate the buffer for data transmission
  191. // We can either tell the lib how big the buffer should be
  192. // by assigning a value to BufferSize or let the lib
  193. // allocate the default size
  194. //
  195. status = SmartcardInitialize(
  196. SmartcardExtension
  197. );
  198. if (status != STATUS_SUCCESS) {
  199. SmartcardLogError(
  200. DriverObject,
  201. LIT220_SMARTCARD_LIB_ERROR,
  202. NULL,
  203. 0
  204. );
  205. leave;
  206. }
  207. // Set flag so if something fails we know to exit out of the
  208. // smartcard library
  209. smclibInitialized = TRUE;
  210. status = IoInitializeTimer(
  211. DeviceObject,
  212. Lit220ReceiveBlockTimeout,
  213. NULL
  214. );
  215. if (status != STATUS_SUCCESS) {
  216. SmartcardLogError(
  217. DriverObject,
  218. LIT220_INSUFFICIENT_RESOURCES,
  219. NULL,
  220. 0
  221. );
  222. status = STATUS_INSUFFICIENT_RESOURCES;
  223. leave;
  224. }
  225. deviceExtension->WorkItem = NULL;
  226. deviceExtension->WorkItem = IoAllocateWorkItem(
  227. DeviceObject
  228. );
  229. if (deviceExtension->WorkItem == NULL) {
  230. SmartcardLogError(
  231. DriverObject,
  232. LIT220_INSUFFICIENT_RESOURCES,
  233. NULL,
  234. 0
  235. );
  236. status = STATUS_INSUFFICIENT_RESOURCES;
  237. leave;
  238. }
  239. // register our new device
  240. status = IoRegisterDeviceInterface(
  241. PhysicalDeviceObject,
  242. &SmartCardReaderGuid,
  243. NULL,
  244. &deviceExtension->PnPDeviceName
  245. );
  246. ASSERT(status == STATUS_SUCCESS);
  247. SmartcardDebug(
  248. DEBUG_DRIVER,
  249. ("%s!Lit220AddDevice: DevName - %ws\n",
  250. DRIVER_NAME, deviceExtension->PnPDeviceName.Buffer)
  251. );
  252. //
  253. // Initialize some events
  254. //
  255. KeInitializeEvent(&ReaderExtension->AckEvnt,
  256. NotificationEvent,
  257. FALSE);
  258. KeInitializeEvent(&ReaderExtension->DataEvnt,
  259. NotificationEvent,
  260. FALSE);
  261. KeInitializeEvent(
  262. &deviceExtension->SerialCloseDone,
  263. NotificationEvent,
  264. TRUE
  265. );
  266. // Used for stop / start notification
  267. KeInitializeEvent(
  268. &deviceExtension->ReaderStarted,
  269. NotificationEvent,
  270. FALSE
  271. );
  272. // Used to keep track of open close calls
  273. deviceExtension->ReaderOpen = FALSE;
  274. } finally {
  275. if (status != STATUS_SUCCESS) {
  276. Lit220RemoveDevice(DeviceObject);
  277. }
  278. }
  279. if (status != STATUS_SUCCESS) {
  280. return (status);
  281. }
  282. //
  283. // Set up call back functions for smartcard library
  284. //
  285. SmartcardExtension->ReaderFunction[RDF_TRANSMIT] =
  286. Lit220IoRequest;
  287. SmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] =
  288. Lit220SetProtocol;
  289. SmartcardExtension->ReaderFunction[RDF_CARD_POWER] =
  290. Lit220Power;
  291. SmartcardExtension->ReaderFunction[RDF_CARD_TRACKING] =
  292. Lit220CardTracking;
  293. //
  294. // Save deviceObject
  295. //
  296. KeAcquireSpinLock(
  297. &SmartcardExtension->OsData->SpinLock,
  298. &oldIrql
  299. );
  300. SmartcardExtension->OsData->DeviceObject =
  301. DeviceObject;
  302. //
  303. // Set the Current and Notification IRPs to NULL
  304. //
  305. SmartcardExtension->OsData->CurrentIrp = NULL;
  306. SmartcardExtension->OsData->NotificationIrp = NULL;
  307. KeReleaseSpinLock(
  308. &SmartcardExtension->OsData->SpinLock,
  309. oldIrql
  310. );
  311. //
  312. // Save the deviceObject for the connected serial port
  313. //
  314. SmartcardExtension->ReaderExtension->ConnectedSerialPort =
  315. PhysicalDeviceObject;
  316. //
  317. // Set the vendor info
  318. //
  319. strcpy(
  320. SmartcardExtension->VendorAttr.VendorName.Buffer,
  321. LIT220_VENDOR_NAME);
  322. SmartcardExtension->VendorAttr.VendorName.Length =
  323. (USHORT) strlen(SmartcardExtension->VendorAttr.VendorName.Buffer);
  324. SmartcardExtension->VendorAttr.UnitNo = devUnitNo++;
  325. strcpy(
  326. SmartcardExtension->VendorAttr.IfdType.Buffer,
  327. LIT220_PRODUCT_NAME);
  328. SmartcardExtension->VendorAttr.IfdType.Length =
  329. (USHORT) strlen(SmartcardExtension->VendorAttr.IfdType.Buffer);
  330. //
  331. // Clk frequency in KHz encoded as little endian integer
  332. //
  333. SmartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3571;
  334. SmartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3571;
  335. SmartcardExtension->ReaderCapabilities.DataRate.Default = 9600;
  336. SmartcardExtension->ReaderCapabilities.DataRate.Max = 115200;
  337. SmartcardExtension->ReaderCapabilities.MaxIFSD = MAX_IFSD;
  338. SmartcardExtension->ReaderCapabilities.SupportedProtocols =
  339. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  340. // Save a copy to the PhysicalDeviceObject
  341. ReaderExtension->PhysicalDeviceObject = PhysicalDeviceObject;
  342. // Set initial state for SerialEventState
  343. SmartcardExtension->ReaderExtension->SerialEventState = 0;
  344. // Device is connected
  345. SmartcardExtension->ReaderExtension->DeviceRemoved = FALSE;
  346. // Assume reader is attached until we ask the serial driver
  347. SmartcardExtension->ReaderExtension->ModemStatus = SERIAL_DSR_STATE;
  348. // Set initial power state
  349. deviceExtension->PowerState = PowerDeviceD0;
  350. // save the current power state of the reader
  351. SmartcardExtension->ReaderExtension->ReaderPowerState =
  352. PowerReaderWorking;
  353. // Clear the DO_DEVICE_INITIALIZING bit
  354. DeviceObject->Flags |= DO_BUFFERED_IO;
  355. DeviceObject->Flags |= DO_POWER_PAGABLE;
  356. DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  357. return status;
  358. }
  359. VOID
  360. Lit220CloseSerialPort(
  361. IN PDEVICE_OBJECT DeviceObject,
  362. IN PVOID Context
  363. )
  364. /*++
  365. Routine Description:
  366. This routine closes the connection to the serial driver when the
  367. reader has been removed (unplugged). This routine runs as a system
  368. thread at IRQL == PASSIVE_LEVEL.
  369. It waits for a DeviceClose event sent by another part of the driver to
  370. indicate that the serial connection should be close.
  371. If the notification IRP is still pending we complete it.
  372. Once the connection is closed it will signal the SerialCloseDone event so the
  373. PnP Remove IRP knows when it is safe to unload the device.
  374. */
  375. {
  376. PSMARTCARD_EXTENSION SmartcardExtension = DeviceObject->DeviceExtension;
  377. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  378. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  379. NTSTATUS status;
  380. PIRP irp;
  381. PIO_STACK_LOCATION irpStack;
  382. IO_STATUS_BLOCK ioStatusBlock;
  383. KIRQL oldIrql;
  384. //
  385. // first mark this device as 'gone'.
  386. // This will prevent that someone can re-open the device
  387. //
  388. // We intentionally ignore error here for the case we are disabling an interface
  389. // that is already disabled.
  390. //
  391. IoSetDeviceInterfaceState(
  392. &deviceExtension->PnPDeviceName,
  393. FALSE
  394. );
  395. // Mark the device as removed so no more IRPs will be sent to the
  396. // serial port
  397. ReaderExtension->DeviceRemoved = TRUE;
  398. SmartcardDebug(
  399. DEBUG_DRIVER,
  400. ("%s!Lit220CloseSerialPort: Got Close signal. Checking if we can remove device now.\n",
  401. DRIVER_NAME)
  402. );
  403. //
  404. // Cancel the Notification IRP if it is around
  405. //
  406. Lit220CompleteCardTracking(SmartcardExtension);
  407. SmartcardDebug(
  408. DEBUG_DRIVER,
  409. ("%s!Lit220CloseSerialPort: Sending IRP_MJ_CLOSE\n",
  410. DRIVER_NAME)
  411. );
  412. //
  413. // Create an IRP for closing the serial driver
  414. //
  415. irp = IoAllocateIrp(
  416. (CCHAR)(DeviceObject->StackSize + 1),
  417. FALSE
  418. );
  419. ASSERT(irp != NULL);
  420. if (irp) {
  421. //
  422. // Send a close to the serial driver. The serial enumerator
  423. // will receive this and start tracking again. This will
  424. // eventually trigger a device removal.
  425. //
  426. IoSetNextIrpStackLocation(irp);
  427. irp->UserIosb = &ioStatusBlock;
  428. irpStack = IoGetCurrentIrpStackLocation(irp);
  429. irpStack->MajorFunction = IRP_MJ_CLOSE;
  430. status = Lit220CallSerialDriver(
  431. ReaderExtension->BusDeviceObject,
  432. irp
  433. );
  434. ASSERT(status == STATUS_SUCCESS);
  435. IoFreeIrp(irp);
  436. } else {
  437. SmartcardDebug(
  438. DEBUG_ERROR,
  439. ("%s!Lit220CloseSerialPort: Could not allocate IRP for close!\n",
  440. DRIVER_NAME)
  441. );
  442. }
  443. // Inform the remove function that the call is complete
  444. KeSetEvent(
  445. &deviceExtension->SerialCloseDone,
  446. 0,
  447. FALSE
  448. );
  449. }
  450. NTSTATUS
  451. Lit220SerialCallComplete(
  452. IN PDEVICE_OBJECT DeviceObject,
  453. IN PIRP Irp,
  454. IN PKEVENT Event)
  455. /*++
  456. Routine Description:
  457. Completion routine for an Irp sent to the serial driver.
  458. It sets only an event that we can use to wait for.
  459. --*/
  460. {
  461. UNREFERENCED_PARAMETER (DeviceObject);
  462. SmartcardDebug(
  463. DEBUG_TRACE,
  464. ("%s!Lit220SerialCallComplete: enter\n",
  465. DRIVER_NAME)
  466. );
  467. if (Irp->Cancel) {
  468. Irp->IoStatus.Status = STATUS_CANCELLED;
  469. }
  470. KeSetEvent(Event, 0, FALSE);
  471. return STATUS_MORE_PROCESSING_REQUIRED;
  472. }
  473. NTSTATUS
  474. Lit220CallSerialDriver(
  475. IN PDEVICE_OBJECT DeviceObject,
  476. IN PIRP Irp)
  477. /*++
  478. Routine Description:
  479. Sends an Irp to the serial driver.
  480. --*/
  481. {
  482. NTSTATUS status = STATUS_SUCCESS;
  483. KEVENT Event;
  484. // Copy out stack location to the next
  485. IoCopyCurrentIrpStackLocationToNext(Irp);
  486. // Initializate event for process synchronication.
  487. KeInitializeEvent(
  488. &Event,
  489. NotificationEvent,
  490. FALSE
  491. );
  492. // Set the completion routine
  493. IoSetCompletionRoutine(
  494. Irp,
  495. Lit220SerialCallComplete,
  496. &Event,
  497. TRUE,
  498. TRUE,
  499. TRUE
  500. );
  501. // Call the serial driver
  502. status = IoCallDriver(
  503. DeviceObject,
  504. Irp
  505. );
  506. // Wait for it to complete
  507. if (status == STATUS_PENDING) {
  508. status = KeWaitForSingleObject(
  509. &Event,
  510. Executive,
  511. KernelMode,
  512. FALSE,
  513. NULL
  514. );
  515. ASSERT(STATUS_SUCCESS == status);
  516. status = Irp->IoStatus.Status;
  517. }
  518. return status;
  519. }
  520. NTSTATUS
  521. Lit220PnP(
  522. IN PDEVICE_OBJECT DeviceObject,
  523. IN PIRP Irp
  524. )
  525. /*++
  526. Routine Description:
  527. This routine will receive the various Plug N Play messages. It is
  528. here that we start our device, stop it, etc. Safe to submit requests
  529. to the serial bus driver.
  530. Arguments:
  531. DeviceObject - Pointer to class device object.
  532. Irp - Pointer to the request packet.
  533. Return Value:
  534. Status is returned.
  535. --*/
  536. {
  537. KEVENT Event;
  538. NTSTATUS status;
  539. PIO_STACK_LOCATION IrpStack;
  540. PSMARTCARD_EXTENSION SmartcardExtension = DeviceObject->DeviceExtension;
  541. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  542. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  543. PDEVICE_OBJECT busDeviceObject = ReaderExtension->BusDeviceObject;
  544. PIRP pIrp = NULL;
  545. IO_STATUS_BLOCK ioStatusBlock;
  546. LARGE_INTEGER Interval;
  547. PIRP createIrp = NULL;
  548. HANDLE handle;
  549. PIO_STACK_LOCATION NextIrpStack;
  550. PIRP irp;
  551. BOOLEAN deviceRemoved = FALSE;
  552. KIRQL irql;
  553. status = SmartcardAcquireRemoveLockWithTag(
  554. SmartcardExtension,
  555. 'PnP'
  556. );
  557. ASSERT(status == STATUS_SUCCESS);
  558. if (status != STATUS_SUCCESS) {
  559. Irp->IoStatus.Information = 0;
  560. Irp->IoStatus.Status = status;
  561. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  562. return status;
  563. }
  564. //
  565. // pull the minor code out of our Irp Stack so we know what
  566. // PnP function we're supposed to do
  567. //
  568. IrpStack = IoGetCurrentIrpStackLocation(Irp);
  569. ASSERT(IrpStack);
  570. SmartcardDebug(
  571. DEBUG_TRACE,
  572. ("%s!Lit220PnP: Enter - MinorFunction %X\n",
  573. DRIVER_NAME,
  574. IrpStack->MinorFunction)
  575. );
  576. switch (IrpStack->MinorFunction) {
  577. PDEVICE_OBJECT BusDeviceObject = ReaderExtension->BusDeviceObject;
  578. case IRP_MN_START_DEVICE:
  579. SmartcardDebug(
  580. DEBUG_DRIVER,
  581. ("%s!Lit220PnP: MN_START_DEVICE\n",
  582. DRIVER_NAME)
  583. );
  584. //
  585. // Before we start initializing our device, we must
  586. // call to the layer below us first.
  587. //
  588. IoCopyCurrentIrpStackLocationToNext (Irp);
  589. KeInitializeEvent(
  590. &Event,
  591. SynchronizationEvent,
  592. FALSE
  593. );
  594. IoSetCompletionRoutine(
  595. Irp,
  596. Lit220SynchCompletionRoutine,
  597. &Event,
  598. TRUE,
  599. TRUE,
  600. TRUE
  601. );
  602. //
  603. // Call down to the serial bus driver.
  604. //
  605. status = IoCallDriver(
  606. ReaderExtension->BusDeviceObject,
  607. Irp
  608. );
  609. if (status == STATUS_PENDING) {
  610. //
  611. // Still pending, wait for the IRP to complete
  612. //
  613. status = KeWaitForSingleObject(
  614. &Event,
  615. Executive,
  616. KernelMode,
  617. FALSE,
  618. NULL
  619. );
  620. }
  621. if (NT_SUCCESS(status)) {
  622. status = Lit220StartDevice(SmartcardExtension);
  623. } else {
  624. SmartcardLogError(
  625. SmartcardExtension->OsData->DeviceObject,
  626. LIT220_SERIAL_CONNECTION_FAILURE,
  627. NULL,
  628. 0
  629. );
  630. }
  631. //
  632. // Complete the IRP first otherwise if we failed we may remove
  633. // the driver before we have a chance to complete this IRP.
  634. // Causing a system crash.
  635. //
  636. Irp->IoStatus.Status = status;
  637. Irp->IoStatus.Information = 0;
  638. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  639. break;
  640. case IRP_MN_QUERY_STOP_DEVICE:
  641. SmartcardDebug(
  642. DEBUG_DRIVER,
  643. ("%s!Lit220PnP: IRP_MN_QUERY_STOP_DEVICE\n",
  644. DRIVER_NAME)
  645. );
  646. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  647. if ((deviceExtension->IoCount > 0) /* ***&& (!ReaderExtension->DeviceRemoved)*/) {
  648. // we refuse to stop if we have pending io
  649. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  650. status = STATUS_DEVICE_BUSY;
  651. } else {
  652. // stop processing requests
  653. KeClearEvent(&deviceExtension->ReaderStarted);
  654. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  655. IoCopyCurrentIrpStackLocationToNext (Irp);
  656. status = IoCallDriver(ReaderExtension->BusDeviceObject, Irp);
  657. }
  658. break;
  659. case IRP_MN_CANCEL_STOP_DEVICE:
  660. SmartcardDebug(
  661. DEBUG_DRIVER,
  662. ("%s!Lit220PnP: IRP_MN_CANCEL_STOP_DEVICE\n",
  663. DRIVER_NAME)
  664. );
  665. IoCopyCurrentIrpStackLocationToNext (Irp);
  666. status = IoCallDriver(ReaderExtension->BusDeviceObject, Irp);
  667. if (status == STATUS_SUCCESS) {
  668. // we can continue to process requests
  669. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  670. }
  671. break;
  672. case IRP_MN_STOP_DEVICE:
  673. //
  674. // Do whatever you need to do to shutdown the device.
  675. //
  676. SmartcardDebug(
  677. DEBUG_DRIVER,
  678. ("%s!Lit220PnP: MN_STOP_DEVICE\n",
  679. DRIVER_NAME)
  680. );
  681. Lit220StopDevice(SmartcardExtension);
  682. //
  683. // Send the stop IRP down
  684. //
  685. IoCopyCurrentIrpStackLocationToNext (Irp);
  686. status = (IoCallDriver(
  687. ReaderExtension->BusDeviceObject,
  688. Irp)
  689. );
  690. break;
  691. case IRP_MN_QUERY_REMOVE_DEVICE:
  692. // now look if someone is currently connected to us
  693. if (deviceExtension->ReaderOpen) {
  694. //
  695. // someone is connected, fail the call
  696. // we will enable the device interface in
  697. // IRP_MN_CANCEL_REMOVE_DEVICE again
  698. //
  699. status = STATUS_UNSUCCESSFUL;
  700. Irp->IoStatus.Status = status;
  701. Irp->IoStatus.Information = 0;
  702. IoCompleteRequest (
  703. Irp,
  704. IO_NO_INCREMENT
  705. );
  706. break;
  707. }
  708. // disable the reader
  709. status = IoSetDeviceInterfaceState(
  710. &deviceExtension->PnPDeviceName,
  711. FALSE
  712. );
  713. // Send the call down the DevNode
  714. IoCopyCurrentIrpStackLocationToNext (Irp);
  715. status = IoCallDriver(
  716. ReaderExtension->BusDeviceObject,
  717. Irp
  718. );
  719. break;
  720. case IRP_MN_CANCEL_REMOVE_DEVICE:
  721. //
  722. // Send call down to serial driver - we need
  723. // to process this call on the way up the devNode
  724. //
  725. IoCopyCurrentIrpStackLocationToNext (Irp);
  726. //
  727. // Initialize the event
  728. //
  729. KeInitializeEvent(
  730. &Event,
  731. SynchronizationEvent,
  732. FALSE
  733. );
  734. IoSetCompletionRoutine (
  735. Irp,
  736. Lit220SynchCompletionRoutine,
  737. &Event,
  738. TRUE,
  739. TRUE,
  740. TRUE
  741. );
  742. status = IoCallDriver (
  743. ReaderExtension->BusDeviceObject,
  744. Irp
  745. );
  746. if (STATUS_PENDING == status) {
  747. KeWaitForSingleObject(
  748. &Event,
  749. Executive, // Waiting for reason of a driver
  750. KernelMode, // Waiting in kernel mode
  751. FALSE, // No allert
  752. NULL // No timeout
  753. );
  754. status = Irp->IoStatus.Status;
  755. }
  756. // Re-enable the device interface
  757. if ((status == STATUS_SUCCESS) &&
  758. (ReaderExtension->SerialConfigData.WaitMask != 0))
  759. {
  760. status = IoSetDeviceInterfaceState(
  761. &deviceExtension->PnPDeviceName,
  762. TRUE
  763. );
  764. ASSERT(NT_SUCCESS(status));
  765. }
  766. //
  767. // We must now complete the IRP, since we stopped it in the
  768. // completetion routine with MORE_PROCESSING_REQUIRED.
  769. //
  770. Irp->IoStatus.Status = status;
  771. Irp->IoStatus.Information = 0;
  772. IoCompleteRequest (
  773. Irp,
  774. IO_NO_INCREMENT
  775. );
  776. break;
  777. case IRP_MN_REMOVE_DEVICE:
  778. SmartcardDebug(
  779. DEBUG_DRIVER,
  780. ("%s!Lit220PnP: MN_REMOVE_DEVICE\n",
  781. DRIVER_NAME)
  782. );
  783. // Wait until we can safely unload the device
  784. SmartcardReleaseRemoveLockAndWait(SmartcardExtension);
  785. Lit220RemoveDevice(DeviceObject);
  786. // Mark the device as removed
  787. deviceRemoved = TRUE;
  788. //
  789. // Send on the remove IRP.
  790. // We need to send the remove down the stack before we detach,
  791. // but we don't need to wait for the completion of this operation
  792. // (and to register a completion routine).
  793. //
  794. IoCopyCurrentIrpStackLocationToNext (Irp);
  795. status = IoCallDriver(
  796. busDeviceObject,
  797. Irp
  798. );
  799. break;
  800. default:
  801. IoCopyCurrentIrpStackLocationToNext (Irp);
  802. status = IoCallDriver(
  803. ReaderExtension->BusDeviceObject,
  804. Irp
  805. );
  806. break;
  807. }
  808. if (deviceRemoved == FALSE) {
  809. SmartcardReleaseRemoveLockWithTag(
  810. SmartcardExtension,
  811. 'PnP'
  812. );
  813. }
  814. SmartcardDebug(
  815. DEBUG_TRACE,
  816. ("%s!Lit220PnP: Exit %X\n",
  817. DRIVER_NAME,
  818. status)
  819. );
  820. return status;
  821. }
  822. NTSTATUS
  823. Lit220StartDevice(
  824. IN PSMARTCARD_EXTENSION SmartcardExtension
  825. )
  826. {
  827. PDEVICE_OBJECT deviceObject = SmartcardExtension->OsData->DeviceObject;
  828. PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension;
  829. PREADER_EXTENSION readerExtension = SmartcardExtension->ReaderExtension;
  830. NTSTATUS status;
  831. KEVENT Event;
  832. PIRP irp;
  833. IO_STATUS_BLOCK ioStatusBlock;
  834. PIO_STACK_LOCATION IrpStack;
  835. PAGED_CODE();
  836. try {
  837. //
  838. // Send a create IRP to the serial driver
  839. //
  840. KeInitializeEvent(
  841. &Event,
  842. NotificationEvent,
  843. FALSE
  844. );
  845. //
  846. // Create an IRP for opening the serial driver
  847. //
  848. irp = IoAllocateIrp(
  849. (CCHAR)(deviceObject->StackSize + 1),
  850. FALSE
  851. );
  852. ASSERT(irp != NULL);
  853. if (irp == NULL) {
  854. status = STATUS_INSUFFICIENT_RESOURCES;
  855. SmartcardLogError(
  856. SmartcardExtension->OsData->DeviceObject,
  857. LIT220_INSUFFICIENT_RESOURCES,
  858. NULL,
  859. 0
  860. );
  861. leave;
  862. }
  863. //
  864. // Open the underlying serial driver.
  865. // This is necessary for two reasons:
  866. // a) The serial driver can't be used without opening it
  867. // b) The call will go through serenum first which informs
  868. // it to stop looking/polling for new devices.
  869. //
  870. IoSetNextIrpStackLocation(irp);
  871. irp->UserIosb = &ioStatusBlock;
  872. IrpStack = IoGetCurrentIrpStackLocation(irp);
  873. IrpStack->MajorFunction = IRP_MJ_CREATE;
  874. IrpStack->MinorFunction = 0UL;
  875. IrpStack->Parameters.Create.Options = 0;
  876. IrpStack->Parameters.Create.ShareAccess = 0;
  877. IrpStack->Parameters.Create.FileAttributes = 0;
  878. IrpStack->Parameters.Create.EaLength = 0;
  879. status = Lit220CallSerialDriver(
  880. readerExtension->BusDeviceObject,
  881. irp
  882. );
  883. ASSERT(status == STATUS_SUCCESS);
  884. IoFreeIrp(irp);
  885. if (status != STATUS_SUCCESS) {
  886. SmartcardDebug(
  887. DEBUG_ERROR,
  888. ("%s!Lit220PNP: CreateIRP failed %X\n",
  889. DRIVER_NAME,
  890. status)
  891. );
  892. if (status == STATUS_SHARED_IRQ_BUSY) {
  893. SmartcardLogError(
  894. SmartcardExtension->OsData->DeviceObject,
  895. LIT220_SERIAL_SHARE_IRQ_CONFLICT,
  896. NULL,
  897. 0
  898. );
  899. } else {
  900. SmartcardLogError(
  901. SmartcardExtension->OsData->DeviceObject,
  902. LIT220_SERIAL_CONNECTION_FAILURE,
  903. NULL,
  904. 0
  905. );
  906. }
  907. leave;
  908. }
  909. KeClearEvent(&deviceExtension->SerialCloseDone);
  910. //
  911. // Configure the reader
  912. //
  913. SmartcardDebug(
  914. DEBUG_DRIVER,
  915. ("%s!Lit220PnP: Now doing Lit220Initialize - SmartcardExt %X\n",
  916. DRIVER_NAME,
  917. SmartcardExtension)
  918. );
  919. ASSERT(SmartcardExtension != NULL);
  920. status = Lit220Initialize(SmartcardExtension);
  921. if (status != STATUS_SUCCESS) {
  922. // The function fails in Lit220Initialize will log
  923. // the appropriate error. So we don't need to do that
  924. // here
  925. SmartcardDebug(
  926. DEBUG_ERROR,
  927. ("%s!Lit220PNP: Lit220Initialize failed %X\n",
  928. DRIVER_NAME,
  929. status)
  930. );
  931. SmartcardLogError(
  932. SmartcardExtension->OsData->DeviceObject,
  933. LIT220_INITIALIZATION_FAILURE,
  934. NULL,
  935. 0
  936. );
  937. leave;
  938. }
  939. // Enable the interface for the device
  940. status = IoSetDeviceInterfaceState(
  941. &deviceExtension->PnPDeviceName,
  942. TRUE
  943. );
  944. if (!NT_SUCCESS(status)) {
  945. SmartcardLogError(
  946. SmartcardExtension->OsData->DeviceObject,
  947. LIT220_SERIAL_CONNECTION_FAILURE,
  948. NULL,
  949. 0
  950. );
  951. leave;
  952. }
  953. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  954. }
  955. finally {
  956. if (status != STATUS_SUCCESS) {
  957. Lit220StopDevice(SmartcardExtension);
  958. }
  959. }
  960. return status;
  961. }
  962. VOID
  963. Lit220StopDevice(
  964. IN PSMARTCARD_EXTENSION SmartcardExtension
  965. )
  966. /*++
  967. Routine Description:
  968. This routine handles stopping the device. It closes
  969. connection to serial port and stops the input filter
  970. if it has been activated.
  971. Arguments:
  972. SmartcardExtension - pointer to the smart card data struct.
  973. Return Value:
  974. NTSTATUS
  975. --*/
  976. {
  977. PDEVICE_OBJECT deviceObject = SmartcardExtension->OsData->DeviceObject;
  978. PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension;
  979. PREADER_EXTENSION readerExtension = SmartcardExtension->ReaderExtension;
  980. NTSTATUS status;
  981. PAGED_CODE();
  982. if (KeReadStateEvent(&deviceExtension->SerialCloseDone) == 0l) {
  983. // test if we ever started event tracking
  984. if (SmartcardExtension->ReaderExtension->SerialConfigData.WaitMask == 0) {
  985. // no, we did not
  986. // We 'only' need to close the serial port
  987. Lit220CloseSerialPort(deviceObject, NULL);
  988. } else {
  989. PUCHAR requestBuffer;
  990. //
  991. // Stop the wait for character input and DSR changes.
  992. // When this happens it will signal the our waitforclose
  993. // thread to close the connection to the serial driver (if
  994. // it is not already closed).
  995. //
  996. readerExtension->SerialConfigData.WaitMask = 0;
  997. // save the pointer
  998. requestBuffer = SmartcardExtension->SmartcardRequest.Buffer;
  999. // Stop the event requests
  1000. *(PULONG) SmartcardExtension->SmartcardRequest.Buffer =
  1001. readerExtension->SerialConfigData.WaitMask;
  1002. SmartcardExtension->SmartcardRequest.BufferLength =
  1003. sizeof(ULONG);
  1004. readerExtension->SerialIoControlCode =
  1005. IOCTL_SERIAL_SET_WAIT_MASK;
  1006. // No bytes expected back
  1007. SmartcardExtension->SmartcardReply.BufferLength = 0;
  1008. status = Lit220SerialIo(SmartcardExtension);
  1009. ASSERT(status == STATUS_SUCCESS);
  1010. // Restore the pointer
  1011. SmartcardExtension->SmartcardRequest.Buffer = requestBuffer;
  1012. // Wait for the close thread to complete
  1013. KeWaitForSingleObject(
  1014. &deviceExtension->SerialCloseDone,
  1015. Executive,
  1016. KernelMode,
  1017. FALSE,
  1018. NULL
  1019. );
  1020. }
  1021. }
  1022. }
  1023. VOID
  1024. Lit220RemoveDevice(
  1025. IN PDEVICE_OBJECT DeviceObject
  1026. )
  1027. {
  1028. PDEVICE_EXTENSION deviceExtension;
  1029. PSMARTCARD_EXTENSION smartcardExtension;
  1030. NTSTATUS status;
  1031. PAGED_CODE();
  1032. if (DeviceObject == NULL) {
  1033. return;
  1034. }
  1035. deviceExtension = DeviceObject->DeviceExtension;
  1036. smartcardExtension = &deviceExtension->SmartcardExtension;
  1037. SmartcardDebug(
  1038. DEBUG_TRACE,
  1039. ( "%s!Lit220RemoveDevice: Enter\n",
  1040. DRIVER_NAME)
  1041. );
  1042. // We need to stop the device before we can remove it.
  1043. Lit220StopDevice(smartcardExtension);
  1044. /* Superfluous -- Remove later
  1045. // now wait until our device has been closed
  1046. status = KeWaitForSingleObject(
  1047. &deviceExtension->ReaderClosed,
  1048. Executive,
  1049. KernelMode,
  1050. FALSE,
  1051. NULL
  1052. );
  1053. ASSERT(status == STATUS_SUCCESS);
  1054. */
  1055. //
  1056. // Clean ourself out of the driver stack layer
  1057. //
  1058. if (deviceExtension->SmartcardExtension.ReaderExtension &&
  1059. deviceExtension->SmartcardExtension.ReaderExtension->BusDeviceObject) {
  1060. IoDetachDevice(
  1061. deviceExtension->SmartcardExtension.ReaderExtension->BusDeviceObject
  1062. );
  1063. }
  1064. // Free PnPDeviceName
  1065. if(deviceExtension->PnPDeviceName.Buffer != NULL) {
  1066. RtlFreeUnicodeString(&deviceExtension->PnPDeviceName);
  1067. }
  1068. //
  1069. // Let the lib free the send/receive buffers
  1070. //
  1071. if(smartcardExtension->OsData != NULL) {
  1072. SmartcardExit(smartcardExtension);
  1073. }
  1074. // Free reader extension
  1075. if (smartcardExtension->ReaderExtension != NULL) {
  1076. ExFreePool(smartcardExtension->ReaderExtension);
  1077. }
  1078. // Free the work item
  1079. if (deviceExtension->WorkItem != NULL) {
  1080. IoFreeWorkItem(deviceExtension->WorkItem);
  1081. deviceExtension->WorkItem = NULL;
  1082. }
  1083. // Delete the device object
  1084. IoDeleteDevice(DeviceObject);
  1085. }
  1086. NTSTATUS
  1087. Lit220SynchCompletionRoutine(
  1088. IN PDEVICE_OBJECT DeviceObject,
  1089. IN PIRP Irp,
  1090. IN PKEVENT Event
  1091. )
  1092. /*++
  1093. Routine Description:
  1094. This routine is for use with synchronous IRP processing.
  1095. All it does is signal an event, so the driver knows it
  1096. can continue.
  1097. Arguments:
  1098. DriverObject - Pointer to driver object created by system.
  1099. Irp - Irp that just completed
  1100. Event - Event we'll signal to say Irp is done
  1101. Return Value:
  1102. None.
  1103. --*/
  1104. {
  1105. SmartcardDebug(
  1106. DEBUG_TRACE,
  1107. ("%s!Lit220SynchCompletionRoutine: Enter\n",
  1108. DRIVER_NAME)
  1109. );
  1110. KeSetEvent(
  1111. (PKEVENT) Event,
  1112. 0,
  1113. FALSE
  1114. );
  1115. return (STATUS_MORE_PROCESSING_REQUIRED);
  1116. }
  1117. VOID
  1118. Lit220SystemPowerCompletion(
  1119. IN PDEVICE_OBJECT DeviceObject,
  1120. IN UCHAR MinorFunction,
  1121. IN POWER_STATE PowerState,
  1122. IN PIRP Irp,
  1123. IN PIO_STATUS_BLOCK IoStatus
  1124. )
  1125. /*++
  1126. Routine Description:
  1127. This function is called when the underlying stacks
  1128. completed the power transition.
  1129. --*/
  1130. {
  1131. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1132. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  1133. UNREFERENCED_PARAMETER (MinorFunction);
  1134. Irp->IoStatus.Information = 0;
  1135. Irp->IoStatus.Status = IoStatus->Status;
  1136. SmartcardReleaseRemoveLockWithTag(
  1137. smartcardExtension,
  1138. 'rwoP'
  1139. );
  1140. if (PowerState.SystemState == PowerSystemWorking) {
  1141. PoSetPowerState (
  1142. DeviceObject,
  1143. SystemPowerState,
  1144. PowerState
  1145. );
  1146. }
  1147. PoStartNextPowerIrp(Irp);
  1148. IoSkipCurrentIrpStackLocation(Irp);
  1149. PoCallDriver(smartcardExtension->ReaderExtension->BusDeviceObject, Irp);
  1150. // IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1151. }
  1152. NTSTATUS
  1153. Lit220DevicePowerCompletion (
  1154. IN PDEVICE_OBJECT DeviceObject,
  1155. IN PIRP Irp,
  1156. IN PSMARTCARD_EXTENSION SmartcardExtension
  1157. )
  1158. /*++
  1159. Routine Description:
  1160. This routine is called after the underlying stack powered
  1161. UP the serial port, so it can be used again.
  1162. --*/
  1163. {
  1164. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1165. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  1166. NTSTATUS status;
  1167. ULONG state;
  1168. KIRQL irql;
  1169. ASSERT(irpStack != NULL);
  1170. if(Irp->PendingReturned) {
  1171. IoMarkIrpPending(Irp);
  1172. }
  1173. state = Lit220IsCardPresent(SmartcardExtension) ? SCARD_PRESENT : SCARD_ABSENT;
  1174. //
  1175. // Check if the card is inserted
  1176. //
  1177. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  1178. &irql);
  1179. SmartcardExtension->ReaderCapabilities.CurrentState = state;
  1180. //
  1181. // If a card was present before power down or now there is
  1182. // a card in the reader, we complete any pending card monitor
  1183. // request, since we do not really know what card is now in the
  1184. // reader.
  1185. //
  1186. if(SmartcardExtension->ReaderExtension->CardPresent ||
  1187. SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT) {
  1188. state = SmartcardExtension->ReaderCapabilities.CurrentState & SCARD_PRESENT;
  1189. //
  1190. // Issue a power request in order to reset the card's status
  1191. //
  1192. if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_PRESENT) {
  1193. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  1194. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1195. irql);
  1196. status = Lit220Power(SmartcardExtension);
  1197. ASSERT(status == STATUS_SUCCESS);
  1198. } else {
  1199. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1200. irql);
  1201. }
  1202. Lit220NotifyCardChange(
  1203. SmartcardExtension,
  1204. state
  1205. );
  1206. } else {
  1207. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1208. irql);
  1209. }
  1210. // save the current power state of the reader
  1211. SmartcardExtension->ReaderExtension->ReaderPowerState =
  1212. PowerReaderWorking;
  1213. SmartcardReleaseRemoveLockWithTag(
  1214. SmartcardExtension,
  1215. 'rwoP'
  1216. );
  1217. // inform the power manager of our state.
  1218. PoSetPowerState (
  1219. DeviceObject,
  1220. DevicePowerState,
  1221. irpStack->Parameters.Power.State
  1222. );
  1223. PoStartNextPowerIrp(Irp);
  1224. // signal that we can process ioctls again
  1225. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  1226. return STATUS_SUCCESS;
  1227. }
  1228. typedef enum _ACTION {
  1229. Undefined = 0,
  1230. SkipRequest,
  1231. WaitForCompletion,
  1232. CompleteRequest,
  1233. MarkPending
  1234. } ACTION;
  1235. NTSTATUS
  1236. Lit220DispatchPower (
  1237. IN PDEVICE_OBJECT DeviceObject,
  1238. IN PIRP Irp
  1239. )
  1240. /*++
  1241. Routine Description:
  1242. The power dispatch routine.
  1243. All we care about is the transition from a low D state to D0.
  1244. Arguments:
  1245. DeviceObject - pointer to a device object.
  1246. Irp - pointer to an I/O Request Packet.
  1247. Return Value:
  1248. NT status code
  1249. --*/
  1250. {
  1251. NTSTATUS status = STATUS_SUCCESS;
  1252. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  1253. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1254. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  1255. PDEVICE_OBJECT AttachedDeviceObject;
  1256. POWER_STATE powerState;
  1257. ACTION action = SkipRequest;
  1258. KIRQL irql;
  1259. SmartcardDebug(
  1260. DEBUG_DRIVER,
  1261. ("%s!Lit220DispatchPower: Enter\n",
  1262. DRIVER_NAME)
  1263. );
  1264. status = SmartcardAcquireRemoveLockWithTag(
  1265. smartcardExtension,
  1266. 'rwoP'
  1267. );
  1268. ASSERT(status == STATUS_SUCCESS);
  1269. if (!NT_SUCCESS(status)) {
  1270. PoStartNextPowerIrp(Irp);
  1271. Irp->IoStatus.Status = status;
  1272. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1273. return status;
  1274. }
  1275. AttachedDeviceObject = smartcardExtension->ReaderExtension->BusDeviceObject;
  1276. switch (irpStack->Parameters.Power.Type) {
  1277. case DevicePowerState:
  1278. if (irpStack->MinorFunction == IRP_MN_SET_POWER) {
  1279. switch (irpStack->Parameters.Power.State.DeviceState) {
  1280. case PowerDeviceD0:
  1281. // Turn on the reader
  1282. SmartcardDebug(
  1283. DEBUG_DRIVER,
  1284. ("%s!Lit220DispatchPower: PowerDevice D0\n",
  1285. DRIVER_NAME)
  1286. );
  1287. //
  1288. // First, we send down the request to the bus, in order
  1289. // to power on the port. When the request completes,
  1290. // we turn on the reader
  1291. //
  1292. IoCopyCurrentIrpStackLocationToNext(Irp);
  1293. IoSetCompletionRoutine (
  1294. Irp,
  1295. Lit220DevicePowerCompletion,
  1296. smartcardExtension,
  1297. TRUE,
  1298. TRUE,
  1299. TRUE
  1300. );
  1301. action = WaitForCompletion;
  1302. break;
  1303. case PowerDeviceD3:
  1304. // Turn off the reader
  1305. SmartcardDebug(
  1306. DEBUG_DRIVER,
  1307. ("%s!Lit220DispatchPower: PowerDevice D3\n",
  1308. DRIVER_NAME)
  1309. );
  1310. PoSetPowerState (
  1311. DeviceObject,
  1312. DevicePowerState,
  1313. irpStack->Parameters.Power.State
  1314. );
  1315. // save the current card state
  1316. KeAcquireSpinLock(&smartcardExtension->OsData->SpinLock,
  1317. &irql);
  1318. smartcardExtension->ReaderExtension->CardPresent =
  1319. smartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT;
  1320. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  1321. irql);
  1322. if (smartcardExtension->ReaderExtension->CardPresent) {
  1323. smartcardExtension->MinorIoControlCode = SCARD_POWER_DOWN;
  1324. status = Lit220Power(smartcardExtension);
  1325. ASSERT(status == STATUS_SUCCESS);
  1326. }
  1327. //
  1328. // If there is a pending card tracking request, setting
  1329. // this flag will prevent completion of the request
  1330. // when the system will be waked up again.
  1331. //
  1332. smartcardExtension->ReaderExtension->PowerRequest = TRUE;
  1333. // save the current power state of the reader
  1334. smartcardExtension->ReaderExtension->ReaderPowerState =
  1335. PowerReaderOff;
  1336. action = SkipRequest;
  1337. break;
  1338. default:
  1339. ASSERT(FALSE);
  1340. action = SkipRequest;
  1341. break;
  1342. }
  1343. } else {
  1344. ASSERT(FALSE);
  1345. action = SkipRequest;
  1346. break;
  1347. }
  1348. break;
  1349. case SystemPowerState: {
  1350. //
  1351. // The system wants to change the power state.
  1352. // We need to translate the system power state to
  1353. // a corresponding device power state.
  1354. //
  1355. POWER_STATE_TYPE powerType = DevicePowerState;
  1356. ASSERT(smartcardExtension->ReaderExtension->ReaderPowerState !=
  1357. PowerReaderUnspecified);
  1358. switch (irpStack->MinorFunction) {
  1359. case IRP_MN_QUERY_POWER:
  1360. SmartcardDebug(
  1361. DEBUG_DRIVER,
  1362. ("%s!Lit220DispatchPower: Query Power\n",
  1363. DRIVER_NAME)
  1364. );
  1365. //
  1366. // By default we succeed and pass down
  1367. //
  1368. action = SkipRequest;
  1369. Irp->IoStatus.Status = STATUS_SUCCESS;
  1370. switch (irpStack->Parameters.Power.State.SystemState) {
  1371. case PowerSystemMaximum:
  1372. case PowerSystemWorking:
  1373. case PowerSystemSleeping1:
  1374. case PowerSystemSleeping2:
  1375. break;
  1376. case PowerSystemSleeping3:
  1377. case PowerSystemHibernate:
  1378. case PowerSystemShutdown:
  1379. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  1380. if (deviceExtension->IoCount == 0) {
  1381. // Block any further ioctls
  1382. KeClearEvent(&deviceExtension->ReaderStarted);
  1383. } else {
  1384. // can't go to sleep mode since the reader is busy.
  1385. status = STATUS_DEVICE_BUSY;
  1386. action = CompleteRequest;
  1387. }
  1388. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  1389. break;
  1390. }
  1391. break;
  1392. case IRP_MN_SET_POWER:
  1393. SmartcardDebug(
  1394. DEBUG_DRIVER,
  1395. ("%s!Lit220DispatchPower: PowerSystem S%d\n",
  1396. DRIVER_NAME,
  1397. irpStack->Parameters.Power.State.SystemState - 1)
  1398. );
  1399. switch (irpStack->Parameters.Power.State.SystemState) {
  1400. case PowerSystemMaximum:
  1401. case PowerSystemWorking:
  1402. case PowerSystemSleeping1:
  1403. case PowerSystemSleeping2:
  1404. if (smartcardExtension->ReaderExtension->ReaderPowerState ==
  1405. PowerReaderWorking) {
  1406. // We're already in the right state
  1407. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  1408. action = SkipRequest;
  1409. break;
  1410. }
  1411. // wake up the underlying stack...
  1412. powerState.DeviceState = PowerDeviceD0;
  1413. action = MarkPending;
  1414. break;
  1415. case PowerSystemSleeping3:
  1416. case PowerSystemHibernate:
  1417. case PowerSystemShutdown:
  1418. if (smartcardExtension->ReaderExtension->ReaderPowerState ==
  1419. PowerReaderOff) {
  1420. // We're already in the right state
  1421. action = SkipRequest;
  1422. break;
  1423. }
  1424. powerState.DeviceState = PowerDeviceD3;
  1425. // first, inform the power manager of our new state.
  1426. PoSetPowerState (
  1427. DeviceObject,
  1428. SystemPowerState,
  1429. powerState
  1430. );
  1431. action = MarkPending;
  1432. break;
  1433. default:
  1434. ASSERT(FALSE);
  1435. action = CompleteRequest;
  1436. break;
  1437. }
  1438. }
  1439. }
  1440. break;
  1441. default:
  1442. ASSERT(FALSE);
  1443. action = CompleteRequest;
  1444. break;
  1445. }
  1446. switch (action) {
  1447. case CompleteRequest:
  1448. Irp->IoStatus.Status = status;
  1449. Irp->IoStatus.Information = 0;
  1450. SmartcardReleaseRemoveLockWithTag(
  1451. smartcardExtension,
  1452. 'rwoP'
  1453. );
  1454. PoStartNextPowerIrp(Irp);
  1455. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1456. break;
  1457. case MarkPending:
  1458. Irp->IoStatus.Status = STATUS_PENDING;
  1459. IoMarkIrpPending(Irp);
  1460. status = PoRequestPowerIrp (
  1461. DeviceObject,
  1462. IRP_MN_SET_POWER,
  1463. powerState,
  1464. Lit220SystemPowerCompletion,
  1465. Irp,
  1466. NULL
  1467. );
  1468. ASSERT(status == STATUS_PENDING);
  1469. break;
  1470. case SkipRequest:
  1471. SmartcardReleaseRemoveLockWithTag(
  1472. smartcardExtension,
  1473. 'rwoP'
  1474. );
  1475. PoStartNextPowerIrp(Irp);
  1476. IoSkipCurrentIrpStackLocation(Irp);
  1477. status = PoCallDriver(AttachedDeviceObject, Irp);
  1478. break;
  1479. case WaitForCompletion:
  1480. status = PoCallDriver(AttachedDeviceObject, Irp);
  1481. break;
  1482. default:
  1483. ASSERT(FALSE);
  1484. break;
  1485. }
  1486. SmartcardDebug(
  1487. DEBUG_DRIVER,
  1488. ("%s!Lit220DispatchPower: Exit %lx\n",
  1489. DRIVER_NAME,
  1490. status)
  1491. );
  1492. return status;
  1493. }