VOID BOpt_FreeMenu ( BM_MENU_OPTION *FreeMenu ) /*++ Routine Description Free resources allocated in Allocate Rountine Arguments: FreeMenu Menu to be freed Returns: VOID --*/ { 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); } }
/** Delete Boot Option that represent a Deleted state in BootOptionMenu. After deleting this boot option, call Var_ChangeBootOrder to make sure BootOrder is in valid state. @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; UINT16 BootString[10]; EFI_STATUS Status; UINTN Index; UINTN Index2; Status = EFI_SUCCESS; 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; } UnicodeSPrint ( BootString, sizeof (BootString), L"Boot%04x", NewMenuEntry->OptionNumber ); EfiLibDeleteVariable (BootString, &gEfiGlobalVariableGuid); 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; Status = Var_ChangeBootOrder (); 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 BootOptionMenu. After deleting this Driver option, call Var_ChangeDriverOrder to make sure DriverOrder is in valid state. @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; UINT16 DriverString[12]; EFI_STATUS Status; UINTN Index; UINTN Index2; Status = EFI_SUCCESS; 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; } UnicodeSPrint ( DriverString, sizeof (DriverString), L"Driver%04x", NewMenuEntry->OptionNumber ); EfiLibDeleteVariable (DriverString, &gEfiGlobalVariableGuid); Index2++; RemoveEntryList (&NewMenuEntry->Link); BOpt_DestroyMenuEntry (NewMenuEntry); NewMenuEntry = NULL; } DriverOptionMenu.MenuNumber -= Index2; Status = Var_ChangeDriverOrder (); return Status; }
/** 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; }
/** 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; }
/** 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; }
EFI_STATUS GetConsoleMenu ( IN UINTN ConsoleMenuType ) { EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *AllDevicePath; EFI_DEVICE_PATH_PROTOCOL *MultiDevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePathInst; UINTN Size; UINTN AllCount; UINTN Index; UINTN Index2; BM_MENU_ENTRY *NewMenuEntry; BM_CONSOLE_CONTEXT *NewConsoleContext; BM_TERMINAL_CONTEXT *NewTerminalContext; TYPE_OF_TERMINAL Terminal; BM_MENU_ENTRY *NewTerminalMenuEntry; UINTN Com; BM_MENU_OPTION *ConsoleMenu; DevicePath = NULL; AllDevicePath = NULL; AllCount = 0; switch (ConsoleMenuType) { case BM_CONSOLE_IN_CONTEXT_SELECT: ConsoleMenu = &ConsoleInpMenu; DevicePath = EfiLibGetVariable ( L"ConIn", &gEfiGlobalVariableGuid ); AllDevicePath = EfiLibGetVariable ( L"ConInDev", &gEfiGlobalVariableGuid ); break; case BM_CONSOLE_OUT_CONTEXT_SELECT: ConsoleMenu = &ConsoleOutMenu; DevicePath = EfiLibGetVariable ( L"ConOut", &gEfiGlobalVariableGuid ); AllDevicePath = EfiLibGetVariable ( L"ConOutDev", &gEfiGlobalVariableGuid ); break; case BM_CONSOLE_ERR_CONTEXT_SELECT: ConsoleMenu = &ConsoleErrMenu; DevicePath = EfiLibGetVariable ( L"ErrOut", &gEfiGlobalVariableGuid ); AllDevicePath = EfiLibGetVariable ( L"ErrOutDev", &gEfiGlobalVariableGuid ); break; default: return EFI_UNSUPPORTED; } if (NULL == AllDevicePath) { return EFI_NOT_FOUND; } InitializeListHead (&ConsoleMenu->Head); AllCount = EfiDevicePathInstanceCount (AllDevicePath); ConsoleMenu->MenuNumber = 0; // // Following is menu building up for Console Out Devices // MultiDevicePath = AllDevicePath; Index2 = 0; for (Index = 0; Index < AllCount; Index++) { DevicePathInst = EfiDevicePathInstance (&MultiDevicePath, &Size); NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext; NewMenuEntry->OptionNumber = Index2; NewConsoleContext->DevicePath = DevicePathInstanceDup (DevicePathInst); NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath); if (NULL == NewMenuEntry->DisplayString) { NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath); } NewConsoleContext->IsTerminal = IsTerminalDevicePath ( NewConsoleContext->DevicePath, &Terminal, &Com ); NewConsoleContext->IsActive = BdsLibMatchDevicePaths ( DevicePath, NewConsoleContext->DevicePath ); NewTerminalMenuEntry = NULL; NewTerminalContext = NULL; if (NewConsoleContext->IsTerminal) { BOpt_DestroyMenuEntry (NewMenuEntry); } else { Index2++; ConsoleMenu->MenuNumber++; InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link); } } return EFI_SUCCESS; }
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_FindFileSystem ( IN BMM_CALLBACK_DATA *CallbackData ) /*++ Routine Description Find file systems for current Extensible Firmware Including Handles that support Simple File System protocol, Load File protocol. Building up the FileSystem Menu for user selection All file system will be stored in FsOptionMenu for future use. Arguments: CallbackData - BMM context data Returns: EFI_SUCCESS - Success find the file system EFI_OUT_OF_RESOURCES - Can not create menu entry --*/ { UINTN NoBlkIoHandles; UINTN NoSimpleFsHandles; UINTN NoLoadFileHandles; EFI_HANDLE *BlkIoHandle; EFI_HANDLE *SimpleFsHandle; EFI_HANDLE *LoadFileHandle; UINT16 *VolumeLabel; EFI_BLOCK_IO_PROTOCOL *BlkIo; UINTN Index; EFI_STATUS Status; BM_MENU_ENTRY *MenuEntry; BM_FILE_CONTEXT *FileContext; UINT16 *TempStr; UINTN OptionNumber; VOID *Buffer; EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; UINT16 DeviceType; BBS_BBS_DEVICE_PATH BbsDevicePathNode; EFI_DEVICE_PATH_PROTOCOL *DevicePath; BOOLEAN RemovableMedia; NoSimpleFsHandles = 0; NoLoadFileHandles = 0; OptionNumber = 0; InitializeListHead (&FsOptionMenu.Head); // // Locate Handles that support BlockIo protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &NoBlkIoHandles, &BlkIoHandle ); if (!EFI_ERROR (Status)) { for (Index = 0; Index < NoBlkIoHandles; Index++) { Status = gBS->HandleProtocol ( BlkIoHandle[Index], &gEfiBlockIoProtocolGuid, &BlkIo ); if (EFI_ERROR (Status)) { continue; } // // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media // if (BlkIo->Media->RemovableMedia) { Buffer = EfiAllocateZeroPool (BlkIo->Media->BlockSize); if (NULL == Buffer) { SafeFreePool (BlkIoHandle); return EFI_OUT_OF_RESOURCES; } BlkIo->ReadBlocks ( BlkIo, BlkIo->Media->MediaId, 0, BlkIo->Media->BlockSize, Buffer ); SafeFreePool (Buffer); } } SafeFreePool (BlkIoHandle); } // // Locate Handles that support Simple File System protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &NoSimpleFsHandles, &SimpleFsHandle ); if (!EFI_ERROR (Status)) { // // Find all the instances of the File System prototocol // for (Index = 0; Index < NoSimpleFsHandles; Index++) { Status = gBS->HandleProtocol ( SimpleFsHandle[Index], &gEfiBlockIoProtocolGuid, &BlkIo ); if (EFI_ERROR (Status)) { // // If no block IO exists assume it's NOT a removable media // RemovableMedia = FALSE; } else { // // If block IO exists check to see if it's remobable media // RemovableMedia = BlkIo->Media->RemovableMedia; } // // Allocate pool for this load option // MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT); if (NULL == MenuEntry) { SafeFreePool (SimpleFsHandle); return EFI_OUT_OF_RESOURCES; } FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext; FileContext->Handle = SimpleFsHandle[Index]; MenuEntry->OptionNumber = Index; FileContext->FHandle = EfiLibOpenRoot (FileContext->Handle); if (!FileContext->FHandle) { BOpt_DestroyMenuEntry (MenuEntry); continue; } MenuEntry->HelpString = DevicePathToStr (EfiDevicePathFromHandle (FileContext->Handle)); FileContext->Info = EfiLibFileSystemVolumeLabelInfo (FileContext->FHandle); FileContext->FileName = EfiStrDuplicate (L"\\"); FileContext->DevicePath = EfiFileDevicePath ( FileContext->Handle, FileContext->FileName ); FileContext->IsDir = TRUE; FileContext->IsRoot = TRUE; FileContext->IsRemovableMedia = FALSE; FileContext->IsLoadFile = FALSE; // // Get current file system's Volume Label // if (FileContext->Info == NULL) { VolumeLabel = L"NO FILE SYSTEM INFO"; } else { if (FileContext->Info->VolumeLabel == NULL) { VolumeLabel = L"NULL VOLUME LABEL"; } else { VolumeLabel = FileContext->Info->VolumeLabel; if (*VolumeLabel == 0x0000) { VolumeLabel = L"NO VOLUME LABEL"; } } } TempStr = MenuEntry->HelpString; MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR); ASSERT (MenuEntry->DisplayString != NULL); SPrint ( MenuEntry->DisplayString, MAX_CHAR, L"%s, [%s]", VolumeLabel, TempStr ); OptionNumber++; InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link); } } if (NoSimpleFsHandles != 0) { SafeFreePool (SimpleFsHandle); } // // Searching for handles that support Load File protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiLoadFileProtocolGuid, NULL, &NoLoadFileHandles, &LoadFileHandle ); if (!EFI_ERROR (Status)) { for (Index = 0; Index < NoLoadFileHandles; Index++) { MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT); if (NULL == MenuEntry) { SafeFreePool (LoadFileHandle); return EFI_OUT_OF_RESOURCES; } FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext; FileContext->IsRemovableMedia = FALSE; FileContext->IsLoadFile = TRUE; FileContext->Handle = LoadFileHandle[Index]; FileContext->IsRoot = TRUE; FileContext->DevicePath = EfiDevicePathFromHandle (FileContext->Handle); MenuEntry->HelpString = DevicePathToStr (FileContext->DevicePath); TempStr = MenuEntry->HelpString; MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR); ASSERT (MenuEntry->DisplayString != NULL); SPrint ( MenuEntry->DisplayString, MAX_CHAR, L"Load File [%s]", TempStr ); MenuEntry->OptionNumber = OptionNumber; OptionNumber++; InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link); } } if (NoLoadFileHandles != 0) { SafeFreePool (LoadFileHandle); } // // Add Legacy Boot Option Support Here // Status = gBS->LocateProtocol ( &gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios ); if (!EFI_ERROR (Status)) { for (Index = BBS_TYPE_FLOPPY; Index <= BBS_TYPE_EMBEDDED_NETWORK; Index++) { MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT); if (NULL == MenuEntry) { return EFI_OUT_OF_RESOURCES; } FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext; FileContext->IsRemovableMedia = FALSE; FileContext->IsLoadFile = TRUE; FileContext->IsBootLegacy = TRUE; DeviceType = (UINT16) Index; BbsDevicePathNode.Header.Type = BBS_DEVICE_PATH; BbsDevicePathNode.Header.SubType = BBS_BBS_DP; SetDevicePathNodeLength ( &BbsDevicePathNode.Header, sizeof (BBS_BBS_DEVICE_PATH) ); BbsDevicePathNode.DeviceType = DeviceType; BbsDevicePathNode.StatusFlag = 0; BbsDevicePathNode.String[0] = 0; DevicePath = EfiAppendDevicePathNode ( EndDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevicePathNode ); FileContext->DevicePath = DevicePath; MenuEntry->HelpString = DevicePathToStr (FileContext->DevicePath); TempStr = MenuEntry->HelpString; MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR); ASSERT (MenuEntry->DisplayString != NULL); SPrint ( MenuEntry->DisplayString, MAX_CHAR, L"Boot Legacy [%s]", TempStr ); MenuEntry->OptionNumber = OptionNumber; OptionNumber++; InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link); } } // // Remember how many file system options are here // FsOptionMenu.MenuNumber = OptionNumber; return EFI_SUCCESS; }