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.

4238 lines
114 KiB

  1. /*++
  2. Copyright (c) 1997 Rainbow Technologies Inc.
  3. Module Name:
  4. RNBO3531.c
  5. Abstract:
  6. Author:
  7. Mehdi Sotoodeh mehdi@rainbow.com
  8. Environment:
  9. Kernel mode
  10. Revision History :
  11. Jan 98 - Started from the DDK sources from Klaus Schutz
  12. Mar 98 - PnP support added
  13. Apr 98 - Changes on card timings and PnP
  14. - Added power management
  15. May 98 - RemoveLock changes
  16. - RBSCT1Transmit timeout bug fixed
  17. - Sent to MicroSoft
  18. May 98 - Added variable baudrate support
  19. - Reduced ATR response time
  20. - Sent to MicroSoft
  21. - Data transmission size of 256 bug fixed.
  22. Jun 98 - Power management update
  23. - RBSCReaderPower and RBSCCardTracking moved to non-paged
  24. code (use of KeAcquireSpinLock/IoAcquireCancelSpinLock)
  25. - fixed: completeion function when IoSkipCurrentIrpStackLocation
  26. is called.
  27. - turned off PowerRequest flag on exit from RBSCReaderPower.
  28. - Sent to MicroSoft
  29. Sep 98 - Power management update
  30. - Sent to MicroSoft
  31. Oct 98 - warning fixes for win64 compatibility.
  32. Nov 98 - Set to default when PTS fails.
  33. - Mondex fix
  34. - Sent to MicroSoft
  35. Dec 98 - Reties removed from the reset operations
  36. - Sent to MicroSoft
  37. Apr 99 - Misc. changes
  38. --*/
  39. #include <stdio.h>
  40. #include "RNBO3531.h"
  41. //
  42. // We do not need these functions after init anymore
  43. //
  44. #pragma alloc_text(INIT, DriverEntry)
  45. #pragma alloc_text(PAGEABLE, RBSCAddDevice)
  46. #pragma alloc_text(PAGEABLE, RBSCUnloadDriver)
  47. #pragma alloc_text(PAGEABLE, RBSCRemoveDevice)
  48. #pragma alloc_text(PAGEABLE, RBSCTransmit)
  49. #pragma alloc_text(PAGEABLE, RBSCSetProtocol)
  50. #pragma alloc_text(PAGEABLE, RBSCT0Transmit)
  51. #pragma alloc_text(PAGEABLE, RBSCT1Transmit)
  52. #if DBG
  53. #pragma optimize ("", off)
  54. #endif
  55. UCHAR GetReaderType[] = {IFDCMD_HEADER1,IFDCMD_HEADER2,IFDCMD_GET_TYPE};
  56. UCHAR CardPowerDown[] = {IFDCMD_HEADER1,IFDCMD_HEADER2,IFDCMD_PWR_OFF};
  57. UCHAR CardPowerUp[] = {IFDCMD_HEADER1,IFDCMD_HEADER2,IFDCMD_PWR_ON};
  58. #ifdef NT4
  59. #define SmartcardAcquireRemoveLockWithTag(x,y) SmartcardAcquireRemoveLock(x)
  60. #define SmartcardReleaseRemoveLockWithTag(x,y) SmartcardReleaseRemoveLock(x)
  61. #endif
  62. #ifndef NT5
  63. DWORD UsedPortsMask = 0; // Bit mask for used ports
  64. #endif
  65. //
  66. // Table to convert inverse convention data
  67. //
  68. static UCHAR InverseCharTable[256] =
  69. {
  70. 0xFF,0x7F,0xBF,0x3F,0xDF,0x5F,0x9F,0x1F,
  71. 0xEF,0x6F,0xAF,0x2F,0xCF,0x4F,0x8F,0x0F,
  72. 0xF7,0x77,0xB7,0x37,0xD7,0x57,0x97,0x17,
  73. 0xE7,0x67,0xA7,0x27,0xC7,0x47,0x87,0x07,
  74. 0xFB,0x7B,0xBB,0x3B,0xDB,0x5B,0x9B,0x1B,
  75. 0xEB,0x6B,0xAB,0x2B,0xCB,0x4B,0x8B,0x0B,
  76. 0xF3,0x73,0xB3,0x33,0xD3,0x53,0x93,0x13,
  77. 0xE3,0x63,0xA3,0x23,0xC3,0x43,0x83,0x03,
  78. 0xFD,0x7D,0xBD,0x3D,0xDD,0x5D,0x9D,0x1D,
  79. 0xED,0x6D,0xAD,0x2D,0xCD,0x4D,0x8D,0x0D,
  80. 0xF5,0x75,0xB5,0x35,0xD5,0x55,0x95,0x15,
  81. 0xE5,0x65,0xA5,0x25,0xC5,0x45,0x85,0x05,
  82. 0xF9,0x79,0xB9,0x39,0xD9,0x59,0x99,0x19,
  83. 0xE9,0x69,0xA9,0x29,0xC9,0x49,0x89,0x09,
  84. 0xF1,0x71,0xB1,0x31,0xD1,0x51,0x91,0x11,
  85. 0xE1,0x61,0xA1,0x21,0xC1,0x41,0x81,0x01,
  86. 0xFE,0x7E,0xBE,0x3E,0xDE,0x5E,0x9E,0x1E,
  87. 0xEE,0x6E,0xAE,0x2E,0xCE,0x4E,0x8E,0x0E,
  88. 0xF6,0x76,0xB6,0x36,0xD6,0x56,0x96,0x16,
  89. 0xE6,0x66,0xA6,0x26,0xC6,0x46,0x86,0x06,
  90. 0xFA,0x7A,0xBA,0x3A,0xDA,0x5A,0x9A,0x1A,
  91. 0xEA,0x6A,0xAA,0x2A,0xCA,0x4A,0x8A,0x0A,
  92. 0xF2,0x72,0xB2,0x32,0xD2,0x52,0x92,0x12,
  93. 0xE2,0x62,0xA2,0x22,0xC2,0x42,0x82,0x02,
  94. 0xFC,0x7C,0xBC,0x3C,0xDC,0x5C,0x9C,0x1C,
  95. 0xEC,0x6C,0xAC,0x2C,0xCC,0x4C,0x8C,0x0C,
  96. 0xF4,0x74,0xB4,0x34,0xD4,0x54,0x94,0x14,
  97. 0xE4,0x64,0xA4,0x24,0xC4,0x44,0x84,0x04,
  98. 0xF8,0x78,0xB8,0x38,0xD8,0x58,0x98,0x18,
  99. 0xE8,0x68,0xA8,0x28,0xC8,0x48,0x88,0x08,
  100. 0xF0,0x70,0xB0,0x30,0xD0,0x50,0x90,0x10,
  101. 0xE0,0x60,0xA0,0x20,0xC0,0x40,0x80,0x00
  102. };
  103. #if DBG
  104. void
  105. _stdcall
  106. DumpData(
  107. PUCHAR Msg,
  108. PUCHAR Buffer,
  109. ULONG Length
  110. )
  111. /*++
  112. Routine Description:
  113. This function formats the debug output and
  114. shows it on the debug screen
  115. Arguments:
  116. Buffer - pointer to the buffer which contains the
  117. debug data
  118. Length - length of the datablock
  119. Return Value:
  120. Note:
  121. Output Format:
  122. 0000 : FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
  123. 0010 : FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
  124. 0020 : .....
  125. --*/
  126. {
  127. ULONG i, n;
  128. char buff[80];
  129. n = sprintf( buff, "RNBO3531!%s = %ld", Msg, Length );
  130. for( i = 0; i < Length; i++ )
  131. {
  132. if( (i & 15) == 0 )
  133. {
  134. SmartcardDebug( DEBUG_PROTOCOL, ("%s\n", buff) );
  135. n = sprintf( buff, "%04X :", i );
  136. }
  137. n += sprintf( buff+n, " %02X", Buffer[i] );
  138. if( ((i + 1) & 7) == 0 )
  139. {
  140. n += sprintf( buff+n, " " );
  141. }
  142. }
  143. SmartcardDebug( DEBUG_PROTOCOL, ("%s\n", buff) );
  144. }
  145. #else
  146. #define DumpData(Msg,Buffer,Length)
  147. #endif
  148. VOID
  149. RBSCDelay(
  150. ULONG waitTime
  151. )
  152. /*++
  153. Routine Description:
  154. Delay function.
  155. Arguments:
  156. waitTime - Waiting time in micro-seconds
  157. Return Value:
  158. None
  159. --*/
  160. {
  161. if( waitTime )
  162. {
  163. LARGE_INTEGER delayPeriod;
  164. delayPeriod.HighPart = -1;
  165. delayPeriod.LowPart = waitTime * (-10); // units of 100nsec
  166. KeDelayExecutionThread( KernelMode,
  167. FALSE,
  168. &delayPeriod );
  169. }
  170. }
  171. NTSTATUS
  172. DriverEntry(
  173. PDRIVER_OBJECT DriverObject,
  174. PUNICODE_STRING RegistryPath
  175. )
  176. /*++
  177. Routine Description:
  178. This routine is called at system initialization time to initialize
  179. this driver.
  180. Arguments:
  181. DriverObject - Supplies the driver object.
  182. RegistryPath - Supplies the registry path for this driver.
  183. Return Value:
  184. STATUS_SUCCESS - We could initialize at least one device.
  185. STATUS_NO_SUCH_DEVICE - We could not initialize even one device.
  186. --*/
  187. {
  188. #ifndef NT5
  189. RTL_QUERY_REGISTRY_TABLE paramTable[2];
  190. ULONG i, noOfDevices = 0;
  191. DWORD UsedPorts = 1; // COM1 as default
  192. NTSTATUS status;
  193. #endif
  194. SmartcardDebug(
  195. DEBUG_DRIVER,
  196. ("RNBO3531!DriverEntry: Enter - %s %s\n",
  197. __DATE__,
  198. __TIME__)
  199. );
  200. //
  201. // Initialize the Driver Object with driver's entry points
  202. //
  203. DriverObject->DriverUnload = RBSCUnloadDriver;
  204. DriverObject->MajorFunction[IRP_MJ_CREATE] = RBSCCreateClose;
  205. DriverObject->MajorFunction[IRP_MJ_CLOSE] = RBSCCreateClose;
  206. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = RBSCCleanup;
  207. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RBSCDeviceControl;
  208. #ifdef NT5
  209. DriverObject->DriverExtension->AddDevice = RBSCAddDevice;
  210. DriverObject->MajorFunction[IRP_MJ_POWER] = RBSCPower;
  211. DriverObject->MajorFunction[IRP_MJ_PNP] = RBSCPnPDeviceControl;
  212. #else
  213. RtlZeroMemory( paramTable, sizeof(paramTable) );
  214. paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  215. paramTable[0].Name = L"ComPorts";
  216. paramTable[0].EntryContext = &UsedPorts;
  217. paramTable[0].DefaultType = REG_DWORD;
  218. paramTable[0].DefaultData = &UsedPorts;
  219. paramTable[0].DefaultLength = 0;
  220. //
  221. // now try to find the entry in the registry
  222. //
  223. RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE,
  224. RegistryPath->Buffer,
  225. &paramTable[0],
  226. NULL,
  227. NULL );
  228. //
  229. // We now search the registry for DeviceN value
  230. //
  231. for( i = 0;
  232. noOfDevices < MAXIMUM_SERIAL_READERS && UsedPorts != 0;
  233. i++, UsedPorts >>= 1 )
  234. {
  235. PFILE_OBJECT SerialFileObject;
  236. PDEVICE_OBJECT SerialDeviceObject;
  237. UNICODE_STRING SerialDeviceName;
  238. while( (UsedPorts & 1) == 0 )
  239. {
  240. UsedPorts >>= 1;
  241. i++;
  242. }
  243. RtlInitUnicodeString( &SerialDeviceName, L"\\Device\\Serial0" );
  244. //
  245. // create string like \Device\SerialN
  246. //
  247. SerialDeviceName.Buffer[14] = L'0' + (WCHAR) i;
  248. //
  249. // Try to create a device with the just created device name
  250. // It is possible that a smart card device with this name
  251. // already exists from a previous call.
  252. // It is possible to have up to 4 devices in a system
  253. //
  254. status = IoGetDeviceObjectPointer( &SerialDeviceName,
  255. FILE_ALL_ACCESS,
  256. &SerialFileObject,
  257. &SerialDeviceObject );
  258. if( !NT_SUCCESS(status) )
  259. {
  260. UNICODE_STRING comPortNumber;
  261. WCHAR buffer[2];
  262. //
  263. // Extract the com-port-number
  264. //
  265. comPortNumber.Buffer = buffer;
  266. comPortNumber.Length = sizeof(WCHAR);
  267. comPortNumber.MaximumLength = sizeof(buffer);
  268. comPortNumber.Buffer[0] = SerialDeviceName.Buffer[14] + (WCHAR)1;
  269. //
  270. // Write an event-log msg that this com port is not available
  271. //
  272. SmartcardLogError( DriverObject,
  273. RBSC_CANT_CONNECT_TO_SERIAL_PORT,
  274. &comPortNumber,
  275. status );
  276. continue;
  277. }
  278. //
  279. // Now try to create a device and connect to the serial port
  280. //
  281. status = RBSCAddDevice( DriverObject, SerialDeviceObject );
  282. if( status == STATUS_SUCCESS )
  283. {
  284. //
  285. // We have successfully created a device
  286. //
  287. PREADER_EXTENSION ReaderExtension =
  288. DriverObject->DeviceObject->DeviceExtension;
  289. //
  290. // Save the serial port number this device is connected to
  291. //
  292. ReaderExtension->SmartcardExtension.ReaderCapabilities.Channel =
  293. i + 1;
  294. //
  295. // The fileObject is used in the unload function for
  296. // dereferencing
  297. //
  298. ReaderExtension->SerialFileObject = SerialFileObject;
  299. noOfDevices++;
  300. } else {
  301. //
  302. // We were unable to get the reader type.
  303. // So remove the device.
  304. //
  305. ObDereferenceObject( SerialFileObject );
  306. SmartcardLogError( DriverObject,
  307. RBSC_CANNOT_OPEN_DEVICE,
  308. &SerialDeviceName,
  309. status );
  310. }
  311. }
  312. if( noOfDevices == 0 )
  313. {
  314. SmartcardLogError( DriverObject,
  315. RBSC_NO_SUCH_DEVICE,
  316. NULL,
  317. status );
  318. return STATUS_NO_SUCH_DEVICE;
  319. }
  320. #endif
  321. return STATUS_SUCCESS;
  322. }
  323. VOID
  324. RBSCUnloadDriver(
  325. PDRIVER_OBJECT DriverObject
  326. )
  327. /*++
  328. Routine Description:
  329. The driver unload routine. This is called by the I/O system
  330. when the device is unloaded from memory.
  331. Arguments:
  332. DriverObject - Pointer to driver object created by system.
  333. Return Value:
  334. STATUS_SUCCESS.
  335. --*/
  336. {
  337. #ifdef NT5
  338. //
  339. // We do not need to do anything since all the cleanups are done by
  340. // RBSCRemoveDevice().
  341. //
  342. #else
  343. while( DriverObject->DeviceObject )
  344. {
  345. RBSCRemoveDevice( DriverObject->DeviceObject );
  346. }
  347. #endif
  348. SmartcardDebug(
  349. DEBUG_INFO,
  350. ("RNBO3531!UnloadDriver\n")
  351. );
  352. }
  353. #ifdef NT5
  354. NTSTATUS
  355. RBSCIoCompletion(
  356. PDEVICE_OBJECT DeviceObject,
  357. PIRP Irp,
  358. PKEVENT Event
  359. )
  360. /*++
  361. Routine Description:
  362. Completion routine for an Irp sent to the serial driver. The event will
  363. be set to notify that the serial driver is done. The routine will not
  364. 'complete' the Irp, so the caller of RBSCCallSerialDriver can continue.
  365. Arguments:
  366. DeviceObject - Pointer to device object
  367. Irp - Irp to complete
  368. Event - Used for process synchronization
  369. Return Value:
  370. STATUS_CANCELLED Irp was cancelled by the IO manager
  371. STATUS_MORE_PROCESSING_REQUIRED Irp will be finished by caller of
  372. RBSCCallSerialDriver
  373. --*/
  374. {
  375. UNREFERENCED_PARAMETER( DeviceObject );
  376. Irp->IoStatus.Status =
  377. Irp->Cancel ? STATUS_CANCELLED : STATUS_MORE_PROCESSING_REQUIRED;
  378. KeSetEvent( Event, 0, FALSE );
  379. return STATUS_MORE_PROCESSING_REQUIRED;
  380. }
  381. NTSTATUS
  382. RBSCCallSerialDriver(
  383. PDEVICE_OBJECT AttachedSerialPort,
  384. PIRP Irp
  385. )
  386. /*++
  387. Routine Description:
  388. Send an Irp to the serial driver and wait until the serial driver has
  389. finished the request.
  390. To make sure that the serial driver will not complete the Irp we first
  391. initialize an event and set our own completion routine for the Irp.
  392. When the serial driver has processed the Irp the completion routine will
  393. set the event and tell the IO manager that more processing is required.
  394. By waiting for the event we make sure that we continue only if the serial
  395. driver has processed the Irp completely.
  396. Arguments:
  397. AttachedSerialPort - The PDO
  398. Irp - Irp to send to the serial driver
  399. Return Value:
  400. status returned by the serial driver
  401. Note:
  402. Since this function can be called after our device is removed, do not
  403. use any of the reader extension data here.
  404. --*/
  405. {
  406. NTSTATUS status = STATUS_SUCCESS;
  407. KEVENT Event;
  408. SmartcardDebug(
  409. DEBUG_TRACE,
  410. ("RNBO3531!CallSerialDriver: Enter\n")
  411. );
  412. //
  413. // Prepare everything to call the underlying driver
  414. //
  415. //
  416. // Copy our stack to the next stack location.
  417. //
  418. IoCopyCurrentIrpStackLocationToNext( Irp);
  419. //
  420. // initialize an event for process synchronization. the event is passed
  421. // to our completion routine and will be set if the serial driver is done
  422. //
  423. KeInitializeEvent( &Event,
  424. NotificationEvent,
  425. FALSE );
  426. //
  427. // Our IoCompletionRoutine sets only our event
  428. //
  429. IoSetCompletionRoutine( Irp,
  430. RBSCIoCompletion,
  431. &Event,
  432. TRUE,
  433. TRUE,
  434. TRUE );
  435. //
  436. // Call the serial driver
  437. //
  438. status = (IoGetCurrentIrpStackLocation( Irp )->MajorFunction ==
  439. IRP_MJ_POWER) ?
  440. PoCallDriver( AttachedSerialPort, Irp ) :
  441. IoCallDriver( AttachedSerialPort, Irp );
  442. //
  443. // Wait until the serial driver has processed the Irp
  444. //
  445. if( status == STATUS_PENDING )
  446. {
  447. status = KeWaitForSingleObject( &Event,
  448. Executive,
  449. KernelMode,
  450. FALSE, // No alert
  451. NULL ); // No timeout
  452. ASSERT( STATUS_SUCCESS == status );
  453. status = Irp->IoStatus.Status;
  454. }
  455. SmartcardDebug(
  456. DEBUG_TRACE,
  457. ("RNBO3531!CallSerialDriver: Exit %x\n",status)
  458. );
  459. return status;
  460. }
  461. #endif
  462. NTSTATUS
  463. RBSCStartDevice(
  464. PDEVICE_OBJECT DeviceObject
  465. )
  466. /*++
  467. Routine Description:
  468. Open the underlying serial driver and initialize it.
  469. Then initialize the reader hardware.
  470. Arguments:
  471. DeviceObject - Pointer to device object
  472. Return Value:
  473. STATUS_SUCCESS
  474. STATUS_NO_MEMORY
  475. status returned by LowLevel routines
  476. --*/
  477. {
  478. PREADER_EXTENSION ReaderExtension = DeviceObject->DeviceExtension;
  479. PDEVICE_OBJECT AttachedSerialPort = ReaderExtension->AttachedSerialPort;
  480. NTSTATUS status;
  481. #ifdef NT5
  482. PIO_STACK_LOCATION irpSp;
  483. PIRP irp = IoAllocateIrp( (CCHAR)(DeviceObject->StackSize + 1), FALSE );
  484. ASSERT( irp != NULL );
  485. if( irp == NULL )
  486. {
  487. return STATUS_NO_MEMORY;
  488. }
  489. #endif
  490. _try {
  491. #ifdef NT5
  492. PIO_STACK_LOCATION irpStack;
  493. IO_STATUS_BLOCK ioStatusBlock;
  494. //
  495. // Open the underlying serial driver.
  496. // This is necessary for two reasons:
  497. // a) The serial driver can't be used without opening it
  498. // b) The call will go through serenum first which informs
  499. // it to stop looking/polling for new devices.
  500. //
  501. irp->UserIosb = &ioStatusBlock;
  502. IoSetNextIrpStackLocation(irp);
  503. irpStack = IoGetCurrentIrpStackLocation( irp );
  504. irpStack->MajorFunction = IRP_MJ_CREATE;
  505. irpStack->Parameters.Create.Options = 0;
  506. irpStack->Parameters.Create.ShareAccess = 0;
  507. irpStack->Parameters.Create.FileAttributes = 0;
  508. irpStack->Parameters.Create.EaLength = 0;
  509. status = RBSCCallSerialDriver( AttachedSerialPort, irp );
  510. if( status != STATUS_SUCCESS )
  511. {
  512. if( status == STATUS_SHARED_IRQ_BUSY )
  513. {
  514. // Port is in use by another device
  515. SmartcardLogError( DeviceObject,
  516. RBSC_CANT_SHARE_IRQ,
  517. NULL,
  518. 0 );
  519. }
  520. leave;
  521. }
  522. #endif
  523. KeClearEvent( &ReaderExtension->SerialCloseDone );
  524. ReaderExtension->SmartcardExtension.ReaderCapabilities.CurrentState =
  525. (ULONG) SCARD_UNKNOWN;
  526. status = RBSCConfigureSerialPort( ReaderExtension );
  527. if( status != STATUS_SUCCESS )
  528. {
  529. leave;
  530. }
  531. //
  532. // Send a wait mask to the serial driver.
  533. // This call only sets the wait mask.
  534. // We want to be informed when CTS or DSR changes its state
  535. //
  536. #ifdef NT5
  537. ReaderExtension->WaitMask = SERIAL_EV_CTS | SERIAL_EV_DSR;
  538. #else
  539. ReaderExtension->WaitMask = SERIAL_EV_CTS;
  540. #endif
  541. status = RBSCSerialIo( &ReaderExtension->SmartcardExtension,
  542. IOCTL_SERIAL_SET_WAIT_MASK,
  543. (PUCHAR) &ReaderExtension->WaitMask,
  544. sizeof(ReaderExtension->WaitMask),
  545. 0 );
  546. if( status != STATUS_SUCCESS)
  547. {
  548. leave;
  549. }
  550. //
  551. // Now tell the serial driver that we want to be informed
  552. // when CTS or DSR changes its state.
  553. // Changing the lowest two bits tells IoBuildDeviceIoControlRequest
  554. // NOT to allocate a system buffer for the I/O operation.
  555. // We don't need a system buffer since we use our own buffers.
  556. //
  557. ReaderExtension->SerialStatusIrp = IoAllocateIrp(
  558. (CCHAR) (DeviceObject->StackSize + 1),
  559. FALSE
  560. );
  561. if (ReaderExtension->SerialStatusIrp == NULL) {
  562. status = STATUS_INSUFFICIENT_RESOURCES;
  563. leave;
  564. }
  565. irpSp = IoGetNextIrpStackLocation( ReaderExtension->SerialStatusIrp );
  566. irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
  567. irpSp->Parameters.DeviceIoControl.InputBufferLength = 0;
  568. irpSp->Parameters.DeviceIoControl.OutputBufferLength =
  569. sizeof(ReaderExtension->WaitMask);
  570. irpSp->Parameters.DeviceIoControl.IoControlCode =
  571. IOCTL_SERIAL_WAIT_ON_MASK;
  572. ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer =
  573. &ReaderExtension->WaitMask;
  574. //
  575. // this artificial delay is necessary to make this driver work
  576. // with digi board cards
  577. //
  578. RBSCDelay( 100000 );
  579. //
  580. // We simulate a callback now that triggers the card supervision
  581. //
  582. RBSCSerialEvents(
  583. ReaderExtension->SmartcardExtension.OsData->DeviceObject,
  584. ReaderExtension->SerialStatusIrp,
  585. ReaderExtension
  586. );
  587. #ifdef NT5
  588. status = IoSetDeviceInterfaceState(
  589. &ReaderExtension->PnPDeviceName,
  590. TRUE
  591. );
  592. if( status != STATUS_SUCCESS )
  593. {
  594. leave;
  595. }
  596. #endif
  597. KeSetEvent( &ReaderExtension->ReaderStarted, 0, FALSE );
  598. } _finally {
  599. if (status == STATUS_SHARED_IRQ_BUSY)
  600. {
  601. SmartcardLogError( DeviceObject,
  602. RBSC_IRQ_BUSY,
  603. NULL,
  604. status );
  605. }
  606. #ifdef NT5
  607. IoFreeIrp( irp );
  608. #endif
  609. }
  610. SmartcardDebug(
  611. DEBUG_TRACE,
  612. ("RNBO3531!StartDevice: Exit (%x)\n",status)
  613. );
  614. return status;
  615. }
  616. VOID
  617. RBSCStopDevice(
  618. PREADER_EXTENSION ReaderExtension
  619. )
  620. /*++
  621. Routine Description:
  622. Waits for the device to be closed
  623. Arguments:
  624. ReaderExtension - Pointer to our device data
  625. Return Value:
  626. void
  627. --*/
  628. {
  629. SmartcardDebug(
  630. DEBUG_TRACE,
  631. ("RNBO3531!StopDevice: Enter\n")
  632. );
  633. if( !KeReadStateEvent( &ReaderExtension->SerialCloseDone ) )
  634. {
  635. NTSTATUS status;
  636. // test if we ever started event tracking
  637. if( ReaderExtension->WaitMask == 0 )
  638. {
  639. // no, we did not
  640. // We 'only' need to close the serial port
  641. RBSCCloseSerialPort(
  642. ReaderExtension->SmartcardExtension.OsData->DeviceObject,
  643. NULL );
  644. }
  645. else
  646. {
  647. //
  648. // We now inform the serial driver that we're no longer
  649. // interested in serial events. This will also free the irp
  650. // we use for those io-completions
  651. //
  652. ReaderExtension->WaitMask = 0;
  653. status = RBSCSerialIo(
  654. &ReaderExtension->SmartcardExtension,
  655. IOCTL_SERIAL_SET_WAIT_MASK,
  656. (PUCHAR)&ReaderExtension->WaitMask,
  657. sizeof(ULONG),
  658. 0
  659. );
  660. ASSERT( status == STATUS_SUCCESS );
  661. // now wait until the connetion to serial is closed
  662. status = KeWaitForSingleObject(
  663. &ReaderExtension->SerialCloseDone,
  664. Executive,
  665. KernelMode,
  666. FALSE,
  667. NULL
  668. );
  669. ASSERT( status == STATUS_SUCCESS );
  670. }
  671. }
  672. SmartcardDebug(
  673. DEBUG_TRACE,
  674. ("RNBO3531!StopDevice\n")
  675. );
  676. }
  677. VOID
  678. RBSCRemoveDevice(
  679. PDEVICE_OBJECT DeviceObject
  680. )
  681. /*++
  682. Routine Description:
  683. Stops the device then releases all the resources used.
  684. Arguments:
  685. DeviceObject - Pointer to device object
  686. Return Value:
  687. void
  688. --*/
  689. {
  690. NTSTATUS status;
  691. PREADER_EXTENSION ReaderExtension;
  692. PSMARTCARD_EXTENSION SmartcardExtension;
  693. PAGED_CODE();
  694. SmartcardDebug(
  695. DEBUG_INFO,
  696. ("RNBO3531!RemoveDevice: Enter\n")
  697. );
  698. ReaderExtension = DeviceObject->DeviceExtension;
  699. SmartcardExtension = &ReaderExtension->SmartcardExtension;
  700. if( SmartcardExtension->OsData )
  701. {
  702. // complete pending card tracking requests (if any)
  703. RBSCCompleteCardTracking( SmartcardExtension );
  704. ASSERT( SmartcardExtension->OsData->NotificationIrp == NULL );
  705. #ifdef NT5
  706. SmartcardReleaseRemoveLockAndWait( SmartcardExtension );
  707. #endif
  708. }
  709. #ifndef NT5
  710. //
  711. // Free the device slot (if in use)
  712. //
  713. UsedPortsMask &= ~(1<<SmartcardExtension->VendorAttr.UnitNo);
  714. #endif
  715. RBSCStopDevice( ReaderExtension );
  716. #ifdef NT5
  717. if( ReaderExtension->AttachedSerialPort )
  718. {
  719. IoDetachDevice( ReaderExtension->AttachedSerialPort );
  720. }
  721. if( ReaderExtension->PnPDeviceName.Buffer != NULL )
  722. {
  723. RtlFreeUnicodeString( &ReaderExtension->PnPDeviceName );
  724. }
  725. if( ReaderExtension->CloseSerial != NULL )
  726. {
  727. IoFreeWorkItem(ReaderExtension->CloseSerial);
  728. }
  729. #else
  730. if( ReaderExtension->SerialFileObject )
  731. {
  732. ObDereferenceObject( ReaderExtension->SerialFileObject );
  733. }
  734. if( ReaderExtension->DosDeviceName.Buffer != NULL )
  735. {
  736. //
  737. // Delete the symbolic link of the smart card reader
  738. //
  739. IoDeleteSymbolicLink( &ReaderExtension->DosDeviceName );
  740. RtlFreeUnicodeString( &ReaderExtension->DosDeviceName );
  741. }
  742. #endif
  743. if( SmartcardExtension->OsData != NULL )
  744. {
  745. SmartcardExit( SmartcardExtension );
  746. }
  747. IoDeleteDevice( DeviceObject );
  748. SmartcardDebug(
  749. DEBUG_INFO,
  750. ("RNBO3531!RemoveDevice: Exit\n")
  751. );
  752. }
  753. #ifdef NT5
  754. NTSTATUS
  755. RBSCPnPDeviceControl(
  756. PDEVICE_OBJECT DeviceObject,
  757. PIRP Irp
  758. )
  759. /*++
  760. Routine Description:
  761. driver callback for pnp manager
  762. Request: Action:
  763. IRP_MN_START_DEVICE Notify the driver about the new device
  764. and start the device
  765. IRP_MN_STOP_DEVICE Free all resources used by the device and
  766. tell the driver that the device was stopped
  767. IRP_MN_QUERY_REMOVE_DEVICE If the device is opened (i.e. in use) an
  768. error will be returned to prevent the PnP
  769. manager to stop the driver
  770. IRP_MN_CANCEL_REMOVE_DEVICE just notify that we can continue without any
  771. restrictions
  772. IRP_MN_REMOVE_DEVICE notify the driver that the device was
  773. removed, stop & unload the device
  774. All other requests will be passed to the driver to ensure correct
  775. processing.
  776. Arguments:
  777. DeviceObject - Pointer to device object
  778. Irp - Irp from the PnP manager
  779. Return Value:
  780. STATUS_SUCCESS
  781. STATUS_UNSUCCESSFUL
  782. status returned by serial driver
  783. --*/
  784. {
  785. PREADER_EXTENSION ReaderExtension = DeviceObject->DeviceExtension;
  786. PDEVICE_OBJECT AttachedSerialPort = ReaderExtension->AttachedSerialPort;
  787. NTSTATUS status;
  788. PIO_STACK_LOCATION stack;
  789. BOOLEAN deviceRemoved = FALSE, irpSkipped = FALSE;
  790. KEVENT Event;
  791. KIRQL irql;
  792. SmartcardDebug(
  793. DEBUG_TRACE,
  794. ("RNBO3531!PnPDeviceControl: Enter (%08x)\n",
  795. IoGetCurrentIrpStackLocation( Irp )->MinorFunction)
  796. );
  797. status = SmartcardAcquireRemoveLockWithTag(
  798. &ReaderExtension->SmartcardExtension, ' PnP' );
  799. ASSERT( status == STATUS_SUCCESS );
  800. Irp->IoStatus.Information = 0;
  801. if( status != STATUS_SUCCESS )
  802. {
  803. Irp->IoStatus.Status = status;
  804. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  805. return status;
  806. }
  807. stack = IoGetCurrentIrpStackLocation( Irp );
  808. //
  809. // Now look what the PnP manager wants...
  810. //
  811. switch( stack->MinorFunction )
  812. {
  813. case IRP_MN_START_DEVICE:
  814. SmartcardDebug(
  815. DEBUG_DRIVER,
  816. ("RNBO3531!PnPDeviceControl: IRP_MN_START_DEVICE\n")
  817. );
  818. // We have to call the underlying driver first
  819. status = RBSCCallSerialDriver( AttachedSerialPort, Irp );
  820. ASSERT( status == STATUS_SUCCESS );
  821. if( status == STATUS_SUCCESS)
  822. {
  823. status = RBSCStartDevice( DeviceObject );
  824. }
  825. break;
  826. case IRP_MN_QUERY_STOP_DEVICE:
  827. SmartcardDebug(
  828. DEBUG_DRIVER,
  829. ("RNBO3531!PnPDeviceControl: IRP_MN_QUERY_STOP_DEVICE\n")
  830. );
  831. KeAcquireSpinLock( &ReaderExtension->SpinLock, &irql );
  832. if( ReaderExtension->IoCount > 0 )
  833. {
  834. // we refuse to stop if we have pending io
  835. KeReleaseSpinLock( &ReaderExtension->SpinLock, irql );
  836. status = STATUS_DEVICE_BUSY;
  837. break;
  838. }
  839. // stop processing requests
  840. KeClearEvent( &ReaderExtension->ReaderStarted );
  841. KeReleaseSpinLock( &ReaderExtension->SpinLock, irql );
  842. status = RBSCCallSerialDriver( AttachedSerialPort, Irp );
  843. break;
  844. case IRP_MN_CANCEL_STOP_DEVICE:
  845. SmartcardDebug(
  846. DEBUG_DRIVER,
  847. ("RNBO3531!PnPDeviceControl: IRP_MN_CANCEL_STOP_DEVICE\n")
  848. );
  849. status = RBSCCallSerialDriver( AttachedSerialPort, Irp );
  850. if( status == STATUS_SUCCESS )
  851. {
  852. // we can continue to process requests
  853. KeSetEvent( &ReaderExtension->ReaderStarted, 0, FALSE );
  854. }
  855. break;
  856. case IRP_MN_STOP_DEVICE:
  857. SmartcardDebug(
  858. DEBUG_DRIVER,
  859. ("RNBO3531!PnPDeviceControl: IRP_MN_STOP_DEVICE\n")
  860. );
  861. RBSCStopDevice( ReaderExtension );
  862. status = RBSCCallSerialDriver( AttachedSerialPort, Irp );
  863. break;
  864. case IRP_MN_QUERY_REMOVE_DEVICE:
  865. SmartcardDebug(
  866. DEBUG_DRIVER,
  867. ("RNBO3531!PnPDeviceControl: IRP_MN_QUERY_REMOVE_DEVICE\n")
  868. );
  869. // disable the interface (and ignore possible errors)
  870. IoSetDeviceInterfaceState(
  871. &ReaderExtension->PnPDeviceName,
  872. FALSE
  873. );
  874. // now look if someone is currently connected to us
  875. if (ReaderExtension->ReaderOpen)
  876. {
  877. //
  878. // someone is connected, fail the call
  879. // we will enable the device interface in
  880. // IRP_MN_CANCEL_REMOVE_DEVICE again
  881. //
  882. status = STATUS_UNSUCCESSFUL;
  883. break;
  884. }
  885. // pass the call to the next driver in the stack
  886. status = RBSCCallSerialDriver( AttachedSerialPort, Irp );
  887. break;
  888. case IRP_MN_CANCEL_REMOVE_DEVICE:
  889. SmartcardDebug(
  890. DEBUG_DRIVER,
  891. ("RNBO3531!PnPDeviceControl: IRP_MN_CANCEL_REMOVE_DEVICE\n")
  892. );
  893. status = RBSCCallSerialDriver( AttachedSerialPort, Irp );
  894. //
  895. // reenable the interface only in case that the reader is
  896. // still connected. This covers the following case:
  897. // hibernate machine, disconnect reader, wake up, stop device
  898. // (from task bar) and stop fails since an app. holds the device open
  899. //
  900. if( status == STATUS_SUCCESS &&
  901. ReaderExtension->WaitMask != 0 )
  902. {
  903. status = IoSetDeviceInterfaceState(
  904. &ReaderExtension->PnPDeviceName,
  905. TRUE
  906. );
  907. ASSERT(status == STATUS_SUCCESS);
  908. }
  909. break;
  910. case IRP_MN_REMOVE_DEVICE:
  911. // Remove our device
  912. SmartcardDebug(
  913. DEBUG_DRIVER,
  914. ("RNBO3531!PnPDeviceControl: IRP_MN_REMOVE_DEVICE\n")
  915. );
  916. RBSCRemoveDevice( DeviceObject );
  917. // DeviceObject is freed, do not reference it again.
  918. status = RBSCCallSerialDriver( AttachedSerialPort, Irp );
  919. deviceRemoved = TRUE;
  920. break;
  921. default:
  922. // This is an Irp that is only useful for underlying drivers
  923. IoSkipCurrentIrpStackLocation(Irp);
  924. status = IoCallDriver( AttachedSerialPort, Irp );
  925. irpSkipped = TRUE;
  926. break;
  927. }
  928. if( !irpSkipped )
  929. {
  930. Irp->IoStatus.Status = status;
  931. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  932. }
  933. if( !deviceRemoved )
  934. {
  935. SmartcardReleaseRemoveLockWithTag(
  936. &ReaderExtension->SmartcardExtension, ' PnP' );
  937. }
  938. SmartcardDebug(
  939. DEBUG_TRACE,
  940. ("RNBO3531!PnPDeviceControl: Exit %x\n",status)
  941. );
  942. return status;
  943. }
  944. #endif
  945. NTSTATUS
  946. RBSCAddDevice(
  947. PDRIVER_OBJECT DriverObject,
  948. PDEVICE_OBJECT PhysicalDeviceObject
  949. )
  950. /*++
  951. Routine Description:
  952. This is the add-device routine for the miniport.
  953. Find a device slot then, create device object and attach it to the
  954. given PhysicalDeviceObject.
  955. Initialize the device extension and its smart card data.
  956. Arguments:
  957. DriverObject - a pointer to the driver object for this device
  958. PhysicalDeviceObject- The device object of the serial port to attach to
  959. Return Value:
  960. NTSTATUS
  961. --*/
  962. {
  963. NTSTATUS status;
  964. PDEVICE_OBJECT DeviceObject = NULL;
  965. PSMARTCARD_EXTENSION SmartcardExtension = NULL;
  966. PAGED_CODE();
  967. SmartcardDebug(
  968. DEBUG_TRACE,
  969. ("RNBO3531!AddDevice: Enter\n")
  970. );
  971. try {
  972. ULONG DeviceNo;
  973. PREADER_EXTENSION ReaderExtension;
  974. #ifndef NT5
  975. UNICODE_STRING SmartcardDeviceName;
  976. for( DeviceNo = 0;
  977. DeviceNo < MAXIMUM_SERIAL_READERS;
  978. DeviceNo++ )
  979. {
  980. if( (UsedPortsMask & (1<<DeviceNo)) == 0 )
  981. {
  982. break;
  983. }
  984. }
  985. if( DeviceNo == MAXIMUM_SERIAL_READERS )
  986. {
  987. SmartcardLogError(
  988. DriverObject,
  989. RBSC_CANT_CREATE_MORE_DEVICES,
  990. NULL,
  991. 0
  992. );
  993. status = STATUS_INSUFFICIENT_RESOURCES;
  994. leave;
  995. }
  996. //
  997. // construct the device name
  998. //
  999. RtlInitUnicodeString( &SmartcardDeviceName, L"\\Device\\RNBO3531?" );
  1000. SmartcardDeviceName.Buffer[16] = L'0' + (WCHAR) DeviceNo;
  1001. #endif
  1002. //
  1003. // Create the functional device object
  1004. //
  1005. status = IoCreateDevice(
  1006. DriverObject,
  1007. sizeof(READER_EXTENSION),
  1008. #ifdef NT5
  1009. NULL, // No name
  1010. #else
  1011. &SmartcardDeviceName,
  1012. #endif
  1013. FILE_DEVICE_SMARTCARD,
  1014. 0,
  1015. TRUE, // Exclusive
  1016. &DeviceObject
  1017. );
  1018. if( status != STATUS_SUCCESS )
  1019. {
  1020. SmartcardLogError( DriverObject,
  1021. RBSC_CANT_CREATE_DEVICE,
  1022. NULL,
  1023. 0 );
  1024. leave;
  1025. }
  1026. //
  1027. // set up the device extension and initialize it.
  1028. //
  1029. ReaderExtension = DeviceObject->DeviceExtension;
  1030. SmartcardExtension = &ReaderExtension->SmartcardExtension;
  1031. SmartcardExtension->ReaderExtension = ReaderExtension;
  1032. #ifdef NT5
  1033. ReaderExtension->CloseSerial = IoAllocateWorkItem(
  1034. DeviceObject
  1035. );
  1036. if (ReaderExtension->CloseSerial == NULL) {
  1037. SmartcardLogError(
  1038. DriverObject,
  1039. RBSC_NO_MEMORY,
  1040. NULL,
  1041. 0
  1042. );
  1043. leave;
  1044. }
  1045. #endif
  1046. // Used for stop / start notification
  1047. KeInitializeEvent( &ReaderExtension->ReaderStarted,
  1048. NotificationEvent,
  1049. FALSE );
  1050. KeInitializeEvent( &ReaderExtension->SerialCloseDone,
  1051. NotificationEvent,
  1052. TRUE );
  1053. // Used to keep track of open close calls
  1054. ReaderExtension->ReaderOpen = FALSE;
  1055. KeInitializeSpinLock( &ReaderExtension->SpinLock );
  1056. //
  1057. // enter correct version of the lib
  1058. //
  1059. SmartcardExtension->Version = SMCLIB_VERSION;
  1060. SmartcardExtension->SmartcardRequest.BufferSize =
  1061. SmartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
  1062. status = SmartcardInitialize( SmartcardExtension );
  1063. if( status != STATUS_SUCCESS )
  1064. {
  1065. SmartcardLogError(
  1066. DriverObject,
  1067. (SmartcardExtension->OsData ?
  1068. RBSC_WRONG_LIB_VESION : RBSC_NO_MEMORY),
  1069. NULL,
  1070. 0
  1071. );
  1072. leave;
  1073. }
  1074. //
  1075. // Set up call back functions
  1076. //
  1077. SmartcardExtension->ReaderFunction[ RDF_TRANSMIT ] =
  1078. RBSCTransmit;
  1079. SmartcardExtension->ReaderFunction[ RDF_SET_PROTOCOL ] =
  1080. RBSCSetProtocol;
  1081. SmartcardExtension->ReaderFunction[ RDF_CARD_POWER ] =
  1082. RBSCReaderPower;
  1083. SmartcardExtension->ReaderFunction[ RDF_CARD_TRACKING ] =
  1084. RBSCCardTracking;
  1085. //
  1086. // setup smartcard extension
  1087. //
  1088. //
  1089. // Initialize the vendor information
  1090. //
  1091. strcpy( SmartcardExtension->VendorAttr.VendorName.Buffer,
  1092. VENDOR_NAME );
  1093. SmartcardExtension->VendorAttr.VendorName.Length =
  1094. sizeof(VENDOR_NAME);
  1095. strcpy( SmartcardExtension->VendorAttr.IfdType.Buffer,
  1096. READER_NAME );
  1097. SmartcardExtension->VendorAttr.IfdType.Length =
  1098. sizeof(READER_NAME);
  1099. SmartcardExtension->VendorAttr.UnitNo = MAXULONG;
  1100. for (DeviceNo = 0; DeviceNo < MAXULONG; DeviceNo++)
  1101. {
  1102. PDEVICE_OBJECT devObj;
  1103. for (devObj = DeviceObject;
  1104. devObj != NULL;
  1105. devObj = devObj->NextDevice)
  1106. {
  1107. PREADER_EXTENSION devExt = devObj->DeviceExtension;
  1108. if (DeviceNo ==
  1109. devExt->SmartcardExtension.VendorAttr.UnitNo)
  1110. {
  1111. break;
  1112. }
  1113. }
  1114. if (devObj == NULL)
  1115. {
  1116. SmartcardExtension->VendorAttr.UnitNo = DeviceNo;
  1117. break;
  1118. }
  1119. }
  1120. //
  1121. // tell the lib our device object
  1122. //
  1123. SmartcardExtension->OsData->DeviceObject = DeviceObject;
  1124. #ifdef NT5
  1125. ReaderExtension->AttachedSerialPort = IoAttachDeviceToDeviceStack(
  1126. DeviceObject,
  1127. PhysicalDeviceObject
  1128. );
  1129. if( ReaderExtension->AttachedSerialPort == NULL )
  1130. {
  1131. SmartcardLogError( DriverObject,
  1132. RBSC_CANT_ATTACH_TO_SERIAL_PORT,
  1133. &DriverObject->DriverName,
  1134. 0 );
  1135. status = STATUS_UNSUCCESSFUL;
  1136. leave;
  1137. }
  1138. // register our new device
  1139. status = IoRegisterDeviceInterface( PhysicalDeviceObject,
  1140. &SmartCardReaderGuid,
  1141. NULL,
  1142. &ReaderExtension->PnPDeviceName );
  1143. ASSERT( status == STATUS_SUCCESS );
  1144. ReaderExtension->ReaderPowerState = PowerReaderWorking;
  1145. #else
  1146. //
  1147. // Save the deviceObject for the connected serial port
  1148. //
  1149. ReaderExtension->AttachedSerialPort = PhysicalDeviceObject;
  1150. status = RBSCStartDevice( DeviceObject );
  1151. if( status != STATUS_SUCCESS )
  1152. {
  1153. leave;
  1154. }
  1155. //
  1156. // Create a symbolic link
  1157. //
  1158. status = SmartcardCreateLink( &ReaderExtension->DosDeviceName,
  1159. &SmartcardDeviceName );
  1160. #endif
  1161. if( status != STATUS_SUCCESS )
  1162. {
  1163. leave;
  1164. }
  1165. //
  1166. // tell the OS that we supposed to do buffered io
  1167. //
  1168. #ifdef NT5
  1169. DeviceObject->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
  1170. #else
  1171. DeviceObject->Flags |= DO_BUFFERED_IO;
  1172. UsedPortsMask |= (1<<DeviceNo);
  1173. #endif
  1174. DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  1175. SmartcardDebug(
  1176. DEBUG_INFO,
  1177. ("RNBO3531!AddDevice: Device #%d created Ext=%08x.\n",
  1178. DeviceNo,ReaderExtension)
  1179. );
  1180. }
  1181. finally
  1182. {
  1183. if( status != STATUS_SUCCESS && DeviceObject != NULL )
  1184. {
  1185. RBSCRemoveDevice( DeviceObject );
  1186. }
  1187. }
  1188. SmartcardDebug(
  1189. DEBUG_TRACE,
  1190. ("RNBO3531!AddDevice: Exit %x\n",status)
  1191. );
  1192. return status;
  1193. }
  1194. NTSTATUS
  1195. RBSCConfigureSerialPort(
  1196. PREADER_EXTENSION ReaderExtension
  1197. )
  1198. /*++
  1199. Routine Description:
  1200. This routine reads the default configuraton values for this device.
  1201. Arguments:
  1202. ReaderExtension - Pointer to our device data
  1203. Return Value:
  1204. none
  1205. --*/
  1206. {
  1207. PSMARTCARD_EXTENSION SmartcardExtension =
  1208. &ReaderExtension->SmartcardExtension;
  1209. PUCHAR RxBuffer = SmartcardExtension->SmartcardReply.Buffer;
  1210. NTSTATUS status;
  1211. {
  1212. //
  1213. // Set up baudrate
  1214. //
  1215. SERIAL_BAUD_RATE BaudRate;
  1216. BaudRate.BaudRate = DATARATE_DEFAULT;
  1217. status = RBSCSerialIo( SmartcardExtension,
  1218. IOCTL_SERIAL_SET_BAUD_RATE,
  1219. (PUCHAR) &BaudRate,
  1220. sizeof(SERIAL_BAUD_RATE),
  1221. 0 );
  1222. }
  1223. if( status == STATUS_SUCCESS )
  1224. {
  1225. //
  1226. // Set up line control parameters
  1227. //
  1228. ReaderExtension->LineControl.Parity = ODD_PARITY;
  1229. ReaderExtension->LineControl.StopBits = STOP_BIT_1;
  1230. ReaderExtension->LineControl.WordLength = SERIAL_DATABITS_8;
  1231. status = RBSCSerialIo( SmartcardExtension,
  1232. IOCTL_SERIAL_SET_LINE_CONTROL,
  1233. (PUCHAR)&ReaderExtension->LineControl,
  1234. sizeof(SERIAL_LINE_CONTROL),
  1235. 0 );
  1236. }
  1237. if( status == STATUS_SUCCESS )
  1238. {
  1239. //
  1240. // Set serial special characters
  1241. //
  1242. SERIAL_CHARS SerialChars;
  1243. SerialChars.ErrorChar = 0;
  1244. SerialChars.EofChar = 0;
  1245. SerialChars.EventChar = 0;
  1246. SerialChars.XonChar = 0;
  1247. SerialChars.XoffChar = 0;
  1248. SerialChars.BreakChar = 0xFF;
  1249. status = RBSCSerialIo( SmartcardExtension,
  1250. IOCTL_SERIAL_SET_CHARS,
  1251. (PUCHAR) &SerialChars,
  1252. sizeof(SERIAL_CHARS),
  1253. 0 );
  1254. }
  1255. if( status == STATUS_SUCCESS )
  1256. {
  1257. //
  1258. // Set up timeouts (all in msec)
  1259. //
  1260. ReaderExtension->SerialTimeouts.ReadTotalTimeoutMultiplier = 1;
  1261. ReaderExtension->SerialTimeouts.ReadIntervalTimeout = 2*
  1262. ATR_CHAR_TIMEOUT/1000;
  1263. ReaderExtension->SerialTimeouts.ReadTotalTimeoutConstant = 2*
  1264. ATR_BLOCK_TIMEOUT/1000;
  1265. status = RBSCSerialIo( SmartcardExtension,
  1266. IOCTL_SERIAL_SET_TIMEOUTS,
  1267. (PUCHAR)&ReaderExtension->SerialTimeouts,
  1268. sizeof(SERIAL_TIMEOUTS),
  1269. 0 );
  1270. }
  1271. if( status == STATUS_SUCCESS )
  1272. {
  1273. //
  1274. // Set flowcontrol and handshaking
  1275. //
  1276. SERIAL_HANDFLOW HandFlow;
  1277. HandFlow.XonLimit = 0;
  1278. HandFlow.XoffLimit = 0;
  1279. HandFlow.FlowReplace = SERIAL_XOFF_CONTINUE ;
  1280. HandFlow.ControlHandShake = 0;
  1281. status = RBSCSerialIo( SmartcardExtension,
  1282. IOCTL_SERIAL_SET_HANDFLOW,
  1283. (PUCHAR) &HandFlow,
  1284. sizeof(SERIAL_HANDFLOW),
  1285. 0 );
  1286. }
  1287. if( status == STATUS_SUCCESS )
  1288. {
  1289. //
  1290. // Set break off
  1291. //
  1292. status = RBSCSerialIo( SmartcardExtension,
  1293. IOCTL_SERIAL_SET_BREAK_OFF,
  1294. NULL,
  1295. 0,
  1296. 0 );
  1297. }
  1298. if( status == STATUS_SUCCESS )
  1299. {
  1300. status = RBSCSerialIo( SmartcardExtension,
  1301. IOCTL_SERIAL_SET_RTS,
  1302. NULL,
  1303. 0,
  1304. 0 );
  1305. }
  1306. if( status == STATUS_SUCCESS )
  1307. {
  1308. status = RBSCSerialIo( SmartcardExtension,
  1309. IOCTL_SERIAL_SET_DTR,
  1310. NULL,
  1311. 0,
  1312. 0 );
  1313. }
  1314. if( status == STATUS_SUCCESS )
  1315. {
  1316. //
  1317. // Toggle DTR line to wake-up the reader if it is
  1318. // in SLEEP mode
  1319. //
  1320. RBSCDelay( 10000 );
  1321. status = RBSCSerialIo( SmartcardExtension,
  1322. IOCTL_SERIAL_CLR_DTR,
  1323. NULL,
  1324. 0,
  1325. 0 );
  1326. }
  1327. if( status == STATUS_SUCCESS )
  1328. {
  1329. status = RBSCSerialIo( SmartcardExtension,
  1330. IOCTL_SERIAL_SET_DTR,
  1331. NULL,
  1332. 0,
  1333. 0 );
  1334. }
  1335. if( status == STATUS_SUCCESS )
  1336. {
  1337. RBSCDelay( 10000 );
  1338. status = RBSCPacketExchange( SmartcardExtension,
  1339. GetReaderType,
  1340. sizeof(GetReaderType),
  1341. WAIT_TIME_READER_TYPE,
  1342. TRUE );
  1343. }
  1344. if( status != STATUS_SUCCESS )
  1345. {
  1346. return status;
  1347. }
  1348. if( SmartcardExtension->SmartcardReply.BufferLength <
  1349. SIZE_READER_TYPE ||
  1350. RxBuffer[0] != 'R' || RxBuffer[1] != 'N' ||
  1351. RxBuffer[2] != 'B' || RxBuffer[3] != 'O' ||
  1352. RxBuffer[15] != READER_TYPE_1 )
  1353. {
  1354. return STATUS_DEVICE_DATA_ERROR;
  1355. }
  1356. //
  1357. // Set reader info
  1358. //
  1359. SmartcardExtension->VendorAttr.IfdVersion.VersionMajor =
  1360. (UCHAR)RxBuffer[6];
  1361. SmartcardExtension->VendorAttr.IfdVersion.VersionMinor =
  1362. (UCHAR)RxBuffer[7];
  1363. SmartcardExtension->VendorAttr.IfdVersion.BuildNumber =
  1364. ((USHORT)RxBuffer[8]<<8) + ((USHORT)RxBuffer[9]);
  1365. //
  1366. // Clk frequency in KHz encoded as little endian integer
  1367. //
  1368. SmartcardExtension->ReaderCapabilities.CLKFrequency.Default =
  1369. SmartcardExtension->ReaderCapabilities.CLKFrequency.Max =
  1370. ((USHORT)RxBuffer[10]<<8) + ((USHORT)RxBuffer[11]);
  1371. SmartcardExtension->ReaderCapabilities.DataRate.Default =
  1372. SmartcardExtension->ReaderCapabilities.DataRate.Max = DATARATE_DEFAULT;
  1373. if( RxBuffer[13] != 0 )
  1374. {
  1375. // reader is supposed to support higher data rates
  1376. ULONG NumRates = 1;
  1377. if( RxBuffer[13] & DATARATE_14400 )
  1378. {
  1379. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  1380. ReaderExtension->DataRatesSupported[ NumRates++ ] = 14400;
  1381. }
  1382. if( RxBuffer[13] & DATARATE_19200 )
  1383. {
  1384. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  1385. ReaderExtension->DataRatesSupported[ NumRates++ ] = 19200;
  1386. }
  1387. if( RxBuffer[13] & DATARATE_28800 )
  1388. {
  1389. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  1390. ReaderExtension->DataRatesSupported[ NumRates++ ] = 28800;
  1391. }
  1392. if( RxBuffer[13] & DATARATE_38400 )
  1393. {
  1394. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  1395. ReaderExtension->DataRatesSupported[ NumRates++ ] = 38400;
  1396. }
  1397. if( RxBuffer[13] & DATARATE_57600 )
  1398. {
  1399. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  1400. ReaderExtension->DataRatesSupported[ NumRates++ ] = 57600;
  1401. }
  1402. if( RxBuffer[13] & DATARATE_115200 )
  1403. {
  1404. SmartcardExtension->ReaderCapabilities.DataRate.Max =
  1405. ReaderExtension->DataRatesSupported[ NumRates++ ] = 115200;
  1406. }
  1407. if( NumRates > 1 )
  1408. {
  1409. ReaderExtension->DataRatesSupported[0] = 9600; // always supported
  1410. SmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
  1411. (UCHAR) NumRates;
  1412. SmartcardExtension->ReaderCapabilities.DataRatesSupported.List =
  1413. ReaderExtension->DataRatesSupported;
  1414. SmartcardDebug(
  1415. DEBUG_INFO,
  1416. ("RNBO3531!ConfigureSerialPort: %ld DataRates, Max=%ld\n",
  1417. NumRates,
  1418. SmartcardExtension->ReaderCapabilities.DataRate.Max)
  1419. );
  1420. }
  1421. }
  1422. SmartcardExtension->ReaderCapabilities.MaxIFSD = MAX_IFSD;
  1423. //
  1424. // setup smartcard extension - reader capabilities
  1425. //
  1426. SmartcardExtension->ReaderCapabilities.SupportedProtocols =
  1427. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
  1428. SmartcardExtension->ReaderCapabilities.ReaderType =
  1429. SCARD_READER_TYPE_SERIAL;
  1430. status = RBSCSerialIo( SmartcardExtension,
  1431. IOCTL_SERIAL_GET_MODEMSTATUS,
  1432. NULL,
  1433. 0,
  1434. sizeof(ReaderExtension->ModemStatus) );
  1435. if( status == STATUS_SUCCESS )
  1436. {
  1437. ReaderExtension->ModemStatus =
  1438. *(PULONG)SmartcardExtension->SmartcardReply.Buffer;
  1439. SmartcardExtension->ReaderCapabilities.CurrentState =
  1440. (ReaderExtension->ModemStatus & SERIAL_CTS_STATE) ?
  1441. SCARD_SWALLOWED : SCARD_ABSENT;
  1442. }
  1443. return STATUS_SUCCESS;
  1444. }
  1445. NTSTATUS
  1446. RBSCCreateClose(
  1447. PDEVICE_OBJECT DeviceObject,
  1448. PIRP Irp
  1449. )
  1450. /*++
  1451. Routine Description:
  1452. This routine is called by the I/O system when the device is opened
  1453. or closed.
  1454. Arguments:
  1455. DeviceObject - Pointer to device object
  1456. Irp - IRP involved.
  1457. Return Value:
  1458. STATUS_SUCCESS.
  1459. --*/
  1460. {
  1461. PREADER_EXTENSION ReaderExtension = DeviceObject->DeviceExtension;
  1462. PSMARTCARD_EXTENSION SmartcardExtension =
  1463. &ReaderExtension->SmartcardExtension;
  1464. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  1465. NTSTATUS status = STATUS_SUCCESS;
  1466. __try
  1467. {
  1468. if( irpStack->MajorFunction == IRP_MJ_CREATE )
  1469. {
  1470. SmartcardDebug(
  1471. DEBUG_DRIVER,
  1472. ("RNBO3531!Create\n")
  1473. );
  1474. #ifdef NT5
  1475. if( SmartcardAcquireRemoveLockWithTag(
  1476. SmartcardExtension, 'lCrC' ) != STATUS_SUCCESS )
  1477. {
  1478. status = STATUS_DEVICE_REMOVED;
  1479. __leave;
  1480. }
  1481. // test if the device has been opened already
  1482. if (InterlockedCompareExchange(
  1483. &ReaderExtension->ReaderOpen,
  1484. TRUE,
  1485. FALSE) == FALSE)
  1486. {
  1487. SmartcardDebug(
  1488. DEBUG_DRIVER,
  1489. ("RNBO3531!CreateClose: Open\n")
  1490. );
  1491. }
  1492. else
  1493. {
  1494. // the device is already in use
  1495. status = STATUS_UNSUCCESSFUL;
  1496. // release the lock
  1497. SmartcardReleaseRemoveLockWithTag( SmartcardExtension,
  1498. 'lCrC' );
  1499. }
  1500. #endif
  1501. } else {
  1502. SmartcardDebug(
  1503. DEBUG_DRIVER,
  1504. ("RNBO3531!Close\n")
  1505. );
  1506. #ifdef NT5
  1507. SmartcardReleaseRemoveLockWithTag( SmartcardExtension,
  1508. 'lCrC' );
  1509. #endif
  1510. ReaderExtension->ReaderOpen = FALSE;
  1511. }
  1512. }
  1513. __finally
  1514. {
  1515. Irp->IoStatus.Status = status;
  1516. Irp->IoStatus.Information = 0;
  1517. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  1518. }
  1519. return status;
  1520. }
  1521. NTSTATUS
  1522. RBSCCancel(
  1523. PDEVICE_OBJECT DeviceObject,
  1524. PIRP Irp
  1525. )
  1526. /*++
  1527. Routine Description:
  1528. This routine is called by the I/O system
  1529. when the irp should be cancelled
  1530. Arguments:
  1531. DeviceObject - Pointer to device object
  1532. Irp - IRP involved.
  1533. Return Value:
  1534. STATUS_CANCELLED
  1535. --*/
  1536. {
  1537. PREADER_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1538. PSMARTCARD_EXTENSION SmartcardExtension = &deviceExtension->SmartcardExtension;
  1539. SmartcardDebug(
  1540. DEBUG_TRACE,
  1541. ("%s!RBSCCancel: Enter\n",
  1542. DRIVER_NAME)
  1543. );
  1544. ASSERT(Irp == SmartcardExtension->OsData->NotificationIrp);
  1545. IoReleaseCancelSpinLock(
  1546. Irp->CancelIrql
  1547. );
  1548. RBSCCompleteCardTracking(SmartcardExtension);
  1549. SmartcardDebug(
  1550. DEBUG_TRACE,
  1551. ("%s!RBSCCancel: Exit\n",
  1552. DRIVER_NAME)
  1553. );
  1554. return STATUS_CANCELLED;
  1555. }
  1556. NTSTATUS
  1557. RBSCCleanup(
  1558. PDEVICE_OBJECT DeviceObject,
  1559. PIRP Irp
  1560. )
  1561. /*++
  1562. Routine Description:
  1563. This routine is called by the I/O system when the calling thread
  1564. terminates
  1565. Arguments:
  1566. DeviceObject - Pointer to device object
  1567. Irp - IRP involved.
  1568. Return Value:
  1569. STATUS_CANCELLED
  1570. --*/
  1571. {
  1572. PREADER_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  1573. PSMARTCARD_EXTENSION SmartcardExtension = &deviceExtension->SmartcardExtension;
  1574. NTSTATUS status = STATUS_SUCCESS;
  1575. SmartcardDebug(
  1576. DEBUG_TRACE,
  1577. ("%s!RBSCCleanup: Enter\n",
  1578. DRIVER_NAME)
  1579. );
  1580. ASSERT(Irp != SmartcardExtension->OsData->NotificationIrp);
  1581. // We need to complete the notification irp
  1582. RBSCCompleteCardTracking(SmartcardExtension);
  1583. SmartcardDebug(
  1584. DEBUG_DRIVER,
  1585. ("%s!RBSCCleanup: Completing IRP %lx\n",
  1586. DRIVER_NAME,
  1587. Irp)
  1588. );
  1589. Irp->IoStatus.Information = 0;
  1590. Irp->IoStatus.Status = STATUS_SUCCESS;
  1591. IoCompleteRequest(
  1592. Irp,
  1593. IO_NO_INCREMENT
  1594. );
  1595. SmartcardDebug(
  1596. DEBUG_TRACE,
  1597. ("%s!RBSCCleanup: Exit\n",
  1598. DRIVER_NAME)
  1599. );
  1600. return STATUS_SUCCESS;
  1601. }
  1602. NTSTATUS
  1603. RBSCSerialIo(
  1604. PSMARTCARD_EXTENSION SmartcardExtension,
  1605. ULONG SerialIoControlCode,
  1606. PUCHAR TxBuffer,
  1607. ULONG TxSize,
  1608. ULONG RxSize
  1609. )
  1610. /*++
  1611. Routine Description:
  1612. This routine sends IOCTL's to the serial driver. It waits on for their
  1613. completion, and then returns.
  1614. Arguments:
  1615. SmartcardExtension - Pointer to the smart card data
  1616. SerialIoControlCode - IOCTL code to be sent to the serial driver
  1617. TxBuffer - Ponter to the data to send
  1618. TxSize - Size of data to send
  1619. RxSize - Number of bytes expected to receive
  1620. Return Value:
  1621. NTSTATUS
  1622. --*/
  1623. {
  1624. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  1625. NTSTATUS status;
  1626. IO_STATUS_BLOCK ioStatus;
  1627. KEVENT event;
  1628. PIRP irp;
  1629. if (KeReadStateEvent(&ReaderExtension->SerialCloseDone))
  1630. {
  1631. //
  1632. // we have no connection to serial, fail the call
  1633. // this could be the case if the reader was removed
  1634. // during stand by / hibernation
  1635. //
  1636. return STATUS_UNSUCCESSFUL;
  1637. }
  1638. //
  1639. // Check if the buffers are large enough
  1640. //
  1641. ASSERT( RxSize <= SmartcardExtension->SmartcardReply.BufferSize );
  1642. if( RxSize > SmartcardExtension->SmartcardReply.BufferSize )
  1643. {
  1644. SmartcardLogError( SmartcardExtension->OsData->DeviceObject,
  1645. RBSC_BUFFER_TOO_SMALL,
  1646. NULL,
  1647. 0 );
  1648. return STATUS_BUFFER_TOO_SMALL;
  1649. }
  1650. KeInitializeEvent( &event, NotificationEvent, FALSE );
  1651. //
  1652. // Build irp to be sent to serial driver
  1653. //
  1654. irp = IoBuildDeviceIoControlRequest(
  1655. SerialIoControlCode,
  1656. ReaderExtension->AttachedSerialPort,
  1657. (TxSize ? TxBuffer : NULL),
  1658. TxSize,
  1659. (RxSize ? SmartcardExtension->SmartcardReply.Buffer : NULL),
  1660. RxSize,
  1661. FALSE,
  1662. &event,
  1663. &ioStatus
  1664. );
  1665. ASSERT( irp != NULL );
  1666. if( irp == NULL )
  1667. {
  1668. return STATUS_INSUFFICIENT_RESOURCES;
  1669. }
  1670. switch( SerialIoControlCode )
  1671. {
  1672. PIO_STACK_LOCATION nextsp;
  1673. //
  1674. // The serial driver trasfers data from/to
  1675. // irp->AssociatedIrp.SystemBuffer
  1676. //
  1677. case SMARTCARD_WRITE:
  1678. nextsp = IoGetNextIrpStackLocation( irp );
  1679. nextsp->MajorFunction = IRP_MJ_WRITE;
  1680. nextsp->Parameters.Write.Length = TxSize;
  1681. nextsp->Parameters.Write.ByteOffset.QuadPart = 0;
  1682. break;
  1683. case SMARTCARD_READ:
  1684. nextsp = IoGetNextIrpStackLocation( irp );
  1685. nextsp->MajorFunction = IRP_MJ_READ;
  1686. nextsp->Parameters.Read.Length = RxSize;
  1687. nextsp->Parameters.Read.ByteOffset.QuadPart = 0;
  1688. break;
  1689. }
  1690. status = IoCallDriver( ReaderExtension->AttachedSerialPort, irp );
  1691. if( status == STATUS_PENDING )
  1692. {
  1693. KeWaitForSingleObject( &event,
  1694. Suspended,
  1695. KernelMode,
  1696. FALSE,
  1697. NULL );
  1698. status = ioStatus.Status;
  1699. if( status == STATUS_TIMEOUT &&
  1700. ioStatus.Information != 0 &&
  1701. ioStatus.Information < RxSize )
  1702. {
  1703. // Ignore time-out if some data returned
  1704. status = STATUS_SUCCESS;
  1705. }
  1706. // save the number of bytes received
  1707. SmartcardExtension->SmartcardReply.BufferLength =
  1708. (RxSize != 0 && status == STATUS_SUCCESS) ?
  1709. (ULONG) ioStatus.Information : 0;
  1710. } else {
  1711. SmartcardExtension->SmartcardReply.BufferLength =
  1712. (status == STATUS_SUCCESS) ? RxSize : 0;
  1713. }
  1714. #if 0
  1715. if( SerialIoControlCode == SMARTCARD_WRITE )
  1716. {
  1717. // TDB: Wait for Tx buffer empty
  1718. }
  1719. #endif
  1720. //
  1721. // STATUS_TIMEOUT isn't correctly mapped
  1722. // to a WIN32 error, that's why we change it here
  1723. // to STATUS_IO_TIMEOUT
  1724. //
  1725. return( (status == STATUS_TIMEOUT) ? STATUS_IO_TIMEOUT : status );
  1726. }
  1727. NTSTATUS
  1728. RBSCWriteToCard(
  1729. PSMARTCARD_EXTENSION SmartcardExtension,
  1730. PUCHAR Buffer,
  1731. ULONG Length
  1732. )
  1733. /*++
  1734. Routine Description:
  1735. This routine sends data to the smart card. It handles the inverse
  1736. convention and gaurd time.
  1737. Arguments:
  1738. SmartcardExtension - Pointer to our smartcard data
  1739. Buffer - Points to the data to send
  1740. Length - Length of data to send (bytes)
  1741. Return Value:
  1742. NTSTATUS
  1743. --*/
  1744. {
  1745. NTSTATUS status;
  1746. UCHAR TempBuffer[MIN_BUFFER_SIZE];
  1747. ULONG StopBits = SmartcardExtension->CardCapabilities.PtsData.StopBits;
  1748. DumpData( "Data to the card", Buffer, Length );
  1749. if( SmartcardExtension->CardCapabilities.ATR.Buffer[0] == 0x3F )
  1750. {
  1751. ULONG l;
  1752. if( Length > sizeof(TempBuffer) )
  1753. {
  1754. return STATUS_DEVICE_DATA_ERROR;
  1755. }
  1756. for( l = 0; l < Length; l++ )
  1757. {
  1758. TempBuffer[l] = InverseCharTable[ Buffer[l] ];
  1759. }
  1760. Buffer = TempBuffer;
  1761. }
  1762. if( StopBits <= 2 )
  1763. {
  1764. return RBSCSerialIo( SmartcardExtension,
  1765. SMARTCARD_WRITE,
  1766. Buffer,
  1767. Length,
  1768. 0 );
  1769. }
  1770. while( Length != 0 )
  1771. {
  1772. status = RBSCSerialIo( SmartcardExtension,
  1773. SMARTCARD_WRITE,
  1774. Buffer,
  1775. 1,
  1776. 0 );
  1777. if( status != STATUS_SUCCESS )
  1778. {
  1779. return status;
  1780. }
  1781. Buffer++;
  1782. Length--;
  1783. if( Length != 0 )
  1784. KeStallExecutionProcessor(
  1785. (StopBits-1)*SmartcardExtension->CardCapabilities.etu );
  1786. }
  1787. return STATUS_SUCCESS;
  1788. }
  1789. NTSTATUS
  1790. RBSCSetCommParams(
  1791. PSMARTCARD_EXTENSION SmartcardExtension,
  1792. ULONG DataRate
  1793. )
  1794. /*++
  1795. Routine Description:
  1796. This routine sets the stop bits and read timeouts of the serial driver.
  1797. Arguments:
  1798. SmartcardExtension - Pointer to our smartcard data
  1799. Return Value:
  1800. NTSTATUS
  1801. --*/
  1802. {
  1803. NTSTATUS status;
  1804. PSERIAL_LINE_CONTROL plc =
  1805. &SmartcardExtension->ReaderExtension->LineControl;
  1806. PSERIAL_TIMEOUTS timeout =
  1807. &SmartcardExtension->ReaderExtension->SerialTimeouts;
  1808. SmartcardDebug(
  1809. DEBUG_PROTOCOL,
  1810. ("RNBO3531!SetCommParams: DataRate=%ld, StopBits=%d\n",
  1811. DataRate,SmartcardExtension->CardCapabilities.PtsData.StopBits)
  1812. );
  1813. plc->StopBits =
  1814. (SmartcardExtension->CardCapabilities.PtsData.StopBits == 2) ?
  1815. STOP_BITS_2 : STOP_BIT_1;
  1816. status = RBSCSerialIo( SmartcardExtension,
  1817. IOCTL_SERIAL_SET_LINE_CONTROL,
  1818. (PUCHAR) plc,
  1819. sizeof(SERIAL_LINE_CONTROL),
  1820. 0 );
  1821. if( status != STATUS_SUCCESS )
  1822. {
  1823. return status;
  1824. }
  1825. if( SmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries > 1 )
  1826. {
  1827. // Setup baudrate
  1828. SERIAL_BAUD_RATE BaudRate;
  1829. BaudRate.BaudRate = DataRate;
  1830. status = RBSCSerialIo( SmartcardExtension,
  1831. IOCTL_SERIAL_SET_BAUD_RATE,
  1832. (PUCHAR) &BaudRate,
  1833. sizeof(SERIAL_BAUD_RATE),
  1834. 0 );
  1835. if( status != STATUS_SUCCESS )
  1836. {
  1837. return status;
  1838. }
  1839. }
  1840. if( SmartcardExtension->CardCapabilities.Protocol.Selected &
  1841. SCARD_PROTOCOL_T1 )
  1842. {
  1843. timeout->ReadTotalTimeoutConstant = 2* // for safty
  1844. (SmartcardExtension->CardCapabilities.T1.BWT +
  1845. WAIT_TIME_MINIMUM)/1000;
  1846. timeout->ReadIntervalTimeout = 2* // for safty
  1847. (SmartcardExtension->CardCapabilities.T1.CWT +
  1848. WAIT_TIME_MINIMUM)/1000;
  1849. } else {
  1850. timeout->ReadTotalTimeoutConstant =
  1851. timeout->ReadIntervalTimeout = 2* // for safty
  1852. (SmartcardExtension->CardCapabilities.T0.WT +
  1853. WAIT_TIME_MINIMUM)/1000;
  1854. }
  1855. //
  1856. // Set up timeout (in msec)
  1857. //
  1858. return RBSCSerialIo( SmartcardExtension,
  1859. IOCTL_SERIAL_SET_TIMEOUTS,
  1860. (PUCHAR) timeout,
  1861. sizeof(SERIAL_TIMEOUTS),
  1862. 0 );
  1863. }
  1864. NTSTATUS
  1865. RBSCReadFromCard(
  1866. PSMARTCARD_EXTENSION SmartcardExtension,
  1867. ULONG Length
  1868. )
  1869. /*++
  1870. Routine Description:
  1871. Reads a block of data from the card.
  1872. On successful read, it converts the data if inverse conversion used.
  1873. Arguments:
  1874. SmartcardExtension - Pointer to smart card data.
  1875. Length - Number of bytes to read.
  1876. Return Value:
  1877. NTSTATUS
  1878. --*/
  1879. {
  1880. NTSTATUS status;
  1881. SmartcardDebug(
  1882. DEBUG_PROTOCOL,
  1883. ("RNBO3531!ReadFromCard(%ld)\n",Length)
  1884. );
  1885. status = RBSCSerialIo(
  1886. SmartcardExtension,
  1887. SMARTCARD_READ,
  1888. NULL,
  1889. 0,
  1890. Length
  1891. );
  1892. if( status == STATUS_SUCCESS &&
  1893. SmartcardExtension->SmartcardReply.BufferLength != Length )
  1894. {
  1895. status = STATUS_IO_TIMEOUT;
  1896. }
  1897. if( SmartcardExtension->CardCapabilities.ATR.Buffer[0] == 0x3F )
  1898. {
  1899. ULONG i;
  1900. for( i = 0; i < SmartcardExtension->SmartcardReply.BufferLength; i++ )
  1901. {
  1902. SmartcardExtension->SmartcardReply.Buffer[i] = InverseCharTable[
  1903. SmartcardExtension->SmartcardReply.Buffer[i] ];
  1904. }
  1905. }
  1906. #if 0
  1907. // The data dump here can time-out some cards
  1908. DumpData( "Data from card",
  1909. SmartcardExtension->SmartcardReply.Buffer,
  1910. SmartcardExtension->SmartcardReply.BufferLength );
  1911. SmartcardDebug(
  1912. DEBUG_PROTOCOL,
  1913. ("RNBO3531!ReadFromCard Exit %08X\n", status)
  1914. );
  1915. #endif
  1916. return status;
  1917. }
  1918. NTSTATUS
  1919. RBSCSerialEvents(
  1920. PDEVICE_OBJECT DeviceObject,
  1921. PIRP Irp,
  1922. PREADER_EXTENSION ReaderExtension
  1923. )
  1924. /*++
  1925. Routine Description:
  1926. This routine is called in three cases:
  1927. a) CTS changed (card inserted or removed) or
  1928. b) DSR changed (reader has been removed) or
  1929. c) The serial WaitMask is set to zero
  1930. For a) we update the card status and complete outstanding
  1931. card tracking requests.
  1932. For b) and c) we start to unload the driver
  1933. Arguments:
  1934. DeviceObject - Pointer to device object
  1935. Irp - The notofication Irp
  1936. ReaderExtension - Pointer to our device data
  1937. Return Value:
  1938. NTSTATUS
  1939. --*/
  1940. {
  1941. PSMARTCARD_EXTENSION SmartcardExtension = &ReaderExtension->SmartcardExtension;
  1942. PIO_STACK_LOCATION nextsp;
  1943. NTSTATUS status;
  1944. KIRQL irql;
  1945. UNREFERENCED_PARAMETER(DeviceObject);
  1946. SmartcardDebug(
  1947. DEBUG_TRACE,
  1948. ("RNBO3531!SerialEvents: Enter\n")
  1949. );
  1950. KeAcquireSpinLock( &SmartcardExtension->OsData->SpinLock,
  1951. &irql );
  1952. if( ReaderExtension->GetModemStatus )
  1953. {
  1954. //
  1955. // This function requested the modem status previously.
  1956. // As part of the io-completion, this function is then
  1957. // called again. When we're here we can read the actual
  1958. // modem-status to figure out if the card is in the reader
  1959. //
  1960. #ifdef NT5
  1961. if( (ReaderExtension->ModemStatus & SERIAL_DSR_STATE) == 0 )
  1962. {
  1963. SmartcardDebug(
  1964. DEBUG_INFO,
  1965. ("RNBO3531!SerialEvent: Reader removed\n")
  1966. );
  1967. //
  1968. // We set the mask to zero to signal that we can
  1969. // release the irp that we use for the serial events
  1970. //
  1971. ReaderExtension->WaitMask = 0;
  1972. SmartcardExtension->ReaderCapabilities.CurrentState =
  1973. SCARD_UNKNOWN;
  1974. } else
  1975. #endif
  1976. {
  1977. if( ReaderExtension->ModemStatus & SERIAL_CTS_STATE )
  1978. {
  1979. //
  1980. // Card is inserted
  1981. //
  1982. SmartcardExtension->ReaderCapabilities.CurrentState =
  1983. SCARD_SWALLOWED;
  1984. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1985. SCARD_PROTOCOL_UNDEFINED;
  1986. SmartcardDebug(
  1987. DEBUG_DRIVER,
  1988. ("RNBO3531!SerialEvents: Smart card inserted\n")
  1989. );
  1990. } else {
  1991. //
  1992. // Card is removed
  1993. //
  1994. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  1995. SmartcardExtension->ReaderCapabilities.CurrentState =
  1996. SCARD_ABSENT;
  1997. SmartcardExtension->CardCapabilities.Protocol.Selected =
  1998. SCARD_PROTOCOL_UNDEFINED;
  1999. SmartcardDebug(
  2000. DEBUG_DRIVER,
  2001. ("RNBO3531!SerialEvents: Smart card removed\n")
  2002. );
  2003. }
  2004. }
  2005. }
  2006. KeReleaseSpinLock( &SmartcardExtension->OsData->SpinLock, irql );
  2007. if( SmartcardExtension->ReaderExtension->PowerRequest == FALSE )
  2008. {
  2009. // Inform the user of a card insertion/removal event
  2010. RBSCCompleteCardTracking( SmartcardExtension );
  2011. }
  2012. // The wait mask is set to 0 when the driver unloads
  2013. if( ReaderExtension->WaitMask == 0 )
  2014. {
  2015. #ifdef NT5
  2016. // schedule our remove thread
  2017. IoQueueWorkItem(
  2018. ReaderExtension->CloseSerial,
  2019. (PIO_WORKITEM_ROUTINE) RBSCCloseSerialPort,
  2020. DelayedWorkQueue,
  2021. NULL
  2022. );
  2023. #endif
  2024. SmartcardDebug(
  2025. DEBUG_INFO,
  2026. ("RNBO3531!SerialEvent: Exit (Release IRP)\n")
  2027. );
  2028. ReaderExtension->PowerRequest = FALSE;
  2029. //
  2030. // We don't need the IRP anymore, so free it and tell the
  2031. // io subsystem not to touch it anymore by returning the value below
  2032. //
  2033. IoFreeIrp(Irp);
  2034. return STATUS_MORE_PROCESSING_REQUIRED;
  2035. }
  2036. nextsp = IoGetNextIrpStackLocation( ReaderExtension->SerialStatusIrp );
  2037. nextsp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
  2038. nextsp->MinorFunction = 0UL;
  2039. if( ReaderExtension->GetModemStatus )
  2040. {
  2041. nextsp->Parameters.DeviceIoControl.OutputBufferLength =
  2042. sizeof(ReaderExtension->WaitMask);
  2043. nextsp->Parameters.DeviceIoControl.IoControlCode =
  2044. IOCTL_SERIAL_WAIT_ON_MASK;
  2045. ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer =
  2046. &ReaderExtension->WaitMask;
  2047. ReaderExtension->GetModemStatus = FALSE;
  2048. SmartcardDebug(
  2049. DEBUG_DRIVER,
  2050. ("RNBO3531!SerialEvents: IOCTL_SERIAL_WAIT_ON_MASK\n")
  2051. );
  2052. } else {
  2053. //
  2054. // Setup call for device control to get modem status.
  2055. // The CTS signal tells us if the card is inserted or removed.
  2056. // CTS is high if the card is inserted.
  2057. //
  2058. nextsp->Parameters.DeviceIoControl.OutputBufferLength =
  2059. sizeof(ReaderExtension->ModemStatus);
  2060. nextsp->Parameters.DeviceIoControl.IoControlCode =
  2061. IOCTL_SERIAL_GET_MODEMSTATUS;
  2062. ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer =
  2063. &ReaderExtension->ModemStatus;
  2064. ReaderExtension->GetModemStatus = TRUE;
  2065. SmartcardDebug(
  2066. DEBUG_DRIVER,
  2067. ("RNBO3531!SerialEvents: IOCTL_SERIAL_GET_MODEMSTATUS\n")
  2068. );
  2069. }
  2070. IoSetCompletionRoutine( ReaderExtension->SerialStatusIrp,
  2071. RBSCSerialEvents,
  2072. ReaderExtension,
  2073. TRUE,
  2074. TRUE,
  2075. TRUE );
  2076. status = IoCallDriver( ReaderExtension->AttachedSerialPort,
  2077. ReaderExtension->SerialStatusIrp );
  2078. ReaderExtension->PowerRequest = FALSE;
  2079. SmartcardDebug(
  2080. DEBUG_TRACE,
  2081. ("RNBO3531!SerialEvents: Exit\n")
  2082. );
  2083. return STATUS_MORE_PROCESSING_REQUIRED;
  2084. }
  2085. #ifdef NT5
  2086. NTSTATUS
  2087. RBSCDeviceControl(
  2088. PDEVICE_OBJECT DeviceObject,
  2089. PIRP Irp
  2090. )
  2091. /*++
  2092. Routine Description:
  2093. This is our IOCTL dispatch function
  2094. Arguments:
  2095. DeviceObject - Pointer to device object
  2096. Return Value:
  2097. NTSTATUS
  2098. --*/
  2099. {
  2100. PREADER_EXTENSION ReaderExtension = DeviceObject->DeviceExtension;
  2101. PSMARTCARD_EXTENSION SmartcardExtension =
  2102. &ReaderExtension->SmartcardExtension;
  2103. NTSTATUS status;
  2104. KIRQL irql;
  2105. if( ReaderExtension->WaitMask == 0 )
  2106. {
  2107. //
  2108. // the wait mask is set to 0 whenever the device was either
  2109. // surprise-removed or politely removed
  2110. //
  2111. status = STATUS_DEVICE_REMOVED;
  2112. }
  2113. else
  2114. {
  2115. KeAcquireSpinLock( &ReaderExtension->SpinLock, &irql );
  2116. if( ReaderExtension->IoCount == 0 )
  2117. {
  2118. KeReleaseSpinLock( &ReaderExtension->SpinLock, irql );
  2119. status = KeWaitForSingleObject( &ReaderExtension->ReaderStarted,
  2120. Executive,
  2121. KernelMode,
  2122. FALSE,
  2123. NULL );
  2124. ASSERT( status == STATUS_SUCCESS );
  2125. KeAcquireSpinLock( &ReaderExtension->SpinLock, &irql );
  2126. }
  2127. ASSERT( ReaderExtension->IoCount >= 0 );
  2128. ReaderExtension->IoCount++;
  2129. KeReleaseSpinLock( &ReaderExtension->SpinLock, irql );
  2130. status = SmartcardAcquireRemoveLockWithTag( SmartcardExtension,
  2131. 'tcoI' );
  2132. }
  2133. if (status != STATUS_SUCCESS)
  2134. {
  2135. // the device has been removed. Fail the call
  2136. Irp->IoStatus.Information = 0;
  2137. Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
  2138. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  2139. return STATUS_DEVICE_REMOVED;
  2140. }
  2141. ASSERT(ReaderExtension->ReaderPowerState == PowerReaderWorking);
  2142. status = SmartcardDeviceControl( SmartcardExtension, Irp );
  2143. SmartcardReleaseRemoveLockWithTag( SmartcardExtension,'tcoI' );
  2144. KeAcquireSpinLock( &ReaderExtension->SpinLock, &irql );
  2145. ReaderExtension->IoCount--;
  2146. ASSERT( ReaderExtension->IoCount >= 0 );
  2147. KeReleaseSpinLock( &ReaderExtension->SpinLock, irql );
  2148. return status;
  2149. }
  2150. #else
  2151. NTSTATUS
  2152. RBSCDeviceControl(
  2153. PDEVICE_OBJECT DeviceObject,
  2154. PIRP Irp
  2155. )
  2156. {
  2157. SmartcardDebug(
  2158. DEBUG_TRACE,
  2159. ("RNBO3531!DeviceControl: Enter (%lx)\n",
  2160. IoGetCurrentIrpStackLocation( Irp )->MinorFunction)
  2161. );
  2162. return SmartcardDeviceControl(
  2163. &((PREADER_EXTENSION)DeviceObject->DeviceExtension)->SmartcardExtension,
  2164. Irp
  2165. );
  2166. }
  2167. #endif
  2168. NTSTATUS
  2169. RBSCReaderPower(
  2170. PSMARTCARD_EXTENSION SmartcardExtension
  2171. )
  2172. /*++
  2173. Routine Description:
  2174. The smart card lib requires to have this function. It is called
  2175. for certain power requests to the card.
  2176. Arguments:
  2177. SmartcardExtension - Pointer to smart card data struct.
  2178. Return Value:
  2179. NTSTATUS
  2180. --*/
  2181. {
  2182. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  2183. NTSTATUS status;
  2184. KIRQL oldIrql;
  2185. ULONG step;
  2186. //PAGED_CODE();
  2187. SmartcardDebug(
  2188. DEBUG_TRACE,
  2189. ("RNBO3531!ReaderPower: Enter (%lx)\n",
  2190. SmartcardExtension->MinorIoControlCode)
  2191. );
  2192. #define STEP_POWER_DOWN 0
  2193. #define STEP_COLD_RESET (STEP_POWER_DOWN+2)
  2194. #define STEP_WARM_RESET (STEP_COLD_RESET+10)
  2195. switch( SmartcardExtension->MinorIoControlCode )
  2196. {
  2197. case SCARD_WARM_RESET:
  2198. step = STEP_WARM_RESET;
  2199. break;
  2200. case SCARD_COLD_RESET:
  2201. step = STEP_COLD_RESET;
  2202. break;
  2203. case SCARD_POWER_DOWN:
  2204. step = STEP_POWER_DOWN;
  2205. break;
  2206. default :
  2207. return STATUS_INVALID_DEVICE_REQUEST;
  2208. }
  2209. //
  2210. // Since power down triggers the UpdateSerialStatus function, we have
  2211. // to inform it that we forced the change of the status and not the user
  2212. // (who might have removed and inserted a card)
  2213. //
  2214. ReaderExtension->PowerRequest = TRUE;
  2215. do
  2216. {
  2217. switch( step++ )
  2218. {
  2219. case STEP_COLD_RESET+0:
  2220. case STEP_POWER_DOWN+0:
  2221. status = RBSCPacketExchange( SmartcardExtension,
  2222. CardPowerDown,
  2223. sizeof(CardPowerDown),
  2224. WAIT_TIME_PWR_OFF,
  2225. TRUE );
  2226. break;
  2227. case STEP_POWER_DOWN+1:
  2228. if( SmartcardExtension->ReaderCapabilities.CurrentState >
  2229. SCARD_PRESENT )
  2230. {
  2231. SmartcardExtension->ReaderCapabilities.CurrentState =
  2232. SCARD_PRESENT;
  2233. }
  2234. SmartcardExtension->CardCapabilities.Protocol.Selected =
  2235. SCARD_PROTOCOL_UNDEFINED;
  2236. ReaderExtension->PowerRequest = FALSE;
  2237. SmartcardDebug(
  2238. DEBUG_TRACE,
  2239. ("RNBO3531!ReaderPower: Exit PowerDown OK\n")
  2240. );
  2241. return STATUS_SUCCESS;
  2242. case STEP_COLD_RESET+1:
  2243. case STEP_WARM_RESET+0:
  2244. status = RBSCSerialIo( SmartcardExtension,
  2245. IOCTL_SERIAL_SET_DTR,
  2246. NULL,
  2247. 0,
  2248. 0 );
  2249. //RBSCDelay( 15000 );
  2250. break;
  2251. case STEP_COLD_RESET+2:
  2252. case STEP_WARM_RESET+1:
  2253. status = RBSCSerialIo( SmartcardExtension,
  2254. IOCTL_SERIAL_SET_RTS,
  2255. NULL,
  2256. 0,
  2257. 0 );
  2258. // RBSCDelay( 15000 );
  2259. break;
  2260. case STEP_WARM_RESET+2:
  2261. case STEP_COLD_RESET+3:
  2262. //
  2263. // Set up ATR timeouts (all in msec)
  2264. //
  2265. ReaderExtension->SerialTimeouts.ReadTotalTimeoutMultiplier = 1;
  2266. ReaderExtension->SerialTimeouts.ReadIntervalTimeout = 2*
  2267. ATR_CHAR_TIMEOUT/1000;
  2268. ReaderExtension->SerialTimeouts.ReadTotalTimeoutConstant = 2*
  2269. ATR_BLOCK_TIMEOUT/1000;
  2270. status = RBSCSerialIo(
  2271. SmartcardExtension,
  2272. IOCTL_SERIAL_SET_TIMEOUTS,
  2273. (PUCHAR) &ReaderExtension->SerialTimeouts,
  2274. sizeof(SERIAL_TIMEOUTS),
  2275. 0
  2276. );
  2277. break;
  2278. case STEP_WARM_RESET+3:
  2279. case STEP_COLD_RESET+4:
  2280. if( SmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries > 1 )
  2281. {
  2282. // Setup default baudrate
  2283. SmartcardDebug(
  2284. DEBUG_TRACE,
  2285. ("RNBO3531!ReaderPower: Set DataRate=%ld\n",DATARATE_DEFAULT)
  2286. );
  2287. {
  2288. SERIAL_BAUD_RATE BaudRate;
  2289. BaudRate.BaudRate = DATARATE_DEFAULT;
  2290. status = RBSCSerialIo( SmartcardExtension,
  2291. IOCTL_SERIAL_SET_BAUD_RATE,
  2292. (PUCHAR) &BaudRate,
  2293. sizeof(SERIAL_BAUD_RATE),
  2294. 0 );
  2295. }
  2296. }
  2297. break;
  2298. case STEP_WARM_RESET+4:
  2299. case STEP_COLD_RESET+5:
  2300. RBSCDelay(15000);
  2301. status = RBSCPacketExchange( SmartcardExtension,
  2302. CardPowerUp,
  2303. sizeof(CardPowerUp),
  2304. 0, //WAIT_TIME_PWR_ON,
  2305. FALSE );
  2306. break;
  2307. case STEP_WARM_RESET+5:
  2308. case STEP_COLD_RESET+6:
  2309. //
  2310. // Now read in part or all of the ATR
  2311. //
  2312. status = RBSCSerialIo( SmartcardExtension,
  2313. SMARTCARD_READ,
  2314. NULL,
  2315. 0,
  2316. MAXIMUM_ATR_LENGTH );
  2317. break;
  2318. case STEP_WARM_RESET+6:
  2319. case STEP_COLD_RESET+7:
  2320. {
  2321. ULONG i;
  2322. if( SmartcardExtension->SmartcardReply.Buffer[0] == 0x03 )
  2323. {
  2324. //
  2325. // Inverse convention (Inv(3F) = 03)
  2326. //
  2327. SmartcardExtension->CardCapabilities.ATR.Buffer[0] = 0x3F;
  2328. SmartcardExtension->CardCapabilities.ATR.Length = 1;
  2329. }
  2330. else
  2331. if( SmartcardExtension->SmartcardReply.Buffer[0] == 0x3B )
  2332. {
  2333. //
  2334. // Direct convention
  2335. //
  2336. SmartcardExtension->CardCapabilities.ATR.Buffer[0] = 0x3B;
  2337. SmartcardExtension->CardCapabilities.ATR.Length = 1;
  2338. }
  2339. else
  2340. {
  2341. status = STATUS_UNRECOGNIZED_MEDIA;
  2342. }
  2343. for( i = 1; status == STATUS_SUCCESS; i = 0 )
  2344. {
  2345. while( i <
  2346. SmartcardExtension->SmartcardReply.BufferLength &&
  2347. SmartcardExtension->CardCapabilities.ATR.Length <
  2348. MAXIMUM_ATR_LENGTH )
  2349. {
  2350. SmartcardExtension->CardCapabilities.ATR.Buffer[
  2351. SmartcardExtension->CardCapabilities.ATR.Length++ ] =
  2352. (SmartcardExtension->CardCapabilities.ATR.Buffer[0] == 0x3F) ?
  2353. InverseCharTable[
  2354. SmartcardExtension->SmartcardReply.Buffer[i] ] :
  2355. SmartcardExtension->SmartcardReply.Buffer[i];
  2356. i++;
  2357. }
  2358. //
  2359. // Check if ATR is complete
  2360. //
  2361. status = SmartcardUpdateCardCapabilities(
  2362. SmartcardExtension
  2363. );
  2364. if( status == STATUS_SUCCESS )
  2365. {
  2366. break;
  2367. }
  2368. //
  2369. // Read remaining bytes of ATR
  2370. //
  2371. status = RBSCSerialIo(
  2372. SmartcardExtension,
  2373. SMARTCARD_READ,
  2374. NULL,
  2375. 0,
  2376. MAXIMUM_ATR_LENGTH -
  2377. SmartcardExtension->CardCapabilities.ATR.Length
  2378. );
  2379. }
  2380. break;
  2381. }
  2382. case STEP_WARM_RESET+7:
  2383. case STEP_COLD_RESET+8:
  2384. status = RBSCSetCommParams(
  2385. SmartcardExtension,
  2386. SmartcardExtension->CardCapabilities.PtsData.DataRate
  2387. );
  2388. break;
  2389. case STEP_WARM_RESET+8:
  2390. case STEP_COLD_RESET+9:
  2391. //RBSCDelay( 15000 );
  2392. //
  2393. // Make sure card is still in the reader.
  2394. //
  2395. if( (ReaderExtension->ModemStatus & SERIAL_CTS_STATE) == 0 )
  2396. {
  2397. status = STATUS_NO_MEDIA;
  2398. break;
  2399. }
  2400. KeAcquireSpinLock( &SmartcardExtension->OsData->SpinLock,
  2401. &oldIrql );
  2402. //
  2403. // Copy ATR to user space
  2404. //
  2405. if( SmartcardExtension->IoRequest.ReplyBuffer )
  2406. {
  2407. RtlCopyMemory(
  2408. SmartcardExtension->IoRequest.ReplyBuffer,
  2409. SmartcardExtension->CardCapabilities.ATR.Buffer,
  2410. SmartcardExtension->CardCapabilities.ATR.Length
  2411. );
  2412. //
  2413. // Tell user length of ATR
  2414. //
  2415. *SmartcardExtension->IoRequest.Information =
  2416. SmartcardExtension->CardCapabilities.ATR.Length;
  2417. }
  2418. KeReleaseSpinLock( &SmartcardExtension->OsData->SpinLock,
  2419. oldIrql );
  2420. ReaderExtension->PowerRequest = FALSE;
  2421. SmartcardDebug(
  2422. DEBUG_TRACE,
  2423. ("RNBO3531!ReaderPower: Exit Reset OK\n")
  2424. );
  2425. return STATUS_SUCCESS;
  2426. }
  2427. } while( status == STATUS_SUCCESS );
  2428. //
  2429. // Reset failed, make sure card is powered OFF
  2430. //
  2431. RBSCPacketExchange( SmartcardExtension,
  2432. CardPowerDown,
  2433. sizeof(CardPowerDown),
  2434. WAIT_TIME_PWR_OFF,
  2435. TRUE );
  2436. SmartcardExtension->CardCapabilities.ATR.Length = 0;
  2437. status = (ReaderExtension->ModemStatus & SERIAL_CTS_STATE) ?
  2438. STATUS_UNRECOGNIZED_MEDIA :
  2439. STATUS_NO_MEDIA;
  2440. ReaderExtension->PowerRequest = FALSE;
  2441. SmartcardDebug(
  2442. DEBUG_TRACE,
  2443. ("RNBO3531!ReaderPower: Failed %08x\n",status)
  2444. );
  2445. return status;
  2446. }
  2447. NTSTATUS
  2448. RBSCSetProtocol(
  2449. PSMARTCARD_EXTENSION SmartcardExtension
  2450. )
  2451. /*++
  2452. Routine Description:
  2453. The smart card lib requires to have this function. It is called
  2454. to set a particular protocol.
  2455. Arguments:
  2456. SmartcardExtension - Pointer to smart card data struct.
  2457. Return Value:
  2458. NTSTATUS
  2459. --*/
  2460. {
  2461. UCHAR PtsRequest[8];
  2462. NTSTATUS status;
  2463. PAGED_CODE();
  2464. SmartcardDebug(
  2465. DEBUG_TRACE,
  2466. ("RNBO3531!SetProtocol: Enter\n")
  2467. );
  2468. //
  2469. // Check if the card is already in specific state
  2470. // and if the caller wants to have the already selected protocol.
  2471. // We return success if this is the case.
  2472. //
  2473. if( SmartcardExtension->ReaderCapabilities.CurrentState ==
  2474. SCARD_SPECIFIC && (
  2475. SmartcardExtension->CardCapabilities.Protocol.Selected &
  2476. SmartcardExtension->MinorIoControlCode) )
  2477. {
  2478. status = STATUS_SUCCESS;
  2479. } else
  2480. while(TRUE)
  2481. {
  2482. PUCHAR reply = SmartcardExtension->SmartcardReply.Buffer;
  2483. if( SmartcardExtension->CardCapabilities.Protocol.Supported &
  2484. SmartcardExtension->MinorIoControlCode &
  2485. SCARD_PROTOCOL_T1 )
  2486. {
  2487. PtsRequest[5] = 0x11;
  2488. SmartcardExtension->CardCapabilities.Protocol.Selected =
  2489. SCARD_PROTOCOL_T1;
  2490. } else if(
  2491. SmartcardExtension->CardCapabilities.Protocol.Supported &
  2492. SmartcardExtension->MinorIoControlCode &
  2493. SCARD_PROTOCOL_T0 )
  2494. {
  2495. PtsRequest[5] = 0x10;
  2496. SmartcardExtension->CardCapabilities.Protocol.Selected =
  2497. SCARD_PROTOCOL_T0;
  2498. } else {
  2499. return STATUS_INVALID_DEVICE_REQUEST;
  2500. }
  2501. //
  2502. // pts
  2503. //
  2504. PtsRequest[0] = IFDCMD_HEADER1;
  2505. PtsRequest[1] = IFDCMD_HEADER2;
  2506. PtsRequest[2] = IFDCMD_SEND_0xx;
  2507. PtsRequest[3] = 4; // Length
  2508. PtsRequest[4] = 0xff; // PTS
  2509. PtsRequest[6] = // set pts1 which codes Fl and Dl
  2510. (SmartcardExtension->CardCapabilities.PtsData.Fl << 4) |
  2511. SmartcardExtension->CardCapabilities.PtsData.Dl;
  2512. //
  2513. // pck (check character)
  2514. //
  2515. PtsRequest[7] = PtsRequest[4] ^ PtsRequest[5] ^ PtsRequest[6];
  2516. status = RBSCPacketExchange( SmartcardExtension,
  2517. PtsRequest,
  2518. 4,
  2519. 0,
  2520. FALSE );
  2521. if( status == STATUS_SUCCESS )
  2522. {
  2523. status = RBSCWriteToCard( SmartcardExtension, PtsRequest+4, 4 );
  2524. if( status == STATUS_SUCCESS )
  2525. {
  2526. status = RBSCReadFromCard( SmartcardExtension, 4 );
  2527. }
  2528. }
  2529. if( status == STATUS_SUCCESS &&
  2530. reply[0] == PtsRequest[4] &&
  2531. ((reply[1] ^ PtsRequest[5]) & 0x0f) == 0 )
  2532. {
  2533. //
  2534. // Update the current protocol
  2535. //
  2536. SmartcardExtension->ReaderCapabilities.CurrentState =
  2537. SCARD_SPECIFIC;
  2538. status = RBSCSetCommParams(
  2539. SmartcardExtension,
  2540. SmartcardExtension->CardCapabilities.PtsData.DataRate
  2541. );
  2542. } else {
  2543. if (status == STATUS_IO_TIMEOUT &&
  2544. SmartcardExtension->CardCapabilities.PtsData.Type !=
  2545. PTS_TYPE_DEFAULT)
  2546. {
  2547. SmartcardDebug(
  2548. DEBUG_TRACE,
  2549. ("RNBO3531!SetProtocol: PTS failed. Trying default parameters...\n")
  2550. );
  2551. //
  2552. // The card did either NOT reply or it replied incorrectly
  2553. // so try default values
  2554. //
  2555. SmartcardExtension->CardCapabilities.PtsData.Type =
  2556. PTS_TYPE_DEFAULT;
  2557. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  2558. status = RBSCReaderPower( SmartcardExtension );
  2559. if( status == STATUS_SUCCESS )
  2560. continue;
  2561. }
  2562. status = STATUS_DEVICE_PROTOCOL_ERROR;
  2563. }
  2564. break;
  2565. }
  2566. if( status != STATUS_SUCCESS )
  2567. {
  2568. SmartcardExtension->CardCapabilities.Protocol.Selected =
  2569. SCARD_PROTOCOL_UNDEFINED;
  2570. } else {
  2571. //
  2572. // return the selected protocol to the caller
  2573. //
  2574. *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer =
  2575. SmartcardExtension->CardCapabilities.Protocol.Selected;
  2576. *SmartcardExtension->IoRequest.Information =
  2577. sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
  2578. }
  2579. SmartcardDebug(
  2580. DEBUG_TRACE,
  2581. ("RNBO3531!SetProtocol: Exit\n")
  2582. );
  2583. return status;
  2584. }
  2585. NTSTATUS
  2586. RBSCPacketExchange(
  2587. PSMARTCARD_EXTENSION SmartcardExtension,
  2588. PUCHAR Command,
  2589. ULONG Length,
  2590. ULONG WaitTime,
  2591. BOOLEAN IfdResponse
  2592. )
  2593. /*++
  2594. Routine Description:
  2595. This function is used to transmit a command to the reader (not card)
  2596. and return the response (if asked).
  2597. Arguments:
  2598. SmartcardExtension - Pointer to smart card data struct.
  2599. Command - Points to the IFD command to send
  2600. Length - Length of the command in bytes
  2601. WaitTime - Waiting time expected (in microseconds)
  2602. IfdResponse - When TRUE, IFD response is expected (vs card)
  2603. Return Value:
  2604. NTSTATUS
  2605. --*/
  2606. {
  2607. PUCHAR reply = SmartcardExtension->SmartcardReply.Buffer;
  2608. ULONG SerialRequest = SERIAL_PURGE_RXCLEAR | SERIAL_PURGE_TXCLEAR;
  2609. ULONG ResponseSize;
  2610. NTSTATUS status;
  2611. int TrySend;
  2612. DumpData( "PacketExchange", Command, Length );
  2613. for( TrySend = 0; TrySend < 4; TrySend++ )
  2614. {
  2615. //
  2616. // start with clean buffers
  2617. //
  2618. status = RBSCSerialIo( SmartcardExtension,
  2619. IOCTL_SERIAL_PURGE,
  2620. (PUCHAR) &SerialRequest,
  2621. sizeof(ULONG),
  2622. 0 );
  2623. if( status == STATUS_SUCCESS )
  2624. {
  2625. status = RBSCSerialIo( SmartcardExtension,
  2626. SMARTCARD_WRITE,
  2627. Command,
  2628. Length,
  2629. 0 );
  2630. if( status == STATUS_SUCCESS && WaitTime != 0 )
  2631. RBSCDelay( WaitTime );
  2632. }
  2633. if( status == STATUS_SUCCESS && IfdResponse )
  2634. {
  2635. status = RBSCSerialIo( SmartcardExtension,
  2636. SMARTCARD_READ,
  2637. NULL,
  2638. 0,
  2639. IFDRSP_HEADER_SIZE );
  2640. if( status != STATUS_SUCCESS ||
  2641. SmartcardExtension->SmartcardReply.BufferLength !=
  2642. IFDRSP_HEADER_SIZE )
  2643. {
  2644. continue;
  2645. }
  2646. DumpData( "PacketExchange: Received Header",
  2647. reply,
  2648. IFDRSP_HEADER_SIZE );
  2649. //
  2650. // We should have the marker plus the status/length byte
  2651. //
  2652. if( reply[0] != IFDRSP_MARKER )
  2653. {
  2654. status = STATUS_DEVICE_DATA_ERROR;
  2655. continue;
  2656. }
  2657. ResponseSize = (ULONG)reply[1];
  2658. if( ResponseSize > 0 && ResponseSize < IFDRSP_ACK )
  2659. {
  2660. status = RBSCSerialIo( SmartcardExtension,
  2661. SMARTCARD_READ,
  2662. NULL,
  2663. 0,
  2664. ResponseSize );
  2665. if( status == STATUS_SUCCESS &&
  2666. SmartcardExtension->SmartcardReply.BufferLength !=
  2667. ResponseSize )
  2668. {
  2669. status = STATUS_DEVICE_DATA_ERROR;
  2670. }
  2671. DumpData( "PacketExchange: Received Data",
  2672. SmartcardExtension->SmartcardReply.Buffer,
  2673. SmartcardExtension->SmartcardReply.BufferLength );
  2674. }
  2675. else
  2676. {
  2677. //
  2678. // Map IFD errors
  2679. //
  2680. switch( ResponseSize )
  2681. {
  2682. case IFDRSP_ACK : return STATUS_SUCCESS;
  2683. case IFDRSP_NOCARD : return STATUS_NO_MEDIA;
  2684. case IFDRSP_BADCMD : return STATUS_INVALID_DEVICE_REQUEST;
  2685. case IFDRSP_PARITY :
  2686. default :
  2687. status = STATUS_DEVICE_DATA_ERROR;
  2688. break;
  2689. }
  2690. }
  2691. }
  2692. if( status == STATUS_SUCCESS)
  2693. return STATUS_SUCCESS;
  2694. }
  2695. SmartcardExtension->SmartcardReply.BufferLength = 0;
  2696. return status;
  2697. }
  2698. NTSTATUS
  2699. RBSCT0Transmit(
  2700. PSMARTCARD_EXTENSION SmartcardExtension
  2701. )
  2702. /*++
  2703. Routine Description:
  2704. This function performs the T=0 transmission.
  2705. Arguments:
  2706. SmartcardExtension - Pointer to smart card data struct.
  2707. Return Value:
  2708. NTSTATUS
  2709. --*/
  2710. {
  2711. PREADER_EXTENSION ReaderExtension = SmartcardExtension->ReaderExtension;
  2712. NTSTATUS status;
  2713. PUCHAR RxBuffer = SmartcardExtension->SmartcardReply.Buffer;
  2714. PUCHAR TxBuffer = SmartcardExtension->SmartcardRequest.Buffer;
  2715. ULONG RxLength, TxLength, RequestSize;
  2716. UCHAR SendHeader[4], Ins, ProcByte;
  2717. PAGED_CODE();
  2718. SmartcardDebug(
  2719. DEBUG_TRACE,
  2720. ("RNBO3531!T0Transmit: Enter\n")
  2721. );
  2722. //
  2723. // Tell the lib function how many bytes I need for the prologue
  2724. //
  2725. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  2726. //
  2727. // Let the lib build a T=0 packet
  2728. //
  2729. status = SmartcardT0Request( SmartcardExtension );
  2730. if( status != STATUS_SUCCESS )
  2731. return status;
  2732. TxLength = SmartcardExtension->SmartcardRequest.BufferLength;
  2733. if( TxLength < 5 || TxLength > 0x1ff )
  2734. {
  2735. return STATUS_DEVICE_DATA_ERROR;
  2736. }
  2737. //
  2738. // The number of bytes we expect from the card
  2739. // is Le + 2 status bytes
  2740. //
  2741. RxLength = SmartcardExtension->T0.Le + 2;
  2742. //
  2743. // Write command to the reader
  2744. //
  2745. Ins = TxBuffer[1]; // INS
  2746. RequestSize = 5;
  2747. for( ;; )
  2748. {
  2749. if( TxLength > 0 )
  2750. {
  2751. SendHeader[0] = IFDCMD_HEADER1;
  2752. SendHeader[1] = IFDCMD_HEADER2;
  2753. SendHeader[2] = (RequestSize > 256) ?
  2754. IFDCMD_SEND_1xx : IFDCMD_SEND_0xx;
  2755. SendHeader[3] = (UCHAR)RequestSize; // 0=256
  2756. status = RBSCPacketExchange(
  2757. SmartcardExtension,
  2758. SendHeader,
  2759. 4,
  2760. 0,
  2761. FALSE
  2762. );
  2763. if( status != STATUS_SUCCESS)
  2764. {
  2765. break;
  2766. }
  2767. status = RBSCWriteToCard(
  2768. SmartcardExtension,
  2769. TxBuffer,
  2770. RequestSize
  2771. );
  2772. if( status != STATUS_SUCCESS)
  2773. {
  2774. break;
  2775. }
  2776. TxLength -= RequestSize;
  2777. TxBuffer += RequestSize;
  2778. }
  2779. do
  2780. {
  2781. status = RBSCReadFromCard( SmartcardExtension, 1 ); // Proc. byte
  2782. if( status != STATUS_SUCCESS )
  2783. {
  2784. break;
  2785. }
  2786. ProcByte = SmartcardExtension->SmartcardReply.Buffer[0];
  2787. SmartcardDebug(
  2788. DEBUG_TRACE,
  2789. ("RNBO3531!ProcByte=%02x Ins=%02x\n",ProcByte,Ins)
  2790. );
  2791. } while( ProcByte == 0x60);
  2792. if( status != STATUS_SUCCESS )
  2793. {
  2794. break;
  2795. }
  2796. if( ProcByte == Ins || ProcByte == (UCHAR)(Ins+1) )
  2797. {
  2798. //
  2799. // Send all remaining bytes
  2800. //
  2801. if( TxLength > 0 )
  2802. {
  2803. RequestSize = TxLength;
  2804. continue;
  2805. }
  2806. RequestSize = RxLength;
  2807. }
  2808. else if( ProcByte == (UCHAR)~Ins || ProcByte == (UCHAR)~(Ins+1) )
  2809. {
  2810. //
  2811. // Send 1 byte only
  2812. //
  2813. RequestSize = 1;
  2814. if( TxLength > 0 )
  2815. {
  2816. continue;
  2817. }
  2818. }
  2819. else
  2820. {
  2821. //
  2822. // Card returned status byte
  2823. //
  2824. SmartcardExtension->SmartcardReply.Buffer++;
  2825. TxLength = 0;
  2826. RxLength = 1; // Second byte of status (SW2)
  2827. RequestSize = 1;
  2828. }
  2829. status = RBSCReadFromCard( SmartcardExtension, RequestSize );
  2830. if( status != STATUS_SUCCESS )
  2831. {
  2832. break;
  2833. }
  2834. SmartcardExtension->SmartcardReply.Buffer += RequestSize;
  2835. RxLength -= RequestSize;
  2836. if( RxLength == 0 )
  2837. {
  2838. break;
  2839. }
  2840. }
  2841. //
  2842. // Restore reply buffer pointer
  2843. //
  2844. SmartcardExtension->SmartcardReply.BufferLength =
  2845. (ULONG) (SmartcardExtension->SmartcardReply.Buffer - RxBuffer);
  2846. SmartcardExtension->SmartcardReply.Buffer = RxBuffer;
  2847. if( status == STATUS_SUCCESS )
  2848. {
  2849. status = SmartcardT0Reply( SmartcardExtension );
  2850. }
  2851. SmartcardDebug(
  2852. DEBUG_TRACE,
  2853. ("RNBO3531!T0Transmit: Exit (%lx)\n",status)
  2854. );
  2855. return status;
  2856. }
  2857. NTSTATUS
  2858. RBSCT1Transmit(
  2859. PSMARTCARD_EXTENSION SmartcardExtension
  2860. )
  2861. /*++
  2862. Routine Description:
  2863. This function performs the T=1 transmission.
  2864. Arguments:
  2865. SmartcardExtension - Pointer to smart card data struct.
  2866. Return Value:
  2867. NTSTATUS
  2868. --*/
  2869. {
  2870. NTSTATUS status;
  2871. UCHAR SendHeader[4];
  2872. PAGED_CODE();
  2873. SmartcardDebug(
  2874. DEBUG_TRACE,
  2875. ("RNBO3531!T1Transmit: Enter\n")
  2876. );
  2877. do
  2878. {
  2879. PUCHAR TxBuffer = SmartcardExtension->SmartcardRequest.Buffer;
  2880. PUCHAR reply = SmartcardExtension->SmartcardReply.Buffer;
  2881. ULONG TxLength;
  2882. //
  2883. // Tell the lib function how many bytes I need for the prologue
  2884. //
  2885. SmartcardExtension->SmartcardRequest.BufferLength = 0;
  2886. status = SmartcardT1Request( SmartcardExtension );
  2887. if( status != STATUS_SUCCESS )
  2888. {
  2889. break;
  2890. }
  2891. TxLength = SmartcardExtension->SmartcardRequest.BufferLength;
  2892. //RBSCDelay( SmartcardExtension->CardCapabilities.T1.BGT );
  2893. //
  2894. // Write the command to the reader
  2895. //
  2896. SendHeader[0] = IFDCMD_HEADER1;
  2897. SendHeader[1] = IFDCMD_HEADER2;
  2898. SendHeader[2] = (UCHAR)(TxLength > 256) ?
  2899. IFDCMD_SEND_1xx : IFDCMD_SEND_0xx;
  2900. SendHeader[3] = (UCHAR)TxLength; // 0=256
  2901. status = RBSCPacketExchange( SmartcardExtension,
  2902. SendHeader,
  2903. 4,
  2904. 0,
  2905. FALSE );
  2906. if( status != STATUS_SUCCESS )
  2907. {
  2908. break;
  2909. }
  2910. status = RBSCWriteToCard( SmartcardExtension, TxBuffer, TxLength );
  2911. if( status != STATUS_SUCCESS )
  2912. {
  2913. break;
  2914. }
  2915. if( SmartcardExtension->T1.Wtx > 1 )
  2916. {
  2917. SmartcardDebug(
  2918. DEBUG_PROTOCOL,
  2919. ("BWT=%ld, WTX=%d\n",
  2920. SmartcardExtension->CardCapabilities.T1.BWT,
  2921. SmartcardExtension->T1.Wtx)
  2922. );
  2923. RBSCDelay(
  2924. SmartcardExtension->CardCapabilities.T1.BWT*
  2925. SmartcardExtension->T1.Wtx );
  2926. }
  2927. status = RBSCReadFromCard( SmartcardExtension, 3 );
  2928. if( status == STATUS_IO_TIMEOUT )
  2929. {
  2930. //
  2931. // Since the card did not reply we set the number of
  2932. // bytes received to 0. This will trigger a resend
  2933. // request
  2934. //
  2935. SmartcardDebug(
  2936. DEBUG_PROTOCOL,
  2937. ("RNBO3531!T1Transmit: Timeout\n")
  2938. );
  2939. SmartcardExtension->SmartcardReply.BufferLength = 0;
  2940. } else {
  2941. if( status != STATUS_SUCCESS )
  2942. {
  2943. break;
  2944. }
  2945. //
  2946. // Calculate length of the INF part of the response
  2947. //
  2948. SmartcardExtension->SmartcardReply.BufferLength =
  2949. SmartcardExtension->SmartcardReply.Buffer[2] +
  2950. (SmartcardExtension->CardCapabilities.T1.EDC & 1) + 1;
  2951. SmartcardExtension->SmartcardReply.Buffer += 3;
  2952. status = RBSCReadFromCard(
  2953. SmartcardExtension,
  2954. SmartcardExtension->SmartcardReply.BufferLength );
  2955. SmartcardExtension->SmartcardReply.Buffer -= 3;
  2956. SmartcardExtension->SmartcardReply.BufferLength += 3;
  2957. if( status != STATUS_SUCCESS && status != STATUS_IO_TIMEOUT )
  2958. {
  2959. break;
  2960. }
  2961. }
  2962. status = SmartcardT1Reply( SmartcardExtension );
  2963. } while( status == STATUS_MORE_PROCESSING_REQUIRED );
  2964. SmartcardDebug(
  2965. DEBUG_TRACE,
  2966. ("RNBO3531!T1Transmit: Exit (%lx)\n",status)
  2967. );
  2968. return status;
  2969. }
  2970. NTSTATUS
  2971. RBSCTransmit(
  2972. PSMARTCARD_EXTENSION SmartcardExtension
  2973. )
  2974. /*++
  2975. Routine Description:
  2976. This function is called by the smart card library whenever a transmission
  2977. is required.
  2978. Arguments:
  2979. SmartcardExtension - Pointer to smart card data struct.
  2980. Return Value:
  2981. NTSTATUS
  2982. --*/
  2983. {
  2984. NTSTATUS status;
  2985. PAGED_CODE();
  2986. SmartcardDebug(
  2987. DEBUG_TRACE,
  2988. ("RNBO3531!Transmit: GT=%ld, etu=%ld\n",
  2989. SmartcardExtension->CardCapabilities.GT,
  2990. SmartcardExtension->CardCapabilities.etu)
  2991. );
  2992. switch( SmartcardExtension->CardCapabilities.Protocol.Selected )
  2993. {
  2994. case SCARD_PROTOCOL_T0:
  2995. return RBSCT0Transmit( SmartcardExtension );
  2996. case SCARD_PROTOCOL_T1:
  2997. return RBSCT1Transmit( SmartcardExtension );
  2998. }
  2999. return STATUS_INVALID_DEVICE_REQUEST;
  3000. }
  3001. NTSTATUS
  3002. RBSCCardTracking(
  3003. PSMARTCARD_EXTENSION SmartcardExtension
  3004. )
  3005. /*++
  3006. Routine Description:
  3007. The smart card lib requires to have this function. It is called
  3008. to setup event tracking for card insertion and removal events.
  3009. Arguments:
  3010. SmartcardExtension - pointer to the smart card data struct.
  3011. Return Value:
  3012. NTSTATUS
  3013. --*/
  3014. {
  3015. KIRQL ioIrql, keIrql;
  3016. //
  3017. // Set cancel routine for the notification irp
  3018. //
  3019. KeAcquireSpinLock(
  3020. &SmartcardExtension->OsData->SpinLock,
  3021. &keIrql
  3022. );
  3023. IoAcquireCancelSpinLock( &ioIrql );
  3024. if( SmartcardExtension->OsData->NotificationIrp )
  3025. {
  3026. IoSetCancelRoutine( SmartcardExtension->OsData->NotificationIrp,
  3027. RBSCCancel );
  3028. }
  3029. IoReleaseCancelSpinLock( ioIrql );
  3030. KeReleaseSpinLock( &SmartcardExtension->OsData->SpinLock,
  3031. keIrql );
  3032. return STATUS_PENDING;
  3033. }
  3034. VOID
  3035. RBSCCompleteCardTracking(
  3036. PSMARTCARD_EXTENSION SmartcardExtension
  3037. )
  3038. {
  3039. KIRQL ioIrql, keIrql;
  3040. PIRP notificationIrp;
  3041. IoAcquireCancelSpinLock(&ioIrql);
  3042. KeAcquireSpinLock(
  3043. &SmartcardExtension->OsData->SpinLock,
  3044. &keIrql
  3045. );
  3046. notificationIrp = SmartcardExtension->OsData->NotificationIrp;
  3047. SmartcardExtension->OsData->NotificationIrp = NULL;
  3048. KeReleaseSpinLock(
  3049. &SmartcardExtension->OsData->SpinLock,
  3050. keIrql
  3051. );
  3052. if (notificationIrp)
  3053. {
  3054. IoSetCancelRoutine(
  3055. notificationIrp,
  3056. NULL
  3057. );
  3058. }
  3059. IoReleaseCancelSpinLock(ioIrql);
  3060. if (notificationIrp)
  3061. {
  3062. SmartcardDebug(
  3063. DEBUG_DRIVER,
  3064. ("%s!RBSCCardTracking: Completing NotificationIrp %lxh\n",
  3065. DRIVER_NAME,
  3066. notificationIrp)
  3067. );
  3068. // finish the request
  3069. notificationIrp->IoStatus.Information = 0;
  3070. notificationIrp->IoStatus.Status = notificationIrp->Cancel ?
  3071. STATUS_CANCELLED : STATUS_SUCCESS;
  3072. IoCompleteRequest(
  3073. notificationIrp,
  3074. IO_NO_INCREMENT
  3075. );
  3076. }
  3077. }
  3078. #ifdef NT5
  3079. VOID
  3080. RBSCCloseSerialPort(
  3081. PDEVICE_OBJECT DeviceObject,
  3082. PVOID Context
  3083. )
  3084. /*++
  3085. Routine Description:
  3086. This function closes the connection to the serial driver when the reader
  3087. has been removed (unplugged). This function runs as a system thread at
  3088. IRQL == PASSIVE_LEVEL. It waits for the remove event that is set by
  3089. the IoCompletionRoutine
  3090. --*/
  3091. {
  3092. PREADER_EXTENSION ReaderExtension = DeviceObject->DeviceExtension;
  3093. NTSTATUS status;
  3094. PIRP irp;
  3095. PIO_STACK_LOCATION stack;
  3096. IO_STATUS_BLOCK ioStatusBlock;
  3097. //
  3098. // first mark this device as 'gone'.
  3099. // This will prevent that someone can re-open the device
  3100. //
  3101. status = IoSetDeviceInterfaceState( &ReaderExtension->PnPDeviceName,
  3102. FALSE );
  3103. ASSERT( status == STATUS_SUCCESS );
  3104. irp = IoAllocateIrp( (CCHAR)(DeviceObject->StackSize + 1), FALSE );
  3105. ASSERT( irp != NULL );
  3106. if( irp )
  3107. {
  3108. SmartcardDebug(
  3109. DEBUG_TRACE,
  3110. ("RNBO3531!CloseSerialPort: Sending IRP_MJ_CLOSE\n")
  3111. );
  3112. IoSetNextIrpStackLocation( irp );
  3113. //
  3114. // We send down a close to the serial driver. This close goes
  3115. // through serenum first which will trigger it to start looking
  3116. // for changes on the com-port. Since our device is gone it will
  3117. // call the device removal event of our PnP dispatch.
  3118. //
  3119. irp->UserIosb = &ioStatusBlock;
  3120. stack = IoGetCurrentIrpStackLocation( irp );
  3121. stack->MajorFunction = IRP_MJ_CLOSE;
  3122. status = RBSCCallSerialDriver(
  3123. ReaderExtension->AttachedSerialPort,
  3124. irp );
  3125. ASSERT( status == STATUS_SUCCESS );
  3126. IoFreeIrp( irp );
  3127. }
  3128. SmartcardDebug(
  3129. DEBUG_INFO,
  3130. ("RNBO3531!CloseSerialPort: Serial Close Done.\n")
  3131. );
  3132. // inform the remove function that call is complete
  3133. KeSetEvent( &ReaderExtension->SerialCloseDone, 0, FALSE );
  3134. }
  3135. NTSTATUS
  3136. RBSCDevicePowerCompletion (
  3137. IN PDEVICE_OBJECT DeviceObject,
  3138. IN PIRP Irp,
  3139. IN PSMARTCARD_EXTENSION SmartcardExtension
  3140. )
  3141. /*++
  3142. Routine Description:
  3143. This routine is called after the underlying stack powered
  3144. UP the serial port, so it can be used again.
  3145. --*/
  3146. {
  3147. PREADER_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  3148. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  3149. //
  3150. // We issue a power request in order to figure out
  3151. // what the actual card status is
  3152. //
  3153. SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
  3154. RBSCReaderPower( SmartcardExtension );
  3155. //
  3156. // If a card was present before power down or now there is
  3157. // a card in the reader, we complete any pending card monitor
  3158. // request, since we do not really know what card is now in the
  3159. // reader.
  3160. //
  3161. if( SmartcardExtension->ReaderExtension->CardPresent ||
  3162. SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT )
  3163. {
  3164. RBSCCompleteCardTracking( SmartcardExtension );
  3165. }
  3166. // save the current power state of the reader
  3167. SmartcardExtension->ReaderExtension->ReaderPowerState =
  3168. PowerReaderWorking;
  3169. SmartcardReleaseRemoveLockWithTag( SmartcardExtension, 'rwoP' );
  3170. // inform the power manager of our state.
  3171. PoSetPowerState( DeviceObject,
  3172. DevicePowerState,
  3173. irpStack->Parameters.Power.State );
  3174. PoStartNextPowerIrp( Irp );
  3175. // signal that we can process ioctls again
  3176. KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
  3177. return STATUS_SUCCESS;
  3178. }
  3179. VOID
  3180. RBSCSystemPowerCompletion(
  3181. IN PDEVICE_OBJECT DeviceObject,
  3182. IN UCHAR MinorFunction,
  3183. IN POWER_STATE PowerState,
  3184. IN PIRP Irp,
  3185. IN PIO_STATUS_BLOCK IoStatus
  3186. )
  3187. /*++
  3188. Routine Description:
  3189. This function is called when the underlying stacks
  3190. completed the power transition.
  3191. --*/
  3192. {
  3193. PREADER_EXTENSION ReaderExtension = DeviceObject->DeviceExtension;
  3194. UNREFERENCED_PARAMETER (MinorFunction);
  3195. Irp->IoStatus.Information = 0;
  3196. Irp->IoStatus.Status = IoStatus->Status;
  3197. SmartcardReleaseRemoveLockWithTag( &ReaderExtension->SmartcardExtension,
  3198. 'rwoP' );
  3199. if (PowerState.SystemState == PowerSystemWorking)
  3200. {
  3201. PoSetPowerState( DeviceObject,
  3202. SystemPowerState,
  3203. PowerState );
  3204. }
  3205. PoStartNextPowerIrp( Irp );
  3206. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  3207. }
  3208. typedef enum _ACTION {
  3209. Undefined = 0,
  3210. SkipRequest,
  3211. WaitForCompletion,
  3212. CompleteRequest,
  3213. MarkPending
  3214. } ACTION;
  3215. NTSTATUS
  3216. RBSCPower(
  3217. IN PDEVICE_OBJECT DeviceObject,
  3218. IN PIRP Irp
  3219. )
  3220. /*++
  3221. Routine Description:
  3222. The power dispatch routine.
  3223. All we care about is the transition from a low D state to D0.
  3224. Arguments:
  3225. DeviceObject - Pointer to device object
  3226. Irp - pointer to an I/O Request Packet.
  3227. Return Value:
  3228. NT status code
  3229. --*/
  3230. {
  3231. NTSTATUS status;
  3232. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  3233. PREADER_EXTENSION ReaderExtension = DeviceObject->DeviceExtension;
  3234. PSMARTCARD_EXTENSION SmartcardExtension =
  3235. &ReaderExtension->SmartcardExtension;
  3236. PDEVICE_OBJECT AttachedSerialPort;
  3237. POWER_STATE powerState;
  3238. ACTION action;
  3239. SmartcardDebug(
  3240. DEBUG_DRIVER,
  3241. ("RNBO3531!3Power: Enter\n")
  3242. );
  3243. status = SmartcardAcquireRemoveLockWithTag( SmartcardExtension, 'rwoP' );
  3244. ASSERT( status == STATUS_SUCCESS );
  3245. if( !NT_SUCCESS( status ) )
  3246. {
  3247. PoStartNextPowerIrp( Irp );
  3248. Irp->IoStatus.Status = status;
  3249. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  3250. return status;
  3251. }
  3252. AttachedSerialPort = ReaderExtension->AttachedSerialPort;
  3253. if (irpStack->Parameters.Power.Type == DevicePowerState &&
  3254. irpStack->MinorFunction == IRP_MN_SET_POWER )
  3255. {
  3256. switch( irpStack->Parameters.Power.State.DeviceState )
  3257. {
  3258. case PowerDeviceD0:
  3259. // Turn on the reader
  3260. SmartcardDebug(
  3261. DEBUG_DRIVER,
  3262. ("RNBO3531!Power: PowerDevice D0\n")
  3263. );
  3264. //
  3265. // First, we send down the request to the bus, in order
  3266. // to power on the port. When the request completes,
  3267. // we turn on the reader
  3268. //
  3269. IoCopyCurrentIrpStackLocationToNext(Irp);
  3270. IoSetCompletionRoutine (
  3271. Irp,
  3272. RBSCDevicePowerCompletion,
  3273. SmartcardExtension,
  3274. TRUE,
  3275. TRUE,
  3276. TRUE
  3277. );
  3278. action = WaitForCompletion;
  3279. break;
  3280. case PowerDeviceD3:
  3281. // Turn off the reader
  3282. SmartcardDebug(
  3283. DEBUG_DRIVER,
  3284. ("RNBO3531!Power: PowerDevice D3\n")
  3285. );
  3286. PoSetPowerState (
  3287. DeviceObject,
  3288. DevicePowerState,
  3289. irpStack->Parameters.Power.State
  3290. );
  3291. // save the current card state
  3292. ReaderExtension->CardPresent =
  3293. SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT;
  3294. if( ReaderExtension->CardPresent )
  3295. {
  3296. SmartcardExtension->MinorIoControlCode = SCARD_POWER_DOWN;
  3297. status = RBSCReaderPower( SmartcardExtension );
  3298. ASSERT(status == STATUS_SUCCESS);
  3299. }
  3300. //
  3301. // If there is a pending card tracking request, setting
  3302. // this flag will prevent completion of the request
  3303. // when the system will be waked up again.
  3304. //
  3305. ReaderExtension->PowerRequest = TRUE;
  3306. // save the current power state of the reader
  3307. ReaderExtension->ReaderPowerState = PowerReaderOff;
  3308. action = SkipRequest;
  3309. break;
  3310. default:
  3311. ASSERT(FALSE);
  3312. action = SkipRequest;
  3313. break;
  3314. }
  3315. }
  3316. if (irpStack->Parameters.Power.Type == SystemPowerState) {
  3317. //
  3318. // The system wants to change the power state.
  3319. // We need to translate the system power state to
  3320. // a corresponding device power state.
  3321. //
  3322. POWER_STATE_TYPE powerType = DevicePowerState;
  3323. ASSERT(ReaderExtension->ReaderPowerState != PowerReaderUnspecified);
  3324. switch(irpStack->MinorFunction)
  3325. {
  3326. KIRQL irql;
  3327. case IRP_MN_QUERY_POWER:
  3328. SmartcardDebug(
  3329. DEBUG_DRIVER,
  3330. ("RNBO3531!Power: Query Power\n")
  3331. );
  3332. //
  3333. // By default we succeed and pass down
  3334. //
  3335. action = SkipRequest;
  3336. Irp->IoStatus.Status = STATUS_SUCCESS;
  3337. switch (irpStack->Parameters.Power.State.SystemState)
  3338. {
  3339. case PowerSystemMaximum:
  3340. case PowerSystemWorking:
  3341. case PowerSystemSleeping1:
  3342. case PowerSystemSleeping2:
  3343. break;
  3344. case PowerSystemSleeping3:
  3345. case PowerSystemHibernate:
  3346. case PowerSystemShutdown:
  3347. KeAcquireSpinLock(&ReaderExtension->SpinLock, &irql);
  3348. if (ReaderExtension->IoCount == 0)
  3349. {
  3350. // Block any further ioctls
  3351. KeClearEvent(&ReaderExtension->ReaderStarted);
  3352. } else {
  3353. // can't go to sleep mode since the reader is busy.
  3354. status = STATUS_DEVICE_BUSY;
  3355. action = CompleteRequest;
  3356. }
  3357. KeReleaseSpinLock(&ReaderExtension->SpinLock, irql);
  3358. break;
  3359. }
  3360. break;
  3361. case IRP_MN_SET_POWER:
  3362. SmartcardDebug(
  3363. DEBUG_DRIVER,
  3364. ("RNBO3531!Power: PowerSystem S%d\n",
  3365. irpStack->Parameters.Power.State.SystemState - 1)
  3366. );
  3367. switch (irpStack->Parameters.Power.State.SystemState)
  3368. {
  3369. case PowerSystemMaximum:
  3370. case PowerSystemWorking:
  3371. case PowerSystemSleeping1:
  3372. case PowerSystemSleeping2:
  3373. if (SmartcardExtension->ReaderExtension->ReaderPowerState ==
  3374. PowerReaderWorking) {
  3375. // We're already in the right state
  3376. action = CompleteRequest;
  3377. break;
  3378. }
  3379. powerState.DeviceState = PowerDeviceD0;
  3380. // wake up the underlying stack...
  3381. action = MarkPending;
  3382. break;
  3383. case PowerSystemSleeping3:
  3384. case PowerSystemHibernate:
  3385. case PowerSystemShutdown:
  3386. if (SmartcardExtension->ReaderExtension->ReaderPowerState ==
  3387. PowerReaderOff) {
  3388. // We're already in the right state
  3389. action = CompleteRequest;
  3390. break;
  3391. }
  3392. powerState.DeviceState = PowerDeviceD3;
  3393. // first, inform the power manager of our new state.
  3394. PoSetPowerState (
  3395. DeviceObject,
  3396. SystemPowerState,
  3397. powerState
  3398. );
  3399. action = MarkPending;
  3400. break;
  3401. default:
  3402. ASSERT(FALSE);
  3403. action = CompleteRequest;
  3404. break;
  3405. }
  3406. }
  3407. }
  3408. switch( action )
  3409. {
  3410. case CompleteRequest:
  3411. Irp->IoStatus.Status = status;
  3412. Irp->IoStatus.Information = 0;
  3413. SmartcardReleaseRemoveLockWithTag( SmartcardExtension, 'rwoP' );
  3414. PoStartNextPowerIrp( Irp );
  3415. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  3416. break;
  3417. case MarkPending:
  3418. Irp->IoStatus.Status = STATUS_PENDING;
  3419. IoMarkIrpPending( Irp );
  3420. status = PoRequestPowerIrp (
  3421. DeviceObject,
  3422. IRP_MN_SET_POWER,
  3423. powerState,
  3424. RBSCSystemPowerCompletion,
  3425. Irp,
  3426. NULL
  3427. );
  3428. ASSERT(status == STATUS_PENDING);
  3429. break;
  3430. case SkipRequest:
  3431. SmartcardReleaseRemoveLockWithTag( SmartcardExtension, 'rwoP' );
  3432. PoStartNextPowerIrp( Irp );
  3433. IoSkipCurrentIrpStackLocation( Irp );
  3434. status = PoCallDriver( AttachedSerialPort, Irp );
  3435. break;
  3436. case WaitForCompletion:
  3437. status = PoCallDriver( AttachedSerialPort, Irp );
  3438. break;
  3439. default:
  3440. ASSERT(FALSE);
  3441. break;
  3442. }
  3443. SmartcardDebug(
  3444. DEBUG_DRIVER,
  3445. ("RNBO3531!Power: Exit %lx\n",status)
  3446. );
  3447. return status;
  3448. }
  3449. #endif