X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FSetupBrowserDxe%2FExpression.c;h=92a4727b46d49dc1b832db95dd826455dd4be539;hb=e6106e892d5fb4662b5dccf2891451b0e4bfe3e5;hp=883693fde59233acd397001b1bf3d8b290bb5246;hpb=901ba0e78d02bd4407571c296871f96a0d225698;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c index 883693fde5..92a4727b46 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c @@ -1,7 +1,7 @@ /** @file Utility functions for expression evaluation. -Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2013, 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 @@ -34,6 +34,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 // @@ -194,7 +207,10 @@ ResetCurrentExpressionStack ( VOID ) { - mCurrentExpressionPointer = mCurrentExpressionStack; + mCurrentExpressionPointer = mCurrentExpressionStack; + mFormExpressionPointer = mFormExpressionStack; + mStatementExpressionPointer = mStatementExpressionStack; + mOptionExpressionPointer = mOptionExpressionStack; } @@ -267,6 +283,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 @@ -483,7 +787,7 @@ FORM_BROWSER_FORM * IdToForm ( IN FORM_BROWSER_FORMSET *FormSet, IN UINT16 FormId -) + ) { LIST_ENTRY *Link; FORM_BROWSER_FORM *Form; @@ -522,7 +826,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 +891,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; @@ -737,7 +1041,8 @@ IfrToString ( break; default: - return EFI_UNSUPPORTED; + Result->Type = EFI_IFR_TYPE_UNDEFINED; + return EFI_SUCCESS; } UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64); String = Buffer; @@ -757,6 +1062,7 @@ IfrToString ( // so need 1 byte to align, also need 2 bytes for L'\0'. // TmpBuf = AllocateZeroPool (Value.BufferLen + 3); + ASSERT (TmpBuf != NULL); if (Format == EFI_IFR_STRING_ASCII) { CopyMem (TmpBuf, Value.Buffer, Value.BufferLen); PrintFormat = L"%a"; @@ -765,14 +1071,15 @@ IfrToString ( CopyMem (TmpBuf, Value.Buffer, Value.BufferLen * sizeof (CHAR16)); PrintFormat = L"%s"; } - UnicodeSPrint (Buffer, MAXIMUM_VALUE_CHARACTERS, PrintFormat, Value.Buffer); + UnicodeSPrint (Buffer, sizeof (Buffer), PrintFormat, Value.Buffer); String = Buffer; FreePool (TmpBuf); FreePool (Value.Buffer); break; default: - return EFI_UNSUPPORTED; + Result->Type = EFI_IFR_TYPE_UNDEFINED; + return EFI_SUCCESS; } Result->Type = EFI_IFR_TYPE_STRING; @@ -808,7 +1115,8 @@ IfrToUint ( } if (Value.Type >= EFI_IFR_TYPE_OTHER && Value.Type != EFI_IFR_TYPE_BUFFER) { - return EFI_UNSUPPORTED; + Result->Type = EFI_IFR_TYPE_UNDEFINED; + return EFI_SUCCESS; } Status = EFI_SUCCESS; @@ -835,7 +1143,8 @@ IfrToUint ( } else if (Value.Type == EFI_IFR_TYPE_BUFFER) { if (Value.BufferLen > 8) { FreePool (Value.Buffer); - return EFI_UNSUPPORTED; + Result->Type = EFI_IFR_TYPE_UNDEFINED; + return EFI_SUCCESS; } Result->Value.u64 = *(UINT64*) Value.Buffer; FreePool (Value.Buffer); @@ -881,14 +1190,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; + } + Status = PopExpression (&Value[1]); + if (EFI_ERROR (Status)) { + goto Done; + } + + for (Index = 0; Index < 2; Index++) { if (Value[Index].Type != EFI_IFR_TYPE_STRING && Value[Index].Type != EFI_IFR_TYPE_BUFFER) { - Status = EFI_UNSUPPORTED; + Result->Type = EFI_IFR_TYPE_UNDEFINED; + Status = EFI_SUCCESS; goto Done; } @@ -958,7 +1273,7 @@ IfrMatch ( ) { EFI_STATUS Status; - EFI_HII_VALUE Value; + EFI_HII_VALUE Value[2]; CHAR16 *String[2]; UINTN Index; @@ -969,18 +1284,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; @@ -1021,24 +1344,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; + } + + Status = PopExpression (&Value[1]); if (EFI_ERROR (Status)) { return Status; } - if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) { - return EFI_UNSUPPORTED; + + 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.Value.u64; + Base = (UINTN) Value[0].Value.u64; // // String[0] - sub-string @@ -1047,17 +1384,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 +1441,48 @@ 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; - 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[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) { + Result->Type = EFI_IFR_TYPE_UNDEFINED; + return EFI_SUCCESS; } - if (Value.Type != EFI_IFR_TYPE_STRING && Value.Type != EFI_IFR_TYPE_BUFFER) { - return EFI_UNSUPPORTED; + 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; } - if (Value.Type == EFI_IFR_TYPE_STRING) { - String = GetToken (Value.Value.string, FormSet->HiiHandle); + Base = (UINTN) Value[1].Value.u64; + + if (Value[2].Type != EFI_IFR_TYPE_STRING && Value[2].Type != EFI_IFR_TYPE_BUFFER) { + 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,8 +1501,7 @@ IfrMid ( FreePool (String); } else { - Buffer = Value.Buffer; - BufferLen = Value.BufferLen; + BufferLen = Value[2].BufferLen; Result->Type = EFI_IFR_TYPE_BUFFER; if (Length == 0 || Base >= BufferLen) { @@ -1172,10 +1511,10 @@ IfrMid ( 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, &Value[2].Buffer[Base], Result->BufferLen); } - FreePool (Value.Buffer); + FreePool (Value[2].Buffer); } return Status; @@ -1199,7 +1538,7 @@ IfrToken ( ) { EFI_STATUS Status; - EFI_HII_VALUE Value; + EFI_HII_VALUE Value[3]; CHAR16 *String[2]; UINTN Count; CHAR16 *Delimiter; @@ -1207,14 +1546,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 +1576,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 +1653,7 @@ IfrSpan ( ) { EFI_STATUS Status; - EFI_HII_VALUE Value; + EFI_HII_VALUE Value[3]; CHAR16 *String[2]; CHAR16 *Charset; UINTN Base; @@ -1312,14 +1661,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; + } + + 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.Value.u64; + Base = (UINTN) Value[0].Value.u64; // // String[0] - Charset @@ -1328,17 +1691,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 +1705,8 @@ IfrSpan ( } if (Base >= StrLen (String[1])) { - Status = EFI_UNSUPPORTED; + Result->Type = EFI_IFR_TYPE_UNDEFINED; + Status = EFI_SUCCESS; goto Done; } @@ -1439,28 +1799,79 @@ 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; @@ -1468,7 +1879,7 @@ CompareHiiValue ( 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; + return EFI_UNSUPPORTED; } } @@ -1477,7 +1888,7 @@ CompareHiiValue ( // // Both Operator should be type of String // - return EFI_INVALID_PARAMETER; + return EFI_UNSUPPORTED; } if (Value1->Value.string == 0 || Value2->Value.string == 0) { @@ -1488,7 +1899,8 @@ CompareHiiValue ( } if (Value1->Value.string == Value2->Value.string) { - return 0; + *Result = 0; + return EFI_SUCCESS; } Str1 = GetToken (Value1->Value.string, HiiHandle); @@ -1496,21 +1908,21 @@ 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 ) { @@ -1518,34 +1930,34 @@ CompareHiiValue ( // // Both Operator should be type of Buffer. // - return EFI_INVALID_PARAMETER; + return EFI_UNSUPPORTED; } Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen; - Result = CompareMem (Value1->Buffer, Value2->Buffer, Len); - if ((Result == 0) && (Value1->BufferLen != Value2->BufferLen)) + *Result = CompareMem (Value1->Buffer, Value2->Buffer, Len); + if ((*Result == 0) && (Value1->BufferLen != Value2->BufferLen)) { // // 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 = Value1->BufferLen > Value2->BufferLen ? 1 : -1; } - return Result; + return EFI_SUCCESS; } // // Take remain types(integer, boolean, date/time) as integer // - Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64); + Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2); if (Temp64 > 0) { - Result = 1; + *Result = 1; } else if (Temp64 < 0) { - Result = -1; + *Result = -1; } else { - Result = 0; + *Result = 0; } - return Result; + return EFI_SUCCESS; } /** @@ -1651,6 +2063,118 @@ CheckUserPrivilege ( 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; + } + + Link = GetNextNode (&FormSet->FormListHead, Link); + Form = NULL; + } + ASSERT (Form != NULL); + + // + // Get the question value. + // + Status = GetQuestionValue(FormSet, Form, Question, GetSetValueWithHiiDriver); + 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; +} + /** Evaluate the result of a HII expression. @@ -1699,6 +2223,8 @@ EvaluateExpression ( UINT8 DigitUint8; UINT8 *TempBuffer; EFI_TIME EfiTime; + EFI_HII_VALUE QuestionVal; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; // // Save current stack offset. @@ -1729,13 +2255,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 +2275,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 +2358,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); @@ -1931,41 +2466,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)) { + Value->Type = EFI_IFR_TYPE_UNDEFINED; + break; + } - // - // Validate the expression value - // - if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) { - Status = EFI_NOT_FOUND; - goto Done; + 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 (CompareGuid (&OpCode->Guid, &gZeroGuid) != 0) { + 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 +2526,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; @@ -2021,8 +2573,8 @@ EvaluateExpression ( goto Done; } if (Value->Type != EFI_IFR_TYPE_STRING && Value->Type != EFI_IFR_TYPE_BUFFER) { - Status = EFI_INVALID_PARAMETER; - goto Done; + Value->Type = EFI_IFR_TYPE_UNDEFINED; + break; } if (Value->Type == EFI_IFR_TYPE_STRING) { @@ -2048,8 +2600,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 +2619,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 +2645,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; @@ -2146,15 +2698,14 @@ EvaluateExpression ( 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, @@ -2197,8 +2748,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,8 +2776,8 @@ 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; @@ -2265,7 +2816,7 @@ EvaluateExpression ( for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) { StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2); } - 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; @@ -2370,10 +2921,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,9 +2929,16 @@ 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; @@ -2441,10 +2995,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 +3003,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 +3034,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 +3043,33 @@ EvaluateExpression ( goto Done; } - Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle); + if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && + Data2.Type != EFI_IFR_TYPE_STRING && + Data2.Type != EFI_IFR_TYPE_BUFFER) { + Value->Type = EFI_IFR_TYPE_UNDEFINED; + break; + } + + if (Data1.Type > EFI_IFR_TYPE_BOOLEAN && + Data1.Type != EFI_IFR_TYPE_STRING && + Data1.Type != EFI_IFR_TYPE_BUFFER) { + Value->Type = EFI_IFR_TYPE_UNDEFINED; + break; + } + + Status = CompareHiiValue (&Data1, &Data2, &Result, FormSet->HiiHandle); if (Data1.Type == EFI_IFR_TYPE_BUFFER) { FreePool (Data1.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; } @@ -2575,8 +3144,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 +3202,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 +3245,7 @@ EvaluateExpression ( default: break; } - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || Value->Type == EFI_IFR_TYPE_UNDEFINED) { goto Done; } @@ -2710,3 +3279,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 Result->Value.u8 != 0; + + case EFI_IFR_TYPE_NUM_SIZE_16: + return Result->Value.u16 != 0; + + case EFI_IFR_TYPE_NUM_SIZE_32: + return Result->Value.u32 != 0; + + case EFI_IFR_TYPE_NUM_SIZE_64: + return 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; +}