]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
MdeModulePkg BootMaintenanceManagerUiLib: Move refresh boot option later
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / BootMaintenance.c
index 7475a94a2791d8baa21e2ac4452f2ea26bfc8927..fdcb56a9df2b5d7012767eef22c980f12d6d31dc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 The functions for Boot Maintainence Main menu.\r
 \r
-Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 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
@@ -443,6 +443,91 @@ BmmExtractDevicePathFromHiiHandle (
 \r
 }\r
 \r
+/**\r
+  Converts the unicode character of the string from uppercase to lowercase.\r
+  This is a internal function.\r
+\r
+  @param ConfigString  String to be converted\r
+\r
+**/\r
+VOID\r
+HiiToLower (\r
+  IN EFI_STRING  ConfigString\r
+  )\r
+{\r
+  EFI_STRING  String;\r
+  BOOLEAN     Lower;\r
+\r
+  ASSERT (ConfigString != NULL);\r
+\r
+  //\r
+  // Convert all hex digits in range [A-F] in the configuration header to [a-f]\r
+  //\r
+  for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {\r
+    if (*String == L'=') {\r
+      Lower = TRUE;\r
+    } else if (*String == L'&') {\r
+      Lower = FALSE;\r
+    } else if (Lower && *String >= L'A' && *String <= L'F') {\r
+      *String = (CHAR16) (*String - L'A' + L'a');\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Update the progress string through the offset value.\r
+\r
+  @param Offset           The offset value\r
+  @param Configuration    Point to the configuration string.\r
+\r
+**/\r
+EFI_STRING\r
+UpdateProgress(\r
+  IN  UINTN       Offset,\r
+  IN  EFI_STRING  Configuration\r
+)\r
+{\r
+  UINTN       Length;\r
+  EFI_STRING  StringPtr;\r
+  EFI_STRING  ReturnString;\r
+\r
+  StringPtr    = NULL;\r
+  ReturnString = NULL;\r
+\r
+  //\r
+  // &OFFSET=XXXX followed by a Null-terminator.\r
+  // Length = StrLen (L"&OFFSET=") + 4 + 1\r
+  //\r
+  Length    = StrLen (L"&OFFSET=") + 4 + 1;\r
+\r
+  StringPtr = AllocateZeroPool (Length * sizeof (CHAR16));\r
+\r
+  if (StringPtr == NULL) {\r
+    return  NULL;\r
+  }\r
+\r
+  UnicodeSPrint (\r
+    StringPtr,\r
+    (8 + 4 + 1) * sizeof (CHAR16),\r
+    L"&OFFSET=%04x",\r
+    Offset\r
+    );\r
+\r
+  ReturnString = StrStr (Configuration, StringPtr);\r
+\r
+  if (ReturnString == NULL) {\r
+    //\r
+    // If doesn't find the string in Configuration, convert the string to lower case then search again.\r
+    //\r
+    HiiToLower (StringPtr);\r
+    ReturnString = StrStr (Configuration, StringPtr);\r
+  }\r
+\r
+  FreePool (StringPtr);\r
+\r
+  return ReturnString;\r
+}\r
+\r
 /**\r
   Update the terminal content in TerminalMenu.\r
 \r
@@ -463,16 +548,16 @@ UpdateTerminalContent (
     ASSERT (NewMenuEntry != NULL);\r
     NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
     NewTerminalContext->BaudRateIndex = BmmData->COMBaudRate[Index];\r
-    ASSERT (BmmData->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
+    ASSERT (BmmData->COMBaudRate[Index] < (ARRAY_SIZE (BaudRateList)));\r
     NewTerminalContext->BaudRate      = BaudRateList[BmmData->COMBaudRate[Index]].Value;\r
     NewTerminalContext->DataBitsIndex = BmmData->COMDataRate[Index];\r
-    ASSERT (BmmData->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
+    ASSERT (BmmData->COMDataRate[Index] < (ARRAY_SIZE (DataBitsList)));\r
     NewTerminalContext->DataBits      = (UINT8) DataBitsList[BmmData->COMDataRate[Index]].Value;\r
     NewTerminalContext->StopBitsIndex = BmmData->COMStopBits[Index];\r
-    ASSERT (BmmData->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
+    ASSERT (BmmData->COMStopBits[Index] < (ARRAY_SIZE (StopBitsList)));\r
     NewTerminalContext->StopBits      = (UINT8) StopBitsList[BmmData->COMStopBits[Index]].Value;\r
     NewTerminalContext->ParityIndex   = BmmData->COMParity[Index];\r
-    ASSERT (BmmData->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));\r
+    ASSERT (BmmData->COMParity[Index] < (ARRAY_SIZE (ParityList)));\r
     NewTerminalContext->Parity        = (UINT8) ParityList[BmmData->COMParity[Index]].Value;\r
     NewTerminalContext->TerminalType  = BmmData->COMTerminalType[Index];\r
     NewTerminalContext->FlowControl   = BmmData->COMFlowControl[Index];\r
@@ -486,6 +571,7 @@ UpdateTerminalContent (
 /**\r
   Update the console content in ConsoleMenu.\r
 \r
+  @param ConsoleName       The name for the console device type.\r
   @param BmmData           The BMM fake NV data.\r
 \r
 **/\r
@@ -695,7 +781,8 @@ BootMaintRouteConfig (
   BM_LOAD_CONTEXT                 *NewLoadContext;\r
   UINT16                          Index;\r
   BOOLEAN                         TerminalAttChange;\r
-  BMM_CALLBACK_DATA               *Private; \r
+  BMM_CALLBACK_DATA               *Private;\r
+  UINTN                           Offset;\r
 \r
   if (Progress == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -730,6 +817,7 @@ BootMaintRouteConfig (
   BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
   OldBmmData = &Private->BmmOldFakeNVData;\r
   NewBmmData = &Private->BmmFakeNvData;\r
+  Offset     = 0;\r
   //\r
   // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
   //\r
@@ -751,6 +839,10 @@ BootMaintRouteConfig (
   //         \r
   if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
     Status = Var_UpdateBootNext (Private);\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootNext);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   //\r
@@ -767,11 +859,19 @@ BootMaintRouteConfig (
       NewBmmData->BootOptionDelMark[Index] = FALSE;\r
     }\r
 \r
-    Var_DelBootOption ();\r
+    Status = Var_DelBootOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionDel);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {\r
     Status = Var_UpdateBootOrder (Private);\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionOrder);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0){\r
@@ -783,15 +883,8 @@ BootMaintRouteConfig (
                     &(NewBmmData->BootTimeOut)\r
                     );\r
     if (EFI_ERROR (Status)) {\r
-      //\r
-      // If set variable fail, and don't have the appropriate error status for RouteConfig fuction to return,\r
-      // just return the EFI_NOT_FOUND.\r
-      //\r
-      if (Status == EFI_OUT_OF_RESOURCES) {\r
-        return Status;\r
-      } else {\r
-        return EFI_NOT_FOUND;\r
-      }\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootTimeOut);\r
+      goto Exit;\r
     }\r
     Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;\r
   }\r
@@ -809,15 +902,27 @@ BootMaintRouteConfig (
       NewBmmData->DriverOptionDel[Index] = FALSE;\r
       NewBmmData->DriverOptionDelMark[Index] = FALSE;\r
     }\r
-    Var_DelDriverOption ();  \r
+    Status = Var_DelDriverOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionDel);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {  \r
     Status = Var_UpdateDriverOrder (Private);\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionOrder);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0){\r
-    Var_UpdateConMode(Private);\r
+    Status = Var_UpdateConMode(Private);\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutMode);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   TerminalAttChange = FALSE;\r
@@ -838,23 +943,57 @@ BootMaintRouteConfig (
     TerminalAttChange = TRUE;\r
   }\r
   if (TerminalAttChange) {\r
-    Var_UpdateConsoleInpOption ();\r
-    Var_UpdateConsoleOutOption ();\r
-    Var_UpdateErrorOutOption ();\r
+    if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMBaudRate);\r
+    } else if (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMDataRate);\r
+    } else if (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMStopBits);\r
+    } else if (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMParity);\r
+    } else if (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMTerminalType);\r
+    } else if (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMFlowControl);\r
+    }\r
+    Status = Var_UpdateConsoleInpOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
+    Status = Var_UpdateConsoleOutOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
+    Status = Var_UpdateErrorOutOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
   }\r
   //\r
   // Check data which located in Console Options Menu and save the settings if need\r
   //\r
   if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0){\r
-    Var_UpdateConsoleInpOption();\r
+    Status = Var_UpdateConsoleInpOption();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleInCheck);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0){\r
-    Var_UpdateConsoleOutOption();\r
+    Status = Var_UpdateConsoleOutOption();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutCheck);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0){\r
-    Var_UpdateErrorOutOption();\r
+    Status = Var_UpdateErrorOutOption();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleErrCheck);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0 ||\r
@@ -862,7 +1001,12 @@ BootMaintRouteConfig (
     Status = Var_UpdateBootOption (Private);\r
     NewBmmData->BootOptionChanged = FALSE;\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) {\r
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootDescriptionData);\r
+      } else {\r
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionalData);\r
+      }\r
+      goto Exit;\r
     }\r
     BOpt_GetBootOptions (Private);\r
   }\r
@@ -879,7 +1023,12 @@ BootMaintRouteConfig (
     NewBmmData->DriverOptionChanged = FALSE;\r
     NewBmmData->ForceReconnect      = TRUE;\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) {\r
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverDescriptionData);\r
+      } else {\r
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionalData);\r
+      }\r
+      goto Exit;\r
     }\r
 \r
     BOpt_GetDriverOptions (Private);\r
@@ -891,6 +1040,17 @@ BootMaintRouteConfig (
   CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
 \r
   return EFI_SUCCESS;\r
+\r
+Exit:\r
+  //\r
+  // Fail to save the data, update the progress string.\r
+  //\r
+  *Progress = UpdateProgress (Offset, Configuration);\r
+  if (Status == EFI_OUT_OF_RESOURCES) {\r
+    return Status;\r
+  } else {\r
+    return EFI_NOT_FOUND;\r
+  }\r
 }\r
 \r
 /**\r
@@ -951,13 +1111,14 @@ BootMaintCallback (
         // 2. Re-scan the BootOption menus (including the legacy boot option).\r
         //\r
         CustomizeMenus ();\r
+        EfiBootManagerRefreshAllBootOption ();\r
         BOpt_GetBootOptions (Private);\r
         mFirstEnterBMMForm = TRUE;\r
       }\r
     }\r
   }\r
   //\r
-  // Retrive uncommitted data from Form Browser\r
+  // Retrieve uncommitted data from Form Browser\r
   //\r
   CurrentFakeNVMap = &Private->BmmFakeNvData;\r
   OldFakeNVMap     = &Private->BmmOldFakeNVData;\r
@@ -1054,9 +1215,11 @@ BootMaintCallback (
     }\r
    \r
     if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {\r
+      CleanUselessBeforeSubmit (Private);\r
       CurrentFakeNVMap->BootOptionChanged = FALSE;\r
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
     } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {\r
+      CleanUselessBeforeSubmit (Private);\r
       CurrentFakeNVMap->DriverOptionChanged = FALSE;\r
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
     } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {\r
@@ -1109,6 +1272,7 @@ BootMaintCallback (
       case KEY_VALUE_SAVE_AND_EXIT:\r
       case KEY_VALUE_NO_SAVE_AND_EXIT:\r
         if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
+          CleanUselessBeforeSubmit (Private);\r
           *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
         } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
           DiscardChangeHandler (Private, CurrentFakeNVMap);\r
@@ -1139,7 +1303,7 @@ BootMaintCallback (
     } else if ((QuestionId >= CON_OUT_DEVICE_QUESTION_ID) && (QuestionId < CON_OUT_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
       UpdateConsoleContent (L"ConOut", CurrentFakeNVMap);\r
     } else if ((QuestionId >= CON_ERR_DEVICE_QUESTION_ID) && (QuestionId < CON_ERR_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
-      UpdateConsoleContent (L"ConErr", CurrentFakeNVMap);\r
+      UpdateConsoleContent (L"ErrOut", CurrentFakeNVMap);\r
     }\r
   }\r
 \r
@@ -1210,6 +1374,36 @@ DiscardChangeHandler (
   }\r
 }\r
 \r
+/**\r
+  This function is to clean some useless data before submit changes.\r
+\r
+  @param Private            The BMM context data.\r
+\r
+**/\r
+VOID\r
+CleanUselessBeforeSubmit (\r
+  IN  BMM_CALLBACK_DATA               *Private\r
+  )\r
+{\r
+  UINT16  Index;\r
+  if (Private->BmmPreviousPageId != FORM_BOOT_DEL_ID) {\r
+    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
+      if (Private->BmmFakeNvData.BootOptionDel[Index] && !Private->BmmFakeNvData.BootOptionDelMark[Index]) {\r
+        Private->BmmFakeNvData.BootOptionDel[Index] = FALSE;\r
+        Private->BmmOldFakeNVData.BootOptionDel[Index] = FALSE;\r
+      }\r
+    }\r
+  }\r
+  if (Private->BmmPreviousPageId != FORM_DRV_DEL_ID) {\r
+    for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
+      if (Private->BmmFakeNvData.DriverOptionDel[Index] && !Private->BmmFakeNvData.DriverOptionDelMark[Index]) {\r
+        Private->BmmFakeNvData.DriverOptionDel[Index] = FALSE;\r
+        Private->BmmOldFakeNVData.DriverOptionDel[Index] = FALSE;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
 \r
   Update the menus in the BMM page.\r
@@ -1497,8 +1691,6 @@ BootMaintenanceManagerUiLibConstructor (
   Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mBmmCallbackInfo->FormBrowser2);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  EfiBootManagerRefreshAllBootOption ();\r
-\r
   //\r
   // Create LoadOption in BmmCallbackInfo for Driver Callback\r
   //\r