/** @file\r
Utility functions for expression evaluation.\r
\r
-Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
(*StackPtr)->Buffer = AllocateCopyPool(Data->BufferLen, Data->Buffer);\r
ASSERT ((*StackPtr)->Buffer != NULL);\r
}\r
- \r
+\r
*StackPtr = *StackPtr + 1;\r
\r
return EFI_SUCCESS;\r
mCurrentExpressionPointer = mCurrentExpressionStack;\r
mFormExpressionPointer = mFormExpressionStack;\r
mStatementExpressionPointer = mStatementExpressionStack;\r
- mOptionExpressionPointer = mOptionExpressionStack; \r
+ mOptionExpressionPointer = mOptionExpressionStack;\r
}\r
\r
\r
pointer\r
@param StackEnd On input: old stack end; On output: new stack end\r
@param MemberSize The stack member size.\r
- \r
+\r
@retval EFI_SUCCESS Grow stack success.\r
@retval EFI_OUT_OF_RESOURCES No enough memory for stack space.\r
\r
//\r
// Push the item onto the stack\r
//\r
- CopyMem (*StackPtr, Data, sizeof (FORM_EXPRESSION *)); \r
+ CopyMem (*StackPtr, Data, sizeof (FORM_EXPRESSION *));\r
*StackPtr = *StackPtr + 1;\r
\r
return EFI_SUCCESS;\r
\r
/**\r
Get the expression list count.\r
- \r
- @param Level Which type this expression belong to. Form, \r
+\r
+ @param Level Which type this expression belong to. Form,\r
statement or option?\r
\r
@retval >=0 The expression count\r
@retval -1 Input parameter error.\r
\r
**/\r
-INTN \r
+INTN\r
GetConditionalExpressionCount (\r
IN EXPRESS_LEVEL Level\r
)\r
default:\r
ASSERT (FALSE);\r
return -1;\r
- } \r
+ }\r
}\r
\r
/**\r
Get the expression Buffer pointer.\r
- \r
- @param Level Which type this expression belong to. Form, \r
+\r
+ @param Level Which type this expression belong to. Form,\r
statement or option?\r
\r
@retval The start pointer of the expression buffer or NULL.\r
default:\r
ASSERT (FALSE);\r
return NULL;\r
- } \r
+ }\r
}\r
\r
\r
Push the expression options onto the Stack.\r
\r
@param Pointer Pointer to the current expression.\r
- @param Level Which type this expression belong to. Form, \r
+ @param Level Which type this expression belong to. Form,\r
statement or option?\r
\r
@retval EFI_SUCCESS The value was pushed onto the stack.\r
/**\r
Pop the expression options from the Stack\r
\r
- @param Level Which type this expression belong to. Form, \r
+ @param Level Which type this expression belong to. Form,\r
statement or option?\r
\r
@retval EFI_SUCCESS The value was pushed onto the stack.\r
**/\r
UINTN\r
SaveExpressionEvaluationStackOffset (\r
+ VOID\r
)\r
{\r
UINTN TempStackOffset;\r
}\r
}\r
\r
+/**\r
+ Check whether this value type can be transfer to EFI_IFR_TYPE_BUFFER type.\r
+\r
+ EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to\r
+ EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+ @param Value Expression value to compare on.\r
+\r
+ @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type.\r
+ @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type.\r
+\r
+**/\r
+BOOLEAN\r
+IsTypeInBuffer (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_BUFFER:\r
+ case EFI_IFR_TYPE_DATE:\r
+ case EFI_IFR_TYPE_TIME:\r
+ case EFI_IFR_TYPE_REF:\r
+ return TRUE;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Check whether this value type can be transfer to EFI_IFR_TYPE_UINT64\r
+\r
+ @param Value Expression value to compare on.\r
+\r
+ @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type.\r
+ @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type.\r
+\r
+**/\r
+BOOLEAN\r
+IsTypeInUINT64 (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ case EFI_IFR_TYPE_BOOLEAN:\r
+ return TRUE;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Return the buffer length for this value.\r
+\r
+ EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to\r
+ EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+ @param Value Expression value to compare on.\r
+\r
+ @retval BufLen Return the buffer length.\r
+\r
+**/\r
+UINT16\r
+GetLengthForValue (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_BUFFER:\r
+ return Value->BufferLen;\r
+\r
+ case EFI_IFR_TYPE_DATE:\r
+ return (UINT16) sizeof (EFI_HII_DATE);\r
+\r
+ case EFI_IFR_TYPE_TIME:\r
+ return (UINT16) sizeof (EFI_HII_TIME);\r
+\r
+ case EFI_IFR_TYPE_REF:\r
+ return (UINT16) sizeof (EFI_HII_REF);\r
+\r
+ default:\r
+ return 0;\r
+ }\r
+}\r
+\r
+/**\r
+ Return the buffer pointer for this value.\r
+\r
+ EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to\r
+ EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+ @param Value Expression value to compare on.\r
+\r
+ @retval Buf Return the buffer pointer.\r
+\r
+**/\r
+UINT8 *\r
+GetBufferForValue (\r
+ IN EFI_HII_VALUE *Value\r
+ )\r
+{\r
+ switch (Value->Type) {\r
+ case EFI_IFR_TYPE_BUFFER:\r
+ return Value->Buffer;\r
+\r
+ case EFI_IFR_TYPE_DATE:\r
+ return (UINT8 *) (&Value->Value.date);\r
+\r
+ case EFI_IFR_TYPE_TIME:\r
+ return (UINT8 *) (&Value->Value.time);\r
+\r
+ case EFI_IFR_TYPE_REF:\r
+ return (UINT8 *) (&Value->Value.ref);\r
+\r
+ default:\r
+ return NULL;\r
+ }\r
+}\r
\r
/**\r
Evaluate opcode EFI_IFR_TO_STRING.\r
CHAR16 *PrintFormat;\r
CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];\r
UINT8 *TmpBuf;\r
+ UINT8 *SrcBuf;\r
+ UINTN SrcLen;\r
UINTN BufferSize;\r
\r
Status = PopExpression (&Value);\r
case EFI_IFR_TYPE_BOOLEAN:\r
String = (Value.Value.b) ? L"True" : L"False";\r
break;\r
- \r
+\r
case EFI_IFR_TYPE_BUFFER:\r
+ case EFI_IFR_TYPE_DATE:\r
+ case EFI_IFR_TYPE_TIME:\r
+ case EFI_IFR_TYPE_REF:\r
//\r
- // + 3 is base on the unicode format, the length may be odd number, \r
+ // + 3 is base on the unicode format, the length may be odd number,\r
// so need 1 byte to align, also need 2 bytes for L'\0'.\r
//\r
- TmpBuf = AllocateZeroPool (Value.BufferLen + 3);\r
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ SrcLen = Value.BufferLen;\r
+ SrcBuf = Value.Buffer;\r
+ } else {\r
+ SrcBuf = GetBufferForValue(&Value);\r
+ SrcLen = GetLengthForValue(&Value);\r
+ }\r
+\r
+ TmpBuf = AllocateZeroPool (SrcLen + 3);\r
ASSERT (TmpBuf != NULL);\r
if (Format == EFI_IFR_STRING_ASCII) {\r
- CopyMem (TmpBuf, Value.Buffer, Value.BufferLen);\r
- PrintFormat = L"%a"; \r
+ CopyMem (TmpBuf, SrcBuf, SrcLen);\r
+ PrintFormat = L"%a";\r
} else {\r
// Format == EFI_IFR_STRING_UNICODE\r
- CopyMem (TmpBuf, Value.Buffer, Value.BufferLen * sizeof (CHAR16));\r
- PrintFormat = L"%s"; \r
+ CopyMem (TmpBuf, SrcBuf, SrcLen * sizeof (CHAR16));\r
+ PrintFormat = L"%s";\r
}\r
- UnicodeSPrint (Buffer, sizeof (Buffer), PrintFormat, Value.Buffer); \r
- String = Buffer; \r
+ UnicodeSPrint (Buffer, sizeof (Buffer), PrintFormat, TmpBuf);\r
+ String = Buffer;\r
FreePool (TmpBuf);\r
- FreePool (Value.Buffer);\r
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Value.Buffer);\r
+ }\r
break;\r
- \r
+\r
default:\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
return EFI_SUCCESS;\r
return Status;\r
}\r
\r
- if (Value.Type >= EFI_IFR_TYPE_OTHER && Value.Type != EFI_IFR_TYPE_BUFFER) {\r
+ if (Value.Type >= EFI_IFR_TYPE_OTHER && !IsTypeInBuffer(&Value)) {\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
return EFI_SUCCESS;\r
}\r
Result->Value.u64 = StrDecimalToUint64 (String);\r
}\r
FreePool (String);\r
- } else if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
- if (Value.BufferLen > 8) {\r
- FreePool (Value.Buffer);\r
+ } else if (IsTypeInBuffer(&Value)) {\r
+ if (GetLengthForValue (&Value) > 8) {\r
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Value.Buffer);\r
+ }\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
return EFI_SUCCESS;\r
}\r
- Result->Value.u64 = *(UINT64*) Value.Buffer;\r
- FreePool (Value.Buffer);\r
+ Result->Value.u64 = *(UINT64*) GetBufferForValue (&Value);\r
+ if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Value.Buffer);\r
+ }\r
} else {\r
CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
}\r
UINTN Index;\r
CHAR16 *StringPtr;\r
UINTN Size;\r
+ UINT16 Length0;\r
+ UINT16 Length1;\r
+ UINT8 *TmpBuf;\r
+ UINTN MaxLen;\r
\r
//\r
// String[0] - The second string\r
}\r
\r
for (Index = 0; Index < 2; Index++) {\r
- if (Value[Index].Type != EFI_IFR_TYPE_STRING && Value[Index].Type != EFI_IFR_TYPE_BUFFER) {\r
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING && !IsTypeInBuffer(&Value[Index])) {\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
Status = EFI_SUCCESS;\r
goto Done;\r
\r
if (Value[0].Type == EFI_IFR_TYPE_STRING) {\r
Size = StrSize (String[0]);\r
- StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
+ MaxLen = (StrSize (String[1]) + Size) / sizeof (CHAR16);\r
+ StringPtr= AllocatePool (MaxLen * sizeof (CHAR16));\r
ASSERT (StringPtr != NULL);\r
- StrCpy (StringPtr, String[1]);\r
- StrCat (StringPtr, String[0]);\r
+ StrCpyS (StringPtr, MaxLen, String[1]);\r
+ StrCatS (StringPtr, MaxLen, String[0]);\r
\r
Result->Type = EFI_IFR_TYPE_STRING;\r
Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
} else {\r
Result->Type = EFI_IFR_TYPE_BUFFER;\r
- Result->BufferLen = (UINT16) (Value[0].BufferLen + Value[1].BufferLen);\r
+ Length0 = GetLengthForValue(&Value[0]);\r
+ Length1 = GetLengthForValue(&Value[1]);\r
+ Result->BufferLen = (UINT16) (Length0 + Length1);\r
\r
Result->Buffer = AllocateZeroPool (Result->BufferLen);\r
ASSERT (Result->Buffer != NULL);\r
\r
- CopyMem (Result->Buffer, Value[0].Buffer, Value[0].BufferLen);\r
- CopyMem (&Result->Buffer[Value[0].BufferLen], Value[1].Buffer, Value[1].BufferLen);\r
+ TmpBuf = GetBufferForValue(&Value[0]);\r
+ ASSERT (TmpBuf != NULL);\r
+ CopyMem (Result->Buffer, TmpBuf, Length0);\r
+ TmpBuf = GetBufferForValue(&Value[1]);\r
+ ASSERT (TmpBuf != NULL);\r
+ CopyMem (&Result->Buffer[Length0], TmpBuf, Length1);\r
}\r
Done:\r
if (Value[0].Buffer != NULL) {\r
return Status;\r
}\r
\r
+/**\r
+ Evaluate opcode EFI_IFR_MATCH2.\r
+\r
+ @param FormSet Formset which contains this opcode.\r
+ @param SyntaxType Syntax type for match2.\r
+ @param Result Evaluation result for this opcode.\r
+\r
+ @retval EFI_SUCCESS Opcode evaluation success.\r
+ @retval Other Opcode evaluation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfrMatch2 (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN EFI_GUID *SyntaxType,\r
+ OUT EFI_HII_VALUE *Result\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_VALUE Value[2];\r
+ CHAR16 *String[2];\r
+ UINTN Index;\r
+ UINTN GuidIndex;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN BufferSize;\r
+ EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;\r
+ UINTN RegExSyntaxTypeListSize;\r
+ EFI_REGEX_SYNTAX_TYPE *RegExSyntaxTypeList;\r
+ UINTN CapturesCount;\r
+\r
+ //\r
+ // String[0] - The string to search\r
+ // String[1] - pattern\r
+ //\r
+ String[0] = NULL;\r
+ String[1] = NULL;\r
+ HandleBuffer = NULL;\r
+ RegExSyntaxTypeList = NULL;\r
+ Status = EFI_SUCCESS;\r
+ ZeroMem (Value, sizeof (Value));\r
+\r
+ Status = PopExpression (&Value[0]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = PopExpression (&Value[1]);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ for (Index = 0; Index < 2; Index++) {\r
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\r
+ String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);\r
+ if (String [Index] == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ BufferSize = 0;\r
+ HandleBuffer = NULL;\r
+ Status = gBS->LocateHandle(\r
+ ByProtocol,\r
+ &gEfiRegularExpressionProtocolGuid,\r
+ NULL,\r
+ &BufferSize,\r
+ HandleBuffer);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HandleBuffer = AllocateZeroPool(BufferSize);\r
+ if (HandleBuffer == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ Status = gBS->LocateHandle(\r
+ ByProtocol,\r
+ &gEfiRegularExpressionProtocolGuid,\r
+ NULL,\r
+ &BufferSize,\r
+ HandleBuffer);\r
+\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\r
+ ASSERT (HandleBuffer != NULL);\r
+ for ( Index = 0; Index < BufferSize / sizeof(EFI_HANDLE); Index ++) {\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuffer[Index],\r
+ &gEfiRegularExpressionProtocolGuid,\r
+ (VOID**)&RegularExpressionProtocol\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ RegExSyntaxTypeListSize = 0;\r
+ RegExSyntaxTypeList = NULL;\r
+\r
+ Status = RegularExpressionProtocol->GetInfo (\r
+ RegularExpressionProtocol,\r
+ &RegExSyntaxTypeListSize,\r
+ RegExSyntaxTypeList\r
+ );\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ RegExSyntaxTypeList = AllocateZeroPool(RegExSyntaxTypeListSize);\r
+ if (RegExSyntaxTypeList == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ Status = RegularExpressionProtocol->GetInfo (\r
+ RegularExpressionProtocol,\r
+ &RegExSyntaxTypeListSize,\r
+ RegExSyntaxTypeList\r
+ );\r
+ } else if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ for (GuidIndex = 0; GuidIndex < RegExSyntaxTypeListSize / sizeof(EFI_GUID); GuidIndex++) {\r
+ if (CompareGuid (&RegExSyntaxTypeList[GuidIndex], SyntaxType)) {\r
+ //\r
+ // Find the match type, return the value.\r
+ //\r
+ Result->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ Status = RegularExpressionProtocol->MatchString (\r
+ RegularExpressionProtocol,\r
+ String[0],\r
+ String[1],\r
+ SyntaxType,\r
+ &Result->Value.b,\r
+ NULL,\r
+ &CapturesCount\r
+ );\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ if (RegExSyntaxTypeList != NULL) {\r
+ FreePool (RegExSyntaxTypeList);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Type specified by SyntaxType is not supported\r
+ // in any of the EFI_REGULAR_EXPRESSION_PROTOCOL instances.\r
+ //\r
+ Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
+ Status = EFI_SUCCESS;\r
+\r
+Done:\r
+ if (String[0] != NULL) {\r
+ FreePool (String[0]);\r
+ }\r
+ if (String[1] != NULL) {\r
+ FreePool (String[1]);\r
+ }\r
+ if (RegExSyntaxTypeList != NULL) {\r
+ FreePool (RegExSyntaxTypeList);\r
+ }\r
+ if (HandleBuffer != NULL) {\r
+ FreePool (HandleBuffer);\r
+ }\r
+ return Status;\r
+}\r
\r
/**\r
Evaluate opcode EFI_IFR_FIND.\r
Status = PopExpression (&Value[2]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
- } \r
+ }\r
\r
if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
UINTN Length;\r
CHAR16 *SubString;\r
UINT16 BufferLen;\r
+ UINT8 *Buffer;\r
\r
ZeroMem (Value, sizeof (Value));\r
\r
Status = PopExpression (&Value[2]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
- } \r
+ }\r
\r
if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
}\r
Base = (UINTN) Value[1].Value.u64;\r
\r
- if (Value[2].Type != EFI_IFR_TYPE_STRING && Value[2].Type != EFI_IFR_TYPE_BUFFER) {\r
+ if (Value[2].Type != EFI_IFR_TYPE_STRING && !IsTypeInBuffer(&Value[2])) {\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
return EFI_SUCCESS;\r
}\r
\r
FreePool (String);\r
} else {\r
- BufferLen = Value[2].BufferLen;\r
- \r
+ BufferLen = GetLengthForValue (&Value[2]);\r
+ Buffer = GetBufferForValue (&Value[2]);\r
+\r
Result->Type = EFI_IFR_TYPE_BUFFER;\r
if (Length == 0 || Base >= BufferLen) {\r
Result->BufferLen = 0;\r
Result->Buffer = NULL;\r
} else {\r
- Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length); \r
+ Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length);\r
Result->Buffer = AllocateZeroPool (Result->BufferLen);\r
ASSERT (Result->Buffer != NULL);\r
- CopyMem (Result->Buffer, &Value[2].Buffer[Base], Result->BufferLen);\r
+ CopyMem (Result->Buffer, &Buffer[Base], Result->BufferLen);\r
}\r
\r
- FreePool (Value[2].Buffer);\r
+ if (Value[2].Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Value[2].Buffer);\r
+ }\r
}\r
- \r
+\r
return Status;\r
}\r
\r
Status = PopExpression (&Value[2]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
- } \r
+ }\r
\r
- if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) { \r
+ if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
return EFI_SUCCESS;\r
}\r
for (Index = 0; Index < 2; Index++) {\r
if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
- Status = EFI_SUCCESS; \r
+ Status = EFI_SUCCESS;\r
goto Done;\r
}\r
\r
Status = PopExpression (&Value[2]);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
- } \r
+ }\r
\r
if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
Result->Type = EFI_IFR_TYPE_UNDEFINED;\r
CHAR16 *Str1;\r
CHAR16 *Str2;\r
UINTN Len;\r
+ UINT8 *Buf1;\r
+ UINT16 Buf1Len;\r
+ UINT8 *Buf2;\r
+ UINT16 Buf2Len;\r
\r
- if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
- if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
- if (Value1->Type != Value2->Type) {\r
- //\r
- // Both Operator should be type of String\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
+ if (Value1->Type == EFI_IFR_TYPE_STRING && Value2->Type == EFI_IFR_TYPE_STRING) {\r
if (Value1->Value.string == 0 || Value2->Value.string == 0) {\r
//\r
// StringId 0 is reserved\r
return EFI_SUCCESS;\r
}\r
\r
- if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) {\r
- if (Value1->Type != Value2->Type) {\r
- //\r
- // Both Operator should be type of Buffer.\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
- Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen;\r
- *Result = CompareMem (Value1->Buffer, Value2->Buffer, Len);\r
- if ((*Result == 0) && (Value1->BufferLen != Value2->BufferLen))\r
- {\r
+ //\r
+ // Take types(date, time, ref, buffer) as buffer\r
+ //\r
+ if (IsTypeInBuffer(Value1) && IsTypeInBuffer(Value2)) {\r
+ Buf1 = GetBufferForValue(Value1);\r
+ Buf1Len = GetLengthForValue(Value1);\r
+ Buf2 = GetBufferForValue(Value2);\r
+ Buf2Len = GetLengthForValue(Value2);\r
+\r
+ Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len;\r
+ *Result = CompareMem (Buf1, Buf2, Len);\r
+ if ((*Result == 0) && (Buf1Len != Buf2Len)) {\r
//\r
// In this case, means base on samll number buffer, the data is same\r
// So which value has more data, which value is bigger.\r
//\r
- *Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1;\r
+ *Result = Buf1Len > Buf2Len ? 1 : -1;\r
}\r
return EFI_SUCCESS;\r
- } \r
+ }\r
\r
//\r
- // Take remain types(integer, boolean, date/time) as integer\r
+ // Take types(integer, boolean) as integer\r
//\r
- Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);\r
- if (Temp64 > 0) {\r
- *Result = 1;\r
- } else if (Temp64 < 0) {\r
- *Result = -1;\r
- } else {\r
- *Result = 0;\r
+ if (IsTypeInUINT64(Value1) && IsTypeInUINT64(Value2)) {\r
+ Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);\r
+ if (Temp64 > 0) {\r
+ *Result = 1;\r
+ } else if (Temp64 < 0) {\r
+ *Result = -1;\r
+ } else {\r
+ *Result = 0;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
}\r
\r
- return EFI_SUCCESS;\r
+ return EFI_UNSUPPORTED;\r
}\r
\r
/**\r
/// Enumerate all user information of the current user profile\r
/// to look for any EFI_USER_INFO_ACCESS_SETUP record.\r
///\r
- \r
+\r
for (UserInfoHandle = NULL;;) {\r
Status = mUserManager->GetNextInfo (mUserManager, UserProfileHandle, &UserInfoHandle);\r
if (EFI_ERROR (Status)) {\r
@param FormSetGuid The formset guid which include the question.\r
@param QuestionId The question id which need to get value from.\r
@param Value The return data about question's value.\r
- \r
+\r
@retval TRUE Get the question value success.\r
@retval FALSE Get the question value failed.\r
**/\r
-BOOLEAN \r
+BOOLEAN\r
GetQuestionValueFromForm (\r
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
IN EFI_HII_HANDLE InputHiiHandle,\r
BOOLEAN GetTheVal;\r
LIST_ENTRY *Link;\r
\r
- // \r
- // The input parameter DevicePath or InputHiiHandle must have one valid input. \r
//\r
- ASSERT ((DevicePath != NULL && InputHiiHandle == NULL) || \r
+ // The input parameter DevicePath or InputHiiHandle must have one valid input.\r
+ //\r
+ ASSERT ((DevicePath != NULL && InputHiiHandle == NULL) ||\r
(DevicePath == NULL && InputHiiHandle != NULL) );\r
\r
GetTheVal = TRUE;\r
}\r
} else {\r
HiiHandle = InputHiiHandle;\r
- } \r
+ }\r
ASSERT (HiiHandle != NULL);\r
\r
//\r
\r
//\r
// Base on the Question Id to get the question info.\r
- // \r
+ //\r
Question = IdToQuestion(FormSet, NULL, QuestionId);\r
if (Question == NULL) {\r
GetTheVal = FALSE;\r
Form = NULL;\r
}\r
ASSERT (Form != NULL);\r
- \r
+\r
//\r
// Get the question value.\r
//\r
- Status = GetQuestionValue(FormSet, Form, Question, GetSetValueWithHiiDriver);\r
+ Status = GetQuestionValue(FormSet, Form, Question, GetSetValueWithEditBuffer);\r
if (EFI_ERROR (Status)) {\r
GetTheVal = FALSE;\r
goto Done;\r
}\r
\r
CopyMem (Value, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
- \r
+\r
Done:\r
//\r
// Clean the formset structure and restore the global parameter.\r
if (FormSet != NULL) {\r
DestroyFormSet (FormSet);\r
}\r
- \r
+\r
return GetTheVal;\r
}\r
\r
EFI_HII_VALUE QuestionVal;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
\r
+ StrPtr = NULL;\r
+\r
//\r
// Save current stack offset.\r
//\r
TempBuffer [Index/2] = (UINT8) ((DigitUint8 << 4) + TempBuffer [Index/2]);\r
}\r
}\r
- } \r
+ }\r
}\r
}\r
break;\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- \r
+\r
//\r
// Validate the expression value\r
//\r
if (StrPtr != NULL) {\r
FreePool (StrPtr);\r
}\r
- } else if (CompareGuid (&OpCode->Guid, &gZeroGuid) != 0) {\r
+ } else if (IsZeroGuid (&OpCode->Guid)) {\r
if (!GetQuestionValueFromForm(NULL, FormSet->HiiHandle, &OpCode->Guid, Value->Value.u16, &QuestionVal)){\r
Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
break;\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- if (Value->Type != EFI_IFR_TYPE_STRING && Value->Type != EFI_IFR_TYPE_BUFFER) {\r
+ if (Value->Type != EFI_IFR_TYPE_STRING && !IsTypeInBuffer (Value)) {\r
Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
break;\r
}\r
FreePool (StrPtr);\r
} else {\r
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = Value->BufferLen;\r
+ Value->Value.u64 = GetLengthForValue(Value);\r
FreePool (Value->Buffer);\r
}\r
break;\r
// When converting from an unsigned integer, zero will be converted to\r
// FALSE and any other value will be converted to TRUE.\r
//\r
- Value->Value.b = (BOOLEAN) (Value->Value.u64 != 0);\r
+ Value->Value.b = (BOOLEAN) (HiiValueToUINT64(Value) != 0);\r
\r
Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
} else if (Value->Type == EFI_IFR_TYPE_STRING) {\r
//\r
// When converting from a string, if case-insensitive compare\r
// with "true" is True, then push True. If a case-insensitive compare\r
- // with "false" is True, then push False. Otherwise, push Undefined. \r
+ // with "false" is True, then push False. Otherwise, push Undefined.\r
//\r
StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
if (StrPtr == NULL) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
- \r
+\r
IfrStrToUpper (StrPtr);\r
if (StrCmp (StrPtr, L"TRUE") == 0){\r
Value->Value.b = TRUE;\r
FreePool (StrPtr);\r
} else if (Value->Type == EFI_IFR_TYPE_BUFFER) {\r
//\r
- // When converting from a buffer, if the buffer is all zeroes, \r
- // then push False. Otherwise push True. \r
+ // When converting from a buffer, if the buffer is all zeroes,\r
+ // then push False. Otherwise push True.\r
//\r
for (Index =0; Index < Value->BufferLen; Index ++) {\r
- if (Value->Buffer[Index] != 0) { \r
+ if (Value->Buffer[Index] != 0) {\r
break;\r
}\r
}\r
}\r
\r
Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = ~Value->Value.u64;\r
+ Value->Value.u64 = ~ HiiValueToUINT64(Value);\r
break;\r
\r
case EFI_IFR_SET_OP:\r
case EFI_HII_VARSTORE_NAME_VALUE:\r
if (OpCode->ValueType != EFI_IFR_TYPE_STRING) {\r
NameValue = AllocateZeroPool ((OpCode->ValueWidth * 2 + 1) * sizeof (CHAR16));\r
- ASSERT (Value != NULL);\r
+ ASSERT (NameValue != NULL);\r
//\r
// Convert Buffer to Hex String\r
//\r
TempBuffer = (UINT8 *) &Value->Value + OpCode->ValueWidth - 1;\r
StrPtr = NameValue;\r
for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {\r
- StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);\r
+ UnicodeValueToStringS (\r
+ StrPtr,\r
+ (OpCode->ValueWidth * 2 + 1) * sizeof (CHAR16) - ((UINTN)StrPtr - (UINTN)NameValue),\r
+ PREFIX_ZERO | RADIX_HEX,\r
+ *TempBuffer,\r
+ 2\r
+ );\r
+ StrPtr += StrnLenS (StrPtr, OpCode->ValueWidth * 2 + 1 - ((UINTN)StrPtr - (UINTN)NameValue) / sizeof (CHAR16));\r
}\r
Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer, NULL);\r
FreePool (NameValue);\r
//\r
Status = EFI_UNSUPPORTED;\r
goto Done;\r
- break;\r
}\r
} else {\r
//\r
\r
switch (OpCode->Operand) {\r
case EFI_IFR_ADD_OP:\r
- Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64;\r
+ Value->Value.u64 = HiiValueToUINT64(&Data1) + HiiValueToUINT64(&Data2);\r
break;\r
\r
case EFI_IFR_SUBTRACT_OP:\r
- Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64;\r
+ Value->Value.u64 = HiiValueToUINT64(&Data1) - HiiValueToUINT64(&Data2);\r
break;\r
\r
case EFI_IFR_MULTIPLY_OP:\r
- Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
+ Value->Value.u64 = MultU64x32 (HiiValueToUINT64(&Data1), (UINT32) HiiValueToUINT64(&Data2));\r
break;\r
\r
case EFI_IFR_DIVIDE_OP:\r
- Value->Value.u64 = DivU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
+ Value->Value.u64 = DivU64x32 (HiiValueToUINT64(&Data1), (UINT32) HiiValueToUINT64(&Data2));\r
break;\r
\r
case EFI_IFR_MODULO_OP:\r
- DivU64x32Remainder (Data1.Value.u64, (UINT32) Data2.Value.u64, &TempValue);\r
+ DivU64x32Remainder (HiiValueToUINT64(&Data1), (UINT32) HiiValueToUINT64(&Data2), &TempValue);\r
Value->Value.u64 = TempValue;\r
break;\r
\r
case EFI_IFR_BITWISE_AND_OP:\r
- Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64;\r
+ Value->Value.u64 = HiiValueToUINT64(&Data1) & HiiValueToUINT64(&Data2);\r
break;\r
\r
case EFI_IFR_BITWISE_OR_OP:\r
- Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64;\r
+ Value->Value.u64 = HiiValueToUINT64(&Data1) | HiiValueToUINT64(&Data2);\r
break;\r
\r
case EFI_IFR_SHIFT_LEFT_OP:\r
- Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
+ Value->Value.u64 = LShiftU64 (HiiValueToUINT64(&Data1), (UINTN) HiiValueToUINT64(&Data2));\r
break;\r
\r
case EFI_IFR_SHIFT_RIGHT_OP:\r
- Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
+ Value->Value.u64 = RShiftU64 (HiiValueToUINT64(&Data1), (UINTN) HiiValueToUINT64(&Data2));\r
break;\r
\r
default:\r
goto Done;\r
}\r
\r
- if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && \r
- Data2.Type != EFI_IFR_TYPE_STRING && \r
- Data2.Type != EFI_IFR_TYPE_BUFFER) {\r
+ if (Data2.Type > EFI_IFR_TYPE_BOOLEAN &&\r
+ Data2.Type != EFI_IFR_TYPE_STRING &&\r
+ !IsTypeInBuffer(&Data2)) {\r
Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
break;\r
}\r
\r
- if (Data1.Type > EFI_IFR_TYPE_BOOLEAN && \r
- Data1.Type != EFI_IFR_TYPE_STRING && \r
- Data1.Type != EFI_IFR_TYPE_BUFFER) {\r
+ if (Data1.Type > EFI_IFR_TYPE_BOOLEAN &&\r
+ Data1.Type != EFI_IFR_TYPE_STRING &&\r
+ !IsTypeInBuffer(&Data1)) {\r
Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
break;\r
}\r
Status = CompareHiiValue (&Data1, &Data2, &Result, FormSet->HiiHandle);\r
if (Data1.Type == EFI_IFR_TYPE_BUFFER) {\r
FreePool (Data1.Buffer);\r
+ }\r
+ if (Data2.Type == EFI_IFR_TYPE_BUFFER) {\r
FreePool (Data2.Buffer);\r
}\r
- \r
+\r
if (Status == EFI_UNSUPPORTED) {\r
Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
Status = EFI_SUCCESS;\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- \r
+\r
Status = IfrMatch (FormSet, Value);\r
break;\r
\r
+ case EFI_IFR_MATCH2_OP:\r
+ Status = IfrMatch2 (FormSet, &OpCode->Guid, Value);\r
+ break;\r
+\r
case EFI_IFR_CATENATE_OP:\r
Status = IfrCatenate (FormSet, Value);\r
break;\r
}\r
\r
/**\r
- Return the result of the expression list. Check the expression list and \r
- return the highest priority express result. \r
+ Check whether the result is TRUE or FALSE.\r
+\r
+ For the EFI_HII_VALUE value type is numeric, return TRUE if the\r
+ value is not 0.\r
+\r
+ @param Result Input the result data.\r
+\r
+ @retval TRUE The result is TRUE.\r
+ @retval FALSE The result is FALSE.\r
+\r
+**/\r
+BOOLEAN\r
+IsTrue (\r
+ IN EFI_HII_VALUE *Result\r
+ )\r
+{\r
+ switch (Result->Type) {\r
+ case EFI_IFR_TYPE_BOOLEAN:\r
+ return Result->Value.b;\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_8:\r
+ return (BOOLEAN)(Result->Value.u8 != 0);\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_16:\r
+ return (BOOLEAN)(Result->Value.u16 != 0);\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_32:\r
+ return (BOOLEAN)(Result->Value.u32 != 0);\r
+\r
+ case EFI_IFR_TYPE_NUM_SIZE_64:\r
+ return (BOOLEAN)(Result->Value.u64 != 0);\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Return the result of the expression list. Check the expression list and\r
+ return the highest priority express result.\r
Priority: DisableIf > SuppressIf > GrayOutIf > FALSE\r
\r
@param ExpList The input expression list.\r
@param Evaluate Whether need to evaluate the expression first.\r
@param FormSet FormSet associated with this expression.\r
- @param Form Form associated with this expression. \r
+ @param Form Form associated with this expression.\r
\r
- @retval EXPRESS_RESULT Return the higher priority express result. \r
+ @retval EXPRESS_RESULT Return the higher priority express result.\r
DisableIf > SuppressIf > GrayOutIf > FALSE\r
\r
**/\r
-EXPRESS_RESULT \r
+EXPRESS_RESULT\r
EvaluateExpressionList (\r
IN FORM_EXPRESSION_LIST *ExpList,\r
IN BOOLEAN Evaluate,\r
//\r
// Check whether need to evaluate the expression first.\r
//\r
- if (Evaluate) { \r
+ if (Evaluate) {\r
while (ExpList->Count > Index) {\r
Status = EvaluateExpression (FormSet, Form, ExpList->Expression[Index++]);\r
if (EFI_ERROR (Status)) {\r
//\r
ReturnVal = ExpressFalse;\r
for (Index = 0; Index < ExpList->Count; Index++) {\r
- if (ExpList->Expression[Index]->Result.Type == EFI_IFR_TYPE_BOOLEAN &&\r
- ExpList->Expression[Index]->Result.Value.b) {\r
+ if (IsTrue (&ExpList->Expression[Index]->Result)) {\r
switch (ExpList->Expression[Index]->Type) {\r
case EFI_HII_EXPRESSION_SUPPRESS_IF:\r
CompareOne = ExpressSuppress;\r
break;\r
\r
default:\r
- return ExpressFalse; \r
+ return ExpressFalse;\r
}\r
\r
ReturnVal = ReturnVal < CompareOne ? CompareOne : ReturnVal;\r
}\r
}\r
- \r
+\r
return ReturnVal;\r
}\r