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.
|
||||
RedfishDebugLib|Include/Library/RedfishDebugLib.h
|
||||
|
||||
## @libraryclass Provides the library functions to parse IFR binary data.
|
||||
#
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue