[SETUPLIB][USETUP] Make the GENERIC_LIST store the items display text in UNICODE...
[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 = (PGENERIC_LIST)RtlAllocateHeap(ProcessHeap,
25 0,
26 sizeof(GENERIC_LIST));
27 if (List == NULL)
28 return NULL;
29
30 InitializeListHead(&List->ListHead);
31 List->NumOfEntries = 0;
32
33 List->CurrentEntry = NULL;
34 List->BackupEntry = NULL;
35
36 return List;
37 }
38
39 VOID
40 DestroyGenericList(
41 IN OUT PGENERIC_LIST List,
42 IN BOOLEAN FreeUserData)
43 {
44 PGENERIC_LIST_ENTRY ListEntry;
45 PLIST_ENTRY Entry;
46
47 /* Release list entries */
48 while (!IsListEmpty(&List->ListHead))
49 {
50 Entry = RemoveHeadList(&List->ListHead);
51 ListEntry = CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry);
52
53 /* Release user data */
54 if (FreeUserData && ListEntry->UserData != NULL)
55 RtlFreeHeap(ProcessHeap, 0, ListEntry->UserData);
56
57 /* Release list entry */
58 RtlFreeHeap(ProcessHeap, 0, ListEntry);
59 }
60
61 /* Release list head */
62 RtlFreeHeap(ProcessHeap, 0, List);
63 }
64
65 BOOLEAN
66 AppendGenericListEntry(
67 IN OUT PGENERIC_LIST List,
68 IN PCWSTR Text,
69 IN PVOID UserData,
70 IN BOOLEAN Current)
71 {
72 PGENERIC_LIST_ENTRY Entry;
73
74 Entry = (PGENERIC_LIST_ENTRY)RtlAllocateHeap(ProcessHeap,
75 0,
76 sizeof(GENERIC_LIST_ENTRY) +
77 (wcslen(Text) + 1) * sizeof(WCHAR));
78 if (Entry == NULL)
79 return FALSE;
80
81 wcscpy(Entry->Text, Text);
82 Entry->List = List;
83 Entry->UserData = UserData;
84
85 InsertTailList(&List->ListHead, &Entry->Entry);
86 List->NumOfEntries++;
87
88 if (Current || List->CurrentEntry == NULL)
89 {
90 List->CurrentEntry = Entry;
91 }
92
93 return TRUE;
94 }
95
96 VOID
97 SetCurrentListEntry(
98 IN PGENERIC_LIST List,
99 IN PGENERIC_LIST_ENTRY Entry)
100 {
101 if (Entry->List != List)
102 return;
103 List->CurrentEntry = Entry;
104 }
105
106 PGENERIC_LIST_ENTRY
107 GetCurrentListEntry(
108 IN PGENERIC_LIST List)
109 {
110 return List->CurrentEntry;
111 }
112
113 PGENERIC_LIST_ENTRY
114 GetFirstListEntry(
115 IN PGENERIC_LIST List)
116 {
117 PLIST_ENTRY Entry = List->ListHead.Flink;
118
119 if (Entry == &List->ListHead)
120 return NULL;
121 return CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry);
122 }
123
124 PGENERIC_LIST_ENTRY
125 GetNextListEntry(
126 IN PGENERIC_LIST_ENTRY Entry)
127 {
128 PLIST_ENTRY Next = Entry->Entry.Flink;
129
130 if (Next == &Entry->List->ListHead)
131 return NULL;
132 return CONTAINING_RECORD(Next, GENERIC_LIST_ENTRY, Entry);
133 }
134
135 PVOID
136 GetListEntryUserData(
137 IN PGENERIC_LIST_ENTRY Entry)
138 {
139 return Entry->UserData;
140 }
141
142 PCWSTR
143 GetListEntryText(
144 IN PGENERIC_LIST_ENTRY Entry)
145 {
146 return Entry->Text;
147 }
148
149 ULONG
150 GetNumberOfListEntries(
151 IN PGENERIC_LIST List)
152 {
153 return List->NumOfEntries;
154 }
155
156 VOID
157 SaveGenericListState(
158 IN PGENERIC_LIST List)
159 {
160 List->BackupEntry = List->CurrentEntry;
161 }
162
163 VOID
164 RestoreGenericListState(
165 IN PGENERIC_LIST List)
166 {
167 List->CurrentEntry = List->BackupEntry;
168 }
169
170 BOOLEAN
171 GenericListHasSingleEntry(
172 IN PGENERIC_LIST List)
173 {
174 if (!IsListEmpty(&List->ListHead) && List->ListHead.Flink == List->ListHead.Blink)
175 return TRUE;
176
177 /* if both list head pointers (which normally point to the first and last list member, respectively)
178 point to the same entry then it means that there's just a single thing in there, otherwise... false! */
179 return FALSE;
180 }
181
182 /* EOF */