]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
MdeModulePkg/DisplayEngine: Remove useless NULL ptr check for NewPos
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
index ffcd9ec7ae747e3dea00664eb854c15359efe0cc..b59a9b2965af10c527510a25089602473862de18 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Implementation for EFI_HII_DATABASE_PROTOCOL.\r
 \r
-Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2018, 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
@@ -21,11 +21,16 @@ EFI_HII_PACKAGE_LIST_HEADER    *gRTDatabaseInfoBuffer = NULL;
 EFI_STRING                     gRTConfigRespBuffer    = NULL;\r
 UINTN                          gDatabaseInfoSize = 0;\r
 UINTN                          gConfigRespSize = 0;\r
-BOOLEAN                        gExportConfigResp = TRUE;\r
+BOOLEAN                        gExportConfigResp = FALSE;\r
 UINTN                          gNvDefaultStoreSize = 0;\r
 SKU_ID                         gSkuId              = 0xFFFFFFFFFFFFFFFF;\r
 LIST_ENTRY                     gVarStorageList     = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);\r
 \r
+//\r
+// HII database lock.\r
+//\r
+EFI_LOCK mHiiDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY);\r
+\r
 /**\r
   This function generates a HII_DATABASE_RECORD node and adds into hii database.\r
   This is a internal function.\r
@@ -721,9 +726,14 @@ FindQuestionDefaultSetting (
       VariableStorage = NULL;\r
     }\r
     Entry = AllocatePool (sizeof (VARSTORAGE_DEFAULT_DATA));\r
-    Entry->DefaultId = DefaultId;\r
-    Entry->VariableStorage = VariableStorage;\r
-    InsertTailList (&gVarStorageList, &Entry->Entry);\r
+    if (Entry != NULL) {\r
+      Entry->DefaultId = DefaultId;\r
+      Entry->VariableStorage = VariableStorage;\r
+      InsertTailList (&gVarStorageList, &Entry->Entry);\r
+    } else if (VariableStorage != NULL) {\r
+      FreePool (VariableStorage);\r
+      VariableStorage = NULL;\r
+    }\r
   }\r
   //\r
   // The matched variable storage is not found.\r
@@ -739,6 +749,8 @@ FindQuestionDefaultSetting (
   if (VariableHeader == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
+  StartBit   = 0;\r
+  EndBit     = 0;\r
   ByteOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
   if (BitFieldQuestion) {\r
     BitOffset  = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
@@ -818,6 +830,7 @@ UpdateDefaultSettingInFormPackage (
 \r
   ZeroMem (&VarStoreQuestionHeader, sizeof (VarStoreQuestionHeader));\r
   PackageLength = FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);\r
+  Width         = 0;\r
   IfrOffset     = 0;\r
   IfrScope      = 0;\r
   IfrOpHdr      = (EFI_IFR_OP_HEADER *) FormPackage->IfrData;\r
@@ -841,6 +854,9 @@ UpdateDefaultSettingInFormPackage (
         // Reallocate EFI VarStore Buffer\r
         //\r
         EfiVarStoreList   = ReallocatePool (EfiVarStoreMaxNum * sizeof (UINTN), (EfiVarStoreMaxNum + BASE_NUMBER) * sizeof (UINTN), EfiVarStoreList);\r
+        if (EfiVarStoreList == NULL) {\r
+          goto Done;\r
+        }\r
         EfiVarStoreMaxNum = EfiVarStoreMaxNum + BASE_NUMBER;\r
       }\r
       IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
@@ -848,6 +864,9 @@ UpdateDefaultSettingInFormPackage (
       // Convert VarStore Name from ASCII string to Unicode string.\r
       //\r
       EfiVarStoreList [EfiVarStoreNumber] = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));\r
+      if (EfiVarStoreList [EfiVarStoreNumber] == NULL) {\r
+        break;\r
+      }\r
       CopyMem (EfiVarStoreList [EfiVarStoreNumber], IfrEfiVarStore, IfrEfiVarStore->Header.Length);\r
       AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *) &(EfiVarStoreList [EfiVarStoreNumber]->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
       Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreNumber], &VarStoreQuestionHeader, NULL, IfrEfiVarStore->Size, FALSE);\r
@@ -864,6 +883,9 @@ UpdateDefaultSettingInFormPackage (
         // Reallocate DefaultIdNumber\r
         //\r
         DefaultIdList   = ReallocatePool (DefaultIdMaxNum * sizeof (UINT16), (DefaultIdMaxNum + BASE_NUMBER) * sizeof (UINT16), DefaultIdList);\r
+        if (DefaultIdList == NULL) {\r
+          goto Done;\r
+        }\r
         DefaultIdMaxNum = DefaultIdMaxNum + BASE_NUMBER;\r
       }\r
       DefaultIdList[DefaultIdNumber ++] = ((EFI_IFR_DEFAULTSTORE *) IfrOpHdr)->DefaultId;\r
@@ -881,7 +903,7 @@ UpdateDefaultSettingInFormPackage (
       IfrScope         = IfrOpHdr->Scope;\r
       IfrQuestionType  = IfrOpHdr->OpCode;\r
       IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
-      IfrCheckBox      = (EFI_IFR_CHECKBOX *) (IfrOpHdr + 1);\r
+      IfrCheckBox      = (EFI_IFR_CHECKBOX *) IfrOpHdr;\r
       EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
       Width            = sizeof (BOOLEAN);\r
       if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
@@ -1034,8 +1056,10 @@ UpdateDefaultSettingInFormPackage (
   }\r
 \r
 Done:\r
-  for (Index = 0; Index < EfiVarStoreNumber; Index ++) {\r
-    FreePool (EfiVarStoreList [Index]);\r
+  if (EfiVarStoreList != NULL) {\r
+    for (Index = 0; Index < EfiVarStoreNumber; Index ++) {\r
+      FreePool (EfiVarStoreList [Index]);\r
+    }\r
   }\r
   return;\r
 }\r
@@ -1412,7 +1436,7 @@ Error:
 \r
 /**\r
  Adjust all string packages in a single package list to have the same max string ID.\r
\r
+\r
  @param  PackageList        Pointer to a package list which will be adjusted.\r
 \r
  @retval EFI_SUCCESS  Adjust all string packages successfully.\r
@@ -3135,7 +3159,7 @@ AddPackages (
     PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
     CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
   }\r
-  \r
+\r
   //\r
   // Adjust String Package to make sure all string packages have the same max string ID.\r
   //\r
@@ -3416,39 +3440,6 @@ HiiGetDatabaseInfo(
 \r
 }\r
 \r
-/**\r
-This  function mainly use to get and update configuration settings information.\r
-\r
-@param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL instance.\r
-\r
-@retval EFI_SUCCESS            Get the information successfully.\r
-@retval EFI_OUT_OF_RESOURCES   Not enough memory to store the Configuration Setting data.\r
-\r
-**/\r
-EFI_STATUS\r
-HiiGetConfigurationSetting(\r
-  IN CONST EFI_HII_DATABASE_PROTOCOL        *This\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-\r
-  //\r
-  // Get the HiiDatabase info.\r
-  //\r
-  Status = HiiGetDatabaseInfo(This);\r
-\r
-  //\r
-  // Get ConfigResp string\r
-  //\r
-  if (gExportConfigResp) {\r
-    Status = HiiGetConfigRespInfo (This);\r
-    gExportConfigResp = FALSE;\r
-  }\r
-  return Status;\r
-\r
-}\r
-\r
-\r
 /**\r
   This function adds the packages in the package list to the database and returns a handle. If there is a\r
   EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will\r
@@ -3501,17 +3492,20 @@ HiiNewPackageList (
     DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
     if (CompareGuid (\r
           &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
-          &PackageListGuid) && \r
+          &PackageListGuid) &&\r
         DatabaseRecord->DriverHandle == DriverHandle) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   //\r
   // Build a PackageList node\r
   //\r
   Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);\r
   if (EFI_ERROR (Status)) {\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return Status;\r
   }\r
 \r
@@ -3521,6 +3515,7 @@ HiiNewPackageList (
   //\r
   Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);\r
   if (EFI_ERROR (Status)) {\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return Status;\r
   }\r
 \r
@@ -3542,11 +3537,28 @@ HiiNewPackageList (
   *Handle = DatabaseRecord->Handle;\r
 \r
   //\r
-  // Check whether need to get the Database and configuration setting info.\r
+  // Check whether need to get the Database info.\r
   // Only after ReadyToBoot, need to do the export.\r
   //\r
   if (gExportAfterReadyToBoot) {\r
-    HiiGetConfigurationSetting(This);\r
+    HiiGetDatabaseInfo (This);\r
+  }\r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+  //\r
+  // Notes:\r
+  // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+  // belong to the atomic behavior of Hii Database update.\r
+  // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+  // we can not think it belong to the atomic behavior of Hii Database update.\r
+  // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+  //\r
+\r
+  // Check whether need to get the configuration setting info from HII drivers.\r
+  // When after ReadyToBoot and need to do the export for form package add.\r
+  //\r
+  if (gExportAfterReadyToBoot && gExportConfigResp) {\r
+    HiiGetConfigRespInfo (This);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -3591,6 +3603,8 @@ HiiRemovePackageList (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
 \r
   //\r
@@ -3608,34 +3622,42 @@ HiiRemovePackageList (
       //\r
       Status = RemoveGuidPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveFormPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveStringPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveFontPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveImagePackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveSimpleFontPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveDevicePathPackage (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
 \r
@@ -3655,16 +3677,35 @@ HiiRemovePackageList (
       FreePool (Node);\r
 \r
       //\r
-      // Check whether need to get the Database and configuration setting info.\r
+      // Check whether need to get the Database info.\r
       // Only after ReadyToBoot, need to do the export.\r
       //\r
       if (gExportAfterReadyToBoot) {\r
-        HiiGetConfigurationSetting(This);\r
+        HiiGetDatabaseInfo (This);\r
+      }\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+      //\r
+      // Notes:\r
+      // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+      // belong to the atomic behavior of Hii Database update.\r
+      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+      // we can not think it belong to the atomic behavior of Hii Database update.\r
+      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+      //\r
+\r
+      //\r
+      // Check whether need to get the configuration setting info from HII drivers.\r
+      // When after ReadyToBoot and need to do the export for form package remove.\r
+      //\r
+      if (gExportAfterReadyToBoot && gExportConfigResp) {\r
+        HiiGetConfigRespInfo (This);\r
       }\r
       return EFI_SUCCESS;\r
     }\r
   }\r
 \r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -3717,6 +3758,7 @@ HiiUpdatePackageList (
 \r
   Status = EFI_SUCCESS;\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
   //\r
   // Get original packagelist to be updated\r
   //\r
@@ -3758,6 +3800,7 @@ HiiUpdatePackageList (
         }\r
 \r
         if (EFI_ERROR (Status)) {\r
+          EfiReleaseLock (&mHiiDatabaseLock);\r
           return Status;\r
         }\r
 \r
@@ -3771,19 +3814,35 @@ HiiUpdatePackageList (
       Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);\r
 \r
       //\r
-      // Check whether need to get the Database and configuration setting info.\r
+      // Check whether need to get the Database info.\r
       // Only after ReadyToBoot, need to do the export.\r
       //\r
-      if (gExportAfterReadyToBoot) {\r
-        if (Status == EFI_SUCCESS){\r
-          HiiGetConfigurationSetting(This);\r
-        }\r
+      if (gExportAfterReadyToBoot && Status == EFI_SUCCESS) {\r
+        HiiGetDatabaseInfo (This);\r
+      }\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+      //\r
+      // Notes:\r
+      // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+      // belong to the atomic behavior of Hii Database update.\r
+      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+      // we can not think it belong to the atomic behavior of Hii Database update.\r
+      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+      //\r
+\r
+      //\r
+      // Check whether need to get the configuration setting info from HII drivers.\r
+      // When after ReadyToBoot and need to do the export for form package update.\r
+      //\r
+      if (gExportAfterReadyToBoot && gExportConfigResp && Status == EFI_SUCCESS) {\r
+        HiiGetConfigRespInfo (This);\r
       }\r
 \r
       return Status;\r
     }\r
   }\r
-\r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -3973,7 +4032,7 @@ HiiListPackageLists (
   @retval EFI_NOT_FOUND          The specified Handle could not be found in the\r
                                  current database.\r
   @retval EFI_INVALID_PARAMETER  BufferSize was NULL.\r
-  @retval EFI_INVALID_PARAMETER  The value referenced by BufferSize was not zero \r
+  @retval EFI_INVALID_PARAMETER  The value referenced by BufferSize was not zero\r
                                  and Buffer was NULL.\r
 \r
 **/\r