/** @file\r
Utility functions for expression evaluation.\r
\r
-Copyright (c) 2007 - 2010, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
// Push the item onto the stack\r
//\r
CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));\r
+ if (Data->Type == EFI_IFR_TYPE_BUFFER) {\r
+ (*StackPtr)->Buffer = AllocateCopyPool(Data->BufferLen, Data->Buffer);\r
+ ASSERT ((*StackPtr)->Buffer != NULL);\r
+ }\r
+ \r
*StackPtr = *StackPtr + 1;\r
\r
return EFI_SUCCESS;\r
CHAR16 *String;\r
CHAR16 *PrintFormat;\r
CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];\r
+ UINT8 *TmpBuf;\r
UINTN BufferSize;\r
\r
Status = PopExpression (&Value);\r
case EFI_IFR_TYPE_BOOLEAN:\r
String = (Value.Value.b) ? L"True" : L"False";\r
break;\r
-\r
+ \r
+ case EFI_IFR_TYPE_BUFFER:\r
+ //\r
+ // + 3 is base on the unicode format, the length may be odd number, \r
+ // so need 1 byte to align, also need 2 bytes for L'\0'.\r
+ //\r
+ TmpBuf = AllocateZeroPool (Value.BufferLen + 3);\r
+ if (Format == EFI_IFR_STRING_ASCII) {\r
+ CopyMem (TmpBuf, Value.Buffer, Value.BufferLen);\r
+ PrintFormat = L"%a"; \r
+ } else {\r
+ // Format == EFI_IFR_STRING_UNICODE\r
+ CopyMem (TmpBuf, Value.Buffer, Value.BufferLen * sizeof (CHAR16));\r
+ PrintFormat = L"%s"; \r
+ }\r
+ UnicodeSPrint (Buffer, MAXIMUM_VALUE_CHARACTERS, PrintFormat, Value.Buffer); \r
+ String = Buffer; \r
+ FreePool (TmpBuf);\r
+ FreePool (Value.Buffer);\r
+ break;\r
+ \r
default:\r
return EFI_UNSUPPORTED;\r
}\r
return Status;\r
}\r
\r
- if (Value.Type >= EFI_IFR_TYPE_OTHER) {\r
+ if (Value.Type >= EFI_IFR_TYPE_OTHER && Value.Type != EFI_IFR_TYPE_BUFFER) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
Result->Value.u64 = StrDecimalToUint64 (String);\r
}\r
FreePool (String);\r
+ } else if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ if (Value.BufferLen > 8) {\r
+ FreePool (Value.Buffer);\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ Result->Value.u64 = *(UINT64*) Value.Buffer;\r
+ FreePool (Value.Buffer);\r
} else {\r
CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
}\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
+ EFI_HII_VALUE Value[2];\r
CHAR16 *String[2];\r
UINTN Index;\r
CHAR16 *StringPtr;\r
String[1] = NULL;\r
StringPtr = NULL;\r
Status = EFI_SUCCESS;\r
+ ZeroMem (Value, sizeof (Value));\r
\r
for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
+ Status = PopExpression (&Value[Index]);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING && Value[Index].Type != EFI_IFR_TYPE_BUFFER) {\r
Status = EFI_UNSUPPORTED;\r
goto Done;\r
}\r
\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String[Index] == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
+ if (Value[Index].Type == EFI_IFR_TYPE_STRING) {\r
+ String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);\r
+ if (String[Index] == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
}\r
}\r
\r
- Size = StrSize (String[0]);\r
- StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
- ASSERT (StringPtr != NULL);\r
- StrCpy (StringPtr, String[1]);\r
- StrCat (StringPtr, String[0]);\r
+ if (Value[0].Type == EFI_IFR_TYPE_STRING) {\r
+ Size = StrSize (String[0]);\r
+ StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
+ ASSERT (StringPtr != NULL);\r
+ StrCpy (StringPtr, String[1]);\r
+ StrCat (StringPtr, String[0]);\r
\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
+ Result->Type = EFI_IFR_TYPE_STRING;\r
+ Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
+ } else {\r
+ Result->Type = EFI_IFR_TYPE_BUFFER;\r
+ Result->BufferLen = (UINT16) (Value[0].BufferLen + Value[1].BufferLen);\r
+\r
+ Result->Buffer = AllocateZeroPool (Result->BufferLen);\r
+ ASSERT (Result->Buffer != NULL);\r
\r
+ CopyMem (Result->Buffer, Value[0].Buffer, Value[0].BufferLen);\r
+ CopyMem (&Result->Buffer[Value[0].BufferLen], Value[1].Buffer, Value[1].BufferLen);\r
+ }\r
Done:\r
+ if (Value[0].Buffer != NULL) {\r
+ FreePool (Value[0].Buffer);\r
+ }\r
+ if (Value[1].Buffer != NULL) {\r
+ FreePool (Value[1].Buffer);\r
+ }\r
if (String[0] != NULL) {\r
FreePool (String[0]);\r
}\r
UINTN Base;\r
UINTN Length;\r
CHAR16 *SubString;\r
+ UINT8 *Buffer;\r
+ UINT16 BufferLen;\r
\r
Status = PopExpression (&Value);\r
if (EFI_ERROR (Status)) {\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+ if (Value.Type != EFI_IFR_TYPE_STRING && Value.Type != EFI_IFR_TYPE_BUFFER) {\r
return EFI_UNSUPPORTED;\r
}\r
- String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
+ if (Value.Type == EFI_IFR_TYPE_STRING) {\r
+ String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+ if (String == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
- if (Length == 0 || Base >= StrLen (String)) {\r
- SubString = gEmptyString;\r
- } else {\r
- SubString = String + Base;\r
- if ((Base + Length) < StrLen (String)) {\r
- SubString[Length] = L'\0';\r
+ if (Length == 0 || Base >= StrLen (String)) {\r
+ SubString = gEmptyString;\r
+ } else {\r
+ SubString = String + Base;\r
+ if ((Base + Length) < StrLen (String)) {\r
+ SubString[Length] = L'\0';\r
+ }\r
}\r
- }\r
\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
+ Result->Type = EFI_IFR_TYPE_STRING;\r
+ Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
\r
- FreePool (String);\r
+ FreePool (String);\r
+ } else {\r
+ Buffer = Value.Buffer;\r
+ BufferLen = Value.BufferLen;\r
+ \r
+ Result->Type = EFI_IFR_TYPE_BUFFER;\r
+ if (Length == 0 || Base >= BufferLen) {\r
+ Result->BufferLen = 0;\r
+ Result->Buffer = NULL;\r
+ } else {\r
+ Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length); \r
+ Result->Buffer = AllocateZeroPool (Result->BufferLen);\r
+ ASSERT (Result->Buffer != NULL);\r
+ CopyMem (Result->Buffer, &Value.Buffer[Base], Result->BufferLen);\r
+ }\r
\r
+ FreePool (Value.Buffer);\r
+ }\r
+ \r
return Status;\r
}\r
\r
INT64 Temp64;\r
CHAR16 *Str1;\r
CHAR16 *Str2;\r
+ UINTN Len;\r
\r
if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
- return EFI_INVALID_PARAMETER;\r
+ if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
}\r
\r
if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
return Result;\r
}\r
\r
+ if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) {\r
+ if (Value1->Type != Value2->Type) {\r
+ //\r
+ // Both Operator should be type of Buffer.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen;\r
+ Result = CompareMem (Value1->Buffer, Value2->Buffer, Len);\r
+ if ((Result == 0) && (Value1->BufferLen != Value2->BufferLen))\r
+ {\r
+ //\r
+ // In this case, means base on samll number buffer, the data is same\r
+ // So which value has more data, which value is bigger.\r
+ //\r
+ Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1;\r
+ }\r
+ return Result;\r
+ } \r
+\r
//\r
// Take remain types(integer, boolean, date/time) as integer\r
//\r
RemainSize = UserInfo->InfoSize - sizeof (EFI_USER_INFO);\r
AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)(UserInfo + 1);\r
while (RemainSize >= sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
- if (RemainSize < AccessControl->Size || AccessControl->Size <= sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
+ if (RemainSize < AccessControl->Size || AccessControl->Size < sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
break;\r
}\r
if (AccessControl->Type == EFI_USER_INFO_ACCESS_SETUP) {\r
if (OpCode->VarStorage != NULL) {\r
switch (OpCode->VarStorage->Type) {\r
case EFI_HII_VARSTORE_BUFFER:\r
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
//\r
// Get value from Edit Buffer\r
//\r
//\r
Status = GetValueByName (OpCode->VarStorage, OpCode->ValueName, &StrPtr);\r
if (!EFI_ERROR (Status)) {\r
+ ASSERT (StrPtr != NULL);\r
TempLength = StrLen (StrPtr);\r
if (OpCode->ValueWidth >= ((TempLength + 1) / 2)) {\r
Value->Type = OpCode->ValueType;\r
if ((Index & 1) == 0) {\r
TempBuffer [Index/2] = DigitUint8;\r
} else {\r
- TempBuffer [Index/2] = (UINT8) ((DigitUint8 << 4) + TempStr [Index/2]);\r
+ TempBuffer [Index/2] = (UINT8) ((DigitUint8 << 4) + TempBuffer [Index/2]);\r
}\r
}\r
} \r
Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
Value->Value.u8 = 0;\r
}\r
+ break;\r
default:\r
//\r
// Not recognize storage.\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- if (Value->Type != EFI_IFR_TYPE_STRING) {\r
+ if (Value->Type != EFI_IFR_TYPE_STRING && Value->Type != EFI_IFR_TYPE_BUFFER) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
\r
- StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
- if (StrPtr == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
+ if (Value->Type == EFI_IFR_TYPE_STRING) {\r
+ StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
+ if (StrPtr == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = StrLen (StrPtr);\r
- FreePool (StrPtr);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ Value->Value.u64 = StrLen (StrPtr);\r
+ FreePool (StrPtr);\r
+ } else {\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ Value->Value.u64 = Value->BufferLen;\r
+ FreePool (Value->Buffer);\r
+ }\r
break;\r
\r
case EFI_IFR_NOT_OP:\r
//\r
// When converting from a string, if case-insensitive compare\r
// with "true" is True, then push True. If a case-insensitive compare\r
- // with "false" is True, then push False.\r
+ // with "false" is True, then push False. Otherwise, push Undefined. \r
//\r
StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
if (StrPtr == NULL) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
-\r
- if ((StrCmp (StrPtr, L"true") == 0) || (StrCmp (StrPtr, L"false") == 0)){\r
+ \r
+ IfrStrToUpper (StrPtr);\r
+ if (StrCmp (StrPtr, L"TRUE") == 0){\r
Value->Value.b = TRUE;\r
- } else {\r
+ } else if (StrCmp (StrPtr, L"FALSE") == 0) {\r
Value->Value.b = FALSE;\r
+ } else {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ FreePool (StrPtr);\r
+ goto Done;\r
}\r
FreePool (StrPtr);\r
Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ } else if (Value->Type == EFI_IFR_TYPE_BUFFER) {\r
+ //\r
+ // When converting from a buffer, if the buffer is all zeroes, \r
+ // then push False. Otherwise push True. \r
+ //\r
+ for (Index =0; Index < Value->BufferLen; Index ++) {\r
+ if (Value->Buffer[Index] != 0) { \r
+ break;\r
+ }\r
+ }\r
+\r
+ if (Index >= Value->BufferLen) {\r
+ Value->Value.b = FALSE;\r
+ } else {\r
+ Value->Value.b = TRUE;\r
+ }\r
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ FreePool (Value->Buffer);\r
}\r
break;\r
\r
if (OpCode->VarStorage != NULL) {\r
switch (OpCode->VarStorage->Type) {\r
case EFI_HII_VARSTORE_BUFFER:\r
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
CopyMem (OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth);\r
Data1.Value.b = TRUE;\r
break;\r
for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {\r
StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);\r
}\r
- Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue);\r
+ Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, TRUE);\r
FreePool (NameValue);\r
if (!EFI_ERROR (Status)) {\r
Data1.Value.b = TRUE;\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) {\r
+ if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && \r
+ Data2.Type != EFI_IFR_TYPE_STRING && \r
+ Data2.Type != EFI_IFR_TYPE_BUFFER) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
}\r
\r
Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle);\r
+ if (Data1.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Data1.Buffer);\r
+ FreePool (Data2.Buffer);\r
+ }\r
+ \r
if (Result == EFI_INVALID_PARAMETER) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
break;\r
\r
case EFI_IFR_MATCH_OP:\r
+ Status = InitializeUnicodeCollationProtocol ();\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ \r
Status = IfrMatch (FormSet, Value);\r
break;\r
\r