]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/ConfigAccess.c
Fill all EFI_IFR_DATA_ARRAY fields before call FormCallBack function.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / ConfigAccess.c
index 6be0496c61240a25e2517c20ce0d095ef43e1694..806759dc56f881bae2b8600940991317f8884d88 100644 (file)
@@ -19,6 +19,32 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 BOOLEAN            mHiiPackageListUpdated = FALSE;\r
 \r
+HII_VENDOR_DEVICE_PATH  mUefiHiiVendorDevicePath = {\r
+  {\r
+    {\r
+      {\r
+        HARDWARE_DEVICE_PATH,\r
+        HW_VENDOR_DP,\r
+        {\r
+          (UINT8) (sizeof (HII_VENDOR_DEVICE_PATH_NODE)),\r
+          (UINT8) ((sizeof (HII_VENDOR_DEVICE_PATH_NODE)) >> 8)\r
+        }\r
+      },\r
+      EFI_CALLER_ID_GUID\r
+    },\r
+    0,\r
+    0\r
+  },\r
+  {\r
+    END_DEVICE_PATH_TYPE,\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    { \r
+      (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL)),\r
+      (UINT8) ((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)\r
+    }\r
+  }\r
+};\r
+\r
 CONFIG_ACCESS_PRIVATE gConfigAccessPrivateTempate = {\r
   CONFIG_ACCESS_PRIVATE_SIGNATURE,\r
   {\r
@@ -57,14 +83,15 @@ GetFirstStorageOfFormSet (
 }\r
 \r
 /**\r
-  Get the EFI_IFR_VARSTORE where the Question's value is stored.\r
+  Get the FORM_BROWSER_STATEMENT that matches the Question's value.\r
     \r
   @param FormSet                  The Form Set.\r
+  @param QuestionId               QuestionId\r
    \r
-  @retval FORMSET_STORAGE *       The EFI_IFR_VARSTORE where the Question's value is stored.\r
-  @retval NULL                    If the Form Set does not have EFI_IFR_VARSTORE.\r
+  @retval FORM_BROWSER_STATEMENT*   FORM_BROWSER_STATEMENT that match Question's value.\r
+  @retval NULL                      If the Form Set does not have EFI_IFR_VARSTORE.\r
 **/\r
-FORMSET_STORAGE *\r
+FORM_BROWSER_STATEMENT *\r
 GetStorageFromQuestionId (\r
   IN CONST FORM_BROWSER_FORMSET * FormSet,\r
   IN       EFI_QUESTION_ID        QuestionId\r
@@ -89,7 +116,7 @@ GetStorageFromQuestionId (
         // UEFI Question ID is unique in a FormSet.\r
         //\r
         ASSERT (Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER);\r
-        return Statement->Storage;\r
+        return Statement;\r
       }\r
       StatementList = GetNextNode (&Form->StatementListHead, StatementList);\r
     }\r
@@ -163,7 +190,7 @@ GetStorageFromConfigString (
       Name = Storage->Name;\r
     }\r
     \r
-    if (IsConfigHdrMatch (ConfigString, &Storage->Guid, Name)) {\r
+    if (HiiIsConfigHdrMatch (ConfigString, &Storage->Guid, Name)) {\r
       return Storage;\r
     }\r
 \r
@@ -195,20 +222,32 @@ InstallDefaultConfigAccessProtocol (
 {\r
   EFI_STATUS                                  Status;\r
   CONFIG_ACCESS_PRIVATE                       *ConfigAccessInstance;\r
+  HII_VENDOR_DEVICE_PATH                      *HiiVendorPath;\r
 \r
   ASSERT (ThunkContext->IfrPackageCount != 0);\r
 \r
-  Status = HiiLibCreateHiiDriverHandle (&ThunkContext->UefiHiiDriverHandle);\r
-  ASSERT_EFI_ERROR (Status);\r
-  \r
   ConfigAccessInstance = AllocateCopyPool (\r
                            sizeof (CONFIG_ACCESS_PRIVATE), \r
                            &gConfigAccessPrivateTempate\r
                            );\r
   ASSERT (ConfigAccessInstance != NULL);\r
-  \r
+\r
+  //\r
+  // Use memory address as unique ID to distinguish from different device paths\r
+  // This function may be called multi times by the framework HII driver.\r
+  //\r
+  HiiVendorPath = AllocateCopyPool (\r
+                           sizeof (HII_VENDOR_DEVICE_PATH), \r
+                           &mUefiHiiVendorDevicePath\r
+                           );\r
+  ASSERT (HiiVendorPath != NULL);\r
+\r
+  HiiVendorPath->Node.UniqueId = (UINT64) ((UINTN) HiiVendorPath);\r
+\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
           &ThunkContext->UefiHiiDriverHandle,\r
+          &gEfiDevicePathProtocolGuid,          \r
+          HiiVendorPath,\r
           &gEfiHiiConfigAccessProtocolGuid,\r
           &ConfigAccessInstance->ConfigAccessProtocol,\r
           NULL\r
@@ -236,8 +275,7 @@ UninstallDefaultConfigAccessProtocol (
 {\r
   EFI_STATUS                      Status;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
-  \r
-  HiiLibDestroyHiiDriverHandle (ThunkContext->UefiHiiDriverHandle);\r
+  HII_VENDOR_DEVICE_PATH          *HiiVendorPath;\r
 \r
   Status = gBS->HandleProtocol (\r
                   ThunkContext->UefiHiiDriverHandle,\r
@@ -246,10 +284,20 @@ UninstallDefaultConfigAccessProtocol (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  Status = gBS->UninstallProtocolInterface (\r
+  Status = gBS->HandleProtocol (\r
+                  ThunkContext->UefiHiiDriverHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &HiiVendorPath\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
                   ThunkContext->UefiHiiDriverHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  HiiVendorPath,\r
                   &gEfiHiiConfigAccessProtocolGuid,\r
-                  ConfigAccess\r
+                  ConfigAccess,\r
+                  NULL\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
@@ -296,11 +344,11 @@ CallFormCallBack (
     }\r
 \r
     *Data = AllocateZeroPool (*DataSize);\r
-    if (Data == NULL) {\r
+    if (*Data == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    FwFormCallBack->NvRead (\r
+    Status = FwFormCallBack->NvRead (\r
                   FwFormCallBack,  \r
                   BufferStorage->Name,\r
                   &BufferStorage->Guid,\r
@@ -356,7 +404,7 @@ GetUefiVariable (
     }\r
 \r
     *Data = AllocateZeroPool (*DataSize);\r
-    if (Data == NULL) {\r
+    if (*Data == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
@@ -564,7 +612,7 @@ ThunkRouteConfig (
   if (EFI_ERROR (Status)) {\r
     goto Done;\r
   }\r
-\r
+  \r
   if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
     if (ConfigAccess->FormCallbackProtocol == NULL ||\r
         ConfigAccess->FormCallbackProtocol->NvWrite == NULL) {\r
@@ -598,8 +646,8 @@ Done:
 }\r
 \r
 /**\r
-  Build the FRAMEWORK_EFI_IFR_DATA_ARRAY which will be used to pass to \r
-  EFI_FORM_CALLBACK_PROTOCOL.Callback. Check definition of FRAMEWORK_EFI_IFR_DATA_ARRAY\r
+  Build the EFI_IFR_DATA_ARRAY which will be used to pass to \r
+  EFI_FORM_CALLBACK_PROTOCOL.Callback. Check definition of EFI_IFR_DATA_ARRAY\r
   for details.\r
 \r
   ASSERT if the Question Type is not EFI_IFR_TYPE_NUM_SIZE_* or EFI_IFR_TYPE_STRING.\r
@@ -610,9 +658,9 @@ Done:
    @param Value            The Question Value.\r
    @param NvMapAllocated   On output indicates if a buffer is allocated for NvMap.\r
    \r
-   @return A pointer to FRAMEWORK_EFI_IFR_DATA_ARRAY. The caller must free this buffer allocated.\r
+   @return A pointer to EFI_IFR_DATA_ARRAY. The caller must free this buffer allocated.\r
 **/   \r
-FRAMEWORK_EFI_IFR_DATA_ARRAY *\r
+EFI_IFR_DATA_ARRAY *\r
 CreateIfrDataArray (\r
   IN    CONFIG_ACCESS_PRIVATE         *ConfigAccess,\r
   IN    EFI_QUESTION_ID               QuestionId,\r
@@ -621,14 +669,13 @@ CreateIfrDataArray (
   OUT   BOOLEAN                       *NvMapAllocated\r
   )\r
 {\r
-  FRAMEWORK_EFI_IFR_DATA_ARRAY      *IfrDataArray;\r
-  FRAMEWORK_EFI_IFR_DATA_ENTRY      *IfrDataEntry;\r
+  EFI_IFR_DATA_ARRAY                *IfrDataArray;\r
+  EFI_IFR_DATA_ENTRY                *IfrDataEntry;\r
   UINTN                             BrowserDataSize;\r
-  FORMSET_STORAGE                  *BufferStorage;\r
-  EFI_STATUS                        Status;\r
+  FORMSET_STORAGE                   *BufferStorage;\r
   UINTN                             Size;\r
-  UINTN                             StringSize;\r
   EFI_STRING                        String;\r
+  FORM_BROWSER_STATEMENT            *Statement;\r
 \r
   *NvMapAllocated = FALSE;\r
 \r
@@ -644,17 +691,14 @@ CreateIfrDataArray (
       break;\r
 \r
     case EFI_IFR_TYPE_STRING:\r
-      StringSize = 0;\r
-      Status = HiiLibGetString (ConfigAccess->ThunkContext->UefiHiiHandle, Value->string, String, &StringSize);\r
-      ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
-\r
-      String = AllocateZeroPool (StringSize);\r
-      ASSERT (String != NULL);\r
-\r
-      Status = HiiLibGetString (ConfigAccess->ThunkContext->UefiHiiHandle, Value->string, String, &StringSize);\r
-      ASSERT_EFI_ERROR (Status);\r
+      if (Value->string == 0) {\r
+        Size = 0;\r
+      } else {\r
+        String = HiiGetString (ConfigAccess->ThunkContext->UefiHiiHandle, Value->string, NULL);\r
+        ASSERT (String != NULL);\r
 \r
-      Size = StringSize;\r
+        Size = StrSize (String);\r
+      }\r
       break;\r
       \r
     default:\r
@@ -663,21 +707,27 @@ CreateIfrDataArray (
       break;\r
   }\r
 \r
-  IfrDataArray = AllocateZeroPool (sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY) + sizeof (FRAMEWORK_EFI_IFR_DATA_ENTRY) + Size);\r
+  IfrDataArray = AllocateZeroPool (sizeof (EFI_IFR_DATA_ARRAY) + sizeof (EFI_IFR_DATA_ENTRY) + Size);\r
   ASSERT (IfrDataArray != NULL);\r
+  IfrDataArray->EntryCount = 1;\r
+  IfrDataEntry             = (EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);\r
 \r
-  BufferStorage  = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);\r
+  Statement = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);\r
 \r
-  if (BufferStorage == NULL) {\r
+  if (Statement == NULL || Statement->Storage == NULL) {\r
     //\r
     // The QuestionId is not associated with a Buffer Storage.\r
     // Try to get the first Buffer Storage then.\r
     //\r
     BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);\r
+  } else {\r
+    BufferStorage        = Statement->Storage;\r
+    IfrDataEntry->OpCode = Statement->Operand;\r
   }\r
   \r
   if (BufferStorage != NULL) {\r
-    BrowserDataSize = BufferStorage->Size;\r
+    BrowserDataSize      = BufferStorage->Size;\r
+    IfrDataEntry->Length = (UINT8) (sizeof (EFI_IFR_DATA_ENTRY) + Size);\r
 \r
     if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
       *NvMapAllocated = TRUE;\r
@@ -687,10 +737,7 @@ CreateIfrDataArray (
       IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride;\r
     }\r
     \r
-    Status = GetBrowserData (&BufferStorage->Guid, BufferStorage->Name, &BrowserDataSize, IfrDataArray->NvRamMap);\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    IfrDataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);\r
+    ASSERT (HiiGetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, (UINT8 *) IfrDataArray->NvRamMap));\r
 \r
     switch (Type) {\r
       case EFI_IFR_TYPE_NUM_SIZE_8:\r
@@ -702,9 +749,11 @@ CreateIfrDataArray (
         break;\r
 \r
       case EFI_IFR_TYPE_STRING:\r
-        ASSERT (String != NULL);\r
-        StrCpy ((CHAR16 *) &IfrDataEntry->Data, String);\r
-        FreePool (String);\r
+        if (Size != 0) {\r
+          ASSERT (String != NULL);\r
+          StrCpy ((CHAR16 *) &IfrDataEntry->Data, String);\r
+          FreePool (String);\r
+        }\r
         break;\r
       default:\r
         ASSERT (FALSE);\r
@@ -712,11 +761,11 @@ CreateIfrDataArray (
     }\r
 \r
     //\r
-    // Need to fiil in the information for the rest of field for FRAMEWORK_EFI_IFR_DATA_ENTRY.\r
+    // Need to fiil in the information for the rest of field for EFI_IFR_DATA_ENTRY.\r
     // It seems that no implementation is found to use other fields. Leave them uninitialized for now.\r
     //\r
     //UINT8   OpCode;           // Likely a string, numeric, or one-of\r
-    //UINT8   Length;           // Length of the FRAMEWORK_EFI_IFR_DATA_ENTRY packet\r
+    //UINT8   Length;           // Length of the EFI_IFR_DATA_ENTRY packet\r
     //UINT16  Flags;            // Flags settings to determine what behavior is desired from the browser after the callback\r
     //VOID    *Data;            // The data in the form based on the op-code type - this is not a pointer to the data, the data follows immediately\r
     // If the OpCode is a OneOf or Numeric type - Data is a UINT16 value\r
@@ -744,21 +793,24 @@ SyncBrowserDataForNvMapOverride (
   IN          EFI_QUESTION_ID               QuestionId\r
   )\r
 {\r
-  FORMSET_STORAGE                  *BufferStorage;\r
-  EFI_STATUS                        Status;\r
-  UINTN                             BrowserDataSize;\r
+  FORMSET_STORAGE   *BufferStorage;\r
+  BOOLEAN           CheckFlag;\r
+  UINTN             BrowserDataSize;\r
+  FORM_BROWSER_STATEMENT *Statement;\r
 \r
   if (ConfigAccess->ThunkContext->NvMapOverride != NULL) {\r
 \r
-    BufferStorage = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);\r
+    Statement = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);\r
 \r
-    if (BufferStorage == NULL) {\r
+    if (Statement == NULL || Statement->Storage == NULL) {\r
       //\r
       // QuestionId is a statement without Storage.\r
       // 1) It is a Goto. \r
       // \r
       //\r
       BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);\r
+    } else {\r
+      BufferStorage = Statement->Storage;\r
     }\r
 \r
     //\r
@@ -768,22 +820,22 @@ SyncBrowserDataForNvMapOverride (
     \r
     BrowserDataSize = BufferStorage->Size;\r
 \r
-    Status = SetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL);\r
-    ASSERT_EFI_ERROR (Status);\r
+    CheckFlag = HiiSetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL);\r
+    ASSERT (CheckFlag);\r
   }\r
 \r
 }\r
 \r
 /**\r
-  Free up resource allocated for a FRAMEWORK_EFI_IFR_DATA_ARRAY by CreateIfrDataArray ().\r
+  Free up resource allocated for a EFI_IFR_DATA_ARRAY by CreateIfrDataArray ().\r
 \r
-  @param Array              The FRAMEWORK_EFI_IFR_DATA_ARRAY allocated.\r
-  @param NvMapAllocated     If the NvRamMap is allocated for FRAMEWORK_EFI_IFR_DATA_ARRAY.\r
+  @param Array              The EFI_IFR_DATA_ARRAY allocated.\r
+  @param NvMapAllocated     If the NvRamMap is allocated for EFI_IFR_DATA_ARRAY.\r
 \r
 **/\r
 VOID\r
 DestroyIfrDataArray (\r
-  IN  FRAMEWORK_EFI_IFR_DATA_ARRAY *Array,\r
+  IN  EFI_IFR_DATA_ARRAY           *Array,\r
   IN  BOOLEAN                      NvMapAllocated\r
   )\r
 {\r
@@ -946,8 +998,8 @@ ThunkCallback (
   CONFIG_ACCESS_PRIVATE                       *ConfigAccess;\r
   EFI_FORM_CALLBACK_PROTOCOL                  *FormCallbackProtocol;\r
   EFI_HII_CALLBACK_PACKET                     *Packet;\r
-  FRAMEWORK_EFI_IFR_DATA_ARRAY                *Data;\r
-  FRAMEWORK_EFI_IFR_DATA_ENTRY                *DataEntry;\r
+  EFI_IFR_DATA_ARRAY                          *Data;\r
+  EFI_IFR_DATA_ENTRY                          *DataEntry;\r
   UINT16                                      KeyValue;\r
   ONE_OF_OPTION_MAP_ENTRY                     *OneOfOptionMapEntry;\r
   EFI_HANDLE                                  NotifyHandle;\r
@@ -986,7 +1038,7 @@ ThunkCallback (
   }\r
 \r
   //\r
-  // Build the FRAMEWORK_EFI_IFR_DATA_ARRAY\r
+  // Build the EFI_IFR_DATA_ARRAY\r
   //\r
   Data = CreateIfrDataArray (ConfigAccess, QuestionId, Type, Value, &NvMapAllocated);\r
 \r
@@ -1016,7 +1068,7 @@ ThunkCallback (
   if (EFI_ERROR (Status)) {\r
     if (Packet != NULL) {\r
       do {\r
-        IfrLibCreatePopUp (1, &Key, Packet->String);\r
+        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, Packet->String, NULL);\r
       } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
     }\r
     //\r
@@ -1025,7 +1077,7 @@ ThunkCallback (
   } else {\r
     if (Packet != NULL) {\r
         if (Packet->DataArray.EntryCount  == 1 && Packet->DataArray.NvRamMap == NULL) {\r
-          DataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY));\r
+          DataEntry = (EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (EFI_IFR_DATA_ARRAY));\r
           if ((DataEntry->Flags & EXIT_REQUIRED) == EXIT_REQUIRED) {\r
               *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
           }\r