Author: vmikayelyan Date: Fri Aug 19 15:47:45 2016 New Revision: 72372
URL: http://svn.reactos.org/svn/reactos?rev=72372&view=rev Log: 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.
Modified: branches/GSoC_2016/USB/drivers/usb/usbhub/fdo.c
Modified: branches/GSoC_2016/USB/drivers/usb/usbhub/fdo.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/USB/drivers/usb/usbhub... ============================================================================== --- branches/GSoC_2016/USB/drivers/usb/usbhub/fdo.c [iso-8859-1] (original) +++ branches/GSoC_2016/USB/drivers/usb/usbhub/fdo.c [iso-8859-1] Fri Aug 19 15:47:45 2016 @@ -1387,11 +1387,13 @@ NTSTATUS USBHUB_FdoQueryBusRelations( IN PDEVICE_OBJECT DeviceObject, + IN PDEVICE_RELATIONS RelationsFromTop, OUT PDEVICE_RELATIONS* pDeviceRelations) { PHUB_DEVICE_EXTENSION HubDeviceExtension; PDEVICE_RELATIONS DeviceRelations; ULONG i; + ULONG ChildrenFromTop = 0; ULONG Children = 0; ULONG NeededSize;
@@ -1410,9 +1412,18 @@ Children++; }
- NeededSize = sizeof(DEVICE_RELATIONS); - if (Children > 1) - NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT); + if (RelationsFromTop) + { + ChildrenFromTop = RelationsFromTop->Count; + if (!Children) + { + // We have nothing to add + *pDeviceRelations = RelationsFromTop; + return STATUS_SUCCESS; + } + } + + NeededSize = sizeof(DEVICE_RELATIONS) + (Children + ChildrenFromTop - 1) * sizeof(PDEVICE_OBJECT);
// // Allocate DeviceRelations @@ -1421,9 +1432,21 @@ NeededSize);
if (!DeviceRelations) - return STATUS_INSUFFICIENT_RESOURCES; - DeviceRelations->Count = Children; - Children = 0; + { + if (!RelationsFromTop) + return STATUS_INSUFFICIENT_RESOURCES; + else + return STATUS_NOT_SUPPORTED; + } + // Copy the objects coming from top + if (ChildrenFromTop) + { + RtlCopyMemory(DeviceRelations->Objects, RelationsFromTop->Objects, + ChildrenFromTop * sizeof(PDEVICE_OBJECT)); + } + + DeviceRelations->Count = Children + ChildrenFromTop; + Children = ChildrenFromTop;
// // Fill in return structure @@ -1438,6 +1461,10 @@ DeviceRelations->Objects[Children++] = HubDeviceExtension->ChildDeviceObject[i]; } } + + // We should do this, because replaced this with our's one + if (RelationsFromTop) + ExFreePool(RelationsFromTop);
ASSERT(Children == DeviceRelations->Count); *pDeviceRelations = DeviceRelations; @@ -1976,7 +2003,6 @@ { PIO_STACK_LOCATION Stack; NTSTATUS Status = STATUS_SUCCESS; - ULONG_PTR Information = 0; PHUB_DEVICE_EXTENSION HubDeviceExtension;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension; @@ -2007,12 +2033,28 @@ case BusRelations: { PDEVICE_RELATIONS DeviceRelations = NULL; + PDEVICE_RELATIONS RelationsFromTop = (PDEVICE_RELATIONS)Irp->IoStatus.Information; DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
- Status = USBHUB_FdoQueryBusRelations(DeviceObject, &DeviceRelations); - - Information = (ULONG_PTR)DeviceRelations; - break; + Status = USBHUB_FdoQueryBusRelations(DeviceObject, RelationsFromTop, &DeviceRelations); + + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_NOT_SUPPORTED) + { + // We should process this to not lose relations from top. + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + } + // We should fail an IRP + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + Irp->IoStatus.Status = Status; + return ForwardIrpAndForget(DeviceObject, Irp); } case RemovalRelations: { @@ -2066,7 +2108,6 @@ } }
- Irp->IoStatus.Information = Information; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status;