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.

417 lines
12 KiB

  1. #include "usbsc.h"
  2. #include "usbscpnp.h"
  3. #include "usbutil.h"
  4. #include "usbcom.h"
  5. #include "usbsccb.h"
  6. #include "usbscnt.h"
  7. NTSTATUS
  8. UsbScStartDevice(
  9. PDEVICE_OBJECT DeviceObject,
  10. PIRP Irp
  11. )
  12. /*++
  13. Routine Description:
  14. Handles the IRP_MN_START_DEVICE
  15. Gets the usb descriptors from the reader and configures it.
  16. Also starts "polling" the interrupt pipe
  17. Arguments:
  18. Return Value:
  19. --*/
  20. {
  21. NTSTATUS status = STATUS_SUCCESS;
  22. PDEVICE_EXTENSION pDevExt;
  23. PSMARTCARD_EXTENSION smartcardExtension;
  24. PREADER_EXTENSION readerExtension;
  25. ULONG deviceInstance;
  26. UCHAR string[MAXIMUM_ATTR_STRING_LENGTH];
  27. HANDLE regKey;
  28. PKEY_VALUE_PARTIAL_INFORMATION pInfo;
  29. __try
  30. {
  31. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScStartDevice Enter\n",DRIVER_NAME ));
  32. pDevExt = DeviceObject->DeviceExtension;
  33. smartcardExtension = &pDevExt->SmartcardExtension;
  34. readerExtension = smartcardExtension->ReaderExtension;
  35. status = UsbConfigureDevice(DeviceObject);
  36. if (!NT_SUCCESS(status)) {
  37. __leave;
  38. }
  39. //
  40. // Set the vendor information
  41. //
  42. status = GetStringDescriptor(DeviceObject,
  43. pDevExt->DeviceDescriptor->iManufacturer,
  44. smartcardExtension->VendorAttr.VendorName.Buffer,
  45. &smartcardExtension->VendorAttr.VendorName.Length);
  46. status = GetStringDescriptor(DeviceObject,
  47. pDevExt->DeviceDescriptor->iProduct,
  48. smartcardExtension->VendorAttr.IfdType.Buffer,
  49. &smartcardExtension->VendorAttr.IfdType.Length);
  50. status = GetStringDescriptor(DeviceObject,
  51. pDevExt->DeviceDescriptor->iSerialNumber,
  52. smartcardExtension->VendorAttr.IfdSerialNo.Buffer,
  53. &smartcardExtension->VendorAttr.IfdSerialNo.Length);
  54. smartcardExtension->VendorAttr.UnitNo = MAXULONG;
  55. for (deviceInstance = 0; deviceInstance < MAXULONG; deviceInstance++) {
  56. PDEVICE_OBJECT devObj;
  57. for (devObj = DeviceObject; devObj != NULL; devObj = devObj->NextDevice) {
  58. PDEVICE_EXTENSION devExt = devObj->DeviceExtension;
  59. PSMARTCARD_EXTENSION smcExt = &devExt->SmartcardExtension;
  60. if (deviceInstance == smcExt->VendorAttr.UnitNo) {
  61. break;
  62. }
  63. }
  64. if (devObj == NULL) {
  65. smartcardExtension->VendorAttr.UnitNo = deviceInstance;
  66. break;
  67. }
  68. }
  69. //
  70. // Initialize Reader Capabilities
  71. //
  72. smartcardExtension->ReaderCapabilities.SupportedProtocols
  73. = readerExtension->ClassDescriptor.dwProtocols;
  74. smartcardExtension->ReaderCapabilities.ReaderType = SCARD_READER_TYPE_USB;
  75. smartcardExtension->ReaderCapabilities.MechProperties = 0; // Not currently supporting any Mechanical properties
  76. smartcardExtension->ReaderCapabilities.Channel = smartcardExtension->VendorAttr.UnitNo;
  77. // Assume card is absent.
  78. smartcardExtension->ReaderCapabilities.CurrentState = (ULONG) SCARD_ABSENT;
  79. smartcardExtension->ReaderCapabilities.CLKFrequency.Default
  80. = readerExtension->ClassDescriptor.dwDefaultClock;
  81. smartcardExtension->ReaderCapabilities.CLKFrequency.Max
  82. = readerExtension->ClassDescriptor.dwMaximumClock;
  83. smartcardExtension->ReaderCapabilities.DataRate.Default
  84. = readerExtension->ClassDescriptor.dwDataRate;
  85. smartcardExtension->ReaderCapabilities.DataRate.Max
  86. = readerExtension->ClassDescriptor.dwMaxDataRate;
  87. smartcardExtension->ReaderCapabilities.MaxIFSD
  88. = readerExtension->ClassDescriptor.dwMaxIFSD;
  89. // See if the escape command should be allowed
  90. status = IoOpenDeviceRegistryKey(pDevExt->PhysicalDeviceObject,
  91. PLUGPLAY_REGKEY_DEVICE,
  92. GENERIC_READ,
  93. &regKey);
  94. if (!NT_SUCCESS(status)) {
  95. readerExtension->EscapeCommandEnabled = FALSE;
  96. } else {
  97. UNICODE_STRING strEnable;
  98. ULONG tmp = 0;
  99. ULONG size;
  100. ULONG length;
  101. length = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG);
  102. pInfo = ExAllocatePool(PagedPool, length);
  103. if (pInfo) {
  104. RtlInitUnicodeString (&strEnable, ESCAPE_COMMAND_ENABLE);
  105. status = ZwQueryValueKey(regKey,
  106. &strEnable,
  107. KeyValuePartialInformation,
  108. pInfo,
  109. length,
  110. &size);
  111. }
  112. ZwClose(regKey);
  113. if (!NT_SUCCESS(status)) {
  114. readerExtension->EscapeCommandEnabled = FALSE;
  115. } else {
  116. readerExtension->EscapeCommandEnabled = *((PULONG)pInfo->Data) ? TRUE : FALSE;
  117. }
  118. ExFreePool(pInfo);
  119. }
  120. if (readerExtension->EscapeCommandEnabled) {
  121. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Escape Command Enabled\n",DRIVER_NAME ));
  122. } else {
  123. SmartcardDebug( DEBUG_PROTOCOL, ("%s : Escape Command Disabled\n",DRIVER_NAME ));
  124. }
  125. //
  126. // Get clock frequencies and data rates
  127. //
  128. if (!(readerExtension->ClassDescriptor.dwFeatures & AUTO_CLOCK_FREQ)
  129. && readerExtension->ClassDescriptor.bNumClockSupported) {
  130. // Doesn't support auto clock frequency selection
  131. ULONG bufferLength;
  132. bufferLength = readerExtension->ClassDescriptor.bNumClockSupported * sizeof(DWORD);
  133. smartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.List
  134. = ExAllocatePool(NonPagedPool,
  135. bufferLength);
  136. if (!smartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.List) {
  137. status = STATUS_INSUFFICIENT_RESOURCES;
  138. __leave;
  139. }
  140. ASSERT(pDevExt->LowerDeviceObject);
  141. status = USBClassRequest(pDevExt->LowerDeviceObject,
  142. Interface,
  143. GET_CLOCK_FREQUENCIES,
  144. 0,
  145. pDevExt->Interface->InterfaceNumber,
  146. smartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.List,
  147. &bufferLength,
  148. TRUE,
  149. 0,
  150. &pDevExt->RemoveLock);
  151. if (!NT_SUCCESS(status)) {
  152. __leave;
  153. }
  154. smartcardExtension->ReaderCapabilities.CLKFrequenciesSupported.Entries
  155. = readerExtension->ClassDescriptor.bNumClockSupported;
  156. }
  157. if (!(readerExtension->ClassDescriptor.dwFeatures & AUTO_BAUD_RATE)
  158. && readerExtension->ClassDescriptor.bNumDataRatesSupported) {
  159. // Doesn't support auto data rate selection
  160. ULONG bufferLength;
  161. bufferLength = readerExtension->ClassDescriptor.bNumDataRatesSupported * sizeof(DWORD);
  162. smartcardExtension->ReaderCapabilities.DataRatesSupported.List
  163. = ExAllocatePool(NonPagedPool,
  164. bufferLength);
  165. if (!smartcardExtension->ReaderCapabilities.DataRatesSupported.List) {
  166. status = STATUS_INSUFFICIENT_RESOURCES;
  167. __leave;
  168. }
  169. ASSERT(pDevExt->LowerDeviceObject);
  170. status = USBClassRequest(pDevExt->LowerDeviceObject,
  171. Interface,
  172. GET_DATA_RATES,
  173. 0,
  174. pDevExt->Interface->InterfaceNumber,
  175. smartcardExtension->ReaderCapabilities.DataRatesSupported.List,
  176. &bufferLength,
  177. TRUE,
  178. 0,
  179. &pDevExt->RemoveLock);
  180. if (!NT_SUCCESS(status)) {
  181. __leave;
  182. }
  183. smartcardExtension->ReaderCapabilities.DataRatesSupported.Entries
  184. = readerExtension->ClassDescriptor.bNumDataRatesSupported;
  185. }
  186. ASSERT(pDevExt->LowerDeviceObject);
  187. pDevExt->WrapperHandle = USBInitializeInterruptTransfers(DeviceObject,
  188. pDevExt->LowerDeviceObject,
  189. sizeof(USBSC_HWERROR_HEADER),
  190. &pDevExt->Interface->Pipes[readerExtension->InterruptIndex],
  191. smartcardExtension,
  192. UsbScTrackingISR,
  193. USBWRAP_NOTIFICATION_READ_COMPLETE,
  194. &pDevExt->RemoveLock);
  195. status = USBStartInterruptTransfers(pDevExt->WrapperHandle);
  196. if (!NT_SUCCESS(status)) {
  197. __leave;
  198. }
  199. }
  200. __finally
  201. {
  202. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScStartDevice Exit : 0x%x\n",DRIVER_NAME, status ));
  203. }
  204. return status;
  205. }
  206. NTSTATUS
  207. UsbScStopDevice(
  208. PDEVICE_OBJECT DeviceObject,
  209. PIRP Irp
  210. )
  211. /*++
  212. Routine Description:
  213. Handles IRP_MN_STOP_DEVICE
  214. Stops "polling" the interrupt pipe and frees resources allocated in StartDevice
  215. Arguments:
  216. Return Value:
  217. --*/
  218. {
  219. NTSTATUS status = STATUS_SUCCESS;
  220. PDEVICE_EXTENSION pDevExt;
  221. __try
  222. {
  223. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScStopDevice Enter\n",DRIVER_NAME ));
  224. if (!DeviceObject) {
  225. __leave;
  226. }
  227. pDevExt = DeviceObject->DeviceExtension;
  228. status = USBStopInterruptTransfers(pDevExt->WrapperHandle);
  229. status = USBReleaseInterruptTransfers(pDevExt->WrapperHandle);
  230. if (pDevExt->DeviceDescriptor) {
  231. ExFreePool(pDevExt->DeviceDescriptor);
  232. pDevExt->DeviceDescriptor = NULL;
  233. }
  234. if (pDevExt->Interface) {
  235. ExFreePool(pDevExt->Interface);
  236. pDevExt->Interface = NULL;
  237. }
  238. }
  239. __finally
  240. {
  241. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScStopDevice Exit : 0x%x\n",DRIVER_NAME, status ));
  242. }
  243. return status;
  244. }
  245. NTSTATUS
  246. UsbScRemoveDevice(
  247. PDEVICE_OBJECT DeviceObject,
  248. PIRP Irp
  249. )
  250. /*++
  251. Routine Description:
  252. handles IRP_MN_REMOVE_DEVICE
  253. stops and unloads the device.
  254. Arguments:
  255. Return Value:
  256. --*/
  257. {
  258. NTSTATUS status = STATUS_SUCCESS;
  259. __try
  260. {
  261. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScRemoveDevice Enter\n",DRIVER_NAME ));
  262. UsbScStopDevice(DeviceObject,
  263. Irp);
  264. }
  265. __finally
  266. {
  267. SmartcardDebug( DEBUG_TRACE, ("%s!UsbScRemoveDevice Exit : 0x%x\n",DRIVER_NAME, status ));
  268. }
  269. return status;
  270. }