ReactOS 0.4.17-dev-806-gffa4164
range.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Arbitration Library
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Allocation range search core
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include <ntifs.h>
11#include <ndk/rtlfuncs.h>
12#include "arbiter.h"
13
14#define NDEBUG
15#include <debug.h>
16
17/* RANGE WALKER ***************************************************************/
18
19#define ARBITER_RESERVED_PASS_DONE 0xFFFFFFFF
20
45CODE_SEG("PAGE")
49 _In_ PARBITER_INSTANCE Arbiter,
51{
53 PRTL_RANGE Range;
54 BOOLEAN SelfConflictOnly = FALSE;
55
56 PAGED_CODE();
57
58 /*
59 * Only a fixed requirement may reclaim its window. Anything else still
60 * has other placements to try, and letting it overlap would hide
61 * real conflicts.
62 */
63 if (ArbState->CurrentAlternative == NULL ||
64 !(ArbState->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_FIXED))
65 {
66 return FALSE;
67 }
68
69 if (ArbState->Entry == NULL || ArbState->Entry->PhysicalDeviceObject == NULL)
70 return FALSE;
71
72 if (!NT_SUCCESS(RtlGetFirstRange(Arbiter->PossibleAllocation, &Iterator, &Range)))
73 return FALSE;
74
75 while (Range != NULL)
76 {
77 /* A range that overlaps the window and is not made available. */
78 if (Range->Start <= ArbState->CurrentMaximum &&
79 Range->End >= ArbState->CurrentMinimum &&
80 !(Range->Attributes & ArbState->RangeAvailableAttributes))
81 {
82 if ((PDEVICE_OBJECT)Range->Owner != ArbState->Entry->PhysicalDeviceObject)
83 return FALSE;
84
85 SelfConflictOnly = TRUE;
86 ArbState->Start = ArbState->CurrentMinimum;
87 ArbState->End = ArbState->CurrentMaximum;
88 }
89
90 if (!NT_SUCCESS(RtlGetNextRange(&Iterator, &Range, TRUE)))
91 break;
92 }
93
94 return SelfConflictOnly;
95}
96
113CODE_SEG("PAGE")
114static
115VOID
117 _In_ PARBITER_INSTANCE Arbiter,
118 _Inout_ PARBITER_ALTERNATIVE Alternative)
119{
120 PARBITER_ORDERING Ordering;
122 INT32 Priority = Alternative->Priority;
123 BOOLEAN Preferred;
124 ULONG Index;
125
126 PAGED_CODE();
127
129 return;
130
133 {
134 /* Stay in the reserved pass until its final whole-window try is spent. */
135 if (Alternative->Reserved[0] == ARBITER_RESERVED_PASS_DONE)
136 Alternative->Priority = ARBITER_PRIORITY_EXHAUSTED;
137 return;
138 }
139
140 Preferred = (Alternative->Descriptor->Option & IO_RESOURCE_PREFERRED) != 0;
141
143 {
144 Ordering = Arbiter->OrderingList.Orderings;
145 }
146 else
147 {
148 /* A fixed alternative fits in exactly one place; it gets a single shot. */
149 if (Alternative->Flags & ARBITER_ALTERNATIVE_FLAG_FIXED)
150 {
151 Alternative->Priority = ARBITER_PRIORITY_EXHAUSTED;
152 return;
153 }
154
155 Index = (Priority < 0) ? (ULONG)(-(Priority + 1)) : (ULONG)(Priority - 1);
156 if (Index >= Arbiter->OrderingList.Count)
157 {
158 Alternative->Reserved[0] = 0;
159 Alternative->Priority = Preferred ? ARBITER_PRIORITY_PREFERRED_RESERVED
161 return;
162 }
163 Ordering = &Arbiter->OrderingList.Orderings[Index + 1];
164 }
165
166 End = &Arbiter->OrderingList.Orderings[Arbiter->OrderingList.Count];
167 for (; Ordering < End; ++Ordering)
168 {
169 UINT64 Start, RangeEnd;
170
171 if (Ordering->Start > Alternative->Maximum ||
172 Alternative->Minimum > Ordering->End)
173 {
174 continue; /* No intersection with this alternative's window */
175 }
176
177 Start = max(Alternative->Minimum, Ordering->Start);
178 RangeEnd = min(Alternative->Maximum, Ordering->End);
179
180 if ((RangeEnd - Start + 1) >= Alternative->Length)
181 {
182 INT32 NewPriority = (INT32)(Ordering - Arbiter->OrderingList.Orderings) + 1;
183 Alternative->Priority = Preferred ? -NewPriority : NewPriority;
184 return;
185 }
186 }
187
188 Alternative->Reserved[0] = 0;
189 Alternative->Priority = Preferred ? ARBITER_PRIORITY_PREFERRED_RESERVED
191}
192
205CODE_SEG("PAGE")
206static
210{
211 WCHAR Buffer[16];
214 ULONG Length = 0;
215
216 PAGED_CODE();
217
218 if (DeviceObject == NULL)
219 return FALSE;
220
222 sizeof(Buffer), Buffer, &Length)))
223 {
224 return FALSE;
225 }
226
229}
230
246CODE_SEG("PAGE")
247static
250 _In_ PDEVICE_OBJECT DeviceA,
251 _In_ PDEVICE_OBJECT DeviceB)
252{
254
255 PAGED_CODE();
256
257 for (A = DeviceA->AttachedDevice; A != NULL; A = A->AttachedDevice)
258 {
259 for (B = DeviceB->AttachedDevice; B != NULL; B = B->AttachedDevice)
260 {
261 if (A->DriverObject == B->DriverObject)
262 return TRUE;
263 }
264 }
265
266 return FALSE;
267}
268
297CODE_SEG("PAGE")
298static
301 _In_ PARBITER_INSTANCE Arbiter,
303{
304 PARBITER_LIST_ENTRY Entry = ArbState->Entry;
305 PDEVICE_OBJECT Requester;
307 PRTL_RANGE Range;
308 BOOLEAN RequesterIsRoot;
309
310 PAGED_CODE();
311
312 if (Entry == NULL || Entry->PhysicalDeviceObject == NULL ||
313 ArbState->CurrentAlternative == NULL)
314 {
315 return FALSE;
316 }
317
318 Requester = Entry->PhysicalDeviceObject;
319 RequesterIsRoot = ArbpIsRootEnumerated(Requester);
320
321 if (!NT_SUCCESS(RtlGetFirstRange(Arbiter->PossibleAllocation, &Iterator, &Range)))
322 return FALSE;
323
324 while (Range != NULL)
325 {
326 /*
327 * Candidate: overlaps the requested window, is not already made available
328 * by attribute, and either the request or the range is driver-exclusive.
329 */
330 if (Range->Start <= ArbState->CurrentMaximum &&
331 Range->End >= ArbState->CurrentMinimum &&
332 !(Range->Attributes & ArbState->RangeAvailableAttributes) &&
333 (ArbState->CurrentAlternative->Descriptor->ShareDisposition == CmResourceShareDriverExclusive ||
335 Range->Owner != NULL)
336 {
338 BOOLEAN Share = FALSE;
339
340 /* Two root-enumerated devices may share; else only a shared driver. */
341 if (RequesterIsRoot && ArbpIsRootEnumerated(Owner))
342 Share = TRUE;
343 else if (ArbpSharesDriverStack(Requester, Owner))
344 Share = TRUE;
345
346 if (Share)
347 {
348 ArbState->Start = ArbState->CurrentMinimum;
349 ArbState->End = ArbState->CurrentMaximum;
350 if (ArbState->CurrentAlternative->Descriptor->ShareDisposition ==
352 {
353 ArbState->RangeAttributes |= ARBITER_RANGE_SHARED_DRIVER;
354 }
355 return TRUE;
356 }
357 }
358
359 if (!NT_SUCCESS(RtlGetNextRange(&Iterator, &Range, TRUE)))
360 break;
361 }
362
363 return FALSE;
364}
365
398CODE_SEG("PAGE")
399static
402 _In_ PARBITER_INSTANCE Arbiter,
404{
405 PARBITER_LIST_ENTRY Entry = ArbState->Entry;
406 PARBITER_ALTERNATIVE Alternative = ArbState->CurrentAlternative;
408 PRTL_RANGE Range;
409
410 PAGED_CODE();
411
412 if (Arbiter->ResourceType != CmResourceTypeInterrupt)
413 return FALSE;
414
415 if (Entry == NULL || Entry->PhysicalDeviceObject == NULL || Alternative == NULL)
416 return FALSE;
417
418 if (!NT_SUCCESS(RtlGetFirstRange(Arbiter->Allocation, &Iterator, &Range)))
419 return FALSE;
420
421 while (Range != NULL)
422 {
423 if ((PDEVICE_OBJECT)Range->Owner == Entry->PhysicalDeviceObject &&
424 Range->Start >= ArbState->CurrentMinimum &&
425 Range->Start <= ArbState->CurrentMaximum &&
426 Range->End <= ArbState->CurrentMaximum &&
427 (Range->End - Range->Start + 1) >= Alternative->Length)
428 {
429 ArbState->Start = Range->Start;
430 ArbState->End = Range->Start + Alternative->Length - 1;
431 return TRUE;
432 }
433
434 if (!NT_SUCCESS(RtlGetNextRange(&Iterator, &Range, TRUE)))
435 break;
436 }
437
438 return FALSE;
439}
440
469CODE_SEG("PAGE")
470static
473 _In_ PARBITER_INSTANCE Arbiter,
474 _Inout_ PARBITER_ALTERNATIVE Alternative,
475 _Out_ PUINT64 Minimum,
476 _Out_ PUINT64 Maximum)
477{
478 ULONG Index;
479
480 PAGED_CODE();
481
482 if (Alternative->Reserved[0] == ARBITER_RESERVED_PASS_DONE)
483 return FALSE;
484
485 for (Index = Alternative->Reserved[0];
486 Index < Arbiter->ReservedList.Count;
487 ++Index)
488 {
489 PARBITER_ORDERING Window = &Arbiter->ReservedList.Orderings[Index];
490 UINT64 Lo, Hi;
491
492 if (Window->Start > Alternative->Maximum ||
493 Alternative->Minimum > Window->End)
494 {
495 continue; /* No intersection with this alternative's window */
496 }
497
498 Lo = max(Alternative->Minimum, Window->Start);
499 Hi = min(Alternative->Maximum, Window->End);
500 if ((Hi - Lo + 1) < Alternative->Length)
501 continue;
502
503 Alternative->Reserved[0] = Index + 1;
504 *Minimum = Lo;
505 *Maximum = Hi;
506 return TRUE;
507 }
508
509 /*
510 * Reserved windows exhausted. A final whole-window pass follows
511 * turns on FIXED, and either answer is wrong for the other case.
512 *
513 * A flexible alternative must not get one: [Minimum, Maximum] ignores both
514 * the ordering and the reserved list, re-granting the ranges the reserved
515 * pass had just punched out. A bridge's [0, 0xFFFFFFFF] memory window
516 * searched against an empty pool resolves to 0, placing the window on top
517 * of RAM.
518 *
519 * A fixed alternative must get one: it has a single possible placement, so
520 * the whole window is that candidate. Withholding it goes straight to
521 * EXHAUSTED without ever calling FindSuitableRange, so neither the
522 * boot-allocated availability mask nor OverrideConflict can grant the
523 * device its own firmware configuration. That is fatal whenever no
524 * ordering window spans the requirement, as the root port list's does not
525 * below 0x100.
526 */
527 Alternative->Reserved[0] = ARBITER_RESERVED_PASS_DONE;
528
529 if (Alternative->Flags & ARBITER_ALTERNATIVE_FLAG_FIXED)
530 {
531 *Minimum = Alternative->Minimum;
532 *Maximum = Alternative->Maximum;
533 return TRUE;
534 }
535
536 return FALSE;
537}
538
559CODE_SEG("PAGE")
561NTAPI
563 _In_ PARBITER_INSTANCE Arbiter,
565{
566 PARBITER_ALTERNATIVE Alternative;
568 UINT64 Minimum, Maximum;
569
570 PAGED_CODE();
571
572 if (ArbState->AlternativeCount == 0)
573 return FALSE;
574
575 for (;;)
576 {
577 /* Advance the alternative we last worked on, or seed all on first entry. */
578 if (ArbState->CurrentAlternative != NULL)
579 {
580 ArbpWritePriority(Arbiter, ArbState->CurrentAlternative);
581 }
582 else
583 {
584 for (Alternative = ArbState->Alternatives;
585 Alternative < &ArbState->Alternatives[ArbState->AlternativeCount];
586 ++Alternative)
587 {
588 Alternative->Priority = ARBITER_PRIORITY_NULL;
589 ArbpWritePriority(Arbiter, Alternative);
590 }
591 }
592
593 /* Pick the best (lowest-priority) alternative. */
594 Lowest = ArbState->Alternatives;
595 for (Alternative = ArbState->Alternatives + 1;
596 Alternative < &ArbState->Alternatives[ArbState->AlternativeCount];
597 ++Alternative)
598 {
599 if (Alternative->Priority < Lowest->Priority)
600 Lowest = Alternative;
601 }
602
604 return FALSE;
605
606 if (Lowest->Priority == ARBITER_PRIORITY_RESERVED ||
608 {
609 /*
610 * Last-resort pass: the reserved windows in turn, then the whole
611 * requirement window (see ArbpTakeReservedWindow).
612 */
613 if (!ArbpTakeReservedWindow(Arbiter, Lowest, &Minimum, &Maximum))
614 {
615 /*
616 * CurrentAlternative must be set before looping. While it is
617 * still NULL, the top of the loop re-seeds every alternative's
618 * priority back to ARBITER_PRIORITY_NULL, which would discard
619 * the EXHAUSTED just recorded and spin forever.
620 */
622 ArbState->CurrentAlternative = Lowest;
623 continue;
624 }
625 }
626 else
627 {
628 PARBITER_ORDERING Ordering;
629 ULONG Index = (Lowest->Priority < 0) ? (ULONG)(-(Lowest->Priority + 1))
630 : (ULONG)(Lowest->Priority - 1);
631 if (Index >= Arbiter->OrderingList.Count)
632 {
634 ArbState->CurrentAlternative = Lowest;
635 continue;
636 }
637 Ordering = &Arbiter->OrderingList.Orderings[Index];
638 Minimum = max(Lowest->Minimum, Ordering->Start);
639 Maximum = min(Lowest->Maximum, Ordering->End);
640 }
641
642 /*
643 * Trim the window so an aligned allocation of the required length is
644 * possible; skip the window entirely if it cannot hold one.
645 */
646 if (Lowest->Length != 0)
647 {
648 UINT64 Alignment = Lowest->Alignment ? Lowest->Alignment : 1;
649 UINT64 LengthMinusOne = Lowest->Length - 1;
650 UINT64 AlignedMax;
651
652 Minimum += Alignment - 1;
653 Minimum -= Minimum % Alignment;
654
655 if (Minimum > Maximum || LengthMinusOne > Maximum - Minimum)
656 {
657 ArbState->CurrentAlternative = Lowest; /* consume this priority */
658 continue;
659 }
660
661 AlignedMax = Maximum - LengthMinusOne;
662 AlignedMax -= AlignedMax % Alignment;
663 if (AlignedMax < Minimum)
664 {
665 ArbState->CurrentAlternative = Lowest; /* no aligned start fits */
666 continue;
667 }
668 Maximum = AlignedMax + LengthMinusOne;
669 }
670 else
671 {
672 Minimum = Lowest->Minimum;
673 Maximum = Lowest->Maximum;
674 }
675
676 if (Minimum != ArbState->CurrentMinimum ||
677 Maximum != ArbState->CurrentMaximum ||
678 ArbState->CurrentAlternative != Lowest)
679 {
680 ArbState->CurrentMinimum = Minimum;
681 ArbState->CurrentMaximum = Maximum;
682 ArbState->CurrentAlternative = Lowest;
683 return TRUE;
684 }
685
686 ArbState->CurrentAlternative = Lowest;
687 }
688}
689
714CODE_SEG("PAGE")
716NTAPI
718 _In_ PARBITER_INSTANCE Arbiter,
720{
721 PARBITER_ALTERNATIVE Alternative = ArbState->CurrentAlternative;
722 ULONG Flags = 0;
724
725 PAGED_CODE();
726
727 if (Alternative == NULL)
728 return FALSE;
729
730 if (ArbState->CurrentMinimum > ArbState->CurrentMaximum)
731 return FALSE;
732
733 if (Alternative->Length == 0)
734 {
735 ArbState->Start = ArbState->CurrentMinimum;
736 ArbState->End = ArbState->CurrentMinimum;
737 return TRUE;
738 }
739
740 /*
741 * Interrupt retention: give the device back its firmware-routed vector rather
742 * than letting the top-down search pick an untranslatable one
743 */
744 if (ArbpReuseOwnedInterrupt(Arbiter, ArbState))
745 return TRUE;
746
747 /* Legacy requests consider preallocated (boot) ranges available. */
748 if (ArbState->Entry != NULL &&
749 (ArbState->Entry->RequestSource == ArbiterRequestLegacyReported ||
750 ArbState->Entry->RequestSource == ArbiterRequestLegacyAssigned))
751 {
752 ArbState->RangeAvailableAttributes |= ARBITER_RANGE_BOOT_ALLOCATED;
753 }
754
755 if (ArbState->Flags & ARBITER_STATE_FLAG_NULL_CONFLICT_OK)
757 if (Alternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED)
760 ArbState->RangeAvailableAttributes |= ARBITER_RANGE_INACCESSIBLE;
761
762 Status = RtlFindRange(Arbiter->PossibleAllocation,
763 ArbState->CurrentMinimum,
764 ArbState->CurrentMaximum,
765 Alternative->Length,
766 max(Alternative->Alignment, 1),
767 Flags,
768 ArbState->RangeAvailableAttributes,
769 Arbiter->ConflictCallbackContext,
770 Arbiter->ConflictCallback,
771 &ArbState->Start);
772 if (!NT_SUCCESS(Status))
773 {
774 /*
775 * The window is occupied. A CmResourceShareDriverExclusive requirement
776 * can still succeed by sharing the conflicting range with the same driver
777 * or another root-enumerated device
778 *
779 * This matters a lot because HAL reverses quite a bit and marks it this.
780 * This mechanism is how Windows "internally allows this".
781 */
782 if (ArbpShareDriverExclusive(Arbiter, ArbState))
783 return TRUE;
784 if (Arbiter->OverrideConflict != NULL &&
785 Arbiter->OverrideConflict(Arbiter, ArbState))
786 {
787 return TRUE;
788 }
789
790 /*
791 * A window that only fails because it runs into the MMCONFIG region
792 * points at the firmware's MCFG table rather than at any device.
793 */
794 if (ArbiterLibIsConflictWithMmConfigRange(ArbState->CurrentMinimum,
795 ArbState->CurrentMaximum))
796 {
797 ArbState->Flags |= ARBITER_STATE_FLAG_MCFG_CONFLICT;
798 }
799
800 return FALSE;
801 }
802
803 ArbState->End = ArbState->Start + Alternative->Length - 1;
804 return TRUE;
805}
806
825CODE_SEG("PAGE")
826VOID
827NTAPI
829 _In_ PARBITER_INSTANCE Arbiter,
831{
833
834 PAGED_CODE();
835
836 if (ArbState->CurrentAlternative != NULL &&
837 (ArbState->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED))
838 {
840 }
841
842 RtlAddRange(Arbiter->PossibleAllocation,
843 ArbState->Start,
844 ArbState->End,
845 ArbState->RangeAttributes,
846 Flags,
847 NULL,
848 ArbState->Entry ? ArbState->Entry->PhysicalDeviceObject : NULL);
849}
850
863CODE_SEG("PAGE")
864VOID
865NTAPI
867 _In_ PARBITER_INSTANCE Arbiter,
869{
870 PAGED_CODE();
871
872 RtlDeleteRange(Arbiter->PossibleAllocation,
873 ArbState->Start,
874 ArbState->End,
875 ArbState->Entry ? ArbState->Entry->PhysicalDeviceObject : NULL);
876}
#define PAGED_CODE()
#define CODE_SEG(...)
static _Out_opt_ PULONGLONG Start
unsigned char BOOLEAN
Definition: actypes.h:127
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define ARBITER_STATE_FLAG_NULL_CONFLICT_OK
Definition: arbiter.h:60
#define ARBITER_ALTERNATIVE_FLAG_SHARED
Definition: arbiter.h:31
#define ARBITER_PRIORITY_NULL
Definition: arbiter.h:25
#define ARBITER_PRIORITY_RESERVED
Definition: arbiter.h:27
#define ARBITER_PRIORITY_EXHAUSTED
Definition: arbiter.h:28
#define ARBITER_STATE_FLAG_MCFG_CONFLICT
Definition: arbiter.h:62
#define ARBITER_RANGE_INACCESSIBLE
Definition: arbiter.h:56
#define ARBITER_ALTERNATIVE_FLAG_INACCESSIBLE_OK
Definition: arbiter.h:34
#define ARBITER_PRIORITY_PREFERRED_RESERVED
Definition: arbiter.h:26
BOOLEAN NTAPI ArbiterLibIsConflictWithMmConfigRange(_In_ ULONGLONG Start, _In_ ULONGLONG End)
Determines whether a range overlaps the recorded MMCONFIG window.
Definition: ordering.c:689
#define ARBITER_RANGE_SHARED_DRIVER
Definition: arbiter.h:54
#define ARBITER_ALTERNATIVE_FLAG_FIXED
Definition: arbiter.h:32
#define ARBITER_RANGE_BOOT_ALLOCATED
Definition: arbiter.h:53
LONG NTSTATUS
Definition: precomp.h:26
unsigned __int64 * PUINT64
Definition: basetsd.h:181
Definition: ehthrow.cxx:93
Definition: ehthrow.cxx:54
Definition: bufpool.h:45
LPWSTR Name
Definition: desk.c:124
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define A(row, col)
#define B(row, col)
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define L(x)
Definition: resources.c:13
struct _DEVICE_OBJECT * PDEVICE_OBJECT
union Alignment_ Alignment
Status
Definition: gdiplustypes.h:24
if(dx< 0)
Definition: linetemp.h:194
#define min(a, b)
Definition: monoChain.cc:55
@ Root
Definition: cmtypes.h:261
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1629
NTSYSAPI NTSTATUS NTAPI RtlDeleteRange(_Inout_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ PVOID Owner)
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)
NTSYSAPI NTSTATUS NTAPI RtlFindRange(_In_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Minimum, _In_ ULONGLONG Maximum, _In_ ULONGLONG Length, _In_ ULONGLONG Alignment, _In_ ULONG Flags, _In_ UCHAR AttributeAvailableMask, _In_opt_ PVOID Context, _In_opt_ PRTL_CONFLICT_RANGE_CALLBACK Callback, _Out_ PULONGLONG Start)
NTSYSAPI NTSTATUS NTAPI RtlGetNextRange(_Inout_ PRTL_RANGE_LIST_ITERATOR Iterator, _Outptr_ PRTL_RANGE *Range, _In_ BOOLEAN MoveForwards)
NTSYSAPI NTSTATUS NTAPI RtlGetFirstRange(_In_ PRTL_RANGE_LIST RangeList, _Out_ PRTL_RANGE_LIST_ITERATOR Iterator, _Outptr_ PRTL_RANGE *Range)
#define RTL_RANGE_LIST_ADD_IF_CONFLICT
Definition: rtltypes.h:81
#define RTL_RANGE_LIST_ADD_SHARED
Definition: rtltypes.h:82
#define RTL_RANGE_LIST_NULL_CONFLICT_OK
Definition: rtltypes.h:90
#define RTL_RANGE_LIST_SHARED_OK
Definition: rtltypes.h:89
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
short WCHAR
Definition: pedump.c:58
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:1382
BOOLEAN NTAPI ArbiterLibGetNextAllocationRange(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_ALLOCATION_STATE ArbState)
Moves the working window to the next candidate range, walking the entry's alternatives in priority or...
Definition: range.c:562
static BOOLEAN ArbpTakeReservedWindow(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_ALTERNATIVE Alternative, _Out_ PUINT64 Minimum, _Out_ PUINT64 Maximum)
Takes the next window of the reserved (last-resort) pass for an alternative: each ReservedList range ...
Definition: range.c:472
VOID NTAPI ArbiterLibBacktrackAllocation(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_ALLOCATION_STATE ArbState)
Undoes the last AddAllocation performed for this entry.
Definition: range.c:866
BOOLEAN NTAPI ArbiterLibFindSuitableRange(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_ALLOCATION_STATE ArbState)
Finds a free range of the current candidate window in the arbiter's tentative allocation list.
Definition: range.c:717
static VOID ArbpWritePriority(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_ALTERNATIVE Alternative)
Writes an alternative's priority to the next ordering-list range it can be satisfied from.
Definition: range.c:116
static BOOLEAN ArbpSharesDriverStack(_In_ PDEVICE_OBJECT DeviceA, _In_ PDEVICE_OBJECT DeviceB)
Determines whether a common driver is loaded on both device stacks, above the physical device objects...
Definition: range.c:249
static BOOLEAN ArbpShareDriverExclusive(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_ALLOCATION_STATE ArbState)
Attempts last-chance sharing for a CmResourceShareDriverExclusive requirement whose window RtlFindRan...
Definition: range.c:300
BOOLEAN NTAPI ArbiterLibOverrideConflict(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_ALLOCATION_STATE ArbState)
The OverrideConflict default, the last of the conflict escapes: grants a FIXED requirement whose wind...
Definition: range.c:48
VOID NTAPI ArbiterLibAddAllocation(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_ALLOCATION_STATE ArbState)
Records the chosen placement in the arbiter's tentative allocation list, owned by the requesting devi...
Definition: range.c:828
static BOOLEAN ArbpReuseOwnedInterrupt(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_ALLOCATION_STATE ArbState)
Hands a device back its own already routed IRQ instead of searching for a fresh one,...
Definition: range.c:401
static BOOLEAN ArbpIsRootEnumerated(_In_ PDEVICE_OBJECT DeviceObject)
Determines whether a device is enumerated by the root enumerator.
Definition: range.c:208
#define ARBITER_RESERVED_PASS_DONE
Definition: range.c:19
#define CmResourceTypeInterrupt
Definition: restypes.h:105
Entry
Definition: section.c:5216
Definition: window.c:29
Definition: iotypes.h:4633
UINT64 Start
Definition: arbiter.h:99
ULONGLONG End
Definition: rtltypes.h:1497
ULONGLONG Start
Definition: rtltypes.h:1496
UCHAR Attributes
Definition: rtltypes.h:1500
PVOID Owner
Definition: rtltypes.h:1499
#define max(a, b)
Definition: svc.c:63
int32_t INT32
Definition: typedefs.h:58
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:656
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
@ CmResourceShareDriverExclusive
Definition: cmtypes.h:242
@ ArbiterRequestLegacyAssigned
Definition: iotypes.h:4619
@ ArbiterRequestLegacyReported
Definition: iotypes.h:4617
@ DevicePropertyEnumeratorName
Definition: iotypes.h:1210
#define IO_RESOURCE_PREFERRED