From 03ffa1d901a9a432abd2376d772fbc774b09e5e0 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 30 Dec 2023 14:23:58 +0100 Subject: [PATCH] Clean up code a bit --- xtldr2/includes/bootman.h | 8 ++ xtldr2/protocol.c | 269 ++++++++++++++++++++++++++++++++++++++ xtldr2/textui.c | 4 +- xtldr2/xtldr.c | 259 ------------------------------------ 4 files changed, 279 insertions(+), 261 deletions(-) diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index b45f494..b728275 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -105,6 +105,14 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); +XTCDECL +EFI_STATUS +BlLoadModule(IN PWCHAR ModuleName); + +XTCDECL +EFI_STATUS +BlLoadModules(IN PWCHAR ModulesList); + XTCDECL EFI_STATUS BlMemoryAllocatePages(IN UINT64 Pages, diff --git a/xtldr2/protocol.c b/xtldr2/protocol.c index 02793ce..ac743e2 100644 --- a/xtldr2/protocol.c +++ b/xtldr2/protocol.c @@ -9,6 +9,275 @@ #include +/** + * Loads a specified XTLDR module from disk. + * + * @param ModuleName + * Specifies the name of the module to load. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlLoadModule(IN PWCHAR ModuleName) +{ + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2]; + PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; + PEFI_FILE_HANDLE DirHandle, FsHandle; + EFI_HANDLE DiskHandle, ModuleHandle; + PPECOFF_IMAGE_SECTION_HEADER SectionHeader; + PPECOFF_IMAGE_DOS_HEADER DosHeader; + PPECOFF_IMAGE_PE_HEADER PeHeader; + PXTBL_MODULE_DEPS ModuleDependencies; + PXTBL_MODULE_INFO ModuleInfo; + PLIST_ENTRY ModuleListEntry; + WCHAR ModuleFileName[12]; + USHORT SectionIndex; + SIZE_T ModuleSize; + EFI_STATUS Status; + PVOID ModuleData; + PWCHAR DepsData; + + ModuleListEntry = BlpLoadedModules.Flink; + while(ModuleListEntry != &BlpLoadedModules) + { + /* Get module information */ + ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); + + if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) + { + /* Module already loaded */ + BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName); + return STATUS_EFI_SUCCESS; + } + + /* Move to the module */ + ModuleListEntry = ModuleListEntry->Flink; + } + + /* Print debug message */ + BlDebugPrint(L"Loading module '%S' ...\n", ModuleName); + + /* Set module path */ + RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR)); + RtlConcatenateWideString(ModuleFileName, L".EFI", 0); + + /* Open EFI volume */ + Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open a volume */ + return Status; + } + + /* Open XTLDR modules directory and close the FS immediately */ + Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); + FsHandle->Close(FsHandle); + + /* Check if directory opened successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open directory */ + BlCloseVolume(DiskHandle); + return Status; + } + + /* Read module file from disk and close EFI volume */ + Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); + BlCloseVolume(DiskHandle); + + /* Make sure module file was read successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to read file */ + return Status; + } + + /* Allocate memory for module information block */ + Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory */ + return Status; + } + + /* Zero module information block and initialize dependencies list */ + RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO)); + RtlInitializeListHead(&ModuleInfo->Dependencies); + + /* Setup PE/COFF EFI image headers */ + DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData; + PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->e_lfanew); + SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader + + PeHeader->FileHeader.SizeOfOptionalHeader); + + /* Look for .moddeps and .modinfo sections */ + for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++) + { + /* Check section name */ + if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0) + { + /* Store address of .moddeps data segment */ + DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData; + + /* Iterate over all dependencies stored */ + while(*DepsData != 0) + { + /* Load dependency module */ + BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData); + Status = BlLoadModule(DepsData); + + 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%lx)\n", DepsData, Status); + return STATUS_EFI_UNSUPPORTED; + } + + /* Allocate memory for module dependency */ + Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); + if(Status == STATUS_EFI_SUCCESS) + { + /* Memory allocated successfully, store module's dependency */ + ModuleDependencies->ModuleName = DepsData; + RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink); + } + + /* Get next dependency module name */ + DepsData += 8; + } + } + else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0) + { + /* Store module description */ + ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData; + } + } + + /* Finally, store module name */ + ModuleInfo->ModuleName = ModuleName; + + /* Setup module device path */ + ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH); + ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8; + ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH; + ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP; + ModuleDevicePath[0].MemoryType = EfiLoaderData; + ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData; + ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize; + ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); + ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8; + ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH; + ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; + + /* Load EFI image */ + Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, (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); + } + else + { + /* Failed to load module */ + BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); + } + + /* Return error status code */ + return Status; + } + + /* Access module interface for further module type check */ + Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage, + EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open LoadedImage protocol */ + BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%lx)\n", Status); + return Status; + } + + /* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */ + 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"); + + /* Close protocol and skip module */ + EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); + } + + /* Close loaded image protocol */ + EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); + + /* Start EFI image */ + Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to start module image */ + BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); + return Status; + } + + /* Add module to the list of loaded modules */ + RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Helper routine to load all modules supplied in the configuration file. + * + * @param ModulesList + * Supplies a space separated list of XTLDR modules to load (mostly read from configuration file). + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlLoadModules(IN PWCHAR ModulesList) +{ + PWCHAR LastModule, Module; + EFI_STATUS ReturnStatus, Status; + + /* Set default return value */ + ReturnStatus = STATUS_EFI_SUCCESS; + + if(ModulesList != NULL) + { + /* Tokenize provided list of modules */ + Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule); + + /* Iterate over all arguments passed to boot loader */ + while(Module != NULL) + { + Status = BlLoadModule(Module); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load module, print error message and set new return value */ + BlDebugPrint(L"Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status); + ReturnStatus = STATUS_EFI_LOAD_ERROR; + } + + /* Take next module from the list */ + Module = RtlTokenizeWideString(NULL, L" ", &LastModule); + } + } + + /* Return success */ + return ReturnStatus; +} + /** * This routine locates and opens the requested XT boot loader protocol. * diff --git a/xtldr2/textui.c b/xtldr2/textui.c index 01fb4a1..0ec3605 100644 --- a/xtldr2/textui.c +++ b/xtldr2/textui.c @@ -1085,7 +1085,7 @@ BlDisplayBootMenu() if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n", + BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n", MenuEntries[HighligtedEntryId].EntryName, Status); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); } @@ -1198,7 +1198,7 @@ BlDisplayBootMenu() if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n", + BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n", MenuEntries[HighligtedEntryId].EntryName, Status); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); } diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 6a71a5b..09d786a 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -9,14 +9,6 @@ #include -XTCDECL -EFI_STATUS -BlLoadModule(IN PWCHAR Module); - -XTCDECL -EFI_STATUS -BlLoadModules(IN PWCHAR ModulesList); - /** * Initializes a list of operating systems for XTLDR boot menu. * @@ -166,255 +158,6 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) return STATUS_EFI_SUCCESS; } -XTCDECL -EFI_STATUS -BlLoadModules(IN PWCHAR ModulesList) -{ - PWCHAR LastModule, Module; - EFI_STATUS ReturnStatus, Status; - - /* Set default return value */ - ReturnStatus = STATUS_EFI_SUCCESS; - - if(ModulesList != NULL) - { - /* Tokenize provided list of modules */ - Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule); - - /* Iterate over all arguments passed to boot loader */ - while(Module != NULL) - { - Status = BlLoadModule(Module); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load module, print error message and set new return value */ - BlDebugPrint(L"Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status); - ReturnStatus = STATUS_EFI_LOAD_ERROR; - } - - /* Take next module from the list */ - Module = RtlTokenizeWideString(NULL, L" ", &LastModule); - } - } - - /* Return success */ - return ReturnStatus; -} - -XTCDECL -EFI_STATUS -BlLoadModule(IN PWCHAR ModuleName) -{ - EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2]; - PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; - PEFI_FILE_HANDLE DirHandle, FsHandle; - EFI_HANDLE DiskHandle, ModuleHandle; - PPECOFF_IMAGE_SECTION_HEADER SectionHeader; - PPECOFF_IMAGE_DOS_HEADER DosHeader; - PPECOFF_IMAGE_PE_HEADER PeHeader; - PXTBL_MODULE_DEPS ModuleDependencies; - PXTBL_MODULE_INFO ModuleInfo; - PLIST_ENTRY ModuleListEntry; - WCHAR ModuleFileName[12]; - USHORT SectionIndex; - SIZE_T ModuleSize; - EFI_STATUS Status; - PVOID ModuleData; - PWCHAR DepsData; - - ModuleListEntry = BlpLoadedModules.Flink; - while(ModuleListEntry != &BlpLoadedModules) - { - /* Get module information */ - ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); - - if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) - { - /* Module already loaded */ - BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName); - return STATUS_EFI_SUCCESS; - } - - /* Move to the module */ - ModuleListEntry = ModuleListEntry->Flink; - } - - /* Print debug message */ - BlDebugPrint(L"Loading module '%S' ...\n", ModuleName); - - /* Set module path */ - RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR)); - RtlConcatenateWideString(ModuleFileName, L".EFI", 0); - - /* Open EFI volume */ - Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open a volume */ - return Status; - } - - /* Open XTLDR modules directory and close the FS immediately */ - Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); - FsHandle->Close(FsHandle); - - /* Check if directory opened successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open directory */ - BlCloseVolume(DiskHandle); - return Status; - } - - /* Read module file from disk and close EFI volume */ - Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); - BlCloseVolume(DiskHandle); - - /* Make sure module file was read successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to read file */ - return Status; - } - - /* Allocate memory for module information block */ - Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory */ - return Status; - } - - /* Zero module information block and initialize dependencies list */ - RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO)); - RtlInitializeListHead(&ModuleInfo->Dependencies); - - /* Setup PE/COFF EFI image headers */ - DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData; - PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->e_lfanew); - SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader + - PeHeader->FileHeader.SizeOfOptionalHeader); - - /* Look for .moddeps and .modinfo sections */ - for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++) - { - /* Check section name */ - if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0) - { - /* Store address of .moddeps data segment */ - DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData; - - /* Iterate over all dependencies stored */ - while(*DepsData != 0) - { - /* Load dependency module */ - BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData); - Status = BlLoadModule(DepsData); - - 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%lx)\n", DepsData, Status); - return STATUS_EFI_UNSUPPORTED; - } - - /* Allocate memory for module dependency */ - Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); - if(Status == STATUS_EFI_SUCCESS) - { - /* Memory allocated successfully, store module's dependency */ - ModuleDependencies->ModuleName = DepsData; - RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink); - } - - /* Get next dependency module name */ - DepsData += 8; - } - } - else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0) - { - /* Store module description */ - ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData; - } - } - - /* Finally, store module name */ - ModuleInfo->ModuleName = ModuleName; - - /* Setup module device path */ - ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH); - ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8; - ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH; - ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP; - ModuleDevicePath[0].MemoryType = EfiLoaderData; - ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData; - ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize; - ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); - ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8; - ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH; - ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; - - /* Load EFI image */ - Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, (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); - } - else - { - /* Failed to load module */ - BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); - } - - /* Return error status code */ - return Status; - } - - /* Access module interface for further module type check */ - Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage, - EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open LoadedImage protocol */ - BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%lx)\n", Status); - return Status; - } - - /* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */ - 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"); - - /* Close protocol and skip module */ - EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); - } - - /* Close loaded image protocol */ - EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); - - /* Start EFI image */ - Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to start module image */ - BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%lx)\n", ModuleName, Status); - return Status; - } - - /* Add module to the list of loaded modules */ - RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - /** * This routine is the entry point of the XT EFI boot loader. * @@ -545,8 +288,6 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlConsolePrint(L"\n\n END OF LIST\n"); - for(;;); - for(;;) { if(BlpStatus.BootMenu != NULL)