nt!PipSetDevNodeState函数的重要作用值从状态DeviceNodeStarted到状态DeviceNodeEnumerateCompletion到状态DeviceNodeStarted重要
第一部分:
NTSTATUS
PipProcessDevNodeTree(
IN PDEVICE_NODE SubtreeRootDeviceNode,
IN BOOLEAN LoadDriver,
IN BOOLEAN ReallocateResources,
IN ENUM_TYPE EnumType,
IN BOOLEAN Synchronous,
IN BOOLEAN ProcessOnlyIntermediateStates,
IN PADD_CONTEXT AddContext,
IN PPI_DEVICE_REQUEST Request
)
{
case DeviceNodeStarted:
nextNode = ChildNode;
if (!ProcessOnlyIntermediateStates) {
if ((currentNode->Flags & DNF_REENUMERATE)) {
status = PipEnumerateDevice(currentNode, Synchronous);
if (NT_SUCCESS(status)) {
//
// Remember the bus we just enumerated.
//
enumeratedBus = currentNode;
nextNode = SameNode;
} else if (status == STATUS_PENDING) {
nextNode = SiblingNode;
}
}
}
break;
NTSTATUS
PipEnumerateDevice(
IN PDEVICE_NODE DeviceNode,
IN BOOLEAN Synchronous
)
{
NTSTATUS status;
PAGED_CODE();
//
// Clear the flag before the query so we dont lose an enum request.
//
DeviceNode->Flags &= ~DNF_REENUMERATE;
status = IopQueryDeviceRelations(BusRelations,
DeviceNode->PhysicalDeviceObject,
Synchronous,
&DeviceNode->OverUsed1.PendingDeviceRelations
);
return status;
}
NTSTATUS
IopQueryDeviceRelations(
IN DEVICE_RELATION_TYPE Relations,
IN PDEVICE_OBJECT DeviceObject,
IN BOOLEAN Synchronous,
OUT PDEVICE_RELATIONS *DeviceRelations
)
{
IO_STACK_LOCATION irpSp;
NTSTATUS status;
PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
UNREFERENCED_PARAMETER (Synchronous);
//
// Initialize the stack location to pass to IopSynchronousCall()
//
RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
//
// Set the function codes.
//
irpSp.MajorFunction = IRP_MJ_PNP;
irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
//
// Set the pointer to the resource list
//
irpSp.Parameters.QueryDeviceRelations.Type = Relations;
//
// Make the call and return.
//
status = IopSynchronousCall(DeviceObject, &irpSp, (PULONG_PTR)DeviceRelations);
if (Relations == BusRelations) {
deviceNode->CompletionStatus = status;
PipSetDevNodeState( deviceNode, DeviceNodeEnumerateCompletion, NULL );
status = STATUS_SUCCESS;
}
return status;
}
第二部分:
NTSTATUS
PipProcessDevNodeTree(
IN PDEVICE_NODE SubtreeRootDeviceNode,
IN BOOLEAN LoadDriver,
IN BOOLEAN ReallocateResources,
IN ENUM_TYPE EnumType,
IN BOOLEAN Synchronous,
IN BOOLEAN ProcessOnlyIntermediateStates,
IN PADD_CONTEXT AddContext,
IN PPI_DEVICE_REQUEST Request
)
{
case DeviceNodeEnumerateCompletion:
status = PipEnumerateCompleted(currentNode);
nextNode = ChildNode;
break;
NTSTATUS
PipEnumerateCompleted(
IN PDEVICE_NODE DeviceNode
)
{
PDEVICE_NODE childDeviceNode, nextChildDeviceNode;
PDEVICE_OBJECT childDeviceObject;
BOOLEAN childRemoved;
NTSTATUS status, allocationStatus;
ULONG i;
PAGED_CODE();
if (DeviceNode->OverUsed1.PendingDeviceRelations == NULL) {
PipSetDevNodeState(DeviceNode, DeviceNodeStarted, NULL);
return STATUS_SUCCESS;
}
//
// Walk all the child device nodes and mark them as not present
//
childDeviceNode = DeviceNode->Child;
while (childDeviceNode) {
childDeviceNode->Flags &= ~DNF_ENUMERATED;
childDeviceNode = childDeviceNode->Sibling;
}
//
// Check all the PDOs returned see if any new one or any one disappeared.
//
for (i = 0; i < DeviceNode->OverUsed1.PendingDeviceRelations->Count; i++) {
childDeviceObject = DeviceNode->OverUsed1.PendingDeviceRelations->Objects[i];
ASSERT(DeviceNode->State == DeviceNodeEnumerateCompletion);
PipSetDevNodeState(DeviceNode, DeviceNodeStarted, NULL);
return status;
}