mirror of https://github.com/acidanthera/audk.git
898 lines
31 KiB
C
898 lines
31 KiB
C
/** @file
|
|
Main file for the "varpolicy" dynamic UEFI shell command and application.
|
|
|
|
This feature can provide detailed UEFI variable policy configuration
|
|
information in the UEFI shell.
|
|
|
|
Copyright (c) Microsoft Corporation.
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include "VariablePolicy.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/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"
|
|
},
|
|
{
|
|
VariableVendorMemoryTypeInfo,
|
|
&gEfiMemoryTypeInformationGuid,
|
|
L"Memory Type Information"
|
|
},
|
|
{
|
|
VariableVendorMonotonicCounter,
|
|
&gMtcVendorGuid,
|
|
L"Monotonic Counter"
|
|
},
|
|
{
|
|
VariableVendorMorControl,
|
|
&gEfiMemoryOverwriteRequestControlLockGuid,
|
|
L"Memory Overwrite Request (MOR) Control Lock"
|
|
},
|
|
{
|
|
VariableVendorShell,
|
|
&gShellVariableGuid,
|
|
L"UEFI Shell"
|
|
},
|
|
{
|
|
VariableVendorShell,
|
|
&gShellAliasGuid,
|
|
L"UEFI Shell Alias"
|
|
}
|
|
};
|
|
|
|
/**
|
|
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/app.
|
|
|
|
@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_ABORTED Failed to initialize the shell library.
|
|
@retval SHELL_INVALID_PARAMETER An argument passed to the shell command is invalid.
|
|
@retval Others A different error occurred.
|
|
|
|
**/
|
|
SHELL_STATUS
|
|
EFIAPI
|
|
RunVarPolicy (
|
|
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 ();
|
|
if (EFI_ERROR (Status)) {
|
|
ASSERT_EFI_ERROR (Status);
|
|
return SHELL_ABORTED;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/**
|
|
Retrieve HII package list from ImageHandle and publish to HII database.
|
|
|
|
@param[in] ImageHandle The image handle of the process.
|
|
|
|
@return HII handle.
|
|
|
|
**/
|
|
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;
|
|
}
|