ReactOS 0.4.17-dev-934-g091855f
ordering.c File Reference
#include <ntifs.h>
#include <ndk/rtlfuncs.h>
#include "arbiter.h"
#include <debug.h>
Include dependency graph for ordering.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define ARBITER_ORDERING_GRANULARITY   16
 
#define ARBITER_ORDERING_LIMIT   1024
 
#define ARBP_POLICY_ROOT   L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Arbiters\\"
 
#define ARBP_LONGEST_SUBKEY   L"ReservedResources"
 

Typedefs

typedef VOID(NTAPI * PARB_RANGE_CALLBACK) (_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
 

Functions

static NTSTATUS ArbpCreateOrderingList (_Out_ PARBITER_ORDERING_LIST OrderingList)
 
VOID NTAPI ArbiterLibFreeOrderingList (_Inout_ PARBITER_ORDERING_LIST OrderingList)
 
NTSTATUS NTAPI ArbiterLibAddOrdering (_Inout_ PARBITER_ORDERING_LIST OrderingList, _In_ UINT64 Start, _In_ UINT64 End)
 
static NTSTATUS ArbpExcludeOrderingRange (_Inout_ PARBITER_ORDERING_LIST OrderingList, _In_ UINT64 Start, _In_ UINT64 End)
 Removes [Start, End] from every window of an ordering list, splitting windows that straddle it.
 
static NTSTATUS ArbpOpenPolicySubkey (_In_ PCWSTR SubkeyName, _Out_ PHANDLE KeyHandle)
 
static NTSTATUS ArbpReadPolicyValue (_In_ HANDLE KeyHandle, _In_ PCWSTR ValueName, _Out_ PKEY_VALUE_FULL_INFORMATION *Value)
 
static BOOLEAN ArbpDescriptorMatchesArbiter (_In_ PARBITER_INSTANCE Arbiter, _In_ UCHAR DescriptorType)
 
static NTSTATUS ArbpForEachRegistryRange (_In_ PARBITER_INSTANCE Arbiter, _In_ PCWSTR Subkey, _In_ PCWSTR ValueName, _In_opt_ PARB_TRANSLATE_ORDERING Translate, _In_ PARB_RANGE_CALLBACK Callback, _In_opt_ PVOID Context)
 
static VOID NTAPI ArbpAddOrderingCallback (_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
 
static VOID NTAPI ArbpAddReservedCallback (_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
 Range callback moving one reserved window into last-resort territory: recorded in the arbiter's ReservedList and pruned out of every ordering window, including the full-range fallback.
 
static VOID NTAPI ArbpAddRangeCallback (_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
 Range callback carving one window out of a range list as an unowned blocking range, so it is never handed to a device.
 
static VOID NTAPI ArbpMmConfigCallback (_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
 Range callback recording the MMCONFIG (ECAM) window and reserving it in a range list as a boot allocation.
 
NTSTATUS NTAPI ArbiterLibDefaultAssignmentOrdering (_Inout_ PARBITER_INSTANCE Arbiter, _In_ PCWSTR AllocationOrderName, _In_ PCWSTR ReservedResourcesName, _In_opt_ PARB_TRANSLATE_ORDERING TranslateOrderingFunction)
 Builds the arbiter's allocation ordering from the registry policy, most-preferred window first.
 
NTSTATUS NTAPI ArbiterLibAddInaccessibleAllocationRange (_In_ PARBITER_INSTANCE Arbiter, _In_ PCWSTR OrderingName, _Inout_ PRTL_RANGE_LIST RangeList)
 Carves the firmware-reported inaccessible ranges (Arbiters\InaccessibleRange<OrderingName>) out of a range list as unowned blocking ranges, so they are never handed to a device.
 
NTSTATUS NTAPI ArbiterLibAddMmConfigRangeAsBootReserved (_In_ PARBITER_INSTANCE Arbiter, _Inout_ PRTL_RANGE_LIST RangeList)
 Reserves the PCI-Express enhanced-config (MMCONFIG / ECAM) MMIO window (Arbiters\ReservedResources\MmConfigRange) in a range list, and records it for ArbiterLibIsConflictWithMmConfigRange.
 
BOOLEAN NTAPI ArbiterLibIsConflictWithMmConfigRange (_In_ ULONGLONG Start, _In_ ULONGLONG End)
 Determines whether a range overlaps the recorded MMCONFIG window.
 

Variables

static ULONGLONG ArbpMmConfigStart = 1
 
static ULONGLONG ArbpMmConfigEnd = 0
 

Macro Definition Documentation

◆ ARBITER_ORDERING_GRANULARITY

#define ARBITER_ORDERING_GRANULARITY   16

Definition at line 17 of file ordering.c.

◆ ARBITER_ORDERING_LIMIT

#define ARBITER_ORDERING_LIMIT   1024

Definition at line 18 of file ordering.c.

◆ ARBP_LONGEST_SUBKEY

#define ARBP_LONGEST_SUBKEY   L"ReservedResources"

Definition at line 21 of file ordering.c.

◆ ARBP_POLICY_ROOT

#define ARBP_POLICY_ROOT   L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Arbiters\\"

Definition at line 20 of file ordering.c.

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file ordering.c.

Typedef Documentation

◆ PARB_RANGE_CALLBACK

typedef VOID(NTAPI * PARB_RANGE_CALLBACK) (_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)

Definition at line 206 of file ordering.c.

Function Documentation

◆ ArbiterLibAddInaccessibleAllocationRange()

NTSTATUS NTAPI ArbiterLibAddInaccessibleAllocationRange ( _In_ PARBITER_INSTANCE  Arbiter,
_In_ PCWSTR  OrderingName,
_Inout_ PRTL_RANGE_LIST  RangeList 
)

Carves the firmware-reported inaccessible ranges (Arbiters\InaccessibleRange<OrderingName>) out of a range list as unowned blocking ranges, so they are never handed to a device.

Parameters
[in]ArbiterThe arbiter instance the ranges are filtered for.
[in]OrderingNameThe InaccessibleRange value to read.
[in,out]RangeListThe range list to carve the windows out of.
Returns
Returns STATUS_SUCCESS, including when nothing is recorded (an absent value reserves nothing).

Definition at line 634 of file ordering.c.

638{
639 PAGED_CODE();
640 return ArbpForEachRegistryRange(Arbiter, L"InaccessibleRange", OrderingName,
641 NULL, ArbpAddRangeCallback, RangeList);
642}
#define PAGED_CODE()
#define NULL
Definition: types.h:112
#define L(x)
Definition: resources.c:13
static VOID NTAPI ArbpAddRangeCallback(_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
Range callback carving one window out of a range list as an unowned blocking range,...
Definition: ordering.c:490
static NTSTATUS ArbpForEachRegistryRange(_In_ PARBITER_INSTANCE Arbiter, _In_ PCWSTR Subkey, _In_ PCWSTR ValueName, _In_opt_ PARB_TRANSLATE_ORDERING Translate, _In_ PARB_RANGE_CALLBACK Callback, _In_opt_ PVOID Context)
Definition: ordering.c:313

◆ ArbiterLibAddMmConfigRangeAsBootReserved()

NTSTATUS NTAPI ArbiterLibAddMmConfigRangeAsBootReserved ( _In_ PARBITER_INSTANCE  Arbiter,
_Inout_ PRTL_RANGE_LIST  RangeList 
)

Reserves the PCI-Express enhanced-config (MMCONFIG / ECAM) MMIO window (Arbiters\ReservedResources\MmConfigRange) in a range list, and records it for ArbiterLibIsConflictWithMmConfigRange.

Parameters
[in]ArbiterThe arbiter instance the window is filtered for.
[in,out]RangeListThe range list to reserve the window in.
Returns
Returns STATUS_SUCCESS, including on a legacy pre-PCIe machine where the value is simply absent and nothing is reserved.

Definition at line 663 of file ordering.c.

666{
667 PAGED_CODE();
668 return ArbpForEachRegistryRange(Arbiter, L"ReservedResources", L"MmConfigRange",
669 NULL, ArbpMmConfigCallback, RangeList);
670}
static VOID NTAPI ArbpMmConfigCallback(_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
Range callback recording the MMCONFIG (ECAM) window and reserving it in a range list as a boot alloca...
Definition: ordering.c:523

◆ ArbiterLibAddOrdering()

NTSTATUS NTAPI ArbiterLibAddOrdering ( _Inout_ PARBITER_ORDERING_LIST  OrderingList,
_In_ UINT64  Start,
_In_ UINT64  End 
)

Definition at line 78 of file ordering.c.

82{
83 PAGED_CODE();
84
85 if (End < Start)
87
88 /* Double the array capacity when it fills up, up to the sanity cap. */
89 if (OrderingList->Count == OrderingList->Maximum)
90 {
91 ULONG NewMaximum;
92 PARBITER_ORDERING NewArray;
93
94 NewMaximum = OrderingList->Maximum ? (ULONG)OrderingList->Maximum * 2
96 if (NewMaximum > ARBITER_ORDERING_LIMIT)
98
100 NewMaximum * sizeof(ARBITER_ORDERING),
102 if (NewArray == NULL)
104
105 if (OrderingList->Orderings != NULL)
106 {
107 RtlCopyMemory(NewArray, OrderingList->Orderings,
108 OrderingList->Count * sizeof(ARBITER_ORDERING));
109 ExFreePoolWithTag(OrderingList->Orderings, TAG_ARBITER);
110 }
111
112 OrderingList->Maximum = (UINT16)NewMaximum;
113 OrderingList->Orderings = NewArray;
114 }
115
116 OrderingList->Orderings[OrderingList->Count].Start = Start;
117 OrderingList->Orderings[OrderingList->Count].End = End;
118 OrderingList->Count++;
119 return STATUS_SUCCESS;
120}
static _Out_opt_ PULONGLONG Start
unsigned short UINT16
Definition: actypes.h:129
#define TAG_ARBITER
Definition: arbiter.h:10
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
if(dx< 0)
Definition: linetemp.h:194
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define ARBITER_ORDERING_LIMIT
Definition: ordering.c:18
#define ARBITER_ORDERING_GRANULARITY
Definition: ordering.c:17
#define STATUS_SUCCESS
Definition: shellext.h:65
UINT64 Start
Definition: arbiter.h:99
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by ArbiterLibDefaultAssignmentOrdering(), ArbpAddOrderingCallback(), ArbpAddReservedCallback(), and ArbpExcludeOrderingRange().

◆ ArbiterLibDefaultAssignmentOrdering()

NTSTATUS NTAPI ArbiterLibDefaultAssignmentOrdering ( _Inout_ PARBITER_INSTANCE  Arbiter,
_In_ PCWSTR  AllocationOrderName,
_In_ PCWSTR  ReservedResourcesName,
_In_opt_ PARB_TRANSLATE_ORDERING  TranslateOrderingFunction 
)

Builds the arbiter's allocation ordering from the registry policy, most-preferred window first.

Parameters
[in,out]ArbiterThe arbiter instance whose OrderingList and ReservedList are (re)created. Callers may rebuild an existing ordering against a different policy table (see pcix!ario_ApplyBrokenVideoHack).
[in]AllocationOrderNameThe AllocationOrder value naming this arbiter's preferred windows. The engine walks the resulting list in index order, so index 0 is the most-preferred window.
[in]ReservedResourcesNameThe ReservedResources value naming this arbiter's last-resort windows: each is recorded in the ReservedList for the engine's final pass and pruned out of every ordering window, so it is only ever offered once all orderings fail.
[in]TranslateOrderingFunctionOptional per-arbiter descriptor translation.
Returns
Returns STATUS_SUCCESS if the ordering was built. Absent registry policy is not a failure; the ordering then holds only the full-range fallback, so the arbiter can always search the whole space.

Definition at line 571 of file ordering.c.

576{
578
579 PAGED_CODE();
580
581 ArbiterLibFreeOrderingList(&Arbiter->OrderingList);
582 ArbiterLibFreeOrderingList(&Arbiter->ReservedList);
583
584 Status = ArbpCreateOrderingList(&Arbiter->OrderingList);
585 if (!NT_SUCCESS(Status))
586 return Status;
587 Status = ArbpCreateOrderingList(&Arbiter->ReservedList);
588 if (!NT_SUCCESS(Status))
589 {
590 ArbiterLibFreeOrderingList(&Arbiter->OrderingList);
591 return Status;
592 }
593
594 ArbpForEachRegistryRange(Arbiter, L"AllocationOrder", AllocationOrderName,
595 TranslateOrderingFunction, ArbpAddOrderingCallback, NULL);
596
597 Status = ArbiterLibAddOrdering(&Arbiter->OrderingList, 0, ARBITER_MAXIMUM_ADDRESS);
598 if (!NT_SUCCESS(Status))
599 return Status;
600
601 /*
602 * The reserved windows come last, after the fallback is in place, so the
603 * pruning punches them out of the fallback too. Otherwise the fallback
604 * pass would hand them out like any other range.
605 */
606 return ArbpForEachRegistryRange(Arbiter, L"ReservedResources", ReservedResourcesName,
607 TranslateOrderingFunction, ArbpAddReservedCallback,
608 NULL);
609}
#define ARBITER_MAXIMUM_ADDRESS
Definition: arbiter.h:13
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
static VOID NTAPI ArbpAddReservedCallback(_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
Range callback moving one reserved window into last-resort territory: recorded in the arbiter's Reser...
Definition: ordering.c:456
static NTSTATUS ArbpCreateOrderingList(_Out_ PARBITER_ORDERING_LIST OrderingList)
Definition: ordering.c:37
static VOID NTAPI ArbpAddOrderingCallback(_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
Definition: ordering.c:415
VOID NTAPI ArbiterLibFreeOrderingList(_Inout_ PARBITER_ORDERING_LIST OrderingList)
Definition: ordering.c:60
NTSTATUS NTAPI ArbiterLibAddOrdering(_Inout_ PARBITER_ORDERING_LIST OrderingList, _In_ UINT64 Start, _In_ UINT64 End)
Definition: ordering.c:78

Referenced by ArbiterLibInitializeInstance(), and ario_ApplyBrokenVideoHack().

◆ ArbiterLibFreeOrderingList()

VOID NTAPI ArbiterLibFreeOrderingList ( _Inout_ PARBITER_ORDERING_LIST  OrderingList)

Definition at line 60 of file ordering.c.

62{
63 PAGED_CODE();
64
65 if (OrderingList->Orderings != NULL)
66 ExFreePoolWithTag(OrderingList->Orderings, TAG_ARBITER);
67
68 OrderingList->Orderings = NULL;
69 OrderingList->Count = 0;
70 OrderingList->Maximum = 0;
71}

Referenced by ArbiterLibDefaultAssignmentOrdering(), ArbiterLibDeleteInstance(), ArbpExcludeOrderingRange(), and ario_ApplyBrokenVideoHack().

◆ ArbiterLibIsConflictWithMmConfigRange()

BOOLEAN NTAPI ArbiterLibIsConflictWithMmConfigRange ( _In_ ULONGLONG  Start,
_In_ ULONGLONG  End 
)

Determines whether a range overlaps the recorded MMCONFIG window.

Parameters
[in]StartThe inclusive start of the range to test.
[in]EndThe inclusive end of the range to test.
Returns
Returns TRUE if [Start, End] overlaps the recorded window, FALSE otherwise or when no window was ever recorded.

Definition at line 689 of file ordering.c.

692{
694 return FALSE; /* No MMCONFIG window recorded */
695
696 return (BOOLEAN)(Start <= ArbpMmConfigEnd && ArbpMmConfigStart <= End);
697}
unsigned char BOOLEAN
Definition: actypes.h:127
#define FALSE
Definition: types.h:117
static ULONGLONG ArbpMmConfigEnd
Definition: ordering.c:29
static ULONGLONG ArbpMmConfigStart
Definition: ordering.c:28

Referenced by ArbiterLibFindSuitableRange().

◆ ArbpAddOrderingCallback()

static VOID NTAPI ArbpAddOrderingCallback ( _In_ PARBITER_INSTANCE  Arbiter,
_In_opt_ PVOID  Context,
_In_ ULONGLONG  Start,
_In_ ULONGLONG  End 
)
static

Definition at line 415 of file ordering.c.

420{
421 PAGED_CODE();
423 ArbiterLibAddOrdering(&Arbiter->OrderingList, Start, End);
424}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
_In_ PVOID Context
Definition: storport.h:2269

Referenced by ArbiterLibDefaultAssignmentOrdering().

◆ ArbpAddRangeCallback()

static VOID NTAPI ArbpAddRangeCallback ( _In_ PARBITER_INSTANCE  Arbiter,
_In_opt_ PVOID  Context,
_In_ ULONGLONG  Start,
_In_ ULONGLONG  End 
)
static

Range callback carving one window out of a range list as an unowned blocking range, so it is never handed to a device.

Parameters
[in]ArbiterUnused.
[in]ContextThe RTL_RANGE_LIST to add the blocking range to.
[in]StartThe inclusive start of the window.
[in]EndThe inclusive end of the window.

Definition at line 490 of file ordering.c.

495{
496 PAGED_CODE();
497 UNREFERENCED_PARAMETER(Arbiter);
500}
#define ARBITER_RANGE_INACCESSIBLE
Definition: arbiter.h:56
NTSYSAPI NTSTATUS NTAPI RtlAddRange(_Inout_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ UCHAR Attributes, _In_ ULONG Flags, _In_opt_ PVOID UserData, _In_opt_ PVOID Owner)
#define RTL_RANGE_LIST_ADD_IF_CONFLICT
Definition: rtltypes.h:81

Referenced by ArbiterLibAddInaccessibleAllocationRange().

◆ ArbpAddReservedCallback()

static VOID NTAPI ArbpAddReservedCallback ( _In_ PARBITER_INSTANCE  Arbiter,
_In_opt_ PVOID  Context,
_In_ ULONGLONG  Start,
_In_ ULONGLONG  End 
)
static

Range callback moving one reserved window into last-resort territory: recorded in the arbiter's ReservedList and pruned out of every ordering window, including the full-range fallback.

Parameters
[in]ArbiterThe arbiter instance whose lists are adjusted.
[in]ContextUnused.
[in]StartThe inclusive start of the reserved window.
[in]EndThe inclusive end of the reserved window.
Remarks
Once pruned here, the window can only ever be offered by the engine's (PREFERRED_)RESERVED pass, the one that is usable only when nothing else fits. This is what keeps allocations from touching ranges like COM1/COM2 and the VGA windows that the PCStandard policy table reserves, even though no enumerated device owns them yet.

Definition at line 456 of file ordering.c.

461{
462 PAGED_CODE();
464
465 if (NT_SUCCESS(ArbiterLibAddOrdering(&Arbiter->ReservedList, Start, End)))
466 ArbpExcludeOrderingRange(&Arbiter->OrderingList, Start, End);
467}
static NTSTATUS ArbpExcludeOrderingRange(_Inout_ PARBITER_ORDERING_LIST OrderingList, _In_ UINT64 Start, _In_ UINT64 End)
Removes [Start, End] from every window of an ordering list, splitting windows that straddle it.
Definition: ordering.c:146

Referenced by ArbiterLibDefaultAssignmentOrdering().

◆ ArbpCreateOrderingList()

static NTSTATUS ArbpCreateOrderingList ( _Out_ PARBITER_ORDERING_LIST  OrderingList)
static

Definition at line 37 of file ordering.c.

39{
40 PAGED_CODE();
41
42 OrderingList->Orderings = ExAllocatePoolWithTag(PagedPool,
45 if (OrderingList->Orderings == NULL)
46 {
47 OrderingList->Count = 0;
48 OrderingList->Maximum = 0;
50 }
51
52 OrderingList->Count = 0;
53 OrderingList->Maximum = ARBITER_ORDERING_GRANULARITY;
54 return STATUS_SUCCESS;
55}

Referenced by ArbiterLibDefaultAssignmentOrdering(), and ArbpExcludeOrderingRange().

◆ ArbpDescriptorMatchesArbiter()

static BOOLEAN ArbpDescriptorMatchesArbiter ( _In_ PARBITER_INSTANCE  Arbiter,
_In_ UCHAR  DescriptorType 
)
static

Definition at line 292 of file ordering.c.

295{
296 PAGED_CODE();
297
298 if (DescriptorType == (UCHAR)Arbiter->ResourceType)
299 return TRUE;
300
301 /* Large-memory descriptors also satisfy the plain memory arbiter. */
303 Arbiter->ResourceType == CmResourceTypeMemory);
304}
#define TRUE
Definition: types.h:120
#define CmResourceTypeMemory
Definition: restypes.h:106
unsigned char UCHAR
Definition: typedefs.h:53
_In_ ULONG _In_ PVOID _In_ LONG DescriptorType
Definition: usbdlib.h:160
#define CmResourceTypeMemoryLarge
Definition: cmtypes.h:231

Referenced by ArbpForEachRegistryRange().

◆ ArbpExcludeOrderingRange()

static NTSTATUS ArbpExcludeOrderingRange ( _Inout_ PARBITER_ORDERING_LIST  OrderingList,
_In_ UINT64  Start,
_In_ UINT64  End 
)
static

Removes [Start, End] from every window of an ordering list, splitting windows that straddle it.

Parameters
[in,out]OrderingListThe ordering list to prune. The pruned set is built in a temporary list and swapped in on success; on failure the original list is left untouched.
[in]StartThe inclusive start of the range to remove.
[in]EndThe inclusive end of the range to remove. Must not be below Start.
Returns
Returns STATUS_SUCCESS, STATUS_INVALID_PARAMETER for a backwards range, or STATUS_INSUFFICIENT_RESOURCES.

Definition at line 146 of file ordering.c.

150{
154
155 PAGED_CODE();
156
157 if (End < Start)
159
161 if (!NT_SUCCESS(Status))
162 return Status;
163
164 for (Index = 0; Index < OrderingList->Count; ++Index)
165 {
166 UINT64 CurrentStart = OrderingList->Orderings[Index].Start;
167 UINT64 CurrentEnd = OrderingList->Orderings[Index].End;
168
170
171 if (CurrentEnd < Start || CurrentStart > End)
172 {
173 /* Wholly outside the hole: survives unchanged. */
174 Status = ArbiterLibAddOrdering(&Pruned, CurrentStart, CurrentEnd);
175 }
176 else
177 {
178 if (CurrentStart < Start) /* Left fragment survives */
179 Status = ArbiterLibAddOrdering(&Pruned, CurrentStart, Start - 1);
180
181 if (NT_SUCCESS(Status) && CurrentEnd > End) /* Right fragment survives */
182 Status = ArbiterLibAddOrdering(&Pruned, End + 1, CurrentEnd);
183 }
184
185 if (!NT_SUCCESS(Status))
186 {
188 return Status;
189 }
190 }
191
192 ArbiterLibFreeOrderingList(OrderingList);
193 *OrderingList = Pruned;
194 return STATUS_SUCCESS;
195}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by ArbpAddReservedCallback().

◆ ArbpForEachRegistryRange()

static NTSTATUS ArbpForEachRegistryRange ( _In_ PARBITER_INSTANCE  Arbiter,
_In_ PCWSTR  Subkey,
_In_ PCWSTR  ValueName,
_In_opt_ PARB_TRANSLATE_ORDERING  Translate,
_In_ PARB_RANGE_CALLBACK  Callback,
_In_opt_ PVOID  Context 
)
static

Definition at line 313 of file ordering.c.

320{
324
325 PAGED_CODE();
326
328 return STATUS_SUCCESS;
329
331
332 /* Follow a REG_SZ indirection to the named sibling value. */
333 if (NT_SUCCESS(Status) && Value->Type == REG_SZ)
334 {
335 PWSTR TargetName = (PWSTR)((PUCHAR)Value + Value->DataOffset);
336 ULONG TargetChars = Value->DataLength / sizeof(WCHAR);
338
339 if (TargetChars != 0 &&
340 TargetName[TargetChars - 1] == UNICODE_NULL &&
342 {
344 Value = Target;
345 }
346 }
347
348 if (NT_SUCCESS(Status) &&
350 Value->DataLength >= sizeof(IO_RESOURCE_REQUIREMENTS_LIST))
351 {
353 PIO_RESOURCE_LIST Alternative;
354 PUCHAR DataEnd;
355 ULONG Index;
356
357 Requirements = (PIO_RESOURCE_REQUIREMENTS_LIST)((PUCHAR)Value + Value->DataOffset);
358 DataEnd = (PUCHAR)Requirements + Value->DataLength;
359 Alternative = &Requirements->List[0];
360
361 for (Index = 0; Index < Alternative->Count; ++Index)
362 {
365 UINT64 Minimum, Maximum, Length, Alignment;
366
367 /* Never trust the stored Count past the actual value data. */
368 if ((PUCHAR)(Descriptor + 1) > DataEnd)
369 break;
370
371 /*
372 * Policy windows are written in bus-relative terms, so an arbiter
373 * that allocates in a different space translates each one first.
374 * A window it cannot translate comes back CmResourceTypeNull and
375 * is dropped by the type test below.
376 */
377 if (Translate != NULL)
378 {
379 Status = Translate(&Window, Descriptor);
380 if (!NT_SUCCESS(Status))
381 break;
382 }
383 else
384 {
386 }
387
388 if (!ArbpDescriptorMatchesArbiter(Arbiter, Window.Type))
389 continue;
390
391 /*
392 * Decode through the arbiter's own callback: the bounds live in a
393 * different union member for every resource type.
394 */
395 Status = Arbiter->UnpackRequirement(&Window, &Minimum, &Maximum,
396 &Length, &Alignment);
397 if (!NT_SUCCESS(Status))
398
399 break;
400 Callback(Arbiter, Context, Minimum, Maximum);
401 }
402 }
403
404 if (Value != NULL)
407 return STATUS_SUCCESS;
408}
#define REG_SZ
Definition: layer.c:22
_In_ ULONG _In_ ULONG _In_opt_ DXGKCB_MIRACAST_SEND_MESSAGE_CALLBACK Callback
Definition: dispmprt.h:620
union Alignment_ Alignment
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define REG_RESOURCE_REQUIREMENTS_LIST
Definition: nt_native.h:1507
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static BOOLEAN ArbpDescriptorMatchesArbiter(_In_ PARBITER_INSTANCE Arbiter, _In_ UCHAR DescriptorType)
Definition: ordering.c:292
static NTSTATUS ArbpReadPolicyValue(_In_ HANDLE KeyHandle, _In_ PCWSTR ValueName, _Out_ PKEY_VALUE_FULL_INFORMATION *Value)
Definition: ordering.c:244
static NTSTATUS ArbpOpenPolicySubkey(_In_ PCWSTR SubkeyName, _Out_ PHANDLE KeyHandle)
Definition: ordering.c:217
short WCHAR
Definition: pedump.c:58
static PCWSTR TargetName
Definition: ping.c:67
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
Definition: window.c:29
IO_RESOURCE_DESCRIPTOR Descriptors[1]
Definition: iotypes.h:2739
IO_RESOURCE_LIST List[1]
Definition: iotypes.h:2749
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST

Referenced by ArbiterLibAddInaccessibleAllocationRange(), ArbiterLibAddMmConfigRangeAsBootReserved(), and ArbiterLibDefaultAssignmentOrdering().

◆ ArbpMmConfigCallback()

static VOID NTAPI ArbpMmConfigCallback ( _In_ PARBITER_INSTANCE  Arbiter,
_In_opt_ PVOID  Context,
_In_ ULONGLONG  Start,
_In_ ULONGLONG  End 
)
static

Range callback recording the MMCONFIG (ECAM) window and reserving it in a range list as a boot allocation.

Parameters
[in]ArbiterUnused.
[in]ContextThe RTL_RANGE_LIST to reserve the window in.
[in]StartThe inclusive start of the ECAM window.
[in]EndThe inclusive end of the ECAM window.

Definition at line 523 of file ordering.c.

Referenced by ArbiterLibAddMmConfigRangeAsBootReserved().

◆ ArbpOpenPolicySubkey()

static NTSTATUS ArbpOpenPolicySubkey ( _In_ PCWSTR  SubkeyName,
_Out_ PHANDLE  KeyHandle 
)
static

Definition at line 217 of file ordering.c.

220{
221 WCHAR PathBuffer[sizeof(ARBP_POLICY_ROOT ARBP_LONGEST_SUBKEY) / sizeof(WCHAR)];
222 UNICODE_STRING KeyPath;
225
226 PAGED_CODE();
227
228 RtlInitEmptyUnicodeString(&KeyPath, PathBuffer, sizeof(PathBuffer));
230 if (NT_SUCCESS(Status))
232 if (!NT_SUCCESS(Status))
233 return Status;
234
237 return ZwOpenKey(KeyHandle, KEY_READ, &ObjectAttributes);
238}
_In_opt_ PWSTR SubkeyName
Definition: cdrom.h:960
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define KEY_READ
Definition: nt_native.h:1026
#define ARBP_POLICY_ROOT
Definition: ordering.c:20
#define ARBP_LONGEST_SUBKEY
Definition: ordering.c:21
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228

Referenced by ArbpForEachRegistryRange().

◆ ArbpReadPolicyValue()

static NTSTATUS ArbpReadPolicyValue ( _In_ HANDLE  KeyHandle,
_In_ PCWSTR  ValueName,
_Out_ PKEY_VALUE_FULL_INFORMATION *  Value 
)
static

Definition at line 244 of file ordering.c.

248{
249 UNICODE_STRING NameString;
251 ULONG Size = 0;
254
255 PAGED_CODE();
256
257 RtlInitUnicodeString(&NameString, ValueName);
258
259 /* Size probe: only a buffer-size result means the value is readable. */
260 Status = ZwQueryValueKey(KeyHandle, &NameString, KeyValueFullInformationAlign64,
261 NULL, 0, &Size);
264
266 if (Buffer == NULL)
268
269 Status = ZwQueryValueKey(KeyHandle, &NameString, KeyValueFullInformationAlign64,
271
272 if (NT_SUCCESS(Status) &&
273 ((ULONGLONG)Buffer->DataOffset + Buffer->DataLength > ResultLength))
274 {
276 }
277
278 if (!NT_SUCCESS(Status))
279 {
281 return Status;
282 }
283
284 *Value = Buffer;
285 return STATUS_SUCCESS;
286}
Definition: bufpool.h:45
@ KeyValueFullInformationAlign64
Definition: reg.c:111
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3782
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by ArbpForEachRegistryRange().

Variable Documentation

◆ ArbpMmConfigEnd

ULONGLONG ArbpMmConfigEnd = 0
static

Definition at line 29 of file ordering.c.

Referenced by ArbiterLibIsConflictWithMmConfigRange(), and ArbpMmConfigCallback().

◆ ArbpMmConfigStart

ULONGLONG ArbpMmConfigStart = 1
static

Definition at line 28 of file ordering.c.

Referenced by ArbiterLibIsConflictWithMmConfigRange(), and ArbpMmConfigCallback().