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.

2816 lines
94 KiB

  1. /*++
  2. Copyright (c) 1998 Gemplus Development
  3. Name:
  4. Gprnt.C
  5. Description:
  6. This is the main module which holds:
  7. - the main functions for a standard DDK NT driver
  8. - the IOCTL functions defined for this driver.
  9. Environment:
  10. Kernel Mode
  11. Revision History:
  12. 08/10/99: Y. Nadeau
  13. - Make a version for Compaq PC-CARD Reader.
  14. 06/04/98: (Y. Nadeau M. Veillette)
  15. - Code review
  16. 18/11/98: V1.00.006 (Y. Nadeau)
  17. - Add log errors at startup, and Cleanup revised.
  18. 16/10/98: V1.00.005 (Y. Nadeau)
  19. - Remove DEVICEID in IoCreateDevice (Klaus)
  20. 18/09/98: V1.00.004 (Y. Nadeau)
  21. - Correction for NT5 beta 3
  22. 06/05/98: V1.00.003 (P. Plouidy)
  23. - Power management for NT5
  24. 10/02/98: V1.00.002 (P. Plouidy)
  25. - Plug and Play for NT5
  26. 03/07/97: V1.00.001 (P. Plouidy)
  27. - Start of development.
  28. --*/
  29. #include <stdio.h>
  30. #include "gprnt.h"
  31. #include "gprcmd.h"
  32. #include "gprelcmd.h"
  33. #include "logmsg.h"
  34. //
  35. // Pragma section
  36. //
  37. #pragma alloc_text (INIT,DriverEntry)
  38. #pragma alloc_text (PAGEABLE,GprAddDevice)
  39. #pragma alloc_text (PAGEABLE,GprCreateDevice)
  40. #pragma alloc_text (PAGEABLE,GprUnloadDevice)
  41. #pragma alloc_text (PAGEABLE,GprUnloadDriver)
  42. #if DBG
  43. #pragma optimize ("",off)
  44. #endif
  45. //
  46. // Constant section
  47. // - MAX_DEVICES is the maximum number of device supported
  48. // - POLLING_TIME polling frequency in ms
  49. //
  50. #define MAX_DEVICES 4
  51. #define POLLING_TIME 500
  52. ULONG dataRatesSupported[] = {9909};
  53. //
  54. // Global variable section
  55. // bDeviceSlot is an array of boolean to signal if a device is already created.
  56. //
  57. BOOLEAN bDeviceSlot[GPR_MAX_DEVICE];
  58. NTSTATUS DriverEntry(
  59. PDRIVER_OBJECT DriverObject,
  60. PUNICODE_STRING RegistryPath
  61. )
  62. /*++
  63. Routine description:
  64. This routine is called at system initialization time to initialize
  65. this driver.
  66. Arguments
  67. DriverObject - supplies the driver object.
  68. RegistryPath - supplies the registry path for this driver.
  69. Return Value:
  70. STATUS_SUCCESS We could initialize at least one device
  71. --*/
  72. {
  73. SmartcardDebug(
  74. DEBUG_INFO,
  75. ("%s!DriverEntry: Enter - %s %s\n",
  76. SC_DRIVER_NAME,
  77. __DATE__,
  78. __TIME__)
  79. );
  80. // Initialization of the Driver Object with driver's entry points.
  81. DriverObject->DriverUnload = GprUnloadDriver;
  82. DriverObject->DriverExtension->AddDevice = GprAddDevice;
  83. DriverObject->MajorFunction[IRP_MJ_PNP] = GprDispatchPnp;
  84. DriverObject->MajorFunction[IRP_MJ_CREATE] = GprCreateClose;
  85. DriverObject->MajorFunction[IRP_MJ_CLOSE] = GprCreateClose;
  86. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = GprCleanup;
  87. DriverObject->MajorFunction[IRP_MJ_POWER] = GprPower;
  88. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GprDeviceControl;
  89. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = GprSystemControl;
  90. SmartcardDebug(
  91. DEBUG_DRIVER,
  92. ("%s!DriverEntry: Exit\n",
  93. SC_DRIVER_NAME)
  94. );
  95. return(STATUS_SUCCESS);
  96. }
  97. NTSTATUS GprAddDevice(
  98. IN PDRIVER_OBJECT DriverObject,
  99. IN PDEVICE_OBJECT PhysicalDeviceObject
  100. )
  101. /*++
  102. Routine Description:
  103. Add device routine
  104. Arguments
  105. DriverObject point to the driver object.
  106. PhysicalDeviceObject point to the PDO for the pnp device added
  107. Return Value:
  108. STATUS_SUCCESS
  109. STATUS_INSUFFICIENT_RESOURCES
  110. */
  111. {
  112. NTSTATUS NTStatus = STATUS_SUCCESS;
  113. PDEVICE_OBJECT DeviceObject = NULL;
  114. ANSI_STRING DeviceID;
  115. PAGED_CODE();
  116. ASSERT(DriverObject != NULL);
  117. ASSERT(PhysicalDeviceObject != NULL);
  118. SmartcardDebug(
  119. DEBUG_DRIVER,
  120. ( "%s!GprAddDevice: Enter\n",
  121. SC_DRIVER_NAME)
  122. );
  123. __try
  124. {
  125. PDEVICE_EXTENSION DeviceExtension;
  126. LONG DeviceIdLength;
  127. //
  128. // try to create the device
  129. //
  130. NTStatus = GprCreateDevice(
  131. DriverObject,
  132. PhysicalDeviceObject,
  133. &DeviceObject
  134. );
  135. if (NTStatus != STATUS_SUCCESS) {
  136. SmartcardDebug(
  137. DEBUG_ERROR,
  138. ( "%s!GprAddDevice: GprCreateDevice=%X(hex)\n",
  139. SC_DRIVER_NAME,
  140. NTStatus)
  141. );
  142. __leave;
  143. }
  144. //
  145. // Attach the physicalDeviceObject to the new created device
  146. //
  147. DeviceExtension = DeviceObject->DeviceExtension;
  148. DeviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject = IoAttachDeviceToDeviceStack(
  149. DeviceObject,
  150. PhysicalDeviceObject
  151. );
  152. ASSERT(DeviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject != NULL);
  153. if (DeviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject == NULL) {
  154. NTStatus = STATUS_UNSUCCESSFUL;
  155. __leave;
  156. }
  157. //
  158. // Register the new device object
  159. //
  160. NTStatus = IoRegisterDeviceInterface(
  161. PhysicalDeviceObject,
  162. &SmartCardReaderGuid,
  163. NULL,
  164. &DeviceExtension->PnPDeviceName
  165. );
  166. RtlUnicodeStringToAnsiString(&DeviceID, &DeviceExtension->PnPDeviceName, TRUE);
  167. DeviceIdLength = (LONG) RtlCompareMemory(DeviceID.Buffer, COMPAQ_ID, CHECK_ID_LEN);
  168. SmartcardDebug(
  169. DEBUG_ERROR,
  170. ( "%s!GprAddDevice: DeviceIdLength = %d, PnPDeviceName=%s\n",
  171. SC_DRIVER_NAME, DeviceIdLength, DeviceID.Buffer)
  172. );
  173. // it's a DeviceID of COMPAQ ?
  174. if ( DeviceIdLength == CHECK_ID_LEN) {
  175. SmartcardDebug(
  176. DEBUG_INFO,
  177. ( "%s!GprAddDevice: Compaq reader detect!\n",
  178. SC_DRIVER_NAME)
  179. );
  180. DeviceExtension->DriverFlavor = DF_CPQ400;
  181. }
  182. // Initialize the vendor information.
  183. // Driver flavor
  184. //
  185. switch (DeviceExtension->DriverFlavor) {
  186. case DF_IBM400:
  187. // IBM IBM400
  188. RtlCopyMemory(DeviceExtension->SmartcardExtension.VendorAttr.VendorName.Buffer,
  189. SZ_VENDOR_NAME_IBM, sizeof(SZ_VENDOR_NAME_IBM));
  190. RtlCopyMemory(DeviceExtension->SmartcardExtension.VendorAttr.IfdType.Buffer,
  191. SZ_READER_NAME_IBM, sizeof(SZ_READER_NAME_IBM));
  192. DeviceExtension->SmartcardExtension.VendorAttr.VendorName.Length = sizeof(SZ_VENDOR_NAME_IBM);
  193. DeviceExtension->SmartcardExtension.VendorAttr.IfdType.Length = sizeof(SZ_READER_NAME_IBM);
  194. break;
  195. case DF_CPQ400:
  196. // COMPAQ PC_CARD_SMARTCARD_READER
  197. RtlCopyMemory(DeviceExtension->SmartcardExtension.VendorAttr.VendorName.Buffer,
  198. SZ_VENDOR_NAME_COMPAQ, sizeof(SZ_VENDOR_NAME_COMPAQ));
  199. RtlCopyMemory(DeviceExtension->SmartcardExtension.VendorAttr.IfdType.Buffer,
  200. SZ_READER_NAME_COMPAQ, sizeof(SZ_READER_NAME_COMPAQ));
  201. DeviceExtension->SmartcardExtension.VendorAttr.VendorName.Length = sizeof(SZ_VENDOR_NAME_COMPAQ);
  202. DeviceExtension->SmartcardExtension.VendorAttr.IfdType.Length = sizeof(SZ_READER_NAME_COMPAQ);
  203. break;
  204. default:
  205. // Gemplus GPR400
  206. break;
  207. }
  208. SmartcardDebug(
  209. DEBUG_INFO,
  210. ( "%s!GprAddDevice: DriverFlavor VendorName:%s IfdType:%s UnitNo:%d\n",
  211. SC_DRIVER_NAME,
  212. DeviceExtension->SmartcardExtension.VendorAttr.VendorName.Buffer,
  213. DeviceExtension->SmartcardExtension.VendorAttr.IfdType.Buffer,
  214. DeviceExtension->SmartcardExtension.VendorAttr.UnitNo)
  215. );
  216. RtlFreeAnsiString(&DeviceID);
  217. ASSERT(NTStatus == STATUS_SUCCESS);
  218. DeviceObject->Flags |= DO_BUFFERED_IO;
  219. DeviceObject->Flags |= DO_POWER_PAGABLE;
  220. DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  221. }
  222. __finally
  223. {
  224. if (NTStatus != STATUS_SUCCESS) {
  225. GprUnloadDevice(DeviceObject);
  226. }
  227. }
  228. SmartcardDebug(
  229. DEBUG_DRIVER,
  230. ( "%s!GprAddDevice: Exit =%X(hex)\n",
  231. SC_DRIVER_NAME,
  232. NTStatus)
  233. );
  234. return NTStatus;
  235. }
  236. NTSTATUS GprCreateDevice(
  237. IN PDRIVER_OBJECT DriverObject,
  238. IN PDEVICE_OBJECT PhysicalDeviceObject,
  239. OUT PDEVICE_OBJECT *DeviceObject
  240. )
  241. /*++
  242. Routine description:
  243. This routine creates an object for the physical device specified
  244. and sets up the deviceExtension
  245. Arguments:
  246. DriverObject context of call
  247. DeviceObject ptr to the created device object
  248. Return value:
  249. STATUS_SUCCESS
  250. --*/
  251. {
  252. NTSTATUS NTStatus = STATUS_SUCCESS;
  253. ULONG DeviceInstance;
  254. PDEVICE_EXTENSION DeviceExtension;
  255. PSMARTCARD_EXTENSION SmartcardExtension;
  256. PAGED_CODE();
  257. ASSERT(DriverObject != NULL);
  258. ASSERT(PhysicalDeviceObject != NULL);
  259. *DeviceObject = NULL;
  260. SmartcardDebug(
  261. DEBUG_DRIVER,
  262. ( "%s!GprCreateDevice: Enter\n",
  263. SC_DRIVER_NAME)
  264. );
  265. __try
  266. {
  267. for ( DeviceInstance = 0; DeviceInstance < GPR_MAX_DEVICE; DeviceInstance++ ) {
  268. if (bDeviceSlot[DeviceInstance] == FALSE) {
  269. bDeviceSlot[DeviceInstance] = TRUE;
  270. break;
  271. }
  272. }
  273. // Create the device object
  274. NTStatus = IoCreateDevice(
  275. DriverObject,
  276. sizeof(DEVICE_EXTENSION),
  277. NULL,
  278. FILE_DEVICE_SMARTCARD,
  279. 0,
  280. TRUE,
  281. DeviceObject
  282. );
  283. if (NTStatus != STATUS_SUCCESS) {
  284. SmartcardDebug(
  285. DEBUG_ERROR,
  286. ( "%s!GprCreateDevice: IoCreateDevice status=%X(hex)\n",
  287. SC_DRIVER_NAME,
  288. NTStatus)
  289. );
  290. SmartcardLogError(
  291. DriverObject,
  292. GEMSCR0D_ERROR_CLAIM_RESOURCES,
  293. NULL,
  294. 0
  295. );
  296. __leave;
  297. }
  298. ASSERT(DeviceObject != NULL);
  299. // set up the device extension.
  300. DeviceExtension = (*DeviceObject)->DeviceExtension;
  301. ASSERT(DeviceExtension != NULL);
  302. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  303. // allocate the reader extension
  304. SmartcardExtension->ReaderExtension = ExAllocatePool(
  305. NonPagedPool,
  306. sizeof( READER_EXTENSION )
  307. );
  308. if ( SmartcardExtension->ReaderExtension == NULL ) {
  309. SmartcardLogError(
  310. DriverObject,
  311. GEMSCR0D_ERROR_CLAIM_RESOURCES,
  312. NULL,
  313. 0
  314. );
  315. SmartcardDebug(
  316. DEBUG_ERROR,
  317. ( "%s!GprCreateDevice: ReaderExtension failed %X(hex)\n",
  318. SC_DRIVER_NAME,
  319. NTStatus )
  320. );
  321. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  322. __leave;
  323. }
  324. RtlZeroMemory(
  325. SmartcardExtension->ReaderExtension,
  326. sizeof( READER_EXTENSION )
  327. );
  328. // allocate the Vo Buffer
  329. SmartcardExtension->ReaderExtension->Vo = ExAllocatePool(
  330. NonPagedPool,
  331. GPR_BUFFER_SIZE
  332. );
  333. if ( SmartcardExtension->ReaderExtension->Vo == NULL ) {
  334. SmartcardLogError(
  335. DriverObject,
  336. GEMSCR0D_ERROR_CLAIM_RESOURCES,
  337. NULL,
  338. 0
  339. );
  340. SmartcardDebug(
  341. DEBUG_ERROR,
  342. ( "%s!GprCreateDevice: Vo buffer failed %X(hex)\n",
  343. SC_DRIVER_NAME,
  344. NTStatus )
  345. );
  346. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  347. __leave;
  348. }
  349. RtlZeroMemory(
  350. SmartcardExtension->ReaderExtension->Vo,
  351. GPR_BUFFER_SIZE
  352. );
  353. // Used for device removal notification
  354. KeInitializeEvent(
  355. &(SmartcardExtension->ReaderExtension->ReaderRemoved),
  356. NotificationEvent,
  357. FALSE
  358. );
  359. //
  360. // GPR400 acknowledge event initialization
  361. //
  362. KeInitializeEvent(
  363. &(SmartcardExtension->ReaderExtension->GPRAckEvent),
  364. SynchronizationEvent,
  365. FALSE
  366. );
  367. KeInitializeEvent(
  368. &(SmartcardExtension->ReaderExtension->GPRIccPresEvent),
  369. SynchronizationEvent,
  370. FALSE
  371. );
  372. // Setup the DPC routine to be called after the ISR completes.
  373. KeInitializeDpc(
  374. &DeviceExtension->DpcObject,
  375. GprCardEventDpc,
  376. *DeviceObject // should be DeviceExtension
  377. );
  378. // Card presence polling DPC routine initialization
  379. KeInitializeDpc(
  380. &SmartcardExtension->ReaderExtension->CardDpcObject,
  381. GprCardPresenceDpc,
  382. DeviceExtension
  383. );
  384. // Initialization of the card detection timer
  385. KeInitializeTimer(
  386. &(SmartcardExtension->ReaderExtension->CardDetectionTimer)
  387. );
  388. // This event signals Start/Stop notification
  389. KeInitializeEvent(
  390. &DeviceExtension->ReaderStarted,
  391. NotificationEvent,
  392. FALSE
  393. );
  394. // Used to keep track of open calls
  395. KeInitializeEvent(
  396. &DeviceExtension->ReaderClosed,
  397. NotificationEvent,
  398. TRUE
  399. );
  400. // Used to keep track of open calls
  401. KeInitializeEvent(
  402. &SmartcardExtension->ReaderExtension->IdleState,
  403. SynchronizationEvent,
  404. TRUE
  405. );
  406. SmartcardExtension->ReaderExtension->RestartCardDetection = FALSE;
  407. // void function, This routine must be called
  408. // before an initial call to KeAcquireSpinLock
  409. KeInitializeSpinLock(&DeviceExtension->SpinLock);
  410. // This worker thread is use to start de GPR in Power mode
  411. DeviceExtension->GprWorkStartup = IoAllocateWorkItem(
  412. *DeviceObject
  413. );
  414. if ( DeviceExtension->GprWorkStartup == NULL ) {
  415. SmartcardLogError(
  416. DriverObject,
  417. GEMSCR0D_ERROR_CLAIM_RESOURCES,
  418. NULL,
  419. 0
  420. );
  421. SmartcardDebug(
  422. DEBUG_ERROR,
  423. ( "%s!GprCreateDevice: GprWorkStartup failed %X(hex)\n",
  424. SC_DRIVER_NAME,
  425. NTStatus )
  426. );
  427. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  428. __leave;
  429. }
  430. // Now setup information in our deviceExtension.
  431. SmartcardExtension->ReaderCapabilities.CurrentState = (ULONG) SCARD_UNKNOWN;
  432. SmartcardExtension->ReaderCapabilities.MechProperties = 0;
  433. // enter correct version of the lib
  434. SmartcardExtension->Version = SMCLIB_VERSION;
  435. // Setup the Smartcard support functions that we implement.
  436. SmartcardExtension->ReaderFunction[RDF_CARD_POWER] = GprCbReaderPower;
  437. SmartcardExtension->ReaderFunction[RDF_TRANSMIT] = GprCbTransmit;
  438. SmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = GprCbSetProtocol;
  439. SmartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = GprCbSetupCardTracking;
  440. SmartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = GprCbVendorIoctl;
  441. DeviceExtension->PowerState = PowerDeviceD0;
  442. // Initialize the vendor information.
  443. strcpy(SmartcardExtension->VendorAttr.VendorName.Buffer, SC_VENDOR_NAME);
  444. strcpy(SmartcardExtension->VendorAttr.IfdType.Buffer, SC_IFD_TYPE);
  445. SmartcardExtension->VendorAttr.VendorName.Length = (USHORT)strlen(SC_VENDOR_NAME);
  446. SmartcardExtension->VendorAttr.IfdType.Length = (USHORT)strlen(SC_IFD_TYPE);
  447. SmartcardExtension->VendorAttr.UnitNo = DeviceInstance;
  448. DeviceExtension->DriverFlavor = DF_GPR400;
  449. //
  450. // Reader capabilities:
  451. // - the type of the reader (SCARD_READER_TYPE_PCMCIA)
  452. // - the protocols supported by the reader (SCARD_PROTOCOL_T0, SCARD_PROTOCOL_T1)
  453. // - the mechanical characteristic of the reader:
  454. // Verify if the reader can supports the detection of the card
  455. // insertion/removal. Only the main reader supports this functionnality.
  456. // - the default clock frequency
  457. // - the maximum clock frequency
  458. // - the default data rate
  459. // - the maximum data rate
  460. // - the maximum IFSD
  461. //
  462. SmartcardExtension->ReaderCapabilities.ReaderType =
  463. SCARD_READER_TYPE_PCMCIA;
  464. SmartcardExtension->ReaderCapabilities.SupportedProtocols =
  465. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  466. SmartcardExtension->ReaderCapabilities.Channel = DeviceInstance;
  467. SmartcardExtension->ReaderCapabilities.CLKFrequency.Default = GPR_DEFAULT_FREQUENCY;
  468. SmartcardExtension->ReaderCapabilities.CLKFrequency.Max = GPR_MAX_FREQUENCY;
  469. SmartcardExtension->ReaderCapabilities.MaxIFSD = GPR_MAX_IFSD;
  470. SmartcardExtension->ReaderCapabilities.DataRate.Default = GPR_DEFAULT_DATARATE;
  471. SmartcardExtension->ReaderCapabilities.DataRate.Max = GPR_MAX_DATARATE;
  472. //
  473. // Reader capabilities (continue):
  474. // - List all the supported data rates
  475. //
  476. SmartcardExtension->ReaderCapabilities.DataRatesSupported.List =
  477. dataRatesSupported;
  478. SmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
  479. sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
  480. //
  481. // Reader Extension:
  482. //- the command timeout for the reader (GPR_DEFAULT_TIME)
  483. //
  484. SmartcardExtension->ReaderExtension->CmdTimeOut = GPR_DEFAULT_TIME;
  485. SmartcardExtension->ReaderExtension->PowerTimeOut = GPR_DEFAULT_POWER_TIME;
  486. //
  487. // Flag will prevent completion of the request
  488. // when the system will be waked up again.
  489. //
  490. SmartcardExtension->ReaderExtension->PowerRequest = FALSE;
  491. //
  492. // Flag to know we strating a new device, not an hibernation mode.
  493. //
  494. SmartcardExtension->ReaderExtension->NewDevice = TRUE;
  495. SmartcardExtension->SmartcardRequest.BufferSize = MIN_BUFFER_SIZE;
  496. SmartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
  497. NTStatus = SmartcardInitialize(SmartcardExtension);
  498. if (NTStatus != STATUS_SUCCESS) {
  499. SmartcardLogError(
  500. DriverObject,
  501. GEMSCR0D_ERROR_CLAIM_RESOURCES,
  502. NULL,
  503. 0
  504. );
  505. SmartcardDebug(
  506. DEBUG_ERROR,
  507. ( "%s!GprCreateDevice: SmartcardInitialize failed %X(hex)\n",
  508. SC_DRIVER_NAME,
  509. NTStatus )
  510. );
  511. __leave;
  512. }
  513. //
  514. // tell the lib our device object & create
  515. // symbolic link
  516. //
  517. SmartcardExtension->OsData->DeviceObject = *DeviceObject;
  518. // save the current power state of the reader
  519. SmartcardExtension->ReaderExtension->ReaderPowerState =
  520. PowerReaderWorking;
  521. }
  522. __finally
  523. {
  524. if (NTStatus != STATUS_SUCCESS) {
  525. // Do the driver unload in the calling function.
  526. }
  527. SmartcardDebug(
  528. DEBUG_DRIVER,
  529. ( "%s!GprCreateDevice: Exit %X(hex)\n",
  530. SC_DRIVER_NAME,
  531. NTStatus )
  532. );
  533. }
  534. return NTStatus;
  535. }
  536. NTSTATUS GprStartDevice(
  537. PDEVICE_OBJECT DeviceObject,
  538. PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
  539. )
  540. /*++
  541. Routine Description
  542. get the actual configuration from the passed FullResourceDescriptor
  543. and initializes the reader hardware
  544. --*/
  545. {
  546. PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
  547. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  548. PSMARTCARD_EXTENSION pSCardExt = &DeviceExtension->SmartcardExtension;
  549. PREADER_EXTENSION pReaderExt = pSCardExt->ReaderExtension;
  550. NTSTATUS NTStatus = STATUS_SUCCESS;
  551. ULONG Count;
  552. PCMCIA_READER_CONFIG *pConfig = NULL;
  553. ASSERT(DeviceObject != NULL);
  554. ASSERT(FullResourceDescriptor != NULL);
  555. SmartcardDebug(
  556. DEBUG_DRIVER,
  557. ("%s!GprStartDevice: Enter \n",
  558. SC_DRIVER_NAME)
  559. );
  560. // Get the number of resources we need
  561. Count = FullResourceDescriptor->PartialResourceList.Count;
  562. SmartcardDebug(
  563. DEBUG_DRIVER,
  564. ("%s!GprStartDevice: Resource Count = %d\n",
  565. SC_DRIVER_NAME,
  566. Count)
  567. );
  568. PartialDescriptor = FullResourceDescriptor->PartialResourceList.PartialDescriptors;
  569. pConfig = &(pReaderExt->ConfigData);
  570. //
  571. // parse all partial descriptors
  572. //
  573. while (Count--) {
  574. switch (PartialDescriptor->Type) {
  575. case CmResourceTypePort:
  576. {
  577. //
  578. // 0 - memory, 1 - IO
  579. //
  580. ULONG AddressSpace = 1;
  581. pReaderExt->BaseIoAddress =
  582. (PGPR400_REGISTERS) UlongToPtr(PartialDescriptor->u.Port.Start.LowPart);
  583. ASSERT(PartialDescriptor->u.Port.Length >= 4);
  584. SmartcardDebug(
  585. DEBUG_DRIVER,
  586. ("%s!GprStartDevice: IoBase = %lxh\n",
  587. SC_DRIVER_NAME,
  588. pReaderExt->BaseIoAddress)
  589. );
  590. break;
  591. }
  592. case CmResourceTypeInterrupt:
  593. {
  594. KINTERRUPT_MODE Mode;
  595. BOOLEAN Shared;
  596. Mode = (
  597. PartialDescriptor->Flags &
  598. CM_RESOURCE_INTERRUPT_LATCHED ?
  599. Latched : LevelSensitive
  600. );
  601. Shared = (
  602. PartialDescriptor->ShareDisposition ==
  603. CmResourceShareShared
  604. );
  605. pConfig->Vector = PartialDescriptor->u.Interrupt.Vector;
  606. pConfig->Affinity = PartialDescriptor->u.Interrupt.Affinity;
  607. pConfig->Level = (KIRQL) PartialDescriptor->u.Interrupt.Level;
  608. //
  609. // store IRQ to allow query configuration
  610. //
  611. SmartcardDebug(
  612. DEBUG_DRIVER,
  613. ("%s!GprStartDevice: Irq Vector: %d\n",
  614. SC_DRIVER_NAME,
  615. PartialDescriptor->u.Interrupt.Vector)
  616. );
  617. DeviceExtension->InterruptServiceRoutine = GprIsr;
  618. DeviceExtension->IsrContext = DeviceExtension;
  619. //
  620. //connect the driver's isr
  621. //
  622. NTStatus = IoConnectInterrupt(
  623. &DeviceExtension->InterruptObject,
  624. DeviceExtension->InterruptServiceRoutine,
  625. DeviceExtension->IsrContext,
  626. NULL,
  627. pConfig->Vector,
  628. pConfig->Level,
  629. pConfig->Level,
  630. Mode,
  631. Shared,
  632. pConfig->Affinity,
  633. FALSE
  634. );
  635. break;
  636. }
  637. default:
  638. NTStatus = STATUS_UNSUCCESSFUL;
  639. break;
  640. }
  641. PartialDescriptor++;
  642. }
  643. __try
  644. {
  645. //
  646. // IOBase initialized ?
  647. //
  648. if ( pReaderExt->BaseIoAddress == NULL ) {
  649. SmartcardDebug(
  650. DEBUG_DRIVER,
  651. ("%s!GprStartDevice: No IO \n",
  652. SC_DRIVER_NAME)
  653. );
  654. //
  655. // under NT 4.0 the failure of this fct for the second reader
  656. // means there is only one device
  657. //
  658. SmartcardLogError(
  659. DeviceObject,
  660. GEMSCR0D_ERROR_IO_PORT,
  661. NULL,
  662. 0
  663. );
  664. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  665. __leave;
  666. }
  667. //
  668. // irq connected ?
  669. //
  670. if ( DeviceExtension->InterruptObject == NULL ) {
  671. SmartcardDebug(
  672. DEBUG_DRIVER,
  673. ("%s!GprStartDevice: No Irq \n",
  674. SC_DRIVER_NAME)
  675. );
  676. SmartcardLogError(
  677. DeviceObject,
  678. GEMSCR0D_ERROR_INTERRUPT,
  679. NULL,
  680. 0
  681. );
  682. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  683. __leave;
  684. }
  685. // YN
  686. //
  687. // GPR400 Check Hardware
  688. //
  689. NTStatus = IfdCheck(pSCardExt);
  690. if (NTStatus != STATUS_SUCCESS) {
  691. SmartcardDebug(
  692. DEBUG_INFO,
  693. ("%s!GprStartDevice: ####### Reader is at bad state...\n",
  694. SC_DRIVER_NAME)
  695. );
  696. SmartcardLogError(
  697. DeviceObject,
  698. GEMSCR0D_UNABLE_TO_INITIALIZE,
  699. NULL,
  700. 0
  701. );
  702. // Unblock reader
  703. KeClearEvent(&pReaderExt->ReaderRemoved);
  704. KeSetEvent(&DeviceExtension->ReaderStarted, 0, FALSE);
  705. __leave;
  706. }
  707. // StartGpr in a worker thread.
  708. IoQueueWorkItem(
  709. DeviceExtension->GprWorkStartup,
  710. (PIO_WORKITEM_ROUTINE) GprWorkStartup,
  711. DelayedWorkQueue,
  712. NULL
  713. );
  714. //
  715. // Put interface here
  716. //
  717. NTStatus = IoSetDeviceInterfaceState(
  718. &DeviceExtension->PnPDeviceName,
  719. TRUE
  720. );
  721. }
  722. __finally
  723. {
  724. if (!NT_SUCCESS(NTStatus)) {
  725. DeviceExtension->OpenFlag = FALSE;
  726. GprStopDevice(DeviceObject);
  727. }
  728. SmartcardDebug(
  729. DEBUG_DRIVER,
  730. ("%s!GprStartDevice: Exit %X(hex)\n",
  731. SC_DRIVER_NAME,
  732. NTStatus)
  733. );
  734. }
  735. return NTStatus;
  736. }
  737. VOID GprStopDevice(
  738. PDEVICE_OBJECT DeviceObject
  739. )
  740. /*++
  741. Routine Description
  742. Disconnect the interrupt used by the device & unmap the IO port
  743. --*/
  744. {
  745. PDEVICE_EXTENSION DeviceExtension;
  746. PSMARTCARD_EXTENSION pSCardExt = NULL;
  747. ASSERT(DeviceObject != NULL);
  748. SmartcardDebug(
  749. DEBUG_DRIVER,
  750. ("%s!GprStopDevice: Enter \n",
  751. SC_DRIVER_NAME)
  752. );
  753. DeviceExtension = DeviceObject->DeviceExtension;
  754. pSCardExt = &(DeviceExtension->SmartcardExtension);
  755. //
  756. // disconnect the interrupt
  757. //
  758. if ( DeviceExtension->InterruptObject != NULL ) {
  759. IoDisconnectInterrupt(DeviceExtension->InterruptObject);
  760. DeviceExtension->InterruptObject = NULL;
  761. }
  762. SmartcardDebug(
  763. DEBUG_DRIVER,
  764. ("%s!GprStopDevice: Exit \n",
  765. SC_DRIVER_NAME)
  766. );
  767. }
  768. NTSTATUS
  769. GprSystemControl(
  770. IN PDEVICE_OBJECT DeviceObject,
  771. IN PIRP Irp
  772. )
  773. /*++
  774. Routine Description:
  775. Arguments:
  776. DeviceObject - Pointer to device object for this miniport
  777. Irp - IRP involved.
  778. Return Value:
  779. STATUS_SUCCESS.
  780. --*/
  781. {
  782. PDEVICE_EXTENSION DeviceExtension;
  783. PSMARTCARD_EXTENSION SmartcardExtension;
  784. PREADER_EXTENSION ReaderExtension;
  785. NTSTATUS status = STATUS_SUCCESS;
  786. DeviceExtension = DeviceObject->DeviceExtension;
  787. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  788. ReaderExtension = SmartcardExtension->ReaderExtension;
  789. IoSkipCurrentIrpStackLocation(Irp);
  790. status = IoCallDriver(ReaderExtension->AttachedDeviceObject, Irp);
  791. return status;
  792. }
  793. NTSTATUS GprDeviceControl(
  794. IN PDEVICE_OBJECT DeviceObject,
  795. IN PIRP Irp
  796. )
  797. /*++
  798. Routine description
  799. this is the IOCTL dispatch function
  800. --*/
  801. {
  802. PDEVICE_EXTENSION DeviceExtension = NULL;
  803. PSMARTCARD_EXTENSION SmartcardExtension = NULL;
  804. NTSTATUS NTStatus = STATUS_SUCCESS;
  805. LARGE_INTEGER Timeout;
  806. KIRQL irql;
  807. ASSERT(DeviceObject != NULL);
  808. ASSERT(Irp != NULL);
  809. DeviceExtension = DeviceObject->DeviceExtension;
  810. ASSERT(DeviceExtension != NULL);
  811. SmartcardExtension = &(DeviceExtension->SmartcardExtension);
  812. ASSERT(SmartcardExtension != NULL);
  813. SmartcardDebug(
  814. DEBUG_DRIVER,
  815. ("%s!GprDeviceControl: Enter\n",SC_DRIVER_NAME));
  816. KeAcquireSpinLock(&DeviceExtension->SpinLock,&irql);
  817. if (DeviceExtension->IoCount == 0) {
  818. KeReleaseSpinLock(&DeviceExtension->SpinLock,irql);
  819. NTStatus = KeWaitForSingleObject(
  820. &DeviceExtension->ReaderStarted,
  821. Executive,
  822. KernelMode,
  823. FALSE,
  824. NULL);
  825. ASSERT(NTStatus == STATUS_SUCCESS);
  826. KeAcquireSpinLock(&DeviceExtension->SpinLock,&irql);
  827. }
  828. ASSERT(DeviceExtension->IoCount >= 0);
  829. DeviceExtension->IoCount++;
  830. KeReleaseSpinLock(&DeviceExtension->SpinLock,irql);
  831. Timeout.QuadPart = 0;
  832. NTStatus = KeWaitForSingleObject(
  833. &(SmartcardExtension->ReaderExtension->ReaderRemoved),
  834. Executive,
  835. KernelMode,
  836. FALSE,
  837. &Timeout
  838. );
  839. if (NTStatus == STATUS_SUCCESS) {
  840. NTStatus = STATUS_DEVICE_REMOVED;
  841. } else {
  842. NTStatus = SmartcardAcquireRemoveLockWithTag(SmartcardExtension, 'tcoI');
  843. // Cancel the card detection timer
  844. KeCancelTimer(&(DeviceExtension->SmartcardExtension.ReaderExtension->CardDetectionTimer));
  845. AskForCardPresence(SmartcardExtension);
  846. Timeout.QuadPart = -(100 * POLLING_TIME);
  847. KeWaitForSingleObject(
  848. &(DeviceExtension->SmartcardExtension.ReaderExtension->GPRIccPresEvent),
  849. Executive,
  850. KernelMode,
  851. FALSE,
  852. &Timeout
  853. );
  854. }
  855. if (NTStatus != STATUS_SUCCESS) {
  856. // The device has been removed. Fail the call
  857. KeAcquireSpinLock(&DeviceExtension->SpinLock,&irql);
  858. DeviceExtension->IoCount--;
  859. KeReleaseSpinLock(&DeviceExtension->SpinLock,irql);
  860. Irp->IoStatus.Information = 0;
  861. Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
  862. NTStatus = STATUS_DEVICE_REMOVED;
  863. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  864. SmartcardDebug(
  865. DEBUG_DRIVER,
  866. ("%s!GprDeviceControl: Exit %x\n"
  867. ,SC_DRIVER_NAME
  868. ,NTStatus)
  869. );
  870. return(STATUS_DEVICE_REMOVED);
  871. }
  872. ASSERT(DeviceExtension->SmartcardExtension.ReaderExtension->ReaderPowerState ==
  873. PowerReaderWorking);
  874. NTStatus = SmartcardDeviceControl(
  875. &DeviceExtension->SmartcardExtension,
  876. Irp
  877. );
  878. // Restart the card detection timer
  879. Timeout.QuadPart = -(10000 * POLLING_TIME);
  880. KeSetTimer(
  881. &(SmartcardExtension->ReaderExtension->CardDetectionTimer),
  882. Timeout,
  883. &SmartcardExtension->ReaderExtension->CardDpcObject
  884. );
  885. //SmartcardReleaseRemoveLock(SmartcardExtension);
  886. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'tcoI');
  887. KeAcquireSpinLock(&DeviceExtension->SpinLock,&irql);
  888. DeviceExtension->IoCount--;
  889. ASSERT(DeviceExtension->IoCount >= 0);
  890. KeReleaseSpinLock(&DeviceExtension->SpinLock,irql);
  891. SmartcardDebug(
  892. DEBUG_DRIVER,
  893. ("%s!GprDeviceControl: Exit %x\n"
  894. ,SC_DRIVER_NAME
  895. ,NTStatus)
  896. );
  897. return(NTStatus);
  898. }
  899. VOID GprFinishPendingRequest(
  900. PDEVICE_OBJECT DeviceObject,
  901. NTSTATUS NTStatus
  902. )
  903. /*++
  904. Routine Description :
  905. finishes a pending tracking request if the interrupt is served or the device
  906. will be unloaded
  907. Arguments
  908. DeviceObject context of the request
  909. NTStatus status to report to the calling process
  910. Return Value
  911. STATUS_SUCCESS
  912. --*/
  913. {
  914. PDEVICE_EXTENSION DeviceExtension;
  915. PSMARTCARD_EXTENSION SmartcardExtension;
  916. KIRQL CurrentIrql;
  917. PIRP PendingIrp;
  918. ASSERT(DeviceObject != NULL);
  919. DeviceExtension = DeviceObject->DeviceExtension;
  920. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  921. if ( SmartcardExtension->OsData->NotificationIrp != NULL ) {
  922. SmartcardDebug(
  923. DEBUG_DRIVER,
  924. ( "%s!GprFinishPendingRequest: Completing Irp %lx\n",
  925. SC_DRIVER_NAME,
  926. SmartcardExtension->OsData->NotificationIrp)
  927. );
  928. PendingIrp = SmartcardExtension->OsData->NotificationIrp;
  929. IoAcquireCancelSpinLock( &CurrentIrql );
  930. IoSetCancelRoutine( PendingIrp, NULL );
  931. IoReleaseCancelSpinLock( CurrentIrql );
  932. //
  933. // finish the request
  934. //
  935. PendingIrp->IoStatus.Status = NTStatus;
  936. PendingIrp->IoStatus.Information = 0;
  937. IoCompleteRequest(PendingIrp, IO_NO_INCREMENT );
  938. //
  939. // reset the tracking context to enable tracking
  940. //
  941. SmartcardExtension->OsData->NotificationIrp = NULL;
  942. }
  943. }
  944. NTSTATUS GprCallPcmciaDriver(
  945. IN PDEVICE_OBJECT DeviceObject,
  946. IN PIRP Irp
  947. )
  948. /*++
  949. Routine Description :
  950. Send an Irp to the pcmcia driver and wait until the pcmcia driver has
  951. finished the request.
  952. To make sure that the pcmcia driver will not complete the Irp we first
  953. initialize an event and set our own completion routine for the Irp.
  954. When the pcmcia driver has processed the Irp the completion routine will
  955. set the event and tell the IO manager that more processing is required.
  956. By waiting for the event we make sure that we continue only if the pcmcia
  957. driver has processed the Irp completely.
  958. Arguments
  959. DeviceObject context of call
  960. Irp Irp to send to the pcmcia driver
  961. Return Value
  962. status returned by the pcmcia driver
  963. --*/
  964. {
  965. NTSTATUS NTStatus = STATUS_SUCCESS;
  966. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  967. KEVENT Event;
  968. ASSERT(DeviceObject != NULL);
  969. ASSERT(Irp != NULL);
  970. // Copy our stack location to the next.
  971. IoCopyCurrentIrpStackLocationToNext(Irp);
  972. //
  973. // initialize an event for process synchronization. the event is passed
  974. // to our completion routine and will be set if the pcmcia driver is done
  975. //
  976. KeInitializeEvent(
  977. &Event,
  978. NotificationEvent,
  979. FALSE
  980. );
  981. //
  982. // Our IoCompletionRoutine sets only our event
  983. //
  984. IoSetCompletionRoutine (
  985. Irp,
  986. GprComplete,
  987. &Event,
  988. TRUE,
  989. TRUE,
  990. TRUE
  991. );
  992. //
  993. // Call the pcmcia driver
  994. //
  995. if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_POWER) {
  996. NTStatus = PoCallDriver(
  997. DeviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject,
  998. Irp
  999. );
  1000. } else {
  1001. NTStatus = IoCallDriver(
  1002. DeviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject,
  1003. Irp
  1004. );
  1005. }
  1006. //
  1007. // Wait until the pcmcia driver has processed the Irp
  1008. //
  1009. if (NTStatus == STATUS_PENDING) {
  1010. NTStatus = KeWaitForSingleObject(
  1011. &Event,
  1012. Executive,
  1013. KernelMode,
  1014. FALSE,
  1015. NULL
  1016. );
  1017. if (NTStatus == STATUS_SUCCESS) {
  1018. NTStatus = Irp->IoStatus.Status;
  1019. }
  1020. }
  1021. SmartcardDebug(
  1022. DEBUG_DRIVER,
  1023. ("%s!GprCallPcmciaDriver: Exit %x\n",
  1024. SC_DRIVER_NAME,
  1025. NTStatus)
  1026. );
  1027. return NTStatus;
  1028. }
  1029. NTSTATUS GprComplete (
  1030. IN PDEVICE_OBJECT DeviceObject,
  1031. IN PIRP Irp,
  1032. IN PKEVENT Event
  1033. )
  1034. /*++
  1035. Routine Description:
  1036. Completion routine for an Irp sent to the pcmcia driver. The event will
  1037. be set to notify that the pcmcia driver is done. The routine will not
  1038. 'complete' the Irp, so the caller of GprCallPcmciaDriver can continue.
  1039. Arguments:
  1040. DeviceObject context of call
  1041. Irp Irp to complete
  1042. Event Used by GprCallPcmciaDriver for process synchronization
  1043. Return Value
  1044. STATUS_CANCELLED Irp was cancelled by the IO manager
  1045. STATUS_MORE_PROCESSING_REQUIRED Irp will be finished by caller of
  1046. GprCallPcmciaDriver
  1047. --*/
  1048. {
  1049. UNREFERENCED_PARAMETER (DeviceObject);
  1050. ASSERT(Irp != NULL);
  1051. ASSERT(Event != NULL);
  1052. if (Irp->Cancel) {
  1053. Irp->IoStatus.Status = STATUS_CANCELLED;
  1054. }
  1055. // else
  1056. // {
  1057. // Irp->IoStatus.Status = STATUS_MORE_PROCESSING_REQUIRED;
  1058. // }
  1059. KeSetEvent (Event, 0, FALSE);
  1060. return STATUS_MORE_PROCESSING_REQUIRED;
  1061. }
  1062. NTSTATUS GprDispatchPnp(
  1063. IN PDEVICE_OBJECT DeviceObject,
  1064. IN PIRP Irp
  1065. )
  1066. /*++
  1067. Routine Description
  1068. driver callback for pnp manager
  1069. Request: Action:
  1070. IRP_MN_START_DEVICE Notify the pcmcia driver about the new device
  1071. and start the device
  1072. IRP_MN_STOP_DEVICE Free all resources used by the device and tell
  1073. the pcmcia driver that the device was stopped
  1074. IRP_MN_QUERY_REMOVE_DEVICE If the device is opened (i.e. in use) an error will
  1075. be returned to prevent the PnP manager to stop
  1076. the driver
  1077. IRP_MN_CANCEL_REMOVE_DEVICE just notify that we can continue without any
  1078. restrictions
  1079. IRP_MN_REMOVE_DEVICE notify the pcmcia driver that the device was
  1080. removed, stop & unload the device
  1081. All other requests will be passed to the pcmcia driver to ensure correct processing.
  1082. Arguments:
  1083. Device Object context of call
  1084. Irp irp from the PnP manager
  1085. Return value
  1086. STATUS_SUCCESS
  1087. STATUS_UNSUCCESSFUL
  1088. status returned by pcmcia driver
  1089. --*/
  1090. {
  1091. NTSTATUS NTStatus = STATUS_SUCCESS;
  1092. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  1093. PSMARTCARD_EXTENSION smartcardExtension = NULL;
  1094. PIO_STACK_LOCATION IrpStack;
  1095. BOOLEAN deviceRemoved = FALSE, irpSkipped = FALSE;
  1096. KIRQL irql;
  1097. LARGE_INTEGER Timeout;
  1098. ASSERT(DeviceObject != NULL);
  1099. ASSERT(Irp != NULL);
  1100. SmartcardDebug(
  1101. DEBUG_DRIVER,
  1102. ("%s!GprDispatchPnp: Enter\n",
  1103. SC_DRIVER_NAME)
  1104. );
  1105. smartcardExtension = &(DeviceExtension->SmartcardExtension);
  1106. //NTStatus = SmartcardAcquireRemoveLock(smartcardExtension);
  1107. NTStatus = SmartcardAcquireRemoveLockWithTag(smartcardExtension, ' PnP');
  1108. ASSERT(NTStatus == STATUS_SUCCESS);
  1109. if (NTStatus != STATUS_SUCCESS) {
  1110. Irp->IoStatus.Information = 0;
  1111. Irp->IoStatus.Status = NTStatus;
  1112. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1113. return NTStatus;
  1114. }
  1115. // Irp->IoStatus.Information = 0;
  1116. IrpStack = IoGetCurrentIrpStackLocation(Irp);
  1117. Timeout.QuadPart = 0;
  1118. //
  1119. // Now look what the PnP manager wants...
  1120. //
  1121. switch (IrpStack->MinorFunction) {
  1122. case IRP_MN_START_DEVICE:
  1123. //
  1124. // Now we should connect to our resources (Irql, Io etc.)
  1125. //
  1126. SmartcardDebug(
  1127. DEBUG_DRIVER,
  1128. ("%s!GprDispatchPnp: IRP_MN_START_DEVICE\n",
  1129. SC_DRIVER_NAME)
  1130. );
  1131. //
  1132. // We have to call the underlying driver first
  1133. //
  1134. NTStatus = GprCallPcmciaDriver(
  1135. DeviceObject,
  1136. Irp
  1137. );
  1138. ASSERT(NT_SUCCESS(NTStatus));
  1139. if (NT_SUCCESS(NTStatus)) {
  1140. NTStatus = GprStartDevice(
  1141. DeviceObject,
  1142. &IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0]
  1143. );
  1144. }
  1145. break;
  1146. case IRP_MN_QUERY_STOP_DEVICE:
  1147. SmartcardDebug(
  1148. DEBUG_DRIVER,
  1149. ("%s!GprDispatchPnP: IRP_MN_QUERY_STOP_DEVICE\n",
  1150. SC_DRIVER_NAME)
  1151. );
  1152. KeAcquireSpinLock(&DeviceExtension->SpinLock, &irql);
  1153. if (DeviceExtension->IoCount > 0) {
  1154. // we refuse to stop if we have pending io
  1155. KeReleaseSpinLock(&DeviceExtension->SpinLock, irql);
  1156. NTStatus = STATUS_DEVICE_BUSY;
  1157. } else {
  1158. // stop processing requests
  1159. KeClearEvent(&DeviceExtension->ReaderStarted);
  1160. KeReleaseSpinLock(&DeviceExtension->SpinLock, irql);
  1161. NTStatus = GprCallPcmciaDriver(
  1162. DeviceObject,
  1163. Irp);
  1164. }
  1165. break;
  1166. case IRP_MN_CANCEL_STOP_DEVICE:
  1167. SmartcardDebug(
  1168. DEBUG_DRIVER,
  1169. ("%s!GprDispatchPnP: IRP_MN_CANCEL_STOP_DEVICE\n",
  1170. SC_DRIVER_NAME)
  1171. );
  1172. NTStatus = GprCallPcmciaDriver(
  1173. DeviceObject,
  1174. Irp
  1175. );
  1176. if (NTStatus == STATUS_SUCCESS) {
  1177. // we can continue to process requests
  1178. KeSetEvent(&DeviceExtension->ReaderStarted, 0, FALSE);
  1179. }
  1180. break;
  1181. case IRP_MN_STOP_DEVICE:
  1182. //
  1183. // Stop the device.
  1184. //
  1185. SmartcardDebug(
  1186. DEBUG_DRIVER,
  1187. ("%s!GprDispatchPnp: IRP_MN_STOP_DEVICE\n",
  1188. SC_DRIVER_NAME)
  1189. );
  1190. GprStopDevice(DeviceObject);
  1191. NTStatus = GprCallPcmciaDriver(DeviceObject, Irp);
  1192. break;
  1193. case IRP_MN_QUERY_REMOVE_DEVICE:
  1194. //
  1195. // Remove our device
  1196. //
  1197. SmartcardDebug(
  1198. DEBUG_DRIVER,
  1199. ("%s!GprDispatchPnp: IRP_MN_QUERY_REMOVE_DEVICE\n",
  1200. SC_DRIVER_NAME)
  1201. );
  1202. // disable the reader
  1203. NTStatus = IoSetDeviceInterfaceState(
  1204. &DeviceExtension->PnPDeviceName,
  1205. FALSE
  1206. );
  1207. SmartcardDebug(
  1208. DEBUG_TRACE,
  1209. ("%s!GprDispatchPnp: Set Pnp Interface state to FALSE, status=%x\n",
  1210. SC_DRIVER_NAME,
  1211. NTStatus)
  1212. );
  1213. if (NTStatus != STATUS_SUCCESS) {
  1214. break;
  1215. }
  1216. //
  1217. // check if the reader has been opened
  1218. // Note: This call only checks and does NOT wait for a close
  1219. //
  1220. Timeout.QuadPart = 0;
  1221. NTStatus = KeWaitForSingleObject(
  1222. &DeviceExtension->ReaderClosed,
  1223. Executive,
  1224. KernelMode,
  1225. FALSE,
  1226. &Timeout
  1227. );
  1228. if (NTStatus == STATUS_TIMEOUT) {
  1229. // someone is connected, enable the reader and fail the call
  1230. IoSetDeviceInterfaceState(
  1231. &DeviceExtension->PnPDeviceName,
  1232. TRUE
  1233. );
  1234. SmartcardDebug(
  1235. DEBUG_TRACE,
  1236. ("%s!GprDispatchPnp: Set Pnp Interface state to TRUE\n",
  1237. SC_DRIVER_NAME)
  1238. );
  1239. NTStatus = STATUS_UNSUCCESSFUL;
  1240. break;
  1241. }
  1242. // pass the call to the next driver in the stack
  1243. NTStatus = GprCallPcmciaDriver(DeviceObject, Irp);
  1244. break;
  1245. case IRP_MN_CANCEL_REMOVE_DEVICE:
  1246. //
  1247. // Removal of device has been cancelled
  1248. //
  1249. SmartcardDebug(
  1250. DEBUG_DRIVER,
  1251. ("%s!GprDispatchPnp: IRP_MN_CANCEL_REMOVE_DEVICE\n",
  1252. SC_DRIVER_NAME)
  1253. );
  1254. NTStatus = GprCallPcmciaDriver(DeviceObject, Irp);
  1255. if (NTStatus == STATUS_SUCCESS) {
  1256. NTStatus = IoSetDeviceInterfaceState(
  1257. &DeviceExtension->PnPDeviceName,
  1258. TRUE
  1259. );
  1260. SmartcardDebug(
  1261. DEBUG_TRACE,
  1262. ("%s!GprDispatchPnp: Set Pnp Interface state to TRUE, status=%s\n",
  1263. SC_DRIVER_NAME,
  1264. NTStatus)
  1265. );
  1266. }
  1267. break;
  1268. case IRP_MN_REMOVE_DEVICE:
  1269. //
  1270. // Remove our device
  1271. //
  1272. SmartcardDebug(
  1273. DEBUG_DRIVER,
  1274. ("%s!GprDispatchPnp: IRP_MN_REMOVE_DEVICE\n",
  1275. SC_DRIVER_NAME)
  1276. );
  1277. KeSetEvent(&(smartcardExtension->ReaderExtension->ReaderRemoved), 0, FALSE);
  1278. GprStopDevice(DeviceObject);
  1279. SmartcardDebug(
  1280. DEBUG_DRIVER,
  1281. ("%s!GprDispatchPnp: call pcmcia\n",
  1282. SC_DRIVER_NAME,
  1283. NTStatus)
  1284. );
  1285. NTStatus = GprCallPcmciaDriver(DeviceObject, Irp);
  1286. SmartcardDebug(
  1287. DEBUG_DRIVER,
  1288. ("%s!GprDispatchPnp: Finish with unload driver\n",
  1289. SC_DRIVER_NAME,
  1290. NTStatus)
  1291. );
  1292. GprUnloadDevice(DeviceObject);
  1293. deviceRemoved = TRUE;
  1294. break;
  1295. case IRP_MN_SURPRISE_REMOVAL:
  1296. //
  1297. // Unexpectedly removed our Reader
  1298. //
  1299. SmartcardDebug(
  1300. DEBUG_DRIVER,
  1301. ("%s!GprDispatchPnp: IRP_MN_SURPRISE_REMOVAL\n",
  1302. SC_DRIVER_NAME)
  1303. );
  1304. if ( DeviceExtension->InterruptObject != NULL ) {
  1305. IoDisconnectInterrupt(DeviceExtension->InterruptObject);
  1306. DeviceExtension->InterruptObject = NULL;
  1307. }
  1308. KeSetEvent(&(smartcardExtension->ReaderExtension->ReaderRemoved), 0, FALSE);
  1309. NTStatus = GprCallPcmciaDriver(DeviceObject, Irp);
  1310. break;
  1311. default:
  1312. // This might be an Irp that is only useful
  1313. // for the underlying bus driver
  1314. NTStatus = GprCallPcmciaDriver(DeviceObject, Irp);
  1315. irpSkipped = TRUE;
  1316. break;
  1317. }
  1318. if (!irpSkipped) {
  1319. Irp->IoStatus.Status = NTStatus;
  1320. }
  1321. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1322. if (deviceRemoved == FALSE) {
  1323. SmartcardReleaseRemoveLockWithTag(smartcardExtension, ' PnP');
  1324. }
  1325. SmartcardDebug(
  1326. DEBUG_DRIVER,
  1327. ("%s!GprDispatchPnp: Exit %x\n",
  1328. SC_DRIVER_NAME,
  1329. NTStatus)
  1330. );
  1331. return NTStatus;
  1332. }
  1333. BOOLEAN GprIsr(
  1334. IN PKINTERRUPT pkInterrupt,
  1335. IN PVOID pvContext
  1336. )
  1337. /*++
  1338. Routine Description
  1339. Interrupt Service routine called when an exchange has been processed by the GPR
  1340. --*/
  1341. {
  1342. PDEVICE_EXTENSION DeviceExtension = NULL;
  1343. ASSERT(pvContext != NULL);
  1344. DeviceExtension = (PDEVICE_EXTENSION) pvContext;
  1345. //
  1346. //Request a DPC which will complete the pending User I/O Request
  1347. //Packet (aka, IRP), if there is one.
  1348. //
  1349. KeInsertQueueDpc(
  1350. &DeviceExtension->DpcObject,
  1351. DeviceExtension,
  1352. &DeviceExtension->SmartcardExtension
  1353. );
  1354. return(TRUE);
  1355. }
  1356. NTSTATUS GprCleanup(
  1357. IN PDEVICE_OBJECT DeviceObject,
  1358. IN PIRP Irp
  1359. )
  1360. /*++
  1361. Routine Description:
  1362. This routine is called by the I/O system when the calling thread terminates
  1363. Arguments:
  1364. DeviceObject - Pointer to device object for this miniport
  1365. Irp - IRP involved.
  1366. Return Value:
  1367. STATUS_SUCCESS
  1368. --*/
  1369. {
  1370. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1371. PSMARTCARD_EXTENSION SmartcardExtension = &deviceExtension->SmartcardExtension;
  1372. NTSTATUS NTStatus = STATUS_SUCCESS;
  1373. ASSERT(DeviceObject != NULL);
  1374. ASSERT(Irp != NULL);
  1375. SmartcardDebug(
  1376. DEBUG_DRIVER,
  1377. ("%s!GprCleanUp: Enter\n",
  1378. SC_DRIVER_NAME)
  1379. );
  1380. IoAcquireCancelSpinLock(&(Irp->CancelIrql));
  1381. if (SmartcardExtension->OsData->NotificationIrp) {
  1382. // We need to complete the notification irp
  1383. IoSetCancelRoutine(
  1384. SmartcardExtension->OsData->NotificationIrp,
  1385. NULL
  1386. );
  1387. GprCancelEventWait(
  1388. DeviceObject,
  1389. SmartcardExtension->OsData->NotificationIrp
  1390. );
  1391. } else {
  1392. IoReleaseCancelSpinLock( Irp->CancelIrql );
  1393. }
  1394. SmartcardDebug(
  1395. DEBUG_DRIVER,
  1396. ("%s!GprCleanUp: Completing IRP %lx\n",
  1397. SC_DRIVER_NAME,
  1398. Irp)
  1399. );
  1400. Irp->IoStatus.Information = 0;
  1401. Irp->IoStatus.Status = STATUS_SUCCESS;
  1402. SmartcardDebug(
  1403. DEBUG_DRIVER,
  1404. ("%s!GprCleanUp: IoCompleteRequest\n",
  1405. SC_DRIVER_NAME)
  1406. );
  1407. IoCompleteRequest(
  1408. Irp,
  1409. IO_NO_INCREMENT
  1410. );
  1411. SmartcardDebug(
  1412. DEBUG_DRIVER,
  1413. ("%s!GprCleanUp: exit %x\n",
  1414. SC_DRIVER_NAME,
  1415. NTStatus)
  1416. );
  1417. return(NTStatus);
  1418. }
  1419. NTSTATUS GprCancelEventWait(
  1420. IN PDEVICE_OBJECT DeviceObject,
  1421. IN PIRP Irp
  1422. )
  1423. /*++
  1424. Routine Description:
  1425. This routine is called by the I/O system
  1426. when the irp should be cancelled
  1427. Arguments:
  1428. DeviceObject - Pointer to device object for this miniport
  1429. Irp - IRP involved.
  1430. Return Value:
  1431. STATUS_CANCELLED
  1432. --*/
  1433. {
  1434. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1435. PSMARTCARD_EXTENSION SmartcardExtension = &deviceExtension->SmartcardExtension;
  1436. SmartcardDebug(
  1437. DEBUG_DRIVER,
  1438. ("%s!GprCancelEventWait: Enter\n",
  1439. SC_DRIVER_NAME)
  1440. );
  1441. ASSERT(Irp == SmartcardExtension->OsData->NotificationIrp);
  1442. SmartcardExtension->OsData->NotificationIrp = NULL;
  1443. Irp->IoStatus.Information = 0;
  1444. Irp->IoStatus.Status = STATUS_CANCELLED;
  1445. IoReleaseCancelSpinLock(
  1446. Irp->CancelIrql
  1447. );
  1448. SmartcardDebug(
  1449. DEBUG_DRIVER,
  1450. ("%s!GprCancelEventWait: Request completed Irp = %lx\n",
  1451. SC_DRIVER_NAME,
  1452. Irp)
  1453. );
  1454. IoCompleteRequest(
  1455. Irp,
  1456. IO_NO_INCREMENT
  1457. );
  1458. SmartcardDebug(
  1459. DEBUG_DRIVER,
  1460. ("%s!GprCancelEventWait: Exit\n",
  1461. SC_DRIVER_NAME)
  1462. );
  1463. return STATUS_CANCELLED;
  1464. }
  1465. VOID GprCardEventDpc(
  1466. PKDPC Dpc,
  1467. PDEVICE_OBJECT DeviceObject,
  1468. PDEVICE_EXTENSION DeviceExtension,
  1469. PSMARTCARD_EXTENSION SmartcardExtension
  1470. )
  1471. /*++
  1472. Routine Description :
  1473. DPC routine for interrupts generated by the reader when a card is
  1474. inserted/removed. This routine is called only when there is a user
  1475. pending request on an insertion/removal IOCTL call. It will check
  1476. if the Irp exists and its not being cancelled, and it will then
  1477. complete it to signal the user event.
  1478. --*/
  1479. {
  1480. ULONG OldState;
  1481. ULONG NewState;
  1482. READER_EXTENSION *pReaderExt;
  1483. KIRQL irql;
  1484. ASSERT (DeviceExtension != NULL);
  1485. ASSERT (SmartcardExtension != NULL);
  1486. pReaderExt = SmartcardExtension->ReaderExtension;
  1487. ASSERT (pReaderExt != NULL);
  1488. // Read reader status response from the reader.
  1489. GprllReadResp(pReaderExt);
  1490. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  1491. &irql);
  1492. ASSERT(pReaderExt->Vo != NULL);
  1493. OldState = SmartcardExtension->ReaderCapabilities.CurrentState;
  1494. if ((pReaderExt->To==0xA2) && (pReaderExt->Lo==4)) {
  1495. //
  1496. // The TLV answer indicates the status of the card (inserted/removed)
  1497. //
  1498. if ( (pReaderExt->Vo[1] & 0x80) == 0x80) {
  1499. if (SmartcardExtension->ReaderCapabilities.CurrentState <3) {
  1500. NewState = SCARD_SWALLOWED;
  1501. } else {
  1502. NewState = SmartcardExtension->ReaderCapabilities.CurrentState;
  1503. }
  1504. } else {
  1505. NewState = SCARD_ABSENT;
  1506. }
  1507. // register this state
  1508. SmartcardExtension->ReaderCapabilities.CurrentState = NewState;
  1509. } else {
  1510. KeSetEvent(&(SmartcardExtension->ReaderExtension->GPRAckEvent),0,FALSE);
  1511. }
  1512. //
  1513. // If the caller was waiting on a IOCTL_SMARTCARD_IS_PRESENT or
  1514. // IOCTL_SMARTCARD_IS_ABSENT command, complete the request, but
  1515. // check first if its being cancelled!
  1516. //
  1517. if ( (OldState != SmartcardExtension->ReaderCapabilities.CurrentState)) {
  1518. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1519. irql);
  1520. GprFinishPendingRequest( DeviceObject, STATUS_SUCCESS );
  1521. } else {
  1522. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1523. irql);
  1524. }
  1525. }
  1526. VOID GprCardPresenceDpc(
  1527. IN PKDPC pDpc,
  1528. IN PVOID pvContext,
  1529. IN PVOID pArg1,
  1530. IN PVOID pArg2
  1531. )
  1532. /*++
  1533. Routine Description:
  1534. This is the DPC routine called by polling to detect the card insertion/removal
  1535. --*/
  1536. {
  1537. PDEVICE_EXTENSION pDevExt = NULL;
  1538. PSMARTCARD_EXTENSION SmartcardExtension = NULL;
  1539. LARGE_INTEGER Timeout;
  1540. NTSTATUS status;
  1541. UNREFERENCED_PARAMETER (pArg1);
  1542. UNREFERENCED_PARAMETER (pArg2);
  1543. pDevExt = (PDEVICE_EXTENSION) pvContext;
  1544. SmartcardExtension = &(pDevExt->SmartcardExtension);
  1545. // SmartcardDebug(DEBUG_DRIVER,("------ CARD PRESENCE DPC -> ENTER\n"));
  1546. // ISV
  1547. // If wait conditions can be satisfied - get hardware.
  1548. // Otherwise - just restart Timer to test it next time...
  1549. status = testForIdleAndBlock(SmartcardExtension->ReaderExtension);
  1550. if (NT_SUCCESS(status)) {
  1551. // Send TLV command, to know card state,
  1552. // We don't care about return status, we get the response
  1553. // from the Interrupt
  1554. // SmartcardDebug(DEBUG_DRIVER,("------ CARD PRESENCE DPC -> GOT ACCESS! status %x\n", status));
  1555. AskForCardPresence(SmartcardExtension);
  1556. // Release hardware
  1557. setIdle(SmartcardExtension->ReaderExtension);
  1558. }
  1559. if (!KeReadStateEvent(&(SmartcardExtension->ReaderExtension->ReaderRemoved))) {
  1560. // Restart the polling timer
  1561. Timeout.QuadPart = -(10000 * POLLING_TIME);
  1562. KeSetTimer(&(SmartcardExtension->ReaderExtension->CardDetectionTimer),
  1563. Timeout,
  1564. &SmartcardExtension->ReaderExtension->CardDpcObject
  1565. );
  1566. }
  1567. // SmartcardDebug(DEBUG_DRIVER,("------ CARD PRESENCE DPC -> EXIT\n"));
  1568. }
  1569. VOID GprUnloadDevice(
  1570. PDEVICE_OBJECT DeviceObject
  1571. )
  1572. /*++
  1573. Routine description
  1574. close connections to smclib.sys and the pcmcia driver, delete symbolic
  1575. link and mark the slot as unused.
  1576. Arguments
  1577. DeviceObject device to unload
  1578. --*/
  1579. {
  1580. PDEVICE_EXTENSION DeviceExtension;
  1581. PAGED_CODE();
  1582. ASSERT(DeviceObject != NULL);
  1583. if (DeviceObject == NULL) {
  1584. return;
  1585. }
  1586. SmartcardDebug(
  1587. DEBUG_DRIVER,
  1588. ("%s!GprUnloadDevice: Enter \n",
  1589. SC_DRIVER_NAME)
  1590. );
  1591. DeviceExtension = DeviceObject->DeviceExtension;
  1592. ASSERT(
  1593. DeviceExtension->SmartcardExtension.VendorAttr.UnitNo <
  1594. GPR_MAX_DEVICE
  1595. );
  1596. if (DeviceExtension->PnPDeviceName.Buffer != NULL) {
  1597. // disble our device so no one can open it
  1598. IoSetDeviceInterfaceState(
  1599. &DeviceExtension->PnPDeviceName,
  1600. FALSE
  1601. );
  1602. }
  1603. // Mark this slot as available
  1604. bDeviceSlot[DeviceExtension->SmartcardExtension.VendorAttr.UnitNo] = FALSE;
  1605. // report to the lib that the device will be unloaded
  1606. if (DeviceExtension->SmartcardExtension.OsData != NULL) {
  1607. // finish pending tracking requests
  1608. GprFinishPendingRequest(DeviceObject, STATUS_CANCELLED);
  1609. ASSERT(DeviceExtension->SmartcardExtension.OsData->NotificationIrp == NULL);
  1610. // Wait until we can safely unload the device
  1611. SmartcardReleaseRemoveLockAndWait(&DeviceExtension->SmartcardExtension);
  1612. }
  1613. if (DeviceExtension->SmartcardExtension.ReaderExtension != NULL) {
  1614. // Free under reader stuff
  1615. if (!KeReadStateTimer(&(DeviceExtension->SmartcardExtension.ReaderExtension->CardDetectionTimer))) {
  1616. // Prevent restarting timer by sync functions
  1617. KeCancelTimer(&(DeviceExtension->SmartcardExtension.ReaderExtension->CardDetectionTimer));
  1618. }
  1619. // Detach from the pcmcia driver
  1620. if (DeviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject) {
  1621. IoDetachDevice(
  1622. DeviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject
  1623. );
  1624. DeviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject = NULL;
  1625. }
  1626. // free output buffer
  1627. if (DeviceExtension->SmartcardExtension.ReaderExtension->Vo) {
  1628. ExFreePool(DeviceExtension->SmartcardExtension.ReaderExtension->Vo);
  1629. DeviceExtension->SmartcardExtension.ReaderExtension->Vo = NULL;
  1630. }
  1631. // free ReaderExtension structure
  1632. ExFreePool(DeviceExtension->SmartcardExtension.ReaderExtension);
  1633. DeviceExtension->SmartcardExtension.ReaderExtension = NULL;
  1634. }
  1635. if (DeviceExtension->GprWorkStartup != NULL) {
  1636. IoFreeWorkItem(DeviceExtension->GprWorkStartup);
  1637. DeviceExtension->GprWorkStartup = NULL;
  1638. }
  1639. if (DeviceExtension->SmartcardExtension.OsData != NULL) {
  1640. SmartcardExit(&DeviceExtension->SmartcardExtension);
  1641. }
  1642. if (DeviceExtension->PnPDeviceName.Buffer != NULL) {
  1643. RtlFreeUnicodeString(&DeviceExtension->PnPDeviceName);
  1644. DeviceExtension->PnPDeviceName.Buffer = NULL;
  1645. }
  1646. // delete the device object
  1647. IoDeleteDevice(DeviceObject);
  1648. SmartcardDebug(
  1649. DEBUG_DRIVER,
  1650. ("%s!GprUnloadDevice: Exit \n",
  1651. SC_DRIVER_NAME)
  1652. );
  1653. return;
  1654. }
  1655. VOID GprUnloadDriver(
  1656. PDRIVER_OBJECT DriverObject
  1657. )
  1658. /*++
  1659. Routine Description :
  1660. unloads all devices for a given driver object
  1661. Arguments
  1662. DriverObject context of driver
  1663. --*/
  1664. {
  1665. PAGED_CODE();
  1666. SmartcardDebug(
  1667. DEBUG_DRIVER,
  1668. ("%s!GprUnloadDriver\n",
  1669. SC_DRIVER_NAME)
  1670. );
  1671. }
  1672. NTSTATUS GprCreateClose(
  1673. PDEVICE_OBJECT DeviceObject,
  1674. PIRP Irp
  1675. )
  1676. /*++
  1677. Routine Description
  1678. Create / Close Device function
  1679. --*/
  1680. {
  1681. NTSTATUS NTStatus = STATUS_SUCCESS;
  1682. PDEVICE_EXTENSION DeviceExtension;
  1683. PSMARTCARD_EXTENSION SmartcardExtension;
  1684. PIO_STACK_LOCATION IrpStack;
  1685. LARGE_INTEGER Timeout;
  1686. DeviceExtension = DeviceObject->DeviceExtension;
  1687. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1688. IrpStack = IoGetCurrentIrpStackLocation( Irp );
  1689. // Initialize
  1690. Irp->IoStatus.Information = 0;
  1691. // dispatch major function
  1692. switch ( IrpStack->MajorFunction ) {
  1693. case IRP_MJ_CREATE:
  1694. SmartcardDebug(
  1695. DEBUG_DRIVER,
  1696. ("%s!GprCreateClose: OPEN DEVICE\n",
  1697. SC_DRIVER_NAME)
  1698. );
  1699. NTStatus = SmartcardAcquireRemoveLockWithTag(SmartcardExtension, 'lCrC');
  1700. if (NTStatus != STATUS_SUCCESS) {
  1701. NTStatus = STATUS_DEVICE_REMOVED;
  1702. } else {
  1703. Timeout.QuadPart = 0;
  1704. // test if the device has been opened already
  1705. NTStatus = KeWaitForSingleObject(
  1706. &DeviceExtension->ReaderClosed,
  1707. Executive,
  1708. KernelMode,
  1709. FALSE,
  1710. &Timeout
  1711. );
  1712. if (NTStatus == STATUS_SUCCESS) {
  1713. DeviceExtension->OpenFlag = TRUE;
  1714. SmartcardDebug(
  1715. DEBUG_DRIVER,
  1716. ("%s!GprCreateClose: Set Card Detection timer\n",
  1717. SC_DRIVER_NAME)
  1718. );
  1719. // start the detection timer
  1720. Timeout.QuadPart = -(10000 * POLLING_TIME);
  1721. KeSetTimer(
  1722. &(SmartcardExtension->ReaderExtension->CardDetectionTimer),
  1723. Timeout,
  1724. &SmartcardExtension->ReaderExtension->CardDpcObject
  1725. );
  1726. KeClearEvent(&DeviceExtension->ReaderClosed);
  1727. } else {
  1728. // the device is already in use
  1729. NTStatus = STATUS_UNSUCCESSFUL;
  1730. // release the lock
  1731. //SmartcardReleaseRemoveLock(SmartcardExtension);
  1732. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'lCrC');
  1733. }
  1734. }
  1735. SmartcardDebug(
  1736. DEBUG_DRIVER,
  1737. ("%s!GprCreateClose: OPEN DEVICE EXIT %x\n",
  1738. SC_DRIVER_NAME, NTStatus)
  1739. );
  1740. break;
  1741. case IRP_MJ_CLOSE:
  1742. SmartcardDebug(
  1743. DEBUG_DRIVER,
  1744. ("%s!GprCreateClose: CLOSE DEVICE\n",
  1745. SC_DRIVER_NAME)
  1746. );
  1747. // Cancel the card detection timer
  1748. //SmartcardReleaseRemoveLock(SmartcardExtension);
  1749. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'lCrC');
  1750. KeSetEvent(&DeviceExtension->ReaderClosed, 0, FALSE);
  1751. if (DeviceExtension->OpenFlag == TRUE) {
  1752. if (!KeReadStateTimer(&(DeviceExtension->SmartcardExtension.ReaderExtension->CardDetectionTimer))) {
  1753. SmartcardDebug(
  1754. DEBUG_DRIVER,
  1755. ("%s!GprCreateClose: Cancel Detection timer\n",
  1756. SC_DRIVER_NAME)
  1757. );
  1758. // Prevent restarting timer by sync functions
  1759. KeCancelTimer(&(DeviceExtension->SmartcardExtension.ReaderExtension->CardDetectionTimer));
  1760. }
  1761. DeviceExtension->OpenFlag = FALSE;
  1762. }
  1763. SmartcardDebug(
  1764. DEBUG_DRIVER,
  1765. ("%s!GprCreateClose: CLOSE DEVICE EXIT %x\n",
  1766. SC_DRIVER_NAME, NTStatus)
  1767. );
  1768. break;
  1769. default:
  1770. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  1771. SmartcardDebug(
  1772. DEBUG_DRIVER,
  1773. ("%s!GprCreateClose: Exit %x\n",
  1774. SC_DRIVER_NAME,
  1775. NTStatus)
  1776. );
  1777. break;
  1778. }
  1779. Irp->IoStatus.Status = NTStatus;
  1780. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1781. return NTStatus;
  1782. }
  1783. VOID GprWorkStartup(
  1784. IN PDEVICE_OBJECT DeviceObject,
  1785. IN PVOID Context
  1786. )
  1787. /*++
  1788. Routine Description:
  1789. This function start the GPR after the power completion is completed.
  1790. This function runs as a system thread at IRQL == PASSIVE_LEVEL.
  1791. --*/
  1792. {
  1793. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1794. PSMARTCARD_EXTENSION SmartcardExtension = &deviceExtension->SmartcardExtension;
  1795. LARGE_INTEGER Timeout;
  1796. NTSTATUS NTStatus;
  1797. USHORT i = 0;
  1798. KIRQL irql;
  1799. BOOLEAN ContinueLoop = TRUE;
  1800. UNREFERENCED_PARAMETER(Context);
  1801. SmartcardDebug(DEBUG_DRIVER,("------ WORK STARTUP -> ENTER\n"));
  1802. ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
  1803. // remove this call, use a work thread. Klaus!
  1804. //
  1805. // Reset the reader
  1806. //
  1807. waitForIdleAndBlock(SmartcardExtension->ReaderExtension);
  1808. while ( ContinueLoop ) {
  1809. NTStatus = IfdReset(SmartcardExtension);
  1810. i++;
  1811. if (NTStatus == STATUS_SUCCESS) {
  1812. ContinueLoop = FALSE;
  1813. } else if (i >= 3) {
  1814. ContinueLoop= FALSE;
  1815. } else if ( NTStatus == STATUS_DEVICE_REMOVED) {
  1816. ContinueLoop= FALSE;
  1817. }
  1818. }
  1819. SmartcardDebug(
  1820. DEBUG_DRIVER,
  1821. ("%s!GprWorkStartup: IfdReset Status: %x\n",
  1822. SC_DRIVER_NAME, NTStatus)
  1823. );
  1824. if (NTStatus != STATUS_SUCCESS) {
  1825. SmartcardLogError(
  1826. DeviceObject,
  1827. GEMSCR0D_UNABLE_TO_INITIALIZE,
  1828. NULL,
  1829. 0
  1830. );
  1831. // Advise that reader is ready for working
  1832. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  1833. if (SmartcardExtension->ReaderExtension->RestartCardDetection) {
  1834. SmartcardExtension->ReaderExtension->RestartCardDetection = FALSE;
  1835. // Restart the card detection timer
  1836. Timeout.QuadPart = -(10000 * POLLING_TIME);
  1837. KeSetTimer(
  1838. &(SmartcardExtension->ReaderExtension->CardDetectionTimer),
  1839. Timeout,
  1840. &SmartcardExtension->ReaderExtension->CardDpcObject
  1841. );
  1842. SmartcardDebug(DEBUG_DRIVER,(" CARD DETECTION RESTARTED!\n"));
  1843. }
  1844. setIdle(SmartcardExtension->ReaderExtension);
  1845. SmartcardDebug(DEBUG_DRIVER,("------ WORK STARTUP -> EXIT\n"));
  1846. return;
  1847. }
  1848. // Do appropriate stuff for resume of hibernate mode.
  1849. if ( SmartcardExtension->ReaderExtension->NewDevice == FALSE ) {
  1850. // Restart the card detection timer
  1851. Timeout.QuadPart = -(10000 * POLLING_TIME);
  1852. KeSetTimer(
  1853. &(SmartcardExtension->ReaderExtension->CardDetectionTimer),
  1854. Timeout,
  1855. &SmartcardExtension->ReaderExtension->CardDpcObject
  1856. );
  1857. // If a card was present before power down or now there is
  1858. // a card in the reader, we complete any pending card monitor
  1859. // request, since we do not really know what card is now in the
  1860. // reader.
  1861. //
  1862. KeAcquireSpinLock(&SmartcardExtension->OsData->SpinLock,
  1863. &irql);
  1864. if (SmartcardExtension->ReaderExtension->CardPresent ||
  1865. SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT) {
  1866. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1867. irql);
  1868. SmartcardDebug(
  1869. DEBUG_DRIVER,
  1870. ("%s!GprDevicePowerCompletion: GprFinishPendingRequest\n",
  1871. SC_DRIVER_NAME)
  1872. );
  1873. GprFinishPendingRequest(
  1874. DeviceObject,
  1875. STATUS_SUCCESS
  1876. );
  1877. } else {
  1878. KeReleaseSpinLock(&SmartcardExtension->OsData->SpinLock,
  1879. irql);
  1880. }
  1881. }
  1882. // Device initialization finish,
  1883. // NewDevice help to know it we are in hibernation mode or non
  1884. SmartcardExtension->ReaderExtension->NewDevice = FALSE;
  1885. // Advise that reader is ready for working
  1886. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  1887. if (SmartcardExtension->ReaderExtension->RestartCardDetection) {
  1888. SmartcardExtension->ReaderExtension->RestartCardDetection = FALSE;
  1889. // Restart the card detection timer
  1890. Timeout.QuadPart = -(10000 * POLLING_TIME);
  1891. KeSetTimer(
  1892. &(SmartcardExtension->ReaderExtension->CardDetectionTimer),
  1893. Timeout,
  1894. &SmartcardExtension->ReaderExtension->CardDpcObject
  1895. );
  1896. SmartcardDebug(DEBUG_DRIVER,(" CARD DETECTION RESTARTED!\n"));
  1897. }
  1898. setIdle(SmartcardExtension->ReaderExtension);
  1899. SmartcardDebug(DEBUG_DRIVER,("------ WORK STARTUP -> EXIT\n"));
  1900. }
  1901. // Functions to synchronize device execution
  1902. VOID setBusy(PREADER_EXTENSION Device)
  1903. {
  1904. KeClearEvent(&Device->IdleState);
  1905. SmartcardDebug(DEBUG_DRIVER,(" DEVICE BUSY\n"));
  1906. };
  1907. VOID setIdle(PREADER_EXTENSION Device)
  1908. {
  1909. LARGE_INTEGER Timeout;
  1910. KeSetEvent(&Device->IdleState,IO_NO_INCREMENT,FALSE);
  1911. SmartcardDebug(DEBUG_DRIVER,(" DEVICE IDLE\n"));
  1912. };
  1913. NTSTATUS waitForIdle(PREADER_EXTENSION Device)
  1914. {
  1915. NTSTATUS status;
  1916. ASSERT(KeGetCurrentIrql()<=DISPATCH_LEVEL);
  1917. status = KeWaitForSingleObject(&Device->IdleState, Executive,KernelMode, FALSE, NULL);
  1918. if (!NT_SUCCESS(status)) return STATUS_IO_TIMEOUT;
  1919. return STATUS_SUCCESS;
  1920. };
  1921. NTSTATUS waitForIdleAndBlock(PREADER_EXTENSION Device)
  1922. {
  1923. if (NT_SUCCESS(waitForIdle(Device))) {
  1924. setBusy(Device);
  1925. return STATUS_SUCCESS;
  1926. } else return STATUS_IO_TIMEOUT;
  1927. };
  1928. NTSTATUS testForIdleAndBlock(PREADER_EXTENSION Device)
  1929. {
  1930. ASSERT(KeGetCurrentIrql()<=DISPATCH_LEVEL);
  1931. if (KeReadStateEvent(&Device->IdleState)) {
  1932. setBusy(Device);
  1933. return STATUS_SUCCESS;
  1934. }
  1935. return STATUS_IO_TIMEOUT;
  1936. };
  1937. //-------------------------------------------------------------
  1938. NTSTATUS GprPower (
  1939. IN PDEVICE_OBJECT DeviceObject,
  1940. IN PIRP Irp
  1941. )
  1942. /*++
  1943. Routine Description:
  1944. The power dispatch routine.
  1945. This driver is the power policy owner of the device stack,
  1946. because this driver knows about the connected reader.
  1947. Therefor this driver will translate system power states
  1948. to device power states.
  1949. Arguments:
  1950. DeviceObject - pointer to a device object.
  1951. Irp - pointer to an I/O Request Packet.
  1952. Return Value:
  1953. NT status code
  1954. --*/
  1955. {
  1956. NTSTATUS status;
  1957. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  1958. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1959. PDEVICE_OBJECT AttachedDeviceObject = ATTACHED_DEVICE_OBJECT;
  1960. status = STATUS_SUCCESS;
  1961. SmartcardDebug(
  1962. DEBUG_ERROR,
  1963. ("%s!GprPower: Enter\n",
  1964. SC_DRIVER_NAME)
  1965. );
  1966. SmartcardDebug(
  1967. DEBUG_ERROR,
  1968. ("%s!GprPower: Irp = %lx\n",
  1969. SC_DRIVER_NAME,
  1970. Irp)
  1971. );
  1972. if (irpStack->MinorFunction == IRP_MN_QUERY_POWER)
  1973. status = power_HandleQueryPower(DeviceObject,Irp);
  1974. else if (irpStack->MinorFunction == IRP_MN_SET_POWER)
  1975. status = power_HandleSetPower(DeviceObject,Irp);
  1976. else {
  1977. SmartcardDebug(
  1978. DEBUG_ERROR,
  1979. ("%s!GprPower: **** Forwarding Power request down...\n",
  1980. SC_DRIVER_NAME)
  1981. );
  1982. // Default device does not do anything.
  1983. // So let's just transfer request to low level driver...
  1984. PoStartNextPowerIrp(Irp);// must be done while we own the IRP
  1985. IoSkipCurrentIrpStackLocation(Irp);
  1986. status = PoCallDriver(AttachedDeviceObject, Irp);
  1987. }
  1988. SmartcardDebug(
  1989. DEBUG_DRIVER,
  1990. ("%s!GprPower: Exit %lx\n",
  1991. SC_DRIVER_NAME,
  1992. status)
  1993. );
  1994. return status;
  1995. }
  1996. // Manages set power requests
  1997. NTSTATUS power_HandleSetPower(PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  1998. {
  1999. PIO_STACK_LOCATION irpStack;
  2000. NTSTATUS status = STATUS_SUCCESS;
  2001. POWER_STATE sysPowerState, desiredDevicePowerState;
  2002. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  2003. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  2004. PDEVICE_OBJECT AttachedDeviceObject = ATTACHED_DEVICE_OBJECT;
  2005. KIRQL irql;
  2006. if (!Irp) return STATUS_INVALID_PARAMETER;
  2007. irpStack = IoGetCurrentIrpStackLocation(Irp);
  2008. switch (irpStack->Parameters.Power.Type) {
  2009. case SystemPowerState:
  2010. // Get input system power state
  2011. sysPowerState.SystemState = irpStack->Parameters.Power.State.SystemState;
  2012. SmartcardDebug(
  2013. DEBUG_ERROR,
  2014. ("%s!power_HandleSetPower: PowerSystem S%d\n",
  2015. SC_DRIVER_NAME,
  2016. irpStack->Parameters.Power.State.SystemState - 1)
  2017. );
  2018. // If system is in working state always set our device to D0
  2019. // regardless of the wait state or system-to-device state power map
  2020. if ( sysPowerState.SystemState == PowerSystemWorking) {
  2021. desiredDevicePowerState.DeviceState = PowerDeviceD0;
  2022. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  2023. SmartcardDebug(
  2024. DEBUG_ERROR,
  2025. ("%s!power_HandleSetPower: PowerSystemWorking, Setting device power D0(ON)...\n",
  2026. SC_DRIVER_NAME)
  2027. );
  2028. } else {
  2029. //System reduces power, so do specific for device processing...
  2030. // if no wait pending and the system's not in working state, just turn off
  2031. desiredDevicePowerState.DeviceState = PowerDeviceD3;
  2032. SmartcardDebug(DEBUG_ERROR,
  2033. ("%s!power_HandleSetPower: Going Device Power D3(off)\n",
  2034. SC_DRIVER_NAME));
  2035. }
  2036. // We've determined the desired device state; are we already in this state?
  2037. if (smartcardExtension->ReaderExtension->ReaderPowerState != desiredDevicePowerState.DeviceState) {
  2038. SmartcardDebug(
  2039. DEBUG_ERROR,
  2040. ("%s!power_HandleSetPower: Requesting to set DevicePower D%d\n",
  2041. SC_DRIVER_NAME,
  2042. desiredDevicePowerState.DeviceState - 1));
  2043. // Callback will release the lock
  2044. status = SmartcardAcquireRemoveLockWithTag(smartcardExtension, 'rwoP');
  2045. IoMarkIrpPending(Irp);
  2046. // No, request that we be put into this state
  2047. // by requesting a new Power Irp from the Pnp manager
  2048. deviceExtension->PowerIrp = Irp;
  2049. status = PoRequestPowerIrp (DeviceObject,
  2050. IRP_MN_SET_POWER,
  2051. desiredDevicePowerState,
  2052. // completion routine will pass the Irp down to the PDO
  2053. (PREQUEST_POWER_COMPLETE)onPowerRequestCompletion,
  2054. DeviceObject, NULL);
  2055. } else { // Yes, just pass it on to PDO (Physical Device Object)
  2056. IoCopyCurrentIrpStackLocationToNext(Irp);
  2057. PoStartNextPowerIrp(Irp);
  2058. status = PoCallDriver(AttachedDeviceObject, Irp);
  2059. }
  2060. break;
  2061. case DevicePowerState:
  2062. SmartcardDebug(
  2063. DEBUG_ERROR,
  2064. ("%s!power_HandleSetPower: Setting Device Power D%d\n",
  2065. SC_DRIVER_NAME,
  2066. irpStack->Parameters.Power.State.DeviceState - 1));
  2067. // For requests to D1, D2, or D3 ( sleep or off states ),
  2068. // sets deviceExtension->CurrentDevicePowerState to DeviceState immediately.
  2069. // This enables any code checking state to consider us as sleeping or off
  2070. // already, as this will imminently become our state.
  2071. // For requests to DeviceState D0 ( fully on ), sets fGoingToD0 flag TRUE
  2072. // to flag that we must set a completion routine and update
  2073. // deviceExtension->CurrentDevicePowerState there.
  2074. // In the case of powering up to fully on, we really want to make sure
  2075. // the process is completed before updating our CurrentDevicePowerState,
  2076. // so no IO will be attempted or accepted before we're really ready.
  2077. if (irpStack->Parameters.Power.State.DeviceState==PowerDeviceD3) {
  2078. // save the current card state
  2079. KeAcquireSpinLock(&smartcardExtension->OsData->SpinLock,
  2080. &irql);
  2081. smartcardExtension->ReaderExtension->CardPresent =
  2082. smartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT;
  2083. if (smartcardExtension->ReaderExtension->CardPresent) {
  2084. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  2085. irql);
  2086. SmartcardDebug(
  2087. DEBUG_DRIVER,
  2088. ("%s!power_HandleSetPower: Power down card....\n",
  2089. SC_DRIVER_NAME));
  2090. smartcardExtension->MinorIoControlCode = SCARD_POWER_DOWN;
  2091. GprCbReaderPower(smartcardExtension);
  2092. } else {
  2093. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  2094. irql);
  2095. }
  2096. if (!KeReadStateTimer(&smartcardExtension->ReaderExtension->CardDetectionTimer)) {
  2097. SmartcardDebug(DEBUG_DRIVER,(" STOP CARD DETECTION!\n"));
  2098. smartcardExtension->ReaderExtension->RestartCardDetection = TRUE;
  2099. // Stop detection for during power events
  2100. KeCancelTimer(&smartcardExtension->ReaderExtension->CardDetectionTimer);
  2101. }
  2102. // If there is a pending card tracking request, setting
  2103. // this flag will prevent completion of the request
  2104. // when the system will be waked up again.
  2105. smartcardExtension->ReaderExtension->PowerRequest = TRUE;
  2106. desiredDevicePowerState.DeviceState = PowerDeviceD3;
  2107. PoSetPowerState(DeviceObject,DevicePowerState,desiredDevicePowerState);
  2108. // save the current power state of the reader
  2109. smartcardExtension->ReaderExtension->ReaderPowerState = PowerReaderOff;
  2110. // Forward Irp down...
  2111. IoCopyCurrentIrpStackLocationToNext(Irp);
  2112. PoStartNextPowerIrp(Irp);
  2113. } else {
  2114. status = SmartcardAcquireRemoveLockWithTag(smartcardExtension, 'rwoP');
  2115. SmartcardDebug(DEBUG_ERROR,
  2116. ("%s!power_HandleSetPower: Going to device power D0...\n",
  2117. SC_DRIVER_NAME));
  2118. IoCopyCurrentIrpStackLocationToNext(Irp);
  2119. IoSetCompletionRoutine(Irp,
  2120. onDevicePowerUpComplete,
  2121. // Always pass FDO to completion routine as its Context;
  2122. // This is because the DriverObject passed by the system to the routine
  2123. // is the Physical Device Object ( PDO ) not the Functional Device Object ( FDO )
  2124. DeviceObject,
  2125. TRUE, // invoke on success
  2126. TRUE, // invoke on error
  2127. TRUE); // invoke on cancellation of the Irp
  2128. }
  2129. status = PoCallDriver(AttachedDeviceObject, Irp);
  2130. break;
  2131. }
  2132. return status;
  2133. }
  2134. // Manages device power up
  2135. NTSTATUS onDevicePowerUpComplete(
  2136. IN PDEVICE_OBJECT NullDeviceObject,
  2137. IN PIRP Irp,
  2138. IN PVOID DeviceObject
  2139. )
  2140. {
  2141. NTSTATUS status = STATUS_SUCCESS;
  2142. PIO_STACK_LOCATION irpStack;
  2143. PDEVICE_EXTENSION deviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
  2144. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  2145. POWER_STATE desiredDevicePowerState;
  2146. SmartcardDebug(DEBUG_DRIVER,
  2147. ("%s!onDevicePowerUpComplete: Enter Device Power Up...\n",
  2148. SC_DRIVER_NAME));
  2149. // If the lower driver returned PENDING, mark our stack location as pending also.
  2150. if (Irp->PendingReturned) IoMarkIrpPending(Irp);
  2151. irpStack = IoGetCurrentIrpStackLocation (Irp);
  2152. // We can assert that we're a device powerup-to D0 request,
  2153. // because that was the only type of request we set a completion routine
  2154. // for in the first place
  2155. ASSERT(irpStack->MajorFunction == IRP_MJ_POWER);
  2156. ASSERT(irpStack->MinorFunction == IRP_MN_SET_POWER);
  2157. ASSERT(irpStack->Parameters.Power.Type==DevicePowerState);
  2158. ASSERT(irpStack->Parameters.Power.State.DeviceState==PowerDeviceD0);
  2159. // We've got power up request, so...
  2160. // Report everybody that reader is powered up again!
  2161. smartcardExtension->ReaderExtension->ReaderPowerState = PowerReaderWorking;
  2162. // GPR400 Check Hardware
  2163. if (NT_SUCCESS(IfdCheck(smartcardExtension))) {
  2164. // StartGpr in a worker thread.
  2165. IoQueueWorkItem(
  2166. deviceExtension->GprWorkStartup,
  2167. (PIO_WORKITEM_ROUTINE) GprWorkStartup,
  2168. DelayedWorkQueue,
  2169. NULL);
  2170. } else {
  2171. SmartcardDebug(
  2172. DEBUG_ERROR,
  2173. ("%s!GprDevicePowerCompletion: Reader is in Bad State\n",
  2174. SC_DRIVER_NAME)
  2175. );
  2176. }
  2177. smartcardExtension->ReaderExtension->PowerRequest = FALSE;
  2178. // Now that we know we've let the lower drivers do what was needed to power up,
  2179. // we can set our device extension flags accordingly
  2180. SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
  2181. // Report our state to Power manager...
  2182. desiredDevicePowerState.DeviceState = PowerDeviceD0;
  2183. PoSetPowerState(DeviceObject,DevicePowerState,desiredDevicePowerState);
  2184. PoStartNextPowerIrp(Irp);
  2185. SmartcardDebug(DEBUG_DRIVER,
  2186. ("%s!onDevicePowerUpComplete: Exit for the device state D0...\n",
  2187. SC_DRIVER_NAME));
  2188. return status;
  2189. }
  2190. // Manages system power transitions
  2191. NTSTATUS onPowerRequestCompletion(
  2192. IN PDEVICE_OBJECT NullDeviceObject,
  2193. IN UCHAR MinorFunction,
  2194. IN POWER_STATE PowerState,
  2195. IN PVOID DeviceObject,
  2196. IN PIO_STATUS_BLOCK IoStatus
  2197. )
  2198. {
  2199. NTSTATUS status = STATUS_SUCCESS;
  2200. PDEVICE_EXTENSION deviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
  2201. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  2202. PDEVICE_OBJECT AttachedDeviceObject = ATTACHED_DEVICE_OBJECT;
  2203. PIRP Irp;
  2204. SmartcardDebug(DEBUG_DRIVER,
  2205. ("%s!onPowerRequestCompletion: Enter...\n",
  2206. SC_DRIVER_NAME));
  2207. // Get the Irp we saved for later processing in BulkUsb_ProcessPowerIrp()
  2208. // when we decided to request the Power Irp that this routine
  2209. // is the completion routine for.
  2210. Irp = deviceExtension->PowerIrp;
  2211. // We will return the status set by the PDO for the power request we're completing
  2212. status = IoStatus->Status;
  2213. smartcardExtension->ReaderExtension->ReaderPowerState = PowerState.DeviceState;
  2214. // we must pass down to the next driver in the stack
  2215. IoCopyCurrentIrpStackLocationToNext(Irp);
  2216. // Calling PoStartNextPowerIrp() indicates that the driver is finished
  2217. // with the previous power IRP, if any, and is ready to handle the next power IRP.
  2218. // It must be called for every power IRP.Although power IRPs are completed only once,
  2219. // typically by the lowest-level driver for a device, PoStartNextPowerIrp must be called
  2220. // for every stack location. Drivers must call PoStartNextPowerIrp while the current IRP
  2221. // stack location points to the current driver. Therefore, this routine must be called
  2222. // before IoCompleteRequest, IoSkipCurrentStackLocation, and PoCallDriver.
  2223. PoStartNextPowerIrp(Irp);
  2224. // PoCallDriver is used to pass any power IRPs to the PDO instead of IoCallDriver.
  2225. // When passing a power IRP down to a lower-level driver, the caller should use
  2226. // IoSkipCurrentIrpStackLocation or IoCopyCurrentIrpStackLocationToNext to copy the IRP to
  2227. // the next stack location, then call PoCallDriver. Use IoCopyCurrentIrpStackLocationToNext
  2228. // if processing the IRP requires setting a completion routine, or IoSkipCurrentStackLocation
  2229. // if no completion routine is needed.
  2230. PoCallDriver(AttachedDeviceObject,Irp);
  2231. deviceExtension->PowerIrp = NULL;
  2232. SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
  2233. SmartcardDebug(DEBUG_DRIVER,
  2234. ("%s!onPowerRequestCompletion: Exit...\n",
  2235. SC_DRIVER_NAME));
  2236. return status;
  2237. }
  2238. NTSTATUS power_HandleQueryPower(PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  2239. {
  2240. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  2241. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  2242. PDEVICE_OBJECT AttachedDeviceObject = ATTACHED_DEVICE_OBJECT;
  2243. NTSTATUS status = STATUS_SUCCESS;
  2244. KIRQL irql;
  2245. SmartcardDebug(
  2246. DEBUG_ERROR,
  2247. ("%s!power_HandleQueryPower: Enter QueryPower...\n",
  2248. SC_DRIVER_NAME));
  2249. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  2250. if (deviceExtension->IoCount != 0)
  2251. { // can't go to sleep mode since the reader is busy.
  2252. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  2253. status = Irp->IoStatus.Status = STATUS_DEVICE_BUSY;
  2254. Irp->IoStatus.Information = 0;
  2255. PoStartNextPowerIrp(Irp);
  2256. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  2257. return status;
  2258. }
  2259. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  2260. // Block any further ioctls
  2261. KeClearEvent(&deviceExtension->ReaderStarted);
  2262. SmartcardDebug(DEBUG_DRIVER,
  2263. ("%s!power_HandleQueryPower: Reader BLOCKED!!!!!!!...\n",
  2264. SC_DRIVER_NAME));
  2265. Irp->IoStatus.Status = STATUS_SUCCESS;
  2266. PoStartNextPowerIrp(Irp);
  2267. IoSkipCurrentIrpStackLocation(Irp);
  2268. status = PoCallDriver(AttachedDeviceObject, Irp);
  2269. return status;
  2270. }