X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FSetupBrowserDxe%2FIfrParse.c;h=cc3823f0efd4573001697ad48bb5e9f2f8a11fbb;hb=a7f87053e00ff8a24664b24f745702fa1ece2d80;hp=3285cfe5aae6acc59c1363219affea71f84066ca;hpb=d02847d3c09bd897934e71d54921e9a2c5baf596;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c index 3285cfe5aa..cc3823f0ef 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c @@ -1,8 +1,8 @@ /** @file Parser for IFR binary encoding. -Copyright (c) 2007 - 2009, Intel Corporation -All rights reserved. This program and the accompanying materials +Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -13,19 +13,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "Setup.h" -#include "Ui.h" UINT16 mStatementIndex; UINT16 mExpressionOpCodeIndex; BOOLEAN mInScopeSubtitle; -BOOLEAN mInScopeSuppress; -BOOLEAN mInScopeGrayOut; -BOOLEAN mInScopeDisable; -FORM_EXPRESSION *mSuppressExpression; -FORM_EXPRESSION *mGrayOutExpression; -FORM_EXPRESSION *mDisableExpression; - /** Initialize Statement header members. @@ -45,6 +37,7 @@ CreateStatement ( { FORM_BROWSER_STATEMENT *Statement; EFI_IFR_STATEMENT_HEADER *StatementHdr; + INTN ConditionalExprCount; if (Form == NULL) { // @@ -69,17 +62,18 @@ CreateStatement ( CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID)); CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID)); - if (mInScopeSuppress) { - Statement->SuppressExpression = mSuppressExpression; - } - - if (mInScopeGrayOut) { - Statement->GrayOutExpression = mGrayOutExpression; - } - - - if (mInScopeDisable) { - Statement->DisableExpression = mDisableExpression; + ConditionalExprCount = GetConditionalExpressionCount(ExpressStatement); + if (ConditionalExprCount > 0) { + // + // Form is inside of suppressif + // + + Statement->Expression = (FORM_EXPRESSION_LIST *) AllocatePool( + (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *)))); + ASSERT (Statement->Expression != NULL); + Statement->Expression->Count = (UINTN) ConditionalExprCount; + Statement->Expression->Signature = FORM_EXPRESSION_LIST_SIGNATURE; + CopyMem (Statement->Expression->Expression, GetConditionalExpressionList(ExpressStatement), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount)); } Statement->InSubtitle = mInScopeSubtitle; @@ -96,15 +90,15 @@ CreateStatement ( Convert a numeric value to a Unicode String and insert it to String Package. This string is used as the Unicode Name for the EFI Variable. This is to support the deprecated vareqval opcode. - + @param FormSet The FormSet. @param Statement The numeric question whose VarStoreInfo.VarName is the numeric value which is used to produce the Unicode Name for the EFI Variable. - + If the Statement is NULL, the ASSERT. If the opcode is not Numeric, then ASSERT. - + @retval EFI_SUCCESS The funtion always succeeds. **/ EFI_STATUS @@ -118,7 +112,7 @@ UpdateCheckBoxStringToken ( ASSERT (Statement != NULL); ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP); - + UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1); Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL); @@ -127,21 +121,21 @@ UpdateCheckBoxStringToken ( } Statement->VarStoreInfo.VarName = Id; - + return EFI_SUCCESS; } /** Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME. - + @param OpCodeData The current opcode. - + @retval TRUE Yes. @retval FALSE No. **/ BOOLEAN IsNextOpCodeGuidedVarEqName ( - UINT8 *OpCodeData + IN UINT8 *OpCodeData ) { // @@ -151,7 +145,7 @@ IsNextOpCodeGuidedVarEqName ( if (*OpCodeData == EFI_IFR_GUID_OP) { if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) { // - // Specific GUIDed opcodes to support IFR generated from Framework HII VFR + // Specific GUIDed opcodes to support IFR generated from Framework HII VFR // if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) { return TRUE; @@ -329,19 +323,20 @@ InitializeConfigHdr ( ) { CHAR16 *Name; - - if (Storage->Type == EFI_HII_VARSTORE_BUFFER) { + + if (Storage->Type == EFI_HII_VARSTORE_BUFFER || + Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { Name = Storage->Name; } else { Name = NULL; } - + Storage->ConfigHdr = HiiConstructConfigHdr ( &Storage->Guid, Name, FormSet->DriverHandle ); - + if (Storage->ConfigHdr == NULL) { return EFI_NOT_FOUND; } @@ -358,6 +353,7 @@ InitializeConfigHdr ( @param FormSet Pointer of the current FormSet. @param Question The Question to be initialized. + @param Form Pointer of the current form. @retval EFI_SUCCESS Function success. @retval EFI_INVALID_PARAMETER No storage associated with the Question. @@ -366,7 +362,8 @@ InitializeConfigHdr ( EFI_STATUS InitializeRequestElement ( IN OUT FORM_BROWSER_FORMSET *FormSet, - IN OUT FORM_BROWSER_STATEMENT *Question + IN OUT FORM_BROWSER_STATEMENT *Question, + IN OUT FORM_BROWSER_FORM *Form ) { FORMSET_STORAGE *Storage; @@ -374,6 +371,9 @@ InitializeRequestElement ( UINTN StringSize; CHAR16 *NewStr; CHAR16 RequestElement[30]; + LIST_ENTRY *Link; + BOOLEAN Find; + FORM_BROWSER_CONFIG_REQUEST *ConfigInfo; Storage = Question->Storage; if (Storage == NULL) { @@ -391,7 +391,8 @@ InitializeRequestElement ( // // Prepare // - if (Storage->Type == EFI_HII_VARSTORE_BUFFER) { + if (Storage->Type == EFI_HII_VARSTORE_BUFFER || + Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { StrLen = UnicodeSPrint ( RequestElement, 30 * sizeof (CHAR16), @@ -434,6 +435,54 @@ InitializeRequestElement ( Storage->ElementCount++; Storage->SpareStrLen -= StrLen; + // + // Update the Config Request info saved in the form. + // + ConfigInfo = NULL; + Find = FALSE; + Link = GetFirstNode (&Form->ConfigRequestHead); + while (!IsNull (&Form->ConfigRequestHead, Link)) { + ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link); + + if (ConfigInfo != NULL && ConfigInfo->Storage->VarStoreId == Storage->VarStoreId) { + Find = TRUE; + break; + } + + Link = GetNextNode (&Form->ConfigRequestHead, Link); + } + + if (!Find) { + ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST)); + ASSERT (ConfigInfo != NULL); + ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE; + ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr); + ConfigInfo->SpareStrLen = 0; + ConfigInfo->Storage = Storage; + InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link); + } + + // + // Append to + // + if (StrLen > ConfigInfo->SpareStrLen) { + // + // Old String buffer is not sufficient for RequestElement, allocate a new one + // + StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16); + NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16)); + ASSERT (NewStr != NULL); + if (ConfigInfo->ConfigRequest != NULL) { + CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize); + FreePool (ConfigInfo->ConfigRequest); + } + ConfigInfo->ConfigRequest = NewStr; + ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL; + } + + StrCat (ConfigInfo->ConfigRequest, RequestElement); + ConfigInfo->ElementCount++; + ConfigInfo->SpareStrLen -= StrLen; return EFI_SUCCESS; } @@ -451,6 +500,8 @@ DestroyExpression ( { LIST_ENTRY *Link; EXPRESSION_OPCODE *OpCode; + LIST_ENTRY *SubExpressionLink; + FORM_EXPRESSION *SubExpression; while (!IsListEmpty (&Expression->OpCodeListHead)) { Link = GetFirstNode (&Expression->OpCodeListHead); @@ -460,6 +511,19 @@ DestroyExpression ( if (OpCode->ValueList != NULL) { FreePool (OpCode->ValueList); } + + if (OpCode->ValueName != NULL) { + FreePool (OpCode->ValueName); + } + + if (OpCode->MapExpressionList.ForwardLink != NULL) { + while (!IsListEmpty (&OpCode->MapExpressionList)) { + SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList); + SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink); + RemoveEntryList(&SubExpression->Link); + DestroyExpression (SubExpression); + } + } } // @@ -528,11 +592,13 @@ DestroyStorage ( /** Free resources of a Statement. + @param FormSet Pointer of the FormSet @param Statement Pointer of the Statement **/ VOID DestroyStatement ( + IN FORM_BROWSER_FORMSET *FormSet, IN OUT FORM_BROWSER_STATEMENT *Statement ) { @@ -558,6 +624,9 @@ DestroyStatement ( while (!IsListEmpty (&Statement->OptionListHead)) { Link = GetFirstNode (&Statement->OptionListHead); Option = QUESTION_OPTION_FROM_LINK (Link); + if (Option->SuppressExpression != NULL) { + FreePool (Option->SuppressExpression); + } RemoveEntryList (&Option->Link); FreePool (Option); @@ -585,29 +654,42 @@ DestroyStatement ( DestroyExpression (Expression); } + if (Statement->Expression != NULL) { + FreePool (Statement->Expression); + } + if (Statement->VariableName != NULL) { FreePool (Statement->VariableName); } if (Statement->BlockName != NULL) { FreePool (Statement->BlockName); } + if (Statement->BufferValue != NULL) { + FreePool (Statement->BufferValue); + } + if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) { + DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle); + } } /** Free resources of a Form. + @param FormSet Pointer of the FormSet @param Form Pointer of the Form. **/ VOID DestroyForm ( - IN OUT FORM_BROWSER_FORM *Form + IN FORM_BROWSER_FORMSET *FormSet, + IN OUT FORM_BROWSER_FORM *Form ) { LIST_ENTRY *Link; FORM_EXPRESSION *Expression; FORM_BROWSER_STATEMENT *Statement; + FORM_BROWSER_CONFIG_REQUEST *ConfigInfo; // // Free Form Expressions @@ -628,7 +710,23 @@ DestroyForm ( Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link); RemoveEntryList (&Statement->Link); - DestroyStatement (Statement); + DestroyStatement (FormSet, Statement); + } + + // + // Free ConfigRequest string. + // + while (!IsListEmpty (&Form->ConfigRequestHead)) { + Link = GetFirstNode (&Form->ConfigRequestHead); + ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link); + RemoveEntryList (&ConfigInfo->Link); + + FreePool (ConfigInfo->ConfigRequest); + FreePool (ConfigInfo); + } + + if (Form->SuppressExpression != NULL) { + FreePool (Form->SuppressExpression); } // @@ -652,8 +750,17 @@ DestroyFormSet ( LIST_ENTRY *Link; FORMSET_STORAGE *Storage; FORMSET_DEFAULTSTORE *DefaultStore; + FORM_EXPRESSION *Expression; FORM_BROWSER_FORM *Form; + if (FormSet->IfrBinaryData == NULL) { + // + // Uninitialized FormSet + // + FreePool (FormSet); + return; + } + // // Free IFR binary buffer // @@ -685,6 +792,17 @@ DestroyFormSet ( } } + // + // Free Formset Expressions + // + while (!IsListEmpty (&FormSet->ExpressionListHead)) { + Link = GetFirstNode (&FormSet->ExpressionListHead); + Expression = FORM_EXPRESSION_FROM_LINK (Link); + RemoveEntryList (&Expression->Link); + + DestroyExpression (Expression); + } + // // Free Forms // @@ -694,7 +812,7 @@ DestroyFormSet ( Form = FORM_BROWSER_FORM_FROM_LINK (Link); RemoveEntryList (&Form->Link); - DestroyForm (Form); + DestroyForm (FormSet, Form); } } @@ -724,12 +842,14 @@ IsExpressionOpCode ( ) { if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) || - ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) || + ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) || + ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) || (Operand == EFI_IFR_CATENATE_OP) || (Operand == EFI_IFR_TO_LOWER_OP) || (Operand == EFI_IFR_TO_UPPER_OP) || - (Operand == EFI_IFR_VERSION_OP) - ) { + (Operand == EFI_IFR_MAP_OP) || + (Operand == EFI_IFR_VERSION_OP) || + (Operand == EFI_IFR_SECURITY_OP)) { return TRUE; } else { return FALSE; @@ -815,21 +935,26 @@ ParseOpCodes ( UINT16 NumberOfStatement; UINT16 NumberOfExpression; EFI_IMAGE_ID *ImageId; + BOOLEAN SuppressForQuestion; BOOLEAN SuppressForOption; - BOOLEAN InScopeOptionSuppress; - FORM_EXPRESSION *OptionSuppressExpression; UINT16 DepthOfDisable; BOOLEAN OpCodeDisabled; BOOLEAN SingleOpCodeExpression; BOOLEAN InScopeDefault; EFI_HII_VALUE *Value; + EFI_IFR_FORM_MAP_METHOD *MapMethod; + UINT8 MapScopeDepth; + LIST_ENTRY *Link; + FORMSET_STORAGE *VarStorage; + LIST_ENTRY *MapExpressionList; + EFI_VARSTORE_ID TempVarstoreId; + BOOLEAN InScopeDisable; + INTN ConditionalExprCount; mInScopeSubtitle = FALSE; + SuppressForQuestion = FALSE; SuppressForOption = FALSE; - mInScopeSuppress = FALSE; - InScopeOptionSuppress = FALSE; - mInScopeGrayOut = FALSE; - mInScopeDisable = FALSE; + InScopeDisable = FALSE; DepthOfDisable = 0; OpCodeDisabled = FALSE; SingleOpCodeExpression = FALSE; @@ -837,8 +962,14 @@ ParseOpCodes ( CurrentExpression = NULL; CurrentDefault = NULL; CurrentOption = NULL; - OptionSuppressExpression = NULL; ImageId = NULL; + MapMethod = NULL; + MapScopeDepth = 0; + Link = NULL; + VarStorage = NULL; + MapExpressionList = NULL; + TempVarstoreId = 0; + ConditionalExprCount = 0; // // Get the number of Statements and Expressions @@ -860,6 +991,9 @@ ParseOpCodes ( InitializeListHead (&FormSet->StorageListHead); InitializeListHead (&FormSet->DefaultStoreListHead); InitializeListHead (&FormSet->FormListHead); + InitializeListHead (&FormSet->ExpressionListHead); + ResetCurrentExpressionStack (); + ResetMapExpressionListStack (); CurrentForm = NULL; CurrentStatement = NULL; @@ -897,7 +1031,7 @@ ParseOpCodes ( if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) { if (DepthOfDisable == 0) { - mInScopeDisable = FALSE; + InScopeDisable = FALSE; OpCodeDisabled = FALSE; } else { DepthOfDisable--; @@ -928,7 +1062,7 @@ ParseOpCodes ( CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID)); break; - case EFI_IFR_EQ_ID_LIST_OP: + case EFI_IFR_EQ_ID_VAL_LIST_OP: CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID)); CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16)); ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList); @@ -957,6 +1091,89 @@ ParseOpCodes ( ExpressionOpCode->QuestionId = CurrentStatement->QuestionId; break; + case EFI_IFR_SECURITY_OP: + CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID)); + break; + + case EFI_IFR_GET_OP: + case EFI_IFR_SET_OP: + CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId)); + if (TempVarstoreId != 0) { + if (FormSet->StorageListHead.ForwardLink != NULL) { + Link = GetFirstNode (&FormSet->StorageListHead); + while (!IsNull (&FormSet->StorageListHead, Link)) { + VarStorage = FORMSET_STORAGE_FROM_LINK (Link); + if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) { + ExpressionOpCode->VarStorage = VarStorage; + break; + } + Link = GetNextNode (&FormSet->StorageListHead, Link); + } + } + if (ExpressionOpCode->VarStorage == NULL) { + // + // VarStorage is not found. + // + return EFI_INVALID_PARAMETER; + } + } + ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType; + switch (ExpressionOpCode->ValueType) { + case EFI_IFR_TYPE_BOOLEAN: + case EFI_IFR_TYPE_NUM_SIZE_8: + ExpressionOpCode->ValueWidth = 1; + break; + + case EFI_IFR_TYPE_NUM_SIZE_16: + case EFI_IFR_TYPE_STRING: + ExpressionOpCode->ValueWidth = 2; + break; + + case EFI_IFR_TYPE_NUM_SIZE_32: + ExpressionOpCode->ValueWidth = 4; + break; + + case EFI_IFR_TYPE_NUM_SIZE_64: + ExpressionOpCode->ValueWidth = 8; + break; + + case EFI_IFR_TYPE_DATE: + ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE); + break; + + case EFI_IFR_TYPE_TIME: + ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME); + break; + + case EFI_IFR_TYPE_REF: + ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF); + break; + + case EFI_IFR_TYPE_OTHER: + case EFI_IFR_TYPE_UNDEFINED: + case EFI_IFR_TYPE_ACTION: + case EFI_IFR_TYPE_BUFFER: + default: + // + // Invalid value type for Get/Set opcode. + // + return EFI_INVALID_PARAMETER; + } + CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID)); + CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16)); + if ((ExpressionOpCode->VarStorage != NULL) && + (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE || + ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) { + ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle); + if (ExpressionOpCode->ValueName == NULL) { + // + // String ID is invalid. + // + return EFI_INVALID_PARAMETER; + } + } + break; + case EFI_IFR_QUESTION_REF1_OP: CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID)); break; @@ -1031,11 +1248,38 @@ ParseOpCodes ( default: break; } - + // + // Create sub expression nested in MAP opcode + // + if (CurrentExpression == NULL && MapScopeDepth > 0) { + CurrentExpression = CreateExpression (CurrentForm); + ASSERT (MapExpressionList != NULL); + InsertTailList (MapExpressionList, &CurrentExpression->Link); + if (Scope == 0) { + SingleOpCodeExpression = TRUE; + } + } ASSERT (CurrentExpression != NULL); InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link); - - if (SingleOpCodeExpression) { + if (Operand == EFI_IFR_MAP_OP) { + // + // Store current Map Expression List. + // + if (MapExpressionList != NULL) { + PushMapExpressionList (MapExpressionList); + } + // + // Initialize new Map Expression List. + // + MapExpressionList = &ExpressionOpCode->MapExpressionList; + InitializeListHead (MapExpressionList); + // + // Store current expression. + // + PushCurrentExpression (CurrentExpression); + CurrentExpression = NULL; + MapScopeDepth ++; + } else if (SingleOpCodeExpression) { // // There are two cases to indicate the end of an Expression: // for single OpCode expression: one Expression OpCode @@ -1043,7 +1287,7 @@ ParseOpCodes ( // SingleOpCodeExpression = FALSE; - if (mInScopeDisable && CurrentForm == NULL) { + if (InScopeDisable && CurrentForm == NULL) { // // This is DisableIf expression for Form, it should be a constant expression // @@ -1081,11 +1325,13 @@ ParseOpCodes ( CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID)); CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID)); - // - // The formset OpCode contains ClassGuid - // - FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3); - CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID)); + if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) { + // + // The formset OpCode contains ClassGuid + // + FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3); + CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID)); + } break; case EFI_IFR_FORM_OP: @@ -1097,10 +1343,98 @@ ParseOpCodes ( CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE; InitializeListHead (&CurrentForm->ExpressionListHead); InitializeListHead (&CurrentForm->StatementListHead); + InitializeListHead (&CurrentForm->ConfigRequestHead); + CurrentForm->FormType = STANDARD_MAP_FORM_TYPE; + CurrentForm->NvUpdateRequired = FALSE; CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16)); CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID)); + ConditionalExprCount = GetConditionalExpressionCount(ExpressForm); + if ( ConditionalExprCount > 0) { + // + // Form is inside of suppressif + // + CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool( + (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *)))); + ASSERT (CurrentForm->SuppressExpression != NULL); + CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount; + CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE; + CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount)); + } + + if (Scope != 0) { + // + // Enter scope of a Form, suppressif will be used for Question or Option + // + SuppressForQuestion = TRUE; + } + + // + // Insert into Form list of this FormSet + // + InsertTailList (&FormSet->FormListHead, &CurrentForm->Link); + break; + + case EFI_IFR_FORM_MAP_OP: + // + // Create a new Form for this FormSet + // + CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM)); + ASSERT (CurrentForm != NULL); + CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE; + CurrentForm->NvUpdateRequired = FALSE; + InitializeListHead (&CurrentForm->ExpressionListHead); + InitializeListHead (&CurrentForm->StatementListHead); + InitializeListHead (&CurrentForm->ConfigRequestHead); + CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16)); + + MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP)); + // + // FormMap Form must contain at least one Map Method. + // + if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) { + return EFI_INVALID_PARAMETER; + } + // + // Try to find the standard form map method. + // + while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) { + if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) { + CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID)); + CurrentForm->FormType = STANDARD_MAP_FORM_TYPE; + break; + } + MapMethod ++; + } + // + // If the standard form map method is not found, the first map method title will be used. + // + if (CurrentForm->FormTitle == 0) { + MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP)); + CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID)); + } + + ConditionalExprCount = GetConditionalExpressionCount(ExpressForm); + if ( ConditionalExprCount > 0) { + // + // Form is inside of suppressif + // + CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool( + (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *)))); + ASSERT (CurrentForm->SuppressExpression != NULL); + CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount; + CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE; + CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount)); + } + + if (Scope != 0) { + // + // Enter scope of a Form, suppressif will be used for Question or Option + // + SuppressForQuestion = TRUE; + } + // // Insert into Form list of this FormSet // @@ -1158,11 +1492,32 @@ ParseOpCodes ( // Create a EFI variable Storage for this FormSet // Storage = CreateStorage (FormSet); - Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE; CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID)); CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID)); CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32)); + CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size, sizeof (UINT16)); + + if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) { + Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE; + break; + } + + Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER; + Storage->Buffer = AllocateZeroPool (Storage->Size); + Storage->EditBuffer = AllocateZeroPool (Storage->Size); + + AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name; + Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2); + ASSERT (Storage->Name != NULL); + for (Index = 0; AsciiString[Index] != 0; Index++) { + Storage->Name[Index] = (CHAR16) AsciiString[Index]; + } + + // + // Initialize + // + InitializeConfigHdr (FormSet, Storage); break; // @@ -1188,7 +1543,7 @@ ParseOpCodes ( case EFI_IFR_SUBTITLE_OP: CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm); ASSERT (CurrentStatement != NULL); - + CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags; if (Scope != 0) { @@ -1230,26 +1585,32 @@ ParseOpCodes ( case EFI_IFR_REF_OP: CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); ASSERT (CurrentStatement != NULL); - CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED; - CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID)); - if (OpCodeLength >= sizeof (EFI_IFR_REF2)) { - CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID)); + Value = &CurrentStatement->HiiValue; + Value->Type = EFI_IFR_TYPE_REF; + if (OpCodeLength >= sizeof (EFI_IFR_REF)) { + CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID)); - if (OpCodeLength >= sizeof (EFI_IFR_REF3)) { - CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID)); + if (OpCodeLength >= sizeof (EFI_IFR_REF2)) { + CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID)); - if (OpCodeLength >= sizeof (EFI_IFR_REF4)) { - CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID)); + if (OpCodeLength >= sizeof (EFI_IFR_REF3)) { + CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID)); + + if (OpCodeLength >= sizeof (EFI_IFR_REF4)) { + CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID)); + } } } } + CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); break; case EFI_IFR_ONE_OF_OP: case EFI_IFR_NUMERIC_OP: CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); ASSERT(CurrentStatement != NULL); - + CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags; Value = &CurrentStatement->HiiValue; @@ -1258,7 +1619,7 @@ ParseOpCodes ( CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue; CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue; CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step; - CurrentStatement->StorageWidth = sizeof (UINT8); + CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8); Value->Type = EFI_IFR_TYPE_NUM_SIZE_8; break; @@ -1266,7 +1627,7 @@ ParseOpCodes ( CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16)); CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16)); CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16)); - CurrentStatement->StorageWidth = sizeof (UINT16); + CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16); Value->Type = EFI_IFR_TYPE_NUM_SIZE_16; break; @@ -1274,7 +1635,7 @@ ParseOpCodes ( CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32)); CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32)); CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32)); - CurrentStatement->StorageWidth = sizeof (UINT32); + CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32); Value->Type = EFI_IFR_TYPE_NUM_SIZE_32; break; @@ -1282,7 +1643,7 @@ ParseOpCodes ( CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64)); CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64)); CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64)); - CurrentStatement->StorageWidth = sizeof (UINT64); + CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64); Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; break; @@ -1290,7 +1651,7 @@ ParseOpCodes ( break; } - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) { SuppressForOption = TRUE; @@ -1300,11 +1661,12 @@ ParseOpCodes ( case EFI_IFR_ORDERED_LIST_OP: CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); ASSERT(CurrentStatement != NULL); - + CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags; CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers; CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER; + CurrentStatement->BufferValue = NULL; if (Scope != 0) { SuppressForOption = TRUE; @@ -1314,12 +1676,12 @@ ParseOpCodes ( case EFI_IFR_CHECKBOX_OP: CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); ASSERT(CurrentStatement != NULL); - + CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags; - CurrentStatement->StorageWidth = sizeof (BOOLEAN); + CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN); CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN; - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); break; @@ -1338,8 +1700,9 @@ ParseOpCodes ( CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING; CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16)); + CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle); - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); break; case EFI_IFR_PASSWORD_OP: @@ -1356,21 +1719,22 @@ ParseOpCodes ( CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING; CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16))); + CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle); - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); break; case EFI_IFR_DATE_OP: CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); ASSERT(CurrentStatement != NULL); - + CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags; CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE; if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) { - CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE); + CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE); - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); } else { // // Don't assign storage for RTC type of date/time @@ -1383,14 +1747,14 @@ ParseOpCodes ( case EFI_IFR_TIME_OP: CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); ASSERT(CurrentStatement != NULL); - + CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags; CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME; if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) { - CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME); + CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME); - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); } else { // // Don't assign storage for RTC type of date/time @@ -1415,8 +1779,10 @@ ParseOpCodes ( CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type; CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16)); - CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE)); - ExtendValueToU64 (&CurrentDefault->Value); + if (OpCodeLength > OFFSET_OF (EFI_IFR_DEFAULT, Value)) { + CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value)); + ExtendValueToU64 (&CurrentDefault->Value); + } // // Insert to Default Value list of current Question @@ -1443,11 +1809,20 @@ ParseOpCodes ( CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags; CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type; CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID)); - CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE)); + CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value)); ExtendValueToU64 (&CurrentOption->Value); - if (InScopeOptionSuppress) { - CurrentOption->SuppressExpression = OptionSuppressExpression; + ConditionalExprCount = GetConditionalExpressionCount(ExpressOption); + if ( ConditionalExprCount > 0) { + // + // Form is inside of suppressif + // + CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool( + (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *)))); + ASSERT (CurrentOption->SuppressExpression != NULL); + CurrentOption->SuppressExpression->Count = (UINTN) ConditionalExprCount; + CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE; + CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount)); } // @@ -1458,6 +1833,7 @@ ParseOpCodes ( // // Now we know the Storage width of nested Ordered List // + ASSERT (CurrentStatement != NULL); if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) { Width = 1; switch (CurrentOption->Value.Type) { @@ -1487,8 +1863,12 @@ ParseOpCodes ( CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width); CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth); CurrentStatement->ValueType = CurrentOption->Value.Type; + if (CurrentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) { + CurrentStatement->HiiValue.Buffer = CurrentStatement->BufferValue; + CurrentStatement->HiiValue.BufferLen = CurrentStatement->StorageWidth; + } - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); } break; @@ -1510,6 +1890,14 @@ ParseOpCodes ( CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF; InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link); } + + // + // Take a look at next OpCode to see whether current expression consists + // of single OpCode + // + if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) { + SingleOpCodeExpression = TRUE; + } break; case EFI_IFR_SUPPRESS_IF_OP: @@ -1518,14 +1906,27 @@ ParseOpCodes ( // CurrentExpression = CreateExpression (CurrentForm); CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF; - InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link); + + if (CurrentForm == NULL) { + InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link); + } else { + InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link); + } if (SuppressForOption) { - InScopeOptionSuppress = TRUE; - OptionSuppressExpression = CurrentExpression; + PushConditionalExpression(CurrentExpression, ExpressOption); + } else if (SuppressForQuestion) { + PushConditionalExpression(CurrentExpression, ExpressStatement); } else { - mInScopeSuppress = TRUE; - mSuppressExpression = CurrentExpression; + PushConditionalExpression(CurrentExpression, ExpressForm); + } + + // + // Take a look at next OpCode to see whether current expression consists + // of single OpCode + // + if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) { + SingleOpCodeExpression = TRUE; } break; @@ -1536,9 +1937,15 @@ ParseOpCodes ( CurrentExpression = CreateExpression (CurrentForm); CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF; InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link); + PushConditionalExpression(CurrentExpression, ExpressStatement); - mInScopeGrayOut = TRUE; - mGrayOutExpression = CurrentExpression; + // + // Take a look at next OpCode to see whether current expression consists + // of single OpCode + // + if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) { + SingleOpCodeExpression = TRUE; + } break; case EFI_IFR_DISABLE_IF_OP: @@ -1557,12 +1964,11 @@ ParseOpCodes ( // This is DisableIf for Question, enqueue it to Form expression list // InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link); + PushConditionalExpression(CurrentExpression, ExpressStatement); } - mDisableExpression = CurrentExpression; - mInScopeDisable = TRUE; - OpCodeDisabled = FALSE; - + OpCodeDisabled = FALSE; + InScopeDisable = TRUE; // // Take a look at next OpCode to see whether current expression consists // of single OpCode @@ -1597,6 +2003,14 @@ ParseOpCodes ( ASSERT (CurrentStatement != NULL); CurrentStatement->ValueExpression = CurrentExpression; } + + // + // Take a look at next OpCode to see whether current expression consists + // of single OpCode + // + if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) { + SingleOpCodeExpression = TRUE; + } break; case EFI_IFR_RULE_OP: @@ -1605,6 +2019,58 @@ ParseOpCodes ( CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId; InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link); + + // + // Take a look at next OpCode to see whether current expression consists + // of single OpCode + // + if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) { + SingleOpCodeExpression = TRUE; + } + break; + + case EFI_IFR_READ_OP: + CurrentExpression = CreateExpression (CurrentForm); + CurrentExpression->Type = EFI_HII_EXPRESSION_READ; + InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link); + + // + // Make sure CurrentStatement is not NULL. + // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR + // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler. + // + ASSERT (CurrentStatement != NULL); + CurrentStatement->ReadExpression = CurrentExpression; + + // + // Take a look at next OpCode to see whether current expression consists + // of single OpCode + // + if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) { + SingleOpCodeExpression = TRUE; + } + break; + + case EFI_IFR_WRITE_OP: + CurrentExpression = CreateExpression (CurrentForm); + CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE; + InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link); + + // + // Make sure CurrentStatement is not NULL. + // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR + // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler. + // + ASSERT (CurrentStatement != NULL); + CurrentStatement->WriteExpression = CurrentExpression; + + // + // Take a look at next OpCode to see whether current expression consists + // of single OpCode + // + if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) { + SingleOpCodeExpression = TRUE; + } break; // @@ -1623,6 +2089,7 @@ ParseOpCodes ( break; case EFI_IFR_FORM_OP: + case EFI_IFR_FORM_MAP_OP: ASSERT (CurrentForm != NULL); ImageId = &CurrentForm->ImageId; break; @@ -1654,6 +2121,44 @@ ParseOpCodes ( CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval; break; + // + // Refresh guid. + // + case EFI_IFR_REFRESH_ID_OP: + ASSERT (CurrentStatement != NULL); + CopyMem (&CurrentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID)); + break; + + // + // Modal tag + // + case EFI_IFR_MODAL_TAG_OP: + ASSERT (CurrentForm != NULL); + CurrentForm->ModalForm = TRUE; + break; + + // + // Lock tag, used by form and statement. + // + case EFI_IFR_LOCKED_OP: + // + // Get ScopeOpcode from top of stack + // + PopScope (&ScopeOpCode); + PushScope (ScopeOpCode); + switch (ScopeOpCode) { + case EFI_IFR_FORM_OP: + case EFI_IFR_FORM_MAP_OP: + ASSERT (CurrentForm != NULL); + CurrentForm->Locked = TRUE; + break; + + default: + ASSERT (CurrentStatement != NULL); + CurrentStatement->Locked = TRUE; + } + break; + // // Vendor specific // @@ -1718,10 +2223,12 @@ ParseOpCodes ( break; case EFI_IFR_FORM_OP: + case EFI_IFR_FORM_MAP_OP: // // End of Form // CurrentForm = NULL; + SuppressForQuestion = FALSE; break; case EFI_IFR_ONE_OF_OPTION_OP: @@ -1744,18 +2251,23 @@ ParseOpCodes ( case EFI_IFR_SUPPRESS_IF_OP: if (SuppressForOption) { - InScopeOptionSuppress = FALSE; + PopConditionalExpression(ExpressOption); + } else if (SuppressForQuestion) { + PopConditionalExpression(ExpressStatement); } else { - mInScopeSuppress = FALSE; + PopConditionalExpression(ExpressForm); } break; case EFI_IFR_GRAY_OUT_IF_OP: - mInScopeGrayOut = FALSE; + PopConditionalExpression(ExpressStatement); break; case EFI_IFR_DISABLE_IF_OP: - mInScopeDisable = FALSE; + if (CurrentForm != NULL) { + PopConditionalExpression(ExpressStatement); + } + InScopeDisable = FALSE; OpCodeDisabled = FALSE; break; @@ -1768,9 +2280,26 @@ ParseOpCodes ( InScopeDefault = FALSE; break; + case EFI_IFR_MAP_OP: + // + // Get current Map Expression List. + // + Status = PopMapExpressionList ((VOID **) &MapExpressionList); + if (Status == EFI_ACCESS_DENIED) { + MapExpressionList = NULL; + } + // + // Get current expression. + // + Status = PopCurrentExpression ((VOID **) &CurrentExpression); + ASSERT_EFI_ERROR (Status); + ASSERT (MapScopeDepth > 0); + MapScopeDepth --; + break; + default: if (IsExpressionOpCode (ScopeOpCode)) { - if (mInScopeDisable && CurrentForm == NULL) { + if (InScopeDisable && CurrentForm == NULL) { // // This is DisableIf expression for Form, it should be a constant expression // @@ -1786,7 +2315,7 @@ ParseOpCodes ( OpCodeDisabled = CurrentExpression->Result.Value.b; // - // DisableIf Expression is only used once and not quequed, free it + // DisableIf Expression is only used once and not queued, free it // DestroyExpression (CurrentExpression); }