diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 2bf7737..2ff7bd0 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -77,7 +77,7 @@ typedef PVOID (*PBL_GET_VIRTUAL_ADDRESS)(IN PXTBL_PAGE_MAPPING PageMap, IN PVOID typedef EFI_STATUS (*PBL_INITIALIZE_ENTROPY)(PULONGLONG RNGBuffer); typedef VOID (*PBL_INITIALIZE_PAGE_MAP)(OUT PXTBL_PAGE_MAPPING PageMap, IN SHORT PageMapLevel, IN PAGE_SIZE PageSize); typedef EFI_STATUS (*PBL_INSTALL_XT_PROTOCOL)(IN PVOID Interface, IN PEFI_GUID Guid); -typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PLIST_ENTRY OptionsList); +typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PWCHAR ShortName, IN PLIST_ENTRY OptionsList); typedef EFI_STATUS (*PBL_LOCATE_PROTOCOL_HANDLES)(OUT PEFI_HANDLE *Handles, OUT PUINT_PTR Count, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_LOAD_EFI_IMAGE)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN PVOID ImageData, IN SIZE_T ImageSize, OUT PEFI_HANDLE ImageHandle); typedef EFI_STATUS (*PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); @@ -146,6 +146,7 @@ typedef struct _XTBL_BOOT_PARAMETERS typedef struct _XTBL_BOOTMENU_ITEM { PWCHAR EntryName; + PWCHAR ShortName; PLIST_ENTRY Options; } XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM; diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index 4ba7d0d..b456305 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -207,7 +207,8 @@ BlInstallProtocol(IN PVOID Interface, XTCDECL EFI_STATUS -BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList); +BlInvokeBootProtocol(IN PWCHAR ShortName, + IN PLIST_ENTRY OptionsList); XTCDECL EFI_STATUS diff --git a/xtldr/textui.c b/xtldr/textui.c index ef580ee..de3cc50 100644 --- a/xtldr/textui.c +++ b/xtldr/textui.c @@ -135,7 +135,8 @@ BlDisplayBootMenu() BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); /* Boot the highlighted (chosen) OS */ - Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options); + Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, + MenuEntries[HighligtedEntryId].Options); if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ @@ -279,7 +280,8 @@ BlDisplayBootMenu() TimeOut = -1; /* Boot the highlighted (default) OS */ - Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].Options); + Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, + MenuEntries[HighligtedEntryId].Options); if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index 2c71a63..bb58a1c 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -94,12 +94,14 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId) { - PWCHAR DefaultMenuEntry, MenuEntryName; + EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; + PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName; PLIST_ENTRY MenuEntrySectionList, MenuEntryList; PXTBL_CONFIG_SECTION MenuEntrySection; PXTBL_CONFIG_ENTRY MenuEntryOption; - PXTBL_BOOTMENU_ITEM OsList; ULONG DefaultOS, NumberOfEntries; + PXTBL_BOOTMENU_ITEM OsList; + EFI_STATUS Status; /* Set default values */ DefaultOS = 0; @@ -109,6 +111,20 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, /* Get default menu entry from configuration */ DefaultMenuEntry = BlGetConfigValue(L"DEFAULT"); + /* Check if configuration allows to use last booted OS */ + if(RtlCompareWideStringInsensitive(BlGetConfigValue(L"KEEPLASTBOOT"), L"TRUE", 0) == 0) + { + /* Attempt to get last booted Operating System from NVRAM */ + Status = BlGetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID*)&LastBooted); + if(Status == STATUS_EFI_SUCCESS) + { + /* Set default menu entry to last booted OS */ + DefaultMenuEntry = LastBooted; + } + BlDebugPrint(L"Last booted OS: '%S' - '%S'\n", LastBooted, DefaultMenuEntry); + BlSleepExecution(5000); + } + /* Iterate through all menu sections */ MenuEntrySectionList = BlpMenuList->Flink; while(MenuEntrySectionList != BlpMenuList) @@ -146,6 +162,7 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, /* Add OS to the boot menu list */ OsList[NumberOfEntries].EntryName = MenuEntryName; + OsList[NumberOfEntries].ShortName = MenuEntrySection->SectionName; OsList[NumberOfEntries].Options = &MenuEntrySection->Options; /* Get next menu entry */ @@ -162,6 +179,9 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, /** * 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. * @@ -171,8 +191,10 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries, */ XTCDECL EFI_STATUS -BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) +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; @@ -289,6 +311,21 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList) return Status; } + /* Check if chosen operating system should be saved */ + if(RtlCompareWideStringInsensitive(BlGetConfigValue(L"KEEPLASTBOOT"), L"TRUE", 0) == 0) + { + /* Save chosen operating system in NVRAM */ + Status = BlSetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID)ShortName, RtlWideStringLength(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); + } + + BlDebugPrint(L"Now setting OS: '%S'\n", ShortName); + BlSleepExecution(5000); + } + /* Boot Operating System */ return BootProtocol->BootSystem(&BootParameters); }