From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.byosoft.com.cn (mail.byosoft.com.cn [58.240.74.242]) by mx.groups.io with SMTP id smtpd.web10.255.1607650266535913467 for ; Thu, 10 Dec 2020 17:31:08 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=none, err=permanent DNS error (domain: byosoft.com.cn, ip: 58.240.74.242, mailfrom: gaoliming@byosoft.com.cn) Received: from DESKTOPS6D0PVI ([58.246.60.130]) (envelope-sender ) by 192.168.6.13 with ESMTP for ; Fri, 11 Dec 2020 09:30:59 +0800 X-WM-Sender: gaoliming@byosoft.com.cn X-WM-AuthFlag: YES X-WM-AuthUser: gaoliming@byosoft.com.cn From: "gaoliming" To: "'Wu, Hao A'" , , , "'Kinney, Michael D'" References: <20201209180605.1409-1-michael.d.kinney@intel.com> ,<004d01d6cea2$d9b15670$8d140350$@byosoft.com.cn> In-Reply-To: Subject: =?UTF-8?B?5Zue5aSNOiBbRVhURVJOQUxdIOWbnuWkjTogW2VkazItZGV2ZWxdIFtQYXRjaCB2MiAxLzFdIE1kZU1vZHVsZVBrZy9WYXJpYWJsZS9SdW50aW1lRHhlOiBSZXN0b3JlIFZhcmlhYmxlIExvY2sgUHJvdG9jb2wgYmVoYXZpb3I=?= Date: Fri, 11 Dec 2020 09:31:03 +0800 Message-ID: <008801d6cf5d$4a5b3d90$df11b8b0$@byosoft.com.cn> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQHQSuV2IQ1nv7KDY/FBKjKC86AZyQH0Kw6fAqx3ORgB9stYGgMGp2ZFqbEvpUA= Content-Type: multipart/alternative; boundary="----=_NextPart_000_0089_01D6CFA0.58855B60" Content-Language: zh-cn ------=_NextPart_000_0089_01D6CFA0.58855B60 Content-Type: text/plain; charset="gb2312" Content-Transfer-Encoding: quoted-printable Bret: For the patch split, I consider it from the platform integrator. If the platform meets with the problem, he can cherry-pick the fix with the minim= al code change.=20 =20 The patch is separated to two commits. They are still one patch serial.= =20 =20 Thanks Liming =B7=A2=BC=FE=C8=CB: Wu, Hao A =20 =B7=A2=CB=CD=CA=B1=BC=E4: 2020=C4=EA12=D4=C211=C8=D5 8:42 =CA=D5=BC=FE=C8=CB: devel@edk2.groups.io; bret.barkelew@microsoft.com; gao= liming ; Kinney, Michael D =D6=F7=CC=E2: RE: [EXTERNAL] =BB=D8=B8=B4: [edk2-devel] [Patch v2 1/1] MdeModulePkg/Variable/RuntimeDxe: Restore Variable Lock Protocol behavior =20 Hello Bret and Mike, =20 Thanks for the explanation on the code reusing open. If the code will eventually be gone, I am fine with it. =20 For Liming=A1=AFs suggestion to split the patch into a 2-patch series (1 f= or the fix and 1 for the unit tests), I am okay with putting them in 1 patch. My preference is also breaking them into 2 patches, since these 2 patches are not doing exacting one thing. But it is only a suggestion, please feel free to make your own decision. =20 In summary, with the typos addressed in the patch (in my previous reply to the patch): Reviewed-by: Hao A Wu > =20 Best Regards, Hao Wu =20 From: devel@edk2.groups.io > On Behalf Of Bret Barkelew via groups.io Sent: Thursday, December 10, 2020 3:35 PM To: gaoliming = >; Wu, Hao A >; devel@edk2.groups.io ; Kinney, Michael D > Subject: Re: [EXTERNAL] =BB=D8=B8=B4: [edk2-devel] [Patch v2 1/1] MdeModulePkg/Variable/RuntimeDxe: Restore Variable Lock Protocol behavior =20 I would prefer to not reuse the code from the library. They are SUPPOSED t= o be internal functions and are not part of the public interface. I=A1=AFve duplicated them here because this shim is supposed to be temporary and should go away within the next few stabilizations. =20 I would also prefer to keep the tests and the code together. These are pur= e unit tests rather than driver tests and serve to document and prove the co= de that is being submitted. However, I=A1=AFm willing to be flexible on this. =20 - Bret _____ From: gaoliming > Sent: Wednesday, December 9, 2020 7:16:28 PM To: 'Wu, Hao A' >; devel@edk2.groups.io >; Kinney, Michael D > Cc: Bret Barkelew > Subject: [EXTERNAL] =BB=D8=B8=B4: [edk2-devel] [Patch v2 1/1] MdeModulePkg/Variable/RuntimeDxe: Restore Variable Lock Protocol behavior= =20 =20 Mike: I agree Hao comment. There is the similar code logic in VariablePolicyLi= b library. They can be shared.=20 Besides, I suggest to split this patch. One is the bug fix to restore Variable Lock Protocol behavior, another is to add Variable driver unit test.=20 Thanks Liming > -----=D3=CA=BC=FE=D4=AD=BC=FE----- > =B7=A2=BC=FE=C8=CB: Wu, Hao A > > =B7=A2=CB=CD=CA=B1=BC=E4: 2020=C4=EA12=D4=C210=C8=D5 10:25 > =CA=D5=BC=FE=C8=CB: devel@edk2.groups.io ;= Kinney, Michael D > > > =B3=AD=CB=CD: Bret Barkelew >; Liming Gao > > > =D6=F7=CC=E2: RE: [edk2-devel] [Patch v2 1/1] MdeModulePkg/Variable/Runt= imeDxe: > Restore Variable Lock Protocol behavior >=20 > > -----Original Message----- > > From: devel@edk2.groups.io > On Behalf Of Michael > > D Kinney > > Sent: Thursday, December 10, 2020 2:06 AM > > To: devel@edk2.groups.io =20 > > Cc: Bret Barkelew >; Wu, Hao A > > >; Liming Gao >; Bret > > Barkelew > > > Subject: [edk2-devel] [Patch v2 1/1] MdeModulePkg/Variable/RuntimeDxe: > > Restore Variable Lock Protocol behavior > > > > From: Bret Barkelew > > > > > https://nam06.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fbugzil= la.t ianocore.org%2Fshow_bug.cgi%3Fid%3D3111 &data=3D04%7C01%7Cbret.barkelew%40microsoft.com%7C4115faaa16c6475b8e35= 08d8 9cba0189%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637431669999943616%7= CU nknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiL= CJ XVCI6Mn0%3D%7C1000&sdata=3DDU8EYtayepZpsyxajKK9w0mQ5kExWXG2AJvCcvVVy1A= %3D& amp;reserved=3D0 > > > > The VariableLock shim currently fails if called twice because the underlying > > Variable Policy engine returns an error if a policy is set on an existing > variable. > > > > This breaks existing code which expect it to silently pass if a variab= le is > locked > > multiple times (because it should "be locked"). > > > > Refactor the shim to confirm that the variable is indeed locked and th= en > > change the error to EFI_SUCCESS and generate a DEBUG_ERROR message > so > > the duplicate lock can be reported in a debug log and removed. >=20 >=20 > Hello, >=20 > Is it possible to reuse: > a) EvaluatePolicyMatch() and GetBestPolicyMatch() functions > b) Macros like GET_NEXT_POLICY, GET_POLICY_NAME and etc. > under MdeModulePkg\Library\VariablePolicyLib to reduce duplicate codes? >=20 > A couple of minor inline comments below: >=20 >=20 > > > > Add host based unit tests for the multiple lock case using Variable Lo= ck > > Protocol, Variable Policy Protocol, and mixes of Variable Lock Protoco= l and > > Variable Policy Protocol. > > > > Cc: Michael D Kinney > > > Cc: Hao A Wu > > > Cc: Liming Gao > > > Signed-off-by: Bret Barkelew > > > --- > > MdeModulePkg/Test/MdeModulePkgHostTest.dsc | 11 + > > .../VariableLockRequestToLockUnitTest.c | 434 > ++++++++++++++++++ > > .../VariableLockRequestToLockUnitTest.inf | 36 ++ > > .../RuntimeDxe/VariableLockRequestToLock.c | 363 > +++++++++++++-- > > 4 files changed, 809 insertions(+), 35 deletions(-) create mode 1006= 44 > > MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Vari > > ableLockRequestToLockUnitTest.c > > create mode 100644 > > MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Vari > > ableLockRequestToLockUnitTest.inf > > > > diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc > > b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc > > index 72a119db4568..4da4692c8451 100644 > > --- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc > > +++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc > > @@ -19,6 +19,9 @@ [Defines] > > > > !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc > > > > +[LibraryClasses] > > + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf > > + > > [Components] > > > > MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeSer > > vicesTableLib.inf > > > > @@ -30,3 +33,11 @@ [Components] > > > > ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSyst > > emLib.inf > > > > UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeResetSystemLib/ > > UnitTest/MockUefiRuntimeServicesTableLib.inf > > } > > + > > + > > MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Vari > > ableLockRequestToLockUnitTest.inf { > > + > > + > > > VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= i > > b.inf > > + > > > VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Va > > riablePolicyHelperLib.inf > > + > > + > > + > > gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDis > > abl > > + e|TRUE > > + } > > diff --git > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va > > riableLockRequestToLockUnitTest.c > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va > > riableLockRequestToLockUnitTest.c > > new file mode 100644 > > index 000000000000..2f4c4d2f79f4 > > --- /dev/null > > +++ > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va > > ri > > +++ ableLockRequestToLockUnitTest.c > > @@ -0,0 +1,434 @@ > > +/** @file > > + This is a host-based unit test for the VariableLockRequestToLock shim. > > + > > + Copyright (c) Microsoft Corporation. > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > +#include > > +#include #include > > + #include #inclu= de > > + > > + > > +#include > > + > > +#define UNIT_TEST_NAME "VarPol/VarLock Shim Unit Test" > > +#define UNIT_TEST_VERSION "1.0" > > + > > +///=3D=3D=3D CODE UNDER TEST > > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > +=3D=3D=3D=3D > > + > > +EFI_STATUS > > +EFIAPI > > +VariableLockRequestToLock ( > > + IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, > > + IN CHAR16 *VariableName, > > + IN EFI_GUID *VendorGuid > > + ); > > + > > +///=3D=3D=3D TEST DATA > > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > + > > +// > > +// Test GUID 1 {F955BA2D-4A2C-480C-BFD1-3CC522610592} > > +// > > +EFI_GUID mTestGuid1 =3D { > > + 0xf955ba2d, 0x4a2c, 0x480c, {0xbf, 0xd1, 0x3c, 0xc5, 0x22, 0x61, 0x= 5, > > +0x92} }; > > + > > +// > > +// Test GUID 2 {2DEA799E-5E73-43B9-870E-C945CE82AF3A} > > +// > > +EFI_GUID mTestGuid2 =3D { > > + 0x2dea799e, 0x5e73, 0x43b9, {0x87, 0xe, 0xc9, 0x45, 0xce, 0x82, 0xa= f, > > +0x3a} }; > > + > > +// > > +// Test GUID 3 {698A2BFD-A616-482D-B88C-7100BD6682A9} > > +// > > +EFI_GUID mTestGuid3 =3D { > > + 0x698a2bfd, 0xa616, 0x482d, {0xb8, 0x8c, 0x71, 0x0, 0xbd, 0x66, 0x8= 2, > > +0xa9} }; > > + > > +#define TEST_VAR_1_NAME L"TestVar1" > > +#define TEST_VAR_2_NAME L"TestVar2" > > +#define TEST_VAR_3_NAME L"TestVar3" > > + > > +#define TEST_POLICY_ATTRIBUTES_NULL 0 > > +#define TEST_POLICY_MIN_SIZE_NULL 0 > > +#define TEST_POLICY_MAX_SIZE_NULL MAX_UINT32 > > + > > +#define TEST_POLICY_MIN_SIZE_10 10 > > +#define TEST_POLICY_MAX_SIZE_200 200 > > + > > +///=3D=3D=3D HELPER FUNCTIONS > > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > +=3D=3D=3D=3D > > + > > +/** > > + Mocked version of GetVariable, for testing. > > + > > + @param VariableName > > + @param VendorGuid > > + @param Attributes > > + @param DataSize > > + @param Data > > +**/ > > +EFI_STATUS > > +EFIAPI > > +StubGetVariableNull ( > > + IN CHAR16 *VariableName, > > + IN EFI_GUID *VendorGuid, > > + OUT UINT32 *Attributes, OPTIONAL > > + IN OUT UINTN *DataSize, > > + OUT VOID *Data OPTIONAL > > + ) > > +{ > > + UINT32 MockedAttr; > > + UINTN MockedDataSize; > > + VOID *MockedData; > > + EFI_STATUS MockedReturn; > > + > > + check_expected_ptr (VariableName); > > + check_expected_ptr (VendorGuid); > > + check_expected_ptr (DataSize); > > + > > + MockedAttr =3D (UINT32)mock(); > > + MockedDataSize =3D (UINTN)mock(); > > + MockedData =3D (VOID*)(UINTN)mock(); > > + MockedReturn =3D (EFI_STATUS)mock(); > > + > > + if (Attributes !=3D NULL) { > > + *Attributes =3D MockedAttr; > > + } > > + if (Data !=3D NULL && !EFI_ERROR (MockedReturn)) { > > + CopyMem (Data, MockedData, MockedDataSize); } > > + > > + *DataSize =3D MockedDataSize; > > + > > + return MockedReturn; > > +} > > + > > +// > > +// Anything you think might be helpful that isn't a test itself. > > +// > > + > > +/** > > + This is a common setup function that will ensure the library is > > +always > > + initialized with the stubbed GetVariable. > > + > > + Not used by all test cases, but by most. > > + > > + @param[in] Context Unit test case context **/ STATIC > > +UNIT_TEST_STATUS EFIAPI LibInitMocked ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + return EFI_ERROR (InitVariablePolicyLib (StubGetVariableNull)) ? > > +UNIT_TEST_ERROR_PREREQUISITE_NOT_MET : UNIT_TEST_PASSED; } > > + > > +/** > > + Common cleanup function to make sure that the library is always > > +de-initialized > > + prior to the next test case. > > + > > + @param[in] Context Unit test case context **/ STATIC VOID EFIAPI > > +LibCleanup ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + DeinitVariablePolicyLib(); > > +} > > + > > +///=3D=3D=3D TEST CASES > > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > + > > +///=3D=3D=3D=3D=3D SHIM SUITE > > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > =3D=3D > > + > > +/** > > + Test Case that locks a single variable using the Variable Lock Protocol. > > + The call is expected to succeed. > > + > > + @param[in] Context Unit test case context **/ UNIT_TEST_STATUS > > +EFIAPI LockingWithoutAnyPoliciesShouldSucceed ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + > > + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, > > + &mTestGuid1); UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Test Case that locks the same variable twice using the Variable Loc= k > Procol. >=20 >=20 > Minor comment, typo for 'Procol' -> 'Protocol' >=20 >=20 > > + Both calls are expected to succeed. > > + > > + @param[in] Context Unit test case context > > + **/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +LockingTwiceShouldSucceed ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + > > + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, > > + &mTestGuid1); UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, > > + &mTestGuid1); UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Test Case that locks a variable using the Variable Policy Protocol > > +then locks > > + the same variable using the Variable Lock Protocol. > > + Both calls are expected to succeed. > > + > > + @param[in] Context Unit test case context > > + **/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +LockingALockedVariableShouldSucceed ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + VARIABLE_POLICY_ENTRY *NewEntry; > > + > > + // > > + // Create a variable policy that locks the variable. > > + // > > + Status =3D CreateBasicVariablePolicy ( > > + &mTestGuid1, > > + TEST_VAR_1_NAME, > > + TEST_POLICY_MIN_SIZE_NULL, > > + TEST_POLICY_MAX_SIZE_200, > > + TEST_POLICY_ATTRIBUTES_NULL, > > + TEST_POLICY_ATTRIBUTES_NULL, > > + VARIABLE_POLICY_TYPE_LOCK_NOW, > > + &NewEntry > > + ); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + // > > + // Register the new policy. > > + // > > + Status =3D RegisterVariablePolicy (NewEntry); > > + > > + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, > > + &mTestGuid1); UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + FreePool (NewEntry); > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Test Case that locks a variable using the Variable Policy Protocol > > +with a > > + policy other than LOCK_NOW then attempts to lock the same variable > > +using the > > + Variable Lock Protocol. The call to Variable Policy is expected to > > +succced >=20 >=20 > 'succced' -> 'succeed' >=20 >=20 > > + and the call to Variable Lock is expected to fail. > > + > > + @param[in] Context Unit test case context > > + **/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +LockingAnUnlockedVariableShouldFail ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + VARIABLE_POLICY_ENTRY *NewEntry; > > + > > + // Create a variable policy that locks the variable. > > + Status =3D CreateVarStateVariablePolicy (&mTestGuid1, > > + TEST_VAR_1_NAME, > > + > TEST_POLICY_MIN_SIZE_NULL, > > + > TEST_POLICY_MAX_SIZE_200, > > + > TEST_POLICY_ATTRIBUTES_NULL, > > + > TEST_POLICY_ATTRIBUTES_NULL, > > + &mTestGuid2, > > + 1, > > + TEST_VAR_2_NAME, > > + &NewEntry); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + // Register the new policy. > > + Status =3D RegisterVariablePolicy (NewEntry); > > + > > + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, > > + &mTestGuid1); UT_ASSERT_TRUE (EFI_ERROR (Status)); > > + > > + FreePool (NewEntry); > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Test Case that locks a variable using Variable Lock Protocol Policy > > +Protocol > > + then and then attempts to lock the same variable using the Variable > > +Policy > > + Protocol. The call to Variable Lock is expected to succced and the >=20 >=20 > 'succced' -> 'succeed' >=20 > Best Regards, > Hao Wu >=20 >=20 > > +call to > > + Variable Policy is expected to fail. > > + > > + @param[in] Context Unit test case context > > + **/ > > +UNIT_TEST_STATUS > > +EFIAPI > > +SettingPolicyForALockedVariableShouldFail ( > > + IN UNIT_TEST_CONTEXT Context > > + ) > > +{ > > + EFI_STATUS Status; > > + VARIABLE_POLICY_ENTRY *NewEntry; > > + > > + // Lock the variable. > > + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, > > + &mTestGuid1); UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + // Create a variable policy that locks the variable. > > + Status =3D CreateVarStateVariablePolicy (&mTestGuid1, > > + TEST_VAR_1_NAME, > > + > TEST_POLICY_MIN_SIZE_NULL, > > + > TEST_POLICY_MAX_SIZE_200, > > + > TEST_POLICY_ATTRIBUTES_NULL, > > + > TEST_POLICY_ATTRIBUTES_NULL, > > + &mTestGuid2, > > + 1, > > + TEST_VAR_2_NAME, > > + &NewEntry); > > + UT_ASSERT_NOT_EFI_ERROR (Status); > > + > > + // Register the new policy. > > + Status =3D RegisterVariablePolicy (NewEntry); UT_ASSERT_TRUE > > + (EFI_ERROR (Status)); > > + > > + FreePool (NewEntry); > > + > > + return UNIT_TEST_PASSED; > > +} > > + > > +/** > > + Main entry point to this unit test application. > > + > > + Sets up and runs the test suites. > > +**/ > > +VOID > > +EFIAPI > > +UnitTestMain ( > > + VOID > > + ) > > +{ > > + EFI_STATUS Status; > > + UNIT_TEST_FRAMEWORK_HANDLE Framework; > > + UNIT_TEST_SUITE_HANDLE ShimTests; > > + > > + Framework =3D NULL; > > + > > + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, > > UNIT_TEST_VERSION)); > > + > > + // > > + // Start setting up the test framework for running the tests. > > + // > > + Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME, > > + gEfiCallerBaseName, UNIT_TEST_VERSION); if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status > > =3D %r\n", Status)); > > + goto EXIT; > > + } > > + > > + // > > + // Add all test suites and tests. > > + // > > + Status =3D CreateUnitTestSuite ( > > + &ShimTests, Framework, > > + "Variable Lock Shim Tests", "VarPolicy.VarLockShim", NUL= L, > NULL > > + ); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for > > ShimTests\n")); > > + Status =3D EFI_OUT_OF_RESOURCES; > > + goto EXIT; > > + } > > + AddTestCase ( > > + ShimTests, > > + "Locking a variable with no matching policies should always work"= , > > "EmptyPolicies", > > + LockingWithoutAnyPoliciesShouldSucceed, LibInitMocked, > LibCleanup, > > NULL > > + ); > > + AddTestCase ( > > + ShimTests, > > + "Locking a variable twice should always work", "DoubleLock", > > + LockingTwiceShouldSucceed, LibInitMocked, LibCleanup, NULL > > + ); > > + AddTestCase ( > > + ShimTests, > > + "Locking a variable that's already locked by another policy shoul= d > work", > > "LockAfterPolicy", > > + LockingALockedVariableShouldSucceed, LibInitMocked, LibCleanup, > NULL > > + ); > > + AddTestCase ( > > + ShimTests, > > + "Locking a variable that already has an unlocked policy should fail", > > "LockAfterUnlockedPolicy", > > + LockingAnUnlockedVariableShouldFail, LibInitMocked, LibCleanup, > NULL > > + ); > > + AddTestCase ( > > + ShimTests, > > + "Adding a policy for a variable that has previously been locked should > > always fail", "SetPolicyAfterLock", > > + SettingPolicyForALockedVariableShouldFail, LibInitMocked, > LibCleanup, > > NULL > > + ); > > + > > + // > > + // Execute the tests. > > + // > > + Status =3D RunAllTestSuites (Framework); > > + > > +EXIT: > > + if (Framework !=3D NULL) { > > + FreeUnitTestFramework (Framework); > > + } > > + > > + return; > > +} > > + > > +/// > > +/// Avoid ECC error for function name that starts with lower case > > +letter /// #define Main main > > + > > +/** > > + Standard POSIX C entry point for host based unit test execution. > > + > > + @param[in] Argc Number of arguments > > + @param[in] Argv Array of pointers to arguments > > + > > + @retval 0 Success > > + @retval other Error > > +**/ > > +INT32 > > +Main ( > > + IN INT32 Argc, > > + IN CHAR8 *Argv[] > > + ) > > +{ > > + UnitTestMain (); > > + return 0; > > +} > > diff --git > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va > > riableLockRequestToLockUnitTest.inf > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va > > riableLockRequestToLockUnitTest.inf > > new file mode 100644 > > index 000000000000..2a659d7e1370 > > --- /dev/null > > +++ > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va > > ri > > +++ ableLockRequestToLockUnitTest.inf > > @@ -0,0 +1,36 @@ > > +## @file > > +# This is a host-based unit test for the VariableLockRequestToLock shim. > > +# > > +# Copyright (c) Microsoft Corporation. > > +# SPDX-License-Identifier: BSD-2-Clause-Patent ## > > + > > +[Defines] > > + INF_VERSION =3D 0x00010017 > > + BASE_NAME =3D VariableLockRequestToLockUnitTest > > + FILE_GUID =3D A7388B6C-7274-4717-9649-BDC5DFD1FCBE > > + VERSION_STRING =3D 1.0 > > + MODULE_TYPE =3D HOST_APPLICATION > > + > > +# > > +# The following information is for reference only and not required by the > > build tools. > > +# > > +# VALID_ARCHITECTURES =3D IA32 X64 ARM AARCH64 > > +# > > + > > +[Sources] > > + VariableLockRequestToLockUnitTest.c > > + ../VariableLockRequestToLock.c > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + MdeModulePkg/MdeModulePkg.dec > > + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec > > + > > +[LibraryClasses] > > + UnitTestLib > > + DebugLib > > + VariablePolicyLib > > + VariablePolicyHelperLib > > + BaseMemoryLib > > + MemoryAllocationLib > > diff --git > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToL > > ock.c > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToL > > ock.c > > index 4aa854aaf260..191de6b907c5 100644 > > --- > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToL > > ock.c > > +++ > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToL > > o > > +++ ck.c > > @@ -1,67 +1,360 @@ > > -/** @file -- VariableLockRequestToLock.c -Temporary location of the > > RequestToLock shim code while -projects are moved to VariablePolicy. > > Should be removed when deprecated. > > +/** @file > > + Temporary location of the RequestToLock shim code while projects > > + are moved to VariablePolicy. Should be removed when deprecated. > > > > -Copyright (c) Microsoft Corporation. > > -SPDX-License-Identifier: BSD-2-Clause-Patent > > + Copyright (c) Microsoft Corporation. > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > > > **/ > > > > #include > > - > > #include > > +#include > > #include > > - > > -#include > > - > > -#include > > #include > > #include > > +#include > > > > +// > > +// NOTE: DO NOT USE THESE MACROS on any structure that has not been > > validated. > > +// Current table data has already been sanitized. > > +// > > +#define GET_NEXT_POLICY(CurPolicy) > > +(VARIABLE_POLICY_ENTRY*)((UINT8*)CurPolicy + CurPolicy->Size) #define > > +GET_POLICY_NAME(CurPolicy) (CHAR16*)((UINTN)CurPolicy + > > +CurPolicy->OffsetToName) > > + > > +#define MATCH_PRIORITY_EXACT 0 > > +#define MATCH_PRIORITY_MIN MAX_UINT8 > > + > > +/** > > + This helper function evaluates a policy and determines whether it > > +matches the > > + target variable. If matched, will also return a value corresponding > > +to the > > + priority of the match. > > + > > + The rules for "best match" are listed in the Variable Policy Spec. > > + Perfect name matches will return 0. > > + Single wildcard characters will return the number of wildcard > characters. > > + Full namespaces will return MAX_UINT8. > > + > > + @param[in] EvalEntry Pointer to the policy entry being > evaluated. > > + @param[in] VariableName Same as EFI_SET_VARIABLE. > > + @param[in] VendorGuid Same as EFI_SET_VARIABLE. > > + @param[out] MatchPriority [Optional] On finding a match, this valu= e > > contains > > + the priority of the match. Lower > number =3D=3D higher > > + priority. Only valid if a match found. > > + > > + @retval TRUE Current entry matches the target variable. > > + @retval FALSE Current entry does not match at all. > > + > > +**/ > > +STATIC > > +BOOLEAN > > +EvaluatePolicyMatch ( > > + IN CONST VARIABLE_POLICY_ENTRY *EvalEntry, > > + IN CONST CHAR16 *VariableName, > > + IN CONST EFI_GUID *VendorGuid, > > + OUT UINT8 *MatchPriority OPTIONAL > > + ) > > +{ > > + BOOLEAN Result; > > + CHAR16 *PolicyName; > > + UINT8 CalculatedPriority; > > + UINTN Index; > > + > > + Result =3D FALSE; > > + CalculatedPriority =3D MATCH_PRIORITY_EXACT; > > + > > + // > > + // Step 1: If the GUID doesn't match, we're done. No need to evalua= te > > anything else. > > + // > > + if (!CompareGuid (&EvalEntry->Namespace, VendorGuid)) { > > + goto Exit; > > + } > > + > > + // > > + // If the GUID matches, check to see whether there is a Name > > + associated // with the policy. If not, this policy matches the enti= re > > namespace. > > + // Missing Name is indicated by size being equal to name. > > + // > > + if (EvalEntry->Size =3D=3D EvalEntry->OffsetToName) { > > + CalculatedPriority =3D MATCH_PRIORITY_MIN; > > + Result =3D TRUE; > > + goto Exit; > > + } > > + > > + // > > + // Now that we know the name exists, get it. > > + // > > + PolicyName =3D GET_POLICY_NAME (EvalEntry); > > + > > + // > > + // Evaluate the name against the policy name and check for a match. > > + // Account for any wildcards. > > + // > > + Index =3D 0; > > + Result =3D TRUE; > > + // > > + // Keep going until the end of both strings. > > + // > > + while (PolicyName[Index] !=3D CHAR_NULL || VariableName[Index] !=3D > > CHAR_NULL) { > > + // > > + // If we don't have a match... > > + // > > + if (PolicyName[Index] !=3D VariableName[Index] || PolicyName[Inde= x] > =3D=3D > > '#') { > > + // > > + // If this is a numerical wildcard, we can consider it a match = if we > alter > > + // the priority. > > + // > > + if (PolicyName[Index] =3D=3D L'#' && > > + ((L'0' <=3D VariableName[Index] && VariableName[Index] <= =3D > L'9') || > > + (L'A' <=3D VariableName[Index] && VariableName[Index] <= =3D > L'F') || > > + (L'a' <=3D VariableName[Index] && VariableName[Index] <= =3D > L'f'))) { > > + if (CalculatedPriority < MATCH_PRIORITY_MIN) { > > + CalculatedPriority++; > > + } > > + // > > + // Otherwise, not a match. > > + // > > + } else { > > + Result =3D FALSE; > > + goto Exit; > > + } > > + } > > + Index++; > > + } > > + > > +Exit: > > + if (Result && MatchPriority !=3D NULL) { > > + *MatchPriority =3D CalculatedPriority; > > + } > > + return Result; > > +} > > + > > +/** > > + This helper function walks the current policy table and returns a > > +pointer > > + to the best match, if any are found. Leverages EvaluatePolicyMatch(= ) > > +to > > + determine "best". > > + > > + @param[in] PolicyTable Pointer to current policy table. > > + @param[in] PolicyTableSize Size of current policy table. > > + @param[in] VariableName Same as EFI_SET_VARIABLE. > > + @param[in] VendorGuid Same as EFI_SET_VARIABLE. > > + @param[out] ReturnPriority [Optional] If pointer is provided, return > the > > + priority of the match. Same as > EvaluatePolicyMatch(). > > + Only valid if a match is returned. > > + > > + @retval VARIABLE_POLICY_ENTRY* Best match that was > found. > > + @retval NULL No match was found. > > + > > +**/ > > +STATIC > > +VARIABLE_POLICY_ENTRY* > > +GetBestPolicyMatch ( > > + IN UINT8 *PolicyTable, > > + IN UINT32 PolicyTableSize, > > + IN CONST CHAR16 *VariableName, > > + IN CONST EFI_GUID *VendorGuid, > > + OUT UINT8 *ReturnPriority OPTIONAL > > + ) > > +{ > > + VARIABLE_POLICY_ENTRY *BestResult; > > + VARIABLE_POLICY_ENTRY *CurrentEntry; > > + UINT8 MatchPriority; > > + UINT8 CurrentPriority; > > + > > + BestResult =3D NULL; > > + MatchPriority =3D MATCH_PRIORITY_EXACT; > > + > > + // > > + // Walk all entries in the table, looking for matches. > > + // > > + CurrentEntry =3D (VARIABLE_POLICY_ENTRY*)PolicyTable; > > + while ((UINTN)CurrentEntry < (UINTN)((UINT8*)PolicyTable + > > PolicyTableSize)) { > > + // > > + // Check for a match. > > + // > > + if (EvaluatePolicyMatch (CurrentEntry, VariableName, VendorGuid, > > &CurrentPriority)) { > > + // > > + // If match is better, take it. > > + // > > + if (BestResult =3D=3D NULL || CurrentPriority < MatchPriority) = { > > + BestResult =3D CurrentEntry; > > + MatchPriority =3D CurrentPriority; > > + } > > + > > + // > > + // If you've hit the highest-priority match, can exit now. > > + // > > + if (MatchPriority =3D=3D 0) { > > + break; > > + } > > + } > > + > > + // > > + // If we're still in the loop, move to the next entry. > > + // > > + CurrentEntry =3D GET_NEXT_POLICY (CurrentEntry); } > > + > > + // > > + // If a return priority was requested, return it. > > + // > > + if (ReturnPriority !=3D NULL) { > > + *ReturnPriority =3D MatchPriority; > > + } > > + > > + return BestResult; > > +} > > + > > +/** > > + This helper function will dump and walk the current policy tables t= o > > +determine > > + whether a matching policy already exists that satisfies the lock request. > > + > > + @param[in] VariableName A pointer to the variable name that is > being > > searched. > > + @param[in] VendorGuid A pointer to the vendor GUID that is being > > searched. > > + > > + @retval TRUE We can safely assume this variable is locked. > > + @retval FALSE An error has occurred or we cannot prove that the > variable > > is > > + locked. > > + > > +**/ > > +STATIC > > +BOOLEAN > > +IsVariableAlreadyLocked ( > > + IN CHAR16 *VariableName, > > + IN EFI_GUID *VendorGuid > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT8 *PolicyTable; > > + UINT32 PolicyTableSize; > > + BOOLEAN Result; > > + VARIABLE_POLICY_ENTRY *MatchPolicy; > > + UINT8 MatchPriority; > > + > > + Result =3D TRUE; > > + > > + // > > + // First, we need to dump the existing policy table. > > + // > > + PolicyTableSize =3D 0; > > + PolicyTable =3D NULL; > > + Status =3D DumpVariablePolicy (PolicyTable, &PolicyTableSize); if > > + (Status !=3D EFI_BUFFER_TOO_SMALL) { > > + DEBUG ((DEBUG_ERROR, "%a - Failed to determine policy table > > size! %r\n", __FUNCTION__, Status)); > > + return FALSE; > > + } > > + PolicyTable =3D AllocateZeroPool (PolicyTableSize); if (PolicyTabl= e =3D=3D > > + NULL) { > > + DEBUG ((DEBUG_ERROR, "%a - Failed to allocated space for policy > table! > > 0x%X\n", __FUNCTION__, PolicyTableSize)); > > + return FALSE; > > + } > > + Status =3D DumpVariablePolicy (PolicyTable, &PolicyTableSize); if > > + (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "%a - Failed to dump policy table! %r\n", > > __FUNCTION__, Status)); > > + Result =3D FALSE; > > + goto Exit; > > + } > > + > > + // > > + // Now we need to walk the table looking for a match. > > + // > > + MatchPolicy =3D GetBestPolicyMatch ( > > + PolicyTable, > > + PolicyTableSize, > > + VariableName, > > + VendorGuid, > > + &MatchPriority > > + ); > > + if (MatchPolicy !=3D NULL && MatchPriority !=3D MATCH_PRIORITY_EXAC= T) > { > > + DEBUG ((DEBUG_ERROR, "%a - We would not have expected a > non-exact > > match! %d\n", __FUNCTION__, MatchPriority)); > > + Result =3D FALSE; > > + goto Exit; > > + } > > + > > + // > > + // Now we can check to see whether this variable is currently locke= d. > > + // > > + if (MatchPolicy->LockPolicyType !=3D > VARIABLE_POLICY_TYPE_LOCK_NOW) { > > + DEBUG ((DEBUG_INFO, "%a - Policy may not lock variable! %d\n", > > __FUNCTION__, MatchPolicy->LockPolicyType)); > > + Result =3D FALSE; > > + goto Exit; > > + } > > + > > +Exit: > > + if (PolicyTable !=3D NULL) { > > + FreePool (PolicyTable); > > + } > > + > > + return Result; > > +} > > > > /** > > DEPRECATED. THIS IS ONLY HERE AS A CONVENIENCE WHILE > PORTING. > > - Mark a variable that will become read-only after leaving the DXE phase > of > > execution. > > - Write request coming from SMM environment through > > EFI_SMM_VARIABLE_PROTOCOL is allowed. > > + Mark a variable that will become read-only after leaving the DXE > > + phase of execution. Write request coming from SMM environment > > through > > + EFI_SMM_VARIABLE_PROTOCOL is allowed. > > > > @param[in] This The VARIABLE_LOCK_PROTOCOL > instance. > > - @param[in] VariableName A pointer to the variable name that will b= e > > made read-only subsequently. > > - @param[in] VendorGuid A pointer to the vendor GUID that will be > made > > read-only subsequently. > > + @param[in] VariableName A pointer to the variable name that will b= e > > made > > + read-only subsequently. > > + @param[in] VendorGuid A pointer to the vendor GUID that will be > made > > + read-only subsequently. > > > > - @retval EFI_SUCCESS The variable specified by the > VariableName and > > the VendorGuid was marked > > - as pending to be read-only. > > + @retval EFI_SUCCESS The variable specified by the > VariableName and > > + the VendorGuid was marked as > pending to be > > + read-only. > > @retval EFI_INVALID_PARAMETER VariableName or VendorGuid is > NULL. > > Or VariableName is an empty > string. > > - @retval EFI_ACCESS_DENIED > EFI_END_OF_DXE_EVENT_GROUP_GUID > > or EFI_EVENT_GROUP_READY_TO_BOOT has > > - already been signaled. > > - @retval EFI_OUT_OF_RESOURCES There is not enough resource to > hold > > the lock request. > > + @retval EFI_ACCESS_DENIED > EFI_END_OF_DXE_EVENT_GROUP_GUID > > or > > + > EFI_EVENT_GROUP_READY_TO_BOOT has already been > > + signaled. > > + @retval EFI_OUT_OF_RESOURCES There is not enough resource to > hold > > the lock > > + request. > > **/ > > EFI_STATUS > > EFIAPI > > VariableLockRequestToLock ( > > - IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, > > - IN CHAR16 *VariableName, > > - IN EFI_GUID *VendorGuid > > + IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, > > + IN CHAR16 *VariableName, > > + IN EFI_GUID *VendorGuid > > ) > > { > > - EFI_STATUS Status; > > - VARIABLE_POLICY_ENTRY *NewPolicy; > > + EFI_STATUS Status; > > + VARIABLE_POLICY_ENTRY *NewPolicy; > > + > > + DEBUG ((DEBUG_ERROR, "!!! DEPRECATED INTERFACE !!! %a() will go > away > > + soon!\n", __FUNCTION__)); DEBUG ((DEBUG_ERROR, "!!! DEPRECATED > > + INTERFACE !!! Please move to use Variable Policy!\n")); DEBUG > > + ((DEBUG_ERROR, "!!! DEPRECATED INTERFACE !!! Variable: %g %s\n", > > + VendorGuid, VariableName)); > > > > NewPolicy =3D NULL; > > - Status =3D CreateBasicVariablePolicy( VendorGuid, > > - VariableName, > > - > VARIABLE_POLICY_NO_MIN_SIZE, > > - > VARIABLE_POLICY_NO_MAX_SIZE, > > - > VARIABLE_POLICY_NO_MUST_ATTR, > > - > VARIABLE_POLICY_NO_CANT_ATTR, > > - > VARIABLE_POLICY_TYPE_LOCK_NOW, > > - &NewPolicy ); > > + Status =3D CreateBasicVariablePolicy( > > + VendorGuid, > > + VariableName, > > + VARIABLE_POLICY_NO_MIN_SIZE, > > + VARIABLE_POLICY_NO_MAX_SIZE, > > + VARIABLE_POLICY_NO_MUST_ATTR, > > + VARIABLE_POLICY_NO_CANT_ATTR, > > + VARIABLE_POLICY_TYPE_LOCK_NOW, > > + &NewPolicy > > + ); > > if (!EFI_ERROR( Status )) { > > - Status =3D RegisterVariablePolicy( NewPolicy ); > > + Status =3D RegisterVariablePolicy (NewPolicy); > > + > > + // > > + // If the error returned is EFI_ALREADY_STARTED, we need to check > the > > + // current database for the variable and see whether it's locked. If it's > > + // locked, we're still fine, but also generate a DEBUG_ERROR > message so > > the > > + // duplicate lock can be removed. > > + // > > + if (Status =3D=3D EFI_ALREADY_STARTED) { > > + if (IsVariableAlreadyLocked (VariableName, VendorGuid)) { > > + DEBUG ((DEBUG_ERROR, " Variable: %g %s is already > locked!\n", > > VendorGuid, VariableName)); > > + Status =3D EFI_SUCCESS; > > + } > > + } > > } > > - if (EFI_ERROR( Status )) { > > + if (EFI_ERROR (Status)) { > > DEBUG(( DEBUG_ERROR, "%a - Failed to lock variable %s! %r\n", > > __FUNCTION__, VariableName, Status )); > > - ASSERT_EFI_ERROR( Status ); > > } > > if (NewPolicy !=3D NULL) { > > FreePool( NewPolicy ); > > -- > > 2.29.2.windows.2 > > > > > > > >=20 > > ------=_NextPart_000_0089_01D6CFA0.58855B60 Content-Type: text/html; charset="gb2312" Content-Transfer-Encoding: quoted-printable

Bret:

 For th= e patch split, I consider it from the platform integrator. If the platform = meets with the problem, he can cherry-pick the fix with the minimal code ch= ange.

 

  The patch is separated to two commits. They a= re still one patch serial.

&nbs= p;

Thanks

Liming

=B7=A2=BC= =FE=C8=CB: Wu, Hao A <hao.a.wu@intel.c= om>
=B7=A2=CB=CD=CA=B1=BC=E4: 2020=C4=EA12=D4=C211=C8=D5 8:42
=CA=D5=BC=FE=C8=CB: devel@edk2.groups.io; bret.barkelew@microsoft.com; gaolimin= g <gaoliming@byosoft.com.cn>; Kinney, Michael D <michael.d.kinney@= intel.com>
=D6=F7=CC=E2: RE: [EXTERNAL]
=BB=D8=B8=B4: [edk2= -devel] [Patch v2 1/1] MdeModulePkg/Variable/RuntimeDxe: Restore Variable L= ock Protocol behavior

 

Hello Bret and Mike,

 

Thanks for the explanatio= n on the code reusing open. If the code will eventually be gone, I am fine = with it.

 

For Liming=A1=AFs suggestion to split the= patch into a 2-patch series (1 for the fix and 1 for the unit tests), I am= okay with putting them in 1 patch.

My preference is also breaking them into 2 patches, since these 2 pa= tches are not doing exacting one thing.

But it is only a suggestion, please feel free to make your own d= ecision.

 

In summary, with the typos addressed in t= he patch (in my previous reply to the patch):

Reviewed-by: Hao A Wu <hao.a.wu@intel.com>

 

Best Regards= ,

Hao Wu

 

=

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret Barkelew via = groups.io
Sent: Thursday, December 10, 2020 3:35 PM
To:= gaoliming <gaoliming@byosof= t.com.cn>; Wu, Hao A <hao.a= .wu@intel.com>; devel@edk2.g= roups.io; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: Re: [EXTERNAL]=
=BB=D8=B8=B4: [edk2-dev= el] [Patch v2 1/1] MdeModulePkg/Variable/RuntimeDxe: Restore Variable Lock = Protocol behavior

 

I would prefer to not reuse the code from the libra= ry. They are SUPPOSED to be internal functions and are not part of the publ= ic interface. I=A1=AFve duplicated them here beca= use this shim is supposed to be temporary and should go away within the nex= t few stabilizations.

=  

I would also prefer to keep the tests and the code t= ogether. These are pure unit tests rather than driver tests and serve to do= cument and prove the code that is being submitted. However, I=A1=AF<= span lang=3DEN-US>m willing to be flexible on this.

 

- Bret=


From: gaoliming <gaoliming@byosoft.com.cn>
Sent:<= /b> Wednesday, December 9, 2020 7:16:28 PM
To: 'Wu, Hao A' <hao.a.wu@intel.com>; devel@edk2.groups.io <devel@edk2.groups.io>; Kinney, Michael D <= michael.d.kinney@intel.com>
Cc: Bret Barkelew <
Bret.Barkelew@microsoft.com>
Subject: [EXTERNAL]=
=BB=D8=B8=B4: [edk2-devel] [Patch v2 1/1] MdeModulePkg/Variable/RuntimeDxe= : Restore Variable Lock Protocol behavior

 

Mike:
  I= agree Hao comment. There is the similar code logic in VariablePolicyLiblibrary. They can be shared.

  Besides, I suggest to split th= is patch. One is the bug fix to restore
Variable Lock Protocol behavior,= another is to add Variable driver unit
test.

Thanks
Liming> -----
=D3=CA=BC=FE=D4=AD=BC= =FE-----
>
=B7=A2=BC=FE=C8=CB: Wu, Hao A <hao.a.wu@intel.= com>
>
=B7=A2=CB=CD=CA=B1=BC=E4: 202= 0=C4=EA12=D4=C210=C8=D5 10:25
>
=CA=D5=BC=FE=C8=CB: devel@edk2.groups.io; Kinney, Michael D
> <
michael.d.kinney@intel.com>
>
=B3=AD=CB=CD: Bret Barkelew <bret.barkelew@microsoft.com>; Liming Gao
> <gaoliming@byosoft.com.cn>
> =D6=F7=CC=E2: RE: [edk2-devel] [Patch v2 1/1] MdeMod= ulePkg/Variable/RuntimeDxe:
> Restore Variable Lock Protocol behavior=
>
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Micha= el
> > D Kinney
> > Sent: Thursday, December 10, 2020 2:0= 6 AM
> > To: devel@edk2.gr= oups.io
> > Cc: Bret Barkelew <bret.barkelew@microsoft.com>; Wu, Hao A
> &= gt; <hao.a.wu@intel.com>; L= iming Gao <gaoliming@byosoft= .com.cn>; Bret
> > Barkelew <Bret.Barkelew@microsoft.com>
> > Subjec= t: [edk2-devel] [Patch v2 1/1] MdeModulePkg/Variable/RuntimeDxe:
> &g= t; Restore Variable Lock Protocol behavior
> >
> > From: = Bret Barkelew <bret.barke= lew@microsoft.com>
> >
> > https:/= /nam06.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fbugzilla.tiano= core.org%2Fshow_bug.cgi%3Fid%3D3111&amp;data=3D04%7C01%7Cbret.barkelew%= 40microsoft.com%7C4115faaa16c6475b8e3508d89cba0189%7C72f988bf86f141af91ab2d= 7cd011db47%7C1%7C0%7C637431669999943616%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4= wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdat= a=3DDU8EYtayepZpsyxajKK9w0mQ5kExWXG2AJvCcvVVy1A%3D&amp;reserved=3D0=
> >
> > The VariableLock shim currently fails if called = twice because the
underlying
> > Variable Policy engine returns= an error if a policy is set on an
existing
> variable.
> &g= t;
> > This breaks existing code which expect it to silently pass = if a variable
is
> locked
> > multiple times (because it = should "be locked").
> >
> > Refactor the shim = to confirm that the variable is indeed locked and then
> > change = the error to EFI_SUCCESS and generate a DEBUG_ERROR message
> so
&= gt; > the duplicate lock can be reported in a debug log and removed.
= >
>
> Hello,
>
> Is it possible to reuse:
= >     a) EvaluatePolicyMatch() and GetBestPolicyMatc= h() functions
>     b) Macros like GET_NEXT_POLIC= Y, GET_POLICY_NAME and etc.
> under MdeModulePkg\Library\VariablePoli= cyLib to reduce duplicate codes?
>
> A couple of minor inline = comments below:
>
>
> >
> > Add host based = unit tests for the multiple lock case using Variable Lock
> > Prot= ocol, Variable Policy Protocol, and mixes of Variable Lock Protocol
and<= br>> > Variable Policy Protocol.
> >
> > Cc: Michae= l D Kinney <michael.d.kinn= ey@intel.com>
> > Cc: Hao A Wu <hao.a.wu@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn><= br>> > Signed-off-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > ---
&= gt; >  MdeModulePkg/Test/MdeModulePkgHostTest.dsc   = |  11 +
> >  .../VariableLockRequestToLockUnitTest.c&nb= sp;      | 434
> ++++++++++++++++++
> = >  .../VariableLockRequestToLockUnitTest.inf    = ; |  36 ++
> >  .../RuntimeDxe/VariableLockRequestToLock= .c    | 363
> +++++++++++++--
> >  4 fil= es changed, 809 insertions(+), 35 deletions(-)  create mode 100644
= > > MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Var= i
> > ableLockRequestToLockUnitTest.c
> >  create mo= de 100644
> > MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDx= eUnitTest/Vari
> > ableLockRequestToLockUnitTest.inf
> ><= br>> > diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
>= ; > b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
> > index 72a1= 19db4568..4da4692c8451 100644
> > --- a/MdeModulePkg/Test/MdeModul= ePkgHostTest.dsc
> > +++ b/MdeModulePkg/Test/MdeModulePkgHostTest.= dsc
> > @@ -19,6 +19,9 @@ [Defines]
> >
> > = ; !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
> &g= t;
> > +[LibraryClasses]
> > +  SafeIntLib|MdePkg/Li= brary/BaseSafeIntLib/BaseSafeIntLib.inf
> > +
> >  [= Components]
> >
> > MdeModulePkg/Library/DxeResetSystemLi= b/UnitTest/MockUefiRuntimeSer
> > vicesTableLib.inf
> >> > @@ -30,3 +33,11 @@ [Components]
> >
> > Reset= SystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSyst
> > = emLib.inf
> >
> > UefiRuntimeServicesTableLib|MdeModulePk= g/Library/DxeResetSystemLib/
> > UnitTest/MockUefiRuntimeServicesT= ableLib.inf
> >    }
> > +
> > +<= br>> > MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/= Vari
> > ableLockRequestToLockUnitTest.inf {
> > + &= nbsp;  <LibraryClasses>
> > +
> >
> Vari= ablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLi
&g= t; > b.inf
> > +
> >
> VariablePolicyHelperLib|M= deModulePkg/Library/VariablePolicyHelperLib/Va
> > riablePolicyHel= perLib.inf
> > +    <PcdsFixedAtBuild>
>= ; > +
> > +
> > gEfiMdeModulePkgTokenSpaceGuid.PcdAllo= wVariablePolicyEnforcementDis
> > abl
> > + e|TRUE
>= ; > +  }
> > diff --git
> > a/MdeModulePkg/Univer= sal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va
> > riableLockReques= tToLockUnitTest.c
> > b/MdeModulePkg/Universal/Variable/RuntimeDxe= /RuntimeDxeUnitTest/Va
> > riableLockRequestToLockUnitTest.c
&g= t; > new file mode 100644
> > index 000000000000..2f4c4d2f79f4<= br>> > --- /dev/null
> > +++
> > b/MdeModulePkg/Uni= versal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va
> > ri
> &g= t; +++ ableLockRequestToLockUnitTest.c
> > @@ -0,0 +1,434 @@
&g= t; > +/** @file
> > +  This is a host-based unit test for = the VariableLockRequestToLock
shim.
> > +
> > +  = Copyright (c) Microsoft Corporation.
> > +  SPDX-License-Iden= tifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +=
> > +#include <stdio.h>
> > +#include <string.h= >
> > +#include <stdarg.h>
> > +#include <std= def.h>
> > +#include <setjmp.h>
> > +#include &l= t;cmocka.h>
> > +
> > +#include <Uefi.h>
>= > +#include <Library/DebugLib.h>
> > +#include <Libra= ry/BaseMemoryLib.h>
> > +#include <Library/MemoryAllocationL= ib.h> #include
> > +<Library/UnitTestLib.h> #include <= Library/VariablePolicyLib.h> #include
> > +<Library/Variable= PolicyHelperLib.h>
> > +
> > +#include <Protocol/Va= riableLock.h>
> > +
> > +#define UNIT_TEST_NAME &= nbsp;      "VarPol/VarLock Shim Unit Test&quo= t;
> > +#define UNIT_TEST_VERSION     "1.= 0"
> > +
> > +///=3D=3D=3D CODE UNDER TEST
> &= gt; +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D=3D
> > +=3D=3D=3D=3D
> > +
> > +EFI_S= TATUS
> > +EFIAPI
> > +VariableLockRequestToLock (
>= ; > +  IN CONST EDKII_VARIABLE_LOCK_PROTOCOL  *This,
> &= gt; +  IN       CHAR16   =             &nb= sp;        *VariableName,
> > +=   IN       EFI_GUID   &nb= sp;            =       *VendorGuid
> > +  );
> = > +
> > +///=3D=3D=3D TEST DATA
> > +=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
&g= t; > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > +
> > +//<= br>> > +// Test GUID 1 {F955BA2D-4A2C-480C-BFD1-3CC522610592}
>= > +//
> > +EFI_GUID  mTestGuid1 =3D {
> > + = ; 0xf955ba2d, 0x4a2c, 0x480c, {0xbf, 0xd1, 0x3c, 0xc5, 0x22, 0x61, 0x5,
= > > +0x92} };
> > +
> > +//
> > +// Test G= UID 2 {2DEA799E-5E73-43B9-870E-C945CE82AF3A}
> > +//
> > = +EFI_GUID  mTestGuid2 =3D {
> > +  0x2dea799e, 0x5e73, 0= x43b9, {0x87, 0xe, 0xc9, 0x45, 0xce, 0x82, 0xaf,
> > +0x3a} };
= > > +
> > +//
> > +// Test GUID 3 {698A2BFD-A616-48= 2D-B88C-7100BD6682A9}
> > +//
> > +EFI_GUID  mTestGu= id3 =3D {
> > +  0x698a2bfd, 0xa616, 0x482d, {0xb8, 0x8c, 0x7= 1, 0x0, 0xbd, 0x66, 0x82,
> > +0xa9} };
> > +
> >= ; +#define TEST_VAR_1_NAME        &= nbsp;     L"TestVar1"
> > +#define T= EST_VAR_2_NAME          &= nbsp;   L"TestVar2"
> > +#define TEST_VAR_3_NA= ME            &= nbsp; L"TestVar3"
> > +
> > +#define TEST_POLIC= Y_ATTRIBUTES_NULL  0
> > +#define TEST_POLICY_MIN_SIZE_NULL&n= bsp;   0
> > +#define TEST_POLICY_MAX_SIZE_NULL &nb= sp;  MAX_UINT32
> > +
> > +#define TEST_POLICY_MIN_S= IZE_10      10
> > +#define TEST_POLICY_M= AX_SIZE_200     200
> > +
> > +///=3D= = =3D=3D HELPER FUNCTIONS
> > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> &g= t; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > +=3D=3D=3D=3D> > +
> > +/**
> > +  Mocked version of GetVa= riable, for testing.
> > +
> > +  @param  Varia= bleName
> > +  @param  VendorGuid
> > +  @= param  Attributes
> > +  @param  DataSize
> &= gt; +  @param  Data
> > +**/
> > +EFI_STATUS> > +EFIAPI
> > +StubGetVariableNull (
> > + = IN     CHAR16    *VariableName,
>= > +  IN     EFI_GUID  *VendorGuid,
>= ; > +  OUT    UINT32    *Attributes,&= nbsp; OPTIONAL
> > +  IN OUT UINTN     *D= ataSize,
> > +  OUT    VOID   &= nbsp;  *Data         OPTIONAL<= br>> > +  )
> > +{
> > +  UINT32 &nb= sp;    MockedAttr;
> > +  UINTN  &nb= sp;    MockedDataSize;
> > +  VOID  =       *MockedData;
> > +  EFI_STATUS=   MockedReturn;
> > +
> > +  check_expected_ptr= (VariableName);
> > +  check_expected_ptr (VendorGuid);
&= gt; > +  check_expected_ptr (DataSize);
> > +
> >= +  MockedAttr     =3D (UINT32)mock();
> >= ; +  MockedDataSize =3D (UINTN)mock();
> > +  MockedData=      =3D (VOID*)(UINTN)mock();
> > +  Moc= kedReturn   =3D (EFI_STATUS)mock();
> > +
> > +=   if (Attributes !=3D NULL) {
> > +    *Attrib= utes =3D MockedAttr;
> > +  }
> > +  if (Data != = =3D NULL && !EFI_ERROR (MockedReturn)) {
> > +  = ;  CopyMem (Data, MockedData, MockedDataSize);  }
> > +<= br>> > +  *DataSize =3D MockedDataSize;
> > +
> &= gt; +  return MockedReturn;
> > +}
> > +
> >= ; +//
> > +// Anything you think might be helpful that isn't a tes= t itself.
> > +//
> > +
> > +/**
> > +&= nbsp; This is a common setup function that will ensure the library is
&g= t; > +always
> > +  initialized with the stubbed GetVariab= le.
> > +
> > +  Not used by all test cases, but by = most.
> > +
> > +  @param[in]  Context  Un= it test case context **/ STATIC
> > +UNIT_TEST_STATUS EFIAPI LibIn= itMocked (
> > +  IN UNIT_TEST_CONTEXT  Context
> = > +  )
> > +{
> > +  return EFI_ERROR (InitV= ariablePolicyLib (StubGetVariableNull)) ?
> > +UNIT_TEST_ERROR_PRE= REQUISITE_NOT_MET : UNIT_TEST_PASSED; }
> > +
> > +/**> > +  Common cleanup function to make sure that the library is= always
> > +de-initialized
> > +  prior to the next= test case.
> > +
> > +  @param[in]  Context&nb= sp; Unit test case context **/ STATIC VOID EFIAPI
> > +LibCleanup = (
> > +  IN UNIT_TEST_CONTEXT  Context
> > +&nb= sp; )
> > +{
> > +  DeinitVariablePolicyLib();
&g= t; > +}
> > +
> > +///=3D=3D=3D TEST CASES
> >= ; +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D
> > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> > +
&= gt; > +///=3D=3D=3D=3D=3D SHIM SUITE
> > +=3D=3D=3D=3D=3D=3D=3D= = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D
> > =3D=3D
> > +
> > +/**
> > +=   Test Case that locks a single variable using the Variable Lock
Pr= otocol.
> > +  The call is expected to succeed.
> > = +
> > +  @param[in]  Context  Unit test case contex= t **/ UNIT_TEST_STATUS
> > +EFIAPI LockingWithoutAnyPoliciesShould= Succeed (
> > +  IN UNIT_TEST_CONTEXT  Context
> &= gt; +  )
> > +{
> > +  EFI_STATUS  Status;=
> > +
> > +  Status =3D VariableLockRequestToLock (= NULL, TEST_VAR_1_NAME,
> > + &mTestGuid1);  UT_ASSERT_NOT= _EFI_ERROR (Status);
> > +
> > +  return UNIT_TEST_P= ASSED;
> > +}
> > +
> > +/**
> > + = ; Test Case that locks the same variable twice using the Variable Lock
&= gt; Procol.
>
>
> Minor comment, typo for 'Procol' ->= ; 'Protocol'
>
>
> > +  Both calls are expected= to succeed.
> > +
> > +  @param[in]  Context&n= bsp; Unit test case context
> > +  **/
> > +UNIT_TES= T_STATUS
> > +EFIAPI
> > +LockingTwiceShouldSucceed (
= > > +  IN UNIT_TEST_CONTEXT  Context
> > +  )=
> > +{
> > +  EFI_STATUS  Status;
> >= +
> > +  Status =3D VariableLockRequestToLock (NULL, TEST_VA= R_1_NAME,
> > + &mTestGuid1);  UT_ASSERT_NOT_EFI_ERROR (S= tatus);
> > +
> > +  Status =3D VariableLockRequestT= oLock (NULL, TEST_VAR_1_NAME,
> > + &mTestGuid1);  UT_ASS= ERT_NOT_EFI_ERROR (Status);
> > +
> > +  return UNIT= _TEST_PASSED;
> > +}
> > +
> > +/**
> >= +  Test Case that locks a variable using the Variable Policy Protocol=
> > +then locks
> > +  the same variable using the = Variable Lock Protocol.
> > +  Both calls are expected to suc= ceed.
> > +
> > +  @param[in]  Context  Un= it test case context
> > +  **/
> > +UNIT_TEST_STATU= S
> > +EFIAPI
> > +LockingALockedVariableShouldSucceed (<= br>> > +  IN UNIT_TEST_CONTEXT  Context
> > + = ; )
> > +{
> > +  EFI_STATUS    =          Status;
> > +&nbs= p; VARIABLE_POLICY_ENTRY  *NewEntry;
> > +
> > +&nbs= p; //
> > +  // Create a variable policy that locks the varia= ble.
> > +  //
> > +  Status =3D CreateBasicVar= iablePolicy (
> > +        = ;     &mTestGuid1,
> > +   =           TEST_VAR_1_NAME,
= > > +          &nbs= p;  TEST_POLICY_MIN_SIZE_NULL,
> > +    &= nbsp;        TEST_POLICY_MAX_SIZE_200,> > +          &n= bsp;  TEST_POLICY_ATTRIBUTES_NULL,
> > +   &nb= sp;         TEST_POLICY_ATTRIBUTES_= NULL,
> > +         &= nbsp;   VARIABLE_POLICY_TYPE_LOCK_NOW,
> > +  =            &NewEntry<= br>> > +          &= nbsp;  );
> > +  UT_ASSERT_NOT_EFI_ERROR (Status);
&g= t; > +
> > +  //
> > +  // Register the new = policy.
> > +  //
> > +  Status =3D RegisterVar= iablePolicy (NewEntry);
> > +
> > +  Status =3D Vari= ableLockRequestToLock (NULL, TEST_VAR_1_NAME,
> > + &mTestGuid= 1);  UT_ASSERT_NOT_EFI_ERROR (Status);
> > +
> > +&n= bsp; FreePool (NewEntry);
> > +
> > +  return UNIT_T= EST_PASSED;
> > +}
> > +
> > +/**
> > +=   Test Case that locks a variable using the Variable Policy Protocol> > +with a
> > +  policy other than LOCK_NOW then at= tempts to lock the same variable
> > +using the
> > +&nbs= p; Variable Lock Protocol.  The call to Variable Policy is expected to=
> > +succced
>
>
> 'succced' -> 'succeed'<= br>>
>
> > +  and the call to Variable Lock is exp= ected to fail.
> > +
> > +  @param[in]  Context=   Unit test case context
> > +  **/
> > +UNIT_T= EST_STATUS
> > +EFIAPI
> > +LockingAnUnlockedVariableShou= ldFail (
> > +  IN UNIT_TEST_CONTEXT    &= nbsp; Context
> > +  )
> > +{
> > +  E= FI_STATUS           =      Status;
> > +  VARIABLE_POLICY_ENTRY=      *NewEntry;
> > +
> > +  // = Create a variable policy that locks the variable.
> > +  Stat= us =3D CreateVarStateVariablePolicy (&mTestGuid1,
> > + &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;  TEST_VAR_1_NAME,
> > +
> TEST_POLICY_MIN_SIZE_NULL,=
> > +
> TEST_POLICY_MAX_SIZE_200,
> > +
> TE= ST_POLICY_ATTRIBUTES_NULL,
> > +
> TEST_POLICY_ATTRIBUTES_NU= LL,
> > +         &nb= sp;            =             &nb= sp;      &mTestGuid2,
> > + &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp; 1,
> > +        &nbs= p;            &= nbsp;           &nbs= p;       TEST_VAR_2_NAME,
> > + = ;            &n= bsp;            = ;            &n= bsp;  &NewEntry);
> > + UT_ASSERT_NOT_EFI_ERROR (Status);=
> > +
> > +  // Register the new policy.
> &g= t; +  Status =3D RegisterVariablePolicy (NewEntry);
> > +
= > > +  Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NA= ME,
> > + &mTestGuid1);  UT_ASSERT_TRUE (EFI_ERROR (Statu= s));
> > +
> > +  FreePool (NewEntry);
> > = +
> > +  return UNIT_TEST_PASSED;
> > +}
> >= ; +
> > +/**
> > +  Test Case that locks a variable = using Variable Lock Protocol Policy
> > +Protocol
> > +&n= bsp; then and then attempts to lock the same variable using the Variable> > +Policy
> > +  Protocol.  The call to Variabl= e Lock is expected to succced and the
>
>
> 'succced' -= > 'succeed'
>
> Best Regards,
> Hao Wu
>
&g= t;
> > +call to
> > +  Variable Policy is expected = to fail.
> > +
> > +  @param[in]  Context = Unit test case context
> > +  **/
> > +UNIT_TEST_ST= ATUS
> > +EFIAPI
> > +SettingPolicyForALockedVariableShou= ldFail (
> > +  IN UNIT_TEST_CONTEXT    &= nbsp; Context
> > +  )
> > +{
> > +  E= FI_STATUS           =      Status;
> > +  VARIABLE_POLICY_ENTRY=      *NewEntry;
> > +
> > +  // = Lock the variable.
> > +  Status =3D VariableLockRequestToLoc= k (NULL, TEST_VAR_1_NAME,
> > + &mTestGuid1);  UT_ASSERT_= NOT_EFI_ERROR (Status);
> > +
> > +  // Create a var= iable policy that locks the variable.
> > +  Status =3D Creat= eVarStateVariablePolicy (&mTestGuid1,
> > +   &= nbsp;           &nbs= p;            &= nbsp;            TES= T_VAR_1_NAME,
> > +
> TEST_POLICY_MIN_SIZE_NULL,
> >= ; +
> TEST_POLICY_MAX_SIZE_200,
> > +
> TEST_POLICY_AT= TRIBUTES_NULL,
> > +
> TEST_POLICY_ATTRIBUTES_NULL,
> = > +           &nb= sp;            =             &nb= sp;    &mTestGuid2,
> > +   &nbs= p;            &= nbsp;           &nbs= p;            1,
= > > +          &nbs= p;            &= nbsp;           &nbs= p;     TEST_VAR_2_NAME,
> > +   = ;            &n= bsp;            = ;             &= amp;NewEntry);
> > + UT_ASSERT_NOT_EFI_ERROR (Status);
> >= ; +
> > +  // Register the new policy.
> > +  S= tatus =3D RegisterVariablePolicy (NewEntry);  UT_ASSERT_TRUE
> &= gt; + (EFI_ERROR (Status));
> > +
> > +  FreePool (N= ewEntry);
> > +
> > +  return UNIT_TEST_PASSED;
&= gt; > +}
> > +
> > +/**
> > +  Main entr= y point to this unit test application.
> > +
> > +  = Sets up and runs the test suites.
> > +**/
> > +VOID
&= gt; > +EFIAPI
> > +UnitTestMain (
> > +  VOID
= > > +  )
> > +{
> > +  EFI_STATUS &n= bsp;            = ;    Status;
> > +  UNIT_TEST_FRAMEWORK_HANDLE=   Framework;
> > +  UNIT_TEST_SUITE_HANDLE  &n= bsp;   ShimTests;
> > +
> > +  Framework = =3D NULL;
> > +
> > +  DEBUG ((DEBUG_INFO, "%a= v%a\n", UNIT_TEST_NAME,
> > UNIT_TEST_VERSION));
> >= ; +
> > +  //
> > +  // Start setting up the te= st framework for running the tests.
> > +  //
> > +&= nbsp; Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME,
= > > + gEfiCallerBaseName, UNIT_TEST_VERSION);  if (EFI_ERROR (St= atus)) {
> > +    DEBUG ((DEBUG_ERROR, "Failed= in InitUnitTestFramework. Status
> > =3D %r\n", Status));> > +    goto EXIT;
> > +  }
> &g= t; +
> > +  //
> > +  // Add all test suites an= d tests.
> > +  //
> > +  Status =3D CreateUnit= TestSuite (
> > +        &= nbsp;    &ShimTests, Framework,
> > + &nbs= p;           "Variab= le Lock Shim Tests", "VarPolicy.VarLockShim", NULL,
> = NULL
> > +         &n= bsp;   );
> > +  if (EFI_ERROR (Status)) {
> = > +    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTes= tSuite for
> > ShimTests\n"));
> > +  &nbs= p; Status =3D EFI_OUT_OF_RESOURCES;
> > +    goto E= XIT;
> > +  }
> > +  AddTestCase (
> >= +    ShimTests,
> > +    "Lock= ing a variable with no matching policies should always work",
> = > "EmptyPolicies",
> > +    LockingWit= houtAnyPoliciesShouldSucceed, LibInitMocked,
> LibCleanup,
> &g= t; NULL
> > +    );
> > +  AddTestCas= e (
> > +    ShimTests,
> > +  &= nbsp; "Locking a variable twice should always work", "Double= Lock",
> > +    LockingTwiceShouldSucceed, Lib= InitMocked, LibCleanup, NULL
> > +    );
> &g= t; +  AddTestCase (
> > +    ShimTests,
>= ; > +    "Locking a variable that's already locked b= y another policy should
> work",
> > "LockAfterPol= icy",
> > +    LockingALockedVariableShouldSuc= ceed, LibInitMocked, LibCleanup,
> NULL
> > +  &nb= sp; );
> > +  AddTestCase (
> > +    = ShimTests,
> > +    "Locking a variable that a= lready has an unlocked policy should
fail",
> > "Lock= AfterUnlockedPolicy",
> > +    LockingAnUnlock= edVariableShouldFail, LibInitMocked, LibCleanup,
> NULL
> > = +    );
> > +  AddTestCase (
> > +&nb= sp;   ShimTests,
> > +    "Adding a = policy for a variable that has previously been locked
should
> >= ; always fail", "SetPolicyAfterLock",
> > + &n= bsp;  SettingPolicyForALockedVariableShouldFail, LibInitMocked,
>= ; LibCleanup,
> > NULL
> > +    );
>= > +
> > +  //
> > +  // Execute the tests.<= br>> > +  //
> > +  Status =3D RunAllTestSuites (F= ramework);
> > +
> > +EXIT:
> > +  if (Fram= ework !=3D NULL) {
> > +    FreeUnitTestFramework (= Framework);
> > +  }
> > +
> > +  retu= rn;
> > +}
> > +
> > +///
> > +/// Avoi= d ECC error for function name that starts with lower case
> > +let= ter /// #define Main main
> > +
> > +/**
> > +&n= bsp; Standard POSIX C entry point for host based unit test execution.
&g= t; > +
> > +  @param[in] Argc  Number of arguments> > +  @param[in] Argv  Array of pointers to arguments
= > > +
> > +  @retval 0      Su= ccess
> > +  @retval other  Error
> > +**/
&= gt; > +INT32
> > +Main (
> > +  IN INT32  Ar= gc,
> > +  IN CHAR8  *Argv[]
> > +  )
&= gt; > +{
> > +  UnitTestMain ();
> > +  retu= rn 0;
> > +}
> > diff --git
> > a/MdeModulePkg/U= niversal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va
> > riableLockR= equestToLockUnitTest.inf
> > b/MdeModulePkg/Universal/Variable/Run= timeDxe/RuntimeDxeUnitTest/Va
> > riableLockRequestToLockUnitTest.= inf
> > new file mode 100644
> > index 000000000000..2a65= 9d7e1370
> > --- /dev/null
> > +++
> > b/MdeModu= lePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va
> > ri> > +++ ableLockRequestToLockUnitTest.inf
> > @@ -0,0 +1,3= 6 @@
> > +## @file
> > +# This is a host-based unit test = for the VariableLockRequestToLock
shim.
> > +#
> > +# = Copyright (c) Microsoft Corporation.
> > +# SPDX-License-Identifie= r: BSD-2-Clause-Patent ##
> > +
> > +[Defines]
> &g= t; +  INF_VERSION         =3D = 0x00010017
> > +  BASE_NAME     &nbs= p;     =3D VariableLockRequestToLockUnitTest
> &g= t; +  FILE_GUID         &= nbsp; =3D A7388B6C-7274-4717-9649-BDC5DFD1FCBE
> > +  VERSION= _STRING      =3D 1.0
> > +  MODULE_T= YPE         =3D HOST_APPLICATION> > +
> > +#
> > +# The following information is f= or reference only and not required by
the
> > build tools.
&= gt; > +#
> > +#  VALID_ARCHITECTURES   &nbs= p;       =3D IA32 X64 ARM AARCH64
> >= ; +#
> > +
> > +[Sources]
> > +  VariableLo= ckRequestToLockUnitTest.c
> > +  ../VariableLockRequestToLock= .c
> > +
> > +[Packages]
> > +  MdePkg/MdeP= kg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +&nb= sp; UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
> > +
> &g= t; +[LibraryClasses]
> > +  UnitTestLib
> > +  = DebugLib
> > +  VariablePolicyLib
> > +  Variab= lePolicyHelperLib
> > +  BaseMemoryLib
> > +  M= emoryAllocationLib
> > diff --git
> > a/MdeModulePkg/Univ= ersal/Variable/RuntimeDxe/VariableLockRequestToL
> > ock.c
>= > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToL> > ock.c
> > index 4aa854aaf260..191de6b907c5 100644
&= gt; > ---
> > a/MdeModulePkg/Universal/Variable/RuntimeDxe/Vari= ableLockRequestToL
> > ock.c
> > +++
> > b/MdeMo= dulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToL
> > o=
> > +++ ck.c
> > @@ -1,67 +1,360 @@
> > -/** @f= ile -- VariableLockRequestToLock.c -Temporary location of the
> > = RequestToLock shim code while -projects are moved to VariablePolicy.
>= ; > Should be removed when deprecated.
> > +/** @file
> &= gt; +  Temporary location of the RequestToLock shim code while project= s
> > +  are moved to VariablePolicy. Should be removed when = deprecated.
> >
> > -Copyright (c) Microsoft Corporation.=
> > -SPDX-License-Identifier: BSD-2-Clause-Patent
> > +&= nbsp; Copyright (c) Microsoft Corporation.
> > +  SPDX-Licens= e-Identifier: BSD-2-Clause-Patent
> >
> >  **/
&g= t; >
> >  #include <Uefi.h>
> > -
> &= gt;  #include <Library/DebugLib.h>
> > +#include <Li= brary/BaseMemoryLib.h>
> >  #include <Library/MemoryAll= ocationLib.h>
> > -
> > -#include <Protocol/Variabl= eLock.h>
> > -
> > -#include <Protocol/VariablePoli= cy.h>
> >  #include <Library/VariablePolicyLib.h>> >  #include <Library/VariablePolicyHelperLib.h>
>= > +#include <Protocol/VariableLock.h>
> >
> > += //
> > +// NOTE: DO NOT USE THESE MACROS on any structure that has= not been
> > validated.
> > +//    &= nbsp;  Current table data has already been sanitized.
> > +//=
> > +#define GET_NEXT_POLICY(CurPolicy)
> > +(VARIABLE_P= OLICY_ENTRY*)((UINT8*)CurPolicy + CurPolicy->Size) #define
> > = +GET_POLICY_NAME(CurPolicy)  (CHAR16*)((UINTN)CurPolicy +
> >= +CurPolicy->OffsetToName)
> > +
> > +#define MATCH_PR= IORITY_EXACT  0
> > +#define MATCH_PRIORITY_MIN  &n= bsp; MAX_UINT8
> > +
> > +/**
> > +  This h= elper function evaluates a policy and determines whether it
> > +m= atches the
> > +  target variable. If matched, will also retu= rn a value corresponding
> > +to the
> > +  priority= of the match.
> > +
> > +  The rules for "best= match" are listed in the Variable Policy Spec.
> > +  P= erfect name matches will return 0.
> > +  Single wildcard cha= racters will return the number of wildcard
> characters.
> >= +  Full namespaces will return MAX_UINT8.
> > +
> >= +  @param[in]  EvalEntry      Pointer t= o the policy entry being
> evaluated.
> > +  @param[in]=   VariableName   Same as EFI_SET_VARIABLE.
> > +&nb= sp; @param[in]  VendorGuid     Same as EFI_SET_VAR= IABLE.
> > +  @param[out] MatchPriority  [Optional] On f= inding a match, this value
> > contains
> > +  =             &nb= sp;            =   the priority of the match. Lower
> number =3D=3D higher
>= ; > +           &= nbsp;           &nbs= p;     priority. Only valid if a match found.
> &= gt; +
> > +  @retval  TRUE   Current entry mat= ches the target variable.
> > +  @retval  FALSE  Cu= rrent entry does not match at all.
> > +
> > +**/
>= > +STATIC
> > +BOOLEAN
> > +EvaluatePolicyMatch (
= > > +  IN CONST VARIABLE_POLICY_ENTRY  *EvalEntry,
> = > +  IN CONST CHAR16        = ;         *VariableName,
> &g= t; +  IN CONST EFI_GUID        = ;       *VendorGuid,
> > +  OUT= UINT8           &nb= sp;           *MatchPrior= ity  OPTIONAL
> > +  )
> > +{
> > +&nb= sp; BOOLEAN  Result;
> > +  CHAR16   *PolicyNa= me;
> > +  UINT8    CalculatedPriority;
>= ; > +  UINTN    Index;
> > +
> > +=   Result =3D FALSE;
> > +  CalculatedPriority =3D MATCH_= PRIORITY_EXACT;
> > +
> > +  //
> > + = // Step 1: If the GUID doesn't match, we're done. No need to evaluate
&= gt; > anything else.
> > +  //
> > +  if (!C= ompareGuid (&EvalEntry->Namespace, VendorGuid)) {
> > +&nbs= p;   goto Exit;
> > +  }
> > +
> >= ; +  //
> > +  // If the GUID matches, check to see whet= her there is a Name
> > + associated  // with the policy. If = not, this policy matches the entire
> > namespace.
> > +&= nbsp; // Missing Name is indicated by size being equal to name.
> >= ; +  //
> > +  if (EvalEntry->Size =3D=3D EvalEntry-&= gt;OffsetToName) {
> > +    CalculatedPriority =3D = MATCH_PRIORITY_MIN;
> > +    Result =3D TRUE;
&g= t; > +    goto Exit;
> > +  }
> > = +
> > +  //
> > +  // Now that we know the name= exists, get it.
> > +  //
> > +  PolicyName = =3D GET_POLICY_NAME (EvalEntry);
> > +
> > +  //> > +  // Evaluate the name against the policy name and check f= or a match.
> > +  // Account for any wildcards.
> >= +  //
> > +  Index =3D 0;
> > +  Result = =3D TRUE;
> > +  //
> > +  // Keep going until= the end of both strings.
> > +  //
> > +  whil= e (PolicyName[Index] !=3D CHAR_NULL || VariableName[Index] !=3D
> >= ; CHAR_NULL) {
> > +    //
> > + &nbs= p;  // If we don't have a match...
> > +    //=
> > +    if (PolicyName[Index] !=3D VariableName[I= ndex] || PolicyName[Index]
> =3D=3D
> > '#') {
> > = +      //
> > +    &n= bsp; // If this is a numerical wildcard, we can consider it a match if
w= e
> alter
> > +      // the priorit= y.
> > +      //
> > + &nbs= p;    if (PolicyName[Index] =3D=3D L'#' &&
> &= gt; +            ((L= '0' <=3D VariableName[Index] && VariableName[Index] <=3D
&= gt; L'9') ||
> > +        =      (L'A' <=3D VariableName[Index] && Varia= bleName[Index] <=3D
> L'F') ||
> > +   &nb= sp;         (L'a' <=3D VariableN= ame[Index] && VariableName[Index] <=3D
> L'f'))) {
>= > +        if (CalculatedPriority &l= t; MATCH_PRIORITY_MIN) {
> > +      =     CalculatedPriority++;
> > +   &n= bsp;    }
> > +      //> > +      // Otherwise, not a match.
&g= t; > +      //
> > +   =    } else {
> > +      &nb= sp; Result =3D FALSE;
> > +      &nb= sp; goto Exit;
> > +      }
> > = +    }
> > +    Index++;
> >= ; +  }
> > +
> > +Exit:
> > +  if (Res= ult && MatchPriority !=3D NULL) {
> > +    = *MatchPriority =3D CalculatedPriority;
> > +  }
> > = +  return Result;
> > +}
> > +
> > +/**
= > > +  This helper function walks the current policy table and r= eturns a
> > +pointer
> > +  to the best match, if a= ny are found. Leverages EvaluatePolicyMatch()
> > +to
> >= +  determine "best".
> > +
> > +  @p= aram[in]  PolicyTable      Pointer to current= policy table.
> > +  @param[in]  PolicyTableSize  = Size of current policy table.
> > +  @param[in]  Variabl= eName     Same as EFI_SET_VARIABLE.
> > + = ; @param[in]  VendorGuid       Same as E= FI_SET_VARIABLE.
> > +  @param[out] ReturnPriority  = ; [Optional] If pointer is provided,
return
> the
> > +&n= bsp;            = ;            &n= bsp;     priority of the match. Same as
> Evaluat= ePolicyMatch().
> > +       &nb= sp;            =            Only valid if = a match is returned.
> > +
> > +  @retval  = ;   VARIABLE_POLICY_ENTRY*    Best match that was<= br>> found.
> > +  @retval     NULL&nb= sp;            =          No match was found.
>= ; > +
> > +**/
> > +STATIC
> > +VARIABLE_POLI= CY_ENTRY*
> > +GetBestPolicyMatch (
> > +  IN UINT8&= nbsp;          *PolicyTable,> > +  IN UINT32       &nbs= p;  PolicyTableSize,
> > +  IN CONST CHAR16  &= nbsp; *VariableName,
> > +  IN CONST EFI_GUID  *VendorGu= id,
> > +  OUT UINT8       = ;   *ReturnPriority  OPTIONAL
> > +  )
>= > +{
> > +  VARIABLE_POLICY_ENTRY  *BestResult;
&= gt; > +  VARIABLE_POLICY_ENTRY  *CurrentEntry;
> > +&= nbsp; UINT8          &nbs= p;       MatchPriority;
> > +  = UINT8           &nbs= p;      CurrentPriority;
> > +
> &g= t; +  BestResult =3D NULL;
> > +  MatchPriority =3D MATC= H_PRIORITY_EXACT;
> > +
> > +  //
> > +&nbs= p; // Walk all entries in the table, looking for matches.
> > +&nb= sp; //
> > +  CurrentEntry =3D (VARIABLE_POLICY_ENTRY*)Policy= Table;
> > +  while ((UINTN)CurrentEntry < (UINTN)((UINT8*= )PolicyTable +
> > PolicyTableSize)) {
> > +  &= nbsp; //
> > +    // Check for a match.
> >= ; +    //
> > +    if (EvaluatePolic= yMatch (CurrentEntry, VariableName, VendorGuid,
> > &CurrentPr= iority)) {
> > +      //
> > +&n= bsp;     // If match is better, take it.
> > +=       //
> > +    &nb= sp; if (BestResult =3D=3D NULL || CurrentPriority < MatchPriority) {
= > > +        BestResult =3D Curren= tEntry;
> > +        MatchPrior= ity =3D CurrentPriority;
> > +      }
= > > +
> > +      //
> > +&= nbsp;     // If you've hit the highest-priority match, = can exit now.
> > +      //
> > = +      if (MatchPriority =3D=3D 0) {
> > = +        break;
> > + &nbs= p;    }
> > +    }
> > +> > +    //
> > +    // If we= 're still in the loop, move to the next entry.
> > +  &n= bsp; //
> > +    CurrentEntry =3D GET_NEXT_POLICY (= CurrentEntry);  }
> > +
> > +  //
> > = +  // If a return priority was requested, return it.
> > +&nb= sp; //
> > +  if (ReturnPriority !=3D NULL) {
> > +&= nbsp;   *ReturnPriority =3D MatchPriority;
> > +  }=
> > +
> > +  return BestResult;
> > +}
= > > +
> > +/**
> > +  This helper function wil= l dump and walk the current policy tables to
> > +determine
>= ; > +  whether a matching policy already exists that satisfies the = lock
request.
> > +
> > +  @param[in] VariableNam= e  A pointer to the variable name that is
> being
> > s= earched.
> > +  @param[in] VendorGuid    A poi= nter to the vendor GUID that is being
> > searched.
> > +=
> > +  @retval  TRUE   We can safely assume t= his variable is locked.
> > +  @retval  FALSE  An e= rror has occurred or we cannot prove that the
> variable
> >= is
> > +         &nb= sp;        locked.
> > +
>= ; > +**/
> > +STATIC
> > +BOOLEAN
> > +IsVari= ableAlreadyLocked (
> > +  IN CHAR16    *Varia= bleName,
> > +  IN EFI_GUID  *VendorGuid
> > +&= nbsp; )
> > +{
> > +  EFI_STATUS   &n= bsp;         Status;
> > +=   UINT8          &nb= sp;       *PolicyTable;
> > +  = UINT32           &nb= sp;     PolicyTableSize;
> > +  BOOLEAN&n= bsp;            = ;   Result;
> > +  VARIABLE_POLICY_ENTRY  *Mat= chPolicy;
> > +  UINT8      &nb= sp;           MatchPriori= ty;
> > +
> > +  Result =3D TRUE;
> > +
= > > +  //
> > +  // First, we need to dump the exi= sting policy table.
> > +  //
> > +  PolicyTabl= eSize =3D 0;
> > +  PolicyTable =3D NULL;
> > + = ; Status =3D DumpVariablePolicy (PolicyTable, &PolicyTableSize);  = if
> > + (Status !=3D EFI_BUFFER_TOO_SMALL) {
> > + =    DEBUG ((DEBUG_ERROR, "%a - Failed to determine policy tab= le
> > size! %r\n", __FUNCTION__, Status));
> > +&nb= sp;   return FALSE;
> > +  }
> > +  P= olicyTable =3D AllocateZeroPool (PolicyTableSize);  if (PolicyTable = =3D=3D
> > + NULL) {
> > +    DEBUG ((DEB= UG_ERROR, "%a - Failed to allocated space for policy
> table!> > 0x%X\n", __FUNCTION__, PolicyTableSize));
> > +&nb= sp;   return FALSE;
> > +  }
> > +  S= tatus =3D DumpVariablePolicy (PolicyTable, &PolicyTableSize);  if<= br>> > + (EFI_ERROR (Status)) {
> > +    DEBU= G ((DEBUG_ERROR, "%a - Failed to dump policy table! %r\n",
>= ; > __FUNCTION__, Status));
> > +    Result =3D = FALSE;
> > +    goto Exit;
> > +  }> > +
> > +  //
> > +  // Now we need t= o walk the table looking for a match.
> > +  //
> > = +  MatchPolicy =3D GetBestPolicyMatch (
> > +  &nbs= p;            &= nbsp;  PolicyTable,
> > +      =             PolicyTa= bleSize,
> > +        &nbs= p;         VariableName,
> &g= t; +            = ;      VendorGuid,
> > +   = ;            &n= bsp;  &MatchPriority
> > +     &= nbsp;            );<= br>> > +  if (MatchPolicy !=3D NULL && MatchPriority != =3D MATCH_PRIORITY_EXACT)
> {
> > +    DEBUG= ((DEBUG_ERROR, "%a - We would not have expected a
> non-exact> > match! %d\n", __FUNCTION__, MatchPriority));
> > = +    Result =3D FALSE;
> > +    goto= Exit;
> > +  }
> > +
> > +  //
>= ; > +  // Now we can check to see whether this variable is currentl= y locked.
> > +  //
> > +  if (MatchPolicy->= LockPolicyType !=3D
> VARIABLE_POLICY_TYPE_LOCK_NOW) {
> > +=     DEBUG ((DEBUG_INFO, "%a - Policy may not lock varia= ble! %d\n",
> > __FUNCTION__, MatchPolicy->LockPolicyType)= );
> > +    Result =3D FALSE;
> > + &= nbsp;  goto Exit;
> > +  }
> > +
> > += Exit:
> > +  if (PolicyTable !=3D NULL) {
> > + = ;   FreePool (PolicyTable);
> > +  }
> > +=
> > +  return Result;
> > +}
> >
> &= gt;  /**
> >    DEPRECATED. THIS IS ONLY HERE = AS A CONVENIENCE WHILE
> PORTING.
> > -  Mark a variabl= e that will become read-only after leaving the DXE
phase
> of
&= gt; > execution.
> > -  Write request coming from SMM envi= ronment through
> > EFI_SMM_VARIABLE_PROTOCOL is allowed.
> = > +  Mark a variable that will become read-only after leaving the D= XE
> > + phase of  execution. Write request coming from SMM e= nvironment
> > through
> > + EFI_SMM_VARIABLE_PROTOCOL is= allowed.
> >
> >    @param[in] This =          The VARIABLE_LOCK_PROTOCOL=
> instance.
> > -  @param[in] VariableName  A poi= nter to the variable name that will be
> > made read-only subseque= ntly.
> > -  @param[in] VendorGuid    A pointe= r to the vendor GUID that will be
> made
> > read-only subse= quently.
> > +  @param[in] VariableName  A pointer to th= e variable name that will be
> > made
> > +  &n= bsp;            = ;            read-on= ly subsequently.
> > +  @param[in] VendorGuid  &nbs= p; A pointer to the vendor GUID that will be
> made
> > +&nb= sp;            =             &nb= sp; read-only subsequently.
> >
> > -  @retval EFI_S= UCCESS           The vari= able specified by the
> VariableName and
> > the VendorGuid = was marked
> > -        &n= bsp;            = ;           as pending to= be read-only.
> > +  @retval EFI_SUCCESS   &n= bsp;       The variable specified by the
&= gt; VariableName and
> > +      &nbs= p;            &= nbsp;            the= VendorGuid was marked as
> pending to be
> > +  &= nbsp;           &nbs= p;            &= nbsp;    read-only.
> >    @retval E= FI_INVALID_PARAMETER VariableName or VendorGuid is
> NULL.
> &g= t;            &= nbsp;           &nbs= p;         Or VariableName is an em= pty
> string.
> > -  @retval EFI_ACCESS_DENIED
> = EFI_END_OF_DXE_EVENT_GROUP_GUID
> > or EFI_EVENT_GROUP_READY_TO_BO= OT has
> > -         =             &nb= sp;          already been sign= aled.
> > -  @retval EFI_OUT_OF_RESOURCES  There is not = enough resource to
> hold
> > the lock request.
> >= +  @retval EFI_ACCESS_DENIED
> EFI_END_OF_DXE_EVENT_GROUP_GUID<= br>> > or
> > +
> EFI_EVENT_GROUP_READY_TO_BOOT has al= ready been
> > +        &n= bsp;            = ;           signaled.
= > > +  @retval EFI_OUT_OF_RESOURCES  There is not enough re= source to
> hold
> > the lock
> > +  &nbs= p;            &= nbsp;           &nbs= p;    request.
> >  **/
> >  EFI= _STATUS
> >  EFIAPI
> >  VariableLockRequestToL= ock (
> > -  IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This,
= > > -  IN       CHAR16  =             &nb= sp;        *VariableName,
> > -=   IN       EFI_GUID   &nb= sp;            =      *VendorGuid
> > +  IN CONST EDKII_VA= RIABLE_LOCK_PROTOCOL  *This,
> > +  IN CHAR16  = ;            &n= bsp;            = ;   *VariableName,
> > +  IN EFI_GUID  &n= bsp;            = ;             *= VendorGuid
> >    )
> >  {
> &g= t; -  EFI_STATUS         =      Status;
> > -  VARIABLE_POLICY_ENTRY=    *NewPolicy;
> > +  EFI_STATUS   &= nbsp;         Status;
> > = +  VARIABLE_POLICY_ENTRY  *NewPolicy;
> > +
> >= +  DEBUG ((DEBUG_ERROR, "!!! DEPRECATED INTERFACE !!! %a() will = go
> away
> > + soon!\n", __FUNCTION__));  DEBUG (= (DEBUG_ERROR, "!!! DEPRECATED
> > + INTERFACE !!! Please move= to use Variable Policy!\n"));  DEBUG
> > + ((DEBUG_ERRO= R, "!!! DEPRECATED INTERFACE !!! Variable: %g %s\n",
> >= + VendorGuid, VariableName));
> >
> >    = NewPolicy =3D NULL;
> > -  Status =3D CreateBasicVariablePoli= cy( VendorGuid,
> > -       &nb= sp;            =             &nb= sp;     VariableName,
> > -
> VARIABLE_P= OLICY_NO_MIN_SIZE,
> > -
> VARIABLE_POLICY_NO_MAX_SIZE,
&= gt; > -
> VARIABLE_POLICY_NO_MUST_ATTR,
> > -
> VAR= IABLE_POLICY_NO_CANT_ATTR,
> > -
> VARIABLE_POLICY_TYPE_LOCK= _NOW,
> > -         &= nbsp;           &nbs= p;            &= nbsp;   &NewPolicy );
> > +  Status =3D CreateB= asicVariablePolicy(
> > +       = ;      VendorGuid,
> > +   = ;          VariableName,
&g= t; > +           =   VARIABLE_POLICY_NO_MIN_SIZE,
> > +    &= nbsp;        VARIABLE_POLICY_NO_MAX_SIZE= ,
> > +          = ;   VARIABLE_POLICY_NO_MUST_ATTR,
> > +   = ;          VARIABLE_POLICY_NO_= CANT_ATTR,
> > +        &n= bsp;    VARIABLE_POLICY_TYPE_LOCK_NOW,
> > + &= nbsp;           &NewP= olicy
> > +         &= nbsp;   );
> >    if (!EFI_ERROR( Status = )) {
> > -    Status =3D RegisterVariablePolicy( Ne= wPolicy );
> > +    Status =3D RegisterVariablePoli= cy (NewPolicy);
> > +
> > +    //
> = > +    // If the error returned is EFI_ALREADY_STARTED, w= e need to check
> the
> > +    // current dat= abase for the variable and see whether it's locked.
If it's
> >= +    // locked, we're still fine, but also generate a DEBUG= _ERROR
> message so
> > the
> > +   = // duplicate lock can be removed.
> > +    //
&= gt; > +    if (Status =3D=3D EFI_ALREADY_STARTED) {
&g= t; > +      if (IsVariableAlreadyLocked (Variab= leName, VendorGuid)) {
> > +      &n= bsp; DEBUG ((DEBUG_ERROR, "  Variable: %g %s is already
> l= ocked!\n",
> > VendorGuid, VariableName));
> > +&nbs= p;       Status =3D EFI_SUCCESS;
> >= +      }
> > +    }
&g= t; >    }
> > -  if (EFI_ERROR( Status )) {=
> > +  if (EFI_ERROR (Status)) {
> >  &nb= sp;   DEBUG(( DEBUG_ERROR, "%a - Failed to lock variable %s!= %r\n",
> > __FUNCTION__, VariableName, Status ));
> &g= t; -    ASSERT_EFI_ERROR( Status );
> >  =   }
> >    if (NewPolicy !=3D NULL) {
> = >      FreePool( NewPolicy );
> > --> > 2.29.2.windows.2
> >
> >
> >
>= >
> >

------=_NextPart_000_0089_01D6CFA0.58855B60--