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 2004-2018 Eric Kohl
6 * Copyright 2008-2018 Christoph von Wittich <christoph at reactos.org>
9 /* INCLUDES *****************************************************************/
18 /* FUNCTIONS ****************************************************************/
21 CreateGenericList(VOID
)
25 List
= (PGENERIC_LIST
)RtlAllocateHeap(ProcessHeap
,
27 sizeof(GENERIC_LIST
));
31 InitializeListHead(&List
->ListHead
);
32 List
->NumOfEntries
= 0;
34 List
->CurrentEntry
= NULL
;
35 List
->BackupEntry
= NULL
;
42 IN OUT PGENERIC_LIST List
,
43 IN BOOLEAN FreeUserData
)
45 PGENERIC_LIST_ENTRY ListEntry
;
48 /* Release list entries */
49 while (!IsListEmpty(&List
->ListHead
))
51 Entry
= RemoveHeadList(&List
->ListHead
);
52 ListEntry
= CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
54 /* Release user data */
55 if (FreeUserData
&& ListEntry
->UserData
!= NULL
)
56 RtlFreeHeap(ProcessHeap
, 0, ListEntry
->UserData
);
58 /* Release list entry */
59 RtlFreeHeap(ProcessHeap
, 0, ListEntry
);
62 /* Release list head */
63 RtlFreeHeap(ProcessHeap
, 0, List
);
67 AppendGenericListEntry(
68 IN OUT PGENERIC_LIST List
,
73 PGENERIC_LIST_ENTRY Entry
;
75 Entry
= (PGENERIC_LIST_ENTRY
)RtlAllocateHeap(ProcessHeap
,
77 sizeof(GENERIC_LIST_ENTRY
) + strlen(Text
));
81 strcpy (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! */