VOID BOpt_FreeLegacyOptions ( VOID ) { BOpt_FreeMenu (&LegacyFDMenu); BOpt_FreeMenu (&LegacyHDMenu); BOpt_FreeMenu (&LegacyCDMenu); BOpt_FreeMenu (&LegacyNETMenu); BOpt_FreeMenu (&LegacyBEVMenu); }
/** Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu @retval EFI_SUCCESS The function always complete successfully. **/ EFI_STATUS FreeAllConsoles ( VOID ) { BOpt_FreeMenu (&ConsoleOutMenu); BOpt_FreeMenu (&ConsoleInpMenu); BOpt_FreeMenu (&ConsoleErrMenu); BOpt_FreeMenu (&TerminalMenu); return EFI_SUCCESS; }
/** Free up all Menu Option list. **/ VOID FreeAllMenu ( VOID ) { BOpt_FreeMenu (&DirectoryMenu); BOpt_FreeMenu (&FsOptionMenu); BOpt_FreeMenu (&BootOptionMenu); BOpt_FreeMenu (&DriverOptionMenu); BOpt_FreeMenu (&DriverMenu); BOpt_FreeLegacyOptions (); FreeAllConsoles (); }
/** Free up all Menu Option list. **/ VOID FreeAllMenu ( VOID ) { if (!mAllMenuInit){ return; } BOpt_FreeMenu (&BootOptionMenu); BOpt_FreeMenu (&DriverOptionMenu); BOpt_FreeMenu (&DriverMenu); FreeAllConsoles (); mAllMenuInit = FALSE; }
/** This function update the "BootOrder" EFI Variable based on BMM Formset's NV map. It then refresh BootOptionMenu with the new "BootOrder" list. @param CallbackData The BMM context data. @retval EFI_SUCCESS The function complete successfully. @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function. @return The EFI variable can not be saved. See gRT->SetVariable for detail return information. **/ EFI_STATUS Var_UpdateBootOrder ( IN BMM_CALLBACK_DATA *CallbackData ) { EFI_STATUS Status; UINT16 Index; UINT16 OrderIndex; UINT16 *BootOrderList; UINTN BootOrderListSize; UINT16 OptionNumber; BootOrderList = NULL; BootOrderListSize = 0; // // First check whether BootOrder is present in current configuration // BootOrderList = BdsLibGetVariableAndSize ( L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderListSize ); if (BootOrderList == NULL) { return EFI_OUT_OF_RESOURCES; } ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionOrder) / sizeof (CallbackData->BmmFakeNvData.BootOptionOrder[0]))); for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] != 0); OrderIndex++) { for (Index = OrderIndex; Index < BootOrderListSize / sizeof (UINT16); Index++) { if ((BootOrderList[Index] == (UINT16) (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) { OptionNumber = BootOrderList[Index]; CopyMem (&BootOrderList[OrderIndex + 1], &BootOrderList[OrderIndex], (Index - OrderIndex) * sizeof (UINT16)); BootOrderList[OrderIndex] = OptionNumber; } } } Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BootOrderListSize, BootOrderList ); // // Changing the content without increasing its size with current variable implementation shouldn't fail. // ASSERT_EFI_ERROR (Status); FreePool (BootOrderList); GroupMultipleLegacyBootOption4SameType (); BOpt_FreeMenu (&BootOptionMenu); BOpt_GetBootOptions (CallbackData); return Status; }
/** This function update the "DriverOrder" EFI Variable based on BMM Formset's NV map. It then refresh DriverOptionMenu with the new "DriverOrder" list. @param CallbackData The BMM context data. @retval EFI_SUCCESS The function complete successfully. @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function. @return The EFI variable can not be saved. See gRT->SetVariable for detail return information. **/ EFI_STATUS Var_UpdateDriverOrder ( IN BMM_CALLBACK_DATA *CallbackData ) { EFI_STATUS Status; UINT16 Index; UINT16 *DriverOrderList; UINT16 *NewDriverOrderList; UINTN DriverOrderListSize; DriverOrderList = NULL; DriverOrderListSize = 0; // // First check whether DriverOrder is present in current configuration // DriverOrderList = BdsLibGetVariableAndSize ( L"DriverOrder", &gEfiGlobalVariableGuid, &DriverOrderListSize ); NewDriverOrderList = AllocateZeroPool (DriverOrderListSize); if (NewDriverOrderList == NULL) { return EFI_OUT_OF_RESOURCES; } // // If exists, delete it to hold new DriverOrder // if (DriverOrderList != NULL) { EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid); FreePool (DriverOrderList); } ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder) / sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder[0]))); for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) { NewDriverOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.DriverOptionOrder[Index] - 1); } Status = gRT->SetVariable ( L"DriverOrder", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, DriverOrderListSize, NewDriverOrderList ); // // Changing the content without increasing its size with current variable implementation shouldn't fail. // ASSERT_EFI_ERROR (Status); BOpt_FreeMenu (&DriverOptionMenu); BOpt_GetDriverOptions (CallbackData); return EFI_SUCCESS; }
/** This function update the "DriverOrder" EFI Variable based on BMM Formset's NV map. It then refresh DriverOptionMenu with the new "DriverOrder" list. @param CallbackData The BMM context data. @retval EFI_SUCCESS The function complete successfully. @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function. @return The EFI variable can not be saved. See gRT->SetVariable for detail return information. **/ EFI_STATUS Var_UpdateDriverOrder ( IN BMM_CALLBACK_DATA *CallbackData ) { EFI_STATUS Status; UINT16 Index; UINT16 *DriverOrderList; UINT16 *NewDriverOrderList; UINTN DriverOrderListSize; DriverOrderList = NULL; DriverOrderListSize = 0; // // First check whether DriverOrder is present in current configuration // GetEfiGlobalVariable2 (L"DriverOrder", (VOID **) &DriverOrderList, &DriverOrderListSize); NewDriverOrderList = AllocateZeroPool (DriverOrderListSize); if (NewDriverOrderList == NULL) { return EFI_OUT_OF_RESOURCES; } // // If exists, delete it to hold new DriverOrder // if (DriverOrderList != NULL) { EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid); FreePool (DriverOrderList); } ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder) / sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder[0]))); for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) { NewDriverOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.DriverOptionOrder[Index] - 1); } Status = gRT->SetVariable ( L"DriverOrder", &gEfiGlobalVariableGuid, VAR_FLAG, DriverOrderListSize, NewDriverOrderList ); if (EFI_ERROR (Status)) { return Status; } BOpt_FreeMenu (&DriverOptionMenu); BOpt_GetDriverOptions (CallbackData); return EFI_SUCCESS; }
EFI_STATUS FreeAllConsoles ( VOID ) /*++ Routine Description: Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu Arguments: Returns: EFI_SUCCESS Others --*/ { BOpt_FreeMenu (&ConsoleOutMenu); BOpt_FreeMenu (&ConsoleInpMenu); BOpt_FreeMenu (&ConsoleErrMenu); BOpt_FreeMenu (&TerminalMenu); return EFI_SUCCESS; }
/** This function update the "BootOrder" EFI Variable based on BMM Formset's NV map. It then refresh BootOptionMenu with the new "BootOrder" list. @param CallbackData The BMM context data. @retval EFI_SUCCESS The function complete successfully. @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function. @return The EFI variable can not be saved. See gRT->SetVariable for detail return information. **/ EFI_STATUS Var_UpdateBootOrder ( IN BMM_CALLBACK_DATA *CallbackData ) { EFI_STATUS Status; UINT16 Index; UINT16 OrderIndex; UINT16 *BootOrder; UINTN BootOrderSize; UINT16 OptionNumber; // // First check whether BootOrder is present in current configuration // GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize); if (BootOrder == NULL) { return EFI_OUT_OF_RESOURCES; } ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionOrder) / sizeof (CallbackData->BmmFakeNvData.BootOptionOrder[0]))); // // OptionOrder is subset of BootOrder // for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] != 0); OrderIndex++) { for (Index = OrderIndex; Index < BootOrderSize / sizeof (UINT16); Index++) { if ((BootOrder[Index] == (UINT16) (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) { OptionNumber = BootOrder[Index]; CopyMem (&BootOrder[OrderIndex + 1], &BootOrder[OrderIndex], (Index - OrderIndex) * sizeof (UINT16)); BootOrder[OrderIndex] = OptionNumber; } } } Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, VAR_FLAG, BootOrderSize, BootOrder ); FreePool (BootOrder); BOpt_FreeMenu (&BootOptionMenu); BOpt_GetBootOptions (CallbackData); return Status; }
/** Update the file explower page with the refershed file system. @param CallbackData BMM context data @param KeyValue Key value to identify the type of data to expect. @retval TRUE Inform the caller to create a callback packet to exit file explorer. @retval FALSE Indicate that there is no need to exit file explorer. **/ BOOLEAN UpdateFileExplorer ( IN BMM_CALLBACK_DATA *CallbackData, IN UINT16 KeyValue ) { UINT16 FileOptionMask; BM_MENU_ENTRY *NewMenuEntry; BM_FILE_CONTEXT *NewFileContext; EFI_FORM_ID FormId; BOOLEAN ExitFileExplorer; EFI_STATUS Status; NewMenuEntry = NULL; NewFileContext = NULL; ExitFileExplorer = FALSE; FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue); if (FileExplorerDisplayUnknown == CallbackData->FeDisplayContext) { // // First in, display file system. // BOpt_FreeMenu (&FsOptionMenu); BOpt_FindFileSystem (CallbackData); CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &FsOptionMenu); UpdateFileExplorePage (CallbackData, &FsOptionMenu); CallbackData->FeDisplayContext = FileExplorerDisplayFileSystem; } else { if (FileExplorerDisplayFileSystem == CallbackData->FeDisplayContext) { NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask); } else if (FileExplorerDisplayDirectory == CallbackData->FeDisplayContext) { NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask); } NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext; if (NewFileContext->IsDir ) { CallbackData->FeDisplayContext = FileExplorerDisplayDirectory; RemoveEntryList (&NewMenuEntry->Link); BOpt_FreeMenu (&DirectoryMenu); Status = BOpt_FindFiles (CallbackData, NewMenuEntry); if (EFI_ERROR (Status)) { ExitFileExplorer = TRUE; goto exit; } CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &DirectoryMenu); BOpt_DestroyMenuEntry (NewMenuEntry); UpdateFileExplorePage (CallbackData, &DirectoryMenu); } else { switch (CallbackData->FeCurrentState) { case FileExplorerStateBootFromFile: // // Here boot from file // BootThisFile (NewFileContext); ExitFileExplorer = TRUE; break; case FileExplorerStateAddBootOption: case FileExplorerStateAddDriverOptionState: if (FileExplorerStateAddBootOption == CallbackData->FeCurrentState) { FormId = FORM_BOOT_ADD_DESCRIPTION_ID; } else { FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID; } CallbackData->MenuEntry = NewMenuEntry; CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath; // // Create Subtitle op-code for the display string of the option. // RefreshUpdateData (); mStartLabel->Number = FormId; HiiCreateSubTitleOpCode ( mStartOpCodeHandle, NewMenuEntry->DisplayStringToken, 0, 0, 0 ); HiiUpdateForm ( CallbackData->FeHiiHandle, &mFileExplorerGuid, FormId, mStartOpCodeHandle, // Label FormId mEndOpCodeHandle // LABEL_END ); break; default: break; } } } exit: return ExitFileExplorer; }
BOOLEAN UpdateFileExplorer ( IN BMM_CALLBACK_DATA *CallbackData, IN UINT16 KeyValue ) /*++ Routine Description: Update the file explower page with the refershed file system. Arguments: CallbackData - BMM context data KeyValue - Key value to identify the type of data to expect. Returns: TRUE - Inform the caller to create a callback packet to exit file explorer. FALSE - Indicate that there is no need to exit file explorer. --*/ { UINT16 FileOptionMask; BM_MENU_ENTRY *NewMenuEntry; BM_FILE_CONTEXT *NewFileContext; FORM_ID FormId; BOOLEAN ExitFileExplorer; EFI_STATUS Status; NewMenuEntry = NULL; NewFileContext = NULL; ExitFileExplorer = FALSE; FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue); if (UNKNOWN_CONTEXT == CallbackData->FeDisplayContext) { // // First in, display file system. // BOpt_FreeMenu (&FsOptionMenu); BOpt_FindFileSystem (CallbackData); CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &FsOptionMenu); UpdateFileExplorePage (CallbackData, &FsOptionMenu); CallbackData->FeDisplayContext = FILE_SYSTEM; } else { if (FILE_SYSTEM == CallbackData->FeDisplayContext) { NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask); } else if (DIRECTORY == CallbackData->FeDisplayContext) { NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask); } NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext; if (NewFileContext->IsDir ) { CallbackData->FeDisplayContext = DIRECTORY; RemoveEntryList (&NewMenuEntry->Link); BOpt_FreeMenu (&DirectoryMenu); Status = BOpt_FindFiles (CallbackData, NewMenuEntry); if (EFI_ERROR (Status)) { ExitFileExplorer = TRUE; goto exit; } CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &DirectoryMenu); BOpt_DestroyMenuEntry (NewMenuEntry); UpdateFileExplorePage (CallbackData, &DirectoryMenu); } else { switch (CallbackData->FeCurrentState) { case BOOT_FROM_FILE_STATE: // // Here boot from file // BootThisFile (NewFileContext); ExitFileExplorer = TRUE; break; case ADD_BOOT_OPTION_STATE: case ADD_DRIVER_OPTION_STATE: if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) { FormId = FORM_BOOT_ADD_DESCRIPTION_ID; } else { FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID; } CallbackData->MenuEntry = NewMenuEntry; CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath; // // Clean up file explore page. // RefreshUpdateData (FALSE, 0, FALSE, 0, 1); // // Remove the Subtitle op-code. // CallbackData->Hii->UpdateForm ( CallbackData->Hii, CallbackData->FeHiiHandle, FormId, FALSE, UpdateData ); // // Create Subtitle op-code for the display string of the option. // RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->FeCallbackHandle, FALSE, 0, 1); CreateSubTitleOpCode ( NewMenuEntry->DisplayStringToken, &UpdateData->Data ); CallbackData->Hii->UpdateForm ( CallbackData->Hii, CallbackData->FeHiiHandle, FormId, TRUE, UpdateData ); break; default: break; } } } exit: return ExitFileExplorer; }
EFI_STATUS BOpt_GetBootOptions ( IN BMM_CALLBACK_DATA *CallbackData ) /*++ Routine Description: Build the BootOptionMenu according to BootOrder Variable. This Routine will access the Boot#### to get EFI_LOAD_OPTION Arguments: None Returns: The number of the Var Boot#### --*/ { UINTN Index; UINT16 BootString[10]; UINT8 *LoadOptionFromVar; UINT8 *LoadOption; 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; MenuCount = 0; BootOrderListSize = 0; BootNextSize = 0; BootOrderList = NULL; BootNext = NULL; LoadOptionFromVar = NULL; BOpt_FreeMenu (&BootOptionMenu); InitializeListHead (&BootOptionMenu.Head); // // Get the BootOrder from the Var // BootOrderList = BdsLibGetVariableAndSize ( L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderListSize ); // // Get the BootNext from the Var // BootNext = BdsLibGetVariableAndSize ( L"BootNext", &gEfiGlobalVariableGuid, &BootNextSize ); if (BootNext) { if (BootNextSize != sizeof (UINT16)) { SafeFreePool (BootNext); BootNext = NULL; } } for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) { SPrint (BootString, sizeof (BootString), L"Boot%04x", BootOrderList[Index]); // // Get all loadoptions from the VAR // LoadOptionFromVar = BdsLibGetVariableAndSize ( BootString, &gEfiGlobalVariableGuid, &BootOptionSize ); if (!LoadOptionFromVar) { continue; } LoadOption = EfiAllocateZeroPool (BootOptionSize); if (!LoadOption) { continue; } EfiCopyMem (LoadOption, LoadOptionFromVar, BootOptionSize); SafeFreePool (LoadOptionFromVar); if (BootNext) { BootNextFlag = (BOOLEAN) (*BootNext == BootOrderList[Index]); } else { BootNextFlag = FALSE; } if (0 == (*((UINT32 *) LoadOption) & LOAD_OPTION_ACTIVE)) { SafeFreePool (LoadOption); continue; } // // BUGBUG: could not return EFI_OUT_OF_RESOURCES here directly. // the buffer allocated already should be freed before returning. // NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; LoadOptionPtr = LoadOption; LoadOptionEnd = LoadOption + BootOptionSize; NewMenuEntry->OptionNumber = BootOrderList[Index]; NewLoadContext->LoadOptionModified = FALSE; NewLoadContext->Deleted = FALSE; NewLoadContext->IsBootNext = BootNextFlag; // // Is a Legacy Device? // Ptr = (UINT8 *) LoadOption; // // Attribute = *(UINT32 *)Ptr; // Ptr += sizeof (UINT32); // // FilePathSize = *(UINT16 *)Ptr; // Ptr += sizeof (UINT16); // // Description = (CHAR16 *)Ptr; // Ptr += EfiStrSize ((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->LoadOption = LoadOption; NewLoadContext->LoadOptionSize = BootOptionSize; NewLoadContext->Attributes = *(UINT32 *) LoadOptionPtr; NewLoadContext->IsActive = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE); NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT); LoadOptionPtr += sizeof (UINT32); NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr; LoadOptionPtr += sizeof (UINT16); StringSize = EfiStrSize ((UINT16 *) LoadOptionPtr); NewLoadContext->Description = EfiAllocateZeroPool (StringSize); ASSERT (NewLoadContext->Description != NULL); EfiCopyMem ( NewLoadContext->Description, (UINT16 *) LoadOptionPtr, StringSize ); NewMenuEntry->DisplayString = NewLoadContext->Description; LoadOptionPtr += StringSize; NewLoadContext->FilePathList = EfiAllocateZeroPool (NewLoadContext->FilePathListLength); ASSERT (NewLoadContext->FilePathList != NULL); EfiCopyMem ( NewLoadContext->FilePathList, (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr, NewLoadContext->FilePathListLength ); NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionStrDepository ); NewMenuEntry->HelpStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionHelpStrDepository ); LoadOptionPtr += NewLoadContext->FilePathListLength; if (LoadOptionPtr < LoadOptionEnd) { OptionalDataSize = BootOptionSize - sizeof (UINT32) - sizeof (UINT16) - StringSize - NewLoadContext->FilePathListLength; NewLoadContext->OptionalData = EfiAllocateZeroPool (OptionalDataSize); ASSERT (NewLoadContext->OptionalData != NULL); EfiCopyMem ( NewLoadContext->OptionalData, LoadOptionPtr, OptionalDataSize ); NewLoadContext->OptionalDataSize = OptionalDataSize; } InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link); MenuCount++; } SafeFreePool (BootNext); SafeFreePool (BootOrderList); BootOptionMenu.MenuNumber = MenuCount; return MenuCount; }
EFI_STATUS BOpt_GetDriverOptions ( IN BMM_CALLBACK_DATA *CallbackData ) /*++ Routine Description: Build up all DriverOptionMenu Arguments: Returns: The Option Number --*/ { UINTN Index; UINT16 DriverString[12]; UINT8 *LoadOptionFromVar; UINT8 *LoadOption; 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 // DriverOrderList = BdsLibGetVariableAndSize ( L"DriverOrder", &gEfiGlobalVariableGuid, &DriverOrderListSize ); for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) { SPrint ( DriverString, sizeof (DriverString), L"Driver%04x", DriverOrderList[Index] ); // // Get all loadoptions from the VAR // LoadOptionFromVar = BdsLibGetVariableAndSize ( DriverString, &gEfiGlobalVariableGuid, &DriverOptionSize ); if (!LoadOptionFromVar) { continue; } LoadOption = EfiAllocateZeroPool (DriverOptionSize); if (!LoadOption) { continue; } EfiCopyMem (LoadOption, LoadOptionFromVar, DriverOptionSize); SafeFreePool (LoadOptionFromVar); NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; LoadOptionPtr = LoadOption; LoadOptionEnd = LoadOption + DriverOptionSize; NewMenuEntry->OptionNumber = DriverOrderList[Index]; NewLoadContext->LoadOptionModified = FALSE; 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->LoadOption = LoadOption; NewLoadContext->LoadOptionSize = DriverOptionSize; NewLoadContext->Attributes = *(UINT32 *) LoadOptionPtr; NewLoadContext->IsActive = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE); NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT); LoadOptionPtr += sizeof (UINT32); NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr; LoadOptionPtr += sizeof (UINT16); StringSize = EfiStrSize ((UINT16 *) LoadOptionPtr); NewLoadContext->Description = EfiAllocateZeroPool (StringSize); ASSERT (NewLoadContext->Description != NULL); EfiCopyMem ( NewLoadContext->Description, (UINT16 *) LoadOptionPtr, StringSize ); NewMenuEntry->DisplayString = NewLoadContext->Description; LoadOptionPtr += StringSize; NewLoadContext->FilePathList = EfiAllocateZeroPool (NewLoadContext->FilePathListLength); ASSERT (NewLoadContext->FilePathList != NULL); EfiCopyMem ( NewLoadContext->FilePathList, (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr, NewLoadContext->FilePathListLength ); NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, DriverOptionStrDepository ); NewMenuEntry->HelpStringToken = GetStringTokenFromDepository ( CallbackData, DriverOptionHelpStrDepository ); LoadOptionPtr += NewLoadContext->FilePathListLength; if (LoadOptionPtr < LoadOptionEnd) { OptionalDataSize = DriverOptionSize - sizeof (UINT32) - sizeof (UINT16) - StringSize - NewLoadContext->FilePathListLength; NewLoadContext->OptionalData = EfiAllocateZeroPool (OptionalDataSize); ASSERT (NewLoadContext->OptionalData != NULL); EfiCopyMem ( NewLoadContext->OptionalData, LoadOptionPtr, OptionalDataSize ); NewLoadContext->OptionalDataSize = OptionalDataSize; } InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link); } SafeFreePool (DriverOrderList); DriverOptionMenu.MenuNumber = Index; return EFI_SUCCESS; }
/** 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; }
/** 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; }