[SETUPLIB][USETUP] Use NT RTL String Safe functions instead of Win32-oriented ones...
[reactos.git] / base / setup / lib / utils / genlist.c
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 CreateGenericList(VOID)
21 {
22 PGENERIC_LIST List;
23
24 List = RtlAllocateHeap(ProcessHeap, 0, sizeof(GENERIC_LIST));
25 if (List == NULL)
26 return NULL;
27
28 InitializeListHead(&List->ListHead);
29 List->NumOfEntries = 0;
30
31 List->CurrentEntry = NULL;
32 List->BackupEntry = NULL;
33
34 return List;
35 }
36
37 VOID
38 DestroyGenericList(
39 IN OUT PGENERIC_LIST List,
40 IN BOOLEAN FreeUserData)
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 (FreeUserData && ListEntry->UserData != NULL)
53 RtlFreeHeap(ProcessHeap, 0, ListEntry->UserData);
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 AppendGenericListEntry(
65 IN OUT PGENERIC_LIST List,
66 IN PCWSTR Text,
67 IN PVOID UserData,
68 IN BOOLEAN Current)
69 {
70 PGENERIC_LIST_ENTRY Entry;
71 SIZE_T TextSize;
72
73 TextSize = (wcslen(Text) + 1) * sizeof(WCHAR);
74 Entry = RtlAllocateHeap(ProcessHeap, 0,
75 sizeof(GENERIC_LIST_ENTRY) + TextSize);
76 if (Entry == NULL)
77 return FALSE;
78
79 RtlStringCbCopyW(Entry->Text, TextSize, Text);
80 Entry->List = List;
81 Entry->UserData = UserData;
82
83 InsertTailList(&List->ListHead, &Entry->Entry);
84 List->NumOfEntries++;
85
86 if (Current || List->CurrentEntry == NULL)
87 {
88 List->CurrentEntry = Entry;
89 }
90
91 return TRUE;
92 }
93
94 VOID
95 SetCurrentListEntry(
96 IN PGENERIC_LIST List,
97 IN PGENERIC_LIST_ENTRY Entry)
98 {
99 if (Entry->List != List)
100 return;
101 List->CurrentEntry = Entry;
102 }
103
104 PGENERIC_LIST_ENTRY
105 GetCurrentListEntry(
106 IN PGENERIC_LIST List)
107 {
108 return List->CurrentEntry;
109 }
110
111 PGENERIC_LIST_ENTRY
112 GetFirstListEntry(
113 IN PGENERIC_LIST List)
114 {
115 PLIST_ENTRY Entry = List->ListHead.Flink;
116
117 if (Entry == &List->ListHead)
118 return NULL;
119 return CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry);
120 }
121
122 PGENERIC_LIST_ENTRY
123 GetNextListEntry(
124 IN PGENERIC_LIST_ENTRY Entry)
125 {
126 PLIST_ENTRY Next = Entry->Entry.Flink;
127
128 if (Next == &Entry->List->ListHead)
129 return NULL;
130 return CONTAINING_RECORD(Next, GENERIC_LIST_ENTRY, Entry);
131 }
132
133 PVOID
134 GetListEntryUserData(
135 IN PGENERIC_LIST_ENTRY Entry)
136 {
137 return Entry->UserData;
138 }
139
140 PCWSTR
141 GetListEntryText(
142 IN PGENERIC_LIST_ENTRY Entry)
143 {
144 return Entry->Text;
145 }
146
147 ULONG
148 GetNumberOfListEntries(
149 IN PGENERIC_LIST List)
150 {
151 return List->NumOfEntries;
152 }
153
154 VOID
155 SaveGenericListState(
156 IN PGENERIC_LIST List)
157 {
158 List->BackupEntry = List->CurrentEntry;
159 }
160
161 VOID
162 RestoreGenericListState(
163 IN PGENERIC_LIST List)
164 {
165 List->CurrentEntry = List->BackupEntry;
166 }
167
168 BOOLEAN
169 GenericListHasSingleEntry(
170 IN PGENERIC_LIST List)
171 {
172 if (!IsListEmpty(&List->ListHead) && List->ListHead.Flink == List->ListHead.Blink)
173 return TRUE;
174
175 /* if both list head pointers (which normally point to the first and last list member, respectively)
176 point to the same entry then it means that there's just a single thing in there, otherwise... false! */
177 return FALSE;
178 }
179
180 /* EOF */