diff --git a/boot/xtldr/includes/libxtos.hh b/boot/xtldr/includes/libxtos.hh index b14f107..741d523 100644 --- a/boot/xtldr/includes/libxtos.hh +++ b/boot/xtldr/includes/libxtos.hh @@ -80,7 +80,7 @@ namespace RTL IN PLIST_ENTRY Entry); STATIC XTCDECL VOID InsertTailList(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry); - STATIC XTCDECL BOOLEAN RemoveEntryList(IN PLIST_ENTRY Entry); + STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry); }; class Memory diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index f3c255c..3ea3355 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -99,7 +99,7 @@ typedef EFI_STATUS (XTCDECL *PBL_LOAD_EFI_IMAGE)(IN PEFI_DEVICE_PATH_PROTOCOL De typedef VOID (XTCDECL *PBL_LLIST_INITIALIZE_HEAD)(IN PLIST_ENTRY ListHead); typedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry); typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry); -typedef BOOLEAN (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry); +typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry); typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR VirtualAddress, IN ULONG_PTR PhysicalAddress, IN ULONG NumberOfPages); typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType); diff --git a/sdk/xtdk/rtlfuncs.h b/sdk/xtdk/rtlfuncs.h index 8a1400f..2dee67c 100644 --- a/sdk/xtdk/rtlfuncs.h +++ b/sdk/xtdk/rtlfuncs.h @@ -221,7 +221,7 @@ RtlMultiplyLargeInteger(IN LARGE_INTEGER Multiplicand, XTCLINK XTCDECL -BOOLEAN +VOID RtlRemoveEntryList(IN PLIST_ENTRY Entry); XTCLINK diff --git a/xtoskrnl/includes/rtl/llist.hh b/xtoskrnl/includes/rtl/llist.hh index 9db065c..acea1e5 100644 --- a/xtoskrnl/includes/rtl/llist.hh +++ b/xtoskrnl/includes/rtl/llist.hh @@ -4,6 +4,7 @@ * FILE: xtoskrnl/includes/rtl/llist.hh * DESCRIPTION: Linked list manipulation routines * DEVELOPERS: Aiken Harris + * Rafal Kupiec */ #ifndef __XTOSKRNL_RTL_LLIST_HH @@ -18,6 +19,7 @@ namespace RTL class LinkedList { public: + STATIC XTCDECL PLIST_ENTRY GetFirstEntry(IN PLIST_ENTRY ListHead); STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead); STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead); STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead, @@ -26,7 +28,11 @@ namespace RTL IN PLIST_ENTRY Entry); STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead); STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead); - STATIC XTCDECL BOOLEAN RemoveEntryList(IN PLIST_ENTRY Entry); + STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry); + STATIC XTCDECL VOID SpliceHeadList(IN OUT PLIST_ENTRY ListHead, + IN OUT PLIST_ENTRY SpliceList); + STATIC XTCDECL VOID SpliceTailList(IN OUT PLIST_ENTRY ListHead, + IN OUT PLIST_ENTRY SpliceList); }; } diff --git a/xtoskrnl/rtl/exports.cc b/xtoskrnl/rtl/exports.cc index bb5faff..f5158fd 100644 --- a/xtoskrnl/rtl/exports.cc +++ b/xtoskrnl/rtl/exports.cc @@ -763,16 +763,16 @@ RtlMultiplyLargeInteger(IN LARGE_INTEGER Multiplicand, * @param Entry * Pointer to the entry that will be removed from the list. * - * @return This routine returns TRUE if the list is empty after removal, or FALSE otherwise. + * @return This routine does not return any value. * * @since XT 1.0 */ XTCLINK XTCDECL -BOOLEAN +VOID RtlRemoveEntryList(IN PLIST_ENTRY Entry) { - return RTL::LinkedList::RemoveEntryList(Entry); + RTL::LinkedList::RemoveEntryList(Entry); } /** diff --git a/xtoskrnl/rtl/llist.cc b/xtoskrnl/rtl/llist.cc index 301d82a..1b63de6 100644 --- a/xtoskrnl/rtl/llist.cc +++ b/xtoskrnl/rtl/llist.cc @@ -9,6 +9,32 @@ #include +/** + * Retrieves the first entry from a double-linked list without removing it from the list. + * + * @param ListHead + * Pointer to a structure that serves as the list header. + * + * @return This routine returns a pointer to the first entry in the list. + * If the list is empty, the return value points to the list head. + * + * @since XT 1.0 + */ +XTCDECL +PLIST_ENTRY +RTL::LinkedList::GetFirstEntry(IN PLIST_ENTRY ListHead) +{ + /* Check if the list is empty */ + if(ListEmpty(ListHead)) + { + /* Empty list, return NULLPTR */ + return NULLPTR; + } + + /* Return first entry in the list */ + return ListHead->Flink; +} + /** * This routine initializes a structure representing the head of a double-linked list. * @@ -23,6 +49,7 @@ XTCDECL VOID RTL::LinkedList::InitializeListHead(IN PLIST_ENTRY ListHead) { + /* Initialize list head */ ListHead->Blink = ListHead; ListHead->Flink = ListHead; } @@ -41,6 +68,7 @@ XTCDECL VOID RTL::LinkedList::InitializeListHead32(IN PLIST_ENTRY32 ListHead) { + /* Initialize list head */ ListHead->Blink = PtrToUlong(ListHead); ListHead->Flink = PtrToUlong(ListHead); } @@ -63,6 +91,7 @@ VOID RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry) { + /* Insert entry at the head of the list */ Entry->Flink = ListHead->Flink; Entry->Blink = ListHead; ListHead->Flink->Blink = Entry; @@ -87,6 +116,7 @@ VOID RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry) { + /* Insert entry at the tail of the list */ Entry->Flink = ListHead; Entry->Blink = ListHead->Blink; ListHead->Blink->Flink = Entry; @@ -107,6 +137,7 @@ XTCDECL BOOLEAN RTL::LinkedList::ListEmpty(IN PLIST_ENTRY ListHead) { + /* Check if the list is empty */ return (((ListHead->Flink == NULLPTR) && (ListHead->Blink == NULLPTR)) || (ListHead->Flink == ListHead)); } @@ -162,18 +193,99 @@ RTL::LinkedList::ListLoop(IN PLIST_ENTRY ListHead) * @param Entry * Pointer to the entry that will be removed from the list. * - * @return This routine returns TRUE if the list is empty after removal, or FALSE otherwise. + * @return This routine does not return any value. * * @since XT 1.0 */ XTCDECL -BOOLEAN +VOID RTL::LinkedList::RemoveEntryList(IN PLIST_ENTRY Entry) { /* Remove entry from the list */ Entry->Flink->Blink = Entry->Blink; Entry->Blink->Flink = Entry->Flink; - - /* Return TRUE if list is empty, or FALSE otherwise */ - return ListEmpty(Entry); +} + +/** + * Splices a doubly linked list at the head of another list. The source list is reinitialized to empty. + * + * @param ListHead + * Pointer to a structure that represents the head of the list. + * + * @param SpliceList + * Pointer to a structure that represents the head of the list that will be spliced. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +RTL::LinkedList::SpliceHeadList(IN OUT PLIST_ENTRY ListHead, + IN OUT PLIST_ENTRY SpliceList) +{ + PLIST_ENTRY FirstEntry, LastEntry; + + /* Check if the list to splice is empty */ + if(SpliceList->Flink == SpliceList) + { + /* Nothing to splice, return */ + return; + } + + /* Get first and last entries of the list to splice */ + FirstEntry = SpliceList->Flink; + LastEntry = SpliceList->Blink; + + /* Splice the list at the head of destination */ + FirstEntry->Blink = ListHead; + LastEntry->Flink = ListHead->Flink; + ListHead->Flink->Blink = LastEntry; + ListHead->Flink = FirstEntry; + + /* Reinitialize the source list to empty */ + SpliceList->Blink = SpliceList; + SpliceList->Flink = SpliceList; +} + +/** + * Splices a doubly linked list at the tail of another list. The source list is reinitialized to empty. + * + * @param ListHead + * Pointer to the head of the destination list. + * + * @param SpliceList + * Pointer to the head of the list that will be spliced. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +RTL::LinkedList::SpliceTailList(IN OUT PLIST_ENTRY ListHead, + IN OUT PLIST_ENTRY SpliceList) +{ + PLIST_ENTRY FirstEntry, LastEntry; + + /* Check if the list to splice is empty */ + if(SpliceList->Flink == SpliceList) + { + /* Nothing to splice, return */ + return; + } + + /* Get first and last entries of the list to splice */ + FirstEntry = SpliceList->Flink; + LastEntry = SpliceList->Blink; + + /* Splice the list at the tail of destination */ + FirstEntry->Blink = ListHead->Blink; + LastEntry->Flink = ListHead; + ListHead->Blink->Flink = FirstEntry; + ListHead->Blink = LastEntry; + + /* Reinitialize the source list to empty */ + SpliceList->Blink = SpliceList; + SpliceList->Flink = SpliceList; }