From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by mx.groups.io with SMTP id smtpd.web11.1152.1570571607719413829 for ; Tue, 08 Oct 2019 14:53:27 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=CpHkBoTJ; spf=pass (domain: intel.com, ip: 192.55.52.151, mailfrom: michael.a.kubacki@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Oct 2019 14:53:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,272,1566889200"; d="scan'208";a="394816331" Received: from orsmsx106.amr.corp.intel.com ([10.22.225.133]) by fmsmga006.fm.intel.com with ESMTP; 08 Oct 2019 14:53:26 -0700 Received: from orsmsx157.amr.corp.intel.com (10.22.240.23) by ORSMSX106.amr.corp.intel.com (10.22.225.133) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 8 Oct 2019 14:53:24 -0700 Received: from ORSEDG001.ED.cps.intel.com (10.7.248.4) by ORSMSX157.amr.corp.intel.com (10.22.240.23) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 8 Oct 2019 14:53:24 -0700 Received: from NAM01-SN1-obe.outbound.protection.outlook.com (104.47.32.59) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 8 Oct 2019 14:53:24 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IKID9IDhed0BdakF81a+8ED+ZYdsX22uoyxLL6AIpB0hVJZkXVd3KYddSck0rdxpYUl60p7dab72nPrEI8MgpS38znWFAJRfclbLbtbwZreJp4FEyF0MsWtGUQWILpV5QS9OKSplrp2TE1WkSUGkrtdKGBXDddvUhAjit2bKsMR7i34WTpgvXHKknMHzBOgevQgEsXu5SWt+RI9OoLPhxbMYRSCGZDC/mhbLFEGx05188xJ0AZgS7bpWvEaCEPGwURbq6kNpS1N5uSizjqfAvU/dHiPM1RYJrudEvqzkgtzE9cnTGfUz7sJCz7gXj6AtWKQXg5Ekjw9u5bBW5L+VIA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=W6CKFXYIBbr2xdycgvPzrHEVgHB6ry44iDuV7hwFaSo=; b=DcFjns0BRGEBpQrT2p44KcswcOX7K01Xba4TAfgtpp7zryWaEzCABgu//XLyyZ4/vRxeEECnPr9f7YUJyy2n3+RbkpR+oE/1vjgsvCCvFv6O/ahZpW1QF29iKRN93pKdc6t9nWyFMvoFiRN+BMZ47f/OqxUYvBQnzMvwheD9+D0Bqt4cNLfEfckFdYgq770m+aWVhSoyzpRvWAmoTiX/4KHBm1klhMWP0yzhz3HprHda4QrUacns23cPBGCFgvoaLjDVJzN4Y943g/hVZp0SkBJo2OTC0td1SSUAG1AU9YY2cwhD7P+4irHS7kw0tPUsjtBaEk3IbgBMf++tntSXVg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=W6CKFXYIBbr2xdycgvPzrHEVgHB6ry44iDuV7hwFaSo=; b=CpHkBoTJwaq8S2QZ4RcMQ8/rjssviPyCB42LL3aT1GtS3chWOdZR3hYVd3wRFdZpAoe5p/2xJQe9F+a451gAlzzZ4y+wDdPlyDtbTHjZsIsdnDVkHC4TqYUCJVOaokW07pnBGK4x+yjOFxTjX9yco1fJiBjReYqnTbBCwkkDtHY= Received: from DM6PR11MB3834.namprd11.prod.outlook.com (20.179.17.87) by DM6PR11MB4299.namprd11.prod.outlook.com (52.132.250.161) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2327.24; Tue, 8 Oct 2019 21:53:21 +0000 Received: from DM6PR11MB3834.namprd11.prod.outlook.com ([fe80::59cc:8a30:6b9e:584e]) by DM6PR11MB3834.namprd11.prod.outlook.com ([fe80::59cc:8a30:6b9e:584e%3]) with mapi id 15.20.2327.025; Tue, 8 Oct 2019 21:53:21 +0000 From: "Kubacki, Michael A" To: "Wu, Hao A" , "devel@edk2.groups.io" CC: "Bi, Dandan" , Ard Biesheuvel , "Dong, Eric" , Laszlo Ersek , "Gao, Liming" , "Kinney, Michael D" , "Ni, Ray" , "Wang, Jian J" , "Yao, Jiewen" Subject: Re: [PATCH V2 1/9] MdeModulePkg/Variable: Consolidate common parsing functions Thread-Topic: [PATCH V2 1/9] MdeModulePkg/Variable: Consolidate common parsing functions Thread-Index: AQHVdZ61inQfPKoAP0KlFZJJbtwGd6dCIc0AgAcQSLCABtI0MIABVcZA Date: Tue, 8 Oct 2019 21:53:21 +0000 Message-ID: References: <20190928014717.31372-1-michael.a.kubacki@intel.com> <20190928014717.31372-2-michael.a.kubacki@intel.com> In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows x-ctpclassification: CTP_NT x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNDkxZDFlNjAtZTBiYy00MmUzLTkyZjItZjgxYzJiYzY3MDY1IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoicElHNzlcL2hCMHFSTWZpbnpzWXcxZmFNM1l5WGNRSWVteXAxQ2RLTHQzVHBtazFKdjBTRjV3VFJManNMSTd0XC9JIn0= dlp-reaction: no-action dlp-version: 11.2.0.6 authentication-results: spf=none (sender IP is ) smtp.mailfrom=michael.a.kubacki@intel.com; x-originating-ip: [134.134.136.217] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 77fe9fca-ba0a-4b9c-d7f9-08d74c39effe x-ms-traffictypediagnostic: DM6PR11MB4299: x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:10000; x-forefront-prvs: 01842C458A x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(136003)(39860400002)(366004)(346002)(396003)(376002)(189003)(199004)(13464003)(51914003)(45074003)(229853002)(52536014)(53546011)(8936002)(316002)(6506007)(55016002)(7736002)(33656002)(186003)(305945005)(446003)(81156014)(81166006)(26005)(6116002)(3846002)(25786009)(9686003)(102836004)(71200400001)(71190400001)(476003)(66066001)(86362001)(11346002)(8676002)(110136005)(486006)(76176011)(6246003)(4326008)(6436002)(14454004)(76116006)(54906003)(107886003)(30864003)(7696005)(66476007)(14444005)(256004)(99286004)(66446008)(64756008)(74316002)(478600001)(66556008)(2501003)(66946007)(5660300002)(2906002)(559001)(579004)(569006);DIR:OUT;SFP:1102;SCL:1;SRVR:DM6PR11MB4299;H:DM6PR11MB3834.namprd11.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: sQELi/j3mK8mgZSvcmTl+wlebtstoh6xn3y+wOHKAaCWpc9uFbMjGSB3rrq4GZ6MYgOrvwc0lsJmbNLRqxsS6IwxgO3m3yWkn0nMYR37MdlG/QJF/e2BpnkyGgpSqoMLFyWJFnL3c4bhjU9kNCbK5N279fCIxWgamfYrkINMtGRA0FbVE7cn3z4X/FjuYosCgWA4Y+3VgAQYG0SG6wgDYtxn9oC84xnDD0jlTwehhAdi/654eEDTZsZC90IKyQ2ik5sJEm0Vg6cO6z1ftsQ5arQ5JMlM7Sv0K4bvMAmpAkL1IyA0QkBanAo44+tzL0ka/skTyEC9n8bOwm4XfWkFMzkPQ4WOER0qxtN1q/adJfn9RP8WHNhnojvfqi37/Xma6nFCHuXHLm89KZGbzQFXC0zt/cukaV9tfKTB5RGL4Oo= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: 77fe9fca-ba0a-4b9c-d7f9-08d74c39effe X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Oct 2019 21:53:21.7238 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: fmnNLnW4DrL4g82z9rbZpf7g4oKiNK8zCNily5uXg0kLiCPVKVXQme8Yjk0dr7UeyArXj4NKp4STJDIpuqc4VSSZWkCNdS1Ci5EXGbruusg= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR11MB4299 Return-Path: michael.a.kubacki@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable The rationale for moving the generic parsing functions out would be better = to capture in the commit message. That will be added to V3. Thanks, Michael > -----Original Message----- > From: Wu, Hao A > Sent: Monday, October 7, 2019 7:12 PM > To: Kubacki, Michael A ; > devel@edk2.groups.io > Cc: Bi, Dandan ; Ard Biesheuvel > ; Dong, Eric ; Laszlo Ers= ek > ; Gao, Liming ; Kinney, Michael > D ; Ni, Ray ; Wang, Jian J > ; Yao, Jiewen > Subject: RE: [PATCH V2 1/9] MdeModulePkg/Variable: Consolidate common > parsing functions >=20 > > -----Original Message----- > > From: Kubacki, Michael A > > Sent: Friday, October 04, 2019 1:36 AM > > To: Wu, Hao A; devel@edk2.groups.io > > Cc: Bi, Dandan; Ard Biesheuvel; Dong, Eric; Laszlo Ersek; Gao, Liming; > Kinney, > > Michael D; Ni, Ray; Wang, Jian J; Yao, Jiewen > > Subject: RE: [PATCH V2 1/9] MdeModulePkg/Variable: Consolidate > common > > parsing functions > > > > The main reason is cohesiveness in the VariableParsing.c file. These ar= e > > functions that > > are commonly needed for general variable data structure parsing > operations. > > Most of > > them just read a member or two in a VARIABLE_STORE_HEADER or > > VARIABLE_HEADER > > data structure, perform a simple calculation if needed, and return som= e > > value. More > > complex functions such as FindVariableEx (), do this in iteration acros= s the > > variable store. > > If a function is needed that performs these tasks, it is easier to have= them > > grouped into a > > cohesive file than search which one is in Variable.c and VariableParsin= g.c on > a > > case-by-case > > basis. UpdateVariableInfo () is the exception here, I can move this to = a > > separate file > > if you prefer. >=20 >=20 > I am fine to leave this function under VariableParsing.c. >=20 >=20 > > > > Also, Variable.c is, in my opinion, far too large. It is on trend to on= ly grow > > larger: > > * Today: ~4,600 LOC > > * ~2 years ago: ~4,200 LOC > > * ~4 years ago: ~4,100 LOC > > * ~5 years ago: ~3,440 LOC > > * ~8 years ago: ~2,600 LOC > > > > I think moving out generic parsing services such as these better groups > > related > > functionality in the short-term but also aids future refactoring effort= s in the > > file. >=20 >=20 > Thanks for the clarification. >=20 > I suggest to update the commit message and add the above detailed criteri= a > for > those functions that got moved to the new file. >=20 > Best Regards, > Hao Wu >=20 >=20 > > > > Thanks, > > Michael > > > > > -----Original Message----- > > > From: Wu, Hao A > > > Sent: Thursday, October 3, 2019 1:03 AM > > > To: Kubacki, Michael A ; > > > devel@edk2.groups.io > > > Cc: Bi, Dandan ; Ard Biesheuvel > > > ; Dong, Eric ; Laszlo > > Ersek > > > ; Gao, Liming ; Kinney, > > Michael > > > D ; Ni, Ray ; Wang, Jia= n > J > > > ; Yao, Jiewen > > > Subject: RE: [PATCH V2 1/9] MdeModulePkg/Variable: Consolidate > > common > > > parsing functions > > > > > > A couple of inline comments below: > > > > > > > > > > -----Original Message----- > > > > From: Kubacki, Michael A > > > > Sent: Saturday, September 28, 2019 9:47 AM > > > > To: devel@edk2.groups.io > > > > Cc: Bi, Dandan; Ard Biesheuvel; Dong, Eric; Laszlo Ersek; Gao, Limi= ng; > > > Kinney, > > > > Michael D; Ni, Ray; Wang, Jian J; Wu, Hao A; Yao, Jiewen > > > > Subject: [PATCH V2 1/9] MdeModulePkg/Variable: Consolidate > common > > > > parsing functions > > > > > > > > This change moves the following functions into a dedicated file > > > > so they may be used in other variable files as needed. Furthermore, > > > > it reduces the overall size of the common Variable.c file. > > > > > > > > * DataSizeOfVariable () > > > > * FindVariableEx () > > > > * GetEndPointer () > > > > * GetNextVariablePtr () > > > > * GetStartPointer () > > > > * GetVariableDataOffset () > > > > * GetVariableDataPtr () > > > > * GetVariableHeaderSize () > > > > * GetVariableNamePtr () > > > > * GetVariableStoreStatus () > > > > * GetVendorGuidPtr () > > > > * IsValidVariableHeader () > > > > * NameSizeOfVariable () > > > > * SetDataSizeOfVariable () > > > > * SetNameSizeOfVariable () > > > > * UpdateVariableInfo () > > > > * VariableCompareTimeStampInternal () > > > > * VariableServiceGetNextVariableInternal () > > > > > > > > > May I know what are the criteria for the above functions being moved = to > a > > > separate file? > > > > > > At first, I think all of them will be consumed by the new codes that > > > implement > > > the runtime cache. But I found that, for functions like > > > GetVariableDataOffset(), > > > GetVariableStoreStatus() and etc., their usages are still remained wi= thin > file > > > Variable.c (seems not related with the runtime cache). > > > > > > > > > > > > > > Cc: Dandan Bi > > > > Cc: Ard Biesheuvel > > > > Cc: Eric Dong > > > > Cc: Laszlo Ersek > > > > Cc: Liming Gao > > > > Cc: Michael D Kinney > > > > Cc: Ray Ni > > > > Cc: Jian J Wang > > > > Cc: Hao A Wu > > > > Cc: Jiewen Yao > > > > Signed-off-by: Michael Kubacki > > > > --- > > > > > > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > > > > | 2 + > > > > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > | > > > 2 > > > > + > > > > > > > > > > > > > > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf > > > > | 7 + > > > > MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h = | > 119 > > - > > > --- > > > > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h > | > > > 306 > > > > ++++++++ > > > > MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c = | > 726 > > > +-- > > > > ---------------- > > > > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c = | > > 3 > > > +- > > > > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c > | > > > 731 > > > > ++++++++++++++++++++ > > > > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > | > > 1 > > > + > > > > 9 files changed, 1052 insertions(+), 845 deletions(-) > > > > > > > > > For the below change in VariableStandaloneMm.inf: > > > > > > [Guids] > > > ... > > > ## SOMETIMES_CONSUMES ## Variable:L"db" > > > ## SOMETIMES_CONSUMES ## Variable:L"dbx" > > > ## SOMETIMES_CONSUMES ## Variable:L"dbt" > > > gEfiImageSecurityDatabaseGuid > > > ... > > > > > > I think the above GUID is not used by the module specified by the abo= ve > > INF. > > > Could you double confirm on this? > > > > > > Best Regards, > > > Hao Wu > > > > > > > > > > > > > > diff --git > > > > > > > > > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > > > > > > > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > > > > index 641376c9c5..c35e5fe787 100644 > > > > --- > > > > > > > > > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > > > > +++ > > > > > > > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > > > > @@ -36,6 +36,8 @@ > > > > Variable.c > > > > VariableDxe.c > > > > Variable.h > > > > + VariableParsing.c > > > > + VariableParsing.h > > > > PrivilegePolymorphic.h > > > > Measurement.c > > > > TcgMorLockDxe.c > > > > diff --git > > > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > > > > index 0a160d269d..626738b9c7 100644 > > > > --- > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > > > > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > > > > @@ -45,6 +45,8 @@ > > > > Variable.c > > > > VariableTraditionalMm.c > > > > VariableSmm.c > > > > + VariableParsing.c > > > > + VariableParsing.h > > > > VarCheck.c > > > > Variable.h > > > > PrivilegePolymorphic.h > > > > diff --git > > > > > > > > > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i > > > > nf > > > > > > > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm. > > > > inf > > > > index 21bc81163b..1ba8f9ebfb 100644 > > > > --- > > > > > > > > > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i > > > > nf > > > > +++ > > > > > > > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm. > > > > inf > > > > @@ -45,6 +45,8 @@ > > > > Variable.c > > > > VariableSmm.c > > > > VariableStandaloneMm.c > > > > + VariableParsing.c > > > > + VariableParsing.h > > > > VarCheck.c > > > > Variable.h > > > > PrivilegePolymorphic.h > > > > @@ -99,6 +101,11 @@ > > > > ## SOMETIMES_PRODUCES ## Variable:L"Lang" > > > > gEfiGlobalVariableGuid > > > > > > > > + ## SOMETIMES_CONSUMES ## Variable:L"db" > > > > + ## SOMETIMES_CONSUMES ## Variable:L"dbx" > > > > + ## SOMETIMES_CONSUMES ## Variable:L"dbt" > > > > + gEfiImageSecurityDatabaseGuid > > > > + > > > > gEfiMemoryOverwriteControlDataGuid ## > > SOMETIMES_CONSUMES > > > > ## Variable:L"MemoryOverwriteRequestControl" > > > > gEfiMemoryOverwriteRequestControlLockGuid ## > > > > SOMETIMES_PRODUCES ## > > > > Variable:L"MemoryOverwriteRequestControlLock" > > > > > > > > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > > > > index 9eac43759f..fb574b2e32 100644 > > > > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > > > > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > > > > @@ -179,89 +179,6 @@ FindVariable ( > > > > IN BOOLEAN IgnoreRtCheck > > > > ); > > > > > > > > -/** > > > > - > > > > - Gets the pointer to the end of the variable storage area. > > > > - > > > > - This function gets pointer to the end of the variable storage > > > > - area, according to the input variable store header. > > > > - > > > > - @param VarStoreHeader Pointer to the Variable Store Header. > > > > - > > > > - @return Pointer to the end of the variable storage area. > > > > - > > > > -**/ > > > > -VARIABLE_HEADER * > > > > -GetEndPointer ( > > > > - IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > - ); > > > > - > > > > -/** > > > > - This code gets the size of variable header. > > > > - > > > > - @return Size of variable header in bytes in type UINTN. > > > > - > > > > -**/ > > > > -UINTN > > > > -GetVariableHeaderSize ( > > > > - VOID > > > > - ); > > > > - > > > > -/** > > > > - > > > > - This code gets the pointer to the variable name. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return Pointer to Variable Name which is Unicode encoding. > > > > - > > > > -**/ > > > > -CHAR16 * > > > > -GetVariableNamePtr ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ); > > > > - > > > > -/** > > > > - This code gets the pointer to the variable guid. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return A EFI_GUID* pointer to Vendor Guid. > > > > - > > > > -**/ > > > > -EFI_GUID * > > > > -GetVendorGuidPtr ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ); > > > > - > > > > -/** > > > > - > > > > - This code gets the pointer to the variable data. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return Pointer to Variable Data. > > > > - > > > > -**/ > > > > -UINT8 * > > > > -GetVariableDataPtr ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ); > > > > - > > > > -/** > > > > - > > > > - This code gets the size of variable data. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return Size of variable in bytes. > > > > - > > > > -**/ > > > > -UINTN > > > > -DataSizeOfVariable ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ); > > > > - > > > > /** > > > > This function is to check if the remaining variable space is eno= ugh to > set > > > > all Variables from argument list successfully. The purpose of th= e check > > > > @@ -450,17 +367,6 @@ ReclaimForOS( > > > > VOID > > > > ); > > > > > > > > -/** > > > > - Get non-volatile maximum variable size. > > > > - > > > > - @return Non-volatile maximum variable size. > > > > - > > > > -**/ > > > > -UINTN > > > > -GetNonVolatileMaxVariableSize ( > > > > - VOID > > > > - ); > > > > - > > > > /** > > > > Get maximum variable size, covering both non-volatile and volati= le > > > variables. > > > > > > > > @@ -546,31 +452,6 @@ VariableServiceGetVariable ( > > > > OUT VOID *Data OPTIONAL > > > > ); > > > > > > > > -/** > > > > - This code Finds the Next available variable. > > > > - > > > > - Caution: This function may receive untrusted input. > > > > - This function may be invoked in SMM mode. This function will do > basic > > > > validation, before parse the data. > > > > - > > > > - @param[in] VariableName Pointer to variable name. > > > > - @param[in] VendorGuid Variable Vendor Guid. > > > > - @param[out] VariablePtr Pointer to variable header address. > > > > - > > > > - @retval EFI_SUCCESS The function completed successfull= y. > > > > - @retval EFI_NOT_FOUND The next variable was not found. > > > > - @retval EFI_INVALID_PARAMETER If VariableName is not an empty > > > string, > > > > while VendorGuid is NULL. > > > > - @retval EFI_INVALID_PARAMETER The input values of VariableName > > and > > > > VendorGuid are not a name and > > > > - GUID of an existing variable. > > > > - > > > > -**/ > > > > -EFI_STATUS > > > > -EFIAPI > > > > -VariableServiceGetNextVariableInternal ( > > > > - IN CHAR16 *VariableName, > > > > - IN EFI_GUID *VendorGuid, > > > > - OUT VARIABLE_HEADER **VariablePtr > > > > - ); > > > > - > > > > /** > > > > > > > > This code Finds the Next available variable. > > > > diff --git > > > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h > > > > new file mode 100644 > > > > index 0000000000..9d77c4916c > > > > --- /dev/null > > > > +++ > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h > > > > @@ -0,0 +1,306 @@ > > > > +/** @file > > > > + Functions in this module are associated with variable parsing > > operations > > > > and > > > > + are intended to be usable across variable driver source files. > > > > + > > > > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent > > > > + > > > > +**/ > > > > + > > > > +#ifndef _VARIABLE_PARSING_H_ > > > > +#define _VARIABLE_PARSING_H_ > > > > + > > > > +#include > > > > +#include "Variable.h" > > > > + > > > > +/** > > > > + > > > > + This code checks if variable header is valid or not. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + @param VariableStoreEnd Pointer to the Variable Store End. > > > > + > > > > + @retval TRUE Variable header is valid. > > > > + @retval FALSE Variable header is not valid. > > > > + > > > > +**/ > > > > +BOOLEAN > > > > +IsValidVariableHeader ( > > > > + IN VARIABLE_HEADER *Variable, > > > > + IN VARIABLE_HEADER *VariableStoreEnd > > > > + ); > > > > + > > > > +/** > > > > + > > > > + This code gets the current status of Variable Store. > > > > + > > > > + @param VarStoreHeader Pointer to the Variable Store Header. > > > > + > > > > + @retval EfiRaw Variable store status is raw. > > > > + @retval EfiValid Variable store status is valid. > > > > + @retval EfiInvalid Variable store status is invalid. > > > > + > > > > +**/ > > > > +VARIABLE_STORE_STATUS > > > > +GetVariableStoreStatus ( > > > > + IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > + ); > > > > + > > > > +/** > > > > + This code gets the size of variable header. > > > > + > > > > + @return Size of variable header in bytes in type UINTN. > > > > + > > > > +**/ > > > > +UINTN > > > > +GetVariableHeaderSize ( > > > > + VOID > > > > + ); > > > > + > > > > +/** > > > > + > > > > + This code gets the size of name of variable. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return UINTN Size of variable in bytes. > > > > + > > > > +**/ > > > > +UINTN > > > > +NameSizeOfVariable ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ); > > > > + > > > > +/** > > > > + This code sets the size of name of variable. > > > > + > > > > + @param[in] Variable Pointer to the Variable Header. > > > > + @param[in] NameSize Name size to set. > > > > + > > > > +**/ > > > > +VOID > > > > +SetNameSizeOfVariable ( > > > > + IN VARIABLE_HEADER *Variable, > > > > + IN UINTN NameSize > > > > + ); > > > > + > > > > +/** > > > > + > > > > + This code gets the size of variable data. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Size of variable in bytes. > > > > + > > > > +**/ > > > > +UINTN > > > > +DataSizeOfVariable ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ); > > > > + > > > > +/** > > > > + This code sets the size of variable data. > > > > + > > > > + @param[in] Variable Pointer to the Variable Header. > > > > + @param[in] DataSize Data size to set. > > > > + > > > > +**/ > > > > +VOID > > > > +SetDataSizeOfVariable ( > > > > + IN VARIABLE_HEADER *Variable, > > > > + IN UINTN DataSize > > > > + ); > > > > + > > > > +/** > > > > + > > > > + This code gets the pointer to the variable name. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Pointer to Variable Name which is Unicode encoding. > > > > + > > > > +**/ > > > > +CHAR16 * > > > > +GetVariableNamePtr ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ); > > > > + > > > > +/** > > > > + This code gets the pointer to the variable guid. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return A EFI_GUID* pointer to Vendor Guid. > > > > + > > > > +**/ > > > > +EFI_GUID * > > > > +GetVendorGuidPtr ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ); > > > > + > > > > +/** > > > > + > > > > + This code gets the pointer to the variable data. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Pointer to Variable Data. > > > > + > > > > +**/ > > > > +UINT8 * > > > > +GetVariableDataPtr ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ); > > > > + > > > > +/** > > > > + This code gets the variable data offset related to variable head= er. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Variable Data offset. > > > > + > > > > +**/ > > > > +UINTN > > > > +GetVariableDataOffset ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ); > > > > + > > > > +/** > > > > + > > > > + This code gets the pointer to the next variable header. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Pointer to next variable header. > > > > + > > > > +**/ > > > > +VARIABLE_HEADER * > > > > +GetNextVariablePtr ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ); > > > > + > > > > +/** > > > > + > > > > + Gets the pointer to the first variable header in given variable = store > area. > > > > + > > > > + @param VarStoreHeader Pointer to the Variable Store Header. > > > > + > > > > + @return Pointer to the first variable header. > > > > + > > > > +**/ > > > > +VARIABLE_HEADER * > > > > +GetStartPointer ( > > > > + IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > + ); > > > > + > > > > +/** > > > > + > > > > + Gets the pointer to the end of the variable storage area. > > > > + > > > > + This function gets pointer to the end of the variable storage > > > > + area, according to the input variable store header. > > > > + > > > > + @param VarStoreHeader Pointer to the Variable Store Header. > > > > + > > > > + @return Pointer to the end of the variable storage area. > > > > + > > > > +**/ > > > > +VARIABLE_HEADER * > > > > +GetEndPointer ( > > > > + IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > + ); > > > > + > > > > +/** > > > > + Compare two EFI_TIME data. > > > > + > > > > + > > > > + @param FirstTime A pointer to the first EFI_TIME data. > > > > + @param SecondTime A pointer to the second EFI_TIME data= . > > > > + > > > > + @retval TRUE The FirstTime is not later than the S= econdTime. > > > > + @retval FALSE The FirstTime is later than the Secon= dTime. > > > > + > > > > +**/ > > > > +BOOLEAN > > > > +VariableCompareTimeStampInternal ( > > > > + IN EFI_TIME *FirstTime, > > > > + IN EFI_TIME *SecondTime > > > > + ); > > > > + > > > > +/** > > > > + Find the variable in the specified variable store. > > > > + > > > > + @param[in] VariableName Name of the variable to be = found > > > > + @param[in] VendorGuid Vendor GUID to be found. > > > > + @param[in] IgnoreRtCheck Ignore > > > EFI_VARIABLE_RUNTIME_ACCESS > > > > attribute > > > > + check at runtime when searc= hing variable. > > > > + @param[in, out] PtrTrack Variable Track Pointer stru= cture that > > > > contains Variable Information. > > > > + > > > > + @retval EFI_SUCCESS Variable found successfully > > > > + @retval EFI_NOT_FOUND Variable not found > > > > +**/ > > > > +EFI_STATUS > > > > +FindVariableEx ( > > > > + IN CHAR16 *VariableName, > > > > + IN EFI_GUID *VendorGuid, > > > > + IN BOOLEAN IgnoreRtCheck, > > > > + IN OUT VARIABLE_POINTER_TRACK *PtrTrack > > > > + ); > > > > + > > > > +/** > > > > + This code Finds the Next available variable. > > > > + > > > > + Caution: This function may receive untrusted input. > > > > + This function may be invoked in SMM mode. This function will do > basic > > > > validation, before parse the data. > > > > + > > > > + @param[in] VariableName Pointer to variable name. > > > > + @param[in] VendorGuid Variable Vendor Guid. > > > > + @param[out] VariablePtr Pointer to variable header address. > > > > + > > > > + @retval EFI_SUCCESS The function completed successfull= y. > > > > + @retval EFI_NOT_FOUND The next variable was not found. > > > > + @retval EFI_INVALID_PARAMETER If VariableName is not an empty > > > string, > > > > while VendorGuid is NULL. > > > > + @retval EFI_INVALID_PARAMETER The input values of VariableName > > > and > > > > VendorGuid are not a name and > > > > + GUID of an existing variable. > > > > + > > > > +**/ > > > > +EFI_STATUS > > > > +EFIAPI > > > > +VariableServiceGetNextVariableInternal ( > > > > + IN CHAR16 *VariableName, > > > > + IN EFI_GUID *VendorGuid, > > > > + OUT VARIABLE_HEADER **VariablePtr > > > > + ); > > > > + > > > > +/** > > > > + Routine used to track statistical information about variable usa= ge. > > > > + The data is stored in the EFI system table so it can be accessed= later. > > > > + VariableInfo.efi can dump out the table. Only Boot Services vari= able > > > > + accesses are tracked by this code. The PcdVariableCollectStatist= ics > > > > + build flag controls if this feature is enabled. > > > > + > > > > + A read that hits in the cache will have Read and Cache true for > > > > + the transaction. Data is allocated by this routine, but never > > > > + freed. > > > > + > > > > + @param[in] VariableName Name of the Variable to track. > > > > + @param[in] VendorGuid Guid of the Variable to track. > > > > + @param[in] Volatile TRUE if volatile FALSE if non-volatile= . > > > > + @param[in] Read TRUE if GetVariable() was called. > > > > + @param[in] Write TRUE if SetVariable() was called. > > > > + @param[in] Delete TRUE if deleted via SetVariable(). > > > > + @param[in] Cache TRUE for a cache hit. > > > > + > > > > +**/ > > > > +VOID > > > > +UpdateVariableInfo ( > > > > + IN CHAR16 *VariableName, > > > > + IN EFI_GUID *VendorGuid, > > > > + IN BOOLEAN Volatile, > > > > + IN BOOLEAN Read, > > > > + IN BOOLEAN Write, > > > > + IN BOOLEAN Delete, > > > > + IN BOOLEAN Cache > > > > + ); > > > > + > > > > +#endif > > > > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > > > > index f32c9c2808..76536308e6 100644 > > > > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > > > > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > > > > @@ -23,6 +23,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > > > > **/ > > > > > > > > #include "Variable.h" > > > > +#include "VariableParsing.h" > > > > > > > > VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal; > > > > > > > > @@ -92,131 +93,6 @@ AUTH_VAR_LIB_CONTEXT_IN mAuthContextIn > =3D { > > > > > > > > AUTH_VAR_LIB_CONTEXT_OUT mAuthContextOut; > > > > > > > > -/** > > > > - Routine used to track statistical information about variable usa= ge. > > > > - The data is stored in the EFI system table so it can be accessed= later. > > > > - VariableInfo.efi can dump out the table. Only Boot Services vari= able > > > > - accesses are tracked by this code. The PcdVariableCollectStatist= ics > > > > - build flag controls if this feature is enabled. > > > > - > > > > - A read that hits in the cache will have Read and Cache true for > > > > - the transaction. Data is allocated by this routine, but never > > > > - freed. > > > > - > > > > - @param[in] VariableName Name of the Variable to track. > > > > - @param[in] VendorGuid Guid of the Variable to track. > > > > - @param[in] Volatile TRUE if volatile FALSE if non-volatile= . > > > > - @param[in] Read TRUE if GetVariable() was called. > > > > - @param[in] Write TRUE if SetVariable() was called. > > > > - @param[in] Delete TRUE if deleted via SetVariable(). > > > > - @param[in] Cache TRUE for a cache hit. > > > > - > > > > -**/ > > > > -VOID > > > > -UpdateVariableInfo ( > > > > - IN CHAR16 *VariableName, > > > > - IN EFI_GUID *VendorGuid, > > > > - IN BOOLEAN Volatile, > > > > - IN BOOLEAN Read, > > > > - IN BOOLEAN Write, > > > > - IN BOOLEAN Delete, > > > > - IN BOOLEAN Cache > > > > - ) > > > > -{ > > > > - VARIABLE_INFO_ENTRY *Entry; > > > > - > > > > - if (FeaturePcdGet (PcdVariableCollectStatistics)) { > > > > - > > > > - if (AtRuntime ()) { > > > > - // Don't collect statistics at runtime. > > > > - return; > > > > - } > > > > - > > > > - if (gVariableInfo =3D=3D NULL) { > > > > - // > > > > - // On the first call allocate a entry and place a pointer to= it in > > > > - // the EFI System Table. > > > > - // > > > > - gVariableInfo =3D AllocateZeroPool (sizeof (VARIABLE_INFO_EN= TRY)); > > > > - ASSERT (gVariableInfo !=3D NULL); > > > > - > > > > - CopyGuid (&gVariableInfo->VendorGuid, VendorGuid); > > > > - gVariableInfo->Name =3D AllocateZeroPool (StrSize (VariableN= ame)); > > > > - ASSERT (gVariableInfo->Name !=3D NULL); > > > > - StrCpyS (gVariableInfo->Name, > > StrSize(VariableName)/sizeof(CHAR16), > > > > VariableName); > > > > - gVariableInfo->Volatile =3D Volatile; > > > > - } > > > > - > > > > - > > > > - for (Entry =3D gVariableInfo; Entry !=3D NULL; Entry =3D Entry= ->Next) { > > > > - if (CompareGuid (VendorGuid, &Entry->VendorGuid)) { > > > > - if (StrCmp (VariableName, Entry->Name) =3D=3D 0) { > > > > - if (Read) { > > > > - Entry->ReadCount++; > > > > - } > > > > - if (Write) { > > > > - Entry->WriteCount++; > > > > - } > > > > - if (Delete) { > > > > - Entry->DeleteCount++; > > > > - } > > > > - if (Cache) { > > > > - Entry->CacheCount++; > > > > - } > > > > - > > > > - return; > > > > - } > > > > - } > > > > - > > > > - if (Entry->Next =3D=3D NULL) { > > > > - // > > > > - // If the entry is not in the table add it. > > > > - // Next iteration of the loop will fill in the data. > > > > - // > > > > - Entry->Next =3D AllocateZeroPool (sizeof (VARIABLE_INFO_EN= TRY)); > > > > - ASSERT (Entry->Next !=3D NULL); > > > > - > > > > - CopyGuid (&Entry->Next->VendorGuid, VendorGuid); > > > > - Entry->Next->Name =3D AllocateZeroPool (StrSize (VariableN= ame)); > > > > - ASSERT (Entry->Next->Name !=3D NULL); > > > > - StrCpyS (Entry->Next->Name, > > StrSize(VariableName)/sizeof(CHAR16), > > > > VariableName); > > > > - Entry->Next->Volatile =3D Volatile; > > > > - } > > > > - > > > > - } > > > > - } > > > > -} > > > > - > > > > - > > > > -/** > > > > - > > > > - This code checks if variable header is valid or not. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - @param VariableStoreEnd Pointer to the Variable Store End. > > > > - > > > > - @retval TRUE Variable header is valid. > > > > - @retval FALSE Variable header is not valid. > > > > - > > > > -**/ > > > > -BOOLEAN > > > > -IsValidVariableHeader ( > > > > - IN VARIABLE_HEADER *Variable, > > > > - IN VARIABLE_HEADER *VariableStoreEnd > > > > - ) > > > > -{ > > > > - if ((Variable =3D=3D NULL) || (Variable >=3D VariableStoreEnd) |= | (Variable- > > > > >StartId !=3D VARIABLE_DATA)) { > > > > - // > > > > - // Variable is NULL or has reached the end of variable store, > > > > - // or the StartId is not correct. > > > > - // > > > > - return FALSE; > > > > - } > > > > - > > > > - return TRUE; > > > > -} > > > > - > > > > - > > > > /** > > > > > > > > This function writes data to the FWH at the correct LBA even if = the > LBAs > > > > @@ -376,345 +252,6 @@ UpdateVariableStore ( > > > > return EFI_SUCCESS; > > > > } > > > > > > > > - > > > > -/** > > > > - > > > > - This code gets the current status of Variable Store. > > > > - > > > > - @param VarStoreHeader Pointer to the Variable Store Header. > > > > - > > > > - @retval EfiRaw Variable store status is raw. > > > > - @retval EfiValid Variable store status is valid. > > > > - @retval EfiInvalid Variable store status is invalid. > > > > - > > > > -**/ > > > > -VARIABLE_STORE_STATUS > > > > -GetVariableStoreStatus ( > > > > - IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > - ) > > > > -{ > > > > - if ((CompareGuid (&VarStoreHeader->Signature, > > > > &gEfiAuthenticatedVariableGuid) || > > > > - CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid)= ) > > && > > > > - VarStoreHeader->Format =3D=3D VARIABLE_STORE_FORMATTED && > > > > - VarStoreHeader->State =3D=3D VARIABLE_STORE_HEALTHY > > > > - ) { > > > > - > > > > - return EfiValid; > > > > - } else if (((UINT32 *)(&VarStoreHeader->Signature))[0] =3D=3D 0x= ffffffff > && > > > > - ((UINT32 *)(&VarStoreHeader->Signature))[1] =3D=3D 0x= ffffffff && > > > > - ((UINT32 *)(&VarStoreHeader->Signature))[2] =3D=3D 0x= ffffffff && > > > > - ((UINT32 *)(&VarStoreHeader->Signature))[3] =3D=3D 0x= ffffffff && > > > > - VarStoreHeader->Size =3D=3D 0xffffffff && > > > > - VarStoreHeader->Format =3D=3D 0xff && > > > > - VarStoreHeader->State =3D=3D 0xff > > > > - ) { > > > > - > > > > - return EfiRaw; > > > > - } else { > > > > - return EfiInvalid; > > > > - } > > > > -} > > > > - > > > > -/** > > > > - This code gets the size of variable header. > > > > - > > > > - @return Size of variable header in bytes in type UINTN. > > > > - > > > > -**/ > > > > -UINTN > > > > -GetVariableHeaderSize ( > > > > - VOID > > > > - ) > > > > -{ > > > > - UINTN Value; > > > > - > > > > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > - Value =3D sizeof (AUTHENTICATED_VARIABLE_HEADER); > > > > - } else { > > > > - Value =3D sizeof (VARIABLE_HEADER); > > > > - } > > > > - > > > > - return Value; > > > > -} > > > > - > > > > -/** > > > > - > > > > - This code gets the size of name of variable. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return UINTN Size of variable in bytes. > > > > - > > > > -**/ > > > > -UINTN > > > > -NameSizeOfVariable ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ) > > > > -{ > > > > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > - > > > > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > - if (AuthVariable->State =3D=3D (UINT8) (-1) || > > > > - AuthVariable->DataSize =3D=3D (UINT32) (-1) || > > > > - AuthVariable->NameSize =3D=3D (UINT32) (-1) || > > > > - AuthVariable->Attributes =3D=3D (UINT32) (-1)) { > > > > - return 0; > > > > - } > > > > - return (UINTN) AuthVariable->NameSize; > > > > - } else { > > > > - if (Variable->State =3D=3D (UINT8) (-1) || > > > > - Variable->DataSize =3D=3D (UINT32) (-1) || > > > > - Variable->NameSize =3D=3D (UINT32) (-1) || > > > > - Variable->Attributes =3D=3D (UINT32) (-1)) { > > > > - return 0; > > > > - } > > > > - return (UINTN) Variable->NameSize; > > > > - } > > > > -} > > > > - > > > > -/** > > > > - This code sets the size of name of variable. > > > > - > > > > - @param[in] Variable Pointer to the Variable Header. > > > > - @param[in] NameSize Name size to set. > > > > - > > > > -**/ > > > > -VOID > > > > -SetNameSizeOfVariable ( > > > > - IN VARIABLE_HEADER *Variable, > > > > - IN UINTN NameSize > > > > - ) > > > > -{ > > > > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > - > > > > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > - AuthVariable->NameSize =3D (UINT32) NameSize; > > > > - } else { > > > > - Variable->NameSize =3D (UINT32) NameSize; > > > > - } > > > > -} > > > > - > > > > -/** > > > > - > > > > - This code gets the size of variable data. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return Size of variable in bytes. > > > > - > > > > -**/ > > > > -UINTN > > > > -DataSizeOfVariable ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ) > > > > -{ > > > > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > - > > > > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > - if (AuthVariable->State =3D=3D (UINT8) (-1) || > > > > - AuthVariable->DataSize =3D=3D (UINT32) (-1) || > > > > - AuthVariable->NameSize =3D=3D (UINT32) (-1) || > > > > - AuthVariable->Attributes =3D=3D (UINT32) (-1)) { > > > > - return 0; > > > > - } > > > > - return (UINTN) AuthVariable->DataSize; > > > > - } else { > > > > - if (Variable->State =3D=3D (UINT8) (-1) || > > > > - Variable->DataSize =3D=3D (UINT32) (-1) || > > > > - Variable->NameSize =3D=3D (UINT32) (-1) || > > > > - Variable->Attributes =3D=3D (UINT32) (-1)) { > > > > - return 0; > > > > - } > > > > - return (UINTN) Variable->DataSize; > > > > - } > > > > -} > > > > - > > > > -/** > > > > - This code sets the size of variable data. > > > > - > > > > - @param[in] Variable Pointer to the Variable Header. > > > > - @param[in] DataSize Data size to set. > > > > - > > > > -**/ > > > > -VOID > > > > -SetDataSizeOfVariable ( > > > > - IN VARIABLE_HEADER *Variable, > > > > - IN UINTN DataSize > > > > - ) > > > > -{ > > > > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > - > > > > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > - AuthVariable->DataSize =3D (UINT32) DataSize; > > > > - } else { > > > > - Variable->DataSize =3D (UINT32) DataSize; > > > > - } > > > > -} > > > > - > > > > -/** > > > > - > > > > - This code gets the pointer to the variable name. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return Pointer to Variable Name which is Unicode encoding. > > > > - > > > > -**/ > > > > -CHAR16 * > > > > -GetVariableNamePtr ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ) > > > > -{ > > > > - return (CHAR16 *) ((UINTN) Variable + GetVariableHeaderSize ()); > > > > -} > > > > - > > > > -/** > > > > - This code gets the pointer to the variable guid. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return A EFI_GUID* pointer to Vendor Guid. > > > > - > > > > -**/ > > > > -EFI_GUID * > > > > -GetVendorGuidPtr ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ) > > > > -{ > > > > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > - > > > > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > - return &AuthVariable->VendorGuid; > > > > - } else { > > > > - return &Variable->VendorGuid; > > > > - } > > > > -} > > > > - > > > > -/** > > > > - > > > > - This code gets the pointer to the variable data. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return Pointer to Variable Data. > > > > - > > > > -**/ > > > > -UINT8 * > > > > -GetVariableDataPtr ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ) > > > > -{ > > > > - UINTN Value; > > > > - > > > > - // > > > > - // Be careful about pad size for alignment. > > > > - // > > > > - Value =3D (UINTN) GetVariableNamePtr (Variable); > > > > - Value +=3D NameSizeOfVariable (Variable); > > > > - Value +=3D GET_PAD_SIZE (NameSizeOfVariable (Variable)); > > > > - > > > > - return (UINT8 *) Value; > > > > -} > > > > - > > > > -/** > > > > - This code gets the variable data offset related to variable head= er. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return Variable Data offset. > > > > - > > > > -**/ > > > > -UINTN > > > > -GetVariableDataOffset ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ) > > > > -{ > > > > - UINTN Value; > > > > - > > > > - // > > > > - // Be careful about pad size for alignment > > > > - // > > > > - Value =3D GetVariableHeaderSize (); > > > > - Value +=3D NameSizeOfVariable (Variable); > > > > - Value +=3D GET_PAD_SIZE (NameSizeOfVariable (Variable)); > > > > - > > > > - return Value; > > > > -} > > > > - > > > > -/** > > > > - > > > > - This code gets the pointer to the next variable header. > > > > - > > > > - @param Variable Pointer to the Variable Header. > > > > - > > > > - @return Pointer to next variable header. > > > > - > > > > -**/ > > > > -VARIABLE_HEADER * > > > > -GetNextVariablePtr ( > > > > - IN VARIABLE_HEADER *Variable > > > > - ) > > > > -{ > > > > - UINTN Value; > > > > - > > > > - Value =3D (UINTN) GetVariableDataPtr (Variable); > > > > - Value +=3D DataSizeOfVariable (Variable); > > > > - Value +=3D GET_PAD_SIZE (DataSizeOfVariable (Variable)); > > > > - > > > > - // > > > > - // Be careful about pad size for alignment. > > > > - // > > > > - return (VARIABLE_HEADER *) HEADER_ALIGN (Value); > > > > -} > > > > - > > > > -/** > > > > - > > > > - Gets the pointer to the first variable header in given variable = store > area. > > > > - > > > > - @param VarStoreHeader Pointer to the Variable Store Header. > > > > - > > > > - @return Pointer to the first variable header. > > > > - > > > > -**/ > > > > -VARIABLE_HEADER * > > > > -GetStartPointer ( > > > > - IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > - ) > > > > -{ > > > > - // > > > > - // The start of variable store. > > > > - // > > > > - return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1); > > > > -} > > > > - > > > > -/** > > > > - > > > > - Gets the pointer to the end of the variable storage area. > > > > - > > > > - This function gets pointer to the end of the variable storage > > > > - area, according to the input variable store header. > > > > - > > > > - @param VarStoreHeader Pointer to the Variable Store Header. > > > > - > > > > - @return Pointer to the end of the variable storage area. > > > > - > > > > -**/ > > > > -VARIABLE_HEADER * > > > > -GetEndPointer ( > > > > - IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > - ) > > > > -{ > > > > - // > > > > - // The end of variable store > > > > - // > > > > - return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) > > VarStoreHeader > > > + > > > > VarStoreHeader->Size); > > > > -} > > > > - > > > > /** > > > > Record variable error flag. > > > > > > > > @@ -1228,75 +765,6 @@ Done: > > > > return Status; > > > > } > > > > > > > > -/** > > > > - Find the variable in the specified variable store. > > > > - > > > > - @param[in] VariableName Name of the variable to be = found > > > > - @param[in] VendorGuid Vendor GUID to be found. > > > > - @param[in] IgnoreRtCheck Ignore > > > EFI_VARIABLE_RUNTIME_ACCESS > > > > attribute > > > > - check at runtime when searc= hing variable. > > > > - @param[in, out] PtrTrack Variable Track Pointer stru= cture that > > > > contains Variable Information. > > > > - > > > > - @retval EFI_SUCCESS Variable found successfully > > > > - @retval EFI_NOT_FOUND Variable not found > > > > -**/ > > > > -EFI_STATUS > > > > -FindVariableEx ( > > > > - IN CHAR16 *VariableName, > > > > - IN EFI_GUID *VendorGuid, > > > > - IN BOOLEAN IgnoreRtCheck, > > > > - IN OUT VARIABLE_POINTER_TRACK *PtrTrack > > > > - ) > > > > -{ > > > > - VARIABLE_HEADER *InDeletedVariable; > > > > - VOID *Point; > > > > - > > > > - PtrTrack->InDeletedTransitionPtr =3D NULL; > > > > - > > > > - // > > > > - // Find the variable by walk through HOB, volatile and non-volat= ile > > > variable > > > > store. > > > > - // > > > > - InDeletedVariable =3D NULL; > > > > - > > > > - for ( PtrTrack->CurrPtr =3D PtrTrack->StartPtr > > > > - ; IsValidVariableHeader (PtrTrack->CurrPtr, PtrTrack->EndPtr= ) > > > > - ; PtrTrack->CurrPtr =3D GetNextVariablePtr (PtrTrack->CurrPt= r) > > > > - ) { > > > > - if (PtrTrack->CurrPtr->State =3D=3D VAR_ADDED || > > > > - PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSITION= & > > > > VAR_ADDED) > > > > - ) { > > > > - if (IgnoreRtCheck || !AtRuntime () || ((PtrTrack->CurrPtr- > >Attributes > > & > > > > EFI_VARIABLE_RUNTIME_ACCESS) !=3D 0)) { > > > > - if (VariableName[0] =3D=3D 0) { > > > > - if (PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRAN= SITION & > > > > VAR_ADDED)) { > > > > - InDeletedVariable =3D PtrTrack->CurrPtr; > > > > - } else { > > > > - PtrTrack->InDeletedTransitionPtr =3D InDeletedVariable= ; > > > > - return EFI_SUCCESS; > > > > - } > > > > - } else { > > > > - if (CompareGuid (VendorGuid, GetVendorGuidPtr (PtrTrack- > > > >CurrPtr))) > > > > { > > > > - Point =3D (VOID *) GetVariableNamePtr (PtrTrack->CurrP= tr); > > > > - > > > > - ASSERT (NameSizeOfVariable (PtrTrack->CurrPtr) !=3D 0)= ; > > > > - if (CompareMem (VariableName, Point, NameSizeOfVariabl= e > > > > (PtrTrack->CurrPtr)) =3D=3D 0) { > > > > - if (PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_= TRANSITION > & > > > > VAR_ADDED)) { > > > > - InDeletedVariable =3D PtrTrack->CurrPtr; > > > > - } else { > > > > - PtrTrack->InDeletedTransitionPtr =3D InDeletedVari= able; > > > > - return EFI_SUCCESS; > > > > - } > > > > - } > > > > - } > > > > - } > > > > - } > > > > - } > > > > - } > > > > - > > > > - PtrTrack->CurrPtr =3D InDeletedVariable; > > > > - return (PtrTrack->CurrPtr =3D=3D NULL) ? EFI_NOT_FOUND : > EFI_SUCCESS; > > > > -} > > > > - > > > > - > > > > /** > > > > Finds variable in storage blocks of volatile and non-volatile st= orage > areas. > > > > > > > > @@ -2078,38 +1546,6 @@ AutoUpdateLangVariable ( > > > > } > > > > } > > > > > > > > -/** > > > > - Compare two EFI_TIME data. > > > > - > > > > - > > > > - @param FirstTime A pointer to the first EFI_TIME data. > > > > - @param SecondTime A pointer to the second EFI_TIME data= . > > > > - > > > > - @retval TRUE The FirstTime is not later than the S= econdTime. > > > > - @retval FALSE The FirstTime is later than the Secon= dTime. > > > > - > > > > -**/ > > > > -BOOLEAN > > > > -VariableCompareTimeStampInternal ( > > > > - IN EFI_TIME *FirstTime, > > > > - IN EFI_TIME *SecondTime > > > > - ) > > > > -{ > > > > - if (FirstTime->Year !=3D SecondTime->Year) { > > > > - return (BOOLEAN) (FirstTime->Year < SecondTime->Year); > > > > - } else if (FirstTime->Month !=3D SecondTime->Month) { > > > > - return (BOOLEAN) (FirstTime->Month < SecondTime->Month); > > > > - } else if (FirstTime->Day !=3D SecondTime->Day) { > > > > - return (BOOLEAN) (FirstTime->Day < SecondTime->Day); > > > > - } else if (FirstTime->Hour !=3D SecondTime->Hour) { > > > > - return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour); > > > > - } else if (FirstTime->Minute !=3D SecondTime->Minute) { > > > > - return (BOOLEAN) (FirstTime->Minute < SecondTime->Minute); > > > > - } > > > > - > > > > - return (BOOLEAN) (FirstTime->Second <=3D SecondTime->Second); > > > > -} > > > > - > > > > /** > > > > Update the variable region with Variable information. If > > > > EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set, > > > > index of associated public key is needed. > > > > @@ -2885,166 +2321,6 @@ Done: > > > > return Status; > > > > } > > > > > > > > -/** > > > > - This code Finds the Next available variable. > > > > - > > > > - Caution: This function may receive untrusted input. > > > > - This function may be invoked in SMM mode. This function will do > basic > > > > validation, before parse the data. > > > > - > > > > - @param[in] VariableName Pointer to variable name. > > > > - @param[in] VendorGuid Variable Vendor Guid. > > > > - @param[out] VariablePtr Pointer to variable header address. > > > > - > > > > - @retval EFI_SUCCESS The function completed successfull= y. > > > > - @retval EFI_NOT_FOUND The next variable was not found. > > > > - @retval EFI_INVALID_PARAMETER If VariableName is not an empty > > > string, > > > > while VendorGuid is NULL. > > > > - @retval EFI_INVALID_PARAMETER The input values of VariableName > > and > > > > VendorGuid are not a name and > > > > - GUID of an existing variable. > > > > - > > > > -**/ > > > > -EFI_STATUS > > > > -EFIAPI > > > > -VariableServiceGetNextVariableInternal ( > > > > - IN CHAR16 *VariableName, > > > > - IN EFI_GUID *VendorGuid, > > > > - OUT VARIABLE_HEADER **VariablePtr > > > > - ) > > > > -{ > > > > - VARIABLE_STORE_TYPE Type; > > > > - VARIABLE_POINTER_TRACK Variable; > > > > - VARIABLE_POINTER_TRACK VariableInHob; > > > > - VARIABLE_POINTER_TRACK VariablePtrTrack; > > > > - EFI_STATUS Status; > > > > - VARIABLE_STORE_HEADER > > > *VariableStoreHeader[VariableStoreTypeMax]; > > > > - > > > > - Status =3D FindVariable (VariableName, VendorGuid, &Variable, > > > > &mVariableModuleGlobal->VariableGlobal, FALSE); > > > > - if (Variable.CurrPtr =3D=3D NULL || EFI_ERROR (Status)) { > > > > - // > > > > - // For VariableName is an empty string, FindVariable() will tr= y to find > > and > > > > return > > > > - // the first qualified variable, and if FindVariable() returns= error > > > > (EFI_NOT_FOUND) > > > > - // as no any variable is found, still go to return the error > > > > (EFI_NOT_FOUND). > > > > - // > > > > - if (VariableName[0] !=3D 0) { > > > > - // > > > > - // For VariableName is not an empty string, and FindVariable= () > > returns > > > > error as > > > > - // VariableName and VendorGuid are not a name and GUID of an > > > existing > > > > variable, > > > > - // there is no way to get next variable, follow spec to retu= rn > > > > EFI_INVALID_PARAMETER. > > > > - // > > > > - Status =3D EFI_INVALID_PARAMETER; > > > > - } > > > > - goto Done; > > > > - } > > > > - > > > > - if (VariableName[0] !=3D 0) { > > > > - // > > > > - // If variable name is not NULL, get next variable. > > > > - // > > > > - Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > > > > - } > > > > - > > > > - // > > > > - // 0: Volatile, 1: HOB, 2: Non-Volatile. > > > > - // The index and attributes mapping must be kept in this order a= s > > > > FindVariable > > > > - // makes use of this mapping to implement search algorithm. > > > > - // > > > > - VariableStoreHeader[VariableStoreTypeVolatile] =3D > > > > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > > > > >VariableGlobal.VolatileVariableBase; > > > > - VariableStoreHeader[VariableStoreTypeHob] =3D > > > > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > > > > >VariableGlobal.HobVariableBase; > > > > - VariableStoreHeader[VariableStoreTypeNv] =3D mNvVariableCa= che; > > > > - > > > > - while (TRUE) { > > > > - // > > > > - // Switch from Volatile to HOB, to Non-Volatile. > > > > - // > > > > - while (!IsValidVariableHeader (Variable.CurrPtr, Variable.EndP= tr)) { > > > > - // > > > > - // Find current storage index > > > > - // > > > > - for (Type =3D (VARIABLE_STORE_TYPE) 0; Type < > VariableStoreTypeMax; > > > > Type++) { > > > > - if ((VariableStoreHeader[Type] !=3D NULL) && (Variable.Sta= rtPtr =3D=3D > > > > GetStartPointer (VariableStoreHeader[Type]))) { > > > > - break; > > > > - } > > > > - } > > > > - ASSERT (Type < VariableStoreTypeMax); > > > > - // > > > > - // Switch to next storage > > > > - // > > > > - for (Type++; Type < VariableStoreTypeMax; Type++) { > > > > - if (VariableStoreHeader[Type] !=3D NULL) { > > > > - break; > > > > - } > > > > - } > > > > - // > > > > - // Capture the case that > > > > - // 1. current storage is the last one, or > > > > - // 2. no further storage > > > > - // > > > > - if (Type =3D=3D VariableStoreTypeMax) { > > > > - Status =3D EFI_NOT_FOUND; > > > > - goto Done; > > > > - } > > > > - Variable.StartPtr =3D GetStartPointer (VariableStoreHeader[T= ype]); > > > > - Variable.EndPtr =3D GetEndPointer (VariableStoreHeader[T= ype]); > > > > - Variable.CurrPtr =3D Variable.StartPtr; > > > > - } > > > > - > > > > - // > > > > - // Variable is found > > > > - // > > > > - if (Variable.CurrPtr->State =3D=3D VAR_ADDED || Variable.CurrP= tr- > >State > > =3D=3D > > > > (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { > > > > - if (!AtRuntime () || ((Variable.CurrPtr->Attributes & > > > > EFI_VARIABLE_RUNTIME_ACCESS) !=3D 0)) { > > > > - if (Variable.CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSIT= ION & > > > > VAR_ADDED)) { > > > > - // > > > > - // If it is a IN_DELETED_TRANSITION variable, > > > > - // and there is also a same ADDED one at the same time, > > > > - // don't return it. > > > > - // > > > > - VariablePtrTrack.StartPtr =3D Variable.StartPtr; > > > > - VariablePtrTrack.EndPtr =3D Variable.EndPtr; > > > > - Status =3D FindVariableEx ( > > > > - GetVariableNamePtr (Variable.CurrPtr), > > > > - GetVendorGuidPtr (Variable.CurrPtr), > > > > - FALSE, > > > > - &VariablePtrTrack > > > > - ); > > > > - if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->Sta= te =3D=3D > > > > VAR_ADDED) { > > > > - Variable.CurrPtr =3D GetNextVariablePtr (Variable.Curr= Ptr); > > > > - continue; > > > > - } > > > > - } > > > > - > > > > - // > > > > - // Don't return NV variable when HOB overrides it > > > > - // > > > > - if ((VariableStoreHeader[VariableStoreTypeHob] !=3D NULL) = && > > > > (VariableStoreHeader[VariableStoreTypeNv] !=3D NULL) && > > > > - (Variable.StartPtr =3D=3D GetStartPointer > > > > (VariableStoreHeader[VariableStoreTypeNv])) > > > > - ) { > > > > - VariableInHob.StartPtr =3D GetStartPointer > > > > (VariableStoreHeader[VariableStoreTypeHob]); > > > > - VariableInHob.EndPtr =3D GetEndPointer > > > > (VariableStoreHeader[VariableStoreTypeHob]); > > > > - Status =3D FindVariableEx ( > > > > - GetVariableNamePtr (Variable.CurrPtr), > > > > - GetVendorGuidPtr (Variable.CurrPtr), > > > > - FALSE, > > > > - &VariableInHob > > > > - ); > > > > - if (!EFI_ERROR (Status)) { > > > > - Variable.CurrPtr =3D GetNextVariablePtr (Variable.Curr= Ptr); > > > > - continue; > > > > - } > > > > - } > > > > - > > > > - *VariablePtr =3D Variable.CurrPtr; > > > > - Status =3D EFI_SUCCESS; > > > > - goto Done; > > > > - } > > > > - } > > > > - > > > > - Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > > > > - } > > > > - > > > > -Done: > > > > - return Status; > > > > -} > > > > - > > > > /** > > > > > > > > This code Finds the Next available variable. > > > > diff --git > > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c > > > > index cb6fcebe2d..dc78f68fa9 100644 > > > > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c > > > > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c > > > > @@ -1,12 +1,13 @@ > > > > /** @file > > > > Provides variable driver extended services. > > > > > > > > -Copyright (c) 2015, Intel Corporation. All rights reserved.
> > > > +Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.=
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > > **/ > > > > > > > > #include "Variable.h" > > > > +#include "VariableParsing.h" > > > > > > > > /** > > > > Finds variable in storage blocks of volatile and non-volatile st= orage > areas. > > > > diff --git > > > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c > > > > new file mode 100644 > > > > index 0000000000..7de0a90772 > > > > --- /dev/null > > > > +++ > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c > > > > @@ -0,0 +1,731 @@ > > > > +/** @file > > > > + Functions in this module are associated with variable parsing > > operations > > > > and > > > > + are intended to be usable across variable driver source files. > > > > + > > > > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent > > > > + > > > > +**/ > > > > + > > > > +#include "VariableParsing.h" > > > > + > > > > +/** > > > > + > > > > + This code checks if variable header is valid or not. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + @param VariableStoreEnd Pointer to the Variable Store End. > > > > + > > > > + @retval TRUE Variable header is valid. > > > > + @retval FALSE Variable header is not valid. > > > > + > > > > +**/ > > > > +BOOLEAN > > > > +IsValidVariableHeader ( > > > > + IN VARIABLE_HEADER *Variable, > > > > + IN VARIABLE_HEADER *VariableStoreEnd > > > > + ) > > > > +{ > > > > + if ((Variable =3D=3D NULL) || (Variable >=3D VariableStoreEnd) |= | (Variable- > > > > >StartId !=3D VARIABLE_DATA)) { > > > > + // > > > > + // Variable is NULL or has reached the end of variable store, > > > > + // or the StartId is not correct. > > > > + // > > > > + return FALSE; > > > > + } > > > > + > > > > + return TRUE; > > > > +} > > > > + > > > > +/** > > > > + > > > > + This code gets the current status of Variable Store. > > > > + > > > > + @param VarStoreHeader Pointer to the Variable Store Header. > > > > + > > > > + @retval EfiRaw Variable store status is raw. > > > > + @retval EfiValid Variable store status is valid. > > > > + @retval EfiInvalid Variable store status is invalid. > > > > + > > > > +**/ > > > > +VARIABLE_STORE_STATUS > > > > +GetVariableStoreStatus ( > > > > + IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > + ) > > > > +{ > > > > + if ((CompareGuid (&VarStoreHeader->Signature, > > > > &gEfiAuthenticatedVariableGuid) || > > > > + CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid)= ) > > && > > > > + VarStoreHeader->Format =3D=3D VARIABLE_STORE_FORMATTED && > > > > + VarStoreHeader->State =3D=3D VARIABLE_STORE_HEALTHY > > > > + ) { > > > > + > > > > + return EfiValid; > > > > + } else if (((UINT32 *)(&VarStoreHeader->Signature))[0] =3D=3D 0x= ffffffff > && > > > > + ((UINT32 *)(&VarStoreHeader->Signature))[1] =3D=3D 0x= ffffffff && > > > > + ((UINT32 *)(&VarStoreHeader->Signature))[2] =3D=3D 0x= ffffffff && > > > > + ((UINT32 *)(&VarStoreHeader->Signature))[3] =3D=3D 0x= ffffffff && > > > > + VarStoreHeader->Size =3D=3D 0xffffffff && > > > > + VarStoreHeader->Format =3D=3D 0xff && > > > > + VarStoreHeader->State =3D=3D 0xff > > > > + ) { > > > > + > > > > + return EfiRaw; > > > > + } else { > > > > + return EfiInvalid; > > > > + } > > > > +} > > > > + > > > > +/** > > > > + This code gets the size of variable header. > > > > + > > > > + @return Size of variable header in bytes in type UINTN. > > > > + > > > > +**/ > > > > +UINTN > > > > +GetVariableHeaderSize ( > > > > + VOID > > > > + ) > > > > +{ > > > > + UINTN Value; > > > > + > > > > + if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > + Value =3D sizeof (AUTHENTICATED_VARIABLE_HEADER); > > > > + } else { > > > > + Value =3D sizeof (VARIABLE_HEADER); > > > > + } > > > > + > > > > + return Value; > > > > +} > > > > + > > > > +/** > > > > + > > > > + This code gets the size of name of variable. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return UINTN Size of variable in bytes. > > > > + > > > > +**/ > > > > +UINTN > > > > +NameSizeOfVariable ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ) > > > > +{ > > > > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > + > > > > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > + if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > + if (AuthVariable->State =3D=3D (UINT8) (-1) || > > > > + AuthVariable->DataSize =3D=3D (UINT32) (-1) || > > > > + AuthVariable->NameSize =3D=3D (UINT32) (-1) || > > > > + AuthVariable->Attributes =3D=3D (UINT32) (-1)) { > > > > + return 0; > > > > + } > > > > + return (UINTN) AuthVariable->NameSize; > > > > + } else { > > > > + if (Variable->State =3D=3D (UINT8) (-1) || > > > > + Variable->DataSize =3D=3D (UINT32) (-1) || > > > > + Variable->NameSize =3D=3D (UINT32) (-1) || > > > > + Variable->Attributes =3D=3D (UINT32) (-1)) { > > > > + return 0; > > > > + } > > > > + return (UINTN) Variable->NameSize; > > > > + } > > > > +} > > > > + > > > > +/** > > > > + This code sets the size of name of variable. > > > > + > > > > + @param[in] Variable Pointer to the Variable Header. > > > > + @param[in] NameSize Name size to set. > > > > + > > > > +**/ > > > > +VOID > > > > +SetNameSizeOfVariable ( > > > > + IN VARIABLE_HEADER *Variable, > > > > + IN UINTN NameSize > > > > + ) > > > > +{ > > > > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > + > > > > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > + if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > + AuthVariable->NameSize =3D (UINT32) NameSize; > > > > + } else { > > > > + Variable->NameSize =3D (UINT32) NameSize; > > > > + } > > > > +} > > > > + > > > > +/** > > > > + > > > > + This code gets the size of variable data. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Size of variable in bytes. > > > > + > > > > +**/ > > > > +UINTN > > > > +DataSizeOfVariable ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ) > > > > +{ > > > > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > + > > > > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > + if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > + if (AuthVariable->State =3D=3D (UINT8) (-1) || > > > > + AuthVariable->DataSize =3D=3D (UINT32) (-1) || > > > > + AuthVariable->NameSize =3D=3D (UINT32) (-1) || > > > > + AuthVariable->Attributes =3D=3D (UINT32) (-1)) { > > > > + return 0; > > > > + } > > > > + return (UINTN) AuthVariable->DataSize; > > > > + } else { > > > > + if (Variable->State =3D=3D (UINT8) (-1) || > > > > + Variable->DataSize =3D=3D (UINT32) (-1) || > > > > + Variable->NameSize =3D=3D (UINT32) (-1) || > > > > + Variable->Attributes =3D=3D (UINT32) (-1)) { > > > > + return 0; > > > > + } > > > > + return (UINTN) Variable->DataSize; > > > > + } > > > > +} > > > > + > > > > +/** > > > > + This code sets the size of variable data. > > > > + > > > > + @param[in] Variable Pointer to the Variable Header. > > > > + @param[in] DataSize Data size to set. > > > > + > > > > +**/ > > > > +VOID > > > > +SetDataSizeOfVariable ( > > > > + IN VARIABLE_HEADER *Variable, > > > > + IN UINTN DataSize > > > > + ) > > > > +{ > > > > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > + > > > > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > + if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > + AuthVariable->DataSize =3D (UINT32) DataSize; > > > > + } else { > > > > + Variable->DataSize =3D (UINT32) DataSize; > > > > + } > > > > +} > > > > + > > > > +/** > > > > + > > > > + This code gets the pointer to the variable name. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Pointer to Variable Name which is Unicode encoding. > > > > + > > > > +**/ > > > > +CHAR16 * > > > > +GetVariableNamePtr ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ) > > > > +{ > > > > + return (CHAR16 *) ((UINTN) Variable + GetVariableHeaderSize ()); > > > > +} > > > > + > > > > +/** > > > > + This code gets the pointer to the variable guid. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return A EFI_GUID* pointer to Vendor Guid. > > > > + > > > > +**/ > > > > +EFI_GUID * > > > > +GetVendorGuidPtr ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ) > > > > +{ > > > > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > > > > + > > > > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > > > > + if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > > > > + return &AuthVariable->VendorGuid; > > > > + } else { > > > > + return &Variable->VendorGuid; > > > > + } > > > > +} > > > > + > > > > +/** > > > > + > > > > + This code gets the pointer to the variable data. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Pointer to Variable Data. > > > > + > > > > +**/ > > > > +UINT8 * > > > > +GetVariableDataPtr ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ) > > > > +{ > > > > + UINTN Value; > > > > + > > > > + // > > > > + // Be careful about pad size for alignment. > > > > + // > > > > + Value =3D (UINTN) GetVariableNamePtr (Variable); > > > > + Value +=3D NameSizeOfVariable (Variable); > > > > + Value +=3D GET_PAD_SIZE (NameSizeOfVariable (Variable)); > > > > + > > > > + return (UINT8 *) Value; > > > > +} > > > > + > > > > +/** > > > > + This code gets the variable data offset related to variable head= er. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Variable Data offset. > > > > + > > > > +**/ > > > > +UINTN > > > > +GetVariableDataOffset ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ) > > > > +{ > > > > + UINTN Value; > > > > + > > > > + // > > > > + // Be careful about pad size for alignment > > > > + // > > > > + Value =3D GetVariableHeaderSize (); > > > > + Value +=3D NameSizeOfVariable (Variable); > > > > + Value +=3D GET_PAD_SIZE (NameSizeOfVariable (Variable)); > > > > + > > > > + return Value; > > > > +} > > > > + > > > > +/** > > > > + > > > > + This code gets the pointer to the next variable header. > > > > + > > > > + @param Variable Pointer to the Variable Header. > > > > + > > > > + @return Pointer to next variable header. > > > > + > > > > +**/ > > > > +VARIABLE_HEADER * > > > > +GetNextVariablePtr ( > > > > + IN VARIABLE_HEADER *Variable > > > > + ) > > > > +{ > > > > + UINTN Value; > > > > + > > > > + Value =3D (UINTN) GetVariableDataPtr (Variable); > > > > + Value +=3D DataSizeOfVariable (Variable); > > > > + Value +=3D GET_PAD_SIZE (DataSizeOfVariable (Variable)); > > > > + > > > > + // > > > > + // Be careful about pad size for alignment. > > > > + // > > > > + return (VARIABLE_HEADER *) HEADER_ALIGN (Value); > > > > +} > > > > + > > > > +/** > > > > + > > > > + Gets the pointer to the first variable header in given variable = store > area. > > > > + > > > > + @param VarStoreHeader Pointer to the Variable Store Header. > > > > + > > > > + @return Pointer to the first variable header. > > > > + > > > > +**/ > > > > +VARIABLE_HEADER * > > > > +GetStartPointer ( > > > > + IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > + ) > > > > +{ > > > > + // > > > > + // The start of variable store. > > > > + // > > > > + return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1); > > > > +} > > > > + > > > > +/** > > > > + > > > > + Gets the pointer to the end of the variable storage area. > > > > + > > > > + This function gets pointer to the end of the variable storage > > > > + area, according to the input variable store header. > > > > + > > > > + @param VarStoreHeader Pointer to the Variable Store Header. > > > > + > > > > + @return Pointer to the end of the variable storage area. > > > > + > > > > +**/ > > > > +VARIABLE_HEADER * > > > > +GetEndPointer ( > > > > + IN VARIABLE_STORE_HEADER *VarStoreHeader > > > > + ) > > > > +{ > > > > + // > > > > + // The end of variable store > > > > + // > > > > + return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) > > VarStoreHeader > > > + > > > > VarStoreHeader->Size); > > > > +} > > > > + > > > > +/** > > > > + Compare two EFI_TIME data. > > > > + > > > > + > > > > + @param FirstTime A pointer to the first EFI_TIME data. > > > > + @param SecondTime A pointer to the second EFI_TIME data= . > > > > + > > > > + @retval TRUE The FirstTime is not later than the S= econdTime. > > > > + @retval FALSE The FirstTime is later than the Secon= dTime. > > > > + > > > > +**/ > > > > +BOOLEAN > > > > +VariableCompareTimeStampInternal ( > > > > + IN EFI_TIME *FirstTime, > > > > + IN EFI_TIME *SecondTime > > > > + ) > > > > +{ > > > > + if (FirstTime->Year !=3D SecondTime->Year) { > > > > + return (BOOLEAN) (FirstTime->Year < SecondTime->Year); > > > > + } else if (FirstTime->Month !=3D SecondTime->Month) { > > > > + return (BOOLEAN) (FirstTime->Month < SecondTime->Month); > > > > + } else if (FirstTime->Day !=3D SecondTime->Day) { > > > > + return (BOOLEAN) (FirstTime->Day < SecondTime->Day); > > > > + } else if (FirstTime->Hour !=3D SecondTime->Hour) { > > > > + return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour); > > > > + } else if (FirstTime->Minute !=3D SecondTime->Minute) { > > > > + return (BOOLEAN) (FirstTime->Minute < SecondTime->Minute); > > > > + } > > > > + > > > > + return (BOOLEAN) (FirstTime->Second <=3D SecondTime->Second); > > > > +} > > > > + > > > > +/** > > > > + Find the variable in the specified variable store. > > > > + > > > > + @param[in] VariableName Name of the variable to be = found > > > > + @param[in] VendorGuid Vendor GUID to be found. > > > > + @param[in] IgnoreRtCheck Ignore > > > EFI_VARIABLE_RUNTIME_ACCESS > > > > attribute > > > > + check at runtime when searc= hing variable. > > > > + @param[in, out] PtrTrack Variable Track Pointer stru= cture that > > > > contains Variable Information. > > > > + > > > > + @retval EFI_SUCCESS Variable found successfully > > > > + @retval EFI_NOT_FOUND Variable not found > > > > +**/ > > > > +EFI_STATUS > > > > +FindVariableEx ( > > > > + IN CHAR16 *VariableName, > > > > + IN EFI_GUID *VendorGuid, > > > > + IN BOOLEAN IgnoreRtCheck, > > > > + IN OUT VARIABLE_POINTER_TRACK *PtrTrack > > > > + ) > > > > +{ > > > > + VARIABLE_HEADER *InDeletedVariable; > > > > + VOID *Point; > > > > + > > > > + PtrTrack->InDeletedTransitionPtr =3D NULL; > > > > + > > > > + // > > > > + // Find the variable by walk through HOB, volatile and non-volat= ile > > > variable > > > > store. > > > > + // > > > > + InDeletedVariable =3D NULL; > > > > + > > > > + for ( PtrTrack->CurrPtr =3D PtrTrack->StartPtr > > > > + ; IsValidVariableHeader (PtrTrack->CurrPtr, PtrTrack->EndPtr= ) > > > > + ; PtrTrack->CurrPtr =3D GetNextVariablePtr (PtrTrack->CurrPt= r) > > > > + ) { > > > > + if (PtrTrack->CurrPtr->State =3D=3D VAR_ADDED || > > > > + PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSITION= & > > > > VAR_ADDED) > > > > + ) { > > > > + if (IgnoreRtCheck || !AtRuntime () || ((PtrTrack->CurrPtr- > >Attributes > > > & > > > > EFI_VARIABLE_RUNTIME_ACCESS) !=3D 0)) { > > > > + if (VariableName[0] =3D=3D 0) { > > > > + if (PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRAN= SITION > & > > > > VAR_ADDED)) { > > > > + InDeletedVariable =3D PtrTrack->CurrPtr; > > > > + } else { > > > > + PtrTrack->InDeletedTransitionPtr =3D InDeletedVariable= ; > > > > + return EFI_SUCCESS; > > > > + } > > > > + } else { > > > > + if (CompareGuid (VendorGuid, GetVendorGuidPtr (PtrTrack- > > > >CurrPtr))) > > > > { > > > > + Point =3D (VOID *) GetVariableNamePtr (PtrTrack->CurrP= tr); > > > > + > > > > + ASSERT (NameSizeOfVariable (PtrTrack->CurrPtr) !=3D 0)= ; > > > > + if (CompareMem (VariableName, Point, NameSizeOfVariabl= e > > > > (PtrTrack->CurrPtr)) =3D=3D 0) { > > > > + if (PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_= TRANSITION > > & > > > > VAR_ADDED)) { > > > > + InDeletedVariable =3D PtrTrack->CurrPtr; > > > > + } else { > > > > + PtrTrack->InDeletedTransitionPtr =3D InDeletedVari= able; > > > > + return EFI_SUCCESS; > > > > + } > > > > + } > > > > + } > > > > + } > > > > + } > > > > + } > > > > + } > > > > + > > > > + PtrTrack->CurrPtr =3D InDeletedVariable; > > > > + return (PtrTrack->CurrPtr =3D=3D NULL) ? EFI_NOT_FOUND : > EFI_SUCCESS; > > > > +} > > > > + > > > > +/** > > > > + This code Finds the Next available variable. > > > > + > > > > + Caution: This function may receive untrusted input. > > > > + This function may be invoked in SMM mode. This function will do > basic > > > > validation, before parse the data. > > > > + > > > > + @param[in] VariableName Pointer to variable name. > > > > + @param[in] VendorGuid Variable Vendor Guid. > > > > + @param[out] VariablePtr Pointer to variable header address. > > > > + > > > > + @retval EFI_SUCCESS The function completed successfull= y. > > > > + @retval EFI_NOT_FOUND The next variable was not found. > > > > + @retval EFI_INVALID_PARAMETER If VariableName is not an empty > > > string, > > > > while VendorGuid is NULL. > > > > + @retval EFI_INVALID_PARAMETER The input values of VariableName > > > and > > > > VendorGuid are not a name and > > > > + GUID of an existing variable. > > > > + > > > > +**/ > > > > +EFI_STATUS > > > > +EFIAPI > > > > +VariableServiceGetNextVariableInternal ( > > > > + IN CHAR16 *VariableName, > > > > + IN EFI_GUID *VendorGuid, > > > > + OUT VARIABLE_HEADER **VariablePtr > > > > + ) > > > > +{ > > > > + VARIABLE_STORE_TYPE Type; > > > > + VARIABLE_POINTER_TRACK Variable; > > > > + VARIABLE_POINTER_TRACK VariableInHob; > > > > + VARIABLE_POINTER_TRACK VariablePtrTrack; > > > > + EFI_STATUS Status; > > > > + VARIABLE_STORE_HEADER > > > > *VariableStoreHeader[VariableStoreTypeMax]; > > > > + > > > > + Status =3D FindVariable (VariableName, VendorGuid, &Variable, > > > > &mVariableModuleGlobal->VariableGlobal, FALSE); > > > > + if (Variable.CurrPtr =3D=3D NULL || EFI_ERROR (Status)) { > > > > + // > > > > + // For VariableName is an empty string, FindVariable() will tr= y to find > > > and > > > > return > > > > + // the first qualified variable, and if FindVariable() returns= error > > > > (EFI_NOT_FOUND) > > > > + // as no any variable is found, still go to return the error > > > > (EFI_NOT_FOUND). > > > > + // > > > > + if (VariableName[0] !=3D 0) { > > > > + // > > > > + // For VariableName is not an empty string, and FindVariable= () > > returns > > > > error as > > > > + // VariableName and VendorGuid are not a name and GUID of an > > > > existing variable, > > > > + // there is no way to get next variable, follow spec to retu= rn > > > > EFI_INVALID_PARAMETER. > > > > + // > > > > + Status =3D EFI_INVALID_PARAMETER; > > > > + } > > > > + goto Done; > > > > + } > > > > + > > > > + if (VariableName[0] !=3D 0) { > > > > + // > > > > + // If variable name is not NULL, get next variable. > > > > + // > > > > + Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > > > > + } > > > > + > > > > + // > > > > + // 0: Volatile, 1: HOB, 2: Non-Volatile. > > > > + // The index and attributes mapping must be kept in this order a= s > > > > FindVariable > > > > + // makes use of this mapping to implement search algorithm. > > > > + // > > > > + VariableStoreHeader[VariableStoreTypeVolatile] =3D > > > > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > > > > >VariableGlobal.VolatileVariableBase; > > > > + VariableStoreHeader[VariableStoreTypeHob] =3D > > > > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > > > > >VariableGlobal.HobVariableBase; > > > > + VariableStoreHeader[VariableStoreTypeNv] =3D mNvVariableCa= che; > > > > + > > > > + while (TRUE) { > > > > + // > > > > + // Switch from Volatile to HOB, to Non-Volatile. > > > > + // > > > > + while (!IsValidVariableHeader (Variable.CurrPtr, Variable.EndP= tr)) { > > > > + // > > > > + // Find current storage index > > > > + // > > > > + for (Type =3D (VARIABLE_STORE_TYPE) 0; Type < > > VariableStoreTypeMax; > > > > Type++) { > > > > + if ((VariableStoreHeader[Type] !=3D NULL) && (Variable.Sta= rtPtr =3D=3D > > > > GetStartPointer (VariableStoreHeader[Type]))) { > > > > + break; > > > > + } > > > > + } > > > > + ASSERT (Type < VariableStoreTypeMax); > > > > + // > > > > + // Switch to next storage > > > > + // > > > > + for (Type++; Type < VariableStoreTypeMax; Type++) { > > > > + if (VariableStoreHeader[Type] !=3D NULL) { > > > > + break; > > > > + } > > > > + } > > > > + // > > > > + // Capture the case that > > > > + // 1. current storage is the last one, or > > > > + // 2. no further storage > > > > + // > > > > + if (Type =3D=3D VariableStoreTypeMax) { > > > > + Status =3D EFI_NOT_FOUND; > > > > + goto Done; > > > > + } > > > > + Variable.StartPtr =3D GetStartPointer (VariableStoreHeader[T= ype]); > > > > + Variable.EndPtr =3D GetEndPointer (VariableStoreHeader[T= ype]); > > > > + Variable.CurrPtr =3D Variable.StartPtr; > > > > + } > > > > + > > > > + // > > > > + // Variable is found > > > > + // > > > > + if (Variable.CurrPtr->State =3D=3D VAR_ADDED || Variable.CurrP= tr- > >State > > > =3D=3D > > > > (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { > > > > + if (!AtRuntime () || ((Variable.CurrPtr->Attributes & > > > > EFI_VARIABLE_RUNTIME_ACCESS) !=3D 0)) { > > > > + if (Variable.CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSIT= ION & > > > > VAR_ADDED)) { > > > > + // > > > > + // If it is a IN_DELETED_TRANSITION variable, > > > > + // and there is also a same ADDED one at the same time, > > > > + // don't return it. > > > > + // > > > > + VariablePtrTrack.StartPtr =3D Variable.StartPtr; > > > > + VariablePtrTrack.EndPtr =3D Variable.EndPtr; > > > > + Status =3D FindVariableEx ( > > > > + GetVariableNamePtr (Variable.CurrPtr), > > > > + GetVendorGuidPtr (Variable.CurrPtr), > > > > + FALSE, > > > > + &VariablePtrTrack > > > > + ); > > > > + if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->Sta= te =3D=3D > > > > VAR_ADDED) { > > > > + Variable.CurrPtr =3D GetNextVariablePtr (Variable.Curr= Ptr); > > > > + continue; > > > > + } > > > > + } > > > > + > > > > + // > > > > + // Don't return NV variable when HOB overrides it > > > > + // > > > > + if ((VariableStoreHeader[VariableStoreTypeHob] !=3D NULL) = && > > > > (VariableStoreHeader[VariableStoreTypeNv] !=3D NULL) && > > > > + (Variable.StartPtr =3D=3D GetStartPointer > > > > (VariableStoreHeader[VariableStoreTypeNv])) > > > > + ) { > > > > + VariableInHob.StartPtr =3D GetStartPointer > > > > (VariableStoreHeader[VariableStoreTypeHob]); > > > > + VariableInHob.EndPtr =3D GetEndPointer > > > > (VariableStoreHeader[VariableStoreTypeHob]); > > > > + Status =3D FindVariableEx ( > > > > + GetVariableNamePtr (Variable.CurrPtr), > > > > + GetVendorGuidPtr (Variable.CurrPtr), > > > > + FALSE, > > > > + &VariableInHob > > > > + ); > > > > + if (!EFI_ERROR (Status)) { > > > > + Variable.CurrPtr =3D GetNextVariablePtr (Variable.Curr= Ptr); > > > > + continue; > > > > + } > > > > + } > > > > + > > > > + *VariablePtr =3D Variable.CurrPtr; > > > > + Status =3D EFI_SUCCESS; > > > > + goto Done; > > > > + } > > > > + } > > > > + > > > > + Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > > > > + } > > > > + > > > > +Done: > > > > + return Status; > > > > +} > > > > + > > > > +/** > > > > + Routine used to track statistical information about variable usa= ge. > > > > + The data is stored in the EFI system table so it can be accessed= later. > > > > + VariableInfo.efi can dump out the table. Only Boot Services vari= able > > > > + accesses are tracked by this code. The PcdVariableCollectStatist= ics > > > > + build flag controls if this feature is enabled. > > > > + > > > > + A read that hits in the cache will have Read and Cache true for > > > > + the transaction. Data is allocated by this routine, but never > > > > + freed. > > > > + > > > > + @param[in] VariableName Name of the Variable to track. > > > > + @param[in] VendorGuid Guid of the Variable to track. > > > > + @param[in] Volatile TRUE if volatile FALSE if non-volatile= . > > > > + @param[in] Read TRUE if GetVariable() was called. > > > > + @param[in] Write TRUE if SetVariable() was called. > > > > + @param[in] Delete TRUE if deleted via SetVariable(). > > > > + @param[in] Cache TRUE for a cache hit. > > > > + > > > > +**/ > > > > +VOID > > > > +UpdateVariableInfo ( > > > > + IN CHAR16 *VariableName, > > > > + IN EFI_GUID *VendorGuid, > > > > + IN BOOLEAN Volatile, > > > > + IN BOOLEAN Read, > > > > + IN BOOLEAN Write, > > > > + IN BOOLEAN Delete, > > > > + IN BOOLEAN Cache > > > > + ) > > > > +{ > > > > + VARIABLE_INFO_ENTRY *Entry; > > > > + > > > > + if (FeaturePcdGet (PcdVariableCollectStatistics)) { > > > > + > > > > + if (AtRuntime ()) { > > > > + // Don't collect statistics at runtime. > > > > + return; > > > > + } > > > > + > > > > + if (gVariableInfo =3D=3D NULL) { > > > > + // > > > > + // On the first call allocate a entry and place a pointer to= it in > > > > + // the EFI System Table. > > > > + // > > > > + gVariableInfo =3D AllocateZeroPool (sizeof > (VARIABLE_INFO_ENTRY)); > > > > + ASSERT (gVariableInfo !=3D NULL); > > > > + > > > > + CopyGuid (&gVariableInfo->VendorGuid, VendorGuid); > > > > + gVariableInfo->Name =3D AllocateZeroPool (StrSize (VariableN= ame)); > > > > + ASSERT (gVariableInfo->Name !=3D NULL); > > > > + StrCpyS (gVariableInfo->Name, > > > StrSize(VariableName)/sizeof(CHAR16), > > > > VariableName); > > > > + gVariableInfo->Volatile =3D Volatile; > > > > + } > > > > + > > > > + > > > > + for (Entry =3D gVariableInfo; Entry !=3D NULL; Entry =3D Entry= ->Next) { > > > > + if (CompareGuid (VendorGuid, &Entry->VendorGuid)) { > > > > + if (StrCmp (VariableName, Entry->Name) =3D=3D 0) { > > > > + if (Read) { > > > > + Entry->ReadCount++; > > > > + } > > > > + if (Write) { > > > > + Entry->WriteCount++; > > > > + } > > > > + if (Delete) { > > > > + Entry->DeleteCount++; > > > > + } > > > > + if (Cache) { > > > > + Entry->CacheCount++; > > > > + } > > > > + > > > > + return; > > > > + } > > > > + } > > > > + > > > > + if (Entry->Next =3D=3D NULL) { > > > > + // > > > > + // If the entry is not in the table add it. > > > > + // Next iteration of the loop will fill in the data. > > > > + // > > > > + Entry->Next =3D AllocateZeroPool (sizeof (VARIABLE_INFO_EN= TRY)); > > > > + ASSERT (Entry->Next !=3D NULL); > > > > + > > > > + CopyGuid (&Entry->Next->VendorGuid, VendorGuid); > > > > + Entry->Next->Name =3D AllocateZeroPool (StrSize (VariableN= ame)); > > > > + ASSERT (Entry->Next->Name !=3D NULL); > > > > + StrCpyS (Entry->Next->Name, > > > StrSize(VariableName)/sizeof(CHAR16), > > > > VariableName); > > > > + Entry->Next->Volatile =3D Volatile; > > > > + } > > > > + > > > > + } > > > > + } > > > > +} > > > > diff --git > > > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > > > > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > > > > index ec463d063e..ce409f22a3 100644 > > > > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > > > > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > > > > @@ -30,6 +30,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > > #include > > > > #include "Variable.h" > > > > +#include "VariableParsing.h" > > > > > > > > BOOLEAN mAtRuntime = =3D FALSE; > > > > UINT8 *mVariableBuf= ferPayload =3D NULL; > > > > -- > > > > 2.16.2.windows.1 > > > > > >=20