* [edk2-devel] [PATCH v1 0/3] Add Variable Policy Audit and Shell Command
@ 2023-09-19 14:32 Michael Kubacki
2023-09-19 14:32 ` [edk2-devel] [PATCH v1 1/3] MdeModulePkg/VariablePolicy: Add more granular variable policy querying Michael Kubacki
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Michael Kubacki @ 2023-09-19 14:32 UTC (permalink / raw)
To: devel
Cc: Anatol Belski, Anthony Perard, Dandan Bi, Gerd Hoffmann, Hao A Wu,
Jian J Wang, Jianyong Wu, Jiewen Yao, Jordan Justen, Julien Grall,
Liming Gao, Michael D Kinney, Zhichao Gao
From: Michael Kubacki <michael.kubacki@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.
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.
The shell command is added to OvmfPkg so it is available in an
easily obtainable virtual platform.
This is being made available to ease auditing and enabling of UEFI
variable policy to encourage its adoption for securing UEFI
variables.
---
Command Help:
Lists UEFI variable policy information.
VARPOLICY [-p] [-s] [-v]
-p - The policy flag will print variable policy info for each variable.
-s - The stats flag will print overall UEFI variable policy statistics.
-v - The verbose flag indicates all known information should be printed.
This includes a dump of the corresponding UEFI variable data in
addition to all other UEFI variable policy information.
EXAMPLES:
* To dump all active UEFI variables:
fs0:\> varpolicy
* To include UEFI variable policy information:
varpolicy -p
* To include UEFI variable statistics:
varpolicy -s
Press ENTER to continue or 'Q' break:
---
Images showing example output are available in the PR:
https://github.com/tianocore/edk2/pull/4835
Cc: Anatol Belski <anbelski@linux.microsoft.com>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Jianyong Wu <jianyong.wu@arm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Julien Grall <julien@xen.org>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Zhichao Gao <zhichao.gao@intel.com>
Michael Kubacki (3):
MdeModulePkg/VariablePolicy: Add more granular variable policy
querying
ShellPkg: Add varpolicy dynamic shell command
OvmfPkg: Add varpolicy shell command
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c | 174 +++-
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c | 304 ++++++
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c | 4 +-
MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c | 346 ++++++-
ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.c | 1009 ++++++++++++++++++++
MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h | 39 +-
MdeModulePkg/Include/Library/VariablePolicyLib.h | 107 +++
MdeModulePkg/Include/Protocol/VariablePolicy.h | 133 ++-
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf | 1 +
OvmfPkg/CloudHv/CloudHvX64.dsc | 4 +
OvmfPkg/Microvm/MicrovmX64.dsc | 4 +
OvmfPkg/OvmfPkgIa32.dsc | 4 +
OvmfPkg/OvmfPkgIa32X64.dsc | 4 +
OvmfPkg/OvmfPkgX64.dsc | 4 +
OvmfPkg/OvmfXen.dsc | 4 +
ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.h | 94 ++
ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf | 56 ++
ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.uni | 86 ++
ShellPkg/ShellPkg.dsc | 1 +
19 files changed, 2332 insertions(+), 46 deletions(-)
create mode 100644 ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.c
create mode 100644 ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.h
create mode 100644 ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf
create mode 100644 ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.uni
--
2.42.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#108840): https://edk2.groups.io/g/devel/message/108840
Mute This Topic: https://groups.io/mt/101457406/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 10+ messages in thread
* [edk2-devel] [PATCH v1 1/3] MdeModulePkg/VariablePolicy: Add more granular variable policy querying
2023-09-19 14:32 [edk2-devel] [PATCH v1 0/3] Add Variable Policy Audit and Shell Command Michael Kubacki
@ 2023-09-19 14:32 ` Michael Kubacki
2023-10-24 5:11 ` 回复: " gaoliming via groups.io
2023-09-19 14:32 ` [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell command Michael Kubacki
2023-09-19 14:33 ` [edk2-devel] [PATCH v1 3/3] OvmfPkg: Add varpolicy " Michael Kubacki
2 siblings, 1 reply; 10+ messages in thread
From: Michael Kubacki @ 2023-09-19 14:32 UTC (permalink / raw)
To: devel; +Cc: Dandan Bi, Hao A Wu, Jian J Wang, Liming Gao
From: Michael Kubacki <michael.kubacki@microsoft.com>
Introduces two new APIs to EDKII_VARIABLE_POLICY_PROTOCOL:
1. GetVariablePolicyInfo()
2. GetLockOnVariableStateVariablePolicyInfo()
These allow a caller to retrieve policy information associated with
a UEFI variable given the variable name and vendor GUID.
GetVariablePolicyInfo() - Returns the variable policy applied to the
UEFI variable. If the variable policy is applied toward an individual
UEFI variable, that name can optionally be returned.
GetLockOnVariableStateVariablePolicyInfo() - Returns the Lock on
Variable State policy applied to the UEFI variable. If the Lock on
Variable State policy is applied to a specific variable name, that
name can optionally be returned.
These functions can be useful for a variety of purposes such as
auditing, testing, and functional flows.
Also fixed some variable name typos in code touched by the changes.
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c | 174 ++++++++--
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c | 304 +++++++++++++++++
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c | 4 +-
MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c | 346 +++++++++++++++++++-
MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h | 39 ++-
MdeModulePkg/Include/Library/VariablePolicyLib.h | 107 ++++++
MdeModulePkg/Include/Protocol/VariablePolicy.h | 133 +++++++-
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf | 1 +
8 files changed, 1062 insertions(+), 46 deletions(-)
diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
index 5de46133bb26..1448af85555a 100644
--- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
+++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
@@ -76,14 +76,20 @@ VarCheckPolicyLibMmiHandler (
VOID *InternalCommBuffer;
EFI_STATUS Status;
EFI_STATUS SubCommandStatus;
- VAR_CHECK_POLICY_COMM_HEADER *PolicyCommmHeader;
- VAR_CHECK_POLICY_COMM_HEADER *InternalPolicyCommmHeader;
+ VAR_CHECK_POLICY_COMM_HEADER *PolicyCommHeader;
+ VAR_CHECK_POLICY_COMM_HEADER *InternalPolicyCommHeader;
VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *IsEnabledParams;
VAR_CHECK_POLICY_COMM_DUMP_PARAMS *DumpParamsIn;
VAR_CHECK_POLICY_COMM_DUMP_PARAMS *DumpParamsOut;
+ VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS *GetInfoParamsInternal;
+ VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS *GetInfoParamsExternal;
+ CHAR16 *InternalCopyOfOutputVariableName;
+ CHAR16 *ExternalCopyOfOutputVariableName;
UINT8 *DumpInputBuffer;
UINT8 *DumpOutputBuffer;
+ UINTN AllowedOutputVariableNameSize;
UINTN DumpTotalPages;
+ UINTN LocalSize;
VARIABLE_POLICY_ENTRY *PolicyEntry;
UINTN ExpectedSize;
UINT32 TempSize;
@@ -122,21 +128,21 @@ VarCheckPolicyLibMmiHandler (
//
InternalCommBuffer = &mSecurityEvalBuffer[0];
CopyMem (InternalCommBuffer, CommBuffer, InternalCommBufferSize);
- PolicyCommmHeader = CommBuffer;
- InternalPolicyCommmHeader = InternalCommBuffer;
+ PolicyCommHeader = CommBuffer;
+ InternalPolicyCommHeader = InternalCommBuffer;
// Check the revision and the signature of the comm header.
- if ((InternalPolicyCommmHeader->Signature != VAR_CHECK_POLICY_COMM_SIG) ||
- (InternalPolicyCommmHeader->Revision != VAR_CHECK_POLICY_COMM_REVISION))
+ if ((InternalPolicyCommHeader->Signature != VAR_CHECK_POLICY_COMM_SIG) ||
+ (InternalPolicyCommHeader->Revision != VAR_CHECK_POLICY_COMM_REVISION))
{
DEBUG ((DEBUG_INFO, "%a - Signature or revision are incorrect!\n", __func__));
// We have verified the buffer is not null and have enough size to hold Result field.
- PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
+ PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
return EFI_SUCCESS;
}
// If we're in the middle of a paginated dump and any other command is sent,
// pagination cache must be cleared.
- if ((mPaginationCache != NULL) && (InternalPolicyCommmHeader->Command != mCurrentPaginationCommand)) {
+ if ((mPaginationCache != NULL) && (InternalPolicyCommHeader->Command != mCurrentPaginationCommand)) {
FreePool (mPaginationCache);
mPaginationCache = NULL;
mPaginationCacheSize = 0;
@@ -146,10 +152,10 @@ VarCheckPolicyLibMmiHandler (
//
// Now we can process the command as it was sent.
//
- PolicyCommmHeader->Result = EFI_ABORTED; // Set a default return for incomplete commands.
- switch (InternalPolicyCommmHeader->Command) {
+ PolicyCommHeader->Result = EFI_ABORTED; // Set a default return for incomplete commands.
+ switch (InternalPolicyCommHeader->Command) {
case VAR_CHECK_POLICY_COMMAND_DISABLE:
- PolicyCommmHeader->Result = DisableVariablePolicy ();
+ PolicyCommHeader->Result = DisableVariablePolicy ();
break;
case VAR_CHECK_POLICY_COMMAND_IS_ENABLED:
@@ -158,14 +164,14 @@ VarCheckPolicyLibMmiHandler (
ExpectedSize += sizeof (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS);
if (InternalCommBufferSize < ExpectedSize) {
DEBUG ((DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __func__, InternalCommBufferSize, ExpectedSize));
- PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
+ PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
break;
}
// Now that we know we've got a valid size, we can fill in the rest of the data.
- IsEnabledParams = (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *)((UINT8 *)CommBuffer + sizeof (VAR_CHECK_POLICY_COMM_HEADER));
- IsEnabledParams->State = IsVariablePolicyEnabled ();
- PolicyCommmHeader->Result = EFI_SUCCESS;
+ IsEnabledParams = (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *)((UINT8 *)CommBuffer + sizeof (VAR_CHECK_POLICY_COMM_HEADER));
+ IsEnabledParams->State = IsVariablePolicyEnabled ();
+ PolicyCommHeader->Result = EFI_SUCCESS;
break;
case VAR_CHECK_POLICY_COMMAND_REGISTER:
@@ -174,7 +180,7 @@ VarCheckPolicyLibMmiHandler (
ExpectedSize += sizeof (VARIABLE_POLICY_ENTRY);
if (InternalCommBufferSize < ExpectedSize) {
DEBUG ((DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __func__, InternalCommBufferSize, ExpectedSize));
- PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
+ PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
break;
}
@@ -187,11 +193,11 @@ VarCheckPolicyLibMmiHandler (
(InternalCommBufferSize < ExpectedSize))
{
DEBUG ((DEBUG_INFO, "%a - Bad policy entry contents!\n", __func__));
- PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
+ PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
break;
}
- PolicyCommmHeader->Result = RegisterVariablePolicy (PolicyEntry);
+ PolicyCommHeader->Result = RegisterVariablePolicy (PolicyEntry);
break;
case VAR_CHECK_POLICY_COMMAND_DUMP:
@@ -200,13 +206,13 @@ VarCheckPolicyLibMmiHandler (
ExpectedSize += sizeof (VAR_CHECK_POLICY_COMM_DUMP_PARAMS) + VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;
if (InternalCommBufferSize < ExpectedSize) {
DEBUG ((DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __func__, InternalCommBufferSize, ExpectedSize));
- PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
+ PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
break;
}
// Now that we know we've got a valid size, we can fill in the rest of the data.
- DumpParamsIn = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS *)(InternalPolicyCommmHeader + 1);
- DumpParamsOut = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS *)(PolicyCommmHeader + 1);
+ DumpParamsIn = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS *)(InternalPolicyCommHeader + 1);
+ DumpParamsOut = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS *)(PolicyCommHeader + 1);
// If we're requesting the first page, initialize the cache and get the sizes.
if (DumpParamsIn->PageRequested == 0) {
@@ -289,17 +295,131 @@ VarCheckPolicyLibMmiHandler (
}
// There's currently no use for this, but it shouldn't be hard to implement.
- PolicyCommmHeader->Result = SubCommandStatus;
+ PolicyCommHeader->Result = SubCommandStatus;
break;
case VAR_CHECK_POLICY_COMMAND_LOCK:
- PolicyCommmHeader->Result = LockVariablePolicy ();
+ PolicyCommHeader->Result = LockVariablePolicy ();
+ break;
+
+ case VAR_CHECK_POLICY_COMMAND_GET_INFO:
+ case VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO:
+ ExpectedSize += VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END + VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE;
+
+ if (InternalCommBufferSize < ExpectedSize) {
+ PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ GetInfoParamsInternal = (VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS *)(InternalPolicyCommHeader + 1);
+ GetInfoParamsExternal = (VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS *)(PolicyCommHeader + 1);
+
+ SubCommandStatus = SafeUintnSub (
+ VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE,
+ GetInfoParamsInternal->InputVariableNameSize,
+ &AllowedOutputVariableNameSize
+ );
+ if (EFI_ERROR (SubCommandStatus)) {
+ PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (GetInfoParamsInternal->OutputVariableNameSize > 0) {
+ SubCommandStatus = SafeUintnAdd (
+ ((UINTN)GetInfoParamsInternal + VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END),
+ (UINTN)GetInfoParamsInternal->InputVariableNameSize,
+ (UINTN *)&InternalCopyOfOutputVariableName
+ );
+ if (EFI_ERROR (SubCommandStatus)) {
+ PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
+ break;
+ }
+ } else {
+ InternalCopyOfOutputVariableName = NULL;
+ }
+
+ ZeroMem (&GetInfoParamsInternal->OutputPolicyEntry, sizeof (GetInfoParamsInternal->OutputPolicyEntry));
+ ZeroMem (&GetInfoParamsExternal->OutputPolicyEntry, sizeof (GetInfoParamsExternal->OutputPolicyEntry));
+
+ LocalSize = (UINTN)GetInfoParamsInternal->OutputVariableNameSize;
+
+ if (InternalPolicyCommHeader->Command == VAR_CHECK_POLICY_COMMAND_GET_INFO) {
+ SubCommandStatus = GetVariablePolicyInfo (
+ GetInfoParamsInternal->InputVariableName,
+ &GetInfoParamsInternal->InputVendorGuid,
+ &LocalSize,
+ &GetInfoParamsInternal->OutputPolicyEntry.VariablePolicy,
+ InternalCopyOfOutputVariableName
+ );
+ } else if (InternalPolicyCommHeader->Command == VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO) {
+ SubCommandStatus = GetLockOnVariableStateVariablePolicyInfo (
+ GetInfoParamsInternal->InputVariableName,
+ &GetInfoParamsInternal->InputVendorGuid,
+ &LocalSize,
+ &GetInfoParamsInternal->OutputPolicyEntry.LockOnVarStatePolicy,
+ InternalCopyOfOutputVariableName
+ );
+ } else {
+ PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (EFI_ERROR (SubCommandStatus) && (SubCommandStatus != EFI_BUFFER_TOO_SMALL)) {
+ PolicyCommHeader->Result = SubCommandStatus;
+ break;
+ }
+
+ if (EFI_ERROR (SafeUintnToUint32 (LocalSize, &GetInfoParamsInternal->OutputVariableNameSize))) {
+ PolicyCommHeader->Result = EFI_BAD_BUFFER_SIZE;
+ break;
+ }
+
+ ASSERT (sizeof (GetInfoParamsInternal->OutputPolicyEntry) == sizeof (GetInfoParamsExternal->OutputPolicyEntry));
+ CopyMem (
+ &GetInfoParamsExternal->OutputPolicyEntry,
+ &GetInfoParamsInternal->OutputPolicyEntry,
+ sizeof (GetInfoParamsExternal->OutputPolicyEntry)
+ );
+
+ GetInfoParamsExternal->OutputVariableNameSize = GetInfoParamsInternal->OutputVariableNameSize;
+ if (SubCommandStatus == EFI_BUFFER_TOO_SMALL) {
+ PolicyCommHeader->Result = EFI_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ SubCommandStatus = SafeUintnAdd (
+ ((UINTN)GetInfoParamsExternal + VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END),
+ (UINTN)GetInfoParamsInternal->InputVariableNameSize,
+ (UINTN *)&ExternalCopyOfOutputVariableName
+ );
+ if (EFI_ERROR (SubCommandStatus)) {
+ PolicyCommHeader->Result = EFI_BAD_BUFFER_SIZE;
+ break;
+ }
+
+ if (GetInfoParamsInternal->OutputVariableNameSize > 0) {
+ SubCommandStatus = StrnCpyS (
+ ExternalCopyOfOutputVariableName,
+ AllowedOutputVariableNameSize,
+ InternalCopyOfOutputVariableName,
+ (UINTN)GetInfoParamsInternal->OutputVariableNameSize
+ );
+ ASSERT_EFI_ERROR (SubCommandStatus);
+ } else {
+ // The comm buffer should always have the space for the variable policy output
+ // variable name. Fill it with NULL chars if a variable name is not present so
+ // it has a consistent value in the case of variable name absence.
+ SetMem (ExternalCopyOfOutputVariableName, AllowedOutputVariableNameSize, CHAR_NULL);
+ }
+
+ PolicyCommHeader->Result = SubCommandStatus;
+
break;
default:
// Mark unknown requested command as EFI_UNSUPPORTED.
- DEBUG ((DEBUG_INFO, "%a - Invalid command requested! %d\n", __func__, PolicyCommmHeader->Command));
- PolicyCommmHeader->Result = EFI_UNSUPPORTED;
+ DEBUG ((DEBUG_INFO, "%a - Invalid command requested! %d\n", __func__, PolicyCommHeader->Command));
+ PolicyCommHeader->Result = EFI_UNSUPPORTED;
break;
}
@@ -307,8 +427,8 @@ VarCheckPolicyLibMmiHandler (
DEBUG_VERBOSE,
"%a - Command %d returning %r.\n",
__func__,
- PolicyCommmHeader->Command,
- PolicyCommmHeader->Result
+ PolicyCommHeader->Command,
+ PolicyCommHeader->Result
));
return Status;
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
index 214f76ab9626..768662829dbf 100644
--- a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
@@ -8,6 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Uefi.h>
+#include <Library/BaseLib.h>
#include <Library/SafeIntLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
@@ -684,6 +685,309 @@ DumpVariablePolicy (
return EFI_SUCCESS;
}
+/**
+ This function will return variable policy information for a UEFI variable with a
+ registered variable policy.
+
+ @param[in] VariableName The name of the variable to use for the policy search.
+ @param[in] VendorGuid The vendor GUID of the variable to use for the policy search.
+ @param[in,out] VariablePolicyVariableNameBufferSize On input, the size, in bytes, of the VariablePolicyVariableName
+ buffer.
+
+ On output, the size, in bytes, needed to store the variable
+ policy variable name.
+
+ If testing for the VariablePolicyVariableName buffer size
+ needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
+ guaranteed to be returned if the variable policy variable name
+ is found.
+ @param[out] VariablePolicy Pointer to a buffer where the policy entry will be written
+ if found.
+ @param[out] VariablePolicyVariableName Pointer to a buffer where the variable name used for the
+ variable policy will be written if a variable name is
+ registered.
+
+ If the variable policy is not associated with a variable name
+ (e.g. applied to variable vendor namespace) and this parameter
+ is given, this parameter will not be modified and
+ VariablePolicyVariableNameBufferSize will be set to zero to
+ indicate a name was not present.
+
+ If the pointer given is not NULL,
+ VariablePolicyVariableNameBufferSize must be non-NULL.
+
+ @retval EFI_SUCCESS A variable policy entry was found and returned successfully.
+ @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused a calculation error.
+ @retval EFI_BUFFER_TOO_SMALL The VariablePolicyVariableName buffer value is too small for the size needed.
+ The buffer should now point to the size needed.
+ @retval EFI_NOT_READY Variable policy has not yet been initialized.
+ @retval EFI_INVALID_PARAMETER A required pointer argument passed is NULL. This will be returned if
+ VariablePolicyVariableName is non-NULL and VariablePolicyVariableNameBufferSize
+ is NULL.
+ @retval EFI_NOT_FOUND A variable policy was not found for the given UEFI variable name and vendor GUID.
+
+**/
+EFI_STATUS
+EFIAPI
+GetVariablePolicyInfo (
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ IN OUT UINTN *VariablePolicyVariableNameBufferSize OPTIONAL,
+ OUT VARIABLE_POLICY_ENTRY *VariablePolicy,
+ OUT CHAR16 *VariablePolicyVariableName OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT8 MatchPriority;
+ UINTN LocalVariablePolicyVariableNameBufferSize;
+ UINTN RequiredVariablePolicyVariableNameBufferSize;
+ VARIABLE_POLICY_ENTRY *MatchPolicy;
+
+ Status = EFI_SUCCESS;
+
+ if (!IsVariablePolicyLibInitialized ()) {
+ return EFI_NOT_READY;
+ }
+
+ if ((VariableName == NULL) || (VendorGuid == NULL) || (VariablePolicy == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MatchPolicy = GetBestPolicyMatch (
+ VariableName,
+ VendorGuid,
+ &MatchPriority
+ );
+ if (MatchPolicy != NULL) {
+ CopyMem (VariablePolicy, MatchPolicy, sizeof (*VariablePolicy));
+
+ if (VariablePolicyVariableNameBufferSize == NULL) {
+ if (VariablePolicyVariableName != NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+ }
+
+ if (MatchPolicy->Size != MatchPolicy->OffsetToName) {
+ if (MatchPolicy->Size < MatchPolicy->OffsetToName) {
+ ASSERT (MatchPolicy->Size > MatchPolicy->OffsetToName);
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ RequiredVariablePolicyVariableNameBufferSize = (UINTN)(MatchPolicy->Size - MatchPolicy->OffsetToName);
+ ASSERT (RequiredVariablePolicyVariableNameBufferSize > 0);
+
+ if (*VariablePolicyVariableNameBufferSize < RequiredVariablePolicyVariableNameBufferSize) {
+ // Let the caller get the size needed to hold the policy variable name
+ *VariablePolicyVariableNameBufferSize = RequiredVariablePolicyVariableNameBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (VariablePolicyVariableName == NULL) {
+ // If the policy variable name size given is valid, then a valid policy variable name buffer should be provided
+ *VariablePolicyVariableNameBufferSize = RequiredVariablePolicyVariableNameBufferSize;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ LocalVariablePolicyVariableNameBufferSize = *VariablePolicyVariableNameBufferSize;
+
+ // Actual string size should match expected string size
+ if (
+ ((StrnLenS (GET_POLICY_NAME (MatchPolicy), RequiredVariablePolicyVariableNameBufferSize) + 1) * sizeof (CHAR16))
+ != RequiredVariablePolicyVariableNameBufferSize)
+ {
+ ASSERT_EFI_ERROR (EFI_BAD_BUFFER_SIZE);
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ *VariablePolicyVariableNameBufferSize = RequiredVariablePolicyVariableNameBufferSize;
+
+ Status = StrnCpyS (
+ VariablePolicyVariableName,
+ LocalVariablePolicyVariableNameBufferSize / sizeof (CHAR16),
+ GET_POLICY_NAME (MatchPolicy),
+ RequiredVariablePolicyVariableNameBufferSize / sizeof (CHAR16)
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ // A variable policy variable name is not present. Return values according to interface.
+ *VariablePolicyVariableNameBufferSize = 0;
+ }
+
+ return Status;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This function will return the Lock on Variable State policy information for the policy
+ associated with the given UEFI variable.
+
+ @param[in] VariableName The name of the variable to use for the policy search.
+ @param[in] VendorGuid The vendor GUID of the variable to use for the policy
+ search.
+ @param[in,out] VariableLockPolicyVariableNameBufferSize On input, the size, in bytes, of the
+ VariableLockPolicyVariableName buffer.
+
+ On output, the size, in bytes, needed to store the variable
+ policy variable name.
+
+ If testing for the VariableLockPolicyVariableName buffer
+ size needed, set this value to zero so EFI_BUFFER_TOO_SMALL
+ is guaranteed to be returned if the variable policy variable
+ name is found.
+ @param[out] VariablePolicy Pointer to a buffer where the policy entry will be written
+ if found.
+ @param[out] VariableLockPolicyVariableName Pointer to a buffer where the variable name used for the
+ variable lock on variable state policy will be written if
+ a variable name is registered.
+
+ If the lock on variable policy is not associated with a
+ variable name (e.g. applied to variable vendor namespace)
+ and this parameter is given, this parameter will not be
+ modified and VariableLockPolicyVariableNameBufferSize will
+ be set to zero to indicate a name was not present.
+
+ If the pointer given is not NULL,
+ VariableLockPolicyVariableNameBufferSize must be non-NULL.
+
+ @retval EFI_SUCCESS A Lock on Variable State variable policy entry was found and returned
+ successfully.
+ @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused a calculation error.
+ @retval EFI_BUFFER_TOO_SMALL The VariableLockPolicyVariableName buffer is too small for the size needed.
+ The buffer should now point to the size needed.
+ @retval EFI_NOT_READY Variable policy has not yet been initialized.
+ @retval EFI_INVALID_PARAMETER A required pointer argument passed is NULL. This will be returned if
+ VariableLockPolicyVariableName is non-NULL and
+ VariableLockPolicyVariableNameBufferSize is NULL.
+ @retval EFI_NOT_FOUND A Lock on Variable State variable policy was not found for the given UEFI
+ variable name and vendor GUID.
+
+**/
+EFI_STATUS
+EFIAPI
+GetLockOnVariableStateVariablePolicyInfo (
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ IN OUT UINTN *VariableLockPolicyVariableNameBufferSize OPTIONAL,
+ OUT VARIABLE_LOCK_ON_VAR_STATE_POLICY *VariablePolicy,
+ OUT CHAR16 *VariableLockPolicyVariableName OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT8 MatchPriority;
+ UINTN RequiredVariablePolicyVariableNameBufferSize;
+ UINTN RequiredVariableLockPolicyVariableNameBufferSize;
+ UINTN LocalVariablePolicyLockVariableNameBufferSize;
+ UINTN LockOnVarStatePolicyEndOffset;
+ CHAR16 *LocalVariableLockPolicyVariableName;
+ VARIABLE_LOCK_ON_VAR_STATE_POLICY *LocalLockOnVarStatePolicy;
+ VARIABLE_POLICY_ENTRY *MatchPolicy;
+
+ Status = EFI_SUCCESS;
+
+ if (!IsVariablePolicyLibInitialized ()) {
+ return EFI_NOT_READY;
+ }
+
+ if ((VariableName == NULL) || (VendorGuid == NULL) || (VariablePolicy == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MatchPolicy = GetBestPolicyMatch (
+ VariableName,
+ VendorGuid,
+ &MatchPriority
+ );
+ if (MatchPolicy != NULL) {
+ if (MatchPolicy->LockPolicyType != VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = SafeUintnAdd (
+ sizeof (VARIABLE_POLICY_ENTRY),
+ sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY),
+ &LockOnVarStatePolicyEndOffset
+ );
+ if (EFI_ERROR (Status) || (LockOnVarStatePolicyEndOffset > (UINTN)MatchPolicy->Size)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ LocalLockOnVarStatePolicy = (VARIABLE_LOCK_ON_VAR_STATE_POLICY *)(MatchPolicy + 1);
+ CopyMem (VariablePolicy, LocalLockOnVarStatePolicy, sizeof (*LocalLockOnVarStatePolicy));
+
+ if ((VariableLockPolicyVariableNameBufferSize == NULL)) {
+ if (VariableLockPolicyVariableName != NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+ }
+
+ // The name offset should be less than or equal to the total policy size.
+ if (MatchPolicy->Size < MatchPolicy->OffsetToName) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ RequiredVariablePolicyVariableNameBufferSize = (UINTN)(MatchPolicy->Size - MatchPolicy->OffsetToName);
+ RequiredVariableLockPolicyVariableNameBufferSize = MatchPolicy->Size -
+ (LockOnVarStatePolicyEndOffset + RequiredVariablePolicyVariableNameBufferSize);
+
+ LocalVariablePolicyLockVariableNameBufferSize = *VariableLockPolicyVariableNameBufferSize;
+ *VariableLockPolicyVariableNameBufferSize = RequiredVariableLockPolicyVariableNameBufferSize;
+
+ if (LocalVariablePolicyLockVariableNameBufferSize < RequiredVariableLockPolicyVariableNameBufferSize) {
+ // Let the caller get the size needed to hold the policy variable name
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (VariableLockPolicyVariableName == NULL) {
+ // If the policy variable name size given is valid, then a valid policy variable name buffer should be provided
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (RequiredVariableLockPolicyVariableNameBufferSize == 0) {
+ return Status;
+ }
+
+ LocalVariableLockPolicyVariableName = (CHAR16 *)((UINT8 *)LocalLockOnVarStatePolicy + sizeof (*LocalLockOnVarStatePolicy));
+ *VariableLockPolicyVariableNameBufferSize = RequiredVariableLockPolicyVariableNameBufferSize;
+
+ // Actual string size should match expected string size (if a variable name is present)
+ if (
+ (RequiredVariablePolicyVariableNameBufferSize > 0) &&
+ (((StrnLenS (GET_POLICY_NAME (MatchPolicy), RequiredVariablePolicyVariableNameBufferSize) + 1) * sizeof (CHAR16)) !=
+ RequiredVariablePolicyVariableNameBufferSize))
+ {
+ ASSERT_EFI_ERROR (EFI_BAD_BUFFER_SIZE);
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ // Actual string size should match expected string size (if here, variable lock variable name is present)
+ if (
+ ((StrnLenS (LocalVariableLockPolicyVariableName, RequiredVariableLockPolicyVariableNameBufferSize) + 1) * sizeof (CHAR16)) !=
+ RequiredVariableLockPolicyVariableNameBufferSize)
+ {
+ ASSERT_EFI_ERROR (EFI_BAD_BUFFER_SIZE);
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ Status = StrnCpyS (
+ VariableLockPolicyVariableName,
+ LocalVariablePolicyLockVariableNameBufferSize / sizeof (CHAR16),
+ LocalVariableLockPolicyVariableName,
+ RequiredVariableLockPolicyVariableNameBufferSize / sizeof (CHAR16)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
/**
This API function returns whether or not the policy engine is
currently being enforced.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
index d5c409c914d1..c4ccdfd20f74 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
@@ -33,7 +33,9 @@ EDKII_VARIABLE_POLICY_PROTOCOL mVariablePolicyProtocol = {
ProtocolIsVariablePolicyEnabled,
RegisterVariablePolicy,
DumpVariablePolicy,
- LockVariablePolicy
+ LockVariablePolicy,
+ GetVariablePolicyInfo,
+ GetLockOnVariableStateVariablePolicyInfo
};
EDKII_VAR_CHECK_PROTOCOL mVarCheck = {
VarCheckRegisterSetVariableCheckHandler,
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
index 6151a2ba0b18..0dd72dde27ce 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
@@ -410,6 +410,338 @@ ProtocolLockVariablePolicy (
return (EFI_ERROR (Status)) ? Status : PolicyHeader->Result;
}
+/**
+ Internal implementation to retrieve variable information for a given UEFI variable that is shared
+ between different policy types.
+
+ Currently, the two policy structure types supported (and all that is defined) are VARIABLE_POLICY_ENTRY
+ and VARIABLE_LOCK_ON_VAR_STATE_POLICY.
+
+ @param[in] Command The command value to use in the communicate call.
+ @param[in] VariableName The name of the variable to use for the policy search.
+ @param[in] VendorGuid The vendor GUID of the variable to use for the policy search.
+ @param[in,out] VariablePolicyVariableNameBufferSize On input, the size, in bytes, of the VariablePolicyVariableName
+ buffer.
+
+ On output, the size, in bytes, needed to store the variable
+ policy variable name.
+
+ If testing for the VariablePolicyVariableName buffer size
+ needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
+ guaranteed to be returned if the variable policy variable name
+ is found.
+ @param[out] VariablePolicy Pointer to a buffer where the policy entry will be written
+ if found.
+ @param[out] VariablePolicyVariableName Pointer to a buffer where the variable name used for the
+ variable policy will be written if a variable name is
+ registered.
+
+ If the variable policy is not associated with a variable name
+ (e.g. applied to variable vendor namespace) and this parameter
+ is given, this parameter will not be modified and
+ VariablePolicyVariableNameBufferSize will be set to zero to
+ indicate a name was not present.
+
+ If the pointer given is not NULL,
+ VariablePolicyVariableNameBufferSize must be non-NULL.
+
+ @retval EFI_SUCCESS A variable policy entry was found and returned successfully.
+ @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused a calculation error.
+ @retval EFI_BUFFER_TOO_SMALL The VariablePolicyVariableName buffer value is too small for the size needed.
+ The buffer should now point to the size needed.
+ @retval EFI_NOT_READY Variable policy has not yet been initialized.
+ @retval EFI_INVALID_PARAMETER A required pointer argument passed is NULL. This will be returned if
+ VariablePolicyVariableName is non-NULL and VariablePolicyVariableNameBufferSize
+ is NULL. It can also be returned if the Command value provided is invalid.
+ @retval EFI_NOT_FOUND A variable policy was not found for the given UEFI variable name and vendor GUID.
+
+
+**/
+STATIC
+EFI_STATUS
+InternalProtocolGetVariablePolicyInfo (
+ IN UINT32 Command,
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ IN OUT UINTN *VariablePolicyVariableNameBufferSize, OPTIONAL
+ OUT VOID *VariablePolicy,
+ OUT CHAR16 *VariablePolicyVariableName OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *OutputVariableName;
+ EFI_MM_COMMUNICATE_HEADER *CommHeader;
+ VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader;
+ VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS *CommandParams;
+ UINTN AllowedOutputVariableNameSize;
+ UINTN BufferSize;
+ UINTN VariableNameSize;
+
+ if ((VariableName == NULL) || (VendorGuid == NULL) || (VariablePolicy == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Command) {
+ case VAR_CHECK_POLICY_COMMAND_GET_INFO:
+ case VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO:
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AcquireLockOnlyAtBootTime (&mMmCommunicationLock);
+
+ VariableNameSize = StrnSizeS (
+ VariableName,
+ (VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE - VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END)
+ );
+ if (VariableNameSize >= (VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE - VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ if ((VariablePolicyVariableName != NULL) && (VariablePolicyVariableNameBufferSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ BufferSize = mMmCommunicationBufferSize;
+ CommHeader = mMmCommunicationBuffer;
+
+ Status = SafeUintnSub (
+ VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE,
+ VariableNameSize,
+ &AllowedOutputVariableNameSize
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ if (VariablePolicyVariableNameBufferSize != NULL) {
+ AllowedOutputVariableNameSize = MIN (AllowedOutputVariableNameSize, *VariablePolicyVariableNameBufferSize);
+ } else {
+ AllowedOutputVariableNameSize = 0;
+ }
+
+ PolicyHeader = (VAR_CHECK_POLICY_COMM_HEADER *)&CommHeader->Data;
+ CommandParams = (VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS *)(PolicyHeader + 1);
+
+ CopyGuid (&CommHeader->HeaderGuid, &gVarCheckPolicyLibMmiHandlerGuid);
+ CommHeader->MessageLength = BufferSize - OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
+ PolicyHeader->Signature = VAR_CHECK_POLICY_COMM_SIG;
+ PolicyHeader->Revision = VAR_CHECK_POLICY_COMM_REVISION;
+ PolicyHeader->Command = Command;
+
+ ZeroMem ((VOID *)&CommandParams->OutputPolicyEntry, sizeof (CommandParams->OutputPolicyEntry));
+ CopyGuid (&CommandParams->InputVendorGuid, VendorGuid);
+ Status = SafeUintnToUint32 (VariableNameSize, &CommandParams->InputVariableNameSize);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ Status = SafeUintnToUint32 (AllowedOutputVariableNameSize, &CommandParams->OutputVariableNameSize);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ if (AllowedOutputVariableNameSize > 0) {
+ Status = StrnCpyS (
+ CommandParams->InputVariableName,
+ AllowedOutputVariableNameSize / sizeof (CHAR16),
+ VariableName,
+ (UINTN)CommandParams->InputVariableNameSize / sizeof (CHAR16)
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ Status = InternalMmCommunicate (CommHeader, &BufferSize);
+ if (Status == EFI_SUCCESS) {
+ CopyMem (
+ VariablePolicy,
+ (VOID *)&CommandParams->OutputPolicyEntry,
+ (Command == VAR_CHECK_POLICY_COMMAND_GET_INFO) ?
+ sizeof (CommandParams->OutputPolicyEntry.VariablePolicy) :
+ sizeof (CommandParams->OutputPolicyEntry.LockOnVarStatePolicy)
+ );
+
+ if (VariablePolicyVariableNameBufferSize == NULL) {
+ if (VariablePolicyVariableName != NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ goto Done;
+ }
+
+ if (PolicyHeader->Result == EFI_BUFFER_TOO_SMALL) {
+ *VariablePolicyVariableNameBufferSize = (UINTN)CommandParams->OutputVariableNameSize;
+ goto Done;
+ }
+
+ if (PolicyHeader->Result == EFI_SUCCESS) {
+ if (CommandParams->OutputVariableNameSize > 0) {
+ Status = SafeUintnAdd (
+ ((UINTN)CommandParams + VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END),
+ (UINTN)CommandParams->InputVariableNameSize,
+ (UINTN *)&OutputVariableName
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto Done;
+ }
+
+ Status = StrnCpyS (
+ VariablePolicyVariableName,
+ *VariablePolicyVariableNameBufferSize / sizeof (CHAR16),
+ OutputVariableName,
+ (UINTN)CommandParams->OutputVariableNameSize
+ );
+ ASSERT_EFI_ERROR (Status);
+ *VariablePolicyVariableNameBufferSize = (UINTN)CommandParams->OutputVariableNameSize;
+ } else {
+ // A variable policy variable name is not present. Return values according to interface.
+ *VariablePolicyVariableNameBufferSize = 0;
+ }
+ }
+ }
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mMmCommunicationLock);
+
+ return (EFI_ERROR (Status)) ? Status : PolicyHeader->Result;
+}
+
+/**
+ This function will return variable policy information for a UEFI variable with a
+ registered variable policy.
+
+ @param[in] VariableName The name of the variable to use for the policy search.
+ @param[in] VendorGuid The vendor GUID of the variable to use for the policy search.
+ @param[in,out] VariablePolicyVariableNameBufferSize On input, the size, in bytes, of the VariablePolicyVariableName
+ buffer.
+
+ On output, the size, in bytes, needed to store the variable
+ policy variable name.
+
+ If testing for the VariablePolicyVariableName buffer size
+ needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
+ guaranteed to be returned if the variable policy variable name
+ is found.
+ @param[out] VariablePolicy Pointer to a buffer where the policy entry will be written
+ if found.
+ @param[out] VariablePolicyVariableName Pointer to a buffer where the variable name used for the
+ variable policy will be written if a variable name is
+ registered.
+
+ If the variable policy is not associated with a variable name
+ (e.g. applied to variable vendor namespace) and this parameter
+ is given, this parameter will not be modified and
+ VariablePolicyVariableNameBufferSize will be set to zero to
+ indicate a name was not present.
+
+ If the pointer given is not NULL,
+ VariablePolicyVariableNameBufferSize must be non-NULL.
+
+ @retval EFI_SUCCESS A variable policy entry was found and returned successfully.
+ @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused a calculation error.
+ @retval EFI_BUFFER_TOO_SMALL The VariablePolicyVariableName buffer value is too small for the size needed.
+ The buffer should now point to the size needed.
+ @retval EFI_NOT_READY Variable policy has not yet been initialized.
+ @retval EFI_INVALID_PARAMETER A required pointer argument passed is NULL. This will be returned if
+ VariablePolicyVariableName is non-NULL and VariablePolicyVariableNameBufferSize
+ is NULL.
+ @retval EFI_NOT_FOUND A variable policy was not found for the given UEFI variable name and vendor GUID.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ProtocolGetVariablePolicyInfo (
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ IN OUT UINTN *VariablePolicyVariableNameBufferSize, OPTIONAL
+ OUT VARIABLE_POLICY_ENTRY *VariablePolicy,
+ OUT CHAR16 *VariablePolicyVariableName OPTIONAL
+ )
+{
+ return InternalProtocolGetVariablePolicyInfo (
+ VAR_CHECK_POLICY_COMMAND_GET_INFO,
+ VariableName,
+ VendorGuid,
+ VariablePolicyVariableNameBufferSize,
+ VariablePolicy,
+ VariablePolicyVariableName
+ );
+}
+
+/**
+ This function will return the Lock on Variable State policy information for the policy
+ associated with the given UEFI variable.
+
+ @param[in] VariableName The name of the variable to use for the policy search.
+ @param[in] VendorGuid The vendor GUID of the variable to use for the policy
+ search.
+ @param[in,out] VariableLockPolicyVariableNameBufferSize On input, the size, in bytes, of the
+ VariableLockPolicyVariableName buffer.
+
+ On output, the size, in bytes, needed to store the variable
+ policy variable name.
+
+ If testing for the VariableLockPolicyVariableName buffer
+ P size needed, set this value to zero so EFI_BUFFER_TOO_SMALL
+ is guaranteed to be returned if the variable policy variable
+ name is found.
+ @param[out] VariablePolicy Pointer to a buffer where the policy entry will be written
+ if found.
+ @param[out] VariableLockPolicyVariableName Pointer to a buffer where the variable name used for the
+ variable lock on variable state policy will be written if
+ a variable name is registered.
+
+ If the lock on variable policy is not associated with a
+ variable name (e.g. applied to variable vendor namespace)
+ and this parameter is given, this parameter will not be
+ modified and VariableLockPolicyVariableNameBufferSize will
+ be set to zero to indicate a name was not present.
+
+ If the pointer given is not NULL,
+ VariableLockPolicyVariableNameBufferSize must be non-NULL.
+
+ @retval EFI_SUCCESS A Lock on Variable State variable policy entry was found and returned
+ successfully.
+ @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused a calculation error.
+ @retval EFI_BUFFER_TOO_SMALL The VariableLockPolicyVariableName buffer is too small for the size needed.
+ The buffer should now point to the size needed.
+ @retval EFI_NOT_READY Variable policy has not yet been initialized.
+ @retval EFI_INVALID_PARAMETER A required pointer argument passed is NULL. This will be returned if
+ VariableLockPolicyVariableName is non-NULL and
+ VariableLockPolicyVariableNameBufferSize is NULL.
+ @retval EFI_NOT_FOUND A Lock on Variable State variable policy was not found for the given UEFI
+ variable name and vendor GUID.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ProtocolGetLockOnVariableStateVariablePolicyInfo (
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ IN OUT UINTN *VariableLockPolicyVariableNameBufferSize, OPTIONAL
+ OUT VARIABLE_LOCK_ON_VAR_STATE_POLICY *VariablePolicy,
+ OUT CHAR16 *VariableLockPolicyVariableName OPTIONAL
+ )
+{
+ return InternalProtocolGetVariablePolicyInfo (
+ VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO,
+ VariableName,
+ VendorGuid,
+ VariableLockPolicyVariableNameBufferSize,
+ VariablePolicy,
+ VariableLockPolicyVariableName
+ );
+}
+
/**
This helper function locates the shared comm buffer and assigns it to input pointers.
@@ -514,12 +846,14 @@ VariablePolicySmmDxeMain (
}
// Configure the VariablePolicy protocol structure.
- mVariablePolicyProtocol.Revision = EDKII_VARIABLE_POLICY_PROTOCOL_REVISION;
- mVariablePolicyProtocol.DisableVariablePolicy = ProtocolDisableVariablePolicy;
- mVariablePolicyProtocol.IsVariablePolicyEnabled = ProtocolIsVariablePolicyEnabled;
- mVariablePolicyProtocol.RegisterVariablePolicy = ProtocolRegisterVariablePolicy;
- mVariablePolicyProtocol.DumpVariablePolicy = ProtocolDumpVariablePolicy;
- mVariablePolicyProtocol.LockVariablePolicy = ProtocolLockVariablePolicy;
+ mVariablePolicyProtocol.Revision = EDKII_VARIABLE_POLICY_PROTOCOL_REVISION;
+ mVariablePolicyProtocol.DisableVariablePolicy = ProtocolDisableVariablePolicy;
+ mVariablePolicyProtocol.IsVariablePolicyEnabled = ProtocolIsVariablePolicyEnabled;
+ mVariablePolicyProtocol.RegisterVariablePolicy = ProtocolRegisterVariablePolicy;
+ mVariablePolicyProtocol.DumpVariablePolicy = ProtocolDumpVariablePolicy;
+ mVariablePolicyProtocol.LockVariablePolicy = ProtocolLockVariablePolicy;
+ mVariablePolicyProtocol.GetVariablePolicyInfo = ProtocolGetVariablePolicyInfo;
+ mVariablePolicyProtocol.GetLockOnVariableStateVariablePolicyInfo = ProtocolGetLockOnVariableStateVariablePolicyInfo;
// Register all the protocols and return the status.
Status = gBS->InstallMultipleProtocolInterfaces (
diff --git a/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h b/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
index ff3d4a1fd68a..a692fa40c946 100644
--- a/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
+++ b/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
@@ -32,23 +32,52 @@ typedef struct _VAR_CHECK_POLICY_COMM_DUMP_PARAMS {
BOOLEAN HasMore;
} VAR_CHECK_POLICY_COMM_DUMP_PARAMS;
+typedef union {
+ VARIABLE_POLICY_ENTRY VariablePolicy;
+ VARIABLE_LOCK_ON_VAR_STATE_POLICY LockOnVarStatePolicy;
+} VAR_CHECK_POLICY_OUTPUT_POLICY_ENTRY;
+
+typedef struct _VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS {
+ EFI_GUID InputVendorGuid;
+ UINT32 InputVariableNameSize;
+ UINT32 OutputVariableNameSize;
+ VAR_CHECK_POLICY_OUTPUT_POLICY_ENTRY OutputPolicyEntry;
+ CHAR16 InputVariableName[1];
+} VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS;
+
#pragma pack(pop)
+#define VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END \
+ (OFFSET_OF(VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS, InputVariableName))
+
// Make sure that we will hold at least the headers.
#define VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE MAX((OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + sizeof (VAR_CHECK_POLICY_COMM_HEADER) + EFI_PAGES_TO_SIZE(1)), EFI_PAGES_TO_SIZE(4))
#define VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE (VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE - \
(OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + \
sizeof(VAR_CHECK_POLICY_COMM_HEADER) + \
sizeof(VAR_CHECK_POLICY_COMM_DUMP_PARAMS)))
+
+#define VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE (VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE - \
+ (OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + \
+ sizeof(VAR_CHECK_POLICY_COMM_HEADER) + \
+ OFFSET_OF(VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS, InputVariableName)))
+
STATIC_ASSERT (
VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE < VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE,
"an integer underflow may have occurred calculating VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE"
);
-#define VAR_CHECK_POLICY_COMMAND_DISABLE 0x0001
-#define VAR_CHECK_POLICY_COMMAND_IS_ENABLED 0x0002
-#define VAR_CHECK_POLICY_COMMAND_REGISTER 0x0003
-#define VAR_CHECK_POLICY_COMMAND_DUMP 0x0004
-#define VAR_CHECK_POLICY_COMMAND_LOCK 0x0005
+STATIC_ASSERT (
+ VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE < VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE,
+ "an integer underflow may have occurred calculating VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE"
+ );
+
+#define VAR_CHECK_POLICY_COMMAND_DISABLE 0x0001
+#define VAR_CHECK_POLICY_COMMAND_IS_ENABLED 0x0002
+#define VAR_CHECK_POLICY_COMMAND_REGISTER 0x0003
+#define VAR_CHECK_POLICY_COMMAND_DUMP 0x0004
+#define VAR_CHECK_POLICY_COMMAND_LOCK 0x0005
+#define VAR_CHECK_POLICY_COMMAND_GET_INFO 0x0006
+#define VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO 0x0007
#endif // _VAR_CHECK_POLICY_MMI_COMMON_H_
diff --git a/MdeModulePkg/Include/Library/VariablePolicyLib.h b/MdeModulePkg/Include/Library/VariablePolicyLib.h
index 63c49fbca1ed..bc4e26b2d434 100644
--- a/MdeModulePkg/Include/Library/VariablePolicyLib.h
+++ b/MdeModulePkg/Include/Library/VariablePolicyLib.h
@@ -102,6 +102,113 @@ DumpVariablePolicy (
IN OUT UINT32 *Size
);
+/**
+ This function will return variable policy information for a UEFI variable with a
+ registered variable policy.
+
+ @param[in] VariableName The name of the variable to use for the policy search.
+ @param[in] VendorGuid The vendor GUID of the variable to use for the policy search.
+ @param[in,out] VariablePolicyVariableNameBufferSize On input, the size, in bytes, of the VariablePolicyVariableName
+ buffer.
+
+ On output, the size, in bytes, needed to store the variable
+ policy variable name.
+
+ If testing for the VariablePolicyVariableName buffer size
+ needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
+ guaranteed to be returned if the variable policy variable name
+ is found.
+ @param[out] VariablePolicy Pointer to a buffer where the policy entry will be written
+ if found.
+ @param[out] VariablePolicyVariableName Pointer to a buffer where the variable name used for the
+ variable policy will be written if a variable name is
+ registered.
+
+ If the variable policy is not associated with a variable name
+ (e.g. applied to variable vendor namespace) and this parameter
+ is given, this parameter will not be modified and
+ VariablePolicyVariableNameBufferSize will be set to zero to
+ indicate a name was not present.
+
+ If the pointer given is not NULL,
+ VariablePolicyVariableNameBufferSize must be non-NULL.
+
+ @retval EFI_SUCCESS A variable policy entry was found and returned successfully.
+ @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused a calculation error.
+ @retval EFI_BUFFER_TOO_SMALL The VariablePolicyVariableName buffer value is too small for the size needed.
+ The buffer should now point to the size needed.
+ @retval EFI_NOT_READY Variable policy has not yet been initialized.
+ @retval EFI_INVALID_PARAMETER A required pointer argument passed is NULL. This will be returned if
+ VariablePolicyVariableName is non-NULL and VariablePolicyVariableNameBufferSize
+ is NULL.
+ @retval EFI_NOT_FOUND A variable policy was not found for the given UEFI variable name and vendor GUID.
+
+**/
+EFI_STATUS
+EFIAPI
+GetVariablePolicyInfo (
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ IN OUT UINTN *VariablePolicyVariableNameBufferSize OPTIONAL,
+ OUT VARIABLE_POLICY_ENTRY *VariablePolicy,
+ OUT CHAR16 *VariablePolicyVariableName OPTIONAL
+ );
+
+/**
+ This function will return the Lock on Variable State policy information for the policy
+ associated with the given UEFI variable.
+
+ @param[in] VariableName The name of the variable to use for the policy search.
+ @param[in] VendorGuid The vendor GUID of the variable to use for the policy
+ search.
+ @param[in,out] VariableLockPolicyVariableNameBufferSize On input, the size, in bytes, of the
+ VariableLockPolicyVariableName buffer.
+
+ On output, the size, in bytes, needed to store the variable
+ policy variable name.
+
+ If testing for the VariableLockPolicyVariableName buffer
+ size needed, set this value to zero so EFI_BUFFER_TOO_SMALL
+ is guaranteed to be returned if the variable policy variable
+ name is found.
+ @param[out] VariablePolicy Pointer to a buffer where the policy entry will be written
+ if found.
+ @param[out] VariableLockPolicyVariableName Pointer to a buffer where the variable name used for the
+ variable lock on variable state policy will be written if
+ a variable name is registered.
+
+ If the lock on variable policy is not associated with a
+ variable name (e.g. applied to variable vendor namespace)
+ and this parameter is given, this parameter will not be
+ modified and VariableLockPolicyVariableNameBufferSize will
+ be set to zero to indicate a name was not present.
+
+ If the pointer given is not NULL,
+ VariableLockPolicyVariableNameBufferSize must be non-NULL.
+
+ @retval EFI_SUCCESS A Lock on Variable State variable policy entry was found and returned
+ successfully.
+ @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused a calculation error.
+ @retval EFI_BUFFER_TOO_SMALL The VariableLockPolicyVariableName buffer is too small for the size needed.
+ The buffer should now point to the size needed.
+ @retval EFI_NOT_READY Variable policy has not yet been initialized.
+ @retval EFI_INVALID_PARAMETER A required pointer argument passed is NULL. This will be returned if
+ VariableLockPolicyVariableName is non-NULL and
+ VariableLockPolicyVariableNameBufferSize is NULL.
+ @retval EFI_NOT_FOUND A Lock on Variable State variable policy was not found for the given UEFI
+ variable name and vendor GUID.
+
+**/
+EFI_STATUS
+EFIAPI
+GetLockOnVariableStateVariablePolicyInfo (
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ IN OUT UINTN *VariableLockPolicyVariableNameBufferSize OPTIONAL,
+ OUT VARIABLE_LOCK_ON_VAR_STATE_POLICY *VariablePolicy,
+ OUT CHAR16 *VariableLockPolicyVariableName OPTIONAL
+ );
+
/**
This API function returns whether or not the policy engine is
currently being enforced.
diff --git a/MdeModulePkg/Include/Protocol/VariablePolicy.h b/MdeModulePkg/Include/Protocol/VariablePolicy.h
index 98d739401f83..4b57f70a9da8 100644
--- a/MdeModulePkg/Include/Protocol/VariablePolicy.h
+++ b/MdeModulePkg/Include/Protocol/VariablePolicy.h
@@ -9,7 +9,17 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#ifndef __EDKII_VARIABLE_POLICY_PROTOCOL__
#define __EDKII_VARIABLE_POLICY_PROTOCOL__
-#define EDKII_VARIABLE_POLICY_PROTOCOL_REVISION 0x0000000000010000
+#define EDKII_VARIABLE_POLICY_PROTOCOL_REVISION 0x0000000000020000
+
+/*
+ Rev 0x0000000000010000:
+ - Initial protocol definition
+
+ Rev 0x0000000000020000:
+ - Add GetVariablePolicyInfo() API
+ - Add GetLockOnVariableStateVariablePolicyInfo() API
+
+*/
#define EDKII_VARIABLE_POLICY_PROTOCOL_GUID \
{ \
@@ -141,13 +151,122 @@ EFI_STATUS
VOID
);
+/**
+ This function will return variable policy information for a UEFI variable with a
+ registered variable policy.
+
+ @param[in] VariableName The name of the variable to use for the policy search.
+ @param[in] VendorGuid The vendor GUID of the variable to use for the policy search.
+ @param[in,out] VariablePolicyVariableNameBufferSize On input, the size, in bytes, of the VariablePolicyVariableName
+ buffer.
+
+ On output, the size, in bytes, needed to store the variable
+ policy variable name.
+
+ If testing for the VariablePolicyVariableName buffer size
+ needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
+ guaranteed to be returned if the variable policy variable name
+ is found.
+ @param[out] VariablePolicy Pointer to a buffer where the policy entry will be written
+ if found.
+ @param[out] VariablePolicyVariableName Pointer to a buffer where the variable name used for the
+ variable policy will be written if a variable name is
+ registered.
+
+ If the variable policy is not associated with a variable name
+ (e.g. applied to variable vendor namespace) and this parameter
+ is given, this parameter will not be modified and
+ VariablePolicyVariableNameBufferSize will be set to zero to
+ indicate a name was not present.
+
+ If the pointer given is not NULL,
+ VariablePolicyVariableNameBufferSize must be non-NULL.
+
+ @retval EFI_SUCCESS A variable policy entry was found and returned successfully.
+ @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused a calculation error.
+ @retval EFI_BUFFER_TOO_SMALL The VariablePolicyVariableName buffer value is too small for the size needed.
+ The buffer should now point to the size needed.
+ @retval EFI_NOT_READY Variable policy has not yet been initialized.
+ @retval EFI_INVALID_PARAMETER A required pointer argument passed is NULL. This will be returned if
+ VariablePolicyVariableName is non-NULL and VariablePolicyVariableNameBufferSize
+ is NULL.
+ @retval EFI_NOT_FOUND A variable policy was not found for the given UEFI variable name and vendor GUID.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *GET_VARIABLE_POLICY_INFO)(
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ IN OUT UINTN *VariablePolicyVariableNameBufferSize OPTIONAL,
+ OUT VARIABLE_POLICY_ENTRY *VariablePolicy,
+ OUT CHAR16 *VariablePolicyVariableName OPTIONAL
+ );
+
+/**
+ This function will return the Lock on Variable State policy information for the policy
+ associated with the given UEFI variable.
+
+ @param[in] VariableName The name of the variable to use for the policy search.
+ @param[in] VendorGuid The vendor GUID of the variable to use for the policy
+ search.
+ @param[in,out] VariableLockPolicyVariableNameBufferSize On input, the size, in bytes, of the
+ VariableLockPolicyVariableName buffer.
+
+ On output, the size, in bytes, needed to store the variable
+ policy variable name.
+
+ If testing for the VariableLockPolicyVariableName buffer
+ size needed, set this value to zero so EFI_BUFFER_TOO_SMALL
+ is guaranteed to be returned if the variable policy variable
+ name is found.
+ @param[out] VariablePolicy Pointer to a buffer where the policy entry will be written
+ if found.
+ @param[out] VariableLockPolicyVariableName Pointer to a buffer where the variable name used for the
+ variable lock on variable state policy will be written if
+ a variable name is registered.
+
+ If the lock on variable policy is not associated with a
+ variable name (e.g. applied to variable vendor namespace)
+ and this parameter is given, this parameter will not be
+ modified and VariableLockPolicyVariableNameBufferSize will
+ be set to zero to indicate a name was not present.
+
+ If the pointer given is not NULL,
+ VariableLockPolicyVariableNameBufferSize must be non-NULL.
+
+ @retval EFI_SUCCESS A Lock on Variable State variable policy entry was found and returned
+ successfully.
+ @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused a calculation error.
+ @retval EFI_BUFFER_TOO_SMALL The VariableLockPolicyVariableName buffer is too small for the size needed.
+ The buffer should now point to the size needed.
+ @retval EFI_NOT_READY Variable policy has not yet been initialized.
+ @retval EFI_INVALID_PARAMETER A required pointer argument passed is NULL. This will be returned if
+ VariableLockPolicyVariableName is non-NULL and
+ VariableLockPolicyVariableNameBufferSize is NULL.
+ @retval EFI_NOT_FOUND A Lock on Variable State variable policy was not found for the given UEFI
+ variable name and vendor GUID.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *GET_LOCK_ON_VARIABLE_STATE_VARIABLE_POLICY_INFO)(
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ IN OUT UINTN *VariableLockPolicyVariableNameBufferSize OPTIONAL,
+ OUT VARIABLE_LOCK_ON_VAR_STATE_POLICY *VariablePolicy,
+ OUT CHAR16 *VariableLockPolicyVariableName OPTIONAL
+ );
+
typedef struct {
- UINT64 Revision;
- DISABLE_VARIABLE_POLICY DisableVariablePolicy;
- IS_VARIABLE_POLICY_ENABLED IsVariablePolicyEnabled;
- REGISTER_VARIABLE_POLICY RegisterVariablePolicy;
- DUMP_VARIABLE_POLICY DumpVariablePolicy;
- LOCK_VARIABLE_POLICY LockVariablePolicy;
+ UINT64 Revision;
+ DISABLE_VARIABLE_POLICY DisableVariablePolicy;
+ IS_VARIABLE_POLICY_ENABLED IsVariablePolicyEnabled;
+ REGISTER_VARIABLE_POLICY RegisterVariablePolicy;
+ DUMP_VARIABLE_POLICY DumpVariablePolicy;
+ LOCK_VARIABLE_POLICY LockVariablePolicy;
+ GET_VARIABLE_POLICY_INFO GetVariablePolicyInfo;
+ GET_LOCK_ON_VARIABLE_STATE_VARIABLE_POLICY_INFO GetLockOnVariableStateVariablePolicyInfo;
} _EDKII_VARIABLE_POLICY_PROTOCOL;
typedef _EDKII_VARIABLE_POLICY_PROTOCOL EDKII_VARIABLE_POLICY_PROTOCOL;
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
index 3fe6043bf631..7048d555f0a9 100644
--- a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
@@ -32,6 +32,7 @@ [Packages]
[LibraryClasses]
+ BaseLib
DebugLib
BaseMemoryLib
MemoryAllocationLib
--
2.42.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#108841): https://edk2.groups.io/g/devel/message/108841
Mute This Topic: https://groups.io/mt/101457410/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell command
2023-09-19 14:32 [edk2-devel] [PATCH v1 0/3] Add Variable Policy Audit and Shell Command Michael Kubacki
2023-09-19 14:32 ` [edk2-devel] [PATCH v1 1/3] MdeModulePkg/VariablePolicy: Add more granular variable policy querying Michael Kubacki
@ 2023-09-19 14:32 ` Michael Kubacki
2023-10-24 5:16 ` 回复: " gaoliming via groups.io
2023-09-19 14:33 ` [edk2-devel] [PATCH v1 3/3] OvmfPkg: Add varpolicy " Michael Kubacki
2 siblings, 1 reply; 10+ messages in thread
From: Michael Kubacki @ 2023-09-19 14:32 UTC (permalink / raw)
To: devel; +Cc: Zhichao Gao, Michael D Kinney
From: Michael Kubacki <michael.kubacki@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/VariablePolicyDynamicCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
```
Include the following line in platform FDF:
```
INF ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf
```
Cc: Zhichao Gao <zhichao.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.c | 1009 ++++++++++++++++++++
ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.h | 94 ++
ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf | 56 ++
ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.uni | 86 ++
ShellPkg/ShellPkg.dsc | 1 +
5 files changed, 1246 insertions(+)
diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.c b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.c
new file mode 100644
index 000000000000..49993f635396
--- /dev/null
+++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.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/VariablePolicyDynamicCommand.h b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.h
new file mode 100644
index 000000000000..7ce5beca389a
--- /dev/null
+++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.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/VariablePolicyDynamicCommand.inf b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf
new file mode 100644
index 000000000000..22b4baa5e6f2
--- /dev/null
+++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.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/VariablePolicyDynamicCommand.uni b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.uni
new file mode 100644
index 000000000000..a65f477b41c3
--- /dev/null
+++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.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/VariablePolicyDynamicCommand.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/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [edk2-devel] [PATCH v1 3/3] OvmfPkg: Add varpolicy shell command
2023-09-19 14:32 [edk2-devel] [PATCH v1 0/3] Add Variable Policy Audit and Shell Command Michael Kubacki
2023-09-19 14:32 ` [edk2-devel] [PATCH v1 1/3] MdeModulePkg/VariablePolicy: Add more granular variable policy querying Michael Kubacki
2023-09-19 14:32 ` [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell command Michael Kubacki
@ 2023-09-19 14:33 ` Michael Kubacki
2023-10-24 0:44 ` Yao, Jiewen
2 siblings, 1 reply; 10+ messages in thread
From: Michael Kubacki @ 2023-09-19 14:33 UTC (permalink / raw)
To: devel
Cc: Anatol Belski, Anthony Perard, Gerd Hoffmann, Jianyong Wu,
Jiewen Yao, Jordan Justen, Julien Grall
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds the varpolicy EFI shell command to all DSC files that
currently include other dynamic shell commands from ShellPkg.
This command allows variable policies to be dumped in the EFI
shell for convenient auditing and debug.
Use the command in QEMU EFI shell as follows:
- `"varpolicy"` dumps platform variables
- `"varpolicy -?"` shows help text
- `"varpolicy -b"` pages output as expected
- `"varpolicy -s"` shows accurate variable statistic information
- `"varpolicy -p"` shows accurate UEFI variable policy information
- `"varpolicy-v -b"` dumps all information including variable data hex dump
Cc: Anatol Belski <anbelski@linux.microsoft.com>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jianyong Wu <jianyong.wu@arm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Julien Grall <julien@xen.org>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
OvmfPkg/CloudHv/CloudHvX64.dsc | 4 ++++
OvmfPkg/Microvm/MicrovmX64.dsc | 4 ++++
OvmfPkg/OvmfPkgIa32.dsc | 4 ++++
OvmfPkg/OvmfPkgIa32X64.dsc | 4 ++++
OvmfPkg/OvmfPkgX64.dsc | 4 ++++
OvmfPkg/OvmfXen.dsc | 4 ++++
6 files changed, 24 insertions(+)
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index 35942e02df93..c23c7eaf6cc2 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -837,6 +837,10 @@ [Components]
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
+ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 0f26f2a9a97d..ea1fa3e2963f 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -849,6 +849,10 @@ [Components]
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
+ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index fcd3a3fda5f2..ed3a19feebe6 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -915,6 +915,10 @@ [Components]
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
+ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index d0ae0b996d66..16ca139b2973 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -933,6 +933,10 @@ [Components.X64]
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
+ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a6811eee557e..dc1a0942aa8b 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -1001,6 +1001,10 @@ [Components]
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
+ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index ccd3a873c714..0063245b5659 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -722,6 +722,10 @@ [Components]
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
+ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
--
2.42.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#108843): https://edk2.groups.io/g/devel/message/108843
Mute This Topic: https://groups.io/mt/101457415/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH v1 3/3] OvmfPkg: Add varpolicy shell command
2023-09-19 14:33 ` [edk2-devel] [PATCH v1 3/3] OvmfPkg: Add varpolicy " Michael Kubacki
@ 2023-10-24 0:44 ` Yao, Jiewen
2023-10-24 2:13 ` Michael D Kinney
0 siblings, 1 reply; 10+ messages in thread
From: Yao, Jiewen @ 2023-10-24 0:44 UTC (permalink / raw)
To: mikuback@linux.microsoft.com, devel@edk2.groups.io
Cc: Anatol Belski, Anthony Perard, Gerd Hoffmann, Jianyong Wu,
Justen, Jordan L, Julien Grall
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
> -----Original Message-----
> From: mikuback@linux.microsoft.com <mikuback@linux.microsoft.com>
> Sent: Tuesday, September 19, 2023 10:33 PM
> To: devel@edk2.groups.io
> Cc: Anatol Belski <anbelski@linux.microsoft.com>; Anthony Perard
> <anthony.perard@citrix.com>; Gerd Hoffmann <kraxel@redhat.com>; Jianyong
> Wu <jianyong.wu@arm.com>; Yao, Jiewen <jiewen.yao@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Julien Grall <julien@xen.org>
> Subject: [PATCH v1 3/3] OvmfPkg: Add varpolicy shell command
>
> From: Michael Kubacki <michael.kubacki@microsoft.com>
>
> Adds the varpolicy EFI shell command to all DSC files that
> currently include other dynamic shell commands from ShellPkg.
>
> This command allows variable policies to be dumped in the EFI
> shell for convenient auditing and debug.
>
> Use the command in QEMU EFI shell as follows:
>
> - `"varpolicy"` dumps platform variables
> - `"varpolicy -?"` shows help text
> - `"varpolicy -b"` pages output as expected
> - `"varpolicy -s"` shows accurate variable statistic information
> - `"varpolicy -p"` shows accurate UEFI variable policy information
> - `"varpolicy-v -b"` dumps all information including variable data hex dump
>
> Cc: Anatol Belski <anbelski@linux.microsoft.com>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Jianyong Wu <jianyong.wu@arm.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Julien Grall <julien@xen.org>
> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
> ---
> OvmfPkg/CloudHv/CloudHvX64.dsc | 4 ++++
> OvmfPkg/Microvm/MicrovmX64.dsc | 4 ++++
> OvmfPkg/OvmfPkgIa32.dsc | 4 ++++
> OvmfPkg/OvmfPkgIa32X64.dsc | 4 ++++
> OvmfPkg/OvmfPkgX64.dsc | 4 ++++
> OvmfPkg/OvmfXen.dsc | 4 ++++
> 6 files changed, 24 insertions(+)
>
> diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc
> b/OvmfPkg/CloudHv/CloudHvX64.dsc
> index 35942e02df93..c23c7eaf6cc2 100644
> --- a/OvmfPkg/CloudHv/CloudHvX64.dsc
> +++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
> @@ -837,6 +837,10 @@ [Components]
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> }
> +
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> amicCommand.inf {
> + <PcdsFixedAtBuild>
> + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> + }
>
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.i
> nf {
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc
> b/OvmfPkg/Microvm/MicrovmX64.dsc
> index 0f26f2a9a97d..ea1fa3e2963f 100644
> --- a/OvmfPkg/Microvm/MicrovmX64.dsc
> +++ b/OvmfPkg/Microvm/MicrovmX64.dsc
> @@ -849,6 +849,10 @@ [Components]
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> }
> +
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> amicCommand.inf {
> + <PcdsFixedAtBuild>
> + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> + }
>
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.i
> nf {
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> index fcd3a3fda5f2..ed3a19feebe6 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -915,6 +915,10 @@ [Components]
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> }
> +
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> amicCommand.inf {
> + <PcdsFixedAtBuild>
> + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> + }
>
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.i
> nf {
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
> index d0ae0b996d66..16ca139b2973 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> @@ -933,6 +933,10 @@ [Components.X64]
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> }
> +
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> amicCommand.inf {
> + <PcdsFixedAtBuild>
> + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> + }
>
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.i
> nf {
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> index a6811eee557e..dc1a0942aa8b 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -1001,6 +1001,10 @@ [Components]
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> }
> +
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> amicCommand.inf {
> + <PcdsFixedAtBuild>
> + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> + }
>
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.i
> nf {
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
> index ccd3a873c714..0063245b5659 100644
> --- a/OvmfPkg/OvmfXen.dsc
> +++ b/OvmfPkg/OvmfXen.dsc
> @@ -722,6 +722,10 @@ [Components]
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> }
> +
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> amicCommand.inf {
> + <PcdsFixedAtBuild>
> + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> + }
>
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.i
> nf {
> <PcdsFixedAtBuild>
> gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> --
> 2.42.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109966): https://edk2.groups.io/g/devel/message/109966
Mute This Topic: https://groups.io/mt/101457415/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH v1 3/3] OvmfPkg: Add varpolicy shell command
2023-10-24 0:44 ` Yao, Jiewen
@ 2023-10-24 2:13 ` Michael D Kinney
0 siblings, 0 replies; 10+ messages in thread
From: Michael D Kinney @ 2023-10-24 2:13 UTC (permalink / raw)
To: devel@edk2.groups.io, Yao, Jiewen, mikuback@linux.microsoft.com
Cc: Anatol Belski, Anthony Perard, Gerd Hoffmann, Jianyong Wu,
Justen, Jordan L, Julien Grall, Kinney, Michael D
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yao,
> Jiewen
> Sent: Monday, October 23, 2023 5:44 PM
> To: mikuback@linux.microsoft.com; devel@edk2.groups.io
> Cc: Anatol Belski <anbelski@linux.microsoft.com>; Anthony Perard
> <anthony.perard@citrix.com>; Gerd Hoffmann <kraxel@redhat.com>;
> Jianyong Wu <jianyong.wu@arm.com>; Justen, Jordan L
> <jordan.l.justen@intel.com>; Julien Grall <julien@xen.org>
> Subject: Re: [edk2-devel] [PATCH v1 3/3] OvmfPkg: Add varpolicy shell
> command
>
> Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
>
> > -----Original Message-----
> > From: mikuback@linux.microsoft.com <mikuback@linux.microsoft.com>
> > Sent: Tuesday, September 19, 2023 10:33 PM
> > To: devel@edk2.groups.io
> > Cc: Anatol Belski <anbelski@linux.microsoft.com>; Anthony Perard
> > <anthony.perard@citrix.com>; Gerd Hoffmann <kraxel@redhat.com>;
> Jianyong
> > Wu <jianyong.wu@arm.com>; Yao, Jiewen <jiewen.yao@intel.com>;
> Justen,
> > Jordan L <jordan.l.justen@intel.com>; Julien Grall <julien@xen.org>
> > Subject: [PATCH v1 3/3] OvmfPkg: Add varpolicy shell command
> >
> > From: Michael Kubacki <michael.kubacki@microsoft.com>
> >
> > Adds the varpolicy EFI shell command to all DSC files that
> > currently include other dynamic shell commands from ShellPkg.
> >
> > This command allows variable policies to be dumped in the EFI
> > shell for convenient auditing and debug.
> >
> > Use the command in QEMU EFI shell as follows:
> >
> > - `"varpolicy"` dumps platform variables
> > - `"varpolicy -?"` shows help text
> > - `"varpolicy -b"` pages output as expected
> > - `"varpolicy -s"` shows accurate variable statistic information
> > - `"varpolicy -p"` shows accurate UEFI variable policy information
> > - `"varpolicy-v -b"` dumps all information including variable data
> hex dump
> >
> > Cc: Anatol Belski <anbelski@linux.microsoft.com>
> > Cc: Anthony Perard <anthony.perard@citrix.com>
> > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > Cc: Jianyong Wu <jianyong.wu@arm.com>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Jordan Justen <jordan.l.justen@intel.com>
> > Cc: Julien Grall <julien@xen.org>
> > Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
> > ---
> > OvmfPkg/CloudHv/CloudHvX64.dsc | 4 ++++
> > OvmfPkg/Microvm/MicrovmX64.dsc | 4 ++++
> > OvmfPkg/OvmfPkgIa32.dsc | 4 ++++
> > OvmfPkg/OvmfPkgIa32X64.dsc | 4 ++++
> > OvmfPkg/OvmfPkgX64.dsc | 4 ++++
> > OvmfPkg/OvmfXen.dsc | 4 ++++
> > 6 files changed, 24 insertions(+)
> >
> > diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc
> > b/OvmfPkg/CloudHv/CloudHvX64.dsc
> > index 35942e02df93..c23c7eaf6cc2 100644
> > --- a/OvmfPkg/CloudHv/CloudHvX64.dsc
> > +++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
> > @@ -837,6 +837,10 @@ [Components]
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > }
> > +
> >
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> > amicCommand.inf {
> > + <PcdsFixedAtBuild>
> > + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > + }
> >
> >
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.
> i
> > nf {
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc
> > b/OvmfPkg/Microvm/MicrovmX64.dsc
> > index 0f26f2a9a97d..ea1fa3e2963f 100644
> > --- a/OvmfPkg/Microvm/MicrovmX64.dsc
> > +++ b/OvmfPkg/Microvm/MicrovmX64.dsc
> > @@ -849,6 +849,10 @@ [Components]
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > }
> > +
> >
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> > amicCommand.inf {
> > + <PcdsFixedAtBuild>
> > + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > + }
> >
> >
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.
> i
> > nf {
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> > index fcd3a3fda5f2..ed3a19feebe6 100644
> > --- a/OvmfPkg/OvmfPkgIa32.dsc
> > +++ b/OvmfPkg/OvmfPkgIa32.dsc
> > @@ -915,6 +915,10 @@ [Components]
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > }
> > +
> >
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> > amicCommand.inf {
> > + <PcdsFixedAtBuild>
> > + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > + }
> >
> >
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.
> i
> > nf {
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
> > index d0ae0b996d66..16ca139b2973 100644
> > --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> > +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> > @@ -933,6 +933,10 @@ [Components.X64]
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > }
> > +
> >
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> > amicCommand.inf {
> > + <PcdsFixedAtBuild>
> > + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > + }
> >
> >
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.
> i
> > nf {
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> > index a6811eee557e..dc1a0942aa8b 100644
> > --- a/OvmfPkg/OvmfPkgX64.dsc
> > +++ b/OvmfPkg/OvmfPkgX64.dsc
> > @@ -1001,6 +1001,10 @@ [Components]
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > }
> > +
> >
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> > amicCommand.inf {
> > + <PcdsFixedAtBuild>
> > + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > + }
> >
> >
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.
> i
> > nf {
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
> > index ccd3a873c714..0063245b5659 100644
> > --- a/OvmfPkg/OvmfXen.dsc
> > +++ b/OvmfPkg/OvmfXen.dsc
> > @@ -722,6 +722,10 @@ [Components]
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > }
> > +
> >
> ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn
> > amicCommand.inf {
> > + <PcdsFixedAtBuild>
> > + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > + }
> >
> >
> OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.
> i
> > nf {
> > <PcdsFixedAtBuild>
> > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > --
> > 2.42.0.windows.2
>
>
>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109978): https://edk2.groups.io/g/devel/message/109978
Mute This Topic: https://groups.io/mt/101457415/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 10+ messages in thread
* 回复: [edk2-devel] [PATCH v1 1/3] MdeModulePkg/VariablePolicy: Add more granular variable policy querying
2023-09-19 14:32 ` [edk2-devel] [PATCH v1 1/3] MdeModulePkg/VariablePolicy: Add more granular variable policy querying Michael Kubacki
@ 2023-10-24 5:11 ` gaoliming via groups.io
0 siblings, 0 replies; 10+ messages in thread
From: gaoliming via groups.io @ 2023-10-24 5:11 UTC (permalink / raw)
To: devel, mikuback
Cc: 'Dandan Bi', 'Hao A Wu', 'Jian J Wang'
Michael:
The change is good to me. Reviewed-by: Liming Gao
<gaoliming@byosoft.com.cn>
Thanks
Liming
> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Michael
> Kubacki
> 发送时间: 2023年9月19日 22:33
> 收件人: devel@edk2.groups.io
> 抄送: Dandan Bi <dandan.bi@intel.com>; Hao A Wu <hao.a.wu@intel.com>;
> Jian J Wang <jian.j.wang@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>
> 主题: [edk2-devel] [PATCH v1 1/3] MdeModulePkg/VariablePolicy: Add more
> granular variable policy querying
>
> From: Michael Kubacki <michael.kubacki@microsoft.com>
>
> Introduces two new APIs to EDKII_VARIABLE_POLICY_PROTOCOL:
> 1. GetVariablePolicyInfo()
> 2. GetLockOnVariableStateVariablePolicyInfo()
>
> These allow a caller to retrieve policy information associated with
> a UEFI variable given the variable name and vendor GUID.
>
> GetVariablePolicyInfo() - Returns the variable policy applied to the
> UEFI variable. If the variable policy is applied toward an individual
> UEFI variable, that name can optionally be returned.
>
> GetLockOnVariableStateVariablePolicyInfo() - Returns the Lock on
> Variable State policy applied to the UEFI variable. If the Lock on
> Variable State policy is applied to a specific variable name, that
> name can optionally be returned.
>
> These functions can be useful for a variety of purposes such as
> auditing, testing, and functional flows.
>
> Also fixed some variable name typos in code touched by the changes.
>
> Cc: Dandan Bi <dandan.bi@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
> ---
> MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c |
> 174 ++++++++--
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c |
> 304 +++++++++++++++++
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
> | 4 +-
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c |
> 346 +++++++++++++++++++-
> MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
> | 39 ++-
> MdeModulePkg/Include/Library/VariablePolicyLib.h |
> 107 ++++++
> MdeModulePkg/Include/Protocol/VariablePolicy.h |
> 133 +++++++-
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf | 1
> +
> 8 files changed, 1062 insertions(+), 46 deletions(-)
>
> diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
> b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
> index 5de46133bb26..1448af85555a 100644
> --- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
> +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
> @@ -76,14 +76,20 @@ VarCheckPolicyLibMmiHandler (
> VOID *InternalCommBuffer;
> EFI_STATUS Status;
> EFI_STATUS SubCommandStatus;
> - VAR_CHECK_POLICY_COMM_HEADER
> *PolicyCommmHeader;
> - VAR_CHECK_POLICY_COMM_HEADER
> *InternalPolicyCommmHeader;
> + VAR_CHECK_POLICY_COMM_HEADER
> *PolicyCommHeader;
> + VAR_CHECK_POLICY_COMM_HEADER
> *InternalPolicyCommHeader;
> VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS
> *IsEnabledParams;
> VAR_CHECK_POLICY_COMM_DUMP_PARAMS *DumpParamsIn;
> VAR_CHECK_POLICY_COMM_DUMP_PARAMS
> *DumpParamsOut;
> + VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS
> *GetInfoParamsInternal;
> + VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS
> *GetInfoParamsExternal;
> + CHAR16
> *InternalCopyOfOutputVariableName;
> + CHAR16
> *ExternalCopyOfOutputVariableName;
> UINT8 *DumpInputBuffer;
> UINT8 *DumpOutputBuffer;
> + UINTN
> AllowedOutputVariableNameSize;
> UINTN DumpTotalPages;
> + UINTN LocalSize;
> VARIABLE_POLICY_ENTRY *PolicyEntry;
> UINTN ExpectedSize;
> UINT32 TempSize;
> @@ -122,21 +128,21 @@ VarCheckPolicyLibMmiHandler (
> //
> InternalCommBuffer = &mSecurityEvalBuffer[0];
> CopyMem (InternalCommBuffer, CommBuffer, InternalCommBufferSize);
> - PolicyCommmHeader = CommBuffer;
> - InternalPolicyCommmHeader = InternalCommBuffer;
> + PolicyCommHeader = CommBuffer;
> + InternalPolicyCommHeader = InternalCommBuffer;
> // Check the revision and the signature of the comm header.
> - if ((InternalPolicyCommmHeader->Signature !=
> VAR_CHECK_POLICY_COMM_SIG) ||
> - (InternalPolicyCommmHeader->Revision !=
> VAR_CHECK_POLICY_COMM_REVISION))
> + if ((InternalPolicyCommHeader->Signature !=
> VAR_CHECK_POLICY_COMM_SIG) ||
> + (InternalPolicyCommHeader->Revision !=
> VAR_CHECK_POLICY_COMM_REVISION))
> {
> DEBUG ((DEBUG_INFO, "%a - Signature or revision are incorrect!\n",
> __func__));
> // We have verified the buffer is not null and have enough size to
hold
> Result field.
> - PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
> + PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
> return EFI_SUCCESS;
> }
>
> // If we're in the middle of a paginated dump and any other command is
> sent,
> // pagination cache must be cleared.
> - if ((mPaginationCache != NULL) &&
> (InternalPolicyCommmHeader->Command != mCurrentPaginationCommand))
> {
> + if ((mPaginationCache != NULL) &&
> (InternalPolicyCommHeader->Command != mCurrentPaginationCommand)) {
> FreePool (mPaginationCache);
> mPaginationCache = NULL;
> mPaginationCacheSize = 0;
> @@ -146,10 +152,10 @@ VarCheckPolicyLibMmiHandler (
> //
> // Now we can process the command as it was sent.
> //
> - PolicyCommmHeader->Result = EFI_ABORTED; // Set a default return
> for incomplete commands.
> - switch (InternalPolicyCommmHeader->Command) {
> + PolicyCommHeader->Result = EFI_ABORTED; // Set a default return
> for incomplete commands.
> + switch (InternalPolicyCommHeader->Command) {
> case VAR_CHECK_POLICY_COMMAND_DISABLE:
> - PolicyCommmHeader->Result = DisableVariablePolicy ();
> + PolicyCommHeader->Result = DisableVariablePolicy ();
> break;
>
> case VAR_CHECK_POLICY_COMMAND_IS_ENABLED:
> @@ -158,14 +164,14 @@ VarCheckPolicyLibMmiHandler (
> ExpectedSize += sizeof
> (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS);
> if (InternalCommBufferSize < ExpectedSize) {
> DEBUG ((DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n",
> __func__, InternalCommBufferSize, ExpectedSize));
> - PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
> + PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
> break;
> }
>
> // Now that we know we've got a valid size, we can fill in the rest
of
> the data.
> - IsEnabledParams =
> (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *)((UINT8
> *)CommBuffer + sizeof (VAR_CHECK_POLICY_COMM_HEADER));
> - IsEnabledParams->State = IsVariablePolicyEnabled ();
> - PolicyCommmHeader->Result = EFI_SUCCESS;
> + IsEnabledParams =
> (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *)((UINT8
> *)CommBuffer + sizeof (VAR_CHECK_POLICY_COMM_HEADER));
> + IsEnabledParams->State = IsVariablePolicyEnabled ();
> + PolicyCommHeader->Result = EFI_SUCCESS;
> break;
>
> case VAR_CHECK_POLICY_COMMAND_REGISTER:
> @@ -174,7 +180,7 @@ VarCheckPolicyLibMmiHandler (
> ExpectedSize += sizeof (VARIABLE_POLICY_ENTRY);
> if (InternalCommBufferSize < ExpectedSize) {
> DEBUG ((DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n",
> __func__, InternalCommBufferSize, ExpectedSize));
> - PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
> + PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
> break;
> }
>
> @@ -187,11 +193,11 @@ VarCheckPolicyLibMmiHandler (
> (InternalCommBufferSize < ExpectedSize))
> {
> DEBUG ((DEBUG_INFO, "%a - Bad policy entry contents!\n",
> __func__));
> - PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
> + PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
> break;
> }
>
> - PolicyCommmHeader->Result = RegisterVariablePolicy (PolicyEntry);
> + PolicyCommHeader->Result = RegisterVariablePolicy (PolicyEntry);
> break;
>
> case VAR_CHECK_POLICY_COMMAND_DUMP:
> @@ -200,13 +206,13 @@ VarCheckPolicyLibMmiHandler (
> ExpectedSize += sizeof
> (VAR_CHECK_POLICY_COMM_DUMP_PARAMS) +
> VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;
> if (InternalCommBufferSize < ExpectedSize) {
> DEBUG ((DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n",
> __func__, InternalCommBufferSize, ExpectedSize));
> - PolicyCommmHeader->Result = EFI_INVALID_PARAMETER;
> + PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
> break;
> }
>
> // Now that we know we've got a valid size, we can fill in the rest
of
> the data.
> - DumpParamsIn = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS
> *)(InternalPolicyCommmHeader + 1);
> - DumpParamsOut = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS
> *)(PolicyCommmHeader + 1);
> + DumpParamsIn = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS
> *)(InternalPolicyCommHeader + 1);
> + DumpParamsOut = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS
> *)(PolicyCommHeader + 1);
>
> // If we're requesting the first page, initialize the cache and get
the
> sizes.
> if (DumpParamsIn->PageRequested == 0) {
> @@ -289,17 +295,131 @@ VarCheckPolicyLibMmiHandler (
> }
>
> // There's currently no use for this, but it shouldn't be hard to
> implement.
> - PolicyCommmHeader->Result = SubCommandStatus;
> + PolicyCommHeader->Result = SubCommandStatus;
> break;
>
> case VAR_CHECK_POLICY_COMMAND_LOCK:
> - PolicyCommmHeader->Result = LockVariablePolicy ();
> + PolicyCommHeader->Result = LockVariablePolicy ();
> + break;
> +
> + case VAR_CHECK_POLICY_COMMAND_GET_INFO:
> + case VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO:
> + ExpectedSize +=
> VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END +
> VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE;
> +
> + if (InternalCommBufferSize < ExpectedSize) {
> + PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
> + break;
> + }
> +
> + GetInfoParamsInternal =
> (VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS
> *)(InternalPolicyCommHeader + 1);
> + GetInfoParamsExternal =
> (VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS *)(PolicyCommHeader +
> 1);
> +
> + SubCommandStatus = SafeUintnSub (
> +
> VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE,
> +
> GetInfoParamsInternal->InputVariableNameSize,
> + &AllowedOutputVariableNameSize
> + );
> + if (EFI_ERROR (SubCommandStatus)) {
> + PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
> + break;
> + }
> +
> + if (GetInfoParamsInternal->OutputVariableNameSize > 0) {
> + SubCommandStatus = SafeUintnAdd (
> + ((UINTN)GetInfoParamsInternal +
> VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END),
> +
> (UINTN)GetInfoParamsInternal->InputVariableNameSize,
> + (UINTN
> *)&InternalCopyOfOutputVariableName
> + );
> + if (EFI_ERROR (SubCommandStatus)) {
> + PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
> + break;
> + }
> + } else {
> + InternalCopyOfOutputVariableName = NULL;
> + }
> +
> + ZeroMem (&GetInfoParamsInternal->OutputPolicyEntry, sizeof
> (GetInfoParamsInternal->OutputPolicyEntry));
> + ZeroMem (&GetInfoParamsExternal->OutputPolicyEntry, sizeof
> (GetInfoParamsExternal->OutputPolicyEntry));
> +
> + LocalSize =
> (UINTN)GetInfoParamsInternal->OutputVariableNameSize;
> +
> + if (InternalPolicyCommHeader->Command ==
> VAR_CHECK_POLICY_COMMAND_GET_INFO) {
> + SubCommandStatus = GetVariablePolicyInfo (
> +
> GetInfoParamsInternal->InputVariableName,
> +
> &GetInfoParamsInternal->InputVendorGuid,
> + &LocalSize,
> +
> &GetInfoParamsInternal->OutputPolicyEntry.VariablePolicy,
> + InternalCopyOfOutputVariableName
> + );
> + } else if (InternalPolicyCommHeader->Command ==
> VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO) {
> + SubCommandStatus = GetLockOnVariableStateVariablePolicyInfo
> (
> +
> GetInfoParamsInternal->InputVariableName,
> +
> &GetInfoParamsInternal->InputVendorGuid,
> + &LocalSize,
> +
> &GetInfoParamsInternal->OutputPolicyEntry.LockOnVarStatePolicy,
> + InternalCopyOfOutputVariableName
> + );
> + } else {
> + PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
> + break;
> + }
> +
> + if (EFI_ERROR (SubCommandStatus) && (SubCommandStatus !=
> EFI_BUFFER_TOO_SMALL)) {
> + PolicyCommHeader->Result = SubCommandStatus;
> + break;
> + }
> +
> + if (EFI_ERROR (SafeUintnToUint32 (LocalSize,
> &GetInfoParamsInternal->OutputVariableNameSize))) {
> + PolicyCommHeader->Result = EFI_BAD_BUFFER_SIZE;
> + break;
> + }
> +
> + ASSERT (sizeof (GetInfoParamsInternal->OutputPolicyEntry) == sizeof
> (GetInfoParamsExternal->OutputPolicyEntry));
> + CopyMem (
> + &GetInfoParamsExternal->OutputPolicyEntry,
> + &GetInfoParamsInternal->OutputPolicyEntry,
> + sizeof (GetInfoParamsExternal->OutputPolicyEntry)
> + );
> +
> + GetInfoParamsExternal->OutputVariableNameSize =
> GetInfoParamsInternal->OutputVariableNameSize;
> + if (SubCommandStatus == EFI_BUFFER_TOO_SMALL) {
> + PolicyCommHeader->Result = EFI_BUFFER_TOO_SMALL;
> + break;
> + }
> +
> + SubCommandStatus = SafeUintnAdd (
> + ((UINTN)GetInfoParamsExternal +
> VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END),
> +
> (UINTN)GetInfoParamsInternal->InputVariableNameSize,
> + (UINTN
> *)&ExternalCopyOfOutputVariableName
> + );
> + if (EFI_ERROR (SubCommandStatus)) {
> + PolicyCommHeader->Result = EFI_BAD_BUFFER_SIZE;
> + break;
> + }
> +
> + if (GetInfoParamsInternal->OutputVariableNameSize > 0) {
> + SubCommandStatus = StrnCpyS (
> + ExternalCopyOfOutputVariableName,
> + AllowedOutputVariableNameSize,
> + InternalCopyOfOutputVariableName,
> +
> (UINTN)GetInfoParamsInternal->OutputVariableNameSize
> + );
> + ASSERT_EFI_ERROR (SubCommandStatus);
> + } else {
> + // The comm buffer should always have the space for the variable
> policy output
> + // variable name. Fill it with NULL chars if a variable name is
not
> present so
> + // it has a consistent value in the case of variable name
absence.
> + SetMem (ExternalCopyOfOutputVariableName,
> AllowedOutputVariableNameSize, CHAR_NULL);
> + }
> +
> + PolicyCommHeader->Result = SubCommandStatus;
> +
> break;
>
> default:
> // Mark unknown requested command as EFI_UNSUPPORTED.
> - DEBUG ((DEBUG_INFO, "%a - Invalid command requested! %d\n",
> __func__, PolicyCommmHeader->Command));
> - PolicyCommmHeader->Result = EFI_UNSUPPORTED;
> + DEBUG ((DEBUG_INFO, "%a - Invalid command requested! %d\n",
> __func__, PolicyCommHeader->Command));
> + PolicyCommHeader->Result = EFI_UNSUPPORTED;
> break;
> }
>
> @@ -307,8 +427,8 @@ VarCheckPolicyLibMmiHandler (
> DEBUG_VERBOSE,
> "%a - Command %d returning %r.\n",
> __func__,
> - PolicyCommmHeader->Command,
> - PolicyCommmHeader->Result
> + PolicyCommHeader->Command,
> + PolicyCommHeader->Result
> ));
>
> return Status;
> diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> index 214f76ab9626..768662829dbf 100644
> --- a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> @@ -8,6 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>
> #include <Uefi.h>
>
> +#include <Library/BaseLib.h>
> #include <Library/SafeIntLib.h>
> #include <Library/MemoryAllocationLib.h>
> #include <Library/BaseMemoryLib.h>
> @@ -684,6 +685,309 @@ DumpVariablePolicy (
> return EFI_SUCCESS;
> }
>
> +/**
> + This function will return variable policy information for a UEFI
variable
> with a
> + registered variable policy.
> +
> + @param[in] VariableName The
> name of the variable to use for the policy search.
> + @param[in] VendorGuid The
> vendor GUID of the variable to use for the policy search.
> + @param[in,out] VariablePolicyVariableNameBufferSize On input, the
> size, in bytes, of the VariablePolicyVariableName
> + buffer.
> +
> + On
> output, the size, in bytes, needed to store the variable
> + policy
> variable name.
> +
> + If
> testing for the VariablePolicyVariableName buffer size
> +
> needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
> +
> guaranteed to be returned if the variable policy variable name
> + is
> found.
> + @param[out] VariablePolicy Pointer to
> a buffer where the policy entry will be written
> + if
> found.
> + @param[out] VariablePolicyVariableName Pointer to
> a buffer where the variable name used for the
> +
> variable policy will be written if a variable name is
> +
> registered.
> +
> + If the
> variable policy is not associated with a variable name
> + (e.g.
> applied to variable vendor namespace) and this parameter
> + is
> given, this parameter will not be modified and
> +
> VariablePolicyVariableNameBufferSize will be set to zero to
> +
> indicate a name was not present.
> +
> + If the
> pointer given is not NULL,
> +
> VariablePolicyVariableNameBufferSize must be non-NULL.
> +
> + @retval EFI_SUCCESS A variable policy entry was
> found and returned successfully.
> + @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused
> a calculation error.
> + @retval EFI_BUFFER_TOO_SMALL The
> VariablePolicyVariableName buffer value is too small for the size needed.
> + The buffer should now point
> to the size needed.
> + @retval EFI_NOT_READY Variable policy has not yet
> been initialized.
> + @retval EFI_INVALID_PARAMETER A required pointer argument
> passed is NULL. This will be returned if
> + VariablePolicyVariableName
> is non-NULL and VariablePolicyVariableNameBufferSize
> + is NULL.
> + @retval EFI_NOT_FOUND A variable policy was not
> found for the given UEFI variable name and vendor GUID.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetVariablePolicyInfo (
> + IN CONST CHAR16 *VariableName,
> + IN CONST EFI_GUID *VendorGuid,
> + IN OUT UINTN
> *VariablePolicyVariableNameBufferSize OPTIONAL,
> + OUT VARIABLE_POLICY_ENTRY *VariablePolicy,
> + OUT CHAR16 *VariablePolicyVariableName
> OPTIONAL
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 MatchPriority;
> + UINTN LocalVariablePolicyVariableNameBufferSize;
> + UINTN
> RequiredVariablePolicyVariableNameBufferSize;
> + VARIABLE_POLICY_ENTRY *MatchPolicy;
> +
> + Status = EFI_SUCCESS;
> +
> + if (!IsVariablePolicyLibInitialized ()) {
> + return EFI_NOT_READY;
> + }
> +
> + if ((VariableName == NULL) || (VendorGuid == NULL) || (VariablePolicy
==
> NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + MatchPolicy = GetBestPolicyMatch (
> + VariableName,
> + VendorGuid,
> + &MatchPriority
> + );
> + if (MatchPolicy != NULL) {
> + CopyMem (VariablePolicy, MatchPolicy, sizeof (*VariablePolicy));
> +
> + if (VariablePolicyVariableNameBufferSize == NULL) {
> + if (VariablePolicyVariableName != NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + return Status;
> + }
> +
> + if (MatchPolicy->Size != MatchPolicy->OffsetToName) {
> + if (MatchPolicy->Size < MatchPolicy->OffsetToName) {
> + ASSERT (MatchPolicy->Size > MatchPolicy->OffsetToName);
> + return EFI_BAD_BUFFER_SIZE;
> + }
> +
> + RequiredVariablePolicyVariableNameBufferSize =
> (UINTN)(MatchPolicy->Size - MatchPolicy->OffsetToName);
> + ASSERT (RequiredVariablePolicyVariableNameBufferSize > 0);
> +
> + if (*VariablePolicyVariableNameBufferSize <
> RequiredVariablePolicyVariableNameBufferSize) {
> + // Let the caller get the size needed to hold the policy variable
> name
> + *VariablePolicyVariableNameBufferSize =
> RequiredVariablePolicyVariableNameBufferSize;
> + return EFI_BUFFER_TOO_SMALL;
> + }
> +
> + if (VariablePolicyVariableName == NULL) {
> + // If the policy variable name size given is valid, then a valid
policy
> variable name buffer should be provided
> + *VariablePolicyVariableNameBufferSize =
> RequiredVariablePolicyVariableNameBufferSize;
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + LocalVariablePolicyVariableNameBufferSize =
> *VariablePolicyVariableNameBufferSize;
> +
> + // Actual string size should match expected string size
> + if (
> + ((StrnLenS (GET_POLICY_NAME (MatchPolicy),
> RequiredVariablePolicyVariableNameBufferSize) + 1) * sizeof (CHAR16))
> + != RequiredVariablePolicyVariableNameBufferSize)
> + {
> + ASSERT_EFI_ERROR (EFI_BAD_BUFFER_SIZE);
> + return EFI_BAD_BUFFER_SIZE;
> + }
> +
> + *VariablePolicyVariableNameBufferSize =
> RequiredVariablePolicyVariableNameBufferSize;
> +
> + Status = StrnCpyS (
> + VariablePolicyVariableName,
> + LocalVariablePolicyVariableNameBufferSize / sizeof
> (CHAR16),
> + GET_POLICY_NAME (MatchPolicy),
> + RequiredVariablePolicyVariableNameBufferSize / sizeof
> (CHAR16)
> + );
> + ASSERT_EFI_ERROR (Status);
> + } else {
> + // A variable policy variable name is not present. Return values
> according to interface.
> + *VariablePolicyVariableNameBufferSize = 0;
> + }
> +
> + return Status;
> + }
> +
> + return EFI_NOT_FOUND;
> +}
> +
> +/**
> + This function will return the Lock on Variable State policy information
for
> the policy
> + associated with the given UEFI variable.
> +
> + @param[in] VariableName
> The name of the variable to use for the policy search.
> + @param[in] VendorGuid
> The vendor GUID of the variable to use for the policy
> +
> search.
> + @param[in,out] VariableLockPolicyVariableNameBufferSize On input,
> the size, in bytes, of the
> +
> VariableLockPolicyVariableName buffer.
> +
> +
> On output, the size, in bytes, needed to store the variable
> +
> policy variable name.
> +
> + If
> testing for the VariableLockPolicyVariableName buffer
> +
> size needed, set this value to zero so EFI_BUFFER_TOO_SMALL
> + is
> guaranteed to be returned if the variable policy variable
> +
> name is found.
> + @param[out] VariablePolicy
> Pointer to a buffer where the policy entry will be written
> + if
> found.
> + @param[out] VariableLockPolicyVariableName
> Pointer to a buffer where the variable name used for the
> +
> variable lock on variable state policy will be written if
> + a
> variable name is registered.
> +
> + If
> the lock on variable policy is not associated with a
> +
> variable name (e.g. applied to variable vendor namespace)
> +
> and this parameter is given, this parameter will not be
> +
> modified and VariableLockPolicyVariableNameBufferSize will
> +
> be set to zero to indicate a name was not present.
> +
> + If
> the pointer given is not NULL,
> +
> VariableLockPolicyVariableNameBufferSize must be non-NULL.
> +
> + @retval EFI_SUCCESS A Lock on Variable State
> variable policy entry was found and returned
> + successfully.
> + @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused
> a calculation error.
> + @retval EFI_BUFFER_TOO_SMALL The
> VariableLockPolicyVariableName buffer is too small for the size needed.
> + The buffer should now point
> to the size needed.
> + @retval EFI_NOT_READY Variable policy has not yet
> been initialized.
> + @retval EFI_INVALID_PARAMETER A required pointer argument
> passed is NULL. This will be returned if
> +
> VariableLockPolicyVariableName is non-NULL and
> +
> VariableLockPolicyVariableNameBufferSize is NULL.
> + @retval EFI_NOT_FOUND A Lock on Variable State
> variable policy was not found for the given UEFI
> + variable name and vendor
> GUID.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetLockOnVariableStateVariablePolicyInfo (
> + IN CONST CHAR16 *VariableName,
> + IN CONST EFI_GUID *VendorGuid,
> + IN OUT UINTN
> *VariableLockPolicyVariableNameBufferSize OPTIONAL,
> + OUT VARIABLE_LOCK_ON_VAR_STATE_POLICY *VariablePolicy,
> + OUT CHAR16
> *VariableLockPolicyVariableName OPTIONAL
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 MatchPriority;
> + UINTN
> RequiredVariablePolicyVariableNameBufferSize;
> + UINTN
> RequiredVariableLockPolicyVariableNameBufferSize;
> + UINTN
> LocalVariablePolicyLockVariableNameBufferSize;
> + UINTN
> LockOnVarStatePolicyEndOffset;
> + CHAR16
> *LocalVariableLockPolicyVariableName;
> + VARIABLE_LOCK_ON_VAR_STATE_POLICY *LocalLockOnVarStatePolicy;
> + VARIABLE_POLICY_ENTRY *MatchPolicy;
> +
> + Status = EFI_SUCCESS;
> +
> + if (!IsVariablePolicyLibInitialized ()) {
> + return EFI_NOT_READY;
> + }
> +
> + if ((VariableName == NULL) || (VendorGuid == NULL) || (VariablePolicy
==
> NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + MatchPolicy = GetBestPolicyMatch (
> + VariableName,
> + VendorGuid,
> + &MatchPriority
> + );
> + if (MatchPolicy != NULL) {
> + if (MatchPolicy->LockPolicyType !=
> VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE) {
> + return EFI_NOT_FOUND;
> + }
> +
> + Status = SafeUintnAdd (
> + sizeof (VARIABLE_POLICY_ENTRY),
> + sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY),
> + &LockOnVarStatePolicyEndOffset
> + );
> + if (EFI_ERROR (Status) || (LockOnVarStatePolicyEndOffset >
> (UINTN)MatchPolicy->Size)) {
> + return EFI_BAD_BUFFER_SIZE;
> + }
> +
> + LocalLockOnVarStatePolicy =
> (VARIABLE_LOCK_ON_VAR_STATE_POLICY *)(MatchPolicy + 1);
> + CopyMem (VariablePolicy, LocalLockOnVarStatePolicy, sizeof
> (*LocalLockOnVarStatePolicy));
> +
> + if ((VariableLockPolicyVariableNameBufferSize == NULL)) {
> + if (VariableLockPolicyVariableName != NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + return Status;
> + }
> +
> + // The name offset should be less than or equal to the total policy
size.
> + if (MatchPolicy->Size < MatchPolicy->OffsetToName) {
> + return EFI_BAD_BUFFER_SIZE;
> + }
> +
> + RequiredVariablePolicyVariableNameBufferSize =
> (UINTN)(MatchPolicy->Size - MatchPolicy->OffsetToName);
> + RequiredVariableLockPolicyVariableNameBufferSize =
> MatchPolicy->Size -
> +
> (LockOnVarStatePolicyEndOffset +
> RequiredVariablePolicyVariableNameBufferSize);
> +
> + LocalVariablePolicyLockVariableNameBufferSize =
> *VariableLockPolicyVariableNameBufferSize;
> + *VariableLockPolicyVariableNameBufferSize =
> RequiredVariableLockPolicyVariableNameBufferSize;
> +
> + if (LocalVariablePolicyLockVariableNameBufferSize <
> RequiredVariableLockPolicyVariableNameBufferSize) {
> + // Let the caller get the size needed to hold the policy variable
name
> + return EFI_BUFFER_TOO_SMALL;
> + }
> +
> + if (VariableLockPolicyVariableName == NULL) {
> + // If the policy variable name size given is valid, then a valid
policy
> variable name buffer should be provided
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (RequiredVariableLockPolicyVariableNameBufferSize == 0) {
> + return Status;
> + }
> +
> + LocalVariableLockPolicyVariableName = (CHAR16 *)((UINT8
> *)LocalLockOnVarStatePolicy + sizeof (*LocalLockOnVarStatePolicy));
> + *VariableLockPolicyVariableNameBufferSize =
> RequiredVariableLockPolicyVariableNameBufferSize;
> +
> + // Actual string size should match expected string size (if a
variable
> name is present)
> + if (
> + (RequiredVariablePolicyVariableNameBufferSize > 0) &&
> + (((StrnLenS (GET_POLICY_NAME (MatchPolicy),
> RequiredVariablePolicyVariableNameBufferSize) + 1) * sizeof (CHAR16)) !=
> + RequiredVariablePolicyVariableNameBufferSize))
> + {
> + ASSERT_EFI_ERROR (EFI_BAD_BUFFER_SIZE);
> + return EFI_BAD_BUFFER_SIZE;
> + }
> +
> + // Actual string size should match expected string size (if here,
variable
> lock variable name is present)
> + if (
> + ((StrnLenS (LocalVariableLockPolicyVariableName,
> RequiredVariableLockPolicyVariableNameBufferSize) + 1) * sizeof
> (CHAR16)) !=
> + RequiredVariableLockPolicyVariableNameBufferSize)
> + {
> + ASSERT_EFI_ERROR (EFI_BAD_BUFFER_SIZE);
> + return EFI_BAD_BUFFER_SIZE;
> + }
> +
> + Status = StrnCpyS (
> + VariableLockPolicyVariableName,
> + LocalVariablePolicyLockVariableNameBufferSize / sizeof
> (CHAR16),
> + LocalVariableLockPolicyVariableName,
> + RequiredVariableLockPolicyVariableNameBufferSize /
> sizeof (CHAR16)
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + return Status;
> + }
> +
> + return EFI_NOT_FOUND;
> +}
> +
> /**
> This API function returns whether or not the policy engine is
> currently being enforced.
> diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
> index d5c409c914d1..c4ccdfd20f74 100644
> --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
> +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
> @@ -33,7 +33,9 @@ EDKII_VARIABLE_POLICY_PROTOCOL
> mVariablePolicyProtocol = {
> ProtocolIsVariablePolicyEnabled,
> RegisterVariablePolicy,
> DumpVariablePolicy,
> - LockVariablePolicy
> + LockVariablePolicy,
> + GetVariablePolicyInfo,
> + GetLockOnVariableStateVariablePolicyInfo
> };
> EDKII_VAR_CHECK_PROTOCOL mVarCheck = {
> VarCheckRegisterSetVariableCheckHandler,
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
> index 6151a2ba0b18..0dd72dde27ce 100644
> ---
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
> +++
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
> @@ -410,6 +410,338 @@ ProtocolLockVariablePolicy (
> return (EFI_ERROR (Status)) ? Status : PolicyHeader->Result;
> }
>
> +/**
> + Internal implementation to retrieve variable information for a given
UEFI
> variable that is shared
> + between different policy types.
> +
> + Currently, the two policy structure types supported (and all that is
defined)
> are VARIABLE_POLICY_ENTRY
> + and VARIABLE_LOCK_ON_VAR_STATE_POLICY.
> +
> + @param[in] Command The
> command value to use in the communicate call.
> + @param[in] VariableName The
> name of the variable to use for the policy search.
> + @param[in] VendorGuid The
> vendor GUID of the variable to use for the policy search.
> + @param[in,out] VariablePolicyVariableNameBufferSize On input, the
> size, in bytes, of the VariablePolicyVariableName
> + buffer.
> +
> + On
> output, the size, in bytes, needed to store the variable
> + policy
> variable name.
> +
> + If
> testing for the VariablePolicyVariableName buffer size
> +
> needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
> +
> guaranteed to be returned if the variable policy variable name
> + is
> found.
> + @param[out] VariablePolicy Pointer to
> a buffer where the policy entry will be written
> + if
> found.
> + @param[out] VariablePolicyVariableName Pointer to
> a buffer where the variable name used for the
> +
> variable policy will be written if a variable name is
> +
> registered.
> +
> + If the
> variable policy is not associated with a variable name
> + (e.g.
> applied to variable vendor namespace) and this parameter
> + is
> given, this parameter will not be modified and
> +
> VariablePolicyVariableNameBufferSize will be set to zero to
> +
> indicate a name was not present.
> +
> + If the
> pointer given is not NULL,
> +
> VariablePolicyVariableNameBufferSize must be non-NULL.
> +
> + @retval EFI_SUCCESS A variable policy entry was
> found and returned successfully.
> + @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused
> a calculation error.
> + @retval EFI_BUFFER_TOO_SMALL The
> VariablePolicyVariableName buffer value is too small for the size needed.
> + The buffer should now point
> to the size needed.
> + @retval EFI_NOT_READY Variable policy has not yet
> been initialized.
> + @retval EFI_INVALID_PARAMETER A required pointer argument
> passed is NULL. This will be returned if
> + VariablePolicyVariableName
> is non-NULL and VariablePolicyVariableNameBufferSize
> + is NULL. It can also be
> returned if the Command value provided is invalid.
> + @retval EFI_NOT_FOUND A variable policy was not
> found for the given UEFI variable name and vendor GUID.
> +
> +
> +**/
> +STATIC
> +EFI_STATUS
> +InternalProtocolGetVariablePolicyInfo (
> + IN UINT32 Command,
> + IN CONST CHAR16 *VariableName,
> + IN CONST EFI_GUID *VendorGuid,
> + IN OUT UINTN *VariablePolicyVariableNameBufferSize, OPTIONAL
> + OUT VOID *VariablePolicy,
> + OUT CHAR16
> *VariablePolicyVariableName OPTIONAL
> + )
> +{
> + EFI_STATUS Status;
> + CHAR16 *OutputVariableName;
> + EFI_MM_COMMUNICATE_HEADER *CommHeader;
> + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader;
> + VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS *CommandParams;
> + UINTN
> AllowedOutputVariableNameSize;
> + UINTN BufferSize;
> + UINTN VariableNameSize;
> +
> + if ((VariableName == NULL) || (VendorGuid == NULL) || (VariablePolicy
==
> NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + switch (Command) {
> + case VAR_CHECK_POLICY_COMMAND_GET_INFO:
> + case VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO:
> + break;
> + default:
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + AcquireLockOnlyAtBootTime (&mMmCommunicationLock);
> +
> + VariableNameSize = StrnSizeS (
> + VariableName,
> +
> (VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE -
> VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END)
> + );
> + if (VariableNameSize >=
> (VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE -
> VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> +
> + if ((VariablePolicyVariableName != NULL) &&
> (VariablePolicyVariableNameBufferSize == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> +
> + BufferSize = mMmCommunicationBufferSize;
> + CommHeader = mMmCommunicationBuffer;
> +
> + Status = SafeUintnSub (
> + VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE,
> + VariableNameSize,
> + &AllowedOutputVariableNameSize
> + );
> + if (EFI_ERROR (Status)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> +
> + if (VariablePolicyVariableNameBufferSize != NULL) {
> + AllowedOutputVariableNameSize = MIN
> (AllowedOutputVariableNameSize, *VariablePolicyVariableNameBufferSize);
> + } else {
> + AllowedOutputVariableNameSize = 0;
> + }
> +
> + PolicyHeader = (VAR_CHECK_POLICY_COMM_HEADER
> *)&CommHeader->Data;
> + CommandParams = (VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS
> *)(PolicyHeader + 1);
> +
> + CopyGuid (&CommHeader->HeaderGuid,
> &gVarCheckPolicyLibMmiHandlerGuid);
> + CommHeader->MessageLength = BufferSize - OFFSET_OF
> (EFI_MM_COMMUNICATE_HEADER, Data);
> + PolicyHeader->Signature = VAR_CHECK_POLICY_COMM_SIG;
> + PolicyHeader->Revision = VAR_CHECK_POLICY_COMM_REVISION;
> + PolicyHeader->Command = Command;
> +
> + ZeroMem ((VOID *)&CommandParams->OutputPolicyEntry, sizeof
> (CommandParams->OutputPolicyEntry));
> + CopyGuid (&CommandParams->InputVendorGuid, VendorGuid);
> + Status = SafeUintnToUint32 (VariableNameSize,
> &CommandParams->InputVariableNameSize);
> + if (EFI_ERROR (Status)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> +
> + Status = SafeUintnToUint32 (AllowedOutputVariableNameSize,
> &CommandParams->OutputVariableNameSize);
> + if (EFI_ERROR (Status)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> +
> + if (AllowedOutputVariableNameSize > 0) {
> + Status = StrnCpyS (
> + CommandParams->InputVariableName,
> + AllowedOutputVariableNameSize / sizeof (CHAR16),
> + VariableName,
> + (UINTN)CommandParams->InputVariableNameSize /
> sizeof (CHAR16)
> + );
> + ASSERT_EFI_ERROR (Status);
> + }
> +
> + Status = InternalMmCommunicate (CommHeader, &BufferSize);
> + if (Status == EFI_SUCCESS) {
> + CopyMem (
> + VariablePolicy,
> + (VOID *)&CommandParams->OutputPolicyEntry,
> + (Command == VAR_CHECK_POLICY_COMMAND_GET_INFO) ?
> + sizeof (CommandParams->OutputPolicyEntry.VariablePolicy) :
> + sizeof (CommandParams->OutputPolicyEntry.LockOnVarStatePolicy)
> + );
> +
> + if (VariablePolicyVariableNameBufferSize == NULL) {
> + if (VariablePolicyVariableName != NULL) {
> + Status = EFI_INVALID_PARAMETER;
> + }
> +
> + goto Done;
> + }
> +
> + if (PolicyHeader->Result == EFI_BUFFER_TOO_SMALL) {
> + *VariablePolicyVariableNameBufferSize =
> (UINTN)CommandParams->OutputVariableNameSize;
> + goto Done;
> + }
> +
> + if (PolicyHeader->Result == EFI_SUCCESS) {
> + if (CommandParams->OutputVariableNameSize > 0) {
> + Status = SafeUintnAdd (
> + ((UINTN)CommandParams +
> VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END),
> +
> (UINTN)CommandParams->InputVariableNameSize,
> + (UINTN *)&OutputVariableName
> + );
> + if (EFI_ERROR (Status)) {
> + Status = EFI_BAD_BUFFER_SIZE;
> + goto Done;
> + }
> +
> + Status = StrnCpyS (
> + VariablePolicyVariableName,
> + *VariablePolicyVariableNameBufferSize / sizeof
> (CHAR16),
> + OutputVariableName,
> +
> (UINTN)CommandParams->OutputVariableNameSize
> + );
> + ASSERT_EFI_ERROR (Status);
> + *VariablePolicyVariableNameBufferSize =
> (UINTN)CommandParams->OutputVariableNameSize;
> + } else {
> + // A variable policy variable name is not present. Return values
> according to interface.
> + *VariablePolicyVariableNameBufferSize = 0;
> + }
> + }
> + }
> +
> +Done:
> + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock);
> +
> + return (EFI_ERROR (Status)) ? Status : PolicyHeader->Result;
> +}
> +
> +/**
> + This function will return variable policy information for a UEFI
variable
> with a
> + registered variable policy.
> +
> + @param[in] VariableName The
> name of the variable to use for the policy search.
> + @param[in] VendorGuid The
> vendor GUID of the variable to use for the policy search.
> + @param[in,out] VariablePolicyVariableNameBufferSize On input, the
> size, in bytes, of the VariablePolicyVariableName
> + buffer.
> +
> + On
> output, the size, in bytes, needed to store the variable
> + policy
> variable name.
> +
> + If
> testing for the VariablePolicyVariableName buffer size
> +
> needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
> +
> guaranteed to be returned if the variable policy variable name
> + is
> found.
> + @param[out] VariablePolicy Pointer to
> a buffer where the policy entry will be written
> + if
> found.
> + @param[out] VariablePolicyVariableName Pointer to
> a buffer where the variable name used for the
> +
> variable policy will be written if a variable name is
> +
> registered.
> +
> + If the
> variable policy is not associated with a variable name
> + (e.g.
> applied to variable vendor namespace) and this parameter
> + is
> given, this parameter will not be modified and
> +
> VariablePolicyVariableNameBufferSize will be set to zero to
> +
> indicate a name was not present.
> +
> + If the
> pointer given is not NULL,
> +
> VariablePolicyVariableNameBufferSize must be non-NULL.
> +
> + @retval EFI_SUCCESS A variable policy entry was
> found and returned successfully.
> + @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused
> a calculation error.
> + @retval EFI_BUFFER_TOO_SMALL The
> VariablePolicyVariableName buffer value is too small for the size needed.
> + The buffer should now point
> to the size needed.
> + @retval EFI_NOT_READY Variable policy has not yet
> been initialized.
> + @retval EFI_INVALID_PARAMETER A required pointer argument
> passed is NULL. This will be returned if
> + VariablePolicyVariableName
> is non-NULL and VariablePolicyVariableNameBufferSize
> + is NULL.
> + @retval EFI_NOT_FOUND A variable policy was not
> found for the given UEFI variable name and vendor GUID.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +ProtocolGetVariablePolicyInfo (
> + IN CONST CHAR16 *VariableName,
> + IN CONST EFI_GUID *VendorGuid,
> + IN OUT UINTN *VariablePolicyVariableNameBufferSize, OPTIONAL
> + OUT VARIABLE_POLICY_ENTRY *VariablePolicy,
> + OUT CHAR16
> *VariablePolicyVariableName OPTIONAL
> + )
> +{
> + return InternalProtocolGetVariablePolicyInfo (
> + VAR_CHECK_POLICY_COMMAND_GET_INFO,
> + VariableName,
> + VendorGuid,
> + VariablePolicyVariableNameBufferSize,
> + VariablePolicy,
> + VariablePolicyVariableName
> + );
> +}
> +
> +/**
> + This function will return the Lock on Variable State policy information
for
> the policy
> + associated with the given UEFI variable.
> +
> + @param[in] VariableName
> The name of the variable to use for the policy search.
> + @param[in] VendorGuid
> The vendor GUID of the variable to use for the policy
> +
> search.
> + @param[in,out] VariableLockPolicyVariableNameBufferSize On input,
> the size, in bytes, of the
> +
> VariableLockPolicyVariableName buffer.
> +
> +
> On output, the size, in bytes, needed to store the variable
> +
> policy variable name.
> +
> + If
> testing for the VariableLockPolicyVariableName buffer
> + P
> size needed, set this value to zero so EFI_BUFFER_TOO_SMALL
> + is
> guaranteed to be returned if the variable policy variable
> +
> name is found.
> + @param[out] VariablePolicy
> Pointer to a buffer where the policy entry will be written
> + if
> found.
> + @param[out] VariableLockPolicyVariableName
> Pointer to a buffer where the variable name used for the
> +
> variable lock on variable state policy will be written if
> + a
> variable name is registered.
> +
> + If
> the lock on variable policy is not associated with a
> +
> variable name (e.g. applied to variable vendor namespace)
> +
> and this parameter is given, this parameter will not be
> +
> modified and VariableLockPolicyVariableNameBufferSize will
> +
> be set to zero to indicate a name was not present.
> +
> + If
> the pointer given is not NULL,
> +
> VariableLockPolicyVariableNameBufferSize must be non-NULL.
> +
> + @retval EFI_SUCCESS A Lock on Variable State
> variable policy entry was found and returned
> + successfully.
> + @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused
> a calculation error.
> + @retval EFI_BUFFER_TOO_SMALL The
> VariableLockPolicyVariableName buffer is too small for the size needed.
> + The buffer should now point
> to the size needed.
> + @retval EFI_NOT_READY Variable policy has not yet
> been initialized.
> + @retval EFI_INVALID_PARAMETER A required pointer argument
> passed is NULL. This will be returned if
> +
> VariableLockPolicyVariableName is non-NULL and
> +
> VariableLockPolicyVariableNameBufferSize is NULL.
> + @retval EFI_NOT_FOUND A Lock on Variable State
> variable policy was not found for the given UEFI
> + variable name and vendor
> GUID.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +ProtocolGetLockOnVariableStateVariablePolicyInfo (
> + IN CONST CHAR16 *VariableName,
> + IN CONST EFI_GUID *VendorGuid,
> + IN OUT UINTN *VariableLockPolicyVariableNameBufferSize, OPTIONAL
> + OUT VARIABLE_LOCK_ON_VAR_STATE_POLICY *VariablePolicy,
> + OUT CHAR16
> *VariableLockPolicyVariableName OPTIONAL
> + )
> +{
> + return InternalProtocolGetVariablePolicyInfo (
> +
> VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO,
> + VariableName,
> + VendorGuid,
> + VariableLockPolicyVariableNameBufferSize,
> + VariablePolicy,
> + VariableLockPolicyVariableName
> + );
> +}
> +
> /**
> This helper function locates the shared comm buffer and assigns it to
input
> pointers.
>
> @@ -514,12 +846,14 @@ VariablePolicySmmDxeMain (
> }
>
> // Configure the VariablePolicy protocol structure.
> - mVariablePolicyProtocol.Revision =
> EDKII_VARIABLE_POLICY_PROTOCOL_REVISION;
> - mVariablePolicyProtocol.DisableVariablePolicy =
> ProtocolDisableVariablePolicy;
> - mVariablePolicyProtocol.IsVariablePolicyEnabled =
> ProtocolIsVariablePolicyEnabled;
> - mVariablePolicyProtocol.RegisterVariablePolicy =
> ProtocolRegisterVariablePolicy;
> - mVariablePolicyProtocol.DumpVariablePolicy =
> ProtocolDumpVariablePolicy;
> - mVariablePolicyProtocol.LockVariablePolicy =
> ProtocolLockVariablePolicy;
> + mVariablePolicyProtocol.Revision
> = EDKII_VARIABLE_POLICY_PROTOCOL_REVISION;
> + mVariablePolicyProtocol.DisableVariablePolicy =
> ProtocolDisableVariablePolicy;
> + mVariablePolicyProtocol.IsVariablePolicyEnabled =
> ProtocolIsVariablePolicyEnabled;
> + mVariablePolicyProtocol.RegisterVariablePolicy =
> ProtocolRegisterVariablePolicy;
> + mVariablePolicyProtocol.DumpVariablePolicy
> = ProtocolDumpVariablePolicy;
> + mVariablePolicyProtocol.LockVariablePolicy =
> ProtocolLockVariablePolicy;
> + mVariablePolicyProtocol.GetVariablePolicyInfo =
> ProtocolGetVariablePolicyInfo;
> + mVariablePolicyProtocol.GetLockOnVariableStateVariablePolicyInfo =
> ProtocolGetLockOnVariableStateVariablePolicyInfo;
>
> // Register all the protocols and return the status.
> Status = gBS->InstallMultipleProtocolInterfaces (
> diff --git a/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
> b/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
> index ff3d4a1fd68a..a692fa40c946 100644
> --- a/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
> +++ b/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
> @@ -32,23 +32,52 @@ typedef struct
> _VAR_CHECK_POLICY_COMM_DUMP_PARAMS {
> BOOLEAN HasMore;
> } VAR_CHECK_POLICY_COMM_DUMP_PARAMS;
>
> +typedef union {
> + VARIABLE_POLICY_ENTRY VariablePolicy;
> + VARIABLE_LOCK_ON_VAR_STATE_POLICY LockOnVarStatePolicy;
> +} VAR_CHECK_POLICY_OUTPUT_POLICY_ENTRY;
> +
> +typedef struct _VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS {
> + EFI_GUID InputVendorGuid;
> + UINT32
> InputVariableNameSize;
> + UINT32
> OutputVariableNameSize;
> + VAR_CHECK_POLICY_OUTPUT_POLICY_ENTRY OutputPolicyEntry;
> + CHAR16 InputVariableName[1];
> +} VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS;
> +
> #pragma pack(pop)
>
> +#define VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END \
> +
> (OFFSET_OF(VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS,
> InputVariableName))
> +
> // Make sure that we will hold at least the headers.
> #define VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE
> MAX((OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + sizeof
> (VAR_CHECK_POLICY_COMM_HEADER) + EFI_PAGES_TO_SIZE(1)),
> EFI_PAGES_TO_SIZE(4))
> #define VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE
> (VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE - \
>
> (OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + \
>
> sizeof(VAR_CHECK_POLICY_COMM_HEADER) + \
>
> sizeof(VAR_CHECK_POLICY_COMM_DUMP_PARAMS)))
> +
> +#define VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE
> (VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE - \
> +
> (OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + \
> +
> sizeof(VAR_CHECK_POLICY_COMM_HEADER) + \
> +
> OFFSET_OF(VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS,
> InputVariableName)))
> +
> STATIC_ASSERT (
> VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE <
> VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE,
> "an integer underflow may have occurred calculating
> VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE"
> );
>
> -#define VAR_CHECK_POLICY_COMMAND_DISABLE 0x0001
> -#define VAR_CHECK_POLICY_COMMAND_IS_ENABLED 0x0002
> -#define VAR_CHECK_POLICY_COMMAND_REGISTER 0x0003
> -#define VAR_CHECK_POLICY_COMMAND_DUMP 0x0004
> -#define VAR_CHECK_POLICY_COMMAND_LOCK 0x0005
> +STATIC_ASSERT (
> + VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE <
> VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE,
> + "an integer underflow may have occurred calculating
> VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE"
> + );
> +
> +#define VAR_CHECK_POLICY_COMMAND_DISABLE
> 0x0001
> +#define VAR_CHECK_POLICY_COMMAND_IS_ENABLED
> 0x0002
> +#define VAR_CHECK_POLICY_COMMAND_REGISTER
> 0x0003
> +#define VAR_CHECK_POLICY_COMMAND_DUMP
> 0x0004
> +#define VAR_CHECK_POLICY_COMMAND_LOCK
> 0x0005
> +#define VAR_CHECK_POLICY_COMMAND_GET_INFO
> 0x0006
> +#define VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO
> 0x0007
>
> #endif // _VAR_CHECK_POLICY_MMI_COMMON_H_
> diff --git a/MdeModulePkg/Include/Library/VariablePolicyLib.h
> b/MdeModulePkg/Include/Library/VariablePolicyLib.h
> index 63c49fbca1ed..bc4e26b2d434 100644
> --- a/MdeModulePkg/Include/Library/VariablePolicyLib.h
> +++ b/MdeModulePkg/Include/Library/VariablePolicyLib.h
> @@ -102,6 +102,113 @@ DumpVariablePolicy (
> IN OUT UINT32 *Size
> );
>
> +/**
> + This function will return variable policy information for a UEFI
variable
> with a
> + registered variable policy.
> +
> + @param[in] VariableName The
> name of the variable to use for the policy search.
> + @param[in] VendorGuid The
> vendor GUID of the variable to use for the policy search.
> + @param[in,out] VariablePolicyVariableNameBufferSize On input, the
> size, in bytes, of the VariablePolicyVariableName
> + buffer.
> +
> + On
> output, the size, in bytes, needed to store the variable
> + policy
> variable name.
> +
> + If
> testing for the VariablePolicyVariableName buffer size
> +
> needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
> +
> guaranteed to be returned if the variable policy variable name
> + is
> found.
> + @param[out] VariablePolicy Pointer to
> a buffer where the policy entry will be written
> + if
> found.
> + @param[out] VariablePolicyVariableName Pointer to
> a buffer where the variable name used for the
> +
> variable policy will be written if a variable name is
> +
> registered.
> +
> + If the
> variable policy is not associated with a variable name
> + (e.g.
> applied to variable vendor namespace) and this parameter
> + is
> given, this parameter will not be modified and
> +
> VariablePolicyVariableNameBufferSize will be set to zero to
> +
> indicate a name was not present.
> +
> + If the
> pointer given is not NULL,
> +
> VariablePolicyVariableNameBufferSize must be non-NULL.
> +
> + @retval EFI_SUCCESS A variable policy entry was
> found and returned successfully.
> + @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused
> a calculation error.
> + @retval EFI_BUFFER_TOO_SMALL The
> VariablePolicyVariableName buffer value is too small for the size needed.
> + The buffer should now point
> to the size needed.
> + @retval EFI_NOT_READY Variable policy has not yet
> been initialized.
> + @retval EFI_INVALID_PARAMETER A required pointer argument
> passed is NULL. This will be returned if
> + VariablePolicyVariableName
> is non-NULL and VariablePolicyVariableNameBufferSize
> + is NULL.
> + @retval EFI_NOT_FOUND A variable policy was not
> found for the given UEFI variable name and vendor GUID.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetVariablePolicyInfo (
> + IN CONST CHAR16 *VariableName,
> + IN CONST EFI_GUID *VendorGuid,
> + IN OUT UINTN
> *VariablePolicyVariableNameBufferSize OPTIONAL,
> + OUT VARIABLE_POLICY_ENTRY *VariablePolicy,
> + OUT CHAR16 *VariablePolicyVariableName
> OPTIONAL
> + );
> +
> +/**
> + This function will return the Lock on Variable State policy information
for
> the policy
> + associated with the given UEFI variable.
> +
> + @param[in] VariableName
> The name of the variable to use for the policy search.
> + @param[in] VendorGuid
> The vendor GUID of the variable to use for the policy
> +
> search.
> + @param[in,out] VariableLockPolicyVariableNameBufferSize On input,
> the size, in bytes, of the
> +
> VariableLockPolicyVariableName buffer.
> +
> +
> On output, the size, in bytes, needed to store the variable
> +
> policy variable name.
> +
> + If
> testing for the VariableLockPolicyVariableName buffer
> +
> size needed, set this value to zero so EFI_BUFFER_TOO_SMALL
> + is
> guaranteed to be returned if the variable policy variable
> +
> name is found.
> + @param[out] VariablePolicy
> Pointer to a buffer where the policy entry will be written
> + if
> found.
> + @param[out] VariableLockPolicyVariableName
> Pointer to a buffer where the variable name used for the
> +
> variable lock on variable state policy will be written if
> + a
> variable name is registered.
> +
> + If
> the lock on variable policy is not associated with a
> +
> variable name (e.g. applied to variable vendor namespace)
> +
> and this parameter is given, this parameter will not be
> +
> modified and VariableLockPolicyVariableNameBufferSize will
> +
> be set to zero to indicate a name was not present.
> +
> + If
> the pointer given is not NULL,
> +
> VariableLockPolicyVariableNameBufferSize must be non-NULL.
> +
> + @retval EFI_SUCCESS A Lock on Variable State
> variable policy entry was found and returned
> + successfully.
> + @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused
> a calculation error.
> + @retval EFI_BUFFER_TOO_SMALL The
> VariableLockPolicyVariableName buffer is too small for the size needed.
> + The buffer should now point
> to the size needed.
> + @retval EFI_NOT_READY Variable policy has not yet
> been initialized.
> + @retval EFI_INVALID_PARAMETER A required pointer argument
> passed is NULL. This will be returned if
> +
> VariableLockPolicyVariableName is non-NULL and
> +
> VariableLockPolicyVariableNameBufferSize is NULL.
> + @retval EFI_NOT_FOUND A Lock on Variable State
> variable policy was not found for the given UEFI
> + variable name and vendor
> GUID.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetLockOnVariableStateVariablePolicyInfo (
> + IN CONST CHAR16 *VariableName,
> + IN CONST EFI_GUID *VendorGuid,
> + IN OUT UINTN
> *VariableLockPolicyVariableNameBufferSize OPTIONAL,
> + OUT VARIABLE_LOCK_ON_VAR_STATE_POLICY *VariablePolicy,
> + OUT CHAR16
> *VariableLockPolicyVariableName OPTIONAL
> + );
> +
> /**
> This API function returns whether or not the policy engine is
> currently being enforced.
> diff --git a/MdeModulePkg/Include/Protocol/VariablePolicy.h
> b/MdeModulePkg/Include/Protocol/VariablePolicy.h
> index 98d739401f83..4b57f70a9da8 100644
> --- a/MdeModulePkg/Include/Protocol/VariablePolicy.h
> +++ b/MdeModulePkg/Include/Protocol/VariablePolicy.h
> @@ -9,7 +9,17 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #ifndef __EDKII_VARIABLE_POLICY_PROTOCOL__
> #define __EDKII_VARIABLE_POLICY_PROTOCOL__
>
> -#define EDKII_VARIABLE_POLICY_PROTOCOL_REVISION
> 0x0000000000010000
> +#define EDKII_VARIABLE_POLICY_PROTOCOL_REVISION
> 0x0000000000020000
> +
> +/*
> + Rev 0x0000000000010000:
> + - Initial protocol definition
> +
> + Rev 0x0000000000020000:
> + - Add GetVariablePolicyInfo() API
> + - Add GetLockOnVariableStateVariablePolicyInfo() API
> +
> +*/
>
> #define EDKII_VARIABLE_POLICY_PROTOCOL_GUID \
> { \
> @@ -141,13 +151,122 @@ EFI_STATUS
> VOID
> );
>
> +/**
> + This function will return variable policy information for a UEFI
variable
> with a
> + registered variable policy.
> +
> + @param[in] VariableName The
> name of the variable to use for the policy search.
> + @param[in] VendorGuid The
> vendor GUID of the variable to use for the policy search.
> + @param[in,out] VariablePolicyVariableNameBufferSize On input, the
> size, in bytes, of the VariablePolicyVariableName
> + buffer.
> +
> + On
> output, the size, in bytes, needed to store the variable
> + policy
> variable name.
> +
> + If
> testing for the VariablePolicyVariableName buffer size
> +
> needed, set this value to zero so EFI_BUFFER_TOO_SMALL is
> +
> guaranteed to be returned if the variable policy variable name
> + is
> found.
> + @param[out] VariablePolicy Pointer to
> a buffer where the policy entry will be written
> + if
> found.
> + @param[out] VariablePolicyVariableName Pointer to
> a buffer where the variable name used for the
> +
> variable policy will be written if a variable name is
> +
> registered.
> +
> + If the
> variable policy is not associated with a variable name
> + (e.g.
> applied to variable vendor namespace) and this parameter
> + is
> given, this parameter will not be modified and
> +
> VariablePolicyVariableNameBufferSize will be set to zero to
> +
> indicate a name was not present.
> +
> + If the
> pointer given is not NULL,
> +
> VariablePolicyVariableNameBufferSize must be non-NULL.
> +
> + @retval EFI_SUCCESS A variable policy entry was
> found and returned successfully.
> + @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused
> a calculation error.
> + @retval EFI_BUFFER_TOO_SMALL The
> VariablePolicyVariableName buffer value is too small for the size needed.
> + The buffer should now point
> to the size needed.
> + @retval EFI_NOT_READY Variable policy has not yet
> been initialized.
> + @retval EFI_INVALID_PARAMETER A required pointer argument
> passed is NULL. This will be returned if
> + VariablePolicyVariableName
> is non-NULL and VariablePolicyVariableNameBufferSize
> + is NULL.
> + @retval EFI_NOT_FOUND A variable policy was not
> found for the given UEFI variable name and vendor GUID.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_VARIABLE_POLICY_INFO)(
> + IN CONST CHAR16 *VariableName,
> + IN CONST EFI_GUID *VendorGuid,
> + IN OUT UINTN
> *VariablePolicyVariableNameBufferSize OPTIONAL,
> + OUT VARIABLE_POLICY_ENTRY *VariablePolicy,
> + OUT CHAR16
> *VariablePolicyVariableName OPTIONAL
> + );
> +
> +/**
> + This function will return the Lock on Variable State policy information
for
> the policy
> + associated with the given UEFI variable.
> +
> + @param[in] VariableName
> The name of the variable to use for the policy search.
> + @param[in] VendorGuid
> The vendor GUID of the variable to use for the policy
> +
> search.
> + @param[in,out] VariableLockPolicyVariableNameBufferSize On input,
> the size, in bytes, of the
> +
> VariableLockPolicyVariableName buffer.
> +
> +
> On output, the size, in bytes, needed to store the variable
> +
> policy variable name.
> +
> + If
> testing for the VariableLockPolicyVariableName buffer
> +
> size needed, set this value to zero so EFI_BUFFER_TOO_SMALL
> + is
> guaranteed to be returned if the variable policy variable
> +
> name is found.
> + @param[out] VariablePolicy
> Pointer to a buffer where the policy entry will be written
> + if
> found.
> + @param[out] VariableLockPolicyVariableName
> Pointer to a buffer where the variable name used for the
> +
> variable lock on variable state policy will be written if
> + a
> variable name is registered.
> +
> + If
> the lock on variable policy is not associated with a
> +
> variable name (e.g. applied to variable vendor namespace)
> +
> and this parameter is given, this parameter will not be
> +
> modified and VariableLockPolicyVariableNameBufferSize will
> +
> be set to zero to indicate a name was not present.
> +
> + If
> the pointer given is not NULL,
> +
> VariableLockPolicyVariableNameBufferSize must be non-NULL.
> +
> + @retval EFI_SUCCESS A Lock on Variable State
> variable policy entry was found and returned
> + successfully.
> + @retval EFI_BAD_BUFFER_SIZE An internal buffer size caused
> a calculation error.
> + @retval EFI_BUFFER_TOO_SMALL The
> VariableLockPolicyVariableName buffer is too small for the size needed.
> + The buffer should now point
> to the size needed.
> + @retval EFI_NOT_READY Variable policy has not yet
> been initialized.
> + @retval EFI_INVALID_PARAMETER A required pointer argument
> passed is NULL. This will be returned if
> +
> VariableLockPolicyVariableName is non-NULL and
> +
> VariableLockPolicyVariableNameBufferSize is NULL.
> + @retval EFI_NOT_FOUND A Lock on Variable State
> variable policy was not found for the given UEFI
> + variable name and vendor
> GUID.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *GET_LOCK_ON_VARIABLE_STATE_VARIABLE_POLICY_INFO)(
> + IN CONST CHAR16 *VariableName,
> + IN CONST EFI_GUID *VendorGuid,
> + IN OUT UINTN
> *VariableLockPolicyVariableNameBufferSize OPTIONAL,
> + OUT VARIABLE_LOCK_ON_VAR_STATE_POLICY *VariablePolicy,
> + OUT CHAR16
> *VariableLockPolicyVariableName OPTIONAL
> + );
> +
> typedef struct {
> - UINT64 Revision;
> - DISABLE_VARIABLE_POLICY DisableVariablePolicy;
> - IS_VARIABLE_POLICY_ENABLED IsVariablePolicyEnabled;
> - REGISTER_VARIABLE_POLICY RegisterVariablePolicy;
> - DUMP_VARIABLE_POLICY DumpVariablePolicy;
> - LOCK_VARIABLE_POLICY LockVariablePolicy;
> + UINT64 Revision;
> + DISABLE_VARIABLE_POLICY
> DisableVariablePolicy;
> + IS_VARIABLE_POLICY_ENABLED
> IsVariablePolicyEnabled;
> + REGISTER_VARIABLE_POLICY
> RegisterVariablePolicy;
> + DUMP_VARIABLE_POLICY
> DumpVariablePolicy;
> + LOCK_VARIABLE_POLICY
> LockVariablePolicy;
> + GET_VARIABLE_POLICY_INFO
> GetVariablePolicyInfo;
> + GET_LOCK_ON_VARIABLE_STATE_VARIABLE_POLICY_INFO
> GetLockOnVariableStateVariablePolicyInfo;
> } _EDKII_VARIABLE_POLICY_PROTOCOL;
>
> typedef _EDKII_VARIABLE_POLICY_PROTOCOL
> EDKII_VARIABLE_POLICY_PROTOCOL;
> diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> index 3fe6043bf631..7048d555f0a9 100644
> --- a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> @@ -32,6 +32,7 @@ [Packages]
>
>
> [LibraryClasses]
> + BaseLib
> DebugLib
> BaseMemoryLib
> MemoryAllocationLib
> --
> 2.42.0.windows.2
>
>
>
> -=-=-=-=-=-=
> Groups.io Links: You receive all messages sent to this group.
> View/Reply Online (#108841):
> https://edk2.groups.io/g/devel/message/108841
> Mute This Topic: https://groups.io/mt/101457410/4905953
> Group Owner: devel+owner@edk2.groups.io
> Unsubscribe: https://edk2.groups.io/g/devel/unsub
> [gaoliming@byosoft.com.cn]
> -=-=-=-=-=-=
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109982): https://edk2.groups.io/g/devel/message/109982
Mute This Topic: https://groups.io/mt/102152457/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 10+ messages in thread
* 回复: [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell command
2023-09-19 14:32 ` [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell command Michael Kubacki
@ 2023-10-24 5:16 ` gaoliming via groups.io
2023-10-24 6:21 ` Gao, Zhichao
0 siblings, 1 reply; 10+ messages in thread
From: gaoliming via groups.io @ 2023-10-24 5:16 UTC (permalink / raw)
To: devel, mikuback; +Cc: 'Zhichao Gao', 'Michael D Kinney'
Michael:
Will you provide standalone application for varpolicy like tftp?
Thanks
Liming
> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Michael
> Kubacki
> 发送时间: 2023年9月19日 22:33
> 收件人: devel@edk2.groups.io
> 抄送: Zhichao Gao <zhichao.gao@intel.com>; Michael D Kinney
> <michael.d.kinney@intel.com>
> 主题: [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell
> command
>
> From: Michael Kubacki <michael.kubacki@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@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Signed-off-by: Michael Kubacki <michael.kubacki@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@edk2.groups.io
> Unsubscribe: https://edk2.groups.io/g/devel/unsub
> [gaoliming@byosoft.com.cn]
> -=-=-=-=-=-=
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109983): https://edk2.groups.io/g/devel/message/109983
Mute This Topic: https://groups.io/mt/102152515/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell command
2023-10-24 5:16 ` 回复: " gaoliming via groups.io
@ 2023-10-24 6:21 ` Gao, Zhichao
2023-10-24 23:36 ` Michael Kubacki
0 siblings, 1 reply; 10+ messages in thread
From: Gao, Zhichao @ 2023-10-24 6:21 UTC (permalink / raw)
To: devel@edk2.groups.io, Gao, Liming, mikuback@linux.microsoft.com
Cc: Kinney, Michael D
Hi Michael:
The patch looks good to me. Reviewed-by: Zhichao Gao <zhichao.gao@intel.com>
Agree with Liming, Michael do you consider to add the APP version inf like DP/HTTP/TFTP?
Thanks,
Zhichao
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> gaoliming via groups.io
> Sent: Tuesday, October 24, 2023 1:17 PM
> To: devel@edk2.groups.io; mikuback@linux.microsoft.com
> Cc: Gao, Zhichao <zhichao.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@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@edk2.groups.io <devel@edk2.groups.io> 代表 Michael
> > Kubacki
> > 发送时间: 2023年9月19日 22:33
> > 收件人: devel@edk2.groups.io
> > 抄送: Zhichao Gao <zhichao.gao@intel.com>; Michael D Kinney
> > <michael.d.kinney@intel.com>
> > 主题: [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell
> > command
> >
> > From: Michael Kubacki <michael.kubacki@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@intel.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Signed-off-by: Michael Kubacki <michael.kubacki@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@edk2.groups.io
> > Unsubscribe: https://edk2.groups.io/g/devel/unsub
> > [gaoliming@byosoft.com.cn]
> > -=-=-=-=-=-=
> >
>
>
>
>
>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109987): https://edk2.groups.io/g/devel/message/109987
Mute This Topic: https://groups.io/mt/102152885/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell command
2023-10-24 6:21 ` Gao, Zhichao
@ 2023-10-24 23:36 ` Michael Kubacki
0 siblings, 0 replies; 10+ messages in thread
From: Michael Kubacki @ 2023-10-24 23:36 UTC (permalink / raw)
To: devel, zhichao.gao, Gao, Liming; +Cc: Kinney, Michael D
On 10/24/2023 2:21 AM, Gao, Zhichao wrote:
> Hi Michael:
>
> The patch looks good to me. Reviewed-by: Zhichao Gao <zhichao.gao@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@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> gaoliming via groups.io
>> Sent: Tuesday, October 24, 2023 1:17 PM
>> To: devel@edk2.groups.io; mikuback@linux.microsoft.com
>> Cc: Gao, Zhichao <zhichao.gao@intel.com>; Kinney, Michael D
>> <michael.d.kinney@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@edk2.groups.io <devel@edk2.groups.io> 代表 Michael
>>> Kubacki
>>> 发送时间: 2023年9月19日 22:33
>>> 收件人: devel@edk2.groups.io
>>> 抄送: Zhichao Gao <zhichao.gao@intel.com>; Michael D Kinney
>>> <michael.d.kinney@intel.com>
>>> 主题: [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell
>>> command
>>>
>>> From: Michael Kubacki <michael.kubacki@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@intel.com>
>>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>>> Signed-off-by: Michael Kubacki <michael.kubacki@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@edk2.groups.io
>>> Unsubscribe: https://edk2.groups.io/g/devel/unsub
>>> [gaoliming@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/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2023-10-24 23:37 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-19 14:32 [edk2-devel] [PATCH v1 0/3] Add Variable Policy Audit and Shell Command Michael Kubacki
2023-09-19 14:32 ` [edk2-devel] [PATCH v1 1/3] MdeModulePkg/VariablePolicy: Add more granular variable policy querying Michael Kubacki
2023-10-24 5:11 ` 回复: " gaoliming via groups.io
2023-09-19 14:32 ` [edk2-devel] [PATCH v1 2/3] ShellPkg: Add varpolicy dynamic shell command Michael Kubacki
2023-10-24 5:16 ` 回复: " gaoliming via groups.io
2023-10-24 6:21 ` Gao, Zhichao
2023-10-24 23:36 ` Michael Kubacki
2023-09-19 14:33 ` [edk2-devel] [PATCH v1 3/3] OvmfPkg: Add varpolicy " Michael Kubacki
2023-10-24 0:44 ` Yao, Jiewen
2023-10-24 2:13 ` Michael D Kinney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox