]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Add PlatformVarCleanupLib library
authorStar Zeng <star.zeng@intel.com>
Tue, 25 Aug 2015 03:11:06 +0000 (03:11 +0000)
committerlzeng14 <lzeng14@Edk2>
Tue, 25 Aug 2015 03:11:06 +0000 (03:11 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18295 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Include/Library/PlatformVarCleanupLib.h [new file with mode: 0644]
MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanup.h [new file with mode: 0644]
MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanup.vfr [new file with mode: 0644]
MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanupHii.h [new file with mode: 0644]
MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanupLib.c [new file with mode: 0644]
MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.inf [new file with mode: 0644]
MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.uni [new file with mode: 0644]
MdeModulePkg/Library/PlatformVarCleanupLib/VfrStrings.uni [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/MdeModulePkg.dsc

diff --git a/MdeModulePkg/Include/Library/PlatformVarCleanupLib.h b/MdeModulePkg/Include/Library/PlatformVarCleanupLib.h
new file mode 100644 (file)
index 0000000..a4691f0
--- /dev/null
@@ -0,0 +1,61 @@
+/** @file\r
+  The library class provides platform variable cleanup services.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _PLATFORM_VARIABLE_CLEANUP_LIB_\r
+#define _PLATFORM_VARIABLE_CLEANUP_LIB_\r
+\r
+#include <Guid/VarErrorFlag.h>\r
+\r
+typedef enum {\r
+  VarCleanupAll,\r
+  VarCleanupManually,\r
+  VarCleanupMax,\r
+} VAR_CLEANUP_TYPE;\r
+\r
+/**\r
+  Get last boot variable error flag.\r
+\r
+  @return   Last boot variable error flag.\r
+\r
+**/\r
+VAR_ERROR_FLAG\r
+EFIAPI\r
+GetLastBootVarErrorFlag (\r
+  );\r
+\r
+/**\r
+  Platform variable cleanup.\r
+\r
+  @param[in] Flag                   Variable error flag.\r
+  @param[in] Type                   Variable cleanup type.\r
+                                    If it is VarCleanupManually, the interface must be called after console connected.\r
+\r
+  @retval EFI_SUCCESS               No error or error processed.\r
+  @retval EFI_UNSUPPORTED           The specified Flag or Type is not supported.\r
+                                    For example, system error may be not supported to process and Platform should have mechanism to reset system to manufacture mode.\r
+                                    Another, if system and user variables are wanted to be distinguished to process, the interface must be called after EndOfDxe.\r
+  @retval EFI_OUT_OF_RESOURCES      Not enough resource to process the error.\r
+  @retval EFI_INVALID_PARAMETER     The specified Flag or Type is an invalid value.\r
+  @retval Others                    Other failure occurs.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatformVarCleanup (\r
+  IN VAR_ERROR_FLAG     Flag,\r
+  IN VAR_CLEANUP_TYPE   Type\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanup.h b/MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanup.h
new file mode 100644 (file)
index 0000000..5290aae
--- /dev/null
@@ -0,0 +1,108 @@
+/** @file\r
+  Include file for platform variable cleanup.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _PLAT_VAR_CLEANUP_\r
+#define _PLAT_VAR_CLEANUP_\r
+\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/PlatformVarCleanupLib.h>\r
+\r
+#include <Protocol/Variable.h>\r
+#include <Protocol/VarCheck.h>\r
+#include <Protocol/FormBrowser2.h>\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiConfigRouting.h>\r
+#include <Protocol/DevicePath.h>\r
+\r
+#include <Guid/EventGroup.h>\r
+#include <Guid/MdeModuleHii.h>\r
+#include <Guid/ImageAuthentication.h>\r
+#include <Guid/VarErrorFlag.h>\r
+\r
+#include "PlatVarCleanupHii.h"\r
+\r
+//\r
+// This is the generated IFR binary data for each formset defined in VFR.\r
+// This data array is ready to be used as input of HiiAddPackages() to\r
+// create a packagelist (which contains Form packages, String packages, etc).\r
+//\r
+extern UINT8 PlatVarCleanupBin[];\r
+\r
+//\r
+// This is the generated String package data for all .UNI files.\r
+// This data array is ready to be used as input of HiiAddPackages() to\r
+// create a packagelist (which contains Form packages, String packages, etc).\r
+//\r
+extern UINT8 PlatformVarCleanupLibStrings[];\r
+\r
+#define USER_VARIABLE_NODE_SIGNATURE SIGNATURE_32 ('U', 'V', 'N', 'S')\r
+\r
+typedef struct {\r
+  UINTN             Signature;\r
+  LIST_ENTRY        Link;\r
+  EFI_GUID          Guid;\r
+  CHAR16            *PromptString;\r
+  LIST_ENTRY        NameLink;\r
+} USER_VARIABLE_NODE;\r
+\r
+#define USER_VARIABLE_FROM_LINK(a) CR (a, USER_VARIABLE_NODE, Link, USER_VARIABLE_NODE_SIGNATURE)\r
+\r
+#define USER_VARIABLE_NAME_NODE_SIGNATURE SIGNATURE_32 ('U', 'V', 'N', 'N')\r
+\r
+typedef struct {\r
+  UINTN             Signature;\r
+  LIST_ENTRY        Link;\r
+  CHAR16            *Name;\r
+  UINTN             DataSize;\r
+  UINT32            Attributes;\r
+  UINT16            Index;\r
+  EFI_QUESTION_ID   QuestionId;\r
+  CHAR16            *PromptString;\r
+  CHAR16            *HelpString;\r
+  BOOLEAN           Deleted;\r
+} USER_VARIABLE_NAME_NODE;\r
+\r
+#define USER_VARIABLE_NAME_FROM_LINK(a) CR (a, USER_VARIABLE_NAME_NODE, Link, USER_VARIABLE_NAME_NODE_SIGNATURE)\r
+\r
+#pragma pack(1)\r
+//\r
+// HII specific Vendor Device Path definition.\r
+//\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH            VendorDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL      End;\r
+} HII_VENDOR_DEVICE_PATH;\r
+#pragma pack()\r
+\r
+#define VARIABLE_CLEANUP_HII_PRIVATE_SIGNATURE SIGNATURE_32 ('V', 'C', 'H', 'P')\r
+\r
+typedef struct {\r
+  UINTN                             Signature;\r
+  EFI_HANDLE                        DriverHandle;\r
+  EFI_HII_HANDLE                    HiiHandle;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL    ConfigAccess;\r
+  EFI_HII_CONFIG_ROUTING_PROTOCOL   *ConfigRouting;\r
+  VARIABLE_CLEANUP_DATA             VariableCleanupData;\r
+} VARIABLE_CLEANUP_HII_PRIVATE_DATA;\r
+\r
+#define VARIABLE_CLEANUP_HII_PRIVATE_FROM_THIS(a) CR (a, VARIABLE_CLEANUP_HII_PRIVATE_DATA, ConfigAccess, VARIABLE_CLEANUP_HII_PRIVATE_SIGNATURE)\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanup.vfr b/MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanup.vfr
new file mode 100644 (file)
index 0000000..7dfeafa
--- /dev/null
@@ -0,0 +1,41 @@
+/** @file\r
+ Platform variable cleanup Formset.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "PlatVarCleanupHii.h"\r
+\r
+formset\r
+  guid     = VARIABLE_CLEANUP_HII_GUID,\r
+  title    = STRING_TOKEN(STR_ENTRY_TITLE),\r
+  help     = STRING_TOKEN(STR_TITLE_HELP),\r
+\r
+  varstore VARIABLE_CLEANUP_DATA,\r
+    varid = VARIABLE_CLEANUP_VARSTORE_ID,\r
+    name  = VariableCleanup,\r
+    guid  = VARIABLE_CLEANUP_HII_GUID;\r
+\r
+  form formid = FORM_ID_VARIABLE_CLEANUP,\r
+    title = STRING_TOKEN(STR_TITLE);\r
+\r
+    checkbox varid = VARIABLE_CLEANUP_DATA.SelectAll,\r
+      prompt   = STRING_TOKEN(STR_SELECT_ALL_PROMPT),\r
+      help     = STRING_TOKEN(STR_SELECT_ALL_HELP),\r
+      flags    = INTERACTIVE,\r
+      key      = SELECT_ALL_QUESTION_ID,\r
+    endcheckbox;\r
+\r
+    label LABEL_START;\r
+    label LABEL_END;\r
+\r
+  endform;\r
+endformset;\r
diff --git a/MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanupHii.h b/MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanupHii.h
new file mode 100644 (file)
index 0000000..02af877
--- /dev/null
@@ -0,0 +1,59 @@
+/** @file\r
+  Include file for platform variable cleanup HII.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _PLAT_VAR_CLEANUP_HII_\r
+#define _PLAT_VAR_CLEANUP_HII_\r
+\r
+//\r
+// {24F14D8A-D7A8-4991-91E0-96C3B7DB8456}\r
+//\r
+#define VARIABLE_CLEANUP_HII_GUID \\r
+  { \\r
+    0x24f14d8a, 0xd7a8, 0x4991, { 0x91, 0xe0, 0x96, 0xc3, 0xb7, 0xdb, 0x84, 0x56 } \\r
+  }\r
+\r
+#define MAX_USER_VARIABLE_COUNT         0x1000\r
+\r
+typedef struct {\r
+  UINT8   SelectAll;\r
+  //\r
+  // FALSE is to not delete, TRUE is to delete.\r
+  //\r
+  UINT8   UserVariable[MAX_USER_VARIABLE_COUNT];\r
+} VARIABLE_CLEANUP_DATA;\r
+\r
+#define VARIABLE_CLEANUP_VARSTORE_ID    0x8000\r
+\r
+//\r
+// Field offset of structure VARIABLE_CLEANUP_DATA\r
+//\r
+#define VAR_OFFSET(Field)               ((UINTN) &(((VARIABLE_CLEANUP_DATA *) 0)->Field))\r
+#define USER_VARIABLE_VAR_OFFSET        (VAR_OFFSET (UserVariable))\r
+\r
+#define FORM_ID_VARIABLE_CLEANUP        0x8000\r
+\r
+#define LABEL_START                     0x0000\r
+#define LABEL_END                       0xFFFF\r
+\r
+#define SELECT_ALL_QUESTION_ID          0x7FFD\r
+#define SAVE_AND_EXIT_QUESTION_ID       0x7FFE\r
+#define NO_SAVE_AND_EXIT_QUESTION_ID    0x7FFF\r
+\r
+//\r
+// Tool automatic generated Question Id start from 1.\r
+// In order to avoid to conflict them, the user variable QuestionID offset is defined from 0x8000.\r
+//\r
+#define USER_VARIABLE_QUESTION_ID       0x8000\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanupLib.c b/MdeModulePkg/Library/PlatformVarCleanupLib/PlatVarCleanupLib.c
new file mode 100644 (file)
index 0000000..d99174c
--- /dev/null
@@ -0,0 +1,1250 @@
+/** @file\r
+  Sample platform variable cleanup library implementation.\r
+\r
+Copyright (c) 2015, 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
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "PlatVarCleanup.h"\r
+\r
+VAR_ERROR_FLAG              mLastVarErrorFlag = VAR_ERROR_FLAG_NO_ERROR;\r
+EDKII_VAR_CHECK_PROTOCOL    *mVarCheck = NULL;\r
+\r
+///\r
+/// The flag to indicate whether the platform has left the DXE phase of execution.\r
+///\r
+BOOLEAN                     mEndOfDxe = FALSE;\r
+\r
+LIST_ENTRY                  mUserVariableList = INITIALIZE_LIST_HEAD_VARIABLE (mUserVariableList);\r
+UINT16                      mUserVariableCount = 0;\r
+UINT16                      mMarkedUserVariableCount = 0;\r
+\r
+EFI_GUID                    mVariableCleanupHiiGuid = VARIABLE_CLEANUP_HII_GUID;\r
+CHAR16                      mVarStoreName[] = L"VariableCleanup";\r
+\r
+HII_VENDOR_DEVICE_PATH      mVarCleanupHiiVendorDevicePath = {\r
+  {\r
+    {\r
+      HARDWARE_DEVICE_PATH,\r
+      HW_VENDOR_DP,\r
+      {\r
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    VARIABLE_CLEANUP_HII_GUID\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
+/**\r
+  Internal get variable error flag.\r
+\r
+  @return   Variable error flag.\r
+\r
+**/\r
+VAR_ERROR_FLAG\r
+InternalGetVarErrorFlag (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS        Status;\r
+  UINTN             Size;\r
+  VAR_ERROR_FLAG    ErrorFlag;\r
+\r
+  Size = sizeof (ErrorFlag);\r
+  Status = gRT->GetVariable (\r
+                  VAR_ERROR_FLAG_NAME,\r
+                  &gEdkiiVarErrorFlagGuid,\r
+                  NULL,\r
+                  &Size,\r
+                  &ErrorFlag\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_INFO, "%s - not found\n", VAR_ERROR_FLAG_NAME));\r
+    return VAR_ERROR_FLAG_NO_ERROR;\r
+  }\r
+  return ErrorFlag;\r
+}\r
+\r
+/**\r
+  Is user variable?\r
+\r
+  @param[in] Name   Pointer to variable name.\r
+  @param[in] Guid   Pointer to vendor guid.\r
+\r
+  @retval TRUE      User variable.\r
+  @retval FALSE     System variable.\r
+\r
+**/\r
+BOOLEAN\r
+IsUserVariable (\r
+  IN CHAR16                     *Name,\r
+  IN EFI_GUID                   *Guid\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  VAR_CHECK_VARIABLE_PROPERTY   Property;\r
+\r
+  ZeroMem (&Property, sizeof (Property));\r
+  Status = mVarCheck->VariablePropertyGet (\r
+                        Name,\r
+                        Guid,\r
+                        &Property\r
+                        );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // No property, it is user variable.\r
+    //\r
+    DEBUG ((EFI_D_INFO, "PlatformVarCleanup - User variable: %g:%s\n", Guid, Name));\r
+    return TRUE;\r
+  }\r
+\r
+//  DEBUG ((EFI_D_INFO, "PlatformVarCleanup - Variable Property: %g:%s\n", Guid, Name));\r
+//  DEBUG ((EFI_D_INFO, "  Revision  - 0x%04x\n", Property.Revision));\r
+//  DEBUG ((EFI_D_INFO, "  Property  - 0x%04x\n", Property.Property));\r
+//  DEBUG ((EFI_D_INFO, "  Attribute - 0x%08x\n", Property.Attributes));\r
+//  DEBUG ((EFI_D_INFO, "  MinSize   - 0x%x\n", Property.MinSize));\r
+//  DEBUG ((EFI_D_INFO, "  MaxSize   - 0x%x\n", Property.MaxSize));\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Find user variable node by variable GUID.\r
+\r
+  @param[in] Guid   Pointer to vendor guid.\r
+\r
+  @return Pointer to user variable node.\r
+\r
+**/\r
+USER_VARIABLE_NODE *\r
+FindUserVariableNodeByGuid (\r
+  IN EFI_GUID   *Guid\r
+  )\r
+{\r
+  USER_VARIABLE_NODE    *UserVariableNode;\r
+  LIST_ENTRY            *Link;\r
+\r
+  for (Link = mUserVariableList.ForwardLink\r
+       ;Link != &mUserVariableList\r
+       ;Link = Link->ForwardLink) {\r
+    UserVariableNode = USER_VARIABLE_FROM_LINK (Link);\r
+\r
+    if (CompareGuid (Guid, &UserVariableNode->Guid)) {\r
+      //\r
+      // Found it.\r
+      //\r
+      return UserVariableNode;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Create new one if not found.\r
+  //\r
+  UserVariableNode = AllocateZeroPool (sizeof (*UserVariableNode));\r
+  ASSERT (UserVariableNode != NULL);\r
+  UserVariableNode->Signature = USER_VARIABLE_NODE_SIGNATURE;\r
+  CopyGuid (&UserVariableNode->Guid, Guid);\r
+  //\r
+  // (36 chars of "########-####-####-####-############" + 1 space + 1 terminator) * sizeof (CHAR16).\r
+  //\r
+  UserVariableNode->PromptString = AllocatePool ((36 + 2) * sizeof (CHAR16));\r
+  ASSERT (UserVariableNode->PromptString != NULL);\r
+  UnicodeSPrint (UserVariableNode->PromptString, (36 + 2) * sizeof (CHAR16), L" %g", &UserVariableNode->Guid);\r
+  InitializeListHead (&UserVariableNode->NameLink);\r
+  InsertTailList (&mUserVariableList, &UserVariableNode->Link);\r
+  return UserVariableNode;\r
+}\r
+\r
+/**\r
+  Create user variable node.\r
+\r
+**/\r
+VOID\r
+CreateUserVariableNode (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_STATUS                    GetVariableStatus;\r
+  CHAR16                        *VarName;\r
+  UINTN                         MaxVarNameSize;\r
+  UINTN                         VarNameSize;\r
+  UINTN                         MaxDataSize;\r
+  UINTN                         DataSize;\r
+  VOID                          *Data;\r
+  UINT32                        Attributes;\r
+  EFI_GUID                      Guid;\r
+  USER_VARIABLE_NODE            *UserVariableNode;\r
+  USER_VARIABLE_NAME_NODE       *UserVariableNameNode;\r
+  UINT16                        Index;\r
+  UINTN                         StringSize;\r
+\r
+  //\r
+  // Initialize 128 * sizeof (CHAR16) variable name size.\r
+  //\r
+  MaxVarNameSize = 128 * sizeof (CHAR16);\r
+  VarName = AllocateZeroPool (MaxVarNameSize);\r
+  ASSERT (VarName != NULL);\r
+\r
+  //\r
+  // Initialize 0x1000 variable data size.\r
+  //\r
+  MaxDataSize = 0x1000;\r
+  Data = AllocateZeroPool (MaxDataSize);\r
+  ASSERT (Data != NULL);\r
+\r
+  Index = 0;\r
+  do {\r
+    VarNameSize = MaxVarNameSize;\r
+    Status = gRT->GetNextVariableName (&VarNameSize, VarName, &Guid);\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      VarName = ReallocatePool (MaxVarNameSize, VarNameSize, VarName);\r
+      ASSERT (VarName != NULL);\r
+      MaxVarNameSize = VarNameSize;\r
+      Status = gRT->GetNextVariableName (&VarNameSize, VarName, &Guid);\r
+    }\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      if (IsUserVariable (VarName, &Guid)) {\r
+        DataSize = MaxDataSize;\r
+        GetVariableStatus = gRT->GetVariable (VarName, &Guid, &Attributes, &DataSize, Data);\r
+        if (GetVariableStatus == EFI_BUFFER_TOO_SMALL) {\r
+          Data = ReallocatePool (MaxDataSize, DataSize, Data);\r
+          ASSERT (Data != NULL);\r
+          MaxDataSize = DataSize;\r
+          GetVariableStatus = gRT->GetVariable (VarName, &Guid, &Attributes, &DataSize, Data);\r
+        }\r
+        ASSERT_EFI_ERROR (GetVariableStatus);\r
+\r
+        if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
+          UserVariableNode = FindUserVariableNodeByGuid (&Guid);\r
+          ASSERT (UserVariableNode != NULL);\r
+\r
+          //\r
+          // Different variables that have same variable GUID share same user variable node.\r
+          //\r
+          UserVariableNameNode = AllocateZeroPool (sizeof (*UserVariableNameNode));\r
+          ASSERT (UserVariableNameNode != NULL);\r
+          UserVariableNameNode->Signature = USER_VARIABLE_NAME_NODE_SIGNATURE;\r
+          UserVariableNameNode->Name = AllocateCopyPool (VarNameSize, VarName);\r
+          UserVariableNameNode->Attributes = Attributes;\r
+          UserVariableNameNode->DataSize = DataSize;\r
+          UserVariableNameNode->Index = Index;\r
+          UserVariableNameNode->QuestionId = (EFI_QUESTION_ID) (USER_VARIABLE_QUESTION_ID + Index);\r
+          //\r
+          // 2 space * sizeof (CHAR16) + StrSize.\r
+          //\r
+          StringSize = 2 * sizeof (CHAR16) + StrSize (UserVariableNameNode->Name);\r
+          UserVariableNameNode->PromptString = AllocatePool (StringSize);\r
+          ASSERT (UserVariableNameNode->PromptString != NULL);\r
+          UnicodeSPrint (UserVariableNameNode->PromptString, StringSize, L"  %s", UserVariableNameNode->Name);\r
+          //\r
+          // (33 chars of "Attribtues = 0x and DataSize = 0x" + 1 terminator + (sizeof (UINT32) + sizeof (UINTN)) * 2) * sizeof (CHAR16).\r
+          //\r
+          StringSize = (33 + 1 + (sizeof (UINT32) + sizeof (UINTN)) * 2) * sizeof (CHAR16);\r
+          UserVariableNameNode->HelpString = AllocatePool (StringSize);\r
+          ASSERT (UserVariableNameNode->HelpString != NULL);\r
+          UnicodeSPrint (UserVariableNameNode->HelpString, StringSize, L"Attribtues = 0x%08x and DataSize = 0x%x", UserVariableNameNode->Attributes, UserVariableNameNode->DataSize);\r
+          UserVariableNameNode->Deleted = FALSE;\r
+          InsertTailList (&UserVariableNode->NameLink, &UserVariableNameNode->Link);\r
+          Index++;\r
+        }\r
+      }\r
+    }\r
+  } while (Status != EFI_NOT_FOUND);\r
+\r
+  mUserVariableCount = Index;\r
+  ASSERT (mUserVariableCount <= MAX_USER_VARIABLE_COUNT);\r
+  DEBUG ((EFI_D_INFO, "PlatformVarCleanup - User variable count: 0x%04x\n", mUserVariableCount));\r
+\r
+  FreePool (VarName);\r
+  FreePool (Data);\r
+}\r
+\r
+/**\r
+  Destroy user variable nodes.\r
+\r
+**/\r
+VOID\r
+DestroyUserVariableNode (\r
+  VOID\r
+  )\r
+{\r
+  USER_VARIABLE_NODE        *UserVariableNode;\r
+  LIST_ENTRY                *Link;\r
+  USER_VARIABLE_NAME_NODE   *UserVariableNameNode;\r
+  LIST_ENTRY                *NameLink;\r
+\r
+  while (mUserVariableList.ForwardLink != &mUserVariableList) {\r
+    Link = mUserVariableList.ForwardLink;\r
+    UserVariableNode = USER_VARIABLE_FROM_LINK (Link);\r
+\r
+    RemoveEntryList (&UserVariableNode->Link);\r
+\r
+    while (UserVariableNode->NameLink.ForwardLink != &UserVariableNode->NameLink) {\r
+      NameLink = UserVariableNode->NameLink.ForwardLink;\r
+      UserVariableNameNode = USER_VARIABLE_NAME_FROM_LINK (NameLink);\r
+\r
+      RemoveEntryList (&UserVariableNameNode->Link);\r
+\r
+      FreePool (UserVariableNameNode->Name);\r
+      FreePool (UserVariableNameNode->PromptString);\r
+      FreePool (UserVariableNameNode->HelpString);\r
+      FreePool (UserVariableNameNode);\r
+    }\r
+\r
+    FreePool (UserVariableNode->PromptString);\r
+    FreePool (UserVariableNode);\r
+  }\r
+}\r
+\r
+/**\r
+  Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2\r
+  descriptor with the input data. NO authentication is required in this function.\r
+\r
+  @param[in, out] DataSize          On input, the size of Data buffer in bytes.\r
+                                    On output, the size of data returned in Data\r
+                                    buffer in bytes.\r
+  @param[in, out] Data              On input, Pointer to data buffer to be wrapped or\r
+                                    pointer to NULL to wrap an empty payload.\r
+                                    On output, Pointer to the new payload date buffer allocated from pool,\r
+                                    it's caller's responsibility to free the memory after using it.\r
+\r
+  @retval EFI_SUCCESS               Create time based payload successfully.\r
+  @retval EFI_OUT_OF_RESOURCES      There are not enough memory resourses to create time based payload.\r
+  @retval EFI_INVALID_PARAMETER     The parameter is invalid.\r
+  @retval Others                    Unexpected error happens.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateTimeBasedPayload (\r
+  IN OUT UINTN      *DataSize,\r
+  IN OUT UINT8      **Data\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINT8                             *NewData;\r
+  UINT8                             *Payload;\r
+  UINTN                             PayloadSize;\r
+  EFI_VARIABLE_AUTHENTICATION_2     *DescriptorData;\r
+  UINTN                             DescriptorSize;\r
+  EFI_TIME                          Time;\r
+\r
+  if (Data == NULL || DataSize == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // At user physical presence, the variable does not need to be signed but the\r
+  // parameters to the SetVariable() call still need to be prepared as authenticated\r
+  // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate\r
+  // data in it.\r
+  //\r
+  Payload     = *Data;\r
+  PayloadSize = *DataSize;\r
+\r
+  DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);\r
+  NewData = (UINT8 *) AllocateZeroPool (DescriptorSize + PayloadSize);\r
+  if (NewData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if ((Payload != NULL) && (PayloadSize != 0)) {\r
+    CopyMem (NewData + DescriptorSize, Payload, PayloadSize);\r
+  }\r
+\r
+  DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData);\r
+\r
+  ZeroMem (&Time, sizeof (EFI_TIME));\r
+  Status = gRT->GetTime (&Time, NULL);\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (NewData);\r
+    return Status;\r
+  }\r
+  Time.Pad1       = 0;\r
+  Time.Nanosecond = 0;\r
+  Time.TimeZone   = 0;\r
+  Time.Daylight   = 0;\r
+  Time.Pad2       = 0;\r
+  CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME));\r
+\r
+  DescriptorData->AuthInfo.Hdr.dwLength         = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);\r
+  DescriptorData->AuthInfo.Hdr.wRevision        = 0x0200;\r
+  DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;\r
+  CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid);\r
+\r
+  if (Payload != NULL) {\r
+    FreePool (Payload);\r
+  }\r
+\r
+  *DataSize = DescriptorSize + PayloadSize;\r
+  *Data     = NewData;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create a counter based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION\r
+  descriptor with the input data. NO authentication is required in this function.\r
+\r
+  @param[in, out] DataSize          On input, the size of Data buffer in bytes.\r
+                                    On output, the size of data returned in Data\r
+                                    buffer in bytes.\r
+  @param[in, out] Data              On input, Pointer to data buffer to be wrapped or\r
+                                    pointer to NULL to wrap an empty payload.\r
+                                    On output, Pointer to the new payload date buffer allocated from pool,\r
+                                    it's caller's responsibility to free the memory after using it.\r
+\r
+  @retval EFI_SUCCESS               Create counter based payload successfully.\r
+  @retval EFI_OUT_OF_RESOURCES      There are not enough memory resourses to create time based payload.\r
+  @retval EFI_INVALID_PARAMETER     The parameter is invalid.\r
+  @retval Others                    Unexpected error happens.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateCounterBasedPayload (\r
+  IN OUT UINTN      *DataSize,\r
+  IN OUT UINT8      **Data\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINT8                             *NewData;\r
+  UINT8                             *Payload;\r
+  UINTN                             PayloadSize;\r
+  EFI_VARIABLE_AUTHENTICATION       *DescriptorData;\r
+  UINTN                             DescriptorSize;\r
+  UINT64                            MonotonicCount;\r
+\r
+  if (Data == NULL || DataSize == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // At user physical presence, the variable does not need to be signed but the\r
+  // parameters to the SetVariable() call still need to be prepared as authenticated\r
+  // variable. So we create EFI_VARIABLE_AUTHENTICATED descriptor without certificate\r
+  // data in it.\r
+  //\r
+  Payload     = *Data;\r
+  PayloadSize = *DataSize;\r
+\r
+  DescriptorSize = (OFFSET_OF (EFI_VARIABLE_AUTHENTICATION, AuthInfo)) + \\r
+                   (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) + \\r
+                   sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256);\r
+  NewData = (UINT8 *) AllocateZeroPool (DescriptorSize + PayloadSize);\r
+  if (NewData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if ((Payload != NULL) && (PayloadSize != 0)) {\r
+    CopyMem (NewData + DescriptorSize, Payload, PayloadSize);\r
+  }\r
+\r
+  DescriptorData = (EFI_VARIABLE_AUTHENTICATION *) (NewData);\r
+\r
+  Status = gBS->GetNextMonotonicCount (&MonotonicCount);\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (NewData);\r
+    return Status;\r
+  }\r
+  DescriptorData->MonotonicCount = MonotonicCount;\r
+\r
+  DescriptorData->AuthInfo.Hdr.dwLength         = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData) + sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256);\r
+  DescriptorData->AuthInfo.Hdr.wRevision        = 0x0200;\r
+  DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;\r
+  CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid);\r
+\r
+  if (Payload != NULL) {\r
+    FreePool (Payload);\r
+  }\r
+\r
+  *DataSize = DescriptorSize + PayloadSize;\r
+  *Data     = NewData;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Delete user variable.\r
+\r
+  @param[in] DeleteAll              Delete all user variables.\r
+  @param[in] VariableCleanupData    Pointer to variable cleanup data.\r
+\r
+**/\r
+VOID\r
+DeleteUserVariable (\r
+  IN BOOLEAN                DeleteAll,\r
+  IN VARIABLE_CLEANUP_DATA  *VariableCleanupData OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  USER_VARIABLE_NODE        *UserVariableNode;\r
+  LIST_ENTRY                *Link;\r
+  USER_VARIABLE_NAME_NODE   *UserVariableNameNode;\r
+  LIST_ENTRY                *NameLink;\r
+  UINTN                     DataSize;\r
+  UINT8                     *Data;\r
+\r
+  for (Link = mUserVariableList.ForwardLink\r
+       ;Link != &mUserVariableList\r
+       ;Link = Link->ForwardLink) {\r
+    UserVariableNode = USER_VARIABLE_FROM_LINK (Link);\r
+\r
+    for (NameLink = UserVariableNode->NameLink.ForwardLink\r
+        ;NameLink != &UserVariableNode->NameLink\r
+        ;NameLink = NameLink->ForwardLink) {\r
+      UserVariableNameNode = USER_VARIABLE_NAME_FROM_LINK (NameLink);\r
+\r
+      if (!UserVariableNameNode->Deleted && (DeleteAll || ((VariableCleanupData != NULL) && (VariableCleanupData->UserVariable[UserVariableNameNode->Index] == TRUE)))) {\r
+        DEBUG ((EFI_D_INFO, "PlatformVarCleanup - Delete variable: %g:%s\n", &UserVariableNode->Guid, UserVariableNameNode->Name));\r
+        if ((UserVariableNameNode->Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+          DataSize = 0;\r
+          Data = NULL;\r
+          Status = CreateTimeBasedPayload (&DataSize, &Data);\r
+          if (!EFI_ERROR (Status)) {\r
+            Status = gRT->SetVariable (UserVariableNameNode->Name, &UserVariableNode->Guid, UserVariableNameNode->Attributes, DataSize, Data);\r
+            FreePool (Data);\r
+          }\r
+        } else if ((UserVariableNameNode->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+          DataSize = 0;\r
+          Data = NULL;\r
+          Status = CreateCounterBasedPayload (&DataSize, &Data);\r
+          if (!EFI_ERROR (Status)) {\r
+            Status = gRT->SetVariable (UserVariableNameNode->Name, &UserVariableNode->Guid, UserVariableNameNode->Attributes, DataSize, Data);\r
+            FreePool (Data);\r
+          }\r
+        } else {\r
+          Status = gRT->SetVariable (UserVariableNameNode->Name, &UserVariableNode->Guid, 0, 0, NULL);\r
+        }\r
+        if (!EFI_ERROR (Status)) {\r
+          UserVariableNameNode->Deleted = TRUE;\r
+        } else {\r
+          DEBUG ((EFI_D_INFO, "PlatformVarCleanup - Delete variable fail: %g:%s\n", &UserVariableNode->Guid, UserVariableNameNode->Name));\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+  @param[in]  This          Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Request       A null-terminated Unicode string in <ConfigRequest> format.\r
+  @param[out] Progress      On return, points to a character in the Request string.\r
+                            Points to the string's null terminator if request was successful.\r
+                            Points to the most recent '&' before the first failing name/value\r
+                            pair (or the beginning of the string if the failure is in the\r
+                            first name/value pair) if the request was not successful.\r
+  @param[out] Results       A null-terminated Unicode string in <ConfigAltResp> format which\r
+                            has all values filled in for the names in the Request string.\r
+                            String to be allocated by the called function.\r
+\r
+  @retval EFI_SUCCESS               The Results is filled with the requested values.\r
+  @retval EFI_OUT_OF_RESOURCES      Not enough memory to store the results.\r
+  @retval EFI_INVALID_PARAMETER     Request is illegal syntax, or unknown name.\r
+  @retval EFI_NOT_FOUND             Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VariableCleanupHiiExtractConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,\r
+  IN  CONST EFI_STRING                          Request,\r
+  OUT EFI_STRING                                *Progress,\r
+  OUT EFI_STRING                                *Results\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  VARIABLE_CLEANUP_HII_PRIVATE_DATA *Private;\r
+  UINTN                             BufferSize;\r
+  EFI_STRING                        ConfigRequestHdr;\r
+  EFI_STRING                        ConfigRequest;\r
+  BOOLEAN                           AllocatedRequest;\r
+  UINTN                             Size;\r
+\r
+  if (Progress == NULL || Results == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Progress = Request;\r
+  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mVariableCleanupHiiGuid, mVarStoreName)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  ConfigRequestHdr = NULL;\r
+  ConfigRequest    = NULL;\r
+  AllocatedRequest = FALSE;\r
+  Size             = 0;\r
+\r
+  Private = VARIABLE_CLEANUP_HII_PRIVATE_FROM_THIS (This);\r
+  //\r
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig().\r
+  //\r
+  BufferSize = sizeof (VARIABLE_CLEANUP_DATA);\r
+  ConfigRequest = Request;\r
+  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
+    //\r
+    // Request has no request element, construct full request string.\r
+    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.\r
+    //\r
+    ConfigRequestHdr = HiiConstructConfigHdr (&mVariableCleanupHiiGuid, mVarStoreName, Private->HiiHandle);\r
+    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
+    ConfigRequest = AllocateZeroPool (Size);\r
+    ASSERT (ConfigRequest != NULL);\r
+    AllocatedRequest = TRUE;\r
+    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
+    FreePool (ConfigRequestHdr);\r
+  }\r
+\r
+  Status = Private->ConfigRouting->BlockToConfig (\r
+                                     Private->ConfigRouting,\r
+                                     ConfigRequest,\r
+                                     (UINT8 *) &Private->VariableCleanupData,\r
+                                     BufferSize,\r
+                                     Results,\r
+                                     Progress\r
+                                     );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Free the allocated config request string.\r
+  //\r
+  if (AllocatedRequest) {\r
+    FreePool (ConfigRequest);\r
+    ConfigRequest = NULL;\r
+  }\r
+  //\r
+  // Set Progress string to the original request string or the string's null terminator.\r
+  //\r
+  if (Request == NULL) {\r
+    *Progress = NULL;\r
+  } else if (StrStr (Request, L"OFFSET") == NULL) {\r
+    *Progress = Request + StrLen (Request);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Update user variable form.\r
+\r
+  @param[in] Private    Points to the VARIABLE_CLEANUP_HII_PRIVATE_DATA.\r
+\r
+**/\r
+VOID\r
+UpdateUserVariableForm (\r
+  IN VARIABLE_CLEANUP_HII_PRIVATE_DATA  *Private\r
+  )\r
+{\r
+  EFI_STRING_ID             PromptStringToken;\r
+  EFI_STRING_ID             HelpStringToken;\r
+  VOID                      *StartOpCodeHandle;\r
+  VOID                      *EndOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL        *StartLabel;\r
+  EFI_IFR_GUID_LABEL        *EndLabel;\r
+  USER_VARIABLE_NODE        *UserVariableNode;\r
+  LIST_ENTRY                *Link;\r
+  USER_VARIABLE_NAME_NODE   *UserVariableNameNode;\r
+  LIST_ENTRY                *NameLink;\r
+  BOOLEAN                   Created;\r
+\r
+  //\r
+  // Init OpCode Handle.\r
+  //\r
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  ASSERT (StartOpCodeHandle != NULL);\r
+\r
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  ASSERT (EndOpCodeHandle != NULL);\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode as the start opcode.\r
+  //\r
+  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+  StartLabel->Number = LABEL_START;\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode as the end opcode.\r
+  //\r
+  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+  EndLabel->Number = LABEL_END;\r
+\r
+  HiiUpdateForm (\r
+    Private->HiiHandle,\r
+    &mVariableCleanupHiiGuid,\r
+    FORM_ID_VARIABLE_CLEANUP,\r
+    StartOpCodeHandle, // LABEL_START\r
+    EndOpCodeHandle    // LABEL_END\r
+    );\r
+\r
+  for (Link = mUserVariableList.ForwardLink\r
+      ;Link != &mUserVariableList\r
+      ;Link = Link->ForwardLink) {\r
+    UserVariableNode = USER_VARIABLE_FROM_LINK (Link);\r
+\r
+    //\r
+    // Create checkbox opcode for variables in the same variable GUID space.\r
+    //\r
+    Created = FALSE;\r
+    for (NameLink = UserVariableNode->NameLink.ForwardLink\r
+        ;NameLink != &UserVariableNode->NameLink\r
+        ;NameLink = NameLink->ForwardLink) {\r
+      UserVariableNameNode = USER_VARIABLE_NAME_FROM_LINK (NameLink);\r
+\r
+      if (!UserVariableNameNode->Deleted) {\r
+        if (!Created) {\r
+          //\r
+          // Create subtitle opcode for variable GUID.\r
+          //\r
+          PromptStringToken = HiiSetString (Private->HiiHandle, 0, UserVariableNode->PromptString, NULL);\r
+          HiiCreateSubTitleOpCode (StartOpCodeHandle, PromptStringToken, 0, 0, 0);\r
+          Created = TRUE;\r
+        }\r
+\r
+        //\r
+        // Only create opcode for the non-deleted variables.\r
+        //\r
+        PromptStringToken = HiiSetString (Private->HiiHandle, 0, UserVariableNameNode->PromptString, NULL);\r
+        HelpStringToken = HiiSetString (Private->HiiHandle, 0, UserVariableNameNode->HelpString, NULL);\r
+        HiiCreateCheckBoxOpCode (\r
+          StartOpCodeHandle,\r
+          UserVariableNameNode->QuestionId,\r
+          VARIABLE_CLEANUP_VARSTORE_ID,\r
+          (UINT16) (USER_VARIABLE_VAR_OFFSET + UserVariableNameNode->Index),\r
+          PromptStringToken,\r
+          HelpStringToken,\r
+          EFI_IFR_FLAG_CALLBACK,\r
+          Private->VariableCleanupData.UserVariable[UserVariableNameNode->Index],\r
+          NULL\r
+          );\r
+      }\r
+    }\r
+  }\r
+\r
+  HiiCreateSubTitleOpCode (\r
+    StartOpCodeHandle,\r
+    STRING_TOKEN (STR_NULL_STRING),\r
+    0,\r
+    0,\r
+    0\r
+    );\r
+\r
+  //\r
+  // Create the "Apply changes" and "Discard changes" tags.\r
+  //\r
+  HiiCreateActionOpCode (\r
+    StartOpCodeHandle,\r
+    SAVE_AND_EXIT_QUESTION_ID,\r
+    STRING_TOKEN (STR_SAVE_AND_EXIT),\r
+    STRING_TOKEN (STR_NULL_STRING),\r
+    EFI_IFR_FLAG_CALLBACK,\r
+    0\r
+    );\r
+  HiiCreateActionOpCode (\r
+    StartOpCodeHandle,\r
+    NO_SAVE_AND_EXIT_QUESTION_ID,\r
+    STRING_TOKEN (STR_NO_SAVE_AND_EXIT),\r
+    STRING_TOKEN (STR_NULL_STRING),\r
+    EFI_IFR_FLAG_CALLBACK,\r
+    0\r
+    );\r
+\r
+  HiiUpdateForm (\r
+    Private->HiiHandle,\r
+    &mVariableCleanupHiiGuid,\r
+    FORM_ID_VARIABLE_CLEANUP,\r
+    StartOpCodeHandle, // LABEL_START\r
+    EndOpCodeHandle    // LABEL_END\r
+    );\r
+\r
+  HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+  HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+}\r
+\r
+/**\r
+  This function applies changes in a driver's configuration.\r
+  Input is a Configuration, which has the routing data for this\r
+  driver followed by name / value configuration pairs. The driver\r
+  must apply those pairs to its configurable storage. If the\r
+  driver's configuration is stored in a linear block of data\r
+  and the driver's name / value pairs are in <BlockConfig>\r
+  format, it may use the ConfigToBlock helper function (above) to\r
+  simplify the job. Currently not implemented.\r
+\r
+  @param[in]  This                  Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Configuration         A null-terminated Unicode string in\r
+                                    <ConfigString> format.\r
+  @param[out] Progress              A pointer to a string filled in with the\r
+                                    offset of the most recent '&' before the\r
+                                    first failing name / value pair (or the\r
+                                    beginn ing of the string if the failure\r
+                                    is in the first name / value pair) or\r
+                                    the terminating NULL if all was\r
+                                    successful.\r
+\r
+  @retval EFI_SUCCESS               The results have been distributed or are\r
+                                    awaiting distribution.\r
+  @retval EFI_OUT_OF_RESOURCES      Not enough memory to store the\r
+                                    parts of the results that must be\r
+                                    stored awaiting possible future\r
+                                    protocols.\r
+  @retval EFI_INVALID_PARAMETERS    Passing in a NULL for the\r
+                                    Results parameter would result\r
+                                    in this type of error.\r
+  @retval EFI_NOT_FOUND             Target for the specified routing data\r
+                                    was not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VariableCleanupHiiRouteConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,\r
+  IN  CONST EFI_STRING                          Configuration,\r
+  OUT EFI_STRING                                *Progress\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  VARIABLE_CLEANUP_HII_PRIVATE_DATA *Private;\r
+  UINTN                             BufferSize;\r
+\r
+  if (Progress == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  *Progress = Configuration;\r
+\r
+  if (Configuration == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check routing data in <ConfigHdr>.\r
+  // Note: there is no name for Name/Value storage, only GUID will be checked.\r
+  //\r
+  if (!HiiIsConfigHdrMatch (Configuration, &mVariableCleanupHiiGuid, mVarStoreName)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Private = VARIABLE_CLEANUP_HII_PRIVATE_FROM_THIS (This);\r
+  //\r
+  // Get Buffer Storage data.\r
+  //\r
+  BufferSize = sizeof (VARIABLE_CLEANUP_DATA);\r
+  //\r
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock().\r
+  //\r
+  Status = Private->ConfigRouting->ConfigToBlock (\r
+                            Private->ConfigRouting,\r
+                            Configuration,\r
+                            (UINT8 *) &Private->VariableCleanupData,\r
+                            &BufferSize,\r
+                            Progress\r
+                            );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  DeleteUserVariable (FALSE, &Private->VariableCleanupData);\r
+  //\r
+  // For "F10" hotkey to refresh the form.\r
+  //\r
+//  UpdateUserVariableForm (Private);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function is called to provide results data to the driver.\r
+  This data consists of a unique key that is used to identify\r
+  which data is either being passed back or being asked for.\r
+\r
+  @param[in]  This                  Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Action                Specifies the type of action taken by the browser.\r
+  @param[in]  QuestionId            A unique value which is sent to the original\r
+                                    exporting driver so that it can identify the type\r
+                                    of data to expect. The format of the data tends to\r
+                                    vary based on the opcode that generated the callback.\r
+  @param[in]  Type                  The type of value for the question.\r
+  @param[in]  Value                 A pointer to the data being sent to the original\r
+                                    exporting driver.\r
+  @param[out] ActionRequest         On return, points to the action requested by the\r
+                                    callback function.\r
+\r
+  @retval EFI_SUCCESS               The callback successfully handled the action.\r
+  @retval EFI_OUT_OF_RESOURCES      Not enough storage is available to hold the\r
+                                    variable and its data.\r
+  @retval EFI_DEVICE_ERROR          The variable could not be saved.\r
+  @retval EFI_UNSUPPORTED           The specified Action is not supported by the\r
+                                    callback.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VariableCleanupHiiCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  EFI_BROWSER_ACTION                     Action,\r
+  IN  EFI_QUESTION_ID                        QuestionId,\r
+  IN  UINT8                                  Type,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
+  )\r
+{\r
+  VARIABLE_CLEANUP_HII_PRIVATE_DATA *Private;\r
+  VARIABLE_CLEANUP_DATA             *VariableCleanupData;\r
+\r
+  Private = VARIABLE_CLEANUP_HII_PRIVATE_FROM_THIS (This);\r
+\r
+  if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {\r
+    //\r
+    // All other action return unsupported.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Retrive uncommitted data from Form Browser.\r
+  //\r
+  VariableCleanupData = &Private->VariableCleanupData;\r
+  HiiGetBrowserData (&mVariableCleanupHiiGuid, mVarStoreName, sizeof (VARIABLE_CLEANUP_DATA), (UINT8 *) VariableCleanupData);\r
+  if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+    if (Value == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+    if ((Value == NULL) || (ActionRequest == NULL)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    if ((QuestionId >= USER_VARIABLE_QUESTION_ID) && (QuestionId < USER_VARIABLE_QUESTION_ID + MAX_USER_VARIABLE_COUNT)) {\r
+      if (Value->b){\r
+        //\r
+        // Means one user variable checkbox is marked to delete but not press F10 or "Commit Changes and Exit" menu.\r
+        //\r
+        mMarkedUserVariableCount++;\r
+        ASSERT (mMarkedUserVariableCount <= mUserVariableCount);\r
+        if (mMarkedUserVariableCount == mUserVariableCount) {\r
+          //\r
+          // All user variables have been marked, then also mark the SelectAll checkbox.\r
+          //\r
+          VariableCleanupData->SelectAll = TRUE;\r
+        }\r
+      } else {\r
+        //\r
+        // Means one user variable checkbox is unmarked.\r
+        //\r
+        mMarkedUserVariableCount--;\r
+        //\r
+        // Also unmark the SelectAll checkbox.\r
+        //\r
+        VariableCleanupData->SelectAll = FALSE;\r
+      }\r
+    } else {\r
+      switch (QuestionId) {\r
+        case SELECT_ALL_QUESTION_ID:\r
+         if (Value->b){\r
+            //\r
+            // Means the SelectAll checkbox is marked to delete all user variables but not press F10 or "Commit Changes and Exit" menu.\r
+            //\r
+            SetMem (VariableCleanupData->UserVariable, sizeof (VariableCleanupData->UserVariable), TRUE);\r
+            mMarkedUserVariableCount = mUserVariableCount;\r
+          } else {\r
+            //\r
+            // Means the SelectAll checkbox is unmarked.\r
+            //\r
+            SetMem (VariableCleanupData->UserVariable, sizeof (VariableCleanupData->UserVariable), FALSE);\r
+            mMarkedUserVariableCount = 0;\r
+          }\r
+          break;\r
+        case SAVE_AND_EXIT_QUESTION_ID:\r
+          DeleteUserVariable (FALSE, VariableCleanupData);\r
+          *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
+          break;\r
+\r
+        case NO_SAVE_AND_EXIT_QUESTION_ID:\r
+          //\r
+          // Restore local maintain data.\r
+          //\r
+          *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
+          break;\r
+\r
+        default:\r
+          break;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Pass changed uncommitted data back to Form Browser.\r
+  //\r
+  HiiSetBrowserData (&mVariableCleanupHiiGuid, mVarStoreName, sizeof (VARIABLE_CLEANUP_DATA), (UINT8 *) VariableCleanupData, NULL);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Platform variable cleanup.\r
+\r
+  @param[in] Flag                   Variable error flag.\r
+  @param[in] Type                   Variable cleanup type.\r
+                                    If it is VarCleanupManually, the interface must be called after console connected.\r
+\r
+  @retval EFI_SUCCESS               No error or error processed.\r
+  @retval EFI_UNSUPPORTED           The specified Flag or Type is not supported.\r
+                                    For example, system error may be not supported to process and Platform should have mechanism to reset system to manufacture mode.\r
+                                    Another, if system and user variables are wanted to be distinguished to process, the interface must be called after EndOfDxe.\r
+  @retval EFI_OUT_OF_RESOURCES      Not enough resource to process the error.\r
+  @retval EFI_INVALID_PARAMETER     The specified Flag or Type is an invalid value.\r
+  @retval Others                    Other failure occurs.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatformVarCleanup (\r
+  IN VAR_ERROR_FLAG     Flag,\r
+  IN VAR_CLEANUP_TYPE   Type\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_FORM_BROWSER2_PROTOCOL            *FormBrowser2;\r
+  VARIABLE_CLEANUP_HII_PRIVATE_DATA     *Private;\r
+\r
+  if (!mEndOfDxe) {\r
+    //\r
+    // This implementation must be called after EndOfDxe.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if ((Type >= VarCleanupMax) || ((Flag & ((VAR_ERROR_FLAG) (VAR_ERROR_FLAG_SYSTEM_ERROR & VAR_ERROR_FLAG_USER_ERROR))) == 0)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Flag == VAR_ERROR_FLAG_NO_ERROR) {\r
+    //\r
+    // Just return success if no error.\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if ((Flag & (~((VAR_ERROR_FLAG) VAR_ERROR_FLAG_SYSTEM_ERROR))) == 0) {\r
+    //\r
+    // This sample does not support system variables cleanup.\r
+    //\r
+    DEBUG ((EFI_D_ERROR, "NOTICE - VAR_ERROR_FLAG_SYSTEM_ERROR\n"));\r
+    DEBUG ((EFI_D_ERROR, "Platform should have mechanism to reset system to manufacture mode\n"));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Continue to process VAR_ERROR_FLAG_USER_ERROR.\r
+  //\r
+\r
+  //\r
+  // Create user variable nodes for the following processing.\r
+  //\r
+  CreateUserVariableNode ();\r
+\r
+  switch (Type) {\r
+    case VarCleanupAll:\r
+      DeleteUserVariable (TRUE, NULL);\r
+      //\r
+      // Destroyed the created user variable nodes\r
+      //\r
+      DestroyUserVariableNode ();\r
+      return EFI_SUCCESS;\r
+      break;\r
+\r
+    case VarCleanupManually:\r
+      //\r
+      // Locate FormBrowser2 protocol.\r
+      //\r
+      Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      Private = AllocateZeroPool (sizeof (VARIABLE_CLEANUP_HII_PRIVATE_DATA));\r
+      if (Private == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      Private->Signature = VARIABLE_CLEANUP_HII_PRIVATE_SIGNATURE;\r
+      Private->ConfigAccess.ExtractConfig = VariableCleanupHiiExtractConfig;\r
+      Private->ConfigAccess.RouteConfig   = VariableCleanupHiiRouteConfig;\r
+      Private->ConfigAccess.Callback      = VariableCleanupHiiCallback;\r
+\r
+      Status = gBS->LocateProtocol (\r
+                      &gEfiHiiConfigRoutingProtocolGuid,\r
+                      NULL,\r
+                      (VOID **) &Private->ConfigRouting\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+\r
+      //\r
+      // Install Device Path Protocol and Config Access protocol to driver handle.\r
+      //\r
+      Status = gBS->InstallMultipleProtocolInterfaces (\r
+                      &Private->DriverHandle,\r
+                      &gEfiDevicePathProtocolGuid,\r
+                      &mVarCleanupHiiVendorDevicePath,\r
+                      &gEfiHiiConfigAccessProtocolGuid,\r
+                      &Private->ConfigAccess,\r
+                      NULL\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+\r
+      //\r
+      // Publish our HII data.\r
+      //\r
+      Private->HiiHandle = HiiAddPackages (\r
+                             &mVariableCleanupHiiGuid,\r
+                             Private->DriverHandle,\r
+                             PlatformVarCleanupLibStrings,\r
+                             PlatVarCleanupBin,\r
+                             NULL\r
+                             );\r
+      if (Private->HiiHandle == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+\r
+      UpdateUserVariableForm (Private);\r
+\r
+      Status = FormBrowser2->SendForm (\r
+                               FormBrowser2,\r
+                               &Private->HiiHandle,\r
+                               1,\r
+                               NULL,\r
+                               0,\r
+                               NULL,\r
+                               NULL\r
+                               );\r
+      break;\r
+\r
+    default:\r
+      return EFI_UNSUPPORTED;\r
+      break;\r
+  }\r
+\r
+Done:\r
+  if (Private->DriverHandle != NULL) {\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
+           Private->DriverHandle,\r
+           &gEfiDevicePathProtocolGuid,\r
+           &mVarCleanupHiiVendorDevicePath,\r
+           &gEfiHiiConfigAccessProtocolGuid,\r
+           &Private->ConfigAccess,\r
+           NULL\r
+           );\r
+  }\r
+  if (Private->HiiHandle != NULL) {\r
+    HiiRemovePackages (Private->HiiHandle);\r
+  }\r
+\r
+  FreePool (Private);\r
+\r
+  //\r
+  // Destroyed the created user variable nodes\r
+  //\r
+  DestroyUserVariableNode ();\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Get last boot variable error flag.\r
+\r
+  @return   Last boot variable error flag.\r
+\r
+**/\r
+VAR_ERROR_FLAG\r
+EFIAPI\r
+GetLastBootVarErrorFlag (\r
+  )\r
+{\r
+  return mLastVarErrorFlag;\r
+}\r
+\r
+/**\r
+  Notification function of END_OF_DXE.\r
+\r
+  This is a notification function registered on END_OF_DXE event.\r
+\r
+  @param[in] Event      Event whose notification function is being invoked.\r
+  @param[in] Context    Pointer to the notification function's context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformVarCleanupEndOfDxeEvent (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  mEndOfDxe = TRUE;\r
+}\r
+\r
+/**\r
+  The constructor function caches the pointer to VarCheck protocol and last boot variable error flag.\r
+\r
+  The constructor function locates VarCheck protocol from protocol database.\r
+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
+\r
+  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
+  @param  SystemTable   A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatformVarCleanupLibConstructor (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  EFI_EVENT     Event;\r
+\r
+  mLastVarErrorFlag = InternalGetVarErrorFlag ();\r
+  DEBUG ((EFI_D_INFO, "mLastVarErrorFlag - 0x%02x\n", mLastVarErrorFlag));\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEdkiiVarCheckProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &mVarCheck\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event.\r
+  //\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  PlatformVarCleanupEndOfDxeEvent,\r
+                  NULL,\r
+                  &gEfiEndOfDxeEventGroupGuid,\r
+                  &Event\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.inf b/MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.inf
new file mode 100644 (file)
index 0000000..c56a175
--- /dev/null
@@ -0,0 +1,73 @@
+## @file\r
+#  Sample platform variable cleanup library instance.\r
+#\r
+#  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions\r
+#  of the BSD License which accompanies this distribution.  The\r
+#  full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                   = 0x00010005\r
+  BASE_NAME                     = PlatformVarCleanupLib\r
+  MODULE_UNI_FILE               = PlatformVarCleanupLib.uni\r
+  FILE_GUID                     = 9C9623EB-4EF3-44e0-A931-F3A340D1A0F9\r
+  MODULE_TYPE                   = DXE_DRIVER\r
+  VERSION_STRING                = 1.0\r
+  LIBRARY_CLASS                 = PlatformVarCleanupLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER\r
+  CONSTRUCTOR                   = PlatformVarCleanupLibConstructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES          = IA32 X64\r
+#\r
+\r
+[Sources.common]\r
+  PlatVarCleanupLib.c\r
+  PlatVarCleanup.h\r
+  PlatVarCleanupHii.h\r
+  PlatVarCleanup.vfr\r
+  VfrStrings.uni\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  UefiRuntimeServicesTableLib\r
+  UefiLib\r
+  BaseLib\r
+  DebugLib\r
+  BaseMemoryLib\r
+  PrintLib\r
+  MemoryAllocationLib\r
+  HiiLib\r
+\r
+[Guids]\r
+  gEfiIfrTianoGuid                  ## SOMETIMES_PRODUCES   ## GUID\r
+  gEdkiiVarErrorFlagGuid            ## CONSUMES             ## Variable:L"VarErrorFlag"\r
+  gEfiEndOfDxeEventGroupGuid        ## CONSUMES             ## Event\r
+  gEfiCertPkcs7Guid                 ## SOMETIMES_CONSUMES   ## GUID\r
+  gEfiCertTypeRsa2048Sha256Guid     ## SOMETIMES_CONSUMES   ## GUID\r
+\r
+[Protocols]\r
+  gEfiVariableArchProtocolGuid      ## CONSUMES\r
+  gEdkiiVarCheckProtocolGuid        ## CONSUMES\r
+  gEfiDevicePathProtocolGuid        ## SOMETIMES_PRODUCES\r
+  gEfiFormBrowser2ProtocolGuid      ## SOMETIMES_CONSUMES\r
+  gEfiHiiConfigAccessProtocolGuid   ## SOMETIMES_PRODUCES\r
+  gEfiHiiConfigRoutingProtocolGuid  ## SOMETIMES_CONSUMES\r
+\r
+[Depex]\r
+  gEdkiiVarCheckProtocolGuid AND\r
+  gEfiVariableArchProtocolGuid\r
+\r
diff --git a/MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.uni b/MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.uni
new file mode 100644 (file)
index 0000000..e4a0deb
Binary files /dev/null and b/MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.uni differ
diff --git a/MdeModulePkg/Library/PlatformVarCleanupLib/VfrStrings.uni b/MdeModulePkg/Library/PlatformVarCleanupLib/VfrStrings.uni
new file mode 100644 (file)
index 0000000..56f8e36
Binary files /dev/null and b/MdeModulePkg/Library/PlatformVarCleanupLib/VfrStrings.uni differ
index c0e9d32e04ab611272ca5334a72bab35afd0579b..5c1d29a68afe04e026db1218aa23e0ce04bedf99 100644 (file)
   #\r
   VarCheckLib|Include/Library/VarCheckLib.h\r
 \r
   #\r
   VarCheckLib|Include/Library/VarCheckLib.h\r
 \r
+  ## @libraryclass  Provides services to get variable error flag and do platform variable cleanup.\r
+  #\r
+  PlatformVarCleanupLib|Include/Library/PlatformVarCleanupLib.h\r
+\r
 [Guids]\r
   ## MdeModule package token space guid\r
   # Include/Guid/MdeModulePkgTokenSpace.h\r
 [Guids]\r
   ## MdeModule package token space guid\r
   # Include/Guid/MdeModulePkgTokenSpace.h\r
index 9bc8ed5936759ce53d6688ffe9fd32ef101086ce..3e04477318b94b9602c0a377ac0eb6119f46dbb2 100644 (file)
   MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf\r
   MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf\r
   MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf\r
   MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf\r
   MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf\r
   MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf\r
+  MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.inf\r
 \r
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf\r
   MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf\r
 \r
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf\r
   MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf\r