]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/UefiIfrParser.c
Fix a bug about the iSCSI DHCP dependency issue.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / UefiIfrParser.c
index d58d62c58abbcaa431f48e6bbbb28e0569f2cfc9..4c4411fabb9328d49deeab941517aa1874bf6cd1 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
 Parser for IFR binary encoding.\r
 \r
-Copyright (c) 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2008 - 2010, 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
@@ -12,24 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <PiDxe.h>\r
-\r
-#include <Protocol/HiiConfigAccess.h>\r
-#include <Protocol/HiiConfigRouting.h>\r
-#include <Protocol/HiiDatabase.h>\r
-#include <Protocol/HiiString.h>\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/HiiLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-\r
-#include <Guid/MdeModuleHii.h>\r
-\r
-#include "UefiIfrParser.h"\r
+#include "HiiDatabase.h"\r
 \r
 #include "UefiIfrParserExpression.h"\r
 \r
@@ -42,6 +25,15 @@ BOOLEAN          mInScopeGrayOut;
 EFI_GUID  mFrameworkHiiCompatibilityGuid = EFI_IFR_FRAMEWORK_GUID;\r
 extern EFI_GUID mTianoHiiIfrGuid;\r
 \r
+/**\r
+  Find the question's OneOfOptionMap list in FormSet \r
+  based on the input question Id. \r
+  \r
+  @param FormSet     FormSet context.\r
+  @param QuestionId  Unique ID to specicy the question in FormSet.\r
+  \r
+  @return the found OneOfOptionMap list. If not found, NULL will return.\r
+**/\r
 LIST_ENTRY *\r
 GetOneOfOptionMapEntryListHead (\r
   IN CONST FORM_BROWSER_FORMSET  *FormSet,\r
@@ -64,6 +56,12 @@ GetOneOfOptionMapEntryListHead (
   return NULL;\r
 }\r
 \r
+/**\r
+  Free OneOfOption map list.\r
+  \r
+  @param OneOfOptionMapListHead Pointer to list header of OneOfOptionMap list.\r
+\r
+**/\r
 VOID\r
 DestoryOneOfOptionMap (\r
   IN LIST_ENTRY     *OneOfOptionMapListHead\r
@@ -226,6 +224,7 @@ CreateStorage (
   FORMSET_STORAGE  *Storage;\r
 \r
   Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
+  ASSERT (Storage != NULL);\r
   Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
   InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
 \r
@@ -425,9 +424,14 @@ IsExpressionOpCode (
   )\r
 {\r
   if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
-      ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
-      (Operand == EFI_IFR_CATENATE_OP)\r
-     ) {\r
+      ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP))  ||\r
+      ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
+      (Operand == EFI_IFR_CATENATE_OP) ||\r
+      (Operand == EFI_IFR_TO_LOWER_OP) ||\r
+      (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
     return TRUE;\r
   } else {\r
     return FALSE;\r
@@ -518,12 +522,16 @@ ParseOpCodes (
   ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
   UINT8                   OneOfType;\r
   EFI_IFR_ONE_OF          *OneOfOpcode;\r
+  HII_THUNK_CONTEXT       *ThunkContext;\r
+  EFI_IFR_FORM_MAP_METHOD *MapMethod;\r
 \r
-  mInScopeSubtitle         = FALSE;\r
-  mInScopeSuppress         = FALSE;\r
-  mInScopeGrayOut          = FALSE;\r
-  CurrentDefault           = NULL;\r
-  CurrentOption            = NULL;\r
+  mInScopeSubtitle = FALSE;\r
+  mInScopeSuppress = FALSE;\r
+  mInScopeGrayOut  = FALSE;\r
+  CurrentDefault   = NULL;\r
+  CurrentOption    = NULL;\r
+  MapMethod        = NULL;\r
+  ThunkContext     = UefiHiiHandleToThunkContext ((CONST HII_THUNK_PRIVATE_DATA*) mHiiThunkPrivateData, FormSet->HiiHandle);\r
 \r
   //\r
   // Set to a invalid value.\r
@@ -564,7 +572,7 @@ ParseOpCodes (
     //\r
     // If scope bit set, push onto scope stack\r
     //\r
-    if (Scope) {\r
+    if (Scope != 0) {\r
       PushScope (Operand);\r
     }\r
 \r
@@ -594,6 +602,7 @@ ParseOpCodes (
       // Create a new Form for this FormSet\r
       //\r
       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
+      ASSERT (CurrentForm != NULL);\r
       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
 \r
       InitializeListHead (&CurrentForm->StatementListHead);\r
@@ -607,6 +616,50 @@ ParseOpCodes (
       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
       break;\r
 \r
+    case EFI_IFR_FORM_MAP_OP:\r
+      //\r
+      // Create a new Form Map for this FormSet\r
+      //\r
+      CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
+      ASSERT (CurrentForm != NULL);\r
+      CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
+\r
+      InitializeListHead (&CurrentForm->StatementListHead);\r
+\r
+      CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
+      MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
+\r
+      //\r
+      // FormMap Form must contain at least one Map Method.\r
+      //\r
+      if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      //\r
+      // Try to find the standard form map method.\r
+      //\r
+      while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {\r
+        if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {\r
+          CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
+          break;\r
+        }\r
+        MapMethod ++;\r
+      }\r
+      //\r
+      // If the standard form map method is not found, the first map method title will be used.\r
+      //\r
+      if (CurrentForm->FormTitle == 0) {\r
+        MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
+        CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
+      }\r
+\r
+      //\r
+      // Insert into Form list of this FormSet\r
+      //\r
+      InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
+      break;\r
+\r
     //\r
     // Storage\r
     //\r
@@ -631,7 +684,21 @@ ParseOpCodes (
       break;\r
 \r
     case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
-      ASSERT (FALSE);\r
+      //\r
+      // Framework IFR doesn't support Name/Value VarStore opcode\r
+      //\r
+      if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) {\r
+        ASSERT (FALSE);\r
+      }\r
+\r
+      //\r
+      // Create a name/value Storage for this FormSet\r
+      //\r
+      Storage = CreateStorage (FormSet);\r
+      Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
+\r
+      CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
+      CopyMem (&Storage->Guid,       &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid,       sizeof (EFI_GUID));\r
 \r
       break;\r
 \r
@@ -652,6 +719,7 @@ ParseOpCodes (
     //\r
     case EFI_IFR_DEFAULTSTORE_OP:\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
@@ -668,15 +736,17 @@ ParseOpCodes (
     //\r
     case EFI_IFR_SUBTITLE_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
 \r
-      if (Scope) {\r
+      if (Scope != 0) {\r
         mInScopeSubtitle = TRUE;\r
       }\r
       break;\r
 \r
     case EFI_IFR_TEXT_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
       break;\r
@@ -686,6 +756,7 @@ ParseOpCodes (
     //\r
     case EFI_IFR_ACTION_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
         //\r
@@ -698,13 +769,14 @@ ParseOpCodes (
       break;\r
 \r
     case EFI_IFR_RESET_BUTTON_OP:\r
-      CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
-\r
+      CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
       CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
       break;\r
 \r
     case EFI_IFR_REF_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
       if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
@@ -723,6 +795,7 @@ ParseOpCodes (
     case EFI_IFR_ONE_OF_OP:\r
     case EFI_IFR_NUMERIC_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
       Value = &CurrentStatement->HiiValue;\r
@@ -732,7 +805,7 @@ ParseOpCodes (
         CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
         CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
         CurrentStatement->Step    = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
-        CurrentStatement->StorageWidth = sizeof (UINT8);\r
+        CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r
         Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
         break;\r
 \r
@@ -740,7 +813,7 @@ ParseOpCodes (
         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step,     sizeof (UINT16));\r
-        CurrentStatement->StorageWidth = sizeof (UINT16);\r
+        CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r
         Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
         break;\r
 \r
@@ -748,7 +821,7 @@ ParseOpCodes (
         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step,     sizeof (UINT32));\r
-        CurrentStatement->StorageWidth = sizeof (UINT32);\r
+        CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r
         Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
         break;\r
 \r
@@ -756,7 +829,7 @@ ParseOpCodes (
         CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
         CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
         CopyMem (&CurrentStatement->Step,    &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step,     sizeof (UINT64));\r
-        CurrentStatement->StorageWidth = sizeof (UINT64);\r
+        CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r
         Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
         break;\r
 \r
@@ -772,6 +845,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_ORDERED_LIST_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
       CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
@@ -789,15 +863,17 @@ ParseOpCodes (
 \r
     case EFI_IFR_CHECKBOX_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
-      CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
+      CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
 \r
       break;\r
 \r
     case EFI_IFR_STRING_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       //\r
       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
@@ -816,6 +892,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_PASSWORD_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       //\r
       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
@@ -833,6 +910,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_DATE_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
@@ -841,6 +919,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_TIME_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
@@ -857,6 +936,7 @@ ParseOpCodes (
       // A Question may have more than one Default value which have different default types.\r
       //\r
       CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
+      ASSERT (CurrentDefault != NULL);\r
       CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
 \r
       CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
@@ -880,6 +960,7 @@ ParseOpCodes (
       // It create a selection for use in current Question.\r
       //\r
       CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
+      ASSERT (CurrentOption != NULL);\r
       CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
 \r
       CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
@@ -908,13 +989,19 @@ ParseOpCodes (
       break;\r
 \r
     case EFI_IFR_DISABLE_IF_OP:\r
-      ASSERT (FALSE);\r
-\r
+      //\r
+      // Framework IFR doesn't support DisableIf opcode\r
+      //\r
+      if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) {\r
+        ASSERT (FALSE);\r
+      }\r
 \r
     //\r
     // Expression\r
     //\r
     case EFI_IFR_VALUE_OP:\r
+    case EFI_IFR_READ_OP:\r
+    case EFI_IFR_WRITE_OP:\r
       break;\r
 \r
     case EFI_IFR_RULE_OP:\r
@@ -936,6 +1023,7 @@ ParseOpCodes (
         break;\r
 \r
       case EFI_IFR_FORM_OP:\r
+      case EFI_IFR_FORM_MAP_OP:\r
         ImageId = &CurrentForm->ImageId;\r
         break;\r
 \r
@@ -944,10 +1032,17 @@ ParseOpCodes (
         break;\r
 \r
       default:\r
+        //\r
+        // Make sure CurrentStatement is not NULL.\r
+        // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
+        // file is wrongly generated by tools such as VFR Compiler.\r
+        //\r
+        ASSERT (CurrentStatement != NULL);\r
         ImageId = &CurrentStatement->ImageId;\r
         break;\r
       }\r
-\r
+      \r
+      ASSERT (ImageId != NULL);\r
       CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
       break;\r
 \r
@@ -955,6 +1050,7 @@ ParseOpCodes (
     // Refresh\r
     //\r
     case EFI_IFR_REFRESH_OP:\r
+      ASSERT (CurrentStatement != NULL);\r
       CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
       break;\r
 \r
@@ -987,8 +1083,7 @@ ParseOpCodes (
         default:\r
           break;\r
         }\r
-      } \r
-      else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &mFrameworkHiiCompatibilityGuid)) {\r
+      } else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &mFrameworkHiiCompatibilityGuid)) {\r
         if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) {\r
           OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (FormSet, OptionMap->QuestionId);\r
           if (OneOfOptinMapEntryListHead == NULL) {\r
@@ -1039,6 +1134,7 @@ ParseOpCodes (
         break;\r
 \r
       case EFI_IFR_FORM_OP:\r
+      case EFI_IFR_FORM_MAP_OP:\r
         //\r
         // End of Form\r
         //\r