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.

1482 lines
44 KiB

  1. /*++
  2. Copyright (c) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. GENUSB.C
  5. Abstract:
  6. This source file contains the DriverEntry() and AddDevice() entry points
  7. for the GENUSB driver and the dispatch routines which handle:
  8. IRP_MJ_POWER
  9. IRP_MJ_SYSTEM_CONTROL
  10. IRP_MJ_PNP
  11. Environment:
  12. kernel mode
  13. Revision History:
  14. Sep 2001 : Copied from USBMASS
  15. --*/
  16. //*****************************************************************************
  17. // I N C L U D E S
  18. //*****************************************************************************
  19. #include <initguid.h>
  20. #include "genusb.h"
  21. //*****************************************************************************
  22. // L O C A L F U N C T I O N P R O T O T Y P E S
  23. //*****************************************************************************
  24. #ifdef ALLOC_PRAGMA
  25. #pragma alloc_text(PAGE, DriverEntry)
  26. #pragma alloc_text(PAGE, GenUSB_Unload)
  27. #pragma alloc_text(PAGE, GenUSB_AddDevice)
  28. #pragma alloc_text(PAGE, GenUSB_QueryParams)
  29. #pragma alloc_text(PAGE, GenUSB_Pnp)
  30. #pragma alloc_text(PAGE, GenUSB_StartDevice)
  31. #pragma alloc_text(PAGE, GenUSB_StopDevice)
  32. #pragma alloc_text(PAGE, GenUSB_RemoveDevice)
  33. #pragma alloc_text(PAGE, GenUSB_QueryStopRemoveDevice)
  34. #pragma alloc_text(PAGE, GenUSB_CancelStopRemoveDevice)
  35. #pragma alloc_text(PAGE, GenUSB_SetDeviceInterface)
  36. #pragma alloc_text(PAGE, GenUSB_SyncPassDownIrp)
  37. #pragma alloc_text(PAGE, GenUSB_SyncSendUsbRequest)
  38. #pragma alloc_text(PAGE, GenUSB_SetDIRegValues)
  39. #pragma alloc_text(PAGE, GenUSB_SystemControl)
  40. #pragma alloc_text(PAGE, GenUSB_Power)
  41. #pragma alloc_text(PAGE, GenUSB_SetPower)
  42. #if 0
  43. #pragma alloc_text(PAGE, GenUSB_AbortPipe)
  44. #endif
  45. #endif
  46. //******************************************************************************
  47. //
  48. // DriverEntry()
  49. //
  50. //******************************************************************************
  51. NTSTATUS
  52. DriverEntry (
  53. IN PDRIVER_OBJECT DriverObject,
  54. IN PUNICODE_STRING RegistryPath
  55. )
  56. {
  57. PAGED_CODE();
  58. // Query the registry for global parameters
  59. GenUSB_QueryGlobalParams();
  60. DBGPRINT(2, ("enter: DriverEntry\n"));
  61. DBGFBRK(DBGF_BRK_DRIVERENTRY);
  62. //
  63. // Initialize the Driver Object with the driver's entry points
  64. //
  65. //
  66. // GENUSB.C
  67. //
  68. DriverObject->DriverUnload = GenUSB_Unload;
  69. DriverObject->DriverExtension->AddDevice = GenUSB_AddDevice;
  70. //
  71. // OCRW.C
  72. //
  73. DriverObject->MajorFunction[IRP_MJ_CREATE] = GenUSB_Create;
  74. DriverObject->MajorFunction[IRP_MJ_CLOSE] = GenUSB_Close;
  75. DriverObject->MajorFunction[IRP_MJ_READ] = GenUSB_Read;
  76. DriverObject->MajorFunction[IRP_MJ_WRITE] = GenUSB_Write;
  77. //
  78. // DEVIOCTL.C
  79. //
  80. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GenUSB_DeviceControl;
  81. //
  82. // GENUSB.C
  83. //
  84. DriverObject->MajorFunction[IRP_MJ_PNP] = GenUSB_Pnp;
  85. DriverObject->MajorFunction[IRP_MJ_POWER] = GenUSB_Power;
  86. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = GenUSB_SystemControl;
  87. DBGPRINT(2, ("exit: DriverEntry\n"));
  88. return STATUS_SUCCESS;
  89. }
  90. //******************************************************************************
  91. //
  92. // GenUSB_Unload()
  93. //
  94. //******************************************************************************
  95. VOID
  96. GenUSB_Unload (
  97. IN PDRIVER_OBJECT DriverObject
  98. )
  99. {
  100. DEVICE_EXTENSION deviceExtension;
  101. PAGED_CODE();
  102. DBGPRINT(2, ("enter: GenUSB_Unload\n"));
  103. DBGFBRK(DBGF_BRK_UNLOAD);
  104. DBGPRINT(2, ("exit: GenUSB_Unload\n"));
  105. }
  106. //******************************************************************************
  107. //
  108. // GenUSB_AddDevice()
  109. //
  110. //******************************************************************************
  111. NTSTATUS
  112. GenUSB_AddDevice (
  113. IN PDRIVER_OBJECT DriverObject,
  114. IN PDEVICE_OBJECT PhysicalDeviceObject
  115. )
  116. {
  117. PDEVICE_OBJECT deviceObject;
  118. PDEVICE_EXTENSION fdoDeviceExtension;
  119. NTSTATUS ntStatus;
  120. PAGED_CODE();
  121. DBGPRINT(2, ("enter: GenUSB_AddDevice\n"));
  122. DBGFBRK(DBGF_BRK_ADDDEVICE);
  123. // Create the FDO
  124. //
  125. ntStatus = IoCreateDevice(DriverObject,
  126. sizeof(DEVICE_EXTENSION),
  127. NULL,
  128. FILE_DEVICE_UNKNOWN,
  129. 0,
  130. FALSE,
  131. &deviceObject);
  132. if (!NT_SUCCESS(ntStatus))
  133. {
  134. return ntStatus;
  135. }
  136. fdoDeviceExtension = deviceObject->DeviceExtension;
  137. LOGENTRY(fdoDeviceExtension, 'ADDD', DriverObject, PhysicalDeviceObject, 0);
  138. // Set all DeviceExtension pointers to NULL and all variable to zero
  139. RtlZeroMemory(fdoDeviceExtension, sizeof(DEVICE_EXTENSION));
  140. // Store a back point to the DeviceObject for this DeviceExtension
  141. fdoDeviceExtension->Self = deviceObject;
  142. // Remember our PDO
  143. fdoDeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
  144. // Attach the FDO we created to the top of the PDO stack
  145. fdoDeviceExtension->StackDeviceObject =
  146. IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);
  147. LOGINIT (fdoDeviceExtension);
  148. IoInitializeRemoveLock (&fdoDeviceExtension->RemoveLock,
  149. POOL_TAG,
  150. 0,
  151. 0);
  152. // Set the initial system and device power states
  153. fdoDeviceExtension->SystemPowerState = PowerSystemWorking;
  154. fdoDeviceExtension->DevicePowerState = PowerDeviceD0;
  155. // Initialize the spinlock which protects the PDO DeviceFlags
  156. KeInitializeSpinLock(&fdoDeviceExtension->SpinLock);
  157. ExInitializeFastMutex(&fdoDeviceExtension->ConfigMutex);
  158. fdoDeviceExtension->OpenedCount = 0;
  159. GenUSB_QueryParams(deviceObject);
  160. fdoDeviceExtension->ReadInterface = -1;
  161. fdoDeviceExtension->ReadPipe = -1;
  162. fdoDeviceExtension->WriteInterface = -1;
  163. fdoDeviceExtension->ReadPipe = -1;
  164. IoInitializeTimer (deviceObject, GenUSB_Timer, NULL);
  165. deviceObject->Flags |= DO_DIRECT_IO;
  166. deviceObject->Flags |= DO_POWER_PAGABLE;
  167. deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  168. DBGPRINT(2, ("exit: GenUSB_AddDevice\n"));
  169. LOGENTRY(fdoDeviceExtension,
  170. 'addd',
  171. deviceObject,
  172. fdoDeviceExtension,
  173. fdoDeviceExtension->StackDeviceObject);
  174. return STATUS_SUCCESS;
  175. }
  176. //******************************************************************************
  177. //
  178. // GenUSB_QueryParams()
  179. //
  180. // This is called at AddDevice() time when the FDO is being created to query
  181. // device parameters from the registry.
  182. //
  183. //******************************************************************************
  184. VOID
  185. GenUSB_QueryParams (
  186. IN PDEVICE_OBJECT DeviceObject
  187. )
  188. {
  189. PDEVICE_EXTENSION deviceExtension;
  190. RTL_QUERY_REGISTRY_TABLE paramTable[3];
  191. HANDLE handle;
  192. NTSTATUS status;
  193. ULONG defaultReadPipe;
  194. ULONG defaultWritePipe;
  195. PAGED_CODE();
  196. DBGPRINT(2, ("enter: GenUSB_QueryFdoParams\n"));
  197. deviceExtension = DeviceObject->DeviceExtension;
  198. // Set the default value in case the registry key does not exist.
  199. defaultReadPipe = 0;
  200. defaultWritePipe = 0;
  201. status = IoOpenDeviceRegistryKey(
  202. deviceExtension->PhysicalDeviceObject,
  203. PLUGPLAY_REGKEY_DRIVER,
  204. STANDARD_RIGHTS_ALL,
  205. &handle);
  206. if (NT_SUCCESS(status))
  207. {
  208. RtlZeroMemory (&paramTable[0], sizeof(paramTable));
  209. paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  210. paramTable[0].Name = REGKEY_DEFAULT_READ_PIPE;
  211. paramTable[0].EntryContext = &defaultReadPipe;
  212. paramTable[0].DefaultType = REG_DWORD;
  213. paramTable[0].DefaultData = &defaultReadPipe;
  214. paramTable[0].DefaultLength = sizeof(ULONG);
  215. paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  216. paramTable[1].Name = REGKEY_DEFAULT_WRITE_PIPE;
  217. paramTable[1].EntryContext = &defaultWritePipe;
  218. paramTable[1].DefaultType = REG_DWORD;
  219. paramTable[1].DefaultData = &defaultWritePipe;
  220. paramTable[1].DefaultLength = sizeof(ULONG);
  221. RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
  222. (PCWSTR)handle,
  223. &paramTable[0],
  224. NULL, // Context
  225. NULL); // Environment
  226. ZwClose(handle);
  227. }
  228. // deviceExtension->DefaultReadPipe = defaultReadPipe;
  229. // deviceExtension->DefaultWritePipe = defaultWritePipe;
  230. DBGPRINT(2, ("DefaultReadPipe %08X\n", defaultReadPipe));
  231. DBGPRINT(2, ("DefaultWritePipe %08X\n", defaultWritePipe));
  232. DBGPRINT(2, ("exit: GenUSB_QueryFdoParams\n"));
  233. }
  234. //******************************************************************************
  235. //
  236. // GenUSB_Pnp()
  237. //
  238. // Dispatch routine which handles IRP_MJ_PNP
  239. //
  240. //******************************************************************************
  241. NTSTATUS
  242. GenUSB_Pnp (
  243. IN PDEVICE_OBJECT DeviceObject,
  244. IN PIRP Irp
  245. )
  246. {
  247. PDEVICE_EXTENSION deviceExtension;
  248. PIO_STACK_LOCATION irpStack;
  249. NTSTATUS status;
  250. PAGED_CODE();
  251. deviceExtension = DeviceObject->DeviceExtension;
  252. status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
  253. if (!NT_SUCCESS(status)) {
  254. Irp->IoStatus.Status = status;
  255. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  256. return status;
  257. }
  258. irpStack = IoGetCurrentIrpStackLocation(Irp);
  259. DBGPRINT(2, ("enter: GenUSB_Pnp %s\n",
  260. PnPMinorFunctionString(irpStack->MinorFunction)));
  261. LOGENTRY(deviceExtension, 'PNP ', DeviceObject, Irp, irpStack->MinorFunction);
  262. switch (irpStack->MinorFunction) {
  263. case IRP_MN_START_DEVICE:
  264. status = GenUSB_StartDevice(DeviceObject, Irp);
  265. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  266. break;
  267. case IRP_MN_REMOVE_DEVICE:
  268. status = GenUSB_RemoveDevice(DeviceObject, Irp);
  269. break;
  270. case IRP_MN_QUERY_STOP_DEVICE:
  271. case IRP_MN_QUERY_REMOVE_DEVICE:
  272. status = GenUSB_QueryStopRemoveDevice(DeviceObject, Irp);
  273. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  274. break;
  275. case IRP_MN_CANCEL_STOP_DEVICE:
  276. case IRP_MN_CANCEL_REMOVE_DEVICE:
  277. status = GenUSB_CancelStopRemoveDevice(DeviceObject, Irp);
  278. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  279. break;
  280. case IRP_MN_STOP_DEVICE:
  281. status = GenUSB_StopDevice(DeviceObject, Irp);
  282. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  283. break;
  284. case IRP_MN_SURPRISE_REMOVAL:
  285. //
  286. // The documentation says to set the status before passing the
  287. // Irp down the stack
  288. //
  289. Irp->IoStatus.Status = STATUS_SUCCESS;
  290. // nothing else special yet, just fall through to default
  291. default:
  292. //
  293. // Pass the request down to the next lower driver
  294. //
  295. IoSkipCurrentIrpStackLocation(Irp);
  296. status = IoCallDriver(deviceExtension->StackDeviceObject, Irp);
  297. IoReleaseRemoveLock (&deviceExtension->RemoveLock, Irp);
  298. break;
  299. }
  300. DBGPRINT(2, ("exit: GenUSB_Pnp %08X\n", status));
  301. LOGENTRY(deviceExtension, 'pnp ', status, 0, 0);
  302. return status;
  303. }
  304. //******************************************************************************
  305. //
  306. // GenUSB_StartDevice()
  307. //
  308. // This routine handles IRP_MJ_PNP, IRP_MN_START_DEVICE for the FDO
  309. //
  310. // The PnP Manager sends this IRP at IRQL PASSIVE_LEVEL in the context of a
  311. // system thread.
  312. //
  313. // This IRP must be handled first by the underlying bus driver for a device
  314. // and then by each higher driver in the device stack.
  315. //
  316. //******************************************************************************
  317. NTSTATUS
  318. GenUSB_StartDevice (
  319. IN PDEVICE_OBJECT DeviceObject,
  320. IN PIRP Irp
  321. )
  322. {
  323. PDEVICE_EXTENSION deviceExtension;
  324. NTSTATUS status;
  325. PAGED_CODE();
  326. DBGPRINT(2, ("enter: GenUSB_StartDevice\n"));
  327. DBGFBRK(DBGF_BRK_STARTDEVICE);
  328. deviceExtension = DeviceObject->DeviceExtension;
  329. LOGENTRY(deviceExtension, 'STRT', DeviceObject, Irp, 0);
  330. if (deviceExtension->IsStarted)
  331. {
  332. status = STATUS_SUCCESS;
  333. goto GenUSB_StartDeviceDone;
  334. }
  335. // Pass IRP_MN_START_DEVICE Irp down the stack first before we do anything.
  336. status = GenUSB_SyncPassDownIrp(DeviceObject, Irp);
  337. if (!NT_SUCCESS(status)) {
  338. DBGPRINT(1, ("Lower driver failed IRP_MN_START_DEVICE\n"));
  339. LOGENTRY(deviceExtension, 'STRF', DeviceObject, Irp, status);
  340. goto GenUSB_StartDeviceDone;
  341. }
  342. // If this is the first time the device as been started, retrieve the
  343. // Device and Configuration Descriptors from the device.
  344. if (deviceExtension->DeviceDescriptor == NULL) {
  345. status = GenUSB_GetDescriptors(DeviceObject);
  346. if (!NT_SUCCESS(status)) {
  347. goto GenUSB_StartDeviceDone;
  348. }
  349. // Create the interface but do not set it yet.
  350. GenUSB_SetDeviceInterface (deviceExtension, TRUE, FALSE);
  351. // Set up the registry values for the clients
  352. GenUSB_SetDIRegValues (deviceExtension);
  353. // Set up the device Interface.
  354. GenUSB_SetDeviceInterface (deviceExtension, FALSE, TRUE);
  355. }
  356. else
  357. {
  358. ExAcquireFastMutex (&deviceExtension->ConfigMutex);
  359. if (NULL != deviceExtension->ConfigurationHandle)
  360. {
  361. IoStartTimer (DeviceObject);
  362. }
  363. ExReleaseFastMutex (&deviceExtension->ConfigMutex);
  364. }
  365. deviceExtension->IsStarted = TRUE;
  366. GenUSB_StartDeviceDone:
  367. // Must complete request since completion routine returned
  368. // STATUS_MORE_PROCESSING_REQUIRED
  369. Irp->IoStatus.Status = status;
  370. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  371. DBGPRINT(2, ("exit: GenUSB_FdoStartDevice %08X\n", status));
  372. LOGENTRY(deviceExtension, 'strt', status, 0, 0);
  373. return status;
  374. }
  375. //******************************************************************************
  376. //
  377. // GenUSB_SetDeviceInterface()
  378. //
  379. // This routine is called at START_DEVICE time to publish a device interface
  380. // GUID so that the user mode LIB can find the FDOs.
  381. //
  382. //******************************************************************************
  383. NTSTATUS
  384. GenUSB_SetDeviceInterface (
  385. IN PDEVICE_EXTENSION DeviceExtension,
  386. IN BOOLEAN Create,
  387. IN BOOLEAN Set
  388. )
  389. {
  390. NTSTATUS status = STATUS_SUCCESS;
  391. PAGED_CODE();
  392. if (Create || Set)
  393. {
  394. if (Create)
  395. {
  396. ASSERT (NULL == DeviceExtension->DevInterfaceLinkName.Buffer);
  397. status = IoRegisterDeviceInterface (
  398. DeviceExtension->PhysicalDeviceObject,
  399. (LPGUID)&GUID_DEVINTERFACE_GENUSB,
  400. NULL,
  401. &DeviceExtension->DevInterfaceLinkName);
  402. }
  403. if (NT_SUCCESS(status) && Set)
  404. {
  405. status = IoSetDeviceInterfaceState (
  406. &DeviceExtension->DevInterfaceLinkName,
  407. TRUE);
  408. }
  409. }
  410. else
  411. {
  412. ASSERT (NULL != DeviceExtension->DevInterfaceLinkName.Buffer);
  413. status = IoSetDeviceInterfaceState(
  414. &DeviceExtension->DevInterfaceLinkName,
  415. FALSE);
  416. RtlFreeUnicodeString (&DeviceExtension->DevInterfaceLinkName);
  417. }
  418. return status;
  419. }
  420. //******************************************************************************
  421. //
  422. // GenUSB_SyncCompletionRoutine()
  423. //
  424. // Completion routine used by GenUSB_SyncPassDownIrp and
  425. // GenUSB_SyncSendUsbRequest
  426. //
  427. // If the Irp is one we allocated ourself, DeviceObject is NULL.
  428. //
  429. //******************************************************************************
  430. NTSTATUS
  431. GenUSB_SyncCompletionRoutine (
  432. IN PDEVICE_OBJECT DeviceObject,
  433. IN PIRP Irp,
  434. IN PVOID Context
  435. )
  436. {
  437. PDEVICE_EXTENSION deviceExtension;
  438. KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
  439. return STATUS_MORE_PROCESSING_REQUIRED;
  440. }
  441. //******************************************************************************
  442. //
  443. // GenUSB_SyncPassDownIrp()
  444. //
  445. //******************************************************************************
  446. NTSTATUS
  447. GenUSB_SyncPassDownIrp (
  448. IN PDEVICE_OBJECT DeviceObject,
  449. IN PIRP Irp
  450. )
  451. {
  452. PDEVICE_EXTENSION deviceExtension;
  453. NTSTATUS status;
  454. KEVENT localevent;
  455. PAGED_CODE();
  456. DBGPRINT(2, ("enter: GenUSB_SyncPassDownIrp\n"));
  457. deviceExtension = DeviceObject->DeviceExtension;
  458. // Initialize the event we'll wait on
  459. KeInitializeEvent(&localevent, SynchronizationEvent, FALSE);
  460. // Copy down Irp params for the next driver
  461. IoCopyCurrentIrpStackLocationToNext(Irp);
  462. // Set the completion routine, which will signal the event
  463. IoSetCompletionRoutine(Irp,
  464. GenUSB_SyncCompletionRoutine,
  465. &localevent,
  466. TRUE, // InvokeOnSuccess
  467. TRUE, // InvokeOnError
  468. TRUE); // InvokeOnCancel
  469. // Pass the Irp down the stack
  470. status = IoCallDriver(deviceExtension->StackDeviceObject, Irp);
  471. KeWaitForSingleObject(&localevent,
  472. Executive,
  473. KernelMode,
  474. FALSE,
  475. NULL);
  476. status = Irp->IoStatus.Status;
  477. DBGPRINT(2, ("exit: GenUSB_SyncPassDownIrp %08X\n", status));
  478. return status;
  479. }
  480. //******************************************************************************
  481. //
  482. // GenUSB_SyncSendUsbRequest()
  483. //
  484. // Must be called at IRQL PASSIVE_LEVEL
  485. //
  486. //******************************************************************************
  487. NTSTATUS
  488. GenUSB_SyncSendUsbRequest (
  489. IN PDEVICE_OBJECT DeviceObject,
  490. IN PURB Urb
  491. )
  492. {
  493. PDEVICE_EXTENSION deviceExtension;
  494. KEVENT localevent;
  495. PIRP irp;
  496. PIO_STACK_LOCATION nextStack;
  497. NTSTATUS status;
  498. PAGED_CODE();
  499. DBGPRINT(3, ("enter: GenUSB_SyncSendUsbRequest\n"));
  500. deviceExtension = DeviceObject->DeviceExtension;
  501. // Initialize the event we'll wait on
  502. KeInitializeEvent(&localevent, SynchronizationEvent, FALSE);
  503. // Allocate the Irp
  504. irp = IoAllocateIrp(deviceExtension->StackDeviceObject->StackSize, FALSE);
  505. LOGENTRY(deviceExtension, 'SSUR', DeviceObject, irp, Urb);
  506. if (NULL == irp)
  507. {
  508. return STATUS_INSUFFICIENT_RESOURCES;
  509. }
  510. // Set the Irp parameters
  511. //
  512. nextStack = IoGetNextIrpStackLocation(irp);
  513. nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  514. nextStack->Parameters.DeviceIoControl.IoControlCode =
  515. IOCTL_INTERNAL_USB_SUBMIT_URB;
  516. nextStack->Parameters.Others.Argument1 = Urb;
  517. // Set the completion routine, which will signal the event
  518. IoSetCompletionRoutine(irp,
  519. GenUSB_SyncCompletionRoutine,
  520. &localevent,
  521. TRUE, // InvokeOnSuccess
  522. TRUE, // InvokeOnError
  523. TRUE); // InvokeOnCancel
  524. // Pass the Irp & Urb down the stack
  525. status = IoCallDriver (deviceExtension->StackDeviceObject, irp);
  526. // If the request is pending, block until it completes
  527. if (status == STATUS_PENDING)
  528. {
  529. LARGE_INTEGER timeout;
  530. // Specify a timeout of 5 seconds to wait for this call to complete.
  531. //
  532. timeout.QuadPart = -10000 * 5000;
  533. status = KeWaitForSingleObject(&localevent,
  534. Executive,
  535. KernelMode,
  536. FALSE,
  537. &timeout);
  538. if (status == STATUS_TIMEOUT)
  539. {
  540. status = STATUS_IO_TIMEOUT;
  541. // Cancel the Irp we just sent.
  542. IoCancelIrp(irp);
  543. // And wait until the cancel completes
  544. KeWaitForSingleObject(&localevent,
  545. Executive,
  546. KernelMode,
  547. FALSE,
  548. NULL);
  549. }
  550. else
  551. {
  552. status = irp->IoStatus.Status;
  553. }
  554. }
  555. // Done with the Irp, now free it.
  556. IoFreeIrp(irp);
  557. LOGENTRY(deviceExtension, 'ssur', status, Urb, Urb->UrbHeader.Status);
  558. DBGPRINT(3, ("exit: GenUSB_SyncSendUsbRequest %08X\n", status));
  559. return status;
  560. }
  561. //******************************************************************************
  562. //
  563. // GenUSB_QueryStopRemoveDevice()
  564. //
  565. // This routine handles IRP_MJ_PNP, IRP_MN_QUERY_STOP_DEVICE and
  566. // IRP_MN_QUERY_REMOVE_DEVICE for the FDO.
  567. //
  568. // The PnP Manager sends this IRP at IRQL PASSIVE_LEVEL in the context of a
  569. // system thread.
  570. //
  571. // This IRP is handled first by the driver at the top of the device stack and
  572. // then by each lower driver in the attachment chain.
  573. //
  574. //******************************************************************************
  575. NTSTATUS
  576. GenUSB_QueryStopRemoveDevice (
  577. IN PDEVICE_OBJECT DeviceObject,
  578. IN PIRP Irp
  579. )
  580. {
  581. PDEVICE_EXTENSION deviceExtension;
  582. NTSTATUS status;
  583. PAGED_CODE();
  584. DBGPRINT(2, ("enter: GenUSB_QueryStopRemoveDevice\n"));
  585. DBGFBRK(DBGF_BRK_QUERYSTOPDEVICE);
  586. deviceExtension = DeviceObject->DeviceExtension;
  587. LOGENTRY(deviceExtension, 'QSRD', Irp, 0, 0);
  588. //
  589. // Notification that we are about to stop or be removed, but we don't care
  590. // Pass the IRP_MN_QUERY_STOP/REMOVE_DEVICE Irp down the stack.
  591. //
  592. IoSkipCurrentIrpStackLocation(Irp);
  593. status = IoCallDriver(deviceExtension->StackDeviceObject, Irp);
  594. DBGPRINT(2, ("exit: GenUSB_FdoQueryStopRemoveDevice %08X\n", status));
  595. LOGENTRY(deviceExtension, 'qsrd', Irp, 0, status);
  596. return status;
  597. }
  598. //******************************************************************************
  599. //
  600. // GenUSB_FdoCancelStopRemoveDevice()
  601. //
  602. // This routine handles IRP_MJ_PNP, IRP_MN_CANCEL_STOP_DEVICE and
  603. // IRP_MN_CANCEL_REMOVE_DEVICE for the FDO.
  604. //
  605. // The PnP Manager sends this IRP at IRQL PASSIVE_LEVEL in the context of a
  606. // system thread.
  607. //
  608. // This IRP must be handled first by the underlying bus driver for a device
  609. // and then by each higher driver in the device stack.
  610. //
  611. //******************************************************************************
  612. NTSTATUS
  613. GenUSB_CancelStopRemoveDevice (
  614. IN PDEVICE_OBJECT DeviceObject,
  615. IN PIRP Irp
  616. )
  617. {
  618. PDEVICE_EXTENSION deviceExtension;
  619. NTSTATUS status;
  620. PAGED_CODE();
  621. DBGPRINT(2, ("enter: GenUSB_FdoCancelStopRemoveDevice\n"));
  622. DBGFBRK(DBGF_BRK_CANCELSTOPDEVICE);
  623. deviceExtension = DeviceObject->DeviceExtension;
  624. LOGENTRY(deviceExtension, 'CSRD', DeviceObject, Irp, 0);
  625. // The documentation says to set the status before passing the Irp down
  626. Irp->IoStatus.Status = STATUS_SUCCESS;
  627. //
  628. // Notification that the attempt to stop or be removed, is cancelled
  629. // but we don't care
  630. // Pass the IRP_MN_CANCEL_STOP/REMOVE_DEVICE Irp down the stack.
  631. //
  632. IoSkipCurrentIrpStackLocation(Irp);
  633. status = IoCallDriver(deviceExtension->StackDeviceObject, Irp);
  634. DBGPRINT(2, ("exit: GenUSB_FdoQueryStopRemoveDevice %08X\n", status));
  635. LOGENTRY(deviceExtension, 'qsrd', Irp, 0, status);
  636. return status;
  637. }
  638. //******************************************************************************
  639. //
  640. // GenUSB_FdoStopDevice()
  641. //
  642. // This routine handles IRP_MJ_PNP, IRP_MN_STOP_DEVICE for the FDO
  643. //
  644. // The PnP Manager sends this IRP at IRQL PASSIVE_LEVEL in the context of a
  645. // system thread.
  646. //
  647. // The PnP Manager only sends this IRP if a prior IRP_MN_QUERY_STOP_DEVICE
  648. // completed successfully.
  649. //
  650. // This IRP is handled first by the driver at the top of the device stack and
  651. // then by each lower driver in the attachment chain.
  652. //
  653. // A driver must set Irp->IoStatus.Status to STATUS_SUCCESS. A driver must
  654. // not fail this IRP. If a driver cannot release the device's hardware
  655. // resources, it can fail a query-stop IRP, but once it succeeds the query-stop
  656. // request it must succeed the stop request.
  657. //
  658. //******************************************************************************
  659. NTSTATUS
  660. GenUSB_StopDevice (
  661. IN PDEVICE_OBJECT DeviceObject,
  662. IN PIRP Irp
  663. )
  664. {
  665. PDEVICE_EXTENSION deviceExtension;
  666. NTSTATUS status;
  667. PAGED_CODE();
  668. DBGPRINT(2, ("enter: GenUSB_FdoStopDevice\n"));
  669. DBGFBRK(DBGF_BRK_STOPDEVICE);
  670. deviceExtension = DeviceObject->DeviceExtension;
  671. LOGENTRY(deviceExtension, 'STOP', Irp, 0, 0);
  672. // Release the device resources allocated during IRP_MN_START_DEVICE
  673. // Stop the timeout timer
  674. IoStopTimer(DeviceObject);
  675. // The documentation says to set the status before passing the
  676. // Irp down the stack
  677. Irp->IoStatus.Status = STATUS_SUCCESS;
  678. // Pass the IRP_MN_STOP_DEVICE Irp down the stack.
  679. //
  680. IoSkipCurrentIrpStackLocation(Irp);
  681. status = IoCallDriver(deviceExtension->StackDeviceObject, Irp);
  682. DBGPRINT(2, ("exit: GenUSB_FdoStopDevice %08X\n", status));
  683. LOGENTRY(deviceExtension, 'stop', 0, 0, status);
  684. return status;
  685. }
  686. //******************************************************************************
  687. //
  688. // GenUSB_RemoveDevice()
  689. //
  690. // This routine handles IRP_MJ_PNP, IRP_MN_REMOVE_DEVICE for the FDO
  691. //
  692. // The PnP Manager sends this IRP at IRQL PASSIVE_LEVEL in the context of a
  693. // system thread.
  694. //
  695. // This IRP is handled first by the driver at the top of the device stack and
  696. // then by each lower driver in the attachment chain.
  697. //
  698. // A driver must set Irp->IoStatus.Status to STATUS_SUCCESS. Drivers must not
  699. // fail this IRP.
  700. //
  701. //******************************************************************************
  702. NTSTATUS
  703. GenUSB_RemoveDevice (
  704. IN PDEVICE_OBJECT DeviceObject,
  705. IN PIRP Irp
  706. )
  707. {
  708. PDEVICE_EXTENSION deviceExtension;
  709. NTSTATUS status;
  710. PAGED_CODE();
  711. DBGPRINT(2, ("enter: GenUSB_FdoRemoveDevice\n"));
  712. DBGFBRK(DBGF_BRK_REMOVEDEVICE);
  713. deviceExtension = DeviceObject->DeviceExtension;
  714. IoReleaseRemoveLockAndWait (&deviceExtension->RemoveLock, Irp);
  715. // Free everything that was allocated during IRP_MN_START_DEVICE
  716. // The configuration should have been desected in the close,
  717. // which we should have received even in a surprise remove case.
  718. //
  719. // GenUSB_DeselectConfiguration (deviceExtension, FALSE);
  720. //
  721. LOGUNINIT(deviceExtension);
  722. ASSERT (NULL == deviceExtension->ConfigurationHandle);
  723. if (deviceExtension->DeviceDescriptor != NULL)
  724. {
  725. ExFreePool(deviceExtension->DeviceDescriptor);
  726. }
  727. if (deviceExtension->ConfigurationDescriptor != NULL)
  728. {
  729. ExFreePool(deviceExtension->ConfigurationDescriptor);
  730. }
  731. if (deviceExtension->SerialNumber != NULL)
  732. {
  733. ExFreePool(deviceExtension->SerialNumber);
  734. }
  735. // The documentation says to set the status before passing the Irp down
  736. Irp->IoStatus.Status = STATUS_SUCCESS;
  737. // Pass the IRP_MN_REMOVE_DEVICE Irp down the stack.
  738. IoSkipCurrentIrpStackLocation(Irp);
  739. status = IoCallDriver(deviceExtension->StackDeviceObject, Irp);
  740. LOGENTRY(deviceExtension, 'rem3', DeviceObject, 0, 0);
  741. // Free everything that was allocated during AddDevice
  742. IoDetachDevice(deviceExtension->StackDeviceObject);
  743. IoDeleteDevice(DeviceObject);
  744. DBGPRINT(2, ("exit: GenUSB_FdoRemoveDevice %08X\n", status));
  745. return status;
  746. }
  747. NTSTATUS
  748. GenUSB_SetDIRegValues (
  749. IN PDEVICE_EXTENSION DeviceExtension
  750. )
  751. {
  752. NTSTATUS status;
  753. HANDLE key;
  754. UNICODE_STRING name;
  755. ULONG value = 0xf00d;
  756. RtlInitUnicodeString (&name, L"PlaceHolder");
  757. status = IoOpenDeviceInterfaceRegistryKey (
  758. &DeviceExtension->DevInterfaceLinkName,
  759. STANDARD_RIGHTS_ALL,
  760. &key);
  761. if (!NT_SUCCESS (status))
  762. {
  763. ASSERT (NT_SUCCESS (status));
  764. return status;
  765. }
  766. status = ZwSetValueKey (
  767. key,
  768. &name,
  769. 0,
  770. REG_DWORD,
  771. &value,
  772. sizeof (value));
  773. if (!NT_SUCCESS (status))
  774. {
  775. ASSERT (NT_SUCCESS (status));
  776. return status;
  777. }
  778. //
  779. // Write in the class code and subcodes.
  780. //
  781. ASSERT (DeviceExtension->DeviceDescriptor);
  782. RtlInitUnicodeString (&name, GENUSB_REG_STRING_DEVICE_CLASS);
  783. value = DeviceExtension->DeviceDescriptor->bDeviceClass;
  784. status = ZwSetValueKey (
  785. key,
  786. &name,
  787. 0,
  788. REG_DWORD,
  789. &value,
  790. sizeof (value));
  791. ASSERT (NT_SUCCESS (status));
  792. RtlInitUnicodeString (&name, GENUSB_REG_STRING_DEVICE_SUB_CLASS);
  793. value = DeviceExtension->DeviceDescriptor->bDeviceSubClass;
  794. status = ZwSetValueKey (
  795. key,
  796. &name,
  797. 0,
  798. REG_DWORD,
  799. &value,
  800. sizeof (value));
  801. ASSERT (NT_SUCCESS (status));
  802. RtlInitUnicodeString (&name, GENUSB_REG_STRING_DEVICE_PROTOCOL);
  803. value = DeviceExtension->DeviceDescriptor->bDeviceProtocol;
  804. status = ZwSetValueKey (
  805. key,
  806. &name,
  807. 0,
  808. REG_DWORD,
  809. &value,
  810. sizeof (value));
  811. ASSERT (NT_SUCCESS (status));
  812. RtlInitUnicodeString (&name, GENUSB_REG_STRING_VID);
  813. value = DeviceExtension->DeviceDescriptor->idVendor;
  814. status = ZwSetValueKey (
  815. key,
  816. &name,
  817. 0,
  818. REG_DWORD,
  819. &value,
  820. sizeof (value));
  821. ASSERT (NT_SUCCESS (status));
  822. RtlInitUnicodeString (&name, GENUSB_REG_STRING_PID);
  823. value = DeviceExtension->DeviceDescriptor->idProduct;
  824. status = ZwSetValueKey (
  825. key,
  826. &name,
  827. 0,
  828. REG_DWORD,
  829. &value,
  830. sizeof (value));
  831. ASSERT (NT_SUCCESS (status));
  832. RtlInitUnicodeString (&name, GENUSB_REG_STRING_REV);
  833. value = DeviceExtension->DeviceDescriptor->bcdDevice;
  834. status = ZwSetValueKey (
  835. key,
  836. &name,
  837. 0,
  838. REG_DWORD,
  839. &value,
  840. sizeof (value));
  841. ASSERT (NT_SUCCESS (status));
  842. ZwClose (key);
  843. return status;
  844. }
  845. //******************************************************************************
  846. //
  847. // GenUSB_Power()
  848. //
  849. // Dispatch routine which handles IRP_MJ_POWER
  850. //
  851. //******************************************************************************
  852. NTSTATUS
  853. GenUSB_Power (
  854. IN PDEVICE_OBJECT DeviceObject,
  855. IN PIRP Irp
  856. )
  857. {
  858. PDEVICE_EXTENSION deviceExtension;
  859. PIO_STACK_LOCATION irpStack;
  860. NTSTATUS status;
  861. PAGED_CODE();
  862. deviceExtension = DeviceObject->DeviceExtension;
  863. irpStack = IoGetCurrentIrpStackLocation(Irp);
  864. DBGPRINT(2, ("enter: GenUSB_Power %08X %08X %s\n",
  865. DeviceObject,
  866. Irp,
  867. PowerMinorFunctionString(irpStack->MinorFunction)));
  868. LOGENTRY(deviceExtension, 'PWR_',
  869. Irp,
  870. deviceExtension->DevicePowerState,
  871. irpStack->MinorFunction);
  872. if (irpStack->MinorFunction == IRP_MN_SET_POWER)
  873. {
  874. LOGENTRY(deviceExtension, 'PWRs',
  875. irpStack->Parameters.Power.Type,
  876. irpStack->Parameters.Power.State.SystemState,
  877. irpStack->Parameters.Power.ShutdownType);
  878. DBGPRINT(2, ("%s IRP_MN_SET_POWER %s\n",
  879. (irpStack->Parameters.Power.Type == SystemPowerState) ?
  880. "System" : "Device",
  881. (irpStack->Parameters.Power.Type == SystemPowerState) ?
  882. PowerSystemStateString(irpStack->Parameters.Power.State.SystemState) :
  883. PowerDeviceStateString(irpStack->Parameters.Power.State.DeviceState)));
  884. }
  885. if (irpStack->MinorFunction == IRP_MN_SET_POWER)
  886. {
  887. //
  888. // Handle powering the FDO down and up...
  889. //
  890. status = GenUSB_SetPower(deviceExtension, Irp);
  891. }
  892. else
  893. {
  894. // No special processing for IRP_MN_QUERY_POWER, IRP_MN_WAIT_WAKE,
  895. // or IRP_MN_POWER_SEQUENCE at this time. Just pass the request
  896. // down to the next lower driver now.
  897. //
  898. PoStartNextPowerIrp(Irp);
  899. IoSkipCurrentIrpStackLocation(Irp);
  900. status = PoCallDriver(deviceExtension->StackDeviceObject, Irp);
  901. }
  902. DBGPRINT(2, ("exit: GenUSB_Power %08X\n", status));
  903. LOGENTRY(deviceExtension, 'powr', status, 0, 0);
  904. return status;
  905. }
  906. //******************************************************************************
  907. //
  908. // GenUSB_FdoSetPower()
  909. //
  910. // Dispatch routine which handles IRP_MJ_POWER, IRP_MN_SET_POWER for the FDO
  911. //
  912. //******************************************************************************
  913. NTSTATUS
  914. GenUSB_SetPower (
  915. PDEVICE_EXTENSION DeviceExtension,
  916. IN PIRP Irp
  917. )
  918. {
  919. PIO_STACK_LOCATION irpStack;
  920. POWER_STATE_TYPE powerType;
  921. POWER_STATE powerState;
  922. POWER_STATE oldState;
  923. POWER_STATE newState;
  924. NTSTATUS status;
  925. PAGED_CODE();
  926. //
  927. // Get our Irp parameters
  928. //
  929. irpStack = IoGetCurrentIrpStackLocation(Irp);
  930. powerType = irpStack->Parameters.Power.Type;
  931. powerState = irpStack->Parameters.Power.State;
  932. LOGENTRY(DeviceExtension, 'FDSP', Irp, powerType, powerState.SystemState);
  933. switch (powerType)
  934. {
  935. case SystemPowerState:
  936. // Remember the current system state.
  937. //
  938. DeviceExtension->SystemPowerState = powerState.SystemState;
  939. // Map the new system state to a new device state
  940. //
  941. if (powerState.SystemState != PowerSystemWorking)
  942. {
  943. newState.DeviceState = PowerDeviceD3;
  944. }
  945. else
  946. {
  947. newState.DeviceState = PowerDeviceD0;
  948. }
  949. // If the new device state is different than the current device
  950. // state, request a device state power Irp.
  951. //
  952. if (DeviceExtension->DevicePowerState != newState.DeviceState)
  953. {
  954. DBGPRINT(2, ("Requesting power Irp %08X %08X from %s to %s\n",
  955. DeviceExtension, Irp,
  956. PowerDeviceStateString(DeviceExtension->DevicePowerState),
  957. PowerDeviceStateString(newState.DeviceState)));
  958. ASSERT(DeviceExtension->CurrentPowerIrp == NULL);
  959. DeviceExtension->CurrentPowerIrp = Irp;
  960. status = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject,
  961. IRP_MN_SET_POWER,
  962. newState,
  963. GenUSB_SetPowerCompletion,
  964. DeviceExtension,
  965. NULL);
  966. }
  967. break;
  968. case DevicePowerState:
  969. DBGPRINT(2, ("Received power Irp %08X %08X from %s to %s\n",
  970. DeviceExtension, Irp,
  971. PowerDeviceStateString(DeviceExtension->DevicePowerState),
  972. PowerDeviceStateString(powerState.DeviceState)));
  973. //
  974. // Update the current device state.
  975. //
  976. oldState.DeviceState = DeviceExtension->DevicePowerState;
  977. if (oldState.DeviceState == PowerDeviceD0 &&
  978. powerState.DeviceState > PowerDeviceD0)
  979. {
  980. //
  981. // DeviceState is checked on devicecontrol, read and write, but is
  982. // only set here and in the completion routine
  983. // GenUSB_SetPowerD0Completion
  984. //
  985. DeviceExtension->DevicePowerState = powerState.DeviceState;
  986. //
  987. // After talking extensively with JD, he tells me that I do not need
  988. // to queue requests for power downs or query stop. If that is the
  989. // case then even if the device power state isn't PowerDeviceD0 we
  990. // can still allow trasfers. This, of course, is a property of the
  991. // brand new port driver that went into XP.
  992. //
  993. // Also we shouldn't need to queue our current request.
  994. // Instead we will just let the transfers fail.
  995. //
  996. // The app will see the failures returned with the appropriate
  997. // status codes so that they can do the right thing.
  998. //
  999. PoStartNextPowerIrp (Irp);
  1000. IoSkipCurrentIrpStackLocation (Irp);
  1001. status = PoCallDriver(DeviceExtension->StackDeviceObject, Irp);
  1002. }
  1003. else if (oldState.DeviceState > PowerDeviceD0 &&
  1004. powerState.DeviceState == PowerDeviceD0)
  1005. {
  1006. //
  1007. // Since we didn't have to do anything for powering down
  1008. // We likewise need to do nothing for powering back up.
  1009. //
  1010. IoCopyCurrentIrpStackLocationToNext (Irp);
  1011. IoSetCompletionRoutine (Irp,
  1012. GenUSB_SetPowerD0Completion,
  1013. NULL, // no context
  1014. TRUE,
  1015. TRUE,
  1016. TRUE);
  1017. status = PoCallDriver(DeviceExtension->StackDeviceObject, Irp);
  1018. }
  1019. }
  1020. DBGPRINT(2, ("exit: GenUSB_FdoSetPower %08X\n", status));
  1021. LOGENTRY(DeviceExtension, 'fdsp', status, 0, 0);
  1022. return status;
  1023. }
  1024. //******************************************************************************
  1025. //
  1026. // GenUSB_SetPowerCompletion()
  1027. //
  1028. // Completion routine for PoRequestPowerIrp() in GenUSB_FdoSetPower.
  1029. //
  1030. // The purpose of this routine is to block passing down the SystemPowerState
  1031. // Irp until the requested DevicePowerState Irp completes.
  1032. //
  1033. //******************************************************************************
  1034. VOID
  1035. GenUSB_SetPowerCompletion(
  1036. IN PDEVICE_OBJECT PdoDeviceObject,
  1037. IN UCHAR MinorFunction,
  1038. IN POWER_STATE PowerState,
  1039. IN PVOID Context,
  1040. IN PIO_STATUS_BLOCK IoStatus
  1041. )
  1042. {
  1043. PDEVICE_EXTENSION deviceExtension;
  1044. PIRP irp;
  1045. deviceExtension = (PDEVICE_EXTENSION) Context;
  1046. ASSERT(deviceExtension->CurrentPowerIrp != NULL);
  1047. irp = deviceExtension->CurrentPowerIrp;
  1048. deviceExtension->CurrentPowerIrp = NULL;
  1049. #if DBG
  1050. {
  1051. PIO_STACK_LOCATION irpStack;
  1052. SYSTEM_POWER_STATE systemState;
  1053. irpStack = IoGetCurrentIrpStackLocation(irp);
  1054. systemState = irpStack->Parameters.Power.State.SystemState;
  1055. DBGPRINT(2, ("GenUSB_SetPowerCompletion %08X %08X %s %08X\n",
  1056. deviceExtension, irp,
  1057. PowerSystemStateString(systemState),
  1058. IoStatus->Status));
  1059. LOGENTRY(deviceExtension, 'fspc', 0, systemState, IoStatus->Status);
  1060. }
  1061. #endif
  1062. // The requested DevicePowerState Irp has completed.
  1063. // Now pass down the SystemPowerState Irp which requested the
  1064. // DevicePowerState Irp.
  1065. PoStartNextPowerIrp(irp);
  1066. IoCopyCurrentIrpStackLocationToNext(irp);
  1067. // Mark the Irp pending since GenUSB_FdoSetPower() would have
  1068. // originally returned STATUS_PENDING after calling PoRequestPowerIrp().
  1069. IoMarkIrpPending(irp);
  1070. PoCallDriver(deviceExtension->StackDeviceObject, irp);
  1071. }
  1072. //******************************************************************************
  1073. //
  1074. // GenUSB_SetPowerD0Completion()
  1075. //
  1076. // Completion routine used by GenUSB_FdoSetPower when passing down a
  1077. // IRP_MN_SET_POWER DevicePowerState PowerDeviceD0 Irp for the FDO.
  1078. //
  1079. // The purpose of this routine is to delay unblocking the device queue
  1080. // until after the DevicePowerState PowerDeviceD0 Irp completes.
  1081. //
  1082. //******************************************************************************
  1083. NTSTATUS
  1084. GenUSB_SetPowerD0Completion (
  1085. IN PDEVICE_OBJECT DeviceObject,
  1086. IN PIRP Irp,
  1087. IN PVOID NotUsed
  1088. )
  1089. {
  1090. PDEVICE_EXTENSION deviceExtension;
  1091. PIO_STACK_LOCATION irpStack;
  1092. DEVICE_POWER_STATE deviceState;
  1093. KIRQL irql;
  1094. NTSTATUS status;
  1095. deviceExtension = DeviceObject->DeviceExtension;
  1096. irpStack = IoGetCurrentIrpStackLocation(Irp);
  1097. ASSERT(PowerDeviceD0 == irpStack->Parameters.Power.State.DeviceState);
  1098. ASSERT(deviceExtension->DevicePowerState != PowerDeviceD0);
  1099. deviceState=deviceExtension->DevicePowerState;
  1100. //
  1101. // DeviceState is checked on devicecontrol, read, and write, but is only
  1102. // set here, and in the power down code of GenUSB_SetPower.
  1103. //
  1104. deviceExtension->DevicePowerState = PowerDeviceD0;
  1105. status = Irp->IoStatus.Status;
  1106. DBGPRINT(2, ("GenUSB_FdoSetPowerD0Completion %08X %08X %s %08X\n",
  1107. DeviceObject, Irp,
  1108. PowerDeviceStateString(deviceState),
  1109. status));
  1110. LOGENTRY(deviceExtension, 'fs0c', DeviceObject, deviceState, status);
  1111. // Powering up. Unblock the device queue which was left blocked
  1112. // after GenUSB_StartIo() passed down the power down Irp.
  1113. PoStartNextPowerIrp(Irp);
  1114. return status;
  1115. }
  1116. //******************************************************************************
  1117. //
  1118. // GenUSB_SystemControl()
  1119. //
  1120. // Dispatch routine which handles IRP_MJ_SYSTEM_CONTROL
  1121. //
  1122. //******************************************************************************
  1123. NTSTATUS
  1124. GenUSB_SystemControl (
  1125. IN PDEVICE_OBJECT DeviceObject,
  1126. IN PIRP Irp
  1127. )
  1128. {
  1129. PDEVICE_EXTENSION deviceExtension;
  1130. PIO_STACK_LOCATION irpStack;
  1131. NTSTATUS ntStatus;
  1132. PAGED_CODE();
  1133. deviceExtension = DeviceObject->DeviceExtension;
  1134. irpStack = IoGetCurrentIrpStackLocation(Irp);
  1135. DBGPRINT(2, ("enter: GenUSB_SystemControl %2X\n", irpStack->MinorFunction));
  1136. LOGENTRY(deviceExtension, 'SYSC', DeviceObject, Irp, irpStack->MinorFunction);
  1137. switch (irpStack->MinorFunction)
  1138. {
  1139. //
  1140. // XXXXX Need to handle any of these?
  1141. //
  1142. default:
  1143. //
  1144. // Pass the request down to the next lower driver
  1145. //
  1146. IoSkipCurrentIrpStackLocation(Irp);
  1147. ntStatus = IoCallDriver(deviceExtension->StackDeviceObject, Irp);
  1148. break;
  1149. }
  1150. DBGPRINT(2, ("exit: GenUSB_SystemControl %08X\n", ntStatus));
  1151. LOGENTRY(deviceExtension, 'sysc', ntStatus, 0, 0);
  1152. return ntStatus;
  1153. }