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.

665 lines
21 KiB

  1. // @doc
  2. /**********************************************************************
  3. *
  4. * @module SwUsbFltShell.c |
  5. *
  6. * Basic driver entry points for SwUsbFlt.sys
  7. *
  8. * History
  9. * ----------------------------------------------------------
  10. * Matthew L Coill Original
  11. *
  12. * (c) 1986-1998 Microsoft Corporation. All right reserved.
  13. *
  14. * @topic SwUsbFltShell |
  15. * Contains the most basic driver entry points (that any WDM driver
  16. * would have) for SwUsbFlt.sys.
  17. *
  18. **********************************************************************/
  19. #define __DEBUG_MODULE_IN_USE__ SWUSBFLTSHELL_C
  20. #include <wdm.h>
  21. #include <usbdi.h>
  22. #include <usbdlib.h>
  23. #include "SwUsbFltShell.h"
  24. typedef unsigned char BYTE;
  25. // Some Local defines for HID
  26. #define HID_REQUEST_TYPE 0x22
  27. #define HID_REPORT_REQUEST 0xA
  28. #define USB_INTERFACE_CLASS_HID 0x03
  29. #define DESCRIPTOR_TYPE_CONFIGURATION 0x22
  30. // Memory TAG
  31. #define SWFILTER_TAG (ULONG)'lfWS'
  32. // Forward Definitions
  33. NTSTATUS SWUSB_AddDevice(IN PDRIVER_OBJECT, IN PDEVICE_OBJECT);
  34. NTSTATUS SWUSB_Power(IN PDEVICE_OBJECT, IN PIRP);
  35. VOID SWUSB_Unload(IN PDRIVER_OBJECT);
  36. //
  37. // Mark the pageable routines as such
  38. //
  39. #ifdef ALLOC_PRAGMA
  40. #pragma alloc_text (INIT, DriverEntry)
  41. #pragma alloc_text (PAGE, SWUSB_AddDevice)
  42. #pragma alloc_text (PAGE, SWUSB_Unload)
  43. #pragma alloc_text (PAGE, SWUSB_Power)
  44. #pragma alloc_text (PAGE, SWUSB_PnP)
  45. #endif
  46. /***********************************************************************************
  47. **
  48. ** NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath )
  49. **
  50. ** @func Standard DriverEntry routine
  51. **
  52. ** @rdesc STATUS_SUCCESS or various errors
  53. **
  54. *************************************************************************************/
  55. NTSTATUS DriverEntry
  56. (
  57. IN PDRIVER_OBJECT pDriverObject, // @parm Driver Object
  58. IN PUNICODE_STRING puniRegistryPath // @parm Path to driver specific registry section.
  59. )
  60. {
  61. int i;
  62. UNREFERENCED_PARAMETER (puniRegistryPath);
  63. PAGED_CODE();
  64. KdPrint(("Built %s at %s\n", __DATE__, __TIME__));
  65. KdPrint(("Entering DriverEntry, pDriverObject = 0x%0.8x\n", pDriverObject));
  66. // Hook all IRPs so we can pass them on.
  67. for (i=0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
  68. {
  69. pDriverObject->MajorFunction[i] = SWUSB_Pass;
  70. }
  71. // Define entries for IRPs we expect to handle
  72. pDriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = SWUSB_Ioctl_Internal;
  73. pDriverObject->MajorFunction[IRP_MJ_PNP] = SWUSB_PnP;
  74. pDriverObject->MajorFunction[IRP_MJ_POWER] = SWUSB_Power;
  75. pDriverObject->DriverExtension->AddDevice = SWUSB_AddDevice;
  76. pDriverObject->DriverUnload = SWUSB_Unload;
  77. return STATUS_SUCCESS;
  78. }
  79. /***********************************************************************************
  80. **
  81. ** VOID SWUSB_Unload(IN PDRIVER_OBJECT pDriverObject)
  82. **
  83. ** @func Called to unload driver deallocate any memory here
  84. **
  85. *************************************************************************************/
  86. VOID SWUSB_Unload
  87. (
  88. IN PDRIVER_OBJECT pDriverObject //@parm Driver Object for our driver
  89. )
  90. {
  91. PAGED_CODE();
  92. UNREFERENCED_PARAMETER(pDriverObject);
  93. KdPrint(("SWUsbFlt.sys unloading\n"));
  94. return;
  95. }
  96. /***********************************************************************************
  97. **
  98. ** NTSTATUS SWUSB_AddDevice(IN PDRIVER_OBJECT pDriverObject, IN PDEVICE_OBJECT pPhysicalDeviceObject)
  99. **
  100. ** @func Handles AddDevice calls from PnP system, create filter device and
  101. ** attach to top of stack.
  102. ** @rdesc STATUS_SUCCES, or various errors
  103. **
  104. *************************************************************************************/
  105. NTSTATUS SWUSB_AddDevice
  106. (
  107. IN PDRIVER_OBJECT pDriverObject, // @parm Driver object to create filter device for
  108. IN PDEVICE_OBJECT pPhysicalDeviceObject // @parm PDO for device to create
  109. )
  110. {
  111. NTSTATUS NtStatus = STATUS_SUCCESS;
  112. PDEVICE_OBJECT pDeviceObject = NULL;
  113. PSWUSB_FILTER_EXT pFilterExt = NULL;
  114. PAGED_CODE();
  115. KdPrint(("Entering SWUSB_AddDevice, pDriverObject = 0x%0.8x, pPDO = 0x%0.8x\n", pDriverObject, pPhysicalDeviceObject));
  116. // Create a filter device object.
  117. NtStatus = IoCreateDevice(pDriverObject,
  118. sizeof (SWUSB_FILTER_EXT),
  119. NULL, // No Name
  120. FILE_DEVICE_UNKNOWN,
  121. 0,
  122. FALSE,
  123. &pDeviceObject);
  124. if (!NT_SUCCESS (NtStatus)) {
  125. //
  126. // returning failure here prevents the entire stack from functioning,
  127. // but most likely the rest of the stack will not be able to create
  128. // device objects either, so it is still OK.
  129. //
  130. KdPrint(("Failed to create filter device object\n"));
  131. KdPrint(("Exiting AddDevice(prematurely) Status: 0x%0.8x\n", NtStatus));
  132. return NtStatus;
  133. }
  134. // Initialize the the device extension.
  135. pFilterExt = (PSWUSB_FILTER_EXT)pDeviceObject->DeviceExtension; // Get pointer to extension
  136. pFilterExt->pPDO = pPhysicalDeviceObject; // Remember our PDO
  137. pFilterExt->pTopOfStack = NULL; //We are not attached to stack yet
  138. // We don't have the pipe information until PNP StartDevice
  139. RtlZeroMemory(&(pFilterExt->outputPipeInfo), sizeof(USBD_PIPE_INFORMATION));
  140. //we use the same IO method as hidclass.sys, which DO_DIRECT_IO
  141. pDeviceObject->StackSize = pPhysicalDeviceObject->StackSize + 1;
  142. pDeviceObject->Flags |= (DO_DIRECT_IO | DO_POWER_PAGABLE);
  143. pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  144. // Attach our filter driver to the device stack.
  145. // the return value of IoAttachDeviceToDeviceStack is the top of the
  146. // attachment chain. This is where all the IRPs should be routed.
  147. //
  148. // Our filter will send IRPs to the top of the stack and use the PDO
  149. // for all PlugPlay functions.
  150. pFilterExt->pTopOfStack = IoAttachDeviceToDeviceStack (pDeviceObject, pPhysicalDeviceObject);
  151. // if this attachment fails then top of stack will be null.
  152. // failure for attachment is an indication of a broken plug play system.
  153. ASSERT (NULL != pFilterExt->pTopOfStack);
  154. KdPrint(("Exiting SWUSB_AddDevice with STATUS_SUCCESS\n"));
  155. return STATUS_SUCCESS;
  156. }
  157. NTSTATUS SWUSB_SubmitUrb
  158. (
  159. IN PDEVICE_OBJECT pDeviceObject, //@parm [OUT] Device Object to submit URB on
  160. IN PURB pUrb //@parm [OUT] URB to submit
  161. )
  162. {
  163. NTSTATUS NtStatus;
  164. PSWUSB_FILTER_EXT pFilterExt;
  165. PIRP pIrp;
  166. KEVENT event;
  167. IO_STATUS_BLOCK ioStatus;
  168. PIO_STACK_LOCATION pNextStack;
  169. KdPrint(("Entering SWUSB_SubmitUrb\n"));
  170. pFilterExt = (PSWUSB_FILTER_EXT)pDeviceObject->DeviceExtension;
  171. // issue a synchronous request to read the UTB
  172. KeInitializeEvent(&event, NotificationEvent, FALSE);
  173. pIrp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
  174. pFilterExt->pTopOfStack,
  175. NULL,
  176. 0,
  177. NULL,
  178. 0,
  179. TRUE, /* INTERNAL */
  180. &event,
  181. &ioStatus);
  182. if (pIrp)
  183. { // pass the URB to the USB 'class driver'
  184. pNextStack = IoGetNextIrpStackLocation(pIrp);
  185. ASSERT(pNextStack != NULL);
  186. pNextStack->Parameters.Others.Argument1 = pUrb;
  187. NtStatus = IoCallDriver(pFilterExt->pTopOfStack, pIrp);
  188. if (NtStatus == STATUS_PENDING) {
  189. NTSTATUS waitStatus;
  190. // Specify a timeout of 5 seconds for this call to complete.
  191. LARGE_INTEGER timeout = {(ULONG) -50000000, 0xFFFFFFFF };
  192. waitStatus = KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, &timeout);
  193. if (waitStatus == STATUS_TIMEOUT)
  194. { // Cancel the Irp we just sent.
  195. IoCancelIrp(pIrp);
  196. // Now wait for the Irp to be cancelled/completed below
  197. waitStatus = KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
  198. /*
  199. * Note - Return STATUS_IO_TIMEOUT, not STATUS_TIMEOUT.
  200. * STATUS_IO_TIMEOUT is an NT error status, STATUS_TIMEOUT is not.
  201. */
  202. ioStatus.Status = STATUS_IO_TIMEOUT;
  203. }
  204. // USBD maps the error code for us
  205. NtStatus = ioStatus.Status;
  206. }
  207. }
  208. else
  209. {
  210. NtStatus = STATUS_INSUFFICIENT_RESOURCES;
  211. }
  212. KdPrint(("Exiting SWUSB_SubmitUrb\n"));
  213. return NtStatus;
  214. }
  215. /***********************************************************************************
  216. **
  217. ** NTSTATUS SWUSB_GetConfigurationDescriptor(IN PDEVICE_OBJECT pDeviceObject, OUT USB_CONFIGURATION_DESCRIPTOR** ppUCD)
  218. **
  219. ** @func Retreive the Full Configuration Descriptor from the device
  220. **
  221. ** @rdesc STATUS_SUCCES, or various errors
  222. **
  223. *************************************************************************************/
  224. NTSTATUS SWUSB_GetConfigurationDescriptor
  225. (
  226. IN PDEVICE_OBJECT pDeviceObject, // @parm [IN] Pointer to our DeviceObject
  227. OUT USB_CONFIGURATION_DESCRIPTOR** ppUCD // @parm [OUT] Usb Configuration Descriptor (allocated here)
  228. )
  229. {
  230. NTSTATUS NtStatus;
  231. PURB pDescriptorRequestUrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), SWFILTER_TAG);
  232. USB_CONFIGURATION_DESCRIPTOR sizingUCD;
  233. // Null out incase of error
  234. *ppUCD = NULL;
  235. KdPrint(("Entering SWUSB_GetConfigurationDescriptor\n"));
  236. if (pDescriptorRequestUrb == NULL)
  237. {
  238. return STATUS_INSUFFICIENT_RESOURCES;
  239. }
  240. // Create and send a size gathering descriptor
  241. UsbBuildGetDescriptorRequest(
  242. pDescriptorRequestUrb,
  243. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  244. USB_CONFIGURATION_DESCRIPTOR_TYPE,
  245. 1,
  246. 0,
  247. &sizingUCD,
  248. NULL,
  249. sizeof(USB_CONFIGURATION_DESCRIPTOR),
  250. NULL
  251. );
  252. NtStatus = SWUSB_SubmitUrb(pDeviceObject, pDescriptorRequestUrb);
  253. if (NT_SUCCESS(NtStatus))
  254. { // Allocate the UCD, Create and send an URB to retreive the information
  255. *ppUCD = ExAllocatePoolWithTag(NonPagedPool, sizingUCD.wTotalLength, SWFILTER_TAG);
  256. if (*ppUCD == NULL)
  257. {
  258. NtStatus = STATUS_INSUFFICIENT_RESOURCES;
  259. }
  260. else
  261. {
  262. UsbBuildGetDescriptorRequest(
  263. pDescriptorRequestUrb,
  264. sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
  265. USB_CONFIGURATION_DESCRIPTOR_TYPE,
  266. 1,
  267. 0,
  268. *ppUCD,
  269. NULL,
  270. sizingUCD.wTotalLength,
  271. NULL
  272. );
  273. NtStatus = SWUSB_SubmitUrb(pDeviceObject, pDescriptorRequestUrb);
  274. }
  275. }
  276. // Deallocate the URB
  277. ExFreePool(pDescriptorRequestUrb);
  278. KdPrint(("Exiting SWUSB_GetConfigurationDescriptor\n"));
  279. return NtStatus;
  280. }
  281. /***********************************************************************************
  282. **
  283. ** NTSTATUS StartDeviceComplete(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, PVOID pvContext)
  284. **
  285. ** @func StartDeviceComplete
  286. **
  287. ** @rdesc STATUS_SUCCESS always
  288. **
  289. *************************************************************************************/
  290. NTSTATUS StartDeviceComplete
  291. (
  292. IN PDEVICE_OBJECT pDeviceObject,
  293. IN PIRP pIrp,
  294. PVOID pvContext // @parm Actually a pointer to an event to signal
  295. )
  296. {
  297. PKEVENT pNotifyEvent;
  298. UNREFERENCED_PARAMETER(pDeviceObject);
  299. UNREFERENCED_PARAMETER(pIrp);
  300. // Cast context to device extension
  301. pNotifyEvent = (PKEVENT)pvContext;
  302. KeSetEvent(pNotifyEvent, IO_NO_INCREMENT, FALSE);
  303. // Done with this IRP let the system finish with it
  304. return STATUS_MORE_PROCESSING_REQUIRED;
  305. }
  306. /***********************************************************************************
  307. **
  308. ** NTSTATUS SWUSB_PnP(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
  309. **
  310. ** @func Handles IRP_MJ_PnP
  311. **
  312. ** @rdesc STATUS_SUCCESS, or various errors
  313. **
  314. *************************************************************************************/
  315. NTSTATUS SWUSB_PnP
  316. (
  317. IN PDEVICE_OBJECT pDeviceObject, // @parm Device Object for our context
  318. IN PIRP pIrp // @parm IRP to handle
  319. )
  320. {
  321. NTSTATUS NtStatus = STATUS_SUCCESS;
  322. PSWUSB_FILTER_EXT pFilterExt;
  323. PIO_STACK_LOCATION pIrpStack;
  324. PDEVICE_OBJECT *ppPrevDeviceObjectPtr;
  325. PDEVICE_OBJECT pCurDeviceObject;
  326. BOOLEAN fRemovedFromList;
  327. BOOLEAN fFoundOne;
  328. PAGED_CODE();
  329. //cast device extension to proper type
  330. pFilterExt = (PSWUSB_FILTER_EXT) pDeviceObject->DeviceExtension;
  331. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  332. switch (pIrpStack->MinorFunction) {
  333. case IRP_MN_REMOVE_DEVICE:
  334. {
  335. KdPrint(("IRP_MN_REMOVE_DEVICE\n"));
  336. // Send on the remove IRP
  337. IoSkipCurrentIrpStackLocation (pIrp);
  338. NtStatus = IoCallDriver (pFilterExt->pTopOfStack, pIrp);
  339. // Clean up
  340. IoDetachDevice (pFilterExt->pTopOfStack); //Detach from top of stack
  341. IoDeleteDevice (pDeviceObject); //Delete ourselves
  342. // Must succeed this (???)
  343. return STATUS_SUCCESS;
  344. };
  345. case IRP_MN_START_DEVICE:
  346. case IRP_MN_QUERY_DEVICE_RELATIONS:
  347. case IRP_MN_QUERY_STOP_DEVICE:
  348. case IRP_MN_QUERY_REMOVE_DEVICE:
  349. case IRP_MN_SURPRISE_REMOVAL:
  350. case IRP_MN_STOP_DEVICE:
  351. case IRP_MN_CANCEL_STOP_DEVICE:
  352. case IRP_MN_CANCEL_REMOVE_DEVICE:
  353. case IRP_MN_QUERY_INTERFACE:
  354. case IRP_MN_QUERY_CAPABILITIES:
  355. case IRP_MN_QUERY_RESOURCES:
  356. case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
  357. case IRP_MN_READ_CONFIG:
  358. case IRP_MN_WRITE_CONFIG:
  359. case IRP_MN_EJECT:
  360. case IRP_MN_SET_LOCK:
  361. case IRP_MN_QUERY_ID:
  362. case IRP_MN_QUERY_PNP_DEVICE_STATE:
  363. default:
  364. IoSkipCurrentIrpStackLocation (pIrp);
  365. NtStatus = IoCallDriver (pFilterExt->pTopOfStack, pIrp);
  366. break;
  367. }
  368. return NtStatus;
  369. }
  370. /***********************************************************************************
  371. **
  372. ** NTSTATUS ReportDescriptorComplete(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, PVOID pvContext)
  373. **
  374. ** @func ReportDescriptorComplete
  375. **
  376. ** @rdesc STATUS_SUCCESS always
  377. **
  378. *************************************************************************************/
  379. NTSTATUS ReportDescriptorComplete
  380. (
  381. IN PDEVICE_OBJECT pDeviceObject,
  382. IN PIRP pIrp,
  383. PVOID pvContext // @parm Actually a pointer to an event to signal
  384. )
  385. {
  386. PKEVENT pNotifyEvent;
  387. UNREFERENCED_PARAMETER(pDeviceObject);
  388. UNREFERENCED_PARAMETER(pIrp);
  389. // Cast context to device extension
  390. pNotifyEvent = (PKEVENT)pvContext;
  391. KeSetEvent(pNotifyEvent, IO_NO_INCREMENT, FALSE);
  392. // Done with this IRP let the system finish with it
  393. return STATUS_MORE_PROCESSING_REQUIRED;
  394. }
  395. /***********************************************************************************
  396. **
  397. ** NTSTATUS SelectConfigComplete(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, PVOID pvContext)
  398. **
  399. ** @func SelectConfigComplete
  400. **
  401. ** @rdesc STATUS_SUCCESS always
  402. **
  403. *************************************************************************************/
  404. NTSTATUS SelectConfigComplete
  405. (
  406. IN PDEVICE_OBJECT pDeviceObject,
  407. IN PIRP pIrp,
  408. PVOID pvContext // @parm Actually a pointer to an event to signal
  409. )
  410. {
  411. PKEVENT pNotifyEvent;
  412. USBD_INTERFACE_INFORMATION* pUsbInterfaceInformation;
  413. PSWUSB_FILTER_EXT pFilterExt;
  414. PURB pUrb = URB_FROM_IRP(pIrp);
  415. ULONG pipeIndex;
  416. pFilterExt = pDeviceObject->DeviceExtension;
  417. if (pIrp->IoStatus.Status == STATUS_SUCCESS)
  418. {
  419. pUsbInterfaceInformation = &(pUrb->UrbSelectConfiguration.Interface);
  420. for (pipeIndex = 0; pipeIndex < pUsbInterfaceInformation->NumberOfPipes; pipeIndex++){
  421. if ((pUsbInterfaceInformation->Pipes[pipeIndex].EndpointAddress & USB_ENDPOINT_DIRECTION_MASK) == 0)
  422. {
  423. if (pUsbInterfaceInformation->Pipes[pipeIndex].PipeType == UsbdPipeTypeInterrupt)
  424. {
  425. pFilterExt->outputPipeInfo = pUsbInterfaceInformation->Pipes[pipeIndex];
  426. break;
  427. }
  428. }
  429. }
  430. }
  431. //If the IRP failed somehow, make sure outputPipeInfo stays NULL
  432. else RtlZeroMemory(&(pFilterExt->outputPipeInfo), sizeof(USBD_PIPE_INFORMATION));
  433. // Cast context to device extension
  434. pNotifyEvent = (PKEVENT)pvContext;
  435. KeSetEvent(pNotifyEvent, IO_NO_INCREMENT, FALSE);
  436. // Done with this IRP let the system finish with it
  437. return STATUS_MORE_PROCESSING_REQUIRED;
  438. }
  439. /***********************************************************************************
  440. **
  441. ** NTSTATUS SWUSB_Ioctl_Internal(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
  442. **
  443. ** @func IRP_MJ_INTERNAL_IOCTL
  444. **
  445. ** @rdesc STATUS_SUCCES, or various errors
  446. **
  447. *************************************************************************************/
  448. NTSTATUS SWUSB_Ioctl_Internal
  449. (
  450. IN PDEVICE_OBJECT pDeviceObject, // @parm pointer to Device Object
  451. IN PIRP pIrp // @parm pointer to IRP
  452. )
  453. {
  454. NTSTATUS NtStatus;
  455. NTSTATUS NTStatus2;
  456. ULONG uIoctl;
  457. PSWUSB_FILTER_EXT pFilterExt;
  458. uIoctl = IoGetCurrentIrpStackLocation(pIrp)->Parameters.DeviceIoControl.IoControlCode;
  459. pFilterExt = (PSWUSB_FILTER_EXT)pDeviceObject->DeviceExtension;
  460. switch (uIoctl)
  461. {
  462. case IOCTL_INTERNAL_USB_SUBMIT_URB:
  463. {
  464. PURB pUrb = URB_FROM_IRP(pIrp);
  465. //Only handle this if it's a HID descriptor request and we have a pipe handle
  466. if (pUrb->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE &&
  467. pUrb->UrbControlDescriptorRequest.DescriptorType == DESCRIPTOR_TYPE_CONFIGURATION &&
  468. pFilterExt->outputPipeInfo.PipeHandle != NULL)
  469. {
  470. BYTE* pOutData = NULL;
  471. KEVENT irpCompleteEvent;
  472. PURB pInterruptUrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), SWFILTER_TAG);
  473. KdPrint(("IOCTL_INTERNAL_USB_SUBMIT_URB\n"));
  474. if (pInterruptUrb == NULL)
  475. {
  476. pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
  477. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  478. KdPrint(("IOCTL_INTERNAL_USB_SUBMIT_URB -- STATUS_INSUFFICIENT_RESOURCES\n"));
  479. return STATUS_INSUFFICIENT_RESOURCES;
  480. }
  481. pOutData = ExAllocatePoolWithTag(NonPagedPool, sizeof(BYTE)*2, SWFILTER_TAG);
  482. if (pOutData == NULL)
  483. {
  484. ExFreePool(pInterruptUrb);
  485. pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
  486. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  487. KdPrint(("IOCTL_INTERNAL_USB_SUBMIT_URB (1) -- STATUS_INSUFFICIENT_RESOURCES\n"));
  488. return STATUS_INSUFFICIENT_RESOURCES;
  489. }
  490. pOutData[0] = 0x0D;
  491. pOutData[1] = 0xFF;
  492. UsbBuildInterruptOrBulkTransferRequest(
  493. pInterruptUrb,
  494. sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
  495. pFilterExt->outputPipeInfo.PipeHandle,
  496. pOutData,
  497. NULL,
  498. 2,
  499. USBD_SHORT_TRANSFER_OK,
  500. NULL
  501. );
  502. KeInitializeEvent(&irpCompleteEvent, NotificationEvent, FALSE);
  503. IoCopyCurrentIrpStackLocationToNext(pIrp);
  504. IoSetCompletionRoutine(pIrp, ReportDescriptorComplete, (PVOID)(&irpCompleteEvent), TRUE, TRUE, TRUE);
  505. NtStatus = IoCallDriver (pFilterExt->pTopOfStack, pIrp);
  506. if (NtStatus == STATUS_PENDING)
  507. {
  508. KeWaitForSingleObject(&irpCompleteEvent, Executive, KernelMode, FALSE, 0);
  509. }
  510. NtStatus = pIrp->IoStatus.Status;
  511. NTStatus2 = SWUSB_SubmitUrb(pDeviceObject, pInterruptUrb);
  512. ExFreePool(pOutData);
  513. ExFreePool(pInterruptUrb);
  514. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  515. return NtStatus;
  516. }
  517. if ((pUrb->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION))
  518. {
  519. KEVENT irpCompleteEvent;
  520. KeInitializeEvent(&irpCompleteEvent, NotificationEvent, FALSE);
  521. IoCopyCurrentIrpStackLocationToNext(pIrp);
  522. IoSetCompletionRoutine(pIrp, SelectConfigComplete, (PVOID)(&irpCompleteEvent), TRUE, TRUE, TRUE);
  523. NtStatus = IoCallDriver (pFilterExt->pTopOfStack, pIrp);
  524. if (NtStatus == STATUS_PENDING)
  525. {
  526. KeWaitForSingleObject(&irpCompleteEvent, Executive, KernelMode, FALSE, 0);
  527. }
  528. NtStatus = pIrp->IoStatus.Status;
  529. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  530. return NtStatus;
  531. }
  532. }
  533. }
  534. IoSkipCurrentIrpStackLocation (pIrp);
  535. NtStatus = IoCallDriver (pFilterExt->pTopOfStack, pIrp);
  536. return NtStatus;
  537. }
  538. /***********************************************************************************
  539. **
  540. ** NTSTATUS SWUSB_Power(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
  541. **
  542. ** @func Passes on power IRPs to lower drivers
  543. **
  544. ** @rdesc Status from lower level driver
  545. **
  546. *************************************************************************************/
  547. NTSTATUS SWUSB_Power
  548. (
  549. IN PDEVICE_OBJECT pDeviceObject,
  550. IN PIRP pIrp
  551. )
  552. {
  553. NTSTATUS NtStatus;
  554. PSWUSB_FILTER_EXT pFilterExt = (PSWUSB_FILTER_EXT)pDeviceObject->DeviceExtension;
  555. PAGED_CODE();
  556. KdPrint(("SWUSB_Power() - Entering\n"));
  557. PoStartNextPowerIrp(pIrp);
  558. IoSkipCurrentIrpStackLocation(pIrp);
  559. NtStatus = PoCallDriver(pFilterExt->pTopOfStack, pIrp);
  560. KdPrint(("SWUSB_Power() - Exiting\n"));
  561. return NtStatus;
  562. }
  563. /***********************************************************************************
  564. **
  565. ** NTSTATUS SWUSB_Pass (IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
  566. **
  567. ** @func Passes on unhandled IRPs to lower drivers DEBUG version trace out info
  568. ** Cannot be pageable since we have no idea what IRPs we're getting.
  569. **
  570. ** @rdesc STATUS_SUCCESS, various errors
  571. **
  572. *************************************************************************************/
  573. NTSTATUS SWUSB_Pass (
  574. IN PDEVICE_OBJECT pDeviceObject, // @parm Device Object as our context
  575. IN PIRP pIrp // @parm IRP to pass on
  576. )
  577. {
  578. NTSTATUS NtStatus;
  579. PSWUSB_FILTER_EXT pFilterExt;
  580. KdPrint(("SWUSB_Pass() - Entering\n"));
  581. pFilterExt = (PSWUSB_FILTER_EXT)pDeviceObject->DeviceExtension;
  582. IoSkipCurrentIrpStackLocation (pIrp);
  583. NtStatus = IoCallDriver (pFilterExt->pTopOfStack, pIrp);
  584. //return
  585. return NtStatus;
  586. }