1) Add in support for Framework VFR file which specify all VAR Store correctly. This patch enable the ThunkExtractConfig and ThunkRounteConfig to handle more than one VAR Storage based on the VARSTORE ID specified.

2) Remove the unnecessary data structure defined for IFR Parser.
  1) All data structure definition that have nothing to do with IFR Default value scanning (
     required to implement Framework HII's GetDefaultImage ()) is removed.
  2) Ignore the IFR opcode which is invalid for Form Package
     generated using Framework VFR file.
3) Remove unnecessary files.
4) Add in Doxygen function header for all functions.



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6440 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qwang12 2008-11-10 12:40:07 +00:00
parent 4f1afaacb2
commit a9d853203d
17 changed files with 1242 additions and 3387 deletions

View File

@ -1,8 +1,7 @@
/**@file
This file contains functions related to Config Access Protocols installed by
by HII Thunk Modules which is used to thunk UEFI Config Access Callback to
Framework HII Callback.
This file implements functions related to Config Access Protocols installed by
by HII Thunk Modules. These Config access Protocols are used to thunk UEFI Config
Access Callback to Framework HII Callback and EFI Variable Set/Get operations.
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
@ -16,8 +15,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiDatabase.h"
#include "UefiIfrParser.h"
BOOLEAN mHiiPackageListUpdated;
BOOLEAN mHiiPackageListUpdated = FALSE;
CONFIG_ACCESS_PRIVATE gConfigAccessPrivateTempate = {
CONFIG_ACCESS_PRIVATE_SIGNATURE,
@ -27,154 +27,157 @@ CONFIG_ACCESS_PRIVATE gConfigAccessPrivateTempate = {
ThunkCallback
}, //ConfigAccessProtocol
NULL, //FormCallbackProtocol
{NULL, NULL}, //ConfigAccessStorageListHead
NULL
};
/**
Find and return the pointer to Package Header of the Form package
in the Framework Package List. The Framework Package List is created
by a module calling the Framework HII interface.
The Framwork Package List contains package data
generated by Intel's UEFI VFR Compiler and String gather tool. The data format
of the package data is defined by TIANO_AUTOGEN_PACKAGES_HEADER.
If the package list contains other type of packages such as KEYBOARD_LAYOUT,
FONTS and IMAGES, the ASSERT. This is to make sure the caller is a
Framework Module which does not include packages introduced by UEFI Specification
or packages that is not supported by Thunk layer.
Get the first EFI_IFR_VARSTORE from the FormSet.
@param Packages The Framework Package List
@param FormSet The Form Set.
@retval EFI_HII_PACKAGE_HEADER* Return the Package Header of Form Package.
@retval NULL If no Form Package is found.
@retval FORMSET_STORAGE * Return the first EFI_IFR_VARSTORE.
@retval NULL If the Form Set does not have EFI_IFR_VARSTORE.
**/
EFI_HII_PACKAGE_HEADER *
GetIfrFormSet (
IN CONST EFI_HII_PACKAGES *Packages
)
FORMSET_STORAGE *
GetFirstStorageOfFormSet (
IN CONST FORM_BROWSER_FORMSET * FormSet
)
{
TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;
EFI_HII_PACKAGE_HEADER *IfrPackage;
UINTN Index;
LIST_ENTRY *StorageList;
FORMSET_STORAGE *Storage;
ASSERT (Packages != NULL);
StorageList = GetFirstNode (&FormSet->StorageListHead);
IfrPackage = NULL;
TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));
for (Index = 0; Index < Packages->NumberOfPackages; Index++) {
//
// BugBug: The current UEFI HII build tool generate a binary in the format defined in:
// TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in
// this binary is with same package type. So the returned IfrPackNum and StringPackNum
// may not be the exact number of valid package number in the binary generated
// by HII Build tool.
//
switch (TianoAutogenPackageHdrArray[Index]->PackageHeader.Type) {
case EFI_HII_PACKAGE_FORMS:
return &TianoAutogenPackageHdrArray[Index]->PackageHeader;
break;
case EFI_HII_PACKAGE_STRINGS:
case EFI_HII_PACKAGE_SIMPLE_FONTS:
break;
//
// The following fonts are invalid for a module that using Framework to UEFI thunk layer.
//
case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
case EFI_HII_PACKAGE_FONTS:
case EFI_HII_PACKAGE_IMAGES:
default:
ASSERT (FALSE);
break;
}
if (!IsNull (&FormSet->StorageListHead, StorageList)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
return Storage;
}
return (EFI_HII_PACKAGE_HEADER *) NULL;
return NULL;
}
/**
This function scan EFI_IFR_VARSTORE_OP in the Form Package.
It create entries for these VARSTORE found and append the entry
to a Link List.
If FormSetPackage is not EFI_HII_PACKAGE_FORM, then ASSERT.
If there is no linear buffer storage in this formset, then ASSERT.
@param FormSetPackage The Form Package header.
@param BufferStorageListHead The link list for the VARSTORE found in the form package.
Get the EFI_IFR_VARSTORE where the Question's value is stored.
@param FormSet The Form Set.
@retval EFI_SUCCESS The function scan the form set and find one or more VARSTOREs.
@retval EFI_OUT_OF_RESOURCES There is not enough memory to complete the function.
@retval FORMSET_STORAGE * The EFI_IFR_VARSTORE where the Question's value is stored.
@retval NULL If the Form Set does not have EFI_IFR_VARSTORE.
**/
EFI_STATUS
GetBufferStorage (
IN CONST EFI_HII_PACKAGE_HEADER *FormSetPackage,
OUT LIST_ENTRY *BufferStorageListHead
FORMSET_STORAGE *
GetStorageFromQuestionId (
IN CONST FORM_BROWSER_FORMSET * FormSet,
IN EFI_QUESTION_ID QuestionId
)
{
UINTN OpCodeOffset;
UINTN OpCodeLength;
UINT8 *OpCodeData;
UINT8 Operand;
EFI_IFR_VARSTORE *VarStoreOpCode;
BUFFER_STORAGE_ENTRY *BufferStorage;
LIST_ENTRY *FormList;
LIST_ENTRY *StatementList;
FORM_BROWSER_FORM *Form;
FORM_BROWSER_STATEMENT *Statement;
ASSERT (FormSetPackage->Type == EFI_HII_PACKAGE_FORMS);
FormList = GetFirstNode (&FormSet->FormListHead);
OpCodeOffset = sizeof (EFI_HII_PACKAGE_HEADER);
//
// Scan all opcode for the FormSet Package for
// EFI_IFR_VARSTORE_OP opcode.
//
while (OpCodeOffset < FormSetPackage->Length) {
OpCodeData = (UINT8 *) FormSetPackage + OpCodeOffset;
while (!IsNull (&FormSet->FormListHead, FormList)) {
Form = FORM_BROWSER_FORM_FROM_LINK (FormList);
OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
OpCodeOffset += OpCodeLength;
Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
StatementList = GetFirstNode (&Form->StatementListHead);
if (Operand == EFI_IFR_VARSTORE_OP) {
VarStoreOpCode = (EFI_IFR_VARSTORE *)OpCodeData;
BufferStorage = AllocateZeroPool (sizeof (*BufferStorage));
if (BufferStorage == NULL) {
return EFI_OUT_OF_RESOURCES;
while (!IsNull (&Form->StatementListHead, StatementList)) {
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);
if ((QuestionId == Statement->QuestionId) && (Statement->Storage != NULL)) {
//
// UEFI Question ID is unique in a FormSet.
//
ASSERT (Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER);
return Statement->Storage;
}
//
// Record the attributes: GUID, Name, VarStoreId and Size.
//
CopyMem (&BufferStorage->Guid, &VarStoreOpCode->Guid, sizeof (EFI_GUID));
BufferStorage->Name = AllocateZeroPool (AsciiStrSize (VarStoreOpCode->Name) * 2);
AsciiStrToUnicodeStr (VarStoreOpCode->Name, BufferStorage->Name);
BufferStorage->VarStoreId = VarStoreOpCode->VarStoreId;
BufferStorage->Size = VarStoreOpCode->Size;
BufferStorage->Signature = BUFFER_STORAGE_ENTRY_SIGNATURE;
InsertTailList (BufferStorageListHead, &BufferStorage->Link);
StatementList = GetNextNode (&Form->StatementListHead, StatementList);
}
}
return EFI_SUCCESS;
FormList = GetNextNode (&FormSet->FormListHead, FormList);
}
return NULL;
}
/**
Get the EFI_IFR_VARSTORE based the ID.
@param FormSet The Form Set.
@retval FORMSET_STORAGE * The EFI_IFR_VARSTORE with the ID.
@retval NULL If the Form Set does not have EFI_IFR_VARSTORE with such ID.
**/
FORMSET_STORAGE *
GetStorageFromVarStoreId (
IN CONST FORM_BROWSER_FORMSET * FormSet,
IN EFI_VARSTORE_ID VarStoreId
)
{
LIST_ENTRY *StorageList;
FORMSET_STORAGE *Storage;
StorageList = GetFirstNode (&FormSet->StorageListHead);
while (!IsNull (&FormSet->StorageListHead, StorageList)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
if (VarStoreId == Storage->VarStoreId) {
return Storage;
}
StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);
}
return NULL;
}
/**
Get the EFI_IFR_VARSTORE based the <ConfigHdr> string in a <ConfigRequest>
or a <ConfigResp> string.
@param FormSet The Form Set.
@param ConfigString The Configuration String which is defined by UEFI HII.
@retval FORMSET_STORAGE * The EFI_IFR_VARSTORE where the Question's value is stored.
@retval NULL If the Form Set does not have EFI_IFR_VARSTORE with such ID.
**/
FORMSET_STORAGE *
GetStorageFromConfigString (
IN CONST FORM_BROWSER_FORMSET *FormSet,
IN CONST EFI_STRING ConfigString
)
{
LIST_ENTRY *StorageList;
FORMSET_STORAGE *Storage;
StorageList = GetFirstNode (&FormSet->StorageListHead);
while (!IsNull (&FormSet->StorageListHead, StorageList)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
if (IsConfigHdrMatch (ConfigString, &Storage->Guid, Storage->Name)) {
return Storage;
}
StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);
}
return NULL;
}
/**
This function installs a EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered
by a module using Framework HII Protocol Interfaces.
UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so
that Setup Utility can load the Buffer Storage using this protocol.
UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so
that Setup Utility can load the Buffer Storage using this protocol.
@param Packages The framework package list.
@param ThunkContext The Thunk Layer Handle Mapping Database Entry.
@param Packages The Package List.
@param ThunkContext The Thunk Context.
@retval EFI_SUCCESS The Config Access Protocol is installed successfully.
@retval EFI_OUT_RESOURCE There is not enough memory.
@retval EFI_SUCCESS The Config Access Protocol is installed successfully.
@retval EFI_OUT_RESOURCE There is not enough memory.
**/
EFI_STATUS
@ -183,73 +186,42 @@ InstallDefaultConfigAccessProtocol (
IN OUT HII_THUNK_CONTEXT *ThunkContext
)
{
EFI_HII_PACKAGE_HEADER *FormSetPackage;
EFI_STATUS Status;
CONFIG_ACCESS_PRIVATE *ConfigAccessInstance;
ASSERT (ThunkContext->IfrPackageCount != 0);
Status = HiiLibCreateHiiDriverHandle (&ThunkContext->UefiHiiDriverHandle);
ASSERT_EFI_ERROR (Status);
ConfigAccessInstance = AllocateCopyPool (
sizeof (CONFIG_ACCESS_PRIVATE),
&gConfigAccessPrivateTempate
);
ASSERT (ConfigAccessInstance != NULL);
InitializeListHead (&ConfigAccessInstance->BufferStorageListHead);
//
// We assume there is only one formset package in each Forms Package
//
FormSetPackage = GetIfrFormSet (Packages);
ASSERT (FormSetPackage != NULL);
Status = GetBufferStorage (FormSetPackage, &ConfigAccessInstance->BufferStorageListHead);
if (EFI_ERROR (Status)) {
FreePool (ConfigAccessInstance);
ASSERT (FALSE);
return Status;
}
Status = gBS->InstallMultipleProtocolInterfaces (
&ThunkContext->UefiHiiDriverHandle,
&gEfiHiiConfigAccessProtocolGuid,
&ConfigAccessInstance->ConfigAccessProtocol,
NULL
);
//
//BUGBUG: Remove when done.
//
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
FreePool (ConfigAccessInstance);
return Status;
}
ConfigAccessInstance->ThunkContext = ThunkContext;
return EFI_SUCCESS;
}
VOID
DestroyBufferStorageList (
IN LIST_ENTRY *ListHead
)
{
LIST_ENTRY *Link;
BUFFER_STORAGE_ENTRY *Entry;
/**
This function un-installs the EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered
by a module using Framework HII Protocol Interfaces.
while (!IsListEmpty (ListHead)) {
Link = GetFirstNode (ListHead);
Entry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link);
FreePool (Entry->Name);
Link = RemoveEntryList (Link);
FreePool (Entry);
}
}
ASSERT if no Config Access is found for such pakcage list or failed to uninstall the protocol.
@param ThunkContext The Thunk Context.
**/
VOID
UninstallDefaultConfigAccessProtocol (
IN HII_THUNK_CONTEXT *ThunkContext
@ -266,7 +238,6 @@ UninstallDefaultConfigAccessProtocol (
&gEfiHiiConfigAccessProtocolGuid,
(VOID **) &ConfigAccess
);
ASSERT_EFI_ERROR (Status);
Status = gBS->UninstallProtocolInterface (
@ -278,8 +249,6 @@ UninstallDefaultConfigAccessProtocol (
ConfigAccessInstance = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccess);
DestroyBufferStorageList (&ConfigAccessInstance->BufferStorageListHead);
}
@ -297,7 +266,7 @@ UninstallDefaultConfigAccessProtocol (
**/
EFI_STATUS
CallFormCallBack (
IN BUFFER_STORAGE_ENTRY *BufferStorage,
IN FORMSET_STORAGE *BufferStorage,
IN EFI_FORM_CALLBACK_PROTOCOL *FwFormCallBack,
OUT VOID **Data,
OUT UINTN *DataSize
@ -359,7 +328,7 @@ CallFormCallBack (
EFI_STATUS
GetUefiVariable (
IN BUFFER_STORAGE_ENTRY *BufferStorage,
IN FORMSET_STORAGE *BufferStorage,
OUT VOID **Data,
OUT UINTN *DataSize
)
@ -399,31 +368,6 @@ GetUefiVariable (
return Status;
}
BUFFER_STORAGE_ENTRY *
GetBufferStorageEntry (
IN CONFIG_ACCESS_PRIVATE *ConfigAccess,
IN UINT16 VarStoreId
)
{
LIST_ENTRY *Link;
BUFFER_STORAGE_ENTRY *BufferStorage;
Link = GetFirstNode (&ConfigAccess->BufferStorageListHead);
while (!IsNull (&ConfigAccess->BufferStorageListHead, Link)) {
BufferStorage = BUFFER_STORAGE_ENTRY_FROM_LINK (Link);
if (BufferStorage->VarStoreId == VarStoreId) {
return BufferStorage;
}
Link = GetNextNode (&ConfigAccess->BufferStorageListHead, Link);
}
return NULL;
}
/**
This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig
@ -458,19 +402,19 @@ ThunkExtractConfig (
{
EFI_STATUS Status;
CONFIG_ACCESS_PRIVATE *ConfigAccess;
BUFFER_STORAGE_ENTRY *BufferStorage;
FORMSET_STORAGE *BufferStorage;
VOID *Data;
UINTN DataSize;
Data = NULL;
ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);
//
// For now, only one var varstore is supported so that we don't need to parse the Configuration string.
//
BufferStorage = GetBufferStorageEntry (ConfigAccess, (UINT16) RESERVED_VARSTORE_ID);
BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Request);
if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {
//
// NvMapOverride is not used. Get the Storage data from EFI Variable or Framework Form Callback.
//
if (ConfigAccess->FormCallbackProtocol == NULL ||
ConfigAccess->FormCallbackProtocol->NvRead == NULL) {
Status = GetUefiVariable (
@ -487,6 +431,9 @@ ThunkExtractConfig (
);
}
} else {
//
// Use the NvMapOverride.
//
DataSize = BufferStorage->Size;
Data = AllocateCopyPool (DataSize, ConfigAccess->ThunkContext->NvMapOverride);
@ -515,7 +462,6 @@ ThunkExtractConfig (
}
/**
This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig
so that data can be written to the data storage such as UEFI Variable or module's
customized storage exposed by EFI_FRAMEWORK_CALLBACK.
@ -540,7 +486,7 @@ ThunkRouteConfig (
{
EFI_STATUS Status;
CONFIG_ACCESS_PRIVATE *ConfigAccess;
BUFFER_STORAGE_ENTRY *BufferStorage;
FORMSET_STORAGE *BufferStorage;
UINT8 *Data;
UINTN DataSize;
UINTN DataSize2;
@ -551,10 +497,7 @@ ThunkRouteConfig (
Data = NULL;
ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);
//
// For now, only one var varstore is supported so that we don't need to parse the Configuration string.
//
BufferStorage = GetBufferStorageEntry (ConfigAccess, (UINT16) RESERVED_VARSTORE_ID);
BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Configuration);
DataSize2 = BufferStorage->Size;
if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {
@ -632,6 +575,21 @@ Done:
return Status;
}
/**
Build the FRAMEWORK_EFI_IFR_DATA_ARRAY which will be used to pass to
EFI_FORM_CALLBACK_PROTOCOL.Callback. Check definition of FRAMEWORK_EFI_IFR_DATA_ARRAY
for details.
ASSERT if the Question Type is not EFI_IFR_TYPE_NUM_SIZE_* or EFI_IFR_TYPE_STRING.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL
@param QuestionId The Question ID.
@param Type The Question Type.
@param Value The Question Value.
@param NvMapAllocated On output indicates if a buffer is allocated for NvMap.
@return A pointer to FRAMEWORK_EFI_IFR_DATA_ARRAY. The caller must free this buffer allocated.
**/
FRAMEWORK_EFI_IFR_DATA_ARRAY *
CreateIfrDataArray (
IN CONFIG_ACCESS_PRIVATE *ConfigAccess,
@ -644,19 +602,15 @@ CreateIfrDataArray (
FRAMEWORK_EFI_IFR_DATA_ARRAY *IfrDataArray;
FRAMEWORK_EFI_IFR_DATA_ENTRY *IfrDataEntry;
UINTN BrowserDataSize;
BUFFER_STORAGE_ENTRY *BufferStorageEntry;
LIST_ENTRY *Link;
FORMSET_STORAGE *BufferStorage;
EFI_STATUS Status;
UINTN Size;
UINTN StringSize;
EFI_STRING String;
String = NULL;
*NvMapAllocated = FALSE;
Link = GetFirstNode (&ConfigAccess->BufferStorageListHead);
if (IsNull (&ConfigAccess->BufferStorageListHead, Link)) {
return NULL;
}
String = NULL;
switch (Type) {
case EFI_IFR_TYPE_NUM_SIZE_8:
@ -690,68 +644,121 @@ CreateIfrDataArray (
IfrDataArray = AllocateZeroPool (sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY) + sizeof (FRAMEWORK_EFI_IFR_DATA_ENTRY) + Size);
ASSERT (IfrDataArray != NULL);
BufferStorageEntry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link);
BrowserDataSize = BufferStorageEntry->Size;
BufferStorage = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);
if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {
*NvMapAllocated = TRUE;
IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize);
} else {
*NvMapAllocated = FALSE;
IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride;
if (BufferStorage == NULL) {
//
// The QuestionId is not associated with a Buffer Storage.
// Try to get the first Buffer Storage then.
//
BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);
}
Status = GetBrowserData (NULL, NULL, &BrowserDataSize, IfrDataArray->NvRamMap);
ASSERT_EFI_ERROR (Status);
if (BufferStorage != NULL) {
BrowserDataSize = BufferStorage->Size;
IfrDataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);
if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {
*NvMapAllocated = TRUE;
IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize);
} else {
*NvMapAllocated = FALSE;
IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride;
}
Status = GetBrowserData (&BufferStorage->Guid, BufferStorage->Name, &BrowserDataSize, IfrDataArray->NvRamMap);
ASSERT_EFI_ERROR (Status);
switch (Type) {
case EFI_IFR_TYPE_NUM_SIZE_8:
case EFI_IFR_TYPE_NUM_SIZE_16:
case EFI_IFR_TYPE_NUM_SIZE_32:
case EFI_IFR_TYPE_NUM_SIZE_64:
case EFI_IFR_TYPE_BOOLEAN:
CopyMem (&IfrDataEntry->Data, &(Value->u8), sizeof (*Value));
break;
IfrDataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);
case EFI_IFR_TYPE_STRING:
ASSERT (String != NULL);
StrCpy ((CHAR16 *) &IfrDataEntry->Data, String);
FreePool (String);
break;
default:
ASSERT (FALSE);
break;
switch (Type) {
case EFI_IFR_TYPE_NUM_SIZE_8:
case EFI_IFR_TYPE_NUM_SIZE_16:
case EFI_IFR_TYPE_NUM_SIZE_32:
case EFI_IFR_TYPE_NUM_SIZE_64:
case EFI_IFR_TYPE_BOOLEAN:
CopyMem (&IfrDataEntry->Data, &(Value->u8), sizeof (*Value));
break;
case EFI_IFR_TYPE_STRING:
ASSERT (String != NULL);
StrCpy ((CHAR16 *) &IfrDataEntry->Data, String);
FreePool (String);
break;
default:
ASSERT (FALSE);
break;
}
//
// Need to fiil in the information for the rest of field for FRAMEWORK_EFI_IFR_DATA_ENTRY.
// It seems that no implementation is found to use other fields. Leave them uninitialized for now.
//
//UINT8 OpCode; // Likely a string, numeric, or one-of
//UINT8 Length; // Length of the FRAMEWORK_EFI_IFR_DATA_ENTRY packet
//UINT16 Flags; // Flags settings to determine what behavior is desired from the browser after the callback
//VOID *Data; // The data in the form based on the op-code type - this is not a pointer to the data, the data follows immediately
// If the OpCode is a OneOf or Numeric type - Data is a UINT16 value
// If the OpCode is a String type - Data is a CHAR16[x] type
// If the OpCode is a Checkbox type - Data is a UINT8 value
// If the OpCode is a NV Access type - Data is a FRAMEWORK_EFI_IFR_NV_DATA structure
}
return IfrDataArray;
}
/**
If a NvMapOverride is passed in to EFI_FORM_BROWSER_PROTOCOL.SendForm, the Form Browser
needs to be informed when data changed in NvMapOverride. This function will invoke
SetBrowserData () to set internal data of Form Browser.
@param ConfigAccess The Config Access Private Context.
@param QuestionId The Question Id that invokes the callback.
**/
VOID
SyncBrowserDataForNvMapOverride (
IN CONFIG_ACCESS_PRIVATE *ConfigAccess
IN CONST CONFIG_ACCESS_PRIVATE *ConfigAccess,
IN EFI_QUESTION_ID QuestionId
)
{
BUFFER_STORAGE_ENTRY *BufferStorageEntry;
LIST_ENTRY *Link;
FORMSET_STORAGE *BufferStorage;
EFI_STATUS Status;
UINTN BrowserDataSize;
if (ConfigAccess->ThunkContext->NvMapOverride != NULL) {
Link = GetFirstNode (&ConfigAccess->BufferStorageListHead);
ASSERT (!IsNull (&ConfigAccess->BufferStorageListHead, Link));
BufferStorageEntry = BUFFER_STORAGE_ENTRY_FROM_LINK(Link);
BrowserDataSize = BufferStorageEntry->Size;
Status = SetBrowserData (NULL, NULL, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL);
BufferStorage = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);
if (BufferStorage == NULL) {
//
// QuestionId is a statement without Storage.
// 1) It is a Goto.
//
//
BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);
}
//
// If NvMapOverride is not NULL, this Form must have at least one Buffer Type Variable Storage.
//
ASSERT (BufferStorage != NULL);
BrowserDataSize = BufferStorage->Size;
Status = SetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL);
ASSERT_EFI_ERROR (Status);
}
}
/**
Free up resource allocated for a FRAMEWORK_EFI_IFR_DATA_ARRAY by CreateIfrDataArray ().
@param Array The FRAMEWORK_EFI_IFR_DATA_ARRAY allocated.
@param NvMapAllocated If the NvRamMap is allocated for FRAMEWORK_EFI_IFR_DATA_ARRAY.
**/
VOID
DestroyIfrDataArray (
IN FRAMEWORK_EFI_IFR_DATA_ARRAY *Array,
@ -767,7 +774,21 @@ DestroyIfrDataArray (
}
}
/**
Get the ONE_OF_OPTION_MAP_ENTRY for a QuestionId that invokes the
EFI_FORM_CALLBACK_PROTOCOL.Callback. The information is needed as
the callback mechanism for EFI_IFR_ONE_OF_OPTION is changed from
EFI_IFR_ONE_OF_OPTION in Framework IFR. Check EFI_IFR_GUID_OPTIONKEY
for detailed information.
@param ThunkContext The Thunk Context.
@param QuestionId The Question Id.
@param Type The Question Type.
@param Value The One Of Option's value.
@return The ONE_OF_OPTION_MAP_ENTRY found.
@retval NULL If no entry is found.
**/
ONE_OF_OPTION_MAP_ENTRY *
GetOneOfOptionMapEntry (
IN HII_THUNK_CONTEXT *ThunkContext,
@ -780,10 +801,13 @@ GetOneOfOptionMapEntry (
LIST_ENTRY *Link2;
ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;
ONE_OF_OPTION_MAP *OneOfOptionMap;
FORM_BROWSER_FORMSET *FormSet;
Link = GetFirstNode (&ThunkContext->OneOfOptionMapListHead);
FormSet = ThunkContext->FormSet;
while (!IsNull (&ThunkContext->OneOfOptionMapListHead, Link)) {
Link = GetFirstNode (&FormSet->OneOfOptionMapListHead);
while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) {
OneOfOptionMap = ONE_OF_OPTION_MAP_FROM_LINK(Link);
if (OneOfOptionMap->QuestionId == QuestionId) {
ASSERT (OneOfOptionMap->ValueType == Type);
@ -801,7 +825,7 @@ GetOneOfOptionMapEntry (
}
}
Link = GetNextNode (&ThunkContext->OneOfOptionMapListHead, Link);
Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link);
}
@ -815,6 +839,18 @@ GetOneOfOptionMapEntry (
PackageGuid, Handle, and Package are used for each of the
notification types.
If any Pakcage List in database is updated, mHiiPackageListUpdated
will be set. If mHiiPackageListUpdated is set, Framework ThunkCallback()
will force the UEFI Setup Browser to save the uncommitted data. This
is needed as Framework's Callback function may dynamically update
opcode in a Package List. UEFI Setup Browser will quit itself and reparse
the Package List's IFR and display it. UEFI Config Access's implementation
is required to save the modified (SetBrowserData or directly save the data
to NV storage). But Framework HII Modules is not aware of this rule. Therefore,
we will enforce the rule in ThunkCallback (). The side effect of force saving
of NV data is the NV flag in browser may not flag a update as data has already
been saved to NV storage.
@param PackageType Package type of the notification.
@param PackageGuid If PackageType is
@ -851,8 +887,7 @@ FormUpdateNotify (
/**
Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.CallBack to EFI_FORM_CALLBACK_PROTOCOL.Callback. Therefor,
the framework HII module willl do no porting (except some porting works needed for callback for EFI_ONE_OF_OPTION opcode)
and still work with a UEFI HII SetupBrowser.
the framework HII module willl do no porting and work with a UEFI HII SetupBrowser.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action Specifies the type of action taken by the browser. See EFI_BROWSER_ACTION_x.
@ -922,6 +957,9 @@ ThunkCallback (
//
KeyValue = QuestionId;
} else {
//
// Otherwise, use the original Key specified in One Of Option in the Framework VFR syntax.
//
KeyValue = OneOfOptionMapEntry->FwKey;
}
@ -939,7 +977,7 @@ ThunkCallback (
&NotifyHandle
);
//
//
//Call the Framework Callback function.
//
Packet = NULL;
Status = FormCallbackProtocol->Callback (
@ -948,7 +986,7 @@ ThunkCallback (
Data,
&Packet
);
SyncBrowserDataForNvMapOverride (ConfigAccess);
SyncBrowserDataForNvMapOverride (ConfigAccess, QuestionId);
//
// Callback require browser to perform action
@ -998,15 +1036,19 @@ ThunkCallback (
// the form and load all the variable storages.
//
if (*ActionRequest == EFI_BROWSER_ACTION_REQUEST_NONE && mHiiPackageListUpdated) {
mHiiPackageListUpdated= FALSE;
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
} else {
if (ConfigAccess->ThunkContext->FormSetSubClass == EFI_FRONT_PAGE_SUBCLASS ||
ConfigAccess->ThunkContext->FormSetSubClass == EFI_SINGLE_USE_SUBCLASS) {
if (ConfigAccess->ThunkContext->FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS ||
ConfigAccess->ThunkContext->FormSet->SubClass == EFI_SINGLE_USE_SUBCLASS) {
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
}
}
//
// Clean up.
//
DestroyIfrDataArray (Data, NvMapAllocated);
return Status;

View File

@ -22,20 +22,31 @@ EFI_GRAPHICS_OUTPUT_BLT_PIXEL mSysFGColor = {0};
/**
This function is only called by Graphics Console module and GraphicsLib.
EDK II provides a UEFI Graphics Console module. ECP provides a GraphicsLib
complying to UEFI HII.
Translates a Unicode character into the corresponding font glyph.
This function will ASSERT and return EFI_UNSUPPORTED.
Notes:
This function is only called by Graphics Console module and GraphicsLib.
Wrap the Framework HII GetGlyph function to UEFI Font Protocol.
EDK II provides a UEFI Graphics Console module. ECP provides a GraphicsLib
complying to UEFI HII.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param Source A pointer to a Unicode string.
@param Index On input, the offset into the string from which to fetch the character. On successful completion, the
index is updated to the first character past the character(s) making up the just extracted glyph.
@param GlyphBuffer Pointer to an array where the glyphs corresponding to the characters in the source may be stored.
GlyphBuffer is assumed to be wide enough to accept a wide glyph character.
@param BitWidth If EFI_SUCCESS was returned, the UINT16 pointed to by this value is filled with the length of the glyph in pixels.
It is unchanged if the call was unsuccessful.
@param InternalStatus To save the time required to read the string from the beginning on each glyph extraction
(for example, to ensure that the narrow versus wide glyph mode is correct), this value is
updated each time the function is called with the status that is local to the call. The cell pointed
to by this parameter must be initialized to zero prior to invoking the call the first time for any string.
@param This N.A.
@param Source N.A.
@param Index N.A.
@param GlyphBuffer N.A.
@param BitWidth N.A.
@param InternalStatus N.A.
@return EFI_UNSUPPORTED N.A.
@retval EFI_SUCCESS It worked.
@retval EFI_NOT_FOUND A glyph for a character was not found.
**/
EFI_STATUS
@ -122,22 +133,25 @@ HiiGetGlyph (
}
/**
Translates a glyph into the format required for input to the Universal Graphics Adapter (UGA) Block Transfer (BLT) routines.
Notes:
This function is only called by Graphics Console module and GraphicsLib.
EDK II provides a UEFI Graphics Console module. ECP provides a GraphicsLib
complying to UEFI HII.
This function will ASSERT and return EFI_UNSUPPORTED.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param GlyphBuffer A pointer to the buffer that contains glyph data.
@param Foreground The foreground setting requested to be used for the generated BltBuffer data. Type EFI_UGA_PIXEL is defined in "Related Definitions" below.
@param Background The background setting requested to be used for the generated BltBuffer data.
@param Count The entry in the BltBuffer upon which to act.
@param Width The width in bits of the glyph being converted.
@param Height The height in bits of the glyph being converted
@param BltBuffer A pointer to the buffer that contains the data that is ready to be used by the UGA BLT routines.
@param This N.A.
@param GlyphBuffer N.A.
@param Foreground N.A.
@param Background N.A.
@param Count N.A.
@param Width N.A.
@param Height N.A.
@param BltBuffer N.A.
@return EFI_UNSUPPORTED N.A.
@retval EFI_SUCCESS It worked.
@retval EFI_NOT_FOUND A glyph for a character was not found.
**/
EFI_STATUS

View File

@ -55,6 +55,8 @@ FW_HII_FORMSET_TEMPLATE FormSetTemplate = {
};
EFI_GUID mTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;
/**
This thunk module only handles UEFI HII packages. The caller of this function
@ -144,10 +146,12 @@ HiiGetForms (
CopyMem (OutputFormSet, &FormSetTemplate, sizeof (FW_HII_FORMSET_TEMPLATE));
CopyMem (&OutputFormSet->FormSet.Guid, &ThunkContext->TagGuid, sizeof (EFI_GUID));
OutputFormSet->FormSet.Class = ThunkContext->FormSetClass;
OutputFormSet->FormSet.SubClass = ThunkContext->FormSetSubClass;
OutputFormSet->FormSet.Help = ThunkContext->FormSetHelp;
OutputFormSet->FormSet.FormSetTitle = ThunkContext->FormSetTitle;
if (ThunkContext->FormSet != NULL) {
OutputFormSet->FormSet.Class = ThunkContext->FormSet->Class;
OutputFormSet->FormSet.SubClass = ThunkContext->FormSet->SubClass;
OutputFormSet->FormSet.Help = ThunkContext->FormSet->Help;
OutputFormSet->FormSet.FormSetTitle = ThunkContext->FormSet->FormSetTitle;
}
return EFI_SUCCESS;
}
@ -182,25 +186,25 @@ HiiGetDefaultImage (
)
{
LIST_ENTRY *UefiDefaults;
EFI_HII_HANDLE UefiHiiHandle;
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT *ThunkContext;
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);
if (UefiHiiHandle == NULL) {
ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
if (ThunkContext == NULL) {
ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
UefiDefaults = NULL;
Status = UefiIfrGetBufferTypeDefaults (UefiHiiHandle, &UefiDefaults);
Status = UefiIfrGetBufferTypeDefaults (ThunkContext, &UefiDefaults);
if (EFI_ERROR (Status)) {
goto Done;
}
Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, VariablePackList);
Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, ThunkContext->FormSet->DefaultVarStoreId, VariablePackList);
Done:
FreeDefaultList (UefiDefaults);
@ -209,12 +213,15 @@ Done:
}
/**
EDES_TODO: Add function description.
This function update the FormCallbackProtocol cached in Config Access
private context data.
@param CallbackHandle EDES_TODO: Add parameter description
@param ThunkContext EDES_TODO: Add parameter description
@param CallbackHandle The EFI Handle on which the Framework FormCallbackProtocol is
installed.
@param ThunkContext The Thunk Context.
@return EDES_TODO: Add description for return value
@retval EFI_SUCCESS The update is successful.
@retval EFI_INVALID_PARAMETER If no Framework FormCallbackProtocol is located on CallbackHandle.
**/
EFI_STATUS
@ -260,17 +267,17 @@ UpdateFormCallBack (
/**
EDES_TODO: Add function description.
Get the package data from the Package List.
@param HiiPackageList EDES_TODO: Add parameter description
@param PackageIndex EDES_TODO: Add parameter description
@param BufferLen EDES_TODO: Add parameter description
@param Buffer EDES_TODO: Add parameter description
@param HiiPackageList Package List.
@param PackageIndex The index of the Package in the Package List.
@param BufferLen The Length of the Pacage data.
@param Buffer On output, the Package data.
@return EDES_TODO: Add description for return value
@return EFI_NOT_FOUND No Package is found for PackageIndex.
@return EFI_SUCCESS The package data is returned.
**/
STATIC
EFI_STATUS
GetPackageData (
IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,
@ -317,10 +324,16 @@ GetPackageData (
}
/**
Check if Label exist in the IFR form package.
Check if Label exist in the IFR form package and return the FormSet GUID
and Form ID.
@param
@param Package The Package Header.
@param Label The Label ID.
@param FormsetGuid Returns the FormSet GUID.
@param FormId Returns the Form ID.
@retval EFI_SUCCESS The FORM ID is found.
@retval EFI_NOT_FOUND The FORM ID is not found.
**/
EFI_STATUS
LocateLabel (
@ -332,12 +345,11 @@ LocateLabel (
{
UINTN Offset;
EFI_IFR_OP_HEADER *IfrOpHdr;
UINT8 ExtendOpCode;
UINT16 LabelNumber;
EFI_GUID InternalFormSetGuid;
EFI_FORM_ID InternalFormId;
BOOLEAN GetFormSet;
BOOLEAN GetForm;
EFI_IFR_GUID_LABEL *LabelOpcode;
IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));
Offset = sizeof (EFI_HII_PACKAGE_HEADER);
@ -360,26 +372,18 @@ LocateLabel (
break;
case EFI_IFR_GUID_OP :
ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;
if (ExtendOpCode != EFI_IFR_EXTEND_OP_LABEL) {
//
// Go to the next Op-Code
//
Offset += IfrOpHdr->Length;
IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
continue;
LabelOpcode = (EFI_IFR_GUID_LABEL *) IfrOpHdr;
//
// If it is an Label opcode.
//
if ((LabelOpcode->ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) && (CompareMem (&LabelOpcode->Guid, &mTianoHiiIfrGuid, sizeof (EFI_GUID)) == 0)) {
if (CompareMem (&Label, &LabelOpcode->Number, sizeof (UINT16)) == 0) {
ASSERT (GetForm && GetFormSet);
CopyGuid (FormsetGuid, &InternalFormSetGuid);
*FormId = InternalFormId;
return EFI_SUCCESS;
}
}
CopyMem (&LabelNumber, &((EFI_IFR_GUID_LABEL *)IfrOpHdr)->Number, sizeof (UINT16));
if (LabelNumber == Label) {
ASSERT (GetForm && GetFormSet);
CopyGuid (FormsetGuid, &InternalFormSetGuid);
*FormId = InternalFormId;
return EFI_SUCCESS;
}
break;
default :
break;
@ -462,6 +466,7 @@ Done:
return Status;
}
/**
This function allows the caller to update a form that has
previously been registered with the EFI HII database.
@ -539,10 +544,10 @@ HiiUpdateForm (
if (Data->DataCount != 0) {
ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);
Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, AddData, &UefiHiiUpdateData);
Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, &UefiHiiUpdateData);
ASSERT_EFI_ERROR (Status);
Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, AddData, UefiHiiUpdateData);
Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, TRUE, UefiHiiUpdateData);
ASSERT_EFI_ERROR (Status);
}

View File

@ -43,13 +43,10 @@
ConfigAccess.h
OpcodeCreation.c
OpcodeCreation.h
UefiIfrParserInternal.h
UefiIfrParserCommon.c
UefiIfrParserCommon.h
UefiIfrParser.c
UefiIfrParser.h
UefiIfrParserExpression.c
UefiIfrParserExpressionInternal.h
UefiIfrParserExpression.h
UefiIfrDefault.c
UefiIfrDefault.h
Keyboard.c
@ -104,3 +101,4 @@
gEfiFormBrowser2ProtocolGuid

View File

@ -51,6 +51,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <MdeModuleHii.h>
#include "UefiIfrParser.h"
//
// VARSTORE ID of 0 for Buffer Storage Type Storage is reserved in UEFI IFR form. But VARSTORE ID
@ -59,7 +61,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Framework VFR has to be ported or pre-processed to change the default VARSTORE to a VARSTORE
// with ID equal to 0x0001.
//
#define RESERVED_VARSTORE_ID 0x0001
#define FRAMEWORK_RESERVED_VARSTORE_ID 0x0001
#pragma pack (push, 1)
@ -87,32 +89,6 @@ typedef struct {
#define ONE_OF_OPTION_MAP_ENTRY_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP_ENTRY, Link, ONE_OF_OPTION_MAP_ENTRY_SIGNATURE)
#define ONE_OF_OPTION_MAP_ENTRY_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'M', 'E')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
UINT16 FwKey;
EFI_IFR_TYPE_VALUE Value;
} ONE_OF_OPTION_MAP_ENTRY;
#define ONE_OF_OPTION_MAP_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP, Link, ONE_OF_OPTION_MAP_SIGNATURE)
#define ONE_OF_OPTION_MAP_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'O', 'M')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
UINT8 ValueType; //EFI_IFR_TYPE_NUM_*
EFI_QUESTION_ID QuestionId;
LIST_ENTRY OneOfOptionMapEntryListHead; //ONE_OF_OPTION_MAP_ENTRY
} ONE_OF_OPTION_MAP;
#define QUESTION_ID_MAP_ENTRY_FROM_LINK(Record) CR(Record, QUESTION_ID_MAP_ENTRY, Link, QUESTION_ID_MAP_ENTRY_SIGNATURE)
@ -161,17 +137,10 @@ typedef struct {
// TagGuid is the used to record this GuidId.
EFI_GUID TagGuid;
LIST_ENTRY QuestionIdMapListHead; //QUESTION_ID_MAP
LIST_ENTRY OneOfOptionMapListHead; //ONE_OF_OPTION_MAP
UINT8 *NvMapOverride;
UINT16 FormSetClass;
UINT16 FormSetSubClass;
STRING_REF FormSetTitle;
STRING_REF FormSetHelp;
FORM_BROWSER_FORMSET *FormSet;
} HII_THUNK_CONTEXT;
@ -199,8 +168,6 @@ typedef struct {
//
EFI_FORM_CALLBACK_PROTOCOL *FormCallbackProtocol;
LIST_ENTRY BufferStorageListHead;
HII_THUNK_CONTEXT *ThunkContext;
} CONFIG_ACCESS_PRIVATE;

View File

@ -16,6 +16,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "HiiDatabase.h"
/**
Retrieves the current keyboard layout.
This function is not implemented by HII Thunk Module.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param DescriptorCount A pointer to the number of Descriptor entries being described in the keyboard layout being retrieved.
@param Descriptor A pointer to a buffer containing an array of EFI_KEY_DESCRIPTOR entries. Each entry will reflect the definition of a specific physical key. Type EFI_KEY_DESCRIPTOR is defined in "Related Definitions" below.
@retval EFI_SUCCESS The keyboard layout was retrieved successfully.
**/
EFI_STATUS
EFIAPI
HiiGetKeyboardLayout (
@ -23,15 +34,6 @@ HiiGetKeyboardLayout (
OUT UINT16 *DescriptorCount,
OUT FRAMEWORK_EFI_KEY_DESCRIPTOR *Descriptor
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
ASSERT (FALSE);
//

View File

@ -18,6 +18,108 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
EFI_GUID mTianoExtendedOpcodeGuid = EFI_IFR_TIANO_GUID;
EFI_IFR_GUID_OPTIONKEY mOptionKeyTemplate = {
{EFI_IFR_GUID_OP, sizeof (EFI_IFR_GUID_OPTIONKEY), 0},
EFI_IFR_FRAMEWORK_GUID,
EFI_IFR_EXTEND_OP_OPTIONKEY,
0,
0,
0
};
typedef struct {
UINT8 FrameworkIfrOp;
UINT8 UefiIfrOp;
} IFR_OPCODE_MAP;
IFR_OPCODE_MAP mQuestionOpcodeMap [] = {
{ FRAMEWORK_EFI_IFR_ONE_OF_OP, EFI_IFR_ONE_OF_OP},
{ FRAMEWORK_EFI_IFR_CHECKBOX_OP, EFI_IFR_CHECKBOX_OP},
{ FRAMEWORK_EFI_IFR_NUMERIC_OP, EFI_IFR_NUMERIC_OP},
{ FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP, EFI_IFR_ONE_OF_OPTION_OP},
{ FRAMEWORK_EFI_IFR_ORDERED_LIST_OP, EFI_IFR_ORDERED_LIST_OP}
};
EFI_STATUS
QuestionOpFwToUefi (
IN UINT8 FwOp,
OUT UINT8 *UefiOp
)
{
UINTN Index;
for (Index = 0; Index < sizeof (mQuestionOpcodeMap) / sizeof (mQuestionOpcodeMap[0]); Index++) {
if (FwOp == mQuestionOpcodeMap[Index].FrameworkIfrOp) {
*UefiOp = mQuestionOpcodeMap[Index].UefiIfrOp;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
FwQIdToUefiQId (
IN CONST FORM_BROWSER_FORMSET *FormSet,
IN UINT16 VarStoreId,
IN UINT8 FwOpCode,
IN UINT16 FwQId,
OUT UINT16 *UefiQId
)
{
LIST_ENTRY *FormList;
LIST_ENTRY *StatementList;
FORM_BROWSER_FORM *Form;
FORM_BROWSER_STATEMENT *Statement;
EFI_STATUS Status;
UINT8 UefiOp;
*UefiQId = 0;
FormList = GetFirstNode (&FormSet->FormListHead);
while (!IsNull (&FormSet->FormListHead, FormList)) {
Form = FORM_BROWSER_FORM_FROM_LINK (FormList);
StatementList = GetFirstNode (&Form->StatementListHead);
while (!IsNull (&Form->StatementListHead, StatementList)) {
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);
if (Statement->VarStoreId != 0 && Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER) {
if (FwQId == Statement->VarStoreInfo.VarOffset) {
Status = QuestionOpFwToUefi (FwOpCode, &UefiOp);
ASSERT_EFI_ERROR (Status);
if (UefiOp == Statement->Operand) {
//
// If ASSERT here, the Framework VFR file has two IFR Question with the Same Type refering to the
// same field in NvMap. This is ambigurity, we don't handle it for now.
//
//
// UEFI Question ID is unique in a FormSet.
//
ASSERT (VarStoreId == Statement->VarStoreId);
*UefiQId = Statement->QuestionId;
return EFI_SUCCESS;
}
}
}
StatementList = GetNextNode (&Form->StatementListHead, StatementList);
}
FormList = GetNextNode (&FormSet->FormListHead, FormList);
}
return EFI_NOT_FOUND;
}
#define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000
EFI_STATUS
AppendToUpdateBuffer (
@ -46,54 +148,18 @@ AppendToUpdateBuffer (
EFI_QUESTION_ID
AssignQuestionId (
IN UINT16 FwQuestionId
IN UINT16 FwQuestionId,
IN FORM_BROWSER_FORMSET *FormSet
)
{
if (FwQuestionId == 0) {
//
// In UEFI IFR, the Question ID can't be zero. Zero means no storage.
// So use 0xABBA as a Question ID.
//
return 0xABBA;
FormSet->MaxQuestionId++;
return FormSet->MaxQuestionId;
} else {
return FwQuestionId;
}
}
EFI_STATUS
FwQuestionIdToUefiQuestionId (
IN HII_THUNK_CONTEXT *ThunkContext,
IN UINT16 VarStoreId,
IN UINT16 FwId,
OUT EFI_QUESTION_ID *UefiQId
)
{
LIST_ENTRY *MapEntryListHead;
LIST_ENTRY *Link;
QUESTION_ID_MAP_ENTRY *MapEntry;
MapEntryListHead = GetMapEntryListHead (ThunkContext, VarStoreId);
ASSERT (MapEntryListHead != NULL);
Link = GetFirstNode (MapEntryListHead);
while (!IsNull (MapEntryListHead, Link)) {
MapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link);
if (MapEntry->FwQId == FwId) {
*UefiQId = MapEntry->UefiQid;
return EFI_SUCCESS;
}
Link = GetNextNode (MapEntryListHead, Link);
}
return EFI_NOT_FOUND;
}
EFI_STATUS
UCreateEndOfOpcode (
OUT EFI_HII_UPDATE_DATA *UefiData
@ -281,6 +347,24 @@ F2UCreateOneOfOptionOpCode (
return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);
}
EFI_STATUS
CreateGuidOptionKeyOpCode (
IN EFI_QUESTION_ID QuestionId,
IN UINT16 OptionValue,
IN EFI_QUESTION_ID KeyValue,
OUT EFI_HII_UPDATE_DATA *UefiData
)
{
EFI_IFR_GUID_OPTIONKEY UOpcode;
CopyMem (&UOpcode, &mOptionKeyTemplate, sizeof (EFI_IFR_GUID_OPTIONKEY));
UOpcode.QuestionId = QuestionId;
CopyMem (&UOpcode.OptionValue, &OptionValue, sizeof (OptionValue));
UOpcode.KeyValue = KeyValue;
return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);
}
/*
typedef struct _EFI_IFR_QUESTION_HEADER {
@ -349,14 +433,10 @@ F2UCreateOneOfOpCode (
EFI_IFR_ONE_OF UOpcode;
FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;
FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;
ONE_OF_OPTION_MAP *OneOfOptionMap;
ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;
ASSERT (NextFwOpcode != NULL);
ASSERT (DataCount != NULL);
OneOfOptionMap = NULL;
ZeroMem (&UOpcode, sizeof(UOpcode));
*DataCount = 0;
@ -381,41 +461,12 @@ F2UCreateOneOfOpCode (
UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;
if (UOpcode.Question.QuestionId == 0) {
Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
if (EFI_ERROR (Status)) {
UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key);
UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);
}
OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));
ASSERT (OneOfOptionMap != NULL);
OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;
OneOfOptionMap->QuestionId = UOpcode.Question.QuestionId;
InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);
switch (FwOpcode->Width) {
case 1:
OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_8;
break;
case 2:
OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_16;
break;
default:
ASSERT (FALSE);
break;
}
InsertTailList (&ThunkContext->OneOfOptionMapListHead, &OneOfOptionMap->Link);
}
OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));
ASSERT (OneOfOptionMapEntry != NULL);
OneOfOptionMapEntry->FwKey = FwOneOfOp->Key;
OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;
CopyMem (&OneOfOptionMapEntry->Value, &FwOneOfOp->Value, FwOpcode->Width);
ASSERT (OneOfOptionMap != NULL);
InsertTailList (&OneOfOptionMap->OneOfOptionMapEntryListHead, &OneOfOptionMapEntry->Link);
}
if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {
@ -430,9 +481,9 @@ F2UCreateOneOfOpCode (
//
// Assign QuestionId if still not assigned.
//
Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
if (EFI_ERROR (Status)) {
UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);
UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);
}
}
@ -447,10 +498,18 @@ F2UCreateOneOfOpCode (
//
FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);
while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {
FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;
Status = F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width, UefiData);
if (EFI_ERROR (Status)) {
return Status;
}
Status = CreateGuidOptionKeyOpCode (UOpcode.Question.QuestionId, FwOneOfOp->Value, FwOneOfOp->Key, UefiData);
if (EFI_ERROR (Status)) {
return Status;
}
FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);
*DataCount += 1;
}
@ -533,9 +592,9 @@ F2UCreateOrderedListOpCode (
UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;
if (UOpcode.Question.QuestionId == 0) {
Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
if (EFI_ERROR (Status)) {
UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key);
UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);
}
}
@ -549,9 +608,9 @@ F2UCreateOrderedListOpCode (
}
if (UOpcode.Question.QuestionId == 0) {
Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
if (EFI_ERROR (Status)) {
UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);
UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);
}
}
@ -637,18 +696,18 @@ F2UCreateCheckBoxOpCode (
UOpcode.Question.Header.Help = FwOpcode->Help;
if (FwOpcode->Key == 0) {
Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
if (EFI_ERROR (Status)) {
//
// Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
//
UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);
UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);
}
} else {
UOpcode.Question.QuestionId = FwOpcode->Key;
}
UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID;
UOpcode.Question.VarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;
UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;
//
@ -746,12 +805,12 @@ F2UCreateNumericOpCode (
ZeroMem (&UOpcode, sizeof(UOpcode));
if (FwOpcode->Key == 0) {
Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
if (EFI_ERROR (Status)) {
//
// Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
//
UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);
UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);
}
} else {
UOpcode.Question.QuestionId = FwOpcode->Key;
@ -887,7 +946,7 @@ F2UCreateStringOpCode (
ZeroMem (&UOpcode, sizeof(UOpcode));
if (FwOpcode->Key == 0) {
FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
} else {
UOpcode.Question.QuestionId = FwOpcode->Key;
}
@ -899,7 +958,7 @@ F2UCreateStringOpCode (
UOpcode.Question.Header.Help = FwOpcode->Help;
UOpcode.Question.QuestionId = FwOpcode->Key;
UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID;
UOpcode.Question.VarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;
UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;
UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));
@ -957,7 +1016,6 @@ EFI_STATUS
FwUpdateDataToUefiUpdateData (
IN HII_THUNK_CONTEXT *ThunkContext,
IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *Data,
IN BOOLEAN AddData,
OUT EFI_HII_UPDATE_DATA **UefiData
)
{

View File

@ -105,7 +105,6 @@ EFI_STATUS
FwUpdateDataToUefiUpdateData (
IN HII_THUNK_CONTEXT *ThunkContext,
IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *Data,
IN BOOLEAN AddData,
OUT EFI_HII_UPDATE_DATA **UefiData
);
#endif

View File

@ -362,7 +362,7 @@ UefiRegisterPackageList (
//
// If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering
// packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is
// not used as the name of the package list. A GUID is generated as a Package List
// not used as the name of the package list. Formset GUID is used as the Package List
// GUID.
//
ASSERT (StringPackageCount >=1 && IfrPackageCount == 1);
@ -383,7 +383,9 @@ UefiRegisterPackageList (
//
// UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so
// that Setup Utility can load the Buffer Storage using this protocol.
// that Setup Utility can load the Buffer Storage using this protocol. An UEFI VFR can only
// produce IFR package generated with Buffer Storage type and EFI Variable Storage.
// The default EFI_HII_CONFIG_ACCESS_PROTOCOL is used to Get/Set the Buffer Storage.
//
if (IfrPackageCount != 0) {
InstallDefaultConfigAccessProtocol (Packages, ThunkContext);
@ -425,8 +427,10 @@ UefiRegisterPackageList (
if (IfrPackageCount == 0) {
if (StringPackageCount != 0) {
//
// Look for a Package List with only IFR Package with the same GUID name.
// If found one, add the String Packages to it.
// Look for a Package List with only IFR Package with the same TAG GUID name.
// If found one, add the String Packages to the found Package List.
// This is needed because Framework HII Module may not register the String Package
// and IFR Package in one NewPack () call.
//
UpdatePackListWithOnlyIfrPack (
Private,
@ -435,11 +439,12 @@ UefiRegisterPackageList (
);
}
} else {
CreateQuestionIdMap (ThunkContext);
if (StringPackageCount == 0) {
//
// Register the Package List to UEFI HII first.
// Look for the String Package with the same TAG GUID name and add
// the found String Package to this Package List.
// This is needed because Framework HII Module may not register the String Package
// and IFR Package in one NewPack () call.
//
Status = FindStringPackAndUpdatePackListWithOnlyIfrPack (
Private,
@ -450,6 +455,14 @@ UefiRegisterPackageList (
goto Done;
}
}
//
// Parse the Formset. Must be called after FindStringPackAndUpdatePackListWithOnlyIfrPack is called so
// that String Package is ready.
//
ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);
ASSERT (ThunkContext->FormSet != NULL);
}
Done:
@ -468,6 +481,18 @@ Done:
}
/**
Registers the various packages that are passed in a Package List.
@param This Pointer of Frameowk HII protocol instance.
@param Packages Pointer of HII packages.
@param Handle Handle value to be returned.
@retval EFI_SUCCESS Pacakges has added to HII database successfully.
@retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.
**/
EFI_STATUS
EFIAPI
HiiNewPack (
@ -475,24 +500,6 @@ HiiNewPack (
IN EFI_HII_PACKAGES *Packages,
OUT FRAMEWORK_EFI_HII_HANDLE *Handle
)
/*++
Routine Description:
Extracts the various packs from a package list.
Arguments:
This - Pointer of HII protocol.
Packages - Pointer of HII packages.
Handle - Handle value to be returned.
Returns:
EFI_SUCCESS - Pacakges has added to HII database successfully.
EFI_INVALID_PARAMETER - Invalid parameter.
--*/
{
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
@ -509,10 +516,10 @@ Returns:
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
//
// We use a simple Global variable to inform NewPackNotify
// We use a simple Global variable to inform NewOrAddPackNotify()
// that the package list registered here is already registered
// in the HII Thunk Layer. So NewPackNotify does not need to
// call RegisterUefiHiiHandle () to registered it.
// in the HII Thunk Layer. So NewOrAddPackNotify () does not need to
// call registered the Package List again.
//
mInFrameworkHiiNewPack = TRUE;
@ -532,26 +539,27 @@ Returns:
return Status;
}
/**
Remove a package from the HII database.
@param This Pointer of Frameowk HII protocol instance.
@param Handle Handle value to be removed.
@retval EFI_SUCCESS Pacakges has added to HII database successfully.
@retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.
**/
EFI_STATUS
EFIAPI
HiiRemovePack (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle
)
/*++
Routine Description:
Removes the various packs from a Handle
Arguments:
Returns:
--*/
{
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT *ThunkContext;
HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT *ThunkContext;
EFI_TPL OldTpl;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
@ -584,6 +592,25 @@ Returns:
return Status;
}
/**
This notification function will be called when a Package List is registered
using UEFI HII interface. The Package List registered need to be recorded in
Framework Thunk module as Thunk Module may need to look for String Package in
the package registered.
If the Package List registered is not either Sting Package or IFR package,
then ASSERT. If the NotifyType is not ADD_PACK or NEW_PACK, then ASSERT.
Both cases means UEFI HII Database itself is buggy.
@param PackageType The Package Type.
@param PackageGuid The Package GUID.
@param Package The Package Header.
@param Handle The HII Handle of this Package List.
@param NotifyType The reason of the notification.
@retval EFI_SUCCESS The notification function is successful.
**/
EFI_STATUS
EFIAPI
NewOrAddPackNotify (
@ -609,8 +636,8 @@ NewOrAddPackNotify (
}
//
// We only create a ThunkContext if the Uefi Hii Handle is only already registered
// by the HII Thunk Layer.
// We will create a ThunkContext to log the package list only if the
// package is not registered with by Framework HII Thunk module yet.
//
ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);
if (ThunkContext == NULL) {
@ -621,17 +648,38 @@ NewOrAddPackNotify (
}
if (PackageType == EFI_HII_PACKAGE_FORMS) {
GetAttributesOfFirstFormSet (ThunkContext);
if (ThunkContext->FormSet != NULL) {
DestroyFormSet (ThunkContext->FormSet);
}
//
// Reparse the FormSet.
//
ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);
ASSERT (ThunkContext->FormSet != NULL);
}
return Status;
}
//
// Framework HII module may cache a GUID as the name of the package list.
// Then search for the Framework HII handle database for the handle matching
// this GUID
/**
This notification function will be called when a Package List is removed
using UEFI HII interface. The Package List removed need to be removed from
Framework Thunk module too.
If the Package List registered is not Sting Package,
then ASSERT. If the NotifyType is not REMOVE_PACK, then ASSERT.
Both cases means UEFI HII Database itself is buggy.
@param PackageType The Package Type.
@param PackageGuid The Package GUID.
@param Package The Package Header.
@param Handle The HII Handle of this Package List.
@param NotifyType The reason of the notification.
@retval EFI_SUCCESS The notification function is successful.
**/
EFI_STATUS
EFIAPI
RemovePackNotify (

View File

@ -15,6 +15,26 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "HiiDatabase.h"
/**
This is the Framework Setup Browser interface which displays a FormSet.
@param This The EFI_FORM_BROWSER_PROTOCOL context.
@param UseDatabase TRUE if the FormSet is from HII database. The Thunk implementation
only support UseDatabase is TRUE.
@param Handle The Handle buffer.
@param HandleCount The number of Handle in the Handle Buffer. It must be 1 for this implementation.
@param Packet The pointer to data buffer containing IFR and String package. Not supported.
@param CallbackHandle Not supported.
@param NvMapOverride The buffer is used only when there is no NV variable to define the
current settings and the caller needs to provide to the browser the
current settings for the the "fake" NV variable. If used, no saving of
an NV variable is possbile. This parameter is also ignored if Handle is NULL.
@retval EFI_SUCCESS If the Formset is displayed correctly.
@retval EFI_UNSUPPORTED If UseDatabase is FALSE or HandleCount is not 1.
@retval EFI_INVALID_PARAMETER If the *Handle passed in is not found in the database.
**/
EFI_STATUS
EFIAPI
ThunkSendForm (
@ -75,6 +95,26 @@ ThunkSendForm (
return Status;
}
/**
Rountine used to display a generic dialog interface and return
the Key or Input from user input.
@param NumberOfLines The number of lines for the dialog box.
@param HotKey Defines if a single character is parsed (TRUE) and returned in KeyValue
or if a string is returned in StringBuffer.
@param MaximumStringSize The maximum size in bytes of a typed-in string.
@param StringBuffer On return contains the typed-in string if HotKey
is FALSE.
@param KeyValue The EFI_INPUT_KEY value returned if HotKey is TRUE.
@param String The pointer to the first string in the list of strings
that comprise the dialog box.
@param ... A series of NumberOfLines text strings that will be used
to construct the dialog box.
@retval EFI_SUCCESS The dialog is created successfully and user interaction was received.
@retval EFI_DEVICE_ERROR The user typed in an ESC.
@retval EFI_INVALID_PARAMETER One of the parameters was invalid.(StringBuffer == NULL && HotKey == FALSE).
**/
EFI_STATUS
EFIAPI
ThunkCreatePopUp (

View File

@ -24,9 +24,9 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "HiiDatabase.h"
#include "UefiIfrParser.h"
#include "UefiIfrDefault.h"
#include "HiiDatabase.h"
//
// Extern Variables
@ -36,216 +36,6 @@ extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;
extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;
extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;
extern EFI_GUID gZeroGuid;
/**
Fetch the Ifr binary data of a FormSet.
@param Handle PackageList Handle
@param FormSetGuid GUID of a formset. If not specified (NULL or zero
GUID), take the first FormSet found in package
list.
@param BinaryLength The length of the FormSet IFR binary.
@param 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
)
{
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
UINTN BufferSize;
UINT8 *Package;
UINT8 *OpCodeData;
UINT32 Offset;
UINT32 Offset2;
BOOLEAN ReturnDefault;
UINT32 PackageListLength;
EFI_HII_PACKAGE_HEADER PackageHeader;
OpCodeData = NULL;
Package = NULL;
ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;
//
// if FormSetGuid is NULL or zero GUID, return first FormSet in the package list
//
if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {
ReturnDefault = TRUE;
} else {
ReturnDefault = FALSE;
}
//
// Get HII PackageList
//
BufferSize = 0;
HiiPackageList = NULL;
Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
if (Status == EFI_BUFFER_TOO_SMALL) {
HiiPackageList = AllocatePool (BufferSize);
ASSERT (HiiPackageList != NULL);
Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &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;
CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
while (Offset < PackageListLength) {
Package = ((UINT8 *) HiiPackageList) + Offset;
CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
//
// Search FormSet 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) {
//
// Check whether return default FormSet
//
if (ReturnDefault) {
break;
}
//
// FormSet GUID is specified, check it
//
if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
break;
}
}
Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
}
if (Offset2 < PackageHeader.Length) {
//
// Target formset found
//
break;
}
}
Offset += PackageHeader.Length;
}
if (Offset >= PackageListLength) {
//
// Form package not found in this Package List
//
gBS->FreePool (HiiPackageList);
return EFI_NOT_FOUND;
}
if (ReturnDefault && FormSetGuid != NULL) {
//
// Return the default FormSet GUID
//
CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));
}
//
// To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
// in this FormSet; So, here just simply copy the data from start of a FormSet to the end
// of the Form Package.
//
*BinaryLength = PackageHeader.Length - Offset2;
*BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);
gBS->FreePool (HiiPackageList);
if (*BinaryData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
return EFI_SUCCESS;
}
/**
Initialize the internal data structure of a FormSet.
@param Handle PackageList Handle
@param FormSetGuid GUID of a formset. If not specified (NULL or zero
GUID), take the first FormSet found in package
list.
@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
InitializeFormSet (
IN EFI_HII_HANDLE Handle,
IN OUT EFI_GUID *FormSetGuid,
OUT FORM_BROWSER_FORMSET *FormSet
)
{
EFI_STATUS Status;
EFI_HANDLE DriverHandle;
Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);
if (EFI_ERROR (Status)) {
return Status;
}
FormSet->HiiHandle = Handle;
CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));
//
// Retrieve ConfigAccess Protocol associated with this HiiPackageList
//
Status = mHiiDatabase->GetPackageListHandle (mHiiDatabase, 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;
}
//
// Parse the IFR binary OpCodes
//
Status = ParseOpCodes (FormSet);
if (EFI_ERROR (Status)) {
return Status;
}
return Status;
}
/**
Set the data position at Offset with Width in Node->Buffer based
the value passed in.
@ -276,6 +66,11 @@ SetNodeBuffer (
/**
Reset Question to its default value.
Note Framework 0.92's HII Implementation does not support for default value for these opcodes:
EFI_IFR_ORDERED_LIST_OP:
EFI_IFR_PASSWORD_OP:
EFI_IFR_STRING_OP:
@param FormSet FormSet data structure.
@param DefaultId The Class of the default.
@ -330,22 +125,10 @@ GetQuestionDefault (
Default = QUESTION_DEFAULT_FROM_LINK (Link);
if (Default->DefaultId == DefaultId) {
if (Default->ValueExpression != NULL) {
//
// Default is provided by an Expression, evaluate it
//
Status = EvaluateExpression (FormSet, Form, Default->ValueExpression);
if (EFI_ERROR (Status)) {
return Status;
}
CopyMem (HiiValue, &Default->ValueExpression->Result, sizeof (EFI_HII_VALUE));
} else {
//
// Default value is embedded in EFI_IFR_DEFAULT
//
CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));
}
//
// Default value is embedded in EFI_IFR_DEFAULT
//
CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));
SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);
return EFI_SUCCESS;
@ -580,41 +363,30 @@ GetBufferTypeDefaultId (
**/
EFI_STATUS
UefiIfrGetBufferTypeDefaults (
IN EFI_HII_HANDLE UefiHiiHandle,
IN HII_THUNK_CONTEXT *ThunkContext,
OUT LIST_ENTRY **UefiDefaults
)
{
FORM_BROWSER_FORMSET *FormSet;
EFI_GUID FormSetGuid;
LIST_ENTRY *DefaultLink;
FORMSET_DEFAULTSTORE *DefaultStore;
EFI_STATUS Status;
ASSERT (UefiDefaults != NULL);
FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
ASSERT (FormSet != NULL);
CopyGuid (&FormSetGuid, &gZeroGuid);
Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);
ASSERT_EFI_ERROR (Status);
*UefiDefaults = AllocateZeroPool (sizeof (LIST_ENTRY));
ASSERT (UefiDefaults != NULL);
InitializeListHead (*UefiDefaults);
DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);
while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {
DefaultLink = GetFirstNode (&ThunkContext->FormSet->DefaultStoreListHead);
while (!IsNull (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink)) {
DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);
Status = GetBufferTypeDefaultId (DefaultStore, FormSet, *UefiDefaults);
Status = GetBufferTypeDefaultId (DefaultStore, ThunkContext->FormSet, *UefiDefaults);
ASSERT_EFI_ERROR (Status);
DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);
DefaultLink = GetNextNode (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink);
}
DestroyFormSet (FormSet);
return EFI_SUCCESS;
}
@ -642,6 +414,7 @@ EFI_STATUS
UefiDefaultsToFwDefaults (
IN LIST_ENTRY *ListHead,
IN UINTN DefaultMask,
IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId,
OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList
)
{
@ -713,9 +486,9 @@ UefiDefaultsToFwDefaults (
//
// In UEFI, 0 is defined to be invalid for EFI_IFR_VARSTORE.VarStoreId.
// So the default storage of Var Store in VFR from a Framework module
// should be translated to 0x0001 (RESERVED_VARSTORE_ID).
// should be translated to 0x0001 (FRAMEWORK_RESERVED_VARSTORE_ID).
//
if (Node->StoreId == RESERVED_VARSTORE_ID) {
if (Node->StoreId == UefiFormSetDefaultVarStoreId) {
Pack->VariableId = 0;
} else {
Pack->VariableId = Node->StoreId;

View File

@ -45,8 +45,8 @@ typedef struct {
**/
EFI_STATUS
UefiIfrGetBufferTypeDefaults (
EFI_HII_HANDLE UefiHiiHandle,
LIST_ENTRY **UefiDefaults
IN HII_THUNK_CONTEXT *ThunkContext,
OUT LIST_ENTRY **UefiDefaults
);
/**
@ -73,6 +73,7 @@ EFI_STATUS
UefiDefaultsToFwDefaults (
IN LIST_ENTRY *UefiIfrDefaults,
IN UINTN DefaultMask,
IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId,
OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList
);

View File

@ -1,6 +1,12 @@
/** @file
Function and Macro defintions for IFR parsing. To get the default value from IFR package, the IFR
opcode needs to be parsed. Most of code is taken from MdeModulePkg\Universal\SetupBrowserDxe\IfrParse.c.
This parser is simplified from the origianl IfrParser.c in the following way:
1) All data structure definition that have nothing to do with IFR Default value scanning (
required to implement Framework HII's GetDefaultImage ()) is removed.
2) Ignore the IFR opcode which is invalid for Form Package
generated using Framework VFR file.
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
@ -16,13 +22,6 @@
#ifndef _HII_THUNK_UEFI_IFR_PARSER_
#define _HII_THUNK_UEFI_IFR_PARSER_
#include <PiDxe.h>
#include <Protocol/Print.h>
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/HiiConfigRouting.h>
#include <Protocol/HiiDatabase.h>
#include <Protocol/HiiString.h>
//
// IFR relative definition
@ -44,6 +43,34 @@
extern EFI_GUID gTianoHiiIfrGuid;
#define ONE_OF_OPTION_MAP_ENTRY_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP_ENTRY, Link, ONE_OF_OPTION_MAP_ENTRY_SIGNATURE)
#define ONE_OF_OPTION_MAP_ENTRY_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'M', 'E')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
UINT16 FwKey;
EFI_IFR_TYPE_VALUE Value;
} ONE_OF_OPTION_MAP_ENTRY;
#define ONE_OF_OPTION_MAP_FROM_LINK(Record) CR(Record, ONE_OF_OPTION_MAP, Link, ONE_OF_OPTION_MAP_SIGNATURE)
#define ONE_OF_OPTION_MAP_SIGNATURE EFI_SIGNATURE_32 ('O', 'O', 'O', 'M')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
UINT16 VarStoreId;
UINT8 ValueType; //EFI_IFR_TYPE_NUM_*
EFI_QUESTION_ID QuestionId;
LIST_ENTRY OneOfOptionMapEntryListHead; //ONE_OF_OPTION_MAP_ENTRY
} ONE_OF_OPTION_MAP;
typedef struct {
UINT8 Type;
@ -52,16 +79,6 @@ typedef struct {
#define NAME_VALUE_NODE_SIGNATURE EFI_SIGNATURE_32 ('N', 'V', 'S', 'T')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
CHAR16 *Name;
CHAR16 *Value;
CHAR16 *EditValue;
} NAME_VALUE_NODE;
#define NAME_VALUE_NODE_FROM_LINK(a) CR (a, NAME_VALUE_NODE, Link, NAME_VALUE_NODE_SIGNATURE)
#define FORMSET_STORAGE_SIGNATURE EFI_SIGNATURE_32 ('F', 'S', 'T', 'G')
typedef struct {
@ -75,21 +92,15 @@ typedef struct {
CHAR16 *Name; // For EFI_IFR_VARSTORE
UINT16 Size;
UINT8 *Buffer;
UINT8 *EditBuffer; // Edit copy for Buffer Storage
LIST_ENTRY NameValueListHead; // List of NAME_VALUE_NODE
UINT32 Attributes; // For EFI_IFR_VARSTORE_EFI: EFI Variable attribute
CHAR16 *ConfigHdr; // <ConfigHdr>
CHAR16 *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>
UINTN ElementCount; // Number of <RequestElement> in the <ConfigRequest>
UINTN SpareStrLen; // Spare length of ConfigRequest string buffer
} FORMSET_STORAGE;
#define FORMSET_STORAGE_FROM_LINK(a) CR (a, FORMSET_STORAGE, Link, FORMSET_STORAGE_SIGNATURE)
#if 0
#define EXPRESSION_OPCODE_SIGNATURE EFI_SIGNATURE_32 ('E', 'X', 'O', 'P')
typedef struct {
@ -133,6 +144,7 @@ typedef struct {
} FORM_EXPRESSION;
#define FORM_EXPRESSION_FROM_LINK(a) CR (a, FORM_EXPRESSION, Link, FORM_EXPRESSION_SIGNATURE)
#endif
#define QUESTION_DEFAULT_SIGNATURE EFI_SIGNATURE_32 ('Q', 'D', 'F', 'T')
@ -143,7 +155,6 @@ typedef struct {
UINT16 DefaultId;
EFI_HII_VALUE Value; // Default value
FORM_EXPRESSION *ValueExpression; // Not-NULL indicates default value is provided by EFI_IFR_VALUE
} QUESTION_DEFAULT;
#define QUESTION_DEFAULT_FROM_LINK(a) CR (a, QUESTION_DEFAULT, Link, QUESTION_DEFAULT_SIGNATURE)
@ -159,7 +170,9 @@ typedef struct {
EFI_HII_VALUE Value;
EFI_IMAGE_ID ImageId;
#if 0
FORM_EXPRESSION *SuppressExpression; // Non-NULL indicates nested inside of SuppressIf
#endif
} QUESTION_OPTION;
#define QUESTION_OPTION_FROM_LINK(a) CR (a, QUESTION_OPTION, Link, QUESTION_OPTION_SIGNATURE)
@ -188,10 +201,17 @@ typedef struct {
EFI_STRING_ID VarName;
UINT16 VarOffset;
} VarStoreInfo;
#if 0
CHAR16 *UnicodeVarName;
#endif
UINT16 StorageWidth;
UINT8 QuestionFlags;
#if 0
CHAR16 *VariableName; // Name/Value or EFI Variable name
CHAR16 *BlockName; // Buffer storage block name: "OFFSET=...WIDTH=..."
#endif
EFI_HII_VALUE HiiValue; // Edit copy for checkbox, numberic, oneof
UINT8 *BufferValue; // Edit copy for string, password, orderedlist
@ -219,7 +239,9 @@ typedef struct {
//
// Get from IFR parsing
//
#if 0
FORM_EXPRESSION *ValueExpression; // nested EFI_IFR_VALUE, provide Question value and indicate Question is ReadOnly
#endif
LIST_ENTRY DefaultListHead; // nested EFI_IFR_DEFAULT list (QUESTION_DEFAULT), provide default values
LIST_ENTRY OptionListHead; // nested EFI_IFR_ONE_OF_OPTION list (QUESTION_OPTION)
@ -227,10 +249,12 @@ typedef struct {
UINT8 RefreshInterval; // nested EFI_IFR_REFRESH, refresh interval(in seconds) for Question value, 0 means no refresh
BOOLEAN InSubtitle; // nesting inside of EFI_IFR_SUBTITLE
#if 0
LIST_ENTRY InconsistentListHead;// nested inconsistent expression list (FORM_EXPRESSION)
LIST_ENTRY NoSubmitListHead; // nested nosubmit expression list (FORM_EXPRESSION)
FORM_EXPRESSION *GrayOutExpression; // nesting inside of GrayOutIf
FORM_EXPRESSION *SuppressExpression; // nesting inside of SuppressIf
#endif
} FORM_BROWSER_STATEMENT;
@ -247,7 +271,9 @@ typedef struct {
EFI_IMAGE_ID ImageId;
#if 0
LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)
#endif
LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT)
} FORM_BROWSER_FORM;
@ -267,9 +293,6 @@ typedef struct {
typedef struct {
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN IfrBinaryLength;
UINT8 *IfrBinaryData;
@ -282,21 +305,25 @@ typedef struct {
EFI_IMAGE_ID ImageId;
FORM_BROWSER_STATEMENT *StatementBuffer; // Buffer for all Statements and Questions
#if 0
EXPRESSION_OPCODE *ExpressionBuffer; // Buffer for all Expression OpCode
#endif
LIST_ENTRY StorageListHead; // Storage list (FORMSET_STORAGE)
LIST_ENTRY DefaultStoreListHead; // DefaultStore list (FORMSET_DEFAULTSTORE)
LIST_ENTRY FormListHead; // Form list (FORM_BROWSER_FORM)
LIST_ENTRY OneOfOptionMapListHead; //ONE_OF_OPTION_MAP
UINT16 MaxQuestionId;
EFI_VARSTORE_ID DefaultVarStoreId;
UINTN NumberOfStatement;
} FORM_BROWSER_FORMSET;
EFI_STATUS
EvaluateExpression (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form,
IN OUT FORM_EXPRESSION *Expression
);
EFI_STATUS
ParseOpCodes (
IN FORM_BROWSER_FORMSET *FormSet

View File

@ -16,11 +16,19 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "HiiDatabase.h"
#include "HiiHandle.h"
#include <Library/DebugLib.h>
EFI_GUID gFrameworkHiiCompatbilityGuid = EFI_IFR_FRAMEWORK_GUID;
EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;
CONST EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
/**
Find the corressponding UEFI HII Handle from a Framework HII Handle given.
@param Private The HII Thunk Module Private context.
@param FwHiiHandle The Framemwork HII Handle.
@return NULL If Framework HII Handle is invalid.
@return The corresponding UEFI HII Handle.
**/
EFI_HII_HANDLE
FwHiiHandleToUefiHiiHandle (
IN CONST HII_THUNK_PRIVATE_DATA *Private,
@ -42,6 +50,15 @@ FwHiiHandleToUefiHiiHandle (
}
/**
Find the corressponding HII Thunk Context from a Framework HII Handle given.
@param Private The HII Thunk Module Private context.
@param FwHiiHandle The Framemwork HII Handle.
@return NULL If Framework HII Handle is invalid.
@return The corresponding HII Thunk Context.
**/
HII_THUNK_CONTEXT *
FwHiiHandleToThunkContext (
IN CONST HII_THUNK_PRIVATE_DATA *Private,
@ -67,6 +84,15 @@ FwHiiHandleToThunkContext (
return NULL;
}
/**
Find the corressponding HII Thunk Context from a UEFI HII Handle given.
@param Private The HII Thunk Module Private context.
@param UEFIHiiHandle The UEFI HII Handle.
@return NULL If UEFI HII Handle is invalid.
@return The corresponding HII Thunk Context.
**/
HII_THUNK_CONTEXT *
UefiHiiHandleToThunkContext (
IN CONST HII_THUNK_PRIVATE_DATA *Private,
@ -90,6 +116,15 @@ UefiHiiHandleToThunkContext (
return NULL;
}
/**
Find the corressponding HII Thunk Context from a Tag GUID.
@param Private The HII Thunk Module Private context.
@param Guid The Tag GUID.
@return NULL No HII Thunk Context matched the Tag GUID.
@return The corresponding HII Thunk Context.
**/
HII_THUNK_CONTEXT *
TagGuidToIfrPackThunkContext (
IN CONST HII_THUNK_PRIVATE_DATA *Private,
@ -115,7 +150,13 @@ TagGuidToIfrPackThunkContext (
}
/**
Clean up the HII Thunk Context for a UEFI HII Handle.
@param Private The HII Thunk Module Private context.
@param UEFIHiiHandle The UEFI HII Handle.
**/
VOID
DestroyThunkContextForUefiHiiHandle (
IN HII_THUNK_PRIVATE_DATA *Private,
@ -164,13 +205,18 @@ CreateThunkContextForUefiHiiHandle (
CopyGuid(&ThunkContext->TagGuid, &PackageGuid);
InitializeListHead (&ThunkContext->QuestionIdMapListHead);
InitializeListHead (&ThunkContext->OneOfOptionMapListHead);
return ThunkContext;
}
/**
Get the number of HII Package for a Package type.
@param PackageListHeader The Package List.
@param PackageType The Package Type.
@return The number of Package for given type.
**/
UINTN
GetPackageCountByType (
IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,
@ -194,28 +240,13 @@ GetPackageCountByType (
return Count;
}
LIST_ENTRY *
GetOneOfOptionMapEntryListHead (
IN CONST HII_THUNK_CONTEXT *ThunkContext,
IN UINT16 QuestionId
)
{
LIST_ENTRY *Link;
ONE_OF_OPTION_MAP *Map;
/**
Get the Form Package from a Framework Package List.
Link = GetFirstNode (&ThunkContext->OneOfOptionMapListHead);
while (!IsNull (&ThunkContext->OneOfOptionMapListHead, Link)) {
Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);
if (QuestionId == Map->QuestionId) {
return &Map->OneOfOptionMapEntryListHead;
}
Link = GetNextNode (&ThunkContext->OneOfOptionMapListHead, Link);
}
return NULL;
}
@param Packages Framework Package List.
@return The Form Package Header found.
**/
EFI_HII_PACKAGE_HEADER *
GetIfrPackage (
IN CONST EFI_HII_PACKAGES *Packages
@ -260,6 +291,15 @@ GetIfrPackage (
return NULL;
}
/**
Get FormSet GUID.
ASSERT if no FormSet Opcode is found.
@param Packages Form Framework Package.
@param FormSetGuid Return the FormSet Guid.
**/
VOID
GetFormSetGuid (
IN EFI_HII_PACKAGE_HEADER *Package,
@ -294,298 +334,18 @@ GetFormSetGuid (
}
/**
Creat a Thunk Context.
VOID
GetAttributesOfFirstFormSet (
IN OUT HII_THUNK_CONTEXT *ThunkContext
)
{
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *List;
EFI_HII_PACKAGE_HEADER *Package;
UINTN Size;
EFI_IFR_OP_HEADER *OpCode;
UINTN Offset;
EFI_IFR_GUID_CLASS *Class;
EFI_IFR_FORM_SET *FormSet;
EFI_IFR_GUID_SUBCLASS *SubClass;
Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);
ASSERT_EFI_ERROR (Status);
//
// There must be at least one EFI_HII_PACKAGE_FORMS in the package list.
//
ASSERT (GetPackageCountByType (List, EFI_HII_PACKAGE_FORMS) >= 1);
//
// Skip the package list header.
//
Package = (EFI_HII_PACKAGE_HEADER *) (List + 1);
while (Package->Type != EFI_HII_PACKAGE_END) {
if (Package->Type == EFI_HII_PACKAGE_FORMS) {
//
// Skip the package header
//
Offset = sizeof (EFI_HII_PACKAGE_HEADER);
while (Offset < Package->Length) {
OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);
switch (OpCode->OpCode) {
case EFI_IFR_FORM_SET_OP:
FormSet = (EFI_IFR_FORM_SET *) OpCode;
ThunkContext->FormSetTitle = FormSet->FormSetTitle;
ThunkContext->FormSetHelp = FormSet->Help;
break;
case EFI_IFR_GUID_OP:
Class = (EFI_IFR_GUID_CLASS*) OpCode;
if (CompareGuid ((EFI_GUID *)(VOID *)&Class->Guid, &gTianoHiiIfrGuid)) {
Class = (EFI_IFR_GUID_CLASS *) OpCode;
switch (Class->ExtendOpCode) {
case EFI_IFR_EXTEND_OP_CLASS:
ThunkContext->FormSetClass = Class->Class;
break;
case EFI_IFR_EXTEND_OP_SUBCLASS:
SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;
ThunkContext->FormSetSubClass = SubClass->SubClass;
break;
default:
break;
}
}
break;
default:
break;
}
Offset += OpCode->Length;
}
//
// The attributes of first FormSet is ready now.
//
FreePool (List);
return;
break;
}
Package = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) Package + Package->Length);
}
}
EFI_STATUS
CreateQuestionIdMap (
IN OUT HII_THUNK_CONTEXT *ThunkContext
)
{
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *List;
EFI_HII_PACKAGE_HEADER *Package;
UINTN Size;
EFI_IFR_OP_HEADER *OpCode;
UINTN Offset;
QUESTION_ID_MAP *IdMap;
EFI_IFR_VARSTORE *VarStore;
EFI_IFR_FORM_SET *FormSet;
EFI_IFR_QUESTION_HEADER *Question;
LIST_ENTRY *QuestionIdMapEntryListHead;
LIST_ENTRY *OneOfOptinMapEntryListHead;
QUESTION_ID_MAP_ENTRY *IdMapEntry;
EFI_IFR_GUID_OPTIONKEY *OptionMap;
ONE_OF_OPTION_MAP *OneOfOptionMap;
ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;
EFI_IFR_GUID_CLASS *Class;
EFI_IFR_GUID_SUBCLASS *SubClass;
UINT8 OneOfType;
EFI_IFR_ONE_OF *OneOfOpcode;
//
// Set to a invalid value.
//
OneOfType = (UINT8) -1;
Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get all VarStoreId and build the the QuestionId map.
// EFI_IFR_QUESTION_HEADER.VarStoreInfo.VarOffset -> Framework Question ID
// EFI_IFR_QUESTION_HEADER.QuestionId -> UEFI Question ID
//
//
// Skip the package list header.
//
Package = (EFI_HII_PACKAGE_HEADER *) (List + 1);
while (Package->Type != EFI_HII_PACKAGE_END) {
if (Package->Type == EFI_HII_PACKAGE_FORMS) {
//
// Skip the package header
//
Offset = sizeof (EFI_HII_PACKAGE_HEADER);
while (Offset < Package->Length) {
OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);
switch (OpCode->OpCode) {
case EFI_IFR_FORM_SET_OP:
FormSet = (EFI_IFR_FORM_SET *) OpCode;
ThunkContext->FormSetTitle = FormSet->FormSetTitle;
ThunkContext->FormSetHelp = FormSet->Help;
break;
case EFI_IFR_VARSTORE_OP:
//
// IFR built from Framework VFR only has UEFI Buffer Type Storage
//
VarStore = (EFI_IFR_VARSTORE *) OpCode;
IdMap = AllocateZeroPool (sizeof (QUESTION_ID_MAP));
ASSERT (IdMap != NULL);
IdMap->Signature = QUESTION_ID_MAP_SIGNATURE;
IdMap->VarStoreId = VarStore->VarStoreId;
IdMap->VarSize = VarStore->Size;
InitializeListHead (&IdMap->MapEntryListHead);
InsertTailList (&ThunkContext->QuestionIdMapListHead, &IdMap->Link);
break;
case EFI_IFR_NUMERIC_OP:
case EFI_IFR_CHECKBOX_OP:
case EFI_IFR_ONE_OF_OP:
case EFI_IFR_ORDERED_LIST_OP:
case EFI_IFR_STRING_OP:
//case EFI_IFR_PASSWORD_OP:
Question = (EFI_IFR_QUESTION_HEADER *)(OpCode + 1);
QuestionIdMapEntryListHead = GetMapEntryListHead (ThunkContext, Question->VarStoreId);
if (QuestionIdMapEntryListHead != NULL) {
//
// If the Question is using Buffer (EFI_IFR_VARSTORE_OP) type VarStore.
//
IdMapEntry = AllocateZeroPool (sizeof (QUESTION_ID_MAP_ENTRY));
ASSERT (IdMapEntry != NULL);
IdMapEntry->FwQId = Question->VarStoreInfo.VarOffset;
IdMapEntry->UefiQid = Question->QuestionId;
IdMapEntry->Signature = QUESTION_ID_MAP_ENTRY_SIGNATURE;
InsertTailList (QuestionIdMapEntryListHead, &IdMapEntry->Link);
}
if (OpCode->OpCode == EFI_IFR_ONE_OF_OP) {
OneOfOpcode = (EFI_IFR_ONE_OF *) OpCode;
OneOfType = OneOfOpcode->Flags & EFI_IFR_NUMERIC_SIZE;
}
break;
case EFI_IFR_GUID_OP:
OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCode;
if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &gFrameworkHiiCompatbilityGuid)) {
if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) {
OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (ThunkContext, OptionMap->QuestionId);
if (OneOfOptinMapEntryListHead == NULL) {
OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));
ASSERT (OneOfOptionMap != NULL);
OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;
OneOfOptionMap->QuestionId = OptionMap->QuestionId;
//
// Make sure OneOfType is initialized.
//
ASSERT (OneOfType != (UINT8) -1);
OneOfOptionMap->ValueType = OneOfType;
InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);
OneOfOptinMapEntryListHead = &OneOfOptionMap->OneOfOptionMapEntryListHead;
InsertTailList (&ThunkContext->OneOfOptionMapListHead, &OneOfOptionMap->Link);
}
OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));
ASSERT (OneOfOptionMapEntry != NULL);
OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;
OneOfOptionMapEntry->FwKey = OptionMap->KeyValue;
CopyMem (&OneOfOptionMapEntry->Value, &OptionMap->OptionValue, sizeof (EFI_IFR_TYPE_VALUE));
InsertTailList (OneOfOptinMapEntryListHead, &OneOfOptionMapEntry->Link);
}
} else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &gTianoHiiIfrGuid)) {
Class = (EFI_IFR_GUID_CLASS *) OpCode;
switch (Class->ExtendOpCode) {
case EFI_IFR_EXTEND_OP_CLASS:
ThunkContext->FormSetClass = Class->Class;
break;
case EFI_IFR_EXTEND_OP_SUBCLASS:
SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;
ThunkContext->FormSetSubClass = SubClass->SubClass;
break;
default:
break;
}
}
break;
default:
break;
}
Offset += OpCode->Length;
}
//
// Only Form Package is in a Package List.
//
break;
}
Package = (EFI_HII_PACKAGE_HEADER *) (UINT8 *) Package + Package->Length;
}
FreePool (List);
return EFI_SUCCESS;
}
LIST_ENTRY *
GetMapEntryListHead (
IN CONST HII_THUNK_CONTEXT *ThunkContext,
IN UINT16 VarStoreId
)
{
LIST_ENTRY *Link;
QUESTION_ID_MAP *Map;
Link = GetFirstNode (&ThunkContext->QuestionIdMapListHead);
while (!IsNull (&ThunkContext->QuestionIdMapListHead, Link)) {
Map = QUESTION_ID_MAP_FROM_LINK (Link);
if (VarStoreId == Map->VarStoreId) {
return &Map->MapEntryListHead;
}
Link = GetNextNode (&ThunkContext->QuestionIdMapListHead, Link);
}
return NULL;
}
ASSERT if no FormSet Opcode is found.
@param Private The HII Thunk Private Context.
@param StringPackageCount The String package count.
@param FormSetGuid The IFR Package count.
@return A newly created Thunk Context.
@retval NULL No resource to create a new Thunk Context.
**/
HII_THUNK_CONTEXT *
CreateThunkContext (
IN HII_THUNK_PRIVATE_DATA *Private,
@ -607,14 +367,16 @@ CreateThunkContext (
return NULL;
}
InitializeListHead (&ThunkContext->QuestionIdMapListHead);
InitializeListHead (&ThunkContext->OneOfOptionMapListHead);
return ThunkContext;
}
/**
Destroy the Thunk Context and free up all resource.
@param ThunkContext The HII Thunk Private Context to be freed.
**/
VOID
DestroyThunkContext (
IN HII_THUNK_CONTEXT *ThunkContext
@ -624,76 +386,284 @@ DestroyThunkContext (
FreeHiiHandle (ThunkContext->FwHiiHandle);
DestroyQuestionIdMap (&ThunkContext->QuestionIdMapListHead);
DestoryOneOfOptionMap (&ThunkContext->OneOfOptionMapListHead);
RemoveEntryList (&ThunkContext->Link);
if (ThunkContext->FormSet != NULL) {
DestroyFormSet (ThunkContext->FormSet);
}
FreePool (ThunkContext);
}
/**
Get the FormSet's Default Varstore ID based on the rule (Descending Priority):
1) Var Store ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01).
2) First Var Store ID.
@param FormSet The Form Set.
**/
VOID
DestroyQuestionIdMap (
IN LIST_ENTRY *QuestionIdMapListHead
GetFormsetDefaultVarstoreId (
IN OUT FORM_BROWSER_FORMSET * FormSet
)
{
QUESTION_ID_MAP *IdMap;
QUESTION_ID_MAP_ENTRY *IdMapEntry;
LIST_ENTRY *Link;
LIST_ENTRY *Link2;
LIST_ENTRY *StorageList;
FORMSET_STORAGE *Storage;
EFI_VARSTORE_ID FirstVarStoreId;
while (!IsListEmpty (QuestionIdMapListHead)) {
Link = GetFirstNode (QuestionIdMapListHead);
IdMap = QUESTION_ID_MAP_FROM_LINK (Link);
//
// VarStoreId 0 is invalid in UEFI IFR.
//
FormSet->DefaultVarStoreId = 0;
StorageList = GetFirstNode (&FormSet->StorageListHead);
while (!IsListEmpty (&IdMap->MapEntryListHead)) {
Link2 = GetFirstNode (&IdMap->MapEntryListHead);
IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link2);
while (!IsNull (&FormSet->StorageListHead, StorageList)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
RemoveEntryList (Link2);
DEBUG ((EFI_D_INFO, "FormSet %g: Found Varstore ID %x\n", &FormSet->Guid, Storage->VarStoreId));
FreePool (IdMapEntry);
if (Storage->VarStoreId == FRAMEWORK_RESERVED_VARSTORE_ID) {
FormSet->DefaultVarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;
break;
}
RemoveEntryList (Link);
FreePool (IdMap);
StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);
}
if (FormSet->DefaultVarStoreId != FRAMEWORK_RESERVED_VARSTORE_ID) {
StorageList = GetFirstNode (&FormSet->StorageListHead);
if (!IsNull (&FormSet->StorageListHead, StorageList)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
FirstVarStoreId = Storage->VarStoreId;
}
}
DEBUG_CODE_BEGIN ();
if (FormSet->DefaultVarStoreId == 0) {
DEBUG ((EFI_D_INFO, "FormSet %g: No Varstore Found\n", &FormSet->Guid));
} else {
DEBUG ((EFI_D_INFO, "FormSet %g: Default Varstore ID is %x\n", &FormSet->Guid, FormSet->DefaultVarStoreId));
}
DEBUG_CODE_END ();
return;
}
VOID
DestoryOneOfOptionMap (
IN LIST_ENTRY *OneOfOptionMapListHead
/**
Fetch the Ifr binary data of a FormSet.
@param Handle PackageList Handle
@param FormSetGuid GUID of a formset. If not specified (NULL or zero
GUID), take the first FormSet found in package
list.
@param BinaryLength The length of the FormSet IFR binary.
@param 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
)
{
ONE_OF_OPTION_MAP *Map;
ONE_OF_OPTION_MAP_ENTRY *MapEntry;
LIST_ENTRY *Link;
LIST_ENTRY *Link2;
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
UINTN BufferSize;
UINT8 *Package;
UINT8 *OpCodeData;
UINT32 Offset;
UINT32 Offset2;
BOOLEAN ReturnDefault;
UINT32 PackageListLength;
EFI_HII_PACKAGE_HEADER PackageHeader;
while (!IsListEmpty (OneOfOptionMapListHead)) {
Link = GetFirstNode (OneOfOptionMapListHead);
Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);
OpCodeData = NULL;
Package = NULL;
ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;
while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {
Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);
MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);
//
// if FormSetGuid is NULL or zero GUID, return first FormSet in the package list
//
if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {
ReturnDefault = TRUE;
} else {
ReturnDefault = FALSE;
}
RemoveEntryList (Link2);
//
// Get HII PackageList
//
BufferSize = 0;
HiiPackageList = NULL;
Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
if (Status == EFI_BUFFER_TOO_SMALL) {
HiiPackageList = AllocatePool (BufferSize);
ASSERT (HiiPackageList != NULL);
FreePool (MapEntry);
Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &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;
CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
while (Offset < PackageListLength) {
Package = ((UINT8 *) HiiPackageList) + Offset;
CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
//
// Search FormSet 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) {
//
// Check whether return default FormSet
//
if (ReturnDefault) {
break;
}
//
// FormSet GUID is specified, check it
//
if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
break;
}
}
Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
}
if (Offset2 < PackageHeader.Length) {
//
// Target formset found
//
break;
}
}
RemoveEntryList (Link);
FreePool (Map);
Offset += PackageHeader.Length;
}
if (Offset >= PackageListLength) {
//
// Form package not found in this Package List
//
gBS->FreePool (HiiPackageList);
return EFI_NOT_FOUND;
}
if (ReturnDefault && FormSetGuid != NULL) {
//
// Return the default FormSet GUID
//
CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));
}
//
// To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
// in this FormSet; So, here just simply copy the data from start of a FormSet to the end
// of the Form Package.
//
*BinaryLength = PackageHeader.Length - Offset2;
*BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);
gBS->FreePool (HiiPackageList);
if (*BinaryData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
return EFI_SUCCESS;
}
/**
Initialize the internal data structure of a FormSet.
@param Handle PackageList Handle
@param FormSetGuid GUID of a formset. If not specified (NULL or zero
GUID), take the first FormSet found in package
list.
@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
InitializeFormSet (
IN EFI_HII_HANDLE Handle,
IN OUT EFI_GUID *FormSetGuid,
OUT FORM_BROWSER_FORMSET *FormSet
)
{
EFI_STATUS Status;
Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);
if (EFI_ERROR (Status)) {
return Status;
}
FormSet->HiiHandle = Handle;
CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));
//
// Parse the IFR binary OpCodes
//
Status = ParseOpCodes (FormSet);
if (EFI_ERROR (Status)) {
return Status;
}
GetFormsetDefaultVarstoreId (FormSet);
return Status;
}
/**
Parse the Form Package and build a FORM_BROWSER_FORMSET structure.
@param UefiHiiHandle PackageList Handle
@return A pointer to FORM_BROWSER_FORMSET.
**/
FORM_BROWSER_FORMSET *
ParseFormSet (
IN EFI_HII_HANDLE UefiHiiHandle
)
{
FORM_BROWSER_FORMSET *FormSet;
EFI_GUID FormSetGuid;
EFI_STATUS Status;
FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
ASSERT (FormSet != NULL);
CopyGuid (&FormSetGuid, &gZeroGuid);
Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);
ASSERT_EFI_ERROR (Status);
return FormSet;
}

View File

@ -96,12 +96,6 @@ DestroyThunkContext (
IN HII_THUNK_CONTEXT *ThunkContext
);
VOID
DestroyQuestionIdMap (
IN LIST_ENTRY *QuestionIdMapListHead
);
VOID
DestoryOneOfOptionMap (
IN LIST_ENTRY *OneOfOptionMapListHead
@ -120,4 +114,10 @@ GetIfrPackage (
)
;
FORM_BROWSER_FORMSET *
ParseFormSet (
IN EFI_HII_HANDLE UefiHiiHandle
)
;
#endif