From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 3C46DD80122 for ; Sat, 28 Oct 2023 01:18:47 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=kVGkKWkgkd99sQHOV5I0RL5txbKYGrNdpbULqUD0tak=; c=relaxed/simple; d=groups.io; h=DKIM-Filter:From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1698455925; v=1; b=OS5FDK+SMpkHnyXutKXNMyZQyUDtVdV5W87Ci/4PdFR0ApQ/QUPdOsG9v+ky1DNqmh5HdVtp 0j1lodhqtPjFF/O3LtqkkqmXDvnlBr+3hImWR8m8sqRwgkcTuephwtkD5feL6BVb7/JMhvHOELW 1iBvdkszHfGf5x/hkZ+R27ys= X-Received: by 127.0.0.2 with SMTP id hZZAYY7687511xMWaSuTiEiw; Fri, 27 Oct 2023 18:18:45 -0700 X-Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mx.groups.io with SMTP id smtpd.web10.36235.1698455925157102106 for ; Fri, 27 Oct 2023 18:18:45 -0700 X-Received: from localhost.localdomain (unknown [47.201.241.95]) by linux.microsoft.com (Postfix) with ESMTPSA id 22C6520B74C0; Fri, 27 Oct 2023 18:18:44 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 22C6520B74C0 From: "Michael Kubacki" To: devel@edk2.groups.io Cc: Zhichao Gao , Michael D Kinney Subject: [edk2-devel] [PATCH v2 2/3] ShellPkg: Add varpolicy dynamic shell command and app Date: Fri, 27 Oct 2023 21:18:11 -0400 Message-ID: <20231028011813.131-3-mikuback@linux.microsoft.com> In-Reply-To: <20231028011813.131-1-mikuback@linux.microsoft.com> References: <20231028011813.131-1-mikuback@linux.microsoft.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,mikuback@linux.microsoft.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 7k9hauUkZtYSrwzLhzWNHDi9x7686176AA= Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=OS5FDK+S; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=linux.microsoft.com (policy=none) From: Michael Kubacki 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/VariablePolicyDyna= micCommand.inf { gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE } ``` Include the following line in platform FDF: ``` INF ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyD= ynamicCommand.inf ``` A standalone UEFI application can also be built that uses the same underlying functional code as the dynamic shell command. The path to use in the DSC and FDF for the app: ``` ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.= inf ``` Cc: Zhichao Gao Cc: Michael D Kinney Signed-off-by: Michael Kubacki Reviewed-by: Zhichao Gao --- ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.c = | 877 ++++++++++++++++++++ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.c= | 59 ++ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynam= icCommand.c | 157 ++++ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.h = | 126 +++ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.uni = | 86 ++ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.i= nf | 58 ++ ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynam= icCommand.inf | 57 ++ ShellPkg/ShellPkg.dsc = | 5 + 8 files changed, 1425 insertions(+) diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Variabl= ePolicy.c b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Variable= Policy.c new file mode 100644 index 000000000000..7f79426c1a35 --- /dev/null +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy= .c @@ -0,0 +1,877 @@ +/** @file + Main file for the "varpolicy" dynamic UEFI shell command and applicati= on. + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 =3D NULL; + +STATIC CONST SHELL_PARAM_ITEM ParamList[] =3D { + { 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[] =3D { + { + 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 AttributesSt= r. + @param[out] AttributesStr The Unicode string for the given at= tributes. + + @retval EFI_SUCCESS The attributes were converted to a strin= g successfully. + @retval EFI_INVALID_PARAMETER The AttributesStr pointer is NULL. + +**/ +EFI_STATUS +GetAttributesString ( + IN UINT32 Attributes, + IN UINTN AttributesStrSize, + OUT CHAR16 *AttributesStr + ) +{ + if ((AttributesStr =3D=3D NULL) || (AttributesStrSize < VAR_POLICY_CMD= _MIN_ATTR_STR_LEN)) { + return EFI_INVALID_PARAMETER; + } + + AttributesStr[0] =3D L'0'; + AttributesStr[1] =3D L'x'; + AttributesStr[2] =3D L'\0'; + + UnicodeValueToStringS (AttributesStr + 2, AttributesStrSize - 2, (RADI= X_HEX), (INT64)Attributes, 30); + + if (Attributes =3D=3D 0) { + StrCatS (AttributesStr, AttributesStrSize, L" No Attributes"); + } else { + if ((Attributes & EFI_VARIABLE_NON_VOLATILE) =3D=3D EFI_VARIABLE_NON= _VOLATILE) { + StrCatS (AttributesStr, AttributesStrSize, L" NV"); + Attributes ^=3D EFI_VARIABLE_NON_VOLATILE; + } + + if ((Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) =3D=3D EFI_VARIAB= LE_BOOTSERVICE_ACCESS) { + StrCatS (AttributesStr, AttributesStrSize, L" BS"); + Attributes ^=3D EFI_VARIABLE_BOOTSERVICE_ACCESS; + } + + if ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) =3D=3D EFI_VARIABLE_R= UNTIME_ACCESS) { + StrCatS (AttributesStr, AttributesStrSize, L" RT"); + Attributes ^=3D EFI_VARIABLE_RUNTIME_ACCESS; + } + + if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) =3D=3D EFI_VAR= IABLE_HARDWARE_ERROR_RECORD) { + StrCatS (AttributesStr, AttributesStrSize, L" HW-Error"); + Attributes ^=3D EFI_VARIABLE_HARDWARE_ERROR_RECORD; + } + + if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) =3D=3D EF= I_VARIABLE_AUTHENTICATED_WRITE_ACCESS) { + StrCatS (AttributesStr, AttributesStrSize, L" Auth-WA"); + Attributes ^=3D EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; + } + + if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS= ) =3D=3D EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) { + StrCatS (AttributesStr, AttributesStrSize, L" Auth-TIME-WA"); + Attributes ^=3D EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS= ; + } + + if ((Attributes & EFI_VARIABLE_APPEND_WRITE) =3D=3D EFI_VARIABLE_APP= END_WRITE) { + StrCatS (AttributesStr, AttributesStrSize, L" APPEND-W"); + Attributes ^=3D EFI_VARIABLE_APPEND_WRITE; + } + + if (Attributes !=3D 0) { + StrCatS (AttributesStr, AttributesStrSize, L" "= ); + } + } + + return EFI_SUCCESS; +} + +/** + Prints UEFI variable statistics information. + + @param[in] TotalVariables Total number of UEFI variables d= iscovered. + @param[in] TotalVariablesSize Total size of UEFI variables dis= covered. + +**/ +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_V= ARS), mVarPolicyShellCommandHiiHandle, TotalVariables); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_STATS_TOTAL_S= IZE), mVarPolicyShellCommandHiiHandle, TotalVariablesSize, TotalVariables= Size); + 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) GUI= D. + + @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 =3D=3D NULL) { + ASSERT (VariableGuid !=3D NULL); + return NULL; + } + + for (Index =3D 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 nam= e. + @param[in] VariableGuid A pointer to the variable vendor G= UID. + @param[in] VariableSize The size of the UEFI variable in b= ytes. + @param[in] VariableAttributes The UEFI variable attributes. + + @retval EFI_SUCCESS The non-verbose variable informati= on was printed successfully. + @retval EFI_INVALID_PARAMETER A pointer argument passed to the f= unction was NULL. + @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to p= rint 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 =3D NULL; + DescriptionStr =3D NULL; + + if ((VariableName =3D=3D NULL) || (VariableGuid =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + CmdVarNamespace =3D GetNameSpaceInfo (VariableGuid); + + if (CmdVarNamespace =3D=3D NULL) { + DescriptionStr =3D AllocatePages (1); + if (DescriptionStr =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Exit; + } + + ZeroMem ((VOID *)DescriptionStr, EFI_PAGES_TO_SIZE (1)); + UnicodeSPrint (DescriptionStr, EFI_PAGES_TO_SIZE (1), L"Unknown Vend= or (%g)", VariableGuid); + } else { + DescriptionStr =3D CmdVarNamespace->Description; + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_TYPE), mV= arPolicyShellCommandHiiHandle, DescriptionStr); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_NAME), mV= arPolicyShellCommandHiiHandle, VariableName); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_VAR_SIZE), mV= arPolicyShellCommandHiiHandle, VariableSize, VariableSize); + + AttributesStr =3D AllocatePages (1); + if (AttributesStr =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Exit; + } + + ZeroMem ((VOID *)AttributesStr, EFI_PAGES_TO_SIZE (1)); + Status =3D GetAttributesString (VariableAttributes, EFI_PAGES_TO_SIZE = (1), AttributesStr); + if (Status =3D=3D EFI_SUCCESS) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_VAR_POL_VAR_ATTR), + mVarPolicyShellCommandHiiHandle, + AttributesStr + ); + } + + Status =3D EFI_SUCCESS; + +Exit: + if (AttributesStr !=3D NULL) { + FreePages (AttributesStr, 1); + } + + if ((CmdVarNamespace =3D=3D NULL) && (DescriptionStr !=3D NULL)) { + FreePages (DescriptionStr, 1); + } + + return Status; +} + +/** + Print verbose information about the variable. + + @param[in] Data A pointer to the variable data buf= fer. + @param[in] DataSize The size of data, in bytes, in the= variable data buffer. + + @retval EFI_SUCCESS The verbose variable information w= as printed successfully. + @retval EFI_INVALID_PARAMETER A pointer argument passed to the f= unction was NULL. + +**/ +EFI_STATUS +PrintVerboseVarInfo ( + IN VOID *Data, + IN UINTN DataSize + ) +{ + if ((DataSize =3D=3D 0) || (Data =3D=3D 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 UEF= I 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 variab= le. + @return FALSE if an error occurred and/or a variable policy was not fo= und 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 VariablePolicyVariableNameBufferSiz= e; + UINTN ReturnedVariableNameSize; + BOOLEAN PolicyHeaderPresent; + CHAR16 *VariablePolicyVariableName; + CHAR16 *VariableAttributesStr; + EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy; + + PolicyHeaderPresent =3D FALSE; + VariableAttributesStr =3D NULL; + VariablePolicyVariableName =3D NULL; + + if ((VariableName =3D=3D NULL) || (VendorGuid =3D=3D NULL)) { + ASSERT ((VariableName !=3D NULL) && (VendorGuid !=3D NULL)); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_INT_= ERR), mVarPolicyShellCommandHiiHandle); + return FALSE; + } + + Status =3D gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NUL= L, (VOID **)&VariablePolicy); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NO_P= ROT), mVarPolicyShellCommandHiiHandle); + return FALSE; + } + + VariablePolicyVariableNameBufferSize =3D EFI_PAGES_TO_SIZE (1); + VariablePolicyVariableName =3D AllocatePages (EFI_SIZE_TO_PA= GES (VariablePolicyVariableNameBufferSize)); + if (VariablePolicyVariableName =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + ASSERT_EFI_ERROR (Status); + goto Done; + } + + ZeroMem (VariablePolicyVariableName, VariablePolicyVariableNameBufferS= ize); + ReturnedVariableNameSize =3D VariablePolicyVariableNameBufferSize; + Status =3D VariablePolicy->GetVariablePolicyInfo ( + VariableName, + VendorGuid, + &ReturnedVariableNameSiz= e, + &VariablePolicyEntry, + VariablePolicyVariableNa= me + ); + if (Status =3D=3D EFI_NOT_READY) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NOT_= INIT), mVarPolicyShellCommandHiiHandle); + } else if (Status =3D=3D 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_UNEX= P_ERR), mVarPolicyShellCommandHiiHandle, Status); + } else { + PolicyHeaderPresent =3D TRUE; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEAD= ER_1), mVarPolicyShellCommandHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEAD= ER_2), mVarPolicyShellCommandHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_HEAD= ER_1), mVarPolicyShellCommandHiiHandle); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_VERS= ION), mVarPolicyShellCommandHiiHandle, VariablePolicyEntry.Version); + + if ((ReturnedVariableNameSize > 0) && (VariablePolicyVariableName[0]= !=3D CHAR_NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_VA= RIABLE), mVarPolicyShellCommandHiiHandle, VariablePolicyVariableName); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_VA= RIABLE), mVarPolicyShellCommandHiiHandle, L""); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_NAME= SPACE), 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, VariablePolicyVariableNameB= ufferSize); + ReturnedVariableNameSize =3D VariablePolicyVariableNameBufferSiz= e; + Status =3D VariablePolicy->GetLockOnVariableS= tateVariablePolicyInfo ( + VariableName, + VendorGuid, + &ReturnedVariableN= ameSize, + &LockOnVarStatePol= icy, + VariablePolicyVari= ableName + ); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLIC= Y_UNEXP_ERR), mVarPolicyShellCommandHiiHandle, Status); + goto Done; + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLIC= Y_STATE_NS), mVarPolicyShellCommandHiiHandle, &LockOnVarStatePolicy.Names= pace); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLIC= Y_STATE_VAL), mVarPolicyShellCommandHiiHandle, LockOnVarStatePolicy.Value= ); + if ((ReturnedVariableNameSize > 0) && (VariablePolicyVariableN= ame[0] !=3D CHAR_NULL)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POL= ICY_STATE_NAME), mVarPolicyShellCommandHiiHandle, VariablePolicyVariableN= ame); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POL= ICY_STATE_NAME), mVarPolicyShellCommandHiiHandle, L""); + } + } + + break; + default: + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VAR_POL_POLICY_= LOCK_TYPE), mVarPolicyShellCommandHiiHandle, L"Unknown"); + break; + } + + VariableAttributesStr =3D AllocatePages (1); + if (VariableAttributesStr =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + ASSERT_EFI_ERROR (Status); + goto Done; + } + + ZeroMem (VariableAttributesStr, EFI_PAGES_TO_SIZE (1)); + Status =3D GetAttributesString (VariablePolicyEntry.AttributesMustHa= ve, EFI_PAGES_TO_SIZE (1), VariableAttributesStr); + if (Status =3D=3D 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 =3D GetAttributesString (VariablePolicyEntry.AttributesCantHa= ve, EFI_PAGES_TO_SIZE (1), VariableAttributesStr); + if (Status =3D=3D 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_HEAD= ER_1), mVarPolicyShellCommandHiiHandle); + } + + if (VariableAttributesStr !=3D NULL) { + FreePages (VariableAttributesStr, 1); + } + + if (VariablePolicyVariableName !=3D NULL) { + FreePages (VariablePolicyVariableName, 1); + } + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), mVar= PolicyShellCommandHiiHandle); + + return Status =3D=3D EFI_SUCCESS; +} + +/** + Gets the next UEFI variable name. + + This buffer manages the UEFI variable name buffer, performing memory r= eallocations as necessary. + + Note: The first time this function is called, VariableNameBufferSize m= ust be 0 and + the VariableName buffer pointer must point to NULL. + + @param[in,out] VariableNameBufferSize On input, a pointer to a buffe= r that holds the current + size of the VariableName buffe= r in bytes. + On output, a pointer to a buff= er that holds the updated + size of the VariableName buffe= r in bytes. + @param[in,out] VariableName On input, a pointer to a point= er to a buffer that holds the + current UEFI variable name. + On output, a pointer to a poin= ter to a buffer that holds the + next UEFI variable name. + @param[in,out] VariableGuid On input, a pointer to a buffe= r that holds the current UEFI + variable GUID. + On output, a pointer to a buff= er that holds the next UEFI + variable GUID. + + @retval EFI_SUCCESS The next UEFI variable name was fo= und successfully. + @retval EFI_INVALID_PARAMETER A pointer argument is NULL or init= ial input values are invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to a= llocate 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 =3D=3D NULL) || (VariableName =3D=3D NULL)= || (VariableGuid =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (*VariableNameBufferSize =3D=3D 0) { + if (*VariableName !=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Allocate a buffer to temporarily hold variable names. To reduce m= emory + // allocations, the default buffer size is 256 characters. The buffe= r can + // be reallocated if expansion is necessary (should be very rare). + // + *VariableNameBufferSize =3D sizeof (CHAR16) * 256; + *VariableName =3D AllocateZeroPool (*VariableNameBufferSiz= e); + if (*VariableName =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem ((VOID *)VariableGuid, sizeof (EFI_GUID)); + } + + NextVariableNameBufferSize =3D *VariableNameBufferSize; + Status =3D gRT->GetNextVariableName ( + &NextVariableNameBufferSize, + *VariableName, + VariableGuid + ); + if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { + *VariableName =3D ReallocatePool ( + *VariableNameBufferSize, + NextVariableNameBufferSize, + *VariableName + ); + if (*VariableName =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *VariableNameBufferSize =3D NextVariableNameBufferSize; + + Status =3D gRT->GetNextVariableName ( + &NextVariableNameBufferSize, + *VariableName, + VariableGuid + ); + ASSERT (Status !=3D EFI_BUFFER_TOO_SMALL); + } + + return Status; +} + +/** + Dumps UEFI variable information. + + This is the main function that enumerates UEFI variables and prints th= e 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 ge= t UEFI variable information. + @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to a= llocate 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 =3D EFI_SUCCESS; + Data =3D NULL; + VariableName =3D NULL; + CurrentVariableDataBufferSize =3D 0; + TotalDataSize =3D 0; + TotalVariables =3D 0; + TotalVariablesWithPolicy =3D 0; + VariableNameBufferSize =3D 0; + + do { + GetNextVariableStatus =3D GetNextVariableNameWithDynamicReallocation= ( + &VariableNameBufferSize, + &VariableName, + &VariableGuid + ); + + if (!EFI_ERROR (GetNextVariableStatus)) { + DataSize =3D 0; + Status =3D gRT->GetVariable ( + VariableName, + &VariableGuid, + &Attributes, + &DataSize, + NULL + ); + if (Status !=3D EFI_BUFFER_TOO_SMALL) { + // If the variable exists, a zero size buffer should be too smal= l + Status =3D EFI_DEVICE_ERROR; + goto DeallocateAndExit; + } + + TotalDataSize +=3D DataSize; + TotalVariables++; + + if (!Stats || Verbose) { + Status =3D PrintNonVerboseVarInfo (VariableName, &VariableGuid, = DataSize, Attributes); + if (!EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREA= K), mVarPolicyShellCommandHiiHandle); + } + } + + if (PolicyCheck || Verbose) { + if (PrintVariablePolicyInfo (VariableName, &VariableGuid)) { + TotalVariablesWithPolicy++; + } + } + + if (Verbose) { + if (CurrentVariableDataBufferSize < DataSize) { + if (Data !=3D NULL) { + FreePool (Data); + } + + Data =3D AllocateZeroPool (DataSize); + if (Data =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto DeallocateAndExit; + } + + CurrentVariableDataBufferSize =3D DataSize; + } + + Status =3D gRT->GetVariable ( + VariableName, + &VariableGuid, + NULL, + &DataSize, + Data + ); + if (EFI_ERROR (Status)) { + Status =3D EFI_DEVICE_ERROR; + goto DeallocateAndExit; + } + + Status =3D PrintVerboseVarInfo (Data, DataSize); + if (EFI_ERROR (Status)) { + Status =3D EFI_DEVICE_ERROR; + goto DeallocateAndExit; + } + } + } + } while (!EFI_ERROR (GetNextVariableStatus)); + + if (TotalVariables =3D=3D 0) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VARS), mVarP= olicyShellCommandHiiHandle); + } else { + if (Verbose || Stats) { + PrintStats (TotalVariables, TotalDataSize); + } + + if (Verbose || PolicyCheck) { + ASSERT (TotalVariablesWithPolicy <=3D TotalVariables); + + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREAK), = mVarPolicyShellCommandHiiHandle); + if (TotalVariablesWithPolicy =3D=3D 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 =3D EFI_SUCCESS; + +DeallocateAndExit: + if (VariableName !=3D NULL) { + FreePool (VariableName); + } + + if (Data !=3D 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 ex= ecuted successfully. + @retval SHELL_ABORTED Failed to initialize the shell l= ibrary. + @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 =3D NULL; + ShellStatus =3D SHELL_INVALID_PARAMETER; + Status =3D EFI_SUCCESS; + PolicyCheck =3D FALSE; + StatsDump =3D FALSE; + VerboseDump =3D FALSE; + + Status =3D ShellInitialize (); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return SHELL_ABORTED; + } + + Status =3D ShellCommandLineParse (ParamList, &Package, &ProblemParam, = TRUE); + if (EFI_ERROR (Status)) { + if ((Status =3D=3D EFI_VOLUME_CORRUPTED) && (ProblemParam !=3D NULL)= ) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), mVa= rPolicyShellCommandHiiHandle, VAR_POLICY_COMMAND_NAME, ProblemParam); + FreePool (ProblemParam); + ShellStatus =3D SHELL_INVALID_PARAMETER; + goto Done; + } else { + ASSERT (FALSE); + } + } else { + if (ShellCommandLineGetCount (Package) > 1) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), mV= arPolicyShellCommandHiiHandle, VAR_POLICY_COMMAND_NAME); + ShellStatus =3D SHELL_INVALID_PARAMETER; + goto Done; + } + + PolicyCheck =3D ShellCommandLineGetFlag (Package, VAR_POLICY_FLAG_PO= LICY_STR); + StatsDump =3D ShellCommandLineGetFlag (Package, VAR_POLICY_FLAG_ST= ATS_STR); + VerboseDump =3D ShellCommandLineGetFlag (Package, VAR_POLICY_FLAG_VE= RBOSE_STR); + + Status =3D DumpVars (VerboseDump, StatsDump, PolicyCheck); + ASSERT_EFI_ERROR (Status); + } + +Done: + if (Package !=3D 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 =3D 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 =3D gHiiDatabase->NewPackageList ( + gHiiDatabase, + PackageList, + NULL, + &HiiHandle + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return NULL; + } + + return HiiHandle; +} diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Variabl= ePolicyApp.c b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Varia= blePolicyApp.c new file mode 100644 index 000000000000..f3ab45de6ae8 --- /dev/null +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy= App.c @@ -0,0 +1,59 @@ +/** @file + Functionality specific for standalone UEFI application support. + + This application can provide detailed UEFI variable policy configurati= on + information in the UEFI shell. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "VariablePolicy.h" + +#include +#include + +extern EFI_HII_HANDLE mVarPolicyShellCommandHiiHandle; + +// +// String token ID of help message text. +// Shell supports finding the help message in the resource section of an +// application image if a .MAN file is not found. This global variable i= s added +// to make the build tool recognize that the help string is consumed by = the user and +// then the build tool will add the string into the resource section. Th= us the +// application can use '-?' option to show help message in Shell. +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringHelpTokenId =3D STRI= NG_TOKEN (STR_GET_HELP_VAR_POLICY); + +/** + Entry of the UEFI variable policy application. + + @param ImageHandle The image handle of the process. + @param SystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS The application successfully initialized= . + @retval EFI_ABORTED The application failed to initialize. + @retval Others A different error occurred. + +**/ +EFI_STATUS +EFIAPI +VariablePolicyAppInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + mVarPolicyShellCommandHiiHandle =3D InitializeHiiPackage (ImageHandle)= ; + if (mVarPolicyShellCommandHiiHandle =3D=3D NULL) { + return EFI_ABORTED; + } + + Status =3D (EFI_STATUS)RunVarPolicy (ImageHandle, SystemTable); + + HiiRemovePackages (mVarPolicyShellCommandHiiHandle); + + return Status; +} diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Variabl= ePolicyDynamicCommand.c b/ShellPkg/DynamicCommand/VariablePolicyDynamicCo= mmand/VariablePolicyDynamicCommand.c new file mode 100644 index 000000000000..c1e309ad078f --- /dev/null +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy= DynamicCommand.c @@ -0,0 +1,157 @@ +/** @file + Functionality specific for dynamic UEFI shell command support. + + 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 "VariablePolicy.h" + +#include +#include +#include +#include +#include +#include + +#include + +extern EFI_HII_HANDLE mVarPolicyShellCommandHiiHandle; + +/** + 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 c= ommand. + @param[in] Shell The instance of the shell protocol u= sed in + the context of processing this comma= nd. + + @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 =3D ShellParameters; + gEfiShellProtocol =3D Shell; + + return RunVarPolicy (gImageHandle, SystemTable); +} + +/** + This is the command help handler function pointer callback type. This + function is responsible for displaying help information for the associ= ated + command. + + @param[in] This The instance of the + EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. + @param[in] Language The pointer to the language string t= o 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 =3D = { + VAR_POLICY_COMMAND_NAME, + VarPolicyCommandHandler, + VarPolicyCommandGetHelp +}; + +/** + 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 success= fully. + @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 =3D InitializeHiiPackage (ImageHandle)= ; + if (mVarPolicyShellCommandHiiHandle =3D=3D NULL) { + return EFI_ABORTED; + } + + Status =3D 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 =3D gBS->UninstallProtocolInterface ( + ImageHandle, + &gEfiShellDynamicCommandProtocolGuid, + &mVarPolicyDynamicCommand + ); + if (EFI_ERROR (Status)) { + return Status; + } + + HiiRemovePackages (mVarPolicyShellCommandHiiHandle); + + return EFI_SUCCESS; +} diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Variabl= ePolicy.h b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Variable= Policy.h new file mode 100644 index 000000000000..b8a232c5b05a --- /dev/null +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy= .h @@ -0,0 +1,126 @@ +/** @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 +#include + +#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 gl= obal + 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 l= ine. + @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 =3D "0123456789ABCDEF"; = \ + _LocalOffset =3D (Offset); = \ + _LocalDataSize =3D (DataSize); = \ + _DataToDump =3D (UINT8 *)(Data); = \ + = \ + ASSERT (_DataToDump !=3D NULL); = \ + = \ + while (_LocalDataSize !=3D 0) { = \ + _Size =3D 16; = \ + if (_Size > _LocalDataSize) { = \ + _Size =3D _LocalDataSize; = \ + } = \ + = \ + for (_DumpHexIndex =3D 0; _DumpHexIndex < _Size; _DumpHexInd= ex +=3D 1) { \ + _TempByte =3D (UINT8) _DataToDump[_DumpHexIndex= ]; \ + _Val[_DumpHexIndex * 3 + 0] =3D (UINT8) _Hex[_TempByte >>= 4]; \ + _Val[_DumpHexIndex * 3 + 1] =3D (UINT8) _Hex[_TempByte & = 0xF]; \ + _Val[_DumpHexIndex * 3 + 2] =3D = \ + (CHAR8) ((_DumpHexIndex =3D=3D 7) ? '-' : ' '); = \ + _Str[_DumpHexIndex] =3D = \ + (CHAR8) ((_TempByte < ' ' || _TempByte > '~') ? '.' : _T= empByte); \ + } = \ + = \ + _Val[_DumpHexIndex * 3] =3D 0; = \ + _Str[_DumpHexIndex] =3D 0; = \ + = \ + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_HEX_DUM= P_LINE), mVarPolicyShellCommandHiiHandle, _LocalOffset, _Val, _Str); \ + _DataToDump =3D (UINT8 *)(((UINTN)_DataToDump) + _Size); = \ + _LocalOffset +=3D _Size; = \ + _LocalDataSize -=3D _Size; = \ + } = \ + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_LINE_BREA= K), mVarPolicyShellCommandHiiHandle); \ + } + +/** + 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 + ); + +/** + 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 ex= ecuted successfully. + @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 + ); + +#endif diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Variabl= ePolicy.uni b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Variab= lePolicy.uni new file mode 100644 index 000000000000..194468285609 --- /dev/null +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy= .uni @@ -0,0 +1,86 @@ +// /** +// String definitions for the Variable Policy ("varpolicy") shell comman= d/app. +// +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +/=3D# + +#langdef en-US "english" + +// General Strings +#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown f= lag - '%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 Appli= cation Error Getting Policy Info!%N\r\n" +#string STR_VAR_POL_POLICY_NO_PROT #language en-US "%EVariable Polic= y 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 Polic= y Not Found for This Variable!%N\r\n" +#string STR_VAR_POL_POLICY_UNEXP_ERR #language en-US "%EUnexpected Err= or 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 Polic= y Info |\r\n" +#string STR_VAR_POL_POLICY_VERSION #language en-US "| Version: 0x%-8= x |\r\n" +#string STR_VAR_POL_POLICY_VARIABLE #language en-US "| Variable: % -6= 4s |\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 Attri= butes: |\r\n" +#string STR_VAR_POL_POLICY_ATTR_NOT #language en-US "| Disallowed Att= ributes: |\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%-8= x |\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 v= ariables have policy%N\r\n" +#string STR_VAR_POL_POLICY_STATS_FAIL #language en-US " %E%d/%d UEFI v= ariables 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 St= atistics |\r\n" +#string STR_VAR_POL_STATS_TOTAL_VARS #language en-US " Total UEFI Varia= bles: %,d\r\n" +#string STR_VAR_POL_STATS_TOTAL_SIZE #language en-US " Total UEFI Varia= ble 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 variabl= e.\r\n" +" \r\n" +" -s - The stats flag will print overall UEFI variable policy statistic= s.\r\n" +" \r\n" +" -v - The verbose flag indicates all known information should be print= ed.\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/DynamicCommand/VariablePolicyDynamicCommand/Variabl= ePolicyApp.inf b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Var= iablePolicyApp.inf new file mode 100644 index 000000000000..78ca661ed77f --- /dev/null +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy= App.inf @@ -0,0 +1,58 @@ +## @file +# A UEFI variable policy application 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 =3D 0x00010006 + BASE_NAME =3D varpolicy + FILE_GUID =3D CA3D995F-3291-45AF-B50A-7C8AE584D857 + MODULE_TYPE =3D UEFI_APPLICATION + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D VariablePolicyAppInitialize + # Note: GetHelpText() in the EFI shell protocol will associate the hel= p text + # for the app if the app name (command) matches the .TH section = name in + # the Unicode help text. That name is "varpolicy". + UEFI_HII_RESOURCE_SECTION =3D TRUE + +[Sources.common] + VariablePolicy.uni + VariablePolicy.h + VariablePolicy.c + VariablePolicyApp.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + HiiLib + MemoryAllocationLib + PrintLib + ShellLib + UefiApplicationEntryPoint + UefiBootServicesTableLib + UefiHiiServicesLib + UefiRuntimeServicesTableLib + +[Protocols] + gEdkiiVariablePolicyProtocolGuid ## SOMETIMES_CONSUMES + gEfiHiiPackageListProtocolGuid ## CONSUMES + +[Guids] + ## SOMETIMES_CONSUMES ## Variables in Vendor Namespace + gEfiCapsuleReportGuid + gEfiCapsuleVendorGuid + gEfiGlobalVariableGuid + gEfiMemoryOverwriteRequestControlLockGuid + +[DEPEX] + TRUE diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/Variabl= ePolicyDynamicCommand.inf b/ShellPkg/DynamicCommand/VariablePolicyDynamic= Command/VariablePolicyDynamicCommand.inf new file mode 100644 index 000000000000..4f0e02363046 --- /dev/null +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy= DynamicCommand.inf @@ -0,0 +1,57 @@ +## @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 =3D 1.27 + BASE_NAME =3D VariablePolicyDynamicCommand + FILE_GUID =3D 17D0EF2A-5933-4007-8950-5749169D3DC5 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D VariablePolicyDynamicCommandEntryPoint + UNLOAD_IMAGE =3D VariablePolicyDynamicCommandUnload + UEFI_HII_RESOURCE_SECTION =3D TRUE + +[Sources.common] + VariablePolicy.uni + VariablePolicy.h + VariablePolicy.c + VariablePolicyDynamicCommand.c + +[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/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc index dd0d88603f11..557b0ec0f3d6 100644 --- a/ShellPkg/ShellPkg.dsc +++ b/ShellPkg/ShellPkg.dsc @@ -154,6 +154,11 @@ [Components] gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE } ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf + ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDyn= amicCommand.inf { + + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + } + ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp= .inf ShellPkg/Application/AcpiViewApp/AcpiViewApp.inf =20 [BuildOptions] --=20 2.42.0.windows.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#110236): https://edk2.groups.io/g/devel/message/110236 Mute This Topic: https://groups.io/mt/102234065/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-