From 9ffc373bf625d7210da745d559d4535df84b4133 Mon Sep 17 00:00:00 2001 From: Justin Miller Date: Sun, 19 Jul 2026 10:29:04 -0700 Subject: [PATCH] [NTOS:IO][SDK:DRIVERS][FORMATTING] Start SDK:Arbiter from scratch (#9270) Same idea as 094b7d9 and Final step that doesn't require rtlrange improvements --- ntoskrnl/io/pnpmgr/arb/arbbus.c | 8 +- ntoskrnl/io/pnpmgr/arb/arbdma.c | 8 +- ntoskrnl/io/pnpmgr/arb/arbirq.c | 8 +- ntoskrnl/io/pnpmgr/arb/arbmem.c | 8 +- ntoskrnl/io/pnpmgr/arb/arbport.c | 8 +- sdk/lib/drivers/arbiter/arbiter.c | 428 +++++++++++++++++++----------- sdk/lib/drivers/arbiter/arbiter.h | 205 +++++++++----- 7 files changed, 428 insertions(+), 245 deletions(-) diff --git a/ntoskrnl/io/pnpmgr/arb/arbbus.c b/ntoskrnl/io/pnpmgr/arb/arbbus.c index 72269064838..82a19a9aca2 100644 --- a/ntoskrnl/io/pnpmgr/arb/arbbus.c +++ b/ntoskrnl/io/pnpmgr/arb/arbbus.c @@ -2,7 +2,7 @@ * PROJECT: ReactOS Kernel * LICENSE: MIT (https://spdx.org/licenses/MIT) * PURPOSE: PnP manager Root Bus Arbiter - * COPYRIGHT: Copyright 2025 Justin Miller + * COPYRIGHT: Copyright 2025-2026 Justin Miller */ /* INCLUDES *****************************************************************/ @@ -23,8 +23,8 @@ IopArbBusNumberUnpackRequirements( _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor, _Out_ PUINT64 OutMinimumAddress, _Out_ PUINT64 OutMaximumAddress, - _Out_ PUINT32 OutLength, - _Out_ PUINT32 OutAlignment) + _Out_ PUINT64 OutLength, + _Out_ PUINT64 OutAlignment) { PAGED_CODE(); DPRINT("IopArbBusNumberUnpackRequirements: IoDescriptor: %p, OutMinimumAddress: %p, OutMaximumAddress: %p, OutLength: %p, OutAlignment: %p\n", @@ -60,7 +60,7 @@ NTAPI IopArbBusNumberUnpackResource( _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor, _Out_ PUINT64 Start, - _Out_ PUINT32 OutLength) + _Out_ PUINT64 OutLength) { PAGED_CODE(); DPRINT("IopArbBusNumberUnpackResource: CmDescriptor: %p, Start: %p, OutLength: %p\n", diff --git a/ntoskrnl/io/pnpmgr/arb/arbdma.c b/ntoskrnl/io/pnpmgr/arb/arbdma.c index 752eab51c43..cc1a5fd3052 100644 --- a/ntoskrnl/io/pnpmgr/arb/arbdma.c +++ b/ntoskrnl/io/pnpmgr/arb/arbdma.c @@ -2,7 +2,7 @@ * PROJECT: ReactOS Kernel * LICENSE: MIT (https://spdx.org/licenses/MIT) * PURPOSE: PnP manager Root DMA Arbiter - * COPYRIGHT: Copyright 2025 Justin Miller + * COPYRIGHT: Copyright 2025-2026 Justin Miller */ /* INCLUDES *****************************************************************/ @@ -23,8 +23,8 @@ IopArbDmaUnpackRequirements( _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor, _Out_ PUINT64 OutMinimumAddress, _Out_ PUINT64 OutMaximumAddress, - _Out_ PUINT32 OutLength, - _Out_ PUINT32 OutAlignment) + _Out_ PUINT64 OutLength, + _Out_ PUINT64 OutAlignment) { PAGED_CODE(); DPRINT("IopArbDmaUnpackRequirements: IoDescriptor: %p, OutMinimumAddress: %p, OutMaximumAddress: %p, OutLength: %p, OutAlignment: %p\n", @@ -60,7 +60,7 @@ NTAPI IopArbDmaUnpackResource( _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor, _Out_ PUINT64 Start, - _Out_ PUINT32 OutLength) + _Out_ PUINT64 OutLength) { PAGED_CODE(); DPRINT("IopArbDmaUnpackResource: CmDescriptor: %p, Start: %p, OutLength: %p\n", diff --git a/ntoskrnl/io/pnpmgr/arb/arbirq.c b/ntoskrnl/io/pnpmgr/arb/arbirq.c index d3a54247478..324b3387abc 100644 --- a/ntoskrnl/io/pnpmgr/arb/arbirq.c +++ b/ntoskrnl/io/pnpmgr/arb/arbirq.c @@ -2,7 +2,7 @@ * PROJECT: ReactOS Kernel * LICENSE: MIT (https://spdx.org/licenses/MIT) * PURPOSE: PnP manager Root IRQ Arbiter - * COPYRIGHT: Copyright 2025 Justin Miller + * COPYRIGHT: Copyright 2025-2026 Justin Miller */ /* INCLUDES *****************************************************************/ @@ -23,8 +23,8 @@ IopArbIrqUnpackRequirements( _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor, _Out_ PUINT64 OutMinimumAddress, _Out_ PUINT64 OutMaximumAddress, - _Out_ PUINT32 OutLength, - _Out_ PUINT32 OutAlignment) + _Out_ PUINT64 OutLength, + _Out_ PUINT64 OutAlignment) { PAGED_CODE(); DPRINT("IopArbIrqUnpackRequirements: IoDescriptor: %p, OutMinimumAddress: %p, OutMaximumAddress: %p, OutLength: %p, OutAlignment: %p\n", @@ -60,7 +60,7 @@ NTAPI IopArbIrqUnpackResource( _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor, _Out_ PUINT64 Start, - _Out_ PUINT32 OutLength) + _Out_ PUINT64 OutLength) { PAGED_CODE(); DPRINT("IopArbIrqUnpackResource: CmDescriptor: %p, Start: %p, OutLength: %p\n", diff --git a/ntoskrnl/io/pnpmgr/arb/arbmem.c b/ntoskrnl/io/pnpmgr/arb/arbmem.c index 43dec6ff781..8629f0676db 100644 --- a/ntoskrnl/io/pnpmgr/arb/arbmem.c +++ b/ntoskrnl/io/pnpmgr/arb/arbmem.c @@ -2,7 +2,7 @@ * PROJECT: ReactOS Kernel * LICENSE: MIT (https://spdx.org/licenses/MIT) * PURPOSE: PnP manager Root Memory Arbiter - * COPYRIGHT: Copyright 2025 Justin Miller + * COPYRIGHT: Copyright 2025-2026 Justin Miller */ /* INCLUDES *****************************************************************/ @@ -23,8 +23,8 @@ IopArbMemUnpackRequirements( _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor, _Out_ PUINT64 OutMinimumAddress, _Out_ PUINT64 OutMaximumAddress, - _Out_ PUINT32 OutLength, - _Out_ PUINT32 OutAlignment) + _Out_ PUINT64 OutLength, + _Out_ PUINT64 OutAlignment) { PAGED_CODE(); DPRINT("IopArbMemUnpackRequirements: IoDescriptor: %p, OutMinimumAddress: %p, OutMaximumAddress: %p, OutLength: %p, OutAlignment: %p\n", @@ -60,7 +60,7 @@ NTAPI IopArbMemUnpackResource( _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor, _Out_ PUINT64 Start, - _Out_ PUINT32 OutLength) + _Out_ PUINT64 OutLength) { PAGED_CODE(); DPRINT("IopArbMemUnpackResource: CmDescriptor: %p, Start: %p, OutLength: %p\n", diff --git a/ntoskrnl/io/pnpmgr/arb/arbport.c b/ntoskrnl/io/pnpmgr/arb/arbport.c index 1af44f05388..2c2dc356244 100644 --- a/ntoskrnl/io/pnpmgr/arb/arbport.c +++ b/ntoskrnl/io/pnpmgr/arb/arbport.c @@ -2,7 +2,7 @@ * PROJECT: ReactOS Kernel * LICENSE: MIT (https://spdx.org/licenses/MIT) * PURPOSE: PnP manager Root Port Arbiter - * COPYRIGHT: Copyright 2025 Justin Miller + * COPYRIGHT: Copyright 2025-2026 Justin Miller */ /* INCLUDES *****************************************************************/ @@ -23,8 +23,8 @@ IopPortMemUnpackRequirements( _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor, _Out_ PUINT64 OutMinimumAddress, _Out_ PUINT64 OutMaximumAddress, - _Out_ PUINT32 OutLength, - _Out_ PUINT32 OutAlignment) + _Out_ PUINT64 OutLength, + _Out_ PUINT64 OutAlignment) { PAGED_CODE(); DPRINT("IopPortMemUnpackRequirements: IoDescriptor: %p, OutMinimumAddress: %p, OutMaximumAddress: %p, OutLength: %p, OutAlignment: %p\n", @@ -60,7 +60,7 @@ NTAPI IopPortMemUnpackResource( _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor, _Out_ PUINT64 Start, - _Out_ PUINT32 OutLength) + _Out_ PUINT64 OutLength) { PAGED_CODE(); DPRINT("IopPortMemUnpackResource: CmDescriptor: %p, Start: %p, OutLength: %p\n", diff --git a/sdk/lib/drivers/arbiter/arbiter.c b/sdk/lib/drivers/arbiter/arbiter.c index e4e1c719ac7..7ca2fd85de0 100644 --- a/sdk/lib/drivers/arbiter/arbiter.c +++ b/sdk/lib/drivers/arbiter/arbiter.c @@ -1,8 +1,8 @@ /* - * PROJECT: ReactOS Kernel&Driver SDK - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) - * PURPOSE: Hardware Resources Arbiter Library - * COPYRIGHT: Copyright 2020 Vadim Galyant + * PROJECT: ReactOS Arbitrartion Library + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Generic Arbiter Library + * COPYRIGHT: Copyright 2026 Justin Miller */ /* INCLUDES *******************************************************************/ @@ -14,18 +14,19 @@ #define NDEBUG #include -/* GLOBALS ********************************************************************/ - -/* DATA **********************************************************************/ - -/* FUNCTIONS ******************************************************************/ +#define ARBITER_SIG 'sbrA' +#define TAG_ARBITER 'ibrA' +/* + * TODO: ArbTestAllocation-ArbQueryConflict have some signature rewrites + * that need to happen when we retarget to vista. + */ CODE_SEG("PAGE") NTSTATUS NTAPI ArbTestAllocation( _In_ PARBITER_INSTANCE Arbiter, - _In_ PLIST_ENTRY ArbitrationList) + _Inout_ PLIST_ENTRY ArbitrationList) { PAGED_CODE(); @@ -38,7 +39,7 @@ NTSTATUS NTAPI ArbRetestAllocation( _In_ PARBITER_INSTANCE Arbiter, - _In_ PLIST_ENTRY ArbitrationList) + _Inout_ PLIST_ENTRY ArbitrationList) { PAGED_CODE(); @@ -46,6 +47,66 @@ ArbRetestAllocation( return STATUS_NOT_IMPLEMENTED; } +CODE_SEG("PAGE") +NTSTATUS +NTAPI +ArbBootAllocation( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PLIST_ENTRY ArbitrationList) +{ + PAGED_CODE(); + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +CODE_SEG("PAGE") +NTSTATUS +NTAPI +ArbAddReserved( + _In_ PARBITER_INSTANCE Arbiter, + _In_opt_ PIO_RESOURCE_DESCRIPTOR Requirement, + _In_opt_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource) +{ + PAGED_CODE(); + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +CODE_SEG("PAGE") +NTSTATUS +NTAPI +ArbQueryConflict( + _In_ PARBITER_INSTANCE Arbiter, + _In_ PDEVICE_OBJECT PhysicalDeviceObject, + _In_ PIO_RESOURCE_DESCRIPTOR ConflictingResource, + _Out_ PULONG ConflictCount, + _Out_ PARBITER_CONFLICT_INFO *Conflicts) +{ + PAGED_CODE(); + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +#if (NTDDI_VERSION >= NTDDI_VISTA) +CODE_SEG("PAGE") +NTSTATUS +NTAPI +ArbInitializeRangeList( + _In_ PARBITER_INSTANCE Arbiter, + _In_ ULONG ResourceCount, + _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Resources, + _Inout_ PRTL_RANGE_LIST RangeList) +{ + PAGED_CODE(); + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} +#endif + CODE_SEG("PAGE") NTSTATUS NTAPI @@ -70,12 +131,12 @@ ArbRollbackAllocation( return STATUS_NOT_IMPLEMENTED; } -/* FIXME: the prototype is not correct yet. */ CODE_SEG("PAGE") NTSTATUS NTAPI -ArbAddReserved( - _In_ PARBITER_INSTANCE Arbiter) +ArbStartArbiter( + _In_ PARBITER_INSTANCE Arbiter, + _In_ PCM_RESOURCE_LIST StartResources) { PAGED_CODE(); @@ -92,6 +153,7 @@ ArbPreprocessEntry( { PAGED_CODE(); + UNIMPLEMENTED; return STATUS_SUCCESS; } @@ -108,6 +170,18 @@ ArbAllocateEntry( return STATUS_NOT_IMPLEMENTED; } +CODE_SEG("PAGE") +NTSTATUS +NTAPI +ArbSortArbitrationList( + _Inout_ PLIST_ENTRY ArbitrationList) +{ + PAGED_CODE(); + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + CODE_SEG("PAGE") BOOLEAN NTAPI @@ -158,79 +232,38 @@ ArbBacktrackAllocation( UNIMPLEMENTED; } -/* FIXME: the prototype is not correct yet. */ CODE_SEG("PAGE") -NTSTATUS +VOID +NTAPI +ArbConfirmAllocation( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PARBITER_ALLOCATION_STATE ArbState) +{ + PAGED_CODE(); + + UNIMPLEMENTED; +} + +CODE_SEG("PAGE") +BOOLEAN NTAPI ArbOverrideConflict( - _In_ PARBITER_INSTANCE Arbiter) -{ - PAGED_CODE(); - - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -CODE_SEG("PAGE") -NTSTATUS -NTAPI -ArbBootAllocation( _In_ PARBITER_INSTANCE Arbiter, - _In_ PLIST_ENTRY ArbitrationList) + _Inout_ PARBITER_ALLOCATION_STATE ArbState) { PAGED_CODE(); UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* FIXME: the prototype is not correct yet. */ -CODE_SEG("PAGE") -NTSTATUS -NTAPI -ArbQueryConflict( - _In_ PARBITER_INSTANCE Arbiter) -{ - PAGED_CODE(); - - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -/* FIXME: the prototype is not correct yet. */ -CODE_SEG("PAGE") -NTSTATUS -NTAPI -ArbStartArbiter( - _In_ PARBITER_INSTANCE Arbiter) -{ - PAGED_CODE(); - - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + return FALSE; } CODE_SEG("PAGE") NTSTATUS NTAPI -ArbAddOrdering( - _Out_ PARBITER_ORDERING_LIST OrderList, - _In_ UINT64 MinimumAddress, - _In_ UINT64 MaximumAddress) -{ - PAGED_CODE(); - - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -CODE_SEG("PAGE") -NTSTATUS -NTAPI -ArbPruneOrdering( - _Out_ PARBITER_ORDERING_LIST OrderingList, - _In_ UINT64 MinimumAddress, - _In_ UINT64 MaximumAddress) +ArbArbiterHandler( + _In_ PVOID Context, + _In_ ARBITER_ACTION Action, + _Inout_ PARBITER_PARAMETERS Parameters) { PAGED_CODE(); @@ -242,7 +275,7 @@ CODE_SEG("PAGE") NTSTATUS NTAPI ArbInitializeOrderingList( - _Out_ PARBITER_ORDERING_LIST OrderList) + _Out_ PARBITER_ORDERING_LIST OrderingList) { PAGED_CODE(); @@ -254,21 +287,62 @@ CODE_SEG("PAGE") VOID NTAPI ArbFreeOrderingList( - _Out_ PARBITER_ORDERING_LIST OrderList) + _Inout_ PARBITER_ORDERING_LIST OrderingList) { PAGED_CODE(); UNIMPLEMENTED; } +CODE_SEG("PAGE") +NTSTATUS +NTAPI +ArbCopyOrderingList( + _Out_ PARBITER_ORDERING_LIST Destination, + _In_ PARBITER_ORDERING_LIST Source) +{ + PAGED_CODE(); + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +CODE_SEG("PAGE") +NTSTATUS +NTAPI +ArbAddOrdering( + _Inout_ PARBITER_ORDERING_LIST OrderingList, + _In_ UINT64 Start, + _In_ UINT64 End) +{ + PAGED_CODE(); + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +CODE_SEG("PAGE") +NTSTATUS +NTAPI +ArbPruneOrdering( + _Inout_ PARBITER_ORDERING_LIST OrderingList, + _In_ UINT64 Start, + _In_ UINT64 End) +{ + PAGED_CODE(); + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + CODE_SEG("PAGE") NTSTATUS NTAPI ArbBuildAssignmentOrdering( - _Inout_ PARBITER_INSTANCE ArbInstance, - _In_ PCWSTR OrderName, - _In_ PCWSTR ReservedOrderName, - _In_ PARB_TRANSLATE_ORDERING TranslateOrderingFunction) + _Inout_ PARBITER_INSTANCE Arbiter, + _In_ PCWSTR AllocationOrderName, + _In_ PCWSTR ReservedResourcesName, + _In_opt_ PARB_TRANSLATE_ORDERING TranslateOrderingFunction) { PAGED_CODE(); @@ -276,6 +350,50 @@ ArbBuildAssignmentOrdering( return STATUS_SUCCESS; } +CODE_SEG("PAGE") +VOID +NTAPI +ArbDeleteArbiterInstance( + _In_ PARBITER_INSTANCE Arbiter) +{ + PAGED_CODE(); + + if (Arbiter->PossibleAllocation) + { + RtlFreeRangeList(Arbiter->PossibleAllocation); + ExFreePoolWithTag(Arbiter->PossibleAllocation, TAG_ARBITER); + Arbiter->PossibleAllocation = NULL; + } + + if (Arbiter->Allocation) + { + RtlFreeRangeList(Arbiter->Allocation); + ExFreePoolWithTag(Arbiter->Allocation, TAG_ARBITER); + Arbiter->Allocation = NULL; + } + + if (Arbiter->AllocationStack) + { + ExFreePoolWithTag(Arbiter->AllocationStack, TAG_ARBITER); + Arbiter->AllocationStack = NULL; + Arbiter->AllocationStackMaxSize = 0; + } + +#if (NTDDI_VERSION >= NTDDI_VISTA) + if (Arbiter->TransactionEvent) + { + ExFreePoolWithTag(Arbiter->TransactionEvent, TAG_ARBITER); + Arbiter->TransactionEvent = NULL; + } +#endif + + if (Arbiter->MutexEvent) + { + ExFreePoolWithTag(Arbiter->MutexEvent, TAG_ARBITER); + Arbiter->MutexEvent = NULL; + } +} + CODE_SEG("PAGE") NTSTATUS NTAPI @@ -301,106 +419,104 @@ ArbInitializeArbiterInstance( ASSERT(Arbiter->PossibleAllocation == NULL); ASSERT(Arbiter->AllocationStack == NULL); - Arbiter->Signature = ARBITER_SIGNATURE; + Arbiter->Signature = ARBITER_SIG; Arbiter->BusDeviceObject = BusDeviceObject; - - Arbiter->MutexEvent = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_ARBITER); - if (!Arbiter->MutexEvent) - { - DPRINT1("ArbInitializeArbiterInstance: STATUS_INSUFFICIENT_RESOURCES\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - KeInitializeEvent(Arbiter->MutexEvent, SynchronizationEvent, TRUE); - - Arbiter->AllocationStack = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, TAG_ARB_ALLOCATION); - if (!Arbiter->AllocationStack) - { - DPRINT1("ArbInitializeArbiterInstance: STATUS_INSUFFICIENT_RESOURCES\n"); - ExFreePoolWithTag(Arbiter->MutexEvent, TAG_ARBITER); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Arbiter->AllocationStackMaxSize = PAGE_SIZE; - - Arbiter->Allocation = ExAllocatePoolWithTag(PagedPool, sizeof(RTL_RANGE_LIST), TAG_ARB_RANGE); - if (!Arbiter->Allocation) - { - DPRINT1("ArbInitializeArbiterInstance: STATUS_INSUFFICIENT_RESOURCES\n"); - ExFreePoolWithTag(Arbiter->AllocationStack, TAG_ARB_ALLOCATION); - ExFreePoolWithTag(Arbiter->MutexEvent, TAG_ARBITER); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Arbiter->PossibleAllocation = ExAllocatePoolWithTag(PagedPool, sizeof(RTL_RANGE_LIST), TAG_ARB_RANGE); - if (!Arbiter->PossibleAllocation) - { - DPRINT1("ArbInitializeArbiterInstance: STATUS_INSUFFICIENT_RESOURCES\n"); - ExFreePoolWithTag(Arbiter->Allocation, TAG_ARB_RANGE); - ExFreePoolWithTag(Arbiter->AllocationStack, TAG_ARB_ALLOCATION); - ExFreePoolWithTag(Arbiter->MutexEvent, TAG_ARBITER); - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlInitializeRangeList(Arbiter->Allocation); - RtlInitializeRangeList(Arbiter->PossibleAllocation); - Arbiter->Name = ArbiterName; Arbiter->ResourceType = ResourceType; Arbiter->TransactionInProgress = FALSE; +#if (NTDDI_VERSION >= NTDDI_VISTA) + Arbiter->OrderingName = OrderName; +#endif + + /* The per-instance lock: a signaled synchronization event used as a mutex. */ + Arbiter->MutexEvent = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_ARBITER); + if (!Arbiter->MutexEvent) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Failure; + } + KeInitializeEvent(Arbiter->MutexEvent, SynchronizationEvent, TRUE); + +#if (NTDDI_VERSION >= NTDDI_VISTA) + /* Vista+: a notification event exposing whether a Test is outstanding. */ + Arbiter->TransactionEvent = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_ARBITER); + if (!Arbiter->TransactionEvent) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Failure; + } + KeInitializeEvent(Arbiter->TransactionEvent, NotificationEvent, TRUE); +#endif + + Arbiter->AllocationStack = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, TAG_ARBITER); + if (!Arbiter->AllocationStack) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Failure; + } + Arbiter->AllocationStackMaxSize = PAGE_SIZE; + Arbiter->Allocation = ExAllocatePoolWithTag(PagedPool, sizeof(RTL_RANGE_LIST), TAG_ARBITER); + if (!Arbiter->Allocation) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Failure; + } + RtlInitializeRangeList(Arbiter->Allocation); + + Arbiter->PossibleAllocation = ExAllocatePoolWithTag(PagedPool, sizeof(RTL_RANGE_LIST), TAG_ARBITER); + if (!Arbiter->PossibleAllocation) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Failure; + } + RtlInitializeRangeList(Arbiter->PossibleAllocation); if (!Arbiter->TestAllocation) Arbiter->TestAllocation = ArbTestAllocation; - if (!Arbiter->RetestAllocation) Arbiter->RetestAllocation = ArbRetestAllocation; - if (!Arbiter->CommitAllocation) Arbiter->CommitAllocation = ArbCommitAllocation; - if (!Arbiter->RollbackAllocation) Arbiter->RollbackAllocation = ArbRollbackAllocation; - - if (!Arbiter->AddReserved) - Arbiter->AddReserved = ArbAddReserved; - - if (!Arbiter->PreprocessEntry) - Arbiter->PreprocessEntry = ArbPreprocessEntry; - - if (!Arbiter->AllocateEntry) - Arbiter->AllocateEntry = ArbAllocateEntry; - - if (!Arbiter->GetNextAllocationRange) - Arbiter->GetNextAllocationRange = ArbGetNextAllocationRange; - - if (!Arbiter->FindSuitableRange) - Arbiter->FindSuitableRange = ArbFindSuitableRange; - - if (!Arbiter->AddAllocation) - Arbiter->AddAllocation = ArbAddAllocation; - - if (!Arbiter->BacktrackAllocation) - Arbiter->BacktrackAllocation = ArbBacktrackAllocation; - - if (!Arbiter->OverrideConflict) - Arbiter->OverrideConflict = ArbOverrideConflict; - if (!Arbiter->BootAllocation) Arbiter->BootAllocation = ArbBootAllocation; - + if (!Arbiter->AddReserved) + Arbiter->AddReserved = ArbAddReserved; if (!Arbiter->QueryConflict) Arbiter->QueryConflict = ArbQueryConflict; - if (!Arbiter->StartArbiter) Arbiter->StartArbiter = ArbStartArbiter; + if (!Arbiter->PreprocessEntry) + Arbiter->PreprocessEntry = ArbPreprocessEntry; + if (!Arbiter->AllocateEntry) + Arbiter->AllocateEntry = ArbAllocateEntry; + if (!Arbiter->GetNextAllocationRange) + Arbiter->GetNextAllocationRange = ArbGetNextAllocationRange; + if (!Arbiter->FindSuitableRange) + Arbiter->FindSuitableRange = ArbFindSuitableRange; + if (!Arbiter->AddAllocation) + Arbiter->AddAllocation = ArbAddAllocation; + if (!Arbiter->BacktrackAllocation) + Arbiter->BacktrackAllocation = ArbBacktrackAllocation; + if (!Arbiter->OverrideConflict) + Arbiter->OverrideConflict = ArbOverrideConflict; +#if (NTDDI_VERSION >= NTDDI_VISTA) + if (!Arbiter->InitializeRangeList) + Arbiter->InitializeRangeList = ArbInitializeRangeList; +#endif Status = ArbBuildAssignmentOrdering(Arbiter, OrderName, OrderName, TranslateOrderingFunction); - if (NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { - return STATUS_SUCCESS; + DPRINT1("ArbInitializeArbiterInstance: ArbBuildAssignmentOrdering failed, Status %X\n", Status); + goto Failure; } - DPRINT1("ArbInitializeArbiterInstance: Status %X\n", Status); + return STATUS_SUCCESS; +Failure: + DPRINT1("ArbInitializeArbiterInstance: '%S' failed, Status %X\n", ArbiterName, Status); + ArbDeleteArbiterInstance(Arbiter); return Status; } diff --git a/sdk/lib/drivers/arbiter/arbiter.h b/sdk/lib/drivers/arbiter/arbiter.h index 98e81711671..6614b99e74d 100644 --- a/sdk/lib/drivers/arbiter/arbiter.h +++ b/sdk/lib/drivers/arbiter/arbiter.h @@ -1,36 +1,23 @@ /* - * PROJECT: ReactOS Kernel&Driver SDK - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) - * PURPOSE: Hardware Resources Arbiter Library - * COPYRIGHT: Copyright 2020 Vadim Galyant + * PROJECT: ReactOS Arbitrartion Library + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Generic Arbiter Library + * COPYRIGHT: Copyright 2026 Justin Miller */ #pragma once -#define ARBITER_SIGNATURE 'sbrA' -#define TAG_ARBITER 'MbrA' -#define TAG_ARB_ALLOCATION 'AbrA' -#define TAG_ARB_RANGE 'RbrA' - -typedef struct _ARBITER_ORDERING -{ - UINT64 Start; - UINT64 End; -} ARBITER_ORDERING, *PARBITER_ORDERING; - -typedef struct _ARBITER_ORDERING_LIST -{ - UINT16 Count; - UINT16 Maximum; - PARBITER_ORDERING Orderings; -} ARBITER_ORDERING_LIST, *PARBITER_ORDERING_LIST; - typedef struct _ARBITER_ALTERNATIVE { UINT64 Minimum; UINT64 Maximum; +#if (NTDDI_VERSION >= NTDDI_VISTA) + UINT64 Length; + UINT64 Alignment; +#else UINT32 Length; UINT32 Alignment; +#endif INT32 Priority; UINT32 Flags; PIO_RESOURCE_DESCRIPTOR Descriptor; @@ -53,6 +40,19 @@ typedef struct _ARBITER_ALLOCATION_STATE ULONG_PTR WorkSpace; } ARBITER_ALLOCATION_STATE, *PARBITER_ALLOCATION_STATE; +typedef struct _ARBITER_ORDERING +{ + UINT64 Start; + UINT64 End; +} ARBITER_ORDERING, *PARBITER_ORDERING; + +typedef struct _ARBITER_ORDERING_LIST +{ + UINT16 Count; + UINT16 Maximum; + PARBITER_ORDERING Orderings; +} ARBITER_ORDERING_LIST, *PARBITER_ORDERING_LIST; + typedef struct _ARBITER_INSTANCE *PARBITER_INSTANCE; typedef NTSTATUS @@ -60,8 +60,8 @@ typedef NTSTATUS _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor, _Out_ PUINT64 OutMinimumAddress, _Out_ PUINT64 OutMaximumAddress, - _Out_ PUINT32 OutLength, - _Out_ PUINT32 OutAlignment + _Out_ PUINT64 OutLength, + _Out_ PUINT64 OutAlignment ); typedef NTSTATUS @@ -75,7 +75,7 @@ typedef NTSTATUS (NTAPI * PARB_UNPACK_RESOURCE)( _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor, _Out_ PUINT64 Start, - _Out_ PUINT32 OutLength + _Out_ PUINT64 OutLength ); typedef INT32 @@ -83,18 +83,85 @@ typedef INT32 _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor ); +#if (NTDDI_VERSION >= NTDDI_VISTA) typedef NTSTATUS (NTAPI * PARB_TEST_ALLOCATION)( _In_ PARBITER_INSTANCE Arbiter, - _In_ PLIST_ENTRY ArbitrationList + _Inout_ PARBITER_TEST_ALLOCATION_PARAMETERS Parameters ); typedef NTSTATUS (NTAPI * PARB_RETEST_ALLOCATION)( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PARBITER_RETEST_ALLOCATION_PARAMETERS Parameters +); + +typedef NTSTATUS +(NTAPI * PARB_BOOT_ALLOCATION)( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PARBITER_BOOT_ALLOCATION_PARAMETERS Parameters +); + +typedef NTSTATUS +(NTAPI * PARB_QUERY_ARBITRATE)( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PARBITER_QUERY_ARBITRATE_PARAMETERS Parameters +); + +typedef NTSTATUS +(NTAPI * PARB_QUERY_CONFLICT)( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PARBITER_QUERY_CONFLICT_PARAMETERS Parameters +); + +typedef NTSTATUS +(NTAPI * PARB_ADD_RESERVED)( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PARBITER_ADD_RESERVED_PARAMETERS Parameters +); + +#else +typedef NTSTATUS +(NTAPI * PARB_TEST_ALLOCATION)( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PLIST_ENTRY ArbitrationList +); + +typedef NTSTATUS +(NTAPI * PARB_RETEST_ALLOCATION)( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PLIST_ENTRY ArbitrationList +); + +typedef NTSTATUS +(NTAPI * PARB_BOOT_ALLOCATION)( + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PLIST_ENTRY ArbitrationList +); + +typedef NTSTATUS +(NTAPI * PARB_QUERY_ARBITRATE)( _In_ PARBITER_INSTANCE Arbiter, _In_ PLIST_ENTRY ArbitrationList ); +typedef NTSTATUS +(NTAPI * PARB_QUERY_CONFLICT)( + _In_ PARBITER_INSTANCE Arbiter, + _In_ PDEVICE_OBJECT PhysicalDeviceObject, + _In_ PIO_RESOURCE_DESCRIPTOR ConflictingResource, + _Out_ PULONG ConflictCount, + _Out_ PARBITER_CONFLICT_INFO *Conflicts +); + +typedef NTSTATUS +(NTAPI * PARB_ADD_RESERVED)( + _In_ PARBITER_INSTANCE Arbiter, + _In_opt_ PIO_RESOURCE_DESCRIPTOR Requirement, + _In_opt_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource +); +#endif // (NTDDI_VERSION >= NTDDI_VISTA) + typedef NTSTATUS (NTAPI * PARB_COMMIT_ALLOCATION)( _In_ PARBITER_INSTANCE Arbiter @@ -105,34 +172,10 @@ typedef NTSTATUS _In_ PARBITER_INSTANCE Arbiter ); -typedef NTSTATUS -(NTAPI * PARB_BOOT_ALLOCATION)( - _In_ PARBITER_INSTANCE Arbiter, - _In_ PLIST_ENTRY ArbitrationList -); - -/* Not correct yet, FIXME! */ -typedef NTSTATUS -(NTAPI * PARB_QUERY_ARBITRATE)( - _In_ PARBITER_INSTANCE Arbiter -); - -/* Not correct yet, FIXME! */ -typedef NTSTATUS -(NTAPI * PARB_QUERY_CONFLICT)( - _In_ PARBITER_INSTANCE Arbiter -); - -/* Not correct yet, FIXME! */ -typedef NTSTATUS -(NTAPI * PARB_ADD_RESERVED)( - _In_ PARBITER_INSTANCE Arbiter -); - -/* Not correct yet, FIXME! */ typedef NTSTATUS (NTAPI * PARB_START_ARBITER)( - _In_ PARBITER_INSTANCE Arbiter + _In_ PARBITER_INSTANCE Arbiter, + _In_ PCM_RESOURCE_LIST StartResources ); typedef NTSTATUS @@ -171,25 +214,44 @@ typedef VOID _Inout_ PARBITER_ALLOCATION_STATE ArbState ); -/* Not correct yet, FIXME! */ -typedef NTSTATUS +typedef BOOLEAN (NTAPI * PARB_OVERRIDE_CONFLICT)( - _In_ PARBITER_INSTANCE Arbiter + _In_ PARBITER_INSTANCE Arbiter, + _Inout_ PARBITER_ALLOCATION_STATE ArbState ); +typedef NTSTATUS +(NTAPI * PARB_TRANSLATE_ORDERING)( + _Out_ PIO_RESOURCE_DESCRIPTOR OutIoDescriptor, + _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +typedef NTSTATUS +(NTAPI * PARB_INITIALIZE_RANGE_LIST)( + _In_ PARBITER_INSTANCE Arbiter, + _In_ ULONG DescriptorCount, + _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptors, + _Inout_ PRTL_RANGE_LIST RangeList +); +#endif + typedef struct _ARBITER_INSTANCE { UINT32 Signature; PKEVENT MutexEvent; PCWSTR Name; +#if (NTDDI_VERSION >= NTDDI_VISTA) + PCWSTR OrderingName; // Vista+: selects registry AllocationOrder\ +#endif CM_RESOURCE_TYPE ResourceType; PRTL_RANGE_LIST Allocation; PRTL_RANGE_LIST PossibleAllocation; ARBITER_ORDERING_LIST OrderingList; ARBITER_ORDERING_LIST ReservedList; - INT32 ReferenceCount; + ULONG ReferenceCount; PARBITER_INTERFACE Interface; - UINT32 AllocationStackMaxSize; + ULONG AllocationStackMaxSize; PARBITER_ALLOCATION_STATE AllocationStack; PARB_UNPACK_REQUIREMENT UnpackRequirement; PARB_PACK_RESOURCE PackResource; @@ -200,30 +262,35 @@ typedef struct _ARBITER_INSTANCE PARB_COMMIT_ALLOCATION CommitAllocation; PARB_ROLLBACK_ALLOCATION RollbackAllocation; PARB_BOOT_ALLOCATION BootAllocation; - PARB_QUERY_ARBITRATE QueryArbitrate; // Not used yet - PARB_QUERY_CONFLICT QueryConflict; // Not used yet - PARB_ADD_RESERVED AddReserved; // Not used yet - PARB_START_ARBITER StartArbiter; // Not used yet + PARB_QUERY_ARBITRATE QueryArbitrate; + PARB_QUERY_CONFLICT QueryConflict; + PARB_ADD_RESERVED AddReserved; + PARB_START_ARBITER StartArbiter; PARB_PREPROCESS_ENTRY PreprocessEntry; PARB_ALLOCATE_ENTRY AllocateEntry; PARB_GET_NEXT_ALLOCATION_RANGE GetNextAllocationRange; PARB_FIND_SUITABLE_RANGE FindSuitableRange; PARB_ADD_ALLOCATION AddAllocation; PARB_BACKTRACK_ALLOCATION BacktrackAllocation; - PARB_OVERRIDE_CONFLICT OverrideConflict; // Not used yet + PARB_OVERRIDE_CONFLICT OverrideConflict; +#if (NTDDI_VERSION >= NTDDI_VISTA) + PARB_INITIALIZE_RANGE_LIST InitializeRangeList; +#endif BOOLEAN TransactionInProgress; +#if (NTDDI_VERSION >= NTDDI_VISTA) + PKEVENT TransactionEvent; +#endif PVOID Extension; PDEVICE_OBJECT BusDeviceObject; PVOID ConflictCallbackContext; - PVOID ConflictCallback; + PRTL_CONFLICT_RANGE_CALLBACK ConflictCallback; +#if (NTDDI_VERSION >= NTDDI_VISTA) && (NTDDI_VERSION < NTDDI_WINBLUE) + WCHAR PdoDescriptionString[336]; + CHAR PdoSymbolicNameString[672]; + WCHAR PdoAddressString[1]; +#endif } ARBITER_INSTANCE, *PARBITER_INSTANCE; -typedef NTSTATUS -(NTAPI * PARB_TRANSLATE_ORDERING)( - _Out_ PIO_RESOURCE_DESCRIPTOR OutIoDescriptor, - _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor -); - CODE_SEG("PAGE") NTSTATUS NTAPI