]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
Update comments in BaseExtractGuidedSectionLib library instance to say its used memor...
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Expression.c
index 90fdc7462ffa17dfab6f7c41ce3615c5c1b0d02c..883693fde59233acd397001b1bf3d8b290bb5246 100644 (file)
@@ -1,8 +1,8 @@
 /** @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
@@ -140,6 +140,11 @@ PushStack (
   // 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
@@ -703,6 +708,7 @@ IfrToString (
   CHAR16         *String;\r
   CHAR16         *PrintFormat;\r
   CHAR16         Buffer[MAXIMUM_VALUE_CHARACTERS];\r
+  UINT8          *TmpBuf;\r
   UINTN          BufferSize;\r
 \r
   Status = PopExpression (&Value);\r
@@ -744,7 +750,27 @@ IfrToString (
   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
@@ -781,7 +807,7 @@ IfrToUint (
     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
@@ -806,6 +832,13 @@ 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
+      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
@@ -832,7 +865,7 @@ IfrCatenate (
   )\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
@@ -846,35 +879,54 @@ IfrCatenate (
   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
@@ -1061,6 +1113,8 @@ IfrMid (
   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
@@ -1084,28 +1138,46 @@ IfrMid (
   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
@@ -1392,9 +1464,12 @@ CompareHiiValue (
   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
@@ -1438,6 +1513,26 @@ CompareHiiValue (
     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
@@ -1528,7 +1623,7 @@ CheckUserPrivilege (
     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
@@ -1716,6 +1811,7 @@ EvaluateExpression (
       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
@@ -1729,6 +1825,7 @@ EvaluateExpression (
             //\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
@@ -1740,7 +1837,7 @@ EvaluateExpression (
                   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
@@ -1764,6 +1861,7 @@ EvaluateExpression (
             Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
             Value->Value.u8 = 0;\r
           }\r
+          break;\r
         default:\r
           //\r
           // Not recognize storage.\r
@@ -1922,20 +2020,26 @@ EvaluateExpression (
       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
@@ -2031,21 +2135,44 @@ EvaluateExpression (
         //\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
@@ -2122,6 +2249,7 @@ EvaluateExpression (
       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
@@ -2137,7 +2265,7 @@ EvaluateExpression (
             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
@@ -2350,7 +2478,9 @@ EvaluateExpression (
       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
@@ -2364,6 +2494,11 @@ EvaluateExpression (
       }\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
@@ -2400,6 +2535,11 @@ EvaluateExpression (
       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