ReactOS 0.4.17-dev-684-ga6524ef
rangelist.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/rangelist.c
5 * PURPOSE: Range list implementation
6 * PROGRAMMERS: No programmer listed.
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <rtl.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* TYPES ********************************************************************/
17
18typedef struct _RTL_RANGE_ENTRY
19{
23
24/* PRIVATE FUNCTIONS ********************************************************/
25
26/**********************************************************************
27 * NAME PRIVATE
28 * RtlpOverlaps
29 *
30 * DESCRIPTION
31 * Returns whether the closed interval [Start1, End1] intersects the
32 * closed interval [Start2, End2].
33 */
34static
37 _In_ ULONGLONG Start1,
38 _In_ ULONGLONG End1,
39 _In_ ULONGLONG Start2,
40 _In_ ULONGLONG End2)
41{
42 return (Start1 <= End2 && Start2 <= End1);
43}
44
45/**********************************************************************
46 * NAME PRIVATE
47 * RtlpWindowIsAvailable
48 *
49 * DESCRIPTION
50 * Shared availability test used by RtlIsRangeAvailable and RtlFindRange.
51 * Walks every entry that overlaps [Start, End] and decides whether the
52 * window is free. An overlapping entry does NOT cause a conflict when:
53 * - the caller passed RTL_RANGE_LIST_SHARED_OK and the entry is shared,
54 * - the entry carries an attribute present in AttributeAvailableMask,
55 * - the caller passed RTL_RANGE_LIST_NULL_CONFLICT_OK and the entry has
56 * a NULL owner, or
57 * - the conflict Callback returns TRUE (asking us to ignore it).
58 * When the window is not available, *ConflictStart (if supplied) receives
59 * the lowest Start among the conflicting entries so a caller searching
60 * top-down can jump past them.
61 */
62static
65 _In_ PRTL_RANGE_LIST RangeList,
67 _In_ ULONGLONG End,
69 _In_ UCHAR AttributeAvailableMask,
72 _Out_opt_ PULONGLONG ConflictStart)
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}
119
120/**********************************************************************
121 * NAME PRIVATE
122 * RtlpConflictsOnAdd
123 *
124 * DESCRIPTION
125 * Returns whether inserting [Start, End] would conflict with an existing
126 * entry. Two shared ranges (the caller passing RTL_RANGE_LIST_ADD_SHARED
127 * against an already-shared entry) are allowed to coexist.
128 */
129static
132 _In_ PRTL_RANGE_LIST RangeList,
134 _In_ ULONGLONG End,
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}
161
162/* FUNCTIONS ***************************************************************/
163
164/**********************************************************************
165 * NAME EXPORTED
166 * RtlAddRange
167 *
168 * DESCRIPTION
169 * Adds a range to a range list.
170 *
171 * ARGUMENTS
172 * RangeList Range list.
173 * Start
174 * End
175 * Attributes
176 * Flags
177 * UserData
178 * Owner
179 *
180 * RETURN VALUE
181 * Status
182 *
183 * @implemented
184 */
186NTAPI
189 IN ULONGLONG End,
191 IN ULONG Flags,
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}
273
274
275/**********************************************************************
276 * NAME EXPORTED
277 * RtlCopyRangeList
278 *
279 * DESCRIPTION
280 * Copy a range list.
281 *
282 * ARGUMENTS
283 * CopyRangeList Pointer to the destination range list.
284 * RangeList Pointer to the source range list.
285 *
286 * RETURN VALUE
287 * Status
288 *
289 * @implemented
290 */
292NTAPI
294 IN PRTL_RANGE_LIST RangeList)
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}
327
328
329/**********************************************************************
330 * NAME EXPORTED
331 * RtlDeleteOwnersRanges
332 *
333 * DESCRIPTION
334 * Delete all ranges that belong to the given owner.
335 *
336 * ARGUMENTS
337 * RangeList Pointer to the range list.
338 * Owner User supplied value that identifies the owner
339 * of the ranges to be deleted.
340 *
341 * RETURN VALUE
342 * Status
343 *
344 * @implemented
345 */
347NTAPI
349 IN PVOID Owner)
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}
376
377
378/**********************************************************************
379 * NAME EXPORTED
380 * RtlDeleteRange
381 *
382 * DESCRIPTION
383 * Deletes a given range.
384 *
385 * ARGUMENTS
386 * RangeList Pointer to the range list.
387 * Start Start of the range to be deleted.
388 * End End of the range to be deleted.
389 * Owner Owner of the ranges to be deleted.
390 *
391 * RETURN VALUE
392 * Status
393 *
394 * @implemented
395 */
397NTAPI
400 IN ULONGLONG End,
401 IN PVOID Owner)
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}
428
429
430/**********************************************************************
431 * NAME EXPORTED
432 * RtlFindRange
433 *
434 * DESCRIPTION
435 * Searches (top-down) for an unused range, honoring the shared,
436 * null-conflict and attribute-availability rules and the conflict
437 * callback.
438 *
439 * ARGUMENTS
440 * RangeList Pointer to the range list.
441 * Minimum
442 * Maximum
443 * Length
444 * Alignment
445 * Flags
446 * AttributeAvailableMask
447 * Context
448 * Callback
449 * Start
450 *
451 * RETURN VALUE
452 * Status
453 *
454 * @implemented
455 */
457NTAPI
459 IN ULONGLONG Minimum,
460 IN ULONGLONG Maximum,
463 IN ULONG Flags,
464 IN UCHAR AttributeAvailableMask,
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}
527
528
529/**********************************************************************
530 * NAME EXPORTED
531 * RtlFreeRangeList
532 *
533 * DESCRIPTION
534 * Deletes all ranges in a range list.
535 *
536 * ARGUMENTS
537 * RangeList Pointer to the range list.
538 *
539 * RETURN VALUE
540 * None
541 *
542 * @implemented
543 */
544VOID
545NTAPI
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}
565
566
567/**********************************************************************
568 * NAME EXPORTED
569 * RtlGetFirstRange
570 *
571 * DESCRIPTION
572 * Retrieves the first range of a range list.
573 *
574 * ARGUMENTS
575 * RangeList Pointer to the range list.
576 * Iterator Pointer to a user supplied list state buffer.
577 * Range Pointer to the first range.
578 *
579 * RETURN VALUE
580 * Status
581 *
582 * @implemented
583 */
585NTAPI
588 OUT PRTL_RANGE *Range)
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}
606
607
608/**********************************************************************
609 * NAME EXPORTED
610 * RtlGetLastRange
611 *
612 * DESCRIPTION
613 * Retrieves the last range of a range list. Combine with
614 * RtlGetNextRange(..., MoveForwards = FALSE) to walk a list backwards.
615 *
616 * ARGUMENTS
617 * RangeList Pointer to the range list.
618 * Iterator Pointer to a user supplied list state buffer.
619 * Range Pointer to the last range.
620 *
621 * RETURN VALUE
622 * Status
623 *
624 * @implemented
625 */
627NTAPI
630 OUT PRTL_RANGE *Range)
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}
648
649
650/**********************************************************************
651 * NAME EXPORTED
652 * RtlGetNextRange
653 *
654 * DESCRIPTION
655 * Retrieves the next (or previous) range of a range list.
656 *
657 * ARGUMENTS
658 * Iterator Pointer to a user supplied list state buffer.
659 * Range Pointer to the first range.
660 * MoveForwards TRUE, get next range
661 * FALSE, get previous range
662 *
663 * RETURN VALUE
664 * Status
665 *
666 * @implemented
667 */
669NTAPI
671 OUT PRTL_RANGE *Range,
672 IN BOOLEAN MoveForwards)
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}
711
712
713/**********************************************************************
714 * NAME EXPORTED
715 * RtlInitializeRangeList
716 *
717 * DESCRIPTION
718 * Initializes a range list.
719 *
720 * ARGUMENTS
721 * RangeList Pointer to a user supplied range list.
722 *
723 * RETURN VALUE
724 * None
725 *
726 * @implemented
727 */
728VOID
729NTAPI
731{
732 InitializeListHead(&RangeList->ListHead);
733 RangeList->Flags = 0;
734 RangeList->Count = 0;
735 RangeList->Stamp = 0;
736}
737
738
739/**********************************************************************
740 * NAME EXPORTED
741 * RtlInvertRangeListEx
742 *
743 * DESCRIPTION
744 * Inverts a range list, tagging the newly created gap ranges with the
745 * supplied Attributes / UserData / Owner.
746 *
747 * ARGUMENTS
748 * InvertedRangeList Inverted range list.
749 * RangeList Range list.
750 * Attributes Attributes for the created gap ranges.
751 * UserData UserData for the created gap ranges.
752 * Owner Owner for the created gap ranges.
753 *
754 * RETURN VALUE
755 * Status
756 *
757 * @implemented
758 */
760NTAPI
762 IN PRTL_RANGE_LIST RangeList,
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}
854
855
856/**********************************************************************
857 * NAME EXPORTED
858 * RtlInvertRangeList
859 *
860 * DESCRIPTION
861 * Inverts a range list.
862 *
863 * ARGUMENTS
864 * InvertedRangeList Inverted range list.
865 * RangeList Range list.
866 *
867 * RETURN VALUE
868 * Status
869 *
870 * @implemented
871 */
873NTAPI
875 IN PRTL_RANGE_LIST RangeList)
876{
877 return RtlInvertRangeListEx(InvertedRangeList,
878 RangeList,
879 0,
880 NULL,
881 NULL);
882}
883
884
885/**********************************************************************
886 * NAME EXPORTED
887 * RtlIsRangeAvailable
888 *
889 * DESCRIPTION
890 * Checks whether a range is available or not.
891 *
892 * ARGUMENTS
893 * RangeList Pointer to the range list.
894 * Start
895 * End
896 * Flags
897 * AttributeAvailableMask
898 * Context
899 * Callback
900 * Available
901 *
902 * RETURN VALUE
903 * Status
904 *
905 * @implemented
906 */
908NTAPI
911 IN ULONGLONG End,
912 IN ULONG Flags,
913 IN UCHAR AttributeAvailableMask,
916 OUT PBOOLEAN Available)
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}
932
933
934/**********************************************************************
935 * NAME EXPORTED
936 * RtlMergeRangeList
937 *
938 * DESCRIPTION
939 * Merges two range lists.
940 *
941 * ARGUMENTS
942 * MergedRangeList Resulting range list.
943 * RangeList1 First range list.
944 * RangeList2 Second range list
945 * Flags
946 *
947 * RETURN VALUE
948 * Status
949 *
950 * @implemented
951 */
953NTAPI
955 IN PRTL_RANGE_LIST RangeList1,
956 IN PRTL_RANGE_LIST RangeList2,
957 IN ULONG Flags)
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}
997
998/* EOF */
static _Out_opt_ PULONGLONG Start
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlpAllocateMemory(ULONG Bytes, ULONG Tag)
Definition: libsupp.c:35
VOID NTAPI RtlpFreeMemory(PVOID Mem, ULONG Tag)
Definition: libsupp.c:44
return Found
Definition: dirsup.c:1270
#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 RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
Status
Definition: gdiplustypes.h:24
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_LIST_NULL_CONFLICT_OK
Definition: rtltypes.h:90
#define RTL_RANGE_SHARED
Definition: rtltypes.h:92
BOOLEAN(NTAPI * PRTL_CONFLICT_RANGE_CALLBACK)(PVOID Context, struct _RTL_RANGE *Range)
Definition: rtltypes.h:705
#define RTL_RANGE_LIST_SHARED_OK
Definition: rtltypes.h:89
#define _Out_opt_
Definition: no_sal2.h:214
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:395
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:285
#define STATUS_RANGE_LIST_CONFLICT
Definition: ntstatus.h:885
#define STATUS_RANGE_NOT_FOUND
Definition: ntstatus.h:893
NTSTATUS NTAPI RtlDeleteOwnersRanges(IN OUT PRTL_RANGE_LIST RangeList, IN PVOID Owner)
Definition: rangelist.c:348
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
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: rangelist.c:458
NTSTATUS NTAPI RtlGetLastRange(IN PRTL_RANGE_LIST RangeList, OUT PRTL_RANGE_LIST_ITERATOR Iterator, OUT PRTL_RANGE *Range)
Definition: rangelist.c:628
NTSTATUS NTAPI RtlGetFirstRange(IN PRTL_RANGE_LIST RangeList, OUT PRTL_RANGE_LIST_ITERATOR Iterator, OUT PRTL_RANGE *Range)
Definition: rangelist.c:586
VOID NTAPI RtlInitializeRangeList(IN OUT PRTL_RANGE_LIST RangeList)
Definition: rangelist.c:730
NTSTATUS NTAPI RtlCopyRangeList(OUT PRTL_RANGE_LIST CopyRangeList, IN PRTL_RANGE_LIST RangeList)
Definition: rangelist.c:293
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: rangelist.c:909
static BOOLEAN RtlpOverlaps(_In_ ULONGLONG Start1, _In_ ULONGLONG End1, _In_ ULONGLONG Start2, _In_ ULONGLONG End2)
Definition: rangelist.c:36
struct _RTL_RANGE_ENTRY * PRTL_RANGE_ENTRY
NTSTATUS NTAPI RtlGetNextRange(IN OUT PRTL_RANGE_LIST_ITERATOR Iterator, OUT PRTL_RANGE *Range, IN BOOLEAN MoveForwards)
Definition: rangelist.c:670
NTSTATUS NTAPI RtlDeleteRange(IN OUT PRTL_RANGE_LIST RangeList, IN ULONGLONG Start, IN ULONGLONG End, IN PVOID Owner)
Definition: rangelist.c:398
VOID NTAPI RtlFreeRangeList(IN PRTL_RANGE_LIST RangeList)
Definition: rangelist.c:546
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
NTSTATUS NTAPI RtlMergeRangeLists(OUT PRTL_RANGE_LIST MergedRangeList, IN PRTL_RANGE_LIST RangeList1, IN PRTL_RANGE_LIST RangeList2, IN ULONG Flags)
Definition: rangelist.c:954
struct _RTL_RANGE_ENTRY RTL_RANGE_ENTRY
static BOOLEAN RtlpConflictsOnAdd(_In_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ ULONG Flags)
Definition: rangelist.c:131
NTSTATUS NTAPI RtlInvertRangeList(OUT PRTL_RANGE_LIST InvertedRangeList, IN PRTL_RANGE_LIST RangeList)
Definition: rangelist.c:874
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
Entry
Definition: section.c:5216
#define STATUS_SUCCESS
Definition: shellext.h:65
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_ PVOID Context
Definition: storport.h:2269
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
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
unsigned char UCHAR
Definition: typedefs.h:53
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#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
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:656
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170