diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 42ffaa3..a6ffe68 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -45,7 +45,7 @@ typedef LONG (*PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType); /* Boot Loader protocol routine pointers */ typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN EFI_ALLOCATE_TYPE AllocationType, IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); -typedef EFI_STATUS (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); +typedef EFI_STATUS (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLength, OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); typedef BOOLEAN (*PBL_BOOTUTIL_GET_BOOLEAN_PARAMETER)(IN CONST PWCHAR Parameters, IN CONST PWCHAR Needle); typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); @@ -153,6 +153,7 @@ typedef struct _XTBL_BOOT_PARAMETERS typedef struct _XTBL_BOOTMENU_ITEM { PWCHAR EntryName; + PWCHAR FullName; PWCHAR ShortName; PLIST_ENTRY Options; } XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM; diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index 791b09a..b008f89 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -197,7 +197,8 @@ BlInitializeBootLoader(); XTCDECL EFI_STATUS -BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, +BlInitializeBootMenuList(IN ULONG MaxNameLength, + OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); diff --git a/xtldr/textui.c b/xtldr/textui.c index cbe038a..f69dbb7 100644 --- a/xtldr/textui.c +++ b/xtldr/textui.c @@ -34,18 +34,18 @@ BlDisplayBootMenu() LONG TimeOut; PWCHAR TimeOutString; + /* Draw boot menu */ + BlpDrawBootMenu(&Handle); + /* Initialize boot menu list */ TopVisibleEntry = 0; - Status = BlInitializeBootMenuList(&MenuEntries, &NumberOfEntries, &HighligtedEntryId); + Status = BlInitializeBootMenuList(Handle.Width - 4, &MenuEntries, &NumberOfEntries, &HighligtedEntryId); if(Status != STATUS_EFI_SUCCESS) { /* Failed to initialize boot menu list, exit into XTLDR shell */ return; } - /* Draw boot menu */ - BlpDrawBootMenu(&Handle); - /* Calculate how many entries can be visible in the menu box */ VisibleEntries = Handle.Height - 2; @@ -175,7 +175,7 @@ BlDisplayBootMenu() 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].EntryName); + BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); /* Boot the highlighted (chosen) OS */ Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, @@ -184,7 +184,7 @@ BlDisplayBootMenu() { /* Failed to boot OS */ BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", - MenuEntries[HighligtedEntryId].EntryName, Status); + MenuEntries[HighligtedEntryId].FullName, Status); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); RedrawBootMenu = TRUE; } @@ -356,7 +356,7 @@ BlDisplayBootMenu() 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].EntryName); + BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); /* Disable the timer just in case booting OS fails */ TimeOut = -1; @@ -368,7 +368,7 @@ BlDisplayBootMenu() { /* Failed to boot OS */ BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", - MenuEntries[HighligtedEntryId].EntryName, Status); + MenuEntries[HighligtedEntryId].FullName, Status); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); RedrawBootMenu = TRUE; } diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c index 2e6511a..d50deaa 100644 --- a/xtldr/xtldr.c +++ b/xtldr/xtldr.c @@ -90,16 +90,17 @@ BlInitializeBootLoader() */ XTCDECL EFI_STATUS -BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, +BlInitializeBootMenuList(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; + PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName, VisibleName; PLIST_ENTRY MenuEntrySectionList, MenuEntryList; PXTBL_CONFIG_SECTION MenuEntrySection; PXTBL_CONFIG_ENTRY MenuEntryOption; - ULONG DefaultOS, NumberOfEntries; + ULONG DefaultOS, NameLength,NumberOfEntries; PXTBL_BOOTMENU_ITEM OsList; EFI_STATUS Status; @@ -177,10 +178,36 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, } /* Add OS to the boot menu list */ - OsList[NumberOfEntries].EntryName = MenuEntryName; + OsList[NumberOfEntries].FullName = MenuEntryName; OsList[NumberOfEntries].ShortName = MenuEntrySection->SectionName; OsList[NumberOfEntries].Options = &MenuEntrySection->Options; + /* Check if the menu entry name fits the maximum length */ + NameLength = RtlWideStringLength(MenuEntryName, 0); + 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); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Copy shorter name and append "..." at the end */ + RtlCopyMemory(VisibleName, MenuEntryName, (MaxNameLength - 3) * sizeof(WCHAR)); + RtlCopyMemory(VisibleName + MaxNameLength - 3, L"...", 3 * sizeof(WCHAR)); + VisibleName[MaxNameLength] = L'\0'; + + /* Set visible menu entry name */ + OsList[NumberOfEntries].EntryName = VisibleName; + } + else + { + /* Menu entry name fits the maximum length, use it as is */ + OsList[NumberOfEntries].EntryName = MenuEntryName; + } + /* Get next menu entry */ MenuEntrySectionList = MenuEntrySectionList->Flink; NumberOfEntries++;