/** @file\r
Parser for IFR binary encoding.\r
\r
-Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2017, 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
Initialize Statement header members.\r
\r
@param OpCodeData Pointer of the raw OpCode data.\r
- @param FormSet Pointer of the current FormSe.\r
+ @param FormSet Pointer of the current FormSet.\r
@param Form Pointer of the current Form.\r
\r
@return The Statement.\r
\r
Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
Statement->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;\r
+ Statement->QuestionReferToBitField = FALSE;\r
\r
StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
ASSERT (Statement != NULL);\r
ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);\r
\r
- UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);\r
+ UnicodeValueToStringS (Str, sizeof (Str), 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);\r
\r
Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);\r
if (Id == 0) {\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
Question->VarStoreInfo.VarOffset,\r
Question->StorageWidth\r
);\r
+ HiiToLower(RequestElement);\r
Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
} else {\r
StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\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
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
INTN ConditionalExprCount;\r
BOOLEAN InUnknownScope;\r
UINT8 UnknownDepth;\r
+ FORMSET_DEFAULTSTORE *PreDefaultStore;\r
+ LIST_ENTRY *DefaultLink;\r
+ BOOLEAN HaveInserted;\r
+ UINT16 TotalBits;\r
+ BOOLEAN QuestionReferBitField;\r
\r
SuppressForQuestion = FALSE;\r
SuppressForOption = FALSE;\r
ConditionalExprCount = 0;\r
InUnknownScope = FALSE;\r
UnknownDepth = 0;\r
+ QuestionReferBitField = FALSE;\r
\r
//\r
// Get the number of Statements and Expressions\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
// DefaultStore\r
//\r
case EFI_IFR_DEFAULTSTORE_OP:\r
+ HaveInserted = FALSE;\r
DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
ASSERT (DefaultStore != NULL);\r
DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
\r
CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
-\r
//\r
- // Insert to DefaultStore list of this Formset\r
+ // Insert it to the DefaultStore list of this Formset with ascending order.\r
//\r
- InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
+ if (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
+ DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
+ while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r
+ PreDefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
+ DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);\r
+ if (DefaultStore->DefaultId < PreDefaultStore->DefaultId) {\r
+ InsertTailList (&PreDefaultStore->Link, &DefaultStore->Link);\r
+ HaveInserted = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (!HaveInserted) {\r
+ InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
+ }\r
break;\r
\r
//\r
CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
Value = &CurrentStatement->HiiValue;\r
\r
- switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
- case EFI_IFR_NUMERIC_SIZE_1:\r
- CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
- CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
- CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- break;\r
+ if (QuestionReferBitField) {\r
+ //\r
+ // Get the bit var store info (bit/byte offset, bit/byte offset)\r
+ //\r
+ CurrentStatement->QuestionReferToBitField = TRUE;\r
+ CurrentStatement->BitStorageWidth = CurrentStatement->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
+ CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r
+ CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r
+ TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r
+ CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r
\r
- case EFI_IFR_NUMERIC_SIZE_2:\r
- CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
- CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
- CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- break;\r
+ //\r
+ // Get the Minimum/Maximum/Step value(Note: bit field type has been stored as UINT32 type)\r
+ //\r
+ CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue;\r
+ CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue;\r
+ CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step;\r
\r
- case EFI_IFR_NUMERIC_SIZE_4:\r
- CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
- CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
- CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
- break;\r
+ //\r
+ // Update the Flag and type of Minimum/Maximum/Step according to the actual width of bit field,\r
+ // in order to make Browser handle these question with bit varstore correctly.\r
+ //\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->Flags &= EDKII_IFR_DISPLAY_BIT;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->Flags >>= 2;\r
+ switch (CurrentStatement->StorageWidth) {\r
+ case 1:\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_8;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue = (UINT8)CurrentStatement->Minimum;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue = (UINT8)CurrentStatement->Maximum;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step = (UINT8)CurrentStatement->Step;\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ break;\r
+ case 2:\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_16;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue = (UINT16)CurrentStatement->Minimum;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue = (UINT16)CurrentStatement->Maximum;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step = (UINT16)CurrentStatement->Step;\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+ break;\r
+ case 3:\r
+ case 4:\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->Flags |= EFI_IFR_TYPE_NUM_SIZE_32;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue = (UINT32)CurrentStatement->Minimum;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue = (UINT32)CurrentStatement->Maximum;\r
+ ((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step = (UINT32)CurrentStatement->Step;\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ } else {\r
+ switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+ case EFI_IFR_NUMERIC_SIZE_1:\r
+ CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
+ CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
+ CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
+ CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ break;\r
\r
- case EFI_IFR_NUMERIC_SIZE_8:\r
- CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
- CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
- CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
- CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- break;\r
+ case EFI_IFR_NUMERIC_SIZE_2:\r
+ CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
+ CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
+ CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
+ CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+ break;\r
\r
- default:\r
- break;\r
- }\r
+ case EFI_IFR_NUMERIC_SIZE_4:\r
+ CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
+ CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
+ CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
+ CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
+ break;\r
\r
+ case EFI_IFR_NUMERIC_SIZE_8:\r
+ CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
+ CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
+ CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
+ CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
\r
if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r
CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
\r
+ if (QuestionReferBitField) {\r
+ //\r
+ // Get the bit var store info (bit/byte offset, bit/byte offset)\r
+ //\r
+ CurrentStatement->QuestionReferToBitField = TRUE;\r
+ CurrentStatement->BitStorageWidth = 1;\r
+ CurrentStatement->BitVarOffset = CurrentStatement->VarStoreInfo.VarOffset;\r
+ CurrentStatement->VarStoreInfo.VarOffset = CurrentStatement->BitVarOffset / 8;\r
+ TotalBits = CurrentStatement->BitVarOffset % 8 + CurrentStatement->BitStorageWidth;\r
+ CurrentStatement->StorageWidth = (TotalBits % 8 == 0? TotalBits / 8: TotalBits / 8 + 1);\r
+ }\r
+\r
InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
\r
break;\r
//\r
// Vendor specific\r
//\r
- case EFI_IFR_GUID_OP: \r
+ case EFI_IFR_GUID_OP:\r
CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+ if (CompareGuid ((EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
+ Scope = 0;\r
+ QuestionReferBitField = TRUE;\r
+ }\r
break;\r
\r
//\r
// Scope End\r
//\r
case EFI_IFR_END_OP:\r
+ QuestionReferBitField = FALSE;\r
Status = PopScope (&ScopeOpCode);\r
if (EFI_ERROR (Status)) {\r
ResetScopeStack ();\r