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

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