mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 07:26:20 +00:00
Simplify IoSynchronousInvalidateDeviceRelations/IoInvalidateDeviceRelations
IoInvalidateDeviceRelations now creates a workitem, which will call IoSynchronousInvalidateDeviceRelations() svn path=/trunk/; revision=27435
This commit is contained in:
parent
8b8021bbb9
commit
e3d5443c9a
1 changed files with 172 additions and 214 deletions
|
@ -37,17 +37,11 @@ PIO_BUS_TYPE_GUID_LIST IopBusTypeGuidList = NULL;
|
|||
|
||||
typedef struct _INVALIDATE_DEVICE_RELATION_DATA
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
DEVICE_RELATION_TYPE Type;
|
||||
PIO_WORKITEM WorkItem;
|
||||
PKEVENT Event;
|
||||
NTSTATUS Status;
|
||||
} INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
|
||||
|
||||
static VOID NTAPI
|
||||
IopInvalidateDeviceRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID InvalidateContext);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
IoSynchronousInvalidateDeviceRelations(
|
||||
|
@ -253,6 +247,22 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
|||
&Stack);
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
IopAsynchronousInvalidateDeviceRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID InvalidateContext)
|
||||
{
|
||||
PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext;
|
||||
|
||||
IoSynchronousInvalidateDeviceRelations(
|
||||
Data->DeviceObject,
|
||||
Data->Type);
|
||||
|
||||
ObDereferenceObject(Data->WorkItem);
|
||||
IoFreeWorkItem(Data->WorkItem);
|
||||
ExFreePool(Data);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -275,55 +285,18 @@ IoInvalidateDeviceRelations(
|
|||
return;
|
||||
}
|
||||
|
||||
ObReferenceObject(DeviceObject);
|
||||
Data->DeviceObject = DeviceObject;
|
||||
Data->Type = Type;
|
||||
Data->WorkItem = WorkItem;
|
||||
Data->Event = NULL;
|
||||
|
||||
IoQueueWorkItem(
|
||||
WorkItem,
|
||||
IopInvalidateDeviceRelations,
|
||||
IopAsynchronousInvalidateDeviceRelations,
|
||||
DelayedWorkQueue,
|
||||
Data);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
IoSynchronousInvalidateDeviceRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN DEVICE_RELATION_TYPE Type)
|
||||
{
|
||||
PIO_WORKITEM WorkItem;
|
||||
PINVALIDATE_DEVICE_RELATION_DATA Data;
|
||||
KEVENT Event;
|
||||
|
||||
Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
|
||||
if (!Data)
|
||||
return;
|
||||
WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||
if (!WorkItem)
|
||||
{
|
||||
ExFreePool(Data);
|
||||
return;
|
||||
}
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Data->Type = Type;
|
||||
Data->WorkItem = WorkItem;
|
||||
Data->Event = &Event;
|
||||
|
||||
IoQueueWorkItem(
|
||||
WorkItem,
|
||||
IopInvalidateDeviceRelations,
|
||||
DelayedWorkQueue,
|
||||
Data);
|
||||
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
ExFreePool(Data);
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
@ -2185,6 +2158,158 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
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;
|
||||
BOOLEAN BootDrivers;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
|
||||
HANDLE Handle;
|
||||
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))
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the state of the system boot. If the \\SystemRoot link isn't
|
||||
* created yet, we will assume that it's possible to load only boot
|
||||
* drivers.
|
||||
*/
|
||||
InitializeObjectAttributes(
|
||||
&ObjectAttributes,
|
||||
&LinkName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenFile(
|
||||
&Handle,
|
||||
FILE_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
0,
|
||||
0);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
BootDrivers = FALSE;
|
||||
ZwClose(Handle);
|
||||
}
|
||||
else
|
||||
BootDrivers = TRUE;
|
||||
|
||||
/*
|
||||
* Initialize services for discovered children. Only boot drivers will
|
||||
* be loaded from boot driver!
|
||||
*/
|
||||
Status = IopInitializePnpServices(DeviceNode, BootDrivers);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status);
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINT("IopInvalidateDeviceRelations() finished\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* IopActionConfigureChildServices
|
||||
*
|
||||
|
@ -2527,173 +2652,6 @@ IopInitializePnpServices(IN PDEVICE_NODE DeviceNode,
|
|||
return IopTraverseDeviceTree(&Context);
|
||||
}
|
||||
|
||||
/* Invalidate device list enumerated by a device node.
|
||||
* The call can be make synchronous by defining the Event field
|
||||
* of the INVALIDATE_DEVICE_RELATION_DATA structure
|
||||
*/
|
||||
static VOID NTAPI
|
||||
IopInvalidateDeviceRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID InvalidateContext) /* PINVALIDATE_DEVICE_RELATION_DATA */
|
||||
{
|
||||
PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext;
|
||||
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
|
||||
PKEVENT Event = Data->Event;
|
||||
DEVICETREE_TRAVERSE_CONTEXT Context;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PDEVICE_NODE ChildDeviceNode;
|
||||
IO_STACK_LOCATION Stack;
|
||||
BOOLEAN BootDrivers;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
|
||||
HANDLE Handle;
|
||||
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 = Data->Type;
|
||||
|
||||
Status = IopInitiatePnpIrp(
|
||||
DeviceObject,
|
||||
&IoStatusBlock,
|
||||
IRP_MN_QUERY_DEVICE_RELATIONS,
|
||||
&Stack);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
|
||||
|
||||
if (!DeviceRelations || DeviceRelations->Count <= 0)
|
||||
{
|
||||
DPRINT("No PDOs\n");
|
||||
if (DeviceRelations)
|
||||
{
|
||||
ExFreePool(DeviceRelations);
|
||||
}
|
||||
Status = STATUS_SUCCESS;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
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);
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
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);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the state of the system boot. If the \\SystemRoot link isn't
|
||||
* created yet, we will assume that it's possible to load only boot
|
||||
* drivers.
|
||||
*/
|
||||
InitializeObjectAttributes(
|
||||
&ObjectAttributes,
|
||||
&LinkName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenFile(
|
||||
&Handle,
|
||||
FILE_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
0,
|
||||
0);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
BootDrivers = FALSE;
|
||||
ZwClose(Handle);
|
||||
}
|
||||
else
|
||||
BootDrivers = TRUE;
|
||||
|
||||
/*
|
||||
* Initialize services for discovered children. Only boot drivers will
|
||||
* be loaded from boot driver!
|
||||
*/
|
||||
Status = IopInitializePnpServices(DeviceNode, BootDrivers);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DPRINT("IopInvalidateDeviceRelations() finished\n");
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
IoFreeWorkItem(Data->WorkItem);
|
||||
if (Event)
|
||||
{
|
||||
Data->Status = Status;
|
||||
KeSetEvent(Event, 0, FALSE);
|
||||
}
|
||||
else
|
||||
ExFreePool(Data);
|
||||
}
|
||||
|
||||
static NTSTATUS INIT_FUNCTION
|
||||
IopEnumerateDetectedDevices(
|
||||
IN HANDLE hBaseKey,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue