mirror of https://github.com/acidanthera/audk.git
RedfishPkg: introduce HII utility helper library
HiiUtilityLib is a helper library that provides the functions to manipulate HII options. Signed-off-by: Nickle Wang <nicklew@nvidia.com> Cc: Abner Chang <abner.chang@amd.com> Cc: Igor Kulchytskyy <igork@ami.com> Cc: Nick Ramirez <nramirez@nvidia.com> Reviewed-by: Abner Chang <abner.chang@amd.com> Reviewed-by: Igor Kulchytskyy <igork @ami.com>
This commit is contained in:
parent
78f088b5a7
commit
02990e2558
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,191 @@
|
||||||
|
/** @file
|
||||||
|
Definitions of Hii Expression.
|
||||||
|
|
||||||
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
||||||
|
Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef HII_EXPRESSION_H_
|
||||||
|
#define HII_EXPRESSION_H_
|
||||||
|
|
||||||
|
#include <Library/HiiUtilityLib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the expression list count.
|
||||||
|
|
||||||
|
@param[in] Level Which type this expression belong to. Form,
|
||||||
|
statement or option?
|
||||||
|
|
||||||
|
@retval >=0 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. Form,
|
||||||
|
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. Form,
|
||||||
|
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. Form,
|
||||||
|
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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,376 @@
|
||||||
|
/** @file
|
||||||
|
HII internal header file.
|
||||||
|
|
||||||
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
||||||
|
Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef HII_INTERNAL_H_
|
||||||
|
#define HII_INTERNAL_H_
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
|
||||||
|
#include <Protocol/UnicodeCollation.h>
|
||||||
|
#include <Protocol/HiiConfigRouting.h>
|
||||||
|
#include <Protocol/HiiDatabase.h>
|
||||||
|
#include <Protocol/UserManager.h>
|
||||||
|
#include <Protocol/DevicePathFromText.h>
|
||||||
|
#include <Protocol/RegularExpressionProtocol.h>
|
||||||
|
|
||||||
|
#include <Guid/MdeModuleHii.h>
|
||||||
|
#include <Guid/ZeroGuid.h>
|
||||||
|
#include <Guid/HiiPlatformSetupFormset.h>
|
||||||
|
#include <Guid/HiiFormMapMethodGuid.h>
|
||||||
|
|
||||||
|
#include <Library/PrintLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/HiiLib.h>
|
||||||
|
#include <Library/DevicePathLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
|
||||||
|
#include "HiiExpression.h"
|
||||||
|
#include <Library/HiiUtilityLib.h>
|
||||||
|
|
||||||
|
#define EXPRESSION_STACK_SIZE_INCREMENT 0x100
|
||||||
|
#define EFI_IFR_SPECIFICATION_VERSION (UINT16) (((EFI_SYSTEM_TABLE_REVISION >> 16) << 8) | (((EFI_SYSTEM_TABLE_REVISION & 0xFFFF) / 10) << 4) | ((EFI_SYSTEM_TABLE_REVISION & 0xFFFF) % 10))
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Definition of HII_FORM_CONFIG_REQUEST
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
UINTN Signature;
|
||||||
|
LIST_ENTRY Link;
|
||||||
|
|
||||||
|
CHAR16 *ConfigRequest; ///< <ConfigRequest> = <ConfigHdr> + <RequestElement>
|
||||||
|
CHAR16 *ConfigAltResp; ///< Alt config response string for this ConfigRequest.
|
||||||
|
UINTN ElementCount; ///< Number of <RequestElement> in the <ConfigRequest>
|
||||||
|
UINTN SpareStrLen;
|
||||||
|
CHAR16 *RestoreConfigRequest; ///< When submit form fail, the element need to be restored
|
||||||
|
CHAR16 *SyncConfigRequest; ///< When submit form fail, the 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_REQUEST, Link, HII_FORM_CONFIG_REQUEST_SIGNATURE)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Incremental string length of ConfigRequest
|
||||||
|
///
|
||||||
|
#define CONFIG_REQUEST_STRING_INCREMENTAL 1024
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocate new memory and then copy the Unicode string Source to Destination.
|
||||||
|
|
||||||
|
@param[in,out] Dest Location to copy string
|
||||||
|
@param[in] Src String to copy
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
NewStringCopy (
|
||||||
|
IN OUT CHAR16 **Dest,
|
||||||
|
IN CHAR16 *Src
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set Value of given Name in a NameValue Storage.
|
||||||
|
|
||||||
|
@param[in] Storage The NameValue Storage.
|
||||||
|
@param[in] Name The Name.
|
||||||
|
@param[in] Value The Value to set.
|
||||||
|
@param[out] 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 question.
|
||||||
|
Note: Data type UINT32 can cover all the bit field value.
|
||||||
|
|
||||||
|
@param[in] Question The question refer to bit field.
|
||||||
|
@param[in] Buffer Point to the buffer which the question value get from.
|
||||||
|
@param[out] 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[in] Question The question refer to bit field.
|
||||||
|
@param[in,out] Buffer Point to the buffer which the question value set to.
|
||||||
|
@param[in] 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[in] Question The question.
|
||||||
|
@param[in] Value Unicode buffer save the question value.
|
||||||
|
@param[out] QuestionValue The Question Value retrieved from Buffer.
|
||||||
|
|
||||||
|
@retval Status whether convert the value success.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
BufferToQuestionValue (
|
||||||
|
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[in] Token The String's ID.
|
||||||
|
@param[in] HiiHandle The package list in the HII database to search for
|
||||||
|
the specified string.
|
||||||
|
|
||||||
|
@return The output string.
|
||||||
|
|
||||||
|
**/
|
||||||
|
CHAR16 *
|
||||||
|
GetTokenString (
|
||||||
|
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[in] ConfigString String to be converted
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
HiiStringToLowercase (
|
||||||
|
IN EFI_STRING ConfigString
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Evaluate if the result is a non-zero value.
|
||||||
|
|
||||||
|
@param[in] Result The result to be evaluated.
|
||||||
|
|
||||||
|
@retval TRUE It is a non-zero value.
|
||||||
|
@retval FALSE It is a zero value.
|
||||||
|
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
IsHiiValueTrue (
|
||||||
|
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 associated
|
||||||
|
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
|
||||||
|
NewHiiString (
|
||||||
|
IN CHAR16 *String,
|
||||||
|
IN EFI_HII_HANDLE HiiHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Perform nosubmitif check for a Form.
|
||||||
|
|
||||||
|
@param[in] FormSet FormSet data structure.
|
||||||
|
@param[in] Form Form data structure.
|
||||||
|
@param[in] 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[in] FormSet FormSet data structure.
|
||||||
|
@param[in,out] CurrentForm Current input form data structure.
|
||||||
|
@param[out] 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 <ConfigResp>.
|
||||||
|
|
||||||
|
@param[in] Storage The Storage to be converted.
|
||||||
|
@param[in] ConfigResp The returned <ConfigResp>.
|
||||||
|
@param[in] 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 <ConfigResp> to settings in Buffer Storage or NameValue Storage.
|
||||||
|
|
||||||
|
@param[in] Storage The Storage to receive the settings.
|
||||||
|
@param[in] ConfigResp The <ConfigResp> 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[in] Handle PackageList Handle
|
||||||
|
@param[in,out] FormSetGuid On input, GUID or class GUID of a formset. If not
|
||||||
|
specified (NULL or zero GUID), take the first
|
||||||
|
FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
|
||||||
|
found in package list.
|
||||||
|
On output, GUID of the formset found(if not NULL).
|
||||||
|
@param[out] BinaryLength The length of the FormSet IFR binary.
|
||||||
|
@param[out] BinaryData The buffer designed to receive the FormSet.
|
||||||
|
|
||||||
|
@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[in] FormSet FormSet data structure.
|
||||||
|
@param[in] Storage Buffer Storage.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
LoadFormSetStorage (
|
||||||
|
IN HII_FORMSET *FormSet,
|
||||||
|
IN HII_FORMSET_STORAGE *Storage
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free resources of a Form.
|
||||||
|
|
||||||
|
@param[in] FormSet Pointer of the FormSet
|
||||||
|
@param[in,out] 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[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
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Zero extend integer/boolean/date/time to UINT64 for comparing.
|
||||||
|
|
||||||
|
@param[in] Value HII Value to be converted.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
ExtendValueToU64 (
|
||||||
|
IN HII_STATEMENT_VALUE *Value
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parse opcodes in the formset IFR binary.
|
||||||
|
|
||||||
|
@param[in] 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_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,810 @@
|
||||||
|
/** @file
|
||||||
|
Implementation of HII utility library.
|
||||||
|
|
||||||
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
||||||
|
Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "HiiInternal.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 first
|
||||||
|
FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
|
||||||
|
found in package list.
|
||||||
|
On output, GUID of the formset found(if not 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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_HANDLE DriverHandle;
|
||||||
|
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
|
||||||
|
|
||||||
|
if ((FormSetGuid == NULL) || (FormSet == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locate required Hii Database protocol
|
||||||
|
//
|
||||||
|
Status = gBS->LocateProtocol (
|
||||||
|
&gEfiHiiDatabaseProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
(VOID **)&HiiDatabase
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormSet->Signature = HII_FORMSET_SIGNATURE;
|
||||||
|
FormSet->HiiHandle = Handle;
|
||||||
|
CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));
|
||||||
|
//
|
||||||
|
// Retrieve ConfigAccess Protocol associated with this HiiPackageList
|
||||||
|
//
|
||||||
|
Status = HiiDatabase->GetPackageListHandle (HiiDatabase, Handle, &DriverHandle);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormSet->DriverHandle = DriverHandle;
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
DriverHandle,
|
||||||
|
&gEfiHiiConfigAccessProtocolGuid,
|
||||||
|
(VOID **)&FormSet->ConfigAccess
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Configuration Driver don't attach ConfigAccess protocol to its HII package
|
||||||
|
// list, then there will be no configuration action required
|
||||||
|
//
|
||||||
|
FormSet->ConfigAccess = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
DriverHandle,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
(VOID **)&FormSet->DevicePath
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Configuration Driver don't attach ConfigAccess protocol to its HII package
|
||||||
|
// list, then there will be no configuration action required
|
||||||
|
//
|
||||||
|
FormSet->DevicePath = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parse the IFR binary OpCodes
|
||||||
|
//
|
||||||
|
Status = ParseOpCodes (FormSet);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize a Formset and get current setting for Questions.
|
||||||
|
|
||||||
|
@param FormSet FormSet data structure.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
InitializeFormSet (
|
||||||
|
IN OUT HII_FORMSET *FormSet
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
HII_FORMSET_STORAGE *Storage;
|
||||||
|
LIST_ENTRY *FormLink;
|
||||||
|
HII_STATEMENT *Question;
|
||||||
|
HII_FORM *Form;
|
||||||
|
|
||||||
|
if (FormSet == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Load Storage for all questions with storage
|
||||||
|
//
|
||||||
|
Link = GetFirstNode (&FormSet->StorageListHead);
|
||||||
|
while (!IsNull (&FormSet->StorageListHead, Link)) {
|
||||||
|
Storage = HII_STORAGE_FROM_LINK (Link);
|
||||||
|
LoadFormSetStorage (FormSet, Storage);
|
||||||
|
Link = GetNextNode (&FormSet->StorageListHead, Link);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get Current Value for all no storage questions
|
||||||
|
//
|
||||||
|
FormLink = GetFirstNode (&FormSet->FormListHead);
|
||||||
|
while (!IsNull (&FormSet->FormListHead, FormLink)) {
|
||||||
|
Form = HII_FORM_FROM_LINK (FormLink);
|
||||||
|
Link = GetFirstNode (&Form->StatementListHead);
|
||||||
|
while (!IsNull (&Form->StatementListHead, Link)) {
|
||||||
|
Question = HII_STATEMENT_FROM_LINK (Link);
|
||||||
|
if (Question->Storage == NULL) {
|
||||||
|
RetrieveQuestion (FormSet, Form, Question);
|
||||||
|
}
|
||||||
|
|
||||||
|
Link = GetNextNode (&Form->StatementListHead, Link);
|
||||||
|
}
|
||||||
|
|
||||||
|
FormLink = GetNextNode (&FormSet->FormListHead, FormLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free resources allocated for a FormSet.
|
||||||
|
|
||||||
|
@param[in,out] FormSet Pointer of the FormSet
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
DestroyFormSet (
|
||||||
|
IN OUT HII_FORMSET *FormSet
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
HII_FORMSET_STORAGE *Storage;
|
||||||
|
HII_FORMSET_DEFAULTSTORE *DefaultStore;
|
||||||
|
HII_FORM *Form;
|
||||||
|
|
||||||
|
if (FormSet->IfrBinaryData == NULL) {
|
||||||
|
//
|
||||||
|
// Uninitialized FormSet
|
||||||
|
//
|
||||||
|
FreePool (FormSet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free IFR binary buffer
|
||||||
|
//
|
||||||
|
FreePool (FormSet->IfrBinaryData);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free FormSet Storage
|
||||||
|
//
|
||||||
|
if (FormSet->StorageListHead.ForwardLink != NULL) {
|
||||||
|
while (!IsListEmpty (&FormSet->StorageListHead)) {
|
||||||
|
Link = GetFirstNode (&FormSet->StorageListHead);
|
||||||
|
Storage = HII_STORAGE_FROM_LINK (Link);
|
||||||
|
RemoveEntryList (&Storage->Link);
|
||||||
|
|
||||||
|
if (Storage != NULL) {
|
||||||
|
FreePool (Storage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free FormSet Default Store
|
||||||
|
//
|
||||||
|
if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
|
||||||
|
while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
|
||||||
|
Link = GetFirstNode (&FormSet->DefaultStoreListHead);
|
||||||
|
DefaultStore = HII_FORMSET_DEFAULTSTORE_FROM_LINK (Link);
|
||||||
|
RemoveEntryList (&DefaultStore->Link);
|
||||||
|
|
||||||
|
FreePool (DefaultStore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free Forms
|
||||||
|
//
|
||||||
|
if (FormSet->FormListHead.ForwardLink != NULL) {
|
||||||
|
while (!IsListEmpty (&FormSet->FormListHead)) {
|
||||||
|
Link = GetFirstNode (&FormSet->FormListHead);
|
||||||
|
Form = HII_FORM_FROM_LINK (Link);
|
||||||
|
RemoveEntryList (&Form->Link);
|
||||||
|
|
||||||
|
DestroyForm (FormSet, Form);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (FormSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Submit data for a form.
|
||||||
|
|
||||||
|
@param[in] FormSet FormSet which contains the Form.
|
||||||
|
@param[in] 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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
EFI_STRING ConfigResp;
|
||||||
|
EFI_STRING Progress;
|
||||||
|
HII_FORMSET_STORAGE *Storage;
|
||||||
|
HII_FORM_CONFIG_REQUEST *ConfigInfo;
|
||||||
|
|
||||||
|
if ((FormSet == NULL) || (Form == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = NoSubmitCheck (FormSet, &Form, NULL);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Link = GetFirstNode (&Form->ConfigRequestHead);
|
||||||
|
while (!IsNull (&Form->ConfigRequestHead, Link)) {
|
||||||
|
ConfigInfo = HII_FORM_CONFIG_REQUEST_FROM_LINK (Link);
|
||||||
|
Link = GetNextNode (&Form->ConfigRequestHead, Link);
|
||||||
|
|
||||||
|
Storage = ConfigInfo->Storage;
|
||||||
|
if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Skip if there is no RequestElement
|
||||||
|
//
|
||||||
|
if (ConfigInfo->ElementCount == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->LocateProtocol (
|
||||||
|
&gEfiHiiConfigRoutingProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
(VOID **)&HiiConfigRouting
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = HiiConfigRouting->RouteConfig (
|
||||||
|
HiiConfigRouting,
|
||||||
|
ConfigResp,
|
||||||
|
&Progress
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
FreePool (ConfigResp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (ConfigResp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Save Question Value to the memory, but not to storage.
|
||||||
|
|
||||||
|
@param[in] FormSet FormSet data structure.
|
||||||
|
@param[in] Form Form data structure.
|
||||||
|
@param[in,out] Question Pointer to the Question.
|
||||||
|
@param[in] QuestionValue New Question Value to be set.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The question value has been set successfully.
|
||||||
|
@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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT8 *Src;
|
||||||
|
UINTN BufferLen;
|
||||||
|
UINTN StorageWidth;
|
||||||
|
HII_FORMSET_STORAGE *Storage;
|
||||||
|
CHAR16 *ValueStr;
|
||||||
|
BOOLEAN IsBufferStorage;
|
||||||
|
UINT8 *TemBuffer;
|
||||||
|
CHAR16 *TemName;
|
||||||
|
CHAR16 *TemString;
|
||||||
|
UINTN Index;
|
||||||
|
HII_NAME_VALUE_NODE *Node;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
if ((FormSet == NULL) || (Form == NULL) || (Question == NULL) || (QuestionValue == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
Node = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If Question value is provided by an Expression, then it is read only
|
||||||
|
//
|
||||||
|
if ((Question->ValueExpression != NULL) || (Question->Value.Type != QuestionValue->Type)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Before set question value, evaluate its write expression.
|
||||||
|
//
|
||||||
|
if ((Question->WriteExpression != NULL) && (Form->FormType == STANDARD_MAP_FORM_TYPE)) {
|
||||||
|
Status = EvaluateHiiExpression (FormSet, Form, Question->WriteExpression);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage = Question->Storage;
|
||||||
|
if (Storage != NULL) {
|
||||||
|
StorageWidth = Question->StorageWidth;
|
||||||
|
if (Question->Value.Type == EFI_IFR_TYPE_BUFFER) {
|
||||||
|
Question->Value.BufferLen = QuestionValue->BufferLen;
|
||||||
|
Question->Value.Buffer = AllocateCopyPool (QuestionValue->BufferLen, QuestionValue->Buffer);
|
||||||
|
if (Question->Value.Buffer == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Question->Value.BufferValueType = QuestionValue->BufferValueType;
|
||||||
|
Src = Question->Value.Buffer;
|
||||||
|
} else if (Question->Value.Type == EFI_IFR_TYPE_STRING) {
|
||||||
|
Question->Value.Value.string = QuestionValue->Value.string;
|
||||||
|
TemString = HiiGetString (FormSet->HiiHandle, QuestionValue->Value.string, NULL);
|
||||||
|
if (TemString == NULL) {
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Question->Value.BufferLen = Question->StorageWidth;
|
||||||
|
Question->Value.Buffer = AllocateZeroPool (Question->StorageWidth);
|
||||||
|
if (Question->Value.Buffer == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (Question->Value.Buffer, TemString, StrSize (TemString));
|
||||||
|
Src = Question->Value.Buffer;
|
||||||
|
} else {
|
||||||
|
CopyMem (&Question->Value.Value, &QuestionValue->Value, sizeof (EFI_IFR_TYPE_VALUE));
|
||||||
|
Src = (UINT8 *)&Question->Value.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
|
||||||
|
IsBufferStorage = TRUE;
|
||||||
|
} else {
|
||||||
|
IsBufferStorage = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsBufferStorage) {
|
||||||
|
//
|
||||||
|
// If the Question refer to bit filed, copy the value in related bit filed to storage edit buffer.
|
||||||
|
//
|
||||||
|
if (Question->QuestionReferToBitField) {
|
||||||
|
SetBitsQuestionValue (Question, Storage->Buffer + Question->VarStoreInfo.VarOffset, (UINT32)(*Src));
|
||||||
|
} else {
|
||||||
|
CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Question->Value.Type == EFI_IFR_TYPE_STRING) {
|
||||||
|
//
|
||||||
|
// Allocate enough string buffer.
|
||||||
|
//
|
||||||
|
ValueStr = NULL;
|
||||||
|
BufferLen = ((StrLen ((CHAR16 *)Src) * 4) + 1) * sizeof (CHAR16);
|
||||||
|
ValueStr = AllocatePool (BufferLen);
|
||||||
|
if (ValueStr == NULL) {
|
||||||
|
if (Question->Value.Buffer != NULL) {
|
||||||
|
FreePool (Question->Value.Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
|
||||||
|
//
|
||||||
|
TemName = (CHAR16 *)Src;
|
||||||
|
TemString = ValueStr;
|
||||||
|
for ( ; *TemName != L'\0'; TemName++) {
|
||||||
|
UnicodeValueToStringS (
|
||||||
|
TemString,
|
||||||
|
BufferLen - ((UINTN)TemString - (UINTN)ValueStr),
|
||||||
|
PREFIX_ZERO | RADIX_HEX,
|
||||||
|
*TemName,
|
||||||
|
4
|
||||||
|
);
|
||||||
|
TemString += StrnLenS (TemString, (BufferLen - ((UINTN)TemString - (UINTN)ValueStr)) / sizeof (CHAR16));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
BufferLen = StorageWidth * 2 + 1;
|
||||||
|
ValueStr = AllocateZeroPool (BufferLen * sizeof (CHAR16));
|
||||||
|
if (ValueStr == NULL) {
|
||||||
|
if (Question->Value.Buffer != NULL) {
|
||||||
|
FreePool (Question->Value.Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Convert Buffer to Hex String
|
||||||
|
//
|
||||||
|
TemBuffer = Src + StorageWidth - 1;
|
||||||
|
TemString = ValueStr;
|
||||||
|
for (Index = 0; Index < StorageWidth; Index++, TemBuffer--) {
|
||||||
|
UnicodeValueToStringS (
|
||||||
|
TemString,
|
||||||
|
BufferLen * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ValueStr),
|
||||||
|
PREFIX_ZERO | RADIX_HEX,
|
||||||
|
*TemBuffer,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
TemString += StrnLenS (TemString, BufferLen - ((UINTN)TemString - (UINTN)ValueStr) / sizeof (CHAR16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = SetValueByName (Storage, Question->VariableName, ValueStr, &Node);
|
||||||
|
FreePool (ValueStr);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
if (Question->Value.Buffer != NULL) {
|
||||||
|
FreePool (Question->Value.Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Question->Value.Type == EFI_IFR_TYPE_BUFFER) {
|
||||||
|
Question->Value.BufferLen = QuestionValue->BufferLen;
|
||||||
|
Question->Value.Buffer = AllocateCopyPool (QuestionValue->BufferLen, QuestionValue->Buffer);
|
||||||
|
if (Question->Value.Buffer == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Question->Value.BufferValueType = QuestionValue->BufferValueType;
|
||||||
|
} else if (Question->Value.Type == EFI_IFR_TYPE_STRING) {
|
||||||
|
Question->Value.Value.string = QuestionValue->Value.string;
|
||||||
|
TemString = HiiGetString (FormSet->HiiHandle, QuestionValue->Value.string, NULL);
|
||||||
|
if (TemString == NULL) {
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Question->Value.BufferLen = (UINT16)StrSize (TemString);
|
||||||
|
Question->Value.Buffer = AllocateZeroPool (QuestionValue->BufferLen);
|
||||||
|
if (Question->Value.Buffer == NULL) {
|
||||||
|
FreePool (TemString);
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (Question->Value.Buffer, TemString, StrSize (TemString));
|
||||||
|
FreePool (TemString);
|
||||||
|
} else {
|
||||||
|
CopyMem (&Question->Value.Value, &QuestionValue->Value, sizeof (EFI_IFR_TYPE_VALUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get Question's current Value from storage.
|
||||||
|
|
||||||
|
@param[in] FormSet FormSet data structure.
|
||||||
|
@param[in] Form Form data structure.
|
||||||
|
@param[in,out] 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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
|
||||||
|
EFI_BROWSER_ACTION_REQUEST ActionRequest;
|
||||||
|
HII_FORMSET_STORAGE *Storage;
|
||||||
|
HII_STATEMENT_VALUE *QuestionValue;
|
||||||
|
EFI_IFR_TYPE_VALUE *TypeValue;
|
||||||
|
EFI_TIME EfiTime;
|
||||||
|
BOOLEAN Enabled;
|
||||||
|
BOOLEAN Pending;
|
||||||
|
UINT8 *Dst;
|
||||||
|
UINTN StorageWidth;
|
||||||
|
CHAR16 *ConfigRequest;
|
||||||
|
CHAR16 *Progress;
|
||||||
|
CHAR16 *Result;
|
||||||
|
CHAR16 *ValueStr;
|
||||||
|
UINTN Length;
|
||||||
|
BOOLEAN IsBufferStorage;
|
||||||
|
CHAR16 *NewHiiString;
|
||||||
|
|
||||||
|
if ((FormSet == NULL) || (Form == NULL) || (Question == NULL)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
ValueStr = NULL;
|
||||||
|
Result = NULL;
|
||||||
|
|
||||||
|
QuestionValue = AllocateZeroPool (sizeof (HII_STATEMENT_VALUE));
|
||||||
|
if (QuestionValue == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestionValue->Type = Question->Value.Type;
|
||||||
|
QuestionValue->BufferLen = Question->Value.BufferLen;
|
||||||
|
if (QuestionValue->BufferLen != 0) {
|
||||||
|
QuestionValue->Buffer = AllocateZeroPool (QuestionValue->BufferLen);
|
||||||
|
if (QuestionValue->Buffer == NULL) {
|
||||||
|
FreePool (QuestionValue);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Question value is provided by RTC
|
||||||
|
//
|
||||||
|
Storage = Question->Storage;
|
||||||
|
StorageWidth = Question->StorageWidth;
|
||||||
|
|
||||||
|
if (Storage == NULL) {
|
||||||
|
//
|
||||||
|
// It's a Question without storage, or RTC date/time
|
||||||
|
//
|
||||||
|
if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {
|
||||||
|
//
|
||||||
|
// Date and time define the same Flags bit
|
||||||
|
//
|
||||||
|
switch (Question->ExtraData.Flags & EFI_QF_DATE_STORAGE) {
|
||||||
|
case QF_DATE_STORAGE_TIME:
|
||||||
|
|
||||||
|
Status = gRT->GetTime (&EfiTime, NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QF_DATE_STORAGE_WAKEUP:
|
||||||
|
|
||||||
|
Status = gRT->GetWakeupTime (&Enabled, &Pending, &EfiTime);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QF_DATE_STORAGE_NORMAL:
|
||||||
|
default:
|
||||||
|
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
if (Question->Operand == EFI_IFR_DATE_OP) {
|
||||||
|
QuestionValue->Value.date.Year = 0xff;
|
||||||
|
QuestionValue->Value.date.Month = 0xff;
|
||||||
|
QuestionValue->Value.date.Day = 0xff;
|
||||||
|
} else {
|
||||||
|
QuestionValue->Value.time.Hour = 0xff;
|
||||||
|
QuestionValue->Value.time.Minute = 0xff;
|
||||||
|
QuestionValue->Value.time.Second = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QuestionValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Question->Operand == EFI_IFR_DATE_OP) {
|
||||||
|
QuestionValue->Value.date.Year = EfiTime.Year;
|
||||||
|
QuestionValue->Value.date.Month = EfiTime.Month;
|
||||||
|
QuestionValue->Value.date.Day = EfiTime.Day;
|
||||||
|
} else {
|
||||||
|
QuestionValue->Value.time.Hour = EfiTime.Hour;
|
||||||
|
QuestionValue->Value.time.Minute = EfiTime.Minute;
|
||||||
|
QuestionValue->Value.time.Second = EfiTime.Second;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) ||
|
||||||
|
(FormSet->ConfigAccess == NULL))
|
||||||
|
{
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QuestionValue->Type == EFI_IFR_TYPE_BUFFER) {
|
||||||
|
//
|
||||||
|
// For OrderedList, passing in the value buffer to Callback()
|
||||||
|
//
|
||||||
|
TypeValue = (EFI_IFR_TYPE_VALUE *)QuestionValue->Buffer;
|
||||||
|
} else {
|
||||||
|
TypeValue = &QuestionValue->Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
|
||||||
|
Status = FormSet->ConfigAccess->Callback (
|
||||||
|
FormSet->ConfigAccess,
|
||||||
|
EFI_BROWSER_ACTION_RETRIEVE,
|
||||||
|
Question->QuestionId,
|
||||||
|
QuestionValue->Type,
|
||||||
|
TypeValue,
|
||||||
|
&ActionRequest
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status) && (QuestionValue->Type == EFI_IFR_TYPE_STRING)) {
|
||||||
|
if (TypeValue->string == 0) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewHiiString = GetTokenString (TypeValue->string, FormSet->HiiHandle);
|
||||||
|
if (NewHiiString == NULL) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestionValue->Buffer = AllocatePool (StrSize (NewHiiString));
|
||||||
|
if (QuestionValue->Buffer == NULL) {
|
||||||
|
FreePool (NewHiiString);
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (QuestionValue->Buffer, NewHiiString, StrSize (NewHiiString));
|
||||||
|
QuestionValue->BufferLen = (UINT16)StrSize (NewHiiString);
|
||||||
|
|
||||||
|
FreePool (NewHiiString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QuestionValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Question value is provided by EFI variable
|
||||||
|
//
|
||||||
|
if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
|
||||||
|
if ((QuestionValue->Type != EFI_IFR_TYPE_BUFFER) && (QuestionValue->Type != EFI_IFR_TYPE_STRING)) {
|
||||||
|
Dst = QuestionValue->Buffer;
|
||||||
|
StorageWidth = QuestionValue->BufferLen;
|
||||||
|
} else {
|
||||||
|
Dst = (UINT8 *)&QuestionValue->Value;
|
||||||
|
StorageWidth = sizeof (EFI_IFR_TYPE_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gRT->GetVariable (
|
||||||
|
Question->VariableName,
|
||||||
|
&Storage->Guid,
|
||||||
|
NULL,
|
||||||
|
&StorageWidth,
|
||||||
|
Dst
|
||||||
|
);
|
||||||
|
|
||||||
|
return QuestionValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->LocateProtocol (
|
||||||
|
&gEfiHiiConfigRoutingProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
(VOID **)&HiiConfigRouting
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QuestionValue->BufferLen != 0) {
|
||||||
|
Dst = QuestionValue->Buffer;
|
||||||
|
} else {
|
||||||
|
Dst = (UINT8 *)&QuestionValue->Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
|
||||||
|
IsBufferStorage = TRUE;
|
||||||
|
} else {
|
||||||
|
IsBufferStorage = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage = GetFstStgFromVarId (FormSet, Question->VarStoreId);
|
||||||
|
if (Storage == NULL) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// <ConfigRequest> ::= <ConfigHdr> + <BlockName> || <ConfigHdr> + "&" + <VariableName>
|
||||||
|
//
|
||||||
|
if (IsBufferStorage) {
|
||||||
|
Length = StrLen (Storage->ConfigHdr);
|
||||||
|
Length += StrLen (Question->BlockName);
|
||||||
|
} else {
|
||||||
|
Length = StrLen (Storage->ConfigHdr);
|
||||||
|
Length += StrLen (Question->VariableName) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigRequest = AllocatePool ((Length + 1) * sizeof (CHAR16));
|
||||||
|
if (ConfigRequest == NULL) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
StrCpyS (ConfigRequest, Length + 1, Storage->ConfigHdr);
|
||||||
|
if (IsBufferStorage) {
|
||||||
|
StrCatS (ConfigRequest, Length + 1, Question->BlockName);
|
||||||
|
} else {
|
||||||
|
StrCatS (ConfigRequest, Length + 1, L"&");
|
||||||
|
StrCatS (ConfigRequest, Length + 1, Question->VariableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Request current settings from Configuration Driver
|
||||||
|
//
|
||||||
|
Status = HiiConfigRouting->ExtractConfig (
|
||||||
|
HiiConfigRouting,
|
||||||
|
ConfigRequest,
|
||||||
|
&Progress,
|
||||||
|
&Result
|
||||||
|
);
|
||||||
|
FreePool (ConfigRequest);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsBufferStorage) {
|
||||||
|
ValueStr = StrStr (Result, L"&VALUE");
|
||||||
|
if (ValueStr == NULL) {
|
||||||
|
FreePool (Result);
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueStr = ValueStr + 6;
|
||||||
|
} else {
|
||||||
|
ValueStr = Result + Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ValueStr != '=') {
|
||||||
|
FreePool (Result);
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueStr++;
|
||||||
|
Status = BufferToQuestionValue (Question, ValueStr, QuestionValue);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
FreePool (Result);
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Result != NULL) {
|
||||||
|
FreePool (Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QuestionValue;
|
||||||
|
|
||||||
|
ON_ERROR:
|
||||||
|
|
||||||
|
if (QuestionValue->Buffer != NULL) {
|
||||||
|
FreePool (QuestionValue->Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (QuestionValue);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
## @file
|
||||||
|
# Library to handle HII IFR data.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
||||||
|
# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
|
[Defines]
|
||||||
|
INF_VERSION = 0x00010005
|
||||||
|
BASE_NAME = HiiUtilityLib
|
||||||
|
FILE_GUID = D00DA028-F19A-47AF-B22A-6EE9E8BD7335
|
||||||
|
MODULE_TYPE = UEFI_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = HiiUtilityLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
|
||||||
|
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = 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
|
|
@ -60,6 +60,10 @@
|
||||||
# Library provides Redfish debug functions.
|
# Library provides Redfish debug functions.
|
||||||
RedfishDebugLib|Include/Library/RedfishDebugLib.h
|
RedfishDebugLib|Include/Library/RedfishDebugLib.h
|
||||||
|
|
||||||
|
## @libraryclass Provides the library functions to parse IFR binary data.
|
||||||
|
#
|
||||||
|
HiiUtilityLib|Include/Library/HiiUtilityLib.h
|
||||||
|
|
||||||
[LibraryClasses.Common.Private]
|
[LibraryClasses.Common.Private]
|
||||||
## @libraryclass Provides the private C runtime library functions.
|
## @libraryclass Provides the private C runtime library functions.
|
||||||
# CRT library is currently used by edk2 JsonLib (open source
|
# CRT library is currently used by edk2 JsonLib (open source
|
||||||
|
|
Loading…
Reference in New Issue