123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017 |
- /** @file
- Provide boot option support for Application "BootMaint"
- Include file system navigation, system handle selection
- Boot option manipulation
- Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "BootMaintenanceManager.h"
- ///
- /// Define the maximum characters that will be accepted.
- ///
- #define MAX_CHAR 480
- /**
- Check whether a reset is needed, if reset is needed, Popup a menu to notice user.
- **/
- VOID
- BmmSetupResetReminder (
- VOID
- )
- {
- EFI_INPUT_KEY Key;
- CHAR16 *StringBuffer1;
- CHAR16 *StringBuffer2;
- EFI_STATUS Status;
- EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;
- //
- // Use BrowserEx2 protocol to check whether reset is required.
- //
- Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **)&FormBrowserEx2);
- //
- // check any reset required change is applied? if yes, reset system
- //
- if (!EFI_ERROR (Status) && FormBrowserEx2->IsResetRequired ()) {
- StringBuffer1 = AllocateZeroPool (MAX_CHAR * sizeof (CHAR16));
- ASSERT (StringBuffer1 != NULL);
- StringBuffer2 = AllocateZeroPool (MAX_CHAR * sizeof (CHAR16));
- ASSERT (StringBuffer2 != NULL);
- StrCpyS (StringBuffer1, MAX_CHAR, L"Configuration changed. Reset to apply it Now.");
- StrCpyS (StringBuffer2, MAX_CHAR, L"Press ENTER to reset");
- //
- // Popup a menu to notice user
- //
- do {
- CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- FreePool (StringBuffer1);
- FreePool (StringBuffer2);
- gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
- }
- }
- /**
- Create a menu entry by given menu type.
- @param MenuType The Menu type to be created.
- @retval NULL If failed to create the menu.
- @return the new menu entry.
- **/
- BM_MENU_ENTRY *
- BOpt_CreateMenuEntry (
- UINTN MenuType
- )
- {
- BM_MENU_ENTRY *MenuEntry;
- UINTN ContextSize;
- //
- // Get context size according to menu type
- //
- switch (MenuType) {
- case BM_LOAD_CONTEXT_SELECT:
- ContextSize = sizeof (BM_LOAD_CONTEXT);
- break;
- case BM_FILE_CONTEXT_SELECT:
- ContextSize = sizeof (BM_FILE_CONTEXT);
- break;
- case BM_CONSOLE_CONTEXT_SELECT:
- ContextSize = sizeof (BM_CONSOLE_CONTEXT);
- break;
- case BM_TERMINAL_CONTEXT_SELECT:
- ContextSize = sizeof (BM_TERMINAL_CONTEXT);
- break;
- case BM_HANDLE_CONTEXT_SELECT:
- ContextSize = sizeof (BM_HANDLE_CONTEXT);
- break;
- default:
- ContextSize = 0;
- break;
- }
- if (ContextSize == 0) {
- return NULL;
- }
- //
- // Create new menu entry
- //
- MenuEntry = AllocateZeroPool (sizeof (BM_MENU_ENTRY));
- if (MenuEntry == NULL) {
- return NULL;
- }
- MenuEntry->VariableContext = AllocateZeroPool (ContextSize);
- if (MenuEntry->VariableContext == NULL) {
- FreePool (MenuEntry);
- return NULL;
- }
- MenuEntry->Signature = BM_MENU_ENTRY_SIGNATURE;
- MenuEntry->ContextSelection = MenuType;
- return MenuEntry;
- }
- /**
- Free up all resource allocated for a BM_MENU_ENTRY.
- @param MenuEntry A pointer to BM_MENU_ENTRY.
- **/
- VOID
- BOpt_DestroyMenuEntry (
- BM_MENU_ENTRY *MenuEntry
- )
- {
- BM_LOAD_CONTEXT *LoadContext;
- BM_FILE_CONTEXT *FileContext;
- BM_CONSOLE_CONTEXT *ConsoleContext;
- BM_TERMINAL_CONTEXT *TerminalContext;
- BM_HANDLE_CONTEXT *HandleContext;
- //
- // Select by the type in Menu entry for current context type
- //
- switch (MenuEntry->ContextSelection) {
- case BM_LOAD_CONTEXT_SELECT:
- LoadContext = (BM_LOAD_CONTEXT *)MenuEntry->VariableContext;
- FreePool (LoadContext->FilePathList);
- if (LoadContext->OptionalData != NULL) {
- FreePool (LoadContext->OptionalData);
- }
- FreePool (LoadContext);
- break;
- case BM_FILE_CONTEXT_SELECT:
- FileContext = (BM_FILE_CONTEXT *)MenuEntry->VariableContext;
- if (!FileContext->IsRoot) {
- FreePool (FileContext->DevicePath);
- } else {
- if (FileContext->FHandle != NULL) {
- FileContext->FHandle->Close (FileContext->FHandle);
- }
- }
- if (FileContext->FileName != NULL) {
- FreePool (FileContext->FileName);
- }
- if (FileContext->Info != NULL) {
- FreePool (FileContext->Info);
- }
- FreePool (FileContext);
- break;
- case BM_CONSOLE_CONTEXT_SELECT:
- ConsoleContext = (BM_CONSOLE_CONTEXT *)MenuEntry->VariableContext;
- FreePool (ConsoleContext->DevicePath);
- FreePool (ConsoleContext);
- break;
- case BM_TERMINAL_CONTEXT_SELECT:
- TerminalContext = (BM_TERMINAL_CONTEXT *)MenuEntry->VariableContext;
- FreePool (TerminalContext->DevicePath);
- FreePool (TerminalContext);
- break;
- case BM_HANDLE_CONTEXT_SELECT:
- HandleContext = (BM_HANDLE_CONTEXT *)MenuEntry->VariableContext;
- FreePool (HandleContext);
- break;
- default:
- break;
- }
- FreePool (MenuEntry->DisplayString);
- if (MenuEntry->HelpString != NULL) {
- FreePool (MenuEntry->HelpString);
- }
- FreePool (MenuEntry);
- }
- /**
- Get the Menu Entry from the list in Menu Entry List.
- If MenuNumber is great or equal to the number of Menu
- Entry in the list, then ASSERT.
- @param MenuOption The Menu Entry List to read the menu entry.
- @param MenuNumber The index of Menu Entry.
- @return The Menu Entry.
- **/
- BM_MENU_ENTRY *
- BOpt_GetMenuEntry (
- BM_MENU_OPTION *MenuOption,
- UINTN MenuNumber
- )
- {
- BM_MENU_ENTRY *NewMenuEntry;
- UINTN Index;
- LIST_ENTRY *List;
- ASSERT (MenuNumber < MenuOption->MenuNumber);
- List = MenuOption->Head.ForwardLink;
- for (Index = 0; Index < MenuNumber; Index++) {
- List = List->ForwardLink;
- }
- NewMenuEntry = CR (List, BM_MENU_ENTRY, Link, BM_MENU_ENTRY_SIGNATURE);
- return NewMenuEntry;
- }
- /**
- Free resources allocated in Allocate Rountine.
- @param FreeMenu Menu to be freed
- **/
- VOID
- BOpt_FreeMenu (
- BM_MENU_OPTION *FreeMenu
- )
- {
- BM_MENU_ENTRY *MenuEntry;
- while (!IsListEmpty (&FreeMenu->Head)) {
- MenuEntry = CR (
- FreeMenu->Head.ForwardLink,
- BM_MENU_ENTRY,
- Link,
- BM_MENU_ENTRY_SIGNATURE
- );
- RemoveEntryList (&MenuEntry->Link);
- BOpt_DestroyMenuEntry (MenuEntry);
- }
- FreeMenu->MenuNumber = 0;
- }
- /**
- Build the BootOptionMenu according to BootOrder Variable.
- This Routine will access the Boot#### to get EFI_LOAD_OPTION.
- @param CallbackData The BMM context data.
- @return EFI_NOT_FOUND Fail to find "BootOrder" variable.
- @return EFI_SUCESS Success build boot option menu.
- **/
- EFI_STATUS
- BOpt_GetBootOptions (
- IN BMM_CALLBACK_DATA *CallbackData
- )
- {
- UINTN Index;
- UINT16 BootString[10];
- UINT8 *LoadOptionFromVar;
- UINTN BootOptionSize;
- BOOLEAN BootNextFlag;
- UINT16 *BootOrderList;
- UINTN BootOrderListSize;
- UINT16 *BootNext;
- UINTN BootNextSize;
- BM_MENU_ENTRY *NewMenuEntry;
- BM_LOAD_CONTEXT *NewLoadContext;
- UINT8 *LoadOptionPtr;
- UINTN StringSize;
- UINTN OptionalDataSize;
- UINT8 *LoadOptionEnd;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- UINTN MenuCount;
- UINT8 *Ptr;
- EFI_BOOT_MANAGER_LOAD_OPTION *BootOption;
- UINTN BootOptionCount;
- MenuCount = 0;
- BootOrderListSize = 0;
- BootNextSize = 0;
- BootOrderList = NULL;
- BootNext = NULL;
- LoadOptionFromVar = NULL;
- BOpt_FreeMenu (&BootOptionMenu);
- InitializeListHead (&BootOptionMenu.Head);
- //
- // Get the BootOrder from the Var
- //
- GetEfiGlobalVariable2 (L"BootOrder", (VOID **)&BootOrderList, &BootOrderListSize);
- if (BootOrderList == NULL) {
- return EFI_NOT_FOUND;
- }
- //
- // Get the BootNext from the Var
- //
- GetEfiGlobalVariable2 (L"BootNext", (VOID **)&BootNext, &BootNextSize);
- if (BootNext != NULL) {
- if (BootNextSize != sizeof (UINT16)) {
- FreePool (BootNext);
- BootNext = NULL;
- }
- }
- BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
- for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {
- //
- // Don't display the hidden/inactive boot option
- //
- if (((BootOption[Index].Attributes & LOAD_OPTION_HIDDEN) != 0) || ((BootOption[Index].Attributes & LOAD_OPTION_ACTIVE) == 0)) {
- continue;
- }
- UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", BootOrderList[Index]);
- //
- // Get all loadoptions from the VAR
- //
- GetEfiGlobalVariable2 (BootString, (VOID **)&LoadOptionFromVar, &BootOptionSize);
- if (LoadOptionFromVar == NULL) {
- continue;
- }
- if (BootNext != NULL) {
- BootNextFlag = (BOOLEAN)(*BootNext == BootOrderList[Index]);
- } else {
- BootNextFlag = FALSE;
- }
- NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
- ASSERT (NULL != NewMenuEntry);
- NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
- LoadOptionPtr = LoadOptionFromVar;
- LoadOptionEnd = LoadOptionFromVar + BootOptionSize;
- NewMenuEntry->OptionNumber = BootOrderList[Index];
- NewLoadContext->Deleted = FALSE;
- NewLoadContext->IsBootNext = BootNextFlag;
- //
- // Is a Legacy Device?
- //
- Ptr = (UINT8 *)LoadOptionFromVar;
- //
- // Attribute = *(UINT32 *)Ptr;
- //
- Ptr += sizeof (UINT32);
- //
- // FilePathSize = *(UINT16 *)Ptr;
- //
- Ptr += sizeof (UINT16);
- //
- // Description = (CHAR16 *)Ptr;
- //
- Ptr += StrSize ((CHAR16 *)Ptr);
- //
- // Now Ptr point to Device Path
- //
- DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
- if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {
- NewLoadContext->IsLegacy = TRUE;
- } else {
- NewLoadContext->IsLegacy = FALSE;
- }
- //
- // LoadOption is a pointer type of UINT8
- // for easy use with following LOAD_OPTION
- // embedded in this struct
- //
- NewLoadContext->Attributes = *(UINT32 *)LoadOptionPtr;
- LoadOptionPtr += sizeof (UINT32);
- NewLoadContext->FilePathListLength = *(UINT16 *)LoadOptionPtr;
- LoadOptionPtr += sizeof (UINT16);
- StringSize = StrSize ((UINT16 *)LoadOptionPtr);
- NewLoadContext->Description = AllocateZeroPool (StrSize ((UINT16 *)LoadOptionPtr));
- ASSERT (NewLoadContext->Description != NULL);
- StrCpyS (NewLoadContext->Description, StrSize ((UINT16 *)LoadOptionPtr) / sizeof (UINT16), (UINT16 *)LoadOptionPtr);
- ASSERT (NewLoadContext->Description != NULL);
- NewMenuEntry->DisplayString = NewLoadContext->Description;
- NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
- LoadOptionPtr += StringSize;
- NewLoadContext->FilePathList = AllocateZeroPool (NewLoadContext->FilePathListLength);
- ASSERT (NewLoadContext->FilePathList != NULL);
- CopyMem (
- NewLoadContext->FilePathList,
- (EFI_DEVICE_PATH_PROTOCOL *)LoadOptionPtr,
- NewLoadContext->FilePathListLength
- );
- NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);
- NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL);
- LoadOptionPtr += NewLoadContext->FilePathListLength;
- if (LoadOptionPtr < LoadOptionEnd) {
- OptionalDataSize = BootOptionSize -
- sizeof (UINT32) -
- sizeof (UINT16) -
- StringSize -
- NewLoadContext->FilePathListLength;
- NewLoadContext->OptionalData = AllocateZeroPool (OptionalDataSize);
- ASSERT (NewLoadContext->OptionalData != NULL);
- CopyMem (
- NewLoadContext->OptionalData,
- LoadOptionPtr,
- OptionalDataSize
- );
- }
- InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
- MenuCount++;
- FreePool (LoadOptionFromVar);
- }
- EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);
- if (BootNext != NULL) {
- FreePool (BootNext);
- }
- if (BootOrderList != NULL) {
- FreePool (BootOrderList);
- }
- BootOptionMenu.MenuNumber = MenuCount;
- return EFI_SUCCESS;
- }
- /**
- Find drivers that will be added as Driver#### variables from handles
- in current system environment
- All valid handles in the system except those consume SimpleFs, LoadFile
- are stored in DriverMenu for future use.
- @retval EFI_SUCCESS The function complets successfully.
- @return Other value if failed to build the DriverMenu.
- **/
- EFI_STATUS
- BOpt_FindDrivers (
- VOID
- )
- {
- UINTN NoDevicePathHandles;
- EFI_HANDLE *DevicePathHandle;
- UINTN Index;
- EFI_STATUS Status;
- BM_MENU_ENTRY *NewMenuEntry;
- BM_HANDLE_CONTEXT *NewHandleContext;
- EFI_HANDLE CurHandle;
- UINTN OptionNumber;
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;
- EFI_LOAD_FILE_PROTOCOL *LoadFile;
- SimpleFs = NULL;
- LoadFile = NULL;
- InitializeListHead (&DriverMenu.Head);
- //
- // At first, get all handles that support Device Path
- // protocol which is the basic requirement for
- // Driver####
- //
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiDevicePathProtocolGuid,
- NULL,
- &NoDevicePathHandles,
- &DevicePathHandle
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- OptionNumber = 0;
- for (Index = 0; Index < NoDevicePathHandles; Index++) {
- CurHandle = DevicePathHandle[Index];
- Status = gBS->HandleProtocol (
- CurHandle,
- &gEfiSimpleFileSystemProtocolGuid,
- (VOID **)&SimpleFs
- );
- if (Status == EFI_SUCCESS) {
- continue;
- }
- Status = gBS->HandleProtocol (
- CurHandle,
- &gEfiLoadFileProtocolGuid,
- (VOID **)&LoadFile
- );
- if (Status == EFI_SUCCESS) {
- continue;
- }
- NewMenuEntry = BOpt_CreateMenuEntry (BM_HANDLE_CONTEXT_SELECT);
- if (NULL == NewMenuEntry) {
- FreePool (DevicePathHandle);
- return EFI_OUT_OF_RESOURCES;
- }
- NewHandleContext = (BM_HANDLE_CONTEXT *)NewMenuEntry->VariableContext;
- NewHandleContext->Handle = CurHandle;
- NewHandleContext->DevicePath = DevicePathFromHandle (CurHandle);
- NewMenuEntry->DisplayString = UiDevicePathToStr (NewHandleContext->DevicePath);
- NewMenuEntry->DisplayStringToken = HiiSetString (mBmmCallbackInfo->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
- NewMenuEntry->HelpString = NULL;
- NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
- NewMenuEntry->OptionNumber = OptionNumber;
- OptionNumber++;
- InsertTailList (&DriverMenu.Head, &NewMenuEntry->Link);
- }
- if (DevicePathHandle != NULL) {
- FreePool (DevicePathHandle);
- }
- DriverMenu.MenuNumber = OptionNumber;
- return EFI_SUCCESS;
- }
- /**
- Get the Option Number that has not been allocated for use.
- @param Type The type of Option.
- @return The available Option Number.
- **/
- UINT16
- BOpt_GetOptionNumber (
- CHAR16 *Type
- )
- {
- UINT16 *OrderList;
- UINTN OrderListSize;
- UINTN Index;
- CHAR16 StrTemp[20];
- UINT16 *OptionBuffer;
- UINT16 OptionNumber;
- UINTN OptionSize;
- OrderListSize = 0;
- OrderList = NULL;
- OptionNumber = 0;
- Index = 0;
- UnicodeSPrint (StrTemp, sizeof (StrTemp), L"%sOrder", Type);
- GetEfiGlobalVariable2 (StrTemp, (VOID **)&OrderList, &OrderListSize);
- for (OptionNumber = 0; ; OptionNumber++) {
- if (OrderList != NULL) {
- for (Index = 0; Index < OrderListSize / sizeof (UINT16); Index++) {
- if (OptionNumber == OrderList[Index]) {
- break;
- }
- }
- }
- if (Index < OrderListSize / sizeof (UINT16)) {
- //
- // The OptionNumber occurs in the OrderList, continue to use next one
- //
- continue;
- }
- UnicodeSPrint (StrTemp, sizeof (StrTemp), L"%s%04x", Type, (UINTN)OptionNumber);
- DEBUG ((DEBUG_ERROR, "Option = %s\n", StrTemp));
- GetEfiGlobalVariable2 (StrTemp, (VOID **)&OptionBuffer, &OptionSize);
- if (NULL == OptionBuffer) {
- //
- // The Boot[OptionNumber] / Driver[OptionNumber] NOT occurs, we found it
- //
- break;
- }
- }
- return OptionNumber;
- }
- /**
- Get the Option Number for Boot#### that does not used.
- @return The available Option Number.
- **/
- UINT16
- BOpt_GetBootOptionNumber (
- VOID
- )
- {
- return BOpt_GetOptionNumber (L"Boot");
- }
- /**
- Get the Option Number for Driver#### that does not used.
- @return The unused Option Number.
- **/
- UINT16
- BOpt_GetDriverOptionNumber (
- VOID
- )
- {
- return BOpt_GetOptionNumber (L"Driver");
- }
- /**
- Build up all DriverOptionMenu
- @param CallbackData The BMM context data.
- @retval EFI_SUCESS The functin completes successfully.
- @retval EFI_OUT_OF_RESOURCES Not enough memory to compete the operation.
- @retval EFI_NOT_FOUND Fail to get "DriverOrder" variable.
- **/
- EFI_STATUS
- BOpt_GetDriverOptions (
- IN BMM_CALLBACK_DATA *CallbackData
- )
- {
- UINTN Index;
- UINT16 DriverString[12];
- UINT8 *LoadOptionFromVar;
- UINTN DriverOptionSize;
- UINT16 *DriverOrderList;
- UINTN DriverOrderListSize;
- BM_MENU_ENTRY *NewMenuEntry;
- BM_LOAD_CONTEXT *NewLoadContext;
- UINT8 *LoadOptionPtr;
- UINTN StringSize;
- UINTN OptionalDataSize;
- UINT8 *LoadOptionEnd;
- DriverOrderListSize = 0;
- DriverOrderList = NULL;
- DriverOptionSize = 0;
- LoadOptionFromVar = NULL;
- BOpt_FreeMenu (&DriverOptionMenu);
- InitializeListHead (&DriverOptionMenu.Head);
- //
- // Get the DriverOrder from the Var
- //
- GetEfiGlobalVariable2 (L"DriverOrder", (VOID **)&DriverOrderList, &DriverOrderListSize);
- if (DriverOrderList == NULL) {
- return EFI_NOT_FOUND;
- }
- for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {
- UnicodeSPrint (
- DriverString,
- sizeof (DriverString),
- L"Driver%04x",
- DriverOrderList[Index]
- );
- //
- // Get all loadoptions from the VAR
- //
- GetEfiGlobalVariable2 (DriverString, (VOID **)&LoadOptionFromVar, &DriverOptionSize);
- if (LoadOptionFromVar == NULL) {
- continue;
- }
- NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
- if (NULL == NewMenuEntry) {
- return EFI_OUT_OF_RESOURCES;
- }
- NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
- LoadOptionPtr = LoadOptionFromVar;
- LoadOptionEnd = LoadOptionFromVar + DriverOptionSize;
- NewMenuEntry->OptionNumber = DriverOrderList[Index];
- NewLoadContext->Deleted = FALSE;
- NewLoadContext->IsLegacy = FALSE;
- //
- // LoadOption is a pointer type of UINT8
- // for easy use with following LOAD_OPTION
- // embedded in this struct
- //
- NewLoadContext->Attributes = *(UINT32 *)LoadOptionPtr;
- LoadOptionPtr += sizeof (UINT32);
- NewLoadContext->FilePathListLength = *(UINT16 *)LoadOptionPtr;
- LoadOptionPtr += sizeof (UINT16);
- StringSize = StrSize ((UINT16 *)LoadOptionPtr);
- NewLoadContext->Description = AllocateZeroPool (StringSize);
- ASSERT (NewLoadContext->Description != NULL);
- CopyMem (
- NewLoadContext->Description,
- (UINT16 *)LoadOptionPtr,
- StringSize
- );
- NewMenuEntry->DisplayString = NewLoadContext->Description;
- NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
- LoadOptionPtr += StringSize;
- NewLoadContext->FilePathList = AllocateZeroPool (NewLoadContext->FilePathListLength);
- ASSERT (NewLoadContext->FilePathList != NULL);
- CopyMem (
- NewLoadContext->FilePathList,
- (EFI_DEVICE_PATH_PROTOCOL *)LoadOptionPtr,
- NewLoadContext->FilePathListLength
- );
- NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);
- NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL);
- LoadOptionPtr += NewLoadContext->FilePathListLength;
- if (LoadOptionPtr < LoadOptionEnd) {
- OptionalDataSize = DriverOptionSize -
- sizeof (UINT32) -
- sizeof (UINT16) -
- StringSize -
- NewLoadContext->FilePathListLength;
- NewLoadContext->OptionalData = AllocateZeroPool (OptionalDataSize);
- ASSERT (NewLoadContext->OptionalData != NULL);
- CopyMem (
- NewLoadContext->OptionalData,
- LoadOptionPtr,
- OptionalDataSize
- );
- }
- InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
- FreePool (LoadOptionFromVar);
- }
- if (DriverOrderList != NULL) {
- FreePool (DriverOrderList);
- }
- DriverOptionMenu.MenuNumber = Index;
- return EFI_SUCCESS;
- }
- /**
- Get option number according to Boot#### and BootOrder variable.
- The value is saved as #### + 1.
- @param CallbackData The BMM context data.
- **/
- VOID
- GetBootOrder (
- IN BMM_CALLBACK_DATA *CallbackData
- )
- {
- BMM_FAKE_NV_DATA *BmmConfig;
- UINT16 Index;
- UINT16 OptionOrderIndex;
- UINTN DeviceType;
- BM_MENU_ENTRY *NewMenuEntry;
- BM_LOAD_CONTEXT *NewLoadContext;
- ASSERT (CallbackData != NULL);
- DeviceType = (UINTN)-1;
- BmmConfig = &CallbackData->BmmFakeNvData;
- ZeroMem (BmmConfig->BootOptionOrder, sizeof (BmmConfig->BootOptionOrder));
- for (Index = 0, OptionOrderIndex = 0; ((Index < BootOptionMenu.MenuNumber) &&
- (OptionOrderIndex < (sizeof (BmmConfig->BootOptionOrder) / sizeof (BmmConfig->BootOptionOrder[0]))));
- Index++)
- {
- NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
- NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
- if (NewLoadContext->IsLegacy) {
- if (((BBS_BBS_DEVICE_PATH *)NewLoadContext->FilePathList)->DeviceType != DeviceType) {
- DeviceType = ((BBS_BBS_DEVICE_PATH *)NewLoadContext->FilePathList)->DeviceType;
- } else {
- //
- // Only show one legacy boot option for the same device type
- // assuming the boot options are grouped by the device type
- //
- continue;
- }
- }
- BmmConfig->BootOptionOrder[OptionOrderIndex++] = (UINT32)(NewMenuEntry->OptionNumber + 1);
- }
- }
- /**
- Get driver option order from globalc DriverOptionMenu.
- @param CallbackData The BMM context data.
- **/
- VOID
- GetDriverOrder (
- IN BMM_CALLBACK_DATA *CallbackData
- )
- {
- BMM_FAKE_NV_DATA *BmmConfig;
- UINT16 Index;
- UINT16 OptionOrderIndex;
- UINTN DeviceType;
- BM_MENU_ENTRY *NewMenuEntry;
- BM_LOAD_CONTEXT *NewLoadContext;
- ASSERT (CallbackData != NULL);
- DeviceType = (UINTN)-1;
- BmmConfig = &CallbackData->BmmFakeNvData;
- ZeroMem (BmmConfig->DriverOptionOrder, sizeof (BmmConfig->DriverOptionOrder));
- for (Index = 0, OptionOrderIndex = 0; ((Index < DriverOptionMenu.MenuNumber) &&
- (OptionOrderIndex < (sizeof (BmmConfig->DriverOptionOrder) / sizeof (BmmConfig->DriverOptionOrder[0]))));
- Index++)
- {
- NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
- NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
- if (NewLoadContext->IsLegacy) {
- if (((BBS_BBS_DEVICE_PATH *)NewLoadContext->FilePathList)->DeviceType != DeviceType) {
- DeviceType = ((BBS_BBS_DEVICE_PATH *)NewLoadContext->FilePathList)->DeviceType;
- } else {
- //
- // Only show one legacy boot option for the same device type
- // assuming the boot options are grouped by the device type
- //
- continue;
- }
- }
- BmmConfig->DriverOptionOrder[OptionOrderIndex++] = (UINT32)(NewMenuEntry->OptionNumber + 1);
- }
- }
- /**
- Boot the file specified by the input file path info.
- @param FilePath Point to the file path.
- @retval TRUE Exit caller function.
- @retval FALSE Not exit caller function.
- **/
- BOOLEAN
- EFIAPI
- BootFromFile (
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath
- )
- {
- EFI_STATUS Status;
- EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
- CHAR16 *FileName;
- Status = EFI_NOT_STARTED;
- FileName = NULL;
- FileName = ExtractFileNameFromDevicePath (FilePath);
- if (FileName != NULL) {
- Status = EfiBootManagerInitializeLoadOption (
- &BootOption,
- 0,
- LoadOptionTypeBoot,
- LOAD_OPTION_ACTIVE,
- FileName,
- FilePath,
- NULL,
- 0
- );
- }
- if (!EFI_ERROR (Status)) {
- //
- // Since current no boot from removable media directly is allowed */
- //
- gST->ConOut->ClearScreen (gST->ConOut);
- //
- // Check whether need to reset system.
- //
- BmmSetupResetReminder ();
- BmmSetConsoleMode (FALSE);
- EfiBootManagerBoot (&BootOption);
- BmmSetConsoleMode (TRUE);
- FreePool (FileName);
- EfiBootManagerFreeLoadOption (&BootOption);
- }
- return FALSE;
- }
- /**
- Display the form base on the selected file.
- @param FilePath Point to the file path.
- @param FormId The form need to display.
- **/
- BOOLEAN
- ReSendForm (
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- IN EFI_FORM_ID FormId
- )
- {
- gBootMaintenancePrivate.LoadContext->FilePathList = FilePath;
- UpdateOptionPage (&gBootMaintenancePrivate, FormId, FilePath);
- gBootMaintenancePrivate.FormBrowser2->SendForm (
- gBootMaintenancePrivate.FormBrowser2,
- &gBootMaintenancePrivate.BmmHiiHandle,
- 1,
- &mBootMaintGuid,
- FormId,
- NULL,
- NULL
- );
- return TRUE;
- }
- /**
- Create boot option base on the input file path info.
- @param FilePath Point to the file path.
- @retval TRUE Exit caller function.
- @retval FALSE Not exit caller function.
- **/
- BOOLEAN
- EFIAPI
- CreateBootOptionFromFile (
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath
- )
- {
- return ReSendForm (FilePath, FORM_BOOT_ADD_ID);
- }
- /**
- Create driver option base on the input file path info.
- @param FilePath Point to the file path.
- @retval TRUE Exit caller function.
- @retval FALSE Not exit caller function.
- **/
- BOOLEAN
- EFIAPI
- CreateDriverOptionFromFile (
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath
- )
- {
- return ReSendForm (FilePath, FORM_DRV_ADD_FILE_ID);
- }
|