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

338 lines
9.6 KiB

  1. #include <stdarg.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <ntddk.h>
  5. #include <usbdrivr.h>
  6. #include "usbutil.h"
  7. #include "usbsc.h"
  8. #include "smclib.h"
  9. #include "usbscnt.h"
  10. #include "usbsccb.h"
  11. #include "usbscpnp.h"
  12. #include "usbscpwr.h"
  13. // declare pageable/initialization code
  14. #pragma alloc_text( INIT, DriverEntry )
  15. #pragma alloc_text( PAGEABLE, UsbScAddDevice )
  16. #pragma alloc_text( PAGEABLE, UsbScCreateClose )
  17. #pragma alloc_text( PAGEABLE, UsbScUnloadDriver )
  18. NTSTATUS
  19. DriverEntry(
  20. IN PDRIVER_OBJECT DriverObject,
  21. IN PUNICODE_STRING RegistryPath
  22. )
  23. /*++
  24. Routine Description:
  25. Drivers DriverEntry function
  26. Arguments:
  27. Return Value:
  28. --*/
  29. {
  30. NTSTATUS status = STATUS_SUCCESS;
  31. #ifdef BETA_SPEW
  32. #if DEBUG
  33. SmartcardSetDebugLevel(DEBUG_PROTOCOL | DEBUG_ERROR);
  34. #endif
  35. #endif
  36. __try
  37. {
  38. SmartcardDebug( DEBUG_TRACE, ("%s!DriverEntry Enter\n",DRIVER_NAME ));
  39. // Initialize the Driver Object with driver's entry points
  40. DriverObject->DriverUnload = ScUtil_UnloadDriver;
  41. DriverObject->MajorFunction[IRP_MJ_CREATE] = ScUtil_CreateClose;
  42. DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScUtil_CreateClose;
  43. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = ScUtil_Cleanup;
  44. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ScUtil_DeviceIOControl;
  45. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = ScUtil_SystemControl;
  46. DriverObject->MajorFunction[IRP_MJ_PNP] = ScUtil_PnP;
  47. DriverObject->MajorFunction[IRP_MJ_POWER] = ScUtil_Power;
  48. DriverObject->DriverExtension->AddDevice = UsbScAddDevice;
  49. }
  50. __finally
  51. {
  52. SmartcardDebug( DEBUG_TRACE, ("%s!DriverEntry Exit : 0x%x\n",DRIVER_NAME, status ));
  53. }
  54. return status;
  55. }
  56. NTSTATUS
  57. UsbScAddDevice(
  58. IN PDRIVER_OBJECT DriverObject,
  59. IN PDEVICE_OBJECT Pdo
  60. )
  61. /*++
  62. Routine Description:
  63. AddDevice routine. Creates the FDO and does initialization work.
  64. Arguments:
  65. Return Value:
  66. --*/
  67. {
  68. NTSTATUS status;
  69. PDEVICE_EXTENSION pDevExt;
  70. PSMARTCARD_EXTENSION pSmartcardExtension;
  71. PREADER_EXTENSION pReaderExtension;
  72. RTL_QUERY_REGISTRY_TABLE parameters[3];
  73. PDEVICE_OBJECT pDevObj = NULL;
  74. PURB urb;
  75. __try
  76. {
  77. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScAddDevice Enter\n",DRIVER_NAME ));
  78. // create the device object
  79. status = IoCreateDevice(DriverObject,
  80. sizeof( DEVICE_EXTENSION ),
  81. NULL,
  82. FILE_DEVICE_SMARTCARD,
  83. 0,
  84. TRUE,
  85. &pDevObj);
  86. if (!NT_SUCCESS(status)) {
  87. __leave;
  88. }
  89. // initialize device extension
  90. pDevExt = pDevObj->DeviceExtension;
  91. pSmartcardExtension = &pDevExt->SmartcardExtension;
  92. pDevObj->Flags |= DO_POWER_PAGABLE;
  93. IoInitializeRemoveLock(&pDevExt->RemoveLock,
  94. SMARTCARD_POOL_TAG,
  95. 0,
  96. 10);
  97. pDevExt->DeviceDescriptor = NULL;
  98. pDevExt->Interface = NULL;
  99. // allocate & initialize reader extension
  100. pSmartcardExtension->ReaderExtension = ExAllocatePool(NonPagedPool,
  101. sizeof( READER_EXTENSION ));
  102. if ( pSmartcardExtension->ReaderExtension == NULL ) {
  103. status = STATUS_INSUFFICIENT_RESOURCES;
  104. __leave;
  105. }
  106. pReaderExtension = pSmartcardExtension->ReaderExtension;
  107. ASSERT( pReaderExtension != NULL );
  108. RtlZeroMemory(pReaderExtension, sizeof( READER_EXTENSION ));
  109. pReaderExtension->DeviceObject = pDevObj;
  110. // initialize smartcard extension - version & callbacks
  111. // Write the version of the lib we use to the smartcard extension
  112. pSmartcardExtension->Version = SMCLIB_VERSION;
  113. pSmartcardExtension->SmartcardRequest.BufferSize =
  114. pSmartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
  115. //
  116. // Now let the lib allocate the buffer for data transmission
  117. // We can either tell the lib how big the buffer should be
  118. // by assigning a value to BufferSize or let the lib
  119. // allocate the default size
  120. //
  121. status = SmartcardInitialize(pSmartcardExtension);
  122. if (!NT_SUCCESS(status)) {
  123. __leave;
  124. }
  125. pSmartcardExtension->ReaderFunction[RDF_TRANSMIT] = UsbScTransmit;
  126. pSmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = UsbScSetProtocol;
  127. pSmartcardExtension->ReaderFunction[RDF_CARD_POWER] = UsbScCardPower;
  128. pSmartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = UsbScCardTracking;
  129. pSmartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = UsbScVendorIoctl;
  130. pSmartcardExtension->ReaderFunction[RDF_READER_SWALLOW] = NULL; //UsbScCardSwallow;
  131. pSmartcardExtension->ReaderFunction[RDF_CARD_EJECT] = NULL; //UsbScCardEject;
  132. // Save deviceObject
  133. pSmartcardExtension->OsData->DeviceObject = pDevObj;
  134. pDevExt = pDevObj->DeviceExtension;
  135. // attach the device object to the physical device object
  136. pDevExt->LowerDeviceObject = IoAttachDeviceToDeviceStack(pDevObj,
  137. Pdo);
  138. ASSERT( pDevExt->LowerDeviceObject != NULL );
  139. if ( pDevExt->LowerDeviceObject == NULL ) {
  140. status = STATUS_UNSUCCESSFUL;
  141. __leave;
  142. }
  143. pDevExt->PhysicalDeviceObject = Pdo;
  144. pDevObj->Flags |= DO_BUFFERED_IO;
  145. pDevObj->Flags |= DO_POWER_PAGABLE;
  146. pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
  147. ScUtil_Initialize(&pDevExt->ScUtilHandle,
  148. Pdo,
  149. pDevExt->LowerDeviceObject,
  150. pSmartcardExtension,
  151. &pDevExt->RemoveLock,
  152. UsbScStartDevice,
  153. UsbScStopDevice,
  154. UsbScRemoveDevice,
  155. NULL,
  156. UsbScSetDevicePowerState);
  157. }
  158. __finally
  159. {
  160. SmartcardDebug(DEBUG_TRACE, ( "%s!DrvAddDevice: Exit (%lx)\n", DRIVER_NAME, status ));
  161. }
  162. return status;
  163. }
  164. NTSTATUS
  165. UsbScSetDevicePowerState(
  166. IN PDEVICE_OBJECT DeviceObject,
  167. IN DEVICE_POWER_STATE DeviceState,
  168. OUT PBOOLEAN PostWaitWake
  169. )
  170. /*++
  171. Routine Description:
  172. Handles whatever changes need to be made when the device is changing
  173. power states.
  174. Arguments:
  175. DeviceObject
  176. DeviceState - the device power state that the reader is entering
  177. PostWaitWakeIrp - used for future compatability with WDM Wrapper
  178. Return Value:
  179. --*/
  180. {
  181. NTSTATUS status = STATUS_SUCCESS;
  182. PDEVICE_EXTENSION pDevExt;
  183. PSMARTCARD_EXTENSION smartcardExtension;
  184. KIRQL irql;
  185. PIO_STACK_LOCATION irpStack;
  186. __try
  187. {
  188. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSetDevicePowerState Enter\n",DRIVER_NAME ));
  189. pDevExt = DeviceObject->DeviceExtension;
  190. smartcardExtension = &pDevExt->SmartcardExtension;
  191. if (DeviceState < pDevExt->PowerState) {
  192. // We are coming up!
  193. //
  194. // According to the spec, we need to assume that all cards were removed.
  195. // We will get insertion notification if a card is present.
  196. // So if there is a removal irp pending, we should complete that.
  197. //
  198. KeAcquireSpinLock(&smartcardExtension->OsData->SpinLock,
  199. &irql);
  200. if (smartcardExtension->OsData->NotificationIrp) {
  201. irpStack = IoGetCurrentIrpStackLocation(smartcardExtension->OsData->NotificationIrp);
  202. if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SMARTCARD_IS_ABSENT) {
  203. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  204. irql);
  205. UsbScCompleteCardTracking(smartcardExtension);
  206. } else {
  207. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  208. irql);
  209. }
  210. } else {
  211. KeReleaseSpinLock(&smartcardExtension->OsData->SpinLock,
  212. irql);
  213. }
  214. //
  215. // Continue polling the interrupt pipe for insertion notifications
  216. //
  217. USBStartInterruptTransfers(pDevExt->WrapperHandle);
  218. pDevExt->PowerState = DeviceState;
  219. } else if (DeviceState > pDevExt->PowerState) {
  220. //
  221. // We are going down!
  222. //
  223. // Stop polling for insertion notifications
  224. USBStopInterruptTransfers(pDevExt->WrapperHandle);
  225. pDevExt->PowerState = DeviceState;
  226. }
  227. status = STATUS_SUCCESS;
  228. }
  229. __finally
  230. {
  231. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSetDevicePowerState Exit : 0x%x\n",DRIVER_NAME, status ));
  232. }
  233. return status;
  234. }