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.0/hii.c | 3273 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3273 insertions(+) create mode 100644 EDK/MiniSetup/uefi2.0/hii.c (limited to 'EDK/MiniSetup/uefi2.0/hii.c') diff --git a/EDK/MiniSetup/uefi2.0/hii.c b/EDK/MiniSetup/uefi2.0/hii.c new file mode 100644 index 0000000..0e6b2c8 --- /dev/null +++ b/EDK/MiniSetup/uefi2.0/hii.c @@ -0,0 +1,3273 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (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.0/hii.c $ +// +// $Author: Arunsb $ +// +// $Revision: 23 $ +// +// $Date: 4/18/13 9:35a $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/uefi2.0/hii.c $ +// +// 23 4/18/13 9:35a Arunsb +// Dummy functions added to avoid build error in 2.0 build +// +// 22 3/25/13 8:32a 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 +// +// 21 10/18/12 6:00a Arunsb +// Updated for 2.16.1235 QA submission +// +// 17 10/10/12 12:39p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 19 9/25/12 3:04p Arunsb +// RTIfrRegFormNotificationWrapper function call removed +// +// 17 6/04/11 12:26p Arunsb +// [TAG] EIP48930 +// [Description] Boot override hangs with exception 0x0d +// [Files] uefi2.1\Parse.c, uefi2.0\hii.c +// +// 16 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 +// +// 15 5/31/11 9:51a Premkumara +// [TAG] EIP48930 +// [Description] Boot override hangs with exception 0x0d +// [Files] hii.c, Parse.c +// +// 14 3/28/11 10:05p Premkumara +// [TAG] 52562 +// [Category] Enhancement +// [Description] Need to have the Fixed Limit in AMITSE module for +// Controls, Pages and Variable etc. +// [Files] TSEUefiHii.h, Parse.c, Hii.c, hii.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 2/03/11 3:47p Mallikarjunanv +// Initialized the control flags properly +// +// 11 2/03/11 1:04p Mallikarjunanv +// Fixed the issue in TSE Lite with respect to setting control info read +// only flags. Which caused issues when selecting some controls. +// +// 10 2/03/11 12:40p Mallikarjunanv +// [TAG] EIP48587 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Press "F3" not loading the optimized defaults for controls +// [RootCause] Defaults were not updated properly for UEFI 2.0 +// [Solution] Updated the defaults values based on controls offsets and +// check box controls are modified as one-of options. +// [Files] hii.c +// +// 9 10/05/10 3:50p Madhans +// [TAG] - EIP 45511 +// [Category]- BUG FIX +// [Severity]- Major +// [Symptom]- TSE 2.10 with UEFI 2.0 may not work with Runtime Prasing. It +// crashs the system. +// [RootCause]- Initilization of VARIABLE_INFO is affected becaus of UEFI +// 2.1 modifications. +// [Solution]- Initlize the VARIABLE_INFO Strcture with Zero. +// [Files] - hii.c +// +// 8 7/23/10 5:21p Blaines +// Fix root page processing to support Award Style setup. +// +// 7 2/26/10 8:54p Madhans +// For TSE 2.01.1024. refer changelog.log for file checkin history . +// +// 11 2/25/10 7:08p Madhans +// To build the defaults with the NVRAM values. This will avoid issues +// caused when defaults load. +// +// 10 2/19/10 8:20a Mallikarjunanv +// updated year in copyright message +// +// 9 2/17/10 11:26p Madhans +// default Var Attribute for the Var store updated to BS+RT+NV +// +// 8 1/09/10 7:25a Mallikarjunanv +// Updated TSE2.01 Release sources with coding standards +// +// 7 12/22/09 6:40p Madhans +// // EIP: 32318 fix for the crash issue when the page has many controls. +// +// 6 8/20/09 3:11p Madhans +// //EIP 25092 : Fix to Use the HiiChangeString() to Add the string for +// morethen one langs. +// +// 5 8/13/09 7:42a Mallikarjunanv +// modified and moved the function HiiGetEfiKey from binary to uefi module +// +// 4 7/23/09 8:52a Mallikarjunanv +// updated function InitFormsetLinks for eip-24060 +// +// 3 6/23/09 6:51p Blaines +// Coding standard update, +// Remove spaces from file header to allow proper chm function list +// creation. +// +// 2 6/12/09 7:44p Presannar +// Initial implementation of coding standards for AMITSE2.0 +// +// 1 6/04/09 8:05p Madhans +// +// 1 4/28/09 11:08p Madhans +// Tse 2.0 Code complete Checkin. +// +// 3 3/31/09 4:14p Madhans +// UEFI Wrapper improvments. +// +// 2 1/30/09 6:06p Madhans +// Function headers added. +// +// 1 12/18/08 7:59p Madhans +// Intial version of TSE Lite sources +//*****************************************************************// +//*****************************************************************// + +// +//---------------------------------------------------------------------------- +// +// Name: hii.c +// +// Description: This file contains code to handle the uefi2.0 based hii operations +// +//---------------------------------------------------------------------------- +// + +#include "minisetup.h" +#include EFI_PROTOCOL_DEFINITION(Hii) +#include EFI_PROTOCOL_DEFINITION(FormCallback) +extern EFI_HII_PROTOCOL *gHiiProtocol; + +// Maximum supported page, variables, controls. +#define MAX_PAGE 100 +#define MAX_CONTROLS 0xFFFF +#define MAX_VARIABLE 100 +//--------------------------------------------------------------------------- +static VOID* *gSetupHandles = NULL; +UINTN gSetupCount = 0; +#pragma pack(1) +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; +} +SETUP_LINK; +#pragma pack() + +UINTN gDynamicPageCount=0; +static SETUP_LINK *gSetupData = NULL; + +static UINT32 ControlListSize, ControlListOffset; + +static PAGE_LIST *PageListPtr; +static PAGE_INFO *PageInfoPtr; +static UINT32 PageListSize, PageListOffset, PageInfoSize, PageInfoOffset; + +static UINT32 AllocatedFirstPageSize = 0, FirstPageOffset = 0; +static PAGE_INFO *FirstPage = NULL; + +EFI_IFR_FORM_SET *HiiGetFormSetFromHandle( /*EFI_HII_HANDLE*/VOID* handle ); +EFI_IFR_FORM_SET *HiiGetFormSet( UINTN index ); + +UINT32 AddControlToList(CONTROL_INFO *NewControlInfo, UINT32 ControlSize); +VOID AddPageToList(PAGE_INFO *NewPageInfo, UINT32 PageSize); +VOID CreatePage(PAGE_INFO **PageInfo, UINT32 *AllocatedSize, UINT32 *Offset, VOID *Buff, UINT32 BuffSize); +VOID MergePageListAndInfo(); + + +VOID RTIfrProcessExitWrapper(VOID); +VOID RTIfrProcessAddVarListAndPageIDListWrapper(VOID); +BOOLEAN RTIfrProcessFormIfUpdatedWrapper(UINT16 link); +VOID RTIfrProcessRunTimeFormsWrapper(EFI_IFR_REF **ref); + +VOID AddDynamicForm(UINT32 HiiIndex); +int AddVariable(EFI_IFR_VARSTORE *Varstore); +VOID AddPageIdToList(PAGE_ID_INFO *NewPageIdInfo, UINT32 PageIdSize); +VOID MergePageIdListAndInfo(); +VOID AddVariableToList(VARIABLE_INFO *NewVariableInfo, UINT32 VariableSize); +VOID MergeVariableListAndInfo(); +UINTN AddHpkControls(UINT32 HiiIndex, UINT8 *buff,UINTN size, PAGE_INFO **NewPageInfo, UINT32 *AllocatedPageSize, UINT32 *PageOffset); +EFI_STATUS _DisplayErrorMessage(CHAR16 *Temp); + +static PAGE_ID_LIST *PageIdListPtr; +static PAGE_ID_INFO *PageIdInfoPtr; +static UINT32 PageIdListSize, PageIdListOffset, PageIdInfoSize, PageIdInfoOffset; + +static VARIABLE_LIST *VariableListPtr; +static VARIABLE_INFO *VariableInfoPtr; +static UINT32 VariableListSize, VariableListOffset, VariableInfoSize, VariableInfoOffset; + +#define DEFAULT_REFRESH_RATE 0x01 +#define DEFAULT_DATETIME_REFRESH 0x05 +#define FORM_SUBCLASS 3 +#define CONTROL_TYPE_TITLE CONTROL_TYPE_NULL +#define CONTROL_TYPE_MASK 0x0FFF + +#define START_EVAL_IF 0x8000 +#define END_EVAL_IF 0x8001 + +typedef struct PAGELINK +{ + UINT16 FormID; // number from hpk + UINT16 ParentPageID; // number from the tool + UINT16 PageNum; // number assigned by the tool + +}PageLink; + +typedef struct _VAR_KEY_TABLE +{ + UINT32 VarId; + UINT16 Index; + struct _VAR_KEY_TABLE *Next; +}*PVAR_KEY_TABLE, VAR_KEY_TABLE; + +VAR_KEY_TABLE VarKeyTable; + +typedef struct FORMSETLINKS +{ + UINT16 PageCount; + PageLink PageLink[20]; +}FormSetLinks; + +FormSetLinks *FSetLinks = NULL; + +UINT32 CtrlVar=0, CtrlCondVar=0, CtrlCondVar2=0, ActualCondVar=0, ActualCondVar2=0; +UINT32 controllabel=0,controlindex=0; +UINTN updatecondvars=1; + +unsigned short controltypes[] = +{ + CONTROL_TYPE_TITLE, //#define EFI_IFR_FORM_OP 0x01 + CONTROL_TYPE_MEMO, //#define EFI_IFR_SUBTITLE_OP 0x02 + CONTROL_TYPE_TEXT, //#define EFI_IFR_TEXT_OP 0x03 + 0x0, //#define EFI_IFR_GRAPHIC_OP 0x04 + CONTROL_TYPE_POPUPSEL, //#define EFI_IFR_ONE_OF_OP 0x05 + CONTROL_TYPE_CHECKBOX, //#define EFI_IFR_CHECKBOX_OP 0x06 + CONTROL_TYPE_NUMERIC, //#define EFI_IFR_NUMERIC_OP 0x07 + CONTROL_TYPE_PASSWORD, //#define EFI_IFR_PASSWORD_OP 0x08 + 0x0, //#define EFI_IFR_ONE_OF_OPTION_OP 0x09 // ONEOF OPTION field + START_EVAL_IF, //#define EFI_IFR_SUPPRESS_IF_OP 0x0A + 0x0, //#define EFI_IFR_END_FORM_OP 0x0B + 0x0, //#define EFI_IFR_HIDDEN_OP 0x0C + 0x0, //#define EFI_IFR_END_FORM_SET_OP 0x0D + 0x0, //#define EFI_IFR_FORM_SET_OP 0x0E + CONTROL_TYPE_SUBMENU, //#define EFI_IFR_REF_OP 0x0F + 0x0, //#define EFI_IFR_END_ONE_OF_OP 0x10 + //0x0, //#define EFI_IFR_END_OP EFI_IFR_END_ONE_OF_OP + INCONSISTENT_IF, //#define EFI_IFR_INCONSISTENT_IF_OP 0x11 + 0x0, //#define EFI_IFR_EQ_ID_VAL_OP 0x12 + 0x0, //#define EFI_IFR_EQ_ID_ID_OP 0x13 + 0x0, //#define EFI_IFR_EQ_ID_LIST_OP 0x14 + 0x0, //#define EFI_IFR_AND_OP 0x15 + 0x0, //#define EFI_IFR_OR_OP 0x16 + 0x0, //#define EFI_IFR_NOT_OP 0x17 + END_EVAL_IF, //#define EFI_IFR_END_IF_OP 0x18 // for endif of inconsistentif, suppressif, grayoutif + START_EVAL_IF, //#define EFI_IFR_GRAYOUT_IF_OP 0x19 + CONTROL_TYPE_DATE, //#define EFI_IFR_DATE_OP 0x1A + CONTROL_TYPE_TIME, //#define EFI_IFR_TIME_OP 0x1B + CONTROL_TYPE_POPUP_STRING, //#define EFI_IFR_STRING_OP 0x1C + 0x0, //#define EFI_IFR_LABEL_OP 0x1D // defines location where controls can be added + 0x0, //#define EFI_IFR_SAVE_DEFAULTS_OP 0x1E + 0x0, //#define EFI_IFR_RESTORE_DEFAULTS_OP 0x1F + 0x0, //#define EFI_IFR_BANNER_OP 0x20 + 0x0, //#define EFI_IFR_INVENTORY_OP 0x21 + 0x0, //#define EFI_IFR_EQ_VAR_VAL_OP 0x22 + CONTROL_TYPE_ORDERED_LIST, //#define EFI_IFR_ORDERED_LIST_OP 0x23 + CONTROL_TYPE_VARSTORE, //#define EFI_IFR_VARSTORE_OP 0x24 + CONTROL_TYPE_VARSTORE_SELECT, //#define EFI_IFR_VARSTORE_SELECT_OP 0x25 + CONTROL_TYPE_VARSTORE_SELECT_PAIR, //#define EFI_IFR_VARSTORE_SELECT_PAIR_OP 0x26 + 0x0, //#define EFI_IFR_LAST_OPCODE EFI_IFR_VARSTORE_SELECT_PAIR_OP + 0x0, //#define EFI_IFR_NV_ACCESS_COMMAND 0xFF +}; + + + +UINTN TotalRootPages; + +// +//---------------------------------------------------------------------------- +// Procedure: HiiExit +// +// Description: performs the operations that required to exit from HII +// +// Input: VOID +// +// Output: Status +// +//---------------------------------------------------------------------------- +// +EFI_STATUS HiiExit( VOID ) +{ + 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; + + RTIfrProcessExitWrapper(); + + gVariables = gToolVariables; + gPageIdList = gToolPageIdList; + gPageIdInfo = (PAGE_ID_INFO *)(((UINT8 *) gPageIdList) + gPageIdList->PageIdList[0]); + + return EFI_SUCCESS; +} + +VOID FixupPage0ControlInfo( UINTN FormSet, UINTN ControlPtr, VOID* 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; + } + } + } + +} + + +// +//---------------------------------------------------------------------------- +// Procedure: HiiFixupData +// +// Description: Function to fixup hhi data +// +// Input: NIL +// +// Output: Status +// +//---------------------------------------------------------------------------- +// +EFI_STATUS HiiFixupData( ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 i, j=0; + + PAGE_INFO *pageInfo = NULL; + EFI_IFR_FORM_SET *formSet; + EFI_IFR_REF *ref = NULL; + + UINT16 link; + + Status = _HiiLocateSetupHandles(); + if ( EFI_ERROR( Status ) ) + return Status; + + gSetupData = EfiLibAllocateZeroPool( sizeof(SETUP_LINK) * gSetupCount ); + if ( gSetupData == NULL ) + return EFI_OUT_OF_RESOURCES; + + 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 = HiiGetFormSet( i ); + gSetupData[i].ClassID = formSet->Class; + gSetupData[i].SubClassID = formSet->SubClass; + + } + + // 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_PACK_HEADER) + + sizeof(EFI_IFR_FORM_SET) + + i * sizeof(EFI_IFR_REF) + ); + + formSet = 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_PACK_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 = HiiGetFormSet( link ); + ref->Header.OpCode = EFI_IFR_REF_OP; + ref->Header.Length = sizeof(EFI_IFR_REF); + ref->Prompt = formSet->FormSetTitle; + ref->Help = formSet->Help; + FixupPage0ControlInfo( (UINTN)gSetupData[i].FormSet, (UINTN)ref, (VOID*)gSetupData[link].Handle); + ref++; + } + + gSetupData[i].Handle = gSetupData[0].Handle; + + } + + RTIfrProcessAddVarListAndPageIDListWrapper(); + + // 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); + + MemCopy(NewPageInfo,pageInfo,PageSize); + + if ( link == (gSetupCount - 1) ) + { + NewPageInfo->PageHandle = 0;// This page has been removed in runtime!!! + } + else + { + if(RTIfrProcessFormIfUpdatedWrapper(link) == TRUE) + continue; + 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++ ) + { + CONTROL_INFO *controlInfo = (CONTROL_INFO *)((UINTN)gToolControlInfo + NewPageInfo->PageControls.ControlList[j]); + + ControlSize = sizeof(CONTROL_INFO) + controlInfo->ControlDataWidth * 2; + + NewControlInfo = EfiLibAllocateZeroPool(ControlSize); + 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->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); + } + } + + 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) + { + CreatePage(&FirstPage, &AllocatedFirstPageSize, &FirstPageOffset, NewPageInfo, PageSize); + } + else + { + AddPageToList(NewPageInfo,PageSize); + } + MemFreePointer(&NewPageInfo); + } + + RTIfrProcessRunTimeFormsWrapper(&ref); + + MergePageListAndInfo(); + return Status; +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiGetStringLength +// +// Description: Function to get the string length +// +// Input: VOID* handle, +// UINT16 token +// +// Output: Length +// +//---------------------------------------------------------------------------- +// +UINTN HiiGetStringLength( /*EFI_HII_HANDLE*/VOID* handle, UINT16 token ) +{ + CHAR16 *string; + UINTN length = 0; + + string = HiiGetString( handle, token ); + if ( string == NULL ) + return length; + + length = EfiStrLen( string ); + MemFreePointer( (VOID **)&string ); + + return length; +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiFindHandle +// +// Description: Function to find the perticular HII handle +// +// Input: EFI_GUID *guid, UINT16 *index +// +// Output: Handle +// +//---------------------------------------------------------------------------- +// +/*EFI_HII_HANDLE*/VOID* HiiFindHandle( EFI_GUID *guid, UINT16 *index ) +{ + VOID* *handleBuffer = NULL; + VOID* handle = (VOID*)(UINTN)INVALID_HANDLE; + + EFI_IFR_FORM_SET *formSet; + UINT8 *buffer; + + UINT16 found = 0; + UINT16 i, count; + + handleBuffer = _HiiGetHandles( &count ); + if ( handleBuffer == NULL ) + return handle; + + for ( i = found = 0; i < count; i++ ) + { + buffer = _HiiGetForm( handleBuffer[i], 0, NULL ); + if ( buffer == NULL ) + continue; + formSet = (EFI_IFR_FORM_SET *)(buffer + sizeof(EFI_HII_PACK_HEADER)); + if ( EfiCompareGuid( guid, &formSet->Guid ) ) + { + if ( *index == found ) + { + handle = handleBuffer[i]; + (*index)++; + break; + } + found++; + } + + MemFreePointer( &buffer ); + } + + MemFreePointer( (VOID **)&handleBuffer ); + return handle; + +} + +// +//---------------------------------------------------------------------------- +// Procedure: _HiiGetHandles +// +// Description: Function to get HII handles +// +// Input: UINT16 *bufferSize +// +// Output: Status +// +//---------------------------------------------------------------------------- +// +VOID* * _HiiGetHandles( UINT16 *bufferSize ) +{ + EFI_STATUS Status; + EFI_HII_HANDLE *buffer = NULL; + UINTN *OutBuf=NULL; + UINT16 i; + + *bufferSize = 0; + Status = _HiiWrapperFindHandles( bufferSize, NULL ); + if ( Status != EFI_BUFFER_TOO_SMALL ) + return (VOID*)OutBuf; + + buffer = EfiLibAllocatePool( *bufferSize ); + if ( buffer != NULL ) + { + Status = _HiiWrapperFindHandles( bufferSize, (VOID**)buffer ); + if ( EFI_ERROR( Status ) ) + MemFreePointer( (VOID **)&buffer ); + } + + *bufferSize /= sizeof(EFI_HII_HANDLE); + OutBuf = EfiLibAllocatePool( *bufferSize * sizeof(VOID*)); + + for(i=0;i<*bufferSize;i++) + OutBuf[i] = (UINTN)buffer[i]; + + MemFreePointer( (VOID **)&buffer ); + + //return buffer; + return (VOID*)OutBuf; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _HiiLocateSetupHandles +// +// Description: Function to find the Setup Handles +// +// Input: void +// +// Output: Status +// +//---------------------------------------------------------------------------- +// +EFI_STATUS _HiiLocateSetupHandles( VOID ) +{ + EFI_STATUS Status; + UINT16 i = 0; + UINT16 count; + /*EFI_HII_HANDLE*/VOID* *handleBuffer; + UINT8 *buffer; + UINT16 found = 0; + + Status = HiiInitializeProtocol(); + if ( EFI_ERROR( Status ) ) + return Status; + + if(FormBrowserLocateSetupHandles(&handleBuffer,&count)!= EFI_SUCCESS) + { + handleBuffer = _HiiGetHandles( &count ); + } + + if ( handleBuffer == NULL ) + { + Status = EFI_OUT_OF_RESOURCES; + goto _Done; + } + + gSetupHandles = EfiLibAllocatePool( (count + 1) * sizeof(/*EFI_HII_HANDLE*/VOID*) ); + 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; + // EIP : maximum VFRs supported in TSE + if(gSetupCount > MAX_PAGE) + { + CHAR16 *Temp = L"Reached TSE Maximum supported Page"; + _DisplayErrorMessage(Temp); + ASSERT(0); + } + + // at this point we have all the setup specific HII handles into our buffer +_Done: + if(!FormBrowserHandleValid()) + MemFreePointer( (VOID**)&handleBuffer ); + + return Status; + +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiGetFormSetFromHandle +// +// Description: Function to get formset handle +// +// Input: VOID* handle +// +// Output: Formset +// +//---------------------------------------------------------------------------- +// +EFI_IFR_FORM_SET *HiiGetFormSetFromHandle( /*EFI_HII_HANDLE*/VOID* handle ) +{ + UINTN i; + + for ( i = 0; i < gSetupCount; i++ ) + { + if ( gSetupHandles[i] == handle ) + return HiiGetFormSet( i ); + } + + return NULL; +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiGetFormSet +// +// Description: Function to get formset +// +// Input: UINTN index +// +// Output: formset +// +//---------------------------------------------------------------------------- +// +EFI_IFR_FORM_SET *HiiGetFormSet( UINTN index ) +{ + EFI_IFR_FORM_SET *formSet = NULL; + + if ( index >= gSetupCount ) + return formSet; + + if ( gSetupData == NULL ) + return formSet; + + formSet = (EFI_IFR_FORM_SET*)(gSetupData[index].FormSet + sizeof(EFI_HII_PACK_HEADER)); + + return formSet; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _HiiGetForm +// +// Description: to get data using the input handle +// +// Input: VOID* handle, UINT16 form, UINTN *Length +// +// Output: info buffer +// +//---------------------------------------------------------------------------- +// +VOID *_HiiGetForm( /*EFI_HII_HANDLE*/VOID* handle, UINT16 form, UINTN *Length ) +{ + EFI_STATUS Status; + VOID *buffer = NULL; + +#if HII_VERSION <= 1 + UINT16 bufferSize = 0; +#else + UINTN bufferSize = 0; +#endif + + Status = HiiInitializeProtocol(); + + if ( EFI_ERROR(Status) ) + return buffer; + + Status = _HiiWrapperGetForm( handle, form, &bufferSize, buffer ); + if ( Status != EFI_BUFFER_TOO_SMALL ) + return buffer; + + buffer = EfiLibAllocatePool( bufferSize ); + if ( buffer == NULL ) + return buffer; + + Status = _HiiWrapperGetForm( handle, form, &bufferSize, buffer ); + if ( EFI_ERROR(Status) ) + MemFreePointer( (VOID **)&buffer ); + + if(Length!=NULL) + *Length = bufferSize; + + return buffer; +} + + +UINT16 HiiAddStringLanguage( VOID* handle, CHAR16 *lang, CHAR16 *string ) +{ + return HiiChangeStringLanguage( handle, 0, lang, string ); +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiChangeString +// +// Description: to change a existing string +// +// Input: VOID* handle, UINT16 token, CHAR16 *string +// +// Output: Status +// +//---------------------------------------------------------------------------- +// +UINT16 HiiChangeString( VOID* handle, UINT16 token, CHAR16 *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 ) + { + //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: IsFormFound +// +// Description: to check whether the perticular form found or not +// +// Input: EFI_IFR_FORM_SET *formSet,UINT16 formid +// +// Output: 0/1 +// +//---------------------------------------------------------------------------- +// +UINT16 IsFormFound(EFI_IFR_FORM_SET *formSet,UINT16 formid ) +{ + UINT8 * RawData = (UINT8 *)formSet; + while( ((EFI_IFR_OP_HEADER*)RawData)->OpCode != EFI_IFR_END_FORM_SET_OP) + { + if(((EFI_IFR_OP_HEADER*)RawData)->OpCode == EFI_IFR_FORM_OP) + if(((EFI_IFR_FORM*)RawData)->FormId == formid) + return 1; + + RawData += ((EFI_IFR_OP_HEADER*)RawData)->Length; + } + return 0; +} + +// +//---------------------------------------------------------------------------- +// Procedure: _HiiGetLinkIndex +// +// Description: to get the index of the link +// +// Input: EFI_GUID *guid, UINT16 class, UINT16 subclass, UINT16 formid +// +// Output: Index +// +//---------------------------------------------------------------------------- +// +UINT16 _HiiGetLinkIndex( EFI_GUID *guid, UINT16 class, UINT16 subclass, UINT16 formid ) +{ + UINT16 i; + EFI_IFR_FORM_SET *formSet; + EFI_HII_PACK_HEADER *pack; + + for ( i = 0; i < gSetupCount - 1; i++ ) + { + pack = (EFI_HII_PACK_HEADER *)gSetupData[i].FormSet; + + if ( sizeof(EFI_HII_PACK_HEADER) == pack->Length ) + continue; + + formSet = (EFI_IFR_FORM_SET *)((UINT8 *)pack + sizeof(EFI_HII_PACK_HEADER)); + + if(EfiCompareGuid( guid , &(formSet->Guid) )) + { + if( gSetupData[i].ClassID == class ) + { + if( gSetupData[i].SubClassID == subclass ) + { + if(IsFormFound(formSet, formid)) + { + break; + } + } + } + } + } + return i; +} + +EFI_STATUS _HiiWrapperFindHandles( UINT16 *bufferSize, /*EFI_HII_HANDLE*/VOID* *buffer ) +{ + return gHiiProtocol->FindHandles( gHiiProtocol, bufferSize, (EFI_HII_HANDLE*)buffer ); +} + +#if HII_VERSION <= 1 +EFI_STATUS _HiiWrapperGetForm( /*EFI_HII_HANDLE*/VOID* handle, UINT16 form, UINT16 *bufferSize, VOID *buffer ) +#else +EFI_STATUS _HiiWrapperGetForm( /*EFI_HII_HANDLE*/VOID* handle, UINT16 form, UINTN *bufferSize, VOID *buffer ) +#endif +{ + return gHiiProtocol->GetForms( gHiiProtocol,(EFI_HII_HANDLE)(UINTN) handle, form, bufferSize, buffer ); +} + +// +//---------------------------------------------------------------------------- +// Procedure: _HiiParseVariablePack +// +// Description: To parse the variable pack and Update the Current Values with Default Values +// +// Input: EFI_HII_VARIABLE_PACK_LIST *packList, NVRAM_VARIABLE **pVarList +// +// Output: void +// +//---------------------------------------------------------------------------- +// +VOID _HiiParseVariablePack( EFI_HII_VARIABLE_PACK_LIST *packList, UINT32 offs, UINT32 variable, UINTN size, NVRAM_VARIABLE **pVarList ) +{ + EFI_HII_VARIABLE_PACK *pack; + UINT32 index; + UINTN offset; + NVRAM_VARIABLE *varList = *pVarList; + NVRAM_VARIABLE *varPtr; + UINT8 *srcBuffer; + + for ( ; packList != NULL; packList = packList->NextVariablePack ) + { + pack = packList->VariablePack; + if ( pack == NULL ) + continue; + + if ( VarGetVariableInfoId( pack->VariableId, &index ) == NULL ) + continue; + + offset = sizeof(EFI_HII_VARIABLE_PACK) + pack->VariableNameLength; +//--> EIP:48587 + if( index == variable) + { + varPtr = &(varList[index]); + if ( offs + size > varPtr->Size ) + { + UINT8 *pnewBuffer; + pnewBuffer = EfiLibAllocateZeroPool( offs + size ); + MemCopy( pnewBuffer, varPtr->Buffer, varPtr->Size ); + MemFreePointer( (VOID **)&varPtr->Buffer ); + varPtr->Buffer = pnewBuffer; + varPtr->Size = offs + size; + } + srcBuffer = (UINT8 *)pack + offset; + if( variable == pack->VariableId ) + { + // Update the Current Values with Defaults values + MemCopy( &varPtr->Buffer[offs], &srcBuffer[offs], size ); + } + }// <-- EIP:48587 + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiLoadDefaults +// +// Description: function to load the default values +// +// Input: NVRAM_VARIABLE **varList, UINTN Mask +// +// Output: Status +// +//---------------------------------------------------------------------------- +// +EFI_STATUS HiiLoadDefaults( NVRAM_VARIABLE **varList, UINTN Mask ) +{ + EFI_STATUS ReturnStatus = EFI_OUT_OF_RESOURCES; + EFI_STATUS Status; + NVRAM_VARIABLE *defaultVar = NULL; + UINT32 i = 0, index = 0; // EIP:48587 + UINT32 control; // EIP:48587 + + EFI_HII_VARIABLE_PACK_LIST *VariablePack = NULL; + + if ( ( varList == NULL ) /*|| ( *varList == NULL )*/ ) + return ReturnStatus; + + if( ( ! gVariables ) || ( gVariables->VariableCount == 0 ) ) // fatal error + while(1); + + *varList = EfiLibAllocateZeroPool( sizeof(NVRAM_VARIABLE) * gVariables->VariableCount ); + if ( *varList == NULL ) + return EFI_OUT_OF_RESOURCES; + + // Get the Current Values for defaults + defaultVar = ( NVRAM_VARIABLE * )*varList; + for ( i = 0; i < gVariables->VariableCount; i++, defaultVar++ ) + { + defaultVar->Buffer = VarGetNvram( i, &defaultVar->Size ); + } + + ReturnStatus = HiiInitializeProtocol(); + if ( EFI_ERROR( ReturnStatus ) ) + return ReturnStatus; + + ReturnStatus = EFI_SUCCESS; + for ( i = 0; i < gSetupCount - 1; i++ ) + { + Status = gHiiProtocol->GetDefaultImage( + gHiiProtocol, + (EFI_HII_HANDLE)(UINTN)gSetupHandles[i], + Mask, + &VariablePack + ); + + if ( EFI_ERROR( Status ) ) + { + continue; + } +// EIP:48587 + for ( ; index < gPages->PageCount; index++ ) + { + PAGE_INFO *pageInfo = (PAGE_INFO*)((UINT8 *)gPages + gPages->PageList[index]); + + if( pageInfo->PageHandle == NULL ) + { + continue; + } + + if( pageInfo->PageHandle != gSetupHandles[i] ) // EIP:48587 Find the end of current formset and go to next formset + break; + + for ( control= 0; control < pageInfo->PageControls.ControlCount; control++ ) + { + CONTROL_INFO *controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pageInfo->PageControls.ControlList[control]); + + if ( ( controlInfo->ControlVariable == VARIABLE_ID_LANGUAGE ) || ( controlInfo->ControlVariable == VARIABLE_ID_BOOT_ORDER ) || (controlInfo->ControlVariable == VARIABLE_ID_BBS_ORDER) ) + continue; + + if ( controlInfo->ControlDataWidth > 0 ) + { + VOID *ifrData = controlInfo->ControlPtr; + UINT32 ControlVarOffset; + + if ( ifrData == NULL ) + continue; + + ControlVarOffset = UefiGetQuestionOffset(ifrData); + + if ( VariablePack != NULL ) + _HiiParseVariablePack( VariablePack, ControlVarOffset, controlInfo->ControlVariable, controlInfo->ControlDataWidth, varList ); + } + } + } + MemFreePointer( (VOID **)&VariablePack ); + } +// EIP:48587 + + return ReturnStatus; +} + +// +//---------------------------------------------------------------------------- +// Procedure: AddControlToList +// +// Description: to add a control to list +// +// Input: CONTROL_INFO *NewControlInfo, UINT32 ControlSize +// +// Output: offset +// +//---------------------------------------------------------------------------- +// +UINT32 AddControlToList(CONTROL_INFO *NewControlInfo, UINT32 ControlSize) +{ + UINT32 offset; + UINT32 u32Compensation; + + u32Compensation = (sizeof(UINT64) - (ControlSize%sizeof(UINT64))) % sizeof(UINT64); + + if((ControlListOffset + ControlSize + u32Compensation )> ControlListSize) + { + gControlInfo = MemReallocateZeroPool( gControlInfo, ControlListSize, ControlListSize + 4096 ); //Allocate 4k at a time + //Todo: introduce error case + ControlListSize+=4096; + } + + MemCopy((UINT8 *)gControlInfo + ControlListOffset, NewControlInfo, ControlSize); + + offset = ControlListOffset; + + ControlListOffset += (ControlSize + u32Compensation); + + return offset; +} + +// +//---------------------------------------------------------------------------- +// Procedure: AddPageToList +// +// Description: to add a page to list +// +// Input: PAGE_INFO *NewPageInfo, UINT32 PageSize +// +// Output: void +// +//---------------------------------------------------------------------------- +// +VOID AddPageToList(PAGE_INFO *NewPageInfo, UINT32 PageSize) +{ + UINT32 offset; + UINT32 ReallocSize=4096; + + if( PageInfoPtr == NULL ) //EIP48930 + PageInfoOffset = PageInfoSize = 0; + + if(PageInfoOffset + PageSize >= PageInfoSize) + { + if(ReallocSize < PageSize) + ReallocSize = (PageSize&0xFFFFF000) + 4096; + + PageInfoPtr = MemReallocateZeroPool( PageInfoPtr, PageInfoSize, PageInfoSize + ReallocSize ); //Allocate 4k at a time + //Todo: introduce error case + PageInfoSize+=ReallocSize; + } + + MemCopy((UINT8 *)PageInfoPtr + PageInfoOffset, NewPageInfo, PageSize); + + offset = PageInfoOffset; + + PageInfoOffset += PageSize; + + if(!PageListPtr) + { + PageListSize = 512; + PageListPtr = EfiLibAllocateZeroPool(PageListSize); + PageListPtr->PageCount = 1; //Leave space for offset of Page 0 + 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); + PageListSize += 128; + } + PageListPtr->PageList[PageListPtr->PageCount] = offset; + PageListPtr->PageCount++; + PageListOffset += sizeof(UINT32); + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: CreatePage +// +// Description: function used to create a page +// +// Input: PAGE_INFO **PageInfo, UINT32 *AllocatedSize, +// UINT32 *Offset, VOID *Buff, UINT32 BuffSize +// +// Output: void +// +//---------------------------------------------------------------------------- +// +VOID CreatePage(PAGE_INFO **PageInfo, UINT32 *AllocatedSize, UINT32 *Offset, VOID *Buff, UINT32 BuffSize) +{ + + if(!(*AllocatedSize)) + { + //creating a new page + *PageInfo = EfiLibAllocateZeroPool(BuffSize); + *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]); +// Fix the Issue with the Packing, Original code was not finding the correct Offset + *Offset = (UINT32)((UINTN)(&(*PageInfo)->PageControls.ControlList[0]) - (UINTN)(*PageInfo)); + + } + else + { + //adding offsets + if(*Offset + BuffSize >= *AllocatedSize) + { + *PageInfo = MemReallocateZeroPool( *PageInfo, *AllocatedSize, *AllocatedSize + 128 ); //Allocate 128 bytes at a time + //Todo: introduce error case + *AllocatedSize+=128; + } + MemCopy((UINT8 *)(*PageInfo) + *Offset, Buff, BuffSize); + + *Offset += BuffSize; + + (*PageInfo)->PageControls.ControlCount++; + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: MergePageListAndInfo +// +// Description: To merge the information +// +// Input: NIL +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID MergePageListAndInfo() +{ + UINTN i; + + gApplicationData = EfiLibAllocateZeroPool(PageListOffset + FirstPageOffset + PageInfoOffset); + 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(; iPageCount; i++) + { + gPages->PageList[i] += (FirstPageOffset + PageListOffset); + } + + //Free Temp Memory + MemFreePointer(&FirstPage); + MemFreePointer(&PageInfoPtr); + MemFreePointer(&PageListPtr); +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiMyGetStringLength +// +// Description: user function to get the string length +// +// Input: VOID* handle, UINT16 token +// +// Output: Length +// +//---------------------------------------------------------------------------- +// +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: RTIfrProcessExit +// +// Description: Function to process ifr exit +// +// Input: void +// +// Output: void +// +//---------------------------------------------------------------------------- +// +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: Function to add var list page ID list +// +// Input: void +// +// Output: void +// +//---------------------------------------------------------------------------- +// +VOID RTIfrProcessAddVarListAndPageIDList(VOID) +{ + UINT32 i; + + //Create Variable List + for(i=0; i < gToolVariables->VariableCount ; i++) + { + VARIABLE_INFO *VariableInfo; + + VariableInfo = (VARIABLE_INFO *)((UINT8 *)gToolVariables + gToolVariables->VariableList[i]); + + AddVariableToList(VariableInfo, sizeof(VARIABLE_INFO)); + } + + //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, sizeof(PAGE_ID_INFO)); + } + +} + +// +//---------------------------------------------------------------------------- +// Procedure: RTIfrProcessFormIfUpdated +// +// Description: Fuction to process form if updated +// +// Input: UINT16 link +// +// Output: TRUE/FALSE +// +//---------------------------------------------------------------------------- +// +BOOLEAN RTIfrProcessFormIfUpdated(UINT16 link) +{ + UINT32 j; + //Check if the page has changed during run time + for(j=0; j < gHpkInfoLength / sizeof(HPK_INFO); j++) + { + EFI_HII_PACK_HEADER *pack; + + if( + (gHpkInfo[j].Class == gSetupData[link].ClassID) && + (gHpkInfo[j].SubClass == gSetupData[link].SubClassID) + ) + { + pack = (EFI_HII_PACK_HEADER *)gSetupData[link].FormSet; + + if ( gHpkInfo[j].Length != pack->Length ) + break; + } + } + + if(j < gHpkInfoLength / sizeof(HPK_INFO)) + { + //This page changed during run time parse again + if(!gSetupData[link].Added) + AddDynamicForm(link); + return TRUE; + } + gSetupData[link].Added = 1; + + return FALSE; +} + +// +//---------------------------------------------------------------------------- +// Procedure: RTIfrProcessRunTimeForms +// +// Description: Function to process runtime forms +// +// Input: EFI_IFR_REF **ref +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID RTIfrProcessRunTimeForms(EFI_IFR_REF **ref) +{ + UINT32 i; + EFI_IFR_FORM_SET *formSet; + EFI_GUID DynamicPageGuid = DYNAMIC_PAGE_COUNT_GUID; + UINT16 count = 0; + + for(i = 0; i < gSetupCount - 1; i++) + { + if(!(gSetupData[i].Added)) + { + AddDynamicForm(i); + if((gSetupData[i].Added)) + { + formSet = HiiGetFormSet( i ); + (*ref)->Header.OpCode = EFI_IFR_REF_OP; + (*ref)->Header.Length = sizeof(EFI_IFR_REF); + (*ref)->Prompt = formSet->FormSetTitle; + (*ref)->Help = formSet->Help; + (*ref)++; + count++ ; + } + } + } + + gDynamicPageCount = count ; + + //Set Dynamic page count variable + VarSetNvramName( L"DynamicPageCount", &DynamicPageGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, &count, sizeof(count) ); + MergePageIdListAndInfo(); + MergeVariableListAndInfo(); +} + +// +//---------------------------------------------------------------------------- +// Procedure: AddPageIdToList +// +// Description: Function to add page id to list +// +// Input: PAGE_ID_INFO *NewPageIdInfo, UINT32 PageIdSize +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID AddPageIdToList(PAGE_ID_INFO *NewPageIdInfo, UINT32 PageIdSize) +{ + UINT32 offset; + + if( PageIdInfoPtr == NULL ) //EIP48930 + PageIdInfoOffset = PageIdInfoSize = 0; + + if(PageIdInfoOffset + PageIdSize >= PageIdInfoSize) + { + PageIdInfoPtr = MemReallocateZeroPool( PageIdInfoPtr, PageIdInfoSize, PageIdInfoSize + 256 ); //Allocate 4k at a time + //Todo: introduce error case + PageIdInfoSize+=256; + } + + MemCopy((UINT8 *)PageIdInfoPtr + PageIdInfoOffset, NewPageIdInfo, PageIdSize); + + offset = PageIdInfoOffset; + + PageIdInfoOffset += PageIdSize; + + if(!PageIdListPtr) + { + PageIdListSize = 128; + PageIdListPtr = EfiLibAllocateZeroPool(PageIdListSize); + 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); + PageIdListSize += 128; + } + PageIdListPtr->PageIdList[PageIdListPtr->PageIdCount] = offset; + PageIdListPtr->PageIdCount++; + PageIdListOffset += sizeof(UINT32); + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: MergePageIdListAndInfo +// +// Description: Function to merge page id list and info +// +// Input: NIL +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID MergePageIdListAndInfo() +{ + UINTN i; + + gPageIdList = EfiLibAllocateZeroPool(PageIdListOffset + PageIdInfoOffset); + + 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); +} + +// +//---------------------------------------------------------------------------- +// Procedure: AddVariableToList +// +// Description: Function to add variable to list +// +// Input: VARIABLE_INFO *NewVariableInfo, UINT32 VariableSize +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID AddVariableToList(VARIABLE_INFO *NewVariableInfo, UINT32 VariableSize) +{ + UINT32 offset; + + if(VariableInfoOffset + VariableSize >= VariableInfoSize) + { + VariableInfoPtr = MemReallocateZeroPool( VariableInfoPtr, VariableInfoSize, VariableInfoSize + 256 ); //Allocate 4k at a time + //Todo: introduce error case + VariableInfoSize+=256; + } + + MemCopy((UINT8 *)VariableInfoPtr + VariableInfoOffset, NewVariableInfo, VariableSize); + + offset = VariableInfoOffset; + + VariableInfoOffset += VariableSize; + + if(!VariableListPtr) + { + VariableListSize = 128; + VariableListPtr = EfiLibAllocateZeroPool(VariableListSize); + VariableListPtr->VariableList[VariableListPtr->VariableCount] = offset; + VariableListPtr->VariableCount = 1; + VariableListOffset = sizeof(VARIABLE_LIST); + } + else + { + if(VariableListOffset + sizeof(UINT32) >= VariableListSize) + { + VariableListPtr = MemReallocateZeroPool(VariableListPtr, VariableListSize, VariableListSize + 128); + VariableListSize += 128; + } + VariableListPtr->VariableList[VariableListPtr->VariableCount] = offset; + VariableListPtr->VariableCount++; + if(VariableListPtr->VariableCount >= MAX_VARIABLE) + { + CHAR16 *Temp = L"Reached TSE Maximum supported variables"; + _DisplayErrorMessage(Temp); + ASSERT(0); + } + VariableListOffset += sizeof(UINT32); + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: MergeVariableListAndInfo +// +// Description: Function to merge variable list and info +// +// Input: NIL +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID MergeVariableListAndInfo() +{ + UINTN i; + + gVariables = EfiLibAllocateZeroPool(VariableListOffset + VariableInfoOffset); + + 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); +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetSubFormCount +// +// Description: function to count the subform and Ref inside the formset. +// +// Input: UINT8 *buff - Pointer to form to search for links to other forms +// +// Output: count - no of subforms +// +//---------------------------------------------------------------------------- +// + +UINTN GetSubFormCount(UINT8 *buff) +{ + UINTN *tmpFormIDBuf; + UINTN MaxPagecount=100; + UINTN PageCount= 0; + UINTN i=0, j=0, found =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_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_FORM*)Header)->FormId ) + { + found =1; + } + j++; + } + + if(!found) + { + // pages in the root(no parent) + tmpFormIDBuf[PageCount] = ((EFI_IFR_FORM*)Header)->FormId ; + PageCount++; + } + break; + + default: + break; + } + // 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(Header->OpCode != EFI_IFR_END_FORM_SET_OP); + + MemFreePointer(&tmpFormIDBuf); + return PageCount; +} + +// +//---------------------------------------------------------------------------- +// Procedure: InitFormsetLinks +// +// Description: Function to init formset links +// +// Input: char *buff, UINTN InitFormNum +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID InitFormsetLinks(char *buff,UINTN InitFormNum) +{ + UINTN i=0, j=0, found =0,InitForm=InitFormNum; + EFI_IFR_OP_HEADER *Header; + UINTN count = 0; +///EIP:24060 - Start + UINT16 RootPageinFormSet=0; +///EIP:24060 - End + + // allocate memory for data + if(FSetLinks != NULL) + MemFreePointer(&FSetLinks); + + count = GetSubFormCount(buff); + FSetLinks = (FormSetLinks*)EfiLibAllocateZeroPool(sizeof(FormSetLinks) + count * sizeof(PageLink)); + + //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 < FSetLinks->PageCount ) ){ + if(FSetLinks->PageLink[j].FormID == ((EFI_IFR_FORM*)Header)->FormId ) + { + FSetLinks->PageLink[j].PageNum = (UINT16)InitForm++; + found =1; + break; + } + j++; + } + + if(!found) + { +///EIP:24060 - Start + if(!RootPageinFormSet) + RootPageinFormSet = ((EFI_IFR_FORM*)Header)->FormId; +///EIP:24060 - End + // 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++; + } + + 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 < FSetLinks->PageCount ) ){ + if(FSetLinks->PageLink[j].FormID == ((EFI_IFR_FORM*)Header)->FormId ) + { +///EIP:24060 - Start + 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; + + +///EIP:24060 - End + found =1; + } + j++; + } + + if(!found) + { + // sub pages + FSetLinks->PageLink[FSetLinks->PageCount].FormID = ((EFI_IFR_FORM*)Header)->FormId ; + FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = (UINT16)InitForm-1; + FSetLinks->PageLink[FSetLinks->PageCount].PageNum = 0; + FSetLinks->PageCount++; + } + break; + + default: + + break; + + } + i+=Header->Length; + }while(Header->OpCode != EFI_IFR_END_FORM_SET_OP); + +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetPageParent +// +// Description: Function to get parent page +// +// Input: int PageNum +// +// Output: 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: GetPageIdIndex +// +// Description: To get the index of a perticular page +// +// Input: EFI_GUID * FormGuid, UINT16 FormClass, UINT16 FormSubClass +// +// Output: PageIndex +// +//---------------------------------------------------------------------------- +// +UINT16 GetPageIdIndex(EFI_GUID * FormGuid, UINT16 FormClass, UINT16 FormSubClass) +{ + UINT16 i; + PAGE_ID_INFO *PageId; + + if(PageIdListPtr == NULL) + PageIdListPtr = EfiLibAllocateZeroPool(128); + + //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, sizeof(PAGE_ID_INFO)); + } + + return i; + +} + +// +//---------------------------------------------------------------------------- +// Procedure: AddVariable +// +// Description: Function to add variable +// +// Input: EFI_IFR_VARSTORE *Varstore +// +// Output: success +// +//---------------------------------------------------------------------------- +// +int AddVariable(EFI_IFR_VARSTORE *Varstore) +{ + UINT16 i=0; + UINTN varfound=0; + char *str2; + EFI_GUID *GUID = &(Varstore->Guid); + VARIABLE_INFO *Variable; + UINT16 VarName[40]; + PVAR_KEY_TABLE pVarTable; + + + str2= (char*)((UINT8*)Varstore +sizeof(EFI_IFR_VARSTORE)); //name + + //Convert to unicode string + MemSet(VarName, sizeof(VarName), 0); + + i = 0; + while(*str2) + { + VarName[i] = *str2; + i++; + str2++; + } + + + // 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 + if(EfiStrCmp(VarName,Variable->VariableName) ==0) + { + varfound=1; + Variable->VariableID = Varstore->VarId; + break; + } + } + + if(!varfound) + { + VARIABLE_INFO NewVariable; + + MemSet(&NewVariable,sizeof(VARIABLE_INFO),0); + NewVariable.VariableID = Varstore->VarId; + MemCopy((&NewVariable.VariableGuid),&(Varstore->Guid),sizeof(EFI_GUID)); + NewVariable.VariableAttributes = 7; + EfiStrCpy(NewVariable.VariableName,VarName); + + AddVariableToList(&NewVariable, sizeof(VARIABLE_INFO)); + } + + pVarTable = &VarKeyTable; + + while(pVarTable->Next) + pVarTable = pVarTable->Next; + + pVarTable->Next = EfiLibAllocateZeroPool(sizeof(VAR_KEY_TABLE)); + pVarTable = pVarTable->Next; + + pVarTable->VarId = Varstore->VarId; + pVarTable->Index = i; + + return 0; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetVarNumFromVarID +// +// Description: Function to get variable number from var ID +// +// Input: UINT32 ID +// +// Output: Variable Index +// +//---------------------------------------------------------------------------- +// +UINT32 GetVarNumFromVarID(UINT32 ID) +{ + PVAR_KEY_TABLE pVarTable; + + pVarTable = VarKeyTable.Next; + + while(pVarTable) + { + if(pVarTable->VarId == ID) + return(pVarTable->Index); + pVarTable = pVarTable->Next; + } + + return 0; + +} + +// +//---------------------------------------------------------------------------- +// Procedure: CleanVarKeyTable +// +// Description: To clear the key table specific buffers +// +// Input: NIL +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID CleanVarKeyTable() +{ + PVAR_KEY_TABLE pVarTable; + + pVarTable = VarKeyTable.Next; + + while(pVarTable) + { + VarKeyTable.Next = pVarTable->Next; + MemFreePointer(&pVarTable); + pVarTable = VarKeyTable.Next; + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: AddFormSetVariable +// +// Description: +// +// Input: EFI_GUID * VarGuid +// +// Output: VarCount +// +//---------------------------------------------------------------------------- +// +UINT32 AddFormSetVariable(EFI_GUID * VarGuid) +{ + VARIABLE_INFO Variable; + UINT32 i; + + Variable.VariableID = 0; + MemCopy((&Variable.VariableGuid),VarGuid,sizeof(EFI_GUID)); + Variable.VariableAttributes = 0x7; // BT+RT+NV + EfiStrCpy(Variable.VariableName,L"Setup"); + + i = VariableListPtr->VariableCount; + AddVariableToList(&Variable, sizeof(VARIABLE_INFO)); + + return i; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IsVarGuidPresent +// +// Description: +// +// Input: EFI_GUID * VarGuid, int * Index +// +// Output: TRUE/FALSE +// +//---------------------------------------------------------------------------- +// +int 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 1; + } + } + return 0; +} + +// +//---------------------------------------------------------------------------- +// Procedure: AddDynamicForm +// +// Description: +// +// Input: UINT32 HiiIndex +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID AddDynamicForm(UINT32 HiiIndex) +{ + EFI_HII_PACK_HEADER *fset; + EFI_IFR_FORM_SET *Formset; + EFI_IFR_FORM *form; + + UINTN x, i=0; + UINT8 *buff = NULL; + + CONTROL_INFO controlInfo; + UINT32 ControlOffset; + UINT32 VarIndex; + + PVAR_KEY_TABLE pVarTable; + + UINT32 AllocatedPageSize , PageOffset; + PAGE_INFO *NewPageInfo; + + PAGE_INFO TempPage; + + x = gSetupData[HiiIndex].FormSetLength; + buff = (UINT8 *) gSetupData[HiiIndex].FormSet; + fset = (EFI_HII_PACK_HEADER *)buff; + + + while(iType == FORM_SUBCLASS) && (Formset->Header.OpCode == EFI_IFR_FORM_SET_OP )) + { + if(EFI_IFR_END_FORM_SET_OP == *(buff + sizeof(EFI_HII_PACK_HEADER) + sizeof(EFI_IFR_FORM_SET))) + { + // This package has no forms. Processing this further will result in unpredictability. + break; + } + + gSetupData[HiiIndex].Added = 1; + + CtrlVar=0,CtrlCondVar=0; // initialize control variables for every formset + ActualCondVar =0; ActualCondVar2=0; + CtrlCondVar2=0; // this should not be necessary if vfr compiler would start + + // Check the GUID is updated in the Variable list or not + VarIndex = 0; + if(IsVarGuidPresent(&(Formset->Guid), &VarIndex)) + CtrlVar = CtrlCondVar = CtrlCondVar2 = ActualCondVar = ActualCondVar2 = VarIndex; + else + CtrlVar = CtrlCondVar = CtrlCondVar2 = ActualCondVar = ActualCondVar2 = AddFormSetVariable(&(Formset->Guid)); + + pVarTable = &VarKeyTable; + + while(pVarTable->Next) + pVarTable = pVarTable->Next; + + pVarTable->Next = EfiLibAllocateZeroPool(sizeof(VAR_KEY_TABLE)); + pVarTable = pVarTable->Next; + + pVarTable->VarId = 0; + pVarTable->Index = (UINT16)CtrlVar; + + // with a varstote select/select_pair at the beginning of a formset + + i= sizeof(EFI_HII_PACK_HEADER) + sizeof(EFI_IFR_FORM_SET); + form =(EFI_IFR_FORM*)(buff+i ); + + // create the pages lookup table + InitFormsetLinks((char*)form, 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)); + } + + // add the submenu control to main form that points to this form. + controlInfo.ControlHandle = gSetupData[HiiIndex].Handle; + controlInfo.ControlVariable = 0; + controlInfo.ControlConditionalVariable[0] = 0; + controlInfo.ControlConditionalVariable[1] = 0; + controlInfo.ControlType = CONTROL_TYPE_SUBMENU; + controlInfo.ControlPageID = 0; + controlInfo.ControlDestPageID = PageListPtr ? ((UINT16)PageListPtr->PageCount):1 ; + + controlInfo.ControlFlags.ControlVisible = 1; + controlInfo.ControlFlags.ControlAccess = 0; + controlInfo.ControlFlags.ControlReadOnly = 0; + controlInfo.ControlFlags.ControlReset = 0; + controlInfo.ControlFlags.Reserved1 = 0; + controlInfo.ControlFlags.ControlRefresh = 0; + controlInfo.ControlFlags.Reserved2 = 0; + + + controlInfo.ControlHelp = 0; + controlInfo.ControlLabel = 0; + controlInfo.ControlIndex = 0; + controlInfo.ControlLabelCount = 0; + controlInfo.ControlPtr = (VOID*)((UINTN)gSetupData[HiiIndex].FormSet + + sizeof(EFI_HII_PACK_HEADER) + + sizeof(EFI_IFR_FORM_SET) + + TotalRootPages * sizeof(EFI_IFR_REF)); + controlInfo.ControlConditionalPtr = 0; + controlInfo.ControlDataLength = 0; + controlInfo.ControlDataWidth = 0; + controlInfo.QuestionId = 0; + + ControlOffset = AddControlToList(&controlInfo, sizeof(CONTROL_INFO)); + CreatePage(&FirstPage, &AllocatedFirstPageSize, &FirstPageOffset, &ControlOffset, sizeof(UINT32)); + + TotalRootPages++; + + // add forms + while(iGuid), Formset->Class, Formset->SubClass); + TempPage.PageFormID = form->FormId; + TempPage.PageTitle = (UINT16)0; + TempPage.PageSubTitle = form->FormTitle; + TempPage.PageID = PageListPtr ? ((UINT16) PageListPtr->PageCount):1; + TempPage.PageParentID = PageListPtr ? GetPageParent(PageListPtr->PageCount):0; + + TempPage.PageFlags.PageVisible = 0; + TempPage.PageFlags.PageHelpVisible = 0; + TempPage.PageFlags.PageDisableHotKeys = 0; + TempPage.PageFlags.Reserved = 0; + + TempPage.PageVariable = 0; + TempPage.PageControls.ControlCount = 0; + TempPage.PageControls.ControlList[0] = 0; + + //Check for Dynamic Page Flag + if (TempPage.PageParentID == 0 && IsGroupDynamicPages()) //PageParentID is 0 && SDL token is true + { + //then set as dynamic page + TempPage.PageFlags.PageDynamic = TRUE ; + TempPage.PageFlags.PageVisible = TRUE; + + } + + // memory for TempPage.PageControls.ControlList[0] will be allocated later when adding controls + CreatePage(&NewPageInfo, &AllocatedPageSize, &PageOffset, &TempPage, sizeof(PAGE_INFO)); + + i += AddHpkControls(HiiIndex,(buff + i),x-i,&NewPageInfo, &AllocatedPageSize, &PageOffset); + + AddPageToList(NewPageInfo, PageOffset); + if(NewPageInfo->PageControls.ControlCount >= MAX_CONTROLS) + { + CHAR16 *Temp = L"Reached TSE Maximum supported Controls"; + _DisplayErrorMessage(Temp); + ASSERT(0); + } + + MemFreePointer(&NewPageInfo); + + if( *((char*)buff +i) == EFI_IFR_END_FORM_SET_OP) + { + controllabel = controlindex = 0; + if(FSetLinks !=NULL) + { + MemFreePointer(&FSetLinks); + FSetLinks = NULL; + } + i+=2; // add the end_formset opcode size + break; //no more forms in this formset... + } + } + } + else // package is NOT EFI_HII_IFR + { + //go to next package + i += fset->Length ; + } + } // end of while loop + + CleanVarKeyTable(); +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetHelpToken +// +// Description: +// +// Input: UINT8 *ifr +// +// Output: token +// +//---------------------------------------------------------------------------- +// +UINT16 GetHelpToken( UINT8 *ifr ) +{ + EFI_IFR_OP_HEADER *headerPtr = (EFI_IFR_OP_HEADER *)ifr; + UINT16 token = 0; + + switch ( headerPtr->OpCode ) + { + case EFI_IFR_TEXT_OP: + { + EFI_IFR_TEXT *ptr = (EFI_IFR_TEXT *)headerPtr; + token = ptr->Help; + } + break; + case EFI_IFR_ORDERED_LIST_OP: + { + EFI_IFR_ORDERED_LIST *ptr = (EFI_IFR_ORDERED_LIST *)headerPtr; + token = ptr->Help; + } + break; + case EFI_IFR_ONE_OF_OP: + { + EFI_IFR_ONE_OF *ptr = (EFI_IFR_ONE_OF *)headerPtr; + token = ptr->Help; + } + break; + case EFI_IFR_CHECKBOX_OP: + { + EFI_IFR_CHECK_BOX *ptr = (EFI_IFR_CHECK_BOX *)headerPtr; + token = ptr->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->Help; + } + break; + case EFI_IFR_PASSWORD_OP: + { + EFI_IFR_PASSWORD *ptr = (EFI_IFR_PASSWORD *)headerPtr; + token = ptr->Help; + } + break; + case EFI_IFR_REF_OP: + { + EFI_IFR_REF *ptr = (EFI_IFR_REF *)headerPtr; + token = ptr->Help; + } + break; + case EFI_IFR_STRING_OP: + { + EFI_IFR_STRING *ptr = (EFI_IFR_STRING *)headerPtr; + token = ptr->Help; + } + break; + case EFI_IFR_SAVE_DEFAULTS_OP: + { + EFI_IFR_SAVE_DEFAULTS *ptr = (EFI_IFR_SAVE_DEFAULTS *)headerPtr; + token = ptr->Help; + } + break; + case EFI_IFR_INVENTORY_OP: + { + EFI_IFR_INVENTORY *ptr = (EFI_IFR_INVENTORY *)headerPtr; + token = ptr->Help; + } + break; + default: + break; + } + + return token; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetQuestionToken +// +// Description: +// +// Input: UINT8 *ifr +// +// Output: token +// +//---------------------------------------------------------------------------- +// +UINT16 GetQuestionToken( UINT8 *ifr ) +{ + EFI_IFR_OP_HEADER *headerPtr = (EFI_IFR_OP_HEADER *)ifr; + UINT16 token = 0; + + switch ( headerPtr->OpCode ) + { + case EFI_IFR_TEXT_OP: + { + EFI_IFR_TEXT *ptr = (EFI_IFR_TEXT *)headerPtr; + token = ptr->Text; + } + break; + case EFI_IFR_ONE_OF_OP: + { + EFI_IFR_ONE_OF *ptr = (EFI_IFR_ONE_OF *)headerPtr; + token = ptr->Prompt; + } + break; + case EFI_IFR_CHECKBOX_OP: + { + EFI_IFR_CHECK_BOX *ptr = (EFI_IFR_CHECK_BOX *)headerPtr; + token = ptr->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->Prompt; + } + break; + case EFI_IFR_PASSWORD_OP: + { + EFI_IFR_PASSWORD *ptr = (EFI_IFR_PASSWORD *)headerPtr; + token = ptr->Prompt; + } + break; + case EFI_IFR_REF_OP: + { + EFI_IFR_REF *ptr = (EFI_IFR_REF *)headerPtr; + token = ptr->Prompt; + } + break; + case EFI_IFR_STRING_OP: + { + EFI_IFR_STRING *ptr = (EFI_IFR_STRING *)headerPtr; + token = ptr->Prompt; + } + break; + case EFI_IFR_SAVE_DEFAULTS_OP: + { + EFI_IFR_SAVE_DEFAULTS *ptr = (EFI_IFR_SAVE_DEFAULTS *)headerPtr; + token = ptr->Prompt; + } + break; + case EFI_IFR_INVENTORY_OP: + { + EFI_IFR_INVENTORY *ptr = (EFI_IFR_INVENTORY *)headerPtr; + token = ptr->Text; + } + break; + case EFI_IFR_SUBTITLE_OP: + { + EFI_IFR_SUBTITLE *ptr = (EFI_IFR_SUBTITLE *)headerPtr; + token = ptr->SubTitle; + } + break; + default: + break; + } + + return token; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetPageNumFromFormID +// +// Description: +// +// Input: UINTN FormID +// +// Output: PageNum +// +//---------------------------------------------------------------------------- +// +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: Updatedefaults +// +// Description: Function to update defsaults +// +// Input: VOID *Data, UINT16 *size, VOID *Failsafe, VOID *Optimal, +// struct _CONTROL_FLAGS *ControlFlags +// +// Output: void +// +//---------------------------------------------------------------------------- +// +VOID Updatedefaults( VOID *Data, UINT16 *size, VOID *Failsafe, VOID *Optimal, struct _CONTROL_FLAGS *ControlFlags) +{ + + UINT8 Flags=0; + UINTN i=0; + + + switch( *((UINT8*)Data) ) + { + // ------ text -------------- + case EFI_IFR_TEXT_OP: //(only interactive) + Flags =((EFI_IFR_TEXT*)Data)->Flags; + + if(Flags & EFI_IFR_FLAG_INTERACTIVE) + { + + ControlFlags->ControlRefresh = DEFAULT_REFRESH_RATE; + + } + + if(Flags & EFI_IFR_FLAG_RESET_REQUIRED) + ControlFlags->ControlReset = 1; + break; + + // ------ ref -------------- + case EFI_IFR_REF_OP: // uses only interactive , but to signal that a key has to be passed + break; // back to a consumer (this behavior is not defined in TSE as of 5/20/05) + + // ------ one of -------------- + case EFI_IFR_ONE_OF_OP: + + i= sizeof(EFI_IFR_ONE_OF); + do{ + Flags =((EFI_IFR_ONE_OF_OPTION*)((char*)Data+i))->Flags; + + if(Flags & EFI_IFR_FLAG_INTERACTIVE) + ControlFlags->ControlRefresh = DEFAULT_REFRESH_RATE; + + if(Flags & EFI_IFR_FLAG_RESET_REQUIRED) + ControlFlags->ControlReset = 1; + + if(Flags & EFI_IFR_FLAG_DEFAULT) + { + *(UINT16*)Optimal = ((EFI_IFR_ONE_OF_OPTION*)((char*)Data+i))->Value; + *size=(UINT16)((EFI_IFR_ONE_OF*)Data)->Width; + } + + if(Flags & EFI_IFR_FLAG_MANUFACTURING ) + { + *(UINT16*)Failsafe = ((EFI_IFR_ONE_OF_OPTION*)((char*)Data+i))->Value; + *size=(UINT16)((EFI_IFR_ONE_OF*)Data)->Width; + } + + i+=sizeof(EFI_IFR_ONE_OF_OPTION); + + }while(((EFI_IFR_ONE_OF_OPTION*)((char*)Data+i))->Header.OpCode != EFI_IFR_END_ONE_OF_OP); + break; + + // ------ checkbox -------------- + case EFI_IFR_CHECKBOX_OP: + + Flags = ((EFI_IFR_CHECK_BOX*) Data)->Flags ; + + if(Flags & EFI_IFR_FLAG_RESET_REQUIRED) + ControlFlags->ControlReset = 1; + + *size = (UINT16)((EFI_IFR_CHECK_BOX*)Data)->Width /*1*/; + *(UINT16*)Optimal = 0; + *(UINT16*)Failsafe = 0; + if (((EFI_IFR_CHECK_BOX*) Data)->Flags & EFI_IFR_FLAG_DEFAULT) { + *(UINT16*)Optimal = 1; + } + if (((EFI_IFR_CHECK_BOX*) Data)->Flags & EFI_IFR_FLAG_MANUFACTURING) { + *(UINT16*)Failsafe = 1; + } + + ControlFlags->ControlRefresh=0; + break; + + // ------ numeric -------------- + case EFI_IFR_NUMERIC_OP: + ControlFlags->ControlRefresh=0; + + Flags = ((EFI_IFR_CHECK_BOX*) Data)->Flags ; + + if(Flags & EFI_IFR_FLAG_RESET_REQUIRED) + ControlFlags->ControlReset = 1; + + // note: width is defined, but default entry is UINT16 in structure. + *size = ((EFI_IFR_NUMERIC*)Data)->Width/*2*/; + *(UINT16*)Optimal = ((EFI_IFR_NUMERIC*)Data)->Default; + + *(UINT16*)Failsafe = ((EFI_IFR_NUMERIC*)Data)->Default; + + break; + + // ------ ordered list -------------- + case EFI_IFR_ORDERED_LIST_OP: + i= sizeof(EFI_IFR_ORDERED_LIST); + do{ + Flags =((EFI_IFR_ONE_OF_OPTION*)((char*)Data+i))->Flags; + + if(Flags & EFI_IFR_FLAG_INTERACTIVE) + ControlFlags->ControlRefresh = DEFAULT_REFRESH_RATE; + + if(Flags & EFI_IFR_FLAG_RESET_REQUIRED) + ControlFlags->ControlReset = 1; + + if(Flags & EFI_IFR_FLAG_DEFAULT) + { + *size=(UINT16)((EFI_IFR_ONE_OF*)Data)->Width/*2*/; + *(UINT16*)Optimal = ((EFI_IFR_ONE_OF_OPTION*)((char*)Data+i))->Value; + } + + if(Flags & EFI_IFR_FLAG_MANUFACTURING ) + { + *size=(UINT16)((EFI_IFR_ONE_OF*)Data)->Width/*2*/; + *(UINT16*)Failsafe = ((EFI_IFR_ONE_OF_OPTION*)((char*)Data+i))->Value; + } + + i+=sizeof(EFI_IFR_ONE_OF_OPTION); + + }while(((EFI_IFR_ONE_OF_OPTION*)((char*)Data+i))->Header.OpCode != EFI_IFR_END_ONE_OF_OP); + break; + + + // ------ date -------------- + case EFI_IFR_DATE_OP: + ControlFlags->ControlRefresh = DEFAULT_DATETIME_REFRESH; + break; + + // ------ time -------------- + case EFI_IFR_TIME_OP: + ControlFlags->ControlRefresh = DEFAULT_DATETIME_REFRESH; + break; + + case EFI_IFR_STRING_OP: + Flags = ((EFI_IFR_STRING*) Data)->Flags; + + if(Flags & EFI_IFR_FLAG_RESET_REQUIRED) + ControlFlags->ControlReset = 1; + break; + + case EFI_IFR_PASSWORD_OP: + Flags = ((EFI_IFR_STRING*) Data)->Flags; + + if(Flags & EFI_IFR_FLAG_RESET_REQUIRED) + ControlFlags->ControlReset = 1; + break; + + default: + break; + + } + +} + +// +//---------------------------------------------------------------------------- +// Procedure: AddHpkControls +// +// Description: +// +// Input: UINT32 HiiIndex, UINT8 *buff,UINTN size, PAGE_INFO **NewPageInfo, +// UINT32 *AllocatedPageSize, UINT32 *PageOffset +// +// Output: UINTN +// +//---------------------------------------------------------------------------- +// +UINTN AddHpkControls(UINT32 HiiIndex, UINT8 *buff,UINTN size, PAGE_INFO **NewPageInfo, UINT32 *AllocatedPageSize, UINT32 *PageOffset) +{ + UINTN i =0 , end=0,j=0; + UINTN ConditionalPtr=0, ControlPtr = 0; + UINT16 DestPageID =0xFFFF, ControlType=0, QuestionId = 0, HelpOffset=0, OpcodeNum = 0; + BOOLEAN AddControl = TRUE; + struct _CONTROL_FLAGS ControlFlags ; + UINTN CtrlFailSafe = 0, CtrlOptimal = 0; + UINT16 Defaults_size=0; + EFI_IFR_OP_HEADER *Hdr; + + UINT32 ControlSize; + UINT32 ControlOffset; + CONTROL_INFO *NewControlInfo; + + + // for loop for the number of controls of this + while(i < size ) + { + CtrlFailSafe = 0; + CtrlOptimal = 0; + + MemSet( &ControlFlags, sizeof(CONTROL_FLAGS), 0 ); //reset all the flags to zero + ControlFlags.ControlVisible =0x1; +/* ControlFlags.ControlAccess =0; + ControlFlags.ControlRefresh =0; + ControlFlags.ControlReset =0; + ControlFlags.Reserved1 =0; + ControlFlags.Reserved2 =0; +*/ + + // control type + switch(*(buff +i)) + { + case EFI_IFR_END_FORM_OP: + controlindex++; + end =1; + break; + + default : + if( *(buff +i) == EFI_IFR_LABEL_OP) + { + UINT8 *tBuff; + controllabel ++; + controlindex=0; + + tBuff = (buff +i+ *(buff+i+1)); + OpcodeNum=0; + + while( (*tBuff != EFI_IFR_LABEL_OP ) && (*tBuff != EFI_IFR_END_FORM_SET_OP) ) + { + tBuff = tBuff +(unsigned long)*(tBuff+1); + OpcodeNum++; + }; + } + + ControlType = controltypes[*(buff +i) -1]; + HelpOffset = GetHelpToken( buff + i ); + QuestionId = GetQuestionToken( buff + i ); + + // check if it is + switch(ControlType) + { + case CONTROL_TYPE_MEMO: + break; + + case CONTROL_TYPE_SUBMENU: + DestPageID = GetPageNumFromFormID(((EFI_IFR_REF*)((char*)buff +i))->FormId); + break; + + case CONTROL_TYPE_CHECKBOX: + ControlType = CONTROL_TYPE_POPUPSEL; // With no DestPageID + break; + + case CONTROL_TYPE_POPUPSEL: + break; + + case CONTROL_TYPE_TEXT: + break; + + + case CONTROL_TYPE_ORDERED_LIST: + break; + + case END_EVAL_IF: // ENDIF for grayout,suppress or inconsistent + ConditionalPtr = 0; + updatecondvars =1; + + AddControl = FALSE; + break; + + case CONTROL_TYPE_TIME: + break; + + case CONTROL_TYPE_DATE: + break; + + case CONTROL_TYPE_VARSTORE: + AddVariable((EFI_IFR_VARSTORE*)(buff+i)); + AddControl =FALSE; + break; + + case CONTROL_TYPE_VARSTORE_SELECT: + CtrlVar= ActualCondVar = GetVarNumFromVarID(((EFI_IFR_VARSTORE_SELECT*)((char*)buff +i))->VarId); + AddControl =FALSE; + break; + + case CONTROL_TYPE_VARSTORE_SELECT_PAIR: + CtrlVar= ActualCondVar = GetVarNumFromVarID(((EFI_IFR_VARSTORE_SELECT_PAIR*)((char*)buff +i))->VarId); + ActualCondVar2 = GetVarNumFromVarID(((EFI_IFR_VARSTORE_SELECT_PAIR*)((char*)buff +i))->SecondaryVarId); + AddControl =FALSE; + break; + + + case INCONSISTENT_IF: + case START_EVAL_IF: // IF for grayout,suppress or inconsistent + + + if(updatecondvars == 1) + { + Hdr= (EFI_IFR_OP_HEADER*) (buff+i); + Hdr = (EFI_IFR_OP_HEADER*)((UINT8*)Hdr+Hdr->Length); + // special case if there is a varstore just after the IF + switch(Hdr->OpCode) + { + case EFI_IFR_VARSTORE_SELECT_OP: + ActualCondVar = GetVarNumFromVarID(((EFI_IFR_VARSTORE_SELECT*)((char*)Hdr))->VarId); + break; + case EFI_IFR_VARSTORE_SELECT_PAIR_OP: + ActualCondVar = GetVarNumFromVarID(((EFI_IFR_VARSTORE_SELECT_PAIR*)((char*)Hdr))->VarId); + ActualCondVar2 = GetVarNumFromVarID(((EFI_IFR_VARSTORE_SELECT_PAIR*)((char*)Hdr))->SecondaryVarId); + break; + + } + + // save CtrlcondVars + CtrlCondVar = ActualCondVar; + CtrlCondVar2 = ActualCondVar2; + updatecondvars = 0; + ConditionalPtr = (UINTN)buff+i; + + } + + if(ControlType == INCONSISTENT_IF) + { + AddControl = TRUE; + break; + } + + //break; break not used on purpose + + case 0: // if is not a known control, then go to next control + AddControl = FALSE; + break; + + + } + break; + } + + if(end ==1) + break; + + if(AddControl) + { + Defaults_size =0; + Updatedefaults( (void *)(buff + i) , &Defaults_size, &CtrlFailSafe, &CtrlOptimal, &ControlFlags); + + ControlSize = sizeof(CONTROL_INFO) + Defaults_size * 2; + + NewControlInfo = EfiLibAllocateZeroPool(ControlSize); + + ControlPtr = (UINTN)buff+i; + + if(ControlType == INCONSISTENT_IF) + { + ControlType = CONTROL_TYPE_MSGBOX; + ControlPtr = 0; + } + + NewControlInfo->ControlHandle = gSetupData[HiiIndex].Handle; + NewControlInfo->ControlVariable = CtrlVar; + NewControlInfo->ControlConditionalVariable[0] = CtrlCondVar; + NewControlInfo->ControlConditionalVariable[1] = CtrlCondVar2; + NewControlInfo->ControlType = ControlType & CONTROL_TYPE_MASK; + NewControlInfo->ControlPageID = PageListPtr ? ((UINT16)PageListPtr->PageCount):1; + NewControlInfo->ControlDestPageID = DestPageID; + NewControlInfo->ControlFlags = ControlFlags; + NewControlInfo->ControlHelp = HelpOffset; + NewControlInfo->ControlLabel = (UINT16)controllabel; + NewControlInfo->ControlIndex = (UINT16)controlindex; + NewControlInfo->ControlLabelCount = OpcodeNum; + NewControlInfo->ControlPtr = (VOID*) ControlPtr; + NewControlInfo->ControlConditionalPtr = (VOID*)ConditionalPtr; + NewControlInfo->ControlDataLength = Defaults_size; + NewControlInfo->ControlDataWidth = Defaults_size; + NewControlInfo->QuestionId = QuestionId; + + if(Defaults_size !=0) + { + + switch(Defaults_size) + { + case 1: // BYTE + *((UINT8 *) ((UINT8 *)NewControlInfo + sizeof(CONTROL_INFO))) = (UINT8)CtrlFailSafe; + *((UINT8 *) ((UINT8 *)NewControlInfo + sizeof(CONTROL_INFO) + Defaults_size)) = (UINT8)CtrlOptimal; + break; + case 2: //WORD + *((UINT16 *) ((UINT8 *)NewControlInfo + sizeof(CONTROL_INFO))) = (UINT16)CtrlFailSafe; + *((UINT16 *) ((UINT8 *)NewControlInfo + sizeof(CONTROL_INFO) + Defaults_size)) = (UINT16)CtrlOptimal; + break; + case 4: //DWORD + *((UINT32 *) ((UINT8 *)NewControlInfo + sizeof(CONTROL_INFO))) = (UINT32)CtrlFailSafe; + *((UINT32 *) ((UINT8 *)NewControlInfo + sizeof(CONTROL_INFO) + Defaults_size)) = (UINT32)CtrlOptimal; + break; + } + + } + + ControlOffset = AddControlToList(NewControlInfo, ControlSize); + CreatePage(NewPageInfo, AllocatedPageSize, PageOffset, &ControlOffset, sizeof(UINT32)); + + MemFreePointer(&NewControlInfo); + + if (ControlType & ~ CONTROL_TYPE_MASK) + { + ControlOffset = 0; + CreatePage(NewPageInfo, AllocatedPageSize, PageOffset, &ControlOffset, sizeof(UINT32)); + } + + } + else + AddControl = TRUE; + + switch(ControlType) + { + case CONTROL_TYPE_POPUPSEL: + if( buff[i + sizeof(EFI_IFR_ONE_OF)] == EFI_IFR_ONE_OF_OPTION_OP) + { + j = sizeof(EFI_IFR_ONE_OF); + controlindex+=2; // account for one_of and end_one_of opcodes + while(buff[i+j] == EFI_IFR_ONE_OF_OPTION_OP) + { + j += sizeof(EFI_IFR_ONE_OF_OPTION); + controlindex++; + } + j += sizeof(EFI_IFR_END_ONE_OF); + break; + } + else + { + j= *((char*)buff +i+1); // checkbox + controlindex++; + } + break; + + case CONTROL_TYPE_ORDERED_LIST: + if( buff[i + sizeof(EFI_IFR_ORDERED_LIST)] == EFI_IFR_ONE_OF_OPTION_OP) + { + j = sizeof(EFI_IFR_ONE_OF); + controlindex+=2; // account for one_of and end_one_of opcodes + while(buff[i+j] == EFI_IFR_ONE_OF_OPTION_OP) + { + j += sizeof(EFI_IFR_ONE_OF_OPTION); + controlindex++; + } + j += sizeof(EFI_IFR_END_ONE_OF); + break; + } + + break; + + case CONTROL_TYPE_TIME: + j= 3*(*((char*)buff +i+1)); + controlindex+=2; + break; + + case CONTROL_TYPE_DATE: + j= 3*(*((char*)buff +i+1)); + controlindex+=2; + break; + + case CONTROL_TYPE_VARSTORE: + j= (*((char*)buff +i+1)); + controlindex++; + break; + + default: + if( *((char*)buff +i) != EFI_IFR_LABEL_OP) + controlindex++; + j= *((char*)buff +i+1); + + break; + } + + i= i+ j; + DestPageID = 0x0FFFF; + ControlType = 0; + }; + + return i+2; +} + +// +//---------------------------------------------------------------------------- +// Procedure: HiiGetEfiKey +// +// Description: Function to Encode the password key +// +// Input: CHAR16 *PwKey +// +// Output: VOID +// +//---------------------------------------------------------------------------- +// +VOID HiiGetEfiKey(CHAR16 *PwKey) +{ + 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= gHiiProtocol->GetKeyboardLayout(gHiiProtocol, &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= gHiiProtocol->GetKeyboardLayout(gHiiProtocol, &Count, pEfiKD); + + if(EFI_SUCCESS == Status) + { + for(i=0;iKey; + break; + } + } + } + MemFreePointer((VOID **)&pEfiKD); + } +} +//---------------------------------------------------------------------------- +// 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: HiiRemoveString +// +// Description: +// +// Parameter: EFI_HII_HANDLE Handle, UINT16 Token +// +// Return value: VOID +//---------------------------------------------------------------------------- +// +VOID HiiRemoveString(VOID* Handle, UINT16 Token) +{ + //UEFI2.0 doesn't support +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: UefiGetActionWapper +// +// Description: The Wrapper function to get the actual action for the driver +// +// Parameter: UINTN Action +// +// Return Value: EFI_BROWSER_ACTION +//---------------------------------------------------------------------------- +// +UINTN UefiGetActionWapper(UINTN Action) +{ + return Action; +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: SavePswdString +// +// Description: Dummy fucntion to avoid build error +// +// Parameter: CONTROL_INFO * ControlData, CHAR16 *String +// +// Return Value: VOID +//---------------------------------------------------------------------------- +// +VOID SavePswdString (CONTROL_INFO *ControlData, CHAR16 *String) +{ + +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** -- cgit v1.2.3