From nobody Wed May 8 20:14:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+82766+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+82766+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=hpe.com ARC-Seal: i=1; a=rsa-sha256; t=1635382859; cv=none; d=zohomail.com; s=zohoarc; b=bur+399rLehf9rpfcLV71jRA0S66NnlBQblTy5EGGoOZBFjtla5pIe2Y1vUZ3e5k9HuiQmhoKvCSPuCDjIocJXBkx+IDQoJ4+N1bDfcXAhO3kA8i0TTimd/pli14gCqfyWGc+Gpb1mRbdmb4pLOhpblP8E4bKP/hmvFuyRLQiVA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1635382859; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=dX0DJbYw5N4pNAZcprO2ThrFrNRLeb+JnoCDwxJT5bw=; b=MkhncwByk0ZwRv3xuqkkkSI1UkC5JFm+/fOw570oWJ1qbSdIhZazo+oQjpWDrJc9+0ClViX4edywh4yL+zTL6SgAClqgnay1JgjwM3k1EJBpunK0TCUmfiV7Mi5u7uT4eBdrUF+/HCUpuHIBtKbFdpIKOjQdBmGk9tXwjeW1K4Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+82766+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1635382859298468.6467225477446; Wed, 27 Oct 2021 18:00:59 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id ZIf3YY1788612xSYsaAcIkQ1; Wed, 27 Oct 2021 18:00:58 -0700 X-Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) by mx.groups.io with SMTP id smtpd.web08.5209.1635382849531202583 for ; Wed, 27 Oct 2021 18:00:58 -0700 X-Received: from pps.filterd (m0134423.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 19RNZfus013597; Thu, 28 Oct 2021 00:59:59 GMT X-Received: from g2t2352.austin.hpe.com (g2t2352.austin.hpe.com [15.233.44.25]) by mx0b-002e3701.pphosted.com with ESMTP id 3bxvwvj9kj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Oct 2021 00:59:58 +0000 X-Received: from g2t2360.austin.hpecorp.net (g2t2360.austin.hpecorp.net [16.196.225.135]) by g2t2352.austin.hpe.com (Postfix) with ESMTP id CF11762; Thu, 28 Oct 2021 00:59:57 +0000 (UTC) X-Received: from SAC2XFT1JT.asiapacific.hpqcorp.net (unknown [10.43.62.133]) by g2t2360.austin.hpecorp.net (Postfix) with ESMTP id A466B36; Thu, 28 Oct 2021 00:59:55 +0000 (UTC) From: "Abner Chang" To: devel@edk2.groups.io Cc: nickle.wang@hpe.com, Liming Gao Subject: [edk2-devel] [PATCH] edk2-staging/RedfishPkg: HII utility helper library Date: Thu, 28 Oct 2021 08:59:54 +0800 Message-Id: <20211028005954.35128-1-abner.chang@hpe.com> MIME-Version: 1.0 X-Proofpoint-GUID: N8ILU9egsan0Q2K_GgxujQqatFOAVaDh X-Proofpoint-ORIG-GUID: N8ILU9egsan0Q2K_GgxujQqatFOAVaDh X-HPE-SCL: -1 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@hpe.com X-Gm-Message-State: tosJvjAuVkN3roXkE7MivdOqx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1635382858; bh=b60v404MIPkmE7qO5/7jUSViZ86AAnZqmXgg0Xy2BUA=; h=Cc:Date:From:Reply-To:Subject:To; b=VuFABsgZ/K5a3d0M0ExDVhbAt+T46iaL7QyFKdv8FU26qrnjlCFjikokMHbN0WGtfkk M8/klMDoqDWaMQ73D8kUlAzy+GwbBsqll0IYbuyepo1PSxKJyuE4ktXyg8FH1V6qL+OKh KbqxywVNEtnZrftOT6Dd/jmsgqQnpvPAlWk= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1635382861272100001 Content-Type: text/plain; charset="utf-8" HiiUtilityLib is a helper library that provides the functions to manipulate HII options. Signed-off-by: Nickle Wang Cc: Abner Chang Cc: Liming Gao --- RedfishPkg/RedfishPkg.dec | 4 + .../Library/HiiUtilityLib/HiiUtilityLib.inf | 61 + RedfishPkg/Include/Library/HiiUtilityLib.h | 1195 ++++ .../Library/HiiUtilityLib/HiiExpression.h | 190 + .../Library/HiiUtilityLib/HiiInternal.h | 371 ++ .../Library/HiiUtilityLib/HiiExpression.c | 1367 +++++ .../Library/HiiUtilityLib/HiiIfrParse.c | 2671 +++++++++ .../HiiUtilityLib/HiiUtilityInternal.c | 5045 +++++++++++++++++ .../Library/HiiUtilityLib/HiiUtilityLib.c | 855 +++ 9 files changed, 11759 insertions(+) create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.inf create mode 100644 RedfishPkg/Include/Library/HiiUtilityLib.h create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiExpression.h create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiInternal.h create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiExpression.c create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiIfrParse.c create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.c diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec index 4d80515fe07..eac219ccbb9 100644 --- a/RedfishPkg/RedfishPkg.dec +++ b/RedfishPkg/RedfishPkg.dec @@ -55,6 +55,10 @@ # RedfishContentCodingLib|Include/Library/RedfishContentCodingLib.h =20 + ## @libraryclass Provides the library functions to parse IFR binary da= ta. + # + HiiUtilityLib|Include/Library/HiiUtilityLib.h + [LibraryClasses.Common.Private] ## @libraryclass Provides the private C runtime library functions. # CRT library is currently used by edk2 JsonLib (open source diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.inf b/RedfishPk= g/Library/HiiUtilityLib/HiiUtilityLib.inf new file mode 100644 index 00000000000..36a629a758b --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.inf @@ -0,0 +1,61 @@ +## @file +# Library to handle HII IFR data. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D HiiUtilityLib + FILE_GUID =3D D00DA028-F19A-47AF-B22A-6EE9E8BD7335 + MODULE_TYPE =3D UEFI_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D HiiUtilityLib|DXE_DRIVER UEFI_DRIVER = UEFI_APPLICATION + +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + HiiUtilityLib.c + HiiExpression.c + HiiUtilityInternal.c + HiiIfrParse.c + HiiInternal.h + HiiExpression.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + PrintLib + DebugLib + BaseMemoryLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + MemoryAllocationLib + HiiLib + +[Guids] + gZeroGuid + gEdkiiIfrBitVarstoreGuid + gEfiHiiPlatformSetupFormsetGuid + gEfiHiiStandardFormGuid + +[Protocols] + gEfiHiiDatabaseProtocolGuid + gEfiHiiConfigRoutingProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiDevicePathFromTextProtocolGuid + gEfiUnicodeCollation2ProtocolGuid + gEfiRegularExpressionProtocolGuid + gEfiUserManagerProtocolGuid + +[Depex] + TRUE diff --git a/RedfishPkg/Include/Library/HiiUtilityLib.h b/RedfishPkg/Includ= e/Library/HiiUtilityLib.h new file mode 100644 index 00000000000..1f164ba49c6 --- /dev/null +++ b/RedfishPkg/Include/Library/HiiUtilityLib.h @@ -0,0 +1,1195 @@ +/** @file + Definitinos of RedfishPlatformConfigLib + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef HII_UTILITY_LIB_ +#define HII_UTILITY_LIB_ + +#include +#include + +// +// IFR relative definition +// +#define EFI_HII_EXPRESSION_INCONSISTENT_IF 0 +#define EFI_HII_EXPRESSION_NO_SUBMIT_IF 1 +#define EFI_HII_EXPRESSION_GRAY_OUT_IF 2 +#define EFI_HII_EXPRESSION_SUPPRESS_IF 3 +#define EFI_HII_EXPRESSION_DISABLE_IF 4 +#define EFI_HII_EXPRESSION_VALUE 5 +#define EFI_HII_EXPRESSION_RULE 6 +#define EFI_HII_EXPRESSION_READ 7 +#define EFI_HII_EXPRESSION_WRITE 8 +#define EFI_HII_EXPRESSION_WARNING_IF 9 + +#define EFI_HII_VARSTORE_BUFFER 0 +#define EFI_HII_VARSTORE_NAME_VALUE 1 +#define EFI_HII_VARSTORE_EFI_VARIABLE 2 // EFI Varstore type fol= low UEFI spec before 2.3.1. +#define EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER 3 // EFI varstore type fol= low UEFI spec 2.3.1 and later. + +// +// HII_NAME_VALUE_NODE for name/value storage +// +typedef struct { + + UINTN Signature; + LIST_ENTRY Link; + CHAR16 *Name; + CHAR16 *Value; + +} HII_NAME_VALUE_NODE; + +#define HII_NAME_VALUE_NODE_SIGNATURE SIGNATURE_32 ('N', 'V', 'S', 'T') +#define HII_NAME_VALUE_NODE_FROM_LINK(a) CR (a, HII_NAME_VALUE_NODE, Link= , HII_NAME_VALUE_NODE_SIGNATURE) + +// +// Storage info +// +typedef union { + EFI_STRING_ID VarName; + UINT16 VarOffset; +} HII_VAR_STORE_INFO; + +// +// FormSet storage +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + UINT8 Type; // Storage type + EFI_HII_HANDLE HiiHandle; // HiiHandle for this varstore. + + // + // For all type of storages. + // + UINT16 VarStoreId; // VarStore ID. + EFI_GUID Guid; // VarStore Guid. + + // + // For EFI_IFR_VARSTORE, EFI_IFR_VARSTORE_EFI + // + CHAR16 *Name; // VarStore name + UINT16 Size; // Varatore size. + UINT8 *Buffer; // Buffer storage. + UINT8 *EditBuffer; // Edit copy for Buffer Storage + + // + // For EFI_IFR_VARSTORE_EFI: EFI Variable. + // + UINT32 Attributes; + + // + //For EFI_IFR_VARSTORE_NAME_VALUE. + // + LIST_ENTRY NameValueList; // List of NAME_VALUE_NODE + + CHAR16 *ConfigHdr; // + CHAR16 *ConfigRequest; // =3D + <= RequestElement> + UINTN ElementCount; // Number of in the <= ConfigRequest> + UINTN SpareStrLen; // Spare length of ConfigRequest strin= g buffer +} HII_FORMSET_STORAGE; + + +#define HII_STORAGE_SIGNATURE SIGNATURE_32 ('B', 'S', 'T', 'G') +#define HII_STORAGE_FROM_LINK(a) CR (a, HII_FORMSET_STORAGE, Link, HII_ST= ORAGE_SIGNATURE) + +// +// Definition of EXPRESS_RESULT +// +typedef enum { + ExpressFalse =3D 0, + ExpressGrayOut, + ExpressSuppress, + ExpressDisable +} EXPRESS_RESULT; + +// +// Definition of EXPRESS_LEVEL +// +typedef enum { + ExpressNone =3D 0, + ExpressForm, + ExpressStatement, + ExpressOption +} EXPRESS_LEVEL; + +// +// Definition of HII_EXPRESSION_OPCODE_EXTRA +// +typedef union { + + EFI_HII_VALUE Value; // EFI_IFR_UINT64, EFI_IFR_UINT32, EFI_I= FR_UINT16, EFI_IFR_UINT8, EFI_IFR_STRING_REF1 + UINT8 Format; // For EFI_IFR_TO_STRING, EFI_IFR_FIND + UINT8 Flags; // For EFI_IFR_SPAN + UINT8 RuleId; // For EFI_IFR_RULE_REF + EFI_GUID Guid; // For EFI_IFR_SECURITY, EFI_IFR_MATCH2 + + struct { + EFI_QUESTION_ID QuestionId; + EFI_HII_VALUE Value; + } EqIdValData; + + struct { + EFI_QUESTION_ID QuestionId1; + EFI_QUESTION_ID QuestionId2; + } EqIdIdData; + + struct { + EFI_QUESTION_ID QuestionId; // For EFI_IFR_EQ_ID_VAL_LIST + UINT16 ListLength; + UINT16 *ValueList; + } EqIdListData; + + struct { + EFI_QUESTION_ID QuestionId; + } QuestionRef1Data; + + struct { + EFI_STRING_ID DevicePath; // For EFI_IFR_QUESTION_REF3_3 + EFI_GUID Guid; + } QuestionRef3Data; + + struct { + HII_FORMSET_STORAGE *VarStorage; + HII_VAR_STORE_INFO VarStoreInfo; + UINT8 ValueType; + UINT8 ValueWidth; + CHAR16 *ValueName; + } GetSetData; + +} HII_EXPRESSION_OPCODE_EXTRA; + +typedef union _HII_DEPENDENCY_EXPRESSION HII_DEPENDENCY_EXPRESSION; + +// +// Definition of HII_EXPRESSION_CONSTANT +// +// Operand: +// +// EFI_IFR_TRUE +// EFI_IFR_FALSE +// EFI_IFR_ONE +// EFI_IFR_ONES +// EFI_IFR_ZERO +// EFI_IFR_UNDEFINED +// EFI_IFR_VERSION +// EFI_IFR_UINT8 +// EFI_IFR_UINT16 +// EFI_IFR_UINT32 +// EFI_IFR_UINT64 +// +typedef struct { + UINT8 Operand; + EFI_HII_VALUE Value; +} HII_EXPRESSION_CONSTANT; + +// +// Definition of HII_DEPENDENCY_DUP +// +typedef struct { + UINT8 Operand; +} HII_DEPENDENCY_DUP; + +// +// Definition of HII_DEPENDENCY_EQ_ID_VAL +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId; + EFI_HII_VALUE Value; +} HII_DEPENDENCY_EQ_ID_VAL; + +// +// Definition of HII_DEPENDENCY_EQ_ID_VAL +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId1; + EFI_QUESTION_ID QuestionId2; +} HII_DEPENDENCY_EQ_ID_ID; + +// +// Definition of HII_DEPENDENCY_EQ_ID_VAL_LIST +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId; + UINT16 ListLength; + UINT16 *ValueList; +} HII_DEPENDENCY_EQ_ID_VAL_LIST; + +// +// Definition of HII_DEPENDENCY_QUESTION_REF1 +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId; +} HII_DEPENDENCY_QUESTION_REF1; + +// +// Definition of HII_DEPENDENCY_RULE_REF +// +typedef struct { + UINT8 Operand; + UINT8 RuleId; +} HII_DEPENDENCY_RULE_REF; + +// +// Definition of HII_DEPENDENCY_STRING_REF1 +// +typedef struct { + UINT8 Operand; + EFI_HII_VALUE Value; +} HII_DEPENDENCY_STRING_REF1; + +// +// Definition of HII_DEPENDENCY_THIS +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId; +} HII_DEPENDENCY_THIS; + +// +// Definition of HII_DEPENDENCY_SECURITY +// +typedef struct { + UINT8 Operand; + EFI_GUID Permissions; +} HII_DEPENDENCY_SECURITY; + +// +// Definition of HII_DEPENDENCY_GET +// +typedef struct { + UINT8 Operand; + HII_FORMSET_STORAGE *VarStorage; + HII_VAR_STORE_INFO VarStoreInfo; + UINT8 ValueType; + UINT8 ValueWidth; + CHAR16 *ValueName; +} HII_DEPENDENCY_GET; + +// +// Definition of HII_DEPENDENCY_LENGTH +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_LENGTH; + +// +// Definition of HII_DEPENDENCY_BITWISE_NOT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_BITWISE_NOT; + +// +// Definition of HII_DEPENDENCY_STRING_REF2 +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_STRING_REF2; + +// +// Definition of HII_DEPENDENCY_QUESTION_REF2 +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_QUESTION_REF2; + +// +// Definition of HII_DEPENDENCY_QUESTION_REF3 +// +typedef struct { + UINT8 Operand; + EFI_STRING_ID DevicePath; + EFI_GUID Guid; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_QUESTION_REF3; + +// +// Definition of HII_DEPENDENCY_TO_BOOLEAN +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_BOOLEAN; + +// +// Definition of HII_DEPENDENCY_TO_STRING +// +typedef struct { + UINT8 Operand; + UINT8 Format; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_STRING; + +// +// Definition of HII_DEPENDENCY_TO_UINT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_UINT; + +// +// Definition of HII_DEPENDENCY_TO_UPPER +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_UPPER; + +// +// Definition of HII_DEPENDENCY_TO_LOWER +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_LOWER; + +// +// Definition of HII_DEPENDENCY_SET +// +typedef struct { + UINT8 Operand; + HII_FORMSET_STORAGE *VarStorage; + HII_VAR_STORE_INFO VarStoreInfo; + UINT8 ValueType; + UINT8 ValueWidth; + CHAR16 *ValueName; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_SET; + +// +// Definition of HII_DEPENDENCY_NOT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_NOT; + +// +// Definition of HII_DEPENDENCY_CATENATE +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *LeftStringExp; + HII_DEPENDENCY_EXPRESSION *RightStringExp; +} HII_DEPENDENCY_CATENATE; + +// +// Definition of HII_DEPENDENCY_MATCH +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *StringExp; + HII_DEPENDENCY_EXPRESSION *PatternExp; +} HII_DEPENDENCY_MATCH; + +// +// Definition of HII_DEPENDENCY_MATCH2 +// +typedef struct { + UINT8 Operand; + EFI_GUID SyntaxType; + HII_DEPENDENCY_EXPRESSION *StringExp; + HII_DEPENDENCY_EXPRESSION *PatternExp; +} HII_DEPENDENCY_MATCH2; + +// +// Definition of HII_DEPENDENCY_MULT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_MULT; + +// +// Definition of HII_DEPENDENCY_DIV +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; // right value + HII_DEPENDENCY_EXPRESSION *LeftHandExp; // left value +} HII_DEPENDENCY_DIV; + +// +// Definition of HII_DEPENDENCY_MOD +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; // right value + HII_DEPENDENCY_EXPRESSION *LeftHandExp; // left value +} HII_DEPENDENCY_MOD; + +// +// Definition of HII_DEPENDENCY_ADD +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; // right value + HII_DEPENDENCY_EXPRESSION *LeftHandExp; // left value +} HII_DEPENDENCY_ADD; + +// +// Definition of HII_DEPENDENCY_SUBTRACT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; // right value + HII_DEPENDENCY_EXPRESSION *LeftHandExp; // left value +} HII_DEPENDENCY_SUBTRACT; + +// +// Definition of HII_DEPENDENCY_SHIFT_LEFT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_SHIFT_LEFT; + +// +// Definition of HII_DEPENDENCY_SHIFT_RIGHT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_SHIFT_RIGHT; + +// +// Definition of HII_DEPENDENCY_GREATER_THAN +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_GREATER_THAN; + +// +// Definition of HII_DEPENDENCY_GREATER_EQUAL +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_GREATER_EQUAL; + +// +// Definition of HII_DEPENDENCY_LESS_THAN +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_LESS_THAN; + +// +// Definition of HII_DEPENDENCY_LESS_EQUAL +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_LESS_EQUAL; + +// +// Definition of HII_DEPENDENCY_EQUAL +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_EQUAL; + +// +// Definition of HII_DEPENDENCY_NOT_EQUAL +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_NOT_EQUAL; + +// +// Definition of HII_DEPENDENCY_BITWISE_AND +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_BITWISE_AND; + +// +// Definition of HII_DEPENDENCY_BITWISE_OR +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_BITWISE_OR; + +// +// Definition of HII_DEPENDENCY_AND +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_AND; + +// +// Definition of HII_DEPENDENCY_OR +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_OR; + +// +// Definition of HII_DEPENDENCY_CONDITIONAL +// +// Ternary expression +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *CondTrueValExp; // right value + HII_DEPENDENCY_EXPRESSION *CondFalseValExp; // middle value + HII_DEPENDENCY_EXPRESSION *ConditionExp; // left value +} HII_DEPENDENCY_CONDITIONAL; + +// +// Definition of HII_DEPENDENCY_FIND +// +typedef struct { + UINT8 Operand; + UINT8 Format; + HII_DEPENDENCY_EXPRESSION *IndexExp; // right value + HII_DEPENDENCY_EXPRESSION *StringToCompWithExp; // middle value + HII_DEPENDENCY_EXPRESSION *StringToSearchExp; // left value +} HII_DEPENDENCY_FIND; + +// +// Definition of HII_DEPENDENCY_MID +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *LengthExp; // right value + HII_DEPENDENCY_EXPRESSION *IndexExp; // middle value + HII_DEPENDENCY_EXPRESSION *StringOrBufferExp; // left value +} HII_DEPENDENCY_MID; + +// +// Definition of HII_DEPENDENCY_TOKEN +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *IndexExp; // right value + HII_DEPENDENCY_EXPRESSION *DelimiterExp; // middle value + HII_DEPENDENCY_EXPRESSION *StringToSearchExp; // left value +} HII_DEPENDENCY_TOKEN; + +// +// Definition of HII_DEPENDENCY_SPAN +// +typedef struct { + UINT8 Operand; + UINT8 Flags; + HII_DEPENDENCY_EXPRESSION *IndeExp; // right value + HII_DEPENDENCY_EXPRESSION *CharsetExp; // middle value + HII_DEPENDENCY_EXPRESSION *StringToSearchExp; // left value +} HII_DEPENDENCY_SPAN; + +// +// Map expression +// +typedef struct { + HII_DEPENDENCY_EXPRESSION *MatchExp; + HII_DEPENDENCY_EXPRESSION *ReturnExp; +} HII_DEPENDENCY_EXPRESSION_PAIR; + +// +// Definition of HII_DEPENDENCY_MAP +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExp; + HII_DEPENDENCY_EXPRESSION_PAIR *ExpPair; + UINT8 ExpPairNo; +} HII_DEPENDENCY_MAP; + +// +// Definition of HII_DEPENDENCY_EXPRESSION +// +union _HII_DEPENDENCY_EXPRESSION { + // + // Constant + // + HII_EXPRESSION_CONSTANT ContantExp; + // + // build-in expression + // + HII_DEPENDENCY_DUP DupExp; + HII_DEPENDENCY_EQ_ID_VAL EqIdValExp; + HII_DEPENDENCY_EQ_ID_ID EqIdIdExp; + HII_DEPENDENCY_EQ_ID_VAL_LIST EqIdListExp; + HII_DEPENDENCY_QUESTION_REF1 QuestionRef1Exp; + HII_DEPENDENCY_RULE_REF RuleRefExp; + HII_DEPENDENCY_STRING_REF1 StringRef1Exp; + HII_DEPENDENCY_THIS ThisExp; + HII_DEPENDENCY_SECURITY SecurityExp; + HII_DEPENDENCY_GET GetExp; + + // + //unary expression + // + HII_DEPENDENCY_LENGTH LengthExp; + HII_DEPENDENCY_BITWISE_NOT BitWiseNotExp; + HII_DEPENDENCY_STRING_REF2 StringRef2Exp; + HII_DEPENDENCY_QUESTION_REF2 QuestionRef2Exp; + HII_DEPENDENCY_QUESTION_REF3 QuestionRef3Exp; + HII_DEPENDENCY_TO_BOOLEAN ToBooleanExp; + HII_DEPENDENCY_TO_STRING ToStringExp; + HII_DEPENDENCY_TO_UINT ToUintExp; + HII_DEPENDENCY_TO_UPPER ToUpperExp; + HII_DEPENDENCY_TO_LOWER ToLowerExp; + HII_DEPENDENCY_SET SetExp; + HII_DEPENDENCY_NOT NotExp; + + // + // Binary expression + // + HII_DEPENDENCY_CATENATE CatenateExp; + HII_DEPENDENCY_MATCH MatchExp; + HII_DEPENDENCY_MATCH2 Match2Exp; + HII_DEPENDENCY_MULT MultExp; + HII_DEPENDENCY_DIV DivExp; + HII_DEPENDENCY_MOD ModExp; + HII_DEPENDENCY_ADD AddExp; + HII_DEPENDENCY_SUBTRACT SubtractExp; + HII_DEPENDENCY_SHIFT_LEFT ShiftLeftExp; + HII_DEPENDENCY_SHIFT_RIGHT ShiftRightExp; + HII_DEPENDENCY_GREATER_THAN GreaterThanExp; + HII_DEPENDENCY_GREATER_EQUAL GreaterEqualExp; + HII_DEPENDENCY_LESS_THAN LessThanExp; + HII_DEPENDENCY_LESS_EQUAL LessEqualExp; + HII_DEPENDENCY_EQUAL EqualExp; + HII_DEPENDENCY_NOT_EQUAL NotEqualExp; + HII_DEPENDENCY_BITWISE_AND BitwiseAndExp; + HII_DEPENDENCY_BITWISE_OR BitwiseOrExp; + HII_DEPENDENCY_AND AndExp; + HII_DEPENDENCY_OR OrExp; + + // + // ternary expression + // + HII_DEPENDENCY_CONDITIONAL ConditionalExp; + HII_DEPENDENCY_FIND FindExp; + HII_DEPENDENCY_MID MidExp; + HII_DEPENDENCY_TOKEN TokenExp; + HII_DEPENDENCY_SPAN SpanExp; + HII_DEPENDENCY_MAP MapExp; +}; + +// +// Definition of HII_EXPRESSION_OPCODE +// +typedef struct { + + UINTN Signature; + LIST_ENTRY Link; + UINT8 Operand; + HII_EXPRESSION_OPCODE_EXTRA ExtraData; + LIST_ENTRY MapExpressionList; // nested expressions i= nside of Map opcode. +} HII_EXPRESSION_OPCODE; + +#define HII_EXPRESSION_OPCODE_SIGNATURE SIGNATURE_32 ('E', 'X', 'O', 'P') +#define HII_EXPRESSION_OPCODE_FROM_LINK(a) CR (a, HII_EXPRESSION_OPCODE, = Link, HII_EXPRESSION_OPCODE_SIGNATURE) + +// +// Definition of HII_EXPRESSION +// +typedef struct { + + UINTN Signature; + LIST_ENTRY Link; + UINT8 Type; // Type for this expressi= on + EFI_IFR_OP_HEADER *OpCode; // Save the opcode buffer. + LIST_ENTRY OpCodeListHead; // OpCodes consist of thi= s expression (HII_EXPRESSION_OPCODE) + HII_DEPENDENCY_EXPRESSION *RootDepdencyExp; // Expression OpCodes tre= e layout to describe dependency of this expression. + + union { + UINT8 RuleId; // For EFI_IFR_RULE only + EFI_STRING_ID Error; // For EFI_IFR_NO_SUBMIT_IF, EFI_IFR= _INCONSISTENT_IF only + + struct { + EFI_STRING_ID WarningIfError; + UINT8 TimeOut; + } WarningIfData; + + } ExtraData; + + EFI_HII_VALUE Result; // Expression evaluation result + +} HII_EXPRESSION; + +#define HII_EXPRESSION_SIGNATURE SIGNATURE_32 ('F', 'E', 'X', 'P') +#define HII_EXPRESSION_FROM_LINK(a) CR (a, HII_EXPRESSION, Link, HII_EXPR= ESSION_SIGNATURE) + +// +// Definition of HII_EXPRESSION_LIST +// +typedef struct { + UINTN Signature; + UINTN Count; + HII_EXPRESSION *Expression[1]; // Array[Count] of expressions +} HII_EXPRESSION_LIST; + +#define HII_EXPRESSION_LIST_SIGNATURE SIGNATURE_32 ('F', 'E', 'X', 'R') + +// +// Definition of HII_STATEMENT_VALUE +// +typedef struct { + + // + // HII Data Type + // + UINT8 Type; + EFI_IFR_TYPE_VALUE Value; + // + // Buffer Data and Length if Type is EFI_IFR_TYPE_BUFFER or EFI_IFR_TYPE= _STRING + // + UINT8 *Buffer; + UINT16 BufferLen; + UINT8 BufferValueType; // Data type for buffer internal d= ata, currently only for orderedlist + +} HII_STATEMENT_VALUE; + +// +// Default value +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + UINT16 DefaultId; + HII_STATEMENT_VALUE Value; // Default value + + HII_EXPRESSION *ValueExpression; // Not-NULL indicates default v= alue is provided by EFI_IFR_VALUE +} HII_QUESTION_DEFAULT; + +#define HII_QUESTION_DEFAULT_SIGNATURE SIGNATURE_32 ('Q', 'D', 'F', 'T') +#define HII_QUESTION_DEFAULT_FROM_LINK(a) CR (a, HII_QUESTION_DEFAULT, Li= nk, HII_QUESTION_DEFAULT_SIGNATURE) + +#define HII_QUESTION_OPTION_SIGNATURE SIGNATURE_32 ('Q', 'O', 'P', 'T') + +// +// Option value +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + EFI_IFR_ONE_OF_OPTION *OpCode; // OneOfOption Data + + EFI_STRING_ID Text; + UINT8 Flags; + HII_STATEMENT_VALUE Value; + EFI_IMAGE_ID ImageId; + + HII_EXPRESSION_LIST *SuppressExpression; // Non-NULL indicates nested= inside of SuppressIf +} HII_QUESTION_OPTION; + +#define HII_QUESTION_OPTION_FROM_LINK(a) CR (a, HII_QUESTION_OPTION, Link= , HII_QUESTION_OPTION_SIGNATURE) + +// +//class of default +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + UINT16 DefaultId; + EFI_STRING_ID DefaultName; +} HII_FORMSET_DEFAULTSTORE; + +#define HII_FORMSET_DEFAULTSTORE_SIGNATURE SIGNATURE_32 ('F', 'D', 'F', '= S') +#define HII_FORMSET_DEFAULTSTORE_FROM_LINK(a) CR (a, HII_FORMSET_DEFAULTS= TORE, Link, HII_FORMSET_DEFAULTSTORE_SIGNATURE) + +// +// Definition of HII_STATEMENT_EXTRA +// +typedef union { + + UINT8 Flags; + EFI_STRING_ID TextTwo; + EFI_DEFAULT_ID DefaultId; + EFI_STRING_ID QuestionConfig; + EFI_GUID Guid; + + struct { + UINT8 Flags; + UINT64 Minimum; // for EFI_IFR_ONE_OF/EFI_IFR_NUMERIC,= it's Min/Max value + UINT64 Maximum; // for EFI_IFR_STRING/EFI_IFR_PASSWORD= , it's Min/Max length + UINT64 Step; + EFI_GUID Guid; + } NumData; + + struct { + UINT8 Flags; + UINT8 MaxContainers; // for EFI_IFR_ORDERED_LIST + } OrderListData; + + struct { + UINT8 Flags; + UINT8 MinSize; + UINT8 MaxSize; + } StrData; + + struct { + UINT16 MinSize; + UINT16 MaxSize; + } PwdData; + +} HII_STATEMENT_EXTRA; + +// +// Statement (Question) +// +typedef struct _HII_STATEMENT HII_STATEMENT; +struct _HII_STATEMENT{ + UINTN Signature; + LIST_ENTRY Link; + + UINT8 Operand; // The operand (first byte) of t= his Statement or Question + EFI_IFR_OP_HEADER *OpCode; + + // + // Statement Header + // + EFI_STRING_ID Prompt; + EFI_STRING_ID Help; + + // + // Question Header + // + EFI_QUESTION_ID QuestionId; // Question id, the value of zer= o is reserved + EFI_VARSTORE_ID VarStoreId; // VarStore id, a value of zero = indicates no variable storage + HII_VAR_STORE_INFO VarStoreInfo; // VarStoreInfoIf VarStoreId ref= ers to Buffer Storage (EFI_IFR_VARSTORE or EFI_IFR_VARSTORE_EFI), then VarS= toreInfo contains a 16-bit Buffer Storage offset (VarOffset). + // If VarStoreId refers to Name/= Value Storage (EFI_IFR_VARSTORE_NAME_VALUE), then VarStoreInfo contains the= String ID of the name (VarName) for this name/value pair. + UINT8 QuestionFlags; // The flag of this Question.(Re= adonly, reset required, calback attribute....) + + BOOLEAN QuestionReferToBitField; // Whether the questio= n is stored in a bit field. + UINT16 StorageWidth; // The storage width o= f this Question. + UINT16 BitStorageWidth; // The Storage width o= f this Question in bit level. + UINT16 BitVarOffset; // The storahe offset = of this Question in bit level. + CHAR16 *VariableName; // Name/Value or EFI V= ariable name + CHAR16 *BlockName; // Buffer storage bloc= k name: "OFFSET=3D...WIDTH=3D..." + + HII_FORMSET_STORAGE *Storage; // Point to the storag= e that store this question. + HII_STATEMENT_EXTRA ExtraData; + + BOOLEAN Locked; // Whether this statement is = locked. + + HII_STATEMENT_VALUE Value; + + // + // Get from IFR parsing + // + + HII_STATEMENT *ParentStatement; // Parent Statement of curren= t statement. + HII_EXPRESSION_LIST *ExpressionList; // nesting inside of GrayO= utIf/DisableIf/SuppressIf + HII_EXPRESSION *ValueExpression; // nested EFI_IFR_VALUE, p= rovide Question value and indicate Question is ReadOnly + + EFI_IMAGE_ID ImageId; // nested EFI_IFR_IMAGE + UINT8 RefreshInterval; // nested EFI_IFR_REFRESH, = refresh interval(in seconds) for Question value, 0 means no refresh + + LIST_ENTRY DefaultListHead; // nested EFI_IFR_DEFAULT l= ist (HII_QUESTION_DEFAULT), provide default values + LIST_ENTRY OptionListHead; // nested EFI_IFR_ONE_OF_OP= TION list (HII_QUESTION_OPTION) + LIST_ENTRY InconsistentListHead; // nested inconsistent expr= ession list (HII_EXPRESSION) + LIST_ENTRY NoSubmitListHead; // nested nosubmit expressi= on list (HII_EXPRESSION) + LIST_ENTRY WarningListHead; // nested warning expressio= n list (HII_EXPRESSION) + + HII_EXPRESSION *ReadExpression; // nested EFI_IFR_READ, pr= ovide this question value by read expression. + HII_EXPRESSION *WriteExpression; // nested EFI_IFR_WRITE, e= valuate write expression after this question value is set. +}; + +#define HII_STATEMENT_SIGNATURE SIGNATURE_32 ('H', 'S', 'T', 'A') +#define HII_STATEMENT_FROM_LINK(a) CR (a, HII_STATEMENT, Link, HII_STATEM= ENT_SIGNATURE) + +// +// Form +// +#define STANDARD_MAP_FORM_TYPE 0x01 + +typedef struct { + + UINTN Signature; + LIST_ENTRY Link; + + UINT16 FormId; // FormId of normal form or f= ormmap form. + EFI_STRING_ID FormTitle; // FormTile of normal form, o= r FormMapMethod title of formmap form. + UINT16 FormType; // Specific form type for the= different form. + + EFI_IMAGE_ID ImageId; // The image id. + + BOOLEAN ModalForm; // Whether this is a modal fo= rm. + BOOLEAN Locked; // Whether this form is locke= d. + EFI_GUID RefreshGuid; // Form refresh event guid. + + LIST_ENTRY StatementListHead; // List of Statements and Que= stions (HII_STATEMENT) + LIST_ENTRY ConfigRequestHead; // List of configreques for a= ll storage. + LIST_ENTRY RuleListHead; // nesed EFI_IFR_RULE list, p= re-defined expressions attached to the form. + HII_EXPRESSION_LIST *SuppressExpression; // nesting inside of Suppress= If + +} HII_FORM; + + +#define HII_FORM_SIGNATURE SIGNATURE_32 ('F', 'F', 'R', 'M') +#define HII_FORM_FROM_LINK(a) CR (a, HII_FORM, Link, HII_FORM_SIGNATURE) + +// +// FormSet +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + EFI_HII_HANDLE HiiHandle; // Unique id fo= r formset, HII Hanlde of this FormSet package. + EFI_HANDLE DriverHandle; // EFI_HANDLE w= hich was registered with the package list in NewPackageList(). + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; // ConfigAccess= Protocol associated with this HiiPackageList + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + UINTN IfrBinaryLength; // Ifr binary d= ata length of this formset. + UINT8 *IfrBinaryData; // Point to the= Ifr binary data. + + EFI_GUID Guid; // Formset Guid. + EFI_STRING_ID FormSetTitle; // String Id of= Formset title. + EFI_STRING_ID Help; // String Id of= Formset title. + + UINT8 NumberOfClassGuid; // Class Guid n= ame + EFI_GUID ClassGuid[3]; // Up to three = ClassGuid + + EFI_IMAGE_ID ImageId; // The image id. + + LIST_ENTRY StatementListOSF; // Statement li= st out side of the form. + LIST_ENTRY StorageListHead; // Storage list= (HII_FORMSET_STORAGE) + LIST_ENTRY DefaultStoreListHead; // DefaultStore= list (HII_FORMSET_DEFAULTSTORE) + LIST_ENTRY FormListHead; // Form list (H= II_FORM_BROWSER_FORM) + +} HII_FORMSET; + + +#define HII_FORMSET_SIGNATURE SIGNATURE_32 ('H', 'I', 'F', 'S') +#define HII_FORMSET_FROM_LINK(a) CR (a, HII_FORMSET, Link, HII_FORMSET_SI= GNATURE) + +// +// Get/set question value from/to. +// +typedef enum { + GetSetValueWithBuffer =3D 0, // Get/Set question value from/to buf= fer in the storage. + GetSetValueWithHiiDriver, // Get/Set question value from/to hii d= river. + GetSetValueWithBoth, // Compare the editbuffer with buffer f= or this question, not use the question value. + GetSetValueWithMax // Invalid value. +} GET_SET_QUESTION_VALUE_WITH; + +/** + Initialize the internal data structure of a FormSet. + + @param Handle PackageList Handle + @param FormSetGuid On input, GUID or class GUID of a formset= . If not + specified (NULL or zero GUID), take the f= irst + FormSet with class GUID EFI_HII_PLATFORM_= SETUP_FORMSET_GUID + found in package list. + On output, GUID of the formset found(if n= ot NULL). + @param FormSet FormSet data structure. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The specified FormSet could not be found. + +**/ +EFI_STATUS +CreateFormSetFromHiiHandle ( + IN EFI_HII_HANDLE Handle, + IN OUT EFI_GUID *FormSetGuid, + OUT HII_FORMSET *FormSet + ); + +/** + Initialize a Formset and get current setting for Questions. + + @param FormSet FormSet data structure. + +**/ +VOID +InitializeFormSet ( + IN OUT HII_FORMSET *FormSet + ); + +/** + Free resources allocated for a FormSet. + + @param FormSet Pointer of the FormSet + +**/ +VOID +DestroyFormSet ( + IN OUT HII_FORMSET *FormSet + ); + +/** + Save Question Value to the memory, but not to storage. + + @param FormSet FormSet data structure. + @param Form Form data structure. + @param Question Pointer to the Question. + @param QuestionValue New Question Value to be set. + + @retval EFI_SUCCESS The question value has been set successfu= lly. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +EFI_STATUS +SetQuestionValue ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN OUT HII_STATEMENT *Question, + IN HII_STATEMENT_VALUE *QuestionValue + ); + +/** + Get Question's current Value from storage. + + @param FormSet FormSet data structure. + @param Form Form data structure. + @param Question Question to be initialized. + + @return the current Question Value in storage if success. + @return NULL if Question is not found or any error occurs. + +**/ +HII_STATEMENT_VALUE * +RetrieveQuestion ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN OUT HII_STATEMENT *Question + ); + +/** + Get Question's current Value. + + @param[in] FormSet FormSet data structure. + @param[in] Form Form data structure. + @param[out] Question Question to be initialized. + @param[in] GetValueFrom Where to get value, may from editbuf= fer, buffer or hii driver. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Formset, Form or Question is NULL. + +**/ +EFI_STATUS +GetQuestionValue ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN OUT HII_STATEMENT *Question, + IN GET_SET_QUESTION_VALUE_WITH GetValueFrom + ); + +/** + Submit data for a form. + + @param FormSet FormSet which contains the Form. + @param Form Form to submit. + + @retval EFI_SUCCESS The function completed successfully. + @retval Others Other errors occur. + +**/ +EFI_STATUS +SubmitForm ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form + ); + +/** + Evaluate the result of a HII expression. + + If Expression is NULL, then ASSERT. + + @param FormSet FormSet associated with this expression. + @param Form Form associated with this expression. + @param Expression Expression to be evaluated. + + @retval EFI_SUCCESS The expression evaluated successfuly + @retval EFI_NOT_FOUND The Question which referenced by a Questi= onId + could not be found. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + @retval EFI_ACCESS_DENIED The pop operation underflowed the stack + @retval EFI_INVALID_PARAMETER Syntax error with the Expression + +**/ +EFI_STATUS +EvaluateHiiExpression ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN OUT HII_EXPRESSION *Expression + ); + +/** + Retrieve dependencies within an expression. These dependencies can expre= ss how + this expression will be evaluated. + + @param Expression Expression to retrieve dependencies. + + @retval EFI_SUCCESS The dependencies were successfully retrie= ved. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory. + +**/ +EFI_STATUS +GetHiiExpressionDependency ( + IN HII_EXPRESSION *Expression + ); + +/** + Evaluate the result of a HII expression. + + If Expression is NULL, then ASSERT. + + @param FormSet FormSet associated with this expression. + @param Form Form associated with this expression. + @param Expression Expression to be evaluated. + + @retval EFI_SUCCESS The expression evaluated successfuly + @retval EFI_NOT_FOUND The Question which referenced by a Questi= onId + could not be found. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + @retval EFI_ACCESS_DENIED The pop operation underflowed the stack + @retval EFI_INVALID_PARAMETER Syntax error with the Expression + +**/ +EFI_STATUS +HpEvaluateHiiExpression ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN OUT HII_EXPRESSION *Expression + ); + +#endif // _HII_UTILITY_LIB_ diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h b/RedfishPkg/= Library/HiiUtilityLib/HiiExpression.h new file mode 100644 index 00000000000..e96c07b4de2 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h @@ -0,0 +1,190 @@ +/** @file + Definitinos of RedfishPlatformConfigLib + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef HII_EXPRESSION_H_ +#define HII_EXPRESSION_H_ + +#include + +/** + Get the expression list count. + + @param[in] Level Which type this expression belong to. For= m, + statement or option? + + @retval >=3D0 The expression count + @retval -1 Input parameter error. + +**/ +INTN +GetConditionalExpressionCount ( + IN EXPRESS_LEVEL Level + ); + +/** + Get the expression Buffer pointer. + + @param[in] Level Which type this expression belong to. For= m, + statement or option? + + @retval The start pointer of the expression buffer or NULL. + +**/ +HII_EXPRESSION ** +GetConditionalExpressionList ( + IN EXPRESS_LEVEL Level + ); + +/** + Push the expression options onto the Stack. + + @param[in] Pointer Pointer to the current expression. + @param[in] Level Which type this expression belong to. For= m, + statement or option? + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushConditionalExpression ( + IN HII_EXPRESSION *Pointer, + IN EXPRESS_LEVEL Level + ); + +/** + Pop the expression options from the Stack + + @param[in] Level Which type this expression belong to. For= m, + statement or option? + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopConditionalExpression ( + IN EXPRESS_LEVEL Level + ); + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetCurrentExpressionStack ( + VOID + ); + +/** + Push current expression onto the Stack + + @param[in] Pointer Pointer to current expression. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushCurrentExpression ( + IN VOID *Pointer + ); + +/** + Pop current expression from the Stack + + @param[in] Pointer Pointer to current expression to be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopCurrentExpression ( + OUT VOID **Pointer + ); + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetMapExpressionListStack ( + VOID + ); + +/** + Push the list of map expression onto the Stack + + @param[in] Pointer Pointer to the list of map expression to = be pushed. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushMapExpressionList ( + IN VOID *Pointer + ); + +/** + Pop the list of map expression from the Stack + + @param[in] Pointer Pointer to the list of map expression to = be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopMapExpressionList ( + OUT VOID **Pointer + ); + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetScopeStack ( + VOID + ); + +/** + Push an Operand onto the Stack + + @param[in] Operand Operand to push. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + +**/ +EFI_STATUS +PushScope ( + IN UINT8 Operand + ); + +/** + Pop an Operand from the Stack + + @param[out] Operand Operand to pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + +**/ +EFI_STATUS +PopScope ( + OUT UINT8 *Operand + ); + +#endif diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiInternal.h b/RedfishPkg/Li= brary/HiiUtilityLib/HiiInternal.h new file mode 100644 index 00000000000..1106896dc46 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiInternal.h @@ -0,0 +1,371 @@ +/** @file + Definitinos of RedfishPlatformConfigLib + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef HII_INTERNAL_H_ +#define HII_INTERNAL_H_ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HiiExpression.h" +#include + +typedef struct { + + UINTN Signature; + LIST_ENTRY Link; + + CHAR16 *ConfigRequest; // =3D = + + CHAR16 *ConfigAltResp; // Alt config response string for = this ConfigRequest. + UINTN ElementCount; // Number of in t= he + UINTN SpareStrLen; + CHAR16 *RestoreConfigRequest; // When submit form fail, t= he element need to be restored + CHAR16 *SyncConfigRequest; // When submit form fail, t= he element need to be synced + + HII_FORMSET_STORAGE *Storage; +} HII_FORM_CONFIG_REQUEST; + +#define HII_FORM_CONFIG_REQUEST_SIGNATURE SIGNATURE_32 ('F', 'C', 'R', 'S= ') +#define HII_FORM_CONFIG_REQUEST_FROM_LINK(a) CR (a, HII_FORM_CONFIG_REQUE= ST, Link, HII_FORM_CONFIG_REQUEST_SIGNATURE) + +// Incremental string lenght of ConfigRequest +// +#define CONFIG_REQUEST_STRING_INCREMENTAL 1024 + +/** + Allocate new memory and then copy the Unicode string Source to Destinati= on. + + @param Dest Location to copy string + @param Src String to copy + +**/ +VOID +NewStringCpy ( + IN OUT CHAR16 **Dest, + IN CHAR16 *Src + ); + +/** + Set Value of given Name in a NameValue Storage. + + @param Storage The NameValue Storage. + @param Name The Name. + @param Value The Value to set. + @param ReturnNode The node use the input name. + + @retval EFI_SUCCESS Value found for given Name. + @retval EFI_NOT_FOUND No such Name found in NameValue storage. + +**/ +EFI_STATUS +SetValueByName ( + IN HII_FORMSET_STORAGE *Storage, + IN CHAR16 *Name, + IN CHAR16 *Value, + OUT HII_NAME_VALUE_NODE **ReturnNode + ); + +/** + Get bit field value from the buffer and then set the value for the quest= ion. + Note: Data type UINT32 can cover all the bit field value. + + @param Question The question refer to bit field. + @param Buffer Point to the buffer which the question value get= from. + @param QuestionValue The Question Value retrieved from Bits. + +**/ +VOID +GetBitsQuestionValue ( + IN HII_STATEMENT *Question, + IN UINT8 *Buffer, + OUT HII_STATEMENT_VALUE *QuestionValue + ); + +/** + Set bit field value to the buffer. + Note: Data type UINT32 can cover all the bit field value. + + @param Question The question refer to bit field. + @param Buffer Point to the buffer which the question value set= to. + @param Value The bit field value need to set. + +**/ +VOID +SetBitsQuestionValue ( + IN HII_STATEMENT *Question, + IN OUT UINT8 *Buffer, + IN UINT32 Value + ); + +/** + Convert the buffer value to HiiValue. + + @param Question The question. + @param Value Unicode buffer save the question value. + @param QuestionValue The Question Value retrieved from Buffer. + + @retval Status whether convert the value success. + +**/ +EFI_STATUS +BufferToValue ( + IN HII_STATEMENT *Question, + IN CHAR16 *Value, + OUT HII_STATEMENT_VALUE *QuestionValue + ); + +/** + Get the string based on the StringId and HII Package List Handle. + + @param Token The String's ID. + @param HiiHandle The package list in the HII database to s= earch for + the specified string. + + @return The output string. + +**/ +CHAR16* +GetToken ( + IN EFI_STRING_ID Token, + IN EFI_HII_HANDLE HiiHandle + ); + +/** + Converts the unicode character of the string from uppercase to lowercase. + This is a internal function. + + @param ConfigString String to be converted + +**/ +VOID +EFIAPI +HiiToLower ( + IN EFI_STRING ConfigString + ); + +/** + Evaluate if the result is a non-zero value. + + @param Result The result to be evaluated. + + @retval TRUE It is a non-zero value. + @retval FALSE It is a zero value. + +**/ +BOOLEAN +IsTrue ( + IN EFI_HII_VALUE *Result + ); + +/** + Set a new string to string package. + + @param[in] String A pointer to the Null-terminated Unicode= string + to add or update in the String Package a= ssociated + with HiiHandle. + @param[in] HiiHandle A handle that was previously registered = in the + HII Database. + + @return the Id for this new string. + +**/ +EFI_STRING_ID +NewString ( + IN CHAR16 *String, + IN EFI_HII_HANDLE HiiHandle + ); + +/** + Perform nosubmitif check for a Form. + + @param FormSet FormSet data structure. + @param Form Form data structure. + @param Question The Question to be validated. + + @retval EFI_SUCCESS Form validation pass. + @retval other Form validation failed. + +**/ +EFI_STATUS +ValidateNoSubmit ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN HII_STATEMENT *Question + ); + +/** + Perform NoSubmit check for each Form in FormSet. + + @param FormSet FormSet data structure. + @param CurrentForm Current input form data structure. + @param Statement The statement for this check. + + @retval EFI_SUCCESS Form validation pass. + @retval other Form validation failed. + +**/ +EFI_STATUS +NoSubmitCheck ( + IN HII_FORMSET *FormSet, + IN OUT HII_FORM **CurrentForm, + OUT HII_STATEMENT **Statement + ); + + +/** + Convert setting of Buffer Storage or NameValue Storage to . + + @param Storage The Storage to be conveted. + @param ConfigResp The returned . + @param ConfigRequest The ConfigRequest string. + + @retval EFI_SUCCESS Convert success. + @retval EFI_INVALID_PARAMETER Incorrect storage type. + +**/ +EFI_STATUS +StorageToConfigResp ( + IN HII_FORMSET_STORAGE *Storage, + IN CHAR16 **ConfigResp, + IN CHAR16 *ConfigRequest + ); + + +/** + Convert to settings in Buffer Storage or NameValue Storage. + + @param Storage The Storage to receive the settings. + @param ConfigResp The to be converted. + + @retval EFI_SUCCESS Convert success. + @retval EFI_INVALID_PARAMETER Incorrect storage type. + +**/ +EFI_STATUS +ConfigRespToStorage ( + IN HII_FORMSET_STORAGE *Storage, + IN CHAR16 *ConfigResp + ); + +/** + Fetch the Ifr binary data of a FormSet. + + @param Handle PackageList Handle + @param FormSetGuid On input, GUID or class GUID of a formset= . If not + specified (NULL or zero GUID), take the f= irst + FormSet with class GUID EFI_HII_PLATFORM_= SETUP_FORMSET_GUID + found in package list. + On output, GUID of the formset found(if n= ot NULL). + @param BinaryLength The length of the FormSet IFR binary. + @param BinaryData The buffer designed to receive the FormSe= t. + + @retval EFI_SUCCESS Buffer filled with the requested FormSet. + BufferLength was updated. + @retval EFI_INVALID_PARAMETER The handle is unknown. + @retval EFI_NOT_FOUND A form or FormSet on the requested handle= cannot + be found with the requested FormId. + +**/ +EFI_STATUS +GetIfrBinaryData ( + IN EFI_HII_HANDLE Handle, + IN OUT EFI_GUID *FormSetGuid, + OUT UINTN *BinaryLength, + OUT UINT8 **BinaryData + ); + +/** + Fill storage with settings requested from Configuration Driver. + + @param FormSet FormSet data structure. + @param Storage Buffer Storage. + +**/ +VOID +LoadStorage ( + IN HII_FORMSET *FormSet, + IN HII_FORMSET_STORAGE *Storage + ); + +/** + Free resources of a Form. + + @param FormSet Pointer of the FormSet + @param Form Pointer of the Form. + +**/ +VOID +DestroyForm ( + IN HII_FORMSET *FormSet, + IN OUT HII_FORM *Form + ); + +/** + Get formset storage based on the input varstoreid info. + + @param FormSet Pointer of the current FormSet. + @param VarStoreId Varstore ID info. + + @return Pointer to a HII_FORMSET_STORAGE data structure. + +**/ +HII_FORMSET_STORAGE * +GetFstStgFromVarId ( + IN HII_FORMSET *FormSet, + IN EFI_VARSTORE_ID VarStoreId + ); + +/** + Zero extend integer/boolean/date/time to UINT64 for comparing. + + @param Value HII Value to be converted. + +**/ +VOID +ExtendValueToU64 ( + IN HII_STATEMENT_VALUE *Value + ); + +/** + Parse opcodes in the formset IFR binary. + + @param FormSet Pointer of the FormSet data structure. + + @retval EFI_SUCCESS Opcode parse success. + @retval Other Opcode parse fail. + +**/ +EFI_STATUS +ParseOpCodes ( + IN HII_FORMSET *FormSet + ); + +#endif // _HII_INTERNAL_H_ diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c b/RedfishPkg/= Library/HiiUtilityLib/HiiExpression.c new file mode 100644 index 00000000000..7111b40acf0 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c @@ -0,0 +1,1367 @@ +/** @file + Definitinos of RedfishPlatformConfigLib + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "HiiInternal.h" + +// +// Global stack used to evaluate boolean expresions +// +EFI_HII_VALUE *mOpCodeScopeStack =3D NULL; +EFI_HII_VALUE *mOpCodeScopeStackEnd =3D NULL; +EFI_HII_VALUE *mOpCodeScopeStackPointer =3D NULL; + +// +// Stack used for Suppressif/grayoutif/dusableif expression list. +// +HII_EXPRESSION **mFormExpressionStack =3D NULL; +HII_EXPRESSION **mFormExpressionEnd =3D NULL; +HII_EXPRESSION **mFormExpressionPointer =3D NULL; + +HII_EXPRESSION **mStatementExpressionStack =3D NULL; +HII_EXPRESSION **mStatementExpressionEnd =3D NULL; +HII_EXPRESSION **mStatementExpressionPointer =3D NULL; + +HII_EXPRESSION **mOptionExpressionStack =3D NULL; +HII_EXPRESSION **mOptionExpressionEnd =3D NULL; +HII_EXPRESSION **mOptionExpressionPointer =3D NULL; + +// +// Stack used for the sub expresion in map expression. +// +EFI_HII_VALUE *mCurrentExpressionStack =3D NULL; +EFI_HII_VALUE *mCurrentExpressionEnd =3D NULL; +EFI_HII_VALUE *mCurrentExpressionPointer =3D NULL; + +// +// Stack used for the map expression list. +// +EFI_HII_VALUE *mMapExpressionListStack =3D NULL; +EFI_HII_VALUE *mMapExpressionListEnd =3D NULL; +EFI_HII_VALUE *mMapExpressionListPointer =3D NULL; + +// +// Stack used for dependency expression. +// +HII_DEPENDENCY_EXPRESSION **mExpressionDependencyStack =3D NULL; +HII_DEPENDENCY_EXPRESSION **mExpressionDependencyEnd =3D NULL; +HII_DEPENDENCY_EXPRESSION **mExpressionDependencyPointer =3D NULL; + +#define EXPRESSION_STACK_SIZE_INCREMENT 0x100 + +/** + Grow size of the stack. + + This is an internal function. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + + @retval EFI_SUCCESS Grow stack success. + @retval EFI_OUT_OF_RESOURCES No enough memory for stack space. + +**/ +EFI_STATUS +GrowStack ( + IN OUT EFI_HII_VALUE **Stack, + IN OUT EFI_HII_VALUE **StackPtr, + IN OUT EFI_HII_VALUE **StackEnd + ) +{ + UINTN Size; + EFI_HII_VALUE *NewStack; + + Size =3D EXPRESSION_STACK_SIZE_INCREMENT; + if (*StackPtr !=3D NULL) { + Size =3D Size + (*StackEnd - *Stack); + } + + NewStack =3D AllocatePool (Size * sizeof (EFI_HII_VALUE)); + if (NewStack =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (*StackPtr !=3D NULL) { + // + // Copy from Old Stack to the New Stack + // + CopyMem ( + NewStack, + *Stack, + (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE) + ); + + // + // Free The Old Stack + // + FreePool (*Stack); + } + + // + // Make the Stack pointer point to the old data in the new stack + // + *StackPtr =3D NewStack + (*StackPtr - *Stack); + *Stack =3D NewStack; + *StackEnd =3D NewStack + Size; + + return EFI_SUCCESS; +} + + +/** + Push an element onto the Boolean Stack. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + @param Data Data to push. + + @retval EFI_SUCCESS Push stack success. + +**/ +EFI_STATUS +PushStack ( + IN OUT EFI_HII_VALUE **Stack, + IN OUT EFI_HII_VALUE **StackPtr, + IN OUT EFI_HII_VALUE **StackEnd, + IN EFI_HII_VALUE *Data + ) +{ + EFI_STATUS Status; + + // + // Check for a stack overflow condition + // + if (*StackPtr >=3D *StackEnd) { + // + // Grow the stack + // + Status =3D GrowStack (Stack, StackPtr, StackEnd); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Push the item onto the stack + // + CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE)); + if (Data->Type =3D=3D EFI_IFR_TYPE_BUFFER) { + (*StackPtr)->Buffer =3D AllocateCopyPool(Data->BufferLen, Data->Buffer= ); + if ((*StackPtr)->Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + *StackPtr =3D *StackPtr + 1; + + return EFI_SUCCESS; +} + + +/** + Pop an element from the stack. + + @param Stack On input: old stack + @param StackPtr On input: old stack pointer; On output: n= ew stack pointer + @param Data Data to pop. + + @retval EFI_SUCCESS The value was popped onto the stack. + @retval EFI_ACCESS_DENIED The pop operation underflowed the stack + +**/ +EFI_STATUS +PopStack ( + IN EFI_HII_VALUE *Stack, + IN OUT EFI_HII_VALUE **StackPtr, + OUT EFI_HII_VALUE *Data + ) +{ + // + // Check for a stack underflow condition + // + if (*StackPtr =3D=3D Stack) { + return EFI_ACCESS_DENIED; + } + + // + // Pop the item off the stack + // + *StackPtr =3D *StackPtr - 1; + CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE)); + return EFI_SUCCESS; +} + + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetCurrentExpressionStack ( + VOID + ) +{ + mCurrentExpressionPointer =3D mCurrentExpressionStack; + mFormExpressionPointer =3D mFormExpressionStack; + mStatementExpressionPointer =3D mStatementExpressionStack; + mOptionExpressionPointer =3D mOptionExpressionStack; +} + +/** + Push current expression onto the Stack + + @param Pointer Pointer to current expression. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushCurrentExpression ( + IN VOID *Pointer + ) +{ + EFI_HII_VALUE Data; + + Data.Type =3D EFI_IFR_TYPE_NUM_SIZE_64; + Data.Value.u64 =3D (UINT64) (UINTN) Pointer; + + return PushStack ( + &mCurrentExpressionStack, + &mCurrentExpressionPointer, + &mCurrentExpressionEnd, + &Data + ); +} + +/** + Pop current expression from the Stack + + @param Pointer Pointer to current expression to be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopCurrentExpression ( + OUT VOID **Pointer + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Data; + + Status =3D PopStack ( + mCurrentExpressionStack, + &mCurrentExpressionPointer, + &Data + ); + + *Pointer =3D (VOID *) (UINTN) Data.Value.u64; + + return Status; +} + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetMapExpressionListStack ( + VOID + ) +{ + mMapExpressionListPointer =3D mMapExpressionListStack; +} + +/** + Grow size of the stack. + + This is an internal function. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + @param MemberSize The stack member size. + + @retval EFI_SUCCESS Grow stack success. + @retval EFI_OUT_OF_RESOURCES No enough memory for stack space. + +**/ +EFI_STATUS +GrowConditionalStack ( + IN OUT HII_EXPRESSION ***Stack, + IN OUT HII_EXPRESSION ***StackPtr, + IN OUT HII_EXPRESSION ***StackEnd, + IN UINTN MemberSize + ) +{ + UINTN Size; + HII_EXPRESSION **NewStack; + + Size =3D EXPRESSION_STACK_SIZE_INCREMENT; + if (*StackPtr !=3D NULL) { + Size =3D Size + (*StackEnd - *Stack); + } + + NewStack =3D AllocatePool (Size * MemberSize); + if (NewStack =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (*StackPtr !=3D NULL) { + // + // Copy from Old Stack to the New Stack + // + CopyMem ( + NewStack, + *Stack, + (*StackEnd - *Stack) * MemberSize + ); + + // + // Free The Old Stack + // + FreePool (*Stack); + } + + // + // Make the Stack pointer point to the old data in the new stack + // + *StackPtr =3D NewStack + (*StackPtr - *Stack); + *Stack =3D NewStack; + *StackEnd =3D NewStack + Size; + + return EFI_SUCCESS; +} + +/** + Push an element onto the Stack. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + @param Data Data to push. + + @retval EFI_SUCCESS Push stack success. + +**/ +EFI_STATUS +PushConditionalStack ( + IN OUT HII_EXPRESSION ***Stack, + IN OUT HII_EXPRESSION ***StackPtr, + IN OUT HII_EXPRESSION ***StackEnd, + IN HII_EXPRESSION **Data + ) +{ + EFI_STATUS Status; + + // + // Check for a stack overflow condition + // + if (*StackPtr >=3D *StackEnd) { + // + // Grow the stack + // + Status =3D GrowConditionalStack (Stack, StackPtr, StackEnd, sizeof (HI= I_EXPRESSION *)); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Push the item onto the stack + // + CopyMem (*StackPtr, Data, sizeof (HII_EXPRESSION *)); + *StackPtr =3D *StackPtr + 1; + + return EFI_SUCCESS; + +} + +/** + Pop an element from the stack. + + @param Stack On input: old stack + @param StackPtr On input: old stack pointer; On output: n= ew stack pointer + @param Data Data to pop. + + @retval EFI_SUCCESS The value was popped onto the stack. + @retval EFI_ACCESS_DENIED The pop operation underflowed the stack + +**/ +EFI_STATUS +PopConditionalStack ( + IN HII_EXPRESSION **Stack, + IN OUT HII_EXPRESSION ***StackPtr, + OUT HII_EXPRESSION **Data + ) +{ + // + // Check for a stack underflow condition + // + if (*StackPtr =3D=3D Stack) { + return EFI_ACCESS_DENIED; + } + + // + // Pop the item off the stack + // + *StackPtr =3D *StackPtr - 1; + CopyMem (Data, *StackPtr, sizeof (HII_EXPRESSION *)); + return EFI_SUCCESS; + +} + +/** + Get the expression list count. + + @param Level Which type this expression belong to. For= m, + statement or option? + + @retval >=3D0 The expression count + @retval -1 Input parameter error. + +**/ +INTN +GetConditionalExpressionCount ( + IN EXPRESS_LEVEL Level + ) +{ + switch (Level) { + case ExpressForm: + return mFormExpressionPointer - mFormExpressionStack; + case ExpressStatement: + return mStatementExpressionPointer - mStatementExpressionStack; + case ExpressOption: + return mOptionExpressionPointer - mOptionExpressionStack; + default: + ASSERT (FALSE); + return -1; + } +} + +/** + Get the expression Buffer pointer. + + @param Level Which type this expression belong to. For= m, + statement or option? + + @retval The start pointer of the expression buffer or NULL. + +**/ +HII_EXPRESSION ** +GetConditionalExpressionList ( + IN EXPRESS_LEVEL Level + ) +{ + switch (Level) { + case ExpressForm: + return mFormExpressionStack; + case ExpressStatement: + return mStatementExpressionStack; + case ExpressOption: + return mOptionExpressionStack; + default: + ASSERT (FALSE); + return NULL; + } +} + + +/** + Push the expression options onto the Stack. + + @param Pointer Pointer to the current expression. + @param Level Which type this expression belong to. For= m, + statement or option? + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushConditionalExpression ( + IN HII_EXPRESSION *Pointer, + IN EXPRESS_LEVEL Level + ) +{ + switch (Level) { + case ExpressForm: + return PushConditionalStack ( + &mFormExpressionStack, + &mFormExpressionPointer, + &mFormExpressionEnd, + &Pointer + ); + case ExpressStatement: + return PushConditionalStack ( + &mStatementExpressionStack, + &mStatementExpressionPointer, + &mStatementExpressionEnd, + &Pointer + ); + case ExpressOption: + return PushConditionalStack ( + &mOptionExpressionStack, + &mOptionExpressionPointer, + &mOptionExpressionEnd, + &Pointer + ); + default: + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } +} + +/** + Pop the expression options from the Stack + + @param Level Which type this expression belong to. For= m, + statement or option? + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopConditionalExpression ( + IN EXPRESS_LEVEL Level + ) +{ + HII_EXPRESSION *Pointer; + + switch (Level) { + case ExpressForm: + return PopConditionalStack ( + mFormExpressionStack, + &mFormExpressionPointer, + &Pointer + ); + + case ExpressStatement: + return PopConditionalStack ( + mStatementExpressionStack, + &mStatementExpressionPointer, + &Pointer + ); + + case ExpressOption: + return PopConditionalStack ( + mOptionExpressionStack, + &mOptionExpressionPointer, + &Pointer + ); + + default: + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } +} + + +/** + Push the list of map expression onto the Stack + + @param Pointer Pointer to the list of map expression to = be pushed. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushMapExpressionList ( + IN VOID *Pointer + ) +{ + EFI_HII_VALUE Data; + + Data.Type =3D EFI_IFR_TYPE_NUM_SIZE_64; + Data.Value.u64 =3D (UINT64) (UINTN) Pointer; + + return PushStack ( + &mMapExpressionListStack, + &mMapExpressionListPointer, + &mMapExpressionListEnd, + &Data + ); +} + + +/** + Pop the list of map expression from the Stack + + @param Pointer Pointer to the list of map expression to = be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopMapExpressionList ( + OUT VOID **Pointer + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Data; + + Status =3D PopStack ( + mMapExpressionListStack, + &mMapExpressionListPointer, + &Data + ); + + *Pointer =3D (VOID *) (UINTN) Data.Value.u64; + + return Status; +} + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetScopeStack ( + VOID + ) +{ + mOpCodeScopeStackPointer =3D mOpCodeScopeStack; +} + + +/** + Push an Operand onto the Stack + + @param Operand Operand to push. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + +**/ +EFI_STATUS +PushScope ( + IN UINT8 Operand + ) +{ + EFI_HII_VALUE Data; + + Data.Type =3D EFI_IFR_TYPE_NUM_SIZE_8; + Data.Value.u8 =3D Operand; + + return PushStack ( + &mOpCodeScopeStack, + &mOpCodeScopeStackPointer, + &mOpCodeScopeStackEnd, + &Data + ); +} + + +/** + Pop an Operand from the Stack + + @param Operand Operand to pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + +**/ +EFI_STATUS +PopScope ( + OUT UINT8 *Operand + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Data; + + Status =3D PopStack ( + mOpCodeScopeStack, + &mOpCodeScopeStackPointer, + &Data + ); + + *Operand =3D Data.Value.u8; + + return Status; +} + +/** + Grow size of the stack for Expression Dependencies. + + This is an internal function. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + + @retval EFI_SUCCESS Grow Dependency stack success. + @retval EFI_OUT_OF_RESOURCES No enough memory for stack space. + +**/ +EFI_STATUS +GrowDependencyStack ( + IN OUT HII_DEPENDENCY_EXPRESSION ***Stack, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackEnd + ) +{ + UINTN Size; + HII_DEPENDENCY_EXPRESSION **NewStack; + + Size =3D EXPRESSION_STACK_SIZE_INCREMENT; + if (*StackPtr !=3D NULL) { + Size =3D Size + (*StackEnd - *Stack); + } + + NewStack =3D AllocatePool (Size * sizeof (HII_DEPENDENCY_EXPRESSION *)); + if (NewStack =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (*StackPtr !=3D NULL) { + // + // Copy from Old Stack to the New Stack + // + CopyMem ( + NewStack, + *Stack, + (*StackEnd - *Stack) * sizeof (HII_DEPENDENCY_EXPRESSION *) + ); + + // + // Free The Old Stack + // + FreePool (*Stack); + } + + // + // Make the Stack pointer point to the old data in the new stack + // + *StackPtr =3D NewStack + (*StackPtr - *Stack); + *Stack =3D NewStack; + *StackEnd =3D NewStack + Size; + + return EFI_SUCCESS; +} + +/** + Push an element onto the Stack for Expression Dependencies. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + @param Data Data to push. + + @retval EFI_SUCCESS Push stack success. + +**/ +EFI_STATUS +PushDependencyStack ( + IN OUT HII_DEPENDENCY_EXPRESSION ***Stack, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackEnd, + IN HII_DEPENDENCY_EXPRESSION **Data + ) +{ + EFI_STATUS Status; + + // + // Check for a stack overflow condition + // + if (*StackPtr >=3D *StackEnd) { + // + // Grow the stack + // + Status =3D GrowDependencyStack (Stack, StackPtr, StackEnd); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Push the item onto the stack + // + CopyMem (*StackPtr, Data, sizeof (HII_DEPENDENCY_EXPRESSION *)); + *StackPtr =3D *StackPtr + 1; + + return EFI_SUCCESS; + +} + +/** + Pop the Expression Dependency options from the Stack + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param Data Data to push. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopDependencyStack ( + IN HII_DEPENDENCY_EXPRESSION **Stack, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr, + OUT HII_DEPENDENCY_EXPRESSION **Data + ) +{ + // + // Check for a stack underflow condition + // + if (*StackPtr =3D=3D Stack) { + return EFI_ACCESS_DENIED; + } + + // + // Pop the item off the stack + // + *StackPtr =3D *StackPtr - 1; + CopyMem (Data, *StackPtr, sizeof (HII_DEPENDENCY_EXPRESSION *)); + return EFI_SUCCESS; + +} + +/** + Push the list of Expression Dependencies onto the Stack + + @param Pointer Pointer to the list of map expression to = be pushed. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushDependencyExpDes ( + IN HII_DEPENDENCY_EXPRESSION **Pointer + ) +{ + return PushDependencyStack ( + &mExpressionDependencyStack, + &mExpressionDependencyPointer, + &mExpressionDependencyEnd, + Pointer + ); +} + +/** + Pop the list of Expression Dependencies from the Stack + + @param Pointer Pointer to the list of map expression to = be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopDependencyExpDes ( + OUT HII_DEPENDENCY_EXPRESSION **Pointer + ) +{ + return PopDependencyStack ( + mExpressionDependencyStack, + &mExpressionDependencyPointer, + Pointer + ); +} + +/** + Retrieve dependencies within an expression. These dependencies can expre= ss how + this expression will be evaluated. + + @param Expression Expression to retrieve dependencies. + + @retval EFI_SUCCESS The dependencies were successfully retrie= ved. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory. + +**/ +EFI_STATUS +GetHiiExpressionDependency ( + IN OUT HII_EXPRESSION *Expression + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Link; + HII_EXPRESSION_OPCODE *ExpressionOpCode; + HII_DEPENDENCY_EXPRESSION *DepExpressionOpCode; + LIST_ENTRY *SubExpressionLink; + HII_EXPRESSION *SubExpression; + UINT8 MapPairpCount; + + Link =3D GetFirstNode (&Expression->OpCodeListHead); + while (!IsNull (&Expression->OpCodeListHead, Link)) { + + ExpressionOpCode =3D HII_EXPRESSION_OPCODE_FROM_LINK (Link); + Link =3D GetNextNode (&Expression->OpCodeListHead, Link); + Status =3D EFI_SUCCESS; + + DepExpressionOpCode =3D (HII_DEPENDENCY_EXPRESSION *) AllocateZeroPool= (sizeof (HII_DEPENDENCY_EXPRESSION)); + if (DepExpressionOpCode =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + switch (ExpressionOpCode->Operand) { + // + // Constant + // + case EFI_IFR_FALSE_OP: + case EFI_IFR_ONE_OP: + case EFI_IFR_ONES_OP: + case EFI_IFR_TRUE_OP: + case EFI_IFR_UINT8_OP: + case EFI_IFR_UINT16_OP: + case EFI_IFR_UINT32_OP: + case EFI_IFR_UINT64_OP: + case EFI_IFR_UNDEFINED_OP: + case EFI_IFR_VERSION_OP: + case EFI_IFR_ZERO_OP: + DepExpressionOpCode->ContantExp.Operand =3D ExpressionOpCode->Operan= d; + CopyMem (&DepExpressionOpCode->ContantExp.Value, &ExpressionOpCode->= ExtraData.Value, sizeof (EFI_HII_VALUE)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // Built-in functions + // + case EFI_IFR_DUP_OP: + DepExpressionOpCode->DupExp.Operand =3D ExpressionOpCode->Operand; + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_EQ_ID_VAL_OP: + DepExpressionOpCode->EqIdValExp.Operand =3D ExpressionOpCode->O= perand; + CopyMem (&DepExpressionOpCode->EqIdValExp.QuestionId, &ExpressionO= pCode->ExtraData.EqIdValData.QuestionId, sizeof (EFI_QUESTION_ID)); + CopyMem (&DepExpressionOpCode->EqIdValExp.Value, &ExpressionOpCode= ->ExtraData.EqIdValData.Value, sizeof (EFI_HII_VALUE)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_EQ_ID_ID_OP: + DepExpressionOpCode->EqIdIdExp.Operand =3D ExpressionOpCode->O= perand; + CopyMem (&DepExpressionOpCode->EqIdIdExp.QuestionId1, &ExpressionO= pCode->ExtraData.EqIdIdData.QuestionId1, sizeof (EFI_QUESTION_ID)); + CopyMem (&DepExpressionOpCode->EqIdIdExp.QuestionId2, &ExpressionO= pCode->ExtraData.EqIdIdData.QuestionId2, sizeof (EFI_QUESTION_ID)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_EQ_ID_VAL_LIST_OP: + DepExpressionOpCode->EqIdListExp.Operand =3D ExpressionOpCode->= Operand; + DepExpressionOpCode->EqIdListExp.ListLength =3D ExpressionOpCode->= ExtraData.EqIdListData.ListLength; + CopyMem (&DepExpressionOpCode->EqIdListExp.QuestionId, &Expression= OpCode->ExtraData.EqIdListData.QuestionId, sizeof (EFI_QUESTION_ID)); + PushDependencyExpDes (&DepExpressionOpCode); + DepExpressionOpCode->EqIdListExp.ValueList =3D AllocateCopyPool ( + DepExpressionOpCode->EqIdListExp.ListLength * sizeof (UINT16), E= xpressionOpCode->ExtraData.EqIdListData.ValueList); + if (DepExpressionOpCode->EqIdListExp.ValueList =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_GET_OP: + DepExpressionOpCode->GetExp.Operand =3D ExpressionOpCode->Operand; + DepExpressionOpCode->GetExp.VarStorage =3D ExpressionOpCode->Extra= Data.GetSetData.VarStorage; + CopyMem (&DepExpressionOpCode->GetExp.VarStoreInfo.VarName, &Expre= ssionOpCode->ExtraData.GetSetData.VarStoreInfo.VarName, sizeof (EFI_STRING_= ID)); + CopyMem (&DepExpressionOpCode->GetExp.VarStoreInfo.VarOffset, &Exp= ressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, sizeof (UINT16)= ); + DepExpressionOpCode->GetExp.VarStoreInfo =3D ExpressionOpCode->Ext= raData.GetSetData.VarStoreInfo; + if (ExpressionOpCode->ExtraData.GetSetData.ValueName !=3D NULL) { + DepExpressionOpCode->GetExp.ValueName =3D (CHAR16*)AllocateCop= yPool (sizeof (ExpressionOpCode->ExtraData.GetSetData.ValueName), Expressio= nOpCode->ExtraData.GetSetData.ValueName); + if (DepExpressionOpCode->GetExp.ValueName =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + DepExpressionOpCode->GetExp.ValueType =3D ExpressionOpCode->ExtraD= ata.GetSetData.ValueType; + DepExpressionOpCode->GetExp.ValueWidth =3D ExpressionOpCode->Extra= Data.GetSetData.ValueWidth; + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_QUESTION_REF1_OP: + DepExpressionOpCode->QuestionRef1Exp.Operand =3D ExpressionOpCo= de->Operand; + CopyMem (&DepExpressionOpCode->QuestionRef1Exp.QuestionId, &Expres= sionOpCode->ExtraData.QuestionRef1Data.QuestionId, sizeof (EFI_QUESTION_ID)= ); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_RULE_REF_OP: + DepExpressionOpCode->RuleRefExp.Operand =3D ExpressionOpCode->Op= erand; + DepExpressionOpCode->RuleRefExp.RuleId =3D ExpressionOpCode->Extra= Data.RuleId; + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_STRING_REF1_OP: + DepExpressionOpCode->StringRef1Exp.Operand =3D ExpressionOpCode->O= perand; + CopyMem (&DepExpressionOpCode->StringRef1Exp.Value.Value.string, &= ExpressionOpCode->ExtraData.Value.Value.string, sizeof (EFI_STRING_ID)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_THIS_OP: + DepExpressionOpCode->ThisExp.Operand =3D ExpressionOpCode->Operand; + CopyMem (&DepExpressionOpCode->ThisExp.QuestionId, &ExpressionOpCo= de->ExtraData.QuestionRef1Data.QuestionId, sizeof (EFI_QUESTION_ID)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SECURITY_OP: + DepExpressionOpCode->SecurityExp.Operand =3D ExpressionOpCode->Ope= rand; + CopyMem (&DepExpressionOpCode->SecurityExp.Permissions, &Expressio= nOpCode->ExtraData.Guid, sizeof (EFI_GUID)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // unary-op + // + case EFI_IFR_LENGTH_OP: + DepExpressionOpCode->LengthExp.Operand =3D ExpressionOpCode->Opera= nd; + PopDependencyExpDes (&DepExpressionOpCode->LengthExp.SubExpression= ); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_NOT_OP: + DepExpressionOpCode->NotExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->NotExp.SubExpression); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_BITWISE_NOT_OP: + DepExpressionOpCode->BitWiseNotExp.Operand =3D ExpressionOpCode->O= perand; + PopDependencyExpDes (&DepExpressionOpCode->BitWiseNotExp.SubExpres= sion); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_QUESTION_REF2_OP: + DepExpressionOpCode->QuestionRef2Exp.Operand =3D ExpressionOpCode-= >Operand; + PopDependencyExpDes (&DepExpressionOpCode->QuestionRef2Exp.SubExpr= ession); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_QUESTION_REF3_OP: + DepExpressionOpCode->QuestionRef3Exp.Operand =3D ExpressionOpCode-= >Operand; + CopyMem (&DepExpressionOpCode->QuestionRef3Exp.DevicePath, &Expres= sionOpCode->ExtraData.QuestionRef3Data.DevicePath, sizeof (EFI_DEVICE_PATH)= ); + CopyMem (&DepExpressionOpCode->QuestionRef3Exp.Guid, &ExpressionOp= Code->ExtraData.QuestionRef3Data.Guid, sizeof (EFI_GUID)); + PopDependencyExpDes (&DepExpressionOpCode->QuestionRef3Exp.SubExpr= ession); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SET_OP: + DepExpressionOpCode->SetExp.Operand =3D ExpressionOpCode->Operand; + DepExpressionOpCode->SetExp.VarStorage =3D ExpressionOpCode->Extra= Data.GetSetData.VarStorage; + CopyMem (&DepExpressionOpCode->SetExp.VarStoreInfo.VarName, &Expre= ssionOpCode->ExtraData.GetSetData.VarStoreInfo.VarName, sizeof (EFI_STRING_= ID)); + CopyMem (&DepExpressionOpCode->SetExp.VarStoreInfo.VarOffset, &Exp= ressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, sizeof (UINT16)= ); + DepExpressionOpCode->SetExp.VarStoreInfo =3D ExpressionOpCode->Ext= raData.GetSetData.VarStoreInfo; + if (ExpressionOpCode->ExtraData.GetSetData.ValueName !=3D NULL) { + DepExpressionOpCode->SetExp.ValueName =3D (CHAR16*)AllocateCop= yPool (sizeof (ExpressionOpCode->ExtraData.GetSetData.ValueName), Expressio= nOpCode->ExtraData.GetSetData.ValueName); + if (DepExpressionOpCode->SetExp.ValueName =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + DepExpressionOpCode->SetExp.ValueType =3D ExpressionOpCode->ExtraD= ata.GetSetData.ValueType; + DepExpressionOpCode->SetExp.ValueWidth =3D ExpressionOpCode->Extra= Data.GetSetData.ValueWidth; + PopDependencyExpDes (&DepExpressionOpCode->SetExp.SubExpression); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_STRING_REF2_OP: + DepExpressionOpCode->StringRef2Exp.Operand =3D ExpressionOpCode->O= perand; + PopDependencyExpDes (&DepExpressionOpCode->StringRef2Exp.SubExpres= sion); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_BOOLEAN_OP: + DepExpressionOpCode->ToBooleanExp.Operand =3D ExpressionOpCode->Op= erand; + PopDependencyExpDes (&DepExpressionOpCode->ToBooleanExp.SubExpress= ion); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_STRING_OP: + DepExpressionOpCode->ToStringExp.Operand =3D ExpressionOpCode->Ope= rand; + DepExpressionOpCode->ToStringExp.Format =3D ExpressionOpCode->Ext= raData.Format; + PopDependencyExpDes (&DepExpressionOpCode->ToStringExp.SubExpressi= on); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_UINT_OP: + DepExpressionOpCode->ToUintExp.Operand =3D ExpressionOpCode->Opera= nd; + PopDependencyExpDes (&DepExpressionOpCode->ToUintExp.SubExpression= ); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_LOWER_OP: + DepExpressionOpCode->ToLowerExp.Operand =3D ExpressionOpCode->Oper= and; + PopDependencyExpDes (&DepExpressionOpCode->ToLowerExp.SubExpressio= n); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_UPPER_OP: + DepExpressionOpCode->ToUpperExp.Operand =3D ExpressionOpCode->Oper= and; + PopDependencyExpDes (&DepExpressionOpCode->ToUpperExp.SubExpressio= n); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // binary-op + // + case EFI_IFR_ADD_OP: + DepExpressionOpCode->AddExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->AddExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->AddExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_AND_OP: + DepExpressionOpCode->AndExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->AndExp.SubExpression1); + PopDependencyExpDes (&DepExpressionOpCode->AndExp.SubExpression2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_BITWISE_AND_OP: + DepExpressionOpCode->BitwiseAndExp.Operand =3D ExpressionOpCode->Ope= rand; + PopDependencyExpDes (&DepExpressionOpCode->BitwiseAndExp.SubExpressi= on1); + PopDependencyExpDes (&DepExpressionOpCode->BitwiseAndExp.SubExpressi= on2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_BITWISE_OR_OP: + DepExpressionOpCode->BitwiseOrExp.Operand =3D ExpressionOpCode->Oper= and; + PopDependencyExpDes (&DepExpressionOpCode->BitwiseOrExp.SubExpressio= n1); + PopDependencyExpDes (&DepExpressionOpCode->BitwiseOrExp.SubExpressio= n2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_CATENATE_OP: + DepExpressionOpCode->CatenateExp.Operand =3D ExpressionOpCode->Opera= nd; + PopDependencyExpDes (&DepExpressionOpCode->CatenateExp.LeftStringExp= ); + PopDependencyExpDes (&DepExpressionOpCode->CatenateExp.RightStringEx= p); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_DIVIDE_OP: + DepExpressionOpCode->DivExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->DivExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->DivExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_EQUAL_OP: + DepExpressionOpCode->EqualExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->EqualExp.SubExpression1); + PopDependencyExpDes (&DepExpressionOpCode->EqualExp.SubExpression2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_GREATER_EQUAL_OP: + DepExpressionOpCode->GreaterEqualExp.Operand =3D ExpressionOpCode->O= perand; + PopDependencyExpDes (&DepExpressionOpCode->GreaterEqualExp.LeftHandE= xp); + PopDependencyExpDes (&DepExpressionOpCode->GreaterEqualExp.RightHand= Exp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_GREATER_THAN_OP: + DepExpressionOpCode->GreaterThanExp.Operand =3D ExpressionOpCode->Op= erand; + PopDependencyExpDes (&DepExpressionOpCode->GreaterThanExp.LeftHandEx= p); + PopDependencyExpDes (&DepExpressionOpCode->GreaterThanExp.RightHandE= xp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_LESS_EQUAL_OP: + DepExpressionOpCode->LessEqualExp.Operand =3D ExpressionOpCode->Oper= and; + PopDependencyExpDes (&DepExpressionOpCode->LessEqualExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->LessEqualExp.RightHandExp= ); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_LESS_THAN_OP: + DepExpressionOpCode->LessThanExp.Operand =3D ExpressionOpCode->Opera= nd; + PopDependencyExpDes (&DepExpressionOpCode->LessThanExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->LessThanExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MATCH_OP: + DepExpressionOpCode->MatchExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->MatchExp.PatternExp); + PopDependencyExpDes (&DepExpressionOpCode->MatchExp.StringExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MATCH2_OP: + DepExpressionOpCode->Match2Exp.Operand =3D ExpressionOpCode->Operand; + CopyMem (&DepExpressionOpCode->Match2Exp.SyntaxType, &ExpressionOpCo= de->ExtraData.Guid, sizeof (EFI_GUID)); + PopDependencyExpDes (&DepExpressionOpCode->Match2Exp.PatternExp); + PopDependencyExpDes (&DepExpressionOpCode->Match2Exp.StringExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MODULO_OP: + DepExpressionOpCode->ModExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->ModExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->ModExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MULTIPLY_OP: + DepExpressionOpCode->MultExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->MultExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->MultExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_NOT_EQUAL_OP: + DepExpressionOpCode->NotEqualExp.Operand =3D ExpressionOpCode->Opera= nd; + PopDependencyExpDes (&DepExpressionOpCode->NotEqualExp.SubExpression= 1); + PopDependencyExpDes (&DepExpressionOpCode->NotEqualExp.SubExpression= 2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_OR_OP: + DepExpressionOpCode->OrExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->OrExp.SubExpression1); + PopDependencyExpDes (&DepExpressionOpCode->OrExp.SubExpression2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SHIFT_LEFT_OP: + DepExpressionOpCode->ShiftLeftExp.Operand =3D ExpressionOpCode->Oper= and; + PopDependencyExpDes (&DepExpressionOpCode->ShiftLeftExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->ShiftLeftExp.RightHandExp= ); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SHIFT_RIGHT_OP: + DepExpressionOpCode->ShiftRightExp.Operand =3D ExpressionOpCode->Ope= rand; + PopDependencyExpDes (&DepExpressionOpCode->ShiftRightExp.LeftHandExp= ); + PopDependencyExpDes (&DepExpressionOpCode->ShiftRightExp.RightHandEx= p); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SUBTRACT_OP: + DepExpressionOpCode->SubtractExp.Operand =3D ExpressionOpCode->Opera= nd; + PopDependencyExpDes (&DepExpressionOpCode->SubtractExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->SubtractExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // ternary-op + // + case EFI_IFR_CONDITIONAL_OP: + DepExpressionOpCode->ConditionalExp.Operand =3D ExpressionOpCode->Op= erand; + PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.CondTrueVa= lExp); + PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.CondFalseV= alExp); + PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.ConditionE= xp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_FIND_OP: + DepExpressionOpCode->FindExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->FindExp.StringToSearchExp= ); + PopDependencyExpDes (&DepExpressionOpCode->FindExp.StringToCompWithE= xp); + PopDependencyExpDes (&DepExpressionOpCode->FindExp.IndexExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MID_OP: + DepExpressionOpCode->MidExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->MidExp.StringOrBufferExp); + PopDependencyExpDes (&DepExpressionOpCode->MidExp.IndexExp); + PopDependencyExpDes (&DepExpressionOpCode->MidExp.LengthExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TOKEN_OP: + DepExpressionOpCode->TokenExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->TokenExp.StringToSearchEx= p); + PopDependencyExpDes (&DepExpressionOpCode->TokenExp.DelimiterExp); + PopDependencyExpDes (&DepExpressionOpCode->TokenExp.IndexExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SPAN_OP: + DepExpressionOpCode->SpanExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->SpanExp.StringToSearchExp= ); + PopDependencyExpDes (&DepExpressionOpCode->SpanExp.CharsetExp); + PopDependencyExpDes (&DepExpressionOpCode->SpanExp.IndeExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // Map + // + case EFI_IFR_MAP_OP: + // + // Go through map expression list. + // + DepExpressionOpCode->MapExp.Operand =3D ExpressionOpCode->Operand; + MapPairpCount =3D 0; + SubExpressionLink =3D GetFirstNode(&ExpressionOpCode->MapExpressionL= ist); + while (!IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionL= ink)) { + MapPairpCount ++; + SubExpressionLink =3D GetNextNode (&ExpressionOpCode->MapExpressio= nList, SubExpressionLink); + if (IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionLin= k)) { + Status =3D EFI_INVALID_PARAMETER; + goto Done; + } + // + // Goto the first expression on next pair. + // + SubExpressionLink =3D GetNextNode (&ExpressionOpCode->MapExpressio= nList, SubExpressionLink); + } + DepExpressionOpCode->MapExp.ExpPair =3D (HII_DEPENDENCY_EXPRESSION_P= AIR*) AllocateZeroPool ( + MapPairpCount * sizeof (HII_= DEPENDENCY_EXPRESSION_PAIR)); + if (DepExpressionOpCode->MapExp.ExpPair =3D=3D NULL) { + + Status =3D EFI_OUT_OF_RESOURCES; + goto Done; + } + + DepExpressionOpCode->MapExp.ExpPairNo =3D MapPairpCount; + MapPairpCount =3D 0; + PopDependencyExpDes (&DepExpressionOpCode->MapExp.SubExp); + + // + // Go through map expression list. + // + SubExpressionLink =3D GetFirstNode(&ExpressionOpCode->MapExpressionL= ist); + while (!IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionL= ink)) { + SubExpression =3D HII_EXPRESSION_FROM_LINK (SubExpressionLink); + // + // Get the first expression description in this pair. + // + GetHiiExpressionDependency (SubExpression); + DepExpressionOpCode->MapExp.ExpPair[MapPairpCount].MatchExp=3D Sub= Expression->RootDepdencyExp; + + // + // Get the second expression description in this pair. + // + SubExpressionLink =3D GetNextNode (&ExpressionOpCode->MapExpressio= nList, SubExpressionLink); + SubExpression =3D HII_EXPRESSION_FROM_LINK (SubExpressionLink); + GetHiiExpressionDependency (SubExpression); + DepExpressionOpCode->MapExp.ExpPair[MapPairpCount].ReturnExp=3D Su= bExpression->RootDepdencyExp; + // + // Goto the first expression on next pair. + // + SubExpressionLink =3D GetNextNode (&ExpressionOpCode->MapExpressio= nList, SubExpressionLink); + MapPairpCount++; + } + PushDependencyExpDes (&DepExpressionOpCode); + break; + + default: + break; + } + } + + PopDependencyExpDes (&Expression->RootDepdencyExp); + +Done: + return Status; +} diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiIfrParse.c b/RedfishPkg/Li= brary/HiiUtilityLib/HiiIfrParse.c new file mode 100644 index 00000000000..3546f92c1e7 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiIfrParse.c @@ -0,0 +1,2671 @@ +/** @file + Definitinos of RedfishPlatformConfigLib + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HiiInternal.h" + +#define EFI_IFR_SPECIFICATION_VERSION (UINT16) (((EFI_SYSTEM_TABLE_REVISI= ON >> 16) << 8) | (((EFI_SYSTEM_TABLE_REVISION & 0xFFFF) / 10) << 4) | ((EF= I_SYSTEM_TABLE_REVISION & 0xFFFF) % 10)) + +/** + Initialize Statement header members. + + @param[in] OpCodeData Pointer of the raw OpCode data. + @param[in,out] FormSet Pointer of the current FormSet. + @param[in,out] Form Pointer of the current Form. + + @return The Statement. + +**/ +HII_STATEMENT * +CreateStatement ( + IN UINT8 *OpCodeData, + IN OUT HII_FORMSET *FormSet, + IN OUT HII_FORM *Form + ) +{ + HII_STATEMENT *Statement; + EFI_IFR_STATEMENT_HEADER *StatementHdr; + INTN ConditionalExprCount; + + if (Form =3D=3D NULL) { + // + // Only guid op may out side the form level. + // + if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode !=3D EFI_IFR_GUID_OP) { + return NULL; + } + } + + Statement =3D (HII_STATEMENT *) AllocateZeroPool (sizeof (HII_STATEMENT)= ); + if (Statement =3D=3D NULL) { + return NULL; + } + + InitializeListHead (&Statement->DefaultListHead); + InitializeListHead (&Statement->OptionListHead); + InitializeListHead (&Statement->InconsistentListHead); + InitializeListHead (&Statement->NoSubmitListHead); + InitializeListHead (&Statement->WarningListHead); + + Statement->Signature =3D HII_STATEMENT_SIGNATURE; + Statement->Operand =3D ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode; + Statement->OpCode =3D (EFI_IFR_OP_HEADER *) OpCodeData; + Statement->QuestionReferToBitField =3D FALSE; + + StatementHdr =3D (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_= IFR_OP_HEADER)); + CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_I= D)); + CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID)); + + ConditionalExprCount =3D GetConditionalExpressionCount(ExpressStatement); + if (ConditionalExprCount > 0) { + + // + // Form is inside of suppressif + // + Statement->ExpressionList =3D (HII_EXPRESSION_LIST *) AllocatePool( + (UINTN) (sizeof(HII_EXPRESSION_LIST) + ((Con= ditionalExprCount - 1) * sizeof (HII_EXPRESSION *)))); + if (Statement->ExpressionList =3D=3D NULL) { + return NULL; + } + + Statement->ExpressionList->Count =3D (UINTN) ConditionalExprCount; + Statement->ExpressionList->Signature =3D HII_EXPRESSION_LIST_SIGNATURE; + CopyMem (Statement->ExpressionList->Expression, + GetConditionalExpressionList(ExpressStatement), (UINTN) (sizeof (HII= _EXPRESSION *) * ConditionalExprCount)); + } + + // + // Insert this Statement into current Form + // + if (Form =3D=3D NULL) { + InsertTailList (&FormSet->StatementListOSF, &Statement->Link); + } else { + InsertTailList (&Form->StatementListHead, &Statement->Link); + } + return Statement; +} + +/** + Initialize Question's members. + + @param[in] OpCodeData Pointer of the raw OpCode data. + @param[in,out] FormSet Pointer of the current FormSet. + @param[in,out] Form Pointer of the current Form. + + @return The Question. + +**/ +HII_STATEMENT * +CreateQuestion ( + IN UINT8 *OpCodeData, + IN OUT HII_FORMSET *FormSet, + IN OUT HII_FORM *Form + ) +{ + HII_STATEMENT *Statement; + EFI_IFR_QUESTION_HEADER *QuestionHdr; + LIST_ENTRY *Link; + HII_FORMSET_STORAGE *Storage; + HII_NAME_VALUE_NODE *NameValueNode; + BOOLEAN Find; + + Statement =3D CreateStatement (OpCodeData, FormSet, Form); + if (Statement =3D=3D NULL) { + return NULL; + } + + QuestionHdr =3D (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IF= R_OP_HEADER)); + CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_Q= UESTION_ID)); + CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_V= ARSTORE_ID)); + CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.= VarOffset, sizeof (UINT16)); + + Statement->QuestionFlags =3D QuestionHdr->Flags; + + if (Statement->VarStoreId =3D=3D 0) { + // + // VarStoreId of zero indicates no variable storage + // + return Statement; + } + + // + // Find Storage for this Question + // + Link =3D GetFirstNode (&FormSet->StorageListHead); + while (!IsNull (&FormSet->StorageListHead, Link)) { + Storage =3D HII_STORAGE_FROM_LINK (Link); + + if (Statement->VarStoreId =3D=3D Storage->VarStoreId) { + + Statement->Storage =3D Storage; + break; + } + + Link =3D GetNextNode (&FormSet->StorageListHead, Link); + } + if (Statement->Storage =3D=3D NULL) { + return NULL; + } + + // + // Initialilze varname for Name/Value or EFI Variable + // + if ((Statement->Storage->Type =3D=3D EFI_HII_VARSTORE_NAME_VALUE) || + (Statement->Storage->Type =3D=3D EFI_HII_VARSTORE_EFI_VARIABLE)) { + + Statement->VariableName =3D GetToken (Statement->VarStoreInfo.VarName,= FormSet->HiiHandle); + if (Statement->VariableName =3D=3D NULL) { + return NULL; + } + + if (Statement->Storage->Type =3D=3D EFI_HII_VARSTORE_NAME_VALUE) { + + // + // Check whether old string node already exist. + // + Find =3D FALSE; + if (!IsListEmpty(&Statement->Storage->NameValueList)) { + Link =3D GetFirstNode (&Statement->Storage->NameValueList); + while (!IsNull (&Statement->Storage->NameValueList, Link)) { + NameValueNode =3D HII_NAME_VALUE_NODE_FROM_LINK (Link); + + if (StrCmp (Statement->VariableName, NameValueNode->Name) =3D=3D= 0) { + Find =3D TRUE; + break; + } + + Link =3D GetNextNode (&Statement->Storage->NameValueList, Link); + } + } + + + if (!Find) { + // + // Insert to Name/Value varstore list + // + NameValueNode =3D AllocateZeroPool (sizeof (HII_NAME_VALUE_NODE)); + if (NameValueNode =3D=3D NULL) { + return NULL; + } + + NameValueNode->Signature =3D HII_NAME_VALUE_NODE_SIGNATURE; + NameValueNode->Name =3D AllocateCopyPool (StrSize (Statement->Vari= ableName), Statement->VariableName); + if (NameValueNode->Name =3D=3D NULL) { + + FreePool (NameValueNode); + return NULL; + } + + NameValueNode->Value =3D AllocateZeroPool (0x10); + if (NameValueNode->Value =3D=3D NULL) { + + FreePool (NameValueNode->Name); + FreePool (NameValueNode); + return NULL; + } + + + InsertTailList (&Statement->Storage->NameValueList, &NameValueNode= ->Link); + } + } + } + + return Statement; +} + + +/** + Allocate a HII_EXPRESSION node. + + @param[in,out] Form The Form associated with this Exp= ression + @param[in] OpCode The binary opcode data. + + @return Pointer to a HII_EXPRESSION data structure. + +**/ +HII_EXPRESSION * +CreateExpression ( + IN OUT HII_FORM *Form, + IN UINT8 *OpCode + ) +{ + HII_EXPRESSION *Expression; + + Expression =3D AllocateZeroPool (sizeof (HII_EXPRESSION)); + if (Expression =3D=3D NULL) { + return NULL; + } + + Expression->Signature =3D HII_EXPRESSION_SIGNATURE; + InitializeListHead (&Expression->OpCodeListHead); + Expression->OpCode =3D (EFI_IFR_OP_HEADER *) OpCode; + + return Expression; +} + +/** + Create ConfigHdr string for a storage. + + @param[in] FormSet Pointer of the current FormSet + @param[in,out] Storage Pointer of the storage + + @retval EFI_SUCCESS Initialize ConfigHdr success + +**/ +EFI_STATUS +InitializeConfigHdr ( + IN HII_FORMSET *FormSet, + IN OUT HII_FORMSET_STORAGE *Storage + ) +{ + CHAR16 *Name; + + if (Storage->Type =3D=3D EFI_HII_VARSTORE_BUFFER || + Storage->Type =3D=3D EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { + + Name =3D Storage->Name; + } else { + Name =3D NULL; + } + + Storage->ConfigHdr =3D HiiConstructConfigHdr ( + &FormSet->Guid, + Name, + FormSet->DriverHandle + ); + + if (Storage->ConfigHdr =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** + Convert Ascii string to Unicode. + + This is an internal function. + + @param[in] AsciiString The Ascii string to be converted. + @param[out] UnicodeString The Unicode string retrieved. + +**/ +VOID +AsciiToUnicode ( + IN CHAR8 *AsciiString, + OUT CHAR16 *UnicodeString + ) +{ + UINT8 Index; + + Index =3D 0; + while (AsciiString[Index] !=3D 0) { + UnicodeString[Index] =3D (CHAR16)AsciiString[Index]; + Index++; + } + + UnicodeString[Index] =3D L'\0'; +} + +/** + Allocate a HII_FORMSET_STORAGE data structure and insert to FormSet Stor= age List. + + @param[in] FormSet Pointer of the current FormSet + @param[in] StorageType Storage type. + @param[in] OpCodeData Binary data for this opcode. + + @return Pointer to a HII_FORMSET_STORAGE data structure. + +**/ +HII_FORMSET_STORAGE * +CreateStorage ( + IN HII_FORMSET *FormSet, + IN UINT8 StorageType, + IN UINT8 *OpCodeData + ) +{ + HII_FORMSET_STORAGE *Storage; + CHAR8 *AsciiStorageName; + + AsciiStorageName =3D NULL; + + Storage =3D AllocateZeroPool (sizeof (HII_FORMSET_STORAGE)); + if (Storage =3D=3D NULL) { + return NULL; + } + + Storage->Signature =3D HII_STORAGE_SIGNATURE; + Storage->Type =3D StorageType; + + switch (StorageType) { + case EFI_HII_VARSTORE_BUFFER: + + CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, s= izeof (EFI_GUID)); + CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, s= izeof (UINT16)); + + Storage->Buffer =3D AllocateZeroPool (Storage->Size); + if (Storage->Buffer =3D=3D NULL) { + + FreePool (Storage); + return NULL; + } + + AsciiStorageName =3D (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Na= me; + Storage->Name =3D AllocatePool (sizeof (CHAR16) * (AsciiStrLen (A= sciiStorageName) + 1)); + if (Storage->Name =3D=3D NULL) { + + FreePool (Storage); + return NULL; + } + + AsciiToUnicode (AsciiStorageName, Storage->Name); + + break; + + case EFI_HII_VARSTORE_EFI_VARIABLE: + case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER: + CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData= )->Guid, sizeof (EFI_GUID)); + CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData= )->Attributes, sizeof (UINT32)); + CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData= )->Size, sizeof (UINT16)); + + if (StorageType =3D=3D EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { + Storage->Buffer =3D AllocateZeroPool (Storage->Size); + if (Storage->Buffer =3D=3D NULL) { + + FreePool (Storage); + return NULL; + } + } + + AsciiStorageName =3D (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)= ->Name; + Storage->Name =3D AllocatePool (sizeof (CHAR16) * (AsciiStrLen (A= sciiStorageName) + 1)); + if (Storage->Name =3D=3D NULL) { + + FreePool (Storage); + return NULL; + } + AsciiToUnicode (AsciiStorageName, Storage->Name); + + break; + + case EFI_HII_VARSTORE_NAME_VALUE: + CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeDat= a)->Guid, sizeof (EFI_GUID)); + InitializeListHead (&Storage->NameValueList); + + break; + + default: + break; + } + + InitializeConfigHdr (FormSet, Storage); + InsertTailList (&FormSet->StorageListHead, &Storage->Link); + + return Storage; +} + +/** + Get formset storage based on the input varstoreid info. + + @param[in] FormSet Pointer of the current FormSet. + @param[in] VarStoreId Varstore ID info. + + @return Pointer to a HII_FORMSET_STORAGE data structure. + +**/ +HII_FORMSET_STORAGE * +GetFstStgFromVarId ( + IN HII_FORMSET *FormSet, + IN EFI_VARSTORE_ID VarStoreId + ) +{ + HII_FORMSET_STORAGE *Storage; + LIST_ENTRY *Link; + BOOLEAN Found; + + Found =3D FALSE; + Storage =3D NULL; + // + // Find Formset Storage for this Question + // + Link =3D GetFirstNode (&FormSet->StorageListHead); + while (!IsNull (&FormSet->StorageListHead, Link)) { + Storage =3D HII_STORAGE_FROM_LINK (Link); + + if (Storage->VarStoreId =3D=3D VarStoreId) { + Found =3D TRUE; + break; + } + + Link =3D GetNextNode (&FormSet->StorageListHead, Link); + } + + return Found ? Storage : NULL; +} + +/** + Initialize Request Element of a Question. ::=3D '&' | '&'