Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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