Skip to content

Commit 87a3559

Browse files
committed
usb: hub: FDO: Rework IRP_MN_QUERY_DEVICE_RELATIONS
First of all we should keep in account that there might be device relations below and above this FDO, so we should save previous relations coming from top object and shuld pass this IRP down to stack after adding our relations. In case of success query devcie relations must be completed in the PDO. As MSDN requires, if the upper layer provided this IRP with initialized DeviceRelation, then we should replace that relation with another one which will contain our child PDOs too. And after replacement we should free the recources allocated for previous relation structure. If there is relations coming from upper layer, we shuldn't complete this IRP with fail, because that will bring upper layer into unstabile state, it will 'think' that succesfully reported it's relations. svn path=/branches/GSoC_2016/USB/; revision=72372
1 parent ba43f5b commit 87a3559

File tree

1 file changed

+52
-11
lines changed

1 file changed

+52
-11
lines changed

drivers/usb/usbhub/fdo.c

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,11 +1387,13 @@ CreateUsbChildDeviceObject(
13871387
NTSTATUS
13881388
USBHUB_FdoQueryBusRelations(
13891389
IN PDEVICE_OBJECT DeviceObject,
1390+
IN PDEVICE_RELATIONS RelationsFromTop,
13901391
OUT PDEVICE_RELATIONS* pDeviceRelations)
13911392
{
13921393
PHUB_DEVICE_EXTENSION HubDeviceExtension;
13931394
PDEVICE_RELATIONS DeviceRelations;
13941395
ULONG i;
1396+
ULONG ChildrenFromTop = 0;
13951397
ULONG Children = 0;
13961398
ULONG NeededSize;
13971399

@@ -1410,9 +1412,18 @@ USBHUB_FdoQueryBusRelations(
14101412
Children++;
14111413
}
14121414

1413-
NeededSize = sizeof(DEVICE_RELATIONS);
1414-
if (Children > 1)
1415-
NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT);
1415+
if (RelationsFromTop)
1416+
{
1417+
ChildrenFromTop = RelationsFromTop->Count;
1418+
if (!Children)
1419+
{
1420+
// We have nothing to add
1421+
*pDeviceRelations = RelationsFromTop;
1422+
return STATUS_SUCCESS;
1423+
}
1424+
}
1425+
1426+
NeededSize = sizeof(DEVICE_RELATIONS) + (Children + ChildrenFromTop - 1) * sizeof(PDEVICE_OBJECT);
14161427

14171428
//
14181429
// Allocate DeviceRelations
@@ -1421,9 +1432,21 @@ USBHUB_FdoQueryBusRelations(
14211432
NeededSize);
14221433

14231434
if (!DeviceRelations)
1424-
return STATUS_INSUFFICIENT_RESOURCES;
1425-
DeviceRelations->Count = Children;
1426-
Children = 0;
1435+
{
1436+
if (!RelationsFromTop)
1437+
return STATUS_INSUFFICIENT_RESOURCES;
1438+
else
1439+
return STATUS_NOT_SUPPORTED;
1440+
}
1441+
// Copy the objects coming from top
1442+
if (ChildrenFromTop)
1443+
{
1444+
RtlCopyMemory(DeviceRelations->Objects, RelationsFromTop->Objects,
1445+
ChildrenFromTop * sizeof(PDEVICE_OBJECT));
1446+
}
1447+
1448+
DeviceRelations->Count = Children + ChildrenFromTop;
1449+
Children = ChildrenFromTop;
14271450

14281451
//
14291452
// Fill in return structure
@@ -1439,6 +1462,10 @@ USBHUB_FdoQueryBusRelations(
14391462
}
14401463
}
14411464

1465+
// We should do this, because replaced this with our's one
1466+
if (RelationsFromTop)
1467+
ExFreePool(RelationsFromTop);
1468+
14421469
ASSERT(Children == DeviceRelations->Count);
14431470
*pDeviceRelations = DeviceRelations;
14441471

@@ -1976,7 +2003,6 @@ USBHUB_FdoHandlePnp(
19762003
{
19772004
PIO_STACK_LOCATION Stack;
19782005
NTSTATUS Status = STATUS_SUCCESS;
1979-
ULONG_PTR Information = 0;
19802006
PHUB_DEVICE_EXTENSION HubDeviceExtension;
19812007

19822008
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
@@ -2007,12 +2033,28 @@ USBHUB_FdoHandlePnp(
20072033
case BusRelations:
20082034
{
20092035
PDEVICE_RELATIONS DeviceRelations = NULL;
2036+
PDEVICE_RELATIONS RelationsFromTop = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
20102037
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
20112038

2012-
Status = USBHUB_FdoQueryBusRelations(DeviceObject, &DeviceRelations);
2039+
Status = USBHUB_FdoQueryBusRelations(DeviceObject, RelationsFromTop, &DeviceRelations);
20132040

2014-
Information = (ULONG_PTR)DeviceRelations;
2015-
break;
2041+
if (!NT_SUCCESS(Status))
2042+
{
2043+
if (Status == STATUS_NOT_SUPPORTED)
2044+
{
2045+
// We should process this to not lose relations from top.
2046+
Irp->IoStatus.Status = STATUS_SUCCESS;
2047+
break;
2048+
}
2049+
// We should fail an IRP
2050+
Irp->IoStatus.Status = Status;
2051+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
2052+
return Status;
2053+
}
2054+
2055+
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
2056+
Irp->IoStatus.Status = Status;
2057+
return ForwardIrpAndForget(DeviceObject, Irp);
20162058
}
20172059
case RemovalRelations:
20182060
{
@@ -2066,7 +2108,6 @@ USBHUB_FdoHandlePnp(
20662108
}
20672109
}
20682110

2069-
Irp->IoStatus.Information = Information;
20702111
Irp->IoStatus.Status = Status;
20712112
IoCompleteRequest(Irp, IO_NO_INCREMENT);
20722113
return Status;

0 commit comments

Comments
 (0)