[PATCH v5 03/14] MdeModulePkg: Define the VariablePolicyHelperLib


Bret Barkelew <bret@...>
 

https://bugzilla.tianocore.org/show_bug.cgi?id=3D2522

VariablePolicy is an updated interface to
replace VarLock and VarCheckProtocol.

Add the VariablePolicyHelperLib library, containing
several functions to help with the repetitive process
of creating a correctly structured and packed
VariablePolicy entry.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Cc: Liming Gao <liming.gao@...>
Cc: Bret Barkelew <brbarkel@...>
Signed-off-by: Bret Barkelew <brbarkel@...>
---
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c |=
396 ++++++++++++++++++++
MdeModulePkg/Include/Library/VariablePolicyHelperLib.h |=
164 ++++++++
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf |=
35 ++
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.uni |=
12 +
MdeModulePkg/MdeModulePkg.dec |=
5 +
MdeModulePkg/MdeModulePkg.dsc |=
2 +
6 files changed, 614 insertions(+)

diff --git a/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel=
perLib.c b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelpe=
rLib.c
new file mode 100644
index 000000000000..0c9299c8b0e1
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c
@@ -0,0 +1,396 @@
+/** @file -- VariablePolicyHelperLib.c=0D
+This library contains helper functions for marshalling and registering=0D
+new policies with the VariablePolicy infrastructure.=0D
+=0D
+This library is currently written against VariablePolicy revision 0x000100=
00.=0D
+=0D
+Copyright (c) Microsoft Corporation.=0D
+SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#include <Uefi.h>=0D
+=0D
+#include <Library/BaseLib.h>=0D
+#include <Library/DebugLib.h>=0D
+#include <Library/BaseMemoryLib.h>=0D
+#include <Library/MemoryAllocationLib.h>=0D
+=0D
+#include <Protocol/VariablePolicy.h>=0D
+=0D
+/**=0D
+ This internal helper function populates the header structure,=0D
+ all common fields, and takes care of fix-ups.=0D
+=0D
+ NOTE: Only use this internally. Assumes correctly-sized buffers.=0D
+=0D
+ @param[out] EntPtr Pointer to the buffer to be populated.=0D
+ @param[in] Namespace Pointer to an EFI_GUID for the target variable n=
amespace that this policy will protect.=0D
+ @param[in] MinSize MinSize for the VariablePolicy.=0D
+ @param[in] MaxSize MaxSize for the VariablePolicy.=0D
+ @param[in] AttributesMustHave AttributesMustHave for the VariablePol=
icy.=0D
+ @param[in] AttributesCantHave AttributesCantHave for the VariablePol=
icy.=0D
+ @param[in] LockPolicyType LockPolicyType for the VariablePolicy.=
=0D
+=0D
+**/=0D
+STATIC=0D
+VOID=0D
+PopulateCommonData (=0D
+ OUT VARIABLE_POLICY_ENTRY *EntPtr,=0D
+ IN CONST EFI_GUID *Namespace,=0D
+ IN UINT32 MinSize,=0D
+ IN UINT32 MaxSize,=0D
+ IN UINT32 AttributesMustHave,=0D
+ IN UINT32 AttributesCantHave,=0D
+ IN UINT8 LockPolicyType=0D
+ )=0D
+{=0D
+ EntPtr->Version =3D VARIABLE_POLICY_ENTRY_REVISION;=0D
+ CopyGuid( &EntPtr->Namespace, Namespace );=0D
+ EntPtr->MinSize =3D MinSize;=0D
+ EntPtr->MaxSize =3D MaxSize;=0D
+ EntPtr->AttributesMustHave =3D AttributesMustHave;=0D
+ EntPtr->AttributesCantHave =3D AttributesCantHave;=0D
+ EntPtr->LockPolicyType =3D LockPolicyType;=0D
+=0D
+ // NOTE: As a heler, fix up MaxSize for compatibility with the old model=
.=0D
+ if (EntPtr->MaxSize =3D=3D 0) {=0D
+ EntPtr->MaxSize =3D VARIABLE_POLICY_NO_MAX_SIZE;=0D
+ }=0D
+=0D
+ return;=0D
+}=0D
+=0D
+=0D
+/**=0D
+ This helper function will allocate and populate a new VariablePolicy=0D
+ structure for a policy that does not contain any sub-structures (such as=
=0D
+ VARIABLE_LOCK_ON_VAR_STATE_POLICY).=0D
+=0D
+ NOTE: Caller will need to free structure once finished.=0D
+=0D
+ @param[in] Namespace Pointer to an EFI_GUID for the target variable n=
amespace that this policy will protect.=0D
+ @param[in] Name [Optional] If provided, a pointer to the CHAR16 =
array for the target variable name.=0D
+ Otherwise, will create a policy that targets an =
entire namespace.=0D
+ @param[in] MinSize MinSize for the VariablePolicy.=0D
+ @param[in] MaxSize MaxSize for the VariablePolicy.=0D
+ @param[in] AttributesMustHave AttributesMustHave for the VariablePol=
icy.=0D
+ @param[in] AttributesCantHave AttributesCantHave for the VariablePol=
icy.=0D
+ @param[in] LockPolicyType LockPolicyType for the VariablePolicy.=
=0D
+ @param[out] NewEntry If successful, will be set to a pointer to the a=
llocated buffer containing the=0D
+ new policy.=0D
+=0D
+ @retval EFI_SUCCESS Operation completed successfully and=
structure is populated.=0D
+ @retval EFI_INVALID_PARAMETER Namespace is NULL.=0D
+ @retval EFI_INVALID_PARAMETER LockPolicyType is invalid for a basi=
c structure.=0D
+ @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in =
UINT16 size.=0D
+ @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space =
for structure.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+CreateBasicVariablePolicy (=0D
+ IN CONST EFI_GUID *Namespace,=0D
+ IN CONST CHAR16 *Name OPTIONAL,=0D
+ IN UINT32 MinSize,=0D
+ IN UINT32 MaxSize,=0D
+ IN UINT32 AttributesMustHave,=0D
+ IN UINT32 AttributesCantHave,=0D
+ IN UINT8 LockPolicyType,=0D
+ OUT VARIABLE_POLICY_ENTRY **NewEntry=0D
+ )=0D
+{=0D
+ UINTN TotalSize;=0D
+ UINTN NameSize;=0D
+ VARIABLE_POLICY_ENTRY *EntPtr;=0D
+ CHAR16 *CopyName;=0D
+=0D
+ // Check some initial invalid parameters for this function.=0D
+ if (Namespace =3D=3D NULL || NewEntry =3D=3D NULL) {=0D
+ return EFI_INVALID_PARAMETER;=0D
+ }=0D
+ if (LockPolicyType !=3D VARIABLE_POLICY_TYPE_NO_LOCK &&=0D
+ LockPolicyType !=3D VARIABLE_POLICY_TYPE_LOCK_NOW &&=0D
+ LockPolicyType !=3D VARIABLE_POLICY_TYPE_LOCK_ON_CREATE) {=0D
+ return EFI_INVALID_PARAMETER;=0D
+ }=0D
+=0D
+ // Now we've gotta determine the total size of the buffer required for=0D
+ // the VariablePolicy structure.=0D
+ TotalSize =3D sizeof( VARIABLE_POLICY_ENTRY );=0D
+ if (Name !=3D NULL) {=0D
+ NameSize =3D StrnSizeS( Name, MAX_UINT16 );=0D
+ TotalSize +=3D NameSize;=0D
+ }=0D
+ // Make sure the size fits within a VARIABLE_POLICY_ENTRY.Size.=0D
+ ASSERT( TotalSize <=3D MAX_UINT16 );=0D
+ if (TotalSize > MAX_UINT16) {=0D
+ return EFI_BUFFER_TOO_SMALL;=0D
+ }=0D
+=0D
+ // Allocate a buffer to hold all the data. We're on the home stretch.=0D
+ *NewEntry =3D AllocatePool( TotalSize );=0D
+ if (*NewEntry =3D=3D NULL) {=0D
+ return EFI_OUT_OF_RESOURCES;=0D
+ }=0D
+=0D
+ // If we're still here, we're basically done.=0D
+ // Copy the data and GET... OUT....=0D
+ EntPtr =3D *NewEntry;=0D
+ PopulateCommonData ( EntPtr,=0D
+ Namespace,=0D
+ MinSize,=0D
+ MaxSize,=0D
+ AttributesMustHave,=0D
+ AttributesCantHave,=0D
+ LockPolicyType );=0D
+ EntPtr->Size =3D (UINT16)TotalSize; // This is safe =
because we've already checked.=0D
+ EntPtr->OffsetToName =3D sizeof(VARIABLE_POLICY_ENTRY);=0D
+ if (Name !=3D NULL) {=0D
+ CopyName =3D (CHAR16*)((UINT8*)EntPtr + EntPtr->OffsetToName);=0D
+ CopyMem( CopyName, Name, NameSize );=0D
+ }=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+=0D
+/**=0D
+ This helper function will allocate and populate a new VariablePolicy=0D
+ structure for a policy with a lock type of VARIABLE_POLICY_TYPE_LOCK_ON_=
VAR_STATE.=0D
+=0D
+ NOTE: Caller will need to free structure once finished.=0D
+=0D
+ @param[in] Namespace Pointer to an EFI_GUID for the target variable n=
amespace that this policy will protect.=0D
+ @param[in] Name [Optional] If provided, a pointer to the CHAR16 =
array for the target variable name.=0D
+ Otherwise, will create a policy that targets an =
entire namespace.=0D
+ @param[in] MinSize MinSize for the VariablePolicy.=0D
+ @param[in] MaxSize MaxSize for the VariablePolicy.=0D
+ @param[in] AttributesMustHave AttributesMustHave for the VariablePol=
icy.=0D
+ @param[in] AttributesCantHave AttributesCantHave for the VariablePol=
icy.=0D
+ @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIAB=
LE_LOCK_ON_VAR_STATE_POLICY.Namespace.=0D
+ @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STA=
TE_POLICY.Value.=0D
+ @param[in] VarStateName Pointer to the CHAR16 array for the VA=
RIABLE_LOCK_ON_VAR_STATE_POLICY.Name.=0D
+ @param[out] NewEntry If successful, will be set to a pointer to the a=
llocated buffer containing the=0D
+ new policy.=0D
+=0D
+ @retval EFI_SUCCESS Operation completed successfully and=
structure is populated.=0D
+ @retval EFI_INVALID_PARAMETER Namespace, VarStateNamespace, VarSta=
teName is NULL.=0D
+ @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in =
UINT16 size.=0D
+ @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space =
for structure.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+CreateVarStateVariablePolicy (=0D
+ IN CONST EFI_GUID *Namespace,=0D
+ IN CONST CHAR16 *Name OPTIONAL,=0D
+ IN UINT32 MinSize,=0D
+ IN UINT32 MaxSize,=0D
+ IN UINT32 AttributesMustHave,=0D
+ IN UINT32 AttributesCantHave,=0D
+ IN CONST EFI_GUID *VarStateNamespace,=0D
+ IN UINT8 VarStateValue,=0D
+ IN CONST CHAR16 *VarStateName,=0D
+ OUT VARIABLE_POLICY_ENTRY **NewEntry=0D
+ )=0D
+{=0D
+ UINTN TotalSize;=0D
+ UINTN NameSize;=0D
+ UINTN VarStateNameSize;=0D
+ VARIABLE_POLICY_ENTRY *EntPtr;=0D
+ CHAR16 *CopyName;=0D
+ VARIABLE_LOCK_ON_VAR_STATE_POLICY *CopyPolicy;=0D
+=0D
+ // Check some initial invalid parameters for this function.=0D
+ if (Namespace =3D=3D NULL || VarStateNamespace =3D=3D NULL ||=0D
+ VarStateName =3D=3D NULL || NewEntry =3D=3D NULL) {=0D
+ return EFI_INVALID_PARAMETER;=0D
+ }=0D
+=0D
+ // Now we've gotta determine the total size of the buffer required for=0D
+ // the VariablePolicy structure.=0D
+ VarStateNameSize =3D StrnSizeS( VarStateName, MAX_UINT16 );=0D
+ TotalSize =3D sizeof( VARIABLE_POLICY_ENTRY ) +=0D
+ sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY) +=0D
+ VarStateNameSize;=0D
+ if (Name !=3D NULL) {=0D
+ NameSize =3D StrnSizeS( Name, MAX_UINT16 );=0D
+ TotalSize +=3D NameSize;=0D
+ }=0D
+ // Make sure the size fits within a VARIABLE_POLICY_ENTRY.Size.=0D
+ ASSERT( TotalSize <=3D MAX_UINT16 );=0D
+ if (TotalSize > MAX_UINT16) {=0D
+ return EFI_BUFFER_TOO_SMALL;=0D
+ }=0D
+=0D
+ // Allocate a buffer to hold all the data. We're on the home stretch.=0D
+ *NewEntry =3D AllocatePool( TotalSize );=0D
+ if (*NewEntry =3D=3D NULL) {=0D
+ return EFI_OUT_OF_RESOURCES;=0D
+ }=0D
+=0D
+ // If we're still here, we're basically done.=0D
+ // Copy the data and GET... OUT....=0D
+ EntPtr =3D *NewEntry;=0D
+ PopulateCommonData ( EntPtr,=0D
+ Namespace,=0D
+ MinSize,=0D
+ MaxSize,=0D
+ AttributesMustHave,=0D
+ AttributesCantHave,=0D
+ VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE );=0D
+ EntPtr->Size =3D (UINT16)TotalSize; // This is safe =
because we've already checked.=0D
+ EntPtr->OffsetToName =3D sizeof(VARIABLE_POLICY_ENTRY) +=0D
+ sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY) =
+=0D
+ (UINT16)VarStateNameSize;=0D
+=0D
+ CopyPolicy =3D (VARIABLE_LOCK_ON_VAR_STATE_POLICY*)((UINT8*)EntPtr + siz=
eof(VARIABLE_POLICY_ENTRY));=0D
+ CopyName =3D (CHAR16*)((UINT8*)CopyPolicy + sizeof(VARIABLE_LOCK_ON_VAR_=
STATE_POLICY));=0D
+ CopyGuid( &CopyPolicy->Namespace, VarStateNamespace );=0D
+ CopyPolicy->Value =3D VarStateValue;=0D
+ CopyMem( CopyName, VarStateName, VarStateNameSize );=0D
+=0D
+ if (Name !=3D NULL) {=0D
+ CopyName =3D (CHAR16*)((UINT8*)EntPtr + EntPtr->OffsetToName);=0D
+ CopyMem( CopyName, Name, NameSize );=0D
+ }=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+=0D
+/**=0D
+ This helper function does everything that CreateBasicVariablePolicy() do=
es, but also=0D
+ uses the passed in protocol to register the policy with the infrastructu=
re.=0D
+ Does not return a buffer, does not require the caller to free anything.=
=0D
+=0D
+ @param[in] VariablePolicy Pointer to a valid instance of the VariableP=
olicy protocol.=0D
+ @param[in] Namespace Pointer to an EFI_GUID for the target variable n=
amespace that this policy will protect.=0D
+ @param[in] Name [Optional] If provided, a pointer to the CHAR16 =
array for the target variable name.=0D
+ Otherwise, will create a policy that targets an =
entire namespace.=0D
+ @param[in] MinSize MinSize for the VariablePolicy.=0D
+ @param[in] MaxSize MaxSize for the VariablePolicy.=0D
+ @param[in] AttributesMustHave AttributesMustHave for the VariablePol=
icy.=0D
+ @param[in] AttributesCantHave AttributesCantHave for the VariablePol=
icy.=0D
+ @param[in] LockPolicyType LockPolicyType for the VariablePolicy.=
=0D
+=0D
+ @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL.=0D
+ @retval EFI_STATUS Status returned by CreateBasicVariable=
Policy() or RegisterVariablePolicy().=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+RegisterBasicVariablePolicy (=0D
+ IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy,=0D
+ IN CONST EFI_GUID *Namespace,=0D
+ IN CONST CHAR16 *Name OPTIONAL,=0D
+ IN UINT32 MinSize,=0D
+ IN UINT32 MaxSize,=0D
+ IN UINT32 AttributesMustHave,=0D
+ IN UINT32 AttributesCantHave,=0D
+ IN UINT8 LockPolicyType=0D
+ )=0D
+{=0D
+ VARIABLE_POLICY_ENTRY *NewEntry;=0D
+ EFI_STATUS Status;=0D
+=0D
+ // Check the simple things.=0D
+ if (VariablePolicy =3D=3D NULL) {=0D
+ return EFI_INVALID_PARAMETER;=0D
+ }=0D
+=0D
+ // Create the new entry and make sure that everything worked.=0D
+ NewEntry =3D NULL;=0D
+ Status =3D CreateBasicVariablePolicy( Namespace,=0D
+ Name,=0D
+ MinSize,=0D
+ MaxSize,=0D
+ AttributesMustHave,=0D
+ AttributesCantHave,=0D
+ LockPolicyType,=0D
+ &NewEntry );=0D
+=0D
+ // If that was successful, attempt to register the new policy.=0D
+ if (!EFI_ERROR( Status )) {=0D
+ Status =3D VariablePolicy->RegisterVariablePolicy( NewEntry );=0D
+ }=0D
+=0D
+ // If we allocated the buffer, free the buffer.=0D
+ if (NewEntry !=3D NULL) {=0D
+ FreePool( NewEntry );=0D
+ }=0D
+=0D
+ return Status;=0D
+}=0D
+=0D
+=0D
+/**=0D
+ This helper function does everything that CreateBasicVariablePolicy() do=
es, but also=0D
+ uses the passed in protocol to register the policy with the infrastructu=
re.=0D
+ Does not return a buffer, does not require the caller to free anything.=
=0D
+=0D
+ @param[in] VariablePolicy Pointer to a valid instance of the VariableP=
olicy protocol.=0D
+ @param[in] Namespace Pointer to an EFI_GUID for the target variable n=
amespace that this policy will protect.=0D
+ @param[in] Name [Optional] If provided, a pointer to the CHAR16 =
array for the target variable name.=0D
+ Otherwise, will create a policy that targets an =
entire namespace.=0D
+ @param[in] MinSize MinSize for the VariablePolicy.=0D
+ @param[in] MaxSize MaxSize for the VariablePolicy.=0D
+ @param[in] AttributesMustHave AttributesMustHave for the VariablePol=
icy.=0D
+ @param[in] AttributesCantHave AttributesCantHave for the VariablePol=
icy.=0D
+ @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIAB=
LE_LOCK_ON_VAR_STATE_POLICY.Namespace.=0D
+ @param[in] VarStateName Pointer to the CHAR16 array for the VA=
RIABLE_LOCK_ON_VAR_STATE_POLICY.Name.=0D
+ @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STA=
TE_POLICY.Value.=0D
+=0D
+ @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL.=0D
+ @retval EFI_STATUS Status returned by CreateBasicVariablePolicy()=
or RegisterVariablePolicy().=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+RegisterVarStateVariablePolicy (=0D
+ IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy,=0D
+ IN CONST EFI_GUID *Namespace,=0D
+ IN CONST CHAR16 *Name OPTIONAL,=0D
+ IN UINT32 MinSize,=0D
+ IN UINT32 MaxSize,=0D
+ IN UINT32 AttributesMustHave,=0D
+ IN UINT32 AttributesCantHave,=0D
+ IN CONST EFI_GUID *VarStateNamespace,=0D
+ IN CONST CHAR16 *VarStateName,=0D
+ IN UINT8 VarStateValue=0D
+ )=0D
+{=0D
+ VARIABLE_POLICY_ENTRY *NewEntry;=0D
+ EFI_STATUS Status;=0D
+=0D
+ // Check the simple things.=0D
+ if (VariablePolicy =3D=3D NULL) {=0D
+ return EFI_INVALID_PARAMETER;=0D
+ }=0D
+=0D
+ // Create the new entry and make sure that everything worked.=0D
+ NewEntry =3D NULL;=0D
+ Status =3D CreateVarStateVariablePolicy( Namespace,=0D
+ Name,=0D
+ MinSize,=0D
+ MaxSize,=0D
+ AttributesMustHave,=0D
+ AttributesCantHave,=0D
+ VarStateNamespace,=0D
+ VarStateValue,=0D
+ VarStateName,=0D
+ &NewEntry );=0D
+=0D
+ // If that was successful, attempt to register the new policy.=0D
+ if (!EFI_ERROR( Status )) {=0D
+ Status =3D VariablePolicy->RegisterVariablePolicy( NewEntry );=0D
+ }=0D
+=0D
+ // If we allocated the buffer, free the buffer.=0D
+ if (NewEntry !=3D NULL) {=0D
+ FreePool( NewEntry );=0D
+ }=0D
+=0D
+ return Status;=0D
+}=0D
diff --git a/MdeModulePkg/Include/Library/VariablePolicyHelperLib.h b/MdeMo=
dulePkg/Include/Library/VariablePolicyHelperLib.h
new file mode 100644
index 000000000000..3b75e9786094
--- /dev/null
+++ b/MdeModulePkg/Include/Library/VariablePolicyHelperLib.h
@@ -0,0 +1,164 @@
+/** @file -- VariablePolicyHelperLib.h=0D
+This library contains helper functions for marshalling and registering=0D
+new policies with the VariablePolicy infrastructure.=0D
+=0D
+Copyright (c) Microsoft Corporation.=0D
+SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+=0D
+#ifndef _EDKII_VARIABLE_POLICY_HELPER_LIB_H_=0D
+#define _EDKII_VARIABLE_POLICY_HELPER_LIB_H_=0D
+=0D
+#include <Protocol/VariablePolicy.h>=0D
+=0D
+/**=0D
+ This helper function will allocate and populate a new VariablePolicy=0D
+ structure for a policy that does not contain any sub-structures (such as=
=0D
+ VARIABLE_LOCK_ON_VAR_STATE_POLICY).=0D
+=0D
+ NOTE: Caller will need to free structure once finished.=0D
+=0D
+ @param[in] Namespace Pointer to an EFI_GUID for the target variable n=
amespace that this policy will protect.=0D
+ @param[in] Name [Optional] If provided, a pointer to the CHAR16 =
array for the target variable name.=0D
+ Otherwise, will create a policy that targets an =
entire namespace.=0D
+ @param[in] MinSize MinSize for the VariablePolicy.=0D
+ @param[in] MaxSize MaxSize for the VariablePolicy.=0D
+ @param[in] AttributesMustHave AttributesMustHave for the VariablePol=
icy.=0D
+ @param[in] AttributesCantHave AttributesCantHave for the VariablePol=
icy.=0D
+ @param[in] LockPolicyType LockPolicyType for the VariablePolicy.=
=0D
+ @param[out] NewEntry If successful, will be set to a pointer to the a=
llocated buffer containing the=0D
+ new policy.=0D
+=0D
+ @retval EFI_SUCCESS Operation completed successfully and=
structure is populated.=0D
+ @retval EFI_INVALID_PARAMETER Namespace is NULL.=0D
+ @retval EFI_INVALID_PARAMETER LockPolicyType is invalid for a basi=
c structure.=0D
+ @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in =
UINT16 size.=0D
+ @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space =
for structure.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+CreateBasicVariablePolicy (=0D
+ IN CONST EFI_GUID *Namespace,=0D
+ IN CONST CHAR16 *Name OPTIONAL,=0D
+ IN UINT32 MinSize,=0D
+ IN UINT32 MaxSize,=0D
+ IN UINT32 AttributesMustHave,=0D
+ IN UINT32 AttributesCantHave,=0D
+ IN UINT8 LockPolicyType,=0D
+ OUT VARIABLE_POLICY_ENTRY **NewEntry=0D
+ );=0D
+=0D
+=0D
+/**=0D
+ This helper function will allocate and populate a new VariablePolicy=0D
+ structure for a policy with a lock type of VARIABLE_POLICY_TYPE_LOCK_ON_=
VAR_STATE.=0D
+=0D
+ NOTE: Caller will need to free structure once finished.=0D
+=0D
+ @param[in] Namespace Pointer to an EFI_GUID for the target variable n=
amespace that this policy will protect.=0D
+ @param[in] Name [Optional] If provided, a pointer to the CHAR16 =
array for the target variable name.=0D
+ Otherwise, will create a policy that targets an =
entire namespace.=0D
+ @param[in] MinSize MinSize for the VariablePolicy.=0D
+ @param[in] MaxSize MaxSize for the VariablePolicy.=0D
+ @param[in] AttributesMustHave AttributesMustHave for the VariablePol=
icy.=0D
+ @param[in] AttributesCantHave AttributesCantHave for the VariablePol=
icy.=0D
+ @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIAB=
LE_LOCK_ON_VAR_STATE_POLICY.Namespace.=0D
+ @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STA=
TE_POLICY.Value.=0D
+ @param[in] VarStateName Pointer to the CHAR16 array for the VA=
RIABLE_LOCK_ON_VAR_STATE_POLICY.Name.=0D
+ @param[out] NewEntry If successful, will be set to a pointer to the a=
llocated buffer containing the=0D
+ new policy.=0D
+=0D
+ @retval EFI_SUCCESS Operation completed successfully and=
structure is populated.=0D
+ @retval EFI_INVALID_PARAMETER Namespace, VarStateNamespace, VarSta=
teName is NULL.=0D
+ @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in =
UINT16 size.=0D
+ @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space =
for structure.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+CreateVarStateVariablePolicy (=0D
+ IN CONST EFI_GUID *Namespace,=0D
+ IN CONST CHAR16 *Name OPTIONAL,=0D
+ IN UINT32 MinSize,=0D
+ IN UINT32 MaxSize,=0D
+ IN UINT32 AttributesMustHave,=0D
+ IN UINT32 AttributesCantHave,=0D
+ IN CONST EFI_GUID *VarStateNamespace,=0D
+ IN UINT8 VarStateValue,=0D
+ IN CONST CHAR16 *VarStateName,=0D
+ OUT VARIABLE_POLICY_ENTRY **NewEntry=0D
+ );=0D
+=0D
+=0D
+/**=0D
+ This helper function does everything that CreateBasicVariablePolicy() do=
es, but also=0D
+ uses the passed in protocol to register the policy with the infrastructu=
re.=0D
+ Does not return a buffer, does not require the caller to free anything.=
=0D
+=0D
+ @param[in] VariablePolicy Pointer to a valid instance of the VariableP=
olicy protocol.=0D
+ @param[in] Namespace Pointer to an EFI_GUID for the target variable n=
amespace that this policy will protect.=0D
+ @param[in] Name [Optional] If provided, a pointer to the CHAR16 =
array for the target variable name.=0D
+ Otherwise, will create a policy that targets an =
entire namespace.=0D
+ @param[in] MinSize MinSize for the VariablePolicy.=0D
+ @param[in] MaxSize MaxSize for the VariablePolicy.=0D
+ @param[in] AttributesMustHave AttributesMustHave for the VariablePol=
icy.=0D
+ @param[in] AttributesCantHave AttributesCantHave for the VariablePol=
icy.=0D
+ @param[in] LockPolicyType LockPolicyType for the VariablePolicy.=
=0D
+=0D
+ @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL.=0D
+ @retval EFI_STATUS Status returned by CreateBasicVariable=
Policy() or RegisterVariablePolicy().=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+RegisterBasicVariablePolicy (=0D
+ IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy,=0D
+ IN CONST EFI_GUID *Namespace,=0D
+ IN CONST CHAR16 *Name OPTIONAL,=0D
+ IN UINT32 MinSize,=0D
+ IN UINT32 MaxSize,=0D
+ IN UINT32 AttributesMustHave,=0D
+ IN UINT32 AttributesCantHave,=0D
+ IN UINT8 LockPolicyType=0D
+ );=0D
+=0D
+=0D
+/**=0D
+ This helper function does everything that CreateBasicVariablePolicy() do=
es, but also=0D
+ uses the passed in protocol to register the policy with the infrastructu=
re.=0D
+ Does not return a buffer, does not require the caller to free anything.=
=0D
+=0D
+ @param[in] VariablePolicy Pointer to a valid instance of the VariableP=
olicy protocol.=0D
+ @param[in] Namespace Pointer to an EFI_GUID for the target variable n=
amespace that this policy will protect.=0D
+ @param[in] Name [Optional] If provided, a pointer to the CHAR16 =
array for the target variable name.=0D
+ Otherwise, will create a policy that targets an =
entire namespace.=0D
+ @param[in] MinSize MinSize for the VariablePolicy.=0D
+ @param[in] MaxSize MaxSize for the VariablePolicy.=0D
+ @param[in] AttributesMustHave AttributesMustHave for the VariablePol=
icy.=0D
+ @param[in] AttributesCantHave AttributesCantHave for the VariablePol=
icy.=0D
+ @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIAB=
LE_LOCK_ON_VAR_STATE_POLICY.Namespace.=0D
+ @param[in] VarStateName Pointer to the CHAR16 array for the VA=
RIABLE_LOCK_ON_VAR_STATE_POLICY.Name.=0D
+ @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STA=
TE_POLICY.Value.=0D
+=0D
+ @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL.=0D
+ @retval EFI_STATUS Status returned by CreateBasicVariablePolicy()=
or RegisterVariablePolicy().=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+RegisterVarStateVariablePolicy (=0D
+ IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy,=0D
+ IN CONST EFI_GUID *Namespace,=0D
+ IN CONST CHAR16 *Name OPTIONAL,=0D
+ IN UINT32 MinSize,=0D
+ IN UINT32 MaxSize,=0D
+ IN UINT32 AttributesMustHave,=0D
+ IN UINT32 AttributesCantHave,=0D
+ IN CONST EFI_GUID *VarStateNamespace,=0D
+ IN CONST CHAR16 *VarStateName,=0D
+ IN UINT8 VarStateValue=0D
+ );=0D
+=0D
+#endif // _EDKII_VARIABLE_POLICY_HELPER_LIB_H_=0D
diff --git a/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel=
perLib.inf b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel=
perLib.inf
new file mode 100644
index 000000000000..506abf580e94
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.=
inf
@@ -0,0 +1,35 @@
+## @file VariablePolicyHelperLib.inf=0D
+# This library contains helper functions for marshalling and registering=0D
+# new policies with the VariablePolicy infrastructure.=0D
+#=0D
+# This library is currently written against VariablePolicy revision 0x0001=
0000.=0D
+#=0D
+# Copyright (c) Microsoft Corporation.=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+##=0D
+=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010017=0D
+ BASE_NAME =3D VariablePolicyHelperLib=0D
+ # MODULE_UNI_FILE =3D VariablePolicyHelperLib.uni=0D
+ FILE_GUID =3D B3C2206B-FDD1-4AED-8352-FC5EC34C5630=0D
+ VERSION_STRING =3D 1.0=0D
+ MODULE_TYPE =3D BASE=0D
+ LIBRARY_CLASS =3D VariablePolicyHelperLib=0D
+=0D
+=0D
+[Sources]=0D
+ VariablePolicyHelperLib.c=0D
+=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+ MdeModulePkg/MdeModulePkg.dec=0D
+=0D
+=0D
+[LibraryClasses]=0D
+ BaseLib=0D
+ DebugLib=0D
+ MemoryAllocationLib=0D
+ BaseMemoryLib=0D
diff --git a/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel=
perLib.uni b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel=
perLib.uni
new file mode 100644
index 000000000000..39cbf11a4ce9
--- /dev/null
+++ b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.=
uni
@@ -0,0 +1,12 @@
+// /** @file=0D
+// VariablePolicyHelperLib.uni=0D
+//=0D
+// Copyright (c) Microsoft Corporation.=0D
+// SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+//=0D
+// **/=0D
+=0D
+=0D
+#string STR_MODULE_ABSTRACT #language en-US "Library containin=
g helper functions for marshalling and registering new policies with the Va=
riablePolicy infrastructure"=0D
+=0D
+#string STR_MODULE_DESCRIPTION #language en-US "Library containin=
g helper functions for marshalling and registering new policies with the Va=
riablePolicy infrastructure"=0D
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 31339741b840..2db37bd8ea9e 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -149,6 +149,11 @@ [LibraryClasses]
#=0D
DisplayUpdateProgressLib|Include/Library/DisplayUpdateProgressLib.h=0D
=0D
+ ## @libraryclass This library contains helper functions for marshallin=
g and=0D
+ # registering new policies with the VariablePolicy infrastructure.=0D
+ #=0D
+ VariablePolicyHelperLib|Include/Library/VariablePolicyHelperLib.h=0D
+=0D
[Guids]=0D
## MdeModule package token space guid=0D
# Include/Guid/MdeModulePkgTokenSpace.h=0D
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 14b6ed536962..37795b9e4f58 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -99,6 +99,7 @@ [LibraryClasses]
BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.i=
nf=0D
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf=0D
DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGr=
aphics/DisplayUpdateProgressLibGraphics.inf=0D
+ VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var=
iablePolicyHelperLib.inf=0D
=0D
[LibraryClasses.EBC.PEIM]=0D
IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf=0D
@@ -225,6 +226,7 @@ [Components]
MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf=0D
MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf=0D
MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLib=
Null.inf=0D
+ MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf=
=0D
=0D
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf=0D
MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf=0D
--=20
2.26.2.windows.1.8.g01c50adf56.20200515075929

Join devel@edk2.groups.io to automatically receive all group messages.