From b5815efe83ba99eac81269aa28e271bf935ec4fa Mon Sep 17 00:00:00 2001 From: Victor Perevertkin Date: Fri, 19 Jun 2020 23:55:40 +0300 Subject: [PATCH] [NTOS:IO] Move device node functions from pnpmgr/pnpmgr.c to pnpmgr/devnode.c Add SAL2 annotations to functions while moving Convert IopCreateDeviceNode description to a Doxygen format --- ntoskrnl/include/internal/io.h | 9 +- ntoskrnl/io/pnpmgr/devnode.c | 400 +++++++++++++++++++++++++++++++++ ntoskrnl/io/pnpmgr/pnpmgr.c | 384 +------------------------------ ntoskrnl/io/pnpmgr/pnpreport.c | 6 - ntoskrnl/ntos.cmake | 1 + 5 files changed, 410 insertions(+), 390 deletions(-) create mode 100644 ntoskrnl/io/pnpmgr/devnode.c diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index d518e2e6ba9..3f801a0f647 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -762,6 +762,13 @@ NTSTATUS IopTraverseDeviceTree( PDEVICETREE_TRAVERSE_CONTEXT Context); +NTSTATUS +NTAPI +IopCreateDeviceKeyPath( + IN PCUNICODE_STRING RegistryPath, + IN ULONG CreateOptions, + OUT PHANDLE Handle); + // // PnP Routines // @@ -1391,7 +1398,7 @@ IoSetIoCompletion( IN PVOID ApcContext, IN NTSTATUS IoStatus, IN ULONG_PTR IoStatusInformation, - IN BOOLEAN Quota + IN BOOLEAN Quota ); // diff --git a/ntoskrnl/io/pnpmgr/devnode.c b/ntoskrnl/io/pnpmgr/devnode.c new file mode 100644 index 00000000000..6f5e029ceff --- /dev/null +++ b/ntoskrnl/io/pnpmgr/devnode.c @@ -0,0 +1,400 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: PnP manager device tree functions + * COPYRIGHT: Casper S. Hornstrup (chorns@users.sourceforge.net) + * 2007 Hervé Poussineau (hpoussin@reactos.org) + * 2010-2012 Cameron Gutman (cameron.gutman@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +PDEVICE_NODE IopRootDeviceNode; +KSPIN_LOCK IopDeviceTreeLock; + +LONG IopNumberDeviceNodes; + +/* FUNCTIONS *****************************************************************/ + +PDEVICE_NODE +FASTCALL +IopGetDeviceNode( + _In_ PDEVICE_OBJECT DeviceObject) +{ + return ((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode; +} + +PDEVICE_NODE +NTAPI +PipAllocateDeviceNode( + _In_opt_ PDEVICE_OBJECT PhysicalDeviceObject) +{ + PDEVICE_NODE DeviceNode; + PAGED_CODE(); + + /* Allocate it */ + DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE); + if (!DeviceNode) return DeviceNode; + + /* Statistics */ + InterlockedIncrement(&IopNumberDeviceNodes); + + /* Set it up */ + RtlZeroMemory(DeviceNode, sizeof(DEVICE_NODE)); + DeviceNode->InterfaceType = InterfaceTypeUndefined; + DeviceNode->BusNumber = -1; + DeviceNode->ChildInterfaceType = InterfaceTypeUndefined; + DeviceNode->ChildBusNumber = -1; + DeviceNode->ChildBusTypeIndex = -1; +// KeInitializeEvent(&DeviceNode->EnumerationMutex, SynchronizationEvent, TRUE); + InitializeListHead(&DeviceNode->DeviceArbiterList); + InitializeListHead(&DeviceNode->DeviceTranslatorList); + InitializeListHead(&DeviceNode->TargetDeviceNotify); + InitializeListHead(&DeviceNode->DockInfo.ListEntry); + InitializeListHead(&DeviceNode->PendedSetInterfaceState); + + /* Check if there is a PDO */ + if (PhysicalDeviceObject) + { + /* Link it and remove the init flag */ + DeviceNode->PhysicalDeviceObject = PhysicalDeviceObject; + ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = DeviceNode; + PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + } + + /* Return the node */ + return DeviceNode; +} + +/** + * @brief Creates a device node + * + * @param[in] ParentNode Pointer to parent device node + * @param[in] PhysicalDeviceObject Pointer to PDO for device object. Pass NULL to have + * the root device node create one (eg. for legacy drivers) + * @param[in] ServiceName The service (driver) name for a node. Pass NULL + * to set UNKNOWN as a service + * @param[out] DeviceNode Pointer to storage for created device node + * + * @return Status, indicating the result of an operation + */ + +NTSTATUS +IopCreateDeviceNode( + _In_ PDEVICE_NODE ParentNode, + _In_opt_ PDEVICE_OBJECT PhysicalDeviceObject, + _In_opt_ PUNICODE_STRING ServiceName, + _Out_ PDEVICE_NODE *DeviceNode) +{ + PDEVICE_NODE Node; + NTSTATUS Status; + KIRQL OldIrql; + UNICODE_STRING FullServiceName; + UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_"); + UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN"); + UNICODE_STRING KeyName, ClassName; + PUNICODE_STRING ServiceName1; + ULONG LegacyValue; + UNICODE_STRING ClassGUID; + HANDLE InstanceHandle; + + DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n", + ParentNode, PhysicalDeviceObject, ServiceName); + + Node = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE); + if (!Node) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory(Node, sizeof(DEVICE_NODE)); + + if (!ServiceName) + ServiceName1 = &UnknownDeviceName; + else + ServiceName1 = ServiceName; + + if (!PhysicalDeviceObject) + { + FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length + sizeof(UNICODE_NULL); + FullServiceName.Length = 0; + FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength); + if (!FullServiceName.Buffer) + { + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix); + RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1); + RtlUpcaseUnicodeString(&FullServiceName, &FullServiceName, FALSE); + + Status = PnpRootCreateDevice(&FullServiceName, NULL, &PhysicalDeviceObject, &Node->InstancePath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status); + ExFreePool(FullServiceName.Buffer); + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); + return Status; + } + + /* Create the device key for legacy drivers */ + Status = IopCreateDeviceKeyPath(&Node->InstancePath, REG_OPTION_VOLATILE, &InstanceHandle); + if (!NT_SUCCESS(Status)) + { + ExFreePool(FullServiceName.Buffer); + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); + return Status; + } + + Node->ServiceName.MaximumLength = ServiceName1->Length + sizeof(UNICODE_NULL); + Node->ServiceName.Length = 0; + Node->ServiceName.Buffer = ExAllocatePool(PagedPool, Node->ServiceName.MaximumLength); + if (!Node->ServiceName.Buffer) + { + ZwClose(InstanceHandle); + ExFreePool(FullServiceName.Buffer); + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); + return Status; + } + + RtlCopyUnicodeString(&Node->ServiceName, ServiceName1); + + if (ServiceName) + { + RtlInitUnicodeString(&KeyName, L"Service"); + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName->Buffer, ServiceName->Length + sizeof(UNICODE_NULL)); + } + + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString(&KeyName, L"Legacy"); + LegacyValue = 1; + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue)); + + RtlInitUnicodeString(&KeyName, L"ConfigFlags"); + LegacyValue = 0; + ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue)); + + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString(&KeyName, L"Class"); + RtlInitUnicodeString(&ClassName, L"LegacyDriver"); + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL)); + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString(&KeyName, L"ClassGUID"); + RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}"); + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL)); + if (NT_SUCCESS(Status)) + { + // FIXME: Retrieve the real "description" by looking at the "DisplayName" string + // of the corresponding CurrentControlSet\Services\xxx entry for this driver. + RtlInitUnicodeString(&KeyName, L"DeviceDesc"); + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName1->Buffer, ServiceName1->Length + sizeof(UNICODE_NULL)); + } + } + } + } + + ZwClose(InstanceHandle); + ExFreePool(FullServiceName.Buffer); + + if (!NT_SUCCESS(Status)) + { + ExFreePool(Node->ServiceName.Buffer); + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); + return Status; + } + + IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER); + IopDeviceNodeSetFlag(Node, DNF_PROCESSED); + IopDeviceNodeSetFlag(Node, DNF_ADDED); + IopDeviceNodeSetFlag(Node, DNF_STARTED); + } + + Node->PhysicalDeviceObject = PhysicalDeviceObject; + + ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = Node; + + if (ParentNode) + { + KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql); + Node->Parent = ParentNode; + Node->Sibling = NULL; + if (ParentNode->LastChild == NULL) + { + ParentNode->Child = Node; + ParentNode->LastChild = Node; + } + else + { + ParentNode->LastChild->Sibling = Node; + ParentNode->LastChild = Node; + } + KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql); + Node->Level = ParentNode->Level + 1; + } + + PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + + *DeviceNode = Node; + + return STATUS_SUCCESS; +} + +NTSTATUS +IopFreeDeviceNode( + _In_ PDEVICE_NODE DeviceNode) +{ + KIRQL OldIrql; + PDEVICE_NODE PrevSibling = NULL; + + /* All children must be deleted before a parent is deleted */ + ASSERT(!DeviceNode->Child); + ASSERT(DeviceNode->PhysicalDeviceObject); + + KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql); + + /* Get previous sibling */ + if (DeviceNode->Parent && DeviceNode->Parent->Child != DeviceNode) + { + PrevSibling = DeviceNode->Parent->Child; + while (PrevSibling->Sibling != DeviceNode) + PrevSibling = PrevSibling->Sibling; + } + + /* Unlink from parent if it exists */ + if (DeviceNode->Parent) + { + if (DeviceNode->Parent->LastChild == DeviceNode) + { + DeviceNode->Parent->LastChild = PrevSibling; + if (PrevSibling) + PrevSibling->Sibling = NULL; + } + if (DeviceNode->Parent->Child == DeviceNode) + DeviceNode->Parent->Child = DeviceNode->Sibling; + } + + /* Unlink from sibling list */ + if (PrevSibling) + PrevSibling->Sibling = DeviceNode->Sibling; + + KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql); + + RtlFreeUnicodeString(&DeviceNode->InstancePath); + + RtlFreeUnicodeString(&DeviceNode->ServiceName); + + if (DeviceNode->ResourceList) + { + ExFreePool(DeviceNode->ResourceList); + } + + if (DeviceNode->ResourceListTranslated) + { + ExFreePool(DeviceNode->ResourceListTranslated); + } + + if (DeviceNode->ResourceRequirements) + { + ExFreePool(DeviceNode->ResourceRequirements); + } + + if (DeviceNode->BootResources) + { + ExFreePool(DeviceNode->BootResources); + } + + ((PEXTENDED_DEVOBJ_EXTENSION)DeviceNode->PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = NULL; + ExFreePoolWithTag(DeviceNode, TAG_IO_DEVNODE); + + return STATUS_SUCCESS; +} + +static +NTSTATUS +IopTraverseDeviceTreeNode( + _In_ PDEVICETREE_TRAVERSE_CONTEXT Context) +{ + PDEVICE_NODE ParentDeviceNode; + PDEVICE_NODE ChildDeviceNode; + PDEVICE_NODE NextDeviceNode; + NTSTATUS Status; + + /* Copy context data so we don't overwrite it in subsequent calls to this function */ + ParentDeviceNode = Context->DeviceNode; + + /* HACK: Keep a reference to the PDO so we can keep traversing the tree + * if the device is deleted. In a perfect world, children would have to be + * deleted before their parents, and we'd restart the traversal after + * deleting a device node. */ + ObReferenceObject(ParentDeviceNode->PhysicalDeviceObject); + + /* Call the action routine */ + Status = (Context->Action)(ParentDeviceNode, Context->Context); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject); + return Status; + } + + /* Traversal of all children nodes */ + for (ChildDeviceNode = ParentDeviceNode->Child; + ChildDeviceNode != NULL; + ChildDeviceNode = NextDeviceNode) + { + /* HACK: We need this reference to ensure we can get Sibling below. */ + ObReferenceObject(ChildDeviceNode->PhysicalDeviceObject); + + /* Pass the current device node to the action routine */ + Context->DeviceNode = ChildDeviceNode; + + Status = IopTraverseDeviceTreeNode(Context); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(ChildDeviceNode->PhysicalDeviceObject); + ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject); + return Status; + } + + NextDeviceNode = ChildDeviceNode->Sibling; + ObDereferenceObject(ChildDeviceNode->PhysicalDeviceObject); + } + + ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject); + return Status; +} + +NTSTATUS +IopTraverseDeviceTree( + _In_ PDEVICETREE_TRAVERSE_CONTEXT Context) +{ + NTSTATUS Status; + + DPRINT("Context 0x%p\n", Context); + + DPRINT("IopTraverseDeviceTree(DeviceNode 0x%p FirstDeviceNode 0x%p Action %p Context 0x%p)\n", + Context->DeviceNode, Context->FirstDeviceNode, Context->Action, Context->Context); + + /* Start from the specified device node */ + Context->DeviceNode = Context->FirstDeviceNode; + + /* Recursively traverse the device tree */ + Status = IopTraverseDeviceTreeNode(Context); + if (Status == STATUS_UNSUCCESSFUL) + { + /* The action routine just wanted to terminate the traversal with status + code STATUS_SUCCESS */ + Status = STATUS_SUCCESS; + } + + return Status; +} diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 48890364bf9..436e1376f9a 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -15,8 +15,6 @@ /* GLOBALS *******************************************************************/ -PDEVICE_NODE IopRootDeviceNode; -KSPIN_LOCK IopDeviceTreeLock; ERESOURCE PpRegistryDeviceResource; KGUARDED_MUTEX PpDeviceReferenceTableLock; RTL_AVL_TABLE PpDeviceReferenceTable; @@ -24,6 +22,7 @@ RTL_AVL_TABLE PpDeviceReferenceTable; extern ERESOURCE IopDriverLoadResource; extern ULONG ExpInitializationPhase; extern BOOLEAN PnpSystemInit; +extern PDEVICE_NODE IopRootDeviceNode; #define MAX_DEVICE_ID_LEN 200 #define MAX_SEPARATORS_INSTANCEID 0 @@ -40,12 +39,6 @@ KSPIN_LOCK IopDeviceActionLock; /* FUNCTIONS *****************************************************************/ -NTSTATUS -NTAPI -IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, - IN ULONG CreateOptions, - OUT PHANDLE Handle); - VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject); @@ -55,13 +48,6 @@ IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force); PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance); -PDEVICE_NODE -FASTCALL -IopGetDeviceNode(PDEVICE_OBJECT DeviceObject) -{ - return ((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode; -} - VOID IopFixupDeviceId(PWCHAR String) { @@ -1239,252 +1225,6 @@ Quickie: return FoundIndex; } -/* - * DESCRIPTION - * Creates a device node - * - * ARGUMENTS - * ParentNode = Pointer to parent device node - * PhysicalDeviceObject = Pointer to PDO for device object. Pass NULL - * to have the root device node create one - * (eg. for legacy drivers) - * DeviceNode = Pointer to storage for created device node - * - * RETURN VALUE - * Status - */ -NTSTATUS -IopCreateDeviceNode(PDEVICE_NODE ParentNode, - PDEVICE_OBJECT PhysicalDeviceObject, - PUNICODE_STRING ServiceName, - PDEVICE_NODE *DeviceNode) -{ - PDEVICE_NODE Node; - NTSTATUS Status; - KIRQL OldIrql; - UNICODE_STRING FullServiceName; - UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_"); - UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN"); - UNICODE_STRING KeyName, ClassName; - PUNICODE_STRING ServiceName1; - ULONG LegacyValue; - UNICODE_STRING ClassGUID; - HANDLE InstanceHandle; - - DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n", - ParentNode, PhysicalDeviceObject, ServiceName); - - Node = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE); - if (!Node) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlZeroMemory(Node, sizeof(DEVICE_NODE)); - - if (!ServiceName) - ServiceName1 = &UnknownDeviceName; - else - ServiceName1 = ServiceName; - - if (!PhysicalDeviceObject) - { - FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length + sizeof(UNICODE_NULL); - FullServiceName.Length = 0; - FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength); - if (!FullServiceName.Buffer) - { - ExFreePoolWithTag(Node, TAG_IO_DEVNODE); - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix); - RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1); - RtlUpcaseUnicodeString(&FullServiceName, &FullServiceName, FALSE); - - Status = PnpRootCreateDevice(&FullServiceName, NULL, &PhysicalDeviceObject, &Node->InstancePath); - if (!NT_SUCCESS(Status)) - { - DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status); - ExFreePool(FullServiceName.Buffer); - ExFreePoolWithTag(Node, TAG_IO_DEVNODE); - return Status; - } - - /* Create the device key for legacy drivers */ - Status = IopCreateDeviceKeyPath(&Node->InstancePath, REG_OPTION_VOLATILE, &InstanceHandle); - if (!NT_SUCCESS(Status)) - { - ExFreePool(FullServiceName.Buffer); - ExFreePoolWithTag(Node, TAG_IO_DEVNODE); - return Status; - } - - Node->ServiceName.MaximumLength = ServiceName1->Length + sizeof(UNICODE_NULL); - Node->ServiceName.Length = 0; - Node->ServiceName.Buffer = ExAllocatePool(PagedPool, Node->ServiceName.MaximumLength); - if (!Node->ServiceName.Buffer) - { - ZwClose(InstanceHandle); - ExFreePool(FullServiceName.Buffer); - ExFreePoolWithTag(Node, TAG_IO_DEVNODE); - return Status; - } - - RtlCopyUnicodeString(&Node->ServiceName, ServiceName1); - - if (ServiceName) - { - RtlInitUnicodeString(&KeyName, L"Service"); - Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName->Buffer, ServiceName->Length + sizeof(UNICODE_NULL)); - } - - if (NT_SUCCESS(Status)) - { - RtlInitUnicodeString(&KeyName, L"Legacy"); - LegacyValue = 1; - Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue)); - - RtlInitUnicodeString(&KeyName, L"ConfigFlags"); - LegacyValue = 0; - ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue)); - - if (NT_SUCCESS(Status)) - { - RtlInitUnicodeString(&KeyName, L"Class"); - RtlInitUnicodeString(&ClassName, L"LegacyDriver"); - Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL)); - if (NT_SUCCESS(Status)) - { - RtlInitUnicodeString(&KeyName, L"ClassGUID"); - RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}"); - Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL)); - if (NT_SUCCESS(Status)) - { - // FIXME: Retrieve the real "description" by looking at the "DisplayName" string - // of the corresponding CurrentControlSet\Services\xxx entry for this driver. - RtlInitUnicodeString(&KeyName, L"DeviceDesc"); - Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName1->Buffer, ServiceName1->Length + sizeof(UNICODE_NULL)); - } - } - } - } - - ZwClose(InstanceHandle); - ExFreePool(FullServiceName.Buffer); - - if (!NT_SUCCESS(Status)) - { - ExFreePool(Node->ServiceName.Buffer); - ExFreePoolWithTag(Node, TAG_IO_DEVNODE); - return Status; - } - - IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER); - IopDeviceNodeSetFlag(Node, DNF_PROCESSED); - IopDeviceNodeSetFlag(Node, DNF_ADDED); - IopDeviceNodeSetFlag(Node, DNF_STARTED); - } - - Node->PhysicalDeviceObject = PhysicalDeviceObject; - - ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = Node; - - if (ParentNode) - { - KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql); - Node->Parent = ParentNode; - Node->Sibling = NULL; - if (ParentNode->LastChild == NULL) - { - ParentNode->Child = Node; - ParentNode->LastChild = Node; - } - else - { - ParentNode->LastChild->Sibling = Node; - ParentNode->LastChild = Node; - } - KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql); - Node->Level = ParentNode->Level + 1; - } - - PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - - *DeviceNode = Node; - - return STATUS_SUCCESS; -} - -NTSTATUS -IopFreeDeviceNode(PDEVICE_NODE DeviceNode) -{ - KIRQL OldIrql; - PDEVICE_NODE PrevSibling = NULL; - - /* All children must be deleted before a parent is deleted */ - ASSERT(!DeviceNode->Child); - ASSERT(DeviceNode->PhysicalDeviceObject); - - KeAcquireSpinLock(&IopDeviceTreeLock, &OldIrql); - - /* Get previous sibling */ - if (DeviceNode->Parent && DeviceNode->Parent->Child != DeviceNode) - { - PrevSibling = DeviceNode->Parent->Child; - while (PrevSibling->Sibling != DeviceNode) - PrevSibling = PrevSibling->Sibling; - } - - /* Unlink from parent if it exists */ - if (DeviceNode->Parent) - { - if (DeviceNode->Parent->LastChild == DeviceNode) - { - DeviceNode->Parent->LastChild = PrevSibling; - if (PrevSibling) - PrevSibling->Sibling = NULL; - } - if (DeviceNode->Parent->Child == DeviceNode) - DeviceNode->Parent->Child = DeviceNode->Sibling; - } - - /* Unlink from sibling list */ - if (PrevSibling) - PrevSibling->Sibling = DeviceNode->Sibling; - - KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql); - - RtlFreeUnicodeString(&DeviceNode->InstancePath); - - RtlFreeUnicodeString(&DeviceNode->ServiceName); - - if (DeviceNode->ResourceList) - { - ExFreePool(DeviceNode->ResourceList); - } - - if (DeviceNode->ResourceListTranslated) - { - ExFreePool(DeviceNode->ResourceListTranslated); - } - - if (DeviceNode->ResourceRequirements) - { - ExFreePool(DeviceNode->ResourceRequirements); - } - - if (DeviceNode->BootResources) - { - ExFreePool(DeviceNode->BootResources); - } - - ((PEXTENDED_DEVOBJ_EXTENSION)DeviceNode->PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = NULL; - ExFreePoolWithTag(DeviceNode, TAG_IO_DEVNODE); - - return STATUS_SUCCESS; -} - NTSTATUS NTAPI IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, @@ -1583,85 +1323,6 @@ IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, return IoStatusBlock->Status; } -NTSTATUS -IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context) -{ - PDEVICE_NODE ParentDeviceNode; - PDEVICE_NODE ChildDeviceNode; - PDEVICE_NODE NextDeviceNode; - NTSTATUS Status; - - /* Copy context data so we don't overwrite it in subsequent calls to this function */ - ParentDeviceNode = Context->DeviceNode; - - /* HACK: Keep a reference to the PDO so we can keep traversing the tree - * if the device is deleted. In a perfect world, children would have to be - * deleted before their parents, and we'd restart the traversal after - * deleting a device node. */ - ObReferenceObject(ParentDeviceNode->PhysicalDeviceObject); - - /* Call the action routine */ - Status = (Context->Action)(ParentDeviceNode, Context->Context); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject); - return Status; - } - - /* Traversal of all children nodes */ - for (ChildDeviceNode = ParentDeviceNode->Child; - ChildDeviceNode != NULL; - ChildDeviceNode = NextDeviceNode) - { - /* HACK: We need this reference to ensure we can get Sibling below. */ - ObReferenceObject(ChildDeviceNode->PhysicalDeviceObject); - - /* Pass the current device node to the action routine */ - Context->DeviceNode = ChildDeviceNode; - - Status = IopTraverseDeviceTreeNode(Context); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(ChildDeviceNode->PhysicalDeviceObject); - ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject); - return Status; - } - - NextDeviceNode = ChildDeviceNode->Sibling; - ObDereferenceObject(ChildDeviceNode->PhysicalDeviceObject); - } - - ObDereferenceObject(ParentDeviceNode->PhysicalDeviceObject); - return Status; -} - - -NTSTATUS -IopTraverseDeviceTree(PDEVICETREE_TRAVERSE_CONTEXT Context) -{ - NTSTATUS Status; - - DPRINT("Context 0x%p\n", Context); - - DPRINT("IopTraverseDeviceTree(DeviceNode 0x%p FirstDeviceNode 0x%p Action %p Context 0x%p)\n", - Context->DeviceNode, Context->FirstDeviceNode, Context->Action, Context->Context); - - /* Start from the specified device node */ - Context->DeviceNode = Context->FirstDeviceNode; - - /* Recursively traverse the device tree */ - Status = IopTraverseDeviceTreeNode(Context); - if (Status == STATUS_UNSUCCESSFUL) - { - /* The action routine just wanted to terminate the traversal with status - code STATUS_SUCCESS */ - Status = STATUS_SUCCESS; - } - - return Status; -} - - /* * IopCreateDeviceKeyPath * @@ -4038,49 +3699,6 @@ PpInitSystem(VOID) } } -LONG IopNumberDeviceNodes; - -PDEVICE_NODE -NTAPI -PipAllocateDeviceNode(IN PDEVICE_OBJECT PhysicalDeviceObject) -{ - PDEVICE_NODE DeviceNode; - PAGED_CODE(); - - /* Allocate it */ - DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE); - if (!DeviceNode) return DeviceNode; - - /* Statistics */ - InterlockedIncrement(&IopNumberDeviceNodes); - - /* Set it up */ - RtlZeroMemory(DeviceNode, sizeof(DEVICE_NODE)); - DeviceNode->InterfaceType = InterfaceTypeUndefined; - DeviceNode->BusNumber = -1; - DeviceNode->ChildInterfaceType = InterfaceTypeUndefined; - DeviceNode->ChildBusNumber = -1; - DeviceNode->ChildBusTypeIndex = -1; -// KeInitializeEvent(&DeviceNode->EnumerationMutex, SynchronizationEvent, TRUE); - InitializeListHead(&DeviceNode->DeviceArbiterList); - InitializeListHead(&DeviceNode->DeviceTranslatorList); - InitializeListHead(&DeviceNode->TargetDeviceNotify); - InitializeListHead(&DeviceNode->DockInfo.ListEntry); - InitializeListHead(&DeviceNode->PendedSetInterfaceState); - - /* Check if there is a PDO */ - if (PhysicalDeviceObject) - { - /* Link it and remove the init flag */ - DeviceNode->PhysicalDeviceObject = PhysicalDeviceObject; - ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = DeviceNode; - PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - } - - /* Return the node */ - return DeviceNode; -} - /* PUBLIC FUNCTIONS **********************************************************/ NTSTATUS diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c index a9a9b3fab68..b16f70afdc4 100644 --- a/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/ntoskrnl/io/pnpmgr/pnpreport.c @@ -24,12 +24,6 @@ typedef struct _INTERNAL_WORK_QUEUE_ITEM PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure; } INTERNAL_WORK_QUEUE_ITEM, *PINTERNAL_WORK_QUEUE_ITEM; -NTSTATUS -NTAPI -IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, - IN ULONG CreateOptions, - OUT PHANDLE Handle); - NTSTATUS IopSetDeviceInstanceData(HANDLE InstanceKey, PDEVICE_NODE DeviceNode); diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake index b2224bed4c7..a938a42b783 100644 --- a/ntoskrnl/ntos.cmake +++ b/ntoskrnl/ntos.cmake @@ -152,6 +152,7 @@ list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/io/iomgr/util.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/iomgr/volume.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/arbs.c + ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/devnode.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/plugplay.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpdma.c ${REACTOS_SOURCE_DIR}/ntoskrnl/io/pnpmgr/pnpinit.c