]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
Enable buffer type when process some expression opcode which support buffer type.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Expression.c
index aba565ca64320dc4024eb3113f77c32435f1e124..883693fde59233acd397001b1bf3d8b290bb5246 100644 (file)
@@ -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
@@ -1925,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
@@ -2054,6 +2155,24 @@ EvaluateExpression (
         }\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
@@ -2359,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
@@ -2373,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