From 31bb486c913795c8b67d1c4dbaae2bdec4943fc9 Mon Sep 17 00:00:00 2001 From: raywu Date: Thu, 13 Sep 2018 16:11:56 +0800 Subject: SLP1.0 / SLP2.0 / Default Password / Logo / Fix Boot Order --- EDK/MiniSetup/uefi2.1/CtrlCond.c | 806 +++ EDK/MiniSetup/uefi2.1/CtrlCond.h | 146 + EDK/MiniSetup/uefi2.1/Expression.c | 2861 ++++++++ EDK/MiniSetup/uefi2.1/FormBrowser2.c | 1175 ++++ EDK/MiniSetup/uefi2.1/FormBrowser2.h | 156 + EDK/MiniSetup/uefi2.1/Hii.c | 3557 ++++++++++ EDK/MiniSetup/uefi2.1/HiiCallback.c | 1073 +++ EDK/MiniSetup/uefi2.1/HiiNotificationHandler.c | 740 +++ EDK/MiniSetup/uefi2.1/Parse.c | 4700 ++++++++++++++ EDK/MiniSetup/uefi2.1/TseUefiHii.h | 951 +++ EDK/MiniSetup/uefi2.1/Uefi21.cif | 21 + EDK/MiniSetup/uefi2.1/Uefi21.mak | 134 + EDK/MiniSetup/uefi2.1/Uefi21.sdl | 71 + EDK/MiniSetup/uefi2.1/Uefi21Wapper.c | 8266 ++++++++++++++++++++++++ EDK/MiniSetup/uefi2.1/UefiTianoHii.h | 241 + 15 files changed, 24898 insertions(+) create mode 100644 EDK/MiniSetup/uefi2.1/CtrlCond.c create mode 100644 EDK/MiniSetup/uefi2.1/CtrlCond.h create mode 100644 EDK/MiniSetup/uefi2.1/Expression.c create mode 100644 EDK/MiniSetup/uefi2.1/FormBrowser2.c create mode 100644 EDK/MiniSetup/uefi2.1/FormBrowser2.h create mode 100644 EDK/MiniSetup/uefi2.1/Hii.c create mode 100644 EDK/MiniSetup/uefi2.1/HiiCallback.c create mode 100644 EDK/MiniSetup/uefi2.1/HiiNotificationHandler.c create mode 100644 EDK/MiniSetup/uefi2.1/Parse.c create mode 100644 EDK/MiniSetup/uefi2.1/TseUefiHii.h create mode 100644 EDK/MiniSetup/uefi2.1/Uefi21.cif create mode 100644 EDK/MiniSetup/uefi2.1/Uefi21.mak create mode 100644 EDK/MiniSetup/uefi2.1/Uefi21.sdl create mode 100644 EDK/MiniSetup/uefi2.1/Uefi21Wapper.c create mode 100644 EDK/MiniSetup/uefi2.1/UefiTianoHii.h (limited to 'EDK/MiniSetup/uefi2.1') diff --git a/EDK/MiniSetup/uefi2.1/CtrlCond.c b/EDK/MiniSetup/uefi2.1/CtrlCond.c new file mode 100644 index 0000000..d783ffe --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/CtrlCond.c @@ -0,0 +1,806 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (C)Copyright 2012, 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/Uefi2.1/CtrlCond.c $ +// +// $Author: Premkumara $ +// +// $Revision: 21 $ +// +// $Date: 8/28/14 6:16a $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/CtrlCond.c $ +// +// 21 8/28/14 6:16a Premkumara +// EIP-135253 Updating file name proper in #include +// +// 20 2/11/14 8:49p Arunsb +// Changes reverted for 2.16.1243 label +// +// 18 6/10/13 1:19p Arunsb +// Parameters passed properly in GetDefaultValue +// +// 17 6/10/13 10:53a Arunsb +// Argument added in GetDefaultValue for EFI_IFR_TYPE_OTHER support in +// default retrieval. +// +// 16 5/22/13 10:52a Arunsb +// Fixed the issue in read write opcode +// +// 15 4/02/13 8:04a Arunsb +// [TAG] EIP113919, EIP114842 +// [Category] Improvement +// [Description] Provide support for EFI_IFR_WRITE, EFI_IFR_READ, +// EFI_IFR_GET, EFI_IFR_SET and EFI_IFR_MAP_OP. +// [Files] Setupdata.h, ctrlcond.c, expression.c, hii.c and parse.c +// +// 14 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 12 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 13 2/02/12 2:59a Premkumara +// [TAG] EIP75066 +// [Category] Improvement +// [Description] Support loading defaults for Ordelist controls +// [Files] Ordlistbox.c, Uefi21Wapper.c, CtrlCond.c, HiiCallback.c, +// Parse.c, Uefi20Wapper.c, TseUefihiil.h +// +// 12 2/01/12 4:57a Rajashakerg +// [TAG] EIP77256 +// [Category] Improvement +// [Description] Provide the Support to override the control Condition +// checking() generically. And provide customization to supress the +// controls with Security GUIDed opcode. +// [Files] AMITSE.sdl, CommonHelper.c, CtrlCond.c and CtrlCond.h +// +// 11 11/28/11 2:30a Premkumara +// [TAG] EIP75384 +// [Category] Improvement +// [Description] Suppress the warnings from static code analyzer +// [Files] UefiWapper.c, Hii.c, Expression.c, CtrlCond.c, PopupSel.c, +// Minisetupext.c, Menu.c, Date.c, Ezport\Stylecommon.c, +// EzportPlus\StyleCommon.c, +// +// 10 11/14/11 6:55p Blaines +// [TAG] - EIP 75486 +// [Category]- Function Request +// [Synopsis]- Support grayout condition for readonly controls. +// [Description] - Display readonly controls as grayout, non-selectable. +// [Files] +// AMITSE.sdl, CommonHelper.c, Minisetupext.h, stylecommon.c, Legacy.c, +// date.c, edit.c, label.c, memo.c, menu.c,, numeric.c, ordlistbox.c, +// PopupPassword.c, +// PopupSel.c, PopupString.c, ResetButton.c, SubMenu.c, Text.c, Time.c, +// UefiAction.c, ctrlcond.c, +// +// 9 3/28/11 11:03p Madhans +// [TAG] EIP56414 +// [Category] Improvement +// [Description] TSE: Support for EFI_IFR_NO_SUBMIT_IF opcode +// [Files] Callback.c, FakeToken.c, AMITSEstr.uni, Parse.c, CtrlCond.c, +// CtrlCond.h, ctrlcond.h, ctrlcond.c +// +// 8 2/03/11 8:19p Madhans +// [TAG] - EIP 50956 +// [Category]- defect +// [Severity]- Mordarate +// [Symptom]- If we leave the Setup page for 2 or more days. The system +// may hang/Crash. +// [Rootcause] - Memory leaks +// [Solution]- Memeory freed. +// [Files] - ctrlcond.c, memo.c and expression.c +// +// 7 12/02/10 5:34p Madhans +// [TAG] - EIP 49559 +// [Category]- defect +// [Severity]- Mordarate +// [Symptom]- OneOption contols works ok if it stores the values in BYTE +// and Does not contain any suppressif for options. +// But it has issues in supporting UINT16, UINT32 and UINT64 storage. +// [Rootcause] - The Type is not checked for Storeage and issues with +// condition check for options. +// [Solution]- Fix done ctrlcond.c and uefi21wrapper.c +// [Files] - CtrlCond.h, ctrlcond.c and uefi21wrapper.c +// +// 6 9/16/10 8:38p Madhans +// Update for TSE 2.10. Refer Changelog.log for more details. +// +// 8 7/07/10 7:45p Madhans +// Changes to Support Adding Conditions to Suppress or Grayout the Special +// controls. +// +// 7 6/14/10 7:11p Madhans +// to fix parsing issues. +// +// 6 3/11/10 5:41p Madhans +// Coding Standards Update +// +// 5 2/19/10 8:38p Madhans +// +// 4 2/19/10 8:35p Madhans +// Function header fix +// +// 3 11/19/09 5:28p Presannar +// Updated TSE include file name to not clash with CORE file +// +// 2 8/11/09 2:27p Presannar +// Added fn EvaluateControlDefault to evaluate the default expression. +// +// 1 7/24/09 6:54p Presannar +// +// 2 3/31/09 4:15p Madhans +// UEFI Wrapper improvments. +// +// 1 1/09/09 2:38p Presannar +// UEFI 2.1 Hii Related Code - Initial Drop +// +// 24 6/03/08 10:25a Madhans +// Boot Only driver and Add/remove TSE CSM support added. +// +// 23 5/15/08 11:30a Madhans +// Rolled back the Control Condition changes regarding the VarGetValue. +// Will be taken care differently. +// +// 21 8/15/07 2:48p Arunkumars +// Added support for vfr compiler 1.88 +// +// 20 5/22/07 9:17a Arunkumars +// Added support for vareq +// +// 19 12/04/06 3:13p Arunkumars +// Fix for behaviour of control access field in CONTOL_INFO +// +// 18 7/06/06 6:38p Arunkumars +// Warn fixes +// +// 17 6/15/06 9:34a Arunkumars +// Support to show new pages added at runtime +// +// 16 2/14/06 1:02p Arunkumars +// 1. Added Inconsistentif feature +// 2. We publish two events before and after asking for password (see +// postmgt.c and minisetup.h) +// +// 15 1/23/06 11:16p Stefanor +// Fixed a problem reported by Intel: if the setup question have more than +// one boolean condition for grayoutif,setup question is not behaving +// properly. (If the setup question is under multiple condition of +// suppressif and grayoutif, setup question is working with TSE 1.17.1050) +// +// 14 11/22/05 1:48p Franklynd +// two conditional one after the other where not processed properly. The +// last conditional was always returned. +// +// 13 7/19/05 3:40p Jerryp +// Reduced number of parameters. +// Code spacing cleanup +// +// 12 6/23/05 4:40p Franklynd +// Initializing local variable. +// +// 11 5/27/05 10:12a Jerryp +// Changed exit comparison of while loop +// +// 10 5/25/05 1:41a Jerryp +// Added support for ideqvallist +// +// 9 5/24/05 5:28p Stefanor +// fixed conditional problem for boot manager page (and, or condition) +// +// 8 5/18/05 11:55a Franklynd +// Using variable number , not ID +// +// 7 5/18/05 10:51a Franklynd +// updating variables on the fly from varstore_select and +// varstore_select_pair within the conditional expression +// +// 6 5/16/05 5:09p Franklynd +// 1-Support for multivariable (varstore, varstore_select, +// varstore_select_pair) +// 2-Support of optimal and failsafe defaults. +// 3- support of refresh of controls using their flag information. +// 4- added ORDERED_LIST control/ +// +// 5 3/18/05 2:52p Jerryp +// Fixed bug in conditional evaluation expression +// +// 4 3/01/05 3:33p Franklynd +// adding parse of multiple conditions for control. +// +// 3 3/01/05 12:01p Franklynd +// chack password control only if a regular user is loggd in. +// If an admin user is logged in, then don't check password control flags +// +// 2 2/24/05 5:14p Franklynd +// 1- adding number of control after a label in control_info structure. +// 2- adding check of access flags in control (password) +// 3- color schema code moved to styles area. +// +// 1 2/16/05 7:09p Franklynd +// +//************************************************************************* +// +// +// Name: CtrlCond.C +// +// Description: +// +// +//************************************************************************* + +//--------------------------------------------------------------------------- +#include "minisetup.h" +#include "CtrlCond.h" +#include "TseUefiHii.h" +//--------------------------------------------------------------------------- + +extern VOID EvaluateReadWrite(UINT8 *buf,CONTROL_INFO *ControlInfo,EFI_HII_VALUE *); + +UINTN _SkipExpression(UINT8 *ControlCondPtr); + +// +//---------------------------------------------------------------------------- +// Procedure: CheckControlAccess +// +// Description: check control flags +// +// Parameter: UINT32 ControlAccess +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 CheckControlAccess(UINT32 ControlAccess) +{ + UINT8 Cond = COND_NONE; + + if(gPasswordType == AMI_PASSWORD_USER) + { + switch(ControlAccess) + { + case CONTROL_ACCESS_ADMIN: // suppress + Cond = COND_SUPPRESS; + break; + case CONTROL_ACCESS_USER: // grayout (read-only) + Cond = COND_GRAYOUT; + break; + default: + break; + } + } + + return Cond; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UpdateFinalCondition +// +// Description: +// +// Parameter: UINT8 FinalCond, UINT8 Cond +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 UpdateFinalCondition(UINT8 FinalCond, UINT8 Cond) +{ + switch(FinalCond) + { + case COND_NONE: + return(Cond); + break; + + case COND_NOSUBMIT: + return(Cond); + break; + case COND_SUPPRESS: + case COND_HIDDEN: + return(FinalCond); + break; + + case COND_GRAYOUT: + if(Cond != COND_NONE) + return(Cond); + break; + + case COND_INCONSISTENT: + return(Cond); + break; + + } + return(FinalCond); +} +extern EFI_STATUS _SetValueFromQuestionId(UINT16 QuestionId, UINT16 PageId, EFI_HII_VALUE *Value); +// +//---------------------------------------------------------------------------- +// Procedure: CheckControlCondition +// +// Description: +// +// Parameter: CONTROL_INFO *controlInfo +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 CheckControlCondition( CONTROL_INFO *controlInfo ) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *tempControlInfo = NULL; + UINT32 CtrlAccess; + UINT8 *CondPtr; + UINT8 *CtrlPtr; + UINT8 Cond = COND_NONE, FinalCond = COND_NONE; + UINTN controlInfoLength = 0; + UINTN offset = 0; + UINTN i = 0; + UINTN ScopeCount = 0; + EFI_IFR_OP_HEADER *opHeader= (EFI_IFR_OP_HEADER *) NULL; + EFI_IFR_DEFAULT *Default = (EFI_IFR_DEFAULT *) NULL; + + UINT8 condStack[50]; + UINT8 opcodeStack[50]; + + INTN stackIndex = 0; + INTN inScope = 0; + EFI_HII_VALUE Value; + EFI_HII_VALUE Value1; + + BOOLEAN Inside = TRUE; + + CondPtr = (UINT8 *)controlInfo->ControlConditionalPtr; + CtrlAccess = controlInfo->ControlFlags.ControlAccess; + + CtrlPtr = (UINT8 *)controlInfo->ControlPtr; + EfiZeroMem (&Value1, sizeof (EFI_HII_VALUE)); +// EfiZeroMem (&Value, sizeof (EFI_HII_VALUE)); + if(controlInfo->ControlFlags.ControlRWEvaluate) + { + do + { + opHeader = (EFI_IFR_OP_HEADER*)(CtrlPtr + i); + switch(opHeader->OpCode) + { + case EFI_IFR_READ_OP: + EvaluateReadWrite((CtrlPtr + i + opHeader->Length),controlInfo,&Value1); + if(Value1.Type != EFI_IFR_TYPE_UNDEFINED){ + _SetValueFromQuestionId(controlInfo->ControlKey,controlInfo->ControlPageID,&Value1); + } + break; + case EFI_IFR_WRITE_OP: + EvaluateReadWrite((CtrlPtr + i + opHeader->Length),controlInfo,&Value1); + break; + case EFI_IFR_DEFAULT_OP: + Default =(EFI_IFR_DEFAULT*)opHeader; + if(((EFI_IFR_OP_HEADER*)(CtrlPtr + i + opHeader->Length))->OpCode == EFI_IFR_VALUE_OP){ + i += opHeader->Length; + opHeader = (EFI_IFR_OP_HEADER*)(CtrlPtr + i); + EvaluateReadWrite((CtrlPtr + i + opHeader->Length),controlInfo,&Value1); + } + break; + case EFI_IFR_END_OP: + if(ScopeCount) + { + ScopeCount--; + } + break; + } + if(opHeader->Scope) + { + ScopeCount++; + } + i += opHeader->Length ; + }while( ScopeCount); + } + if ( CondPtr == NULL ) + { + FinalCond = CheckControlAccess(CtrlAccess) ; + if(FinalCond != COND_NONE) + return FinalCond ; + goto DONE ; + } + + MemSet(&Value, sizeof(EFI_HII_VALUE),0); + MemSet(&condStack, 50, 0); + MemSet(&opcodeStack, 50, 0); + + controlInfoLength = sizeof(CONTROL_INFO); + tempControlInfo = (CONTROL_INFO*)EfiLibAllocateZeroPool(controlInfoLength); + if (NULL == tempControlInfo) //EIP-75384 Static code + return FinalCond; + + MemCopy(tempControlInfo, controlInfo, controlInfoLength); + + status = EvaluateExpression(tempControlInfo, &Value, &offset); + if(EFI_ERROR(status)) + { + offset = _SkipExpression(tempControlInfo->ControlConditionalPtr); + FinalCond = COND_NONE; + Value.Value.b = FALSE; + } + if(Value.Value.b) + { + if((((EFI_IFR_OP_HEADER*)CondPtr)->OpCode == EFI_IFR_SUPPRESS_IF_OP) || + (((EFI_IFR_OP_HEADER*)CondPtr)->OpCode == EFI_IFR_DISABLE_IF_OP)) + { + FinalCond = COND_SUPPRESS; + Inside = FALSE; + } + if(((EFI_IFR_OP_HEADER*)CondPtr)->OpCode == EFI_IFR_INCONSISTENT_IF_OP) + { + FinalCond = COND_INCONSISTENT; + Inside = FALSE; + } + if(((EFI_IFR_OP_HEADER*)CondPtr)->OpCode == EFI_IFR_NO_SUBMIT_IF_OP) + { + FinalCond = COND_NOSUBMIT; + Inside = FALSE; + } + } + + while( Inside ) + { + switch(*(CondPtr)) + { + case EFI_IFR_DISABLE_IF_OP: + case EFI_IFR_SUPPRESS_IF_OP: + Cond = COND_SUPPRESS; + break; + + case EFI_IFR_GRAY_OUT_IF_OP: + Cond = COND_GRAYOUT; + break; + + case EFI_IFR_INCONSISTENT_IF_OP: + Cond = COND_INCONSISTENT; + Inside = FALSE; + break; + case EFI_IFR_NO_SUBMIT_IF_OP: + Cond = COND_NOSUBMIT; + Inside = FALSE; + break; + case EFI_IFR_END_OP: + if(stackIndex) + { + condStack[--stackIndex] = 0; + opcodeStack[stackIndex] = 0; + } + offset = ((EFI_IFR_OP_HEADER*)CondPtr)->Length; + break; + case EFI_IFR_FORM_OP: + case EFI_IFR_FORM_MAP_OP: + offset += ((EFI_IFR_OP_HEADER*)CondPtr)->Length; + break; + default: + if(CondPtr == (UINT8*)controlInfo->ControlPtr) + { + Inside = FALSE; + }else if(((EFI_IFR_OP_HEADER*)CondPtr)->OpCode != EFI_IFR_END_OP) + { + //Skip this Control + inScope = 0; + do + { + if(((EFI_IFR_OP_HEADER*)((UINT8*)CondPtr + offset))->Scope) + inScope++; + offset += ((EFI_IFR_OP_HEADER*)((UINT8*)CondPtr + offset))->Length; + if(((EFI_IFR_OP_HEADER*)((UINT8*)CondPtr + offset))->OpCode == EFI_IFR_END_OP) + inScope--; + }while(inScope > 0); + } + break; + } + if(((EFI_IFR_OP_HEADER*)CondPtr)->Scope) + { + if(Value.Value.b) + { + condStack[stackIndex] = Cond; + }else + { + condStack[stackIndex] = COND_NONE; + } + opcodeStack[stackIndex++] = ((EFI_IFR_OP_HEADER*)CondPtr)->OpCode; + } + + tempControlInfo->ControlConditionalPtr = (VOID *)((UINT8 *)tempControlInfo->ControlConditionalPtr + offset); + CondPtr = (UINT8*)tempControlInfo->ControlConditionalPtr; + offset = 0; + Value.Value.b = 0; + status = EvaluateExpression(tempControlInfo, &Value, &offset); + if(EFI_ERROR(status)) + { + offset = _SkipExpression(tempControlInfo->ControlConditionalPtr); + FinalCond = COND_NONE; + Value.Value.b = FALSE; + } + } + + while(stackIndex--) + { + Cond = condStack[stackIndex]; + FinalCond = UpdateFinalCondition(FinalCond,Cond); + } + + // if CtrlAccess is CONTROL_ACCESS_DEFAULT then do not override VFR conditions + if(CONTROL_ACCESS_DEFAULT != CtrlAccess) + { + FinalCond = CheckControlAccess(CtrlAccess); + } + + if(tempControlInfo) + { + MemFreePointer(&tempControlInfo); + } + +DONE: + + if( (FinalCond == COND_NONE) && + (controlInfo->ControlFlags.ControlReadOnly == 1) && + IsReadOnlyGrayout() ) + { + FinalCond = COND_GRAYOUT ; + } + + FinalCond = OEMCheckControlCondition(FinalCond,controlInfo);//EIP 77256 : provide the Support to override the control Condition checking() generically. And provide customization to supress the controls with Security GUIDed opcode. + return FinalCond; +} + +// +//---------------------------------------------------------------------------- +// Procedure: CheckInconsistence +// +// Description: checks Inconsistence +// +// Parameter: PAGE_INFO +// +// Return value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN CheckInconsistence( PAGE_INFO *pPageInfo ) +{ + CONTROL_INFO *pControlInfo; + UINTN i; + + //Find out if there is inconsistent value in any of the controls + for(i=0; i < pPageInfo->PageControls.ControlCount; i++) + { + pControlInfo = (CONTROL_INFO*)((UINT8 *)(gControlInfo) + pPageInfo->PageControls.ControlList[i]); + //Check if there is a CONTROL_TYPE_MSGBOX in this page + if(pControlInfo->ControlType == CONTROL_TYPE_MSGBOX) + { + if(CheckControlCondition(pControlInfo) == COND_INCONSISTENT) + return DrawMessageBox(pControlInfo, STRING_TOKEN(STR_INCONSISTENT_MSG_TITLE), ((EFI_IFR_INCONSISTENT_IF*)pControlInfo->ControlConditionalPtr)->Error); + } + } + return FALSE; +} +// +//---------------------------------------------------------------------------- +// Procedure: CheckNoSubmitIf +// +// Description: checks NoSubmitIf +// +// Parameter: VOID +// +// Return value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN CheckNoSubmitIf( VOID) +{ + UINT32 index = 0; + + // Get the Forms + for ( index = 0; index < gPages->PageCount; index++ ) + { + PAGE_INFO *pageInfo = (PAGE_INFO*)((UINT8 *)gPages + gPages->PageList[index]); + UINTN control = 0; + + if(pageInfo->PageHandle == NULL) + { + continue; + } + // Get the Controls in each Page + for(control = 0; control < pageInfo->PageControls.ControlCount; control++) + { + CONTROL_INFO *pControlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if(pControlInfo->ControlType == NO_SUBMIT_IF) + { + if(CheckControlCondition(pControlInfo) == COND_NOSUBMIT) + return DrawMessageBox(pControlInfo, STRING_TOKEN(STR_NOSUBMITIF_MSG_TITLE), ((EFI_IFR_NO_SUBMIT_IF*)pControlInfo->ControlConditionalPtr)->Error); + } + } + } + return FALSE; +} +// +//---------------------------------------------------------------------------- +// Procedure: DrawMessageBox +// +// Description: Draw MessageBox +// +// Parameter: CONTROL_INFO, UINT16, EFI_STRING_ID +// +// Return value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN DrawMessageBox(CONTROL_INFO *pControlInfo, UINT16 Title, EFI_STRING_ID Error) +{ + EFI_STATUS Status; + MSGBOX_DATA *msgbox = NULL; + CONTROL_INFO dummy; + AMI_IFR_MSGBOX MsgData; + ACTION_DATA *action = gApp->Action; + + Status = gMsgBox.Create( &msgbox ); + if ( EFI_ERROR( Status ) ) + return TRUE; // Not able to draw msg box but thats ok dont allow a page switch + + MemSet( &dummy, sizeof(dummy), 0 ); + dummy.ControlHandle = INVALID_HANDLE; + + MsgData.Opcode = 0; + MsgData.Length = 0; + MsgData.Title = Title; + MsgData.TextHandle = pControlInfo->ControlHandle; + MsgData.Text = Error; + dummy.ControlPtr = (VOID *) (&MsgData); + dummy.ControlFlags.ControlVisible = TRUE; + + Status = gMsgBox.Initialize( msgbox, &dummy ); + if ( EFI_ERROR( Status ) ) + { + // Not able to draw msg box but thats ok dont allow a page switch + gMsgBox.Destroy( msgbox, TRUE );; + return TRUE; + } + + gMsgBox.SetType( msgbox, MSGBOX_TYPE_OK | MSGBOX_STYLE_LEFT ); + + do + { + if ( action->Input.Type != ACTION_TYPE_NULL ) + gAction.ClearAction( action ); + + gMsgBox.Draw( msgbox ); + + if ( gAction.GetAction( action ) != EFI_SUCCESS ) + continue; + + if(gMsgBox.HandleAction( msgbox, action ) == EFI_SUCCESS) + break; + }while(1); + + gMsgBox.Destroy( msgbox, TRUE ); + return TRUE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: CheckOneOfOptionSuppressIf +// +// Description: +// +// Parameter: CONTROL_INFO *ParentCtrlInfo, UINT8* CtrlCondPtr +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 CheckOneOfOptionSuppressIf(CONTROL_INFO *ParentCtrlInfo, UINT8* CtrlCondPtr, UINT8* CtrlPtr) +{ + CONTROL_INFO *newCtrlInfo = NULL; + UINT8 condition = COND_NONE; + + newCtrlInfo = (CONTROL_INFO*)EfiLibAllocateZeroPool(sizeof(CONTROL_INFO)); + if(newCtrlInfo == NULL) + { + goto DONE; + } + + newCtrlInfo->ControlHandle = ParentCtrlInfo->ControlHandle; + newCtrlInfo->ControlPageID = ParentCtrlInfo->ControlPageID; + newCtrlInfo->ControlKey = ParentCtrlInfo->ControlKey; + newCtrlInfo->ControlConditionalPtr = (VOID *)CtrlCondPtr; + newCtrlInfo->ControlPtr = (VOID *)CtrlPtr; + condition = CheckControlCondition(newCtrlInfo); + MemFreePointer(&newCtrlInfo); + +DONE: + + return condition; +} + +// +//---------------------------------------------------------------------------- +// Procedure: EvaluateControlDefault +// +// Description: +// +// Parameter: CONTROL_INFO *CtrlInfo +// +// Return value: UINT64 +//---------------------------------------------------------------------------- +// +UINT16 EvaluateControlDefault(CONTROL_INFO *CtrlInfo, UINT64 *Defaults) +{ + CONTROL_INFO *newCtrlInfo = NULL; + EFI_IFR_OP_HEADER *header = (EFI_IFR_OP_HEADER*)CtrlInfo->ControlPtr; + EFI_HII_VALUE value; + UINT16 size = 0; + UINT32 scope = 0; + UINTN i = 0; + UINTN offset = 0; + + newCtrlInfo = (CONTROL_INFO*)EfiLibAllocateZeroPool(sizeof(CONTROL_INFO)); + if(newCtrlInfo == NULL) + { + goto DONE; + } + + newCtrlInfo->ControlHandle = CtrlInfo->ControlHandle; + newCtrlInfo->ControlPageID = CtrlInfo->ControlPageID; + newCtrlInfo->ControlKey = CtrlInfo->ControlKey; + + while(header->OpCode != EFI_IFR_DEFAULT_OP) + { + i += header->Length; + header = (EFI_IFR_OP_HEADER*)((UINT8*)header + i); + } + + newCtrlInfo->ControlConditionalPtr = (VOID *)((UINT8 *)header + header->Length); + // Set End of Default Scope as ControlPtr + do + { + switch(header->OpCode) + { + case EFI_IFR_END_OP: + scope = scope? --scope : 0; + break; + default: + break; + } + scope = header->Scope? ++scope : scope; + header = (EFI_IFR_OP_HEADER*)((UINT8*)header + header->Length); + }while(scope > 0); + + newCtrlInfo->ControlPtr = (VOID *)header; + EvaluateExpression(newCtrlInfo, &value, &offset); + MemFreePointer(&newCtrlInfo); + + size = (UINT16)GetControlDataLength(CtrlInfo); + GetDefaultValue(value.Type, &(value.Value), &size, Defaults, (UINT8*)header);//EIP-Support Default in Orderlist + +DONE: + return size; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/EDK/MiniSetup/uefi2.1/CtrlCond.h b/EDK/MiniSetup/uefi2.1/CtrlCond.h new file mode 100644 index 0000000..32c51ce --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/CtrlCond.h @@ -0,0 +1,146 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (C)Copyright 2012, 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/Uefi2.1/CtrlCond.h $ +// +// $Author: Arunsb $ +// +// $Revision: 8 $ +// +// $Date: 10/18/12 6:04a $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/CtrlCond.h $ +// +// 8 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 5 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 7 2/01/12 4:59a Rajashakerg +// [TAG] EIP77256 +// [Category] Improvement +// [Description] Provide the Support to override the control Condition +// checking() generically. And provide customization to supress the +// controls with Security GUIDed opcode. +// [Files] AMITSE.sdl, CommonHelper.c, CtrlCond.c and CtrlCond.h +// +// 6 3/28/11 11:03p Madhans +// [TAG] EIP56414 +// [Category] Improvement +// [Description] TSE: Support for EFI_IFR_NO_SUBMIT_IF opcode +// [Files] Callback.c, FakeToken.c, AMITSEstr.uni, Parse.c, CtrlCond.c, +// CtrlCond.h, ctrlcond.h, ctrlcond.c +// +// 5 12/02/10 5:34p Madhans +// [TAG] - EIP 49559 +// [Category]- defect +// [Severity]- Mordarate +// [Symptom]- OneOption contols works ok if it stores the values in BYTE +// and Does not contain any suppressif for options. +// But it has issues in supporting UINT16, UINT32 and UINT64 storage. +// [Rootcause] - The Type is not checked for Storeage and issues with +// condition check for options. +// [Solution]- Fix done ctrlcond.c and uefi21wrapper.c +// [Files] - CtrlCond.h, ctrlcond.c and uefi21wrapper.c +// +// 4 4/16/10 5:13p Madhans +// Changes for Tse 2.02. Please see Changelog.log for more details. +// +// 3 2/19/10 8:50p Madhans +// +// 1 7/24/09 6:54p Presannar +// +// 1 1/09/09 2:38p Presannar +// UEFI 2.1 Hii Related Code - Initial Drop +// +// 6 9/17/08 7:44p Madhans +// For Boot only Driver file split changes. +// +// 5 2/14/06 1:02p Arunkumars +// 1. Added Inconsistentif feature +// 2. We publish two events before and after asking for password (see +// postmgt.c and minisetup.h) +// +// 4 7/19/05 3:40p Jerryp +// Reduced number of parameters. +// Code spacing cleanup +// +// 3 5/16/05 5:09p Franklynd +// 1-Support for multivariable (varstore, varstore_select, +// varstore_select_pair) +// 2-Support of optimal and failsafe defaults. +// 3- support of refresh of controls using their flag information. +// 4- added ORDERED_LIST control/ +// +// 2 2/24/05 5:14p Franklynd +// 1- adding number of control after a label in control_info structure. +// 2- adding check of access flags in control (password) +// 3- color schema code moved to styles area. +// +// 1 2/16/05 7:09p Franklynd +// +//************************************************************************* +// +// +// Name: CtrlCond.h +// +// Description: Header File +// +// +//************************************************************************* + +//--------------------------------------------------------------------------- +#include "minisetup.h" +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +#define COND_NONE 0x0 +#define COND_SUPPRESS 0x1 +#define COND_HIDDEN 0x2 +#define COND_GRAYOUT 0x3 +#define COND_INCONSISTENT 0x4 +#define COND_NOSUBMIT 0x5 +//--------------------------------------------------------------------------- + + +// functions +//UINT8 CheckControlCondition(UINT32 ControlAccess, UINT8 *CtrlPtr, UINT32 CtrlVar, UINT32 CtrlVar2, UINT8 *CondPtr); +UINT8 CheckControlCondition( CONTROL_INFO *controlInfo ); +BOOLEAN CheckInconsistence( PAGE_INFO *pPageInfo ); +UINT8 CheckOneOfOptionSuppressIf(CONTROL_INFO *ParentCtrlInfo, UINT8* CtrlCondPtr, UINT8* CtrlPtr); +//Start EIP : NO_SUBMIT_IF +BOOLEAN CheckNoSubmitIf( VOID ); +BOOLEAN DrawMessageBox(CONTROL_INFO *pControlInfo, UINT16 Title, EFI_STRING_ID Error); +UINT8 OEMCheckControlCondition(UINT8 FinalCond, CONTROL_INFO *controlInfo);//EIP 77256 : Provide the Support to override the control Condition checking() generically. And provide customization to supress the controls with Security GUIDed opcode. + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/EDK/MiniSetup/uefi2.1/Expression.c b/EDK/MiniSetup/uefi2.1/Expression.c new file mode 100644 index 0000000..f45de77 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/Expression.c @@ -0,0 +1,2861 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (C)Copyright 2011, 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/Uefi2.1/Expression.c $ +// +// $Author: Arunsb $ +// +// $Revision: 18 $ +// +// $Date: 6/10/13 12:06p $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/Expression.c $ +// +// 18 6/10/13 12:06p Arunsb +// EIP122907. Support for pushthis condition in inconsistent and +// nosubmitif +// +// 17 4/17/13 12:29p Arunsb +// [TAG] EIP111063 +// [Category] Improvement +// [Description] Support for EFI_IFR_QUESTION_REF3_2 and +// EFI_IFR_QUESTION_REF3_3 opcodes +// [Files] Expression.c +// +// 16 4/02/13 8:05a Arunsb +// [TAG] EIP113919, EIP114842 +// [Category] Improvement +// [Description] Provide support for EFI_IFR_WRITE, EFI_IFR_READ, +// EFI_IFR_GET, EFI_IFR_SET and EFI_IFR_MAP_OP. +// [Files] Setupdata.h, ctrlcond.c, expression.c, hii.c and parse.c +// +// 15 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 12 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 14 5/29/12 4:44a Arunsb +// [TAG] EIP91109 +// [Category] Improvement +// [Description] Sync the Aptio IV source for AptioV +// +// 13 12/01/11 1:35a Premkumara +// [TAG] EIP73236 +// [Category] Improvement +// [Description] Large amounts of allocated memory are not freed +// [Files] Expression.c, PopupEdit.c, Popup.c, MessageBox.c, Menu.c, +// Memo.c, +// +// 12 11/28/11 2:08a Premkumara +// [TAG] EIP75384 +// [Category] Improvement +// [Description] Suppress the warnings from static code analyzer +// [Files] UefiWapper.c, Hii.c, Expression.c, CtrlCond.c, PopupSel.c, +// Minisetupext.c, Menu.c, Date.c, Ezport\Stylecommon.c, +// EzportPlus\StyleCommon.c, +// +// 11 6/20/11 10:36a Rajashakerg +// [TAG] EIP56355 +// [Category] Improvement +// [Description] TSE: Support for EFI_IFR_VERSION opcode +// [Files] Expression.c +// +// 10 3/18/11 9:41a Rajashakerg +// [TAG] EIP56355 +// [Category] Improvement +// [Description] TSE: Support for EFI_IFR_VERSION opcode +// [Files] Expression.c +// +// 9 2/03/11 8:19p Madhans +// [TAG] - EIP 50956 +// [Category]- defect +// [Severity]- Mordarate +// [Symptom]- If we leave the Setup page for 2 or more days. The system +// may hang/Crash. +// [Rootcause] - Memory leaks +// [Solution]- Memeory freed. +// [Files] - ctrlcond.c, memo.c and expression.c +// +// 8 12/02/10 2:38p Madhans +// [TAG] - EIP 48169 +// [Category]- Enhancement +// [Severity]- Mordarate +// [Symptom]- Code Cleanup and Compiler Warning need to resolved. +// [Rootcause] Warnings reported when we build AMI higher Warning level. +// [Solution]- 1. Fix the warnings and do the code cleanup. +// 2. Introduce proper checks. +// 3. change the popupSel.c to not change the Option/variable +// cache to default or first option +// when the variable cache is not matching with any of +// option. +// [Files] - commonoem.c bbs.c boot.c hiistring.c resource.c +// popuppassword.c popupsel.c +// expression.c hii.c parse.c +// +// 8 8/18/10 5:58p Mallikarjunanv +// EIP-42300: Handled dataWidth to solve the hanging issue with respect to +// password updates +// +// 7 7/07/10 7:45p Madhans +// Changes to Support Adding Conditions to Suppress or Grayout the Special +// controls. +// +// 6 3/11/10 5:41p Madhans +// Coding Standards Update +// +//************************************************************************* +// +// +// Name: Expression.C +// +// Description: Expression evaluation. +// +// +//************************************************************************* + +//--------------------------------------------------------------------------- +#include "Minisetup.h" +#include "TseUefiHii.h" + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// +// In Aptio UnicodeCollation2 protocol is supported in the same file as +// UnicodeCollation Protocol depending on EFI_SPECIFICATION_VERSION +// +#ifndef TSE_FOR_APTIO_4_50 +#include EFI_PROTOCOL_DEFINITION(UnicodeCollation2) +#else +#if TSE_USE_EDK_LIBRARY +#include EFI_PROTOCOL_DEFINITION(UnicodeCollation2) +#else +#include EFI_PROTOCOL_DEFINITION(UnicodeCollation) +#endif +#endif +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +#define EXPRESSION_STACK_SIZE_INCREMENT 100 +#define NewString(a, b) HiiAddString(b, a) +#define GetToken(a,b) HiiGetString(b, a) +//--------------------------------------------------------------------------- + +// +// Global stack used to evaluate boolean expresions +// +EFI_HII_VALUE *mOpCodeScopeStack = NULL; +EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL; +EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL; + +EFI_HII_VALUE *mExpressionEvaluationStack = NULL; +EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL; +EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL; + +CHAR16 *gEmptyString = L""; +VOID *gInconsistCondPtr = NULL; +// +// Unicode collation protocol interface +// +EFI_UNICODE_COLLATION2_PROTOCOL *mUnicodeCollation = NULL; + +extern EFI_STATUS GetStringFromDevPath(EFI_DEVICE_PATH_PROTOCOL *DevPath, CHAR16 **DevPathStr); +extern EFI_STATUS GetDevPathFromHandle(EFI_HII_HANDLE HiiHandle, EFI_DEVICE_PATH_PROTOCOL **DevicePath); + +// +//---------------------------------------------------------------------------- +// Procedure: GrowStack +// +// Description: Grow size of the stack +// +// Parameter: Stack - On input: old stack; On output: new stack +// StackPtr - On input: old stack pointer; On output: new stack pointer +// StackPtr - On input: old stack end; On output: new stack end +// +// Return value: EFI_SUCCESS - Grow stack success. +// EFI_OUT_OF_RESOURCES - No enough memory for stack space. +//---------------------------------------------------------------------------- +// + +STATIC +EFI_STATUS +GrowStack ( + IN OUT EFI_HII_VALUE **Stack, + IN OUT EFI_HII_VALUE **StackPtr, + IN OUT EFI_HII_VALUE **StackEnd + ) +{ + UINTN Size; + EFI_HII_VALUE *NewStack; + + Size = EXPRESSION_STACK_SIZE_INCREMENT; + if (*StackPtr != NULL) { + Size = Size + (*StackEnd - *Stack); + } + + NewStack = EfiLibAllocatePool (Size * sizeof (EFI_HII_VALUE)); + if (NewStack == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (*StackPtr != NULL) { + // + // Copy from Old Stack to the New Stack + // + EfiCopyMem ( + NewStack, + *Stack, + (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE) + ); + + // + // Free The Old Stack + // + gBS->FreePool (*Stack); + } + + // + // Make the Stack pointer point to the old data in the new stack + // + *StackPtr = NewStack + (*StackPtr - *Stack); + *Stack = NewStack; + *StackEnd = NewStack + Size; + + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// Procedure: PushStack +// +// Description: Push an element onto the Boolean Stack +// +// Parameter: Stack - On input: old stack; On output: new stack +// StackPtr - On input: old stack pointer; On output: new stack pointer +// StackPtr - On input: old stack end; On output: new stack end +// Data - Data to push. +// +// Return value: EFI_SUCCESS - Push stack success. +//---------------------------------------------------------------------------- +// +EFI_STATUS +PushStack ( + IN OUT EFI_HII_VALUE **Stack, + IN OUT EFI_HII_VALUE **StackPtr, + IN OUT EFI_HII_VALUE **StackEnd, + IN EFI_HII_VALUE *Data + ) +{ + EFI_STATUS Status; + + // + // Check for a stack overflow condition + // + if (*StackPtr >= *StackEnd) { + // + // Grow the stack + // + Status = GrowStack (Stack, StackPtr, StackEnd); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Push the item onto the stack + // + EfiCopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE)); + *StackPtr = *StackPtr + 1; + + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// Procedure: PopStack +// +// Description: Pop an element from the stack. +// +// Parameter: Stack - On input: old stack; On output: new stack +// StackPtr - On input: old stack pointer; On output: new stack pointer +// StackPtr - On input: old stack end; On output: new stack end +// Data - Data to pop. +// +// Return value: EFI_SUCCESS - The value was popped onto the stack. +// EFI_ACCESS_DENIED - The pop operation underflowed the stack +//---------------------------------------------------------------------------- +// +EFI_STATUS +PopStack ( + IN OUT EFI_HII_VALUE **Stack, + IN OUT EFI_HII_VALUE **StackPtr, + IN OUT EFI_HII_VALUE **StackEnd, + OUT EFI_HII_VALUE *Data + ) +{ + // + // Check for a stack underflow condition + // + if (*StackPtr == *Stack) { + return EFI_ACCESS_DENIED; + } + + // + // Pop the item off the stack + // + *StackPtr = *StackPtr - 1; + EfiCopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE)); + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// Procedure: ResetScopeStack +// +// Description: Reset stack pointer to begin of the stack. +// +// Parameter: None. +// +// Return value: None. +//---------------------------------------------------------------------------- +// +VOID +ResetScopeStack ( + VOID + ) +{ + mOpCodeScopeStackPointer = mOpCodeScopeStack; +} + +// +//---------------------------------------------------------------------------- +// Procedure: PushScope +// +// Description: Push an Operand onto the Stack +// +// Parameter: Operand to push. +// +// Return value: EFI_SUCCESS - The value was pushed onto the stack. +// EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack. +// +//---------------------------------------------------------------------------- +// +EFI_STATUS +PushScope ( + IN UINT8 Operand + ) +{ + EFI_HII_VALUE Data; + + Data.Type = EFI_IFR_TYPE_NUM_SIZE_8; + Data.Value.u8 = Operand; + + return PushStack ( + &mOpCodeScopeStack, + &mOpCodeScopeStackPointer, + &mOpCodeScopeStackEnd, + &Data + ); +} + +// +//---------------------------------------------------------------------------- +// Procedure: PopScope +// +// Description: Pop an Operand from the Stack +// +// Parameter: Operand to pop. +// +// Return value: EFI_SUCCESS - The value was pushed onto the stack. +// EFI_OUT_OF_RESOURCES - There is not enough system memory to +// grow the stack. +// +//---------------------------------------------------------------------------- +// +EFI_STATUS +PopScope ( + OUT UINT8 *Operand + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Data; + + Status = PopStack ( + &mOpCodeScopeStack, + &mOpCodeScopeStackPointer, + &mOpCodeScopeStackEnd, + &Data + ); + + *Operand = Data.Value.u8; + + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: ResetExpressionStack +// +// Description: Reset stack pointer to begin of the stack. +// +// Parameter: None. +// +// Return value: None +// +//---------------------------------------------------------------------------- +// +VOID +ResetExpressionStack ( + VOID + ) +{ + mExpressionEvaluationStackPointer = mExpressionEvaluationStack; +} + +// +//---------------------------------------------------------------------------- +// Procedure: PushExpression +// +// Description: Push an Expression value onto the Stack +// +// Parameter: Value - Expression value to push. +// +// Return value: EFI_SUCCESS - The value was pushed onto the stack. +// EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack. +// +//---------------------------------------------------------------------------- +// +EFI_STATUS +PushExpression ( + IN EFI_HII_VALUE *Value + ) +{ + return PushStack ( + &mExpressionEvaluationStack, + &mExpressionEvaluationStackPointer, + &mExpressionEvaluationStackEnd, + Value + ); +} + +// +//---------------------------------------------------------------------------- +// Procedure: PopExpression +// +// Description: Pop an Expression value from the Stack +// +// Parameter: Value - Expression value to pop. +// +// Return value: EFI_SUCCESS - The value was popped onto the stack. +// EFI_OUT_OF_RESOURCES - The pop operation underflowed the stack +// +//---------------------------------------------------------------------------- +// +EFI_STATUS +PopExpression ( + OUT EFI_HII_VALUE *Value + ) +{ + return PopStack ( + &mExpressionEvaluationStack, + &mExpressionEvaluationStackPointer, + &mExpressionEvaluationStackEnd, + Value + ); +} + +/* +FORM_BROWSER_FORM * +IdToForm ( + IN FORM_BROWSER_FORMSET *FormSet, + IN UINT16 FormId +) +/*++ + +Routine Description: + Get Form given its FormId. + +Arguments: + FormSet - The formset which contains this form. + FormId - Id of this form. + +Returns: + Pointer - The form. + NULL - Specified Form is not found in the formset. + +--* / +{ + EFI_LIST_ENTRY *Link; + FORM_BROWSER_FORM *Form; + + Link = GetFirstNode (&FormSet->FormListHead); + while (!IsNull (&FormSet->FormListHead, Link)) { + Form = FORM_BROWSER_FORM_FROM_LINK (Link); + + if (Form->FormId == FormId) { + return Form; + } + + Link = GetNextNode (&FormSet->FormListHead, Link); + } + + return NULL; +} + +FORM_BROWSER_STATEMENT * +IdToQuestion2 ( + IN FORM_BROWSER_FORM *Form, + IN UINT16 QuestionId + ) +/*++ + +Routine Description: + Search a Question in Form scope using its QuestionId. + +Arguments: + Form - The form which contains this Question. + QuestionId - Id of this Question. + +Returns: + Pointer - The Question. + NULL - Specified Question not found in the form. + +--* / +{ + EFI_LIST_ENTRY *Link; + FORM_BROWSER_STATEMENT *Question; + + if (QuestionId == 0) { + // + // The value of zero is reserved + // + return NULL; + } + + Link = GetFirstNode (&Form->StatementListHead); + while (!IsNull (&Form->StatementListHead, Link)) { + Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link); + + if (Question->QuestionId == QuestionId) { + return Question; + } + + Link = GetNextNode (&Form->StatementListHead, Link); + } + + return NULL; +} + +FORM_BROWSER_STATEMENT * +IdToQuestion ( + IN FORM_BROWSER_FORMSET *FormSet, + IN FORM_BROWSER_FORM *Form, + IN UINT16 QuestionId + ) +/*++ + +Routine Description: + Search a Question in Formset scope using its QuestionId. + +Arguments: + FormSet - The formset which contains this form. + Form - The form which contains this Question. + QuestionId - Id of this Question. + +Returns: + Pointer - The Question. + NULL - Specified Question not found in the form. + +--* / +{ + EFI_LIST_ENTRY *Link; + FORM_BROWSER_STATEMENT *Question; + + // + // Search in the form scope first + // + Question = IdToQuestion2 (Form, QuestionId); + if (Question != NULL) { + return Question; + } + + // + // Search in the formset scope + // + Link = GetFirstNode (&FormSet->FormListHead); + while (!IsNull (&FormSet->FormListHead, Link)) { + Form = FORM_BROWSER_FORM_FROM_LINK (Link); + + Question = IdToQuestion2 (Form, QuestionId); + if (Question != NULL) { + return Question; + } + + Link = GetNextNode (&FormSet->FormListHead, Link); + } + + return NULL; +} + +FORM_EXPRESSION * +RuleIdToExpression ( + IN FORM_BROWSER_FORM *Form, + IN UINT8 RuleId + ) +/*++ + +Routine Description: + Get Expression given its RuleId. + +Arguments: + Form - The form which contains this Expression. + RuleId - Id of this Expression. + +Returns: + Pointer - The Expression. + NULL - Specified Expression not found in the form. + +--* / +{ + EFI_LIST_ENTRY *Link; + FORM_EXPRESSION *Expression; + + Link = GetFirstNode (&Form->ExpressionListHead); + while (!IsNull (&Form->ExpressionListHead, Link)) { + Expression = FORM_EXPRESSION_FROM_LINK (Link); + + if (Expression->Type == EFI_HII_EXPRESSION_RULE && Expression->RuleId == RuleId) { + return Expression; + } + + Link = GetNextNode (&Form->ExpressionListHead, Link); + } + + return NULL; +} +*/ + +// +//---------------------------------------------------------------------------- +// Procedure: InitializeUnicodeCollationProtocol +// +// Description: Locate the Unicode Collation Protocol interface for later use. +// +// Parameter: None +// +// Return value: EFI_SUCCESS - Protocol interface initialize success. +// Other - Protocol interface initialize failed. +// +//---------------------------------------------------------------------------- +// + +EFI_STATUS +InitializeUnicodeCollationProtocol ( + VOID + ) +{ + EFI_STATUS Status; + + if (mUnicodeCollation != NULL) { + return EFI_SUCCESS; + } + + // + // BUGBUG: Proper impelmentation is to locate all Unicode Collation Protocol + // instances first and then select one which support English language. + // Current implementation just pick the first instance. + // + Status = gBS->LocateProtocol ( + &gEfiUnicodeCollation2ProtocolGuid, + NULL, + &mUnicodeCollation + ); + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfrStrToUpper +// +// Description:function to conver the lower case string to upper +// +// Parameter: +// +// Return value: None +// +//---------------------------------------------------------------------------- +// +VOID +IfrStrToUpper ( + CHAR16 *String + ) +{ + while (*String != 0) { + if ((*String >= 'a') && (*String <= 'z')) { + *String = (*String) & ((UINT16) ~0x20); + } + String++; + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfrToString +// +// Description: Evaluate opcode EFI_IFR_TO_STRING. +// +// Parameter: FormSet - Formset which contains this opcode. +// Format - String format in EFI_IFR_TO_STRING. +// Result - Evaluation result for this opcode. +// +// Return value: EFI_SUCCESS - Opcode evaluation success. +// Other - Opcode evaluation failed. +//---------------------------------------------------------------------------- +// +EFI_STATUS +IfrToString ( + IN EFI_HII_HANDLE *HiiHandle, + IN UINT8 Format, + OUT EFI_HII_VALUE *Result + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Value; + CHAR16 *String; + CHAR16 *PrintFormat; + CHAR16 Buffer[CHARACTER_NUMBER_FOR_VALUE]; + UINTN BufferSize; + + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + return Status; + } + + switch (Value.Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + case EFI_IFR_TYPE_NUM_SIZE_16: + case EFI_IFR_TYPE_NUM_SIZE_32: + case EFI_IFR_TYPE_NUM_SIZE_64: + BufferSize = CHARACTER_NUMBER_FOR_VALUE * sizeof (CHAR16); + switch (Format) { + case EFI_IFR_STRING_UNSIGNED_DEC: + case EFI_IFR_STRING_SIGNED_DEC: + PrintFormat = L"%ld"; + break; + + case EFI_IFR_STRING_LOWERCASE_HEX: + PrintFormat = L"%lx"; + break; + + case EFI_IFR_STRING_UPPERCASE_HEX: + PrintFormat = L"%lX"; + break; + + default: + return EFI_UNSUPPORTED; + } + SPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64); + String = Buffer; + break; + + case EFI_IFR_TYPE_STRING: + EfiCopyMem (Result, &Value, sizeof (EFI_HII_VALUE)); + return EFI_SUCCESS; + + case EFI_IFR_TYPE_BOOLEAN: + String = (Value.Value.b) ? L"True" : L"False"; + break; + + default: + return EFI_UNSUPPORTED; + } + + Result->Type = EFI_IFR_TYPE_STRING; + Result->Value.string = NewString (String, HiiHandle); + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfrToUint +// +// Description: Evaluate opcode EFI_IFR_TO_UINT. +// +// Parameter: FormSet - Formset which contains this opcode. +// Result - Evaluation result for this opcode. +// +// Return value: EFI_SUCCESS - Opcode evaluation success. +// Other - Opcode evaluation failed. +//---------------------------------------------------------------------------- +// +EFI_STATUS +IfrToUint ( + IN EFI_HII_HANDLE *HiiHandle, + OUT EFI_HII_VALUE *Result + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Value; + CHAR16 *String; + CHAR16 *StringPtr; + UINTN BufferSize; + + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Value.Type >= EFI_IFR_TYPE_OTHER) { + return EFI_UNSUPPORTED; + } + + Status = EFI_SUCCESS; + if (Value.Type == EFI_IFR_TYPE_STRING) { + String = GetToken (Value.Value.string, HiiHandle); + if (String == NULL) { + return EFI_NOT_FOUND; + } + + IfrStrToUpper (String); + StringPtr = EfiStrStr (String, L"0X"); + if (StringPtr != NULL) { + // + // Hex string + // + BufferSize = sizeof (UINT64); + Status = HexStringToBuf ((UINT8 *) &Result->Value.u64, &BufferSize, StringPtr + 2, NULL); + } else { + // + // BUGBUG: Need handle decimal string + // + } + gBS->FreePool (String); + } else { + EfiCopyMem (Result, &Value, sizeof (EFI_HII_VALUE)); + } + + Result->Type = EFI_IFR_TYPE_NUM_SIZE_64; + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfrCatenate +// +// Description: Evaluate opcode EFI_IFR_TO_UINT. +// +// Parameter: FormSet - Formset which contains this opcode. +// Result - Evaluation result for this opcode. +// +// Return value: EFI_SUCCESS - Opcode evaluation success. +// Other - Opcode evaluation failed. +//---------------------------------------------------------------------------- +// +EFI_STATUS +IfrCatenate ( + IN EFI_HII_HANDLE *HiiHandle, + OUT EFI_HII_VALUE *Result + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Value; + CHAR16 *String[2]; + UINTN Index; + CHAR16 *StringPtr; + + // + // String[0] - The second string + // String[1] - The first string + // + String[0] = NULL; + String[1] = NULL; + StringPtr = NULL; + Status = EFI_SUCCESS; + + for (Index = 0; Index < 2; Index++) { + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + goto Done; + } + + if (Value.Type != EFI_IFR_TYPE_STRING) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + String[Index] = GetToken (Value.Value.string, HiiHandle); + if (String== NULL) { + Status = EFI_NOT_FOUND; + goto Done; + } + } + + StringPtr= EfiLibAllocatePool (EfiStrSize (String[1]) + EfiStrSize (String[0])); + ASSERT (StringPtr != NULL); + EfiStrCpy (StringPtr, String[1]); + EfiStrCat (StringPtr, String[0]); + + Result->Type = EFI_IFR_TYPE_STRING; + Result->Value.string = NewString (StringPtr, HiiHandle); + +Done: + EfiLibSafeFreePool (String[0]); + EfiLibSafeFreePool (String[1]); + EfiLibSafeFreePool (StringPtr); + + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfrMatch +// +// Description: Evaluate opcode EFI_IFR_MATCH. +// +// Parameter: FormSet - Formset which contains this opcode. +// Result - Evaluation result for this opcode. +// +// Return value: EFI_SUCCESS - Opcode evaluation success. +// Other - Opcode evaluation failed. +//---------------------------------------------------------------------------- +// +EFI_STATUS +IfrMatch ( + IN EFI_HII_HANDLE *HiiHandle, + OUT EFI_HII_VALUE *Result + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Value; + CHAR16 *String[2]; + UINTN Index; + + // + // String[0] - The string to search + // String[1] - pattern + // + String[0] = NULL; + String[1] = NULL; + Status = EFI_SUCCESS; + for (Index = 0; Index < 2; Index++) { + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + goto Done; + } + + if (Value.Type != EFI_IFR_TYPE_STRING) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + String[Index] = GetToken (Value.Value.string, HiiHandle); + if (String== NULL) { + Status = EFI_NOT_FOUND; + goto Done; + } + } + + Result->Type = EFI_IFR_TYPE_BOOLEAN; + Result->Value.b = mUnicodeCollation->MetaiMatch (mUnicodeCollation, String[0], String[1]); + +Done: + EfiLibSafeFreePool (String[0]); + EfiLibSafeFreePool (String[1]); + + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfrFind +// +// Description: Evaluate opcode EFI_IFR_FIND. +// +// Parameter: FormSet - Formset which contains this opcode. +// Format - Case sensitive or insensitive. +// Result - Evaluation result for this opcode. +// +// Return value: EFI_SUCCESS - Opcode evaluation success. +// Other - Opcode evaluation failed. +//---------------------------------------------------------------------------- +// +EFI_STATUS +IfrFind ( + IN EFI_HII_HANDLE *HiiHandle, + IN UINT8 Format, + OUT EFI_HII_VALUE *Result + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Value; + CHAR16 *String[2]; + UINTN Base; + CHAR16 *StringPtr; + UINTN Index; + + if (Format > EFI_IFR_FF_CASE_INSENSITIVE) { + return EFI_UNSUPPORTED; + } + + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + return Status; + } + if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { + return EFI_UNSUPPORTED; + } + Base = (UINTN) Value.Value.u64; + + // + // String[0] - sub-string + // String[1] - The string to search + // + String[0] = NULL; + String[1] = NULL; + for (Index = 0; Index < 2; Index++) { + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + goto Done; + } + + if (Value.Type != EFI_IFR_TYPE_STRING) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + String[Index] = GetToken (Value.Value.string, HiiHandle); + if (String== NULL) { + Status = EFI_NOT_FOUND; + goto Done; + } + + if (Format == EFI_IFR_FF_CASE_INSENSITIVE) { + // + // Case insensitive, convert both string to upper case + // + IfrStrToUpper (String[Index]); + } + } + + Result->Type = EFI_IFR_TYPE_NUM_SIZE_64; + if (Base >= EfiStrLen (String[1])) { + Result->Value.u64 = 0xFFFFFFFFFFFFFFFF; + } else { + StringPtr = EfiStrStr (String[1] + Base, String[0]); + Result->Value.u64 = (StringPtr == NULL) ? 0xFFFFFFFFFFFFFFFF : (StringPtr - String[1]); + } + +Done: + EfiLibSafeFreePool (String[0]); + EfiLibSafeFreePool (String[1]); + + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfrMid +// +// Description: Evaluate opcode EFI_IFR_MID. +// +// Parameter: FormSet - Formset which contains this opcode. +// Result - Evaluation result for this opcode. +// +// Return value: EFI_SUCCESS - Opcode evaluation success. +// Other - Opcode evaluation failed. +//---------------------------------------------------------------------------- +// +EFI_STATUS +IfrMid ( + IN EFI_HII_HANDLE *HiiHandle, + OUT EFI_HII_VALUE *Result + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Value; + CHAR16 *String; + UINTN Base; + UINTN Length; + CHAR16 *SubString; + + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + return Status; + } + if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { + return EFI_UNSUPPORTED; + } + Length = (UINTN) Value.Value.u64; + + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + return Status; + } + if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { + return EFI_UNSUPPORTED; + } + Base = (UINTN) Value.Value.u64; + + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + return Status; + } + if (Value.Type != EFI_IFR_TYPE_STRING) { + return EFI_UNSUPPORTED; + } + String = GetToken (Value.Value.string, HiiHandle); + if (String == NULL) { + return EFI_NOT_FOUND; + } + + if (Length == 0 || Base >= EfiStrLen (String)) { + SubString = gEmptyString; + } else { + SubString = String + Base; + if ((Base + Length) < EfiStrLen (String)) { + SubString[Length] = L'\0'; + } + } + + Result->Type = EFI_IFR_TYPE_STRING; + Result->Value.string = NewString (SubString, HiiHandle); + + gBS->FreePool (String); + + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfrToken +// +// Description: Evaluate opcode EFI_IFR_TOKEN. +// +// Parameter: FormSet - Formset which contains this opcode. +// Result - Evaluation result for this opcode. +// +// Return value: EFI_SUCCESS - Opcode evaluation success. +// Other - Opcode evaluation failed. +//---------------------------------------------------------------------------- +// +EFI_STATUS +IfrToken ( + IN EFI_HII_HANDLE *HiiHandle, + OUT EFI_HII_VALUE *Result + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Value; + CHAR16 *String[2]; + UINTN Count; + CHAR16 *Delimiter; + CHAR16 *SubString; + CHAR16 *StringPtr; + UINTN Index; + + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + return Status; + } + if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { + return EFI_UNSUPPORTED; + } + Count = (UINTN) Value.Value.u64; + + // + // String[0] - Delimiter + // String[1] - The string to search + // + String[0] = NULL; + String[1] = NULL; + for (Index = 0; Index < 2; Index++) { + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + goto Done; + } + + if (Value.Type != EFI_IFR_TYPE_STRING) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + String[Index] = GetToken (Value.Value.string, HiiHandle); + if (String== NULL) { + Status = EFI_NOT_FOUND; + goto Done; + } + } + + Delimiter = String[0]; + SubString = String[1]; + while (Count > 0) { + SubString = EfiStrStr (SubString, Delimiter); + if (SubString != NULL) { + // + // Skip over the delimiter + // + SubString = SubString + EfiStrLen (Delimiter); + } else { + break; + } + Count--; + } + + if (SubString == NULL) { + // + // nth delimited sub-string not found, push an empty string + // + SubString = gEmptyString; + } else { + // + // Put a NULL terminator for nth delimited sub-string + // + StringPtr = EfiStrStr (SubString, Delimiter); + if (StringPtr != NULL) { + *StringPtr = L'\0'; + } + } + + Result->Type = EFI_IFR_TYPE_STRING; + Result->Value.string = NewString (SubString, HiiHandle); + +Done: + EfiLibSafeFreePool (String[0]); + EfiLibSafeFreePool (String[1]); + + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfrSpan +// +// Description: Evaluate opcode EFI_IFR_SPAN. +// +// Parameter: FormSet - Formset which contains this opcode. +// Flags - FIRST_MATCHING or FIRST_NON_MATCHING. +// Result - Evaluation result for this opcode. +// +// Return value: EFI_SUCCESS - Opcode evaluation success. +// Other - Opcode evaluation failed. +//---------------------------------------------------------------------------- +// +EFI_STATUS +IfrSpan ( + IN EFI_HII_HANDLE *HiiHandle, + IN UINT8 Flags, + OUT EFI_HII_VALUE *Result + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Value; + CHAR16 *String[2]; + CHAR16 *Charset; + UINTN Base; + UINTN Index; + CHAR16 *StringPtr; + BOOLEAN Found; + + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + return Status; + } + if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { + return EFI_UNSUPPORTED; + } + Base = (UINTN) Value.Value.u64; + + // + // String[0] - Charset + // String[1] - The string to search + // + String[0] = NULL; + String[1] = NULL; + for (Index = 0; Index < 2; Index++) { + Status = PopExpression (&Value); + if (EFI_ERROR (Status)) { + goto Done; + } + + if (Value.Type != EFI_IFR_TYPE_STRING) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + String[Index] = GetToken (Value.Value.string, HiiHandle); + if (String== NULL) { + Status = EFI_NOT_FOUND; + goto Done; + } + } + + if (Base >= EfiStrLen (String[1])) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + Found = FALSE; + StringPtr = String[1] + Base; + Charset = String[0]; + while (*StringPtr != 0 && !Found) { + Index = 0; + while (Charset[Index] != 0) { + if (*StringPtr >= Charset[Index] && *StringPtr <= Charset[Index + 1]) { + if (Flags == EFI_IFR_FLAGS_FIRST_MATCHING) { + Found = TRUE; + break; + } + } else { + if (Flags == EFI_IFR_FLAGS_FIRST_NON_MATCHING) { + Found = TRUE; + break; + } + } + // + // Skip characters pair representing low-end of a range and high-end of a range + // + Index += 2; + } + + if (!Found) { + StringPtr++; + } + } + + Result->Type = EFI_IFR_TYPE_NUM_SIZE_64; + Result->Value.u64 = StringPtr - String[1]; + +Done: + EfiLibSafeFreePool (String[0]); + EfiLibSafeFreePool (String[1]); + + return Status; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: ExtendValueToU64 +// +// Description: Zero extend integer/boolean/date/time to UINT64 for comparing. +// +// Parameter: Value - HII Value to be converted. +// +// Return value: None. +//---------------------------------------------------------------------------- +// +VOID +ExtendValueToU64 ( + IN EFI_HII_VALUE *Value + ) +{ + UINT64 Temp; + + Temp = 0; + switch (Value->Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + Temp = Value->Value.u8; + break; + + case EFI_IFR_TYPE_NUM_SIZE_16: + Temp = Value->Value.u16; + break; + + case EFI_IFR_TYPE_NUM_SIZE_32: + Temp = Value->Value.u32; + break; + + case EFI_IFR_TYPE_BOOLEAN: + Temp = Value->Value.b; + break; + + case EFI_IFR_TYPE_TIME: + Temp = Value->Value.u32 & 0xffffff; + break; + + case EFI_IFR_TYPE_DATE: + Temp = Value->Value.u32; + break; + + default: + return; + } + + Value->Value.u64 = Temp; +} + +// +//---------------------------------------------------------------------------- +// Procedure: CompareHiiValue +// +// Description: Compare two Hii Value +// +// Parameter: Value1 - Expression value to compare on left-hand +// Value2 - Expression value to compare on right-hand +// HiiHandle - Only required for string compare +// +// Return value: EFI_INVALID_PARAMETER - Could not perform comparation on two values +// 0 - Two operators equeal +// < 0 - Value1 is greater than Value2 +// > 0 - Value1 is less than Value2 +//---------------------------------------------------------------------------- +// +INTN +CompareHiiValue ( + IN EFI_HII_VALUE *Value1, + IN EFI_HII_VALUE *Value2, + IN EFI_HII_HANDLE HiiHandle OPTIONAL + ) +{ + INTN Result; + INT64 Temp64; + CHAR16 *Str1; + CHAR16 *Str2; + + if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) { + return EFI_INVALID_PARAMETER; + } + + if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) { + if (Value1->Type != Value2->Type) { + // + // Both Operator should be type of String + // + return EFI_INVALID_PARAMETER; + } + + if (Value1->Value.string == 0 || Value2->Value.string == 0) { + // + // StringId 0 is reserved + // + return EFI_INVALID_PARAMETER; + } + + if (Value1->Value.string == Value2->Value.string) { + return 0; + } + + Str1 = GetToken (Value1->Value.string, HiiHandle); + if (Str1 == NULL) { + // + // String not found + // + return EFI_INVALID_PARAMETER; + } + + Str2 = GetToken (Value2->Value.string, HiiHandle); + if (Str2 == NULL) { + gBS->FreePool (Str1); + return EFI_INVALID_PARAMETER; + } + + Result = EfiStrCmp (Str1, Str2); + + gBS->FreePool (Str1); + gBS->FreePool (Str2); + + return Result; + } + + // + // Take remain types(integer, boolean, date/time) as integer + // + Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64); + if (Temp64 > 0) { + Result = 1; + } else if (Temp64 < 0) { + Result = -1; + } else { + Result = 0; + } + + return Result; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetRuleControlfromId +// +// Description: +// +// Parameter: UINT8 *IFRData, CONTROL_INFO **RuleControl +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _GetRuleControlfromId(UINT16 RuleId, UINT16 PageId, CONTROL_INFO **RuleControl) +{ + EFI_STATUS Status = EFI_SUCCESS; + CONTROL_INFO *controlInfo = NULL; + BOOLEAN found = FALSE; + UINTN control = 0; + + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[PageId]); + if(pageInfo->PageHandle ==0) + { + Status = EFI_NOT_FOUND; + goto DONE; + } + + for(control= 0; (control < pageInfo->PageControls.ControlCount) && (found == FALSE); control++) + { + controlInfo = (CONTROL_INFO*)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + + if(RuleId == controlInfo->ControlKey) + { + found = TRUE; + } + } + + if(found) + { + *RuleControl = controlInfo; + } + +DONE: + return Status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: checkforpushthispresence +// +// Description: Checks the condition has EFI_IFR_THIS_OP +// +// Parameter: UINT8 * +// +// Return value: TRUE if EFI_IFR_THIS_OP presents else FALSE +//---------------------------------------------------------------------------- +// +BOOLEAN checkforpushthispresence (UINT8 *ControlConditionalPtr) +{ + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER*)ControlConditionalPtr; + UINTN inScope = 0; + UINTN i = 0; + + if (opHeader->Scope) + { + do + { + switch (opHeader->OpCode) + { + case EFI_IFR_THIS_OP: + return TRUE; + case EFI_IFR_END_OP: + inScope--; + break; + default: + if(opHeader->Scope) + { + inScope++; + } + } + i += opHeader->Length; + opHeader = (EFI_IFR_OP_HEADER*)(ControlConditionalPtr + i); + }while(inScope); + } + return FALSE; +} + +// +//---------------------------------------------------------------------------------------- +// +// Procedure: GetValueFromParentControl +// +// Description: Gets the value for inconsistent/submitif from its parent control +// +// Parameter: UINT16, UINT16, EFI_HII_VALUE **, PAGE_INFO *, VOID * +// +// Return value: EFI_SUCCESS if value retrieved successfully else some other EFI Status +//----------------------------------------------------------------------------------------- +// +EFI_STATUS _GetValueFromQuestionId (UINT16 QuestionId, UINT16 PageId, EFI_HII_VALUE **Value); +EFI_STATUS GetValueFromParentControl (UINT16 QuestionId, UINT16 PageId, EFI_HII_VALUE **Value, PAGE_INFO *pageInfo, VOID *CtrlCondPtr) +{ + UINT32 Count = 1; + UINTN control = 0; + EFI_STATUS Status = EFI_UNSUPPORTED; + EFI_IFR_OP_HEADER *OpHeader; + EFI_IFR_QUESTION_HEADER *questionHdr = NULL; + CHAR16 *questionValue; + EFI_STRING_ID StrToken = 0; + CONTROL_INFO *controlInfo; + + for (control= 0; control < pageInfo->PageControls.ControlCount; control++) + { + controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); //If two submit if present then questionid may be same so comparing conditionalptr also + if ((QuestionId == controlInfo->ControlKey) && ((CONTROL_TYPE_MSGBOX == controlInfo->ControlType) || (NO_SUBMIT_IF == controlInfo->ControlType)) && (CtrlCondPtr == controlInfo->ControlConditionalPtr)) + { + if (checkforpushthispresence (controlInfo->ControlConditionalPtr)) + { + do //Find the parent control. Inconsistent/submit only present inside question + { + controlInfo = (CONTROL_INFO*)((UINT8 *)(gControlInfo) + pageInfo->PageControls.ControlList [control-Count]); + Count ++; + }while ((CONTROL_TYPE_MSGBOX == controlInfo->ControlType) || (NO_SUBMIT_IF == controlInfo->ControlType)); //find parent suppress all the inconsistent/submit present in the control + OpHeader=(EFI_IFR_OP_HEADER *)controlInfo->ControlPtr; + if (EFI_IFR_STRING_OP != OpHeader->OpCode) + { + Status = _GetValueFromQuestionId (controlInfo->ControlKey, PageId, Value); + } + else + { + UINTN dataWidth = UefiGetWidth (controlInfo->ControlPtr); + questionHdr = (EFI_IFR_QUESTION_HEADER*)((UINT8 *)controlInfo->ControlPtr + sizeof(EFI_IFR_OP_HEADER)); + questionValue = EfiLibAllocateZeroPool (dataWidth + sizeof (CHAR16)); //sizeof (CHAR16) is for NULL if maximum characters used. + if (NULL == questionValue) + { + return EFI_OUT_OF_RESOURCES; + } + + // EIP-42300: Updated the dataWidth in comparison to the maximum supported + Status = VarGetValue (controlInfo->ControlVariable, questionHdr->VarStoreInfo.VarOffset, dataWidth, (VOID *)questionValue); + if (!EFI_ERROR(Status)) + { + if (*questionValue != 0) + { + StrToken = HiiAddString (controlInfo->ControlHandle, questionValue); + (*Value)->Value.string = StrToken; + (*Value)->Type = EFI_IFR_TYPE_STRING; + } + else + { + Status = EFI_NOT_STARTED; //If null string then dont compare + } + } + } + } + break; + } + } + return Status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetValueFromQuestionId +// +// Description: +// +// Parameter: UINT16 QuestionId, UINT16 PageId, UINT64 *Value +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _GetValueFromQuestionId(UINT16 QuestionId, UINT16 PageId, EFI_HII_VALUE **Value) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_IFR_QUESTION_HEADER *questionHdr = NULL; + BOOLEAN found = FALSE; + UINT32 varId = 0; + UINTN control = 0; + UINT64 questionValue = 0; + + CONTROL_INFO *controlInfo = NULL; + + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[PageId]); + + if(pageInfo->PageHandle ==0) + { + Status = EFI_NOT_FOUND; + goto DONE; + } + + for ( control= 0; (control < pageInfo->PageControls.ControlCount) && (found == FALSE); control++ ) + { + controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if(QuestionId == controlInfo->ControlKey) + { + if ((CONTROL_TYPE_MSGBOX == controlInfo->ControlType) || (NO_SUBMIT_IF == controlInfo->ControlType) || gInconsistCondPtr) + { + if (gInconsistCondPtr == controlInfo->ControlConditionalPtr) //All inconsistentif will have 0 as question id so adding more check + { + varId = controlInfo->ControlVariable; + found = TRUE; + } + } + else + { + varId = controlInfo->ControlVariable; + found = TRUE; + } + } + } + + if(!found) + { + // Control Definition not in this Page. Look within the formset + EFI_HII_HANDLE pgHandle = pageInfo->PageHandle; + UINT32 page = 0; + + for(;page < gPages->PageCount && (found == FALSE); page++) + { +/* + if(page == PageId) + { + continue; + } +*/ + pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[page]); + if(pageInfo->PageHandle != pgHandle) + { + continue; + } + + for(control = 0; control < pageInfo->PageControls.ControlCount && (found == FALSE); control++) + { + controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if(QuestionId == controlInfo->ControlKey) + { + varId = controlInfo->ControlVariable; + found = TRUE; + } + } + } + } + + if(found) + { + if (NULL != controlInfo->ControlPtr) //For inconsistent and nosubmitif controlptr will be NULL + { + UINTN dataWidth = UefiGetWidth(controlInfo->ControlPtr); + questionHdr = (EFI_IFR_QUESTION_HEADER*)((UINT8 *)controlInfo->ControlPtr + sizeof(EFI_IFR_OP_HEADER)); + + // EIP-42300: Updated the dataWidth in comparision to the maximum supported + Status = VarGetValue(varId, questionHdr->VarStoreInfo.VarOffset, (( dataWidth > sizeof(UINT64))? sizeof(UINT64) : dataWidth ), &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + (*Value)->Value.u64 = questionValue; + } + else if ((CONTROL_TYPE_MSGBOX == controlInfo->ControlType) || (NO_SUBMIT_IF == controlInfo->ControlType)) //Check for inconistent control + { + Status = GetValueFromParentControl (QuestionId, PageId, Value, pageInfo, controlInfo->ControlConditionalPtr); + } + } +DONE: + return Status; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: _SetValueFromQuestionId +// +// Description: +// +// Parameter: UINT16 QuestionId, UINT16 PageId, UINT64 *Value +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _SetValueFromQuestionId(UINT16 QuestionId, UINT16 PageId, EFI_HII_VALUE *Value) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_IFR_QUESTION_HEADER *questionHdr = NULL; + BOOLEAN found = FALSE; + UINT32 varId = 0; + UINTN control = 0; + UINT64 questionValue = Value->Value.u64; + + CONTROL_INFO *controlInfo = NULL; + + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[PageId]); + + if(pageInfo->PageHandle ==0) + { + Status = EFI_NOT_FOUND; + goto DONE; + } + + for ( control= 0; (control < pageInfo->PageControls.ControlCount) && (found == FALSE); control++ ) + { + controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if(QuestionId == controlInfo->ControlKey) + { + varId = controlInfo->ControlVariable; + found = TRUE; + } + } + + if(!found) + { + // Control Definition not in this Page. Look within the formset + EFI_HII_HANDLE pgHandle = pageInfo->PageHandle; + UINT32 page = 0; + + for(;page < gPages->PageCount && (found == FALSE); page++) + { + + pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[page]); + if(pageInfo->PageHandle != pgHandle) + { + continue; + } + + for(control = 0; control < pageInfo->PageControls.ControlCount && (found == FALSE); control++) + { + controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if(QuestionId == controlInfo->ControlKey) + { + varId = controlInfo->ControlVariable; + found = TRUE; + } + } + } + } + + if(found) + { + UINTN dataWidth = UefiGetWidth(controlInfo->ControlPtr); + questionHdr = (EFI_IFR_QUESTION_HEADER*)((UINT8 *)controlInfo->ControlPtr + sizeof(EFI_IFR_OP_HEADER)); + + // EIP-42300: Updated the dataWidth in comparision to the maximum supported + Status = VarSetValue(varId, questionHdr->VarStoreInfo.VarOffset, (( dataWidth > sizeof(UINT64))? sizeof(UINT64) : dataWidth ), &questionValue); + + } + +DONE: + return Status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: IsScopeStackEmpty +// +// Description: +// +// Parameter: VOID +// +// Return value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsScopeStackEmpty() +{ + UINT8 opCode = 0; + EFI_STATUS status = EFI_SUCCESS; + + status = PopScope(&opCode); + if(status == EFI_ACCESS_DENIED) + { + return TRUE; + } + + status = PushScope(opCode); + + return FALSE; +} + +// +//--------------------------------------------------------------------------- +// Procedure: GetPageIdFromGuid +// +// Description: Finds the page ID with matching Guid from the page list +// +// Input: EFI_GUID *FormSetGuid +// UINT16 *PageID +// +// Output: EFI_STATUS status - EFI_SUCCESS, if successful, +// EFI_INVALID_PARAMETER, if invalid values found +//--------------------------------------------------------------------------- +// +EFI_STATUS GetpageIdFromGuid(EFI_GUID *FormGuid, UINT16 *PageID) +{ + EFI_STATUS status = EFI_INVALID_PARAMETER; + UINT32 pgIndex = 0; + PAGE_INFO *pgInfo = (PAGE_INFO *)NULL; + PAGE_ID_INFO *pageIdInfo = (PAGE_ID_INFO*)NULL; + + + if(gPages && gApplicationData && gPageIdList) + { + for(pgIndex = 0; pgIndex < gPages->PageCount; pgIndex++) + { + pgInfo = (PAGE_INFO*)((UINTN)gApplicationData + gPages->PageList[pgIndex]); + if(pgInfo){ + pageIdInfo = (PAGE_ID_INFO *)(((UINT8 *) gPageIdList) + gPageIdList->PageIdList[pgInfo->PageIdIndex]); + if(pageIdInfo && (EfiCompareGuid(FormGuid, &(pageIdInfo->PageGuid)) == TRUE))//Compare Guid + { + *PageID = pgInfo->PageID; + status = EFI_SUCCESS; + goto DONE; + } + } + } + } + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: EvaluateExpression +// +// Description: Evaluate the result of a HII expression +// +// Parameter: IN CONTROL_INFO *ControlInfo, +// IN OUT BOOLEAN *ExpressionResult, +// OUT UINTN *Offset +// +// Return value: EFI_SUCCESS - The expression evaluated successfuly +// EFI_NOT_FOUND - The Question which referenced by a +// QuestionId could not be found. +// EFI_OUT_OF_RESOURCES - There is not enough system memory to +// grow the stack. +// EFI_ACCESS_DENIED - The pop operation underflowed the stack +// EFI_INVALID_PARAMETER - Syntax error with the Expression +//---------------------------------------------------------------------------- +// +EFI_STATUS +EvaluateExpression ( + IN CONTROL_INFO *ControlInfo, + IN OUT EFI_HII_VALUE *ExpressionResult, + OUT UINTN *Offset + ) +{ + EFI_IFR_OP_HEADER *ifrData = NULL; + CONTROL_INFO *ruleControl = NULL; + EFI_STATUS Status; + UINT16 Index; + EFI_HII_VALUE Data1; + EFI_HII_VALUE Data2; + EFI_HII_VALUE Data3; + EFI_HII_VALUE *questionValue = NULL; + EFI_HII_VALUE *questionValue2 = NULL; + EFI_HII_VALUE *Value = NULL; + EFI_QUESTION_ID questionId = 0; + INTN Result; + CHAR16 *StrPtr = NULL; + UINTN i = 0; + UINT8 opCode = 0; + BOOLEAN IsDevicePathFound = FALSE ,GUIDFound = FALSE; + EFI_GUID formSetGuid = {0}, zeroFormSetGuid = {0}; + UINTN count = 0,tempcount = 0; + CHAR16 *devPathStr = (CHAR16 *)NULL, *tempDevPathStr = (CHAR16 *)NULL; + EFI_DEVICE_PATH_PROTOCOL *tempDevPath = (EFI_DEVICE_PATH_PROTOCOL *)NULL; + UINT16 DevicePath = 0; + // + // Always reset the stack before evaluating an Expression + // + ResetExpressionStack (); + + ExpressionResult->Type = EFI_IFR_TYPE_OTHER; + + opCode = ((EFI_IFR_OP_HEADER*)ControlInfo->ControlConditionalPtr)->OpCode; + if(opCode != EFI_IFR_SUPPRESS_IF_OP && opCode != EFI_IFR_NO_SUBMIT_IF_OP && + opCode != EFI_IFR_INCONSISTENT_IF_OP && opCode != EFI_IFR_GRAY_OUT_IF_OP && + opCode != EFI_IFR_DISABLE_IF_OP && opCode != EFI_IFR_VALUE_OP) + { + Status = EFI_SUCCESS; + goto DONE; + } + + questionValue = (EFI_HII_VALUE*)EfiLibAllocateZeroPool(sizeof(EFI_HII_VALUE)); + if(questionValue == NULL) + { + Status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + questionValue2 = (EFI_HII_VALUE*)EfiLibAllocateZeroPool(sizeof(EFI_HII_VALUE)); + if(questionValue2 == NULL) + { + Status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + if(((EFI_IFR_OP_HEADER*)ControlInfo->ControlConditionalPtr)->OpCode == EFI_IFR_RULE_OP) + { + PushScope(EFI_IFR_RULE_OP); + }else + { + PushScope(((EFI_IFR_OP_HEADER*)ControlInfo->ControlConditionalPtr)->OpCode); + if ( + ( ( (EFI_IFR_OP_HEADER*)ControlInfo->ControlConditionalPtr)->OpCode == EFI_IFR_INCONSISTENT_IF_OP) || + ( ( (EFI_IFR_OP_HEADER*)ControlInfo->ControlConditionalPtr)->OpCode == EFI_IFR_NO_SUBMIT_IF_OP) + ) + { + gInconsistCondPtr = ControlInfo->ControlConditionalPtr; + } + } + + i += ((EFI_IFR_OP_HEADER*)ControlInfo->ControlConditionalPtr)->Length; + + while (IsScopeStackEmpty() == FALSE) + { + ifrData = (EFI_IFR_OP_HEADER*)((UINT8 *)ControlInfo->ControlConditionalPtr + i); + + EfiZeroMem (&Data1, sizeof (EFI_HII_VALUE)); + EfiZeroMem (&Data2, sizeof (EFI_HII_VALUE)); + EfiZeroMem (&Data3, sizeof (EFI_HII_VALUE)); + EfiZeroMem (questionValue, sizeof(EFI_HII_VALUE)); + EfiZeroMem (questionValue2, sizeof(EFI_HII_VALUE)); + + Value = &Data3; + Value->Type = EFI_IFR_TYPE_BOOLEAN; + Status = EFI_SUCCESS; + + questionValue->Type = EFI_IFR_TYPE_NUM_SIZE_64; + + switch (ifrData->OpCode) + { + // + // Built-in functions + // + case EFI_IFR_EQ_ID_VAL_OP: + questionId = ((EFI_IFR_EQ_ID_VAL*)ifrData)->QuestionId; + Status = _GetValueFromQuestionId(questionId, ControlInfo->ControlPageID, &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + + questionValue2->Type = EFI_IFR_TYPE_NUM_SIZE_64; + questionValue2->Value.u64 = ((EFI_IFR_EQ_ID_VAL*)ifrData)->Value; + + Result = CompareHiiValue (questionValue, questionValue2, NULL); + if (Result == EFI_INVALID_PARAMETER) + { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + Value->Value.b = (Result == 0) ? TRUE : FALSE; + break; + + case EFI_IFR_EQ_ID_ID_OP: + questionId = ((EFI_IFR_EQ_ID_ID*)ifrData)->QuestionId1; + Status = _GetValueFromQuestionId(questionId, ControlInfo->ControlPageID, &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + questionId = ((EFI_IFR_EQ_ID_ID*)ifrData)->QuestionId2; + Status = _GetValueFromQuestionId(questionId, ControlInfo->ControlPageID, &questionValue2); + if(EFI_ERROR(Status)) + { + goto DONE; + } + + Result = CompareHiiValue (questionValue, questionValue2, ControlInfo->ControlHandle); + if (Result == EFI_INVALID_PARAMETER) + { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + Value->Value.b = (Result == 0) ? TRUE : FALSE; + break; + + case EFI_IFR_EQ_ID_LIST_OP: + questionId = ((EFI_IFR_EQ_ID_LIST*)ifrData)->QuestionId; + Status = _GetValueFromQuestionId(questionId, ControlInfo->ControlPageID, &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + + Value->Value.b = FALSE; + for (Index =0; Index < ((EFI_IFR_EQ_ID_LIST*)ifrData)->ListLength; Index++) + { + if (questionValue->Value.u16 == ((EFI_IFR_EQ_ID_LIST*)ifrData)->ValueList[Index]) + { + Value->Value.b = TRUE; + break; + } + } + break; + + case EFI_IFR_DUP_OP: + Status = PopExpression (Value); + if (EFI_ERROR (Status)) + { + goto DONE; + } + + Status = PushExpression (Value); + break; + + case EFI_IFR_QUESTION_REF1_OP: + case EFI_IFR_THIS_OP: + if(ifrData->OpCode == EFI_IFR_THIS_OP) + { + questionId = ControlInfo->ControlKey; + }else + { + questionId = ((EFI_IFR_QUESTION_REF1*)ifrData)->QuestionId; + } + Status = _GetValueFromQuestionId(questionId, ControlInfo->ControlPageID, &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + + Value = questionValue; + break; + + + case EFI_IFR_QUESTION_REF3_OP: + + // + // EFI_IFR_QUESTION_REF3 + // Pop an expression from the expression stack + // + Status = PopExpression (Value); + if (EFI_ERROR (Status)) + { + goto DONE; + } + + // + // Validate the expression value + // + + if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) + { + Status = EFI_NOT_FOUND; + goto DONE; + } + + if(ifrData->Length > sizeof(EFI_IFR_QUESTION_REF3)) + { + if(ifrData->Length > sizeof(EFI_IFR_QUESTION_REF3_2)) + { + MemCopy(&formSetGuid,&((EFI_IFR_QUESTION_REF3_3*)ifrData)->Guid, sizeof (EFI_GUID)); + if(EfiCompareGuid(&formSetGuid, &zeroFormSetGuid) == FALSE) + { + UINT16 PageID; + Status = GetpageIdFromGuid(&formSetGuid,&PageID); + if(Status == 0) + { + GUIDFound = TRUE; + Status = _GetValueFromQuestionId(Value->Value.u16,PageID, &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + } + } + } + DevicePath = ifrData->Length < sizeof(EFI_IFR_QUESTION_REF3_3) ? ((EFI_IFR_QUESTION_REF3_2*)ifrData)->DevicePath : ((EFI_IFR_QUESTION_REF3_3*)ifrData)->DevicePath; + if(DevicePath != 0 && !GUIDFound) + { + PAGE_INFO *tempPageInfo1 = NULL; + devPathStr = GetToken (DevicePath,ControlInfo->ControlHandle); + + if(devPathStr == NULL){ + goto DONE; + } + + for(count = 0; count < gPages->PageCount; count++) + { + PAGE_INFO *tempPageInfo = (PAGE_INFO*)((UINTN)gApplicationData + gPages->PageList[count]); + if(tempPageInfo == NULL) + { + continue; + } + Status = GetDevPathFromHandle(tempPageInfo->PageHandle, &tempDevPath); + if((Status == EFI_SUCCESS) && (tempDevPath != NULL) && tempPageInfo->PageParentID == 0) + { + GetStringFromDevPath(tempDevPath, &tempDevPathStr); + if(EfiStrCmp(devPathStr, tempDevPathStr) == 0) + { + tempcount++; + tempPageInfo1=tempPageInfo; + } + MemFreePointer( (VOID **)&tempDevPathStr ); + } + } + MemFreePointer( (VOID **)&devPathStr ); + + if(tempcount == 1){ + IsDevicePathFound = TRUE; + Status = _GetValueFromQuestionId(Value->Value.u16, tempPageInfo1->PageID, &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + } + if(tempcount > 1){ + goto DONE; + } + } + } + if(!IsDevicePathFound && !GUIDFound && !tempcount) + { + Status = _GetValueFromQuestionId(Value->Value.u16, ControlInfo->ControlPageID, &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + } + Value = questionValue; + break; + + case EFI_IFR_RULE_REF_OP: + questionId = ((EFI_IFR_RULE_REF*)ifrData)->RuleId; + + Status = _GetRuleControlfromId(questionId, ControlInfo->ControlPageID, &ruleControl); + + /* This Section Needs to be modified + // + // Find expression for this rule + // + RuleExpression = RuleIdToExpression (Form, OpCode->RuleId); + if (RuleExpression == NULL) { + return EFI_NOT_FOUND; + }*/ + + // + // Evaluate this rule expression + // + Status = EvaluateExpression (ruleControl, ExpressionResult, Offset); + if (EFI_ERROR (Status)) + { + goto DONE; + } + + Value = ExpressionResult; + break; + + case EFI_IFR_STRING_REF1_OP: + Value->Type = EFI_IFR_TYPE_STRING; + Value->Value.string = ((EFI_IFR_STRING_REF1*)ifrData)->StringId; + break; + + // + // Constant + // + case EFI_IFR_TRUE_OP: + Value->Value.b = TRUE; + break; + case EFI_IFR_FALSE_OP: + Value->Value.b = FALSE; + break; + case EFI_IFR_ONE_OP: +#define ONE 1 + Value->Type = EFI_IFR_TYPE_NUM_SIZE_8; + Value->Value.u8 = ONE; + break; + case EFI_IFR_ONES_OP: +#define ONES 0xFFFFFFFFFFFFFFFF + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; + Value->Value.u64 = ONES; + break; + case EFI_IFR_UINT8_OP: + Value->Type = EFI_IFR_TYPE_NUM_SIZE_8; + Value->Value.u8 = ((EFI_IFR_UINT8*)ifrData)->Value; + break; + case EFI_IFR_UINT16_OP: + Value->Type = EFI_IFR_TYPE_NUM_SIZE_16; + Value->Value.u16 = ((EFI_IFR_UINT16*)ifrData)->Value; + break; + case EFI_IFR_UINT32_OP: + Value->Type = EFI_IFR_TYPE_NUM_SIZE_32; + Value->Value.u32 = ((EFI_IFR_UINT32*)ifrData)->Value; + break; + case EFI_IFR_UINT64_OP: + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; + Value->Value.u64 = ((EFI_IFR_UINT64*)ifrData)->Value; + break; + case EFI_IFR_UNDEFINED_OP: + Value->Type = EFI_IFR_TYPE_OTHER; + break; + case EFI_IFR_VERSION_OP: +#define VERSION (UINT16)(2<<8)|((3<<4) | 0x1) //EIP:56355 Updated the Version to 2.3.1 + Value->Type = EFI_IFR_TYPE_NUM_SIZE_16; + Value->Value.u16 = VERSION; + break; + case EFI_IFR_ZERO_OP: +#define ZERO 0 + Value->Type = EFI_IFR_TYPE_NUM_SIZE_8; + Value->Value.u8 = ZERO; + break; + + // + // unary-op + // + case EFI_IFR_LENGTH_OP: + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Value->Type != EFI_IFR_TYPE_STRING) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + StrPtr = GetToken (Value->Value.string, ControlInfo->ControlHandle); + if (StrPtr == NULL) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; + Value->Value.u64 = EfiStrLen (StrPtr); + gBS->FreePool (StrPtr); + break; + + case EFI_IFR_NOT_OP: + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Value->Type != EFI_IFR_TYPE_BOOLEAN) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + Value->Value.b = !Value->Value.b; + break; + + case EFI_IFR_QUESTION_REF2_OP: + // + // Pop an expression from the expression stack + // + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + goto DONE; + } + + // + // Validate the expression value + // + if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) { + Status = EFI_NOT_FOUND; + goto DONE; + } + + Status = _GetValueFromQuestionId(Value->Value.u16, ControlInfo->ControlPageID, &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + + Value = questionValue; + break; + + case EFI_IFR_STRING_REF2_OP: + // + // Pop an expression from the expression stack + // + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + goto DONE; + } + + // + // Validate the expression value + // + if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) { + Status = EFI_NOT_FOUND; + goto DONE; + } + + Value->Type = EFI_IFR_TYPE_STRING; + StrPtr = GetToken (Value->Value.u16, ControlInfo->ControlHandle); + if (StrPtr == NULL) { + // + // If String not exit, push an empty string + // + Value->Value.string = NewString (gEmptyString, ControlInfo->ControlHandle); + } else { + Index = (UINT16) Value->Value.u64; + Value->Value.string = Index; + gBS->FreePool (StrPtr); + } + break; + + case EFI_IFR_TO_BOOLEAN_OP: + // + // Pop an expression from the expression stack + // + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + goto DONE; + } + + // + // Convert an expression to a Boolean + // + if (Value->Type <= EFI_IFR_TYPE_DATE) { + // + // When converting from an unsigned integer, zero will be converted to + // FALSE and any other value will be converted to TRUE. + // + Value->Value.b = (Value->Value.u64) ? TRUE : FALSE; + + Value->Type = EFI_IFR_TYPE_BOOLEAN; + } else if (Value->Type == EFI_IFR_TYPE_STRING) { + // + // When converting from a string, if case-insensitive compare + // with "true" is True, then push True. If a case-insensitive compare + // with "false" is True, then push False. + // + StrPtr = GetToken (Value->Value.string, ControlInfo->ControlHandle); + if (StrPtr == NULL) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + if ((EfiStrCmp (StrPtr, L"true") == 0)) + { + Value->Value.b = TRUE; + } else if(EfiStrCmp (StrPtr, L"false") == 0) + { + Value->Value.b = FALSE; + } else + { + Value->Type = EFI_IFR_TYPE_OTHER; + } + gBS->FreePool (StrPtr); + Value->Type = EFI_IFR_TYPE_BOOLEAN; + } + break; + + case EFI_IFR_TO_STRING_OP: + Status = IfrToString (ControlInfo->ControlHandle, ((EFI_IFR_TO_STRING*)ifrData)->Format, Value); + break; + + case EFI_IFR_TO_UINT_OP: + Status = IfrToUint (ControlInfo->ControlHandle, Value); + break; + + case EFI_IFR_TO_LOWER_OP: + case EFI_IFR_TO_UPPER_OP: + Status = InitializeUnicodeCollationProtocol (); + if (EFI_ERROR (Status)) { + goto DONE; + } + + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + goto DONE; + } + + if (Value->Type != EFI_IFR_TYPE_STRING) { + Status = EFI_UNSUPPORTED; + goto DONE; + } + + StrPtr = GetToken (Value->Value.string, ControlInfo->ControlHandle); + if (StrPtr == NULL) { + Status = EFI_NOT_FOUND; + goto DONE; + } + + if (ifrData->OpCode == EFI_IFR_TO_LOWER_OP) { + mUnicodeCollation->StrLwr (mUnicodeCollation, StrPtr); + } else { + mUnicodeCollation->StrUpr (mUnicodeCollation, StrPtr); + } + Value->Value.string = NewString (StrPtr, ControlInfo->ControlHandle); + gBS->FreePool (StrPtr); + break; + + case EFI_IFR_BITWISE_NOT_OP: + // + // Pop an expression from the expression stack + // + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Value->Type > EFI_IFR_TYPE_DATE) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; + Value->Value.u64 = ~Value->Value.u64; + break; + + // + // binary-op + // + case EFI_IFR_ADD_OP: + case EFI_IFR_SUBTRACT_OP: + case EFI_IFR_MULTIPLY_OP: + case EFI_IFR_DIVIDE_OP: + case EFI_IFR_MODULO_OP: + case EFI_IFR_BITWISE_AND_OP: + case EFI_IFR_BITWISE_OR_OP: + case EFI_IFR_SHIFT_LEFT_OP: + case EFI_IFR_SHIFT_RIGHT_OP: + // + // Pop an expression from the expression stack + // + Status = PopExpression (&Data2); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Data2.Type > EFI_IFR_TYPE_DATE) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + // + // Pop another expression from the expression stack + // + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Data1.Type > EFI_IFR_TYPE_DATE) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; + + switch (ifrData->OpCode) { + case EFI_IFR_ADD_OP: + Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64; + break; + + case EFI_IFR_SUBTRACT_OP: + Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64; + break; + + case EFI_IFR_MULTIPLY_OP: + Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32)Data2.Value.u64); + break; + + case EFI_IFR_DIVIDE_OP: + Value->Value.u64 = AmiTseDivU64x32 (Data1.Value.u64, (UINT32)Data2.Value.u64,NULL); + break; + + case EFI_IFR_MODULO_OP: + Value->Value.u64 = 0; + AmiTseDivU64x32(Data1.Value.u64, (UINT32)Data2.Value.u64, (UINTN*)&Value->Value.u64); + break; + + case EFI_IFR_BITWISE_AND_OP: + Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64; + break; + + case EFI_IFR_BITWISE_OR_OP: + Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64; + break; + + case EFI_IFR_SHIFT_LEFT_OP: + Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64); + break; + + case EFI_IFR_SHIFT_RIGHT_OP: + Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64); + break; + + default: + break; + } + break; + + case EFI_IFR_AND_OP: + case EFI_IFR_OR_OP: + // + // Two Boolean operator + // + Status = PopExpression (&Data2); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + // + // Pop another expression from the expression stack + // + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + if (ifrData->OpCode == EFI_IFR_AND_OP) { + Value->Value.b = Data1.Value.b && Data2.Value.b; + } else { + Value->Value.b = Data1.Value.b || Data2.Value.b; + } + break; + + case EFI_IFR_EQUAL_OP: + case EFI_IFR_NOT_EQUAL_OP: + case EFI_IFR_GREATER_EQUAL_OP: + case EFI_IFR_GREATER_THAN_OP: + case EFI_IFR_LESS_EQUAL_OP: + case EFI_IFR_LESS_THAN_OP: + // + // Compare two integer, string, boolean or date/time + // + Status = PopExpression (&Data2); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + // + // Pop another expression from the expression stack + // + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + goto DONE; + } + + Result = CompareHiiValue (&Data1, &Data2, ControlInfo->ControlHandle); + if (Result == EFI_INVALID_PARAMETER) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + switch (ifrData->OpCode) { + case EFI_IFR_EQUAL_OP: + Value->Value.b = (Result == 0) ? TRUE : FALSE; + break; + + case EFI_IFR_NOT_EQUAL_OP: + Value->Value.b = (Result != 0) ? TRUE : FALSE; + break; + + case EFI_IFR_GREATER_EQUAL_OP: + Value->Value.b = (Result >= 0) ? TRUE : FALSE; + break; + + case EFI_IFR_GREATER_THAN_OP: + Value->Value.b = (Result > 0) ? TRUE : FALSE; + break; + + case EFI_IFR_LESS_EQUAL_OP: + Value->Value.b = (Result <= 0) ? TRUE : FALSE; + break; + + case EFI_IFR_LESS_THAN_OP: + Value->Value.b = (Result < 0) ? TRUE : FALSE; + break; + + default: + break; + } + break; + + case EFI_IFR_MATCH_OP: + Status = IfrMatch (ControlInfo->ControlHandle, Value); + break; + + case EFI_IFR_CATENATE_OP: + Status = IfrCatenate (ControlInfo->ControlHandle, Value); + break; + + // + // ternary-op + // + case EFI_IFR_CONDITIONAL_OP: + // + // Pop third expression from the expression stack + // + Status = PopExpression (&Data3); + if (EFI_ERROR (Status)) { + goto DONE; + } + + // + // Pop second expression from the expression stack + // + Status = PopExpression (&Data2); + if (EFI_ERROR (Status)) { + goto DONE; + } + + // + // Pop first expression from the expression stack + // + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + if (Data1.Value.b) { + Value = &Data3; + } else { + Value = &Data2; + } + break; + + case EFI_IFR_FIND_OP: + Status = IfrFind (ControlInfo->ControlHandle, ((EFI_IFR_FIND*)ifrData)->Format, Value); + break; + + case EFI_IFR_MID_OP: + Status = IfrMid (ControlInfo->ControlHandle, Value); + break; + + case EFI_IFR_TOKEN_OP: + Status = IfrToken (ControlInfo->ControlHandle, Value); + break; + + case EFI_IFR_SPAN_OP: + Status = IfrSpan (ControlInfo->ControlHandle, ((EFI_IFR_SPAN*)ifrData)->Flags, Value); + break; + + default: + Status = PopScope(&opCode); + if (EFI_ERROR (Status)) + { + goto DONE; + } + continue; + } + if (EFI_ERROR (Status)) + { + goto DONE; + } + + Status = PushExpression (Value); + if (EFI_ERROR (Status)) + { + goto DONE; + } + + i += ifrData->Length; + } + if (NULL != ifrData)//EIP-75384 Static code + { + if(ifrData->OpCode == EFI_IFR_END_OP) + i += ifrData->Length; + } + + // + // Pop the final result from expression stack + // + Value = &Data1; + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + goto DONE; + } + + // + // After evaluating an expression, there should be only one value left on the expression stack + // + if (PopExpression (Value) != EFI_ACCESS_DENIED) + { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + EfiCopyMem (ExpressionResult, Value, sizeof (EFI_HII_VALUE)); + +DONE: + MemFreePointer(&questionValue); + MemFreePointer(&questionValue2); + + *Offset = i; + gInconsistCondPtr = NULL; + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _SkipExpression +// +// Description: Travels till the end of the current Expression and returns the offset +// +// Parameter: ControlCondPtr - Pointer to the Expression beginning. +// +// Return value: UINTN - Offsets to skip the current expression. +//---------------------------------------------------------------------------- +// +UINTN _SkipExpression(UINT8 *ControlCondPtr) +{ + EFI_IFR_OP_HEADER *OpHeader = ( EFI_IFR_OP_HEADER * )ControlCondPtr; + UINTN offset = 0; + INTN inScope = 0; + + // Skip the If condition OpCode + if( + OpHeader->OpCode != EFI_IFR_SUPPRESS_IF_OP && + OpHeader->OpCode != EFI_IFR_NO_SUBMIT_IF_OP && + OpHeader->OpCode != EFI_IFR_INCONSISTENT_IF_OP && + OpHeader->OpCode != EFI_IFR_GRAY_OUT_IF_OP && + OpHeader->OpCode != EFI_IFR_DISABLE_IF_OP + ) + { + // This should not happen. The code should halt here. + offset = 0; + goto DONE; + } + + // Skip the If opcode + offset = OpHeader->Length; + OpHeader = ( EFI_IFR_OP_HEADER * )(( UINT8 *)OpHeader + offset ); + + do + { + switch( OpHeader->OpCode ) + { + case EFI_IFR_END_OP: + inScope--; + break; + default: + if(OpHeader->Scope) + inScope++; + break; + } + offset += OpHeader->Length; + OpHeader = ( EFI_IFR_OP_HEADER * )(( UINT8 *)OpHeader + OpHeader->Length ); + }while(inScope > 0); + +DONE: + return offset; +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/EDK/MiniSetup/uefi2.1/FormBrowser2.c b/EDK/MiniSetup/uefi2.1/FormBrowser2.c new file mode 100644 index 0000000..700bcc2 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/FormBrowser2.c @@ -0,0 +1,1175 @@ +//********************************************************************** +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-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/Uefi2.1/FormBrowser2.c $ +// +// $Author: Premkumara $ +// +// $Revision: 35 $ +// +// $Date: 8/28/14 12:24p $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/FormBrowser2.c $ +// +// 35 8/28/14 12:24p Premkumara +// [TAG] EIP175017 +// [Category] Bug Fix +// [Severity:] Normal +// [Symptom:] Setup hangs when sendform called from oemdriverhealth module +// [Solution] TSE installs timer to read the keys in conin availability. +// This timer stopped in PostManagerHandshake but if mainsetuploop called +// from sendform then this timer not stopped so hang happened in different +// stages.So stopping timer properly resolves the issue. +// [Files] FormBrowser2.c +// +// 34 2/11/14 8:50p Arunsb +// [TAG] EIP147816 +// [Category] Bug Fix +// [Symptom] Having same two formset with two different handles, confirm +// checkbox is grayed out in one formset not in other +// [Root Cause] During BrowserCallback, the current context +// [gCurrVarHandle and gCurrVarIndex] is lost due to multiple pack updates +// within a single callback. +// [Solution] Maintain a stack to preserve the current context values for +// (gCurrVarHandle and gCurrVarIndex) during BrowserCallback +// [Files] FormBrowser2.c +// +// 33 12/04/13 3:43p Premkumara +// [TAG] EIP144581 +// [Category] Bug Fix +// [Severity:] Important +// [Symptom:] TSE gets Hangs when HiiLibSetBrowserData try to update +// LegacyDevOrder +// [Root Cause] LegacyBootData is setting irrespective of valid options +// [Solution] Validating LegacyBootData for valid options and save valid +// options. +// [Files] FormBrowser2.c +// +// 32 5/15/13 4:50a Premkumara +// [TAG] EIP123312 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Build error when token TSE_DEBUG_MESSAGE is enabled +// [RootCause] Parameter missed to pass to a function WriteDataToFile() +// [Solution] Passed valid parameter to WriteDataToFile() +// [Files] FormBrowser2.c +// +// 31 4/18/13 2:23a Arunsb +// [TAG] EIP113266 +// [Category] Improvement +// [Description] gBrowserCallbackEnabled variable moved to boot only +// module +// [Files] boot.c and FormBrowser2.c +// +// 30 2/25/13 10:57a Blaines +// [TAG] - EIP 104273 +// [Category] - Action Item +// [Description] - Provide ability to dump the Hii Pack from the Setup as +// part TSE debug Infrastructure. It should dump the Pack updates on Hii +// notification also. +// So it can be used to debug the issue. +// [Files] - ForBrowser2.c, Hii.c, HiiNotificationHandler.c, +// UefiWapper.c, TseUefiHii.h +// +// 29 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 12 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 27 9/20/12 11:15a Arunsb +// SendForm will operate only with SETUP_FORM_BROWSER_SUPPORT token +// enabled. +// +// 26 5/29/12 3:10a Premkumara +// Added missing version-23 (EIP-90895) changes +// +// 25 5/28/12 9:55a Premkumara +// Added missing version-23 (EIP-90895) changes +// +// 24 5/28/12 5:56a Premkumara +// [TAG] EIP75236 +// [Category] Improvement +// [Description] Add the support to control the GOP dependency in TSE +// notification. +// [Files] AMITSE.sdl, CommonHelper.c, Notify.c, Minisetup.h, +// Minisetup.sdl, protocol.c, FormBrowser.c, FormBrowser2.c +// +// 23 5/26/12 5:35a Arunsb +// [TAG] EIP90895 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Setup hangs when retrieve callback produces +// add/remove/update forms +// [RootCause] Callback with retrieve action produces add/remove/update +// form +// [Solution] If retrieve callback produces add/remove/update form then +// TSE will print debug messages and assert. +// [Files] HiiNotificationHandler.c, HiiCallback.c and FormBrowser2.c +// +// 22 2/03/12 1:31p Arunsb +// [TAG] EIP81617 +// [Category] Improvement +// [Description] Avoiding memory leaks in TSE +// [Files] hiistring21.c, CommonHelper.c, notify.c and formbrowser2.c +// +// 21 1/20/12 5:33a Rajashakerg +// [TAG] EIP75567 +// [Category] Improvement +// [Description] Provide ActionRequest in SendForm function +// [Files] FormBrowser2.c +// +// 20 12/07/11 3:31p Arunsb +// [TAG] EIP75588 +// [Category] New Feature +// [Description] Support for queuing UpdatePack notifications +// [Files] frame.c, page.c, formbrowser2.c, hii.c, hiicallback.c, +// hiinotificationhandler.c, tseuefihii.h and uefi21wapper.c +// +// 19 12/07/11 8:12a Rajashakerg +// [TAG] EIP75118 +// [Category] Improvement +// [Description] xtractConfig() fail since BrowserCallback() cannot find +// the variable to process +// [Files] FormBrowser2.c, FormBrowser2.h, HiiCallback.c, +// Uefi21Wapper.c, PopupSel.c +// +// 18 12/05/11 5:53a Rajashakerg +// [TAG] EIP76381 +// [Category] Improvement +// [Description] Performance: Improving variable data load and usage +// [Files] callback.c, minisetupext.c, variable.c, variable.h, +// minisetup.h, Hii.c, FormBrowser2.c +// +// 17 11/30/11 1:37p 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 +// +// 16 11/28/11 2:27a Premkumara +// [TAG] EIP75384 +// [Category] Improvement +// [Description] Suppress the warnings from static code analyzer +// [Files] UefiWapper.c, Hii.c, Expression.c, CtrlCond.c, PopupSel.c, +// Minisetupext.c, Menu.c, Date.c, Ezport\Stylecommon.c, +// EzportPlus\StyleCommon.c, +// +// 15 11/23/11 5:13a Rajashakerg +// [TAG] EIP75473 +// [Category] Improvement +// [Description] System Time is not updated every second +// [Files] variable.h, variable.c, FormBrowser2.c, TseUefiHii.h, +// Uefi21Wapper.c, hii.h, uefi20Wapper.c +// +// 14 11/21/11 5:55a Rajashakerg +// [TAG] EIP74591 +// [Category] Improvement +// [Description] Make MainSetupLoop as board module hook +// [Files] AMITSE.sdl, CommonHelper.c, protocol.c, minisetup.h, +// FormBrowser.c, FormBrowser2.c +// +// 13 11/14/11 2:43p Blaines +// [TAG] - EIP 75481 +// [Category]- Function Request +// [Synopsis]- TSE debug print infrastructure. +// [Description]- Add TSE debug print info for basic functions such as +// Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms +// data. +// [Files] +// AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c +// Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c, +// HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h, +// Uefi21Wrapper.c, setupdbg.h +// +// 12 11/08/11 4:50a Rajashakerg +// Lowered the TPL to Application level and invoked +// StyleUpdateVersionString() function to update the copy right string in +// the SendForm() function. +// +// 11 6/30/11 11:55a Arunsb +// Adding config header in config string is controlled by +// EDKVersion_1_05_RetrieveData wrapper function. +// +// 10 6/30/11 4:16a Arunsb +// [TAG] EIP57661 +// [Category] New Feature +// [Description] Boot manager algorithm for interaction with Driver +// Health protocol. +// gFSetGuid added to compare in parseform. +// [Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni, +// commonhelper.c, uefisetup.ini, tsedrvhealth.h, +// amivfr.h, minisetupbin.mak, +// hiistring21.c, hiistring20.c, tseadvanced.c, special.c, +// special.h, boot.h, minisetup.h, +// uefi20wapper.c, formbrowser2.c, hii.c, parse.c and +// uefi21wapper.c. +// +// 9 3/28/11 6:00p Madhans +// [TAG] EIP56247 +// [Category] Improvement +// [Description] To support BrowserCallback with ResultData=NULL. +// To to add EDK_1_05_RETRIEVE_DATA SDL on by default for UEFI OptionROM +// cards to work. +// Need Core changes if EDK_1_05_RETRIEVE_DATA=1. +// EDK_1_05_RETRIEVE_DATA=0 May cause UEFI Option ROM card to not work ok. +// +// [Files] Uefi21.sdl +// FormBrowser2.c +// +// 8 12/02/10 5:51p Madhans +// [TAG] - EIP 48169 +// [Category]- Improvment. +// [Severity]- Mordarate +// [Symptom]- To do the Workaround for ConfigtoBlock issues and Fix issues +// with Retirive config. +// [Solution]- Fix done formBrowser2.c and uefi21wrapper.c +// [Files] - formBrowser2.c and uefi21wrapper.c +// +// 7 9/16/10 8:38p Madhans +// Update for TSE 2.10. Refer Changelog.log for more details. +// +// 9 9/15/10 1:55p Madhans +// To fix the issue with TSE when SetBrowser data is called. Without this +// fix always lastbyte of set browser data is missed. +// +// 8 6/17/10 2:58p Madhans +// Exit safely when sendform is not supported. +// +// 7 3/11/10 5:42p Madhans +// Coding Standards Update +// +// 6 2/26/10 6:57p Madhans +// To validate the Hii Handle before trying to process it. +// +// 5 2/19/10 8:35p Madhans +// Function header fix +// +// 4 1/12/10 11:10a Presannar +// Modified code to return BrowserCallback String according to either EDK +// browser or spec +// +// 3 1/08/10 4:43p Presannar +// Fixed BrowserCallback to return EFI_INVALID_PARAMETER when ResultsData +// is NULL and *ResultsDataSize != 0 +// +// 2 11/19/09 5:28p Presannar +// Updated TSE include file name to not clash with CORE file +// +// 1 7/24/09 6:54p Presannar +// +// 3 3/31/09 4:15p Madhans +// UEFI Wrapper improvments. +// +// 2 1/29/09 6:06p Presannar +// Added Function Header Comments +// +// 1 1/09/09 2:38p Presannar +// UEFI 2.1 Hii Related Code - Initial Drop +// +// 1 12/29/08 4:46p Presannar +// FormBrowser2 protocol Send Form and BrowserCallback initial draft +// +//************************************************************************* +// +// +// Name: FormBrowser2.C +// +// Description: +// +// +//************************************************************************* + +//---------------------------------------------------------------------------- +#include "Minisetup.h" +#include "FormBrowser2.h" +#include "TseUefiHii.h" +//---------------------------------------------------------------------------- +extern BOOLEAN gPackUpdatePending; +extern BOOLEAN gEnableDrvNotification; //TRUE if allow notification function to process action, FALSE to ignore the notification +extern UINTN HpkFileCount; +//--------------------------------------------------------------------------- +// Variables +//--------------------------------------------------------------------------- +BOOLEAN gRequireSysReboot = FALSE; //EIP 75567 :If TRUE, ACTION_REQUEST_RESET will be returned from SendForm, else ignore reboot +VOID **gSfHandles; +UINTN gSfHandleCount; +EFI_GUID *gFSetGuid = NULL; +UINT8 *gSfNvMap; +extern BOOLEAN gBrowserCallbackEnabled; //EIP113266 Allow external drivers to change ASL cache only if it's TRUE; ignore browser callback otherwise +extern BOOLEAN gEnterSetup; +extern EFI_EVENT gKeyTimer; +EFI_BROWSER_ACTION gBrowserCallbackAction = 0 ;//Contains the BrowserCallback action when a callback is in progress. +//static CONTROL_INFO *gCallbackControl = NULL; unused +static EFI_HANDLE gCurrVarHandle = (EFI_HANDLE)NULL; +static UINT32 gCurrVarIndex = 0; +#define BROWSERCALLBACK_MAX_ENTRIES 10 +static EFI_HANDLE gCallBackHandleStack[BROWSERCALLBACK_MAX_ENTRIES]; //EIP-147816 +static UINT32 gCallBackVarIndexStack[BROWSERCALLBACK_MAX_ENTRIES];//EIP-147816 + +EFI_GUID gEfiFormBrowser2ProtocolGuid = EFI_FORM_BROWSER2_PROTOCOL_GUID; + +//--------------------------------------------------------------------------- +// Structure +//--------------------------------------------------------------------------- +EFI_FORM_BROWSER2_PROTOCOL FormBrowser2 = +{ + SendForm, + BrowserCallback +}; + +//--------------------------------------------------------------------------- +// Function Prototypes +//--------------------------------------------------------------------------- +EFI_STATUS _StorageToConfigResp(VARIABLE_INFO *VariableInfo, VOID *Buffer, CHAR16 *ConfigHdr, CHAR16 **ConfigResp); +EFI_STATUS _ConfigRespToStorage(VARIABLE_INFO *varInfo, UINT8 **buffer, UINTN *Size, EFI_STRING configResp); +BOOLEAN EDKVersion_1_05_RetrieveData (VOID); +EFI_STATUS CleanNotificationQueue (VOID); +//--------------------------------------------------------------------------- +// Function Implementation +//--------------------------------------------------------------------------- + +// +//---------------------------------------------------------------------------- +// +// Procedure: SetCallBackControlInfo +// +// Description: Set the variable inforamtion +// +// Parameter: EFI_HANDLE VarHandle - Variable handle to process +// UINT32 VarIndex - Variable index in the gVariables->VariableList +// +// Return value:VOID +//---------------------------------------------------------------------------- +// +VOID SetCallBackControlInfo(EFI_HANDLE VarHandle, UINT32 VarIndex) +{ + static int ContextVar=0; + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Entering SetCallBackControlInfo, HIIHandle =%x \n\n", VarHandle ); + if(VarHandle != NULL){ //If the varaible handle is valid, set handle and variable index + if(ContextVar >= BROWSERCALLBACK_MAX_ENTRIES) + { + SETUP_DEBUG_TSE ("\n[TSE] Too many nested Browser Callbacks!\n\n"); + ASSERT (0); + } + gCurrVarHandle = VarHandle; + gCurrVarIndex = VarIndex; + //EIP-147816 + //Use Stack to manage gCurrVarHandle and gCurrVarIndex + gCallBackHandleStack[ContextVar] = gCurrVarHandle; + gCallBackVarIndexStack[ContextVar] = gCurrVarIndex; + ContextVar++; + + } else{ //Else reset global the varaible handle and variable index + + if(ContextVar == 0) + return; + + ContextVar--; + + if(ContextVar == 0) + { + gCurrVarHandle = (EFI_HANDLE)NULL; + gCurrVarIndex = 0; + }else{ + //EIP-147816 + //Reset gCurrVarHandle and gCurrVarIndex to previous stack entry + gCurrVarHandle = gCallBackHandleStack[ContextVar-1] ; + gCurrVarIndex = gCallBackVarIndexStack[ContextVar-1] ; + } + + } + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Exiting SetCallBackControlInfo HIIHandle =%x \n\n", VarHandle ); +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: InstallFormBrowserProtocol +// +// Description: Install FormBrowser Protocol +// +// Parameter: EFI_HANDLE Handle +// +// Return value:EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS InstallFormBrowserProtocol(EFI_HANDLE Handle) +{ + EFI_STATUS status = EFI_SUCCESS; + + UnInstallFormBrowserProtocol(Handle); + status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiFormBrowser2ProtocolGuid, + &FormBrowser2, + NULL + ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: UnInstallFormBrowserProtocol +// +// Description: UnInstall FormBrowser Protocol +// +// Parameter: EFI_HANDLE Handle +// +// Return value:VOID +//---------------------------------------------------------------------------- +// +VOID UnInstallFormBrowserProtocol(EFI_HANDLE Handle) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_HANDLE handle; + VOID *iface; + UINTN size = 0; + + status = gBS->LocateHandle ( + ByProtocol, + &gEfiFormBrowser2ProtocolGuid, + NULL, + &size, + &handle + ); + if(status == EFI_BUFFER_TOO_SMALL) + { + handle = EfiLibAllocateZeroPool(size); + if (handle == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + status = gBS->LocateHandle ( + ByProtocol, + &gEfiFormBrowser2ProtocolGuid, + NULL, + &size, + &handle + ); + } + + if(EFI_ERROR(status)) + { + goto DONE; + } + status = gBS->LocateProtocol ( + &gEfiFormBrowser2ProtocolGuid, + NULL, + &iface + ); + if(EFI_ERROR(status)) + { + goto DONE; + } + status = gBS->UninstallMultipleProtocolInterfaces ( + handle, + &gEfiFormBrowser2ProtocolGuid, + iface, + NULL + ); + + if(EFI_ERROR(status)) + { + goto DONE; + } + +DONE: + return; +} + +// +//--------------------------------------------------------------------------- +// Procedure: SendForm +// +// Description: This is the routine which an external caller uses to direct +// the browser where to obtain it's information. +// +// Input: EFI_FORM_BROWSER2_PROTOCOL *This - The Form Browser protocol instanse. +// EFI_HII_HANDLE *Handles - A pointer to an array of Handles. If +// HandleCount > 1 we display a list of the formsets for the +// handles specified. +// UINTN HandleCount - The number of Handles specified in Handle. +// EFI_GUID *FormSetGuid [OPTIONAL] - This field points to the EFI_GUID +// which must match the Guid field in the EFI_IFR_FORM_SET +// op-code for the specified forms-based package. If +// FormSetGuid is NULL, then this function will display the +// first found forms package. +// UINT16 FormId [OPTIONAL] - This field specifies which EFI_IFR_FORM +// to render as the first displayable page. If this field has +// a value of 0x0000, then the forms browser will render the +// specified forms in their encoded order. +// EFI_SCREEN_DESCRIPTOR *ScreenDimenions [OPTIONAL] - Points to +// recommended form dimensions, including any non-content +// area, in characters. This allows the browser to be called +// so that it occupies a portion of the physical screen +// instead of dynamically determining the screen dimensions. +// EFI_BROWSER_ACTION_REQUEST *ActionRequest [OPTIONAL] - Points to +// the action recommended by the form. +// +// Output: EFI_STATUS status - EFI_SUCCESS, The function completed successfully. +// EFI_INVALID_PARAMETER - One of the parameters has an invalid value. +// EFI_NOT_FOUND - No valid forms could be found to display. +//--------------------------------------------------------------------------- +// +EFI_STATUS +EFIAPI +SendForm ( + IN CONST EFI_FORM_BROWSER2_PROTOCOL *This, + IN EFI_HII_HANDLE *Handles, + IN UINTN HandleCount, + IN EFI_GUID *FormSetGuid, OPTIONAL + IN UINT16 FormId, OPTIONAL + IN CONST EFI_SCREEN_DESCRIPTOR *ScreenDimensions, OPTIONAL + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest OPTIONAL + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN i; + BOOLEAN BackUpgEnterSetup = FALSE; + +#if !SETUP_FORM_BROWSER_SUPPORT + SETUP_DEBUG_TSE ("[TSE] SendForm not supported with SETUP_FORM_BROWSER_SUPPORT token disabled\n"); + return EFI_UNSUPPORTED; +#endif + + if(gApp != NULL || gSetupContextActive) + { + // Inside Setup. Setupdata contexts valid. + UINT8 Sel=0; + + AMI_POST_MANAGER_PROTOCOL *PostMgr = NULL; + + Status = gBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL,(void**) &PostMgr); + if(Status == EFI_SUCCESS) + { + //PostManagerDisplayMsgBox (L"SendForm Unsupported",L"SendForm Not suppored Nestedly or from Valid Setup Context!",MSGBOX_TYPE_OK,&Sel); + PostMgr->DisplayMsgBox( L"SendForm Unsupported", L"SendForm Not suppored Nestedly or from Valid Setup Context!", MSGBOX_TYPE_OK,NULL); + } + return EFI_UNSUPPORTED; + } + + if( Handles == NULL || HandleCount == 0 ) + { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + +#ifndef STANDALONE_APPLICATION + if ( ! gConsoleControl ) + { + //All necessary protocols are not available yet. + //We can still proceed if Uga Draw is the only protocol not available yet. + ActivateApplication(); + + if (!IsDelayLogoTillInputSupported()) //EIP-75236 + ActivateInput(); + } +#endif + + //Initialize send form global variables + if(HandleCount) + { + gSfHandles = EfiLibAllocateZeroPool( HandleCount * sizeof(VOID*)); + gSfHandleCount = 0; + gFSetGuid = FormSetGuid; + for(i=0;iRaiseTPL( EFI_TPL_HIGH_LEVEL ); // guarantees that RestoreTPL won't ASSERT + gBS->RestoreTPL( EFI_TPL_APPLICATION ); + + StyleUpdateVersionString(); + + //Show forms + Status = gST->ConIn->Reset( gST->ConIn, FALSE ); + BackUpgEnterSetup = gEnterSetup; //EIP-175017 + if (gKeyTimer) + { + TimerStopTimer( &gKeyTimer ); + } + Status = MainSetupLoopHook();//EIP74591 : Modified MainSetupLoop as board module hook + gEnterSetup = BackUpgEnterSetup; + + //Reset send form global variables + //gSfHandles = (VOID**)NULL; + MemFreePointer( (VOID**)&gSfHandles ); + gSfHandles = NULL; + + gSfHandleCount = 0; + gSfNvMap = NULL; + +DONE: + + if(gRequireSysReboot){ //EIP 75567 : If system reboot was set, return ACTION_REQUEST_RESET + if(ActionRequest) + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET; + gRequireSysReboot = FALSE; //EIP 75567 :Reset system reboot variable + } + if(gPackUpdatePending) //If IFR notifications are pending clear the queue before exiting SendForm + { + CleanNotificationQueue(); + } + gPackUpdatePending = FALSE; + CleanTempNvramVariableList();//EIP 76381 : Reset to read the variable from NVRAM + return Status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: BrowserCallback +// +// Description: This function is called by a callback handler to retrieve +// uncommitted state data from the browser. +// +// Input: +// IN CONST EFI_FORM_BROWSER2_PROTOCOL *This - A pointer to the +// EFI_FORM_BROWSER2_PROTOCOL instance. +// IN OUT UINTN *ResultsDataSize - A pointer to the size of the +// buffer associated with ResultsData. +// IN OUT EFI_STRING ResultsData - A string returned from an IFR +// browser or equivalent. The results string will have no +// routing information in them. +// IN BOOLEAN RetrieveData - A BOOLEAN field which allows an agent +// to retrieve (if RetrieveData = TRUE) data from the +// uncommitted browser state information or set +// (if RetrieveData = FALSE) data in the uncommitted browser +// state information. +// IN CONST EFI_GUID *VariableGuid, OPTIONAL - An optional field to +// indicate the target variable GUID name to use. +// IN CONST CHAR16 *VariableName OPTIONAL - An optional field to +// indicate the target human-readable variable name. +// +// Output: EFI_STATUS status - EFI_SUCCESS, The results have been distributed +// or are awaiting distribution. +// EFI_BUFFER_TOO_SMALL, The ResultsDataSize +// specified was too small to contain the results data. +//--------------------------------------------------------------------------- +// +EFI_STATUS +EFIAPI +BrowserCallback ( + IN CONST EFI_FORM_BROWSER2_PROTOCOL *This, + IN OUT UINTN *ResultsDataSize, + IN OUT EFI_STRING ResultsData, + IN BOOLEAN RetrieveData, + IN CONST EFI_GUID *VariableGuid, OPTIONAL + IN CONST CHAR16 *VariableName OPTIONAL + ) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + VARIABLE_INFO *varInfo = NULL; + BOOLEAN found; + CHAR16 *configResp = NULL; + CHAR16 *strPtr = NULL; + CHAR16 *configHdr = NULL; + UINT8 *buffer = NULL; + UINTN bufferSize; + UINTN size = 0; + UINTN length = 0; + UINT32 varIndex = 0; + UINT32 index = 0; + UINT16 CurrentBootOption = 0; + + if((gBrowserCallbackEnabled == FALSE) && (gEnableDrvNotification == FALSE)) { //Allow Browser callback for AMI ExecuteCallback/AccessConfig/RouteConfig calls + status = EFI_UNSUPPORTED; + goto DONE; + } + + if(ResultsDataSize == NULL || (*ResultsDataSize && ResultsData == NULL)) + { + status = EFI_INVALID_PARAMETER; + goto DONE; + } + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Entering BrowserCallback()\n\n" ); + + // + // Find target storage + // + if(VariableGuid != NULL) + { + // + // Try to find target storage + // + found = FALSE; + for(index = 0; index < gVariables->VariableCount; index++) + { + varInfo = (VARIABLE_INFO *)VarGetVariableInfoIndex(index); + //EIP-75352 Suppress the warnings from static code analyzer + if(NULL == varInfo){ + continue; + } + if(EfiCompareGuid(&varInfo->VariableGuid, (EFI_GUID *)VariableGuid)) + { + if(((varInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_EFI_VARSTORE) != VARIABLE_ATTRIBUTE_EFI_VARSTORE) && + ((varInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE) != VARIABLE_ATTRIBUTE_NAMEVALUE)) + { + // + // Buffer storage require both GUID and Name + // + if (VariableName == NULL) + { + status = EFI_NOT_FOUND; + goto DONE; + } + + if (EfiStrCmp (varInfo->VariableName, (CHAR16 *)VariableName) == 0) + { + found = TRUE; + varIndex = index; + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Comparing gCurrVarHandle = %x to variableHandle %x\n\n", gCurrVarHandle, varInfo->VariableHandle ); + if (varInfo->VariableHandle == gCurrVarHandle) //Checking for same variable names for two different handles, if match not found continue with default + { + break; + } + } + } + } + } + + if (!found) + { + status = EFI_NOT_FOUND; + goto DONE; + } + else //If gCurrVarHandle is not matched then varInfo will have last index data so again filling VarInfo + { + //Updating the varinfo with the varIndex + varInfo = (VARIABLE_INFO *)VarGetVariableInfoIndex(varIndex); + } + } else + { + // GUID/Name is not specified, store variable index + varIndex = gCurrVarIndex; + varInfo = (VARIABLE_INFO *)VarGetVariableInfoIndex(varIndex); + } + //EIP-75352 Suppress the warnings from static code analyzer + if (NULL == varInfo){ + goto DONE; + } + + + if((varInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_EFI_VARSTORE) == VARIABLE_ATTRIBUTE_EFI_VARSTORE) + { + status = EFI_INVALID_PARAMETER; + goto DONE; + } + + // + // Retrive NVRam Buffer + // + buffer = (UINT8 *)VarGetVariable(varIndex, &size); + if(buffer == NULL) + { + goto DONE; + } + + // + // Generate + // + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] GetConfigHeader()\n" ); + status = GetConfigHeader(varInfo, &configHdr, &length); + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] GetConfigHeader retuned, status = 0x%x \n\n" , status ); + if(EFI_ERROR(status) || (NULL == configHdr))//EIP-75384 Static code + { + goto DONE; + } + + if(RetrieveData) + { + // + // Generate + // + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] _StorageToConfigResp()\n" ); + status = _StorageToConfigResp(varInfo, buffer, configHdr, &configResp); + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] _StorageToConfigResp returned, status = 0x%x \n\n" , status ); + if (EFI_ERROR(status)) + { + goto DONE; + } + + // + // Skip and '&' to point to + // + if (EDKVersion_1_05_RetrieveData ()) + { + strPtr = configResp + EfiStrLen (configHdr) + 1; + } + else + { + strPtr = configResp; + } + bufferSize = EfiStrSize (strPtr); + if (*ResultsDataSize < bufferSize) + { + *ResultsDataSize = bufferSize; + + // gBS->FreePool (configResp); + status = EFI_BUFFER_TOO_SMALL; + goto DONE; + } + + *ResultsDataSize = bufferSize; + EfiCopyMem (ResultsData, strPtr, bufferSize); + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Displaying Retrieve Data Buffer, VariableName: %s, VariableHandle: 0x%x\n\n", varInfo->VariableName, varInfo->VariableHandle ); + +#if TSE_DEBUG_MESSAGES + DebugShowBufferContent(bufferSize, ResultsData); +#endif + + //gBS->FreePool(configResp); + } else + { + // + // Prepare + // + +#if TSE_DEBUG_MESSAGES + { + CHAR16 BrowserCallbackFilename[50]; + CHAR16 BrowserCallbackContent[200]; + CHAR16 *BrowserCallbackBuffer = NULL ; + UINTN Len=0; + + + SPrint(BrowserCallbackFilename,50,L"BROWSERCALLBACK_%s_%03d.txt", varInfo->VariableName, HpkFileCount); + SPrint(BrowserCallbackContent, 200, L"VariableName: %s\nVariableGuid: %g\nResultsDataSize: 0x%x\n", VariableName, &VariableGuid, *ResultsDataSize); + Len = (EfiStrLen (BrowserCallbackContent) + EfiStrLen (ResultsData) + 1) * sizeof (CHAR16); + BrowserCallbackBuffer = EfiLibAllocateZeroPool (Len); + + if (BrowserCallbackBuffer != NULL) + { + EfiStrCpy (BrowserCallbackBuffer, BrowserCallbackContent); + EfiStrCat (BrowserCallbackBuffer, ResultsData); + + status = WriteDataToFile(BrowserCallbackFilename, BrowserCallbackBuffer, Len,0) ;//EIP-123312 resolve build issue + if (!EFI_ERROR (status)) + { + HpkFileCount++ ; + } + + MemFreePointer(&BrowserCallbackBuffer); + } + } +#endif + + + bufferSize = (EfiStrLen (ResultsData) + EfiStrLen (configHdr) + 2) * sizeof (CHAR16); + configResp = EfiLibAllocateZeroPool (bufferSize); + ASSERT (configResp != NULL); + + EfiStrCpy (configResp, configHdr); + EfiStrCat (configResp, L"&"); + EfiStrCat (configResp, ResultsData); + + // + // Update Browser uncommited data + // + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] _ConfigRespToStorage()\n" ); + status = _ConfigRespToStorage (varInfo, &buffer, &size, configResp); + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] _ConfigRespToStorage returned, status = 0x%x \n\n" , status ); + + if (EFI_ERROR (status)) + { + goto DONE; + } + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Displaying Browser Uncommited Data Buffer, VariableName: %s, VariableHandle: 0x%x\n\n", varInfo->VariableName, varInfo->VariableHandle ); + +#if TSE_DEBUG_MESSAGES + DebugShowBufferContent(size, buffer); +#endif + + SETUP_DEBUG_UEFI_CALLBACK ( "\n[TSE] Updating Browser Uncommited Data\n" ); + if (varIndex == VARIABLE_ID_BBS_ORDER) + { + if(gCurrLegacyBootData) + { + UINT16 CurLegBootDataValid = 0; + UINT32 i; + for (i = 0; i < gBootOptionCount; i++ ) + { + if ( &gBootData[i] == gCurrLegacyBootData ) + CurLegBootDataValid = 1; + } + if(CurLegBootDataValid) + CurrentBootOption = gCurrLegacyBootData->Option; + else + gCurrLegacyBootData = NULL; + } + gCurrLegacyBootData = BootGetBootData(CurrentBootOption); + if(gCurrLegacyBootData) + status = VarSetValue(varIndex, 0, size, buffer); + } + else + status = VarSetValue(varIndex, 0, size, buffer); + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Updating Browser Uncommited Data returned, status = 0x%x \n\n" , status ); + } +DONE: +//MEMFREE + if(configResp) + { + MemFreePointer(&configResp); + } + + if(buffer) + { + MemFreePointer(&buffer); + } + + if(configHdr) + { + MemFreePointer(&configHdr); + } + + SETUP_DEBUG_UEFI_CALLBACK ( "\n[TSE] Exiting BrowserCallback(), status = 0x%x \n\n" , status ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _StorageToConfigResp +// +// Description: +// +// Parameter: VARIABLE_INFO *VariableInfo +// VOID *Buffer +// CHAR16 *ConfigHdr +// CHAR16 **ConfigResp +// +// Return value:EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _StorageToConfigResp(VARIABLE_INFO *VariableInfo, VOID *Buffer, CHAR16 *ConfigHdr, CHAR16 **ConfigResp) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_STRING Progress; + CHAR16 *configHdr = NULL; + UINTN length = 0; + + length = EfiStrLen(ConfigHdr) * sizeof(CHAR16); + configHdr = (CHAR16*)EfiLibAllocateZeroPool(length + 2); + if(configHdr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + MemCopy(configHdr, ConfigHdr, length); + + // + // Generate + // + status = GetBlockName(&configHdr, &length, VAR_ZERO_OFFSET, VariableInfo->VariableSize); + if(EFI_ERROR(status)) + { + goto DONE; + } + + if((VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE) == VARIABLE_ATTRIBUTE_NAMEVALUE) + { + status = EFI_UNSUPPORTED; + goto DONE; + }else + { + // + // VARIABLE_ATTRIBUTE_VARSTORE + // + status = HiiInitializeProtocol(); + if(EFI_ERROR(status)) + { + goto DONE; + } + + status = gHiiConfigRouting->BlockToConfig(gHiiConfigRouting, configHdr, Buffer, + VariableInfo->VariableSize, ConfigResp, &Progress); + } + +DONE: + if(configHdr) //EIP81617 + { + MemFreePointer(&configHdr); + } + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _ConfigRespToStorage +// +// Description: +// +// Parameter: VARIABLE_INFO *VariableInfo +// VOID **Buffer +// UINTN *Size +// EFI_STRING ConfigResp +// +// Return value:EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _ConfigRespToStorage(VARIABLE_INFO *VariableInfo, UINT8 **Buffer, UINTN *Size, EFI_STRING ConfigResp) +{ + EFI_STATUS status = EFI_SUCCESS; + + if((VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE) == VARIABLE_ATTRIBUTE_NAMEVALUE) + { + status = EFI_UNSUPPORTED; + goto DONE; + }else + { + EFI_STRING stringPtr = NULL; + EFI_STRING tempPtr = NULL; + UINTN length = 0; + UINT16 *sizeBuf = NULL; + + stringPtr = ConfigResp; + // + // Get Buffer data Size + // + for(stringPtr = ConfigResp; *stringPtr != 0 && EfiStrnCmp(stringPtr, L"&WIDTH=", EfiStrLen(L"&WIDTH=")) != 0; stringPtr++); + stringPtr += EfiStrLen(L"&WIDTH="); + tempPtr = stringPtr; + for(; *stringPtr != 0 && EfiStrnCmp(stringPtr, L"&VALUE=", EfiStrLen(L"&VALUE=")) != 0; length++, stringPtr++); + sizeBuf = (CHAR16*)EfiLibAllocateZeroPool(length + 1); + if(sizeBuf == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + EfiCopyMem(sizeBuf, tempPtr, length); + status = GetHexStringAsBuffer(Buffer, sizeBuf); + MemFreePointer(&sizeBuf); + if(EFI_ERROR(status)) + { + *Size = 0; + goto DONE; + } + // + // Get Buffer Data + // + for(; *stringPtr != 0 && EfiStrnCmp(stringPtr, L"&VALUE=", EfiStrLen(L"&VALUE=")) != 0; stringPtr++); + stringPtr += EfiStrLen(L"&VALUE="); + status = GetHexStringAsBuffer(Buffer, stringPtr); + } + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure : FormBrowserHandleValid +// +// Description : return True Browser is showing forms from SendForm interface. +// +// Input : none +// +// Output : BOOLEAN +// +//---------------------------------------------------------------------------- +// +BOOLEAN FormBrowserHandleValid(VOID) +{ +#if SETUP_FORM_BROWSER_SUPPORT + if(gSfHandles) + return TRUE; +#endif + return FALSE; +} + +// +//---------------------------------------------------------------------------- +// Procedure : FormBrowserLocateSetupHandles +// +// Description : return Handles and count that is passed to SendForm interface. +// +// Input : OUT handleBuffer and count +// +// Output : Status +// +//---------------------------------------------------------------------------- +// +EFI_STATUS FormBrowserLocateSetupHandles(VOID* **handleBuffer,UINT16 *count) +{ + EFI_STATUS status = EFI_SUCCESS; + +#if SETUP_FORM_BROWSER_SUPPORT + if(gSfHandles) + { + *handleBuffer = (VOID**)gSfHandles; + *count = (UINT16)gSfHandleCount; + } + else + { + status = EFI_NOT_FOUND; + } +#else + status = EFI_UNSUPPORTED; +#endif + return status; +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/EDK/MiniSetup/uefi2.1/FormBrowser2.h b/EDK/MiniSetup/uefi2.1/FormBrowser2.h new file mode 100644 index 0000000..1ba0808 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/FormBrowser2.h @@ -0,0 +1,156 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (C)Copyright 2004, American Megatrends, Inc. **// +//** **// +//** All Rights Reserved. **// +//** **// +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **// +//** **// +//** Phone (770)-246-8600 **// +//** **// +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +// $Archive: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/FormBrowser2.h $ +// +// $Author: Arunsb $ +// +// $Revision: 9 $ +// +// $Date: 10/18/12 6:04a $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/FormBrowser2.h $ +// +// 9 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 4 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 8 9/17/12 6:22a Rajashakerg +// Updated EIP changes for 2.16 release. +// +// 6 9/08/12 3:53p Premkumara +// [TAG] EIP 100546 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Old core(such as 4.6.4.0) is not building successfully with +// latest TSE +// [RootCause] BROWSER_ACTION related request macro are not defined in +// TSE +// [Solution] Defined BROWSER_ACTION related request macros in +// FormBrowser2.h +// [Files] FormBrowser2.h +// +// 5 12/07/11 8:13a Rajashakerg +// [TAG] EIP75118 +// [Category] Improvement +// [Description] xtractConfig() fail since BrowserCallback() cannot find +// the variable to process +// [Files] FormBrowser2.c, FormBrowser2.h, HiiCallback.c, +// Uefi21Wapper.c, PopupSel.c +// +// 4 4/16/10 5:13p Madhans +// Changes for Tse 2.02. Please see Changelog.log for more details. +// +// 3 2/19/10 8:50p Madhans +// +// 1 7/24/09 6:54p Presannar +// +// 2 4/14/09 12:36p Presannar +// Added Fn prototype FormBrowserLocateSetupHandles and +// FormBrowserHandleValid +// +// 1 1/09/09 2:38p Presannar +// UEFI 2.1 Hii Related Code - Initial Drop +// +// 1 12/29/08 4:46p Presannar +// FormBrowser2 protocol Send Form and BrowserCallback initial draft +// +//************************************************************************* +// +// +// Name: FormBrowser2.h +// +// Description: +// +// +//************************************************************************* + +//---------------------------------------------------------------------------- +#ifndef _FORM_BROWSER2_H +#define _FORM_BROWSER2_H +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +#include "Minisetup.h" +#include EFI_PROTOCOL_DEFINITION (FormBrowser2) +//---------------------------------------------------------------------------- +//Added for UEFI spec. 2.3 compatibility- EIP-100546 Start +#ifndef EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT +#define EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT 4 +#endif + +#ifndef EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT +#define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT 5 +#endif + +#ifndef EFI_BROWSER_ACTION_REQUEST_FORM_APPLY +#define EFI_BROWSER_ACTION_REQUEST_FORM_APPLY 6 +#endif + +#ifndef EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD +#define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD 7 +#endif +//Added for UEFI spec. 2.3 compatibility- EIP-100546 End +VOID SetCallBackControlInfo(EFI_HANDLE VarHandle, UINT32 VarIndex); + +EFI_STATUS InstallFormBrowserProtocol(EFI_HANDLE Handle); +VOID UnInstallFormBrowserProtocol(EFI_HANDLE Handle); + +EFI_STATUS +EFIAPI +SendForm ( + IN CONST EFI_FORM_BROWSER2_PROTOCOL *This, + IN EFI_HII_HANDLE *Handles, + IN UINTN HandleCount, + IN EFI_GUID *FormSetGuid, OPTIONAL + IN UINT16 FormId, OPTIONAL + IN CONST EFI_SCREEN_DESCRIPTOR *ScreenDimensions, OPTIONAL + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest OPTIONAL + ); + +EFI_STATUS +EFIAPI +BrowserCallback ( + IN CONST EFI_FORM_BROWSER2_PROTOCOL *This, + IN OUT UINTN *ResultsDataSize, + IN OUT EFI_STRING ResultsData, + IN BOOLEAN RetrieveData, + IN CONST EFI_GUID *VariableGuid, OPTIONAL + IN CONST CHAR16 *VariableName OPTIONAL + ); + +EFI_STATUS FormBrowserLocateSetupHandles(VOID* **handleBuffer,UINT16 *count); +BOOLEAN FormBrowserHandleValid(VOID); + +#endif /* #define _FORM_BROWSER2_H */ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2010, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/EDK/MiniSetup/uefi2.1/Hii.c b/EDK/MiniSetup/uefi2.1/Hii.c new file mode 100644 index 0000000..d648b80 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/Hii.c @@ -0,0 +1,3557 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (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/Uefi2.1/Hii.c $ +// +// $Author: Premkumara $ +// +// $Revision: 59 $ +// +// $Date: 9/05/14 2:40p $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/Hii.c $ +// +// 59 9/05/14 2:40p Premkumara +// Moved GetSetDefaultsFromControlPtr() function from Uefi2.1\Hii.c to +// TseAdvanced.c +// +// 58 8/28/14 12:35p Premkumara +// [TAG] EIP175492 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Refresh_ID is not working in for static and dynamic +// controls +// [RootCause] RefreshGroupOnCallBack was not getting called after +// signaling the RefreshId Event due to incorrect RefreshEventGroupId +// [Solution] Assigning correct RefreshEventGroupId to the RefreshId +// Event so that RefreshGroupOnCallBack will get called after signaling +// the Event +// [Files] Hii.c +// +// 57 8/28/14 6:51a Premkumara +// [TAG] EIP93340 +// [Category] Improvement +// [Description] - Defaults can be given to string type controls using tag +// "Default = STRING_TOKEN(STR_DEFAULT_STRING)". +// - New token TSE_SUPPORT_DEFAULT_FOR_STRING_CONTROL is introduced for +// this support. +// - Enabling this TSE_SUPPORT_DEFAULT_FOR_STRING_CONTROL token will +// display default string mention in setup. +// - On loading optimal defaults also string will load default mentioned +// in default value tag. +// [Files] AMITSE.sdl, HiiString21.c, TseAdvanced.c, MiniSetupExt.c, Hii.c +// +// 56 5/02/14 12:44a Arunsb +// [TAG] EIP150526 +// [Category] Bug Fix +// [Severity:] Important +// [Symptom:] TSE hangs on disconnecting and connecting the RAID driver +// [Root Cause] Process pack updated on processing the existing pack +// update +// [Solution] First we getting remove and new pack. +// On getting this TSE starts processing the pack(ProcessPackNotification) +// but on processing the pack itself we getting notification again for +// remove and add. +// So again process pack happens inside notification +// itself(IFRChangeNotifyFn), this processing should not happen inside +// notification so enabled flag gEnableProcessPack in PageHandleAction. +// [Files] hii.c, minisetupext.c and page.c +// +// 55 2/11/14 8:53p Arunsb +// [TAG] EIP132359 +// [Category] Bug Fix +// [Root Cause] The ParentPageID in the destination page of the Ref3 +// control is not updated. +// [Solution] In the function UpdateIFRRefXControls, +// update the ParentPageID in the destination page of the Ref3 control. +// [Files] hii.c +// +// 54 12/04/13 2:54a Premkumara +// [TAG] EIP139099 +// [Category] New Feature +// [Description] Supress formset other than +// EFI_HII_PLATFORM_SETUP_FORMSET_GUID and +// EFI_HII_DRIVER_HEALTH_FORMSET_GUID through elink based on token +// [Files] AMITSE.sdl, AMITSE.mak, CommonOem.c, Hii.c, Parse.c, +// TseUefiHii.h +// +// 53 6/10/13 12:10p Arunsb +// EIP122907. Refresh opcode event stopped when its pack removed +// +// 52 5/22/13 10:57a Arunsb +// Read write opcodes variable number retrieved in special way using +// GetRWVariableID function. +// +// 51 5/21/13 1:31a Arunsb +// [TAG] EIP122350 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Setup hangs on first goto after entering from Shell twice +// [RootCause] HiiExit not happened for all the cases so offsets behaved +// abruptly +// [Solution] HiiExit invoked for all the possible cases +// [Files] Hii.c +// +// 50 4/18/13 5:56a Arunsb +// [TAG] EIP105468 +// [Category] New Feature +// [Description] Support for EFI_IFR_REFRESH_ID opcode for Offline +// +// 49 4/17/13 2:57p Arunsb +// [TAG] EIP109812, 107774 +// [Category] Improvement +// [Description] Provide support for EFI_IFR_TYPE_REF and EFI_IFR_REF5 +// [Files] Hii.c, HiiCallback.c, Parse.c and TseUefiHii.h +// +// 48 4/16/13 9:40a Arunsb +// Missed HII structures added in TSE itself. +// +// 47 4/02/13 8:08a Arunsb +// [TAG] EIP113919, EIP114842 +// [Category] Improvement +// [Description] Provide support for EFI_IFR_WRITE, EFI_IFR_READ, +// EFI_IFR_GET, EFI_IFR_SET and EFI_IFR_MAP_OP. +// [Files] Setupdata.h, ctrlcond.c, expression.c, hii.c and parse.c +// +// 46 3/25/13 8:06a Premkumara +// [TAG] EIP105468 +// [Category] New Feature +// [Description] Support for EFI_IFR_REFRESH_ID opcode for Offline +// Parsing +// [Files] Parse.c, Hii.c, Setupdata.h +// +// 45 2/25/13 10:57a Blaines +// [TAG] - EIP 104273 +// [Category] - Action Item +// [Description] - Provide ability to dump the Hii Pack from the Setup as +// part TSE debug Infrastructure. It should dump the Pack updates on Hii +// notification also. +// So it can be used to debug the issue. +// [Files] - ForBrowser2.c, Hii.c, HiiNotificationHandler.c, +// UefiWapper.c, TseUefiHii.h +// +// 44 11/09/12 2:33a Arunsb +// EIP 105965 : No. of root pages can be more than hii handle because of +// AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST_SUPPORT +// +// 43 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 21 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 41 9/18/12 2:14a Rajashakerg +// [TAG] EIP88658 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Minisetup crashes after controller reconnection during Hii +// callback +// [RootCause] Minisetup crashes after controller reconnection during +// callback. since we have new packs and new handles. +// [Solution] Additional checks for invalid ptrs were added +// [Files] Hii.c, Parse.c, Uefi21Wapper.c +// +// 40 9/17/12 6:22a Rajashakerg +// Updated EIP changes for 2.16 release. +// +// 38 9/08/12 11:42a Arunsb +// [TAG] EIP99059 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] _ReInitializeSetupdataPointers function crashes in Hii.C +// when DyanmicPage processed with PageIdListSize =0 +// [RootCause] Hii pack notification installed for +// SETUP_RUNTIME_IFR_PROCESSING is disabled also +// [Solution] Hii pack notification installed only if +// SETUP_RUNTIME_IFR_PROCESSING is enabled +// [Files] commonhelper.c and Hii.c +// +// 37 5/29/12 4:44a Arunsb +// [TAG] EIP91109 +// [Category] Improvement +// [Description] Sync the Aptio IV source for AptioV +// +// 36 5/28/12 11:14a Premkumara +// [TAG] EIP83080 +// [Category] Improvement +// [Description] Support REF4 type control. +// [Files] TseDrvHealth.h, Hii.c +// +// 35 5/27/12 3:29a Arunsb +// [TAG] EIP90809 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Setup hang +// [RootCause] gFailsafeDefaults memory corruption between +// _MergeVariableListAndInfo and TseVarBuildAMIDefaults +// [Solution] Removed the memory corruption +// [Files] Hii.c +// +// 34 2/03/12 4:49a Rajashakerg +// Defaults not saved for special variables. +// +// 33 12/07/11 3:11p Arunsb +// [TAG] EIP75588 +// [Category] New Feature +// [Description] Support for queuing UpdatePack notifications +// [Files] frame.c, page.c, formbrowser2.c, hii.c, hiicallback.c, +// hiinotificationhandler.c, tseuefihii.h and uefi21wapper.c +// +// 32 12/05/11 5:51a Rajashakerg +// [TAG] EIP76381 +// [Category] Improvement +// [Description] Performance: Improving variable data load and usage +// [Files] callback.c, minisetupext.c, variable.c, variable.h, +// minisetup.h, Hii.c, FormBrowser2.c +// +// 31 11/30/11 1:36p 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 +// +// 30 11/30/11 6:36a Premkumara +// [TAG] EIP71351 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Setup Crash when iSCSI is loaded +// [RootCause] Aptio giving length as 0xe(matches size of +// EFI_IFR_ONE_OF_OPTION) but in latest EDKII driver it is 0x1c. +// [Solution] change the length as j += ((EFI_IFR_OP_HEADER*)(buff + i + +// j))->Length; +// [Files] Parse.c, Hii.c, Variable.c, Minisetupext.c, +// +// 29 11/28/11 2:23a Premkumara +// [TAG] EIP75384 +// [Category] Improvement +// [Description] Suppress the warnings from static code analyzer +// [Files] UefiWapper.c, Hii.c, Expression.c, CtrlCond.c, PopupSel.c, +// Minisetupext.c, Menu.c, Date.c, Ezport\Stylecommon.c, +// EzportPlus\StyleCommon.c, +// +// 28 11/22/11 1:00p Arunsb +// EIP72540 offline pages not included in run time parsing. Extra +// provision provided to hide particular page. But this needs +// customization. +// +// 27 11/14/11 2:43p Blaines +// [TAG] - EIP 75481 +// [Category]- Function Request +// [Synopsis]- TSE debug print infrastructure. +// [Description]- Add TSE debug print info for basic functions such as +// Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms +// data. +// [Files] +// AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c +// Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c, +// HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h, +// Uefi21Wrapper.c, setupdbg.h +// +// 26 11/14/11 4:22a Arunsb +// [TAG] EIP72540 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Advance page disappear on using 4.6.2_TSE_2_14_1219 +// [RootCause] Offline pages also considered in dynamic parsing +// [Solution] Offline pages are not considered in dynamic parsing +// [Files] hii.c and parse.c. +// +// 25 7/19/11 10:50a Blaines +// [TAG] - EIP 63262 +// [Category]- Defect +// [Symptom]- Setup page display problem on rose city. +// When SETUP_GROUP_DYNAMIC_PAGES is enabled and Network Stack is enabled, +// the "iSCSI" menu is listed as a dynamic page in advanced menu but only +// 3 of 4 "Port Configuration" pages shows up. The TSE dynamic page count +// is incorrect. +// +// [Solution]- In the functions (RTIfrProcessRunTimeForms, +// HandleNewIFRPack, HandleRemoveIFRPack, HandleAddIFRPack), make sure the +// nvram cache is updated by calling +// VarUpdateVariable(VARIABLE_ID_DYNAMIC_PAGE_COUNT) when updating +// "DynamicPageCount" variable name. +// . +// [Files] - Hii.c, Minisetup.h, Variable.h +// +// 24 7/01/11 3:27a Arunsb +// Removed unwanted header for chm file creation. +// +// 23 6/30/11 4:17a Arunsb +// [TAG] EIP57661 +// [Category] New Feature +// [Description] Boot manager algorithm for interaction with Driver +// Health protocol. +// Sets the driver health support variable. +// [Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni, +// commonhelper.c, uefisetup.ini, tsedrvhealth.h, +// amivfr.h, minisetupbin.mak, +// hiistring21.c, hiistring20.c, tseadvanced.c, special.c, +// special.h, boot.h, minisetup.h, +// uefi20wapper.c, formbrowser2.c, hii.c, parse.c and +// uefi21wapper.c. +// +// 22 6/28/11 8:26a Arunsb +// EIP56405: Commented the build time parsing code. +// Name value not supported by current vfr compiler. +// Uncomment the codes once vfr compiler supports it. +// +// 21 6/23/11 4:03p Rajashakerg +// [TAG] EIP55762, 58925, 59971 +// [Category] New Feature +// [Description] Support REF2,REF3 and REF4 in AMITSE +// Support direct form navigation path +// Improper layout of controls in the root page when Dynamic pages are +// added using the Legacy Setup Style +// +// [Files] setupdata.h, CommonHelper.c, AMITSE.sdl, Legacy\Legacy.c, +// Legacy\style.h, Legacy\style.h, frame.c, minisetupext.c, +// minisetupext.h, numeric.c, page.c Popupstring.c, Hii.c, +// Uefi21Wrapper.c, Parse.c Hii.c +// +// 20 6/22/11 4:47p Arunsb +// [TAG] EIP56405 +// [Category] New Feature +// [Description] Support for EFI_IFR_VARSTORE_NAME_VALUE opcode +// [Files] Hii.c, parse.c and uefi21wapper.c +// +// 19 6/20/11 10:39a Rajashakerg +// [TAG] EIP57402 +// [Category] New Feature +// [Description] Support for EFI_IFR_DEFAULT_2 opcode. +// [Files] Hii.c +// +// 18 6/01/11 5:22p Blaines +// [TAG] 61122 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] If SETUP_ORPHAN_PAGES_AS_ROOT_PAGE=1, HiiExit() will cause +// an ASSERT in pool.c if debug_mode is enabled. +// [RootCause] HiiExit() exit attempts to free gSetupData elements +// associated with orphaned forms.. +// [Solution] Only free gSetupData[i].FormSet if +// gSetupData[i].FormSetLength is non-zero. +// [Files] Hii.c +// +// 17 4/29/11 4:41p Arunsb +// For 2.13 public patch release IFR RefX feature is omitted. +// +// 14 3/28/11 5:08p Rajashakerg +// [TAG] EIP56413 +// [Category] Improvement +// [Description] TSE: Support for EFI_IFR_RESET_BUTTON opcode +// [Files] ezport.c, minisetupext.h, ResetButton.c, ResetButton.h, +// Hii.c, TseUefiHii.h, Uefi21Wapper.c, hii.h, Uefi20Wapper.c +// +// 13 2/10/11 1:44p Blaines +// [TAG] - EIP 53146 +// [Category]- New Feature +// [Modification] - Update DynamicPageCount variable on HandleNewIFRPack, +// HandleRemoveIFRPack, and HandleAddIFRPack notifications. +// +// 12 2/10/11 12:32p Blaines +// [TAG] - EIP 53146 +// [Category]- New Feature +// [Description] -Add the support to Move the Dynamic IFR Pages under +// subpages. It should be customizable to move around. +// +// 11 12/28/10 12:31p Madhans +// To update the Tag of EIp 46998. UEFI option ROM menus disappear in +// Setup when certain options are selected. +// No file changed but Comment updated right +// +// 10 12/02/10 2:38p Madhans +// [TAG] - EIP 48169 +// [Category]- Enhancement +// [Severity]- Mordarate +// [Symptom]- Code Cleanup and Compiler Warning need to resolved. +// [Rootcause] Warnings reported when we build AMI higher Warning level. +// [Solution]- 1. Fix the warnings and do the code cleanup. +// 2. Introduce proper checks. +// 3. change the popupSel.c to not change the Option/variable +// cache to default or first option +// when the variable cache is not matching with any of +// option. +// [Files] - commonoem.c bbs.c boot.c hiistring.c resource.c +// popuppassword.c popupsel.c +// expression.c hii.c parse.c +// +// 9 10/27/10 4:25p Madhans +// [TAG] EIP46998 +// [Category] Defect +// [Symptom] Some user action on PCIx with UEFI Hii Pages causes Setup +// screen pages and menu disappers. +// [RootCause] UEFI 2.1 parsing code is not handling the Removepack and +// New pack sequance properly. Normally UpdatePack +// does the removepack and AddPack. +// [Solution] UEFI 2.1 parsing code fixed to handle above case correctly. +// [Files] hii.c HiiNotificationHandler.c Parse.c TseUefiHii.h +// uefi21wapper.c +// +// 8 9/16/10 8:38p Madhans +// Update for TSE 2.10. Refer Changelog.log for more details. +// +// 18 8/12/10 1:11p Blaines +// EIP-40946 : Fix root page processing to support Award Style setup. +// +// 17 7/07/10 7:47p Madhans +// To fix the Variables when new forms dynamically added. +// +// 16 7/07/10 7:45p Madhans +// Changes to Support Adding Conditions to Suppress or Grayout the Special +// controls. +// +// 15 6/17/10 2:46p Madhans +// Fix in Classcode/Subclass finding function. +// +// 14 6/14/10 7:14p Madhans +// Dynamic parsing support +// +// 13 6/14/10 7:04p Blaines +// Fix to correctly check if FormSet length has changed and if so Parse +// it. This fixes the issue with duplicate ClassID and SubClassID. +// +// 12 3/11/10 5:42p Madhans +// Coding Standards Update +// +// 11 2/19/10 8:39p Madhans +// +// 10 2/19/10 8:35p Madhans +// Function header fix +// +// 7 1/12/10 11:12a Presannar +// Modified code to update Handle for the Variable Info referenced. +// +// 6 1/11/10 11:14a Presannar +// Get The Variable Info referenced by Control Variable +// BugFix - Remove code to set Extended Attributes +// +// 5 11/19/09 5:31p Presannar +// Updated TSE include file name to not clash with CORE file +// Added code to support Dynamic Notification +// Commented fn. HiiGetEfiKey +// +// 4 8/24/09 12:13p Madhans +// EIP 25092 : Fix to Use the HiiChangeString() to Add the string for +// morethen one langs. with the same token. +// +// 3 8/12/09 8:08a Mallikarjunanv +// moved the Hii function 'HiiGetEfiKey' from commonoem.c to hii.c +// +// 2 8/11/09 2:46p Presannar +// Renamed _HiiGetForm to HiiGetForm +// Modified HiiGetForm by moving retrieving form by ID to another function +// GetFormByFormID +// Added new fns HandleNewIFRPack, HandleRemoveIFRPack, HandleAddIFRPack +// and _FxiupNotificationData for dynamic parsing of IFR data +// Added new fn GetFormByFormID, GetNextForm for form manipulation +// Added Fns _ReInitializeSetupdataPointers to reinitialize setupdata +// pointers. +// +// 1 7/24/09 6:54p Presannar +// +// 4 4/24/09 7:53p Presannar +// Bug fixes +// +// 3 4/14/09 12:39p Presannar +// Added fn implementation for GetFormSetTitleAndHelp +// +// 2 3/31/09 4:15p Madhans +// UEFI Wrapper improvments. +// +// 1 1/09/09 2:38p Presannar +// UEFI 2.1 Hii Related Code - Initial Drop +// +// 8 10/08/08 6:42p Presannar +// Removed function PreparePackageList +// removed call to get UEFI 2.1 HII ImageProtocol +// +// 7 8/22/08 4:56p Madhans +// To skip the Formsets, thier subclass type is not +// EFI_SETUP_APPLICATION_SUBCLASS. +// fix resolve parentpageid for nested sub page that is out of order. (To +// consider case where form are refered after it is defined in the VFR). +// +// 6 8/20/08 4:51p Presannar +// Code Snippet Added to Check if a Form Pack indeed contains a Formset. +// +// 5 8/05/08 3:44p Presannar +// Updated code snippets for functions _AddVariable, HiiFixupData, +// _ParseForm, _UpdeateDefaults, _AddHpkControls. +// Added new code snippets functions _CheckAndAddVariable, +// _GetControlKeytoken, _GetControlDevicePathId, +// _UpdateVariableDevicePathId. +// +// 4 7/23/08 6:09p Presannar +// Fixed infinite loop Bug for function _IsFormFound +// +// 3 7/21/08 2:08p Madhans +// Fix to add the condition control for the first control +// +// 2 7/17/08 11:48a Madhans +// To fix the issue of the last control it is supposed. +// +// 1 6/12/08 6:40p Madhans +// Minisetup Standalone Application for UEFI 2.1 +// +//************************************************************************* +// +// +// Name: Hii.c +// +// Description: Contains Hii related Functions +// +// +//************************************************************************* + +//---------------------------------------------------------------------------- +#include "minisetup.h" +#include "TseDrvHealth.h" //EIP-83080 +#include "TseUefiHii.h" +#ifndef TSE_FOR_APTIO_4_50 +#define EFI_HII_PACKAGE_FORMS EFI_HII_PACKAGE_FORM +#include "tianohii.h" +#endif +//---------------------------------------------------------------------------- +// MACRO DEFINITIONS +//---------------------------------------------------------------------------- +#define MAX_DEV_PATH_STR_LEN 100 //EIP: 55762 + +//---------------------------------------------------------------------------- +// EXTERN VARIABLES +//---------------------------------------------------------------------------- +extern UINTN gLangCount; +extern UINTN gDynamicPageCount; +extern UINT32 gRefreshIdCount; +extern REFRESH_ID_INFO *gRefreshIdInfo; + +//---------------------------------------------------------------------------- +// VARIABLE DECLARATIONS +//---------------------------------------------------------------------------- +static SETUP_LINK *gSetupData = NULL; +static EFI_HII_HANDLE *gSetupHandles; +static EFI_HANDLE gNotifyHandle[3]; +EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *gDevPathToTextProtocol = (EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *)NULL;//EIP-83080 starts +EFI_GUID gDevPathToTextGuid = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;//EIP-83080 Ends +VOID *gFirstPageRef; +PAGE_ID_INFO *PageIdInfoPtr; +PAGE_ID_LIST *PageIdListPtr; +PAGE_INFO *PageInfoPtr; +PAGE_INFO *FirstPage; +PAGE_INFO *NewPageInfo; +PAGE_LIST *PageListPtr; +VARIABLE_LIST *VariableListPtr; +VARIABLE_INFO *VariableInfoPtr; +BOOLEAN gHiiInitialized = FALSE; +UINT32 AllocatedFirstPageSize, FirstPageOffset; +UINT32 ControlListSize, ControlListOffset; +UINT32 PageIdListSize, PageIdListOffset; +UINT32 PageIdInfoSize, PageIdInfoOffset; +UINT32 PageListSize, PageListOffset; +UINT32 PageInfoSize, PageInfoOffset; +UINT32 VariableListSize, VariableListOffset; +UINT32 VariableInfoSize, VariableInfoOffset; +UINTN TotalRootPages; +UINTN gSetupCount = 0; +EFI_GUID *gGuidDump=NULL; //EIP64253 offline vfr pages hided +UINTN gGuidDumpCount=0; + +//---------------------------------------------------------------------------- +// FUNCCTION DECLARATIONS +//---------------------------------------------------------------------------- +EFI_HII_HANDLE *_HiiGetHandles (UINT16 *NumberOfHiiHandles); +EFI_IFR_FORM_SET *_HiiGetFormSet (UINTN index); + + +EFI_STATUS _HiiLocateSetupHandles (VOID); +EFI_STATUS _MergePageIdListAndInfo (VOID); +EFI_STATUS _MergePageListAndInfo (VOID); +EFI_STATUS _MergeVariableListAndInfo (VOID); +EFI_STATUS _GetClassSubClassID (SETUP_LINK *SetupData); +EFI_STATUS GetAcknowledgementKey (); +EFI_STATUS _ReInitializeSetupdataPointers (); + +UINT16 _IsFormFound (EFI_IFR_FORM_SET *formSet, UINT16 formid); +UINT16 _HiiGetLinkIndex (EFI_GUID *guid, UINT16 class, UINT16 subclass, UINT16 formid); +VOID UIUpdateCallback (VOID * Handle, UINT32 OldVariableCount); +EFI_STATUS _FxiupNotificationData(SETUP_LINK *Setup_Link); + +EFI_STATUS UpdateIFRRefXControls (PAGE_INFO *PageInfo, CONTROL_INFO * CtrlInfo);//EIP: 55762 Start +EFI_STATUS GetPageIdFromGuid (EFI_GUID *FormGuid, UINT16 PageFormID, UINT16 *PageID);//EIP: 55762 End +VOID SetDriverHealthCount (VOID);//EIP57661 Starts Driver health support +BOOLEAN IsDriverHealthSupported (VOID);//EIP57661 Ends +EFI_STATUS CreateEventforIFR (CONTROL_INFO *control_Info );//EIP-105468 + + + +VOID FixMergePagesExtraHook (VOID *gPages, VOID *tempPages); +VOID PageRemoveHook (UINTN PageIndex, void *pageInfo, void *PageHandle, UINT16 PageFormID); + +//////////////////////////////////// +// Externing Functions +/////////////////////////////////// +extern BOOLEAN IsSupportDefaultForStringControl (VOID); + +// +//--------------------------------------------------------------------------- +// Procedure: HiiGetForm +// +// Description: Get HII form package by handle and form ID +// +// Input: EFI_HII_HANDLE Handle +// UINT16 form +// UINTN *Length +// +// Output: VOID *formPkBuffer - +//--------------------------------------------------------------------------- +// +VOID *HiiGetForm( EFI_HII_HANDLE Handle, UINT16 form, UINTN *Length ) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_HII_PACKAGE_HEADER *pkgHdr; + EFI_IFR_OP_HEADER *opHeader = NULL; + + VOID *hiiFormPackage=NULL; + UINT8 *formPkBuffer = NULL; + UINT8 *pkgOffset; +// UINT8 *msgBoxSel = NULL; + UINT8 end = 0; + UINT32 offset = 0; + UINTN len=10; + SETUP_LINK DummySetupLink; + + if(Length == NULL) + Length = &len; + + hiiFormPackage = EfiLibAllocateZeroPool(*Length); + + status = gHiiDatabase->ExportPackageLists(gHiiDatabase, Handle, Length, hiiFormPackage); + if(status == EFI_BUFFER_TOO_SMALL) + { + MemFreePointer(&hiiFormPackage); + // + // Allocate space for retrieval of IFR data + // + hiiFormPackage = EfiLibAllocateZeroPool(*Length); + + if (hiiFormPackage == NULL) + { + hiiFormPackage = NULL; + goto DONE; + } + // + // Get all the packages associated with this HiiHandle + // + status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, Length, hiiFormPackage); + if(EFI_ERROR(status)) + { + MemFreePointer(&hiiFormPackage); + hiiFormPackage = NULL; + goto DONE; + } + }else if(EFI_ERROR(status)) + { + hiiFormPackage = NULL; + goto DONE; + } + + offset = sizeof(EFI_HII_PACKAGE_LIST_HEADER); + + while(offset < ((EFI_HII_PACKAGE_LIST_HEADER*)hiiFormPackage)->PackageLength) + { + pkgOffset = ((UINT8*)hiiFormPackage) + offset; + pkgHdr = (EFI_HII_PACKAGE_HEADER*)pkgOffset; + switch(pkgHdr->Type) + { + case EFI_HII_PACKAGE_FORMS: + formPkBuffer = (UINT8*)EfiLibAllocateZeroPool(pkgHdr->Length); + if(formPkBuffer == NULL) + { + goto DONE; + } + MemCopy(formPkBuffer, pkgHdr, pkgHdr->Length); + opHeader = (EFI_IFR_OP_HEADER*)((UINT8*)formPkBuffer + sizeof(EFI_HII_PACKAGE_HEADER)); + if(opHeader->OpCode != EFI_IFR_FORM_SET_OP) + { +#ifdef STANDALONE_APPLICATION + CHAR16 *Temp = L"ERROR! Form Package contains No FormSet. Skipping Package Processing.\x0a\x0dPress a Key to Continue :\x0a\x0d"; + gST->ConOut->OutputString(gST->ConOut,Temp); + status = GetAcknowledgementKey(); + if(EFI_ERROR(status)) + { + gST->ConOut->OutputString(gST->ConOut, L"GetAcknowledgementKey returned ERROR!"); + } +#endif + MemFreePointer(&formPkBuffer); + formPkBuffer = NULL; + *Length = 0; + goto DONE; + } + // to check is the formset is EFI_SETUP_APPLICATION_SUBCLASS. + MemSet(&DummySetupLink,sizeof(DummySetupLink),0); + DummySetupLink.FormSet = formPkBuffer; + if(_GetClassSubClassID(&DummySetupLink) == EFI_UNSUPPORTED) + { + MemFreePointer(&formPkBuffer); + formPkBuffer = NULL; + *Length = 0; + goto DONE; + } + end = 1; + break; + case EFI_HII_PACKAGE_END: + end = 1; + break; + default: + break; + } + if (end) + { + break; + } + offset += pkgHdr->Length; + } + MemFreePointer(&hiiFormPackage); + if(form && (NULL != formPkBuffer))//EIP-75384 Static code + { + UINT8 *tempForm = NULL; + tempForm = GetFormByFormID((EFI_HII_PACKAGE_HEADER *)formPkBuffer, form, Length); + MemFreePointer(&formPkBuffer); + formPkBuffer = tempForm; + } + +DONE: + return formPkBuffer; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetClassSubClassID +// +// Description: +// +// Parameter: VOID *DefValue +// +// Return value: EFI_STATUS - The status +//---------------------------------------------------------------------------- +// + +EFI_STATUS _GetClassSubClassID(SETUP_LINK *SetupData) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER *)NULL; + BOOLEAN flag = TRUE; + INTN inScope = 0; + + if(SetupData->FormSet == NULL) + { + return EFI_UNSUPPORTED; + } + + SetupData->ClassID = 0; + SetupData->SubClassID = 0; + opHeader = (EFI_IFR_OP_HEADER*)(SetupData->FormSet + sizeof(EFI_HII_PACKAGE_HEADER)); + do + { + switch(opHeader->OpCode) + { + case EFI_IFR_GUID_OP: + { + UINT8 extOpcode = (UINT8)*((UINT8*)opHeader + sizeof(EFI_IFR_GUID)); + switch(extOpcode) + { + case EFI_IFR_EXTEND_OP_CLASS: + { + EFI_IFR_GUID_CLASS *guidClass = (EFI_IFR_GUID_CLASS*)opHeader; + SetupData->ClassID = guidClass->Class; + } + break; + case EFI_IFR_EXTEND_OP_SUBCLASS: + { + EFI_IFR_GUID_SUBCLASS *guidSubClass = (EFI_IFR_GUID_SUBCLASS*)opHeader; + SetupData->SubClassID = guidSubClass->SubClass; + flag = FALSE; + } + break; + } + } + break; + case EFI_IFR_END_OP: + if(inScope) + { + inScope--; + } + default: + break; + } + + if(opHeader->Scope) + { + inScope++; + } + opHeader = (EFI_IFR_OP_HEADER*)((UINT8*)opHeader + opHeader->Length); + } while(flag && inScope > 0); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _MergePageIdListAndInfo +// +// Description: +// +// Parameter: +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _MergePageIdListAndInfo() +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN i; + + if((PageIdListOffset + PageIdInfoOffset) == 0) + { + gPageIdList = NULL; + gPageIdInfo = NULL; + return status; // NO Formset to show. + } + + gPageIdList = (PAGE_ID_LIST*)EfiLibAllocateZeroPool(PageIdListOffset + PageIdInfoOffset); + if(gPageIdList == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + MemCopy(gPageIdList,PageIdListPtr,PageIdListOffset); + MemCopy(((UINT8 *)gPageIdList)+ PageIdListOffset,PageIdInfoPtr,PageIdInfoOffset); + + for(i=0; iPageIdCount; i++) + { + gPageIdList->PageIdList[i] += PageIdListOffset; + } + + gPageIdInfo = (PAGE_ID_INFO *)(((UINT8 *) gPageIdList) + gPageIdList->PageIdList[0]); + + //Free Temp Memory + MemFreePointer(&PageIdInfoPtr); + MemFreePointer(&PageIdListPtr); + +DONE: + return status; +} +//EIP: 55762 Start +// +//---------------------------------------------------------------------------- +// Procedure: SpecialControlsFixup +// +// Description: Fixes control information for special control in the varstore +// +// Parameter: None +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS SpecialControlsFixup() +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN i,j; + VARIABLE_INFO *varInfo = NULL; + + for(i = 0; i < gPages->PageCount; i++) + { + PAGE_INFO *PageInfo = (PAGE_INFO*)((UINTN)gApplicationData + gPages->PageList[i]); + if(!PageInfo){ + continue; + } + for ( j = 0; j < PageInfo->PageControls.ControlCount; j++ ) + { + CONTROL_INFO *ctrlInfo = (CONTROL_INFO*)(((UINTN)gControlInfo) + PageInfo->PageControls.ControlList[j]); + if(!ctrlInfo){ + continue; + } + + UpdateIFRRefXControls(PageInfo, ctrlInfo); //Update the CONTROL_INFO with REFX information + + + } + } + for ( i = 0; i < gVariables->VariableCount; i++) + { + varInfo = (VARIABLE_INFO *)((UINT8 *)gVariables + gVariables->VariableList[i]); + if(!varInfo){ + continue; + } + for(j = 0; j < gGuidList->GuidCount; j++) + { + GUID_INFO *GuidInfo = (GUID_INFO *)((UINTN)gGuidList + gGuidList->GuidList[j]); + if(GuidInfo && EfiCompareGuid(&varInfo->VariableGuid, &GuidInfo->GuidValue)) + { + switch(GuidInfo->GuidKey) + { + //case GUID_KEY_NO_COMMIT: + // varInfo->ExtendedAttibutes = AMI_SPECIAL_NO_COMMIT_VARIABLE; + // break; + default: + break; + } + } + } + } + + return status; +} +//EIP: 55762 End +// +//---------------------------------------------------------------------------- +// +// Procedure: _MergePageListAndInfo +// +// Description: +// +// Parameter: +// +// Return value: EFI_STATUS +// EFI_SUCCESS +// EFI_OUT_OF_RESOURCES +//---------------------------------------------------------------------------- +// +EFI_STATUS _MergePageListAndInfo() +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN i; + + SETUP_DEBUG_UEFI ( "\n[TSE] Entering _MergePageListAndInfo()\n" ); + + gApplicationData = (UINT8*)EfiLibAllocateZeroPool(PageListOffset + FirstPageOffset + PageInfoOffset); + if(gApplicationData == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + gPages = (PAGE_LIST *) gApplicationData; + MemCopy(gApplicationData, PageListPtr, PageListOffset); + MemCopy(gApplicationData + PageListOffset, FirstPage, FirstPageOffset); + MemCopy(gApplicationData + PageListOffset + FirstPageOffset, PageInfoPtr, PageInfoOffset); + + //Fix Offsets + i=0; + gPages->PageList[i] = PageListOffset; + i++; + + for(; i < gPages->PageCount; i++) + { + gPages->PageList[i] += (FirstPageOffset + PageListOffset); + } + + //Free Temp Memory + MemFreePointer(&FirstPage); + MemFreePointer(&PageInfoPtr); + MemFreePointer(&PageListPtr); +//EIP: 55762 Start + SpecialControlsFixup(); //Fixes control information for special control in the varstore +//EIP: 55762 End +DONE: + SETUP_DEBUG_UEFI ( "\n[TSE] Exitingg _MergePageListAndInfo(), status = 0x%x \n" , status ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _MergeVariableListAndInfo +// +// Description: +// +// Parameter: +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _MergeVariableListAndInfo() +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN i; + + //EIP-71351 Try to reallocate the existing Variable Cache. + if (gVariables->VariableCount != VariableListPtr->VariableCount) //EIP 90809 Reallocating only when counts varies + { + if(gVariableList != NULL) + gVariableList = MemReallocateZeroPool( gVariableList, sizeof(NVRAM_VARIABLE) * gVariables->VariableCount, VariableListPtr->VariableCount * sizeof(NVRAM_VARIABLE)); + + if(gOptimalDefaults != NULL) + gOptimalDefaults = MemReallocateZeroPool( gOptimalDefaults, sizeof(NVRAM_VARIABLE) * gVariables->VariableCount, VariableListPtr->VariableCount * sizeof(NVRAM_VARIABLE)); + + if(gFailsafeDefaults != NULL) + gFailsafeDefaults = MemReallocateZeroPool( gFailsafeDefaults, sizeof(NVRAM_VARIABLE) * gVariables->VariableCount, VariableListPtr->VariableCount * sizeof(NVRAM_VARIABLE)); + } + + gVariables = (VARIABLE_LIST*)EfiLibAllocateZeroPool(VariableListOffset + VariableInfoOffset); + if(gVariables == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + MemCopy(gVariables,VariableListPtr,VariableListOffset); + MemCopy(((UINT8 *)gVariables)+ VariableListOffset,VariableInfoPtr,VariableInfoOffset); + + for(i=0; iVariableCount; i++) + { + gVariables->VariableList[i] += VariableListOffset; + } + + //Free Temp Memory + MemFreePointer(&VariableInfoPtr); + MemFreePointer(&VariableListPtr); + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: HiiExit +// +// Description: +// +// Parameter: +// +// Return value: EFI_STATUS - Return the Status +//---------------------------------------------------------------------------- +// +VOID RTIfrUnRegFormNotificationWrapper (VOID); +EFI_STATUS HiiExit() +{ + UINTN i; + + //Remove gSetupHandles + MemFreePointer((VOID**)&gSetupHandles); + + // Remove memory held by gSetupData + for ( i = 0; i < gSetupCount; i++ ) + { + //EIP:61122, Free memory only if gSetupData[i].FormSetLength is non-zero. + if(gSetupData[i].FormSetLength) + MemFreePointer(&(gSetupData[i].FormSet)); + } + MemFreePointer(&gSetupData); + gSetupCount = 0; + + MemFreePointer(&gControlInfo); + ControlListSize = ControlListOffset = 0; + + MemFreePointer(&gApplicationData); + gPages = gToolPages; + PageListPtr = NULL; + PageInfoPtr = NULL; + FirstPage = NULL; + AllocatedFirstPageSize = FirstPageOffset = PageListSize = PageListOffset = PageInfoSize = PageInfoOffset = 0; + +//#if SETUP_RUNTIME_IFR_PROCESSING + RTIfrProcessExitWrapper(); +//#endif + + gVariables = gToolVariables; + gPageIdList = gToolPageIdList; + gPageIdInfo = (PAGE_ID_INFO *)(((UINT8 *) gPageIdList) + gPageIdList->PageIdList[0]); + + RTIfrUnRegFormNotificationWrapper (); //EIP99059 + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: UnRegFormNotification +// +// Description: Unregisters the form notification +// +// Parameter: VOID +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UnRegFormNotification (VOID) +{ + UnRegisterFormNotification (gNotifyHandle[0]); + UnRegisterFormNotification (gNotifyHandle[1]); + UnRegisterFormNotification (gNotifyHandle[2]); +} + +VOID FixupPage0ControlInfo( UINTN FormSet, UINTN ControlPtr, EFI_HII_HANDLE Handle) +{ + PAGE_INFO *pageInfo = (PAGE_INFO *)(((UINT8 *)gSetupPkg) + gToolPages->PageList[0]); + CONTROL_INFO *controlInfo = NULL; + UINT32 j; + + if(pageInfo->PageControls.ControlCount) + { + for ( j = 0; j < pageInfo->PageControls.ControlCount; j++ ) + { + controlInfo = (CONTROL_INFO*)((UINTN)gToolControlInfo + pageInfo->PageControls.ControlList[j]); + if( (ControlPtr-FormSet) == (UINTN)controlInfo->ControlPtr ) + { + controlInfo->ControlHandle = Handle; + controlInfo->ControlPtr = (VOID*)ControlPtr; + }else{ + if(controlInfo->ControlType == CONTROL_TYPE_NULL) + controlInfo->ControlHandle = Handle; + } + } + } + +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: RegFormNotification +// +// Description: Registers the hii pack notification +// +// Parameter: VOID +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS RegFormNotification (VOID) +{ + EFI_STATUS status = EFI_SUCCESS; + + status = RegisterFormNotification(IFRChangeNotifyFn, EFI_HII_DATABASE_NOTIFY_NEW_PACK, &gNotifyHandle[0]); + if (EFI_ERROR(status)) + { + return status; + } + status = RegisterFormNotification(IFRChangeNotifyFn, EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, &gNotifyHandle[1]); + if (EFI_ERROR(status)) + { + return status; + } + status = RegisterFormNotification(IFRChangeNotifyFn, EFI_HII_DATABASE_NOTIFY_ADD_PACK, &gNotifyHandle[2]); + if (EFI_ERROR(status)) + { + return status; + } + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: HiiFixupData +// +// Description: +// +// Parameter: +// +// Return value: EFI_STATUS - Return the Status +//---------------------------------------------------------------------------- +// +EFI_STATUS RTIfrRegFormNotificationWrapper (VOID); +extern EFI_GUID RefreshEventGroupId; +EFI_STATUS HiiFixupData() +{ + EFI_STATUS status = EFI_SUCCESS; + + PAGE_INFO *pageInfo = NULL; + EFI_IFR_FORM_SET *formSet; + EFI_IFR_REF *ref = NULL; + //UINT16 *varString; + //UINT16 StringToken = 0; + UINT16 link; + UINT32 i=0; + UINT32 j=0; + + SETUP_DEBUG_UEFI ( "\n[TSE] Entering HiiFixupData()\n" ); + if (PageListOffset || FirstPageOffset || PageInfoOffset) //EIP122350 If handofftse invoked second time then offsets incrementing from current so exiting and reforming. + { + HiiExit(); + } + status = RTIfrRegFormNotificationWrapper (); //EIP99059 + if (EFI_ERROR (status)) + goto DONE; + status = _HiiLocateSetupHandles(); + if (EFI_ERROR(status)) + { + goto DONE; + } + gSetupData = EfiLibAllocateZeroPool(sizeof(SETUP_LINK) * gSetupCount); + if(gSetupData == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + for(i = 0; i < gSetupCount - 1; i++) + { + gSetupData[i].FormSet = HiiGetForm(gSetupHandles[i], 0, &(gSetupData[i].FormSetLength)); + if(gSetupData[i].FormSet == NULL) + { + // make sure the handle is also zero + gSetupData[i].Handle = 0 ; + continue; + } + gSetupData[i].Handle = gSetupHandles[i]; + formSet = (EFI_IFR_FORM_SET*)_HiiGetFormSet(i); + + _GetClassSubClassID(&gSetupData[i]); + +#if TSE_DEBUG_MESSAGES + WritePackToFile(SETUPDATAFILENAME, + gSetupData[i].Handle, + NULL, + gSetupData[i].FormSetLength) ; +#endif + } + + + // need to allocate one more dynamic IFR for the root page, this is NOT a 100% valid + // formset as there is no form defined + gSetupData[i].FormSet = EfiLibAllocateZeroPool(sizeof(EFI_HII_PACKAGE_HEADER) + + sizeof(EFI_IFR_FORM_SET) + /*i*/ gToolPages->PageCount * sizeof(EFI_IFR_REF)); //EIP 105965 : No. of root pages can be more then hii handle because of AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST_SUPPORT + if(gSetupData[i].FormSet == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + formSet = (EFI_IFR_FORM_SET*)_HiiGetFormSet(i); + MemCopy(&(formSet->Guid),&(gSetupPkg->PackageGuid),sizeof(EFI_GUID)); + + TotalRootPages = 0; + if ( gSetupData[i].FormSet != NULL ) + { + ref = (EFI_IFR_REF *)(gSetupData[i].FormSet + sizeof(EFI_HII_PACKAGE_HEADER) + sizeof(EFI_IFR_FORM_SET)); + for ( j = 1; j <= gToolPages->PageCount; j++ ) + { + pageInfo = (PAGE_INFO *)(((UINT8 *)gSetupPkg) + gToolPages->PageList[j]); + if ( pageInfo->PageParentID != 0 ) //if ( pageInfo->PageFormID != 1 ) + { + continue; + } + + TotalRootPages++; + + link = _HiiGetLinkIndex(&(gToolPageIdInfo[pageInfo->PageIdIndex].PageGuid), + gToolPageIdInfo[pageInfo->PageIdIndex].PageClass, + gToolPageIdInfo[pageInfo->PageIdIndex].PageSubClass, + pageInfo->PageFormID); + + if ( link == (gSetupCount - 1) ) + { + continue; + } + + formSet = (EFI_IFR_FORM_SET*)_HiiGetFormSet(link); + //EIP-75352 Suppress the warnings from static code analyzer + if(NULL == formSet){ + continue; + } + ref->Header.OpCode = EFI_IFR_REF_OP; + ref->Header.Length = sizeof(EFI_IFR_REF); + ref->Question.Header.Prompt = formSet->FormSetTitle; + ref->Question.Header.Help = formSet->Help; + FixupPage0ControlInfo( (UINTN)gSetupData[i].FormSet, (UINTN)ref, gSetupData[link].Handle); + ref++; + } + gSetupData[i].Handle = gSetupData[0].Handle; + } +//#if SETUP_RUNTIME_IFR_PROCESSING + RTIfrProcessAddVarListAndPageIDListWrapper(); +//#endif //SETUP_RUNTIME_IFR_PROCESSING +//EIP64253 offline vfr pages hided starts + i = 0; + if(gGuidDump == NULL) + { + gGuidDumpCount = gToolPages->PageCount; + gGuidDump = EfiLibAllocateZeroPool (sizeof (EFI_GUID) * gGuidDumpCount); + j = 0; + } + else + { + j = (UINT32) gGuidDumpCount; + gGuidDump = MemReallocateZeroPool (gGuidDump, gGuidDumpCount * sizeof (EFI_GUID), (gGuidDumpCount+gToolPages->PageCount) * sizeof (EFI_GUID)); + gGuidDumpCount += gToolPages->PageCount; + } + + if (NULL != gGuidDump) + { + for (i = 0; i < gToolPages->PageCount; i++) + { + PAGE_INFO *ParsepageInfo = NULL; + ParsepageInfo = (PAGE_INFO *)(((UINT8 *)gSetupPkg) + gToolPages->PageList [i]); + + EfiCopyMem (&gGuidDump [i+j], &gToolPageIdInfo [ParsepageInfo->PageIdIndex].PageGuid, sizeof (EFI_GUID)); + } + } +//EIP64253 offline vfr pages hided ends + // update the control (IFR) pointers and HII handles + for ( i = 0; i< gToolPages->PageCount; i++ ) + { +// PAGE_INFO *NewPageInfo; + UINT32 PageSize; + UINT32 ControlSize; + CONTROL_INFO *NewControlInfo; + UINTN NoOfControlSpace; + + pageInfo = (PAGE_INFO *)(((UINT8 *)gSetupPkg) + gToolPages->PageList[i]); + + if(i == 0) + { + link = (UINT16)(gSetupCount - 1); + } + else + { + link = _HiiGetLinkIndex( &(gToolPageIdInfo[pageInfo->PageIdIndex].PageGuid), + gToolPageIdInfo[pageInfo->PageIdIndex].PageClass, + gToolPageIdInfo[pageInfo->PageIdIndex].PageSubClass, + pageInfo->PageFormID); + } + + NoOfControlSpace = pageInfo->PageControls.ControlCount ? pageInfo->PageControls.ControlCount - 1 : pageInfo->PageControls.ControlCount; + PageSize = (UINT32)(sizeof(PAGE_INFO) + sizeof(pageInfo->PageControls.ControlList) * NoOfControlSpace); + NewPageInfo = EfiLibAllocateZeroPool(PageSize); + if (NewPageInfo == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(NewPageInfo,pageInfo,PageSize); + + if ( link == (gSetupCount - 1) ) + { + NewPageInfo->PageHandle = 0;// This page has been removed in runtime!!! + } + else + { +//#if SETUP_RUNTIME_IFR_PROCESSING + if(RTIfrProcessFormIfUpdatedWrapper(link) == TRUE) + continue; +//#endif //SETUP_RUNTIME_IFR_PROCESSING + + NewPageInfo->PageHandle = gSetupData[link].Handle; + } + + //Fixup and add the controls in this page to gContolInfo and update offsets in page info + + if(NewPageInfo->PageControls.ControlCount) + { + for ( j = 0; j < NewPageInfo->PageControls.ControlCount; j++ ) + { + VARIABLE_INFO *varInfo = NULL; + CONTROL_INFO *controlInfo = (CONTROL_INFO*)((UINTN)gToolControlInfo + NewPageInfo->PageControls.ControlList[j]); + //EIP:56413 Updated the contol size to copy the Default information for the control + ControlSize = sizeof(CONTROL_INFO) + controlInfo->ControlDataWidth * 2 + controlInfo->DefaultStoreCount * (sizeof(UINT16) + controlInfo->ControlDataWidth) ; + + NewControlInfo = EfiLibAllocateZeroPool(ControlSize); + if (NewControlInfo == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(NewControlInfo, controlInfo, ControlSize); + + if(NewPageInfo->PageHandle != 0) + { + NewControlInfo->ControlHandle = gSetupData[link].Handle; + + if ( NewControlInfo->ControlPtr != 0 ) + { + NewControlInfo->ControlPtr = (VOID *)((UINTN)NewControlInfo->ControlPtr + (UINTN)gSetupData[link].FormSet); + + if ( NewControlInfo->ControlFlags.RefreshID )//EIP-105468 & 175492 + { + UINT32 index=0; + UINT8 *pOpcodeHeader=(UINT8 *)NewControlInfo->ControlPtr; + //search for the EFI_IFR_REFRESH_ID_OP.if Found then only type cast and assign RefreshEventGroupId and create event for IFR. + while(pOpcodeHeader)//EIP-175492 + { + if(EFI_IFR_REFRESH_ID_OP == ((EFI_IFR_OP_HEADER *)(pOpcodeHeader))->OpCode) + { + MemCopy (&RefreshEventGroupId, &(((AMI_EFI_IFR_REFRESH_ID *)(pOpcodeHeader))->RefreshEventGroupId), sizeof (EFI_GUID)); + CreateEventforIFR (NewControlInfo); + break; + } + if((((EFI_IFR_OP_HEADER *)(pOpcodeHeader))->Scope))//if OpcodeHeader has scope then, Increment index + index++; + if(EFI_IFR_END_OP == ((EFI_IFR_OP_HEADER *)(pOpcodeHeader))->OpCode)//if EFI_IFR_END_OP found then,decrement index + index--; + if(!index) + break; + pOpcodeHeader+=((EFI_IFR_OP_HEADER *)(pOpcodeHeader))->Length;//point to next opcode header depending upon the Length + } + } + + if ( NewControlInfo->ControlConditionalPtr != 0 ) + { + NewControlInfo->ControlConditionalPtr = (VOID *)((UINTN)NewControlInfo->ControlConditionalPtr + (UINTN)NewControlInfo->ControlPtr); + } + } + else if ( NewControlInfo ->ControlConditionalPtr != 0 ) + { + NewControlInfo ->ControlConditionalPtr = (VOID *)((UINTN)NewControlInfo ->ControlConditionalPtr + (UINTN)gSetupData[link].FormSet); + } + // Get The Variable Info referenced by Control Variable + if (RTIfrUpdateVariableInfoWrapper (NewControlInfo->ControlVariable, gSetupData[link].Handle) == FALSE) + { + varInfo = VarGetVariableInfoIndex (NewControlInfo->ControlVariable); + if(varInfo->VariableHandle == NULL) + { + varInfo->VariableHandle = gSetupData[link].Handle; + } + //EIP56405: Commented for suppressing build time parsing. Name value not supported by current vfr compiler. Uncomment it once vfr compiler supports it. + /*if (VARIABLE_ATTRIBUTE_NAMEVALUE == (varInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)) + { + if (0 == (EfiStrLen (varInfo->VariableName))) + { + StringToken = (UINT16)((UINT16)(varInfo->NameValueToken [1] << 8) + (UINT8)(varInfo->NameValueToken [0])); + varString = HiiGetString (varInfo->VariableHandle, StringToken); + EfiStrCpy (varInfo->VariableName, varString); + } + }*/ + } + } + NewPageInfo->PageControls.ControlList[j] = AddControlToList(NewControlInfo,ControlSize); //Update new offset in gControlInfo + MemFreePointer(&NewControlInfo); + } + } + else + { + // Add the Empty Control to control List even if NewPageInfo->PageControls.ControlCount = 0 + CONTROL_INFO *controlInfo = (CONTROL_INFO*)((UINTN)gToolControlInfo + 0); + ControlSize = sizeof(CONTROL_INFO) + controlInfo->ControlDataWidth * 2; + NewControlInfo = EfiLibAllocateZeroPool(ControlSize); + MemCopy(NewControlInfo, controlInfo, ControlSize); + AddControlToList(NewControlInfo,ControlSize); //Update new offset in gControlInfo + MemFreePointer(&NewControlInfo); + } + + if(i==0) + { + status = CreatePage(&FirstPage, &AllocatedFirstPageSize, &FirstPageOffset, NewPageInfo, PageSize); + } + else + { + status = AddPageToList(NewPageInfo,PageSize); + } + if(EFI_ERROR(status)) + { + goto DONE; + } + MemFreePointer(&NewPageInfo); + } + +//#if SETUP_RUNTIME_IFR_PROCESSING + RTIfrProcessRunTimeFormsWrapper(&ref); +//#endif //SETUP_RUNTIME_IFR_PROCESSING + + status = _MergePageListAndInfo(); +//EIP57661 Starts + if (IsDriverHealthSupported ()) + { + SetDriverHealthCount (); + } +//EIP57661 Ends +DONE: + SETUP_DEBUG_UEFI ( "\n[TSE] Exiting HiiFixupData(), status = 0x%x \n" , status ); + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _HiiLocateSetupHandles +// +// Description: +// +// Parameter: +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _HiiLocateSetupHandles() +{ + EFI_STATUS status; + UINT16 i = 0; + UINT16 count; + EFI_HII_HANDLE *handleBuffer; + UINT8 *buffer; + UINT16 found = 0; + + status = HiiInitializeProtocol(); + if (EFI_ERROR(status)) + { + goto DONE; + } + + if(FormBrowserLocateSetupHandles(&handleBuffer,&count)!= EFI_SUCCESS) + { + handleBuffer = _HiiGetHandles( &count ); + } + + if ( handleBuffer == NULL ) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + gSetupHandles = (EFI_HII_HANDLE*)EfiLibAllocatePool((count + 1) * sizeof(EFI_HII_HANDLE)); + if ( gSetupHandles == NULL ) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + for ( i = found = 0; i < count; i++ ) + { + buffer = HiiGetForm( handleBuffer[i], 0, NULL ); + if ( buffer == NULL ) + { + continue; + } + + gSetupHandles[found] = handleBuffer[i]; + found++; + MemFreePointer( &buffer ); + } + + gSetupCount = found + 1; + + // at this point we have all the setup specific HII handles into our buffer +DONE: + + if(!FormBrowserHandleValid()) + MemFreePointer((VOID**)&handleBuffer); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _HiiGetLinkIndex +// +// Description: +// +// Parameter: +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 _HiiGetLinkIndex(EFI_GUID *guid, UINT16 class, UINT16 subclass, UINT16 formid) +{ + UINT16 i; + EFI_IFR_FORM_SET *formSet; + EFI_HII_PACKAGE_HEADER *pack; + + for ( i = 0; i < gSetupCount - 1; i++ ) + { + pack = (EFI_HII_PACKAGE_HEADER *)gSetupData[i].FormSet; + + if ( sizeof(EFI_HII_PACKAGE_HEADER) == pack->Length ) + { + continue; + } + + formSet = (EFI_IFR_FORM_SET *)((UINT8 *)pack + sizeof(EFI_HII_PACKAGE_HEADER)); + + if(EfiCompareGuid( guid , (VOID *)&(formSet->Guid) )) + { + if( gSetupData[i].ClassID == class ) + { + if( gSetupData[i].SubClassID == subclass ) + { + if(_IsFormFound(formSet, formid)) + { + break; + } + } + } + } + } + + return i; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _HiiGetFormSet +// +// Description: +// +// Parameter: +// +// Return value: EFI_IFR_FORM_SET +//---------------------------------------------------------------------------- +// +EFI_IFR_FORM_SET *_HiiGetFormSet(UINTN index) +{ + EFI_IFR_FORM_SET *formSet = NULL; + + if ( (index >= gSetupCount) || (gSetupData == NULL)) + { + return formSet; + } + + formSet = (EFI_IFR_FORM_SET*)(gSetupData[index].FormSet + sizeof(EFI_HII_PACKAGE_HEADER)); + + return formSet; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _HiiGetHandles +// +// Description: gets all the HII handles +// +// Parameter: No of handles +// +// Return value: EFI_HII_HANDLE * +//---------------------------------------------------------------------------- +// + +EFI_HII_HANDLE *_HiiGetHandles(UINT16 *NumberOfHiiHandles) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_HII_HANDLE *hiiHandleBuffer = NULL; + + UINTN handleBufferLength = 0; + +// gBS->AllocatePool(EfiBootServicesData, handleBufferLength, +// (VOID **)&hiiHandleBuffer); + hiiHandleBuffer = EfiLibAllocatePool(handleBufferLength); + + status = gHiiDatabase->ListPackageLists (gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL, NULL, + &handleBufferLength, hiiHandleBuffer); + if (status == EFI_BUFFER_TOO_SMALL) + { + // + // Free the old pool + // + MemFreePointer ((VOID**)&hiiHandleBuffer); + // + // Allocate new pool with correct value + // +// gBS->AllocatePool (EfiBootServicesData, handleBufferLength, +// (VOID **)&hiiHandleBuffer); + hiiHandleBuffer = EfiLibAllocatePool(handleBufferLength); + + // + // Get the Handles of the packages that were registered with Hii + // + gBS->SetMem(hiiHandleBuffer,handleBufferLength,0); + status = gHiiDatabase->ListPackageLists (gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL, + NULL, &handleBufferLength, hiiHandleBuffer); + + if (EFI_ERROR (status)) + { + MemFreePointer((VOID**)&hiiHandleBuffer); + hiiHandleBuffer = NULL; + goto DONE; + } + }else if(EFI_ERROR(status)) + { + MemFreePointer((VOID**)&hiiHandleBuffer); + hiiHandleBuffer = NULL; + goto DONE; + } + + *NumberOfHiiHandles = (UINT16)(handleBufferLength / sizeof(EFI_HII_HANDLE)); + +DONE: + return hiiHandleBuffer; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _IsFormFound +// +// Description: +// +// Parameter: +// +// Return value: UINT16 - +// 1 Form Found +// 0 Form Not Found +//---------------------------------------------------------------------------- +// +UINT16 _IsFormFound(EFI_IFR_FORM_SET *formSet,UINT16 formid ) +{ + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER*)formSet; + BOOLEAN flag = TRUE; + UINT16 found = 0; + UINTN offset = 0; + UINTN ScopeCount = 0; + + while(flag) + { + switch(opHeader->OpCode) + { + case EFI_IFR_FORM_OP: + { + EFI_IFR_FORM *formOp = (EFI_IFR_FORM*)opHeader; + if(formOp->FormId == formid) + { + found = 1; + flag = FALSE; + } + } + break; + case EFI_IFR_FORM_MAP_OP: + { + AMI_EFI_IFR_FORM_MAP *formMapOp = (AMI_EFI_IFR_FORM_MAP *)opHeader; + if(formMapOp->FormId == formid) + { + found = 1; + flag = FALSE; + } + } + break; + case EFI_IFR_END_OP: + flag = (--ScopeCount)? TRUE:FALSE; + break; + default: + break; + } + if(opHeader->Scope) + { + ScopeCount++; + } + offset += opHeader->Length; + opHeader = (EFI_IFR_OP_HEADER*)((UINT8*)formSet + offset); + } + + return found; +} + + +// +//---------------------------------------------------------------------------- +// +// Procedure: HiiFindHandle +// +// Description: HiiFindHandle +// +// Parameter: EFI_GUID *guid, UINT16 *index +// +// Return value: EFI_HII_HANDLE +//---------------------------------------------------------------------------- +// + +EFI_HII_HANDLE HiiFindHandle( EFI_GUID *guid, UINT16 *index ) +{ + EFI_HII_HANDLE *handleBuffer = NULL; + EFI_HII_HANDLE handle = INVALID_HANDLE; + UINT16 found = 0; + UINT16 i, count; + UINTN len=10; + EFI_HII_PACKAGE_LIST_HEADER *hiiPackageList; + EFI_STATUS status=EFI_SUCCESS; + + handleBuffer = _HiiGetHandles( &count ); + if ( handleBuffer == NULL ) + return handle; + + for ( i = found = 0; i < count; i++ ) + { + hiiPackageList = EfiLibAllocateZeroPool(len); + + status = gHiiDatabase->ExportPackageLists(gHiiDatabase, handleBuffer[i], &len, hiiPackageList); + if(status == EFI_BUFFER_TOO_SMALL) + { + MemFreePointer(&hiiPackageList); + // + // Allocate space for retrieval of IFR data + // + hiiPackageList = EfiLibAllocateZeroPool(len); + + if (hiiPackageList == NULL) + { + hiiPackageList = NULL; + goto DONE; + } + // + // Get all the packages associated with this HiiHandle + // + status = gHiiDatabase->ExportPackageLists(gHiiDatabase, handleBuffer[i], &len, hiiPackageList); + if(EFI_ERROR(status)) + { + MemFreePointer(&hiiPackageList); + hiiPackageList = NULL; + goto DONE; + } + } + if ( EfiCompareGuid( guid, &hiiPackageList->PackageListGuid ) ) + { + if ( *index == found ) + { + handle = handleBuffer[i]; + (*index)++; + break; + } + found++; + } + + MemFreePointer( &hiiPackageList ); + } + +DONE: + MemFreePointer( (VOID **)&handleBuffer ); + return handle; + +} + + +// +//---------------------------------------------------------------------------- +// +// Procedure: RTIfrProcessExit +// +// Description: RTIfrProcessExit +// +// Parameter: none +// +// Return value: none +//---------------------------------------------------------------------------- +// +VOID RTIfrProcessExit(VOID) +{ + MemFreePointer(&gVariables); + VariableListPtr = NULL; + VariableInfoPtr = NULL; + VariableListOffset = VariableListSize = VariableInfoOffset = VariableInfoSize = 0; + + MemFreePointer(&gPageIdList); + PageIdListPtr = NULL; + PageIdInfoPtr = NULL; + PageIdListOffset = PageIdListSize = PageIdInfoOffset = PageIdInfoSize = 0; +} + + +// +//---------------------------------------------------------------------------- +// +// Procedure: RTIfrProcessAddVarListAndPageIDList +// +// Description: +// +// Parameter: None +// +// Return value: None +//---------------------------------------------------------------------------- +// +VOID RTIfrProcessAddVarListAndPageIDList(VOID) +{ + UINT32 i; + + SETUP_DEBUG_UEFI ( "\n[TSE] Entering RTIfrProcessAddVarListAndPageIDList()\n" ); + + //Create Variable List + for(i=0; i < gToolVariables->VariableCount ; i++) + { + VARIABLE_INFO *VariableInfo; + + VariableInfo = (VARIABLE_INFO*)((UINT8*)gToolVariables + gToolVariables->VariableList[i]); + AddVariableToList(VariableInfo); + } + + //Create Page ID list + for(i=0; i < gToolPageIdList->PageIdCount ; i++) + { + PAGE_ID_INFO *PageIdInfo; + + PageIdInfo = (PAGE_ID_INFO*)((UINT8*)gToolPageIdList + gToolPageIdList->PageIdList[i]); + AddPageIdToList(PageIdInfo); + } + + SETUP_DEBUG_UEFI ( "\n[TSE] Exiting RTIfrProcessAddVarListAndPageIDList()\n" ); +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: RTIfrProcessFormIfUpdated +// +// Description: +// +// Parameter: +// +// Return value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN RTIfrProcessFormIfUpdated(UINT16 link) +{ + UINT32 j; + + SETUP_DEBUG_UEFI ( "\n[TSE] Entering RTIfrProcessFormIfUpdated()\n" ); + + //Fix to correctly check if FormSet length has changed and if so Parse it. This fixes the issue with duplicate ClassID and SubClassID. + + for(j=1; j < gToolPageIdList->PageIdCount; j++) // PAGE_ID_INFO[0] contains reference to the NULL page + { + //Check if the page has changed during run time + EFI_HII_PACKAGE_HEADER *pack; + PAGE_ID_INFO *pageIdList = (PAGE_ID_INFO *)((UINT8 *)gToolPageIdList + gToolPageIdList->PageIdList[j]); + EFI_IFR_FORM_SET *formSet = (EFI_IFR_FORM_SET*)((UINT8 *)gSetupData[link].FormSet + sizeof(EFI_HII_PACKAGE_HEADER)); + + // Compare if the FormSet triplet is already available + if((pageIdList->PageClass == gSetupData[link].ClassID) && + (pageIdList->PageSubClass == gSetupData[link].SubClassID) && + (EfiCompareGuid(&pageIdList->PageGuid, (VOID *)&formSet->Guid))) + { + pack = (EFI_HII_PACKAGE_HEADER *)gSetupData[link].FormSet; + + if ( gHpkInfo[j-1].Length != pack->Length ) + { + break; + } + } + } + + if(j < gToolPageIdList->PageIdCount) + { + //This page changed during run time parse again + if(!gSetupData[link].Added) + { + ParseForm(&gSetupData[link]); + } + return TRUE; + } + + + gSetupData[link].Added = 1; + + SETUP_DEBUG_UEFI ( "\n[TSE] Exiting RTIfrProcessFormIfUpdated()\n" ); + + return FALSE; +} + + +// +//---------------------------------------------------------------------------- +// +// Procedure: RTIfrProcessRunTimeForms +// +// Description: +// +// Parameter: +// +// Return value: None +//---------------------------------------------------------------------------- +// +VOID RTIfrProcessRunTimeForms(EFI_IFR_REF **ref) +{ + UINT32 i; + EFI_STATUS Status = EFI_SUCCESS; + EFI_IFR_FORM_SET *formSet; + EFI_GUID DynamicPageGuid = DYNAMIC_PAGE_COUNT_GUID; + UINTN count = 0; + + SETUP_DEBUG_UEFI ( "\n[TSE] Entering RTIfrProcessRunTimeForms()\n" ); + + if(!IsGroupDynamicPages()) //EIP: 59971 + gFirstPageRef = (VOID*)(*ref); + + for(i = 0; i < gSetupCount - 1; i++) + { + if(!(gSetupData[i].Added)) + { + Status = ParseForm(&gSetupData[i]); + if((gSetupData[i].Added)) + { + formSet = _HiiGetFormSet( i ); + //EIP-75352 Suppress the warnings from static code analyzer + if(NULL == formSet){ + continue; + } + + if(!IsGroupDynamicPages()) //EIP: 59971 + { + (*ref)->Header.OpCode = EFI_IFR_REF_OP; + (*ref)->Header.Length = sizeof(EFI_IFR_REF); + (*ref)->Question.Header.Prompt = formSet->FormSetTitle; + (*ref)->Question.Header.Help = formSet->Help; + (*ref)++; + gFirstPageRef = (VOID*)(*ref); + } + + } + if (EFI_SUCCESS == Status) //To avoid increment count incase parsing is aborted and avoid showing sub-link under advanced page + count++ ; + } + } + + gDynamicPageCount = count ; + + //Set Dynamic page count variable + VarSetNvramName( L"DynamicPageCount", &DynamicPageGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &count, sizeof(count) ); + VarUpdateVariable(VARIABLE_ID_DYNAMIC_PAGE_COUNT); //EIP_63262: Update nvram cache for DynamicPageCount + + _MergePageIdListAndInfo(); + _MergeVariableListAndInfo(); + + SETUP_DEBUG_UEFI ( "\n[TSE] Exiting RTIfrProcessRunTimeForms()\n" ); +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: HiiLoadDefaults +// +// Description: +// +// Parameter: +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS HiiLoadDefaults( VOID **varList, UINT32 Mask ) +{ + // This function needs to be revisited once Aptio supports GetAltCfg + EFI_STATUS status = EFI_SUCCESS; + UINT32 index = 0; + + status = GetNvramVariableList((NVRAM_VARIABLE **)varList); // EIP 76381 : Performance Improving of variable data load and usage + if(EFI_ERROR(status)){ + goto DONE; + } + + // Get the Controls in each Page + for ( index = 0; index < gPages->PageCount; index++ ) + { + PAGE_INFO *pageInfo = (PAGE_INFO*)((UINT8 *)gPages + gPages->PageList[index]); + UINTN control = 0; + + if(pageInfo->PageHandle == NULL) + { + continue; + } + // Get the Default values for each control and update DefaultStore + for(control = 0; control < pageInfo->PageControls.ControlCount; control++) + { + CONTROL_INFO *controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if(controlInfo->ControlDataWidth > 0) + { + UINT32 offset = 0; + UINTN width = 0; + UINT8 *defaultValue = NULL; + + if( UefiIsEfiVariable(controlInfo->ControlVariable,VarGetVariableInfoIndex( controlInfo->ControlVariable ) ) ) + continue; + + offset = UefiGetQuestionOffset(controlInfo->ControlPtr); + width = UefiGetWidth(controlInfo->ControlPtr); + + defaultValue = (Mask & AMI_FLAG_MANUFACTURING)? ((UINT8*)controlInfo + sizeof(CONTROL_INFO)) : + ((UINT8*)controlInfo + sizeof(CONTROL_INFO) + controlInfo->ControlDataWidth); + _VarGetSetValue( VAR_COMMAND_SET_VALUE, *varList, controlInfo->ControlVariable, offset, width, defaultValue ); + } + } + } + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: HiiMyGetStringLength +// +// Description: +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// +UINTN HiiMyGetStringLength( /*EFI_HII_HANDLE*/VOID* handle, UINT16 token ) +{ + CHAR16 *string; + UINTN length = 0; + + string = HiiGetString( handle, token ); + if ( string == NULL ) + return length; + + length = TestPrintLength( string ) / (NG_SIZE); + MemFreePointer( (VOID **)&string ); + + return length; +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiMyGetMultiLineStringLength +// +// Description: returns Max length of the in the paragraph +// +// Input: Handle and token +// +// Output: Length +// +//---------------------------------------------------------------------------- +// + +UINTN HiiMyGetMultiLineStringLength( /*EFI_HII_HANDLE*/VOID* handle, UINT16 token ) +{ + CHAR16 *string; + UINTN length = 0,MaxLength=0; + UINTN i,j; + + string = HiiGetString( handle, token ); + if ( string == NULL ) + return length; + + i=j=0; + while(string[i]) + { + // is Newline + if((string[i]==0x0d)&& (string[i+1]==0x0a)) + { + string[i]=0x0; + length = TestPrintLength( &string[j] ) / (NG_SIZE); + if(length>MaxLength) + MaxLength = length; + i+=2; + j=i; + } + else + i++; + } + length = TestPrintLength( &string[j] ) / (NG_SIZE); + MemFreePointer( (VOID **)&string ); + + if(length>MaxLength) + MaxLength = length; + + return MaxLength; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetAcknowledgementKey +// +// Description: Waits for a Key Press +// +// Parameter: VOID +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetAcknowledgementKey() +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN Index; + EFI_INPUT_KEY Key; + + //Flush Key Stroke + while(gST->ConIn->ReadKeyStroke( gST->ConIn, &Key ) == EFI_SUCCESS) + ; + + status = gBS->WaitForEvent( 1, &gST->ConIn->WaitForKey, &Index ); + if(EFI_ERROR(status)) + { + goto DONE; + } + + status = gST->ConIn->ReadKeyStroke( gST->ConIn, &Key ); + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure : HiiChangeString +// +// Description : to change a existing string +// +// Input : VOID* handle, UINT16 token, CHAR16 *string +// +// Output : Status +// +//---------------------------------------------------------------------------- +// +UINT16 HiiChangeString( /*EFI_HII_HANDLE*/VOID* handle, UINT16 token, CHAR16 *string ) +{ +/* return HiiChangeStringLanguage( handle, token, L" ", string );*/ + UINTN i; + UINT16 returntoken; + UINT16 status = token; + + for ( i = 0; i < gLangCount; i++ ) + { + returntoken = HiiChangeStringLanguage( handle, token, gLanguages[i].Unicode, string ); + if (( token != returntoken ) && ( INVALID_TOKEN != returntoken )) + { + //EIP 25092 : Fix to Use the HiiChangeString() to Add the string for morethen one langs. + //with the same token. + token = status = returntoken; + } + + } + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetFormSetTitleAndHelp +// +// Description: GetFormSetTitleAndHelp +// +// Parameter: EFI_HII_HANDLE Handle, EFI_STRING_ID *Title, EFI_STRING_ID *Help +// +// Return value: status +//---------------------------------------------------------------------------- +// +EFI_STATUS GetFormSetTitleAndHelp(EFI_HII_HANDLE Handle, EFI_STRING_ID *Title, EFI_STRING_ID *Help) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_IFR_FORM_SET *formSet = NULL; + UINT32 index = 0; + UINT8 *pkgHdr = NULL; + + + for(index = 0; index < gSetupCount; index++) + { + if(gSetupData[index].Handle == Handle) + { + pkgHdr = (UINT8*)gSetupData[index].FormSet; + formSet = (EFI_IFR_FORM_SET*)(pkgHdr + sizeof(EFI_HII_PACKAGE_HEADER)); + *Title = formSet->FormSetTitle; + *Help = formSet->Help; + break; + } + } + + if(index == gSetupCount) + { + status = EFI_INVALID_PARAMETER; + } + + return status; +} + +/* +VOID HiiTestFormBrowser(EFI_HANDLE Handle ) +{ + EFI_HII_HANDLE hHandle[3]; + EFI_FORM_BROWSER2_PROTOCOL * pfb; + + _HiiLocateSetupHandles(); + hHandle[0] = gSetupHandles[1]; + hHandle[1] = gSetupHandles[3]; + hHandle[2] = gSetupHandles[4]; + + gBS->HandleProtocol(Handle,&gEfiFormBrowser2ProtocolGuid,&pfb); + pfb->SendForm(pfb,(EFI_HII_HANDLE *)&hHandle,3,NULL,0,NULL,NULL); +} +*/ + +// +//--------------------------------------------------------------------------- +// Procedure: HandleNewIFRPack +// +// Description: Added a new IFR pack data in gSetupData +// +// Input: EFI_HANDLE Handle - Formset handle +// UINT8 *PackData - New pack data to add +// +// Output: EFI_STATUS status - EFI_OUT_OF_RESOURCES if memory allocation fails +// EFI_SUCCESS if successful +//--------------------------------------------------------------------------- +// +EFI_STATUS HandleNewIFRPack(EFI_HANDLE Handle, UINT8 *PackData) +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN length = 0; + UINTN oldSetupCount = 0, size = 0; + UINT8 *formSet = PackData; + UINT32 OldVariableCount = gVariables->VariableCount; + UINTN count = gDynamicPageCount; + EFI_GUID DynamicPageGuid = DYNAMIC_PAGE_COUNT_GUID; + + SETUP_DEBUG_UEFI_NOTIFICATION ( "\n\n[TSE] Entering HandleNewIFRPack()\n\n" ); + + if(gSetupCount == 0) + { + goto DONE; + } + + // Check if Handle contains an IFR formset + //formSet = (UINT8*)HiiGetForm(Handle, 0, &length); + if(NULL == formSet) + { + formSet = (UINT8*)HiiGetForm(Handle, 0, &length); + if (NULL == formSet) + { + goto DONE; + } + } + + oldSetupCount = gSetupCount++; + + // Reallocate gSetupHandles + gSetupHandles = MemReallocateZeroPool(gSetupHandles, oldSetupCount * sizeof (EFI_HII_HANDLE), gSetupCount * sizeof (EFI_HII_HANDLE)); + if(gSetupHandles == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + gSetupHandles[oldSetupCount] = Handle; + + // Reallocate and set gSetupData + gSetupData = MemReallocateZeroPool(gSetupData, oldSetupCount * sizeof(SETUP_LINK), gSetupCount * sizeof(SETUP_LINK)); + if(gSetupData == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(&gSetupData[gSetupCount -1], &gSetupData[oldSetupCount -1], sizeof(SETUP_LINK)); + gSetupData[gSetupCount -1].FormSet = formSet; + gSetupData[gSetupCount -1].Handle = Handle; + _GetClassSubClassID(&gSetupData[gSetupCount -1]); + status = _FxiupNotificationData(&gSetupData[gSetupCount -1]); + UIUpdateCallbackHook((VOID*)Handle, OldVariableCount); // EIP 129750 : Modified UIUpdateCallback as module hook + + if (EFI_SUCCESS == status)//To avoid increment count incase parsing is aborted and avoid showing sub-link under advanced page + count++ ; + gDynamicPageCount = count ; + //Set Dynamic page count variable + VarSetNvramName( L"DynamicPageCount", &DynamicPageGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &count, sizeof(count) ); + VarUpdateVariable(VARIABLE_ID_DYNAMIC_PAGE_COUNT); //EIP_63262: Update nvram cache for DynamicPageCount + +DONE: + SETUP_DEBUG_UEFI_NOTIFICATION ( "\n\n[TSE] Exiting HandleNewIFRPack: status = 0x%x \n\n" , status ); + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: HandleRemoveIFRPack +// +// Description: Removes a IFR pack data from gSetupData +// +// Input: EFI_HANDLE Handle - Formset handle +// +// Output: EFI_STATUS status - EFI_OUT_OF_RESOURCES if memory allocation fails +// EFI_SUCCESS if successful +//--------------------------------------------------------------------------- +// +VOID StopRefreshOpEvent (CONTROL_INFO *controlInfo); +EFI_STATUS HandleRemoveIFRPack(EFI_HANDLE Handle) +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN ii = 0, size = 0; + UINTN count = gDynamicPageCount; + EFI_GUID DynamicPageGuid = DYNAMIC_PAGE_COUNT_GUID; + + SETUP_DEBUG_UEFI_NOTIFICATION ( "\n\n[TSE] Entering HandleRemoveIFRPack()\n\n" ); + + if(gSetupCount == 0) + { + goto DONE; + } + + for(ii = 0; ii < gPages->PageCount; ii++) + { + UINTN control = 0; + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[ii]); + + if(pageInfo->PageHandle != Handle) + { + continue; + } + for(control= 0; (control < pageInfo->PageControls.ControlCount); control++) + { + CONTROL_INFO *controlInfo = NULL; + + controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + if (controlInfo->ControlFlags.RefreshID) + { + StopRefreshOpEvent (controlInfo); + } + controlInfo->ControlHandle = (VOID *)NULL; + } + PageRemoveHook (ii, (VOID *)pageInfo, pageInfo->PageHandle, pageInfo->PageFormID); + pageInfo->PageHandle = (VOID *)(UINTN)0xFFFF; + } + + if(count) + { + count-- ; + gDynamicPageCount = count ; + //Set Dynamic page count variable + VarSetNvramName( L"DynamicPageCount", &DynamicPageGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &count, sizeof(count) ); + VarUpdateVariable(VARIABLE_ID_DYNAMIC_PAGE_COUNT); //EIP_63262: Update nvram cache for DynamicPageCount + + } + + // Find gSetupData and free memory + for(ii = 0; ii < gSetupCount - 1; ii++) + { + if(gSetupData[ii].Handle != Handle) + { + continue; + } + gSetupData[ii].ClassID = 0; + gSetupData[ii].FormSetLength = 0; + gSetupData[ii].Added = 0; + gSetupData[ii].SubClassID = 0; + MemFreePointer(&gSetupData[ii].FormSet); + break; + } +DONE: + SETUP_DEBUG_UEFI_NOTIFICATION ( "\n\n[TSE] Exiting HandleRemoveIFRPack: status = 0x%x \n\n" , status ); + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: HandleAddIFRPack +// +// Description: Adds a IFR pack data from gSetupData +// +// Input: EFI_HANDLE Handle - Formset handle +// UINT8 *PackData - Update pack data to add +// +// Output: EFI_STATUS status - EFI_OUT_OF_RESOURCES if memory allocation fails +// EFI_SUCCESS if successful +//--------------------------------------------------------------------------- +// +EFI_STATUS HandleAddIFRPack(EFI_HANDLE Handle, UINT8 *PackData) +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN length = 0; + UINTN ii = 0, size = 0 ; + UINT32 OldVariableCount = gVariables->VariableCount; + UINTN count = gDynamicPageCount; + EFI_GUID DynamicPageGuid = DYNAMIC_PAGE_COUNT_GUID; + UINT8 *formSetData = PackData; + + + SETUP_DEBUG_UEFI_NOTIFICATION ( "\n\n[TSE] Entering HandleAddIFRPack()\n" ); + + if(gSetupCount == 0) + { + goto DONE; + } + + // Find gSetupData + for(ii = 0; ii < gSetupCount - 1; ii++) + { + if(gSetupHandles[ii] == Handle) + { + break; + } + } + + if(NULL == formSetData) + { + formSetData = (UINT8*)HiiGetForm(Handle, 0, &length); + if(NULL == formSetData) + { + goto DONE; + } + } + + // If iterator ii = gSetupCount - 1 (Should not be the case) + if(ii == gSetupCount - 1) + { + status = HandleNewIFRPack(Handle, formSetData); + goto DONE; + } + + // Replace in gSetupData + gSetupData[ii].FormSet = formSetData; + _GetClassSubClassID(&gSetupData[ii]); + status = _FxiupNotificationData(&gSetupData[ii]); + + UIUpdateCallbackHook((VOID*)Handle, OldVariableCount); // EIP 129750 : Modified UIUpdateCallback as module hook + + if (EFI_SUCCESS == status)//To avoid increment count incase parsing is aborted and avoid showing sub-link under advanced page + count++ ; + gDynamicPageCount = count ; + //Set Dynamic page count variable + VarSetNvramName( L"DynamicPageCount", &DynamicPageGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &count, sizeof(count) ); + VarUpdateVariable(VARIABLE_ID_DYNAMIC_PAGE_COUNT); //EIP_63262: Update nvram cache for DynamicPageCount + +DONE: + SETUP_DEBUG_UEFI_NOTIFICATION ( "\n[TSE] Exiting HandleAddIFRPack: status = 0x%x \n\n" , status ); + return status; +} + + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetFormByFormID +// +// Description: +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// + +VOID *GetFormByFormID(EFI_HII_PACKAGE_HEADER *IFRData, UINT16 FormID, UINTN *Length) +{ + EFI_IFR_OP_HEADER *opHeader = NULL; + UINTN formLength = 0; + UINTN offset = 0; + UINT8 *form = NULL; + UINT8 *formBegin = NULL; + BOOLEAN flag = TRUE; + + offset = sizeof(EFI_HII_PACKAGE_HEADER); + + ResetScopeStack(); + do + { + EFI_IFR_FORM *formOp = NULL; + AMI_EFI_IFR_FORM_MAP *formMapOp = NULL; + UINT8 scope = 0; + + opHeader = (EFI_IFR_OP_HEADER*)((UINT8*)IFRData + offset); + switch(opHeader->OpCode) + { + case EFI_IFR_FORM_OP: + formOp = (EFI_IFR_FORM*)opHeader; + if(formOp->FormId == FormID) + { + formBegin = (UINT8*)opHeader; + } + break; + case EFI_IFR_FORM_MAP_OP: + formMapOp = (AMI_EFI_IFR_FORM_MAP *)opHeader; + if(formMapOp->FormId == FormID) + { + formBegin = (UINT8*)opHeader; + } + break; + case EFI_IFR_END_OP: + PopScope(&scope); + switch(scope) + { + case EFI_IFR_FORM_SET_OP: + flag = FALSE; + break; + case EFI_IFR_FORM_OP: + case EFI_IFR_FORM_MAP_OP: + if(formBegin) + { + flag = FALSE; + } + break; + default: + break; + } + break; + default: + break; + } + if(opHeader->Scope) + { + PushScope(opHeader->OpCode); + } + if(formBegin) + { + formLength += opHeader->Length; + } + offset += opHeader->Length; + }while(flag); + + if(formLength) + { + form = EfiLibAllocateZeroPool(formLength); + if (form == NULL) + { + goto DONE; + } + MemCopy(form, formBegin, formLength); + *Length = formLength; + } + +DONE: + ResetScopeStack(); + return form; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetNextForm +// +// Description: +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// +VOID *GetNextForm(EFI_HII_PACKAGE_HEADER *Package, UINT8 **IFRDataPtr, UINTN *Length) +{ + UINT8 *form = NULL; + UINT8 *formBegin = NULL; + UINTN offset = 0; + UINTN formLen = 0; + UINTN formScope = 0; + BOOLEAN endForm = FALSE; + + static UINTN scopeCount = 0; + + if(Package == NULL) + { + goto DONE; + } + if(*IFRDataPtr == NULL) + { + *IFRDataPtr = (UINT8 *)Package + sizeof(EFI_HII_PACKAGE_HEADER); + scopeCount = 0; + } + + do + { + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER *)(*IFRDataPtr + offset); + switch(opHeader->OpCode) + { + case EFI_IFR_FORM_OP: + case EFI_IFR_FORM_MAP_OP: + formBegin = (UINT8 *)opHeader; + break; + case EFI_IFR_END_OP: + scopeCount -= scopeCount? 1 : 0; + formScope -= formScope? 1 : 0; + endForm = formScope? FALSE : TRUE; + break; + default: + break; + } + if(opHeader->Scope) + { + scopeCount++; + formScope += formBegin? 1 : 0; + } + formLen += formBegin? opHeader->Length : 0; + offset+=opHeader->Length; + }while(endForm == FALSE); + + if(formBegin) + { + form = EfiLibAllocateZeroPool(formLen); + if(form == NULL) + { + *Length = 0; + goto DONE; + } + MemCopy(form, formBegin, formLen); + *Length = formLen; + formBegin += formLen; + *IFRDataPtr += offset; + } + +DONE: + return form; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: FixSetupData +// +// Description: +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// +EFI_STATUS FixSetupData() +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN ii = 0; + + SETUP_DEBUG_UEFI ( "\n[TSE] Entering FixSetupData()\n" ); + + if(gIFRChangeNotify) + { + if(gRemovedHandle!=NULL) + { + UIUpdateCallbackHook((VOID*)gRemovedHandle, gVariables->VariableCount); // EIP 129750 : Modified UIUpdateCallback as module hook + gRemovedHandle = NULL; + gIFRChangeNotify = FALSE; + } + } +//EIP 88658 : Minisetup crashes after controller reconnection during Hii callback + if((gApplicationData == NULL) || (gSetupCount == 0)) + { + status = EFI_UNSUPPORTED; + goto DONE; + } + + for(ii = 0; ii < gPages->PageCount; ii++) + { + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[ii]); + + if(pageInfo->PageHandle != (VOID *)(UINTN)0xFFFF) + { + continue; + } + pageInfo->PageHandle = NULL; + } + + SETUP_DEBUG_UEFI ( "\n[TSE] Exiting FixSetupData(), status = 0x%x \n" , status ); + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _FxiupNotificationData +// +// Description: +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// +EFI_STATUS _FxiupNotificationData(SETUP_LINK *Setup_Link) +{ + EFI_STATUS Status = EFI_SUCCESS; + PAGE_ID_LIST *tempPageIdList = gPageIdList; + PAGE_LIST *tempPages = gPages; + VARIABLE_LIST *tempVariables = gVariables; + + //ReInitialize Setupdata Pointers + _ReInitializeSetupdataPointers(); + //Parse Form + Status = ParseForm(Setup_Link); + // Merge ListPtr and InfoPtr + _MergePageIdListAndInfo(); + _MergeVariableListAndInfo(); + _MergePageListAndInfo(); + + FixMergePagesExtraHook ((VOID *)gPages, (VOID *)tempPages ); + + // Free memory used by temp Ptrs + MemFreePointer((VOID**)&tempPageIdList); + MemFreePointer((VOID**)&tempPages); + MemFreePointer((VOID**)&tempVariables); + + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _ReInitializeSetupdataPointers +// +// Description: +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// +EFI_STATUS _ReInitializeSetupdataPointers() +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 i = 0; + + // Reinitialize PageIdListPtr and PageIdInfoPtr + PageIdListPtr = (PAGE_ID_LIST *)EfiLibAllocateZeroPool(PageIdListSize); + if(PageIdListPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(PageIdListPtr, gPageIdList, PageIdListOffset); + + //Fix Offsets + for(i=0; i < PageIdListPtr->PageIdCount; i++) + { + PageIdListPtr->PageIdList[i] -= PageIdListOffset; + } + + PageIdInfoPtr = (PAGE_ID_INFO *)EfiLibAllocateZeroPool(PageIdInfoSize); + if(PageIdInfoPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(PageIdInfoPtr, (UINT8 *)gPageIdList + PageIdListOffset, PageIdInfoOffset); + + // Reinitialize PageListPtr, FirstPage and PageInfoPtr + PageListPtr = (PAGE_LIST *)EfiLibAllocateZeroPool(PageListSize); + if(PageIdListPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(PageListPtr, gPages, PageListOffset); + //Fix Offsets + for(i = 0; i < PageListPtr->PageCount; i++) + { + PageListPtr->PageList[i] -= (i == 0)? PageListOffset : (FirstPageOffset + PageListOffset); + } + + FirstPage = (PAGE_INFO *)EfiLibAllocateZeroPool(AllocatedFirstPageSize); + if(FirstPage == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(FirstPage, (UINT8 *)gPages + PageListOffset, FirstPageOffset); + + PageInfoPtr = (PAGE_INFO *)EfiLibAllocateZeroPool(PageInfoSize); + if(PageInfoPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(PageInfoPtr, (UINT8 *)gPages + PageListOffset + FirstPageOffset, PageInfoOffset); + + // Reinitialize VariableInfoPtr and VariableListPtr + VariableListPtr = (VARIABLE_LIST *)EfiLibAllocateZeroPool(VariableListSize); + if(VariableListPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(VariableListPtr, gVariables, VariableListOffset); + + //Fix Offsets + for(i=0; i < VariableListPtr->VariableCount; i++) + { + VariableListPtr->VariableList[i] -= VariableListOffset; + } + + VariableInfoPtr = (VARIABLE_INFO *)EfiLibAllocateZeroPool(VariableInfoSize); + if(VariableInfoPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(VariableInfoPtr, (UINT8 *)gVariables + VariableListOffset, VariableInfoOffset); + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: RTIfrUpdateVariableInfo +// +// Description: Wrapper function to include RTIfrUpdateVariableInfo +// based on SDL token. +// +// Input: ControlVariable +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID RTIfrUpdateVariableInfo( UINT32 ControlVariable, EFI_HANDLE Handle ) +{ + VARIABLE_INFO *varInfo = NULL; +// UINT16 *varString; +// UINT16 StringToken = 0; + + + if (ControlVariable < VariableListPtr->VariableCount) + { + varInfo = (VARIABLE_INFO*)((UINT8*)VariableInfoPtr + VariableListPtr->VariableList[ControlVariable]); + if(varInfo->VariableHandle == NULL) + { + varInfo->VariableHandle = Handle; + } + //EIP56405: Commented for suppressing build time parsing. Name value not supported by current vfr compiler. Uncomment it once vfr compiler supports it. + /*if (VARIABLE_ATTRIBUTE_NAMEVALUE == (varInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)) + { + if (0 == (EfiStrLen (varInfo->VariableName))) + { + StringToken = (UINT16)((UINT16)(varInfo->NameValueToken [1] << 8) + (UINT8)(varInfo->NameValueToken [0])); + varString = HiiGetString (varInfo->VariableHandle, StringToken); + EfiStrCpy (varInfo->VariableName, varString); + } + }*/ + }else + { + // ERROR. This case should not Occur.If it Does then DOOM!!! + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiGetEfiKey +// +// Description: Function to Encode the password key +// +// Input: CHAR16 *PwKey +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID HiiGetEfiKey(CHAR16 *PwKey) +{ +// Need to fix this for UEFI 2.1 +/* + EFI_HII_KEYBOARD_LAYOUT *Key + EFI_KEY_DESCRIPTOR *pEfiKD = NULL; //, *pRetEfiKD = NULL; + UINT16 Count = 0,i; + EFI_STATUS Status; + + if(EFI_SUCCESS != HiiInitializeProtocol()) + return; + + //Get Count (No Of Key board Desc) + Status= gHiiDatabase->GetKeyboardLayout(gHiiDatabase, NULL, &Count, pEfiKD); + + if(EFI_BUFFER_TOO_SMALL != Status) + return; + + if(Count) + { + //Allocate space for Count number of EFI_KEY_DESCRIPTOR + pEfiKD = EfiLibAllocateZeroPool(sizeof(EFI_KEY_DESCRIPTOR)*Count); + + Status= gHiiDatabase->GetKeyboardLayout(gHiiDatabase, &Count, pEfiKD); + + if(EFI_SUCCESS == Status) + { + for(i=0;iKey; + break; + } + } + } + MemFreePointer((VOID **)&pEfiKD); + } +*/ +} +//EIP:56413 START +// +//---------------------------------------------------------------------------- +// Procedure: UefiupdateResetButtonDefault +// +// Description: Function to update defaults depending on the Default Id on Selecting the Reset Button +// +// Input: CONTROL_INFO ControlData, UINT16 DefaultId +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiupdateResetButtonDefault(CONTROL_INFO ControlData, UINT16 DefaultId) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 control, offset = 0; + UINTN index=0, size = 0; + UINT8 *Defaultaddress = 0; + + //Getting the current page info + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[ControlData.ControlPageID]); + + if (NULL != pageInfo && 0 == pageInfo->PageHandle) + return EFI_UNSUPPORTED; + + for ( control= 0; control < pageInfo->PageControls.ControlCount; control++ ) + { + CONTROL_INFO *controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + index=0; + //checking for the Default count of the control + while(index < controlInfo->DefaultStoreCount) + { + Defaultaddress = (UINT8 *)controlInfo + sizeof(CONTROL_INFO)+(controlInfo->ControlDataWidth * 2)+(index *(sizeof(UINT16) + controlInfo->ControlDataWidth)); + //checking for the default Id of the Resetbutton + if(DefaultId == (UINT16)*Defaultaddress) + { + offset = UefiGetQuestionOffset(controlInfo->ControlPtr); + size = UefiGetWidth(controlInfo->ControlPtr); + status = VarSetValue(controlInfo->ControlVariable, offset, size, Defaultaddress+sizeof(UINT16) ); + } + index++; + } + //EIP:57402 Checking for the ControlEvaluateDefault Flag and the Default Id equal tp Manufacturing Id + if(controlInfo->ControlFlags.ControlEvaluateDefault) + { + UINT64 Defaults = 0 ; + UINT16 size = 0; + offset = UefiGetQuestionOffset(controlInfo->ControlPtr); + + //EIP: 57402 Evaluating the Control Default + size = EvaluateControlDefault(controlInfo,&Defaults); + status = VarSetValue(controlInfo->ControlVariable, offset, size, &Defaults ); + // EIP: 57402 Setiing the Evaluated value to the gOptimalDefaults + if(DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) + _VarGetSetValue( VAR_COMMAND_SET_VALUE, gOptimalDefaults, controlInfo->ControlVariable, offset, size, &Defaults ); + } + } + + return status; + +} +//EIP:56413 END + +//EIP-83080 Start +// +//--------------------------------------------------------------------------- +// Procedure: GetDevPathFromHandle +// +// Description: Get the device path for the the given handle +// +// Input: EFI_HII_HANDLE HiiHandle - Input handle +// EFI_DEVICE_PATH_PROTOCOL **DevicePath - Corresponding device path +// if successful. +// +// Output: EFI_STATUS Status - EFI_SUCCESS, if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS GetDevPathFromHandle(EFI_HII_HANDLE HiiHandle, EFI_DEVICE_PATH_PROTOCOL **DevicePath) +{ + EFI_STATUS Status = EFI_INVALID_PARAMETER; + EFI_HANDLE DriverHandle = (EFI_HANDLE)NULL; + EFI_DEVICE_PATH_PROTOCOL *TempDevPath = (EFI_DEVICE_PATH_PROTOCOL *)NULL; + + *DevicePath = TempDevPath; + + Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, HiiHandle, &DriverHandle); + if(EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->HandleProtocol (DriverHandle, &gEfiDevicePathProtocolGuid, &TempDevPath); + if(Status == EFI_SUCCESS){ + *DevicePath = TempDevPath; + } + + return Status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: GetStringFromDevPath +// +// Description: Gets the string presentation of the given DevicePath +// +// Input: EFI_DEVICE_PATH_PROTOCOL *DevPath - Given device path +// CHAR16 **DevPathStr - Return pointer to the string presentation +// +// Output: EFI_STATUS status - EFI_SUCCESS, if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS GetStringFromDevPath(EFI_DEVICE_PATH_PROTOCOL *DevPath, CHAR16 **DevPathStr) +{ + EFI_STATUS status = EFI_ABORTED; + + if(gDevPathToTextProtocol == NULL) + { + status = gBS->LocateProtocol(&gDevPathToTextGuid, NULL, &gDevPathToTextProtocol); + } + if(gDevPathToTextProtocol != NULL) + { + *DevPathStr = gDevPathToTextProtocol->ConvertDevicePathToText(DevPath, FALSE, FALSE); + status = EFI_SUCCESS; + } + return status; +} +//EIP: 83080 End + + +//EIP: 132359 Start +// +//--------------------------------------------------------------------------- +// Procedure: FixIFRRefXControl +// +// Description: Updates the parent pageID for the EFI_IFR_REFX +// control +// +// Input: CONTROL_INFO * CtrlInfo - Control Info in the library +// PAGE_INFO *PageInfo - Page Info in the library +// +// Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS FixIFRRefXControl(PAGE_INFO *PageInfo, CONTROL_INFO * CtrlInfo) +{ + EFI_STATUS status = EFI_NOT_FOUND; + UINT32 i=0; + PAGE_INFO *pageInfo; + + for (i = 0; i < gPages->PageCount; i++) + { + pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[i]); + if (pageInfo->PageID == CtrlInfo->ControlDestPageID) + { + pageInfo->PageParentID = PageInfo->PageID ; //CtrlInfo->ControlPageID; + status = EFI_SUCCESS; + break; + } + } + + return status; +} +//EIP: 55762 Start +// +//--------------------------------------------------------------------------- +// Procedure: UpdateIFRRefXControls +// +// Description: Updates the reference link information in for the EFI_IFR_REFX +// controls +// +// Input: CONTROL_INFO * CtrlInfo - Control Info in the library +// BOOLEAN *PgHasRefXCtrl - Return TRUE if REF4 control found +// +// Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS UpdateIFRRefXControls(PAGE_INFO *PageInfo, CONTROL_INFO * CtrlInfo) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *tempDevPath = (EFI_DEVICE_PATH_PROTOCOL *)NULL; + BOOLEAN IsQuestionIdValid = FALSE; + BOOLEAN IsFormSetIdValid = FALSE; + BOOLEAN IsDevicePathFound = FALSE; + EFI_GUID formSetGuid = {0}, zeroFormSetGuid = {0}; + UINT16 ControlDestPageID = 0xFFFF; + UINT16 ControlDestQuestionID = 0xFFFF; + UINTN count = 0; + UINTN control = 0; + PAGE_INFO *pageInfo = (PAGE_INFO*)NULL; + PAGE_ID_INFO *pageIdInfo = (PAGE_ID_INFO*)NULL; + + CHAR16 *devPathStr = (CHAR16 *)NULL, *tempDevPathStr = (CHAR16 *)NULL; + + if((CtrlInfo == NULL) || (CtrlInfo->ControlPtr == NULL)) + { + status = EFI_INVALID_PARAMETER; + goto DONE; + } + + if(CtrlInfo->ControlHandle == NULL) + { + status = EFI_INVALID_PARAMETER; + goto DONE; + } + + if(((EFI_IFR_OP_HEADER*)CtrlInfo->ControlPtr)->OpCode != EFI_IFR_REF_OP) + { + status = EFI_INVALID_PARAMETER; + goto DONE; + } + + //EIP109812, 107774 + if(((EFI_IFR_OP_HEADER *)CtrlInfo->ControlPtr)->Length == sizeof(AMI_EFI_IFR_REF5)) //If AMI_EFI_IFR_REF5 + { + if(CtrlInfo->ControlDataLength == sizeof(AMI_EFI_HII_REF)) //if default value is of size AMI_EFI_HII_REF, retrieve its value + { + AMI_EFI_HII_REF *Ref = NULL ; + Ref = (AMI_EFI_HII_REF*)((UINT8*)CtrlInfo + sizeof(CONTROL_INFO) + CtrlInfo->ControlDataLength); //take the default value + if(Ref) + { + //fetch the destination questionId + ControlDestQuestionID = Ref->QuestionId; //Set the destination question ID to set focus + if(Ref->DevicePath) //if device path is provided + { + devPathStr = HiiGetString(CtrlInfo->ControlHandle, Ref->DevicePath); //get the text representation of device path + if(devPathStr == NULL) //If the device path string is invalid, remain the same + { + CtrlInfo->ControlDestPageID = PageInfo->PageID; //The link refers to the current page + CtrlInfo->DestQuestionID = CtrlInfo->QuestionId; //set the current control's question Id as the destination question Id. + goto DONE; + } + else + { //If the device path string is not NULL + CHAR16 *zeroDevPathStr = (CHAR16 *)EfiLibAllocateZeroPool(MAX_DEV_PATH_STR_LEN * sizeof(CHAR16)); + if(zeroDevPathStr) + { + //MemSet(&zeroDevPathStr[0], MAX_DEV_PATH_STR_LEN * sizeof(CHAR16), L'0'); + MemSet(&zeroDevPathStr[0], MAX_DEV_PATH_STR_LEN * sizeof(CHAR16), 0); + if(EfiStrCmp(devPathStr, zeroDevPathStr) == 0) //If the DevicePath string contains all zeros, remain the same page. + { + CtrlInfo->ControlDestPageID = PageInfo->PageID; //The link refers to the current page + CtrlInfo->DestQuestionID = CtrlInfo->QuestionId; //set the current control's question Id as the destination question Id. + goto DONE; + } + } + } + //Device Path is not zero. check whether the provided device path is found. + for(count = 0; count < gPages->PageCount; count++) + { + PAGE_INFO *tempPageInfo = (PAGE_INFO*)((UINTN)gApplicationData + gPages->PageList[count]); + if(tempPageInfo == NULL) + { + continue; + } + status = GetDevPathFromHandle(tempPageInfo->PageHandle, &tempDevPath); + if((status == EFI_SUCCESS) && (tempDevPath != NULL)) + { + GetStringFromDevPath(tempDevPath, &tempDevPathStr); + if(EfiStrCmp(devPathStr, tempDevPathStr) == 0) //if the provided device path is found + { + CtrlInfo->ControlDestPageID = tempPageInfo->PageID; //set that page ID + ControlDestPageID = tempPageInfo->PageID; + IsDevicePathFound = TRUE; + break; + } + } + } + if(!IsDevicePathFound) //if provided device path is not found, remain the same + { + CtrlInfo->ControlDestPageID = PageInfo->PageID; //The link refers to the current page; + CtrlInfo->DestQuestionID = CtrlInfo->QuestionId; //set the current control's page ID itself as destination page Id. + goto DONE; + } + } + else //if device path is not provided + { + //get formset GUID + MemCopy(&formSetGuid, &(Ref->FormSetGuid), sizeof (EFI_GUID)); + if(EfiCompareGuid(&formSetGuid, &zeroFormSetGuid) == FALSE) //If it is not all zeroes + { + GetPageIdFromGuid(&formSetGuid, Ref->FormId, &ControlDestPageID); + if(ControlDestPageID != 0xFFFF) //If the destination page ID is valid + { + CtrlInfo->ControlDestPageID = ControlDestPageID; //Assign it to CONTROL_INFO->ControlDestPageID + IsFormSetIdValid = TRUE; + } + } + if(!IsFormSetIdValid) //if formset Id is invalid, remain the same + { + CtrlInfo->ControlDestPageID = PageInfo->PageID; //The link refers to the current page; + CtrlInfo->DestQuestionID = CtrlInfo->QuestionId; //set the current control's page ID itself as destination page Id. + goto DONE; + } + } + //at this point either through device path or formset ID the destination page ID will be obtained. + //check whether the provided Dest. Question ID exist in that destination page + pageInfo = (PAGE_INFO*)((UINT8 *)gPages + gPages->PageList[ControlDestPageID]); + if(pageInfo->PageHandle == NULL) + { + CtrlInfo->ControlDestPageID = PageInfo->PageID; //The link refers to the current page; + CtrlInfo->DestQuestionID = CtrlInfo->QuestionId; //set the current control's page ID itself as destination page Id. + goto DONE; + } + for(control = 0; control < pageInfo->PageControls.ControlCount; control++) //check if the destination Question ID is exists in any of + { //the availble controls of the page. + CONTROL_INFO *controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + if(ControlDestQuestionID == controlInfo->ControlKey) + { + IsQuestionIdValid = TRUE; + CtrlInfo->ControlDestPageID = ControlDestPageID; //Assign it to CONTROL_INFO->ControlDestPageID + CtrlInfo->DestQuestionID = ControlDestQuestionID; + break; + } + } + if(!IsQuestionIdValid) //if the provided Question ID is invalid, remain the same + { + CtrlInfo->ControlDestPageID = PageInfo->PageID; //The link refers to the current page; + CtrlInfo->DestQuestionID = CtrlInfo->QuestionId; //set the current control's page ID itself as destination page Id. + } + } + } + } + + else if(((EFI_IFR_OP_HEADER *)CtrlInfo->ControlPtr)->Length >= sizeof(EFI_IFR_REF2)) //If EFI_IFR_REFX + { + CtrlInfo->DestQuestionID = ((EFI_IFR_REF2 *)CtrlInfo->ControlPtr)->QuestionId; //Set the destination question ID to set focus + + if(((EFI_IFR_OP_HEADER *)CtrlInfo->ControlPtr)->Length >= sizeof(EFI_IFR_REF3)) //If EFI_IFR_REF3/EFI_IFR_REF4 + { + + MemCopy(&formSetGuid, &((EFI_IFR_REF3 *)CtrlInfo->ControlPtr)->FormSetId, sizeof (EFI_GUID)); + + if(EfiCompareGuid(&formSetGuid, &zeroFormSetGuid) == FALSE) //If it is not all zeroes + { + GetPageIdFromGuid(&formSetGuid, ((EFI_IFR_REF3 *)CtrlInfo->ControlPtr)->FormId, &ControlDestPageID); + if(ControlDestPageID != 0xFFFF) //If the destination page ID is valid + { + CtrlInfo->ControlDestPageID = ControlDestPageID; //Assign it to CONTROL_INFO->ControlDestPageID + IsFormSetIdValid = TRUE; + FixIFRRefXControl(PageInfo, CtrlInfo); + } + } + + if(((EFI_IFR_OP_HEADER *)CtrlInfo->ControlPtr)->Length >= sizeof(EFI_IFR_REF4)) //If EFI_IFR_REF4 + { + + + devPathStr = HiiGetString(CtrlInfo->ControlHandle, ((EFI_IFR_REF4 *)CtrlInfo->ControlPtr)->DevicePath); + if(devPathStr == NULL) //If the device path string is invalid + { + CtrlInfo->ControlDestPageID = PageInfo->PageID; //The link refers to the current page + goto DONE; + } + else + { //If the device path string is valid + CHAR16 *zeroDevPathStr = (CHAR16 *)EfiLibAllocateZeroPool(MAX_DEV_PATH_STR_LEN * sizeof(CHAR16)); + if(zeroDevPathStr) + { + MemSet(&zeroDevPathStr[0], MAX_DEV_PATH_STR_LEN * sizeof(CHAR16), L'0'); + if(EfiStrCmp(devPathStr, zeroDevPathStr) == 0) //If the DevicePath string contains all zeros + { + CtrlInfo->ControlDestPageID = PageInfo->PageID; //The link refers to the current page + goto DONE; + } + } + } + + for(count = 0; count < gPages->PageCount; count++) + { + PAGE_INFO *tempPageInfo = (PAGE_INFO*)((UINTN)gApplicationData + gPages->PageList[count]); + if(tempPageInfo == NULL) + { + continue; + } + status = GetDevPathFromHandle(tempPageInfo->PageHandle, &tempDevPath); + if((status == EFI_SUCCESS) && (tempDevPath != NULL)) + { + GetStringFromDevPath(tempDevPath, &tempDevPathStr); + if(EfiStrCmp(devPathStr, tempDevPathStr) == 0) + { + CtrlInfo->ControlDestPageID = tempPageInfo->PageID; + IsDevicePathFound = TRUE; + break; + } + } + } + if(!IsDevicePathFound) //the provided device path is not found, hence remain in the same page. + { + CtrlInfo->ControlDestPageID = PageInfo->PageID; //The link refers to the current page + goto DONE; + } + } + else + { //If the Device path is not present + if(IsFormSetIdValid == FALSE) //If the FormSetId is invalid + { + PAGE_ID_INFO *pageIdInfo = (PAGE_ID_INFO *)(((UINT8 *) gPageIdList) + gPageIdList->PageIdList[PageInfo->PageIdIndex]); + if(pageIdInfo) + { + ControlDestPageID = 0xFFFF; + GetPageIdFromGuid(&(pageIdInfo->PageGuid), ((EFI_IFR_REF3 *)CtrlInfo->ControlPtr)->FormId, &ControlDestPageID); + if(ControlDestPageID != 0xFFFF) //If the destination page ID is valid, assign it to CONTROL_INFO->ControlDestPageID + { + CtrlInfo->ControlDestPageID = ControlDestPageID; + } + } + } + } + } + } + +DONE: + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: GetPageIdFromGuid +// +// Description: Finds the page ID with matching Guid from the page list +// +// Input: EFI_GUID *FormGuid +// UINT16 *PageID +// +// Output: EFI_STATUS status - EFI_SUCCESS, if successful, +// EFI_INVALID_PARAMETER, if invalid values found +//--------------------------------------------------------------------------- +// +EFI_STATUS GetPageIdFromGuid(EFI_GUID *FormGuid, UINT16 PageFormID, UINT16 *PageID) +{ + EFI_STATUS status = EFI_INVALID_PARAMETER; + UINT32 pgIndex = 0; + PAGE_INFO *pgInfo = (PAGE_INFO *)NULL; + PAGE_ID_INFO *pageIdInfo = (PAGE_ID_INFO*)NULL; + + if(gPages && gApplicationData && gPageIdList) + { + for(pgIndex = 0; pgIndex < gPages->PageCount; pgIndex++) + { + pgInfo = (PAGE_INFO*)((UINTN)gApplicationData + gPages->PageList[pgIndex]); + if ((NULL != pgInfo) && (NULL == pgInfo->PageHandle)) //EIP133981 if relash module formsetguid passed then it will return the pageid + continue; //so this should not happen when the resource not published so added the condition + if(pgInfo->PageFormID == PageFormID) + { + pageIdInfo = (PAGE_ID_INFO *)(((UINT8 *) gPageIdList) + gPageIdList->PageIdList[pgInfo->PageIdIndex]); + if(pageIdInfo && (EfiCompareGuid(FormGuid, &(pageIdInfo->PageGuid)) == TRUE))//Compare Guid + { + *PageID = pgInfo->PageID; + status = EFI_SUCCESS; + goto DONE; + } + } + } + } + +DONE: + return status; +} +//EIP: 55762 End + +//EIP75588 starts +// +//--------------------------------------------------------------------------- +// Procedure: FindHandleWithInSetupData +// +// Description: Checks if the given handle is avaiable in the scope of the +// current formset. +// +// Input: EFI_HII_HANDLE Handle +// +// Output: EFI_STATUS Status - EFI_NOT_FOUND, if not found, else EFI_SUCCESS +//--------------------------------------------------------------------------- +// +EFI_STATUS FindHandleWithInSetupData (EFI_HII_HANDLE Handle) +{ + EFI_STATUS Status = EFI_NOT_FOUND; + UINTN i = 0; + + if (gSetupData) //Check if the notification is within out formset's scope + { + for (i = 0; i < gSetupCount; i++) + { + if (gSetupData[i].Handle == Handle) + { + Status = EFI_SUCCESS; + break; + } + } + } + return Status; +} +//EIP75588 ends + +// +//--------------------------------------------------------------------------- +// Procedure: GetRWVariableID +// +// Description: Returns the variable ID for read write operation +// +// Input: UINT16, CONTROL_INFO *, UINT16 * +// +// Output: EFI_STATUS +//--------------------------------------------------------------------------- +// +EFI_STATUS GetRWVariableID (UINT16 RWVarStoreId, CONTROL_INFO *ControlInfo, UINT16 *VarStoreId) +{ + VARIABLE_INFO *varInfo = NULL; + UINT32 index = 0; + + for (index = 0; index < gVariables->VariableCount; index++) + { + varInfo = (VARIABLE_INFO *)VarGetVariableInfoIndex(index); + //EIP-75352 Suppress the warnings from static code analyzer + if(NULL == varInfo) + { + continue; + } + if ((ControlInfo->ControlHandle == varInfo->VariableHandle) && (varInfo->VariableID == RWVarStoreId)) + { + *VarStoreId = index; + return EFI_SUCCESS; + } + } + return EFI_NOT_FOUND; +} + +// +//--------------------------------------------------------------------------- +// Procedure: StopRefreshOpEvent +// +// Description: Stops the refresh event +// +// Input: CONTROL_INFO * +// +// Output: VOID +//--------------------------------------------------------------------------- +// +VOID StopRefreshOpEvent (CONTROL_INFO *controlInfo) +{ + CONTROL_INFO *RefreshEventcontrolInfo = (CONTROL_INFO *)NULL; + UINTN index; + EFI_STATUS Status = EFI_UNSUPPORTED; + + if (gRefreshIdInfo) + { + for(index = 0; index < gRefreshIdCount; index++) + { + if(gRefreshIdInfo[index].pEvent) //Close the event + { + RefreshEventcontrolInfo = (CONTROL_INFO *)gRefreshIdInfo[index].pNotifyContext; + if ( + (controlInfo->ControlHandle == RefreshEventcontrolInfo->ControlHandle) && + (controlInfo->ControlConditionalPtr == RefreshEventcontrolInfo->ControlConditionalPtr) && + (controlInfo->ControlPtr == RefreshEventcontrolInfo->ControlPtr) + ) + { + Status = gBS->CloseEvent (gRefreshIdInfo[index].pEvent); + if(Status == EFI_SUCCESS) + { + gRefreshIdInfo[index].pEvent = NULL; + } //Dont free the pNotifyContext might be using in formcallback, so freeing here will crash in formcallback. Free in MiniSetupUIExit + break; + } + } + } + } +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** \ No newline at end of file diff --git a/EDK/MiniSetup/uefi2.1/HiiCallback.c b/EDK/MiniSetup/uefi2.1/HiiCallback.c new file mode 100644 index 0000000..b78fa49 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/HiiCallback.c @@ -0,0 +1,1073 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (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/Uefi2.1/HiiCallback.c $ +// +// $Author: Arunsb $ +// +// $Revision: 41 $ +// +// $Date: 7/03/13 11:25a $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/HiiCallback.c $ +// +// 41 7/03/13 11:25a Arunsb +// Validated gApplicationData to NULL. In some case gApplicationData is +// NULL then it leading to hang. +// +// 40 5/22/13 11:02a Arunsb +// [TAG] EIP123047 +// Password retrieved only for its string not for entire size. So password +// not validated properly, changed upto entire size. +// +// 39 4/17/13 2:37p Arunsb +// [TAG] EIP109812, 107774 +// [Category] Improvement +// [Description] Provide support for EFI_IFR_TYPE_REF and EFI_IFR_REF5 +// [Files] Hii.c, HiiCallback.c, Parse.c and TseUefiHii.h +// +// 38 4/16/13 11:44a Arunsb +// EFI_IFR_TYPE_UNDEFINED declaration moved to tseuefihii.h +// +// 37 3/12/13 11:35p Rajashakerg +// [TAG] EIP105167 +// [Category] Improvement +// [Description] Making the specify setup items departing from F2/F3 +// effect. +// [Files] AMITSE.sdl, CommonHelper.c, callback.c, minisetupext.h, +// PopupPassword.c, SubMenu.c, HiiCallback.c +// +// 36 3/12/13 7:05a Rajashakerg +// [TAG] EIP105167 +// [Category] Improvement +// [Description] Making the specify setup items departing from F2/F3 +// effect. +// [Files] AMITSE.sdl, CommonHelper.c, callback.c, minisetupext.h, +// PopupPassword.c, SubMenu.c, HiiCallback.c +// +// 35 3/08/13 1:39a Rajashakerg +// [TAG] EIP113085 +// [Category] Improvement +// [Description] Modify callback function behavior to match UEFI SPEC. +// [Files] HiiCallback.c, PopupPassword.c, SubMenu.c +// +// 34 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 11 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 32 9/17/12 6:22a Rajashakerg +// Updated EIP changes for 2.16 release. +// +// 30 9/10/12 10:38a Arunsb +// [TAG] EIP90372 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Setup browser handling of +// EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD +// [RootCause] For discard action current value is saved +// [Solution] Introduced a global variable which will set for discard +// action for that current value will not be saved +// [Files] HiiCallback.c and Uefi21Wapper.c +// +// 29 5/29/12 4:46a Arunsb +// [TAG] EIP91109 +// [Category] Improvement +// [Description] Sync the Aptio IV source for AptioV +// +// 28 5/26/12 5:21a Arunsb +// [TAG] EIP90895 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Setup hangs when retrieve callback produces +// add/remove/update forms +// [RootCause] Callback with retrieve action produces add/remove/update +// form +// [Solution] If retrieve callback produces add/remove/update form then +// TSE will print debug messages and assert. +// [Files] HiiNotificationHandler.c, HiiCallback.c and FormBrowser2.c +// +// 27 5/09/12 1:32p Arunsb +// [TAG] EIP86885 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] ISCSI attempt order is not changing on setup +// [RootCause] Orderlist maxcontainers value and ordered list size not +// handled properly +// [Solution] Orderlist maxcontainers value is 0xff, but TSE changed the +// cache value for only the added attempts(dynamic orderlist creation) +// remaining buffer left as is, Now the remaining buffers made as 0. +// [Files] HiiCallback.c and ordlistbox.c +// +// 26 4/19/12 6:09p Blaines +// [TAG] - EIP 88031 +// [Category]- Defect +// [Synopsis]- Hii Callbacks may enter infinite loop on +// BROWSER_ACTION_RETRIEVE +// [Solution] - Only allow EFI_BROWSER_ACTION_RETRIEVE action for all +// Interactive controls from MiniSetupEntry. +// [Files] - Submenu.c, HiiCallback.c, +// +// 25 4/05/12 12:49p Arunsb +// [TAG] EIP83252 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] System hangs with onboard SAS Option ROM +// [RootCause] ProcessPackNotification not invoked properly +// [Solution] gEnableDrvNotification flag handled properly to invoke +// ProcessPackNotification +// [Files] uefi2.1\hiicallback.c and uefi2.1\uefi21wapper.c +// +// 24 2/02/12 3:00a Premkumara +// [TAG] EIP75066 +// [Category] Improvement +// [Description] Support loading defaults for Ordelist controls +// [Files] Ordlistbox.c, Uefi21Wapper.c, CtrlCond.c, HiiCallback.c, +// Parse.c, Uefi20Wapper.c, TseUefihiil.h +// +// 23 12/16/11 2:01a Arunsb +// [TAG] EIP78100 +// [Category] Bug Fix +// [Severity] Critical +// [Symptom] TSE 2.15 can't enter Setup menu +// [RootCause] Tried to access the NULL controldata +// [Solution] Controldata validated for NULL +// [Files] Hiicallback.c and uefihpktool.exe +// +// 22 12/08/11 4:33p Arunsb +// [TAG] EIP75536 +// [Category] Improvement +// [Description] String handling inside the callbacks in Minisetup +// [Files] Hiicallback.c and hiistring21.c +// +// 21 12/08/11 12:29a Arunsb +// ProcessBrowserActionRequestHook declaration changed +// +// 20 12/07/11 3:02p Arunsb +// [TAG] EIP75588 +// [Category] New Feature +// [Description] Support for queuing UpdatePack notifications +// [Files] frame.c, page.c, formbrowser2.c, hii.c, hiicallback.c, +// hiinotificationhandler.c, tseuefihii.h and uefi21wapper.c +// +// 19 12/07/11 2:22p Rajashakerg +// [TAG] EIP75572 +// [Category] Improvement +// [Description] Callback for Date and Time doesn't pass the new value +// [Files] HiiCallback.c +// +// 18 12/07/11 9:31a Rajashakerg +// [TAG] EIP77108 +// [Category] Improvement +// [Description] Make ProcessBrowserActionRequest as board module hook +// [Files] AMITSE.sdl, CommonHelper.c, HiiCallback.c +// +// 17 12/07/11 8:14a Rajashakerg +// [TAG] EIP75118 +// [Category] Improvement +// [Description] xtractConfig() fail since BrowserCallback() cannot find +// the variable to process +// [Files] FormBrowser2.c, FormBrowser2.h, HiiCallback.c, +// Uefi21Wapper.c, PopupSel.c +// +// 16 12/01/11 12:38p Premkumara +// [TAG] EIP75536 +// [Category] Improvement +// [Description] 1.String handling inside the callbacks in +// Minisetup.Adding Null termination for String and Password control type. +// 2.Iterate to check the available language and add/change the string +// only for the passed language. +// [Files] HiiCallback.c, hiistring21.c +// +// 15 12/01/11 11:22a Rajashakerg +// UefiGetValidOptionSize() function declared to resolve build error. +// +// 14 12/01/11 7:44a Rajashakerg +// [TAG] EIP75464 +// [Category] Improvement +// [Description] Improper handling of action controls +// [Files] SubMenu.c, UefiAction.c, HiiCallback.c, Uefi21Wapper.c +// +// 13 11/28/11 5:10a Rajashakerg +// [TAG] EIP73231 +// [Category] Improvement +// [Description] Callback handling :For interactive controls updating +// the currnet vaule in cache even when hii callback returns error status. +// [Files] Date.c, SubMenu.c, ordlistbox.c, time.c, UefiAction.c, +// hii.h, uefi20Wapper.c, HiiCallback.c, TseUefiHii.h, Uefi21Wapper.c +// +// 12 11/14/11 2:43p Blaines +// [TAG] - EIP 75481 +// [Category]- Function Request +// [Synopsis]- TSE debug print infrastructure. +// [Description]- Add TSE debug print info for basic functions such as +// Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms +// data. +// [Files] +// AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c +// Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c, +// HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h, +// Uefi21Wrapper.c, setupdbg.h +// +// 11 7/19/11 2:33p Arunsb +// Suppressing the callback for AMI_CALLBACK_FORM_OPEN action +// +// 10 4/22/11 5:31p Arunsb +// [TAG] EIP58009 +// [Category] Bug Fix +// [Severity] Normal +// [RootCause] Certain controls not compatible with UEFI 2.3 version +// [Solution] The UEFI 2.3 features will be added only if core supports +// it +// [Files] HiiCallback.c and commonhelper.c +// +// 9 3/21/11 12:58a Rajashakerg +// [TAG] EIP53480 +// [Category] Improvement +// [Description] FormBrowser extended actions support +// [Files] callback.c, minisetupext.c, minisetupext.h, numeric.c, +// PopupSel.c, PopupString.c, SubMenu.c, TseLiteCommon.c, UefiAction.c, +// Hiicallback.c, TseUefiHii.h, Uefi21Wapper.c, HiiCallback.c +// +// 8 3/09/11 7:26p Madhans +// [TAG] EIPEIP48615 +// [Category] Improvement +// [Description] To support UEFI 2.1 RefreshOp. Based in Refersh Rate +// Controls are refershed periodically. +// [Files] minisetupext.h +// SubMenu.h +// SubMenu.c +// Memo.c +// Memo.h +// numeric.c +// numeric.h +// time.c +// Date.c +// PopupSel.c +// PopupSel.h +// PopupString.c +// PopupString.h +// ordlistbox.c +// minisetupext.c +// UefiAction.c +// hii.h +// Uefi20wapper.c +// hiicallback.c +// Parse.c +// tseuefihii.h +// Uefi21wapper.c +// +// 7 12/02/10 6:09p Madhans +// [TAG] - EIP49562 +// [Category]- Improvment. +// [Severity]- Mordarate +// [Symptom]- Need to support UEFI 2.2 requirements related to Calling +// Formcallback with +// EFI_BROWSER_ACTION_CHANGING and EFI_BROWSER_ACTION_CHANGED action. +// [Solution]- Implemented the support. +// [Files] - submenu.c, numeric.c, popupsel.c, popupString.c, +// uefi20\hii.h, uefi20\uefi20wrapper.c +// uefi21\hiicalback.c, uefi21\tseuefihii.h +// +// 6 6/17/10 2:59p Madhans +// Dynamic parsing support in TSE. +// +// 5 4/16/10 5:13p Madhans +// Changes for Tse 2.02. Please see Changelog.log for more details. +// +// 4 2/19/10 8:50p Madhans +// +// 4 11/30/09 1:10p Presannar +// Modified ConfigAccessCallback EFI_BROWSER_ACTION from pass by reference +// to pass by value +// +// 3 11/19/09 5:31p Presannar +// Updated TSE include file name to not clash with CORE file +// +// 2 8/11/09 2:49p Presannar +// Added code to FormCallBack by calling FixSetupData after +// ConfigAccess->Callback to handle dynamic removal of IFR data +// Added code to handle callback for EFI_IFR_REF_OP opcode +// +// 1 7/24/09 6:54p Presannar +// +// 5 4/24/09 7:54p Presannar +// TSE 2.0 UEFI 2.1 Code Complete +// +// 4 4/14/09 12:41p Presannar +// Added Fn SpecialActionCallBack +// Modified fn signature FormCallBack +// +// 3 3/31/09 4:15p Madhans +// UEFI Wrapper improvments. +// +// 2 1/29/09 6:08p Presannar +// Added Function Header comments +// Modified implementation for fn CallFormCallBack and CallTextCallBack +// +// 1 1/09/09 2:38p Presannar +// UEFI 2.1 Hii Related Code - Initial Drop +// +// 1 12/29/08 4:45p Presannar +// Initial draft Form Callback handler +// +//************************************************************************* +// +// +// Name: HiiCallback.c +// +// Description: Contains Hii related Functions +// +// +//************************************************************************* + +//---------------------------------------------------------------------------- +#include "Minisetup.h" +#include "FormBrowser2.h" +#include "TseUefiHii.h" +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +static UINT8 *gPrevControlValue = NULL; +static CHAR16 *gCurPswdString = NULL; +extern UINT16 gOrderlistcount; +extern BOOLEAN gEnableDrvNotification; //TRUE if allow notification function to process action, FALSE to ignore the notification +extern BOOLEAN gBrowserCallbackEnabled; //Allow external drivers to change cache only if it's TRUE; ignore browser callback otherwise +extern EFI_BROWSER_ACTION gBrowserCallbackAction ; //Contains the BrowserCallback action when a callback is in progress. +EFI_STATUS ProcessBrowserActionRequestHook(EFI_BROWSER_ACTION_REQUEST actionReq);//EIP77108 : Modified ProcessBrowserActionRequest as board module hook +//---------------------------------------------------------------------------- + +UINT32 GetUefiSpecVersion (VOID); +VOID UefiGetValidOptionSize(CONTROL_INFO *CtrlInfo, UINT32 *SizeOfData); + +// +//---------------------------------------------------------------------------- +// +// Procedure: FormCallBack +// +// Description: +// +// Parameter: EFI_HII_HANDLE Handle, EFI_QUESTION_ID QuestionID, +// UINT8 Type, EFI_IFR_TYPE_VALUE *Value +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS FormCallBack(EFI_HII_HANDLE Handle, EFI_QUESTION_ID QuestionID, UINT8 Type, EFI_IFR_TYPE_VALUE *Value, EFI_BROWSER_ACTION action) +{ + EFI_HANDLE DriverHandle; + EFI_GUID EfiHiiConfigAccessProtocolGuid = EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID; + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; + EFI_BROWSER_ACTION_REQUEST actionReq = EFI_BROWSER_ACTION_REQUEST_NONE; + //EFI_BROWSER_ACTION action = EFI_BROWSER_ACTION_CHANGED; //EFI_BROWSER_ACTION_CHANGING; + EFI_STATUS status = EFI_SUCCESS; + BOOLEAN PreservegEnableDrvNotification = FALSE; + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Entering FormCallBack()\n\n" ); + SETUP_DEBUG_UEFI_CALLBACK ( "Handle = 0x%x \nQuestionID = %d \nType = 0x%x \nValue = 0x%x \naction = 0x%x\n\n" , Handle, QuestionID, Type, *Value, action ); + + // + // Get Driver Handle that installed this Hii Form + // + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Getting Driver Handle\n" ); + status = gHiiDatabase->GetPackageListHandle(gHiiDatabase, Handle, &DriverHandle); + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Getting Driver Handle returned, status = 0x%x \n\n", status ); + if(EFI_ERROR(status)) + { + goto DONE; + } + + // + // Get ConfigAccess protocol handle + // + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Getting ConfigAccess protocol handle\n" ); + status = gBS->HandleProtocol( DriverHandle, &EfiHiiConfigAccessProtocolGuid , &ConfigAccess ); + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Getting ConfigAccess protocol handle returned, status = 0x%x \n\n" , status ); + if(EFI_ERROR(status)) + { + goto DONE; + } + + // + // Invoke Config Access Protocol + // + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] ConfigAccess->Callback()\n\n" ); + + PreservegEnableDrvNotification = gEnableDrvNotification; + gEnableDrvNotification = TRUE; //Set to enable notification processing + gBrowserCallbackEnabled = TRUE; + gBrowserCallbackAction = action ; //Save the current BrowserCallback action + status = ConfigAccess->Callback(ConfigAccess, action, QuestionID, Type, Value, &actionReq); + gBrowserCallbackAction = 0 ; //Clear the current BrowserCallback action + gBrowserCallbackEnabled = FALSE; + if (!PreservegEnableDrvNotification) // If gEnableDrvNotification is already True Don't touch it + gEnableDrvNotification = FALSE; //Reset to disable notification processing + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] ConfigAccess->Callback returned, status = 0x%x \n\n" , status ); + if(EFI_ERROR(status)) + { + goto DONE; + } + + // Clean up PAGE_INFO struct with Handle set to 0xFFFF + status = FixSetupData(); + if(EFI_ERROR(status)) + { + } + + if(actionReq) + { + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] ProcessBrowserActionRequestHook()\n" ); + status = ProcessBrowserActionRequestHook(actionReq);//EIP77108 : Modified ProcessBrowserActionRequest as board module hook + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] ProcessBrowserActionRequestHook returned, status = 0x%x \n\n" , status ); + } + +DONE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Exiting FormCallBack()\n\n" ); + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: CallFormCallBack +// +// Description: +// +// Parameter: CONTROL_INFO * ControlData, UINT16 Key , UINT8 Flags, UINTN Action +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +BOOLEAN BrowserActionDiscard = FALSE; +EFI_STATUS CallFormCallBack(CONTROL_INFO * ControlData, UINT16 Key ,UINT8 Flags, UINTN Action)//EIP-53480: Implementation of FormBrowser with actions support +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_IFR_TYPE_VALUE value; + EFI_IFR_OP_HEADER *OpHeader = (EFI_IFR_OP_HEADER *)ControlData->ControlPtr; + EFI_BROWSER_ACTION action ; + EFI_HII_HANDLE hiiHandle; + UINT16 ControlType = 0; + UINT8 type = 0; + UINT16 tok = 0; + UINTN size = 0; + UINT32 offset = 0; + VOID *ctrlValue = NULL, *FullCtrlValue = NULL; + UINT32 UefiSpecVer = 0; + UINT32 tempVariable = 0; + MemSet( &value, sizeof(value), 0 ); + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Entering CallFormCallBack()\n\n" ); + + UefiSpecVer = GetUefiSpecVersion (); + if (UefiSpecVer <= 0x2000A) //If spec version is 2.0 suppressing other actions + { + if (AMI_CALLBACK_CONTROL_UPDATE != Action) + { + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Exiting CallFormCallBack()\n\n" ); + status = EFI_UNSUPPORTED; + goto DONE; + } + } + else if (UefiSpecVer >= 0x2001E) //If spec version is greater than 2.30 then suppressing other actions + { + if ( + (AMI_CALLBACK_CONTROL_UPDATE != Action) && + (AMI_CALLBACK_RETRIEVE != Action) && + (AMI_CALLBACK_FORM_OPEN != Action) && + (AMI_CALLBACK_FORM_CLOSE != Action) && + (AMI_CALLBACK_FORM_DEFAULT_MANUFACTURING != Action)&& + (AMI_CALLBACK_FORM_DEFAULT_STANDARD != Action) )//EIP 105167 : Making the specify setup items departing from F2/F3 effect. + { + switch(Action) + { + case AMI_CALLBACK_FORM_OPEN: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_FORM_OPEN Unsupported\n\n" ); + break; + case AMI_CALLBACK_FORM_CLOSE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_FORM_CLOSE Unsupported\n\n" ); + break; + case AMI_CALLBACK_RETRIEVE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_RETRIEVE Unsupported\n\n" ); + break; + case AMI_CALLBACK_CONTROL_UPDATE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_CHANGING Unsupported\n\n" ); + break; + case AMI_CALLBACK_FORM_DEFAULT_MANUFACTURING : + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] AMI_CALLBACK_FORM_DEFAULT_MANUFACTURING Unsupported\n\n" ); + break; + case AMI_CALLBACK_FORM_DEFAULT_STANDARD : + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] AMI_CALLBACK_FORM_DEFAULT_STANDARD Unsupported\n\n" );//EIP 105167 : Making the specify setup items departing from F2/F3 effect. + break; + default: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Callback Action Unsupported\n\n" ); + break; + } + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Exiting CallFormCallBack()\n\n" ); + status = EFI_UNSUPPORTED; + goto DONE; + } + } + action = UefiGetActionWapper(Action); + + if(ControlData->ControlHandle == INVALID_HANDLE) + { + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] INVALID_HANDLE\n\n" ); + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Exiting CallFormCallBack()\n\n" ); + goto DONE; + } + + hiiHandle = ControlData->ControlHandle; + ControlType = ControlData->ControlType; + tempVariable = ControlData->ControlVariable; + + if(AMI_CALLBACK_FORM_OPEN != Action) + { + if(OpHeader->OpCode != EFI_IFR_ACTION_OP && OpHeader->OpCode != EFI_IFR_REF_OP) + { + offset = UefiGetQuestionOffset(ControlData->ControlPtr); + //If the control is Ordered list then we are calculating the actual size + if(ControlData->ControlType == CONTROL_TYPE_ORDERED_LIST) + { + UINTN Type=0; + UefiGetValidOptionType( ControlData, &Type, (UINT32 *)&size); + size = gOrderlistcount * size; + } + else + size = UefiGetWidth(ControlData->ControlPtr); + + if ((EFI_IFR_PASSWORD_OP == OpHeader->OpCode) || (EFI_IFR_STRING_OP == OpHeader->OpCode)) + { + ctrlValue = EfiLibAllocateZeroPool (size + sizeof (CHAR16)); //If max character reached then the string should have NULL at last + } + else + { + ctrlValue = EfiLibAllocateZeroPool (size); + } + if(ctrlValue == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + if((EFI_IFR_PASSWORD_OP == OpHeader->OpCode)&&(NULL != gCurPswdString) ) + { + MemCopy( ctrlValue, gCurPswdString, size); + } + else + status = VarGetValue(ControlData->ControlVariable, offset, size, ctrlValue ); + + if(EFI_ERROR(status)) + { + goto DONE; + } + //Checking the Previous value presence and updateing the cache with the previous value + if(NULL != gPrevControlValue) + status = VarSetValue(ControlData->ControlVariable, offset, size, gPrevControlValue ); + if(EFI_ERROR(status)) + { + goto DONE; + } + } + + switch(OpHeader->OpCode) + { + case EFI_IFR_NUMERIC_OP: + type = ((EFI_IFR_NUMERIC *)(ControlData->ControlPtr))->Flags & EFI_IFR_NUMERIC_SIZE; + MemCopy(&(value), ctrlValue, size); + break; + case EFI_IFR_REF_OP: + //type = EFI_IFR_TYPE_UNDEFINED; //REF_OP uses type EFI_IFR_TYPE_UNDEFINED + //EIP109812, 107774 + if ((GetUefiSpecVersion ()) >= 0x2001E) //If spec version is greater than or equals 2.3 then type will be buffer + { + type = EFI_IFR_TYPE_REF; + } + else + { + type = EFI_IFR_TYPE_UNDEFINED; + } + break; + case EFI_IFR_ONE_OF_OP: + type = ((EFI_IFR_ONE_OF *)(ControlData->ControlPtr))->Flags & EFI_IFR_NUMERIC_SIZE; + MemCopy(&(value), ctrlValue, size); + break; + case EFI_IFR_ORDERED_LIST_OP: + if ((GetUefiSpecVersion ()) >= 0x2001E) //If spec version is greater than or equals 2.3 then type will be buffer + { + type = EFI_IFR_TYPE_BUFFER; + } + else + { + type = EFI_IFR_TYPE_OTHER; + } + MemCopy(&(value), ctrlValue, size); + break; + case EFI_IFR_CHECKBOX_OP: + type = EFI_IFR_TYPE_BOOLEAN; + MemCopy(&(value), ctrlValue, size); + break; + case EFI_IFR_ACTION_OP: + type = EFI_IFR_TYPE_OTHER; + tok = ((EFI_IFR_ACTION*)ControlData->ControlPtr)->QuestionConfig; + MemCopy(&(value), &tok, sizeof(EFI_STRING_ID)); + break; + case EFI_IFR_STRING_OP: + case EFI_IFR_PASSWORD_OP: + type = EFI_IFR_TYPE_STRING; + tok = HiiAddString(hiiHandle, ctrlValue); + MemCopy(&(value), &tok, sizeof(EFI_STRING_ID)); + break; + case EFI_IFR_DATE_OP: + type = EFI_IFR_TYPE_DATE; + MemCopy(&(value), ctrlValue, size); + break; + case EFI_IFR_TIME_OP: + type = EFI_IFR_TYPE_TIME; + MemCopy(&(value), ctrlValue, size); + break; + + default: + goto DONE; + break; + } + } + else + { + type = EFI_IFR_TYPE_UNDEFINED; + } + + SetCallBackControlInfo(hiiHandle, tempVariable); + + switch(Action) + { + case AMI_CALLBACK_FORM_OPEN: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Sending EFI_BROWSER_ACTION_FORM_OPEN \n\n" ); + break; + case AMI_CALLBACK_FORM_CLOSE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Sending EFI_BROWSER_ACTION_FORM_CLOSE \n\n" ); + break; + case AMI_CALLBACK_RETRIEVE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Sending EFI_BROWSER_ACTION_RETRIEVE \n\n" ); + break; + case AMI_CALLBACK_CONTROL_UPDATE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Sending EFI_BROWSER_ACTION_CHANGING \n\n" ); + break; + case AMI_CALLBACK_FORM_DEFAULT_MANUFACTURING : + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Sending EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING \n\n" ); + break; + case AMI_CALLBACK_FORM_DEFAULT_STANDARD : + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Sending EFI_BROWSER_ACTION_DEFAULT_STANDARD \\n\n" );//EIP 105167 : Making the specify setup items departing from F2/F3 effect. + break; + default: + + break; + } + BrowserActionDiscard = FALSE; + status = FormCallBack(hiiHandle, Key, type, &value, action); + + switch(Action) + { + case AMI_CALLBACK_FORM_OPEN: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_FORM_OPEN returned, status = 0x%x \n\n" , status ); + break; + case AMI_CALLBACK_FORM_CLOSE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_FORM_CLOSE returned, status = 0x%x \n\n" , status ); + break; + case AMI_CALLBACK_RETRIEVE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_RETRIEVE returned, status = 0x%x \n\n" , status ); + break; + case AMI_CALLBACK_CONTROL_UPDATE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_CHANGING returned, status = 0x%x \n\n" , status ); + break; + case AMI_CALLBACK_FORM_DEFAULT_MANUFACTURING : + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] AMI_CALLBACK_FORM_DEFAULT_MANUFACTURING returned, status = 0x%x \n\n" , status ); + break; + case AMI_CALLBACK_FORM_DEFAULT_STANDARD : + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] AMI_CALLBACK_FORM_DEFAULT_STANDARD returned, status = 0x%x \n\n" , status ); //EIP 105167 : Making the specify setup items departing from F2/F3 effect. + break; + default: + + break; + } + + SetCallBackControlInfo(NULL, 0); + + if(CONTROL_TYPE_SUBMENU == ControlType) { //Skip rest of the step for REF / Submenu control + goto DONE; + } + //For the action EFI_BROWSER_ACTION_CHANGING update the cache and invoke callback with EFI_BROWSER_ACTION_CHANGED + if((!EFI_ERROR(status))&&(OpHeader->OpCode != EFI_IFR_ACTION_OP && OpHeader->OpCode != EFI_IFR_REF_OP)) + { + if (FALSE == BrowserActionDiscard) + { + if((OpHeader->OpCode == EFI_IFR_STRING_OP)||(OpHeader->OpCode == EFI_IFR_PASSWORD_OP)) + { + if ( NULL != ctrlValue ) + MemFreePointer( (VOID **)&ctrlValue ); + ctrlValue = HiiGetString( hiiHandle, value.string ); + FullCtrlValue = EfiLibAllocateZeroPool (size); + if (NULL == FullCtrlValue) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy (FullCtrlValue, ctrlValue, EfiStrLen (ctrlValue) * sizeof (CHAR16)); //If not allocated with full size then junk will be store after original string + + if ((EFI_IFR_PASSWORD_OP == OpHeader->OpCode) && IsPasswordEncodeEnabled (ControlData)) + { + ctrlValue = PasswordUpdate (FullCtrlValue, size); + } + VarSetValue (tempVariable, offset, size, FullCtrlValue);//EIP 105167 : Making the specify setup items departing from F2/F3 effect. + MemFreePointer ((VOID **)&FullCtrlValue); + } + else + { + VarSetValue(tempVariable, offset, size, &value );//EIP 105167 : Making the specify setup items departing from F2/F3 effect. + } + } + } + BrowserActionDiscard = FALSE; + + if( (action == EFI_BROWSER_ACTION_CHANGING ) && (/*(status == EFI_UNSUPPORTED) ||*/ (status == EFI_SUCCESS)) ) + { + switch(OpHeader->OpCode) + { + case EFI_IFR_NUMERIC_OP: + case EFI_IFR_ONE_OF_OP: + case EFI_IFR_ORDERED_LIST_OP: + case EFI_IFR_CHECKBOX_OP: + case EFI_IFR_ACTION_OP: + case EFI_IFR_STRING_OP: + case EFI_IFR_PASSWORD_OP: + case EFI_IFR_DATE_OP: + case EFI_IFR_TIME_OP: + if(hiiHandle != NULL) + { + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_CHANGING Success\n\n" ); + + action = EFI_BROWSER_ACTION_CHANGED; + SetCallBackControlInfo(hiiHandle, tempVariable); + + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Sending EFI_BROWSER_ACTION_CHANGED \n\n" ); + + status = FormCallBack(hiiHandle, Key, type, &value,action); + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_CHANGED returned, status = 0x%x \n\n" , status ); + + SetCallBackControlInfo(NULL, 0); + } + status = EFI_SUCCESS; + break; + default: + break; + } + } + if(OpHeader->OpCode == EFI_IFR_STRING_OP || OpHeader->OpCode == EFI_IFR_PASSWORD_OP) + { + HiiRemoveString(hiiHandle, tok); + } + +DONE: + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Exiting CallFormCallBack()\n\n" ); + if(gPrevControlValue) + MemFreePointer( (VOID **)&gPrevControlValue ); + if(gCurPswdString) + MemFreePointer( (VOID **)&gCurPswdString ); + MemFreePointer( (VOID **)&ctrlValue ); + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: CallTextCallBack +// +// Description: +// +// Parameter: TEXT_DATA *text, ACTION_DATA *Data +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS CallTextCallBack(TEXT_DATA *text, ACTION_DATA *Data) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + + if (text->Interval == 0) + return Status; + if ( --(text->Interval) == 0 ) + { + // initialize the interval + text->Interval = (UINT8)(text->ControlData.ControlFlags.ControlRefresh); + return EFI_SUCCESS; + } + else + return Status; + +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: SpecialActionCallBack +// +// Description: +// +// Parameter: CONTROL_INFO * ControlData, UINT16 Key +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS SpecialActionCallBack(CONTROL_INFO * ControlData, UINT16 Key) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_IFR_TYPE_VALUE value; + + UINT16 tok = 0; + UINT8 type = 0; + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Entering SpecialActionCallBack()\n\n" ); + + MemSet( &value, sizeof(value), 0 ); + type = EFI_IFR_TYPE_OTHER; + tok = ((EFI_IFR_ACTION*)ControlData->ControlPtr)->Question.Header.Prompt; + MemCopy(&(value), &tok, sizeof(EFI_STRING_ID)); + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Sending EFI_BROWSER_ACTION_CHANGING \n\n" ); + + SetCallBackControlInfo(ControlData->ControlHandle, ControlData->ControlVariable); + status = FormCallBack(ControlData->ControlHandle, Key, type, &value,EFI_BROWSER_ACTION_CHANGING); + SetCallBackControlInfo(NULL, 0); + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] EFI_BROWSER_ACTION_CHANGING returned, status = 0x%x \n\n" , status ); + + SETUP_DEBUG_UEFI_CALLBACK ( "[TSE] Exiting SpecialActionCallBack()\n\n" ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: UefiPreControlUpdate +// +// Description: store the Control value before updating and calling the callback. +// +// Parameter: CONTROL_INFO * ControlData +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// + +VOID UefiPreControlUpdate (CONTROL_INFO *ControlData) +{ + EFI_STATUS status = EFI_SUCCESS; + + if(gPrevControlValue) + MemFreePointer( (VOID **)&gPrevControlValue ); + + if (NULL == ControlData) //UefiPreControlUpdate will be called with NULL for clearing gPrevControlValue. So returning from here if it is NULL. + { + return; + } + if(UefiIsInteractive(ControlData)) + { + UINT32 size = 0; + UINT32 offset = 0; + offset = UefiGetQuestionOffset(ControlData->ControlPtr); + if(ControlData->ControlType == CONTROL_TYPE_ORDERED_LIST) + { + UINTN Type=0; + UefiGetValidOptionType( ControlData, &Type, &size); + size = gOrderlistcount * size; + } + else + size = UefiGetWidth(ControlData->ControlPtr); + gPrevControlValue = EfiLibAllocateZeroPool(size); + if(gPrevControlValue == NULL) + { + //EFI_OUT_OF_RESOURCES; + return; + } + + status = VarGetValue(ControlData->ControlVariable, offset, size, gPrevControlValue ); + } +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: SavePswdString +// +// Description: fucntion to save the password string. +// +// Parameter: CONTROL_INFO * ControlData, CHAR16 *String +// +// Return Value: VOID +//---------------------------------------------------------------------------- +// + +VOID SavePswdString (CONTROL_INFO *ControlData, CHAR16 *String) +{ + EFI_STATUS status = EFI_SUCCESS; + + if(gCurPswdString) + MemFreePointer( (VOID **)&gCurPswdString ); + + if (NULL == ControlData) //UefiPreControlUpdate will be called with NULL for clearing gPrevControlValue. So returning from here if it is NULL. + { + return; + } + if(UefiIsInteractive(ControlData)) + { + UINT32 size = 0; + size = UefiGetWidth(ControlData->ControlPtr); + gCurPswdString = EfiLibAllocateZeroPool(size); + if ( NULL == gCurPswdString ) + return ; + MemCopy(gCurPswdString, String, size); + } +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: UefiIsProceedWithPageChange +// +// Description: If the Formcallback returns status is EFI_UNSUPPORTED or EFI_SUCCESS. +// Change page is allowed. Otherwise changeing of page should not happen +// For UEFI 2.0 Just return EFI_SUCCESS; +// +// Parameter: EFI_STATUS +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiIsProceedWithPageChange(EFI_STATUS Status) +{ + // For Submenu if the status is EFI_UNSUPPORTED or EFI_SUCCESS. + // Change page is allowed. + if((Status == EFI_UNSUPPORTED) || (Status == EFI_SUCCESS)) + { + return EFI_SUCCESS; + } + else + return Status; +} +// +//---------------------------------------------------------------------------- +// +// Procedure: UEFICallSetupFormCallBack +// +// Description: The Wrapper function function which calls the CallFormCallBack() if the control is Interactive +// +// Parameter: UINTN Action +// +// Return Value: VOID +//---------------------------------------------------------------------------- +// +VOID UEFICallSetupFormCallBack(UINTN Action ) +{ +//EIP-53480: Implementation of FormBrowser with actions support + UINT32 page, control; + gBrowserCallbackEnabled = TRUE; + + if (NULL != gApplicationData) + { + for ( page = 0; page < gPages->PageCount; page++ ) + { + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[page]); + + if (NULL != pageInfo && 0 == pageInfo->PageHandle) + continue; + + for ( control= 0; control < pageInfo->PageControls.ControlCount; control++ ) + { + CONTROL_INFO *controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if (UefiIsInteractive(controlInfo)) + { + // EIP88031 : Allow BROWSER_ACTION_RETRIEVE for all Interactive controls on MiniSetupEntry + //if((Action == EFI_BROWSER_ACTION_RETRIEVE)&&(controlInfo->ControlType == CONTROL_TYPE_SUBMENU)) + // continue; + + UefiPreControlUpdate(NULL); //EIP 75464 : Updating the gPrevControlValue buffer to NULLL before invoking CallFormCallBack + CallFormCallBack(controlInfo, UefiGetControlKey(controlInfo), FALSE,Action); + } + + } + } + } + gBrowserCallbackEnabled = FALSE; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: UefiGetActionWapper +// +// Description: The Wrapper function to get the actual action for the driver +// +// Parameter: UINTN Action +// +// Return Value: EFI_BROWSER_ACTION +//---------------------------------------------------------------------------- +// +EFI_BROWSER_ACTION UefiGetActionWapper(UINTN Action) +{ + if(Action == AMI_CALLBACK_CONTROL_UPDATE) + return EFI_BROWSER_ACTION_CHANGING; + + if(Action == AMI_CALLBACK_RETRIEVE) + return EFI_BROWSER_ACTION_RETRIEVE; + + if(Action == AMI_CALLBACK_FORM_OPEN) + return EFI_BROWSER_ACTION_FORM_OPEN; + + if(Action == AMI_CALLBACK_FORM_CLOSE) + return EFI_BROWSER_ACTION_FORM_CLOSE; + + if(Action == AMI_CALLBACK_FORM_DEFAULT_MANUFACTURING) + return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING;//EIP 105167 : Making the specify setup items departing from F2/F3 effect. + + if(Action == AMI_CALLBACK_FORM_DEFAULT_STANDARD) + return EFI_BROWSER_ACTION_DEFAULT_STANDARD; + + return Action; + +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/EDK/MiniSetup/uefi2.1/HiiNotificationHandler.c b/EDK/MiniSetup/uefi2.1/HiiNotificationHandler.c new file mode 100644 index 0000000..c652a90 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/HiiNotificationHandler.c @@ -0,0 +1,740 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (C)Copyright 2011, 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/Uefi2.1/HiiNotificationHandler.c $ +// +// $Author: Arunsb $ +// +// $Revision: 14 $ +// +// $Date: 2/11/14 8:54p $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/HiiNotificationHandler.c $ +// +// 14 2/11/14 8:54p Arunsb +// [TAG] EIP130997 +// [Category] Improvement +// [Description] New pack support in ESA +// +// 13 2/25/13 10:57a Blaines +// [TAG] - EIP 104273 +// [Category] - Action Item +// [Description] - Provide ability to dump the Hii Pack from the Setup as +// part TSE debug Infrastructure. It should dump the Pack updates on Hii +// notification also. +// So it can be used to debug the issue. +// [Files] - ForBrowser2.c, Hii.c, HiiNotificationHandler.c, +// UefiWapper.c, TseUefiHii.h +// +// 12 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 10 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 11 5/26/12 5:20a Arunsb +// [TAG] EIP90895 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Setup hangs when retrieve callback produces +// add/remove/update forms +// [RootCause] Callback with retrieve action produces add/remove/update +// form +// [Solution] If retrieve callback produces add/remove/update form then +// TSE will print debug messages and assert. +// [Files] HiiNotificationHandler.c, HiiCallback.c and FormBrowser2.c +// +// 10 12/10/11 4:47a Arunsb +// Header corrected +// +// 9 12/07/11 2:54p Arunsb +// [TAG] EIP75588 +// [Category] New Feature +// [Description] Support for queuing UpdatePack notifications +// [Files] frame.c, page.c, formbrowser2.c, hii.c, hiicallback.c, +// hiinotificationhandler.c, tseuefihii.h and uefi21wapper.c +// +// 8 11/14/11 2:43p Blaines +// [TAG] - EIP 75481 +// [Category]- Function Request +// [Synopsis]- TSE debug print infrastructure. +// [Description]- Add TSE debug print info for basic functions such as +// Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms +// data. +// [Files] +// AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c +// Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c, +// HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h, +// Uefi21Wrapper.c, setupdbg.h +// +// 7 12/28/10 12:31p Madhans +// To update the Tag of EIp 46998. UEFI option ROM menus disappear in +// Setup when certain options are selected. +// No file changed but Comment updated right +// +// 6 10/27/10 4:25p Madhans +// [TAG] EIP46998 +// [Category] Defect +// [Symptom] Some user action on PCIx with UEFI Hii Pages causes Setup +// screen pages and menu disappers. +// [RootCause] UEFI 2.1 parsing code is not handling the Removepack and +// New pack sequance properly. Normally UpdatePack +// does the removepack and AddPack. +// [Solution] UEFI 2.1 parsing code fixed to handle above case correctly. +// [Files] hii.c HiiNotificationHandler.c Parse.c TseUefiHii.h +// uefi21wapper.c +// +// 5 6/17/10 2:59p Madhans +// Dynamic parsing support in TSE. +// +// 4 4/16/10 5:13p Madhans +// Changes for Tse 2.02. Please see Changelog.log for more details. +// +// 3 2/19/10 8:50p Madhans +// +// 4 2/19/10 8:21a Mallikarjunanv +// updated year in copyright message +// +// 3 2/15/10 10:19p Madhans +// to support EDK nt32 version +// +// 2 11/19/09 5:31p Presannar +// Updated TSE include file name to not clash with CORE file +// +// 1 8/11/09 2:50p Presannar +// HiiNotificationHandler to handle notification of dynamic modification +// of IFR data. +// +// 2 7/24/09 3:58p Presannar +// Modified IFRChangeNotifyFn to handle New/Add pack notification +// +// 1 7/09/09 11:24a Presannar +// Initial Draft +// Code to handle Notification arising from Dynamic Form Modification +// +//************************************************************************* +// +// +// Name: HiiNotificationHandler.c +// +// Description: Contains Hii related Functions +// +// +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include Files +//--------------------------------------------------------------------------- +#include "Minisetup.h" +#include "TseUefiHii.h" + +//--------------------------------------------------------------------------- +// Defines +//--------------------------------------------------------------------------- +#define BY_ENTRY 0 +#define BY_HANDLE 1 +#define BY_TYPE 2 +#define BY_HANDLE_TYPE 3 + +//--------------------------------------------------------------------------- +// Type definitions +//--------------------------------------------------------------------------- +typedef struct _NOTIFICATION_INFO NOTIFICATION_INFO; + +typedef struct _NOTIFICATION_INFO +{ + EFI_HII_HANDLE Handle; + EFI_HII_DATABASE_NOTIFY_TYPE NotifyType; + UINT8 *PackData; + UINTN DataLength; + NOTIFICATION_INFO *prevNotifInfo; + NOTIFICATION_INFO *nextNotifInfo; +}; + +typedef struct _NOTIFICATION_QUEUE +{ + UINTN NumOfNotification; + NOTIFICATION_INFO *headNotifInfo; + NOTIFICATION_INFO *tailNotifInfo; +} NOTIFICATION_QUEUE; + +//--------------------------------------------------------------------------- +// Externs +//--------------------------------------------------------------------------- +extern EFI_STATUS FindHandleWithInSetupData(EFI_HII_HANDLE Handle); +extern EFI_BROWSER_ACTION gBrowserCallbackAction ; +extern BOOLEAN gBrowserCallbackEnabled; +//--------------------------------------------------------------------------- +// Variables +//--------------------------------------------------------------------------- +BOOLEAN gIFRChangeNotify = FALSE; +EFI_HII_HANDLE gRemovedHandle=NULL; +BOOLEAN gEnableDrvNotification = FALSE; //TRUE if allow notification function to process action, FALSE to ignore the notification +BOOLEAN gEnableProcessPack = FALSE; //TRUE if the process pack is allowed, FALSE if to be ignored + +static EFI_HANDLE gIFRHandle; +static UINTN gNotifyType; +#ifndef TSE_FOR_APTIO_4_50 +#define EFI_HII_PACKAGE_FORMS EFI_HII_PACKAGE_FORM +#include "tianohii.h" +#endif + +NOTIFICATION_QUEUE *gNotificationQueue = (NOTIFICATION_QUEUE *)NULL; //This is a pointer to the notifiaction queue +BOOLEAN gPackUpdatePending = FALSE; + +//--------------------------------------------------------------------------- +// Function Prototypes +//--------------------------------------------------------------------------- +EFI_STATUS AddNotificationToQueue(EFI_HII_HANDLE Handle, EFI_HII_DATABASE_NOTIFY_TYPE Type); +EFI_STATUS ProcessPackNotificationHook (VOID); +//--------------------------------------------------------------------------- +// Function Implementation +//--------------------------------------------------------------------------- + +// +//---------------------------------------------------------------------------- +// +// Procedure: RegisterFormNotification +// +// Description: Notification Registering Function +// +// Parameter: EFI_HII_DATABASE_NOTIFY PackageNotifyFn, +// EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, +// EFI_HANDLE *NotifyHandle +// +// Return value: EFI_STATUS +// EFI_SUCCESS +//---------------------------------------------------------------------------- +// +EFI_STATUS RegisterFormNotification(EFI_HII_DATABASE_NOTIFY PackageNotifyFn, + EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, + EFI_HANDLE *NotifyHandle) +{ + // + // Register notification + // + return gHiiDatabase->RegisterPackageNotify ( + gHiiDatabase, + EFI_HII_PACKAGE_FORMS, + NULL, + PackageNotifyFn, + NotifyType, + NotifyHandle + ); +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: UnRegisterFormNotification +// +// Description: Notification UnRegistering Function +// +// Parameter: EFI_HANDLE *NotifyHandle +// +// Return value: EFI_STATUS +// EFI_SUCCESS +//---------------------------------------------------------------------------- +// +EFI_STATUS UnRegisterFormNotification(EFI_HANDLE NotifyHandle) +{ + // + // UnRegister notification + // + return gHiiDatabase->UnregisterPackageNotify (gHiiDatabase, NotifyHandle); +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: IFRChangeNotifyFn +// +// Description: Function that handles IFR change notification +// +// Parameter: IN UINT8 PackageType, +// IN CONST EFI_GUID *PackageGuid, +// IN CONST EFI_HII_PACKAGE_HEADER *Package, +// IN EFI_HII_HANDLE Handle, +// IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType +// +// Return value: EFI_STATUS +// EFI_SUCCESS +//---------------------------------------------------------------------------- +// +EFI_STATUS +IFRChangeNotifyFn ( + IN UINT8 PackageType, + IN CONST EFI_GUID *PackageGuid, + IN CONST EFI_HII_PACKAGE_HEADER *Package, + IN EFI_HII_HANDLE Handle, + IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType + ) +{ + EFI_STATUS status = EFI_NOT_FOUND; + + //EIP90895 + if( (gBrowserCallbackEnabled == TRUE) && + ( (gBrowserCallbackAction == EFI_BROWSER_ACTION_FORM_OPEN) || + (gBrowserCallbackAction == EFI_BROWSER_ACTION_FORM_CLOSE) || + (gBrowserCallbackAction == EFI_BROWSER_ACTION_RETRIEVE) ) ) + { + if (TSE_DEBUG_MESSAGES) + { + SETUP_DEBUG_TSE ("\n\n[TSE] WARNING: Browser callback is currently in progress"); + SETUP_DEBUG_TSE ("\n[TSE] HII PACK REMOVE/ADD/UPDATE from EFI_BROWSER_ACTION_FORM_OPEN/EFI_BROWSER_ACTION_RETRIEVE/EFI_BROWSER_ACTION_CLOSE"); + SETUP_DEBUG_TSE ("\n[TSE] It is not recommended to proceed with the current action, behavior could be unpredictable."); + SETUP_DEBUG_TSE ("\n[TSE] It is advisable to work with the card vendor to properly support UEFI 2.3.1, or"); + SETUP_DEBUG_TSE ("\n[TSE] decrease the value of TSE_CALLBACK_SPEC_VERSION to (UEFI 2.1) to change the callback functionality."); + SETUP_DEBUG_TSE ("\n[TSE] So UEFI 2.3.1 Callbacks will be disabled!\n\n"); + } + ASSERT (0); + } + + if (FALSE == gEnableDrvNotification) //EIP75588 + { + SETUP_DEBUG_UEFI_NOTIFICATION ("\n\n[TSE] Illegal Notification (Type: NotifyType 0x%x) recieved. \n\n", NotifyType); + } + status = AddNotificationToQueue (Handle, NotifyType); //Adding notification to the queue + if(status != EFI_SUCCESS) //Failed to add notification in the queue, return error + { + goto DONE; + } + gPackUpdatePending = TRUE; + + if(gEnableDrvNotification && !gEnableProcessPack) + { + SETUP_DEBUG_UEFI_NOTIFICATION ("\n\n[TSE] IFRChangeNotifyFn() calling ProcessPackNotificationHook() \n\n"); + gEnableProcessPack = TRUE; + status = ProcessPackNotificationHook (); // Synchronized Notification Call happening because of Callback,ExtractConfig. routeconfig. + gEnableProcessPack = FALSE; + } +DONE: + SETUP_DEBUG_UEFI_NOTIFICATION ("\n\n[TSE] Exiting IFRChangeNotifyFn() status: %x\n\n", status); + return status; +} + +//EIP75588 starts +// +//--------------------------------------------------------------------------- +// Procedure: AddNotificationToQueue +// +// Description: Adds new notification to the queue and increments queue size +// +// Input: EFI_HII_HANDLE Handle, EFI_HII_DATABASE_NOTIFY_TYPE Type +// +// Output: EFI_STATUS status - EFI_ABORTED, By default +// EFI_OUT_OF_RESOURCES, if memory allocation fails +// EFI_SUCCESS, if successful +//--------------------------------------------------------------------------- +// +EFI_STATUS AddNotificationToQueue (EFI_HII_HANDLE Handle, EFI_HII_DATABASE_NOTIFY_TYPE Type) +{ + EFI_STATUS status = EFI_ABORTED; + NOTIFICATION_INFO *tempNotifInfo = (NOTIFICATION_INFO *)NULL; + + if (gNotificationQueue == NULL) + { + gNotificationQueue = EfiLibAllocateZeroPool (sizeof (NOTIFICATION_QUEUE)); + if (NULL == gNotificationQueue) + { + status = EFI_OUT_OF_RESOURCES; //Cannot allocate memory for the notification queue + goto DONE; + } + } + if (NULL == tempNotifInfo) + { + tempNotifInfo = EfiLibAllocateZeroPool(sizeof(NOTIFICATION_INFO)); + if (NULL == tempNotifInfo) + { + status = EFI_OUT_OF_RESOURCES; //Cannot allocate memory for the notification queue + goto DONE; + } + } + tempNotifInfo->Handle = Handle; + tempNotifInfo->NotifyType = Type; + if((Type == EFI_HII_DATABASE_NOTIFY_NEW_PACK) || (Type == EFI_HII_DATABASE_NOTIFY_ADD_PACK)) + { + tempNotifInfo->PackData = (UINT8*)HiiGetForm(Handle, 0, &tempNotifInfo->DataLength); + } + if((gNotificationQueue->NumOfNotification == 0) || (gNotificationQueue->headNotifInfo == NULL)) + { + gNotificationQueue->headNotifInfo = tempNotifInfo; + gNotificationQueue->tailNotifInfo = tempNotifInfo; + } + else + { + tempNotifInfo->prevNotifInfo = gNotificationQueue->tailNotifInfo; + gNotificationQueue->tailNotifInfo = tempNotifInfo; + gNotificationQueue->tailNotifInfo->prevNotifInfo->nextNotifInfo = tempNotifInfo; + } + gNotificationQueue->NumOfNotification++; + status = EFI_SUCCESS; +DONE: + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: RemoveFromQueueByEntry +// +// Description: Removes the notification entry from the queue, and returns +// the pointer to the next notification node +// +// Input: NOTIFICATION_INFO *matchingNotifInfo +// +// Output: VOID +//--------------------------------------------------------------------------- +// +VOID RemoveFromQueueByEntry(NOTIFICATION_INFO *matchingNotifInfo) +{ + NOTIFICATION_INFO *tempNotifInfo = matchingNotifInfo; + + if ((NULL == tempNotifInfo) || (NULL == gNotificationQueue) || (0 == gNotificationQueue->NumOfNotification)){ + goto DONE; + } + if(gNotificationQueue->headNotifInfo == tempNotifInfo){ + if (gNotificationQueue->headNotifInfo == gNotificationQueue->tailNotifInfo){ + gNotificationQueue->tailNotifInfo = tempNotifInfo->nextNotifInfo; + } + gNotificationQueue->headNotifInfo = tempNotifInfo->nextNotifInfo; + }else if(gNotificationQueue->tailNotifInfo == tempNotifInfo){ + gNotificationQueue->tailNotifInfo = tempNotifInfo->prevNotifInfo; + } + if(tempNotifInfo->prevNotifInfo){ + tempNotifInfo->prevNotifInfo->nextNotifInfo = tempNotifInfo->nextNotifInfo; + } + if(tempNotifInfo->nextNotifInfo){ + tempNotifInfo->nextNotifInfo->prevNotifInfo = tempNotifInfo->prevNotifInfo; + } + gNotificationQueue->NumOfNotification--; //Decrement the number of notification by 1 + MemFreePointer(&tempNotifInfo); //Free the node +DONE: + return; +} + +// +//--------------------------------------------------------------------------- +// Procedure: RemoveNotifFromQueueByHandleType +// +// Description: Removes the all the node with same notification handle and +// type except the passed the entry from the queue +// +// Input: EFI_HII_HANDLE Handle +// EFI_HII_DATABASE_NOTIFY_TYPE Type +// NOTIFICATION_INFO *matchingNotifInfo +// +// Output: EFI_STATUS status - EFI_ABORTED, By default ; +// EFI_INVALID_PARAMETER, if invalid gNotificationQueue +// EFI_SUCCESS, if successful +//--------------------------------------------------------------------------- +// +EFI_STATUS RemoveNotifFromQueueByHandleType (UINTN RemoveOption, EFI_HII_HANDLE Handle, EFI_HII_DATABASE_NOTIFY_TYPE Type, NOTIFICATION_INFO *matchingNotifInfo) +{ + EFI_STATUS status = EFI_NOT_FOUND; + NOTIFICATION_INFO *tempNotifInfo = (NOTIFICATION_INFO *)NULL; + NOTIFICATION_INFO *currNotifInfo = (NOTIFICATION_INFO *)NULL; + EFI_HII_HANDLE NotifyHandle = (EFI_HII_HANDLE)NULL; + EFI_HII_DATABASE_NOTIFY_TYPE NotifyType = 0; + + if (NULL == gNotificationQueue){ + status = EFI_INVALID_PARAMETER; //gNotificationQueue invalid + goto DONE; + } + + if((Handle != NULL) || (Type != 0)){ + NotifyHandle = Handle; + NotifyType = Type; + } else{ + NotifyHandle = matchingNotifInfo->Handle; + NotifyType = matchingNotifInfo->NotifyType; + } + tempNotifInfo = gNotificationQueue->headNotifInfo; + while(tempNotifInfo != NULL) + { + currNotifInfo = tempNotifInfo->nextNotifInfo; + if (BY_ENTRY == RemoveOption){ + if (tempNotifInfo == matchingNotifInfo){ + RemoveFromQueueByEntry(tempNotifInfo); + status = EFI_SUCCESS; + break; + } + }else if(tempNotifInfo != matchingNotifInfo){ //Match found + if (BY_HANDLE == RemoveOption){ + if (tempNotifInfo->Handle == NotifyHandle){ + RemoveFromQueueByEntry(tempNotifInfo); + status = EFI_SUCCESS; + } + } else if(RemoveOption == BY_TYPE){ + if(tempNotifInfo->NotifyType == NotifyType){ + RemoveFromQueueByEntry(tempNotifInfo); + status = EFI_SUCCESS; + } + } else if(RemoveOption == BY_HANDLE_TYPE){ +//If match found process the node and move to the next node + if((tempNotifInfo->Handle == NotifyHandle) && (tempNotifInfo->NotifyType == NotifyType)){ + RemoveFromQueueByEntry(tempNotifInfo); + status = EFI_SUCCESS; + } + } + } + tempNotifInfo = currNotifInfo; + } +DONE: + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: CleanNotificationQueue +// +// Description: Cleans the IFR notification queue +// +// Input: None +// +// Output: EFI_STATUS status - EFI_SUCCESS, if successful +//--------------------------------------------------------------------------- +// +EFI_STATUS CleanNotificationQueue() +{ + EFI_STATUS status = EFI_ABORTED; + + do //Loop to clean up the notification queue + { + if((NULL == gNotificationQueue) || (NULL == gNotificationQueue->headNotifInfo)) + { + status = EFI_SUCCESS; //The is no notification to process + goto DONE; + } + RemoveFromQueueByEntry(gNotificationQueue->headNotifInfo); //Removes this node + }while (1); + if (gNotificationQueue) + { + MemFreePointer (&gNotificationQueue); + gNotificationQueue = (NOTIFICATION_QUEUE *)NULL; //Reset the Notification Queue + } +DONE: + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: RemoveDuplicateIFRNotification +// +// Description: Finds duplicate notification on the same handle and remove +// +// Input: None +// +// Output: EFI_STATUS status - EFI_ABORTED, By default ; +// EFI_INVALID_PARAMETER, if invalid gNotificationQueue +// EFI_SUCCESS, if successful +//--------------------------------------------------------------------------- +// +EFI_STATUS RemoveDuplicateIFRNotification() +{ + EFI_STATUS status = EFI_ABORTED; + EFI_HII_HANDLE Handle = (EFI_HII_HANDLE)NULL; + NOTIFICATION_INFO *tempNotifInfo = (NOTIFICATION_INFO *)NULL; + EFI_HII_DATABASE_NOTIFY_TYPE NotifyType = 0; + BOOLEAN packFound = FALSE; + + if((gNotificationQueue == NULL) || (gNotificationQueue->headNotifInfo == NULL)) + { + status = EFI_SUCCESS; //The is no notification to process + goto DONE; + } + SETUP_DEBUG_UEFI_NOTIFICATION ("\n\n[TSE] Before RemoveDuplicateIFRNotification(), NumOfNotification left: %d\n\n", gNotificationQueue->NumOfNotification); + + tempNotifInfo = gNotificationQueue->tailNotifInfo; + Handle = tempNotifInfo->Handle; + NotifyType = tempNotifInfo->NotifyType; + + while(tempNotifInfo != NULL) //Loop to removed duplicate notifications + { + if((EFI_HII_DATABASE_NOTIFY_REMOVE_PACK == tempNotifInfo->NotifyType) || + (EFI_HII_DATABASE_NOTIFY_ADD_PACK == tempNotifInfo->NotifyType)){ + RemoveNotifFromQueueByHandleType (BY_HANDLE_TYPE, 0, 0, tempNotifInfo); //If the handle belongs to the formset, clean up notification queue + } + if(tempNotifInfo != NULL){ //If the current node is valid + tempNotifInfo = tempNotifInfo->prevNotifInfo; //Move current notification node pointer to previous notification node + } + } + tempNotifInfo = gNotificationQueue->tailNotifInfo; + while(tempNotifInfo != NULL) //Loop to removed duplicate notifications + { + status = FindHandleWithInSetupData(tempNotifInfo->Handle); + if (EFI_SUCCESS == status){ + packFound = TRUE; + } + + if(tempNotifInfo->NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK){ + if(packFound){ + BOOLEAN newPackOnThisHandle = FALSE; + NOTIFICATION_INFO *thisNotifInfo = tempNotifInfo->prevNotifInfo; + while(thisNotifInfo) //Loop to find if there is a new pack notification in the queue with this handle + { + if((thisNotifInfo->Handle == tempNotifInfo->Handle) && (EFI_HII_DATABASE_NOTIFY_NEW_PACK == thisNotifInfo->NotifyType)){ + newPackOnThisHandle = TRUE; + break; + } + thisNotifInfo = thisNotifInfo->prevNotifInfo; + } + if(newPackOnThisHandle){ //If a new pack notification was found, no need to process any notification on this handle + RemoveNotifFromQueueByHandleType(BY_HANDLE, tempNotifInfo->Handle, 0, NULL); + tempNotifInfo = gNotificationQueue->tailNotifInfo; + continue; + } else{ //Removed everything except for the remove pack notification on the handle + RemoveNotifFromQueueByHandleType(BY_HANDLE, tempNotifInfo->Handle, 0, tempNotifInfo); + } + } else{ + RemoveNotifFromQueueByHandleType(BY_ENTRY, NULL, 0, tempNotifInfo); //clean up notification queue, except for this handle + } + } else if(tempNotifInfo->NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) { + if(packFound){ + if((gIFRChangeNotify == TRUE) && (gRemovedHandle != NULL)){ + RemoveNotifFromQueueByHandleType(BY_HANDLE, gRemovedHandle, 0, tempNotifInfo); //If the previous remove pack is already processed, clean up notification queue with this handle + } else{ + NOTIFICATION_INFO *thisNotifInfo = tempNotifInfo->prevNotifInfo; + while (thisNotifInfo) //Loop to find if there is a remove pack notification in the queue with this handle + { + if((thisNotifInfo->Handle == tempNotifInfo->Handle) && (thisNotifInfo->NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK)){ + tempNotifInfo = thisNotifInfo; //Skip the first remove pack encountered on this handle + break; + } + thisNotifInfo = thisNotifInfo->prevNotifInfo; + } + } + } else{ + RemoveNotifFromQueueByHandleType(BY_ENTRY, NULL, 0, tempNotifInfo); //clean up notification queue, except for this handle + } + } + if (NULL != tempNotifInfo){ //If the current node is valid + tempNotifInfo = tempNotifInfo->prevNotifInfo; //Move current notification node pointer to previous notification node + } + packFound = FALSE; + } + SETUP_DEBUG_UEFI_NOTIFICATION ("\n\n[TSE] After RemoveDuplicateIFRNotification(), NumOfNotification left: %d\n\n", gNotificationQueue->NumOfNotification); +DONE: + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: ProcessPackNotification +// +// Description: Processes the IFR notification queue +// +// Input: None +// +// Output: EFI_STATUS status - EFI_ABORTED, By default +// EFI_SUCCESS, if successful +// EFI_ERROR, otherwise +//--------------------------------------------------------------------------- +// +EFI_STATUS ProcessPackNotification (VOID) +{ + EFI_STATUS status = EFI_ABORTED; + EFI_HII_HANDLE Handle = (EFI_HII_HANDLE)NULL; + EFI_HII_DATABASE_NOTIFY_TYPE NotifyType = 0; + UINT8 *PackData = (UINT8 *)NULL; + + SETUP_DEBUG_UEFI_NOTIFICATION( "\n\n[TSE] Entering IFRChangeNotifyFn() \n\n"); + RemoveDuplicateIFRNotification(); + + if((gNotificationQueue == NULL) || (gNotificationQueue->headNotifInfo == NULL)) + { + status = EFI_NOT_FOUND; //There is no notification to process + goto DONE; + } + + do + { + if ((NULL == gNotificationQueue) || (NULL == gNotificationQueue->headNotifInfo)) + { + status = EFI_SUCCESS; //All the notifications are processed + goto DONE; + } + Handle = gNotificationQueue->headNotifInfo->Handle; + NotifyType = gNotificationQueue->headNotifInfo->NotifyType; + PackData = gNotificationQueue->headNotifInfo->PackData; + + SETUP_DEBUG_UEFI_NOTIFICATION( "\n\n[TSE] gNotificationQueue->NumOfNotification left: %d \n\n", gNotificationQueue->NumOfNotification); + + switch(NotifyType) + { + case EFI_HII_DATABASE_NOTIFY_REMOVE_PACK: + SETUP_DEBUG_UEFI_NOTIFICATION( "\n[TSE] NotifyType: EFI_HII_DATABASE_NOTIFY_REMOVE_PACK \n\n[TSE] Removing IFR Pack \n"); + if(gIFRChangeNotify) + { + if(gRemovedHandle!=NULL) + { + FixSetupData(); //Will fix the UI and Setup data. + } + } + status = HandleRemoveIFRPack(Handle); + gIFRChangeNotify = TRUE; + gRemovedHandle = Handle; + break; + case EFI_HII_DATABASE_NOTIFY_NEW_PACK: + SETUP_DEBUG_UEFI_NOTIFICATION( "\n[TSE] NotifyType: EFI_HII_DATABASE_NOTIFY_NEW_PACK \n\n[TSE] New IFR Pack \n"); + if(gIFRChangeNotify) + { + if(gRemovedHandle!=NULL) + { + FixSetupData(); //Will fix the UI and Setup data. + } + } + status = HandleNewIFRPack (Handle, PackData); + break; + case EFI_HII_DATABASE_NOTIFY_ADD_PACK: + SETUP_DEBUG_UEFI_NOTIFICATION( "\n[TSE] NotifyType: EFI_HII_DATABASE_NOTIFY_ADD_PACK \n\n[TSE] Add IFR Pack \n"); + status = HandleAddIFRPack(Handle, PackData); + gIFRChangeNotify = FALSE; + FixSetupData(); + break; + default: + break; + } + +#if TSE_DEBUG_MESSAGES + ProcessPackToFile(NotifyType, Handle) ; +#endif + RemoveFromQueueByEntry(gNotificationQueue->headNotifInfo); //Remove the processed notification node from the queue + SETUP_DEBUG_UEFI_NOTIFICATION( "\n[TSE] NumOfNotification left: %d, headNotifInfo: 0x%x \n\n", gNotificationQueue->NumOfNotification, gNotificationQueue->headNotifInfo); + }while(1); + +DONE: + gPackUpdatePending = FALSE; + SETUP_DEBUG_UEFI_NOTIFICATION( "\n[TSE] Exiting ProcessPackNotificationHook, status: %x \n\n", status); + return status; +} +//EIP75588 ends + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/EDK/MiniSetup/uefi2.1/Parse.c b/EDK/MiniSetup/uefi2.1/Parse.c new file mode 100644 index 0000000..31579d1 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/Parse.c @@ -0,0 +1,4700 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* + +//************************************************************************* +// $Header: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/Parse.c 68 7/12/14 12:23p Arunsb $ +// +// $Revision: 68 $ +// +// $Date: 7/12/14 12:23p $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/Parse.c $ +// +// 68 7/12/14 12:23p Arunsb +// [TAG] EIP174938 +// [Category] Bug Fix +// [Severity:] Normal +// [Symptom:] Arrow mark shown when driver health page published +// [Root Cause] Driver health formset considered as dynamic page so arrow +// shown +// [Solution] For driverhealth formset DynamicPageCount variable not +// incremented. Returned EFI_ABORTED in parseform for driverhealth formset +// so DynamicPageCount not incremented so arrow will not be shown. +// [Files] Parse.c and uefi21wapper.c +// +// 67 5/02/14 5:48a Arunsb +// [TAG] EIP156258 +// [Category] Improvement +// [Description] Providing ELINK option to suppress the handle +// comparison on dynamic parsing +// [Files] AMITSE.mak, AMITSE.sdl, commonoem.c, commonoem.h and Parse.c +// +// 66 5/02/14 4:42a Premkumara +// [TAG] EIP95647 +// [Category] Improvement +// [Description] Dynamic Forms need to hide. +// [Files] AMITSE.mak, AMITSE.sdl, CommonOem.c, Parse.c +// +// 65 5/01/14 10:29p Arunsb +// EIP148837 change reverted, this is specially for Aptio5 customization +// +// 64 5/01/14 6:40p Premkumara +// Resolved build error +// +// 63 5/01/14 4:42p Premkumara +// [TAG] EIP151552 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] IScsi Configuration option throws exception on pressing it +// after 'Esc' is done to move back to previous page. +// [RootCause] When "Save and Exit" in iScsi page is selected to create +// new controls, while parsing PageInfo->PageParentID is not handled +// properly. So while initializing menu title menu menu->CurrEntry is not +// setting properly because of ParentPageID. +// [Solution] While parsing PageInfo->PageParentID is not handled +// properly. So while initializing menu title menu menu->CurrEntry is not +// setting properly so that menu will be initialize and draw proper data. +// [Files] Parse.c +// +// 62 5/01/14 4:09p Premkumara +// [TAG] EIP148837 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Checkbox Control control is not working in dynamic page. +// [RootCause] TSE is treating both the OneOf control and CheckBox +// Control as CONTROL_TYPE_POPUPSEL +// During dynamic parsing TSE is changing the Control type to +// CONTROL_TYPE_POPUPSEL if it is CheckBox. +// That's Why in ESA ComboBox is coming instead of CheckBox. +// [Solution] For Dynamic Parsing after creating the Control Info i am +// calling GetCheckBoxStyle() to get the Type as +// CONTROL_TYPE_CHECKBOX for CheckBox Control. +// [Files] Parse.c +// +// 61 12/04/13 2:56a Premkumara +// [TAG] EIP139099 +// [Category] New Feature +// [Description] Supress formset other than +// EFI_HII_PLATFORM_SETUP_FORMSET_GUID and +// EFI_HII_DRIVER_HEALTH_FORMSET_GUID through elink based on token +// [Files] AMITSE.sdl, AMITSE.mak, CommonOem.c, Hii.c, Parse.c, +// TseUefiHii.h +// +// 60 6/10/13 12:21p Arunsb +// EIP122907 EFI_IFR_TYPE_OTHER support provided. +// +// 59 5/22/13 11:11a Arunsb +// Fixed these issues, +// -If control has submit/inconsistent and its form has condition over it +// then it will hang, +// - Read write opcode hang +// +// 58 5/22/13 10:19a Premkumara +// [TAG] EIP120418 +// [Category] Improvement +// [Issue Faced] When any suppressif, grayoutif, disableif over +// the form then HPKTool crashes +// [Root Cause] The end of suppressif, grayoutif, disableif +// over the form were not handle properly +// [Solution] The suppressif,grayoutif,disable are pushed +// and end of suppressif, grayoutif, disableif over the form are popupout +// properly at the end of parsing form +// [Files] Parse.c +// +// 57 5/20/13 3:36a Premkumara +// [TAG] EIP124286 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Optimal Defaults are not loading on pressing ResetButton +// [RootCause] While filling defaults for DefaultOp2 optimal defaults +// are skipped in __UpdateDefaults() fn +// [Solution] If default ID EFI_IFR_DEFAULT_OP is found then fill +// default link for all types of defaults +// [Files] Parse.c +// +// 56 4/17/13 2:29p Arunsb +// [TAG] EIP109812, 107774 +// [Category] Improvement +// [Description] Provide support for EFI_IFR_TYPE_REF and EFI_IFR_REF5 +// [Files] Hii.c, HiiCallback.c, Parse.c and TseUefiHii.h +// +// 55 4/16/13 9:58a Arunsb +// Missed HII structures added in TSE itself. So Hii structure names +// changed. +// +// 54 4/02/13 8:21a Arunsb +// [TAG] EIP113919, EIP114842 +// [Category] Improvement +// [Description] Provide support for EFI_IFR_WRITE, EFI_IFR_READ, +// EFI_IFR_GET, EFI_IFR_SET and EFI_IFR_MAP_OP. +// [Files] Setupdata.h, ctrlcond.c, expression.c, hii.c and parse.c +// +// 53 3/29/13 8:19a Arunsb +// [TAG] EIP111061 +// [Category] Improvement +// [Description] Provide support for efivarstore opcode +// [Files] Parse.c and tseuefihii.h +// +// 52 3/25/13 8:05a Premkumara +// [TAG] EIP105468 +// [Category] New Feature +// [Description] Support for EFI_IFR_REFRESH_ID opcode for Offline +// Parsing +// [Files] Parse.c, Hii.c, Setupdata.h +// +// 51 3/20/13 10:42a Blaines +// [TAG] - EIP 116513 +// [Category]- Defect +// [Symptom]- System hangs while navigating SAS Card UEFI HII Page, when +// TSE_MULTILINE_CONTROLS is enabled. +// +// [Root cause] +// The Hii page contained EFI_IFR_ACTION controls with a refresh value +// greater than zero. When DEBUG_MODE is enabled, +// The increased page draw completion time caused the Action timer to +// expire. The constant page refresh prevented the call +// to function ActionReadKey from the function ActionGetAction. +// +// [Solution]- Set the refresh value for EFI_IFR_ACTION controls only if +// AMI CALLBACK value is used. +// +// [Files] +// - Parse.c +// +// 50 3/20/13 9:29a Premkumara +// [TAG] EIP116566 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Fixed Boot Order Issue +// [RootCause] Some controls are using checkbox(from runtime pages) +// value to suppress some controls in SuperIO configuration page. +// Dynamic parsing is modifying Checkbox controls optimal and failsafe +// defaults by setting size=1 irrespective of presence of defaults. +// [Solution] Setting size =0/1 based on presence of fail safe/Optimal +// defaults for CheckBox controls. +// [Files] Parse.c +// +// +// 48 3/15/13 2:15a Premkumara +// [TAG] EIP85745 & 109814 +// [Category] Improvement +// [Description] Support for Modal Form Support as per UEFI 2.3.1 +// [Files] Parse.c, Page.c, Menu.c, Hotclick.c +// +// 47 12/21/12 8:34p Blaines +// [TAG] EIP 108987 +// [Category] Defect +// [Symptom] SAS controller card HII menus hang when selecting and HII +// pack update occurs. +// [RootCause] The Setup maintains a page data cache when hii packs are +// created, and will normally try to reuse the page data when hii packs +// are removed/updated. If the existing page data cannot be reused, the +// function _InvalidateExistingPage is called, but the +// NewPageInfo->PageParentID is updated with the +// OldPageInfo->PageParentID. +// This resulted in circular page reference, causing the function +// MenuInitialize (menu.c) to enter an infinite loop. +// +// [Solution] In the function _InvalidateExistingPage, remove the code +// that changes NewPageInfo->PageParentID with the +// OldPageInfo->PageParentID. +// +// [Files Changed] +// - Parse.c +// +// +// 46 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 16 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 44 9/25/12 8:31a Rajashakerg +// [TAG] EIP94424 +// [Category] Improvement +// [Description] Some form can't normal display when add Hii item will +// in runtime during +// [Files] AMITSE.sdl, AMITSE.mak, Parse.c +// +// 43 9/18/12 2:15a Rajashakerg +// [TAG] EIP88658 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Minisetup crashes after controller reconnection during Hii +// callback +// [RootCause] Minisetup crashes after controller reconnection during +// callback. since we have new packs and new handles. +// [Solution] Additional checks for invalid ptrs were added +// [Files] Hii.c, Parse.c, Uefi21Wapper.c +// +// 42 2/02/12 3:12a Premkumara +// Updated with CheckBox scope issue. +// +// 41 2/02/12 3:03a Premkumara +// [TAG] EIP75066 +// [Category] Improvement +// [Description] Support loading defaults for Ordelist controls +// [Files] Ordlistbox.c, Uefi21Wapper.c, CtrlCond.c, HiiCallback.c, +// Parse.c, Uefi20Wapper.c, TseUefihiil.h +// +// 40 1/20/12 1:59a Arunsb +// [TAG] EIP80424 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Circular reference is not updated after pack update which +// leads to RSOD +// [RootCause] Circular reference is not updated after pack update which +// leads to RSOD +// [Solution] Setting NewPageInfo->PageHandle before calling +// _AdvAddPageToList() so that Circular reference is updated properly +// [Files] Parse.c +// +// 39 1/17/12 5:39a Premkumara +// [TAG] EIP80422 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Update Defaults for Checkbox controls doesn't support scope +// [RootCause] The flaw in this is that this code will never get +// executed as the scope of a Checkbox control is always 1 +// [Solution] Comment the scope check if(CheckBoxOp->Header.Scope == 0) +// in _UpdateDefaults() function to execute if scope is 0 +// [Files] Parse.c +// +// 38 11/30/11 6:34a Premkumara +// [TAG] EIP71351 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Setup Crash when iSCSI is loaded +// [RootCause] Aptio giving length as 0xe(matches size of +// EFI_IFR_ONE_OF_OPTION) but in latest EDKII driver it is 0x1c. +// [Solution] change the length as j += ((EFI_IFR_OP_HEADER*)(buff + i + +// j))->Length; +// [Files] Parse.c, Hii.c, Variable.c, Minisetupext.c, +// +// 37 11/14/11 2:43p Blaines +// [TAG] - EIP 75481 +// [Category]- Function Request +// [Synopsis]- TSE debug print infrastructure. +// [Description]- Add TSE debug print info for basic functions such as +// Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms +// data. +// [Files] +// AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c +// Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c, +// HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h, +// Uefi21Wrapper.c, setupdbg.h +// +// 36 11/14/11 4:27a Arunsb +// [TAG] EIP72540 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Advance page disappear on using 4.6.2_TSE_2_14_1219 +// [RootCause] Offline pages also considered in dynamic parsing +// [Solution] Offline pages are not considered in dynamic parsing +// [Files] hii.c and parse.c +// +// 35 11/10/11 11:47a Premkumara +// [TAG] EIP73396 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] On Pressing ESC the token SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY +// key doesnt work in UEFI2.1 +// [RootCause] In AddPageIdToList() function. +// If PageIdSize = 0 then first pageInfo will not copy into PageIdInfoPtr +// [Solution] In Parse.c, +// - removed PageIdSize =0 in AddPageIdToList() function. If PageIdSize = +// 0 then first pageInfo will not copy into PageIdInfoPtr +// [Files] Parse.c +// +// 34 9/29/11 3:24p Madhans +// File Checkin comments corrected. +// +// 33 8/26/11 6:12p Blaines +// [TAG] EIP68354 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] non-refresh date control is gets refreshed +// [RootCause] Date controls that don't have IFR_REFRESH_OP are being +// assumed to have it. The Flags are not checked for type +// QF_DATE_STORAGE_TIME. +// [Solution] The Flags are checked for type QF_DATE_STORAGE_TIME. +// [Files] TseLite: Time.c, Date.c +// Uefi21: Parese.c, Uefi21Wrapper.c +// +// 31 6/30/11 4:19a Arunsb +// [TAG] EIP57661 +// [Category] New Feature +// [Description] Boot manager algorithm for interaction with Driver +// Health protocol. +// Dynamic parsing changed for driver health config. page +// via sendform. +// [Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni, +// commonhelper.c, uefisetup.ini, tsedrvhealth.h, +// amivfr.h, minisetupbin.mak, +// hiistring21.c, hiistring20.c, tseadvanced.c, special.c, +// special.h, boot.h, minisetup.h, +// uefi20wapper.c, formbrowser2.c, hii.c, parse.c and +// uefi21wapper.c. +// +// 30 6/28/11 2:40p Arunsb +// Build error resolved +// +// 29 6/28/11 9:38a Arunsb +// EIP 56405 . Review comment addressed +// Comment: Uncomment the 2.1 EFI Varstore support part. +// +// 28 6/24/11 10:16a Premkumara +// [TAG] EIP62310, EIP 59743, EIP 62308 +// [Category] Improvement +// [Description] Merge all SupportEFI_IFR_SUPPRESS_IF_OP, +// EFI_IFR_GRAYOUT_IF_OP, +// cases in one case +// [Files] Parse.c +// +// 27 6/23/11 4:02p Rajashakerg +// [TAG] EIP55762, 58925, 59971 +// [Category] New Feature +// [Description] Support REF2,REF3 and REF4 in AMITSE +// Support direct form navigation path +// Improper layout of controls in the root page when Dynamic pages are +// added using the Legacy Setup Style +// +// [Files] setupdata.h, CommonHelper.c, AMITSE.sdl, Legacy\Legacy.c, +// Legacy\style.h, Legacy\style.h, frame.c, minisetupext.c, +// minisetupext.h, numeric.c, page.c Popupstring.c, Hii.c, +// Uefi21Wrapper.c, Parse.c Hii.c +// +// 26 6/22/11 5:17p Arunsb +// [TAG] EIP56405 +// [Category] New Feature +// [Description] Support for EFI_IFR_VARSTORE_NAME_VALUE opcode +// [Files] Hii.c, parse.c and uefi21wapper.c +// +// 25 6/22/11 9:27a Premkumara +// [TAG] EIP 62310, EIP 59743, EIP 62308 +// [Description] SupportEFI_IFR_SUPPRESS_IF_OP, EFI_IFR_GRAYOUT_IF_OP, +// EFI_IFR_DISABLE_IF_OP Over the Form or Formset +// [Files] parse.c +// +// 24 6/08/11 4:52p Arunsb +// [TAG] EIP61650 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Cannot edit time field when using new "time" format +// [RootCause] Default refresh interval set to all the time variables +// [Solution] Default refresh interval provided only for RTC time +// variable +// [Files] uefi2.1\Parse.c +// +// 23 6/01/11 4:11p Madhans +// [TAG] EIP61588 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Advanced -> ISCSI -> Add an attempt-> Mac Address -> Save +// changes causes the system to hang. +// [RootCause] Dynamic update for the goto control to same target page +// was not updated correctly. +// [Solution] Fixed to update the control destination page correctly. +// [Files] parse.c +// special.c +// +// 22 5/31/11 9:52a Premkumara +// [TAG] EIP48930 +// [Description] Boot override hangs with exception 0x0d +// [Files] Parse.c, hii.c +// +// 21 4/29/11 4:46p Arunsb +// For 2.13 public patch release IFR RefX feature is omitted +// +// 20 4/22/11 6:09p Arunsb +// [TAG] EIP59002 +// [Category] Bug Fix +// [Severity] Normal +// [RootCause] Refresh interval not set properly +// [Solution] If control has callback then it is handled in +// EFI_IFR_ACTION_OP +// also. +// [Files] Parse.c +// +// 19 4/20/11 5:37p Blaines +// [TAG] - EIP 55762 +// [Category]- Action Item +// [Synopsis]- Add support for IFR RefX controls. +// [Files] - setupdata.h, special.c, frame.c, Hii.c, Parse.c, +// Uefi21Wrapper.c +// +// 18 3/28/11 11:03p Madhans +// [TAG] EIP56414 +// [Category] Improvement +// [Description] TSE: Support for EFI_IFR_NO_SUBMIT_IF opcode +// [Files] Callback.c, FakeToken.c, AMITSEstr.uni, Parse.c, CtrlCond.c, +// CtrlCond.h, ctrlcond.h, ctrlcond.c +// +// 17 3/28/11 9:49p Premkumara +// [TAG] EIP52562 +// [Category] Improvement +// [Description] Need to have the Fixed Limit in AMITSE module for +// Controls, Pages and Variable etc. +// [Files] TSEUefiHii.h, Hii.c, Parse.c, hii.c +// +// 16 3/28/11 5:34p Rajashakerg +// [TAG] EIP56896 +// [Category] Improvement +// [Description] +// TSE: Support for EFI_IFR_LOCKED opcode +// [Files] Parse.c +// +// 15 3/18/11 2:46a Rajashakerg +// [TAG] EIP56124 +// [Category] New Feature +// [Description] TSE: Support for EFI_IFR_DEFAULT opcode +// [Files] Parse.c, TseUefiHii.h +// +// 14 3/09/11 7:26p Madhans +// [TAG] EIPEIP48615 +// [Category] Improvement +// [Description] To support UEFI 2.1 RefreshOp. Based in Refersh Rate +// Controls are refershed periodically. +// [Files] minisetupext.h +// SubMenu.h +// SubMenu.c +// Memo.c +// Memo.h +// numeric.c +// numeric.h +// time.c +// Date.c +// PopupSel.c +// PopupSel.h +// PopupString.c +// PopupString.h +// ordlistbox.c +// minisetupext.c +// UefiAction.c +// hii.h +// Uefi20wapper.c +// hiicallback.c +// Parse.c +// tseuefihii.h +// Uefi21wapper.c +// +// 13 2/10/11 12:32p Blaines +// [TAG] - EIP 53146 +// [Category]- New Feature +// [Description] -Add the support to Move the Dynamic IFR Pages under +// subpages. It should be customizable to move around. +// +// 12 12/28/10 12:31p Madhans +// To update the Tag of EIp 46998. UEFI option ROM menus disappear in +// Setup when certain options are selected. +// No file changed but Comment updated right +// +// 11 12/06/10 5:48p Madhans +// [TAG] - EIP 49488 +// [Category]- Defect +// [Severity]- Mordarate +// [Symptom]- ISCSI Pages not working. +// [Rootcause] Variable Entry that is added by offline parsing is left +// untouched and it cause the issue when locating the varible based on +// GUID and Variable Name. +// [Solution]- Fixed when adding Variable to the list to check for NULL +// Variable handle. +// [Files] - Parse.c +// +// 10 12/02/10 2:39p Madhans +// [TAG] - EIP 48169 +// [Category]- Enhancement +// [Severity]- Mordarate +// [Symptom]- Code Cleanup and Compiler Warning need to resolved. +// [Rootcause] Warnings reported when we build AMI higher Warning level. +// [Solution]- 1. Fix the warnings and do the code cleanup. +// 2. Introduce proper checks. +// 3. change the popupSel.c to not change the Option/variable +// cache to default or first option +// when the variable cache is not matching with any of +// option. +// [Files] - commonoem.c bbs.c boot.c hiistring.c resource.c +// popuppassword.c popupsel.c +// expression.c hii.c parse.c +// +// 9 10/27/10 4:25p Madhans +// [TAG] EIP46998 +// [Category] Defect +// [Symptom] Some user action on PCIx with UEFI Hii Pages causes Setup +// screen pages and menu disappers. +// [RootCause] UEFI 2.1 parsing code is not handling the Removepack and +// New pack sequance properly. Normally UpdatePack +// does the removepack and AddPack. +// [Solution] UEFI 2.1 parsing code fixed to handle above case correctly. +// [Files] hii.c HiiNotificationHandler.c Parse.c TseUefiHii.h +// uefi21wapper.c +// +// 8 9/16/10 8:38p Madhans +// Update for TSE 2.10. Refer Changelog.log for more details. +// +// 13 9/15/10 1:53p Madhans +// To fix the Issues Parent page fixing with Dynamic update of Pages. +// +// 11 9/07/10 1:43p Blaines +// Support loading defaults for Data&Time in UEFI 2.1 +// +// 10 8/12/10 1:11p Blaines +// EIP-40946 : Fix root page processing to support Award Style setup. +// +// 9 8/10/10 7:14p Madhans +// EIP 40555 : To avoid Compilation issues with Fareast Windows. +// +// 8 6/17/10 4:19p Madhans +// To fix the circular Page referance +// +// 7 6/17/10 2:47p Madhans +// Fix for parsing correctly. +// in Dyncamic parsing Fix the parent pages. +// +// 6 6/14/10 7:14p Madhans +// Dynamic parsing support +// +// 5 3/11/10 5:43p Madhans +// Coding Standards Update +// +// 4 2/15/10 10:19p Madhans +// to support EDK nt32 version +// +// 3 11/19/09 5:31p Presannar +// Updated TSE include file name to not clash with CORE file +// +// 2 8/11/09 2:57p Presannar +// Added fn _AdvAddPageToList, _ReplacePageWithNewPage and +// _AdvAddControlToList to handle dynamic updation of IFR data +// Renamed _GetDefaultValue as GetDefaultValue +// Modified _GetQuestionToken to get prompt of Ordered List opcode +// Modified AddControlToList and AddPageToList to do Advanced Parsing +// Added fn _ReplacePageWithNewPage and _InvalidateExistingPage to help in +// handling Adv Page parsing +// +// 1 7/24/09 6:54p Presannar +// +// 5 5/28/09 11:49a Presannar +// Bug fixes and clean up +// +// 3 5/19/09 11:29a Presannar +// Removed check for Handle, while searching for existing Variable Info. +// This is a temporary fix. The issue needs to be analyzed further to +// check Handle also. +// +// 2 5/13/09 10:43a Presannar +// When EFI_IFR_DEFAULT_OP was encountered, its scope got ignored when +// skipping the opcode. Special handling of EFI_IFR_DEFAULT_OP case was +// removed to allow the default case to take care of it. +// Added File Header +// +//************************************************************************* +// +// +// Name: Parse.c +// +// Description: +// +// +//************************************************************************* + +//--------------------------------------------------------------------------- + +#include "Minisetup.h" +#include "TseUefiHii.h" + +#define PARSE_START_INDEX 1 +//--------------------------------------------------------------------------- + +// +//---------------------------------------------------------------------------- +// Name: PageLink +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// FormID UINT16 +// ParentPageID UINT16 +// PageNum UINT16 +//---------------------------------------------------------------------------- +// +typedef struct PAGELINK +{ + UINT16 FormID; // number from hpk + UINT16 ParentPageID; // number from the tool + UINT16 PageNum; // number assigned by the tool +}PageLink; + +// +//---------------------------------------------------------------------------- +// Name: FormSetLinks +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// PageCount UINT16 +// PageLink[20] PageLink +//---------------------------------------------------------------------------- +// +typedef struct FORMSETLINKS +{ + UINT16 PageCount; + PageLink PageLink[20]; +}FormSetLinks; + +// +//---------------------------------------------------------------------------- +// Name: *PVAR_KEY_TABLE, VAR_KEY_TABLE +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// VarId UINT16 +// Index PageLink +// Handle EFI_HII_HANDLE +// *Next struct _VAR_KEY_TABLE +//---------------------------------------------------------------------------- +// +typedef struct _VAR_KEY_TABLE +{ + UINT32 VarId; + UINT16 Index; + EFI_HII_HANDLE Handle; + struct _VAR_KEY_TABLE *Next; +}*PVAR_KEY_TABLE, VAR_KEY_TABLE; +//---------------------------------------------------------------------------- +// MACRO DEFINITIONS +//---------------------------------------------------------------------------- +#define START_EVAL_IF 0x8000 +#define END_EVAL_IF 0x8001 +#define DEFAULT_REFRESH_RATE 0x01 +#define DEFAULT_DATETIME_REFRESH 0x05 +#define CONTROL_TYPE_MASK 0x0FFF +#define STANDARD_FORM_MAP_GUID { 0x3bd2f4ec, 0xe524, 0x46e4, 0xa9, 0xd8, 0x51, 0x1, 0x17, 0x42, 0x55, 0x62 } + +#ifndef TSE_FOR_APTIO_4_50 +#define EFI_HII_PACKAGE_FORMS EFI_HII_PACKAGE_FORM +#include "tianohii.h" +#endif +//---------------------------------------------------------------------------- +// VARIABLE DECLARATIONS +//---------------------------------------------------------------------------- +static FormSetLinks *FSetLinks; + +VAR_KEY_TABLE VarKeyTable; + +BOOLEAN ResetCondVars = TRUE; +BOOLEAN ResetVars = TRUE; +BOOLEAN Inconsistant = FALSE; +BOOLEAN NoSubmitIf = FALSE; // EIP: NO_SUBMIT_IF +BOOLEAN IsRecursive = FALSE; +UINT8 DefaultStoreCount = 0; +UINT32 CtrlVar = 0; +UINT32 gnewCtrlVar = 0; +UINT32 PageOffset; +UINT32 PageVar = 0; +UINT32 gRefreshIdCount = 0; //No. of controls with Refresh Id set +UINTN gDynamicPageCount=0; +VOID *gConditionalOverFormPtr = NULL;//EIP-120418 +BOOLEAN updateformcondvars = TRUE; +BOOLEAN gConditionOverForm = FALSE; +//BOOLEAN IsRefreshIdSet = FALSE; +EFI_GUID RefreshEventGroupId; +REFRESH_ID_INFO *gRefreshIdInfo = NULL; +EFI_GUID StandardFormGuid = STANDARD_FORM_MAP_GUID; + +//--------------------------------------------------------------------------- +// EXTERN VARIABLES +//--------------------------------------------------------------------------- +extern PAGE_ID_INFO *PageIdInfoPtr; +extern PAGE_ID_LIST *PageIdListPtr; +extern PAGE_INFO *FirstPage; +extern PAGE_INFO *NewPageInfo; +extern PAGE_INFO *PageInfoPtr; +extern PAGE_LIST *PageListPtr; +extern VARIABLE_LIST *VariableListPtr; +extern VARIABLE_INFO *VariableInfoPtr; + +extern UINT32 AllocatedFirstPageSize, FirstPageOffset; +extern UINT32 ControlListSize, ControlListOffset; +extern UINT32 PageIdInfoSize, PageIdInfoOffset; +extern UINT32 PageIdListSize, PageIdListOffset; +extern UINT32 PageInfoSize, PageInfoOffset; +extern UINT32 PageListSize, PageListOffset; +extern UINT32 VariableListSize, VariableListOffset; +extern UINT32 VariableInfoSize, VariableInfoOffset; +extern UINTN TotalRootPages; +extern SETUP_LINK *gSetupData ; +extern VOID **gSfHandles; +extern EFI_GUID *gGuidDump; //EIP64253 offline vfr pages hided +extern UINTN gGuidDumpCount; +//--------------------------------------------------------------------------- +// EXTERN FUNCTIONS +//--------------------------------------------------------------------------- +extern BOOLEAN IsGroupDynamicPages(); +extern BOOLEAN IsOrphanPagesAsRootPage(); + +extern EFI_STATUS DebugShowControlInfo(UINT32 formID, VOID *passedCtrlInfo) ; +extern VOID DebugShowPageInfo(UINT32 formID, VOID *passedPageInfo) ; +extern VOID ResetExpressionStack ( VOID ); +extern EFI_STATUS PushExpression (IN EFI_HII_VALUE *Value); +extern EFI_STATUS PopExpression (IN EFI_HII_VALUE *Value); +extern INTN CompareHiiValue (IN EFI_HII_VALUE *Value1,IN EFI_HII_VALUE *Value2,IN EFI_HII_HANDLE HiiHandle OPTIONAL); +extern EFI_STATUS _GetValueFromQuestionId(UINT16 QuestionId, UINT16 PageId, EFI_HII_VALUE **Value); +extern EFI_STATUS VarGetValue( UINT32 variable, UINT32 offset, UINTN size, VOID *buffer ); + +extern VOID *gFirstPageRef; +extern UINT32 GetUefiSpecVersion (VOID); +extern BOOLEAN ShowClassGuidFormsets (TSE_EFI_IFR_FORM_SET *SetupFormSet );//EIP-139099 +extern BOOLEAN HideDynamicFormsets (EFI_GUID *FormSetGuid );//EIP-95647 +//--------------------------------------------------------------------------- +// FUNCTION DECLARATIONS +//--------------------------------------------------------------------------- +EFI_STATUS _AddVariable(UINT8 *IFRData, EFI_HII_HANDLE Handle); +EFI_STATUS _InitFormsetLinks(char *buff, UINTN InitFormNum); +EFI_STATUS _AdvAddPageToList(PAGE_INFO *NewPageInfo, UINT32 PageSize); +EFI_STATUS _ReplacePageWithNewPage(PAGE_INFO *OldPageInfo, PAGE_INFO *NewPageInfo, UINT32 PageSize); +EFI_STATUS _InvalidateExistingPage(PAGE_INFO *OldPageInfo, PAGE_INFO *NewPageInfo); +VOID RefreshGroupOnCallBack(EFI_EVENT Event, VOID *Context); +UINT8 _IsVarGuidPresent(EFI_GUID *VarGuid, int *Index); +UINT16 _GetPageIdIndex(EFI_GUID *FormGuid, UINT16 FormClass, UINT16 FormSubClass); +UINT16 _GetPageParent(int PageNum); +UINT32 _AddFormSetVariable(EFI_GUID *VarGuid); +UINT32 _AdvAddControlToList(CONTROL_INFO *ControlInfo, UINT32 ControlSize); +UINT32 _GetVarNumFromVarID(UINT32 ID, EFI_HII_HANDLE Handle, void *); +UINTN _AddHpkControls(EFI_HII_HANDLE Handle, UINT8 *buff,UINTN Size, PAGE_INFO **NewPageInfo, UINT32 *AllocatedPageSize, UINT32 *PageOffset); +UINTN _GetSubFormCount(UINT8 *buff); +UINT16 _GetQuestionToken(UINT8 *ifrData) ; +VOID _CleanVarKeyTable(); +EFI_STATUS CreateEventforIFR (CONTROL_INFO *control_Info );//EIP-105468 + + + +// +//---------------------------------------------------------------------------- +// +// Procedure: _AddFormSetVariable +// +// Description: +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// +UINT32 _AddFormSetVariable(EFI_GUID * VarGuid) +{ + VARIABLE_INFO Variable; + UINT32 i; + + MemSet(&Variable, sizeof(Variable), 0); + MemCopy((&Variable.VariableGuid),VarGuid,sizeof(EFI_GUID)); + Variable.VariableAttributes = 0x7; // BT+RT+NV + EfiStrCpy(Variable.VariableName,L"Setup"); + + i = VariableListPtr->VariableCount; + AddVariableToList(&Variable); + + return i; +} + +//---------------------------------------------------------------------------- +// Procedure: _DisplayErrorMessage +// +// Description: Function to display Error message when TSE supported limit exceeds +// +//---------------------------------------------------------------------------- + +EFI_STATUS _DisplayErrorMessage(CHAR16 *Temp) +{ + EFI_EVENT Event; + EFI_STATUS status = EFI_SUCCESS;; + status = PostManagerDisplayInfoBox(L" Unrecoverable Error",Temp,20,&Event); + if(status) + { + gST->ConOut->OutputString(gST->ConOut,Temp); + } + return status; +} + +//---------------------------------------------------------------------------- +// Procedure: _AddVariable +// +// Description: +//---------------------------------------------------------------------------- +BOOLEAN VariableHandleSuppressed (EFI_GUID *VariableGuid, CHAR16 *VariableName); +EFI_STATUS _AddVariable(UINT8 *IFRData, EFI_HII_HANDLE Handle) +{ + EFI_GUID *guid=NULL; + EFI_STATUS status = EFI_SUCCESS; + VARIABLE_INFO *variable=NULL; + VARIABLE_INFO newVariable; + PVAR_KEY_TABLE pVarTable; + + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER*)IFRData; + EFI_IFR_VARSTORE *varstore=NULL; + AMI_EFI_IFR_VARSTORE_EFI *efivarstore; + EFI_IFR_VARSTORE_NAME_VALUE *nameValuevarstore; + + char *str2; + CHAR16 *varNamePtr; + UINT16 i; + UINT16 varId = 0; + UINT16 varName[40]; + UINT16 varstoreSize = 0; + UINT32 attributes = 0; + UINT32 extAttributes = 0; + UINTN varfound = 0; + BOOLEAN bGreaterUEFIVersion = FALSE; + + SETUP_DEBUG_UEFI ( "\n[TSE] Entering _AddVariable()\n" ); + + switch(opHeader->OpCode) + { + case EFI_IFR_VARSTORE_OP: + varstore = (EFI_IFR_VARSTORE*)IFRData; + guid = &(varstore->Guid); + varId = varstore->VarStoreId; + varstoreSize = varstore->Size; + attributes |= 0; + extAttributes |= VARIABLE_ATTRIBUTE_VARSTORE; + str2 = (char*)varstore->Name; + + //Convert to unicode string + MemSet(varName, sizeof(varName), 0); + i = 0; + for(varNamePtr = varName; *str2; *varNamePtr = *str2, str2++, varNamePtr++) + ; + break; + case EFI_IFR_VARSTORE_EFI_OP: + efivarstore = (AMI_EFI_IFR_VARSTORE_EFI*)IFRData; + guid = &(efivarstore->Guid); + varId = efivarstore->VarStoreId; + attributes |= efivarstore->Attributes; + extAttributes |= VARIABLE_ATTRIBUTE_EFI_VARSTORE; + if ((GetUefiSpecVersion()) > 0x2001E) //If UEFI spec version is greater than 2.3 then store the Name and size from the opcode + { + bGreaterUEFIVersion = TRUE; //set it to True for version great than 2.3 + str2 = (char*)efivarstore->Name; //name of the opcode + //Convert to unicode string + MemSet(varName, sizeof(varName), 0); + i = 0; + for(varNamePtr = varName; *str2; *varNamePtr = *str2, str2++, varNamePtr++) + ; + + varstoreSize = efivarstore->Size; //size of the varstore + } + break; + case EFI_IFR_VARSTORE_NAME_VALUE_OP: + nameValuevarstore = (EFI_IFR_VARSTORE_NAME_VALUE*)IFRData; + guid = &(nameValuevarstore->Guid); + varId = nameValuevarstore->VarStoreId; + EfiStrCpy (varName, L""); + attributes |= 0; + extAttributes |= VARIABLE_ATTRIBUTE_NAMEVALUE; + break; + default: + break; + } + + // check that the variable is not already in the list + for(i=0; i < VariableListPtr->VariableCount; i++) + { + variable = (VARIABLE_INFO*)((UINT8 *)VariableInfoPtr + VariableListPtr->VariableList[i]); + if( EfiCompareGuid(guid, &(variable->VariableGuid)) )//Compare Guid + { + switch(opHeader->OpCode) + { + case EFI_IFR_VARSTORE_OP: + if((EfiStrCmp(varName, variable->VariableName) ==0)) + { + if ((Handle == variable->VariableHandle) || VariableHandleSuppressed (guid, varName)) + { + varfound=1; + break; + } + + // Aptio SETUP Patch. refer EIP 39861 + // In aptio If it Setup Variable all the forms refers same varstore. + if((i==0) || UefiIsEfiVariable(i, variable)) + { + varfound=1; + break; + } + + if(variable->VariableHandle == NULL) + { + // if Variable Handle is zero, then it added from OFFline parsing and we need use this + // Entry if the size also matchs. + if(varstore->Size == variable->VariableSize) + { + variable->VariableHandle = Handle; + varfound=1; + break; + } + } + + } + break; + case EFI_IFR_VARSTORE_EFI_OP: + + if (bGreaterUEFIVersion) //If UEFI spec version is greater than 2.3, then use the name to find the variable + { + if((EfiStrCmp(varName, variable->VariableName) ==0)) + { + if ((Handle == variable->VariableHandle) || VariableHandleSuppressed (guid, varName)) + { + varfound=1; + break; + } + + // Aptio SETUP Patch. refer EIP 39861 + // In aptio If it Setup Variable all the forms refers same varstore. + if((i==0) || UefiIsEfiVariable(i, variable)) + { + varfound=1; + break; + } + + if(variable->VariableHandle == NULL) + { + // if Variable Handle is zero, then it added from OFFline parsing and we need use this + // Entry if the size also matchs. + if(efivarstore->Size == variable->VariableSize) + { + variable->VariableHandle = Handle; + varfound=1; + break; + } + } + + } + } + else + { + if((variable->ExtendedAttibutes & VARIABLE_ATTRIBUTE_EFI_VARSTORE) == VARIABLE_ATTRIBUTE_EFI_VARSTORE && + variable->VariableAttributes == attributes) + { + varfound = 1; + } + } + break; + case EFI_IFR_VARSTORE_NAME_VALUE_OP: + varfound = 1; + break; + } + if(varfound) + { + break; + } + } + } + + if(!varfound) + { + MemSet(&newVariable, sizeof(VARIABLE_INFO), 0); + newVariable.VariableID = varId; + MemCopy((&newVariable.VariableGuid),guid,sizeof(EFI_GUID)); + newVariable.VariableAttributes = attributes; + newVariable.ExtendedAttibutes = extAttributes; + newVariable.VariableHandle = Handle; + + if(opHeader->OpCode == EFI_IFR_VARSTORE_OP) + { + EfiStrCpy(newVariable.VariableName, varName); + newVariable.VariableSize = varstoreSize; + } + else if ((EFI_IFR_VARSTORE_EFI_OP == opHeader->OpCode) && (bGreaterUEFIVersion)) //Name is available in the opcode only if UEFI spec followed is + { //greater than 2.3 + EfiStrCpy(newVariable.VariableName, varName); + newVariable.VariableSize = varstoreSize; + } + + AddVariableToList(&newVariable); + }else + { + variable->VariableID = varId; + variable->VariableHandle = Handle; + variable->ExtendedAttibutes = extAttributes; + + if(opHeader->OpCode == EFI_IFR_VARSTORE_OP) + { + variable->VariableSize = varstoreSize; + } + else if (EFI_IFR_VARSTORE_NAME_VALUE_OP == opHeader->OpCode) + { + EfiStrCpy (variable->VariableName, varName); + } + else if ((EFI_IFR_VARSTORE_EFI_OP == opHeader->OpCode) && (bGreaterUEFIVersion)) //Size is available in the opcode only if UEFI spec followed is + { //greater than 2.3 + variable->VariableSize = varstoreSize; + } + } + + pVarTable = &VarKeyTable; + + while(pVarTable->Next) + pVarTable = pVarTable->Next; + + pVarTable->Next = EfiLibAllocateZeroPool(sizeof(VAR_KEY_TABLE)); + if(pVarTable->Next == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + pVarTable = pVarTable->Next; + pVarTable->VarId = varId; + pVarTable->Handle = Handle; + pVarTable->Index = i; + +DONE: + SETUP_DEBUG_UEFI( "\n[TSE] Exiting _AddVariable(), status = 0x%x \n" , status ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _CleanVarKeyTable +// +// Description: Clean VarKey Table +// +// Parameter: None +// +// Return value: None +//---------------------------------------------------------------------------- +// +VOID _CleanVarKeyTable() +{ + PVAR_KEY_TABLE pVarTable = VarKeyTable.Next; + + while(pVarTable) + { + VarKeyTable.Next = pVarTable->Next; + MemFreePointer(&pVarTable); + pVarTable = VarKeyTable.Next; + } +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetControlKeyToken +// +// Description: Get ControlKey Token +// +// Parameter: None +// +// Return value: None +//---------------------------------------------------------------------------- +// +UINT16 _GetControlKeyToken(UINT8 *IFRData) +{ + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER*)IFRData; + EFI_IFR_QUESTION_HEADER *question; + UINT16 questionKey = 0; + + switch(opHeader->OpCode) + { + case EFI_IFR_ONE_OF_OP: // 0x05 + case EFI_IFR_CHECKBOX_OP: // 0x06 + case EFI_IFR_NUMERIC_OP: // 0x07 + case EFI_IFR_PASSWORD_OP: // 0x08 + case EFI_IFR_ACTION_OP: // 0x0C + case EFI_IFR_RESET_BUTTON_OP: // 0x0D + case EFI_IFR_REF_OP: // 0x0F + case EFI_IFR_DATE_OP: // 0x1A + case EFI_IFR_TIME_OP: // 0x1B + case EFI_IFR_STRING_OP: // 0x1C + case EFI_IFR_ORDERED_LIST_OP: // 0x23 + question = (EFI_IFR_QUESTION_HEADER*)((UINT8*)IFRData + sizeof(EFI_IFR_OP_HEADER)); + questionKey = question->QuestionId; + break; + case EFI_IFR_RULE_OP: // 0x18 + questionKey = ((EFI_IFR_RULE*)((UINT8*)IFRData))->RuleId; + break; + default: + break; + } + + return questionKey; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetControlDevicePathId +// +// Description: Get Control DevicePathId +// +// Parameter: +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 _GetControlDevicePathId(UINT8 *IFRData) +{ + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER*)IFRData; + UINTN inScope = 0; + UINTN i = 0; + UINT16 devicePath = 0; + BOOLEAN found = FALSE; + + if(opHeader->Scope) + { + do + { + switch(opHeader->OpCode) + { + case EFI_IFR_VARSTORE_DEVICE_OP: + devicePath = ((EFI_IFR_VARSTORE_DEVICE*)((UINT8*)IFRData + i))->DevicePath; + found = TRUE; + break; + case EFI_IFR_END_OP: + inScope--; + break; + default: + if(opHeader->Scope) + { + inScope++; + } + } + i += opHeader->Length; + opHeader = (EFI_IFR_OP_HEADER*)(IFRData + i); + }while(inScope || found); + } + + return devicePath; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetDefaultValue +// +// Description: Get Default Value +// +// Input: UINT8 Type +// EFI_IFR_TYPE_VALUE *Value +// UINT16 *Size - [IN/OUT] parameter - IN for the type +// EFI_IFR_TYPE_BUFFER. For all other types, +// as OUT parameter +// VOID *DefValue +// +// Output: Void +//---------------------------------------------------------------------------- +// +VOID GetDefaultValue(UINT8 Type, EFI_IFR_TYPE_VALUE *Value, UINT16 *Size, VOID *DefValue, UINT8 *TempData) +{ + UINT8 *Data = TempData; + switch(Type) + { + case EFI_IFR_TYPE_NUM_SIZE_8: + *Size = (UINT16)sizeof(UINT8); + *(UINT8*)DefValue = Value->u8; + break; + case EFI_IFR_TYPE_NUM_SIZE_16: + case EFI_IFR_TYPE_STRING: + *Size = (UINT16)sizeof(UINT16); + *(UINT16*)DefValue = Value->u16; + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + *Size = (UINT16)sizeof(UINT32); + *(UINT32*)DefValue = Value->u32; + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + *Size = (UINT16)sizeof(UINT64); + *(UINT64*)DefValue = Value->u64; + break; + case EFI_IFR_TYPE_DATE: + *Size = sizeof(EFI_HII_DATE); + MemCopy(DefValue, &(Value->date), sizeof(EFI_HII_DATE)); + break; + case EFI_IFR_TYPE_TIME: + *Size = sizeof(EFI_HII_TIME); + MemCopy(DefValue, &(Value->time), sizeof(EFI_HII_TIME)); + break; + case EFI_IFR_TYPE_BUFFER: + // Size will be received as parameter + MemCopy(DefValue, Value, *Size); + break; + case EFI_IFR_TYPE_REF: //EIP109812, 107774 + // Size will be received as parameter + MemCopy (DefValue, Value, *Size); + break; + case EFI_IFR_TYPE_BOOLEAN: + *Size = 1; + MemCopy(DefValue, &(Value->b), *Size); + break; + case EFI_IFR_TYPE_OTHER: + { + UINTN ScopeCount = 0; + EFI_IFR_OP_HEADER *OpHeader = (EFI_IFR_OP_HEADER *)Data; + EFI_IFR_DEFAULT *DefaultOp = NULL; + *Size = 0; + + if (OpHeader->Scope) + { + ScopeCount ++; + OpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)OpHeader + OpHeader->Length); + if (OpHeader->Scope) + { + ScopeCount ++; + if (EFI_IFR_VALUE_OP == OpHeader->OpCode) + { + OpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)OpHeader + OpHeader->Length); + switch (OpHeader->OpCode) + { + case EFI_IFR_UINT8_OP: + *Size = (UINT16)sizeof (UINT8); + *(UINT8 *)DefValue = *(UINT8 *)((UINT8 *)OpHeader + sizeof (EFI_IFR_OP_HEADER)); + break; + case EFI_IFR_UINT16_OP: + *Size = (UINT16)sizeof (UINT16); + *(UINT16 *)DefValue = *(UINT16 *)((UINT8 *)OpHeader + sizeof (EFI_IFR_OP_HEADER)); + break; + case EFI_IFR_UINT32_OP: + *Size = (UINT16)sizeof (UINT32); + *(UINT32 *)DefValue = *(UINT32 *)((UINT8 *)OpHeader + sizeof (EFI_IFR_OP_HEADER)); + break; + case EFI_IFR_UINT64_OP: + *Size = (UINT16)sizeof (UINT64); + *(UINT64 *)DefValue = *(UINT64 *)((UINT8 *)OpHeader + sizeof (EFI_IFR_OP_HEADER)); + break; + default: + *Size = 0; + break; + } + } + } + } + while (ScopeCount) + { + OpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)OpHeader + OpHeader->Length); + if (EFI_IFR_END_OP == OpHeader->OpCode) + { + ScopeCount --; + } + } + } + break; + default: + *Size = 0; + *(UINT8*)DefValue = 0; + break; + } + +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetHelpToken +// +// Description: Get Control Question Help Token +// +// Parameter: +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 _GetHelpToken(UINT8 *ifrData) +{ + EFI_IFR_OP_HEADER *headerPtr = (EFI_IFR_OP_HEADER*)ifrData; + UINT16 token = 0; + + switch ( headerPtr->OpCode ) + { + case EFI_IFR_TEXT_OP: + { + EFI_IFR_TEXT *ptr = (EFI_IFR_TEXT*)headerPtr; + token = ptr->Statement.Help; + } + break; + case EFI_IFR_ORDERED_LIST_OP: + { + EFI_IFR_ORDERED_LIST *ptr = (EFI_IFR_ORDERED_LIST*)headerPtr; + token = ptr->Question.Header.Help; + } + break; + case EFI_IFR_ONE_OF_OP: + { + EFI_IFR_ONE_OF *ptr = (EFI_IFR_ONE_OF*)headerPtr; + token = ptr->Question.Header.Help; + } + break; + case EFI_IFR_CHECKBOX_OP: + { + EFI_IFR_CHECKBOX *ptr = (EFI_IFR_CHECKBOX*)headerPtr; + token = ptr->Question.Header.Help; + } + break; + case EFI_IFR_DATE_OP: + case EFI_IFR_TIME_OP: + case EFI_IFR_NUMERIC_OP: + { + EFI_IFR_NUMERIC *ptr = (EFI_IFR_NUMERIC*)headerPtr; + token = ptr->Question.Header.Help; + } + break; + case EFI_IFR_PASSWORD_OP: + { + EFI_IFR_PASSWORD *ptr = (EFI_IFR_PASSWORD*)headerPtr; + token = ptr->Question.Header.Help; + } + break; + case EFI_IFR_ACTION_OP: + { + EFI_IFR_ACTION *ptr = (EFI_IFR_ACTION*)headerPtr; + token = ptr->Question.Header.Help; + } + break; + case EFI_IFR_RESET_BUTTON_OP: + { + EFI_IFR_RESET_BUTTON *ptr = (EFI_IFR_RESET_BUTTON*)headerPtr; +#ifdef TSE_FOR_APTIO_4_50 + token = ptr->Statement.Help; +#else + token = ptr->Question.Header.Help; +#endif + } + case EFI_IFR_REF_OP: + { + EFI_IFR_REF *ptr = (EFI_IFR_REF*)headerPtr; + token = ptr->Question.Header.Help; + } + break; + case EFI_IFR_STRING_OP: + { + EFI_IFR_STRING *ptr = (EFI_IFR_STRING*)headerPtr; + token = ptr->Question.Header.Help; + } + break; + default: + break; + } + + return token; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetPageIdIndex +// +// Description: Get Page ID index +// +// Parameter: +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 _GetPageIdIndex(EFI_GUID * FormGuid, UINT16 FormClass, UINT16 FormSubClass) +{ + UINT16 i; + PAGE_ID_INFO *pageId; + + if(PageIdListPtr == NULL) + { + PageIdListSize = 128; + PageIdListPtr = (PAGE_ID_LIST *)EfiLibAllocateZeroPool(128); + PageIdListOffset = sizeof(UINT32); // Points to first Offset of PageIdList + } + + //search if this combination exists + for(i = 0; i < PageIdListPtr->PageIdCount ; i++) + { + pageId = (PAGE_ID_INFO *) ((UINT8 *)PageIdInfoPtr + PageIdListPtr->PageIdList[i]); + if( EfiCompareGuid(FormGuid,&(pageId->PageGuid)) )//Compare Guid + { + if(FormClass == pageId->PageClass)//Compare class + { + if(FormSubClass == pageId->PageSubClass)//Compare SubClass + { + break; //found entry + } + } + } + } + + if(i >= PageIdListPtr->PageIdCount) + { + PAGE_ID_INFO NewPageId; + + MemCopy(&(NewPageId.PageGuid),FormGuid,sizeof(EFI_GUID)); + NewPageId.PageClass = FormClass; + NewPageId.PageSubClass = FormSubClass; + + i = (UINT16)PageIdListPtr->PageIdCount; + AddPageIdToList(&NewPageId); + } + + return i; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetPageNumFromFormID +// +// Description: Get Page Id from Form Id +// +// Parameter: +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 _GetPageNumFromFormID(UINTN FormID) +{ + UINTN i=0; + + do{ + if(FSetLinks->PageLink[i].FormID == FormID) + { + return (FSetLinks->PageLink[i].PageNum); + break; + } + }while(i++ < FSetLinks->PageCount); + + return 0; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetPageParent +// +// Description: Get Parent Page PageID +// +// Parameter: +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 _GetPageParent(int PageNum) +{ + UINT16 i=0; + + do{ + if(FSetLinks->PageLink[i].PageNum == PageNum ) + { + return (FSetLinks->PageLink[i].ParentPageID ); + break; + } + }while( i++ < FSetLinks->PageCount ); + + return 0; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetQuestionToken +// +// Description: Get Control Question Prompt +// +// Parameter: +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 _GetQuestionToken(UINT8 *ifrData) +{ + EFI_IFR_OP_HEADER *headerPtr = (EFI_IFR_OP_HEADER*)ifrData; + UINT16 token = 0; + + switch ( headerPtr->OpCode ) + { + case EFI_IFR_TEXT_OP: + { + EFI_IFR_TEXT *ptr = (EFI_IFR_TEXT*)headerPtr; + token = ptr->Statement.Prompt; + } + break; + case EFI_IFR_ONE_OF_OP: + { + EFI_IFR_ONE_OF *ptr = (EFI_IFR_ONE_OF*)headerPtr; + token = ptr->Question.Header.Prompt; + } + break; + case EFI_IFR_CHECKBOX_OP: + { + EFI_IFR_CHECKBOX *ptr = (EFI_IFR_CHECKBOX*)headerPtr; + token = ptr->Question.Header.Prompt; + } + break; + case EFI_IFR_DATE_OP: + case EFI_IFR_TIME_OP: + case EFI_IFR_NUMERIC_OP: + { + EFI_IFR_NUMERIC *ptr = (EFI_IFR_NUMERIC*)headerPtr; + token = ptr->Question.Header.Prompt; + } + break; + case EFI_IFR_ORDERED_LIST_OP: + { + EFI_IFR_ORDERED_LIST *ptr = (EFI_IFR_ORDERED_LIST *)headerPtr; + token = ptr->Question.Header.Prompt; + } + break; + case EFI_IFR_PASSWORD_OP: + { + EFI_IFR_PASSWORD *ptr = (EFI_IFR_PASSWORD*)headerPtr; + token = ptr->Question.Header.Prompt; + } + break; + case EFI_IFR_ACTION_OP: + { + EFI_IFR_ACTION *ptr = (EFI_IFR_ACTION*)headerPtr; + token = ptr->Question.Header.Prompt; + } + break; + case EFI_IFR_RESET_BUTTON_OP: + { + EFI_IFR_RESET_BUTTON *ptr = (EFI_IFR_RESET_BUTTON*)headerPtr; +#ifdef TSE_FOR_APTIO_4_50 + token = ptr->Statement.Prompt; +#else + token = ptr->Question.Header.Prompt; +#endif + } + break; + case EFI_IFR_REF_OP: + { + EFI_IFR_REF *ptr = (EFI_IFR_REF*)headerPtr; + token = ptr->Question.Header.Prompt; + } + break; + case EFI_IFR_STRING_OP: + { + EFI_IFR_STRING *ptr = (EFI_IFR_STRING*)headerPtr; + token = ptr->Question.Header.Prompt; + } + break; + case EFI_IFR_SUBTITLE_OP: + { + EFI_IFR_SUBTITLE *ptr = (EFI_IFR_SUBTITLE*)headerPtr; + token = ptr->Statement.Prompt; + } + break; + default: + break; + } + + return token; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetSubFormCount +// +// Description: Count the subform and Ref inside the formset +// +// Parameter: +// +// Return value: UINTN +//---------------------------------------------------------------------------- +// +UINTN _GetSubFormCount(UINT8 *buff) +{ + UINTN *tmpFormIDBuf; + UINTN MaxPagecount=100; + UINTN PageCount= 0; + UINTN i=0, j=0, found =0; + INTN ScopeCount = 0; + EFI_IFR_OP_HEADER *Header; + + tmpFormIDBuf = (UINTN*)EfiLibAllocateZeroPool(MaxPagecount*sizeof(UINTN)); + //go thru the forms and get the links, creating the lookup table also + do + { + Header = (EFI_IFR_OP_HEADER*)(buff+i); + switch(Header->OpCode ) + { + case EFI_IFR_FORM_OP: // find parent in lookup table and then the parent pageNum to link + // Add page if is not in lookup table already + found=0; + j=0; + + while( (found==0) && ( j < PageCount ) ){ + if(tmpFormIDBuf[j] == ((EFI_IFR_FORM*)Header)->FormId ) + { + found =1; + break; + } + j++; + } + + if(!found) + { + // pages in the root(no parent) + tmpFormIDBuf[PageCount] = ((EFI_IFR_FORM*)Header)->FormId ; + PageCount++; + } + + break; + case EFI_IFR_FORM_MAP_OP: // find parent in lookup table and then the parent pageNum to link + // Add page if is not in lookup table already + found=0; + j=0; + + while((found==0) && (j < PageCount)) + { + if(tmpFormIDBuf[j] == ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId) + { + found =1; + } + j++; + } + + if(!found) + { + // pages in the root(no parent) + tmpFormIDBuf[PageCount] = ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId ; + PageCount++; + } + break; + + case EFI_IFR_REF_OP: // add to lookup table adding the PageID and ParentPageID + // Add page if is not in lookup table already + found=0; + j=0; + + while((found==0) && (j < PageCount)) + { + if(tmpFormIDBuf[j] == ((EFI_IFR_REF*)Header)->FormId) + { + found =1; + } + j++; + } + + if(!found) + { + // pages in the root(no parent) + tmpFormIDBuf[PageCount] = ((EFI_IFR_REF*)Header)->FormId ; + PageCount++; + } + break; + case EFI_IFR_END_OP: + ScopeCount--; + break; + default: + break; + } + if(Header->Scope) + { + ScopeCount++; + } + // If the Buffer is not enough the reallocate more + if(PageCount >= MaxPagecount) + { + UINTN *tmpBuf; + MaxPagecount +=50; + tmpBuf = (UINTN*)EfiLibAllocateZeroPool(MaxPagecount*sizeof(UINTN)); + MemCopy(tmpBuf,tmpFormIDBuf,sizeof(UINTN)*PageCount); + MemFreePointer(&tmpFormIDBuf); + tmpFormIDBuf = tmpBuf; + } + i+=Header->Length; + }while(ScopeCount != 0); + + MemFreePointer(&tmpFormIDBuf); + return PageCount; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetVarNumFromVarID +// +// Description: Get Variable Index +// +// Parameter: +// +// Return value: UINT32 +//---------------------------------------------------------------------------- +// +UINT32 _GetVarNumFromVarID (UINT32 ID, EFI_HII_HANDLE Handle, void *IfrData) +{ + PVAR_KEY_TABLE pVarTable = VarKeyTable.Next; + UINT16 *varString; + UINT16 Width = 0; + VARIABLE_INFO *Variable = NULL; + VARIABLE_INFO newVariable; + EFI_STATUS Status = EFI_SUCCESS; + EFI_IFR_QUESTION_HEADER *QuestionHeader = NULL; + + while(pVarTable) + { + if ((pVarTable->VarId == ID) && (pVarTable->Handle == Handle)) + { + Variable = (VARIABLE_INFO*)((UINT8 *)VariableInfoPtr + VariableListPtr->VariableList [pVarTable->Index]); + if (Variable) + { + if (VARIABLE_ATTRIBUTE_NAMEVALUE == (Variable->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)) + { + QuestionHeader = (EFI_IFR_QUESTION_HEADER *)((UINT8 *)IfrData + sizeof (EFI_IFR_OP_HEADER)); + varString = HiiGetString (Variable->VariableHandle, QuestionHeader->VarStoreInfo.VarName); + Width = UefiGetWidth (IfrData); + if (varString) + { + if (0 == (EfiStrLen (Variable->VariableName))) + { + Variable->VariableSize = Width; + EfiStrCpy (Variable->VariableName, varString); + } + else + { + MemSet (&newVariable, sizeof (VARIABLE_INFO), 0); + EfiCopyMem (&newVariable, Variable, sizeof (VARIABLE_INFO)); + newVariable.VariableSize = Width; + EfiStrCpy (newVariable.VariableName, varString); + Status = AddVariableToList (&newVariable); + if (!EFI_ERROR (Status)) + { + return gnewCtrlVar; + } + } + } + } + return (pVarTable->Index); + } + } + pVarTable = pVarTable->Next; + } + return 0; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _InitFormsetLinks +// +// Description: Init Formset Links +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// +EFI_STATUS _InitFormsetLinks(char *buff,UINTN InitFormNum) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_IFR_OP_HEADER *Header; + + UINTN j=0, found =0, InitForm = InitFormNum; + UINTN ScopeCount = 0, count = 0; + UINT16 RootPageinFormSet=0,RootPageID=0; + UINT16 *_PageIdList = (UINT16 *)NULL, _PageIdListCount = 0; + EFI_FORM_ID tempFormID = 0; + + SETUP_DEBUG_UEFI( "\n[TSE] Entering _InitFormsetLinks()\n"); + + + // allocate memory for data + if(FSetLinks != NULL) + MemFreePointer(&FSetLinks); + + count = _GetSubFormCount(buff); + FSetLinks = (FormSetLinks*)EfiLibAllocateZeroPool(sizeof(FormSetLinks) + count * sizeof(PageLink)); + if(FSetLinks == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + //go thru the forms and get the links, creating the lookup table also + do + { + Header = (EFI_IFR_OP_HEADER*)(buff); + switch(Header->OpCode ) + { + case EFI_IFR_FORM_OP: + // find parent in lookup table and then the parent pageNum to link + // Add page if is not in lookup table already + found = 0; + j = 0; + + while( (found == 0) && ( j < FSetLinks->PageCount ) ) + { + if(FSetLinks->PageLink[j].FormID == ((EFI_IFR_FORM*)Header)->FormId ) + { + FSetLinks->PageLink[j].PageNum = (UINT16)InitForm++; + found = 1; + break; + } + j++; + } + + if(found == 0) + { + if(!RootPageinFormSet) + RootPageinFormSet = ((EFI_IFR_FORM*)Header)->FormId; + // pages in the root(no parent) + FSetLinks->PageLink[FSetLinks->PageCount].FormID = ((EFI_IFR_FORM*)Header)->FormId ; + + if(IsOrphanPagesAsRootPage()) + { + FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = 0; + } + else + { + if(RootPageinFormSet == ((EFI_IFR_FORM*)Header)->FormId) + FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = 0; + else + FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = FSetLinks->PageLink[0].PageNum; + } + + FSetLinks->PageLink[FSetLinks->PageCount].PageNum = (UINT16)InitForm++; + FSetLinks->PageCount++; + } + + if(Header->Scope) + { + ScopeCount++; + } + + break; + case EFI_IFR_FORM_MAP_OP: + // find parent in lookup table and then the parent pageNum to link + // Add page if is not in lookup table already + found = 0; + j = 0; + + while( (found == 0) && ( j < FSetLinks->PageCount ) ) + { + if(FSetLinks->PageLink[j].FormID == ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId ) + { + FSetLinks->PageLink[j].PageNum = (UINT16)InitForm++; + found = 1; + break; + } + j++; + } + + if(found == 0) + { + if(!RootPageinFormSet) + RootPageinFormSet = ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId; + // pages in the root(no parent) + FSetLinks->PageLink[FSetLinks->PageCount].FormID = ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId ; + + if(IsOrphanPagesAsRootPage()) + { + FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = 0; + } + else + { + if(RootPageinFormSet == ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId) + FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = 0; + else + FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = FSetLinks->PageLink[0].PageNum; + } + + FSetLinks->PageLink[FSetLinks->PageCount].PageNum = (UINT16)InitForm++; + FSetLinks->PageCount++; + } + + if(Header->Scope) + { + ScopeCount++; + } + + case EFI_IFR_REF_OP: + // add to lookup table adding the PageID and ParentPageID + // Add page if is not in lookup table already + found = 0; + j = 0; + + while( (found == 0) && ( j < FSetLinks->PageCount ) ) + { + tempFormID = ((EFI_IFR_REF*)Header)->FormId; + if(tempFormID == 0) //If the EFI_IFR_REFX FormId is invalid + { + tempFormID = (UINT16)InitForm; // Set the check FormId to the current FormId + } + + if(FSetLinks->PageLink[j].FormID == tempFormID) + { + if(RootPageinFormSet != FSetLinks->PageLink[j].FormID) + { + if(FSetLinks->PageLink[j].PageNum != (UINT16)InitForm-1) // Parent of the Page can't be same page id. + { + FSetLinks->PageLink[j].ParentPageID = (UINT16)InitForm-1; + } + } + found = 1; + } + j++; + } + + if(found == 0) + { + // sub pages + if(((EFI_IFR_FORM*)Header)->FormId) //If the the FormId is valid, store it + { + FSetLinks->PageLink[FSetLinks->PageCount].FormID = ((EFI_IFR_REF*)Header)->FormId ; + } else{ //Else store the current FormId + FSetLinks->PageLink[FSetLinks->PageCount].FormID = (UINT16)InitForm; + } + FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = (UINT16)InitForm-1; + FSetLinks->PageLink[FSetLinks->PageCount].PageNum = 0; + FSetLinks->PageCount++; + } + break; + case EFI_IFR_END_OP: + ScopeCount--; + break; + default: + if(Header->Scope) + { + ScopeCount++; + } + break; + + } + buff += Header->Length; + }while(ScopeCount != 0); + + // Fix to find the Circulr Links. + for(j=0;jPageCount;j++) + { + if(FSetLinks->PageLink[j].FormID == RootPageinFormSet) + { + RootPageID = FSetLinks->PageLink[j].PageNum; + break; + } + } + + _PageIdList = EfiLibAllocateZeroPool(FSetLinks->PageCount*sizeof(UINT16)); + for(j=0;jPageCount;j++) + { + UINT16 k,CurrentPageId,m,n; + BOOLEAN IsCircular=TRUE; // Default + + if(FSetLinks->PageLink[j].ParentPageID == 0) + continue; // Rootpage. + + CurrentPageId = FSetLinks->PageLink[j].PageNum; + + MemSet(_PageIdList, FSetLinks->PageCount*sizeof(UINT16), 0); + _PageIdListCount = 0; + + k=0; + while(kPageCount) + { + if(FSetLinks->PageLink[k].PageNum == CurrentPageId) + { + _PageIdList[_PageIdListCount++] = CurrentPageId; + CurrentPageId = FSetLinks->PageLink[k].ParentPageID; + + if(CurrentPageId == RootPageID) + break; // Root found. + + // Check if it circular. + for(m=0;(m<_PageIdListCount)&& IsCircular ;m++) + { + if(_PageIdList[m] == CurrentPageId) // Circular pages.. Fix the PageIdList[0] + { + for(n=0;nPageCount;n++) + { + if(FSetLinks->PageLink[n].PageNum == _PageIdList[0]) + { + FSetLinks->PageLink[n].ParentPageID = RootPageID; + IsCircular = FALSE; + break; + } + } + } + } + if(!IsCircular) + break; + + k=0; + continue; + } + k++; + } + + } + MemFreePointer(&_PageIdList); + +DONE: + + SETUP_DEBUG_UEFI( "\n[TSE] Exiting _InitFormsetLinks(), status = 0x%x \n" , status ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _IsVarGuidPresent +// +// Description: Check if the Variable Guid is already defined +// +// Parameter: +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 _IsVarGuidPresent(EFI_GUID * VarGuid, int * Index) +{ + UINT32 i=0; + VARIABLE_INFO *Variable; + + for(i=0; i < VariableListPtr->VariableCount; i++) + { + Variable = (VARIABLE_INFO *) ((UINT8 *)VariableInfoPtr + VariableListPtr->VariableList[i]); + if( EfiCompareGuid(VarGuid,&(Variable->VariableGuid)) )//Compare Guid + if( (EfiStrCmp(L"Setup",Variable->VariableName) ==0) || + (EfiStrCmp(L"setup",Variable->VariableName) ==0 )) + { + *Index = i; + return TRUE; + } + } + return FALSE; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _UpdateDefaults +// +// Description: Get Control Defaults +// +// Parameter: EFI_HII_HANDLE Handle, +// VOID *Data, +// UINT16 *size, +// VOID *Failsafe, +// VOID *Optimal, +// DEFAULT_VALUE **defaultValue, +// struct _CONTROL_FLAGS *Control_Flags, +// VOID *ConditionalPtr +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 _UpdateDefaults( EFI_HII_HANDLE Handle, VOID *Data, UINT16 *size, VOID **FailsafeValue, VOID **OptimalValue, DEFAULT_VALUE **defaultValue, struct _CONTROL_FLAGS *Control_Flags, VOID *ConditionalPtr) +{ + + EFI_IFR_OP_HEADER *OpHeader; + EFI_QUESTION_ID QuestionId = 0; + + EFI_IFR_ONE_OF *OneOfOp = (EFI_IFR_ONE_OF *)NULL; + EFI_IFR_ONE_OF_OPTION *OneOfOption = (EFI_IFR_ONE_OF_OPTION *)NULL; + EFI_IFR_CHECKBOX *CheckBoxOp = (EFI_IFR_CHECKBOX *)NULL; + EFI_IFR_NUMERIC *NumericOp = (EFI_IFR_NUMERIC *)NULL; + EFI_IFR_ORDERED_LIST *OrderedListOp = (EFI_IFR_ORDERED_LIST *)NULL; + EFI_IFR_PASSWORD *PasswordOp = (EFI_IFR_PASSWORD *)NULL; + EFI_IFR_ACTION *ActionOp = (EFI_IFR_ACTION *)NULL; + EFI_IFR_STRING *StringOp = (EFI_IFR_STRING *)NULL; + EFI_IFR_DEFAULT *DefaultOp = (EFI_IFR_DEFAULT *)NULL; + EFI_IFR_REF *RefOp = (EFI_IFR_REF *)NULL; + EFI_IFR_DATE *DateOp = (EFI_IFR_DATE *)NULL; + EFI_IFR_TIME *TimeOp = (EFI_IFR_TIME *)NULL; + EFI_STRING_ID varName = 0; + VARIABLE_INFO *varInfo = (VARIABLE_INFO *)NULL; + + UINT8 Flags=0, questionFlags = 0; + UINTN ScopeCount = 0; + UINT16 *varString = (UINT16 *)NULL; + int i=0; + UINT8 defaultCount = 0;//EIP: 56124 Declaration to count the defaults of the control + VOID *Failsafe = NULL; + VOID *Optimal = NULL; + UINT16 RecommandedDefaultSize=0; + UINT8 DefaultSize = 0; + + SETUP_DEBUG_UEFI( "\n[TSE] Entering _UpdateDefaults()\n"); + // Assume the default values are 64 bits or less. If the values are larger, + // we will re-allocate more space. + Failsafe = EfiLibAllocateZeroPool (sizeof (UINT64)); + if(NULL == Failsafe) + { + return 0; + } + Optimal = EfiLibAllocateZeroPool (sizeof (UINT64)); + if(NULL == Optimal) + { + MemFreePointer (Failsafe); + return 0; + } + + do + { + OpHeader = (EFI_IFR_OP_HEADER*)((UINT8*)Data + i); + switch(OpHeader->OpCode) + { + // ------ text -------------- + case EFI_IFR_TEXT_OP: //(only interactive) + break; + + // ------ ref -------------- + case EFI_IFR_REF_OP: // uses only interactive , but to signal that a key has to be passed + // back to a consumer (this behavior is not defined in TSE as of 5/20/05) + RefOp = (EFI_IFR_REF*)((UINT8*)Data + i); + + questionFlags = RefOp->Question.Flags; + break; + + // ------ one of -------------- + case EFI_IFR_ONE_OF_OP: + OneOfOp = (EFI_IFR_ONE_OF*)((UINT8*)Data + i); + + QuestionId = OneOfOp->Question.VarStoreInfo.VarOffset; + CtrlVar = _GetVarNumFromVarID(OneOfOp->Question.VarStoreId, Handle, (void *)OneOfOp); + varName = OneOfOp->Question.VarStoreInfo.VarName; + + questionFlags = OneOfOp->Question.Flags; + DefaultSize = 1 << (OneOfOp->Flags & 0x0F); //if 0, the size is 1 so adding with 1 + break; + + // ------ one of option-------------- + case EFI_IFR_ONE_OF_OPTION_OP: + OneOfOption = (EFI_IFR_ONE_OF_OPTION*)((UINT8*)Data + i); + + Flags =OneOfOption->Flags; + if((Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) + { + GetDefaultValue(OneOfOption->Type, &(OneOfOption->Value), size, Optimal,(UINT8*)Data + i); + } + + if((Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG) + { + GetDefaultValue(OneOfOption->Type, &(OneOfOption->Value), size, Failsafe,(UINT8*)Data + i); + } + + break; + + // ------ checkbox -------------- + case EFI_IFR_CHECKBOX_OP: + CheckBoxOp = (EFI_IFR_CHECKBOX*)Data; + + CtrlVar = _GetVarNumFromVarID(CheckBoxOp->Question.VarStoreId, Handle, (void *)CheckBoxOp); + QuestionId = CheckBoxOp->Question.VarStoreInfo.VarOffset; + varName = CheckBoxOp->Question.VarStoreInfo.VarName; + questionFlags = CheckBoxOp->Question.Flags; + //if(CheckBoxOp->Header.Scope == 0) EIP-80422 + //{ + Flags = CheckBoxOp->Flags ; + + //*size = sizeof(UINT8); + *(UINT8*)Optimal = (Flags & EFI_IFR_CHECKBOX_DEFAULT)? 1 : 0; + if (*(UINT8*)Optimal) + *size = sizeof(UINT8);//EIP-116566 Set size if it has default + + *(UINT8*)Failsafe = (Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG)? 1 : 0; + if (*(UINT8*)Failsafe) + *size = sizeof(UINT8);//EIP-116566 Set size if it has default + + Control_Flags->ControlRefresh = 0; + //} + DefaultSize = 1; + break; + + // ------ numeric -------------- + case EFI_IFR_NUMERIC_OP: + NumericOp = (EFI_IFR_NUMERIC*)((UINT8*)Data + i); + + Control_Flags->ControlRefresh = 0; + questionFlags = NumericOp->Question.Flags; + QuestionId = NumericOp->Question.VarStoreInfo.VarOffset; + CtrlVar = _GetVarNumFromVarID(NumericOp->Question.VarStoreId, Handle, (void *)NumericOp); + varName = NumericOp->Question.VarStoreInfo.VarName; + DefaultSize = 1 << (NumericOp->Flags & 0x0F); //if 0, the size is 1 so adding with 1 + break; + + // ------ ordered list -------------- + case EFI_IFR_ORDERED_LIST_OP: + OrderedListOp = (EFI_IFR_ORDERED_LIST*)((UINT8*)Data + i); + + QuestionId = OrderedListOp->Question.VarStoreInfo.VarOffset; + CtrlVar = _GetVarNumFromVarID(OrderedListOp->Question.VarStoreId, Handle, (void *)OrderedListOp); + varName = OrderedListOp->Question.VarStoreInfo.VarName; + questionFlags =OrderedListOp->Question.Flags; + DefaultSize = OrderedListOp->MaxContainers; + break; + + // ------ date -------------- + case EFI_IFR_DATE_OP: + DateOp = (EFI_IFR_DATE*)((UINT8*)Data + i); + + CtrlVar = _GetVarNumFromVarID(DateOp->Question.VarStoreId, Handle, (void *)DateOp); + varName = DateOp->Question.VarStoreInfo.VarName; + questionFlags =DateOp->Question.Flags; + QuestionId = DateOp->Question.VarStoreInfo.VarOffset; + if ((DateOp->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_TIME) + { + Control_Flags->ControlRefresh = DEFAULT_DATETIME_REFRESH; /**refresh*/ + } + break; + + // ------ time -------------- + case EFI_IFR_TIME_OP: + TimeOp = (EFI_IFR_TIME*)((UINT8*)Data + i); + CtrlVar = _GetVarNumFromVarID(TimeOp->Question.VarStoreId, Handle, (void *)TimeOp); + varName = TimeOp->Question.VarStoreInfo.VarName; + questionFlags =TimeOp->Question.Flags; + QuestionId = TimeOp->Question.VarStoreInfo.VarOffset; + if ((TimeOp->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_TIME) //EIP 61650 Not able to edit the normal storage time opcode + { + Control_Flags->ControlRefresh = DEFAULT_DATETIME_REFRESH; + } + //Control_Flags->ControlRefresh = DEFAULT_DATETIME_REFRESH; + break; + + // ------ string -------------- + case EFI_IFR_STRING_OP: + StringOp = (EFI_IFR_STRING*)Data; + + questionFlags = StringOp->Question.Flags; + QuestionId = StringOp->Question.VarStoreInfo.VarOffset; + CtrlVar = _GetVarNumFromVarID(StringOp->Question.VarStoreId, Handle, (void *)StringOp); + varName = StringOp->Question.VarStoreInfo.VarName; + break; + + // ------ End op -------------- + case EFI_IFR_END_OP: + if(ScopeCount) + { + ScopeCount--; + } + break; + + // ------ password-------------- + case EFI_IFR_PASSWORD_OP: + PasswordOp = (EFI_IFR_PASSWORD*)Data; + + questionFlags = PasswordOp->Question.Flags; + CtrlVar = _GetVarNumFromVarID(PasswordOp->Question.VarStoreId, Handle, (void *)PasswordOp); + QuestionId = PasswordOp->Question.VarStoreInfo.VarOffset; + varName = PasswordOp->Question.VarStoreInfo.VarName; + break; + + // ------- Action -------------- + case EFI_IFR_ACTION_OP: + ActionOp = (EFI_IFR_ACTION*)Data; + + questionFlags = ActionOp->Question.Flags; + CtrlVar = _GetVarNumFromVarID(ActionOp->Question.VarStoreId, Handle, (void *)ActionOp); + QuestionId = ActionOp->Question.VarStoreInfo.VarOffset; + // if ((questionFlags & EFI_IFR_FLAG_CALLBACK) && (Control_Flags->ControlRefresh == 0)) + + //EIP:116513 Do refresh only if AMI CALLBACK value is used. + if(ConditionalPtr != NULL) + { + if(INTERACTIVE_TEXT_VALUE == UefiTseLiteGetAmiCallbackIndex(ConditionalPtr,ActionOp )) + Control_Flags->ControlRefresh = DEFAULT_REFRESH_RATE; + } + break; + + // ------- Reset Button -------------- + case EFI_IFR_RESET_BUTTON_OP: + break; + + // ------ default -------------- + case EFI_IFR_DEFAULT_OP: + DefaultOp = (EFI_IFR_DEFAULT*)((UINT8*)Data + i); + + if(DefaultOp->Type == EFI_IFR_TYPE_BUFFER) //Update the size value for the EFI_IFR_TYPE_BUFFER + { + //Update size for the array of value stored in VALUE field excluding size for op_header, DefaultId & Type + *size = ((EFI_IFR_OP_HEADER*)DefaultOp)->Length - sizeof(EFI_IFR_OP_HEADER) - sizeof(UINT16) - sizeof(UINT8); + } + else if(DefaultOp->Type == EFI_IFR_TYPE_REF) //ifREf5 Opcode with default value, value is obtained as size of EFI_HII_REF EIP109812, 107774 + { + //buffer is of size EFI_HII_REF. + *size = sizeof(AMI_EFI_HII_REF); + } + + if(DefaultOp->Header.Scope && DefaultOp->Type > EFI_IFR_TYPE_BUFFER) + { + // retrieve default value from within scope (evaluate EFI_IFR_VALUE) + Control_Flags->ControlEvaluateDefault = TRUE; + } + else if(DefaultOp->DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) + { + // if Optimal is not large enough to hold the buffer, allocate more space for it. + if (*size > sizeof (UINT64)) { + Optimal = MemReallocateZeroPool (Optimal, sizeof (UINT64), (UINTN) *size); + } + GetDefaultValue(DefaultOp->Type, &(DefaultOp->Value), size, Optimal,(UINT8*)Data + i); + if ((0 == *size) && (DefaultOp->Type == EFI_IFR_TYPE_OTHER)) // GetDefaultValue will return 0 if need Evalutaion + Control_Flags->ControlEvaluateDefault = TRUE; + else if (DefaultSize) { + *size = DefaultSize; + } + } + else if(DefaultOp->DefaultId == EFI_IFR_OPTION_DEFAULT_MFG) + { + // if Failsafe is not large enough to hold the buffer, allocate more space for it. + if (*size > sizeof (UINT64)) { + Failsafe = MemReallocateZeroPool (Failsafe, sizeof (UINT64), (UINTN) *size); + } + GetDefaultValue(DefaultOp->Type, &(DefaultOp->Value), size, Failsafe,(UINT8*)Data + i); + if ((0 == *size) && (DefaultOp->Type == EFI_IFR_TYPE_OTHER)) + Control_Flags->ControlEvaluateDefault = TRUE; + else if (DefaultSize) { + *size = DefaultSize; + } + } + //else //EIP-124286 Commented since it will not fill Standard and above case defaults for default2 when ResetButton is pressed + { // EIp : 56124 Defautls are stored as linked list + DEFAULT_VALUE *defaults = NULL; + if(*defaultValue == NULL) + { + *defaultValue = (DEFAULT_VALUE*)EfiLibAllocateZeroPool(sizeof(DEFAULT_VALUE)); + defaults = *defaultValue; + }else + { + for(defaults = *defaultValue; defaults->Next; defaults = defaults->Next) + ; + defaults->Next = (DEFAULT_VALUE*)EfiLibAllocateZeroPool(sizeof(DEFAULT_VALUE)); + defaults = defaults->Next; + } + defaults->DefaultId = DefaultOp->DefaultId; + GetDefaultValue(DefaultOp->Type, &(DefaultOp->Value), size, &defaults->Value, (UINT8*)Data + i); + if((*size == 0 ) && (DefaultOp->Type == EFI_IFR_TYPE_OTHER)) + Control_Flags->ControlEvaluateDefault = TRUE; + else if (DefaultSize) + *size = DefaultSize; + defaultCount++; + } +// DefaultSize = 0; //If defaultstore 2 is present then changing to 0 will mal function so commented. + break; + + // ------ refresh -------------- + case EFI_IFR_REFRESH_OP: + Control_Flags->ControlRefresh = ((EFI_IFR_REFRESH*)((UINT8*)Data + i))->RefreshInterval; + // SetupData's ControlRefresh Granularity is 1/20 Sec (TSE_REFRESH_GRANURALITY) and makesure it does not cross BYTE size + Control_Flags->ControlRefresh = (UINT8)( ((Control_Flags->ControlRefresh*TSE_REFRESH_GRANURALITY) <= 0xFF)? + (Control_Flags->ControlRefresh*TSE_REFRESH_GRANURALITY): 0xFF); + break; + + // ------ refresh id -------------- + case EFI_IFR_REFRESH_ID_OP: + MemCopy( &RefreshEventGroupId, &(((AMI_EFI_IFR_REFRESH_ID *)((UINT8*)Data + i))->RefreshEventGroupId), sizeof(EFI_GUID) ); + Control_Flags->RefreshID = TRUE;//EIP-105468 + break; + + // ------ inconsistent if -------------- + case EFI_IFR_INCONSISTENT_IF_OP: + if(IsRecursive == FALSE) + { + Inconsistant = TRUE; + } + break; + //----locked-----EIP:56896 + case EFI_IFR_LOCKED_OP: + questionFlags |= EFI_IFR_FLAG_READ_ONLY; + break; + //EIP : -------------- NO_SUBMIT_IF -------------- + case EFI_IFR_NO_SUBMIT_IF_OP: + if(IsRecursive == FALSE) + { + NoSubmitIf = TRUE; + } + break; + + + default: + break; + } + + if(OpHeader->Scope) + { + ScopeCount++; + } + + i += OpHeader->Length; + }while(ScopeCount != 0); + + Control_Flags->ControlReset = (questionFlags & EFI_IFR_FLAG_RESET_REQUIRED)? 1 : 0; + Control_Flags->ControlReadOnly = (questionFlags & EFI_IFR_FLAG_READ_ONLY)? 1 : 0; + Control_Flags->ControlInteractive = (questionFlags & EFI_IFR_FLAG_CALLBACK)? 1 : 0; + + if(CtrlVar) + { + varInfo = (VARIABLE_INFO*)((UINT8 *)VariableInfoPtr + VariableListPtr->VariableList[CtrlVar]); + if(varInfo->ExtendedAttibutes) + { + varInfo->VariableNameId = varName; + varString = HiiGetString(varInfo->VariableHandle, varName); + if(varString && (EfiStrLen(varInfo->VariableName) == 0)) + { + EfiStrCpy(varInfo->VariableName, varString); + } + } + } + + *FailsafeValue = Failsafe; + *OptimalValue = Optimal; + + SETUP_DEBUG_UEFI( "\n[TSE] Exiting _UpdateDefaults()\n") ; + + return defaultCount;//EIP:56124 Returning the Default count for the control +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetValueFromOpCode +// +// Description: Gets the value from the opcode +// +// Parameter: EFI_IFR_OP_HEADER *, +// EFI_HII_VALUE *, +// INTN +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID GetValueFromOpCode (EFI_IFR_OP_HEADER *ifrData, EFI_HII_VALUE *Value, INTN Result) +{ + EFI_HII_VALUE Data1; + EFI_HII_VALUE Data2; + EFI_STATUS Status = EFI_SUCCESS; + EfiZeroMem (&Data1, sizeof (EFI_HII_VALUE)); + EfiZeroMem (&Data1, sizeof (EFI_HII_VALUE)); + EfiZeroMem (Value, sizeof (EFI_HII_VALUE)); + + switch (ifrData->OpCode) { + case EFI_IFR_EQUAL_OP: + Value->Value.b = (Result == 0) ? TRUE : FALSE; + break; + + case EFI_IFR_NOT_EQUAL_OP: + Value->Value.b = (Result != 0) ? TRUE : FALSE; + break; + + case EFI_IFR_GREATER_EQUAL_OP: + Value->Value.b = (Result >= 0) ? TRUE : FALSE; + break; + + case EFI_IFR_GREATER_THAN_OP: + Value->Value.b = (Result > 0) ? TRUE : FALSE; + break; + + case EFI_IFR_LESS_EQUAL_OP: + Value->Value.b = (Result <= 0) ? TRUE : FALSE; + break; + + case EFI_IFR_LESS_THAN_OP: + Value->Value.b = (Result < 0) ? TRUE : FALSE; + break; + case EFI_IFR_UINT8_OP: + Value->Type = EFI_IFR_TYPE_NUM_SIZE_8; + Value->Value.u8 = ((EFI_IFR_UINT8*)ifrData)->Value; + break; + case EFI_IFR_UINT16_OP: + Value->Type = EFI_IFR_TYPE_NUM_SIZE_16; + Value->Value.u16 = ((EFI_IFR_UINT16*)ifrData)->Value; + break; + case EFI_IFR_UINT32_OP: + Value->Type = EFI_IFR_TYPE_NUM_SIZE_32; + Value->Value.u32 = ((EFI_IFR_UINT32*)ifrData)->Value; + break; + case EFI_IFR_UINT64_OP: + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; + Value->Value.u64 = ((EFI_IFR_UINT64*)ifrData)->Value; + break; + case EFI_IFR_NOT_OP: + Status = PopExpression (Value); + if (EFI_ERROR (Status)) { + break; + } + if (Value->Type != EFI_IFR_TYPE_BOOLEAN) { + break; + } + Value->Value.b = !Value->Value.b; + break; + case EFI_IFR_AND_OP: + case EFI_IFR_OR_OP: + // + // Two Boolean operator + // + Status = PopExpression (&Data2); + if (EFI_ERROR (Status)) { + break; + } + if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) { + break; + } + + // + // Pop another expression from the expression stack + // + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + break; + } + if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) { + break; + } + + if (ifrData->OpCode == EFI_IFR_AND_OP) { + Value->Value.b = Data1.Value.b && Data2.Value.b; + } else { + Value->Value.b = Data1.Value.b || Data2.Value.b; + } + break; + // + // binary-op + // + case EFI_IFR_ADD_OP: + case EFI_IFR_SUBTRACT_OP: + case EFI_IFR_MULTIPLY_OP: + case EFI_IFR_DIVIDE_OP: + case EFI_IFR_MODULO_OP: + case EFI_IFR_BITWISE_AND_OP: + case EFI_IFR_BITWISE_OR_OP: + case EFI_IFR_SHIFT_LEFT_OP: + case EFI_IFR_SHIFT_RIGHT_OP: + // + // Pop an expression from the expression stack + // + Status = PopExpression (&Data2); + if (EFI_ERROR (Status)) { + break; + } + if (Data2.Type > EFI_IFR_TYPE_DATE) { + Status = EFI_INVALID_PARAMETER; + break; + } + + // + // Pop another expression from the expression stack + // + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + break; + } + if (Data1.Type > EFI_IFR_TYPE_DATE) { + break; + } + + Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; + + switch (ifrData->OpCode) { + case EFI_IFR_ADD_OP: + Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64; + break; + + case EFI_IFR_SUBTRACT_OP: + Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64; + break; + + case EFI_IFR_MULTIPLY_OP: + Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32)Data2.Value.u64); + break; + + case EFI_IFR_DIVIDE_OP: + Value->Value.u64 = AmiTseDivU64x32 (Data1.Value.u64, (UINT32)Data2.Value.u64,NULL); + break; + + case EFI_IFR_MODULO_OP: + Value->Value.u64 = 0; + AmiTseDivU64x32(Data1.Value.u64, (UINT32)Data2.Value.u64, (UINTN*)Value->Value.u64); + break; + + case EFI_IFR_BITWISE_AND_OP: + Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64; + break; + + case EFI_IFR_BITWISE_OR_OP: + Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64; + break; + + case EFI_IFR_SHIFT_LEFT_OP: + Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64); + break; + + case EFI_IFR_SHIFT_RIGHT_OP: + Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64); + break; + + default: + break; + } + + default: + Value->Type = EFI_IFR_TYPE_UNDEFINED; + break; + } +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: EvaluateReadWrite +// +// Description: Evaluates read write conditions +// +// Parameter: UINT8 *, +// CONTROL_INFO *, +// EFI_HII_VALUE * +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +EFI_STATUS GetRWVariableID (UINT16 RWVarStoreId, CONTROL_INFO *ControlInfo, UINT16 *VarStoreId); +VOID EvaluateReadWrite(UINT8 *buf, CONTROL_INFO *ControlInfo, EFI_HII_VALUE *Value1) +{ + EFI_HII_VALUE *Value=NULL; + EFI_HII_VALUE *questionValue=NULL; + EFI_IFR_TYPE_VALUE questionValue1; + UINT64 qValue=0; + EFI_HII_VALUE Data1; + EFI_HII_VALUE Data2; + EFI_HII_VALUE Data3; + EFI_IFR_OP_HEADER *ifrData = NULL; + EFI_STATUS Status; + INTN Result; + UINTN i = 0; + UINTN j = 0; + EFI_QUESTION_ID questionId = 0; + AMI_EFI_IFR_GET *IfrGet =NULL; + AMI_EFI_IFR_SET *IfrSet =NULL; + UINTN dataWidth = 0; + UINT16 Size = 0; + EFI_IFR_QUESTION_HEADER *questionHdr = NULL; + UINT64 def; + UINTN ScopeCount = 0; + + ResetExpressionStack (); + questionValue = (EFI_HII_VALUE*)EfiLibAllocateZeroPool(sizeof(EFI_HII_VALUE)); + EfiZeroMem (questionValue, sizeof (EFI_HII_VALUE)); + EfiZeroMem (&Data1, sizeof (EFI_HII_VALUE)); + EfiZeroMem (&Data2, sizeof (EFI_HII_VALUE)); + EfiZeroMem (&Data3, sizeof (EFI_HII_VALUE)); + Value = &Data3; + Value->Type = EFI_IFR_TYPE_BOOLEAN; + + ifrData = (EFI_IFR_OP_HEADER*)buf; + + do + { + if(ifrData->Scope) + { + ScopeCount++; + } + + switch(ifrData->OpCode) + { + + case EFI_IFR_THIS_OP: + Status = _GetValueFromQuestionId(ControlInfo->ControlKey, ControlInfo->ControlPageID, &questionValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + Value = questionValue; + break; + case EFI_IFR_END_OP: + if(ScopeCount) + { + ScopeCount--; + } + + goto DONE; + + case EFI_IFR_GET_OP: + { + UINT16 VarStoreId = 0; + IfrGet = (AMI_EFI_IFR_GET *)ifrData; + GetDefaultValue(IfrGet->VarStoreType,&questionValue1, &Size, &def, (UINT8 *)ifrData); + Status = GetRWVariableID (IfrGet->VarStoreId, ControlInfo, &VarStoreId); + if(EFI_ERROR(Status)) + { + goto DONE; + } + Status = VarGetValue(VarStoreId, IfrGet->VarStoreInfo.VarOffset, (( Size > sizeof(UINT64))? sizeof(UINT64) : Size ), &qValue); + if(EFI_ERROR(Status)) + { + goto DONE; + } + Value->Value.u64 = qValue; + break; + } + case EFI_IFR_SET_OP: + { + UINT16 VarStoreId = 0; + IfrSet = (AMI_EFI_IFR_SET *)ifrData; + GetDefaultValue(IfrSet->VarStoreType,&questionValue1, &Size, &def, (UINT8 *)ifrData); + Status = GetRWVariableID (IfrSet->VarStoreId, ControlInfo, &VarStoreId); + if(EFI_ERROR(Status)) + { + goto DONE; + } + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + goto DONE; + } + qValue = Data1.Value.u64; + if(Data1.Type != EFI_IFR_TYPE_UNDEFINED){ + Status = VarSetValue(VarStoreId, IfrSet->VarStoreInfo.VarOffset, (( Size > sizeof(UINT64))? sizeof(UINT64) : Size ), &qValue); + } + if(EFI_ERROR(Status)) + { + goto DONE; + } + Value->Type = Data1.Type; + Value->Value.u64 = qValue; + break; + } + case EFI_IFR_MAP_OP: + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + goto DONE; + } + i+=ifrData->Length; + ifrData = (EFI_IFR_OP_HEADER*)(buf + i); + while (ifrData->OpCode != EFI_IFR_END_OP) + { + GetValueFromOpCode(ifrData,Value,Result); + Result = CompareHiiValue (&Data1, Value,NULL); + i+=ifrData->Length; + ifrData = (EFI_IFR_OP_HEADER*)(buf + i); //Skip its pair so incrementing ifrData + if (0 == Result) + { + GetValueFromOpCode(ifrData,Value,Result); //Retreiving the value + while(ifrData->OpCode != EFI_IFR_END_OP) + { + i+=ifrData->Length; + ifrData = (EFI_IFR_OP_HEADER*)(buf + i); + } + } + else + { + i+=ifrData->Length; + ifrData = (EFI_IFR_OP_HEADER*)(buf + i); + } + } + if ((EFI_IFR_END_OP == ifrData->OpCode) && (ScopeCount)) //Since endopcode validated before itself here we decrementing scope + { + ScopeCount --; + } + break; + case EFI_IFR_CONDITIONAL_OP: + // + // Pop third expression from the expression stack + // + Status = PopExpression (&Data3); + if (EFI_ERROR (Status)) { + goto DONE; + } + + // + // Pop second expression from the expression stack + // + Status = PopExpression (&Data2); + if (EFI_ERROR (Status)) { + goto DONE; + } + + // + // Pop first expression from the expression stack + // + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + goto DONE; + } + + if (Data1.Value.b) { + Value = &Data2; + } else { + Value = &Data3; + } + break; + case EFI_IFR_EQUAL_OP: + case EFI_IFR_NOT_EQUAL_OP: + case EFI_IFR_GREATER_EQUAL_OP: + case EFI_IFR_GREATER_THAN_OP: + case EFI_IFR_LESS_EQUAL_OP: + case EFI_IFR_LESS_THAN_OP: + // + // Compare two integer, string, boolean or date/time + // + Status = PopExpression (&Data2); + if (EFI_ERROR (Status)) { + goto DONE; + } + if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + + // + // Pop another expression from the expression stack + // + Status = PopExpression (&Data1); + if (EFI_ERROR (Status)) { + goto DONE; + } + + Result = CompareHiiValue (&Data1, &Data2,NULL); + if (Result == EFI_INVALID_PARAMETER) { + Status = EFI_INVALID_PARAMETER; + goto DONE; + } + GetValueFromOpCode(ifrData,Value,Result); + break; + case EFI_IFR_UINT8_OP: + case EFI_IFR_UINT16_OP: + case EFI_IFR_UINT32_OP: + case EFI_IFR_UINT64_OP: + GetValueFromOpCode(ifrData,Value,Result); + break; + + // binary-op + + case EFI_IFR_ADD_OP: + case EFI_IFR_SUBTRACT_OP: + case EFI_IFR_MULTIPLY_OP: + case EFI_IFR_DIVIDE_OP: + case EFI_IFR_MODULO_OP: + case EFI_IFR_BITWISE_AND_OP: + case EFI_IFR_BITWISE_OR_OP: + case EFI_IFR_SHIFT_LEFT_OP: + case EFI_IFR_SHIFT_RIGHT_OP: + GetValueFromOpCode(ifrData,Value,Result); + break; + case EFI_IFR_UNDEFINED_OP: + Value1->Type = EFI_IFR_TYPE_UNDEFINED; + return; + default: + goto DONE; + break; + + } + PushExpression(Value); + DONE: + i += ((EFI_IFR_OP_HEADER*)(buf + i))->Length; + ifrData = (EFI_IFR_OP_HEADER*)(buf + i); + } while(ScopeCount); + MemFreePointer(&questionValue); + Status = PopExpression (&Data1); + if(EFI_ERROR (Status)){ + Data1.Type = EFI_IFR_TYPE_UNDEFINED; + } + MemCopy(Value1,&Data1,sizeof(EFI_HII_VALUE)); +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _AddHpkControls +// +// Description: Add Control Setup Data +// +// Parameter: +// +// Return value: UINTN +//---------------------------------------------------------------------------- +// +UINTN _AddHpkControls(EFI_HII_HANDLE Handle, UINT8 *buff,UINTN Size, PAGE_INFO **NewPageInfo, UINT32 *AllocatedPageSize, UINT32 *PageOffset) +{ + CONTROL_FLAGS control_Flags; + CONTROL_INFO *control_Info; + CONTROL_INFO *NotifyContext = (CONTROL_INFO*)NULL; + EFI_IFR_OP_HEADER *opHeader= NULL; + EFI_EVENT RefreshIdEvent = (EFI_EVENT)NULL; + EFI_IFR_OP_HEADER *opHdrPtr= (EFI_IFR_OP_HEADER *)NULL; + + + BOOLEAN addControl = TRUE; + BOOLEAN updatecondvars = TRUE; + UINT8 opCode = 0; + UINT16 controlLabel = 0; + UINT16 controlIndex = 0; + UINT16 destPageID =0xFFFF; + UINT16 controlType = 0; + UINT16 devicePathId = 0; + UINT16 helpOffset = 0; + UINT16 questionId = 0; + UINT16 opcodeNum = 0; + UINT16 defaults_size=0; + UINT16 controlKey = 0; + UINT32 controlSize = 0; + UINT32 controlOffset = 0; + INT32 ifCounter = 0; + VOID *ctrlFailSafe = NULL; + VOID *ctrlOptimal = NULL; + UINTN i =0, end=0,j=0,index=0, itr = 0; + VOID *conditionalPtr = NULL; + VOID *controlPtr = NULL; + BOOLEAN Formlock = FALSE;//EIP:56896 support for Formlock + UINT16 refQuestionId = 0; //EIP: 55762 + EFI_STATUS Status = EFI_SUCCESS; + INT32 ScopeCount = 0; + + + DEFAULT_VALUE *defaultValue = NULL, *Temp= NULL;//EIP:56214 Declaration for the Default value + + SETUP_DEBUG_UEFI("\n[TSE] Entering _AddHpkControls\n"); + + // for loop for the number of controls of this + while(i < Size ) + { + addControl = TRUE; + MemSet(&control_Flags, sizeof(CONTROL_FLAGS), 0); + control_Flags.ControlVisible =0x1; + controlType = 0; + CtrlVar = 0; + destPageID =0xFFFF; + + opHeader = (EFI_IFR_OP_HEADER*)(buff + i); + if(opHeader->Scope) + { + PushScope(opHeader->OpCode); + } + + // control type + switch(opHeader->OpCode) + { + case EFI_IFR_SUBTITLE_OP: + controlType = CONTROL_TYPE_MEMO; + break; + case EFI_IFR_TEXT_OP: + controlType = CONTROL_TYPE_TEXT; + break; + case EFI_IFR_ONE_OF_OP: + case EFI_IFR_CHECKBOX_OP: + controlType = CONTROL_TYPE_POPUPSEL; + break; + case EFI_IFR_NUMERIC_OP: + controlType = CONTROL_TYPE_NUMERIC; + break; + case EFI_IFR_PASSWORD_OP: + controlType = CONTROL_TYPE_PASSWORD; + break; + case EFI_IFR_ACTION_OP: + controlType = CONTROL_TYPE_ACTION; + break; + case EFI_IFR_MODAL_TAG_OP: //EIP-85745 Modal Support + (*NewPageInfo)->PageFlags.PageModal = 1; + break; + case EFI_IFR_RESET_BUTTON_OP: + controlType = CONTROL_TYPE_RESET; + break; + case EFI_IFR_REF_OP: + controlType = CONTROL_TYPE_SUBMENU; + destPageID = _GetPageNumFromFormID(((EFI_IFR_REF*)((char*)buff +i))->FormId); +//EIP: 55762 Start + if(opHeader->Length >= sizeof(EFI_IFR_REF2)) + { + refQuestionId = ((EFI_IFR_REF2*)((char*)buff +i))->QuestionId; + } +//EIP: 55762 End + break; + case EFI_IFR_INCONSISTENT_IF_OP: + controlType = INCONSISTENT_IF; + break; + //EIP : NO_SUBMIT_IF + case EFI_IFR_NO_SUBMIT_IF_OP: + controlType = NO_SUBMIT_IF; + break; + case EFI_IFR_RULE_OP: + controlType = CONTROL_TYPE_RULE; + conditionalPtr = (VOID *)((UINT8 *)opHeader + sizeof(EFI_IFR_RULE)); + break; + case EFI_IFR_END_OP: + PopScope(&opCode); + switch(opCode) + { + case EFI_IFR_FORM_OP: + case EFI_IFR_FORM_MAP_OP: + i += opHeader->Length; + end =1; + break; + case EFI_IFR_NO_SUBMIT_IF_OP: + case EFI_IFR_INCONSISTENT_IF_OP: + case EFI_IFR_SUPPRESS_IF_OP: + case EFI_IFR_GRAY_OUT_IF_OP: + case EFI_IFR_DISABLE_IF_OP: + controlType = --ifCounter? 0 : END_EVAL_IF; + break; + default: + controlType = 0; + break; + } + addControl = FALSE; + break; + case EFI_IFR_DATE_OP: + controlType = CONTROL_TYPE_DATE; + break; + case EFI_IFR_TIME_OP: + controlType = CONTROL_TYPE_TIME; + break; + case EFI_IFR_STRING_OP: + controlType = CONTROL_TYPE_POPUP_STRING; + break; + case EFI_IFR_SUPPRESS_IF_OP: + //case EFI_IFR_NO_SUBMIT_IF_OP: + case EFI_IFR_GRAY_OUT_IF_OP: + case EFI_IFR_DISABLE_IF_OP: + controlType = START_EVAL_IF; + addControl =FALSE; + break; + case EFI_IFR_ORDERED_LIST_OP: + controlType = CONTROL_TYPE_ORDERED_LIST; + break; + case EFI_IFR_VARSTORE_OP: + case EFI_IFR_VARSTORE_NAME_VALUE_OP: + case EFI_IFR_VARSTORE_EFI_OP: + _AddVariable((UINT8*)opHeader, Handle); + addControl =FALSE; + break; + //EIP:56896 Form lock support provided. + case EFI_IFR_LOCKED_OP: + Formlock = TRUE; + break; + default: + addControl = FALSE; + break; + } + + switch(controlType) + { + //EIP : NO_SUBMIT_IF + case NO_SUBMIT_IF: + case INCONSISTENT_IF: + case START_EVAL_IF: // IF for grayout,suppress, no submit and disable + if(updatecondvars == 1) + { + updatecondvars = 0; + conditionalPtr = (gConditionOverForm == TRUE) ? gConditionalOverFormPtr : (VOID *)opHeader; + } + ifCounter++; + break; + case END_EVAL_IF: + conditionalPtr = NULL; + updatecondvars = TRUE; + ifCounter = 0; + break; + default: + break; + } + + if(end ==1) + break; + + if(addControl) + { + defaults_size =0; + + controlKey = _GetControlKeyToken((UINT8*)opHeader); + devicePathId = _GetControlDevicePathId((UINT8*)opHeader); + helpOffset = _GetHelpToken((UINT8*)opHeader); + questionId = _GetQuestionToken((UINT8*)opHeader); + + DefaultStoreCount = _UpdateDefaults(Handle, (void *)opHeader, &defaults_size, &ctrlFailSafe, &ctrlOptimal, &defaultValue,&control_Flags, conditionalPtr); + //EIP:56896 Checking for the Formlock condition + if(Formlock) + control_Flags.ControlReadOnly = 1; + //EIP:56124 Allocating the control Size depending on the default count of the control + controlSize = sizeof(CONTROL_INFO) + defaults_size * 2+ DefaultStoreCount*(sizeof(UINT16) + defaults_size); + control_Info = EfiLibAllocateZeroPool(controlSize); + if(control_Info == NULL) + { + i = Size; + goto DONE; + } + + controlPtr = (VOID *)opHeader; + + if(controlType == INCONSISTENT_IF ) + { + controlType = CONTROL_TYPE_MSGBOX; + controlPtr = 0; + } + //EIP : NO_SUBMIT_IF + if(controlType == NO_SUBMIT_IF ) + { + controlType = NO_SUBMIT_IF; + controlPtr = 0; + } + + /* Update Control Info*/ + /* + * control_Info->ControlHandle + * HII Handle to the formset that contains this control + */ + control_Info->ControlHandle = Handle; + /* + * control_Info->ControlVariable + * Overrides the variable ID for this specific control + */ + control_Info->ControlVariable = CtrlVar; + /* + * control_Info->ControlConditionalVariable + * Conditional variable ID?s for this control + * or + * For UEFI 2.1 Use the following. + * control_Info->ControlKey + * control_Info->DefaultStoreCount + * control_Info->Reserved + */ + control_Info->ControlKey = controlKey; + control_Info->DevicePathId = devicePathId; + control_Info->DefaultStoreCount = DefaultStoreCount; + /* + * control_Info->ControlType + * Type of the control on the page + */ + control_Info->ControlType = controlType & CONTROL_TYPE_MASK; + /* + * control_Info->ControlPageID + * Page ID that contains this control + */ + control_Info->ControlPageID = PageListPtr ? (UINT16)PageListPtr->PageCount:1; + /* + * control_Info->ControlDestPageID + * Dest PageId. Only needed for controls of type CONTROL_TYPE_SUBMENU + */ + control_Info->ControlDestPageID = destPageID; + /* + * control_Info->DestQuestionID + * Question Id that will be selected refered page is visited. Only needed for controls of type CONTROL_TYPE_SUBMENU + */ + control_Info->DestQuestionID = refQuestionId; //EIP: 55762 + /* + * control_Info->ControlFlags + * Various attributes for a specific control + */ + control_Info->ControlFlags = control_Flags; + /* + * control_Info->ControlHelp + * Token for help string for this control + */ + control_Info->ControlHelp = helpOffset; + /* + * control_Info->ControlLabel + * One-based label number that this control is ?linked to? + */ + control_Info->ControlLabel = controlLabel; + /* + * control_Info->ControlIndex + * Zero-based opcode number from the last label + */ + control_Info->ControlIndex = controlIndex; + /* + * control_Info->ControlLabelCount + * Number of opcodes associated with this control's label + */ + control_Info->ControlLabelCount = opcodeNum; + /* + * control_Info->ControlPtr + * Pointer to control data in HII + */ + control_Info->ControlPtr = (VOID *)controlPtr; + /* + * control_Info->ControlConditionalPtr + * Pointer to control condition data in HII + */ + control_Info->ControlConditionalPtr = (gConditionOverForm == TRUE) ? gConditionalOverFormPtr :(VOID *)conditionalPtr; + /* + * control_Info->ControlDataLength + * Length of HII data for control + */ + control_Info->ControlDataLength = defaults_size; + /* + * control_Info->ControlDataWidth + * Width of data (in bytes) for this control + */ + control_Info->ControlDataWidth = defaults_size; + /* + * control_Info->QuestionId + * QuestionId of this control + */ + control_Info->QuestionId = questionId; + + //READ/WRTIE opcode opHeader + if((*NewPageInfo)->PageFlags.PageStdMap){ + + if (opHeader->Scope && controlType && addControl) + { + UINT32 scopeCount = 0; + BOOLEAN scoped = TRUE; + + if(opHeader->OpCode == EFI_IFR_SUBTITLE_OP) + { + EFI_IFR_OP_HEADER *nextOpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)opHeader + opHeader->Length); + if(nextOpHeader->OpCode != EFI_IFR_END_OP) + scoped = FALSE; + } + itr = 0; + while(scoped) + { + opHdrPtr = (EFI_IFR_OP_HEADER*)((UINT8*)controlPtr + itr); + switch(opHdrPtr->OpCode) + { + case EFI_IFR_READ_OP: + case EFI_IFR_WRITE_OP: + case EFI_IFR_MAP_OP: + control_Info->ControlFlags.ControlRWEvaluate = 1; + scoped = FALSE; + break; + case EFI_IFR_END_OP: + if(scopeCount) + { + scopeCount--; + } + if (!scopeCount) //Check for sudden scopeCount from previous statement + scoped = FALSE; + break; + } + if(opHdrPtr->Scope) + { + scopeCount++; + } + itr += opHdrPtr->Length ; + } + } + } + + if(defaults_size) + { + /* + * control_Info[sizeof(CONTROL_INFO)] + * Used when user selects load failsafe value + */ + + /* + * control_Info[sizeof(CONTROL_INFO) + valSize] + * Used when user selects load optimal value + */ + /* //EIP: 56124 Storing the default information by using Memcopy + MemCopy((UINT8 *)control_Info + sizeof(CONTROL_INFO), &ctrlFailSafe, defaults_size); + MemCopy((UINT8 *)control_Info + sizeof(CONTROL_INFO)+ defaults_size, &ctrlOptimal, defaults_size); + if(DefaultStoreCount) + { + index=0; + while(index < DefaultStoreCount) + { + MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &defaultValue->DefaultId, sizeof(UINT16) ); + MemCopy((UINT8 *)control_Info + sizeof(CONTROL_INFO) + (defaults_size * 2) + (index *(sizeof(UINT16) + defaults_size)) + sizeof(UINT16) , &defaultValue->Value, defaults_size ); + defaultValue = defaultValue->Next; + index++; + } + + } + + */ + Temp = defaultValue; + switch(defaults_size) + { + case 1: // BYTE + *((UINT8 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO))) = *((UINT8 *) ctrlFailSafe); + *((UINT8 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size)) = *((UINT8 *)ctrlOptimal); + if(DefaultStoreCount) + {//copy the defaults to the location in the control info + index=0; + while(index < DefaultStoreCount) + { + MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &Temp->DefaultId, sizeof(UINT16) ); + *((UINT8 *) ( (UINT8 *)control_Info + sizeof(CONTROL_INFO)+(defaults_size * 2)+(index *(sizeof(UINT16) + defaults_size))+ sizeof(UINT16) )) = (UINT8 ) (Temp->Value); + Temp = Temp->Next; + index++; + } + + } + break; + case 2: //WORD + *((UINT16 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO))) = *((UINT16 *)ctrlFailSafe); + *((UINT16 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size)) = *((UINT16 *)ctrlOptimal); + if(DefaultStoreCount) + {//copy the defaults to the location in the control info + index=0; + while(index < DefaultStoreCount) + { + MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &Temp->DefaultId, sizeof(UINT16) ); + *((UINT16 *) ( (UINT8 *)control_Info + sizeof(CONTROL_INFO)+(defaults_size * 2)+(index *(sizeof(UINT16) + defaults_size))+ sizeof(UINT16) ) )= (UINT16 ) (Temp->Value); + Temp = Temp->Next; + index++; + } + + } + break; + case 4: //DWORD + *((UINT32 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO))) = *((UINT32 *)ctrlFailSafe); + *((UINT32 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size)) = *((UINT32 *)ctrlOptimal); + if(DefaultStoreCount) + {//copy the defaults to the location in the control info + index=0; + while(index < DefaultStoreCount) + { + MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &Temp->DefaultId, sizeof(UINT16) ); + *((UINT32 *) ( (UINT8 *)control_Info + sizeof(CONTROL_INFO)+(defaults_size * 2)+(index *(sizeof(UINT16) + defaults_size))+ sizeof(UINT16) )) = (UINT32) (Temp->Value); + Temp = Temp->Next; + index++; + } + + } + break; + case 8: //QWORD + *((UINT64 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO))) = *((UINT64 *)ctrlFailSafe); + *((UINT64 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size)) = *((UINT64 *)ctrlOptimal); + if(DefaultStoreCount) + {//copy the defaults to the location in the control info + index=0; + while(index < DefaultStoreCount) + { + MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &Temp->DefaultId, sizeof(UINT16) ); + *((UINT64 *) ( (UINT8 *)control_Info + sizeof(CONTROL_INFO)+(defaults_size * 2)+(index *(sizeof(UINT16) + defaults_size))+ sizeof(UINT16) )) = (UINT64) (Temp->Value); + Temp = Temp->Next; + index++; + } + + } + break; + default: // MemCopy the value equivalent to the default buffer size + MemCopy( ((UINT8 *)control_Info + sizeof(CONTROL_INFO)) , (UINT8 *)ctrlFailSafe, defaults_size); + MemCopy( ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size) , (UINT8 *)ctrlOptimal, defaults_size); + break; + } + } + //Create group event using Refresh Id GUID + if ( control_Info->ControlFlags.RefreshID )//EIP-105468 + { + Status = CreateEventforIFR (control_Info); + if (EFI_ERROR (Status)) + { + i = Size; + goto DONE; + } + } + //EIP-148837 + /*if(IsRefreshIdSet) { + ++gRefreshIdCount; //increament the refresh id control count + NotifyContext = EfiLibAllocateZeroPool(sizeof(CONTROL_INFO)); + if(NotifyContext == NULL) + { + i = Size; + goto DONE; + } + MemCopy(NotifyContext, control_Info, sizeof(CONTROL_INFO)); + gBS->CreateEventEx ( + EFI_EVENT_NOTIFY_SIGNAL, + EFI_TPL_CALLBACK, + (EFI_EVENT_NOTIFY)RefreshGroupOnCallBack, + (void*)NotifyContext, + &RefreshEventGroupId, + &RefreshIdEvent + ); + IsRefreshIdSet = FALSE; + if(RefreshIdEvent == NULL) + { + i = Size; + goto DONE; + } + + //store the Event and Context for this control, to be freed on exiting the application. + gRefreshIdInfo = MemReallocateZeroPool(gRefreshIdInfo, sizeof(REFRESH_ID_INFO)*(gRefreshIdCount-1), sizeof(REFRESH_ID_INFO)*gRefreshIdCount); + if(gRefreshIdInfo == NULL) + { + i = Size; + goto DONE; + } + gRefreshIdInfo[gRefreshIdCount-1].pEvent = RefreshIdEvent; + gRefreshIdInfo[gRefreshIdCount-1].pNotifyContext = (UINT8*)NotifyContext; + }*/ + while(defaultValue != NULL) + { + Temp=defaultValue; + defaultValue = defaultValue->Next; + MemFreePointer(&Temp); + } + + controlOffset = AddControlToList(control_Info, controlSize); + CreatePage(NewPageInfo, AllocatedPageSize, PageOffset, &controlOffset, sizeof(UINT32)); + MemFreePointer(&control_Info); + + if (controlType & ~CONTROL_TYPE_MASK) + { + controlOffset = 0; + CreatePage(NewPageInfo, AllocatedPageSize, PageOffset, &controlOffset, sizeof(UINT32)); + } + } + + MemFreePointer (&ctrlFailSafe); + MemFreePointer (&ctrlOptimal); + j= opHeader->Length; + if (opHeader->Scope && controlType && addControl) + { + UINT32 scopeCount = 0; + BOOLEAN scoped = TRUE; + + if(opHeader->OpCode == EFI_IFR_SUBTITLE_OP) + { + EFI_IFR_OP_HEADER *nextOpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)opHeader + opHeader->Length); + if(nextOpHeader->OpCode != EFI_IFR_END_OP) + scoped = FALSE; + } + + while(scoped) + { + switch(((EFI_IFR_OP_HEADER*)(buff + i + j))->OpCode) + { + case EFI_IFR_ONE_OF_OPTION_OP: + //j += sizeof(EFI_IFR_ONE_OF_OPTION); //EIP71351 + j += ((EFI_IFR_OP_HEADER*)(buff + i + j))->Length; //Aptio giving length as 0xe(matches size of EFI_IFR_ONE_OF_OPTION) but in latest EDKII driver it is 0x1c. + break; + case EFI_IFR_END_OP: + if(scopeCount) + { + scopeCount--; + j += ((EFI_IFR_OP_HEADER*)(buff + i + j))->Length; + }else + { + scoped = FALSE; + } + break; + default: + if(((EFI_IFR_OP_HEADER*)(buff + i + j))->Scope) + { + scopeCount++; + } + j += ((EFI_IFR_OP_HEADER*)(buff + i + j))->Length; + break; + } + // Increase Control Index to account above control and final EFI_IFR_END_OP + controlIndex++; + } + } + + // + // Add Inconsistant Control for Control that have INCONSISTANT_IF embedded within + // their scope. Eg. BOOLEAN | DATE | NUMERIC | ORDERED_LIST | STRING | TIME + // + if(Inconsistant) + { + BOOLEAN BackupgConditionOverForm = FALSE; + Inconsistant = FALSE; + IsRecursive = TRUE; + BackupgConditionOverForm = gConditionOverForm; //To have the current control as condptr. If saving condition over form as condptr then it will hang + gConditionOverForm = FALSE; + _AddHpkControls(Handle, buff + i + opHeader->Length, j - opHeader->Length, + NewPageInfo, AllocatedPageSize, PageOffset); + gConditionOverForm = BackupgConditionOverForm; + IsRecursive = FALSE; + } + //EIP : NO_SUBMIT_IF + if(NoSubmitIf) + { + BOOLEAN BackupgConditionOverForm = FALSE; + NoSubmitIf = FALSE; + IsRecursive = TRUE; + BackupgConditionOverForm = gConditionOverForm; //To have the current control as condptr if has condition over form as condptr then it will hang + gConditionOverForm = FALSE; + _AddHpkControls(Handle, buff + i + opHeader->Length, j - opHeader->Length, + NewPageInfo, AllocatedPageSize, PageOffset); + gConditionOverForm = BackupgConditionOverForm; + IsRecursive = FALSE; + } + + i= i+ j; + }; +DONE: + SETUP_DEBUG_UEFI("\n[TSE] Exiting _AddHpkControls\n"); + return i; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: AddControlToList +// +// Description: +// +// Parameter: CONTROL_INFO *ControlInfo +// UINT32 ControlSize +// +// Return value: EFI_STATUS +// EFI_SUCCESS +//---------------------------------------------------------------------------- +// +UINT32 AddControlToList(CONTROL_INFO *ControlInfo, UINT32 ControlSize) +{ +// EFI_STATUS status = EFI_SUCCESS; + UINT32 offset = 0; + UINT32 u32Compensation = 0; + + SETUP_DEBUG_UEFI( "\n[TSE] Entering AddControlToList(), QuestionId: %d \n", ControlInfo->QuestionId ); + +#if TSE_DEBUG_MESSAGES + if((gDbgPrint & PRINT_UEFI_PARSE)== PRINT_UEFI_PARSE) + DebugShowControlInfo( ControlInfo->ControlPageID, ControlInfo) ; +#endif + + if(gIFRChangeNotify) + { + offset = _AdvAddControlToList(ControlInfo, ControlSize); + if(offset) + { + goto DONE; + } + } + u32Compensation = (sizeof(UINT64) - (ControlSize % sizeof(UINT64))) % sizeof(UINT64); + + if((ControlListOffset + ControlSize + u32Compensation ) >= ControlListSize) + { + //Allocate 4k at a time + gControlInfo = MemReallocateZeroPool( gControlInfo, ControlListSize, ControlListSize + 4096 ); +/* + if(gControlInfo == NULL) + { + status = EFI_OUT_OF_RESOURCES; + offset = -1; + goto DONE; + } +*/ + ControlListSize+=4096; + } + + MemCopy((UINT8 *)gControlInfo + ControlListOffset, ControlInfo, ControlSize); + offset = ControlListOffset; + ControlListOffset += (ControlSize + u32Compensation); + +DONE: + SETUP_DEBUG_UEFI( "\n[TSE] Exiting AddControlToList()\n"); + + return offset; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: AddPageIdToList +// +// Description: +// +// Parameter: PAGE_ID_INFO *NewPageIdInfo +// +// Return value: EFI_STATUS - +// EFI_SUCCESS - +// EFI_OUT_OF_RESOURCES - +//---------------------------------------------------------------------------- +// +EFI_STATUS AddPageIdToList(PAGE_ID_INFO *NewPageIdInfo) +{ + EFI_STATUS status = EFI_SUCCESS; + + UINT32 offset; + UINT32 PageIdSize = sizeof(PAGE_ID_INFO); + + SETUP_DEBUG_UEFI( "\n[TSE] Entering AddPageIdToList(), PageClass: 0x%x, PageSubClass: 0x%x,\n", NewPageIdInfo->PageClass, NewPageIdInfo->PageSubClass); + + //@VgDebug + if( PageIdInfoPtr == NULL ) + PageIdInfoOffset = PageIdInfoSize = 0; //EIP-73396 Removed (PageIdSize=0) since size is 0 the first PageInfo will not copy to PageIdInfoPtr + + if(PageIdInfoOffset + PageIdSize >= PageIdInfoSize) + { + //Allocate 4k at a time + PageIdInfoPtr = MemReallocateZeroPool( PageIdInfoPtr, PageIdInfoSize, PageIdInfoSize + 256 ); + if(PageIdInfoPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + PageIdInfoSize+=256; + } + + MemCopy((UINT8 *)PageIdInfoPtr + PageIdInfoOffset, NewPageIdInfo, PageIdSize); + offset = PageIdInfoOffset; + PageIdInfoOffset += PageIdSize; + + if(!PageIdListPtr) + { + PageIdListSize = 128; + PageIdListPtr = EfiLibAllocateZeroPool(PageIdListSize); + if(PageIdListPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + PageIdListPtr->PageIdList[PageIdListPtr->PageIdCount] = offset; + PageIdListPtr->PageIdCount = 1; + PageIdListOffset = sizeof(PAGE_ID_LIST); + } + else + { + if(PageIdListOffset + sizeof(UINT32) >= PageIdListSize) + { + PageIdListPtr = MemReallocateZeroPool(PageIdListPtr, PageIdListSize, PageIdListSize + 128); + if(PageIdInfoPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + PageIdListSize += 128; + } + PageIdListPtr->PageIdList[PageIdListPtr->PageIdCount] = offset; + PageIdListPtr->PageIdCount++; + PageIdListOffset += sizeof(UINT32); + } + +DONE: + SETUP_DEBUG_UEFI( "\n[TSE] Exiting AddPageIdToList(), status = 0x%x \n" , status ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: AddPageToList +// +// Description: +// +// Parameter: PAGE_INFO *NewPageInfo +// UINT32 PageSize +// +// Return value: EFI_STATUS +// EFI_SUCCESS +//---------------------------------------------------------------------------- +// +EFI_STATUS AddPageToList(PAGE_INFO *NewPageInfo, UINT32 PageSize) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 offset; + UINT32 ReallocSize=4096; + + SETUP_DEBUG_UEFI( "\n[TSE] Entering AddPageToList(), PageFormID: %d \n", NewPageInfo->PageFormID ); + +#if TSE_DEBUG_MESSAGES + if((gDbgPrint & PRINT_UEFI_PARSE)== PRINT_UEFI_PARSE) + DebugShowPageInfo(NewPageInfo->PageFormID, NewPageInfo) ; +#endif + + + if(gIFRChangeNotify) + { + status = _AdvAddPageToList(NewPageInfo, PageSize); + if(status == EFI_SUCCESS) + { + goto DONE; + } + status = EFI_SUCCESS;// EIP 88658 : Minisetup crashes after controller reconnection during Hii callback + } + if(PageInfoOffset + PageSize >= PageInfoSize) + { + if(ReallocSize < PageSize) + ReallocSize = (PageSize & 0xFFFFF000) + 4096; + PageInfoPtr = MemReallocateZeroPool( PageInfoPtr, PageInfoSize, PageInfoSize + ReallocSize ); //Allocate 4k at a time + if(PageInfoPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + PageInfoSize+=ReallocSize; + } + + MemCopy((UINT8 *)PageInfoPtr + PageInfoOffset, NewPageInfo, PageSize); + offset = PageInfoOffset; + PageInfoOffset += PageSize; + + if(!PageListPtr) + { + PageListSize = 512; + PageListPtr = EfiLibAllocateZeroPool(PageListSize); + if(PageListPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + /* Leave space for offset of Page 0 */ + PageListPtr->PageCount = 1; + PageListPtr->PageList[PageListPtr->PageCount] = offset; + PageListPtr->PageCount++; + PageListOffset = sizeof(PAGE_LIST)+sizeof(UINT32); + } + else + { + if(PageListOffset + sizeof(UINT32) >= PageListSize) + { + PageListPtr = MemReallocateZeroPool(PageListPtr, PageListSize, PageListSize + 128); + if(PageListPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + PageListSize += 128; + } + PageListPtr->PageList[PageListPtr->PageCount] = offset; + PageListPtr->PageCount++; + PageListOffset += sizeof(UINT32); + } + +DONE: + SETUP_DEBUG_UEFI( "\n[TSE] Exiting AddPageToList(), status = 0x%x \n" , status ) ; + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: AddVariableToList +// +// Description: +// +// Parameter: +// +// +// Return value: EFI_STATUS +// EFI_SUCCESS - +// EFI_OUT_OF_RESOURCES - +//---------------------------------------------------------------------------- +// +EFI_STATUS AddVariableToList(VARIABLE_INFO *NewVariableInfo) +{ + EFI_STATUS status = EFI_SUCCESS; + + UINT32 offset; + UINT32 VariableSize = sizeof(VARIABLE_INFO); + + SETUP_DEBUG_UEFI( "\n[TSE] Entering AddVariableToList(), VariableName: %s\n", NewVariableInfo->VariableName); + + if(VariableInfoOffset + VariableSize >= VariableInfoSize) + { + //Allocate 4k at a time + VariableInfoPtr = MemReallocateZeroPool( VariableInfoPtr, VariableInfoSize, + VariableInfoSize + 256 ); + if(VariableInfoPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + VariableInfoSize += 256; + } + + MemCopy((UINT8 *)VariableInfoPtr + VariableInfoOffset, NewVariableInfo, VariableSize); + offset = VariableInfoOffset; + VariableInfoOffset += VariableSize; + + if(!VariableListPtr) + { + VariableListSize = 128; + VariableListPtr = EfiLibAllocateZeroPool(VariableListSize); + if(VariableListPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + VariableListPtr->VariableList[VariableListPtr->VariableCount] = offset; + VariableListPtr->VariableCount = 1; + VariableListOffset = sizeof(VARIABLE_LIST); + } + else + { + if(VariableListOffset + sizeof(UINT32) >= VariableListSize) + { + VariableListPtr = MemReallocateZeroPool(VariableListPtr, VariableListSize, + VariableListSize + 128); + if(VariableListPtr == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + VariableListSize += 128; + } + VariableListPtr->VariableList[VariableListPtr->VariableCount] = offset; + gnewCtrlVar = VariableListPtr->VariableCount; + VariableListPtr->VariableCount++; + // EIP : Display Error message variable exceeds Maximum variable supported in TSE + if(VariableListPtr->VariableCount >= MAX_VARIABLE) + { + CHAR16 *Temp = L"Reached TSE Maximum supported variables"; + _DisplayErrorMessage(Temp); + ASSERT(0); + } + VariableListOffset += sizeof(UINT32); + } + +DONE: + SETUP_DEBUG_UEFI( "\n[TSE] Exiting AddVariableToList(), status = 0x%x \n" , status ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: CreatePage +// +// Description: +// +// Parameter: PAGE_INFO **PageInfo +// UINT32 *AllocatedSize +// UINT32 *Offset +// VOID *Buff +// UINT32 BuffSize +// +// Return value: EFI_STATUS +// EFI_SUCCESS - +// EFI_OUT_OF_RESOURCES - +//---------------------------------------------------------------------------- +// +EFI_STATUS CreatePage(PAGE_INFO **PageInfo, UINT32 *AllocatedSize, + UINT32 *Offset, VOID *Buff, UINT32 BuffSize) +{ + EFI_STATUS status = EFI_SUCCESS; + + SETUP_DEBUG_UEFI( "\n[TSE] Entering CreatePage()\n"); + + if(!(*AllocatedSize)) + { + //creating a new page + *PageInfo = EfiLibAllocateZeroPool(BuffSize); + if(PageInfo == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + *AllocatedSize = BuffSize; + MemCopy(*PageInfo, Buff, BuffSize); + + if((*PageInfo)->PageControls.ControlCount) + *Offset = BuffSize; + else //We have space to store one more offset + //*Offset = BuffSize - sizeof((*PageInfo)->PageControls.ControlList[0]); + *Offset = (UINT32)((UINTN)(&(*PageInfo)->PageControls.ControlList[0]) - (UINTN)(*PageInfo)); + } + else + { + //adding offsets + if(*Offset + BuffSize >= *AllocatedSize) + { + //Allocate 128 bytes at a time + *PageInfo = MemReallocateZeroPool( *PageInfo, *AllocatedSize, *AllocatedSize + 128 ); + if(PageInfo == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + *AllocatedSize+=128; + } + MemCopy((UINT8 *)(*PageInfo) + *Offset, Buff, BuffSize); + *Offset += BuffSize; + (*PageInfo)->PageControls.ControlCount++; + } + +DONE: + SETUP_DEBUG_UEFI( "\n[TSE] Exiting CreatePage(), status = 0x%x \n" , status ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: ParseForm +// +// Description: Parse the HII Package for the Form Pack and parse the FormPack +// +// Parameter: IFRPackage - The Header of the Package to parse. +// +// Return value: EFI_STATUS - Return the Status of the Parsing +//---------------------------------------------------------------------------- +// +EFI_STATUS ParseForm(SETUP_LINK *Setup_Link) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_HII_PACKAGE_HEADER *pkgHdr; + EFI_IFR_FORM_SET *formSet = NULL; + EFI_IFR_FORM *form = (EFI_IFR_FORM *)NULL; + AMI_EFI_IFR_FORM_MAP_METHOD *formMapMethod = (AMI_EFI_IFR_FORM_MAP_METHOD *) NULL; + AMI_EFI_IFR_FORM_MAP *formMap = (AMI_EFI_IFR_FORM_MAP *) NULL; + EFI_IFR_GUID_CLASS *guidClassOp; + EFI_IFR_GUID_SUBCLASS *guidSubClassOp; + EFI_IFR_OP_HEADER *opHeader; + EFI_GUID DriverHealthHiiGuid = EFI_HII_DRIVER_HEALTH_FORMSET_GUID; + EFI_GUID CredentialHiiGuid = EFI_HII_USER_CREDENTIAL_FORMSET_GUID; + extern EFI_GUID *gFSetGuid; + UINT16 FormSetTitle = 0 ; + UINT32 formOffset = 0, ifOverformCounter = 0; + UINT8 Opcode = 0; + CONTROL_INFO *control_Info; + + UINT8 opCode = 0; + UINT16 extendOpCode = 0; + UINT16 fsClass = 0; + UINT16 fsSubClass = 0; + UINT32 controlOffset = 0; + UINT32 varIndex = 0; + UINTN i = 0,formMapLength =0,formType = 0; + UINTN jIndex = 0; + + PVAR_KEY_TABLE pVarTable; + UINT32 allocatedPageSize = 0; + PAGE_INFO *tmpPgInfo; + + UINT8 *ifrData = NULL; + + SETUP_DEBUG_UEFI ( "\n[TSE] Entering ParseForm()\n" ); + + pkgHdr = (EFI_HII_PACKAGE_HEADER*)Setup_Link->FormSet; + + if(pkgHdr->Type != EFI_HII_PACKAGE_FORMS) + { + status = EFI_UNSUPPORTED; + goto DONE; + } + ifrData = ((UINT8 *)pkgHdr) + sizeof(EFI_HII_PACKAGE_HEADER); + + while(i < pkgHdr->Length) + { + opHeader = (EFI_IFR_OP_HEADER*)(ifrData + i); + + switch(opHeader->OpCode) + { + case EFI_IFR_SUPPRESS_IF_OP: + case EFI_IFR_DISABLE_IF_OP: + case EFI_IFR_GRAY_OUT_IF_OP: + if(updateformcondvars == 1)//EIP-120418 Support suppressif,grayoutif, DisableIf over form + { + updateformcondvars = 0; + gConditionOverForm = TRUE; + gConditionalOverFormPtr = (void*)opHeader; + } + PushScope(opHeader->OpCode); + ifOverformCounter++; + break; + case EFI_IFR_FORM_SET_OP: + formSet = (EFI_IFR_FORM_SET*)opHeader; + + FormSetTitle = formSet->FormSetTitle; + + if ( !ShowClassGuidFormsets( (TSE_EFI_IFR_FORM_SET*)formSet) ) //EIP-139099 If ClassGuid is matches then continue parsing to display formset + { + FormSetTitle = 0;//Clear FormSetTitle + i += (pkgHdr->Length - opHeader->Length); //Change i value to end of Pkg to skip parsing forms,etc,. + status = EFI_ABORTED; + gConditionOverForm = FALSE; + updateformcondvars = 1; + break; + } + + if ( HideDynamicFormsets(&formSet->Guid) ) //EIP-95647 Suppressing formsets mentioned in elink AMITSE_SUPPRESS_DYNAMIC_FORMSET_LIST + { + FormSetTitle = 0; + i += (pkgHdr->Length - opHeader->Length); + status = EFI_ABORTED; + gConditionOverForm = FALSE; + updateformcondvars = 1; + break; + } + + PushScope(opHeader->OpCode); + + if(_IsVarGuidPresent(&formSet->Guid, &varIndex) == FALSE) + { + varIndex = _AddFormSetVariable(&formSet->Guid); + } + + for(pVarTable = &VarKeyTable ; pVarTable->Next; pVarTable= pVarTable->Next) + ; + + pVarTable->Next = EfiLibAllocateZeroPool(sizeof(VAR_KEY_TABLE)); + if(pVarTable->Next == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + pVarTable = pVarTable->Next; + pVarTable->VarId = 0; + pVarTable->Index = (UINT16)varIndex; + + // create the pages lookup table + _InitFormsetLinks((char*)ifrData, PageListPtr ? PageListPtr->PageCount:1); + + // add NULL control above submenu in main + controlOffset = 0; + CreatePage(&FirstPage, &AllocatedFirstPageSize, &FirstPageOffset, + &controlOffset, sizeof(UINT32)); + + // add second null control for splitting the page in 2 halves + if (TotalRootPages == 7) + { + controlOffset = 0; + CreatePage(&FirstPage, &AllocatedFirstPageSize, &FirstPageOffset, + &controlOffset, sizeof(UINT32)); + } + + control_Info = (CONTROL_INFO*)EfiLibAllocateZeroPool(sizeof(CONTROL_INFO)); + if(control_Info == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + // add the submenu control to main form that points to this form. + control_Info->ControlHandle = Setup_Link->Handle; + control_Info->ControlType = CONTROL_TYPE_SUBMENU; + control_Info->ControlDestPageID = PageListPtr ? ((UINT16)PageListPtr->PageCount):1 ; + + control_Info->ControlFlags.ControlVisible = 1; + + if(!IsGroupDynamicPages()) //EIP: 59971 + control_Info->ControlPtr = (VOID*)gFirstPageRef; + +/* What is this here for? + + controlInfo->ControlPtr = (UINTN)gSetupData[HiiIndex].FormSet + + sizeof(EFI_HII_PACK_HEADER) + + sizeof(EFI_IFR_FORM_SET) + + TotalRootPages * sizeof(EFI_IFR_REF); +*/ + + controlOffset = AddControlToList(control_Info, sizeof(CONTROL_INFO)); + CreatePage(&FirstPage, &AllocatedFirstPageSize, &FirstPageOffset, + &controlOffset, sizeof(UINT32)); + MemFreePointer(&control_Info); + + TotalRootPages++; + break; + case EFI_IFR_FORM_OP: + case EFI_IFR_FORM_MAP_OP: + if(opHeader->OpCode == EFI_IFR_FORM_OP) + form = (EFI_IFR_FORM*)opHeader; + else{ + formMap =(AMI_EFI_IFR_FORM_MAP *)opHeader; + formMapMethod =(AMI_EFI_IFR_FORM_MAP_METHOD *)((UINT8 *)formMap + sizeof(AMI_EFI_IFR_FORM_MAP)); + formMapLength = sizeof(AMI_EFI_IFR_FORM_MAP); + // + // FormMap Form must contain at least one Map Method. + // + if (opHeader->Length < (formMapLength + sizeof(AMI_EFI_IFR_FORM_MAP_METHOD))) { + return EFI_INVALID_PARAMETER; + } + // + // Try to find the standard form map method. + // + while (formMapLength < opHeader->Length) { + if (EfiCompareGuid((EFI_GUID *) (VOID *) &formMapMethod->MethodIdentifier, &StandardFormGuid)) { + formType = 1; + break; + } + formMapMethod ++; + formMapLength+= sizeof(AMI_EFI_IFR_FORM_MAP_METHOD); + } + if(!formType) + formMapMethod =(AMI_EFI_IFR_FORM_MAP_METHOD *)((UINT8 *)formMap + sizeof(AMI_EFI_IFR_FORM_MAP)); + } + + tmpPgInfo = (PAGE_INFO*)EfiLibAllocateZeroPool(sizeof(PAGE_INFO)); + if(tmpPgInfo == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + allocatedPageSize = PageOffset = 0; + NewPageInfo = NULL; + + tmpPgInfo->PageFormID = (opHeader->OpCode == EFI_IFR_FORM_OP) ? form->FormId : formMap->FormId; + tmpPgInfo->PageID = PageListPtr ? (UINT16) PageListPtr->PageCount : 1; + tmpPgInfo->PageIdIndex = _GetPageIdIndex(&formSet->Guid, fsClass, fsSubClass); + tmpPgInfo->PageHandle = Setup_Link->Handle; + tmpPgInfo->PageParentID = PageListPtr ? _GetPageParent(PageListPtr->PageCount) : 0; + tmpPgInfo->PageSubTitle = (opHeader->OpCode == EFI_IFR_FORM_OP) ? form->FormTitle :formMapMethod->MethodTitle; + if(formType &&opHeader->OpCode == EFI_IFR_FORM_MAP_OP ){ + tmpPgInfo->PageFlags.PageStdMap = 1; + } + else{ + tmpPgInfo->PageFlags.PageStdMap = 0; + } + //tmpPgInfo->PageSubTitle = form->FormTitle; + + + + for (jIndex = 0; jIndex < gGuidDumpCount; jIndex ++) //EIP64253 Check for offline vfr's + { + if (EfiCompareGuid (&gGuidDump [jIndex], &formSet->Guid)) + { + break; + } + } + if (jIndex == gGuidDumpCount) //EIP64253 If offline vfr dont hide it + { + //EIP 94424 : Some form can't normal display when add Hii item will in runtime during + //EIP:68341 Support for displaying FormSet Title + if (tmpPgInfo->PageParentID == 0) + { + tmpPgInfo->PageSubTitle = FormSetTitle ; + } + //Check for Dynamic Page Flag + if (tmpPgInfo->PageParentID == 0 && IsGroupDynamicPages()) //PageParentID is 0 && SDL token is true + { + //then set as dynamic page + // if (!EfiCompareGuid (&formSet->Guid, &DriverHealthHiiGuid) || (NULL != gSfHandles)) //EIP 57661 Not to show the form with EFI_HII_DRIVER_HEALTH_FORMSET_GUID + // { + if ((NULL == gSfHandles) && (!EfiCompareGuid (&formSet->Guid, &DriverHealthHiiGuid)) && (!EfiCompareGuid (&formSet->Guid, &CredentialHiiGuid)) ) + { + tmpPgInfo->PageFlags.PageDynamic = TRUE ; + } + if ((NULL == gSfHandles) && (EfiCompareGuid (&formSet->Guid, &DriverHealthHiiGuid))) //EIP174938 if driverhealth page we have to not consider it as dynamic page so returning aborted + { //If not returning aborted then arrow will displayed + status = EFI_ABORTED; + } + // } + tmpPgInfo->PageFlags.PageVisible = TRUE; + if ( tmpPgInfo->PageFlags.PageDynamic) //EIP-151552 Title is changing to MAIN and causing crashing while navigating from dynamic page to root page + { + tmpPgInfo->PageParentID = gDynamicParentPage; + } + } + if( (tmpPgInfo->PageParentID == 0) && (NULL != gSfHandles)) + { + if ((NULL == gFSetGuid) && (!EfiCompareGuid (&formSet->Guid, &DriverHealthHiiGuid)) && (!EfiCompareGuid (&formSet->Guid, &CredentialHiiGuid)) ) + { + tmpPgInfo->PageFlags.PageVisible = FALSE; + } + else if ((NULL != gFSetGuid) && (EfiCompareGuid (&formSet->Guid, gFSetGuid))) + { + tmpPgInfo->PageFlags.PageVisible = FALSE; + } + else + tmpPgInfo->PageFlags.PageVisible = TRUE; + } + } + /* + * Add tmpPgInfo to PageInfo and PageList Structures. + * Memory for tmpPgInfo->PageControls.ControlList[0] + * will be allocated later when adding controls + */ + CreatePage(&NewPageInfo, &allocatedPageSize, &PageOffset, + tmpPgInfo, sizeof(PAGE_INFO)); + MemFreePointer(&tmpPgInfo); + + i += _AddHpkControls(Setup_Link->Handle, (UINT8*)opHeader, pkgHdr->Length - i, + &NewPageInfo, &allocatedPageSize, &PageOffset); + AddPageToList(NewPageInfo, PageOffset); + // EIP: Display Error message when Control count exceeds MAX_CONTROLS supported + if(NewPageInfo->PageControls.ControlCount >= MAX_CONTROLS) + { + CHAR16 *Temp = L"Reached TSE Maximum supported Controls"; + _DisplayErrorMessage(Temp); + ASSERT(0); + } + MemFreePointer(&NewPageInfo); + /* The Form Opcode Length is already added */ + continue; + + case EFI_IFR_GUID_OP: + extendOpCode = (UINT8)*((UINT8*)opHeader + sizeof(EFI_IFR_GUID)); + switch(extendOpCode) + { + case EFI_IFR_EXTEND_OP_LABEL: //0x0 + break; + case EFI_IFR_EXTEND_OP_BANNER: //0x1 + break; + case EFI_IFR_EXTEND_OP_TIMEOUT: //0x2 + break; + case EFI_IFR_EXTEND_OP_CLASS: //0x3 + guidClassOp = (EFI_IFR_GUID_CLASS*)opHeader; + fsClass = guidClassOp->Class; + break; + case EFI_IFR_EXTEND_OP_SUBCLASS: //0x4 + guidSubClassOp = (EFI_IFR_GUID_SUBCLASS*)opHeader; + fsSubClass = guidSubClassOp->SubClass; + break; + default: + break; + } + + break; + case EFI_IFR_VARSTORE_OP: // 0x24 + case EFI_IFR_VARSTORE_NAME_VALUE_OP: //0x25 + case EFI_IFR_VARSTORE_EFI_OP: // 0x26 + _AddVariable((UINT8*)opHeader, Setup_Link->Handle); + + break; + case EFI_IFR_DEFAULTSTORE_OP: + break; + case EFI_IFR_END_OP: + PopScope(&opCode); + if(EFI_IFR_SUPPRESS_IF_OP == opCode || EFI_IFR_GRAY_OUT_IF_OP == opCode || EFI_IFR_DISABLE_IF_OP == opCode) + { + --ifOverformCounter;//Resetting flags + gConditionOverForm = FALSE; + updateformcondvars = 1; + } + + if(opCode == EFI_IFR_FORM_SET_OP) + { + if(FSetLinks !=NULL) + { + MemFreePointer(&FSetLinks); + FSetLinks = NULL; + } + i += sizeof(EFI_HII_PACKAGE_HEADER); + } + // To match the Scoping. Don't abort the parsing. + // Suppressif in the Form level need to be supported. + /* + else0 + { + status = EFI_ABORTED; + goto DONE; + } + */ + break; + default: + if(opHeader->Scope) + PushScope(opHeader->OpCode); + break; + } + + i += opHeader->Length; + } + + _CleanVarKeyTable(); + Setup_Link->Added = 1; + +DONE: + SETUP_DEBUG_UEFI ("\n[TSE] Exiting ParseForm(), status = 0x%x \n" , status ); + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: _AdvAddControlToList +// +// Description: Add control info the control list +// +// Input: CONTROL_INFO *ControlInfo - Pointer to the CONTROL_INFO +// UINT32 ControlSize - Size the control info +// +// Output: UINT32 offset - Return the control list offset +//--------------------------------------------------------------------------- +// +UINT32 _AdvAddControlToList(CONTROL_INFO *ControlInfo, UINT32 ControlSize) +{ + CONTROL_INFO *ctrlInfo = (CONTROL_INFO*)gControlInfo; + UINT32 ctrlSize = 0; + UINT32 offset = 0; + UINT32 u32Compensation = 0; + UINT32 ctrlListOffset = 0; + + SETUP_DEBUG_UEFI( "\n[TSE] Entering _AdvAddControlToList()\n"); + + do + { + if(ctrlInfo == NULL) + { + break; //If ctrlInfo is invalid + } + + if(ctrlListOffset == ControlListOffset) + { + break; + } + + //ctrlSize = sizeof(CONTROL_INFO) + ctrlInfo->ControlDataWidth * 2; + ctrlSize = sizeof(CONTROL_INFO) + (2* ctrlInfo->ControlDataWidth) + (ctrlInfo->DefaultStoreCount * (sizeof(UINT16)+ctrlInfo->ControlDataWidth)); + if(ctrlInfo->ControlHandle == NULL && ctrlSize == ControlSize) + { + // Add the Control + MemCopy(ctrlInfo, ControlInfo, ControlSize); + offset = ctrlListOffset; + break; + } + + + // Skip to the Next Control in gControl + u32Compensation = (sizeof(UINT64) - (ctrlSize % sizeof(UINT64))) % sizeof(UINT64); + ctrlListOffset += (ctrlSize + u32Compensation); + ctrlInfo = (CONTROL_INFO *)((UINT8 *)ctrlInfo + ctrlSize + u32Compensation); + }while(TRUE); + + SETUP_DEBUG_UEFI( "\n[TSE] Exiting _AdvAddControlToList()\n"); + + return offset; +} + +VOID UpdateCtrlDestPageID(VOID * Handle, UINT16 NewPageID) +{ + UINT32 page = PARSE_START_INDEX; + UINT32 control = 0; + + for(;page < PageListPtr->PageCount; page++) + { + PAGE_INFO *pgInfo = (PAGE_INFO *)((UINT8 *)PageInfoPtr + PageListPtr->PageList[page]); + + if(pgInfo->PageHandle == Handle) + { + for(control = 0;control < pgInfo->PageControls.ControlCount; control++) + { + CONTROL_INFO *controlInfo = NULL; + + controlInfo = (CONTROL_INFO*)((UINT8 *)gControlInfo + pgInfo->PageControls.ControlList[control]); + if((NewPageID < controlInfo->ControlDestPageID) && (controlInfo->ControlDestPageID != 0xFFFF)) + { + controlInfo->ControlDestPageID--; + } + } + } + } + +} + +// +//--------------------------------------------------------------------------- +// Procedure: _AdvAddPageToList +// +// Description: Add page into to the page list +// +// Input: PAGE_INFO *NewPageInfo - Pointer to new page info structure +// UINT32 PageSize - Page into size +// +// Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS _AdvAddPageToList(PAGE_INFO *NewPageInfo, UINT32 PageSize) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 ii = 0; + UINT16 pageNo=0; + + SETUP_DEBUG_UEFI( "\n[TSE] Entering _AdvAddPageToList()\n"); + + for(ii = PARSE_START_INDEX; ii < PageListPtr->PageCount; ii++) + { + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINT8 *)PageInfoPtr + PageListPtr->PageList[ii]); + + if(pageInfo->PageHandle == (VOID *)(UINTN)0xFFFF) + { + if(pageInfo->PageFormID == NewPageInfo->PageFormID) + { + if(pageInfo->PageControls.ControlCount == NewPageInfo->PageControls.ControlCount) + { + pageNo = NewPageInfo->PageID; + pageInfo->PageHandle = NewPageInfo->PageHandle; //EIP-80424 + // Updated in old page location itself + status = _ReplacePageWithNewPage(pageInfo, NewPageInfo, PageSize); + }else + { + status = _InvalidateExistingPage(pageInfo, NewPageInfo); + status = EFI_UNSUPPORTED; + } + break; + } + } + } + + if(pageNo) + { + // Search in FSetLink for the Page and update PageID and ParentPageID + for(ii = 0; ii < FSetLinks->PageCount; ii++) + { + if(FSetLinks->PageLink[ii].FormID != NewPageInfo->PageFormID) + { + if(FSetLinks->PageLink[ii].ParentPageID == pageNo) + { + FSetLinks->PageLink[ii].ParentPageID = NewPageInfo->PageID; + } + + if(FSetLinks->PageLink[ii].PageNum > pageNo) + { + FSetLinks->PageLink[ii].PageNum--; + } + } + else + { + //FSetLinks->PageLink[ii].ParentPageID = NewPageInfo->PageParentID; + FSetLinks->PageLink[ii].PageNum = NewPageInfo->PageID; + } + + if(FSetLinks->PageLink[ii].ParentPageID > pageNo) + FSetLinks->PageLink[ii].ParentPageID--; + + } + + for(ii = PARSE_START_INDEX; ii < PageListPtr->PageCount; ii++) + { + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINT8 *)PageInfoPtr + PageListPtr->PageList[ii]); + if(pageInfo->PageHandle == NewPageInfo->PageHandle) + { + if(pageInfo->PageParentID == pageNo) + pageInfo->PageParentID = NewPageInfo->PageID; + + if(pageInfo->PageParentID > pageNo) + pageInfo->PageParentID--; + } + } + + UpdateCtrlDestPageID(NewPageInfo->PageHandle, pageNo); + } + + SETUP_DEBUG_UEFI( "\n[TSE] Exiting _AdvAddPageToList(), status = 0x%x \n" , status ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _ReplacePageWithNewPage +// +// Description: +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// +EFI_STATUS _ReplacePageWithNewPage(PAGE_INFO *OldPageInfo, PAGE_INFO *NewPageInfo, UINT32 PageSize) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 page = PARSE_START_INDEX; + UINT32 control = 0; + + SETUP_DEBUG_UEFI( "\n[TSE] Entering _ReplacePageWithNewPage()\n"); + + + // Go thru NewPageInfo CtrlList and update Control PageId + for(;control < NewPageInfo->PageControls.ControlCount; control++) + { + CONTROL_INFO *controlInfo = NULL; + + controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + NewPageInfo->PageControls.ControlList[control]); + + // Update the ControlDestPageID if it pointing to the same page. + if(controlInfo->ControlDestPageID == controlInfo->ControlPageID) + controlInfo->ControlDestPageID = OldPageInfo->PageID; + + controlInfo->ControlPageID = OldPageInfo->PageID; + } + + // Go thru all PageList with the same Handle as NewPageInfo and + // Go thru their CtrlList and Update any destination PageID that + // refers this page + for(;page < PageListPtr->PageCount; page++) + { + PAGE_INFO *pgInfo = (PAGE_INFO *)((UINT8 *)PageInfoPtr + PageListPtr->PageList[page]); + + if(pgInfo->PageHandle == NewPageInfo->PageHandle) + { + for(control = 0;control < pgInfo->PageControls.ControlCount; control++) + { + CONTROL_INFO *controlInfo = NULL; + + controlInfo = (CONTROL_INFO*)((UINT8 *)gControlInfo + pgInfo->PageControls.ControlList[control]); + if(_GetPageNumFromFormID(NewPageInfo->PageFormID) == controlInfo->ControlDestPageID) + { + controlInfo->ControlDestPageID = OldPageInfo->PageID; + } + } + + if(pgInfo->PageParentID == NewPageInfo->PageID) + pgInfo->PageParentID = OldPageInfo->PageID; + } + } + + // Update NewPageInfo PageId and ParentPageId + NewPageInfo->PageID = OldPageInfo->PageID; +// NewPageInfo->PageParentID = OldPageInfo->PageParentID; + // Copy NewPageInfo to pageInfo + MemCopy(OldPageInfo, NewPageInfo, PageSize); + + SETUP_DEBUG_UEFI( "\n[TSE] Exiting _ReplacePageWithNewPage(), status = 0x%x \n" , status ); + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _InvalidateExistingPage +// +// Description: +// +// Parameter: +// +// Return value: +//---------------------------------------------------------------------------- +// +EFI_STATUS _InvalidateExistingPage(PAGE_INFO *OldPageInfo, PAGE_INFO *NewPageInfo) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 page = 0; + + SETUP_DEBUG_UEFI( "\n[TSE] Entering _InvalidateExistingPage()\n"); + + // Search thru gPages for pages with Controls with destination page + // that refer OldPage and change them to point to NewPage + for(page = PARSE_START_INDEX; page < PageListPtr->PageCount; page++) + { + UINT32 control = 0; + PAGE_INFO *pgInfo = (PAGE_INFO *)((UINTN)PageInfoPtr + PageListPtr->PageList[page]); + + if(pgInfo->PageHandle == NewPageInfo->PageHandle) + { + for(control = 0; control < pgInfo->PageControls.ControlCount; control++) + { + CONTROL_INFO *controlInfo = NULL; + + controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pgInfo->PageControls.ControlList[control]); + if(controlInfo->ControlDestPageID == _GetPageNumFromFormID(NewPageInfo->PageFormID)) + { + controlInfo->ControlDestPageID = NewPageInfo->PageID; + } + } + } + } + //EIP: 108987 May cause circular page reference. + //NewPageInfo->PageParentID = OldPageInfo->PageParentID; + + SETUP_DEBUG_UEFI( "\n[TSE] Exiting _InvalidateExistingPage(), status = 0x%x \n" , status ) ; + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: RefreshGroupOnCallBack +// +// Description: Callback function which refreshes Controls of a Group which are +// set with refresh Id +// +// Parameter: EFI_EVENT Event, VOID *Context +// +// Return value: +//---------------------------------------------------------------------------- +// +VOID RefreshGroupOnCallBack(EFI_EVENT Event, VOID *Context) +{ + EFI_STATUS Status = EFI_SUCCESS; + CONTROL_INFO *control_Info; + UINT16 Key; + + control_Info = (CONTROL_INFO*)Context; + Key = UefiGetControlKey (control_Info); + + //refresh the control + Status = UefiRefershQuestionValueNvRAM (control_Info); + + if (UefiIsInteractive (control_Info)) + { + UefiPreControlUpdate (control_Info); + Status = CallFormCallBack (control_Info, Key, 0, AMI_CALLBACK_CONTROL_UPDATE);//EIP-53480: Updated the action to AMI_CALLBACK_CONTROL_UPDATE + } + + //check if the control is in the current page, and redraw only then. + if((Status == EFI_SUCCESS) && (control_Info->ControlPageID == gApp->CurrentPage)) + { + gApp->CompleteRedraw = TRUE; + } +} +//EIP-105468 Starts +// +//---------------------------------------------------------------------------- +// +// Procedure: CreateEventforIFR +// +// Description: To create Event if any control has RefreshID opcode +// +// +// Parameter: CONTROL_INFO* +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +//#define EFI_REFRESH_ID_GUID { 0x68a6632a, 0x5120, 0x45c3, 0x9b, 0x8e, 0xfc, 0xbf, 0x8c, 0xa0, 0xe7, 0x2e } +EFI_STATUS CreateEventforIFR (CONTROL_INFO *control_Info ) +{ + EFI_STATUS Status = EFI_SUCCESS; + CONTROL_INFO *NotifyContext = (CONTROL_INFO*)NULL; + EFI_EVENT RefreshIdEvent = (EFI_EVENT)NULL; + UINTN i = 0; + + //EFI_GUID RefreshIDGuid = EFI_REFRESH_ID_GUID; + //MemCopy( &RefreshEventGroupId, &RefreshIDGuid, sizeof(EFI_GUID) ); +// MemCopy( &RefreshEventGroupId, &(((AMI_EFI_IFR_REFRESH_ID *)control_Info->ControlPtr)->RefreshEventGroupId), sizeof(EFI_GUID) ); + //Create group event using Refresh Id GUID + + ++gRefreshIdCount; //increament the refresh id control count + NotifyContext = EfiLibAllocateZeroPool(sizeof(CONTROL_INFO)); + if(NotifyContext == NULL) + { + Status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + MemCopy(NotifyContext, control_Info, sizeof(CONTROL_INFO)); + gBS->CreateEventEx ( + EFI_EVENT_NOTIFY_SIGNAL, + EFI_TPL_CALLBACK, + (EFI_EVENT_NOTIFY)RefreshGroupOnCallBack, + (void*)NotifyContext, + &RefreshEventGroupId, + &RefreshIdEvent + ); + if(RefreshIdEvent == NULL) + { + Status = EFI_UNSUPPORTED; + goto DONE; + } + + //store the Event and Context for this control, to be freed on exiting the application. + gRefreshIdInfo = MemReallocateZeroPool(gRefreshIdInfo, sizeof(REFRESH_ID_INFO)*(gRefreshIdCount-1), sizeof(REFRESH_ID_INFO)*gRefreshIdCount); + if(gRefreshIdInfo == NULL) + { + Status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + gRefreshIdInfo[gRefreshIdCount-1].pEvent = RefreshIdEvent; + gRefreshIdInfo[gRefreshIdCount-1].pNotifyContext = (UINT8*)NotifyContext; +DONE: + return Status; +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/EDK/MiniSetup/uefi2.1/TseUefiHii.h b/EDK/MiniSetup/uefi2.1/TseUefiHii.h new file mode 100644 index 0000000..6bbc3a8 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/TseUefiHii.h @@ -0,0 +1,951 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (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/Uefi2.1/TseUefiHii.h $ +// +// $Author: Arunsb $ +// +// $Revision: 39 $ +// +// $Date: 2/11/14 8:55p $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/TseUefiHii.h $ +// +// 39 2/11/14 8:55p Arunsb +// EFI_IFR_EQ_ID_LIST_OP entry added +// +// 38 12/04/13 2:57a Premkumara +// [TAG] EIP139099 +// [Category] New Feature +// [Description] Supress formset other than +// EFI_HII_PLATFORM_SETUP_FORMSET_GUID and +// EFI_HII_DRIVER_HEALTH_FORMSET_GUID through elink based on token +// [Files] AMITSE.sdl, AMITSE.mak, CommonOem.c, Hii.c, Parse.c, +// TseUefiHii.h +// +// 37 6/10/13 12:23p Arunsb +// EIP122907 GetDefaultValue function argument added for +// EFI_IFR_TYPE_OTHER support. +// +// 36 5/22/13 11:12a Arunsb +// Build error rectified +// +// 35 4/18/13 9:37a Arunsb +// Opcodes added to avoid build error in 2.0 build. +// +// 34 4/17/13 2:12p Arunsb +// [TAG] EIP109812, 107774 +// [Category] Improvement +// [Description] Provide support for EFI_IFR_TYPE_REF and EFI_IFR_REF5 +// [Files] Hii.c, HiiCallback.c, Parse.c and TseUefiHii.h +// +// 33 4/16/13 9:49a Arunsb +// Missed out Hii headers and structures added. +// +// 32 3/29/13 12:26p 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 +// +// 31 3/29/13 8:21a Arunsb +// [TAG] EIP111061 +// [Category] Improvement +// [Description] Provide support for efivarstore opcode +// [Files] Parse.c and tseuefihii.h +// +// 30 2/25/13 10:57a Blaines +// [TAG] - EIP 104273 +// [Category] - Action Item +// [Description] - Provide ability to dump the Hii Pack from the Setup as +// part TSE debug Infrastructure. It should dump the Pack updates on Hii +// notification also. +// So it can be used to debug the issue. +// [Files] - ForBrowser2.c, Hii.c, HiiNotificationHandler.c, +// UefiWapper.c, TseUefiHii.h +// +// 29 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 10 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 27 2/02/12 3:05a Premkumara +// [TAG] EIP75066 +// [Category] Improvement +// [Description] Support loading defaults for Ordelist controls +// [Files] Ordlistbox.c, Uefi21Wapper.c, CtrlCond.c, HiiCallback.c, +// Parse.c, Uefi20Wapper.c, TseUefihiil.h +// +// 26 12/07/11 2:50p Arunsb +// [TAG] EIP75588 +// [Category] New Feature +// [Description] Support for queuing UpdatePack notifications +// [Files] frame.c, page.c, formbrowser2.c, hii.c, hiicallback.c, +// hiinotificationhandler.c, tseuefihii.h and uefi21wapper.c +// +// 25 12/01/11 7:27a Arunsb +// UefiGetValidOptionSize declaration removed. To resolce build error in +// 2.0 +// +// 24 11/28/11 5:13a Rajashakerg +// [TAG] EIP73231 +// [Category] Improvement +// [Description] Callback handling :For interactive controls updating +// the currnet vaule in cache even when hii callback returns error status. +// [Files] Date.c, SubMenu.c, ordlistbox.c, time.c, UefiAction.c, +// hii.h, uefi20Wapper.c, HiiCallback.c, TseUefiHii.h, Uefi21Wapper.c +// +// 23 11/23/11 5:17a Rajashakerg +// [TAG] EIP75473 +// [Category] Improvement +// [Description] System Time is not updated every second +// [Files] variable.h, variable.c, FormBrowser2.c, TseUefiHii.h, +// Uefi21Wapper.c, hii.h, uefi20Wapper.c +// +// 22 11/14/11 2:43p Blaines +// [TAG] - EIP 75481 +// [Category]- Function Request +// [Synopsis]- TSE debug print infrastructure. +// [Description]- Add TSE debug print info for basic functions such as +// Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms +// data. +// [Files] +// AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c +// Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c, +// HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h, +// Uefi21Wrapper.c, setupdbg.h +// +// 21 11/03/11 4:44a Premkumara +// [TAG] EIP70966 +// [Category] Improvement +// [Description] Hii orderlist item can't update priority from value in +// Setup menu for both enable and disable TSE_MULTILINE_CONTROLS token +// [Files] Ordlistbox.c, ordlistbox.h, TseUefiHii.h, Uefi21Wrapper.c +// +// 20 10/20/11 12:25p Blaines +// Correct the comments. +// +// 19 10/20/11 11:48a Blaines +// [TAG] EIP 72333 +// [Category] Sighting +// [Symptom] Some SAS controller card HII Screen Titles are displaying +// the wrong information +// [RootCause] Menu tab always displays the root page title when +// navigating submenu pages. TSE did not support the display of Formset +// Help. +// +// [Solution] Display Formset Help for Dynamic page, Display page title of +// submenu pages in the menu tab. +// +// [Files Changed] +// - AMITSE.sdl, CommonHelper.c, special.c, Menu.c, minisetupext.h, +// TseUefiHii.h, Uefi21Wapper.c +// +// 18 9/29/11 7:02p Blaines +// [TAG] - EIP 66860 +// [Category]- Function Request +// [Synopsis]- AmiPostManager interface for text entry. +// [Files] - LogoLib.h, AMIPostMgr.h, protocol.c, protocol.h, +// TseAdvanced.c, TseLitehelper.c, TseUefiHii.h, Uefi21Wapper.c +// +// 17 6/20/11 12:20p Rajashakerg +// [TAG] EIP57402 +// [Category] New Feature +// [Description] Support for EFI_IFR_DEFAULT_2 opcode. +// [Files] Hii.c, TseUefiHii.h +// +// 16 4/04/11 10:34a Arunsb +// Added macros compatible UEFI 2.3 +// +// 15 3/28/11 9:44p Premkumara +// [TAG] EIP52562 +// [Category] Improvement +// [Description] Need to have the Fixed Limit in AMITSE module for +// Controls, Pages and Variable etc. +// +// [Files] TSEUefiiHii.h, Parse.c, Hii.c, hii.c +// +// 14 3/28/11 5:10p Rajashakerg +// [TAG] EIP56413 +// [Category] Improvement +// [Description] TSE: Support for EFI_IFR_RESET_BUTTON opcode +// [Files] ezport.c, minisetupext.h, ResetButton.c, ResetButton.h, +// Hii.c, TseUefiHii.h, Uefi21Wapper.c, hii.h, Uefi20Wapper.c +// +// 13 3/21/11 1:00a Rajashakerg +// [TAG] EIP53480 +// [Category] Improvement +// [Description] FormBrowser extended actions support +// [Files] callback.c, minisetupext.c, minisetupext.h, numeric.c, +// PopupSel.c, PopupString.c, SubMenu.c, TseLiteCommon.c, UefiAction.c, +// Hiicallback.c, TseUefiHii.h, Uefi21Wapper.c, HiiCallback.c +// +// 12 3/18/11 2:52a Rajashakerg +// [TAG] EIP56124 +// [Category] New Feature +// [Description] TSE: Support for EFI_IFR_DEFAULT opcode +// [Files] Parse.c, TseUefiHii.h +// +// 11 3/09/11 7:26p Madhans +// [TAG] EIPEIP48615 +// [Category] Improvement +// [Description] To support UEFI 2.1 RefreshOp. Based in Refersh Rate +// Controls are refershed periodically. +// [Files] minisetupext.h +// SubMenu.h +// SubMenu.c +// Memo.c +// Memo.h +// numeric.c +// numeric.h +// time.c +// Date.c +// PopupSel.c +// PopupSel.h +// PopupString.c +// PopupString.h +// ordlistbox.c +// minisetupext.c +// UefiAction.c +// hii.h +// Uefi20wapper.c +// hiicallback.c +// Parse.c +// tseuefihii.h +// Uefi21wapper.c +// +// 10 2/01/11 7:38p Madhans +// [TAG] - EIP 50737 +// [Category]- Defect +// [Severity]- Mordarate +// [Symptom] - Suppressing the Interactive control does not work +// correctly. +// [RootCause] - The control conditional pointer if not set correctly. +// [Solution]- To fix the Control condition pointer. And identify the +// suppress if related to UEFI action control +// [Files] - UefiAction.c TseLiteHelper.c hii.h uefi20wapper.c +// uefi21wapper.c +// +// 9 12/28/10 12:31p Madhans +// To update the Tag of EIp 46998. UEFI option ROM menus disappear in +// Setup when certain options are selected. +// No file changed but Comment updated right +// +// 8 12/02/10 6:09p Madhans +// [TAG] - EIP49562 +// [Category]- Improvment. +// [Severity]- Mordarate +// [Symptom]- Need to support UEFI 2.2 requirements related to Calling +// Formcallback with +// EFI_BROWSER_ACTION_CHANGING and EFI_BROWSER_ACTION_CHANGED action. +// [Solution]- Implemented the support. +// [Files] - submenu.c, numeric.c, popupsel.c, popupString.c, +// uefi20\hii.h, uefi20\uefi20wrapper.c +// uefi21\hiicalback.c, uefi21\tseuefihii.h +// +// 7 10/27/10 4:25p Madhans +// [TAG] EIP46998 +// [Category] Defect +// [Symptom] Some user action on PCIx with UEFI Hii Pages causes Setup +// screen pages and menu disappers. +// [RootCause] UEFI 2.1 parsing code is not handling the Removepack and +// New pack sequance properly. Normally UpdatePack +// does the removepack and AddPack. +// [Solution] UEFI 2.1 parsing code fixed to handle above case correctly. +// [Files] hii.c HiiNotificationHandler.c Parse.c TseUefiHii.h +// uefi21wapper.c +// +// 6 9/16/10 8:38p Madhans +// Update for TSE 2.10. Refer Changelog.log for more details. +// +// 6 7/07/10 7:45p Madhans +// Changes to Support Adding Conditions to Suppress or Grayout the Special +// controls. +// +// 5 6/14/10 7:14p Madhans +// Dynamic parsing support +// +// 4 3/11/10 5:44p Madhans +// Coding Standards Update +// +// 3 2/26/10 7:01p Madhans +// To build with EDK +// +// 1 11/19/09 5:26p Presannar +// +// 2 8/11/09 3:00p Presannar +// Added Fn signature FixSetupData, HandleNewIFRPack, HandleRemoveIFRPack, +// HandleAddIFRPack, GetFormByFormID, HiiGetForm, GetDefaultValue, +// IFRChangeHandler, RegisterFormNotification, UnRegisterFormNotification +// and VarUpdateFormSetVariable +// +// 1 7/24/09 6:54p Presannar +// +// 2 4/14/09 12:39p Presannar +// Added Fn prototype FormCallBack, CallFormCallBack and +// SpecialActionCallBack +// +// 1 3/31/09 4:15p Madhans +// +// 2 1/29/09 6:09p Presannar +// Added Function Prototypes for GetControlConditionVariable and +// HiiRemoveString +// +// 1 1/09/09 2:38p Presannar +// UEFI 2.1 Hii Related Code - Initial Drop +// +// 30 9/17/08 7:44p Madhans +// For Boot only Driver file split changes. +// +// 29 3/19/08 5:39p Madhans +// Get Max line length of multiline string support for Message box +// +// 28 10/24/07 11:23a Arunkumars +// - Moved IDE security code to binary +// - Fixed build errors under UGA draw support +// - Added EFI key password support +// - Added modifier hot key support +// - Added popup support in From browser protocol +// +// 27 7/18/07 8:04a Arunkumars +// added hook for password encode and colour +// +// 26 7/09/07 1:27p Arunkumars +// - Added elink hooks for Logo, Password management and Control Keys +// customizations +// +// 25 5/22/07 9:21a Arunkumars +// Added support to dynamically parse forms that have been updated using +// UpdateForm; under SDL token for Run time Hii support +// +// 24 3/12/07 7:25p Arunkumars +// Added support to store EFI_KEYs for password. +// +// 23 8/14/06 12:38p Arunkumars +// Wide glyph support added +// +// 22 7/06/06 6:37p Arunkumars +// Include tiano.h instead of efi.h +// +// 21 6/15/06 9:34a Arunkumars +// Support to show new pages added at runtime +// +// 20 6/06/06 11:19a Madhans +// HII_VERSION Sdl Added. the token should be +// 0 - hii version older then aptio 3 version +// 1 - Aptio 3, 4 and 4.5 and Tiano 8 +// 2 - tiano 8.5 and later +// +// 19 5/26/06 12:23p Madhans +// HiiGetLinkIndex modified to check for Class, subclass and guid though +// page variable. +// +// 18 10/04/05 11:29a Stefanor +// add string & language +// started fix for fixup data on mulitple reentry +// started dynamic IFR support +// +// 17 9/02/05 1:24p Jerryp +// Added skeleton for runtime IFR processing +// +// 16 8/10/05 5:10p Franklynd +// Fixing callback protocol issue. +// +// 15 8/10/05 4:01p Franklynd +// Fixes for ading and getting new strings from HII. using a specific +// language instead of all available languages. +// +// 14 8/05/05 4:47p Jerryp +// Added form browser callback when exploding a multiple variable +// Updated to version 1.12.1027 +// +// 13 7/22/05 11:02a Jerryp +// Added code to OPTIONALLY use HII->GetDefaultImage instead of BCP +// compatible defaults +// +// 12 7/19/05 3:45p Jerryp +// Added function to change string for all languages or individual +// languages +// +// 11 5/19/05 10:29a Jerryp +// Added new HiiChangeString function +// +// 10 5/01/05 11:23a Jerryp +// Modifed HiiGetFormSet to accept a parameter +// +// 9 4/29/05 1:11p Franklynd +// Adding support for formcallback protocol to update nvram setup +// variables +// +// 8 2/07/05 2:32p Jerryp +// Removed HPK data +// +// 7 2/06/05 11:15a Jerryp +// Full hotkey support +// +// 6 2/04/05 10:30a Jerryp +// Added ability to get strings in ANY language +// +// 5 2/02/05 4:20p Jerryp +// **WORK IN PROGRESS ** +// Latest changes for Label/Index. +// Not completely tested +// +// 4 1/31/05 2:32p Jerryp +// Added HiiGetStringLength function +// +// 3 1/14/05 7:09p Jerryp +// First integration code with boot to shell. +// Still a bug in booting to shell from FV +// +// 2 1/10/05 5:16p Jerryp +// Finished sync with HII +// +// 1 1/07/05 4:30p Jerryp +// Initial checkin +// useful debugging functions and HII header +// +//************************************************************************* +// +// +// Name: TseUefiHii.h +// +// Description: +// +// +//************************************************************************* + +//--------------------------------------------------------------------------- +#ifndef _AMI_UEFI_HII_H_ // DO NOT CHANGE THIS TO _HII_H_ !! That is used by the HII Protocol header +#define _AMI_UEFI_HII_H_ +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +#include "Minisetup.h" +#include "FormBrowser2.h" +#include EFI_PROTOCOL_DEFINITION(HiiDatabase) +#include EFI_PROTOCOL_DEFINITION(HiiFont) +#include EFI_PROTOCOL_DEFINITION(HiiString) +#include EFI_PROTOCOL_DEFINITION(HiiConfigRouting) +#include EFI_PROTOCOL_DEFINITION(HiiConfigAccess) +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +#if TSE_USE_EDK_LIBRARY +#include "TianoHii.h" +#else +#include "UefiTianoHii.h" // Internal file used then EDKsupport is OFF +#endif +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +#define AMI_TIME_HOUR 1 +#define AMI_TIME_MIN 2 +#define AMI_TIME_SEC 3 +#define AMI_DATE_YEAR 4 +#define AMI_DATE_MONTH 5 +#define AMI_DATE_DAY 6 +//--------------------------------------------------------------------------- +#define TSE_REFRESH_GRANURALITY 5 +//--------------------------------------------------------------------------- +// Maximum supported page, variables, controls. +#define MAX_PAGE 246 +#define MAX_CONTROLS 0xFFFE +#define MAX_VARIABLE 300 + +#ifndef _EFI_IFR_TYPE_BUFFER +#define EFI_IFR_TYPE_BUFFER 0x0B +#endif +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +extern EFI_HII_DATABASE_PROTOCOL *gHiiDatabase; +extern EFI_HII_FONT_PROTOCOL *gHiiFont; +extern EFI_HII_STRING_PROTOCOL *gHiiString; +extern EFI_HII_CONFIG_ROUTING_PROTOCOL *gHiiConfigRouting; + +extern /*EFI_HII_HANDLE*/VOID* gHiiHandle; +extern UINTN gTitle; +extern UINTN gHelp; +extern UINTN gSubTitle; +extern UINTN gHelpTitle; +extern UINTN gNavStrings; +extern BOOLEAN gIFRChangeNotify; +extern EFI_HII_HANDLE gRemovedHandle; +//--------------------------------------------------------------------------- + + +// +//---------------------------------------------------------------------------- +// Name: EFI_HII_VALUE +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Type UINT8 +// Value EFI_IFR_TYPE_VALUE +//---------------------------------------------------------------------------- +// +typedef struct _EFI_HII_VALUE +{ + UINT8 Type; + EFI_IFR_TYPE_VALUE Value; +}EFI_HII_VALUE; + + +// +//---------------------------------------------------------------------------- +// Name: SETUP_LINK +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// FormSet UINT8* +// Handle VOID* +// ClassID UINT16 +// FormSetLength UINTN +// Added UINT8 +// SubClassID UINT16 +// ClassGuidCount UINT16 +// ClassGuid EFI_GUID* +//---------------------------------------------------------------------------- +// +typedef struct +{ + UINT8* FormSet; + VOID* Handle; + UINT16 ClassID; + UINTN FormSetLength; + UINT8 Added; //To know if this page was present in the tool data + UINT16 SubClassID; + UINT16 ClassGuidCount; + EFI_GUID* ClassGuid; +}SETUP_LINK; + +//EIP111061 +typedef struct AMI_EFI_IFR_VARSTORE_EFI { + EFI_IFR_OP_HEADER Header; + EFI_VARSTORE_ID VarStoreId; + EFI_GUID Guid; + UINT32 Attributes; + UINT16 Size; + UINT8 Name[1]; +} AMI_EFI_IFR_VARSTORE_EFI; //as per UEFI spec 2.3.1 + +//--------------------------------------------------------------------------- +EFI_IFR_FORM_SET *HiiGetFormSetFromHandle( /*EFI_HII_HANDLE*/VOID* handle ); +EFI_IFR_FORM_SET *HiiGetFormSet( UINTN index ); +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +extern VOID RTIfrProcessAddVarListAndPageIDListWrapper(VOID); +extern VOID RTIfrProcessExitWrapper(VOID); +extern VOID RTIfrProcessRunTimeFormsWrapper(EFI_IFR_REF **ref); +extern BOOLEAN RTIfrUpdateVariableInfoWrapper(UINT32 ControlVariable, EFI_HANDLE Handle); +extern BOOLEAN RTIfrProcessFormIfUpdatedWrapper(UINT16 link); +extern INTN EfiStrnCmp(IN CHAR16 *String, IN CHAR16 *String2, IN UINTN Length); +extern EFI_STATUS GetHexStringAsBuffer(UINT8 **Buffer, CHAR16 *HexStringBuffer); +extern EFI_STATUS BufferToHexString(IN OUT CHAR16 *Str, IN UINT8 *Buffer, IN UINTN BufferSize); +extern EFI_STATUS UnicodeToConfigString(IN OUT CHAR16 *ConfigString, IN OUT UINTN *StrBufferLen, IN CHAR16 *UnicodeString); +//--------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// Hii.c +// ---------------------------------------------------------------------------- +EFI_STATUS HiiExit(VOID); +EFI_STATUS HiiFixupData(); +EFI_STATUS HiiLoadDefaults( VOID **varList, UINT32 Mask ); +EFI_STATUS FixSetupData(); +EFI_STATUS HandleNewIFRPack(EFI_HANDLE Handle, UINT8 *PackData); //EIP 75588 +EFI_STATUS HandleRemoveIFRPack(EFI_HANDLE Handle); +EFI_STATUS HandleAddIFRPack(EFI_HANDLE Handle, UINT8 *PackData); +VOID* HiiFindHandle( EFI_GUID *guid, UINT16 *index ); +UINT16 HiiChangeString(VOID* handle, UINT16 token, CHAR16 *string); + +VOID *GetFormByFormID(EFI_HII_PACKAGE_HEADER *IFRData, UINT16 FormID, UINTN *Length); +VOID *HiiGetForm( EFI_HII_HANDLE Handle, UINT16 form, UINTN *Length ); + +PAGE_ID_INFO *GetPageIdInfoByIndex(PAGE_ID_INFO *PageIdInfo, UINT16 PgIndex); +//EIP:56413 Function to update the Resetbutton Defaults to the control +EFI_STATUS UefiupdateResetButtonDefault(CONTROL_INFO ControlData, UINT16 DefaultId); + //EIP: 57402 Evaluating the Control Default +UINT16 EvaluateControlDefault(CONTROL_INFO *CtrlInfo, UINT64 *Defaults); + +// ---------------------------------------------------------------------------- +// Uefi21Wrapper.c +// ---------------------------------------------------------------------------- +EFI_STATUS GetConfigHeader(VARIABLE_INFO *VariableInfo, EFI_STRING *Configuration, UINTN *Length); +EFI_STATUS ProcessActionQuestionConfiguration(CONTROL_INFO *control); +EFI_STATUS UefiGetOneOfOptions(CONTROL_INFO *CtrlInfo, VOID **Handle, UINT16 **OptionPtrTokens, + UINT64 **ValuePtrTokens, UINT16 *ItemCount, + UINT16 *Interactive, UINT16 *CallBackKey); +VOID UefiGetValidOptionType(CONTROL_INFO *CtrlInfo, UINTN *Type, UINT32 *SizeOfData); +EFI_STATUS UefiVarGetNvram(VARIABLE_INFO *VariableInfo, VOID **Buffer, UINTN Offset, UINTN Size); +EFI_STATUS UefiVarSetNvram(VARIABLE_INFO *VariableInfo, VOID *Buffer, UINTN Offset, UINTN Size); + +BOOLEAN IsPasswordEncodeEnabled(VOID *PwDataPtr); +BOOLEAN UefiIsEfiVariable(UINT32 variable, VARIABLE_INFO *varInfo); +BOOLEAN UefiIsInteractive(CONTROL_INFO *ControlData); + +UINT8 UefiGetBaseValue(VOID *IfrPtr); +UINT8 UefiGetIfrLength(VOID *IfrPtr); +UINT8 UefiGetMaxEntries(VOID *IfrPtr); + +UINT16 UefiGetControlKey(CONTROL_INFO *ControlData); +UINT16 UefiGetHelpField(VOID *IfrPtr); +UINT16 UefiGetPromptField(VOID *IfrPtr); +UINT16 UefiGetQuestionOffset(VOID *IfrPtr); +UINT16 UefiGetTextField(VOID *IfrPtr); +UINT16 UefiGetTextTwoField(VOID *IfrPtr); +UINT16 UefiGetTitleField(VOID *IfrPtr); +UINT16 UefiGetWidth(VOID *IfrPtr); +UINT8 UefiGetFlagsField(VOID *IfrPtr); + +UINT16 UefiTseLiteGetAmiCallbackIndex(VOID * Ptr,VOID * CtrlPtr); +UINT16 UefiTseLiteGetBootOverRideIndex(VOID *IfrPtr); + +UINTN HiiGetDefaultMask(VOID); +UINTN HiiGetManufactuingMask(VOID); +UINTN HiiMyGetMultiLineStringLength( /*EFI_HII_HANDLE*/VOID* handle, UINT16 token ); +UINTN HiiMyGetStringLength( /*EFI_HII_HANDLE*/VOID* handle, UINT16 token ); + +UINT64 UefiGetMaxValue(VOID *IfrPtr); +UINT64 UefiGetMinValue(VOID *IfrPtr); +UINT64 UefiGetStepValue(VOID *IfrPtr); + +VOID EfiLibSafeFreePool(IN VOID *Buffer); +VOID HiiRemoveString(EFI_HII_HANDLE Handle, UINT16 Token); +VOID UefiGetDateTimeDetails(VOID *IfrPtr,UINT8 Type,UINT16 * Help,UINT16 * Min,UINT16 * Max); +VOID UefiSetPromptField(VOID *IfrPtr,UINT16 Token); +VOID UefiSetHelpField(VOID *IfrPtr,UINT16 Token); +VOID UefiSetSubTitleField(VOID *IfrPtr,UINT16 Token); + +VOID *UefiCreateSubTitleTemplate(UINT16 Token); +VOID *UefiCreateStringTemplate(UINT16 Token); +EFI_STATUS UefiRefershQuestionValueNvRAM(CONTROL_INFO *ControlData); +UINT16 UefiGetResetButtonDefaultid(VOID *IfrPtr);//EIP:56413 Function decleration to get the Default ID +BOOLEAN CheckTimeFlags(UINT8 Flags); +BOOLEAN CheckDateFlags(UINT8 Flags); + +// ---------------------------------------------------------------------------- +// TSE Advanced +// ---------------------------------------------------------------------------- +VOID UefiAddEndOp(VOID *IfrPtr); +VOID BBSUpdateControlOffset(CONTROL_INFO *control); +VOID UefiCreateDynamicControlCondition(CONTROL_INFO *control,UINT16 VarId, UINT16 PrevControlQuestionID,UINT16 Value); +VOID UefiSetEqIDValue(VOID *IfrPtr, UINT16 Value); +VOID UefiSetEqIDQuestionID(VOID *IfrPtr, UINT16 Value); +VOID UefiSetOneOfOption(VOID *IfrPtr, UINT64 Value, UINT32 Size, UINT8 Flag, UINT16 Option); +VOID UefiSetWidth(VOID *IfrPtr,UINT8 Width); +VOID UefiSpecialGuidCallback(VOID * HiiHandle, UINT16 Key, EFI_GUID *pGUID); +VOID UefiUpdateControlVarOffset(VOID *IfrPtr, UINT16 Value); + +VOID* UefiCreateOneOfWithOptionsTemplate(UINTN OptionCount, CONTROL_INFO *CtrlInfo); +VOID* UefiGetSpecialEqIDIfrPtr(CONTROL_INFO *ControlInfo, UINT32 * Variable, GUID_INFO **GuidInfo); + +BOOLEAN UefiIsOneOfControl(VOID *IfrPtr); + +UINT16 UefiGetEqIDQuestionID(VOID *IfrPtr); +UINT16 UefiGetQuestionID(CONTROL_INFO *Control); +UINT16 UefiGetSpecialEqIDValue(CONTROL_INFO *ControlInfo, GUID_INFO **GuidInfo); + +UINT32 GetControlConditionVarId(CONTROL_INFO *controlInfo); +UINTN GetControlDataLength(CONTROL_INFO *controlInfo); + +// ---------------------------------------------------------------------------- +// Expression.c +// ---------------------------------------------------------------------------- +EFI_STATUS EvaluateExpression(IN CONTROL_INFO *ControlInfo, + IN OUT EFI_HII_VALUE *ExpressionResult, + OUT UINTN *Offset); +VOID ResetScopeStack(VOID); +EFI_STATUS PushScope(IN UINT8 Operand); +EFI_STATUS PopScope(OUT UINT8 *Operand); +BOOLEAN IsScopeStackEmpty(); +UINTN _SkipExpression(UINT8 *ControlCondPtr); +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// Parse.c +// ---------------------------------------------------------------------------- +EFI_STATUS AddPageIdToList(PAGE_ID_INFO *NewPageIdInfo); +EFI_STATUS AddPageToList(PAGE_INFO *NewPageInfo, UINT32 PageSize); +EFI_STATUS AddVariableToList(VARIABLE_INFO *NewVariableInfo); +EFI_STATUS CreatePage(PAGE_INFO **PageInfo, UINT32 *AllocatedSize, UINT32 *Offset, VOID *Buff, UINT32 BuffSize); +EFI_STATUS ParseForm(SETUP_LINK *Setup_Link); +UINT32 AddControlToList(CONTROL_INFO *ControlInfo, UINT32 ControlSize); +VOID GetDefaultValue(UINT8 Type, EFI_IFR_TYPE_VALUE *Value, UINT16 *Size, VOID *DefValue, UINT8 *TempData); +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// HiiCallBack.c +// ---------------------------------------------------------------------------- +#if TSE_DEBUG_MESSAGES +#define SETUPDATAFILENAME L"SETUPDATA_0x%x_%03d.hpk" +EFI_STATUS WritePackToFile(CHAR16 *filenameFormat, EFI_HANDLE Handle, UINT8 *PackData, UINTN length); +EFI_STATUS WriteDataToFile(CHAR16 *filename, VOID *Data, UINTN length, UINT32 index); +VOID *HiiGetPackList( EFI_HII_HANDLE Handle, UINT16 form, UINTN *Length ); +VOID ProcessPackToFile(EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, EFI_HANDLE Handle); +VOID DebugShowBufferContent(UINTN bufSize, VOID *buffer) ; +#endif //End of TSE_DEBUG_MESSAGES +EFI_STATUS FormCallBack(EFI_HII_HANDLE Handle, EFI_QUESTION_ID QuestionID, UINT8 Type, EFI_IFR_TYPE_VALUE *Value,EFI_BROWSER_ACTION action); +EFI_STATUS CallFormCallBack(CONTROL_INFO * ControlData, UINT16 Key ,UINT8 Flags,UINTN Action);//EIP-53480: Implementation of FormBrowser with actions support +EFI_STATUS SpecialActionCallBack(CONTROL_INFO * ControlData, UINT16 Key); +EFI_STATUS CallTextCallBack(TEXT_DATA *text, ACTION_DATA *Data); +VOID UefiPreControlUpdate(CONTROL_INFO *ControlData); +EFI_STATUS UefiIsProceedWithPageChange(EFI_STATUS Status); +VOID UEFICallSetupFormCallBack(UINTN Action );//EIP-53480: Decleration of the Wrapper function which calls the CallFormCallBack() +EFI_BROWSER_ACTION UefiGetActionWapper(UINTN Action);//EIP-53480 The Wrapper function to get the actual action for the driver +// ---------------------------------------------------------------------------- + +//HiiNotificationHandler.c +// ---------------------------------------------------------------------------- +EFI_STATUS +IFRChangeNotifyFn (IN UINT8 PackageType, IN CONST EFI_GUID *PackageGuid, + IN CONST EFI_HII_PACKAGE_HEADER *Package, IN EFI_HII_HANDLE Handle, + IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType); +EFI_STATUS RegisterFormNotification(EFI_HII_DATABASE_NOTIFY PackageNotifyFn, + EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, + EFI_HANDLE *NotifyHandle); +EFI_STATUS UnRegisterFormNotification(EFI_HANDLE NotifyHandle); +VOID VarUpdateFormSetVariable(); +EFI_STATUS _DisplayErrorMessage(); // EIP : 52562 To display Error message when TSE limits exceeds +// ---------------------------------------------------------------------------- + +#define AMI_FLAG_MANUFACTURING EFI_IFR_OPTION_DEFAULT_MFG +#define AMI_FLAG_DEFAULT EFI_IFR_OPTION_DEFAULT +EFI_STATUS GetBlockName(EFI_STRING *Configuration, UINTN *Length, UINTN Offset, UINTN Size); + +// ---------------------------------------------------------------------------- +// To Be removed +#define EfiCopyMem(_Destination, _Source, _Length) gBS->CopyMem ((_Destination), (_Source), (_Length)) +#define EfiZeroMem(_Destination, _Length) gBS->SetMem ((_Destination), (_Length), 0) + +//EIP:56124 Defining the Default value linked list +typedef struct _DEFAULT_VALUE +{ + UINT16 DefaultId; + UINT64 Value; + struct _DEFAULT_VALUE *Next; +}DEFAULT_VALUE; +//EIP:56124 END + +//Added for UEFI spec. 2.3 compatibility- Start +#ifndef EFI_BROWSER_ACTION_RETRIEVE +#define EFI_BROWSER_ACTION_RETRIEVE 2 +#endif +#ifndef EFI_BROWSER_ACTION_FORM_OPEN +#define EFI_BROWSER_ACTION_FORM_OPEN 3 +#endif +#ifndef EFI_BROWSER_ACTION_FORM_CLOSE +#define EFI_BROWSER_ACTION_FORM_CLOSE 4 +#endif + +#pragma pack (1) +typedef struct _AMI_EFI_IFR_REFRESH_ID { + EFI_IFR_OP_HEADER Header; + EFI_GUID RefreshEventGroupId; +} AMI_EFI_IFR_REFRESH_ID; + +#ifndef EFI_IFR_EQ_ID_LIST_OP +#define EFI_IFR_EQ_ID_LIST_OP 0x14 +#endif + +#ifndef EFI_IFR_ANIMATION_OP +#define EFI_IFR_ANIMATION_OP 0x1F +#endif + +#ifndef EFI_IFR_MAP_OP +#define EFI_IFR_MAP_OP 0x22 +#endif + +#ifndef EFI_IFR_GET_OP +#define EFI_IFR_GET_OP 0x2B +#endif + +#ifndef EFI_IFR_SET_OP +#define EFI_IFR_SET_OP 0x2C +#endif + +#ifndef EFI_IFR_READ_OP +#define EFI_IFR_READ_OP 0x2D +#endif + +#ifndef EFI_IFR_WRITE_OP +#define EFI_IFR_WRITE_OP 0x2E +#endif + +#ifndef EFI_IFR_FORM_MAP_OP +#define EFI_IFR_FORM_MAP_OP 0x5D +#endif + +#ifndef EFI_IFR_MODAL_TAG_OP +#define EFI_IFR_MODAL_TAG_OP 0x61 +#endif + +#ifndef EFI_IFR_REFRESH_ID_OP +#define EFI_IFR_REFRESH_ID_OP 0x62 +#endif + +#ifndef EFI_IFR_TYPE_UNDEFINED +#define EFI_IFR_TYPE_UNDEFINED 0x09 +#endif + +#ifndef EFI_IFR_TYPE_ACTION +#define EFI_IFR_TYPE_ACTION 0x0A +#endif + +#ifndef EFI_IFR_TYPE_REF +#define EFI_IFR_TYPE_REF 0x0C +#endif + +typedef struct _AMI_EFI_IFR_FORM_MAP_METHOD { + /// + /// The string identifier which provides the human-readable name of + /// the configuration method for this standards map form. + /// + EFI_STRING_ID MethodTitle; + /// + /// Identifier which uniquely specifies the configuration methods + /// associated with this standards map form. + /// + EFI_GUID MethodIdentifier; +} AMI_EFI_IFR_FORM_MAP_METHOD; + +typedef struct _AMI_EFI_IFR_FORM_MAP { + /// + /// The sequence that defines the type of opcode as well as the length + /// of the opcode being defined. Header.OpCode = EFI_IFR_FORM_MAP_OP. + /// + EFI_IFR_OP_HEADER Header; + /// + /// The unique identifier for this particular form. + /// + EFI_FORM_ID FormId; + /// + /// One or more configuration method's name and unique identifier. + /// + // EFI_IFR_FORM_MAP_METHOD Methods[]; +} AMI_EFI_IFR_FORM_MAP; + +typedef struct _AMI_EFI_IFR_SET { + /// + /// The sequence that defines the type of opcode as well as the length + /// of the opcode being defined. Header.OpCode = EFI_IFR_SET_OP. + /// + EFI_IFR_OP_HEADER Header; + /// + /// Specifies the identifier of a previously declared variable store to + /// use when storing the question's value. + /// + EFI_VARSTORE_ID VarStoreId; + union { + /// + /// A 16-bit Buffer Storage offset. + /// + EFI_STRING_ID VarName; + /// + /// A Name Value or EFI Variable name (VarName). + /// + UINT16 VarOffset; + } VarStoreInfo; + /// + /// Specifies the type used for storage. + /// + UINT8 VarStoreType; +} AMI_EFI_IFR_SET; + +typedef struct _AMI_EFI_IFR_GET { + /// + /// The sequence that defines the type of opcode as well as the length + /// of the opcode being defined. Header.OpCode = EFI_IFR_GET_OP. + /// + EFI_IFR_OP_HEADER Header; + /// + /// Specifies the identifier of a previously declared variable store to + /// use when retrieving the value. + /// + EFI_VARSTORE_ID VarStoreId; + union { + /// + /// A 16-bit Buffer Storage offset. + /// + EFI_STRING_ID VarName; + /// + /// A Name Value or EFI Variable name (VarName). + /// + UINT16 VarOffset; + } VarStoreInfo; + /// + /// Specifies the type used for storage. + /// + UINT8 VarStoreType; +} AMI_EFI_IFR_GET; + +//EIP109812, 107774 +typedef struct _AMI_EFI_HII_REF { + EFI_QUESTION_ID QuestionId; + EFI_FORM_ID FormId; + EFI_GUID FormSetGuid; + EFI_STRING_ID DevicePath; +} AMI_EFI_HII_REF; + +typedef struct _AMI_EFI_IFR_REF5 { + EFI_IFR_OP_HEADER Header; + EFI_IFR_QUESTION_HEADER Question; +} AMI_EFI_IFR_REF5; + +///////////////////////////////////////////////////////////////////////////////// +// +//Declaring the struct which are not present in core (UefiHii.h) +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#ifndef _TSE_EFI_IFR_FORM_SET +#define _TSE_EFI_IFR_FORM_SET +typedef struct _TSE_EFI_IFR_FORM_SET { + EFI_IFR_OP_HEADER Header; + EFI_GUID Guid; + EFI_STRING_ID FormSetTitle; + EFI_STRING_ID Help; + UINT8 Flags; + EFI_GUID ClassGuid[1]; +} TSE_EFI_IFR_FORM_SET; +#endif +#pragma pack () + +//End for UEFI spec. 2.3 compatibility +#endif /* _AMI_UEFI_HII_H_ */ +// ---------------------------------------------------------------------------- +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** \ No newline at end of file diff --git a/EDK/MiniSetup/uefi2.1/Uefi21.cif b/EDK/MiniSetup/uefi2.1/Uefi21.cif new file mode 100644 index 0000000..e026775 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/Uefi21.cif @@ -0,0 +1,21 @@ + + name = "TSE Sources - UEFI2.1" + category = ModulePart + LocalRoot = "EDK\MiniSetup\uefi2.1" + RefName = "Uefi21" +[files] +"Uefi21.sdl" +"Uefi21.mak" +"CtrlCond.c" +"CtrlCond.h" +"FormBrowser2.c" +"FormBrowser2.h" +"Expression.c" +"Hii.c" +"HiiCallback.c" +"HiiNotificationHandler.c" +"Parse.c" +"TseUefiHii.h" +"Uefi21Wapper.c" +"UefiTianoHii.h" + diff --git a/EDK/MiniSetup/uefi2.1/Uefi21.mak b/EDK/MiniSetup/uefi2.1/Uefi21.mak new file mode 100644 index 0000000..d038c9d --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/Uefi21.mak @@ -0,0 +1,134 @@ +##*****************************************************************## +##*****************************************************************## +##*****************************************************************## +##** **## +##** C)Copyright 1985-2010, 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/Uefi2.1/Uefi21.mak $ +## +## $Author: Arunsb $ +## +## $Revision: 8 $ +## +## $Date: 10/18/12 6:04a $ +## +##*****************************************************************## +##*****************************************************************## +## Revision History +## ---------------- +## $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/Uefi21.mak $ +# +# 8 10/18/12 6:04a Arunsb +# Updated for 2.16.1235 QA submission +## +## 6 10/10/12 12:41p Arunsb +## Synched the source for v2.16.1232, backup with Aptio +# +# 7 3/29/11 1:26p Madhans +# To remove /Od Option. It is not needed. +# +# 6 10/14/10 5:07p Madhans +# +# 5 4/23/10 6:12p Madhans +# +# 4 4/16/10 5:13p Madhans +# Changes for Tse 2.02. Please see Changelog.log for more details. +# +# 3 2/19/10 8:50p Madhans +## +## 2 11/19/09 5:39p Presannar +## Include Path to CORE to be compatible with existing Implementation. To +## be removed in the Next release label +## +## 1 7/24/09 6:54p Presannar +## +## 3 4/24/09 7:54p Presannar +## TSE 2.0 UEFI 2.1 Code Complete +## +## 2 3/31/09 4:15p Madhans +## UEFI Wrapper improvments. +## +## 1 1/09/09 2:38p Presannar +## UEFI 2.1 Hii Related Code - Initial Drop +## +## +##*****************************************************************## +##************************************************************************* +## +## +## Name: Uefi21.mak +## +## Description: +## +## +##************************************************************************* + +# MAK file for the eModule:UEFI2.1 + +Uefi21_INCLUDES = \ + -I $(TSESRC_DIR) \ + -I $(TSE_STYLE_DIR) \ + -I $(TSESRC_DIR)\AMILOGO \ + -I $(TSELITESRC_DIR) \ + -I $(UEFISRC_DIR) \ + -I $(TSEBIN_DIR) \ + -I $(TSEBIN_DIR)\Inc \ +!if "$(TSE_BOARD_SOURCE_SUPPORT)" == "1" + -I $(TSE_BOARD_DIR)\ +!endif + -I $(PROJECT_DIR)\Include\Protocol \ + -I $(PROJECT_DIR) \ + -I $(PROJECT_DIR)\Include \ + -I $(BUILD_DIR) \ +!if "$(TSE_USE_EDK_LIBRARY)" == "1" + -I $(EDK_SOURCE)\Foundation\Library\Dxe\UefiEfiIfrSupportLib \ +!endif +!if "$(TSE_USE_EDK_LIBRARY)" != "1" + -I $(PROJECT_DIR)\Core \ +!endif + +!if "$(TSE_USE_EDK_LIBRARY)" == "1" +TSE_DEFAULTS = $(EDK_DEFAULTS) +!else +TSE_DEFAULTS = $(BUILD_DEFAULTS) +!endif + +$(BUILD_DIR)\Uefi21Local.lib : Uefi21Lib + +Uefi21Lib : $(BUILD_DIR)\Uefi21.mak Uefi21LibBin + +$(BUILD_DIR)\Uefi21.mak : $(UEFISRC_DIR)\$(@B).cif $(UEFISRC_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(UEFISRC_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +Uefi21LibBin : + $(MAKE) /$(MAKEFLAGS) $(TSE_DEFAULTS)\ + /f $(BUILD_DIR)\Uefi21.mak all\ + "MY_INCLUDES=$(Uefi21_INCLUDES)"\ + "UNI_INCLUDE_PATH=$(TSEBIN_DIR)"\ + TYPE=LIBRARY \ + "EXT_HEADERS=$(BUILD_DIR)\token.h"\ + LIBRARY_NAME=$(BUILD_DIR)\Uefi21Local.lib\ + "CFLAGS=$(CFLAGS) /DTSE_FOR_APTIO_4_50" + +##*****************************************************************## +##*****************************************************************## +##** **## +##** C)Copyright 1985-2010, American Megatrends, Inc. **## +##** **## +##** All Rights Reserved. **## +##** **## +##** 6145-F Northbelt Pkwy, Norcross, GA 30071 **## +##** **## +##** Phone (770)-246-8600 **## +##** **## +##*****************************************************************## +##*****************************************************************## diff --git a/EDK/MiniSetup/uefi2.1/Uefi21.sdl b/EDK/MiniSetup/uefi2.1/Uefi21.sdl new file mode 100644 index 0000000..be933fb --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/Uefi21.sdl @@ -0,0 +1,71 @@ +TOKEN + Name = "UEFI_HII_2_1_SUPPORT" + Value = "1" + Help = "Main switch to enable UEFI 2.1 sources support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes + Master = Yes + Token = "EFI_SPECIFICATION_VERSION" ">" "0x20000" +End + +TOKEN + Name = "UEFI_SOURCES_SUPPORT" + Value = "1" + Help = "Don't Edit." + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "UEFI_2_1_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "TSE_SUPPORT_VFRCOMPILE_1_88" + Value = "0" + Help = "Turn on to support vfrcompiler version 1.88 and later" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "TianoHII_SUPPORT" + Value = "1" + Help = "Switch to enable Tiano defined HII support in Project. Turn on for form support with class,subclass. If Core changes to use just Form Guid This can be turned off" + TokenType = Boolean + TargetMAK = Yes + TargetH = Yes +End + +TOKEN + Name = "SETUP_FORM_BROWSER_SUPPORT" + Value = "1" + Help = "1 => Installs form browser protocol should turn on SETUP_RUNTIME_IFR_PROCESSING. 0 => Does not install form browser protocol." + TokenType = Boolean + TargetH = Yes + Token = "SETUP_RUNTIME_IFR_PROCESSING" "=" "1" +End + +PATH + Name = "UEFISRC_DIR" +End + +MODULE + Help = "Includes Uefi21.mak to Project" + File = "Uefi21.mak" +End + +ELINK + Name = "$(BUILD_DIR)\Uefi21Local.lib" + Parent = "$(UEFISRC_DIR)\Uefi21Local$(ARCH).lib" + InvokeOrder = ReplaceParent +End + diff --git a/EDK/MiniSetup/uefi2.1/Uefi21Wapper.c b/EDK/MiniSetup/uefi2.1/Uefi21Wapper.c new file mode 100644 index 0000000..eab9ad5 --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/Uefi21Wapper.c @@ -0,0 +1,8266 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (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/Uefi2.1/Uefi21Wapper.c $ +// +// $Author: Premkumara $ +// +// $Revision: 85 $ +// +// $Date: 8/28/14 11:54a $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/Uefi21Wapper.c $ +// +// 85 8/28/14 11:54a Premkumara +// [TAG] EIP174031 +// [Category] Improvement +// [Description] Removed TODO comments and added proper comments in those +// places +// [Files] commonoem.c, commonhelper.c, special.c, submenu.c, +// minisetupext.c, uefi21wapper.c and legacy.c +// +// 84 8/28/14 9:56a Premkumara +// [TAG] EIP173038 +// [Category] Bug Fix +// [Symptom:] System hangs on using UefiVarsetnvramforCurrentform +// [Root Cause] UINT32 gProcessedForms[MAX_FORMS_TO_PROCESS]; +// Entries overbound the arrary MAX_FORMS_TO_PROCESS +// [Solution] gProcessedForms formed dynamically +// [Files] Uefi21wapper.c +// +// 83 7/12/14 12:25p Arunsb +// [TAG] EIP174938 +// [Category] Bug Fix +// [Severity:] Normal +// [Symptom:] Arrow mark shown when driver health page published +// [Root Cause] Driver health formset considered as dynamic page so arrow +// shown +// [Solution] For driverhealth formset DynamicPageCount variable not +// incremented. Returned EFI_ABORTED in parseform for driverhealth formset +// so DynamicPageCount not incremented so arrow will not be shown. +// [Files] Parse.c and uefi21wapper.c +// +// 82 5/21/14 6:33p Arunsb +// [TAG] EIPEIP169096,168632 +// [Description] Changed global variable guid usage for tse debug +// messages. Removed unwanted RT flag in TSE. +// [Files] commonoem.c, setupdbg.h, print.c and uefi21wapper.c +// +// 81 5/02/14 5:02a Arunsb +// [TAG] EIP156958 +// [Category] Bug Fix +// [Severity:] Normal +// [Symptom:] UefiVarsetnvramforCurrentform function not saving the values +// properly for passed page ID +// [Root Cause] This function calling VarSetNvram to update the NVRAM, +// this function updates the offset value to NVRAM and then got the whole +// buffer from NVRAM again and updates the cache so second controls and +// further modified controls cache values are overwritten by NVRAM value. +// [Solution] Instead of calling VarSetNvram set the values in +// UefiVarsetnvramforCurrentform fnc itself. +// [Files] uefi21wapper.c +// +// 80 2/11/14 8:57p Arunsb +// [TAG] EIP133728 +// [Category] New Feature +// [Description] Provide special control support in ESA for driver health +// [Files] uefi21wapper.c +// +// 79 10/18/13 4:20p Arunsb +// [TAG] EIP140268 +// [Category] Bug Fix +// [Severity:] Normal +// [Symptom:] Clicking driver health control crashes +// [Root Cause] Incremented pointer freed instead of allocated pointer +// [Solution] Pointer freed properly +// [Files] uefi21wapper.c +// +// 78 8/26/13 3:10p Blaines +// [TAG] - EIP 134138 +// [Category] - Defect +// [Symptom] - Incorrect Driver Health name shown in BIOS (UEFI Mode) +// Setup for SAS Card. +// +// [Root cause] +// In the function FindDriverHealthDriverName,when querying the +// GetDriverName() routine of Component Name Protocol, the function is +// passing more than one language. +// +// [Solution]- +// In the function FindDriverHealthDriverName,when querying the +// GetDriverName() routine of Component Name Protocol, pass only one +// language to the routine. +// +// [Files] +// Uefi21Wapper.c +// +// 77 7/01/13 10:47a Premkumara +// [TAG] EIP126997 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] Selecting Save current form Now or Discard Current form and +// Exit now controls causing setup crash +// [RootCause] NULL is not handled properly for controls->controlPtr +// [Solution] Handled NULL check properly in necessary places +// [Files] Uefi21Wapper.c +// +// 76 5/22/13 11:18a Arunsb +// Name value string not saving properly. Fixed it. +// +// 75 4/18/13 9:39a Arunsb +// Functions moved to avoid build error in 2.0 build +// +// 74 4/16/13 9:20a Arunsb +// Build error corrected +// +// 73 4/16/13 8:01a Arunsb +// [TAG] EIP106950 +// [Category] New Feature +// [Description] PasswordEncode hook function +// +// 72 3/29/13 12:30p 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 +// +// 71 3/25/13 8:31a Premkumara +// [TAG] EIP116315 +// [Category] Improvement +// [Description] Display control prompt string for password control. +// (for String on CHAP secret popup) +// [Files] - AMITSE.sdl +// - CommonHelper.c +// - FakeToken.c +// - AmiTSEStr.uni +// - TseLite\PopupPassword.c +// - uefi2.1\UefiWapper21.c +// - uefi2.0\HiiCallback.c +// - uefi2.0\hii.h +// - uefi2.0\hii.c +// +// 70 2/25/13 10:57a Blaines +// [TAG] - EIP 104273 +// [Category] - Action Item +// [Description] - Provide ability to dump the Hii Pack from the Setup as +// part TSE debug Infrastructure. It should dump the Pack updates on Hii +// notification also. +// So it can be used to debug the issue. +// [Files] - ForBrowser2.c, Hii.c, HiiNotificationHandler.c, +// UefiWapper.c, TseUefiHii.h +// +// 69 12/05/12 4:51a Premkumara +// [TAG] EIP105552 +// [Category] Improvement +// [Description] Adding RefreshID support for OrderList, Password +// controls +// [Files] Uefi21Wapper.c +// +// 68 10/18/12 8:56a Rajashakerg +// [TAG] EIP103568 +// [Category] Improvement +// [Description] Help string support for ordered list +// [Files] Uefi21Wapper.c, ordlistbox.c +// +// 67 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 24 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 65 9/18/12 2:15a Rajashakerg +// [TAG] EIP88658 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Minisetup crashes after controller reconnection during Hii +// callback +// [RootCause] Minisetup crashes after controller reconnection during +// callback. since we have new packs and new handles. +// [Solution] Additional checks for invalid ptrs were added +// [Files] Hii.c, Parse.c, Uefi21Wapper.c +// +// 64 9/17/12 6:22a Rajashakerg +// Updated EIP changes for 2.16 release. +// +// 62 9/10/12 11:46a Arunsb +// [TAG] EIP90372 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Setup browser handling of +// EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD +// [RootCause] For discard action current value is saved +// [Solution] Introduced a global variable which will set for discard +// action for that current value will not be saved +// [Files] HiiCallback.c and Uefi21Wapper.c +// +// 61 5/29/12 4:46a Arunsb +// [TAG] EIP91109 +// [Category] Improvement +// [Description] Sync the Aptio IV source for AptioV +// +// 60 5/28/12 12:38p Arunsb +// [TAG] EIP86885 +// [Category] Improvement +// [Description] Support added for following callback action requests +// EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT +// EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT +// EFI_BROWSER_ACTION_REQUEST_FORM_APPLY +// EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD +// [Files] Uefi21Wapper.c +// +// 59 4/27/12 1:39a Rajashakerg +// [TAG] EIP74964 +// [Category] Improvement +// [Description] UefiGetDateTimeDetails does not initialize the min and +// max values +// [Files] Uefi21Wapper.c +// +// 58 4/05/12 12:49p Arunsb +// [TAG] EIP83252 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] System hangs with onboard SAS Option ROM +// [RootCause] ProcessPackNotification not invoked properly +// [Solution] gEnableDrvNotification flag handled properly to invoke +// ProcessPackNotification +// [Files] uefi2.1\hiicallback.c and uefi2.1\uefi21wapper.c +// +// 57 2/02/12 5:41p Arunsb +// [TAG] EIP81814 +// [Category] Improvement +// [Description] Merging common utility function for page, control and +// variable data. +// [Files] Uefi21Wapper.c +// +// 56 2/02/12 1:19p Premkumara +// [TAG] EIP75351,75352,75384 +// [Category] Improvement +// [Description] Suppress the warnings from static code analyzer +// [Files] String.c, boot.c, TseAdvanced.c,Time.c, PopupEdit.c, +// MessageBox.c, Label.c, Edit.c, Date.c +// +// 55 2/02/12 3:06a Premkumara +// [TAG] EIP75066 +// [Category] Improvement +// [Description] Support loading defaults for Ordelist controls +// [Files] Ordlistbox.c, Uefi21Wapper.c, CtrlCond.c, HiiCallback.c, +// Parse.c, Uefi20Wapper.c, TseUefihiil.h +// +// 54 1/20/12 5:10a Rajashakerg +// [TAG] EIP77875 +// [Category] Improvement +// [Description] Minisetup: Memory leaks in text browser +// [Files] Uefi21Wapper.c, hiistring21.c, variable.c +// +// 53 1/20/12 12:31a Rajashakerg +// [TAG] EIP80426 +// [Category] Improvement +// [Description] When restoring settings, avoid accessing the varstore +// for text controls +// [Files] uefi21wapper.c, Setupdata.h. +// +// 52 1/13/12 1:41a Arunsb +// [TAG] EIP80360 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] HDDSecurity module - Issue in login with TSE, Master +// password disabled +// [RootCause] Cache not updated +// [Solution] Cache updated properly +// [Files] Tseadvanced.c, special.c and uefi21wapper.c +// +// 51 1/09/12 1:59a Arunsb +// [TAG] EIP79952 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Add driver option displays select boot option as title +// [RootCause] Title problem +// [Solution] Title changed +// [Files] Faketokens.c, amitsestr.uni, addbootoption.c, +// uefi2.0\hiicallback.c and uefi21wapper.c +// +// 50 12/08/11 5:21p Arunsb +// progress freeing removed +// +// 49 12/08/11 1:09p Rajashakerg +// [TAG] EIP75379 +// [Category] Improvement +// [Description] Suppress the warnings from static code analyzer +// [Files] Postmgmtext.c, Uefi21Wapper.c +// +// 48 12/08/11 12:18p Rajashakerg +// [TAG] EIP75558 +// [Category] Improvement +// [Description] Incorrect static strings retrieved in Text Broswer +// [Files] Uefi21Wapper.c +// +// 47 12/07/11 2:48p Arunsb +// [TAG] EIP75588 +// [Category] New Feature +// [Description] Support for queuing UpdatePack notifications +// [Files] frame.c, page.c, formbrowser2.c, hii.c, hiicallback.c, +// hiinotificationhandler.c, tseuefihii.h and uefi21wapper.c +// +// 46 12/07/11 2:08p Arunsb +// [TAG] EIP77475 +// [Category] New Feature +// [Description] Changed varsetvalue to _vargetsetvalue in +// UefiRefershQuestionValueNvRAM fnc since _vargetsetvalue wont calls the +// SetupConfigModifiedHook +// [Files] uefi21wapper.c +// +// 45 12/07/11 8:56a Rajashakerg +// [TAG] EIP73231 +// [Category] Improvement +// [Description] Updated the check for date and time flags for NON RTC. +// [Files] Uefi21Wapper.c +// +// 44 12/07/11 8:16a Rajashakerg +// [TAG] EIP75118 +// [Category] Improvement +// [Description] xtractConfig() fail since BrowserCallback() cannot find +// the variable to process +// [Files] FormBrowser2.c, FormBrowser2.h, HiiCallback.c, +// Uefi21Wapper.c, PopupSel.c +// +// 43 12/07/11 7:18a Rajashakerg +// [TAG] EIP75558 +// [Category] Improvement +// [Description] Incorrect static strings retrieved in Text Broswer +// [Files] Uefi20Wapper.c +// +// 42 12/01/11 7:46a Rajashakerg +// [TAG] EIP75464 +// [Category] Improvement +// [Description] Improper handling of action controls +// [Files] SubMenu.c, UefiAction.c, HiiCallback.c, Uefi21Wapper.c +// +// 41 11/28/11 5:16a Rajashakerg +// [TAG] EIP73231 +// [Category] Improvement +// [Description] Callback handling :For interactive controls updating +// the currnet vaule in cache even when hii callback returns error status. +// [Files] Date.c, SubMenu.c, ordlistbox.c, time.c, UefiAction.c, +// hii.h, uefi20Wapper.c, HiiCallback.c, TseUefiHii.h, Uefi21Wapper.c +// +// 40 11/28/11 2:15a Premkumara +// [TAG] EIP75384 +// [Category] Improvement +// [Description] Suppress the warnings from static code analyzer +// [Files] UefiWapper.c, Hii.c, Expression.c, CtrlCond.c, PopupSel.c, +// Minisetupext.c, Menu.c, Date.c, Ezport\Stylecommon.c, +// EzportPlus\StyleCommon.c, +// +// 39 11/23/11 5:20a Rajashakerg +// [TAG] EIP75473 +// [Category] Improvement +// [Description] System Time is not updated every second +// [Files] variable.h, variable.c, FormBrowser2.c, TseUefiHii.h, +// Uefi21Wapper.c, hii.h, uefi20Wapper.c +// +// 38 11/20/11 7:39a Premkumara +// [TAG] EIP73226 +// [Category] New Feature +// [Description] Extended support for password prompt +// [Files] FakeToken.c, Uefi21Wapper.c, AmiTSEStr.uni, PopupPassword.c, +// +// 37 11/14/11 2:43p Blaines +// [TAG] - EIP 75481 +// [Category]- Function Request +// [Synopsis]- TSE debug print infrastructure. +// [Description]- Add TSE debug print info for basic functions such as +// Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms +// data. +// [Files] +// AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c +// Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c, +// HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h, +// Uefi21Wrapper.c, setupdbg.h +// +// 36 11/14/11 12:07a Arunsb +// While checking in EIP70421 & 70422 Support for driver order, +// UefiRefershQuestionValueNvRAM +// function had a wrong fix. So reverting. +// +// 35 11/13/11 1:13p 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 +// +// 34 11/03/11 4:43a Premkumara +// [TAG] EIP70966 +// [Category] Improvement +// [Description] Hii orderlist item can't update priority from value in +// Setup menu for both enable and disable TSE_MULTILINE_CONTROLS token +// [Files] Ordlistbox.c, ordlistbox.h, TseUefiHii.h, Uefi21Wrapper.c +// +// 33 10/20/11 12:25p Blaines +// Correct the comments. +// +// 32 10/20/11 11:48a Blaines +// [TAG] EIP 72333 +// [Category] Sighting +// [Symptom] Some SAS controller card HII Screen Titles are displaying +// the wrong information +// [RootCause] Menu tab always displays the root page title when +// navigating submenu pages. TSE did not support the display of Formset +// Help. +// +// [Solution] Display Formset Help for Dynamic page, Display page title of +// submenu pages in the menu tab. +// +// [Files Changed] +// - AMITSE.sdl, CommonHelper.c, special.c, Menu.c, minisetupext.h, +// TseUefiHii.h, Uefi21Wapper.c +// +// 31 9/29/11 7:02p Blaines +// [TAG] - EIP 66860 +// [Category]- Function Request +// [Synopsis]- AmiPostManager interface for text entry. +// [Files] - LogoLib.h, AMIPostMgr.h, protocol.c, protocol.h, +// TseAdvanced.c, TseLitehelper.c, TseUefiHii.h, Uefi21Wapper.c +// +// 30 8/26/11 6:22p Blaines +// [TAG] EIP68354 +// [Category] Bug Fix +// [Severity] Normal +// [RootCause] Callback was invoked during periodic update for time and +// date controls without EFI_IFR_REFRESH_OP. +// [Solution] Callback is only invoked for interactive controls. +// [Files] TseLite: Time.c, Date.c +// Uefi21: Parese.c, Uefi21Wrapper.c +// +// 29 7/19/11 3:04p Arunsb +// [TAG] EIP57661 +// [Category] New Feature +// [Description] Driver health variables are updated in cache too. +// [Files] notify.c, Uefi21Wapper.c and variable.h +// +// 28 6/30/11 4:20a Arunsb +// [TAG] EIP57661 +// [Category] New Feature +// [Description] Boot manager algorithm for interaction with Driver +// Health protocol. +// [Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni, +// commonhelper.c, uefisetup.ini, tsedrvhealth.h, +// amivfr.h, minisetupbin.mak, +// hiistring21.c, hiistring20.c, tseadvanced.c, special.c, +// special.h, boot.h, minisetup.h, +// uefi20wapper.c, formbrowser2.c, hii.c, parse.c and +// uefi21wapper.c. +// +// 27 6/23/11 4:01p Rajashakerg +// [TAG] EIP55762, 58925, 59971 +// [Category] New Feature +// [Description] Support REF2,REF3 and REF4 in AMITSE +// Support direct form navigation path +// Improper layout of controls in the root page when Dynamic pages are +// added using the Legacy Setup Style +// +// [Files] setupdata.h, CommonHelper.c, AMITSE.sdl, Legacy\Legacy.c, +// Legacy\style.h, Legacy\style.h, frame.c, minisetupext.c, +// minisetupext.h, numeric.c, page.c Popupstring.c, Hii.c, +// Uefi21Wrapper.c, Parse.c Hii.c +// +// 26 6/22/11 6:05p Arunsb +// [TAG] EIP56405 +// [Category] New Feature +// [Description] Support for EFI_IFR_VARSTORE_NAME_VALUE opcode +// [Files] Hii.c, parse.c and uefi21wapper.c +// +// 25 6/20/11 12:28p Rajashakerg +// [TAG] EIP60563 +// [Category] New Feature +// [Description] Support for signed decimal value for +// EFI_IFR_NUMERIC_OP. +// [Files] numeric.c, numeric.h, string.c, string.h, Uefi21Wapper.c +// +// 24 4/29/11 4:46p Arunsb +// For 2.13 public patch release IFR RefX feature is omitted +// +// 22 3/28/11 11:45p Madhans +// UefiGetKeyField() updated. +// +// 21 3/28/11 5:06p Rajashakerg +// [TAG] EIP56413 +// [Category] Improvement +// [Description] TSE: Support for EFI_IFR_RESET_BUTTON opcode +// [Files] ezport.c, minisetupext.h, ResetButton.c, ResetButton.h, +// Hii.c, TseUefiHii.h, Uefi21Wapper.c, hii.h, Uefi20Wapper.c +// +// 20 3/21/11 1:02a Rajashakerg +// [TAG] EIP53480 +// [Category] Improvement +// [Description] FormBrowser extended actions support +// [Files] callback.c, minisetupext.c, minisetupext.h, numeric.c, +// PopupSel.c, PopupString.c, SubMenu.c, TseLiteCommon.c, UefiAction.c, +// Hiicallback.c, TseUefiHii.h, Uefi21Wapper.c, HiiCallback.c +// +// 19 3/09/11 7:26p Madhans +// [TAG] EIPEIP48615 +// [Category] Improvement +// [Description] To support UEFI 2.1 RefreshOp. Based in Refersh Rate +// Controls are refershed periodically. +// [Files] minisetupext.h +// SubMenu.h +// SubMenu.c +// Memo.c +// Memo.h +// numeric.c +// numeric.h +// time.c +// Date.c +// PopupSel.c +// PopupSel.h +// PopupString.c +// PopupString.h +// ordlistbox.c +// minisetupext.c +// UefiAction.c +// hii.h +// Uefi20wapper.c +// hiicallback.c +// Parse.c +// tseuefihii.h +// Uefi21wapper.c +// +// 18 2/01/11 7:38p Madhans +// [TAG] - EIP 50737 +// [Category]- Defect +// [Severity]- Mordarate +// [Symptom] - Suppressing the Interactive control does not work +// correctly. +// [RootCause] - The control conditional pointer if not set correctly. +// [Solution]- To fix the Control condition pointer. And identify the +// suppress if related to UEFI action control +// [Files] - UefiAction.c TseLiteHelper.c hii.h uefi20wapper.c +// uefi21wapper.c +// +// 17 12/28/10 12:31p Madhans +// To update the Tag of EIp 46998. UEFI option ROM menus disappear in +// Setup when certain options are selected. +// No file changed but Comment updated right +// +// 16 12/02/10 5:51p Madhans +// [TAG] - EIP 48169 +// [Category]- Improvment. +// [Severity]- Mordarate +// [Symptom]- To do the Workaround for ConfigtoBlock issues and Fix issues +// with Retirive config. +// [Solution]- Fix done formBrowser2.c and uefi21wrapper.c +// [Files] - formBrowser2.c and uefi21wrapper.c +// +// 15 12/02/10 5:34p Madhans +// [TAG] - EIP 49559 +// [Category]- defect +// [Severity]- Mordarate +// [Symptom]- OneOption contols works ok if it stores the values in BYTE +// and Does not contain any suppressif for options. +// But it has issues in supporting UINT16, UINT32 and UINT64 storage. +// [Rootcause] - The Type is not checked for Storeage and issues with +// condition check for options. +// [Solution]- Fix done ctrlcond.c and uefi21wrapper.c +// [Files] - CtrlCond.h, ctrlcond.c and uefi21wrapper.c +// +// 14 12/02/10 5:21p Madhans +// [TAG] - EIP 49557 +// [Category]- defect +// [Severity]- Mordarate +// [Symptom]- UEFIAction controls does not work correctly. +// [Rootcause] - Action controls does not Process the QuestionResp +// correctly. +// [Solution]- Fix done UEFIAction to check for QuestionResp and call the +// callback +// [Files] - uefiaction.c and uefi21wapper.c +// +// 13 11/10/10 7:02p Blaines +// EIP 47037: Add range checks to properly edit and update date/time. +// +// 12 10/27/10 4:25p Madhans +// [TAG] EIP46998 +// [Category] Defect +// [Symptom] Some user action on PCIx with UEFI Hii Pages causes Setup +// screen pages and menu disappers. +// [RootCause] UEFI 2.1 parsing code is not handling the Removepack and +// New pack sequance properly. Normally UpdatePack +// does the removepack and AddPack. +// [Solution] UEFI 2.1 parsing code fixed to handle above case correctly. +// [Files] hii.c HiiNotificationHandler.c Parse.c TseUefiHii.h +// uefi21wapper.c +// +// 11 9/16/10 8:38p Madhans +// Update for TSE 2.10. Refer Changelog.log for more details. +// +// 17 7/07/10 7:45p Madhans +// Changes to Support Adding Conditions to Suppress or Grayout the Special +// controls. +// +// 16 6/22/10 6:44a Mallikarjunanv +// EIP 39764 - Password Encoding Enabled by default. +// +// 15 6/21/10 4:19p Blaines +// Added code to support more question types for the function +// UefiGetKeyField. +// +// 14 6/17/10 2:48p Madhans +// Varsotre NameValue fix. +// +// 13 6/15/10 12:33p Blaines +// Update function header and properly initialize status variable in +// UefiSetTime and UefiGetTime. +// +// 12 6/14/10 7:15p Madhans +// Dynamic parsing support +// +// 11 6/08/10 5:17p Blaines +// Add support for UEFI 2.0/2.1 Date and Time controls +// +// 10 4/08/10 12:09p Madhans +// To call the Special Callback with proper Key value. +// +// 9 4/07/10 6:25p Madhans +// For UEFI 2.1 Error Manger variable is EFI variable not an HII Varstore. +// +// 8 3/11/10 5:44p Madhans +// Coding Standards Update +// +// 7 2/26/10 7:02p Madhans +// To build with EDK support. +// +// 4 12/14/09 4:52p Presannar +// Bug Fix Eip-32732 +// +// 3 11/30/09 1:10p Presannar +// Modified ConfigAccessCallback EFI_BROWSER_ACTION from pass by reference +// to pass by value +// +// 2 11/19/09 5:33p Presannar +// Updated TSE include file name to not clash with CORE file +// Updated fn GetControlConditionVarId to search for Control within the +// formset if not found in current form +// Added Fn IsPasswordEncodeEnabled +// +// 1 7/24/09 6:54p Presannar +// +// 6 5/28/09 11:50a Presannar +// Bug Fixes +// +// 5 4/24/09 7:54p Presannar +// TSE 2.0 UEFI 2.1 Code Complete +// +// 4 4/14/09 12:43p Presannar +// Added Fn ProcessActionQuestionConfiguration, +// ProcessBrowserActionRequest and _VerifyResponseString +// Added AMI_IFR_MSGBOX declarations +// Updated Uefi Action control handling +// +// 3 3/31/09 4:15p Madhans +// UEFI Wrapper improvments. +// +// 2 1/29/09 6:10p Presannar +// Added case for EFI_IFR_SUBTITLE_OP +// Added new fn GetControlConditionVariable and HiiRemoveString +// +// 1 1/09/09 2:38p Presannar +// UEFI 2.1 Hii Related Code - Initial Drop +// +//*****************************************************************// +// +// +// Name: Uefi21Wapper.c +// +// Description: +// +// +//****************************************************************// + +//---------------------------------------------------------------------------- + +#include "minisetup.h" +#include "TseUefiHii.h" +#include "TseElinks.h" //EIP106950 +#include EFI_PROTOCOL_DEFINITION(UnicodeCollation) +#if TSE_DEBUG_MESSAGES +#include +#endif +#include "TseDrvHealth.h" //Has TSE related driver health structures +//EIP 57661 Driver health support +UINT16 *_DevicePathToStr (EFI_DEVICE_PATH_PROTOCOL *Path); +CHAR16 DriverHealthStatus [6][23] = { + L"Healthy", + L"Repair Required", + L"Configuration Required", + L"Failed", + L"Reconnect Required", + L"Reboot Required" + }; +EFI_HANDLE gDrvHandle = NULL; +EFI_DRIVER_HEALTH_PROTOCOL *gDrvHealthInstance = NULL; +DRV_HEALTH_HNDLS *gDrvHealthHandlesHead = NULL; +extern BOOLEAN gEnableDrvNotification; //TRUE if allow notification function to process action, FALSE to ignore the notification +extern AMI_POST_MANAGER_PROTOCOL *mPostMgr; +extern VOID _GetNextLanguage(CHAR8 **LangCode, CHAR8 *Lang); +//---------------------------------------------------------------------------- +#if TSE_DEBUG_MESSAGES +BOOLEAN SetupDebugKeyHandler(UINT16 ItemIndex, UINT16 Unicode, CHAR16 *Value) ; +EFI_STATUS DisplayParseFormSetData(VOID) ; +EFI_STATUS DebugShowAllHiiVariable(UINT32 formID) ; +UINT16 _GetQuestionToken(UINT8 *ifrData); +VOID ProcessPackToFile(EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, EFI_HANDLE Handle); +UINTN HpkFileCount=0; +#endif //End of TSE_DEBUG_MESSAGES + +EFI_FILE_PROTOCOL * CreateFile(CHAR16 *filename, UINT32 index); +EFI_GUID guidSimpleFileSystemProtocol = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; + +static EFI_IFR_SUBTITLE _Title = { { EFI_IFR_SUBTITLE_OP, sizeof(EFI_IFR_SUBTITLE) }, 0 }; +static EFI_IFR_SUBTITLE _Help = { { EFI_IFR_SUBTITLE_OP, sizeof(EFI_IFR_SUBTITLE) }, 0 }; +static EFI_IFR_SUBTITLE _SubTitle = { { EFI_IFR_SUBTITLE_OP, sizeof(EFI_IFR_SUBTITLE) }, 0 }; +static EFI_IFR_SUBTITLE _HelpTitle = { { EFI_IFR_SUBTITLE_OP, sizeof(EFI_IFR_SUBTITLE) }, STRING_TOKEN(STR_HELP_TITLE) }; +static EFI_IFR_SUBTITLE _NavStrings = { { EFI_IFR_SUBTITLE_OP, sizeof(EFI_IFR_SUBTITLE) }, 0 }; + +static STRING_REF CallbackErrToken=0; + +AMI_IFR_MSGBOX _PreviousMsgBox = { 0, 0, STRING_TOKEN(STR_LOAD_PREVIOUS), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_LOAD_PREVIOUS_MSG) }; +AMI_IFR_MSGBOX _FailsafeMsgBox = { 0, 0, STRING_TOKEN(STR_LOAD_FAILSAFE), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_LOAD_FAILSAFE_MSG) }; +AMI_IFR_MSGBOX _OptimalMsgBox = { 0, 0, STRING_TOKEN(STR_LOAD_OPTIMAL), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_LOAD_OPTIMAL_MSG) }; +AMI_IFR_MSGBOX _SaveMsgBox = { 0, 0, STRING_TOKEN(STR_SAVE_VALUES), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_SAVE_VALUES_MSG) }; +AMI_IFR_MSGBOX _SaveExitMsgBox = { 0, 0, STRING_TOKEN(STR_SAVE_EXIT), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_SAVE_EXIT_MSG) }; +AMI_IFR_MSGBOX _ExitMsgBox = { 0, 0, STRING_TOKEN(STR_EXIT), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_EXIT_MSG) }; +AMI_IFR_MSGBOX _SaveResetMsgBox = { 0, 0, STRING_TOKEN(STR_SAVE_RESET), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_SAVE_RESET_MSG) }; +AMI_IFR_MSGBOX _ResetMsgBox = { 0, 0, STRING_TOKEN(STR_RESET), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_RESET_MSG) }; +AMI_IFR_MSGBOX _HelpMsgBox = { 0, 0, STRING_TOKEN(STR_GENERAL_HELP), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_GENERAL_HELP_MSG) }; +AMI_IFR_MSGBOX _SaveUserMsgBox = { 0, 0, STRING_TOKEN(STR_SAVE_USER_DEFAULTS), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_SAVE_VALUES_MSG) }; +AMI_IFR_MSGBOX _LoadUserMsgBox = { 0, 0, STRING_TOKEN(STR_LOAD_USER_DEFAULTS), (VOID*)INVALID_HANDLE, STRING_TOKEN(STR_LOAD_USER_MSG) }; + +AMI_IFR_MSGBOX _InvalidPasswordFailMsgBox = { 0, 0, STRING_TOKEN(STR_ERROR),(VOID*) INVALID_HANDLE, STRING_TOKEN(STR_ERROR_PSWD) }; +AMI_IFR_MSGBOX _ClearPasswordMsgBox = { 0, 0, STRING_TOKEN(STR_WARNING),(VOID*) INVALID_HANDLE, STRING_TOKEN(STR_PSWD_CLR) };//EIP:73226 To Clear Old Password message +AMI_IFR_MSGBOX _ClearPasswordLabelMsgBox = { 0, 0, STRING_TOKEN(STR_WARNING),(VOID*) INVALID_HANDLE, STRING_TOKEN(STR_PSWD_CLR_LABEL) };//EIP:73226 To Clear Old Password message +AMI_IFR_MSGBOX _BootLaunchFailedMsgBox = { 0, 0, STRING_TOKEN(STR_WARNING), INVALID_HANDLE, STRING_TOKEN(STR_WARNING_NOT_FOUND) }; +AMI_IFR_MSGBOX _gInvalidRangeFailMsgBox = { 0, 0, STRING_TOKEN(STR_ERROR), INVALID_HANDLE, STRING_TOKEN(STR_ERROR_INPUT) }; + +AMI_IFR_MSGBOX _gDelBootOptionReserved = { 0, 0, STRING_TOKEN(STR_WARNING), INVALID_HANDLE, STRING_TOKEN(STR_DEL_BOOT_OPTION_RESERVED) }; +AMI_IFR_MSGBOX _gAddBootOptionReserved = { 0, 0, STRING_TOKEN(STR_WARNING), INVALID_HANDLE, STRING_TOKEN(STR_ADD_BOOT_OPTION_RESERVED) }; +AMI_IFR_MSGBOX _gAddBootOptionEmpty = { 0, 0, STRING_TOKEN(STR_WARNING), INVALID_HANDLE, STRING_TOKEN(STR_ADD_BOOT_OPTION_EMPTY) }; +AMI_IFR_MSGBOX _gAddDriverOptionEmpty = { 0, 0, STRING_TOKEN(STR_WARNING), INVALID_HANDLE, STRING_TOKEN(STR_ADD_DRIVER_OPTION_EMPTY) }; + + +UINTN gPreviousMsgBox = (UINTN)&_PreviousMsgBox; +UINTN gFailsafeMsgBox = (UINTN)&_FailsafeMsgBox; +UINTN gOptimalMsgBox = (UINTN)&_OptimalMsgBox; +UINTN gSaveMsgBox = (UINTN)&_SaveMsgBox; +UINTN gSaveExitMsgBox = (UINTN)&_SaveExitMsgBox; +UINTN gExitMsgBox = (UINTN)&_ExitMsgBox; +UINTN gSaveResetMsgBox = (UINTN)&_SaveResetMsgBox; +UINTN gResetMsgBox = (UINTN)&_ResetMsgBox; +UINTN gHelpMsgBox = (UINTN)&_HelpMsgBox; +UINTN gSaveUserMsgBox = (UINTN)&_SaveUserMsgBox; +UINTN gLoadUserMsgBox = (UINTN)&_LoadUserMsgBox; + +UINTN gBootLaunchFailedMsgBox = (UINTN)&_BootLaunchFailedMsgBox; +UINTN gInvalidPasswordFailMsgBox = (UINTN)&_InvalidPasswordFailMsgBox; +UINTN gClearPasswordMsgBox = (UINTN)&_ClearPasswordMsgBox;//EIP:73226 To display Clear Old Password message +UINTN gClearLabelPasswordMsgBox = (UINTN)&_ClearPasswordLabelMsgBox; +UINTN gInvalidRangeFailMsgBox = (UINTN)&_gInvalidRangeFailMsgBox; +UINTN gDelBootOptionReserved = (UINTN)&_gDelBootOptionReserved; +UINTN gAddBootOptionReserved = (UINTN)&_gAddBootOptionReserved; +UINTN gAddBootOptionEmpty = (UINTN)&_gAddBootOptionEmpty; +UINTN gAddDriverOptionEmpty = (UINTN)&_gAddDriverOptionEmpty; + +static AMI_IFR_MSGBOX gCallbackErrorMsgBox = { 0, 0, STRING_TOKEN(STR_ERROR), (VOID*)INVALID_HANDLE, 0 }; + +static BOOLEAN gHiiInitialized = FALSE; + +EFI_GUID gEfiHiiConfigRoutingProtocolGuid = EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID; + +EFI_HII_CONFIG_ROUTING_PROTOCOL *gHiiConfigRouting; + +UINTN gTitle = (UINTN)&_Title; +UINTN gHelp = (UINTN)&_Help; +UINTN gSubTitle = (UINTN)&_SubTitle; +UINTN gHelpTitle = (UINTN)&_HelpTitle; +UINTN gNavStrings = (UINTN)&_NavStrings; + +VOID _UefiGetValidOptions(CONTROL_INFO *IfrPtr, UINT16 **OptionPtrTokens, + UINT64 **ValuePtrTokens, UINT16 *ItemCount, + UINT8 MaxItems); + +EFI_STATUS _VerifyResponseString(EFI_STRING Configuration, BOOLEAN NameValue); +UINT32 FindVarFromITKQuestionId(UINT16 QuestionId); + +//EIP81814 Starts +//--------------------------------------------------------------------------- +// Defines for Utility Functions +//--------------------------------------------------------------------------- +#define MAX_FORMS_TO_PROCESS 50 +#define EFI_INCONSISTENT_VALUE (0x80000000 | 28) +#define EFI_NOSUBMIT_VALUE (0x80000000 | 29) +#define CHECKBOX_OPTION_COUNT 2 +#define OPTION_DEFAULT 0x10 +#define OPTION_DEFAULT_MFG 0x20 +#define TSE_GET_ONE_OF_WIDTH(a) (((EFI_IFR_ONE_OF*)(a))->Width) +#define TSE_GET_ONE_OF_OPTION_WIDTH(a) ( \ + ((EFI_IFR_ONE_OF_OPTION*)a)->Type == EFI_IFR_TYPE_NUM_SIZE_8 ? sizeof(UINT8) : (\ + ((EFI_IFR_ONE_OF_OPTION*)a)->Type == EFI_IFR_TYPE_NUM_SIZE_16 ? sizeof(UINT16) : (\ + ((EFI_IFR_ONE_OF_OPTION*)a)->Type == EFI_IFR_TYPE_NUM_SIZE_32 ? sizeof(UINT32) : (\ + ((EFI_IFR_ONE_OF_OPTION*)a)->Type == EFI_IFR_TYPE_NUM_SIZE_64 ? sizeof(UINT64) : (\ + ((EFI_IFR_ONE_OF_OPTION*)a)->Type == EFI_IFR_TYPE_BOOLEAN ? sizeof(BOOLEAN) : (\ + ((EFI_IFR_ONE_OF_OPTION*)a)->Type == EFI_IFR_TYPE_TIME ? sizeof(EFI_HII_TIME) : (\ + ((EFI_IFR_ONE_OF_OPTION*)a)->Type == EFI_IFR_TYPE_DATE ? sizeof(EFI_HII_DATE) : (\ + ((EFI_IFR_ONE_OF_OPTION*)a)->Type == EFI_IFR_TYPE_STRING ? sizeof(EFI_STRING_ID) : (\ + 0))))))))) + + + +typedef struct _OPTION_LIST OPTION_LIST; + +typedef struct _OPTION_LIST +{ + UINT16 Option; + UINT64 Value; + UINT8 Flag; + OPTION_LIST *Next; +}; + +static BOOLEAN LibInitialized = FALSE; +UINT32 *gProcessedForms; //[MAX_FORMS_TO_PROCESS]; //EIP 162180 +UINT32 gVarOffset = 0; +UINT32 gProFormOffset = 0; +UINT32 gProFormOffsetAllocCount = 0; +//--------------------------------------------------------------------------- +// Prototypes for Utility Functions +//--------------------------------------------------------------------------- +BOOLEAN _InconsistenceCheck(PAGE_INFO *PgInfo, UINT16 *ErrStrToken); +BOOLEAN _DestinationFormProcessed(UINT32 FormID); +EFI_STATUS _GetVariableIDList(UINT32 FormID, UINT32 **varIDList); +EFI_STATUS _GetCheckBoxOptions(CONTROL_INFO *CtrlInfo, UINT32 *OptionCount, OPTION_LIST **OptionArray); +EFI_STATUS LoadDefaults(UINT32 FormID, BOOLEAN *ResetVal, BOOLEAN * ValChanged); +BOOLEAN _InconsistenceCheck(PAGE_INFO *PgInfo, UINT16 *ErrStrToken); +BOOLEAN _NoSubmitCheck(CONTROL_INFO *ctrlInfo, UINT16 *ErrStrToken); +EFI_STATUS _GetVariableIDList(UINT32 FormID, UINT32 **VarIDList); +BOOLEAN _DestinationFormProcessed(UINT32 FormID); +BOOLEAN IsNoSubmitOfForms(UINT32 FormID, UINT16* ErrToken); +EFI_STATUS CheckforNosubmitIf(UINT32 FormID, BOOLEAN Recursive, UINT16 *ErrToken); +EFI_STATUS _GetControlFlag(UINT32 PgIndex, UINT32 CtrlIndex, CONTROL_FLAGS **CtrlFlag); +EFI_STATUS GetNumOfPages(UINT32 *NumOfPages); +EFI_STATUS GetPageTitle(UINT32 PgIndex, UINT16 *TitleToken); +EFI_STATUS GetPageSubTitle(UINT32 PgIndex, UINT16 *SubtitleToken); +EFI_STATUS GetPageHandle(UINT32 PgIndex, EFI_HII_HANDLE *Handle); +EFI_STATUS GetPageIdIndex(UINT32 PgIndex, UINT16 *PgIdIndex); +BOOLEAN IsParentPage(UINT32 PgIndex); +EFI_STATUS GetPageHiiId(UINT32 PgIndex, UINT16 *PageId); +EFI_STATUS GetPageParentId(UINT32 PgIndex, UINT16 *PageParentId); +EFI_STATUS GetCtrlsDestCtrlId(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *DestCtrlId); +EFI_STATUS GetControlType(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlType); +EFI_STATUS GetControlQuestionPrompt(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlPrompt); +EFI_STATUS GetControlHelpStr(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlHelp); +BOOLEAN IsControlCheckBox(UINT32 PgIndex, UINT32 CtrlIndex); +EFI_STATUS GetControlDataWidth(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlWidth); +EFI_STATUS GetControlDestinationPage(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlDestPg); +UINT8 GetControlAccess(UINT32 PgIndex, UINT32 CtrlIndex); +UINT8 GetControlRefresh(UINT32 PgIndex, UINT32 CtrlIndex); +BOOLEAN IsControlVisible(UINT32 PgIndex, UINT32 CtrlIndex); +BOOLEAN IsControlResetRequired(UINT32 PgIndex, UINT32 CtrlIndex); +BOOLEAN IsControlReadOnly(UINT32 PgIndex, UINT32 CtrlIndex); +BOOLEAN IsControlInteractive(UINT32 PgIndex, UINT32 CtrlIndex); +EFI_STATUS EvaluateControlCondition(UINT32 PgIndex, UINT32 CtrlIndex, UINTN *ExpResult); +EFI_STATUS GetQuestionValue(UINT32 PgIndex, UINT32 CtrlIndex, UINT8 **Value, UINTN *ValueSize); +EFI_STATUS SetQuestionValue(UINT32 PgIndex, UINT32 CtrlIndex, UINT8 *Value, UINTN ValueSize, UINT16 *ErrStrToken); +EFI_STATUS SaveQuestionValues(UINT32 FormID); +VOID FreeOptionList(OPTION_LIST *OptionArray); +EFI_STATUS GetControlDisplayFormat(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *Format); +EFI_STATUS GetControlMinMax(UINT32 PgIndex, UINT32 CtrlIndex, UINT64 *Min, UINT64 *Max); +EFI_STATUS GetControlDefault(UINT32 PgIndex, UINT32 CtrlIndex,UINT8 *Def, BOOLEAN Optimal); +EFI_STATUS GetOrderedListMaxEntries(UINT32 PgIndex, UINT32 CtrlIndex, UINT8 *MaxEntry); +EFI_STATUS GetOrderedListOptionDataWidth(CONTROL_INFO *ControlInfo, UINT32 *DataWidth); +EFI_STATUS GetOrderedListDataTypeWidth(UINT32 PgIndex, UINT32 CtrlIndex, UINT32 *DataWidth); +BOOLEAN IsPageRefreshable(UINT32 PgIndex); +BOOLEAN IsPageModal(UINT32 PgIndex); +BOOLEAN IfNoCommitVariable(UINT32 PgIndex, UINT32 CtrlIndex); +BOOLEAN IdentifyFormHasDefault(UINT32 FormID); +BOOLEAN IsFormsetHasDefault(UINT32 FormID); +EFI_STATUS GetPageGuidFromPgIndex(UINT32 PgIndex, EFI_GUID *FormGuid); +void AddEntryIngProcessedForms (UINT32 FormID); +void CleargProcessedForms (void); +//---------------------------------------------------------------------------- +//EIP81814 Ends + +#define _GET_MINMAXSTEP_DATA(b,c,d) ( \ + ((c)==EFI_IFR_NUMERIC_SIZE_1)?((b).u8.d):( \ + ((c)==EFI_IFR_NUMERIC_SIZE_2)?((b).u16.d):( \ + ((c)==EFI_IFR_NUMERIC_SIZE_4)?((b).u32.d): \ + ((b).u64.d) ))) + +#define TSE_GET_NUMERIC_MINVALUE(a) _GET_MINMAXSTEP_DATA((((EFI_IFR_NUMERIC*)(a))->data),(((EFI_IFR_NUMERIC*)(a))->Flags&EFI_IFR_NUMERIC_SIZE),MinValue) +#define TSE_GET_NUMERIC_MAXVALUE(a) _GET_MINMAXSTEP_DATA((((EFI_IFR_NUMERIC*)(a))->data),(((EFI_IFR_NUMERIC*)(a))->Flags&EFI_IFR_NUMERIC_SIZE),MaxValue) +#define TSE_GET_NUMERIC_STEP(a) _GET_MINMAXSTEP_DATA((((EFI_IFR_NUMERIC*)(a))->data),(((EFI_IFR_NUMERIC*)(a))->Flags&EFI_IFR_NUMERIC_SIZE),Step) +#define TSE_GET_NUMERIC_BASE(a) (((((EFI_IFR_NUMERIC*)a)->Flags&EFI_IFR_DISPLAY)==EFI_IFR_DISPLAY_UINT_HEX)?AMI_BASE_HEX:((((EFI_IFR_NUMERIC*)a)->Flags&EFI_IFR_DISPLAY)==EFI_IFR_DISPLAY_INT_DEC) ? AMI_BASE_INT_DEC :AMI_BASE_DEC) + +//---------------------------------------------------------------------------- + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetHelpField +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetHelpField(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT16 Token = 0; + + if(IfrPtr == NULL){ + return Token; + } + switch(OpHeader->OpCode) + { + case EFI_IFR_REF_OP: + Token = ((EFI_IFR_REF *)OpHeader)->Question.Header.Help; + break; + case EFI_IFR_TEXT_OP: + Token = ((EFI_IFR_TEXT *)OpHeader)->Statement.Help; + break; + case EFI_IFR_ONE_OF_OP: + Token = ((EFI_IFR_ONE_OF *)OpHeader)->Question.Header.Help; + break; + case EFI_IFR_TIME_OP: + Token = ((EFI_IFR_TIME *)OpHeader)->Question.Header.Help; + break; + case EFI_IFR_DATE_OP: + Token = ((EFI_IFR_DATE *)OpHeader)->Question.Header.Help; + break; + case EFI_IFR_NUMERIC_OP: + Token = ((EFI_IFR_NUMERIC *)OpHeader)->Question.Header.Help; + break; + case EFI_IFR_PASSWORD_OP: + Token = ((EFI_IFR_PASSWORD *)OpHeader)->Question.Header.Help; + break; + case EFI_IFR_ACTION_OP: + Token = ((EFI_IFR_ACTION *)OpHeader)->Question.Header.Help; + break; + case EFI_IFR_STRING_OP: + Token = ((EFI_IFR_STRING *)OpHeader)->Question.Header.Help; + break; + case EFI_IFR_RESET_BUTTON_OP: + Token = ((EFI_IFR_RESET_BUTTON *)OpHeader)->Statement.Help;//EIP:56413 Updated the Help field for Reset Button + break; + case EFI_IFR_ORDERED_LIST_OP: + Token = ((EFI_IFR_ORDERED_LIST *)OpHeader)->Question.Header.Help;//EIP:103568 Updated the Help field for order list control. + break; + default: + break; + } + + return Token; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetPromptField +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetPromptField(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT16 Token = 0; + + if(IfrPtr == NULL){ + return Token; + } + switch(OpHeader->OpCode) + { + case EFI_IFR_REF_OP: + Token = ((EFI_IFR_REF *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_NUMERIC_OP: + Token = ((EFI_IFR_NUMERIC *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_TIME_OP: + Token = ((EFI_IFR_TIME *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_DATE_OP: + Token = ((EFI_IFR_DATE *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_ONE_OF_OP: + Token = ((EFI_IFR_ONE_OF *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_ORDERED_LIST_OP: + Token = ((EFI_IFR_ORDERED_LIST *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_CHECKBOX_OP: + Token = ((EFI_IFR_CHECKBOX *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_PASSWORD_OP: + Token = ((EFI_IFR_PASSWORD *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_ACTION_OP: + Token = ((EFI_IFR_ACTION *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_STRING_OP: + Token = ((EFI_IFR_STRING *)OpHeader)->Question.Header.Prompt; + break; + case EFI_IFR_RESET_BUTTON_OP: + Token = ((EFI_IFR_RESET_BUTTON *)OpHeader)->Statement.Prompt;//EIP:56413 Updated the Prompt field for Reset Button + break; + default: + break; + } + + return Token; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetKeyField +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetKeyField(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT16 Token = 0; + + switch(OpHeader->OpCode) + { + case EFI_IFR_REF_OP: + Token = ((EFI_IFR_REF *)IfrPtr)->Question.QuestionId; + break; + case EFI_IFR_NUMERIC_OP: + Token = ((EFI_IFR_NUMERIC *)IfrPtr)->Question.QuestionId; + break; + case EFI_IFR_STRING_OP: + Token = ((EFI_IFR_STRING *)IfrPtr)->Question.QuestionId; + break; + + case EFI_IFR_PASSWORD_OP: + Token = ((EFI_IFR_PASSWORD *)IfrPtr)->Question.QuestionId; + break; + case EFI_IFR_CHECKBOX_OP: + Token = ((EFI_IFR_CHECKBOX *)IfrPtr)->Question.QuestionId; + break; + case EFI_IFR_ACTION_OP: + Token = ((EFI_IFR_ACTION *)IfrPtr)->Question.QuestionId; + break; + case EFI_IFR_DATE_OP: + Token = ((EFI_IFR_DATE *)IfrPtr)->Question.QuestionId; + break; + case EFI_IFR_ONE_OF_OP: + Token = ((EFI_IFR_ONE_OF *)IfrPtr)->Question.QuestionId; + break; + case EFI_IFR_ORDERED_LIST_OP: + Token = ((EFI_IFR_ORDERED_LIST *)IfrPtr)->Question.QuestionId; + break; + case EFI_IFR_TIME_OP: + Token = ((EFI_IFR_TIME *)IfrPtr)->Question.QuestionId; + break; + default: + break; + } + + return Token; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetTitleField +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetTitleField(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT16 Token = 0; + +// EIP 88658 : Minisetup crashes after controller reconnection during Hii callback + if(IfrPtr == NULL){ + goto DONE; + } + switch(OpHeader->OpCode) + { + case EFI_IFR_SUBTITLE_OP: + Token = ((EFI_IFR_SUBTITLE *)IfrPtr)->Statement.Prompt; + break; + case EFI_IFR_FORM_SET_OP: + Token = ((EFI_IFR_FORM_SET *)IfrPtr)->FormSetTitle; + break; + case EFI_IFR_FORM_OP: + Token = ((EFI_IFR_FORM *)IfrPtr)->FormTitle; + break; + default: + break; + } + +DONE: + return Token; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetFlagsField +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 UefiGetFlagsField(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT8 Flag = 0; + + switch(OpHeader->OpCode) + { + case EFI_IFR_REF_OP: + Flag = ((EFI_IFR_REF *)IfrPtr)->Question.Flags; + break; + case EFI_IFR_TIME_OP: + Flag = ((EFI_IFR_TIME *)IfrPtr)->Flags; + break; + case EFI_IFR_DATE_OP: + Flag = ((EFI_IFR_DATE *)IfrPtr)->Flags; + break; + default: + break; + } + + return Flag; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiIsInteractive +// +// Description: +// +// Parameter: CONTROL_INFO *ControlData +// +// Return value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN UefiIsInteractive(CONTROL_INFO *ControlData) +{ + return (BOOLEAN)(ControlData->ControlFlags.ControlInteractive); +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetControlKey +// +// Description: +// +// Parameter: CONTROL_INFO *ControlData +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetControlKey(CONTROL_INFO *ControlData) +{ + return ControlData->ControlKey; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetTextField +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetTextField(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT16 Token = 0; + + switch(OpHeader->OpCode) + { + case EFI_IFR_TEXT_OP: + Token = ((EFI_IFR_TEXT*)OpHeader)->Statement.Prompt; + break; + default: + break; + } + + return Token; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetTextTwoField +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetTextTwoField(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT16 Token = 0; + + switch(OpHeader->OpCode) + { + case EFI_IFR_TEXT_OP: + Token = ((EFI_IFR_TEXT*)OpHeader)->TextTwo; + break; + default: + break; + } + + return Token; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiSetSubTitleField +// +// Description: +// +// Parameter: VOID *IfrPtr,UINT16 Token +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiSetSubTitleField(VOID *IfrPtr,UINT16 Token) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + + switch(OpHeader->OpCode) + { + case EFI_IFR_SUBTITLE_OP: + ((EFI_IFR_SUBTITLE*)OpHeader)->Statement.Prompt = Token; + break; + default: + break; + } +} +// +//---------------------------------------------------------------------------- +// Procedure: UefiSetHelpField +// +// Description: +// +// Parameter: VOID *IfrPtr,UINT16 Token +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiSetHelpField(VOID *IfrPtr, UINT16 Token) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + + switch(OpHeader->OpCode) + { + case EFI_IFR_REF_OP: + ((EFI_IFR_REF *)OpHeader)->Question.Header.Help = Token ; + break; + case EFI_IFR_TEXT_OP: + ((EFI_IFR_TEXT *)OpHeader)->Statement.Help = Token ; + break; + case EFI_IFR_ONE_OF_OP: + ((EFI_IFR_ONE_OF *)OpHeader)->Question.Header.Help = Token ; + break; + case EFI_IFR_TIME_OP: + ((EFI_IFR_TIME *)OpHeader)->Question.Header.Help = Token ; + break; + case EFI_IFR_DATE_OP: + ((EFI_IFR_DATE *)OpHeader)->Question.Header.Help = Token ; + break; + case EFI_IFR_NUMERIC_OP: + ((EFI_IFR_NUMERIC *)OpHeader)->Question.Header.Help = Token ; + break; + case EFI_IFR_PASSWORD_OP: + ((EFI_IFR_PASSWORD *)OpHeader)->Question.Header.Help = Token ; + break; + case EFI_IFR_ACTION_OP: + ((EFI_IFR_ACTION *)OpHeader)->Question.Header.Help = Token ; + break; + case EFI_IFR_STRING_OP: + ((EFI_IFR_STRING *)OpHeader)->Question.Header.Help = Token ; + break; + case EFI_IFR_RESET_BUTTON_OP: + ((EFI_IFR_RESET_BUTTON *)OpHeader)->Statement.Help = Token ; + break; + default: + break; + } + +} +// +//---------------------------------------------------------------------------- +// Procedure: UefiSetPromptField +// +// Description: +// +// Parameter: VOID *IfrPtr,UINT16 Token +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiSetPromptField(VOID *IfrPtr,UINT16 Token) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + + switch(OpHeader->OpCode) + { + case EFI_IFR_REF_OP: + ((EFI_IFR_REF*)OpHeader)->Question.Header.Prompt = Token; + break; + case EFI_IFR_ONE_OF_OP: + case EFI_IFR_NUMERIC_OP: + case EFI_IFR_TIME_OP: + case EFI_IFR_DATE_OP: + case EFI_IFR_ORDERED_LIST_OP: + case EFI_IFR_CHECKBOX_OP: + case EFI_IFR_PASSWORD_OP: + case EFI_IFR_STRING_OP: + { + EFI_IFR_QUESTION_HEADER *Question = (EFI_IFR_QUESTION_HEADER *)((UINT8 *)OpHeader + sizeof(EFI_IFR_OP_HEADER)); + + Question->Header.Prompt = Token; + } + break; + default: + break; + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiCreateSubTitleTemplate +// +// Description: +// +// Parameter: UINT16 Token +// +// Return value: VOID * +//---------------------------------------------------------------------------- +// +VOID * UefiCreateSubTitleTemplate(UINT16 Token) +{ + EFI_IFR_OP_HEADER *OpHeader = EfiLibAllocateZeroPool(sizeof(EFI_IFR_SUBTITLE)); + + OpHeader->OpCode = EFI_IFR_SUBTITLE_OP ; + OpHeader->Length = sizeof(EFI_IFR_SUBTITLE) ; + UefiSetSubTitleField((VOID *)OpHeader,Token); + return (VOID*)OpHeader; +} +// +//---------------------------------------------------------------------------- +// Procedure: UefiCreateStringTemplate +// +// Description: Function to create uefi string template +// +// Parameter: UINT16 Token +// +// Return value: VOID * +//---------------------------------------------------------------------------- +// +VOID * UefiCreateStringTemplate(UINT16 Token) +{ + EFI_IFR_OP_HEADER *OpHeader = EfiLibAllocateZeroPool(sizeof(EFI_IFR_STRING)); + + OpHeader->OpCode = EFI_IFR_STRING_OP ; + OpHeader->Length = sizeof(EFI_IFR_STRING) ; + UefiSetPromptField((VOID *)OpHeader,Token); + return (VOID*)OpHeader; +} +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetIfrLength +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 UefiGetIfrLength(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + + return OpHeader->Length; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetMinValue +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT64 +//---------------------------------------------------------------------------- +// +UINT64 UefiGetMinValue(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT64 Min = 0; + + switch(OpHeader->OpCode) + { + case EFI_IFR_NUMERIC_OP: + // Should The type be Taken Into Account? // + //Min = (UINT64)((EFI_IFR_NUMERIC*)OpHeader)->data.u64.MinValue; + Min = TSE_GET_NUMERIC_MINVALUE(IfrPtr); + break; + case EFI_IFR_PASSWORD_OP: + Min = (UINT64)((EFI_IFR_PASSWORD*)OpHeader)->MinSize; + break; + case EFI_IFR_STRING_OP: + Min = (UINT64)((EFI_IFR_STRING*)OpHeader)->MinSize; + break; + default: + break; + } + return Min; + +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetMaxValue +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT64 +//---------------------------------------------------------------------------- +// +UINT64 UefiGetMaxValue(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT64 Max = 0; + + switch(OpHeader->OpCode) + { + case EFI_IFR_NUMERIC_OP: + // Should The type be Taken Into Account? // + //Max = (UINT64)((EFI_IFR_NUMERIC*)OpHeader)->data.u64.MaxValue; + Max = TSE_GET_NUMERIC_MAXVALUE(IfrPtr); + break; + case EFI_IFR_PASSWORD_OP: + Max = (UINT64)((EFI_IFR_PASSWORD*)OpHeader)->MaxSize; + break; + case EFI_IFR_STRING_OP: + Max = (UINT64)((EFI_IFR_STRING*)OpHeader)->MaxSize; + break; + default: + break; + } + return Max; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetStepValue +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT64 +//---------------------------------------------------------------------------- +// +UINT64 UefiGetStepValue(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT64 Step = 0; + switch(OpHeader->OpCode) + { + case EFI_IFR_NUMERIC_OP: + // Should The type be Taken Into Account? // + //Step = (UINT64)((EFI_IFR_NUMERIC*)OpHeader)->data.u64.Step; + Step = TSE_GET_NUMERIC_STEP(IfrPtr); + break; + default: + break; + } + return Step; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetBaseValue +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 UefiGetBaseValue(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT8 Base = EFI_IFR_DISPLAY_UINT_DEC; + + switch(OpHeader->OpCode) + { + case EFI_IFR_NUMERIC_OP: + //Base = (((EFI_IFR_NUMERIC *)OpHeader)->Flags & EFI_IFR_DISPLAY); + Base = TSE_GET_NUMERIC_BASE(IfrPtr); + break; + default: + break; + } + return Base; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetWidth +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetWidth(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT16 Width = 0; + + if (NULL == OpHeader) //EIP-126997 Avoid setup crash + return Width; + + switch(OpHeader->OpCode) + { + case EFI_IFR_NUMERIC_OP: + case EFI_IFR_ONE_OF_OP: + Width = (UINT16)(1 << (((EFI_IFR_NUMERIC*)OpHeader)->Flags & EFI_IFR_NUMERIC_SIZE)); + break; + case EFI_IFR_PASSWORD_OP: + Width = (UINT16)((EFI_IFR_PASSWORD*)OpHeader)->MaxSize * sizeof(CHAR16); + break; + case EFI_IFR_STRING_OP: + Width = (UINT16)((EFI_IFR_STRING*)OpHeader)->MaxSize * sizeof(CHAR16); + break; + case EFI_IFR_CHECKBOX_OP: + Width = sizeof(UINT8); + break; + case EFI_IFR_DATE_OP: + Width = sizeof(EFI_HII_DATE); + break; + case EFI_IFR_TIME_OP: + Width = sizeof(EFI_HII_TIME); + break; + case EFI_IFR_EQ_ID_VAL_OP: + case EFI_IFR_EQ_ID_LIST_OP: + case EFI_IFR_EQ_ID_ID_OP: + ASSERT(1); + break; + default: + break; + } + return Width; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetQuestionOffset +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +extern UINT32 gtempCurrentPage; +UINT16 UefiGetQuestionOffset(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + EFI_IFR_QUESTION_HEADER *QHeader = NULL; + UINT16 VarOffset = 0; + UINT32 iIndex = 0; + VARIABLE_INFO *Variable = NULL; + + if (NULL == OpHeader) //EIP-126997 Avoid setup crash + return VarOffset; + + switch(OpHeader->OpCode) + { + case EFI_IFR_CHECKBOX_OP: + case EFI_IFR_REF_OP: + case EFI_IFR_RESET_BUTTON_OP: + case EFI_IFR_ACTION_OP: + case EFI_IFR_DATE_OP: + case EFI_IFR_NUMERIC_OP: + case EFI_IFR_ONE_OF_OP: + case EFI_IFR_STRING_OP: + case EFI_IFR_PASSWORD_OP: + case EFI_IFR_ORDERED_LIST_OP: + case EFI_IFR_TIME_OP: + QHeader = (EFI_IFR_QUESTION_HEADER *)((UINT8*)OpHeader + sizeof(EFI_IFR_OP_HEADER)); + for (iIndex = 0; iIndex < gVariables->VariableCount; iIndex++) + { + Variable = (VARIABLE_INFO*)((UINT8 *)gVariables + gVariables->VariableList [iIndex]); + if ((VARIABLE_ATTRIBUTE_NAMEVALUE == (Variable->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE))) + { + UINT32 page = (NULL == gApp ? gtempCurrentPage : gApp->CurrentPage); + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList [page]); + + //Always dont depend on VariableID alone it will be same for different handles, compare handle also + if (pageInfo && (pageInfo->PageHandle == Variable->VariableHandle) && (Variable->VariableID == QHeader->VarStoreId)) + { + return 0; + } + } + } + VarOffset = QHeader->VarStoreInfo.VarOffset; + break; + default: + break; + } + return VarOffset; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetDateTimeDetails +// +// Description: +// +// Parameter: VOID *IfrPtr,UINT8 Type,UINT16 * Help,UINT16 * Min,UINT16 * Max +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiGetDateTimeDetails(VOID *IfrPtr,UINT8 Type,UINT16 * Help,UINT16 * Min,UINT16 * Max) +{ +/* + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + EFI_IFR_NUMERIC *NumIfr=NULL; + switch(OpHeader->OpCode) + { + case EFI_IFR_TIME_OP: + if(Type == AMI_TIME_HOUR) + NumIfr = &(((EFI_IFR_TIME*)OpHeader)->Hour); + else if (Type == AMI_TIME_MIN) + NumIfr = &(((EFI_IFR_TIME*)OpHeader)->Minute); + else if (Type == AMI_TIME_SEC) + NumIfr = &(((EFI_IFR_TIME*)OpHeader)->Second); + break; + case EFI_IFR_DATE_OP: + if(Type == AMI_DATE_YEAR) + NumIfr = &(((EFI_IFR_DATE*)OpHeader)->Year); + else if (Type == AMI_DATE_MONTH) + NumIfr = &(((EFI_IFR_DATE*)OpHeader)->Month); + else if (Type == AMI_DATE_DAY) + NumIfr = &(((EFI_IFR_DATE*)OpHeader)->Day); + break; + default: + break; + } + if(NumIfr) + { + *Help = NumIfr->Help; + *Min = NumIfr->Minimum; + *Max = NumIfr->Maximum; + }*/ + + *Min = 0; + *Max = 0xFFFF;//EIP 74964 Initializing the MIN/MAX values for date and time. + +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetOneOfOptions +// +// Description: +// +// Parameter: VOID *IfrPtr,VOID **Handle,UINT16 **OptionPtrTokens, +// UINT64 **ValuePtrTokens, UINT16 *ItemCount, +// UINT16 *Interactive,UINT16 *CallBackKey +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiGetOneOfOptions(CONTROL_INFO *CtrlInfo, VOID **Handle, UINT16 **OptionPtrTokens, + UINT64 **ValuePtrTokens, UINT16 *ItemCount, + UINT16 *Interactive,UINT16 *CallBackKey ) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)(CtrlInfo->ControlPtr); + EFI_IFR_QUESTION_HEADER *QHeader; + EFI_STATUS Status = EFI_SUCCESS; + UINT16 Index= 0; + UINT8 Opcode = OpHeader->OpCode; + UINT8 MaxItems = 10; + + if(OpHeader->OpCode == EFI_IFR_CHECKBOX_OP) + { + MaxItems = 2; + *Handle = gHiiHandle; + } + + // Evaluate Interactive and Callback + QHeader = (EFI_IFR_QUESTION_HEADER *)((UINT8 *)OpHeader + sizeof(EFI_IFR_OP_HEADER)); + if(QHeader->Flags & EFI_IFR_FLAG_CALLBACK) + { + if(Interactive) + *Interactive = TRUE; + if(CallBackKey) + *CallBackKey = QHeader->QuestionId; + } + + // Free Buffers if Allocated and Allocate afresh + if( OptionPtrTokens != NULL ) + { + if( *OptionPtrTokens != NULL ) + MemFreePointer((VOID **)OptionPtrTokens); + } + + if( ValuePtrTokens != NULL ) + { + if( *ValuePtrTokens != NULL ) + MemFreePointer((VOID **)ValuePtrTokens); + } + + if( NULL != OptionPtrTokens )//EIP-75379 Static code analysis check for NULL + { + *OptionPtrTokens = (UINT16 *)EfiLibAllocateZeroPool(MaxItems * sizeof(UINT16)); + } + + if(ValuePtrTokens) + *ValuePtrTokens = (UINT64 *)EfiLibAllocateZeroPool(MaxItems * sizeof(UINT64)); + + if ( NULL == OptionPtrTokens || NULL == *OptionPtrTokens )//EIP-75379 Static code analysis check for NULL + { + Status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + //Populate Options + if(Opcode == EFI_IFR_CHECKBOX_OP) + { + *ItemCount = MaxItems; + for(Index = 0; Index < MaxItems; Index++) + { + (*OptionPtrTokens)[Index] = gCheckboxTokens[Index]; + if(ValuePtrTokens) + (*ValuePtrTokens)[Index] = Index; + } + } + else + { + *ItemCount = 0; + _UefiGetValidOptions(CtrlInfo, OptionPtrTokens, ValuePtrTokens, ItemCount, MaxItems); + } + +DONE: + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _UefiGetValidOptions +// +// Description: +// +// Parameter: CONTROL_INFO *CtrlInfo, UINT16 **OptionPtrTokens, +// UINT64 **ValuePtrTokens, UINT16 *ItemCount,UINT8 MaxItems +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID _UefiGetValidOptions(CONTROL_INFO *CtrlInfo, UINT16 **OptionPtrTokens, + UINT64 **ValuePtrTokens, UINT16 *ItemCount,UINT8 MaxItems) +{ + EFI_IFR_OP_HEADER *OpHeader = (EFI_IFR_OP_HEADER *)CtrlInfo->ControlPtr; + UINT32 Offset = 0; + INT32 InScope = 0; + UINT16 Max = (UINT16)MaxItems; + UINT16 Itr = 0; + UINT8 suppress = FALSE; + UINT8 condition = COND_NONE; + INT32 suppressScopeCount = 0; + UINT8 *conditionPtr = NULL; + + do + { + if(OpHeader->Scope) + { + InScope++; + suppressScopeCount = suppressScopeCount? ++suppressScopeCount : 0; + } + switch(OpHeader->OpCode) + { + case EFI_IFR_SUPPRESS_IF_OP: + if(suppress == FALSE) + { + conditionPtr = (UINT8 *)OpHeader; + suppress = TRUE; + suppressScopeCount++; + } + break; + case EFI_IFR_ONE_OF_OPTION_OP: + // Evaluate Condition to determine if option is required to be added to list + condition = suppress && conditionPtr? CheckOneOfOptionSuppressIf(CtrlInfo, conditionPtr, (UINT8*)OpHeader) : COND_NONE; + if(condition != COND_SUPPRESS) + { + // Add Option to Buffer. + if(Itr == Max) + { + *OptionPtrTokens = MemReallocateZeroPool(*OptionPtrTokens, Max * sizeof(UINT16), (Max + 10) * sizeof(UINT16)); + if(ValuePtrTokens) + { + *ValuePtrTokens = MemReallocateZeroPool(*ValuePtrTokens, Max * sizeof(UINT64), (Max + 10) * sizeof(UINT64)); + } + Max += 10; + } + (*OptionPtrTokens)[Itr] = ((EFI_IFR_ONE_OF_OPTION *)OpHeader)->Option; + if(ValuePtrTokens) + { + switch(((EFI_IFR_ONE_OF_OPTION *)OpHeader)->Type) + { + case EFI_IFR_TYPE_NUM_SIZE_16: + (*ValuePtrTokens)[Itr] = ((EFI_IFR_ONE_OF_OPTION *)OpHeader)->Value.u16; + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + (*ValuePtrTokens)[Itr] = ((EFI_IFR_ONE_OF_OPTION *)OpHeader)->Value.u32; + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + (*ValuePtrTokens)[Itr] = ((EFI_IFR_ONE_OF_OPTION *)OpHeader)->Value.u64; + break; + case EFI_IFR_TYPE_NUM_SIZE_8: + default: + (*ValuePtrTokens)[Itr] = ((EFI_IFR_ONE_OF_OPTION *)OpHeader)->Value.u8; + break; + } + } + Itr++; + } + break; + case EFI_IFR_END_OP: + InScope = InScope > 0? --InScope : 0; + suppressScopeCount = suppressScopeCount > 0? --suppressScopeCount : 0; + suppress = suppressScopeCount == 0? FALSE : suppress; + conditionPtr = suppress == TRUE? conditionPtr : NULL; + default: + break; + } + + // Move to Next Opcode + Offset += OpHeader->Length; + OpHeader = (EFI_IFR_OP_HEADER *)((UINT8*)CtrlInfo->ControlPtr + Offset); + }while(InScope); + *ItemCount = Itr; +} + +// +//--------------------------------------------------------------------------- +// Procedure: UefiGetValidOptionType +// +// Description: Assuming all the options in this control has option with +// same type and length +// +// Input: CONTROL_INFO *CtrlInfo - Pointer to the control info data +// UINTN *Type - Returns EFI_IFR_TYPE_NUM_SIZE +// +// Output: VOID +//--------------------------------------------------------------------------- +// +VOID UefiGetValidOptionType(CONTROL_INFO *CtrlInfo, UINTN *Type, UINT32 *SizeOfData) +{ + EFI_IFR_OP_HEADER *OpHeader = (EFI_IFR_OP_HEADER *)CtrlInfo->ControlPtr; + UINT32 Offset = 0; + INT32 InScope = 0; + UINT8 suppress = FALSE; + UINT8 condition = COND_NONE; + INT32 suppressScopeCount = 0; + UINT8 *conditionPtr = NULL; + + do + { + if(OpHeader->Scope) + { + InScope++; + suppressScopeCount = suppressScopeCount? ++suppressScopeCount : 0; + } + switch(OpHeader->OpCode) + { + case EFI_IFR_SUPPRESS_IF_OP: + if(suppress == FALSE) + { + conditionPtr = (UINT8 *)OpHeader; + suppress = TRUE; + suppressScopeCount++; + } + break; + case EFI_IFR_ONE_OF_OPTION_OP: + // Evaluate Condition to determine if option is required to be added to list + condition = suppress && conditionPtr? CheckOneOfOptionSuppressIf(CtrlInfo, conditionPtr, (UINT8*)OpHeader) : COND_NONE; + if(condition != COND_SUPPRESS) + { + switch(((EFI_IFR_ONE_OF_OPTION *)OpHeader)->Type) + { + case EFI_IFR_TYPE_NUM_SIZE_16: + *Type = EFI_IFR_TYPE_NUM_SIZE_16; + *SizeOfData = sizeof(UINT16); + goto DONE; + case EFI_IFR_TYPE_NUM_SIZE_32: + *Type = EFI_IFR_TYPE_NUM_SIZE_32; + *SizeOfData = sizeof(UINT32); + goto DONE; + case EFI_IFR_TYPE_NUM_SIZE_64: + *Type = EFI_IFR_TYPE_NUM_SIZE_64; + *SizeOfData = sizeof(UINT64); + goto DONE; + case EFI_IFR_TYPE_NUM_SIZE_8: + default: + *Type = EFI_IFR_TYPE_NUM_SIZE_8; + *SizeOfData = sizeof(UINT8); + goto DONE; + } + } + break; + case EFI_IFR_END_OP: + InScope = InScope > 0? --InScope : 0; + suppressScopeCount = suppressScopeCount > 0? --suppressScopeCount : 0; + suppress = suppressScopeCount == 0? FALSE : suppress; + conditionPtr = suppress == TRUE? conditionPtr : NULL; + break; + default: + break; + } + // Move to Next Opcode + Offset += OpHeader->Length; + OpHeader = (EFI_IFR_OP_HEADER *)((UINT8*)CtrlInfo->ControlPtr + Offset); + }while(InScope); + +DONE: + return; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetMaxEntries +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 UefiGetMaxEntries(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT8 Value = 0; + + switch(OpHeader->OpCode) + { + case EFI_IFR_ORDERED_LIST_OP: + Value = ((EFI_IFR_ORDERED_LIST*)OpHeader)->MaxContainers; + break; + default: + break; + } + return Value; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiTseLiteGetBootOverRideIndex +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiTseLiteGetBootOverRideIndex(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER * OpHeader = (EFI_IFR_OP_HEADER *)IfrPtr; + EFI_IFR_EQ_ID_LIST *EqIdList; + UINT16 Index=0xFFFF; + UINT8 InScope = 0; + + if ((OpHeader != NULL) && (OpHeader->OpCode == EFI_IFR_SUPPRESS_IF_OP)) + { + do + { + if(OpHeader->Scope) + { + InScope++; + } + + if(OpHeader->OpCode == EFI_IFR_END_OP) + { + InScope--; + if(InScope == 0) + { + // EFI_IFR_EQ_ID_LIST_OP opcode not found + goto DONE; + } + } + + OpHeader = (EFI_IFR_OP_HEADER*)((UINT8*)OpHeader + OpHeader->Length); + }while(OpHeader->OpCode != EFI_IFR_EQ_ID_LIST_OP); + + // FIX ME : Do it better. Check the list length and + if(OpHeader->OpCode == EFI_IFR_EQ_ID_LIST_OP) + { + EqIdList = (EFI_IFR_EQ_ID_LIST*)OpHeader; + Index = EqIdList->ListLength - 1; + } + } + +DONE: + return Index; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiTseLiteGetAmiCallbackIndex +// +// Description: +// +// Parameter: VOID * Ptr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiTseLiteGetAmiCallbackIndex(VOID * Ptr, VOID * CtrlPtr) +{ + EFI_IFR_OP_HEADER * OpHeader = (EFI_IFR_OP_HEADER *)Ptr; + UINT16 Index=0xFFFF; + UINT8 InScope = 0; + VOID *SupressIfPtr = NULL; + + if ((OpHeader != NULL) && (OpHeader->OpCode == EFI_IFR_SUPPRESS_IF_OP)) + { + // Locate the Last supress If till the control Ptr + do + { + if(OpHeader->Scope) + { + InScope++; + } + if(OpHeader->OpCode == EFI_IFR_END_OP) + { + InScope--; + if(InScope == 0) + { + // EFI_IFR_EQ_ID_VAL_OP opcode not found + goto DONE; + } + } + if(OpHeader->OpCode == EFI_IFR_SUPPRESS_IF_OP) + SupressIfPtr = (VOID*)OpHeader; + OpHeader = (EFI_IFR_OP_HEADER*)((UINT8*)OpHeader + OpHeader->Length); + }while((UINTN)OpHeader < (UINTN)CtrlPtr); + + OpHeader = (EFI_IFR_OP_HEADER*)SupressIfPtr ; + do + { + if(OpHeader->Scope) + { + InScope++; + } + if(OpHeader->OpCode == EFI_IFR_END_OP) + { + InScope--; + if(InScope == 0) + { + // EFI_IFR_EQ_ID_VAL_OP opcode not found + goto DONE; + } + } + OpHeader = (EFI_IFR_OP_HEADER*)((UINT8*)OpHeader + OpHeader->Length); + }while(OpHeader->OpCode != EFI_IFR_EQ_ID_VAL_OP); + + // FIX ME : Do it better. Check the list length and + if(OpHeader->OpCode == EFI_IFR_EQ_ID_VAL_OP) + { + Index = ((EFI_IFR_EQ_ID_VAL*)OpHeader)->Value; + } + } + +DONE: + return Index; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: UefiFormCallbackNVRead +// +// Description: +// +// Parameter: CHAR16 *name, EFI_GUID *guid, UINT32 *attributes, +// UINTN *size, VOID **buffer +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiFormCallbackNVRead(CHAR16 *name, EFI_GUID *guid, UINT32 *attributes, UINTN *size, VOID **buffer) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiFormCallbackNVWrite +// +// Description: +// +// Parameter: CHAR16 *name, EFI_GUID *guid, UINT32 attributes, +// VOID *buffer, UINTN size +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiFormCallbackNVWrite(CHAR16 *name, EFI_GUID *guid, UINT32 attributes, VOID *buffer, UINTN size) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiVarGetNvram +// +// Description: +// +// Parameter: VARIABLE_INFO *VariableInfo, VOID **Buffer, UINTN Offset, +// UINTN Size +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS NameValueGetHexStringAsBuffer (UINT8 **Buffer, CHAR16 *HexStringBuffer, UINTN Size); +EFI_STATUS UefiVarGetNvram(VARIABLE_INFO *VariableInfo, VOID **Buffer, UINTN Offset, UINTN Size) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_STRING configuration = (EFI_STRING)NULL; + EFI_STRING result = (EFI_STRING)NULL; + EFI_STRING stringPtr = (EFI_STRING)NULL; + UINTN length = 1; + UINT8 *buffer = NULL; + EFI_GUID EfiHiiConfigAccessProtocolGuid = EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID; + EFI_HANDLE DriverHandle; + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; + CHAR16 tmpString = (CHAR16)NULL; + EFI_STRING progress = &tmpString; + BOOLEAN PreservegEnableDrvNotification = FALSE; + + configuration = EfiLibAllocateZeroPool(length); + if(configuration == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + // + // Construct the Configuration Header String + // + status = GetConfigHeader(VariableInfo, &configuration, &length); + if(EFI_ERROR(status) || (configuration == NULL))//EIP-75384 Static Analysis + { + goto DONE; + } + + if(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE) + { + //Allocate Memory for "&" + UINTN len = length + EfiStrLen(L"&") + EfiStrLen(VariableInfo->VariableName) + sizeof(CHAR16); + + configuration = MemReallocateZeroPool(configuration, length * sizeof(CHAR16), len * sizeof(CHAR16)); + if(configuration == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + EfiStrCat(configuration, L"&"); + EfiStrCat(configuration, VariableInfo->VariableName); + length = len; + }else + { + status = GetBlockName(&configuration, &length, Offset, Size); + if(EFI_ERROR(status)) + { + goto DONE; + } + } + + SetCallBackControlInfo(VariableInfo->VariableHandle, 0); //Set this varaible handle to allow BrowserCallback + + PreservegEnableDrvNotification = gEnableDrvNotification; + gEnableDrvNotification = TRUE; //EIP75588 Set to enable notification processing + + if (!(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)) // Invoke Config Routing Route Config + { + status = gHiiConfigRouting->ExtractConfig (gHiiConfigRouting, configuration, &progress, &result); + } + else + { + status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, VariableInfo->VariableHandle, &DriverHandle); //Calling the driver which publishes the name value + if(!EFI_ERROR(status)) + { + status = gBS->HandleProtocol (DriverHandle, &EfiHiiConfigAccessProtocolGuid , &ConfigAccess); + if(!EFI_ERROR(status)) + { + status = ConfigAccess->ExtractConfig (ConfigAccess, configuration, &progress, &result); + } + } + } + if (!PreservegEnableDrvNotification) // If gEnableDrvNotification is already True Don't touch it + gEnableDrvNotification = FALSE; //EIP75588 Reset to disable notification processing + SetCallBackControlInfo(NULL, 0); //Disable update + if(EFI_ERROR(status) || (progress == (EFI_STRING)NULL)) + { + goto DONE; + } + + if(EFI_ERROR(status = _VerifyResponseString(result, (VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)? TRUE : FALSE))) + { + goto DONE; + } + + stringPtr = result; + if(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE) + { + for(stringPtr = result; *stringPtr != 0 && EfiStrnCmp(stringPtr, VariableInfo->VariableName, EfiStrLen(VariableInfo->VariableName)) != 0; stringPtr++) + ; + stringPtr += EfiStrLen(VariableInfo->VariableName); + stringPtr += EfiStrLen(L"="); + status = NameValueGetHexStringAsBuffer (&buffer, stringPtr, Size); + }else + { + for(stringPtr = result; *stringPtr != 0 && EfiStrnCmp(stringPtr, L"&VALUE=", EfiStrLen(L"&VALUE=")) != 0; stringPtr++) + ; + stringPtr += EfiStrLen(L"&VALUE="); + status = GetHexStringAsBuffer (&buffer, stringPtr); + } + + + if(EFI_ERROR(status)) + { + goto DONE; + } + + *Buffer = buffer; + +DONE: + if(configuration) + { + MemFreePointer(&configuration); + } + if(result) + { + MemFreePointer(&result); + } + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiVarSetNvram +// +// Description: +// +// Parameter: VARIABLE_INFO *VariableInfo, VOID *Buffer, UINTN Offset, +// UINTN Size +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS NameValueBufToHexString (IN OUT CHAR16 **, IN OUT UINTN *, IN UINT8 *, IN UINTN ); +EFI_STATUS UefiVarSetNvram(VARIABLE_INFO *VariableInfo, VOID *Buffer, UINTN Offset, UINTN Size) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_STRING configuration = NULL; + EFI_STRING progress = NULL; + CHAR16 *tempBuffer = NULL; + UINTN length = 0; + UINTN finalLen = 0; + UINTN bufLen = 1; + BOOLEAN PreservegEnableDrvNotification = FALSE; + + // + //Construct the Configuration Header String + // + status = GetConfigHeader(VariableInfo, &configuration, &length); + if(EFI_ERROR(status) || (configuration == NULL))//EIP-75384 Static Analysis + { + goto DONE; + } + + if(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE) + { + UINTN len = length + EfiStrLen(L"&") + EfiStrLen(VariableInfo->VariableName) + EfiStrLen(L"=") + sizeof(CHAR16); + configuration = MemReallocateZeroPool (configuration, length * sizeof(CHAR16), len * sizeof(CHAR16)); + if (configuration == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + EfiStrCat(configuration, L"&"); + EfiStrCat(configuration, VariableInfo->VariableName); + EfiStrCat(configuration, L"="); + length = EfiStrLen (configuration) * sizeof (CHAR16); + }else + { + status = GetBlockName(&configuration, &length, Offset, Size); + if(EFI_ERROR(status)) + { + goto DONE; + } + } + + // + // Get the Buffer as Hex String + // + if (!(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)) + { + tempBuffer = (UINT16*)EfiLibAllocateZeroPool(bufLen * sizeof(UINT16)); + if(tempBuffer == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + status = BufToHexString(tempBuffer, &bufLen, Buffer, Size); + if(EFI_ERROR(status)) + { + if(status != EFI_BUFFER_TOO_SMALL) + { + goto DONE; + } + if(tempBuffer) + { + MemFreePointer(&tempBuffer); + } + tempBuffer = (UINT16*)EfiLibAllocateZeroPool(bufLen * 2); + if(tempBuffer == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + } + status = BufToHexString(tempBuffer, &bufLen, Buffer, Size); + } + else + { + bufLen = 0; + status = NameValueBufToHexString (&tempBuffer, &bufLen, Buffer, Size); + } + if(EFI_ERROR(status)) + { + goto DONE; + } + +// + // Calculate the total Configuration string length + // &OFFSET=0&WIDTH=&VALUE= + // | length | 7 | bufLen | 1 | + // + if (!(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)) + { + finalLen = length + (bufLen * 2) + (EfiStrLen(L"&VALUE=") * sizeof(CHAR16)); + } + else + { // + + + finalLen = length + bufLen + (2 * sizeof (CHAR16)); //Last 2 bytes for appending & and NULL + } + configuration = MemReallocateZeroPool(configuration, length, finalLen); + if(configuration == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + if (!(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)) + { + EfiStrCat(configuration, L"&VALUE="); + } + EfiStrCat(configuration, tempBuffer); + if (VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE) + { + EfiStrCat (configuration, L"&"); + } + MemFreePointer(&tempBuffer); + PreservegEnableDrvNotification = gEnableDrvNotification; + gEnableDrvNotification = TRUE; //EIP75588 Set to enable notification processing + status = gHiiConfigRouting->RouteConfig (gHiiConfigRouting, configuration, &progress); + if(!PreservegEnableDrvNotification) // If gEnableDrvNotification is already True Don't touch it + gEnableDrvNotification = FALSE; //Reset to disable notification processing + MemFreePointer (&configuration); +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _ConstructConfigHdr +// +// Description: Construct using routing information GUID/NAME/PATH. +// +// Parameter: IN OUT CHAR16 *ConfigHdr, +// IN OUT UINTN *StrBufferLen, +// IN EFI_GUID *Guid, +// IN CHAR16 *Name, OPTIONAL +// IN EFI_HANDLE *DriverHandle +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _ConstructConfigHdr ( + IN OUT CHAR16 *ConfigHdr, + IN OUT UINTN *StrBufferLen, + IN EFI_GUID *Guid, + IN CHAR16 *Name, OPTIONAL + IN EFI_HANDLE *DriverHandle + ) +{ + EFI_STATUS Status; + UINTN NameStrLen; + UINTN DevicePathSize; + UINTN BufferSize; + CHAR16 *StrPtr; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + if (Name == NULL) + { + // + // There will be no "NAME" in for Name/Value storage + // + NameStrLen = 0; + } else + { + // + // For buffer storage + // + NameStrLen = EfiStrLen (Name); + } + + // + // Retrieve DevicePath Protocol associated with this HiiPackageList + // + Status = gBS->HandleProtocol ( + DriverHandle, + &gEfiDevicePathProtocolGuid, + &DevicePath + ); + if (EFI_ERROR (Status)) + { + return Status; + } + + DevicePathSize = EfiDevicePathSize (DevicePath); + + // + // GUID=32&NAME=NameStrLen&PATH=DevicePathStrLen + // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 | + // + BufferSize = (5 + 32 + 6 + NameStrLen * 4 + 6 + DevicePathSize * 2 + 1) * sizeof (CHAR16); + if (*StrBufferLen < BufferSize) + { + *StrBufferLen = BufferSize; + return EFI_BUFFER_TOO_SMALL; + } + + *StrBufferLen = BufferSize; + + StrPtr = ConfigHdr; + + EfiStrCpy (StrPtr, L"GUID="); + StrPtr += 5; + BufferToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID)); + StrPtr += 32; + + // + // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044" + // + EfiStrCpy (StrPtr, L"&NAME="); + StrPtr += 6; + if (Name != NULL) + { + BufferSize = (NameStrLen * 4 + 1) * sizeof (CHAR16); + UnicodeToConfigString (StrPtr, &BufferSize, Name); + StrPtr += (NameStrLen * 4); + } + + EfiStrCpy (StrPtr, L"&PATH="); + StrPtr += 6; + BufferToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize); + + return EFI_SUCCESS; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: GetConfigHeader +// +// Description: +// +// Parameter: VARIABLE_INFO *VariableInfo, EFI_STRING *Configuration, UINTN *Length +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetConfigHeader(VARIABLE_INFO *VariableInfo, EFI_STRING *Configuration, UINTN *Length) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_STRING configuration = NULL; + EFI_HANDLE driverHandle; + UINTN length = 50; + + // + // Initialize Protocols + // + status = HiiInitializeProtocol(); + if(EFI_ERROR(status)) + { + goto DONE; + } + + // + // Retrieve the Device Path from Handle + // + status = gHiiDatabase->GetPackageListHandle(gHiiDatabase, VariableInfo->VariableHandle, &driverHandle); + if(EFI_ERROR(status)) + { + goto DONE; + } + + // Allocate static memory of 50 Bytes, which will be freed if not used + configuration = (UINT16*)EfiLibAllocateZeroPool(50); + + // Construct the Configuration Header String + // + status = _ConstructConfigHdr(configuration, &length, &VariableInfo->VariableGuid, VariableInfo->VariableName, driverHandle); + if(EFI_ERROR(status)) + { + if(status == EFI_BUFFER_TOO_SMALL) + { + MemFreePointer(&configuration); + configuration = (UINT16*)EfiLibAllocateZeroPool(length); + if(configuration == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + status = _ConstructConfigHdr(configuration, &length, &VariableInfo->VariableGuid, VariableInfo->VariableName, driverHandle); + } + } + + if(EFI_ERROR(status)) + { + goto DONE; + } + + if(*Configuration) + { + MemFreePointer(Configuration); + } + *Configuration = configuration; + *Length = length; + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetBlockName +// +// Description: +// +// Parameter: EFI_STRING *Configuration, UINTN *Length, UINTN Size +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetBlockName(EFI_STRING *Configuration, UINTN *Length, UINTN Offset, UINTN Size) +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN length = 0; + UINTN finalLen = 0; + CHAR16 *tempBuffer = NULL; + + length = (EfiStrLen(L"&OFFSET=") + sizeof(Offset) + EfiStrLen(L"&WIDTH=") + sizeof(Size) + 1) * sizeof(CHAR16); + tempBuffer = (CHAR16*)EfiLibAllocateZeroPool(length); + if(tempBuffer == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + SPrint(tempBuffer, length, L"&OFFSET=%x&WIDTH=%x", Offset, Size); + + length = EfiStrLen(*Configuration) * sizeof(CHAR16); + finalLen = (EfiStrLen(*Configuration) + EfiStrLen(tempBuffer) + 1) * sizeof(CHAR16); + *Configuration = MemReallocateZeroPool(*Configuration, length, finalLen); + if(*Configuration == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + + EfiStrCat(*Configuration, tempBuffer); + + MemFreePointer(&tempBuffer); + *Length = finalLen; + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _VerifyResponseString +// +// Description: Verifies Correctness of Response String. This is to prevent +// crashing if the result pointer is pointing to an invalid location. +// +// Parameter: EFI_STRING *Configuration +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _VerifyResponseString(EFI_STRING Configuration, BOOLEAN NameValue) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_STRING config = Configuration; + CHAR16 *keyWord[] = {L"GUID=", L"&NAME=", L"&PATH=", L"&OFFSET=",L"&WIDTH=", L"&VALUE="}; + UINT32 i = 0; + UINT32 count = NameValue? 3 : 6; // If Name Value Check only upto &Path else check until &Value. + + if(EfiStrnCmp(config, keyWord[i], EfiStrLen(keyWord[i])) != 0) + { + status = EFI_NOT_FOUND; + goto DONE; + } + + for(i = 1; i < count; i++) + { + for(;EfiStrnCmp(config, keyWord[i], EfiStrLen(keyWord[i])) != 0 && (config != (Configuration + EfiStrLen(Configuration))); config++) + ; + if(EfiStrnCmp(config, keyWord[i], EfiStrLen(keyWord[i])) != 0) + { + status = EFI_NOT_FOUND; + goto DONE; + } + } + +DONE: + return status; +} + +#if !TSE_USE_EDK_LIBRARY +VOID +EfiLibSafeFreePool ( + IN VOID *Buffer + ) +{ +MemFreePointer(&Buffer); +} +#endif + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetHexStringAsBuffer +// +// Description: +// +// Parameter: CHAR8 *Buffer +// UINT16 *HexStringBuffer +// UINTN Size +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetHexStringAsBuffer(UINT8 **Buffer, CHAR16 *HexStringBuffer) +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN bufLength = 0; + UINTN convertedStrLen = 0; + + status = HexStringToBuf(*Buffer, &bufLength, HexStringBuffer, &convertedStrLen); + if(EFI_ERROR(status)) + { + if(status == EFI_BUFFER_TOO_SMALL) + { + if(*Buffer) + { + MemFreePointer(Buffer); + } + *Buffer = EfiLibAllocateZeroPool(bufLength); + if(*Buffer == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + }else + { + goto DONE; + } + status = HexStringToBuf(*Buffer, &bufLength, HexStringBuffer, &convertedStrLen); + } + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: NameValueGetHexStringAsBuffer +// +// Description: +// +// Parameter: CHAR8 *Buffer +// UINT16 *HexStringBuffer +// UINTN Size +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS NameValueHexStringToBuf (IN OUT UINT8 *, IN OUT UINTN *Len,IN CHAR16 *, OUT UINTN *); +EFI_STATUS NameValueGetHexStringAsBuffer (UINT8 **Buffer, CHAR16 *HexStringBuffer, UINTN Size) +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN bufLength = 0; + UINTN convertedStrLen = 0; + + if (Size <= sizeof (UINT64)) + { + GetHexStringAsBuffer (Buffer, HexStringBuffer); + } + else + { + status = NameValueHexStringToBuf (*Buffer, &bufLength, HexStringBuffer, &convertedStrLen); + if(EFI_ERROR(status)) + { + if(status == EFI_BUFFER_TOO_SMALL) + { + if(*Buffer) + { + MemFreePointer(Buffer); + } + bufLength = (Size > bufLength) ? Size : bufLength; + *Buffer = EfiLibAllocateZeroPool(bufLength); + if(*Buffer == NULL) + { + status = EFI_OUT_OF_RESOURCES; + goto DONE; + } + }else + { + goto DONE; + } + status = NameValueHexStringToBuf (*Buffer, &bufLength, HexStringBuffer, &convertedStrLen); + } + } +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: HiiExtendedInitializeProtocol +// +// Description: +// +// Parameter: +// +// Return value: EFI_STATUS +// EFI_SUCCESS +//---------------------------------------------------------------------------- +// +EFI_STATUS HiiExtendedInitializeProtocol() +{ + EFI_STATUS status = EFI_SUCCESS; + + if (gHiiInitialized) + { + goto DONE; + } + + status = gBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &gHiiConfigRouting); + if(EFI_ERROR(status)) + { + goto DONE; + } + + gHiiInitialized = TRUE; + +DONE: + return status; +} + + +// +//---------------------------------------------------------------------------- +// Procedure: GetControlConditionVariable +// +// Description: +// +// Parameter: CONTROL_INFO *ControlInfo +// +// Return value: UINT32 +//---------------------------------------------------------------------------- +// +UINT32 GetControlConditionVariable(CONTROL_INFO *ControlInfo) +{ + EFI_IFR_OP_HEADER *ifrPtr; + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[ControlInfo->ControlPageID]); + UINTN control = 0; + CONTROL_INFO *CtrlInfo; + BOOLEAN found = FALSE; + EFI_QUESTION_ID QuestionId; + UINT32 varId = 0; + + if ( ControlInfo == NULL ) + return 0; + + ifrPtr = (EFI_IFR_OP_HEADER *)ControlInfo->ControlConditionalPtr; + + if ( ifrPtr == NULL ) + return 0; + + if ( ( ifrPtr->OpCode != EFI_IFR_SUPPRESS_IF_OP ) && ( ifrPtr->OpCode != EFI_IFR_GRAY_OUT_IF_OP ) ) + return 0; + + ifrPtr = (EFI_IFR_OP_HEADER *)((UINTN)ifrPtr + ifrPtr->Length); + // skip NOT if it is present + if ( ifrPtr->OpCode == EFI_IFR_NOT_OP ) + ifrPtr = (EFI_IFR_OP_HEADER *)((UINTN)ifrPtr + ifrPtr->Length); + + if ( ifrPtr->OpCode == EFI_IFR_EQ_ID_LIST_OP ) + QuestionId = ((EFI_IFR_EQ_ID_LIST *)ifrPtr)->QuestionId; + else if ( ifrPtr->OpCode == EFI_IFR_EQ_ID_VAL_OP ) + QuestionId = ((EFI_IFR_EQ_ID_VAL *)ifrPtr)->QuestionId; + else + return 0; + + if(pageInfo->PageHandle ==0) + return 0; + + for ( control= 0; (control < pageInfo->PageControls.ControlCount) && (found == FALSE); control++ ) + { + CtrlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if(QuestionId == CtrlInfo->ControlKey) + { + varId = CtrlInfo->ControlVariable; + found = TRUE; + } + } + if(!found) + return 0; + + return varId; +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiRemoveString +// +// Description: +// +// Parameter: EFI_HII_HANDLE Handle, UINT16 Token +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID HiiRemoveString(EFI_HII_HANDLE Handle, UINT16 Token) +{ + UINT32 i = 0; + CHAR16 *nullString = NULL; + + for ( i = 0; i < gLangCount; i++ ) + { + HiiChangeStringLanguage( Handle, Token, gLanguages[i].Unicode, nullString ); + } +} + + +// +//---------------------------------------------------------------------------- +// Procedure: UefiIsEfiVariable +// +// Description: +// +// Parameter: UINT32 variable, VARIABLE_INFO *varInfo +// +// Return value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN UefiIsEfiVariable(UINT32 variable, VARIABLE_INFO *varInfo) +{ + if (varInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_EFI_VARSTORE || + variable == VARIABLE_ID_LANGUAGE || + variable == VARIABLE_ID_DEL_BOOT_OPTION || + variable == VARIABLE_ID_ADD_BOOT_OPTION || + variable == VARIABLE_ID_BOOT_MANAGER || + variable == VARIABLE_ID_BOOT_NOW || + variable == VARIABLE_ID_LEGACY_DEV_INFO || + variable == VARIABLE_ID_LEGACY_GROUP_INFO || + variable == VARIABLE_ID_BOOT_TIMEOUT || + variable == VARIABLE_ID_BOOT_ORDER || + variable == VARIABLE_ID_AMI_CALLBACK || + variable == VARIABLE_ID_AMITSESETUP || + variable == VARIABLE_ID_ERROR_MANAGER || + variable == VARIABLE_ID_USER_DEFAULTS || + variable == VARIABLE_ID_BBS_ORDER || + variable == VARIABLE_ID_DRIVER_MANAGER || + variable == VARIABLE_ID_DRIVER_ORDER || + variable == VARIABLE_ID_ADD_DRIVER_OPTION || //EIP70421 Support for driver order + variable == VARIABLE_ID_DEL_DRIVER_OPTION || + variable == VARIABLE_ID_IDE_SECURITY) + { + return TRUE; + } + else + { + return FALSE; + } +} + +EFI_HII_PACKAGE_LIST_HEADER * +PreparePackageList ( + IN UINTN NumberOfPackages, + IN EFI_GUID *GuidId, + ... + ); + +#if APTIO_4_00 != 1 && SETUP_USE_GUIDED_SECTION !=1 +// +//---------------------------------------------------------------------------- +// Procedure: InitMiniSetupStrings +// +// Description: +// +// Parameter: VOID +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS InitMiniSetupStrings( VOID ) +{ + EFI_STATUS Status=EFI_SUCCESS; + UINT16 Index = 0; + EFI_HII_PACKAGE_LIST_HEADER *PackageList=NULL; +#ifdef STANDALONE_APPLICATION + EFI_GUID MiniSetupGuid = ENVIRONMENT_VARIABLE_ID ; +#else + EFI_GUID MiniSetupGuid = MINI_SETUP_GUID ; +#endif + Status = HiiInitializeProtocol(); + if ( EFI_ERROR ( Status ) ) + return Status; + + gHiiHandle = HiiFindHandle( &MiniSetupGuid, &Index ); + + if(gHiiHandle != INVALID_HANDLE){ //Remove the previous pack installed with this GUID + Status = gHiiDatabase->RemovePackageList(gHiiDatabase, gHiiHandle); + gHiiHandle = INVALID_HANDLE; + } + + if ( gHiiHandle == INVALID_HANDLE ) + { + PackageList = PreparePackageList ( + 1, + &MiniSetupGuid, + STRING_ARRAY_NAME + ); + if (PackageList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gHiiDatabase->NewPackageList ( + gHiiDatabase, + PackageList, + gImageHandle, + &gHiiHandle + ); + } + + return Status; +} +#endif + + +// +//---------------------------------------------------------------------------- +// Procedure: HiiGetManufactuingMask +// +// Description: +// +// Parameter: VOID +// +// Return value: UINTN +//---------------------------------------------------------------------------- +// +UINTN HiiGetManufactuingMask(VOID) +{ + return AMI_FLAG_MANUFACTURING; +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiGetDefaultMask +// +// Description: +// +// Parameter: VOID +// +// Return value: UINTN +//---------------------------------------------------------------------------- +// +UINTN HiiGetDefaultMask(VOID) +{ + return AMI_FLAG_DEFAULT; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetControlConditionVarId +// +// Description: +// +// Parameter: CONTROL_INFO *controlInfo +// +// Return value: UINT32 +//---------------------------------------------------------------------------- +// +UINT32 GetControlConditionVarId(CONTROL_INFO *controlInfo) +{ + EFI_IFR_OP_HEADER *ifrPtr; + PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[controlInfo->ControlPageID]); + UINTN control = 0; + CONTROL_INFO *CtrlInfo; + BOOLEAN found = FALSE; + EFI_QUESTION_ID QuestionId; + UINT32 varId = 0; + + if ( controlInfo == NULL ) + return 0; + + ifrPtr = (EFI_IFR_OP_HEADER *)controlInfo->ControlConditionalPtr; + + if ( ifrPtr == NULL ) + return 0; + + if ( ( ifrPtr->OpCode != EFI_IFR_SUPPRESS_IF_OP ) && ( ifrPtr->OpCode != EFI_IFR_GRAY_OUT_IF_OP ) ) + return 0; + + ifrPtr = (EFI_IFR_OP_HEADER *)((UINTN)ifrPtr + ifrPtr->Length); + // skip NOT if it is present + if ( ifrPtr->OpCode == EFI_IFR_NOT_OP ) + ifrPtr = (EFI_IFR_OP_HEADER *)((UINTN)ifrPtr + ifrPtr->Length); + + if ( ifrPtr->OpCode == EFI_IFR_EQ_ID_LIST_OP ) + QuestionId = ((EFI_IFR_EQ_ID_LIST *)ifrPtr)->QuestionId; + else if ( ifrPtr->OpCode == EFI_IFR_EQ_ID_VAL_OP ) + QuestionId = ((EFI_IFR_EQ_ID_VAL *)ifrPtr)->QuestionId; + else + return 0; + + if(pageInfo->PageHandle ==0) + return 0; + + for ( control= 0; (control < pageInfo->PageControls.ControlCount) && (found == FALSE); control++ ) + { + CtrlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if(QuestionId == CtrlInfo->ControlKey) + { + varId = CtrlInfo->ControlVariable; + found = TRUE; + } + } + if(!found) + { + // Control Definition not in this Page. Look within the formset + EFI_HII_HANDLE pgHandle = controlInfo->ControlHandle; + UINT32 page = 0; + + for(;page < gPages->PageCount && (found == FALSE); page++) + { + if(page == controlInfo->ControlPageID) + { + continue; + } + pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[page]); + if(pageInfo->PageHandle != pgHandle) + { + continue; + } + + for(control = 0; control < pageInfo->PageControls.ControlCount && (found == FALSE); control++) + { + controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if(QuestionId == controlInfo->ControlKey) + { + varId = controlInfo->ControlVariable; + found = TRUE; + } + } + } + } + + if(!found) + return 0; + + return varId; +} + +// +//---------------------------------------------------------------------------- +// Procedure : ProcessActionQuestionConfiguration +// +// Description : Function to process Action Control Configuration String. +// +// Input : CONTROL_INFO *control +// +// Output : EFI_STATUS +// +//---------------------------------------------------------------------------- +// +EFI_STATUS ProcessActionQuestionConfiguration(CONTROL_INFO *control) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_STRING configuration = NULL; + EFI_STRING progress = NULL; + EFI_IFR_ACTION *UefiAction = NULL; + BOOLEAN PreservegEnableDrvNotification = FALSE; + + if((control == NULL) || (control->ControlPtr == NULL)){ + Status = EFI_UNSUPPORTED; + goto DONE; + } + UefiAction = (EFI_IFR_ACTION*)control->ControlPtr; + + if(UefiAction->Header.Length == sizeof(EFI_IFR_ACTION)) + { + if(UefiAction->QuestionConfig) + { + //Process UefiAction QuestionConfig + configuration = HiiGetString(control->ControlHandle, UefiAction->QuestionConfig); + if((configuration != NULL) && EfiStrLen(configuration)) + { + PreservegEnableDrvNotification = gEnableDrvNotification; + gEnableDrvNotification = TRUE; //EIP75588 Set to enable notification processing + Status = gHiiConfigRouting->RouteConfig(gHiiConfigRouting, configuration, &progress); + if (!PreservegEnableDrvNotification) // If gEnableDrvNotification is already True Don't touch it + gEnableDrvNotification = FALSE; //Reset to disable notification processing + MemFreePointer(&configuration); + } + } + } +DONE: + return Status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: ProcessBrowserActionRequest +// +// Description: +// +// Parameter: EFI_BROWSER_ACTION_REQUEST actionReq +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiVarsetnvramforCurrentform(UINT32 FormID); +EFI_STATUS UefiLoadPreviousValuesforCurrentform(UINT32 FormID); +VOID HotclickESCaction(VOID); +extern BOOLEAN BrowserActionDiscard; +EFI_STATUS ProcessBrowserActionRequest(EFI_BROWSER_ACTION_REQUEST ActionReq) +{ + + switch(ActionReq) + { + case EFI_BROWSER_ACTION_REQUEST_RESET: + // Do nothing. Reset the system. + gApp->Quit = ResetSys(); + break; + case EFI_BROWSER_ACTION_REQUEST_SUBMIT: + //Save values here before exiting. + gApp->Quit = SaveAndExit(); + break; + case EFI_BROWSER_ACTION_REQUEST_EXIT: + //Donot save values. Exit as is. + gApp->Quit = ExitApplication(); + break; + //EIP 86885 : START + //Changes to support new action request form browser + case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT: + UefiVarsetnvramforCurrentform (gApp->CurrentPage) ; + HotclickESCaction(); + break; + case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT: + BrowserActionDiscard = TRUE; + UefiLoadPreviousValuesforCurrentform (gApp->CurrentPage); + HotclickESCaction(); + break; + case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY: + UefiVarsetnvramforCurrentform (gApp->CurrentPage) ; + break; + case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD: + BrowserActionDiscard = TRUE; + UefiLoadPreviousValuesforCurrentform (gApp->CurrentPage); + break; + //EIP 86885 : END + default: + break; + } +// gProFormOffset = 0; //EIP 86885 + CleargProcessedForms (); +// MemSet (gProcessedForms, MAX_FORMS_TO_PROCESS, 0); + + return EFI_SUCCESS; +} + +VOID* UefiGetSpecialEqIDIfrPtr(CONTROL_INFO *ControlInfo, UINT32 *Variable, GUID_INFO **GuidInfo) +{ + VOID *Conditional = ControlInfo->ControlConditionalPtr; + VOID *ControlPtr = ControlInfo->ControlPtr; + EFI_IFR_OP_HEADER * OpHeader = (EFI_IFR_OP_HEADER *)Conditional; + GUID_INFO *specialGuid = NULL; + VARIABLE_INFO *varInfo = NULL; + UINT32 i = 0; + UINT8 InScope = 0; + + if((OpHeader==NULL) || (ControlPtr <= Conditional)) + return NULL; + + if ((OpHeader != NULL) && + ((OpHeader->OpCode == EFI_IFR_SUPPRESS_IF_OP) || + (OpHeader->OpCode == EFI_IFR_GRAY_OUT_IF_OP))) + { + do + { + if(OpHeader->Scope) + { + InScope++; + } + if(OpHeader->OpCode == EFI_IFR_END_OP) + { + InScope--; + if(InScope == 0) + { + // EFI_IFR_EQ_ID_VAL_OP opcode not found + OpHeader = NULL; + goto DONE; + } + } + OpHeader = (EFI_IFR_OP_HEADER*)((UINT8*)OpHeader + OpHeader->Length); + }while((OpHeader->OpCode != EFI_IFR_EQ_ID_VAL_OP) && + (OpHeader->OpCode != EFI_IFR_EQ_ID_LIST_OP)); + } + + if(NoVarStoreSupport()) + { + if(*Variable == VARIABLE_ID_SETUP) + { + *Variable = FindVarFromITKQuestionId(UefiGetEqIDQuestionID(OpHeader)); + } + } + + // Retrieve Special Control Information??? Update with proper comment + varInfo = VarGetVariableInfoIndex( *Variable ); + if( varInfo == NULL ) + { + OpHeader = NULL; + goto DONE; + } + + for ( i = 0; i < gGuidList->GuidCount; i++ ) + { + GUID_INFO *guidInfo = (GUID_INFO *)((UINTN)gGuidList + gGuidList->GuidList[i]); + if ( EfiCompareGuid( &varInfo->VariableGuid, &guidInfo->GuidValue ) ) + { + specialGuid = guidInfo; + break; + } + } + + if ( specialGuid != NULL ) + { + if ( GuidInfo != NULL ) + *GuidInfo = specialGuid; + } + else + { + OpHeader = NULL; + } + + // See if Other condition is Special condition + if(OpHeader == NULL) + { + if(ControlPtr > Conditional) + { + UINTN Offset = _SkipExpression(Conditional); + if(Offset) + { + Conditional = (VOID*)((UINTN)Conditional + Offset); + if(ControlPtr > Conditional) + { + CONTROL_INFO TempCtlInfo; + MemCopy(&TempCtlInfo, ControlInfo, sizeof (CONTROL_INFO)); + TempCtlInfo.ControlConditionalPtr = Conditional; + *Variable = (UINT16)GetControlConditionVarId(&TempCtlInfo); + OpHeader = UefiGetSpecialEqIDIfrPtr(&TempCtlInfo, Variable, GuidInfo) ; + } + } + } + } + +DONE: + return OpHeader; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetSpecialEqIDValue +// +// Description: +// +// Parameter: CONTROL_INFO *ControlInfo, GUID_INFO **GuidInfo +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetSpecialEqIDValue(CONTROL_INFO *ControlInfo, GUID_INFO **GuidInfo) +{ + UINT16 value = (UINT16)-2; + UINT32 condVarID = 0; + EFI_IFR_OP_HEADER *ifrPtr = NULL; + + condVarID = (UINT32)GetControlConditionVarId(ControlInfo); + ifrPtr = (EFI_IFR_OP_HEADER *)UefiGetSpecialEqIDIfrPtr(ControlInfo, &condVarID, GuidInfo); + + if(ifrPtr != NULL) + { + switch(ifrPtr->OpCode) + { + case EFI_IFR_EQ_ID_LIST_OP: + value = ((EFI_IFR_EQ_ID_LIST *)ifrPtr)->ValueList[0]; + break; + case EFI_IFR_EQ_ID_VAL_OP: + value = ((EFI_IFR_EQ_ID_VAL *)ifrPtr)->Value; + break; + default: + break; + } + } + + return value; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiSetEqIDValue +// +// Description: +// +// Parameter: VOID *IfrPtr, UINT16 Value +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiSetEqIDValue(VOID *IfrPtr, UINT16 Value) +{ + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER *)IfrPtr; + + switch(opHeader->OpCode) + { + case EFI_IFR_EQ_ID_LIST_OP: + ((EFI_IFR_EQ_ID_LIST *)IfrPtr)->ValueList[0] = Value; + break; + case EFI_IFR_EQ_ID_VAL_OP: + ((EFI_IFR_EQ_ID_VAL *)IfrPtr)->Value = Value; + break; + default: + break; + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiIsOneOfControl +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN UefiIsOneOfControl(VOID *IfrPtr) +{ + return (((EFI_IFR_OP_HEADER *)IfrPtr)->OpCode == EFI_IFR_ONE_OF_OP)? TRUE : FALSE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiUpdateControlVarOffset +// +// Description: +// +// Parameter: VOID *IfrPtr, UINT16 Value +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiUpdateControlVarOffset(VOID *IfrPtr, UINT16 Value) +{ + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER *)IfrPtr; + + switch(opHeader->OpCode) + { + case EFI_IFR_ONE_OF_OP: + ((EFI_IFR_ONE_OF *)opHeader)->Question.VarStoreInfo.VarOffset = Value; + break; + default: + break; + } +} + + +// +//---------------------------------------------------------------------------- +// Procedure: UefiCreateOneOfWithOptionsTemplate +// +// Description: +// +// Parameter: UINTN OptionCount, CONTROL_INFO *CtrlInfo +// +// Return value: VOID* +//---------------------------------------------------------------------------- +// +VOID* UefiCreateOneOfWithOptionsTemplate(UINTN OptionCount, CONTROL_INFO *CtrlInfo) +{ + VOID *buffer = NULL; + UINTN size = 0; + UINTN length = 0; + UINTN offset; + + offset = (UINTN)CtrlInfo->ControlPtr - (UINTN)CtrlInfo->ControlConditionalPtr; + + size = offset + sizeof(EFI_IFR_ONE_OF) + sizeof(EFI_IFR_OP_HEADER) + + OptionCount * sizeof(EFI_IFR_ONE_OF_OPTION); + buffer = EfiLibAllocateZeroPool(size); + if(buffer == NULL) + { + goto DONE; + } + MemCopy(buffer, CtrlInfo->ControlConditionalPtr, offset); + + length = UefiGetIfrLength(CtrlInfo->ControlPtr); + CtrlInfo->ControlConditionalPtr = buffer; + MemCopy( (UINT8 *)buffer + offset, CtrlInfo->ControlPtr, length ); + CtrlInfo->ControlPtr = (UINT8 *)buffer + offset; + +DONE: + return (UINT8 *)buffer + offset; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiSetOneOfOption +// +// Description: +// +// Parameter: VOID *IfrPtr, UINT64 Value, UINT32 Size, UINT8 Flag, UINT16 Option +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiSetOneOfOption(VOID *IfrPtr, UINT64 Value, UINT32 Size, UINT8 Flag, UINT16 Option) +{ + EFI_IFR_ONE_OF_OPTION *option = (EFI_IFR_ONE_OF_OPTION *)IfrPtr; + UINT8 flag = 0; + + flag |= ((Flag & AMI_FLAG_DEFAULT) == AMI_FLAG_DEFAULT)? EFI_IFR_OPTION_DEFAULT : 0; + flag |= ((Flag & AMI_FLAG_MANUFACTURING) == AMI_FLAG_MANUFACTURING)? EFI_IFR_OPTION_DEFAULT_MFG : 0; + + switch(Size) + { + case sizeof(UINT8): + flag |= EFI_IFR_TYPE_NUM_SIZE_8; + option->Value.u8 = (UINT8)Value; + break; + case sizeof(UINT16): + flag |= EFI_IFR_TYPE_NUM_SIZE_16; + option->Value.u16 = (UINT16)Value; + break; + case sizeof(UINT32): + flag |= EFI_IFR_TYPE_NUM_SIZE_32; + option->Value.u32 = (UINT32)Value; + break; + case sizeof(UINT64): + flag |= EFI_IFR_TYPE_NUM_SIZE_64; + option->Value.u64 = (UINT64)Value; + break; + default: + break; + } + + option->Flags = flag; + option->Option = Option; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiAddEndOp +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiAddEndOp(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER *)IfrPtr; + + opHeader->OpCode = EFI_IFR_END_OP; + opHeader->Length = sizeof(EFI_IFR_OP_HEADER); +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetQuestionID +// +// Description: +// +// Parameter: CONTROL_INFO *Control +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetQuestionID(CONTROL_INFO *Control) +{ + return 0; //(UINT16)GetControlConditionVarId(Control); +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiCreateDynamicControlCondition +// +// Description: +// +// Parameter: CONTROL_INFO *control,UINT16 VarId, UINT16 PrevControlQuestionID,UINT16 Value +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiCreateDynamicControlCondition(CONTROL_INFO *control,UINT16 VarId, UINT16 PrevControlQuestionID,UINT16 Value) +{ + //Add condition here for boot and bbs special controls +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetEqIDQuestionID +// +// Description: +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetEqIDQuestionID(VOID *IfrPtr) +{ + UINT16 questionID = 0; + + return questionID; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiSetEqIDQuestionID +// +// Description: +// +// Parameter: VOID *IfrPtr, UINT16 Value +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiSetEqIDQuestionID(VOID *IfrPtr, UINT16 Value) +{ +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiUpdateControlQuestionID +// +// Description: +// +// Parameter: VOID *IfrPtr, UINT16 Value +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiUpdateControlQuestionID(VOID *IfrPtr, UINT16 Value) +{ + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER *)IfrPtr; + + switch(opHeader->OpCode) + { + case EFI_IFR_ONE_OF_OP: + ((EFI_IFR_ONE_OF *)opHeader)->Question.QuestionId = Value; + break; + default: + break; + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiSpecialGuidCallback +// +// Description: +// +// Parameter: VOID * HiiHandle, UINT16 Key, EFI_GUID *pGUID +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiSpecialGuidCallback(VOID * HiiHandle, UINT16 Key, EFI_GUID *pGUID) +{ + EFI_HANDLE DriverHandle; + EFI_GUID EfiHiiConfigAccessProtocolGuid = EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID; + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; + EFI_IFR_TYPE_VALUE Value; + EFI_BROWSER_ACTION_REQUEST ActionReq; + EFI_STATUS Status; + BOOLEAN PreservegEnableDrvNotification = FALSE; + + Status = gHiiDatabase->GetPackageListHandle(gHiiDatabase,HiiHandle,&DriverHandle); + if(!EFI_ERROR(Status)) + { + Status = gBS->HandleProtocol( DriverHandle, &EfiHiiConfigAccessProtocolGuid , &ConfigAccess ); + if(!EFI_ERROR(Status)) + { + EFI_BROWSER_ACTION action = EFI_BROWSER_ACTION_CHANGED; + + MemSet( &Value, sizeof(Value), 0 ); + Value.u64 = (UINTN)pGUID; + PreservegEnableDrvNotification = gEnableDrvNotification; + gEnableDrvNotification = TRUE; //EIP75588 Set to enable notification processing + Status = ConfigAccess->Callback(ConfigAccess, action,Key,((sizeof(VOID*)==sizeof(UINT32))?EFI_IFR_TYPE_NUM_SIZE_32:EFI_IFR_TYPE_NUM_SIZE_64),&Value,&ActionReq); + if (!PreservegEnableDrvNotification) // If gEnableDrvNotification is already True Don't touch it + gEnableDrvNotification = FALSE; //Reset to disable notification processing + // Clean up PAGE_INFO struct with Handle set to 0xFFFF + Status = FixSetupData(); + if(EFI_ERROR(Status)) + { + } + } + } + +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiSetWidth +// +// Description: +// +// Parameter: VOID *IfrPtr,UINT8 Width +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID UefiSetWidth(VOID *IfrPtr,UINT8 Width) +{ + EFI_IFR_OP_HEADER *OpHeader = (EFI_IFR_OP_HEADER*)IfrPtr; + + switch(OpHeader->OpCode) + { + case EFI_IFR_NUMERIC_OP: + break; + case EFI_IFR_PASSWORD_OP: + break; + case EFI_IFR_STRING_OP: + break; + case EFI_IFR_ONE_OF_OP: + break; + case EFI_IFR_CHECKBOX_OP: + break; + default: + break; + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: BBSUpdateControlOffset +// +// Description: +// +// Parameter: CONTROL_INFO *control +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID BBSUpdateControlOffset(CONTROL_INFO *control) +{ + UINT16 offset= ((EFI_IFR_ONE_OF*)control->ControlPtr)->Question.VarStoreInfo.VarOffset; + + offset = offset +sizeof(UINT32)+sizeof(UINT16); + offset = (UINT16)(offset + gCurrLegacyBootData->LegacyEntryOffset); + + UefiUpdateControlVarOffset(control->ControlPtr, offset); +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetControlDataLength +// +// Description: This function will return width of questions +// +// Parameter: CONTROL_INFO * +// +// Return value: UINTN +//---------------------------------------------------------------------------- +// +UINTN GetControlDataLength(CONTROL_INFO *controlInfo) +{ + UINTN width = 0; + + switch(controlInfo->ControlType) + { + case CONTROL_TYPE_CHECKBOX: + case CONTROL_TYPE_POPUPSEL: + case CONTROL_TYPE_NUMERIC: + case CONTROL_TYPE_PASSWORD: + case CONTROL_TYPE_POPUP_STRING: + width = UefiGetWidth(controlInfo->ControlPtr); + break; + case CONTROL_TYPE_ORDERED_LIST: + width = (((EFI_IFR_ORDERED_LIST*)(controlInfo->ControlPtr))->MaxContainers); + break; + case CONTROL_TYPE_TEXT: + width = sizeof(UINT16); + break; + case CONTROL_TYPE_DATE: + width = sizeof(EFI_HII_DATE); + break; + case CONTROL_TYPE_TIME: + width = sizeof(EFI_HII_TIME); + break; + default: + break; + } + return width; +} + + +//EIP 23354 : Start +// +//---------------------------------------------------------------------------- +// Procedure: IsPasswordEncodeEnabled +// +// Description: Function to return Password Encoding Status. +// +// Input: CONTROL_INFO +// +// Output: TRUE/FALSE +// +//---------------------------------------------------------------------------- +// +BOOLEAN IsPasswordEncodeEnabled (CONTROL_INFO *controlInfo) +{ +//EIP106950 : Starts + extern PASSWORD_ENOCDE_LIST_TEMPLATE gPasswordEncodeList []; + extern UINT32 gEncodeListCount; + UINT32 iIndex = 0; + EFI_GUID tFormsetGuid; + + //Get page info +// PAGE_INFO *pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[controlInfo->ControlPageID]); + + //Get FormsetGuid + GetPageGuidFromPgIndex (controlInfo->ControlPageID, &tFormsetGuid); + + for (iIndex = 0; iIndex < gEncodeListCount; iIndex ++) + { + //If given QuestionId and FormsetGuid is same then return Encoding Flag + if ( (gPasswordEncodeList [iIndex].QuestionID == ((EFI_IFR_PASSWORD *)controlInfo->ControlPtr)->Question.QuestionId) && + (EfiCompareGuid(&gPasswordEncodeList [iIndex].FormsetGuid, &tFormsetGuid) ) + ) + { + return gPasswordEncodeList [iIndex].EncodingFlag; + } + } +//EIP106950 : Ends + + // IDE Password Encode the password + if ( + (VARIABLE_ID_IDE_SECURITY == controlInfo->ControlVariable) || + (VARIABLE_ID_AMITSESETUP == controlInfo->ControlVariable) + ) + { + return TRUE; + } + return FALSE; +} + +//EIP 23354 : End +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetTime +// +// Description: Function to get time +// +// Parameter: CONTROL_INFO *control, EFI_TIME *Tm +// +// Return value: STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiGetTime(CONTROL_INFO *control, EFI_TIME *Tm) +{ + VOID *IfrPtr = NULL ; + UINT8 Flags ; + EFI_STATUS Status = EFI_UNSUPPORTED; + + + if((control != NULL) && (control->ControlPtr != NULL)) + { + IfrPtr = control->ControlPtr; + Flags = UefiGetFlagsField(IfrPtr) ; + + + if( ((Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_TIME)|| + ((Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_TIME) )// EIP 77875 : Incorrect logic used to check Time and Date control types + { + Status = gRT->GetTime( Tm, NULL ); + } + else if( ((Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) || + ((Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) )// EIP 77875 : Incorrect logic used to check Time and Date control types + { + + if(control->ControlType == CONTROL_TYPE_DATE) + { + EFI_HII_DATE *date = NULL ; + + date = EfiLibAllocateZeroPool( sizeof(EFI_HII_DATE) ); + + if ( date != NULL ) + { + Status = VarGetValue( control->ControlVariable, UefiGetQuestionOffset(IfrPtr), UefiGetWidth(IfrPtr), date ); + if ( ! EFI_ERROR( Status ) ) + { + Tm->Month = date->Month ; + Tm->Day = date->Day ; + Tm->Year = date->Year ; + } + + MemFreePointer( (VOID **)&date ); + } + }else{ + EFI_HII_TIME *time = NULL ; + + time = EfiLibAllocateZeroPool( sizeof(EFI_HII_TIME) ); + + if ( time != NULL ) + { + Status = VarGetValue( control->ControlVariable, UefiGetQuestionOffset(IfrPtr), UefiGetWidth(IfrPtr), time ); + Tm->Hour = time->Hour ; + Tm->Minute = time->Minute ; + Tm->Second = time->Second ; + + MemFreePointer( (VOID **)&time ); + } + } + } + else if( ((Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_WAKEUP) || + ((Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_WAKEUP) )// EIP 77875 : Incorrect logic used to check Time and Date control types + { + + BOOLEAN Enabled; + BOOLEAN Pending; + Status = gRT->GetWakeupTime( &Enabled, &Pending, Tm ); + } + } + else + Status = gRT->GetTime( Tm, NULL ); + + return Status ; + +} +// +//---------------------------------------------------------------------------- +// Procedure: UefiSetTime +// +// Description: Function to set time +// +// Parameter: CONTROL_INFO *control, EFI_TIME *Tm +// +// Return value: STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiSetTime(CONTROL_INFO *control, EFI_TIME *Tm) +{ + VOID *IfrPtr = NULL ; + UINT8 Flags = 0; + EFI_STATUS Status = EFI_UNSUPPORTED; + + + if((control != NULL) && (control->ControlPtr != NULL)) + { + IfrPtr = control->ControlPtr; + Flags = UefiGetFlagsField(IfrPtr) ; + + if( ((Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_TIME)|| + ((Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_TIME) )// EIP 77875 : Incorrect logic used to check Time and Date control types + { + Status = gRT->SetTime( Tm ); + } + else if( ((Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) || + ((Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) )// EIP 77875 : Incorrect logic used to check Time and Date control types + { + if(control->ControlType == CONTROL_TYPE_DATE) + { + EFI_HII_DATE *date = NULL ; + EFI_TIME Tc ; + + date = EfiLibAllocateZeroPool( sizeof(EFI_HII_DATE) ); + + if ( date != NULL ) + { +//EIP 47037 : Start + UefiGetTime(control, &Tc); + date->Month = (Tm->Month <= 12)?Tm->Month : ((Tc.Month>12)? 1:Tc.Month) ; + date->Day = (Tm->Day <= 31)?Tm->Day : ((Tc.Day>31)? 1:Tc.Day) ; + date->Year = Tm->Year ; +//EIP 47037 : End + Status = VarSetValue( control->ControlVariable, UefiGetQuestionOffset(IfrPtr), UefiGetWidth(IfrPtr), date ); + + MemFreePointer( (VOID **)&date ); + } + + }else{ + EFI_HII_TIME *time = NULL ; + EFI_TIME Tc ; + + time = EfiLibAllocateZeroPool( sizeof(EFI_HII_TIME) ); + + if ( time != NULL ) + { +//EIP 47037 : Start + UefiGetTime(control, &Tc); + time->Hour = (Tm->Hour <= 23)?Tm->Hour : ((Tc.Hour>23)? 0:Tc.Hour) ; + time->Minute = (Tm->Minute <= 59)? Tm->Minute : ((Tc.Minute>59)? 0:Tc.Minute) ; + time->Second = (Tm->Second <= 59)?Tm->Second : ((Tc.Second>59)? 0:Tc.Second); +//EIP 47037 : End + Status = VarSetValue( control->ControlVariable, UefiGetQuestionOffset(IfrPtr), UefiGetWidth(IfrPtr), time ); + MemFreePointer( (VOID **)&time ); + } + } + } + else if( ((Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_WAKEUP) || + ((Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_WAKEUP) )// EIP 77875 : Incorrect logic used to check Time and Date control types + { + BOOLEAN Enabled = TRUE ; + Status = gRT->SetWakeupTime( Enabled, Tm ); + } + } + else + Status = gRT->SetTime( Tm ); + + + return Status ; + +} +//EIP: 55762 Start +// +//--------------------------------------------------------------------------- +// Procedure: UpdateDestiantionQuestion +// +// Description: Finds the destination question ID for the current destination +// +// Input: UINT32 CurrPageID - Current page ID +// UINT32 DestQuestionId - Destination question ID to set focus +// UINT32 *FocusControlIndex - +// +// Output: EFI_STATUS status - EFI_SUCCESS is successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS UpdateDestiantionQuestion(UINT32 CurrPageID, UINT32 DestQuestionId, UINT32 *FocusControlIndex) +{ + EFI_STATUS status = EFI_NOT_FOUND; + UINT32 j = 0; + + PAGE_INFO *PageInfo = (PAGE_INFO*)((UINTN)gApplicationData + gPages->PageList[CurrPageID]); + + for ( j = 0; j < PageInfo->PageControls.ControlCount; j++ ) + { + CONTROL_INFO *ctrlInfo = (CONTROL_INFO*)(((UINTN)gControlInfo) + PageInfo->PageControls.ControlList [j /*PageInfo->PageIdIndex */]); + if(!ctrlInfo){ + continue; + } + + + if(UefiGetKeyField(ctrlInfo->ControlPtr) == DestQuestionId){ + *FocusControlIndex = j; + status = EFI_SUCCESS; + goto DONE; + } + } + +DONE: + return status; +} +//EIP: 55762 End + +// +//---------------------------------------------------------------------------- +// Procedure: UefiRefershQuestionValueNvRAM +// +// Description: Function to Refresh the questions +// +// Parameter: CONTROL_INFO *ControlData +// +// Return value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiRefershQuestionValueNvRAM(CONTROL_INFO *ControlData) +{ + + + UINT8 * CurBuf=NULL; + UINT8 * NvBuf = NULL; + UINTN VarSize=0; + EFI_STATUS Status=EFI_UNSUPPORTED; + UINT8 Flags = 0; + UINTN offset = UefiGetQuestionOffset(ControlData->ControlPtr); +//EIP-105552 Starts + UINT16 Size = 0;// = UefiGetWidth(ControlData->ControlPtr); + //If the control is Ordered list then we are calculating the actual size + if( CONTROL_TYPE_ORDERED_LIST != ControlData->ControlType) + { + Size = UefiGetWidth(ControlData->ControlPtr); + VarSize = GetControlDataLength(ControlData); + } + else + { + UINTN Type=0; + UINT16 OptionCount = 0; + UINT16 *OptionList=NULL; + UINT64 *ValueList=NULL; + + UefiGetOneOfOptions(ControlData,&ControlData->ControlHandle,&OptionList, &ValueList, &OptionCount,NULL,NULL); + if (OptionList) + MemFreePointer( (VOID **)&(OptionList)); + if (ValueList) + MemFreePointer( (VOID **)&(ValueList)); + + UefiGetValidOptionType( ControlData, &Type, (UINT32 *)&Size); + Size = OptionCount * Size; + VarSize = Size; + + } +//EIP-105552 Ends + NvBuf = VarGetNvramQuestionValue(ControlData->ControlVariable, offset, VarSize); //Read value for specific question + if(NvBuf == NULL){ // No Variable Assosiated then Just refrsh the page + return EFI_SUCCESS; + } + + if((UINTN)(Size) > VarSize){ + goto DONE; + } + + CurBuf = EfiLibAllocateZeroPool(Size); + + switch(ControlData->ControlType) + { + + case CONTROL_TYPE_NUMERIC: + case CONTROL_TYPE_ORDERED_LIST: + case CONTROL_TYPE_POPUPSEL: + case CONTROL_TYPE_POPUP_STRING: + case CONTROL_TYPE_CHECKBOX: + case CONTROL_TYPE_PASSWORD: + VarGetValue( ControlData->ControlVariable, + UefiGetQuestionOffset(ControlData->ControlPtr), Size, CurBuf ); + break; + case CONTROL_TYPE_DATE: + case CONTROL_TYPE_TIME: + Flags = UefiGetFlagsField(ControlData->ControlPtr) ; + if( ((Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) || + ((Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) ) + { + VarGetValue( ControlData->ControlVariable, + UefiGetQuestionOffset(ControlData->ControlPtr), Size, CurBuf ); + } + else + { + // RTC/Wakeup Date/Timecontrol + Status = EFI_SUCCESS; + goto DONE; + } + break; + default: + goto DONE; + } + if(MemCmp((UINT8 *)NvBuf, (UINT8 *)CurBuf, Size)) + { + _VarGetSetValue (VAR_COMMAND_SET_VALUE, gVariableList, ControlData->ControlVariable, UefiGetQuestionOffset (ControlData->ControlPtr), Size, NvBuf); + } + else + { + if(UefiIsInteractive(ControlData)) + Status = CallFormCallBack(ControlData,UefiGetControlKey(ControlData),0,EFI_BROWSER_ACTION_RETRIEVE); + } + + Status = EFI_SUCCESS; +DONE: + + MemFreePointer((VOID**)&CurBuf); + MemFreePointer((VOID**)&NvBuf); + return Status; +} +//EIP:56413: START +// +//---------------------------------------------------------------------------- +// Procedure: UefiGetResetButtonDefaultid +// +// Description: Funtion get the ResetButton Default Id from the Opcode information +// +// Parameter: VOID *IfrPtr +// +// Return value: UINT16 +//---------------------------------------------------------------------------- +// +UINT16 UefiGetResetButtonDefaultid(VOID *IfrPtr) +{ + EFI_IFR_OP_HEADER *OpHeader=(EFI_IFR_OP_HEADER *)IfrPtr; + UINT16 DefaultId = 0xFFFF;//Initializing the default to handle error case + + if(OpHeader->OpCode == EFI_IFR_RESET_BUTTON_OP ) + { + DefaultId = ((EFI_IFR_RESET_BUTTON *)OpHeader)->DefaultId; + return DefaultId; + } +return DefaultId; +} +//EIP:56413: END + +// +//---------------------------------------------------------------------------- +// Procedure: FindDriverHealthDriverName +// +// Description: Finds the driver name which supports driver health protocol +// +// Input: UINT16 = Entry for which driver name has to be return +// +// Output: CHAR16 * = Driver Name +// +//---------------------------------------------------------------------------- +// +CHAR16 *FindDriverHealthDriverName (UINT16 DriverEntry) +{ + EFI_STATUS Status, StatusforGetHealth = EFI_UNSUPPORTED; +// EFI_GUID DriverHealthProtocolGuid = EFI_DRIVER_HEALTH_PROTOCOL_GUID; + EFI_HANDLE *DriverHealthHandles; + UINTN NumHandles = 0, iIndex = 0; + UINTN Count = 0; + CHAR16 *DriverName = NULL, *DrvNameWithStatus; + EFI_GUID EfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID; + EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 = NULL; + EFI_DRIVER_HEALTH_PROTOCOL *DrvHealthInstance = NULL; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DRIVER_HEALTH_STATUS HealthStatus = EfiDriverHealthStatusHealthy; + EFI_GUID EfiDriverHealthProtocolGuid = EFI_DRIVER_HEALTH_PROTOCOL_GUID; + + CHAR8 *LangStrings = (CHAR8 *)NULL; + CHAR8 *tempLangStrings = (CHAR8 *)NULL; + CHAR8 Lang[200]; + + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &EfiDriverHealthProtocolGuid, + NULL, + &NumHandles, + &DriverHealthHandles + ); + if ((Status != EFI_SUCCESS) || (NumHandles == 0)) + { + return NULL; + } + for (iIndex = 0; iIndex < NumHandles; iIndex ++) + { + Status = gBS->HandleProtocol (DriverHealthHandles [iIndex], &EfiDriverHealthProtocolGuid, &DrvHealthInstance); + if (EFI_ERROR (Status)) + { + continue; + } + if (Count != DriverEntry) + { + Count ++; + continue; + } + StatusforGetHealth = DrvHealthInstance->GetHealthStatus (DrvHealthInstance, NULL, NULL, &HealthStatus, NULL, NULL); + Status = gBS->HandleProtocol (DriverHealthHandles [iIndex], &EfiComponentName2ProtocolGuid, &ComponentName2); + if (EFI_ERROR (Status)) + { + break; + } + //EIP 134138 + LangStrings = StrDup8( ComponentName2->SupportedLanguages ); + tempLangStrings = LangStrings; //Ptr will be incremented in _GetNextLanguage so taking backup for freeing + _GetNextLanguage (&LangStrings, Lang); + + Status = ComponentName2->GetDriverName ( + ComponentName2, + Lang, + //ComponentName2->SupportedLanguages, + &DriverName + ); + + MemFreePointer( (VOID **)&tempLangStrings ); + + if ((EFI_ERROR (Status)) || (NULL == DriverName)) + { + break; + } + if (!EFI_ERROR (StatusforGetHealth)) + { + DrvNameWithStatus = EfiLibAllocateZeroPool ((EfiStrLen (DriverName) + EfiStrLen (DriverHealthStatus [HealthStatus]) + 7) * sizeof (CHAR16)); //7 for spaces and NULL character + if (NULL != DrvNameWithStatus) + { + SPrint ( + DrvNameWithStatus, + ((EfiStrLen (DriverName) + EfiStrLen (DriverHealthStatus [HealthStatus]) + 7) * sizeof (CHAR16)), + L"%s %s", + DriverName, + DriverHealthStatus [HealthStatus] + ); + MemFreePointer ((VOID **)&DriverHealthHandles); + return DrvNameWithStatus; + } + } + goto DONE; + } + if (iIndex == NumHandles) + { + goto DONE; + } + if (!DriverName) + { + Status = gBS->HandleProtocol (DriverHealthHandles [iIndex], &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath); + if (!EFI_ERROR (Status)) + { + DriverName = _DevicePathToStr (DevicePath); + if (!EFI_ERROR (StatusforGetHealth)) + { + DrvNameWithStatus = EfiLibAllocateZeroPool ((EfiStrLen (DriverName) + EfiStrLen (DriverHealthStatus [HealthStatus]) + 7) * sizeof (CHAR16)); //7 for spaces and NULL character + if (NULL != DrvNameWithStatus) + { + SPrint ( + DrvNameWithStatus, + ((EfiStrLen (DriverName) + EfiStrLen (DriverHealthStatus [HealthStatus]) + 7) * sizeof (CHAR16)), + L"%s %s", + DriverName, + DriverHealthStatus [HealthStatus] + ); + MemFreePointer ((VOID **)&DriverHealthHandles); + return DrvNameWithStatus; + } + } + } + else + { + DriverName = EfiLibAllocateZeroPool (30 * sizeof (CHAR16)); //This case will be helpfull when driver name or device path not present + SPrint ( + DriverName, + (30 * sizeof (CHAR16)), + L"Driver At Handle %x", + DriverHealthHandles [iIndex] + ); + } + } +DONE: + MemFreePointer ((VOID **)&DriverHealthHandles); + return DriverName; +} + +// +//----------------------------------------------------------------------------------------------------- +// Procedure: CtrlsSupportsHealthProtocol +// +// Description: Finds the number of controllers supports driver health protocol for the driver entry +// +// Input: UINT16 = Entry for driver to which total controllers has to be find +// +// Output: UINT16 = Total number of controllers supports driver health +// +//----------------------------------------------------------------------------------------------------- +// +UINT16 CtrlsSupportsHealthProtocol (UINT16 EntryItem) +{ + EFI_STATUS Status; + EFI_HANDLE *Handles; + UINTN NumHandles = 0; + UINT16 ControllerCnt = 0, Count = 0; + EFI_HANDLE *DriverHealthHandles; + UINTN DriverHealthIndex; + UINTN ControllerIndex = 0; + UINTN HandleCount = 0; + UINTN ChildIndex = 0; + EFI_DRIVER_HEALTH_PROTOCOL *DriverHealth; + EFI_DRIVER_HEALTH_STATUS HealthStatus; + EFI_GUID EfiDriverHealthProtocolGuid = EFI_DRIVER_HEALTH_PROTOCOL_GUID; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &EfiDriverHealthProtocolGuid, + NULL, + &NumHandles, + &DriverHealthHandles + ); + if ((EFI_ERROR (Status)) || (NumHandles == 0)) + { + return ControllerCnt; + } + for (DriverHealthIndex = 0; DriverHealthIndex < NumHandles; DriverHealthIndex++) + { + if (DriverHealthHandles [DriverHealthIndex] == NULL) + { + continue; + } + Status = gBS->HandleProtocol ( + DriverHealthHandles [DriverHealthIndex], + &EfiDriverHealthProtocolGuid, + (VOID **)&DriverHealth + ); + if (EFI_ERROR (Status)) + { + continue; + } + if (EntryItem > Count) + { + Count ++; + continue; + } + gDrvHandle = DriverHealthHandles [DriverHealthIndex]; + gDrvHealthInstance = DriverHealth; + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &HandleCount, + &Handles + ); + if (EFI_ERROR (Status)) + { + MemFreePointer ((VOID **)&DriverHealthHandles); + return ControllerCnt; + } + for (ControllerIndex = 0; ControllerIndex < HandleCount; ControllerIndex ++) + { + if (NULL == Handles [ControllerIndex]) + { + continue; + } + Status = DriverHealth->GetHealthStatus (DriverHealth, Handles [ControllerIndex], NULL, &HealthStatus, NULL, NULL); + if (EFI_ERROR (Status)) + { + continue; + } + AddHandleIntoList (Handles [ControllerIndex], NULL, HealthStatus); + ControllerCnt ++; + for (ChildIndex = 0; ChildIndex < HandleCount; ChildIndex++) + { + if (Handles [ChildIndex] == NULL) + { + continue; + } + Status = DriverHealth->GetHealthStatus (DriverHealth, Handles [ControllerIndex], Handles [ChildIndex], &HealthStatus, NULL, NULL); + if (EFI_ERROR (Status)) + { + continue; + } + AddHandleIntoList (Handles [ControllerIndex], Handles [ChildIndex], HealthStatus); + ControllerCnt ++; + } + } + break; + } + MemFreePointer ((VOID **)&DriverHealthHandles); + return ControllerCnt; +} + +// +//---------------------------------------------------------------------------------- +// Procedure: GetCtrlNameAndHealth +// +// Description: Finds the controller name with its health +// +// Input: UINT16 = Entry for controller to which name has to be find +// +// Output: CHAR16 * = Controller name with its health status +// +//----------------------------------------------------------------------------------- +// +CHAR16 *GetCtrlNameAndHealth (UINT16 ControllerEntry) +{ + UINT16 Count = 0; + CHAR16 *ContrNameAndHlth = NULL; + DRV_HEALTH_HNDLS *DrvHlthHandles = NULL; + + + DrvHlthHandles = gDrvHealthHandlesHead; + while (Count != ControllerEntry) + { + DrvHlthHandles = DrvHlthHandles->Next; + Count ++; + } + ContrNameAndHlth = GetDrvHlthCtrlName (DrvHlthHandles); + return ContrNameAndHlth; +} + +// +//---------------------------------------------------------------------------------- +// Procedure: GetDrvHlthCtrlName +// +// Description: Finds the controller name +// +// Input: DRV_HEALTH_HNDLS * = Details for finding the controller name +// +// Output: CHAR16 * = Controller name for the controller and child handle +// +//----------------------------------------------------------------------------------- +// +CHAR16 *GetDrvHlthCtrlName (DRV_HEALTH_HNDLS *DrvHlthHandles)// EFI_HANDLE DriverHealth, EFI_HANDLE ControllerHandle, EFI_HANDLE ChildHandle) +{ + EFI_STATUS Status = EFI_SUCCESS; + CHAR16 *CtrlName = NULL; + CHAR16 *ContrNameAndHlth = NULL; + EFI_GUID EfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID; + EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 = NULL; + EFI_DRIVER_HEALTH_STATUS HealthStatus = EfiDriverHealthStatusHealthy; //EIP 134138 + + Status = gDrvHealthInstance->GetHealthStatus ( //If controllers reconnected status might change so getting the status again + gDrvHealthInstance, + DrvHlthHandles->ControllerHandle, + DrvHlthHandles->ChildHandle, + &HealthStatus, + NULL, + NULL + ); + if (EFI_ERROR (Status)) + { + return NULL; + } + DrvHlthHandles->HealthStatus = HealthStatus; + Status = gBS->HandleProtocol ( + gDrvHandle, + &EfiComponentName2ProtocolGuid, + (VOID **)&ComponentName2 + ); + if (!EFI_ERROR (Status)) + { + Status = ComponentName2->GetControllerName (ComponentName2, DrvHlthHandles->ControllerHandle, DrvHlthHandles->ChildHandle, ComponentName2->SupportedLanguages, &CtrlName); + if (EFI_ERROR (Status)) + { + CtrlName = NULL; + } + } + if (NULL == CtrlName) + { + CtrlName = EfiLibAllocateZeroPool (50 * sizeof (CHAR16)); //16+16+"DriverName" + if (NULL == CtrlName) + { + return NULL; + } + SPrint (CtrlName, 50 * sizeof (CHAR16), L"Controller %x Child %x", DrvHlthHandles->ControllerHandle, DrvHlthHandles->ChildHandle); + } + ContrNameAndHlth = EfiLibAllocateZeroPool ((EfiStrLen (CtrlName) + EfiStrLen (DriverHealthStatus [HealthStatus]) + 7) * sizeof (CHAR16)); //7 for spaces and NULL char. + if (NULL == ContrNameAndHlth) + { + return NULL; + } + SPrint ( + ContrNameAndHlth, + ((EfiStrLen (CtrlName) + EfiStrLen (DriverHealthStatus [HealthStatus]) + 7) * sizeof (CHAR16)), + L"%s %s", + CtrlName, + DriverHealthStatus [HealthStatus] + ); + return ContrNameAndHlth; +} + +// +//----------------------------------------------------------------------------------------------------- +// Procedure: AddHandleIntoList +// +// Description: Adds the driver health details to the linked list +// +// Input: EFI_HANDLE = Controller handle +// EFI_HANDLE = Child handle +// EFI_DRIVER_HEALTH_STATUS = Health status corresponding to controller and child handle +// +// Output: VOID +// +//------------------------------------------------------------------------------------------------------ +// +VOID AddHandleIntoList (EFI_HANDLE ControllerHandle, EFI_HANDLE ChildHandle, EFI_DRIVER_HEALTH_STATUS HealthStatus) +{ + DRV_HEALTH_HNDLS *DrvHealthHandles; + DRV_HEALTH_HNDLS *tempHealthHandle; + + DrvHealthHandles = EfiLibAllocateZeroPool (sizeof (DRV_HEALTH_HNDLS)); + if (NULL == DrvHealthHandles) + { + return; + } + DrvHealthHandles->ControllerHandle = ControllerHandle; + DrvHealthHandles->ChildHandle = ChildHandle; + DrvHealthHandles->HealthStatus = HealthStatus; + DrvHealthHandles->Next = NULL; + if (NULL == gDrvHealthHandlesHead) + { + gDrvHealthHandlesHead = DrvHealthHandles; + return; + } + tempHealthHandle = gDrvHealthHandlesHead; + while (tempHealthHandle->Next) + { + tempHealthHandle = tempHealthHandle->Next; + } + tempHealthHandle->Next = DrvHealthHandles; +} + +// +//---------------------------------------------------------------------------------- +// Procedure: FreeControllersList +// +// Description: Frees the driver health details linked list +// +// Input: VOID +// +// Output: VOID +// +//----------------------------------------------------------------------------------- +// +VOID FreeControllersList (VOID) +{ + DRV_HEALTH_HNDLS *DrvHealthHandles, *tempDrvHealthHandles; + + if (!gDrvHealthHandlesHead) + { + return; + } + DrvHealthHandles = gDrvHealthHandlesHead; + while (DrvHealthHandles) + { + tempDrvHealthHandles = DrvHealthHandles; + DrvHealthHandles = DrvHealthHandles->Next; + MemFreePointer ((VOID **)&tempDrvHealthHandles); + } +} + +// +//------------------------------------------------------------------------------------------- +// Procedure: SetDrvHealthHandleAndCtrlCount +// +// Description: Finds and sets the number of controllers supports the driver health handle +// +// Input: UINT16 = Driver health handle entry +// +// Output: VOID +// +//-------------------------------------------------------------------------------------------- +// +VOID SetDrvHealthHandleAndCtrlCount (UINT16 ItemEntry) +{ + UINTN TotControllers = 0; + EFI_GUID DrvHealthCtrlGuid = AMITSE_DRIVER_HEALTH_CTRL_GUID; + + FreeControllersList (); + gDrvHealthHandlesHead = NULL; + + TotControllers = CtrlsSupportsHealthProtocol (ItemEntry); + VarSetNvramName (L"DrvHealthCtrlCnt", &DrvHealthCtrlGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &TotControllers, sizeof (UINTN)); +} + +//EIP57661 Starts +// +//---------------------------------------------------------------------------- +// Procedure: SetDriverHealthCount +// +// Description: Sets the DriverHealthCount and DriverHlthEnable variables +// +// Input: VOID +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID SetDriverHealthCount (VOID) +{ + EFI_STATUS Status; + EFI_GUID DriverHealthProtocolGuid = EFI_DRIVER_HEALTH_PROTOCOL_GUID; + EFI_HANDLE *DriverHealthHandles = NULL; + UINTN NumHandles = 0, iIndex = 0, HealthCount = 0; + EFI_GUID DrvHealthGuid = AMITSE_DRIVER_HEALTH_GUID; + EFI_GUID DrvHlthEnableGuid = AMITSE_DRIVER_HEALTH_ENB_GUID; + EFI_DRIVER_HEALTH_PROTOCOL *DrvHealthInstance = NULL; + + SETUP_DEBUG_UEFI ( "\n[TSE] Entering SetDriverHealthCount()\n" ); + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &DriverHealthProtocolGuid, + NULL, + &NumHandles, + &DriverHealthHandles + ); + if (EFI_SUCCESS != Status) + { + NumHandles = 0; + } + for (iIndex = 0; iIndex < NumHandles; iIndex ++) + { + Status = gBS->HandleProtocol (DriverHealthHandles [iIndex], &DriverHealthProtocolGuid, &DrvHealthInstance); + if (EFI_ERROR (Status)) + { + continue; + } + HealthCount ++; + } + if (NumHandles) + { + MemFreePointer ((VOID **)&DriverHealthHandles); + } + VarSetNvramName (L"DriverHealthCount", &DrvHealthGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &HealthCount, sizeof (UINTN)); + VarUpdateVariable (VARIABLE_ID_DRV_HLTH_COUNT); //Update NVRAM cache for DriverHealthCount + HealthCount = HealthCount ? 1 : 0; //To enable driver health root menu + VarSetNvramName (L"DriverHlthEnable", &DrvHlthEnableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &HealthCount, sizeof (UINTN)); + VarUpdateVariable (VARIABLE_ID_DRV_HLTH_ENB); //Update NVRAM cache for DriverHlthEnable + SETUP_DEBUG_UEFI ( "\n[TSE] Exiting SetDriverHealthCount()\n" ); +} + +// +//------------------------------------------------------------------------------------------- +// Procedure: DisplayMsgListMessageBox +// +// Description: Displays the messages from EFI_DRIVER_HEALTH_HII_MESSAGE +// +// Input: EFI_DRIVER_HEALTH_HII_MESSAGE * = Message to show +// +// Output: VOID +// +//-------------------------------------------------------------------------------------------- +// +VOID DisplayMsgListMessageBox (EFI_DRIVER_HEALTH_HII_MESSAGE *MessageList) +{ + CHAR16 *DisplayString = NULL; + CHAR16 *String = NULL; + UINT8 Count = 0; + UINT8 MsgBoxSel = 0; + EFI_STATUS Status = EFI_SUCCESS; + + while (MessageList [Count].HiiHandle) + { + String = HiiGetString (MessageList [Count].HiiHandle, MessageList [Count].StringId); + Count ++; + if (Count > 15) //Checking for safe termination, otherwise msgbox fill the full screen + { + break; + } + if (String) + { + if (!DisplayString) + { + DisplayString = EfiLibAllocateZeroPool ((EfiStrLen (String) + 2) * sizeof (CHAR16)); //2 for /n and NULL character + } + else + { + DisplayString = MemReallocateZeroPool ( + DisplayString, + ( (EfiStrLen (DisplayString) + 1) * sizeof (CHAR16) ), + ( ((EfiStrLen (String) + 2) * sizeof (CHAR16)) + ((EfiStrLen (DisplayString) + 1) * sizeof (CHAR16)) ) //2 for /n and NULL character + ); + } + if (NULL == DisplayString) + { + MemFreePointer ((VOID **)&String); + continue; + } + if (DisplayString [0]) + { + EfiStrCat (DisplayString, String); + EfiStrCat (DisplayString, L"\n"); + } + else + { + EfiStrCpy (DisplayString, String); + EfiStrCat (DisplayString, L"\n"); + } + } + } + if (DisplayString) + { + CHAR16 *text = NULL; + text = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DRV_HLTH_TITLE)); + Status = mPostMgr->DisplayMsgBox ( + text, + DisplayString, + MSGBOX_TYPE_OK, + &MsgBoxSel + ); + if(EFI_ERROR (Status)) + return; + + MemFreePointer ((VOID **)&DisplayString); + if (text) + { + MemFreePointer ((VOID **)&text); + } + } +} + +// +//------------------------------------------------------------------------------------------- +// Procedure: DoDriverHealthOperation +// +// Description: Performs the driver health operations for the corresponding controller entry +// +// Input: VOID * = Control Info for the correponding controller entry +// UINT16 = Controller entry in the page +// +// Output: VOID +// +//-------------------------------------------------------------------------------------------- +// +VOID DoDriverHealthOperation (VOID *Tempcontrol, UINT16 ControllerEntry) +{ + UINT16 Count = 0; + EFI_STATUS Status = EFI_SUCCESS; + DRV_HEALTH_HNDLS *DrvHlthHandles = NULL; + EFI_DRIVER_HEALTH_STATUS LocalHealthStatus = EfiDriverHealthStatusHealthy; + EFI_DRIVER_HEALTH_HII_MESSAGE *MessageList = NULL; + EFI_HII_HANDLE FormHiiHandle; + UINT8 MsgBoxSel = 0; + CONTROL_INFO *control = (CONTROL_INFO *)Tempcontrol; + + if(!mPostMgr) + { + //Loacate Post Manager Protocol + Status = gBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL,(void**) &mPostMgr); + if(Status != EFI_SUCCESS) + return; + } + + DrvHlthHandles = gDrvHealthHandlesHead; + while (Count != ControllerEntry) + { + DrvHlthHandles = DrvHlthHandles->Next; + Count ++; + } + if (EfiDriverHealthStatusHealthy == DrvHlthHandles->HealthStatus) + { + Status = gDrvHealthInstance->GetHealthStatus ( + gDrvHealthInstance, + DrvHlthHandles->ControllerHandle, + DrvHlthHandles->ChildHandle, + &LocalHealthStatus, + &MessageList, + &FormHiiHandle + ); + if (NULL != MessageList) + { + DisplayMsgListMessageBox (MessageList); + } + } + if (EfiDriverHealthStatusRepairRequired == DrvHlthHandles->HealthStatus) + { + Status = gDrvHealthInstance->Repair ( + gDrvHealthInstance, + DrvHlthHandles->ControllerHandle, + DrvHlthHandles->ChildHandle, + NULL + ); + if (!EFI_ERROR (Status)) + { + Status = gDrvHealthInstance->GetHealthStatus ( + gDrvHealthInstance, + DrvHlthHandles->ControllerHandle, + DrvHlthHandles->ChildHandle, + &LocalHealthStatus, + &MessageList, + &FormHiiHandle + ); + if (NULL != MessageList) + { + DisplayMsgListMessageBox (MessageList); + } + } + } + if ((EfiDriverHealthStatusConfigurationRequired == DrvHlthHandles->HealthStatus) || + (EfiDriverHealthStatusConfigurationRequired == LocalHealthStatus)) + { + UINT32 i=0; + PAGE_INFO *pageInfo; + if (EfiDriverHealthStatusConfigurationRequired != LocalHealthStatus) + { + Status = gDrvHealthInstance->GetHealthStatus ( + gDrvHealthInstance, + DrvHlthHandles->ControllerHandle, + DrvHlthHandles->ChildHandle, + &LocalHealthStatus, + &MessageList, + &FormHiiHandle + ); + } + if (!EFI_ERROR (Status) && (FormHiiHandle)) + { + if (NULL != MessageList) + { + DisplayMsgListMessageBox (MessageList); + } + for (i = 0; i < gPages->PageCount; i++) + { + pageInfo = (PAGE_INFO *)((UINTN)gApplicationData + gPages->PageList[i]); + if (pageInfo->PageHandle == FormHiiHandle) + { + PAGE_DATA **page; //To display the configuration page in advanced menu itself + + control->ControlDestPageID = i; + pageInfo->PageFlags.PageVisible = FALSE; + pageInfo->PageParentID = control->ControlPageID; + + //For ESA gApp will be NULL but for TSE gApp will be not-NULL + if(gApp) + { + page = &gApp->PageList [pageInfo->PageID]; + gPage.Destroy (*page, FALSE); + gPage.Initialize (*page, pageInfo); + gApp->CurrentPage = i; + } + break; + } + } + } + } + if (EfiDriverHealthStatusFailed == DrvHlthHandles->HealthStatus) + { + Status = gDrvHealthInstance->GetHealthStatus ( + gDrvHealthInstance, + DrvHlthHandles->ControllerHandle, + DrvHlthHandles->ChildHandle, + &LocalHealthStatus, + &MessageList, + &FormHiiHandle + ); + if ((!EFI_ERROR (Status)) && (NULL != MessageList)) + { + DisplayMsgListMessageBox (MessageList); + } + } + if (EfiDriverHealthStatusReconnectRequired == DrvHlthHandles->HealthStatus) + { + CHAR16 *Title = NULL; + CHAR16 *Message = NULL; + + Title = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DRV_HLTH_TITLE)); + Message = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DRV_HLTH_RECON)); + Status = mPostMgr->DisplayMsgBox ( + Title, + Message, + MSGBOX_TYPE_OKCANCEL, + &MsgBoxSel + ); + if(EFI_ERROR (Status)) + return; + + if (0 == MsgBoxSel) //User pressed OK + { + gBS->DisconnectController (DrvHlthHandles->ControllerHandle, NULL, NULL); + gBS->ConnectController (DrvHlthHandles->ControllerHandle, NULL, NULL, TRUE); + } + } + if (EfiDriverHealthStatusRebootRequired == DrvHlthHandles->HealthStatus) + { + CHAR16 *Title = NULL; + CHAR16 *Message = NULL; + + Title = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DRV_HLTH_TITLE)); + Message = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DRV_HLTH_REBOOT)); + Status = mPostMgr->DisplayMsgBox ( + Title, + Message, + MSGBOX_TYPE_OKCANCEL, + &MsgBoxSel + ); + if(EFI_ERROR (Status)) + return; + + if (0 == MsgBoxSel) //User pressed OK + { + DrvHlthHandles = gDrvHealthHandlesHead; + while (DrvHlthHandles) + { + //Proceed with repair for all the controllers in repair state + if (EfiDriverHealthStatusRepairRequired == DrvHlthHandles->HealthStatus) + { + Status = gDrvHealthInstance->Repair ( + gDrvHealthInstance, + DrvHlthHandles->ControllerHandle, + DrvHlthHandles->ChildHandle, + NULL + ); + } + DrvHlthHandles = DrvHlthHandles->Next; + } + FreeControllersList (); + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + } + } +} + +// +//--------------------------------------------------------------------------- +// Procedure: CheckTimeFlags +// +// Description: Function to check the time flags. +// +// Input: UINT16 ItemCount +// +// Output: VOID +//--------------------------------------------------------------------------- +// +BOOLEAN CheckTimeFlags(UINT8 Flags) +{ + return ((Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) ; +} + +// +//--------------------------------------------------------------------------- +// Procedure: CheckDateFlags +// +// Description: Function to check the date flags. +// +// Input: UINT16 ItemCount +// +// Output: VOID +//--------------------------------------------------------------------------- +// +BOOLEAN CheckDateFlags(UINT8 Flags) +{ + return ((Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL); +} + +//EIP75481 Support TSE debug print infrastructure +// +//--------------------------------------------------------------------------- +// Procedure: CreateFile +// +// Description: Creates a file to output hpk data +// +// Input: CHAR16 *filenameFormat, +// EFI_HII_HANDLE *Handle, +// UINTN Index +// +// +// Output: EFI_FILE_PROTOCOL* +//--------------------------------------------------------------------------- +// +EFI_FILE_PROTOCOL * CreateFile(CHAR16 *filename, UINT32 index) +{ + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pSFP; + EFI_STATUS Status = EFI_SUCCESS; + EFI_FILE_PROTOCOL *pRoot,*FileHandle; + EFI_HANDLE *gSmplFileSysHndlBuf = NULL; + UINTN Count = 0; + UINT16 i = 0; + + // Locate all the simple file system devices in the system + Status = pBS->LocateHandleBuffer(ByProtocol, &guidSimpleFileSystemProtocol, NULL, &Count, &gSmplFileSysHndlBuf); + + if(!EFI_ERROR(Status)) + { + Status = gBS->HandleProtocol( gSmplFileSysHndlBuf[index], &guidSimpleFileSystemProtocol, &pSFP ); + + if (!EFI_ERROR(Status)) + { + Status = pSFP->OpenVolume(pSFP,&pRoot); + + if (!EFI_ERROR(Status)) + { + Status = pRoot->Open(pRoot, + &FileHandle, + filename, + EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, + 0); + + pRoot->Close(pRoot); + + if (!EFI_ERROR(Status)) + { + return FileHandle; + } + } + } + } + + if(gSmplFileSysHndlBuf != NULL) + pBS->FreePool(gSmplFileSysHndlBuf); + + return NULL; +} + +// +//--------------------------------------------------------------------------- +// Procedure: WriteDataToFile +// +// Description: Writes data to file +// +// Input: CHAR16 *filename, VOID *Data, UINTN length +// +// +// Output: VOID +//--------------------------------------------------------------------------- +// +EFI_STATUS WriteDataToFile(CHAR16 *filename, VOID *Data, UINTN length, UINT32 index) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + EFI_FILE_PROTOCOL *FileHandle=NULL; + + UINTN len = length; + + SETUP_DEBUG_UEFI_NOTIFICATION( "\n\n[TSE] Entering WriteDataToFile \n\n"); + + if (Data == NULL) + { + goto DONE; + } + + FileHandle = CreateFile(filename, index); + + if (FileHandle != NULL) + { + FileHandle->SetPosition(FileHandle,0); + FileHandle->Write(FileHandle,&len, Data); + FileHandle->Close(FileHandle); + Status = EFI_SUCCESS ; + + SETUP_DEBUG_UEFI_NOTIFICATION( "\n\n[TSE] Exporting Filename: %s \n\n", filename); + } +DONE: + + SETUP_DEBUG_UEFI_NOTIFICATION( "\n\n[TSE] Exiting WriteDataToFile, Status: %x \n\n", Status); + + return Status ; +} + +#if TSE_DEBUG_MESSAGES +// +//--------------------------------------------------------------------------- +// Procedure: HiiGetPackList +// +// Description: Get HII form package by handle and form ID +// +// Input: EFI_HII_HANDLE Handle +// UINT16 form +// UINTN *Length +// +// Output: VOID *formPkBuffer - +//--------------------------------------------------------------------------- +// +VOID *HiiGetPackList( EFI_HII_HANDLE Handle, UINT16 form, UINTN *Length ) +{ + EFI_STATUS status = EFI_SUCCESS; + VOID *hiiFormPackage=NULL; + UINTN len=10; + + if(Length == NULL) + Length = &len; + + hiiFormPackage = EfiLibAllocateZeroPool(*Length); + + status = gHiiDatabase->ExportPackageLists(gHiiDatabase, Handle, Length, hiiFormPackage); + if(status == EFI_BUFFER_TOO_SMALL) + { + MemFreePointer(&hiiFormPackage); + // + // Allocate space for retrieval of IFR data + // + hiiFormPackage = EfiLibAllocateZeroPool(*Length); + + if (hiiFormPackage == NULL) + { + hiiFormPackage = NULL; + goto DONE; + } + // + // Get all the packages associated with this HiiHandle + // + status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, Length, hiiFormPackage); + if(EFI_ERROR(status)) + { + MemFreePointer(&hiiFormPackage); + hiiFormPackage = NULL; + } + } + else if(EFI_ERROR(status)) + { + hiiFormPackage = NULL; + } + +DONE: + return hiiFormPackage; +} + +// +//--------------------------------------------------------------------------- +// Procedure: ProcessPackToFile +// +// Description: Prints the HPK data to file +// +// Input: EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, EFI_HANDLE Handle +// +// +// Output: VOID +//--------------------------------------------------------------------------- +// +VOID ProcessPackToFile(EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, EFI_HANDLE Handle) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + CHAR16 *filenameFormat = NULL; + CHAR16 filename[50]; + VOID *formSetData = NULL; + UINTN length = 0; + + SETUP_DEBUG_UEFI_NOTIFICATION( "\n\n[TSE] Entering ProcessPackToFile \n\n"); + + + if(NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) + filenameFormat = L"REMOVED_0x%x_%03d.hpk" ; + + else if(NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK) + filenameFormat = L"NEW_0x%x_%03d.hpk" ; + + else if(NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) + filenameFormat = L"UPDATE_0x%x_%03d.hpk" ; + + else + goto DONE ; + + + formSetData = (UINT8*)HiiGetPackList(Handle, 0, &length); + + if (formSetData == NULL) + { + goto DONE; + } + + SPrint(filename, 50, filenameFormat, Handle, HpkFileCount); + + Status = WriteDataToFile(filename, formSetData, length, 0) ; + + if (!EFI_ERROR (Status)) + { + HpkFileCount++ ; + } + +DONE: + + SETUP_DEBUG_UEFI_NOTIFICATION( "\n\n[TSE] Exiting ProcessPackToFile, Status: %x \n\n", Status); +} +// +//--------------------------------------------------------------------------- +// Procedure: WritePackToFile +// +// Description: Writes Hpk data to file +// +// Input: CHAR16 *filenameFormat, EFI_HANDLE Handle, UINT8 *PackData, UINTN length +// +// +// Output: VOID +//--------------------------------------------------------------------------- +// +EFI_STATUS WritePackToFile(CHAR16 *filenameFormat, EFI_HANDLE Handle, UINT8 *PackData, UINTN length) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + EFI_FILE_PROTOCOL *FileHandle=NULL; + UINT8 *formSet = PackData; + UINTN len = length; + CHAR16 filename[50]; + + SETUP_DEBUG_UEFI_NOTIFICATION( "\n\n[TSE] Entering WritePackToFile \n\n"); + + if(formSet == NULL) + { + formSet = (UINT8*)HiiGetPackList(Handle, 0, &len); + if (formSet == NULL) + { + goto DONE; + } + } + + SPrint(filename, 50, filenameFormat, Handle, HpkFileCount); + + Status = WriteDataToFile(filename, formSet, length,0) ; + + if (!EFI_ERROR (Status)) + { + HpkFileCount++ ; + } + +DONE: + + SETUP_DEBUG_UEFI_NOTIFICATION( "\n\n[TSE] Exiting WritePackToFile, Status: %x \n\n", Status); + + return Status ; +} +// +//--------------------------------------------------------------------------- +// Procedure: DebugShowBufferContent +// +// Description: Prints the buffer, 16 characters max in a line +// +// Input: UINTN bufSize - Buffer length to print +// VOID *buffer - Buffer to print +// +// Output: VOID +//--------------------------------------------------------------------------- +// +VOID DebugShowBufferContent(UINTN bufSize, VOID *buffer) +{ + + //#if TSE_DEBUG_MESSAGES == 2 + + UINTN index = 0, j = 0; + UINTN size = bufSize; + UINT8 *temp = (UINT8 *)buffer; + + for(index = 0; index < size; ){ + SETUP_DEBUG_UEFI_CALLBACK ( "[0x%08x (%04d)] ", index, index); + for(j = 0; (j < 16) && (temp != NULL); index++, j++){ + if(index >= size){ + break; + } + if(j==8) SETUP_DEBUG_UEFI_CALLBACK ( "- "); + SETUP_DEBUG_UEFI_CALLBACK ( "%02x ", (UINT8)temp[index]); + } + SETUP_DEBUG_UEFI_CALLBACK ("\n"); + } + + +// #endif + +} +// +//--------------------------------------------------------------------------- +// Procedure: DebugLibShowHiiControlState +// +// Description: Prints the AMI Setup Lib control states +// +// Input: None +// +// Output: VOID +//--------------------------------------------------------------------------- +// +VOID DebugLibShowHiiControlState(UINT32 formID, UINT32 ctrlIndex, VOID *passedCtrlInfo) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = (CONTROL_INFO *)NULL; + UINTN ctrlCond = COND_NONE; + + ctrlInfo = (CONTROL_INFO *)passedCtrlInfo; + if(passedCtrlInfo == NULL){ + //status = _GetControlInfo(formID, ctrlIndex, &ctrlInfo); + //if((ctrlInfo == NULL) || EFI_ERROR(status)){ + SETUP_DEBUG_TSE("Invalid ctrlInfo, formID: 0x%x, ctrlIndex: 0x%x, status: 0x%x", formID, ctrlIndex, status); + return; + //} + } + ctrlCond = CheckControlCondition(ctrlInfo); + + switch(ctrlCond){ + case COND_NONE: + SETUP_DEBUG_TSE("Control Condition: COND_NONE\n"); + break; + case COND_SUPPRESS: + SETUP_DEBUG_TSE("Control Condition: COND_SUPPRESS\n"); + break; + case COND_HIDDEN: + SETUP_DEBUG_TSE("Control Condition: COND_HIDDEN\n"); + break; + case COND_GRAYOUT: + SETUP_DEBUG_TSE("Control Condition: COND_GRAYOUT\n"); + break; + case COND_INCONSISTENT: + SETUP_DEBUG_TSE("Control Condition: COND_INCONSISTENT\n"); + break; + default: + break; + } + return; +} +// +//--------------------------------------------------------------------------- +// Procedure: DebugShowControlInfo +// +// Description: Prints the cache controls information +// +// Input: UINT32 formID +// UINTN count +// VOID *passedCtrlInfo +// BOOLEAN detailed - If TRUE, prints the control buffers +// +// Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS DebugShowControlInfo(UINT32 formID, VOID *passedCtrlInfo) +{ + EFI_STATUS status = EFI_SUCCESS; + UINTN bufferLen = 0; + UINT32 i = 0, j = 0; + UINT8 *temp = (UINT8 *)NULL; + EFI_IFR_QUESTION_HEADER *questionHdr = NULL; + UINT8 *questionValue = (UINT8 *)NULL; + UINTN dataWidth = 0; + CONTROL_INFO *ctrlInfo = (CONTROL_INFO *)NULL; + CHAR16 *String = (CHAR16 *)NULL; + + ctrlInfo = (CONTROL_INFO *)passedCtrlInfo; + + if(passedCtrlInfo == NULL){ + //status = _GetControlInfo(formID, ctrlIndex, &ctrlInfo); + goto DONE ; + } + + if((ctrlInfo == NULL) || EFI_ERROR(status)){ + SETUP_DEBUG_TSE("Invalid ctrlInfo, formID: 0x%x, status: 0x%x", formID, status); + goto DONE ; + } + + SETUP_DEBUG_TSE("\n----- Adding Control -----\n"); + + if(ctrlInfo->ControlHandle != NULL){ + String = HiiGetString(ctrlInfo->ControlHandle, ctrlInfo->QuestionId); + } + + if (String) + { + SETUP_DEBUG_TSE("QuestionId: 0x%x, %s\n", ctrlInfo->QuestionId, String); + } + SETUP_DEBUG_TSE("ControlHandle: 0x%x\n", ctrlInfo->ControlHandle); + SETUP_DEBUG_TSE("ControlType: 0x%x\n", ctrlInfo->ControlType); + SETUP_DEBUG_TSE("ControlPageID: %d\n", ctrlInfo->ControlPageID); + SETUP_DEBUG_TSE("ControlDestPageID: %d\n", ctrlInfo->ControlDestPageID); + SETUP_DEBUG_TSE("ControlIndex: %d\n", ctrlInfo->ControlIndex); + SETUP_DEBUG_TSE("ControlPtr: 0x%x\n", ctrlInfo->ControlPtr); + SETUP_DEBUG_TSE("ControlConditionalPtr: 0x%x\n", ctrlInfo->ControlConditionalPtr); + SETUP_DEBUG_TSE("ControlDataLength: 0x%x\n", ctrlInfo->ControlDataLength); + SETUP_DEBUG_TSE("ControlDataWidth: 0x%x\n", ctrlInfo->ControlDataWidth); + SETUP_DEBUG_TSE("ControlKey: %d\n", ctrlInfo->ControlKey); + SETUP_DEBUG_TSE("DestQuestionID: 0x%x\n", &ctrlInfo->DestQuestionID); + //DebugLibShowHiiControlState(formID, ctrlInfo->ControlIndex, ctrlInfo); + //DebugShowControlFlags(formID, ctrlIndex, ctrlInfo, &ctrlInfo->ControlFlags); + + +DONE: + MemFreePointer( (VOID **)&String ); + + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: DebugShowPageInfo +// +// Description: Shows the Page information +// +// Input: UINT32 formID - The form +// PAGE_INFO *passedPageInfo +// +// Output: VOID +//--------------------------------------------------------------------------- +// +VOID DebugShowPageInfo(UINT32 formID, VOID *passedPageInfo) +{ + EFI_STATUS status = EFI_SUCCESS; + PAGE_INFO *pageInfo = (PAGE_INFO *)NULL; + + pageInfo = (PAGE_INFO *)passedPageInfo; + + if(pageInfo == NULL) + return ; + + SETUP_DEBUG_TSE("\n+++++ Adding Page +++++\n"); + SETUP_DEBUG_TSE("PageTitle: %s \n", HiiGetString(pageInfo->PageHandle, pageInfo->PageSubTitle )); //Varies Allows a page to override the main title bar + //SETUP_DEBUG_TSE("PageSubTitle: %s \n", HiiGetString(pageInfo->PageHandle, pageInfo->PageSubTitle )); //Varies Token for the subtitle string for this page + SETUP_DEBUG_TSE("PageHandle: 0x%x\n", pageInfo->PageHandle); + SETUP_DEBUG_TSE("PageIdIndex: %d\n", pageInfo->PageIdIndex); //varies Index in to PageIdList triplets + SETUP_DEBUG_TSE("PageFormID: %d\n", pageInfo->PageFormID); //Varies Form ID within the formset for this page + SETUP_DEBUG_TSE("PageID: %d\n", pageInfo->PageID); //Varies unique ID for this page + SETUP_DEBUG_TSE("PageParentID: %d\n", pageInfo->PageParentID); //Varies Identify this page's parent page + SETUP_DEBUG_TSE("PageFlags: 0x%x\n", pageInfo->PageFlags); //3 Various attributes for a specific page + SETUP_DEBUG_TSE("PageVariable: 0x%x\n", pageInfo->PageVariable); //Varies Overrides the variable ID for this page (0 = use default) + SETUP_DEBUG_TSE("PageDynamic: 0x%x\n", pageInfo->PageFlags.PageDynamic); //Identify this page as dynamic page + +} +// +//--------------------------------------------------------------------------- +// Procedure: DebugShowHiiVariable +// +// Description: Prints the variable information for the given parameter +// +// Input: UINT32 formID +// +// Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS DebugShowHiiVariable(UINT32 formID, UINT32 varIndex, UINT32 *passedVarIDList) +{ + EFI_STATUS status = EFI_SUCCESS; + NVRAM_VARIABLE *nvPtr = (NVRAM_VARIABLE *)NULL; + UINT32 *varIDList = (UINT32 *)NULL; + VARIABLE_INFO *varInfo = (VARIABLE_INFO *)NULL ; + UINTN index = 0, j = 0, size = 0 ; + UINT8 *temp = (UINT8 *)NULL ; + + nvPtr = gVariableList; + size = nvPtr[varIndex].Size < 0xFFFF ? nvPtr[varIndex].Size : 0; + temp = nvPtr[varIndex].Buffer; + varInfo = VarGetVariableInfoIndex( varIndex ); + + if(size){ + SETUP_DEBUG_VAR ("\n----------- DebugShowHiiVariable -----------\n"); + SETUP_DEBUG_VAR ("VariableName: %s, Buffer size: %d, Buffer: 0x%x \n", varInfo->VariableName, size, nvPtr[varIndex].Buffer); + + for(index = 0; index < size; ){ + SETUP_DEBUG_VAR ( "[0x%08x (%04d)] ", index, index); + for(j = 0; (j < 16) && (temp != NULL); index++, j++){ + if(index >= size){ + break; + } + if(j==8) SETUP_DEBUG_VAR ( "- "); + SETUP_DEBUG_VAR ( "%02x ", (UINT8)temp[index]); + } + SETUP_DEBUG_VAR ("\n"); + } + + SETUP_DEBUG_VAR ("----------- End of DebugShowHiiVariable, status: 0x%x -----------\n\n", status); + } else{ + SETUP_DEBUG_VAR ("!!!!!! VariableName: %s, size: %d !!!!!\n", varInfo->VariableName, nvPtr[varIndex].Size); + } + + return status; +} +// +//--------------------------------------------------------------------------- +// Procedure: DebugShowAllHiiVariable +// +// Description: Prints the variable information in the list +// +// Input: UINT32 formID +// +// Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS DebugShowAllHiiVariable(UINT32 formID) +{ + EFI_STATUS status = EFI_SUCCESS; + NVRAM_VARIABLE *nvPtr = (NVRAM_VARIABLE *)NULL; + UINT32 i = 0; + UINT32 *varIDList = (UINT32*)EfiLibAllocateZeroPool(gVariables->VariableCount * sizeof(UINT32)); + + SETUP_DEBUG_VAR ("\n----------- DebugShowAllHiiVariable -----------\n"); + + if(varIDList == NULL) + { + status = EFI_OUT_OF_RESOURCES; + SETUP_DEBUG_VAR ("ERROR-%r: varIDList Memory Allocation Failed\n", status); + goto DONE; + } + + nvPtr = gVariableList; + + SETUP_DEBUG_VAR ("++ Total number of variables: %d ++\n\n", gVariables->VariableCount); + for ( i = 0; i < gVariables->VariableCount; i++){ + DebugShowHiiVariable(formID, i, varIDList); + } + SETUP_DEBUG_VAR ("\n"); + +DONE: + + SETUP_DEBUG_VAR ("--------- End of DebugShowAllHiiVariable, status: 0x%x ---------\n\n", status); + return status; +} +// +//--------------------------------------------------------------------------- +// Procedure: DisplayParseFormSetData +// +// Description: Prints the current FormSet data +// +// Input: UINT32 FormID - Library formID of a FormSet +// +// Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS DisplayParseFormSetData(VOID) +{ + + EFI_STATUS status = EFI_SUCCESS; + PAGE_INFO *pageInfo = (PAGE_INFO *)NULL; + EFI_HII_PACKAGE_HEADER *pkgHdr = (EFI_HII_PACKAGE_HEADER *)NULL; + UINT8 *formSet = (UINT8 *)NULL; + UINT8 *ifrData = (UINT8 *)NULL; + EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER *)NULL; + UINTN length = 0; + UINTN i = 0, count = 0; + CHAR16 *opcodeName = (CHAR16 *)NULL; + EFI_GUID *tempFormSetGuid = (EFI_GUID *)NULL; + BOOLEAN validOpCode = TRUE; + UINTN pScopeCount = 0; + BOOLEAN CurrentForm = FALSE; + PAGE_DATA *Page ; + UINT16 questionId = 0; + FRAME_DATA *frame = NULL ; + //UINT16 PageFormID = 0; + + Page = gApp->PageList[gApp->CurrentPage]; + + formSet = (UINT8*)HiiGetForm(Page->PageData.PageHandle, 0, &length); + if(formSet == NULL){ + status = EFI_UNSUPPORTED; + SETUP_DEBUG_TSE ("ERROR: 0x%x, failed to get FormSet data\n",status); + goto DONE; + } + + pkgHdr = (EFI_HII_PACKAGE_HEADER*)formSet; + + if(pkgHdr->Type != EFI_HII_PACKAGE_FORMS) + { + status = EFI_UNSUPPORTED; + SETUP_DEBUG_TSE("ERROR: 0x%x, pkgHdr->Type is not supported, Since it is not EFI_HII_PACKAGE_FORM\n",status); + goto DONE; + } + + + ifrData = ((UINT8 *)pkgHdr) + sizeof(EFI_HII_PACKAGE_HEADER); + + while(i < pkgHdr->Length) + { + opHeader = (EFI_IFR_OP_HEADER*)(ifrData + i); + tempFormSetGuid = (EFI_GUID *)NULL; + + if(opHeader == NULL){ + break; + } + + count = pScopeCount; + questionId = 0; + + switch(opHeader->OpCode) + { + case EFI_IFR_FORM_OP: //0x01 - Form + opcodeName = L"EFI_IFR_FORM_OP"; + + if(CurrentForm) + { + SETUP_DEBUG_TSE ( "[TSE] Form OpCode End\n" ); + goto DONE; + } + + if(((EFI_IFR_FORM*)(ifrData + i))->FormId == Page->PageData.PageFormID) + { + SETUP_DEBUG_TSE ( "[TSE] Form OpCode Start\n" ); + SETUP_DEBUG_TSE ( "FormTitle: %s\n", HiiGetString(Page->PageData.PageHandle, Page->PageData.PageSubTitle )); + + frame = Page->FrameList[StyleFrameIndexOf(MAIN_FRAME)]; + if(frame != NULL) + SETUP_DEBUG_TSE ( "NumberOfControls: %ld\n", frame->ControlCount ); + + CurrentForm = TRUE; + } + + break; + case EFI_IFR_SUBTITLE_OP: //0x02 - Subtitle statement + opcodeName = L"EFI_IFR_SUBTITLE_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_TEXT_OP: //0x03 - Static text/image statement + opcodeName = L"EFI_IFR_TEXT_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_IMAGE_OP: //0x04 - Static image. + opcodeName = L"EFI_IFR_IMAGE_OP"; + break; + case EFI_IFR_ONE_OF_OP: //0x05 - One-of question + opcodeName = L"EFI_IFR_ONE_OF_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_CHECKBOX_OP: //0x06 - Boolean question + opcodeName = L"EFI_IFR_CHECKBOX_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_NUMERIC_OP: //0x07 - Numeric question + opcodeName = L"EFI_IFR_NUMERIC_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_PASSWORD_OP: //0x08 - Password string question + opcodeName = L"EFI_IFR_PASSWORD_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_ONE_OF_OPTION_OP: //0x09 - Option + opcodeName = L"EFI_IFR_ONE_OF_OPTION_OP"; + /* + switch(((EFI_IFR_ONE_OF_OPTION *)opHeader)->Type) + { + case EFI_IFR_TYPE_NUM_SIZE_16: + questionId = ((EFI_IFR_ONE_OF_OPTION *)opHeader)->Value.u16; + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + questionId = ((EFI_IFR_ONE_OF_OPTION *)opHeader)->Value.u32; + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + questionId = (UINT16)((EFI_IFR_ONE_OF_OPTION *)opHeader)->Value.u64; + break; + case EFI_IFR_TYPE_NUM_SIZE_8: + default: + questionId = ((EFI_IFR_ONE_OF_OPTION *)opHeader)->Value.u8; + break; + } + */ + break; + case EFI_IFR_SUPPRESS_IF_OP: //0x0A - Suppress if conditional + opcodeName = L"EFI_IFR_SUPPRESS_IF_OP"; + break; + case EFI_IFR_LOCKED_OP: //0x0B - Marks statement/question as locked + opcodeName = L"EFI_IFR_LOCKED_OP"; + break; + case EFI_IFR_ACTION_OP: //0x0C - Button question + opcodeName = L"EFI_IFR_ACTION_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_RESET_BUTTON_OP: //0x0D - Reset button statement + opcodeName = L"EFI_IFR_RESET_BUTTON_OP"; + break; + case EFI_IFR_FORM_SET_OP: //0x0E - Form set + opcodeName = L"EFI_IFR_FORM_SET_OP"; + break; + case EFI_IFR_REF_OP: //0x0F - Cross-reference statement + opcodeName = L"EFI_IFR_REF_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_NO_SUBMIT_IF_OP: //0x10 - Error checking conditional + opcodeName = L"EFI_IFR_NO_SUBMIT_IF_OP"; + break; + case EFI_IFR_INCONSISTENT_IF_OP: //0x11 - Error checking conditional + opcodeName = L"EFI_IFR_INCONSISTENT_IF_OP"; + break; + case EFI_IFR_EQ_ID_VAL_OP: //0x12 - Return true if question value equals UINT16 + opcodeName = L"EFI_IFR_EQ_ID_VAL_OP"; + break; + case EFI_IFR_EQ_ID_ID_OP: //0x13 - Return true if question value equals another question value + opcodeName = L"EFI_IFR_EQ_ID_ID_OP"; + break; + case 0x14: //0x14 - Return true if question value is found in list of UINT16s + opcodeName = L"EFI_IFR_EQ_ID_VAL_LIST_OP"; + break; + case EFI_IFR_AND_OP: //0x15 - Push true if both sub-expressions returns true. + opcodeName = L"EFI_IFR_AND_OP"; + break; + case EFI_IFR_OR_OP: //0x16 - Push true if either sub-expressions returns true. + opcodeName = L"EFI_IFR_OR_OP"; + break; + case EFI_IFR_NOT_OP: //0x17 - Push false if sub-expression returns true, otherwise return true. + opcodeName = L"EFI_IFR_NOT_OP"; + break; + case EFI_IFR_RULE_OP: //0x18 - Create rule in current form. + opcodeName = L"EFI_IFR_RULE_OP"; + break; + case EFI_IFR_GRAY_OUT_IF_OP: //0x19 - Nested statements, questions or options will not be selectable if expression returns true. + opcodeName = L"EFI_IFR_GRAY_OUT_IF_OP"; + break; + case EFI_IFR_DATE_OP: //0x1A - Date question. + opcodeName = L"EFI_IFR_DATE_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_TIME_OP: //0x1B - Time question. + opcodeName = L"EFI_IFR_TIME_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_STRING_OP: //0x1C - String question + opcodeName = L"EFI_IFR_STRING_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_REFRESH_OP: //0x1D - Interval for refreshing a question + opcodeName = L"EFI_IFR_REFRESH_OP"; + break; + case EFI_IFR_DISABLE_IF_OP: //0x1E - Nested statements, questions or options will not be processed if expression returns true. + opcodeName = L"EFI_IFR_DISABLE_IF_OP"; + break; + case 0x1F: //0x1F - Animation associated with question statement, form or form set. + opcodeName = L"EFI_IFR_ANIMATION_OP"; + break; + case EFI_IFR_TO_LOWER_OP: //0x20 - Convert a string on the expression stack to lower case. + opcodeName = L"EFI_IFR_TO_LOWER_OP"; + break; + case EFI_IFR_TO_UPPER_OP: //0x21 - Convert a string on the expression stack toupper case. + opcodeName = L"EFI_IFR_TO_UPPER_OP"; + break; + case 0x22: //0x22 - Convert one value to another by selecting a match from a list. + opcodeName = L"EFI_IFR_MAP_OP"; + break; + case EFI_IFR_ORDERED_LIST_OP: //0x23 - Set question + opcodeName = L"EFI_IFR_ORDERED_LIST_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_VARSTORE_OP: //0x24 - Define a buffer-style variable storage. + opcodeName = L"EFI_IFR_VARSTORE_OP"; + break; + case EFI_IFR_VARSTORE_NAME_VALUE_OP: //0x25 - Define a name/value style variable storage. + opcodeName = L"EFI_IFR_VARSTORE_NAME_VALUE_OP"; + break; + case EFI_IFR_VARSTORE_EFI_OP: //0x26 - Define a UEFI variable style variable storage. + opcodeName = L"EFI_IFR_VARSTORE_EFI_OP"; + break; + case EFI_IFR_VARSTORE_DEVICE_OP: //0x27 - Specify the device path to use for variable storage. + opcodeName = L"EFI_IFR_VARSTORE_DEVICE_OP"; + break; + case EFI_IFR_VERSION_OP: //0x28 - Push the revision level of the UEFI Specification to which this FormsProcessor is compliant. + opcodeName = L"EFI_IFR_VERSION_OP"; + break; + case EFI_IFR_END_OP: //0x29 - Marks end of scope. + opcodeName = L"EFI_IFR_END_OP"; + break; + case EFI_IFR_MATCH_OP: //0x2A - Push TRUE if string matches a pattern. + opcodeName = L"EFI_IFR_MATCH_OP"; + break; + case 0x2B: //0x2B - Return a stored value. + opcodeName = L"EFI_IFR_GET_OP"; + break; + case 0x2C: //0x2C - Change a stored value. + opcodeName = L"EFI_IFR_SET_OP"; + break; + case 0x2D: //0x2D - Provides a value for the current question or default. + opcodeName = L"EFI_IFR_READ_OP"; + break; + case 0x2E: //0x2E - Change a value for the current question. + opcodeName = L"EFI_IFR_WRITE_OP"; + break; + case EFI_IFR_EQUAL_OP: //0x2F - Push TRUE if two expressions are equal. + opcodeName = L"EFI_IFR_EQUAL_OP"; + break; + case EFI_IFR_NOT_EQUAL_OP: //0x30 - Push TRUE if two expressions are not equal. + opcodeName = L"EFI_IFR_NOT_EQUAL_OP"; + break; + case EFI_IFR_GREATER_THAN_OP: //0x31 - Push TRUE if one expression is greater than another expression. + opcodeName = L"EFI_IFR_GREATER_THAN_OP"; + break; + case EFI_IFR_GREATER_EQUAL_OP: //0x32 - Push TRUE if one expression is greater than or equal to another expression. + opcodeName = L"EFI_IFR_GREATER_EQUAL_OP"; + break; + case EFI_IFR_LESS_THAN_OP: //0x33 - Push TRUE if one expression is less than another expression. + opcodeName = L"EFI_IFR_LESS_THAN_OP"; + break; + case EFI_IFR_LESS_EQUAL_OP: //0x34 - Push TRUE if one expression is less than or equal to another expression. + opcodeName = L"EFI_IFR_LESS_EQUAL_OP"; + break; + case EFI_IFR_BITWISE_AND_OP: //0x35 - Bitwise-AND two unsigned integers and push the result. + opcodeName = L"EFI_IFR_BITWISE_AND_OP"; + break; + case EFI_IFR_BITWISE_OR_OP: //0x36 - Bitwise-OR two unsigned integers and push the result. + opcodeName = L"EFI_IFR_BITWISE_OR_OP"; + break; + case EFI_IFR_BITWISE_NOT_OP: //0x37 - Bitwise-NOT an unsigned integer and push the result. + opcodeName = L"EFI_IFR_BITWISE_NOT_OP"; + break; + case EFI_IFR_SHIFT_LEFT_OP: //0x38 - Shift an unsigned integer left by a number of bits and push the result. + opcodeName = L"EFI_IFR_SHIFT_LEFT_OP"; + break; + case EFI_IFR_SHIFT_RIGHT_OP: //0x39 - Shift an unsigned integer right by a number of bits and push the result. + opcodeName = L"EFI_IFR_SHIFT_RIGHT_OP"; + break; + case EFI_IFR_ADD_OP: //0x3A - Add two unsigned integers and push the result. + opcodeName = L"EFI_IFR_ADD_OP"; + break; + case EFI_IFR_SUBTRACT_OP: //0x3B - Subtract two unsigned integers and push the result. + opcodeName = L"EFI_IFR_SUBTRACT_OP"; + break; + case EFI_IFR_MULTIPLY_OP: //0x3C - Multiply two unsigned integers and push the result. + opcodeName = L"EFI_IFR_MULTIPLY_OP"; + break; + case EFI_IFR_DIVIDE_OP: //0x3D - Divide one unsigned integer by another and push the result. + opcodeName = L"EFI_IFR_DIVIDE_OP"; + break; + case EFI_IFR_MODULO_OP: //0x3E - Divide one unsigned integer by another and push the remainder. + opcodeName = L"EFI_IFR_MODULO_OP"; + break; + case EFI_IFR_RULE_REF_OP: //0x3F //Evaluate a rule + opcodeName = L"EFI_IFR_RULE_REF_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_QUESTION_REF1_OP: //0x40 - Push a question’s value + opcodeName = L"EFI_IFR_QUESTION_REF1_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_QUESTION_REF2_OP: //0x41 - Push a question’s value + opcodeName = L"EFI_IFR_QUESTION_REF2_OP"; + questionId = _GetQuestionToken((UINT8*)opHeader); + break; + case EFI_IFR_UINT8_OP: //0x42 - Push an 8-bit unsigned integer + opcodeName = L"EFI_IFR_UINT8_OP"; + break; + case EFI_IFR_UINT16_OP: //0x43 - Push a 16-bit unsigned integer. + opcodeName = L"EFI_IFR_UINT16_OP"; + break; + case EFI_IFR_UINT32_OP: //0x44 - Push a 32-bit unsigned integer + opcodeName = L"EFI_IFR_UINT32_OP"; + break; + case EFI_IFR_UINT64_OP: //0x45 - Push a 64-bit unsigned integer. + opcodeName = L"EFI_IFR_UINT64_OP"; + break; + case EFI_IFR_TRUE_OP: //0x46 - Push a boolean TRUE. + opcodeName = L"EFI_IFR_TRUE_OP"; + break; + case EFI_IFR_FALSE_OP: //0x47 - Push a boolean FALSE + opcodeName = L"EFI_IFR_FALSE_OP"; + break; + case EFI_IFR_TO_UINT_OP: //0x48 - Convert expression to an unsigned integer + opcodeName = L"EFI_IFR_TO_UINT_OP"; + break; + case EFI_IFR_TO_STRING_OP: //0x49 - Convert expression to a string + opcodeName = L"EFI_IFR_TO_STRING_OP"; + break; + case EFI_IFR_TO_BOOLEAN_OP: //0x4A - Convert expression to a boolean. + opcodeName = L"EFI_IFR_TO_BOOLEAN_OP"; + break; + case EFI_IFR_MID_OP: //0x4B - Extract portion of string or buffer + opcodeName = L"EFI_IFR_MID_OP"; + break; + case EFI_IFR_FIND_OP: //0x4C - Find a string in a string. + opcodeName = L"EFI_IFR_FIND_OP"; + break; + case EFI_IFR_TOKEN_OP: //0x4D - Extract a delimited byte or character string from buffer or string. + opcodeName = L"EFI_IFR_TOKEN_OP"; + break; + case EFI_IFR_STRING_REF1_OP: //0x4E - Push a string + opcodeName = L"EFI_IFR_STRING_REF1_OP"; + break; + case EFI_IFR_STRING_REF2_OP: //0x4F - Push a string + opcodeName = L"EFI_IFR_STRING_REF2_OP"; + break; + case EFI_IFR_CONDITIONAL_OP: //0x50 - Duplicate one of two expressions depending on result of the first expression. + opcodeName = L"EFI_IFR_CONDITIONAL_OP"; + break; + case EFI_IFR_QUESTION_REF3_OP: //0x51 - Push a question’s value from a different form. + opcodeName = L"EFI_IFR_QUESTION_REF3_OP"; + break; + case EFI_IFR_ZERO_OP: //0x52 - Push a zero + opcodeName = L"EFI_IFR_ZERO_OP"; + break; + case EFI_IFR_ONE_OP: //0x53 //Push a one + opcodeName = L"EFI_IFR_ONE_OP"; + break; + case EFI_IFR_ONES_OP: //0x54 - Push a 0xFFFFFFFFFFFFFFFF. + opcodeName = L"EFI_IFR_ONES_OP"; + break; + case EFI_IFR_UNDEFINED_OP: //0x55 - Push Undefined + opcodeName = L"EFI_IFR_UNDEFINED_OP"; + break; + case EFI_IFR_LENGTH_OP: //0x56 - Push length of buffer or string. + opcodeName = L"EFI_IFR_LENGTH_OP"; + break; + case EFI_IFR_DUP_OP: //0x57 - Duplicate top of expression stack + opcodeName = L"EFI_IFR_DUP_OP"; + break; + case EFI_IFR_THIS_OP: //0x58 - Push the current question’s value + opcodeName = L"EFI_IFR_THIS_OP"; + break; + case EFI_IFR_SPAN_OP: //0x59 - Return first matching/non-matching character in a string + opcodeName = L"EFI_IFR_SPAN_OP"; + break; + case EFI_IFR_VALUE_OP: //0x5A - Provide a value for a question + opcodeName = L"EFI_IFR_VALUE_OP"; + break; + case EFI_IFR_DEFAULT_OP: //0x5B - Provide a default value for a question. + opcodeName = L"EFI_IFR_DEFAULT_OP"; + break; + case 0x5C: //0x5C - Define a Default Type Declaration + opcodeName = L"EFI_IFR_DEFAULTSTORE_OP"; + break; + case 0x5D: //0x5D - Create a standards-map form. + opcodeName = L"EFI_IFR_FORM_MAP_OP"; + break; + case EFI_IFR_CATENATE_OP: //0x5E - Push concatenated buffers or strings. + opcodeName = L"EFI_IFR_CATENATE_OP"; + break; + case EFI_IFR_GUID_OP: //0x5F - An extensible GUIDed op-code + opcodeName = L"EFI_IFR_GUID_OP"; + break; + case 0x60: //0x60 - Returns whether current user profile contains specified setup access privileges. + opcodeName = L"EFI_IFR_SECURITY_OP"; + break; + case 0x61: //0x61 - Specify current form is modal + opcodeName = L"EFI_IFR_MODAL_TAG_OP"; + break; + case 0x62: //0x62 - Establish an event group for refreshing a forms-based element. + opcodeName = L"EFI_IFR_REFRESH_ID_OP"; + break; + default: + opcodeName = L"Invalid Opcode"; + validOpCode = FALSE; + break; + } + + if(opHeader->OpCode == EFI_IFR_END_OP){ + pScopeCount--; + count = pScopeCount; + } + while(count){ + if(CurrentForm) SETUP_DEBUG_TSE ( " "); + + count--; + } + + if(CurrentForm) SETUP_DEBUG_TSE ( "\n\n%s, len: %d\n", opcodeName, opHeader->Length); + + if(CurrentForm && questionId) SETUP_DEBUG_TSE ( "questionId: 0x%x %s \n", questionId, HiiGetString(Page->PageData.PageHandle , questionId )); + + if(opHeader->Length==0) + { + //validOpCode = FALSE ; + goto DONE; + } + + + if(validOpCode){ + UINTN index = 0, j = 0; + UINTN size = opHeader->Length; + UINT8 *temp = (UINT8 *)opHeader; + UINTN sCount = pScopeCount; + + if(size){ + for(index = 0; index < size; ){ + sCount = pScopeCount; + while(sCount){ + sCount--; + } + + if(CurrentForm) SETUP_DEBUG_TSE ( "[0x%08x (%04d)] ", index, index); + + for(j = 0; (j < 16) && (temp != NULL); index++, j++) + { + if(index >= size){ + break; + } + if(CurrentForm && j==8) SETUP_DEBUG_TSE ( "- "); + if(CurrentForm) SETUP_DEBUG_TSE ( "%02x ", (UINT8)temp[index]); + } + if(CurrentForm)SETUP_DEBUG_TSE ("\n"); + + } + } + } + + if(opHeader->Scope){ + pScopeCount++; + } + + i += opHeader->Length; + validOpCode = TRUE; + } + +DONE: + if(formSet){ + EfiLibSafeFreePool(formSet); + } + + pScopeCount = 0; + + return status; +} + +#endif //End of TSE_DEBUG_MESSAGES +//EIP75481 Support TSE debug print infrastructure +//EIP 80426 : START +#define ASSERT_ERROR_STATUS(assertion) if(EFI_ERROR(assertion)) goto DONE +#define MAX_PAGES_TO_PROCESS 50 +UINT32 gProcessedPages[MAX_PAGES_TO_PROCESS]; +UINT32 gProPageOffset = 0; +UINT32 gCurrLoadVarIndex = 0; //Used to track which variable is getting loaded +UINT8 *gCurrLoadVarBuf = (UINT8 *)NULL; //Used to store current variable buffer + +// +//--------------------------------------------------------------------------- +// Procedure: _GetControlInfo +// +// Description: Returns pointer to the CONTROL_INFO struct of given CtrlIndex +// +// Input: UINT32 PgIndex - Page index containing the control +// UINT32 CtrlIndex - HII Control index +// CONTROL_INFO **CtrlInfo - Pointer to the CONTROL_INFO structure +// +// Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS _GetPageInfo(UINT32 PgIndex, PAGE_INFO **PageInfo); +EFI_STATUS _GetControlInfo(UINT32 PgIndex, UINT32 CtrlIndex, CONTROL_INFO **CtrlInfo) +{ + EFI_STATUS status = EFI_SUCCESS; + PAGE_INFO *pageInfo = NULL; + + status = _GetPageInfo(PgIndex, &pageInfo); + if(pageInfo->PageHandle == NULL) + { + status = EFI_NOT_FOUND; //If the page handle is invalid, then page may contain incorrect control data. Return error. + } + ASSERT_ERROR_STATUS(status); + + if(CtrlIndex > pageInfo->PageControls.ControlCount) + { + status = EFI_INVALID_PARAMETER; + goto DONE; + } + + *CtrlInfo = (CONTROL_INFO*)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[CtrlIndex]); + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetNumOfControls +// +// Description: Get the Number of Control for a Page +// +// Input: IN UINT32 PgIndex +// OUT UINT32 *numOfControls +// +// Output: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetNumOfControls(UINT32 PgIndex, UINT32 *NumOfControls) +{ + EFI_STATUS status = EFI_SUCCESS; + PAGE_INFO *pageInfo = NULL; + + status = _GetPageInfo(PgIndex, &pageInfo); + ASSERT_ERROR_STATUS(status); + + *NumOfControls = pageInfo->PageControls.ControlCount; + +DONE: + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: CleanCurrLoadVarBuffer +// +// Description: Cleans the temporary variables +// +// Input: None +// +// Output: VOID +//--------------------------------------------------------------------------- +// +VOID CleanCurrLoadVarBuffer() +{ + if(gCurrLoadVarBuf!= NULL) { + MemFreePointer(&gCurrLoadVarBuf); + } + gCurrLoadVarBuf = (UINT8 *)NULL; + gCurrLoadVarIndex = 0; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _DestinationPageProcessed +// +// Description: Checks whether the page is already processed or not. +// +// Input: UINT32 PageID +// +// Output: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN _DestinationPageProcessed(UINT32 PageID) +{ + BOOLEAN isProcessed = FALSE; + UINT32 index = 0; + + for(index = 0; index < gProPageOffset; index++) + { + if(PageID == gProcessedPages[index]) + { + isProcessed = TRUE; + break; + } + } + return isProcessed; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _GetDefaultNvramVariableIDList +// +// Description: To get the default variable names. +// +// Input: UINT32 FormID +// BOOLEAN DefaultsFlag +// BOOLEAN *ResetVal +// BOOLEAN *ValChanged +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _GetDefaultNvramVariableIDList(UINT32 PageID, BOOLEAN DefaultsFlag, BOOLEAN *ResetVal, BOOLEAN *ValChanged) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT16 CtrlDataSize = 0; + UINT32 count = 0; + UINT32 index = 0; + UINTN CurVarSize = 0; + CONTROL_INFO *ctrlInfo; + NVRAM_VARIABLE *nvPtr = gVariableList; + NVRAM_VARIABLE *defaults = gOptimalDefaults; + EFI_IFR_QUESTION_HEADER *questionHdr = (EFI_IFR_QUESTION_HEADER *)NULL; + + gProcessedPages[gProPageOffset++] = PageID; + + status = GetNumOfControls(PageID, &count); + ASSERT_ERROR_STATUS(status); + + for(index = 0; index < count; index++) + { + //Iterating for all controls + status = _GetControlInfo(PageID , index, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + // CONTROL_TYPE_TEXT is a special case here since its value is not + // in the varstore. If this is a text control, continue. + if(ctrlInfo->ControlType == CONTROL_TYPE_TEXT){ + continue; + } + + if((ctrlInfo->ControlType == CONTROL_TYPE_SUBMENU) || (ctrlInfo->ControlType == CONTROL_TYPE_REF2)) + { + if(_DestinationPageProcessed(ctrlInfo->ControlDestPageID) == FALSE) + { + status = _GetDefaultNvramVariableIDList(ctrlInfo->ControlDestPageID, DefaultsFlag, ResetVal, ValChanged); + ASSERT_ERROR_STATUS(status); + } + } + if(ctrlInfo->ControlType == CONTROL_TYPE_POPUP_STRING && DefaultsFlag) + { + UINT16 defaultToken = 0; + CHAR16 * defaultValue = NULL; + + // First, check if the control has a default value. During parsing, the + // Control Data Width is set to zero if there is no default value. + if (ctrlInfo->ControlDataWidth == 0) { + continue; // move to next control if this one has no default. + } + + // Get the Default String Id + defaultToken = *(UINT16*)((UINT8*)ctrlInfo + sizeof(CONTROL_INFO) + ctrlInfo->ControlDataWidth); + // Get the string corresponding to the StringId + defaultValue = HiiGetString(ctrlInfo->ControlHandle, defaultToken); + // Set the default value to nvPtr + questionHdr = (EFI_IFR_QUESTION_HEADER*)((UINT8*)ctrlInfo->ControlPtr + sizeof(EFI_IFR_OP_HEADER)); + if(defaultValue) + { + if(EfiStrCmp(defaultValue, (CHAR16 *)&nvPtr[ctrlInfo->ControlVariable].Buffer[questionHdr->VarStoreInfo.VarOffset]) != 0) + { + EfiStrCpy((CHAR16 *)&nvPtr[ctrlInfo->ControlVariable].Buffer[questionHdr->VarStoreInfo.VarOffset], defaultValue); + *ValChanged = TRUE; + + if(ctrlInfo->ControlFlags.ControlReset) + { + //ControlReset reset requested. + *ResetVal |= ctrlInfo->ControlFlags.ControlReset; + } + } + } + continue; + } + + if(ctrlInfo->ControlFlags.ControlEvaluateDefault) + { + UINT64 defaults = 0; + UINT16 size = EvaluateControlDefault(ctrlInfo, &defaults); + + if(DefaultsFlag) + { + //Loading Defaults for control + questionHdr = (EFI_IFR_QUESTION_HEADER*)((UINT8*)ctrlInfo->ControlPtr + sizeof(EFI_IFR_OP_HEADER)); + + if(MemCmp((UINT8*)&nvPtr[ctrlInfo->ControlVariable].Buffer[questionHdr->VarStoreInfo.VarOffset], (UINT8*)&defaults, size) != 0) + { + //defaults and Memory value donot match. Copying defaults to memory value + MemCopy( &nvPtr[ctrlInfo->ControlVariable].Buffer[questionHdr->VarStoreInfo.VarOffset], &defaults, size); + *ValChanged = TRUE; + + if(ctrlInfo->ControlFlags.ControlReset) + { + //ControlReset reset requested + *ResetVal |= ctrlInfo->ControlFlags.ControlReset; + } + } + continue; + } + } + + if(DefaultsFlag) { //If loading defaults, use the data size given in CONTROL_INFO. Else get the data size using GetControlDataLength(). + CtrlDataSize = ctrlInfo->ControlDataWidth; + } + else { + CtrlDataSize = (UINT16)GetControlDataLength(ctrlInfo); + } + + if(CtrlDataSize == 0) { + //Control Data Width for control %s is 0\n", HiiGetString(ctrlInfo->ControlHandle, ctrlInfo->QuestionId)); + continue; + } + + if(ctrlInfo->ControlVariable <= gVariables->VariableCount) + { + if(DefaultsFlag == TRUE) + { + //Loading Defaults for control + questionHdr = (EFI_IFR_QUESTION_HEADER*)((UINT8*)ctrlInfo->ControlPtr + sizeof(EFI_IFR_OP_HEADER)); + + if(MemCmp((UINT8*)&nvPtr[ctrlInfo->ControlVariable].Buffer[questionHdr->VarStoreInfo.VarOffset], (UINT8*)&defaults[ctrlInfo->ControlVariable].Buffer[questionHdr->VarStoreInfo.VarOffset], ctrlInfo->ControlDataWidth) != 0) + { + //defaults and Memory value donot match. Copying defaults to memory value + MemCopy( &nvPtr[ctrlInfo->ControlVariable].Buffer[questionHdr->VarStoreInfo.VarOffset], &defaults[ctrlInfo->ControlVariable].Buffer[questionHdr->VarStoreInfo.VarOffset], ctrlInfo->ControlDataWidth); + *ValChanged = TRUE; + + if(ctrlInfo->ControlFlags.ControlReset) + { + //ControlReset reset requested. + *ResetVal |= ctrlInfo->ControlFlags.ControlReset; + } + } + } + else + { + UINT8 *tempLoadVarBuff = (UINT8 *)NULL; + + if(gCurrLoadVarBuf != NULL) + { + if(gCurrLoadVarIndex != ctrlInfo->ControlVariable) + { + tempLoadVarBuff = VarGetNvram( ctrlInfo->ControlVariable, &CurVarSize ); + if(tempLoadVarBuff != NULL){ + CleanCurrLoadVarBuffer(); + gCurrLoadVarBuf = tempLoadVarBuff; + gCurrLoadVarIndex = ctrlInfo->ControlVariable; + } + } + } + else + { + tempLoadVarBuff = VarGetNvram( ctrlInfo->ControlVariable, &CurVarSize ); + if(tempLoadVarBuff != NULL){ + CleanCurrLoadVarBuffer(); + gCurrLoadVarBuf = tempLoadVarBuff; + gCurrLoadVarIndex = ctrlInfo->ControlVariable; + } + } + + if(gCurrLoadVarBuf != NULL) + { + if(tempLoadVarBuff != NULL){ + gCurrLoadVarIndex = ctrlInfo->ControlVariable; + } + questionHdr = (EFI_IFR_QUESTION_HEADER*)((UINT8*)ctrlInfo->ControlPtr + sizeof(EFI_IFR_OP_HEADER)); + MemCopy( &nvPtr[ctrlInfo->ControlVariable].Buffer[questionHdr->VarStoreInfo.VarOffset], &gCurrLoadVarBuf[questionHdr->VarStoreInfo.VarOffset], CtrlDataSize); + } + } + } + } + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: LoadNvram +// +// Description: Intermediate function to get the nvram variables to restore. +// +// Parameter: UINT32 PageID +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS LoadNvram(UINT32 PageID) +{ + EFI_STATUS status = EFI_SUCCESS; + + gProPageOffset = 0; + MemSet(gProcessedPages, MAX_PAGES_TO_PROCESS * sizeof(UINT32), 0); + status = _GetDefaultNvramVariableIDList(PageID, FALSE, NULL, NULL); + ASSERT_ERROR_STATUS(status); + +DONE: + CleanCurrLoadVarBuffer(); + return status; +} +//EIP 80426 : END + +//EIP81814 Starts +// +//---------------------------------------------------------------------------- +// Procedure: LoadDefaults +// +// Description: function to load the defaults to the nvram cache +// +// Parameter: UINT32 FormID - form identifier +// BOOLEAN *ResetVal - Reboot flag of the control variable +// BOOLEAN * ValChanged - flag to check whether the value changed +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS LoadDefaults(UINT32 FormID, BOOLEAN *ResetVal, BOOLEAN * ValChanged) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 *varIDList = (UINT32*)EfiLibAllocateZeroPool(gVariables->VariableCount * sizeof(UINT32)); + + + if(varIDList == NULL) + { + status = EFI_OUT_OF_RESOURCES; + + goto DONE; + } + + gVarOffset = 0; +// gProFormOffset = 0; +// MemSet(gProcessedForms, MAX_FORMS_TO_PROCESS, 0); + CleargProcessedForms (); + + //inplace of updating all the variables, update only the variables that are modified + //status = _GetVariableIDList(FormID, &varIDList); + status = _GetDefaultNvramVariableIDList(FormID, TRUE, ResetVal, ValChanged); + ASSERT_ERROR_STATUS(status); + +DONE: + if (varIDList) { + MemFreePointer(&varIDList); + } + CleanCurrLoadVarBuffer(); + + + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: _InconsistenceCheck +// +// Description: Checks if the controls in a page is inconsistent +// +// Input: PAGE_INFO *PgInfo - Input page info +// UINT16 *ErrStrToken - Pointer to the output error code +// +// Output: BOOLEAN flag - TRUE if inconsistence, else FALSE +//--------------------------------------------------------------------------- +// +BOOLEAN _InconsistenceCheck(PAGE_INFO *PgInfo, UINT16 *ErrStrToken) +{ + CONTROL_INFO *ctrlInfo = NULL; + EFI_IFR_INCONSISTENT_IF *inconsistentIf = NULL; + BOOLEAN flag = FALSE; + UINT32 i = 0; + + //Find out if there is inconsistent value in any of the controls + for(i=0; i < PgInfo->PageControls.ControlCount; i++) + { + + ctrlInfo = (CONTROL_INFO*)((UINTN)(gControlInfo) + PgInfo->PageControls.ControlList[i]); + //Check if there is a CONTROL_TYPE_MSGBOX in this page + if(ctrlInfo->ControlType == CONTROL_TYPE_MSGBOX) + { + + if(CheckControlCondition(ctrlInfo) == COND_INCONSISTENT) + { + + inconsistentIf = (EFI_IFR_INCONSISTENT_IF*)ctrlInfo->ControlConditionalPtr; + *ErrStrToken = inconsistentIf->Error; + flag = TRUE; + goto DONE; + } + } + } + +DONE: + + return flag; +} + +// +//--------------------------------------------------------------------------- +// Procedure: _NoSubmitCheck +// +// Description: Checks if the controls in a page has no submit +// +// Input: CONTROL_INFO *ctrlInfo - Input control info +// UINT16 *ErrStrToken - Pointer to the output error code +// +// Output: BOOLEAN flag - TRUE if nosubmit, else FALSE +//--------------------------------------------------------------------------- +// +BOOLEAN _NoSubmitCheck(CONTROL_INFO *ctrlInfo, UINT16 *ErrStrToken) +{ + EFI_IFR_NO_SUBMIT_IF *nosubmitIf = NULL; + BOOLEAN flag = FALSE; + + + + if(ctrlInfo->ControlType == CONTROL_TYPE_MSGBOX) + { + + if(CheckControlCondition(ctrlInfo) == COND_NOSUBMIT) + { + + nosubmitIf = (EFI_IFR_NO_SUBMIT_IF*)ctrlInfo->ControlConditionalPtr; + *ErrStrToken = nosubmitIf->Error; + flag = TRUE; + } + } + + + return flag; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetVariableIDList +// +// Description: function to get the list of all variables that are need to update +// +// Parameter: UINT32 FormID, +// UINT32 **VarIDList +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS _GetVariableIDList(UINT32 FormID, UINT32 **VarIDList) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 count = 0; + UINT32 index = 0; + UINT32 varIndex = 0; + UINT32 *varPtr = NULL; + CONTROL_INFO *ctrlInfo; + + + if(*VarIDList == NULL || VarIDList == NULL) + { + status = EFI_INVALID_PARAMETER; + + goto DONE; + } + AddEntryIngProcessedForms (FormID); +// gProcessedForms[gProFormOffset++] = FormID; + status = GetNumOfControls(FormID, &count); + ASSERT_ERROR_STATUS(status); + varPtr = *VarIDList; + for(index = 0; index < count; index++) + { + + status = _GetControlInfo(FormID , index, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + if((ctrlInfo->ControlType == CONTROL_TYPE_SUBMENU) || (ctrlInfo->ControlType == CONTROL_TYPE_REF2)) + { + + if(_DestinationFormProcessed(ctrlInfo->ControlDestPageID) == FALSE) + { + + _GetVariableIDList(ctrlInfo->ControlDestPageID, VarIDList); + } + } + + for(varIndex = 0; varIndex < gVariables->VariableCount; varIndex++) + { + + if(varPtr[varIndex] == ctrlInfo->ControlVariable) + { + + break; + } + } + if(varIndex == gVariables->VariableCount) + { + + varPtr[gVarOffset++] = ctrlInfo->ControlVariable; + } + } + +DONE: + + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _DestinationFormProcessed +// +// Description: Is this form Processed +// +// Parameter: IN UINT32 FormID +// +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN _DestinationFormProcessed(UINT32 FormID) +{ + BOOLEAN isProcessed = FALSE; + UINT32 index = 0; + + + for(index = 0; index < gProFormOffset; index++) + { + + if(FormID == gProcessedForms[index]) + { + + isProcessed = TRUE; + break; + } + } + + return isProcessed; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IsNoSubmitOfForms +// +// Description: Is this formset or form has the no submit if +// +// Parameter: IN UINT32 FormID +// OUT UINT16* ErrToken +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsNoSubmitOfForms(UINT32 FormID, UINT16* ErrToken) +{ + BOOLEAN flag = FALSE; + EFI_STATUS status = EFI_SUCCESS; + UINT32 count = 0; + UINT32 index = 0; + CONTROL_INFO *ctrlInfo; + + +// gProcessedForms[gProFormOffset++] = FormID; + AddEntryIngProcessedForms (FormID); + + status = GetNumOfControls(FormID, &count); + ASSERT_ERROR_STATUS(status); + + for(index = 0; index < count; index++) + { + + status = _GetControlInfo(FormID, index, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + if((ctrlInfo->ControlType == CONTROL_TYPE_SUBMENU)//If submenu traverse recursively through the sub forms + || (ctrlInfo->ControlType == CONTROL_TYPE_REF2)) + { + + if(_DestinationFormProcessed(ctrlInfo->ControlDestPageID) == FALSE)//If the form has not be processed already + { + flag = IsNoSubmitOfForms(ctrlInfo->ControlDestPageID, ErrToken); + if(flag) + { + break; + } + } + } + if(_NoSubmitCheck(ctrlInfo, ErrToken) == TRUE)//if the control is no submit if + { + flag = TRUE; + break; + } + }//end of for loop of controls + +DONE: + + return flag; +} + +// +//---------------------------------------------------------------------------- +// Procedure: CheckforNosubmitIf +// +// Description: Check for no submit if +// +// Parameter: UINT32 FormID, BOOLEAN Recursive, UINT16 *ErrToken +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +EFI_STATUS CheckforNosubmitIf(UINT32 FormID, BOOLEAN Recursive, UINT16 *ErrToken) +{ + EFI_STATUS status = EFI_SUCCESS; + BOOLEAN flag = FALSE; + + if(Recursive)//To check all the forms in the formset + { +// gProFormOffset = 0; +// MemSet(gProcessedForms, MAX_FORMS_TO_PROCESS, 0); + CleargProcessedForms (); + flag = IsNoSubmitOfForms(FormID,ErrToken); + } + else//for single form ID + { + PAGE_INFO *PgInfo = NULL; + EFI_STATUS status = EFI_SUCCESS; + UINT32 i = 0; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetPageInfo(FormID, &PgInfo); + ASSERT_ERROR_STATUS(status); + + for(i=0; i < PgInfo->PageControls.ControlCount; i++) + { + + ctrlInfo = (CONTROL_INFO*)((UINTN)(gControlInfo) + PgInfo->PageControls.ControlList[i]); + if(_NoSubmitCheck(ctrlInfo, ErrToken) == TRUE) + { + flag = TRUE; + break; + } + } + } + + if(flag) + { + status = EFI_NOSUBMIT_VALUE; + } + +DONE: + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: _GetControlFlag +// +// Description: Gets attribute flag for a given CtrlIndex in a page +// +// Input: UINT32 PgIndex - Page index containing the control +// UINT32 CtrlIndex - Control index +// CONTROL_FLAGS **CtrlFlag - Pointer to the flag attribute structure +// +// Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR +//--------------------------------------------------------------------------- +// +EFI_STATUS _GetControlFlag(UINT32 PgIndex, UINT32 CtrlIndex, CONTROL_FLAGS **CtrlFlag) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *CtrlFlag = &ctrlInfo->ControlFlags; + +DONE: + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetNumOfPages +// +// Description: Get the Total Number of HII Form Pages to display +// +// Parameter: OUT UINT32 *numOfPages +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_OUT_OF_RESOURCES +//---------------------------------------------------------------------------- +// +EFI_STATUS GetNumOfPages(UINT32 *NumOfPages) +{ + EFI_STATUS status = EFI_SUCCESS; + + + if(LibInitialized == FALSE) + { + status = EFI_NOT_READY; + + goto DONE; + } + + *NumOfPages = gPages->PageCount; + +DONE: + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetPageTitle +// +// Description: Get the Page Title String Index +// +// Parameter: IN UINT32 PgIndex +// OUT UINT16 *titleToken +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetPageTitle(UINT32 PgIndex, UINT16 *TitleToken) +{ + EFI_STATUS status = EFI_SUCCESS; + PAGE_INFO *pageInfo = NULL; + + status = _GetPageInfo(PgIndex, &pageInfo); + ASSERT_ERROR_STATUS(status); + + *TitleToken = pageInfo->PageTitle; + +DONE: + return status; + +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetPageHandle +// +// Description: Get the Handle for the Page +// +// Parameter: IN UINTN PgIndex +// OUT EFI_HII_HANDLE *handle +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetPageHandle(UINT32 PgIndex, EFI_HII_HANDLE *Handle) +{ + EFI_STATUS status = EFI_SUCCESS; + PAGE_INFO *pageInfo = NULL; + + status = _GetPageInfo(PgIndex, &pageInfo); + ASSERT_ERROR_STATUS(status); + + *Handle = pageInfo->PageHandle; +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetPageIdIndex +// +// Description: Get the page ID index for the Page +// +// Parameter: IN UINTN PgIndex +// OUT UINT16 *PgIdIndex +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetPageIdIndex(UINT32 PgIndex, UINT16 *PgIdIndex) +{ + EFI_STATUS status = EFI_SUCCESS; + PAGE_INFO *pageInfo = NULL; + + status = _GetPageInfo(PgIndex, &pageInfo); + ASSERT_ERROR_STATUS(status); + + *PgIdIndex = pageInfo->PageIdIndex; + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: IsParentPage +// +// Description: Is this page a parent page +// +// Parameter: IN UINT32 PgIndex +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsParentPage(UINT32 PgIndex) +{ + EFI_STATUS status = EFI_SUCCESS; + BOOLEAN isTrue = FALSE; + PAGE_INFO *pageInfo = NULL; + + status = _GetPageInfo(PgIndex, &pageInfo); + ASSERT_ERROR_STATUS(status); + isTrue = pageInfo->PageParentID == 0? TRUE : FALSE; + +DONE: + return isTrue; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetPageHiiId +// +// Description: Get the Page Title String Index +// +// Parameter: IN UINT32 PgIndex +// OUT UINT16 *PageId +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetPageHiiId(UINT32 PgIndex, UINT16 *PageId) +{ + EFI_STATUS status = EFI_SUCCESS; + PAGE_INFO *pageInfo = NULL; + + status = _GetPageInfo(PgIndex, &pageInfo); + ASSERT_ERROR_STATUS(status); + + *PageId = pageInfo->PageFormID; + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetPageParentId +// +// Description: Get the parent page ID from the page index +// +// Parameter: IN UINT32 PgIndex - Current page Index/ID +// OUT UINT16 *PageParentId - Parent page ID +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetPageParentId(UINT32 PgIndex, UINT16 *PageParentId) +{ + EFI_STATUS status = EFI_SUCCESS; + PAGE_INFO *pageInfo = NULL; + + status = _GetPageInfo(PgIndex, &pageInfo); + ASSERT_ERROR_STATUS(status); + + *PageParentId = pageInfo->PageParentID; + +DONE: + return status; +} + +// +//--------------------------------------------------------------------------- +// Procedure: GetCtrlsDestCtrlId +// +// Description: Returns the QuestionID to select in the destination page +// +// Input: UINT32 PgIndex - ASL page ID +// UINT32 CtrlIndex - Control index, Lib control ID +// UINT16 *DestCtrlId - Destination control index +// +// Output: EFI_STATUS status +//--------------------------------------------------------------------------- +// +EFI_STATUS GetCtrlsDestCtrlId(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *DestCtrlId) +{ + EFI_STATUS status = EFI_NOT_FOUND; + CONTROL_INFO *ctrlInfo = (CONTROL_INFO *)NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *DestCtrlId = ctrlInfo->DestQuestionID; + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlType +// +// Description: Get the AMI Control Type +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// OUT UINT16 *ctrlType +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetControlType(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlType) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *CtrlType = ctrlInfo->ControlType; + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlQuestionPrompt +// +// Description: Get the Control Question Prompt's String Id +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// OUT UINT16 *ctrlPrompt +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetControlQuestionPrompt(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlPrompt) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *CtrlPrompt = ctrlInfo->QuestionId; +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlHelpStr +// +// Description: Get the Control Help String ID +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// OUT UINT16 *ctrlHelp +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetControlHelpStr(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlHelp) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *CtrlHelp = ctrlInfo->ControlHelp; +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: _GetCheckBoxOptions +// +// Description: Get the List of Options for the Checkbox Control +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// OUT UINTN *optionCount +// OUT OPTION_LIST *optionArray +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS _GetCheckBoxOptions(CONTROL_INFO *CtrlInfo, UINT32 *OptionCount, OPTION_LIST **OptionArray) +{ + EFI_STATUS status = EFI_SUCCESS; + OPTION_LIST *optList = NULL; + OPTION_LIST *temp = NULL; + EFI_IFR_CHECKBOX *checkBoxOp = (EFI_IFR_CHECKBOX*)(CtrlInfo->ControlPtr); + UINT32 index = 0; + + *OptionCount = CHECKBOX_OPTION_COUNT; + for(index = 0; index < *OptionCount; index++) + { + + temp = (OPTION_LIST*)EfiLibAllocateZeroPool(sizeof(OPTION_LIST)); + if(temp == NULL) + { + status = EFI_OUT_OF_RESOURCES; + + goto DONE; + } + + if(*OptionArray == NULL) + { + + *OptionArray = temp; + }else + { + + if(optList){ + optList->Next = temp; + } + } + optList = temp; + + // Option will be set In the Application + temp->Option = 0; + temp->Value = index; + temp->Flag = ((checkBoxOp->Flags & EFI_IFR_CHECKBOX_DEFAULT) == EFI_IFR_CHECKBOX_DEFAULT)? OPTION_DEFAULT : 0; + temp->Flag = ((checkBoxOp->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) == EFI_IFR_CHECKBOX_DEFAULT_MFG)? OPTION_DEFAULT_MFG : 0; + temp->Next = NULL; + } + + +DONE: + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: IsControlCheckBox +// +// Description: Check if the control is a check box +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsControlCheckBox(UINT32 PgIndex, UINT32 CtrlIndex) +{ + BOOLEAN isCheckBox = FALSE; + CONTROL_INFO *ctrlInfo = NULL; + EFI_IFR_OP_HEADER *opHeader = NULL; + + _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + + opHeader = (EFI_IFR_OP_HEADER*)ctrlInfo->ControlPtr; + isCheckBox = (opHeader->OpCode == EFI_IFR_CHECKBOX_OP)? TRUE : FALSE; + + return isCheckBox; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlDataWidth +// +// Description: Get the Data size +// +// Parameter: UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *controlWidth +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetControlDataWidth(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlWidth) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *CtrlWidth = (UINT16)GetControlDataLength(ctrlInfo)/*ctrlInfo->ControlDataWidth*/; +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlDestinationPage +// +// Description: +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// OUT UINT16 *ctrlDestPg +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS GetControlDestinationPage(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *CtrlDestPg) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *CtrlDestPg = ctrlInfo->ControlDestPageID; +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlAccess +// +// Description: Get the Control Access Specifier for a Control +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// +// Return Value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 GetControlAccess(UINT32 PgIndex, UINT32 CtrlIndex) +{ + CONTROL_FLAGS *flags = NULL; + + _GetControlFlag(PgIndex, CtrlIndex, &flags); + + return (UINT8)flags->ControlAccess; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlRefresh +// +// Description: Get the Control Refresh for a Control +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// +// Return Value: UINT8 +//---------------------------------------------------------------------------- +// +UINT8 GetControlRefresh(UINT32 PgIndex, UINT32 CtrlIndex) +{ + CONTROL_FLAGS *flags = NULL; + + _GetControlFlag(PgIndex, CtrlIndex, &flags); + + return (UINT8)flags->ControlRefresh; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: IsControlVisible +// +// Description: Get the Control Visiblity for a Control +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsControlVisible(UINT32 PgIndex, UINT32 CtrlIndex) +{ + CONTROL_FLAGS *flags = NULL; + + _GetControlFlag(PgIndex, CtrlIndex, &flags); + + return (BOOLEAN)flags->ControlVisible; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: IsControlResetRequired +// +// Description: Get the Control Reset status for a Control +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsControlResetRequired(UINT32 PgIndex, UINT32 CtrlIndex) +{ + CONTROL_FLAGS *flags = NULL; + + _GetControlFlag(PgIndex, CtrlIndex, &flags); + + return (BOOLEAN)flags->ControlReset; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: IsControlReadOnly +// +// Description: Get the Control Readonly Specifier for a Control +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsControlReadOnly(UINT32 PgIndex, UINT32 CtrlIndex) +{ + CONTROL_FLAGS *flags = NULL; + + _GetControlFlag(PgIndex, CtrlIndex, &flags); + + return (BOOLEAN)flags->ControlReadOnly; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: IsControlInteractive +// +// Description: Get the Control Interactive Specifier for a Control +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// +// Return Value: EFI_STATUS +// BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsControlInteractive(UINT32 PgIndex, UINT32 CtrlIndex) +{ + CONTROL_FLAGS *flags = (CONTROL_FLAGS *)NULL; + EFI_STATUS status = EFI_SUCCESS; + BOOLEAN isInteractive = FALSE; + + status = _GetControlFlag(PgIndex, CtrlIndex, &flags); + ASSERT_ERROR_STATUS(status); + + if(flags != NULL){ + isInteractive = (BOOLEAN)flags->ControlInteractive; + } + +DONE: + return isInteractive; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: EvaluateControlCondition +// +// Description: Evaluate control HII expression and return display Result +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// OUT UINTN *expResult +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS EvaluateControlCondition(UINT32 PgIndex, UINT32 CtrlIndex, UINTN *ExpResult) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *ExpResult = CheckControlCondition(ctrlInfo); + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetQuestionValue +// +// Description: Get the Question Value +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// OUT UINT8 *Value +// OUT UINTN *ValueSize +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +// EFI_OUT_OF_RESOURCES +//---------------------------------------------------------------------------- +// +EFI_STATUS GetQuestionValue(UINT32 PgIndex, UINT32 CtrlIndex, UINT8 **Value, UINTN *ValueSize) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_IFR_QUESTION_HEADER *questionHdr = NULL; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *ValueSize = GetControlDataLength(ctrlInfo); + *Value = (UINT8*)EfiLibAllocateZeroPool(*ValueSize); + if(*Value == NULL) + { + status = EFI_OUT_OF_RESOURCES; + + goto DONE; + } + + if(ctrlInfo->ControlType == CONTROL_TYPE_TEXT) + { + UINT16 textTwo = ((EFI_IFR_TEXT*)(ctrlInfo->ControlPtr))->TextTwo; + + MemCopy(*Value, &textTwo, *ValueSize); + goto DONE; + } + + questionHdr = (EFI_IFR_QUESTION_HEADER*)((UINT8*)ctrlInfo->ControlPtr + sizeof(EFI_IFR_OP_HEADER)); + status = VarGetValue(ctrlInfo->ControlVariable, questionHdr->VarStoreInfo.VarOffset, *ValueSize, Value); + ASSERT_ERROR_STATUS(status); + +DONE: + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: SetQuestionValue +// +// Description: Set the Value for a Question +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// IN UINT8 *Value +// IN UINTN ValueSize +// OUT UINT16 *ErrStrToken +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +//---------------------------------------------------------------------------- +// +EFI_STATUS SetQuestionValue(UINT32 PgIndex, UINT32 CtrlIndex, UINT8 *Value, UINTN ValueSize, UINT16 *ErrStrToken) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_IFR_QUESTION_HEADER *questionHdr = NULL; + CONTROL_INFO *ctrlInfo = NULL; + PAGE_INFO *pgInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + questionHdr = (EFI_IFR_QUESTION_HEADER*)((UINT8*)ctrlInfo->ControlPtr + sizeof(EFI_IFR_OP_HEADER)); + status = VarSetValue(ctrlInfo->ControlVariable, questionHdr->VarStoreInfo.VarOffset, ValueSize, Value); + ASSERT_ERROR_STATUS(status); + + status = _GetPageInfo(PgIndex, &pgInfo); + ASSERT_ERROR_STATUS(status); + + if(_InconsistenceCheck(pgInfo, ErrStrToken) == TRUE) + { + + status = EFI_INCONSISTENT_VALUE; + } + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: SaveQuestionValues +// +// Description: Save all the values to the system +// +// Parameter: VOID +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +//---------------------------------------------------------------------------- +// +EFI_STATUS SaveQuestionValues(UINT32 FormID) +{ + EFI_STATUS status = EFI_SUCCESS; + EFI_STATUS tempStatus = EFI_SUCCESS; + NVRAM_VARIABLE *nvPtr; + UINT32 i = 0; + UINT32 *varIDList = (UINT32*)EfiLibAllocateZeroPool(gVariables->VariableCount * sizeof(UINT32)); + + if(varIDList == NULL) + { + status = EFI_OUT_OF_RESOURCES; + + goto DONE; + } + + nvPtr = gVariableList; + gVarOffset = 0; +// gProFormOffset = 0; +// MemSet(gProcessedForms, MAX_FORMS_TO_PROCESS, 0); + CleargProcessedForms (); + status = _GetVariableIDList(FormID, &varIDList); + ASSERT_ERROR_STATUS(status); + for ( i = 0; i < gVariables->VariableCount; i++) + { + + if(nvPtr[varIDList[i]].Buffer == NULL) + { + + continue; + } + tempStatus = VarSetNvram(varIDList[i], nvPtr[varIDList[i]].Buffer, nvPtr[varIDList[i]].Size); + if(EFI_ERROR(tempStatus)) + { + status = tempStatus; + } + } + +DONE: + if (varIDList) { + MemFreePointer(&varIDList); + } + + + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: FreeOptionList +// +// Description: +// +// Parameter: OPTION_LIST *OptionArray +// +// Return Value: VOID +//---------------------------------------------------------------------------- +// +VOID FreeOptionList(OPTION_LIST *OptionArray) +{ + OPTION_LIST *optList = OptionArray; + + do + { + optList = OptionArray; + OptionArray = OptionArray->Next; + if(optList) + { + MemFreePointer(&optList); + } + }while(OptionArray); + +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlDisplayFormat +// +// Description: +// +// Parameter: UINT32 PgIndex +// UINT32 CtrlIndex +// UINT16 *Format +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetControlDisplayFormat(UINT32 PgIndex, UINT32 CtrlIndex, UINT16 *Format) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + if(ctrlInfo->ControlType == CONTROL_TYPE_NUMERIC) + { + + *Format = ((EFI_IFR_NUMERIC*)ctrlInfo->ControlPtr)->Flags & EFI_IFR_DISPLAY; + } + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlMinMax +// +// Description: +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// UINT64 *Min +// UINT64 *Max +// +// Return Value: EFI_STATUS +// EFI_SUCCESS +// EFI_NOT_READY +// EFI_INVALID_PARAMETER +// EFI_OUT_OF_RESOURCES +//---------------------------------------------------------------------------- +// +EFI_STATUS GetControlMinMax(UINT32 PgIndex, UINT32 CtrlIndex, UINT64 *Min, UINT64 *Max) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + switch(ctrlInfo->ControlType) + { + case CONTROL_TYPE_NUMERIC: + case CONTROL_TYPE_PASSWORD: + case CONTROL_TYPE_POPUP_STRING: + + *Min = UefiGetMinValue(ctrlInfo->ControlPtr); + *Max = UefiGetMaxValue(ctrlInfo->ControlPtr); + break; + default: + + break; + } + +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetControlDefault +// +// Description: +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// UINT64 *Def +// BOOLEAN Optimal +// +// Return Value: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetControlDefault(UINT32 PgIndex, UINT32 CtrlIndex,UINT8 *Def, BOOLEAN Optimal) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + + if(Def == NULL) + { + status = EFI_INVALID_PARAMETER; + + goto DONE; + } + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + switch(ctrlInfo->ControlDataWidth) + { + /* + * ctrlInfo[sizeof(ctrlInfo)] + * Used when user selects load Optimal value + * + * ctrlInfo[sizeof(ctrlInfo) + valSize] + * Used when user selects load optimal value + */ + case 1: // BYTE + + *Def = Optimal? *((UINT8 *) ((UINT8 *)ctrlInfo + sizeof(*ctrlInfo))) : + *((UINT8 *) ((UINT8 *)ctrlInfo + sizeof(*ctrlInfo) + ctrlInfo->ControlDataWidth)); + break; + case 2: //WORD + + *((UINT16*)Def) = Optimal? *((UINT16 *) ((UINT8 *)ctrlInfo + sizeof(*ctrlInfo))) : + *((UINT16 *) ((UINT8 *)ctrlInfo + sizeof(*ctrlInfo) + ctrlInfo->ControlDataWidth)); + break; + case 4: //DWORD + + *((UINT32*)Def) = Optimal? *((UINT32 *) ((UINT8 *)ctrlInfo + sizeof(*ctrlInfo))) : + *((UINT32 *) ((UINT8 *)ctrlInfo + sizeof(*ctrlInfo) + ctrlInfo->ControlDataWidth)); + break; + case 8: //QWORD + + *((UINT64*)Def) = Optimal? *((UINT64 *) ((UINT8 *)ctrlInfo + sizeof(*ctrlInfo))) : + *((UINT64 *) ((UINT8 *)ctrlInfo + sizeof(*ctrlInfo) + ctrlInfo->ControlDataWidth)); + break; + default: + break; + } + +DONE: + + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetOrderedListMaxEntries +// +// Description: Create a Timer Event +// +// Input: UINT32 PgIndex, UINT32 CtrlIndex, UINT8 *MaxEntry +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetOrderedListMaxEntries(UINT32 PgIndex, UINT32 CtrlIndex, UINT8 *MaxEntry) +{ + EFI_STATUS status = EFI_SUCCESS; + CONTROL_INFO *ctrlInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + *MaxEntry = 0; + if(ctrlInfo->ControlType == CONTROL_TYPE_ORDERED_LIST) + { + *MaxEntry = UefiGetMaxEntries(ctrlInfo->ControlPtr); + } +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetOrderedListOptionDataWidth +// +// Description: Gets OrderedList Data Width +// +// Parameter: CONTROL_INFO *ControlInfo, UINT32 *DataWidth +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetOrderedListOptionDataWidth(CONTROL_INFO *ControlInfo, UINT32 *DataWidth) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_IFR_OP_HEADER *OpHeader = NULL; + EFI_IFR_ONE_OF_OPTION *OneOfOptionOp = NULL; + + OpHeader = (EFI_IFR_OP_HEADER*)ControlInfo->ControlPtr; + + if(OpHeader->OpCode != EFI_IFR_ORDERED_LIST_OP) + { + Status = EFI_UNSUPPORTED; + goto DONE; + } + + do + { + OpHeader = (EFI_IFR_OP_HEADER*)((UINT8*)ControlInfo->ControlPtr + OpHeader->Length); + }while(OpHeader->OpCode != EFI_IFR_ONE_OF_OPTION_OP); + + OneOfOptionOp = (EFI_IFR_ONE_OF_OPTION*)OpHeader; + + switch(OneOfOptionOp->Type) + { + case EFI_IFR_TYPE_NUM_SIZE_16: + *DataWidth = sizeof(UINT16); + break; + case EFI_IFR_TYPE_NUM_SIZE_32: + *DataWidth = sizeof(UINT32); + break; + case EFI_IFR_TYPE_NUM_SIZE_64: + *DataWidth = sizeof(UINT64); + break; + case EFI_IFR_TYPE_NUM_SIZE_8: + default: + *DataWidth = sizeof(UINT8); + break; + } + +DONE: + return Status; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: GetOrderedListDataTypeWidth +// +// Description: Gets OrderedList DataType Width +// +// Parameter: UINT32 PgIndex, UINT32 CtrlIndex, UINT32 *DataWidth +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetOrderedListDataTypeWidth(UINT32 PgIndex, UINT32 CtrlIndex, UINT32 *DataWidth) +{ + EFI_STATUS Status = EFI_SUCCESS; + CONTROL_INFO *CtrlInfo = NULL; + + Status = _GetControlInfo(PgIndex, CtrlIndex, &CtrlInfo); + if(EFI_ERROR(Status)) + { + goto DONE; + } + + Status = GetOrderedListOptionDataWidth(CtrlInfo, DataWidth); + +DONE: + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IsPageRefreshable +// +// Description: Is this page can be refreshable +// +// Parameter: IN UINT32 PgIndex +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsPageRefreshable(UINT32 PgIndex) +{ + EFI_STATUS status = EFI_SUCCESS; + BOOLEAN isTrue = FALSE; + PAGE_INFO *pageInfo = NULL; + + status = _GetPageInfo(PgIndex, &pageInfo); + ASSERT_ERROR_STATUS(status); + isTrue = pageInfo->PageFlags.PageRefresh ? TRUE : FALSE; + +DONE: + return isTrue; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IfNoCommitVariable +// +// Description: Is this a no commit variable +// +// Parameter: IN UINT32 PgIndex +// IN UINT32 CtrlIndex +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IfNoCommitVariable(UINT32 PgIndex, UINT32 CtrlIndex) +{ + EFI_STATUS status = EFI_SUCCESS; + BOOLEAN isTrue = FALSE; + CONTROL_INFO *CtrlInfo = NULL; + VARIABLE_INFO *varInfo = NULL; + + status = _GetControlInfo(PgIndex, CtrlIndex, &CtrlInfo); + ASSERT_ERROR_STATUS(status); + varInfo = VarGetVariableInfoIndex(CtrlInfo->ControlVariable); + if((varInfo != NULL) && (varInfo->ExtendedAttibutes /*& AMI_SPECIAL_NO_COMMIT_VARIABLE*/)){ //If the variable is valid and set to NO_COMMIT + isTrue = TRUE; + } +DONE: + return isTrue; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IdentifyFormHasDefault +// +// Description: Is this formset has the default set +// +// Parameter: IN UINT32 FormID +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IdentifyFormHasDefault(UINT32 FormID) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 count = 0; + UINT32 index = 0; + CONTROL_INFO *ctrlInfo; + BOOLEAN isDefault = FALSE; + +// gProcessedForms[gProFormOffset++] = FormID; + AddEntryIngProcessedForms (FormID); + + status = GetNumOfControls(FormID, &count); + ASSERT_ERROR_STATUS(status); + + for(index = 0; index < count; index++) + { + + status = _GetControlInfo(FormID, index, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + if((ctrlInfo->ControlType == CONTROL_TYPE_SUBMENU)//If submenu traverse recursively through the sub forms + || (ctrlInfo->ControlType == CONTROL_TYPE_REF2)) + { + + if(_DestinationFormProcessed(ctrlInfo->ControlDestPageID) == FALSE)//If the form has not be processed already + { + isDefault = IdentifyFormHasDefault(ctrlInfo->ControlDestPageID); + if(isDefault) + { + break; + } + } + } + + if(ctrlInfo->ControlType == CONTROL_TYPE_CHECKBOX || //Check for the control is checkbox + ctrlInfo->ControlFlags.ControlEvaluateDefault || //or if the control has the Evaluate default bit set + ctrlInfo->ControlDataWidth) // or if the ControlDataWidth is set to the size of the defaults + { + isDefault = TRUE; + break; + } + }//end of for loop of controls + +DONE: + return isDefault; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IsFormsetHasDefault +// +// Description: Is this formset has the default set +// +// Parameter: IN UINT32 FormID +// +// Return Value: BOOLEAN +//---------------------------------------------------------------------------- +// +BOOLEAN IsFormsetHasDefault(UINT32 FormID) +{ + BOOLEAN isDefault = FALSE; + +// gProFormOffset = 0; +// MemSet(gProcessedForms, MAX_FORMS_TO_PROCESS, 0); + CleargProcessedForms (); + isDefault = IdentifyFormHasDefault(FormID); + + return isDefault; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetPageGuidFromFormId +// +// Description: To get the form GUID from the page index +// +// Input: UINT32 PgIndex +// EFI_GUID *FormGuid +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS GetPageGuidFromPgIndex(UINT32 PgIndex, EFI_GUID *FormGuid) +{ + EFI_STATUS status = EFI_INVALID_PARAMETER; + PAGE_INFO *pgInfo = (PAGE_INFO *)NULL; + PAGE_ID_INFO *pageIdInfo = (PAGE_ID_INFO*)NULL; + + status = _GetPageInfo(PgIndex, &pgInfo); + ASSERT_ERROR_STATUS(status); + + if(gPages && gPageIdList && pgInfo) + { + pageIdInfo = (PAGE_ID_INFO *)(((UINT8 *) gPageIdList) + gPageIdList->PageIdList[pgInfo->PageIdIndex]); + if(pageIdInfo) + { + MemCopy(FormGuid, &pageIdInfo->PageGuid, sizeof(EFI_GUID)); + } + } + +DONE: + return status; +} +//EIP81814 Ends + +//EIP 86885 Starts +// +//-------------------------------------------------------------------------------------- +// Procedure: UefiVarsetnvramforCurrentform +// +// Description: Save the values for the passed pageID +// If this function is not called as part of browser action then it is +// caller responsibility to reset the gProFormOffset and gProcessedForms +// gProFormOffset = 0; +// MemSet (gProcessedForms, MAX_FORMS_TO_PROCESS, 0); +// +// Input: UINT32 - page ID to save the values +// +// Output: EFI_STATUS - Status of the operation +//-------------------------------------------------------------------------------------- +// +EFI_STATUS UefiVarsetnvramforCurrentform (UINT32 FormID) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 count = 0; + UINT32 index = 0; + CONTROL_INFO *ctrlInfo; + UINT8 *tempLoadVarBuff = (UINT8 *)NULL; + UINT8 *CurrentValue = NULL; + UINTN CurVarSize = 0; + UINT32 size = 0; + UINT32 offset = 0; + VARIABLE_INFO *varInfo = (VARIABLE_INFO *)NULL; + +// gProcessedForms [gProFormOffset++] = FormID; + AddEntryIngProcessedForms (FormID); + + status = GetNumOfControls (FormID, &count); + ASSERT_ERROR_STATUS (status); + + for(index = 0; index < count; index++) + { + status = _GetControlInfo(FormID , index, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + if (NULL == ctrlInfo->ControlPtr) //EIP-Setup crashes when clicking Discard and Exit goto control in simulator + continue; + + if((ctrlInfo->ControlType == CONTROL_TYPE_SUBMENU) || (ctrlInfo->ControlType == CONTROL_TYPE_REF2)) + { + if(_DestinationFormProcessed(ctrlInfo->ControlDestPageID) == FALSE) + { + UefiVarsetnvramforCurrentform(ctrlInfo->ControlDestPageID); + } + continue; + } + tempLoadVarBuff = VarGetNvram( ctrlInfo->ControlVariable, &CurVarSize ); + if (NULL == tempLoadVarBuff) + { + continue; + } + offset = UefiGetQuestionOffset (ctrlInfo->ControlPtr); + if(CONTROL_TYPE_ORDERED_LIST == ctrlInfo->ControlType) + { + UINTN Type = 0; + UefiGetValidOptionType (ctrlInfo, &Type, &size); + size = (UefiGetMaxEntries (ctrlInfo->ControlPtr)) * size; + } + else + { + size = UefiGetWidth(ctrlInfo->ControlPtr); + } + if (0 == size) + { + continue; + } + CurrentValue = EfiLibAllocateZeroPool(size); + if(CurrentValue == NULL) + { + return EFI_OUT_OF_RESOURCES; + } + status = VarGetValue(ctrlInfo->ControlVariable, offset, size, CurrentValue ); + if (!EFI_ERROR (status)) + { + MemCopy ( tempLoadVarBuff+offset, CurrentValue, size ); + + varInfo = VarGetVariableInfoIndex (ctrlInfo->ControlVariable); + if(varInfo == NULL) + { + continue; + } + + if((varInfo->ExtendedAttibutes & AMI_SPECIAL_VARIABLE_NO_SET) == AMI_SPECIAL_VARIABLE_NO_SET) + { + // Don't save the variable + continue; + } + else + { + if(UefiIsEfiVariable(ctrlInfo->ControlVariable, varInfo)) + { + VarSetNvramName( varInfo->VariableName, &varInfo->VariableGuid, varInfo->VariableAttributes, tempLoadVarBuff, CurVarSize ); + } + else + { + UefiVarSetNvram(varInfo, tempLoadVarBuff, VAR_ZERO_OFFSET, CurVarSize); + } + } + } + MemFreePointer ((VOID **)&tempLoadVarBuff); + MemFreePointer ((VOID **)&CurrentValue); + } +DONE: + return status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: UefiLoadPreviousValuesforCurrentform +// +// Description: Loads previous value for the current form +// +// Input: FormID - Current page ID +// +// Output: EFI_STATUS +//---------------------------------------------------------------------------- +// +EFI_STATUS UefiLoadPreviousValuesforCurrentform(UINT32 FormID) +{ + EFI_STATUS status = EFI_SUCCESS; + UINT32 count = 0; + UINT32 index = 0; + CONTROL_INFO *ctrlInfo; + UINT8 *tempLoadVarBuff = (UINT8 *)NULL; + UINT8 *CurrentValue = NULL; + UINTN CurVarSize = 0; + UINT32 size = 0; + UINT32 offset = 0; + +// gProcessedForms [gProFormOffset++] = FormID; + AddEntryIngProcessedForms (FormID); + + status = GetNumOfControls (FormID, &count); + ASSERT_ERROR_STATUS (status); + + for(index = 0; index < count; index++) + { + status = _GetControlInfo(FormID , index, &ctrlInfo); + ASSERT_ERROR_STATUS(status); + + if (NULL == ctrlInfo->ControlPtr) //EIP-126997 Avoid setup crash + continue; + + if((ctrlInfo->ControlType == CONTROL_TYPE_SUBMENU) || (ctrlInfo->ControlType == CONTROL_TYPE_REF2)) + { + if(_DestinationFormProcessed(ctrlInfo->ControlDestPageID) == FALSE) + { + UefiVarsetnvramforCurrentform(ctrlInfo->ControlDestPageID); + } + } + tempLoadVarBuff = VarGetNvram (ctrlInfo->ControlVariable, &CurVarSize); + if (NULL == tempLoadVarBuff) + { + continue; + } + offset = UefiGetQuestionOffset (ctrlInfo->ControlPtr); + if (CONTROL_TYPE_ORDERED_LIST == ctrlInfo->ControlType) + { + UINTN Type = 0; + UefiGetValidOptionType (ctrlInfo, &Type, &size); + size = (UefiGetMaxEntries (ctrlInfo->ControlPtr)) * size; + } + else + { + size = UefiGetWidth (ctrlInfo->ControlPtr); + } + CurrentValue = EfiLibAllocateZeroPool(size); + if(CurrentValue == NULL) + { + return EFI_OUT_OF_RESOURCES; + } + status = VarGetValue (ctrlInfo->ControlVariable, offset, size, CurrentValue); + if (!EFI_ERROR (status)) + { + MemCopy (gVariableList [ctrlInfo->ControlVariable].Buffer + offset, tempLoadVarBuff + offset, size); + } + MemFreePointer ((VOID **)&tempLoadVarBuff); + MemFreePointer ((VOID **)&CurrentValue); + } +DONE: + return status; +} +//EIP 86885 Ends + +///////////////EIP 162180 Starts////////////////////////// +// +//---------------------------------------------------------------------------- +// Procedure: CleargProcessedForms +// +// Description: Clears gProcessedForms data +// +// Input: void +// +// Output: void +//---------------------------------------------------------------------------- +// +void CleargProcessedForms (void) +{ + gProFormOffset = 0; + MemSet(gProcessedForms, (gProFormOffsetAllocCount * sizeof (UINT32)), 0); +} + +// +//---------------------------------------------------------------------------- +// Procedure: AddEntryIngProcessedForms +// +// Description: Adds the formid in gProcessedForms +// +// Input: UINT32 FormID +// +// Output: void +//---------------------------------------------------------------------------- +// +void AddEntryIngProcessedForms (UINT32 FormID) +{ + if (gProFormOffset >= gProFormOffsetAllocCount) //Check if enough size has been already allocated + { + gProcessedForms = MemReallocateZeroPool (gProcessedForms, gProFormOffsetAllocCount * sizeof (UINT32), (gProFormOffsetAllocCount + MAX_FORMS_TO_PROCESS) * sizeof (UINT32)); + if (NULL == gProcessedForms) + { + return; + } + gProFormOffsetAllocCount += MAX_FORMS_TO_PROCESS; + } + gProcessedForms [gProFormOffset++] = FormID; +} +///////////////EIP 162180 Ends////////////////////////// +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** \ No newline at end of file diff --git a/EDK/MiniSetup/uefi2.1/UefiTianoHii.h b/EDK/MiniSetup/uefi2.1/UefiTianoHii.h new file mode 100644 index 0000000..4978f3f --- /dev/null +++ b/EDK/MiniSetup/uefi2.1/UefiTianoHii.h @@ -0,0 +1,241 @@ +//********************************************************************** +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2010, 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/Uefi2.1/UefiTianoHii.h $ +// +// $Author: Arunsb $ +// +// $Revision: 3 $ +// +// $Date: 10/18/12 6:04a $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/UefiTianoHii.h $ +// +// 3 10/18/12 6:04a Arunsb +// Updated for 2.16.1235 QA submission +// +// 4 10/10/12 12:41p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 2 4/16/10 5:13p Madhans +// Changes for Tse 2.02. Please see Changelog.log for more details. +// +// 2 3/11/10 5:44p Madhans +// Coding Standards Update +// +//*****************************************************************// +// +// +// Name: UefiTianoHii.h +// +// Description: +// +// +//****************************************************************// + + +//---------------------------------------------------------------------------- +#ifndef _TIANO_HII_H_ +#define _TIANO_HII_H_ + +#include "TseUefiHii.h" + +#define NARROW_CHAR 0xFFF0 +#define WIDE_CHAR 0xFFF1 +#define NON_BREAKING_CHAR 0xFFF2 + +// +// State defined for password statemachine +// +#define BROWSER_STATE_VALIDATE_PASSWORD 0 +#define BROWSER_STATE_SET_PASSWORD 1 + +// +// References to string tokens must use this macro to enable scanning for +// token usages. +// +#define STRING_TOKEN(t) t + +// +// GUIDed opcodes defined for Tiano +// +#define EFI_IFR_TIANO_GUID \ + { 0xf0b1735, 0x87a0, 0x4193, 0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce } + +//---------------------------------------------------------------------------- + + +#pragma pack(1) + + +//---------------------------------------------------------------------------- + +#define EFI_IFR_EXTEND_OP_LABEL 0x0 +#define EFI_IFR_EXTEND_OP_BANNER 0x1 +#define EFI_IFR_EXTEND_OP_TIMEOUT 0x2 +#define EFI_IFR_EXTEND_OP_CLASS 0x3 +#define EFI_IFR_EXTEND_OP_SUBCLASS 0x4 + +//---------------------------------------------------------------------------- + +// +//---------------------------------------------------------------------------- +// Name: EFI_IFR_GUID_LABEL +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Header EFI_IFR_OP_HEADER +// Guid EFI_GUID +// ExtendOpCode UINT8 +// Number UINT16 +//---------------------------------------------------------------------------- +// +typedef struct _EFI_IFR_GUID_LABEL { + EFI_IFR_OP_HEADER Header; + EFI_GUID Guid; + UINT8 ExtendOpCode; + UINT16 Number; +} EFI_IFR_GUID_LABEL; + +//---------------------------------------------------------------------------- + +#define EFI_IFR_BANNER_ALIGN_LEFT 0 +#define EFI_IFR_BANNER_ALIGN_CENTER 1 +#define EFI_IFR_BANNER_ALIGN_RIGHT 2 + +//---------------------------------------------------------------------------- + +// +//---------------------------------------------------------------------------- +// Name: EFI_IFR_GUID_BANNER +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Header EFI_IFR_OP_HEADER +// Guid EFI_GUID +// ExtendOpCode UINT8 +// Title EFI_STRING_ID +// LineNumber UINT16 +// Alignment UINT8 +//---------------------------------------------------------------------------- +// +typedef struct _EFI_IFR_GUID_BANNER { + EFI_IFR_OP_HEADER Header; + EFI_GUID Guid; + UINT8 ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER + EFI_STRING_ID Title; // The string token for the banner title + UINT16 LineNumber; // 1-based line number + UINT8 Alignment; // left, center, or right-aligned +} EFI_IFR_GUID_BANNER; + + +// +//---------------------------------------------------------------------------- +// Name: EFI_IFR_GUID_TIMEOUT +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Header EFI_IFR_OP_HEADER +// Guid EFI_GUID +// ExtendOpCode UINT8 +// TimeOut UINT16 +//---------------------------------------------------------------------------- +// +typedef struct _EFI_IFR_GUID_TIMEOUT { + EFI_IFR_OP_HEADER Header; + EFI_GUID Guid; + UINT8 ExtendOpCode; + UINT16 TimeOut; +} EFI_IFR_GUID_TIMEOUT; + +//---------------------------------------------------------------------------- + +#define EFI_NON_DEVICE_CLASS 0x00 +#define EFI_DISK_DEVICE_CLASS 0x01 +#define EFI_VIDEO_DEVICE_CLASS 0x02 +#define EFI_NETWORK_DEVICE_CLASS 0x04 +#define EFI_INPUT_DEVICE_CLASS 0x08 +#define EFI_ON_BOARD_DEVICE_CLASS 0x10 +#define EFI_OTHER_DEVICE_CLASS 0x20 + +//---------------------------------------------------------------------------- + +// +//---------------------------------------------------------------------------- +// Name: EFI_IFR_GUID_CLASS +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Header EFI_IFR_OP_HEADER +// Guid EFI_GUID +// ExtendOpCode UINT8 +// Class UINT16 +//---------------------------------------------------------------------------- +// +typedef struct _EFI_IFR_GUID_CLASS { + EFI_IFR_OP_HEADER Header; + EFI_GUID Guid; + UINT8 ExtendOpCode; + UINT16 Class; +} EFI_IFR_GUID_CLASS; + +//---------------------------------------------------------------------------- + +#define EFI_SETUP_APPLICATION_SUBCLASS 0x00 +#define EFI_GENERAL_APPLICATION_SUBCLASS 0x01 +#define EFI_FRONT_PAGE_SUBCLASS 0x02 +#define EFI_SINGLE_USE_SUBCLASS 0x03 + +//---------------------------------------------------------------------------- + + +// +//---------------------------------------------------------------------------- +// Name: EFI_IFR_GUID_SUBCLASS +// +// Description: +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// Header EFI_IFR_OP_HEADER +// Guid EFI_GUID +// ExtendOpCode UINT8 +// SubClass UINT16 +//---------------------------------------------------------------------------- +// +typedef struct _EFI_IFR_GUID_SUBCLASS { + EFI_IFR_OP_HEADER Header; + EFI_GUID Guid; + UINT8 ExtendOpCode; + UINT16 SubClass; +} EFI_IFR_GUID_SUBCLASS; + + +#pragma pack() + + +#endif -- cgit v1.2.3