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>
8 /* INCLUDES *****************************************************************/
17 /* FUNCTIONS ****************************************************************/
20 CreateGenericList(VOID
)
24 List
= (PGENERIC_LIST
)RtlAllocateHeap(ProcessHeap
,
26 sizeof(GENERIC_LIST
));
30 InitializeListHead(&List
->ListHead
);
31 List
->NumOfEntries
= 0;
33 List
->CurrentEntry
= NULL
;
34 List
->BackupEntry
= NULL
;
41 IN OUT PGENERIC_LIST List
,
42 IN BOOLEAN FreeUserData
)
44 PGENERIC_LIST_ENTRY ListEntry
;
47 /* Release list entries */
48 while (!IsListEmpty(&List
->ListHead
))
50 Entry
= RemoveHeadList(&List
->ListHead
);
51 ListEntry
= CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
53 /* Release user data */
54 if (FreeUserData
&& ListEntry
->UserData
!= NULL
)
55 RtlFreeHeap(ProcessHeap
, 0, ListEntry
->UserData
);
57 /* Release list entry */
58 RtlFreeHeap(ProcessHeap
, 0, ListEntry
);
61 /* Release list head */
62 RtlFreeHeap(ProcessHeap
, 0, List
);
66 AppendGenericListEntry(
67 IN OUT PGENERIC_LIST List
,
72 PGENERIC_LIST_ENTRY Entry
;
74 Entry
= (PGENERIC_LIST_ENTRY
)RtlAllocateHeap(ProcessHeap
,
76 sizeof(GENERIC_LIST_ENTRY
) +
77 (wcslen(Text
) + 1) * sizeof(WCHAR
));
81 wcscpy(Entry
->Text
, Text
);
83 Entry
->UserData
= UserData
;
85 InsertTailList(&List
->ListHead
, &Entry
->Entry
);
88 if (Current
|| List
->CurrentEntry
== NULL
)
90 List
->CurrentEntry
= Entry
;
98 IN PGENERIC_LIST List
,
99 IN PGENERIC_LIST_ENTRY Entry
)
101 if (Entry
->List
!= List
)
103 List
->CurrentEntry
= Entry
;
108 IN PGENERIC_LIST List
)
110 return List
->CurrentEntry
;
115 IN PGENERIC_LIST List
)
117 PLIST_ENTRY Entry
= List
->ListHead
.Flink
;
119 if (Entry
== &List
->ListHead
)
121 return CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
126 IN PGENERIC_LIST_ENTRY Entry
)
128 PLIST_ENTRY Next
= Entry
->Entry
.Flink
;
130 if (Next
== &Entry
->List
->ListHead
)
132 return CONTAINING_RECORD(Next
, GENERIC_LIST_ENTRY
, Entry
);
136 GetListEntryUserData(
137 IN PGENERIC_LIST_ENTRY Entry
)
139 return Entry
->UserData
;
144 IN PGENERIC_LIST_ENTRY Entry
)
150 GetNumberOfListEntries(
151 IN PGENERIC_LIST List
)
153 return List
->NumOfEntries
;
157 SaveGenericListState(
158 IN PGENERIC_LIST List
)
160 List
->BackupEntry
= List
->CurrentEntry
;
164 RestoreGenericListState(
165 IN PGENERIC_LIST List
)
167 List
->CurrentEntry
= List
->BackupEntry
;
171 GenericListHasSingleEntry(
172 IN PGENERIC_LIST List
)
174 if (!IsListEmpty(&List
->ListHead
) && List
->ListHead
.Flink
== List
->ListHead
.Blink
)
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! */