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
) + strlen(Text
));
80 strcpy (Entry
->Text
, Text
);
82 Entry
->UserData
= UserData
;
84 InsertTailList(&List
->ListHead
, &Entry
->Entry
);
87 if (Current
|| List
->CurrentEntry
== NULL
)
89 List
->CurrentEntry
= Entry
;
97 IN PGENERIC_LIST List
,
98 IN PGENERIC_LIST_ENTRY Entry
)
100 if (Entry
->List
!= List
)
102 List
->CurrentEntry
= Entry
;
107 IN PGENERIC_LIST List
)
109 return List
->CurrentEntry
;
114 IN PGENERIC_LIST List
)
116 PLIST_ENTRY Entry
= List
->ListHead
.Flink
;
118 if (Entry
== &List
->ListHead
)
120 return CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
125 IN PGENERIC_LIST_ENTRY Entry
)
127 PLIST_ENTRY Next
= Entry
->Entry
.Flink
;
129 if (Next
== &Entry
->List
->ListHead
)
131 return CONTAINING_RECORD(Next
, GENERIC_LIST_ENTRY
, Entry
);
135 GetListEntryUserData(
136 IN PGENERIC_LIST_ENTRY Entry
)
138 return Entry
->UserData
;
143 IN PGENERIC_LIST_ENTRY Entry
)
149 GetNumberOfListEntries(
150 IN PGENERIC_LIST List
)
152 return List
->NumOfEntries
;
156 SaveGenericListState(
157 IN PGENERIC_LIST List
)
159 List
->BackupEntry
= List
->CurrentEntry
;
163 RestoreGenericListState(
164 IN PGENERIC_LIST List
)
166 List
->CurrentEntry
= List
->BackupEntry
;
170 GenericListHasSingleEntry(
171 IN PGENERIC_LIST List
)
173 if (!IsListEmpty(&List
->ListHead
) && List
->ListHead
.Flink
== List
->ListHead
.Blink
)
176 /* if both list head pointers (which normally point to the first and last list member, respectively)
177 point to the same entry then it means that there's just a single thing in there, otherwise... false! */