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.

2391 lines
71 KiB

  1. /*++
  2. Copyright (c) 1997 - 1999 SCM Microsystems, Inc.
  3. Module Name:
  4. PscrNT.c
  5. Abstract:
  6. Main Driver Module - NT Version
  7. Author:
  8. Andreas Straub
  9. Revision History:
  10. Andreas Straub 1.00 8/18/1997 Initial Version
  11. Klaus Schuetz 1.01 9/20/1997 Timing changed
  12. Andreas Straub 1.02 9/24/1997 Low Level error handling,
  13. minor bugfixes, clanup
  14. Andreas Straub 1.03 10/8/1997 Timing changed, generic SCM
  15. interface changed
  16. Andreas Straub 1.04 10/18/1997 Interrupt handling changed
  17. Andreas Straub 1.05 10/19/1997 Generic IOCTL's added
  18. Andreas Straub 1.06 10/25/1997 Timeout limit for FW update variable
  19. Andreas Straub 1.07 11/7/1997 Version information added
  20. Klaus Schuetz 1.08 11/10/1997 PnP capabilities added
  21. Klaus Schuetz Cleanup added
  22. --*/
  23. #include <PscrNT.h>
  24. #include <PscrCmd.h>
  25. #include <PscrCB.h>
  26. #include <PscrLog.h>
  27. #include <PscrVers.h>
  28. #pragma alloc_text(INIT, DriverEntry)
  29. #pragma alloc_text(PAGEABLE, PscrAddDevice)
  30. #pragma alloc_text(PAGEABLE, PscrStartDevice)
  31. #pragma alloc_text(PAGEABLE, PscrUnloadDriver)
  32. #pragma alloc_text(PAGEABLE, PscrCreateClose)
  33. BOOLEAN DeviceSlot[PSCR_MAX_DEVICE];
  34. NTSTATUS
  35. DriverEntry(
  36. PDRIVER_OBJECT DriverObject,
  37. PUNICODE_STRING RegistryPath
  38. )
  39. /*++
  40. DriverEntry:
  41. entry function of the driver. setup the callbacks for the OS and try to
  42. initialize a device object for every device in the system
  43. Arguments:
  44. DriverObject context of the driver
  45. RegistryPath path to the registry entry for the driver
  46. Return Value:
  47. STATUS_SUCCESS
  48. STATUS_UNSUCCESSFUL
  49. --*/
  50. {
  51. NTSTATUS NTStatus = STATUS_SUCCESS;
  52. ULONG Device;
  53. SmartcardDebug(
  54. DEBUG_TRACE,
  55. ( "PSCR!DriverEntry: Enter\n" )
  56. );
  57. // tell the system our entry points
  58. DriverObject->MajorFunction[IRP_MJ_CREATE] =
  59. DriverObject->MajorFunction[IRP_MJ_CLOSE] = PscrCreateClose;
  60. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PscrDeviceIoControl;
  61. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = PscrSystemControl;
  62. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = PscrCleanup;
  63. DriverObject->MajorFunction[IRP_MJ_PNP] = PscrPnP;
  64. DriverObject->MajorFunction[IRP_MJ_POWER] = PscrPower;
  65. DriverObject->DriverExtension->AddDevice = PscrAddDevice;
  66. DriverObject->DriverUnload = PscrUnloadDriver;
  67. SmartcardDebug(
  68. DEBUG_TRACE,
  69. ("PSCR!DriverEntry: Exit %x\n",
  70. NTStatus)
  71. );
  72. return NTStatus;
  73. }
  74. NTSTATUS
  75. PscrAddDevice(
  76. IN PDRIVER_OBJECT DriverObject,
  77. IN PDEVICE_OBJECT PhysicalDeviceObject
  78. )
  79. /*++
  80. Routine Description:
  81. This function is called by the pnp manager. This is used to create
  82. a new device instance.
  83. --*/
  84. {
  85. NTSTATUS status;
  86. UNICODE_STRING vendorNameU, ifdTypeU;
  87. ANSI_STRING vendorNameA, ifdTypeA;
  88. HANDLE regKey = NULL;
  89. PDEVICE_OBJECT DeviceObject = NULL;
  90. SmartcardDebug(
  91. DEBUG_TRACE,
  92. ( "PSCR!PscrAddDevice: Enter\n" )
  93. );
  94. try {
  95. ULONG DeviceInstance;
  96. UNICODE_STRING DriverID;
  97. PDEVICE_EXTENSION DeviceExtension;
  98. PREADER_EXTENSION ReaderExtension;
  99. PSMARTCARD_EXTENSION SmartcardExtension;
  100. RTL_QUERY_REGISTRY_TABLE parameters[3];
  101. RtlZeroMemory(parameters, sizeof(parameters));
  102. RtlZeroMemory(&vendorNameU, sizeof(vendorNameU));
  103. RtlZeroMemory(&ifdTypeU, sizeof(ifdTypeU));
  104. RtlZeroMemory(&vendorNameA, sizeof(vendorNameA));
  105. RtlZeroMemory(&ifdTypeA, sizeof(ifdTypeA));
  106. for ( DeviceInstance = 0; DeviceInstance < PSCR_MAX_DEVICE; DeviceInstance++ ) {
  107. if (DeviceSlot[DeviceInstance] == FALSE) {
  108. DeviceSlot[DeviceInstance] = TRUE;
  109. break;
  110. }
  111. }
  112. if (DeviceInstance == PSCR_MAX_DEVICE) {
  113. status = STATUS_INSUFFICIENT_RESOURCES;
  114. leave;
  115. }
  116. // Create the device object
  117. status = IoCreateDevice(
  118. DriverObject,
  119. sizeof(DEVICE_EXTENSION),
  120. NULL,
  121. FILE_DEVICE_SMARTCARD,
  122. 0,
  123. TRUE,
  124. &DeviceObject
  125. );
  126. if (status != STATUS_SUCCESS) {
  127. SmartcardLogError(
  128. DriverObject,
  129. PSCR_INSUFFICIENT_RESOURCES,
  130. NULL,
  131. 0
  132. );
  133. leave;
  134. }
  135. // set up the device extension.
  136. DeviceExtension = DeviceObject->DeviceExtension;
  137. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  138. // initialize the DPC routine
  139. KeInitializeDpc(
  140. &DeviceExtension->DpcObject,
  141. PscrDpcRoutine,
  142. DeviceObject
  143. );
  144. KeInitializeSpinLock(&DeviceExtension->SpinLock);
  145. // Used for device removal notification
  146. KeInitializeEvent(
  147. &DeviceExtension->ReaderRemoved,
  148. NotificationEvent,
  149. FALSE
  150. );
  151. // Used for stop / start notification
  152. KeInitializeEvent(
  153. &DeviceExtension->ReaderStarted,
  154. NotificationEvent,
  155. FALSE
  156. );
  157. // allocate the reader extension
  158. ReaderExtension = ExAllocatePool(
  159. NonPagedPool,
  160. sizeof( READER_EXTENSION )
  161. );
  162. if ( ReaderExtension == NULL ) {
  163. SmartcardLogError(
  164. DriverObject,
  165. PSCR_INSUFFICIENT_RESOURCES,
  166. NULL,
  167. 0
  168. );
  169. status = STATUS_INSUFFICIENT_RESOURCES;
  170. leave;
  171. }
  172. RtlZeroMemory( ReaderExtension, sizeof( READER_EXTENSION ));
  173. SmartcardExtension->ReaderExtension = ReaderExtension;
  174. // setup smartcard extension - callback's
  175. SmartcardExtension->ReaderFunction[RDF_CARD_POWER] = CBCardPower;
  176. SmartcardExtension->ReaderFunction[RDF_TRANSMIT] = CBTransmit;
  177. SmartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = CBCardTracking;
  178. SmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = CBSetProtocol;
  179. SmartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = PscrGenericIOCTL;
  180. // setup smartcard extension - vendor attribute
  181. RtlCopyMemory(
  182. SmartcardExtension->VendorAttr.VendorName.Buffer,
  183. PSCR_VENDOR_NAME,
  184. sizeof( PSCR_VENDOR_NAME )
  185. );
  186. SmartcardExtension->VendorAttr.VendorName.Length =
  187. sizeof( PSCR_VENDOR_NAME );
  188. RtlCopyMemory(
  189. SmartcardExtension->VendorAttr.IfdType.Buffer,
  190. PSCR_IFD_TYPE,
  191. sizeof( PSCR_IFD_TYPE )
  192. );
  193. SmartcardExtension->VendorAttr.IfdType.Length =
  194. sizeof( PSCR_IFD_TYPE );
  195. SmartcardExtension->VendorAttr.UnitNo =
  196. DeviceInstance;
  197. SmartcardExtension->VendorAttr.IfdVersion.BuildNumber = 0;
  198. // store firmware revision in ifd version
  199. SmartcardExtension->VendorAttr.IfdVersion.VersionMajor =
  200. ReaderExtension->FirmwareMajor;
  201. SmartcardExtension->VendorAttr.IfdVersion.VersionMinor =
  202. ReaderExtension->FirmwareMinor;
  203. SmartcardExtension->VendorAttr.IfdSerialNo.Length = 0;
  204. // setup smartcard extension - reader capabilities
  205. SmartcardExtension->ReaderCapabilities.SupportedProtocols =
  206. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  207. SmartcardExtension->ReaderCapabilities.ReaderType =
  208. SCARD_READER_TYPE_PCMCIA;
  209. SmartcardExtension->ReaderCapabilities.MechProperties = 0;
  210. SmartcardExtension->ReaderCapabilities.Channel = 0;
  211. SmartcardExtension->ReaderCapabilities.CLKFrequency.Default = 4000;
  212. SmartcardExtension->ReaderCapabilities.CLKFrequency.Max = 4000;
  213. SmartcardExtension->ReaderCapabilities.DataRate.Default = 10750;
  214. SmartcardExtension->ReaderCapabilities.DataRate.Max = 10750;
  215. // enter correct version of the lib
  216. SmartcardExtension->Version = SMCLIB_VERSION;
  217. SmartcardExtension->SmartcardRequest.BufferSize = MIN_BUFFER_SIZE;
  218. SmartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
  219. SmartcardExtension->ReaderExtension->ReaderPowerState =
  220. PowerReaderWorking;
  221. status = SmartcardInitialize(SmartcardExtension);
  222. if (status != STATUS_SUCCESS) {
  223. SmartcardLogError(
  224. DriverObject,
  225. PSCR_INSUFFICIENT_RESOURCES,
  226. NULL,
  227. 0
  228. );
  229. leave;
  230. }
  231. // tell the lib our device object
  232. SmartcardExtension->OsData->DeviceObject = DeviceObject;
  233. DeviceExtension->AttachedPDO = IoAttachDeviceToDeviceStack(
  234. DeviceObject,
  235. PhysicalDeviceObject
  236. );
  237. if (DeviceExtension->AttachedPDO == NULL) {
  238. status = STATUS_UNSUCCESSFUL;
  239. leave;
  240. }
  241. // register our new device
  242. status = IoRegisterDeviceInterface(
  243. PhysicalDeviceObject,
  244. &SmartCardReaderGuid,
  245. NULL,
  246. &DeviceExtension->DeviceName
  247. );
  248. ASSERT(status == STATUS_SUCCESS);
  249. DeviceObject->Flags |= DO_BUFFERED_IO;
  250. DeviceObject->Flags |= DO_POWER_PAGABLE;
  251. DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  252. //
  253. // try to read the reader name from the registry
  254. // if that does not work, we will use the default
  255. // (hardcoded) name
  256. //
  257. if (IoOpenDeviceRegistryKey(
  258. PhysicalDeviceObject,
  259. PLUGPLAY_REGKEY_DEVICE,
  260. KEY_READ,
  261. &regKey
  262. ) != STATUS_SUCCESS) {
  263. leave;
  264. }
  265. parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  266. parameters[0].Name = L"VendorName";
  267. parameters[0].EntryContext = &vendorNameU;
  268. parameters[0].DefaultType = REG_SZ;
  269. parameters[0].DefaultData = &vendorNameU;
  270. parameters[0].DefaultLength = 0;
  271. parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  272. parameters[1].Name = L"IfdType";
  273. parameters[1].EntryContext = &ifdTypeU;
  274. parameters[1].DefaultType = REG_SZ;
  275. parameters[1].DefaultData = &ifdTypeU;
  276. parameters[1].DefaultLength = 0;
  277. if (RtlQueryRegistryValues(
  278. RTL_REGISTRY_HANDLE,
  279. (PWSTR) regKey,
  280. parameters,
  281. NULL,
  282. NULL
  283. ) != STATUS_SUCCESS) {
  284. leave;
  285. }
  286. if (RtlUnicodeStringToAnsiString(
  287. &vendorNameA,
  288. &vendorNameU,
  289. TRUE
  290. ) != STATUS_SUCCESS) {
  291. leave;
  292. }
  293. if (RtlUnicodeStringToAnsiString(
  294. &ifdTypeA,
  295. &ifdTypeU,
  296. TRUE
  297. ) != STATUS_SUCCESS) {
  298. leave;
  299. }
  300. if (vendorNameA.Length == 0 ||
  301. vendorNameA.Length > MAXIMUM_ATTR_STRING_LENGTH ||
  302. ifdTypeA.Length == 0 ||
  303. ifdTypeA.Length > MAXIMUM_ATTR_STRING_LENGTH) {
  304. leave;
  305. }
  306. RtlCopyMemory(
  307. SmartcardExtension->VendorAttr.VendorName.Buffer,
  308. vendorNameA.Buffer,
  309. vendorNameA.Length
  310. );
  311. SmartcardExtension->VendorAttr.VendorName.Length =
  312. vendorNameA.Length;
  313. RtlCopyMemory(
  314. SmartcardExtension->VendorAttr.IfdType.Buffer,
  315. ifdTypeA.Buffer,
  316. ifdTypeA.Length
  317. );
  318. SmartcardExtension->VendorAttr.IfdType.Length =
  319. ifdTypeA.Length;
  320. } finally {
  321. if (vendorNameU.Buffer) {
  322. RtlFreeUnicodeString(&vendorNameU);
  323. }
  324. if (ifdTypeU.Buffer) {
  325. RtlFreeUnicodeString(&ifdTypeU);
  326. }
  327. if (vendorNameA.Buffer) {
  328. RtlFreeAnsiString(&vendorNameA);
  329. }
  330. if (ifdTypeA.Buffer) {
  331. RtlFreeAnsiString(&ifdTypeA);
  332. }
  333. if (regKey != NULL) {
  334. ZwClose(regKey);
  335. }
  336. if (status != STATUS_SUCCESS) {
  337. PscrUnloadDevice(DeviceObject);
  338. }
  339. SmartcardDebug(
  340. DEBUG_TRACE,
  341. ( "PSCR!PscrAddDevice: Exit %x\n",
  342. status)
  343. );
  344. }
  345. return status;
  346. }
  347. NTSTATUS
  348. PscrCallPcmciaDriver(
  349. IN PDEVICE_OBJECT AttachedPDO,
  350. IN PIRP Irp
  351. )
  352. /*++
  353. Routine Description:
  354. Send an Irp to the pcmcia driver and wait until the pcmcia driver has
  355. finished the request.
  356. To make sure that the pcmcia driver will not complete the Irp we first
  357. initialize an event and set our own completion routine for the Irp.
  358. When the pcmcia driver has processed the Irp the completion routine will
  359. set the event and tell the IO manager that more processing is required.
  360. By waiting for the event we make sure that we continue only if the pcmcia
  361. driver has processed the Irp completely.
  362. Return Value:
  363. status returned by the pcmcia driver
  364. --*/
  365. {
  366. NTSTATUS status = STATUS_SUCCESS;
  367. KEVENT Event;
  368. // Copy our stack location to the next.
  369. IoCopyCurrentIrpStackLocationToNext(Irp);
  370. //
  371. // initialize an event for process synchronization. the event is passed
  372. // to our completion routine and will be set if the pcmcia driver is done
  373. //
  374. KeInitializeEvent(
  375. &Event,
  376. NotificationEvent,
  377. FALSE
  378. );
  379. // Our IoCompletionRoutine sets only our event
  380. IoSetCompletionRoutine (
  381. Irp,
  382. PscrPcmciaCallComplete,
  383. &Event,
  384. TRUE,
  385. TRUE,
  386. TRUE
  387. );
  388. if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_POWER) {
  389. status = PoCallDriver(AttachedPDO, Irp);
  390. } else {
  391. // Call the serial driver
  392. status = IoCallDriver(AttachedPDO, Irp);
  393. }
  394. // Wait until the pcmcia driver has processed the Irp
  395. if (status == STATUS_PENDING) {
  396. status = KeWaitForSingleObject(
  397. &Event,
  398. Executive,
  399. KernelMode,
  400. FALSE,
  401. NULL
  402. );
  403. if (status == STATUS_SUCCESS) {
  404. status = Irp->IoStatus.Status;
  405. }
  406. }
  407. return status;
  408. }
  409. NTSTATUS
  410. PscrPcmciaCallComplete (
  411. IN PDEVICE_OBJECT DeviceObject,
  412. IN PIRP Irp,
  413. IN PKEVENT Event
  414. )
  415. /*++
  416. Routine Description:
  417. Completion routine for an Irp sent to the pcmcia driver. The event will
  418. be set to notify that the pcmcia driver is done. The routine will not
  419. 'complete' the Irp, so the caller of PscrCallPcmciaDriver can continue.
  420. --*/
  421. {
  422. UNREFERENCED_PARAMETER (DeviceObject);
  423. if (Irp->Cancel) {
  424. Irp->IoStatus.Status = STATUS_CANCELLED;
  425. }
  426. KeSetEvent (Event, 0, FALSE);
  427. return STATUS_MORE_PROCESSING_REQUIRED;
  428. }
  429. NTSTATUS
  430. PscrPnP(
  431. IN PDEVICE_OBJECT DeviceObject,
  432. IN PIRP Irp
  433. )
  434. /*++
  435. Routine Description:
  436. driver callback for pnp manager
  437. All other requests will be passed to the pcmcia driver to ensure correct processing.
  438. --*/
  439. {
  440. NTSTATUS status = STATUS_SUCCESS;
  441. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  442. PIO_STACK_LOCATION IrpStack;
  443. PDEVICE_OBJECT AttachedPDO;
  444. BOOLEAN deviceRemoved = FALSE, irpSkipped = FALSE;
  445. KIRQL irql;
  446. LARGE_INTEGER timeout;
  447. SmartcardDebug(
  448. DEBUG_TRACE,
  449. ( "PSCR!PscrPnPDeviceControl: Enter\n" )
  450. );
  451. status = SmartcardAcquireRemoveLock(&DeviceExtension->SmartcardExtension);
  452. ASSERT(status == STATUS_SUCCESS);
  453. if (status != STATUS_SUCCESS) {
  454. Irp->IoStatus.Information = 0;
  455. Irp->IoStatus.Status = status;
  456. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  457. return status;
  458. }
  459. AttachedPDO = DeviceExtension->AttachedPDO;
  460. IrpStack = IoGetCurrentIrpStackLocation(Irp);
  461. // Now look what the PnP manager wants...
  462. switch (IrpStack->MinorFunction) {
  463. case IRP_MN_START_DEVICE:
  464. // Now we should connect to our resources (Irql, Io etc.)
  465. SmartcardDebug(
  466. DEBUG_DRIVER,
  467. ("PSCR!PscrPnPDeviceControl: IRP_MN_START_DEVICE\n")
  468. );
  469. // We have to call the underlying driver first
  470. status = PscrCallPcmciaDriver(AttachedPDO, Irp);
  471. if (NT_SUCCESS(status)) {
  472. status = PscrStartDevice(
  473. DeviceObject,
  474. &IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0]
  475. );
  476. ASSERT(NT_SUCCESS(status));
  477. }
  478. break;
  479. case IRP_MN_QUERY_STOP_DEVICE:
  480. SmartcardDebug(
  481. DEBUG_DRIVER,
  482. ("PSCR!PscrPnPDeviceControl: IRP_MN_QUERY_STOP_DEVICE\n")
  483. );
  484. KeAcquireSpinLock(&DeviceExtension->SpinLock, &irql);
  485. if (DeviceExtension->IoCount > 0) {
  486. // we refuse to stop if we have pending io
  487. KeReleaseSpinLock(&DeviceExtension->SpinLock, irql);
  488. status = STATUS_DEVICE_BUSY;
  489. } else {
  490. // stop processing requests
  491. KeClearEvent(&DeviceExtension->ReaderStarted);
  492. KeReleaseSpinLock(&DeviceExtension->SpinLock, irql);
  493. status = PscrCallPcmciaDriver(AttachedPDO, Irp);
  494. }
  495. break;
  496. case IRP_MN_CANCEL_STOP_DEVICE:
  497. SmartcardDebug(
  498. DEBUG_DRIVER,
  499. ("PSCR!PscrPnPDeviceControl: IRP_MN_CANCEL_STOP_DEVICE\n")
  500. );
  501. status = PscrCallPcmciaDriver(AttachedPDO, Irp);
  502. ASSERT(status == STATUS_SUCCESS);
  503. // we can continue to process requests
  504. DeviceExtension->IoCount = 0;
  505. KeSetEvent(&DeviceExtension->ReaderStarted, 0, FALSE);
  506. break;
  507. case IRP_MN_STOP_DEVICE:
  508. // Stop the device. Aka disconnect from our resources
  509. SmartcardDebug(
  510. DEBUG_DRIVER,
  511. ("PSCR!PscrPnPDeviceControl: IRP_MN_STOP_DEVICE\n")
  512. );
  513. PscrStopDevice(DeviceObject);
  514. status = PscrCallPcmciaDriver(AttachedPDO, Irp);
  515. break;
  516. case IRP_MN_QUERY_REMOVE_DEVICE:
  517. // Remove our device
  518. SmartcardDebug(
  519. DEBUG_DRIVER,
  520. ("PSCR!PscrPnPDeviceControl: IRP_MN_QUERY_REMOVE_DEVICE\n")
  521. );
  522. // disable the reader
  523. status = IoSetDeviceInterfaceState(
  524. &DeviceExtension->DeviceName,
  525. FALSE
  526. );
  527. ASSERT(status == STATUS_SUCCESS);
  528. if (status != STATUS_SUCCESS) {
  529. break;
  530. }
  531. //
  532. // check if the reader has been opened
  533. //
  534. if (DeviceExtension->ReaderOpen) {
  535. // someone is connected, enable the reader and fail the call
  536. IoSetDeviceInterfaceState(
  537. &DeviceExtension->DeviceName,
  538. TRUE
  539. );
  540. status = STATUS_UNSUCCESSFUL;
  541. break;
  542. }
  543. // pass the call to the next driver in the stack
  544. status = PscrCallPcmciaDriver(AttachedPDO, Irp);
  545. break;
  546. case IRP_MN_CANCEL_REMOVE_DEVICE:
  547. // Removal of device has been cancelled
  548. SmartcardDebug(
  549. DEBUG_DRIVER,
  550. ("PSCR!PscrPnPDeviceControl: IRP_MN_CANCEL_REMOVE_DEVICE\n")
  551. );
  552. status = PscrCallPcmciaDriver(AttachedPDO, Irp);
  553. if (status == STATUS_SUCCESS) {
  554. status = IoSetDeviceInterfaceState(
  555. &DeviceExtension->DeviceName,
  556. TRUE
  557. );
  558. }
  559. break;
  560. case IRP_MN_SURPRISE_REMOVAL:
  561. SmartcardDebug(
  562. DEBUG_DRIVER,
  563. ("PSCR!PscrPnPDeviceControl: IRP_MN_SURPRISE_REMOVAL\n")
  564. );
  565. if ( DeviceExtension->InterruptObject != NULL ) {
  566. IoDisconnectInterrupt(DeviceExtension->InterruptObject);
  567. DeviceExtension->InterruptObject = NULL;
  568. }
  569. status = PscrCallPcmciaDriver(AttachedPDO, Irp);
  570. break;
  571. case IRP_MN_REMOVE_DEVICE:
  572. // Remove our device
  573. SmartcardDebug(
  574. DEBUG_DRIVER,
  575. ("PSCR!PscrPnPDeviceControl: IRP_MN_REMOVE_DEVICE\n")
  576. );
  577. KeSetEvent(&DeviceExtension->ReaderRemoved, 0, FALSE);
  578. PscrStopDevice(DeviceObject);
  579. PscrUnloadDevice(DeviceObject);
  580. status = PscrCallPcmciaDriver(AttachedPDO, Irp);
  581. deviceRemoved = TRUE;
  582. break;
  583. default:
  584. // This is an Irp that is only useful for underlying drivers
  585. status = PscrCallPcmciaDriver(AttachedPDO, Irp);
  586. irpSkipped = TRUE;
  587. break;
  588. }
  589. if (irpSkipped == FALSE) {
  590. // Don't touch the status field of irps we don't process
  591. Irp->IoStatus.Status = status;
  592. }
  593. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  594. if (deviceRemoved == FALSE) {
  595. SmartcardReleaseRemoveLock(&DeviceExtension->SmartcardExtension);
  596. }
  597. SmartcardDebug(
  598. DEBUG_TRACE,
  599. ( "PSCR!PscrPnPDeviceControl: Exit %x\n",
  600. status)
  601. );
  602. return status;
  603. }
  604. VOID
  605. PscrSystemPowerCompletion(
  606. IN PDEVICE_OBJECT DeviceObject,
  607. IN UCHAR MinorFunction,
  608. IN POWER_STATE PowerState,
  609. IN PKEVENT Event,
  610. IN PIO_STATUS_BLOCK IoStatus
  611. )
  612. /*++
  613. Routine Description:
  614. This function is called when the underlying stacks
  615. completed the power transition.
  616. --*/
  617. {
  618. UNREFERENCED_PARAMETER (DeviceObject);
  619. UNREFERENCED_PARAMETER (MinorFunction);
  620. UNREFERENCED_PARAMETER (PowerState);
  621. UNREFERENCED_PARAMETER (IoStatus);
  622. KeSetEvent(Event, 0, FALSE);
  623. }
  624. NTSTATUS
  625. PscrDevicePowerCompletion (
  626. IN PDEVICE_OBJECT DeviceObject,
  627. IN PIRP Irp,
  628. IN PSMARTCARD_EXTENSION SmartcardExtension
  629. )
  630. /*++
  631. Routine Description:
  632. This routine is called after the underlying stack powered
  633. UP the serial port, so it can be used again.
  634. --*/
  635. {
  636. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  637. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  638. NTSTATUS status;
  639. UCHAR state;
  640. if (Irp->PendingReturned) {
  641. IoMarkIrpPending(Irp);
  642. }
  643. status = CmdResetInterface(SmartcardExtension->ReaderExtension);
  644. ASSERT(status == STATUS_SUCCESS);
  645. SmartcardExtension->ReaderExtension->StatusFileSelected = FALSE;
  646. state = CBGetCardState(SmartcardExtension);
  647. CBUpdateCardState(SmartcardExtension, state, TRUE);
  648. // save the current power state of the reader
  649. SmartcardExtension->ReaderExtension->ReaderPowerState =
  650. PowerReaderWorking;
  651. SmartcardReleaseRemoveLock(SmartcardExtension);
  652. // inform the power manager of our state.
  653. PoSetPowerState (
  654. DeviceObject,
  655. DevicePowerState,
  656. irpStack->Parameters.Power.State
  657. );
  658. PoStartNextPowerIrp(Irp);
  659. // signal that we can process ioctls again
  660. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  661. return STATUS_SUCCESS;
  662. }
  663. typedef enum _ACTION {
  664. Undefined = 0,
  665. SkipRequest,
  666. WaitForCompletion,
  667. CompleteRequest,
  668. MarkPending
  669. } ACTION;
  670. NTSTATUS
  671. PscrPower (
  672. IN PDEVICE_OBJECT DeviceObject,
  673. IN PIRP Irp
  674. )
  675. /*++
  676. Routine Description:
  677. The power dispatch routine.
  678. This driver is the power policy owner of the device stack,
  679. because this driver knows about the connected reader.
  680. Therefor this driver will translate system power states
  681. to device power states.
  682. Arguments:
  683. DeviceObject - pointer to a device object.
  684. Irp - pointer to an I/O Request Packet.
  685. Return Value:
  686. NT status code
  687. --*/
  688. {
  689. NTSTATUS status = STATUS_SUCCESS;
  690. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  691. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  692. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  693. POWER_STATE powerState;
  694. ACTION action = SkipRequest;
  695. KEVENT event;
  696. KIRQL irql;
  697. SmartcardDebug(
  698. DEBUG_DRIVER,
  699. ("PSCR!PscrPower: Enter\n")
  700. );
  701. ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
  702. //
  703. // Prefix initialization
  704. //
  705. powerState.DeviceState = PowerDeviceUnspecified;
  706. status = SmartcardAcquireRemoveLock(smartcardExtension);
  707. ASSERT(NT_SUCCESS(status));
  708. if (!NT_SUCCESS(status)) {
  709. PoStartNextPowerIrp(Irp);
  710. Irp->IoStatus.Status = status;
  711. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  712. return status;
  713. }
  714. if (irpStack->Parameters.Power.Type == DevicePowerState &&
  715. irpStack->MinorFunction == IRP_MN_SET_POWER) {
  716. switch (irpStack->Parameters.Power.State.DeviceState) {
  717. case PowerDeviceD0:
  718. // Turn on the reader
  719. SmartcardDebug(
  720. DEBUG_DRIVER,
  721. ("PSCR!PscrPower: PowerDevice D0\n")
  722. );
  723. //
  724. // First, we send down the request to the bus, in order
  725. // to power on the port. When the request completes,
  726. // we turn on the reader
  727. //
  728. IoCopyCurrentIrpStackLocationToNext(Irp);
  729. IoSetCompletionRoutine (
  730. Irp,
  731. PscrDevicePowerCompletion,
  732. smartcardExtension,
  733. TRUE,
  734. TRUE,
  735. TRUE
  736. );
  737. action = WaitForCompletion;
  738. break;
  739. case PowerDeviceD3:
  740. // Turn off the reader
  741. SmartcardDebug(
  742. DEBUG_DRIVER,
  743. ("PSCR!PscrPower: PowerDevice D3\n")
  744. );
  745. PoSetPowerState (
  746. DeviceObject,
  747. DevicePowerState,
  748. irpStack->Parameters.Power.State
  749. );
  750. // save the current card state
  751. KeAcquireSpinLock(&smartcardExtension->OsData->SpinLock,
  752. &irql);
  753. smartcardExtension->ReaderExtension->CardPresent =
  754. smartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT;
  755. if (smartcardExtension->ReaderExtension->CardPresent) {
  756. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  757. irql);
  758. smartcardExtension->MinorIoControlCode = SCARD_POWER_DOWN;
  759. status = CBCardPower(smartcardExtension);
  760. ASSERT(NT_SUCCESS(status));
  761. } else {
  762. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  763. irql);
  764. }
  765. // save the current power state of the reader
  766. smartcardExtension->ReaderExtension->ReaderPowerState =
  767. PowerReaderOff;
  768. action = SkipRequest;
  769. break;
  770. default:
  771. action = SkipRequest;
  772. break;
  773. }
  774. }
  775. if (irpStack->Parameters.Power.Type == SystemPowerState) {
  776. //
  777. // The system wants to change the power state.
  778. // We need to translate the system power state to
  779. // a corresponding device power state.
  780. //
  781. POWER_STATE_TYPE powerType = DevicePowerState;
  782. ASSERT(smartcardExtension->ReaderExtension->ReaderPowerState !=
  783. PowerReaderUnspecified);
  784. switch (irpStack->MinorFunction) {
  785. case IRP_MN_QUERY_POWER:
  786. SmartcardDebug(
  787. DEBUG_DRIVER,
  788. ("PSCR!PscrPower: Query Power\n")
  789. );
  790. //
  791. // By default we succeed and pass down
  792. //
  793. action = SkipRequest;
  794. Irp->IoStatus.Status = STATUS_SUCCESS;
  795. switch (irpStack->Parameters.Power.State.SystemState) {
  796. case PowerSystemMaximum:
  797. case PowerSystemWorking:
  798. case PowerSystemSleeping1:
  799. case PowerSystemSleeping2:
  800. break;
  801. case PowerSystemSleeping3:
  802. case PowerSystemHibernate:
  803. case PowerSystemShutdown:
  804. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  805. if (deviceExtension->IoCount == 0) {
  806. // Block any further ioctls
  807. KeClearEvent(&deviceExtension->ReaderStarted);
  808. } else {
  809. // can't go to sleep mode since the reader is busy.
  810. status = STATUS_DEVICE_BUSY;
  811. action = CompleteRequest;
  812. }
  813. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  814. break;
  815. }
  816. break;
  817. case IRP_MN_SET_POWER:
  818. SmartcardDebug(
  819. DEBUG_DRIVER,
  820. ("PSCR!PscrPower: PowerSystem S%d\n",
  821. irpStack->Parameters.Power.State.SystemState - 1)
  822. );
  823. switch (irpStack->Parameters.Power.State.SystemState) {
  824. case PowerSystemMaximum:
  825. case PowerSystemWorking:
  826. case PowerSystemSleeping1:
  827. case PowerSystemSleeping2:
  828. if (smartcardExtension->ReaderExtension->ReaderPowerState ==
  829. PowerReaderWorking) {
  830. // We're already in the right state
  831. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  832. action = SkipRequest;
  833. break;
  834. }
  835. powerState.DeviceState = PowerDeviceD0;
  836. // wake up the underlying stack...
  837. action = MarkPending;
  838. break;
  839. case PowerSystemSleeping3:
  840. case PowerSystemHibernate:
  841. case PowerSystemShutdown:
  842. if (smartcardExtension->ReaderExtension->ReaderPowerState ==
  843. PowerReaderOff) {
  844. // We're already in the right state
  845. action = SkipRequest;
  846. break;
  847. }
  848. powerState.DeviceState = PowerDeviceD3;
  849. // first, inform the power manager of our new state.
  850. PoSetPowerState (
  851. DeviceObject,
  852. SystemPowerState,
  853. powerState
  854. );
  855. action = MarkPending;
  856. break;
  857. default:
  858. action = SkipRequest;
  859. break;
  860. }
  861. }
  862. }
  863. switch (action) {
  864. case CompleteRequest:
  865. Irp->IoStatus.Status = status;
  866. Irp->IoStatus.Information = 0;
  867. SmartcardReleaseRemoveLock(smartcardExtension);
  868. PoStartNextPowerIrp(Irp);
  869. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  870. break;
  871. case MarkPending:
  872. // initialize the event we need in the completion function
  873. KeInitializeEvent(
  874. &event,
  875. NotificationEvent,
  876. FALSE
  877. );
  878. // request the device power irp
  879. status = PoRequestPowerIrp (
  880. DeviceObject,
  881. IRP_MN_SET_POWER,
  882. powerState,
  883. PscrSystemPowerCompletion,
  884. &event,
  885. NULL
  886. );
  887. ASSERT(status == STATUS_PENDING);
  888. if (status == STATUS_PENDING) {
  889. // wait until the device power irp completed
  890. status = KeWaitForSingleObject(
  891. &event,
  892. Executive,
  893. KernelMode,
  894. FALSE,
  895. NULL
  896. );
  897. SmartcardReleaseRemoveLock(smartcardExtension);
  898. if (powerState.SystemState == PowerSystemWorking) {
  899. PoSetPowerState (
  900. DeviceObject,
  901. SystemPowerState,
  902. powerState
  903. );
  904. }
  905. PoStartNextPowerIrp(Irp);
  906. IoSkipCurrentIrpStackLocation(Irp);
  907. status = PoCallDriver(deviceExtension->AttachedPDO, Irp);
  908. } else {
  909. SmartcardReleaseRemoveLock(smartcardExtension);
  910. Irp->IoStatus.Status = status;
  911. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  912. }
  913. break;
  914. case SkipRequest:
  915. SmartcardReleaseRemoveLock(smartcardExtension);
  916. PoStartNextPowerIrp(Irp);
  917. IoSkipCurrentIrpStackLocation(Irp);
  918. status = PoCallDriver(deviceExtension->AttachedPDO, Irp);
  919. break;
  920. case WaitForCompletion:
  921. status = PoCallDriver(deviceExtension->AttachedPDO, Irp);
  922. break;
  923. default:
  924. ASSERT(FALSE);
  925. break;
  926. }
  927. SmartcardDebug(
  928. DEBUG_DRIVER,
  929. ("PSCR!PscrPower: Exit %lx\n",
  930. status)
  931. );
  932. return status;
  933. }
  934. NTSTATUS
  935. PscrStartDevice(
  936. PDEVICE_OBJECT DeviceObject,
  937. PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
  938. )
  939. /*++
  940. Routine Description:
  941. get the actual configuration from the passed FullResourceDescriptor
  942. and initializes the reader hardware
  943. Note:
  944. for an NT 4.00 build the resources must be translated by the HAL
  945. Arguments:
  946. DeviceObject context of call
  947. FullResourceDescriptor actual configuration of the reader
  948. Return Value:
  949. STATUS_SUCCESS
  950. status returned from the HAL (NT 4.00 only )
  951. status returned by LowLevel routines
  952. --*/
  953. {
  954. PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
  955. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  956. PSMARTCARD_EXTENSION SmartcardExtension = &DeviceExtension->SmartcardExtension;
  957. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  958. NTSTATUS status;
  959. ULONG Count;
  960. SmartcardDebug(
  961. DEBUG_TRACE,
  962. ("PSCR!PscrStartDevice: Enter\n")
  963. );
  964. // Get the number of resources we need
  965. Count = FullResourceDescriptor->PartialResourceList.Count;
  966. PartialDescriptor = FullResourceDescriptor->PartialResourceList.PartialDescriptors;
  967. // parse all partial descriptors
  968. while (Count--) {
  969. switch (PartialDescriptor->Type) {
  970. case CmResourceTypePort: {
  971. // 0 - memory, 1 - IO
  972. ULONG AddressSpace = 1;
  973. BOOLEAN Translated;
  974. PHYSICAL_ADDRESS PhysicalAddress;
  975. ReaderExtension->IOBase =
  976. (PPSCR_REGISTERS) UlongToPtr(PartialDescriptor->u.Port.Start.LowPart);
  977. ASSERT(PartialDescriptor->u.Port.Length >= 4);
  978. SmartcardDebug(
  979. DEBUG_TRACE,
  980. ("PSCR!PscrStartDevice: IoBase = %lxh\n",
  981. ReaderExtension->IOBase)
  982. );
  983. break;
  984. }
  985. case CmResourceTypeInterrupt: {
  986. KINTERRUPT_MODE Mode;
  987. BOOLEAN Shared;
  988. KIRQL Irql;
  989. KAFFINITY Affinity;
  990. ULONG Vector;
  991. Mode = (
  992. PartialDescriptor->Flags &
  993. CM_RESOURCE_INTERRUPT_LATCHED ?
  994. Latched : LevelSensitive
  995. );
  996. Shared = (
  997. PartialDescriptor->ShareDisposition ==
  998. CmResourceShareShared
  999. );
  1000. Vector = PartialDescriptor->u.Interrupt.Vector;
  1001. Affinity = PartialDescriptor->u.Interrupt.Affinity;
  1002. Irql = (KIRQL) PartialDescriptor->u.Interrupt.Level;
  1003. // store IRQ to allow query configuration
  1004. ReaderExtension->CurrentIRQ =
  1005. PartialDescriptor->u.Interrupt.Vector;
  1006. SmartcardDebug(
  1007. DEBUG_TRACE,
  1008. ("PSCR!PscrStartDevice: Irql: %d\n",
  1009. PartialDescriptor->u.Interrupt.Level)
  1010. );
  1011. // connect the driver's isr
  1012. status = IoConnectInterrupt(
  1013. &DeviceExtension->InterruptObject,
  1014. PscrIrqServiceRoutine,
  1015. (PVOID) DeviceExtension,
  1016. NULL,
  1017. Vector,
  1018. Irql,
  1019. Irql,
  1020. Mode,
  1021. Shared,
  1022. Affinity,
  1023. FALSE
  1024. );
  1025. break;
  1026. }
  1027. case CmResourceTypeDevicePrivate:
  1028. break;
  1029. default:
  1030. ASSERT(FALSE);
  1031. status = STATUS_UNSUCCESSFUL;
  1032. break;
  1033. }
  1034. PartialDescriptor++;
  1035. }
  1036. try {
  1037. HANDLE handle;
  1038. UCHAR CardState;
  1039. // IOBase initialized ?
  1040. if ( ReaderExtension->IOBase == NULL ) {
  1041. //
  1042. // under NT 4.0 the failure of this fct for the second reader
  1043. // means there is only one device
  1044. //
  1045. SmartcardLogError(
  1046. DeviceObject,
  1047. PSCR_ERROR_IO_PORT,
  1048. NULL,
  1049. 0
  1050. );
  1051. status = STATUS_INSUFFICIENT_RESOURCES;
  1052. leave;
  1053. }
  1054. // irq connected ?
  1055. if ( DeviceExtension->InterruptObject == NULL ) {
  1056. SmartcardLogError(
  1057. DeviceObject,
  1058. PSCR_ERROR_INTERRUPT,
  1059. NULL,
  1060. 0
  1061. );
  1062. status = STATUS_INSUFFICIENT_RESOURCES;
  1063. leave;
  1064. }
  1065. ReaderExtension->Device = DEVICE_ICC1;
  1066. ReaderExtension->MaxRetries = PSCR_MAX_RETRIES;
  1067. status = CmdResetInterface( ReaderExtension );
  1068. SmartcardExtension->ReaderCapabilities.MaxIFSD =
  1069. ReaderExtension->MaxIFSD;
  1070. if (status != STATUS_SUCCESS) {
  1071. SmartcardLogError(
  1072. DeviceObject,
  1073. PSCR_CANT_INITIALIZE_READER,
  1074. NULL,
  1075. 0
  1076. );
  1077. leave;
  1078. }
  1079. status = CmdReset(
  1080. ReaderExtension,
  1081. 0x00, // reader
  1082. FALSE, // cold reset
  1083. NULL, // no atr
  1084. NULL
  1085. );
  1086. if (status != STATUS_SUCCESS) {
  1087. SmartcardLogError(
  1088. DeviceObject,
  1089. PSCR_CANT_INITIALIZE_READER,
  1090. NULL,
  1091. 0
  1092. );
  1093. leave;
  1094. }
  1095. PscrFlushInterface(DeviceExtension->SmartcardExtension.ReaderExtension);
  1096. CmdGetFirmwareRevision(
  1097. DeviceExtension->SmartcardExtension.ReaderExtension
  1098. );
  1099. // If you change the min. firmware version here, please update
  1100. // the .mc file for the correct error message, too
  1101. if (SmartcardExtension->ReaderExtension->FirmwareMajor < 2 ||
  1102. SmartcardExtension->ReaderExtension->FirmwareMajor == 2 &&
  1103. SmartcardExtension->ReaderExtension->FirmwareMinor < 0x30) {
  1104. SmartcardLogError(
  1105. DeviceObject,
  1106. PSCR_WRONG_FIRMWARE,
  1107. NULL,
  1108. 0
  1109. );
  1110. }
  1111. //
  1112. // make sure the ICC1 status file in the reader file system will
  1113. // be selected
  1114. //
  1115. ReaderExtension->StatusFileSelected = FALSE;
  1116. CardState = CBGetCardState(&DeviceExtension->SmartcardExtension);
  1117. CBUpdateCardState(&DeviceExtension->SmartcardExtension, CardState, FALSE);
  1118. // signal that the reader has been started (again)
  1119. KeSetEvent(&DeviceExtension->ReaderStarted, 0, FALSE);
  1120. status = IoSetDeviceInterfaceState(
  1121. &DeviceExtension->DeviceName,
  1122. TRUE
  1123. );
  1124. if (status == STATUS_OBJECT_NAME_EXISTS) {
  1125. // We tried to re-enable the device which is ok
  1126. // This can happen after a stop - start sequence
  1127. status = STATUS_SUCCESS;
  1128. }
  1129. ASSERT(status == STATUS_SUCCESS);
  1130. } finally {
  1131. if (status != STATUS_SUCCESS) {
  1132. PscrStopDevice(DeviceObject);
  1133. }
  1134. SmartcardDebug(
  1135. DEBUG_TRACE,
  1136. ( "PSCR!PscrStartDevice: Exit %x\n",
  1137. status )
  1138. );
  1139. }
  1140. return status;
  1141. }
  1142. VOID
  1143. PscrStopDevice(
  1144. PDEVICE_OBJECT DeviceObject
  1145. )
  1146. /*++
  1147. Routine Description:
  1148. Diconnect the interrupt used by the device & unmap the IO port
  1149. --*/
  1150. {
  1151. PDEVICE_EXTENSION DeviceExtension;
  1152. NTSTATUS status;
  1153. LARGE_INTEGER delayPeriod;
  1154. if (DeviceObject == NULL) {
  1155. return;
  1156. }
  1157. SmartcardDebug(
  1158. DEBUG_TRACE,
  1159. ( "PSCR!PscrStopDevice: Enter\n" )
  1160. );
  1161. DeviceExtension = DeviceObject->DeviceExtension;
  1162. KeClearEvent(&DeviceExtension->ReaderStarted);
  1163. // disconnect the interrupt
  1164. if ( DeviceExtension->InterruptObject != NULL ) {
  1165. IoDisconnectInterrupt(DeviceExtension->InterruptObject);
  1166. DeviceExtension->InterruptObject = NULL;
  1167. }
  1168. // unmap ports
  1169. if (DeviceExtension->UnMapPort) {
  1170. MmUnmapIoSpace(
  1171. DeviceExtension->SmartcardExtension.ReaderExtension->IOBase,
  1172. DeviceExtension->SmartcardExtension.ReaderExtension->IOWindow
  1173. );
  1174. DeviceExtension->UnMapPort = FALSE;
  1175. }
  1176. SmartcardDebug(
  1177. DEBUG_TRACE,
  1178. ( "PSCR!PscrStopDevice: Exit\n" )
  1179. );
  1180. }
  1181. VOID
  1182. PscrUnloadDevice(
  1183. PDEVICE_OBJECT DeviceObject
  1184. )
  1185. /*++
  1186. Routine Description:
  1187. close connections to smclib.sys and the pcmcia driver, delete symbolic
  1188. link and mark the slot as unused.
  1189. Arguments:
  1190. DeviceObject device to unload
  1191. Return Value:
  1192. void
  1193. --*/
  1194. {
  1195. PDEVICE_EXTENSION DeviceExtension;
  1196. NTSTATUS status;
  1197. if (DeviceObject == NULL) {
  1198. return;
  1199. }
  1200. SmartcardDebug(
  1201. DEBUG_TRACE,
  1202. ( "PSCR!PscrUnloadDevice: Enter\n" )
  1203. );
  1204. DeviceExtension = DeviceObject->DeviceExtension;
  1205. ASSERT(
  1206. DeviceExtension->SmartcardExtension.VendorAttr.UnitNo <
  1207. PSCR_MAX_DEVICE
  1208. );
  1209. if (DeviceExtension->DeviceName.Buffer != NULL) {
  1210. // disble our device so no one can open it
  1211. IoSetDeviceInterfaceState(
  1212. &DeviceExtension->DeviceName,
  1213. FALSE
  1214. );
  1215. }
  1216. // Mark this slot as available
  1217. DeviceSlot[DeviceExtension->SmartcardExtension.VendorAttr.UnitNo] = FALSE;
  1218. // report to the lib that the device will be unloaded
  1219. if (DeviceExtension->SmartcardExtension.OsData != NULL) {
  1220. KIRQL CancelIrql;
  1221. PSMARTCARD_EXTENSION SmartcardExtension =
  1222. &DeviceExtension->SmartcardExtension;
  1223. ASSERT(SmartcardExtension->OsData->NotificationIrp == NULL);
  1224. IoAcquireCancelSpinLock( &CancelIrql );
  1225. if ( SmartcardExtension->OsData->NotificationIrp != NULL ) {
  1226. PIRP notificationIrp;
  1227. notificationIrp = InterlockedExchangePointer(
  1228. &(SmartcardExtension->OsData->NotificationIrp),
  1229. NULL
  1230. );
  1231. IoSetCancelRoutine(
  1232. notificationIrp,
  1233. NULL
  1234. );
  1235. IoReleaseCancelSpinLock( CancelIrql );
  1236. SmartcardDebug(
  1237. DEBUG_TRACE,
  1238. ( "PSCR!PscrUnloadDevice: Completing NotificationIrp %lx\n",
  1239. notificationIrp)
  1240. );
  1241. // finish the request
  1242. notificationIrp->IoStatus.Status = STATUS_SUCCESS;
  1243. notificationIrp->IoStatus.Information = 0;
  1244. IoCompleteRequest(
  1245. notificationIrp,
  1246. IO_NO_INCREMENT
  1247. );
  1248. } else {
  1249. IoReleaseCancelSpinLock( CancelIrql );
  1250. }
  1251. // Wait until we can safely unload the device
  1252. SmartcardReleaseRemoveLockAndWait(SmartcardExtension);
  1253. SmartcardExit(&DeviceExtension->SmartcardExtension);
  1254. }
  1255. // delete the symbolic link
  1256. if ( DeviceExtension->DeviceName.Buffer != NULL ) {
  1257. RtlFreeUnicodeString(&DeviceExtension->DeviceName);
  1258. DeviceExtension->DeviceName.Buffer = NULL;
  1259. }
  1260. if (DeviceExtension->SmartcardExtension.ReaderExtension != NULL) {
  1261. ExFreePool(DeviceExtension->SmartcardExtension.ReaderExtension);
  1262. DeviceExtension->SmartcardExtension.ReaderExtension = NULL;
  1263. }
  1264. // Detach from the pcmcia driver
  1265. if (DeviceExtension->AttachedPDO) {
  1266. IoDetachDevice(DeviceExtension->AttachedPDO);
  1267. DeviceExtension->AttachedPDO = NULL;
  1268. }
  1269. // delete the device object
  1270. IoDeleteDevice(DeviceObject);
  1271. SmartcardDebug(
  1272. DEBUG_TRACE,
  1273. ( "PSCR!PscrUnloadDevice: Exit\n" )
  1274. );
  1275. }
  1276. VOID
  1277. PscrUnloadDriver(
  1278. PDRIVER_OBJECT DriverObject
  1279. )
  1280. /*++
  1281. PscrUnloadDriver:
  1282. unloads all devices for a given driver object
  1283. Arguments:
  1284. DriverObject context of driver
  1285. --*/
  1286. {
  1287. SmartcardDebug(
  1288. DEBUG_TRACE,
  1289. ( "PSCR!PscrUnloadDriver\n" )
  1290. );
  1291. }
  1292. NTSTATUS
  1293. PscrCreateClose(
  1294. PDEVICE_OBJECT DeviceObject,
  1295. PIRP Irp
  1296. )
  1297. /*++
  1298. PscrCreateClose:
  1299. allowes only one open process a time
  1300. Arguments:
  1301. DeviceObject context of device
  1302. Irp context of call
  1303. Return Value:
  1304. STATUS_SUCCESS
  1305. STATUS_DEVICE_BUSY
  1306. --*/
  1307. {
  1308. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1309. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  1310. NTSTATUS status = STATUS_SUCCESS;
  1311. __try {
  1312. if (irpStack->MajorFunction == IRP_MJ_CREATE) {
  1313. status = SmartcardAcquireRemoveLockWithTag(
  1314. &deviceExtension->SmartcardExtension,
  1315. 'lCrC'
  1316. );
  1317. if (status != STATUS_SUCCESS) {
  1318. status = STATUS_DEVICE_REMOVED;
  1319. __leave;
  1320. }
  1321. // test if the device has been opened already
  1322. if (InterlockedCompareExchange(
  1323. &deviceExtension->ReaderOpen,
  1324. TRUE,
  1325. FALSE) == FALSE) {
  1326. SmartcardDebug(
  1327. DEBUG_DRIVER,
  1328. ("%s!PscrCreateClose: Open\n",
  1329. DRIVER_NAME)
  1330. );
  1331. } else {
  1332. // the device is already in use
  1333. status = STATUS_UNSUCCESSFUL;
  1334. // release the lock
  1335. SmartcardReleaseRemoveLockWithTag(
  1336. &deviceExtension->SmartcardExtension,
  1337. 'lCrC'
  1338. );
  1339. }
  1340. } else {
  1341. SmartcardDebug(
  1342. DEBUG_DRIVER,
  1343. ("%s!PscrCreateClose: Close\n",
  1344. DRIVER_NAME)
  1345. );
  1346. SmartcardReleaseRemoveLockWithTag(
  1347. &deviceExtension->SmartcardExtension,
  1348. 'lCrC'
  1349. );
  1350. deviceExtension->ReaderOpen = FALSE;
  1351. }
  1352. }
  1353. __finally {
  1354. Irp->IoStatus.Status = status;
  1355. Irp->IoStatus.Information = 0;
  1356. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1357. }
  1358. return status;
  1359. }
  1360. NTSTATUS
  1361. PscrSystemControl(
  1362. PDEVICE_OBJECT DeviceObject,
  1363. PIRP Irp
  1364. )
  1365. /*++
  1366. PscrSystemControl:
  1367. --*/
  1368. {
  1369. PDEVICE_EXTENSION DeviceExtension;
  1370. NTSTATUS status = STATUS_SUCCESS;
  1371. DeviceExtension = DeviceObject->DeviceExtension;
  1372. IoSkipCurrentIrpStackLocation(Irp);
  1373. status = IoCallDriver(DeviceExtension->AttachedPDO, Irp);
  1374. return status;
  1375. }
  1376. NTSTATUS
  1377. PscrDeviceIoControl(
  1378. PDEVICE_OBJECT DeviceObject,
  1379. PIRP Irp
  1380. )
  1381. /*++
  1382. PscrDeviceIoControl:
  1383. all IRP's requiring IO are queued to the StartIo routine, other requests
  1384. are served immediately
  1385. --*/
  1386. {
  1387. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1388. NTSTATUS status;
  1389. KIRQL irql;
  1390. LARGE_INTEGER timeout;
  1391. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  1392. if (deviceExtension->IoCount == 0) {
  1393. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  1394. status = KeWaitForSingleObject(
  1395. &deviceExtension->ReaderStarted,
  1396. Executive,
  1397. KernelMode,
  1398. FALSE,
  1399. NULL
  1400. );
  1401. ASSERT(status == STATUS_SUCCESS);
  1402. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  1403. }
  1404. ASSERT(deviceExtension->IoCount >= 0);
  1405. deviceExtension->IoCount++;
  1406. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  1407. timeout.QuadPart = 0;
  1408. status = KeWaitForSingleObject(
  1409. &deviceExtension->ReaderRemoved,
  1410. Executive,
  1411. KernelMode,
  1412. FALSE,
  1413. &timeout
  1414. );
  1415. if (status == STATUS_SUCCESS) {
  1416. status = STATUS_DEVICE_REMOVED;
  1417. } else {
  1418. status = SmartcardAcquireRemoveLock(&deviceExtension->SmartcardExtension);
  1419. }
  1420. if (status != STATUS_SUCCESS) {
  1421. // the device has been removed. Fail the call
  1422. Irp->IoStatus.Information = 0;
  1423. Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
  1424. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1425. return STATUS_DEVICE_REMOVED;
  1426. }
  1427. status = SmartcardDeviceControl(
  1428. &(deviceExtension->SmartcardExtension),
  1429. Irp
  1430. );
  1431. SmartcardReleaseRemoveLock(&deviceExtension->SmartcardExtension);
  1432. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  1433. deviceExtension->IoCount--;
  1434. ASSERT(deviceExtension->IoCount >= 0);
  1435. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  1436. return status;
  1437. }
  1438. NTSTATUS
  1439. PscrGenericIOCTL(
  1440. PSMARTCARD_EXTENSION SmartcardExtension
  1441. )
  1442. /*++
  1443. PscrGenericIOCTL:
  1444. Performs generic callbacks to the reader
  1445. Arguments:
  1446. SmartcardExtension context of the call
  1447. Return Value:
  1448. STATUS_SUCCESS
  1449. --*/
  1450. {
  1451. NTSTATUS NTStatus;
  1452. PIRP Irp;
  1453. PIO_STACK_LOCATION IrpStack;
  1454. SmartcardDebug(
  1455. DEBUG_TRACE,
  1456. ( "PSCR!PscrGenericIOCTL: Enter\n" )
  1457. );
  1458. //
  1459. // get pointer to current IRP stack location
  1460. //
  1461. Irp = SmartcardExtension->OsData->CurrentIrp;
  1462. IrpStack = IoGetCurrentIrpStackLocation( Irp );
  1463. //
  1464. // assume error
  1465. //
  1466. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  1467. Irp->IoStatus.Information = 0;
  1468. //
  1469. // dispatch IOCTL
  1470. //
  1471. switch ( IrpStack->Parameters.DeviceIoControl.IoControlCode ) {
  1472. case IOCTL_PSCR_COMMAND:
  1473. NTStatus = CmdPscrCommand(
  1474. SmartcardExtension->ReaderExtension,
  1475. (PUCHAR)Irp->AssociatedIrp.SystemBuffer,
  1476. IrpStack->Parameters.DeviceIoControl.InputBufferLength,
  1477. (PUCHAR)Irp->AssociatedIrp.SystemBuffer,
  1478. IrpStack->Parameters.DeviceIoControl.OutputBufferLength,
  1479. (PULONG) &Irp->IoStatus.Information
  1480. );
  1481. //
  1482. // the command could change the active file in the reader file
  1483. // system, so make sure that the status file will be selected
  1484. // before the next read
  1485. //
  1486. SmartcardExtension->ReaderExtension->StatusFileSelected = FALSE;
  1487. break;
  1488. case IOCTL_GET_VERSIONS:
  1489. if ( IrpStack->Parameters.DeviceIoControl.OutputBufferLength <
  1490. SIZEOF_VERSION_CONTROL ) {
  1491. NTStatus = STATUS_BUFFER_TOO_SMALL;
  1492. } else {
  1493. PVERSION_CONTROL VersionControl;
  1494. VersionControl = (PVERSION_CONTROL)Irp->AssociatedIrp.SystemBuffer;
  1495. VersionControl->SmclibVersion = SmartcardExtension->Version;
  1496. VersionControl->DriverMajor = PSCR_MAJOR_VERSION;
  1497. VersionControl->DriverMinor = PSCR_MINOR_VERSION;
  1498. // update firmware version (changed after update)
  1499. CmdGetFirmwareRevision(
  1500. SmartcardExtension->ReaderExtension
  1501. );
  1502. VersionControl->FirmwareMajor =
  1503. SmartcardExtension->ReaderExtension->FirmwareMajor;
  1504. VersionControl->FirmwareMinor =
  1505. SmartcardExtension->ReaderExtension->FirmwareMinor;
  1506. VersionControl->UpdateKey =
  1507. SmartcardExtension->ReaderExtension->UpdateKey;
  1508. Irp->IoStatus.Information = SIZEOF_VERSION_CONTROL;
  1509. NTStatus = STATUS_SUCCESS;
  1510. }
  1511. break;
  1512. case IOCTL_SET_TIMEOUT:
  1513. {
  1514. ULONG NewLimit;
  1515. //
  1516. // get new timeout limit
  1517. //
  1518. if ( IrpStack->Parameters.DeviceIoControl.InputBufferLength ==
  1519. sizeof( ULONG )) {
  1520. NewLimit = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
  1521. } else {
  1522. NewLimit = 0;
  1523. }
  1524. //
  1525. // report actual timeout limit
  1526. //
  1527. if ( IrpStack->Parameters.DeviceIoControl.OutputBufferLength ==
  1528. sizeof( ULONG )) {
  1529. *(PULONG)Irp->AssociatedIrp.SystemBuffer =
  1530. SmartcardExtension->ReaderExtension->MaxRetries * DELAY_PSCR_WAIT;
  1531. Irp->IoStatus.Information = sizeof( ULONG );
  1532. }
  1533. //
  1534. // set new timeout limit
  1535. //
  1536. if ( (NewLimit != 0) ||
  1537. (NewLimit == MAXULONG-DELAY_PSCR_WAIT+2 )) {
  1538. SmartcardExtension->ReaderExtension->MaxRetries =
  1539. (NewLimit + DELAY_PSCR_WAIT - 1) / DELAY_PSCR_WAIT;
  1540. }
  1541. }
  1542. NTStatus = STATUS_SUCCESS;
  1543. break;
  1544. case IOCTL_GET_CONFIGURATION:
  1545. //
  1546. // return IOBase and IRQ
  1547. //
  1548. if ( IrpStack->Parameters.DeviceIoControl.OutputBufferLength <
  1549. SIZEOF_PSCR_CONFIGURATION ) {
  1550. NTStatus = STATUS_BUFFER_TOO_SMALL;
  1551. } else {
  1552. PPSCR_CONFIGURATION PSCRConfiguration;
  1553. PSCRConfiguration =
  1554. (PPSCR_CONFIGURATION)Irp->AssociatedIrp.SystemBuffer;
  1555. PSCRConfiguration->IOBase =
  1556. SmartcardExtension->ReaderExtension->IOBase;
  1557. PSCRConfiguration->IRQ =
  1558. SmartcardExtension->ReaderExtension->CurrentIRQ;
  1559. Irp->IoStatus.Information = SIZEOF_PSCR_CONFIGURATION;
  1560. NTStatus = STATUS_SUCCESS;
  1561. }
  1562. break;
  1563. default:
  1564. break;
  1565. }
  1566. //
  1567. // set status of the packet
  1568. //
  1569. Irp->IoStatus.Status = NTStatus;
  1570. SmartcardDebug(
  1571. DEBUG_TRACE,
  1572. ( "PSCR!PscrGenericIOCTL: Exit\n" )
  1573. );
  1574. return( NTStatus );
  1575. }
  1576. BOOLEAN
  1577. PscrIrqServiceRoutine(
  1578. PKINTERRUPT Interrupt,
  1579. PDEVICE_EXTENSION DeviceExtension
  1580. )
  1581. /*++
  1582. PscrIrqServiceRoutine:
  1583. because the device not supports shared interrupts, the call is passed
  1584. to the DPC routine immediately and the IRQ is reported as served
  1585. Arguments:
  1586. Interrupt interrupt object related to the interrupt
  1587. DeviceExtension context of call
  1588. Return Value:
  1589. STATUS_SUCCESS
  1590. --*/
  1591. {
  1592. SmartcardDebug(
  1593. DEBUG_TRACE,
  1594. ("PSCR!PscrIrqServiceRoutine: Enter\n")
  1595. );
  1596. //
  1597. // When someone yanks out the card the interrupt handler gets called,
  1598. // but since there is no card anymore when don't need to schedule a DPC
  1599. //
  1600. //
  1601. // the interrupt is caused by a freeze event. the interface will be
  1602. // cleared either by PscrRead() or the DPC routine (depending on
  1603. // which is called first)
  1604. //
  1605. DeviceExtension->SmartcardExtension.ReaderExtension->FreezePending = TRUE;
  1606. InterlockedIncrement(&DeviceExtension->PendingInterrupts);
  1607. KeInsertQueueDpc(
  1608. &DeviceExtension->DpcObject,
  1609. DeviceExtension,
  1610. &DeviceExtension->SmartcardExtension
  1611. );
  1612. SmartcardDebug(
  1613. DEBUG_TRACE,
  1614. ( "PSCR!PscrIrqServiceRoutine: Exit\n" )
  1615. );
  1616. return TRUE;
  1617. }
  1618. VOID
  1619. PscrDpcRoutine(
  1620. PKDPC Dpc,
  1621. PDEVICE_OBJECT DeviceObject,
  1622. PDEVICE_EXTENSION DeviceExtension,
  1623. PSMARTCARD_EXTENSION SmartcardExtension
  1624. )
  1625. /*++
  1626. PscrDpcRoutine:
  1627. finishes interrupt requests. the freeze event data of the reader will be read
  1628. & the card state will be updated if data valid
  1629. Arguments:
  1630. Dpc dpc object related to the call
  1631. DeviceObject context of the device
  1632. DeviceExtension passed as system argument 1
  1633. SmartcardExtension passed as system argument 2
  1634. Return Value:
  1635. void
  1636. --*/
  1637. {
  1638. NTSTATUS status = STATUS_SUCCESS;
  1639. UCHAR Event;
  1640. SmartcardDebug(
  1641. DEBUG_TRACE,
  1642. ( "PSCR!PscrInterruptEvent: IoBase %xh\n",
  1643. SmartcardExtension->ReaderExtension->IOBase)
  1644. );
  1645. //
  1646. // In case of a card change the reader provides a TLV packet describing
  1647. // the event ('freeze event'). If PscrRead was called before the DPC
  1648. // routine is called, this event was cleared; in this case the card state
  1649. // will be updated by reading the card status file
  1650. //
  1651. do {
  1652. ASSERT(DeviceExtension->PendingInterrupts < 10);
  1653. SmartcardDebug(
  1654. DEBUG_TRACE,
  1655. ( "PSCR!PscrInterruptEvent: PendingInterrupts = %ld\n",
  1656. DeviceExtension->PendingInterrupts)
  1657. );
  1658. PscrFreeze( SmartcardExtension );
  1659. } while (InterlockedDecrement(&DeviceExtension->PendingInterrupts) > 0);
  1660. }
  1661. void
  1662. PscrFreeze(
  1663. PSMARTCARD_EXTENSION SmartcardExtension
  1664. )
  1665. /*++
  1666. PscrFreeze:
  1667. Read & evaluate freeze data
  1668. Arguments:
  1669. ReaderExtension context of call
  1670. pDevice device which causes the freeze event
  1671. Return Value:
  1672. STATUS_SUCCESS
  1673. STATUS_UNSUCCESSFUL
  1674. --*/
  1675. {
  1676. NTSTATUS NTStatus = STATUS_UNSUCCESSFUL;
  1677. PREADER_EXTENSION ReaderExtension;
  1678. PPSCR_REGISTERS IOBase;
  1679. UCHAR TLVList[9], CardState;
  1680. ULONG NBytes;
  1681. ULONG Idx, Retries, Status;
  1682. UCHAR ReadFreeze[] = { 0x12, 0x00, 0x05, 0x00, 0xB0, 0x00, 0x00, 0x01, 0xA6};
  1683. ReaderExtension = SmartcardExtension->ReaderExtension;
  1684. IOBase = ReaderExtension->IOBase;
  1685. for (Retries = 0; Retries < 5; Retries++) {
  1686. Status = READ_PORT_UCHAR( &IOBase->CmdStatusReg );
  1687. ReaderExtension->InvalidStatus = TRUE;
  1688. if (!( Status & PSCR_DATA_AVAIL_BIT )) {
  1689. PscrWriteDirect(
  1690. ReaderExtension,
  1691. ReadFreeze,
  1692. sizeof( ReadFreeze ),
  1693. &NBytes
  1694. );
  1695. SysDelay(15);
  1696. }
  1697. NTStatus = PscrRead(
  1698. ReaderExtension,
  1699. (PUCHAR) TLVList,
  1700. sizeof( TLVList ),
  1701. &NBytes
  1702. );
  1703. ReaderExtension->InvalidStatus = FALSE;
  1704. if ( NT_SUCCESS( NTStatus ) && ( NBytes == 9 )) {
  1705. // get result
  1706. if ( ( TLVList[ PSCR_NAD ] == 0x21 ) &&
  1707. ( TLVList[ PSCR_INF ] == TAG_FREEZE_EVENTS )) {
  1708. CardState =
  1709. (TLVList[PSCR_INF + 2] == DEVICE_ICC1 ? PSCR_ICC_PRESENT : PSCR_ICC_ABSENT);
  1710. SmartcardDebug(
  1711. DEBUG_TRACE,
  1712. ( "PSCR!PscrFreeze: CardState = %d\n",
  1713. CardState)
  1714. );
  1715. CBUpdateCardState(SmartcardExtension, CardState, FALSE);
  1716. }
  1717. }
  1718. }
  1719. }
  1720. NTSTATUS
  1721. PscrCancel(
  1722. IN PDEVICE_OBJECT DeviceObject,
  1723. IN PIRP Irp
  1724. )
  1725. /*++
  1726. Routine Description:
  1727. This routine is called by the I/O system
  1728. when the irp should be cancelled
  1729. Arguments:
  1730. DeviceObject - Pointer to device object for this miniport
  1731. Irp - IRP involved.
  1732. Return Value:
  1733. STATUS_CANCELLED
  1734. --*/
  1735. {
  1736. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1737. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  1738. SmartcardDebug(
  1739. DEBUG_TRACE,
  1740. ("PSCR!PscrCancel: Enter\n")
  1741. );
  1742. ASSERT(Irp == smartcardExtension->OsData->NotificationIrp);
  1743. smartcardExtension->OsData->NotificationIrp = NULL;
  1744. Irp->IoStatus.Information = 0;
  1745. Irp->IoStatus.Status = STATUS_CANCELLED;
  1746. IoReleaseCancelSpinLock(
  1747. Irp->CancelIrql
  1748. );
  1749. SmartcardDebug(
  1750. DEBUG_DRIVER,
  1751. ("PSCR!PscrCancel: Completing wait for Irp = %lx\n",
  1752. Irp)
  1753. );
  1754. IoCompleteRequest(
  1755. Irp,
  1756. IO_NO_INCREMENT
  1757. );
  1758. SmartcardDebug(
  1759. DEBUG_TRACE,
  1760. ("PSCR!PscrCancel: Exit\n")
  1761. );
  1762. return STATUS_CANCELLED;
  1763. }
  1764. NTSTATUS
  1765. PscrCleanup(
  1766. IN PDEVICE_OBJECT DeviceObject,
  1767. IN PIRP Irp
  1768. )
  1769. /*++
  1770. Routine Description:
  1771. This routine is called by the I/O system when the calling thread terminates
  1772. Arguments:
  1773. DeviceObject - Pointer to device object for this miniport
  1774. Irp - IRP involved.
  1775. Return Value:
  1776. STATUS_CANCELLED
  1777. --*/
  1778. {
  1779. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1780. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  1781. NTSTATUS status = STATUS_SUCCESS;
  1782. SmartcardDebug(
  1783. DEBUG_TRACE,
  1784. ("%s!PscrCleanup: Enter\n",
  1785. DRIVER_NAME)
  1786. );
  1787. IoAcquireCancelSpinLock(&(Irp->CancelIrql));
  1788. if (smartcardExtension->OsData->NotificationIrp) {
  1789. // We need to complete the notification irp
  1790. IoSetCancelRoutine(
  1791. smartcardExtension->OsData->NotificationIrp,
  1792. NULL
  1793. );
  1794. PscrCancel(
  1795. DeviceObject,
  1796. smartcardExtension->OsData->NotificationIrp
  1797. );
  1798. } else {
  1799. IoReleaseCancelSpinLock( Irp->CancelIrql );
  1800. }
  1801. SmartcardDebug(
  1802. DEBUG_DRIVER,
  1803. ("%s!PscrCleanup: Completing IRP %lx\n",
  1804. DRIVER_NAME,
  1805. Irp)
  1806. );
  1807. Irp->IoStatus.Information = 0;
  1808. Irp->IoStatus.Status = STATUS_SUCCESS;
  1809. IoCompleteRequest(
  1810. Irp,
  1811. IO_NO_INCREMENT
  1812. );
  1813. SmartcardDebug(
  1814. DEBUG_TRACE,
  1815. ("%s!PscrCleanup: Exit\n",
  1816. DRIVER_NAME)
  1817. );
  1818. return STATUS_SUCCESS;
  1819. }
  1820. void
  1821. SysDelay(
  1822. ULONG Timeout
  1823. )
  1824. /*++
  1825. SysDelay:
  1826. performs a required delay. The usage of KeStallExecutionProcessor is
  1827. very nasty, but it happends only if SysDelay is called in the context of
  1828. our DPC routine (which is only called if a card change was detected).
  1829. For 'normal' IO we have Irql < DISPATCH_LEVEL, so if the reader is polled
  1830. while waiting for response we will not block the entire system
  1831. Arguments:
  1832. Timeout delay in milli seconds
  1833. Return Value:
  1834. void
  1835. --*/
  1836. {
  1837. LARGE_INTEGER SysTimeout;
  1838. if ( KeGetCurrentIrql() >= DISPATCH_LEVEL ) {
  1839. ULONG Cnt = 20 * Timeout;
  1840. while ( Cnt-- ) {
  1841. // KeStallExecutionProcessor: counted in us
  1842. KeStallExecutionProcessor( 50 );
  1843. }
  1844. } else {
  1845. SysTimeout.QuadPart = (LONGLONG)-10 * 1000 * Timeout;
  1846. // KeDelayExecutionThread: counted in 100 ns
  1847. KeDelayExecutionThread( KernelMode, FALSE, &SysTimeout );
  1848. }
  1849. return;
  1850. }