/** This function will register the new Boot####, Driver#### or SysPrep#### option. After the *#### is updated, the *Order will also be updated. @param Option Pointer to load option to add. @param Position Position of the new load option to put in the ****Order variable. @retval EFI_SUCCESS The *#### have been successfully registered. @retval EFI_INVALID_PARAMETER The option number exceeds 0xFFFF. @retval EFI_ALREADY_STARTED The option number of Option is being used already. Note: this API only adds new load option, no replacement support. @retval EFI_OUT_OF_RESOURCES There is no free option number that can be used when the option number specified in the Option is LoadOptionNumberUnassigned. @retval EFI_STATUS Return the status of gRT->SetVariable (). **/ EFI_STATUS EFIAPI EfiBootManagerAddLoadOptionVariable ( IN EFI_BOOT_MANAGER_LOAD_OPTION *Option, IN UINTN Position ) { EFI_STATUS Status; UINT16 OptionNumber; if (Option == NULL) { return EFI_INVALID_PARAMETER; } if (Option->OptionType != LoadOptionTypeDriver && Option->OptionType != LoadOptionTypeSysPrep && Option->OptionType != LoadOptionTypeBoot ) { return EFI_INVALID_PARAMETER; } // // Get the free option number if the option number is unassigned // if (Option->OptionNumber == LoadOptionNumberUnassigned) { Status = BmGetFreeOptionNumber (Option->OptionType, &OptionNumber); if (EFI_ERROR (Status)) { return Status; } Option->OptionNumber = OptionNumber; } if (Option->OptionNumber >= LoadOptionNumberMax) { return EFI_INVALID_PARAMETER; } Status = BmAddOptionNumberToOrderVariable (mBmLoadOptionOrderName[Option->OptionType], (UINT16) Option->OptionNumber, Position); if (!EFI_ERROR (Status)) { // // Save the Boot#### or Driver#### variable // Status = EfiBootManagerLoadOptionToVariable (Option); if (EFI_ERROR (Status)) { // // Remove the #### from *Order variable when the Driver####/SysPrep####/Boot#### cannot be saved. // EfiBootManagerDeleteLoadOptionVariable (Option->OptionNumber, Option->OptionType); } } return Status; }
/** Delete Boot Option that represent a Deleted state in BootOptionMenu. @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to BM_LOAD_CONTEXT marked for deletion is deleted. @retval EFI_NOT_FOUND If can not find the boot option want to be deleted. @return Others If failed to update the "BootOrder" variable after deletion. **/ EFI_STATUS Var_DelBootOption ( VOID ) { BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; EFI_STATUS Status; UINTN Index; UINTN Index2; Index2 = 0; for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2)); if (NULL == NewMenuEntry) { return EFI_NOT_FOUND; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; if (!NewLoadContext->Deleted) { continue; } Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber,LoadOptionTypeBoot); if (EFI_ERROR (Status)) { return Status; } Index2++; // // If current Load Option is the same as BootNext, // must delete BootNext in order to make sure // there will be no panic on next boot // if (NewLoadContext->IsBootNext) { EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid); } RemoveEntryList (&NewMenuEntry->Link); BOpt_DestroyMenuEntry (NewMenuEntry); NewMenuEntry = NULL; } BootOptionMenu.MenuNumber -= Index2; return EFI_SUCCESS; }
/** Delete Load Option that represent a Deleted state in DriverOptionMenu. @retval EFI_SUCCESS Load Option is successfully updated. @retval EFI_NOT_FOUND Fail to find the driver option want to be deleted. @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI Variable. **/ EFI_STATUS Var_DelDriverOption ( VOID ) { BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; EFI_STATUS Status; UINTN Index; UINTN Index2; Index2 = 0; for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2)); if (NULL == NewMenuEntry) { return EFI_NOT_FOUND; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; if (!NewLoadContext->Deleted) { continue; } Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber,LoadOptionTypeDriver); if (EFI_ERROR (Status)) { return Status; } Index2++; RemoveEntryList (&NewMenuEntry->Link); BOpt_DestroyMenuEntry (NewMenuEntry); NewMenuEntry = NULL; } DriverOptionMenu.MenuNumber -= Index2; return EFI_SUCCESS; }
EFIAPI EfiBootManagerGetLoadOptions ( OUT UINTN *OptionCount, IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType ) { EFI_STATUS Status; UINT16 *OptionOrder; UINTN OptionOrderSize; UINTN Index; UINTN OptionIndex; EFI_BOOT_MANAGER_LOAD_OPTION *Options; CHAR16 OptionName[BM_OPTION_NAME_LEN]; UINT16 OptionNumber; *OptionCount = 0; if (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep || LoadOptionType == LoadOptionTypeBoot) { // // Read the BootOrder, or DriverOrder variable. // GetEfiGlobalVariable2 (mBmLoadOptionOrderName[LoadOptionType], (VOID **) &OptionOrder, &OptionOrderSize); if (OptionOrder == NULL) { return NULL; } *OptionCount = OptionOrderSize / sizeof (UINT16); Options = AllocatePool (*OptionCount * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION)); ASSERT (Options != NULL); OptionIndex = 0; for (Index = 0; Index < *OptionCount; Index++) { OptionNumber = OptionOrder[Index]; UnicodeSPrint (OptionName, sizeof (OptionName), L"%s%04x", mBmLoadOptionName[LoadOptionType], OptionNumber); Status = EfiBootManagerVariableToLoadOption (OptionName, &Options[OptionIndex]); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "[Bds] %s doesn't exist - Update ****Order variable to remove the reference!!", OptionName)); EfiBootManagerDeleteLoadOptionVariable (OptionNumber, LoadOptionType); } else { ASSERT (Options[OptionIndex].OptionNumber == OptionNumber); OptionIndex++; } } if (OptionOrder != NULL) { FreePool (OptionOrder); } if (OptionIndex < *OptionCount) { Options = ReallocatePool (*OptionCount * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION), OptionIndex * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION), Options); ASSERT (Options != NULL); *OptionCount = OptionIndex; } } else { return NULL; } return Options; }