X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FSetupBrowserDxe%2FIfrParse.c;h=8e8607d4c0093c77589c9189d4542c1ac4a0c70c;hb=3f5287971ffdb5c42e3325a3a94c101f08d3a02a;hp=161e15401b8785dc45583f32ad61199261f8792b;hpb=cbf73e503031172207d39cdabe3bf1b56d453997;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c index 161e15401b..8e8607d4c0 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 - 2015, 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 @@ -16,15 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. UINT16 mStatementIndex; UINT16 mExpressionOpCodeIndex; - -BOOLEAN mInScopeSubtitle; -BOOLEAN mInScopeSuppress; -BOOLEAN mInScopeGrayOut; -BOOLEAN mInScopeDisable; -FORM_EXPRESSION *mSuppressExpression; -FORM_EXPRESSION *mGrayOutExpression; -FORM_EXPRESSION *mDisableExpression; - +EFI_QUESTION_ID mUsedQuestionId; +extern LIST_ENTRY gBrowserStorageList; /** Initialize Statement header members. @@ -44,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]; @@ -59,35 +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; - } - - - 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; - // // 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; } @@ -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) { @@ -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; + } - InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link); + Link = GetNextNode (&Statement->Storage->NameValueListHead, 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); + } } } @@ -267,13 +286,15 @@ CreateQuestion ( Allocate a FORM_EXPRESSION node. @param Form The Form associated with this Expression + @param OpCode The binary opcode data. @return Pointer to a FORM_EXPRESSION data structure. **/ FORM_EXPRESSION * CreateExpression ( - IN OUT FORM_BROWSER_FORM *Form + IN OUT FORM_BROWSER_FORM *Form, + IN UINT8 *OpCode ) { FORM_EXPRESSION *Expression; @@ -282,81 +303,370 @@ CreateExpression ( ASSERT (Expression != NULL); Expression->Signature = FORM_EXPRESSION_SIGNATURE; InitializeListHead (&Expression->OpCodeListHead); + Expression->OpCode = (EFI_IFR_OP_HEADER *) OpCode; return Expression; } +/** + Create ConfigHdr string for a storage. + + @param FormSet Pointer of the current FormSet + @param Storage Pointer of the storage + + @retval EFI_SUCCESS Initialize ConfigHdr success + +**/ +EFI_STATUS +InitializeConfigHdr ( + IN FORM_BROWSER_FORMSET *FormSet, + IN OUT FORMSET_STORAGE *Storage + ) +{ + CHAR16 *Name; + + if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER || + Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { + Name = Storage->BrowserStorage->Name; + } else { + Name = NULL; + } + + Storage->ConfigHdr = HiiConstructConfigHdr ( + &Storage->BrowserStorage->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; + } +} + +/** + Check whether exist device path info in the ConfigHdr string. + + @param String UEFI configuration string + + @retval TRUE Device Path exist. + @retval FALSE Not exist device path info. + +**/ +BOOLEAN +IsDevicePathExist ( + IN EFI_STRING String + ) +{ + UINTN Length; + + for (; (*String != 0 && StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0); String++); + if (*String == 0) { + return FALSE; + } + + String += StrLen (L"PATH="); + if (*String == 0) { + return FALSE; + } + + for (Length = 0; *String != 0 && *String != L'&'; String++, Length++); + if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { + return FALSE; + } + + return TRUE; +} /** Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List. - @param FormSet Pointer of the current FormSet + @param FormSet Pointer of the current FormSet + @param StorageType Storage type. + @param OpCodeData Binary data for this opcode. @return Pointer to a FORMSET_STORAGE data structure. **/ FORMSET_STORAGE * CreateStorage ( - IN FORM_BROWSER_FORMSET *FormSet + IN FORM_BROWSER_FORMSET *FormSet, + IN UINT8 StorageType, + IN UINT8 *OpCodeData ) { - FORMSET_STORAGE *Storage; + 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; + + 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; + } + + 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]; + } + } Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE)); ASSERT (Storage != NULL); Storage->Signature = FORMSET_STORAGE_SIGNATURE; - InitializeListHead (&Storage->NameValueListHead); 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; + + BrowserStorage->Initialized = FALSE; + } + + Storage->BrowserStorage = BrowserStorage; + InitializeConfigHdr (FormSet, Storage); + Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr); + Storage->SpareStrLen = 0; + return Storage; } - /** - Create ConfigHdr string for a storage. + Get Formset_storage base on the input varstoreid info. - @param FormSet Pointer of the current FormSet - @param Storage Pointer of the storage + @param FormSet Pointer of the current FormSet. + @param VarStoreId Varstore ID info. - @retval EFI_SUCCESS Initialize ConfigHdr success + @return Pointer to a FORMSET_STORAGE data structure. **/ -EFI_STATUS -InitializeConfigHdr ( +FORMSET_STORAGE * +GetFstStgFromVarId ( IN FORM_BROWSER_FORMSET *FormSet, - IN OUT FORMSET_STORAGE *Storage + IN EFI_VARSTORE_ID VarStoreId ) { - CHAR16 *Name; + FORMSET_STORAGE *FormsetStorage; + LIST_ENTRY *Link; + BOOLEAN Found; - if (Storage->Type == EFI_HII_VARSTORE_BUFFER) { - Name = Storage->Name; - } else { - Name = NULL; - } + Found = FALSE; + FormsetStorage = NULL; + // + // Find Formset Storage for this Question + // + Link = GetFirstNode (&FormSet->StorageListHead); + while (!IsNull (&FormSet->StorageListHead, Link)) { + FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link); - Storage->ConfigHdr = HiiConstructConfigHdr ( - &Storage->Guid, - Name, - FormSet->DriverHandle - ); + if (FormsetStorage->VarStoreId == VarStoreId) { + Found = TRUE; + break; + } - if (Storage->ConfigHdr == NULL) { - return EFI_NOT_FOUND; + Link = GetNextNode (&FormSet->StorageListHead, Link); } - Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr); - Storage->SpareStrLen = 0; - - return EFI_SUCCESS; + return Found ? FormsetStorage : NULL; } +/** + Get Formset_storage base on the input browser storage. + + More than one formsets may share the same browser storage, + this function just get the first formset storage which + share the browser storage. + + @param Storage browser storage info. + + @return Pointer to a FORMSET_STORAGE data structure. + + +**/ +FORMSET_STORAGE * +GetFstStgFromBrsStg ( + IN BROWSER_STORAGE *Storage + ) +{ + FORMSET_STORAGE *FormsetStorage; + LIST_ENTRY *Link; + LIST_ENTRY *FormsetLink; + FORM_BROWSER_FORMSET *FormSet; + BOOLEAN Found; + + Found = FALSE; + FormsetStorage = NULL; + + FormsetLink = GetFirstNode (&gBrowserFormSetList); + while (!IsNull (&gBrowserFormSetList, FormsetLink)) { + FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormsetLink); + FormsetLink = GetNextNode (&gBrowserFormSetList, FormsetLink); + + Link = GetFirstNode (&FormSet->StorageListHead); + while (!IsNull (&FormSet->StorageListHead, Link)) { + FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link); + Link = GetNextNode (&FormSet->StorageListHead, Link); + + if (FormsetStorage->BrowserStorage == Storage) { + Found = TRUE; + break; + } + } + + if (Found) { + break; + } + } + + return Found ? FormsetStorage : NULL; +} /** Initialize Request Element of a Question. ::= '&' | '&'