[edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell command

Michael Kubacki mikuback at linux.microsoft.com
Tue Oct 24 23:36:56 UTC 2023


On 10/24/2023 2:21 AM, Gao, Zhichao wrote:
> Hi Michael:
> 
> The patch looks good to me. Reviewed-by: Zhichao Gao <zhichao.gao at intel.com>
> 
> Agree with Liming, Michael do you consider to add the APP version inf like DP/HTTP/TFTP?
> 
Yes, that's a good suggestion. I will add it in a v2 update.

> Thanks,
> Zhichao
> 
>> -----Original Message-----
>> From: devel at edk2.groups.io <devel at edk2.groups.io> On Behalf Of
>> gaoliming via groups.io
>> Sent: Tuesday, October 24, 2023 1:17 PM
>> To: devel at edk2.groups.io; mikuback at linux.microsoft.com
>> Cc: Gao, Zhichao <zhichao.gao at intel.com>; Kinney, Michael D
>> <michael.d.kinney at intel.com>
>> Subject: 回复: [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic
>> shell command
>>
>> Michael:
>>    Will you provide standalone application for varpolicy like tftp?
>>
>> Thanks
>> Liming
>>> -----邮件原件-----
>>> 发件人: devel at edk2.groups.io <devel at edk2.groups.io> 代表 Michael
>>> Kubacki
>>> 发送时间: 2023年9月19日 22:33
>>> 收件人: devel at edk2.groups.io
>>> 抄送: Zhichao Gao <zhichao.gao at intel.com>; Michael D Kinney
>>> <michael.d.kinney at intel.com>
>>> 主题: [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell
>>> command
>>>
>>> From: Michael Kubacki <michael.kubacki at microsoft.com>
>>>
>>> Adds a new module (dynamic shell command) to ShellPkg that lists
>>> variable policy information for all UEFI variables on the system.
>>>
>>> Some other UEFI variable related functionality is also included to
>>> give a greater sense of platform UEFI variable state. This command
>>> is intended to help make variable policies more transparent and
>>> easier to understand and configure on a platform.
>>>
>>> Like all dynamic shell commands, a platform only needs to include
>>> `VariablePolicyDynamicCommand.inf` in their flash image to have
>>> the command registered in their UEFI shell.
>>>
>>> Include the following lines in platform DSC (in DXE components section):
>>>
>>> ```
>>>
>>>
>> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy
>>> DynamicCommand.inf {
>>>      <PcdsFixedAtBuild>
>>>        gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
>>>    }
>>> ```
>>>
>>> Include the following line in platform FDF:
>>>
>>> ```
>>> INF
>>>
>> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy
>>> DynamicCommand.inf
>>> ```
>>>
>>> Cc: Zhichao Gao <zhichao.gao at intel.com>
>>> Cc: Michael D Kinney <michael.d.kinney at intel.com>
>>> Signed-off-by: Michael Kubacki <michael.kubacki at microsoft.com>
>>> ---
>>>
>>>
>> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy
>>> DynamicCommand.c   | 1009 ++++++++++++++++++++
>>>
>>>
>> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy
>>> DynamicCommand.h   |   94 ++
>>>
>>>
>> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy
>>> DynamicCommand.inf |   56 ++
>>>
>>>
>> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy
>>> DynamicCommand.uni |   86 ++
>>>   ShellPkg/ShellPkg.dsc
>>> |    1 +
>>>   5 files changed, 1246 insertions(+)
>>>
>>> diff --git
>>>
>> a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.c
>>>
>> b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.c
>>> new file mode 100644
>>> index 000000000000..49993f635396
>>> --- /dev/null
>>> +++
>>>
>> b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.c
>>> @@ -0,0 +1,1009 @@
>>> +/** @file
>>> +  Main file for the "varpolicy" dynamic UEFI shell command.
>>> +
>>> +  This command can provide detailed UEFI variable policy configuration
>>> +  information in the UEFI shell.
>>> +
>>> +  Copyright (c) Microsoft Corporation.
>>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>>> +
>>> +**/
>>> +
>>> +#include "VariablePolicyDynamicCommand.h"
>>> +
>>> +#include <Library/BaseLib.h>
>>> +#include <Library/BaseMemoryLib.h>
>>> +#include <Library/DebugLib.h>
>>> +#include <Library/HiiLib.h>
>>> +#include <Library/MemoryAllocationLib.h>
>>> +#include <Library/PrintLib.h>
>>> +#include <Library/ShellLib.h>
>>> +#include <Library/UefiBootServicesTableLib.h>
>>> +#include <Library/UefiRuntimeServicesTableLib.h>
>>> +#include <Library/UefiHiiServicesLib.h>
>>> +
>>> +#include <Protocol/HiiPackageList.h>
>>> +#include <Protocol/ShellDynamicCommand.h>
>>> +#include <Protocol/VariablePolicy.h>
>>> +
>>> +#define VAR_POLICY_FLAG_STATS_STR    L"-s"
>>> +#define VAR_POLICY_FLAG_POLICY_STR   L"-p"
>>> +#define VAR_POLICY_FLAG_VERBOSE_STR  L"-v"
>>> +
>>> +#define VAR_POLICY_CMD_MIN_ATTR_STR_LEN  64
>>> +
>>> +EFI_HII_HANDLE  mVarPolicyShellCommandHiiHandle = NULL;
>>> +
>>> +STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {
>>> +  { VAR_POLICY_FLAG_POLICY_STR,  TypeFlag },
>>> +  { VAR_POLICY_FLAG_STATS_STR,   TypeFlag },
>>> +  { VAR_POLICY_FLAG_VERBOSE_STR, TypeFlag },
>>> +  { NULL,                        TypeMax  }
>>> +};
>>> +
>>> +STATIC CONST VAR_POLICY_CMD_VAR_NAMESPACE  mVarNamespaces[]
>>> = {
>>> +  {
>>> +    VariableVendorCapsule,
>>> +    &gEfiCapsuleVendorGuid,
>>> +    L"Capsule"
>>> +  },
>>> +  {
>>> +    VariableVendorCapsuleReport,
>>> +    &gEfiCapsuleReportGuid,
>>> +    L"Capsule Reporting"
>>> +  },
>>> +  {
>>> +    VariableVendorGlobal,
>>> +    &gEfiGlobalVariableGuid,
>>> +    L"UEFI Global"
>>> +  },
>>> +  {
>>> +    VariableVendorMorControl,
>>> +    &gEfiMemoryOverwriteRequestControlLockGuid,
>>> +    L"Memory Overwrite Request (MOR) Control Lock"
>>> +  }
>>> +};
>>> +
>>> +/**
>>> +  Returns UEFI variable attribute information in a string.
>>> +
>>> +  AttributesStrSize must at least be
>>> VAR_POLICY_CMD_MIN_ATTR_STR_LEN in length
>>> +  or EFI_INVALID_PARAMETER will be returned.
>>> +
>>> +  @param[in]  Attributes             The UEFI variable attributes.
>>> +  @param[in]  AttributesStrSize      The size, in bytes, of
>> AttributesStr.
>>> +  @param[out] AttributesStr          The Unicode string for the given
>>> attributes.
>>> +
>>> +  @retval EFI_SUCCESS           The attributes were converted to a
>>> string successfully.
>>> +  @retval EFI_INVALID_PARAMETER The AttributesStr pointer is NULL.
>>> +
>>> +**/
>>> +EFI_STATUS
>>> +GetAttributesString (
>>> +  IN  UINT32  Attributes,
>>> +  IN  UINTN   AttributesStrSize,
>>> +  OUT CHAR16  *AttributesStr
>>> +  )
>>> +{
>>> +  if ((AttributesStr == NULL) || (AttributesStrSize <
>>> VAR_POLICY_CMD_MIN_ATTR_STR_LEN)) {
>>> +    return EFI_INVALID_PARAMETER;
>>> +  }
>>> +
>>> +  AttributesStr[0] = L'0';
>>> +  AttributesStr[1] = L'x';
>>> +  AttributesStr[2] = L'\0';
>>> +
>>> +  UnicodeValueToStringS (AttributesStr + 2, AttributesStrSize - 2,
>>> (RADIX_HEX), (INT64)Attributes, 30);
>>> +
>>> +  if (Attributes == 0) {
>>> +    StrCatS (AttributesStr, AttributesStrSize, L" No Attributes");
>>> +  } else {
>>> +    if ((Attributes & EFI_VARIABLE_NON_VOLATILE) ==
>>> EFI_VARIABLE_NON_VOLATILE) {
>>> +      StrCatS (AttributesStr, AttributesStrSize, L" NV");
>>> +      Attributes ^= EFI_VARIABLE_NON_VOLATILE;
>>> +    }
>>> +
>>> +    if ((Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) ==
>>> EFI_VARIABLE_BOOTSERVICE_ACCESS) {
>>> +      StrCatS (AttributesStr, AttributesStrSize, L" BS");
>>> +      Attributes ^= EFI_VARIABLE_BOOTSERVICE_ACCESS;
>>> +    }
>>> +
>>> +    if ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) ==
>>> EFI_VARIABLE_RUNTIME_ACCESS) {
>>> +      StrCatS (AttributesStr, AttributesStrSize, L" RT");
>>> +      Attributes ^= EFI_VARIABLE_RUNTIME_ACCESS;
>>> +    }
>>> +
>>> +    if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) ==
>>> EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
>>> +      StrCatS (AttributesStr, AttributesStrSize, L" HW-Error");
>>> +      Attributes ^= EFI_VARIABLE_HARDWARE_ERROR_RECORD;
>>> +    }
>>> +
>>> +    if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) ==
>>> EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) {
>>> +      StrCatS (AttributesStr, AttributesStrSize, L" Auth-WA");
>>> +      Attributes ^= EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
>>> +    }
>>> +
>>> +    if ((Attributes &
>>> EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) ==
>>> EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
>>> +      StrCatS (AttributesStr, AttributesStrSize, L" Auth-TIME-WA");
>>> +      Attributes ^=
>>> EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
>>> +    }
>>> +
>>> +    if ((Attributes & EFI_VARIABLE_APPEND_WRITE) ==
>>> EFI_VARIABLE_APPEND_WRITE) {
>>> +      StrCatS (AttributesStr, AttributesStrSize, L" APPEND-W");
>>> +      Attributes ^= EFI_VARIABLE_APPEND_WRITE;
>>> +    }
>>> +
>>> +    if (Attributes != 0) {
>>> +      StrCatS (AttributesStr, AttributesStrSize, L" <Unknown
>> Attribute>");
>>> +    }
>>> +  }
>>> +
>>> +  return EFI_SUCCESS;
>>> +}
>>> +
>>> +/**
>>> +  Prints UEFI variable statistics information.
>>> +
>>> +  @param[in] TotalVariables             Total number of UEFI variables
>>> discovered.
>>> +  @param[in] TotalVariablesSize         Total size of UEFI variables
>>> discovered.
>>> +
>>> +**/
>>> +VOID
>>> +PrintStats (
>>> +  IN  UINTN  TotalVariables,
>>> +  IN  UINTN  TotalVariablesSize
>>> +  )
>>> +{
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_STATS_HEADER_1), mVarPolicyShellCommandHiiHandle);
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_STATS_HEADER_2), mVarPolicyShellCommandHiiHandle);
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_STATS_HEADER_1), mVarPolicyShellCommandHiiHandle);
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_STATS_TOTAL_VARS), mVarPolicyShellCommandHiiHandle,
>>> TotalVariables);
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_STATS_TOTAL_SIZE), mVarPolicyShellCommandHiiHandle,
>>> TotalVariablesSize, TotalVariablesSize);
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_STATS_HEADER_1), mVarPolicyShellCommandHiiHandle);
>>> +}
>>> +
>>> +/**
>>> +  Returns information for the given variable namespace if available.
>>> +
>>> +  @param[in]  VariableGuid      The UEFI variable vendor (namespace)
>>> GUID.
>>> +
>>> +  @return     Pointer to a namespace info structure on a GUID match.
>>> +  @return     NULL on lack of a GUID match.
>>> +
>>> +**/
>>> +CONST VAR_POLICY_CMD_VAR_NAMESPACE *
>>> +GetNameSpaceInfo (
>>> +  IN  EFI_GUID  *VariableGuid
>>> +  )
>>> +{
>>> +  UINTN  Index;
>>> +
>>> +  if (VariableGuid == NULL) {
>>> +    ASSERT (VariableGuid != NULL);
>>> +    return NULL;
>>> +  }
>>> +
>>> +  for (Index = 0; Index < ARRAY_SIZE (mVarNamespaces); Index++) {
>>> +    if (CompareGuid (mVarNamespaces[Index].VendorGuid, VariableGuid))
>> {
>>> +      return &mVarNamespaces[Index];
>>> +    }
>>> +  }
>>> +
>>> +  return NULL;
>>> +}
>>> +
>>> +/**
>>> +  Print non-verbose information about the variable.
>>> +
>>> +  @param[in]    VariableName          A pointer the Unicode
>>> variable name.
>>> +  @param[in]    VariableGuid          A pointer to the variable
>>> vendor GUID.
>>> +  @param[in]    VariableSize          The size of the UEFI variable in
>>> bytes.
>>> +  @param[in]    VariableAttributes    The UEFI variable attributes.
>>> +
>>> +  @retval   EFI_SUCCESS               The non-verbose variable
>>> information was printed successfully.
>>> +  @retval   EFI_INVALID_PARAMETER     A pointer argument passed to
>>> the function was NULL.
>>> +  @retval   EFI_OUT_OF_RESOURCES      Insufficient memory
>>> resources to print the attributes.
>>> +
>>> +**/
>>> +EFI_STATUS
>>> +PrintNonVerboseVarInfo (
>>> +  IN CHAR16    *VariableName,
>>> +  IN EFI_GUID  *VariableGuid,
>>> +  IN UINTN     VariableSize,
>>> +  IN UINT32    VariableAttributes
>>> +  )
>>> +{
>>> +  EFI_STATUS                          Status;
>>> +  CHAR16                              *AttributesStr;
>>> +  CHAR16                              *DescriptionStr;
>>> +  CONST VAR_POLICY_CMD_VAR_NAMESPACE  *CmdVarNamespace;
>>> +
>>> +  AttributesStr  = NULL;
>>> +  DescriptionStr = NULL;
>>> +
>>> +  if ((VariableName == NULL) || (VariableGuid == NULL)) {
>>> +    return EFI_INVALID_PARAMETER;
>>> +  }
>>> +
>>> +  CmdVarNamespace = GetNameSpaceInfo (VariableGuid);
>>> +
>>> +  if (CmdVarNamespace == NULL) {
>>> +    DescriptionStr = AllocatePages (1);
>>> +    if (DescriptionStr == NULL) {
>>> +      Status = EFI_OUT_OF_RESOURCES;
>>> +      goto Exit;
>>> +    }
>>> +
>>> +    ZeroMem ((VOID *)DescriptionStr, EFI_PAGES_TO_SIZE (1));
>>> +    UnicodeSPrint (DescriptionStr, EFI_PAGES_TO_SIZE (1), L"Unknown
>>> Vendor (%g)", VariableGuid);
>>> +  } else {
>>> +    DescriptionStr = CmdVarNamespace->Description;
>>> +  }
>>> +
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_TYPE),
>>> mVarPolicyShellCommandHiiHandle, DescriptionStr);
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>> (STR_VAR_POL_VAR_NAME),
>>> mVarPolicyShellCommandHiiHandle, VariableName);
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_SIZE),
>>> mVarPolicyShellCommandHiiHandle, VariableSize, VariableSize);
>>> +
>>> +  AttributesStr = AllocatePages (1);
>>> +  if (AttributesStr == NULL) {
>>> +    Status = EFI_OUT_OF_RESOURCES;
>>> +    goto Exit;
>>> +  }
>>> +
>>> +  ZeroMem ((VOID *)AttributesStr, EFI_PAGES_TO_SIZE (1));
>>> +  Status = GetAttributesString (VariableAttributes, EFI_PAGES_TO_SIZE
>> (1),
>>> AttributesStr);
>>> +  if (Status == EFI_SUCCESS) {
>>> +    ShellPrintHiiEx (
>>> +      -1,
>>> +      -1,
>>> +      NULL,
>>> +      STRING_TOKEN (STR_VAR_POL_VAR_ATTR),
>>> +      mVarPolicyShellCommandHiiHandle,
>>> +      AttributesStr
>>> +      );
>>> +  }
>>> +
>>> +  Status = EFI_SUCCESS;
>>> +
>>> +Exit:
>>> +  if (AttributesStr != NULL) {
>>> +    FreePages (AttributesStr, 1);
>>> +  }
>>> +
>>> +  if ((CmdVarNamespace == NULL) && (DescriptionStr != NULL)) {
>>> +    FreePages (DescriptionStr, 1);
>>> +  }
>>> +
>>> +  return Status;
>>> +}
>>> +
>>> +/**
>>> +  Print verbose information about the variable.
>>> +
>>> +  @param[in]    Data                  A pointer to the variable data
>>> buffer.
>>> +  @param[in]    DataSize              The size of data, in bytes, in
>>> the variable data buffer.
>>> +
>>> +  @retval   EFI_SUCCESS               The verbose variable
>>> information was printed successfully.
>>> +  @retval   EFI_INVALID_PARAMETER     A pointer argument passed to
>>> the function was NULL.
>>> +
>>> +**/
>>> +EFI_STATUS
>>> +PrintVerboseVarInfo (
>>> +  IN  VOID   *Data,
>>> +  IN  UINTN  DataSize
>>> +  )
>>> +{
>>> +  if ((DataSize == 0) || (Data == NULL)) {
>>> +    return EFI_INVALID_PARAMETER;
>>> +  }
>>> +
>>> +  VAR_POLICY_CMD_SHELL_DUMP_HEX (0, Data, DataSize);
>>> +
>>> +  return EFI_SUCCESS;
>>> +}
>>> +
>>> +/**
>>> +  Prints variable policy information for the given variable.
>>> +
>>> +  @param[in]  VariableName    A pointer to the Unicode string of the
>>> UEFI variable name.
>>> +  @param[in]  VendorGuid      A pointer to the UEFI variable vendor
>>> GUID.
>>> +
>>> +  @return TRUE if a variable policy was found and printed for the
>> variable.
>>> +  @return FALSE if an error occurred and/or a variable policy was not
>> found
>>> and
>>> +          printed for the variable.
>>> +
>>> +**/
>>> +BOOLEAN
>>> +PrintVariablePolicyInfo (
>>> +  IN  CHAR16    *VariableName,
>>> +  IN  EFI_GUID  *VendorGuid
>>> +  )
>>> +{
>>> +  EFI_STATUS                         Status;
>>> +  VARIABLE_POLICY_ENTRY              VariablePolicyEntry;
>>> +  VARIABLE_LOCK_ON_VAR_STATE_POLICY  LockOnVarStatePolicy;
>>> +  UINTN
>>> VariablePolicyVariableNameBufferSize;
>>> +  UINTN                              ReturnedVariableNameSize;
>>> +  BOOLEAN                            PolicyHeaderPresent;
>>> +  CHAR16
>>> *VariablePolicyVariableName;
>>> +  CHAR16                             *VariableAttributesStr;
>>> +  EDKII_VARIABLE_POLICY_PROTOCOL     *VariablePolicy;
>>> +
>>> +  PolicyHeaderPresent        = FALSE;
>>> +  VariableAttributesStr      = NULL;
>>> +  VariablePolicyVariableName = NULL;
>>> +
>>> +  if ((VariableName == NULL) || (VendorGuid == NULL)) {
>>> +    ASSERT ((VariableName != NULL) && (VendorGuid != NULL));
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_INT_ERR), mVarPolicyShellCommandHiiHandle);
>>> +    return FALSE;
>>> +  }
>>> +
>>> +  Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL,
>>> (VOID **)&VariablePolicy);
>>> +  if (EFI_ERROR (Status)) {
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_NO_PROT), mVarPolicyShellCommandHiiHandle);
>>> +    return FALSE;
>>> +  }
>>> +
>>> +  VariablePolicyVariableNameBufferSize = EFI_PAGES_TO_SIZE (1);
>>> +  VariablePolicyVariableName           = AllocatePages
>>> (EFI_SIZE_TO_PAGES (VariablePolicyVariableNameBufferSize));
>>> +  if (VariablePolicyVariableName == NULL) {
>>> +    Status = EFI_OUT_OF_RESOURCES;
>>> +    ASSERT_EFI_ERROR (Status);
>>> +    goto Done;
>>> +  }
>>> +
>>> +  ZeroMem (VariablePolicyVariableName,
>>> VariablePolicyVariableNameBufferSize);
>>> +  ReturnedVariableNameSize = VariablePolicyVariableNameBufferSize;
>>> +  Status                   =  VariablePolicy->GetVariablePolicyInfo (
>>> +                                                VariableName,
>>> +                                                VendorGuid,
>>> +
>>> &ReturnedVariableNameSize,
>>> +
>>> &VariablePolicyEntry,
>>> +
>>> VariablePolicyVariableName
>>> +                                                );
>>> +  if (Status == EFI_NOT_READY) {
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_NOT_INIT), mVarPolicyShellCommandHiiHandle);
>>> +  } else if (Status == EFI_NOT_FOUND) {
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_NOT_FOUND),
>> mVarPolicyShellCommandHiiHandle);
>>> +  } else if (EFI_ERROR (Status)) {
>>> +    // A different error return code is not expected
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_UNEXP_ERR), mVarPolicyShellCommandHiiHandle,
>>> Status);
>>> +  } else {
>>> +    PolicyHeaderPresent = TRUE;
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_HEADER_1), mVarPolicyShellCommandHiiHandle);
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_HEADER_2), mVarPolicyShellCommandHiiHandle);
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_HEADER_1), mVarPolicyShellCommandHiiHandle);
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_VERSION), mVarPolicyShellCommandHiiHandle,
>>> VariablePolicyEntry.Version);
>>> +
>>> +    if ((ReturnedVariableNameSize > 0) &&
>>> (VariablePolicyVariableName[0] != CHAR_NULL)) {
>>> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_VARIABLE), mVarPolicyShellCommandHiiHandle,
>>> VariablePolicyVariableName);
>>> +    } else {
>>> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_VARIABLE), mVarPolicyShellCommandHiiHandle,
>>> L"<Entire Namespace>");
>>> +    }
>>> +
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_NAMESPACE),
>> mVarPolicyShellCommandHiiHandle,
>>> &VariablePolicyEntry.Namespace);
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_MIN_SIZE), mVarPolicyShellCommandHiiHandle,
>>> VariablePolicyEntry.MinSize);
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_MAX_SIZE), mVarPolicyShellCommandHiiHandle,
>>> VariablePolicyEntry.MaxSize);
>>> +
>>> +    switch (VariablePolicyEntry.LockPolicyType) {
>>> +      case VARIABLE_POLICY_TYPE_NO_LOCK:
>>> +        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle,
>>> L"No Lock");
>>> +        break;
>>> +      case VARIABLE_POLICY_TYPE_LOCK_NOW:
>>> +        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle,
>>> L"Lock Now");
>>> +        break;
>>> +      case VARIABLE_POLICY_TYPE_LOCK_ON_CREATE:
>>> +        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle,
>>> L"On Create");
>>> +        break;
>>> +      case VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE:
>>> +        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle,
>>> L"On Variable State");
>>> +
>>> +        ZeroMem (VariablePolicyVariableName,
>>> VariablePolicyVariableNameBufferSize);
>>> +        ReturnedVariableNameSize =
>>> VariablePolicyVariableNameBufferSize;
>>> +        Status                   =
>>> VariablePolicy->GetLockOnVariableStateVariablePolicyInfo (
>>> +
>>> VariableName,
>>> +
>>> VendorGuid,
>>> +
>>> &ReturnedVariableNameSize,
>>> +
>>> &LockOnVarStatePolicy,
>>> +
>>> VariablePolicyVariableName
>>> +                                                      );
>>> +        if (EFI_ERROR (Status)) {
>>> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_UNEXP_ERR), mVarPolicyShellCommandHiiHandle,
>>> Status);
>>> +          goto Done;
>>> +        } else {
>>> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_STATE_NS), mVarPolicyShellCommandHiiHandle,
>>> &LockOnVarStatePolicy.Namespace);
>>> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_STATE_VAL), mVarPolicyShellCommandHiiHandle,
>>> LockOnVarStatePolicy.Value);
>>> +          if ((ReturnedVariableNameSize > 0) &&
>>> (VariablePolicyVariableName[0] != CHAR_NULL)) {
>>> +            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_STATE_NAME),
>> mVarPolicyShellCommandHiiHandle,
>>> VariablePolicyVariableName);
>>> +          } else {
>>> +            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_STATE_NAME),
>> mVarPolicyShellCommandHiiHandle,
>>> L"<Entire Namespace>");
>>> +          }
>>> +        }
>>> +
>>> +        break;
>>> +      default:
>>> +        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_LOCK_TYPE), mVarPolicyShellCommandHiiHandle,
>>> L"Unknown");
>>> +        break;
>>> +    }
>>> +
>>> +    VariableAttributesStr = AllocatePages (1);
>>> +    if (VariableAttributesStr == NULL) {
>>> +      Status = EFI_OUT_OF_RESOURCES;
>>> +      ASSERT_EFI_ERROR (Status);
>>> +      goto Done;
>>> +    }
>>> +
>>> +    ZeroMem (VariableAttributesStr, EFI_PAGES_TO_SIZE (1));
>>> +    Status = GetAttributesString (VariablePolicyEntry.AttributesMustHave,
>>> EFI_PAGES_TO_SIZE (1), VariableAttributesStr);
>>> +    if (Status == EFI_SUCCESS) {
>>> +      ShellPrintHiiEx (
>>> +        -1,
>>> +        -1,
>>> +        NULL,
>>> +        STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_MUST),
>>> +        mVarPolicyShellCommandHiiHandle
>>> +        );
>>> +      ShellPrintHiiEx (
>>> +        -1,
>>> +        -1,
>>> +        NULL,
>>> +        STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_GEN),
>>> +        mVarPolicyShellCommandHiiHandle,
>>> +        VariableAttributesStr
>>> +        );
>>> +    }
>>> +
>>> +    ZeroMem (VariableAttributesStr, EFI_PAGES_TO_SIZE (1));
>>> +    Status = GetAttributesString (VariablePolicyEntry.AttributesCantHave,
>>> EFI_PAGES_TO_SIZE (1), VariableAttributesStr);
>>> +    if (Status == EFI_SUCCESS) {
>>> +      ShellPrintHiiEx (
>>> +        -1,
>>> +        -1,
>>> +        NULL,
>>> +        STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_NOT),
>>> +        mVarPolicyShellCommandHiiHandle
>>> +        );
>>> +      ShellPrintHiiEx (
>>> +        -1,
>>> +        -1,
>>> +        NULL,
>>> +        STRING_TOKEN (STR_VAR_POL_POLICY_ATTR_GEN),
>>> +        mVarPolicyShellCommandHiiHandle,
>>> +        VariableAttributesStr
>>> +        );
>>> +    }
>>> +  }
>>> +
>>> +Done:
>>> +  if (PolicyHeaderPresent) {
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_VAR_POL_POLICY_HEADER_1), mVarPolicyShellCommandHiiHandle);
>>> +  }
>>> +
>>> +  if (VariableAttributesStr != NULL) {
>>> +    FreePages (VariableAttributesStr, 1);
>>> +  }
>>> +
>>> +  if (VariablePolicyVariableName != NULL) {
>>> +    FreePages (VariablePolicyVariableName, 1);
>>> +  }
>>> +
>>> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK),
>>> mVarPolicyShellCommandHiiHandle);
>>> +
>>> +  return Status == EFI_SUCCESS;
>>> +}
>>> +
>>> +/**
>>> +  Gets the next UEFI variable name.
>>> +
>>> +  This buffer manages the UEFI variable name buffer, performing memory
>>> reallocations as necessary.
>>> +
>>> +  Note: The first time this function is called, VariableNameBufferSize
>> must
>>> be 0 and
>>> +  the VariableName buffer pointer must point to NULL.
>>> +
>>> +  @param[in,out] VariableNameBufferSize   On input, a pointer to a
>>> buffer that holds the current
>>> +                                          size of the
>>> VariableName buffer in bytes.
>>> +                                          On output, a pointer to
>>> a buffer that holds the updated
>>> +                                          size of the
>>> VariableName buffer in bytes.
>>> +  @param[in,out] VariableName             On input, a pointer to a
>>> pointer to a buffer that holds the
>>> +                                          current UEFI variable
>>> name.
>>> +                                          On output, a pointer to
>>> a pointer to a buffer that holds the
>>> +                                          next UEFI variable
>>> name.
>>> +  @param[in,out] VariableGuid             On input, a pointer to a
>>> buffer that holds the current UEFI
>>> +                                          variable GUID.
>>> +                                          On output, a pointer to
>>> a buffer that holds the next UEFI
>>> +                                          variable GUID.
>>> +
>>> +  @retval    EFI_SUCCESS              The next UEFI variable name
>>> was found successfully.
>>> +  @retval    EFI_INVALID_PARAMETER    A pointer argument is NULL
>>> or initial input values are invalid.
>>> +  @retval    EFI_OUT_OF_RESOURCES     Insufficient memory
>>> resources to allocate a required buffer.
>>> +  @retval    Others                   Return status codes from the
>>> UEFI spec define GetNextVariableName() interface.
>>> +
>>> +**/
>>> +EFI_STATUS
>>> +GetNextVariableNameWithDynamicReallocation (
>>> +  IN  OUT UINTN     *VariableNameBufferSize,
>>> +  IN  OUT CHAR16    **VariableName,
>>> +  IN  OUT EFI_GUID  *VariableGuid
>>> +  )
>>> +{
>>> +  EFI_STATUS  Status;
>>> +  UINTN       NextVariableNameBufferSize;
>>> +
>>> +  if ((VariableNameBufferSize == NULL) || (VariableName == NULL) ||
>>> (VariableGuid == NULL)) {
>>> +    return EFI_INVALID_PARAMETER;
>>> +  }
>>> +
>>> +  if (*VariableNameBufferSize == 0) {
>>> +    if (*VariableName != NULL) {
>>> +      return EFI_INVALID_PARAMETER;
>>> +    }
>>> +
>>> +    //
>>> +    // Allocate a buffer to temporarily hold variable names. To reduce
>>> memory
>>> +    // allocations, the default buffer size is 256 characters. The buffer
>> can
>>> +    // be reallocated if expansion is necessary (should be very rare).
>>> +    //
>>> +    *VariableNameBufferSize = sizeof (CHAR16) * 256;
>>> +    *VariableName           = AllocateZeroPool
>>> (*VariableNameBufferSize);
>>> +    if (*VariableName == NULL) {
>>> +      return EFI_OUT_OF_RESOURCES;
>>> +    }
>>> +
>>> +    ZeroMem ((VOID *)VariableGuid, sizeof (EFI_GUID));
>>> +  }
>>> +
>>> +  NextVariableNameBufferSize = *VariableNameBufferSize;
>>> +  Status                     = gRT->GetNextVariableName (
>>> +
>>> &NextVariableNameBufferSize,
>>> +                                      *VariableName,
>>> +                                      VariableGuid
>>> +                                      );
>>> +  if (Status == EFI_BUFFER_TOO_SMALL) {
>>> +    *VariableName = ReallocatePool (
>>> +                      *VariableNameBufferSize,
>>> +                      NextVariableNameBufferSize,
>>> +                      *VariableName
>>> +                      );
>>> +    if (*VariableName == NULL) {
>>> +      return EFI_OUT_OF_RESOURCES;
>>> +    }
>>> +
>>> +    *VariableNameBufferSize = NextVariableNameBufferSize;
>>> +
>>> +    Status = gRT->GetNextVariableName (
>>> +                    &NextVariableNameBufferSize,
>>> +                    *VariableName,
>>> +                    VariableGuid
>>> +                    );
>>> +    ASSERT (Status != EFI_BUFFER_TOO_SMALL);
>>> +  }
>>> +
>>> +  return Status;
>>> +}
>>> +
>>> +/**
>>> +  Dumps UEFI variable information.
>>> +
>>> +  This is the main function that enumerates UEFI variables and prints the
>>> information
>>> +  selected by the user.
>>> +
>>> +  @param[in] Verbose            Whether to print verbose information.
>>> +  @param[in] Stats              Whether to print statistical
>>> information.
>>> +  @param[in] PolicyCheck        Whether to print variable policy related
>>> information.
>>> +
>>> +
>>> +  @retval    EFI_SUCCESS              The UEFI variable information
>>> was dumped successfully.
>>> +  @retval    EFI_DEVICE_ERROR         An error occurred attempting
>>> to get UEFI variable information.
>>> +  @retval    EFI_OUT_OF_RESOURCES     Insufficient memory
>>> resources to allocate a required buffer.
>>> +
>>> +**/
>>> +EFI_STATUS
>>> +DumpVars (
>>> +  IN  BOOLEAN  Verbose,
>>> +  IN  BOOLEAN  Stats,
>>> +  IN  BOOLEAN  PolicyCheck
>>> +  )
>>> +{
>>> +  EFI_STATUS  Status;
>>> +  EFI_STATUS  GetNextVariableStatus;
>>> +  UINT32      Attributes;
>>> +  UINTN       CurrentVariableDataBufferSize;
>>> +  UINTN       DataSize;
>>> +  UINTN       TotalDataSize;
>>> +  UINTN       TotalVariables;
>>> +  UINTN       TotalVariablesWithPolicy;
>>> +  UINTN       VariableNameBufferSize;
>>> +  EFI_GUID    VariableGuid;
>>> +  CHAR16      *VariableName;
>>> +  VOID        *Data;
>>> +
>>> +  Status                        = EFI_SUCCESS;
>>> +  Data                          = NULL;
>>> +  VariableName                  = NULL;
>>> +  CurrentVariableDataBufferSize = 0;
>>> +  TotalDataSize                 = 0;
>>> +  TotalVariables                = 0;
>>> +  TotalVariablesWithPolicy      = 0;
>>> +  VariableNameBufferSize        = 0;
>>> +
>>> +  do {
>>> +    GetNextVariableStatus =
>>> GetNextVariableNameWithDynamicReallocation (
>>> +                              &VariableNameBufferSize,
>>> +                              &VariableName,
>>> +                              &VariableGuid
>>> +                              );
>>> +
>>> +    if (!EFI_ERROR (GetNextVariableStatus)) {
>>> +      DataSize = 0;
>>> +      Status   = gRT->GetVariable (
>>> +                        VariableName,
>>> +                        &VariableGuid,
>>> +                        &Attributes,
>>> +                        &DataSize,
>>> +                        NULL
>>> +                        );
>>> +      if (Status != EFI_BUFFER_TOO_SMALL) {
>>> +        // If the variable exists, a zero size buffer should be too small
>>> +        Status = EFI_DEVICE_ERROR;
>>> +        goto DeallocateAndExit;
>>> +      }
>>> +
>>> +      TotalDataSize += DataSize;
>>> +      TotalVariables++;
>>> +
>>> +      if (!Stats || Verbose) {
>>> +        Status = PrintNonVerboseVarInfo (VariableName, &VariableGuid,
>>> DataSize, Attributes);
>>> +        if (!EFI_ERROR (Status)) {
>>> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle);
>>> +        }
>>> +      }
>>> +
>>> +      if (PolicyCheck || Verbose) {
>>> +        if (PrintVariablePolicyInfo (VariableName, &VariableGuid)) {
>>> +          TotalVariablesWithPolicy++;
>>> +        }
>>> +      }
>>> +
>>> +      if (Verbose) {
>>> +        if (CurrentVariableDataBufferSize < DataSize) {
>>> +          if (Data != NULL) {
>>> +            FreePool (Data);
>>> +          }
>>> +
>>> +          Data = AllocateZeroPool (DataSize);
>>> +          if (Data == NULL) {
>>> +            Status = EFI_OUT_OF_RESOURCES;
>>> +            goto DeallocateAndExit;
>>> +          }
>>> +
>>> +          CurrentVariableDataBufferSize = DataSize;
>>> +        }
>>> +
>>> +        Status = gRT->GetVariable (
>>> +                        VariableName,
>>> +                        &VariableGuid,
>>> +                        NULL,
>>> +                        &DataSize,
>>> +                        Data
>>> +                        );
>>> +        if (EFI_ERROR (Status)) {
>>> +          Status = EFI_DEVICE_ERROR;
>>> +          goto DeallocateAndExit;
>>> +        }
>>> +
>>> +        Status = PrintVerboseVarInfo (Data, DataSize);
>>> +        if (EFI_ERROR (Status)) {
>>> +          Status = EFI_DEVICE_ERROR;
>>> +          goto DeallocateAndExit;
>>> +        }
>>> +      }
>>> +    }
>>> +  } while (!EFI_ERROR (GetNextVariableStatus));
>>> +
>>> +  if (TotalVariables == 0) {
>>> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VARS),
>>> mVarPolicyShellCommandHiiHandle);
>>> +  } else {
>>> +    if (Verbose || Stats) {
>>> +      PrintStats (TotalVariables, TotalDataSize);
>>> +    }
>>> +
>>> +    if (Verbose || PolicyCheck) {
>>> +      ASSERT (TotalVariablesWithPolicy <= TotalVariables);
>>> +
>>> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle);
>>> +      if (TotalVariablesWithPolicy == TotalVariables) {
>>> +        ShellPrintHiiEx (
>>> +          -1,
>>> +          -1,
>>> +          NULL,
>>> +          STRING_TOKEN (STR_VAR_POL_POLICY_STATS_PASS),
>>> +          mVarPolicyShellCommandHiiHandle,
>>> +          TotalVariablesWithPolicy,
>>> +          TotalVariables
>>> +          );
>>> +      } else {
>>> +        ShellPrintHiiEx (
>>> +          -1,
>>> +          -1,
>>> +          NULL,
>>> +          STRING_TOKEN (STR_VAR_POL_POLICY_STATS_FAIL),
>>> +          mVarPolicyShellCommandHiiHandle,
>>> +          TotalVariablesWithPolicy,
>>> +          TotalVariables
>>> +          );
>>> +      }
>>> +
>>> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle);
>>> +    }
>>> +  }
>>> +
>>> +  Status = EFI_SUCCESS;
>>> +
>>> +DeallocateAndExit:
>>> +  if (VariableName != NULL) {
>>> +    FreePool (VariableName);
>>> +  }
>>> +
>>> +  if (Data != NULL) {
>>> +    FreePool (Data);
>>> +  }
>>> +
>>> +  ASSERT_EFI_ERROR (Status);
>>> +
>>> +  return Status;
>>> +}
>>> +
>>> +/**
>>> +  Main entry function for the "varpolicy" command.
>>> +
>>> +  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
>>> +  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
>>> +
>>> +  @retval   SHELL_SUCCESS               The "varpolicy" shell
>>> command executed successfully.
>>> +  @retval   SHELL_INVALID_PARAMETER     An argument passed to
>>> the shell command is invalid.
>>> +  @retval   Others                      A different error occurred.
>>> +
>>> +**/
>>> +SHELL_STATUS
>>> +EFIAPI
>>> +ShellCommandRunVarPolicy (
>>> +  IN EFI_HANDLE        ImageHandle,
>>> +  IN EFI_SYSTEM_TABLE  *SystemTable
>>> +  )
>>> +{
>>> +  EFI_STATUS    Status;
>>> +  SHELL_STATUS  ShellStatus;
>>> +  BOOLEAN       PolicyCheck;
>>> +  BOOLEAN       StatsDump;
>>> +  BOOLEAN       VerboseDump;
>>> +  LIST_ENTRY    *Package;
>>> +  CHAR16        *ProblemParam;
>>> +
>>> +  Package     = NULL;
>>> +  ShellStatus = SHELL_INVALID_PARAMETER;
>>> +  Status      = EFI_SUCCESS;
>>> +  PolicyCheck = FALSE;
>>> +  StatsDump   = FALSE;
>>> +  VerboseDump = FALSE;
>>> +
>>> +  Status = ShellInitialize ();
>>> +  ASSERT_EFI_ERROR (Status);
>>> +
>>> +  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam,
>>> TRUE);
>>> +  if (EFI_ERROR (Status)) {
>>> +    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL))
>>> {
>>> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM),
>>> mVarPolicyShellCommandHiiHandle, VAR_POLICY_COMMAND_NAME,
>>> ProblemParam);
>>> +      FreePool (ProblemParam);
>>> +      ShellStatus = SHELL_INVALID_PARAMETER;
>>> +      goto Done;
>>> +    } else {
>>> +      ASSERT (FALSE);
>>> +    }
>>> +  } else {
>>> +    if (ShellCommandLineGetCount (Package) > 1) {
>>> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_GEN_TOO_MANY), mVarPolicyShellCommandHiiHandle,
>>> VAR_POLICY_COMMAND_NAME);
>>> +      ShellStatus = SHELL_INVALID_PARAMETER;
>>> +      goto Done;
>>> +    }
>>> +
>>> +    PolicyCheck = ShellCommandLineGetFlag (Package,
>>> VAR_POLICY_FLAG_POLICY_STR);
>>> +    StatsDump   = ShellCommandLineGetFlag (Package,
>>> VAR_POLICY_FLAG_STATS_STR);
>>> +    VerboseDump = ShellCommandLineGetFlag (Package,
>>> VAR_POLICY_FLAG_VERBOSE_STR);
>>> +
>>> +    Status = DumpVars (VerboseDump, StatsDump, PolicyCheck);
>>> +    ASSERT_EFI_ERROR (Status);
>>> +  }
>>> +
>>> +Done:
>>> +  if (Package != NULL) {
>>> +    ShellCommandLineFreeVarList (Package);
>>> +  }
>>> +
>>> +  return ShellStatus;
>>> +}
>>> +
>>> +/**
>>> +  This is the shell command handler function pointer callback type.
>>> +
>>> +  This function handles the command when it is invoked in the shell.
>>> +
>>> +  @param[in] This                   The instance of the
>>> +
>>> EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
>>> +  @param[in] SystemTable            The pointer to the system table.
>>> +  @param[in] ShellParameters        The parameters associated with
>>> the command.
>>> +  @param[in] Shell                  The instance of the shell protocol
>>> used in
>>> +                                    the context of processing this
>>> command.
>>> +
>>> +  @return EFI_SUCCESS               the operation was successful
>>> +  @return other                     the operation failed.
>>> +
>>> +**/
>>> +SHELL_STATUS
>>> +EFIAPI
>>> +VarPolicyCommandHandler (
>>> +  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
>>> +  IN EFI_SYSTEM_TABLE                    *SystemTable,
>>> +  IN EFI_SHELL_PARAMETERS_PROTOCOL       *ShellParameters,
>>> +  IN EFI_SHELL_PROTOCOL                  *Shell
>>> +  )
>>> +{
>>> +  gEfiShellParametersProtocol = ShellParameters;
>>> +  gEfiShellProtocol           = Shell;
>>> +
>>> +  return ShellCommandRunVarPolicy (gImageHandle, SystemTable);
>>> +}
>>> +
>>> +/**
>>> +  This is the command help handler function pointer callback type.  This
>>> +  function is responsible for displaying help information for the
>> associated
>>> +  command.
>>> +
>>> +  @param[in] This                   The instance of the
>>> +
>>> EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
>>> +  @param[in] Language               The pointer to the language
>>> string to use.
>>> +
>>> +  @return string                    Pool allocated help string, must be
>>> freed
>>> +                                    by caller.
>>> +
>>> +**/
>>> +STATIC
>>> +CHAR16 *
>>> +EFIAPI
>>> +VarPolicyCommandGetHelp (
>>> +  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
>>> +  IN CONST CHAR8                         *Language
>>> +  )
>>> +{
>>> +  return HiiGetString (
>>> +           mVarPolicyShellCommandHiiHandle,
>>> +           STRING_TOKEN (STR_GET_HELP_VAR_POLICY),
>>> +           Language
>>> +           );
>>> +}
>>> +
>>> +STATIC EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL
>>> mVarPolicyDynamicCommand = {
>>> +  VAR_POLICY_COMMAND_NAME,
>>> +  VarPolicyCommandHandler,
>>> +  VarPolicyCommandGetHelp
>>> +};
>>> +
>>> +/**
>>> +  Retrieve HII package list from ImageHandle and publish to HII database.
>>> +
>>> +  @param[in] ImageHandle    The image handle of the process.
>>> +
>>> +  @return HII handle.
>>> +
>>> +**/
>>> +STATIC
>>> +EFI_HII_HANDLE
>>> +InitializeHiiPackage (
>>> +  IN  EFI_HANDLE  ImageHandle
>>> +  )
>>> +{
>>> +  EFI_STATUS                   Status;
>>> +  EFI_HII_PACKAGE_LIST_HEADER  *PackageList;
>>> +  EFI_HII_HANDLE               HiiHandle;
>>> +
>>> +  //
>>> +  // Retrieve HII package list from ImageHandle
>>> +  //
>>> +  Status = gBS->OpenProtocol (
>>> +                  ImageHandle,
>>> +                  &gEfiHiiPackageListProtocolGuid,
>>> +                  (VOID **)&PackageList,
>>> +                  ImageHandle,
>>> +                  NULL,
>>> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
>>> +                  );
>>> +  ASSERT_EFI_ERROR (Status);
>>> +  if (EFI_ERROR (Status)) {
>>> +    return NULL;
>>> +  }
>>> +
>>> +  //
>>> +  // Publish HII package list to HII Database.
>>> +  //
>>> +  Status = gHiiDatabase->NewPackageList (
>>> +                           gHiiDatabase,
>>> +                           PackageList,
>>> +                           NULL,
>>> +                           &HiiHandle
>>> +                           );
>>> +  ASSERT_EFI_ERROR (Status);
>>> +  if (EFI_ERROR (Status)) {
>>> +    return NULL;
>>> +  }
>>> +
>>> +  return HiiHandle;
>>> +}
>>> +
>>> +/**
>>> +  Entry point of the UEFI variable policy dynamic shell command.
>>> +
>>> +  Produce the Dynamic Command Protocol to handle the "varpolicy"
>>> command.
>>> +
>>> +  @param[in] ImageHandle        The image handle of the process.
>>> +  @param[in] SystemTable        The EFI System Table pointer.
>>> +
>>> +  @retval EFI_SUCCESS           The "varpolicy" command executed
>>> successfully.
>>> +  @retval EFI_ABORTED           HII package failed to initialize.
>>> +  @retval others                Other errors when executing
>>> "varpolicy" command.
>>> +
>>> +**/
>>> +EFI_STATUS
>>> +EFIAPI
>>> +VariablePolicyDynamicCommandEntryPoint (
>>> +  IN EFI_HANDLE        ImageHandle,
>>> +  IN EFI_SYSTEM_TABLE  *SystemTable
>>> +  )
>>> +{
>>> +  EFI_STATUS  Status;
>>> +
>>> +  mVarPolicyShellCommandHiiHandle = InitializeHiiPackage (ImageHandle);
>>> +  if (mVarPolicyShellCommandHiiHandle == NULL) {
>>> +    return EFI_ABORTED;
>>> +  }
>>> +
>>> +  Status = gBS->InstallProtocolInterface (
>>> +                  &ImageHandle,
>>> +                  &gEfiShellDynamicCommandProtocolGuid,
>>> +                  EFI_NATIVE_INTERFACE,
>>> +                  &mVarPolicyDynamicCommand
>>> +                  );
>>> +  ASSERT_EFI_ERROR (Status);
>>> +
>>> +  return Status;
>>> +}
>>> +
>>> +/**
>>> +  Unload the dynamic "varpolicy" UEFI Shell command.
>>> +
>>> +  @param[in] ImageHandle        The image handle of the process.
>>> +
>>> +  @retval EFI_SUCCESS           The image is unloaded.
>>> +  @retval Others                Failed to unload the image.
>>> +
>>> +**/
>>> +EFI_STATUS
>>> +EFIAPI
>>> +VariablePolicyDynamicCommandUnload (
>>> +  IN EFI_HANDLE  ImageHandle
>>> +  )
>>> +{
>>> +  EFI_STATUS  Status;
>>> +
>>> +  Status = gBS->UninstallProtocolInterface (
>>> +                  ImageHandle,
>>> +                  &gEfiShellDynamicCommandProtocolGuid,
>>> +                  &mVarPolicyDynamicCommand
>>> +                  );
>>> +  if (EFI_ERROR (Status)) {
>>> +    return Status;
>>> +  }
>>> +
>>> +  HiiRemovePackages (mVarPolicyShellCommandHiiHandle);
>>> +
>>> +  return EFI_SUCCESS;
>>> +}
>>> diff --git
>>>
>> a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.h
>>>
>> b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.h
>>> new file mode 100644
>>> index 000000000000..7ce5beca389a
>>> --- /dev/null
>>> +++
>>>
>> b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.h
>>> @@ -0,0 +1,94 @@
>>> +/** @file
>>> +  Internal header file for the module.
>>> +
>>> +  Copyright (c) Microsoft Corporation.
>>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>>> +
>>> +**/
>>> +
>>> +#ifndef VAR_POLICY_DYNAMIC_SHELL_COMMAND_H_
>>> +#define VAR_POLICY_DYNAMIC_SHELL_COMMAND_H_
>>> +
>>> +#include <Uefi.h>
>>> +
>>> +#define VAR_POLICY_COMMAND_NAME  L"varpolicy"
>>> +
>>> +typedef enum {
>>> +  VariableVendorCapsule,
>>> +  VariableVendorCapsuleReport,
>>> +  VariableVendorGlobal,
>>> +  VariableVendorMorControl,
>>> +  VariableVendorGuidMax
>>> +} VAR_POLICY_CMD_VENDOR_GUID_TYPE;
>>> +
>>> +typedef struct {
>>> +  VAR_POLICY_CMD_VENDOR_GUID_TYPE    VendorGuidType;
>>> +  EFI_GUID                           *VendorGuid;
>>> +  CHAR16                             *Description;
>>> +} VAR_POLICY_CMD_VAR_NAMESPACE;
>>> +
>>> +/**
>>> +  Log a formatted console message.
>>> +
>>> +  This is not specific to this shell command but scoped so to prevent
>> global
>>> +  name conflicts.
>>> +
>>> +  The hex dump is split into lines of 16 dumped bytes.
>>> +
>>> +  The full hex dump is bracketed, and its byte ascii char also print.
>>> +  If the byte value is not an ascii code, it will print as '.'
>>> +
>>> +  @param[in] Offset            Offset to be display after PrefixFormat.
>>> +                               Offset will be increased for each print
>>> line.
>>> +  @param[in] Data              The data to dump.
>>> +  @param[in] DataSize          Number of bytes in Data.
>>> +
>>> +**/
>>> +#define VAR_POLICY_CMD_SHELL_DUMP_HEX(Offset,
>>> \
>>> +                                      Data,
>>> \
>>> +                                      DataSize
>>> \
>>> +                                      )
>>> \
>>> +
>>> {
>>>                  \
>>> +          UINT8 *_DataToDump;
>>> \
>>> +          UINT8 _Val[50];
>>> \
>>> +          UINT8 _Str[20];
>>> \
>>> +          UINT8 _TempByte;
>>> \
>>> +          UINTN _Size;
>>> \
>>> +          UINTN _DumpHexIndex;
>>> \
>>> +          UINTN _LocalOffset;
>>> \
>>> +          UINTN _LocalDataSize;
>>> \
>>> +          CONST CHAR8 *_Hex = "0123456789ABCDEF";
>>> \
>>> +          _LocalOffset = (Offset);
>>> \
>>> +          _LocalDataSize = (DataSize);
>>> \
>>> +          _DataToDump = (UINT8 *)(Data);
>>> \
>>> +
>>> \
>>> +          ASSERT (_DataToDump != NULL);
>>> \
>>> +
>>> \
>>> +          while (_LocalDataSize != 0)
>>> {                                               \
>>> +            _Size = 16;
>>> \
>>> +            if (_Size > _LocalDataSize)
>>> {                                             \
>>> +              _Size = _LocalDataSize;
>>> \
>>> +            }
>>> \
>>> +
>>> \
>>> +            for (_DumpHexIndex = 0; _DumpHexIndex < _Size;
>>> _DumpHexIndex += 1) {      \
>>> +              _TempByte            = (UINT8)
>>> _DataToDump[_DumpHexIndex];              \
>>> +              _Val[_DumpHexIndex * 3 + 0]  = (UINT8)
>>> _Hex[_TempByte >> 4];            \
>>> +              _Val[_DumpHexIndex * 3 + 1]  = (UINT8)
>>> _Hex[_TempByte & 0xF];           \
>>> +              _Val[_DumpHexIndex * 3 + 2]  =
>>> \
>>> +                (CHAR8) ((_DumpHexIndex == 7) ? '-' : ' ');
>>> \
>>> +              _Str[_DumpHexIndex]          =
>>> \
>>> +                (CHAR8) ((_TempByte < ' ' || _TempByte > '~') ? '.' :
>>> _TempByte);     \
>>> +            }
>>> \
>>> +
>>> \
>>> +            _Val[_DumpHexIndex * 3]  = 0;
>>> \
>>> +            _Str[_DumpHexIndex]      = 0;
>>> \
>>> +
>>> \
>>> +            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_GEN_HEX_DUMP_LINE), mVarPolicyShellCommandHiiHandle,
>>> _LocalOffset, _Val, _Str); \
>>> +            _DataToDump = (UINT8 *)(((UINTN)_DataToDump) + _Size);
>>> \
>>> +            _LocalOffset += _Size;
>>> \
>>> +            _LocalDataSize -= _Size;
>>> \
>>> +          }
>>> \
>>> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
>>> (STR_GEN_LINE_BREAK), mVarPolicyShellCommandHiiHandle); \
>>> +        }
>>> +
>>> +#endif
>>> diff --git
>>>
>> a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.inf
>>>
>> b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.inf
>>> new file mode 100644
>>> index 000000000000..22b4baa5e6f2
>>> --- /dev/null
>>> +++
>>>
>> b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.inf
>>> @@ -0,0 +1,56 @@
>>> +##  @file
>>> +# A UEFI variable policy dynamic shell command that displays information
>>> +# about UEFI variable policy configuration on the system.
>>> +#
>>> +# Copyright (c) Microsoft Corporation.
>>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>>> +#
>>> +##
>>> +
>>> +[Defines]
>>> +  INF_VERSION                 = 1.27
>>> +  BASE_NAME                   = VariablePolicyDynamicCommand
>>> +  FILE_GUID                   =
>>> 17D0EF2A-5933-4007-8950-5749169D3DC5
>>> +  MODULE_TYPE                 = DXE_DRIVER
>>> +  VERSION_STRING              = 1.0
>>> +  ENTRY_POINT                 =
>>> VariablePolicyDynamicCommandEntryPoint
>>> +  UNLOAD_IMAGE                =
>>> VariablePolicyDynamicCommandUnload
>>> +  UEFI_HII_RESOURCE_SECTION   = TRUE
>>> +
>>> +[Sources.common]
>>> +  VariablePolicyDynamicCommand.c
>>> +  VariablePolicyDynamicCommand.h
>>> +  VariablePolicyDynamicCommand.uni
>>> +
>>> +[Packages]
>>> +  MdePkg/MdePkg.dec
>>> +  MdeModulePkg/MdeModulePkg.dec
>>> +  ShellPkg/ShellPkg.dec
>>> +
>>> +[LibraryClasses]
>>> +  BaseLib
>>> +  BaseMemoryLib
>>> +  DebugLib
>>> +  HiiLib
>>> +  MemoryAllocationLib
>>> +  PrintLib
>>> +  ShellLib
>>> +  UefiBootServicesTableLib
>>> +  UefiDriverEntryPoint
>>> +  UefiHiiServicesLib
>>> +  UefiRuntimeServicesTableLib
>>> +
>>> +[Protocols]
>>> +  gEdkiiVariablePolicyProtocolGuid            ##
>>> SOMETIMES_CONSUMES
>>> +  gEfiHiiPackageListProtocolGuid              ## CONSUMES
>>> +  gEfiShellDynamicCommandProtocolGuid         ## PRODUCES
>>> +
>>> +[Guids]
>>> +  ## SOMETIMES_CONSUMES ## Variables in Vendor Namespace
>>> +  gEfiCapsuleReportGuid
>>> +  gEfiCapsuleVendorGuid
>>> +  gEfiGlobalVariableGuid
>>> +  gEfiMemoryOverwriteRequestControlLockGuid
>>> +
>>> +[DEPEX]
>>> +  TRUE
>>> diff --git
>>>
>> a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.uni
>>>
>> b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.uni
>>> new file mode 100644
>>> index 000000000000..a65f477b41c3
>>> --- /dev/null
>>> +++
>>>
>> b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePoli
>>> cyDynamicCommand.uni
>>> @@ -0,0 +1,86 @@
>>> +// /**
>>> +// String definitions for the Variable Policy ("varpolicy") shell
>> command.
>>> +//
>>> +// Copyright (c) Microsoft Corporation.
>>> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>>> +//
>>> +// **/
>>> +
>>> +/=#
>>> +
>>> +#langdef   en-US "english"
>>> +
>>> +// General Strings
>>> +#string STR_GEN_PROBLEM               #language en-US "%H%s%N:
>>> Unknown flag - '%H%s%N'\r\n"
>>> +#string STR_GEN_TOO_MANY              #language en-US "%H%s%N:
>>> Too many arguments.\r\n"
>>> +#string STR_GEN_NO_VARS               #language en-US "No UEFI
>>> variables found!\r\n"
>>> +#string STR_GEN_LINE_BREAK            #language en-US "\r\n"
>>> +
>>> +#string STR_GEN_HEX_DUMP_LINE         #language en-US
>>> "%B%08X%N: %-48a %V*%a*%N\r\n"
>>> +
>>> +#string STR_VAR_POL_POLICY_INT_ERR     #language en-US "%EInternal
>>> Application Error Getting Policy Info!%N\r\n"
>>> +#string STR_VAR_POL_POLICY_NO_PROT     #language en-US
>>> "%EVariable Policy Protocol Was Not Found!%N\r\n"
>>> +#string STR_VAR_POL_POLICY_NOT_INIT    #language en-US "%EUEFI
>>> Variable Policy is Not Initialized!%N\r\n"
>>> +#string STR_VAR_POL_POLICY_NOT_FOUND   #language en-US
>>> "%EVariable Policy Not Found for This Variable!%N\r\n"
>>> +#string STR_VAR_POL_POLICY_UNEXP_ERR   #language en-US
>>> "%EUnexpected Error Getting Policy Info!%N - %H%r%N\r\n"
>>> +#string STR_VAR_POL_POLICY_HEADER_1    #language en-US
>>>
>> "+--------------------------------------------------------------------------
>> ---+\r\n"
>>> +#string STR_VAR_POL_POLICY_HEADER_2    #language en-US "| Variable
>>> Policy Info
>>> |\r\n"
>>> +#string STR_VAR_POL_POLICY_VERSION     #language en-US "| Version:
>>> 0x%-8x
>>> |\r\n"
>>> +#string STR_VAR_POL_POLICY_VARIABLE    #language en-US "| Variable: %
>>> -64s  |\r\n"
>>> +#string STR_VAR_POL_POLICY_NAMESPACE   #language en-US "|
>>> Namespace: {%g}                           |\r\n"
>>> +#string STR_VAR_POL_POLICY_MIN_SIZE    #language en-US "| Minimum
>>> Size: 0x%-8x
>>> |\r\n"
>>> +#string STR_VAR_POL_POLICY_MAX_SIZE    #language en-US "|
>>> Maximum Size: 0x%-8x
>>> |\r\n"
>>> +#string STR_VAR_POL_POLICY_ATTR_MUST   #language en-US "|
>>> Required Attributes:
>>> |\r\n"
>>> +#string STR_VAR_POL_POLICY_ATTR_NOT    #language en-US "|
>>> Disallowed Attributes:
>>> |\r\n"
>>> +#string STR_VAR_POL_POLICY_ATTR_GEN    #language en-US
>>> "|   %73-.73s |\r\n"
>>> +#string STR_VAR_POL_POLICY_LOCK_TYPE   #language en-US "| Lock
>>> Type: % -64s |\r\n"
>>> +#string STR_VAR_POL_POLICY_STATE_NS    #language en-US "|
>>> Namespace: {%g}                         |\r\n"
>>> +#string STR_VAR_POL_POLICY_STATE_VAL   #language en-US "|   Value:
>>> 0x%-8x
>>> |\r\n"
>>> +#string STR_VAR_POL_POLICY_STATE_NAME  #language en-US "|
>>> Name: % -64s    |\r\n"
>>> +#string STR_VAR_POL_POLICY_STATS_PASS  #language en-US
>>> "  %V%d/%d UEFI variables have policy%N\r\n"
>>> +#string STR_VAR_POL_POLICY_STATS_FAIL  #language en-US "  %E%d/%d
>>> UEFI variables have policy%N\r\n"
>>> +
>>> +#string STR_VAR_POL_VAR_TYPE         #language en-US "%H%
>>> -70s%N\r\n"
>>> +#string STR_VAR_POL_VAR_NAME         #language en-US "Name: %
>>> -70s\r\n"
>>> +#string STR_VAR_POL_VAR_SIZE         #language en-US "Size: 0x%-16x
>>> (%-,d) bytes\r\n"
>>> +#string STR_VAR_POL_VAR_ATTR         #language en-US "Attributes: %
>>> -60s\r\n"
>>> +
>>> +#string STR_VAR_POL_STATS_HEADER_1   #language en-US
>>> "+----------------------------------------------------------------+\r\n"
>>> +#string STR_VAR_POL_STATS_HEADER_2   #language en-US "| UEFI
>>> Variable Statistics                                       |\r\n"
>>> +#string STR_VAR_POL_STATS_TOTAL_VARS #language en-US "  Total UEFI
>>> Variables: %,d\r\n"
>>> +#string STR_VAR_POL_STATS_TOTAL_SIZE #language en-US "  Total UEFI
>>> Variable Size: 0x%x (%,d) bytes\r\n"
>>> +
>>> +#string STR_GET_HELP_VAR_POLICY      #language en-US ""
>>> +".TH varpolicy 0 "Lists UEFI variable policy information."\r\n"
>>> +".SH NAME\r\n"
>>> +"Lists UEFI variable policy information.\r\n"
>>> +".SH SYNOPSIS\r\n"
>>> +" \r\n"
>>> +"VARPOLICY [-p] [-s] [-v]\r\n"
>>> +".SH OPTIONS\r\n"
>>> +" \r\n"
>>> +"  -p - The policy flag will print variable policy info for each
>> variable.\r\n"
>>> +" \r\n"
>>> +"  -s - The stats flag will print overall UEFI variable policy
>> statistics.\r\n"
>>> +" \r\n"
>>> +"  -v - The verbose flag indicates all known information should be
>>> printed.\r\n"
>>> +" \r\n"
>>> +"       This includes a dump of the corresponding UEFI variable data
>>> in\r\n"
>>> +"       addition to all other UEFI variable policy information.\r\n"
>>> +".SH DESCRIPTION\r\n"
>>> +" \r\n"
>>> +".SH EXAMPLES\r\n"
>>> +" \r\n"
>>> +"EXAMPLES:\r\n"
>>> +"  * To dump all active UEFI variables:\r\n"
>>> +"    fs0:\> varpolicy\r\n"
>>> +"\r\n"
>>> +"  * To include UEFI variable policy information:\r\n"
>>> +"    fs0:\> varpolicy -p\r\n"
>>> +"\r\n"
>>> +"  * To include UEFI variable statistics:\r\n"
>>> +"    fs0:\> varpolicy -s\r\n"
>>> +"\r\n"
>>> +"  * To include a hexadecimal dump of data for each variable\r\n"
>>> +"    and all other variable information:\r\n"
>>> +"    fs0:\> varpolicy -v\r\n"
>>> diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc
>>> index dd0d88603f11..c0a8a8f12bd5 100644
>>> --- a/ShellPkg/ShellPkg.dsc
>>> +++ b/ShellPkg/ShellPkg.dsc
>>> @@ -154,6 +154,7 @@ [Components]
>>>         gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
>>>     }
>>>     ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf
>>> +
>>>
>> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy
>>> DynamicCommand.inf
>>>     ShellPkg/Application/AcpiViewApp/AcpiViewApp.inf
>>>
>>>   [BuildOptions]
>>> --
>>> 2.42.0.windows.2
>>>
>>>
>>>
>>> -=-=-=-=-=-=
>>> Groups.io Links: You receive all messages sent to this group.
>>> View/Reply Online (#108842):
>>> https://edk2.groups.io/g/devel/message/108842
>>> Mute This Topic: https://groups.io/mt/101457414/4905953
>>> Group Owner: devel+owner at edk2.groups.io
>>> Unsubscribe: https://edk2.groups.io/g/devel/unsub
>>> [gaoliming at byosoft.com.cn]
>>> -=-=-=-=-=-=
>>>
>>
>>
>>
>>
>>
>>
>>
> 
> 
> 
> 
> 
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#110012): https://edk2.groups.io/g/devel/message/110012
Mute This Topic: https://groups.io/mt/102152885/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