mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[NTOS:PNP] Implement NT5.2-like DEVICE_NODE state management
- Use DeviceNode->State field and its values, instead of DeviceNode->Flags for tracking current node state - Change DNF_* flags to the ones compatible with Windows XP+ - Simplify state changes for device nodes and encapsulate all the logic inside the PiDevNodeStateMachine routine. This makes the ground for future improvements in the device removal sequence and resource management - Now values inside DeviceNode->State and ->Flags are compatible with the windbg !devnode macro and can be tracked using it - BUGFIX: fixed cases where IRP_MN_START_DEVICE or IRP_MN_QUERY_DEVICE_RELATIONS may be sent to a device after a IRP_MN_REMOVE_DEVICE CORE-7826
This commit is contained in:
parent
b704292808
commit
798fc13b48
12 changed files with 723 additions and 967 deletions
|
@ -567,11 +567,6 @@ IopDetectResourceConflict(
|
||||||
//
|
//
|
||||||
// PNP Routines
|
// PNP Routines
|
||||||
//
|
//
|
||||||
NTSTATUS
|
|
||||||
PiCallDriverAddDevice(
|
|
||||||
_In_ PDEVICE_NODE DeviceNode,
|
|
||||||
_In_ BOOLEAN LoadDrivers);
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopInitializePlugPlayServices(
|
IopInitializePlugPlayServices(
|
||||||
|
@ -609,6 +604,11 @@ PiInsertDevNode(
|
||||||
_In_ PDEVICE_NODE DeviceNode,
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
_In_ PDEVICE_NODE ParentNode);
|
_In_ PDEVICE_NODE ParentNode);
|
||||||
|
|
||||||
|
PNP_DEVNODE_STATE
|
||||||
|
PiSetDevNodeState(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_In_ PNP_DEVNODE_STATE NewState);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
PiSetDevNodeProblem(
|
PiSetDevNodeProblem(
|
||||||
_In_ PDEVICE_NODE DeviceNode,
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
@ -629,7 +629,6 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
||||||
PDEVICE_CAPABILITIES DeviceCaps);
|
PDEVICE_CAPABILITIES DeviceCaps);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
|
||||||
IopSynchronousCall(
|
IopSynchronousCall(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIO_STACK_LOCATION IoStackLocation,
|
IN PIO_STACK_LOCATION IoStackLocation,
|
||||||
|
@ -651,18 +650,6 @@ IopGetDeviceNode(
|
||||||
IN PDEVICE_OBJECT DeviceObject
|
IN PDEVICE_OBJECT DeviceObject
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
IopActionConfigureChildServices(
|
|
||||||
IN PDEVICE_NODE DeviceNode,
|
|
||||||
IN PVOID Context
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
IopActionInitChildServices(
|
|
||||||
IN PDEVICE_NODE DeviceNode,
|
|
||||||
IN PVOID Context
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
IoCreateDriverList(
|
IoCreateDriverList(
|
||||||
VOID
|
VOID
|
||||||
|
@ -682,10 +669,6 @@ IopQueueTargetDeviceEvent(
|
||||||
PUNICODE_STRING DeviceIds
|
PUNICODE_STRING DeviceIds
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
IopInitializePnpServices(
|
|
||||||
IN PDEVICE_NODE DeviceNode);
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopOpenRegistryKeyEx(
|
IopOpenRegistryKeyEx(
|
||||||
|
@ -817,21 +800,6 @@ IopReadyDeviceObjects(
|
||||||
IN PDRIVER_OBJECT Driver
|
IN PDRIVER_OBJECT Driver
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
IopStartDevice(
|
|
||||||
IN PDEVICE_NODE DeviceNode
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
IopStopDevice(
|
|
||||||
IN PDEVICE_NODE DeviceNode
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
IopRemoveDevice(
|
|
||||||
IN PDEVICE_NODE DeviceNode
|
|
||||||
);
|
|
||||||
|
|
||||||
PVPB
|
PVPB
|
||||||
NTAPI
|
NTAPI
|
||||||
IopCheckVpbMounted(
|
IopCheckVpbMounted(
|
||||||
|
@ -1387,6 +1355,35 @@ PiNotifyTargetDeviceChange(
|
||||||
_In_ PDEVICE_OBJECT DeviceObject,
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
_In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification);
|
_In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification);
|
||||||
|
|
||||||
|
//
|
||||||
|
// PnP IRPs
|
||||||
|
//
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpStartDevice(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpStopDevice(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpQueryStopDevice(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpCancelStopDevice(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpQueryDeviceRelations(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_In_ DEVICE_RELATION_TYPE Type);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpQueryPnPDeviceState(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_Out_ PPNP_DEVICE_STATE DeviceState);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Global I/O Data
|
// Global I/O Data
|
||||||
//
|
//
|
||||||
|
|
|
@ -596,9 +596,6 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
KdInitSystem(3, LoaderBlock);
|
KdInitSystem(3, LoaderBlock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Load services for devices found by PnP manager */
|
|
||||||
IopInitializePnpServices(IopRootDeviceNode);
|
|
||||||
|
|
||||||
/* Load system start drivers */
|
/* Load system start drivers */
|
||||||
IopInitializeSystemDrivers();
|
IopInitializeSystemDrivers();
|
||||||
PnpSystemInit = TRUE;
|
PnpSystemInit = TRUE;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -70,6 +70,8 @@ PipAllocateDeviceNode(
|
||||||
PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT("Allocated devnode 0x%p\n", DeviceNode);
|
||||||
|
|
||||||
/* Return the node */
|
/* Return the node */
|
||||||
return DeviceNode;
|
return DeviceNode;
|
||||||
}
|
}
|
||||||
|
@ -98,6 +100,32 @@ PiInsertDevNode(
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&IopDeviceTreeLock, oldIrql);
|
KeReleaseSpinLock(&IopDeviceTreeLock, oldIrql);
|
||||||
DeviceNode->Level = ParentNode->Level + 1;
|
DeviceNode->Level = ParentNode->Level + 1;
|
||||||
|
|
||||||
|
DPRINT("Inserted devnode 0x%p to parent 0x%p\n", DeviceNode, ParentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
PNP_DEVNODE_STATE
|
||||||
|
PiSetDevNodeState(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_In_ PNP_DEVNODE_STATE NewState)
|
||||||
|
{
|
||||||
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&IopDeviceTreeLock, &oldIrql);
|
||||||
|
|
||||||
|
PNP_DEVNODE_STATE prevState = DeviceNode->State;
|
||||||
|
if (prevState != NewState)
|
||||||
|
{
|
||||||
|
DeviceNode->State = NewState;
|
||||||
|
DeviceNode->PreviousState = prevState;
|
||||||
|
DeviceNode->StateHistory[DeviceNode->StateHistoryEntry++] = prevState;
|
||||||
|
DeviceNode->StateHistoryEntry %= DEVNODE_HISTORY_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&IopDeviceTreeLock, oldIrql);
|
||||||
|
|
||||||
|
DPRINT("%wZ Changed state 0x%x => 0x%x\n", &DeviceNode->InstancePath, prevState, NewState);
|
||||||
|
return prevState;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -302,9 +330,11 @@ IopFreeDeviceNode(
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PDEVICE_NODE PrevSibling = NULL;
|
PDEVICE_NODE PrevSibling = NULL;
|
||||||
|
|
||||||
/* All children must be deleted before a parent is deleted */
|
|
||||||
ASSERT(!DeviceNode->Child);
|
|
||||||
ASSERT(DeviceNode->PhysicalDeviceObject);
|
ASSERT(DeviceNode->PhysicalDeviceObject);
|
||||||
|
/* All children must be deleted before a parent is deleted */
|
||||||
|
ASSERT(DeviceNode->Child == NULL);
|
||||||
|
/* This is the only state where we are allowed to remove the node */
|
||||||
|
ASSERT(DeviceNode->State == DeviceNodeRemoved);
|
||||||
/* No notifications should be registered for this device */
|
/* No notifications should be registered for this device */
|
||||||
ASSERT(IsListEmpty(&DeviceNode->TargetDeviceNotify));
|
ASSERT(IsListEmpty(&DeviceNode->TargetDeviceNotify));
|
||||||
|
|
||||||
|
|
|
@ -689,37 +689,54 @@ IopGetRelatedDevice(PPLUGPLAY_CONTROL_RELATED_DEVICE_DATA RelatedDeviceData)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOLEAN
|
||||||
|
PiIsDevNodeStarted(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode)
|
||||||
|
{
|
||||||
|
return (DeviceNode->State == DeviceNodeStartPending ||
|
||||||
|
DeviceNode->State == DeviceNodeStartCompletion ||
|
||||||
|
DeviceNode->State == DeviceNodeStartPostWork ||
|
||||||
|
DeviceNode->State == DeviceNodeStarted ||
|
||||||
|
DeviceNode->State == DeviceNodeQueryStopped ||
|
||||||
|
DeviceNode->State == DeviceNodeEnumeratePending ||
|
||||||
|
DeviceNode->State == DeviceNodeEnumerateCompletion ||
|
||||||
|
DeviceNode->State == DeviceNodeStopped ||
|
||||||
|
DeviceNode->State == DeviceNodeRestartCompletion);
|
||||||
|
}
|
||||||
|
|
||||||
static ULONG
|
static ULONG
|
||||||
IopGetDeviceNodeStatus(PDEVICE_NODE DeviceNode)
|
IopGetDeviceNodeStatus(PDEVICE_NODE DeviceNode)
|
||||||
{
|
{
|
||||||
ULONG Output = 0;
|
ULONG Output = DN_NT_ENUMERATOR | DN_NT_DRIVER;
|
||||||
|
|
||||||
if (DeviceNode->Parent == IopRootDeviceNode)
|
if (DeviceNode->Parent == IopRootDeviceNode)
|
||||||
Output |= DN_ROOT_ENUMERATED;
|
Output |= DN_ROOT_ENUMERATED;
|
||||||
|
|
||||||
if (DeviceNode->Flags & DNF_ADDED)
|
// FIXME: review for deleted and removed states
|
||||||
|
if (DeviceNode->State >= DeviceNodeDriversAdded)
|
||||||
Output |= DN_DRIVER_LOADED;
|
Output |= DN_DRIVER_LOADED;
|
||||||
|
|
||||||
/* FIXME: DN_ENUM_LOADED */
|
if (PiIsDevNodeStarted(DeviceNode))
|
||||||
|
|
||||||
if (DeviceNode->Flags & DNF_STARTED)
|
|
||||||
Output |= DN_STARTED;
|
Output |= DN_STARTED;
|
||||||
|
|
||||||
/* FIXME: Manual */
|
if (DeviceNode->UserFlags & DNUF_WILL_BE_REMOVED)
|
||||||
|
Output |= DN_WILL_BE_REMOVED;
|
||||||
|
|
||||||
if (!(DeviceNode->Flags & DNF_PROCESSED))
|
if (DeviceNode->Flags & DNF_HAS_PROBLEM)
|
||||||
Output |= DN_NEED_TO_ENUM;
|
|
||||||
|
|
||||||
/* DN_NOT_FIRST_TIME is 9x only */
|
|
||||||
|
|
||||||
/* FIXME: DN_HARDWARE_ENUM */
|
|
||||||
|
|
||||||
/* DN_LIAR and DN_HAS_MARK are 9x only */
|
|
||||||
|
|
||||||
if (DeviceNode->Problem != 0)
|
|
||||||
Output |= DN_HAS_PROBLEM;
|
Output |= DN_HAS_PROBLEM;
|
||||||
|
|
||||||
/* FIXME: DN_FILTERED */
|
if (DeviceNode->Flags & DNF_HAS_PRIVATE_PROBLEM)
|
||||||
|
Output |= DN_PRIVATE_PROBLEM;
|
||||||
|
|
||||||
|
if (DeviceNode->Flags & DNF_DRIVER_BLOCKED)
|
||||||
|
Output |= DN_DRIVER_BLOCKED;
|
||||||
|
|
||||||
|
if (DeviceNode->Flags & DNF_CHILD_WITH_INVALID_ID)
|
||||||
|
Output |= DN_CHILD_WITH_INVALID_ID;
|
||||||
|
|
||||||
|
if (DeviceNode->Flags & DNF_HAS_PRIVATE_PROBLEM)
|
||||||
|
Output |= DN_PRIVATE_PROBLEM;
|
||||||
|
|
||||||
if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
|
if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
|
||||||
Output |= DN_LEGACY_DRIVER;
|
Output |= DN_LEGACY_DRIVER;
|
||||||
|
@ -730,10 +747,6 @@ IopGetDeviceNodeStatus(PDEVICE_NODE DeviceNode)
|
||||||
if (!(DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE))
|
if (!(DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE))
|
||||||
Output |= DN_DISABLEABLE;
|
Output |= DN_DISABLEABLE;
|
||||||
|
|
||||||
/* FIXME: Implement the rest */
|
|
||||||
|
|
||||||
Output |= DN_NT_ENUMERATOR | DN_NT_DRIVER;
|
|
||||||
|
|
||||||
return Output;
|
return Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -431,9 +431,8 @@ IopInitializePlugPlayServices(VOID)
|
||||||
IopRootDeviceNode = PipAllocateDeviceNode(Pdo);
|
IopRootDeviceNode = PipAllocateDeviceNode(Pdo);
|
||||||
|
|
||||||
/* Set flags */
|
/* Set flags */
|
||||||
IopRootDeviceNode->Flags |= DNF_STARTED + DNF_PROCESSED + DNF_ENUMERATED +
|
IopRootDeviceNode->Flags |= DNF_MADEUP | DNF_ENUMERATED |
|
||||||
DNF_MADEUP + DNF_NO_RESOURCE_REQUIRED +
|
DNF_IDS_QUERIED | DNF_NO_RESOURCE_REQUIRED;
|
||||||
DNF_ADDED;
|
|
||||||
|
|
||||||
/* Create instance path */
|
/* Create instance path */
|
||||||
RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath,
|
RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath,
|
||||||
|
@ -443,19 +442,20 @@ IopInitializePlugPlayServices(VOID)
|
||||||
IopRootDriverObject->DriverExtension->AddDevice(IopRootDriverObject,
|
IopRootDriverObject->DriverExtension->AddDevice(IopRootDriverObject,
|
||||||
IopRootDeviceNode->PhysicalDeviceObject);
|
IopRootDeviceNode->PhysicalDeviceObject);
|
||||||
|
|
||||||
|
PiSetDevNodeState(IopRootDeviceNode, DeviceNodeStarted);
|
||||||
|
|
||||||
/* Initialize PnP-Event notification support */
|
/* Initialize PnP-Event notification support */
|
||||||
Status = IopInitPlugPlayEvents();
|
Status = IopInitPlugPlayEvents();
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
/* Report the device to the user-mode pnp manager */
|
|
||||||
IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
|
|
||||||
&IopRootDeviceNode->InstancePath);
|
|
||||||
|
|
||||||
/* Initialize the Bus Type GUID List */
|
/* Initialize the Bus Type GUID List */
|
||||||
PnpBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
|
PnpBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
|
||||||
RtlZeroMemory(PnpBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
|
RtlZeroMemory(PnpBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
|
||||||
ExInitializeFastMutex(&PnpBusTypeGuidList->Lock);
|
ExInitializeFastMutex(&PnpBusTypeGuidList->Lock);
|
||||||
|
|
||||||
|
/* Initialize PnP root relations (this is a syncronous operation) */
|
||||||
|
PiQueueDeviceAction(IopRootDeviceNode->PhysicalDeviceObject, PiActionEnumRootDevices, NULL, NULL);
|
||||||
|
|
||||||
/* Launch the firmware mapper */
|
/* Launch the firmware mapper */
|
||||||
Status = IopUpdateRootKey();
|
Status = IopUpdateRootKey();
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
225
ntoskrnl/io/pnpmgr/pnpirp.c
Normal file
225
ntoskrnl/io/pnpmgr/pnpirp.c
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
|
* PURPOSE: Shortcuts for sending different IRP_MJ_PNP requests
|
||||||
|
* COPYRIGHT: Copyright 2010 Sir Richard <sir_richard@svn.reactos.org>
|
||||||
|
* Copyright 2020 Victor Perevertkin <victor.perevertkin@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
IopSynchronousCall(
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_ PIO_STACK_LOCATION IoStackLocation,
|
||||||
|
_Out_ PVOID *Information)
|
||||||
|
{
|
||||||
|
PIRP Irp;
|
||||||
|
PIO_STACK_LOCATION IrpStack;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PDEVICE_OBJECT TopDeviceObject;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Call the top of the device stack */
|
||||||
|
TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
|
||||||
|
|
||||||
|
/* Allocate an IRP */
|
||||||
|
Irp = IoAllocateIrp(TopDeviceObject->StackSize, FALSE);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
ObDereferenceObject(TopDeviceObject);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize to failure */
|
||||||
|
Irp->IoStatus.Status = IoStatusBlock.Status = STATUS_NOT_SUPPORTED;
|
||||||
|
Irp->IoStatus.Information = IoStatusBlock.Information = 0;
|
||||||
|
|
||||||
|
/* Special case for IRP_MN_FILTER_RESOURCE_REQUIREMENTS */
|
||||||
|
if ((IoStackLocation->MajorFunction == IRP_MJ_PNP) &&
|
||||||
|
(IoStackLocation->MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS))
|
||||||
|
{
|
||||||
|
/* Copy the resource requirements list into the IOSB */
|
||||||
|
Irp->IoStatus.Information =
|
||||||
|
IoStatusBlock.Information = (ULONG_PTR)IoStackLocation->Parameters.FilterResourceRequirements.IoResourceRequirementList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the event */
|
||||||
|
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
|
/* Set them up */
|
||||||
|
Irp->UserIosb = &IoStatusBlock;
|
||||||
|
Irp->UserEvent = &Event;
|
||||||
|
|
||||||
|
/* Queue the IRP */
|
||||||
|
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||||
|
IoQueueThreadIrp(Irp);
|
||||||
|
|
||||||
|
/* Copy-in the stack */
|
||||||
|
IrpStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
*IrpStack = *IoStackLocation;
|
||||||
|
|
||||||
|
/* Call the driver */
|
||||||
|
Status = IoCallDriver(TopDeviceObject, Irp);
|
||||||
|
/* Otherwise we may get stuck here or have IoStatusBlock not populated */
|
||||||
|
ASSERT(!KeAreAllApcsDisabled());
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Wait for it */
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
Status = IoStatusBlock.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the reference */
|
||||||
|
ObDereferenceObject(TopDeviceObject);
|
||||||
|
|
||||||
|
/* Return the information */
|
||||||
|
*Information = (PVOID)IoStatusBlock.Information;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IRP_MN_START_DEVICE (0x00)
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpStartDevice(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(DeviceNode);
|
||||||
|
ASSERT(DeviceNode->State == DeviceNodeResourcesAssigned);
|
||||||
|
|
||||||
|
PVOID info;
|
||||||
|
IO_STACK_LOCATION stack = {
|
||||||
|
.MajorFunction = IRP_MJ_PNP,
|
||||||
|
.MinorFunction = IRP_MN_START_DEVICE,
|
||||||
|
.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList,
|
||||||
|
.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vista+ does an asynchronous call
|
||||||
|
NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, &info);
|
||||||
|
DeviceNode->CompletionStatus = status;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IRP_MN_STOP_DEVICE (0x04)
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpStopDevice(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(DeviceNode);
|
||||||
|
ASSERT(DeviceNode->State == DeviceNodeQueryStopped);
|
||||||
|
|
||||||
|
PVOID info;
|
||||||
|
IO_STACK_LOCATION stack = {
|
||||||
|
.MajorFunction = IRP_MJ_PNP,
|
||||||
|
.MinorFunction = IRP_MN_STOP_DEVICE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Drivers should never fail a IRP_MN_STOP_DEVICE request
|
||||||
|
NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, &info);
|
||||||
|
ASSERT(NT_SUCCESS(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IRP_MN_QUERY_STOP_DEVICE (0x05)
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpQueryStopDevice(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(DeviceNode);
|
||||||
|
ASSERT(DeviceNode->State == DeviceNodeStarted);
|
||||||
|
|
||||||
|
PVOID info;
|
||||||
|
IO_STACK_LOCATION stack = {
|
||||||
|
.MajorFunction = IRP_MJ_PNP,
|
||||||
|
.MinorFunction = IRP_MN_QUERY_STOP_DEVICE
|
||||||
|
};
|
||||||
|
|
||||||
|
NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, &info);
|
||||||
|
DeviceNode->CompletionStatus = status;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IRP_MN_CANCEL_STOP_DEVICE (0x06)
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpCancelStopDevice(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(DeviceNode);
|
||||||
|
ASSERT(DeviceNode->State == DeviceNodeQueryStopped);
|
||||||
|
|
||||||
|
PVOID info;
|
||||||
|
IO_STACK_LOCATION stack = {
|
||||||
|
.MajorFunction = IRP_MJ_PNP,
|
||||||
|
.MinorFunction = IRP_MN_CANCEL_STOP_DEVICE
|
||||||
|
};
|
||||||
|
|
||||||
|
// in fact we don't care which status is returned here
|
||||||
|
NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, &info);
|
||||||
|
ASSERT(NT_SUCCESS(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IRP_MN_QUERY_DEVICE_RELATIONS (0x07)
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpQueryDeviceRelations(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_In_ DEVICE_RELATION_TYPE Type)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(DeviceNode);
|
||||||
|
ASSERT(DeviceNode->State == DeviceNodeStarted);
|
||||||
|
|
||||||
|
IO_STACK_LOCATION stack = {
|
||||||
|
.MajorFunction = IRP_MJ_PNP,
|
||||||
|
.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS,
|
||||||
|
.Parameters.QueryDeviceRelations.Type = Type
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vista+ does an asynchronous call
|
||||||
|
NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject,
|
||||||
|
&stack,
|
||||||
|
(PVOID)&DeviceNode->OverUsed1.PendingDeviceRelations);
|
||||||
|
DeviceNode->CompletionStatus = status;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IRP_MN_QUERY_PNP_DEVICE_STATE (0x14)
|
||||||
|
NTSTATUS
|
||||||
|
PiIrpQueryPnPDeviceState(
|
||||||
|
_In_ PDEVICE_NODE DeviceNode,
|
||||||
|
_Out_ PPNP_DEVICE_STATE DeviceState)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(DeviceNode);
|
||||||
|
ASSERT(DeviceNode->State == DeviceNodeStartPostWork ||
|
||||||
|
DeviceNode->State == DeviceNodeStarted);
|
||||||
|
|
||||||
|
ULONG_PTR longState;
|
||||||
|
IO_STACK_LOCATION stack = {
|
||||||
|
.MajorFunction = IRP_MJ_PNP,
|
||||||
|
.MinorFunction = IRP_MN_QUERY_PNP_DEVICE_STATE
|
||||||
|
};
|
||||||
|
|
||||||
|
NTSTATUS status;
|
||||||
|
status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, (PVOID)&longState);
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
*DeviceState = longState;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
|
@ -475,82 +475,6 @@ Quickie:
|
||||||
return FoundIndex;
|
return FoundIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIO_STACK_LOCATION IoStackLocation,
|
|
||||||
OUT PVOID *Information)
|
|
||||||
{
|
|
||||||
PIRP Irp;
|
|
||||||
PIO_STACK_LOCATION IrpStack;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
KEVENT Event;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PDEVICE_OBJECT TopDeviceObject;
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
/* Call the top of the device stack */
|
|
||||||
TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
|
|
||||||
|
|
||||||
/* Allocate an IRP */
|
|
||||||
Irp = IoAllocateIrp(TopDeviceObject->StackSize, FALSE);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(TopDeviceObject);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize to failure */
|
|
||||||
Irp->IoStatus.Status = IoStatusBlock.Status = STATUS_NOT_SUPPORTED;
|
|
||||||
Irp->IoStatus.Information = IoStatusBlock.Information = 0;
|
|
||||||
|
|
||||||
/* Special case for IRP_MN_FILTER_RESOURCE_REQUIREMENTS */
|
|
||||||
if ((IoStackLocation->MajorFunction == IRP_MJ_PNP) &&
|
|
||||||
(IoStackLocation->MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS))
|
|
||||||
{
|
|
||||||
/* Copy the resource requirements list into the IOSB */
|
|
||||||
Irp->IoStatus.Information =
|
|
||||||
IoStatusBlock.Information = (ULONG_PTR)IoStackLocation->Parameters.FilterResourceRequirements.IoResourceRequirementList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the event */
|
|
||||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
|
||||||
|
|
||||||
/* Set them up */
|
|
||||||
Irp->UserIosb = &IoStatusBlock;
|
|
||||||
Irp->UserEvent = &Event;
|
|
||||||
|
|
||||||
/* Queue the IRP */
|
|
||||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
|
||||||
IoQueueThreadIrp(Irp);
|
|
||||||
|
|
||||||
/* Copy-in the stack */
|
|
||||||
IrpStack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
*IrpStack = *IoStackLocation;
|
|
||||||
|
|
||||||
/* Call the driver */
|
|
||||||
Status = IoCallDriver(TopDeviceObject, Irp);
|
|
||||||
/* Otherwise we may get stuck here or have IoStatusBlock not populated */
|
|
||||||
ASSERT(!KeAreAllApcsDisabled());
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
/* Wait for it */
|
|
||||||
KeWaitForSingleObject(&Event,
|
|
||||||
Executive,
|
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the reference */
|
|
||||||
ObDereferenceObject(TopDeviceObject);
|
|
||||||
|
|
||||||
/* Return the information */
|
|
||||||
*Information = (PVOID)IoStatusBlock.Information;
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject,
|
IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
|
@ -28,10 +28,6 @@ NTSTATUS
|
||||||
IopSetDeviceInstanceData(HANDLE InstanceKey,
|
IopSetDeviceInstanceData(HANDLE InstanceKey,
|
||||||
PDEVICE_NODE DeviceNode);
|
PDEVICE_NODE DeviceNode);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
|
||||||
PVOID Context);
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject,
|
PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN OUT PKEVENT SyncEvent OPTIONAL,
|
IN OUT PKEVENT SyncEvent OPTIONAL,
|
||||||
|
@ -149,20 +145,20 @@ PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject,
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
IoReportDetectedDevice(
|
||||||
IN INTERFACE_TYPE LegacyBusType,
|
_In_ PDRIVER_OBJECT DriverObject,
|
||||||
IN ULONG BusNumber,
|
_In_ INTERFACE_TYPE LegacyBusType,
|
||||||
IN ULONG SlotNumber,
|
_In_ ULONG BusNumber,
|
||||||
IN PCM_RESOURCE_LIST ResourceList,
|
_In_ ULONG SlotNumber,
|
||||||
IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL,
|
_In_opt_ PCM_RESOURCE_LIST ResourceList,
|
||||||
IN BOOLEAN ResourceAssigned,
|
_In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements,
|
||||||
IN OUT PDEVICE_OBJECT *DeviceObject OPTIONAL)
|
_In_ BOOLEAN ResourceAssigned,
|
||||||
|
_Inout_ PDEVICE_OBJECT *DeviceObject)
|
||||||
{
|
{
|
||||||
PDEVICE_NODE DeviceNode;
|
PDEVICE_NODE DeviceNode;
|
||||||
PDEVICE_OBJECT Pdo;
|
PDEVICE_OBJECT Pdo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HANDLE InstanceKey;
|
HANDLE InstanceKey;
|
||||||
ULONG RequiredLength;
|
|
||||||
UNICODE_STRING ValueName, ServiceLongName, ServiceName;
|
UNICODE_STRING ValueName, ServiceLongName, ServiceName;
|
||||||
WCHAR HardwareId[256];
|
WCHAR HardwareId[256];
|
||||||
PWCHAR IfString;
|
PWCHAR IfString;
|
||||||
|
@ -223,6 +219,7 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We use the caller's PDO if they supplied one */
|
/* We use the caller's PDO if they supplied one */
|
||||||
|
UNICODE_STRING instancePath;
|
||||||
if (DeviceObject && *DeviceObject)
|
if (DeviceObject && *DeviceObject)
|
||||||
{
|
{
|
||||||
Pdo = *DeviceObject;
|
Pdo = *DeviceObject;
|
||||||
|
@ -230,10 +227,7 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Create the PDO */
|
/* Create the PDO */
|
||||||
Status = PnpRootCreateDevice(&ServiceName,
|
Status = PnpRootCreateDevice(&ServiceName, NULL, &Pdo, &instancePath);
|
||||||
NULL,
|
|
||||||
&Pdo,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("PnpRootCreateDevice() failed (Status 0x%08lx)\n", Status);
|
DPRINT("PnpRootCreateDevice() failed (Status 0x%08lx)\n", Status);
|
||||||
|
@ -249,28 +243,7 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
PiInsertDevNode(DeviceNode, IopRootDeviceNode);
|
Status = RtlDuplicateUnicodeString(0, &instancePath, &DeviceNode->InstancePath);
|
||||||
|
|
||||||
/* We're enumerated already */
|
|
||||||
IopDeviceNodeSetFlag(DeviceNode, DNF_ENUMERATED);
|
|
||||||
|
|
||||||
/* We don't call AddDevice for devices reported this way */
|
|
||||||
IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED);
|
|
||||||
|
|
||||||
/* We don't send IRP_MN_START_DEVICE */
|
|
||||||
IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
|
|
||||||
|
|
||||||
/* We need to get device IDs */
|
|
||||||
#if 0
|
|
||||||
IopDeviceNodeSetFlag(DeviceNode, DNF_NEED_QUERY_IDS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This is a legacy driver for this device */
|
|
||||||
IopDeviceNodeSetFlag(DeviceNode, DNF_LEGACY_DRIVER);
|
|
||||||
|
|
||||||
/* Perform a manual configuration of our device */
|
|
||||||
IopActionInterrogateDeviceStack(DeviceNode, DeviceNode->Parent);
|
|
||||||
IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
|
|
||||||
|
|
||||||
/* Open a handle to the instance path key */
|
/* Open a handle to the instance path key */
|
||||||
Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
|
Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
|
||||||
|
@ -321,30 +294,6 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a hardware ID if the driver didn't report one */
|
|
||||||
RtlInitUnicodeString(&ValueName, L"HardwareID");
|
|
||||||
if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
||||||
{
|
|
||||||
/* Just use our most specific compatible ID */
|
|
||||||
IdLength = 0;
|
|
||||||
IdLength += swprintf(&HardwareId[IdLength],
|
|
||||||
L"DETECTED%ls\\%wZ",
|
|
||||||
IfString,
|
|
||||||
&ServiceName);
|
|
||||||
IdLength++;
|
|
||||||
|
|
||||||
HardwareId[IdLength++] = UNICODE_NULL;
|
|
||||||
|
|
||||||
/* Write the value to the registry */
|
|
||||||
Status = ZwSetValueKey(InstanceKey, &ValueName, 0, REG_MULTI_SZ, HardwareId, IdLength * sizeof(WCHAR));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("Failed to write the hardware ID: 0x%x\n", Status);
|
|
||||||
ZwClose(InstanceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign the resources to the device node */
|
/* Assign the resources to the device node */
|
||||||
DeviceNode->BootResources = ResourceList;
|
DeviceNode->BootResources = ResourceList;
|
||||||
DeviceNode->ResourceRequirements = ResourceRequirements;
|
DeviceNode->ResourceRequirements = ResourceRequirements;
|
||||||
|
@ -380,13 +329,11 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
|
||||||
if (DeviceObject && *DeviceObject)
|
if (DeviceObject && *DeviceObject)
|
||||||
PnpRootRegisterDevice(*DeviceObject);
|
PnpRootRegisterDevice(*DeviceObject);
|
||||||
|
|
||||||
/* Report the device's enumeration to umpnpmgr */
|
PiInsertDevNode(DeviceNode, IopRootDeviceNode);
|
||||||
IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED,
|
DeviceNode->Flags |= DNF_MADEUP | DNF_ENUMERATED;
|
||||||
&DeviceNode->InstancePath);
|
|
||||||
|
|
||||||
/* Report the device's arrival to umpnpmgr */
|
// we still need to query IDs, send events and reenumerate this node
|
||||||
IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
|
PiSetDevNodeState(DeviceNode, DeviceNodeStartPostWork);
|
||||||
&DeviceNode->InstancePath);
|
|
||||||
|
|
||||||
DPRINT("Reported device: %S (%wZ)\n", HardwareId, &DeviceNode->InstancePath);
|
DPRINT("Reported device: %S (%wZ)\n", HardwareId, &DeviceNode->InstancePath);
|
||||||
|
|
||||||
|
|
|
@ -698,7 +698,7 @@ ByeBye:
|
||||||
|
|
||||||
// Hacked, because after fixing resource list parsing
|
// Hacked, because after fixing resource list parsing
|
||||||
// we actually detect resource conflicts
|
// we actually detect resource conflicts
|
||||||
return Silent ? Result : FALSE; // Result;
|
return Silent ? Result : FALSE; // Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -1109,20 +1109,17 @@ IopAssignDeviceResources(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG ListSize;
|
ULONG ListSize;
|
||||||
|
|
||||||
IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
|
||||||
|
|
||||||
Status = IopFilterResourceRequirements(DeviceNode);
|
Status = IopFilterResourceRequirements(DeviceNode);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
|
|
||||||
if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements)
|
if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements)
|
||||||
{
|
{
|
||||||
DeviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED;
|
|
||||||
DeviceNode->Flags &= ~DNF_ASSIGNING_RESOURCES;
|
|
||||||
|
|
||||||
/* No resource needed for this device */
|
/* No resource needed for this device */
|
||||||
DeviceNode->ResourceList = NULL;
|
DeviceNode->ResourceList = NULL;
|
||||||
DeviceNode->ResourceListTranslated = NULL;
|
DeviceNode->ResourceListTranslated = NULL;
|
||||||
|
PiSetDevNodeState(DeviceNode, DeviceNodeResourcesAssigned);
|
||||||
|
DeviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1191,9 +1188,7 @@ Finish:
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
|
|
||||||
IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED);
|
PiSetDevNodeState(DeviceNode, DeviceNodeResourcesAssigned);
|
||||||
|
|
||||||
IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
@ -1206,8 +1201,6 @@ ByeBye:
|
||||||
|
|
||||||
DeviceNode->ResourceListTranslated = NULL;
|
DeviceNode->ResourceListTranslated = NULL;
|
||||||
|
|
||||||
IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,7 @@ list(APPEND SOURCE
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/plugplay.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/plugplay.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpdma.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpdma.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpinit.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpinit.c
|
||||||
|
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpirp.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpmgr.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpmgr.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpnotify.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpnotify.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpreport.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpreport.c
|
||||||
|
|
|
@ -164,44 +164,53 @@ extern POBJECT_TYPE NTSYSAPI IoDriverObjectType;
|
||||||
//
|
//
|
||||||
// Device Node Flags
|
// Device Node Flags
|
||||||
//
|
//
|
||||||
#define DNF_PROCESSED 0x00000001
|
|
||||||
#define DNF_STARTED 0x00000002
|
// this set of flags is relevant for w2k3 and newer
|
||||||
#define DNF_START_FAILED 0x00000004
|
// w2k has a completely different set of flags
|
||||||
#define DNF_ENUMERATED 0x00000008
|
#define DNF_MADEUP 0x00000001
|
||||||
#define DNF_DELETED 0x00000010
|
#define DNF_DUPLICATE 0x00000002
|
||||||
#define DNF_MADEUP 0x00000020
|
#define DNF_HAL_NODE 0x00000004
|
||||||
#define DNF_START_REQUEST_PENDING 0x00000040
|
#define DNF_REENUMERATE 0x00000008
|
||||||
#define DNF_NO_RESOURCE_REQUIRED 0x00000080
|
#define DNF_ENUMERATED 0x00000010
|
||||||
#define DNF_INSUFFICIENT_RESOURCES 0x00000100
|
#define DNF_IDS_QUERIED 0x00000020
|
||||||
#define DNF_RESOURCE_ASSIGNED 0x00000200
|
#define DNF_HAS_BOOT_CONFIG 0x00000040
|
||||||
#define DNF_RESOURCE_REPORTED 0x00000400
|
#define DNF_BOOT_CONFIG_RESERVED 0x00000080
|
||||||
#define DNF_HAL_NODE 0x00000800 // ???
|
#define DNF_NO_RESOURCE_REQUIRED 0x00000100
|
||||||
#define DNF_ADDED 0x00001000
|
#define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x00000200
|
||||||
#define DNF_ADD_FAILED 0x00002000
|
#define DNF_RESOURCE_REQUIREMENTS_CHANGED 0x00000400
|
||||||
#define DNF_LEGACY_DRIVER 0x00004000
|
#define DNF_NON_STOPPED_REBALANCE 0x00000800
|
||||||
#define DNF_STOPPED 0x00008000
|
#define DNF_LEGACY_DRIVER 0x00001000
|
||||||
#define DNF_WILL_BE_REMOVED 0x00010000
|
#define DNF_HAS_PROBLEM 0x00002000
|
||||||
|
#define DNF_HAS_PRIVATE_PROBLEM 0x00004000
|
||||||
|
#define DNF_HARDWARE_VERIFICATION 0x00008000
|
||||||
|
#define DNF_DEVICE_GONE 0x00010000
|
||||||
#define DNF_LEGACY_RESOURCE_DEVICENODE 0x00020000
|
#define DNF_LEGACY_RESOURCE_DEVICENODE 0x00020000
|
||||||
#define DNF_NOT_CONFIGURED 0x00040000
|
#define DNF_NEEDS_REBALANCE 0x00040000
|
||||||
#define DNF_REINSTALL 0x00080000
|
#define DNF_LOCKED_FOR_EJECT 0x00080000
|
||||||
#define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x00100000 // ???
|
#define DNF_DRIVER_BLOCKED 0x00100000
|
||||||
#define DNF_DISABLED 0x00200000
|
#define DNF_CHILD_WITH_INVALID_ID 0x00200000
|
||||||
#define DNF_RESTART_OK 0x00400000
|
|
||||||
#define DNF_NEED_RESTART 0x00800000
|
// these flags were added in Vista or later
|
||||||
#define DNF_VISITED 0x01000000
|
#define DNF_ASYNC_START_NOT_SUPPORTED 0x00400000
|
||||||
#define DNF_ASSIGNING_RESOURCES 0x02000000
|
#define DNF_ASYNC_ENUMERATION_NOT_SUPPORTED 0x00800000
|
||||||
#define DNF_BEEING_ENUMERATED 0x04000000
|
#define DNF_LOCKED_FOR_REBALANCE 0x01000000
|
||||||
#define DNF_NEED_ENUMERATION_ONLY 0x08000000
|
#define DNF_UNINSTALLED 0x02000000
|
||||||
#define DNF_LOCKED 0x10000000
|
#define DNF_NO_LOWER_DEVICE_FILTERS 0x04000000
|
||||||
#define DNF_HAS_BOOT_CONFIG 0x20000000
|
#define DNF_NO_LOWER_CLASS_FILTERS 0x08000000
|
||||||
#define DNF_BOOT_CONFIG_RESERVED 0x40000000
|
#define DNF_NO_SERVICE 0x10000000
|
||||||
#define DNF_HAS_PROBLEM 0x80000000 // ???
|
#define DNF_NO_UPPER_DEVICE_FILTERS 0x20000000
|
||||||
|
#define DNF_NO_UPPER_CLASS_FILTERS 0x40000000
|
||||||
|
#define DNF_WAITING_FOR_FDO 0x80000000
|
||||||
|
|
||||||
//
|
//
|
||||||
// Device Node User Flags
|
// Device Node User Flags
|
||||||
//
|
//
|
||||||
|
#define DNUF_WILL_BE_REMOVED 0x0001
|
||||||
#define DNUF_DONT_SHOW_IN_UI 0x0002
|
#define DNUF_DONT_SHOW_IN_UI 0x0002
|
||||||
|
#define DNUF_NEED_RESTART 0x0004
|
||||||
#define DNUF_NOT_DISABLEABLE 0x0008
|
#define DNUF_NOT_DISABLEABLE 0x0008
|
||||||
|
#define DNUF_SHUTDOWN_QUERIED 0x0010
|
||||||
|
#define DNUF_SHUTDOWN_SUBTREE_DONE 0x0020
|
||||||
|
|
||||||
//
|
//
|
||||||
// Internal Option Flags
|
// Internal Option Flags
|
||||||
|
@ -815,6 +824,8 @@ typedef struct _IO_CLIENT_EXTENSION
|
||||||
PVOID ClientIdentificationAddress;
|
PVOID ClientIdentificationAddress;
|
||||||
} IO_CLIENT_EXTENSION, *PIO_CLIENT_EXTENSION;
|
} IO_CLIENT_EXTENSION, *PIO_CLIENT_EXTENSION;
|
||||||
|
|
||||||
|
#define DEVNODE_HISTORY_SIZE 20
|
||||||
|
|
||||||
//
|
//
|
||||||
// Device Node
|
// Device Node
|
||||||
//
|
//
|
||||||
|
@ -829,7 +840,7 @@ typedef struct _DEVICE_NODE
|
||||||
PO_IRP_MANAGER PoIrpManager;
|
PO_IRP_MANAGER PoIrpManager;
|
||||||
PNP_DEVNODE_STATE State;
|
PNP_DEVNODE_STATE State;
|
||||||
PNP_DEVNODE_STATE PreviousState;
|
PNP_DEVNODE_STATE PreviousState;
|
||||||
PNP_DEVNODE_STATE StateHistory[20];
|
PNP_DEVNODE_STATE StateHistory[DEVNODE_HISTORY_SIZE];
|
||||||
ULONG StateHistoryEntry;
|
ULONG StateHistoryEntry;
|
||||||
NTSTATUS CompletionStatus;
|
NTSTATUS CompletionStatus;
|
||||||
PIRP PendingIrp;
|
PIRP PendingIrp;
|
||||||
|
|
Loading…
Reference in a new issue