From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web12.2214.1607647355613266025 for ; Thu, 10 Dec 2020 16:42:35 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=twryGwPw; spf=pass (domain: intel.com, ip: 192.55.52.136, mailfrom: hao.a.wu@intel.com) IronPort-SDR: G8C0ixOnCavTi/S8/R6hICg8PuqowKyUe90rLScO2tAzDehjxok1j3uhfYFCgOVAOkBa0z6J1B 2WSsC7+5ql6Q== X-IronPort-AV: E=McAfee;i="6000,8403,9831"; a="153590438" X-IronPort-AV: E=Sophos;i="5.78,409,1599548400"; d="scan'208,217";a="153590438" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Dec 2020 16:42:34 -0800 IronPort-SDR: HK7J97qn+VAn638WHwYs6EJdO4jOJ2UHG19KBdXSP2GKsMbsZeNFf70xBY2J7yuS+9byrozUm8 I7qS1Bw9QSNg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,409,1599548400"; d="scan'208,217";a="333671421" Received: from fmsmsx605.amr.corp.intel.com ([10.18.126.85]) by orsmga003.jf.intel.com with ESMTP; 10 Dec 2020 16:42:33 -0800 Received: from fmsmsx611.amr.corp.intel.com (10.18.126.91) by fmsmsx605.amr.corp.intel.com (10.18.126.85) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Thu, 10 Dec 2020 16:42:33 -0800 Received: from fmsmsx612.amr.corp.intel.com (10.18.126.92) by fmsmsx611.amr.corp.intel.com (10.18.126.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Thu, 10 Dec 2020 16:42:32 -0800 Received: from fmsedg601.ED.cps.intel.com (10.1.192.135) by fmsmsx612.amr.corp.intel.com (10.18.126.92) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5 via Frontend Transport; Thu, 10 Dec 2020 16:42:32 -0800 Received: from NAM02-CY1-obe.outbound.protection.outlook.com (104.47.37.59) by edgegateway.intel.com (192.55.55.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1713.5; Thu, 10 Dec 2020 16:42:30 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oLzx/TTojDxW4RYbE9pIW8Mjw52usXHYt22qBKBg+ARl6nDGGgW2EFEJtx5rTNGGCaYLaekwRYKCj9nW5A74wGFQDoN+C5J8GF07L6Ut/iPJJ/ycGQxMjFAmlZm+uJU6qdZLEOOW/FMfruAvIrFH6b/jlIAEcjW7n+C3p0c8l48+MnKwIH81e7kbRBZrkCk9UOif2Jq7LkI0u6zLVJ4e2Idx0V3GJqy//NtrqseS0oLKiUpMase0F312m4BH0eNV9gzsbqwpynuIUKc8e7kuu8VoljGnzQ0qzzdEMgYV3h52cvghsy1ifYJOgNzJT+JLk1WO/SBUwjv1PIq9vpjtOg== 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=OVXBras66bQisBgfnw0iIBcB7dTUm918RVQHCH3AM28=; b=Dr6TKholSW7TR6Vcwy3TGd0zhGsbPgDgnNDE+RfkQuenu3VduHI0zAl8OvlEVsOKrpwsrFRQumpywy5Do9CW04bCmEQz/LWQ3UfTIOGnGjB6T31QtzEQDr1n1gengUdHU4Nxng7DXogJg1D71Yl0pkHiywEN7Ac+gIQXvs6Fr4BR9VBhVW7wuitCEX63zSnD4vjo+WgtocZJIDXU6IOy7O6tPwFGjESjwAuQKsyNWhr3A/zv6L8t9uaYgvyV4XTEG/4hGqvKDGB8nA+BqIIltziiz+rN3vntlt9lPFjGA1bqXsDkDYQZ41KAVPVokXZTMocMo+v5eddOXdCEDtRxuA== 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=OVXBras66bQisBgfnw0iIBcB7dTUm918RVQHCH3AM28=; b=twryGwPwpfkfUboAAs1AAID7/r0g2m+4OyfZuYBvPBDXMjobBZdOT9ouDo7kBeCuwrYvoqP37G5tb7wJEObvLlWeJOhfa4B5JOoK2BOTXPzMym5jamQvQpf/V9TkmeITcDZz5WFS8GO7F93RSoe7b91C9S/5WVSpgFVIfauf46k= Received: from BN8PR11MB3666.namprd11.prod.outlook.com (2603:10b6:408:8c::19) by BN6PR11MB1282.namprd11.prod.outlook.com (2603:10b6:404:4a::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.14; Fri, 11 Dec 2020 00:42:28 +0000 Received: from BN8PR11MB3666.namprd11.prod.outlook.com ([fe80::4cda:993f:ffc1:f169]) by BN8PR11MB3666.namprd11.prod.outlook.com ([fe80::4cda:993f:ffc1:f169%6]) with mapi id 15.20.3654.014; Fri, 11 Dec 2020 00:42:28 +0000 From: "Wu, Hao A" To: "devel@edk2.groups.io" , "bret.barkelew@microsoft.com" , gaoliming , "Kinney, Michael D" Subject: =?UTF-8?B?UmU6IFtFWFRFUk5BTF0g5Zue5aSNOiBbZWRrMi1kZXZlbF0gW1BhdGNoIHYyIDEvMV0gTWRlTW9kdWxlUGtnL1ZhcmlhYmxlL1J1bnRpbWVEeGU6IFJlc3RvcmUgVmFyaWFibGUgTG9jayBQcm90b2NvbCBiZWhhdmlvcg==?= Thread-Topic: =?gb2312?B?W0VYVEVSTkFMXSC72Li0OiBbZWRrMi1kZXZlbF0gW1BhdGNoIHYyIDEvMV0g?= =?gb2312?B?TWRlTW9kdWxlUGtnL1ZhcmlhYmxlL1J1bnRpbWVEeGU6IFJlc3RvcmUgVmFy?= =?gb2312?Q?iable_Lock_Protocol_behavior?= Thread-Index: AQHWzlYHpbk0zif76kyxrBBi9qYzTanvjMvwgAAcOwCAAEgcgIABHYyg Date: Fri, 11 Dec 2020 00:42:28 +0000 Message-ID: References: <20201209180605.1409-1-michael.d.kinney@intel.com> ,<004d01d6cea2$d9b15670$8d140350$@byosoft.com.cn> In-Reply-To: Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Enabled=True; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId=72f988bf-86f1-41af-91ab-2d7cd011db47; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetDate=2020-12-10T07:30:59.7851022Z; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_ContentBits=0; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Method=Privileged dlp-product: dlpe-windows dlp-reaction: no-action dlp-version: 11.5.1.3 authentication-results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=intel.com; x-originating-ip: [192.198.147.218] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: f3b067dd-f94d-4f2d-65ea-08d89d6da323 x-ms-traffictypediagnostic: BN6PR11MB1282: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:10000; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: CfSPtFyNzaw7U/Zo4nhigxxpTXP73bu4kIHj/1efbwZnH2JGybeP4DdT6giTxI9WmJuMOGCwny0PVR/kFkKwO5gFBnSbZsaG1x2VE80qpubptPowkg6DIlhqesBnpEOA+WfM+tJ2rITIvh2zcyL+j+hpqVPuDikdyLDEcKGPZWuH3gnBwwhdyjbayF2jBVsLuHzVUF5p0DBAQ/mywOSPZDawMM8o+lMMx1cmP4YvRVJWHDEnr0gzpu2TFIzcSxUAwIIVn99x6ercYo3FhGziYRPJWJkkkn/8LF3qwzxBt4jJUok3wPwa0ZLz7nZOYuvNuBD90wxvfz23TmgtNP+G3yT6u8+RsF27UIDVNtcPDQd4wpIfJq8v5KCpOPtx1+3M/yOpa43AlWIG4x5kDQHGGA== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BN8PR11MB3666.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(376002)(346002)(136003)(366004)(508600001)(45080400002)(5660300002)(30864003)(166002)(71200400001)(76116006)(53546011)(8936002)(83380400001)(7696005)(966005)(86362001)(6636002)(110136005)(2906002)(66556008)(9686003)(55016002)(186003)(66476007)(52536014)(66946007)(33656002)(224303003)(66446008)(76236003)(64756008)(26005)(6506007)(559001)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?gb2312?B?WUZBZUtub1ZDbU1HaStOZWNCYVFTcjkrd0JVRGY4VUZTcnZrNVRVbWRWTHlo?= =?gb2312?B?MWc3UzYyVnduU21PRDlKUHZXM0d6WTFCR3d1R09xdTFJV3ZoemhSNXRkQ2dW?= =?gb2312?B?Rm5wU0ZnQjRhR2NPWUlnQUVtcHpDamd5MXE2SWlqK0RxVHU3RnJJNWRsN0Zv?= =?gb2312?B?b1IrcDdPOFBpcExuOFZ0RWRiWktmZzVaeFhTTlRGUlZ6Zk10L0xNTkZxQm1m?= =?gb2312?B?cS9uaGU2VE4xLzdYLzNqM252V3k0VGxMQk8xdEQzTnVkZkRnbEhsOS91T1Y1?= =?gb2312?B?cmhWYlJ2ZVRuUmQzQUtFUDFLK2xMSU1TMTB6a0FENmxtTmo3WmUzdkRpZjBV?= =?gb2312?B?a2tBbUZhaDRsOHF6bDVwc1dIcjVhSUcxK1JZUDhsM1dpUDVXTjVtYUJpK0g2?= =?gb2312?B?Ry9udWhWUWZ0V0MvWjF6S2YyTVBqZmFKR3VvL2ZmelQrWVM0Y0MyQjVPcmpL?= =?gb2312?B?M1NhR0pYZ0VMTXUyV3RCUks5dGFlVU1wOVJCZUM3MndEOTNVZnd2cWJGQmVp?= =?gb2312?B?dmdkWmcxa0trU3RodTVsOVFIWXpYV2doL1V1L0JKUkNBb09Ga3RwRk1Xb0kx?= =?gb2312?B?YVJsa2s1K2t5REVBYVZYeTRFc2xWTWxaNFVGZ3BxRWxJZFcyRUp4SjUxRGxx?= =?gb2312?B?c1VpM2E3enZOMnVjaHkwTUJtZjE0TnRGTlViOXFWOXZ2MTU3VnhvNS9vanZ3?= =?gb2312?B?ZCs5UFk3bzJOeVFGWEliWUN2UGJzM2dISXcwYTIwZ1V3Vlcyb3psOU1EMHhi?= =?gb2312?B?dmgvdFVQWGtFNmRCUzJ2S0pUbmI5R0h1UUxTMXRoWkdQRmpBT3JLWUFjQm1L?= =?gb2312?B?bFUxMGpYcXQ1VDRIZjhMQmFFeDNFSzBCRmJJdHZoR0cvblpRcW5Ra1AvNHcv?= =?gb2312?B?K2h0bjBZeUswaEdRQnZEU2FwNE9zQm9jd3p5VU1rcWFiQi91ZlhURnlEOWY1?= =?gb2312?B?ZWh2ZW5TTXlvVDQxR3ozOWVmY3J3SjdLTkxtZ1NkdWN3VFFsVG45cjY0UUtm?= =?gb2312?B?THFQNWZMN2VXcnhkelRJQjN6R1laU0hTa3ZNUXk0VElrSVIyTnFqV3I5elRj?= =?gb2312?B?WVlVSFFXR3NhU2hCeGk5T2plc0Fua3Vua1hNMzIzMWdCWkFtd1podVJ5L2li?= =?gb2312?B?VmpCU1ZUM3huVDdqU1QxTFZKM1RFS0FkS1l0Q0c1d3V0WFRHZVVBS3JmV0h6?= =?gb2312?B?QTJnV29kck5ob3hRN1ZJanJpOWNjeGQvUWttV2tVZlpPSyt1dFVDQTdPbVF0?= =?gb2312?B?UVJVYStKSzFVVmN4VU9nU2xzNkllTC8wd21SL0d4bUUyWTFtVWo0K29Fai9T?= =?gb2312?Q?2Hb2QCTwrFTGu+4vwZchTAoIXXuGGAbIKJ?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BN8PR11MB3666.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: f3b067dd-f94d-4f2d-65ea-08d89d6da323 X-MS-Exchange-CrossTenant-originalarrivaltime: 11 Dec 2020 00:42:28.5917 (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: 5Hl5j7AZEIkRR5z3PDnJt2AOdwTBPhSdgBwEVWULeyPH82lMVAJ/PTUoZltSy8x8ubuojPq4CnQ4XYmHxAH9BA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR11MB1282 Return-Path: hao.a.wu@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: multipart/alternative; boundary="_000_BN8PR11MB3666F30E5317D9E284A429D8CACA0BN8PR11MB3666namp_" --_000_BN8PR11MB3666F30E5317D9E284A429D8CACA0BN8PR11MB3666namp_ Content-Type: text/plain; charset="gb2312" Content-Transfer-Encoding: base64 SGVsbG8gQnJldCBhbmQgTWlrZSwNCg0KVGhhbmtzIGZvciB0aGUgZXhwbGFuYXRpb24gb24gdGhl IGNvZGUgcmV1c2luZyBvcGVuLiBJZiB0aGUgY29kZSB3aWxsIGV2ZW50dWFsbHkgYmUgZ29uZSwg SSBhbSBmaW5lIHdpdGggaXQuDQoNCkZvciBMaW1pbmehr3Mgc3VnZ2VzdGlvbiB0byBzcGxpdCB0 aGUgcGF0Y2ggaW50byBhIDItcGF0Y2ggc2VyaWVzICgxIGZvciB0aGUgZml4IGFuZCAxIGZvciB0 aGUgdW5pdCB0ZXN0cyksIEkgYW0gb2theSB3aXRoIHB1dHRpbmcgdGhlbSBpbiAxIHBhdGNoLg0K TXkgcHJlZmVyZW5jZSBpcyBhbHNvIGJyZWFraW5nIHRoZW0gaW50byAyIHBhdGNoZXMsIHNpbmNl IHRoZXNlIDIgcGF0Y2hlcyBhcmUgbm90IGRvaW5nIGV4YWN0aW5nIG9uZSB0aGluZy4NCkJ1dCBp dCBpcyBvbmx5IGEgc3VnZ2VzdGlvbiwgcGxlYXNlIGZlZWwgZnJlZSB0byBtYWtlIHlvdXIgb3du IGRlY2lzaW9uLg0KDQpJbiBzdW1tYXJ5LCB3aXRoIHRoZSB0eXBvcyBhZGRyZXNzZWQgaW4gdGhl IHBhdGNoIChpbiBteSBwcmV2aW91cyByZXBseSB0byB0aGUgcGF0Y2gpOg0KUmV2aWV3ZWQtYnk6 IEhhbyBBIFd1IDxoYW8uYS53dUBpbnRlbC5jb20+DQoNCkJlc3QgUmVnYXJkcywNCkhhbyBXdQ0K DQpGcm9tOiBkZXZlbEBlZGsyLmdyb3Vwcy5pbyA8ZGV2ZWxAZWRrMi5ncm91cHMuaW8+IE9uIEJl aGFsZiBPZiBCcmV0IEJhcmtlbGV3IHZpYSBncm91cHMuaW8NClNlbnQ6IFRodXJzZGF5LCBEZWNl bWJlciAxMCwgMjAyMCAzOjM1IFBNDQpUbzogZ2FvbGltaW5nIDxnYW9saW1pbmdAYnlvc29mdC5j b20uY24+OyBXdSwgSGFvIEEgPGhhby5hLnd1QGludGVsLmNvbT47IGRldmVsQGVkazIuZ3JvdXBz LmlvOyBLaW5uZXksIE1pY2hhZWwgRCA8bWljaGFlbC5kLmtpbm5leUBpbnRlbC5jb20+DQpTdWJq ZWN0OiBSZTogW0VYVEVSTkFMXSC72Li0OiBbZWRrMi1kZXZlbF0gW1BhdGNoIHYyIDEvMV0gTWRl TW9kdWxlUGtnL1ZhcmlhYmxlL1J1bnRpbWVEeGU6IFJlc3RvcmUgVmFyaWFibGUgTG9jayBQcm90 b2NvbCBiZWhhdmlvcg0KDQpJIHdvdWxkIHByZWZlciB0byBub3QgcmV1c2UgdGhlIGNvZGUgZnJv bSB0aGUgbGlicmFyeS4gVGhleSBhcmUgU1VQUE9TRUQgdG8gYmUgaW50ZXJuYWwgZnVuY3Rpb25z IGFuZCBhcmUgbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuIEmhr3ZlIGR1cGxpY2F0 ZWQgdGhlbSBoZXJlIGJlY2F1c2UgdGhpcyBzaGltIGlzIHN1cHBvc2VkIHRvIGJlIHRlbXBvcmFy eSBhbmQgc2hvdWxkIGdvIGF3YXkgd2l0aGluIHRoZSBuZXh0IGZldyBzdGFiaWxpemF0aW9ucy4N Cg0KSSB3b3VsZCBhbHNvIHByZWZlciB0byBrZWVwIHRoZSB0ZXN0cyBhbmQgdGhlIGNvZGUgdG9n ZXRoZXIuIFRoZXNlIGFyZSBwdXJlIHVuaXQgdGVzdHMgcmF0aGVyIHRoYW4gZHJpdmVyIHRlc3Rz IGFuZCBzZXJ2ZSB0byBkb2N1bWVudCBhbmQgcHJvdmUgdGhlIGNvZGUgdGhhdCBpcyBiZWluZyBz dWJtaXR0ZWQuIEhvd2V2ZXIsIEmhr20gd2lsbGluZyB0byBiZSBmbGV4aWJsZSBvbiB0aGlzLg0K DQotIEJyZXQNCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQpGcm9tOiBnYW9saW1p bmcgPGdhb2xpbWluZ0BieW9zb2Z0LmNvbS5jbjxtYWlsdG86Z2FvbGltaW5nQGJ5b3NvZnQuY29t LmNuPj4NClNlbnQ6IFdlZG5lc2RheSwgRGVjZW1iZXIgOSwgMjAyMCA3OjE2OjI4IFBNDQpUbzog J1d1LCBIYW8gQScgPGhhby5hLnd1QGludGVsLmNvbTxtYWlsdG86aGFvLmEud3VAaW50ZWwuY29t Pj47IGRldmVsQGVkazIuZ3JvdXBzLmlvPG1haWx0bzpkZXZlbEBlZGsyLmdyb3Vwcy5pbz4gPGRl dmVsQGVkazIuZ3JvdXBzLmlvPG1haWx0bzpkZXZlbEBlZGsyLmdyb3Vwcy5pbz4+OyBLaW5uZXks IE1pY2hhZWwgRCA8bWljaGFlbC5kLmtpbm5leUBpbnRlbC5jb208bWFpbHRvOm1pY2hhZWwuZC5r aW5uZXlAaW50ZWwuY29tPj4NCkNjOiBCcmV0IEJhcmtlbGV3IDxCcmV0LkJhcmtlbGV3QG1pY3Jv c29mdC5jb208bWFpbHRvOkJyZXQuQmFya2VsZXdAbWljcm9zb2Z0LmNvbT4+DQpTdWJqZWN0OiBb RVhURVJOQUxdILvYuLQ6IFtlZGsyLWRldmVsXSBbUGF0Y2ggdjIgMS8xXSBNZGVNb2R1bGVQa2cv VmFyaWFibGUvUnVudGltZUR4ZTogUmVzdG9yZSBWYXJpYWJsZSBMb2NrIFByb3RvY29sIGJlaGF2 aW9yDQoNCk1pa2U6DQogIEkgYWdyZWUgSGFvIGNvbW1lbnQuIFRoZXJlIGlzIHRoZSBzaW1pbGFy IGNvZGUgbG9naWMgaW4gVmFyaWFibGVQb2xpY3lMaWINCmxpYnJhcnkuIFRoZXkgY2FuIGJlIHNo YXJlZC4NCg0KICBCZXNpZGVzLCBJIHN1Z2dlc3QgdG8gc3BsaXQgdGhpcyBwYXRjaC4gT25lIGlz IHRoZSBidWcgZml4IHRvIHJlc3RvcmUNClZhcmlhYmxlIExvY2sgUHJvdG9jb2wgYmVoYXZpb3Is IGFub3RoZXIgaXMgdG8gYWRkIFZhcmlhYmxlIGRyaXZlciB1bml0DQp0ZXN0Lg0KDQpUaGFua3MN CkxpbWluZw0KPiAtLS0tLdPKvP7Urbz+LS0tLS0NCj4gt6K8/sjLOiBXdSwgSGFvIEEgPGhhby5h Lnd1QGludGVsLmNvbTxtYWlsdG86aGFvLmEud3VAaW50ZWwuY29tPj4NCj4gt6LLzcqxvOQ6IDIw MjDE6jEy1MIxMMjVIDEwOjI1DQo+IMrVvP7IyzogZGV2ZWxAZWRrMi5ncm91cHMuaW88bWFpbHRv OmRldmVsQGVkazIuZ3JvdXBzLmlvPjsgS2lubmV5LCBNaWNoYWVsIEQNCj4gPG1pY2hhZWwuZC5r aW5uZXlAaW50ZWwuY29tPG1haWx0bzptaWNoYWVsLmQua2lubmV5QGludGVsLmNvbT4+DQo+ILOt y806IEJyZXQgQmFya2VsZXcgPGJyZXQuYmFya2VsZXdAbWljcm9zb2Z0LmNvbTxtYWlsdG86YnJl dC5iYXJrZWxld0BtaWNyb3NvZnQuY29tPj47IExpbWluZyBHYW8NCj4gPGdhb2xpbWluZ0BieW9z b2Z0LmNvbS5jbjxtYWlsdG86Z2FvbGltaW5nQGJ5b3NvZnQuY29tLmNuPj4NCj4g1vfM4jogUkU6 IFtlZGsyLWRldmVsXSBbUGF0Y2ggdjIgMS8xXSBNZGVNb2R1bGVQa2cvVmFyaWFibGUvUnVudGlt ZUR4ZToNCj4gUmVzdG9yZSBWYXJpYWJsZSBMb2NrIFByb3RvY29sIGJlaGF2aW9yDQo+DQo+ID4g LS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gPiBGcm9tOiBkZXZlbEBlZGsyLmdyb3Vwcy5p bzxtYWlsdG86ZGV2ZWxAZWRrMi5ncm91cHMuaW8+IDxkZXZlbEBlZGsyLmdyb3Vwcy5pbzxtYWls dG86ZGV2ZWxAZWRrMi5ncm91cHMuaW8+PiBPbiBCZWhhbGYgT2YgTWljaGFlbA0KPiA+IEQgS2lu bmV5DQo+ID4gU2VudDogVGh1cnNkYXksIERlY2VtYmVyIDEwLCAyMDIwIDI6MDYgQU0NCj4gPiBU bzogZGV2ZWxAZWRrMi5ncm91cHMuaW88bWFpbHRvOmRldmVsQGVkazIuZ3JvdXBzLmlvPg0KPiA+ IENjOiBCcmV0IEJhcmtlbGV3IDxicmV0LmJhcmtlbGV3QG1pY3Jvc29mdC5jb208bWFpbHRvOmJy ZXQuYmFya2VsZXdAbWljcm9zb2Z0LmNvbT4+OyBXdSwgSGFvIEENCj4gPiA8aGFvLmEud3VAaW50 ZWwuY29tPG1haWx0bzpoYW8uYS53dUBpbnRlbC5jb20+PjsgTGltaW5nIEdhbyA8Z2FvbGltaW5n QGJ5b3NvZnQuY29tLmNuPG1haWx0bzpnYW9saW1pbmdAYnlvc29mdC5jb20uY24+PjsgQnJldA0K PiA+IEJhcmtlbGV3IDxCcmV0LkJhcmtlbGV3QG1pY3Jvc29mdC5jb208bWFpbHRvOkJyZXQuQmFy a2VsZXdAbWljcm9zb2Z0LmNvbT4+DQo+ID4gU3ViamVjdDogW2VkazItZGV2ZWxdIFtQYXRjaCB2 MiAxLzFdIE1kZU1vZHVsZVBrZy9WYXJpYWJsZS9SdW50aW1lRHhlOg0KPiA+IFJlc3RvcmUgVmFy aWFibGUgTG9jayBQcm90b2NvbCBiZWhhdmlvcg0KPiA+DQo+ID4gRnJvbTogQnJldCBCYXJrZWxl dyA8YnJldC5iYXJrZWxld0BtaWNyb3NvZnQuY29tPG1haWx0bzpicmV0LmJhcmtlbGV3QG1pY3Jv c29mdC5jb20+Pg0KPiA+DQo+ID4gaHR0cHM6Ly9uYW0wNi5zYWZlbGlua3MucHJvdGVjdGlvbi5v dXRsb29rLmNvbS8/dXJsPWh0dHBzJTNBJTJGJTJGYnVnemlsbGEudGlhbm9jb3JlLm9yZyUyRnNo b3dfYnVnLmNnaSUzRmlkJTNEMzExMSZhbXA7ZGF0YT0wNCU3QzAxJTdDYnJldC5iYXJrZWxldyU0 MG1pY3Jvc29mdC5jb20lN0M0MTE1ZmFhYTE2YzY0NzViOGUzNTA4ZDg5Y2JhMDE4OSU3QzcyZjk4 OGJmODZmMTQxYWY5MWFiMmQ3Y2QwMTFkYjQ3JTdDMSU3QzAlN0M2Mzc0MzE2Njk5OTk5NDM2MTYl N0NVbmtub3duJTdDVFdGcGJHWnNiM2Q4ZXlKV0lqb2lNQzR3TGpBd01EQWlMQ0pRSWpvaVYybHVN eklpTENKQlRpSTZJazFoYVd3aUxDSlhWQ0k2TW4wJTNEJTdDMTAwMCZhbXA7c2RhdGE9RFU4RVl0 YXllcFpwc3l4YWpLSzl3MG1RNWtFeFdYRzJBSnZDY3ZWVnkxQSUzRCZhbXA7cmVzZXJ2ZWQ9MA0K PiA+DQo+ID4gVGhlIFZhcmlhYmxlTG9jayBzaGltIGN1cnJlbnRseSBmYWlscyBpZiBjYWxsZWQg dHdpY2UgYmVjYXVzZSB0aGUNCnVuZGVybHlpbmcNCj4gPiBWYXJpYWJsZSBQb2xpY3kgZW5naW5l IHJldHVybnMgYW4gZXJyb3IgaWYgYSBwb2xpY3kgaXMgc2V0IG9uIGFuDQpleGlzdGluZw0KPiB2 YXJpYWJsZS4NCj4gPg0KPiA+IFRoaXMgYnJlYWtzIGV4aXN0aW5nIGNvZGUgd2hpY2ggZXhwZWN0 IGl0IHRvIHNpbGVudGx5IHBhc3MgaWYgYSB2YXJpYWJsZQ0KaXMNCj4gbG9ja2VkDQo+ID4gbXVs dGlwbGUgdGltZXMgKGJlY2F1c2UgaXQgc2hvdWxkICJiZSBsb2NrZWQiKS4NCj4gPg0KPiA+IFJl ZmFjdG9yIHRoZSBzaGltIHRvIGNvbmZpcm0gdGhhdCB0aGUgdmFyaWFibGUgaXMgaW5kZWVkIGxv Y2tlZCBhbmQgdGhlbg0KPiA+IGNoYW5nZSB0aGUgZXJyb3IgdG8gRUZJX1NVQ0NFU1MgYW5kIGdl bmVyYXRlIGEgREVCVUdfRVJST1IgbWVzc2FnZQ0KPiBzbw0KPiA+IHRoZSBkdXBsaWNhdGUgbG9j ayBjYW4gYmUgcmVwb3J0ZWQgaW4gYSBkZWJ1ZyBsb2cgYW5kIHJlbW92ZWQuDQo+DQo+DQo+IEhl bGxvLA0KPg0KPiBJcyBpdCBwb3NzaWJsZSB0byByZXVzZToNCj4gICAgIGEpIEV2YWx1YXRlUG9s aWN5TWF0Y2goKSBhbmQgR2V0QmVzdFBvbGljeU1hdGNoKCkgZnVuY3Rpb25zDQo+ICAgICBiKSBN YWNyb3MgbGlrZSBHRVRfTkVYVF9QT0xJQ1ksIEdFVF9QT0xJQ1lfTkFNRSBhbmQgZXRjLg0KPiB1 bmRlciBNZGVNb2R1bGVQa2dcTGlicmFyeVxWYXJpYWJsZVBvbGljeUxpYiB0byByZWR1Y2UgZHVw bGljYXRlIGNvZGVzPw0KPg0KPiBBIGNvdXBsZSBvZiBtaW5vciBpbmxpbmUgY29tbWVudHMgYmVs b3c6DQo+DQo+DQo+ID4NCj4gPiBBZGQgaG9zdCBiYXNlZCB1bml0IHRlc3RzIGZvciB0aGUgbXVs dGlwbGUgbG9jayBjYXNlIHVzaW5nIFZhcmlhYmxlIExvY2sNCj4gPiBQcm90b2NvbCwgVmFyaWFi bGUgUG9saWN5IFByb3RvY29sLCBhbmQgbWl4ZXMgb2YgVmFyaWFibGUgTG9jayBQcm90b2NvbA0K YW5kDQo+ID4gVmFyaWFibGUgUG9saWN5IFByb3RvY29sLg0KPiA+DQo+ID4gQ2M6IE1pY2hhZWwg RCBLaW5uZXkgPG1pY2hhZWwuZC5raW5uZXlAaW50ZWwuY29tPG1haWx0bzptaWNoYWVsLmQua2lu bmV5QGludGVsLmNvbT4+DQo+ID4gQ2M6IEhhbyBBIFd1IDxoYW8uYS53dUBpbnRlbC5jb208bWFp bHRvOmhhby5hLnd1QGludGVsLmNvbT4+DQo+ID4gQ2M6IExpbWluZyBHYW8gPGdhb2xpbWluZ0Bi eW9zb2Z0LmNvbS5jbjxtYWlsdG86Z2FvbGltaW5nQGJ5b3NvZnQuY29tLmNuPj4NCj4gPiBTaWdu ZWQtb2ZmLWJ5OiBCcmV0IEJhcmtlbGV3IDxCcmV0LkJhcmtlbGV3QG1pY3Jvc29mdC5jb208bWFp bHRvOkJyZXQuQmFya2VsZXdAbWljcm9zb2Z0LmNvbT4+DQo+ID4gLS0tDQo+ID4gIE1kZU1vZHVs ZVBrZy9UZXN0L01kZU1vZHVsZVBrZ0hvc3RUZXN0LmRzYyAgICB8ICAxMSArDQo+ID4gIC4uLi9W YXJpYWJsZUxvY2tSZXF1ZXN0VG9Mb2NrVW5pdFRlc3QuYyAgICAgICB8IDQzNA0KPiArKysrKysr KysrKysrKysrKysNCj4gPiAgLi4uL1ZhcmlhYmxlTG9ja1JlcXVlc3RUb0xvY2tVbml0VGVzdC5p bmYgICAgIHwgIDM2ICsrDQo+ID4gIC4uLi9SdW50aW1lRHhlL1ZhcmlhYmxlTG9ja1JlcXVlc3RU b0xvY2suYyAgICB8IDM2Mw0KPiArKysrKysrKysrKysrLS0NCj4gPiAgNCBmaWxlcyBjaGFuZ2Vk LCA4MDkgaW5zZXJ0aW9ucygrKSwgMzUgZGVsZXRpb25zKC0pICBjcmVhdGUgbW9kZSAxMDA2NDQN Cj4gPiBNZGVNb2R1bGVQa2cvVW5pdmVyc2FsL1ZhcmlhYmxlL1J1bnRpbWVEeGUvUnVudGltZUR4 ZVVuaXRUZXN0L1ZhcmkNCj4gPiBhYmxlTG9ja1JlcXVlc3RUb0xvY2tVbml0VGVzdC5jDQo+ID4g IGNyZWF0ZSBtb2RlIDEwMDY0NA0KPiA+IE1kZU1vZHVsZVBrZy9Vbml2ZXJzYWwvVmFyaWFibGUv UnVudGltZUR4ZS9SdW50aW1lRHhlVW5pdFRlc3QvVmFyaQ0KPiA+IGFibGVMb2NrUmVxdWVzdFRv TG9ja1VuaXRUZXN0LmluZg0KPiA+DQo+ID4gZGlmZiAtLWdpdCBhL01kZU1vZHVsZVBrZy9UZXN0 L01kZU1vZHVsZVBrZ0hvc3RUZXN0LmRzYw0KPiA+IGIvTWRlTW9kdWxlUGtnL1Rlc3QvTWRlTW9k dWxlUGtnSG9zdFRlc3QuZHNjDQo+ID4gaW5kZXggNzJhMTE5ZGI0NTY4Li40ZGE0NjkyYzg0NTEg MTAwNjQ0DQo+ID4gLS0tIGEvTWRlTW9kdWxlUGtnL1Rlc3QvTWRlTW9kdWxlUGtnSG9zdFRlc3Qu ZHNjDQo+ID4gKysrIGIvTWRlTW9kdWxlUGtnL1Rlc3QvTWRlTW9kdWxlUGtnSG9zdFRlc3QuZHNj DQo+ID4gQEAgLTE5LDYgKzE5LDkgQEAgW0RlZmluZXNdDQo+ID4NCj4gPiAgIWluY2x1ZGUgVW5p dFRlc3RGcmFtZXdvcmtQa2cvVW5pdFRlc3RGcmFtZXdvcmtQa2dIb3N0LmRzYy5pbmMNCj4gPg0K PiA+ICtbTGlicmFyeUNsYXNzZXNdDQo+ID4gKyAgU2FmZUludExpYnxNZGVQa2cvTGlicmFyeS9C YXNlU2FmZUludExpYi9CYXNlU2FmZUludExpYi5pbmYNCj4gPiArDQo+ID4gIFtDb21wb25lbnRz XQ0KPiA+DQo+ID4gTWRlTW9kdWxlUGtnL0xpYnJhcnkvRHhlUmVzZXRTeXN0ZW1MaWIvVW5pdFRl c3QvTW9ja1VlZmlSdW50aW1lU2VyDQo+ID4gdmljZXNUYWJsZUxpYi5pbmYNCj4gPg0KPiA+IEBA IC0zMCwzICszMywxMSBAQCBbQ29tcG9uZW50c10NCj4gPg0KPiA+IFJlc2V0U3lzdGVtTGlifE1k ZU1vZHVsZVBrZy9MaWJyYXJ5L0R4ZVJlc2V0U3lzdGVtTGliL0R4ZVJlc2V0U3lzdA0KPiA+IGVt TGliLmluZg0KPiA+DQo+ID4gVWVmaVJ1bnRpbWVTZXJ2aWNlc1RhYmxlTGlifE1kZU1vZHVsZVBr Zy9MaWJyYXJ5L0R4ZVJlc2V0U3lzdGVtTGliLw0KPiA+IFVuaXRUZXN0L01vY2tVZWZpUnVudGlt ZVNlcnZpY2VzVGFibGVMaWIuaW5mDQo+ID4gICAgfQ0KPiA+ICsNCj4gPiArDQo+ID4gTWRlTW9k dWxlUGtnL1VuaXZlcnNhbC9WYXJpYWJsZS9SdW50aW1lRHhlL1J1bnRpbWVEeGVVbml0VGVzdC9W YXJpDQo+ID4gYWJsZUxvY2tSZXF1ZXN0VG9Mb2NrVW5pdFRlc3QuaW5mIHsNCj4gPiArICAgIDxM aWJyYXJ5Q2xhc3Nlcz4NCj4gPiArDQo+ID4NCj4gVmFyaWFibGVQb2xpY3lMaWJ8TWRlTW9kdWxl UGtnL0xpYnJhcnkvVmFyaWFibGVQb2xpY3lMaWIvVmFyaWFibGVQb2xpY3lMaQ0KPiA+IGIuaW5m DQo+ID4gKw0KPiA+DQo+IFZhcmlhYmxlUG9saWN5SGVscGVyTGlifE1kZU1vZHVsZVBrZy9MaWJy YXJ5L1ZhcmlhYmxlUG9saWN5SGVscGVyTGliL1ZhDQo+ID4gcmlhYmxlUG9saWN5SGVscGVyTGli LmluZg0KPiA+ICsgICAgPFBjZHNGaXhlZEF0QnVpbGQ+DQo+ID4gKw0KPiA+ICsNCj4gPiBnRWZp TWRlTW9kdWxlUGtnVG9rZW5TcGFjZUd1aWQuUGNkQWxsb3dWYXJpYWJsZVBvbGljeUVuZm9yY2Vt ZW50RGlzDQo+ID4gYWJsDQo+ID4gKyBlfFRSVUUNCj4gPiArICB9DQo+ID4gZGlmZiAtLWdpdA0K PiA+IGEvTWRlTW9kdWxlUGtnL1VuaXZlcnNhbC9WYXJpYWJsZS9SdW50aW1lRHhlL1J1bnRpbWVE eGVVbml0VGVzdC9WYQ0KPiA+IHJpYWJsZUxvY2tSZXF1ZXN0VG9Mb2NrVW5pdFRlc3QuYw0KPiA+ IGIvTWRlTW9kdWxlUGtnL1VuaXZlcnNhbC9WYXJpYWJsZS9SdW50aW1lRHhlL1J1bnRpbWVEeGVV bml0VGVzdC9WYQ0KPiA+IHJpYWJsZUxvY2tSZXF1ZXN0VG9Mb2NrVW5pdFRlc3QuYw0KPiA+IG5l dyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMDAwMDAwLi4yZjRjNGQyZjc5ZjQN Cj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrDQo+ID4gYi9NZGVNb2R1bGVQa2cvVW5pdmVyc2Fs L1ZhcmlhYmxlL1J1bnRpbWVEeGUvUnVudGltZUR4ZVVuaXRUZXN0L1ZhDQo+ID4gcmkNCj4gPiAr KysgYWJsZUxvY2tSZXF1ZXN0VG9Mb2NrVW5pdFRlc3QuYw0KPiA+IEBAIC0wLDAgKzEsNDM0IEBA DQo+ID4gKy8qKiBAZmlsZQ0KPiA+ICsgIFRoaXMgaXMgYSBob3N0LWJhc2VkIHVuaXQgdGVzdCBm b3IgdGhlIFZhcmlhYmxlTG9ja1JlcXVlc3RUb0xvY2sNCnNoaW0uDQo+ID4gKw0KPiA+ICsgIENv cHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLg0KPiA+ICsgIFNQRFgtTGljZW5zZS1J ZGVudGlmaWVyOiBCU0QtMi1DbGF1c2UtUGF0ZW50DQo+ID4gKw0KPiA+ICsqKi8NCj4gPiArDQo+ ID4gKyNpbmNsdWRlIDxzdGRpby5oPg0KPiA+ICsjaW5jbHVkZSA8c3RyaW5nLmg+DQo+ID4gKyNp bmNsdWRlIDxzdGRhcmcuaD4NCj4gPiArI2luY2x1ZGUgPHN0ZGRlZi5oPg0KPiA+ICsjaW5jbHVk ZSA8c2V0am1wLmg+DQo+ID4gKyNpbmNsdWRlIDxjbW9ja2EuaD4NCj4gPiArDQo+ID4gKyNpbmNs dWRlIDxVZWZpLmg+DQo+ID4gKyNpbmNsdWRlIDxMaWJyYXJ5L0RlYnVnTGliLmg+DQo+ID4gKyNp bmNsdWRlIDxMaWJyYXJ5L0Jhc2VNZW1vcnlMaWIuaD4NCj4gPiArI2luY2x1ZGUgPExpYnJhcnkv TWVtb3J5QWxsb2NhdGlvbkxpYi5oPiAjaW5jbHVkZQ0KPiA+ICs8TGlicmFyeS9Vbml0VGVzdExp Yi5oPiAjaW5jbHVkZSA8TGlicmFyeS9WYXJpYWJsZVBvbGljeUxpYi5oPiAjaW5jbHVkZQ0KPiA+ ICs8TGlicmFyeS9WYXJpYWJsZVBvbGljeUhlbHBlckxpYi5oPg0KPiA+ICsNCj4gPiArI2luY2x1 ZGUgPFByb3RvY29sL1ZhcmlhYmxlTG9jay5oPg0KPiA+ICsNCj4gPiArI2RlZmluZSBVTklUX1RF U1RfTkFNRSAgICAgICAgIlZhclBvbC9WYXJMb2NrIFNoaW0gVW5pdCBUZXN0Ig0KPiA+ICsjZGVm aW5lIFVOSVRfVEVTVF9WRVJTSU9OICAgICAiMS4wIg0KPiA+ICsNCj4gPiArLy8vPT09IENPREUg VU5ERVIgVEVTVA0KPiA+ICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT0NCj4gPiA9PT09PT09PT09PT09PQ0KPiA+ICs9PT09DQo+ID4gKw0K PiA+ICtFRklfU1RBVFVTDQo+ID4gK0VGSUFQSQ0KPiA+ICtWYXJpYWJsZUxvY2tSZXF1ZXN0VG9M b2NrICgNCj4gPiArICBJTiBDT05TVCBFREtJSV9WQVJJQUJMRV9MT0NLX1BST1RPQ09MICAqVGhp cywNCj4gPiArICBJTiAgICAgICBDSEFSMTYgICAgICAgICAgICAgICAgICAgICAgICAqVmFyaWFi bGVOYW1lLA0KPiA+ICsgIElOICAgICAgIEVGSV9HVUlEICAgICAgICAgICAgICAgICAgICAgICpW ZW5kb3JHdWlkDQo+ID4gKyAgKTsNCj4gPiArDQo+ID4gKy8vLz09PSBURVNUIERBVEENCj4gPiAr PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 DQo+ID4gPT09PT09PT09PT09PT0NCj4gPiArPT09PT09PT09PT0NCj4gPiArDQo+ID4gKy8vDQo+ ID4gKy8vIFRlc3QgR1VJRCAxIHtGOTU1QkEyRC00QTJDLTQ4MEMtQkZEMS0zQ0M1MjI2MTA1OTJ9 DQo+ID4gKy8vDQo+ID4gK0VGSV9HVUlEICBtVGVzdEd1aWQxID0gew0KPiA+ICsgIDB4Zjk1NWJh MmQsIDB4NGEyYywgMHg0ODBjLCB7MHhiZiwgMHhkMSwgMHgzYywgMHhjNSwgMHgyMiwgMHg2MSwg MHg1LA0KPiA+ICsweDkyfSB9Ow0KPiA+ICsNCj4gPiArLy8NCj4gPiArLy8gVGVzdCBHVUlEIDIg ezJERUE3OTlFLTVFNzMtNDNCOS04NzBFLUM5NDVDRTgyQUYzQX0NCj4gPiArLy8NCj4gPiArRUZJ X0dVSUQgIG1UZXN0R3VpZDIgPSB7DQo+ID4gKyAgMHgyZGVhNzk5ZSwgMHg1ZTczLCAweDQzYjks IHsweDg3LCAweGUsIDB4YzksIDB4NDUsIDB4Y2UsIDB4ODIsIDB4YWYsDQo+ID4gKzB4M2F9IH07 DQo+ID4gKw0KPiA+ICsvLw0KPiA+ICsvLyBUZXN0IEdVSUQgMyB7Njk4QTJCRkQtQTYxNi00ODJE LUI4OEMtNzEwMEJENjY4MkE5fQ0KPiA+ICsvLw0KPiA+ICtFRklfR1VJRCAgbVRlc3RHdWlkMyA9 IHsNCj4gPiArICAweDY5OGEyYmZkLCAweGE2MTYsIDB4NDgyZCwgezB4YjgsIDB4OGMsIDB4NzEs IDB4MCwgMHhiZCwgMHg2NiwgMHg4MiwNCj4gPiArMHhhOX0gfTsNCj4gPiArDQo+ID4gKyNkZWZp bmUgVEVTVF9WQVJfMV9OQU1FICAgICAgICAgICAgICBMIlRlc3RWYXIxIg0KPiA+ICsjZGVmaW5l IFRFU1RfVkFSXzJfTkFNRSAgICAgICAgICAgICAgTCJUZXN0VmFyMiINCj4gPiArI2RlZmluZSBU RVNUX1ZBUl8zX05BTUUgICAgICAgICAgICAgIEwiVGVzdFZhcjMiDQo+ID4gKw0KPiA+ICsjZGVm aW5lIFRFU1RfUE9MSUNZX0FUVFJJQlVURVNfTlVMTCAgMA0KPiA+ICsjZGVmaW5lIFRFU1RfUE9M SUNZX01JTl9TSVpFX05VTEwgICAgMA0KPiA+ICsjZGVmaW5lIFRFU1RfUE9MSUNZX01BWF9TSVpF X05VTEwgICAgTUFYX1VJTlQzMg0KPiA+ICsNCj4gPiArI2RlZmluZSBURVNUX1BPTElDWV9NSU5f U0laRV8xMCAgICAgIDEwDQo+ID4gKyNkZWZpbmUgVEVTVF9QT0xJQ1lfTUFYX1NJWkVfMjAwICAg ICAyMDANCj4gPiArDQo+ID4gKy8vLz09PSBIRUxQRVIgRlVOQ1RJT05TDQo+ID4gKz09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KPiA+ID09 PT09PT09PT09PT09DQo+ID4gKz09PT0NCj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgIE1vY2tlZCB2 ZXJzaW9uIG9mIEdldFZhcmlhYmxlLCBmb3IgdGVzdGluZy4NCj4gPiArDQo+ID4gKyAgQHBhcmFt ICBWYXJpYWJsZU5hbWUNCj4gPiArICBAcGFyYW0gIFZlbmRvckd1aWQNCj4gPiArICBAcGFyYW0g IEF0dHJpYnV0ZXMNCj4gPiArICBAcGFyYW0gIERhdGFTaXplDQo+ID4gKyAgQHBhcmFtICBEYXRh DQo+ID4gKyoqLw0KPiA+ICtFRklfU1RBVFVTDQo+ID4gK0VGSUFQSQ0KPiA+ICtTdHViR2V0VmFy aWFibGVOdWxsICgNCj4gPiArICBJTiAgICAgQ0hBUjE2ICAgICpWYXJpYWJsZU5hbWUsDQo+ID4g KyAgSU4gICAgIEVGSV9HVUlEICAqVmVuZG9yR3VpZCwNCj4gPiArICBPVVQgICAgVUlOVDMyICAg ICpBdHRyaWJ1dGVzLCAgT1BUSU9OQUwNCj4gPiArICBJTiBPVVQgVUlOVE4gICAgICpEYXRhU2l6 ZSwNCj4gPiArICBPVVQgICAgVk9JRCAgICAgICpEYXRhICAgICAgICAgT1BUSU9OQUwNCj4gPiAr ICApDQo+ID4gK3sNCj4gPiArICBVSU5UMzIgICAgICBNb2NrZWRBdHRyOw0KPiA+ICsgIFVJTlRO ICAgICAgIE1vY2tlZERhdGFTaXplOw0KPiA+ICsgIFZPSUQgICAgICAgICpNb2NrZWREYXRhOw0K PiA+ICsgIEVGSV9TVEFUVVMgIE1vY2tlZFJldHVybjsNCj4gPiArDQo+ID4gKyAgY2hlY2tfZXhw ZWN0ZWRfcHRyIChWYXJpYWJsZU5hbWUpOw0KPiA+ICsgIGNoZWNrX2V4cGVjdGVkX3B0ciAoVmVu ZG9yR3VpZCk7DQo+ID4gKyAgY2hlY2tfZXhwZWN0ZWRfcHRyIChEYXRhU2l6ZSk7DQo+ID4gKw0K PiA+ICsgIE1vY2tlZEF0dHIgICAgID0gKFVJTlQzMiltb2NrKCk7DQo+ID4gKyAgTW9ja2VkRGF0 YVNpemUgPSAoVUlOVE4pbW9jaygpOw0KPiA+ICsgIE1vY2tlZERhdGEgICAgID0gKFZPSUQqKShV SU5UTiltb2NrKCk7DQo+ID4gKyAgTW9ja2VkUmV0dXJuICAgPSAoRUZJX1NUQVRVUyltb2NrKCk7 DQo+ID4gKw0KPiA+ICsgIGlmIChBdHRyaWJ1dGVzICE9IE5VTEwpIHsNCj4gPiArICAgICpBdHRy aWJ1dGVzID0gTW9ja2VkQXR0cjsNCj4gPiArICB9DQo+ID4gKyAgaWYgKERhdGEgIT0gTlVMTCAm JiAhRUZJX0VSUk9SIChNb2NrZWRSZXR1cm4pKSB7DQo+ID4gKyAgICBDb3B5TWVtIChEYXRhLCBN b2NrZWREYXRhLCBNb2NrZWREYXRhU2l6ZSk7ICB9DQo+ID4gKw0KPiA+ICsgICpEYXRhU2l6ZSA9 IE1vY2tlZERhdGFTaXplOw0KPiA+ICsNCj4gPiArICByZXR1cm4gTW9ja2VkUmV0dXJuOw0KPiA+ ICt9DQo+ID4gKw0KPiA+ICsvLw0KPiA+ICsvLyBBbnl0aGluZyB5b3UgdGhpbmsgbWlnaHQgYmUg aGVscGZ1bCB0aGF0IGlzbid0IGEgdGVzdCBpdHNlbGYuDQo+ID4gKy8vDQo+ID4gKw0KPiA+ICsv KioNCj4gPiArICBUaGlzIGlzIGEgY29tbW9uIHNldHVwIGZ1bmN0aW9uIHRoYXQgd2lsbCBlbnN1 cmUgdGhlIGxpYnJhcnkgaXMNCj4gPiArYWx3YXlzDQo+ID4gKyAgaW5pdGlhbGl6ZWQgd2l0aCB0 aGUgc3R1YmJlZCBHZXRWYXJpYWJsZS4NCj4gPiArDQo+ID4gKyAgTm90IHVzZWQgYnkgYWxsIHRl c3QgY2FzZXMsIGJ1dCBieSBtb3N0Lg0KPiA+ICsNCj4gPiArICBAcGFyYW1baW5dICBDb250ZXh0 ICBVbml0IHRlc3QgY2FzZSBjb250ZXh0ICoqLyBTVEFUSUMNCj4gPiArVU5JVF9URVNUX1NUQVRV UyBFRklBUEkgTGliSW5pdE1vY2tlZCAoDQo+ID4gKyAgSU4gVU5JVF9URVNUX0NPTlRFWFQgIENv bnRleHQNCj4gPiArICApDQo+ID4gK3sNCj4gPiArICByZXR1cm4gRUZJX0VSUk9SIChJbml0VmFy aWFibGVQb2xpY3lMaWIgKFN0dWJHZXRWYXJpYWJsZU51bGwpKSA/DQo+ID4gK1VOSVRfVEVTVF9F UlJPUl9QUkVSRVFVSVNJVEVfTk9UX01FVCA6IFVOSVRfVEVTVF9QQVNTRUQ7IH0NCj4gPiArDQo+ ID4gKy8qKg0KPiA+ICsgIENvbW1vbiBjbGVhbnVwIGZ1bmN0aW9uIHRvIG1ha2Ugc3VyZSB0aGF0 IHRoZSBsaWJyYXJ5IGlzIGFsd2F5cw0KPiA+ICtkZS1pbml0aWFsaXplZA0KPiA+ICsgIHByaW9y IHRvIHRoZSBuZXh0IHRlc3QgY2FzZS4NCj4gPiArDQo+ID4gKyAgQHBhcmFtW2luXSAgQ29udGV4 dCAgVW5pdCB0ZXN0IGNhc2UgY29udGV4dCAqKi8gU1RBVElDIFZPSUQgRUZJQVBJDQo+ID4gK0xp YkNsZWFudXAgKA0KPiA+ICsgIElOIFVOSVRfVEVTVF9DT05URVhUICBDb250ZXh0DQo+ID4gKyAg KQ0KPiA+ICt7DQo+ID4gKyAgRGVpbml0VmFyaWFibGVQb2xpY3lMaWIoKTsNCj4gPiArfQ0KPiA+ ICsNCj4gPiArLy8vPT09IFRFU1QgQ0FTRVMNCj4gPiArPT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQo+ID4gPT09PT09PT09PT09PT0NCj4g PiArPT09PT09PT09PQ0KPiA+ICsNCj4gPiArLy8vPT09PT0gU0hJTSBTVUlURQ0KPiA+ICs9PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCj4g PiA9PQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAgVGVzdCBDYXNlIHRoYXQgbG9ja3MgYSBzaW5n bGUgdmFyaWFibGUgdXNpbmcgdGhlIFZhcmlhYmxlIExvY2sNClByb3RvY29sLg0KPiA+ICsgIFRo ZSBjYWxsIGlzIGV4cGVjdGVkIHRvIHN1Y2NlZWQuDQo+ID4gKw0KPiA+ICsgIEBwYXJhbVtpbl0g IENvbnRleHQgIFVuaXQgdGVzdCBjYXNlIGNvbnRleHQgKiovIFVOSVRfVEVTVF9TVEFUVVMNCj4g PiArRUZJQVBJIExvY2tpbmdXaXRob3V0QW55UG9saWNpZXNTaG91bGRTdWNjZWVkICgNCj4gPiAr ICBJTiBVTklUX1RFU1RfQ09OVEVYVCAgQ29udGV4dA0KPiA+ICsgICkNCj4gPiArew0KPiA+ICsg IEVGSV9TVEFUVVMgIFN0YXR1czsNCj4gPiArDQo+ID4gKyAgU3RhdHVzID0gVmFyaWFibGVMb2Nr UmVxdWVzdFRvTG9jayAoTlVMTCwgVEVTVF9WQVJfMV9OQU1FLA0KPiA+ICsgJm1UZXN0R3VpZDEp OyAgVVRfQVNTRVJUX05PVF9FRklfRVJST1IgKFN0YXR1cyk7DQo+ID4gKw0KPiA+ICsgIHJldHVy biBVTklUX1RFU1RfUEFTU0VEOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICBUZXN0 IENhc2UgdGhhdCBsb2NrcyB0aGUgc2FtZSB2YXJpYWJsZSB0d2ljZSB1c2luZyB0aGUgVmFyaWFi bGUgTG9jaw0KPiBQcm9jb2wuDQo+DQo+DQo+IE1pbm9yIGNvbW1lbnQsIHR5cG8gZm9yICdQcm9j b2wnIC0+ICdQcm90b2NvbCcNCj4NCj4NCj4gPiArICBCb3RoIGNhbGxzIGFyZSBleHBlY3RlZCB0 byBzdWNjZWVkLg0KPiA+ICsNCj4gPiArICBAcGFyYW1baW5dICBDb250ZXh0ICBVbml0IHRlc3Qg Y2FzZSBjb250ZXh0DQo+ID4gKyAgKiovDQo+ID4gK1VOSVRfVEVTVF9TVEFUVVMNCj4gPiArRUZJ QVBJDQo+ID4gK0xvY2tpbmdUd2ljZVNob3VsZFN1Y2NlZWQgKA0KPiA+ICsgIElOIFVOSVRfVEVT VF9DT05URVhUICBDb250ZXh0DQo+ID4gKyAgKQ0KPiA+ICt7DQo+ID4gKyAgRUZJX1NUQVRVUyAg U3RhdHVzOw0KPiA+ICsNCj4gPiArICBTdGF0dXMgPSBWYXJpYWJsZUxvY2tSZXF1ZXN0VG9Mb2Nr IChOVUxMLCBURVNUX1ZBUl8xX05BTUUsDQo+ID4gKyAmbVRlc3RHdWlkMSk7ICBVVF9BU1NFUlRf Tk9UX0VGSV9FUlJPUiAoU3RhdHVzKTsNCj4gPiArDQo+ID4gKyAgU3RhdHVzID0gVmFyaWFibGVM b2NrUmVxdWVzdFRvTG9jayAoTlVMTCwgVEVTVF9WQVJfMV9OQU1FLA0KPiA+ICsgJm1UZXN0R3Vp ZDEpOyAgVVRfQVNTRVJUX05PVF9FRklfRVJST1IgKFN0YXR1cyk7DQo+ID4gKw0KPiA+ICsgIHJl dHVybiBVTklUX1RFU1RfUEFTU0VEOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICBU ZXN0IENhc2UgdGhhdCBsb2NrcyBhIHZhcmlhYmxlIHVzaW5nIHRoZSBWYXJpYWJsZSBQb2xpY3kg UHJvdG9jb2wNCj4gPiArdGhlbiBsb2Nrcw0KPiA+ICsgIHRoZSBzYW1lIHZhcmlhYmxlIHVzaW5n IHRoZSBWYXJpYWJsZSBMb2NrIFByb3RvY29sLg0KPiA+ICsgIEJvdGggY2FsbHMgYXJlIGV4cGVj dGVkIHRvIHN1Y2NlZWQuDQo+ID4gKw0KPiA+ICsgIEBwYXJhbVtpbl0gIENvbnRleHQgIFVuaXQg dGVzdCBjYXNlIGNvbnRleHQNCj4gPiArICAqKi8NCj4gPiArVU5JVF9URVNUX1NUQVRVUw0KPiA+ ICtFRklBUEkNCj4gPiArTG9ja2luZ0FMb2NrZWRWYXJpYWJsZVNob3VsZFN1Y2NlZWQgKA0KPiA+ ICsgIElOIFVOSVRfVEVTVF9DT05URVhUICBDb250ZXh0DQo+ID4gKyAgKQ0KPiA+ICt7DQo+ID4g KyAgRUZJX1NUQVRVUyAgICAgICAgICAgICBTdGF0dXM7DQo+ID4gKyAgVkFSSUFCTEVfUE9MSUNZ X0VOVFJZICAqTmV3RW50cnk7DQo+ID4gKw0KPiA+ICsgIC8vDQo+ID4gKyAgLy8gQ3JlYXRlIGEg dmFyaWFibGUgcG9saWN5IHRoYXQgbG9ja3MgdGhlIHZhcmlhYmxlLg0KPiA+ICsgIC8vDQo+ID4g KyAgU3RhdHVzID0gQ3JlYXRlQmFzaWNWYXJpYWJsZVBvbGljeSAoDQo+ID4gKyAgICAgICAgICAg ICAmbVRlc3RHdWlkMSwNCj4gPiArICAgICAgICAgICAgIFRFU1RfVkFSXzFfTkFNRSwNCj4gPiAr ICAgICAgICAgICAgIFRFU1RfUE9MSUNZX01JTl9TSVpFX05VTEwsDQo+ID4gKyAgICAgICAgICAg ICBURVNUX1BPTElDWV9NQVhfU0laRV8yMDAsDQo+ID4gKyAgICAgICAgICAgICBURVNUX1BPTElD WV9BVFRSSUJVVEVTX05VTEwsDQo+ID4gKyAgICAgICAgICAgICBURVNUX1BPTElDWV9BVFRSSUJV VEVTX05VTEwsDQo+ID4gKyAgICAgICAgICAgICBWQVJJQUJMRV9QT0xJQ1lfVFlQRV9MT0NLX05P VywNCj4gPiArICAgICAgICAgICAgICZOZXdFbnRyeQ0KPiA+ICsgICAgICAgICAgICAgKTsNCj4g PiArICBVVF9BU1NFUlRfTk9UX0VGSV9FUlJPUiAoU3RhdHVzKTsNCj4gPiArDQo+ID4gKyAgLy8N Cj4gPiArICAvLyBSZWdpc3RlciB0aGUgbmV3IHBvbGljeS4NCj4gPiArICAvLw0KPiA+ICsgIFN0 YXR1cyA9IFJlZ2lzdGVyVmFyaWFibGVQb2xpY3kgKE5ld0VudHJ5KTsNCj4gPiArDQo+ID4gKyAg U3RhdHVzID0gVmFyaWFibGVMb2NrUmVxdWVzdFRvTG9jayAoTlVMTCwgVEVTVF9WQVJfMV9OQU1F LA0KPiA+ICsgJm1UZXN0R3VpZDEpOyAgVVRfQVNTRVJUX05PVF9FRklfRVJST1IgKFN0YXR1cyk7 DQo+ID4gKw0KPiA+ICsgIEZyZWVQb29sIChOZXdFbnRyeSk7DQo+ID4gKw0KPiA+ICsgIHJldHVy biBVTklUX1RFU1RfUEFTU0VEOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICBUZXN0 IENhc2UgdGhhdCBsb2NrcyBhIHZhcmlhYmxlIHVzaW5nIHRoZSBWYXJpYWJsZSBQb2xpY3kgUHJv dG9jb2wNCj4gPiArd2l0aCBhDQo+ID4gKyAgcG9saWN5IG90aGVyIHRoYW4gTE9DS19OT1cgdGhl biBhdHRlbXB0cyB0byBsb2NrIHRoZSBzYW1lIHZhcmlhYmxlDQo+ID4gK3VzaW5nIHRoZQ0KPiA+ ICsgIFZhcmlhYmxlIExvY2sgUHJvdG9jb2wuICBUaGUgY2FsbCB0byBWYXJpYWJsZSBQb2xpY3kg aXMgZXhwZWN0ZWQgdG8NCj4gPiArc3VjY2NlZA0KPg0KPg0KPiAnc3VjY2NlZCcgLT4gJ3N1Y2Nl ZWQnDQo+DQo+DQo+ID4gKyAgYW5kIHRoZSBjYWxsIHRvIFZhcmlhYmxlIExvY2sgaXMgZXhwZWN0 ZWQgdG8gZmFpbC4NCj4gPiArDQo+ID4gKyAgQHBhcmFtW2luXSAgQ29udGV4dCAgVW5pdCB0ZXN0 IGNhc2UgY29udGV4dA0KPiA+ICsgICoqLw0KPiA+ICtVTklUX1RFU1RfU1RBVFVTDQo+ID4gK0VG SUFQSQ0KPiA+ICtMb2NraW5nQW5VbmxvY2tlZFZhcmlhYmxlU2hvdWxkRmFpbCAoDQo+ID4gKyAg SU4gVU5JVF9URVNUX0NPTlRFWFQgICAgICBDb250ZXh0DQo+ID4gKyAgKQ0KPiA+ICt7DQo+ID4g KyAgRUZJX1NUQVRVUyAgICAgICAgICAgICAgICBTdGF0dXM7DQo+ID4gKyAgVkFSSUFCTEVfUE9M SUNZX0VOVFJZICAgICAqTmV3RW50cnk7DQo+ID4gKw0KPiA+ICsgIC8vIENyZWF0ZSBhIHZhcmlh YmxlIHBvbGljeSB0aGF0IGxvY2tzIHRoZSB2YXJpYWJsZS4NCj4gPiArICBTdGF0dXMgPSBDcmVh dGVWYXJTdGF0ZVZhcmlhYmxlUG9saWN5ICgmbVRlc3RHdWlkMSwNCj4gPiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBURVNUX1ZBUl8xX05BTUUsDQo+ID4gKw0KPiBU RVNUX1BPTElDWV9NSU5fU0laRV9OVUxMLA0KPiA+ICsNCj4gVEVTVF9QT0xJQ1lfTUFYX1NJWkVf MjAwLA0KPiA+ICsNCj4gVEVTVF9QT0xJQ1lfQVRUUklCVVRFU19OVUxMLA0KPiA+ICsNCj4gVEVT VF9QT0xJQ1lfQVRUUklCVVRFU19OVUxMLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICZtVGVzdEd1aWQyLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIDEsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgVEVTVF9WQVJfMl9OQU1FLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICZOZXdFbnRyeSk7DQo+ID4gKyBVVF9BU1NFUlRfTk9UX0VGSV9F UlJPUiAoU3RhdHVzKTsNCj4gPiArDQo+ID4gKyAgLy8gUmVnaXN0ZXIgdGhlIG5ldyBwb2xpY3ku DQo+ID4gKyAgU3RhdHVzID0gUmVnaXN0ZXJWYXJpYWJsZVBvbGljeSAoTmV3RW50cnkpOw0KPiA+ ICsNCj4gPiArICBTdGF0dXMgPSBWYXJpYWJsZUxvY2tSZXF1ZXN0VG9Mb2NrIChOVUxMLCBURVNU X1ZBUl8xX05BTUUsDQo+ID4gKyAmbVRlc3RHdWlkMSk7ICBVVF9BU1NFUlRfVFJVRSAoRUZJX0VS Uk9SIChTdGF0dXMpKTsNCj4gPiArDQo+ID4gKyAgRnJlZVBvb2wgKE5ld0VudHJ5KTsNCj4gPiAr DQo+ID4gKyAgcmV0dXJuIFVOSVRfVEVTVF9QQVNTRUQ7DQo+ID4gK30NCj4gPiArDQo+ID4gKy8q Kg0KPiA+ICsgIFRlc3QgQ2FzZSB0aGF0IGxvY2tzIGEgdmFyaWFibGUgdXNpbmcgVmFyaWFibGUg TG9jayBQcm90b2NvbCBQb2xpY3kNCj4gPiArUHJvdG9jb2wNCj4gPiArICB0aGVuIGFuZCB0aGVu IGF0dGVtcHRzIHRvIGxvY2sgdGhlIHNhbWUgdmFyaWFibGUgdXNpbmcgdGhlIFZhcmlhYmxlDQo+ ID4gK1BvbGljeQ0KPiA+ICsgIFByb3RvY29sLiAgVGhlIGNhbGwgdG8gVmFyaWFibGUgTG9jayBp cyBleHBlY3RlZCB0byBzdWNjY2VkIGFuZCB0aGUNCj4NCj4NCj4gJ3N1Y2NjZWQnIC0+ICdzdWNj ZWVkJw0KPg0KPiBCZXN0IFJlZ2FyZHMsDQo+IEhhbyBXdQ0KPg0KPg0KPiA+ICtjYWxsIHRvDQo+ ID4gKyAgVmFyaWFibGUgUG9saWN5IGlzIGV4cGVjdGVkIHRvIGZhaWwuDQo+ID4gKw0KPiA+ICsg IEBwYXJhbVtpbl0gIENvbnRleHQgIFVuaXQgdGVzdCBjYXNlIGNvbnRleHQNCj4gPiArICAqKi8N Cj4gPiArVU5JVF9URVNUX1NUQVRVUw0KPiA+ICtFRklBUEkNCj4gPiArU2V0dGluZ1BvbGljeUZv ckFMb2NrZWRWYXJpYWJsZVNob3VsZEZhaWwgKA0KPiA+ICsgIElOIFVOSVRfVEVTVF9DT05URVhU ICAgICAgQ29udGV4dA0KPiA+ICsgICkNCj4gPiArew0KPiA+ICsgIEVGSV9TVEFUVVMgICAgICAg ICAgICAgICAgU3RhdHVzOw0KPiA+ICsgIFZBUklBQkxFX1BPTElDWV9FTlRSWSAgICAgKk5ld0Vu dHJ5Ow0KPiA+ICsNCj4gPiArICAvLyBMb2NrIHRoZSB2YXJpYWJsZS4NCj4gPiArICBTdGF0dXMg PSBWYXJpYWJsZUxvY2tSZXF1ZXN0VG9Mb2NrIChOVUxMLCBURVNUX1ZBUl8xX05BTUUsDQo+ID4g KyAmbVRlc3RHdWlkMSk7ICBVVF9BU1NFUlRfTk9UX0VGSV9FUlJPUiAoU3RhdHVzKTsNCj4gPiAr DQo+ID4gKyAgLy8gQ3JlYXRlIGEgdmFyaWFibGUgcG9saWN5IHRoYXQgbG9ja3MgdGhlIHZhcmlh YmxlLg0KPiA+ICsgIFN0YXR1cyA9IENyZWF0ZVZhclN0YXRlVmFyaWFibGVQb2xpY3kgKCZtVGVz dEd1aWQxLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRF U1RfVkFSXzFfTkFNRSwNCj4gPiArDQo+IFRFU1RfUE9MSUNZX01JTl9TSVpFX05VTEwsDQo+ID4g Kw0KPiBURVNUX1BPTElDWV9NQVhfU0laRV8yMDAsDQo+ID4gKw0KPiBURVNUX1BPTElDWV9BVFRS SUJVVEVTX05VTEwsDQo+ID4gKw0KPiBURVNUX1BPTElDWV9BVFRSSUJVVEVTX05VTEwsDQo+ID4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1UZXN0R3VpZDIsDQo+ ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwNCj4gPiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBURVNUX1ZBUl8yX05BTUUsDQo+ ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk5ld0VudHJ5KTsN Cj4gPiArIFVUX0FTU0VSVF9OT1RfRUZJX0VSUk9SIChTdGF0dXMpOw0KPiA+ICsNCj4gPiArICAv LyBSZWdpc3RlciB0aGUgbmV3IHBvbGljeS4NCj4gPiArICBTdGF0dXMgPSBSZWdpc3RlclZhcmlh YmxlUG9saWN5IChOZXdFbnRyeSk7ICBVVF9BU1NFUlRfVFJVRQ0KPiA+ICsgKEVGSV9FUlJPUiAo U3RhdHVzKSk7DQo+ID4gKw0KPiA+ICsgIEZyZWVQb29sIChOZXdFbnRyeSk7DQo+ID4gKw0KPiA+ ICsgIHJldHVybiBVTklUX1RFU1RfUEFTU0VEOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4g PiArICBNYWluIGVudHJ5IHBvaW50IHRvIHRoaXMgdW5pdCB0ZXN0IGFwcGxpY2F0aW9uLg0KPiA+ ICsNCj4gPiArICBTZXRzIHVwIGFuZCBydW5zIHRoZSB0ZXN0IHN1aXRlcy4NCj4gPiArKiovDQo+ ID4gK1ZPSUQNCj4gPiArRUZJQVBJDQo+ID4gK1VuaXRUZXN0TWFpbiAoDQo+ID4gKyAgVk9JRA0K PiA+ICsgICkNCj4gPiArew0KPiA+ICsgIEVGSV9TVEFUVVMgICAgICAgICAgICAgICAgICBTdGF0 dXM7DQo+ID4gKyAgVU5JVF9URVNUX0ZSQU1FV09SS19IQU5ETEUgIEZyYW1ld29yazsNCj4gPiAr ICBVTklUX1RFU1RfU1VJVEVfSEFORExFICAgICAgU2hpbVRlc3RzOw0KPiA+ICsNCj4gPiArICBG cmFtZXdvcmsgPSBOVUxMOw0KPiA+ICsNCj4gPiArICBERUJVRyAoKERFQlVHX0lORk8sICIlYSB2 JWFcbiIsIFVOSVRfVEVTVF9OQU1FLA0KPiA+IFVOSVRfVEVTVF9WRVJTSU9OKSk7DQo+ID4gKw0K PiA+ICsgIC8vDQo+ID4gKyAgLy8gU3RhcnQgc2V0dGluZyB1cCB0aGUgdGVzdCBmcmFtZXdvcmsg Zm9yIHJ1bm5pbmcgdGhlIHRlc3RzLg0KPiA+ICsgIC8vDQo+ID4gKyAgU3RhdHVzID0gSW5pdFVu aXRUZXN0RnJhbWV3b3JrICgmRnJhbWV3b3JrLCBVTklUX1RFU1RfTkFNRSwNCj4gPiArIGdFZmlD YWxsZXJCYXNlTmFtZSwgVU5JVF9URVNUX1ZFUlNJT04pOyAgaWYgKEVGSV9FUlJPUiAoU3RhdHVz KSkgew0KPiA+ICsgICAgREVCVUcgKChERUJVR19FUlJPUiwgIkZhaWxlZCBpbiBJbml0VW5pdFRl c3RGcmFtZXdvcmsuIFN0YXR1cw0KPiA+ID0gJXJcbiIsIFN0YXR1cykpOw0KPiA+ICsgICAgZ290 byBFWElUOw0KPiA+ICsgIH0NCj4gPiArDQo+ID4gKyAgLy8NCj4gPiArICAvLyBBZGQgYWxsIHRl c3Qgc3VpdGVzIGFuZCB0ZXN0cy4NCj4gPiArICAvLw0KPiA+ICsgIFN0YXR1cyA9IENyZWF0ZVVu aXRUZXN0U3VpdGUgKA0KPiA+ICsgICAgICAgICAgICAgJlNoaW1UZXN0cywgRnJhbWV3b3JrLA0K PiA+ICsgICAgICAgICAgICAgIlZhcmlhYmxlIExvY2sgU2hpbSBUZXN0cyIsICJWYXJQb2xpY3ku VmFyTG9ja1NoaW0iLCBOVUxMLA0KPiBOVUxMDQo+ID4gKyAgICAgICAgICAgICApOw0KPiA+ICsg IGlmIChFRklfRVJST1IgKFN0YXR1cykpIHsNCj4gPiArICAgIERFQlVHICgoREVCVUdfRVJST1Is ICJGYWlsZWQgaW4gQ3JlYXRlVW5pdFRlc3RTdWl0ZSBmb3INCj4gPiBTaGltVGVzdHNcbiIpKTsN Cj4gPiArICAgIFN0YXR1cyA9IEVGSV9PVVRfT0ZfUkVTT1VSQ0VTOw0KPiA+ICsgICAgZ290byBF WElUOw0KPiA+ICsgIH0NCj4gPiArICBBZGRUZXN0Q2FzZSAoDQo+ID4gKyAgICBTaGltVGVzdHMs DQo+ID4gKyAgICAiTG9ja2luZyBhIHZhcmlhYmxlIHdpdGggbm8gbWF0Y2hpbmcgcG9saWNpZXMg c2hvdWxkIGFsd2F5cyB3b3JrIiwNCj4gPiAiRW1wdHlQb2xpY2llcyIsDQo+ID4gKyAgICBMb2Nr aW5nV2l0aG91dEFueVBvbGljaWVzU2hvdWxkU3VjY2VlZCwgTGliSW5pdE1vY2tlZCwNCj4gTGli Q2xlYW51cCwNCj4gPiBOVUxMDQo+ID4gKyAgICApOw0KPiA+ICsgIEFkZFRlc3RDYXNlICgNCj4g PiArICAgIFNoaW1UZXN0cywNCj4gPiArICAgICJMb2NraW5nIGEgdmFyaWFibGUgdHdpY2Ugc2hv dWxkIGFsd2F5cyB3b3JrIiwgIkRvdWJsZUxvY2siLA0KPiA+ICsgICAgTG9ja2luZ1R3aWNlU2hv dWxkU3VjY2VlZCwgTGliSW5pdE1vY2tlZCwgTGliQ2xlYW51cCwgTlVMTA0KPiA+ICsgICAgKTsN Cj4gPiArICBBZGRUZXN0Q2FzZSAoDQo+ID4gKyAgICBTaGltVGVzdHMsDQo+ID4gKyAgICAiTG9j a2luZyBhIHZhcmlhYmxlIHRoYXQncyBhbHJlYWR5IGxvY2tlZCBieSBhbm90aGVyIHBvbGljeSBz aG91bGQNCj4gd29yayIsDQo+ID4gIkxvY2tBZnRlclBvbGljeSIsDQo+ID4gKyAgICBMb2NraW5n QUxvY2tlZFZhcmlhYmxlU2hvdWxkU3VjY2VlZCwgTGliSW5pdE1vY2tlZCwgTGliQ2xlYW51cCwN Cj4gTlVMTA0KPiA+ICsgICAgKTsNCj4gPiArICBBZGRUZXN0Q2FzZSAoDQo+ID4gKyAgICBTaGlt VGVzdHMsDQo+ID4gKyAgICAiTG9ja2luZyBhIHZhcmlhYmxlIHRoYXQgYWxyZWFkeSBoYXMgYW4g dW5sb2NrZWQgcG9saWN5IHNob3VsZA0KZmFpbCIsDQo+ID4gIkxvY2tBZnRlclVubG9ja2VkUG9s aWN5IiwNCj4gPiArICAgIExvY2tpbmdBblVubG9ja2VkVmFyaWFibGVTaG91bGRGYWlsLCBMaWJJ bml0TW9ja2VkLCBMaWJDbGVhbnVwLA0KPiBOVUxMDQo+ID4gKyAgICApOw0KPiA+ICsgIEFkZFRl c3RDYXNlICgNCj4gPiArICAgIFNoaW1UZXN0cywNCj4gPiArICAgICJBZGRpbmcgYSBwb2xpY3kg Zm9yIGEgdmFyaWFibGUgdGhhdCBoYXMgcHJldmlvdXNseSBiZWVuIGxvY2tlZA0Kc2hvdWxkDQo+ ID4gYWx3YXlzIGZhaWwiLCAiU2V0UG9saWN5QWZ0ZXJMb2NrIiwNCj4gPiArICAgIFNldHRpbmdQ b2xpY3lGb3JBTG9ja2VkVmFyaWFibGVTaG91bGRGYWlsLCBMaWJJbml0TW9ja2VkLA0KPiBMaWJD bGVhbnVwLA0KPiA+IE5VTEwNCj4gPiArICAgICk7DQo+ID4gKw0KPiA+ICsgIC8vDQo+ID4gKyAg Ly8gRXhlY3V0ZSB0aGUgdGVzdHMuDQo+ID4gKyAgLy8NCj4gPiArICBTdGF0dXMgPSBSdW5BbGxU ZXN0U3VpdGVzIChGcmFtZXdvcmspOw0KPiA+ICsNCj4gPiArRVhJVDoNCj4gPiArICBpZiAoRnJh bWV3b3JrICE9IE5VTEwpIHsNCj4gPiArICAgIEZyZWVVbml0VGVzdEZyYW1ld29yayAoRnJhbWV3 b3JrKTsNCj4gPiArICB9DQo+ID4gKw0KPiA+ICsgIHJldHVybjsNCj4gPiArfQ0KPiA+ICsNCj4g PiArLy8vDQo+ID4gKy8vLyBBdm9pZCBFQ0MgZXJyb3IgZm9yIGZ1bmN0aW9uIG5hbWUgdGhhdCBz dGFydHMgd2l0aCBsb3dlciBjYXNlDQo+ID4gK2xldHRlciAvLy8gI2RlZmluZSBNYWluIG1haW4N Cj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgIFN0YW5kYXJkIFBPU0lYIEMgZW50cnkgcG9pbnQgZm9y IGhvc3QgYmFzZWQgdW5pdCB0ZXN0IGV4ZWN1dGlvbi4NCj4gPiArDQo+ID4gKyAgQHBhcmFtW2lu XSBBcmdjICBOdW1iZXIgb2YgYXJndW1lbnRzDQo+ID4gKyAgQHBhcmFtW2luXSBBcmd2ICBBcnJh eSBvZiBwb2ludGVycyB0byBhcmd1bWVudHMNCj4gPiArDQo+ID4gKyAgQHJldHZhbCAwICAgICAg U3VjY2Vzcw0KPiA+ICsgIEByZXR2YWwgb3RoZXIgIEVycm9yDQo+ID4gKyoqLw0KPiA+ICtJTlQz Mg0KPiA+ICtNYWluICgNCj4gPiArICBJTiBJTlQzMiAgQXJnYywNCj4gPiArICBJTiBDSEFSOCAg KkFyZ3ZbXQ0KPiA+ICsgICkNCj4gPiArew0KPiA+ICsgIFVuaXRUZXN0TWFpbiAoKTsNCj4gPiAr ICByZXR1cm4gMDsNCj4gPiArfQ0KPiA+IGRpZmYgLS1naXQNCj4gPiBhL01kZU1vZHVsZVBrZy9V bml2ZXJzYWwvVmFyaWFibGUvUnVudGltZUR4ZS9SdW50aW1lRHhlVW5pdFRlc3QvVmENCj4gPiBy aWFibGVMb2NrUmVxdWVzdFRvTG9ja1VuaXRUZXN0LmluZg0KPiA+IGIvTWRlTW9kdWxlUGtnL1Vu aXZlcnNhbC9WYXJpYWJsZS9SdW50aW1lRHhlL1J1bnRpbWVEeGVVbml0VGVzdC9WYQ0KPiA+IHJp YWJsZUxvY2tSZXF1ZXN0VG9Mb2NrVW5pdFRlc3QuaW5mDQo+ID4gbmV3IGZpbGUgbW9kZSAxMDA2 NDQNCj4gPiBpbmRleCAwMDAwMDAwMDAwMDAuLjJhNjU5ZDdlMTM3MA0KPiA+IC0tLSAvZGV2L251 bGwNCj4gPiArKysNCj4gPiBiL01kZU1vZHVsZVBrZy9Vbml2ZXJzYWwvVmFyaWFibGUvUnVudGlt ZUR4ZS9SdW50aW1lRHhlVW5pdFRlc3QvVmENCj4gPiByaQ0KPiA+ICsrKyBhYmxlTG9ja1JlcXVl c3RUb0xvY2tVbml0VGVzdC5pbmYNCj4gPiBAQCAtMCwwICsxLDM2IEBADQo+ID4gKyMjIEBmaWxl DQo+ID4gKyMgVGhpcyBpcyBhIGhvc3QtYmFzZWQgdW5pdCB0ZXN0IGZvciB0aGUgVmFyaWFibGVM b2NrUmVxdWVzdFRvTG9jaw0Kc2hpbS4NCj4gPiArIw0KPiA+ICsjIENvcHlyaWdodCAoYykgTWlj cm9zb2Z0IENvcnBvcmF0aW9uLg0KPiA+ICsjIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBCU0Qt Mi1DbGF1c2UtUGF0ZW50ICMjDQo+ID4gKw0KPiA+ICtbRGVmaW5lc10NCj4gPiArICBJTkZfVkVS U0lPTiAgICAgICAgID0gMHgwMDAxMDAxNw0KPiA+ICsgIEJBU0VfTkFNRSAgICAgICAgICAgPSBW YXJpYWJsZUxvY2tSZXF1ZXN0VG9Mb2NrVW5pdFRlc3QNCj4gPiArICBGSUxFX0dVSUQgICAgICAg ICAgID0gQTczODhCNkMtNzI3NC00NzE3LTk2NDktQkRDNURGRDFGQ0JFDQo+ID4gKyAgVkVSU0lP Tl9TVFJJTkcgICAgICA9IDEuMA0KPiA+ICsgIE1PRFVMRV9UWVBFICAgICAgICAgPSBIT1NUX0FQ UExJQ0FUSU9ODQo+ID4gKw0KPiA+ICsjDQo+ID4gKyMgVGhlIGZvbGxvd2luZyBpbmZvcm1hdGlv biBpcyBmb3IgcmVmZXJlbmNlIG9ubHkgYW5kIG5vdCByZXF1aXJlZCBieQ0KdGhlDQo+ID4gYnVp bGQgdG9vbHMuDQo+ID4gKyMNCj4gPiArIyAgVkFMSURfQVJDSElURUNUVVJFUyAgICAgICAgICAg PSBJQTMyIFg2NCBBUk0gQUFSQ0g2NA0KPiA+ICsjDQo+ID4gKw0KPiA+ICtbU291cmNlc10NCj4g PiArICBWYXJpYWJsZUxvY2tSZXF1ZXN0VG9Mb2NrVW5pdFRlc3QuYw0KPiA+ICsgIC4uL1Zhcmlh YmxlTG9ja1JlcXVlc3RUb0xvY2suYw0KPiA+ICsNCj4gPiArW1BhY2thZ2VzXQ0KPiA+ICsgIE1k ZVBrZy9NZGVQa2cuZGVjDQo+ID4gKyAgTWRlTW9kdWxlUGtnL01kZU1vZHVsZVBrZy5kZWMNCj4g PiArICBVbml0VGVzdEZyYW1ld29ya1BrZy9Vbml0VGVzdEZyYW1ld29ya1BrZy5kZWMNCj4gPiAr DQo+ID4gK1tMaWJyYXJ5Q2xhc3Nlc10NCj4gPiArICBVbml0VGVzdExpYg0KPiA+ICsgIERlYnVn TGliDQo+ID4gKyAgVmFyaWFibGVQb2xpY3lMaWINCj4gPiArICBWYXJpYWJsZVBvbGljeUhlbHBl ckxpYg0KPiA+ICsgIEJhc2VNZW1vcnlMaWINCj4gPiArICBNZW1vcnlBbGxvY2F0aW9uTGliDQo+ ID4gZGlmZiAtLWdpdA0KPiA+IGEvTWRlTW9kdWxlUGtnL1VuaXZlcnNhbC9WYXJpYWJsZS9SdW50 aW1lRHhlL1ZhcmlhYmxlTG9ja1JlcXVlc3RUb0wNCj4gPiBvY2suYw0KPiA+IGIvTWRlTW9kdWxl UGtnL1VuaXZlcnNhbC9WYXJpYWJsZS9SdW50aW1lRHhlL1ZhcmlhYmxlTG9ja1JlcXVlc3RUb0wN Cj4gPiBvY2suYw0KPiA+IGluZGV4IDRhYTg1NGFhZjI2MC4uMTkxZGU2YjkwN2M1IDEwMDY0NA0K PiA+IC0tLQ0KPiA+IGEvTWRlTW9kdWxlUGtnL1VuaXZlcnNhbC9WYXJpYWJsZS9SdW50aW1lRHhl L1ZhcmlhYmxlTG9ja1JlcXVlc3RUb0wNCj4gPiBvY2suYw0KPiA+ICsrKw0KPiA+IGIvTWRlTW9k dWxlUGtnL1VuaXZlcnNhbC9WYXJpYWJsZS9SdW50aW1lRHhlL1ZhcmlhYmxlTG9ja1JlcXVlc3RU b0wNCj4gPiBvDQo+ID4gKysrIGNrLmMNCj4gPiBAQCAtMSw2NyArMSwzNjAgQEANCj4gPiAtLyoq IEBmaWxlIC0tIFZhcmlhYmxlTG9ja1JlcXVlc3RUb0xvY2suYyAtVGVtcG9yYXJ5IGxvY2F0aW9u IG9mIHRoZQ0KPiA+IFJlcXVlc3RUb0xvY2sgc2hpbSBjb2RlIHdoaWxlIC1wcm9qZWN0cyBhcmUg bW92ZWQgdG8gVmFyaWFibGVQb2xpY3kuDQo+ID4gU2hvdWxkIGJlIHJlbW92ZWQgd2hlbiBkZXBy ZWNhdGVkLg0KPiA+ICsvKiogQGZpbGUNCj4gPiArICBUZW1wb3JhcnkgbG9jYXRpb24gb2YgdGhl IFJlcXVlc3RUb0xvY2sgc2hpbSBjb2RlIHdoaWxlIHByb2plY3RzDQo+ID4gKyAgYXJlIG1vdmVk IHRvIFZhcmlhYmxlUG9saWN5LiBTaG91bGQgYmUgcmVtb3ZlZCB3aGVuIGRlcHJlY2F0ZWQuDQo+ ID4NCj4gPiAtQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uDQo+ID4gLVNQRFgt TGljZW5zZS1JZGVudGlmaWVyOiBCU0QtMi1DbGF1c2UtUGF0ZW50DQo+ID4gKyAgQ29weXJpZ2h0 IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uDQo+ID4gKyAgU1BEWC1MaWNlbnNlLUlkZW50aWZp ZXI6IEJTRC0yLUNsYXVzZS1QYXRlbnQNCj4gPg0KPiA+ICAqKi8NCj4gPg0KPiA+ICAjaW5jbHVk ZSA8VWVmaS5oPg0KPiA+IC0NCj4gPiAgI2luY2x1ZGUgPExpYnJhcnkvRGVidWdMaWIuaD4NCj4g PiArI2luY2x1ZGUgPExpYnJhcnkvQmFzZU1lbW9yeUxpYi5oPg0KPiA+ICAjaW5jbHVkZSA8TGli cmFyeS9NZW1vcnlBbGxvY2F0aW9uTGliLmg+DQo+ID4gLQ0KPiA+IC0jaW5jbHVkZSA8UHJvdG9j b2wvVmFyaWFibGVMb2NrLmg+DQo+ID4gLQ0KPiA+IC0jaW5jbHVkZSA8UHJvdG9jb2wvVmFyaWFi bGVQb2xpY3kuaD4NCj4gPiAgI2luY2x1ZGUgPExpYnJhcnkvVmFyaWFibGVQb2xpY3lMaWIuaD4N Cj4gPiAgI2luY2x1ZGUgPExpYnJhcnkvVmFyaWFibGVQb2xpY3lIZWxwZXJMaWIuaD4NCj4gPiAr I2luY2x1ZGUgPFByb3RvY29sL1ZhcmlhYmxlTG9jay5oPg0KPiA+DQo+ID4gKy8vDQo+ID4gKy8v IE5PVEU6IERPIE5PVCBVU0UgVEhFU0UgTUFDUk9TIG9uIGFueSBzdHJ1Y3R1cmUgdGhhdCBoYXMg bm90IGJlZW4NCj4gPiB2YWxpZGF0ZWQuDQo+ID4gKy8vICAgICAgIEN1cnJlbnQgdGFibGUgZGF0 YSBoYXMgYWxyZWFkeSBiZWVuIHNhbml0aXplZC4NCj4gPiArLy8NCj4gPiArI2RlZmluZSBHRVRf TkVYVF9QT0xJQ1koQ3VyUG9saWN5KQ0KPiA+ICsoVkFSSUFCTEVfUE9MSUNZX0VOVFJZKikoKFVJ TlQ4KilDdXJQb2xpY3kgKyBDdXJQb2xpY3ktPlNpemUpICNkZWZpbmUNCj4gPiArR0VUX1BPTElD WV9OQU1FKEN1clBvbGljeSkgIChDSEFSMTYqKSgoVUlOVE4pQ3VyUG9saWN5ICsNCj4gPiArQ3Vy UG9saWN5LT5PZmZzZXRUb05hbWUpDQo+ID4gKw0KPiA+ICsjZGVmaW5lIE1BVENIX1BSSU9SSVRZ X0VYQUNUICAwDQo+ID4gKyNkZWZpbmUgTUFUQ0hfUFJJT1JJVFlfTUlOICAgIE1BWF9VSU5UOA0K PiA+ICsNCj4gPiArLyoqDQo+ID4gKyAgVGhpcyBoZWxwZXIgZnVuY3Rpb24gZXZhbHVhdGVzIGEg cG9saWN5IGFuZCBkZXRlcm1pbmVzIHdoZXRoZXIgaXQNCj4gPiArbWF0Y2hlcyB0aGUNCj4gPiAr ICB0YXJnZXQgdmFyaWFibGUuIElmIG1hdGNoZWQsIHdpbGwgYWxzbyByZXR1cm4gYSB2YWx1ZSBj b3JyZXNwb25kaW5nDQo+ID4gK3RvIHRoZQ0KPiA+ICsgIHByaW9yaXR5IG9mIHRoZSBtYXRjaC4N Cj4gPiArDQo+ID4gKyAgVGhlIHJ1bGVzIGZvciAiYmVzdCBtYXRjaCIgYXJlIGxpc3RlZCBpbiB0 aGUgVmFyaWFibGUgUG9saWN5IFNwZWMuDQo+ID4gKyAgUGVyZmVjdCBuYW1lIG1hdGNoZXMgd2ls bCByZXR1cm4gMC4NCj4gPiArICBTaW5nbGUgd2lsZGNhcmQgY2hhcmFjdGVycyB3aWxsIHJldHVy biB0aGUgbnVtYmVyIG9mIHdpbGRjYXJkDQo+IGNoYXJhY3RlcnMuDQo+ID4gKyAgRnVsbCBuYW1l c3BhY2VzIHdpbGwgcmV0dXJuIE1BWF9VSU5UOC4NCj4gPiArDQo+ID4gKyAgQHBhcmFtW2luXSAg RXZhbEVudHJ5ICAgICAgUG9pbnRlciB0byB0aGUgcG9saWN5IGVudHJ5IGJlaW5nDQo+IGV2YWx1 YXRlZC4NCj4gPiArICBAcGFyYW1baW5dICBWYXJpYWJsZU5hbWUgICBTYW1lIGFzIEVGSV9TRVRf VkFSSUFCTEUuDQo+ID4gKyAgQHBhcmFtW2luXSAgVmVuZG9yR3VpZCAgICAgU2FtZSBhcyBFRklf U0VUX1ZBUklBQkxFLg0KPiA+ICsgIEBwYXJhbVtvdXRdIE1hdGNoUHJpb3JpdHkgIFtPcHRpb25h bF0gT24gZmluZGluZyBhIG1hdGNoLCB0aGlzIHZhbHVlDQo+ID4gY29udGFpbnMNCj4gPiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgcHJpb3JpdHkgb2YgdGhlIG1hdGNoLiBMb3dl cg0KPiBudW1iZXIgPT0gaGlnaGVyDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg cHJpb3JpdHkuIE9ubHkgdmFsaWQgaWYgYSBtYXRjaCBmb3VuZC4NCj4gPiArDQo+ID4gKyAgQHJl dHZhbCAgVFJVRSAgIEN1cnJlbnQgZW50cnkgbWF0Y2hlcyB0aGUgdGFyZ2V0IHZhcmlhYmxlLg0K PiA+ICsgIEByZXR2YWwgIEZBTFNFICBDdXJyZW50IGVudHJ5IGRvZXMgbm90IG1hdGNoIGF0IGFs bC4NCj4gPiArDQo+ID4gKyoqLw0KPiA+ICtTVEFUSUMNCj4gPiArQk9PTEVBTg0KPiA+ICtFdmFs dWF0ZVBvbGljeU1hdGNoICgNCj4gPiArICBJTiBDT05TVCBWQVJJQUJMRV9QT0xJQ1lfRU5UUlkg ICpFdmFsRW50cnksDQo+ID4gKyAgSU4gQ09OU1QgQ0hBUjE2ICAgICAgICAgICAgICAgICAqVmFy aWFibGVOYW1lLA0KPiA+ICsgIElOIENPTlNUIEVGSV9HVUlEICAgICAgICAgICAgICAgKlZlbmRv ckd1aWQsDQo+ID4gKyAgT1VUIFVJTlQ4ICAgICAgICAgICAgICAgICAgICAgICAqTWF0Y2hQcmlv cml0eSAgT1BUSU9OQUwNCj4gPiArICApDQo+ID4gK3sNCj4gPiArICBCT09MRUFOICBSZXN1bHQ7 DQo+ID4gKyAgQ0hBUjE2ICAgKlBvbGljeU5hbWU7DQo+ID4gKyAgVUlOVDggICAgQ2FsY3VsYXRl ZFByaW9yaXR5Ow0KPiA+ICsgIFVJTlROICAgIEluZGV4Ow0KPiA+ICsNCj4gPiArICBSZXN1bHQg PSBGQUxTRTsNCj4gPiArICBDYWxjdWxhdGVkUHJpb3JpdHkgPSBNQVRDSF9QUklPUklUWV9FWEFD VDsNCj4gPiArDQo+ID4gKyAgLy8NCj4gPiArICAvLyBTdGVwIDE6IElmIHRoZSBHVUlEIGRvZXNu J3QgbWF0Y2gsIHdlJ3JlIGRvbmUuIE5vIG5lZWQgdG8gZXZhbHVhdGUNCj4gPiBhbnl0aGluZyBl bHNlLg0KPiA+ICsgIC8vDQo+ID4gKyAgaWYgKCFDb21wYXJlR3VpZCAoJkV2YWxFbnRyeS0+TmFt ZXNwYWNlLCBWZW5kb3JHdWlkKSkgew0KPiA+ICsgICAgZ290byBFeGl0Ow0KPiA+ICsgIH0NCj4g PiArDQo+ID4gKyAgLy8NCj4gPiArICAvLyBJZiB0aGUgR1VJRCBtYXRjaGVzLCBjaGVjayB0byBz ZWUgd2hldGhlciB0aGVyZSBpcyBhIE5hbWUNCj4gPiArIGFzc29jaWF0ZWQgIC8vIHdpdGggdGhl IHBvbGljeS4gSWYgbm90LCB0aGlzIHBvbGljeSBtYXRjaGVzIHRoZSBlbnRpcmUNCj4gPiBuYW1l c3BhY2UuDQo+ID4gKyAgLy8gTWlzc2luZyBOYW1lIGlzIGluZGljYXRlZCBieSBzaXplIGJlaW5n IGVxdWFsIHRvIG5hbWUuDQo+ID4gKyAgLy8NCj4gPiArICBpZiAoRXZhbEVudHJ5LT5TaXplID09 IEV2YWxFbnRyeS0+T2Zmc2V0VG9OYW1lKSB7DQo+ID4gKyAgICBDYWxjdWxhdGVkUHJpb3JpdHkg PSBNQVRDSF9QUklPUklUWV9NSU47DQo+ID4gKyAgICBSZXN1bHQgPSBUUlVFOw0KPiA+ICsgICAg Z290byBFeGl0Ow0KPiA+ICsgIH0NCj4gPiArDQo+ID4gKyAgLy8NCj4gPiArICAvLyBOb3cgdGhh dCB3ZSBrbm93IHRoZSBuYW1lIGV4aXN0cywgZ2V0IGl0Lg0KPiA+ICsgIC8vDQo+ID4gKyAgUG9s aWN5TmFtZSA9IEdFVF9QT0xJQ1lfTkFNRSAoRXZhbEVudHJ5KTsNCj4gPiArDQo+ID4gKyAgLy8N Cj4gPiArICAvLyBFdmFsdWF0ZSB0aGUgbmFtZSBhZ2FpbnN0IHRoZSBwb2xpY3kgbmFtZSBhbmQg Y2hlY2sgZm9yIGEgbWF0Y2guDQo+ID4gKyAgLy8gQWNjb3VudCBmb3IgYW55IHdpbGRjYXJkcy4N Cj4gPiArICAvLw0KPiA+ICsgIEluZGV4ID0gMDsNCj4gPiArICBSZXN1bHQgPSBUUlVFOw0KPiA+ ICsgIC8vDQo+ID4gKyAgLy8gS2VlcCBnb2luZyB1bnRpbCB0aGUgZW5kIG9mIGJvdGggc3RyaW5n cy4NCj4gPiArICAvLw0KPiA+ICsgIHdoaWxlIChQb2xpY3lOYW1lW0luZGV4XSAhPSBDSEFSX05V TEwgfHwgVmFyaWFibGVOYW1lW0luZGV4XSAhPQ0KPiA+IENIQVJfTlVMTCkgew0KPiA+ICsgICAg Ly8NCj4gPiArICAgIC8vIElmIHdlIGRvbid0IGhhdmUgYSBtYXRjaC4uLg0KPiA+ICsgICAgLy8N Cj4gPiArICAgIGlmIChQb2xpY3lOYW1lW0luZGV4XSAhPSBWYXJpYWJsZU5hbWVbSW5kZXhdIHx8 IFBvbGljeU5hbWVbSW5kZXhdDQo+ID09DQo+ID4gJyMnKSB7DQo+ID4gKyAgICAgIC8vDQo+ID4g KyAgICAgIC8vIElmIHRoaXMgaXMgYSBudW1lcmljYWwgd2lsZGNhcmQsIHdlIGNhbiBjb25zaWRl ciBpdCBhIG1hdGNoIGlmDQp3ZQ0KPiBhbHRlcg0KPiA+ICsgICAgICAvLyB0aGUgcHJpb3JpdHku DQo+ID4gKyAgICAgIC8vDQo+ID4gKyAgICAgIGlmIChQb2xpY3lOYW1lW0luZGV4XSA9PSBMJyMn ICYmDQo+ID4gKyAgICAgICAgICAgICgoTCcwJyA8PSBWYXJpYWJsZU5hbWVbSW5kZXhdICYmIFZh cmlhYmxlTmFtZVtJbmRleF0gPD0NCj4gTCc5JykgfHwNCj4gPiArICAgICAgICAgICAgIChMJ0En IDw9IFZhcmlhYmxlTmFtZVtJbmRleF0gJiYgVmFyaWFibGVOYW1lW0luZGV4XSA8PQ0KPiBMJ0Yn KSB8fA0KPiA+ICsgICAgICAgICAgICAgKEwnYScgPD0gVmFyaWFibGVOYW1lW0luZGV4XSAmJiBW YXJpYWJsZU5hbWVbSW5kZXhdIDw9DQo+IEwnZicpKSkgew0KPiA+ICsgICAgICAgIGlmIChDYWxj dWxhdGVkUHJpb3JpdHkgPCBNQVRDSF9QUklPUklUWV9NSU4pIHsNCj4gPiArICAgICAgICAgIENh bGN1bGF0ZWRQcmlvcml0eSsrOw0KPiA+ICsgICAgICAgIH0NCj4gPiArICAgICAgLy8NCj4gPiAr ICAgICAgLy8gT3RoZXJ3aXNlLCBub3QgYSBtYXRjaC4NCj4gPiArICAgICAgLy8NCj4gPiArICAg ICAgfSBlbHNlIHsNCj4gPiArICAgICAgICBSZXN1bHQgPSBGQUxTRTsNCj4gPiArICAgICAgICBn b3RvIEV4aXQ7DQo+ID4gKyAgICAgIH0NCj4gPiArICAgIH0NCj4gPiArICAgIEluZGV4Kys7DQo+ ID4gKyAgfQ0KPiA+ICsNCj4gPiArRXhpdDoNCj4gPiArICBpZiAoUmVzdWx0ICYmIE1hdGNoUHJp b3JpdHkgIT0gTlVMTCkgew0KPiA+ICsgICAgKk1hdGNoUHJpb3JpdHkgPSBDYWxjdWxhdGVkUHJp b3JpdHk7DQo+ID4gKyAgfQ0KPiA+ICsgIHJldHVybiBSZXN1bHQ7DQo+ID4gK30NCj4gPiArDQo+ ID4gKy8qKg0KPiA+ICsgIFRoaXMgaGVscGVyIGZ1bmN0aW9uIHdhbGtzIHRoZSBjdXJyZW50IHBv bGljeSB0YWJsZSBhbmQgcmV0dXJucyBhDQo+ID4gK3BvaW50ZXINCj4gPiArICB0byB0aGUgYmVz dCBtYXRjaCwgaWYgYW55IGFyZSBmb3VuZC4gTGV2ZXJhZ2VzIEV2YWx1YXRlUG9saWN5TWF0Y2go KQ0KPiA+ICt0bw0KPiA+ICsgIGRldGVybWluZSAiYmVzdCIuDQo+ID4gKw0KPiA+ICsgIEBwYXJh bVtpbl0gIFBvbGljeVRhYmxlICAgICAgUG9pbnRlciB0byBjdXJyZW50IHBvbGljeSB0YWJsZS4N Cj4gPiArICBAcGFyYW1baW5dICBQb2xpY3lUYWJsZVNpemUgIFNpemUgb2YgY3VycmVudCBwb2xp Y3kgdGFibGUuDQo+ID4gKyAgQHBhcmFtW2luXSAgVmFyaWFibGVOYW1lICAgICBTYW1lIGFzIEVG SV9TRVRfVkFSSUFCTEUuDQo+ID4gKyAgQHBhcmFtW2luXSAgVmVuZG9yR3VpZCAgICAgICBTYW1l IGFzIEVGSV9TRVRfVkFSSUFCTEUuDQo+ID4gKyAgQHBhcmFtW291dF0gUmV0dXJuUHJpb3JpdHkg ICBbT3B0aW9uYWxdIElmIHBvaW50ZXIgaXMgcHJvdmlkZWQsDQpyZXR1cm4NCj4gdGhlDQo+ID4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvcml0eSBvZiB0aGUgbWF0Y2guIFNh bWUgYXMNCj4gRXZhbHVhdGVQb2xpY3lNYXRjaCgpLg0KPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgT25seSB2YWxpZCBpZiBhIG1hdGNoIGlzIHJldHVybmVkLg0KPiA+ICsNCj4g PiArICBAcmV0dmFsICAgICBWQVJJQUJMRV9QT0xJQ1lfRU5UUlkqICAgIEJlc3QgbWF0Y2ggdGhh dCB3YXMNCj4gZm91bmQuDQo+ID4gKyAgQHJldHZhbCAgICAgTlVMTCAgICAgICAgICAgICAgICAg ICAgICBObyBtYXRjaCB3YXMgZm91bmQuDQo+ID4gKw0KPiA+ICsqKi8NCj4gPiArU1RBVElDDQo+ ID4gK1ZBUklBQkxFX1BPTElDWV9FTlRSWSoNCj4gPiArR2V0QmVzdFBvbGljeU1hdGNoICgNCj4g PiArICBJTiBVSU5UOCAgICAgICAgICAgKlBvbGljeVRhYmxlLA0KPiA+ICsgIElOIFVJTlQzMiAg ICAgICAgICBQb2xpY3lUYWJsZVNpemUsDQo+ID4gKyAgSU4gQ09OU1QgQ0hBUjE2ICAgICpWYXJp YWJsZU5hbWUsDQo+ID4gKyAgSU4gQ09OU1QgRUZJX0dVSUQgICpWZW5kb3JHdWlkLA0KPiA+ICsg IE9VVCBVSU5UOCAgICAgICAgICAqUmV0dXJuUHJpb3JpdHkgIE9QVElPTkFMDQo+ID4gKyAgKQ0K PiA+ICt7DQo+ID4gKyAgVkFSSUFCTEVfUE9MSUNZX0VOVFJZICAqQmVzdFJlc3VsdDsNCj4gPiAr ICBWQVJJQUJMRV9QT0xJQ1lfRU5UUlkgICpDdXJyZW50RW50cnk7DQo+ID4gKyAgVUlOVDggICAg ICAgICAgICAgICAgICBNYXRjaFByaW9yaXR5Ow0KPiA+ICsgIFVJTlQ4ICAgICAgICAgICAgICAg ICAgQ3VycmVudFByaW9yaXR5Ow0KPiA+ICsNCj4gPiArICBCZXN0UmVzdWx0ID0gTlVMTDsNCj4g PiArICBNYXRjaFByaW9yaXR5ID0gTUFUQ0hfUFJJT1JJVFlfRVhBQ1Q7DQo+ID4gKw0KPiA+ICsg IC8vDQo+ID4gKyAgLy8gV2FsayBhbGwgZW50cmllcyBpbiB0aGUgdGFibGUsIGxvb2tpbmcgZm9y IG1hdGNoZXMuDQo+ID4gKyAgLy8NCj4gPiArICBDdXJyZW50RW50cnkgPSAoVkFSSUFCTEVfUE9M SUNZX0VOVFJZKilQb2xpY3lUYWJsZTsNCj4gPiArICB3aGlsZSAoKFVJTlROKUN1cnJlbnRFbnRy eSA8IChVSU5UTikoKFVJTlQ4KilQb2xpY3lUYWJsZSArDQo+ID4gUG9saWN5VGFibGVTaXplKSkg ew0KPiA+ICsgICAgLy8NCj4gPiArICAgIC8vIENoZWNrIGZvciBhIG1hdGNoLg0KPiA+ICsgICAg Ly8NCj4gPiArICAgIGlmIChFdmFsdWF0ZVBvbGljeU1hdGNoIChDdXJyZW50RW50cnksIFZhcmlh YmxlTmFtZSwgVmVuZG9yR3VpZCwNCj4gPiAmQ3VycmVudFByaW9yaXR5KSkgew0KPiA+ICsgICAg ICAvLw0KPiA+ICsgICAgICAvLyBJZiBtYXRjaCBpcyBiZXR0ZXIsIHRha2UgaXQuDQo+ID4gKyAg ICAgIC8vDQo+ID4gKyAgICAgIGlmIChCZXN0UmVzdWx0ID09IE5VTEwgfHwgQ3VycmVudFByaW9y aXR5IDwgTWF0Y2hQcmlvcml0eSkgew0KPiA+ICsgICAgICAgIEJlc3RSZXN1bHQgPSBDdXJyZW50 RW50cnk7DQo+ID4gKyAgICAgICAgTWF0Y2hQcmlvcml0eSA9IEN1cnJlbnRQcmlvcml0eTsNCj4g PiArICAgICAgfQ0KPiA+ICsNCj4gPiArICAgICAgLy8NCj4gPiArICAgICAgLy8gSWYgeW91J3Zl IGhpdCB0aGUgaGlnaGVzdC1wcmlvcml0eSBtYXRjaCwgY2FuIGV4aXQgbm93Lg0KPiA+ICsgICAg ICAvLw0KPiA+ICsgICAgICBpZiAoTWF0Y2hQcmlvcml0eSA9PSAwKSB7DQo+ID4gKyAgICAgICAg YnJlYWs7DQo+ID4gKyAgICAgIH0NCj4gPiArICAgIH0NCj4gPiArDQo+ID4gKyAgICAvLw0KPiA+ ICsgICAgLy8gSWYgd2UncmUgc3RpbGwgaW4gdGhlIGxvb3AsIG1vdmUgdG8gdGhlIG5leHQgZW50 cnkuDQo+ID4gKyAgICAvLw0KPiA+ICsgICAgQ3VycmVudEVudHJ5ID0gR0VUX05FWFRfUE9MSUNZ IChDdXJyZW50RW50cnkpOyAgfQ0KPiA+ICsNCj4gPiArICAvLw0KPiA+ICsgIC8vIElmIGEgcmV0 dXJuIHByaW9yaXR5IHdhcyByZXF1ZXN0ZWQsIHJldHVybiBpdC4NCj4gPiArICAvLw0KPiA+ICsg IGlmIChSZXR1cm5Qcmlvcml0eSAhPSBOVUxMKSB7DQo+ID4gKyAgICAqUmV0dXJuUHJpb3JpdHkg PSBNYXRjaFByaW9yaXR5Ow0KPiA+ICsgIH0NCj4gPiArDQo+ID4gKyAgcmV0dXJuIEJlc3RSZXN1 bHQ7DQo+ID4gK30NCj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgIFRoaXMgaGVscGVyIGZ1bmN0aW9u IHdpbGwgZHVtcCBhbmQgd2FsayB0aGUgY3VycmVudCBwb2xpY3kgdGFibGVzIHRvDQo+ID4gK2Rl dGVybWluZQ0KPiA+ICsgIHdoZXRoZXIgYSBtYXRjaGluZyBwb2xpY3kgYWxyZWFkeSBleGlzdHMg dGhhdCBzYXRpc2ZpZXMgdGhlIGxvY2sNCnJlcXVlc3QuDQo+ID4gKw0KPiA+ICsgIEBwYXJhbVtp bl0gVmFyaWFibGVOYW1lICBBIHBvaW50ZXIgdG8gdGhlIHZhcmlhYmxlIG5hbWUgdGhhdCBpcw0K PiBiZWluZw0KPiA+IHNlYXJjaGVkLg0KPiA+ICsgIEBwYXJhbVtpbl0gVmVuZG9yR3VpZCAgICBB IHBvaW50ZXIgdG8gdGhlIHZlbmRvciBHVUlEIHRoYXQgaXMgYmVpbmcNCj4gPiBzZWFyY2hlZC4N Cj4gPiArDQo+ID4gKyAgQHJldHZhbCAgVFJVRSAgIFdlIGNhbiBzYWZlbHkgYXNzdW1lIHRoaXMg dmFyaWFibGUgaXMgbG9ja2VkLg0KPiA+ICsgIEByZXR2YWwgIEZBTFNFICBBbiBlcnJvciBoYXMg b2NjdXJyZWQgb3Igd2UgY2Fubm90IHByb3ZlIHRoYXQgdGhlDQo+IHZhcmlhYmxlDQo+ID4gaXMN Cj4gPiArICAgICAgICAgICAgICAgICAgbG9ja2VkLg0KPiA+ICsNCj4gPiArKiovDQo+ID4gK1NU QVRJQw0KPiA+ICtCT09MRUFODQo+ID4gK0lzVmFyaWFibGVBbHJlYWR5TG9ja2VkICgNCj4gPiAr ICBJTiBDSEFSMTYgICAgKlZhcmlhYmxlTmFtZSwNCj4gPiArICBJTiBFRklfR1VJRCAgKlZlbmRv ckd1aWQNCj4gPiArICApDQo+ID4gK3sNCj4gPiArICBFRklfU1RBVFVTICAgICAgICAgICAgIFN0 YXR1czsNCj4gPiArICBVSU5UOCAgICAgICAgICAgICAgICAgICpQb2xpY3lUYWJsZTsNCj4gPiAr ICBVSU5UMzIgICAgICAgICAgICAgICAgIFBvbGljeVRhYmxlU2l6ZTsNCj4gPiArICBCT09MRUFO ICAgICAgICAgICAgICAgIFJlc3VsdDsNCj4gPiArICBWQVJJQUJMRV9QT0xJQ1lfRU5UUlkgICpN YXRjaFBvbGljeTsNCj4gPiArICBVSU5UOCAgICAgICAgICAgICAgICAgIE1hdGNoUHJpb3JpdHk7 DQo+ID4gKw0KPiA+ICsgIFJlc3VsdCA9IFRSVUU7DQo+ID4gKw0KPiA+ICsgIC8vDQo+ID4gKyAg Ly8gRmlyc3QsIHdlIG5lZWQgdG8gZHVtcCB0aGUgZXhpc3RpbmcgcG9saWN5IHRhYmxlLg0KPiA+ ICsgIC8vDQo+ID4gKyAgUG9saWN5VGFibGVTaXplID0gMDsNCj4gPiArICBQb2xpY3lUYWJsZSA9 IE5VTEw7DQo+ID4gKyAgU3RhdHVzID0gRHVtcFZhcmlhYmxlUG9saWN5IChQb2xpY3lUYWJsZSwg JlBvbGljeVRhYmxlU2l6ZSk7ICBpZg0KPiA+ICsgKFN0YXR1cyAhPSBFRklfQlVGRkVSX1RPT19T TUFMTCkgew0KPiA+ICsgICAgREVCVUcgKChERUJVR19FUlJPUiwgIiVhIC0gRmFpbGVkIHRvIGRl dGVybWluZSBwb2xpY3kgdGFibGUNCj4gPiBzaXplISAlclxuIiwgX19GVU5DVElPTl9fLCBTdGF0 dXMpKTsNCj4gPiArICAgIHJldHVybiBGQUxTRTsNCj4gPiArICB9DQo+ID4gKyAgUG9saWN5VGFi bGUgPSBBbGxvY2F0ZVplcm9Qb29sIChQb2xpY3lUYWJsZVNpemUpOyAgaWYgKFBvbGljeVRhYmxl ID09DQo+ID4gKyBOVUxMKSB7DQo+ID4gKyAgICBERUJVRyAoKERFQlVHX0VSUk9SLCAiJWEgLSBG YWlsZWQgdG8gYWxsb2NhdGVkIHNwYWNlIGZvciBwb2xpY3kNCj4gdGFibGUhDQo+ID4gMHglWFxu IiwgX19GVU5DVElPTl9fLCBQb2xpY3lUYWJsZVNpemUpKTsNCj4gPiArICAgIHJldHVybiBGQUxT RTsNCj4gPiArICB9DQo+ID4gKyAgU3RhdHVzID0gRHVtcFZhcmlhYmxlUG9saWN5IChQb2xpY3lU YWJsZSwgJlBvbGljeVRhYmxlU2l6ZSk7ICBpZg0KPiA+ICsgKEVGSV9FUlJPUiAoU3RhdHVzKSkg ew0KPiA+ICsgICAgREVCVUcgKChERUJVR19FUlJPUiwgIiVhIC0gRmFpbGVkIHRvIGR1bXAgcG9s aWN5IHRhYmxlISAlclxuIiwNCj4gPiBfX0ZVTkNUSU9OX18sIFN0YXR1cykpOw0KPiA+ICsgICAg UmVzdWx0ID0gRkFMU0U7DQo+ID4gKyAgICBnb3RvIEV4aXQ7DQo+ID4gKyAgfQ0KPiA+ICsNCj4g PiArICAvLw0KPiA+ICsgIC8vIE5vdyB3ZSBuZWVkIHRvIHdhbGsgdGhlIHRhYmxlIGxvb2tpbmcg Zm9yIGEgbWF0Y2guDQo+ID4gKyAgLy8NCj4gPiArICBNYXRjaFBvbGljeSA9IEdldEJlc3RQb2xp Y3lNYXRjaCAoDQo+ID4gKyAgICAgICAgICAgICAgICAgIFBvbGljeVRhYmxlLA0KPiA+ICsgICAg ICAgICAgICAgICAgICBQb2xpY3lUYWJsZVNpemUsDQo+ID4gKyAgICAgICAgICAgICAgICAgIFZh cmlhYmxlTmFtZSwNCj4gPiArICAgICAgICAgICAgICAgICAgVmVuZG9yR3VpZCwNCj4gPiArICAg ICAgICAgICAgICAgICAgJk1hdGNoUHJpb3JpdHkNCj4gPiArICAgICAgICAgICAgICAgICAgKTsN Cj4gPiArICBpZiAoTWF0Y2hQb2xpY3kgIT0gTlVMTCAmJiBNYXRjaFByaW9yaXR5ICE9IE1BVENI X1BSSU9SSVRZX0VYQUNUKQ0KPiB7DQo+ID4gKyAgICBERUJVRyAoKERFQlVHX0VSUk9SLCAiJWEg LSBXZSB3b3VsZCBub3QgaGF2ZSBleHBlY3RlZCBhDQo+IG5vbi1leGFjdA0KPiA+IG1hdGNoISAl ZFxuIiwgX19GVU5DVElPTl9fLCBNYXRjaFByaW9yaXR5KSk7DQo+ID4gKyAgICBSZXN1bHQgPSBG QUxTRTsNCj4gPiArICAgIGdvdG8gRXhpdDsNCj4gPiArICB9DQo+ID4gKw0KPiA+ICsgIC8vDQo+ ID4gKyAgLy8gTm93IHdlIGNhbiBjaGVjayB0byBzZWUgd2hldGhlciB0aGlzIHZhcmlhYmxlIGlz IGN1cnJlbnRseSBsb2NrZWQuDQo+ID4gKyAgLy8NCj4gPiArICBpZiAoTWF0Y2hQb2xpY3ktPkxv Y2tQb2xpY3lUeXBlICE9DQo+IFZBUklBQkxFX1BPTElDWV9UWVBFX0xPQ0tfTk9XKSB7DQo+ID4g KyAgICBERUJVRyAoKERFQlVHX0lORk8sICIlYSAtIFBvbGljeSBtYXkgbm90IGxvY2sgdmFyaWFi bGUhICVkXG4iLA0KPiA+IF9fRlVOQ1RJT05fXywgTWF0Y2hQb2xpY3ktPkxvY2tQb2xpY3lUeXBl KSk7DQo+ID4gKyAgICBSZXN1bHQgPSBGQUxTRTsNCj4gPiArICAgIGdvdG8gRXhpdDsNCj4gPiAr ICB9DQo+ID4gKw0KPiA+ICtFeGl0Og0KPiA+ICsgIGlmIChQb2xpY3lUYWJsZSAhPSBOVUxMKSB7 DQo+ID4gKyAgICBGcmVlUG9vbCAoUG9saWN5VGFibGUpOw0KPiA+ICsgIH0NCj4gPiArDQo+ID4g KyAgcmV0dXJuIFJlc3VsdDsNCj4gPiArfQ0KPiA+DQo+ID4gIC8qKg0KPiA+ICAgIERFUFJFQ0FU RUQuIFRISVMgSVMgT05MWSBIRVJFIEFTIEEgQ09OVkVOSUVOQ0UgV0hJTEUNCj4gUE9SVElORy4N Cj4gPiAtICBNYXJrIGEgdmFyaWFibGUgdGhhdCB3aWxsIGJlY29tZSByZWFkLW9ubHkgYWZ0ZXIg bGVhdmluZyB0aGUgRFhFDQpwaGFzZQ0KPiBvZg0KPiA+IGV4ZWN1dGlvbi4NCj4gPiAtICBXcml0 ZSByZXF1ZXN0IGNvbWluZyBmcm9tIFNNTSBlbnZpcm9ubWVudCB0aHJvdWdoDQo+ID4gRUZJX1NN TV9WQVJJQUJMRV9QUk9UT0NPTCBpcyBhbGxvd2VkLg0KPiA+ICsgIE1hcmsgYSB2YXJpYWJsZSB0 aGF0IHdpbGwgYmVjb21lIHJlYWQtb25seSBhZnRlciBsZWF2aW5nIHRoZSBEWEUNCj4gPiArIHBo YXNlIG9mICBleGVjdXRpb24uIFdyaXRlIHJlcXVlc3QgY29taW5nIGZyb20gU01NIGVudmlyb25t ZW50DQo+ID4gdGhyb3VnaA0KPiA+ICsgRUZJX1NNTV9WQVJJQUJMRV9QUk9UT0NPTCBpcyBhbGxv d2VkLg0KPiA+DQo+ID4gICAgQHBhcmFtW2luXSBUaGlzICAgICAgICAgIFRoZSBWQVJJQUJMRV9M T0NLX1BST1RPQ09MDQo+IGluc3RhbmNlLg0KPiA+IC0gIEBwYXJhbVtpbl0gVmFyaWFibGVOYW1l ICBBIHBvaW50ZXIgdG8gdGhlIHZhcmlhYmxlIG5hbWUgdGhhdCB3aWxsIGJlDQo+ID4gbWFkZSBy ZWFkLW9ubHkgc3Vic2VxdWVudGx5Lg0KPiA+IC0gIEBwYXJhbVtpbl0gVmVuZG9yR3VpZCAgICBB IHBvaW50ZXIgdG8gdGhlIHZlbmRvciBHVUlEIHRoYXQgd2lsbCBiZQ0KPiBtYWRlDQo+ID4gcmVh ZC1vbmx5IHN1YnNlcXVlbnRseS4NCj4gPiArICBAcGFyYW1baW5dIFZhcmlhYmxlTmFtZSAgQSBw b2ludGVyIHRvIHRoZSB2YXJpYWJsZSBuYW1lIHRoYXQgd2lsbCBiZQ0KPiA+IG1hZGUNCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZC1vbmx5IHN1YnNlcXVlbnRseS4NCj4gPiAr ICBAcGFyYW1baW5dIFZlbmRvckd1aWQgICAgQSBwb2ludGVyIHRvIHRoZSB2ZW5kb3IgR1VJRCB0 aGF0IHdpbGwgYmUNCj4gbWFkZQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFk LW9ubHkgc3Vic2VxdWVudGx5Lg0KPiA+DQo+ID4gLSAgQHJldHZhbCBFRklfU1VDQ0VTUyAgICAg ICAgICAgVGhlIHZhcmlhYmxlIHNwZWNpZmllZCBieSB0aGUNCj4gVmFyaWFibGVOYW1lIGFuZA0K PiA+IHRoZSBWZW5kb3JHdWlkIHdhcyBtYXJrZWQNCj4gPiAtICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBhcyBwZW5kaW5nIHRvIGJlIHJlYWQtb25seS4NCj4gPiArICBAcmV0dmFsIEVG SV9TVUNDRVNTICAgICAgICAgICBUaGUgdmFyaWFibGUgc3BlY2lmaWVkIGJ5IHRoZQ0KPiBWYXJp YWJsZU5hbWUgYW5kDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIFZl bmRvckd1aWQgd2FzIG1hcmtlZCBhcw0KPiBwZW5kaW5nIHRvIGJlDQo+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgcmVhZC1vbmx5Lg0KPiA+ICAgIEByZXR2YWwgRUZJX0lOVkFM SURfUEFSQU1FVEVSIFZhcmlhYmxlTmFtZSBvciBWZW5kb3JHdWlkIGlzDQo+IE5VTEwuDQo+ID4g ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3IgVmFyaWFibGVOYW1lIGlzIGFuIGVt cHR5DQo+IHN0cmluZy4NCj4gPiAtICBAcmV0dmFsIEVGSV9BQ0NFU1NfREVOSUVEDQo+IEVGSV9F TkRfT0ZfRFhFX0VWRU5UX0dST1VQX0dVSUQNCj4gPiBvciBFRklfRVZFTlRfR1JPVVBfUkVBRFlf VE9fQk9PVCBoYXMNCj4gPiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHJlYWR5 IGJlZW4gc2lnbmFsZWQuDQo+ID4gLSAgQHJldHZhbCBFRklfT1VUX09GX1JFU09VUkNFUyAgVGhl cmUgaXMgbm90IGVub3VnaCByZXNvdXJjZSB0bw0KPiBob2xkDQo+ID4gdGhlIGxvY2sgcmVxdWVz dC4NCj4gPiArICBAcmV0dmFsIEVGSV9BQ0NFU1NfREVOSUVEDQo+IEVGSV9FTkRfT0ZfRFhFX0VW RU5UX0dST1VQX0dVSUQNCj4gPiBvcg0KPiA+ICsNCj4gRUZJX0VWRU5UX0dST1VQX1JFQURZX1RP X0JPT1QgaGFzIGFscmVhZHkgYmVlbg0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIHNpZ25hbGVkLg0KPiA+ICsgIEByZXR2YWwgRUZJX09VVF9PRl9SRVNPVVJDRVMgIFRoZXJl IGlzIG5vdCBlbm91Z2ggcmVzb3VyY2UgdG8NCj4gaG9sZA0KPiA+IHRoZSBsb2NrDQo+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC4NCj4gPiAgKiovDQo+ID4gIEVG SV9TVEFUVVMNCj4gPiAgRUZJQVBJDQo+ID4gIFZhcmlhYmxlTG9ja1JlcXVlc3RUb0xvY2sgKA0K PiA+IC0gIElOIENPTlNUIEVES0lJX1ZBUklBQkxFX0xPQ0tfUFJPVE9DT0wgKlRoaXMsDQo+ID4g LSAgSU4gICAgICAgQ0hBUjE2ICAgICAgICAgICAgICAgICAgICAgICAqVmFyaWFibGVOYW1lLA0K PiA+IC0gIElOICAgICAgIEVGSV9HVUlEICAgICAgICAgICAgICAgICAgICAgKlZlbmRvckd1aWQN Cj4gPiArICBJTiBDT05TVCBFREtJSV9WQVJJQUJMRV9MT0NLX1BST1RPQ09MICAqVGhpcywNCj4g PiArICBJTiBDSEFSMTYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqVmFyaWFibGVOYW1l LA0KPiA+ICsgIElOIEVGSV9HVUlEICAgICAgICAgICAgICAgICAgICAgICAgICAgICpWZW5kb3JH dWlkDQo+ID4gICAgKQ0KPiA+ICB7DQo+ID4gLSAgRUZJX1NUQVRVUyAgICAgICAgICAgICAgU3Rh dHVzOw0KPiA+IC0gIFZBUklBQkxFX1BPTElDWV9FTlRSWSAgICpOZXdQb2xpY3k7DQo+ID4gKyAg RUZJX1NUQVRVUyAgICAgICAgICAgICBTdGF0dXM7DQo+ID4gKyAgVkFSSUFCTEVfUE9MSUNZX0VO VFJZICAqTmV3UG9saWN5Ow0KPiA+ICsNCj4gPiArICBERUJVRyAoKERFQlVHX0VSUk9SLCAiISEh IERFUFJFQ0FURUQgSU5URVJGQUNFICEhISAlYSgpIHdpbGwgZ28NCj4gYXdheQ0KPiA+ICsgc29v biFcbiIsIF9fRlVOQ1RJT05fXykpOyAgREVCVUcgKChERUJVR19FUlJPUiwgIiEhISBERVBSRUNB VEVEDQo+ID4gKyBJTlRFUkZBQ0UgISEhIFBsZWFzZSBtb3ZlIHRvIHVzZSBWYXJpYWJsZSBQb2xp Y3khXG4iKSk7ICBERUJVRw0KPiA+ICsgKChERUJVR19FUlJPUiwgIiEhISBERVBSRUNBVEVEIElO VEVSRkFDRSAhISEgVmFyaWFibGU6ICVnICVzXG4iLA0KPiA+ICsgVmVuZG9yR3VpZCwgVmFyaWFi bGVOYW1lKSk7DQo+ID4NCj4gPiAgICBOZXdQb2xpY3kgPSBOVUxMOw0KPiA+IC0gIFN0YXR1cyA9 IENyZWF0ZUJhc2ljVmFyaWFibGVQb2xpY3koIFZlbmRvckd1aWQsDQo+ID4gLSAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFyaWFibGVOYW1lLA0KPiA+IC0NCj4gVkFSSUFC TEVfUE9MSUNZX05PX01JTl9TSVpFLA0KPiA+IC0NCj4gVkFSSUFCTEVfUE9MSUNZX05PX01BWF9T SVpFLA0KPiA+IC0NCj4gVkFSSUFCTEVfUE9MSUNZX05PX01VU1RfQVRUUiwNCj4gPiAtDQo+IFZB UklBQkxFX1BPTElDWV9OT19DQU5UX0FUVFIsDQo+ID4gLQ0KPiBWQVJJQUJMRV9QT0xJQ1lfVFlQ RV9MT0NLX05PVywNCj4gPiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAm TmV3UG9saWN5ICk7DQo+ID4gKyAgU3RhdHVzID0gQ3JlYXRlQmFzaWNWYXJpYWJsZVBvbGljeSgN Cj4gPiArICAgICAgICAgICAgIFZlbmRvckd1aWQsDQo+ID4gKyAgICAgICAgICAgICBWYXJpYWJs ZU5hbWUsDQo+ID4gKyAgICAgICAgICAgICBWQVJJQUJMRV9QT0xJQ1lfTk9fTUlOX1NJWkUsDQo+ ID4gKyAgICAgICAgICAgICBWQVJJQUJMRV9QT0xJQ1lfTk9fTUFYX1NJWkUsDQo+ID4gKyAgICAg ICAgICAgICBWQVJJQUJMRV9QT0xJQ1lfTk9fTVVTVF9BVFRSLA0KPiA+ICsgICAgICAgICAgICAg VkFSSUFCTEVfUE9MSUNZX05PX0NBTlRfQVRUUiwNCj4gPiArICAgICAgICAgICAgIFZBUklBQkxF X1BPTElDWV9UWVBFX0xPQ0tfTk9XLA0KPiA+ICsgICAgICAgICAgICAgJk5ld1BvbGljeQ0KPiA+ ICsgICAgICAgICAgICAgKTsNCj4gPiAgICBpZiAoIUVGSV9FUlJPUiggU3RhdHVzICkpIHsNCj4g PiAtICAgIFN0YXR1cyA9IFJlZ2lzdGVyVmFyaWFibGVQb2xpY3koIE5ld1BvbGljeSApOw0KPiA+ ICsgICAgU3RhdHVzID0gUmVnaXN0ZXJWYXJpYWJsZVBvbGljeSAoTmV3UG9saWN5KTsNCj4gPiAr DQo+ID4gKyAgICAvLw0KPiA+ICsgICAgLy8gSWYgdGhlIGVycm9yIHJldHVybmVkIGlzIEVGSV9B TFJFQURZX1NUQVJURUQsIHdlIG5lZWQgdG8gY2hlY2sNCj4gdGhlDQo+ID4gKyAgICAvLyBjdXJy ZW50IGRhdGFiYXNlIGZvciB0aGUgdmFyaWFibGUgYW5kIHNlZSB3aGV0aGVyIGl0J3MgbG9ja2Vk Lg0KSWYgaXQncw0KPiA+ICsgICAgLy8gbG9ja2VkLCB3ZSdyZSBzdGlsbCBmaW5lLCBidXQgYWxz byBnZW5lcmF0ZSBhIERFQlVHX0VSUk9SDQo+IG1lc3NhZ2Ugc28NCj4gPiB0aGUNCj4gPiArICAg IC8vIGR1cGxpY2F0ZSBsb2NrIGNhbiBiZSByZW1vdmVkLg0KPiA+ICsgICAgLy8NCj4gPiArICAg IGlmIChTdGF0dXMgPT0gRUZJX0FMUkVBRFlfU1RBUlRFRCkgew0KPiA+ICsgICAgICBpZiAoSXNW YXJpYWJsZUFscmVhZHlMb2NrZWQgKFZhcmlhYmxlTmFtZSwgVmVuZG9yR3VpZCkpIHsNCj4gPiAr ICAgICAgICBERUJVRyAoKERFQlVHX0VSUk9SLCAiICBWYXJpYWJsZTogJWcgJXMgaXMgYWxyZWFk eQ0KPiBsb2NrZWQhXG4iLA0KPiA+IFZlbmRvckd1aWQsIFZhcmlhYmxlTmFtZSkpOw0KPiA+ICsg ICAgICAgIFN0YXR1cyA9IEVGSV9TVUNDRVNTOw0KPiA+ICsgICAgICB9DQo+ID4gKyAgICB9DQo+ ID4gICAgfQ0KPiA+IC0gIGlmIChFRklfRVJST1IoIFN0YXR1cyApKSB7DQo+ID4gKyAgaWYgKEVG SV9FUlJPUiAoU3RhdHVzKSkgew0KPiA+ICAgICAgREVCVUcoKCBERUJVR19FUlJPUiwgIiVhIC0g RmFpbGVkIHRvIGxvY2sgdmFyaWFibGUgJXMhICVyXG4iLA0KPiA+IF9fRlVOQ1RJT05fXywgVmFy aWFibGVOYW1lLCBTdGF0dXMgKSk7DQo+ID4gLSAgICBBU1NFUlRfRUZJX0VSUk9SKCBTdGF0dXMg KTsNCj4gPiAgICB9DQo+ID4gICAgaWYgKE5ld1BvbGljeSAhPSBOVUxMKSB7DQo+ID4gICAgICBG cmVlUG9vbCggTmV3UG9saWN5ICk7DQo+ID4gLS0NCj4gPiAyLjI5LjIud2luZG93cy4yDQo+ID4N Cj4gPg0KPiA+DQo+ID4NCj4gPg0KDQoNCg0K --_000_BN8PR11MB3666F30E5317D9E284A429D8CACA0BN8PR11MB3666namp_ Content-Type: text/html; charset="gb2312" Content-Transfer-Encoding: quoted-printable

Hello Bret and Mike,

 

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

 

For Liming=A1=AFs suggestion to split the patch in= to a 2-patch series (1 for the fix and 1 for the unit tests), I am okay wit= h 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 m= ake your own decision.

 

In summary, with the typos addressed in the 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 <deve= l@edk2.groups.io> On Behalf Of Bret Barkelew via groups.io
Sent: Thursday, December 10, 2020 3:35 PM
To: gaoliming <gaoliming@byosoft.com.cn>; Wu, Hao A <hao.a= .wu@intel.com>; devel@edk2.groups.io; Kinney, Michael D <michael.d.ki= nney@intel.com>
Subject: Re: [EXTERNAL]
=BB=D8=B8=B4: [edk2-devel] [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 because this shim is supposed = to be temporary and should go away within the next few stabilizations.

 

I would also prefer to keep the tests and the code = together. These are pure unit tests rather than driver tests and serve to d= ocument and prove the code that is being submitted. However, I=A1=AFm willi= ng to be flexible on this.

 

- Bret


From: gaoli= ming <gaoliming@byosoft.com.= cn>
Sent: 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, Mi= chael D <michael.d.kinney@= intel.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Subject: [EXTERNAL]
=BB=D8=B8=B4: [edk2-devel] [Patch v= 2 1/1] MdeModulePkg/Variable/RuntimeDxe: Restore Variable Lock Protocol behavior

 

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

  Besides, I suggest to split this patch. One is the bug fix to resto= re
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: 2020=C4=EA12=D4=C210=C8=D5 10:25
> =CA=D5=BC=FE=C8=CB: devel@edk2.groups.io; Kinney, Michael D
> <michael.d.kinney@in= tel.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] MdeModulePkg/Variable/RuntimeDxe:
> Restore Variable Lock Protocol behavior
>
> > -----Original Message-----
> > From: devel@edk2.groups.= io <devel@edk2.groups.io= > On Behalf Of Michael
> > D Kinney
> > Sent: Thursday, December 10, 2020 2:06 AM
> > To: devel@edk2.groups.io=
> > Cc: Bret Barkelew <bret.barkelew@microsoft.com>; Wu, Hao A
> > <hao.a.wu@intel.com= >; Liming Gao <gaoliming@= byosoft.com.cn>; Bret
> > Barkelew <Bret= .Barkelew@microsoft.com>
> > Subject: [edk2-devel] [Patch v2 1/1] MdeModulePkg/Variable/Runti= meDxe:
> > Restore Variable Lock Protocol behavior
> >
> > From: Bret Barkelew <bret.barkelew@microsoft.com>
> >
> > https://nam06.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fbugzil= la.tianocore.org%2Fshow_bug.cgi%3Fid%3D3111&amp;data=3D04%7C01%7Cbret.b= arkelew%40microsoft.com%7C4115faaa16c6475b8e3508d89cba0189%7C72f988bf86f141= af91ab2d7cd011db47%7C1%7C0%7C637431669999943616%7CUnknown%7CTWFpbGZsb3d8eyJ= WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&= amp;sdata=3DDU8EYtayepZpsyxajKK9w0mQ5kExWXG2AJvCcvVVy1A%3D&amp;reserved= = =3D0
> >
> > The VariableLock shim currently fails if called twice because th= e
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 = 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 messa= ge
> so
> > the duplicate lock can be reported in a debug log and removed. >
>
> Hello,
>
> Is it possible to reuse:
>     a) EvaluatePolicyMatch() and GetBestPolicyMat= ch() functions
>     b) Macros like GET_NEXT_POLICY, GET_POLICY_NA= ME and etc.
> under MdeModulePkg\Library\VariablePolicyLib to reduce duplicate code= s?
>
> A couple of minor inline comments below:
>
>
> >
> > Add host based unit tests for the multiple lock case using Varia= ble Lock
> > Protocol, Variable Policy Protocol, and mixes of Variable Lock P= rotocol
and
> > Variable Policy Protocol.
> >
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Hao A Wu <hao.a.wu@= intel.com>
> > Cc: Liming Gao <g= aoliming@byosoft.com.cn>
> > Signed-off-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > ---
> >  MdeModulePkg/Test/MdeModulePkgHostTest.dsc  &nbs= p; |  11 +
> >  .../VariableLockRequestToLockUnitTest.c   &= nbsp;   | 434
> ++++++++++++++++++
> >  .../VariableLockRequestToLockUnitTest.inf   = ;  |  36 ++
> >  .../RuntimeDxe/VariableLockRequestToLock.c  &nbs= p; | 363
> +++++++++++++--
> >  4 files changed, 809 insertions(+), 35 deletions(-)  = create mode 100644
> > MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va= ri
> > ableLockRequestToLockUnitTest.c
> >  create mode 100644
> > MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va= ri
> > 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/MockUefiRuntimeS= er
> > vicesTableLib.inf
> >
> > @@ -30,3 +33,11 @@ [Components]
> >
> > ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSy= st
> > emLib.inf
> >
> > UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeResetSystemL= ib/
> > UnitTest/MockUefiRuntimeServicesTableLib.inf
> >    }
> > +
> > +
> > MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Va= ri
> > ableLockRequestToLockUnitTest.inf {
> > +    <LibraryClasses>
> > +
> >
> VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePoli= cyLi
> > b.inf
> > +
> >
> VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/= Va
> > riablePolicyHelperLib.inf
> > +    <PcdsFixedAtBuild>
> > +
> > +
> > gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcement= Dis
> > 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 VariableLockReque= stToLock
shim.
> > +
> > +  Copyright (c) Microsoft Corporation.
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include <stdarg.h>
> > +#include <stddef.h>
> > +#include <setjmp.h>
> > +#include <cmocka.h>
> > +
> > +#include <Uefi.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/MemoryAllocationLib.h> #include
> > +<Library/UnitTestLib.h> #include <Library/VariablePoli= cyLib.h> #include
> > +<Library/VariablePolicyHelperLib.h>
> > +
> > +#include <Protocol/VariableLock.h>
> > +
> > +#define UNIT_TEST_NAME       = ; "VarPol/VarLock Shim Unit Test"
> > +#define UNIT_TEST_VERSION     "1.0&quo= t;
> > +
> > +///=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  = ;            &n= bsp;         *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
> > +=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, 0x2= 2, 0x61, 0x5,
> > +0x92} };
> > +
> > +//
> > +// Test GUID 2 {2DEA799E-5E73-43B9-870E-C945CE82AF3A}
> > +//
> > +EFI_GUID  mTestGuid2 =3D {
> > +  0x2dea799e, 0x5e73, 0x43b9, {0x87, 0xe, 0xc9, 0x45, 0xce= , 0x82, 0xaf,
> > +0x3a} };
> > +
> > +//
> > +// Test GUID 3 {698A2BFD-A616-482D-B88C-7100BD6682A9}
> > +//
> > +EFI_GUID  mTestGuid3 =3D {
> > +  0x698a2bfd, 0xa616, 0x482d, {0xb8, 0x8c, 0x71, 0x0, 0xbd= , 0x66, 0x82,
> > +0xa9} };
> > +
> > +#define TEST_VAR_1_NAME      &nbs= p;       L"TestVar1"
> > +#define TEST_VAR_2_NAME      &nbs= p;       L"TestVar2"
> > +#define TEST_VAR_3_NAME      &nbs= p;       L"TestVar3"
> > +
> > +#define TEST_POLICY_ATTRIBUTES_NULL  0
> > +#define TEST_POLICY_MIN_SIZE_NULL    0
> > +#define TEST_POLICY_MAX_SIZE_NULL    MAX_UINT32<= br> > > +
> > +#define TEST_POLICY_MIN_SIZE_10      1= 0
> > +#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    *Var= iableName,
> > +  IN     EFI_GUID  *VendorGuid, > > +  OUT    UINT32    *Attribut= es,  OPTIONAL
> > +  IN OUT UINTN     *DataSize,
> > +  OUT    VOID     = *Data         OPTIONAL
> > +  )
> > +{
> > +  UINT32      MockedAttr;
> > +  UINTN       MockedDataSize= ;
> > +  VOID        *MockedDa= ta;
> > +  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)moc= k();
> > +  MockedReturn   =3D (EFI_STATUS)mock();
> > +
> > +  if (Attributes !=3D NULL) {
> > +    *Attributes =3D MockedAttr;
> > +  }
> > +  if (Data !=3D NULL && !EFI_ERROR (MockedReturn))= {
> > +    CopyMem (Data, MockedData, MockedDataSize);&= nbsp; }
> > +
> > +  *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 lib= rary 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 (StubGetVariable= Null)) ?
> > +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 Variabl= e 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_N= AME,
> > + &mTestGuid1);  UT_ASSERT_NOT_EFI_ERROR (Status);
> > +
> > +  return UNIT_TEST_PASSED;
> > +}
> > +
> > +/**
> > +  Test Case that locks the same variable twice using the V= ariable Lock
> Procol.
>
>
> Minor comment, typo for 'Procol' -> 'Protocol'
>
>
> > +  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_N= AME,
> > + &mTestGuid1);  UT_ASSERT_NOT_EFI_ERROR (Status);
> > +
> > +  Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_N= AME,
> > + &mTestGuid1);  UT_ASSERT_NOT_EFI_ERROR (Status);
> > +
> > +  return UNIT_TEST_PASSED;
> > +}
> > +
> > +/**
> > +  Test Case that locks a variable using the Variable Polic= y 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       &nbs= p;     Status;
> > +  VARIABLE_POLICY_ENTRY  *NewEntry;
> > +
> > +  //
> > +  // Create a variable policy that locks the variable.
> > +  //
> > +  Status =3D CreateBasicVariablePolicy (
> > +          &nb= sp;  &mTestGuid1,
> > +          &nb= sp;  TEST_VAR_1_NAME,
> > +          &nb= sp;  TEST_POLICY_MIN_SIZE_NULL,
> > +          &nb= sp;  TEST_POLICY_MAX_SIZE_200,
> > +          &nb= sp;  TEST_POLICY_ATTRIBUTES_NULL,
> > +          &nb= sp;  TEST_POLICY_ATTRIBUTES_NULL,
> > +          &nb= sp;  VARIABLE_POLICY_TYPE_LOCK_NOW,
> > +          &nb= sp;  &NewEntry
> > +          &nb= sp;  );
> > +  UT_ASSERT_NOT_EFI_ERROR (Status);
> > +
> > +  //
> > +  // Register the new policy.
> > +  //
> > +  Status =3D RegisterVariablePolicy (NewEntry);
> > +
> > +  Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_N= AME,
> > + &mTestGuid1);  UT_ASSERT_NOT_EFI_ERROR (Status);
> > +
> > +  FreePool (NewEntry);
> > +
> > +  return UNIT_TEST_PASSED;
> > +}
> > +
> > +/**
> > +  Test Case that locks a variable using the Variable Polic= y Protocol
> > +with a
> > +  policy other than LOCK_NOW then attempts to lock the sam= e variable
> > +using the
> > +  Variable Lock Protocol.  The call to Variable Polic= y is expected to
> > +succced
>
>
> 'succced' -> 'succeed'
>
>
> > +  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      Conte= xt
> > +  )
> > +{
> > +  EFI_STATUS       &nbs= p;        Status;
> > +  VARIABLE_POLICY_ENTRY     *NewEntry;=
> > +
> > +  // Create a variable policy that locks the variable.
> > +  Status =3D CreateVarStateVariablePolicy (&mTestGuid1= ,
> > +          &nb= sp;            =             &nb= sp;     TEST_VAR_1_NAME,
> > +
> TEST_POLICY_MIN_SIZE_NULL,
> > +
> TEST_POLICY_MAX_SIZE_200,
> > +
> TEST_POLICY_ATTRIBUTES_NULL,
> > +
> TEST_POLICY_ATTRIBUTES_NULL,
> > +          &nb= sp;            =             &nb= sp;     &mTestGuid2,
> > +          &nb= sp;            =             &nb= sp;     1,
> > +          &nb= sp;            =             &nb= sp;     TEST_VAR_2_NAME,
> > +          &nb= sp;            =             &nb= sp;     &NewEntry);
> > + UT_ASSERT_NOT_EFI_ERROR (Status);
> > +
> > +  // Register the new policy.
> > +  Status =3D RegisterVariablePolicy (NewEntry);
> > +
> > +  Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_N= AME,
> > + &mTestGuid1);  UT_ASSERT_TRUE (EFI_ERROR (Status)); > > +
> > +  FreePool (NewEntry);
> > +
> > +  return UNIT_TEST_PASSED;
> > +}
> > +
> > +/**
> > +  Test Case that locks a variable using Variable Lock Prot= ocol Policy
> > +Protocol
> > +  then and then attempts to lock the same variable using t= he Variable
> > +Policy
> > +  Protocol.  The call to Variable Lock is expected to= succced and the
>
>
> 'succced' -> 'succeed'
>
> Best Regards,
> Hao Wu
>
>
> > +call to
> > +  Variable Policy is expected to fail.
> > +
> > +  @param[in]  Context  Unit test case context > > +  **/
> > +UNIT_TEST_STATUS
> > +EFIAPI
> > +SettingPolicyForALockedVariableShouldFail (
> > +  IN UNIT_TEST_CONTEXT      Conte= xt
> > +  )
> > +{
> > +  EFI_STATUS       &nbs= p;        Status;
> > +  VARIABLE_POLICY_ENTRY     *NewEntry;=
> > +
> > +  // Lock the variable.
> > +  Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_N= AME,
> > + &mTestGuid1);  UT_ASSERT_NOT_EFI_ERROR (Status);
> > +
> > +  // Create a variable policy that locks the variable.
> > +  Status =3D CreateVarStateVariablePolicy (&mTestGuid1= ,
> > +          &nb= sp;            =             &nb= sp;     TEST_VAR_1_NAME,
> > +
> TEST_POLICY_MIN_SIZE_NULL,
> > +
> TEST_POLICY_MAX_SIZE_200,
> > +
> TEST_POLICY_ATTRIBUTES_NULL,
> > +
> TEST_POLICY_ATTRIBUTES_NULL,
> > +          &nb= sp;            =             &nb= sp;     &mTestGuid2,
> > +          &nb= sp;            =             &nb= sp;     1,
> > +          &nb= sp;            =             &nb= sp;     TEST_VAR_2_NAME,
> > +          &nb= sp;            =             &nb= sp;     &NewEntry);
> > + UT_ASSERT_NOT_EFI_ERROR (Status);
> > +
> > +  // Register the new policy.
> > +  Status =3D RegisterVariablePolicy (NewEntry);  UT_A= SSERT_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       &nbs= p;          Status;
> > +  UNIT_TEST_FRAMEWORK_HANDLE  Framework;
> > +  UNIT_TEST_SUITE_HANDLE      Shi= mTests;
> > +
> > +  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 t= ests.
> > +  //
> > +  Status =3D InitUnitTestFramework (&Framework, UNIT_T= EST_NAME,
> > + gEfiCallerBaseName, UNIT_TEST_VERSION);  if (EFI_ERROR (S= tatus)) {
> > +    DEBUG ((DEBUG_ERROR, "Failed in InitUni= tTestFramework. Status
> > =3D %r\n", Status));
> > +    goto EXIT;
> > +  }
> > +
> > +  //
> > +  // Add all test suites and tests.
> > +  //
> > +  Status =3D CreateUnitTestSuite (
> > +          &nb= sp;  &ShimTests, Framework,
> > +          &nb= sp;  "Variable Lock Shim Tests", "VarPolicy.VarLockShim= ", NULL,
> NULL
> > +          &nb= sp;  );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "Failed in CreateU= nitTestSuite for
> > ShimTests\n"));
> > +    Status =3D EFI_OUT_OF_RESOURCES;
> > +    goto EXIT;
> > +  }
> > +  AddTestCase (
> > +    ShimTests,
> > +    "Locking a variable with no matching po= licies should always work",
> > "EmptyPolicies",
> > +    LockingWithoutAnyPoliciesShouldSucceed, LibI= nitMocked,
> LibCleanup,
> > NULL
> > +    );
> > +  AddTestCase (
> > +    ShimTests,
> > +    "Locking a variable twice should always= work", "DoubleLock",
> > +    LockingTwiceShouldSucceed, LibInitMocked, Li= bCleanup, NULL
> > +    );
> > +  AddTestCase (
> > +    ShimTests,
> > +    "Locking a variable that's already lock= ed by another policy should
> work",
> > "LockAfterPolicy",
> > +    LockingALockedVariableShouldSucceed, LibInit= Mocked, LibCleanup,
> NULL
> > +    );
> > +  AddTestCase (
> > +    ShimTests,
> > +    "Locking a variable that already has an= unlocked policy should
fail",
> > "LockAfterUnlockedPolicy",
> > +    LockingAnUnlockedVariableShouldFail, LibInit= Mocked, LibCleanup,
> NULL
> > +    );
> > +  AddTestCase (
> > +    ShimTests,
> > +    "Adding a policy for a variable that ha= s previously been locked
should
> > always fail", "SetPolicyAfterLock",
> > +    SettingPolicyForALockedVariableShouldFail, L= ibInitMocked,
> 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 ca= se
> > +letter /// #define Main main
> > +
> > +/**
> > +  Standard POSIX C entry point for host based unit test ex= ecution.
> > +
> > +  @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 VariableLockRequestToL= ock
shim.
> > +#
> > +# Copyright (c) Microsoft Corporation.
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent ##
> > +
> > +[Defines]
> > +  INF_VERSION       &nb= sp; =3D 0x00010017
> > +  BASE_NAME        = ;   =3D VariableLockRequestToLockUnitTest
> > +  FILE_GUID        = ;   =3D A7388B6C-7274-4717-9649-BDC5DFD1FCBE
> > +  VERSION_STRING      =3D 1.0
> > +  MODULE_TYPE       &nb= sp; =3D HOST_APPLICATION
> > +
> > +#
> > +# The following information is for reference only and not requi= red 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/VariableLockRequest= ToL
> > ock.c
> > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequest= ToL
> > ock.c
> > index 4aa854aaf260..191de6b907c5 100644
> > ---
> > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequest= ToL
> > ock.c
> > +++
> > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequest= ToL
> > o
> > +++ ck.c
> > @@ -1,67 +1,360 @@
> > -/** @file -- VariableLockRequestToLock.c -Temporary location of= the
> > RequestToLock shim code while -projects are moved to VariablePol= icy.
> > Should be removed when deprecated.
> > +/** @file
> > +  Temporary location of the RequestToLock shim code while = projects
> > +  are moved to VariablePolicy. Should be removed when depr= ecated.
> >
> > -Copyright (c) Microsoft Corporation.
> > -SPDX-License-Identifier: BSD-2-Clause-Patent
> > +  Copyright (c) Microsoft Corporation.
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> >  **/
> >
> >  #include <Uefi.h>
> > -
> >  #include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> >  #include <Library/MemoryAllocationLib.h>
> > -
> > -#include <Protocol/VariableLock.h>
> > -
> > -#include <Protocol/VariablePolicy.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.
> > +//       Current table data has a= lready 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 w= hether it
> > +matches the
> > +  target variable. If matched, will also return a value co= rresponding
> > +to the
> > +  priority of the match.
> > +
> > +  The rules for "best match" are listed in the V= ariable Policy Spec.
> > +  Perfect name matches will return 0.
> > +  Single wildcard characters will return the number of wil= dcard
> characters.
> > +  Full namespaces will return MAX_UINT8.
> > +
> > +  @param[in]  EvalEntry     = Pointer to the policy entry being
> evaluated.
> > +  @param[in]  VariableName   Same as EFI_SE= T_VARIABLE.
> > +  @param[in]  VendorGuid     Same= as EFI_SET_VARIABLE.
> > +  @param[out] MatchPriority  [Optional] On finding a = match, this value
> > contains
> > +          &nb= sp;            =       the priority of the match. Lower
> number =3D=3D higher
> > +          &nb= sp;            =       priority. Only valid if a match found.
> > +
> > +  @retval  TRUE   Current entry matches the= target variable.
> > +  @retval  FALSE  Current entry does not match a= t all.
> > +
> > +**/
> > +STATIC
> > +BOOLEAN
> > +EvaluatePolicyMatch (
> > +  IN CONST VARIABLE_POLICY_ENTRY  *EvalEntry,
> > +  IN CONST CHAR16       = ;          *VariableName,
> > +  IN CONST EFI_GUID      &nb= sp;        *VendorGuid,
> > +  OUT UINT8        = ;            &n= bsp;  *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 nee= d to evaluate
> > anything else.
> > +  //
> > +  if (!CompareGuid (&EvalEntry->Namespace, VendorGu= id)) {
> > +    goto Exit;
> > +  }
> > +
> > +  //
> > +  // If the GUID matches, check to see whether there is a = Name
> > + associated  // with the policy. If not, this policy match= es the entire
> > 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 f= or 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[Inde= x] || PolicyName[Index]
> =3D=3D
> > '#') {
> > +      //
> > +      // If this is a numerical wildca= rd, we can consider it a match if
we
> alter
> > +      // the priority.
> > +      //
> > +      if (PolicyName[Index] =3D=3D L'#= ' &&
> > +          &nb= sp; ((L'0' <=3D VariableName[Index] && VariableName[Index] <= =3D
> L'9') ||
> > +          &nb= sp;  (L'A' <=3D VariableName[Index] && VariableName[Index] = <=3D
> L'F') ||
> > +          &nb= sp;  (L'a' <=3D VariableName[Index] && VariableName[Index] = <=3D
> L'f'))) {
> > +        if (CalculatedPriori= ty < MATCH_PRIORITY_MIN) {
> > +          Calculat= edPriority++;
> > +        }
> > +      //
> > +      // 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 EvaluateP= olicyMatch()
> > +to
> > +  determine "best".
> > +
> > +  @param[in]  PolicyTable    &nbs= p; Pointer to current policy table.
> > +  @param[in]  PolicyTableSize  Size of current p= olicy table.
> > +  @param[in]  VariableName     Sa= me as EFI_SET_VARIABLE.
> > +  @param[in]  VendorGuid     = ;  Same as EFI_SET_VARIABLE.
> > +  @param[out] ReturnPriority   [Optional] If poi= nter is provided,
return
> the
> > +          &nb= sp;            =         priority of the match. Same as > EvaluatePolicyMatch().
> > +          &nb= sp;            =         Only valid if a match is returne= d.
> > +
> > +  @retval     VARIABLE_POLICY_ENTRY*&n= bsp;   Best match that was
> found.
> > +  @retval     NULL   &n= bsp;            = ;      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        &nb= sp;         MatchPriority;
> > +  UINT8        &nb= sp;         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*)PolicyTa= ble +
> > PolicyTableSize)) {
> > +    //
> > +    // Check for a match.
> > +    //
> > +    if (EvaluatePolicyMatch (CurrentEntry, Varia= bleName, VendorGuid,
> > &CurrentPriority)) {
> > +      //
> > +      // If match is better, take it.<= br> > > +      //
> > +      if (BestResult =3D=3D NULL || Cu= rrentPriority < MatchPriority) {
> > +        BestResult =3D Curre= ntEntry;
> > +        MatchPriority =3D Cu= rrentPriority;
> > +      }
> > +
> > +      //
> > +      // If you've hit the highest-pri= ority match, can exit now.
> > +      //
> > +      if (MatchPriority =3D=3D 0) { > > +        break;
> > +      }
> > +    }
> > +
> > +    //
> > +    // If we're still in the loop, move to the n= ext entry.
> > +    //
> > +    CurrentEntry =3D GET_NEXT_POLICY (CurrentEnt= ry);  }
> > +
> > +  //
> > +  // 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 poli= cy tables to
> > +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 ca= nnot prove that the
> variable
> > is
> > +          &nb= sp;       locked.
> > +
> > +**/
> > +STATIC
> > +BOOLEAN
> > +IsVariableAlreadyLocked (
> > +  IN CHAR16    *VariableName,
> > +  IN EFI_GUID  *VendorGuid
> > +  )
> > +{
> > +  EFI_STATUS       &nbs= p;     Status;
> > +  UINT8        &nb= sp;         *PolicyTable;
> > +  UINT32        &n= bsp;        PolicyTableSize;
> > +  BOOLEAN        &= nbsp;       Result;
> > +  VARIABLE_POLICY_ENTRY  *MatchPolicy;
> > +  UINT8        &nb= sp;         MatchPriority;
> > +
> > +  Result =3D TRUE;
> > +
> > +  //
> > +  // First, we need to dump the existing policy table.
> > +  //
> > +  PolicyTableSize =3D 0;
> > +  PolicyTable =3D NULL;
> > +  Status =3D DumpVariablePolicy (PolicyTable, &PolicyT= ableSize);  if
> > + (Status !=3D EFI_BUFFER_TOO_SMALL) {
> > +    DEBUG ((DEBUG_ERROR, "%a - Failed to de= termine policy table
> > size! %r\n", __FUNCTION__, Status));
> > +    return FALSE;
> > +  }
> > +  PolicyTable =3D AllocateZeroPool (PolicyTableSize); = ; if (PolicyTable =3D=3D
> > + NULL) {
> > +    DEBUG ((DEBUG_ERROR, "%a - Failed to al= located space for policy
> table!
> > 0x%X\n", __FUNCTION__, PolicyTableSize));
> > +    return FALSE;
> > +  }
> > +  Status =3D DumpVariablePolicy (PolicyTable, &PolicyT= ableSize);  if
> > + (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "%a - Failed to du= mp 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 (
> > +          &nb= sp;       PolicyTable,
> > +          &nb= sp;       PolicyTableSize,
> > +          &nb= sp;       VariableName,
> > +          &nb= sp;       VendorGuid,
> > +          &nb= sp;       &MatchPriority
> > +          &nb= sp;       );
> > +  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 curr= ently locked.
> > +  //
> > +  if (MatchPolicy->LockPolicyType !=3D
> VARIABLE_POLICY_TYPE_LOCK_NOW) {
> > +    DEBUG ((DEBUG_INFO, "%a - Policy may no= t 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 enviro= nment
> > through
> > + EFI_SMM_VARIABLE_PROTOCOL is allowed.
> >
> >    @param[in] This     &= nbsp;    The VARIABLE_LOCK_PROTOCOL
> instance.
> > -  @param[in] VariableName  A pointer to the variable = name that will be
> > 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 be
> > made
> > +          &nb= sp;            =     read-only subsequently.
> > +  @param[in] VendorGuid    A pointer to the= vendor GUID that will be
> made
> > +          &nb= sp;            =     read-only subsequently.
> >
> > -  @retval EFI_SUCCESS      &= nbsp;    The variable specified by the
> VariableName and
> > the VendorGuid was marked
> > -          &nb= sp;            =          as pending to be read-only= .
> > +  @retval EFI_SUCCESS      &= nbsp;    The variable specified by the
> VariableName and
> > +          &nb= sp;            =          the VendorGuid was marked = as
> pending to be
> > +          &nb= sp;            =          read-only.
> >    @retval EFI_INVALID_PARAMETER VariableName or = VendorGuid is
> NULL.
> >           = ;            &n= bsp;          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
> > -          &nb= sp;            =          already been signaled.
> > -  @retval EFI_OUT_OF_RESOURCES  There is not enough r= esource 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
> > +          &nb= sp;            =          signaled.
> > +  @retval EFI_OUT_OF_RESOURCES  There is not enough r= esource to
> hold
> > the lock
> > +          &nb= sp;            =          request.
> >  **/
> >  EFI_STATUS
> >  EFIAPI
> >  VariableLockRequestToLock (
> > -  IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This,
> > -  IN       CHAR16  = ;            &n= bsp;        *VariableName,
> > -  IN       EFI_GUID &nb= sp;            =        *VendorGuid
> > +  IN CONST EDKII_VARIABLE_LOCK_PROTOCOL  *This,
> > +  IN CHAR16        = ;            &n= bsp;         *VariableName,
> > +  IN EFI_GUID       &nb= sp;            =         *VendorGuid
> >    )
> >  {
> > -  EFI_STATUS       &nbs= p;      Status;
> > -  VARIABLE_POLICY_ENTRY   *NewPolicy;
> > +  EFI_STATUS       &nbs= p;     Status;
> > +  VARIABLE_POLICY_ENTRY  *NewPolicy;
> > +
> > +  DEBUG ((DEBUG_ERROR, "!!! DEPRECATED INTERFACE !!! = %a() will go
> away
> > + soon!\n", __FUNCTION__));  DEBUG ((DEBUG_ERROR, &quo= t;!!! DEPRECATED
> > + INTERFACE !!! Please move to use Variable Policy!\n"));&n= bsp; DEBUG
> > + ((DEBUG_ERROR, "!!! DEPRECATED INTERFACE !!! Variable: %g= %s\n",
> > + VendorGuid, VariableName));
> >
> >    NewPolicy =3D NULL;
> > -  Status =3D CreateBasicVariablePolicy( VendorGuid,
> > -          &nb= sp;            =             &nb= sp;  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,
> > -          &nb= sp;            =             &nb= sp;  &NewPolicy );
> > +  Status =3D CreateBasicVariablePolicy(
> > +          &nb= sp;  VendorGuid,
> > +          &nb= sp;  VariableName,
> > +          &nb= sp;  VARIABLE_POLICY_NO_MIN_SIZE,
> > +          &nb= sp;  VARIABLE_POLICY_NO_MAX_SIZE,
> > +          &nb= sp;  VARIABLE_POLICY_NO_MUST_ATTR,
> > +          &nb= sp;  VARIABLE_POLICY_NO_CANT_ATTR,
> > +          &nb= sp;  VARIABLE_POLICY_TYPE_LOCK_NOW,
> > +          &nb= sp;  &NewPolicy
> > +          &nb= sp;  );
> >    if (!EFI_ERROR( Status )) {
> > -    Status =3D RegisterVariablePolicy( NewPolicy= );
> > +    Status =3D RegisterVariablePolicy (NewPolicy= );
> > +
> > +    //
> > +    // If the error returned is EFI_ALREADY_STAR= TED, 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 genera= te a DEBUG_ERROR
> message so
> > the
> > +    // duplicate lock can be removed.
> > +    //
> > +    if (Status =3D=3D EFI_ALREADY_STARTED) {
> > +      if (IsVariableAlreadyLocked (Var= iableName, VendorGuid)) {
> > +        DEBUG ((DEBUG_ERROR,= "  Variable: %g %s is already
> locked!\n",
> > VendorGuid, VariableName));
> > +        Status =3D EFI_SUCCE= SS;
> > +      }
> > +    }
> >    }
> > -  if (EFI_ERROR( Status )) {
> > +  if (EFI_ERROR (Status)) {
> >      DEBUG(( DEBUG_ERROR, "%a - Fa= iled to lock variable %s! %r\n",
> > __FUNCTION__, VariableName, Status ));
> > -    ASSERT_EFI_ERROR( Status );
> >    }
> >    if (NewPolicy !=3D NULL) {
> >      FreePool( NewPolicy );
> > --
> > 2.29.2.windows.2
> >
> >
> >
> >
> >


--_000_BN8PR11MB3666F30E5317D9E284A429D8CACA0BN8PR11MB3666namp_--