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.

2045 lines
55 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) SCM Microsystems, 1998 - 1999
  6. //
  7. // File: drvnt5.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "DriverNT.h"
  11. #include "DrvNT5.h"
  12. #include "CBHndlr.h"
  13. #include "STCCmd.h"
  14. #include "SRVers.h"
  15. // declare pageable/initialization code
  16. #pragma alloc_text( INIT, DriverEntry )
  17. #pragma alloc_text( PAGEABLE, DrvAddDevice )
  18. #pragma alloc_text( PAGEABLE, DrvCreateDevice )
  19. #pragma alloc_text( PAGEABLE, DrvRemoveDevice )
  20. #pragma alloc_text( PAGEABLE, DrvDriverUnload )
  21. //________________________________ D R I V E R E N T R Y ________________________________________
  22. NTSTATUS
  23. DriverEntry(
  24. IN PDRIVER_OBJECT DriverObject,
  25. IN PUNICODE_STRING RegistryPath
  26. )
  27. /*++
  28. Routine Description:
  29. Arguments:
  30. Return Value:
  31. --*/
  32. {
  33. NTSTATUS NTStatus = STATUS_SUCCESS;
  34. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!DriverEntry: Enter\n"));
  35. // initialization of the drivers entry points
  36. DriverObject->DriverUnload = DrvDriverUnload;
  37. DriverObject->MajorFunction[IRP_MJ_CREATE] = DrvCreateClose;
  38. DriverObject->MajorFunction[IRP_MJ_CLOSE] = DrvCreateClose;
  39. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DrvCleanup;
  40. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DrvDeviceIoControl;
  41. DriverObject->MajorFunction[IRP_MJ_PNP] = DrvPnPHandler;
  42. DriverObject->MajorFunction[IRP_MJ_POWER] = DrvPowerHandler;
  43. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DrvSystemControl;
  44. DriverObject->DriverExtension->AddDevice = DrvAddDevice;
  45. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!DriverEntry: Exit\n"));
  46. return( NTStatus );
  47. }
  48. //________________________________ I N I T I A L I Z A T I O N ____________________________________
  49. NTSTATUS
  50. DrvAddDevice(
  51. IN PDRIVER_OBJECT DriverObject,
  52. IN PDEVICE_OBJECT PhysicalDeviceObject
  53. )
  54. /*++
  55. Routine Description:
  56. Arguments:
  57. Return Value:
  58. --*/
  59. {
  60. PDEVICE_OBJECT DeviceObject = NULL;
  61. NTSTATUS NTStatus = STATUS_SUCCESS;
  62. ULONG deviceInstance;
  63. UNICODE_STRING vendorNameU, ifdTypeU;
  64. ANSI_STRING vendorNameA, ifdTypeA;
  65. HANDLE regKey = NULL;
  66. // this is a list of our supported data rates
  67. static ULONG dataRatesSupported[] = {
  68. 9600, 19200, 28800, 38400, 48000, 57600, 67200, 76800, 86400, 96000, 115200
  69. };
  70. PAGED_CODE();
  71. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvAddDevice: Enter\n" ));
  72. __try
  73. {
  74. PDEVICE_EXTENSION DeviceExtension;
  75. PSMARTCARD_EXTENSION SmartcardExtension;
  76. PREADER_EXTENSION ReaderExtension;
  77. RTL_QUERY_REGISTRY_TABLE parameters[3];
  78. RtlZeroMemory(parameters, sizeof(parameters));
  79. RtlZeroMemory(&vendorNameU, sizeof(vendorNameU));
  80. RtlZeroMemory(&ifdTypeU, sizeof(ifdTypeU));
  81. RtlZeroMemory(&vendorNameA, sizeof(vendorNameA));
  82. RtlZeroMemory(&ifdTypeA, sizeof(ifdTypeA));
  83. // create the device object
  84. NTStatus = IoCreateDevice(
  85. DriverObject,
  86. sizeof( DEVICE_EXTENSION ),
  87. NULL,
  88. FILE_DEVICE_SMARTCARD,
  89. 0,
  90. TRUE,
  91. &DeviceObject
  92. );
  93. if( NTStatus != STATUS_SUCCESS )
  94. {
  95. SmartcardLogError( DriverObject, STC_CANT_CREATE_DEVICE, NULL, 0 );
  96. __leave;
  97. }
  98. // initialize device extension
  99. DeviceExtension = DeviceObject->DeviceExtension;
  100. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  101. KeInitializeEvent(
  102. &DeviceExtension->ReaderStarted,
  103. NotificationEvent,
  104. FALSE
  105. );
  106. // Used to keep track of open close calls
  107. DeviceExtension->ReaderOpen = FALSE;
  108. KeInitializeSpinLock(&DeviceExtension->SpinLock);
  109. // initialize smartcard extension - version & callbacks
  110. SmartcardExtension->Version = SMCLIB_VERSION;
  111. SmartcardExtension->ReaderFunction[RDF_TRANSMIT] = CBTransmit;
  112. SmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = CBSetProtocol;
  113. SmartcardExtension->ReaderFunction[RDF_CARD_POWER] = CBCardPower;
  114. SmartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = CBCardTracking;
  115. // initialize smartcard extension - vendor attribute
  116. RtlCopyMemory(
  117. SmartcardExtension->VendorAttr.VendorName.Buffer,
  118. SR_VENDOR_NAME,
  119. sizeof( SR_VENDOR_NAME )
  120. );
  121. SmartcardExtension->VendorAttr.VendorName.Length =
  122. sizeof( SR_VENDOR_NAME );
  123. RtlCopyMemory(
  124. SmartcardExtension->VendorAttr.IfdType.Buffer,
  125. SR_PRODUCT_NAME,
  126. sizeof( SR_PRODUCT_NAME )
  127. );
  128. SmartcardExtension->VendorAttr.IfdType.Length =
  129. sizeof( SR_PRODUCT_NAME );
  130. SmartcardExtension->VendorAttr.UnitNo = MAXULONG;
  131. for (deviceInstance = 0; deviceInstance < MAXULONG; deviceInstance++) {
  132. PDEVICE_OBJECT devObj;
  133. for (devObj = DeviceObject;
  134. devObj != NULL;
  135. devObj = devObj->NextDevice) {
  136. PDEVICE_EXTENSION devExt = devObj->DeviceExtension;
  137. PSMARTCARD_EXTENSION smcExt = &devExt->SmartcardExtension;
  138. if (deviceInstance == smcExt->VendorAttr.UnitNo) {
  139. break;
  140. }
  141. }
  142. if (devObj == NULL) {
  143. SmartcardExtension->VendorAttr.UnitNo = deviceInstance;
  144. break;
  145. }
  146. }
  147. SmartcardExtension->VendorAttr.IfdVersion.BuildNumber = 0;
  148. // initialize smartcard extension - reader capabilities
  149. SmartcardExtension->ReaderCapabilities.SupportedProtocols =
  150. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  151. SmartcardExtension->ReaderCapabilities.ReaderType =
  152. SCARD_READER_TYPE_SERIAL;
  153. SmartcardExtension->ReaderCapabilities.MechProperties = 0;
  154. SmartcardExtension->ReaderCapabilities.Channel = 0;
  155. SmartcardExtension->ReaderCapabilities.MaxIFSD =
  156. STC_BUFFER_SIZE - PACKET_OVERHEAD;
  157. SmartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3571;
  158. SmartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3571;
  159. SmartcardExtension->ReaderCapabilities.DataRate.Default =
  160. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  161. dataRatesSupported[0];
  162. // reader could support higher data rates
  163. SmartcardExtension->ReaderCapabilities.DataRatesSupported.List =
  164. dataRatesSupported;
  165. SmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
  166. sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
  167. SmartcardExtension->ReaderCapabilities.CurrentState = (ULONG) SCARD_UNKNOWN;
  168. SmartcardExtension->SmartcardRequest.BufferSize = MIN_BUFFER_SIZE;
  169. SmartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
  170. // allocate & initialize reader extension
  171. SmartcardExtension->ReaderExtension = ExAllocatePool(
  172. NonPagedPool,
  173. sizeof( READER_EXTENSION )
  174. );
  175. if( SmartcardExtension->ReaderExtension == NULL )
  176. {
  177. SmartcardLogError( DriverObject, STC_NO_MEMORY, NULL, 0 );
  178. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  179. __leave;
  180. }
  181. ReaderExtension = SmartcardExtension->ReaderExtension;
  182. ASSERT( ReaderExtension != NULL );
  183. RtlZeroMemory(ReaderExtension, sizeof( READER_EXTENSION ));
  184. ReaderExtension->SmartcardExtension = SmartcardExtension;
  185. ReaderExtension->ReadTimeout = 5000;
  186. KeInitializeEvent(
  187. &ReaderExtension->SerialCloseDone,
  188. NotificationEvent,
  189. TRUE
  190. );
  191. ReaderExtension->CloseSerial = IoAllocateWorkItem(
  192. DeviceObject
  193. );
  194. ReaderExtension->ReadWorkItem = IoAllocateWorkItem(
  195. DeviceObject
  196. );
  197. if (ReaderExtension->CloseSerial == NULL ||
  198. ReaderExtension->ReadWorkItem == NULL) {
  199. NTStatus = STATUS_INSUFFICIENT_RESOURCES;
  200. __leave;
  201. }
  202. KeInitializeEvent(
  203. &ReaderExtension->DataAvailable,
  204. NotificationEvent,
  205. FALSE
  206. );
  207. KeInitializeEvent(
  208. &ReaderExtension->IoEvent,
  209. NotificationEvent,
  210. FALSE
  211. );
  212. NTStatus = SmartcardInitialize( SmartcardExtension );
  213. if( NTStatus != STATUS_SUCCESS )
  214. {
  215. SmartcardLogError(
  216. DriverObject,
  217. (SmartcardExtension->OsData ? STC_WRONG_LIB_VERSION : STC_NO_MEMORY ),
  218. NULL,
  219. 0
  220. );
  221. __leave;
  222. }
  223. // Save deviceObject
  224. SmartcardExtension->OsData->DeviceObject = DeviceObject;
  225. // save the current Power state of the reader
  226. SmartcardExtension->ReaderExtension->ReaderPowerState = PowerReaderWorking;
  227. DeviceExtension = DeviceObject->DeviceExtension;
  228. ReaderExtension = DeviceExtension->SmartcardExtension.ReaderExtension;
  229. // attach the device object to the physical device object
  230. ReaderExtension->SerialDeviceObject =
  231. IoAttachDeviceToDeviceStack(
  232. DeviceObject,
  233. PhysicalDeviceObject
  234. );
  235. ASSERT( ReaderExtension->SerialDeviceObject != NULL );
  236. if( ReaderExtension->SerialDeviceObject == NULL )
  237. {
  238. SmartcardLogError(
  239. DriverObject,
  240. STC_CANT_CONNECT_TO_ASSIGNED_PORT,
  241. NULL,
  242. NTStatus
  243. );
  244. NTStatus = STATUS_UNSUCCESSFUL;
  245. __leave;
  246. }
  247. // register our new device
  248. NTStatus = IoRegisterDeviceInterface(
  249. PhysicalDeviceObject,
  250. &SmartCardReaderGuid,
  251. NULL,
  252. &DeviceExtension->PnPDeviceName
  253. );
  254. ASSERT( NTStatus == STATUS_SUCCESS );
  255. DeviceObject->Flags |= DO_BUFFERED_IO;
  256. DeviceObject->Flags |= DO_POWER_PAGABLE;
  257. DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  258. //
  259. // try to read the reader name from the registry
  260. // if that does not work, we will use the default
  261. // (hardcoded) name
  262. //
  263. if (IoOpenDeviceRegistryKey(
  264. PhysicalDeviceObject,
  265. PLUGPLAY_REGKEY_DEVICE,
  266. KEY_READ,
  267. &regKey
  268. ) != STATUS_SUCCESS) {
  269. __leave;
  270. }
  271. parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  272. parameters[0].Name = L"VendorName";
  273. parameters[0].EntryContext = &vendorNameU;
  274. parameters[0].DefaultType = REG_SZ;
  275. parameters[0].DefaultData = &vendorNameU;
  276. parameters[0].DefaultLength = 0;
  277. parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  278. parameters[1].Name = L"IfdType";
  279. parameters[1].EntryContext = &ifdTypeU;
  280. parameters[1].DefaultType = REG_SZ;
  281. parameters[1].DefaultData = &ifdTypeU;
  282. parameters[1].DefaultLength = 0;
  283. if (RtlQueryRegistryValues(
  284. RTL_REGISTRY_HANDLE,
  285. (PWSTR) regKey,
  286. parameters,
  287. NULL,
  288. NULL
  289. ) != STATUS_SUCCESS) {
  290. __leave;
  291. }
  292. if (RtlUnicodeStringToAnsiString(
  293. &vendorNameA,
  294. &vendorNameU,
  295. TRUE
  296. ) != STATUS_SUCCESS) {
  297. __leave;
  298. }
  299. if (RtlUnicodeStringToAnsiString(
  300. &ifdTypeA,
  301. &ifdTypeU,
  302. TRUE
  303. ) != STATUS_SUCCESS) {
  304. __leave;
  305. }
  306. if (vendorNameA.Length == 0 ||
  307. vendorNameA.Length > MAXIMUM_ATTR_STRING_LENGTH ||
  308. ifdTypeA.Length == 0 ||
  309. ifdTypeA.Length > MAXIMUM_ATTR_STRING_LENGTH) {
  310. __leave;
  311. }
  312. RtlCopyMemory(
  313. SmartcardExtension->VendorAttr.VendorName.Buffer,
  314. vendorNameA.Buffer,
  315. vendorNameA.Length
  316. );
  317. SmartcardExtension->VendorAttr.VendorName.Length =
  318. vendorNameA.Length;
  319. RtlCopyMemory(
  320. SmartcardExtension->VendorAttr.IfdType.Buffer,
  321. ifdTypeA.Buffer,
  322. ifdTypeA.Length
  323. );
  324. SmartcardExtension->VendorAttr.IfdType.Length =
  325. ifdTypeA.Length;
  326. }
  327. __finally
  328. {
  329. if (vendorNameU.Buffer) {
  330. RtlFreeUnicodeString(&vendorNameU);
  331. }
  332. if (ifdTypeU.Buffer) {
  333. RtlFreeUnicodeString(&ifdTypeU);
  334. }
  335. if (vendorNameA.Buffer) {
  336. RtlFreeAnsiString(&vendorNameA);
  337. }
  338. if (ifdTypeA.Buffer) {
  339. RtlFreeAnsiString(&ifdTypeA);
  340. }
  341. if (regKey != NULL) {
  342. ZwClose(regKey);
  343. }
  344. if (NTStatus != STATUS_SUCCESS) {
  345. DrvRemoveDevice( DeviceObject );
  346. }
  347. SmartcardDebug(
  348. DEBUG_TRACE,
  349. ( "SCMSTCS!DrvAddDevice: Exit (%lx)\n", NTStatus )
  350. );
  351. }
  352. return NTStatus;
  353. }
  354. NTSTATUS
  355. DrvStartDevice(
  356. IN PDEVICE_OBJECT DeviceObject
  357. )
  358. /*++
  359. Routine Description:
  360. Arguments:
  361. Return Value:
  362. --*/
  363. {
  364. NTSTATUS NTStatus;
  365. PIRP Irp;
  366. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvStartDevice: Enter\n" ));
  367. Irp = IoAllocateIrp((CCHAR)( DeviceObject->StackSize + 1 ), FALSE );
  368. ASSERT( Irp != NULL );
  369. if( Irp != NULL )
  370. {
  371. PDEVICE_EXTENSION DeviceExtension;
  372. PIO_STACK_LOCATION IrpStack;
  373. IO_STATUS_BLOCK IoStatusBlock;
  374. PSMARTCARD_EXTENSION SmartcardExtension;
  375. PREADER_EXTENSION ReaderExtension;
  376. DeviceExtension = DeviceObject->DeviceExtension;
  377. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  378. ReaderExtension = SmartcardExtension->ReaderExtension;
  379. ASSERT( DeviceExtension != NULL );
  380. ASSERT( SmartcardExtension != NULL );
  381. ASSERT( ReaderExtension != NULL );
  382. KeClearEvent( &ReaderExtension->SerialCloseDone );
  383. //
  384. // send MJ_CREATE to the serial driver. a side effect of this call is that the serial
  385. // enumerator will be informed about the device and not longer poll the interface
  386. //
  387. Irp->UserIosb = &IoStatusBlock;
  388. IoSetNextIrpStackLocation( Irp );
  389. IrpStack = IoGetCurrentIrpStackLocation( Irp );
  390. IrpStack->MajorFunction = IRP_MJ_CREATE;
  391. IrpStack->Parameters.Create.Options = 0;
  392. IrpStack->Parameters.Create.ShareAccess = 0;
  393. IrpStack->Parameters.Create.FileAttributes = 0;
  394. IrpStack->Parameters.Create.EaLength = 0;
  395. NTStatus = DrvCallSerialDriver(
  396. ReaderExtension->SerialDeviceObject,
  397. Irp
  398. );
  399. if( NTStatus == STATUS_SUCCESS )
  400. {
  401. SERIAL_PORT_CONFIG COMConfig;
  402. // configure the serial port
  403. COMConfig.BaudRate.BaudRate = SR_BAUD_RATE;
  404. COMConfig.LineControl.StopBits = SR_STOP_BITS;
  405. COMConfig.LineControl.Parity = SR_PARITY;
  406. COMConfig.LineControl.WordLength = SR_DATA_LENGTH;
  407. // timeouts
  408. COMConfig.Timeouts.ReadIntervalTimeout =
  409. SR_READ_INTERVAL_TIMEOUT;
  410. COMConfig.Timeouts.ReadTotalTimeoutConstant =
  411. SR_READ_TOTAL_TIMEOUT_CONSTANT;
  412. COMConfig.Timeouts.ReadTotalTimeoutMultiplier = 0;
  413. COMConfig.Timeouts.WriteTotalTimeoutConstant =
  414. SR_WRITE_TOTAL_TIMEOUT_CONSTANT;
  415. COMConfig.Timeouts.WriteTotalTimeoutMultiplier = 0;
  416. // special characters
  417. COMConfig.SerialChars.ErrorChar = 0;
  418. COMConfig.SerialChars.EofChar = 0;
  419. COMConfig.SerialChars.EventChar = 0;
  420. COMConfig.SerialChars.XonChar = 0;
  421. COMConfig.SerialChars.XoffChar = 0;
  422. COMConfig.SerialChars.BreakChar = 0;
  423. // handflow
  424. COMConfig.HandFlow.XonLimit = 0;
  425. COMConfig.HandFlow.XoffLimit = 0;
  426. COMConfig.HandFlow.ControlHandShake = 0;
  427. COMConfig.HandFlow.FlowReplace =
  428. SERIAL_XOFF_CONTINUE;
  429. // miscellenaeous
  430. COMConfig.WaitMask = SR_NOTIFICATION_EVENT;
  431. COMConfig.Purge = SR_PURGE;
  432. NTStatus = IFInitializeInterface( ReaderExtension, &COMConfig );
  433. if( NTStatus == STATUS_SUCCESS )
  434. {
  435. // configure the reader & initialize the card state
  436. NTStatus = STCConfigureSTC(
  437. ReaderExtension,
  438. ( PSTC_REGISTER ) STCInitialize
  439. );
  440. CBUpdateCardState( SmartcardExtension, SCARD_UNKNOWN );
  441. //
  442. // store firmware revision in ifd version
  443. //
  444. STCGetFirmwareRevision( ReaderExtension );
  445. SmartcardExtension->VendorAttr.IfdVersion.VersionMajor =
  446. ReaderExtension->FirmwareMajor;
  447. SmartcardExtension->VendorAttr.IfdVersion.VersionMinor =
  448. ReaderExtension->FirmwareMinor;
  449. SmartcardExtension->VendorAttr.IfdSerialNo.Length = 0;
  450. if( NTStatus == STATUS_SUCCESS )
  451. {
  452. NTStatus = IoSetDeviceInterfaceState(
  453. &DeviceExtension->PnPDeviceName,
  454. TRUE
  455. );
  456. if( NTStatus == STATUS_SUCCESS )
  457. {
  458. KeSetEvent( &DeviceExtension->ReaderStarted, 0, FALSE );
  459. }
  460. }
  461. else
  462. {
  463. SmartcardLogError( DeviceObject, STC_NO_READER_FOUND, NULL, 0 );
  464. }
  465. }
  466. else
  467. {
  468. SmartcardLogError( DeviceObject, STC_ERROR_INIT_INTERFACE, NULL, 0 );
  469. }
  470. }
  471. else
  472. {
  473. SmartcardLogError( DeviceObject, STC_CONNECT_FAILS, NULL, 0 );
  474. }
  475. IoFreeIrp( Irp );
  476. }
  477. else
  478. {
  479. SmartcardLogError( DeviceObject, STC_NO_MEMORY, NULL, 0 );
  480. NTStatus = STATUS_NO_MEMORY;
  481. }
  482. if (NTStatus != STATUS_SUCCESS) {
  483. DrvStopDevice(DeviceObject->DeviceExtension);
  484. }
  485. SmartcardDebug(
  486. (NTStatus == STATUS_SUCCESS ? DEBUG_TRACE : DEBUG_ERROR),
  487. ( "SCMSTCS!DrvStartDevice: Exit %lx\n",
  488. NTStatus )
  489. );
  490. return( NTStatus );
  491. }
  492. //________________________________________ U N L O A D ____________________________________________
  493. VOID
  494. DrvStopDevice(
  495. IN PDEVICE_EXTENSION DeviceExtension
  496. )
  497. /*++
  498. Routine Description:
  499. Arguments:
  500. Return Value:
  501. --*/
  502. {
  503. PSMARTCARD_EXTENSION SmartcardExtension;
  504. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvStopDevice: Enter\n" ));
  505. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  506. if( KeReadStateEvent( &SmartcardExtension->ReaderExtension->SerialCloseDone ) == 0l )
  507. {
  508. NTSTATUS NTStatus;
  509. ULONG WaitMask;
  510. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvStopDevice: Power Down\n" ));
  511. // power down the reader
  512. STCConfigureSTC(
  513. SmartcardExtension->ReaderExtension,
  514. ( PSTC_REGISTER ) STCClose
  515. );
  516. // the following delay is neccessary to make sure the last read operation is completed
  517. // and a IOCTL_SERIAL_WAIT_ON_MASK is started
  518. SysDelay( 2 * SR_READ_TOTAL_TIMEOUT_CONSTANT );
  519. //
  520. // no more event notification neccessary. a side effect is the
  521. // finishing of all pending notification irp's by the serial driver,
  522. // so the callback will complete the irp & initiate the close of the
  523. // connection to the serial driver
  524. //
  525. WaitMask = 0;
  526. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!Set Wait Mask\n" ));
  527. NTStatus = IFSerialIoctl(
  528. SmartcardExtension->ReaderExtension,
  529. IOCTL_SERIAL_SET_WAIT_MASK,
  530. &WaitMask,
  531. sizeof( ULONG ),
  532. NULL,
  533. 0
  534. );
  535. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!Wait For Done\n" ));
  536. // wait until the connetion to the serial driver is closed
  537. NTStatus = KeWaitForSingleObject(
  538. &SmartcardExtension->ReaderExtension->SerialCloseDone,
  539. Executive,
  540. KernelMode,
  541. FALSE,
  542. NULL
  543. );
  544. }
  545. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvStopDevice: Exit\n" ));
  546. }
  547. VOID
  548. DrvRemoveDevice(
  549. PDEVICE_OBJECT DeviceObject
  550. )
  551. /*++
  552. Routine Description:
  553. Arguments:
  554. Return Value:
  555. --*/
  556. {
  557. NTSTATUS NTStatus;
  558. PDEVICE_EXTENSION DeviceExtension;
  559. PSMARTCARD_EXTENSION SmartcardExtension;
  560. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvRemoveDevice: Enter\n" ));
  561. PAGED_CODE();
  562. if( DeviceObject != NULL )
  563. {
  564. DeviceExtension = DeviceObject->DeviceExtension;
  565. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  566. DrvStopDevice( DeviceExtension );
  567. if( SmartcardExtension->OsData )
  568. {
  569. ASSERT( SmartcardExtension->OsData->NotificationIrp == NULL );
  570. // Wait until we can safely unload the device
  571. SmartcardReleaseRemoveLockAndWait( SmartcardExtension );
  572. }
  573. if( SmartcardExtension->ReaderExtension->SerialDeviceObject )
  574. {
  575. IoDetachDevice( SmartcardExtension->ReaderExtension->SerialDeviceObject );
  576. }
  577. if( DeviceExtension->PnPDeviceName.Buffer != NULL )
  578. {
  579. RtlFreeUnicodeString( &DeviceExtension->PnPDeviceName );
  580. }
  581. if( SmartcardExtension->OsData != NULL )
  582. {
  583. SmartcardExit( SmartcardExtension );
  584. }
  585. if( SmartcardExtension->ReaderExtension != NULL )
  586. {
  587. if (SmartcardExtension->ReaderExtension->CloseSerial != NULL) {
  588. IoFreeWorkItem(SmartcardExtension->ReaderExtension->CloseSerial);
  589. }
  590. if (SmartcardExtension->ReaderExtension->ReadWorkItem != NULL) {
  591. IoFreeWorkItem(SmartcardExtension->ReaderExtension->ReadWorkItem);
  592. }
  593. ExFreePool( SmartcardExtension->ReaderExtension );
  594. }
  595. IoDeleteDevice( DeviceObject );
  596. }
  597. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvRemoveDevice: Exit\n" ));
  598. }
  599. VOID
  600. DrvDriverUnload(
  601. IN PDRIVER_OBJECT DriverObject
  602. )
  603. /*++
  604. Routine Description:
  605. Arguments:
  606. Return Value:
  607. --*/
  608. {
  609. PDEVICE_OBJECT DeviceObject;
  610. NTSTATUS NTStatus;
  611. PAGED_CODE();
  612. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvDriverUnload: Enter\n" ));
  613. // just make sure that all device instances have been unloaded
  614. while( DeviceObject = DriverObject->DeviceObject )
  615. {
  616. DrvRemoveDevice( DeviceObject );
  617. } while( DeviceObject = DriverObject->DeviceObject );
  618. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvDriverUnload: Exit\n" ));
  619. }
  620. NTSTATUS
  621. DrvSystemControl(
  622. IN PDEVICE_OBJECT DeviceObject,
  623. IN PIRP Irp
  624. )
  625. /*++
  626. Routine Description:
  627. Arguments:
  628. DeviceObject - Pointer to device object for this miniport
  629. Irp - IRP involved.
  630. Return Value:
  631. STATUS_SUCCESS.
  632. --*/
  633. {
  634. PDEVICE_EXTENSION DeviceExtension;
  635. PSMARTCARD_EXTENSION SmartcardExtension;
  636. PREADER_EXTENSION ReaderExtension;
  637. NTSTATUS status = STATUS_SUCCESS;
  638. DeviceExtension = DeviceObject->DeviceExtension;
  639. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  640. ReaderExtension = SmartcardExtension->ReaderExtension;
  641. IoSkipCurrentIrpStackLocation(Irp);
  642. status = IoCallDriver(ReaderExtension->SerialDeviceObject, Irp);
  643. return status;
  644. }
  645. //______________________________ D E V I C E I O C O N T R O L ________________________________
  646. NTSTATUS
  647. DrvCreateClose(
  648. IN PDEVICE_OBJECT DeviceObject,
  649. IN PIRP Irp
  650. )
  651. /*++
  652. Routine Description:
  653. This routine is called by the I/O system when the device is opened or closed.
  654. Arguments:
  655. DeviceObject - Pointer to device object for this miniport
  656. Irp - IRP involved.
  657. Return Value:
  658. STATUS_SUCCESS.
  659. --*/
  660. {
  661. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  662. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  663. NTSTATUS status = STATUS_SUCCESS;
  664. __try {
  665. if (irpStack->MajorFunction == IRP_MJ_CREATE) {
  666. status = SmartcardAcquireRemoveLockWithTag(
  667. &deviceExtension->SmartcardExtension,
  668. 'lCrC'
  669. );
  670. if (status != STATUS_SUCCESS) {
  671. status = STATUS_DEVICE_REMOVED;
  672. __leave;
  673. }
  674. // test if the device has been opened already
  675. if (InterlockedCompareExchange(
  676. &deviceExtension->ReaderOpen,
  677. TRUE,
  678. FALSE) == FALSE) {
  679. SmartcardDebug(
  680. DEBUG_DRIVER,
  681. ("%s!DrvCreateClose: Open\n",
  682. DRIVER_NAME)
  683. );
  684. } else {
  685. // the device is already in use
  686. status = STATUS_UNSUCCESSFUL;
  687. // release the lock
  688. SmartcardReleaseRemoveLockWithTag(
  689. &deviceExtension->SmartcardExtension,
  690. 'lCrC'
  691. );
  692. }
  693. } else {
  694. SmartcardDebug(
  695. DEBUG_DRIVER,
  696. ("%s!DrvCreateClose: Close\n",
  697. DRIVER_NAME)
  698. );
  699. SmartcardReleaseRemoveLockWithTag(
  700. &deviceExtension->SmartcardExtension,
  701. 'lCrC'
  702. );
  703. deviceExtension->ReaderOpen = FALSE;
  704. }
  705. }
  706. __finally {
  707. Irp->IoStatus.Status = status;
  708. Irp->IoStatus.Information = 0;
  709. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  710. }
  711. return status;
  712. }
  713. NTSTATUS
  714. DrvDeviceIoControl(
  715. PDEVICE_OBJECT DeviceObject,
  716. PIRP Irp
  717. )
  718. /*++
  719. Routine Description:
  720. Arguments:
  721. Return Value:
  722. --*/
  723. {
  724. NTSTATUS NTStatus=STATUS_SUCCESS;
  725. PDEVICE_EXTENSION DeviceExtension;
  726. PSMARTCARD_EXTENSION SmartcardExtension;
  727. KIRQL CurrentIrql;
  728. DeviceExtension = DeviceObject->DeviceExtension;
  729. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  730. if (KeReadStateEvent(&(SmartcardExtension->ReaderExtension->SerialCloseDone))) {
  731. //
  732. // we have no connection to serial, the device was either
  733. // surprise-removed or politely removed
  734. //
  735. NTStatus = STATUS_DEVICE_REMOVED;
  736. }
  737. if (NTStatus == STATUS_SUCCESS)
  738. {
  739. KeAcquireSpinLock( &DeviceExtension->SpinLock, &CurrentIrql );
  740. // make sure that the reader is already started
  741. if( DeviceExtension->IoCount == 0 )
  742. {
  743. KeReleaseSpinLock( &DeviceExtension->SpinLock, CurrentIrql );
  744. // wait until the pnp manager has started the device
  745. NTStatus = KeWaitForSingleObject(
  746. &DeviceExtension->ReaderStarted,
  747. Executive,
  748. KernelMode,
  749. FALSE,
  750. NULL
  751. );
  752. KeAcquireSpinLock( &DeviceExtension->SpinLock, &CurrentIrql );
  753. }
  754. DeviceExtension->IoCount++;
  755. KeReleaseSpinLock( &DeviceExtension->SpinLock, CurrentIrql );
  756. NTStatus = SmartcardAcquireRemoveLockWithTag(SmartcardExtension, 'tcoI');
  757. }
  758. if( NTStatus != STATUS_SUCCESS )
  759. {
  760. // if no remove lock can be acquired, the device has been removed
  761. Irp->IoStatus.Information = 0;
  762. Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
  763. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  764. NTStatus = STATUS_DEVICE_REMOVED;
  765. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvDeviceIoControl: the device has been removed\n" ));
  766. }
  767. else
  768. {
  769. // let the lib process the call
  770. NTStatus = SmartcardDeviceControl( SmartcardExtension, Irp );
  771. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'tcoI');
  772. KeAcquireSpinLock( &DeviceExtension->SpinLock, &CurrentIrql );
  773. DeviceExtension->IoCount--;
  774. KeReleaseSpinLock(&DeviceExtension->SpinLock, CurrentIrql);
  775. }
  776. return( NTStatus );
  777. }
  778. NTSTATUS
  779. DrvGenericIOCTL(
  780. PSMARTCARD_EXTENSION SmartcardExtension
  781. )
  782. /*++
  783. DrvGenericIOCTL:
  784. Performs generic callbacks to the reader
  785. Arguments:
  786. SmartcardExtension context of the call
  787. Return Value:
  788. STATUS_SUCCESS
  789. --*/
  790. {
  791. NTSTATUS NTStatus;
  792. PIRP Irp;
  793. PIO_STACK_LOCATION IrpStack;
  794. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvGenericIOCTL: Enter\n" ));
  795. // get pointer to current IRP stack location
  796. Irp = SmartcardExtension->OsData->CurrentIrp;
  797. IrpStack = IoGetCurrentIrpStackLocation( Irp );
  798. // assume error
  799. NTStatus = STATUS_INVALID_DEVICE_REQUEST;
  800. Irp->IoStatus.Information = 0;
  801. // dispatch IOCTL
  802. switch( IrpStack->Parameters.DeviceIoControl.IoControlCode )
  803. {
  804. case IOCTL_GET_VERSIONS:
  805. if( IrpStack->Parameters.DeviceIoControl.OutputBufferLength <
  806. sizeof( VERSION_CONTROL ))
  807. {
  808. NTStatus = STATUS_BUFFER_TOO_SMALL;
  809. }
  810. else
  811. {
  812. PVERSION_CONTROL VersionControl;
  813. VersionControl = (PVERSION_CONTROL)Irp->AssociatedIrp.SystemBuffer;
  814. VersionControl->SmclibVersion = SmartcardExtension->Version;
  815. VersionControl->DriverMajor = SCMSTCS_MAJOR_VERSION;
  816. VersionControl->DriverMinor = SCMSTCS_MINOR_VERSION;
  817. // update firmware version
  818. STCGetFirmwareRevision( SmartcardExtension->ReaderExtension );
  819. VersionControl->FirmwareMajor =
  820. SmartcardExtension->ReaderExtension->FirmwareMajor;
  821. VersionControl->FirmwareMinor =
  822. SmartcardExtension->ReaderExtension->FirmwareMinor;
  823. Irp->IoStatus.Information = sizeof( VERSION_CONTROL );
  824. NTStatus = STATUS_SUCCESS;
  825. }
  826. break;
  827. default:
  828. break;
  829. }
  830. // set status of the packet
  831. Irp->IoStatus.Status = NTStatus;
  832. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvGenericIOCTL: Exit\n" ));
  833. return( NTStatus );
  834. }
  835. NTSTATUS
  836. DrvCancel(
  837. IN PDEVICE_OBJECT DeviceObject,
  838. IN PIRP Irp
  839. )
  840. /*++
  841. Routine Description:
  842. This function is called whenever the caller wants to
  843. cancel a pending irp.
  844. Arguments:
  845. DeviceObject - Our device object
  846. Irp - the pending irp that we should cancel
  847. --*/
  848. {
  849. PDEVICE_EXTENSION DeviceExtension;
  850. PSMARTCARD_EXTENSION SmartcardExtension;
  851. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvCancel: Enter\n" ));
  852. DeviceExtension = DeviceObject->DeviceExtension;
  853. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  854. ASSERT( Irp == SmartcardExtension->OsData->NotificationIrp );
  855. Irp->IoStatus.Information = 0;
  856. Irp->IoStatus.Status = STATUS_CANCELLED;
  857. SmartcardExtension->OsData->NotificationIrp = NULL;
  858. IoReleaseCancelSpinLock( Irp->CancelIrql );
  859. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!Cancel Irp %lx\n", Irp ));
  860. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  861. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvCancel: Exit\n" ));
  862. return( STATUS_CANCELLED );
  863. }
  864. NTSTATUS
  865. DrvCleanup(
  866. IN PDEVICE_OBJECT DeviceObject,
  867. IN PIRP Irp
  868. )
  869. /*++
  870. Routine Description:
  871. This function is called, when the 'calling app' terminates (unexpectedly).
  872. We have to clean up all pending irps. In our case it can only be the
  873. notification irp.
  874. --*/
  875. {
  876. NTSTATUS NTStatus = STATUS_SUCCESS;
  877. PDEVICE_EXTENSION DeviceExtension;
  878. PSMARTCARD_EXTENSION SmartcardExtension;
  879. KIRQL CancelIrql;
  880. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvCleanup: Enter\n" ));
  881. DeviceExtension = DeviceObject->DeviceExtension;
  882. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  883. IoAcquireCancelSpinLock(&CancelIrql);
  884. ASSERT( Irp != SmartcardExtension->OsData->NotificationIrp );
  885. // cancel pending notification irps
  886. if( SmartcardExtension->OsData->NotificationIrp )
  887. {
  888. // reset the cancel function so that it won't be called anymore
  889. IoSetCancelRoutine(
  890. SmartcardExtension->OsData->NotificationIrp,
  891. NULL
  892. );
  893. SmartcardExtension->OsData->NotificationIrp->CancelIrql =
  894. CancelIrql;
  895. // DrvCancel will release the cancel spin lock
  896. DrvCancel(
  897. DeviceObject,
  898. SmartcardExtension->OsData->NotificationIrp
  899. );
  900. } else {
  901. IoReleaseCancelSpinLock(CancelIrql);
  902. }
  903. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!Completing Irp %lx\n", Irp ));
  904. // complete the irp that was passed to this function
  905. Irp->IoStatus.Information = 0;
  906. Irp->IoStatus.Status = STATUS_SUCCESS;
  907. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  908. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvCleanup: Exit\n" ));
  909. return( STATUS_SUCCESS );
  910. }
  911. VOID
  912. DrvWaitForDeviceRemoval(
  913. IN PDEVICE_OBJECT DeviceObject,
  914. IN PVOID Context
  915. )
  916. /*++
  917. Routine Description:
  918. Arguments:
  919. Return Value:
  920. --*/
  921. {
  922. NTSTATUS NTStatus;
  923. PDEVICE_EXTENSION DeviceExtension;
  924. PREADER_EXTENSION ReaderExtension;
  925. PIRP Irp;
  926. PIO_STACK_LOCATION IrpStack;
  927. IO_STATUS_BLOCK IoStatusBlock;
  928. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvWaitForDeviceRemoval: Enter\n" ));
  929. DeviceExtension = DeviceObject->DeviceExtension;
  930. ReaderExtension = DeviceExtension->SmartcardExtension.ReaderExtension;
  931. ASSERT( DeviceExtension != NULL );
  932. ASSERT( ReaderExtension != NULL );
  933. // mark the device as invalid, so no application can re-open it
  934. IoSetDeviceInterfaceState( &DeviceExtension->PnPDeviceName, FALSE );
  935. // close the connection to the serial driver
  936. Irp = IoAllocateIrp( (CCHAR)( DeviceObject->StackSize + 1 ), FALSE );
  937. ASSERT( Irp != NULL );
  938. if( Irp != NULL )
  939. {
  940. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!DrvWaitForDeviceRemoval: Sending IRP_MJ_CLOSE\n" ));
  941. IoSetNextIrpStackLocation( Irp );
  942. //
  943. // send MJ_CLOSE to the serial driver. a side effect of this call is that the serial
  944. // enumerator will be informed about changes at the COM port, so it will trigger the
  945. // appropriate pnp calls
  946. //
  947. Irp->UserIosb = &IoStatusBlock;
  948. IrpStack = IoGetCurrentIrpStackLocation( Irp );
  949. IrpStack->MajorFunction = IRP_MJ_CLOSE;
  950. NTStatus = DrvCallSerialDriver( ReaderExtension->SerialDeviceObject, Irp );
  951. IoFreeIrp( Irp );
  952. }
  953. // inform waiting threads that the close to the serial driver has finished
  954. KeSetEvent( &ReaderExtension->SerialCloseDone, 0, FALSE );
  955. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvWaitForDeviceRemoval: Exit\n" ));
  956. return;
  957. }
  958. NTSTATUS
  959. DrvIoCompletion (
  960. IN PDEVICE_OBJECT DeviceObject,
  961. IN PIRP Irp,
  962. IN PKEVENT Event
  963. )
  964. /*++
  965. Routine Description:
  966. Arguments:
  967. Return Value:
  968. --*/
  969. {
  970. UNREFERENCED_PARAMETER( DeviceObject );
  971. if( Irp->Cancel )
  972. {
  973. Irp->IoStatus.Status = STATUS_CANCELLED;
  974. }
  975. else
  976. {
  977. Irp->IoStatus.Status = STATUS_MORE_PROCESSING_REQUIRED;
  978. }
  979. KeSetEvent( Event, 0, FALSE );
  980. return( STATUS_MORE_PROCESSING_REQUIRED );
  981. }
  982. NTSTATUS
  983. DrvCallSerialDriver(
  984. IN PDEVICE_OBJECT DeviceObject,
  985. IN PIRP Irp
  986. )
  987. /*++
  988. Routine Description:
  989. Arguments:
  990. Return Value:
  991. --*/
  992. {
  993. NTSTATUS NTStatus = STATUS_SUCCESS;
  994. KEVENT Event;
  995. // copy the stack location of the actual call to the next position
  996. IoCopyCurrentIrpStackLocationToNext( Irp );
  997. // this event will be passed to the completion routine & signaled if the call
  998. // is finished
  999. KeInitializeEvent( &Event, NotificationEvent, FALSE );
  1000. // the DrvIoCompletion signals the event & keeps the irp alive by setting the
  1001. // status to STATUS_MORE_PROCESSING_REQUIRED
  1002. IoSetCompletionRoutine (
  1003. Irp,
  1004. DrvIoCompletion,
  1005. &Event,
  1006. TRUE,
  1007. TRUE,
  1008. TRUE
  1009. );
  1010. // call the appropriate driver
  1011. if( IoGetCurrentIrpStackLocation( Irp )->MajorFunction == IRP_MJ_POWER )
  1012. {
  1013. NTStatus = PoCallDriver( DeviceObject, Irp );
  1014. }
  1015. else
  1016. {
  1017. NTStatus = IoCallDriver( DeviceObject, Irp );
  1018. }
  1019. // wait until the irp was processed
  1020. if( NTStatus == STATUS_PENDING )
  1021. {
  1022. NTStatus = KeWaitForSingleObject(
  1023. &Event,
  1024. Executive,
  1025. KernelMode,
  1026. FALSE,
  1027. NULL
  1028. );
  1029. NTStatus = Irp->IoStatus.Status;
  1030. }
  1031. return( NTStatus );
  1032. }
  1033. //__________________________________ P L U G ' N ' P L A Y ________________________________________
  1034. NTSTATUS
  1035. DrvPnPHandler(
  1036. IN PDEVICE_OBJECT DeviceObject,
  1037. IN PIRP Irp
  1038. )
  1039. /*++
  1040. Routine Description:
  1041. Arguments:
  1042. Return Value:
  1043. --*/
  1044. {
  1045. NTSTATUS NTStatus = STATUS_SUCCESS;
  1046. PDEVICE_EXTENSION DeviceExtension;
  1047. PSMARTCARD_EXTENSION SmartcardExtension;
  1048. PREADER_EXTENSION ReaderExtension;
  1049. PAGED_CODE();
  1050. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvPnPDeviceControl: Enter\n" ));
  1051. DeviceExtension = DeviceObject->DeviceExtension;
  1052. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1053. ReaderExtension = SmartcardExtension->ReaderExtension;
  1054. NTStatus = SmartcardAcquireRemoveLockWithTag(SmartcardExtension, ' PnP');
  1055. if( NTStatus != STATUS_SUCCESS )
  1056. {
  1057. Irp->IoStatus.Information = 0;
  1058. Irp->IoStatus.Status = NTStatus;
  1059. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1060. }
  1061. else
  1062. {
  1063. PDEVICE_OBJECT AttachedDeviceObject;
  1064. BOOLEAN DeviceRemoved,
  1065. IrpSkipped;
  1066. AttachedDeviceObject = ReaderExtension->SerialDeviceObject;
  1067. DeviceRemoved = FALSE,
  1068. IrpSkipped = FALSE;
  1069. // dispatch on pnp minor function
  1070. switch( IoGetCurrentIrpStackLocation( Irp )->MinorFunction )
  1071. {
  1072. case IRP_MN_START_DEVICE:
  1073. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!IRP_MN_START_DEVICE\n" ));
  1074. // call the serial driver first to make sure the interface is ready
  1075. NTStatus = DrvCallSerialDriver(AttachedDeviceObject, Irp );
  1076. if( NT_SUCCESS(NTStatus))
  1077. {
  1078. NTStatus = DrvStartDevice(DeviceObject);
  1079. }
  1080. break;
  1081. case IRP_MN_QUERY_STOP_DEVICE:
  1082. {
  1083. KIRQL CurrentIrql;
  1084. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!IRP_MN_QUERY_STOP_DEVICE\n" ));
  1085. KeAcquireSpinLock(&DeviceExtension->SpinLock, &CurrentIrql );
  1086. if( DeviceExtension->IoCount > 0 )
  1087. {
  1088. // don't stop if any io requests are pending
  1089. KeReleaseSpinLock(&DeviceExtension->SpinLock, CurrentIrql );
  1090. NTStatus = STATUS_DEVICE_BUSY;
  1091. }
  1092. else
  1093. {
  1094. // don't allow further io requests
  1095. KeClearEvent( &DeviceExtension->ReaderStarted );
  1096. KeReleaseSpinLock( &DeviceExtension->SpinLock, CurrentIrql );
  1097. NTStatus = DrvCallSerialDriver( AttachedDeviceObject, Irp );
  1098. }
  1099. break;
  1100. }
  1101. case IRP_MN_CANCEL_STOP_DEVICE:
  1102. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!IRP_MN_CANCEL_STOP_DEVICE\n" ));
  1103. NTStatus = DrvCallSerialDriver( AttachedDeviceObject, Irp );
  1104. if( NTStatus == STATUS_SUCCESS )
  1105. {
  1106. // driver is ready to process io requests
  1107. KeSetEvent( &DeviceExtension->ReaderStarted, 0, FALSE );
  1108. }
  1109. break;
  1110. case IRP_MN_STOP_DEVICE:
  1111. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!IRP_MN_STOP_DEVICE\n" ));
  1112. DrvStopDevice( DeviceExtension );
  1113. NTStatus = DrvCallSerialDriver(AttachedDeviceObject, Irp );
  1114. break;
  1115. case IRP_MN_QUERY_REMOVE_DEVICE:
  1116. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!IRP_MN_QUERY_REMOVE_DEVICE\n" ));
  1117. // disable the reader (and ignore possibles errors)
  1118. IoSetDeviceInterfaceState(
  1119. &DeviceExtension->PnPDeviceName,
  1120. FALSE
  1121. );
  1122. // check if the reader is in use
  1123. if(DeviceExtension->ReaderOpen)
  1124. {
  1125. //
  1126. // someone is connected, fail the call
  1127. // we will enable the device interface in
  1128. // IRP_MN_CANCEL_REMOVE_DEVICE again
  1129. //
  1130. NTStatus = STATUS_UNSUCCESSFUL;
  1131. }
  1132. else
  1133. {
  1134. // ready to remove the device
  1135. NTStatus = DrvCallSerialDriver(AttachedDeviceObject, Irp );
  1136. }
  1137. break;
  1138. case IRP_MN_CANCEL_REMOVE_DEVICE:
  1139. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!IRP_MN_CANCEL_REMOVE_DEVICE\n" ));
  1140. NTStatus = DrvCallSerialDriver( AttachedDeviceObject, Irp );
  1141. //
  1142. // reenable the interface only in case that the reader is
  1143. // still connected. This covers the following case:
  1144. // hibernate machine, disconnect reader, wake up, stop device
  1145. // (from task bar) and stop fails since an app. holds the device open
  1146. //
  1147. if(( NTStatus == STATUS_SUCCESS )&&
  1148. (KeReadStateEvent(&(ReaderExtension->SerialCloseDone))!= TRUE))
  1149. {
  1150. // enable the reader
  1151. SmartcardDebug( DEBUG_DRIVER, ( "IoSetDeviceInterfaceState( &DeviceExtension->PnPDeviceName, TRUE )\n" ));
  1152. NTStatus = IoSetDeviceInterfaceState( &DeviceExtension->PnPDeviceName, TRUE );
  1153. }
  1154. break;
  1155. case IRP_MN_REMOVE_DEVICE:
  1156. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!IRP_MN_REMOVE_DEVICE\n" ));
  1157. DrvRemoveDevice( DeviceObject );
  1158. NTStatus = DrvCallSerialDriver( AttachedDeviceObject, Irp );
  1159. DeviceRemoved = TRUE;
  1160. break;
  1161. default:
  1162. // the irp is not handled by the driver, so pass it to theserial driver
  1163. SmartcardDebug(
  1164. DEBUG_DRIVER,
  1165. ( "SCMSTCS!IRP_MN_%lx\n", IoGetCurrentIrpStackLocation( Irp )->MinorFunction )
  1166. );
  1167. IoSkipCurrentIrpStackLocation( Irp );
  1168. NTStatus = IoCallDriver( AttachedDeviceObject, Irp );
  1169. IrpSkipped = TRUE;
  1170. break;
  1171. }
  1172. if( IrpSkipped == FALSE)
  1173. {
  1174. Irp->IoStatus.Status = NTStatus;
  1175. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1176. }
  1177. if( DeviceRemoved == FALSE)
  1178. {
  1179. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, ' PnP');
  1180. }
  1181. }
  1182. SmartcardDebug( DEBUG_TRACE, ( "SCMSTCS!DrvPnPDeviceControl: Exit %X\n", NTStatus ));
  1183. return( NTStatus );
  1184. }
  1185. //__________________________________________ P O W E R ____________________________________________
  1186. VOID
  1187. DrvSystemPowerCompletion(
  1188. IN PDEVICE_OBJECT DeviceObject,
  1189. IN UCHAR MinorFunction,
  1190. IN POWER_STATE PowerState,
  1191. IN PKEVENT Event,
  1192. IN PIO_STATUS_BLOCK IoStatus
  1193. )
  1194. /*++
  1195. Routine Description:
  1196. This function is called when the underlying stacks
  1197. completed the power transition.
  1198. --*/
  1199. {
  1200. UNREFERENCED_PARAMETER (DeviceObject);
  1201. UNREFERENCED_PARAMETER (MinorFunction);
  1202. UNREFERENCED_PARAMETER (PowerState);
  1203. UNREFERENCED_PARAMETER (IoStatus);
  1204. KeSetEvent(Event, 0, FALSE);
  1205. }
  1206. NTSTATUS
  1207. DrvDevicePowerCompletion(
  1208. IN PDEVICE_OBJECT DeviceObject,
  1209. IN PIRP Irp,
  1210. IN PSMARTCARD_EXTENSION SmartcardExtension
  1211. )
  1212. /*++
  1213. Routine Description:
  1214. Arguments:
  1215. Return Value:
  1216. --*/
  1217. {
  1218. NTSTATUS NTStatus;
  1219. PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
  1220. BOOLEAN CardPresent;
  1221. if(Irp->PendingReturned) {
  1222. IoMarkIrpPending(Irp);
  1223. }
  1224. // re-initialize the the reader & get the current card state
  1225. NTStatus = STCConfigureSTC(
  1226. SmartcardExtension->ReaderExtension,
  1227. ( PSTC_REGISTER ) STCInitialize
  1228. );
  1229. // Save the state of the card BEFORE stand by / hibernation
  1230. CardPresent =
  1231. SmartcardExtension->ReaderCapabilities.CurrentState >= SCARD_ABSENT;
  1232. // get the current state of the card
  1233. CBUpdateCardState(SmartcardExtension, SCARD_UNKNOWN);
  1234. if (CardPresent ||
  1235. SmartcardExtension->ReaderCapabilities.CurrentState >= SCARD_ABSENT) {
  1236. //
  1237. // If a card was present before power down or now there is
  1238. // a card in the reader, we complete any pending card monitor
  1239. // request, since we do not really know what card is now in the
  1240. // reader.
  1241. //
  1242. SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
  1243. CBUpdateCardState(SmartcardExtension, SCARD_UNKNOWN);
  1244. }
  1245. // save the current Power state of the reader
  1246. SmartcardExtension->ReaderExtension->ReaderPowerState = PowerReaderWorking;
  1247. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'rwoP');
  1248. // inform the Power manager of our state.
  1249. PoSetPowerState (
  1250. DeviceObject,
  1251. DevicePowerState,
  1252. IoGetCurrentIrpStackLocation( Irp )->Parameters.Power.State
  1253. );
  1254. PoStartNextPowerIrp( Irp );
  1255. // signal that we can process ioctls again
  1256. KeSetEvent(&DeviceExtension->ReaderStarted, 0, FALSE);
  1257. return( STATUS_SUCCESS );
  1258. }
  1259. typedef enum _ACTION
  1260. {
  1261. Undefined = 0,
  1262. SkipRequest,
  1263. WaitForCompletion,
  1264. CompleteRequest,
  1265. MarkPending
  1266. } ACTION;
  1267. NTSTATUS
  1268. DrvPowerHandler(
  1269. IN PDEVICE_OBJECT DeviceObject,
  1270. IN PIRP Irp
  1271. )
  1272. /*++
  1273. Routine Description:
  1274. Arguments:
  1275. Return Value:
  1276. --*/
  1277. {
  1278. NTSTATUS NTStatus = STATUS_SUCCESS;
  1279. PIO_STACK_LOCATION IrpStack;
  1280. PDEVICE_EXTENSION DeviceExtension;
  1281. PSMARTCARD_EXTENSION SmartcardExtension;
  1282. PDEVICE_OBJECT AttachedDeviceObject;
  1283. POWER_STATE PowerState;
  1284. ACTION Action;
  1285. KEVENT event;
  1286. PAGED_CODE();
  1287. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!DrvPowerHandler: Enter\n" ));
  1288. IrpStack = IoGetCurrentIrpStackLocation( Irp );
  1289. DeviceExtension = DeviceObject->DeviceExtension;
  1290. SmartcardExtension = &DeviceExtension->SmartcardExtension;
  1291. AttachedDeviceObject = SmartcardExtension->ReaderExtension->SerialDeviceObject;
  1292. NTStatus = SmartcardAcquireRemoveLockWithTag(SmartcardExtension, 'rwoP');
  1293. if( !NT_SUCCESS( NTStatus ))
  1294. {
  1295. PoStartNextPowerIrp( Irp );
  1296. Irp->IoStatus.Status = NTStatus;
  1297. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1298. }
  1299. else
  1300. {
  1301. switch (IrpStack->Parameters.Power.Type) {
  1302. case DevicePowerState:
  1303. if (IrpStack->MinorFunction == IRP_MN_SET_POWER ) {
  1304. switch ( IrpStack->Parameters.Power.State.DeviceState ) {
  1305. case PowerDeviceD0:
  1306. // turn the reader on
  1307. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!DrvPowerHandler: PowerDevice D0\n" ));
  1308. //
  1309. // send the request to the serial driver to power up the port.
  1310. // the reader will be powered from our completion routine
  1311. //
  1312. IoCopyCurrentIrpStackLocationToNext( Irp );
  1313. IoSetCompletionRoutine (
  1314. Irp,
  1315. DrvDevicePowerCompletion,
  1316. SmartcardExtension,
  1317. TRUE,
  1318. TRUE,
  1319. TRUE
  1320. );
  1321. Action = WaitForCompletion;
  1322. break;
  1323. case PowerDeviceD3:
  1324. // turn the reader off
  1325. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!DrvPowerHandler: PowerDevice D3\n" ));
  1326. PoSetPowerState (
  1327. DeviceObject,
  1328. DevicePowerState,
  1329. IrpStack->Parameters.Power.State
  1330. );
  1331. //
  1332. // check if we're still connected to the reader
  1333. // someone might have pulled the plug without re-scanning for hw/changes
  1334. //
  1335. if (KeReadStateEvent( &SmartcardExtension->ReaderExtension->SerialCloseDone ) == 0l) {
  1336. // power down the card
  1337. if ( SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT ) {
  1338. SmartcardExtension->MinorIoControlCode = SCARD_POWER_DOWN;
  1339. NTStatus = CBCardPower( SmartcardExtension );
  1340. //
  1341. // This will trigger the card monitor, since we do not really
  1342. // know if the user will remove / re-insert a card while the
  1343. // system is asleep
  1344. //
  1345. }
  1346. // power down the reader
  1347. STCConfigureSTC(
  1348. SmartcardExtension->ReaderExtension,
  1349. ( PSTC_REGISTER ) STCClose
  1350. );
  1351. }
  1352. // wait until the last read is finished to make sure we go to power
  1353. // down with a pending tracking irp
  1354. SysDelay( 2 * SR_READ_TOTAL_TIMEOUT_CONSTANT );
  1355. // save the current Power state of the reader
  1356. SmartcardExtension->ReaderExtension->ReaderPowerState = PowerReaderOff;
  1357. Action = SkipRequest;
  1358. break;
  1359. default:
  1360. Action = SkipRequest;
  1361. break;
  1362. }
  1363. } else {
  1364. Action = SkipRequest;
  1365. break;
  1366. }
  1367. break;
  1368. case SystemPowerState: {
  1369. //
  1370. // The system wants to change the power state.
  1371. // We need to translate the system power state to
  1372. // a corresponding device power state.
  1373. //
  1374. POWER_STATE_TYPE PowerType = DevicePowerState;
  1375. ASSERT(SmartcardExtension->ReaderExtension->ReaderPowerState !=
  1376. PowerReaderUnspecified);
  1377. switch ( IrpStack->MinorFunction ) {
  1378. KIRQL irql;
  1379. case IRP_MN_QUERY_POWER:
  1380. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!DrvPowerHandler: Query Power\n" ));
  1381. switch (IrpStack->Parameters.Power.State.SystemState) {
  1382. case PowerSystemMaximum:
  1383. case PowerSystemWorking:
  1384. case PowerSystemSleeping1:
  1385. case PowerSystemSleeping2:
  1386. Action = SkipRequest;
  1387. break;
  1388. case PowerSystemSleeping3:
  1389. case PowerSystemHibernate:
  1390. case PowerSystemShutdown:
  1391. KeAcquireSpinLock(&DeviceExtension->SpinLock, &irql);
  1392. if (DeviceExtension->IoCount == 0) {
  1393. // Block any further ioctls
  1394. KeClearEvent(&DeviceExtension->ReaderStarted);
  1395. Action = SkipRequest;
  1396. } else {
  1397. // can't go to sleep mode since the reader is busy.
  1398. NTStatus = STATUS_DEVICE_BUSY;
  1399. Action = CompleteRequest;
  1400. }
  1401. KeReleaseSpinLock(&DeviceExtension->SpinLock, irql);
  1402. break;
  1403. }
  1404. break;
  1405. case IRP_MN_SET_POWER:
  1406. SmartcardDebug(
  1407. DEBUG_DRIVER,
  1408. ( "SCMSTCS!DrvPowerHandler: PowerSystem S%d\n", IrpStack->Parameters.Power.State.SystemState - 1 )
  1409. );
  1410. switch (IrpStack->Parameters.Power.State.SystemState) {
  1411. case PowerSystemMaximum:
  1412. case PowerSystemWorking:
  1413. case PowerSystemSleeping1:
  1414. case PowerSystemSleeping2:
  1415. if ( SmartcardExtension->ReaderExtension->ReaderPowerState ==
  1416. PowerReaderWorking) {
  1417. // We're already in the right state
  1418. KeSetEvent(&DeviceExtension->ReaderStarted, 0, FALSE);
  1419. Action = SkipRequest;
  1420. break;
  1421. }
  1422. PowerState.DeviceState = PowerDeviceD0;
  1423. // wake up the underlying stack...
  1424. Action = MarkPending;
  1425. break;
  1426. case PowerSystemSleeping3:
  1427. case PowerSystemHibernate:
  1428. case PowerSystemShutdown:
  1429. if ( SmartcardExtension->ReaderExtension->ReaderPowerState == PowerReaderOff ) {
  1430. // We're already in the right state
  1431. Action = SkipRequest;
  1432. break;
  1433. }
  1434. PowerState.DeviceState = PowerDeviceD3;
  1435. // first, inform the Power manager of our new state.
  1436. PoSetPowerState (
  1437. DeviceObject,
  1438. SystemPowerState,
  1439. PowerState
  1440. );
  1441. Action = MarkPending;
  1442. break;
  1443. default:
  1444. Action = CompleteRequest;
  1445. break;
  1446. }
  1447. break;
  1448. default:
  1449. Action = SkipRequest;
  1450. break;
  1451. }
  1452. }
  1453. break;
  1454. default:
  1455. Action = CompleteRequest;
  1456. break;
  1457. }
  1458. switch( Action )
  1459. {
  1460. case CompleteRequest:
  1461. Irp->IoStatus.Status = NTStatus;
  1462. Irp->IoStatus.Information = 0;
  1463. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'rwoP');
  1464. PoStartNextPowerIrp( Irp );
  1465. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  1466. break;
  1467. case MarkPending:
  1468. // initialize the event we need in the completion function
  1469. KeInitializeEvent(
  1470. &event,
  1471. NotificationEvent,
  1472. FALSE
  1473. );
  1474. // request the device power irp
  1475. NTStatus = PoRequestPowerIrp (
  1476. DeviceObject,
  1477. IRP_MN_SET_POWER,
  1478. PowerState,
  1479. DrvSystemPowerCompletion,
  1480. &event,
  1481. NULL
  1482. );
  1483. if (NTStatus == STATUS_PENDING) {
  1484. // wait until the device power irp completed
  1485. NTStatus = KeWaitForSingleObject(
  1486. &event,
  1487. Executive,
  1488. KernelMode,
  1489. FALSE,
  1490. NULL
  1491. );
  1492. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'rwoP');
  1493. if (PowerState.SystemState == PowerSystemWorking) {
  1494. PoSetPowerState (
  1495. DeviceObject,
  1496. SystemPowerState,
  1497. PowerState
  1498. );
  1499. }
  1500. PoStartNextPowerIrp(Irp);
  1501. IoSkipCurrentIrpStackLocation(Irp);
  1502. NTStatus = PoCallDriver(AttachedDeviceObject, Irp);
  1503. } else {
  1504. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'rwoP');
  1505. Irp->IoStatus.Status = NTStatus;
  1506. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1507. }
  1508. break;
  1509. case SkipRequest:
  1510. SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'rwoP');
  1511. PoStartNextPowerIrp( Irp );
  1512. IoSkipCurrentIrpStackLocation( Irp );
  1513. NTStatus = PoCallDriver( AttachedDeviceObject, Irp );
  1514. break;
  1515. case WaitForCompletion:
  1516. NTStatus = PoCallDriver( AttachedDeviceObject, Irp );
  1517. break;
  1518. default:
  1519. break;
  1520. }
  1521. }
  1522. SmartcardDebug( DEBUG_DRIVER, ( "SCMSTCS!DrvPowerHandler: Exit %X\n", NTStatus ));
  1523. return( NTStatus );
  1524. }
  1525. void
  1526. SysDelay(
  1527. ULONG Timeout
  1528. )
  1529. /*++
  1530. SysDelay:
  1531. performs a required delay
  1532. Arguments:
  1533. Timeout delay in milliseconds
  1534. --*/
  1535. {
  1536. if( KeGetCurrentIrql() >= DISPATCH_LEVEL )
  1537. {
  1538. ULONG Cnt = 20 * Timeout;
  1539. while( Cnt-- )
  1540. {
  1541. // KeStallExecutionProcessor: counted in us
  1542. KeStallExecutionProcessor( 50 );
  1543. }
  1544. }
  1545. else
  1546. {
  1547. LARGE_INTEGER SysTimeout;
  1548. SysTimeout.QuadPart =
  1549. (LONGLONG) Timeout * -10 * 1000;
  1550. // KeDelayExecutionThread: counted in 100 ns
  1551. KeDelayExecutionThread( KernelMode, FALSE, &SysTimeout );
  1552. }
  1553. return;
  1554. }
  1555. //_________________________________________ END OF FILE _________________________________________