xref: /reactos/base/setup/lib/utils/genlist.c (revision 40462c92)
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 = 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
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
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
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
97 GetCurrentListEntry(
98     IN PGENERIC_LIST List)
99 {
100     return List->CurrentEntry;
101 }
102 
103 PGENERIC_LIST_ENTRY
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
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
126 GetListEntryData(
127     IN PGENERIC_LIST_ENTRY Entry)
128 {
129     return Entry->Data;
130 }
131 
132 ULONG_PTR
133 GetListEntryUiData(
134     IN PGENERIC_LIST_ENTRY Entry)
135 {
136     return Entry->UiData;
137 }
138 
139 ULONG
140 GetNumberOfListEntries(
141     IN PGENERIC_LIST List)
142 {
143     return List->NumOfEntries;
144 }
145 
146 /* EOF */
147