1483 lines
43 KiB
C
1483 lines
43 KiB
C
/** @file
|
|
HII Extension Library implementation that uses DXE protocols and services.
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2013 - 2020, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "InternalHiiExLib.h"
|
|
|
|
extern GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiDefaultTypeToWidth[8];
|
|
|
|
UINTN
|
|
EFIAPI
|
|
InternalHiiOpCodeHandlePosition (
|
|
IN VOID *OpCodeHandle
|
|
);
|
|
|
|
UINT8 *
|
|
EFIAPI
|
|
InternalHiiCreateOpCodeExtended (
|
|
IN VOID *OpCodeHandle,
|
|
IN VOID *OpCodeTemplate,
|
|
IN UINT8 OpCode,
|
|
IN UINTN OpCodeSize,
|
|
IN UINTN ExtensionSize,
|
|
IN UINT8 Scope
|
|
);
|
|
|
|
UINT8 *
|
|
EFIAPI
|
|
InternalHiiAppendOpCodes (
|
|
IN VOID *OpCodeHandle,
|
|
IN VOID *RawOpCodeHandle
|
|
);
|
|
|
|
UINT8 *
|
|
EFIAPI
|
|
InternalHiiOpCodeHandleBuffer (
|
|
IN VOID *OpCodeHandle
|
|
);
|
|
|
|
/**
|
|
Get HII handle list by specified package type.
|
|
|
|
@param[in] PackageType Specifies the package type of the packages to list.
|
|
|
|
@return A pointer to the HII handle list or NULL if there is no specified package in HII database or fail to allocate pool.
|
|
**/
|
|
EFI_HII_HANDLE *
|
|
HiiGetHiiHandlesByPackageType (
|
|
IN UINT8 PackageType
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN HiiHandleListSize;
|
|
EFI_HII_HANDLE *HiiHandleList;
|
|
|
|
HiiHandleListSize = 0;
|
|
HiiHandleList = NULL;
|
|
Status = gHiiDatabase->ListPackageLists (
|
|
gHiiDatabase,
|
|
PackageType,
|
|
NULL,
|
|
&HiiHandleListSize,
|
|
HiiHandleList
|
|
);
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
return NULL;
|
|
}
|
|
|
|
HiiHandleList = AllocateZeroPool (HiiHandleListSize + sizeof (EFI_HII_HANDLE));
|
|
if (HiiHandleList == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
Status = gHiiDatabase->ListPackageLists (
|
|
gHiiDatabase,
|
|
PackageType,
|
|
NULL,
|
|
&HiiHandleListSize,
|
|
HiiHandleList
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (HiiHandleList);
|
|
return NULL;
|
|
}
|
|
|
|
return HiiHandleList;
|
|
}
|
|
|
|
/**
|
|
Get formset GUID from input form package.
|
|
|
|
@param[in] HiiFormPackage Pointer to HII form package.
|
|
@param[out] FormsetGuid Pointer to formset GUID.
|
|
|
|
@retval EFI_SUCCESS Successfully get formset GUID
|
|
@retval EFI_INVALID_PARAMETER Input pointer is NULL or package type is not form type
|
|
@retval EFI_NOT_FOUND Formset is not found in form package
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
GetFormsetGuidByPackage (
|
|
IN UINT8 *HiiFormPackage,
|
|
OUT EFI_GUID *FormsetGuid
|
|
)
|
|
{
|
|
EFI_HII_PACKAGE_HEADER *PackageHeader;
|
|
UINT32 Offset;
|
|
UINT8 *OpCodeData;
|
|
|
|
if (HiiFormPackage == NULL || FormsetGuid == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiFormPackage;
|
|
if (PackageHeader->Type != EFI_HII_PACKAGE_FORMS) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Offset = sizeof (EFI_HII_PACKAGE_HEADER);
|
|
while (Offset < PackageHeader->Length) {
|
|
OpCodeData = HiiFormPackage + Offset;
|
|
|
|
if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
|
|
CopyGuid (FormsetGuid, (GUID *)(VOID *)&((EFI_IFR_FORM_SET *) OpCodeData)->Guid);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Offset += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
/**
|
|
Create H2O_IFR_GUID_TEXT opcode.
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] PreviousOpCodeHeader Pointer to the opcode header of previous opcode
|
|
@param[in] TextTwo String ID for Text Two
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateGuidTextOpCode (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_IFR_OP_HEADER *PreviousOpCodeHeader,
|
|
IN EFI_STRING_ID TextTwo
|
|
)
|
|
{
|
|
H2O_IFR_GUID_TEXT *GuidText;
|
|
|
|
GuidText = (H2O_IFR_GUID_TEXT *) HiiCreateGuidOpCode (
|
|
OpCodeHandle,
|
|
&gH2OIfrExtGuid,
|
|
NULL,
|
|
sizeof (H2O_IFR_GUID_TEXT)
|
|
);
|
|
if (GuidText == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
GuidText->Function = H2O_IFR_EXT_TEXT;
|
|
GuidText->Text = TextTwo;
|
|
|
|
if (PreviousOpCodeHeader->Scope == 0) {
|
|
PreviousOpCodeHeader->Scope = 1;
|
|
HiiCreateEndOpCode (OpCodeHandle);
|
|
}
|
|
|
|
return (UINT8 *) GuidText;
|
|
}
|
|
|
|
/**
|
|
Create H2O_IFR_GUID_EXT_FLAGS opcode.
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] PreviousOpCodeHeader Pointer to the opcode header of previous opcode
|
|
@param[in] ExtFlags Extended Flags for previous opcode
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateGuidExtFlagsOpCode (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_IFR_OP_HEADER *PreviousOpCodeHeader,
|
|
IN UINT32 ExtFlags
|
|
)
|
|
{
|
|
H2O_IFR_GUID_EXT_FLAGS *GuidExtFlags;
|
|
|
|
GuidExtFlags = (H2O_IFR_GUID_EXT_FLAGS *) HiiCreateGuidOpCode (
|
|
OpCodeHandle,
|
|
&gH2OIfrExtGuid,
|
|
NULL,
|
|
sizeof (H2O_IFR_GUID_EXT_FLAGS)
|
|
);
|
|
if (GuidExtFlags == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
GuidExtFlags->Function = H2O_IFR_EXT_EXT_FLAGS;
|
|
GuidExtFlags->ExtFlags = ExtFlags;
|
|
|
|
if (PreviousOpCodeHeader->Scope == 0) {
|
|
PreviousOpCodeHeader->Scope = 1;
|
|
HiiCreateEndOpCode (OpCodeHandle);
|
|
}
|
|
|
|
return (UINT8 *) GuidExtFlags;
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_REFRESH opcode.
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] PreviousOpCodeHeader Pointer to the opcode header of previous opcode
|
|
@param[in] RefreshInterval Refresh Interval by seconds for previous opcode
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateRefreshOpCode (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_IFR_OP_HEADER *PreviousOpCodeHeader,
|
|
IN UINT8 RefreshInterval
|
|
)
|
|
{
|
|
EFI_IFR_REFRESH OpCode;
|
|
UINT8 *OpCodePtr;
|
|
|
|
OpCode.RefreshInterval = RefreshInterval;
|
|
|
|
OpCodePtr = (UINT8 *)InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_REFRESH_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
0
|
|
);
|
|
if (OpCodePtr == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
if (PreviousOpCodeHeader->Scope == 0) {
|
|
PreviousOpCodeHeader->Scope = 1;
|
|
HiiCreateEndOpCode (OpCodeHandle);
|
|
}
|
|
|
|
return (UINT8 *) OpCodePtr;
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_ACTION_OP opcode with text two.
|
|
If string ID of text two is zero, it will create EFI_IFR_ACTION_OP opcode without text two.
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] QuestionId Question ID
|
|
@param[in] Prompt String ID for Prompt
|
|
@param[in] Help String ID for Help
|
|
@param[in] TextTwo String ID for Text Two
|
|
@param[in] QuestionFlags Flags in Question Header
|
|
@param[in] QuestionConfig String ID for configuration
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
EFIAPI
|
|
HiiCreateActionOpCodeEx (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN EFI_STRING_ID Prompt,
|
|
IN EFI_STRING_ID Help,
|
|
IN EFI_STRING_ID TextTwo,
|
|
IN UINT8 QuestionFlags,
|
|
IN EFI_STRING_ID QuestionConfig
|
|
)
|
|
{
|
|
EFI_IFR_ACTION *Action;
|
|
|
|
Action = (EFI_IFR_ACTION *) HiiCreateActionOpCode (
|
|
OpCodeHandle,
|
|
QuestionId,
|
|
Prompt,
|
|
Help,
|
|
QuestionFlags,
|
|
QuestionConfig
|
|
);
|
|
if (Action == NULL || TextTwo == 0) {
|
|
return (UINT8 *) Action;
|
|
}
|
|
|
|
HiiCreateGuidTextOpCode (OpCodeHandle, &Action->Header, TextTwo);
|
|
|
|
return (UINT8 *) Action;
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_ACTION_OP opcode with text two and scope.
|
|
If string ID of text two is zero, it will create EFI_IFR_ACTION_OP opcode without text two.
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] QuestionId Question ID
|
|
@param[in] Prompt String ID for Prompt
|
|
@param[in] Help String ID for Help
|
|
@param[in] TextTwo String ID for Text Two
|
|
@param[in] QuestionFlags Flags in Question Header
|
|
@param[in] QuestionConfig String ID for configuration
|
|
@param[in] Scope Scope
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
EFIAPI
|
|
HiiCreateActionOpCodeExWithScope (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN EFI_STRING_ID Prompt,
|
|
IN EFI_STRING_ID Help,
|
|
IN EFI_STRING_ID TextTwo,
|
|
IN UINT8 QuestionFlags,
|
|
IN EFI_STRING_ID QuestionConfig,
|
|
IN UINT8 Scope
|
|
)
|
|
{
|
|
EFI_IFR_ACTION *Action;
|
|
|
|
Action = (EFI_IFR_ACTION *) HiiCreateActionOpCode (
|
|
OpCodeHandle,
|
|
QuestionId,
|
|
Prompt,
|
|
Help,
|
|
QuestionFlags,
|
|
QuestionConfig
|
|
);
|
|
if (Action == NULL || TextTwo == 0) {
|
|
return (UINT8 *) Action;
|
|
}
|
|
|
|
Action->Header.Scope = Scope;
|
|
HiiCreateGuidTextOpCode (OpCodeHandle, &Action->Header, TextTwo);
|
|
|
|
return (UINT8 *) Action;
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_ACTION_OP opcode with text two and refresh opcode.
|
|
If string ID of text two is zero, it will create EFI_IFR_ACTION_OP opcode without text two.
|
|
If RefreshInterval is zero, it will create EFI_IFR_ACTION_OP opcode without refresh.
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] QuestionId Question ID
|
|
@param[in] Prompt String ID for Prompt
|
|
@param[in] Help String ID for Help
|
|
@param[in] TextTwo String ID for Text Two
|
|
@param[in] QuestionFlags Flags in Question Header
|
|
@param[in] QuestionConfig String ID for configuration
|
|
@param[in] RefreshInterval RefreshInterval
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
EFIAPI
|
|
HiiCreateActionOpCodeExWithRefresh (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN EFI_STRING_ID Prompt,
|
|
IN EFI_STRING_ID Help,
|
|
IN EFI_STRING_ID TextTwo,
|
|
IN UINT8 QuestionFlags,
|
|
IN EFI_STRING_ID QuestionConfig,
|
|
IN UINT8 RefreshInterval
|
|
)
|
|
{
|
|
EFI_IFR_ACTION *Action;
|
|
UINT8 Scope;
|
|
|
|
if (RefreshInterval == 0) {
|
|
Scope = 0;
|
|
} else {
|
|
Scope = 1;
|
|
}
|
|
|
|
Action = (EFI_IFR_ACTION *) HiiCreateActionOpCodeExWithScope (
|
|
OpCodeHandle,
|
|
QuestionId,
|
|
Prompt,
|
|
Help,
|
|
TextTwo,
|
|
QuestionFlags,
|
|
QuestionConfig,
|
|
Scope
|
|
);
|
|
if (Action == NULL || Scope == 0) {
|
|
return (UINT8 *) Action;
|
|
}
|
|
|
|
HiiCreateRefreshOpCode (OpCodeHandle, &Action->Header, RefreshInterval);
|
|
HiiCreateEndOpCode (OpCodeHandle);
|
|
|
|
return (UINT8 *) Action;
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_PASSWORD_OP opcode with text two.
|
|
If string ID of text two is zero, it will create EFI_IFR_PASSWORD_OP opcode without text two.
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] QuestionId Question ID
|
|
@param[in] VarStoreId Storage ID
|
|
@param[in] VarOffset Offset in Storage
|
|
@param[in] Prompt String ID for Prompt
|
|
@param[in] Help String ID for Help
|
|
@param[in] TextTwo String ID for Text Two
|
|
@param[in] QuestionFlags Flags in Question Header
|
|
@param[in] Minimum Numeric minimum value
|
|
@param[in] Maximum Numeric maximum value
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
EFIAPI
|
|
HiiCreatePasswordOpCodeEx (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN EFI_VARSTORE_ID VarStoreId,
|
|
IN UINT16 VarOffset,
|
|
IN EFI_STRING_ID Prompt,
|
|
IN EFI_STRING_ID Help,
|
|
IN EFI_STRING_ID TextTwo,
|
|
IN UINT8 QuestionFlags,
|
|
IN UINT16 MinSize,
|
|
IN UINT16 MaxSize
|
|
)
|
|
{
|
|
EFI_IFR_PASSWORD Password;
|
|
UINT8 *OpCodePtr;
|
|
|
|
ZeroMem (&Password, sizeof (Password));
|
|
Password.Header.OpCode = EFI_IFR_PASSWORD_OP;
|
|
Password.Header.Length = sizeof (Password);
|
|
Password.Question.QuestionId = QuestionId;
|
|
Password.Question.VarStoreId = VarStoreId;
|
|
Password.Question.VarStoreInfo.VarOffset = VarOffset;
|
|
Password.Question.Header.Prompt = Prompt;
|
|
Password.Question.Header.Help = Help;
|
|
Password.Question.Flags = QuestionFlags;
|
|
Password.MinSize = MinSize;
|
|
Password.MaxSize = MaxSize;
|
|
|
|
OpCodePtr = HiiCreateRawOpCodes (OpCodeHandle, (UINT8 *) &Password, sizeof (Password));
|
|
if (OpCodePtr == NULL || TextTwo == 0) {
|
|
return OpCodePtr;
|
|
}
|
|
|
|
HiiCreateGuidTextOpCode (OpCodeHandle, &((EFI_IFR_PASSWORD *) OpCodePtr)->Header, TextTwo);
|
|
|
|
return OpCodePtr;
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_ONE_OF_OPTION_OP opcode with ext op.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
If Type is invalid, then ASSERT().
|
|
If Flags is invalid, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] StringId StringId for the option
|
|
@param[in] Flags Flags for the option
|
|
@param[in] Type Type for the option
|
|
@param[in] Value Value for the option
|
|
@param[in] ExtendedOpCodeHandle Handle for a buffer of Extended opcodes.
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
EFIAPI
|
|
HiiCreateOneOfOptionOpCodeWithExtOp (
|
|
IN VOID *OpCodeHandle,
|
|
IN UINT16 StringId,
|
|
IN UINT8 Flags,
|
|
IN UINT8 Type,
|
|
IN UINT64 Value,
|
|
IN VOID *ExtendedOpCodeHandle
|
|
)
|
|
{
|
|
EFI_IFR_ONE_OF_OPTION OpCode;
|
|
UINTN Position;
|
|
|
|
ASSERT (ExtendedOpCodeHandle != NULL);
|
|
if (ExtendedOpCodeHandle == NULL) {
|
|
return NULL;
|
|
}
|
|
ASSERT (Type < EFI_IFR_TYPE_OTHER);
|
|
|
|
ZeroMem (&OpCode, sizeof (OpCode));
|
|
OpCode.Option = StringId;
|
|
OpCode.Flags = (UINT8) (Flags & (EFI_IFR_OPTION_DEFAULT));
|
|
OpCode.Type = Type;
|
|
CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]);
|
|
|
|
Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
|
|
InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OPTION_OP, sizeof (OpCode), 0, 1);
|
|
|
|
InternalHiiAppendOpCodes (OpCodeHandle, ExtendedOpCodeHandle);
|
|
HiiCreateEndOpCode (OpCodeHandle);
|
|
return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_IMAGE_OP opcode.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] ImageId Image ID for Image
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
EFIAPI
|
|
HiiCreateImageOpCode (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_IMAGE_ID ImageId
|
|
)
|
|
{
|
|
EFI_IFR_IMAGE OpCode;
|
|
|
|
ZeroMem (&OpCode, sizeof (OpCode));
|
|
OpCode.Id = ImageId;
|
|
|
|
return InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_IMAGE_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_TRUE opcode.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateTrueOpCode (
|
|
IN VOID *OpCodeHandle
|
|
)
|
|
{
|
|
EFI_IFR_TRUE OpCode;
|
|
|
|
return InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_TRUE_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_FALSE opcode.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateFalseOpCode (
|
|
IN VOID *OpCodeHandle
|
|
)
|
|
{
|
|
EFI_IFR_FALSE OpCode;
|
|
|
|
return InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_FALSE_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_AND opcode.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateAndOpCode (
|
|
IN VOID *OpCodeHandle
|
|
)
|
|
{
|
|
EFI_IFR_AND OpCode;
|
|
|
|
return InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_AND_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_OR opcode.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateOrOpCode (
|
|
IN VOID *OpCodeHandle
|
|
)
|
|
{
|
|
EFI_IFR_OR OpCode;
|
|
|
|
return InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_OR_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_NOT opcode.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateNotOpCode (
|
|
IN VOID *OpCodeHandle
|
|
)
|
|
{
|
|
EFI_IFR_NOT OpCode;
|
|
|
|
return InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_NOT_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_EQ_ID_VAL opcode.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] QuestionId Question ID
|
|
@param[in] Value Value for the equal
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateIdEqualOpCodeEx (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN UINT16 Value
|
|
)
|
|
{
|
|
EFI_IFR_EQ_ID_VAL OpCode;
|
|
|
|
OpCode.QuestionId = QuestionId;
|
|
OpCode.Value = Value;
|
|
|
|
return InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_EQ_ID_VAL_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_EQ_ID_VAL_LIST opcode.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] QuestionId Question ID
|
|
@param[in] ListLength Numer of value
|
|
@param[in] ValueList List of value
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateIdEqualListOpCodeEx (
|
|
IN VOID *OpCodeHandle,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN UINT8 ListLength,
|
|
IN UINT16 *ValueList
|
|
)
|
|
{
|
|
EFI_IFR_EQ_ID_VAL_LIST *OpCode;
|
|
UINTN OpCodeSize;
|
|
UINT8 *OpCodePtr;
|
|
UINT8 Index;
|
|
|
|
OpCodeSize = sizeof (EFI_IFR_EQ_ID_VAL_LIST) + sizeof (UINT16) * (ListLength - 1);
|
|
OpCode = AllocatePool (OpCodeSize);
|
|
if (OpCode == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
OpCode->QuestionId = QuestionId;
|
|
OpCode->ListLength = ListLength;
|
|
for (Index = 0; Index < ListLength; Index++) {
|
|
OpCode->ValueList[Index] = ValueList[Index];
|
|
}
|
|
|
|
OpCodePtr = InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
OpCode,
|
|
EFI_IFR_EQ_ID_VAL_LIST_OP,
|
|
OpCodeSize,
|
|
0,
|
|
0
|
|
);
|
|
FreePool (OpCode);
|
|
|
|
return OpCodePtr;
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_SUPPRESS_IF opcode with scope.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] Scope Scope
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateSuppressIfOpCodeEx (
|
|
IN VOID *OpCodeHandle,
|
|
IN UINT8 Scope
|
|
)
|
|
{
|
|
EFI_IFR_SUPPRESS_IF OpCode;
|
|
|
|
return InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_SUPPRESS_IF_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
Scope
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create EFI_IFR_GRAY_OUT_IF opcode with scope.
|
|
|
|
If OpCodeHandle is NULL, then ASSERT().
|
|
|
|
@param[in] OpCodeHandle Handle to the buffer of opcodes.
|
|
@param[in] Scope Scope
|
|
|
|
@retval NULL There is not enough space left in Buffer to add the opcode.
|
|
@retval Other A pointer to the created opcode.
|
|
**/
|
|
UINT8 *
|
|
HiiCreateGrayOutIfOpCodeEx (
|
|
IN VOID *OpCodeHandle,
|
|
IN UINT8 Scope
|
|
)
|
|
{
|
|
EFI_IFR_GRAY_OUT_IF OpCode;
|
|
|
|
return InternalHiiCreateOpCodeExtended (
|
|
OpCodeHandle,
|
|
&OpCode,
|
|
EFI_IFR_GRAY_OUT_IF_OP,
|
|
sizeof (OpCode),
|
|
0,
|
|
Scope
|
|
);
|
|
}
|
|
|
|
/**
|
|
Get formset information (title string ID, tilte help string ID and root form ID) from Hii database
|
|
|
|
@param[in] HiiHandle Hii handle
|
|
@param[in, out] FormSetGuid Pointer to formset GUID
|
|
@param[out] FormSetTitleStrId Pointer to formset title string ID
|
|
@param[out] FormSetHelpStrId Pointer to formset help string ID
|
|
@param[out] RootFormId Pointer to root Form ID
|
|
|
|
@retval EFI_SUCCESS Successfully get formset information
|
|
@retval EFI_INVALID_PARAMETER Input pointer is NULL or form ID is zero
|
|
@retval EFI_OUT_OF_RESOURCES Fail to allocate pool
|
|
@retval EFI_NOT_FOUND Fail to export package list or get matched formset
|
|
@retval Other Fail to locate Hii database protocol or export package list
|
|
**/
|
|
EFI_STATUS
|
|
GetFormSetInfo (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN OUT EFI_GUID *FormSetGuid,
|
|
OUT EFI_STRING_ID *FormSetTitleStrId,
|
|
OUT EFI_STRING_ID *FormSetHelpStrId,
|
|
OUT EFI_FORM_ID *RootFormId
|
|
)
|
|
{
|
|
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
|
|
EFI_STATUS Status;
|
|
UINTN BufferSize;
|
|
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
|
|
UINT8 *Package;
|
|
UINT8 *OpCodeData;
|
|
UINT32 Offset;
|
|
UINT32 Offset2;
|
|
UINT32 PackageListLength;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
BOOLEAN Found;
|
|
EFI_IFR_FORM_SET *FormSet;
|
|
EFI_GUID ZeroGuid;
|
|
|
|
|
|
if (HiiHandle == NULL || FormSetGuid == NULL || FormSetTitleStrId == NULL || FormSetHelpStrId == NULL || RootFormId == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Get HII PackageList
|
|
//
|
|
BufferSize = 0;
|
|
HiiPackageList = NULL;
|
|
Status = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
HiiPackageList = AllocatePool (BufferSize);
|
|
if (HiiPackageList == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Status = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Get Form package from this HII package List
|
|
//
|
|
Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
|
|
Offset2 = 0;
|
|
PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);
|
|
if (PackageListLength > BufferSize) {
|
|
PackageListLength = (UINT32)BufferSize;
|
|
}
|
|
|
|
ZeroMem (&ZeroGuid, sizeof(EFI_GUID));
|
|
FormSet = NULL;
|
|
Found = FALSE;
|
|
while (Offset < PackageListLength) {
|
|
Package = ((UINT8 *) HiiPackageList) + Offset;
|
|
CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
|
|
if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
|
|
//
|
|
// Search FormSet Opcode in this Form Package
|
|
//
|
|
Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
|
|
while (Offset2 < PackageHeader.Length) {
|
|
OpCodeData = Package + Offset2;
|
|
|
|
if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
|
|
FormSet = (EFI_IFR_FORM_SET *) OpCodeData;
|
|
|
|
if (CompareGuid (FormSetGuid, &ZeroGuid) || CompareGuid (FormSetGuid, (EFI_GUID *)(VOID *)&FormSet->Guid)) {
|
|
CopyGuid (FormSetGuid, (EFI_GUID *)(VOID *)&FormSet->Guid);
|
|
*FormSetTitleStrId = FormSet->FormSetTitle;
|
|
*FormSetHelpStrId = FormSet->Help;
|
|
} else {
|
|
FormSet = NULL;
|
|
}
|
|
}
|
|
|
|
if (FormSet != NULL && (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_OP)) {
|
|
*RootFormId = ((EFI_IFR_FORM *) OpCodeData)->FormId;
|
|
Found = TRUE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Go to next opcode
|
|
//
|
|
Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
|
|
if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < sizeof (EFI_IFR_OP_HEADER)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Found) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Go to next package
|
|
//
|
|
Offset += PackageHeader.Length;
|
|
if (PackageHeader.Length == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
FreePool (HiiPackageList);
|
|
|
|
return Found ? EFI_SUCCESS : EFI_NOT_FOUND;
|
|
}
|
|
|
|
/**
|
|
Get HII package list by specified HII handle.
|
|
|
|
@param[in] HiiHandle Pointer to specified HII handle.
|
|
|
|
@return A pointer to the HII package list or NULL if not found or fail to allocate pool.
|
|
**/
|
|
EFI_HII_PACKAGE_LIST_HEADER *
|
|
HiiGetHiiPackageList (
|
|
IN EFI_HII_HANDLE HiiHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN HiiPackageListSize;
|
|
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
|
|
|
|
if (HiiHandle == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
HiiPackageList = NULL;
|
|
HiiPackageListSize = 0;
|
|
Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &HiiPackageListSize, HiiPackageList);
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
return NULL;
|
|
}
|
|
HiiPackageList = AllocateZeroPool (HiiPackageListSize);
|
|
if (HiiPackageList == NULL) {
|
|
return NULL;
|
|
}
|
|
Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &HiiPackageListSize, HiiPackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (HiiPackageList);
|
|
return NULL;
|
|
}
|
|
|
|
return HiiPackageList;
|
|
}
|
|
|
|
/**
|
|
Get HII handle by specified formset GUID.
|
|
|
|
@param[in] FormSetGuid Pointer to specified formset GUID.
|
|
|
|
@return The HII handle or NULL if not found or invalid input parameter.
|
|
**/
|
|
EFI_HII_HANDLE
|
|
EFIAPI
|
|
HiiGetHiiHandleByFormSetGuid (
|
|
IN EFI_GUID *FormSetGuid
|
|
)
|
|
{
|
|
EFI_HII_HANDLE *HiiHandles;
|
|
EFI_HII_HANDLE HiiHandle;
|
|
UINTN Index;
|
|
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
|
|
UINT8 *Package;
|
|
EFI_HII_PACKAGE_HEADER *PackageHeader;
|
|
UINT32 Offset;
|
|
UINT32 PackageListLength;
|
|
EFI_GUID PackageFormsetGuid;
|
|
EFI_STATUS Status;
|
|
|
|
if (FormSetGuid == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
HiiHandles = HiiGetHiiHandlesByPackageType (EFI_HII_PACKAGE_FORMS);
|
|
if (HiiHandles == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
HiiHandle = NULL;
|
|
for (Index = 0; HiiHandles[Index] != NULL; Index++) {
|
|
HiiPackageList = HiiGetHiiPackageList (HiiHandles[Index]);
|
|
if (HiiPackageList == NULL) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// In HII package list, find the Form package which support specific form set GUID.
|
|
//
|
|
Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
|
|
PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);
|
|
while (Offset < PackageListLength) {
|
|
Package = (UINT8 *) HiiPackageList + Offset;
|
|
PackageHeader = (EFI_HII_PACKAGE_HEADER *) Package;
|
|
Offset += PackageHeader->Length;
|
|
|
|
if (PackageHeader->Type == EFI_HII_PACKAGE_FORMS) {
|
|
Status = GetFormsetGuidByPackage (Package, &PackageFormsetGuid);
|
|
if (!EFI_ERROR (Status) && CompareGuid (&PackageFormsetGuid, FormSetGuid)) {
|
|
HiiHandle = HiiHandles[Index];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
FreePool (HiiPackageList);
|
|
if (HiiHandle != NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
FreePool (HiiHandles);
|
|
return HiiHandle;
|
|
}
|
|
|
|
/**
|
|
Get current keyboard layout from HII database.
|
|
|
|
@return Pointer to HII Keyboard Layout. NULL means failure occurred while trying to get keyboard layout.
|
|
**/
|
|
EFI_HII_KEYBOARD_LAYOUT *
|
|
EFIAPI
|
|
HiiGetCurrentKeyboardLayout (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
|
|
EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
|
|
UINT16 Length;
|
|
|
|
//
|
|
// Locate HII Database Protocol
|
|
//
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiHiiDatabaseProtocolGuid,
|
|
NULL,
|
|
(VOID **) &HiiDatabase
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Get current keyboard layout from HII database
|
|
//
|
|
Length = 0;
|
|
KeyboardLayout = NULL;
|
|
Status = HiiDatabase->GetKeyboardLayout (
|
|
HiiDatabase,
|
|
NULL,
|
|
&Length,
|
|
KeyboardLayout
|
|
);
|
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
|
KeyboardLayout = AllocatePool (Length);
|
|
ASSERT (KeyboardLayout != NULL);
|
|
|
|
Status = HiiDatabase->GetKeyboardLayout (
|
|
HiiDatabase,
|
|
NULL,
|
|
&Length,
|
|
KeyboardLayout
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (KeyboardLayout);
|
|
KeyboardLayout = NULL;
|
|
}
|
|
}
|
|
|
|
return KeyboardLayout;
|
|
}
|
|
|
|
/**
|
|
Copy image from the image ID of source Hii handle to the image ID of destination Hii handle.
|
|
If the image ID of destination Hii handle is zero, it will create a new string ID.
|
|
|
|
@param[in] SrcHiiHandle Source Hii handle
|
|
@param[in] SrcImageId Image ID of source Hii handle
|
|
@param[in] DstHiiHandle Destination Hii handle
|
|
@param[in] DstImageId Pointer to image ID of destination Hii handle
|
|
|
|
@retval EFI_SUCCESS Successfully copy image
|
|
@retval EFI_INVALID_PARAMETER Input pointer is NULL or source image ID is zero
|
|
@retval Other Fail to get source image or fail to set image.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiCopyImageByImageId (
|
|
IN EFI_HII_HANDLE SrcHiiHandle,
|
|
IN EFI_IMAGE_ID SrcImageId,
|
|
IN EFI_HII_HANDLE DstHiiHandle,
|
|
IN OUT EFI_IMAGE_ID *DstImageId
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_IMAGE_INPUT SrcImage;
|
|
|
|
if (SrcHiiHandle == NULL || SrcImageId == 0 || DstHiiHandle == NULL || DstImageId == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
ZeroMem (&SrcImage, sizeof (EFI_IMAGE_INPUT));
|
|
Status = gHiiImage->GetImage (
|
|
gHiiImage,
|
|
SrcHiiHandle,
|
|
SrcImageId,
|
|
&SrcImage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (*DstImageId == 0) {
|
|
Status = gHiiImage->NewImage (gHiiImage, DstHiiHandle, DstImageId, &SrcImage);
|
|
} else {
|
|
Status = gHiiImage->SetImage (gHiiImage, DstHiiHandle, *DstImageId, &SrcImage);
|
|
|
|
}
|
|
|
|
if (SrcImage.Bitmap != NULL) {
|
|
FreePool (SrcImage.Bitmap);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Copy string from the string ID of source Hii handle to the string ID of destination Hii handle.
|
|
If the string ID of destination Hii handle, it will create a new string ID.
|
|
|
|
@param[in] SrcHiiHandle Source Hii handle
|
|
@param[in] SrcStringId String ID of source Hii handle
|
|
@param[in] DstHiiHandle Destination Hii handle
|
|
@param[in] DstStringId Pointer to string ID of destination Hii handle
|
|
|
|
@retval EFI_SUCCESS Successfully copy string
|
|
@retval EFI_INVALID_PARAMETER Input pointer is NULL or source string ID is zero
|
|
@retval EFI_NOT_FOUND Get PlatformLangCodes variable fail
|
|
@retval EFI_OUT_OF_RESOURCES Allocate pool fail
|
|
@retval Other Fail to get variable
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiCopyStringByStringId (
|
|
IN EFI_HII_HANDLE SrcHiiHandle,
|
|
IN EFI_STRING_ID SrcStringId,
|
|
IN EFI_HII_HANDLE DstHiiHandle,
|
|
IN OUT EFI_STRING_ID *DstStringId
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN PlatformLangCodesSize;
|
|
CHAR8 *PlatformLangCodes;
|
|
CHAR8 *PlatformLang;
|
|
UINTN Index;
|
|
CHAR16 *SrcString;
|
|
EFI_STRING_ID NewStringId;
|
|
|
|
if (SrcHiiHandle == NULL || SrcStringId == 0 || DstHiiHandle == NULL || DstStringId == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PlatformLangCodes = NULL;
|
|
PlatformLangCodesSize = 0;
|
|
Status = gRT->GetVariable (L"PlatformLangCodes", &gEfiGlobalVariableGuid, NULL, &PlatformLangCodesSize, (VOID *) PlatformLangCodes);
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
PlatformLangCodes = AllocateZeroPool (PlatformLangCodesSize);
|
|
if (PlatformLangCodes == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = gRT->GetVariable (L"PlatformLangCodes", &gEfiGlobalVariableGuid, NULL, &PlatformLangCodesSize, (VOID *) PlatformLangCodes);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (PlatformLangCodes);
|
|
return Status;
|
|
}
|
|
|
|
Index = 0;
|
|
while (Index < PlatformLangCodesSize) {
|
|
PlatformLang = &PlatformLangCodes[Index];
|
|
|
|
while (PlatformLangCodes[Index] != ';' && PlatformLangCodes[Index] != 0) {
|
|
Index++;
|
|
}
|
|
PlatformLangCodes[Index++] = 0;
|
|
|
|
SrcString = HiiGetString (SrcHiiHandle, SrcStringId, PlatformLang);
|
|
if (SrcString != NULL) {
|
|
NewStringId = HiiSetString (DstHiiHandle, *DstStringId, SrcString, PlatformLang);
|
|
if (NewStringId != 0) {
|
|
*DstStringId = NewStringId;
|
|
}
|
|
FreePool (SrcString);
|
|
}
|
|
}
|
|
|
|
FreePool (PlatformLangCodes);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Insert EFI_IFR_REF3_OP opcode in target formset
|
|
|
|
@param[in] HiiHandle Hii handle
|
|
@param[in] FormSetGuid Formset GUID
|
|
@param[in] FormId Form ID
|
|
@param[in] LabelNumber Label number
|
|
@param[in] RefHiiHandle Hii handle of EFI_IFR_REF3_OP opcode
|
|
@param[in] FormSetGuid Formset GUID of EFI_IFR_REF3_OP opcode
|
|
@param[in] FormId Form ID of EFI_IFR_REF3_OP opcode
|
|
@param[in] RefQuestionId Question ID of EFI_IFR_REF3_OP opcode
|
|
|
|
@retval EFI_SUCCESS Successfully Insert opcodes
|
|
@retval EFI_INVALID_PARAMETER Input pointer is NULL or form ID is zero
|
|
@retval EFI_OUT_OF_RESOURCES Fail to create opcode
|
|
@retval Other Fail to update form data into Hii database or get formset info
|
|
**/
|
|
EFI_STATUS
|
|
HiiInsertRef3Opcode (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_GUID *FormSetGuid,
|
|
IN UINT16 FormId,
|
|
IN UINT16 LabelNumber,
|
|
IN EFI_HII_HANDLE RefHiiHandle,
|
|
IN EFI_GUID *RefFormSetGuid,
|
|
IN EFI_FORM_ID RefFormId,
|
|
IN EFI_QUESTION_ID RefQuestionId
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_GUID GoToFormSetGuid;
|
|
EFI_STRING_ID GoToFormSetTitleStrId;
|
|
EFI_STRING_ID GoToFormSetHelpStrId;
|
|
EFI_FORM_ID GoToFormId;
|
|
EFI_STRING_ID NewTitleStrId;
|
|
EFI_STRING_ID NewHelpStrId;
|
|
VOID *StartOpCodeHandle;
|
|
EFI_IFR_GUID_LABEL *StartLabel;
|
|
|
|
if (HiiHandle == NULL || RefHiiHandle == NULL || RefQuestionId == 0) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Prepare all elements for creating EFI_IFR_REF3_OP opcode
|
|
//
|
|
if (RefFormSetGuid == NULL) {
|
|
ZeroMem (&GoToFormSetGuid, sizeof(EFI_GUID));
|
|
} else {
|
|
CopyMem (&GoToFormSetGuid, RefFormSetGuid, sizeof(EFI_GUID));
|
|
}
|
|
|
|
Status = GetFormSetInfo (
|
|
RefHiiHandle,
|
|
&GoToFormSetGuid,
|
|
&GoToFormSetTitleStrId,
|
|
&GoToFormSetHelpStrId,
|
|
&GoToFormId
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (RefFormId != 0) {
|
|
GoToFormId = RefFormId;
|
|
}
|
|
|
|
NewTitleStrId = 0;
|
|
NewHelpStrId = 0;
|
|
HiiCopyStringByStringId (RefHiiHandle, GoToFormSetTitleStrId, HiiHandle, &NewTitleStrId);
|
|
HiiCopyStringByStringId (RefHiiHandle, GoToFormSetHelpStrId , HiiHandle, &NewHelpStrId);
|
|
|
|
//
|
|
// Insert EFI_IFR_REF3_OP opcode in target formset
|
|
//
|
|
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
if (StartOpCodeHandle == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
if (StartLabel == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
StartLabel->Number = LabelNumber;
|
|
|
|
HiiCreateGotoExOpCode (
|
|
StartOpCodeHandle,
|
|
GoToFormId,
|
|
NewTitleStrId,
|
|
NewHelpStrId,
|
|
0,
|
|
RefQuestionId,
|
|
0,
|
|
&GoToFormSetGuid,
|
|
0
|
|
);
|
|
|
|
Status = HiiUpdateForm (
|
|
HiiHandle,
|
|
FormSetGuid,
|
|
FormId,
|
|
StartOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
if (StartOpCodeHandle != NULL) {
|
|
HiiFreeOpCodeHandle (StartOpCodeHandle);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Clean all created opcodes between start and end labels.
|
|
|
|
@param[in] HiiHandle Hii handle
|
|
@param[in] FormSetGuid Formset GUID
|
|
@param[in] FormId Form ID
|
|
@param[in] StartLabelNumber Start label number
|
|
@param[in] EndLabelNumber End label number
|
|
|
|
@retval EFI_SUCCESS Successfully clean opcodes
|
|
@retval EFI_INVALID_PARAMETER Input pointer is NULL or form ID is zero
|
|
@retval EFI_OUT_OF_RESOURCES Fail to create opcode
|
|
@retval Other Fail to update form data into Hii database
|
|
**/
|
|
EFI_STATUS
|
|
HiiCleanLabelOpcode (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_GUID *FormSetGuid,
|
|
IN UINT16 FormId,
|
|
IN UINT16 StartLabelNumber,
|
|
IN UINT16 EndLabelNumber
|
|
)
|
|
{
|
|
VOID *StartOpCodeHandle;
|
|
VOID *EndOpCodeHandle;
|
|
EFI_IFR_GUID_LABEL *StartLabel;
|
|
EFI_IFR_GUID_LABEL *EndLabel;
|
|
EFI_STATUS Status;
|
|
|
|
if (HiiHandle == NULL || FormSetGuid == NULL || FormId == 0) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
if (StartOpCodeHandle == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
EndOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
if (EndOpCodeHandle == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
if (StartLabel == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
StartLabel->Number = StartLabelNumber;
|
|
|
|
EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
if (EndLabel == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
EndLabel->Number = EndLabelNumber;
|
|
|
|
Status = HiiUpdateForm (
|
|
HiiHandle,
|
|
FormSetGuid,
|
|
FormId,
|
|
StartOpCodeHandle,
|
|
EndOpCodeHandle
|
|
);
|
|
|
|
if (StartOpCodeHandle != NULL) {
|
|
HiiFreeOpCodeHandle (StartOpCodeHandle);
|
|
}
|
|
if (EndOpCodeHandle != NULL) {
|
|
HiiFreeOpCodeHandle (EndOpCodeHandle);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
HiiGetStringIdByName (
|
|
IN PCD_STRING_NAME_TO_ID *StringNameToIdInfo,
|
|
IN CHAR8 *StringName,
|
|
OUT EFI_STRING_ID *StringId
|
|
)
|
|
{
|
|
if (StringNameToIdInfo == NULL || StringName == NULL || StringId == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
while (*StringNameToIdInfo->StringName != CHAR_NULL) {
|
|
if (AsciiStrCmp (StringNameToIdInfo->StringName, StringName) == 0) {
|
|
*StringId = StringNameToIdInfo->StringId;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
StringNameToIdInfo++;
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|