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.

2524 lines
65 KiB

  1. /*++
  2. Copyright (C) 1997, 98 Microsoft Corporation
  3. Module Name:
  4. bulltlp3.c
  5. Abstract:
  6. Smart card driver for Bull TLP3 reader
  7. Author:
  8. Klaus U. Schutz
  9. Environment:
  10. Kernel mode
  11. Revision History :
  12. Nov. 1997 - 1.0 Release
  13. Jan. 1998 - Fix for vendor defined IOCTLs
  14. TLP3SerialIo now writes the whole data packet if GT is 0
  15. Support for higher data rates added
  16. Feb. 1998 - PnP version
  17. --*/
  18. #include <stdio.h>
  19. #include "bulltlp3.h"
  20. #pragma alloc_text(INIT, DriverEntry)
  21. #pragma alloc_text(PAGEABLE, TLP3CreateAndStartDevice)
  22. #pragma alloc_text(PAGEABLE, TLP3StartSerialEventTracking)
  23. #pragma alloc_text(PAGEABLE, TLP3AddDevice)
  24. #pragma alloc_text(PAGEABLE, TLP3CreateDevice)
  25. #pragma alloc_text(PAGEABLE, TLP3RemoveDevice)
  26. #pragma alloc_text(PAGEABLE, TLP3DriverUnload)
  27. #if DBG
  28. #pragma optimize ("", off)
  29. #endif
  30. #ifdef SIMULATION
  31. PWSTR DriverKey;
  32. #endif
  33. NTSTATUS
  34. DriverEntry(
  35. IN PDRIVER_OBJECT DriverObject,
  36. IN PUNICODE_STRING RegistryPath
  37. )
  38. /*++
  39. Routine Description:
  40. This routine is called at system initialization time to initialize
  41. this driver.
  42. Arguments:
  43. DriverObject - Supplies the driver object.
  44. RegistryPath - Supplies the registry path for this driver.
  45. Return Value:
  46. STATUS_SUCCESS - We could initialize at least one device.
  47. STATUS_NO_SUCH_DEVICE - We could not initialize even one device.
  48. --*/
  49. {
  50. NTSTATUS status = STATUS_SUCCESS;
  51. ULONG device;
  52. SmartcardDebug(
  53. DEBUG_INFO,
  54. ("%s!DriverEntry: Enter - %s %s\n",
  55. DRIVER_NAME,
  56. __DATE__,
  57. __TIME__)
  58. )
  59. //
  60. // we do some stuff in this driver that
  61. // assumes a single digit port number
  62. //
  63. ASSERT(MAXIMUM_SERIAL_READERS < 10);
  64. // Initialize the Driver Object with driver's entry points
  65. DriverObject->DriverUnload = TLP3DriverUnload;
  66. DriverObject->MajorFunction[IRP_MJ_CREATE] = TLP3CreateClose;
  67. DriverObject->MajorFunction[IRP_MJ_CLOSE] = TLP3CreateClose;
  68. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TLP3Cleanup;
  69. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TLP3DeviceControl;
  70. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = TLP3SystemControl;
  71. DriverObject->MajorFunction[IRP_MJ_PNP] = TLP3PnP;
  72. DriverObject->MajorFunction[IRP_MJ_POWER] = TLP3Power;
  73. DriverObject->DriverExtension->AddDevice = TLP3AddDevice;
  74. #ifdef SIMULATION
  75. DriverKey = ExAllocatePool(PagedPool, RegistryPath->Length + sizeof(L""));
  76. if (DriverKey) {
  77. RtlZeroMemory(
  78. DriverKey,
  79. RegistryPath->Length + sizeof(L"")
  80. );
  81. RtlCopyMemory(
  82. DriverKey,
  83. RegistryPath->Buffer,
  84. RegistryPath->Length
  85. );
  86. }
  87. #endif
  88. return status;
  89. }
  90. NTSTATUS
  91. TLP3AddDevice(
  92. IN PDRIVER_OBJECT DriverObject,
  93. IN PDEVICE_OBJECT PhysicalDeviceObject
  94. )
  95. /*++
  96. Routine Description:
  97. This routine creates an object for the physical device specified and
  98. sets up the deviceExtension.
  99. --*/
  100. {
  101. PDEVICE_EXTENSION deviceExtension;
  102. NTSTATUS status = STATUS_SUCCESS;
  103. PREADER_EXTENSION readerExtension;
  104. PSMARTCARD_EXTENSION smartcardExtension;
  105. ULONG deviceInstance;
  106. HANDLE regKey = NULL;
  107. PDEVICE_OBJECT DeviceObject = NULL;
  108. // this is a list of our supported data rates
  109. static ULONG dataRatesSupported[] = { 9600, 19200, 38400, 57600, 115200 };
  110. SmartcardDebug(
  111. DEBUG_TRACE,
  112. ( "%s!TLP3AddDevice: Enter\n",
  113. DRIVER_NAME)
  114. );
  115. PAGED_CODE();
  116. __try {
  117. // Create the device object
  118. status = IoCreateDevice(
  119. DriverObject,
  120. sizeof(DEVICE_EXTENSION),
  121. NULL,
  122. FILE_DEVICE_SMARTCARD,
  123. 0,
  124. TRUE,
  125. &DeviceObject
  126. );
  127. if (status != STATUS_SUCCESS) {
  128. SmartcardLogError(
  129. DriverObject,
  130. TLP3_CANT_CREATE_DEVICE,
  131. NULL,
  132. 0
  133. );
  134. __leave;
  135. }
  136. SmartcardDebug(
  137. DEBUG_TRACE,
  138. ( "%s!TLP3CreateDevice: Device created\n",
  139. DRIVER_NAME)
  140. );
  141. // set up the device extension.
  142. deviceExtension = DeviceObject->DeviceExtension;
  143. smartcardExtension = &deviceExtension->SmartcardExtension;
  144. deviceExtension->CloseSerial = IoAllocateWorkItem(
  145. DeviceObject
  146. );
  147. // Used for stop / start notification
  148. KeInitializeEvent(
  149. &deviceExtension->ReaderStarted,
  150. NotificationEvent,
  151. FALSE
  152. );
  153. // Used to keep track of open close calls
  154. deviceExtension->ReaderOpen = FALSE;
  155. KeInitializeSpinLock(&deviceExtension->SpinLock);
  156. // Allocate data struct space for smart card reader
  157. smartcardExtension->ReaderExtension = ExAllocatePool(
  158. NonPagedPool,
  159. sizeof(READER_EXTENSION)
  160. );
  161. if (smartcardExtension->ReaderExtension == NULL) {
  162. SmartcardLogError(
  163. DriverObject,
  164. TLP3_NO_MEMORY,
  165. NULL,
  166. 0
  167. );
  168. status = STATUS_INSUFFICIENT_RESOURCES;
  169. __leave;
  170. }
  171. readerExtension = smartcardExtension->ReaderExtension;
  172. RtlZeroMemory(readerExtension, sizeof(READER_EXTENSION));
  173. // Write the version of the lib we use to the smartcard extension
  174. smartcardExtension->Version = SMCLIB_VERSION;
  175. smartcardExtension->SmartcardRequest.BufferSize =
  176. smartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
  177. //
  178. // Now let the lib allocate the buffer for data transmission
  179. // We can either tell the lib how big the buffer should be
  180. // by assigning a value to BufferSize or let the lib
  181. // allocate the default size
  182. //
  183. status = SmartcardInitialize(smartcardExtension);
  184. if (status != STATUS_SUCCESS) {
  185. SmartcardLogError(
  186. DriverObject,
  187. (smartcardExtension->OsData ? TLP3_WRONG_LIB_VERSION : TLP3_NO_MEMORY),
  188. NULL,
  189. 0
  190. );
  191. __leave;
  192. }
  193. // Save deviceObject
  194. smartcardExtension->OsData->DeviceObject = DeviceObject;
  195. // Set up call back functions
  196. smartcardExtension->ReaderFunction[RDF_TRANSMIT] = TLP3Transmit;
  197. smartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = TLP3SetProtocol;
  198. smartcardExtension->ReaderFunction[RDF_CARD_POWER] = TLP3ReaderPower;
  199. smartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = TLP3CardTracking;
  200. smartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = TLP3VendorIoctl;
  201. // This event signals that the serial driver has been closed
  202. KeInitializeEvent(
  203. &READER_EXTENSION_L(SerialCloseDone),
  204. NotificationEvent,
  205. TRUE
  206. );
  207. //
  208. // Set the vendor information
  209. //
  210. strcpy(smartcardExtension->VendorAttr.VendorName.Buffer, "Bull");
  211. smartcardExtension->VendorAttr.VendorName.Length =
  212. (USHORT) strlen(deviceExtension->SmartcardExtension.VendorAttr.VendorName.Buffer);
  213. strcpy(smartcardExtension->VendorAttr.IfdType.Buffer, "SmarTLP");
  214. smartcardExtension->VendorAttr.IfdType.Length =
  215. (USHORT) strlen(smartcardExtension->VendorAttr.IfdType.Buffer);
  216. smartcardExtension->VendorAttr.UnitNo = MAXULONG;
  217. for (deviceInstance = 0; deviceInstance < MAXULONG; deviceInstance++) {
  218. PDEVICE_OBJECT devObj;
  219. for (devObj = DeviceObject;
  220. devObj != NULL;
  221. devObj = devObj->NextDevice) {
  222. PDEVICE_EXTENSION devExt = devObj->DeviceExtension;
  223. PSMARTCARD_EXTENSION smcExt = &devExt->SmartcardExtension;
  224. if (deviceInstance == smcExt->VendorAttr.UnitNo) {
  225. break;
  226. }
  227. }
  228. if (devObj == NULL) {
  229. smartcardExtension->VendorAttr.UnitNo = deviceInstance;
  230. break;
  231. }
  232. }
  233. //
  234. // Set the reader capabilities
  235. //
  236. // Clk frequency in KHz encoded as little endian integer
  237. smartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3571;
  238. smartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3571;
  239. smartcardExtension->ReaderCapabilities.DataRate.Default =
  240. smartcardExtension->ReaderCapabilities.DataRate.Max =
  241. dataRatesSupported[0];
  242. // reader could support higher data rates
  243. smartcardExtension->ReaderCapabilities.DataRatesSupported.List =
  244. dataRatesSupported;
  245. smartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
  246. sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
  247. smartcardExtension->ReaderCapabilities.MaxIFSD = 254;
  248. // Now setup information in our deviceExtension
  249. smartcardExtension->ReaderCapabilities.CurrentState =
  250. (ULONG) SCARD_UNKNOWN;
  251. // This reader supports T=0 and T=1
  252. smartcardExtension->ReaderCapabilities.SupportedProtocols =
  253. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  254. smartcardExtension->ReaderCapabilities.MechProperties = 0;
  255. //
  256. // Set serial configuration parameters
  257. //
  258. readerExtension->SerialConfigData.BaudRate.BaudRate = 9600;
  259. readerExtension->SerialConfigData.LineControl.StopBits =
  260. STOP_BITS_2;
  261. readerExtension->SerialConfigData.LineControl.Parity =
  262. EVEN_PARITY;
  263. readerExtension->SerialConfigData.LineControl.WordLength =
  264. SERIAL_DATABITS_8;
  265. // set timeouts
  266. readerExtension->SerialConfigData.Timeouts.ReadIntervalTimeout =
  267. READ_INTERVAL_TIMEOUT_DEFAULT;
  268. readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant =
  269. READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;
  270. readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier = 0;
  271. // set special characters
  272. readerExtension->SerialConfigData.SerialChars.ErrorChar = 0;
  273. readerExtension->SerialConfigData.SerialChars.EofChar = 0;
  274. readerExtension->SerialConfigData.SerialChars.EventChar = 0;
  275. readerExtension->SerialConfigData.SerialChars.XonChar = 0;
  276. readerExtension->SerialConfigData.SerialChars.XoffChar = 0;
  277. readerExtension->SerialConfigData.SerialChars.BreakChar = 0xFF;
  278. // Set handflow
  279. readerExtension->SerialConfigData.HandFlow.XonLimit = 0;
  280. readerExtension->SerialConfigData.HandFlow.XoffLimit = 0;
  281. readerExtension->SerialConfigData.HandFlow.ControlHandShake = 0;
  282. readerExtension->SerialConfigData.HandFlow.FlowReplace =
  283. SERIAL_XOFF_CONTINUE;
  284. #if defined (DEBUG) && defined (DETECT_SERIAL_OVERRUNS)
  285. readerExtension->SerialConfigData.HandFlow.ControlHandShake =
  286. SERIAL_ERROR_ABORT;
  287. #endif
  288. // save the current power state of the reader
  289. readerExtension->ReaderPowerState = PowerReaderWorking;
  290. // and attach to the PDO
  291. ATTACHED_DEVICE_OBJECT =
  292. IoAttachDeviceToDeviceStack(
  293. DeviceObject,
  294. PhysicalDeviceObject
  295. );
  296. ASSERT(ATTACHED_DEVICE_OBJECT != NULL);
  297. if (ATTACHED_DEVICE_OBJECT == NULL) {
  298. SmartcardLogError(
  299. DriverObject,
  300. TLP3_CANT_CONNECT_TO_ASSIGNED_PORT,
  301. NULL,
  302. status
  303. );
  304. status = STATUS_UNSUCCESSFUL;
  305. __leave;
  306. }
  307. // register our new device
  308. status = IoRegisterDeviceInterface(
  309. PhysicalDeviceObject,
  310. &SmartCardReaderGuid,
  311. NULL,
  312. &deviceExtension->PnPDeviceName
  313. );
  314. ASSERT(status == STATUS_SUCCESS);
  315. DeviceObject->Flags |= DO_BUFFERED_IO;
  316. DeviceObject->Flags |= DO_POWER_PAGABLE;
  317. DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  318. }
  319. __finally {
  320. if (regKey) {
  321. ZwClose(regKey);
  322. }
  323. if (status != STATUS_SUCCESS) {
  324. TLP3RemoveDevice(DeviceObject);
  325. }
  326. SmartcardDebug(
  327. DEBUG_TRACE,
  328. ( "%s!TLP3AddDevice: Exit %x\n",
  329. DRIVER_NAME,
  330. status)
  331. );
  332. }
  333. return status;
  334. }
  335. NTSTATUS
  336. TLP3StartDevice(
  337. IN PDEVICE_OBJECT DeviceObject
  338. )
  339. /*++
  340. Routine Description:
  341. Open the serial device, start card tracking and register our
  342. device interface. If any of the calls here fails we don't care
  343. to rollback since a stop will be called later which we then
  344. use to clean up.
  345. --*/
  346. {
  347. NTSTATUS status;
  348. PIRP irp;
  349. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  350. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  351. SmartcardDebug(
  352. DEBUG_TRACE,
  353. ( "%s!TLP3StartDevice: Enter\n",
  354. DRIVER_NAME)
  355. );
  356. irp = IoAllocateIrp(
  357. (CCHAR) (DeviceObject->StackSize + 1),
  358. FALSE
  359. );
  360. ASSERT(irp != NULL);
  361. if (irp == NULL) {
  362. return STATUS_NO_MEMORY;
  363. }
  364. _try {
  365. PIO_STACK_LOCATION irpStack;
  366. HANDLE handle = 0;
  367. IO_STATUS_BLOCK ioStatusBlock;
  368. //
  369. // Open the underlying serial driver.
  370. // This is necessary for two reasons:
  371. // a) The serial driver can't be used without opening it
  372. // b) The call will go through serenum first which informs
  373. // it to stop looking/polling for new devices.
  374. //
  375. irp->UserIosb = &ioStatusBlock;
  376. IoSetNextIrpStackLocation(irp);
  377. irpStack = IoGetCurrentIrpStackLocation(irp);
  378. irpStack->MajorFunction = IRP_MJ_CREATE;
  379. irpStack->Parameters.Create.Options = 0;
  380. irpStack->Parameters.Create.ShareAccess = 0;
  381. irpStack->Parameters.Create.FileAttributes = 0;
  382. irpStack->Parameters.Create.EaLength = 0;
  383. status = TLP3CallSerialDriver(
  384. ATTACHED_DEVICE_OBJECT,
  385. irp
  386. );
  387. if (status != STATUS_SUCCESS) {
  388. leave;
  389. }
  390. KeClearEvent(&READER_EXTENSION_L(SerialCloseDone));
  391. status = TLP3ConfigureSerialPort(&deviceExtension->SmartcardExtension);
  392. if (status != STATUS_SUCCESS) {
  393. leave;
  394. }
  395. status = TLP3StartSerialEventTracking(
  396. &deviceExtension->SmartcardExtension
  397. );
  398. if (status != STATUS_SUCCESS) {
  399. leave;
  400. }
  401. status = IoSetDeviceInterfaceState(
  402. &deviceExtension->PnPDeviceName,
  403. TRUE
  404. );
  405. if (status != STATUS_SUCCESS) {
  406. leave;
  407. }
  408. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  409. }
  410. _finally {
  411. if (status == STATUS_SHARED_IRQ_BUSY) {
  412. SmartcardLogError(
  413. DeviceObject,
  414. TLP3_IRQ_BUSY,
  415. NULL,
  416. status
  417. );
  418. }
  419. if (status != STATUS_SUCCESS) {
  420. TLP3StopDevice(DeviceObject);
  421. }
  422. IoFreeIrp(irp);
  423. }
  424. SmartcardDebug(
  425. DEBUG_TRACE,
  426. ( "%s!TLP3StartDevice: Exit %lx\n",
  427. DRIVER_NAME,
  428. status)
  429. );
  430. return status;
  431. }
  432. VOID
  433. TLP3StopDevice(
  434. IN PDEVICE_OBJECT DeviceObject
  435. )
  436. /*++
  437. Routine Description:
  438. Finishes card tracking requests and closes the connection to the
  439. serial driver.
  440. --*/
  441. {
  442. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  443. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  444. SmartcardDebug(
  445. DEBUG_TRACE,
  446. ( "%s!TLP3StopDevice: Enter\n",
  447. DRIVER_NAME)
  448. );
  449. if (KeReadStateEvent(&READER_EXTENSION_L(SerialCloseDone)) == 0l) {
  450. NTSTATUS status;
  451. PUCHAR requestBuffer;
  452. PSMARTCARD_EXTENSION smartcardExtension =
  453. &deviceExtension->SmartcardExtension;
  454. // test if we ever started event tracking
  455. if (smartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask == 0) {
  456. // no, we did not
  457. // We 'only' need to close the serial port
  458. TLP3CloseSerialPort(DeviceObject, NULL);
  459. } else {
  460. //
  461. // We now inform the serial driver that we're not longer
  462. // interested in serial events. This will also free the irp
  463. // we use for those io-completions
  464. //
  465. smartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask = 0;
  466. // save the pointer
  467. requestBuffer = smartcardExtension->SmartcardRequest.Buffer;
  468. *(PULONG) smartcardExtension->SmartcardRequest.Buffer =
  469. smartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask;
  470. smartcardExtension->SmartcardRequest.BufferLength = sizeof(ULONG);
  471. smartcardExtension->ReaderExtension->SerialIoControlCode =
  472. IOCTL_SERIAL_SET_WAIT_MASK;
  473. // We don't expect to get bytes back
  474. smartcardExtension->SmartcardReply.BufferLength = 0;
  475. TLP3SerialIo(smartcardExtension);
  476. // restore the pointer
  477. smartcardExtension->SmartcardRequest.Buffer = requestBuffer;
  478. // now wait until the connetion to serial is closed
  479. status = KeWaitForSingleObject(
  480. &READER_EXTENSION_L(SerialCloseDone),
  481. Executive,
  482. KernelMode,
  483. FALSE,
  484. NULL
  485. );
  486. ASSERT(status == STATUS_SUCCESS);
  487. }
  488. }
  489. SmartcardDebug(
  490. DEBUG_TRACE,
  491. ( "%s!TLP3StopDevice: Exit\n",
  492. DRIVER_NAME)
  493. );
  494. }
  495. NTSTATUS
  496. TLP3SystemControl(
  497. PDEVICE_OBJECT DeviceObject,
  498. PIRP Irp
  499. )
  500. /*++
  501. --*/
  502. {
  503. PDEVICE_EXTENSION DeviceExtension;
  504. NTSTATUS status = STATUS_SUCCESS;
  505. DeviceExtension = DeviceObject->DeviceExtension;
  506. IoSkipCurrentIrpStackLocation(Irp);
  507. status = IoCallDriver(DeviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject, Irp);
  508. return status;
  509. }
  510. NTSTATUS
  511. TLP3DeviceControl(
  512. PDEVICE_OBJECT DeviceObject,
  513. PIRP Irp
  514. )
  515. /*++
  516. Routine Description:
  517. This is our IOCTL dispatch function
  518. --*/
  519. {
  520. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  521. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  522. NTSTATUS status = STATUS_SUCCESS;
  523. KIRQL irql;
  524. #ifdef SIMULATION
  525. RTL_QUERY_REGISTRY_TABLE parameters[2];
  526. #endif
  527. SmartcardDebug(
  528. DEBUG_TRACE,
  529. ( "%s!TLP3DeviceControl: Enter\n",
  530. DRIVER_NAME)
  531. );
  532. if (smartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask == 0) {
  533. //
  534. // the wait mask is set to 0 whenever the device was either
  535. // surprise-removed or politely removed
  536. //
  537. status = STATUS_DEVICE_REMOVED;
  538. }
  539. if (status == STATUS_SUCCESS) {
  540. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  541. if (deviceExtension->IoCount == 0) {
  542. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  543. status = KeWaitForSingleObject(
  544. &deviceExtension->ReaderStarted,
  545. Executive,
  546. KernelMode,
  547. FALSE,
  548. NULL
  549. );
  550. ASSERT(status == STATUS_SUCCESS);
  551. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  552. }
  553. ASSERT(deviceExtension->IoCount >= 0);
  554. deviceExtension->IoCount++;
  555. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  556. status = SmartcardAcquireRemoveLockWithTag(smartcardExtension, 'tcoI');
  557. }
  558. if (status != STATUS_SUCCESS) {
  559. // the device has been removed. Fail the call
  560. Irp->IoStatus.Information = 0;
  561. Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
  562. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  563. return STATUS_DEVICE_REMOVED;
  564. }
  565. #ifdef SIMULATION
  566. if (DriverKey) {
  567. ULONG oldLevel =
  568. smartcardExtension->ReaderExtension->SimulationLevel;
  569. RtlZeroMemory(parameters, sizeof(parameters));
  570. parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  571. parameters[0].Name = L"SimulationLevel";
  572. parameters[0].EntryContext =
  573. &smartcardExtension->ReaderExtension->SimulationLevel;
  574. parameters[0].DefaultType = REG_DWORD;
  575. parameters[0].DefaultData =
  576. &smartcardExtension->ReaderExtension->SimulationLevel;
  577. parameters[0].DefaultLength = sizeof(ULONG);
  578. if (RtlQueryRegistryValues(
  579. RTL_REGISTRY_ABSOLUTE,
  580. DriverKey,
  581. parameters,
  582. NULL,
  583. NULL
  584. ) == STATUS_SUCCESS) {
  585. SmartcardDebug(
  586. smartcardExtension->ReaderExtension->SimulationLevel == oldLevel ? 0 : DEBUG_SIMULATION,
  587. ( "%s!TLP3AddDevice: SimulationLevel set to %lx\n",
  588. DRIVER_NAME,
  589. smartcardExtension->ReaderExtension->SimulationLevel)
  590. );
  591. }
  592. }
  593. #endif
  594. ASSERT(smartcardExtension->ReaderExtension->ReaderPowerState ==
  595. PowerReaderWorking);
  596. status = SmartcardDeviceControl(
  597. smartcardExtension,
  598. Irp
  599. );
  600. SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'tcoI');
  601. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  602. deviceExtension->IoCount--;
  603. ASSERT(deviceExtension->IoCount >= 0);
  604. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  605. SmartcardDebug(
  606. DEBUG_TRACE,
  607. ( "%s!TLP3DeviceControl: Exit %lx\n",
  608. DRIVER_NAME,
  609. status)
  610. );
  611. return status;
  612. }
  613. VOID
  614. TLP3CloseSerialPort(
  615. IN PDEVICE_OBJECT DeviceObject,
  616. IN PVOID Context
  617. )
  618. /*++
  619. Routine Description:
  620. This function closes the connection to the serial driver when the reader
  621. has been removed (unplugged). This function runs as a system thread at
  622. IRQL == PASSIVE_LEVEL. It waits for the remove event that is set by
  623. the IoCompletionRoutine
  624. --*/
  625. {
  626. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  627. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  628. NTSTATUS status;
  629. PIRP irp;
  630. PIO_STACK_LOCATION irpStack;
  631. IO_STATUS_BLOCK ioStatusBlock;
  632. UNREFERENCED_PARAMETER(Context);
  633. SmartcardDebug(
  634. DEBUG_TRACE,
  635. ( "%s!TLP3CloseSerialPort: Enter\n",
  636. DRIVER_NAME)
  637. );
  638. //
  639. // first mark this device as 'gone'.
  640. // This will prevent that someone can re-open the device
  641. // We intentionally ignore possible errors
  642. //
  643. IoSetDeviceInterfaceState(
  644. &deviceExtension->PnPDeviceName,
  645. FALSE
  646. );
  647. irp = IoAllocateIrp(
  648. (CCHAR) (DeviceObject->StackSize + 1),
  649. FALSE
  650. );
  651. ASSERT(irp != NULL);
  652. if (irp) {
  653. SmartcardDebug(
  654. DEBUG_DRIVER,
  655. ( "%s!TLP3CloseSerialPort: Sending IRP_MJ_CLOSE\n",
  656. DRIVER_NAME)
  657. );
  658. IoSetNextIrpStackLocation(irp);
  659. //
  660. // We send down a close to the serial driver. This close goes
  661. // through serenum first which will trigger it to start looking
  662. // for changes on the com-port. Since our device is gone it will
  663. // call the device removal event of our PnP dispatch.
  664. //
  665. irp->UserIosb = &ioStatusBlock;
  666. irpStack = IoGetCurrentIrpStackLocation( irp );
  667. irpStack->MajorFunction = IRP_MJ_CLOSE;
  668. status = TLP3CallSerialDriver(
  669. ATTACHED_DEVICE_OBJECT,
  670. irp
  671. );
  672. ASSERT(status == STATUS_SUCCESS);
  673. IoFreeIrp(irp);
  674. }
  675. // now 'signal' that we closed the serial driver
  676. KeSetEvent(
  677. &READER_EXTENSION_L(SerialCloseDone),
  678. 0,
  679. FALSE
  680. );
  681. SmartcardDebug(
  682. DEBUG_INFO,
  683. ( "%s!TLP3CloseSerialPort: Exit\n",
  684. DRIVER_NAME)
  685. );
  686. }
  687. NTSTATUS
  688. TLP3IoCompletion (
  689. IN PDEVICE_OBJECT DeviceObject,
  690. IN PIRP Irp,
  691. IN PKEVENT Event
  692. )
  693. {
  694. UNREFERENCED_PARAMETER (DeviceObject);
  695. if (Irp->Cancel) {
  696. Irp->IoStatus.Status = STATUS_CANCELLED;
  697. } else {
  698. Irp->IoStatus.Status = STATUS_MORE_PROCESSING_REQUIRED;
  699. }
  700. KeSetEvent (Event, 0, FALSE);
  701. return STATUS_MORE_PROCESSING_REQUIRED;
  702. }
  703. NTSTATUS
  704. TLP3CallSerialDriver(
  705. IN PDEVICE_OBJECT DeviceObject,
  706. IN PIRP Irp
  707. )
  708. /*++
  709. Routine Description:
  710. Send an Irp to the serial driver.
  711. --*/
  712. {
  713. NTSTATUS status = STATUS_SUCCESS;
  714. KEVENT Event;
  715. // Copy our stack location to the next.
  716. IoCopyCurrentIrpStackLocationToNext(Irp);
  717. //
  718. // initialize an event for process synchronization. The event is passed
  719. // to our completion routine and will be set when the serial driver is done
  720. //
  721. KeInitializeEvent(
  722. &Event,
  723. NotificationEvent,
  724. FALSE
  725. );
  726. // Our IoCompletionRoutine sets only our event
  727. IoSetCompletionRoutine (
  728. Irp,
  729. TLP3IoCompletion,
  730. &Event,
  731. TRUE,
  732. TRUE,
  733. TRUE
  734. );
  735. if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_POWER) {
  736. status = PoCallDriver(DeviceObject, Irp);
  737. } else {
  738. // Call the serial driver
  739. status = IoCallDriver(DeviceObject, Irp);
  740. }
  741. // Wait until the serial driver has processed the Irp
  742. if (status == STATUS_PENDING) {
  743. status = KeWaitForSingleObject(
  744. &Event,
  745. Executive,
  746. KernelMode,
  747. FALSE,
  748. NULL
  749. );
  750. ASSERT (STATUS_SUCCESS == status);
  751. status = Irp->IoStatus.Status;
  752. }
  753. return status;
  754. }
  755. NTSTATUS
  756. TLP3PnP(
  757. IN PDEVICE_OBJECT DeviceObject,
  758. IN PIRP Irp
  759. )
  760. /*++
  761. Routine Description:
  762. --*/
  763. {
  764. PUCHAR requestBuffer;
  765. NTSTATUS status = STATUS_SUCCESS;
  766. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  767. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  768. PREADER_EXTENSION readerExtension = smartcardExtension->ReaderExtension;
  769. PDEVICE_OBJECT AttachedDeviceObject;
  770. PIO_STACK_LOCATION irpStack;
  771. IO_STATUS_BLOCK ioStatusBlock;
  772. BOOLEAN deviceRemoved = FALSE, irpSkipped = FALSE;
  773. KIRQL irql;
  774. SmartcardDebug(
  775. DEBUG_TRACE,
  776. ( "%s!TLP3PnPDeviceControl: Enter\n",
  777. DRIVER_NAME)
  778. );
  779. status = SmartcardAcquireRemoveLockWithTag(smartcardExtension, ' PnP');
  780. ASSERT(status == STATUS_SUCCESS);
  781. if (status != STATUS_SUCCESS) {
  782. Irp->IoStatus.Information = 0;
  783. Irp->IoStatus.Status = status;
  784. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  785. return status;
  786. }
  787. AttachedDeviceObject = ATTACHED_DEVICE_OBJECT;
  788. irpStack = IoGetCurrentIrpStackLocation(Irp);
  789. // Now look what the PnP manager wants...
  790. switch(irpStack->MinorFunction)
  791. {
  792. case IRP_MN_START_DEVICE:
  793. SmartcardDebug(
  794. DEBUG_DRIVER,
  795. ("%s!TLP3PnPDeviceControl: IRP_MN_START_DEVICE\n",
  796. DRIVER_NAME)
  797. );
  798. // We have to call the underlying driver first
  799. status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
  800. ASSERT(NT_SUCCESS(status));
  801. if (NT_SUCCESS(status)) {
  802. status = TLP3StartDevice(DeviceObject);
  803. }
  804. break;
  805. case IRP_MN_QUERY_STOP_DEVICE:
  806. SmartcardDebug(
  807. DEBUG_DRIVER,
  808. ("%s!TLP3PnPDeviceControl: IRP_MN_QUERY_STOP_DEVICE\n",
  809. DRIVER_NAME)
  810. );
  811. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  812. if (deviceExtension->IoCount > 0) {
  813. // we refuse to stop if we have pending io
  814. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  815. status = STATUS_DEVICE_BUSY;
  816. } else {
  817. // stop processing requests
  818. KeClearEvent(&deviceExtension->ReaderStarted);
  819. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  820. status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
  821. }
  822. break;
  823. case IRP_MN_CANCEL_STOP_DEVICE:
  824. SmartcardDebug(
  825. DEBUG_DRIVER,
  826. ("%s!TLP3PnPDeviceControl: IRP_MN_CANCEL_STOP_DEVICE\n",
  827. DRIVER_NAME)
  828. );
  829. status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
  830. if (status == STATUS_SUCCESS) {
  831. // we can continue to process requests
  832. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  833. }
  834. break;
  835. case IRP_MN_STOP_DEVICE:
  836. SmartcardDebug(
  837. DEBUG_DRIVER,
  838. ("%s!TLP3PnPDeviceControl: IRP_MN_STOP_DEVICE\n",
  839. DRIVER_NAME)
  840. );
  841. TLP3StopDevice(DeviceObject);
  842. //
  843. // we don't do anything since a stop is only used
  844. // to reconfigure hw-resources like interrupts and io-ports
  845. //
  846. status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
  847. break;
  848. case IRP_MN_QUERY_REMOVE_DEVICE:
  849. SmartcardDebug(
  850. DEBUG_DRIVER,
  851. ("%s!TLP3PnPDeviceControl: IRP_MN_QUERY_REMOVE_DEVICE\n",
  852. DRIVER_NAME)
  853. );
  854. // disable the interface (and ignore possible errors)
  855. IoSetDeviceInterfaceState(
  856. &deviceExtension->PnPDeviceName,
  857. FALSE
  858. );
  859. // now look if someone is currently connected to us
  860. if (deviceExtension->ReaderOpen) {
  861. //
  862. // someone is connected, fail the call
  863. // we will enable the device interface in
  864. // IRP_MN_CANCEL_REMOVE_DEVICE again
  865. //
  866. status = STATUS_UNSUCCESSFUL;
  867. break;
  868. }
  869. // pass the call to the next driver in the stack
  870. status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
  871. break;
  872. case IRP_MN_CANCEL_REMOVE_DEVICE:
  873. SmartcardDebug(
  874. DEBUG_DRIVER,
  875. ("%s!TLP3PnPDeviceControl: IRP_MN_CANCEL_REMOVE_DEVICE\n",
  876. DRIVER_NAME)
  877. );
  878. status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
  879. //
  880. // reenable the interface only in case that the reader is
  881. // still connected. This covers the following case:
  882. // hibernate machine, disconnect reader, wake up, stop device
  883. // (from task bar) and stop fails since an app. holds the device open
  884. //
  885. if (status == STATUS_SUCCESS &&
  886. READER_EXTENSION_L(SerialConfigData.SerialWaitMask) != 0) {
  887. status = IoSetDeviceInterfaceState(
  888. &deviceExtension->PnPDeviceName,
  889. TRUE
  890. );
  891. ASSERT(status == STATUS_SUCCESS);
  892. }
  893. break;
  894. case IRP_MN_REMOVE_DEVICE:
  895. SmartcardDebug(
  896. DEBUG_DRIVER,
  897. ("%s!TLP3PnPDeviceControl: IRP_MN_REMOVE_DEVICE\n",
  898. DRIVER_NAME)
  899. );
  900. TLP3RemoveDevice(DeviceObject);
  901. status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
  902. deviceRemoved = TRUE;
  903. break;
  904. default:
  905. // This is an Irp that is only useful for underlying drivers
  906. SmartcardDebug(
  907. DEBUG_DRIVER,
  908. ("%s!TLP3PnPDeviceControl: IRP_MN_...%lx\n",
  909. DRIVER_NAME,
  910. irpStack->MinorFunction)
  911. );
  912. IoSkipCurrentIrpStackLocation(Irp);
  913. status = IoCallDriver(AttachedDeviceObject, Irp);
  914. irpSkipped = TRUE;
  915. break;
  916. }
  917. if (irpSkipped == FALSE) {
  918. Irp->IoStatus.Status = status;
  919. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  920. }
  921. if (deviceRemoved == FALSE) {
  922. SmartcardReleaseRemoveLockWithTag(smartcardExtension, ' PnP');
  923. }
  924. SmartcardDebug(
  925. DEBUG_TRACE,
  926. ( "%s!TLP3PnPDeviceControl: Exit %lx\n",
  927. DRIVER_NAME,
  928. status)
  929. );
  930. return status;
  931. }
  932. VOID
  933. TLP3SystemPowerCompletion(
  934. IN PDEVICE_OBJECT DeviceObject,
  935. IN UCHAR MinorFunction,
  936. IN POWER_STATE PowerState,
  937. IN PKEVENT Event,
  938. IN PIO_STATUS_BLOCK IoStatus
  939. )
  940. /*++
  941. Routine Description:
  942. This function is called when the underlying stacks
  943. completed the power transition.
  944. --*/
  945. {
  946. UNREFERENCED_PARAMETER (DeviceObject);
  947. UNREFERENCED_PARAMETER (MinorFunction);
  948. UNREFERENCED_PARAMETER (PowerState);
  949. UNREFERENCED_PARAMETER (IoStatus);
  950. KeSetEvent(Event, 0, FALSE);
  951. }
  952. NTSTATUS
  953. TLP3DevicePowerCompletion (
  954. IN PDEVICE_OBJECT DeviceObject,
  955. IN PIRP Irp,
  956. IN PSMARTCARD_EXTENSION SmartcardExtension
  957. )
  958. /*++
  959. Routine Description:
  960. This routine is called after the underlying stack powered
  961. UP the serial port, so it can be used again.
  962. --*/
  963. {
  964. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  965. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  966. LARGE_INTEGER delayPeriod;
  967. //
  968. // Allow the reader enough time to power itself up
  969. //
  970. delayPeriod.HighPart = -1;
  971. delayPeriod.LowPart = 100000 * (-10);
  972. KeDelayExecutionThread(
  973. KernelMode,
  974. FALSE,
  975. &delayPeriod
  976. );
  977. //
  978. // We issue a power request in order to figure out
  979. // what the actual card status is
  980. //
  981. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  982. TLP3ReaderPower(SmartcardExtension);
  983. //
  984. // If a card was present before power down or now there is
  985. // a card in the reader, we complete any pending card monitor
  986. // request, since we do not really know what card is now in the
  987. // reader.
  988. //
  989. if(SmartcardExtension->ReaderExtension->CardPresent ||
  990. SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT) {
  991. TLP3CompleteCardTracking(SmartcardExtension);
  992. }
  993. // save the current power state of the reader
  994. SmartcardExtension->ReaderExtension->ReaderPowerState =
  995. PowerReaderWorking;
  996. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'rwoP');
  997. // inform the power manager of our state.
  998. PoSetPowerState (
  999. DeviceObject,
  1000. DevicePowerState,
  1001. irpStack->Parameters.Power.State
  1002. );
  1003. PoStartNextPowerIrp(Irp);
  1004. // signal that we can process ioctls again
  1005. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  1006. return STATUS_SUCCESS;
  1007. }
  1008. typedef enum _ACTION {
  1009. Undefined = 0,
  1010. SkipRequest,
  1011. WaitForCompletion,
  1012. CompleteRequest,
  1013. MarkPending
  1014. } ACTION;
  1015. NTSTATUS
  1016. TLP3Power (
  1017. IN PDEVICE_OBJECT DeviceObject,
  1018. IN PIRP Irp
  1019. )
  1020. /*++
  1021. Routine Description:
  1022. The power dispatch routine.
  1023. This driver is the power policy owner of the device stack,
  1024. because this driver knows about the connected reader.
  1025. Therefor this driver will translate system power states
  1026. to device power states.
  1027. Arguments:
  1028. DeviceObject - pointer to a device object.
  1029. Irp - pointer to an I/O Request Packet.
  1030. Return Value:
  1031. NT status code
  1032. --*/
  1033. {
  1034. NTSTATUS status = STATUS_SUCCESS;
  1035. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  1036. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1037. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  1038. PDEVICE_OBJECT AttachedDeviceObject;
  1039. POWER_STATE powerState;
  1040. ACTION action = SkipRequest;
  1041. KEVENT event;
  1042. SmartcardDebug(
  1043. DEBUG_DRIVER,
  1044. ("%s!TLP3Power: Enter\n",
  1045. DRIVER_NAME)
  1046. );
  1047. status = SmartcardAcquireRemoveLockWithTag(smartcardExtension, 'rwoP');
  1048. ASSERT(status == STATUS_SUCCESS);
  1049. if (!NT_SUCCESS(status)) {
  1050. PoStartNextPowerIrp(Irp);
  1051. Irp->IoStatus.Status = status;
  1052. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1053. return status;
  1054. }
  1055. AttachedDeviceObject = ATTACHED_DEVICE_OBJECT;
  1056. switch (irpStack->Parameters.Power.Type) {
  1057. case DevicePowerState:
  1058. if (irpStack->MinorFunction == IRP_MN_SET_POWER) {
  1059. switch (irpStack->Parameters.Power.State.DeviceState) {
  1060. case PowerDeviceD0:
  1061. // Turn on the reader
  1062. SmartcardDebug(
  1063. DEBUG_DRIVER,
  1064. ("%s!TLP3Power: PowerDevice D0\n",
  1065. DRIVER_NAME)
  1066. );
  1067. //
  1068. // First, we send down the request to the bus, in order
  1069. // to power on the port. When the request completes,
  1070. // we turn on the reader
  1071. //
  1072. IoCopyCurrentIrpStackLocationToNext(Irp);
  1073. IoSetCompletionRoutine (
  1074. Irp,
  1075. TLP3DevicePowerCompletion,
  1076. smartcardExtension,
  1077. TRUE,
  1078. TRUE,
  1079. TRUE
  1080. );
  1081. action = WaitForCompletion;
  1082. break;
  1083. case PowerDeviceD3:
  1084. // Turn off the reader
  1085. SmartcardDebug(
  1086. DEBUG_DRIVER,
  1087. ("%s!TLP3Power: PowerDevice D3\n",
  1088. DRIVER_NAME)
  1089. );
  1090. PoSetPowerState (
  1091. DeviceObject,
  1092. DevicePowerState,
  1093. irpStack->Parameters.Power.State
  1094. );
  1095. // save the current card state
  1096. smartcardExtension->ReaderExtension->CardPresent =
  1097. smartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT;
  1098. if (smartcardExtension->ReaderExtension->CardPresent) {
  1099. smartcardExtension->MinorIoControlCode = SCARD_POWER_DOWN;
  1100. status = TLP3ReaderPower(smartcardExtension);
  1101. ASSERT(status == STATUS_SUCCESS);
  1102. }
  1103. //
  1104. // If there is a pending card tracking request, setting
  1105. // this flag will prevent completion of the request
  1106. // when the system will be waked up again.
  1107. //
  1108. smartcardExtension->ReaderExtension->PowerRequest = TRUE;
  1109. // save the current power state of the reader
  1110. smartcardExtension->ReaderExtension->ReaderPowerState =
  1111. PowerReaderOff;
  1112. action = SkipRequest;
  1113. break;
  1114. default:
  1115. ASSERT(FALSE);
  1116. action = SkipRequest;
  1117. break;
  1118. }
  1119. }
  1120. break;
  1121. case SystemPowerState: {
  1122. //
  1123. // The system wants to change the power state.
  1124. // We need to translate the system power state to
  1125. // a corresponding device power state.
  1126. //
  1127. POWER_STATE_TYPE powerType = DevicePowerState;
  1128. ASSERT(smartcardExtension->ReaderExtension->ReaderPowerState !=
  1129. PowerReaderUnspecified);
  1130. switch (irpStack->MinorFunction) {
  1131. KIRQL irql;
  1132. case IRP_MN_QUERY_POWER:
  1133. SmartcardDebug(
  1134. DEBUG_DRIVER,
  1135. ("%s!TLP3Power: Query Power\n",
  1136. DRIVER_NAME)
  1137. );
  1138. switch (irpStack->Parameters.Power.State.SystemState) {
  1139. case PowerSystemMaximum:
  1140. case PowerSystemWorking:
  1141. case PowerSystemSleeping1:
  1142. case PowerSystemSleeping2:
  1143. action = SkipRequest;
  1144. break;
  1145. case PowerSystemSleeping3:
  1146. case PowerSystemHibernate:
  1147. case PowerSystemShutdown:
  1148. KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
  1149. if (deviceExtension->IoCount == 0) {
  1150. // Block any further ioctls
  1151. KeClearEvent(&deviceExtension->ReaderStarted);
  1152. action = SkipRequest;
  1153. } else {
  1154. // can't go to sleep mode since the reader is busy.
  1155. status = STATUS_DEVICE_BUSY;
  1156. action = CompleteRequest;
  1157. }
  1158. KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
  1159. break;
  1160. }
  1161. break;
  1162. case IRP_MN_SET_POWER:
  1163. SmartcardDebug(
  1164. DEBUG_DRIVER,
  1165. ("%s!TLP3Power: PowerSystem S%d\n",
  1166. DRIVER_NAME,
  1167. irpStack->Parameters.Power.State.SystemState - 1)
  1168. );
  1169. switch (irpStack->Parameters.Power.State.SystemState) {
  1170. case PowerSystemMaximum:
  1171. case PowerSystemWorking:
  1172. case PowerSystemSleeping1:
  1173. case PowerSystemSleeping2:
  1174. if (smartcardExtension->ReaderExtension->ReaderPowerState ==
  1175. PowerReaderWorking) {
  1176. // We're already in the right state
  1177. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  1178. action = SkipRequest;
  1179. break;
  1180. }
  1181. // wake up the underlying stack...
  1182. powerState.DeviceState = PowerDeviceD0;
  1183. action = MarkPending;
  1184. break;
  1185. case PowerSystemSleeping3:
  1186. case PowerSystemHibernate:
  1187. case PowerSystemShutdown:
  1188. if (smartcardExtension->ReaderExtension->ReaderPowerState ==
  1189. PowerReaderOff) {
  1190. // We're already in the right state
  1191. action = SkipRequest;
  1192. break;
  1193. }
  1194. powerState.DeviceState = PowerDeviceD3;
  1195. // first, inform the power manager of our new state.
  1196. PoSetPowerState (
  1197. DeviceObject,
  1198. SystemPowerState,
  1199. powerState
  1200. );
  1201. action = MarkPending;
  1202. break;
  1203. default:
  1204. ASSERT(FALSE);
  1205. action = SkipRequest;
  1206. break;
  1207. }
  1208. break;
  1209. }
  1210. }
  1211. break;
  1212. default:
  1213. ASSERT(FALSE);
  1214. action = SkipRequest;
  1215. break;
  1216. }
  1217. switch (action) {
  1218. case CompleteRequest:
  1219. Irp->IoStatus.Status = status;
  1220. Irp->IoStatus.Information = 0;
  1221. SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
  1222. PoStartNextPowerIrp(Irp);
  1223. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1224. break;
  1225. case MarkPending:
  1226. // initialize the event we need in the completion function
  1227. KeInitializeEvent(
  1228. &event,
  1229. NotificationEvent,
  1230. FALSE
  1231. );
  1232. // request the device power irp
  1233. status = PoRequestPowerIrp (
  1234. DeviceObject,
  1235. IRP_MN_SET_POWER,
  1236. powerState,
  1237. TLP3SystemPowerCompletion,
  1238. &event,
  1239. NULL
  1240. );
  1241. ASSERT(status == STATUS_PENDING);
  1242. if (status == STATUS_PENDING) {
  1243. // wait until the device power irp completed
  1244. status = KeWaitForSingleObject(
  1245. &event,
  1246. Executive,
  1247. KernelMode,
  1248. FALSE,
  1249. NULL
  1250. );
  1251. SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
  1252. if (powerState.SystemState == PowerSystemWorking) {
  1253. PoSetPowerState (
  1254. DeviceObject,
  1255. SystemPowerState,
  1256. powerState
  1257. );
  1258. }
  1259. PoStartNextPowerIrp(Irp);
  1260. IoSkipCurrentIrpStackLocation(Irp);
  1261. status = PoCallDriver(AttachedDeviceObject, Irp);
  1262. } else {
  1263. SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
  1264. Irp->IoStatus.Status = status;
  1265. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1266. }
  1267. break;
  1268. case SkipRequest:
  1269. SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
  1270. PoStartNextPowerIrp(Irp);
  1271. IoSkipCurrentIrpStackLocation(Irp);
  1272. status = PoCallDriver(AttachedDeviceObject, Irp);
  1273. break;
  1274. case WaitForCompletion:
  1275. status = PoCallDriver(AttachedDeviceObject, Irp);
  1276. break;
  1277. default:
  1278. ASSERT(FALSE);
  1279. break;
  1280. }
  1281. SmartcardDebug(
  1282. DEBUG_DRIVER,
  1283. ("%s!TLP3Power: Exit %lx\n",
  1284. DRIVER_NAME,
  1285. status)
  1286. );
  1287. return status;
  1288. }
  1289. NTSTATUS
  1290. TLP3CreateClose(
  1291. IN PDEVICE_OBJECT DeviceObject,
  1292. IN PIRP Irp
  1293. )
  1294. /*++
  1295. Routine Description:
  1296. This routine is called by the I/O system when the device is opened or closed.
  1297. Arguments:
  1298. DeviceObject - Pointer to device object for this miniport
  1299. Irp - IRP involved.
  1300. Return Value:
  1301. STATUS_SUCCESS.
  1302. --*/
  1303. {
  1304. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1305. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  1306. NTSTATUS status = STATUS_SUCCESS;
  1307. __try {
  1308. if (irpStack->MajorFunction == IRP_MJ_CREATE) {
  1309. status = SmartcardAcquireRemoveLockWithTag(
  1310. &deviceExtension->SmartcardExtension,
  1311. 'lCrC'
  1312. );
  1313. if (status != STATUS_SUCCESS) {
  1314. status = STATUS_DEVICE_REMOVED;
  1315. __leave;
  1316. }
  1317. // test if the device has been opened already
  1318. if (InterlockedCompareExchange(
  1319. &deviceExtension->ReaderOpen,
  1320. TRUE,
  1321. FALSE) == FALSE) {
  1322. SmartcardDebug(
  1323. DEBUG_DRIVER,
  1324. ("%s!TLP3CreateClose: Open\n",
  1325. DRIVER_NAME)
  1326. );
  1327. } else {
  1328. // the device is already in use
  1329. status = STATUS_UNSUCCESSFUL;
  1330. // release the lock
  1331. SmartcardReleaseRemoveLockWithTag(
  1332. &deviceExtension->SmartcardExtension,
  1333. 'lCrC'
  1334. );
  1335. }
  1336. } else {
  1337. SmartcardDebug(
  1338. DEBUG_DRIVER,
  1339. ("%s!TLP3CreateClose: Close\n",
  1340. DRIVER_NAME)
  1341. );
  1342. SmartcardReleaseRemoveLockWithTag(
  1343. &deviceExtension->SmartcardExtension,
  1344. 'lCrC'
  1345. );
  1346. deviceExtension->ReaderOpen = FALSE;
  1347. }
  1348. }
  1349. __finally {
  1350. Irp->IoStatus.Status = status;
  1351. Irp->IoStatus.Information = 0;
  1352. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1353. }
  1354. return status;
  1355. }
  1356. NTSTATUS
  1357. TLP3Cancel(
  1358. IN PDEVICE_OBJECT DeviceObject,
  1359. IN PIRP Irp
  1360. )
  1361. /*++
  1362. Routine Description:
  1363. This routine is called by the I/O system
  1364. when the irp should be cancelled
  1365. Arguments:
  1366. DeviceObject - Pointer to device object for this miniport
  1367. Irp - IRP involved.
  1368. Return Value:
  1369. STATUS_CANCELLED
  1370. --*/
  1371. {
  1372. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1373. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  1374. SmartcardDebug(
  1375. DEBUG_TRACE,
  1376. ("%s!TLP3Cancel: Enter\n",
  1377. DRIVER_NAME)
  1378. );
  1379. ASSERT(Irp == smartcardExtension->OsData->NotificationIrp);
  1380. IoReleaseCancelSpinLock(
  1381. Irp->CancelIrql
  1382. );
  1383. TLP3CompleteCardTracking(smartcardExtension);
  1384. SmartcardDebug(
  1385. DEBUG_TRACE,
  1386. ("%s!TLP3Cancel: Exit\n",
  1387. DRIVER_NAME)
  1388. );
  1389. return STATUS_CANCELLED;
  1390. }
  1391. NTSTATUS
  1392. TLP3Cleanup(
  1393. IN PDEVICE_OBJECT DeviceObject,
  1394. IN PIRP Irp
  1395. )
  1396. /*++
  1397. Routine Description:
  1398. This routine is called when the calling application terminates.
  1399. We can actually only have the notification irp that we have to cancel.
  1400. --*/
  1401. {
  1402. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1403. PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
  1404. NTSTATUS status = STATUS_SUCCESS;
  1405. SmartcardDebug(
  1406. DEBUG_TRACE,
  1407. ("%s!TLP3Cleanup: Enter\n",
  1408. DRIVER_NAME)
  1409. );
  1410. ASSERT(Irp != smartcardExtension->OsData->NotificationIrp);
  1411. // We need to complete the notification irp
  1412. TLP3CompleteCardTracking(smartcardExtension);
  1413. SmartcardDebug(
  1414. DEBUG_DRIVER,
  1415. ("%s!TLP3Cleanup: Completing IRP %lx\n",
  1416. DRIVER_NAME,
  1417. Irp)
  1418. );
  1419. Irp->IoStatus.Information = 0;
  1420. Irp->IoStatus.Status = STATUS_SUCCESS;
  1421. IoCompleteRequest(
  1422. Irp,
  1423. IO_NO_INCREMENT
  1424. );
  1425. SmartcardDebug(
  1426. DEBUG_TRACE,
  1427. ("%s!TLP3Cleanup: Exit\n",
  1428. DRIVER_NAME)
  1429. );
  1430. return STATUS_SUCCESS;
  1431. }
  1432. VOID
  1433. TLP3RemoveDevice(
  1434. PDEVICE_OBJECT DeviceObject
  1435. )
  1436. /*++
  1437. Routine Description:
  1438. Remove the device from the system.
  1439. --*/
  1440. {
  1441. PDEVICE_EXTENSION deviceExtension;
  1442. PSMARTCARD_EXTENSION smartcardExtension;
  1443. NTSTATUS status;
  1444. PAGED_CODE();
  1445. if (DeviceObject == NULL) {
  1446. return;
  1447. }
  1448. deviceExtension = DeviceObject->DeviceExtension;
  1449. smartcardExtension = &deviceExtension->SmartcardExtension;
  1450. SmartcardDebug(
  1451. DEBUG_TRACE,
  1452. ( "%s!TLP3RemoveDevice: Enter\n",
  1453. DRIVER_NAME)
  1454. );
  1455. if (smartcardExtension->OsData) {
  1456. // complete pending card tracking requests (if any)
  1457. TLP3CompleteCardTracking(smartcardExtension);
  1458. ASSERT(smartcardExtension->OsData->NotificationIrp == NULL);
  1459. // Wait until we can safely unload the device
  1460. SmartcardReleaseRemoveLockAndWait(smartcardExtension);
  1461. }
  1462. TLP3StopDevice(DeviceObject);
  1463. if (deviceExtension->SmartcardExtension.ReaderExtension &&
  1464. deviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject) {
  1465. IoDetachDevice(
  1466. deviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject
  1467. );
  1468. }
  1469. if(deviceExtension->PnPDeviceName.Buffer != NULL) {
  1470. RtlFreeUnicodeString(&deviceExtension->PnPDeviceName);
  1471. }
  1472. if(smartcardExtension->OsData != NULL) {
  1473. SmartcardExit(smartcardExtension);
  1474. }
  1475. if (smartcardExtension->ReaderExtension != NULL) {
  1476. ExFreePool(smartcardExtension->ReaderExtension);
  1477. }
  1478. if (deviceExtension->CloseSerial != NULL) {
  1479. IoFreeWorkItem(deviceExtension->CloseSerial);
  1480. }
  1481. IoDeleteDevice(DeviceObject);
  1482. SmartcardDebug(
  1483. DEBUG_INFO,
  1484. ( "%s!TLP3RemoveDevice: Exit\n",
  1485. DRIVER_NAME)
  1486. );
  1487. }
  1488. VOID
  1489. TLP3DriverUnload(
  1490. IN PDRIVER_OBJECT DriverObject
  1491. )
  1492. /*++
  1493. Routine Description:
  1494. The driver unload routine. This is called by the I/O system
  1495. when the device is unloaded from memory.
  1496. Arguments:
  1497. DriverObject - Pointer to driver object created by system.
  1498. Return Value:
  1499. STATUS_SUCCESS.
  1500. --*/
  1501. {
  1502. PAGED_CODE();
  1503. SmartcardDebug(
  1504. DEBUG_INFO,
  1505. ("%s!TLP3DriverUnload\n",
  1506. DRIVER_NAME)
  1507. );
  1508. }
  1509. NTSTATUS
  1510. TLP3ConfigureSerialPort(
  1511. PSMARTCARD_EXTENSION SmartcardExtension
  1512. )
  1513. /*++
  1514. Routine Description:
  1515. This routine will appropriately configure the serial port.
  1516. It makes synchronous calls to the serial port.
  1517. Arguments:
  1518. SmartcardExtension - Pointer to smart card struct
  1519. Return Value:
  1520. NTSTATUS
  1521. --*/
  1522. {
  1523. PSERIAL_READER_CONFIG configData = &SmartcardExtension->ReaderExtension->SerialConfigData;
  1524. NTSTATUS status = STATUS_SUCCESS;
  1525. USHORT i;
  1526. PUCHAR request = SmartcardExtension->SmartcardRequest.Buffer;
  1527. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  1528. SmartcardExtension->SmartcardReply.BufferLength =
  1529. SmartcardExtension->SmartcardReply.BufferSize;
  1530. for (i = 0; status == STATUS_SUCCESS; i++) {
  1531. switch (i) {
  1532. case 0:
  1533. //
  1534. // Set up baudrate for the TLP3 reader
  1535. //
  1536. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1537. IOCTL_SERIAL_SET_BAUD_RATE;
  1538. SmartcardExtension->SmartcardRequest.Buffer =
  1539. (PUCHAR) &configData->BaudRate;
  1540. SmartcardExtension->SmartcardRequest.BufferLength =
  1541. sizeof(SERIAL_BAUD_RATE);
  1542. break;
  1543. case 1:
  1544. //
  1545. // Set up line control parameters
  1546. //
  1547. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1548. IOCTL_SERIAL_SET_LINE_CONTROL;
  1549. SmartcardExtension->SmartcardRequest.Buffer =
  1550. (PUCHAR) &configData->LineControl;
  1551. SmartcardExtension->SmartcardRequest.BufferLength =
  1552. sizeof(SERIAL_LINE_CONTROL);
  1553. break;
  1554. case 2:
  1555. //
  1556. // Set serial special characters
  1557. //
  1558. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1559. IOCTL_SERIAL_SET_CHARS;
  1560. SmartcardExtension->SmartcardRequest.Buffer =
  1561. (PUCHAR) &configData->SerialChars;
  1562. SmartcardExtension->SmartcardRequest.BufferLength =
  1563. sizeof(SERIAL_CHARS);
  1564. break;
  1565. case 3:
  1566. //
  1567. // Set up timeouts
  1568. //
  1569. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1570. IOCTL_SERIAL_SET_TIMEOUTS;
  1571. SmartcardExtension->SmartcardRequest.Buffer =
  1572. (PUCHAR) &configData->Timeouts;
  1573. SmartcardExtension->SmartcardRequest.BufferLength =
  1574. sizeof(SERIAL_TIMEOUTS);
  1575. break;
  1576. case 4:
  1577. // Set flowcontrol and handshaking
  1578. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1579. IOCTL_SERIAL_SET_HANDFLOW;
  1580. SmartcardExtension->SmartcardRequest.Buffer =
  1581. (PUCHAR) &configData->HandFlow;
  1582. SmartcardExtension->SmartcardRequest.BufferLength =
  1583. sizeof(SERIAL_HANDFLOW);
  1584. break;
  1585. case 5:
  1586. // Set break off
  1587. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1588. IOCTL_SERIAL_SET_BREAK_OFF;
  1589. break;
  1590. case 6:
  1591. // set DTR for the reader
  1592. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1593. IOCTL_SERIAL_SET_DTR;
  1594. break;
  1595. case 7:
  1596. SmartcardExtension->ReaderExtension->SerialIoControlCode =
  1597. IOCTL_SERIAL_SET_RTS;
  1598. break;
  1599. case 8:
  1600. return STATUS_SUCCESS;
  1601. }
  1602. status = TLP3SerialIo(SmartcardExtension);
  1603. // restore pointer to original request buffer
  1604. SmartcardExtension->SmartcardRequest.Buffer = request;
  1605. }
  1606. return status;
  1607. }
  1608. NTSTATUS
  1609. TLP3StartSerialEventTracking(
  1610. PSMARTCARD_EXTENSION SmartcardExtension
  1611. )
  1612. /*++
  1613. Routine Description:
  1614. This routine initializes serial event tracking.
  1615. It calls the serial driver to set a wait mask for CTS and DSR tracking.
  1616. --*/
  1617. {
  1618. NTSTATUS status;
  1619. PREADER_EXTENSION readerExtension = SmartcardExtension->ReaderExtension;
  1620. IO_STATUS_BLOCK ioStatus;
  1621. KEVENT event;
  1622. PAGED_CODE();
  1623. readerExtension->SerialConfigData.SerialWaitMask =
  1624. SERIAL_EV_CTS | SERIAL_EV_DSR;
  1625. KeInitializeEvent(
  1626. &event,
  1627. NotificationEvent,
  1628. FALSE
  1629. );
  1630. //
  1631. // Send a wait mask to the serial driver. This call only sets the
  1632. // wait mask. We want to be informed when CTS or DSR changes its state
  1633. //
  1634. readerExtension->SerialStatusIrp = IoBuildDeviceIoControlRequest(
  1635. IOCTL_SERIAL_SET_WAIT_MASK,
  1636. readerExtension->AttachedDeviceObject,
  1637. &readerExtension->SerialConfigData.SerialWaitMask,
  1638. sizeof(readerExtension->SerialConfigData.SerialWaitMask),
  1639. NULL,
  1640. 0,
  1641. FALSE,
  1642. &event,
  1643. &ioStatus
  1644. );
  1645. if (readerExtension->SerialStatusIrp == NULL) {
  1646. return STATUS_INSUFFICIENT_RESOURCES;
  1647. }
  1648. status = IoCallDriver(
  1649. readerExtension->AttachedDeviceObject,
  1650. readerExtension->SerialStatusIrp,
  1651. );
  1652. if (status == STATUS_PENDING) {
  1653. status = KeWaitForSingleObject(
  1654. &event,
  1655. Executive,
  1656. KernelMode,
  1657. FALSE,
  1658. NULL
  1659. );
  1660. ASSERT(status == STATUS_SUCCESS);
  1661. status = ioStatus.Status;
  1662. }
  1663. if (status == STATUS_SUCCESS) {
  1664. KIRQL oldIrql;
  1665. LARGE_INTEGER delayPeriod;
  1666. PIO_STACK_LOCATION irpSp;
  1667. //
  1668. // Now tell the serial driver that we want to be informed
  1669. // when CTS or DSR changes its state.
  1670. //
  1671. readerExtension->SerialStatusIrp = IoAllocateIrp(
  1672. (CCHAR) (SmartcardExtension->OsData->DeviceObject->StackSize + 1),
  1673. FALSE
  1674. );
  1675. if (readerExtension->SerialStatusIrp == NULL) {
  1676. return STATUS_INSUFFICIENT_RESOURCES;
  1677. }
  1678. irpSp = IoGetNextIrpStackLocation( readerExtension->SerialStatusIrp );
  1679. irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
  1680. irpSp->Parameters.DeviceIoControl.InputBufferLength = 0;
  1681. irpSp->Parameters.DeviceIoControl.OutputBufferLength =
  1682. sizeof(readerExtension->SerialConfigData.SerialWaitMask);
  1683. irpSp->Parameters.DeviceIoControl.IoControlCode =
  1684. IOCTL_SERIAL_WAIT_ON_MASK;
  1685. readerExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer =
  1686. &readerExtension->SerialConfigData.SerialWaitMask;
  1687. //
  1688. // this artificial delay is necessary to make this driver work
  1689. // with digi board cards
  1690. //
  1691. delayPeriod.HighPart = -1;
  1692. delayPeriod.LowPart = 100l * 1000 * (-10);
  1693. KeDelayExecutionThread(
  1694. KernelMode,
  1695. FALSE,
  1696. &delayPeriod
  1697. );
  1698. // We simulate a callback now that triggers the card supervision
  1699. TLP3SerialEvent(
  1700. SmartcardExtension->OsData->DeviceObject,
  1701. readerExtension->SerialStatusIrp,
  1702. SmartcardExtension
  1703. );
  1704. status = STATUS_SUCCESS;
  1705. }
  1706. return status;
  1707. }
  1708. VOID
  1709. TLP3CompleteCardTracking(
  1710. IN PSMARTCARD_EXTENSION SmartcardExtension
  1711. )
  1712. {
  1713. KIRQL ioIrql, keIrql;
  1714. PIRP notificationIrp;
  1715. IoAcquireCancelSpinLock(&ioIrql);
  1716. KeAcquireSpinLock(
  1717. &SmartcardExtension->OsData->SpinLock,
  1718. &keIrql
  1719. );
  1720. notificationIrp = SmartcardExtension->OsData->NotificationIrp;
  1721. SmartcardExtension->OsData->NotificationIrp = NULL;
  1722. KeReleaseSpinLock(
  1723. &SmartcardExtension->OsData->SpinLock,
  1724. keIrql
  1725. );
  1726. if (notificationIrp) {
  1727. IoSetCancelRoutine(
  1728. notificationIrp,
  1729. NULL
  1730. );
  1731. }
  1732. IoReleaseCancelSpinLock(ioIrql);
  1733. if (notificationIrp) {
  1734. SmartcardDebug(
  1735. DEBUG_INFO,
  1736. ("%s!TLP3CompleteCardTracking: Completing NotificationIrp %lxh\n",
  1737. DRIVER_NAME,
  1738. notificationIrp)
  1739. );
  1740. // finish the request
  1741. if (notificationIrp->Cancel) {
  1742. notificationIrp->IoStatus.Status = STATUS_CANCELLED;
  1743. } else {
  1744. notificationIrp->IoStatus.Status = STATUS_SUCCESS;
  1745. }
  1746. notificationIrp->IoStatus.Information = 0;
  1747. IoCompleteRequest(
  1748. notificationIrp,
  1749. IO_NO_INCREMENT
  1750. );
  1751. }
  1752. }
  1753. NTSTATUS
  1754. TLP3SerialEvent(
  1755. IN PDEVICE_OBJECT DeviceObject,
  1756. IN PIRP Irp,
  1757. IN PSMARTCARD_EXTENSION SmartcardExtension
  1758. )
  1759. /*++
  1760. Routine Description:
  1761. This routine is called in two cases:
  1762. a) CTS changed (card inserted or removed) or
  1763. b) DSR changed (reader has been removed)
  1764. For a) we update the card status and complete outstanding
  1765. card tracking requests.
  1766. For b) we start to unload the driver
  1767. NOTE: This function calls itself using IoCompletion. In the 'first'
  1768. callback the serial driver only tells us that something has changed.
  1769. We set up a call for 'what has changed' (GetModemStatus) which then
  1770. call this function again.
  1771. When we updated everything and we don't unload the driver card
  1772. tracking is started again.
  1773. --*/
  1774. {
  1775. NTSTATUS status;
  1776. KIRQL irql;
  1777. KeAcquireSpinLock(
  1778. &SmartcardExtension->OsData->SpinLock,
  1779. &irql
  1780. );
  1781. if (SmartcardExtension->ReaderExtension->GetModemStatus) {
  1782. //
  1783. // This function requested the modem status previously.
  1784. // As part of the io-completion, this function is then
  1785. // called again. When we're here we can read the actual
  1786. // modem-status to figure out if the card is in the reader
  1787. //
  1788. if ((SmartcardExtension->ReaderExtension->ModemStatus & SERIAL_DSR_STATE) == 0) {
  1789. SmartcardDebug(
  1790. DEBUG_INFO,
  1791. ("%s!TLP3SerialEvent: Reader removed\n",
  1792. DRIVER_NAME)
  1793. );
  1794. //
  1795. // We set the mask to zero to signal that we can
  1796. // release the irp that we use for the serial events
  1797. //
  1798. SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask = 0;
  1799. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_UNKNOWN;
  1800. } else {
  1801. if (SmartcardExtension->ReaderExtension->ModemStatus & SERIAL_CTS_STATE) {
  1802. // Card is inserted
  1803. SmartcardExtension->ReaderCapabilities.CurrentState =
  1804. SCARD_SWALLOWED;
  1805. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1806. SCARD_PROTOCOL_UNDEFINED;
  1807. SmartcardDebug(
  1808. DEBUG_INFO,
  1809. ("%s!TLP3SerialEvent: Smart card inserted\n",
  1810. DRIVER_NAME)
  1811. );
  1812. } else {
  1813. // Card is removed
  1814. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  1815. SmartcardExtension->ReaderCapabilities.CurrentState =
  1816. SCARD_ABSENT;
  1817. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1818. SCARD_PROTOCOL_UNDEFINED;
  1819. SmartcardDebug(
  1820. DEBUG_INFO,
  1821. ("%s!TLP3SerialEvent: Smart card removed\n",
  1822. DRIVER_NAME)
  1823. );
  1824. }
  1825. }
  1826. }
  1827. KeReleaseSpinLock(
  1828. &SmartcardExtension->OsData->SpinLock,
  1829. irql
  1830. );
  1831. //
  1832. // Only inform the user of a card insertion/removal event
  1833. // if this function isn't called due to a power down - power up cycle
  1834. //
  1835. if (SmartcardExtension->ReaderExtension->PowerRequest == FALSE) {
  1836. TLP3CompleteCardTracking(SmartcardExtension);
  1837. }
  1838. // The wait mask is set to 0 when the driver unloads
  1839. if (SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask == 0) {
  1840. // The reader has been unplugged.
  1841. PDEVICE_EXTENSION deviceExtension =
  1842. SmartcardExtension->OsData->DeviceObject->DeviceExtension;
  1843. // schedule our remove thread
  1844. IoQueueWorkItem(
  1845. deviceExtension->CloseSerial,
  1846. (PIO_WORKITEM_ROUTINE) TLP3CloseSerialPort,
  1847. DelayedWorkQueue,
  1848. NULL
  1849. );
  1850. SmartcardDebug(
  1851. DEBUG_TRACE,
  1852. ("%s!TLP3SerialEvent: Exit (Release IRP)\n",
  1853. DRIVER_NAME)
  1854. );
  1855. //
  1856. // We don't need the IRP anymore, so free it and tell the
  1857. // io subsystem not to touch it anymore by returning the value below
  1858. //
  1859. IoFreeIrp(Irp);
  1860. return STATUS_MORE_PROCESSING_REQUIRED;
  1861. }
  1862. if (SmartcardExtension->ReaderExtension->GetModemStatus == FALSE) {
  1863. //
  1864. // Setup call for device control to get modem status.
  1865. // The CTS signal tells us if the card is inserted or removed.
  1866. // CTS is high if the card is inserted.
  1867. //
  1868. PIO_STACK_LOCATION irpStack;
  1869. irpStack = IoGetNextIrpStackLocation(
  1870. SmartcardExtension->ReaderExtension->SerialStatusIrp
  1871. );
  1872. irpStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
  1873. irpStack->MinorFunction = 0UL;
  1874. irpStack->Parameters.DeviceIoControl.OutputBufferLength =
  1875. sizeof(SmartcardExtension->ReaderExtension->ModemStatus);
  1876. irpStack->Parameters.DeviceIoControl.IoControlCode =
  1877. IOCTL_SERIAL_GET_MODEMSTATUS;
  1878. SmartcardExtension->ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer =
  1879. &SmartcardExtension->ReaderExtension->ModemStatus;
  1880. SmartcardExtension->ReaderExtension->GetModemStatus = TRUE;
  1881. } else {
  1882. PIO_STACK_LOCATION irpStack;
  1883. // Setup call for device control to wait for a serial event
  1884. irpStack = IoGetNextIrpStackLocation(
  1885. SmartcardExtension->ReaderExtension->SerialStatusIrp
  1886. );
  1887. #if defined (DEBUG) && defined (DETECT_SERIAL_OVERRUNS)
  1888. if (Irp->IoStatus.Status != STATUS_SUCCESS) {
  1889. //
  1890. // we need to call the serial driver to reset the internal
  1891. // error counters, otherwise the serial driver refuses to work
  1892. //
  1893. static SERIAL_STATUS serialStatus;
  1894. SmartcardDebug(
  1895. DEBUG_ERROR,
  1896. ( "%s!TLP3SerialEvent: Reset of serial error condition...\n",
  1897. DRIVER_NAME)
  1898. );
  1899. irpStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
  1900. irpStack->MinorFunction = 0UL;
  1901. irpStack->Parameters.DeviceIoControl.OutputBufferLength =
  1902. sizeof(serialStatus);
  1903. irpStack->Parameters.DeviceIoControl.IoControlCode =
  1904. IOCTL_SERIAL_GET_COMMSTATUS;
  1905. SmartcardExtension->ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer =
  1906. &serialStatus;
  1907. } else
  1908. #endif
  1909. {
  1910. irpStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
  1911. irpStack->MinorFunction = 0UL;
  1912. irpStack->Parameters.DeviceIoControl.OutputBufferLength =
  1913. sizeof(SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask);
  1914. irpStack->Parameters.DeviceIoControl.IoControlCode =
  1915. IOCTL_SERIAL_WAIT_ON_MASK;
  1916. SmartcardExtension->ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer =
  1917. &SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask;
  1918. }
  1919. SmartcardExtension->ReaderExtension->GetModemStatus = FALSE;
  1920. }
  1921. IoSetCompletionRoutine(
  1922. SmartcardExtension->ReaderExtension->SerialStatusIrp,
  1923. TLP3SerialEvent,
  1924. SmartcardExtension,
  1925. TRUE,
  1926. TRUE,
  1927. TRUE
  1928. );
  1929. status = IoCallDriver(
  1930. SmartcardExtension->ReaderExtension->AttachedDeviceObject,
  1931. SmartcardExtension->ReaderExtension->SerialStatusIrp
  1932. );
  1933. return STATUS_MORE_PROCESSING_REQUIRED;
  1934. }