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