From c041457799f93b84c3f2a3a6309dcffd782c5d3b Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Sat, 20 Sep 2025 18:47:36 +0200 Subject: [PATCH] Refactor bootloader code into C++ classes --- xtldr/CMakeLists.txt | 1 - xtldr/arch/amd64/memory.cc | 262 ++++----- xtldr/arch/i686/memory.cc | 270 +++++----- xtldr/bootutil.cc | 4 +- xtldr/config.cc | 551 +++++++++---------- xtldr/console.cc | 174 +++--- xtldr/debug.cc | 248 ++++++--- xtldr/efiutils.cc | 72 +-- xtldr/hardware.cc | 112 ---- xtldr/includes/xtldr.hh | 302 +++++++++++ xtldr/memory.cc | 194 +++---- xtldr/modules/acpi/acpi.cc | 8 +- xtldr/modules/beep/beep.cc | 2 +- xtldr/modules/chainldr/chainldr.cc | 6 +- xtldr/modules/xtos_o/amd64/memory.cc | 6 +- xtldr/modules/xtos_o/i686/memory.cc | 4 +- xtldr/protocol.cc | 401 +++++++++----- xtldr/shell.cc | 14 +- xtldr/textui.cc | 766 +++++++++++++-------------- xtldr/volume.cc | 148 +++--- xtldr/xtldr.cc | 225 ++------ 21 files changed, 2031 insertions(+), 1739 deletions(-) delete mode 100644 xtldr/hardware.cc diff --git a/xtldr/CMakeLists.txt b/xtldr/CMakeLists.txt index c07f7cf..3a348c6 100644 --- a/xtldr/CMakeLists.txt +++ b/xtldr/CMakeLists.txt @@ -22,7 +22,6 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/debug.cc ${XTLDR_SOURCE_DIR}/efiutils.cc ${XTLDR_SOURCE_DIR}/globals.cc - ${XTLDR_SOURCE_DIR}/hardware.cc ${XTLDR_SOURCE_DIR}/memory.cc ${XTLDR_SOURCE_DIR}/protocol.cc ${XTLDR_SOURCE_DIR}/shell.cc diff --git a/xtldr/arch/amd64/memory.cc b/xtldr/arch/amd64/memory.cc index eb392f3..10fe6c4 100644 --- a/xtldr/arch/amd64/memory.cc +++ b/xtldr/arch/amd64/memory.cc @@ -25,8 +25,8 @@ */ XTCDECL EFI_STATUS -BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress) +Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; PXTBL_MEMORY_MAPPING Mapping; @@ -35,7 +35,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, EFI_STATUS Status; /* Allocate pages for the Page Map */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -47,7 +47,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); /* Add page mapping itself to memory mapping */ - Status = BlpSelfMapPml(PageMap, SelfMapAddress); + Status = Memory::SelfMapPml(PageMap, SelfMapAddress); if(Status != STATUS_EFI_SUCCESS) { /* PML mapping failed */ @@ -55,8 +55,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Map the trampoline code area */ - Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, - 1, LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, + 1, LoaderFirmwareTemporary); if(Status != STATUS_EFI_SUCCESS) { /* Mapping trampoline code failed */ @@ -64,7 +64,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Get list of XTLDR modules */ - ModulesList = BlGetModulesList(); + ModulesList = Protocol::GetModulesList(); ModulesListEntry = ModulesList->Flink; while(ModulesListEntry != ModulesList) { @@ -72,8 +72,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); /* Map module code */ - Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, - EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, + EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); /* Check if mapping succeeded */ if(Status != STATUS_EFI_SUCCESS) @@ -90,8 +90,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, if(BlpStatus.LoaderBase && BlpStatus.LoaderSize) { /* Map boot loader code as well */ - Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, - EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, + EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); if(Status != STATUS_EFI_SUCCESS) { /* Mapping boot loader code failed */ @@ -105,7 +105,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Iterate through and map all the mappings*/ - BlDebugPrint(L"Mapping and dumping EFI memory:\n"); + Debug::Print(L"Mapping and dumping EFI memory:\n"); ListEntry = PageMap->MemoryMap.Flink; while(ListEntry != &PageMap->MemoryMap) { @@ -116,12 +116,12 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, if(Mapping->VirtualAddress) { /* Dump memory mapping */ - BlDebugPrint(L" Type=%02lu, PhysicalBase=%.16P, VirtualBase=%.16P, Pages=%llu\n", Mapping->MemoryType, + Debug::Print(L" Type=%02lu, PhysicalBase=%.16P, VirtualBase=%.16P, Pages=%llu\n", Mapping->MemoryType, Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); /* Map memory */ - Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, - (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); + Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, + (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); if(Status != STATUS_EFI_SUCCESS) { /* Memory mapping failed */ @@ -137,114 +137,6 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, return STATUS_EFI_SUCCESS; } -/** - * Does the actual virtual memory mapping. - * - * @param PageMap - * Supplies a pointer to the page mapping structure. - * - * @param VirtualAddress - * Supplies a virtual address of the mapping. - * - * @param PhysicalAddress - * Supplies a physical address of the mapping. - * - * @param NumberOfPages - * Supplies a number of the pages of the mapping. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR VirtualAddress, - IN ULONG_PTR PhysicalAddress, - IN ULONG NumberOfPages) -{ - PVOID Pml1, Pml2, Pml3, Pml4, Pml5; - SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry; - PHARDWARE_PTE PmlTable; - SIZE_T PageFrameNumber; - EFI_STATUS Status; - - /* Set the Page Frame Number (PFN) */ - PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; - - /* Do the recursive mapping */ - while(NumberOfPages > 0) - { - /* Calculate the indices in the various Page Tables from the virtual address */ - Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT; - Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT; - Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT; - Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT; - Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PTI_SHIFT)) >> MM_PTI_SHIFT; - - /* Check page map level */ - if(PageMap->PageMapLevel == 5) - { - /* Five level Page Map */ - Pml5 = PageMap->PtePointer; - - /* Get PML4 */ - Status = BlpGetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory mapping failure */ - return Status; - } - } - else - { - /* Four level Page Map */ - Pml4 = PageMap->PtePointer; - } - - /* Get PML3 */ - Status = BlpGetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory mapping failure */ - return Status; - } - - /* Get PML 2 */ - Status = BlpGetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory mapping failure */ - return Status; - } - - /* Get PML1 */ - Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory mapping failure */ - return Status; - } - - /* Set paging entry settings */ - PmlTable = (PHARDWARE_PTE)Pml1; - RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE)); - PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber; - PmlTable[Pml1Entry].Valid = 1; - PmlTable[Pml1Entry].Writable = 1; - - /* Take next virtual address and PFN */ - VirtualAddress += EFI_PAGE_SIZE; - PageFrameNumber++; - - /* Decrease number of pages left */ - NumberOfPages--; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - /** * Returns next level of the Page Table. * @@ -266,10 +158,10 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID PageTable, - IN SIZE_T Entry, - OUT PVOID *NextPageTable) +Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PageTable, + IN SIZE_T Entry, + OUT PVOID *NextPageTable) { EFI_PHYSICAL_ADDRESS Address; ULONGLONG PmlPointer = 0; @@ -288,7 +180,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, else { /* Allocate pages for new PML entry */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -296,7 +188,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, } /* Add new memory mapping */ - Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); + Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); if(Status != STATUS_EFI_SUCCESS) { /* Memory mapping failure */ @@ -320,6 +212,114 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, return STATUS_EFI_SUCCESS; } +/** + * Does the actual virtual memory mapping. + * + * @param PageMap + * Supplies a pointer to the page mapping structure. + * + * @param VirtualAddress + * Supplies a virtual address of the mapping. + * + * @param PhysicalAddress + * Supplies a physical address of the mapping. + * + * @param NumberOfPages + * Supplies a number of the pages of the mapping. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR VirtualAddress, + IN ULONG_PTR PhysicalAddress, + IN ULONG NumberOfPages) +{ + PVOID Pml1, Pml2, Pml3, Pml4, Pml5; + SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry; + PHARDWARE_PTE PmlTable; + SIZE_T PageFrameNumber; + EFI_STATUS Status; + + /* Set the Page Frame Number (PFN) */ + PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; + + /* Do the recursive mapping */ + while(NumberOfPages > 0) + { + /* Calculate the indices in the various Page Tables from the virtual address */ + Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT; + Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT; + Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT; + Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT; + Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PTI_SHIFT)) >> MM_PTI_SHIFT; + + /* Check page map level */ + if(PageMap->PageMapLevel == 5) + { + /* Five level Page Map */ + Pml5 = PageMap->PtePointer; + + /* Get PML4 */ + Status = GetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory mapping failure */ + return Status; + } + } + else + { + /* Four level Page Map */ + Pml4 = PageMap->PtePointer; + } + + /* Get PML3 */ + Status = GetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory mapping failure */ + return Status; + } + + /* Get PML 2 */ + Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory mapping failure */ + return Status; + } + + /* Get PML1 */ + Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory mapping failure */ + return Status; + } + + /* Set paging entry settings */ + PmlTable = (PHARDWARE_PTE)Pml1; + RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE)); + PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber; + PmlTable[Pml1Entry].Valid = 1; + PmlTable[Pml1Entry].Writable = 1; + + /* Take next virtual address and PFN */ + VirtualAddress += EFI_PAGE_SIZE; + PageFrameNumber++; + + /* Decrease number of pages left */ + NumberOfPages--; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * Creates a recursive self mapping for all PML levels. * @@ -335,8 +335,8 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress) +Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PHARDWARE_PTE PmlBase; ULONGLONG PmlIndex; diff --git a/xtldr/arch/i686/memory.cc b/xtldr/arch/i686/memory.cc index c7e6c3c..edcf75b 100644 --- a/xtldr/arch/i686/memory.cc +++ b/xtldr/arch/i686/memory.cc @@ -22,8 +22,8 @@ */ XTCDECL EFI_STATUS -BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress) +Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; EFI_PHYSICAL_ADDRESS Address, DirectoryAddress; @@ -36,7 +36,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, if(PageMap->PageMapLevel == 3) { /* Allocate a page for the 3-level page map structure (PAE enabled) */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failed, cannot proceed with page map creation */ @@ -48,7 +48,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); /* Allocate 4 pages for the Page Directories (PDs) */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 4, &DirectoryAddress); + Status = AllocatePages(AllocateAnyPages, 4, &DirectoryAddress); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failed, cannot proceed with page map creation */ @@ -70,7 +70,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, else { /* Allocate a page for the 2-level page map structure (PAE disabled) */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failed, cannot proceed with page map creation */ @@ -83,7 +83,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Add page mapping itself to memory mapping */ - Status = BlpSelfMapPml(PageMap, SelfMapAddress); + Status = SelfMapPml(PageMap, SelfMapAddress); if(Status != STATUS_EFI_SUCCESS) { /* PML mapping failed */ @@ -91,8 +91,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Map the trampoline code area */ - Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, - 1, LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, + 1, LoaderFirmwareTemporary); if(Status != STATUS_EFI_SUCCESS) { /* Mapping trampoline code failed */ @@ -100,7 +100,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Get list of XTLDR modules */ - ModulesList = BlGetModulesList(); + ModulesList = Protocol::GetModulesList(); ModulesListEntry = ModulesList->Flink; while(ModulesListEntry != ModulesList) { @@ -108,8 +108,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); /* Map module code */ - Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, - EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, + EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); /* Check if mapping succeeded */ if(Status != STATUS_EFI_SUCCESS) @@ -126,8 +126,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, if(BlpStatus.LoaderBase && BlpStatus.LoaderSize) { /* Map boot loader code as well */ - Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, - EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, + EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); if(Status != STATUS_EFI_SUCCESS) { /* Mapping boot loader code failed */ @@ -141,7 +141,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Iterate through and map all the mappings*/ - BlDebugPrint(L"Mapping and dumping EFI memory:\n"); + Debug::Print(L"Mapping and dumping EFI memory:\n"); ListEntry = PageMap->MemoryMap.Flink; while(ListEntry != &PageMap->MemoryMap) { @@ -152,12 +152,12 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, if(Mapping->VirtualAddress) { /* Dump memory mapping */ - BlDebugPrint(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType, + Debug::Print(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType, Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); /* Map memory */ - Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, - (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); + Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, + (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); if(Status != STATUS_EFI_SUCCESS) { /* Memory mapping failed */ @@ -173,116 +173,6 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, return STATUS_EFI_SUCCESS; } -/** - * Does the actual virtual memory mapping. - * - * @param PageMap - * Supplies a pointer to the page mapping structure. - * - * @param VirtualAddress - * Supplies a virtual address of the mapping. - * - * @param PhysicalAddress - * Supplies a physical address of the mapping. - * - * @param NumberOfPages - * Supplies a number of the pages of the mapping. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR VirtualAddress, - IN ULONG_PTR PhysicalAddress, - IN ULONG NumberOfPages) -{ - SIZE_T PageFrameNumber; - PVOID Pml1, Pml2, Pml3; - SIZE_T Pml1Entry, Pml2Entry, Pml3Entry; - PHARDWARE_LEGACY_PTE LegacyPmlTable; - PHARDWARE_MODERN_PTE PmlTable; - EFI_STATUS Status; - - /* Set the Page Frame Number (PFN) */ - PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; - - /* Map all requested pages */ - while(NumberOfPages > 0) - { - /* Check the paging mode to use the correct page table structure */ - if(PageMap->PageMapLevel == 3) - { - /* Calculate the indices for PAE page tables */ - Pml3Entry = (VirtualAddress >> 30) & 0x3; - Pml2Entry = (VirtualAddress >> 21) & 0x1FF; - Pml1Entry = (VirtualAddress >> 12) & 0x1FF; - - /* Get Page Directory Pointer Table (PML3) */ - Pml3 = PageMap->PtePointer; - - /* Get Page Directory (PML2) */ - Status = BlpGetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get the Page Table, abort mapping */ - return Status; - } - - /* Get Page Table (PML1) */ - Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get the Page Table, abort mapping */ - return Status; - } - - /* Set the 64-bit PTE entry */ - PmlTable = (PHARDWARE_MODERN_PTE)Pml1; - RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE)); - PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber; - PmlTable[Pml1Entry].Valid = 1; - PmlTable[Pml1Entry].Writable = 1; - } - else - { - /* Calculate the indices for non-PAE page tables */ - Pml2Entry = (VirtualAddress >> 22) & 0x3FF; - Pml1Entry = (VirtualAddress >> 12) & 0x3FF; - - /* Get Page Directory (PML2) */ - Pml2 = PageMap->PtePointer; - - /* Get Page Table (PML1) */ - Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get the Page Table, abort mapping */ - return Status; - } - - /* Set the 32-bit PTE entry */ - LegacyPmlTable = (PHARDWARE_LEGACY_PTE)Pml1; - RTL::Memory::ZeroMemory(&LegacyPmlTable[Pml1Entry], sizeof(HARDWARE_LEGACY_PTE)); - LegacyPmlTable[Pml1Entry].PageFrameNumber = (UINT32)PageFrameNumber; - LegacyPmlTable[Pml1Entry].Valid = 1; - LegacyPmlTable[Pml1Entry].Writable = 1; - } - - /* Take next virtual address and PFN */ - VirtualAddress += EFI_PAGE_SIZE; - PageFrameNumber++; - - /* Decrease number of pages left */ - NumberOfPages--; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - /** * Returns next level of the Page Table. * @@ -304,10 +194,10 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID PageTable, - IN SIZE_T Entry, - OUT PVOID *NextPageTable) +Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PageTable, + IN SIZE_T Entry, + OUT PVOID *NextPageTable) { EFI_PHYSICAL_ADDRESS Address; ULONGLONG PmlPointer = 0; @@ -349,7 +239,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, else { /* Allocate pages for new PML entry */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -357,7 +247,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, } /* Add new memory mapping */ - Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); + Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); if(Status != STATUS_EFI_SUCCESS) { /* Memory mapping failure */ @@ -396,6 +286,116 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, return STATUS_EFI_SUCCESS; } +/** + * Does the actual virtual memory mapping. + * + * @param PageMap + * Supplies a pointer to the page mapping structure. + * + * @param VirtualAddress + * Supplies a virtual address of the mapping. + * + * @param PhysicalAddress + * Supplies a physical address of the mapping. + * + * @param NumberOfPages + * Supplies a number of the pages of the mapping. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR VirtualAddress, + IN ULONG_PTR PhysicalAddress, + IN ULONG NumberOfPages) +{ + SIZE_T PageFrameNumber; + PVOID Pml1, Pml2, Pml3; + SIZE_T Pml1Entry, Pml2Entry, Pml3Entry; + PHARDWARE_LEGACY_PTE LegacyPmlTable; + PHARDWARE_MODERN_PTE PmlTable; + EFI_STATUS Status; + + /* Set the Page Frame Number (PFN) */ + PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; + + /* Map all requested pages */ + while(NumberOfPages > 0) + { + /* Check the paging mode to use the correct page table structure */ + if(PageMap->PageMapLevel == 3) + { + /* Calculate the indices for PAE page tables */ + Pml3Entry = (VirtualAddress >> 30) & 0x3; + Pml2Entry = (VirtualAddress >> 21) & 0x1FF; + Pml1Entry = (VirtualAddress >> 12) & 0x1FF; + + /* Get Page Directory Pointer Table (PML3) */ + Pml3 = PageMap->PtePointer; + + /* Get Page Directory (PML2) */ + Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get the Page Table, abort mapping */ + return Status; + } + + /* Get Page Table (PML1) */ + Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get the Page Table, abort mapping */ + return Status; + } + + /* Set the 64-bit PTE entry */ + PmlTable = (PHARDWARE_MODERN_PTE)Pml1; + RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE)); + PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber; + PmlTable[Pml1Entry].Valid = 1; + PmlTable[Pml1Entry].Writable = 1; + } + else + { + /* Calculate the indices for non-PAE page tables */ + Pml2Entry = (VirtualAddress >> 22) & 0x3FF; + Pml1Entry = (VirtualAddress >> 12) & 0x3FF; + + /* Get Page Directory (PML2) */ + Pml2 = PageMap->PtePointer; + + /* Get Page Table (PML1) */ + Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get the Page Table, abort mapping */ + return Status; + } + + /* Set the 32-bit PTE entry */ + LegacyPmlTable = (PHARDWARE_LEGACY_PTE)Pml1; + RTL::Memory::ZeroMemory(&LegacyPmlTable[Pml1Entry], sizeof(HARDWARE_LEGACY_PTE)); + LegacyPmlTable[Pml1Entry].PageFrameNumber = (UINT32)PageFrameNumber; + LegacyPmlTable[Pml1Entry].Valid = 1; + LegacyPmlTable[Pml1Entry].Writable = 1; + } + + /* Take next virtual address and PFN */ + VirtualAddress += EFI_PAGE_SIZE; + PageFrameNumber++; + + /* Decrease number of pages left */ + NumberOfPages--; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * Creates a recursive self mapping for all PML levels. * @@ -411,8 +411,8 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress) +Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PHARDWARE_LEGACY_PTE LegacyPml; PHARDWARE_MODERN_PTE Pml; diff --git a/xtldr/bootutil.cc b/xtldr/bootutil.cc index 77e8955..e29ed12 100644 --- a/xtldr/bootutil.cc +++ b/xtldr/bootutil.cc @@ -24,8 +24,8 @@ */ XTCDECL BOOLEAN -BlGetBooleanParameter(IN PCWSTR Parameters, - IN PCWSTR Needle) +BootUtils::GetBooleanParameter(IN PCWSTR Parameters, + IN PCWSTR Needle) { PCWSTR CurrentPosition, TokenEnd, TokenStart; SIZE_T NeedleLength, TokenLength; diff --git a/xtldr/config.cc b/xtldr/config.cc index 75bc1cb..e5bfdaa 100644 --- a/xtldr/config.cc +++ b/xtldr/config.cc @@ -10,6 +10,39 @@ #include +/** + * Returns a boolean value of the specified configuration key. + * + * @param ConfigName + * Specifies the configuration key to return its boolean representation. + * + * @return This routine returns a boolean representation of the configuration value. + * + * @since XT 1.0 + */ +XTCDECL +BOOLEAN +Configuration::GetBooleanValue(IN PCWSTR ConfigName) +{ + PWCHAR Value; + + /* Get config value */ + GetValue(ConfigName, &Value); + + /* Check if option is enabled */ + if(RTL::WideString::CompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 || + RTL::WideString::CompareWideStringInsensitive(Value, L"ON", 0) == 0 || + RTL::WideString::CompareWideStringInsensitive(Value, L"TRUE", 0) == 0 || + RTL::WideString::CompareWideStringInsensitive(Value, L"YES", 0) == 0) + { + /* This option is enabled */ + return TRUE; + } + + /* Return FALSE by default */ + return FALSE; +} + /** * @brief Retrieves the value of a specific OS boot option from a list. * @@ -28,9 +61,9 @@ */ XTCDECL EFI_STATUS -BlGetBootOptionValue(IN PLIST_ENTRY Options, - IN PCWSTR OptionName, - OUT PWCHAR *OptionValue) +Configuration::GetBootOptionValue(IN PLIST_ENTRY Options, + IN PCWSTR OptionName, + OUT PWCHAR *OptionValue) { PXTBL_CONFIG_ENTRY ConfigEntry; PLIST_ENTRY ConfigList; @@ -57,11 +90,11 @@ BlGetBootOptionValue(IN PLIST_ENTRY Options, ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0); /* Allocate memory for the output value string */ - Status = BlAllocateMemoryPool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)OptionValue); + Status = Memory::AllocatePool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)OptionValue); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); *OptionValue = NULLPTR; return Status; } @@ -83,36 +116,36 @@ BlGetBootOptionValue(IN PLIST_ENTRY Options, } /** - * Returns a boolean value of the specified configuration key. + * Retrieves the list of user-editable boot options. * - * @param ConfigName - * Specifies the configuration key to return its boolean representation. + * @param OptionsArray + * A pointer to a variable that will receive the pointer to the array of editable option names. * - * @return This routine returns a boolean representation of the configuration value. + * @param OptionsCount + * A pointer to a variable that will be updated with the number of elements in the OptionsArray. + * + * @return This routine does not return any value. * * @since XT 1.0 */ XTCDECL -BOOLEAN -BlGetConfigBooleanValue(IN PCWSTR ConfigName) +VOID +Configuration::GetEditableOptions(OUT PCWSTR **OptionsArray, + OUT PULONG OptionsCount) { - PWCHAR Value; + ULONG Count = 0; - /* Get config value */ - BlGetConfigValue(ConfigName, &Value); + /* Return a pointer to the global array of editable options */ + *OptionsArray = BlpEditableConfigOptions; - /* Check if option is enabled */ - if(RTL::WideString::CompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 || - RTL::WideString::CompareWideStringInsensitive(Value, L"ON", 0) == 0 || - RTL::WideString::CompareWideStringInsensitive(Value, L"TRUE", 0) == 0 || - RTL::WideString::CompareWideStringInsensitive(Value, L"YES", 0) == 0) + /* Calculate the number of elements in the array */ + while(BlpEditableConfigOptions[Count]) { - /* This option is enabled */ - return TRUE; + Count++; } - /* Return FALSE by default */ - return FALSE; + /* Return the number of elements */ + *OptionsCount = Count; } /** @@ -127,8 +160,8 @@ BlGetConfigBooleanValue(IN PCWSTR ConfigName) */ XTCDECL EFI_STATUS -BlGetConfigValue(IN PCWSTR ConfigName, - OUT PWCHAR *ConfigValue) +Configuration::GetValue(IN PCWSTR ConfigName, + OUT PWCHAR *ConfigValue) { PXTBL_CONFIG_ENTRY ConfigEntry; PLIST_ENTRY ConfigListEntry; @@ -156,11 +189,11 @@ BlGetConfigValue(IN PCWSTR ConfigName, ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0); /* Allocate memory for value */ - Status = BlAllocateMemoryPool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)&Value); + Status = Memory::AllocatePool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)&Value); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, return NULLPTR */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); return Status; } @@ -179,226 +212,6 @@ BlGetConfigValue(IN PCWSTR ConfigName, return STATUS_EFI_NOT_FOUND; } -/** - * Retrieves the list of user-editable boot options. - * - * @param OptionsArray - * A pointer to a variable that will receive the pointer to the array of editable option names. - * - * @param OptionsCount - * A pointer to a variable that will be updated with the number of elements in the OptionsArray. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlGetEditableOptions(OUT PCWSTR **OptionsArray, - OUT PULONG OptionsCount) -{ - ULONG Count = 0; - - /* Return a pointer to the global array of editable options */ - *OptionsArray = BlpEditableConfigOptions; - - /* Calculate the number of elements in the array */ - while(BlpEditableConfigOptions[Count]) - { - Count++; - } - - /* Return the number of elements */ - *OptionsCount = Count; -} - -/** - * Sets the value of a specific OS boot option in a list, or adds it if it doesn't exist. - * - * @param Options - * A pointer to the head of a list of XTBL_CONFIG_ENTRY structures. - * - * @param OptionName - * A pointer to a wide string that contains the name of the boot option to set. - * - * @param OptionValue - * A pointer to a wide string that contains the new value for the boot option. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlSetBootOptionValue(IN PLIST_ENTRY Options, - IN PCWSTR OptionName, - IN PCWSTR OptionValue) -{ - PXTBL_CONFIG_ENTRY ConfigEntry; - PLIST_ENTRY ConfigList; - ULONG Length; - EFI_STATUS Status; - - /* Get the length of the option name we are looking for */ - Length = RTL::WideString::WideStringLength(OptionName, 0); - - /* Start iterating from the first entry in the options list */ - ConfigList = Options->Flink; - while(ConfigList != Options) - { - /* Get the container record for the current config entry */ - ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink); - - /* Compare the current entry's name with the requested option name */ - if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, OptionName, Length) == 0) - { - /* Found the option, get its length */ - Length = RTL::WideString::WideStringLength(OptionValue, 0); - - /* Reallocate memory for the new value */ - Status = BlFreeMemoryPool(ConfigEntry->Value); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to free memory, return status code */ - return Status; - } - - /* Allocate new memory for the updated value */ - Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); - return Status; - } - - /* Copy the value and NULL-terminate the new string */ - RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR)); - ConfigEntry->Value[Length] = L'\0'; - return STATUS_EFI_SUCCESS; - } - - /* Move to the next entry in the list */ - ConfigList = ConfigList->Flink; - } - - /* Option not found, allocate memory for the new one */ - Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID *)&ConfigEntry); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); - return Status; - } - - /* Allocate memory for the option name */ - Length = RTL::WideString::WideStringLength(OptionName, 0); - Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Name); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); - BlFreeMemoryPool(ConfigEntry); - return Status; - } - - /* Copy the option name and NULL-terminate the new string */ - RTL::Memory::CopyMemory(ConfigEntry->Name, OptionName, Length * sizeof(WCHAR)); - ConfigEntry->Name[Length] = L'\0'; - - /* Allocate memory for the option value */ - Length = RTL::WideString::WideStringLength(OptionValue, 0); - Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); - BlFreeMemoryPool(ConfigEntry->Name); - BlFreeMemoryPool(ConfigEntry); - return Status; - } - - /* Copy the value and NULL-terminate the new string */ - RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR)); - ConfigEntry->Value[Length] = L'\0'; - - /* Insert the new config entry at the end of the options list */ - RTL::LinkedList::InsertTailList(Options, &ConfigEntry->Flink); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Updates existing configuration value. - * - * @param ConfigName - * Specifies the configuration key to update. - * - * @param ConfigValue - * Specifies the new configuration value. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlSetConfigValue(IN PCWSTR ConfigName, - IN PCWSTR ConfigValue) -{ - PXTBL_CONFIG_ENTRY ConfigEntry; - PLIST_ENTRY ConfigListEntry; - EFI_STATUS Status; - SIZE_T Length; - - /* Get config entry name length */ - Length = RTL::WideString::WideStringLength(ConfigName, 0); - - /* Iterate through config entries */ - ConfigListEntry = BlpConfig.Flink; - while(ConfigListEntry != &BlpConfig) - { - /* Get config entry */ - ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); - - /* Check if requested configuration found */ - if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) - { - /* Check new config value length */ - Length = RTL::WideString::WideStringLength(ConfigValue, 0); - - /* Reallocate memory for new config value */ - Status = BlFreeMemoryPool(ConfigEntry->Value); - if(Status == STATUS_EFI_SUCCESS) - { - /* Successfully freed memory, allocate a new pool */ - Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); - } - - /* Check memory reallocation status */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to reallocate memory */ - return Status; - } - - /* Update config value */ - RTL::Memory::CopyMemory(ConfigEntry->Value, ConfigValue, Length * sizeof(WCHAR)); - ConfigEntry->Value[Length] = L'\0'; - - /* Return success */ - return STATUS_EFI_SUCCESS; - } - - /* Move to the next config entry */ - ConfigListEntry = ConfigListEntry->Flink; - } - - /* Config entry not found */ - return STATUS_EFI_NOT_FOUND; -} - /** * Loads and parses XTLDR configuration file. * @@ -408,7 +221,7 @@ BlSetConfigValue(IN PCWSTR ConfigName, */ XTCDECL EFI_STATUS -BlpLoadConfiguration() +Configuration::LoadConfiguration() { PLIST_ENTRY SectionListEntry; EFI_STATUS Status; @@ -418,27 +231,27 @@ BlpLoadConfiguration() RTL::LinkedList::InitializeListHead(&BlpConfigSections); /* Read data from configuration file */ - Status = BlpReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); + Status = ReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); if(Status != STATUS_EFI_SUCCESS) { /* Failed to read config file, try with architecture specific directory */ - Status = BlpReadConfigFile(XTBL_ARCH_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); + Status = ReadConfigFile(XTBL_ARCH_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); } /* Check if configuration was read successfully */ if(Status != STATUS_EFI_SUCCESS) { /* Failed to load configuration */ - BlDebugPrint(L"Failed to load FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); + Debug::Print(L"Failed to load FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); return Status; } /* Parse configuration data */ - Status = BlpParseConfigFile(ConfigData, &BlpConfigSections); + Status = ParseConfigFile(ConfigData, &BlpConfigSections); if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse configuration */ - BlDebugPrint(L"Failed to parse FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); + Debug::Print(L"Failed to parse FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); return Status; } @@ -453,7 +266,7 @@ BlpLoadConfiguration() if(RTL::WideString::CompareWideStringInsensitive(Section->SectionName, L"XTLDR", 5) == 0) { /* Update global configuration */ - BlpUpdateConfiguration(&Section->Options); + UpdateConfiguration(&Section->Options); /* Remove XTLDR section from the list */ RTL::LinkedList::RemoveEntryList(SectionListEntry); @@ -480,7 +293,7 @@ BlpLoadConfiguration() */ XTCDECL EFI_STATUS -BlpParseCommandLine(VOID) +Configuration::ParseCommandLine(VOID) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; @@ -546,15 +359,15 @@ BlpParseCommandLine(VOID) } /* Allocate memory for new option */ - Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); + Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); if(Status == STATUS_EFI_SUCCESS) { /* Allocate more memory for option name */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); + Status = Memory::AllocatePool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); if(Status == STATUS_EFI_SUCCESS) { /* Allocate even more memory for option value */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); + Status = Memory::AllocatePool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); } } if(Status != STATUS_EFI_SUCCESS) @@ -577,7 +390,7 @@ BlpParseCommandLine(VOID) } /* Update global configuration */ - BlpUpdateConfiguration(&Config); + UpdateConfiguration(&Config); } } @@ -600,8 +413,8 @@ BlpParseCommandLine(VOID) */ XTCDECL EFI_STATUS -BlpParseConfigFile(IN CONST PCHAR RawConfig, - OUT PLIST_ENTRY Configuration) +Configuration::ParseConfigFile(IN CONST PCHAR RawConfig, + OUT PLIST_ENTRY Configuration) { SIZE_T SectionLength, KeyLength, ValueLength; PCHAR InputData, Key, SectionName, Value; @@ -667,11 +480,11 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, SectionLength = RTL::String::StringLength(SectionName, 0); /* Allocate memory for new section */ - Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_SECTION), (PVOID*)&Section); + Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_SECTION), (PVOID*)&Section); if(Status == STATUS_EFI_SUCCESS) { /* Allocate more memory for section name */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName); + Status = Memory::AllocatePool(sizeof(WCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName); } if(Status != STATUS_EFI_SUCCESS) { @@ -740,15 +553,15 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, ValueLength = RTL::String::StringLength(Value, 0); /* Allocate memory for new option */ - Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); + Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); if(Status == STATUS_EFI_SUCCESS) { /* Allocate more memory for option name */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); + Status = Memory::AllocatePool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); if(Status == STATUS_EFI_SUCCESS) { /* Allocate even more memory for option value */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); + Status = Memory::AllocatePool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); } } if(Status != STATUS_EFI_SUCCESS) @@ -802,9 +615,9 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, */ XTCDECL EFI_STATUS -BlpReadConfigFile(IN PCWSTR ConfigDirectory, - IN PCWSTR ConfigFile, - OUT PCHAR *ConfigData) +Configuration::ReadConfigFile(IN PCWSTR ConfigDirectory, + IN PCWSTR ConfigFile, + OUT PCHAR *ConfigData) { PEFI_FILE_HANDLE DirHandle, FsHandle; EFI_HANDLE DiskHandle; @@ -812,7 +625,7 @@ BlpReadConfigFile(IN PCWSTR ConfigDirectory, SIZE_T FileSize; /* Open EFI volume */ - Status = BlOpenVolume(NULLPTR, &DiskHandle, &FsHandle); + Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle); if(Status != STATUS_EFI_SUCCESS) { /* Failed to open a volume */ @@ -827,21 +640,209 @@ BlpReadConfigFile(IN PCWSTR ConfigDirectory, if(Status != STATUS_EFI_SUCCESS) { /* Failed to open directory */ - BlCloseVolume(&DiskHandle); + Volume::CloseVolume(&DiskHandle); return Status; } /* Read configuration file and close directory */ - Status = BlReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize); + Status = Volume::ReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize); DirHandle->Close(DirHandle); /* Close EFI volume */ - BlCloseVolume(&DiskHandle); + Volume::CloseVolume(&DiskHandle); /* Return read status */ return Status; } + +/** + * Sets the value of a specific OS boot option in a list, or adds it if it doesn't exist. + * + * @param Options + * A pointer to the head of a list of XTBL_CONFIG_ENTRY structures. + * + * @param OptionName + * A pointer to a wide string that contains the name of the boot option to set. + * + * @param OptionValue + * A pointer to a wide string that contains the new value for the boot option. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Configuration::SetBootOptionValue(IN PLIST_ENTRY Options, + IN PCWSTR OptionName, + IN PCWSTR OptionValue) +{ + PXTBL_CONFIG_ENTRY ConfigEntry; + PLIST_ENTRY ConfigList; + ULONG Length; + EFI_STATUS Status; + + /* Get the length of the option name we are looking for */ + Length = RTL::WideString::WideStringLength(OptionName, 0); + + /* Start iterating from the first entry in the options list */ + ConfigList = Options->Flink; + while(ConfigList != Options) + { + /* Get the container record for the current config entry */ + ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink); + + /* Compare the current entry's name with the requested option name */ + if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, OptionName, Length) == 0) + { + /* Found the option, get its length */ + Length = RTL::WideString::WideStringLength(OptionValue, 0); + + /* Reallocate memory for the new value */ + Status = Memory::FreePool(ConfigEntry->Value); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to free memory, return status code */ + return Status; + } + + /* Allocate new memory for the updated value */ + Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print debug message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); + return Status; + } + + /* Copy the value and NULL-terminate the new string */ + RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR)); + ConfigEntry->Value[Length] = L'\0'; + return STATUS_EFI_SUCCESS; + } + + /* Move to the next entry in the list */ + ConfigList = ConfigList->Flink; + } + + /* Option not found, allocate memory for the new one */ + Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID *)&ConfigEntry); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print debug message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); + return Status; + } + + /* Allocate memory for the option name */ + Length = RTL::WideString::WideStringLength(OptionName, 0); + Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Name); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print debug message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); + Memory::FreePool(ConfigEntry); + return Status; + } + + /* Copy the option name and NULL-terminate the new string */ + RTL::Memory::CopyMemory(ConfigEntry->Name, OptionName, Length * sizeof(WCHAR)); + ConfigEntry->Name[Length] = L'\0'; + + /* Allocate memory for the option value */ + Length = RTL::WideString::WideStringLength(OptionValue, 0); + Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print debug message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); + Memory::FreePool(ConfigEntry->Name); + Memory::FreePool(ConfigEntry); + return Status; + } + + /* Copy the value and NULL-terminate the new string */ + RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR)); + ConfigEntry->Value[Length] = L'\0'; + + /* Insert the new config entry at the end of the options list */ + RTL::LinkedList::InsertTailList(Options, &ConfigEntry->Flink); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Updates existing configuration value. + * + * @param ConfigName + * Specifies the configuration key to update. + * + * @param ConfigValue + * Specifies the new configuration value. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Configuration::SetValue(IN PCWSTR ConfigName, + IN PCWSTR ConfigValue) +{ + PXTBL_CONFIG_ENTRY ConfigEntry; + PLIST_ENTRY ConfigListEntry; + EFI_STATUS Status; + SIZE_T Length; + + /* Get config entry name length */ + Length = RTL::WideString::WideStringLength(ConfigName, 0); + + /* Iterate through config entries */ + ConfigListEntry = BlpConfig.Flink; + while(ConfigListEntry != &BlpConfig) + { + /* Get config entry */ + ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); + + /* Check if requested configuration found */ + if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) + { + /* Check new config value length */ + Length = RTL::WideString::WideStringLength(ConfigValue, 0); + + /* Reallocate memory for new config value */ + Status = Memory::FreePool(ConfigEntry->Value); + if(Status == STATUS_EFI_SUCCESS) + { + /* Successfully freed memory, allocate a new pool */ + Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); + } + + /* Check memory reallocation status */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to reallocate memory */ + return Status; + } + + /* Update config value */ + RTL::Memory::CopyMemory(ConfigEntry->Value, ConfigValue, Length * sizeof(WCHAR)); + ConfigEntry->Value[Length] = L'\0'; + + /* Return success */ + return STATUS_EFI_SUCCESS; + } + + /* Move to the next config entry */ + ConfigListEntry = ConfigListEntry->Flink; + } + + /* Config entry not found */ + return STATUS_EFI_NOT_FOUND; +} + /** * Adds new XTLDR configuration entries to the global configuration list. Existing entries are not overwritten. * @@ -854,7 +855,7 @@ BlpReadConfigFile(IN PCWSTR ConfigDirectory, */ XTCDECL VOID -BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) +Configuration::UpdateConfiguration(IN PLIST_ENTRY NewConfig) { PXTBL_CONFIG_ENTRY ConfigEntry; PWCHAR ConfigValue; @@ -871,7 +872,7 @@ BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) NextListEntry = ConfigListEntry->Flink; /* Make sure config entry does not exist yet */ - BlGetConfigValue(ConfigEntry->Name, &ConfigValue); + GetValue(ConfigEntry->Name, &ConfigValue); if(ConfigValue == NULLPTR) { /* Remove new config entry from input list and put it into global config list */ diff --git a/xtldr/console.cc b/xtldr/console.cc index 9e14f2a..386ce3a 100644 --- a/xtldr/console.cc +++ b/xtldr/console.cc @@ -21,19 +21,19 @@ */ XTCDECL VOID -BlClearConsoleLine(IN ULONGLONG LineNo) +Console::ClearLine(IN ULONGLONG LineNo) { UINT_PTR Index, ResX, ResY; /* Query console mode */ - BlQueryConsoleMode(&ResX, &ResY); + QueryMode(&ResX, &ResY); /* Set cursor position and clear line */ - BlSetCursorPosition(0, LineNo); + SetCursorPosition(0, LineNo); for(Index = 0; Index < ResX; Index++) { /* Clear line */ - BlConsoleWrite(L" "); + Write(L" "); } } @@ -46,7 +46,7 @@ BlClearConsoleLine(IN ULONGLONG LineNo) */ XTCDECL VOID -BlClearConsoleScreen() +Console::ClearScreen() { /* Clear screen */ EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); @@ -61,7 +61,7 @@ BlClearConsoleScreen() */ XTCDECL VOID -BlDisableConsoleCursor() +Console::DisableCursor() { EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE); } @@ -75,11 +75,41 @@ BlDisableConsoleCursor() */ XTCDECL VOID -BlEnableConsoleCursor() +Console::EnableCursor() { EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); } +/** + * This routine initializes the EFI console. + * + * @return This routine returns status code. + * + * @since XT 1.0 + */ +XTCDECL +VOID +Console::InitializeConsole() +{ + /* Clear console buffers */ + EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); + EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); + EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); + + /* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might + * set different mode that do not fit on the screen, causing a text to be displayed offscreen */ + if(EfiSystemTable->ConOut->Mode->Mode != 0) + { + /* Set console mode to 0, which is standard, 80x25 text mode */ + SetMode(0); + } + + /* Clear screen and enable cursor */ + SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + ClearScreen(); + EnableCursor(); +} + /** * This routine formats the input string and prints it out to the stdout and serial console. * @@ -95,15 +125,15 @@ BlEnableConsoleCursor() */ XTCDECL VOID -BlConsolePrint(IN PCWSTR Format, +Console::Print(IN PCWSTR Format, IN ...) { RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; VA_LIST Arguments; /* Initialise the print contexts */ - ConsolePrintContext.WriteWideCharacter = BlpConsolePutChar; - SerialPrintContext.WriteWideCharacter = BlpDebugPutChar; + ConsolePrintContext.WriteWideCharacter = PutChar; + SerialPrintContext.WriteWideCharacter = Debug::PutChar; /* Initialise the va_list */ VA_START(Arguments, Format); @@ -127,50 +157,35 @@ BlConsolePrint(IN PCWSTR Format, } /** - * Displays the string on the device at the current cursor location. + * Writes a character to the default EFI console. * - * @param String - * The string to be displayed. + * @param Character + * The integer promotion of the character to be written. * - * @return This routine does not return any value. + * @return This routine returns a status code. * * @since XT 1.0 */ XTCDECL -VOID -BlConsoleWrite(IN PCWSTR String) +XTSTATUS +Console::PutChar(IN WCHAR Character) { - EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, (PWSTR)String); -} + WCHAR Buffer[2]; -/** - * This routine initializes the EFI console. - * - * @return This routine returns status code. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlInitializeConsole() -{ - /* Clear console buffers */ - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE); - EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE); - EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE); - - /* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might - * set different mode that do not fit on the screen, causing a text to be displayed offscreen */ - if(EfiSystemTable->ConOut->Mode->Mode != 0) + /* Check if character is a newline ('\n') */ + if(Character == L'\n') { - /* Set console mode to 0, which is standard, 80x25 text mode */ - BlSetConsoleMode(0); + /* Print carriage return ('\r') as well */ + PutChar(L'\r'); } - /* Clear screen and enable cursor */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); - BlEnableConsoleCursor(); + /* Write character to the screen console */ + Buffer[0] = Character; + Buffer[1] = 0; + EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); + + /* Return success */ + return STATUS_SUCCESS; } /** @@ -188,7 +203,7 @@ BlInitializeConsole() */ XTCDECL VOID -BlQueryConsoleMode(OUT PUINT_PTR ResX, +Console::QueryMode(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY) { EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY); @@ -206,7 +221,7 @@ BlQueryConsoleMode(OUT PUINT_PTR ResX, */ XTCDECL VOID -BlReadKeyStroke(OUT PEFI_INPUT_KEY Key) +Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key) { EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key); } @@ -220,7 +235,7 @@ BlReadKeyStroke(OUT PEFI_INPUT_KEY Key) */ XTCDECL VOID -BlResetConsoleInputBuffer() +Console::ResetInputBuffer() { EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); } @@ -237,28 +252,11 @@ BlResetConsoleInputBuffer() */ XTCDECL VOID -BlSetConsoleAttributes(IN ULONGLONG Attributes) +Console::SetAttributes(IN ULONGLONG Attributes) { EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes); } -/** - * Sets the output console device to the requested mode. - * - * @param Mode - * Supplies a text mode number to set. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlSetConsoleMode(IN ULONGLONG Mode) -{ - return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode); -} - /** * Sets new coordinates of the console cursor position. * @@ -274,40 +272,42 @@ BlSetConsoleMode(IN ULONGLONG Mode) */ XTCDECL VOID -BlSetCursorPosition(IN ULONGLONG PosX, - IN ULONGLONG PosY) +Console::SetCursorPosition(IN ULONGLONG PosX, + IN ULONGLONG PosY) { EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY); } /** - * Writes a character to the default EFI console. + * Sets the output console device to the requested mode. * - * @param Character - * The integer promotion of the character to be written. + * @param Mode + * Supplies a text mode number to set. * * @return This routine returns a status code. * * @since XT 1.0 */ XTCDECL -XTSTATUS -BlpConsolePutChar(IN WCHAR Character) +EFI_STATUS +Console::SetMode(IN ULONGLONG Mode) { - WCHAR Buffer[2]; - - /* Check if character is a newline ('\n') */ - if(Character == L'\n') - { - /* Print carriage return ('\r') as well */ - BlpConsolePutChar(L'\r'); - } - - /* Write character to the screen console */ - Buffer[0] = Character; - Buffer[1] = 0; - EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); - - /* Return success */ - return STATUS_SUCCESS; + return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode); +} + +/** + * Displays the string on the device at the current cursor location. + * + * @param String + * The string to be displayed. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +Console::Write(IN PCWSTR String) +{ + EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, (PWSTR)String); } diff --git a/xtldr/debug.cc b/xtldr/debug.cc index db028f5..03e984b 100644 --- a/xtldr/debug.cc +++ b/xtldr/debug.cc @@ -10,75 +10,105 @@ /** - * This routine formats the input string and prints it out to the debug ports. - * - * @param Format - * The formatted string that is to be written to the output. - * - * @param ... - * Depending on the format string, this routine might expect a sequence of additional arguments. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlDebugPrint(IN PCWSTR Format, - IN ...) -{ - RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; - VA_LIST Arguments; - - /* Check if debugging enabled and if EFI serial port is fully initialized */ - if(DEBUG) - { - /* Initialize the print contexts */ - ConsolePrintContext.WriteWideCharacter = BlpConsolePutChar; - SerialPrintContext.WriteWideCharacter = BlpDebugPutChar; - - /* Initialise the va_list */ - VA_START(Arguments, Format); - - /* Check if serial debug port is enabled */ - if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT)) - { - /* Format and print the string to the serial console */ - RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments); - } - - /* Check if screen debug port is enabled and Boot Services are still available */ - if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE)) - { - /* Format and print the string to the screen */ - RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments); - } - - /* Clean up the va_list */ - VA_END(Arguments); - } -} - -/** - * Writes a character to the serial console. - * - * @param Character - * The integer promotion of the character to be written. + * Enables I/O space access to all serial controllers found on the PCI(E) root bridge. * * @return This routine returns a status code. * * @since XT 1.0 */ XTCDECL -XTSTATUS -BlpDebugPutChar(IN WCHAR Character) +EFI_STATUS +Debug::ActivateSerialIOController() { - WCHAR Buffer[2]; + EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; + PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev; + USHORT Bus, Device, Function, Command; + UINT_PTR Index, PciHandleSize; + PEFI_HANDLE PciHandle = NULLPTR; + PCI_COMMON_HEADER PciHeader; + EFI_STATUS Status; + ULONGLONG Address; - /* Write character to the serial console */ - Buffer[0] = Character; - Buffer[1] = 0; - return HL::ComPort::WriteComPort(&BlpStatus.SerialPort, Buffer[0]); + /* Allocate memory for single EFI_HANDLE, what should be enough in most cases */ + PciHandleSize = sizeof(EFI_HANDLE); + Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Get all instances of PciRootBridgeIo */ + Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR, &PciHandleSize, PciHandle); + if(Status == STATUS_EFI_BUFFER_TOO_SMALL) + { + /* Reallocate more memory as requested by UEFI */ + Memory::FreePool(PciHandle); + Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory reallocation failure */ + return Status; + } + + /* Second attempt to get instances of PciRootBridgeIo */ + Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR, &PciHandleSize, PciHandle); + } + + /* Make sure successfully obtained PciRootBridgeIo instances */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get PciRootBridgeIo instances */ + return Status; + } + + /* Enumerate all devices for each handle, which decides a segment and a bus number range */ + for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++) + { + /* Get inferface from the protocol */ + Status = EfiSystemTable->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get interface */ + return Status; + } + + /* Enumerate whole PCI bridge */ + for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++) + { + /* Enumerate all devices for each bus */ + for(Device = 0; Device < PCI_MAX_DEVICES; Device++) + { + /* Enumerate all functions for each devices */ + for(Function = 0; Function < PCI_MAX_FUNCTION; Function++) + { + /* Read configuration space */ + Address = ((ULONGLONG)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) + + (((UINT_PTR) Function) << 8) + ((UINT_PTR) 0))); + PciDev->Pci.Read(PciDev, EfiPciIoWidthUint32, Address, sizeof (PciHeader) / sizeof (UINT), &PciHeader); + + /* Check if device exists */ + if(PciHeader.VendorId == PCI_INVALID_VENDORID) + { + /* Skip non-existen device */ + continue; + } + + /* Check if device is serial controller or multiport serial controller */ + if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02)) + { + /* Enable I/O space access */ + Address |= 0x4; + Command = PCI_ENABLE_IO_SPACE; + Status = PciDev->Pci.Write(PciDev, EfiPciIoWidthUint16, Address, 1, &Command); + } + } + } + } + } + + /* Return SUCCESS */ + return STATUS_EFI_SUCCESS; } /** @@ -90,7 +120,7 @@ BlpDebugPutChar(IN WCHAR Character) */ XTCDECL EFI_STATUS -BlpInitializeDebugConsole() +Debug::InitializeDebugConsole() { ULONG PortAddress, PortNumber, BaudRate; PWCHAR DebugConfiguration, DebugPort, LastPort; @@ -102,7 +132,7 @@ BlpInitializeDebugConsole() BaudRate = 0; /* Get debug configuration */ - BlGetConfigValue(L"DEBUG", &DebugConfiguration); + Configuration::GetValue(L"DEBUG", &DebugConfiguration); /* Make sure any debug options are provided and debug console is not initialized yet */ if(DebugConfiguration && BlpStatus.DebugPort == 0) @@ -178,8 +208,8 @@ BlpInitializeDebugConsole() else { /* Unsupported debug port specified */ - BlConsolePrint(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort); - BlSleepExecution(3000); + Console::Print(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort); + EfiUtils::SleepExecution(3000); } /* Take next debug port */ @@ -190,7 +220,7 @@ BlpInitializeDebugConsole() if(BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) { /* Try to initialize COM port */ - Status = BlpInitializeSerialPort(PortNumber, PortAddress, BaudRate); + Status = InitializeSerialPort(PortNumber, PortAddress, BaudRate); if(Status != STATUS_EFI_SUCCESS) { /* Remove serial debug port, as COM port initialization failed and return */ @@ -222,9 +252,9 @@ BlpInitializeDebugConsole() */ XTCDECL EFI_STATUS -BlpInitializeSerialPort(IN ULONG PortNumber, - IN ULONG PortAddress, - IN ULONG BaudRate) +Debug::InitializeSerialPort(IN ULONG PortNumber, + IN ULONG PortAddress, + IN ULONG BaudRate) { EFI_STATUS EfiStatus; XTSTATUS Status; @@ -248,12 +278,12 @@ BlpInitializeSerialPort(IN ULONG PortNumber, /* Set custom port address based on the port number and print debug message */ PortAddress = BlComPortList[PortNumber - 1]; - BlConsolePrint(L"Initializing serial console at port COM%d\n", PortNumber); + Console::Print(L"Initializing serial console at port COM%d\n", PortNumber); } else { /* Custom port address supplied, print debug message */ - BlConsolePrint(L"Initializing serial console at COM port address: 0x%lX\n", PortAddress); + Console::Print(L"Initializing serial console at COM port address: 0x%lX\n", PortAddress); } /* Initialize COM port */ @@ -263,11 +293,11 @@ BlpInitializeSerialPort(IN ULONG PortNumber, if(Status == STATUS_NOT_FOUND && PortAddress) { /* This might be PCI(E) serial controller, try to activate I/O space access first */ - EfiStatus = BlpActivateSerialIOController(); + EfiStatus = ActivateSerialIOController(); if(EfiStatus == STATUS_EFI_SUCCESS) { /* Try to reinitialize COM port */ - BlConsolePrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n"); + Console::Print(L"Enabled I/O space access for all PCI(E) serial controllers found\n"); Status = HL::ComPort::InitializeComPort(&BlpStatus.SerialPort, (PUCHAR)UlongToPtr(PortAddress), BaudRate); } } @@ -282,3 +312,75 @@ BlpInitializeSerialPort(IN ULONG PortNumber, /* Return success */ return STATUS_EFI_SUCCESS; } + +/** + * This routine formats the input string and prints it out to the debug ports. + * + * @param Format + * The formatted string that is to be written to the output. + * + * @param ... + * Depending on the format string, this routine might expect a sequence of additional arguments. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +Debug::Print(IN PCWSTR Format, + IN ...) +{ + RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; + VA_LIST Arguments; + + /* Check if debugging enabled and if EFI serial port is fully initialized */ + if(DEBUG) + { + /* Initialize the print contexts */ + ConsolePrintContext.WriteWideCharacter = Console::PutChar; + SerialPrintContext.WriteWideCharacter = PutChar; + + /* Initialise the va_list */ + VA_START(Arguments, Format); + + /* Check if serial debug port is enabled */ + if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT)) + { + /* Format and print the string to the serial console */ + RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments); + } + + /* Check if screen debug port is enabled and Boot Services are still available */ + if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE)) + { + /* Format and print the string to the screen */ + RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments); + } + + /* Clean up the va_list */ + VA_END(Arguments); + } +} + +/** + * Writes a character to the serial console. + * + * @param Character + * The integer promotion of the character to be written. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +XTSTATUS +Debug::PutChar(IN WCHAR Character) +{ + WCHAR Buffer[2]; + + /* Write character to the serial console */ + Buffer[0] = Character; + Buffer[1] = 0; + return HL::ComPort::WriteComPort(&BlpStatus.SerialPort, Buffer[0]); +} diff --git a/xtldr/efiutils.cc b/xtldr/efiutils.cc index 3b6e641..296b864 100644 --- a/xtldr/efiutils.cc +++ b/xtldr/efiutils.cc @@ -18,7 +18,7 @@ */ XTCDECL EFI_STATUS -BlEnterFirmwareSetup() +EfiUtils::EnterFirmwareSetup() { EFI_GUID Guid = EFI_GLOBAL_VARIABLE_GUID; PULONGLONG SetupSupport = NULLPTR; @@ -26,27 +26,27 @@ BlEnterFirmwareSetup() EFI_STATUS Status; /* Check if booting into firmware interface is supported */ - Status = BlGetEfiVariable(&Guid, L"OsIndicationsSupported", (PVOID*)&SetupSupport); + Status = GetEfiVariable(&Guid, L"OsIndicationsSupported", (PVOID*)&SetupSupport); if(Status != STATUS_EFI_SUCCESS || !(*SetupSupport & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) { /* Reboot into firmware setup is not supported */ - BlDebugPrint(L"WARNING: Reboot into firmware setup interface not supported\n"); + Debug::Print(L"WARNING: Reboot into firmware setup interface not supported\n"); if(SetupSupport) { - BlFreeMemoryPool((PVOID)SetupSupport); + Memory::FreePool((PVOID)SetupSupport); } return STATUS_EFI_UNSUPPORTED; } - BlFreeMemoryPool((PVOID)SetupSupport); + Memory::FreePool((PVOID)SetupSupport); /* Get the value of OsIndications variable */ Indications = 0; - Status = BlGetEfiVariable(&Guid, L"OsIndications", (PVOID*)&Indications); + Status = GetEfiVariable(&Guid, L"OsIndications", (PVOID*)&Indications); /* Enable FW setup on next boot */ Indications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI; - Status = BlSetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications, sizeof(Indications)); + Status = SetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications, sizeof(Indications)); if(Status != STATUS_EFI_SUCCESS) { /* Failed to update OsIndications variable */ @@ -54,7 +54,7 @@ BlEnterFirmwareSetup() } /* Reboot into firmware setup */ - BlRebootSystem(); + RebootSystem(); /* Must not reach this point, just make the compiler happy */ return STATUS_EFI_SUCCESS; @@ -69,7 +69,7 @@ BlEnterFirmwareSetup() */ XTCDECL EFI_STATUS -BlExitBootServices() +EfiUtils::ExitBootServices() { PEFI_MEMORY_MAP MemoryMap; EFI_STATUS Status; @@ -79,11 +79,11 @@ BlExitBootServices() BlpStatus.BootServices = FALSE; /* Allocate buffer for EFI memory map */ - Status = BlAllocateMemoryPool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); + Status = Memory::AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); return Status; } @@ -95,7 +95,7 @@ BlExitBootServices() while(Counter > 0) { /* Get memory map each time as it can change between two calls */ - Status = BlGetMemoryMap(MemoryMap); + Status = Memory::GetMemoryMap(MemoryMap); if(Status != STATUS_EFI_SUCCESS) { /* Failed to get new memory map */ @@ -132,8 +132,8 @@ BlExitBootServices() */ XTCDECL EFI_STATUS -BlGetConfigurationTable(IN PEFI_GUID TableGuid, - OUT PVOID *Table) +EfiUtils::GetConfigurationTable(IN PEFI_GUID TableGuid, + OUT PVOID *Table) { SIZE_T Index; @@ -172,9 +172,9 @@ BlGetConfigurationTable(IN PEFI_GUID TableGuid, */ XTCDECL EFI_STATUS -BlGetEfiVariable(IN PEFI_GUID Vendor, - IN PCWSTR VariableName, - OUT PVOID *VariableValue) +EfiUtils::GetEfiVariable(IN PEFI_GUID Vendor, + IN PCWSTR VariableName, + OUT PVOID *VariableValue) { EFI_STATUS Status; PVOID Buffer; @@ -182,7 +182,7 @@ BlGetEfiVariable(IN PEFI_GUID Vendor, /* Allocate a buffer for storing a variable's value */ Size = EFI_MAXIMUM_VARIABLE_SIZE * sizeof(PWCHAR); - Status = BlAllocateMemoryPool(Size, (PVOID*)&Buffer); + Status = Memory::AllocatePool(Size, (PVOID*)&Buffer); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -216,7 +216,7 @@ BlGetEfiVariable(IN PEFI_GUID Vendor, */ XTCDECL ULONGLONG -BlGetRandomValue(IN OUT PULONGLONG RNGBuffer) +EfiUtils::GetRandomValue(IN OUT PULONGLONG RNGBuffer) { /* Recalculate RNG buffer with XORSHIFT */ *RNGBuffer ^= *RNGBuffer >> 12; @@ -236,7 +236,7 @@ BlGetRandomValue(IN OUT PULONGLONG RNGBuffer) */ XTCDECL INT_PTR -BlGetSecureBootStatus() +EfiUtils::GetSecureBootStatus() { EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID; INT_PTR SecureBootStatus = 0; @@ -272,7 +272,7 @@ BlGetSecureBootStatus() */ XTCDECL EFI_STATUS -BlInitializeEntropy(PULONGLONG RNGBuffer) +EfiUtils::InitializeEntropy(PULONGLONG RNGBuffer) { EFI_GUID RngGuid = EFI_RNG_PROTOCOL_GUID; PEFI_RNG_PROTOCOL Rng; @@ -325,10 +325,10 @@ BlInitializeEntropy(PULONGLONG RNGBuffer) */ XTCDECL EFI_STATUS -BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - IN PVOID ImageData, - IN SIZE_T ImageSize, - OUT PEFI_HANDLE ImageHandle) +EfiUtils::LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + IN PVOID ImageData, + IN SIZE_T ImageSize, + OUT PEFI_HANDLE ImageHandle) { /* Load EFI image */ return EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, DevicePath, ImageData, ImageSize, ImageHandle); @@ -343,7 +343,7 @@ BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, */ XTCDECL EFI_STATUS -BlRebootSystem() +EfiUtils::RebootSystem() { /* Reboot machine */ return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULLPTR); @@ -370,10 +370,10 @@ BlRebootSystem() */ XTCDECL EFI_STATUS -BlSetEfiVariable(IN PEFI_GUID Vendor, - IN PCWSTR VariableName, - IN PVOID VariableValue, - IN UINT_PTR Size) +EfiUtils::SetEfiVariable(IN PEFI_GUID Vendor, + IN PCWSTR VariableName, + IN PVOID VariableValue, + IN UINT_PTR Size) { ULONG Attributes; @@ -391,7 +391,7 @@ BlSetEfiVariable(IN PEFI_GUID Vendor, */ XTCDECL EFI_STATUS -BlShutdownSystem() +EfiUtils::ShutdownSystem() { /* Shutdown machine */ return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetShutdown, STATUS_EFI_SUCCESS, 0, NULLPTR); @@ -409,7 +409,7 @@ BlShutdownSystem() */ XTCDECL VOID -BlSleepExecution(IN ULONG_PTR Milliseconds) +EfiUtils::SleepExecution(IN ULONG_PTR Milliseconds) { EfiSystemTable->BootServices->Stall(Milliseconds * 1000); } @@ -426,7 +426,7 @@ BlSleepExecution(IN ULONG_PTR Milliseconds) */ XTCDECL EFI_STATUS -BlStartEfiImage(IN EFI_HANDLE ImageHandle) +EfiUtils::StartEfiImage(IN EFI_HANDLE ImageHandle) { return EfiSystemTable->BootServices->StartImage(ImageHandle, NULLPTR, NULLPTR); } @@ -449,9 +449,9 @@ BlStartEfiImage(IN EFI_HANDLE ImageHandle) */ XTCDECL EFI_STATUS -BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, - IN PEFI_EVENT Event, - OUT PUINT_PTR Index) +EfiUtils::WaitForEfiEvent(IN UINT_PTR NumberOfEvents, + IN PEFI_EVENT Event, + OUT PUINT_PTR Index) { return EfiSystemTable->BootServices->WaitForEvent(NumberOfEvents, Event, Index); } diff --git a/xtldr/hardware.cc b/xtldr/hardware.cc deleted file mode 100644 index 23294de..0000000 --- a/xtldr/hardware.cc +++ /dev/null @@ -1,112 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/hardware.cc - * DESCRIPTION: EFI hardware support for XT Boot Loader - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Enables I/O space access to all serial controllers found on the PCI(E) root bridge. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlpActivateSerialIOController() -{ - EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; - PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev; - USHORT Bus, Device, Function, Command; - UINT_PTR Index, PciHandleSize; - PEFI_HANDLE PciHandle = NULLPTR; - PCI_COMMON_HEADER PciHeader; - EFI_STATUS Status; - ULONGLONG Address; - - /* Allocate memory for single EFI_HANDLE, what should be enough in most cases */ - PciHandleSize = sizeof(EFI_HANDLE); - Status = BlAllocateMemoryPool(PciHandleSize, (PVOID*)&PciHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Get all instances of PciRootBridgeIo */ - Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR, &PciHandleSize, PciHandle); - if(Status == STATUS_EFI_BUFFER_TOO_SMALL) - { - /* Reallocate more memory as requested by UEFI */ - BlFreeMemoryPool(PciHandle); - Status = BlAllocateMemoryPool(PciHandleSize, (PVOID*)&PciHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory reallocation failure */ - return Status; - } - - /* Second attempt to get instances of PciRootBridgeIo */ - Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR, &PciHandleSize, PciHandle); - } - - /* Make sure successfully obtained PciRootBridgeIo instances */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get PciRootBridgeIo instances */ - return Status; - } - - /* Enumerate all devices for each handle, which decides a segment and a bus number range */ - for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++) - { - /* Get inferface from the protocol */ - Status = EfiSystemTable->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get interface */ - return Status; - } - - /* Enumerate whole PCI bridge */ - for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++) - { - /* Enumerate all devices for each bus */ - for(Device = 0; Device < PCI_MAX_DEVICES; Device++) - { - /* Enumerate all functions for each devices */ - for(Function = 0; Function < PCI_MAX_FUNCTION; Function++) - { - /* Read configuration space */ - Address = ((ULONGLONG)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) + - (((UINT_PTR) Function) << 8) + ((UINT_PTR) 0))); - PciDev->Pci.Read(PciDev, EfiPciIoWidthUint32, Address, sizeof (PciHeader) / sizeof (UINT), &PciHeader); - - /* Check if device exists */ - if(PciHeader.VendorId == PCI_INVALID_VENDORID) - { - /* Skip non-existen device */ - continue; - } - - /* Check if device is serial controller or multiport serial controller */ - if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02)) - { - /* Enable I/O space access */ - Address |= 0x4; - Command = PCI_ENABLE_IO_SPACE; - Status = PciDev->Pci.Write(PciDev, EfiPciIoWidthUint16, Address, 1, &Command); - } - } - } - } - } - - /* Return SUCCESS */ - return STATUS_EFI_SUCCESS; -} diff --git a/xtldr/includes/xtldr.hh b/xtldr/includes/xtldr.hh index bccb06b..b9be469 100644 --- a/xtldr/includes/xtldr.hh +++ b/xtldr/includes/xtldr.hh @@ -16,6 +16,308 @@ #include +class BootUtils +{ + public: + STATIC XTCDECL BOOLEAN GetBooleanParameter(IN PCWSTR Parameters, + IN PCWSTR Needle); +}; + +class Configuration +{ + public: + STATIC XTCDECL BOOLEAN GetBooleanValue(IN PCWSTR ConfigName); + STATIC XTCDECL EFI_STATUS GetBootOptionValue(IN PLIST_ENTRY Options, + IN PCWSTR OptionName, + OUT PWCHAR *OptionValue); + STATIC XTCDECL VOID GetEditableOptions(OUT PCWSTR **OptionsArray, + OUT PULONG OptionsCount); + STATIC XTCDECL EFI_STATUS GetValue(IN PCWSTR ConfigName, + OUT PWCHAR *ConfigValue); + STATIC XTCDECL EFI_STATUS LoadConfiguration(); + STATIC XTCDECL EFI_STATUS ParseCommandLine(); + STATIC XTCDECL EFI_STATUS SetBootOptionValue(IN PLIST_ENTRY Options, + IN PCWSTR OptionName, + IN PCWSTR OptionValue); + + private: + STATIC XTCDECL EFI_STATUS ParseConfigFile(IN CONST PCHAR RawConfig, + OUT PLIST_ENTRY Configuration); + STATIC XTCDECL EFI_STATUS ReadConfigFile(IN PCWSTR ConfigDirectory, + IN PCWSTR ConfigFile, + OUT PCHAR *ConfigData); + STATIC XTCDECL EFI_STATUS SetValue(IN PCWSTR ConfigName, + IN PCWSTR ConfigValue); + STATIC XTCDECL VOID UpdateConfiguration(IN PLIST_ENTRY NewConfig); +}; + +class Console +{ + public: + STATIC XTCDECL VOID ClearLine(IN ULONGLONG LineNo); + STATIC XTCDECL VOID ClearScreen(); + STATIC XTCDECL VOID DisableCursor(); + STATIC XTCDECL VOID EnableCursor(); + STATIC XTCDECL VOID InitializeConsole(); + STATIC XTCDECL VOID Print(IN PCWSTR Format, + IN ...); + STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character); + STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX, + OUT PUINT_PTR ResY); + STATIC XTCDECL VOID ReadKeyStroke(OUT PEFI_INPUT_KEY Key); + STATIC XTCDECL VOID ResetInputBuffer(); + STATIC XTCDECL VOID SetAttributes(IN ULONGLONG Attributes); + STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX, + IN ULONGLONG PosY); + STATIC XTCDECL VOID Write(IN PCWSTR String); + + private: + STATIC XTCDECL EFI_STATUS SetMode(IN ULONGLONG Mode); +}; + +class Debug +{ + public: + STATIC XTCDECL EFI_STATUS InitializeDebugConsole(); + STATIC XTCDECL VOID Print(IN PCWSTR Format, + IN ...); + STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character); + + private: + STATIC XTCDECL EFI_STATUS ActivateSerialIOController(); + STATIC XTCDECL EFI_STATUS InitializeSerialPort(IN ULONG PortNumber, + IN ULONG PortAddress, + IN ULONG BaudRate); +}; + +class EfiUtils +{ + public: + STATIC XTCDECL EFI_STATUS EnterFirmwareSetup(); + STATIC XTCDECL EFI_STATUS ExitBootServices(); + STATIC XTCDECL EFI_STATUS GetConfigurationTable(IN PEFI_GUID TableGuid, + OUT PVOID *Table); + STATIC XTCDECL EFI_STATUS GetEfiVariable(IN PEFI_GUID Vendor, + IN PCWSTR VariableName, + OUT PVOID *VariableValue); + STATIC XTCDECL ULONGLONG GetRandomValue(IN OUT PULONGLONG RNGBuffer); + STATIC XTCDECL INT_PTR GetSecureBootStatus(); + STATIC XTCDECL EFI_STATUS InitializeEntropy(PULONGLONG RNGBuffer); + STATIC XTCDECL EFI_STATUS LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + IN PVOID ImageData, + IN SIZE_T ImageSize, + OUT PEFI_HANDLE ImageHandle); + STATIC XTCDECL EFI_STATUS RebootSystem(); + STATIC XTCDECL EFI_STATUS SetEfiVariable(IN PEFI_GUID Vendor, + IN PCWSTR VariableName, + IN PVOID VariableValue, + IN UINT_PTR Size); + STATIC XTCDECL EFI_STATUS ShutdownSystem(); + STATIC XTCDECL VOID SleepExecution(IN ULONG_PTR Milliseconds); + STATIC XTCDECL EFI_STATUS StartEfiImage(IN EFI_HANDLE ImageHandle); + STATIC XTCDECL EFI_STATUS WaitForEfiEvent(IN UINT_PTR NumberOfEvents, + IN PEFI_EVENT Event, + OUT PUINT_PTR Index); +}; + +class Memory +{ + public: + STATIC XTCDECL EFI_STATUS AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType, + IN ULONGLONG NumberOfPages, + OUT PEFI_PHYSICAL_ADDRESS Memory); + STATIC XTCDECL EFI_STATUS AllocatePool(IN UINT_PTR Size, + OUT PVOID *Memory); + STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress); + STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages, + IN EFI_PHYSICAL_ADDRESS Memory); + STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory); + STATIC XTCDECL VOID GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, + OUT PULONG NumberOfMappings); + STATIC XTCDECL EFI_STATUS GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap); + STATIC XTCDECL PVOID GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PhysicalAddress); + STATIC XTCDECL VOID InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, + IN SHORT PageMapLevel, + IN PAGE_SIZE PageSize); + STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, + IN OUT PVOID *MemoryMapAddress, + IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); + STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR VirtualAddress, + IN ULONG_PTR PhysicalAddress, + IN ULONG NumberOfPages); + STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, + IN PVOID VirtualAddress, + IN PVOID PhysicalAddress, + IN ULONGLONG NumberOfPages, + IN LOADER_MEMORY_TYPE MemoryType); + STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress, + IN PVOID PhysicalBase, + IN PVOID VirtualBase); + STATIC XTCDECL EFI_STATUS PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, + IN OUT PLIST_ENTRY ListHead, + IN PVOID PhysicalBase, + IN PVOID VirtualBase); + + private: + STATIC XTCDECL LOADER_MEMORY_TYPE GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType); + STATIC XTCDECL EFI_STATUS GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PageTable, + IN SIZE_T Entry, + OUT PVOID *NextPageTable); + STATIC XTCDECL EFI_STATUS SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress); +}; + +class Protocol +{ + public: + STATIC XTCDECL EFI_STATUS CloseProtocol(IN PEFI_HANDLE Handle, + IN PEFI_GUID ProtocolGuid); + STATIC XTCDECL EFI_STATUS FindBootProtocol(IN PCWSTR SystemType, + OUT PEFI_GUID BootProtocolGuid); + STATIC XTCDECL PLIST_ENTRY GetModulesList(); + STATIC XTCDECL EFI_STATUS InstallProtocol(IN PVOID Interface, + IN PEFI_GUID Guid); + STATIC XTCDECL EFI_STATUS InvokeBootProtocol(IN PWCHAR ShortName, + IN PLIST_ENTRY OptionsList); + STATIC XTCDECL EFI_STATUS LoadModule(IN PWCHAR ModuleName); + STATIC XTCDECL EFI_STATUS LoadModules(IN PWCHAR ModulesList); + STATIC XTCDECL EFI_STATUS LocateProtocolHandles(OUT PEFI_HANDLE *Handles, + OUT PUINT_PTR Count, + IN PEFI_GUID ProtocolGuid); + STATIC XTCDECL EFI_STATUS OpenProtocol(OUT PEFI_HANDLE Handle, + OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid); + STATIC XTCDECL EFI_STATUS OpenProtocolHandle(IN EFI_HANDLE Handle, + OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid); + STATIC XTCDECL VOID RegisterBootMenu(IN PVOID BootMenuRoutine); + STATIC XTCDECL EFI_STATUS RegisterBootProtocol(IN PCWSTR SystemType, + IN PEFI_GUID BootProtocolGuid); + STATIC XTCDECL EFI_STATUS InstallXtLoaderProtocol(); + + private: + STATIC XTCDECL EFI_STATUS GetModuleInformation(IN PWCHAR SectionData, + IN ULONG SectionSize, + OUT PXTBL_MODULE_INFO ModuleInfo); + STATIC XTCDECL EFI_STATUS GetModuleInfoStrings(IN PWCHAR SectionData, + IN ULONG SectionSize, + OUT PWCHAR **ModInfo, + OUT PULONG InfoCount); +}; + +class Shell +{ + public: + STATIC XTCDECL VOID StartLoaderShell(); + + private: + STATIC XTCDECL VOID PrintPrompt(); +}; + +class TextUi +{ + public: + STATIC XTCDECL VOID DisplayBootMenu(); + STATIC XTCDECL VOID DisplayErrorDialog(IN PCWSTR Caption, + IN PCWSTR Message); + STATIC XTCDECL VOID DisplayInfoDialog(IN PCWSTR Caption, + IN PCWSTR Message); + STATIC XTCDECL VOID DisplayInputDialog(IN PCWSTR Caption, + IN PCWSTR Message, + IN OUT PWCHAR *InputFieldText); + STATIC XTCDECL XTBL_DIALOG_HANDLE DisplayProgressDialog(IN PCWSTR Caption, + IN PCWSTR Message, + IN UCHAR Percentage); + STATIC XTCDECL VOID UpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Message, + IN UCHAR Percentage); + + private: + STATIC XTCDECL VOID DetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Message); + STATIC XTCDECL VOID DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry); + STATIC XTCDECL VOID DrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle); + STATIC XTCDECL VOID DrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR MenuEntry, + IN UINT Position, + IN BOOLEAN Highlighted); + STATIC XTCDECL VOID DrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Caption, + IN PCWSTR Message); + STATIC XTCDECL VOID DrawButton(IN PXTBL_DIALOG_HANDLE Handle); + STATIC XTCDECL VOID DrawInputField(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR InputFieldText); + STATIC XTCDECL VOID DrawMessage(IN PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Message); + STATIC XTCDECL VOID DrawProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN UCHAR Percentage); + STATIC XTCDECL VOID DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle); + STATIC XTCDECL EFI_STATUS DrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR OptionName, + IN PCWSTR OptionValue, + IN UINT Position, + IN BOOLEAN Highlighted); +}; + +class Volume +{ + public: + STATIC XTCDECL EFI_STATUS CloseVolume(IN PEFI_HANDLE VolumeHandle); + STATIC XTCDECL EFI_STATUS EnumerateBlockDevices(); + STATIC XTCDECL EFI_STATUS FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, + IN CONST PWCHAR FileSystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); + STATIC XTCDECL EFI_STATUS GetEfiPath(IN PWCHAR SystemPath, + OUT PWCHAR *EfiPath); + STATIC XTCDECL EFI_STATUS GetDevicePath(IN PWCHAR SystemPath, + OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT PWCHAR *ArcName, + OUT PWCHAR *Path); + STATIC XTCDECL EFI_STATUS OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_HANDLE DiskHandle, + OUT PEFI_FILE_HANDLE *FsHandle); + STATIC XTCDECL EFI_STATUS ReadFile(IN PEFI_FILE_HANDLE DirHandle, + IN PCWSTR FileName, + OUT PVOID *FileData, + OUT PSIZE_T FileSize); + + + private: + STATIC XTCDECL EFI_STATUS DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); + STATIC XTCDECL EFI_STATUS DissectArcPath(IN PWCHAR SystemPath, + OUT PWCHAR *ArcName, + OUT PWCHAR *Path, + OUT PUSHORT DriveType, + OUT PULONG DriveNumber, + OUT PULONG PartNumber); + STATIC XTCDECL PEFI_DEVICE_PATH_PROTOCOL DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); + STATIC XTCDECL EFI_STATUS FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode); + STATIC XTCDECL BOOLEAN FindParentBlockDevice(IN PLIST_ENTRY BlockDevices, + IN PEFI_BLOCK_DEVICE_DATA ChildNode, + OUT PEFI_BLOCK_DEVICE_DATA *ParentNode); +}; + +class XtLoader +{ + public: + STATIC XTCDECL VOID InitializeBootLoader(); + STATIC XTCDECL EFI_STATUS InitializeBootMenuList(IN ULONG MaxNameLength, + OUT PXTBL_BOOTMENU_ITEM *MenuEntries, + OUT PULONG EntriesCount, + OUT PULONG DefaultId); +}; + + + + + + + /* XTLDR routines forward references */ XTCDECL EFI_STATUS diff --git a/xtldr/memory.cc b/xtldr/memory.cc index 8b819a9..bfbff2d 100644 --- a/xtldr/memory.cc +++ b/xtldr/memory.cc @@ -24,7 +24,7 @@ */ XTCDECL EFI_STATUS -BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType, +Memory::AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType, IN ULONGLONG NumberOfPages, OUT PEFI_PHYSICAL_ADDRESS Memory) { @@ -46,7 +46,7 @@ BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType, */ XTCDECL EFI_STATUS -BlAllocateMemoryPool(IN UINT_PTR Size, +Memory::AllocatePool(IN UINT_PTR Size, OUT PVOID *Memory) { /* Allocate pool */ @@ -68,7 +68,7 @@ BlAllocateMemoryPool(IN UINT_PTR Size, */ XTCDECL EFI_STATUS -BlFreeMemoryPages(IN ULONGLONG NumberOfPages, +Memory::FreePages(IN ULONGLONG NumberOfPages, IN EFI_PHYSICAL_ADDRESS Memory) { return EfiSystemTable->BootServices->FreePages(Memory, NumberOfPages); @@ -86,12 +86,60 @@ BlFreeMemoryPages(IN ULONGLONG NumberOfPages, */ XTCDECL EFI_STATUS -BlFreeMemoryPool(IN PVOID Memory) +Memory::FreePool(IN PVOID Memory) { /* Free pool */ return EfiSystemTable->BootServices->FreePool(Memory); } +/** + * Converts EFI memory type to XTLDR memory type. + * + * @param EfiMemoryType + * Specifies EFI memory type. + * + * @return This routine returns a mapped XTLDR memory type. + * + * @since XT 1.0 + */ +XTCDECL +LOADER_MEMORY_TYPE +Memory::GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType) +{ + LOADER_MEMORY_TYPE MemoryType; + + /* Check EFI memory type and convert to XTLDR memory type */ + switch(EfiMemoryType) + { + case EfiACPIMemoryNVS: + case EfiACPIReclaimMemory: + case EfiPalCode: + case EfiReservedMemoryType: + MemoryType = LoaderSpecialMemory; + break; + case EfiRuntimeServicesCode: + case EfiRuntimeServicesData: + case EfiMemoryMappedIO: + case EfiMemoryMappedIOPortSpace: + MemoryType = LoaderFirmwarePermanent; + break; + case EfiBootServicesData: + case EfiLoaderCode: + case EfiLoaderData: + MemoryType = LoaderFirmwareTemporary; + break; + case EfiUnusableMemory: + MemoryType = LoaderBad; + break; + default: + MemoryType = LoaderFree; + break; + } + + /* Return XTLDR memory type */ + return MemoryType; +} + /** * Returns the number of mappings in the page mapping structure. * @@ -107,8 +155,8 @@ BlFreeMemoryPool(IN PVOID Memory) */ XTCDECL VOID -BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, - OUT PULONG NumberOfMappings) +Memory::GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, + OUT PULONG NumberOfMappings) { /* Return number of mappings */ *NumberOfMappings = PageMap->MapSize; @@ -126,7 +174,7 @@ BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) +Memory::GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) { EFI_STATUS Status; @@ -155,14 +203,14 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) if(MemoryMap->Map) { /* Free allocated memory */ - BlFreeMemoryPool(MemoryMap->Map); + FreePool(MemoryMap->Map); } return Status; } /* Allocate the desired amount of memory */ MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize; - BlAllocateMemoryPool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); + AllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); } while(Status == STATUS_EFI_BUFFER_TOO_SMALL); @@ -192,8 +240,8 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) */ XTCDECL PVOID -BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID PhysicalAddress) +Memory::GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PhysicalAddress) { PXTBL_MEMORY_MAPPING Mapping; PLIST_ENTRY ListEntry; @@ -243,9 +291,9 @@ BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL VOID -BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, - IN SHORT PageMapLevel, - IN PAGE_SIZE PageSize) +Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, + IN SHORT PageMapLevel, + IN PAGE_SIZE PageSize) { /* Initialize memory mappings */ RTL::LinkedList::InitializeListHead(&PageMap->MemoryMap); @@ -274,9 +322,9 @@ BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, - IN OUT PVOID *MemoryMapAddress, - IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine) +Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, + IN OUT PVOID *MemoryMapAddress, + IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine) { PEFI_MEMORY_DESCRIPTOR Descriptor; LOADER_MEMORY_TYPE MemoryType; @@ -293,15 +341,15 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, if(GetMemoryTypeRoutine == NULLPTR) { /* Use default memory type routine */ - GetMemoryTypeRoutine = BlpGetLoaderMemoryType; + GetMemoryTypeRoutine = GetLoaderMemoryType; } /* Allocate and zero-fill buffer for EFI memory map */ - BlAllocateMemoryPool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); + AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); /* Get EFI memory map */ - Status = BlGetMemoryMap(MemoryMap); + Status = GetMemoryMap(MemoryMap); if(Status != STATUS_EFI_SUCCESS) { /* Failed to get EFI memory map */ @@ -352,14 +400,14 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, if(MemoryType == LoaderFirmwareTemporary) { /* Map EFI firmware code */ - Status = BlMapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart, - (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); + Status = MapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart, + (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); } else if(MemoryType != LoaderFree) { /* Add any non-free memory mapping */ - Status = BlMapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart, - Descriptor->NumberOfPages, MemoryType); + Status = MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart, + Descriptor->NumberOfPages, MemoryType); /* Calculate next valid virtual address */ VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE; @@ -367,8 +415,8 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, else { /* Map all other memory as loader free */ - Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart, - Descriptor->NumberOfPages, LoaderFree); + Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart, + Descriptor->NumberOfPages, LoaderFree); } /* Make sure memory mapping succeeded */ @@ -384,7 +432,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, } /* Always map first page */ - Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)0, 1, LoaderFirmwarePermanent); + Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0, 1, LoaderFirmwarePermanent); if(Status != STATUS_EFI_SUCCESS) { /* Mapping failed */ @@ -392,7 +440,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, } /* Map BIOS ROM and VRAM */ - Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent); + Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent); if(Status != STATUS_EFI_SUCCESS) { /* Mapping failed */ @@ -428,11 +476,11 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, - IN PVOID VirtualAddress, - IN PVOID PhysicalAddress, - IN ULONGLONG NumberOfPages, - IN LOADER_MEMORY_TYPE MemoryType) +Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, + IN PVOID VirtualAddress, + IN PVOID PhysicalAddress, + IN ULONGLONG NumberOfPages, + IN LOADER_MEMORY_TYPE MemoryType) { PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3; PVOID PhysicalAddressEnd, PhysicalAddress2End; @@ -441,7 +489,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, EFI_STATUS Status; /* Allocate memory for new mapping */ - Status = BlAllocateMemoryPool(sizeof(XTBL_MEMORY_MAPPING), (PVOID *)&Mapping1); + Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID *)&Mapping1); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -491,7 +539,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, if(NumberOfMappedPages > 0) { /* Pages associated to the mapping, allocate memory for it */ - Status = BlAllocateMemoryPool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3); + Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -527,7 +575,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, if(NumberOfMappedPages > 0) { /* Pages associated to the mapping, allocate memory for it */ - Status = BlAllocateMemoryPool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3); + Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -564,7 +612,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, /* Remove mapping from the list and free up it's memory */ RTL::LinkedList::RemoveEntryList(&Mapping2->ListEntry); - Status = BlFreeMemoryPool(Mapping2); + Status = FreePool(Mapping2); ListEntry = MappingListEntry; /* Go to the next mapping */ @@ -609,9 +657,9 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, */ XTCDECL PVOID -BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress, - IN PVOID PhysicalBase, - IN PVOID VirtualBase) +Memory::PhysicalAddressToVirtual(IN PVOID PhysicalAddress, + IN PVOID PhysicalBase, + IN PVOID VirtualBase) { /* Convert physical address to virtual address */ return (PUCHAR)VirtualBase + ((PUCHAR)PhysicalAddress - (PUCHAR)PhysicalBase); @@ -638,10 +686,10 @@ BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress, */ XTCDECL EFI_STATUS -BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, - IN OUT PLIST_ENTRY ListHead, - IN PVOID PhysicalBase, - IN PVOID VirtualBase) +Memory::PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, + IN OUT PLIST_ENTRY ListHead, + IN PVOID PhysicalBase, + IN PVOID VirtualBase) { PLIST_ENTRY ListEntry, NextEntry; @@ -663,12 +711,12 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, if(ListEntry->Blink == ListHead) { /* Find virtual address of list head */ - ListEntry->Blink = (PLIST_ENTRY)BlGetVirtualAddress(PageMap, ListEntry->Blink); + ListEntry->Blink = (PLIST_ENTRY)GetVirtualAddress(PageMap, ListEntry->Blink); } else { /* Convert list entry */ - ListEntry->Blink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase); + ListEntry->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase); } if(ListEntry->Flink == ListHead) { @@ -678,7 +726,7 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, else { /* Convert list entry */ - ListEntry->Flink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase); + ListEntry->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase); } /* Get to the next element*/ @@ -686,57 +734,9 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, } /* Convert list head */ - ListHead->Blink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase); - ListHead->Flink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase); + ListHead->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase); + ListHead->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase); /* Return success */ return STATUS_EFI_SUCCESS; } - -/** - * Converts EFI memory type to XTLDR memory type. - * - * @param EfiMemoryType - * Specifies EFI memory type. - * - * @return This routine returns a mapped XTLDR memory type. - * - * @since XT 1.0 - */ -XTCDECL -LOADER_MEMORY_TYPE -BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType) -{ - LOADER_MEMORY_TYPE MemoryType; - - /* Check EFI memory type and convert to XTLDR memory type */ - switch(EfiMemoryType) - { - case EfiACPIMemoryNVS: - case EfiACPIReclaimMemory: - case EfiPalCode: - case EfiReservedMemoryType: - MemoryType = LoaderSpecialMemory; - break; - case EfiRuntimeServicesCode: - case EfiRuntimeServicesData: - case EfiMemoryMappedIO: - case EfiMemoryMappedIOPortSpace: - MemoryType = LoaderFirmwarePermanent; - break; - case EfiBootServicesData: - case EfiLoaderCode: - case EfiLoaderData: - MemoryType = LoaderFirmwareTemporary; - break; - case EfiUnusableMemory: - MemoryType = LoaderBad; - break; - default: - MemoryType = LoaderFree; - break; - } - - /* Return XTLDR memory type */ - return MemoryType; -} diff --git a/xtldr/modules/acpi/acpi.cc b/xtldr/modules/acpi/acpi.cc index 7709643..cc89d2e 100644 --- a/xtldr/modules/acpi/acpi.cc +++ b/xtldr/modules/acpi/acpi.cc @@ -228,7 +228,7 @@ Acpi::GetRsdpTable(OUT PVOID *AcpiTable) PVOID RsdpTable; /* Get RSDP (ACPI 1.0) table from system configuration tables */ - Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &RsdpTable); + Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &RsdpTable); if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(RsdpTable, 20)) { /* RSDP not found or checksum mismatch */ @@ -260,7 +260,7 @@ Acpi::GetSMBiosTable(OUT PVOID *SmBiosTable) EFI_STATUS Status; /* Get SMBIOS table from system configuration tables */ - Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBiosGuid, (PVOID*)&SmBios); + Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBiosGuid, (PVOID*)&SmBios); if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length)) { /* SMBIOS not found or checksum mismatch */ @@ -292,7 +292,7 @@ Acpi::GetSMBios3Table(OUT PVOID *SmBiosTable) EFI_STATUS Status; /* Get SMBIOS3 table from system configuration tables */ - Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBios3Guid, (PVOID*)&SmBios); + Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBios3Guid, (PVOID*)&SmBios); if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length)) { /* SMBIOS3 not found or checksum mismatch */ @@ -324,7 +324,7 @@ Acpi::GetXsdpTable(OUT PVOID *AcpiTable) PVOID XsdpTable; /* Get XSDP (ACPI 2.0) from system configuration tables */ - Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &XsdpTable); + Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &XsdpTable); if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(XsdpTable, 36)) { /* XSDP not found or checksum mismatch */ diff --git a/xtldr/modules/beep/beep.cc b/xtldr/modules/beep/beep.cc index f918a88..d1e548b 100644 --- a/xtldr/modules/beep/beep.cc +++ b/xtldr/modules/beep/beep.cc @@ -167,7 +167,7 @@ Beep::PlayTune(IN PWCHAR Arguments) } /* Wait for duration time */ - XtLdrProtocol->Util.SleepExecution(60000 * Duration / Tempo); + XtLdrProtocol->Utils.SleepExecution(60000 * Duration / Tempo); /* Reset pitch and duration */ Pitch = -1; diff --git a/xtldr/modules/chainldr/chainldr.cc b/xtldr/modules/chainldr/chainldr.cc index b6e93dc..b2c0604 100644 --- a/xtldr/modules/chainldr/chainldr.cc +++ b/xtldr/modules/chainldr/chainldr.cc @@ -90,8 +90,8 @@ ChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; /* Load EFI image */ - Status = XtLdrProtocol->Util.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath, - LoaderData, LoaderSize, &LoaderHandle); + Status = XtLdrProtocol->Utils.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath, + LoaderData, LoaderSize, &LoaderHandle); if(Status != STATUS_EFI_SUCCESS) { /* Failed to chainload EFI binary, return error code */ @@ -121,7 +121,7 @@ ChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) LoadedImage->DeviceHandle = DiskHandle; /* Chainload EFI image */ - return XtLdrProtocol->Util.StartEfiImage(LoaderHandle); + return XtLdrProtocol->Utils.StartEfiImage(LoaderHandle); } /** diff --git a/xtldr/modules/xtos_o/amd64/memory.cc b/xtldr/modules/xtos_o/amd64/memory.cc index cde1f56..02335aa 100644 --- a/xtldr/modules/xtos_o/amd64/memory.cc +++ b/xtldr/modules/xtos_o/amd64/memory.cc @@ -45,7 +45,7 @@ Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters) /* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */ if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) && - !(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA"))) + !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA"))) { /* Enable LA57 (PML5) */ return 5; @@ -98,7 +98,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap) if(PageMap->PageMapLevel == 5) { /* Get the trampoline code information */ - XtLdrProtocol->BootUtil.GetTrampolineInformation(TrampolineEnableXpa, &TrampolineCode, &TrampolineSize); + XtLdrProtocol->BootUtils.GetTrampolineInformation(TrampolineEnableXpa, &TrampolineCode, &TrampolineSize); if(TrampolineCode == NULLPTR || TrampolineSize == 0) { /* Failed to get trampoline information */ @@ -125,7 +125,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap) /* Exit EFI Boot Services */ XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); - Status = XtLdrProtocol->Util.ExitBootServices(); + Status = XtLdrProtocol->Utils.ExitBootServices(); if(Status != STATUS_EFI_SUCCESS) { /* Failed to exit boot services */ diff --git a/xtldr/modules/xtos_o/i686/memory.cc b/xtldr/modules/xtos_o/i686/memory.cc index d31103e..c2b2e1c 100644 --- a/xtldr/modules/xtos_o/i686/memory.cc +++ b/xtldr/modules/xtos_o/i686/memory.cc @@ -34,7 +34,7 @@ Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters) /* Check if eXtended Physical Addressing (XPA) is enabled and if PAE is supported by the CPU */ if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) && - !(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA"))) + !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA"))) { /* Enable PAE (PML3) */ return 3; @@ -80,7 +80,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap) /* Exit EFI Boot Services */ XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); - Status = XtLdrProtocol->Util.ExitBootServices(); + Status = XtLdrProtocol->Utils.ExitBootServices(); if(Status != STATUS_EFI_SUCCESS) { /* Failed to exit boot services */ diff --git a/xtldr/protocol.cc b/xtldr/protocol.cc index 66cafca..b0d756a 100644 --- a/xtldr/protocol.cc +++ b/xtldr/protocol.cc @@ -24,8 +24,8 @@ */ XTCDECL EFI_STATUS -BlCloseProtocol(IN PEFI_HANDLE Handle, - IN PEFI_GUID ProtocolGuid) +Protocol::CloseProtocol(IN PEFI_HANDLE Handle, + IN PEFI_GUID ProtocolGuid) { return EfiSystemTable->BootServices->CloseProtocol(Handle, ProtocolGuid, EfiImageHandle, NULLPTR); } @@ -45,8 +45,8 @@ BlCloseProtocol(IN PEFI_HANDLE Handle, */ XTCDECL EFI_STATUS -BlFindBootProtocol(IN PCWSTR SystemType, - OUT PEFI_GUID BootProtocolGuid) +Protocol::FindBootProtocol(IN PCWSTR SystemType, + OUT PEFI_GUID BootProtocolGuid) { PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; PLIST_ENTRY ProtocolListEntry; @@ -84,7 +84,7 @@ BlFindBootProtocol(IN PCWSTR SystemType, */ XTCDECL PLIST_ENTRY -BlGetModulesList() +Protocol::GetModulesList() { /* Return a pointer to a list of all loaded modules */ return &BlpLoadedModules; @@ -105,8 +105,8 @@ BlGetModulesList() */ XTCDECL EFI_STATUS -BlInstallProtocol(IN PVOID Interface, - IN PEFI_GUID Guid) +Protocol::InstallProtocol(IN PVOID Interface, + IN PEFI_GUID Guid) { EFI_HANDLE Handle = NULLPTR; @@ -114,6 +114,157 @@ BlInstallProtocol(IN PVOID Interface, return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE, Interface); } +/** + * Loads all necessary modules and invokes boot protocol. + * + * @param ShortName + * Supplies a pointer to a short name of the chosen boot menu entry. + * + * @param OptionsList + * Supplies a pointer to list of options associated with chosen boot menu entry. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::InvokeBootProtocol(IN PWCHAR ShortName, + IN PLIST_ENTRY OptionsList) +{ + EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; + XTBL_BOOT_PARAMETERS BootParameters; + PXTBL_BOOT_PROTOCOL BootProtocol; + PLIST_ENTRY OptionsListEntry; + PXTBL_CONFIG_ENTRY Option; + EFI_GUID BootProtocolGuid; + SIZE_T ModuleListLength; + PWCHAR ModulesList; + EFI_HANDLE Handle; + EFI_STATUS Status; + + /* Initialize boot parameters and a list of modules */ + RTL::Memory::ZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS)); + ModulesList = NULLPTR; + + /* Iterate through all options provided by boot menu entry and propagate boot parameters */ + OptionsListEntry = OptionsList->Flink; + while(OptionsListEntry != OptionsList) + { + /* Get option */ + Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink); + + /* Look for boot protocol and modules list */ + if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) + { + /* Check a length of modules list */ + ModuleListLength = RTL::WideString::WideStringLength(Option->Value, 0); + + Status = Memory::AllocatePool(sizeof(WCHAR) * (ModuleListLength + 1), (PVOID *)&ModulesList); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory, print error message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Make a copy of modules list */ + RTL::Memory::CopyMemory(ModulesList, Option->Value, sizeof(WCHAR) * (ModuleListLength + 1)); + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0) + { + /* Boot protocol found */ + BootParameters.SystemType = Option->Value; + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0) + { + /* System path found, get volume device path */ + Status = Volume::GetDevicePath(Option->Value, &BootParameters.DevicePath, + &BootParameters.ArcName, &BootParameters.SystemPath); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to find volume */ + Debug::Print(L"ERROR: Failed to find volume device path (Status Code: 0x%zX)\n", Status); + return Status; + } + + /* Get EFI compatible system path */ + Status = Volume::GetEfiPath(BootParameters.SystemPath, &BootParameters.EfiPath); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get EFI path */ + Debug::Print(L"ERROR: Failed to get EFI path (Status Code: 0x%zX)\n", Status); + return Status; + } + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0) + { + /* Kernel file name found */ + BootParameters.KernelFile = Option->Value; + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0) + { + /* Initrd file name found */ + BootParameters.InitrdFile = Option->Value; + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0) + { + /* Hal file name found */ + BootParameters.HalFile = Option->Value; + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0) + { + /* Kernel parameters found */ + BootParameters.Parameters = Option->Value; + } + + /* Move to the next option entry */ + OptionsListEntry = OptionsListEntry->Flink; + } + + /* Load all necessary modules */ + Status = LoadModules(ModulesList); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load modules, print error message and return status code */ + Debug::Print(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status); + return STATUS_EFI_NOT_READY; + } + + /* Attempt to get boot protocol GUID */ + Status = FindBootProtocol(BootParameters.SystemType, &BootProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get boot protocol GUID */ + Debug::Print(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%zX)\n", Status); + return STATUS_EFI_UNSUPPORTED; + } + + /* Open boot protocol */ + Status = OpenProtocol(&Handle, (PVOID *)&BootProtocol, &BootProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open boot protocol */ + Debug::Print(L"ERROR: Failed to open boot protocol (Status Code: 0x%zX)\n", Status); + return Status; + } + + /* Check if chosen operating system should be saved */ + if(Configuration::GetBooleanValue(L"KEEPLASTBOOT")) + { + /* Save chosen operating system in NVRAM */ + Status = EfiUtils::SetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID)ShortName, RTL::WideString::WideStringLength(ShortName, 0) * sizeof(WCHAR)); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to save chosen Operating System */ + Debug::Print(L"WARNING: Failed to save chosen Operating System in NVRAM (Status Code: 0x%zX)\n", Status); + } + } + + /* Boot Operating System */ + return BootProtocol->BootSystem(&BootParameters); +} + /** * Loads a specified XTLDR module from disk. * @@ -126,7 +277,7 @@ BlInstallProtocol(IN PVOID Interface, */ XTCDECL EFI_STATUS -BlLoadModule(IN PWCHAR ModuleName) +Protocol::LoadModule(IN PWCHAR ModuleName) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PLIST_ENTRY DepsListEntry, ModuleListEntry; @@ -155,7 +306,7 @@ BlLoadModule(IN PWCHAR ModuleName) if(RTL::WideString::CompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) { /* Module already loaded */ - BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName); + Debug::Print(L"WARNING: Module '%S' already loaded!\n", ModuleName); return STATUS_EFI_SUCCESS; } @@ -164,14 +315,14 @@ BlLoadModule(IN PWCHAR ModuleName) } /* Print debug message */ - BlDebugPrint(L"Loading module '%S' ...\n", ModuleName); + Debug::Print(L"Loading module '%S' ...\n", ModuleName); /* Set module path */ RTL::Memory::CopyMemory(ModuleFileName, ModuleName, (RTL::WideString::WideStringLength(ModuleName, 0) + 1) * sizeof(WCHAR)); RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0); /* Open EFI volume */ - Status = BlOpenVolume(NULLPTR, &DiskHandle, &FsHandle); + Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle); if(Status != STATUS_EFI_SUCCESS) { /* Failed to open a volume */ @@ -193,14 +344,14 @@ BlLoadModule(IN PWCHAR ModuleName) if(Status != STATUS_EFI_SUCCESS) { /* Failed to open directory */ - BlCloseVolume(&DiskHandle); + Volume::CloseVolume(&DiskHandle); return Status; } /* Read module file from disk and close directory and EFI volume */ - Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); + Status = Volume::ReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); DirHandle->Close(DirHandle); - BlCloseVolume(&DiskHandle); + Volume::CloseVolume(&DiskHandle); /* Make sure module file was read successfully */ if(Status != STATUS_EFI_SUCCESS) @@ -210,7 +361,7 @@ BlLoadModule(IN PWCHAR ModuleName) } /* Allocate memory for module information block */ - Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); + Status = Memory::AllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); if(Status != STATUS_EFI_SUCCESS) { /* Failed to allocate memory */ @@ -247,7 +398,7 @@ BlLoadModule(IN PWCHAR ModuleName) SectionData = (PWCHAR)((PUCHAR)ModuleData + SectionHeader[SectionIndex].PointerToRawData); /* Get module information */ - Status = BlpGetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo); + Status = GetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo); if(Status != STATUS_EFI_SUCCESS) { /* Failed to read module information */ @@ -271,12 +422,12 @@ BlLoadModule(IN PWCHAR ModuleName) } /* Load dependency module */ - BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, ModuleDependency->ModuleName); - Status = BlLoadModule(ModuleDependency->ModuleName); + Debug::Print(L"Module '%S' requires '%S' ...\n", ModuleName, ModuleDependency->ModuleName); + Status = LoadModule(ModuleDependency->ModuleName); if(Status != STATUS_EFI_SUCCESS) { /* Failed to load module, print error message and return status code */ - BlDebugPrint(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", ModuleDependency->ModuleName, Status); + Debug::Print(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", ModuleDependency->ModuleName, Status); return STATUS_EFI_UNSUPPORTED; } @@ -298,20 +449,20 @@ BlLoadModule(IN PWCHAR ModuleName) ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; /* Load EFI image */ - BlDebugPrint(L"Starting module '%S' ...\n", ModuleName); - Status = BlLoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle); + Debug::Print(L"Starting module '%S' ...\n", ModuleName); + Status = EfiUtils::LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle); if(Status != STATUS_EFI_SUCCESS) { /* Check if caused by secure boot */ if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1) { /* SecureBoot signature validation failed */ - BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName); + Debug::Print(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName); } else { /* Failed to load module */ - BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); + Debug::Print(L"ERROR: Unable to load module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); } /* Return error status code */ @@ -324,7 +475,7 @@ BlLoadModule(IN PWCHAR ModuleName) if(Status != STATUS_EFI_SUCCESS) { /* Failed to open LoadedImage protocol */ - BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Unable to access module interface (Status Code: 0x%zX)\n", Status); return Status; } @@ -332,7 +483,7 @@ BlLoadModule(IN PWCHAR ModuleName) if(LoadedImage->ImageCodeType != EfiBootServicesCode) { /* Different type set, probably 'runtime driver', refuse to load it */ - BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n"); + Debug::Print(L"ERROR: Loaded module is not a boot system driver\n"); /* Close protocol and skip module */ EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR); @@ -349,11 +500,11 @@ BlLoadModule(IN PWCHAR ModuleName) EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR); /* Start EFI image */ - Status = BlStartEfiImage(ModuleHandle); + Status = EfiUtils::StartEfiImage(ModuleHandle); if(Status != STATUS_EFI_SUCCESS) { /* Failed to start module image */ - BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); + Debug::Print(L"ERROR: Failed to start module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); return Status; } @@ -376,7 +527,7 @@ BlLoadModule(IN PWCHAR ModuleName) */ XTCDECL EFI_STATUS -BlLoadModules(IN PWCHAR ModulesList) +Protocol::LoadModules(IN PWCHAR ModulesList) { PWCHAR LastModule, Module; EFI_STATUS ReturnStatus, Status; @@ -392,11 +543,11 @@ BlLoadModules(IN PWCHAR ModulesList) /* Iterate over all arguments passed to boot loader */ while(Module != NULLPTR) { - Status = BlLoadModule(Module); + Status = LoadModule(Module); if(Status != STATUS_EFI_SUCCESS) { /* Failed to load module, print error message and set new return value */ - BlDebugPrint(L"ERROR: Failed to load module '%S' (Status Code: 0x%zX)\n", Module, Status); + Debug::Print(L"ERROR: Failed to load module '%S' (Status Code: 0x%zX)\n", Module, Status); ReturnStatus = STATUS_EFI_LOAD_ERROR; } @@ -427,9 +578,9 @@ BlLoadModules(IN PWCHAR ModulesList) */ XTCDECL EFI_STATUS -BlLocateProtocolHandles(OUT PEFI_HANDLE *Handles, - OUT PUINT_PTR Count, - IN PEFI_GUID ProtocolGuid) +Protocol::LocateProtocolHandles(OUT PEFI_HANDLE *Handles, + OUT PUINT_PTR Count, + IN PEFI_GUID ProtocolGuid) { return EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, ProtocolGuid, NULLPTR, Count, Handles); } @@ -452,9 +603,9 @@ BlLocateProtocolHandles(OUT PEFI_HANDLE *Handles, */ XTCDECL EFI_STATUS -BlOpenProtocol(OUT PEFI_HANDLE Handle, - OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid) +Protocol::OpenProtocol(OUT PEFI_HANDLE Handle, + OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid) { PEFI_HANDLE Handles = NULLPTR; EFI_STATUS Status; @@ -462,7 +613,7 @@ BlOpenProtocol(OUT PEFI_HANDLE Handle, UINT Index; /* Try to locate the handles */ - Status = BlLocateProtocolHandles(&Handles, &Count, ProtocolGuid); + Status = LocateProtocolHandles(&Handles, &Count, ProtocolGuid); if(Status != STATUS_EFI_SUCCESS) { /* Unable to get handles */ @@ -476,7 +627,7 @@ BlOpenProtocol(OUT PEFI_HANDLE Handle, for(Index = 0; Index < Count; Index++) { /* Try to open protocol */ - Status = BlOpenProtocolHandle(Handles[Index], ProtocolHandler, ProtocolGuid); + Status = OpenProtocolHandle(Handles[Index], ProtocolHandler, ProtocolGuid); /* Check if successfully opened the loader protocol */ if(Status == STATUS_EFI_SUCCESS) @@ -520,9 +671,9 @@ BlOpenProtocol(OUT PEFI_HANDLE Handle, */ XTCDECL EFI_STATUS -BlOpenProtocolHandle(IN EFI_HANDLE Handle, - OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid) +Protocol::OpenProtocolHandle(IN EFI_HANDLE Handle, + OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid) { return EfiSystemTable->BootServices->OpenProtocol(Handle, ProtocolGuid, ProtocolHandler, EfiImageHandle, NULLPTR, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); @@ -540,7 +691,7 @@ BlOpenProtocolHandle(IN EFI_HANDLE Handle, */ XTCDECL VOID -BlRegisterBootMenu(IN PVOID BootMenuRoutine) +Protocol::RegisterBootMenu(IN PVOID BootMenuRoutine) { /* Set boot menu routine */ BlpStatus.BootMenu = (PBL_XT_BOOT_MENU)BootMenuRoutine; @@ -561,8 +712,8 @@ BlRegisterBootMenu(IN PVOID BootMenuRoutine) */ XTCDECL EFI_STATUS -BlRegisterBootProtocol(IN PCWSTR SystemType, - IN PEFI_GUID BootProtocolGuid) +Protocol::RegisterBootProtocol(IN PCWSTR SystemType, + IN PEFI_GUID BootProtocolGuid) { PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; PLIST_ENTRY ProtocolListEntry; @@ -586,7 +737,7 @@ BlRegisterBootProtocol(IN PCWSTR SystemType, } /* Create new boot protocol entry */ - Status = BlAllocateMemoryPool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry); + Status = Memory::AllocatePool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -620,9 +771,9 @@ BlRegisterBootProtocol(IN PCWSTR SystemType, */ XTCDECL EFI_STATUS -BlpGetModuleInformation(IN PWCHAR SectionData, - IN ULONG SectionSize, - OUT PXTBL_MODULE_INFO ModuleInfo) +Protocol::GetModuleInformation(IN PWCHAR SectionData, + IN ULONG SectionSize, + OUT PXTBL_MODULE_INFO ModuleInfo) { PXTBL_MODULE_DEPS ModuleDependencies; PXTBL_MODULE_AUTHORS ModuleAuthors; @@ -636,7 +787,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData, RTL::LinkedList::InitializeListHead(&ModuleInfo->Dependencies); /* Get information strings from '.modinfo' section */ - Status = BlpGetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count); + Status = GetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count); if(Status != STATUS_EFI_SUCCESS) { /* Failed to get information strings */ @@ -664,7 +815,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData, if(RTL::WideString::CompareWideString(Key, L"author", 6) == 0) { /* Allocate memory for module author */ - Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_AUTHORS), (PVOID*)&ModuleAuthors); + Status = Memory::AllocatePool(sizeof(XTBL_MODULE_AUTHORS), (PVOID*)&ModuleAuthors); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -692,7 +843,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData, while(Dependency != NULLPTR) { /* Allocate memory for module dependency */ - Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); + Status = Memory::AllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -739,10 +890,10 @@ BlpGetModuleInformation(IN PWCHAR SectionData, */ XTCDECL EFI_STATUS -BlpGetModuleInfoStrings(IN PWCHAR SectionData, - IN ULONG SectionSize, - OUT PWCHAR **ModInfo, - OUT PULONG InfoCount) +Protocol::GetModuleInfoStrings(IN PWCHAR SectionData, + IN ULONG SectionSize, + OUT PWCHAR **ModInfo, + OUT PULONG InfoCount) { ULONG Count, Index, ArrayIndex; PCWSTR InfoStrings; @@ -801,7 +952,7 @@ BlpGetModuleInfoStrings(IN PWCHAR SectionData, } /* Allocate memory for the pointer array and the string data */ - Status = BlAllocateMemoryPool(sizeof(PWCHAR) * (Count + 1) + (DataSize + 1) * sizeof(WCHAR), (PVOID *)&Array); + Status = Memory::AllocatePool(sizeof(PWCHAR) * (Count + 1) + (DataSize + 1) * sizeof(WCHAR), (PVOID *)&Array); if(Status != STATUS_EFI_SUCCESS) { /* Failed to allocate memory */ @@ -858,42 +1009,42 @@ BlpGetModuleInfoStrings(IN PWCHAR SectionData, */ XTCDECL EFI_STATUS -BlpInstallXtLoaderProtocol() +Protocol::InstallXtLoaderProtocol() { EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID; /* Set all routines available via loader protocol */ - BlpLdrProtocol.Boot.FindProtocol = BlFindBootProtocol; - BlpLdrProtocol.Boot.InitializeMenuList = BlInitializeBootMenuList; - BlpLdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol; - BlpLdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu; - BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; - BlpLdrProtocol.BootUtil.GetBooleanParameter = BlGetBooleanParameter; - BlpLdrProtocol.BootUtil.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation; - BlpLdrProtocol.Config.GetBooleanValue = BlGetConfigBooleanValue; - BlpLdrProtocol.Config.GetBootOptionValue = BlGetBootOptionValue; - BlpLdrProtocol.Config.GetEditableOptions = BlGetEditableOptions; - BlpLdrProtocol.Config.GetValue = BlGetConfigValue; - BlpLdrProtocol.Config.SetBootOptionValue = BlSetBootOptionValue; - BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine; - BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen; - BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; - BlpLdrProtocol.Console.EnableCursor = BlEnableConsoleCursor; - BlpLdrProtocol.Console.Print = BlConsolePrint; - BlpLdrProtocol.Console.QueryMode = BlQueryConsoleMode; - BlpLdrProtocol.Console.ReadKeyStroke = BlReadKeyStroke; - BlpLdrProtocol.Console.ResetInputBuffer = BlResetConsoleInputBuffer; - BlpLdrProtocol.Console.SetAttributes = BlSetConsoleAttributes; - BlpLdrProtocol.Console.SetCursorPosition = BlSetCursorPosition; - BlpLdrProtocol.Console.Write = BlConsoleWrite; + BlpLdrProtocol.Boot.FindProtocol = FindBootProtocol; + BlpLdrProtocol.Boot.InitializeMenuList = XtLoader::InitializeBootMenuList; + BlpLdrProtocol.Boot.InvokeProtocol = InvokeBootProtocol; + BlpLdrProtocol.Boot.RegisterMenu = RegisterBootMenu; + BlpLdrProtocol.Boot.RegisterProtocol = RegisterBootProtocol; + BlpLdrProtocol.BootUtils.GetBooleanParameter = BootUtils::GetBooleanParameter; + BlpLdrProtocol.BootUtils.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation; + BlpLdrProtocol.Config.GetBooleanValue = Configuration::GetBooleanValue; + BlpLdrProtocol.Config.GetBootOptionValue = Configuration::GetBootOptionValue; + BlpLdrProtocol.Config.GetEditableOptions = Configuration::GetEditableOptions; + BlpLdrProtocol.Config.GetValue = Configuration::GetValue; + BlpLdrProtocol.Config.SetBootOptionValue = Configuration::SetBootOptionValue; + BlpLdrProtocol.Console.ClearLine = Console::ClearLine; + BlpLdrProtocol.Console.ClearScreen = Console::ClearScreen; + BlpLdrProtocol.Console.DisableCursor = Console::DisableCursor; + BlpLdrProtocol.Console.EnableCursor = Console::EnableCursor; + BlpLdrProtocol.Console.Print = Console::Print; + BlpLdrProtocol.Console.QueryMode = Console::QueryMode; + BlpLdrProtocol.Console.ReadKeyStroke = Console::ReadKeyStroke; + BlpLdrProtocol.Console.ResetInputBuffer = Console::ResetInputBuffer; + BlpLdrProtocol.Console.SetAttributes = Console::SetAttributes; + BlpLdrProtocol.Console.SetCursorPosition = Console::SetCursorPosition; + BlpLdrProtocol.Console.Write = Console::Write; BlpLdrProtocol.Cpu.CpuId = AR::CpuFunc::CpuId; BlpLdrProtocol.Cpu.ReadControlRegister = AR::CpuFunc::ReadControlRegister; BlpLdrProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunc::ReadModelSpecificRegister; BlpLdrProtocol.Cpu.WriteControlRegister = AR::CpuFunc::WriteControlRegister; - BlpLdrProtocol.Debug.Print = BlDebugPrint; - BlpLdrProtocol.Disk.CloseVolume = BlCloseVolume; - BlpLdrProtocol.Disk.OpenVolume = BlOpenVolume; - BlpLdrProtocol.Disk.ReadFile = BlReadFile; + BlpLdrProtocol.Debug.Print = Debug::Print; + BlpLdrProtocol.Disk.CloseVolume = Volume::CloseVolume; + BlpLdrProtocol.Disk.OpenVolume = Volume::OpenVolume; + BlpLdrProtocol.Disk.ReadFile = Volume::ReadFile; BlpLdrProtocol.IoPort.Read8 = HL::IoPort::ReadPort8; BlpLdrProtocol.IoPort.Read16 = HL::IoPort::ReadPort16; BlpLdrProtocol.IoPort.Read32 = HL::IoPort::ReadPort32; @@ -904,54 +1055,54 @@ BlpInstallXtLoaderProtocol() BlpLdrProtocol.LinkedList.InsertHead = RTL::LinkedList::InsertHeadList; BlpLdrProtocol.LinkedList.InsertTail = RTL::LinkedList::InsertTailList; BlpLdrProtocol.LinkedList.RemoveEntry = RTL::LinkedList::RemoveEntryList; - BlpLdrProtocol.Memory.AllocatePages = BlAllocateMemoryPages; - BlpLdrProtocol.Memory.AllocatePool = BlAllocateMemoryPool; - BlpLdrProtocol.Memory.BuildPageMap = BlBuildPageMap; + BlpLdrProtocol.Memory.AllocatePages = Memory::AllocatePages; + BlpLdrProtocol.Memory.AllocatePool = Memory::AllocatePool; + BlpLdrProtocol.Memory.BuildPageMap = Memory::BuildPageMap; BlpLdrProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory; BlpLdrProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory; - BlpLdrProtocol.Memory.FreePages = BlFreeMemoryPages; - BlpLdrProtocol.Memory.FreePool = BlFreeMemoryPool; - BlpLdrProtocol.Memory.GetMappingsCount = BlGetMappingsCount; - BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap; - BlpLdrProtocol.Memory.GetVirtualAddress = BlGetVirtualAddress; - BlpLdrProtocol.Memory.InitializePageMap = BlInitializePageMap; - BlpLdrProtocol.Memory.MapEfiMemory = BlMapEfiMemory; - BlpLdrProtocol.Memory.MapPage = BlMapPage; - BlpLdrProtocol.Memory.MapVirtualMemory = BlMapVirtualMemory; + BlpLdrProtocol.Memory.FreePages = Memory::FreePages; + BlpLdrProtocol.Memory.FreePool = Memory::FreePool; + BlpLdrProtocol.Memory.GetMappingsCount = Memory::GetMappingsCount; + BlpLdrProtocol.Memory.GetMemoryMap = Memory::GetMemoryMap; + BlpLdrProtocol.Memory.GetVirtualAddress = Memory::GetVirtualAddress; + BlpLdrProtocol.Memory.InitializePageMap = Memory::InitializePageMap; + BlpLdrProtocol.Memory.MapEfiMemory = Memory::MapEfiMemory; + BlpLdrProtocol.Memory.MapPage = Memory::MapPage; + BlpLdrProtocol.Memory.MapVirtualMemory = Memory::MapVirtualMemory; BlpLdrProtocol.Memory.MoveMemory = RTL::Memory::MoveMemory; - BlpLdrProtocol.Memory.PhysicalAddressToVirtual = BlPhysicalAddressToVirtual; - BlpLdrProtocol.Memory.PhysicalListToVirtual = BlPhysicalListToVirtual; + BlpLdrProtocol.Memory.PhysicalAddressToVirtual = Memory::PhysicalAddressToVirtual; + BlpLdrProtocol.Memory.PhysicalListToVirtual = Memory::PhysicalListToVirtual; BlpLdrProtocol.Memory.SetMemory = RTL::Memory::SetMemory; BlpLdrProtocol.Memory.ZeroMemory = RTL::Memory::ZeroMemory; - BlpLdrProtocol.Protocol.Close = BlCloseProtocol; - BlpLdrProtocol.Protocol.GetModulesList = BlGetModulesList; - BlpLdrProtocol.Protocol.Install = BlInstallProtocol; - BlpLdrProtocol.Protocol.LocateHandles = BlLocateProtocolHandles; - BlpLdrProtocol.Protocol.Open = BlOpenProtocol; - BlpLdrProtocol.Protocol.OpenHandle = BlOpenProtocolHandle; + BlpLdrProtocol.Protocol.Close = CloseProtocol; + BlpLdrProtocol.Protocol.GetModulesList = GetModulesList; + BlpLdrProtocol.Protocol.Install = InstallProtocol; + BlpLdrProtocol.Protocol.LocateHandles = LocateProtocolHandles; + BlpLdrProtocol.Protocol.Open = OpenProtocol; + BlpLdrProtocol.Protocol.OpenHandle = OpenProtocolHandle; BlpLdrProtocol.String.Compare = RTL::String::CompareString; BlpLdrProtocol.String.Length = RTL::String::StringLength; BlpLdrProtocol.String.ToWideString = RTL::String::StringToWideString; BlpLdrProtocol.String.Trim = RTL::String::TrimString; - BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; - BlpLdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; - BlpLdrProtocol.Tui.DisplayInputDialog = BlDisplayInputDialog; - BlpLdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; - BlpLdrProtocol.Tui.UpdateProgressBar = BlUpdateProgressBar; - BlpLdrProtocol.Util.EnterFirmwareSetup = BlEnterFirmwareSetup; - BlpLdrProtocol.Util.ExitBootServices = BlExitBootServices; - BlpLdrProtocol.Util.GetConfigurationTable = BlGetConfigurationTable; - BlpLdrProtocol.Util.GetEfiVariable = BlGetEfiVariable; - BlpLdrProtocol.Util.GetRandomValue = BlGetRandomValue; - BlpLdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus; - BlpLdrProtocol.Util.InitializeEntropy = BlInitializeEntropy; - BlpLdrProtocol.Util.LoadEfiImage = BlLoadEfiImage; - BlpLdrProtocol.Util.RebootSystem = BlRebootSystem; - BlpLdrProtocol.Util.SetEfiVariable = BlSetEfiVariable; - BlpLdrProtocol.Util.ShutdownSystem = BlShutdownSystem; - BlpLdrProtocol.Util.SleepExecution = BlSleepExecution; - BlpLdrProtocol.Util.StartEfiImage = BlStartEfiImage; - BlpLdrProtocol.Util.WaitForEfiEvent = BlWaitForEfiEvent; + BlpLdrProtocol.Tui.DisplayErrorDialog = TextUi::DisplayErrorDialog; + BlpLdrProtocol.Tui.DisplayInfoDialog = TextUi::DisplayInfoDialog; + BlpLdrProtocol.Tui.DisplayInputDialog = TextUi::DisplayInputDialog; + BlpLdrProtocol.Tui.DisplayProgressDialog = TextUi::DisplayProgressDialog; + BlpLdrProtocol.Tui.UpdateProgressBar = TextUi::UpdateProgressBar; + BlpLdrProtocol.Utils.EnterFirmwareSetup = EfiUtils::EnterFirmwareSetup; + BlpLdrProtocol.Utils.ExitBootServices = EfiUtils::ExitBootServices; + BlpLdrProtocol.Utils.GetConfigurationTable = EfiUtils::GetConfigurationTable; + BlpLdrProtocol.Utils.GetEfiVariable = EfiUtils::GetEfiVariable; + BlpLdrProtocol.Utils.GetRandomValue = EfiUtils::GetRandomValue; + BlpLdrProtocol.Utils.GetSecureBootStatus = EfiUtils::GetSecureBootStatus; + BlpLdrProtocol.Utils.InitializeEntropy = EfiUtils::InitializeEntropy; + BlpLdrProtocol.Utils.LoadEfiImage = EfiUtils::LoadEfiImage; + BlpLdrProtocol.Utils.RebootSystem = EfiUtils::RebootSystem; + BlpLdrProtocol.Utils.SetEfiVariable = EfiUtils::SetEfiVariable; + BlpLdrProtocol.Utils.ShutdownSystem = EfiUtils::ShutdownSystem; + BlpLdrProtocol.Utils.SleepExecution = EfiUtils::SleepExecution; + BlpLdrProtocol.Utils.StartEfiImage = EfiUtils::StartEfiImage; + BlpLdrProtocol.Utils.WaitForEfiEvent = EfiUtils::WaitForEfiEvent; BlpLdrProtocol.WideString.Compare = RTL::WideString::CompareWideString; BlpLdrProtocol.WideString.CompareInsensitive = RTL::WideString::CompareWideStringInsensitive; BlpLdrProtocol.WideString.Concatenate = RTL::WideString::ConcatenateWideString; @@ -960,6 +1111,6 @@ BlpInstallXtLoaderProtocol() BlpLdrProtocol.WideString.Tokenize = RTL::WideString::TokenizeWideString; /* Register XTLDR loader protocol */ - BlDebugPrint(L"Registering XT loader protocol\n"); - return BlInstallProtocol(&BlpLdrProtocol, &Guid); + Debug::Print(L"Registering XT loader protocol\n"); + return InstallProtocol(&BlpLdrProtocol, &Guid); } diff --git a/xtldr/shell.cc b/xtldr/shell.cc index eb86649..1e9c6cd 100644 --- a/xtldr/shell.cc +++ b/xtldr/shell.cc @@ -18,13 +18,13 @@ */ XTCDECL VOID -BlStartLoaderShell() +Shell::StartLoaderShell() { /* Initialize console */ - BlInitializeConsole(); + Console::InitializeConsole(); /* Print prompt */ - BlpPrintShellPrompt(); + PrintPrompt(); for(;;); } @@ -37,14 +37,14 @@ BlStartLoaderShell() */ XTCDECL VOID -BlpPrintShellPrompt() +Shell::PrintPrompt() { /* Set prompt color */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW); /* Print prompt */ - BlConsolePrint(L"XTLDR> "); + Console::Print(L"XTLDR> "); /* Reset standard shell colors */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); } diff --git a/xtldr/textui.cc b/xtldr/textui.cc index 66c5004..a6c1373 100644 --- a/xtldr/textui.cc +++ b/xtldr/textui.cc @@ -10,6 +10,126 @@ #include +/** + * Determines dialog box size based on enabled components and message length. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Message + * Supplies a pointer to the message string put on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +TextUi::DetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Message) +{ + UINT_PTR Width, Height, LineLength; + SIZE_T Index, MessageLength; + UCHAR Attributes; + ULONG Mask; + + /* Set minimum dialog window size */ + Height = 4; + Width = 36; + + /* Zero line length */ + LineLength = 0; + + /* Adjust window height according to enabled components */ + Mask = 1; + Attributes = Handle->Attributes; + while(Mask) + { + /* Check enabled components that affect dialog window size */ + switch(Attributes & Mask) + { + case XTBL_TUI_DIALOG_ACTIVE_BUTTON: + case XTBL_TUI_DIALOG_INACTIVE_BUTTON: + Height += 1; + break; + case XTBL_TUI_DIALOG_ACTIVE_INPUT: + case XTBL_TUI_DIALOG_INACTIVE_INPUT: + case XTBL_TUI_DIALOG_PROGRESS_BAR: + Height += 2; + break; + } + + /* Update component attributes mask */ + Attributes &= ~Mask; + Mask <<= 1; + } + + /* Check if input field is active */ + if(Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT)) + { + /* Set maximum dialog window width to fit input field */ + Width = XTBL_TUI_MAX_DIALOG_WIDTH; + } + + /* Get message length and count dialog window dimensions */ + MessageLength = RTL::WideString::WideStringLength(Message, 0); + for(Index = 0; Index < MessageLength; Index++) + { + /* Check if this is multiline message */ + if(Message[Index] == L'\n' || Index == MessageLength - 1) + { + /* Check if this line exceeds current dialog window width */ + if(LineLength > Width) + { + /* Update dialog window width */ + Width = LineLength; + } + + /* Increase dialog window height to fit next line */ + Height++; + LineLength = 0; + } + else + { + /* Increase dialog window width to fit next character */ + LineLength++; + } + } + + /* Add more space to dialog window to fit side borders */ + Width += 4; + + /* Get console resolution */ + Console::QueryMode(&Handle->ResX, &Handle->ResY); + + /* Make sure dialog window fits in the buffer */ + if(Width > XTBL_TUI_MAX_DIALOG_WIDTH) + { + /* Set maximum dialog window width */ + Width = XTBL_TUI_MAX_DIALOG_WIDTH; + } + + /* Make sure dialog window fits on the screen (X axis) and it is not too small for input field */ + if(Width > (Handle->ResX - 2)) + { + /* Set maximum dialog window width */ + Width = Handle->ResX - 2; + } + + /* Make sure dialog window fits on the screen (Y axis)*/ + if(Height > (Handle->ResY - 2)) + { + /* Set maximum dialog window height */ + Height = Handle->ResY - 2; + } + + /* Set dialog window final dimensions */ + Handle->PosX = (Handle->ResX - Width) / 2; + Handle->PosY = (Handle->ResY - Height) / 2; + Handle->Width = Width; + Handle->Height = Height; +} + /** * Displays a simple TUI-based boot menu. * @@ -19,7 +139,7 @@ */ XTCDECL VOID -BlDisplayBootMenu() +TextUi::DisplayBootMenu() { XTBL_DIALOG_HANDLE Handle; PXTBL_BOOTMENU_ITEM MenuEntries = NULLPTR; @@ -35,11 +155,11 @@ BlDisplayBootMenu() PWCHAR TimeOutString; /* Draw boot menu */ - BlpDrawBootMenu(&Handle); + DrawBootMenu(&Handle); /* Initialize boot menu list */ TopVisibleEntry = 0; - Status = BlInitializeBootMenuList(Handle.Width - 4, &MenuEntries, &NumberOfEntries, &HighligtedEntryId); + Status = XtLoader::InitializeBootMenuList(Handle.Width - 4, &MenuEntries, &NumberOfEntries, &HighligtedEntryId); if(Status != STATUS_EFI_SUCCESS) { /* Failed to initialize boot menu list, exit into XTLDR shell */ @@ -57,7 +177,7 @@ BlDisplayBootMenu() } /* Get timeout from the configuration */ - BlGetConfigValue(L"TIMEOUT", &TimeOutString); + Configuration::GetValue(L"TIMEOUT", &TimeOutString); TimeOut = -1; /* Check if timeout is specified */ @@ -83,7 +203,7 @@ BlDisplayBootMenu() /* Redraw boot menu frame if requested */ if(RedrawBootMenu) { - BlpDrawBootMenu(&Handle); + DrawBootMenu(&Handle); RedrawBootMenu = FALSE; RedrawEntries = TRUE; } @@ -104,8 +224,8 @@ BlDisplayBootMenu() for(Index = 0; Index < VisibleEntries; Index++) { /* Draw menu entry */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[TopVisibleEntry + Index].EntryName, - Index, (BOOLEAN)((TopVisibleEntry + Index) == HighligtedEntryId)); + DrawBootMenuEntry(&Handle, MenuEntries[TopVisibleEntry + Index].EntryName, + Index, (BOOLEAN)((TopVisibleEntry + Index) == HighligtedEntryId)); } /* Clear redraw entries flag */ @@ -115,7 +235,7 @@ BlDisplayBootMenu() else { /* No menu entries found, show error message */ - BlDisplayErrorDialog(L"XTLDR", L"No boot menu entries found in the configuration. Falling back to shell."); + DisplayErrorDialog(L"XTLDR", L"No boot menu entries found in the configuration. Falling back to shell."); /* Exit into XTLDR shell */ return; @@ -150,7 +270,7 @@ BlDisplayBootMenu() while(TRUE) { /* Wait for EFI event */ - BlWaitForEfiEvent(2, Events, &EventIndex); + EfiUtils::WaitForEfiEvent(2, Events, &EventIndex); /* Check which event was received */ if(EventIndex == 0) @@ -165,29 +285,29 @@ BlDisplayBootMenu() EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerCancel, 0); /* Remove the timer message */ - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); + Console::ClearLine(Handle.PosY + Handle.Height + 4); } /* Read key stroke */ - BlReadKeyStroke(&Key); + Console::ReadKeyStroke(&Key); if(Key.ScanCode == 0x03 || Key.UnicodeChar == 0x0D) { /* ENTER or RightArrow key pressed, boot the highlighted OS */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); + Console::SetAttributes(Handle.DialogColor | Handle.TextColor); + Console::ClearLine(Handle.PosY + Handle.Height + 4); + Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4); + Console::Print(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); /* Boot the highlighted (chosen) OS */ - Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, - MenuEntries[HighligtedEntryId].Options); + Status = Protocol::InvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, + MenuEntries[HighligtedEntryId].Options); if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", + Debug::Print(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntries[HighligtedEntryId].FullName, Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + DisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); RedrawBootMenu = TRUE; } @@ -213,10 +333,10 @@ BlDisplayBootMenu() } /* Redraw new highlighted entry and the old one */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName, - OldHighligtedEntryId - TopVisibleEntry, (BOOLEAN)FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, - HighligtedEntryId - TopVisibleEntry, (BOOLEAN)TRUE); + DrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName, + OldHighligtedEntryId - TopVisibleEntry, (BOOLEAN)FALSE); + DrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId - TopVisibleEntry, (BOOLEAN)TRUE); } } else if(Key.ScanCode == 0x02) @@ -238,10 +358,10 @@ BlDisplayBootMenu() } /* Redraw new highlighted entry and the old one */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName, - OldHighligtedEntryId - TopVisibleEntry, (BOOLEAN)FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, - HighligtedEntryId - TopVisibleEntry, (BOOLEAN)TRUE); + DrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName, + OldHighligtedEntryId - TopVisibleEntry, (BOOLEAN)FALSE); + DrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId - TopVisibleEntry, (BOOLEAN)TRUE); } } else if(Key.ScanCode == 0x09) @@ -271,21 +391,21 @@ BlDisplayBootMenu() else if(Key.ScanCode == 0x0B) { /* F1 key pressed, show help */ - BlDisplayInfoDialog(L"XTLDR", L"XTLDR, the XTOS Boot Loader for UEFI and EFI-based machines.\n" - L" \n" - L"Use arrow keys (Up/Down) to change the highlighted entry and\n" - L"PgUp/PgDown keys to jump to the first/last position.\n" - L" \n" - L"Press ENTER key to boot the highlighted boot menu entry.\n" - L"Press 'e' key to edit the highlighted menu entry.\n" - L"Press 's' key to exit into XTLDR shell (enters advanced mode).\n" - L" \n" - L"F1 shows this help, F10 reboots into UEFI firmware interface,\n" - L"F11 reboots the machine and F12 turns it off.\n" - L" \n" - L" \n" - L"XTLDR is a part of the ExectOS Operating System.\n" - L"Visit https://exectos.eu.org/ for more information."); + DisplayInfoDialog(L"XTLDR", L"XTLDR, the XTOS Boot Loader for UEFI and EFI-based machines.\n" + L" \n" + L"Use arrow keys (Up/Down) to change the highlighted entry and\n" + L"PgUp/PgDown keys to jump to the first/last position.\n" + L" \n" + L"Press ENTER key to boot the highlighted boot menu entry.\n" + L"Press 'e' key to edit the highlighted menu entry.\n" + L"Press 's' key to exit into XTLDR shell (enters advanced mode).\n" + L" \n" + L"F1 shows this help, F10 reboots into UEFI firmware interface,\n" + L"F11 reboots the machine and F12 turns it off.\n" + L" \n" + L" \n" + L"XTLDR is a part of the ExectOS Operating System.\n" + L"Visit https://exectos.eu.org/ for more information."); /* Break from boot menu event loop to redraw whole boot menu */ RedrawBootMenu = TRUE; @@ -294,8 +414,8 @@ BlDisplayBootMenu() else if(Key.ScanCode == 0x14) { /* F10 key pressed, reboot into UEFI setup interface */ - BlEnterFirmwareSetup(); - BlDisplayErrorDialog(L"XTLDR", L"Reboot into firmware setup interface not supported!"); + EfiUtils::EnterFirmwareSetup(); + DisplayErrorDialog(L"XTLDR", L"Reboot into firmware setup interface not supported!"); RedrawBootMenu = TRUE; /* Break from boot menu event loop to redraw whole boot menu */ @@ -304,8 +424,8 @@ BlDisplayBootMenu() else if(Key.ScanCode == 0x15) { /* F11 key pressed, reboot the machine */ - BlRebootSystem(); - BlDisplayErrorDialog(L"XTLDR", L"Failed to reboot the machine!"); + EfiUtils::RebootSystem(); + DisplayErrorDialog(L"XTLDR", L"Failed to reboot the machine!"); RedrawBootMenu = TRUE; /* Break from boot menu event loop to redraw whole boot menu */ @@ -314,8 +434,8 @@ BlDisplayBootMenu() else if(Key.ScanCode == 0x16) { /* F12 key pressed, shutdown the machine */ - BlShutdownSystem(); - BlDisplayErrorDialog(L"XTLDR", L"Failed to shutdown the machine!"); + EfiUtils::ShutdownSystem(); + DisplayErrorDialog(L"XTLDR", L"Failed to shutdown the machine!"); RedrawBootMenu = TRUE; /* Break from boot menu event loop to redraw whole boot menu */ @@ -324,7 +444,7 @@ BlDisplayBootMenu() else if(Key.UnicodeChar == 0x65) { /* 'e' key pressed, edit the highlighted entry */ - BlDisplayEditMenu(&MenuEntries[HighligtedEntryId]); + DisplayEditMenu(&MenuEntries[HighligtedEntryId]); RedrawBootMenu = TRUE; /* Break from boot menu event loop to redraw whole boot menu */ @@ -342,32 +462,32 @@ BlDisplayBootMenu() if(TimeOut > 0) { /* Update a message and decrease timeout value */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"The highlighted position will be booted automatically in %ld seconds.", TimeOut); + Console::SetAttributes(Handle.DialogColor | Handle.TextColor); + Console::ClearLine(Handle.PosY + Handle.Height + 4); + Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4); + Console::Print(L"The highlighted position will be booted automatically in %ld seconds.", TimeOut); TimeOut--; } else if(TimeOut == 0) { /* Time out expired, update a message */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); + Console::SetAttributes(Handle.DialogColor | Handle.TextColor); + Console::ClearLine(Handle.PosY + Handle.Height + 4); + Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4); + Console::Print(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); /* Disable the timer just in case booting OS fails */ TimeOut = -1; /* Boot the highlighted (default) OS */ - Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, - MenuEntries[HighligtedEntryId].Options); + Status = Protocol::InvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, + MenuEntries[HighligtedEntryId].Options); if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", + Debug::Print(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntries[HighligtedEntryId].FullName, Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + DisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); RedrawBootMenu = TRUE; } break; @@ -386,7 +506,7 @@ BlDisplayBootMenu() */ XTCDECL VOID -BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) +TextUi::DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) { ULONG HighligtedOptionId, Index, NumberOfOptions, OldHighligtedOptionId, TopVisibleEntry, VisibleEntries; XTBL_DIALOG_HANDLE Handle; @@ -398,10 +518,10 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) EFI_STATUS Status; /* Draw edit menu */ - BlpDrawEditMenu(&Handle); + DrawEditMenu(&Handle); /* Get the list of user editable options */ - BlGetEditableOptions(&EditableOptions, &NumberOfOptions); + Configuration::GetEditableOptions(&EditableOptions, &NumberOfOptions); /* Calculate how many entries can be visible in the menu box */ VisibleEntries = Handle.Height - 2; @@ -421,7 +541,7 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) /* Redraw edit menu frame if requested */ if(RedrawEditMenu) { - BlpDrawEditMenu(&Handle); + DrawEditMenu(&Handle); RedrawEditMenu = FALSE; RedrawEntries = TRUE; } @@ -439,14 +559,14 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) for(Index = 0; Index < VisibleEntries; Index++) { /* Draw menu entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[TopVisibleEntry + Index], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[TopVisibleEntry + Index], Value, Index, - (BOOLEAN)((TopVisibleEntry + Index) == HighligtedOptionId)); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[TopVisibleEntry + Index], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[TopVisibleEntry + Index], Value, Index, + (BOOLEAN)((TopVisibleEntry + Index) == HighligtedOptionId)); /* Free allocated value string if needed */ if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } } @@ -455,15 +575,15 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) } /* Wait for EFI event and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &EventIndex); - BlReadKeyStroke(&Key); + EfiUtils::WaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &EventIndex); + Console::ReadKeyStroke(&Key); /* Check key press scan code */ if(Key.UnicodeChar == 0x0D || Key.UnicodeChar == 0x65) { /* ENTER or 'e' key pressed, edit the highlighted option */ OptionName = EditableOptions[HighligtedOptionId]; - BlGetBootOptionValue(MenuEntry->Options, OptionName, &OriginalValue); + Configuration::GetBootOptionValue(MenuEntry->Options, OptionName, &OriginalValue); /* If the original value is NULLPTR, use an empty string for editing */ if(OriginalValue == NULLPTR) @@ -477,20 +597,20 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) /* Display input dialog to edit the option value */ NewValue = ValueToEdit; - BlDisplayInputDialog(OptionName, L"Enter new value:", &NewValue); + DisplayInputDialog(OptionName, L"Enter new value:", &NewValue); /* Check if the value was changed */ if(NewValue != ValueToEdit) { /* Update the boot option with the new value and free the old value */ - BlSetBootOptionValue(MenuEntry->Options, OptionName, NewValue); - BlFreeMemoryPool(NewValue); + Configuration::SetBootOptionValue(MenuEntry->Options, OptionName, NewValue); + Memory::FreePool(NewValue); } /* Free the original value if it was allocated */ if(OriginalValue != NULLPTR) { - BlFreeMemoryPool(OriginalValue); + Memory::FreePool(OriginalValue); } /* Mark the edit menu for redraw */ @@ -515,23 +635,23 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) } /* Redraw old highlighted entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, (BOOLEAN)FALSE); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, (BOOLEAN)FALSE); /* Free allocated value string if needed */ if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } /* Redraw new highlighted entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, (BOOLEAN)TRUE); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, (BOOLEAN)TRUE); /* Free allocated value string if needed */ if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } } } @@ -554,23 +674,23 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) } /* Redraw old highlighted entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, (BOOLEAN)FALSE); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, (BOOLEAN)FALSE); /* Free allocated value string if needed */ if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } /* Redraw new highlighted entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, (BOOLEAN)TRUE); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, (BOOLEAN)TRUE); /* Free allocated value string if needed */ if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } } } @@ -599,18 +719,18 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) else if(Key.UnicodeChar == 0x02) { /* CTRL-B key pressed, boot the OS */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...\n", MenuEntry->FullName); + Console::SetAttributes(Handle.DialogColor | Handle.TextColor); + Console::ClearLine(Handle.PosY + Handle.Height + 4); + Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4); + Console::Print(L"Booting '%S' now...\n", MenuEntry->FullName); /* Boot the OS */ - Status = BlInvokeBootProtocol(MenuEntry->ShortName, MenuEntry->Options); + Status = Protocol::InvokeBootProtocol(MenuEntry->ShortName, MenuEntry->Options); if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntry->FullName, Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + Debug::Print(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntry->FullName, Status); + DisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); RedrawEditMenu = TRUE; } @@ -640,8 +760,8 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) */ XTCDECL VOID -BlDisplayErrorDialog(IN PCWSTR Caption, - IN PCWSTR Message) +TextUi::DisplayErrorDialog(IN PCWSTR Caption, + IN PCWSTR Message) { XTBL_DIALOG_HANDLE Handle; EFI_INPUT_KEY Key; @@ -651,14 +771,14 @@ BlDisplayErrorDialog(IN PCWSTR Caption, Handle.Attributes = XTBL_TUI_DIALOG_ERROR_BOX | XTBL_TUI_DIALOG_ACTIVE_BUTTON; /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); + DetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); + Console::DisableCursor(); + DrawDialogBox(&Handle, Caption, Message); /* Draw active button */ - BlpDrawDialogButton(&Handle); + DrawButton(&Handle); /* Initialize key stroke */ Key.ScanCode = 0; @@ -668,14 +788,14 @@ BlDisplayErrorDialog(IN PCWSTR Caption, while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) { /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); - BlResetConsoleInputBuffer(); + EfiUtils::WaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + Console::ReadKeyStroke(&Key); + Console::ResetInputBuffer(); } /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::ClearScreen(); } /** @@ -693,8 +813,8 @@ BlDisplayErrorDialog(IN PCWSTR Caption, */ XTCDECL VOID -BlDisplayInfoDialog(IN PCWSTR Caption, - IN PCWSTR Message) +TextUi::DisplayInfoDialog(IN PCWSTR Caption, + IN PCWSTR Message) { XTBL_DIALOG_HANDLE Handle; EFI_INPUT_KEY Key; @@ -704,14 +824,14 @@ BlDisplayInfoDialog(IN PCWSTR Caption, Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_BUTTON; /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); + DetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); + Console::DisableCursor(); + DrawDialogBox(&Handle, Caption, Message); /* Draw active button */ - BlpDrawDialogButton(&Handle); + DrawButton(&Handle); /* Initialize key stroke */ Key.ScanCode = 0; @@ -721,14 +841,14 @@ BlDisplayInfoDialog(IN PCWSTR Caption, while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) { /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); - BlResetConsoleInputBuffer(); + EfiUtils::WaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + Console::ReadKeyStroke(&Key); + Console::ResetInputBuffer(); } /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::ClearScreen(); } /** @@ -749,9 +869,9 @@ BlDisplayInfoDialog(IN PCWSTR Caption, */ XTCDECL VOID -BlDisplayInputDialog(IN PCWSTR Caption, - IN PCWSTR Message, - IN OUT PWCHAR *InputFieldText) +TextUi::DisplayInputDialog(IN PCWSTR Caption, + IN PCWSTR Message, + IN OUT PWCHAR *InputFieldText) { SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition; XTBL_DIALOG_HANDLE Handle; @@ -764,17 +884,17 @@ BlDisplayInputDialog(IN PCWSTR Caption, Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_BUTTON; /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); + DetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); + Console::DisableCursor(); + DrawDialogBox(&Handle, Caption, Message); /* Draw inactive button */ - BlpDrawDialogButton(&Handle); + DrawButton(&Handle); /* Draw active input field */ - BlpDrawDialogInputField(&Handle, *InputFieldText); + DrawInputField(&Handle, *InputFieldText); /* Initialize key stroke */ Key.ScanCode = 0; @@ -784,12 +904,12 @@ BlDisplayInputDialog(IN PCWSTR Caption, InputFieldLength = RTL::WideString::WideStringLength(*InputFieldText, 0); /* Allocate a buffer for storing the input field text */ - Status = BlAllocateMemoryPool(2048 * sizeof(WCHAR), (PVOID *)&InputFieldBuffer); + Status = Memory::AllocatePool(2048 * sizeof(WCHAR), (PVOID *)&InputFieldBuffer); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, print error message and return */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to allocate memory for input field buffer."); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + DisplayErrorDialog(L"XTLDR", L"Failed to allocate memory for input field buffer."); return; } @@ -799,14 +919,14 @@ BlDisplayInputDialog(IN PCWSTR Caption, /* Start at first character */ TextPosition = 0; - BlSetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4); + Console::SetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4); /* Wait until ENTER or ESC key is pressed */ while(TRUE) { /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); + EfiUtils::WaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); + Console::ReadKeyStroke(&Key); /* Check key press scan code */ if(Key.ScanCode == 0x17) @@ -929,19 +1049,19 @@ BlDisplayInputDialog(IN PCWSTR Caption, } /* Redraw input field and button */ - BlpDrawDialogButton(&Handle); - BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]); + DrawButton(&Handle); + DrawInputField(&Handle, &InputFieldBuffer[TextIndex]); /* Set cursor position if input field is active */ if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { - BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); + Console::SetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); } } /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::ClearScreen(); } /** @@ -962,9 +1082,9 @@ BlDisplayInputDialog(IN PCWSTR Caption, */ XTCDECL XTBL_DIALOG_HANDLE -BlDisplayProgressDialog(IN PCWSTR Caption, - IN PCWSTR Message, - IN UCHAR Percentage) +TextUi::DisplayProgressDialog(IN PCWSTR Caption, + IN PCWSTR Message, + IN UCHAR Percentage) { XTBL_DIALOG_HANDLE Handle; @@ -972,172 +1092,19 @@ BlDisplayProgressDialog(IN PCWSTR Caption, Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_PROGRESS_BAR; /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); + DetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); + Console::DisableCursor(); + DrawDialogBox(&Handle, Caption, Message); /* Draw active button */ - BlpDrawDialogProgressBar(&Handle, Percentage); + DrawProgressBar(&Handle, Percentage); /* Return dialog handle */ return Handle; } -/** - * Updates the progress bar on the dialog box. - * - * @param Handle - * Supplies a pointer to the dialog box handle. - * - * @param Message - * Supplies a new message that will be put on the dialog box, while updating the progress bar. - * - * @param Percentage - * Specifies the new percentage progress of the progress bar. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN PCWSTR Message, - IN UCHAR Percentage) -{ - /* Check if message needs an update */ - if(Message != NULLPTR) - { - /* Update a message on the dialog box */ - BlpDrawDialogMessage(Handle, Message); - } - - /* Update progress bar */ - BlpDrawDialogProgressBar(Handle, Percentage); -} - -/** - * Determines dialog box size based on enabled components and message length. - * - * @param Handle - * Supplies a pointer to the dialog box handle. - * - * @param Message - * Supplies a pointer to the message string put on the dialog box. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, - IN PCWSTR Message) -{ - UINT_PTR Width, Height, LineLength; - SIZE_T Index, MessageLength; - UCHAR Attributes; - ULONG Mask; - - /* Set minimum dialog window size */ - Height = 4; - Width = 36; - - /* Zero line length */ - LineLength = 0; - - /* Adjust window height according to enabled components */ - Mask = 1; - Attributes = Handle->Attributes; - while(Mask) - { - /* Check enabled components that affect dialog window size */ - switch(Attributes & Mask) - { - case XTBL_TUI_DIALOG_ACTIVE_BUTTON: - case XTBL_TUI_DIALOG_INACTIVE_BUTTON: - Height += 1; - break; - case XTBL_TUI_DIALOG_ACTIVE_INPUT: - case XTBL_TUI_DIALOG_INACTIVE_INPUT: - case XTBL_TUI_DIALOG_PROGRESS_BAR: - Height += 2; - break; - } - - /* Update component attributes mask */ - Attributes &= ~Mask; - Mask <<= 1; - } - - /* Check if input field is active */ - if(Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT)) - { - /* Set maximum dialog window width to fit input field */ - Width = XTBL_TUI_MAX_DIALOG_WIDTH; - } - - /* Get message length and count dialog window dimensions */ - MessageLength = RTL::WideString::WideStringLength(Message, 0); - for(Index = 0; Index < MessageLength; Index++) - { - /* Check if this is multiline message */ - if(Message[Index] == L'\n' || Index == MessageLength - 1) - { - /* Check if this line exceeds current dialog window width */ - if(LineLength > Width) - { - /* Update dialog window width */ - Width = LineLength; - } - - /* Increase dialog window height to fit next line */ - Height++; - LineLength = 0; - } - else - { - /* Increase dialog window width to fit next character */ - LineLength++; - } - } - - /* Add more space to dialog window to fit side borders */ - Width += 4; - - /* Get console resolution */ - BlQueryConsoleMode(&Handle->ResX, &Handle->ResY); - - /* Make sure dialog window fits in the buffer */ - if(Width > XTBL_TUI_MAX_DIALOG_WIDTH) - { - /* Set maximum dialog window width */ - Width = XTBL_TUI_MAX_DIALOG_WIDTH; - } - - /* Make sure dialog window fits on the screen (X axis) and it is not too small for input field */ - if(Width > (Handle->ResX - 2)) - { - /* Set maximum dialog window width */ - Width = Handle->ResX - 2; - } - - /* Make sure dialog window fits on the screen (Y axis)*/ - if(Height > (Handle->ResY - 2)) - { - /* Set maximum dialog window height */ - Height = Handle->ResY - 2; - } - - /* Set dialog window final dimensions */ - Handle->PosX = (Handle->ResX - Width) / 2; - Handle->PosY = (Handle->ResY - Height) / 2; - Handle->Width = Width; - Handle->Height = Height; -} - /** * Draws a text UI-based boot menu. * @@ -1150,10 +1117,10 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle) +TextUi::DrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle) { /* Query console screen resolution */ - BlQueryConsoleMode(&Handle->ResX, &Handle->ResY); + Console::QueryMode(&Handle->ResX, &Handle->ResY); /* Set boot menu parameters */ Handle->Attributes = 0; @@ -1165,32 +1132,32 @@ BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle) Handle->Height = Handle->ResY - 10; /* Clear screen and disable cursor */ - BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); - BlClearConsoleScreen(); - BlDisableConsoleCursor(); + Console::SetAttributes(Handle->DialogColor | Handle->TextColor); + Console::ClearScreen(); + Console::DisableCursor(); /* Check if debugging enabled */ if(DEBUG) { /* Print debug version of XTLDR banner */ - BlSetCursorPosition((Handle->ResX - 44) / 2, 1); - BlConsolePrint(L"XTLDR Boot Loader v%d.%d (%s-%s)\n", + Console::SetCursorPosition((Handle->ResX - 44) / 2, 1); + Console::Print(L"XTLDR Boot Loader v%d.%d (%s-%s)\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH); } else { /* Print standard XTLDR banner */ - BlSetCursorPosition((Handle->ResX - 22) / 2, 1); - BlConsolePrint(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR); + Console::SetCursorPosition((Handle->ResX - 22) / 2, 1); + Console::Print(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR); } /* Draw empty dialog box for boot menu */ - BlpDrawDialogBox(Handle, NULLPTR, NULLPTR); + DrawDialogBox(Handle, NULLPTR, NULLPTR); /* Print help message below the boot menu */ - BlSetCursorPosition(0, Handle->PosY + Handle->Height); - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlConsolePrint(L" Use cursors to change the selection. Press ENTER key to boot the chosen\n" + Console::SetCursorPosition(0, Handle->PosY + Handle->Height); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::Print(L" Use cursors to change the selection. Press ENTER key to boot the chosen\n" L" Operating System, 'e' to edit it before booting or 's' for XTLDR shell.\n" L" Additional help available after pressing F1 key."); } @@ -1216,37 +1183,37 @@ BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle) */ XTCDECL VOID -BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR MenuEntry, - IN UINT Position, - IN BOOLEAN Highlighted) +TextUi::DrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR MenuEntry, + IN UINT Position, + IN BOOLEAN Highlighted) { UINT Index; /* Move cursor to the right position */ - BlSetCursorPosition(5, 4 + Position); + Console::SetCursorPosition(5, 4 + Position); /* Check whether this entry should be highlighted */ if(Highlighted) { /* Highlight this entry */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK); + Console::SetAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK); } else { /* Set default colors */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); } /* Clear menu entry */ for(Index = 0; Index < Handle->Width - 4; Index++) { - BlConsolePrint(L" "); + Console::Print(L" "); } /* Print menu entry */ - BlSetCursorPosition(5, 4 + Position); - BlConsolePrint(L"%S\n", MenuEntry); + Console::SetCursorPosition(5, 4 + Position); + Console::Print(L"%S\n", MenuEntry); } /** @@ -1267,9 +1234,9 @@ BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, - IN PCWSTR Caption, - IN PCWSTR Message) +TextUi::DrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Caption, + IN PCWSTR Message) { WCHAR BoxLine[XTBL_TUI_MAX_DIALOG_WIDTH]; SIZE_T CaptionLength; @@ -1290,13 +1257,13 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, } /* Set dialog box colors */ - BlSetConsoleAttributes(Handle->DialogColor | 0x0F); + Console::SetAttributes(Handle->DialogColor | 0x0F); /* Iterate through dialog box lines */ for(PosY = Handle->PosY; PosY < Handle->PosY + Handle->Height; PosY++) { /* Set cursor position in the appropriate place */ - BlSetCursorPosition(Handle->PosX, PosY); + Console::SetCursorPosition(Handle->PosX, PosY); /* Draw dialog box */ if(PosY == Handle->PosY) @@ -1370,22 +1337,22 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, BoxLine[Handle->Width] = 0; /* Write the line to the console */ - BlConsoleWrite(BoxLine); + Console::Write(BoxLine); } /* Make sure there is a caption to print */ if(Caption != NULLPTR) { /* Write dialog box caption */ - BlSetCursorPosition(Handle->PosX + 3, Handle->PosY); - BlConsolePrint(L"%S", Caption); + Console::SetCursorPosition(Handle->PosX + 3, Handle->PosY); + Console::Print(L"%S", Caption); } /* Make sure there is a message to print */ if(Message != NULLPTR) { /* Write a message on the dialog box */ - BlpDrawDialogMessage(Handle, Message); + DrawMessage(Handle, Message); } } @@ -1401,7 +1368,7 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) +TextUi::DrawButton(IN PXTBL_DIALOG_HANDLE Handle) { ULONG ButtonColor, TextColor; @@ -1430,10 +1397,10 @@ BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) } /* Disable cursor and draw dialog button */ - BlDisableConsoleCursor(); - BlSetConsoleAttributes(ButtonColor | TextColor); - BlSetCursorPosition(Handle->ResX / 2 - 4, Handle->PosY + Handle->Height - 2); - BlConsolePrint(L"[ OK ]"); + Console::DisableCursor(); + Console::SetAttributes(ButtonColor | TextColor); + Console::SetCursorPosition(Handle->ResX / 2 - 4, Handle->PosY + Handle->Height - 2); + Console::Print(L"[ OK ]"); } /** @@ -1451,8 +1418,8 @@ BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) */ XTCDECL VOID -BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR InputFieldText) +TextUi::DrawInputField(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR InputFieldText) { WCHAR InputField[XTBL_TUI_MAX_DIALOG_WIDTH]; ULONG InputColor, TextColor; @@ -1484,9 +1451,9 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, } /* Set progress bar color and position */ - BlSetConsoleAttributes(InputColor | TextColor); + Console::SetAttributes(InputColor | TextColor); Position = (Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; - BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); + Console::SetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); /* Draw input field */ for(Index = 0; Index < Handle->Width - 8; Index++) @@ -1496,8 +1463,8 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, } /* Disable cursor and write input field to console */ - BlDisableConsoleCursor(); - BlConsoleWrite(InputField); + Console::DisableCursor(); + Console::Write(InputField); /* Check input field text length */ Length = RTL::WideString::WideStringLength(InputFieldText, 0); @@ -1518,14 +1485,14 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, InputField[Handle->Width] = 0; /* Write input field text */ - BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); - BlConsoleWrite(InputField); + Console::SetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); + Console::Write(InputField); /* Check if this is an active input field */ if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { /* Enable cursor for active input field */ - BlEnableConsoleCursor(); + Console::EnableCursor(); } } @@ -1544,8 +1511,8 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, - IN PCWSTR Message) +TextUi::DrawMessage(IN PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Message) { PWCHAR Msg, MsgLine, LastMsgLine; SIZE_T Index, Length, LineLength; @@ -1554,11 +1521,11 @@ BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, /* Allocate memory for dialog box message */ Length = RTL::WideString::WideStringLength(Message, 0); - Status = BlAllocateMemoryPool(Length * sizeof(WCHAR), (PVOID *)&Msg); + Status = Memory::AllocatePool(Length * sizeof(WCHAR), (PVOID *)&Msg); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, print debug message and return */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); return; } @@ -1577,9 +1544,9 @@ BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, LineLength = RTL::WideString::WideStringLength(MsgLine, 0); /* Write line in the dialog box */ - BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); - BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); - BlConsolePrint(L"%S", MsgLine); + Console::SetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); + Console::SetAttributes(Handle->DialogColor | Handle->TextColor); + Console::Print(L"%S", MsgLine); /* Check if message line is shorter than the dialog box working area */ if(LineLength < Handle->Width - 4) @@ -1587,7 +1554,7 @@ BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, /* Fill the rest of the line with spaces */ for(Index = LineLength; Index < Handle->Width - 4; Index++) { - BlConsolePrint(L" "); + Console::Print(L" "); } } @@ -1612,8 +1579,8 @@ BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN UCHAR Percentage) +TextUi::DrawProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN UCHAR Percentage) { UINT_PTR Index, ProgressLength, ProgressBarLength; WCHAR ProgressBar[XTBL_TUI_MAX_DIALOG_WIDTH]; @@ -1624,9 +1591,9 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, ProgressLength = (ProgressBarLength * Percentage) / 100; /* Set progress bar color and position */ - BlSetConsoleAttributes(EFI_TEXT_FGCOLOR_YELLOW); + Console::SetAttributes(EFI_TEXT_FGCOLOR_YELLOW); Position = (Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; - BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); + Console::SetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); /* Draw progress bar */ for(Index = 0; Index < ProgressBarLength; Index++) @@ -1648,8 +1615,8 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, ProgressBar[Index] = 0; /* Disable cursor and write progress bar to console */ - BlDisableConsoleCursor(); - BlConsoleWrite(ProgressBar); + Console::DisableCursor(); + Console::Write(ProgressBar); } /** @@ -1664,10 +1631,10 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle) +TextUi::DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle) { /* Query console screen resolution */ - BlQueryConsoleMode(&Handle->ResX, &Handle->ResY); + Console::QueryMode(&Handle->ResX, &Handle->ResY); /* Set boot menu parameters */ Handle->Attributes = 0; @@ -1679,32 +1646,32 @@ BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle) Handle->Height = Handle->ResY - 10; /* Clear screen and disable cursor */ - BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); - BlClearConsoleScreen(); - BlDisableConsoleCursor(); + Console::SetAttributes(Handle->DialogColor | Handle->TextColor); + Console::ClearScreen(); + Console::DisableCursor(); /* Check if debugging enabled */ if(DEBUG) { /* Print debug version of XTLDR banner */ - BlSetCursorPosition((Handle->ResX - 44) / 2, 1); - BlConsolePrint(L"XTLDR Boot Loader v%d.%d (%s-%s)\n", + Console::SetCursorPosition((Handle->ResX - 44) / 2, 1); + Console::Print(L"XTLDR Boot Loader v%d.%d (%s-%s)\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH); } else { /* Print standard XTLDR banner */ - BlSetCursorPosition((Handle->ResX - 22) / 2, 1); - BlConsolePrint(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR); + Console::SetCursorPosition((Handle->ResX - 22) / 2, 1); + Console::Print(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR); } /* Draw empty dialog box for boot menu */ - BlpDrawDialogBox(Handle, L"Edit Options", NULLPTR); + DrawDialogBox(Handle, L"Edit Options", NULLPTR); /* Print help message below the edit menu */ - BlSetCursorPosition(0, Handle->PosY + Handle->Height); - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlConsolePrint(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n" + Console::SetCursorPosition(0, Handle->PosY + Handle->Height); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::Print(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n" L" option, ESC to return to the main boot menu or CTRL-B to boot.\n"); } @@ -1732,11 +1699,11 @@ BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle) */ XTCDECL EFI_STATUS -BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, - IN PCWSTR OptionName, - IN PCWSTR OptionValue, - IN UINT Position, - IN BOOLEAN Highlighted) +TextUi::DrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR OptionName, + IN PCWSTR OptionValue, + IN UINT Position, + IN BOOLEAN Highlighted) { BOOLEAN Allocation; PCWSTR DisplayValue, ShortValue; @@ -1759,11 +1726,11 @@ BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, if(OptionValueLength > OptionWidth) { /* Allocate buffer for new, shortened value */ - Status = BlAllocateMemoryPool((OptionWidth + 1) * sizeof(WCHAR), (PVOID *)&ShortValue); // This allocates PWCHAR + Status = Memory::AllocatePool((OptionWidth + 1) * sizeof(WCHAR), (PVOID *)&ShortValue); // This allocates PWCHAR if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, print debug message and return */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); return Status; } @@ -1778,37 +1745,70 @@ BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, } /* Move cursor to the right position */ - BlSetCursorPosition(5, 4 + Position); + Console::SetCursorPosition(5, 4 + Position); /* Check whether this entry should be highlighted */ if(Highlighted) { /* Highlight this entry */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK); + Console::SetAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK); } else { /* Set default colors */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); } /* Clear menu entry */ for(Index = 0; Index < Handle->Width - 4; Index++) { - BlConsolePrint(L" "); + Console::Print(L" "); } /* Print menu entry */ - BlSetCursorPosition(5, 4 + Position); - BlConsolePrint(L"%S: %S", OptionName, DisplayValue); + Console::SetCursorPosition(5, 4 + Position); + Console::Print(L"%S: %S", OptionName, DisplayValue); /* Check if allocation was made */ if(Allocation) { /* Free allocated memory */ - BlFreeMemoryPool((PVOID)DisplayValue); + Memory::FreePool((PVOID)DisplayValue); } /* Return success */ return STATUS_EFI_SUCCESS; } + +/** + * Updates the progress bar on the dialog box. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Message + * Supplies a new message that will be put on the dialog box, while updating the progress bar. + * + * @param Percentage + * Specifies the new percentage progress of the progress bar. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +TextUi::UpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Message, + IN UCHAR Percentage) +{ + /* Check if message needs an update */ + if(Message != NULLPTR) + { + /* Update a message on the dialog box */ + DrawMessage(Handle, Message); + } + + /* Update progress bar */ + DrawProgressBar(Handle, Percentage); +} diff --git a/xtldr/volume.cc b/xtldr/volume.cc index e1293ea..3cf4857 100644 --- a/xtldr/volume.cc +++ b/xtldr/volume.cc @@ -22,7 +22,7 @@ */ XTCDECL EFI_STATUS -BlCloseVolume(IN PEFI_HANDLE VolumeHandle) +Volume::CloseVolume(IN PEFI_HANDLE VolumeHandle) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; @@ -46,7 +46,7 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle) */ XTCDECL EFI_STATUS -BlEnumerateBlockDevices() +Volume::EnumerateBlockDevices() { EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; @@ -72,7 +72,7 @@ BlEnumerateBlockDevices() if(Status != STATUS_EFI_SUCCESS) { /* Failed to get boot device handle */ - BlDebugPrint(L"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\n", Status); return Status; } @@ -84,10 +84,10 @@ BlEnumerateBlockDevices() RTL::LinkedList::InitializeListHead(&EfiBlockDevices); /* Discover EFI block devices and store them in linked list */ - Status = BlpDiscoverEfiBlockDevices(&BlockDevices); + Status = DiscoverEfiBlockDevices(&BlockDevices); if(Status != STATUS_EFI_SUCCESS) { - BlDebugPrint(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status); return Status; } @@ -100,11 +100,11 @@ BlEnumerateBlockDevices() PartitionGuid = NULLPTR; /* Find last node */ - Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); + Status = FindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); if(Status != STATUS_EFI_SUCCESS) { /* Skip this device if its last node cannot be found, as it is required for classification */ - BlDebugPrint(L"WARNING: Block device last node not found\n"); + Debug::Print(L"WARNING: Block device last node not found\n"); ListEntry = ListEntry->Flink; continue; } @@ -113,10 +113,10 @@ BlEnumerateBlockDevices() DriveType = XTBL_BOOT_DEVICE_UNKNOWN; /* Locate the parent for this block device to ensure it is not an orphaned entry */ - if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode)) + if(!FindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode)) { /* Orphaned device found. Log a warning and skip it as it cannot be properly classified */ - BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n"); + Debug::Print(L"WARNING: No parent device found, skipping orphaned media device path\n"); ListEntry = ListEntry->Flink; continue; } @@ -125,7 +125,7 @@ BlEnumerateBlockDevices() if(!BlockDeviceData->BlockIo->Media) { /* The device is unusable without media info, log a warning and skip it */ - BlDebugPrint(L"WARNING: Block device is missing media information\n"); + Debug::Print(L"WARNING: Block device is missing media information\n"); ListEntry = ListEntry->Flink; continue; } @@ -144,7 +144,7 @@ BlEnumerateBlockDevices() PartitionNumber = 0; /* Print debug message */ - BlDebugPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n", + Debug::Print(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n", DriveNumber, Media->MediaPresent, Media->ReadOnly); } } @@ -159,7 +159,7 @@ BlEnumerateBlockDevices() PartitionNumber = 0; /* Print debug message */ - BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", + Debug::Print(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly); } else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP) @@ -175,7 +175,7 @@ BlEnumerateBlockDevices() if(BootDeviceHandle != NULLPTR) { /* Allocate memory for device path */ - DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); + DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath); if(DevicePath != NULLPTR) { /* Check if this is the boot device */ @@ -190,7 +190,7 @@ BlEnumerateBlockDevices() } /* Print debug message */ - BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " + Debug::Print(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " L"MBRType: %u, GUID: {%V}, PartSize: %lluB) %S\n", DriveNumber, PartitionNumber, HDPath->MBRType, PartitionGuid, HDPath->PartitionSize * Media->BlockSize, @@ -204,7 +204,7 @@ BlEnumerateBlockDevices() PartitionNumber = 0; /* Print debug message */ - BlDebugPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n", + Debug::Print(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n", DriveNumber, Media->MediaPresent); } @@ -212,15 +212,15 @@ BlEnumerateBlockDevices() if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN) { /* Allocate memory for block device */ - Status = BlAllocateMemoryPool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); + Status = Memory::AllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); if(Status != STATUS_EFI_SUCCESS) { - BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); return STATUS_EFI_OUT_OF_RESOURCES; } /* Initialize block device */ - BlockDevice->DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); + BlockDevice->DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath); BlockDevice->DriveType = DriveType; BlockDevice->DriveNumber = DriveNumber; BlockDevice->PartitionNumber = PartitionNumber; @@ -256,7 +256,7 @@ BlEnumerateBlockDevices() */ XTCDECL EFI_STATUS -BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, +Volume::FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, IN CONST PWCHAR FileSystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath) { @@ -294,7 +294,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, FsPathLength = RTL::WideString::WideStringLength(FileSystemPath, 0) * sizeof(WCHAR); /* Allocate memory pool for device path */ - Status = BlAllocateMemoryPool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL), + Status = Memory::AllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL), (PVOID *)DevicePath); if(Status != STATUS_EFI_SUCCESS) { @@ -337,8 +337,8 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, */ XTCDECL EFI_STATUS -BlGetEfiPath(IN PWCHAR SystemPath, - OUT PWCHAR *EfiPath) +Volume::GetEfiPath(IN PWCHAR SystemPath, + OUT PWCHAR *EfiPath) { SIZE_T Index, PathLength; EFI_STATUS Status; @@ -347,11 +347,11 @@ BlGetEfiPath(IN PWCHAR SystemPath, PathLength = RTL::WideString::WideStringLength(SystemPath, 0); /* Allocate memory for storing EFI path */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (PathLength + 1), (PVOID *)EfiPath); + Status = Memory::AllocatePool(sizeof(WCHAR) * (PathLength + 1), (PVOID *)EfiPath); if(Status != STATUS_EFI_SUCCESS) { /* Failed to allocate memory, print error message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); return STATUS_EFI_OUT_OF_RESOURCES; } @@ -390,7 +390,7 @@ BlGetEfiPath(IN PWCHAR SystemPath, */ XTCDECL EFI_STATUS -BlGetVolumeDevicePath(IN PWCHAR SystemPath, +Volume::GetDevicePath(IN PWCHAR SystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT PWCHAR *ArcName, OUT PWCHAR *Path) @@ -429,13 +429,13 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, if(PathLength == GUID_STRING_LENGTH) { /* This is EFI GUID */ - BlDebugPrint(L"WARNING: EFI/GPT GUID in system path is not supported\n"); + Debug::Print(L"WARNING: EFI/GPT GUID in system path is not supported\n"); return STATUS_EFI_UNSUPPORTED; } else if(PathLength == PARTUUID_STRING_LENGTH) { /* This is MBR UUID */ - BlDebugPrint(L"WARNING: MBR partition UUID in system path is not supported\n"); + Debug::Print(L"WARNING: MBR partition UUID in system path is not supported\n"); return STATUS_EFI_UNSUPPORTED; } else @@ -447,14 +447,14 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, else { /* Defaults to ARC path, dissect it */ - Status = BlpDissectVolumeArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber); + Status = DissectArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber); } /* Check if volume path parsed successfully */ if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse system path */ - BlDebugPrint(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%zX)\n", SystemPath, Status); + Debug::Print(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%zX)\n", SystemPath, Status); return Status; } @@ -492,7 +492,7 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, if(*DevicePath == NULLPTR) { /* Volume not found */ - BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", + Debug::Print(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", DriveType, DriveNumber, PartNumber); return STATUS_EFI_NOT_FOUND; } @@ -519,9 +519,9 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, */ XTCDECL EFI_STATUS -BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_HANDLE DiskHandle, - OUT PEFI_FILE_HANDLE *FsHandle) +Volume::OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_HANDLE DiskHandle, + OUT PEFI_FILE_HANDLE *FsHandle) { EFI_GUID SFSGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; @@ -563,7 +563,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, if(Status != STATUS_EFI_SUCCESS) { /* Failed to open the filesystem protocol, close volume */ - BlCloseVolume(DiskHandle); + CloseVolume(DiskHandle); return Status; } @@ -572,7 +572,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, if(Status != STATUS_EFI_SUCCESS) { /* Failed to open the filesystem, close volume */ - BlCloseVolume(DiskHandle); + CloseVolume(DiskHandle); return Status; } @@ -601,10 +601,10 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, */ XTCDECL EFI_STATUS -BlReadFile(IN PEFI_FILE_HANDLE DirHandle, - IN PCWSTR FileName, - OUT PVOID *FileData, - OUT PSIZE_T FileSize) +Volume::ReadFile(IN PEFI_FILE_HANDLE DirHandle, + IN PCWSTR FileName, + OUT PVOID *FileData, + OUT PSIZE_T FileSize) { EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID; EFI_PHYSICAL_ADDRESS Address; @@ -626,7 +626,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, ReadSize = sizeof(EFI_FILE_INFO) + 32; /* Allocate necessary amount of memory */ - Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo); + Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -639,8 +639,8 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, if(Status == STATUS_EFI_BUFFER_TOO_SMALL) { /* Buffer is too small, but EFI tells the required size, so reallocate */ - BlFreeMemoryPool(&FileInfo); - Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo); + Memory::FreePool(&FileInfo); + Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -657,7 +657,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, { /* Unable to get file information */ FileHandle->Close(FileHandle); - BlFreeMemoryPool(&FileInfo); + Memory::FreePool(&FileInfo); return Status; } @@ -666,12 +666,12 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize); /* Allocate pages */ - Status = BlAllocateMemoryPages(AllocateAnyPages, Pages, &Address); + Status = Memory::AllocatePages(AllocateAnyPages, Pages, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Pages allocation failure */ FileHandle->Close(FileHandle); - BlFreeMemoryPool(&FileInfo); + Memory::FreePool(&FileInfo); return Status; } @@ -686,14 +686,14 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, { /* Failed to read data */ FileHandle->Close(FileHandle); - BlFreeMemoryPool(&FileInfo); - BlFreeMemoryPages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData); + Memory::FreePool(&FileInfo); + Memory::FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData); return Status; } /* Close handle and free memory */ FileHandle->Close(FileHandle); - BlFreeMemoryPool(FileInfo); + Memory::FreePool(FileInfo); /* Return success */ return STATUS_EFI_SUCCESS; @@ -711,7 +711,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, */ XTCDECL EFI_STATUS -BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) +Volume::DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) { EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; @@ -723,11 +723,11 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) EFI_STATUS Status; /* Locate handles which support the disk I/O interface */ - Status = BlLocateProtocolHandles(&Handles, &HandlesCount, &IoGuid); + Status = Protocol::LocateProtocolHandles(&Handles, &HandlesCount, &IoGuid); if(Status != STATUS_EFI_SUCCESS) { /* Failed to locate handles */ - BlDebugPrint(L"ERROR: Failed to locate block devices handles (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to locate block devices handles (Status Code: 0x%zX)\n", Status); return Status; } @@ -735,15 +735,15 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) for(Index = 0; Index < HandlesCount; Index++) { /* Print debug message */ - BlDebugPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount); + Debug::Print(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount); /* Open I/O protocol for given handle */ Io = NULLPTR; - Status = BlOpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid); + Status = Protocol::OpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid); if(Status != STATUS_EFI_SUCCESS || Io == NULLPTR) { /* Failed to open I/O protocol, skip it */ - BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%zX)\n", Status); + Debug::Print(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%zX)\n", Status); continue; } @@ -751,7 +751,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U) { /* Skip stub as it is non-functional */ - BlDebugPrint(L"WARNING: Skipping iPXE stub block I/O protocol"); + Debug::Print(L"WARNING: Skipping iPXE stub block I/O protocol"); continue; } @@ -761,17 +761,17 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Status != STATUS_EFI_SUCCESS || DevicePath == NULLPTR) { /* Device failed to handle DP protocol */ - BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status); + Debug::Print(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULLPTR); continue; } /* Allocate memory for block device */ - Status = BlAllocateMemoryPool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); + Status = Memory::AllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ - BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULLPTR); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULLPTR); return Status; @@ -784,7 +784,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) } /* Free handles buffer */ - BlFreeMemoryPool(Handles); + Memory::FreePool(Handles); /* Return success */ return STATUS_EFI_SUCCESS; @@ -814,12 +814,12 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) */ XTCDECL EFI_STATUS -BlpDissectVolumeArcPath(IN PWCHAR SystemPath, - OUT PWCHAR *ArcName, - OUT PWCHAR *Path, - OUT PUSHORT DriveType, - OUT PULONG DriveNumber, - OUT PULONG PartNumber) +Volume::DissectArcPath(IN PWCHAR SystemPath, + OUT PWCHAR *ArcName, + OUT PWCHAR *Path, + OUT PUSHORT DriveType, + OUT PULONG DriveNumber, + OUT PULONG PartNumber) { PWCHAR ArcPath, LocalArcName; ULONG ArcLength = 0; @@ -954,7 +954,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath, /* Store ARC name if possible */ if(ArcName) { - BlAllocateMemoryPool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName); + Memory::AllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName); RTL::Memory::CopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR)); LocalArcName[ArcLength] = '\0'; *ArcName = LocalArcName; @@ -976,7 +976,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath, */ XTCDECL PEFI_DEVICE_PATH_PROTOCOL -BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) +Volume::DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) { PEFI_DEVICE_PATH_PROTOCOL DevicePathNode; PEFI_DEVICE_PATH_PROTOCOL DevicePathClone; @@ -1012,11 +1012,11 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) } /* Allocate memory for the new device path */ - Status = BlAllocateMemoryPool(Length, (PVOID *)&DevicePathClone); + Status = Memory::AllocatePool(Length, (PVOID *)&DevicePathClone); if(Status != STATUS_EFI_SUCCESS) { /* Failed to allocate memory */ - BlDebugPrint(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status); return NULLPTR; } @@ -1042,8 +1042,8 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) */ XTCDECL EFI_STATUS -BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) +Volume::FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) { PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode; @@ -1088,9 +1088,9 @@ BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, */ XTCDECL BOOLEAN -BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, - IN PEFI_BLOCK_DEVICE_DATA ChildNode, - OUT PEFI_BLOCK_DEVICE_DATA *ParentNode) +Volume::FindParentBlockDevice(IN PLIST_ENTRY BlockDevices, + IN PEFI_BLOCK_DEVICE_DATA ChildNode, + OUT PEFI_BLOCK_DEVICE_DATA *ParentNode) { PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath; PEFI_BLOCK_DEVICE_DATA BlockDeviceData; diff --git a/xtldr/xtldr.cc b/xtldr/xtldr.cc index 20e62a6..a4b0698 100644 --- a/xtldr/xtldr.cc +++ b/xtldr/xtldr.cc @@ -18,7 +18,7 @@ */ XTCDECL VOID -BlInitializeBootLoader() +XtLoader::InitializeBootLoader() { EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; @@ -29,10 +29,10 @@ BlInitializeBootLoader() BlpStatus.BootServices = TRUE; /* Initialize console */ - BlInitializeConsole(); + Console::InitializeConsole(); /* Print XTLDR version */ - BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + Console::Print(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Initialize XTLDR configuration linked lists */ RTL::LinkedList::InitializeListHead(&BlpBootProtocols); @@ -40,10 +40,10 @@ BlInitializeBootLoader() RTL::LinkedList::InitializeListHead(&BlpLoadedModules); /* Store SecureBoot status */ - BlpStatus.SecureBoot = BlGetSecureBootStatus(); + BlpStatus.SecureBoot = EfiUtils::GetSecureBootStatus(); /* Attempt to open EFI LoadedImage protocol */ - Status = BlOpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid); + Status = Protocol::OpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid); if(Status == STATUS_EFI_SUCCESS) { /* Store boot loader image base and size */ @@ -54,7 +54,7 @@ BlInitializeBootLoader() if(DEBUG) { /* Protocol opened successfully, print useful debug information */ - BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n" + Console::Print(L"\n---------- BOOTLOADER DEBUG ----------\n" L"Pointer Size : %d\n" L"Image Base Address : %P\n" L"Image Base Size : 0x%lX\n" @@ -66,11 +66,11 @@ BlInitializeBootLoader() LoadedImage->ImageSize, LoadedImage->Revision, BlpStatus.SecureBoot); - BlSleepExecution(3000); + EfiUtils::SleepExecution(3000); } /* Close EFI LoadedImage protocol */ - BlCloseProtocol(&Handle, &LipGuid); + Protocol::CloseProtocol(&Handle, &LipGuid); } } @@ -92,10 +92,10 @@ BlInitializeBootLoader() */ XTCDECL EFI_STATUS -BlInitializeBootMenuList(IN ULONG MaxNameLength, - OUT PXTBL_BOOTMENU_ITEM *MenuEntries, - OUT PULONG EntriesCount, - OUT PULONG DefaultId) +XtLoader::InitializeBootMenuList(IN ULONG MaxNameLength, + OUT PXTBL_BOOTMENU_ITEM *MenuEntries, + OUT PULONG EntriesCount, + OUT PULONG DefaultId) { EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName, VisibleName; @@ -111,13 +111,13 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength, NumberOfEntries = 0; /* Get default menu entry from configuration */ - BlGetConfigValue(L"DEFAULT", &DefaultMenuEntry); + Configuration::GetValue(L"DEFAULT", &DefaultMenuEntry); /* Check if configuration allows to use last booted OS */ - if(BlGetConfigBooleanValue(L"KEEPLASTBOOT")) + if(Configuration::GetBooleanValue(L"KEEPLASTBOOT")) { /* Attempt to get last booted Operating System from NVRAM */ - Status = BlGetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID*)&LastBooted); + Status = EfiUtils::GetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID*)&LastBooted); if(Status == STATUS_EFI_SUCCESS) { /* Set default menu entry to last booted OS */ @@ -135,7 +135,7 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength, } /* Allocate memory for the OS list depending on the item count */ - Status = BlAllocateMemoryPool(NumberOfEntries * sizeof(XTBL_BOOTMENU_ITEM), (PVOID*)&OsList); + Status = Memory::AllocatePool(NumberOfEntries * sizeof(XTBL_BOOTMENU_ITEM), (PVOID*)&OsList); if(Status != STATUS_EFI_SUCCESS || !OsList) { /* Memory allocation failure */ @@ -189,7 +189,7 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength, if(NameLength > MaxNameLength) { /* Menu entry name is too long, allocate memory for shorter name visible in the boot menu */ - Status = BlAllocateMemoryPool((MaxNameLength + 1) * sizeof(WCHAR), (PVOID*)&VisibleName); + Status = Memory::AllocatePool((MaxNameLength + 1) * sizeof(WCHAR), (PVOID*)&VisibleName); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -224,157 +224,6 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength, return STATUS_EFI_SUCCESS; } -/** - * Loads all necessary modules and invokes boot protocol. - * - * @param ShortName - * Supplies a pointer to a short name of the chosen boot menu entry. - * - * @param OptionsList - * Supplies a pointer to list of options associated with chosen boot menu entry. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlInvokeBootProtocol(IN PWCHAR ShortName, - IN PLIST_ENTRY OptionsList) -{ - EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; - XTBL_BOOT_PARAMETERS BootParameters; - PXTBL_BOOT_PROTOCOL BootProtocol; - PLIST_ENTRY OptionsListEntry; - PXTBL_CONFIG_ENTRY Option; - EFI_GUID BootProtocolGuid; - SIZE_T ModuleListLength; - PWCHAR ModulesList; - EFI_HANDLE Handle; - EFI_STATUS Status; - - /* Initialize boot parameters and a list of modules */ - RTL::Memory::ZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS)); - ModulesList = NULLPTR; - - /* Iterate through all options provided by boot menu entry and propagate boot parameters */ - OptionsListEntry = OptionsList->Flink; - while(OptionsListEntry != OptionsList) - { - /* Get option */ - Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink); - - /* Look for boot protocol and modules list */ - if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) - { - /* Check a length of modules list */ - ModuleListLength = RTL::WideString::WideStringLength(Option->Value, 0); - - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (ModuleListLength + 1), (PVOID *)&ModulesList); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory, print error message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); - return STATUS_EFI_OUT_OF_RESOURCES; - } - - /* Make a copy of modules list */ - RTL::Memory::CopyMemory(ModulesList, Option->Value, sizeof(WCHAR) * (ModuleListLength + 1)); - } - else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0) - { - /* Boot protocol found */ - BootParameters.SystemType = Option->Value; - } - else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0) - { - /* System path found, get volume device path */ - Status = BlGetVolumeDevicePath(Option->Value, &BootParameters.DevicePath, - &BootParameters.ArcName, &BootParameters.SystemPath); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to find volume */ - BlDebugPrint(L"ERROR: Failed to find volume device path (Status Code: 0x%zX)\n", Status); - return Status; - } - - /* Get EFI compatible system path */ - Status = BlGetEfiPath(BootParameters.SystemPath, &BootParameters.EfiPath); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get EFI path */ - BlDebugPrint(L"ERROR: Failed to get EFI path (Status Code: 0x%zX)\n", Status); - return Status; - } - } - else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0) - { - /* Kernel file name found */ - BootParameters.KernelFile = Option->Value; - } - else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0) - { - /* Initrd file name found */ - BootParameters.InitrdFile = Option->Value; - } - else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0) - { - /* Hal file name found */ - BootParameters.HalFile = Option->Value; - } - else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0) - { - /* Kernel parameters found */ - BootParameters.Parameters = Option->Value; - } - - /* Move to the next option entry */ - OptionsListEntry = OptionsListEntry->Flink; - } - - /* Load all necessary modules */ - Status = BlLoadModules(ModulesList); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load modules, print error message and return status code */ - BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status); - return STATUS_EFI_NOT_READY; - } - - /* Attempt to get boot protocol GUID */ - Status = BlFindBootProtocol(BootParameters.SystemType, &BootProtocolGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get boot protocol GUID */ - BlDebugPrint(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%zX)\n", Status); - return STATUS_EFI_UNSUPPORTED; - } - - /* Open boot protocol */ - Status = BlOpenProtocol(&Handle, (PVOID *)&BootProtocol, &BootProtocolGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open boot protocol */ - BlDebugPrint(L"ERROR: Failed to open boot protocol (Status Code: 0x%zX)\n", Status); - return Status; - } - - /* Check if chosen operating system should be saved */ - if(BlGetConfigBooleanValue(L"KEEPLASTBOOT")) - { - /* Save chosen operating system in NVRAM */ - Status = BlSetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID)ShortName, RTL::WideString::WideStringLength(ShortName, 0) * sizeof(WCHAR)); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to save chosen Operating System */ - BlDebugPrint(L"WARNING: Failed to save chosen Operating System in NVRAM (Status Code: 0x%zX)\n", Status); - } - } - - /* Boot Operating System */ - return BootProtocol->BootSystem(&BootParameters); -} - /** * This routine is the entry point of the XT EFI boot loader. * @@ -401,43 +250,43 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, EfiSystemTable = SystemTable; /* Initialize XTLDR and */ - BlInitializeBootLoader(); + XtLoader::InitializeBootLoader(); /* Parse configuration options passed from UEFI shell */ - Status = BlpParseCommandLine(); + Status = Configuration::ParseCommandLine(); if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse command line options */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters."); + TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters."); } /* Attempt to early initialize debug console */ if(DEBUG) { - Status = BlpInitializeDebugConsole(); + Status = Debug::InitializeDebugConsole(); if(Status != STATUS_EFI_SUCCESS) { /* Initialization failed, notify user on stdout */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); + TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); } } /* Load XTLDR configuration file */ - Status = BlpLoadConfiguration(); + Status = Configuration::LoadConfiguration(); if(Status != STATUS_EFI_SUCCESS) { /* Failed to load/parse config file */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file "); + TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file "); } /* Reinitialize debug console if it was not initialized earlier */ if(DEBUG) { - Status = BlpInitializeDebugConsole(); + Status = Debug::InitializeDebugConsole(); if(Status != STATUS_EFI_SUCCESS) { /* Initialization failed, notify user on stdout */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); + TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); } } @@ -446,34 +295,34 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, if(Status != STATUS_EFI_SUCCESS) { /* Failed to disable the timer, print message */ - BlDebugPrint(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%zX)\n", Status); + Debug::Print(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%zX)\n", Status); } /* Install loader protocol */ - Status = BlpInstallXtLoaderProtocol(); + Status = Protocol::InstallXtLoaderProtocol(); if(Status != STATUS_EFI_SUCCESS) { /* Failed to register loader protocol */ - BlDebugPrint(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%zX)\n", Status); return Status; } /* Load all necessary modules */ - BlGetConfigValue(L"MODULES", &Modules); - Status = BlLoadModules(Modules); + Configuration::GetValue(L"MODULES", &Modules); + Status = Protocol::LoadModules(Modules); if(Status != STATUS_EFI_SUCCESS) { /* Failed to load modules */ - BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules."); + Debug::Print(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status); + TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules."); } /* Discover and enumerate EFI block devices */ - Status = BlEnumerateBlockDevices(); + Status = Volume::EnumerateBlockDevices(); if(Status != STATUS_EFI_SUCCESS) { /* Failed to enumerate block devices */ - BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%zX)\n", Status); return Status; } @@ -489,11 +338,11 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, else { /* Display default boot menu */ - BlDisplayBootMenu(); + TextUi::DisplayBootMenu(); } /* Fallback to shell, if boot menu returned */ - BlStartLoaderShell(); + Shell::StartLoaderShell(); } /* This point should be never reached, if this happen return error code */