]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
MdeModulePkg: Fix MSFT C4255 warning
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Expression.c
index ff46fcbc5a7df49a30eb39692baa7ac780f58cf6..297741c0fe9df9d031bd064e5f94e6472c7af8b3 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Utility functions for expression evaluation.\r
 \r
-Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2017, 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
@@ -751,6 +751,7 @@ PopExpression (
 **/\r
 UINTN\r
 SaveExpressionEvaluationStackOffset (\r
+  VOID\r
   )\r
 {\r
   UINTN TempStackOffset;\r
@@ -787,7 +788,7 @@ FORM_BROWSER_FORM *
 IdToForm (\r
   IN FORM_BROWSER_FORMSET  *FormSet,\r
   IN UINT16                FormId\r
-)\r
+  )\r
 {\r
   LIST_ENTRY         *Link;\r
   FORM_BROWSER_FORM  *Form;\r
@@ -988,6 +989,129 @@ IfrStrToUpper (
   }\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
@@ -1013,6 +1137,8 @@ IfrToString (
   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
@@ -1057,24 +1183,37 @@ IfrToString (
     break;\r
     \r
   case EFI_IFR_TYPE_BUFFER:\r
+  case EFI_IFR_TYPE_DATE:\r
+  case EFI_IFR_TYPE_TIME:\r
+  case EFI_IFR_TYPE_REF:\r
     //\r
     // + 3 is base on the unicode format, the length may be odd number, \r
     // so need 1 byte to align, also need 2 bytes for L'\0'.\r
     //\r
-    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
+      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
+      CopyMem (TmpBuf, SrcBuf, SrcLen * sizeof (CHAR16));\r
       PrintFormat = L"%s";  \r
     }\r
-    UnicodeSPrint (Buffer, MAXIMUM_VALUE_CHARACTERS, PrintFormat, Value.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
   default:\r
@@ -1114,7 +1253,7 @@ IfrToUint (
     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
@@ -1140,14 +1279,18 @@ IfrToUint (
       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
@@ -1179,6 +1322,10 @@ IfrCatenate (
   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
@@ -1201,7 +1348,7 @@ IfrCatenate (
   }\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
@@ -1218,22 +1365,29 @@ IfrCatenate (
 \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
@@ -1324,6 +1478,180 @@ Done:
   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
@@ -1446,8 +1774,8 @@ IfrMid (
   UINTN          Base;\r
   UINTN          Length;\r
   CHAR16         *SubString;\r
-  UINT8          *Buffer;\r
   UINT16         BufferLen;\r
+  UINT8          *Buffer;\r
 \r
   ZeroMem (Value, sizeof (Value));\r
 \r
@@ -1478,7 +1806,7 @@ IfrMid (
   }\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
@@ -1502,9 +1830,9 @@ IfrMid (
 \r
     FreePool (String);\r
   } else {\r
-    Buffer    = Value[2].Buffer;\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
@@ -1513,10 +1841,12 @@ IfrMid (
       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
   return Status;\r
@@ -1801,6 +2131,55 @@ ExtendValueToU64 (
   Value->Value.u64 = Temp;\r
 }\r
 \r
+/**\r
+  Get UINT64 type value.\r
+\r
+  @param  Value                  Input Hii value.\r
+\r
+  @retval UINT64                 Return the UINT64 type value.\r
+\r
+**/\r
+UINT64\r
+HiiValueToUINT64 (\r
+  IN EFI_HII_VALUE      *Value\r
+  )\r
+{\r
+  UINT64  RetVal;\r
+\r
+  RetVal = 0;\r
+\r
+  switch (Value->Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+    RetVal = Value->Value.u8;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+    RetVal = Value->Value.u16;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+    RetVal = Value->Value.u32;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_BOOLEAN:\r
+    RetVal = Value->Value.b;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_DATE:\r
+    RetVal = *(UINT64*) &Value->Value.date;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_TIME:\r
+    RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff;\r
+    break;\r
+\r
+  default:\r
+    RetVal = Value->Value.u64;\r
+    break;\r
+  }\r
+\r
+  return RetVal;\r
+}\r
 \r
 /**\r
   Compare two Hii value.\r
@@ -1829,21 +2208,12 @@ CompareHiiValue (
   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
@@ -1878,39 +2248,44 @@ CompareHiiValue (
     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
-  // Take remain types(integer, boolean, date/time) as integer\r
+  // Take types(integer, boolean) as integer\r
   //\r
-  Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);\r
-  if (Temp64 > 0) {\r
-    *Result = 1;\r
-  } else if (Temp64 < 0) {\r
-    *Result = -1;\r
-  } else {\r
-    *Result = 0;\r
+  if (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
@@ -2038,11 +2413,7 @@ GetQuestionValueFromForm (
   )\r
 {\r
   EFI_STATUS                   Status;\r
-  EFI_HANDLE                   DriverHandle;\r
-  EFI_HANDLE                   Handle;\r
-  EFI_HII_HANDLE               *HiiHandles;\r
   EFI_HII_HANDLE               HiiHandle;\r
-  UINTN                        Index;\r
   FORM_BROWSER_STATEMENT       *Question;\r
   FORM_BROWSER_FORMSET         *FormSet;\r
   FORM_BROWSER_FORM            *Form;\r
@@ -2056,7 +2427,6 @@ GetQuestionValueFromForm (
           (DevicePath == NULL && InputHiiHandle != NULL) );\r
 \r
   GetTheVal    = TRUE;\r
-  DriverHandle = NULL;\r
   HiiHandle    = NULL;\r
   Question     = NULL;\r
   Form         = NULL;\r
@@ -2065,38 +2435,10 @@ GetQuestionValueFromForm (
   // Get HiiHandle.\r
   //\r
   if (DevicePath != NULL) {\r
-    //\r
-    // 1. Get Driver handle.\r
-    //\r
-    Status = gBS->LocateDevicePath (\r
-                    &gEfiDevicePathProtocolGuid,\r
-                    &DevicePath,\r
-                    &DriverHandle\r
-                    );\r
-    if (EFI_ERROR (Status) || (DriverHandle == NULL)) {\r
-      return FALSE;\r
-    }\r
-\r
-    //\r
-    // 2. Get Hii handle\r
-    //\r
-    HiiHandles = HiiGetHiiHandles (NULL);\r
-    if (HiiHandles == NULL) {\r
+    HiiHandle = DevicePathToHiiHandle (DevicePath, FormSetGuid);\r
+    if (HiiHandle == NULL) {\r
       return FALSE;\r
     }\r
-\r
-    for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
-      Status = mHiiDatabase->GetPackageListHandle (\r
-                               mHiiDatabase,\r
-                               HiiHandles[Index],\r
-                               &Handle\r
-                               );\r
-      if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
-        HiiHandle = HiiHandles[Index];\r
-        break;\r
-      }\r
-    }\r
-    FreePool (HiiHandles);\r
   } else {\r
     HiiHandle = InputHiiHandle;\r
   } \r
@@ -2107,7 +2449,7 @@ GetQuestionValueFromForm (
   //\r
   FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
   ASSERT (FormSet != NULL);\r
-  Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet, FALSE);\r
+  Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet);\r
   if (EFI_ERROR (Status)) {\r
     GetTheVal = FALSE;\r
     goto Done;\r
@@ -2142,7 +2484,7 @@ GetQuestionValueFromForm (
   //\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
@@ -2210,6 +2552,9 @@ EvaluateExpression (
   UINT8                   *TempBuffer;\r
   EFI_TIME                EfiTime;\r
   EFI_HII_VALUE           QuestionVal;\r
+  EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+\r
+  StrPtr = NULL;\r
 \r
   //\r
   // Save current stack offset.\r
@@ -2469,18 +2814,23 @@ EvaluateExpression (
       }\r
 \r
       if (OpCode->DevicePath != 0) {\r
+        Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
+\r
         StrPtr = GetToken (OpCode->DevicePath, FormSet->HiiHandle);\r
-        if (StrPtr == NULL) {\r
-          Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
-          break;\r
+        if (StrPtr != NULL && mPathFromText != NULL) {\r
+          DevicePath = mPathFromText->ConvertTextToDevicePath(StrPtr);\r
+          if (DevicePath != NULL && GetQuestionValueFromForm(DevicePath, NULL, &OpCode->Guid, Value->Value.u16, &QuestionVal)) {\r
+            Value = &QuestionVal;\r
+          }\r
+          if (DevicePath != NULL) {\r
+            FreePool (DevicePath);\r
+          }\r
         }\r
 \r
-        if (!GetQuestionValueFromForm((EFI_DEVICE_PATH_PROTOCOL*)StrPtr, NULL, &OpCode->Guid, Value->Value.u16, &QuestionVal)){\r
-          Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
-          break;\r
+        if (StrPtr != NULL) {\r
+          FreePool (StrPtr);\r
         }\r
-        Value = &QuestionVal;\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
@@ -2552,7 +2902,7 @@ EvaluateExpression (
       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
@@ -2569,7 +2919,7 @@ EvaluateExpression (
         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
@@ -2660,7 +3010,7 @@ EvaluateExpression (
         // 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
@@ -2761,7 +3111,7 @@ EvaluateExpression (
       }\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
@@ -2787,16 +3137,23 @@ EvaluateExpression (
         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);\r
+            Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer, NULL);\r
             FreePool (NameValue);\r
             if (!EFI_ERROR (Status)) {\r
               Data1.Value.b = TRUE;\r
@@ -2821,7 +3178,6 @@ EvaluateExpression (
           //\r
           Status = EFI_UNSUPPORTED;\r
           goto Done;\r
-          break;\r
         }\r
       } else {\r
         //\r
@@ -2925,40 +3281,40 @@ EvaluateExpression (
 \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
@@ -3025,14 +3381,14 @@ EvaluateExpression (
 \r
       if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && \r
           Data2.Type != EFI_IFR_TYPE_STRING && \r
-          Data2.Type != EFI_IFR_TYPE_BUFFER) {\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
+          !IsTypeInBuffer(&Data1)) {\r
         Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
         break;\r
       }\r
@@ -3040,6 +3396,8 @@ EvaluateExpression (
       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
@@ -3092,6 +3450,10 @@ EvaluateExpression (
       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
@@ -3260,6 +3622,44 @@ Done:
   return Status;\r
 }\r
 \r
+/**\r
+  Check whether the result is TRUE or FALSE.\r
+  \r
+  For the EFI_HII_VALUE value type is numeric, return TRUE if the\r
+  value is not 0.\r
+\r
+  @param  Result             Input the result data.\r
+\r
+  @retval TRUE               The result is TRUE.\r
+  @retval FALSE              The result is FALSE.\r
+\r
+**/\r
+BOOLEAN\r
+IsTrue (\r
+  IN EFI_HII_VALUE     *Result\r
+  )\r
+{\r
+  switch (Result->Type) {\r
+  case EFI_IFR_TYPE_BOOLEAN:\r
+    return Result->Value.b;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+    return (BOOLEAN)(Result->Value.u8 != 0);\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+    return (BOOLEAN)(Result->Value.u16 != 0);\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+    return (BOOLEAN)(Result->Value.u32 != 0);\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_64:\r
+    return (BOOLEAN)(Result->Value.u64 != 0);\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+}\r
+\r
 /**\r
   Return the result of the expression list. Check the expression list and \r
   return the highest priority express result.  \r
@@ -3311,8 +3711,7 @@ EvaluateExpressionList (
   //\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