[edk2-devel] [edk2-platforms] [PATCH v1 4/4] MinPlatformPkg: Add LargeVariableWriteLib

Nate DeSimone nathaniel.l.desimone at intel.com
Sat Apr 3 01:00:35 UTC 2021


LargeVariableWriteLib is used to store large data sets using
the UEFI Variable Services. At time of writting, most UEFI
Variable Services implementations to not allow more than 64KB
of data to be stored in a single UEFI variable. This library
will split data sets across multiple variables as needed.

It adds the SetLargeVariable() API to provide this service.

Cc: Chasel Chiu <chasel.chiu at intel.com>
Cc: Liming Gao <gaoliming at byosoft.com.cn>
Cc: Eric Dong <eric.dong at intel.com>
Cc: Michael Kubacki <michael.kubacki at microsoft.com>
Cc: Isaac Oram <isaac.w.oram at intel.com>
Signed-off-by: Nate DeSimone <nathaniel.l.desimone at intel.com>
---
 .../Include/Dsc/CoreCommonLib.dsc             |   1 +
 .../Include/Library/LargeVariableWriteLib.h   |  48 ++
 .../BaseLargeVariableWriteLib.inf             |  42 ++
 .../LargeVariableWriteLib.c                   | 412 ++++++++++++++++++
 4 files changed, 503 insertions(+)
 create mode 100644 Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h
 create mode 100644 Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableWriteLib/BaseLargeVariableWriteLib.inf
 create mode 100644 Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableWriteLib/LargeVariableWriteLib.c

diff --git a/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc b/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
index 5f2ad3f0f0..78d66b9072 100644
--- a/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
+++ b/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
@@ -143,6 +143,7 @@
   SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
   BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
   LargeVariableReadLib|MinPlatformPkg/Library/BaseLargeVariableReadLib/BaseLargeVariableReadLib.inf
+  LargeVariableWriteLib|MinPlatformPkg/Library/BaseLargeVariableWriteLib/BaseLargeVariableWriteLib.inf
 
   #
   # CryptLib
diff --git a/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h
new file mode 100644
index 0000000000..483091d91e
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h
@@ -0,0 +1,48 @@
+/** @file
+  Large Variable Write Lib
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+
+/**
+  Sets the value of a large variable.
+
+  @param[in]  VariableName       A Null-terminated string that is the name of the vendor's variable.
+                                 Each VariableName is unique for each VendorGuid. VariableName must
+                                 contain 1 or more characters. If VariableName is an empty string,
+                                 then EFI_INVALID_PARAMETER is returned.
+  @param[in]  VendorGuid         A unique identifier for the vendor.
+  @param[in]  LockVariable       If TRUE, any further writes to the variable will be prevented until the next reset.
+                                 Note: LockVariable must be FALSE when running in SMM or after ExitBootServices.
+  @param[in]  DataSize           The size in bytes of the Data buffer. A size of zero causes the variable to be deleted.
+                                 If DataSize is zero, then LockVariable must be FALSE since a variable that does not
+                                 exist cannot be locked.
+  @param[in]  Data               The contents for the variable.
+
+  @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
+                                 defined by the Attributes.
+  @retval EFI_INVALID_PARAMETER  An invalid combination of LockVariable, name, and GUID was supplied, or the
+                                 DataSize exceeds the maximum allowed.
+  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
+  @retval EFI_INVALID_PARAMETER  DataSize is zero and LockVariable is TRUE
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
+  @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
+
+  @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+SetLargeVariable (
+  IN  CHAR16                       *VariableName,
+  IN  EFI_GUID                     *VendorGuid,
+  IN  BOOLEAN                      LockVariable,
+  IN  UINTN                        DataSize,
+  IN  VOID                         *Data
+  );
diff --git a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableWriteLib/BaseLargeVariableWriteLib.inf b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableWriteLib/BaseLargeVariableWriteLib.inf
new file mode 100644
index 0000000000..cac62ea650
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableWriteLib/BaseLargeVariableWriteLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Component description file for Large Variable Write Library
+#
+# This library is used to store large data sets using the UEFI Variable Services.
+# At time of writting, most UEFI Variable Services implementations to not allow
+# more than 64KB of data to be stored in a single UEFI variable. This library
+# will split data sets across multiple variables as needed.
+#
+# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BaseLargeVariableWriteLib
+  FILE_GUID                      = 13E7DD75-FBE0-4B92-87A9-6BED253EB99E
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = LargeVariableWriteLib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  LargeVariableWriteLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  PrintLib
+  VariableReadLib
+  VariableWriteLib
+
+[Pcd]
diff --git a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableWriteLib/LargeVariableWriteLib.c b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableWriteLib/LargeVariableWriteLib.c
new file mode 100644
index 0000000000..1ecb2b9478
--- /dev/null
+++ b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableWriteLib/LargeVariableWriteLib.c
@@ -0,0 +1,412 @@
+/** @file
+  Large Variable Write Lib
+
+  This library is used to store large data sets using the UEFI Variable Services.
+  At time of writting, most UEFI Variable Services implementations to not allow
+  more than 64KB of data to be stored in a single UEFI variable. This library
+  will split data sets across multiple variables as needed.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/VariableReadLib.h>
+#include <Library/VariableWriteLib.h>
+
+#define MAX_VARIABLE_NAME_SIZE      1024
+#define MAX_VARIABLE_SPLIT          131072
+#define MAX_VARIABLE_SPLIT_DIGITS   6
+
+//
+// On some architectures (Ex. Itanium) there a requirement to
+// maintain DWORD alignment of the variable data. Hence the
+// maximum possible padding size is 3.
+//
+#define MAX_VARIABLE_NAME_PAD_SIZE  3
+
+/**
+  Returns the amount of space remaining for storage of
+  non-volatile runtime accessible UEFI variables.
+
+  @retval The remaining storage space for non-volatile runtime accessible UEFI variables in bytes.
+
+**/
+UINT64
+GetRemainingVariableStorageSpace (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+  UINT64          MaximumVariableStorageSize;
+  UINT64          RemainingVariableStorageSize;
+  UINT64          MaximumVariableSize;
+
+  Status                        = EFI_SUCCESS;
+  MaximumVariableStorageSize    = 0;
+  RemainingVariableStorageSize  = 0;
+  MaximumVariableSize           = 0;
+
+  Status = MinQueryVariableInfo (
+             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+             &MaximumVariableStorageSize,
+             &RemainingVariableStorageSize,
+             &MaximumVariableSize
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "GetVariableSplitSize: QueryVariableInfo failed, Status = %r\n", Status));
+    ASSERT_EFI_ERROR (Status);
+    return 0;
+  }
+
+  return RemainingVariableStorageSize;
+}
+
+/**
+  Returns the maximum size of an individual non-volatile runtime accessible UEFI variable.
+
+  @param[in] VariableNameLength         Length of the variable name
+
+  @retval The maximum size of an individual UEFI variable.
+
+**/
+UINT64
+GetVariableSplitSize (
+  IN  UINTN                        VariableNameLength
+  )
+{
+  EFI_STATUS      Status;
+  UINT64          MaximumVariableStorageSize;
+  UINT64          RemainingVariableStorageSize;
+  UINT64          VariableSplitSize;
+
+  Status                        = EFI_SUCCESS;
+  MaximumVariableStorageSize    = 0;
+  RemainingVariableStorageSize  = 0;
+  VariableSplitSize             = 0;
+
+  Status = MinQueryVariableInfo (
+             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+             &MaximumVariableStorageSize,
+             &RemainingVariableStorageSize,
+             &VariableSplitSize
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "GetVariableSplitSize: QueryVariableInfo failed, Status = %r\n", Status));
+    ASSERT_EFI_ERROR (Status);
+    return 0;
+  } else {
+    //
+    // The Variable Name counts as part of the consumed NV storage
+    // space for a UEFI Variable
+    //
+    if ((((VariableNameLength + 1) * sizeof (CHAR16)) + MAX_VARIABLE_NAME_PAD_SIZE) >= VariableSplitSize) {
+      VariableSplitSize = 0;
+    } else {
+      VariableSplitSize -= ((VariableNameLength + 1) * sizeof (CHAR16)) + MAX_VARIABLE_NAME_PAD_SIZE;
+    }
+  }
+
+  return VariableSplitSize;
+}
+
+/**
+  Sets the value of a large variable.
+
+  @param[in]  VariableName       A Null-terminated string that is the name of the vendor's variable.
+                                 Each VariableName is unique for each VendorGuid. VariableName must
+                                 contain 1 or more characters. If VariableName is an empty string,
+                                 then EFI_INVALID_PARAMETER is returned.
+  @param[in]  VendorGuid         A unique identifier for the vendor.
+
+  @retval EFI_SUCCESS            The firmware has successfully deleted the variable and its data as
+                                 defined by the Attributes.
+  @retval EFI_INVALID_PARAMETER  An invalid combination of name, and GUID was supplied.
+  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
+  @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
+
+  @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+DeleteLargeVariableInternal (
+  IN  CHAR16                       *VariableName,
+  IN  EFI_GUID                     *VendorGuid
+  )
+{
+  CHAR16        TempVariableName[MAX_VARIABLE_NAME_SIZE];
+  EFI_STATUS    Status;
+  EFI_STATUS    Status2;
+  UINTN         VarDataSize;
+  UINTN         Index;
+
+  VarDataSize = 0;
+  //
+  // First check if a variable with the given name exists
+  //
+  Status = MinGetVariable (VariableName, VendorGuid, NULL, &VarDataSize, NULL);
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    DEBUG ((DEBUG_INFO, "DeleteLargeVariableInternal: Deleting Single Variable\n"));
+    Status = MinSetVariable (
+                VariableName,
+                VendorGuid,
+                EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                0,
+                NULL
+                );
+    goto Done;
+  } else if (Status == EFI_NOT_FOUND) {
+    //
+    // Check if the first variable of a multi-variable set exists
+    //
+    if (StrLen (VariableName) >= (MAX_VARIABLE_NAME_SIZE - MAX_VARIABLE_SPLIT_DIGITS)) {
+      DEBUG ((DEBUG_ERROR, "DeleteLargeVariableInternal: Variable name too long\n"));
+      Status = EFI_OUT_OF_RESOURCES;
+      goto Done;
+    }
+    VarDataSize = 0;
+    Index       = 0;
+    ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE);
+    UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index);
+    Status = MinGetVariable (TempVariableName, VendorGuid, NULL, &VarDataSize, NULL);
+    if (Status == EFI_BUFFER_TOO_SMALL) {
+      //
+      // The first variable exists. Delete all the variables.
+      //
+      DEBUG ((DEBUG_INFO, "DeleteLargeVariableInternal: Multiple Variables Found\n"));
+      Status = EFI_SUCCESS;
+      for (Index = 0; Index < MAX_VARIABLE_SPLIT; Index++) {
+        VarDataSize = 0;
+        ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE);
+        UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index);
+        DEBUG ((DEBUG_INFO, "Deleting %s, Guid = %g\n", TempVariableName, VendorGuid));
+        Status2 = MinSetVariable (
+                    TempVariableName,
+                    VendorGuid,
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                    0,
+                    NULL
+                    );
+        if (Status2 == EFI_NOT_FOUND) {
+          DEBUG ((DEBUG_INFO, "DeleteLargeVariableInternal: Deletion Complete.\n"));
+          break;
+        } else if (EFI_ERROR (Status2)) {
+          DEBUG ((DEBUG_ERROR, "DeleteLargeVariableInternal: Error deleting variable: Status = %r\n", Status2));
+          Status = Status2;
+        }
+      }
+    } else {
+      Status = EFI_NOT_FOUND;
+    }
+  }
+Done:
+  DEBUG ((DEBUG_ERROR, "DeleteLargeVariableInternal: Status = %r\n", Status));
+  return Status;
+}
+
+/**
+  Sets the value of a large variable.
+
+  @param[in]  VariableName       A Null-terminated string that is the name of the vendor's variable.
+                                 Each VariableName is unique for each VendorGuid. VariableName must
+                                 contain 1 or more characters. If VariableName is an empty string,
+                                 then EFI_INVALID_PARAMETER is returned.
+  @param[in]  VendorGuid         A unique identifier for the vendor.
+  @param[in]  LockVariable       If TRUE, any further writes to the variable will be prevented until the next reset.
+                                 Note: LockVariable must be FALSE when running in SMM or after ExitBootServices.
+  @param[in]  DataSize           The size in bytes of the Data buffer. A size of zero causes the variable to be deleted.
+                                 If DataSize is zero, then LockVariable must be FALSE since a variable that does not
+                                 exist cannot be locked.
+  @param[in]  Data               The contents for the variable.
+
+  @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
+                                 defined by the Attributes.
+  @retval EFI_INVALID_PARAMETER  An invalid combination of LockVariable, name, and GUID was supplied, or the
+                                 DataSize exceeds the maximum allowed.
+  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
+  @retval EFI_INVALID_PARAMETER  DataSize is zero and LockVariable is TRUE
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
+  @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
+
+  @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+SetLargeVariable (
+  IN  CHAR16                       *VariableName,
+  IN  EFI_GUID                     *VendorGuid,
+  IN  BOOLEAN                      LockVariable,
+  IN  UINTN                        DataSize,
+  IN  VOID                         *Data
+  )
+{
+  CHAR16        TempVariableName[MAX_VARIABLE_NAME_SIZE];
+  UINT64        VariableSplitSize;
+  UINT64        RemainingVariableStorage;
+  EFI_STATUS    Status;
+  EFI_STATUS    Status2;
+  UINTN         VariableNameLength;
+  UINTN         Index;
+  UINTN         VariablesSaved;
+  UINT8         *OffsetPtr;
+  UINTN         BytesRemaining;
+  UINTN         SizeToSave;
+
+  //
+  // Check input parameters.
+  //
+  if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DataSize != 0 && Data == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DataSize == 0 && LockVariable) {
+    DEBUG ((DEBUG_ERROR, "SetLargeVariable: Cannot lock a variable that is being deleted\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  VariablesSaved = 0;
+  if (LockVariable && !MinIsVariableRequestToLockSupported()) {
+      Status = EFI_INVALID_PARAMETER;
+      DEBUG ((DEBUG_ERROR, "SetLargeVariable: Variable locking is not currently supported\n"));
+      goto Done;
+  }
+
+  //
+  // Check if the variable is being deleted.
+  //
+  if (DataSize == 0) {
+    DEBUG ((DEBUG_INFO, "SetLargeVariable: Variable is being deleted.\n"));
+    Status = DeleteLargeVariableInternal (VariableName, VendorGuid);
+    goto Done;
+  }
+
+  VariableNameLength  = StrLen (VariableName);
+  VariableSplitSize   = GetVariableSplitSize (VariableNameLength);
+  if (DataSize <= VariableSplitSize) {
+    //
+    // A single variable is sufficient to store the data, only create one.
+    //
+    DEBUG ((DEBUG_INFO, "SetLargeVariable: Saving using single variable.\n"));
+    Status = MinSetVariable (
+               VariableName,
+               VendorGuid,
+               EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+               DataSize,
+               Data
+               );
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+    if (LockVariable) {
+      Status = MinVariableRequestToLock (VariableName, VendorGuid);
+    }
+  } else {
+    //
+    // Multiple variables are needed
+    //
+    if (VariableNameLength >= (MAX_VARIABLE_NAME_SIZE - MAX_VARIABLE_SPLIT_DIGITS)) {
+      Status = EFI_OUT_OF_RESOURCES;
+      DEBUG ((DEBUG_ERROR, "SetLargeVariable: Variable name too long\n"));
+      goto Done;
+    }
+    if ((DataSize / (VariableSplitSize - MAX_VARIABLE_SPLIT_DIGITS)) > MAX_VARIABLE_SPLIT) {
+      DEBUG ((DEBUG_ERROR, "SetLargeVariable: Too many variables are needed to store the data\n"));
+      Status = EFI_OUT_OF_RESOURCES;
+      goto Done;
+    }
+    RemainingVariableStorage = GetRemainingVariableStorageSpace ();
+    if (DataSize > RemainingVariableStorage) {
+      DEBUG ((DEBUG_ERROR, "SetLargeVariable: Not enough NV storage space to store the data\n"));
+      Status = EFI_OUT_OF_RESOURCES;
+      goto Done;
+    }
+    DEBUG ((DEBUG_INFO, "SetLargeVariable: Saving using multiple variables.\n"));
+    OffsetPtr         = (UINT8 *) Data;
+    BytesRemaining    = DataSize;
+    VariablesSaved    = 0;
+    for (Index = 0; (Index < MAX_VARIABLE_SPLIT) && (BytesRemaining > 0); Index++) {
+      ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE);
+      UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index);
+
+      SizeToSave          = 0;
+      VariableNameLength  = StrLen (TempVariableName);
+      VariableSplitSize   = GetVariableSplitSize (VariableNameLength);
+      if (VariableSplitSize == 0) {
+        DEBUG ((DEBUG_ERROR, "Unable to save variable, out of NV storage space\n"));
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Done;
+      }
+
+      if (BytesRemaining > VariableSplitSize) {
+        SizeToSave = (UINTN) VariableSplitSize;
+      } else {
+        SizeToSave = BytesRemaining;
+      }
+      DEBUG ((DEBUG_INFO, "Saving %s, Guid = %g, Size %d\n", TempVariableName, VendorGuid, SizeToSave));
+      Status = MinSetVariable (
+                TempVariableName,
+                VendorGuid,
+                EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                SizeToSave,
+                (VOID *) OffsetPtr
+                );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error writting variable: Status = %r\n", Status));
+        goto Done;
+      }
+      VariablesSaved  = Index;
+      BytesRemaining -= SizeToSave;
+      OffsetPtr += SizeToSave;
+    }
+    if (LockVariable) {
+      for (Index = 0; Index < VariablesSaved; Index++) {
+        ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE);
+        UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index);
+
+        DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", TempVariableName, VendorGuid));
+        Status = MinVariableRequestToLock (TempVariableName, VendorGuid);
+        if (EFI_ERROR (Status)) {
+          DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error locking variable: Status = %r\n", Status));
+          VariablesSaved = 0;
+          goto Done;
+        }
+      }
+    }
+  }
+Done:
+  if (EFI_ERROR (Status) && VariablesSaved > 0) {
+    DEBUG ((DEBUG_ERROR, "SetLargeVariable: An error was encountered, deleting variables with partially stored data\n"));
+    for (Index = 0; Index < VariablesSaved; Index++) {
+      ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE);
+      UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index);
+
+      DEBUG ((DEBUG_INFO, "Deleting %s, Guid = %g\n", TempVariableName, VendorGuid));
+      Status2 = MinSetVariable (
+                  TempVariableName,
+                  VendorGuid,
+                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                  0,
+                  NULL
+                  );
+    DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error deleting variable: Status = %r\n", Status2));
+    }
+  }
+  DEBUG ((DEBUG_ERROR, "SetLargeVariable: Status = %r\n", Status));
+  return Status;
+}
-- 
2.27.0.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#73664): https://edk2.groups.io/g/devel/message/73664
Mute This Topic: https://groups.io/mt/81816893/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list