The function which handles the "Boot####", "BootOrder" ...
may return failure. This patch adds the error handling codes.
return the failure info to browser.

Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Liming Gao <liming....@intel.com>
Cc: Eric Dong <eric.d...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Dandan Bi <dandan...@intel.com>
---
 .../BootMaintenanceManagerUiLib/BootMaintenance.c  | 201 ++++++++++++++++++---
 .../Library/BootMaintenanceManagerUiLib/Variable.c |  28 ++-
 2 files changed, 202 insertions(+), 27 deletions(-)

diff --git a/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c 
b/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
index 7475a94..33c85b7 100644
--- a/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
+++ b/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
@@ -442,10 +442,95 @@ BmmExtractDevicePathFromHiiHandle (
   return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, 
FALSE);
 
 }
 
 /**
+  Converts the unicode character of the string from uppercase to lowercase.
+  This is a internal function.
+
+  @param ConfigString  String to be converted
+
+**/
+VOID
+HiiToLower (
+  IN EFI_STRING  ConfigString
+  )
+{
+  EFI_STRING  String;
+  BOOLEAN     Lower;
+
+  ASSERT (ConfigString != NULL);
+
+  //
+  // Convert all hex digits in range [A-F] in the configuration header to [a-f]
+  //
+  for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {
+    if (*String == L'=') {
+      Lower = TRUE;
+    } else if (*String == L'&') {
+      Lower = FALSE;
+    } else if (Lower && *String >= L'A' && *String <= L'F') {
+      *String = (CHAR16) (*String - L'A' + L'a');
+    }
+  }
+}
+
+/**
+  Update the progress string through the offset value.
+
+  @param Offset           The offset value
+  @param Configuration    Point to the configuration string.
+
+**/
+EFI_STRING
+UpdateProgress(
+  IN  UINTN       Offset,
+  IN  EFI_STRING  Configuration
+)
+{
+  UINTN       Length;
+  EFI_STRING  StringPtr;
+  EFI_STRING  ReturnString;
+
+  StringPtr    = NULL;
+  ReturnString = NULL;
+
+  //
+  // &OFFSET=XXXX followed by a Null-terminator.
+  // Length = StrLen (L"&OFFSET=") + 4 + 1
+  //
+  Length    = StrLen (L"&OFFSET=") + 4 + 1;
+
+  StringPtr = AllocateZeroPool (Length * sizeof (CHAR16));
+
+  if (StringPtr == NULL) {
+    return  NULL;
+  }
+
+  UnicodeSPrint (
+    StringPtr,
+    (8 + 4 + 1) * sizeof (CHAR16),
+    L"&OFFSET=%04x",
+    Offset
+    );
+
+  ReturnString = StrStr (Configuration, StringPtr);
+
+  if (ReturnString == NULL) {
+    //
+    // If doesn't find the string in Configuration, convert the string to 
lower case then search again.
+    //
+    HiiToLower (StringPtr);
+    ReturnString = StrStr (Configuration, StringPtr);
+  }
+
+  FreePool (StringPtr);
+
+  return ReturnString;
+}
+
+/**
   Update the terminal content in TerminalMenu.
 
   @param BmmData           The BMM fake NV data.
 
 **/
@@ -693,11 +778,12 @@ BootMaintRouteConfig (
   BMM_FAKE_NV_DATA                *OldBmmData;
   BM_MENU_ENTRY                   *NewMenuEntry;
   BM_LOAD_CONTEXT                 *NewLoadContext;
   UINT16                          Index;
   BOOLEAN                         TerminalAttChange;
-  BMM_CALLBACK_DATA               *Private; 
+  BMM_CALLBACK_DATA               *Private;
+  UINTN                           Offset;
 
   if (Progress == NULL) {
     return EFI_INVALID_PARAMETER;
   }
   *Progress = Configuration;
@@ -728,10 +814,11 @@ BootMaintRouteConfig (
   // Get Buffer Storage data from EFI variable
   //
   BufferSize = sizeof (BMM_FAKE_NV_DATA);
   OldBmmData = &Private->BmmOldFakeNVData;
   NewBmmData = &Private->BmmFakeNvData;
+  Offset     = 0;
   //
   // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
   //
   Status = ConfigRouting->ConfigToBlock (
                             ConfigRouting,
@@ -749,10 +836,14 @@ BootMaintRouteConfig (
   //
   // Check data which located in BMM main page and save the settings if need
   //         
   if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof 
(NewBmmData->BootNext)) != 0) {
     Status = Var_UpdateBootNext (Private);
+    if (EFI_ERROR (Status)) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootNext);
+      goto Exit;
+    }
   }
 
   //
   // Check data which located in Boot Options Menu and save the settings if 
need
   //      
@@ -765,15 +856,23 @@ BootMaintRouteConfig (
       NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];
       NewBmmData->BootOptionDel[Index] = FALSE;
       NewBmmData->BootOptionDelMark[Index] = FALSE;
     }
 
-    Var_DelBootOption ();
+    Status = Var_DelBootOption ();
+    if (EFI_ERROR (Status)) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionDel);
+      goto Exit;
+    }
   }
 
   if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, 
sizeof (NewBmmData->BootOptionOrder)) != 0) {
     Status = Var_UpdateBootOrder (Private);
+    if (EFI_ERROR (Status)) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionOrder);
+      goto Exit;
+    }
   }
 
   if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof 
(NewBmmData->BootTimeOut)) != 0){
     Status = gRT->SetVariable(
                     L"Timeout",
@@ -781,19 +880,12 @@ BootMaintRouteConfig (
                     EFI_VARIABLE_BOOTSERVICE_ACCESS | 
EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                     sizeof(UINT16),
                     &(NewBmmData->BootTimeOut)
                     );
     if (EFI_ERROR (Status)) {
-      //
-      // If set variable fail, and don't have the appropriate error status for 
RouteConfig fuction to return,
-      // just return the EFI_NOT_FOUND.
-      //
-      if (Status == EFI_OUT_OF_RESOURCES) {
-        return Status;
-      } else {
-        return EFI_NOT_FOUND;
-      }
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootTimeOut);
+      goto Exit;
     }
     Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;
   }
 
   //
@@ -807,19 +899,31 @@ BootMaintRouteConfig (
       NewLoadContext          = (BM_LOAD_CONTEXT *) 
NewMenuEntry->VariableContext;
       NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];
       NewBmmData->DriverOptionDel[Index] = FALSE;
       NewBmmData->DriverOptionDelMark[Index] = FALSE;
     }
-    Var_DelDriverOption ();  
+    Status = Var_DelDriverOption ();
+    if (EFI_ERROR (Status)) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionDel);
+      goto Exit;
+    }
   }
 
   if (CompareMem (NewBmmData->DriverOptionOrder, 
OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {  
     Status = Var_UpdateDriverOrder (Private);
+    if (EFI_ERROR (Status)) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionOrder);
+      goto Exit;
+    }
   }
 
   if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, 
sizeof (NewBmmData->ConsoleOutMode)) != 0){
-    Var_UpdateConMode(Private);
+    Status = Var_UpdateConMode(Private);
+    if (EFI_ERROR (Status)) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutMode);
+      goto Exit;
+    }
   }
 
   TerminalAttChange = FALSE;
   for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
 
@@ -836,35 +940,74 @@ BootMaintRouteConfig (
     }
 
     TerminalAttChange = TRUE;
   }
   if (TerminalAttChange) {
-    Var_UpdateConsoleInpOption ();
-    Var_UpdateConsoleOutOption ();
-    Var_UpdateErrorOutOption ();
+    if (CompareMem (&NewBmmData->COMBaudRate[Index], 
&OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) != 0) 
{
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMBaudRate);
+    } else if (CompareMem (&NewBmmData->COMDataRate[Index], 
&OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) != 0) 
{
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMDataRate);
+    } else if (CompareMem (&NewBmmData->COMStopBits[Index], 
&OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) != 0) 
{
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMStopBits);
+    } else if (CompareMem (&NewBmmData->COMParity[Index], 
&OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) != 0) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMParity);
+    } else if (CompareMem (&NewBmmData->COMTerminalType[Index], 
&OldBmmData->COMTerminalType[Index], sizeof 
(NewBmmData->COMTerminalType[Index])) != 0) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMTerminalType);
+    } else if (CompareMem (&NewBmmData->COMFlowControl[Index], 
&OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) 
!= 0) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMFlowControl);
+    }
+    Status = Var_UpdateConsoleInpOption ();
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
+    Status = Var_UpdateConsoleOutOption ();
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
+    Status = Var_UpdateErrorOutOption ();
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
   }
   //
   // Check data which located in Console Options Menu and save the settings if 
need
   //
   if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, 
sizeof (NewBmmData->ConsoleInCheck)) != 0){
-    Var_UpdateConsoleInpOption();
+    Status = Var_UpdateConsoleInpOption();
+    if (EFI_ERROR (Status)) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleInCheck);
+      goto Exit;
+    }
   }
 
   if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, 
sizeof (NewBmmData->ConsoleOutCheck)) != 0){
-    Var_UpdateConsoleOutOption();
+    Status = Var_UpdateConsoleOutOption();
+    if (EFI_ERROR (Status)) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutCheck);
+      goto Exit;
+    }
   }
 
   if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, 
sizeof (NewBmmData->ConsoleErrCheck)) != 0){
-    Var_UpdateErrorOutOption();
+    Status = Var_UpdateErrorOutOption();
+    if (EFI_ERROR (Status)) {
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleErrCheck);
+      goto Exit;
+    }
   }
 
   if (CompareMem (NewBmmData->BootDescriptionData, 
OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0 
||
        CompareMem (NewBmmData->BootOptionalData, OldBmmData->BootOptionalData, 
sizeof (NewBmmData->BootOptionalData)) != 0) {
     Status = Var_UpdateBootOption (Private);
     NewBmmData->BootOptionChanged = FALSE;
     if (EFI_ERROR (Status)) {
-      return Status;
+      if (CompareMem (NewBmmData->BootDescriptionData, 
OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 
0) {
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootDescriptionData);
+      } else {
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionalData);
+      }
+      goto Exit;
     }
     BOpt_GetBootOptions (Private);
   }
 
   if (CompareMem (NewBmmData->DriverDescriptionData, 
OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) 
!= 0 ||
@@ -877,11 +1020,16 @@ BootMaintRouteConfig (
               NewBmmData->ForceReconnect
               );
     NewBmmData->DriverOptionChanged = FALSE;
     NewBmmData->ForceReconnect      = TRUE;
     if (EFI_ERROR (Status)) {
-      return Status;
+      if (CompareMem (NewBmmData->DriverDescriptionData, 
OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) 
!= 0) {
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverDescriptionData);
+      } else {
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionalData);
+      }
+      goto Exit;
     }
 
     BOpt_GetDriverOptions (Private);
   }
 
@@ -889,10 +1037,21 @@ BootMaintRouteConfig (
   // After user do the save action, need to update OldBmmData.
   //
   CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));
 
   return EFI_SUCCESS;
+
+Exit:
+  //
+  // Fail to save the data, update the progress string.
+  //
+  *Progress = UpdateProgress (Offset, Configuration);
+  if (Status == EFI_OUT_OF_RESOURCES) {
+    return Status;
+  } else {
+    return EFI_NOT_FOUND;
+  }
 }
 
 /**
   This function processes the results of changes in configuration.
 
diff --git a/MdeModulePkg/Library/BootMaintenanceManagerUiLib/Variable.c 
b/MdeModulePkg/Library/BootMaintenanceManagerUiLib/Variable.c
index b65d6a5..a2ae2a7 100644
--- a/MdeModulePkg/Library/BootMaintenanceManagerUiLib/Variable.c
+++ b/MdeModulePkg/Library/BootMaintenanceManagerUiLib/Variable.c
@@ -463,11 +463,13 @@ Var_UpdateErrorOutOption (
   @param HiiHandle       The HII handle associated with the BMM formset.
   @param DescriptionData The description of this driver option.
   @param OptionalData    The optional load option.
   @param ForceReconnect  If to force reconnect.
 
-  @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
+  @retval other                Contain some errors when excuting this 
function.See function
+                               
EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl
+                               for detail return information.
   @retval EFI_SUCCESS          If function completes successfully.
 
 **/
 EFI_STATUS
 Var_UpdateDriverOption (
@@ -523,12 +525,18 @@ Var_UpdateDriverOption (
              DescriptionData,
              CallbackData->LoadContext->FilePathList,
              OptionalDesData,
              OptionalDataSize
            );
-  if (!EFI_ERROR (Status)){
-    Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 );
+  if (EFI_ERROR (Status)){
+    return Status;
+  }
+
+  Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 );
+  if (EFI_ERROR (Status)) {
+    EfiBootManagerFreeLoadOption(&LoadOption);
+    return Status;
   }
 
   NewLoadContext                  = (BM_LOAD_CONTEXT *) 
NewMenuEntry->VariableContext;
   NewLoadContext->Deleted         = FALSE;
   NewLoadContext->Attributes = LoadOption.Attributes;
@@ -580,11 +588,13 @@ Var_UpdateDriverOption (
   the "BootOrder" list. It also append this Boot Opotion to the end
   of BootOptionMenu.
 
   @param CallbackData    The BMM context data.
 
-  @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
+  @retval other                Contain some errors when excuting this 
function. See function
+                               
EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl
+                               for detail return information.
   @retval EFI_SUCCESS          If function completes successfully.
 
 **/
 EFI_STATUS
 Var_UpdateBootOption (
@@ -633,12 +643,18 @@ Var_UpdateBootOption (
              NvRamMap->BootDescriptionData,
              CallbackData->LoadContext->FilePathList,
              OptionalData,
              OptionalDataSize
            );
-  if (!EFI_ERROR (Status)){
-    Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 );
+  if (EFI_ERROR (Status)){
+    return Status;
+  }
+
+  Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 );
+  if (EFI_ERROR (Status)) {
+    EfiBootManagerFreeLoadOption(&LoadOption);
+    return Status;
   }
 
   NewLoadContext                  = (BM_LOAD_CONTEXT *) 
NewMenuEntry->VariableContext;
   NewLoadContext->Deleted         = FALSE;
   NewLoadContext->Attributes = LoadOption.Attributes;
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to