Reactos
1/*
2 * PROJECT: ReactOS Setup Library
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Generic list functions
5 * COPYRIGHT: Copyright 2008-2018 Christoph von Wittich <christoph at reactos.org>
6 */
7
8/* INCLUDES *****************************************************************/
9
10#include "precomp.h"
11
12#include "genlist.h"
13
14#define NDEBUG
15#include <debug.h>
16
17/* FUNCTIONS ****************************************************************/
18
19PGENERIC_LIST
20NTAPI
21CreateGenericList(VOID)
22{
23 PGENERIC_LIST List;
24
25 List = RtlAllocateHeap(ProcessHeap, 0, sizeof(GENERIC_LIST));
26 if (List == NULL)
27 return NULL;
28
29 InitializeListHead(&List->ListHead);
30 List->NumOfEntries = 0;
31 List->CurrentEntry = NULL;
32
33 return List;
34}
35
36VOID
37NTAPI
38DestroyGenericList(
39 IN OUT PGENERIC_LIST List,
40 IN BOOLEAN FreeData)
41{
42 PGENERIC_LIST_ENTRY ListEntry;
43 PLIST_ENTRY Entry;
44
45 /* Release list entries */
46 while (!IsListEmpty(&List->ListHead))
47 {
48 Entry = RemoveHeadList(&List->ListHead);
49 ListEntry = CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry);
50
51 /* Release user data */
52 if (FreeData && ListEntry->Data != NULL)
53 RtlFreeHeap(ProcessHeap, 0, ListEntry->Data);
54
55 /* Release list entry */
56 RtlFreeHeap(ProcessHeap, 0, ListEntry);
57 }
58
59 /* Release list head */
60 RtlFreeHeap(ProcessHeap, 0, List);
61}
62
63BOOLEAN
64NTAPI
65AppendGenericListEntry(
66 IN OUT PGENERIC_LIST List,
67 IN PVOID Data,
68 IN BOOLEAN Current)
69{
70 PGENERIC_LIST_ENTRY Entry;
71
72 Entry = RtlAllocateHeap(ProcessHeap, 0, sizeof(GENERIC_LIST_ENTRY));
73 if (Entry == NULL)
74 return FALSE;
75
76 Entry->List = List;
77 Entry->Data = Data;
78 Entry->UiData = 0;
79
80 InsertTailList(&List->ListHead, &Entry->Entry);
81 ++List->NumOfEntries;
82
83 if (Current || List->CurrentEntry == NULL)
84 List->CurrentEntry = Entry;
85
86 return TRUE;
87}
88
89VOID
90NTAPI
91SetCurrentListEntry(
92 IN PGENERIC_LIST List,
93 IN PGENERIC_LIST_ENTRY Entry)
94{
95 if (!Entry || (Entry->List != List))
96 return;
97 List->CurrentEntry = Entry;
98}
99
100PGENERIC_LIST_ENTRY
101NTAPI
102GetCurrentListEntry(
103 IN PGENERIC_LIST List)
104{
105 return List->CurrentEntry;
106}
107
108PGENERIC_LIST_ENTRY
109NTAPI
110GetFirstListEntry(
111 IN PGENERIC_LIST List)
112{
113 if (IsListEmpty(&List->ListHead))
114 return NULL;
115
116 return CONTAINING_RECORD(List->ListHead.Flink, GENERIC_LIST_ENTRY, Entry);
117}
118
119PGENERIC_LIST_ENTRY
120NTAPI
121GetNextListEntry(
122 IN PGENERIC_LIST_ENTRY Entry)
123{
124 PLIST_ENTRY Next = Entry->Entry.Flink;
125
126 if (Next == &Entry->List->ListHead)
127 return NULL;
128
129 return CONTAINING_RECORD(Next, GENERIC_LIST_ENTRY, Entry);
130}
131
132PVOID
133NTAPI
134GetListEntryData(
135 IN PGENERIC_LIST_ENTRY Entry)
136{
137 return Entry->Data;
138}
139
140ULONG_PTR
141GetListEntryUiData(
142 IN PGENERIC_LIST_ENTRY Entry)
143{
144 return Entry->UiData;
145}
146
147ULONG
148NTAPI
149GetNumberOfListEntries(
150 IN PGENERIC_LIST List)
151{
152 return List->NumOfEntries;
153}
154
155/* EOF */