/********************************************************************** * NAME EXPORTED * RtlMergeRangeList * * DESCRIPTION * Merges two range lists. * * ARGUMENTS * MergedRangeList Resulting range list. * RangeList1 First range list. * RangeList2 Second range list * Flags * * RETURN VALUE * Status * * @implemented */ NTSTATUS NTAPI RtlMergeRangeLists(OUT PRTL_RANGE_LIST MergedRangeList, IN PRTL_RANGE_LIST RangeList1, IN PRTL_RANGE_LIST RangeList2, IN ULONG Flags) { RTL_RANGE_LIST_ITERATOR Iterator; PRTL_RANGE Range; NTSTATUS Status; /* Copy range list 1 to the merged range list */ Status = RtlCopyRangeList(MergedRangeList, RangeList1); if (!NT_SUCCESS(Status)) return Status; /* Add range list 2 entries to the merged range list */ Status = RtlGetFirstRange(RangeList2, &Iterator, &Range); if (!NT_SUCCESS(Status)) return (Status == STATUS_NO_MORE_ENTRIES) ? STATUS_SUCCESS : Status; while (TRUE) { Status = RtlAddRange(MergedRangeList, Range->Start, Range->End, Range->Attributes, Range->Flags | Flags, Range->UserData, Range->Owner); if (!NT_SUCCESS(Status)) break; Status = RtlGetNextRange(&Iterator, &Range, TRUE); if (!NT_SUCCESS(Status)) break; } return (Status == STATUS_NO_MORE_ENTRIES) ? STATUS_SUCCESS : Status; }
/********************************************************************** * NAME EXPORTED * RtlInvertRangeList * * DESCRIPTION * Inverts a range list. * * ARGUMENTS * InvertedRangeList Inverted range list. * RangeList Range list. * * RETURN VALUE * Status * * @implemented */ NTSTATUS NTAPI RtlInvertRangeList (OUT PRTL_RANGE_LIST InvertedRangeList, IN PRTL_RANGE_LIST RangeList) { PRTL_RANGE_ENTRY Previous; PRTL_RANGE_ENTRY Current; PLIST_ENTRY Entry; NTSTATUS Status; /* Don't invert an empty range list */ if (IsListEmpty(&RangeList->ListHead)) { return STATUS_SUCCESS; } /* Add leading and intermediate ranges */ Previous = NULL; Entry = RangeList->ListHead.Flink; while (Entry != &RangeList->ListHead) { Current = CONTAINING_RECORD (Entry, RTL_RANGE_ENTRY, Entry); if (Previous == NULL) { if (Current->Range.Start != (ULONGLONG)0) { Status = RtlAddRange (InvertedRangeList, (ULONGLONG)0, Current->Range.Start - 1, 0, 0, NULL, NULL); if (!NT_SUCCESS(Status)) return Status; } } else { if (Previous->Range.End + 1 != Current->Range.Start) { Status = RtlAddRange (InvertedRangeList, Previous->Range.End + 1, Current->Range.Start - 1, 0, 0, NULL, NULL); if (!NT_SUCCESS(Status)) return Status; } } Previous = Current; Entry = Entry->Flink; } /* Add trailing range */ if (Previous->Range.End + 1 != (ULONGLONG)-1) { Status = RtlAddRange (InvertedRangeList, Previous->Range.End + 1, (ULONGLONG)-1, 0, 0, NULL, NULL); if (!NT_SUCCESS(Status)) return Status; } return STATUS_SUCCESS; }