reactos/sdk/lib/drivers/arbiter/arbiter.c

406 lines
8.8 KiB
C

/*
* 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 <vgal@rambler.ru>
*/
/* INCLUDES *******************************************************************/
#include <ntifs.h>
#include <ndk/rtlfuncs.h>
#include "arbiter.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
/* DATA **********************************************************************/
/* FUNCTIONS ******************************************************************/
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbTestAllocation(
_In_ PARBITER_INSTANCE Arbiter,
_In_ PLIST_ENTRY ArbitrationList)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbRetestAllocation(
_In_ PARBITER_INSTANCE Arbiter,
_In_ PLIST_ENTRY ArbitrationList)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbCommitAllocation(
_In_ PARBITER_INSTANCE Arbiter)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbRollbackAllocation(
_In_ PARBITER_INSTANCE Arbiter)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* FIXME: the prototype is not correct yet. */
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbAddReserved(
_In_ PARBITER_INSTANCE Arbiter)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbPreprocessEntry(
_In_ PARBITER_INSTANCE Arbiter,
_Inout_ PARBITER_ALLOCATION_STATE ArbState)
{
PAGED_CODE();
return STATUS_SUCCESS;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbAllocateEntry(
_In_ PARBITER_INSTANCE Arbiter,
_Inout_ PARBITER_ALLOCATION_STATE ArbState)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
CODE_SEG("PAGE")
BOOLEAN
NTAPI
ArbGetNextAllocationRange(
_In_ PARBITER_INSTANCE Arbiter,
_Inout_ PARBITER_ALLOCATION_STATE ArbState)
{
PAGED_CODE();
UNIMPLEMENTED;
return FALSE;
}
CODE_SEG("PAGE")
BOOLEAN
NTAPI
ArbFindSuitableRange(
_In_ PARBITER_INSTANCE Arbiter,
_Inout_ PARBITER_ALLOCATION_STATE ArbState)
{
PAGED_CODE();
UNIMPLEMENTED;
return FALSE;
}
CODE_SEG("PAGE")
VOID
NTAPI
ArbAddAllocation(
_In_ PARBITER_INSTANCE Arbiter,
_Inout_ PARBITER_ALLOCATION_STATE ArbState)
{
PAGED_CODE();
UNIMPLEMENTED;
}
CODE_SEG("PAGE")
VOID
NTAPI
ArbBacktrackAllocation(
_In_ PARBITER_INSTANCE Arbiter,
_Inout_ PARBITER_ALLOCATION_STATE ArbState)
{
PAGED_CODE();
UNIMPLEMENTED;
}
/* FIXME: the prototype is not correct yet. */
CODE_SEG("PAGE")
NTSTATUS
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)
{
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;
}
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)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbInitializeOrderingList(
_Out_ PARBITER_ORDERING_LIST OrderList)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
CODE_SEG("PAGE")
VOID
NTAPI
ArbFreeOrderingList(
_Out_ PARBITER_ORDERING_LIST OrderList)
{
PAGED_CODE();
UNIMPLEMENTED;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbBuildAssignmentOrdering(
_Inout_ PARBITER_INSTANCE ArbInstance,
_In_ PCWSTR OrderName,
_In_ PCWSTR ReservedOrderName,
_In_ PARB_TRANSLATE_ORDERING TranslateOrderingFunction)
{
PAGED_CODE();
UNIMPLEMENTED;
return STATUS_SUCCESS;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
ArbInitializeArbiterInstance(
_Inout_ PARBITER_INSTANCE Arbiter,
_In_ PDEVICE_OBJECT BusDeviceObject,
_In_ CM_RESOURCE_TYPE ResourceType,
_In_ PCWSTR ArbiterName,
_In_ PCWSTR OrderName,
_In_ PARB_TRANSLATE_ORDERING TranslateOrderingFunction)
{
NTSTATUS Status;
PAGED_CODE();
DPRINT("ArbInitializeArbiterInstance: '%S'\n", ArbiterName);
ASSERT(Arbiter->UnpackRequirement != NULL);
ASSERT(Arbiter->PackResource != NULL);
ASSERT(Arbiter->UnpackResource != NULL);
ASSERT(Arbiter->MutexEvent == NULL);
ASSERT(Arbiter->Allocation == NULL);
ASSERT(Arbiter->PossibleAllocation == NULL);
ASSERT(Arbiter->AllocationStack == NULL);
Arbiter->Signature = ARBITER_SIGNATURE;
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 (!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->QueryConflict)
Arbiter->QueryConflict = ArbQueryConflict;
if (!Arbiter->StartArbiter)
Arbiter->StartArbiter = ArbStartArbiter;
Status = ArbBuildAssignmentOrdering(Arbiter, OrderName, OrderName, TranslateOrderingFunction);
if (NT_SUCCESS(Status))
{
return STATUS_SUCCESS;
}
DPRINT1("ArbInitializeArbiterInstance: Status %X\n", Status);
return Status;
}