/** @file\r
Parser for IFR binary encoding.\r
\r
-Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
UINT16 mStatementIndex;\r
UINT16 mExpressionOpCodeIndex;\r
EFI_QUESTION_ID mUsedQuestionId;\r
-BOOLEAN mInScopeSubtitle;\r
extern LIST_ENTRY gBrowserStorageList;\r
/**\r
Initialize Statement header members.\r
InitializeListHead (&Statement->OptionListHead);\r
InitializeListHead (&Statement->InconsistentListHead);\r
InitializeListHead (&Statement->NoSubmitListHead);\r
+ InitializeListHead (&Statement->WarningListHead);\r
\r
Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
\r
CopyMem (Statement->Expression->Expression, GetConditionalExpressionList(ExpressStatement), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));\r
}\r
\r
- Statement->InSubtitle = mInScopeSubtitle;\r
-\r
//\r
// Insert this Statement into current Form\r
//\r
Allocate a FORM_EXPRESSION node.\r
\r
@param Form The Form associated with this Expression\r
+ @param OpCode The binary opcode data.\r
\r
@return Pointer to a FORM_EXPRESSION data structure.\r
\r
**/\r
FORM_EXPRESSION *\r
CreateExpression (\r
- IN OUT FORM_BROWSER_FORM *Form\r
+ IN OUT FORM_BROWSER_FORM *Form,\r
+ IN UINT8 *OpCode\r
)\r
{\r
FORM_EXPRESSION *Expression;\r
ASSERT (Expression != NULL);\r
Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r
InitializeListHead (&Expression->OpCodeListHead);\r
+ Expression->OpCode = (EFI_IFR_OP_HEADER *) OpCode;\r
\r
return Expression;\r
}\r
EFI_STATUS\r
InitializeConfigHdr (\r
IN FORM_BROWSER_FORMSET *FormSet,\r
- IN OUT BROWSER_STORAGE *Storage\r
+ IN OUT FORMSET_STORAGE *Storage\r
)\r
{\r
CHAR16 *Name;\r
\r
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
- Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
- Name = Storage->Name;\r
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER || \r
+ Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ Name = Storage->BrowserStorage->Name;\r
} else {\r
Name = NULL;\r
}\r
\r
Storage->ConfigHdr = HiiConstructConfigHdr (\r
- &Storage->Guid,\r
+ &Storage->BrowserStorage->Guid,\r
Name,\r
FormSet->DriverHandle\r
);\r
/**\r
Find the global storage link base on the input storate type, name and guid.\r
\r
+ For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,\r
+ same guid + name = same storage\r
+\r
+ For EFI_HII_VARSTORE_NAME_VALUE:\r
+ same guid + HiiHandle = same storage\r
+\r
+ For EFI_HII_VARSTORE_BUFFER:\r
+ same guid + name + HiiHandle = same storage\r
+\r
@param StorageType Storage type.\r
@param StorageGuid Storage guid.\r
@param StorageName Storage Name.\r
+ @param HiiHandle HiiHandle for this varstore.\r
\r
@return Pointer to a GLOBAL_STORAGE data structure.\r
\r
FindStorageInList (\r
IN UINT8 StorageType,\r
IN EFI_GUID *StorageGuid,\r
- IN CHAR16 *StorageName\r
+ IN CHAR16 *StorageName,\r
+ IN EFI_HII_HANDLE HiiHandle\r
)\r
{\r
LIST_ENTRY *Link;\r
Link = GetFirstNode (&gBrowserStorageList);\r
while (!IsNull (&gBrowserStorageList, Link)) {\r
BrowserStorage = BROWSER_STORAGE_FROM_LINK (Link);\r
+ Link = GetNextNode (&gBrowserStorageList, Link);\r
\r
if ((BrowserStorage->Type == StorageType) && CompareGuid (&BrowserStorage->Guid, StorageGuid)) {\r
if (StorageType == EFI_HII_VARSTORE_NAME_VALUE) {\r
- return BrowserStorage;\r
+ if (BrowserStorage->HiiHandle == HiiHandle) {\r
+ return BrowserStorage;\r
+ }\r
+\r
+ continue;\r
}\r
\r
+ ASSERT (StorageName != NULL);\r
if (StrCmp (BrowserStorage->Name, StorageName) == 0) {\r
- return BrowserStorage;\r
+ if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE || StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+ return BrowserStorage;\r
+ } else if (StorageType == EFI_HII_VARSTORE_BUFFER && BrowserStorage->HiiHandle == HiiHandle) {\r
+ return BrowserStorage;\r
+ }\r
}\r
}\r
-\r
- //\r
- // Get Next Storage.\r
- //\r
- Link = GetNextNode (&gBrowserStorageList, Link);\r
}\r
\r
return NULL;\r
}\r
}\r
\r
+/**\r
+ Check whether exist device path info in the ConfigHdr string.\r
+\r
+ @param String UEFI configuration string\r
+\r
+ @retval TRUE Device Path exist.\r
+ @retval FALSE Not exist device path info.\r
+\r
+**/\r
+BOOLEAN\r
+IsDevicePathExist (\r
+ IN EFI_STRING String\r
+ )\r
+{\r
+ UINTN Length;\r
+\r
+ for (; (*String != 0 && StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0); String++);\r
+ if (*String == 0) {\r
+ return FALSE;\r
+ }\r
+\r
+ String += StrLen (L"PATH=");\r
+ if (*String == 0) {\r
+ return FALSE;\r
+ }\r
+\r
+ for (Length = 0; *String != 0 && *String != L'&'; String++, Length++);\r
+ if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
/**\r
Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
\r
Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
\r
- BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString);\r
+ BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString, FormSet->HiiHandle);\r
if (BrowserStorage == NULL) {\r
BrowserStorage = AllocateZeroPool (sizeof (BROWSER_STORAGE));\r
ASSERT (BrowserStorage != NULL);\r
BrowserStorage->Name = UnicodeString;\r
}\r
\r
- InitializeConfigHdr (FormSet, BrowserStorage);\r
+ BrowserStorage->HiiHandle = FormSet->HiiHandle;\r
+\r
+ BrowserStorage->Initialized = FALSE;\r
}\r
- //\r
- // Add count because one formset storage use this global storage.\r
- //\r
- BrowserStorage->ReferenceCount++;\r
\r
Storage->BrowserStorage = BrowserStorage;\r
- Storage->ConfigRequest = AllocateCopyPool (StrSize (BrowserStorage->ConfigHdr), BrowserStorage->ConfigHdr);\r
+ InitializeConfigHdr (FormSet, Storage);\r
+ Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);\r
Storage->SpareStrLen = 0;\r
\r
return Storage;\r
}\r
\r
+/**\r
+ Get Formset_storage base on the input varstoreid info.\r
+\r
+ @param FormSet Pointer of the current FormSet.\r
+ @param VarStoreId Varstore ID info.\r
+\r
+ @return Pointer to a FORMSET_STORAGE data structure.\r
+\r
+**/\r
+FORMSET_STORAGE *\r
+GetFstStgFromVarId (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN EFI_VARSTORE_ID VarStoreId\r
+ )\r
+{\r
+ FORMSET_STORAGE *FormsetStorage;\r
+ LIST_ENTRY *Link;\r
+ BOOLEAN Found;\r
+\r
+ Found = FALSE;\r
+ FormsetStorage = NULL;\r
+ //\r
+ // Find Formset Storage for this Question\r
+ //\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+\r
+ if (FormsetStorage->VarStoreId == VarStoreId) {\r
+ Found = TRUE;\r
+ break;\r
+ }\r
+\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+ }\r
+\r
+ return Found ? FormsetStorage : NULL;\r
+}\r
+\r
+/**\r
+ Get Formset_storage base on the input browser storage.\r
+\r
+ More than one formsets may share the same browser storage,\r
+ this function just get the first formset storage which\r
+ share the browser storage.\r
+\r
+ @param Storage browser storage info.\r
+\r
+ @return Pointer to a FORMSET_STORAGE data structure.\r
+ \r
+\r
+**/\r
+FORMSET_STORAGE *\r
+GetFstStgFromBrsStg (\r
+ IN BROWSER_STORAGE *Storage\r
+ )\r
+{\r
+ FORMSET_STORAGE *FormsetStorage;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *FormsetLink;\r
+ FORM_BROWSER_FORMSET *FormSet;\r
+ BOOLEAN Found;\r
+\r
+ Found = FALSE;\r
+ FormsetStorage = NULL;\r
+\r
+ FormsetLink = GetFirstNode (&gBrowserFormSetList);\r
+ while (!IsNull (&gBrowserFormSetList, FormsetLink)) {\r
+ FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormsetLink);\r
+ FormsetLink = GetNextNode (&gBrowserFormSetList, FormsetLink);\r
+\r
+ Link = GetFirstNode (&FormSet->StorageListHead);\r
+ while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+ FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+ Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+ if (FormsetStorage->BrowserStorage == Storage) {\r
+ Found = TRUE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (Found) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ return Found ? FormsetStorage : NULL;\r
+}\r
+\r
/**\r
Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>\r
\r
LIST_ENTRY *Link;\r
BOOLEAN Find;\r
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
+ UINTN MaxLen;\r
\r
Storage = Question->Storage;\r
if (Storage == NULL) {\r
StrLen = UnicodeSPrint (\r
RequestElement,\r
30 * sizeof (CHAR16),\r
- L"&OFFSET=%x&WIDTH=%x",\r
+ L"&OFFSET=%04x&WIDTH=%04x",\r
Question->VarStoreInfo.VarOffset,\r
Question->StorageWidth\r
);\r
//\r
// Find Formset Storage for this Question\r
//\r
- FormsetStorage = NULL;\r
- Link = GetFirstNode (&FormSet->StorageListHead);\r
- while (!IsNull (&FormSet->StorageListHead, Link)) {\r
- FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
-\r
- if (FormsetStorage->VarStoreId == Question->VarStoreId) {\r
- break;\r
- }\r
-\r
- Link = GetNextNode (&FormSet->StorageListHead, Link);\r
- }\r
+ FormsetStorage = GetFstStgFromVarId(FormSet, Question->VarStoreId);\r
ASSERT (FormsetStorage != NULL);\r
+ StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);\r
+ MaxLen = StringSize / sizeof (CHAR16) + FormsetStorage->SpareStrLen;\r
\r
//\r
// Append <RequestElement> to <ConfigRequest>\r
//\r
// Old String buffer is not sufficient for RequestElement, allocate a new one\r
//\r
- StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);\r
- NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+ MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;\r
+ NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
ASSERT (NewStr != NULL);\r
if (FormsetStorage->ConfigRequest != NULL) {\r
CopyMem (NewStr, FormsetStorage->ConfigRequest, StringSize);\r
FormsetStorage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
}\r
\r
- StrCat (FormsetStorage->ConfigRequest, RequestElement);\r
+ StrCatS (FormsetStorage->ConfigRequest, MaxLen, RequestElement);\r
FormsetStorage->ElementCount++;\r
FormsetStorage->SpareStrLen -= StrLen;\r
\r
while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
\r
- if (ConfigInfo != NULL && ConfigInfo->Storage == Storage) {\r
+ if (ConfigInfo != NULL && ConfigInfo->Storage == FormsetStorage->BrowserStorage) {\r
Find = TRUE;\r
break;\r
}\r
ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));\r
ASSERT (ConfigInfo != NULL);\r
ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;\r
- ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);\r
+ ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (FormsetStorage->ConfigHdr), FormsetStorage->ConfigHdr);\r
+ ASSERT (ConfigInfo->ConfigRequest != NULL);\r
ConfigInfo->SpareStrLen = 0;\r
- ConfigInfo->Storage = Storage;\r
+ ConfigInfo->Storage = FormsetStorage->BrowserStorage;\r
InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);\r
}\r
+ StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);\r
+ MaxLen = StringSize / sizeof (CHAR16) + ConfigInfo->SpareStrLen;\r
\r
//\r
// Append <RequestElement> to <ConfigRequest>\r
//\r
// Old String buffer is not sufficient for RequestElement, allocate a new one\r
//\r
- StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);\r
- NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+ MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;\r
+ NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
ASSERT (NewStr != NULL);\r
if (ConfigInfo->ConfigRequest != NULL) {\r
CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);\r
ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
}\r
\r
- StrCat (ConfigInfo->ConfigRequest, RequestElement);\r
+ StrCatS (ConfigInfo->ConfigRequest, MaxLen, RequestElement);\r
ConfigInfo->ElementCount++;\r
ConfigInfo->SpareStrLen -= StrLen;\r
return EFI_SUCCESS;\r
FreePool (Storage->ConfigRequest);\r
}\r
\r
- //\r
- // Minus the reference to the global storage.\r
- //\r
- ASSERT (Storage->BrowserStorage->ReferenceCount > 0);\r
- Storage->BrowserStorage->ReferenceCount--; \r
-\r
FreePool (Storage);\r
}\r
\r
Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
RemoveEntryList (&Default->Link);\r
\r
+ if (Default->Value.Buffer != NULL) {\r
+ FreePool (Default->Value.Buffer);\r
+ }\r
FreePool (Default);\r
}\r
\r
DestroyExpression (Expression);\r
}\r
\r
+ //\r
+ // Free WarningIf List\r
+ //\r
+ while (!IsListEmpty (&Statement->WarningListHead)) {\r
+ Link = GetFirstNode (&Statement->WarningListHead);\r
+ Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
+ RemoveEntryList (&Expression->Link);\r
+\r
+ DestroyExpression (Expression);\r
+ }\r
+\r
if (Statement->Expression != NULL) {\r
FreePool (Statement->Expression);\r
}\r
FreePool (Form->SuppressExpression);\r
}\r
\r
+ UiFreeMenuList (&Form->FormViewListHead);\r
+\r
//\r
// Free this Form\r
//\r
(Operand == EFI_IFR_TO_UPPER_OP) ||\r
(Operand == EFI_IFR_MAP_OP) ||\r
(Operand == EFI_IFR_VERSION_OP) ||\r
- (Operand == EFI_IFR_SECURITY_OP)) {\r
+ (Operand == EFI_IFR_SECURITY_OP) ||\r
+ (Operand == EFI_IFR_MATCH2_OP)) {\r
return TRUE;\r
} else {\r
return FALSE;\r
}\r
}\r
\r
+/**\r
+ Tell whether this Operand is an Statement OpCode.\r
+\r
+ @param Operand Operand of an IFR OpCode.\r
+\r
+ @retval TRUE This is an Statement OpCode.\r
+ @retval FALSE Not an Statement OpCode.\r
+\r
+**/\r
+BOOLEAN\r
+IsStatementOpCode (\r
+ IN UINT8 Operand\r
+ )\r
+{\r
+ if ((Operand == EFI_IFR_SUBTITLE_OP) ||\r
+ (Operand == EFI_IFR_TEXT_OP) ||\r
+ (Operand == EFI_IFR_RESET_BUTTON_OP) ||\r
+ (Operand == EFI_IFR_REF_OP) ||\r
+ (Operand == EFI_IFR_ACTION_OP) ||\r
+ (Operand == EFI_IFR_NUMERIC_OP) ||\r
+ (Operand == EFI_IFR_ORDERED_LIST_OP) ||\r
+ (Operand == EFI_IFR_CHECKBOX_OP) ||\r
+ (Operand == EFI_IFR_STRING_OP) ||\r
+ (Operand == EFI_IFR_PASSWORD_OP) ||\r
+ (Operand == EFI_IFR_DATE_OP) ||\r
+ (Operand == EFI_IFR_TIME_OP) ||\r
+ (Operand == EFI_IFR_GUID_OP) ||\r
+ (Operand == EFI_IFR_ONE_OF_OP)) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Tell whether this Operand is an known OpCode.\r
+\r
+ @param Operand Operand of an IFR OpCode.\r
+\r
+ @retval TRUE This is an Statement OpCode.\r
+ @retval FALSE Not an Statement OpCode.\r
+\r
+**/\r
+BOOLEAN\r
+IsUnKnownOpCode (\r
+ IN UINT8 Operand\r
+ )\r
+{\r
+ return Operand > EFI_IFR_MATCH2_OP ? TRUE : FALSE;\r
+}\r
\r
/**\r
Calculate number of Statemens(Questions) and Expression OpCodes.\r
EFI_STATUS Status;\r
FORM_BROWSER_FORM *CurrentForm;\r
FORM_BROWSER_STATEMENT *CurrentStatement;\r
+ FORM_BROWSER_STATEMENT *ParentStatement;\r
EXPRESSION_OPCODE *ExpressionOpCode;\r
FORM_EXPRESSION *CurrentExpression;\r
UINT8 Operand;\r
EFI_VARSTORE_ID TempVarstoreId;\r
BOOLEAN InScopeDisable;\r
INTN ConditionalExprCount;\r
+ BOOLEAN InUnknownScope;\r
+ UINT8 UnknownDepth;\r
\r
- mInScopeSubtitle = FALSE;\r
SuppressForQuestion = FALSE;\r
SuppressForOption = FALSE;\r
InScopeDisable = FALSE;\r
MapExpressionList = NULL;\r
TempVarstoreId = 0;\r
ConditionalExprCount = 0;\r
+ InUnknownScope = FALSE;\r
+ UnknownDepth = 0;\r
\r
//\r
// Get the number of Statements and Expressions\r
\r
InitializeListHead (&FormSet->StatementListOSF);\r
InitializeListHead (&FormSet->StorageListHead);\r
+ InitializeListHead (&FormSet->SaveFailStorageListHead);\r
InitializeListHead (&FormSet->DefaultStoreListHead);\r
InitializeListHead (&FormSet->FormListHead);\r
InitializeListHead (&FormSet->ExpressionListHead);\r
\r
CurrentForm = NULL;\r
CurrentStatement = NULL;\r
+ ParentStatement = NULL;\r
\r
ResetScopeStack ();\r
\r
Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
\r
+ if (InUnknownScope) {\r
+ if (Operand == EFI_IFR_END_OP) {\r
+ UnknownDepth --;\r
+\r
+ if (UnknownDepth == 0) {\r
+ InUnknownScope = FALSE;\r
+ }\r
+ } else {\r
+ if (Scope != 0) {\r
+ UnknownDepth ++;\r
+ }\r
+ }\r
+\r
+ continue;\r
+ }\r
+\r
+ if (IsUnKnownOpCode(Operand)) {\r
+ if (Scope != 0) {\r
+ InUnknownScope = TRUE;\r
+ UnknownDepth ++;\r
+ }\r
+\r
+ continue;\r
+ }\r
+\r
//\r
// If scope bit set, push onto scope stack\r
//\r
break;\r
\r
case EFI_IFR_THIS_OP:\r
- ASSERT (CurrentStatement != NULL);\r
- ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r
+ ASSERT (ParentStatement != NULL);\r
+ ExpressionOpCode->QuestionId = ParentStatement->QuestionId;\r
break;\r
\r
case EFI_IFR_SECURITY_OP:\r
CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));\r
break;\r
\r
+ case EFI_IFR_MATCH2_OP:\r
+ CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_MATCH2 *) OpCodeData)->SyntaxType, sizeof (EFI_GUID));\r
+ break;\r
+\r
case EFI_IFR_GET_OP:\r
case EFI_IFR_SET_OP:\r
CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));\r
// Create sub expression nested in MAP opcode\r
//\r
if (CurrentExpression == NULL && MapScopeDepth > 0) {\r
- CurrentExpression = CreateExpression (CurrentForm);\r
+ CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
ASSERT (MapExpressionList != NULL);\r
InsertTailList (MapExpressionList, &CurrentExpression->Link);\r
if (Scope == 0) {\r
return Status;\r
}\r
\r
- if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OpCodeDisabled = CurrentExpression->Result.Value.b;\r
+ OpCodeDisabled = IsTrue(&CurrentExpression->Result);\r
}\r
\r
CurrentExpression = NULL;\r
\r
CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
+ FormSet->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;//save the opcode address of formset\r
\r
if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
//\r
InitializeListHead (&CurrentForm->ExpressionListHead);\r
InitializeListHead (&CurrentForm->StatementListHead);\r
InitializeListHead (&CurrentForm->ConfigRequestHead);\r
+ InitializeListHead (&CurrentForm->FormViewListHead);\r
\r
CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
InitializeListHead (&CurrentForm->ExpressionListHead);\r
InitializeListHead (&CurrentForm->StatementListHead);\r
InitializeListHead (&CurrentForm->ConfigRequestHead);\r
+ InitializeListHead (&CurrentForm->FormViewListHead);\r
+\r
CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
\r
MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
// Create a EFI variable Storage for this FormSet\r
//\r
if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
+ //\r
+ // Create efi varstore with format follow UEFI spec before 2.3.1.\r
+ //\r
Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);\r
} else {\r
+ //\r
+ // Create efi varstore with format follow UEFI spec 2.3.1 and later.\r
+ //\r
Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);\r
}\r
CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
\r
CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
- if (Scope != 0) {\r
- mInScopeSubtitle = TRUE;\r
- }\r
break;\r
\r
case EFI_IFR_TEXT_OP:\r
\r
CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
- if (OpCodeLength > OFFSET_OF (EFI_IFR_DEFAULT, Value)) {\r
+ if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
+ CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *) OpCodeData)->Value);\r
+ ASSERT (CurrentDefault->Value.Buffer != NULL);\r
+ } else {\r
CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
ExtendValueToU64 (&CurrentDefault->Value);\r
}\r
//\r
// Insert to Default Value list of current Question\r
//\r
- InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
+ InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);\r
\r
if (Scope != 0) {\r
InScopeDefault = TRUE;\r
// Option\r
//\r
case EFI_IFR_ONE_OF_OPTION_OP:\r
+ ASSERT (ParentStatement != NULL);\r
+ if (ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP && ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) != 0)) {\r
+ //\r
+ // It's keep the default value for ordered list opcode.\r
+ //\r
+ CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
+ ASSERT (CurrentDefault != NULL);\r
+ CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
+\r
+ CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;\r
+ if ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {\r
+ CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ } else {\r
+ CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ }\r
+\r
+ CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
+ CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value);\r
+ ASSERT (CurrentDefault->Value.Buffer != NULL);\r
+\r
+ //\r
+ // Insert to Default Value list of current Question\r
+ //\r
+ InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);\r
+ break;\r
+ }\r
+\r
//\r
// EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
// It create a selection for use in current Question.\r
//\r
// Insert to Option list of current Question\r
//\r
- InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
-\r
+ InsertTailList (&ParentStatement->OptionListHead, &CurrentOption->Link);\r
//\r
// Now we know the Storage width of nested Ordered List\r
//\r
- ASSERT (CurrentStatement != NULL);\r
- if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {\r
+ if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (ParentStatement->BufferValue == NULL)) {\r
Width = 1;\r
switch (CurrentOption->Value.Type) {\r
case EFI_IFR_TYPE_NUM_SIZE_8:\r
break;\r
}\r
\r
- CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r
- CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
- CurrentStatement->ValueType = CurrentOption->Value.Type;\r
- if (CurrentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
- CurrentStatement->HiiValue.Buffer = CurrentStatement->BufferValue;\r
- CurrentStatement->HiiValue.BufferLen = CurrentStatement->StorageWidth;\r
+ ParentStatement->StorageWidth = (UINT16) (ParentStatement->MaxContainers * Width);\r
+ ParentStatement->BufferValue = AllocateZeroPool (ParentStatement->StorageWidth);\r
+ ParentStatement->ValueType = CurrentOption->Value.Type;\r
+ if (ParentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
+ ParentStatement->HiiValue.Buffer = ParentStatement->BufferValue;\r
+ ParentStatement->HiiValue.BufferLen = ParentStatement->StorageWidth;\r
}\r
\r
- InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
+ InitializeRequestElement (FormSet, ParentStatement, CurrentForm);\r
}\r
break;\r
\r
//\r
// Create an Expression node\r
//\r
- CurrentExpression = CreateExpression (CurrentForm);\r
+ CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
\r
if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
- InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
+ InsertTailList (&ParentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
} else {\r
CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
- InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
+ InsertTailList (&ParentStatement->InconsistentListHead, &CurrentExpression->Link);\r
}\r
\r
//\r
}\r
break;\r
\r
+ case EFI_IFR_WARNING_IF_OP:\r
+ //\r
+ // Create an Expression node\r
+ //\r
+ CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
+ CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));\r
+ CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;\r
+ CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;\r
+ InsertTailList (&ParentStatement->WarningListHead, &CurrentExpression->Link);\r
+\r
+ //\r
+ // Take a look at next OpCode to see whether current expression consists\r
+ // of single OpCode\r
+ //\r
+ if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
+ SingleOpCodeExpression = TRUE;\r
+ }\r
+ break;\r
+\r
case EFI_IFR_SUPPRESS_IF_OP:\r
//\r
// Question and Option will appear in scope of this OpCode\r
//\r
- CurrentExpression = CreateExpression (CurrentForm);\r
+ CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
\r
if (CurrentForm == NULL) {\r
//\r
// Questions will appear in scope of this OpCode\r
//\r
- CurrentExpression = CreateExpression (CurrentForm);\r
+ CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
PushConditionalExpression(CurrentExpression, ExpressStatement);\r
// Expression\r
//\r
case EFI_IFR_VALUE_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
+ CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
\r
// If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
// file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
//\r
- ASSERT (CurrentStatement != NULL);\r
- CurrentStatement->ValueExpression = CurrentExpression;\r
+ ASSERT (ParentStatement != NULL);\r
+ ParentStatement->ValueExpression = CurrentExpression;\r
}\r
\r
//\r
break;\r
\r
case EFI_IFR_RULE_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
+ CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
\r
CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
break;\r
\r
case EFI_IFR_READ_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
+ CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
CurrentExpression->Type = EFI_HII_EXPRESSION_READ;\r
InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
\r
// If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
// file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
//\r
- ASSERT (CurrentStatement != NULL);\r
- CurrentStatement->ReadExpression = CurrentExpression;\r
+ ASSERT (ParentStatement != NULL);\r
+ ParentStatement->ReadExpression = CurrentExpression;\r
\r
//\r
// Take a look at next OpCode to see whether current expression consists\r
break;\r
\r
case EFI_IFR_WRITE_OP:\r
- CurrentExpression = CreateExpression (CurrentForm);\r
+ CurrentExpression = CreateExpression (CurrentForm, OpCodeData);\r
CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;\r
InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
\r
// If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
// file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
//\r
- ASSERT (CurrentStatement != NULL);\r
- CurrentStatement->WriteExpression = CurrentExpression;\r
+ ASSERT (ParentStatement != NULL);\r
+ ParentStatement->WriteExpression = CurrentExpression;\r
\r
//\r
// Take a look at next OpCode to see whether current expression consists\r
break;\r
\r
case EFI_IFR_ONE_OF_OPTION_OP:\r
+ ASSERT (CurrentOption != NULL);\r
ImageId = &CurrentOption->ImageId;\r
break;\r
\r
// If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
// file is wrongly generated by tools such as VFR Compiler.\r
//\r
- ASSERT (CurrentStatement != NULL);\r
- ImageId = &CurrentStatement->ImageId;\r
+ ASSERT (ParentStatement != NULL);\r
+ ImageId = &ParentStatement->ImageId;\r
break;\r
}\r
\r
// Refresh\r
//\r
case EFI_IFR_REFRESH_OP:\r
- ASSERT (CurrentStatement != NULL);\r
- CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
+ ASSERT (ParentStatement != NULL);\r
+ ParentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
break;\r
\r
//\r
// Refresh guid.\r
//\r
case EFI_IFR_REFRESH_ID_OP:\r
- ASSERT (CurrentStatement != NULL);\r
- CopyMem (&CurrentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
+ //\r
+ // Get ScopeOpcode from top of stack\r
+ //\r
+ PopScope (&ScopeOpCode);\r
+ PushScope (ScopeOpCode);\r
+\r
+ switch (ScopeOpCode) {\r
+ case EFI_IFR_FORM_OP:\r
+ case EFI_IFR_FORM_MAP_OP:\r
+ ASSERT (CurrentForm != NULL);\r
+ CopyMem (&CurrentForm->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
+ break;\r
+\r
+ default:\r
+ ASSERT (ParentStatement != NULL);\r
+ CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
+ break;\r
+ }\r
break;\r
\r
//\r
break;\r
\r
default:\r
- ASSERT (CurrentStatement != NULL);\r
- CurrentStatement->Locked = TRUE;\r
+ ASSERT (ParentStatement != NULL);\r
+ ParentStatement->Locked = TRUE;\r
} \r
break;\r
\r
ResetScopeStack ();\r
return Status;\r
}\r
+ \r
+ //\r
+ // Parent statement end tag found, update ParentStatement info.\r
+ //\r
+ if (IsStatementOpCode(ScopeOpCode) && (ParentStatement != NULL) && (ParentStatement->Operand == ScopeOpCode)) {\r
+ ParentStatement = ParentStatement->ParentStatement;\r
+ }\r
\r
switch (ScopeOpCode) {\r
case EFI_IFR_FORM_SET_OP:\r
CurrentOption = NULL;\r
break;\r
\r
- case EFI_IFR_SUBTITLE_OP:\r
- mInScopeSubtitle = FALSE;\r
- break;\r
-\r
case EFI_IFR_NO_SUBMIT_IF_OP:\r
case EFI_IFR_INCONSISTENT_IF_OP:\r
+ case EFI_IFR_WARNING_IF_OP:\r
//\r
// Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
//\r
return Status;\r
}\r
\r
- if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
+ OpCodeDisabled = IsTrue (&CurrentExpression->Result);\r
\r
- OpCodeDisabled = CurrentExpression->Result.Value.b;\r
//\r
// DisableIf Expression is only used once and not queued, free it\r
//\r
default:\r
break;\r
}\r
+\r
+ if (IsStatementOpCode(Operand)) {\r
+ CurrentStatement->ParentStatement = ParentStatement;\r
+ if (Scope != 0) {\r
+ //\r
+ // Scope != 0, other statements or options may nest in this statement.\r
+ // Update the ParentStatement info.\r
+ //\r
+ ParentStatement = CurrentStatement;\r
+ }\r
+ }\r
}\r
\r
return EFI_SUCCESS;\r