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.

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