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
19 PGENERIC_LIST
20 NTAPI
CreateGenericList(VOID)21 CreateGenericList(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
36 VOID
37 NTAPI
DestroyGenericList(IN OUT PGENERIC_LIST List,IN BOOLEAN FreeData)38 DestroyGenericList(
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
63 BOOLEAN
64 NTAPI
AppendGenericListEntry(IN OUT PGENERIC_LIST List,IN PVOID Data,IN BOOLEAN Current)65 AppendGenericListEntry(
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
89 VOID
90 NTAPI
SetCurrentListEntry(IN PGENERIC_LIST List,IN PGENERIC_LIST_ENTRY Entry)91 SetCurrentListEntry(
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
100 PGENERIC_LIST_ENTRY
101 NTAPI
GetCurrentListEntry(IN PGENERIC_LIST List)102 GetCurrentListEntry(
103 IN PGENERIC_LIST List)
104 {
105 return List->CurrentEntry;
106 }
107
108 PGENERIC_LIST_ENTRY
109 NTAPI
GetFirstListEntry(IN PGENERIC_LIST List)110 GetFirstListEntry(
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
119 PGENERIC_LIST_ENTRY
120 NTAPI
GetNextListEntry(IN PGENERIC_LIST_ENTRY Entry)121 GetNextListEntry(
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
132 PVOID
133 NTAPI
GetListEntryData(IN PGENERIC_LIST_ENTRY Entry)134 GetListEntryData(
135 IN PGENERIC_LIST_ENTRY Entry)
136 {
137 return Entry->Data;
138 }
139
140 ULONG_PTR
GetListEntryUiData(IN PGENERIC_LIST_ENTRY Entry)141 GetListEntryUiData(
142 IN PGENERIC_LIST_ENTRY Entry)
143 {
144 return Entry->UiData;
145 }
146
147 ULONG
148 NTAPI
GetNumberOfListEntries(IN PGENERIC_LIST List)149 GetNumberOfListEntries(
150 IN PGENERIC_LIST List)
151 {
152 return List->NumOfEntries;
153 }
154
155 /* EOF */
156