ReactOS 0.4.17-dev-684-ga6524ef
rangelist.c File Reference
#include <rtl.h>
#include <debug.h>
Include dependency graph for rangelist.c:

Go to the source code of this file.

Classes

struct  _RTL_RANGE_ENTRY
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _RTL_RANGE_ENTRY RTL_RANGE_ENTRY
 
typedef struct _RTL_RANGE_ENTRYPRTL_RANGE_ENTRY
 

Functions

static BOOLEAN RtlpOverlaps (_In_ ULONGLONG Start1, _In_ ULONGLONG End1, _In_ ULONGLONG Start2, _In_ ULONGLONG End2)
 
static BOOLEAN RtlpWindowIsAvailable (_In_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ ULONG Flags, _In_ UCHAR AttributeAvailableMask, _In_opt_ PVOID Context, _In_opt_ PRTL_CONFLICT_RANGE_CALLBACK Callback, _Out_opt_ PULONGLONG ConflictStart)
 
static BOOLEAN RtlpConflictsOnAdd (_In_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ ULONG Flags)
 
NTSTATUS NTAPI RtlAddRange (IN OUT PRTL_RANGE_LIST RangeList, IN ULONGLONG Start, IN ULONGLONG End, IN UCHAR Attributes, IN ULONG Flags, IN PVOID UserData OPTIONAL, IN PVOID Owner OPTIONAL)
 
NTSTATUS NTAPI RtlCopyRangeList (OUT PRTL_RANGE_LIST CopyRangeList, IN PRTL_RANGE_LIST RangeList)
 
NTSTATUS NTAPI RtlDeleteOwnersRanges (IN OUT PRTL_RANGE_LIST RangeList, IN PVOID Owner)
 
NTSTATUS NTAPI RtlDeleteRange (IN OUT PRTL_RANGE_LIST RangeList, IN ULONGLONG Start, IN ULONGLONG End, IN PVOID Owner)
 
NTSTATUS NTAPI RtlFindRange (IN PRTL_RANGE_LIST RangeList, IN ULONGLONG Minimum, IN ULONGLONG Maximum, IN ULONG Length, IN ULONG Alignment, IN ULONG Flags, IN UCHAR AttributeAvailableMask, IN PVOID Context OPTIONAL, IN PRTL_CONFLICT_RANGE_CALLBACK Callback OPTIONAL, OUT PULONGLONG Start)
 
VOID NTAPI RtlFreeRangeList (IN PRTL_RANGE_LIST RangeList)
 
NTSTATUS NTAPI RtlGetFirstRange (IN PRTL_RANGE_LIST RangeList, OUT PRTL_RANGE_LIST_ITERATOR Iterator, OUT PRTL_RANGE *Range)
 
NTSTATUS NTAPI RtlGetLastRange (IN PRTL_RANGE_LIST RangeList, OUT PRTL_RANGE_LIST_ITERATOR Iterator, OUT PRTL_RANGE *Range)
 
NTSTATUS NTAPI RtlGetNextRange (IN OUT PRTL_RANGE_LIST_ITERATOR Iterator, OUT PRTL_RANGE *Range, IN BOOLEAN MoveForwards)
 
VOID NTAPI RtlInitializeRangeList (IN OUT PRTL_RANGE_LIST RangeList)
 
NTSTATUS NTAPI RtlInvertRangeListEx (OUT PRTL_RANGE_LIST InvertedRangeList, IN PRTL_RANGE_LIST RangeList, IN UCHAR Attributes, IN PVOID UserData OPTIONAL, IN PVOID Owner OPTIONAL)
 
NTSTATUS NTAPI RtlInvertRangeList (OUT PRTL_RANGE_LIST InvertedRangeList, IN PRTL_RANGE_LIST RangeList)
 
NTSTATUS NTAPI RtlIsRangeAvailable (IN PRTL_RANGE_LIST RangeList, IN ULONGLONG Start, IN ULONGLONG End, IN ULONG Flags, IN UCHAR AttributeAvailableMask, IN PVOID Context OPTIONAL, IN PRTL_CONFLICT_RANGE_CALLBACK Callback OPTIONAL, OUT PBOOLEAN Available)
 
NTSTATUS NTAPI RtlMergeRangeLists (OUT PRTL_RANGE_LIST MergedRangeList, IN PRTL_RANGE_LIST RangeList1, IN PRTL_RANGE_LIST RangeList2, IN ULONG Flags)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file rangelist.c.

Typedef Documentation

◆ PRTL_RANGE_ENTRY

◆ RTL_RANGE_ENTRY

Function Documentation

◆ RtlAddRange()

NTSTATUS NTAPI RtlAddRange ( IN OUT PRTL_RANGE_LIST  RangeList,
IN ULONGLONG  Start,
IN ULONGLONG  End,
IN UCHAR  Attributes,
IN ULONG  Flags,
IN PVOID UserData  OPTIONAL,
IN PVOID Owner  OPTIONAL 
)

Definition at line 187 of file rangelist.c.

194{
195 PRTL_RANGE_ENTRY RangeEntry;
196 //PRTL_RANGE_ENTRY Previous;
197 PRTL_RANGE_ENTRY Current;
199
200 if (Start > End)
202
203 /*
204 * Unless the caller explicitly allows adding on top of a conflict, reject
205 * a range that overlaps an incompatible existing entry.
206 */
208 RtlpConflictsOnAdd(RangeList, Start, End, Flags))
209 {
211 }
212
213 /* Create new range entry */
214 RangeEntry = RtlpAllocateMemory(sizeof(RTL_RANGE_ENTRY), 'elRR');
215 if (RangeEntry == NULL)
217
218 /* Initialize range entry */
219 RangeEntry->Range.Start = Start;
220 RangeEntry->Range.End = End;
221 RangeEntry->Range.Attributes = Attributes;
222 RangeEntry->Range.UserData = UserData;
223 RangeEntry->Range.Owner = Owner;
224
225 RangeEntry->Range.Flags = 0;
227 RangeEntry->Range.Flags |= RTL_RANGE_SHARED;
228
229 /* Insert range entry */
230 if (RangeList->Count == 0)
231 {
232 InsertTailList(&RangeList->ListHead,
233 &RangeEntry->Entry);
234 RangeList->Count++;
235 RangeList->Stamp++;
236 return STATUS_SUCCESS;
237 }
238 else
239 {
240 //Previous = NULL;
241 Entry = RangeList->ListHead.Flink;
242 while (Entry != &RangeList->ListHead)
243 {
245 if (Current->Range.Start > RangeEntry->Range.Start)
246 {
247 /* Insert before current */
248 DPRINT("Insert before current\n");
249 InsertTailList(&Current->Entry,
250 &RangeEntry->Entry);
251
252 RangeList->Count++;
253 RangeList->Stamp++;
254 return STATUS_SUCCESS;
255 }
256
257 //Previous = Current;
258 Entry = Entry->Flink;
259 }
260
261 DPRINT("Insert tail\n");
262 InsertTailList(&RangeList->ListHead,
263 &RangeEntry->Entry);
264 RangeList->Count++;
265 RangeList->Stamp++;
266 return STATUS_SUCCESS;
267 }
268
269 RtlpFreeMemory(RangeEntry, 0);
270
271 return STATUS_UNSUCCESSFUL;
272}
static _Out_opt_ PULONGLONG Start
PVOID NTAPI RtlpAllocateMemory(ULONG Bytes, ULONG Tag)
Definition: libsupp.c:35
VOID NTAPI RtlpFreeMemory(PVOID Mem, ULONG Tag)
Definition: libsupp.c:44
#define NULL
Definition: types.h:112
#define InsertTailList(ListHead, Entry)
struct tagUserData UserData
_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
#define RTL_RANGE_LIST_ADD_IF_CONFLICT
Definition: rtltypes.h:81
#define RTL_RANGE_LIST_ADD_SHARED
Definition: rtltypes.h:82
#define RTL_RANGE_SHARED
Definition: rtltypes.h:92
#define STATUS_RANGE_LIST_CONFLICT
Definition: ntstatus.h:885
static BOOLEAN RtlpConflictsOnAdd(_In_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ ULONG Flags)
Definition: rangelist.c:131
Entry
Definition: section.c:5216
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
Definition: typedefs.h:120
Definition: libsupp.c:19
LIST_ENTRY Entry
Definition: libsupp.c:20
RTL_RANGE Range
Definition: libsupp.c:21
ULONGLONG End
Definition: rtltypes.h:1497
ULONGLONG Start
Definition: rtltypes.h:1496
UCHAR Attributes
Definition: rtltypes.h:1500
PVOID UserData
Definition: rtltypes.h:1498
PVOID Owner
Definition: rtltypes.h:1499
UCHAR Flags
Definition: rtltypes.h:1501
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by RtlInvertRangeListEx(), and RtlMergeRangeLists().

◆ RtlCopyRangeList()

NTSTATUS NTAPI RtlCopyRangeList ( OUT PRTL_RANGE_LIST  CopyRangeList,
IN PRTL_RANGE_LIST  RangeList 
)

Definition at line 293 of file rangelist.c.

295{
296 PRTL_RANGE_ENTRY Current;
297 PRTL_RANGE_ENTRY NewEntry;
299
300 CopyRangeList->Flags = RangeList->Flags;
301
302 Entry = RangeList->ListHead.Flink;
303 while (Entry != &RangeList->ListHead)
304 {
306
307 NewEntry = RtlpAllocateMemory(sizeof(RTL_RANGE_ENTRY), 'elRR');
308 if (NewEntry == NULL)
310
311 RtlCopyMemory(&NewEntry->Range,
312 &Current->Range,
313 sizeof(RTL_RANGE));
314
315 InsertTailList(&CopyRangeList->ListHead,
316 &NewEntry->Entry);
317
318 CopyRangeList->Count++;
319
320 Entry = Entry->Flink;
321 }
322
323 CopyRangeList->Stamp++;
324
325 return STATUS_SUCCESS;
326}
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by RtlMergeRangeLists().

◆ RtlDeleteOwnersRanges()

NTSTATUS NTAPI RtlDeleteOwnersRanges ( IN OUT PRTL_RANGE_LIST  RangeList,
IN PVOID  Owner 
)

Definition at line 348 of file rangelist.c.

350{
351 PRTL_RANGE_ENTRY Current;
354
355 Entry = RangeList->ListHead.Flink;
356 while (Entry != &RangeList->ListHead)
357 {
358 /* Capture the next link before we possibly free this entry */
359 Next = Entry->Flink;
360
362 if (Current->Range.Owner == Owner)
363 {
365 RtlpFreeMemory(Current, 0);
366
367 RangeList->Count--;
368 RangeList->Stamp++;
369 }
370
371 Entry = Next;
372 }
373
374 return STATUS_SUCCESS;
375}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE

◆ RtlDeleteRange()

NTSTATUS NTAPI RtlDeleteRange ( IN OUT PRTL_RANGE_LIST  RangeList,
IN ULONGLONG  Start,
IN ULONGLONG  End,
IN PVOID  Owner 
)

Definition at line 398 of file rangelist.c.

402{
403 PRTL_RANGE_ENTRY Current;
405
406 Entry = RangeList->ListHead.Flink;
407 while (Entry != &RangeList->ListHead)
408 {
410 if (Current->Range.Start == Start &&
411 Current->Range.End == End &&
412 Current->Range.Owner == Owner)
413 {
415
416 RtlpFreeMemory(Current, 0);
417
418 RangeList->Count--;
419 RangeList->Stamp++;
420 return STATUS_SUCCESS;
421 }
422
423 Entry = Entry->Flink;
424 }
425
427}
#define STATUS_RANGE_NOT_FOUND
Definition: ntstatus.h:893

◆ RtlFindRange()

NTSTATUS NTAPI RtlFindRange ( IN PRTL_RANGE_LIST  RangeList,
IN ULONGLONG  Minimum,
IN ULONGLONG  Maximum,
IN ULONG  Length,
IN ULONG  Alignment,
IN ULONG  Flags,
IN UCHAR  AttributeAvailableMask,
IN PVOID Context  OPTIONAL,
IN PRTL_CONFLICT_RANGE_CALLBACK Callback  OPTIONAL,
OUT PULONGLONG  Start 
)

Definition at line 458 of file rangelist.c.

468{
469 ULONGLONG Candidate;
470 ULONGLONG CandidateEnd;
471 ULONGLONG ConflictStart = 0;
472
473 if (Alignment == 0 || Length == 0)
474 {
476 }
477
478 /* A window of Length can only end at Maximum if it also fits below it */
479 if ((ULONGLONG)(Length - 1) > Maximum)
480 {
482 }
483
484 Candidate = (Maximum - (Length - 1)) & ~((ULONGLONG)Alignment - 1);
485
486 for (;;)
487 {
488 if (Candidate < Minimum)
489 {
491 }
492
493 CandidateEnd = Candidate + (Length - 1);
494
495 if (RtlpWindowIsAvailable(RangeList,
496 Candidate,
497 CandidateEnd,
498 Flags,
499 AttributeAvailableMask,
500 Context,
501 Callback,
502 &ConflictStart))
503 {
504 DPRINT("Found range: %I64x\n", Candidate);
505 *Start = Candidate;
506 return STATUS_SUCCESS;
507 }
508
509 /*
510 * Jump the window entirely below the lowest conflicting entry.
511 * Because that entry overlaps the current window, this strictly
512 * decreases Candidate, so the loop always terminates.
513 */
514 if (ConflictStart == 0)
515 {
517 }
518
519 if ((ULONGLONG)(Length - 1) > ConflictStart - 1)
520 {
522 }
523
524 Candidate = ((ConflictStart - 1) - (Length - 1)) & ~((ULONGLONG)Alignment - 1);
525 }
526}
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static BOOLEAN RtlpWindowIsAvailable(_In_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ ULONG Flags, _In_ UCHAR AttributeAvailableMask, _In_opt_ PVOID Context, _In_opt_ PRTL_CONFLICT_RANGE_CALLBACK Callback, _Out_opt_ PULONGLONG ConflictStart)
Definition: rangelist.c:64
_In_ PVOID Context
Definition: storport.h:2269
uint64_t ULONGLONG
Definition: typedefs.h:67
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458

◆ RtlFreeRangeList()

VOID NTAPI RtlFreeRangeList ( IN PRTL_RANGE_LIST  RangeList)

Definition at line 546 of file rangelist.c.

547{
549 PRTL_RANGE_ENTRY Current;
550
551 while (!IsListEmpty(&RangeList->ListHead))
552 {
553 Entry = RemoveHeadList(&RangeList->ListHead);
555
556 DPRINT ("Range start: %I64u\n", Current->Range.Start);
557 DPRINT ("Range end: %I64u\n", Current->Range.End);
558
559 RtlpFreeMemory(Current, 0);
560 }
561
562 RangeList->Flags = 0;
563 RangeList->Count = 0;
564}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964

◆ RtlGetFirstRange()

NTSTATUS NTAPI RtlGetFirstRange ( IN PRTL_RANGE_LIST  RangeList,
OUT PRTL_RANGE_LIST_ITERATOR  Iterator,
OUT PRTL_RANGE Range 
)

Definition at line 586 of file rangelist.c.

589{
590 Iterator->RangeListHead = &RangeList->ListHead;
591 Iterator->MergedHead = NULL;
592 Iterator->Stamp = RangeList->Stamp;
593
594 if (IsListEmpty(&RangeList->ListHead))
595 {
596 Iterator->Current = NULL;
597 *Range = NULL;
599 }
600
601 *Range = &CONTAINING_RECORD(RangeList->ListHead.Flink, RTL_RANGE_ENTRY, Entry)->Range;
602 Iterator->Current = *Range;
603
604 return STATUS_SUCCESS;
605}
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:285
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:656

Referenced by RtlMergeRangeLists().

◆ RtlGetLastRange()

NTSTATUS NTAPI RtlGetLastRange ( IN PRTL_RANGE_LIST  RangeList,
OUT PRTL_RANGE_LIST_ITERATOR  Iterator,
OUT PRTL_RANGE Range 
)

Definition at line 628 of file rangelist.c.

631{
632 Iterator->RangeListHead = &RangeList->ListHead;
633 Iterator->MergedHead = NULL;
634 Iterator->Stamp = RangeList->Stamp;
635
636 if (IsListEmpty(&RangeList->ListHead))
637 {
638 Iterator->Current = NULL;
639 *Range = NULL;
641 }
642
643 *Range = &CONTAINING_RECORD(RangeList->ListHead.Blink, RTL_RANGE_ENTRY, Entry)->Range;
644 Iterator->Current = *Range;
645
646 return STATUS_SUCCESS;
647}

◆ RtlGetNextRange()

NTSTATUS NTAPI RtlGetNextRange ( IN OUT PRTL_RANGE_LIST_ITERATOR  Iterator,
OUT PRTL_RANGE Range,
IN BOOLEAN  MoveForwards 
)

Definition at line 670 of file rangelist.c.

673{
674 PRTL_RANGE_LIST RangeList;
675 PRTL_RANGE_ENTRY Current;
677
678 RangeList = CONTAINING_RECORD(Iterator->RangeListHead, RTL_RANGE_LIST, ListHead);
679 if (Iterator->Stamp != RangeList->Stamp)
681
682 if (Iterator->Current == NULL)
683 {
684 *Range = NULL;
686 }
687
688 /* Iterator->Current points at the RTL_RANGE; recover its entry */
689 Current = CONTAINING_RECORD(Iterator->Current, RTL_RANGE_ENTRY, Range);
690 if (MoveForwards)
691 {
692 Next = Current->Entry.Flink;
693 }
694 else
695 {
696 Next = Current->Entry.Blink;
697 }
698
699 if (Next == Iterator->RangeListHead)
700 {
701 Iterator->Current = NULL;
702 *Range = NULL;
704 }
705
706 *Range = &CONTAINING_RECORD(Next, RTL_RANGE_ENTRY, Entry)->Range;
707 Iterator->Current = *Range;
708
709 return STATUS_SUCCESS;
710}
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121

Referenced by RtlMergeRangeLists().

◆ RtlInitializeRangeList()

VOID NTAPI RtlInitializeRangeList ( IN OUT PRTL_RANGE_LIST  RangeList)

Definition at line 730 of file rangelist.c.

731{
732 InitializeListHead(&RangeList->ListHead);
733 RangeList->Flags = 0;
734 RangeList->Count = 0;
735 RangeList->Stamp = 0;
736}
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944

◆ RtlInvertRangeList()

NTSTATUS NTAPI RtlInvertRangeList ( OUT PRTL_RANGE_LIST  InvertedRangeList,
IN PRTL_RANGE_LIST  RangeList 
)

Definition at line 874 of file rangelist.c.

876{
877 return RtlInvertRangeListEx(InvertedRangeList,
878 RangeList,
879 0,
880 NULL,
881 NULL);
882}
NTSTATUS NTAPI RtlInvertRangeListEx(OUT PRTL_RANGE_LIST InvertedRangeList, IN PRTL_RANGE_LIST RangeList, IN UCHAR Attributes, IN PVOID UserData OPTIONAL, IN PVOID Owner OPTIONAL)
Definition: rangelist.c:761

◆ RtlInvertRangeListEx()

NTSTATUS NTAPI RtlInvertRangeListEx ( OUT PRTL_RANGE_LIST  InvertedRangeList,
IN PRTL_RANGE_LIST  RangeList,
IN UCHAR  Attributes,
IN PVOID UserData  OPTIONAL,
IN PVOID Owner  OPTIONAL 
)

Definition at line 761 of file rangelist.c.

766{
767 PRTL_RANGE_ENTRY Current;
769 ULONGLONG GapStart;
771
772 /*
773 * The list is sorted by ascending Start, but RtlAddRange permits
774 * overlapping entries (RTL_RANGE_LIST_ADD_IF_CONFLICT)
775 *
776 * Whenever two ranges overlap:
777 * walk the covered address space upward from 0: grab every range that
778 * covers the current position... so we can emit the gap up to the next range that
779 * starts beyond it.
780 */
781 GapStart = (ULONGLONG)0;
782
783 for (;;)
784 {
785 ULONGLONG NextStart;
786 BOOLEAN Absorbed;
788
789 /* Advance GapStart past every range that covers it (handles overlaps). */
790 do
791 {
792 Absorbed = FALSE;
793 Entry = RangeList->ListHead.Flink;
794 while (Entry != &RangeList->ListHead)
795 {
797 if (Current->Range.Start <= GapStart &&
798 Current->Range.End >= GapStart)
799 {
800 /* Covered all the way to the top: no gap remains. */
801 if (Current->Range.End == (ULONGLONG)-1)
802 return STATUS_SUCCESS;
803
804 GapStart = Current->Range.End + 1;
805 Absorbed = TRUE;
806 }
807 Entry = Entry->Flink;
808 }
809 }
810 while (Absorbed);
811
812 /* GapStart is now uncovered; find the nearest range starting above it. */
813 NextStart = (ULONGLONG)-1;
814 Found = FALSE;
815 Entry = RangeList->ListHead.Flink;
816 while (Entry != &RangeList->ListHead)
817 {
819 if (Current->Range.Start > GapStart &&
820 Current->Range.Start <= NextStart)
821 {
822 NextStart = Current->Range.Start;
823 Found = TRUE;
824 }
825 Entry = Entry->Flink;
826 }
827
828 /* No further ranges: the gap runs to the top of the address space. */
829 if (!Found)
830 {
831 return RtlAddRange(InvertedRangeList,
832 GapStart,
833 (ULONGLONG)-1,
836 UserData,
837 Owner);
838 }
839
840 Status = RtlAddRange(InvertedRangeList,
841 GapStart,
842 NextStart - 1,
845 UserData,
846 Owner);
847 if (!NT_SUCCESS(Status))
848 return Status;
849
850 /* Resume from the next covered region. */
851 GapStart = NextStart;
852 }
853}
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
return Found
Definition: dirsup.c:1270
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI RtlAddRange(IN OUT PRTL_RANGE_LIST RangeList, IN ULONGLONG Start, IN ULONGLONG End, IN UCHAR Attributes, IN ULONG Flags, IN PVOID UserData OPTIONAL, IN PVOID Owner OPTIONAL)
Definition: rangelist.c:187

Referenced by RtlInvertRangeList().

◆ RtlIsRangeAvailable()

NTSTATUS NTAPI RtlIsRangeAvailable ( IN PRTL_RANGE_LIST  RangeList,
IN ULONGLONG  Start,
IN ULONGLONG  End,
IN ULONG  Flags,
IN UCHAR  AttributeAvailableMask,
IN PVOID Context  OPTIONAL,
IN PRTL_CONFLICT_RANGE_CALLBACK Callback  OPTIONAL,
OUT PBOOLEAN  Available 
)

Definition at line 909 of file rangelist.c.

917{
918 if (Start > End)
920
921 *Available = RtlpWindowIsAvailable(RangeList,
922 Start,
923 End,
924 Flags,
925 AttributeAvailableMask,
926 Context,
927 Callback,
928 NULL);
929
930 return STATUS_SUCCESS;
931}

◆ RtlMergeRangeLists()

NTSTATUS NTAPI RtlMergeRangeLists ( OUT PRTL_RANGE_LIST  MergedRangeList,
IN PRTL_RANGE_LIST  RangeList1,
IN PRTL_RANGE_LIST  RangeList2,
IN ULONG  Flags 
)

Definition at line 954 of file rangelist.c.

958{
960 PRTL_RANGE Range;
962
963 /* Copy range list 1 to the merged range list */
964 Status = RtlCopyRangeList(MergedRangeList,
965 RangeList1);
966 if (!NT_SUCCESS(Status))
967 return Status;
968
969 /* Add range list 2 entries to the merged range list */
970 Status = RtlGetFirstRange(RangeList2,
971 &Iterator,
972 &Range);
973 if (!NT_SUCCESS(Status))
975
976 while (TRUE)
977 {
978 Status = RtlAddRange(MergedRangeList,
979 Range->Start,
980 Range->End,
981 Range->Attributes,
982 Range->Flags | Flags,
983 Range->UserData,
984 Range->Owner);
985 if (!NT_SUCCESS(Status))
986 break;
987
989 &Range,
990 TRUE);
991 if (!NT_SUCCESS(Status))
992 break;
993 }
994
996}
NTSTATUS NTAPI RtlGetFirstRange(IN PRTL_RANGE_LIST RangeList, OUT PRTL_RANGE_LIST_ITERATOR Iterator, OUT PRTL_RANGE *Range)
Definition: rangelist.c:586
NTSTATUS NTAPI RtlCopyRangeList(OUT PRTL_RANGE_LIST CopyRangeList, IN PRTL_RANGE_LIST RangeList)
Definition: rangelist.c:293
NTSTATUS NTAPI RtlGetNextRange(IN OUT PRTL_RANGE_LIST_ITERATOR Iterator, OUT PRTL_RANGE *Range, IN BOOLEAN MoveForwards)
Definition: rangelist.c:670

◆ RtlpConflictsOnAdd()

static BOOLEAN RtlpConflictsOnAdd ( _In_ PRTL_RANGE_LIST  RangeList,
_In_ ULONGLONG  Start,
_In_ ULONGLONG  End,
_In_ ULONG  Flags 
)
static

Definition at line 131 of file rangelist.c.

136{
138
139 for (Entry = RangeList->ListHead.Flink;
140 Entry != &RangeList->ListHead;
141 Entry = Entry->Flink)
142 {
144
145 if (Current->Range.Start > End)
146 break;
147
148 if (!RtlpOverlaps(Start, End, Current->Range.Start, Current->Range.End))
149 continue;
150
151 /* Overlapping shared ranges may coexist */
153 (Current->Range.Flags & RTL_RANGE_SHARED))
154 continue;
155
156 return TRUE;
157 }
158
159 return FALSE;
160}
static BOOLEAN RtlpOverlaps(_In_ ULONGLONG Start1, _In_ ULONGLONG End1, _In_ ULONGLONG Start2, _In_ ULONGLONG End2)
Definition: rangelist.c:36

Referenced by RtlAddRange().

◆ RtlpOverlaps()

static BOOLEAN RtlpOverlaps ( _In_ ULONGLONG  Start1,
_In_ ULONGLONG  End1,
_In_ ULONGLONG  Start2,
_In_ ULONGLONG  End2 
)
static

Definition at line 36 of file rangelist.c.

41{
42 return (Start1 <= End2 && Start2 <= End1);
43}

Referenced by RtlpConflictsOnAdd(), and RtlpWindowIsAvailable().

◆ RtlpWindowIsAvailable()

static BOOLEAN RtlpWindowIsAvailable ( _In_ PRTL_RANGE_LIST  RangeList,
_In_ ULONGLONG  Start,
_In_ ULONGLONG  End,
_In_ ULONG  Flags,
_In_ UCHAR  AttributeAvailableMask,
_In_opt_ PVOID  Context,
_In_opt_ PRTL_CONFLICT_RANGE_CALLBACK  Callback,
_Out_opt_ PULONGLONG  ConflictStart 
)
static

Definition at line 64 of file rangelist.c.

73{
75 BOOLEAN Available = TRUE;
76 ULONGLONG Lowest = 0;
77
78 for (Entry = RangeList->ListHead.Flink;
79 Entry != &RangeList->ListHead;
80 Entry = Entry->Flink)
81 {
83
84 if (Current->Range.Start > End)
85 break;
86
87 /* Ignore entries that do not overlap the requested window */
88 if (!RtlpOverlaps(Start, End, Current->Range.Start, Current->Range.End))
89 continue;
90
91 /* An overlapping entry that is treated as available is not a conflict */
93 (Current->Range.Flags & RTL_RANGE_SHARED))
94 continue;
95
96 if (AttributeAvailableMask & Current->Range.Attributes)
97 continue;
98
100 Current->Range.Owner == NULL)
101 continue;
102
103 /* provide callers the ability to change code paths before we make the range as unavailable. */
104 if (Callback != NULL && Callback(Context, &Current->Range))
105 continue;
106
107 /* This is a real conflict */
108 if (Available || Current->Range.Start < Lowest)
109 Lowest = Current->Range.Start;
110
111 Available = FALSE;
112 }
113
114 if (ConflictStart != NULL && !Available)
115 *ConflictStart = Lowest;
116
117 return Available;
118}
#define RTL_RANGE_LIST_NULL_CONFLICT_OK
Definition: rtltypes.h:90
#define RTL_RANGE_LIST_SHARED_OK
Definition: rtltypes.h:89

Referenced by RtlFindRange(), and RtlIsRangeAvailable().