mirror of
https://github.com/reactos/reactos.git
synced 2024-10-23 14:36:11 +00:00
Implement basic range list functions.
svn path=/trunk/; revision=9378
This commit is contained in:
parent
57df925ccb
commit
4087ebf77f
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: rangelist.c,v 1.1 2004/02/01 20:48:06 ekohl Exp $
|
/* $Id: rangelist.c,v 1.2 2004/05/14 12:11:52 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -28,11 +28,24 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <ntdll/ntdll.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _RTL_RANGE_ENTRY
|
||||||
|
{
|
||||||
|
LIST_ENTRY Entry;
|
||||||
|
RTL_RANGE Range;
|
||||||
|
} RTL_RANGE_ENTRY, *PRTL_RANGE_ENTRY;
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* TODO:
|
||||||
|
* - Check for overlapping ranges.
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
RtlAddRange (IN OUT PRTL_RANGE_LIST RangeList,
|
RtlAddRange (IN OUT PRTL_RANGE_LIST RangeList,
|
||||||
|
@ -43,7 +56,70 @@ RtlAddRange (IN OUT PRTL_RANGE_LIST RangeList,
|
||||||
IN PVOID UserData OPTIONAL,
|
IN PVOID UserData OPTIONAL,
|
||||||
IN PVOID Owner OPTIONAL)
|
IN PVOID Owner OPTIONAL)
|
||||||
{
|
{
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PRTL_RANGE_ENTRY RangeEntry;
|
||||||
|
PRTL_RANGE_ENTRY Previous;
|
||||||
|
PRTL_RANGE_ENTRY Current;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
|
||||||
|
if (Start > End)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* Create new range entry */
|
||||||
|
RangeEntry = RtlAllocateHeap (RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
sizeof(RTL_RANGE_ENTRY));
|
||||||
|
if (RangeEntry == NULL)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Initialize range entry */
|
||||||
|
RangeEntry->Range.Start = Start;
|
||||||
|
RangeEntry->Range.End = End;
|
||||||
|
RangeEntry->Range.Attributes = Attributes;
|
||||||
|
RangeEntry->Range.Flags = Flags;
|
||||||
|
RangeEntry->Range.UserData = UserData;
|
||||||
|
RangeEntry->Range.Owner = Owner;
|
||||||
|
|
||||||
|
/* Insert range entry */
|
||||||
|
if (RangeList->Count == 0)
|
||||||
|
{
|
||||||
|
InsertTailList (&RangeList->ListHead,
|
||||||
|
&RangeEntry->Entry);
|
||||||
|
RangeList->Count++;
|
||||||
|
RangeList->Stamp++;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Previous = NULL;
|
||||||
|
Entry = RangeList->ListHead.Flink;
|
||||||
|
while (Entry != &RangeList->ListHead)
|
||||||
|
{
|
||||||
|
Current = CONTAINING_RECORD (Entry, RTL_RANGE_ENTRY, Entry);
|
||||||
|
if (Current->Range.Start > RangeEntry->Range.End)
|
||||||
|
{
|
||||||
|
/* Insert before current */
|
||||||
|
DPRINT ("Insert before current\n");
|
||||||
|
InsertTailList (&Current->Entry,
|
||||||
|
&RangeEntry->Entry);
|
||||||
|
|
||||||
|
RangeList->Count++;
|
||||||
|
RangeList->Stamp++;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
Previous = Current;
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT ("Insert tail\n");
|
||||||
|
InsertTailList (&RangeList->ListHead,
|
||||||
|
&RangeEntry->Entry);
|
||||||
|
RangeList->Count++;
|
||||||
|
RangeList->Stamp++;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,35 +178,92 @@ RtlFindRange (IN PRTL_RANGE_LIST RangeList,
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
RtlFreeRangeList (IN PRTL_RANGE_LIST RangeList)
|
RtlFreeRangeList (IN PRTL_RANGE_LIST RangeList)
|
||||||
{
|
{
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PRTL_RANGE_ENTRY Current;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (!IsListEmpty(&RangeList->ListHead))
|
||||||
|
{
|
||||||
|
Entry = RemoveHeadList (&RangeList->ListHead);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
Current = CONTAINING_RECORD (Entry, RTL_RANGE_ENTRY, Entry);
|
||||||
|
DPRINT ("Range start: %I64u\n", Current->Range.Start);
|
||||||
|
DPRINT ("Range end: %I64u\n", Current->Range.End);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RtlFreeHeap (RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeList->Count = 0;
|
||||||
|
RangeList->Stamp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
RtlGetFirstRange (IN PRTL_RANGE_LIST RangeList,
|
RtlGetFirstRange (IN PRTL_RANGE_LIST RangeList,
|
||||||
OUT PRTL_RANGE_LIST_ITERATOR Iterator,
|
OUT PRTL_RANGE_LIST_ITERATOR Iterator,
|
||||||
OUT PRTL_RANGE *Range)
|
OUT PRTL_RANGE *Range)
|
||||||
{
|
{
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
Iterator->RangeListHead = &RangeList->ListHead;
|
||||||
|
Iterator->MergedHead = NULL;
|
||||||
|
Iterator->Stamp = RangeList->Stamp;
|
||||||
|
if (IsListEmpty(&RangeList->ListHead))
|
||||||
|
{
|
||||||
|
Iterator->Current = NULL;
|
||||||
|
*Range = NULL;
|
||||||
|
return STATUS_NO_MORE_ENTRIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator->Current = RangeList->ListHead.Flink;
|
||||||
|
*Range = &((PRTL_RANGE_ENTRY)Iterator->Current)->Range;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
RtlGetNextRange (IN OUT PRTL_RANGE_LIST_ITERATOR Iterator,
|
RtlGetNextRange (IN OUT PRTL_RANGE_LIST_ITERATOR Iterator,
|
||||||
OUT PRTL_RANGE *Range,
|
OUT PRTL_RANGE *Range,
|
||||||
IN BOOLEAN MoveForwards)
|
IN BOOLEAN MoveForwards)
|
||||||
{
|
{
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PRTL_RANGE_LIST RangeList;
|
||||||
|
PLIST_ENTRY Next;
|
||||||
|
|
||||||
|
RangeList = CONTAINING_RECORD(Iterator->RangeListHead, RTL_RANGE_LIST, ListHead);
|
||||||
|
if (Iterator->Stamp != RangeList->Stamp)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (MoveForwards)
|
||||||
|
{
|
||||||
|
Next = ((PRTL_RANGE_ENTRY)Iterator->Current)->Entry.Flink;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Next = ((PRTL_RANGE_ENTRY)Iterator->Current)->Entry.Blink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Next == Iterator->RangeListHead)
|
||||||
|
return STATUS_NO_MORE_ENTRIES;
|
||||||
|
|
||||||
|
Iterator->Current = Next;
|
||||||
|
*Range = &((PRTL_RANGE_ENTRY)Next)->Range;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,6 +273,10 @@ RtlGetNextRange (IN OUT PRTL_RANGE_LIST_ITERATOR Iterator,
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
RtlInitializeRangeList (IN OUT PRTL_RANGE_LIST RangeList)
|
RtlInitializeRangeList (IN OUT PRTL_RANGE_LIST RangeList)
|
||||||
{
|
{
|
||||||
|
InitializeListHead (&RangeList->ListHead);
|
||||||
|
RangeList->Flags = 0;
|
||||||
|
RangeList->Count = 0;
|
||||||
|
RangeList->Stamp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue