diff --git a/reactos/include/ndk/iofuncs.h b/reactos/include/ndk/iofuncs.h index 3ff89f4bc00..06648fd596c 100644 --- a/reactos/include/ndk/iofuncs.h +++ b/reactos/include/ndk/iofuncs.h @@ -37,6 +37,13 @@ IoAssignDriveLetters( OUT PUCHAR NtSystemPath, OUT PSTRING NtSystemPathString ); + +NTSTATUS +NTAPI +IoSynchronousInvalidateDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN DEVICE_RELATION_TYPE Type +); #endif // diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index 65dec1a517f..914d67fc393 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -556,6 +556,11 @@ IopActionInitChildServices( IN PVOID Context ); +NTSTATUS +IopEnumerateDevice( + IN PDEVICE_OBJECT DeviceObject +); + NTSTATUS IoCreateDriverList( VOID diff --git a/reactos/ntoskrnl/io/iomgr/iomgr.c b/reactos/ntoskrnl/io/iomgr/iomgr.c index d53ef808e74..2e44a5c0cfd 100644 --- a/reactos/ntoskrnl/io/iomgr/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr/iomgr.c @@ -16,14 +16,6 @@ ULONG IopTraceLevel = 0; BOOLEAN PnpSystemInit = FALSE; -// should go into a proper header -VOID -NTAPI -IoSynchronousInvalidateDeviceRelations( - IN PDEVICE_OBJECT DeviceObject, - IN DEVICE_RELATION_TYPE Type -); - VOID NTAPI IopTimerDispatch( @@ -510,10 +502,8 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) IopReinitializeBootDrivers(); /* Initialize PnP root relations */ - IoSynchronousInvalidateDeviceRelations(IopRootDeviceNode-> - PhysicalDeviceObject, - BusRelations); - + IopEnumerateDevice(IopRootDeviceNode->PhysicalDeviceObject); + /* Check if this was a ramdisk boot */ if (!_strnicmp(LoaderBlock->ArcBootDeviceName, "ramdisk(0)", 10)) { diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index e6005c00b6b..53a49f4c855 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -43,13 +43,6 @@ typedef struct _INVALIDATE_DEVICE_RELATION_DATA PIO_WORKITEM WorkItem; } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA; -VOID -NTAPI -IoSynchronousInvalidateDeviceRelations( - IN PDEVICE_OBJECT DeviceObject, - IN DEVICE_RELATION_TYPE Type); - - /* FUNCTIONS *****************************************************************/ static NTSTATUS @@ -206,7 +199,7 @@ IopStartDevice( DPRINT("Device needs enumeration, invalidating bus relations\n"); /* Invalidate device relations synchronously (otherwise there will be dirty read of DeviceNode) */ - IoSynchronousInvalidateDeviceRelations(DeviceNode->PhysicalDeviceObject, BusRelations); + IopEnumerateDevice(DeviceNode->PhysicalDeviceObject); IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY); } } @@ -1670,6 +1663,125 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, return STATUS_SUCCESS; } + +NTSTATUS +IopEnumerateDevice( + IN PDEVICE_OBJECT DeviceObject) +{ + PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); + DEVICETREE_TRAVERSE_CONTEXT Context; + PDEVICE_RELATIONS DeviceRelations; + IO_STATUS_BLOCK IoStatusBlock; + PDEVICE_NODE ChildDeviceNode; + IO_STACK_LOCATION Stack; + NTSTATUS Status; + ULONG i; + + DPRINT("DeviceObject 0x%p\n", DeviceObject); + + DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); + + Stack.Parameters.QueryDeviceRelations.Type = BusRelations; + + Status = IopInitiatePnpIrp( + DeviceObject, + &IoStatusBlock, + IRP_MN_QUERY_DEVICE_RELATIONS, + &Stack); + if (!NT_SUCCESS(Status) || Status == STATUS_PENDING) + { + DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status); + return Status; + } + + DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; + + if (!DeviceRelations || DeviceRelations->Count < 0) + { + DPRINT("No PDOs\n"); + if (DeviceRelations) + { + ExFreePool(DeviceRelations); + } + return STATUS_UNSUCCESSFUL; + } + + DPRINT("Got %d PDOs\n", DeviceRelations->Count); + + /* + * Create device nodes for all discovered devices + */ + for (i = 0; i < DeviceRelations->Count; i++) + { + if (IopGetDeviceNode(DeviceRelations->Objects[i]) != NULL) + { + ObDereferenceObject(DeviceRelations->Objects[i]); + continue; + } + Status = IopCreateDeviceNode( + DeviceNode, + DeviceRelations->Objects[i], + NULL, + &ChildDeviceNode); + DeviceNode->Flags |= DNF_ENUMERATED; + if (!NT_SUCCESS(Status)) + { + DPRINT("No resources\n"); + for (i = 0; i < DeviceRelations->Count; i++) + ObDereferenceObject(DeviceRelations->Objects[i]); + ExFreePool(DeviceRelations); + return Status; + } + } + ExFreePool(DeviceRelations); + + /* + * Retrieve information about all discovered children from the bus driver + */ + IopInitDeviceTreeTraverseContext( + &Context, + DeviceNode, + IopActionInterrogateDeviceStack, + DeviceNode); + + Status = IopTraverseDeviceTree(&Context); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status); + return Status; + } + + /* + * Retrieve configuration from the registry for discovered children + */ + IopInitDeviceTreeTraverseContext( + &Context, + DeviceNode, + IopActionConfigureChildServices, + DeviceNode); + + Status = IopTraverseDeviceTree(&Context); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status); + return Status; + } + + /* + * Initialize services for discovered children. + */ + Status = IopInitializePnpServices(DeviceNode); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status); + return Status; + } + + DPRINT("IopEnumerateDevice() finished\n"); + return STATUS_SUCCESS; +} + + /* * IopActionConfigureChildServices * @@ -3272,120 +3384,24 @@ IoInvalidateDeviceRelations( /* * @implemented */ -VOID +NTSTATUS NTAPI IoSynchronousInvalidateDeviceRelations( IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type) { - PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); - DEVICETREE_TRAVERSE_CONTEXT Context; - PDEVICE_RELATIONS DeviceRelations; - IO_STATUS_BLOCK IoStatusBlock; - PDEVICE_NODE ChildDeviceNode; - IO_STACK_LOCATION Stack; - NTSTATUS Status; - ULONG i; - - DPRINT("DeviceObject 0x%p\n", DeviceObject); - - DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); - - Stack.Parameters.QueryDeviceRelations.Type = Type; - - Status = IopInitiatePnpIrp( - DeviceObject, - &IoStatusBlock, - IRP_MN_QUERY_DEVICE_RELATIONS, - &Stack); - if (!NT_SUCCESS(Status)) + PAGED_CODE(); + + switch (Type) { - DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status); - return; + case BusRelations: + /* Enumerate the device */ + return IopEnumerateDevice(DeviceObject); + case PowerRelations: + /* Not handled yet */ + return STATUS_NOT_IMPLEMENTED; + default: + /* Ejection relations and target relations are not supported */ + return STATUS_NOT_SUPPORTED; } - - DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; - - if (!DeviceRelations || DeviceRelations->Count <= 0) - { - DPRINT("No PDOs\n"); - if (DeviceRelations) - { - ExFreePool(DeviceRelations); - } - return; - } - - DPRINT("Got %d PDOs\n", DeviceRelations->Count); - - /* - * Create device nodes for all discovered devices - */ - for (i = 0; i < DeviceRelations->Count; i++) - { - if (IopGetDeviceNode(DeviceRelations->Objects[i]) != NULL) - { - ObDereferenceObject(DeviceRelations->Objects[i]); - continue; - } - Status = IopCreateDeviceNode( - DeviceNode, - DeviceRelations->Objects[i], - NULL, - &ChildDeviceNode); - DeviceNode->Flags |= DNF_ENUMERATED; - if (!NT_SUCCESS(Status)) - { - DPRINT("No resources\n"); - for (i = 0; i < DeviceRelations->Count; i++) - ObDereferenceObject(DeviceRelations->Objects[i]); - ExFreePool(DeviceRelations); - return; - } - } - ExFreePool(DeviceRelations); - - /* - * Retrieve information about all discovered children from the bus driver - */ - IopInitDeviceTreeTraverseContext( - &Context, - DeviceNode, - IopActionInterrogateDeviceStack, - DeviceNode); - - Status = IopTraverseDeviceTree(&Context); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status); - return; - } - - /* - * Retrieve configuration from the registry for discovered children - */ - IopInitDeviceTreeTraverseContext( - &Context, - DeviceNode, - IopActionConfigureChildServices, - DeviceNode); - - Status = IopTraverseDeviceTree(&Context); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status); - return; - } - - /* - * Initialize services for discovered children. - */ - Status = IopInitializePnpServices(DeviceNode); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status); - return; - } - - DPRINT("IopInvalidateDeviceRelations() finished\n"); }