diff options
Diffstat (limited to 'EDK/MiniSetup/TseLite/AddBootOption.c')
-rw-r--r-- | EDK/MiniSetup/TseLite/AddBootOption.c | 2548 |
1 files changed, 2548 insertions, 0 deletions
diff --git a/EDK/MiniSetup/TseLite/AddBootOption.c b/EDK/MiniSetup/TseLite/AddBootOption.c new file mode 100644 index 0000000..331bf33 --- /dev/null +++ b/EDK/MiniSetup/TseLite/AddBootOption.c @@ -0,0 +1,2548 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (C)Copyright 2013, American Megatrends, Inc. **// +//** **// +//** All Rights Reserved. **// +//** **// +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **// +//** **// +//** Phone (770)-246-8600 **// +//** **// +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +// $Archive: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/TseLite/AddBootOption.c $ +// +// $Author: Arunsb $ +// +// $Revision: 29 $ +// +// $Date: 5/21/14 6:28p $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/TseLite/AddBootOption.c $ +// +// 29 5/21/14 6:28p Arunsb +// [TAG] EIP170152 +// [Category] Bug Fix +// [Severity:] Normal +// [Symptom:] Add boot option failed to add the boot option +// [Root Cause] If boot order is not there then TSE not allowing to add +// boot options +// [Solution] If boot order not presents also allowing to add boot option +// [Files] AddBootOption.c +// +// 28 5/02/14 12:56p Premkumara +// [TAG] EIP131549 +// [Category] Bug Fix +// [Severity:] Important +// [Symptom:] After adding boot/driver options and Loading defaults causes +// crashing issue. +// [Root Cause] While discarding boot/driver options the boot order get +// corrupted by copying extra data because of wrong size. +// [Solution] Handled proper size to copy boot/driver options while +// loading defaults +// [Files] AddBootOption.c, Special.c +// +// 27 2/11/14 8:46p Arunsb +// +// 26 1/30/14 10:58a Arunsb +// [TAG] EIP132762 +// [Category] Bug Fix +// [Severity:] Normal +// [Symptom:] Adding UEFI bootable RHEL OS(Bootx64.efi) from UEFI REHL6.4 +// DVD disk causes setup hang +// [Root Cause] The DevicePath is not created properly while adding boot +// options +// [Solution] Added '\' before file path name e.g \EFI\Boot\Bootx64.efi +// instead of EFI\Boot\Bootx64.efi +// [Files] AddBootOption.c +// +// 25 12/04/13 2:22p Premkumara +// [TAG] EIP131549 +// [Category] Bug Fix +// [Severity:] Important +// [Symptom:] After adding boot/driver options and Loading defaults causes +// crashing issue. +// [Root Cause] While discarding boot/driver options the boot order get +// corrupted by copying extra data because of wrong size. +// [Solution] Handled proper size to copy boot/driver options while +// loading defaults +// [Files] AddBootOption.c, Special.c +// +// 24 5/22/13 10:56a Premkumara +// [TAG] EIP123432 +// [Category] Bug Fix +// [Issue Faced] Take print screen for save & Exit msg box. OK +// of msg box is consumed by Save & Exit msg box. +// - Cursor is missing after taking print screen of popupedit box in +// string control +// - Printscreen support is not given for Filebrowser feature +// [RootCause] - When msg box for Save&Exit is popped and printscreen +// event is called and displaying msg box over Save&Exit. Then msgbox +// handleaction for printscreen event will change the result value in +// _CallbackMsgbox() function so it will break the while loop in +// _CallbackGetValue() function so destroy the next msg box in +// CallbackShowMessageBox() function. +// - DrawCursor variable is not set to TRUE after printscreen event +// [Solution] - Returning EFI_UNSUPPORTED for printscreen event handling +// function for messgebox and change the result value to 0xff +// - Support given for file browser feature +// [Files] Callback.c, MessageBox.c, Minisetupext.c, PopupString.c, +// AddBootOption.c +// AmiTSEStr.uni, FakeToken.c +// +// 23 5/22/13 10:51a Arunsb +// EfiLibAllocateCopyPool leads to memory crash so changed it to +// EfiLibAllocateZeroPool +// +// 22 4/16/13 12:59p Arunsb +// [TAG] EIP113590 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Can't load default boot priorities if enable token +// "SETUP_SUPPORT_ADD_BOOT_OPTION" +// [RootCause] Size calculated wrongly +// [Solution] Defaults will be formed only if size is 0, otherwise +// current buffer will be overwritten. +// [Files] AddBootOption.c +// +// 21 3/29/13 12:23p Premkumara +// [TAG] EIP97611 +// [Category] New Feature +// [Description] PrintScreen Support in TSE +// [Files] AMITSE.sdl, CommonHelper.c, HotKeyBin.h, AddBootOption.c, +// Page.c, TseUefiHii.h, Uefi21Wapper.c +// +// 20 12/01/12 6:46a Premkumara +// [TAG] EIP105725 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Setup hangs on BBS Menu having string more than 200 +// characters +// [RootCause] File path string is not handled properly +// [Solution] Handled FilePath strings based on length of string and +// allocate memory based on length dynamically +// [Files] AddBootOption.c, AMIVfr.h +// +// 19 10/18/12 6:02a Arunsb +// Updated for 2.16.1235 QA submission +// +// 15 10/10/12 12:38p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 18 5/29/12 4:37a Arunsb +// [TAG] EIP91109 +// [Category] Improvement +// [Description] Sync the Aptio IV source for AptioV +// +// 17 1/24/12 4:37a Arunsb +// [TAG] EIP81581 +// [Category] Improvement +// [Description] Default driver order support +// [Files] globals.c, addbootoption.c, callback.c, minisetupext.h and +// variable.c +// +// 16 1/19/12 10:49a Arunsb +// [TAG] EIP79956 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Two boot option entries displayed with the single name +// value +// [RootCause] If defaults are loaded then boot order is trying to load +// the improper boot order due to add boot option feature +// [Solution] Boot order formed properly for add boot option case. +// If no tsedefaultbootorder module present then gOptimalDefaults +// [VARIABLE_ID_BOOT_ORDER] are saved properly in SaveAddDelBootOptions at +// first time. +// At first time optimal buffer is empty so it was filled with some junk +// value so it is changed to fill the current variable list at first time +// of saving with add boot option feature. +// [Files] Addbootoption.c and callback.c +// +// 15 1/09/12 1:50a Arunsb +// [TAG] EIP79952 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Add driver option displays select boot option as title +// [RootCause] Title problem +// [Solution] Title changes +// [Files] Faketokens.c, amitsestr.uni, addbootoption.c, +// uefi2.0\hiicallback.c and uefi21wapper.c +// +// 14 11/30/11 1:34p Premkumara +// [TAG] EIP75352 +// [Category] Improvement +// [Description] Suppress the warnings from static code analyzer +// [Files] Boot.c, bbs.c, TseAdvanced.c, Special.c, Variable.c, +// TseLiteHelper.c, PopupSel.c, AddBootOption.c, Hii.c, FormBrowser2.c +// +// 13 11/13/11 12:54p Arunsb +// [TAG] EIP70421 +// [Category] New Feature +// [Description] Support for driver order in TSE +// [Files] AMITSE.SDL, CommonHelper.c, setup.ini, uefisetup.ini, +// boot.c, +// minisetup.h, bbs.c, special.c, special.h, tseadvanced.c, +// addbootoption.c, +// callback.c, minisetupext.c, minisetupext.h, popupsel.c, popupsel.h, +// TseLitehelper.c, variable.c, Uefi21Wapper.c, AMIVfr.h, boot.h, +// TseElink.h, variable.h, +// setup.h, Boot.vfr and Setup.uni +// +// 12 1/10/11 3:55p Mallikarjunanv +// Updated to work with respect to EDK Libraries +// +// 11 1/07/11 12:09a Mallikarjunanv +// [TAG] EIP51378 +// [Description] Global variable gHandleBuffer changed to +// gSmplFileSysHndlBuf because of the conflict with HddSecurity module, +// which already using gHandleBuffer. +// +// 10 1/06/11 11:14p Mallikarjunanv +// [TAG] EIP41615 +// [Description] Updated the files with respect to File Browser support. +// +// 9 12/28/10 6:20p Mallikarjunanv +// [TAG] EIP41615 +// [Description] Added the file browser support for the Add boot option +// reated controls +// [Files] AmiVfr.h, AmiTse.sdl, AmiTseStr.uni, CommonHelper.c, +// Faketokens.c, TseElinks.h, EdkHelper.h, minisetup.h, TseAdvanced.c, +// AddBootOption.c +// +// 8 3/26/10 5:25p Madhans +// EIP 35562: Support To create Boot option in Capital letters. +// +// 7 2/26/10 8:54p Madhans +// For TSE 2.01.1024. refer changelog.log for file checkin history . +// +// 11 2/25/10 8:04a Mallikarjunanv +// Updated the memory corruptions in case of add delete boot options +// +// 10 2/19/10 8:19a Mallikarjunanv +// updated year in copyright message +// +// 9 1/28/10 1:10p Mallikarjunanv +// //EIP:34119 - Fix to solve issues, if the boot option name is set with +// max number of characters allowed. +// +// 8 1/09/10 7:12a Mallikarjunanv +// Updated TSE2.01 Release sources with coding standards +// +// 7 1/04/10 10:40a Mallikarjunanv +// EIPs 27161/29095 - Added support for reserved boot option names and +// added support not to create empty boot option names +// +// 6 12/18/09 2:27p Madhans +// EIP: 32350/32445 To fix the Add/Delete Boot option issues with TSE 2.0. +// +// 5 8/18/09 5:34p Madhans +// EIP 25367: To resolve the build issue and to avoid redefinition. +// +// 4 8/13/09 7:39a Mallikarjunanv +// eip:24971 - supporting tse features without tse sources +// +// 3 6/23/09 6:52p Blaines +// Coding standard update, +// Remove spaces from file header to allow proper chm function list +// creation. +// +// 2 6/12/09 7:44p Presannar +// Initial implementation of coding standards for AMITSE2.0 +// +// 1 6/04/09 8:05p Madhans +// +// 2 4/29/09 9:02p Madhans +// Bug Fixes after unit Testing.. +// +// 1 4/28/09 11:04p Madhans +// Tse 2.0 Code complete Checkin. +// +// 1 4/28/09 9:39p Madhans +// Tse 2.0 Code complete Checkin. +// +// 1 12/18/08 7:59p Madhans +// Intial version of TSE Lite sources +// +// +//*****************************************************************// +//*****************************************************************// + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: AddBootOption.c +// +// Description: This file contains code to handle the Add boot option operation. +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include "minisetup.h" + + +/////////////////////////////////////////////////////// +/// MACRO DEFINITIONS +/////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////// +/// VARIABLE DECLARATIONS +/////////////////////////////////////////////////////// + +typedef struct// EIP-41615: Start +{ + UINT64 Type; + UINTN Size; + CHAR16 *Name; + STRING_REF Token; +} FILE_TYPE; +EFI_FILE_PROTOCOL *gFs = NULL; +EFI_GUID gSimpleFileSystemGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; +AMI_POST_MANAGER_PROTOCOL *mPostMgr = NULL; +static EFI_HANDLE *gSmplFileSysHndlBuf = NULL; //EIP:51378 Global variable gHandleBuffer changed to gSmplFileSysHndlBuf because of the conflict with HddSecurity module, which already using gHandleBuffer. +BOOLEAN gValidOption = FALSE; +UINT16 gSelIdx = 0;/// EIP-41615: End +UINTN gDelOptionCount; +BOOT_DATA *gDelBootData; +UINTN gFsCount; +FS_DATA *gFsList; +UINTN gDriverDelOptionCount; //EIP70421 & 70422 Support for driver order +BOOT_DATA *gDelDriverData; //EIP70421 & 70422 Support for driver order +/////////////////////////////////////////////////////// +/// EXTERN VARIABLES +/////////////////////////////////////////////////////// +extern UINTN gDelBootOptionReserved; +extern UINTN gAddBootOptionEmpty; +extern UINTN gAddDriverOptionEmpty; +/////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS +/////////////////////////////////////////////////////// +EFI_DEVICE_PATH_PROTOCOL *_BootBuildFileDevicePath( UINT32 *index, CHAR16 *fileName ); +VOID BbsStrnCpy ( CHAR16 *Dst, CHAR16 *Src, UINTN Length ); +VOID _GetFsLists (VOID); +UINT16 *_DevicePathToStr(EFI_DEVICE_PATH_PROTOCOL *Path); +VOID FixHiddenOptions (BOOLEAN, UINT16 **, UINTN); +UINT16 _BootSetBootNowCount(VOID); +EFI_STATUS ShowPostMsgBox(IN CHAR16 *MsgBoxTitle,IN CHAR16 *Message,IN UINT8 MsgBoxType, UINT8 *pSelection);//EIP:41615 +EFI_STATUS FileBrowserLaunchFilePath(UINT32 Variable); + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: TseUpdateAddDeleteBootVar +// +// Description: Function to update add and delete boot variables +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void TseUpdateAddDeleteBootVar(void) +{ + UINT16 u16DelOption; + EFI_GUID DelBootOptionGuid = DEL_BOOT_OPTION_GUID; + EFI_GUID AddBootOptionGuid = ADD_BOOT_OPTION_GUID; + NEW_BOOT_OPTION AddBootOption; + + //Set del boot option var + u16DelOption = DISABLED_BOOT_OPTION; + VarSetNvramName( L"DelBootOption", &DelBootOptionGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &u16DelOption, sizeof(UINT16) ); + + //Set AddBootOption variable + _GetFsLists (); + MemSet(&AddBootOption, sizeof(NEW_BOOT_OPTION),0); + AddBootOption.FsCount = (UINT16)gFsCount; + VarSetNvramName( L"AddBootOption", &AddBootOptionGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &AddBootOption, sizeof(NEW_BOOT_OPTION) ); + +} + +//EIP70421 & 70422 Support for driver order +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: TseUpdateAddDeleteDriverVar +// +// Description: Function to update add and delete driver variables +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +void TseUpdateAddDeleteDriverVar (void) +{ + UINT16 u16DelOption; + EFI_GUID DelDriverOptionGuid = DEL_DRIVER_OPTION_GUID; + EFI_GUID AddDriverOptionGuid = ADD_DRIVER_OPTION_GUID; + NEW_DRIVER_OPTION AddDriverOption; + + //Set del driver option var + u16DelOption = DISABLED_DRIVER_OPTION; + VarSetNvramName (L"DelDriverOption", &DelDriverOptionGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &u16DelOption, sizeof (UINT16)); + + //Set AddDriverOption variable + _GetFsLists(); + MemSet (&AddDriverOption, sizeof (NEW_DRIVER_OPTION), 0); + AddDriverOption.FsCount = (UINT16)gFsCount; + VarSetNvramName (L"AddDriverOption", &AddDriverOptionGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &AddDriverOption, sizeof (NEW_DRIVER_OPTION)); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: _GetFsLists +// +// Description: function to get the file system details +// +// Input: None +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID _GetFsLists (VOID) +{ + UINTN Count,i; + EFI_HANDLE *HandleBuffer; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + CHAR16 *Str; + EFI_STATUS Status; + + //Find all handles supporting Simple File Sys Protocol + if (0 == gFsCount) //EIP70421 Support for driver order; No need of calling continuously boot then driver, one call is enough to set gFsCount + { + Status = gBS->LocateHandleBuffer( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &Count, + &HandleBuffer + ); + if(EFI_ERROR(Status)) + return; + + for(i=0;i<Count;i++) + { + DevicePath = NULL; + Status = gBS->OpenProtocol ( + HandleBuffer[i], + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath, + NULL, + HandleBuffer[i], + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if(EFI_ERROR(Status)) + continue; + if(!DevicePath) + continue; + Str = NULL; + Str = _DevicePathToStr(DevicePath); + + gFsList = MemReallocateZeroPool(gFsList, gFsCount * sizeof(FS_DATA), (gFsCount + 1) * sizeof(FS_DATA)); + gFsList[gFsCount].FsId = Str ? Str : StrDup(L"Unknown"); + gFsList[gFsCount].FsPath = DevicePath; + + gFsCount++; + } + } +} + +static UINT16 DefaultDevicePath[]=L"DevicePath(Type %x, SubType %x)"; + +static UINT16 *HWDP[] = { + L"PCI(%X|%X)\\", //HW_PCI_DP + L"Pccard(Socket %x)\\", //HW_PCCARD_DP + L"VenHw(%g)\\" //HW_VENDOR_DP +}; + +/*Uncomment if ACPI details are necessary +static UINT16 *ACPIDP[] = { + L"Acpi(%x, %x)\\" //ACPI_DP +};*/ + +static UINT16 *MSGDP[] = { + L"ATA(%s,%s)\\", //MSG_ATAPI_DP + L"SCSI(%x,%x)\\", //MSG_SCSI_DP + L"VenMsg(%g)\\" //MSG_VENDOR_DP +}; + +static UINT16 *MEDIADP[] = { + L"CDROM(Entry%x)\\", //MEDIA_CDROM_DP + L"VenMedia(%g)\\", //MEDIA_VENDOR_DP + L"%g\\" //MEDIA_FILEPATH_DP +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: _HWToStr +// +// Description: Convert Device Path of type to string. +// +// Input: +// IN EFI_DEVICE_PATH_PROTOCOL *Path - Device Path +// OUT UINT16 *Str - String form of device path. +// +// Output: +// int - number of characters not including \0 or -1 if error. +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINTN _HWToStr( + EFI_DEVICE_PATH_PROTOCOL *Path, + UINT16 *Str + ) +{ + switch(Path->SubType) + { + case HW_PCI_DP: + return SPrint(Str,0,HWDP[0],((PCI_DEVICE_PATH*)Path)->Device,((PCI_DEVICE_PATH*)Path)->Function); + case HW_PCCARD_DP: + return SPrint(Str,0,HWDP[1],((AMITSE_PCCARD_DEVICE_PATH*)Path)->FunctionNumber); + case HW_VENDOR_DP: + return SPrint(Str,0,HWDP[2],&((VENDOR_DEVICE_PATH*)Path)->Guid); + } + + return SPrint(Str,0,DefaultDevicePath,Path->Type,Path->SubType); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ACPIToStr +// +// Description: Convert Device Path of type to string. +// +// Input: +// IN EFI_DEVICE_PATH_PROTOCOL *Path - Device Path +// OUT UINT16 *Str - String form of device path. +// +// Output: +// int - number of characters not including \0 or -1 if error. +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +/* +Uncomment below code if ACPI details are necessary. +CAUTION: If ACPI details are included then the string becomes too big +to display +*/ +/* +UINTN ACPIToStr( + EFI_DEVICE_PATH_PROTOCOL *Path, + UINT16 *Str + ) +{ + switch(Path->SubType) + { + case ACPI_DP: + return SPrint(Str,0,ACPIDP[0], ((ACPI_HID_DEVICE_PATH*)Path)->HID, ((ACPI_HID_DEVICE_PATH*)Path)->UID); + } + return SPrint(Str,0,DefaultDevicePath,Path->Type,Path->SubType); +} +*/ + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: _MSGToStr +// +// Description: Convert Device Path of type to string. +// +// Input: +// IN EFI_DEVICE_PATH_PROTOCOL *Path - Device Path +// OUT UINT16 *Str - String form of device path. +// +// Output: +// int - number of characters not including \0 or -1 if error. +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINTN _MSGToStr( + EFI_DEVICE_PATH_PROTOCOL *Path, + UINT16 *Str + ) +{ + switch(Path->SubType) + { + case MSG_ATAPI_DP: + return SPrint(Str,0,MSGDP[0], + ((ATAPI_DEVICE_PATH*)Path)->PrimarySecondary ? L"Sec" : L"Pri", + ((ATAPI_DEVICE_PATH*)Path)->SlaveMaster ? L"Sl" :L"Ma"); + case MSG_SCSI_DP: + return SPrint(Str,0,MSGDP[1], ((SCSI_DEVICE_PATH*)Path)->Pun, ((SCSI_DEVICE_PATH*)Path)->Lun); + case MSG_VENDOR_DP: + return SPrint(Str,0,MSGDP[2], ((VENDOR_DEVICE_PATH*)Path)->Guid); + case MSG_USB_DP: + return SPrint(Str,0,L"USB(%x,%x)\\", + ((USB_DEVICE_PATH*)Path)->ParentPortNumber,((USB_DEVICE_PATH*)Path)->InterfaceNumber); + + } + return SPrint(Str,0,DefaultDevicePath,Path->Type,Path->SubType); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: _MEDIAToStr +// +// Description: Convert Device Path of type to string. +// +// Input: +// IN EFI_DEVICE_PATH_PROTOCOL *Path - Device Path +// OUT UINT16 *Str - String form of device path. +// +// Output: +// int - number of characters not including \0 or -1 if error. +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINTN _MEDIAToStr( + EFI_DEVICE_PATH_PROTOCOL *Path, + UINT16 *Str + ) +{ + switch(Path->SubType) + { + case MEDIA_HARDDRIVE_DP: + { + HARDDRIVE_DEVICE_PATH *Hd = (HARDDRIVE_DEVICE_PATH *)Path; + switch(Hd->SignatureType) + { + case SIGNATURE_TYPE_MBR: + return SPrint(Str,0,L"HD(Part%d,Sig%08X)", Hd->PartitionNumber, *((UINT32 *)(&(Hd->Signature[0])))); + case SIGNATURE_TYPE_GUID: + return SPrint(Str,0, L"HD(Part%d,Sig%g)", Hd->PartitionNumber, (EFI_GUID *) &(Hd->Signature[0])); + default: + return SPrint(Str,0,L"HD(Part%d,MBRType=%02x,SigType=%02x)", + Hd->PartitionNumber, + Hd->MBRType, + Hd->SignatureType + ); + } + } + case MEDIA_CDROM_DP: + return SPrint(Str,0,MEDIADP[0], ((CDROM_DEVICE_PATH*)Path)->BootEntry); + case MEDIA_VENDOR_DP: + return SPrint(Str,0,MEDIADP[1], ((VENDOR_DEVICE_PATH*)Path)->Guid); + case MEDIA_FILEPATH_DP: + return SPrint(Str,0,MEDIADP[2], &((AMITSE_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)Path)->FvFileName); + } + return SPrint(Str,0,DefaultDevicePath,Path->Type,Path->SubType); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: _UnknownToStr +// +// Description: Convert Device Path of type to string. +// +// Input: +// IN EFI_DEVICE_PATH_PROTOCOL *Path - Device Path +// OUT UINT16 *Str - String form of device path. +// +// Output: +// int - number of characters not including \0 or -1 if error. +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINTN _UnknownToStr( + EFI_DEVICE_PATH_PROTOCOL *Path, + UINT16 *Str + ) +{ + return SPrint(Str,0,DefaultDevicePath,Path->Type,Path->SubType); +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: _DevicePathToStr +// +// Description: Convert Device Path of type to string. Str is allocated by +// this routine. It must be freed by the caller. +// +// Input: +// IN EFI_DEVICE_PATH_PROTOCOL *Path - Device Path +// +// +// Output: +// OUT UINT16 *Str - String form of device path. +// +// Notes: +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT16 *_DevicePathToStr(EFI_DEVICE_PATH_PROTOCOL *Path) +{ + CHAR16 Buffer[512]; + CHAR16 *p = Buffer, *Str = NULL; + UINTN Count = 0; + UINTN Length; + + MemSet(Buffer,sizeof(Buffer),0); + for(;;) + { + switch(Path->Type) + { + case HARDWARE_DEVICE_PATH: + Count = _HWToStr(Path, p); + break; + case ACPI_DEVICE_PATH: +/* +Uncomment below code if ACPI details are necessary. +CAUTION: If ACPI details are included then the string becomes too big +to display +*/ +/* + Count = SPrint(p,0,L"Acpi\\"); + ACPIToStr(Path, p); +*/ + break; + case MESSAGING_DEVICE_PATH: + Count = _MSGToStr(Path, p); + break; + case MEDIA_DEVICE_PATH: + Count = _MEDIAToStr(Path, p); + break; + case END_DEVICE_PATH_TYPE: + Count = 0; + break; + case END_ENTIRE_DEVICE_PATH_SUBTYPE: + *p = L'|'; + *(p+1) = L'\0'; + Count = 1; + break; + default: + Count = _UnknownToStr(Path, p); + } + + p += EfiStrLen(p); + + if (Count == -1) return NULL; + if (IsDevicePathEnd(Path)) break; + + Path = NextDevicePathNode(Path); + } + + Length = (UINTN)p - (UINTN)Buffer; + + Str = (UINT16 *)EfiLibAllocateZeroPool(Length+sizeof(UINT16)); + + MemCopy(Str, Buffer, Length); + + return Str; +} + +//EIP70421 & 70422 Support for driver order +//<AMI_PHDR_START> +//-------------------------------------------------------------------------------------------- +// Procedure: _DisableRestorePrevOptions +// +// Description: Function to make the boot/driver option as disable in bootorder/driverorder +// if it is inactive and non hidden +// +// +// Input: BOOLEAN , UINT16 **, UINTN +// +// Output: VOID +// +//------------------------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID _DisableRestorePrevOptions (BOOLEAN Option, UINT16 **Order, UINTN OptionCount) +{ + UINTN iIndex = 0; + BOOT_DATA *pBootData; + + if (0 == OptionCount) + { + return; + } + for (iIndex = 0; iIndex < OptionCount; iIndex ++) + { + if (BOOT_ORDER_OPTION == Option) + { + pBootData = BootGetBootData ((*Order) [iIndex]); + } + else + { + pBootData = DriverGetDriverData ((*Order) [iIndex]); + } + if (pBootData) + { + if ( (!(pBootData->Active & LOAD_OPTION_ACTIVE)) && (!(pBootData->Active & LOAD_OPTION_HIDDEN)) ) + { + (*Order) [iIndex] = DISABLED_BOOT_OPTION; + } + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: BootAddBootOption +// +// Description: Function to add boot option +// +// Input: VOID +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID BootAddBootOption( VOID ) +{ + UINTN i,size; + UINT16 u16Option; + NEW_BOOT_OPTION *newBoot = NULL, *tmpPtr; + CHAR16 *fileName; + UINT32 index; + EFI_DEVICE_PATH_PROTOCOL *devicePath; + UINT16 *NewBootOrder = NULL, *CurrBootOrder = NULL; + UINT16 BootCountVal; + CHAR16 *BootNameBuf = NULL; //EIP:34119 + EFI_STATUS Status; + //Get input + size = 0; + Status = gBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL,(void**) &mPostMgr); + if(Status != EFI_SUCCESS) + return; + newBoot = VarGetVariable( VARIABLE_ID_ADD_BOOT_OPTION, &size ); + //EIP-75352 Suppress the warnings from static code analyzer + if (NULL == newBoot){ + return; + } + +//EIP:34119 - Start + //Fix EIP:29095 - not to create boot option with out a name + if (( EfiStrLen( newBoot->Path ) == 0 ) || ( EfiStrLen(newBoot->Label) == 0 )) + { + // CallbackShowMessageBox( (UINTN)gAddBootOptionEmpty, MSGBOX_TYPE_OK ); + + mPostMgr->DisplayMsgBox( L"WARNING", L"Please set Boot Option Name and File Path", MSGBOX_TYPE_OK,NULL); + return; + } + BootNameBuf = EfiLibAllocateZeroPool( sizeof(newBoot->Label)+2 ); + BbsStrnCpy( BootNameBuf, newBoot->Label, (sizeof(newBoot->Label))/2 ); +//EIP:34119 - End + + // cleanup old data + tmpPtr = EfiLibAllocateZeroPool( size ); + tmpPtr->FsCount = (UINT16)gFsCount; + VarSetValue( VARIABLE_ID_ADD_BOOT_OPTION, 0, size, tmpPtr ); + MemFreePointer( (VOID **)&tmpPtr ); + + fileName = newBoot->Path; + + index = newBoot->SelFs; + + devicePath = _BootBuildFileDevicePath( &index, fileName ); + if ( devicePath != NULL ) + { + EFI_DEVICE_PATH_PROTOCOL *TmpDevPath, *HddMediaPath; + + //Find a free option number + for ( u16Option = 0; u16Option < MAX_BOOT_OPTIONS; u16Option++ ) + { + for(i=0;i<gBootOptionCount;i++) + { + if(gBootData[i].Option == u16Option) + break; + } + if(i<gBootOptionCount) + continue; + for(i=0;i<gDelOptionCount;i++) + { + if(gDelBootData[i].Option == u16Option) + break; + } + if(i<gDelOptionCount) + continue; + + break;//The desired option number is in u16Option + } + + if ( u16Option == MAX_BOOT_OPTIONS ) //Not possible + return; + + gBootData = MemReallocateZeroPool(gBootData, gBootOptionCount * sizeof(BOOT_DATA), (gBootOptionCount + 1) * sizeof(BOOT_DATA) ); + + gBootData[gBootOptionCount].Option = u16Option; + gBootData[gBootOptionCount].Active |= LOAD_OPTION_ACTIVE; +//EIP:34119 - Fix to solve issues, if the boot option name is set with max number of characters allowed. + //gBootData[gBootOptionCount].Name = StrDup( newBoot->Label ); + gBootData[gBootOptionCount].Name = BootNameBuf; +//EIP:34119 - End + + //For a hard drive start the dev path from the partition + for( TmpDevPath = devicePath; + !IsDevicePathEndType(TmpDevPath); + TmpDevPath=NextDevicePathNode(TmpDevPath) + ) + { + if(TmpDevPath->Type==MEDIA_DEVICE_PATH && TmpDevPath->SubType==MEDIA_HARDDRIVE_DP) + { + HddMediaPath = EfiLibAllocateZeroPool(EfiDevicePathSize(TmpDevPath)); + MemCopy(HddMediaPath, TmpDevPath, EfiDevicePathSize(TmpDevPath)); + MemFreePointer((VOID **)&devicePath); + devicePath = HddMediaPath; + break; + } + } + gBootData[gBootOptionCount].DevicePath = devicePath; + gBootData[gBootOptionCount].bNewOption = TRUE; + + size = 0; + CurrBootOrder = VarGetVariable(VARIABLE_ID_BOOT_ORDER, &size); + //EIP-75352 Suppress the warnings from static code analyzer +/* if (NULL == CurrBootOrder){ //If file system available and no boot option presents then add boot option always fails so commenting it. + return; + }*/ + NewBootOrder = EfiLibAllocateZeroPool((gBootOptionCount+1) * sizeof(UINT16)); + + for(i=0;i<gBootOptionCount;i++) + { + if(DISABLED_BOOT_OPTION == CurrBootOrder[i]) + break; + NewBootOrder[i] = CurrBootOrder[i]; + } + if (i < gBootOptionCount) //Preserve the hidden options at last + { + MemCpy (NewBootOrder+i+1, CurrBootOrder+i, (gBootOptionCount-i)*2); + } + NewBootOrder [i] = u16Option; + //i ++; + MemFreePointer ((VOID **) &CurrBootOrder); + gBootOptionCount ++; + MemFreePointer ((VOID **)&newBoot); + + //Update boot manager vars in memory + //1. TSE Boot order + MemFreePointer((VOID **) &gVariableList[VARIABLE_ID_BOOT_ORDER].Buffer); + if (gLoadOptionHidden) //Move hidden options to last + { + FixHiddenOptions (BOOT_ORDER_OPTION, &NewBootOrder, gBootOptionCount); + } + gVariableList[VARIABLE_ID_BOOT_ORDER].Buffer = (UINT8 *)NewBootOrder; + gVariableList[VARIABLE_ID_BOOT_ORDER].Size = gBootOptionCount * sizeof(UINT16); + + //2. BootManager + BootCountVal = (UINT16)gBootOptionCount; + VarSetValue(VARIABLE_ID_BOOT_MANAGER, 0, sizeof(UINT16), (VOID *)(&BootCountVal)); + + //3. Set Boot now count + if(gShowAllBbsDev) + BootCountVal = _BootSetBootNowCount(); + + Status = VarSetValue(VARIABLE_ID_BOOT_NOW, 0, sizeof(UINT16), (VOID *)(&BootCountVal)); + if(Status == EFI_SUCCESS) + mPostMgr->DisplayMsgBox( L"SUCCESS", L"Boot Option Created Successfully", MSGBOX_TYPE_OK,NULL); + } +} + +//EIP70421 & 70422 Support for driver order +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DriverAddDriverOption +// +// Description: Function to add driver options +// +// Input: VOID +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID DriverAddDriverOption(VOID) +{ + UINTN i,size; + UINT16 u16Option; + NEW_DRIVER_OPTION *newDriver = NULL, *tmpPtr; + CHAR16 *fileName; + UINT32 index; + EFI_DEVICE_PATH_PROTOCOL *devicePath; + UINT16 *NewDriverOrder = NULL, *CurrDriverOrder = NULL; + UINT16 DriverCountVal; + CHAR16 *BootNameBuf = NULL; + EFI_STATUS Status; + //Get input + size = 0; + Status = gBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL,(void**) &mPostMgr); + if(Status != EFI_SUCCESS) + return; + newDriver = VarGetVariable( VARIABLE_ID_ADD_DRIVER_OPTION, &size ); + if (( EfiStrLen (newDriver->DriverPath) == 0 ) || (EfiStrLen (newDriver->Label) == 0)) + { + //CallbackShowMessageBox( (UINTN)gAddDriverOptionEmpty, MSGBOX_TYPE_OK ); + + mPostMgr->DisplayMsgBox( L"WARNING", L"Please set Driver Option Name and File Path", MSGBOX_TYPE_OK,NULL); + return; + } + + BootNameBuf = EfiLibAllocateZeroPool( sizeof(newDriver->Label)+2 ); + BbsStrnCpy( BootNameBuf, newDriver->Label, (sizeof(newDriver->Label))/2 ); + + // cleanup old data + tmpPtr = EfiLibAllocateZeroPool( size ); + tmpPtr->FsCount = (UINT16)gFsCount; + VarSetValue( VARIABLE_ID_ADD_DRIVER_OPTION, 0, size, tmpPtr ); + MemFreePointer( (VOID **)&tmpPtr ); + + fileName = newDriver->DriverPath; + + index = newDriver->SelFs; + + devicePath = _BootBuildFileDevicePath( &index, fileName ); + + if ( devicePath != NULL ) + { +// EFI_DEVICE_PATH_PROTOCOL *TmpDevPath, *HddMediaPath; + + //Find a free option number + for ( u16Option = 0; u16Option < MAX_BOOT_OPTIONS; u16Option++ ) + { + for(i=0;i<gDriverOptionCount;i++) + { + if(gDriverData[i].Option == u16Option) + break; + } + if(i<gDriverOptionCount) + continue; + for(i=0;i<gDriverDelOptionCount;i++) + { + if(gDelDriverData[i].Option == u16Option) + break; + } + if(i<gDriverDelOptionCount) + continue; + + break;//The desired option number is in u16Option + } + + if ( u16Option == MAX_BOOT_OPTIONS ) //Not possible + return; + + gDriverData = MemReallocateZeroPool(gDriverData, gDriverOptionCount * sizeof(BOOT_DATA), (gDriverOptionCount + 1) * sizeof(BOOT_DATA) ); + + gDriverData[gDriverOptionCount].Option = u16Option; + gDriverData[gDriverOptionCount].Active |= LOAD_OPTION_ACTIVE; +//EIP:34119 - Fix to solve issues, if the boot option name is set with max number of characters allowed. + //gBootData[gBootOptionCount].Name = StrDup( newDriver->Label ); + gDriverData[gDriverOptionCount].Name = BootNameBuf; +//EIP:34119 - End + + /* + //TSE will append hard drive device path at front if it is MEDIA_DEVICE_PATH but core needs fullpath so commented below + //For a hard drive start the dev path from the partition + for( TmpDevPath = devicePath; + !IsDevicePathEndType(TmpDevPath); + TmpDevPath=NextDevicePathNode(TmpDevPath) + ) + { + if(TmpDevPath->Type==MEDIA_DEVICE_PATH && TmpDevPath->SubType==MEDIA_HARDDRIVE_DP) + { + HddMediaPath = EfiLibAllocateZeroPool(EfiDevicePathSize(TmpDevPath)); + MemCopy(HddMediaPath, TmpDevPath, EfiDevicePathSize(TmpDevPath)); + MemFreePointer((VOID **)&devicePath); + devicePath = HddMediaPath; + break; + } + }*/ + + gDriverData[gDriverOptionCount].DevicePath = devicePath; + gDriverData[gDriverOptionCount].bNewOption = TRUE; + + size = 0; + CurrDriverOrder = VarGetVariable(VARIABLE_ID_DRIVER_ORDER, &size); + NewDriverOrder = EfiLibAllocateZeroPool((gDriverOptionCount+1) * sizeof(UINT16)); + + for(i=0;i<gDriverOptionCount;i++) + { + if(DISABLED_DRIVER_OPTION == CurrDriverOrder[i]) + break; + NewDriverOrder[i] = CurrDriverOrder[i]; + } + if (i < gDriverOptionCount) //Preserve the hidden options at last + { + MemCpy (NewDriverOrder+i+1, CurrDriverOrder+i, (gDriverOptionCount-i)*2); + } + + NewDriverOrder[i] = u16Option; + //i++; + + MemFreePointer((VOID **) &CurrDriverOrder); + + gDriverOptionCount ++; + + MemFreePointer( (VOID **)&newDriver ); + + //Update boot manager vars in memory + //1. TSE driver order + MemFreePointer((VOID **) &gVariableList[VARIABLE_ID_DRIVER_ORDER].Buffer); + if (gLoadOptionHidden) //Move the hidden options to last + { + FixHiddenOptions (DRIVER_ORDER_OPTION, &NewDriverOrder, gDriverOptionCount); + } + gVariableList[VARIABLE_ID_DRIVER_ORDER].Buffer = (UINT8 *)NewDriverOrder; + gVariableList[VARIABLE_ID_DRIVER_ORDER].Size = gDriverOptionCount * sizeof(UINT16); + + //2. DriverManager + DriverCountVal = (UINT16)gDriverOptionCount; + Status = VarSetValue(VARIABLE_ID_DRIVER_MANAGER, 0, sizeof(UINT16), (VOID *)(&DriverCountVal)); + if(Status == EFI_SUCCESS) + mPostMgr->DisplayMsgBox( L"SUCCESS", L"Driver Option Created Successfully", MSGBOX_TYPE_OK,NULL); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: BootDelBootOption +// +// Description: Function to handle the del boot option +// +// Input: UINT16 index +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID BootDelBootOption( UINT16 index ) +{ + UINTN i,j,k, size; + BOOT_DATA *pBootData = NULL; + UINT16 BootCountVal; + UINT16 *NewBootOrder = NULL, *CurrBootOrder = NULL; + EFI_STATUS Status=EFI_UNSUPPORTED; + VOID * UnicodeInterface; + CHAR16 *ResStr = NULL; + CHAR16 *TmpStr = NULL; + + // If it BBS device we should not delete it. + // FIX......to check for the correct Boot option. + Status = gBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL,(void**) &mPostMgr); + if(Status != EFI_SUCCESS) + return; + for(i=0; i<gBootOptionCount; i++) + { + if(index == gBootData[i].Option) + { + if(gBootData[i].DevicePath->Type == BBS_DEVICE_PATH && gBootData[i].DevicePath->SubType == BBS_BBS_DP) + return; + + ///Fix: Eip-27161 - not to allow Reserved boot options to delete + if( ( IsReservedBootOptionNamesEnable() ) && + ( gBootData[i].Name ) ) + { + ResStr = CONVERT_TO_WSTRING(RESERVED_ADD_DEL_BOOT_OPTION_NAME); + TmpStr = EfiLibAllocateZeroPool( EfiStrLen(ResStr)+1 ); + BbsStrnCpy(TmpStr, gBootData[i].Name, (EfiStrLen(ResStr)+1) ); + TmpStr[EfiStrLen(ResStr)]= L'\0'; + Status = InitUnicodeCollectionProtocol(&UnicodeInterface); + if(!EFI_ERROR(Status)) { + if( StringColl( UnicodeInterface, TmpStr, ResStr) == 0 ) + { + //CallbackShowMessageBox( (UINTN)gDelBootOptionReserved, MSGBOX_TYPE_OK ); + mPostMgr->DisplayMsgBox( L"WARNING", L"Reserved Boot Option, can not be Deleted", MSGBOX_TYPE_OK,NULL); + return; + } + } + } + } + } + + //Remove option from gBootData and add to gDelBootData + //Remove option from BootOrder + if(gBootOptionCount - 1) + { + pBootData = EfiLibAllocateZeroPool(sizeof(BOOT_DATA) * (gBootOptionCount - 1)); + NewBootOrder = EfiLibAllocateZeroPool(sizeof(UINT16) * (gBootOptionCount - 1)); + } + + size = 0; + CurrBootOrder = VarGetVariable(VARIABLE_ID_BOOT_ORDER, &size); + //EIP-75352 Suppress the warnings from static code analyzer + if (NULL == CurrBootOrder){ + return; + } + + gDelBootData = MemReallocateZeroPool(gDelBootData, sizeof(BOOT_DATA) * gDelOptionCount, sizeof(BOOT_DATA) * (gDelOptionCount + 1)); + + for(i=0,j=0,k=0; i<gBootOptionCount; i++) + { + if(index == gBootData[i].Option) + { + MemCopy(gDelBootData + gDelOptionCount, gBootData + i, sizeof(BOOT_DATA)); + } + else + { + MemCopy(pBootData + j, gBootData + i, sizeof(BOOT_DATA)); + j++; + } + + if(index != CurrBootOrder[i]) + { + if(k<(gBootOptionCount-1)) + { + NewBootOrder[k] = CurrBootOrder[i]; + k++; + } + } + } + + gDelOptionCount++; + gBootOptionCount--; + + MemFreePointer((VOID **)&gBootData); + gBootData = pBootData; + + MemFreePointer((VOID **)&CurrBootOrder); + + //Update boot manager vars in memory + //1. TSE Boot order + MemFreePointer((VOID **) &gVariableList[VARIABLE_ID_BOOT_ORDER].Buffer); + if (gLoadOptionHidden) //Move the hidden options to last + { + FixHiddenOptions (BOOT_ORDER_OPTION, &NewBootOrder, gBootOptionCount); + } + gVariableList[VARIABLE_ID_BOOT_ORDER].Buffer = (UINT8 *)NewBootOrder; + gVariableList[VARIABLE_ID_BOOT_ORDER].Size = gBootOptionCount * sizeof(UINT16); + + //2. BootManager + BootCountVal = (UINT16)gBootOptionCount; + VarSetValue(VARIABLE_ID_BOOT_MANAGER,0,sizeof(UINT16),(VOID *)(&BootCountVal)); + + //3. Set Boot now count + if(gShowAllBbsDev) + BootCountVal = _BootSetBootNowCount(); + + Status = VarSetValue(VARIABLE_ID_BOOT_NOW,0,sizeof(UINT16),(VOID *)(&BootCountVal)); + if(EFI_SUCCESS == Status) + mPostMgr->DisplayMsgBox( L"SUCCESS", L"Boot Option Deleted Successfully", MSGBOX_TYPE_OK,NULL); +} + +//EIP70421 & 70422 Support for driver order +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DriverDelDriverOption +// +// Description: Function to handle the del Driver option +// +// Input: UINT16 index +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID DriverDelDriverOption( UINT16 index ) +{ + UINTN i,j,k, size; + BOOT_DATA *pDriverData = NULL; + UINT16 DriverCountVal; + UINT16 *NewDriverOrder = NULL, *CurrDriverOrder = NULL; + EFI_STATUS Status=EFI_UNSUPPORTED; +// VOID * UnicodeInterface; + CHAR16 *ResStr = NULL; + CHAR16 *TmpStr = NULL; + + if ((NULL == gDriverData) || (0 == gDriverOptionCount)) + return; + Status = gBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL,(void**) &mPostMgr); + if(Status != EFI_SUCCESS) + return; + for(i=0; i<gDriverOptionCount; i++) + { + if(index == gDriverData[i].Option) + { + if(gDriverData[i].DevicePath->Type == BBS_DEVICE_PATH && gDriverData[i].DevicePath->SubType == BBS_BBS_DP) + return; + break; + } + } + + //Remove option from gDriverData and add to gDelDriverData + //Remove option from DriverOrder + if(gDriverOptionCount - 1) + { + pDriverData = EfiLibAllocateZeroPool(sizeof(BOOT_DATA) * (gDriverOptionCount - 1)); + NewDriverOrder = EfiLibAllocateZeroPool(sizeof(UINT16) * (gDriverOptionCount - 1)); + } + + size = 0; + CurrDriverOrder = VarGetVariable(VARIABLE_ID_DRIVER_ORDER, &size); + + gDelDriverData = MemReallocateZeroPool(gDelDriverData, sizeof(BOOT_DATA) * gDriverDelOptionCount, sizeof(BOOT_DATA) * (gDriverDelOptionCount + 1)); + + for(i=0,j=0,k=0; i<gDriverOptionCount; i++) + { + if(index == gDriverData[i].Option) + { + MemCopy(gDelDriverData + gDriverDelOptionCount, gDriverData + i, sizeof(BOOT_DATA)); + } + else + { + MemCopy(pDriverData + j, gDriverData + i, sizeof(BOOT_DATA)); + j++; + } + + if(index != CurrDriverOrder[i]) + { + if(k<(gDriverOptionCount-1)) + { + NewDriverOrder[k] = CurrDriverOrder[i]; + k++; + } + } + } + + gDriverDelOptionCount++; + gDriverOptionCount--; + + MemFreePointer((VOID **)&gDriverData); + gDriverData = pDriverData; + + MemFreePointer((VOID **)&CurrDriverOrder); + + //Update boot manager vars in memory + //1. TSE Driver Order + MemFreePointer((VOID **) &gVariableList[VARIABLE_ID_DRIVER_ORDER].Buffer); + if (gLoadOptionHidden) + { + FixHiddenOptions (DRIVER_ORDER_OPTION, &NewDriverOrder, gDriverOptionCount); + } + gVariableList[VARIABLE_ID_DRIVER_ORDER].Buffer = (UINT8 *)NewDriverOrder; + gVariableList[VARIABLE_ID_DRIVER_ORDER].Size = gDriverOptionCount * sizeof(UINT16); + + //2. DriverManager + DriverCountVal = (UINT16)gDriverOptionCount; + Status = VarSetValue(VARIABLE_ID_DRIVER_MANAGER,0,sizeof(UINT16),(VOID *)(&DriverCountVal)); + if(EFI_SUCCESS == Status) + mPostMgr->DisplayMsgBox( L"SUCCESS", L"Driver Deleted Successfully", MSGBOX_TYPE_OK,NULL); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DiscardAddDelBootOptions +// +// Description: Function to discarding the add/del boot option +// +// Input: VOID +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID DiscardAddDelBootOptions(VOID) +{ + UINTN count,i,j; + BOOT_DATA *pBootData; + UINT16 *AddOptionList=NULL,*DelOptionList=NULL; + UINTN AddOptionListCount=0, DelOptionListCount=0; + UINT16 *NewBootOrder = NULL, *CurrBootOrder = NULL; + UINTN size, tempsize = 0; + + //find no. of boot options + count = 0; + for(i=0;i<gBootOptionCount;i++) + { + if(!gBootData[i].bNewOption) + count++; + else + AddOptionListCount++; + } + for(i=0;i<gDelOptionCount;i++) + { + if(!gDelBootData[i].bNewOption) + count++; + else + DelOptionListCount++; + } + + //Allocate for boot options + pBootData = NULL; + if(count) + pBootData = EfiLibAllocateZeroPool(count * sizeof(BOOT_DATA)); + if(AddOptionListCount) + AddOptionList=EfiLibAllocateZeroPool(AddOptionListCount * sizeof(UINT16)); + if(DelOptionListCount) + DelOptionList=EfiLibAllocateZeroPool(DelOptionListCount * sizeof(UINT16)); + + count = 0; + AddOptionListCount=0; + DelOptionListCount=0; + + //Copy old options + for(i=0;i<gBootOptionCount;i++) + { + if(!gBootData[i].bNewOption) + { + MemCopy(pBootData+count, gBootData+i, sizeof(BOOT_DATA)); + count++; + } + else + { // Newly added option that need to removed. + AddOptionList[AddOptionListCount++] = gBootData[i].Option; + } + } + + for(i=0;i<gDelOptionCount;i++) + { + if(!gDelBootData[i].bNewOption) + { + MemCopy(pBootData+count, gDelBootData+i, sizeof(BOOT_DATA)); + count++; + + // deleted option that need to added. + DelOptionList[DelOptionListCount++] = gDelBootData[i].Option; + } + } + + MemFreePointer((VOID **) &gBootData); + gBootData = pBootData; + gBootOptionCount = count; + + MemFreePointer((VOID **) &gDelBootData); + gDelOptionCount = 0; + +// EIP 32445 +// Update BootOrderVar Cache after discarding the changes. +// If newly add/Del option discorded. + if(AddOptionListCount || DelOptionListCount) + { + CurrBootOrder = VarGetVariable(VARIABLE_ID_BOOT_ORDER, &size); + NewBootOrder = EfiLibAllocateZeroPool((gBootOptionCount) * sizeof(UINT16)); + count = size/2; + + // Defaults might be load Move the disabled boot option to the end + for(j=0;j<count;j++) + { + if(DISABLED_BOOT_OPTION == CurrBootOrder[j]) + { + if (size < ((j+1)*sizeof(UINT16))) //EIP-131549 + tempsize = ((j+1)*sizeof(UINT16)) - size; + else + tempsize = size - ((j+1)*sizeof(UINT16)); + + MemCopy(&CurrBootOrder[j], &CurrBootOrder[j+1], tempsize); + size-=sizeof(UINT16); + } + } + + // remove the Newly added boot options + count = size/2; + for(i=0;i<AddOptionListCount;i++) + { + for(j=0;j<count;j++) + { + if(CurrBootOrder[j] == AddOptionList[i]) + { + if (size < ((j+1)*sizeof(UINT16))) //EIP-131549 + tempsize = ((j+1)*sizeof(UINT16)) - size; + else + tempsize = size - ((j+1)*sizeof(UINT16)); + + MemCopy(&CurrBootOrder[j], &CurrBootOrder[j+1], tempsize); + size-=sizeof(UINT16); + } + } + } + count = size/2; + // Add the DelOptions + MemCopy(NewBootOrder, CurrBootOrder, size); + MemCopy(&NewBootOrder[count],DelOptionList,DelOptionListCount*sizeof(UINT16) ); + + // Make the remailing options as disabled. + for(i=count+DelOptionListCount;i<gBootOptionCount;i++) + NewBootOrder[i] = DISABLED_BOOT_OPTION; + + MemFreePointer((VOID **) &CurrBootOrder); + MemFreePointer((VOID **) &DelOptionList); + MemFreePointer((VOID **) &AddOptionList); + + //Update boot manager vars in memory + //1. TSE Boot order + MemFreePointer((VOID **) &gVariableList[VARIABLE_ID_BOOT_ORDER].Buffer); + if (gLoadOptionHidden) + { + FixHiddenOptions (BOOT_ORDER_OPTION, &NewBootOrder, gBootOptionCount); + } + _DisableRestorePrevOptions (BOOT_ORDER_OPTION, &NewBootOrder, gBootOptionCount); //Disable options after discarding changes to active so fixed it + gVariableList[VARIABLE_ID_BOOT_ORDER].Buffer = (UINT8 *)NewBootOrder; + gVariableList[VARIABLE_ID_BOOT_ORDER].Size = gBootOptionCount * sizeof(UINT16); + } +} + +//EIP70421 & 70422 Support for driver order +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DiscardAddDelDriverOptions +// +// Description: Function to discarding the add/del driver option +// +// Input: VOID +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID DiscardAddDelDriverOptions(VOID) +{ + UINTN count,i,j; + BOOT_DATA *pDriverData; + UINT16 *AddOptionList=NULL,*DelOptionList=NULL; + UINTN AddOptionListCount=0, DelOptionListCount=0; + UINT16 *NewDriverOrder = NULL, *CurrDriverOrder = NULL; + UINTN size = 0, tempsize = 0; + + //find no. of boot options + count = 0; + for(i=0;i<gDriverOptionCount;i++) + { + if(!gDriverData[i].bNewOption) + count++; + else + AddOptionListCount++; + } + for(i=0;i<gDriverDelOptionCount;i++) + { + if(!gDelDriverData[i].bNewOption) + count++; + else + DelOptionListCount++; + } + + //Allocate for boot options + pDriverData = NULL; + if(count) + pDriverData = EfiLibAllocateZeroPool(count * sizeof(BOOT_DATA)); + if(AddOptionListCount) + AddOptionList=EfiLibAllocateZeroPool(AddOptionListCount * sizeof(UINT16)); + if(DelOptionListCount) + DelOptionList=EfiLibAllocateZeroPool(DelOptionListCount * sizeof(UINT16)); + + count = 0; + AddOptionListCount=0; + DelOptionListCount=0; + + //Copy old options + for(i=0;i<gDriverOptionCount;i++) + { + if(!gDriverData[i].bNewOption) + { + MemCopy(pDriverData+count, gDriverData+i, sizeof(BOOT_DATA)); + count++; + } + else + { // Newly added option that need to removed. + AddOptionList[AddOptionListCount++] = gDriverData[i].Option; + } + } + + for(i=0;i<gDriverDelOptionCount;i++) + { + if(!gDelDriverData[i].bNewOption) + { + MemCopy(pDriverData+count, gDelDriverData+i, sizeof(BOOT_DATA)); + count++; + + // deleted option that need to added. + DelOptionList[DelOptionListCount++] = gDelDriverData[i].Option; + } + } + + MemFreePointer((VOID **) &gDriverData); + gDriverData = pDriverData; + gDriverOptionCount = count; + + MemFreePointer((VOID **) &gDelDriverData); + gDriverDelOptionCount = 0; + +// Update DriverOrderVar Cache after discarding the changes. +// If newly add/Del option discorded. + if(AddOptionListCount || DelOptionListCount) + { + CurrDriverOrder = VarGetVariable(VARIABLE_ID_DRIVER_ORDER, &size); + NewDriverOrder = EfiLibAllocateZeroPool((gDriverOptionCount) * sizeof(UINT16)); + count = size/2; + + // Defaults might be load Move the disabled driver option to the end + for(j=0;j<count;j++) + { + if(DISABLED_BOOT_OPTION == CurrDriverOrder[j]) + { + if (size > ((j+1)*sizeof(UINT16))) //EIP-131549 + tempsize = size - ((j+1)*sizeof(UINT16)); + else + tempsize = ((j+1)*sizeof(UINT16)) - size; + + MemCopy(&CurrDriverOrder[j], &CurrDriverOrder[j+1], tempsize ); + size-=sizeof(UINT16); + } + } + + // remove the Newly added driver options + count = size/2; + for(i=0;i<AddOptionListCount;i++) + { + for(j=0;j<count;j++) + { + if(CurrDriverOrder[j] == AddOptionList[i]) + { + if ((UINTN)size >= ((j+1)*sizeof (UINT16)) ) //Check added bcoz, If only added driver presents and loading defaults will lead to crash + { + if (size > ((j+1)*sizeof(UINT16))) //EIP-131549 + tempsize = size - ((j+1)*sizeof(UINT16)); + else + tempsize = ((j+1)*sizeof(UINT16)) - size; + + MemCopy (&CurrDriverOrder [j], &CurrDriverOrder[j+1], tempsize ); + size-=sizeof(UINT16); + } + } + } + } + + count = size/2; + // Add the DelOptions + MemCopy(NewDriverOrder, CurrDriverOrder, size); + MemCopy(&NewDriverOrder[count],DelOptionList,DelOptionListCount*sizeof(UINT16) ); + + // Make the remaining options as disabled. + for(i=count+DelOptionListCount;i<gDriverOptionCount;i++) + NewDriverOrder[i] = DISABLED_BOOT_OPTION; + + MemFreePointer((VOID **) &CurrDriverOrder); + MemFreePointer((VOID **) &DelOptionList); + MemFreePointer((VOID **) &AddOptionList); + + //Update driver manager vars in memory + //1. TSE Driver Order + MemFreePointer((VOID **) &gVariableList[VARIABLE_ID_DRIVER_ORDER].Buffer); + if (gLoadOptionHidden) + { + FixHiddenOptions (DRIVER_ORDER_OPTION, &NewDriverOrder, gDriverOptionCount); + } + _DisableRestorePrevOptions (DRIVER_ORDER_OPTION, &NewDriverOrder, gDriverOptionCount); + gVariableList[VARIABLE_ID_DRIVER_ORDER].Buffer = (UINT8 *)NewDriverOrder; + gVariableList[VARIABLE_ID_DRIVER_ORDER].Size = gDriverOptionCount * sizeof(UINT16); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SaveAddDelBootOptions +// +// Description: function to save the added/deleted boot option +// +// Input: VOID +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SaveAddDelBootOptions(VOID) +{ + UINTN i,OptimalIndex,FailsafeIndex,size; + UINT16 dpLength,*pNewOptimal, *pOldOptimal, *pNewFailsafe, *pOldFailsafe; + BOOT_OPTION *pOption; + CHAR16 *varName = L"BootXXXX"; + UINT16 BootCountVal; + + //Old Boot order defaults are not valid any more. Form the new + //defaults by removing deleted options and adding the new options at the end. + pNewOptimal = EfiLibAllocateZeroPool( gBootOptionCount * sizeof(UINT16) ); + pNewFailsafe = EfiLibAllocateZeroPool( gBootOptionCount * sizeof(UINT16) ); + pOldOptimal = (UINT16 *)gOptimalDefaults[ VARIABLE_ID_BOOT_ORDER ].Buffer; + pOldFailsafe = (UINT16 *)gFailsafeDefaults[ VARIABLE_ID_BOOT_ORDER ].Buffer; + size = gOptimalDefaults[ VARIABLE_ID_BOOT_ORDER ].Size; + OptimalIndex = FailsafeIndex = 0; + + //Add existing options first + for(i=0;i<size/sizeof(UINT16);i++) + { + if(BootGetBootData(pOldOptimal[i])) + { + pNewOptimal[OptimalIndex] = pOldOptimal[i]; + OptimalIndex++; + } + if(BootGetBootData(pOldFailsafe[i])) + { + pNewFailsafe[FailsafeIndex] = pOldFailsafe[i]; + FailsafeIndex++; + } + } + //Save New boot options + for(i=0;i<gBootOptionCount;i++) + { + if(gBootData[i].bNewOption) + { + dpLength = (UINT16)EfiDevicePathSize( gBootData[i].DevicePath ); + size = sizeof(BOOT_OPTION) + sizeof(CHAR16)*EfiStrLen(gBootData[i].Name) + dpLength; + pOption = EfiLibAllocateZeroPool( size ); + pOption->Active = gBootData[i].Active; + pOption->PathLength = dpLength; + EfiStrCpy( pOption->Name, gBootData[i].Name ); + MemCopy( (UINT8 *)pOption + size - dpLength, gBootData[i].DevicePath, dpLength ); + + SPrint( varName, sizeof(CHAR16) * (EfiStrLen( varName )+1), gBootFormarSpecifier, gBootData[i].Option ); + VarSetNvramName( varName, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + pOption, + size ); + + gBootData[i].bNewOption = 0; + + //Append this option in defaults + pNewOptimal[OptimalIndex] = gBootData[i].Option; + pNewFailsafe[FailsafeIndex] = gBootData[i].Option; + OptimalIndex++; + FailsafeIndex++; + } + } + + //Put new defaults in global default repository + //If Default order is not found in first time then will take current order. + //If any boot options added after that then new boot option always follow the first saved optimized buffer + //Removed EIP81581 fixes All the time changing the default buffer is not good + if (0 == gOptimalDefaults [VARIABLE_ID_BOOT_ORDER].Size) //EIP79956 Defaults not loading properly + { + UINT8 *pOptWithOutDefaultBootOrder = EfiLibAllocateZeroPool (gVariableList [VARIABLE_ID_BOOT_ORDER].Size); + if (NULL != pOptWithOutDefaultBootOrder) + { + MemCopy (pOptWithOutDefaultBootOrder, gVariableList [VARIABLE_ID_BOOT_ORDER].Buffer, gVariableList [VARIABLE_ID_BOOT_ORDER].Size); + gOptimalDefaults [VARIABLE_ID_BOOT_ORDER].Buffer = pOptWithOutDefaultBootOrder; + gOptimalDefaults [VARIABLE_ID_BOOT_ORDER].Size = gVariableList [VARIABLE_ID_BOOT_ORDER].Size; + } + } + else + { + MemFreePointer( (VOID **) &gOptimalDefaults[ VARIABLE_ID_BOOT_ORDER ].Buffer ); + gOptimalDefaults[ VARIABLE_ID_BOOT_ORDER ].Buffer = (UINT8 *)pNewOptimal; + gOptimalDefaults[ VARIABLE_ID_BOOT_ORDER ].Size = OptimalIndex * sizeof(UINT16); + } + + MemFreePointer( (VOID **) &gFailsafeDefaults[ VARIABLE_ID_BOOT_ORDER ].Buffer ); + gFailsafeDefaults[ VARIABLE_ID_BOOT_ORDER ].Buffer = (UINT8 *)pNewFailsafe; + gFailsafeDefaults[ VARIABLE_ID_BOOT_ORDER ].Size = FailsafeIndex * sizeof(UINT16); + + //Delete removed options + for(i=0;i<gDelOptionCount;i++) + { + if(!gDelBootData[i].bNewOption) + { + SPrint( varName, sizeof(CHAR16) * (EfiStrLen( varName )+1), gBootFormarSpecifier, gDelBootData[i].Option ); + VarSetNvramName( varName, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + varName, + 0); + } + } + MemFreePointer((VOID **)&gDelBootData); + gDelOptionCount = 0; + + //Update default value for Boot Manager and Boot Now count + BootCountVal = (UINT16) gBootOptionCount; + _VarGetSetValue (VAR_COMMAND_SET_VALUE, gOptimalDefaults, VARIABLE_ID_BOOT_MANAGER, 0, sizeof(UINT16), (VOID *)(&BootCountVal)); + _VarGetSetValue (VAR_COMMAND_SET_VALUE, gFailsafeDefaults, VARIABLE_ID_BOOT_MANAGER, 0, sizeof(UINT16), (VOID *)(&BootCountVal)); + + if (gShowAllBbsDev) + BootCountVal = _BootSetBootNowCount (); + + _VarGetSetValue (VAR_COMMAND_SET_VALUE, gOptimalDefaults, VARIABLE_ID_BOOT_NOW, 0, sizeof(UINT16), (VOID *)(&BootCountVal)); + _VarGetSetValue (VAR_COMMAND_SET_VALUE, gFailsafeDefaults, VARIABLE_ID_BOOT_NOW, 0, sizeof(UINT16), (VOID *)(&BootCountVal)); +} + +//EIP70421 & 70422 Support for driver order +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SaveAddDelDriverOptions +// +// Description: Function to save the added/deleted Driver option +// +// Input: VOID +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SaveAddDelDriverOptions(VOID) +{ + UINTN i,OptimalIndex,FailsafeIndex,size; + UINT16 dpLength,*pNewOptimal, *pOldOptimal, *pNewFailsafe, *pOldFailsafe; + BOOT_OPTION *pOption; + CHAR16 *varName = L"DriverXXXX"; + UINT16 DriverCountVal; + + //Old Driver order defaults are not valid any more. Form the new + //defaults by removing deleted options and adding the new options at the end. + pNewOptimal = EfiLibAllocateZeroPool( gDriverOptionCount * sizeof(UINT16) ); + pNewFailsafe = EfiLibAllocateZeroPool( gDriverOptionCount * sizeof(UINT16) ); + pOldOptimal = (UINT16 *)gOptimalDefaults[ VARIABLE_ID_DRIVER_ORDER ].Buffer; + pOldFailsafe = (UINT16 *)gFailsafeDefaults[ VARIABLE_ID_DRIVER_ORDER ].Buffer; + size = gOptimalDefaults[ VARIABLE_ID_DRIVER_ORDER ].Size; + OptimalIndex = FailsafeIndex = 0; + + //Add existing options first + for(i=0;i<size/sizeof(UINT16);i++) + { + if (DriverGetDriverData (pOldOptimal [i])) + { + pNewOptimal[OptimalIndex] = pOldOptimal[i]; + OptimalIndex++; + } + if(DriverGetDriverData (pOldFailsafe[i])) + { + pNewFailsafe[FailsafeIndex] = pOldFailsafe[i]; + FailsafeIndex++; + } + } + //Save New driver options + for(i=0;i<gDriverOptionCount;i++) + { + if(gDriverData[i].bNewOption) + { + dpLength = (UINT16)EfiDevicePathSize( gDriverData[i].DevicePath ); + size = sizeof(BOOT_OPTION) + sizeof(CHAR16)*EfiStrLen(gDriverData[i].Name) + dpLength; + pOption = EfiLibAllocateZeroPool( size ); + pOption->Active = gDriverData[i].Active; + pOption->PathLength = dpLength; + EfiStrCpy( pOption->Name, gDriverData[i].Name ); + MemCopy( (UINT8 *)pOption + size - dpLength, gDriverData[i].DevicePath, dpLength ); + + SPrint( varName, sizeof(CHAR16) * (EfiStrLen( varName )+1), gDriverFormarSpecifier, gDriverData[i].Option ); + VarSetNvramName( varName, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + pOption, + size ); + + gDriverData[i].bNewOption = 0; + //Append this option in defaults + pNewOptimal[OptimalIndex] = gDriverData[i].Option; + pNewFailsafe[FailsafeIndex] = gDriverData[i].Option; + OptimalIndex++; + FailsafeIndex++; + } + } + + //Put new defaults in global default repository + //Default order is not found in first time then will take current order. + //If any driver options added after that then new driver option always follow the first saved optimized buffer + //Removed EIP81581 fixes All the time changing the default buffer is not good + if (0 == gOptimalDefaults [VARIABLE_ID_DRIVER_ORDER].Size) + { + UINT8 *pOptWithOutDefaultDriverOrder = EfiLibAllocateZeroPool (gVariableList [VARIABLE_ID_DRIVER_ORDER].Size); + if (NULL != pOptWithOutDefaultDriverOrder) + { + MemCopy (pOptWithOutDefaultDriverOrder, gVariableList [VARIABLE_ID_DRIVER_ORDER].Buffer, gVariableList [VARIABLE_ID_DRIVER_ORDER].Size); + gOptimalDefaults [VARIABLE_ID_DRIVER_ORDER].Buffer = pOptWithOutDefaultDriverOrder; + gOptimalDefaults [VARIABLE_ID_DRIVER_ORDER].Size = gVariableList [VARIABLE_ID_DRIVER_ORDER].Size; + } + } + else + { + MemFreePointer( (VOID **) &gOptimalDefaults[ VARIABLE_ID_DRIVER_ORDER ].Buffer ); + gOptimalDefaults[ VARIABLE_ID_DRIVER_ORDER ].Buffer = (UINT8 *)pNewOptimal; + gOptimalDefaults[ VARIABLE_ID_DRIVER_ORDER ].Size = OptimalIndex * sizeof(UINT16); + } + MemFreePointer( (VOID **) &gFailsafeDefaults[ VARIABLE_ID_DRIVER_ORDER ].Buffer ); + gFailsafeDefaults[ VARIABLE_ID_DRIVER_ORDER ].Buffer = (UINT8 *)pNewFailsafe; + gFailsafeDefaults[ VARIABLE_ID_DRIVER_ORDER ].Size = FailsafeIndex * sizeof(UINT16); + + //Delete removed options + for(i=0;i<gDriverDelOptionCount;i++) + { + if(!gDelDriverData[i].bNewOption) + { + SPrint( varName, sizeof(CHAR16) * (EfiStrLen( varName )+1), gDriverFormarSpecifier, gDelDriverData[i].Option ); + VarSetNvramName (varName, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + varName, + 0); + } + } + MemFreePointer((VOID **)&gDelDriverData); + gDriverDelOptionCount = 0; + + //Update default value for Driver Manager + DriverCountVal = (UINT16) gDriverOptionCount; + _VarGetSetValue( VAR_COMMAND_SET_VALUE, gOptimalDefaults, VARIABLE_ID_DRIVER_MANAGER, 0, sizeof(UINT16), (VOID *)(&DriverCountVal) ); + _VarGetSetValue( VAR_COMMAND_SET_VALUE, gFailsafeDefaults, VARIABLE_ID_DRIVER_MANAGER, 0, sizeof(UINT16), (VOID *)(&DriverCountVal) ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: TSELiteFixAddBootOptionFileList +// +// Description: Function to fix Add Boot Option file list +// +// Input: CONTROL_DATA *ControlData +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID TSELiteFixAddBootOptionFileList(CONTROL_DATA *ControlData) +{ + POPUPSEL_DATA *popupSel = (POPUPSEL_DATA *)ControlData; + UINT16 i=0; + if(gFsCount >= popupSel->ItemCount) // If the filesystem found + { + for(i=0;i<popupSel->ItemCount;i++) + { + popupSel->PtrTokens[i].Option = HiiAddString( popupSel->ControlData.ControlHandle, gFsList[i].FsId ); + popupSel->PtrTokens[i].Value = i; + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: TSELiteFixAddBootOptionFileList +// +// Description: Function to fix Delete Boot option file list +// +// Input: CONTROL_DATA *ControlData +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID TSELiteFixDelBootOptionFileList(CONTROL_DATA *ControlData) +{ + POPUPSEL_DATA *popupSel = (POPUPSEL_DATA *)ControlData; + UINT16 i=0; + + for(i=0;i<popupSel->ItemCount;i++) + { + if((UINT16)popupSel->PtrTokens[i].Value != 0xFFFF) + { + popupSel->PtrTokens[i].Value = gBootData[i-1].Option; + popupSel->PtrTokens[i].Option = HiiAddString( popupSel->ControlData.ControlHandle, BootGetOptionName( &(gBootData[i-1]) ) ); + } + } +} + +/// EIP-41615: START - File Browser related functions for Add Boot Option.. +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: CleanFileTypes +// +// Description: Frees all allocated memory associated with the FILE_TYPE structure +// and resets the InternalString current strings next available string token +// to be the first dynamically added string +// +// Input: FILE_TYPE **FileList - The array of FILE_TYPE structures found in +// a directory +// UINTN *FileCount - pointer to the number of entries in the FileList +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID CleanFileTypes(FILE_TYPE **FileList, UINTN *FileCount) +{ + UINTN i; + for(i = 0; i<*FileCount; i++) gBS->FreePool((*FileList)[i].Name); + if(FileList!=NULL && (*FileList!=NULL) && (*FileCount>0)) gBS->FreePool(*FileList); + if(FileList!=NULL) *FileList = NULL; + *FileCount = 0; +} +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: CheckDirectoryType +// +// Description: Checks if the EFI_FILE_INFO is a directory (and not the current directory) +// +// Input: EFI_FILE_INFO *File +// +// Output: +// +// Returns: BOOLEAN - TRUE - item is a directory, and not the current directory +// FALSE - item is not a directory, or is the current directory +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN CheckDirectoryType(EFI_FILE_INFO *File) +{ + BOOLEAN Status = FALSE; + + if((File->Attribute & EFI_FILE_DIRECTORY) && (EfiStrCmp(File->FileName, L".") != 0)) { + + Status = TRUE; + } + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: CheckExtension +// +// Description: Check is the EFI_FILE_INFO has the same extension as the +// extension passed in the second parameter +// +// Input: EFI_FILE_INFO *File - The file entry whose extension should be checked +// CHAR16 *ExtensionEfi - the extension +// +// Output: +// +// Returns: BOOLEAN - TRUE - The extension matches +// FALSE - the extension does not match +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN CheckExtension(EFI_FILE_INFO *File, CHAR16 *ExtensionEfi) +{ + BOOLEAN Status = FALSE; + UINTN Length = EfiStrLen(File->FileName); + + if((File->Attribute & EFI_FILE_DIRECTORY) != EFI_FILE_DIRECTORY && Length > 3) + if((((File->FileName[Length-1])&0xdf) == ((ExtensionEfi[2])&0xdf)) && + (((File->FileName[Length-2])&0xdf) == ((ExtensionEfi[1])&0xdf)) && + (((File->FileName[Length-3])&0xdf) == ((ExtensionEfi[0])&0xdf))) + Status = TRUE; + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: FindInsertionIndex +// +// Description: Finds the inded where directories items turn into file items +// +// Input: FILE_TYPE *List - the current array of File Type structures +// UINTN FileCount - the count of File Type structures in the array +// +// Output: +// +// Returns: the index to insert a new item +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +UINTN FindInsertionIndex(FILE_TYPE *List, UINTN FileCount) +{ + UINTN i = 0; + + if(FileCount <= 1) return 0; + + for(i = 1; i < (FileCount-1); i++) + { + if(List[i-1].Type != List[i].Type) + break; + } + + return i; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: AddFileTypeEntry +// +// Description: Creates a new entry in the FILE_TYPE array and adds the current File into +// the array. +// +// Input: FILE_TYPE **List - Array of FILE_TYPE structures alread found +// UINTN *FileCount - number of entries in the FILE_TYPE array +// EFI_FILE_INFO *FileInfo - file info of the file that should be added +// +// Output: +// +// Returns: +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +static VOID AddFileTypeEntry(FILE_TYPE **List, UINTN *FileCount, EFI_FILE_INFO *FileInfo) +{ + FILE_TYPE *NewList=NULL; + UINTN Length; + UINTN Index = 0; + + Length = (EfiStrLen(FileInfo->FileName)+3)*sizeof(CHAR16); + + // Allocate space for a new list entry plus all the previous list items + NewList = EfiLibAllocateZeroPool(sizeof(FILE_TYPE)*(++(*FileCount))); + if (NewList != NULL) + { + // Clear the memory of the entire list + MemSet(NewList, sizeof(FILE_TYPE)*(*FileCount), 0); + + // Copy the old entries (if there are any old entries to copy) + if(*List != NULL) + { + Index = FindInsertionIndex(*List, *FileCount); + + MemCopy(NewList, *List, sizeof(FILE_TYPE)*(Index)); + MemCopy(&(NewList[Index+1]), &((*List)[Index]), sizeof(FILE_TYPE)*((*FileCount)-Index-1)); + + gBS->FreePool(*List); + } + + // Store the type of this FILE_TYPE entry (non-zero is directory) + NewList[Index].Type = ((FileInfo->Attribute) & EFI_FILE_DIRECTORY); + + // Store the size of the file + NewList[Index].Size = (UINTN)FileInfo->FileSize; + + // Allocate space for the string + NewList[Index].Name = EfiLibAllocateZeroPool (Length); + if((NewList[Index].Name) != NULL ) + { + // Clear the allocated memory + MemSet(NewList[Index].Name, Length, 0); + + // Create either a Dir string or a File string for addition to the HiiDataBase + if(NewList[Index].Type == EFI_FILE_DIRECTORY) + SPrint(NewList[Index].Name, (sizeof(CHAR16)*EfiStrLen(FileInfo->FileName)+1), L"<%s>", FileInfo->FileName); + else + SPrint(NewList[Index].Name, (sizeof(CHAR16)*EfiStrLen(FileInfo->FileName)+1), L"%s", FileInfo->FileName); + + // Add the string to the HiiDataBase + ///NewList[Index].Token = AddStringToHii(FileInfo->FileName, &gInternalStrings); ///Just by trying using the following line + NewList[Index].Token = HiiAddString(gHiiHandle, NewList[Index].Name ); + + // Clear the memory and create the string for the File Structure + MemSet(NewList[Index].Name, Length, 0); + SPrint(NewList[Index].Name, (sizeof(CHAR16)*EfiStrLen(FileInfo->FileName)+1), L"%s", FileInfo->FileName); + } + *List = NewList; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: CreateFileList +// +// Description: Parse all the files in the current directory and add valid files to the +// FILE_TYPE list and update the filecount +// +// Input: EFI_FILE_PROTOCOL *FileProtocol - the current direcotry to parse +// +// Output: FILE_TYPE **FileList - pointer in which to return the array of FileType items +// UINTN *FileCount - the count of filetype items discovered +// +// Returns: EFI_STATUS +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +static EFI_STATUS CreateFileList(EFI_FILE_PROTOCOL *FileProtocol, FILE_TYPE **FileList, UINTN *FileCount) +{ + EFI_STATUS Status = EFI_SUCCESS; + + UINTN BufferSize = 1; + EFI_FILE_INFO *File = NULL; + + CHAR16 ExtensionEfi[] = L"EFI"; + + // Continue parsing the directory until we no longer read valid files + while(BufferSize != 0 && !EFI_ERROR(Status)) + { + BufferSize = 0; + Status = FileProtocol->Read(FileProtocol, &BufferSize, NULL); + + if(!EFI_ERROR(Status)) break; + + if(Status == EFI_BUFFER_TOO_SMALL) + { + File = EfiLibAllocateZeroPool (BufferSize); + if(File != NULL) { + MemSet(File, BufferSize, 0); + } + } + + Status = FileProtocol->Read(FileProtocol, &BufferSize, File); + + // Check if a valid file was read + if(!EFI_ERROR(Status) && BufferSize != 0) + { + // check if the file read was a directory or a ".efi" extension + if(CheckDirectoryType(File) || CheckExtension(File, ExtensionEfi)) + { + // the file was valid, add it to the file list + AddFileTypeEntry(FileList, FileCount, File); + } + } + + // free the space allocated for readin the file info structure + gBS->FreePool(File); + + // set the pointer to null to prevent the chance of memory corruption + File = NULL; + } + + if(*FileCount == 0) Status = EFI_NOT_FOUND; + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: DisplayFileListMenu +// +// Description: Display a menu of the FILE_TYPE items and return the selected item +// in the Selection +// +// Input: FILE_TYPE *FileList - List of FILE_TYPE items to display in the menu +// UINTN FileCount - the number of FILE_TYPE items in the list +// +// Output: UINT16 *Selection - The index of the selected FILE_TYPE item +// +// Returns: +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +static EFI_STATUS DisplayFileListMenu(FILE_TYPE *FileList, UINTN FileCount, UINT16 *Selection, UINT32 Variable) +{ + EFI_STATUS Status = EFI_SUCCESS; + + UINT16 i = 0; + + POSTMENU_TEMPLATE *List = NULL; + + // Check there are any files to display + if(FileCount != 0 && FileList != NULL) + { + // allocate space for the POSTMENU_TEMPLATE items + List = EfiLibAllocateZeroPool (sizeof(POSTMENU_TEMPLATE)*FileCount); + if(List != NULL) + { + // Clear the memory allocated + MemSet(List, sizeof(POSTMENU_TEMPLATE)*FileCount, 0); + + // Add the STRING_REF tokens to the POSTMENU_TEMPLATE structures + for(i = 0; i < FileCount; i++) + List[i].ItemToken = FileList[i].Token; + } + + // Call post manager to display the menu + Status = mPostMgr->DisplayPostMenu(gHiiHandle, + (VARIABLE_ID_ADD_BOOT_OPTION == Variable) ? STRING_TOKEN (STR_FILE_PATH) : STRING_TOKEN (STR_DRIVER_PATH), + 0, + List, + (UINT16)FileCount, + Selection); + } + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: UpdateFilePathString +// +// Description: To create the File Path string based on the file selected. +// +// Input: CHAR16 *FilePath - Buffer to fill with the file path +// CHAR16 * CurFile - current file selected +// UINT16 idx - Index of the file in the current directory +// +// Output: CHAR16 *FilePath - Updated File Path +// +// Returns: +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID UpdateFilePathString(CHAR16 *FilePath, CHAR16 * CurFile, UINT16 idx) +{ + UINTN Length=0; + + if(EfiStrLen(FilePath)) + { + if( idx==0 ) { + if(EfiStrCmp(CurFile,L"..")) { + EfiStrCat(FilePath,L"\\"); + EfiStrCat(FilePath,CurFile); + } + else { + + for ( Length = EfiStrLen(FilePath); ( Length!= 0 ) && (FilePath[Length-1] != L'\\') ; Length -- ); + if ( Length ) + FilePath[Length-1] = L'\0'; + else + FilePath[Length] = L'\0'; + } + } + else { + EfiStrCat(FilePath,L"\\"); + EfiStrCat(FilePath,CurFile); + } + } + else { + EfiStrCpy(FilePath,L"\\"); + EfiStrCat(FilePath,CurFile); + //EfiStrCpy(FilePath,CurFile); + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: FileBrowserLaunchFileSystem +// +// Description: To select the File System for the new boot option with the help of file browser. +// +// Input: VOID +// +// Output: Selected File System Index +// +// Returns: EFI_STATUS +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS FileBrowserLaunchFileSystem(UINT32 Variable) +{ + EFI_STATUS Status; + UINTN Count = 0; + UINT16 i = 0; + + EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; + EFI_DEVICE_PATH_PROTOCOL *Dp = NULL; + + POSTMENU_TEMPLATE *PossibleFileSystems = NULL; + + Status = gBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL, &mPostMgr); + if(EFI_ERROR(Status)) { + return EFI_UNSUPPORTED; + } + // Locate all the simple file system devices in the system + Status = gBS->LocateHandleBuffer(ByProtocol, &gSimpleFileSystemGuid, NULL, &Count, &gSmplFileSysHndlBuf); + if(!EFI_ERROR(Status)) + { + // allocate space to display all the simple file system devices + PossibleFileSystems = EfiLibAllocateZeroPool (sizeof(POSTMENU_TEMPLATE)*Count); + if(PossibleFileSystems != NULL) + { + // clear the allocated space + MemSet(PossibleFileSystems, sizeof(POSTMENU_TEMPLATE)*Count, 0); + for(i = 0; i < Count; i++) + { + // get the device path for each handle with a simple file system + Status = gBS->HandleProtocol(gSmplFileSysHndlBuf[i], &DevicePathGuid, &Dp); + if(!EFI_ERROR(Status)) + { + CHAR16 *Name = NULL; + + // Get the name of the driver installed on the handle + // GetControllerName(gHandleBuffer[i],&Name); + + Name = NULL; + Name = _DevicePathToStr(Dp); + + // Add the name to the Hii Database + ///PossibleFileSystems[i].ItemToken = AddStringToHii(Name); + PossibleFileSystems[i].ItemToken = HiiAddString(gHiiHandle, Name ); + + PossibleFileSystems[i].Attribute = AMI_POSTMENU_ATTRIB_FOCUS; + } + else + { + PossibleFileSystems[i].ItemToken = 0; + PossibleFileSystems[i].Attribute = AMI_POSTMENU_ATTRIB_HIDDEN; + } + } + // Reset the item selected to be the first item + gSelIdx = 0; + + // Display the post menu and wait for user input + Status = mPostMgr->DisplayPostMenu(gHiiHandle, + (Variable != 0xffff)? STRING_TOKEN(STR_FILE_SYSTEM) : STRING_TOKEN(STR_FILE_SYSTEM_TO_SAVE_IMG),//EIP-123432 + 0, + PossibleFileSystems, + (UINT16)Count, + &gSelIdx); + + + // A valid item was selected by the user + if(!EFI_ERROR(Status)) + { + gValidOption = TRUE; + } + } + } + + else { + ShowPostMsgBox( L"No Valid File System", L"No Valid File System Available", MSGBOX_TYPE_OK, NULL );//EIP:41615 To display Warning message when there is no file system connected. + + } + // Free the allocated menu list space + if(PossibleFileSystems != NULL) + gBS->FreePool(PossibleFileSystems); + if(Variable == VARIABLE_ID_ADD_BOOT_OPTION) + { + // Set the File System Index for the new boot option added + VarSetValue(VARIABLE_ID_ADD_BOOT_OPTION, STRUCT_OFFSET(NEW_BOOT_OPTION,SelFs), sizeof(UINT16), (VOID*)&gSelIdx); + } + if(Variable == VARIABLE_ID_ADD_DRIVER_OPTION) //EIP70421 & 70422 Support for driver order + { + VarSetValue(VARIABLE_ID_ADD_DRIVER_OPTION, STRUCT_OFFSET(NEW_DRIVER_OPTION,SelFs), sizeof(UINT16), (VOID*)&gSelIdx); + } + return Status; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------- +// Procedure: FileBrowserLaunchFilePath +// +// Description: To select the Boot file for the new boot option with the help of file browser. +// +// Input: VOID +// +// Output: File Path string +// +// Returns: EFI_STATUS +// +//---------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS FileBrowserLaunchFilePath(UINT32 Variable) +{ + EFI_STATUS Status; + EFI_HANDLE Handle = 0; + + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs = NULL; + EFI_FILE_PROTOCOL *NewFs = NULL; + FILE_TYPE *FileList = NULL; + UINTN FileCount = 0; + UINT16 i = 0; + //CHAR16 FilePath[120]; + CHAR16 *FilePath=NULL; + UINTN filenamelength = 0, Length = 0; + + // Attempt to locate the post manager protocol + Status = gBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL, &mPostMgr); + if(!EFI_ERROR(Status)) + { + if( gValidOption == TRUE ) + { + gValidOption = FALSE; + + // Get the simple file system protocol + Status = gBS->HandleProtocol(gSmplFileSysHndlBuf[gSelIdx], &gSimpleFileSystemGuid, &SimpleFs); + if(!EFI_ERROR(Status)) + { + // And open it and return the efi file protocol + Status = SimpleFs->OpenVolume(SimpleFs, &gFs); + } + } + else { + return EFI_UNSUPPORTED; + } + + // Free handle buffer space (auto allocated by the called function) + if(gSmplFileSysHndlBuf != NULL) + gBS->FreePool(gSmplFileSysHndlBuf); + + // clean up the file list and strings used in getting the file system + CleanFileTypes(&FileList, &FileCount); + } + + //MemSet(FilePath, 120, 0); + if ( NULL == FilePath ) //EIP-105725 + { + FilePath = (CHAR16*)EfiLibAllocateZeroPool(sizeof(CHAR16)); + } + + while(!EFI_ERROR(Status) && gFs != NULL) + { + i = 0; + + // Create a list of the files in the current directory + Status = CreateFileList(gFs, &FileList, &FileCount); + if(!EFI_ERROR(Status)) + { + // Display the list in a menu and allow the user to select + Status = DisplayFileListMenu(FileList, FileCount, &i, Variable); + if(!EFI_ERROR(Status)) + { + // The user selected something, attempt to open it + Status = gFs->Open( gFs, + &NewFs, + FileList[i].Name, + EFI_FILE_MODE_READ, + 0); + + // close the old file system protocol and set it to null + gFs->Close(gFs); + gFs = NULL; + + Length = EfiStrLen(FilePath) + 3; // adding 2 more character for \ and null termination + filenamelength = EfiStrLen(FileList[i].Name); + if ( NULL != FilePath ) + { + ////EIP-105725 Re-allocating based on filePath string length + FilePath = MemReallocateZeroPool( FilePath, (Length * sizeof (CHAR16)), ( (Length * sizeof (CHAR16)) + (filenamelength * sizeof (CHAR16)) ) ); + } + + + // Create the File Path based on the file selected + UpdateFilePathString(FilePath, FileList[i].Name, i); + + // the newly selected item was opened correctly + if(!EFI_ERROR(Status)) + { + // check what type was opened + if(FileList[i].Type != EFI_FILE_DIRECTORY) + { + // the file was read, close the file system protocol and set it to null + NewFs->Close(NewFs); + NewFs = NULL; + + //SPrint (FileName, 50, L"%s", FileList[i].Name); + //ShowPostMsgBox( L"Selected Boot File Name", FileName, MSGBOX_TYPE_OK, &SelOpt ); + } + gFs = NewFs; + } + } + } + + if(FileCount <= 0) { + ShowPostMsgBox( L"No Valid File", L"No Valid File Available in the Selected File System", MSGBOX_TYPE_OK, NULL );//EIP:41615 Warning message to show unavailability of the selected file + } + // clean the strings that were used and free allocated space + CleanFileTypes(&FileList, &FileCount); + + if(Status == EFI_ABORTED) { + return Status;//EIP:41615 Returning the status if its aborted. + } + } + // Set the File path for the new boot option added. + if(!EFI_ERROR(Status)) + { + if (VARIABLE_ID_ADD_BOOT_OPTION == Variable) + VarSetValue(VARIABLE_ID_ADD_BOOT_OPTION, STRUCT_OFFSET(NEW_BOOT_OPTION,Path), ((EfiStrLen(FilePath)+1)*sizeof(CHAR16)), FilePath); + if (VARIABLE_ID_ADD_DRIVER_OPTION == Variable) //EIP70421 & 70422 Support for driver order + VarSetValue(VARIABLE_ID_ADD_DRIVER_OPTION, STRUCT_OFFSET(NEW_DRIVER_OPTION,DriverPath), ((EfiStrLen(FilePath)+1)*sizeof(CHAR16)), FilePath); + } + MemFreePointer((VOID**)&FilePath); + return Status; +} +//EIP-41615: END.. +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** |