ReactOS 0.4.17-dev-923-g4c9a150
transaction.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Arbitrartion Library
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Test/retest/commit/rollback transaction support
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/* TRANSACTION SUPPORT ********************************************************/
18
41CODE_SEG("PAGE")
42static
45 _In_ PARBITER_INSTANCE Arbiter,
47 _Out_ PARBITER_ALTERNATIVE Alternative)
48{
51
52 PAGED_CODE();
53
54 /*
55 * UnpackRequirement always writes 64-bit Length/Alignment; ARBITER_ALTERNATIVE
56 * narrows them to 32 bits pre-Vista, so decode through 64-bit temporaries and
57 * assign, just to keep both versions in source.
58 */
59 Alternative->Descriptor = Descriptor;
60 Status = Arbiter->UnpackRequirement(Descriptor,
61 &Alternative->Minimum,
62 &Alternative->Maximum,
63 &Length,
64 &Alignment);
65 if (!NT_SUCCESS(Status))
66 return Status;
67
68#if (NTDDI_VERSION >= NTDDI_VISTA) || defined(__REACTOS__)
69 Alternative->Length = Length;
70 Alternative->Alignment = Alignment;
71#else
72 Alternative->Length = (UINT32)Length;
73 Alternative->Alignment = (UINT32)Alignment;
74#endif
75
76 if (Alignment != 0 && (Alternative->Minimum % Alignment) != 0)
77 Alternative->Minimum += Alignment - (Alternative->Minimum % Alignment);
78
79 Alternative->Flags = 0;
80 Alternative->Priority = ARBITER_PRIORITY_NULL;
81
82 if (Descriptor->ShareDisposition == CmResourceShareShared)
83 Alternative->Flags |= ARBITER_ALTERNATIVE_FLAG_SHARED;
84
85 if (Alternative->Maximum < Alternative->Minimum)
86 Alternative->Flags |= ARBITER_ALTERNATIVE_FLAG_BADRANGE;
87 else if ((Alternative->Maximum - Alternative->Minimum + 1) == Alternative->Length)
88 Alternative->Flags |= ARBITER_ALTERNATIVE_FLAG_FIXED;
89
93 {
94 Alternative->Flags |= ARBITER_ALTERNATIVE_FLAG_INACCESSIBLE_OK;
95 }
96
97 return STATUS_SUCCESS;
98}
99
123CODE_SEG("PAGE")
124static
127 _In_ PARBITER_INSTANCE Arbiter,
128 _In_ PLIST_ENTRY ArbitrationList,
129 _In_ ULONG EntryCount)
130{
132 PARBITER_ALTERNATIVE Alternative;
133 PLIST_ENTRY ListEntry;
134 ULONG StateCount = EntryCount + 1; /* + NULL terminator */
135 ULONG AlternativeCount = 0;
136 ULONG Size;
137
138 PAGED_CODE();
139
140 for (ListEntry = ArbitrationList->Flink;
141 ListEntry != ArbitrationList;
142 ListEntry = ListEntry->Flink)
143 {
145
146 if (Entry->AlternativeCount == 0)
147 StateCount--; /* an empty entry contributes no state */
148 else
149 AlternativeCount += Entry->AlternativeCount;
150 }
151
152 Size = StateCount * sizeof(ARBITER_ALLOCATION_STATE) +
153 AlternativeCount * sizeof(ARBITER_ALTERNATIVE);
154
155 if (Arbiter->AllocationStackMaxSize < Size)
156 {
158
160 if (NewStack == NULL)
162
163 if (Arbiter->AllocationStack != NULL)
164 ExFreePoolWithTag(Arbiter->AllocationStack, TAG_ARBITER);
165
166 Arbiter->AllocationStack = NewStack;
167 Arbiter->AllocationStackMaxSize = Size;
168 }
169 RtlZeroMemory(Arbiter->AllocationStack, Size);
170
171 State = Arbiter->AllocationStack;
172 Alternative = (PARBITER_ALTERNATIVE)&Arbiter->AllocationStack[StateCount];
173
174 for (ListEntry = ArbitrationList->Flink;
175 ListEntry != ArbitrationList;
176 ListEntry = ListEntry->Flink)
177 {
179 ULONG Index;
180
181 if (Entry->AlternativeCount == 0)
182 continue;
183
184 State->Entry = Entry;
185 State->AlternativeCount = Entry->AlternativeCount;
186 State->Alternatives = Alternative;
187 State->Start = 1; /* Start(1) > End(0): nothing chosen yet */
188
189 for (Index = 0; Index < Entry->AlternativeCount; ++Index)
190 {
191 NTSTATUS Status = ArbpBuildAlternative(Arbiter, &Entry->Alternatives[Index], Alternative);
192 if (!NT_SUCCESS(Status))
193 return Status;
194 Alternative++;
195 }
196 State++;
197 }
198
199 return STATUS_SUCCESS;
200}
201
224CODE_SEG("PAGE")
225static
228 _In_ PARBITER_INSTANCE Arbiter,
229 _In_ PLIST_ENTRY ArbitrationList)
230{
231 PLIST_ENTRY ListEntry;
232 PVOID PreviousOwner = NULL;
233 ULONG EntryCount = 0;
235
236 PAGED_CODE();
237
238 /* Start the tentative allocation as a copy of the committed one. */
239 RtlFreeRangeList(Arbiter->PossibleAllocation);
240 RtlInitializeRangeList(Arbiter->PossibleAllocation);
241 Status = RtlCopyRangeList(Arbiter->PossibleAllocation, Arbiter->Allocation);
242 if (!NT_SUCCESS(Status))
243 goto Failure;
244
245 for (ListEntry = ArbitrationList->Flink;
246 ListEntry != ArbitrationList;
247 ListEntry = ListEntry->Flink)
248 {
250 ULONG Index;
251
252 EntryCount++;
253
254 /*
255 * Everything a device on the arbitration list already owns is up for
256 * reassignment - remove it from the working list so the device does not
257 * conflict with itself (its boot config in particular).
258 */
259 if (Entry->PhysicalDeviceObject != PreviousOwner)
260 {
261 PreviousOwner = Entry->PhysicalDeviceObject;
262 RtlDeleteOwnersRanges(Arbiter->PossibleAllocation, Entry->PhysicalDeviceObject);
263 }
264
265 /* Score each entry: the sum of its alternatives' constrainedness. */
266 Entry->WorkSpace = 0;
267 if (Arbiter->ScoreRequirement != NULL)
268 {
269 for (Index = 0; Index < Entry->AlternativeCount; ++Index)
270 {
271 INT32 Score = Arbiter->ScoreRequirement(&Entry->Alternatives[Index]);
272 if (Score < 0)
273 {
275 goto Failure;
276 }
277 Entry->WorkSpace += Score;
278 }
279 }
280 }
281
282 ArbiterLibSortArbitrationList(ArbitrationList);
283
284 Status = ArbpBuildAllocationStack(Arbiter, ArbitrationList, EntryCount);
285 if (!NT_SUCCESS(Status))
286 goto Failure;
287
288 Status = Arbiter->AllocateEntry(Arbiter, Arbiter->AllocationStack);
289 if (!NT_SUCCESS(Status))
290 goto Failure;
291
292 return STATUS_SUCCESS;
293
294Failure:
295 RtlFreeRangeList(Arbiter->PossibleAllocation);
296 RtlInitializeRangeList(Arbiter->PossibleAllocation);
297 return Status;
298}
299
327CODE_SEG("PAGE")
328static
331 _In_ PARBITER_INSTANCE Arbiter,
332 _In_ PLIST_ENTRY ArbitrationList)
333{
335 ARBITER_ALTERNATIVE Alternative;
336 PLIST_ENTRY ListEntry;
338
339 PAGED_CODE();
340
341 RtlZeroMemory(&State, sizeof(State));
342 RtlZeroMemory(&Alternative, sizeof(Alternative));
343 State.Alternatives = &Alternative;
344 State.CurrentAlternative = &Alternative;
345 State.AlternativeCount = 1;
346
347 /*
348 * Rebuild the tentative allocation from the committed one
349 * minus everything the listed devices already own.
350 */
351 RtlFreeRangeList(Arbiter->PossibleAllocation);
352 RtlInitializeRangeList(Arbiter->PossibleAllocation);
353 Status = RtlCopyRangeList(Arbiter->PossibleAllocation, Arbiter->Allocation);
354 if (!NT_SUCCESS(Status))
355 goto Failure;
356
357 for (ListEntry = ArbitrationList->Flink;
358 ListEntry != ArbitrationList;
359 ListEntry = ListEntry->Flink)
360 {
362
363 Status = RtlDeleteOwnersRanges(Arbiter->PossibleAllocation,
364 Entry->PhysicalDeviceObject);
365 if (!NT_SUCCESS(Status))
366 goto Failure;
367 }
368
369 for (ListEntry = ArbitrationList->Flink;
370 ListEntry != ArbitrationList;
371 ListEntry = ListEntry->Flink)
372 {
375
376 if (Entry->Result == ArbiterResultNullRequest)
377 continue;
378
379 /* A retest without a preceding successful test is a caller bug. */
380 if (Entry->SelectedAlternative == NULL || Entry->Assignment == NULL)
381 {
383 goto Failure;
384 }
385
386 Status = ArbpBuildAlternative(Arbiter, Entry->SelectedAlternative, &Alternative);
387 if (!NT_SUCCESS(Status))
388 goto Failure;
389
390 State.Entry = Entry;
391 State.WorkSpace = 0;
392
393 Status = Arbiter->UnpackResource(Entry->Assignment, &State.Start, &Length);
394 if (!NT_SUCCESS(Status))
395 goto Failure;
396 State.End = State.Start + Length - 1;
397
398 Status = Arbiter->PreprocessEntry(Arbiter, &State);
399 if (!NT_SUCCESS(Status))
400 goto Failure;
401
402 if (Length != 0)
403 Arbiter->AddAllocation(Arbiter, &State);
404
406 {
408 State.WorkSpace = 0;
409 State.Flags &= ~ARBITER_STATE_FLAG_WORKSPACE;
410 }
411 }
412
413 return STATUS_SUCCESS;
414
415Failure:
417 {
419 State.WorkSpace = 0;
420 State.Flags &= ~ARBITER_STATE_FLAG_WORKSPACE;
421 }
422 RtlFreeRangeList(Arbiter->PossibleAllocation);
423 RtlInitializeRangeList(Arbiter->PossibleAllocation);
424 return Status;
425}
426
443CODE_SEG("PAGE")
445NTAPI
446#if (NTDDI_VERSION >= NTDDI_VISTA)
448 _In_ PARBITER_INSTANCE Arbiter,
450{
451 PAGED_CODE();
452 return ArbpTestAllocation(Arbiter, Parameters->ArbitrationList);
453}
454#else
456 _In_ PARBITER_INSTANCE Arbiter,
457 _Inout_ PLIST_ENTRY ArbitrationList)
458{
459 PAGED_CODE();
460 return ArbpTestAllocation(Arbiter, ArbitrationList);
461}
462#endif
463
479CODE_SEG("PAGE")
481NTAPI
482#if (NTDDI_VERSION >= NTDDI_VISTA)
484 _In_ PARBITER_INSTANCE Arbiter,
486{
487 PAGED_CODE();
488 return ArbpRetestAllocation(Arbiter, Parameters->ArbitrationList);
489}
490#else
492 _In_ PARBITER_INSTANCE Arbiter,
493 _Inout_ PLIST_ENTRY ArbitrationList)
494{
495 PAGED_CODE();
496 return ArbpRetestAllocation(Arbiter, ArbitrationList);
497}
498#endif
499
512CODE_SEG("PAGE")
514NTAPI
516 _In_ PARBITER_INSTANCE Arbiter)
517{
518 PRTL_RANGE_LIST Old = Arbiter->Allocation;
519
520 PAGED_CODE();
521
522 RtlFreeRangeList(Old);
524 Arbiter->Allocation = Arbiter->PossibleAllocation;
525 Arbiter->PossibleAllocation = Old;
526 return STATUS_SUCCESS;
527}
528
540CODE_SEG("PAGE")
542NTAPI
544 _In_ PARBITER_INSTANCE Arbiter)
545{
546 PAGED_CODE();
547
548 RtlFreeRangeList(Arbiter->PossibleAllocation);
549 RtlInitializeRangeList(Arbiter->PossibleAllocation);
550 return STATUS_SUCCESS;
551}
552
553/* BOOT ALLOCATION ************************************************************/
554
579CODE_SEG("PAGE")
580static
583 _In_ PARBITER_INSTANCE Arbiter,
584 _In_ PLIST_ENTRY ArbitrationList)
585{
586 PLIST_ENTRY ListEntry;
588 ARBITER_ALTERNATIVE Alternative;
589 PRTL_RANGE_LIST Old;
591
592 PAGED_CODE();
593
594 /* Stage the additions in PossibleAllocation, then swap them in. */
595 RtlFreeRangeList(Arbiter->PossibleAllocation);
596 RtlInitializeRangeList(Arbiter->PossibleAllocation);
597 Status = RtlCopyRangeList(Arbiter->PossibleAllocation, Arbiter->Allocation);
598 if (!NT_SUCCESS(Status))
599 {
600 RtlFreeRangeList(Arbiter->PossibleAllocation);
601 RtlInitializeRangeList(Arbiter->PossibleAllocation);
602 return Status;
603 }
604
605 for (ListEntry = ArbitrationList->Flink;
606 ListEntry != ArbitrationList;
607 ListEntry = ListEntry->Flink)
608 {
610
611 if (Entry->AlternativeCount == 0)
612 continue;
613
614 RtlZeroMemory(&State, sizeof(State));
615 RtlZeroMemory(&Alternative, sizeof(Alternative));
616
617 if (!NT_SUCCESS(ArbpBuildAlternative(Arbiter, &Entry->Alternatives[0], &Alternative)))
618 continue;
619
620 /* Only sane, fixed single-placement configurations are reserved. */
621 if (Alternative.Length == 0 ||
622 Alternative.Alignment == 0 ||
624 !(Alternative.Flags & ARBITER_ALTERNATIVE_FLAG_FIXED) ||
625 (Alternative.Minimum % Alternative.Alignment) != 0)
626 {
627 continue;
628 }
629
630 State.Entry = Entry;
631 State.AlternativeCount = 1;
632 State.Alternatives = &Alternative;
633 State.CurrentAlternative = &Alternative;
635 State.RangeAttributes = ARBITER_RANGE_BOOT_ALLOCATED;
636 State.Start = State.CurrentMinimum = Alternative.Minimum;
637 State.End = State.CurrentMaximum = Alternative.Maximum;
638
639 if (!NT_SUCCESS(Arbiter->PreprocessEntry(Arbiter, &State)))
640 continue;
641
642 Arbiter->AddAllocation(Arbiter, &State);
643
644 /*
645 * The reservation is also written back into the device's
646 * Assignment, or it is left holding an unfilled one.
647 */
648 if (Arbiter->PackResource != NULL && Entry->Assignment != NULL)
649 {
650 (VOID)Arbiter->PackResource(Alternative.Descriptor,
651 State.Start,
652 Entry->Assignment);
653 }
654 }
655
656 Old = Arbiter->Allocation;
657 RtlFreeRangeList(Old);
659 Arbiter->Allocation = Arbiter->PossibleAllocation;
660 Arbiter->PossibleAllocation = Old;
661
662 return STATUS_SUCCESS;
663}
664
680CODE_SEG("PAGE")
682NTAPI
683#if (NTDDI_VERSION >= NTDDI_VISTA)
685 _In_ PARBITER_INSTANCE Arbiter,
687{
688 PAGED_CODE();
689 return ArbpBootAllocation(Arbiter, Parameters->ArbitrationList);
690}
691#else
693 _In_ PARBITER_INSTANCE Arbiter,
694 _Inout_ PLIST_ENTRY ArbitrationList)
695{
696 PAGED_CODE();
697 return ArbpBootAllocation(Arbiter, ArbitrationList);
698}
699#endif
700
701/* CONFLICT QUERIES ***********************************************************/
702
719CODE_SEG("PAGE")
720static
722NTAPI
725 _In_ PRTL_RANGE Range)
726{
727 PAGED_CODE();
728 *(PRTL_RANGE *)Context = Range;
729 return FALSE;
730}
731
767CODE_SEG("PAGE")
768static
771 _In_ PARBITER_INSTANCE Arbiter,
773 _In_ PIO_RESOURCE_DESCRIPTOR ConflictingResource,
774 _Out_ PULONG ConflictCount,
775 _Out_ PARBITER_CONFLICT_INFO *Conflicts)
776{
777 PRTL_CONFLICT_RANGE_CALLBACK SavedCallback = Arbiter->ConflictCallback;
778 PVOID SavedContext = Arbiter->ConflictCallbackContext;
779 PRTL_RANGE ConflictingRange = NULL;
782 ARBITER_ALTERNATIVE Alternative;
784 ULONG Count = 0;
785 ULONG Capacity = 10;
788
789 PAGED_CODE();
790
791 *ConflictCount = 0;
792 *Conflicts = NULL;
793
794 RtlZeroMemory(&State, sizeof(State));
795
796 Arbiter->ConflictCallback = ArbpQueryConflictCallback;
797 Arbiter->ConflictCallbackContext = &ConflictingRange;
798
799 RtlFreeRangeList(Arbiter->PossibleAllocation);
800 RtlInitializeRangeList(Arbiter->PossibleAllocation);
801 Status = RtlCopyRangeList(Arbiter->PossibleAllocation, Arbiter->Allocation);
802 if (!NT_SUCCESS(Status))
803 goto Cleanup;
804
805 Status = ArbpBuildAlternative(Arbiter, ConflictingResource, &Alternative);
806 if (!NT_SUCCESS(Status))
807 goto Cleanup;
808
809 RtlZeroMemory(&Entry, sizeof(Entry));
810 State.Start = State.CurrentMinimum = Alternative.Minimum;
811 State.End = State.CurrentMaximum = Alternative.Maximum;
812 State.CurrentAlternative = State.Alternatives = &Alternative;
813 State.AlternativeCount = 1;
814 State.Entry = &Entry;
815 Entry.RequestSource = ArbiterRequestPnpEnumerated;
816 Entry.PhysicalDeviceObject = PhysicalDeviceObject;
819 sizeof(Entry.InterfaceType),
820 &Entry.InterfaceType,
821 &ResultLength)))
822 {
823 Entry.InterfaceType = Isa;
824 }
826 sizeof(Entry.BusNumber), &Entry.BusNumber, &ResultLength)))
827 {
828 Entry.BusNumber = 0;
829 }
830
831 List = ExAllocatePoolWithTag(PagedPool, Capacity * sizeof(*List), TAG_ARBITER);
832 if (List == NULL)
833 {
835 goto Cleanup;
836 }
837
838 Status = Arbiter->PreprocessEntry(Arbiter, &State);
839 if (!NT_SUCCESS(Status))
840 {
842 goto Cleanup;
843 }
844
845 /* The requester's own ranges are not conflicts. */
846 RtlDeleteOwnersRanges(Arbiter->PossibleAllocation, PhysicalDeviceObject);
847
848 for (;;)
849 {
850 ConflictingRange = NULL;
851 State.CurrentMinimum = State.Start;
852 State.CurrentMaximum = State.End;
853
854 if (Arbiter->FindSuitableRange(Arbiter, &State))
855 break; /* placeable now: no more conflicts */
856
857 if (Count == Capacity)
858 {
861 (Capacity + 5) * sizeof(*Grown),
863 if (Grown == NULL)
864 {
867 goto Cleanup;
868 }
871 List = Grown;
872 Capacity += 5;
873 }
874
875 if (ConflictingRange == NULL)
876 {
877 /* Blocked, but no specific owner: report one whole-range conflict. */
879 List[Count].Start = 0;
881 ++Count;
882 break;
883 }
884
885 List[Count].OwningObject = (PDEVICE_OBJECT)ConflictingRange->Owner;
886 List[Count].Start = ConflictingRange->Start;
887 List[Count].End = ConflictingRange->End;
888 ++Count;
889
890 /* Remove that owner and look for the next conflict. */
891 Status = RtlDeleteOwnersRanges(Arbiter->PossibleAllocation, ConflictingRange->Owner);
892 if (!NT_SUCCESS(Status))
893 {
895 goto Cleanup;
896 }
897 }
898
899 *Conflicts = List;
900 *ConflictCount = Count;
902
903Cleanup:
905 {
907 State.WorkSpace = 0;
908 State.Flags &= ~ARBITER_STATE_FLAG_WORKSPACE;
909 }
910 RtlFreeRangeList(Arbiter->PossibleAllocation);
911 RtlInitializeRangeList(Arbiter->PossibleAllocation);
912 Arbiter->ConflictCallback = SavedCallback;
913 Arbiter->ConflictCallbackContext = SavedContext;
914 return Status;
915}
916
933CODE_SEG("PAGE")
935NTAPI
936#if (NTDDI_VERSION >= NTDDI_VISTA)
938 _In_ PARBITER_INSTANCE Arbiter,
940{
941 PAGED_CODE();
942 return ArbpQueryConflict(Arbiter,
943 Parameters->PhysicalDeviceObject,
944 Parameters->ConflictingResource,
945 Parameters->ConflictCount,
946 Parameters->Conflicts);
947}
948#else
950 _In_ PARBITER_INSTANCE Arbiter,
952 _In_ PIO_RESOURCE_DESCRIPTOR ConflictingResource,
953 _Out_ PULONG ConflictCount,
954 _Out_ PARBITER_CONFLICT_INFO *Conflicts)
955{
956 PAGED_CODE();
957 return ArbpQueryConflict(Arbiter, PhysicalDeviceObject, ConflictingResource,
958 ConflictCount, Conflicts);
959}
960#endif
#define PAGED_CODE()
#define CODE_SEG(...)
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define ARBITER_ALTERNATIVE_FLAG_BADRANGE
Definition: arbiter.h:33
#define ARBITER_ALTERNATIVE_FLAG_SHARED
Definition: arbiter.h:31
struct _ARBITER_ALTERNATIVE * PARBITER_ALTERNATIVE
struct _ARBITER_ALLOCATION_STATE ARBITER_ALLOCATION_STATE
#define ARBITER_STATE_FLAG_BOOT
Definition: arbiter.h:59
#define ARBITER_PRIORITY_NULL
Definition: arbiter.h:25
#define ARBITER_MAXIMUM_ADDRESS
Definition: arbiter.h:13
#define TAG_ARBITER
Definition: arbiter.h:10
#define ARBITER_STATE_FLAG_WORKSPACE
Definition: arbiter.h:61
NTSTATUS NTAPI ArbiterLibSortArbitrationList(_Inout_ PLIST_ENTRY ArbitrationList)
Orders an arbitration list most-constrained first, so fixed requirements are placed before flexible o...
Definition: entry.c:71
#define ARBITER_ALTERNATIVE_FLAG_INACCESSIBLE_OK
Definition: arbiter.h:34
#define ARBITER_ALTERNATIVE_FLAG_FIXED
Definition: arbiter.h:32
#define ARBITER_RANGE_BOOT_ALLOCATED
Definition: arbiter.h:53
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
_In_ HANDLE _In_ CONST PDXGKMDT_OPM_GET_INFO_PARAMETERS Parameters
Definition: dispmprt.h:321
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static const WCHAR Cleanup[]
Definition: register.c:80
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define PagedPool
Definition: env_spec_w32.h:308
union Alignment_ Alignment
Status
Definition: gdiplustypes.h:24
if(dx< 0)
Definition: linetemp.h:194
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define CM_RESOURCE_MEMORY_COMPAT_FOR_INACCESSIBLE_RANGE
Definition: cmtypes.h:131
NTSYSAPI NTSTATUS NTAPI RtlDeleteOwnersRanges(_Inout_ PRTL_RANGE_LIST RangeList, _In_ _Maybenull_ PVOID Owner)
NTSYSAPI VOID NTAPI RtlInitializeRangeList(_Out_ PRTL_RANGE_LIST RangeList)
NTSYSAPI NTSTATUS NTAPI RtlCopyRangeList(_Out_ PRTL_RANGE_LIST CopyRangeList, _In_ PRTL_RANGE_LIST RangeList)
NTSYSAPI VOID NTAPI RtlFreeRangeList(_In_ PRTL_RANGE_LIST RangeList)
BOOLEAN(NTAPI * PRTL_CONFLICT_RANGE_CALLBACK)(PVOID Context, struct _RTL_RANGE *Range)
Definition: rtltypes.h:708
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
int Count
Definition: noreturn.cpp:7
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:713
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
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
#define CmResourceTypeMemory
Definition: restypes.h:106
@ Isa
Definition: restypes.h:123
Entry
Definition: section.c:5216
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PVOID Context
Definition: storport.h:2269
PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: arbiter.h:77
PDEVICE_OBJECT OwningObject
Definition: iotypes.h:4563
Definition: iotypes.h:4633
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONGLONG End
Definition: rtltypes.h:1517
ULONGLONG Start
Definition: rtltypes.h:1516
PVOID Owner
Definition: rtltypes.h:1519
NTSTATUS NTAPI ArbiterLibBootAllocation(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_BOOT_ALLOCATION_PARAMETERS Parameters)
The BootAllocation action: records every entry's firmware boot configuration in the committed allocat...
Definition: transaction.c:684
NTSTATUS NTAPI ArbiterLibRetestAllocation(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_RETEST_ALLOCATION_PARAMETERS Parameters)
The RetestAllocation action: deterministically re-establishes the placements a previous test chose,...
Definition: transaction.c:483
NTSTATUS NTAPI ArbiterLibTestAllocation(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_TEST_ALLOCATION_PARAMETERS Parameters)
The TestAllocation action: tentatively places every entry of the arbitration list,...
Definition: transaction.c:447
static NTSTATUS ArbpBootAllocation(_In_ PARBITER_INSTANCE Arbiter, _In_ PLIST_ENTRY ArbitrationList)
Reserves each entry's firmware boot configuration in the committed range list, so devices left where ...
Definition: transaction.c:582
static NTSTATUS ArbpBuildAllocationStack(_In_ PARBITER_INSTANCE Arbiter, _In_ PLIST_ENTRY ArbitrationList, _In_ ULONG EntryCount)
Builds the allocation stack for an arbitration list into Arbiter->AllocationStack: one ARBITER_ALLOCA...
Definition: transaction.c:126
NTSTATUS NTAPI ArbiterLibCommitAllocation(_In_ PARBITER_INSTANCE Arbiter)
The CommitAllocation action: the tentative PossibleAllocation becomes the committed Allocation,...
Definition: transaction.c:515
NTSTATUS NTAPI ArbiterLibRollbackAllocation(_In_ PARBITER_INSTANCE Arbiter)
The RollbackAllocation action: discards the tentative allocation; the committed one is untouched.
Definition: transaction.c:543
static NTSTATUS ArbpTestAllocation(_In_ PARBITER_INSTANCE Arbiter, _In_ PLIST_ENTRY ArbitrationList)
Test-allocates every entry on an arbitration list into the arbiter's tentative allocation....
Definition: transaction.c:227
static NTSTATUS ArbpQueryConflict(_In_ PARBITER_INSTANCE Arbiter, _In_ PDEVICE_OBJECT PhysicalDeviceObject, _In_ PIO_RESOURCE_DESCRIPTOR ConflictingResource, _Out_ PULONG ConflictCount, _Out_ PARBITER_CONFLICT_INFO *Conflicts)
Enumerates every committed range that conflicts with a candidate resource for a device....
Definition: transaction.c:770
static NTSTATUS ArbpBuildAlternative(_In_ PARBITER_INSTANCE Arbiter, _In_ PIO_RESOURCE_DESCRIPTOR Descriptor, _Out_ PARBITER_ALTERNATIVE Alternative)
Expands one IO_RESOURCE_DESCRIPTOR into an ARBITER_ALTERNATIVE through the arbiter's UnpackRequiremen...
Definition: transaction.c:44
static BOOLEAN NTAPI ArbpQueryConflictCallback(_In_ PVOID Context, _In_ PRTL_RANGE Range)
RtlFindRange conflict callback installed while a conflict query runs: records the range that blocks p...
Definition: transaction.c:723
NTSTATUS NTAPI ArbiterLibQueryConflict(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PARBITER_QUERY_CONFLICT_PARAMETERS Parameters)
The QueryConflict action: reports which devices' committed ranges collide with a candidate resource.
Definition: transaction.c:937
static NTSTATUS ArbpRetestAllocation(_In_ PARBITER_INSTANCE Arbiter, _In_ PLIST_ENTRY ArbitrationList)
Re-establishes a previously tested solution in the arbiter's tentative allocation without searching a...
Definition: transaction.c:330
int32_t INT32
Definition: typedefs.h:58
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t UINT32
Definition: typedefs.h:59
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
_In_ WDFCOLLECTION _In_ ULONG Index
_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
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
@ CmResourceShareShared
Definition: cmtypes.h:243
#define CmResourceTypeMemoryLarge
Definition: cmtypes.h:231
@ ArbiterRequestPnpEnumerated
Definition: iotypes.h:4621
@ DevicePropertyBusNumber
Definition: iotypes.h:1209
@ DevicePropertyLegacyBusType
Definition: iotypes.h:1208
@ ArbiterResultNullRequest
Definition: iotypes.h:4628