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