]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
MdeModulePkg: Replace [Ascii|Unicode]ValueToString
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
index 920c839956d67a0c25850223e3eddcacb318b427..6b3e5e098e910ba8aea2a2b9daf6d73a4d808173 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Parser for IFR binary encoding.\r
 \r
-Copyright (c) 2007 - 2013, 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
@@ -22,7 +22,7 @@ extern LIST_ENTRY      gBrowserStorageList;
   Initialize Statement header members.\r
 \r
   @param  OpCodeData             Pointer of the raw OpCode data.\r
-  @param  FormSet                Pointer of the current FormSe.\r
+  @param  FormSet                Pointer of the current FormSet.\r
   @param  Form                   Pointer of the current Form.\r
 \r
   @return The Statement.\r
@@ -116,7 +116,7 @@ UpdateCheckBoxStringToken (
   ASSERT (Statement != NULL);\r
   ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);\r
 \r
-  UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);\r
+  UnicodeValueToStringS (Str, sizeof (Str), 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);\r
 \r
   Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);\r
   if (Id == 0) {\r
@@ -320,20 +320,20 @@ CreateExpression (
 EFI_STATUS\r
 InitializeConfigHdr (\r
   IN FORM_BROWSER_FORMSET  *FormSet,\r
-  IN OUT BROWSER_STORAGE   *Storage\r
+  IN OUT FORMSET_STORAGE   *Storage\r
   )\r
 {\r
   CHAR16      *Name;\r
 \r
-  if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
-      Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
-    Name = Storage->Name;\r
+  if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER || \r
+      Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+    Name = Storage->BrowserStorage->Name;\r
   } else {\r
     Name = NULL;\r
   }\r
 \r
   Storage->ConfigHdr = HiiConstructConfigHdr (\r
-                         &Storage->Guid,\r
+                         &Storage->BrowserStorage->Guid,\r
                          Name,\r
                          FormSet->DriverHandle\r
                          );\r
@@ -451,6 +451,40 @@ IntializeBrowserStorage (
   }\r
 }\r
 \r
+/**\r
+  Check whether exist device path info in the ConfigHdr string.\r
+\r
+  @param  String                 UEFI configuration string\r
+\r
+  @retval TRUE                   Device Path exist.\r
+  @retval FALSE                  Not exist device path info.\r
+\r
+**/\r
+BOOLEAN\r
+IsDevicePathExist (\r
+  IN  EFI_STRING                   String\r
+  )\r
+{\r
+  UINTN                    Length;\r
+\r
+  for (; (*String != 0 && StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0); String++);\r
+  if (*String == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  String += StrLen (L"PATH=");\r
+  if (*String == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  for (Length = 0; *String != 0 && *String != L'&'; String++, Length++);\r
+  if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
 /**\r
   Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
 \r
@@ -525,18 +559,108 @@ CreateStorage (
     }\r
 \r
     BrowserStorage->HiiHandle = FormSet->HiiHandle;\r
-    InitializeConfigHdr (FormSet, BrowserStorage);\r
 \r
     BrowserStorage->Initialized = FALSE;\r
   }\r
 \r
   Storage->BrowserStorage = BrowserStorage;\r
-  Storage->ConfigRequest = AllocateCopyPool (StrSize (BrowserStorage->ConfigHdr), BrowserStorage->ConfigHdr);\r
+  InitializeConfigHdr (FormSet, Storage);\r
+  Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);\r
   Storage->SpareStrLen = 0;\r
 \r
   return Storage;\r
 }\r
 \r
+/**\r
+  Get Formset_storage base on the input varstoreid info.\r
+\r
+  @param  FormSet                Pointer of the current FormSet.\r
+  @param  VarStoreId             Varstore ID info.\r
+\r
+  @return Pointer to a FORMSET_STORAGE data structure.\r
+\r
+**/\r
+FORMSET_STORAGE *\r
+GetFstStgFromVarId (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN EFI_VARSTORE_ID       VarStoreId\r
+  )\r
+{\r
+  FORMSET_STORAGE  *FormsetStorage;\r
+  LIST_ENTRY       *Link;\r
+  BOOLEAN          Found;\r
+\r
+  Found = FALSE;\r
+  FormsetStorage = NULL;\r
+  //\r
+  // Find Formset Storage for this Question\r
+  //\r
+  Link = GetFirstNode (&FormSet->StorageListHead);\r
+  while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+    FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+\r
+    if (FormsetStorage->VarStoreId == VarStoreId) {\r
+      Found = TRUE;\r
+      break;\r
+    }\r
+\r
+    Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+  }\r
+\r
+  return Found ? FormsetStorage : NULL;\r
+}\r
+\r
+/**\r
+  Get Formset_storage base on the input browser storage.\r
+\r
+  More than one formsets may share the same browser storage,\r
+  this function just get the first formset storage which\r
+  share the browser storage.\r
+\r
+  @param  Storage              browser storage info.\r
+\r
+  @return Pointer to a FORMSET_STORAGE data structure.\r
+  \r
+\r
+**/\r
+FORMSET_STORAGE *\r
+GetFstStgFromBrsStg (\r
+  IN BROWSER_STORAGE       *Storage\r
+  )\r
+{\r
+  FORMSET_STORAGE      *FormsetStorage;\r
+  LIST_ENTRY           *Link;\r
+  LIST_ENTRY           *FormsetLink;\r
+  FORM_BROWSER_FORMSET *FormSet;\r
+  BOOLEAN              Found;\r
+\r
+  Found = FALSE;\r
+  FormsetStorage = NULL;\r
+\r
+  FormsetLink = GetFirstNode (&gBrowserFormSetList);\r
+  while (!IsNull (&gBrowserFormSetList, FormsetLink)) {\r
+    FormSet = FORM_BROWSER_FORMSET_FROM_LINK (FormsetLink);\r
+    FormsetLink = GetNextNode (&gBrowserFormSetList, FormsetLink);\r
+\r
+    Link = GetFirstNode (&FormSet->StorageListHead);\r
+    while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+      FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
+      Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+      if (FormsetStorage->BrowserStorage == Storage) {\r
+        Found = TRUE;\r
+        break;\r
+      }\r
+    }\r
+\r
+    if (Found) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  return Found ? FormsetStorage : NULL;\r
+}\r
+\r
 /**\r
   Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>\r
 \r
@@ -564,6 +688,7 @@ InitializeRequestElement (
   LIST_ENTRY       *Link;\r
   BOOLEAN          Find;\r
   FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
+  UINTN            MaxLen;\r
 \r
   Storage = Question->Storage;\r
   if (Storage == NULL) {\r
@@ -586,10 +711,11 @@ InitializeRequestElement (
     StrLen = UnicodeSPrint (\r
                RequestElement,\r
                30 * sizeof (CHAR16),\r
-               L"&OFFSET=%x&WIDTH=%x",\r
+               L"&OFFSET=%04x&WIDTH=%04x",\r
                Question->VarStoreInfo.VarOffset,\r
                Question->StorageWidth\r
                );\r
+    HiiToLower(RequestElement);\r
     Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
   } else {\r
     StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\r
@@ -606,18 +732,10 @@ InitializeRequestElement (
   //\r
   // Find Formset Storage for this Question\r
   //\r
-  FormsetStorage = NULL;\r
-  Link = GetFirstNode (&FormSet->StorageListHead);\r
-  while (!IsNull (&FormSet->StorageListHead, Link)) {\r
-    FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
-\r
-    if (FormsetStorage->VarStoreId == Question->VarStoreId) {\r
-      break;\r
-    }\r
-\r
-    Link = GetNextNode (&FormSet->StorageListHead, Link);\r
-  }\r
+  FormsetStorage = GetFstStgFromVarId(FormSet, Question->VarStoreId);\r
   ASSERT (FormsetStorage != NULL);\r
+  StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);\r
+  MaxLen = StringSize / sizeof (CHAR16) + FormsetStorage->SpareStrLen;\r
 \r
   //\r
   // Append <RequestElement> to <ConfigRequest>\r
@@ -626,8 +744,8 @@ InitializeRequestElement (
     //\r
     // Old String buffer is not sufficient for RequestElement, allocate a new one\r
     //\r
-    StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);\r
-    NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+    MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;\r
+    NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
     ASSERT (NewStr != NULL);\r
     if (FormsetStorage->ConfigRequest != NULL) {\r
       CopyMem (NewStr, FormsetStorage->ConfigRequest, StringSize);\r
@@ -637,7 +755,7 @@ InitializeRequestElement (
     FormsetStorage->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;\r
   }\r
 \r
-  StrCat (FormsetStorage->ConfigRequest, RequestElement);\r
+  StrCatS (FormsetStorage->ConfigRequest, MaxLen, RequestElement);\r
   FormsetStorage->ElementCount++;\r
   FormsetStorage->SpareStrLen -= StrLen;\r
 \r
@@ -650,7 +768,7 @@ InitializeRequestElement (
   while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
     ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
 \r
-    if (ConfigInfo != NULL && ConfigInfo->Storage == Storage) {\r
+    if (ConfigInfo != NULL && ConfigInfo->Storage == FormsetStorage->BrowserStorage) {\r
       Find = TRUE;\r
       break;\r
     }\r
@@ -662,11 +780,14 @@ InitializeRequestElement (
     ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));\r
     ASSERT (ConfigInfo != NULL);\r
     ConfigInfo->Signature     = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;\r
-    ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);\r
+    ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (FormsetStorage->ConfigHdr), FormsetStorage->ConfigHdr);\r
+    ASSERT (ConfigInfo->ConfigRequest != NULL);\r
     ConfigInfo->SpareStrLen   = 0;\r
-    ConfigInfo->Storage       = Storage;\r
+    ConfigInfo->Storage       = FormsetStorage->BrowserStorage;\r
     InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);\r
   }\r
+  StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);\r
+  MaxLen = StringSize / sizeof (CHAR16) + ConfigInfo->SpareStrLen;\r
 \r
   //\r
   // Append <RequestElement> to <ConfigRequest>\r
@@ -675,8 +796,8 @@ InitializeRequestElement (
     //\r
     // Old String buffer is not sufficient for RequestElement, allocate a new one\r
     //\r
-    StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);\r
-    NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+    MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;\r
+    NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
     ASSERT (NewStr != NULL);\r
     if (ConfigInfo->ConfigRequest != NULL) {\r
       CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);\r
@@ -686,7 +807,7 @@ InitializeRequestElement (
     ConfigInfo->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;\r
   }\r
 \r
-  StrCat (ConfigInfo->ConfigRequest, RequestElement);\r
+  StrCatS (ConfigInfo->ConfigRequest, MaxLen, RequestElement);\r
   ConfigInfo->ElementCount++;\r
   ConfigInfo->SpareStrLen -= StrLen;\r
   return EFI_SUCCESS;\r
@@ -787,6 +908,9 @@ DestroyStatement (
     Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
     RemoveEntryList (&Default->Link);\r
 \r
+    if (Default->Value.Buffer != NULL) {\r
+      FreePool (Default->Value.Buffer);\r
+    }\r
     FreePool (Default);\r
   }\r
 \r
@@ -912,6 +1036,8 @@ DestroyForm (
     FreePool (Form->SuppressExpression);\r
   }\r
 \r
+  UiFreeMenuList (&Form->FormViewListHead);\r
+\r
   //\r
   // Free this Form\r
   //\r
@@ -1032,7 +1158,8 @@ IsExpressionOpCode (
       (Operand == EFI_IFR_TO_UPPER_OP) ||\r
       (Operand == EFI_IFR_MAP_OP)      ||\r
       (Operand == EFI_IFR_VERSION_OP)  ||\r
-      (Operand == EFI_IFR_SECURITY_OP)) {\r
+      (Operand == EFI_IFR_SECURITY_OP) ||\r
+      (Operand == EFI_IFR_MATCH2_OP)) {\r
     return TRUE;\r
   } else {\r
     return FALSE;\r
@@ -1087,7 +1214,7 @@ IsUnKnownOpCode (
   IN UINT8              Operand\r
   )\r
 {\r
-  return Operand > EFI_IFR_WARNING_IF_OP ? TRUE : FALSE;\r
+  return Operand > EFI_IFR_MATCH2_OP ? TRUE : FALSE;\r
 }\r
 \r
 /**\r
@@ -1184,6 +1311,9 @@ ParseOpCodes (
   INTN                    ConditionalExprCount;\r
   BOOLEAN                 InUnknownScope;\r
   UINT8                   UnknownDepth;\r
+  FORMSET_DEFAULTSTORE    *PreDefaultStore;\r
+  LIST_ENTRY              *DefaultLink;\r
+  BOOLEAN                 HaveInserted;\r
 \r
   SuppressForQuestion      = FALSE;\r
   SuppressForOption        = FALSE;\r
@@ -1226,6 +1356,7 @@ ParseOpCodes (
 \r
   InitializeListHead (&FormSet->StatementListOSF);\r
   InitializeListHead (&FormSet->StorageListHead);\r
+  InitializeListHead (&FormSet->SaveFailStorageListHead);\r
   InitializeListHead (&FormSet->DefaultStoreListHead);\r
   InitializeListHead (&FormSet->FormListHead);\r
   InitializeListHead (&FormSet->ExpressionListHead);\r
@@ -1358,6 +1489,10 @@ ParseOpCodes (
         CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));\r
         break;\r
 \r
+      case EFI_IFR_MATCH2_OP:\r
+        CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_MATCH2 *) OpCodeData)->SyntaxType, sizeof (EFI_GUID));\r
+        break;\r
+\r
       case EFI_IFR_GET_OP:\r
       case EFI_IFR_SET_OP:\r
         CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));\r
@@ -1559,11 +1694,7 @@ ParseOpCodes (
             return Status;\r
           }\r
 \r
-          if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
-            return EFI_INVALID_PARAMETER;\r
-          }\r
-\r
-          OpCodeDisabled = CurrentExpression->Result.Value.b;\r
+          OpCodeDisabled = IsTrue(&CurrentExpression->Result);\r
         }\r
 \r
         CurrentExpression = NULL;\r
@@ -1587,6 +1718,7 @@ ParseOpCodes (
 \r
       CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
       CopyMem (&FormSet->Help,         &((EFI_IFR_FORM_SET *) OpCodeData)->Help,         sizeof (EFI_STRING_ID));\r
+      FormSet->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;//save the opcode address of formset\r
 \r
       if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
         //\r
@@ -1607,6 +1739,7 @@ ParseOpCodes (
       InitializeListHead (&CurrentForm->ExpressionListHead);\r
       InitializeListHead (&CurrentForm->StatementListHead);\r
       InitializeListHead (&CurrentForm->ConfigRequestHead);\r
+      InitializeListHead (&CurrentForm->FormViewListHead);\r
 \r
       CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));\r
@@ -1648,6 +1781,8 @@ ParseOpCodes (
       InitializeListHead (&CurrentForm->ExpressionListHead);\r
       InitializeListHead (&CurrentForm->StatementListHead);\r
       InitializeListHead (&CurrentForm->ConfigRequestHead);\r
+      InitializeListHead (&CurrentForm->FormViewListHead);\r
+\r
       CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
 \r
       MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
@@ -1743,17 +1878,31 @@ ParseOpCodes (
     // DefaultStore\r
     //\r
     case EFI_IFR_DEFAULTSTORE_OP:\r
+      HaveInserted = FALSE;\r
       DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
       ASSERT (DefaultStore != NULL);\r
       DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
 \r
       CopyMem (&DefaultStore->DefaultId,   &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId,   sizeof (UINT16));\r
       CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
-\r
       //\r
-      // Insert to DefaultStore list of this Formset\r
+      // Insert it to the DefaultStore list of this Formset with ascending order.\r
       //\r
-      InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
+      if (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
+        DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
+        while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r
+          PreDefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
+          DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);\r
+          if (DefaultStore->DefaultId < PreDefaultStore->DefaultId) {\r
+            InsertTailList (&PreDefaultStore->Link, &DefaultStore->Link);\r
+            HaveInserted = TRUE;\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      if (!HaveInserted) {\r
+        InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
+      }\r
       break;\r
 \r
     //\r
@@ -1996,7 +2145,11 @@ ParseOpCodes (
 \r
       CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
       CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
-      if (OpCodeLength > OFFSET_OF (EFI_IFR_DEFAULT, Value)) {\r
+      if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+        CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
+        CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *) OpCodeData)->Value);\r
+        ASSERT (CurrentDefault->Value.Buffer != NULL);\r
+      } else {\r
         CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
         ExtendValueToU64 (&CurrentDefault->Value);\r
       }\r
@@ -2015,6 +2168,33 @@ ParseOpCodes (
     // Option\r
     //\r
     case EFI_IFR_ONE_OF_OPTION_OP:\r
+      ASSERT (ParentStatement != NULL);\r
+      if (ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP && ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG)) != 0)) {\r
+        //\r
+        // It's keep the default value for ordered list opcode.\r
+        //\r
+        CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
+        ASSERT (CurrentDefault != NULL);\r
+        CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
+\r
+        CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;\r
+        if ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {\r
+          CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+        } else {\r
+          CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+        }\r
+\r
+        CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
+        CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value);\r
+        ASSERT (CurrentDefault->Value.Buffer != NULL);\r
+\r
+        //\r
+        // Insert to Default Value list of current Question\r
+        //\r
+        InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);\r
+        break;\r
+      }\r
+\r
       //\r
       // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
       // It create a selection for use in current Question.\r
@@ -2043,7 +2223,6 @@ ParseOpCodes (
         CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));\r
       }\r
 \r
-      ASSERT (ParentStatement != NULL);\r
       //\r
       // Insert to Option list of current Question\r
       //\r
@@ -2331,6 +2510,7 @@ ParseOpCodes (
         break;\r
 \r
       case EFI_IFR_ONE_OF_OPTION_OP:\r
+        ASSERT (CurrentOption != NULL);\r
         ImageId = &CurrentOption->ImageId;\r
         break;\r
 \r
@@ -2361,8 +2541,24 @@ ParseOpCodes (
     // Refresh guid.\r
     //\r
     case EFI_IFR_REFRESH_ID_OP:\r
-      ASSERT (ParentStatement != NULL);\r
-      CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
+      //\r
+      // Get ScopeOpcode from top of stack\r
+      //\r
+      PopScope (&ScopeOpCode);\r
+      PushScope (ScopeOpCode);\r
+\r
+      switch (ScopeOpCode) {\r
+      case EFI_IFR_FORM_OP:\r
+      case EFI_IFR_FORM_MAP_OP:\r
+        ASSERT (CurrentForm != NULL);\r
+        CopyMem (&CurrentForm->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
+        break;\r
+\r
+      default:\r
+        ASSERT (ParentStatement != NULL);\r
+        CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
+        break;\r
+      }\r
       break;\r
 \r
     //\r
@@ -2512,11 +2708,8 @@ ParseOpCodes (
               return Status;\r
             }\r
 \r
-            if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
-              return EFI_INVALID_PARAMETER;\r
-            }\r
+            OpCodeDisabled = IsTrue (&CurrentExpression->Result);\r
 \r
-            OpCodeDisabled = CurrentExpression->Result.Value.b;\r
             //\r
             // DisableIf Expression is only used once and not queued, free it\r
             //\r