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
CreateGenericList(VOID)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 List->CurrentEntry = NULL;
31
32 return List;
33 }
34
35 VOID
DestroyGenericList(IN OUT PGENERIC_LIST List,IN BOOLEAN FreeData)36 DestroyGenericList(
37 IN OUT PGENERIC_LIST List,
38 IN BOOLEAN FreeData)
39 {
40 PGENERIC_LIST_ENTRY ListEntry;
41 PLIST_ENTRY Entry;
42
43 /* Release list entries */
44 while (!IsListEmpty(&List->ListHead))
45 {
46 Entry = RemoveHeadList(&List->ListHead);
47 ListEntry = CONTAINING_RECORD(Entry, GENERIC_LIST_ENTRY, Entry);
48
49 /* Release user data */
50 if (FreeData && ListEntry->Data != NULL)
51 RtlFreeHeap(ProcessHeap, 0, ListEntry->Data);
52
53 /* Release list entry */
54 RtlFreeHeap(ProcessHeap, 0, ListEntry);
55 }
56
57 /* Release list head */
58 RtlFreeHeap(ProcessHeap, 0, List);
59 }
60
61 BOOLEAN
AppendGenericListEntry(IN OUT PGENERIC_LIST List,IN PVOID Data,IN BOOLEAN Current)62 AppendGenericListEntry(
63 IN OUT PGENERIC_LIST List,
64 IN PVOID Data,
65 IN BOOLEAN Current)
66 {
67 PGENERIC_LIST_ENTRY Entry;
68
69 Entry = RtlAllocateHeap(ProcessHeap, 0, sizeof(GENERIC_LIST_ENTRY));
70 if (Entry == NULL)
71 return FALSE;
72
73 Entry->List = List;
74 Entry->Data = Data;
75 Entry->UiData = 0;
76
77 InsertTailList(&List->ListHead, &Entry->Entry);
78 ++List->NumOfEntries;
79
80 if (Current || List->CurrentEntry == NULL)
81 List->CurrentEntry = Entry;
82
83 return TRUE;
84 }
85
86 VOID
SetCurrentListEntry(IN PGENERIC_LIST List,IN PGENERIC_LIST_ENTRY Entry)87 SetCurrentListEntry(
88 IN PGENERIC_LIST List,
89 IN PGENERIC_LIST_ENTRY Entry)
90 {
91 if (!Entry || (Entry->List != List))
92 return;
93 List->CurrentEntry = Entry;
94 }
95
96 PGENERIC_LIST_ENTRY
GetCurrentListEntry(IN PGENERIC_LIST List)97 GetCurrentListEntry(
98 IN PGENERIC_LIST List)
99 {
100 return List->CurrentEntry;
101 }
102
103 PGENERIC_LIST_ENTRY
GetFirstListEntry(IN PGENERIC_LIST List)104 GetFirstListEntry(
105 IN PGENERIC_LIST List)
106 {
107 if (IsListEmpty(&List->ListHead))
108 return NULL;
109
110 return CONTAINING_RECORD(List->ListHead.Flink, GENERIC_LIST_ENTRY, Entry);
111 }
112
113 PGENERIC_LIST_ENTRY
GetNextListEntry(IN PGENERIC_LIST_ENTRY Entry)114 GetNextListEntry(
115 IN PGENERIC_LIST_ENTRY Entry)
116 {
117 PLIST_ENTRY Next = Entry->Entry.Flink;
118
119 if (Next == &Entry->List->ListHead)
120 return NULL;
121
122 return CONTAINING_RECORD(Next, GENERIC_LIST_ENTRY, Entry);
123 }
124
125 PVOID
GetListEntryData(IN PGENERIC_LIST_ENTRY Entry)126 GetListEntryData(
127 IN PGENERIC_LIST_ENTRY Entry)
128 {
129 return Entry->Data;
130 }
131
132 ULONG_PTR
GetListEntryUiData(IN PGENERIC_LIST_ENTRY Entry)133 GetListEntryUiData(
134 IN PGENERIC_LIST_ENTRY Entry)
135 {
136 return Entry->UiData;
137 }
138
139 ULONG
GetNumberOfListEntries(IN PGENERIC_LIST List)140 GetNumberOfListEntries(
141 IN PGENERIC_LIST List)
142 {
143 return List->NumOfEntries;
144 }
145
146 /* EOF */
147