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 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 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 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 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 102 GetCurrentListEntry( 103 IN PGENERIC_LIST List) 104 { 105 return List->CurrentEntry; 106 } 107 108 PGENERIC_LIST_ENTRY 109 NTAPI 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 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 134 GetListEntryData( 135 IN PGENERIC_LIST_ENTRY Entry) 136 { 137 return Entry->Data; 138 } 139 140 ULONG_PTR 141 GetListEntryUiData( 142 IN PGENERIC_LIST_ENTRY Entry) 143 { 144 return Entry->UiData; 145 } 146 147 ULONG 148 NTAPI 149 GetNumberOfListEntries( 150 IN PGENERIC_LIST List) 151 { 152 return List->NumOfEntries; 153 } 154 155 /* EOF */ 156