/** @file\r
Utility functions for expression evaluation.\r
\r
-Copyright (c) 2007 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2007 - 2012, 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
http://opensource.org/licenses/bsd-license.php\r
EFI_HII_VALUE *mExpressionEvaluationStack = NULL;\r
EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;\r
EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;\r
+UINTN mExpressionEvaluationStackOffset = 0;\r
+\r
+EFI_HII_VALUE *mCurrentExpressionStack = NULL;\r
+EFI_HII_VALUE *mCurrentExpressionEnd = NULL;\r
+EFI_HII_VALUE *mCurrentExpressionPointer = NULL;\r
+\r
+EFI_HII_VALUE *mMapExpressionListStack = NULL;\r
+EFI_HII_VALUE *mMapExpressionListEnd = NULL;\r
+EFI_HII_VALUE *mMapExpressionListPointer = NULL;\r
\r
//\r
// Unicode collation protocol interface\r
// Push the item onto the stack\r
//\r
CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));\r
+ if (Data->Type == EFI_IFR_TYPE_BUFFER) {\r
+ (*StackPtr)->Buffer = AllocateCopyPool(Data->BufferLen, Data->Buffer);\r
+ ASSERT ((*StackPtr)->Buffer != NULL);\r
+ }\r
+ \r
*StackPtr = *StackPtr + 1;\r
\r
return EFI_SUCCESS;\r
/**\r
Pop an element from the stack.\r
\r
- @param Stack On input: old stack; On output: new stack\r
- @param StackPtr On input: old stack pointer; On output: new stack\r
- pointer\r
- @param StackEnd On input: old stack end; On output: new stack end\r
+ @param Stack On input: old stack\r
+ @param StackPtr On input: old stack pointer; On output: new stack pointer\r
@param Data Data to pop.\r
\r
@retval EFI_SUCCESS The value was popped onto the stack.\r
**/\r
EFI_STATUS\r
PopStack (\r
- IN OUT EFI_HII_VALUE **Stack,\r
+ IN EFI_HII_VALUE *Stack,\r
IN OUT EFI_HII_VALUE **StackPtr,\r
- IN OUT EFI_HII_VALUE **StackEnd,\r
OUT EFI_HII_VALUE *Data\r
)\r
{\r
//\r
// Check for a stack underflow condition\r
//\r
- if (*StackPtr == *Stack) {\r
+ if (*StackPtr == Stack) {\r
return EFI_ACCESS_DENIED;\r
}\r
\r
}\r
\r
\r
+/**\r
+ Reset stack pointer to begin of the stack.\r
+\r
+**/\r
+VOID\r
+ResetCurrentExpressionStack (\r
+ VOID\r
+ )\r
+{\r
+ mCurrentExpressionPointer = mCurrentExpressionStack;\r
+}\r
+\r
+\r
+/**\r
+ Push current expression onto the Stack\r
+\r
+ @param Pointer Pointer to current expression.\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushCurrentExpression (\r
+ IN VOID *Pointer\r
+ )\r
+{\r
+ EFI_HII_VALUE Data;\r
+\r
+ Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ Data.Value.u64 = (UINT64) (UINTN) Pointer;\r
+\r
+ return PushStack (\r
+ &mCurrentExpressionStack,\r
+ &mCurrentExpressionPointer,\r
+ &mCurrentExpressionEnd,\r
+ &Data\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ Pop current expression from the Stack\r
+\r
+ @param Pointer Pointer to current expression to be pop.\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopCurrentExpression (\r
+ OUT VOID **Pointer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_VALUE Data;\r
+\r
+ Status = PopStack (\r
+ mCurrentExpressionStack,\r
+ &mCurrentExpressionPointer,\r
+ &Data\r
+ );\r
+\r
+ *Pointer = (VOID *) (UINTN) Data.Value.u64;\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Reset stack pointer to begin of the stack.\r
+\r
+**/\r
+VOID\r
+ResetMapExpressionListStack (\r
+ VOID\r
+ )\r
+{\r
+ mMapExpressionListPointer = mMapExpressionListStack;\r
+}\r
+\r
+\r
+/**\r
+ Push the list of map expression onto the Stack\r
+\r
+ @param Pointer Pointer to the list of map expression to be pushed.\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushMapExpressionList (\r
+ IN VOID *Pointer\r
+ )\r
+{\r
+ EFI_HII_VALUE Data;\r
+\r
+ Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ Data.Value.u64 = (UINT64) (UINTN) Pointer;\r
+\r
+ return PushStack (\r
+ &mMapExpressionListStack,\r
+ &mMapExpressionListPointer,\r
+ &mMapExpressionListEnd,\r
+ &Data\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ Pop the list of map expression from the Stack\r
+\r
+ @param Pointer Pointer to the list of map expression to be pop.\r
+\r
+ @retval EFI_SUCCESS The value was pushed onto the stack.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopMapExpressionList (\r
+ OUT VOID **Pointer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_VALUE Data;\r
+\r
+ Status = PopStack (\r
+ mMapExpressionListStack,\r
+ &mMapExpressionListPointer,\r
+ &Data\r
+ );\r
+\r
+ *Pointer = (VOID *) (UINTN) Data.Value.u64;\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
Reset stack pointer to begin of the stack.\r
\r
EFI_HII_VALUE Data;\r
\r
Status = PopStack (\r
- &mOpCodeScopeStack,\r
+ mOpCodeScopeStack,\r
&mOpCodeScopeStackPointer,\r
- &mOpCodeScopeStackEnd,\r
&Data\r
);\r
\r
}\r
\r
\r
-/**\r
- Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetExpressionStack (\r
- VOID\r
- )\r
-{\r
- mExpressionEvaluationStackPointer = mExpressionEvaluationStack;\r
-}\r
-\r
-\r
/**\r
Push an Expression value onto the Stack\r
\r
)\r
{\r
return PopStack (\r
- &mExpressionEvaluationStack,\r
+ mExpressionEvaluationStack + mExpressionEvaluationStackOffset,\r
&mExpressionEvaluationStackPointer,\r
- &mExpressionEvaluationStackEnd,\r
Value\r
);\r
}\r
\r
+/**\r
+ Get current stack offset from stack start.\r
+\r
+ @return Stack offset to stack start.\r
+**/\r
+UINTN\r
+SaveExpressionEvaluationStackOffset (\r
+ )\r
+{\r
+ UINTN TempStackOffset;\r
+ TempStackOffset = mExpressionEvaluationStackOffset;\r
+ mExpressionEvaluationStackOffset = mExpressionEvaluationStackPointer - mExpressionEvaluationStack;\r
+ return TempStackOffset;\r
+}\r
+\r
+/**\r
+ Restore stack offset based on input stack offset\r
+\r
+ @param StackOffset Offset to stack start.\r
+\r
+**/\r
+VOID\r
+RestoreExpressionEvaluationStackOffset (\r
+ UINTN StackOffset\r
+ )\r
+{\r
+ mExpressionEvaluationStackOffset = StackOffset;\r
+}\r
\r
/**\r
Get Form given its FormId.\r
LIST_ENTRY *Link;\r
FORM_BROWSER_STATEMENT *Question;\r
\r
- if (QuestionId == 0) {\r
+ if (QuestionId == 0 || Form == NULL) {\r
//\r
// The value of zero is reserved\r
//\r
CHAR16 *String;\r
CHAR16 *PrintFormat;\r
CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];\r
+ UINT8 *TmpBuf;\r
UINTN BufferSize;\r
\r
Status = PopExpression (&Value);\r
case EFI_IFR_TYPE_BOOLEAN:\r
String = (Value.Value.b) ? L"True" : L"False";\r
break;\r
-\r
+ \r
+ case EFI_IFR_TYPE_BUFFER:\r
+ //\r
+ // + 3 is base on the unicode format, the length may be odd number, \r
+ // so need 1 byte to align, also need 2 bytes for L'\0'.\r
+ //\r
+ TmpBuf = AllocateZeroPool (Value.BufferLen + 3);\r
+ ASSERT (TmpBuf != NULL);\r
+ if (Format == EFI_IFR_STRING_ASCII) {\r
+ CopyMem (TmpBuf, Value.Buffer, Value.BufferLen);\r
+ PrintFormat = L"%a"; \r
+ } else {\r
+ // Format == EFI_IFR_STRING_UNICODE\r
+ CopyMem (TmpBuf, Value.Buffer, Value.BufferLen * sizeof (CHAR16));\r
+ PrintFormat = L"%s"; \r
+ }\r
+ UnicodeSPrint (Buffer, MAXIMUM_VALUE_CHARACTERS, PrintFormat, Value.Buffer); \r
+ String = Buffer; \r
+ FreePool (TmpBuf);\r
+ FreePool (Value.Buffer);\r
+ break;\r
+ \r
default:\r
return EFI_UNSUPPORTED;\r
}\r
return Status;\r
}\r
\r
- if (Value.Type >= EFI_IFR_TYPE_OTHER) {\r
+ if (Value.Type >= EFI_IFR_TYPE_OTHER && Value.Type != EFI_IFR_TYPE_BUFFER) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
Result->Value.u64 = StrDecimalToUint64 (String);\r
}\r
FreePool (String);\r
+ } else if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ if (Value.BufferLen > 8) {\r
+ FreePool (Value.Buffer);\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ Result->Value.u64 = *(UINT64*) Value.Buffer;\r
+ FreePool (Value.Buffer);\r
} else {\r
CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
}\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
+ EFI_HII_VALUE Value[2];\r
CHAR16 *String[2];\r
UINTN Index;\r
CHAR16 *StringPtr;\r
String[1] = NULL;\r
StringPtr = NULL;\r
Status = EFI_SUCCESS;\r
+ ZeroMem (Value, sizeof (Value));\r
\r
for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
+ Status = PopExpression (&Value[Index]);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING && Value[Index].Type != EFI_IFR_TYPE_BUFFER) {\r
Status = EFI_UNSUPPORTED;\r
goto Done;\r
}\r
\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String[Index] == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
+ if (Value[Index].Type == EFI_IFR_TYPE_STRING) {\r
+ String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);\r
+ if (String[Index] == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
}\r
}\r
\r
- Size = StrSize (String[0]);\r
- StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
- ASSERT (StringPtr != NULL);\r
- StrCpy (StringPtr, String[1]);\r
- StrCat (StringPtr, String[0]);\r
+ if (Value[0].Type == EFI_IFR_TYPE_STRING) {\r
+ Size = StrSize (String[0]);\r
+ StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
+ ASSERT (StringPtr != NULL);\r
+ StrCpy (StringPtr, String[1]);\r
+ StrCat (StringPtr, String[0]);\r
\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
+ Result->Type = EFI_IFR_TYPE_STRING;\r
+ Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
+ } else {\r
+ Result->Type = EFI_IFR_TYPE_BUFFER;\r
+ Result->BufferLen = (UINT16) (Value[0].BufferLen + Value[1].BufferLen);\r
+\r
+ Result->Buffer = AllocateZeroPool (Result->BufferLen);\r
+ ASSERT (Result->Buffer != NULL);\r
\r
+ CopyMem (Result->Buffer, Value[0].Buffer, Value[0].BufferLen);\r
+ CopyMem (&Result->Buffer[Value[0].BufferLen], Value[1].Buffer, Value[1].BufferLen);\r
+ }\r
Done:\r
+ if (Value[0].Buffer != NULL) {\r
+ FreePool (Value[0].Buffer);\r
+ }\r
+ if (Value[1].Buffer != NULL) {\r
+ FreePool (Value[1].Buffer);\r
+ }\r
if (String[0] != NULL) {\r
FreePool (String[0]);\r
}\r
UINTN Base;\r
UINTN Length;\r
CHAR16 *SubString;\r
+ UINT8 *Buffer;\r
+ UINT16 BufferLen;\r
\r
Status = PopExpression (&Value);\r
if (EFI_ERROR (Status)) {\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+ if (Value.Type != EFI_IFR_TYPE_STRING && Value.Type != EFI_IFR_TYPE_BUFFER) {\r
return EFI_UNSUPPORTED;\r
}\r
- String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
+ if (Value.Type == EFI_IFR_TYPE_STRING) {\r
+ String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+ if (String == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
- if (Length == 0 || Base >= StrLen (String)) {\r
- SubString = gEmptyString;\r
- } else {\r
- SubString = String + Base;\r
- if ((Base + Length) < StrLen (String)) {\r
- SubString[Length] = L'\0';\r
+ if (Length == 0 || Base >= StrLen (String)) {\r
+ SubString = gEmptyString;\r
+ } else {\r
+ SubString = String + Base;\r
+ if ((Base + Length) < StrLen (String)) {\r
+ SubString[Length] = L'\0';\r
+ }\r
}\r
- }\r
\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
+ Result->Type = EFI_IFR_TYPE_STRING;\r
+ Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
\r
- FreePool (String);\r
+ FreePool (String);\r
+ } else {\r
+ Buffer = Value.Buffer;\r
+ BufferLen = Value.BufferLen;\r
+ \r
+ Result->Type = EFI_IFR_TYPE_BUFFER;\r
+ if (Length == 0 || Base >= BufferLen) {\r
+ Result->BufferLen = 0;\r
+ Result->Buffer = NULL;\r
+ } else {\r
+ Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length); \r
+ Result->Buffer = AllocateZeroPool (Result->BufferLen);\r
+ ASSERT (Result->Buffer != NULL);\r
+ CopyMem (Result->Buffer, &Value.Buffer[Base], Result->BufferLen);\r
+ }\r
\r
+ FreePool (Value.Buffer);\r
+ }\r
+ \r
return Status;\r
}\r
\r
@param Value2 Expression value to compare on right-hand.\r
@param HiiHandle Only required for string compare.\r
\r
- @retval EFI_INVALID_PARAMETER Could not perform comparation on two values.\r
- @retval 0 Two operators equeal.\r
+ @retval EFI_INVALID_PARAMETER Could not perform compare on two values.\r
+ @retval 0 Two operators equal.\r
@return Positive value if Value1 is greater than Value2.\r
@retval Negative value if Value1 is less than Value2.\r
\r
INT64 Temp64;\r
CHAR16 *Str1;\r
CHAR16 *Str2;\r
+ UINTN Len;\r
\r
if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
- return EFI_INVALID_PARAMETER;\r
+ if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
}\r
\r
if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
return Result;\r
}\r
\r
+ if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) {\r
+ if (Value1->Type != Value2->Type) {\r
+ //\r
+ // Both Operator should be type of Buffer.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen;\r
+ Result = CompareMem (Value1->Buffer, Value2->Buffer, Len);\r
+ if ((Result == 0) && (Value1->BufferLen != Value2->BufferLen))\r
+ {\r
+ //\r
+ // In this case, means base on samll number buffer, the data is same\r
+ // So which value has more data, which value is bigger.\r
+ //\r
+ Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1;\r
+ }\r
+ return Result;\r
+ } \r
+\r
//\r
// Take remain types(integer, boolean, date/time) as integer\r
//\r
RemainSize = UserInfo->InfoSize - sizeof (EFI_USER_INFO);\r
AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)(UserInfo + 1);\r
while (RemainSize >= sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
- if (RemainSize < AccessControl->Size || AccessControl->Size <= sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
+ if (RemainSize < AccessControl->Size || AccessControl->Size < sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
break;\r
}\r
if (AccessControl->Type == EFI_USER_INFO_ACCESS_SETUP) {\r
return FALSE;\r
}\r
\r
+/**\r
+ Get question value from the predefined formset.\r
+\r
+ @param DevicePath The driver's device path which produece the formset data.\r
+ @param InputHiiHandle The hii handle associate with the formset data.\r
+ @param FormSetGuid The formset guid which include the question.\r
+ @param QuestionId The question id which need to get value from.\r
+ @param Value The return data about question's value.\r
+ \r
+ @retval TRUE Get the question value success.\r
+ @retval FALSE Get the question value failed.\r
+**/\r
+BOOLEAN \r
+GetQuestionValueFromForm (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN EFI_HII_HANDLE InputHiiHandle,\r
+ IN EFI_GUID *FormSetGuid,\r
+ IN EFI_QUESTION_ID QuestionId,\r
+ OUT EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE DriverHandle;\r
+ EFI_HANDLE Handle;\r
+ EFI_HII_HANDLE *HiiHandles;\r
+ EFI_HII_HANDLE HiiHandle;\r
+ UINTN Index;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+ FORM_BROWSER_FORMSET *FormSet;\r
+ FORM_BROWSER_FORM *Form;\r
+ BOOLEAN GetTheVal;\r
+ LIST_ENTRY *Link;\r
+\r
+ // \r
+ // The input parameter DevicePath or InputHiiHandle must have one valid input. \r
+ //\r
+ ASSERT ((DevicePath != NULL && InputHiiHandle == NULL) || \r
+ (DevicePath == NULL && InputHiiHandle != NULL) );\r
+\r
+ GetTheVal = TRUE;\r
+ DriverHandle = NULL;\r
+ HiiHandle = NULL;\r
+ Question = NULL;\r
+ Form = NULL;\r
+\r
+ //\r
+ // Get HiiHandle.\r
+ //\r
+ if (DevicePath != NULL) {\r
+ //\r
+ // 1. Get Driver handle.\r
+ //\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiDevicePathProtocolGuid,\r
+ &DevicePath,\r
+ &DriverHandle\r
+ );\r
+ if (EFI_ERROR (Status) || (DriverHandle == NULL)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // 2. Get Hii handle\r
+ //\r
+ HiiHandles = HiiGetHiiHandles (NULL);\r
+ if (HiiHandles == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
+ Status = mHiiDatabase->GetPackageListHandle (\r
+ mHiiDatabase,\r
+ HiiHandles[Index],\r
+ &Handle\r
+ );\r
+ if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
+ HiiHandle = HiiHandles[Index];\r
+ break;\r
+ }\r
+ }\r
+ FreePool (HiiHandles);\r
+ } else {\r
+ HiiHandle = InputHiiHandle;\r
+ } \r
+ ASSERT (HiiHandle != NULL);\r
+\r
+ //\r
+ // Get the formset data include this question.\r
+ //\r
+ FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
+ ASSERT (FormSet != NULL);\r
+ Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ GetTheVal = FALSE;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Base on the Question Id to get the question info.\r
+ // \r
+ Question = IdToQuestion(FormSet, NULL, QuestionId);\r
+ if (Question == NULL) {\r
+ GetTheVal = FALSE;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Search form in the formset scope\r
+ //\r
+ Link = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, Link)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+ Question = IdToQuestion2 (Form, QuestionId);\r
+ if (Question != NULL) {\r
+ break;\r
+ }\r
+\r
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
+ Form = NULL;\r
+ }\r
+ ASSERT (Form != NULL);\r
+ \r
+ //\r
+ // Get the question value.\r
+ //\r
+ Status = GetQuestionValue(FormSet, Form, Question, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ GetTheVal = FALSE;\r
+ goto Done;\r
+ }\r
+\r
+ CopyMem (Value, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
+ \r
+Done:\r
+ //\r
+ // Clean the formset structure and restore the global parameter.\r
+ //\r
+ if (FormSet != NULL) {\r
+ DestroyFormSet (FormSet);\r
+ }\r
+ \r
+ return GetTheVal;\r
+}\r
+\r
/**\r
Evaluate the result of a HII expression.\r
\r
EFI_HII_VALUE *Value;\r
INTN Result;\r
CHAR16 *StrPtr;\r
+ CHAR16 *NameValue;\r
UINT32 TempValue;\r
+ LIST_ENTRY *SubExpressionLink;\r
+ FORM_EXPRESSION *SubExpression;\r
+ UINTN StackOffset;\r
+ UINTN TempLength;\r
+ CHAR16 TempStr[5];\r
+ UINT8 DigitUint8;\r
+ UINT8 *TempBuffer;\r
+ EFI_TIME EfiTime;\r
+ EFI_HII_VALUE QuestionVal;\r
\r
//\r
- // Always reset the stack before evaluating an Expression\r
+ // Save current stack offset.\r
//\r
- ResetExpressionStack ();\r
+ StackOffset = SaveExpressionEvaluationStackOffset ();\r
\r
ASSERT (Expression != NULL);\r
Expression->Result.Type = EFI_IFR_TYPE_OTHER;\r
case EFI_IFR_EQ_ID_VAL_OP:\r
Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
Result = CompareHiiValue (&Question->HiiValue, &OpCode->Value, NULL);\r
if (Result == EFI_INVALID_PARAMETER) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
break;\r
case EFI_IFR_EQ_ID_ID_OP:\r
Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2);\r
if (Question2 == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
Result = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, FormSet->HiiHandle);\r
if (Result == EFI_INVALID_PARAMETER) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
break;\r
\r
- case EFI_IFR_EQ_ID_LIST_OP:\r
+ case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
Value->Value.b = FALSE;\r
case EFI_IFR_DUP_OP:\r
Status = PopExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
Status = PushExpression (Value);\r
case EFI_IFR_THIS_OP:\r
Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
Value = &Question->HiiValue;\r
Value->Value.b = CheckUserPrivilege (&OpCode->Guid);\r
break;\r
\r
- case EFI_IFR_QUESTION_REF3_OP:\r
- if (OpCode->DevicePath == 0) {\r
+ case EFI_IFR_GET_OP:\r
+ //\r
+ // Get Value from VarStore buffer, EFI VarStore, Name/Value VarStore.\r
+ //\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Value->Value.u8 = 0;\r
+ if (OpCode->VarStorage != NULL) {\r
+ switch (OpCode->VarStorage->Type) {\r
+ case EFI_HII_VARSTORE_BUFFER:\r
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
+ //\r
+ // Get value from Edit Buffer\r
+ //\r
+ Value->Type = OpCode->ValueType;\r
+ CopyMem (&Value->Value, OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, OpCode->ValueWidth);\r
+ break;\r
+ case EFI_HII_VARSTORE_NAME_VALUE:\r
+ if (OpCode->ValueType != EFI_IFR_TYPE_STRING) {\r
+ //\r
+ // Get value from string except for STRING value.\r
+ //\r
+ Status = GetValueByName (OpCode->VarStorage, OpCode->ValueName, &StrPtr);\r
+ if (!EFI_ERROR (Status)) {\r
+ ASSERT (StrPtr != NULL);\r
+ TempLength = StrLen (StrPtr);\r
+ if (OpCode->ValueWidth >= ((TempLength + 1) / 2)) {\r
+ Value->Type = OpCode->ValueType;\r
+ TempBuffer = (UINT8 *) &Value->Value;\r
+ ZeroMem (TempStr, sizeof (TempStr));\r
+ for (Index = 0; Index < TempLength; Index ++) {\r
+ TempStr[0] = StrPtr[TempLength - Index - 1];\r
+ DigitUint8 = (UINT8) StrHexToUint64 (TempStr);\r
+ if ((Index & 1) == 0) {\r
+ TempBuffer [Index/2] = DigitUint8;\r
+ } else {\r
+ TempBuffer [Index/2] = (UINT8) ((DigitUint8 << 4) + TempBuffer [Index/2]);\r
+ }\r
+ }\r
+ } \r
+ }\r
+ }\r
+ break;\r
+ case EFI_HII_VARSTORE_EFI_VARIABLE:\r
+ //\r
+ // Get value from variable.\r
+ //\r
+ TempLength = OpCode->ValueWidth;\r
+ Value->Type = OpCode->ValueType;\r
+ Status = gRT->GetVariable (\r
+ OpCode->ValueName,\r
+ &OpCode->VarStorage->Guid,\r
+ NULL,\r
+ &TempLength,\r
+ &Value->Value\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Value->Value.u8 = 0;\r
+ }\r
+ break;\r
+ default:\r
+ //\r
+ // Not recognize storage.\r
+ //\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Done;\r
+ }\r
+ } else {\r
//\r
- // EFI_IFR_QUESTION_REF3\r
- // Pop an expression from the expression stack\r
+ // For Time/Date Data\r
//\r
- Status = PopExpression (Value);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (OpCode->ValueType != EFI_IFR_TYPE_DATE && OpCode->ValueType != EFI_IFR_TYPE_TIME) {\r
+ //\r
+ // Only support Data/Time data when storage doesn't exist.\r
+ //\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Done;\r
}\r
+ Status = gRT->GetTime (&EfiTime, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ if (OpCode->ValueType == EFI_IFR_TYPE_DATE) {\r
+ switch (OpCode->VarStoreInfo.VarOffset) {\r
+ case 0x00:\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+ Value->Value.u16 = EfiTime.Year;\r
+ break;\r
+ case 0x02:\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ Value->Value.u8 = EfiTime.Month;\r
+ break;\r
+ case 0x03:\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ Value->Value.u8 = EfiTime.Day;\r
+ break;\r
+ default:\r
+ //\r
+ // Invalid Date field.\r
+ //\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ } else {\r
+ switch (OpCode->VarStoreInfo.VarOffset) {\r
+ case 0x00:\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ Value->Value.u8 = EfiTime.Hour;\r
+ break;\r
+ case 0x01:\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ Value->Value.u8 = EfiTime.Minute;\r
+ break;\r
+ case 0x02:\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+ Value->Value.u8 = EfiTime.Second;\r
+ break;\r
+ default:\r
+ //\r
+ // Invalid Time field.\r
+ //\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ }\r
+ }\r
+ }\r
\r
- //\r
- // Validate the expression value\r
- //\r
- if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
- return EFI_NOT_FOUND;\r
+ break;\r
+\r
+ case EFI_IFR_QUESTION_REF3_OP:\r
+ //\r
+ // EFI_IFR_QUESTION_REF3\r
+ // Pop an expression from the expression stack\r
+ //\r
+ Status = PopExpression (Value);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ \r
+ //\r
+ // Validate the expression value\r
+ //\r
+ if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+\r
+ if (OpCode->DevicePath != 0) {\r
+ StrPtr = GetToken (OpCode->DevicePath, FormSet->HiiHandle);\r
+ if (StrPtr == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
+ if (!GetQuestionValueFromForm((EFI_DEVICE_PATH_PROTOCOL*)StrPtr, NULL, &OpCode->Guid, Value->Value.u16, &QuestionVal)){\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+ Value = &QuestionVal;\r
+ } else if (CompareGuid (&OpCode->Guid, &gZeroGuid) != 0) {\r
+ if (!GetQuestionValueFromForm(NULL, FormSet->HiiHandle, &OpCode->Guid, Value->Value.u16, &QuestionVal)){\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+ Value = &QuestionVal; \r
+ } else {\r
Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
//\r
// push the questions' value on to the expression stack\r
//\r
Value = &Question->HiiValue;\r
- } else {\r
- //\r
- // BUGBUG: push 0 for EFI_IFR_QUESTION_REF3_2 and EFI_IFR_QUESTION_REF3_3,\r
- // since it is impractical to evaluate the value of a Question in another\r
- // Hii Package list.\r
- //\r
- ZeroMem (Value, sizeof (EFI_HII_VALUE));\r
}\r
break;\r
\r
//\r
RuleExpression = RuleIdToExpression (Form, OpCode->RuleId);\r
if (RuleExpression == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
//\r
//\r
Status = EvaluateExpression (FormSet, Form, RuleExpression);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
Value = &RuleExpression->Result;\r
case EFI_IFR_LENGTH_OP:\r
Status = PopExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
- if (Value->Type != EFI_IFR_TYPE_STRING) {\r
- return EFI_INVALID_PARAMETER;\r
+ if (Value->Type != EFI_IFR_TYPE_STRING && Value->Type != EFI_IFR_TYPE_BUFFER) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
\r
- StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
- if (StrPtr == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
+ if (Value->Type == EFI_IFR_TYPE_STRING) {\r
+ StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
+ if (StrPtr == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = StrLen (StrPtr);\r
- FreePool (StrPtr);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ Value->Value.u64 = StrLen (StrPtr);\r
+ FreePool (StrPtr);\r
+ } else {\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ Value->Value.u64 = Value->BufferLen;\r
+ FreePool (Value->Buffer);\r
+ }\r
break;\r
\r
case EFI_IFR_NOT_OP:\r
Status = PopExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
if (Value->Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
Value->Value.b = (BOOLEAN) (!Value->Value.b);\r
break;\r
//\r
Status = PopExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
//\r
// Validate the expression value\r
//\r
if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
Value = &Question->HiiValue;\r
//\r
Status = PopExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
//\r
// Validate the expression value\r
//\r
if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
Value->Type = EFI_IFR_TYPE_STRING;\r
//\r
Status = PopExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
//\r
// When converting from an unsigned integer, zero will be converted to\r
// FALSE and any other value will be converted to TRUE.\r
//\r
- Value->Value.b = (BOOLEAN) ((Value->Value.u64) ? TRUE : FALSE);\r
+ Value->Value.b = (BOOLEAN) (Value->Value.u64 != 0);\r
\r
Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
} else if (Value->Type == EFI_IFR_TYPE_STRING) {\r
//\r
// When converting from a string, if case-insensitive compare\r
// with "true" is True, then push True. If a case-insensitive compare\r
- // with "false" is True, then push False.\r
+ // with "false" is True, then push False. Otherwise, push Undefined. \r
//\r
StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
if (StrPtr == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
-\r
- if ((StrCmp (StrPtr, L"true") == 0) || (StrCmp (StrPtr, L"false") == 0)){\r
+ \r
+ IfrStrToUpper (StrPtr);\r
+ if (StrCmp (StrPtr, L"TRUE") == 0){\r
Value->Value.b = TRUE;\r
- } else {\r
+ } else if (StrCmp (StrPtr, L"FALSE") == 0) {\r
Value->Value.b = FALSE;\r
+ } else {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ FreePool (StrPtr);\r
+ goto Done;\r
}\r
FreePool (StrPtr);\r
Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ } else if (Value->Type == EFI_IFR_TYPE_BUFFER) {\r
+ //\r
+ // When converting from a buffer, if the buffer is all zeroes, \r
+ // then push False. Otherwise push True. \r
+ //\r
+ for (Index =0; Index < Value->BufferLen; Index ++) {\r
+ if (Value->Buffer[Index] != 0) { \r
+ break;\r
+ }\r
+ }\r
+\r
+ if (Index >= Value->BufferLen) {\r
+ Value->Value.b = FALSE;\r
+ } else {\r
+ Value->Value.b = TRUE;\r
+ }\r
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ FreePool (Value->Buffer);\r
}\r
break;\r
\r
case EFI_IFR_TO_UPPER_OP:\r
Status = InitializeUnicodeCollationProtocol ();\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
Status = PopExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
if (Value->Type != EFI_IFR_TYPE_STRING) {\r
- return EFI_UNSUPPORTED;\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Done;\r
}\r
\r
StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
if (StrPtr == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
}\r
\r
if (OpCode->Operand == EFI_IFR_TO_LOWER_OP) {\r
//\r
Status = PopExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
if (Value->Type > EFI_IFR_TYPE_DATE) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
\r
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
Value->Value.u64 = ~Value->Value.u64;\r
break;\r
\r
+ case EFI_IFR_SET_OP:\r
+ //\r
+ // Pop an expression from the expression stack\r
+ //\r
+ Status = PopExpression (Value);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ Data1.Type = EFI_IFR_TYPE_BOOLEAN;\r
+ Data1.Value.b = FALSE;\r
+ //\r
+ // Set value to var storage buffer\r
+ //\r
+ if (OpCode->VarStorage != NULL) {\r
+ switch (OpCode->VarStorage->Type) {\r
+ case EFI_HII_VARSTORE_BUFFER:\r
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
+ CopyMem (OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth);\r
+ Data1.Value.b = TRUE;\r
+ break;\r
+ case EFI_HII_VARSTORE_NAME_VALUE:\r
+ if (OpCode->ValueType != EFI_IFR_TYPE_STRING) {\r
+ NameValue = AllocateZeroPool ((OpCode->ValueWidth * 2 + 1) * sizeof (CHAR16));\r
+ ASSERT (Value != NULL);\r
+ //\r
+ // Convert Buffer to Hex String\r
+ //\r
+ TempBuffer = (UINT8 *) &Value->Value + OpCode->ValueWidth - 1;\r
+ StrPtr = NameValue;\r
+ for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {\r
+ StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);\r
+ }\r
+ Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, TRUE);\r
+ FreePool (NameValue);\r
+ if (!EFI_ERROR (Status)) {\r
+ Data1.Value.b = TRUE;\r
+ }\r
+ }\r
+ break;\r
+ case EFI_HII_VARSTORE_EFI_VARIABLE:\r
+ Status = gRT->SetVariable (\r
+ OpCode->ValueName,\r
+ &OpCode->VarStorage->Guid,\r
+ OpCode->VarStorage->Attributes,\r
+ OpCode->ValueWidth,\r
+ &Value->Value\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Data1.Value.b = TRUE;\r
+ }\r
+ break;\r
+ default:\r
+ //\r
+ // Not recognize storage.\r
+ //\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Done;\r
+ break;\r
+ }\r
+ } else {\r
+ //\r
+ // For Time/Date Data\r
+ //\r
+ if (OpCode->ValueType != EFI_IFR_TYPE_DATE && OpCode->ValueType != EFI_IFR_TYPE_TIME) {\r
+ //\r
+ // Only support Data/Time data when storage doesn't exist.\r
+ //\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Done;\r
+ }\r
+ Status = gRT->GetTime (&EfiTime, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ if (OpCode->ValueType == EFI_IFR_TYPE_DATE) {\r
+ switch (OpCode->VarStoreInfo.VarOffset) {\r
+ case 0x00:\r
+ EfiTime.Year = Value->Value.u16;\r
+ break;\r
+ case 0x02:\r
+ EfiTime.Month = Value->Value.u8;\r
+ break;\r
+ case 0x03:\r
+ EfiTime.Day = Value->Value.u8;\r
+ break;\r
+ default:\r
+ //\r
+ // Invalid Date field.\r
+ //\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ } else {\r
+ switch (OpCode->VarStoreInfo.VarOffset) {\r
+ case 0x00:\r
+ EfiTime.Hour = Value->Value.u8;\r
+ break;\r
+ case 0x01:\r
+ EfiTime.Minute = Value->Value.u8;\r
+ break;\r
+ case 0x02:\r
+ EfiTime.Second = Value->Value.u8;\r
+ break;\r
+ default:\r
+ //\r
+ // Invalid Time field.\r
+ //\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ }\r
+ Status = gRT->SetTime (&EfiTime);\r
+ if (!EFI_ERROR (Status)) {\r
+ Data1.Value.b = TRUE;\r
+ }\r
+ }\r
+ }\r
+ Value = &Data1;\r
+ break;\r
+\r
//\r
// binary-op\r
//\r
//\r
Status = PopExpression (&Data2);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
if (Data2.Type > EFI_IFR_TYPE_DATE) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
\r
//\r
//\r
Status = PopExpression (&Data1);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
if (Data1.Type > EFI_IFR_TYPE_DATE) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
\r
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
//\r
Status = PopExpression (&Data2);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
\r
//\r
//\r
Status = PopExpression (&Data1);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
\r
if (OpCode->Operand == EFI_IFR_AND_OP) {\r
//\r
Status = PopExpression (&Data2);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
- if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) {\r
- return EFI_INVALID_PARAMETER;\r
+ if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && \r
+ Data2.Type != EFI_IFR_TYPE_STRING && \r
+ Data2.Type != EFI_IFR_TYPE_BUFFER) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
\r
//\r
//\r
Status = PopExpression (&Data1);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle);\r
+ if (Data1.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Data1.Buffer);\r
+ FreePool (Data2.Buffer);\r
+ }\r
+ \r
if (Result == EFI_INVALID_PARAMETER) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
\r
switch (OpCode->Operand) {\r
break;\r
\r
case EFI_IFR_MATCH_OP:\r
+ Status = InitializeUnicodeCollationProtocol ();\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ \r
Status = IfrMatch (FormSet, Value);\r
break;\r
\r
//\r
Status = PopExpression (&Data3);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
//\r
//\r
Status = PopExpression (&Data2);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
//\r
//\r
Status = PopExpression (&Data1);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
\r
if (Data1.Value.b) {\r
Status = IfrSpan (FormSet, OpCode->Flags, Value);\r
break;\r
\r
+ case EFI_IFR_MAP_OP:\r
+ //\r
+ // Pop the check value\r
+ //\r
+ Status = PopExpression (&Data1);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check MapExpression list is valid.\r
+ //\r
+ if (OpCode->MapExpressionList.ForwardLink == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Go through map expression list.\r
+ //\r
+ SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);\r
+ while (!IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
+ SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r
+ //\r
+ // Evaluate the first expression in this pair.\r
+ //\r
+ Status = EvaluateExpression (FormSet, Form, SubExpression);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ //\r
+ // Compare the expression value with current value\r
+ //\r
+ if (CompareHiiValue (&Data1, &SubExpression->Result, NULL) == 0) {\r
+ //\r
+ // Try get the map value.\r
+ //\r
+ SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);\r
+ if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r
+ Status = EvaluateExpression (FormSet, Form, SubExpression);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ Value = &SubExpression->Result;\r
+ break;\r
+ }\r
+ //\r
+ // Skip the second expression on this pair.\r
+ //\r
+ SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);\r
+ if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Goto the first expression on next pair.\r
+ //\r
+ SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);\r
+ }\r
+\r
+ //\r
+ // No map value is found.\r
+ //\r
+ if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Value->Value.u8 = 0;\r
+ }\r
+ break;\r
+\r
default:\r
break;\r
}\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
Status = PushExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
}\r
\r
Value = &Data1;\r
Status = PopExpression (Value);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
//\r
// After evaluating an expression, there should be only one value left on the expression stack\r
//\r
if (PopExpression (Value) != EFI_ACCESS_DENIED) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = EFI_INVALID_PARAMETER;\r
}\r
\r
- CopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE));\r
+Done:\r
+ RestoreExpressionEvaluationStackOffset (StackOffset);\r
+ if (!EFI_ERROR (Status)) {\r
+ CopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE));\r
+ }\r
\r
- return EFI_SUCCESS;\r
+ return Status;\r
}\r