X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FSetupBrowserDxe%2FIfrParse.c;h=41f89ea7f61eabe76fc24654685268225da527ca;hb=892eccc8d8697ada395b50738c099f8596a78d82;hp=7a09b32b738df9d7a0b54a3757dc9cd7ab2f0114;hpb=d0720b57060cc8f8bd0c21cb9937bbb87b420d36;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c index 7a09b32b73..41f89ea7f6 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 - 2008, 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,21 +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; -FORM_EXPRESSION *mSuppressExpression; -FORM_EXPRESSION *mGrayOutExpression; - -EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID; -GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID mFrameworkHiiCompatibilityGuid = EFI_IFR_FRAMEWORK_GUID; - - +EFI_QUESTION_ID mUsedQuestionId; +extern LIST_ENTRY gBrowserStorageList; /** Initialize Statement header members. @@ -47,12 +37,13 @@ CreateStatement ( { FORM_BROWSER_STATEMENT *Statement; EFI_IFR_STATEMENT_HEADER *StatementHdr; + INTN ConditionalExprCount; if (Form == NULL) { // - // We are currently not in a Form Scope, so just skip this Statement + // Only guid op may out side the form level. // - return NULL; + ASSERT (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP); } Statement = &FormSet->StatementBuffer[mStatementIndex]; @@ -62,30 +53,39 @@ CreateStatement ( InitializeListHead (&Statement->OptionListHead); InitializeListHead (&Statement->InconsistentListHead); InitializeListHead (&Statement->NoSubmitListHead); + InitializeListHead (&Statement->WarningListHead); Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE; Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode; + Statement->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData; StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER)); 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; + 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; - // // Insert this Statement into current Form // - InsertTailList (&Form->StatementListHead, &Statement->Link); - + if (Form == NULL) { + InsertTailList (&FormSet->StatementListOSF, &Statement->Link); + } else { + InsertTailList (&Form->StatementListHead, &Statement->Link); + } return Statement; } @@ -93,15 +93,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 @@ -112,35 +112,33 @@ UpdateCheckBoxStringToken ( { CHAR16 Str[MAXIMUM_VALUE_CHARACTERS]; EFI_STRING_ID Id; - EFI_STATUS Status; ASSERT (Statement != NULL); ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP); - + UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1); - - Status = HiiLibNewString (FormSet->HiiHandle, &Id, Str); - if (EFI_ERROR (Status)) { - return Status; + Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL); + if (Id == 0) { + return EFI_OUT_OF_RESOURCES; } 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 ) { // @@ -148,9 +146,9 @@ IsNextOpCodeGuidedVarEqName ( // OpCodeData += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length; if (*OpCodeData == EFI_IFR_GUID_OP) { - if (CompareGuid (&mFrameworkHiiCompatibilityGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) { + 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; @@ -184,6 +182,7 @@ CreateQuestion ( FORMSET_STORAGE *Storage; NAME_VALUE_NODE *NameValueNode; EFI_STATUS Status; + BOOLEAN Find; Statement = CreateStatement (OpCodeData, FormSet, Form); if (Statement == NULL) { @@ -208,7 +207,7 @@ CreateQuestion ( // Take a look at next OpCode to see whether it is a GUIDed opcode to support // Framework Compatibility // - if (FeaturePcdGet (PcdFrameworkHiiCompatibilitySupport)) { + if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) { if ((*OpCodeData == EFI_IFR_NUMERIC_OP) && IsNextOpCodeGuidedVarEqName (OpCodeData)) { Status = UpdateCheckBoxStringToken (FormSet, Statement); if (EFI_ERROR (Status)) { @@ -225,7 +224,7 @@ CreateQuestion ( Storage = FORMSET_STORAGE_FROM_LINK (Link); if (Storage->VarStoreId == Statement->VarStoreId) { - Statement->Storage = Storage; + Statement->Storage = Storage->BrowserStorage; break; } @@ -243,19 +242,39 @@ CreateQuestion ( if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) { // - // Insert to Name/Value varstore list + // Check whether old string node already exist. // - NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE)); - ASSERT (NameValueNode != NULL); - NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE; - NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName); - ASSERT (NameValueNode->Name != NULL); - NameValueNode->Value = AllocateZeroPool (0x10); - ASSERT (NameValueNode->Value != NULL); - NameValueNode->EditValue = AllocateZeroPool (0x10); - ASSERT (NameValueNode->EditValue != NULL); + Find = FALSE; + if (!IsListEmpty(&Statement->Storage->NameValueListHead)) { + Link = GetFirstNode (&Statement->Storage->NameValueListHead); + while (!IsNull (&Statement->Storage->NameValueListHead, Link)) { + NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link); + + if (StrCmp (Statement->VariableName, NameValueNode->Name) == 0) { + Find = TRUE; + break; + } + + Link = GetNextNode (&Statement->Storage->NameValueListHead, Link); + } + } - InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link); + if (!Find) { + // + // Insert to Name/Value varstore list + // + NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE)); + ASSERT (NameValueNode != NULL); + NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE; + NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName); + ASSERT (NameValueNode->Name != NULL); + NameValueNode->Value = AllocateZeroPool (0x10); + ASSERT (NameValueNode->Value != NULL); + NameValueNode->EditValue = AllocateZeroPool (0x10); + ASSERT (NameValueNode->EditValue != NULL); + + InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link); + } } } @@ -286,92 +305,241 @@ CreateExpression ( return Expression; } - /** - Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List. + Create ConfigHdr string for a storage. @param FormSet Pointer of the current FormSet + @param Storage Pointer of the storage - @return Pointer to a FORMSET_STORAGE data structure. + @retval EFI_SUCCESS Initialize ConfigHdr success **/ -FORMSET_STORAGE * -CreateStorage ( - IN FORM_BROWSER_FORMSET *FormSet +EFI_STATUS +InitializeConfigHdr ( + IN FORM_BROWSER_FORMSET *FormSet, + IN OUT BROWSER_STORAGE *Storage ) { - FORMSET_STORAGE *Storage; + CHAR16 *Name; - Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE)); - ASSERT (Storage != NULL); - Storage->Signature = FORMSET_STORAGE_SIGNATURE; - InitializeListHead (&Storage->NameValueListHead); - InsertTailList (&FormSet->StorageListHead, &Storage->Link); + if (Storage->Type == EFI_HII_VARSTORE_BUFFER || + Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { + Name = Storage->Name; + } else { + Name = NULL; + } - return Storage; + Storage->ConfigHdr = HiiConstructConfigHdr ( + &Storage->Guid, + Name, + FormSet->DriverHandle + ); + + if (Storage->ConfigHdr == NULL) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** + Find the global storage link base on the input storate type, name and guid. + + For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, + same guid + name = same storage + + For EFI_HII_VARSTORE_NAME_VALUE: + same guid + HiiHandle = same storage + + For EFI_HII_VARSTORE_BUFFER: + same guid + name + HiiHandle = same storage + + @param StorageType Storage type. + @param StorageGuid Storage guid. + @param StorageName Storage Name. + @param HiiHandle HiiHandle for this varstore. + + @return Pointer to a GLOBAL_STORAGE data structure. + +**/ +BROWSER_STORAGE * +FindStorageInList ( + IN UINT8 StorageType, + IN EFI_GUID *StorageGuid, + IN CHAR16 *StorageName, + IN EFI_HII_HANDLE HiiHandle + ) +{ + LIST_ENTRY *Link; + BROWSER_STORAGE *BrowserStorage; + + Link = GetFirstNode (&gBrowserStorageList); + while (!IsNull (&gBrowserStorageList, Link)) { + BrowserStorage = BROWSER_STORAGE_FROM_LINK (Link); + Link = GetNextNode (&gBrowserStorageList, Link); + + if ((BrowserStorage->Type == StorageType) && CompareGuid (&BrowserStorage->Guid, StorageGuid)) { + if (StorageType == EFI_HII_VARSTORE_NAME_VALUE) { + if (BrowserStorage->HiiHandle == HiiHandle) { + return BrowserStorage; + } + + continue; + } + + ASSERT (StorageName != NULL); + if (StrCmp (BrowserStorage->Name, StorageName) == 0) { + if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE || StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { + return BrowserStorage; + } else if (StorageType == EFI_HII_VARSTORE_BUFFER && BrowserStorage->HiiHandle == HiiHandle) { + return BrowserStorage; + } + } + } + } + + return NULL; } +/** + Intialize the Global Storage. + + @param BrowserStorage Pointer to the global storage. + @param StorageType Storage type. + @param OpCodeData Binary data for this opcode. + +**/ +VOID +IntializeBrowserStorage ( + IN BROWSER_STORAGE *BrowserStorage, + IN UINT8 StorageType, + IN UINT8 *OpCodeData + ) +{ + switch (StorageType) { + case EFI_HII_VARSTORE_BUFFER: + CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID)); + CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16)); + + BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size); + BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size); + break; + + case EFI_HII_VARSTORE_EFI_VARIABLE: + case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER: + CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID)); + CopyMem (&BrowserStorage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32)); + CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size, sizeof (UINT16)); + + if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { + BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size); + BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size); + } + break; + + case EFI_HII_VARSTORE_NAME_VALUE: + CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID)); + + InitializeListHead (&BrowserStorage->NameValueListHead); + break; + + default: + break; + } +} /** - Create ConfigHdr string for a storage. + Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List. - @param FormSet Pointer of the current FormSet - @param Storage Pointer of the storage + @param FormSet Pointer of the current FormSet + @param StorageType Storage type. + @param OpCodeData Binary data for this opcode. - @retval EFI_SUCCESS Initialize ConfigHdr success + @return Pointer to a FORMSET_STORAGE data structure. **/ -EFI_STATUS -InitializeConfigHdr ( +FORMSET_STORAGE * +CreateStorage ( IN FORM_BROWSER_FORMSET *FormSet, - IN OUT FORMSET_STORAGE *Storage + IN UINT8 StorageType, + IN UINT8 *OpCodeData ) { - EFI_STATUS Status; - UINTN StrBufferLen; - CHAR16 *Name; + FORMSET_STORAGE *Storage; + CHAR16 *UnicodeString; + UINT16 Index; + BROWSER_STORAGE *BrowserStorage; + EFI_GUID *StorageGuid; + CHAR8 *StorageName; + + UnicodeString = NULL; + StorageName = NULL; + switch (StorageType) { + case EFI_HII_VARSTORE_BUFFER: + StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE *) OpCodeData)->Guid; + StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name; + break; - if (Storage->Type == EFI_HII_VARSTORE_BUFFER) { - Name = Storage->Name; - } else { - Name = NULL; + case EFI_HII_VARSTORE_EFI_VARIABLE: + case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER: + StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid; + StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name; + break; + + default: + ASSERT (StorageType == EFI_HII_VARSTORE_NAME_VALUE); + StorageGuid = &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid; + break; } - StrBufferLen = 0; - Status = ConstructConfigHdr ( - Storage->ConfigHdr, - &StrBufferLen, - &Storage->Guid, - Name, - FormSet->DriverHandle - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - Storage->ConfigHdr = AllocateZeroPool (StrBufferLen); - Status = ConstructConfigHdr ( - Storage->ConfigHdr, - &StrBufferLen, - &Storage->Guid, - Name, - FormSet->DriverHandle - ); + if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) { + ASSERT (StorageName != NULL); + + UnicodeString = AllocateZeroPool (AsciiStrSize (StorageName) * 2); + ASSERT (UnicodeString != NULL); + for (Index = 0; StorageName[Index] != 0; Index++) { + UnicodeString[Index] = (CHAR16) StorageName[Index]; + } } - if (EFI_ERROR (Status)) { - return Status; + Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE)); + ASSERT (Storage != NULL); + Storage->Signature = FORMSET_STORAGE_SIGNATURE; + InsertTailList (&FormSet->StorageListHead, &Storage->Link); + + BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString, FormSet->HiiHandle); + if (BrowserStorage == NULL) { + BrowserStorage = AllocateZeroPool (sizeof (BROWSER_STORAGE)); + ASSERT (BrowserStorage != NULL); + + BrowserStorage->Signature = BROWSER_STORAGE_SIGNATURE; + InsertTailList (&gBrowserStorageList, &BrowserStorage->Link); + + IntializeBrowserStorage (BrowserStorage, StorageType, OpCodeData); + BrowserStorage->Type = StorageType; + if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) { + BrowserStorage->Name = UnicodeString; + } + + BrowserStorage->HiiHandle = FormSet->HiiHandle; + InitializeConfigHdr (FormSet, BrowserStorage); + + BrowserStorage->Initialized = FALSE; } - Storage->ConfigRequest = AllocateCopyPool (StrBufferLen, Storage->ConfigHdr); + Storage->BrowserStorage = BrowserStorage; + Storage->ConfigRequest = AllocateCopyPool (StrSize (BrowserStorage->ConfigHdr), BrowserStorage->ConfigHdr); Storage->SpareStrLen = 0; - return EFI_SUCCESS; + return Storage; } - /** Initialize Request Element of a Question. ::= '&' | '&'