Move most of the code of IoSynchronousInvalidateDeviceRelations to IopEnumerateDevice, and use it when possible

Fix IoSynchronousInvalidateDeviceRelations prototype

svn path=/trunk/; revision=35533
This commit is contained in:
Hervé Poussineau 2008-08-22 19:00:31 +00:00
parent bf702f35f2
commit 70f34a3756
4 changed files with 147 additions and 129 deletions

View file

@ -37,6 +37,13 @@ IoAssignDriveLetters(
OUT PUCHAR NtSystemPath, OUT PUCHAR NtSystemPath,
OUT PSTRING NtSystemPathString OUT PSTRING NtSystemPathString
); );
NTSTATUS
NTAPI
IoSynchronousInvalidateDeviceRelations(
IN PDEVICE_OBJECT DeviceObject,
IN DEVICE_RELATION_TYPE Type
);
#endif #endif
// //

View file

@ -556,6 +556,11 @@ IopActionInitChildServices(
IN PVOID Context IN PVOID Context
); );
NTSTATUS
IopEnumerateDevice(
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS NTSTATUS
IoCreateDriverList( IoCreateDriverList(
VOID VOID

View file

@ -16,14 +16,6 @@
ULONG IopTraceLevel = 0; ULONG IopTraceLevel = 0;
BOOLEAN PnpSystemInit = FALSE; BOOLEAN PnpSystemInit = FALSE;
// should go into a proper header
VOID
NTAPI
IoSynchronousInvalidateDeviceRelations(
IN PDEVICE_OBJECT DeviceObject,
IN DEVICE_RELATION_TYPE Type
);
VOID VOID
NTAPI NTAPI
IopTimerDispatch( IopTimerDispatch(
@ -510,9 +502,7 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
IopReinitializeBootDrivers(); IopReinitializeBootDrivers();
/* Initialize PnP root relations */ /* Initialize PnP root relations */
IoSynchronousInvalidateDeviceRelations(IopRootDeviceNode-> IopEnumerateDevice(IopRootDeviceNode->PhysicalDeviceObject);
PhysicalDeviceObject,
BusRelations);
/* Check if this was a ramdisk boot */ /* Check if this was a ramdisk boot */
if (!_strnicmp(LoaderBlock->ArcBootDeviceName, "ramdisk(0)", 10)) if (!_strnicmp(LoaderBlock->ArcBootDeviceName, "ramdisk(0)", 10))

View file

@ -43,13 +43,6 @@ typedef struct _INVALIDATE_DEVICE_RELATION_DATA
PIO_WORKITEM WorkItem; PIO_WORKITEM WorkItem;
} INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA; } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
VOID
NTAPI
IoSynchronousInvalidateDeviceRelations(
IN PDEVICE_OBJECT DeviceObject,
IN DEVICE_RELATION_TYPE Type);
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
static NTSTATUS static NTSTATUS
@ -206,7 +199,7 @@ IopStartDevice(
DPRINT("Device needs enumeration, invalidating bus relations\n"); DPRINT("Device needs enumeration, invalidating bus relations\n");
/* Invalidate device relations synchronously /* Invalidate device relations synchronously
(otherwise there will be dirty read of DeviceNode) */ (otherwise there will be dirty read of DeviceNode) */
IoSynchronousInvalidateDeviceRelations(DeviceNode->PhysicalDeviceObject, BusRelations); IopEnumerateDevice(DeviceNode->PhysicalDeviceObject);
IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY); IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
} }
} }
@ -1670,6 +1663,125 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
return STATUS_SUCCESS; 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 * IopActionConfigureChildServices
* *
@ -3272,120 +3384,24 @@ IoInvalidateDeviceRelations(
/* /*
* @implemented * @implemented
*/ */
VOID NTSTATUS
NTAPI NTAPI
IoSynchronousInvalidateDeviceRelations( IoSynchronousInvalidateDeviceRelations(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN DEVICE_RELATION_TYPE Type) IN DEVICE_RELATION_TYPE Type)
{ {
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); PAGED_CODE();
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); switch (Type)
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))
{ {
DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status); case BusRelations:
return; /* 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");
} }