X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FSetupBrowserDxe%2FExpression.c;h=7f4929c2fcd90a59e934723ba158a20db03a9fd5;hp=883693fde59233acd397001b1bf3d8b290bb5246;hb=9d510e61fceee7b92955ef9a3c20343752d8ce3f;hpb=901ba0e78d02bd4407571c296871f96a0d225698
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
index 883693fde5..7f4929c2fc 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
@@ -1,14 +1,8 @@
/** @file
Utility functions for expression evaluation.
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -34,6 +28,19 @@ EFI_HII_VALUE *mMapExpressionListStack = NULL;
EFI_HII_VALUE *mMapExpressionListEnd = NULL;
EFI_HII_VALUE *mMapExpressionListPointer = NULL;
+FORM_EXPRESSION **mFormExpressionStack = NULL;
+FORM_EXPRESSION **mFormExpressionEnd = NULL;
+FORM_EXPRESSION **mFormExpressionPointer = NULL;
+
+FORM_EXPRESSION **mStatementExpressionStack = NULL;
+FORM_EXPRESSION **mStatementExpressionEnd = NULL;
+FORM_EXPRESSION **mStatementExpressionPointer = NULL;
+
+FORM_EXPRESSION **mOptionExpressionStack = NULL;
+FORM_EXPRESSION **mOptionExpressionEnd = NULL;
+FORM_EXPRESSION **mOptionExpressionPointer = NULL;
+
+
//
// Unicode collation protocol interface
//
@@ -144,7 +151,7 @@ PushStack (
(*StackPtr)->Buffer = AllocateCopyPool(Data->BufferLen, Data->Buffer);
ASSERT ((*StackPtr)->Buffer != NULL);
}
-
+
*StackPtr = *StackPtr + 1;
return EFI_SUCCESS;
@@ -194,7 +201,10 @@ ResetCurrentExpressionStack (
VOID
)
{
- mCurrentExpressionPointer = mCurrentExpressionStack;
+ mCurrentExpressionPointer = mCurrentExpressionStack;
+ mFormExpressionPointer = mFormExpressionStack;
+ mStatementExpressionPointer = mStatementExpressionStack;
+ mOptionExpressionPointer = mOptionExpressionStack;
}
@@ -267,6 +277,294 @@ ResetMapExpressionListStack (
}
+/**
+ Grow size of the stack.
+
+ This is an internal function.
+
+ @param Stack On input: old stack; On output: new stack
+ @param StackPtr On input: old stack pointer; On output: new stack
+ pointer
+ @param StackEnd On input: old stack end; On output: new stack end
+ @param MemberSize The stack member size.
+
+ @retval EFI_SUCCESS Grow stack success.
+ @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
+
+**/
+EFI_STATUS
+GrowConditionalStack (
+ IN OUT FORM_EXPRESSION ***Stack,
+ IN OUT FORM_EXPRESSION ***StackPtr,
+ IN OUT FORM_EXPRESSION ***StackEnd,
+ IN UINTN MemberSize
+ )
+{
+ UINTN Size;
+ FORM_EXPRESSION **NewStack;
+
+ Size = EXPRESSION_STACK_SIZE_INCREMENT;
+ if (*StackPtr != NULL) {
+ Size = Size + (*StackEnd - *Stack);
+ }
+
+ NewStack = AllocatePool (Size * MemberSize);
+ if (NewStack == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (*StackPtr != NULL) {
+ //
+ // Copy from Old Stack to the New Stack
+ //
+ CopyMem (
+ NewStack,
+ *Stack,
+ (*StackEnd - *Stack) * MemberSize
+ );
+
+ //
+ // Free The Old Stack
+ //
+ FreePool (*Stack);
+ }
+
+ //
+ // Make the Stack pointer point to the old data in the new stack
+ //
+ *StackPtr = NewStack + (*StackPtr - *Stack);
+ *Stack = NewStack;
+ *StackEnd = NewStack + Size;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Push an element onto the Stack.
+
+ @param Stack On input: old stack; On output: new stack
+ @param StackPtr On input: old stack pointer; On output: new stack
+ pointer
+ @param StackEnd On input: old stack end; On output: new stack end
+ @param Data Data to push.
+
+ @retval EFI_SUCCESS Push stack success.
+
+**/
+EFI_STATUS
+PushConditionalStack (
+ IN OUT FORM_EXPRESSION ***Stack,
+ IN OUT FORM_EXPRESSION ***StackPtr,
+ IN OUT FORM_EXPRESSION ***StackEnd,
+ IN FORM_EXPRESSION **Data
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Check for a stack overflow condition
+ //
+ if (*StackPtr >= *StackEnd) {
+ //
+ // Grow the stack
+ //
+ Status = GrowConditionalStack (Stack, StackPtr, StackEnd, sizeof (FORM_EXPRESSION *));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Push the item onto the stack
+ //
+ CopyMem (*StackPtr, Data, sizeof (FORM_EXPRESSION *));
+ *StackPtr = *StackPtr + 1;
+
+ return EFI_SUCCESS;
+
+}
+
+/**
+ Pop an element from the stack.
+
+ @param Stack On input: old stack
+ @param StackPtr On input: old stack pointer; On output: new stack pointer
+ @param Data Data to pop.
+
+ @retval EFI_SUCCESS The value was popped onto the stack.
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
+
+**/
+EFI_STATUS
+PopConditionalStack (
+ IN FORM_EXPRESSION **Stack,
+ IN OUT FORM_EXPRESSION ***StackPtr,
+ OUT FORM_EXPRESSION **Data
+ )
+{
+ //
+ // Check for a stack underflow condition
+ //
+ if (*StackPtr == Stack) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // Pop the item off the stack
+ //
+ *StackPtr = *StackPtr - 1;
+ CopyMem (Data, *StackPtr, sizeof (FORM_EXPRESSION *));
+ return EFI_SUCCESS;
+
+}
+
+/**
+ Get the expression list count.
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval >=0 The expression count
+ @retval -1 Input parameter error.
+
+**/
+INTN
+GetConditionalExpressionCount (
+ IN EXPRESS_LEVEL Level
+ )
+{
+ switch (Level) {
+ case ExpressForm:
+ return mFormExpressionPointer - mFormExpressionStack;
+ case ExpressStatement:
+ return mStatementExpressionPointer - mStatementExpressionStack;
+ case ExpressOption:
+ return mOptionExpressionPointer - mOptionExpressionStack;
+ default:
+ ASSERT (FALSE);
+ return -1;
+ }
+}
+
+/**
+ Get the expression Buffer pointer.
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval The start pointer of the expression buffer or NULL.
+
+**/
+FORM_EXPRESSION **
+GetConditionalExpressionList (
+ IN EXPRESS_LEVEL Level
+ )
+{
+ switch (Level) {
+ case ExpressForm:
+ return mFormExpressionStack;
+ case ExpressStatement:
+ return mStatementExpressionStack;
+ case ExpressOption:
+ return mOptionExpressionStack;
+ default:
+ ASSERT (FALSE);
+ return NULL;
+ }
+}
+
+
+/**
+ Push the expression options onto the Stack.
+
+ @param Pointer Pointer to the current expression.
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushConditionalExpression (
+ IN FORM_EXPRESSION *Pointer,
+ IN EXPRESS_LEVEL Level
+ )
+{
+ switch (Level) {
+ case ExpressForm:
+ return PushConditionalStack (
+ &mFormExpressionStack,
+ &mFormExpressionPointer,
+ &mFormExpressionEnd,
+ &Pointer
+ );
+ case ExpressStatement:
+ return PushConditionalStack (
+ &mStatementExpressionStack,
+ &mStatementExpressionPointer,
+ &mStatementExpressionEnd,
+ &Pointer
+ );
+ case ExpressOption:
+ return PushConditionalStack (
+ &mOptionExpressionStack,
+ &mOptionExpressionPointer,
+ &mOptionExpressionEnd,
+ &Pointer
+ );
+ default:
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+/**
+ Pop the expression options from the Stack
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopConditionalExpression (
+ IN EXPRESS_LEVEL Level
+ )
+{
+ FORM_EXPRESSION *Pointer;
+
+ switch (Level) {
+ case ExpressForm:
+ return PopConditionalStack (
+ mFormExpressionStack,
+ &mFormExpressionPointer,
+ &Pointer
+ );
+
+ case ExpressStatement:
+ return PopConditionalStack (
+ mStatementExpressionStack,
+ &mStatementExpressionPointer,
+ &Pointer
+ );
+
+ case ExpressOption:
+ return PopConditionalStack (
+ mOptionExpressionStack,
+ &mOptionExpressionPointer,
+ &Pointer
+ );
+
+ default:
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+
/**
Push the list of map expression onto the Stack
@@ -447,6 +745,7 @@ PopExpression (
**/
UINTN
SaveExpressionEvaluationStackOffset (
+ VOID
)
{
UINTN TempStackOffset;
@@ -483,7 +782,7 @@ FORM_BROWSER_FORM *
IdToForm (
IN FORM_BROWSER_FORMSET *FormSet,
IN UINT16 FormId
-)
+ )
{
LIST_ENTRY *Link;
FORM_BROWSER_FORM *Form;
@@ -522,7 +821,7 @@ IdToQuestion2 (
LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Question;
- if (QuestionId == 0) {
+ if (QuestionId == 0 || Form == NULL) {
//
// The value of zero is reserved
//
@@ -587,7 +886,7 @@ IdToQuestion (
// to keep synchronous, always reload the Question Value.
//
if (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
- GetQuestionValue (FormSet, Form, Question, FALSE);
+ GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);
}
return Question;
@@ -684,95 +983,236 @@ IfrStrToUpper (
}
}
-
/**
- Evaluate opcode EFI_IFR_TO_STRING.
+ Check whether this value type can be transfer to EFI_IFR_TYPE_BUFFER type.
- @param FormSet Formset which contains this opcode.
- @param Format String format in EFI_IFR_TO_STRING.
- @param Result Evaluation result for this opcode.
+ EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to
+ EFI_IFR_TYPE_BUFFER when do the value compare.
- @retval EFI_SUCCESS Opcode evaluation success.
- @retval Other Opcode evaluation failed.
+ @param Value Expression value to compare on.
+
+ @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type.
+ @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type.
**/
-EFI_STATUS
-IfrToString (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN UINT8 Format,
- OUT EFI_HII_VALUE *Result
+BOOLEAN
+IsTypeInBuffer (
+ IN EFI_HII_VALUE *Value
)
{
- EFI_STATUS Status;
- EFI_HII_VALUE Value;
- CHAR16 *String;
- CHAR16 *PrintFormat;
- CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];
- UINT8 *TmpBuf;
- UINTN BufferSize;
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_BUFFER:
+ case EFI_IFR_TYPE_DATE:
+ case EFI_IFR_TYPE_TIME:
+ case EFI_IFR_TYPE_REF:
+ return TRUE;
- Status = PopExpression (&Value);
- if (EFI_ERROR (Status)) {
- return Status;
+ default:
+ return FALSE;
}
+}
- switch (Value.Type) {
+/**
+ Check whether this value type can be transfer to EFI_IFR_TYPE_UINT64
+
+ @param Value Expression value to compare on.
+
+ @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type.
+ @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type.
+
+**/
+BOOLEAN
+IsTypeInUINT64 (
+ IN EFI_HII_VALUE *Value
+ )
+{
+ switch (Value->Type) {
case EFI_IFR_TYPE_NUM_SIZE_8:
case EFI_IFR_TYPE_NUM_SIZE_16:
case EFI_IFR_TYPE_NUM_SIZE_32:
case EFI_IFR_TYPE_NUM_SIZE_64:
- BufferSize = MAXIMUM_VALUE_CHARACTERS * sizeof (CHAR16);
- switch (Format) {
- case EFI_IFR_STRING_UNSIGNED_DEC:
- case EFI_IFR_STRING_SIGNED_DEC:
- PrintFormat = L"%ld";
- break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ return TRUE;
- case EFI_IFR_STRING_LOWERCASE_HEX:
- PrintFormat = L"%lx";
- break;
+ default:
+ return FALSE;
+ }
+}
- case EFI_IFR_STRING_UPPERCASE_HEX:
- PrintFormat = L"%lX";
- break;
+/**
+ Return the buffer length for this value.
- default:
- return EFI_UNSUPPORTED;
- }
- UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64);
- String = Buffer;
- break;
+ EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to
+ EFI_IFR_TYPE_BUFFER when do the value compare.
- case EFI_IFR_TYPE_STRING:
- CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));
- return EFI_SUCCESS;
+ @param Value Expression value to compare on.
- case EFI_IFR_TYPE_BOOLEAN:
- String = (Value.Value.b) ? L"True" : L"False";
+ @retval BufLen Return the buffer length.
+
+**/
+UINT16
+GetLengthForValue (
+ IN EFI_HII_VALUE *Value
+ )
+{
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_BUFFER:
+ return Value->BufferLen;
+
+ case EFI_IFR_TYPE_DATE:
+ return (UINT16) sizeof (EFI_HII_DATE);
+
+ case EFI_IFR_TYPE_TIME:
+ return (UINT16) sizeof (EFI_HII_TIME);
+
+ case EFI_IFR_TYPE_REF:
+ return (UINT16) sizeof (EFI_HII_REF);
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Return the buffer pointer for this value.
+
+ EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to
+ EFI_IFR_TYPE_BUFFER when do the value compare.
+
+ @param Value Expression value to compare on.
+
+ @retval Buf Return the buffer pointer.
+
+**/
+UINT8 *
+GetBufferForValue (
+ IN EFI_HII_VALUE *Value
+ )
+{
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_BUFFER:
+ return Value->Buffer;
+
+ case EFI_IFR_TYPE_DATE:
+ return (UINT8 *) (&Value->Value.date);
+
+ case EFI_IFR_TYPE_TIME:
+ return (UINT8 *) (&Value->Value.time);
+
+ case EFI_IFR_TYPE_REF:
+ return (UINT8 *) (&Value->Value.ref);
+
+ default:
+ return NULL;
+ }
+}
+
+/**
+ Evaluate opcode EFI_IFR_TO_STRING.
+
+ @param FormSet Formset which contains this opcode.
+ @param Format String format in EFI_IFR_TO_STRING.
+ @param Result Evaluation result for this opcode.
+
+ @retval EFI_SUCCESS Opcode evaluation success.
+ @retval Other Opcode evaluation failed.
+
+**/
+EFI_STATUS
+IfrToString (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN UINT8 Format,
+ OUT EFI_HII_VALUE *Result
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_VALUE Value;
+ CHAR16 *String;
+ CHAR16 *PrintFormat;
+ CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];
+ UINT8 *TmpBuf;
+ UINT8 *SrcBuf;
+ UINTN SrcLen;
+ UINTN BufferSize;
+
+ Status = PopExpression (&Value);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ switch (Value.Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ BufferSize = MAXIMUM_VALUE_CHARACTERS * sizeof (CHAR16);
+ switch (Format) {
+ case EFI_IFR_STRING_UNSIGNED_DEC:
+ case EFI_IFR_STRING_SIGNED_DEC:
+ PrintFormat = L"%ld";
+ break;
+
+ case EFI_IFR_STRING_LOWERCASE_HEX:
+ PrintFormat = L"%lx";
+ break;
+
+ case EFI_IFR_STRING_UPPERCASE_HEX:
+ PrintFormat = L"%lX";
+ break;
+
+ default:
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
+ }
+ UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64);
+ String = Buffer;
break;
-
+
+ case EFI_IFR_TYPE_STRING:
+ CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));
+ return EFI_SUCCESS;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ String = (Value.Value.b) ? L"True" : L"False";
+ break;
+
case EFI_IFR_TYPE_BUFFER:
+ case EFI_IFR_TYPE_DATE:
+ case EFI_IFR_TYPE_TIME:
+ case EFI_IFR_TYPE_REF:
//
- // + 3 is base on the unicode format, the length may be odd number,
+ // + 3 is base on the unicode format, the length may be odd number,
// so need 1 byte to align, also need 2 bytes for L'\0'.
//
- TmpBuf = AllocateZeroPool (Value.BufferLen + 3);
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {
+ SrcLen = Value.BufferLen;
+ SrcBuf = Value.Buffer;
+ } else {
+ SrcBuf = GetBufferForValue(&Value);
+ SrcLen = GetLengthForValue(&Value);
+ }
+
+ TmpBuf = AllocateZeroPool (SrcLen + 3);
+ ASSERT (TmpBuf != NULL);
if (Format == EFI_IFR_STRING_ASCII) {
- CopyMem (TmpBuf, Value.Buffer, Value.BufferLen);
- PrintFormat = L"%a";
+ CopyMem (TmpBuf, SrcBuf, SrcLen);
+ PrintFormat = L"%a";
} else {
// Format == EFI_IFR_STRING_UNICODE
- CopyMem (TmpBuf, Value.Buffer, Value.BufferLen * sizeof (CHAR16));
- PrintFormat = L"%s";
+ CopyMem (TmpBuf, SrcBuf, SrcLen * sizeof (CHAR16));
+ PrintFormat = L"%s";
}
- UnicodeSPrint (Buffer, MAXIMUM_VALUE_CHARACTERS, PrintFormat, Value.Buffer);
- String = Buffer;
+ UnicodeSPrint (Buffer, sizeof (Buffer), PrintFormat, TmpBuf);
+ String = Buffer;
FreePool (TmpBuf);
- FreePool (Value.Buffer);
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {
+ FreePool (Value.Buffer);
+ }
break;
-
+
default:
- return EFI_UNSUPPORTED;
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
}
Result->Type = EFI_IFR_TYPE_STRING;
@@ -807,8 +1247,9 @@ IfrToUint (
return Status;
}
- if (Value.Type >= EFI_IFR_TYPE_OTHER && Value.Type != EFI_IFR_TYPE_BUFFER) {
- return EFI_UNSUPPORTED;
+ if (Value.Type >= EFI_IFR_TYPE_OTHER && !IsTypeInBuffer(&Value)) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
}
Status = EFI_SUCCESS;
@@ -832,13 +1273,18 @@ IfrToUint (
Result->Value.u64 = StrDecimalToUint64 (String);
}
FreePool (String);
- } else if (Value.Type == EFI_IFR_TYPE_BUFFER) {
- if (Value.BufferLen > 8) {
+ } else if (IsTypeInBuffer(&Value)) {
+ if (GetLengthForValue (&Value) > 8) {
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {
+ FreePool (Value.Buffer);
+ }
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
+ }
+ Result->Value.u64 = *(UINT64*) GetBufferForValue (&Value);
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {
FreePool (Value.Buffer);
- return EFI_UNSUPPORTED;
}
- Result->Value.u64 = *(UINT64*) Value.Buffer;
- FreePool (Value.Buffer);
} else {
CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));
}
@@ -870,6 +1316,10 @@ IfrCatenate (
UINTN Index;
CHAR16 *StringPtr;
UINTN Size;
+ UINT16 Length0;
+ UINT16 Length1;
+ UINT8 *TmpBuf;
+ UINTN MaxLen;
//
// String[0] - The second string
@@ -881,14 +1331,20 @@ IfrCatenate (
Status = EFI_SUCCESS;
ZeroMem (Value, sizeof (Value));
- for (Index = 0; Index < 2; Index++) {
- Status = PopExpression (&Value[Index]);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
+ Status = PopExpression (&Value[0]);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
- if (Value[Index].Type != EFI_IFR_TYPE_STRING && Value[Index].Type != EFI_IFR_TYPE_BUFFER) {
- Status = EFI_UNSUPPORTED;
+ Status = PopExpression (&Value[1]);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ for (Index = 0; Index < 2; Index++) {
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING && !IsTypeInBuffer(&Value[Index])) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
goto Done;
}
@@ -903,22 +1359,29 @@ IfrCatenate (
if (Value[0].Type == EFI_IFR_TYPE_STRING) {
Size = StrSize (String[0]);
- StringPtr= AllocatePool (StrSize (String[1]) + Size);
+ MaxLen = (StrSize (String[1]) + Size) / sizeof (CHAR16);
+ StringPtr= AllocatePool (MaxLen * sizeof (CHAR16));
ASSERT (StringPtr != NULL);
- StrCpy (StringPtr, String[1]);
- StrCat (StringPtr, String[0]);
+ StrCpyS (StringPtr, MaxLen, String[1]);
+ StrCatS (StringPtr, MaxLen, String[0]);
Result->Type = EFI_IFR_TYPE_STRING;
Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);
} else {
Result->Type = EFI_IFR_TYPE_BUFFER;
- Result->BufferLen = (UINT16) (Value[0].BufferLen + Value[1].BufferLen);
+ Length0 = GetLengthForValue(&Value[0]);
+ Length1 = GetLengthForValue(&Value[1]);
+ Result->BufferLen = (UINT16) (Length0 + Length1);
Result->Buffer = AllocateZeroPool (Result->BufferLen);
ASSERT (Result->Buffer != NULL);
- CopyMem (Result->Buffer, Value[0].Buffer, Value[0].BufferLen);
- CopyMem (&Result->Buffer[Value[0].BufferLen], Value[1].Buffer, Value[1].BufferLen);
+ TmpBuf = GetBufferForValue(&Value[0]);
+ ASSERT (TmpBuf != NULL);
+ CopyMem (Result->Buffer, TmpBuf, Length0);
+ TmpBuf = GetBufferForValue(&Value[1]);
+ ASSERT (TmpBuf != NULL);
+ CopyMem (&Result->Buffer[Length0], TmpBuf, Length1);
}
Done:
if (Value[0].Buffer != NULL) {
@@ -958,7 +1421,7 @@ IfrMatch (
)
{
EFI_STATUS Status;
- EFI_HII_VALUE Value;
+ EFI_HII_VALUE Value[2];
CHAR16 *String[2];
UINTN Index;
@@ -969,18 +1432,26 @@ IfrMatch (
String[0] = NULL;
String[1] = NULL;
Status = EFI_SUCCESS;
- for (Index = 0; Index < 2; Index++) {
- Status = PopExpression (&Value);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
+ ZeroMem (Value, sizeof (Value));
+
+ Status = PopExpression (&Value[0]);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
- if (Value.Type != EFI_IFR_TYPE_STRING) {
- Status = EFI_UNSUPPORTED;
+ Status = PopExpression (&Value[1]);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ for (Index = 0; Index < 2; Index++) {
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
goto Done;
}
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);
+ String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);
if (String [Index] == NULL) {
Status = EFI_NOT_FOUND;
goto Done;
@@ -1001,6 +1472,180 @@ Done:
return Status;
}
+/**
+ Evaluate opcode EFI_IFR_MATCH2.
+
+ @param FormSet Formset which contains this opcode.
+ @param SyntaxType Syntax type for match2.
+ @param Result Evaluation result for this opcode.
+
+ @retval EFI_SUCCESS Opcode evaluation success.
+ @retval Other Opcode evaluation failed.
+
+**/
+EFI_STATUS
+IfrMatch2 (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN EFI_GUID *SyntaxType,
+ OUT EFI_HII_VALUE *Result
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_VALUE Value[2];
+ CHAR16 *String[2];
+ UINTN Index;
+ UINTN GuidIndex;
+ EFI_HANDLE *HandleBuffer;
+ UINTN BufferSize;
+ EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;
+ UINTN RegExSyntaxTypeListSize;
+ EFI_REGEX_SYNTAX_TYPE *RegExSyntaxTypeList;
+ UINTN CapturesCount;
+
+ //
+ // String[0] - The string to search
+ // String[1] - pattern
+ //
+ String[0] = NULL;
+ String[1] = NULL;
+ HandleBuffer = NULL;
+ RegExSyntaxTypeList = NULL;
+ Status = EFI_SUCCESS;
+ ZeroMem (Value, sizeof (Value));
+
+ Status = PopExpression (&Value[0]);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = PopExpression (&Value[1]);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ for (Index = 0; Index < 2; Index++) {
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+
+ String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);
+ if (String [Index] == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+ }
+
+ BufferSize = 0;
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandle(
+ ByProtocol,
+ &gEfiRegularExpressionProtocolGuid,
+ NULL,
+ &BufferSize,
+ HandleBuffer);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ HandleBuffer = AllocateZeroPool(BufferSize);
+ if (HandleBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ Status = gBS->LocateHandle(
+ ByProtocol,
+ &gEfiRegularExpressionProtocolGuid,
+ NULL,
+ &BufferSize,
+ HandleBuffer);
+
+ }
+
+ if (EFI_ERROR (Status)) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+
+ ASSERT (HandleBuffer != NULL);
+ for ( Index = 0; Index < BufferSize / sizeof(EFI_HANDLE); Index ++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiRegularExpressionProtocolGuid,
+ (VOID**)&RegularExpressionProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ RegExSyntaxTypeListSize = 0;
+ RegExSyntaxTypeList = NULL;
+
+ Status = RegularExpressionProtocol->GetInfo (
+ RegularExpressionProtocol,
+ &RegExSyntaxTypeListSize,
+ RegExSyntaxTypeList
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ RegExSyntaxTypeList = AllocateZeroPool(RegExSyntaxTypeListSize);
+ if (RegExSyntaxTypeList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ Status = RegularExpressionProtocol->GetInfo (
+ RegularExpressionProtocol,
+ &RegExSyntaxTypeListSize,
+ RegExSyntaxTypeList
+ );
+ } else if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ for (GuidIndex = 0; GuidIndex < RegExSyntaxTypeListSize / sizeof(EFI_GUID); GuidIndex++) {
+ if (CompareGuid (&RegExSyntaxTypeList[GuidIndex], SyntaxType)) {
+ //
+ // Find the match type, return the value.
+ //
+ Result->Type = EFI_IFR_TYPE_BOOLEAN;
+ Status = RegularExpressionProtocol->MatchString (
+ RegularExpressionProtocol,
+ String[0],
+ String[1],
+ SyntaxType,
+ &Result->Value.b,
+ NULL,
+ &CapturesCount
+ );
+ goto Done;
+ }
+ }
+
+ if (RegExSyntaxTypeList != NULL) {
+ FreePool (RegExSyntaxTypeList);
+ }
+ }
+
+ //
+ // Type specified by SyntaxType is not supported
+ // in any of the EFI_REGULAR_EXPRESSION_PROTOCOL instances.
+ //
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
+
+Done:
+ if (String[0] != NULL) {
+ FreePool (String[0]);
+ }
+ if (String[1] != NULL) {
+ FreePool (String[1]);
+ }
+ if (RegExSyntaxTypeList != NULL) {
+ FreePool (RegExSyntaxTypeList);
+ }
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+ return Status;
+}
/**
Evaluate opcode EFI_IFR_FIND.
@@ -1021,24 +1666,38 @@ IfrFind (
)
{
EFI_STATUS Status;
- EFI_HII_VALUE Value;
+ EFI_HII_VALUE Value[3];
CHAR16 *String[2];
UINTN Base;
CHAR16 *StringPtr;
UINTN Index;
+ ZeroMem (Value, sizeof (Value));
+
if (Format > EFI_IFR_FF_CASE_INSENSITIVE) {
- return EFI_UNSUPPORTED;
+ return EFI_INVALID_PARAMETER;
}
- Status = PopExpression (&Value);
+ Status = PopExpression (&Value[0]);
if (EFI_ERROR (Status)) {
return Status;
}
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {
- return EFI_UNSUPPORTED;
+
+ Status = PopExpression (&Value[1]);
+ if (EFI_ERROR (Status)) {
+ return Status;
}
- Base = (UINTN) Value.Value.u64;
+
+ Status = PopExpression (&Value[2]);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
+ }
+ Base = (UINTN) Value[0].Value.u64;
//
// String[0] - sub-string
@@ -1047,17 +1706,13 @@ IfrFind (
String[0] = NULL;
String[1] = NULL;
for (Index = 0; Index < 2; Index++) {
- Status = PopExpression (&Value);
- if (EFI_ERROR (Status)) {
+ if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
goto Done;
}
- if (Value.Type != EFI_IFR_TYPE_STRING) {
- Status = EFI_UNSUPPORTED;
- goto Done;
- }
-
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);
+ String[Index] = GetToken (Value[Index + 1].Value.string, FormSet->HiiHandle);
if (String[Index] == NULL) {
Status = EFI_NOT_FOUND;
goto Done;
@@ -1108,41 +1763,49 @@ IfrMid (
)
{
EFI_STATUS Status;
- EFI_HII_VALUE Value;
+ EFI_HII_VALUE Value[3];
CHAR16 *String;
UINTN Base;
UINTN Length;
CHAR16 *SubString;
- UINT8 *Buffer;
UINT16 BufferLen;
+ UINT8 *Buffer;
- Status = PopExpression (&Value);
+ ZeroMem (Value, sizeof (Value));
+
+ Status = PopExpression (&Value[0]);
if (EFI_ERROR (Status)) {
return Status;
}
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {
- return EFI_UNSUPPORTED;
- }
- Length = (UINTN) Value.Value.u64;
- Status = PopExpression (&Value);
+ Status = PopExpression (&Value[1]);
if (EFI_ERROR (Status)) {
return Status;
}
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {
- return EFI_UNSUPPORTED;
- }
- Base = (UINTN) Value.Value.u64;
- Status = PopExpression (&Value);
+ Status = PopExpression (&Value[2]);
if (EFI_ERROR (Status)) {
return Status;
}
- if (Value.Type != EFI_IFR_TYPE_STRING && Value.Type != EFI_IFR_TYPE_BUFFER) {
- return EFI_UNSUPPORTED;
+
+ if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
}
- if (Value.Type == EFI_IFR_TYPE_STRING) {
- String = GetToken (Value.Value.string, FormSet->HiiHandle);
+ Length = (UINTN) Value[0].Value.u64;
+
+ if (Value[1].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
+ }
+ Base = (UINTN) Value[1].Value.u64;
+
+ if (Value[2].Type != EFI_IFR_TYPE_STRING && !IsTypeInBuffer(&Value[2])) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
+ }
+ if (Value[2].Type == EFI_IFR_TYPE_STRING) {
+ String = GetToken (Value[2].Value.string, FormSet->HiiHandle);
if (String == NULL) {
return EFI_NOT_FOUND;
}
@@ -1161,23 +1824,25 @@ IfrMid (
FreePool (String);
} else {
- Buffer = Value.Buffer;
- BufferLen = Value.BufferLen;
-
+ BufferLen = GetLengthForValue (&Value[2]);
+ Buffer = GetBufferForValue (&Value[2]);
+
Result->Type = EFI_IFR_TYPE_BUFFER;
if (Length == 0 || Base >= BufferLen) {
Result->BufferLen = 0;
Result->Buffer = NULL;
} else {
- Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length);
+ Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length);
Result->Buffer = AllocateZeroPool (Result->BufferLen);
ASSERT (Result->Buffer != NULL);
- CopyMem (Result->Buffer, &Value.Buffer[Base], Result->BufferLen);
+ CopyMem (Result->Buffer, &Buffer[Base], Result->BufferLen);
}
- FreePool (Value.Buffer);
+ if (Value[2].Type == EFI_IFR_TYPE_BUFFER) {
+ FreePool (Value[2].Buffer);
+ }
}
-
+
return Status;
}
@@ -1199,7 +1864,7 @@ IfrToken (
)
{
EFI_STATUS Status;
- EFI_HII_VALUE Value;
+ EFI_HII_VALUE Value[3];
CHAR16 *String[2];
UINTN Count;
CHAR16 *Delimiter;
@@ -1207,14 +1872,28 @@ IfrToken (
CHAR16 *StringPtr;
UINTN Index;
- Status = PopExpression (&Value);
+ ZeroMem (Value, sizeof (Value));
+
+ Status = PopExpression (&Value[0]);
if (EFI_ERROR (Status)) {
return Status;
}
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {
- return EFI_UNSUPPORTED;
+
+ Status = PopExpression (&Value[1]);
+ if (EFI_ERROR (Status)) {
+ return Status;
}
- Count = (UINTN) Value.Value.u64;
+
+ Status = PopExpression (&Value[2]);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
+ }
+ Count = (UINTN) Value[0].Value.u64;
//
// String[0] - Delimiter
@@ -1223,17 +1902,13 @@ IfrToken (
String[0] = NULL;
String[1] = NULL;
for (Index = 0; Index < 2; Index++) {
- Status = PopExpression (&Value);
- if (EFI_ERROR (Status)) {
+ if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
goto Done;
}
- if (Value.Type != EFI_IFR_TYPE_STRING) {
- Status = EFI_UNSUPPORTED;
- goto Done;
- }
-
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);
+ String[Index] = GetToken (Value[Index + 1].Value.string, FormSet->HiiHandle);
if (String[Index] == NULL) {
Status = EFI_NOT_FOUND;
goto Done;
@@ -1304,7 +1979,7 @@ IfrSpan (
)
{
EFI_STATUS Status;
- EFI_HII_VALUE Value;
+ EFI_HII_VALUE Value[3];
CHAR16 *String[2];
CHAR16 *Charset;
UINTN Base;
@@ -1312,14 +1987,28 @@ IfrSpan (
CHAR16 *StringPtr;
BOOLEAN Found;
- Status = PopExpression (&Value);
+ ZeroMem (Value, sizeof (Value));
+
+ Status = PopExpression (&Value[0]);
if (EFI_ERROR (Status)) {
return Status;
}
- if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {
- return EFI_UNSUPPORTED;
+
+ Status = PopExpression (&Value[1]);
+ if (EFI_ERROR (Status)) {
+ return Status;
}
- Base = (UINTN) Value.Value.u64;
+
+ Status = PopExpression (&Value[2]);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ return EFI_SUCCESS;
+ }
+ Base = (UINTN) Value[0].Value.u64;
//
// String[0] - Charset
@@ -1328,17 +2017,13 @@ IfrSpan (
String[0] = NULL;
String[1] = NULL;
for (Index = 0; Index < 2; Index++) {
- Status = PopExpression (&Value);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- if (Value.Type != EFI_IFR_TYPE_STRING) {
- Status = EFI_UNSUPPORTED;
+ if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
goto Done;
}
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);
+ String[Index] = GetToken (Value[Index + 1].Value.string, FormSet->HiiHandle);
if (String [Index] == NULL) {
Status = EFI_NOT_FOUND;
goto Done;
@@ -1346,7 +2031,8 @@ IfrSpan (
}
if (Base >= StrLen (String[1])) {
- Status = EFI_UNSUPPORTED;
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
goto Done;
}
@@ -1439,47 +2125,89 @@ ExtendValueToU64 (
Value->Value.u64 = Temp;
}
+/**
+ Get UINT64 type value.
+
+ @param Value Input Hii value.
+
+ @retval UINT64 Return the UINT64 type value.
+
+**/
+UINT64
+HiiValueToUINT64 (
+ IN EFI_HII_VALUE *Value
+ )
+{
+ UINT64 RetVal;
+
+ RetVal = 0;
+
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ RetVal = Value->Value.u8;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ RetVal = Value->Value.u16;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ RetVal = Value->Value.u32;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ RetVal = Value->Value.b;
+ break;
+
+ case EFI_IFR_TYPE_DATE:
+ RetVal = *(UINT64*) &Value->Value.date;
+ break;
+
+ case EFI_IFR_TYPE_TIME:
+ RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff;
+ break;
+
+ default:
+ RetVal = Value->Value.u64;
+ break;
+ }
+
+ return RetVal;
+}
/**
Compare two Hii value.
@param Value1 Expression value to compare on left-hand.
@param Value2 Expression value to compare on right-hand.
+ @param Result Return value after compare.
+ retval 0 Two operators equal.
+ return Positive value if Value1 is greater than Value2.
+ retval Negative value if Value1 is less than Value2.
@param HiiHandle Only required for string compare.
- @retval EFI_INVALID_PARAMETER Could not perform compare on two values.
- @retval 0 Two operators equal.
- @return Positive value if Value1 is greater than Value2.
- @retval Negative value if Value1 is less than Value2.
+ @retval other Could not perform compare on two values.
+ @retval EFI_SUCCESS Compare the value success.
**/
-INTN
+EFI_STATUS
CompareHiiValue (
IN EFI_HII_VALUE *Value1,
IN EFI_HII_VALUE *Value2,
+ OUT INTN *Result,
IN EFI_HII_HANDLE HiiHandle OPTIONAL
)
{
- INTN Result;
INT64 Temp64;
CHAR16 *Str1;
CHAR16 *Str2;
UINTN Len;
+ UINT8 *Buf1;
+ UINT16 Buf1Len;
+ UINT8 *Buf2;
+ UINT16 Buf2Len;
- if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {
- if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) {
- return EFI_INVALID_PARAMETER;
- }
- }
-
- if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {
- if (Value1->Type != Value2->Type) {
- //
- // Both Operator should be type of String
- //
- return EFI_INVALID_PARAMETER;
- }
-
+ if (Value1->Type == EFI_IFR_TYPE_STRING && Value2->Type == EFI_IFR_TYPE_STRING) {
if (Value1->Value.string == 0 || Value2->Value.string == 0) {
//
// StringId 0 is reserved
@@ -1488,7 +2216,8 @@ CompareHiiValue (
}
if (Value1->Value.string == Value2->Value.string) {
- return 0;
+ *Result = 0;
+ return EFI_SUCCESS;
}
Str1 = GetToken (Value1->Value.string, HiiHandle);
@@ -1496,56 +2225,61 @@ CompareHiiValue (
//
// String not found
//
- return EFI_INVALID_PARAMETER;
+ return EFI_NOT_FOUND;
}
Str2 = GetToken (Value2->Value.string, HiiHandle);
if (Str2 == NULL) {
FreePool (Str1);
- return EFI_INVALID_PARAMETER;
+ return EFI_NOT_FOUND;
}
- Result = StrCmp (Str1, Str2);
+ *Result = StrCmp (Str1, Str2);
FreePool (Str1);
FreePool (Str2);
- return Result;
+ return EFI_SUCCESS;
}
- if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) {
- if (Value1->Type != Value2->Type) {
- //
- // Both Operator should be type of Buffer.
- //
- return EFI_INVALID_PARAMETER;
- }
- Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen;
- Result = CompareMem (Value1->Buffer, Value2->Buffer, Len);
- if ((Result == 0) && (Value1->BufferLen != Value2->BufferLen))
- {
+ //
+ // Take types(date, time, ref, buffer) as buffer
+ //
+ if (IsTypeInBuffer(Value1) && IsTypeInBuffer(Value2)) {
+ Buf1 = GetBufferForValue(Value1);
+ Buf1Len = GetLengthForValue(Value1);
+ Buf2 = GetBufferForValue(Value2);
+ Buf2Len = GetLengthForValue(Value2);
+
+ Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len;
+ *Result = CompareMem (Buf1, Buf2, Len);
+ if ((*Result == 0) && (Buf1Len != Buf2Len)) {
//
// In this case, means base on samll number buffer, the data is same
// So which value has more data, which value is bigger.
//
- Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1;
+ *Result = Buf1Len > Buf2Len ? 1 : -1;
}
- return Result;
- }
+ return EFI_SUCCESS;
+ }
//
- // Take remain types(integer, boolean, date/time) as integer
+ // Take types(integer, boolean) as integer
//
- Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);
- if (Temp64 > 0) {
- Result = 1;
- } else if (Temp64 < 0) {
- Result = -1;
- } else {
- Result = 0;
+ if (IsTypeInUINT64(Value1) && IsTypeInUINT64(Value2)) {
+ Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);
+ if (Temp64 > 0) {
+ *Result = 1;
+ } else if (Temp64 < 0) {
+ *Result = -1;
+ } else {
+ *Result = 0;
+ }
+
+ return EFI_SUCCESS;
}
- return Result;
+ return EFI_UNSUPPORTED;
}
/**
@@ -1594,7 +2328,7 @@ CheckUserPrivilege (
/// Enumerate all user information of the current user profile
/// to look for any EFI_USER_INFO_ACCESS_SETUP record.
///
-
+
for (UserInfoHandle = NULL;;) {
Status = mUserManager->GetNextInfo (mUserManager, UserProfileHandle, &UserInfoHandle);
if (EFI_ERROR (Status)) {
@@ -1631,24 +2365,136 @@ CheckUserPrivilege (
/// Check if current user has the privilege specified by the permissions GUID.
///
- UserPermissionsGuid = (EFI_GUID *)(AccessControl + 1);
- AccessControlDataSize = AccessControl->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);
- while (AccessControlDataSize >= sizeof (EFI_GUID)) {
- if (CompareGuid (Guid, UserPermissionsGuid)) {
- FreePool (UserInfo);
- return TRUE;
- }
- UserPermissionsGuid++;
- AccessControlDataSize -= sizeof (EFI_GUID);
- }
- }
- RemainSize -= AccessControl->Size;
- AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)((UINT8 *)AccessControl + AccessControl->Size);
+ UserPermissionsGuid = (EFI_GUID *)(AccessControl + 1);
+ AccessControlDataSize = AccessControl->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);
+ while (AccessControlDataSize >= sizeof (EFI_GUID)) {
+ if (CompareGuid (Guid, UserPermissionsGuid)) {
+ FreePool (UserInfo);
+ return TRUE;
+ }
+ UserPermissionsGuid++;
+ AccessControlDataSize -= sizeof (EFI_GUID);
+ }
+ }
+ RemainSize -= AccessControl->Size;
+ AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)((UINT8 *)AccessControl + AccessControl->Size);
+ }
+
+ FreePool (UserInfo);
+ }
+ return FALSE;
+}
+
+/**
+ Get question value from the predefined formset.
+
+ @param DevicePath The driver's device path which produece the formset data.
+ @param InputHiiHandle The hii handle associate with the formset data.
+ @param FormSetGuid The formset guid which include the question.
+ @param QuestionId The question id which need to get value from.
+ @param Value The return data about question's value.
+
+ @retval TRUE Get the question value success.
+ @retval FALSE Get the question value failed.
+**/
+BOOLEAN
+GetQuestionValueFromForm (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HII_HANDLE InputHiiHandle,
+ IN EFI_GUID *FormSetGuid,
+ IN EFI_QUESTION_ID QuestionId,
+ OUT EFI_HII_VALUE *Value
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ FORM_BROWSER_STATEMENT *Question;
+ FORM_BROWSER_FORMSET *FormSet;
+ FORM_BROWSER_FORM *Form;
+ BOOLEAN GetTheVal;
+ LIST_ENTRY *Link;
+
+ //
+ // The input parameter DevicePath or InputHiiHandle must have one valid input.
+ //
+ ASSERT ((DevicePath != NULL && InputHiiHandle == NULL) ||
+ (DevicePath == NULL && InputHiiHandle != NULL) );
+
+ GetTheVal = TRUE;
+ HiiHandle = NULL;
+ Question = NULL;
+ Form = NULL;
+
+ //
+ // Get HiiHandle.
+ //
+ if (DevicePath != NULL) {
+ HiiHandle = DevicePathToHiiHandle (DevicePath, FormSetGuid);
+ if (HiiHandle == NULL) {
+ return FALSE;
+ }
+ } else {
+ HiiHandle = InputHiiHandle;
+ }
+ ASSERT (HiiHandle != NULL);
+
+ //
+ // Get the formset data include this question.
+ //
+ FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
+ ASSERT (FormSet != NULL);
+ Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet);
+ if (EFI_ERROR (Status)) {
+ GetTheVal = FALSE;
+ goto Done;
+ }
+
+ //
+ // Base on the Question Id to get the question info.
+ //
+ Question = IdToQuestion(FormSet, NULL, QuestionId);
+ if (Question == NULL) {
+ GetTheVal = FALSE;
+ goto Done;
+ }
+
+ //
+ // Search form in the formset scope
+ //
+ Link = GetFirstNode (&FormSet->FormListHead);
+ while (!IsNull (&FormSet->FormListHead, Link)) {
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);
+
+ Question = IdToQuestion2 (Form, QuestionId);
+ if (Question != NULL) {
+ break;
}
- FreePool (UserInfo);
+ Link = GetNextNode (&FormSet->FormListHead, Link);
+ Form = NULL;
}
- return FALSE;
+ ASSERT (Form != NULL);
+
+ //
+ // Get the question value.
+ //
+ Status = GetQuestionValue(FormSet, Form, Question, GetSetValueWithEditBuffer);
+ if (EFI_ERROR (Status)) {
+ GetTheVal = FALSE;
+ goto Done;
+ }
+
+ CopyMem (Value, &Question->HiiValue, sizeof (EFI_HII_VALUE));
+
+Done:
+ //
+ // Clean the formset structure and restore the global parameter.
+ //
+ if (FormSet != NULL) {
+ DestroyFormSet (FormSet);
+ }
+
+ return GetTheVal;
}
/**
@@ -1699,6 +2545,10 @@ EvaluateExpression (
UINT8 DigitUint8;
UINT8 *TempBuffer;
EFI_TIME EfiTime;
+ EFI_HII_VALUE QuestionVal;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ StrPtr = NULL;
//
// Save current stack offset.
@@ -1729,13 +2579,18 @@ EvaluateExpression (
case EFI_IFR_EQ_ID_VAL_OP:
Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
if (Question == NULL) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
- Result = CompareHiiValue (&Question->HiiValue, &OpCode->Value, NULL);
- if (Result == EFI_INVALID_PARAMETER) {
- Status = EFI_INVALID_PARAMETER;
+ Status = CompareHiiValue (&Question->HiiValue, &OpCode->Value, &Result, NULL);
+ if (Status == EFI_UNSUPPORTED) {
+ Status = EFI_SUCCESS;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+
+ if (EFI_ERROR (Status)) {
goto Done;
}
Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);
@@ -1744,29 +2599,33 @@ EvaluateExpression (
case EFI_IFR_EQ_ID_ID_OP:
Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
if (Question == NULL) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2);
if (Question2 == NULL) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
- Result = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, FormSet->HiiHandle);
- if (Result == EFI_INVALID_PARAMETER) {
- Status = EFI_INVALID_PARAMETER;
+ Status = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, &Result, FormSet->HiiHandle);
+ if (Status == EFI_UNSUPPORTED) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
+ break;
+ }
+ if (EFI_ERROR (Status)) {
goto Done;
}
Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);
break;
- case EFI_IFR_EQ_ID_LIST_OP:
+ case EFI_IFR_EQ_ID_VAL_LIST_OP:
Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
if (Question == NULL) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
Value->Value.b = FALSE;
@@ -1823,7 +2682,7 @@ EvaluateExpression (
//
// Get value from string except for STRING value.
//
- Status = GetValueByName (OpCode->VarStorage, OpCode->ValueName, &StrPtr);
+ Status = GetValueByName (OpCode->VarStorage, OpCode->ValueName, &StrPtr, GetSetValueWithEditBuffer);
if (!EFI_ERROR (Status)) {
ASSERT (StrPtr != NULL);
TempLength = StrLen (StrPtr);
@@ -1840,7 +2699,7 @@ EvaluateExpression (
TempBuffer [Index/2] = (UINT8) ((DigitUint8 << 4) + TempBuffer [Index/2]);
}
}
- }
+ }
}
}
break;
@@ -1931,41 +2790,57 @@ EvaluateExpression (
break;
case EFI_IFR_QUESTION_REF3_OP:
- if (OpCode->DevicePath == 0) {
- //
- // EFI_IFR_QUESTION_REF3
- // Pop an expression from the expression stack
- //
- Status = PopExpression (Value);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
+ //
+ // EFI_IFR_QUESTION_REF3
+ // Pop an expression from the expression stack
+ //
+ Status = PopExpression (Value);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
- //
- // Validate the expression value
- //
- if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ //
+ // Validate the expression value
+ //
+ if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+
+ if (OpCode->DevicePath != 0) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+
+ StrPtr = GetToken (OpCode->DevicePath, FormSet->HiiHandle);
+ if (StrPtr != NULL && mPathFromText != NULL) {
+ DevicePath = mPathFromText->ConvertTextToDevicePath(StrPtr);
+ if (DevicePath != NULL && GetQuestionValueFromForm(DevicePath, NULL, &OpCode->Guid, Value->Value.u16, &QuestionVal)) {
+ Value = &QuestionVal;
+ }
+ if (DevicePath != NULL) {
+ FreePool (DevicePath);
+ }
}
+ if (StrPtr != NULL) {
+ FreePool (StrPtr);
+ }
+ } else if (IsZeroGuid (&OpCode->Guid)) {
+ if (!GetQuestionValueFromForm(NULL, FormSet->HiiHandle, &OpCode->Guid, Value->Value.u16, &QuestionVal)){
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+ Value = &QuestionVal;
+ } else {
Question = IdToQuestion (FormSet, Form, Value->Value.u16);
if (Question == NULL) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
//
// push the questions' value on to the expression stack
//
Value = &Question->HiiValue;
- } else {
- //
- // BUGBUG: push 0 for EFI_IFR_QUESTION_REF3_2 and EFI_IFR_QUESTION_REF3_3,
- // since it is impractical to evaluate the value of a Question in another
- // Hii Package list.
- //
- ZeroMem (Value, sizeof (EFI_HII_VALUE));
}
break;
@@ -1975,16 +2850,17 @@ EvaluateExpression (
//
RuleExpression = RuleIdToExpression (Form, OpCode->RuleId);
if (RuleExpression == NULL) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
//
// Evaluate this rule expression
//
Status = EvaluateExpression (FormSet, Form, RuleExpression);
- if (EFI_ERROR (Status)) {
- goto Done;
+ if (EFI_ERROR (Status) || RuleExpression->Result.Type == EFI_IFR_TYPE_UNDEFINED) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
Value = &RuleExpression->Result;
@@ -2020,9 +2896,9 @@ EvaluateExpression (
if (EFI_ERROR (Status)) {
goto Done;
}
- if (Value->Type != EFI_IFR_TYPE_STRING && Value->Type != EFI_IFR_TYPE_BUFFER) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
+ if (Value->Type != EFI_IFR_TYPE_STRING && !IsTypeInBuffer (Value)) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
if (Value->Type == EFI_IFR_TYPE_STRING) {
@@ -2037,7 +2913,7 @@ EvaluateExpression (
FreePool (StrPtr);
} else {
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
- Value->Value.u64 = Value->BufferLen;
+ Value->Value.u64 = GetLengthForValue(Value);
FreePool (Value->Buffer);
}
break;
@@ -2048,8 +2924,8 @@ EvaluateExpression (
goto Done;
}
if (Value->Type != EFI_IFR_TYPE_BOOLEAN) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
Value->Value.b = (BOOLEAN) (!Value->Value.b);
break;
@@ -2067,14 +2943,14 @@ EvaluateExpression (
// Validate the expression value
//
if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
Question = IdToQuestion (FormSet, Form, Value->Value.u16);
if (Question == NULL) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
Value = &Question->HiiValue;
@@ -2093,8 +2969,8 @@ EvaluateExpression (
// Validate the expression value
//
if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
- Status = EFI_NOT_FOUND;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
Value->Type = EFI_IFR_TYPE_STRING;
@@ -2128,40 +3004,39 @@ EvaluateExpression (
// When converting from an unsigned integer, zero will be converted to
// FALSE and any other value will be converted to TRUE.
//
- Value->Value.b = (BOOLEAN) (Value->Value.u64 != 0);
+ Value->Value.b = (BOOLEAN) (HiiValueToUINT64(Value) != 0);
Value->Type = EFI_IFR_TYPE_BOOLEAN;
} else if (Value->Type == EFI_IFR_TYPE_STRING) {
//
// When converting from a string, if case-insensitive compare
// with "true" is True, then push True. If a case-insensitive compare
- // with "false" is True, then push False. Otherwise, push Undefined.
+ // with "false" is True, then push False. Otherwise, push Undefined.
//
StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);
if (StrPtr == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}
-
+
IfrStrToUpper (StrPtr);
if (StrCmp (StrPtr, L"TRUE") == 0){
Value->Value.b = TRUE;
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;
} else if (StrCmp (StrPtr, L"FALSE") == 0) {
Value->Value.b = FALSE;
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;
} else {
- Status = EFI_INVALID_PARAMETER;
- FreePool (StrPtr);
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
}
FreePool (StrPtr);
- Value->Type = EFI_IFR_TYPE_BOOLEAN;
} else if (Value->Type == EFI_IFR_TYPE_BUFFER) {
//
- // When converting from a buffer, if the buffer is all zeroes,
- // then push False. Otherwise push True.
+ // When converting from a buffer, if the buffer is all zeroes,
+ // then push False. Otherwise push True.
//
for (Index =0; Index < Value->BufferLen; Index ++) {
- if (Value->Buffer[Index] != 0) {
+ if (Value->Buffer[Index] != 0) {
break;
}
}
@@ -2197,8 +3072,8 @@ EvaluateExpression (
}
if (Value->Type != EFI_IFR_TYPE_STRING) {
- Status = EFI_UNSUPPORTED;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);
@@ -2225,12 +3100,12 @@ EvaluateExpression (
goto Done;
}
if (Value->Type > EFI_IFR_TYPE_DATE) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
- Value->Value.u64 = ~Value->Value.u64;
+ Value->Value.u64 = ~ HiiValueToUINT64(Value);
break;
case EFI_IFR_SET_OP:
@@ -2256,16 +3131,23 @@ EvaluateExpression (
case EFI_HII_VARSTORE_NAME_VALUE:
if (OpCode->ValueType != EFI_IFR_TYPE_STRING) {
NameValue = AllocateZeroPool ((OpCode->ValueWidth * 2 + 1) * sizeof (CHAR16));
- ASSERT (Value != NULL);
+ ASSERT (NameValue != NULL);
//
// Convert Buffer to Hex String
//
TempBuffer = (UINT8 *) &Value->Value + OpCode->ValueWidth - 1;
StrPtr = NameValue;
for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {
- StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);
+ UnicodeValueToStringS (
+ StrPtr,
+ (OpCode->ValueWidth * 2 + 1) * sizeof (CHAR16) - ((UINTN)StrPtr - (UINTN)NameValue),
+ PREFIX_ZERO | RADIX_HEX,
+ *TempBuffer,
+ 2
+ );
+ StrPtr += StrnLenS (StrPtr, OpCode->ValueWidth * 2 + 1 - ((UINTN)StrPtr - (UINTN)NameValue) / sizeof (CHAR16));
}
- Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, TRUE);
+ Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer, NULL);
FreePool (NameValue);
if (!EFI_ERROR (Status)) {
Data1.Value.b = TRUE;
@@ -2290,7 +3172,6 @@ EvaluateExpression (
//
Status = EFI_UNSUPPORTED;
goto Done;
- break;
}
} else {
//
@@ -2370,10 +3251,6 @@ EvaluateExpression (
if (EFI_ERROR (Status)) {
goto Done;
}
- if (Data2.Type > EFI_IFR_TYPE_DATE) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
//
// Pop another expression from the expression stack
@@ -2382,49 +3259,56 @@ EvaluateExpression (
if (EFI_ERROR (Status)) {
goto Done;
}
+
+ if (Data2.Type > EFI_IFR_TYPE_DATE) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+
+
if (Data1.Type > EFI_IFR_TYPE_DATE) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
switch (OpCode->Operand) {
case EFI_IFR_ADD_OP:
- Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64;
+ Value->Value.u64 = HiiValueToUINT64(&Data1) + HiiValueToUINT64(&Data2);
break;
case EFI_IFR_SUBTRACT_OP:
- Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64;
+ Value->Value.u64 = HiiValueToUINT64(&Data1) - HiiValueToUINT64(&Data2);
break;
case EFI_IFR_MULTIPLY_OP:
- Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);
+ Value->Value.u64 = MultU64x32 (HiiValueToUINT64(&Data1), (UINT32) HiiValueToUINT64(&Data2));
break;
case EFI_IFR_DIVIDE_OP:
- Value->Value.u64 = DivU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);
+ Value->Value.u64 = DivU64x32 (HiiValueToUINT64(&Data1), (UINT32) HiiValueToUINT64(&Data2));
break;
case EFI_IFR_MODULO_OP:
- DivU64x32Remainder (Data1.Value.u64, (UINT32) Data2.Value.u64, &TempValue);
+ DivU64x32Remainder (HiiValueToUINT64(&Data1), (UINT32) HiiValueToUINT64(&Data2), &TempValue);
Value->Value.u64 = TempValue;
break;
case EFI_IFR_BITWISE_AND_OP:
- Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64;
+ Value->Value.u64 = HiiValueToUINT64(&Data1) & HiiValueToUINT64(&Data2);
break;
case EFI_IFR_BITWISE_OR_OP:
- Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64;
+ Value->Value.u64 = HiiValueToUINT64(&Data1) | HiiValueToUINT64(&Data2);
break;
case EFI_IFR_SHIFT_LEFT_OP:
- Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);
+ Value->Value.u64 = LShiftU64 (HiiValueToUINT64(&Data1), (UINTN) HiiValueToUINT64(&Data2));
break;
case EFI_IFR_SHIFT_RIGHT_OP:
- Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);
+ Value->Value.u64 = RShiftU64 (HiiValueToUINT64(&Data1), (UINTN) HiiValueToUINT64(&Data2));
break;
default:
@@ -2441,10 +3325,6 @@ EvaluateExpression (
if (EFI_ERROR (Status)) {
goto Done;
}
- if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
//
// Pop another expression from the expression stack
@@ -2453,9 +3333,15 @@ EvaluateExpression (
if (EFI_ERROR (Status)) {
goto Done;
}
+
+ if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+
if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
if (OpCode->Operand == EFI_IFR_AND_OP) {
@@ -2478,12 +3364,6 @@ EvaluateExpression (
if (EFI_ERROR (Status)) {
goto Done;
}
- if (Data2.Type > EFI_IFR_TYPE_BOOLEAN &&
- Data2.Type != EFI_IFR_TYPE_STRING &&
- Data2.Type != EFI_IFR_TYPE_BUFFER) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
//
// Pop another expression from the expression stack
@@ -2493,14 +3373,35 @@ EvaluateExpression (
goto Done;
}
- Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle);
+ if (Data2.Type > EFI_IFR_TYPE_BOOLEAN &&
+ Data2.Type != EFI_IFR_TYPE_STRING &&
+ !IsTypeInBuffer(&Data2)) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+
+ if (Data1.Type > EFI_IFR_TYPE_BOOLEAN &&
+ Data1.Type != EFI_IFR_TYPE_STRING &&
+ !IsTypeInBuffer(&Data1)) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+
+ Status = CompareHiiValue (&Data1, &Data2, &Result, FormSet->HiiHandle);
if (Data1.Type == EFI_IFR_TYPE_BUFFER) {
FreePool (Data1.Buffer);
+ }
+ if (Data2.Type == EFI_IFR_TYPE_BUFFER) {
FreePool (Data2.Buffer);
}
-
- if (Result == EFI_INVALID_PARAMETER) {
- Status = EFI_INVALID_PARAMETER;
+
+ if (Status == EFI_UNSUPPORTED) {
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ if (EFI_ERROR (Status)) {
goto Done;
}
@@ -2539,10 +3440,14 @@ EvaluateExpression (
if (EFI_ERROR (Status)) {
goto Done;
}
-
+
Status = IfrMatch (FormSet, Value);
break;
+ case EFI_IFR_MATCH2_OP:
+ Status = IfrMatch2 (FormSet, &OpCode->Guid, Value);
+ break;
+
case EFI_IFR_CATENATE_OP:
Status = IfrCatenate (FormSet, Value);
break;
@@ -2575,8 +3480,8 @@ EvaluateExpression (
goto Done;
}
if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
}
if (Data1.Value.b) {
@@ -2633,7 +3538,7 @@ EvaluateExpression (
//
// Compare the expression value with current value
//
- if (CompareHiiValue (&Data1, &SubExpression->Result, NULL) == 0) {
+ if ((CompareHiiValue (&Data1, &SubExpression->Result, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
//
// Try get the map value.
//
@@ -2676,7 +3581,7 @@ EvaluateExpression (
default:
break;
}
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || Value->Type == EFI_IFR_TYPE_UNDEFINED) {
goto Done;
}
@@ -2710,3 +3615,117 @@ Done:
return Status;
}
+
+/**
+ Check whether the result is TRUE or FALSE.
+
+ For the EFI_HII_VALUE value type is numeric, return TRUE if the
+ value is not 0.
+
+ @param Result Input the result data.
+
+ @retval TRUE The result is TRUE.
+ @retval FALSE The result is FALSE.
+
+**/
+BOOLEAN
+IsTrue (
+ IN EFI_HII_VALUE *Result
+ )
+{
+ switch (Result->Type) {
+ case EFI_IFR_TYPE_BOOLEAN:
+ return Result->Value.b;
+
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ return (BOOLEAN)(Result->Value.u8 != 0);
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ return (BOOLEAN)(Result->Value.u16 != 0);
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ return (BOOLEAN)(Result->Value.u32 != 0);
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ return (BOOLEAN)(Result->Value.u64 != 0);
+
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ Return the result of the expression list. Check the expression list and
+ return the highest priority express result.
+ Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
+
+ @param ExpList The input expression list.
+ @param Evaluate Whether need to evaluate the expression first.
+ @param FormSet FormSet associated with this expression.
+ @param Form Form associated with this expression.
+
+ @retval EXPRESS_RESULT Return the higher priority express result.
+ DisableIf > SuppressIf > GrayOutIf > FALSE
+
+**/
+EXPRESS_RESULT
+EvaluateExpressionList (
+ IN FORM_EXPRESSION_LIST *ExpList,
+ IN BOOLEAN Evaluate,
+ IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL
+ IN FORM_BROWSER_FORM *Form OPTIONAL
+ )
+{
+ UINTN Index;
+ EXPRESS_RESULT ReturnVal;
+ EXPRESS_RESULT CompareOne;
+ EFI_STATUS Status;
+
+ if (ExpList == NULL) {
+ return ExpressFalse;
+ }
+
+ ASSERT(ExpList->Signature == FORM_EXPRESSION_LIST_SIGNATURE);
+ Index = 0;
+
+ //
+ // Check whether need to evaluate the expression first.
+ //
+ if (Evaluate) {
+ while (ExpList->Count > Index) {
+ Status = EvaluateExpression (FormSet, Form, ExpList->Expression[Index++]);
+ if (EFI_ERROR (Status)) {
+ return ExpressFalse;
+ }
+ }
+ }
+
+ //
+ // Run the list of expressions.
+ //
+ ReturnVal = ExpressFalse;
+ for (Index = 0; Index < ExpList->Count; Index++) {
+ if (IsTrue (&ExpList->Expression[Index]->Result)) {
+ switch (ExpList->Expression[Index]->Type) {
+ case EFI_HII_EXPRESSION_SUPPRESS_IF:
+ CompareOne = ExpressSuppress;
+ break;
+
+ case EFI_HII_EXPRESSION_GRAY_OUT_IF:
+ CompareOne = ExpressGrayOut;
+ break;
+
+ case EFI_HII_EXPRESSION_DISABLE_IF:
+ CompareOne = ExpressDisable;
+ break;
+
+ default:
+ return ExpressFalse;
+ }
+
+ ReturnVal = ReturnVal < CompareOne ? CompareOne : ReturnVal;
+ }
+ }
+
+ return ReturnVal;
+}