/** @file\r
Utility functions for expression evaluation.\r
\r
-Copyright (c) 2007 - 2008, Intel Corporation\r
-All rights reserved. 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
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
-#include "Ui.h"\r
#include "Setup.h"\r
\r
//\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
+FORM_EXPRESSION **mFormExpressionStack = NULL;\r
+FORM_EXPRESSION **mFormExpressionEnd = NULL;\r
+FORM_EXPRESSION **mFormExpressionPointer = NULL;\r
+\r
+FORM_EXPRESSION **mStatementExpressionStack = NULL;\r
+FORM_EXPRESSION **mStatementExpressionEnd = NULL;\r
+FORM_EXPRESSION **mStatementExpressionPointer = NULL;\r
+\r
+FORM_EXPRESSION **mOptionExpressionStack = NULL;\r
+FORM_EXPRESSION **mOptionExpressionEnd = NULL;\r
+FORM_EXPRESSION **mOptionExpressionPointer = NULL;\r
+\r
\r
//\r
// Unicode collation protocol interface\r
//\r
EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;\r
-\r
+EFI_USER_MANAGER_PROTOCOL *mUserManager = NULL;\r
\r
/**\r
Grow size of the stack.\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
+ mFormExpressionPointer = mFormExpressionStack;\r
+ mStatementExpressionPointer = mStatementExpressionStack;\r
+ mOptionExpressionPointer = mOptionExpressionStack;\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
+ Grow size of the stack.\r
+\r
+ This is an internal function.\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 MemberSize The stack member size.\r
+\r
+ @retval EFI_SUCCESS Grow stack success.\r
+ @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.\r
+\r
+**/\r
+EFI_STATUS\r
+GrowConditionalStack (\r
+ IN OUT FORM_EXPRESSION ***Stack,\r
+ IN OUT FORM_EXPRESSION ***StackPtr,\r
+ IN OUT FORM_EXPRESSION ***StackEnd,\r
+ IN UINTN MemberSize\r
+ )\r
+{\r
+ UINTN Size;\r
+ FORM_EXPRESSION **NewStack;\r
+\r
+ Size = EXPRESSION_STACK_SIZE_INCREMENT;\r
+ if (*StackPtr != NULL) {\r
+ Size = Size + (*StackEnd - *Stack);\r
+ }\r
+\r
+ NewStack = AllocatePool (Size * MemberSize);\r
+ if (NewStack == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ if (*StackPtr != NULL) {\r
+ //\r
+ // Copy from Old Stack to the New Stack\r
+ //\r
+ CopyMem (\r
+ NewStack,\r
+ *Stack,\r
+ (*StackEnd - *Stack) * MemberSize\r
+ );\r
+\r
+ //\r
+ // Free The Old Stack\r
+ //\r
+ FreePool (*Stack);\r
+ }\r
+\r
+ //\r
+ // Make the Stack pointer point to the old data in the new stack\r
+ //\r
+ *StackPtr = NewStack + (*StackPtr - *Stack);\r
+ *Stack = NewStack;\r
+ *StackEnd = NewStack + Size;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Push an element onto 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 Data Data to push.\r
+\r
+ @retval EFI_SUCCESS Push stack success.\r
+\r
+**/\r
+EFI_STATUS\r
+PushConditionalStack (\r
+ IN OUT FORM_EXPRESSION ***Stack,\r
+ IN OUT FORM_EXPRESSION ***StackPtr,\r
+ IN OUT FORM_EXPRESSION ***StackEnd,\r
+ IN FORM_EXPRESSION **Data\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Check for a stack overflow condition\r
+ //\r
+ if (*StackPtr >= *StackEnd) {\r
+ //\r
+ // Grow the stack\r
+ //\r
+ Status = GrowConditionalStack (Stack, StackPtr, StackEnd, sizeof (FORM_EXPRESSION *));\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Push the item onto the stack\r
+ //\r
+ CopyMem (*StackPtr, Data, sizeof (FORM_EXPRESSION *));\r
+ *StackPtr = *StackPtr + 1;\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ Pop an element from the stack.\r
+\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
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
+\r
+**/\r
+EFI_STATUS\r
+PopConditionalStack (\r
+ IN FORM_EXPRESSION **Stack,\r
+ IN OUT FORM_EXPRESSION ***StackPtr,\r
+ OUT FORM_EXPRESSION **Data\r
+ )\r
+{\r
+ //\r
+ // Check for a stack underflow condition\r
+ //\r
+ if (*StackPtr == Stack) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ //\r
+ // Pop the item off the stack\r
+ //\r
+ *StackPtr = *StackPtr - 1;\r
+ CopyMem (Data, *StackPtr, sizeof (FORM_EXPRESSION *));\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ Get the expression list count.\r
+\r
+ @param Level Which type this expression belong to. Form,\r
+ statement or option?\r
+\r
+ @retval >=0 The expression count\r
+ @retval -1 Input parameter error.\r
+\r
+**/\r
+INTN\r
+GetConditionalExpressionCount (\r
+ IN EXPRESS_LEVEL Level\r
+ )\r
+{\r
+ switch (Level) {\r
+ case ExpressForm:\r
+ return mFormExpressionPointer - mFormExpressionStack;\r
+ case ExpressStatement:\r
+ return mStatementExpressionPointer - mStatementExpressionStack;\r
+ case ExpressOption:\r
+ return mOptionExpressionPointer - mOptionExpressionStack;\r
+ default:\r
+ ASSERT (FALSE);\r
+ return -1;\r
+ }\r
+}\r
+\r
+/**\r
+ Get the expression Buffer pointer.\r
+\r
+ @param Level Which type this expression belong to. Form,\r
+ statement or option?\r
+\r
+ @retval The start pointer of the expression buffer or NULL.\r
+\r
+**/\r
+FORM_EXPRESSION **\r
+GetConditionalExpressionList (\r
+ IN EXPRESS_LEVEL Level\r
+ )\r
+{\r
+ switch (Level) {\r
+ case ExpressForm:\r
+ return mFormExpressionStack;\r
+ case ExpressStatement:\r
+ return mStatementExpressionStack;\r
+ case ExpressOption:\r
+ return mOptionExpressionStack;\r
+ default:\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Push the expression options onto the Stack.\r
+\r
+ @param Pointer Pointer to the current expression.\r
+ @param Level Which type this expression belong to. Form,\r
+ statement or option?\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
+PushConditionalExpression (\r
+ IN FORM_EXPRESSION *Pointer,\r
+ IN EXPRESS_LEVEL Level\r
+ )\r
+{\r
+ switch (Level) {\r
+ case ExpressForm:\r
+ return PushConditionalStack (\r
+ &mFormExpressionStack,\r
+ &mFormExpressionPointer,\r
+ &mFormExpressionEnd,\r
+ &Pointer\r
+ );\r
+ case ExpressStatement:\r
+ return PushConditionalStack (\r
+ &mStatementExpressionStack,\r
+ &mStatementExpressionPointer,\r
+ &mStatementExpressionEnd,\r
+ &Pointer\r
+ );\r
+ case ExpressOption:\r
+ return PushConditionalStack (\r
+ &mOptionExpressionStack,\r
+ &mOptionExpressionPointer,\r
+ &mOptionExpressionEnd,\r
+ &Pointer\r
+ );\r
+ default:\r
+ ASSERT (FALSE);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+}\r
+\r
+/**\r
+ Pop the expression options from the Stack\r
+\r
+ @param Level Which type this expression belong to. Form,\r
+ statement or option?\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
+PopConditionalExpression (\r
+ IN EXPRESS_LEVEL Level\r
+ )\r
+{\r
+ FORM_EXPRESSION *Pointer;\r
+\r
+ switch (Level) {\r
+ case ExpressForm:\r
+ return PopConditionalStack (\r
+ mFormExpressionStack,\r
+ &mFormExpressionPointer,\r
+ &Pointer\r
+ );\r
+\r
+ case ExpressStatement:\r
+ return PopConditionalStack (\r
+ mStatementExpressionStack,\r
+ &mStatementExpressionPointer,\r
+ &Pointer\r
+ );\r
+\r
+ case ExpressOption:\r
+ return PopConditionalStack (\r
+ mOptionExpressionStack,\r
+ &mOptionExpressionPointer,\r
+ &Pointer\r
+ );\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\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
+ VOID\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
IdToForm (\r
IN FORM_BROWSER_FORMSET *FormSet,\r
IN UINT16 FormId\r
-)\r
+ )\r
{\r
LIST_ENTRY *Link;\r
FORM_BROWSER_FORM *Form;\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
// to keep synchronous, always reload the Question Value.\r
//\r
if (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
- GetQuestionValue (FormSet, Form, Question, FALSE);\r
+ GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);\r
}\r
\r
return Question;\r
**/\r
VOID\r
IfrStrToUpper (\r
- CHAR16 *String\r
+ IN CHAR16 *String\r
)\r
{\r
while (*String != 0) {\r
}\r
}\r
\r
+/**\r
+ Check whether this value type can be transfer to EFI_IFR_TYPE_BUFFER type.\r
+\r
+ EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to\r
+ EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+ @param Value Expression value to compare on.\r
+\r
+ @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type.\r
+ @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type.\r
+\r
+**/\r
+BOOLEAN\r
+IsTypeInBuffer (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_BUFFER:\r
+ case EFI_IFR_TYPE_DATE:\r
+ case EFI_IFR_TYPE_TIME:\r
+ case EFI_IFR_TYPE_REF:\r
+ return TRUE;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Check whether this value type can be transfer to EFI_IFR_TYPE_UINT64\r
+\r
+ @param Value Expression value to compare on.\r
+\r
+ @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type.\r
+ @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type.\r
+\r
+**/\r
+BOOLEAN\r
+IsTypeInUINT64 (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ case EFI_IFR_TYPE_BOOLEAN:\r
+ return TRUE;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Return the buffer length for this value.\r
+\r
+ EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to\r
+ EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+ @param Value Expression value to compare on.\r
+\r
+ @retval BufLen Return the buffer length.\r
+\r
+**/\r
+UINT16\r
+GetLengthForValue (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_BUFFER:\r
+ return Value->BufferLen;\r
+\r
+ case EFI_IFR_TYPE_DATE:\r
+ return (UINT16) sizeof (EFI_HII_DATE);\r
+\r
+ case EFI_IFR_TYPE_TIME:\r
+ return (UINT16) sizeof (EFI_HII_TIME);\r
+\r
+ case EFI_IFR_TYPE_REF:\r
+ return (UINT16) sizeof (EFI_HII_REF);\r
+\r
+ default:\r
+ return 0;\r
+ }\r
+}\r
+\r
+/**\r
+ Return the buffer pointer for this value.\r
+\r
+ EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to\r
+ EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+ @param Value Expression value to compare on.\r
+\r
+ @retval Buf Return the buffer pointer.\r
+\r
+**/\r
+UINT8 *\r
+GetBufferForValue (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_BUFFER:\r
+ return Value->Buffer;\r
+\r
+ case EFI_IFR_TYPE_DATE:\r
+ return (UINT8 *) (&Value->Value.date);\r
+\r
+ case EFI_IFR_TYPE_TIME:\r
+ return (UINT8 *) (&Value->Value.time);\r
+\r
+ case EFI_IFR_TYPE_REF:\r
+ return (UINT8 *) (&Value->Value.ref);\r
+\r
+ default:\r
+ return NULL;\r
+ }\r
+}\r
\r
/**\r
Evaluate opcode EFI_IFR_TO_STRING.\r
CHAR16 *String;\r
CHAR16 *PrintFormat;\r
CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];\r
+ UINT8 *TmpBuf;\r
+ UINT8 *SrcBuf;\r
+ UINTN SrcLen;\r
UINTN BufferSize;\r
\r
Status = PopExpression (&Value);\r
break;\r
\r
default:\r
- return EFI_UNSUPPORTED;\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
}\r
UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64);\r
String = Buffer;\r
String = (Value.Value.b) ? L"True" : L"False";\r
break;\r
\r
+ case EFI_IFR_TYPE_BUFFER:\r
+ case EFI_IFR_TYPE_DATE:\r
+ case EFI_IFR_TYPE_TIME:\r
+ case EFI_IFR_TYPE_REF:\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
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ SrcLen = Value.BufferLen;\r
+ SrcBuf = Value.Buffer;\r
+ } else {\r
+ SrcBuf = GetBufferForValue(&Value);\r
+ SrcLen = GetLengthForValue(&Value);\r
+ }\r
+\r
+ TmpBuf = AllocateZeroPool (SrcLen + 3);\r
+ ASSERT (TmpBuf != NULL);\r
+ if (Format == EFI_IFR_STRING_ASCII) {\r
+ CopyMem (TmpBuf, SrcBuf, SrcLen);\r
+ PrintFormat = L"%a";\r
+ } else {\r
+ // Format == EFI_IFR_STRING_UNICODE\r
+ CopyMem (TmpBuf, SrcBuf, SrcLen * sizeof (CHAR16));\r
+ PrintFormat = L"%s";\r
+ }\r
+ UnicodeSPrint (Buffer, sizeof (Buffer), PrintFormat, TmpBuf);\r
+ String = Buffer;\r
+ FreePool (TmpBuf);\r
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Value.Buffer);\r
+ }\r
+ break;\r
+\r
default:\r
- return EFI_UNSUPPORTED;\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
}\r
\r
Result->Type = EFI_IFR_TYPE_STRING;\r
return Status;\r
}\r
\r
- if (Value.Type >= EFI_IFR_TYPE_OTHER) {\r
- return EFI_UNSUPPORTED;\r
+ if (Value.Type >= EFI_IFR_TYPE_OTHER && !IsTypeInBuffer(&Value)) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
}\r
\r
Status = EFI_SUCCESS;\r
if (String == NULL) {\r
return EFI_NOT_FOUND;\r
}\r
- \r
+\r
IfrStrToUpper (String);\r
StringPtr = StrStr (String, L"0X");\r
if (StringPtr != NULL) {\r
Result->Value.u64 = StrDecimalToUint64 (String);\r
}\r
FreePool (String);\r
+ } else if (IsTypeInBuffer(&Value)) {\r
+ if (GetLengthForValue (&Value) > 8) {\r
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Value.Buffer);\r
+ }\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ ASSERT (GetBufferForValue (&Value) != NULL);\r
+ Result->Value.u64 = *(UINT64*) GetBufferForValue (&Value);\r
+\r
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Value.Buffer);\r
+ }\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
UINTN Size;\r
+ UINT16 Length0;\r
+ UINT16 Length1;\r
+ UINT8 *TmpBuf;\r
+ UINTN MaxLen;\r
\r
//\r
// String[0] - The second string\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
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
+ Status = PopExpression (&Value[0]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = PopExpression (&Value[1]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
+ for (Index = 0; Index < 2; Index++) {\r
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING && !IsTypeInBuffer(&Value[Index])) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
goto Done;\r
}\r
\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== 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
-\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
+ if (Value[0].Type == EFI_IFR_TYPE_STRING) {\r
+ Size = StrSize (String[0]);\r
+ MaxLen = (StrSize (String[1]) + Size) / sizeof (CHAR16);\r
+ StringPtr= AllocatePool (MaxLen * sizeof (CHAR16));\r
+ ASSERT (StringPtr != NULL);\r
+ StrCpyS (StringPtr, MaxLen, String[1]);\r
+ StrCatS (StringPtr, MaxLen, String[0]);\r
\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
+ Length0 = GetLengthForValue(&Value[0]);\r
+ Length1 = GetLengthForValue(&Value[1]);\r
+ Result->BufferLen = (UINT16) (Length0 + Length1);\r
+\r
+ Result->Buffer = AllocateZeroPool (Result->BufferLen);\r
+ ASSERT (Result->Buffer != NULL);\r
+\r
+ TmpBuf = GetBufferForValue(&Value[0]);\r
+ ASSERT (TmpBuf != NULL);\r
+ CopyMem (Result->Buffer, TmpBuf, Length0);\r
+ TmpBuf = GetBufferForValue(&Value[1]);\r
+ ASSERT (TmpBuf != NULL);\r
+ CopyMem (&Result->Buffer[Length0], TmpBuf, Length1);\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
if (String[1] != NULL) {\r
FreePool (String[1]);\r
- } \r
+ }\r
if (StringPtr != NULL) {\r
FreePool (StringPtr);\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
\r
String[0] = NULL;\r
String[1] = NULL;\r
Status = EFI_SUCCESS;\r
+ ZeroMem (Value, sizeof (Value));\r
+\r
+ Status = PopExpression (&Value[0]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = PopExpression (&Value[1]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ for (Index = 0; Index < 2; Index++) {\r
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\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
+ Result->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ Result->Value.b = mUnicodeCollation->MetaiMatch (mUnicodeCollation, String[0], String[1]);\r
+\r
+Done:\r
+ if (String[0] != NULL) {\r
+ FreePool (String[0]);\r
+ }\r
+ if (String[1] != NULL) {\r
+ FreePool (String[1]);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Evaluate opcode EFI_IFR_MATCH2.\r
+\r
+ @param FormSet Formset which contains this opcode.\r
+ @param SyntaxType Syntax type for match2.\r
+ @param Result Evaluation result for this opcode.\r
+\r
+ @retval EFI_SUCCESS Opcode evaluation success.\r
+ @retval Other Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrMatch2 (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN EFI_GUID *SyntaxType,\r
+ OUT EFI_HII_VALUE *Result\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_VALUE Value[2];\r
+ CHAR16 *String[2];\r
+ UINTN Index;\r
+ UINTN GuidIndex;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN BufferSize;\r
+ EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;\r
+ UINTN RegExSyntaxTypeListSize;\r
+ EFI_REGEX_SYNTAX_TYPE *RegExSyntaxTypeList;\r
+ UINTN CapturesCount;\r
+\r
+ //\r
+ // String[0] - The string to search\r
+ // String[1] - pattern\r
+ //\r
+ String[0] = NULL;\r
+ String[1] = NULL;\r
+ HandleBuffer = NULL;\r
+ RegExSyntaxTypeList = NULL;\r
+ Status = EFI_SUCCESS;\r
+ ZeroMem (Value, sizeof (Value));\r
+\r
+ Status = PopExpression (&Value[0]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = PopExpression (&Value[1]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\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
+ BufferSize = 0;\r
+ HandleBuffer = NULL;\r
+ Status = gBS->LocateHandle(\r
+ ByProtocol,\r
+ &gEfiRegularExpressionProtocolGuid,\r
+ NULL,\r
+ &BufferSize,\r
+ HandleBuffer);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HandleBuffer = AllocateZeroPool(BufferSize);\r
+ if (HandleBuffer == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ Status = gBS->LocateHandle(\r
+ ByProtocol,\r
+ &gEfiRegularExpressionProtocolGuid,\r
+ NULL,\r
+ &BufferSize,\r
+ HandleBuffer);\r
+\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\r
+ ASSERT (HandleBuffer != NULL);\r
+ for ( Index = 0; Index < BufferSize / sizeof(EFI_HANDLE); Index ++) {\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuffer[Index],\r
+ &gEfiRegularExpressionProtocolGuid,\r
+ (VOID**)&RegularExpressionProtocol\r
+ );\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
+ RegExSyntaxTypeListSize = 0;\r
+ RegExSyntaxTypeList = NULL;\r
+\r
+ Status = RegularExpressionProtocol->GetInfo (\r
+ RegularExpressionProtocol,\r
+ &RegExSyntaxTypeListSize,\r
+ RegExSyntaxTypeList\r
+ );\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ RegExSyntaxTypeList = AllocateZeroPool(RegExSyntaxTypeListSize);\r
+ if (RegExSyntaxTypeList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ Status = RegularExpressionProtocol->GetInfo (\r
+ RegularExpressionProtocol,\r
+ &RegExSyntaxTypeListSize,\r
+ RegExSyntaxTypeList\r
+ );\r
+ } else if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
+ for (GuidIndex = 0; GuidIndex < RegExSyntaxTypeListSize / sizeof(EFI_GUID); GuidIndex++) {\r
+ if (CompareGuid (&RegExSyntaxTypeList[GuidIndex], SyntaxType)) {\r
+ //\r
+ // Find the match type, return the value.\r
+ //\r
+ Result->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ Status = RegularExpressionProtocol->MatchString (\r
+ RegularExpressionProtocol,\r
+ String[0],\r
+ String[1],\r
+ SyntaxType,\r
+ &Result->Value.b,\r
+ NULL,\r
+ &CapturesCount\r
+ );\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ if (RegExSyntaxTypeList != NULL) {\r
+ FreePool (RegExSyntaxTypeList);\r
}\r
}\r
\r
- Result->Type = EFI_IFR_TYPE_BOOLEAN;\r
- Result->Value.b = mUnicodeCollation->MetaiMatch (mUnicodeCollation, String[0], String[1]);\r
+ //\r
+ // Type specified by SyntaxType is not supported\r
+ // in any of the EFI_REGULAR_EXPRESSION_PROTOCOL instances.\r
+ //\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
\r
Done:\r
if (String[0] != NULL) {\r
}\r
if (String[1] != NULL) {\r
FreePool (String[1]);\r
- } \r
-\r
+ }\r
+ if (RegExSyntaxTypeList != NULL) {\r
+ FreePool (RegExSyntaxTypeList);\r
+ }\r
+ if (HandleBuffer != NULL) {\r
+ FreePool (HandleBuffer);\r
+ }\r
return Status;\r
}\r
\r
-\r
/**\r
Evaluate opcode EFI_IFR_FIND.\r
\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
+ EFI_HII_VALUE Value[3];\r
CHAR16 *String[2];\r
UINTN Base;\r
CHAR16 *StringPtr;\r
UINTN Index;\r
\r
+ ZeroMem (Value, sizeof (Value));\r
+\r
if (Format > EFI_IFR_FF_CASE_INSENSITIVE) {\r
- return EFI_UNSUPPORTED;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
- Status = PopExpression (&Value);\r
+ Status = PopExpression (&Value[0]);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PopExpression (&Value[1]);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PopExpression (&Value[2]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
+\r
+ if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
}\r
- Base = (UINTN) Value.Value.u64;\r
+ Base = (UINTN) Value[0].Value.u64;\r
\r
//\r
// String[0] - sub-string\r
String[0] = NULL;\r
String[1] = NULL;\r
for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
+ if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
goto Done;\r
}\r
\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== NULL) {\r
+ String[Index] = GetToken (Value[Index + 1].Value.string, FormSet->HiiHandle);\r
+ if (String[Index] == NULL) {\r
Status = EFI_NOT_FOUND;\r
goto Done;\r
}\r
}\r
if (String[1] != NULL) {\r
FreePool (String[1]);\r
- } \r
+ }\r
\r
return Status;\r
}\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
+ EFI_HII_VALUE Value[3];\r
CHAR16 *String;\r
UINTN Base;\r
UINTN Length;\r
CHAR16 *SubString;\r
+ UINT16 BufferLen;\r
+ UINT8 *Buffer;\r
\r
- Status = PopExpression (&Value);\r
+ ZeroMem (Value, sizeof (Value));\r
+\r
+ Status = PopExpression (&Value[0]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Length = (UINTN) Value.Value.u64;\r
\r
- Status = PopExpression (&Value);\r
+ Status = PopExpression (&Value[1]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Base = (UINTN) Value.Value.u64;\r
\r
- Status = PopExpression (&Value);\r
+ Status = PopExpression (&Value[2]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- return EFI_UNSUPPORTED;\r
+\r
+ if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
}\r
- String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Length = (UINTN) Value[0].Value.u64;\r
+\r
+ if (Value[1].Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
}\r
+ Base = (UINTN) Value[1].Value.u64;\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
- }\r
+ if (Value[2].Type != EFI_IFR_TYPE_STRING && !IsTypeInBuffer(&Value[2])) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
}\r
+ if (Value[2].Type == EFI_IFR_TYPE_STRING) {\r
+ String = GetToken (Value[2].Value.string, FormSet->HiiHandle);\r
+ if (String == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (SubString, FormSet->HiiHandle);\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
+ Result->Type = EFI_IFR_TYPE_STRING;\r
+ Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
+\r
+ FreePool (String);\r
+ } else {\r
+ BufferLen = GetLengthForValue (&Value[2]);\r
+ Buffer = GetBufferForValue (&Value[2]);\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, &Buffer[Base], Result->BufferLen);\r
+ }\r
\r
- FreePool (String);\r
+ if (Value[2].Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Value[2].Buffer);\r
+ }\r
+ }\r
\r
return Status;\r
}\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
+ EFI_HII_VALUE Value[3];\r
CHAR16 *String[2];\r
UINTN Count;\r
CHAR16 *Delimiter;\r
CHAR16 *StringPtr;\r
UINTN Index;\r
\r
- Status = PopExpression (&Value);\r
+ ZeroMem (Value, sizeof (Value));\r
+\r
+ Status = PopExpression (&Value[0]);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PopExpression (&Value[1]);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PopExpression (&Value[2]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
+\r
+ if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
}\r
- Count = (UINTN) Value.Value.u64;\r
+ Count = (UINTN) Value[0].Value.u64;\r
\r
//\r
// String[0] - Delimiter\r
String[0] = NULL;\r
String[1] = NULL;\r
for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
+ if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
goto Done;\r
}\r
\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== NULL) {\r
+ String[Index] = GetToken (Value[Index + 1].Value.string, FormSet->HiiHandle);\r
+ if (String[Index] == NULL) {\r
Status = EFI_NOT_FOUND;\r
goto Done;\r
}\r
}\r
if (String[1] != NULL) {\r
FreePool (String[1]);\r
- } \r
+ }\r
\r
return Status;\r
}\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
+ EFI_HII_VALUE Value[3];\r
CHAR16 *String[2];\r
CHAR16 *Charset;\r
UINTN Base;\r
CHAR16 *StringPtr;\r
BOOLEAN Found;\r
\r
- Status = PopExpression (&Value);\r
+ ZeroMem (Value, sizeof (Value));\r
+\r
+ Status = PopExpression (&Value[0]);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PopExpression (&Value[1]);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PopExpression (&Value[2]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
- return EFI_UNSUPPORTED;\r
+\r
+ if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ return EFI_SUCCESS;\r
}\r
- Base = (UINTN) Value.Value.u64;\r
+ Base = (UINTN) Value[0].Value.u64;\r
\r
//\r
// String[0] - Charset\r
String[0] = NULL;\r
String[1] = NULL;\r
for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
- if (EFI_ERROR (Status)) {\r
+ if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
goto Done;\r
}\r
\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String== NULL) {\r
+ String[Index] = GetToken (Value[Index + 1].Value.string, FormSet->HiiHandle);\r
+ if (String [Index] == NULL) {\r
Status = EFI_NOT_FOUND;\r
goto Done;\r
}\r
}\r
\r
if (Base >= StrLen (String[1])) {\r
- Status = EFI_UNSUPPORTED;\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
goto Done;\r
}\r
\r
}\r
if (String[1] != NULL) {\r
FreePool (String[1]);\r
- } \r
+ }\r
\r
return Status;\r
}\r
Value->Value.u64 = Temp;\r
}\r
\r
+/**\r
+ Get UINT64 type value.\r
+\r
+ @param Value Input Hii value.\r
+\r
+ @retval UINT64 Return the UINT64 type value.\r
+\r
+**/\r
+UINT64\r
+HiiValueToUINT64 (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ UINT64 RetVal;\r
+\r
+ RetVal = 0;\r
+\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ RetVal = Value->Value.u8;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ RetVal = Value->Value.u16;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ RetVal = Value->Value.u32;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_BOOLEAN:\r
+ RetVal = Value->Value.b;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_DATE:\r
+ RetVal = *(UINT64*) &Value->Value.date;\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_TIME:\r
+ RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff;\r
+ break;\r
+\r
+ default:\r
+ RetVal = Value->Value.u64;\r
+ break;\r
+ }\r
+\r
+ return RetVal;\r
+}\r
\r
/**\r
Compare two Hii value.\r
\r
@param Value1 Expression value to compare on left-hand.\r
@param Value2 Expression value to compare on right-hand.\r
+ @param Result Return value after compare.\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
@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
- @return Positive value if Value1 is greater than Value2.\r
- @retval Negative value if Value1 is less than Value2.\r
+ @retval other Could not perform compare on two values.\r
+ @retval EFI_SUCCESS Compare the value success.\r
\r
**/\r
-INTN\r
+EFI_STATUS\r
CompareHiiValue (\r
IN EFI_HII_VALUE *Value1,\r
IN EFI_HII_VALUE *Value2,\r
+ OUT INTN *Result,\r
IN EFI_HII_HANDLE HiiHandle OPTIONAL\r
)\r
{\r
- INTN Result;\r
INT64 Temp64;\r
CHAR16 *Str1;\r
CHAR16 *Str2;\r
+ UINTN Len;\r
+ UINT8 *Buf1;\r
+ UINT16 Buf1Len;\r
+ UINT8 *Buf2;\r
+ UINT16 Buf2Len;\r
\r
- if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
- if (Value1->Type != Value2->Type) {\r
- //\r
- // Both Operator should be type of String\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
+ if (Value1->Type == EFI_IFR_TYPE_STRING && Value2->Type == EFI_IFR_TYPE_STRING) {\r
if (Value1->Value.string == 0 || Value2->Value.string == 0) {\r
//\r
// StringId 0 is reserved\r
}\r
\r
if (Value1->Value.string == Value2->Value.string) {\r
- return 0;\r
+ *Result = 0;\r
+ return EFI_SUCCESS;\r
}\r
\r
Str1 = GetToken (Value1->Value.string, HiiHandle);\r
//\r
// String not found\r
//\r
- return EFI_INVALID_PARAMETER;\r
+ return EFI_NOT_FOUND;\r
}\r
\r
Str2 = GetToken (Value2->Value.string, HiiHandle);\r
if (Str2 == NULL) {\r
FreePool (Str1);\r
- return EFI_INVALID_PARAMETER;\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ *Result = StrCmp (Str1, Str2);\r
+\r
+ FreePool (Str1);\r
+ FreePool (Str2);\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Take types(date, time, ref, buffer) as buffer\r
+ //\r
+ if (IsTypeInBuffer(Value1) && IsTypeInBuffer(Value2)) {\r
+ Buf1 = GetBufferForValue(Value1);\r
+ Buf1Len = GetLengthForValue(Value1);\r
+ Buf2 = GetBufferForValue(Value2);\r
+ Buf2Len = GetLengthForValue(Value2);\r
+\r
+ Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len;\r
+ *Result = CompareMem (Buf1, Buf2, Len);\r
+ if ((*Result == 0) && (Buf1Len != Buf2Len)) {\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 = Buf1Len > Buf2Len ? 1 : -1;\r
+ }\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Take types(integer, boolean) as integer\r
+ //\r
+ if (IsTypeInUINT64(Value1) && IsTypeInUINT64(Value2)) {\r
+ Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);\r
+ if (Temp64 > 0) {\r
+ *Result = 1;\r
+ } else if (Temp64 < 0) {\r
+ *Result = -1;\r
+ } else {\r
+ *Result = 0;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+ Check if current user has the privilege specified by the permissions GUID.\r
+\r
+ @param[in] Guid A GUID specifying setup access permissions.\r
+\r
+ @retval TRUE Current user has the privilege.\r
+ @retval FALSE Current user does not have the privilege.\r
+**/\r
+BOOLEAN\r
+CheckUserPrivilege (\r
+ IN EFI_GUID *Guid\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_USER_PROFILE_HANDLE UserProfileHandle;\r
+ EFI_USER_INFO_HANDLE UserInfoHandle;\r
+ EFI_USER_INFO *UserInfo;\r
+ EFI_GUID *UserPermissionsGuid;\r
+ UINTN UserInfoSize;\r
+ UINTN AccessControlDataSize;\r
+ EFI_USER_INFO_ACCESS_CONTROL *AccessControl;\r
+ UINTN RemainSize;\r
+\r
+ if (mUserManager == NULL) {\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiUserManagerProtocolGuid,\r
+ NULL,\r
+ (VOID **) &mUserManager\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ///\r
+ /// If the system does not support user management, then it is assumed that\r
+ /// all users have admin privilege and evaluation of each EFI_IFR_SECURITY\r
+ /// op-code is always TRUE.\r
+ ///\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ Status = mUserManager->Current (mUserManager, &UserProfileHandle);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ ///\r
+ /// Enumerate all user information of the current user profile\r
+ /// to look for any EFI_USER_INFO_ACCESS_SETUP record.\r
+ ///\r
+\r
+ for (UserInfoHandle = NULL;;) {\r
+ Status = mUserManager->GetNextInfo (mUserManager, UserProfileHandle, &UserInfoHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+\r
+ UserInfoSize = 0;\r
+ Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, NULL, &UserInfoSize);\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ continue;\r
+ }\r
+\r
+ UserInfo = (EFI_USER_INFO *) AllocatePool (UserInfoSize);\r
+ if (UserInfo == NULL) {\r
+ break;\r
+ }\r
+\r
+ Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, UserInfo, &UserInfoSize);\r
+ if (EFI_ERROR (Status) ||\r
+ UserInfo->InfoType != EFI_USER_INFO_ACCESS_POLICY_RECORD ||\r
+ UserInfo->InfoSize <= sizeof (EFI_USER_INFO)) {\r
+ FreePool (UserInfo);\r
+ continue;\r
+ }\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
+ break;\r
+ }\r
+ if (AccessControl->Type == EFI_USER_INFO_ACCESS_SETUP) {\r
+ ///\r
+ /// Check if current user has the privilege specified by the permissions GUID.\r
+ ///\r
+\r
+ UserPermissionsGuid = (EFI_GUID *)(AccessControl + 1);\r
+ AccessControlDataSize = AccessControl->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
+ while (AccessControlDataSize >= sizeof (EFI_GUID)) {\r
+ if (CompareGuid (Guid, UserPermissionsGuid)) {\r
+ FreePool (UserInfo);\r
+ return TRUE;\r
+ }\r
+ UserPermissionsGuid++;\r
+ AccessControlDataSize -= sizeof (EFI_GUID);\r
+ }\r
+ }\r
+ RemainSize -= AccessControl->Size;\r
+ AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)((UINT8 *)AccessControl + AccessControl->Size);\r
+ }\r
+\r
+ FreePool (UserInfo);\r
+ }\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_HII_HANDLE HiiHandle;\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
+ HiiHandle = NULL;\r
+ Question = NULL;\r
+ Form = NULL;\r
+\r
+ //\r
+ // Get HiiHandle.\r
+ //\r
+ if (DevicePath != NULL) {\r
+ HiiHandle = DevicePathToHiiHandle (DevicePath, FormSetGuid);\r
+ if (HiiHandle == NULL) {\r
+ return FALSE;\r
+ }\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);\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
- Result = StrCmp (Str1, Str2);\r
-\r
- FreePool (Str1);\r
- FreePool (Str2);\r
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
+ Form = NULL;\r
+ }\r
+ ASSERT (Form != NULL);\r
\r
- return Result;\r
+ //\r
+ // Get the question value.\r
+ //\r
+ Status = GetQuestionValue(FormSet, Form, Question, GetSetValueWithEditBuffer);\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
- // Take remain types(integer, boolean, date/time) as integer\r
+ // Clean the formset structure and restore the global parameter.\r
//\r
- Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);\r
- if (Temp64 > 0) {\r
- Result = 1;\r
- } else if (Temp64 < 0) {\r
- Result = -1;\r
- } else {\r
- Result = 0;\r
+ if (FormSet != NULL) {\r
+ DestroyFormSet (FormSet);\r
}\r
\r
- return Result;\r
+ return GetTheVal;\r
}\r
\r
-\r
/**\r
- Evaluate the result of a HII expression\r
+ Evaluate the result of a HII expression.\r
+\r
+ If Expression is NULL, then ASSERT.\r
\r
@param FormSet FormSet associated with this expression.\r
@param Form Form associated with this expression.\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
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+\r
+ StrPtr = NULL;\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
\r
Link = GetFirstNode (&Expression->OpCodeListHead);\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
+ }\r
+\r
+ Status = CompareHiiValue (&Question->HiiValue, &OpCode->Value, &Result, NULL);\r
+ if (Status == EFI_UNSUPPORTED) {\r
+ Status = EFI_SUCCESS;\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
\r
- Result = CompareHiiValue (&Question->HiiValue, &OpCode->Value, NULL);\r
- if (Result == EFI_INVALID_PARAMETER) {\r
- return EFI_INVALID_PARAMETER;\r
+ if (EFI_ERROR (Status)) {\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
\r
Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2);\r
if (Question2 == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
\r
- Result = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, FormSet->HiiHandle);\r
- if (Result == EFI_INVALID_PARAMETER) {\r
- return EFI_INVALID_PARAMETER;\r
+ Status = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, &Result, FormSet->HiiHandle);\r
+ if (Status == EFI_UNSUPPORTED) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+ break;\r
+ }\r
+ if (EFI_ERROR (Status)) {\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\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
break;\r
\r
- case EFI_IFR_QUESTION_REF3_OP:\r
- if (OpCode->DevicePath == 0) {\r
+ case EFI_IFR_SECURITY_OP:\r
+ Value->Value.b = CheckUserPrivilege (&OpCode->Guid);\r
+ break;\r
+\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, GetSetValueWithEditBuffer);\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
+ }\r
+\r
+ if (OpCode->DevicePath != 0) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+\r
+ StrPtr = GetToken (OpCode->DevicePath, FormSet->HiiHandle);\r
+ if (StrPtr != NULL && mPathFromText != NULL) {\r
+ DevicePath = mPathFromText->ConvertTextToDevicePath(StrPtr);\r
+ if (DevicePath != NULL && GetQuestionValueFromForm(DevicePath, NULL, &OpCode->Guid, Value->Value.u16, &QuestionVal)) {\r
+ Value = &QuestionVal;\r
+ }\r
+ if (DevicePath != NULL) {\r
+ FreePool (DevicePath);\r
+ }\r
}\r
\r
+ if (StrPtr != NULL) {\r
+ FreePool (StrPtr);\r
+ }\r
+ } else if (IsZeroGuid (&OpCode->Guid)) {\r
+ if (!GetQuestionValueFromForm(NULL, FormSet->HiiHandle, &OpCode->Guid, Value->Value.u16, &QuestionVal)){\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
+ }\r
+ Value = &QuestionVal;\r
+ } else {\r
Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
\r
//\r
// Evaluate this rule expression\r
//\r
Status = EvaluateExpression (FormSet, Form, RuleExpression);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (EFI_ERROR (Status) || RuleExpression->Result.Type == EFI_IFR_TYPE_UNDEFINED) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\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 && !IsTypeInBuffer (Value)) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\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 = GetLengthForValue(Value);\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
\r
Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
if (Question == NULL) {\r
- return EFI_NOT_FOUND;\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\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) (HiiValueToUINT64(Value) != 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
+ IfrStrToUpper (StrPtr);\r
+ if (StrCmp (StrPtr, L"TRUE") == 0){\r
Value->Value.b = TRUE;\r
- } else {\r
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ } else if (StrCmp (StrPtr, L"FALSE") == 0) {\r
Value->Value.b = FALSE;\r
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ } else {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
}\r
FreePool (StrPtr);\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
\r
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = ~Value->Value.u64;\r
+ Value->Value.u64 = ~ HiiValueToUINT64(Value);\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 (NameValue != 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
+ UnicodeValueToStringS (\r
+ StrPtr,\r
+ (OpCode->ValueWidth * 2 + 1) * sizeof (CHAR16) - ((UINTN)StrPtr - (UINTN)NameValue),\r
+ PREFIX_ZERO | RADIX_HEX,\r
+ *TempBuffer,\r
+ 2\r
+ );\r
+ StrPtr += StrnLenS (StrPtr, OpCode->ValueWidth * 2 + 1 - ((UINTN)StrPtr - (UINTN)NameValue) / sizeof (CHAR16));\r
+ }\r
+ Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer, NULL);\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
+ }\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
//\r
Status = PopExpression (&Data2);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Data2.Type > EFI_IFR_TYPE_DATE) {\r
- return 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
+ if (Data2.Type > EFI_IFR_TYPE_DATE) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
+\r
+\r
if (Data1.Type > EFI_IFR_TYPE_DATE) {\r
- return EFI_INVALID_PARAMETER;\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
\r
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
\r
switch (OpCode->Operand) {\r
case EFI_IFR_ADD_OP:\r
- Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64;\r
+ Value->Value.u64 = HiiValueToUINT64(&Data1) + HiiValueToUINT64(&Data2);\r
break;\r
\r
case EFI_IFR_SUBTRACT_OP:\r
- Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64;\r
+ Value->Value.u64 = HiiValueToUINT64(&Data1) - HiiValueToUINT64(&Data2);\r
break;\r
\r
case EFI_IFR_MULTIPLY_OP:\r
- Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
+ Value->Value.u64 = MultU64x32 (HiiValueToUINT64(&Data1), (UINT32) HiiValueToUINT64(&Data2));\r
break;\r
\r
case EFI_IFR_DIVIDE_OP:\r
- Value->Value.u64 = DivU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
+ Value->Value.u64 = DivU64x32 (HiiValueToUINT64(&Data1), (UINT32) HiiValueToUINT64(&Data2));\r
break;\r
\r
case EFI_IFR_MODULO_OP:\r
- DivU64x32Remainder (Data1.Value.u64, (UINT32) Data2.Value.u64, &TempValue);\r
+ DivU64x32Remainder (HiiValueToUINT64(&Data1), (UINT32) HiiValueToUINT64(&Data2), &TempValue);\r
Value->Value.u64 = TempValue;\r
break;\r
\r
case EFI_IFR_BITWISE_AND_OP:\r
- Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64;\r
+ Value->Value.u64 = HiiValueToUINT64(&Data1) & HiiValueToUINT64(&Data2);\r
break;\r
\r
case EFI_IFR_BITWISE_OR_OP:\r
- Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64;\r
+ Value->Value.u64 = HiiValueToUINT64(&Data1) | HiiValueToUINT64(&Data2);\r
break;\r
\r
case EFI_IFR_SHIFT_LEFT_OP:\r
- Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
+ Value->Value.u64 = LShiftU64 (HiiValueToUINT64(&Data1), (UINTN) HiiValueToUINT64(&Data2));\r
break;\r
\r
case EFI_IFR_SHIFT_RIGHT_OP:\r
- Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
+ Value->Value.u64 = RShiftU64 (HiiValueToUINT64(&Data1), (UINTN) HiiValueToUINT64(&Data2));\r
break;\r
\r
default:\r
//\r
Status = PopExpression (&Data2);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return 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
+ if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
+\r
if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
- return EFI_INVALID_PARAMETER;\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
}\r
\r
if (OpCode->Operand == EFI_IFR_AND_OP) {\r
//\r
Status = PopExpression (&Data2);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) {\r
- return 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
+ if (Data2.Type > EFI_IFR_TYPE_BOOLEAN &&\r
+ Data2.Type != EFI_IFR_TYPE_STRING &&\r
+ !IsTypeInBuffer(&Data2)) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
+ }\r
+\r
+ if (Data1.Type > EFI_IFR_TYPE_BOOLEAN &&\r
+ Data1.Type != EFI_IFR_TYPE_STRING &&\r
+ !IsTypeInBuffer(&Data1)) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\r
+ }\r
+\r
+ Status = CompareHiiValue (&Data1, &Data2, &Result, FormSet->HiiHandle);\r
+ if (Data1.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Data1.Buffer);\r
+ }\r
+ if (Data2.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Data2.Buffer);\r
+ }\r
+\r
+ if (Status == EFI_UNSUPPORTED) {\r
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+ break;\r
}\r
\r
- Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle);\r
- if (Result == EFI_INVALID_PARAMETER) {\r
- return EFI_INVALID_PARAMETER;\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
}\r
\r
switch (OpCode->Operand) {\r
break;\r
\r
case EFI_IFR_NOT_EQUAL_OP:\r
- Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
+ Value->Value.b = (BOOLEAN) ((Result != 0) ? TRUE : FALSE);\r
break;\r
\r
case EFI_IFR_GREATER_EQUAL_OP:\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
+ case EFI_IFR_MATCH2_OP:\r
+ Status = IfrMatch2 (FormSet, &OpCode->Guid, Value);\r
+ break;\r
+\r
case EFI_IFR_CATENATE_OP:\r
Status = IfrCatenate (FormSet, Value);\r
break;\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
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ break;\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, &Result, NULL) == EFI_SUCCESS) && (Result == 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
+ if (EFI_ERROR (Status) || Value->Type == EFI_IFR_TYPE_UNDEFINED) {\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
+\r
+/**\r
+ Check whether the result is TRUE or FALSE.\r
+\r
+ For the EFI_HII_VALUE value type is numeric, return TRUE if the\r
+ value is not 0.\r
+\r
+ @param Result Input the result data.\r
+\r
+ @retval TRUE The result is TRUE.\r
+ @retval FALSE The result is FALSE.\r
+\r
+**/\r
+BOOLEAN\r
+IsTrue (\r
+ IN EFI_HII_VALUE *Result\r
+ )\r
+{\r
+ switch (Result->Type) {\r
+ case EFI_IFR_TYPE_BOOLEAN:\r
+ return Result->Value.b;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ return (BOOLEAN)(Result->Value.u8 != 0);\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ return (BOOLEAN)(Result->Value.u16 != 0);\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ return (BOOLEAN)(Result->Value.u32 != 0);\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ return (BOOLEAN)(Result->Value.u64 != 0);\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Return the result of the expression list. Check the expression list and\r
+ return the highest priority express result.\r
+ Priority: DisableIf > SuppressIf > GrayOutIf > FALSE\r
+\r
+ @param ExpList The input expression list.\r
+ @param Evaluate Whether need to evaluate the expression first.\r
+ @param FormSet FormSet associated with this expression.\r
+ @param Form Form associated with this expression.\r
+\r
+ @retval EXPRESS_RESULT Return the higher priority express result.\r
+ DisableIf > SuppressIf > GrayOutIf > FALSE\r
+\r
+**/\r
+EXPRESS_RESULT\r
+EvaluateExpressionList (\r
+ IN FORM_EXPRESSION_LIST *ExpList,\r
+ IN BOOLEAN Evaluate,\r
+ IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL\r
+ IN FORM_BROWSER_FORM *Form OPTIONAL\r
+ )\r
+{\r
+ UINTN Index;\r
+ EXPRESS_RESULT ReturnVal;\r
+ EXPRESS_RESULT CompareOne;\r
+ EFI_STATUS Status;\r
+\r
+ if (ExpList == NULL) {\r
+ return ExpressFalse;\r
+ }\r
+\r
+ ASSERT(ExpList->Signature == FORM_EXPRESSION_LIST_SIGNATURE);\r
+ Index = 0;\r
+\r
+ //\r
+ // Check whether need to evaluate the expression first.\r
+ //\r
+ if (Evaluate) {\r
+ while (ExpList->Count > Index) {\r
+ Status = EvaluateExpression (FormSet, Form, ExpList->Expression[Index++]);\r
+ if (EFI_ERROR (Status)) {\r
+ return ExpressFalse;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Run the list of expressions.\r
+ //\r
+ ReturnVal = ExpressFalse;\r
+ for (Index = 0; Index < ExpList->Count; Index++) {\r
+ if (IsTrue (&ExpList->Expression[Index]->Result)) {\r
+ switch (ExpList->Expression[Index]->Type) {\r
+ case EFI_HII_EXPRESSION_SUPPRESS_IF:\r
+ CompareOne = ExpressSuppress;\r
+ break;\r
+\r
+ case EFI_HII_EXPRESSION_GRAY_OUT_IF:\r
+ CompareOne = ExpressGrayOut;\r
+ break;\r
+\r
+ case EFI_HII_EXPRESSION_DISABLE_IF:\r
+ CompareOne = ExpressDisable;\r
+ break;\r
+\r
+ default:\r
+ return ExpressFalse;\r
+ }\r
+\r
+ ReturnVal = ReturnVal < CompareOne ? CompareOne : ReturnVal;\r
+ }\r
+ }\r
+\r
+ return ReturnVal;\r
}\r