EFI_STATUS UtilStartEfiApplication ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN UINTN LoadOptionsSize, IN VOID* LoadOptions ) { EFI_STATUS Status; EFI_BOOT_MANAGER_LOAD_OPTION NewOption; Status = EfiBootManagerInitializeLoadOption ( &NewOption, LoadOptionNumberUnassigned, LoadOptionTypeSysPrep, LOAD_OPTION_ACTIVE, L"", DevicePath, LoadOptions, LoadOptionsSize ); ASSERT_EFI_ERROR (Status); EfiBootManagerProcessLoadOption(&NewOption); Status = NewOption.Status; EfiBootManagerFreeLoadOption(&NewOption); return Status; }
/** Boot a file selected by user at File Expoloer of BMM. @param FileContext The file context data, which contains the device path of the file to be boot from. @retval EFI_SUCCESS The function completed successfull. @return Other value if the boot from the file fails. **/ EFI_STATUS BootThisFile ( IN BM_FILE_CONTEXT *FileContext ) { EFI_BOOT_MANAGER_LOAD_OPTION BootOption; EfiBootManagerInitializeLoadOption ( &BootOption, 0, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, FileContext->FileName, FileContext->DevicePath, NULL, 0 ); // // Since current no boot from removable media directly is allowed */ // gST->ConOut->ClearScreen (gST->ConOut); BdsSetConsoleMode (FALSE); EfiBootManagerBoot (&BootOption); BdsSetConsoleMode (TRUE); EfiBootManagerFreeLoadOption (&BootOption); return BootOption.Status; }
/** 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 BootFromFile ( IN EFI_DEVICE_PATH_PROTOCOL *FilePath ) { EFI_BOOT_MANAGER_LOAD_OPTION BootOption; CHAR16 *FileName; FileName = ExtractFileNameFromDevicePath(FilePath); EfiBootManagerInitializeLoadOption ( &BootOption, 0, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, FileName, FilePath, NULL, 0 ); // // Since current no boot from removable media directly is allowed */ // gST->ConOut->ClearScreen (gST->ConOut); BmmBdsSetConsoleMode (FALSE); EfiBootManagerBoot (&BootOption); BmmBdsSetConsoleMode (TRUE); FreePool(FileName); EfiBootManagerFreeLoadOption (&BootOption); return FALSE; }
/** Try to boot the boot option triggered by hot key. **/ VOID EFIAPI EfiBootManagerHotkeyBoot ( VOID ) { if (mHotkeyBootOption.OptionNumber != LoadOptionNumberUnassigned) { EfiBootManagerBoot (&mHotkeyBootOption); EfiBootManagerFreeLoadOption (&mHotkeyBootOption); mHotkeyBootOption.OptionNumber = LoadOptionNumberUnassigned; } }
/** This function attempts to boot per the boot order specified by platform policy. If the boot via Boot#### returns with a status of EFI_SUCCESS the boot manager will stop processing the BootOrder variable and present a boot manager menu to the user. If a boot via Boot#### returns a status other than EFI_SUCCESS, the boot has failed and the next Boot#### in the BootOrder variable will be tried until all possibilities are exhausted. -- Chapter 3.1.1 Boot Manager Programming, the 4th paragraph **/ VOID DefaultBootBehavior ( VOID ) { UINTN BootOptionCount; EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu; EfiBootManagerGetBootManagerMenu (&BootManagerMenu); // // BootManagerMenu always contains the correct information even the above function returns failure. // BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot); if (BootAllBootOptions (BootOptions, BootOptionCount)) { // // Follow generic rule, Call BdsDxeOnConnectConInCallBack to connect ConIn before enter UI // if (PcdGetBool (PcdConInConnectOnDemand)) { BdsDxeOnConnectConInCallBack (NULL, NULL); } // // Show the Boot Manager Menu after successful boot // EfiBootManagerBoot (&BootManagerMenu); } else { EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); // // Re-scan all EFI boot options in case all the boot#### are deleted or failed to boot // // If no valid boot options exist, the boot manager will enumerate all removable media // devices followed by all fixed media devices. The order within each group is undefined. // These new default boot options are not saved to non volatile storage.The boot manger // will then attempt toboot from each boot option. // -- Chapter 3.3 Boot Manager Programming, the 2nd paragraph // EfiBootManagerConnectAll (); BootOptions = BdsEnumerateBootOptions (&BootOptionCount); if (!BootAllBootOptions (BootOptions, BootOptionCount)) { DEBUG ((EFI_D_ERROR, "[Bds]No bootable device!\n")); EfiBootManagerBoot (&BootManagerMenu); } } EfiBootManagerFreeLoadOption (&BootManagerMenu); EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); }
VOID PlatformRegisterFvBootOption ( EFI_GUID *FileGuid, CHAR16 *Description, UINT32 Attributes ) { EFI_STATUS Status; UINTN OptionIndex; EFI_BOOT_MANAGER_LOAD_OPTION NewOption; EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; UINTN BootOptionCount; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_DEVICE_PATH_PROTOCOL *DevicePath; Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage); ASSERT_EFI_ERROR (Status); EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); DevicePath = AppendDevicePathNode ( DevicePathFromHandle (LoadedImage->DeviceHandle), (EFI_DEVICE_PATH_PROTOCOL *) &FileNode ); Status = EfiBootManagerInitializeLoadOption ( &NewOption, LoadOptionNumberUnassigned, LoadOptionTypeBoot, Attributes, Description, DevicePath, NULL, 0 ); if (!EFI_ERROR (Status)) { BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot); OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount); if (OptionIndex == -1) { Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1); ASSERT_EFI_ERROR (Status); } EfiBootManagerFreeLoadOption (&NewOption); EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); } }
/** Free an EFI_BOOT_MANGER_LOAD_OPTION array that was allocated by EfiBootManagerGetLoadOptions(). @param Option Pointer to boot option array to free. @param OptionCount Number of array entries in BootOption @return EFI_SUCCESS BootOption was freed @return EFI_NOT_FOUND BootOption == NULL **/ EFI_STATUS EFIAPI EfiBootManagerFreeLoadOptions ( IN EFI_BOOT_MANAGER_LOAD_OPTION *Option, IN UINTN OptionCount ) { UINTN Index; if (Option == NULL) { return EFI_NOT_FOUND; } for (Index = 0;Index < OptionCount; Index++) { EfiBootManagerFreeLoadOption (&Option[Index]); } FreePool (Option); return EFI_SUCCESS; }
/** Create one boot option for BootManagerMenuApp. @param FileGuid Input file guid for the BootManagerMenuApp. @param Description Description of the BootManagerMenuApp boot option. @param Position Position of the new load option to put in the ****Order variable. @param IsBootCategory Whether this is a boot category. @retval OptionNumber Return the option number info. **/ UINTN RegisterBootManagerMenuAppBootOption ( EFI_GUID *FileGuid, CHAR16 *Description, UINTN Position, BOOLEAN IsBootCategory ) { EFI_STATUS Status; EFI_BOOT_MANAGER_LOAD_OPTION NewOption; EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN OptionNumber; DevicePath = FvFilePath (FileGuid); Status = EfiBootManagerInitializeLoadOption ( &NewOption, LoadOptionNumberUnassigned, LoadOptionTypeBoot, IsBootCategory ? LOAD_OPTION_ACTIVE : LOAD_OPTION_CATEGORY_APP, Description, DevicePath, NULL, 0 ); ASSERT_EFI_ERROR (Status); FreePool (DevicePath); Status = EfiBootManagerAddLoadOptionVariable (&NewOption, Position); ASSERT_EFI_ERROR (Status); OptionNumber = NewOption.OptionNumber; EfiBootManagerFreeLoadOption (&NewOption); return OptionNumber; }
/** Group the legacy boot options in the BootOption. The routine assumes the boot options in the beginning that covers all the device types are ordered properly and re-position the following boot options just after the corresponding boot options with the same device type. For example: 1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0] Assuming [Harddisk1 CdRom2 Efi1] is ordered properly Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0] 2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2] Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2] **/ VOID GroupMultipleLegacyBootOption4SameType ( VOID ) { EFI_STATUS Status; UINTN Index; UINTN DeviceIndex; UINTN DeviceTypeIndex[7]; UINTN *NextIndex; UINT16 OptionNumber; UINT16 *BootOrder; UINTN BootOrderSize; CHAR16 OptionName[sizeof ("Boot####")]; EFI_BOOT_MANAGER_LOAD_OPTION BootOption; SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xff); GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize); if (BootOrder == NULL) { return; } for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]); Status = EfiBootManagerVariableToLoadOption (OptionName, &BootOption); ASSERT_EFI_ERROR (Status); if ((DevicePathType (BootOption.FilePath) == BBS_DEVICE_PATH) && (DevicePathSubType (BootOption.FilePath) == BBS_BBS_DP)) { // // Legacy Boot Option // DEBUG ((EFI_D_ERROR, "[BootManagerDxe] ==== Find Legacy Boot Option 0x%x! ==== \n", Index)); ASSERT ((((BBS_BBS_DEVICE_PATH *) BootOption.FilePath)->DeviceType & 0xF) < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0])); NextIndex = &DeviceTypeIndex[((BBS_BBS_DEVICE_PATH *) BootOption.FilePath)->DeviceType & 0xF]; if (*NextIndex == (UINTN) -1) { // // *NextIndex is the Index in BootOrder to put the next Option Number for the same type // *NextIndex = Index + 1; } else { // // insert the current boot option before *NextIndex, causing [*Next .. Index] shift right one position // OptionNumber = BootOrder[Index]; CopyMem (&BootOrder[*NextIndex + 1], &BootOrder[*NextIndex], (Index - *NextIndex) * sizeof (UINT16)); BootOrder[*NextIndex] = OptionNumber; // // Update the DeviceTypeIndex array to reflect the right shift operation // for (DeviceIndex = 0; DeviceIndex < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]); DeviceIndex++) { if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && DeviceTypeIndex[DeviceIndex] >= *NextIndex) { DeviceTypeIndex[DeviceIndex]++; } } } } EfiBootManagerFreeLoadOption (&BootOption); } gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, VAR_FLAG, BootOrderSize, BootOrder ); FreePool (BootOrder); }
/** Re-order the Boot Option according to the DevOrder. The routine re-orders the Boot Option in BootOption array according to the order specified by DevOrder. @param DevOrder Pointer to buffer containing the BBS Index, high 8-bit value 0xFF indicating a disabled boot option @param DevOrderCount Count of the BBS Index @param EnBootOption Callee allocated buffer containing the enabled Boot Option Numbers @param EnBootOptionCount Count of the enabled Boot Option Numbers @param DisBootOption Callee allocated buffer containing the disabled Boot Option Numbers @param DisBootOptionCount Count of the disabled Boot Option Numbers **/ VOID OrderLegacyBootOption4SameType ( UINT16 *DevOrder, UINTN DevOrderCount, UINT16 **EnBootOption, UINTN *EnBootOptionCount, UINT16 **DisBootOption, UINTN *DisBootOptionCount ) { EFI_STATUS Status; UINT16 *NewBootOption; UINT16 *BootOrder; UINTN BootOrderSize; UINTN Index; UINTN StartPosition; EFI_BOOT_MANAGER_LOAD_OPTION BootOption; CHAR16 OptionName[sizeof ("Boot####")]; UINT16 *BbsIndexArray; UINT16 *DeviceTypeArray; GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize); ASSERT (BootOrder != NULL); BbsIndexArray = AllocatePool (BootOrderSize); DeviceTypeArray = AllocatePool (BootOrderSize); *EnBootOption = AllocatePool (BootOrderSize); *DisBootOption = AllocatePool (BootOrderSize); *DisBootOptionCount = 0; *EnBootOptionCount = 0; Index = 0; ASSERT (*EnBootOption != NULL); ASSERT (*DisBootOption != NULL); for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]); Status = EfiBootManagerVariableToLoadOption (OptionName, &BootOption); ASSERT_EFI_ERROR (Status); if ((DevicePathType (BootOption.FilePath) == BBS_DEVICE_PATH) && (DevicePathSubType (BootOption.FilePath) == BBS_BBS_DP)) { // // Legacy Boot Option // ASSERT (BootOption.OptionalDataSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA)); DeviceTypeArray[Index] = ((BBS_BBS_DEVICE_PATH *) BootOption.FilePath)->DeviceType; BbsIndexArray [Index] = ((LEGACY_BOOT_OPTION_BBS_DATA *) BootOption.OptionalData)->BbsIndex; } else { DeviceTypeArray[Index] = BBS_TYPE_UNKNOWN; BbsIndexArray [Index] = 0xFFFF; } EfiBootManagerFreeLoadOption (&BootOption); } // // Record the corresponding Boot Option Numbers according to the DevOrder // Record the EnBootOption and DisBootOption according to the DevOrder // StartPosition = BootOrderSize / sizeof (UINT16); NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16)); while (DevOrderCount-- != 0) { for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { if (BbsIndexArray[Index] == (DevOrder[DevOrderCount] & 0xFF)) { StartPosition = MIN (StartPosition, Index); NewBootOption[DevOrderCount] = BootOrder[Index]; if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) { (*DisBootOption)[*DisBootOptionCount] = BootOrder[Index]; (*DisBootOptionCount)++; } else { (*EnBootOption)[*EnBootOptionCount] = BootOrder[Index]; (*EnBootOptionCount)++; } break; } } } // // Overwrite the old BootOption // CopyMem (&BootOrder[StartPosition], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16)); Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, VAR_FLAG, BootOrderSize, BootOrder ); ASSERT_EFI_ERROR (Status); FreePool (NewBootOption); FreePool (DeviceTypeArray); FreePool (BbsIndexArray); }
/** This function create a currently loaded Boot Option from the BMM. It then appends this Boot Option to the end of the "BootOrder" list. It also append this Boot Opotion to the end of BootOptionMenu. @param CallbackData The BMM context data. @retval other Contain some errors when excuting this function. See function EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl for detail return information. @retval EFI_SUCCESS If function completes successfully. **/ EFI_STATUS Var_UpdateBootOption ( IN BMM_CALLBACK_DATA *CallbackData ) { UINT16 BootString[10]; UINT16 Index; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; BOOLEAN OptionalDataExist; EFI_STATUS Status; BMM_FAKE_NV_DATA *NvRamMap; EFI_BOOT_MANAGER_LOAD_OPTION LoadOption; UINT8 *OptionalData; UINT32 OptionalDataSize; OptionalDataExist = FALSE; NvRamMap = &CallbackData->BmmFakeNvData; OptionalData = NULL; OptionalDataSize = 0; Index = BOpt_GetBootOptionNumber () ; UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index); if (NvRamMap->BootDescriptionData[0] == 0x0000) { StrCpyS (NvRamMap->BootDescriptionData, sizeof (NvRamMap->BootDescriptionData) / sizeof (NvRamMap->BootDescriptionData[0]), BootString); } if (NvRamMap->BootOptionalData[0] != 0x0000) { OptionalDataExist = TRUE; OptionalData = (UINT8 *)NvRamMap->BootOptionalData; OptionalDataSize = (UINT32)StrSize (NvRamMap->BootOptionalData); } NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } Status = EfiBootManagerInitializeLoadOption ( &LoadOption, Index, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, NvRamMap->BootDescriptionData, CallbackData->LoadContext->FilePathList, OptionalData, OptionalDataSize ); if (EFI_ERROR (Status)){ return Status; } Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 ); if (EFI_ERROR (Status)) { EfiBootManagerFreeLoadOption(&LoadOption); return Status; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; NewLoadContext->Attributes = LoadOption.Attributes; NewLoadContext->FilePathListLength = (UINT16) GetDevicePathSize (LoadOption.FilePath); NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData)); ASSERT (NewLoadContext->Description != NULL); NewMenuEntry->DisplayString = NewLoadContext->Description; CopyMem ( NewLoadContext->Description, LoadOption.Description, StrSize (NvRamMap->BootDescriptionData) ); NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); ASSERT (NewLoadContext->FilePathList != NULL); CopyMem ( NewLoadContext->FilePathList, LoadOption.FilePath, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->OptionNumber = Index; NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL); NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL); if (OptionalDataExist) { NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize); ASSERT (NewLoadContext->OptionalData != NULL); CopyMem ( NewLoadContext->OptionalData, LoadOption.OptionalData, LoadOption.OptionalDataSize ); } InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link); BootOptionMenu.MenuNumber++; EfiBootManagerFreeLoadOption(&LoadOption); return EFI_SUCCESS; }
/** This function create a currently loaded Drive Option from the BMM. It then appends this Driver Option to the end of the "DriverOrder" list. It append this Driver Opotion to the end of DriverOptionMenu. @param CallbackData The BMM context data. @param HiiHandle The HII handle associated with the BMM formset. @param DescriptionData The description of this driver option. @param OptionalData The optional load option. @param ForceReconnect If to force reconnect. @retval other Contain some errors when excuting this function.See function EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl for detail return information. @retval EFI_SUCCESS If function completes successfully. **/ EFI_STATUS Var_UpdateDriverOption ( IN BMM_CALLBACK_DATA *CallbackData, IN EFI_HII_HANDLE HiiHandle, IN UINT16 *DescriptionData, IN UINT16 *OptionalData, IN UINT8 ForceReconnect ) { UINT16 Index; UINT16 DriverString[12]; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; BOOLEAN OptionalDataExist; EFI_STATUS Status; EFI_BOOT_MANAGER_LOAD_OPTION LoadOption; UINT8 *OptionalDesData; UINT32 OptionalDataSize; OptionalDataExist = FALSE; OptionalDesData = NULL; OptionalDataSize = 0; Index = BOpt_GetDriverOptionNumber (); UnicodeSPrint ( DriverString, sizeof (DriverString), L"Driver%04x", Index ); if (*DescriptionData == 0x0000) { StrCpyS (DescriptionData, MAX_MENU_NUMBER, DriverString); } if (*OptionalData != 0x0000) { OptionalDataExist = TRUE; OptionalDesData = (UINT8 *)OptionalData; OptionalDataSize = (UINT32)StrSize (OptionalData); } NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } Status = EfiBootManagerInitializeLoadOption ( &LoadOption, Index, LoadOptionTypeDriver, LOAD_OPTION_ACTIVE | (ForceReconnect << 1), DescriptionData, CallbackData->LoadContext->FilePathList, OptionalDesData, OptionalDataSize ); if (EFI_ERROR (Status)){ return Status; } Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 ); if (EFI_ERROR (Status)) { EfiBootManagerFreeLoadOption(&LoadOption); return Status; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; NewLoadContext->Attributes = LoadOption.Attributes; NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath); NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData)); ASSERT (NewLoadContext->Description != NULL); NewMenuEntry->DisplayString = NewLoadContext->Description; CopyMem ( NewLoadContext->Description, LoadOption.Description, StrSize (DescriptionData) ); NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); ASSERT (NewLoadContext->FilePathList != NULL); CopyMem ( NewLoadContext->FilePathList, LoadOption.FilePath, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->OptionNumber = Index; NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL); NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL); if (OptionalDataExist) { NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize); ASSERT (NewLoadContext->OptionalData != NULL); CopyMem ( NewLoadContext->OptionalData, LoadOption.OptionalData, LoadOption.OptionalDataSize ); } InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link); DriverOptionMenu.MenuNumber++; EfiBootManagerFreeLoadOption(&LoadOption); return EFI_SUCCESS; }