ReactOS  0.4.13-dev-100-gc8611ae
pdo.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Universal Serial Bus Hub Driver
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: drivers/usb/usbhub/pdo.c
5  * PURPOSE: Handle PDO
6  * PROGRAMMERS:
7  * HervĂ© Poussineau (hpoussin@reactos.org)
8  * Michael Martin (michael.martin@reactos.org)
9  * Johannes Anderwald (johannes.anderwald@reactos.org)
10  */
11 
12 #include "usbhub.h"
13 
14 #include <wdmguid.h>
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
20 
21 DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE,
22  0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
23 
25 NTAPI
28  PIRP Irp,
29  PVOID Context)
30 {
31  PIRP OriginalIrp;
32  DPRINT("Entered Urb Completion\n");
33 
34  //
35  // Get the original Irp
36  //
37  OriginalIrp = (PIRP)Context;
38 
39  //
40  // Update it to match what was returned for the IRP that was passed to RootHub
41  //
42  OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
43  OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;
44  DPRINT("Status %x, Information %x\n", Irp->IoStatus.Status, Irp->IoStatus.Information);
45 
46  //
47  // Complete the original Irp
48  //
49  IoCompleteRequest(OriginalIrp, IO_NO_INCREMENT);
50 
51  //
52  // Free our allocated IRP
53  //
54  IoFreeIrp(Irp);
55 
56  //
57  // Return this status so the IO Manager doesnt mess with the Irp
58  //
60 }
61 
64  PDEVICE_OBJECT RootHubDeviceObject,
66  PIRP Irp,
67  OUT PVOID OutParameter1,
68  OUT PVOID OutParameter2)
69 {
70  PIRP ForwardIrp;
72  PIO_STACK_LOCATION ForwardStack, CurrentStack;
73  PURB Urb;
74 
75  //
76  // Get the current stack location for the Irp
77  //
78  CurrentStack = IoGetCurrentIrpStackLocation(Irp);
79  ASSERT(CurrentStack);
80 
81  //
82  // Pull the Urb from that stack, it will be reused in the Irp sent to RootHub
83  //
84  Urb = (PURB)CurrentStack->Parameters.Others.Argument1;
85  ASSERT(Urb);
86 
87  //
88  // Create the Irp to forward to RootHub
89  //
91  RootHubDeviceObject,
92  NULL,
93  0,
94  0,
95  &IoStatus);
96  if (!ForwardIrp)
97  {
98  DPRINT1("Failed to allocate IRP\n");
100  }
101 
102  //
103  // Get the new Irps next stack
104  //
105  ForwardStack = IoGetNextIrpStackLocation(ForwardIrp);
106 
107  //
108  // Copy the stack for the current irp into the next stack of new irp
109  //
110  RtlCopyMemory(ForwardStack, CurrentStack, sizeof(IO_STACK_LOCATION));
111 
113  IoStatus.Information = 0;
114 
115  //
116  // Mark the Irp from upper driver as pending
117  //
119 
120  //
121  // Now set the completion routine for the new Irp.
122  //
123  IoSetCompletionRoutine(ForwardIrp,
125  Irp,
126  TRUE,
127  TRUE,
128  TRUE);
129 
130  IoCallDriver(RootHubDeviceObject, ForwardIrp);
131 
132  //
133  // Always return pending as the completion routine will take care of it
134  //
135  return STATUS_PENDING;
136 }
137 
138 BOOLEAN
141 {
142  ULONG Index;
143  PHUB_DEVICE_EXTENSION HubDeviceExtension;
144  PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
145 
146 
148  ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
149 
150  // This can happen when parent device was surprise removed.
151  if (ChildDeviceExtension->ParentDeviceObject == NULL)
152  return FALSE;
153 
154  HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
155 
156  KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
157  for(Index = 0; Index < USB_MAXCHILDREN; Index++)
158  {
159  if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
160  {
161  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
162 
163  /* PDO exists */
164  return TRUE;
165  }
166  }
167  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
168 
169  /* invalid pdo */
170  return FALSE;
171 }
172 
173 
174 NTSTATUS
177  IN PIRP Irp)
178 {
180  PIO_STACK_LOCATION Stack;
182  PHUB_DEVICE_EXTENSION HubDeviceExtension;
183  PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
184  PDEVICE_OBJECT RootHubDeviceObject;
185  PURB Urb;
186 
187  //DPRINT1("UsbhubInternalDeviceControlPdo(%x) called\n", DeviceObject);
188 
189  //
190  // get current stack location
191  //
193  ASSERT(Stack);
194 
195  //
196  // Set default status
197  //
198  Status = Irp->IoStatus.Status;
199 
201  ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
202 
203  Status = IoAcquireRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
204  if (!NT_SUCCESS(Status))
205  {
206  Irp->IoStatus.Status = Status;
208  return Status;
209  }
210 
211  if (ChildDeviceExtension->Common.PnPState == SurpriseRemovePending ||
212  ChildDeviceExtension->Common.PnPState == RemovePending ||
213  ChildDeviceExtension->ParentDeviceObject == NULL)
214  {
215  // Parent or child device was surprise removed.
216  DPRINT1("[USBHUB] Request for removed device object %p\n", DeviceObject);
217  Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
218  Irp->IoStatus.Information = 0;
220  IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
222  }
223 
224  HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
225  RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
226 
227  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
228  {
230  {
231  DPRINT("IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
232  if (Irp->AssociatedIrp.SystemBuffer == NULL
233  || Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
234  {
236  }
237  else
238  {
239  PVOID* pHubPointer;
240 
241  pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
242  // FIXME
243  *pHubPointer = NULL;
244  Information = sizeof(PVOID);
246  }
247  break;
248  }
250  {
251  //DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB\n");
252 
253  //
254  // Get the Urb
255  //
256  Urb = (PURB)Stack->Parameters.Others.Argument1;
257  ASSERT(Urb);
258 
259  //
260  // Set the real device handle
261  //
262  //DPRINT("UsbdDeviceHandle %x, ChildDeviceHandle %x\n", Urb->UrbHeader.UsbdDeviceHandle, ChildDeviceExtension->UsbDeviceHandle);
263 
264  Urb->UrbHeader.UsbdDeviceHandle = ChildDeviceExtension->UsbDeviceHandle;
265 
266  //
267  // Submit to RootHub
268  //
269  switch (Urb->UrbHeader.Function)
270  {
271  //
272  // Debugging only
273  //
275  DPRINT("URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n");
276  break;
278  DPRINT("URB_FUNCTION_CLASS_DEVICE\n");
279  break;
281  DPRINT("URB_FUNCTION_GET_STATUS_FROM_DEVICE\n");
282  break;
284  DPRINT("URB_FUNCTION_SELECT_CONFIGURATION\n");
285  break;
287  DPRINT("URB_FUNCTION_SELECT_INTERFACE\n");
288  break;
290  DPRINT("URB_FUNCTION_CLASS_OTHER\n");
291  break;
293  {
294  /*
295  DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n");
296  DPRINT1("PipeHandle %x\n", Urb->UrbBulkOrInterruptTransfer.PipeHandle);
297  DPRINT1("TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
298  DPRINT1("Buffer %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
299  DPRINT1("BufferMDL %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
300  DPRINT1("Length %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
301  DPRINT1("UrbLink %x\n", Urb->UrbBulkOrInterruptTransfer.UrbLink);
302  DPRINT1("hca %x\n", Urb->UrbBulkOrInterruptTransfer.hca);
303  if (Urb->UrbBulkOrInterruptTransfer.TransferFlags == USBD_SHORT_TRANSFER_OK)
304  {
305  }
306  */
307  break;
308 
309  }
311  DPRINT("URB_FUNCTION_CLASS_INTERFACE\n");
312  break;
314  DPRINT("URB_FUNCTION_VENDOR_DEVICE\n");
315  break;
316  default:
317  DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
318  break;
319  }
320  Urb->UrbHeader.UsbdDeviceHandle = ChildDeviceExtension->UsbDeviceHandle;
321  //DPRINT1("Stack->CompletionRoutine %x\n", Stack->CompletionRoutine);
322  //
323  // Send the request to RootHub
324  //
325  Status = ForwardUrbToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL);
326  IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
327  return Status;
328  }
329  //
330  // FIXME: Can these be sent to RootHub?
331  //
333  DPRINT1("IOCTL_INTERNAL_USB_RESET_PORT\n");
334  break;
336  {
338  ULONG PortId;
339  PUCHAR PortStatusBits;
340 
341  PortStatusBits = (PUCHAR)Stack->Parameters.Others.Argument1;
342  //
343  // USBD_PORT_ENABLED (bit 0) or USBD_PORT_CONNECTED (bit 1)
344  //
345  DPRINT1("IOCTL_INTERNAL_USB_GET_PORT_STATUS\n");
346  DPRINT("Arg1 %x\n", *PortStatusBits);
347  *PortStatusBits = 0;
348  if (Stack->Parameters.Others.Argument1)
349  {
350  for (PortId = 1; PortId <= HubDeviceExtension->UsbExtHubInfo.NumberOfPorts; PortId++)
351  {
352  Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
353  if (NT_SUCCESS(Status))
354  {
355  DPRINT("Connect %x\n", ((PortStatus.Status & USB_PORT_STATUS_CONNECT) << 1) << ((PortId - 1) * 2));
356  DPRINT("Enable %x\n", ((PortStatus.Status & USB_PORT_STATUS_ENABLE) >> 1) << ((PortId - 1) * 2));
357  *PortStatusBits +=
358  (((PortStatus.Status & USB_PORT_STATUS_CONNECT) << 1) << ((PortId - 1) * 2)) +
359  (((PortStatus.Status & USB_PORT_STATUS_ENABLE) >> 1) << ((PortId - 1) * 2));
360 
361  }
362  }
363  }
364 
365  DPRINT1("Arg1 %x\n", *PortStatusBits);
367  break;
368  }
370  DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
371  break;
373  DPRINT1("IOCTL_INTERNAL_USB_CYCLE_PORT\n");
374  break;
375  case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
376  {
377  DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
378  if (Stack->Parameters.Others.Argument1)
379  {
380  // store device handle
381  *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)ChildDeviceExtension->UsbDeviceHandle;
383  }
384  else
385  {
386  // invalid parameter
388  }
389  break;
390  }
392  {
393  if (Stack->Parameters.Others.Argument1)
394  {
395  // inform caller that it is a real usb hub
396  *(PVOID *)Stack->Parameters.Others.Argument1 = NULL;
397  }
398 
399  if (Stack->Parameters.Others.Argument2)
400  {
401  // output device object
402  *(PVOID *)Stack->Parameters.Others.Argument2 = DeviceObject;
403  }
404 
405  // done
407  break;
408  }
409  default:
410  {
411  DPRINT1("Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
412  Information = Irp->IoStatus.Information;
413  Status = Irp->IoStatus.Status;
414  }
415  }
416 
417  if (Status != STATUS_PENDING)
418  {
419  Irp->IoStatus.Information = Information;
420  Irp->IoStatus.Status = Status;
422  }
423  IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
424  return Status;
425 }
426 
427 NTSTATUS
430  IN PIRP Irp)
431 {
432  PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
433  //NTSTATUS Status;
434  DPRINT("USBHUB_PdoStartDevice %x\n", DeviceObject);
436 
437  //
438  // This should be a PDO
439  //
440  ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
441 
442  //
443  // register device interface
444  //
445  IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_DEVICE, NULL, &ChildDeviceExtension->SymbolicLinkName);
446  IoSetDeviceInterfaceState(&ChildDeviceExtension->SymbolicLinkName, TRUE);
447 
448  SET_NEW_PNP_STATE(ChildDeviceExtension->Common, Started);
449 
451  return STATUS_SUCCESS;
452 }
453 
454 NTSTATUS
457  IN PIRP Irp,
459 {
460  PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
461  ULONG IdType;
463  PWCHAR ReturnString = NULL;
465 
468 
469  switch (IdType)
470  {
471  case BusQueryDeviceID:
472  {
473  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
474  SourceString = &ChildDeviceExtension->usDeviceId;
475  break;
476  }
477  case BusQueryHardwareIDs:
478  {
479  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
480  SourceString = &ChildDeviceExtension->usHardwareIds;
481  break;
482  }
484  {
485  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
486  SourceString = &ChildDeviceExtension->usCompatibleIds;
487  break;
488  }
489  case BusQueryInstanceID:
490  {
491  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
492  SourceString = &ChildDeviceExtension->usInstanceId;
493  break;
494  }
495  default:
496  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
497  return STATUS_NOT_SUPPORTED;
498  }
499 
500  if (SourceString)
501  {
502  //
503  // allocate buffer
504  //
506  if (!ReturnString)
507  {
508  //
509  // no memory
510  //
512  }
513 
514  //
515  // copy buffer
516  //
518  }
519 
520  *Information = (ULONG_PTR)ReturnString;
521 
522  return Status;
523 }
524 
525 NTSTATUS
528  IN PIRP Irp,
530 {
531  PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
532  DEVICE_TEXT_TYPE DeviceTextType;
534  PWCHAR ReturnString = NULL;
536 
537  DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
539 
540  //
541  // FIXME: LocaleId
542  //
543 
544  switch (DeviceTextType)
545  {
548  {
549  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
550 
551  //
552  // does the device provide a text description
553  //
554  if (ChildDeviceExtension->usTextDescription.Buffer && ChildDeviceExtension->usTextDescription.Length)
555  {
556  //
557  // use device text
558  //
559  SourceString = &ChildDeviceExtension->usTextDescription;
560  }
561  break;
562  }
563  default:
564  {
565  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
567  break;
568  }
569  }
570 
571  if (SourceString)
572  {
575  DPRINT1("%S\n", ReturnString);
576  *Information = (ULONG_PTR)ReturnString;
577  }
578 
579  return Status;
580 }
581 
582 NTSTATUS
585  IN PIRP Irp)
586 {
589  PIO_STACK_LOCATION Stack;
591  PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
592  PDEVICE_RELATIONS DeviceRelation;
593 
596  MinorFunction = Stack->MinorFunction;
597 
598  Status = IoAcquireRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
599  if (!NT_SUCCESS(Status))
600  {
601  Irp->IoStatus.Status = Status;
603  return Status;
604  }
605 
606  switch (MinorFunction)
607  {
608  case IRP_MN_START_DEVICE:
609  {
610  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
612  break;
613  }
615  {
617  ULONG i;
618  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
619 
620  DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
621  // FIXME: capabilities can change with connected device
622  DeviceCapabilities->LockSupported = FALSE;
623  DeviceCapabilities->EjectSupported = FALSE;
624  DeviceCapabilities->Removable = TRUE;
625  DeviceCapabilities->DockDevice = FALSE;
626  DeviceCapabilities->UniqueID = FALSE;
627  DeviceCapabilities->SilentInstall = FALSE;
628  DeviceCapabilities->RawDeviceOK = FALSE;
629  DeviceCapabilities->SurpriseRemovalOK = FALSE;
630  DeviceCapabilities->HardwareDisabled = FALSE;
631  //DeviceCapabilities->NoDisplayInUI = FALSE;
632  DeviceCapabilities->Address = UsbChildExtension->PortNumber;
633  DeviceCapabilities->UINumber = 0;
634  DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
635  for (i = 1; i < PowerSystemMaximum; i++)
636  DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
637  //DeviceCapabilities->DeviceWake = PowerDeviceUndefined;
638  DeviceCapabilities->D1Latency = 0;
639  DeviceCapabilities->D2Latency = 0;
640  DeviceCapabilities->D3Latency = 0;
642  break;
643  }
645  {
646  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
647 
648  Information = Irp->IoStatus.Information;
649  Status = Irp->IoStatus.Status;
650  break;
651  }
653  {
654  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
655 
656  Information = Irp->IoStatus.Information;
657  Status = Irp->IoStatus.Status;
658  break;
659  }
661  {
662  DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
664  break;
665  }
666  case IRP_MN_QUERY_ID:
667  {
668  DPRINT("IRP_MN_QUERY_ID\n");
670  break;
671  }
673  {
674  PPNP_BUS_INFORMATION BusInfo;
675  DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
677  RtlCopyMemory(&BusInfo->BusTypeGuid,
678  &GUID_BUS_TYPE_USB,
679  sizeof(BusInfo->BusTypeGuid));
680  BusInfo->LegacyBusType = PNPBus;
681  // FIXME
682  BusInfo->BusNumber = 0;
683  Information = (ULONG_PTR)BusInfo;
685  break;
686  }
688  {
689  PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
690  PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
691 
692  DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
693 
694  ASSERT((UsbChildExtension->Common.PnPState == RemovePending) ||
695  (UsbChildExtension->Common.PnPState == SurpriseRemovePending));
696 
697  SET_NEW_PNP_STATE(UsbChildExtension->Common, NotStarted);
698 
699  if (!IsValidPDO(DeviceObject))
700  {
701  // Parent or child device was surprise removed, freeing resources allocated for child device.
702  SET_NEW_PNP_STATE(UsbChildExtension->Common, Deleted);
703 
704  IoReleaseRemoveLockAndWait(&UsbChildExtension->Common.RemoveLock, Irp);
705 
706  // Remove the usb device
707  if (UsbChildExtension->UsbDeviceHandle)
708  {
709  Status = HubInterface->RemoveUsbDevice(HubInterface->BusContext, UsbChildExtension->UsbDeviceHandle, 0);
711  }
712  // Free full configuration descriptor
713  if (UsbChildExtension->FullConfigDesc)
714  ExFreePool(UsbChildExtension->FullConfigDesc);
715 
716  // Free ID buffers
717  if (UsbChildExtension->usCompatibleIds.Buffer)
718  ExFreePool(UsbChildExtension->usCompatibleIds.Buffer);
719 
720  if (UsbChildExtension->usDeviceId.Buffer)
721  ExFreePool(UsbChildExtension->usDeviceId.Buffer);
722 
723  if (UsbChildExtension->usHardwareIds.Buffer)
724  ExFreePool(UsbChildExtension->usHardwareIds.Buffer);
725 
726  if (UsbChildExtension->usInstanceId.Buffer)
727  ExFreePool(UsbChildExtension->usInstanceId.Buffer);
728 
729  DPRINT("Deleting child PDO\n");
731  }
732  else
733  {
734  IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
735  }
736 
737  // If device is physically presented, we leave its PDO undeleted.
738 
739  /* Complete the IRP */
740  Irp->IoStatus.Status = STATUS_SUCCESS;
742 
743  return STATUS_SUCCESS;
744  }
746  {
747  /* only target relations are supported */
748  if (Stack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
749  {
750  /* not supported */
751  Status = Irp->IoStatus.Status;
752  Information = Irp->IoStatus.Information;
753  break;
754  }
755 
756  /* allocate device relations */
757  DeviceRelation = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
758  if (!DeviceRelation)
759  {
760  /* no memory */
762  break;
763  }
764 
765  /* init device relation */
766  DeviceRelation->Count = 1;
767  DeviceRelation->Objects[0] = DeviceObject;
768  ObReferenceObject(DeviceRelation->Objects[0]);
769 
770  /* store result */
771  Information = (ULONG_PTR)DeviceRelation;
773  break;
774  }
776  {
777  //
778  // We should fail this request, because we're not handling IRP_MN_STOP_DEVICE for now.
779  // We'll receive this IRP ONLY when the PnP manager rebalances resources.
780  //
782  break;
783  }
785  {
786  //
787  // Free interface obtained from bottom, according MSDN we should
788  // check interfaces provided to top, but here we are not checking.
789  // All checking will be performed in roothub driver's
790  // IRP_MN_QUERY_REMOVE_DEVICE handler. This will make problems when
791  // buggy driver is loaded on top of us. But we decided to keep source
792  // simpler, because in any case buggy driver will prevent removing of
793  // whole stack.
794  //
795  UsbChildExtension->DeviceInterface.InterfaceDereference(UsbChildExtension->DeviceInterface.BusContext);
796 
797  SET_NEW_PNP_STATE(UsbChildExtension->Common, RemovePending);
798 
799  /* Sure, no problem */
801  Information = 0;
802  break;
803  }
805  {
806  // Check to see have we received query-remove before
807  if (UsbChildExtension->Common.PnPState == RemovePending)
808  {
809  RESTORE_PREVIOUS_PNP_STATE(UsbChildExtension->Common);
810  UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
811  }
812 
814  break;
815  }
817  {
818  DPRINT1("IRP_MN_QUERY_INTERFACE\n");
819  if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID))
820  {
821  DPRINT1("USB_BUS_INTERFACE_USBDI_GUID\n");
822  RtlCopyMemory(Stack->Parameters.QueryInterface.Interface, &UsbChildExtension->DeviceInterface, Stack->Parameters.QueryInterface.Size);
823  UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
825  break;
826  }
827 
828  // pass irp down
830  Status = IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
831  IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
832  return Status;
833  }
835  {
836  DPRINT("[USBHUB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n");
837 
838  //
839  // Here we should free all resources and stop all access, lets just set
840  // the flag and do further clean-up in subsequent IRP_MN_REMOVE_DEVICE
841  // We can receive this IRP when device is physically connected (on stop/start fail).
842  //
843  SET_NEW_PNP_STATE(UsbChildExtension->Common, SurpriseRemovePending);
844 
846  break;
847  }
848  default:
849  {
850  DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
851  Information = Irp->IoStatus.Information;
852  Status = Irp->IoStatus.Status;
853  }
854  }
855 
856  IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
857 
858  Irp->IoStatus.Information = Information;
859  Irp->IoStatus.Status = Status;
861  return Status;
862 }
863 
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED)
UNICODE_STRING usHardwareIds
Definition: usbhub.h:89
#define IRP_MN_QUERY_RESOURCES
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS USBHUB_PdoStartDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pdo.c:428
#define IRP_MN_QUERY_ID
#define USB_PORT_STATUS_ENABLE
Definition: usb200.h:152
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG IoControlCode
Definition: fltkernel.h:1383
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
#define IRP_MJ_SHUTDOWN
_In_ PIRP Irp
Definition: csq.h:116
struct _HUB_CHILDDEVICE_EXTENSION * PHUB_CHILDDEVICE_EXTENSION
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO
Definition: usbioctl.h:68
#define IOCTL_INTERNAL_USB_ENABLE_PORT
Definition: usbioctl.h:47
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2054
unsigned char * PUCHAR
Definition: retypes.h:3
#define URB_FUNCTION_VENDOR_DEVICE
Definition: usb.h:109
LONG NTSTATUS
Definition: precomp.h:26
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2716
uint16_t * PWCHAR
Definition: typedefs.h:54
BOOLEAN IsValidPDO(IN PDEVICE_OBJECT DeviceObject)
Definition: pdo.c:139
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: usbbusif.h:111
UNICODE_STRING SymbolicLinkName
Definition: usbhub.h:95
struct _HUB_DEVICE_EXTENSION * PHUB_DEVICE_EXTENSION
USB_BUS_INTERFACE_USBDI_V2 DeviceInterface
Definition: usbhub.h:96
enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE
NTSTATUS USBHUB_PdoHandleInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pdo.c:175
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
uint32_t ULONG_PTR
Definition: typedefs.h:63
IO_REMOVE_LOCK RemoveLock
Definition: usbhub.h:78
#define URB_FUNCTION_CLASS_DEVICE
Definition: usb.h:112
PUSB_CONFIGURATION_DESCRIPTOR FullConfigDesc
Definition: usbhub.h:94
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void * Buffer
Definition: sprintf.c:453
UNICODE_STRING usTextDescription
Definition: usbhub.h:91
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define IRP_MN_QUERY_REMOVE_DEVICE
NTSTATUS USBHUB_PdoHandlePnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pdo.c:583
KGUARDED_MUTEX HubMutexLock
Definition: usbhub.h:109
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _PNP_BUS_INFORMATION * PPNP_BUS_INFORMATION
#define IoCompleteRequest
Definition: irp.c:1240
#define DeviceCapabilities
Definition: wingdi.h:4427
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS ForwardUrbToRootHub(PDEVICE_OBJECT RootHubDeviceObject, IN ULONG IoControlCode, PIRP Irp, OUT PVOID OutParameter1, OUT PVOID OutParameter2)
Definition: pdo.c:63
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
switch(r->id)
Definition: btrfs.c:2691
_In_ BUS_QUERY_ID_TYPE IdType
Definition: classpnp.h:357
#define IOCTL_INTERNAL_USB_CYCLE_PORT
Definition: usbioctl.h:53
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define IRP_MN_QUERY_STOP_DEVICE
USB_BUS_INTERFACE_HUB_V5 HubInterface
Definition: usbhub.h:118
struct _URB_HEADER UrbHeader
Definition: usb.h:531
NTSTATUS GetPortStatusAndChange(IN PDEVICE_OBJECT RootHubDeviceObject, IN ULONG PortId, OUT PPORT_STATUS_CHANGE StatusChange)
Definition: fdo.c:36
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define USB_MAXCHILDREN
Definition: usbhub.h:10
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define RESTORE_PREVIOUS_PNP_STATE(_Data_)
Definition: fbtusb.h:115
PDEVICE_OBJECT ChildDeviceObject[USB_MAXCHILDREN]
Definition: usbhub.h:105
UNICODE_STRING usCompatibleIds
Definition: usbhub.h:90
PDEVICE_OBJECT RootHubPhysicalDeviceObject
Definition: usbhub.h:106
#define IRP_MN_START_DEVICE
static const UCHAR Index[8]
Definition: usbohci.c:18
PIRP NTAPI IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:750
#define for
Definition: utility.h:88
COMMON_DEVICE_EXTENSION Common
Definition: usbhub.h:83
PUSB_DEVICE_HANDLE UsbDeviceHandle
Definition: usbhub.h:85
#define IRP_MN_QUERY_DEVICE_TEXT
#define IRP_MN_QUERY_INTERFACE
#define USB_PORT_STATUS_CONNECT
Definition: usb200.h:151
PDEVICE_OBJECT ParentDeviceObject
Definition: usbhub.h:84
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define IRP_MN_QUERY_BUS_INFORMATION
#define URB_FUNCTION_SELECT_CONFIGURATION
Definition: usb.h:86
_Out_ _Inout_ POEM_STRING _In_ PCUNICODE_STRING SourceString
Definition: rtlfuncs.h:1869
#define IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
Definition: usbioctl.h:38
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
Definition: usb.h:97
_In_ UCHAR MinorFunction
Definition: pofuncs.h:42
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:40
PINTERFACE_REFERENCE InterfaceReference
Definition: usbbusif.h:110
#define URB_FUNCTION_SELECT_INTERFACE
Definition: usb.h:87
* PDEVICE_CAPABILITIES
Definition: iotypes.h:927
struct _URB * PURB
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
NTSTATUS NTAPI UrbCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: pdo.c:26
NTSTATUS USBHUB_PdoQueryDeviceText(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, OUT ULONG_PTR *Information)
Definition: pdo.c:526
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1250
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
Definition: usb.h:529
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define URB_FUNCTION_GET_STATUS_FROM_DEVICE
Definition: usb.h:105
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IOCTL_INTERNAL_USB_RESET_PORT
Definition: usbioctl.h:35
#define IOCTL_INTERNAL_USB_GET_PORT_STATUS
Definition: usbioctl.h:44
NTSTATUS USBHUB_PdoQueryId(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, OUT ULONG_PTR *Information)
Definition: pdo.c:455
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define SET_NEW_PNP_STATE(_Data_, _state_)
Definition: fbtusb.h:111
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
PVOID PIRP
Definition: usb.h:38
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
#define IoReleaseRemoveLockAndWait(_RemoveLock, _Tag)
Definition: iofuncs.h:2726
DEVICE_PNP_STATE PnPState
Definition: usbhub.h:75
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2725
unsigned short MaximumLength
Definition: sprintf.c:452
IoMarkIrpPending(Irp)
USB_EXTHUB_INFORMATION_0 UsbExtHubInfo
Definition: usbhub.h:127
#define URB_FUNCTION_CLASS_OTHER
Definition: usb.h:117
#define IoAcquireRemoveLock(RemoveLock, Tag)
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:363
UNICODE_STRING usInstanceId
Definition: usbhub.h:88
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
Definition: usb.h:95
Iosb Information
Definition: create.c:4377
#define IRP_MN_QUERY_CAPABILITIES
UNICODE_STRING usDeviceId
Definition: usbhub.h:87