Rename module name from ***To*** to ***On***. AAAOnBBB means this module produce AAA Protocol/PPI based on BBB. This change improves the readability.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7328 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qwang12
2009-01-21 09:47:43 +00:00
parent 96827f1756
commit 4c9c0f719d
44 changed files with 0 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,139 @@
/**@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.
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HII_THUNK_CONFIG_ACCESS_H
#define _HII_THUNK_CONFIG_ACCESS_H
/**
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.
@param Packages The framework package list.
@param ThunkContext The Thunk Layer Handle Mapping Database Entry.
@retval EFI_SUCCESS The Config Access Protocol is installed successfully.
@retval EFI_OUT_RESOURCE There is not enough memory.
**/
EFI_STATUS
InstallDefaultConfigAccessProtocol (
IN CONST EFI_HII_PACKAGES *Packages,
IN OUT HII_THUNK_CONTEXT *ThunkContext
);
VOID
UninstallDefaultConfigAccessProtocol (
IN HII_THUNK_CONTEXT *ThunkContext
);
/**
This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig
so that data can be read from the data storage such as UEFI Variable or module's
customized storage exposed by EFI_FRAMEWORK_CALLBACK.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL
@param Request A null-terminated Unicode string in <ConfigRequest> format. Note that this
includes the routing information as well as the configurable name / value pairs. It is
invalid for this string to be in <MultiConfigRequest> format.
@param Progress On return, points to a character in the Request string. Points to the string's null
terminator if request was successful. Points to the most recent '&' before the first
failing name / value pair (or the beginning of the string if the failure is in the first
name / value pair) if the request was not successful
@param Results A null-terminated Unicode string in <ConfigAltResp> format which has all
values filled in for the names in the Request string. String to be allocated by the called
function.
@retval EFI_INVALID_PARAMETER If there is no Buffer Storage for this Config Access instance.
@retval EFI_SUCCESS The setting is retrived successfully.
@retval !EFI_SUCCESS The error returned by UEFI Get Variable or Framework Form Callback Nvread.
**/
EFI_STATUS
EFIAPI
ThunkExtractConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Request,
OUT EFI_STRING *Progress,
OUT EFI_STRING *Results
);
/**
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.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL
@param Configuration A null-terminated Unicode string in <ConfigResp> format.
@param Progress A pointer to a string filled in with the offset of the most recent '&' before the first
failing name / value pair (or the beginning of the string if the failure is in the first
name / value pair) or the terminating NULL if all was successful.
@retval EFI_INVALID_PARAMETER If there is no Buffer Storage for this Config Access instance.
@retval EFI_SUCCESS The setting is saved successfully.
@retval !EFI_SUCCESS The error returned by UEFI Set Variable or Framework Form Callback Nvwrite.
**/
EFI_STATUS
EFIAPI
ThunkRouteConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Configuration,
OUT EFI_STRING *Progress
);
/**
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.
@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.
@param QuestionId A unique value which is sent to the original exporting driver so that it can identify the
type of data to expect. The format of the data tends to vary based on the opcode that
generated the callback.
@param Type The type of value for the question. See EFI_IFR_TYPE_x in
EFI_IFR_ONE_OF_OPTION.
@param Value A pointer to the data being sent to the original exporting driver. The type is specified
by Type. Type EFI_IFR_TYPE_VALUE is defined in
EFI_IFR_ONE_OF_OPTION.
@param ActionRequest On return, points to the action requested by the callback function. Type
EFI_BROWSER_ACTION_REQUEST is specified in SendForm() in the Form
Browser Protocol.
@retval EFI_UNSUPPORTED If the Framework HII module does not register Callback although it specify the opcode under
focuse to be INTERRACTIVE.
@retval EFI_SUCCESS The callback complete successfully.
@retval !EFI_SUCCESS The error code returned by EFI_FORM_CALLBACK_PROTOCOL.Callback.
**/
EFI_STATUS
EFIAPI
ThunkCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
);
#endif

View File

@@ -0,0 +1,187 @@
/**@file
This file contains the Glyph related function.
Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiDatabase.h"
EFI_NARROW_GLYPH mNarrowGlyphBuffer = {0, 0, {0}};
BOOLEAN mSysFontColorCached = FALSE;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL mSysFGColor = {0};
/**
Translates a Unicode character into the corresponding font glyph.
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.
@retval EFI_SUCCESS It worked.
@retval EFI_NOT_FOUND A glyph for a character was not found.
**/
EFI_STATUS
EFIAPI
HiiGetGlyph (
IN EFI_HII_PROTOCOL *This,
IN CHAR16 *Source,
IN OUT UINT16 *Index,
OUT UINT8 **GlyphBuffer,
OUT UINT16 *BitWidth,
IN OUT UINT32 *InternalStatus
)
{
EFI_STATUS Status;
EFI_IMAGE_OUTPUT *Blt;
EFI_FONT_DISPLAY_INFO *FontInfo;
UINTN Xpos;
UINTN Ypos;
UINTN BaseLine;
if (!mSysFontColorCached) {
//
// Cache the system font's foreground color.
//
Status = mHiiFontProtocol->GetFontInfo (
mHiiFontProtocol,
NULL,
NULL,
&FontInfo,
NULL
);
if (!EFI_ERROR (Status)) {
ASSERT (StrCmp (FontInfo->FontInfo.FontName, L"sysdefault") == 0);
mSysFGColor = FontInfo->ForegroundColor;
FreePool (FontInfo);
mSysFontColorCached = TRUE;
}
}
Blt = NULL;
Status = mHiiFontProtocol->GetGlyph (
mHiiFontProtocol,
Source[*Index],
NULL,
&Blt,
&BaseLine
);
if (!EFI_ERROR (Status) && (Status != EFI_WARN_UNKNOWN_GLYPH)) {
//
// For simplicity, we only handle Narrow Glyph.
//
if (Blt->Height == EFI_GLYPH_HEIGHT && Blt->Width == EFI_GLYPH_WIDTH) {
ZeroMem (&mNarrowGlyphBuffer, sizeof (mNarrowGlyphBuffer));
mNarrowGlyphBuffer.UnicodeWeight = *Source;
for (Ypos = 0; Ypos < EFI_GLYPH_HEIGHT; Ypos++) {
for (Xpos = 0; Xpos < EFI_GLYPH_WIDTH; Xpos++) {
if (CompareMem (&Blt->Image.Bitmap[Ypos * EFI_GLYPH_WIDTH + Xpos], &mSysFGColor, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) == 0) {
mNarrowGlyphBuffer.GlyphCol1[Ypos] = (UINT8) (mNarrowGlyphBuffer.GlyphCol1[Ypos] | (1 << (EFI_GLYPH_WIDTH - 1 - Xpos)));
}
}
}
*GlyphBuffer = (UINT8 *) &mNarrowGlyphBuffer;
*BitWidth = EFI_GLYPH_WIDTH;
*Index += 1;
} else {
Status = EFI_NOT_FOUND;
}
}
if (EFI_ERROR (Status) || (Status == EFI_WARN_UNKNOWN_GLYPH)) {
if (Status == EFI_WARN_UNKNOWN_GLYPH) {
Status = EFI_NOT_FOUND;
}
*GlyphBuffer = NULL;
}
return Status;
}
/**
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.
@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.
@retval EFI_SUCCESS It worked.
@retval EFI_NOT_FOUND A glyph for a character was not found.
**/
EFI_STATUS
EFIAPI
HiiGlyphToBlt (
IN EFI_HII_PROTOCOL *This,
IN UINT8 *GlyphBuffer,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
IN UINTN Count,
IN UINTN Width,
IN UINTN Height,
IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer
)
{
UINTN X;
UINTN Y;
//
// Convert Monochrome bitmap of the Glyph to BltBuffer structure
//
for (Y = 0; Y < Height; Y++) {
for (X = 0; X < Width; X++) {
if ((((EFI_NARROW_GLYPH *) GlyphBuffer)->GlyphCol1[Y] & (1 << X)) != 0) {
BltBuffer[Y * Width * Count + (Width - X - 1)] = Foreground;
} else {
BltBuffer[Y * Width * Count + (Width - X - 1)] = Background;
}
}
}
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,576 @@
/**@file
This file contains the form processing code to the HII database.
Copyright (c) 2006 - 2008 Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiDatabase.h"
#include "UefiIfrDefault.h"
//
// This structure is only intended to be used in this file.
//
#pragma pack(1)
typedef struct {
EFI_HII_PACK_HEADER PackageHeader;
FRAMEWORK_EFI_IFR_FORM_SET FormSet;
FRAMEWORK_EFI_IFR_END_FORM_SET EndFormSet;
} FW_HII_FORMSET_TEMPLATE;
#pragma pack()
FW_HII_FORMSET_TEMPLATE FormSetTemplate = {
{
sizeof (FW_HII_FORMSET_TEMPLATE),
EFI_HII_IFR
},
{
{
FRAMEWORK_EFI_IFR_FORM_SET_OP,
sizeof (FRAMEWORK_EFI_IFR_FORM_SET)
},
{0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}, //Guid
0,
0,
0,
0,
0,
0
},
{
{
FRAMEWORK_EFI_IFR_END_FORM_SET_OP,
sizeof (FRAMEWORK_EFI_IFR_END_FORM_SET)
}
}
};
EFI_GUID mTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;
/**
This thunk module only handles UEFI HII packages. The caller of this function
won<6F><6E>t be able to parse the content. Therefore, it is not supported.
This function will ASSERT and return EFI_UNSUPPORTED.
@param This N.A.
@param Handle N.A.
@param BufferSize N.A.
@param Buffer N.A.
@retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
HiiExportDatabase (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
)
{
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
/**
This function allows a program to extract a form or form package that has
previously been registered with the EFI HII database.
In this thunk module, this function will create a IFR Package with only
one Formset. Effectively, only the GUID of the Formset is updated and return
in this IFR package to caller. This is enable the Framework modules which call
a API named GetStringFromToken. GetStringFromToken retieves a String based on
a String Token from a Package List known only by the Formset GUID.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param Handle Handle on which the form resides. Type FRAMEWORK_EFI_HII_HANDLE is defined in
EFI_HII_PROTOCOL.NewPack() in the Packages section.
@param FormId Ignored by this implementation.
@param BufferLengthTemp On input, the size of input buffer. On output, it
is the size of FW_HII_FORMSET_TEMPLATE.
@param Buffer The buffer designed to receive the form(s).
@retval EFI_SUCCESS Buffer filled with the requested forms. BufferLength
was updated.
@retval EFI_INVALID_PARAMETER The handle is unknown.
@retval EFI_NOT_FOUND A form on the requested handle cannot be found with the
requested FormId.
@retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough to allow the form to be stored.
**/
EFI_STATUS
EFIAPI
HiiGetForms (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN EFI_FORM_ID FormId,
IN OUT UINTN *BufferLengthTemp,
OUT UINT8 *Buffer
)
{
HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT *ThunkContext;
FW_HII_FORMSET_TEMPLATE *OutputFormSet;
if (*BufferLengthTemp < sizeof(FW_HII_FORMSET_TEMPLATE)) {
*BufferLengthTemp = sizeof(FW_HII_FORMSET_TEMPLATE);
return EFI_BUFFER_TOO_SMALL;
}
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
if (ThunkContext == NULL) {
return EFI_NOT_FOUND;
}
OutputFormSet = (FW_HII_FORMSET_TEMPLATE *) Buffer;
CopyMem (OutputFormSet, &FormSetTemplate, sizeof (FW_HII_FORMSET_TEMPLATE));
CopyMem (&OutputFormSet->FormSet.Guid, &ThunkContext->TagGuid, sizeof (EFI_GUID));
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;
}
/**
This function allows a program to extract the NV Image
that represents the default storage image
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param Handle The HII handle from which will have default data retrieved.
UINTN - Mask used to retrieve the default image.
@param DefaultMask EDES_TODO: Add parameter description
@param VariablePackList Callee allocated, tightly-packed, link list data
structure that contain all default varaible packs
from the Hii Database.
@retval EFI_NOT_FOUND If Hii database does not contain any default images.
@retval EFI_INVALID_PARAMETER Invalid input parameter.
@retval EFI_SUCCESS Operation successful.
**/
EFI_STATUS
EFIAPI
HiiGetDefaultImage (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN UINTN DefaultMask,
OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList
)
{
LIST_ENTRY *UefiDefaults;
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT *ThunkContext;
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
if (ThunkContext == NULL) {
ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
UefiDefaults = NULL;
Status = UefiIfrGetBufferTypeDefaults (ThunkContext, &UefiDefaults);
if (EFI_ERROR (Status)) {
goto Done;
}
Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, ThunkContext->FormSet->DefaultVarStoreId, VariablePackList);
Done:
FreeDefaultList (UefiDefaults);
return Status;
}
/**
This function update the FormCallbackProtocol cached in Config Access
private context data.
@param CallbackHandle The EFI Handle on which the Framework FormCallbackProtocol is
installed.
@param ThunkContext The Thunk Context.
@retval EFI_SUCCESS The update is successful.
@retval EFI_INVALID_PARAMETER If no Framework FormCallbackProtocol is located on CallbackHandle.
**/
EFI_STATUS
UpdateFormCallBack (
IN EFI_HANDLE CallbackHandle,
IN CONST HII_THUNK_CONTEXT *ThunkContext
)
{
EFI_STATUS Status;
EFI_FORM_CALLBACK_PROTOCOL *FormCallbackProtocol;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccessProtocol;
EFI_HANDLE UefiDriverHandle;
CONFIG_ACCESS_PRIVATE *ConfigAccessPrivate;
Status = gBS->HandleProtocol (
CallbackHandle,
&gEfiFormCallbackProtocolGuid,
(VOID **) &FormCallbackProtocol
);
if (EFI_ERROR (Status)) {
return EFI_INVALID_PARAMETER;
}
Status = mHiiDatabase->GetPackageListHandle (
mHiiDatabase,
ThunkContext->UefiHiiHandle,
&UefiDriverHandle
);
ASSERT_EFI_ERROR (Status);
Status = gBS->HandleProtocol (
UefiDriverHandle,
&gEfiHiiConfigAccessProtocolGuid,
(VOID **) &ConfigAccessProtocol
);
ASSERT_EFI_ERROR (Status);
ConfigAccessPrivate = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccessProtocol);
ConfigAccessPrivate->FormCallbackProtocol = FormCallbackProtocol;
return EFI_SUCCESS;
}
/**
Get the package data from the Package List.
@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 EFI_NOT_FOUND No Package is found for PackageIndex.
@return EFI_SUCCESS The package data is returned.
**/
EFI_STATUS
GetPackageData (
IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,
IN UINT32 PackageIndex,
OUT UINT32 *BufferLen,
OUT EFI_HII_PACKAGE_HEADER **Buffer
)
{
UINT32 Index;
EFI_HII_PACKAGE_HEADER *Package;
UINT32 Offset;
UINT32 PackageListLength;
EFI_HII_PACKAGE_HEADER PackageHeader = {0, 0};
ASSERT(HiiPackageList != NULL);
if ((BufferLen == NULL) || (Buffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
Package = NULL;
Index = 0;
Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
while (Offset < PackageListLength) {
Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);
CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
if (Index == PackageIndex) {
break;
}
Offset += PackageHeader.Length;
Index++;
}
if (Offset >= PackageListLength) {
//
// no package found in this Package List
//
return EFI_NOT_FOUND;
}
*BufferLen = PackageHeader.Length;
*Buffer = Package;
return EFI_SUCCESS;
}
/**
Check if Label exist in the IFR form package and return the FormSet GUID
and Form ID.
@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 (
IN CONST EFI_HII_PACKAGE_HEADER *Package,
IN EFI_FORM_LABEL Label,
OUT EFI_GUID *FormsetGuid,
OUT EFI_FORM_ID *FormId
)
{
UINTN Offset;
EFI_IFR_OP_HEADER *IfrOpHdr;
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);
InternalFormId= 0;
ZeroMem (&InternalFormSetGuid, sizeof (EFI_GUID));
GetFormSet = FALSE;
GetForm = FALSE;
while (Offset < Package->Length) {
switch (IfrOpHdr->OpCode) {
case EFI_IFR_FORM_SET_OP :
CopyMem (&InternalFormSetGuid, &((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, sizeof (EFI_GUID));
GetFormSet = TRUE;
break;
case EFI_IFR_FORM_OP:
CopyMem (&InternalFormId, &((EFI_IFR_FORM *) IfrOpHdr)->FormId, sizeof (EFI_FORM_ID));
GetForm = TRUE;
break;
case EFI_IFR_GUID_OP :
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;
}
}
break;
default :
break;
}
//
// Go to the next Op-Code
//
Offset += IfrOpHdr->Length;
IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
}
return EFI_NOT_FOUND;
}
/**
Find the first EFI_FORM_LABEL in FormSets for a given EFI_HII_HANLDE defined.
EFI_FORM_LABEL is a specific to Tiano implementation. The current implementation
does not restrict labels with same label value to be duplicated in either FormSet
scope or Form scope. This function will only locate the FIRST EFI_FORM_LABEL
with value as the same as the input Label in the Formset registered with UefiHiiHandle. The FormSet GUID
and Form ID is returned if such Label is found.
@retval EFI_INVALID_PARAMETER If UefiHiiHandle is not a valid handle.
@retval EFI_NOT_FOUND The package list identified by UefiHiiHandle deos not contain FormSet or
There is no Form ID with value Label found in all Form Sets in the pacakge
list.
@retval EFI_SUCCESS The first found Form ID is returned in FormId.
**/
EFI_STATUS
LocateFormId (
IN EFI_HII_HANDLE Handle,
IN EFI_FORM_LABEL Label,
OUT EFI_GUID *FormsetGuid,
OUT EFI_FORM_ID *FormId
)
{
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
UINT32 Index;
UINTN BufferSize;
EFI_HII_PACKAGE_HEADER PackageHeader;
EFI_HII_PACKAGE_HEADER *Package;
UINT32 PackageLength;
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)) {
goto Done;
}
}
for (Index = 0; ; Index++) {
Status = GetPackageData (HiiPackageList, Index, &PackageLength, &Package);
if (!EFI_ERROR (Status)) {
CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
Status = LocateLabel (Package, Label, FormsetGuid, FormId);
if (!EFI_ERROR(Status)) {
break;
}
}
} else {
break;
}
}
Done:
FreePool (HiiPackageList);
return Status;
}
/**
This function allows the caller to update a form that has
previously been registered with the EFI HII database.
@param This EDES_TODO: Add parameter description
@param Handle Hii Handle associated with the Formset to modify
@param Label Update information starting immediately after this label in the IFR
@param AddData If TRUE, add data. If FALSE, remove data
@param Data If adding data, this is the pointer to the data to add
@retval EFI_SUCCESS Update success.
@retval Other Update fail.
**/
EFI_STATUS
EFIAPI
HiiUpdateForm (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN EFI_FORM_LABEL Label,
IN BOOLEAN AddData,
IN FRAMEWORK_EFI_HII_UPDATE_DATA *Data
)
{
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT *ThunkContext;
EFI_HII_UPDATE_DATA *UefiHiiUpdateData;
EFI_HII_HANDLE UefiHiiHandle;
EFI_GUID FormsetGuid;
EFI_FORM_ID FormId;
EFI_TPL OldTpl;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
mInFrameworkUpdatePakcage = TRUE;
Status = EFI_SUCCESS;
UefiHiiUpdateData = NULL;
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
if (ThunkContext == NULL) {
Status = EFI_NOT_FOUND;
goto Done;
}
if (Data->FormSetUpdate) {
Status = UpdateFormCallBack ((EFI_HANDLE) (UINTN) Data->FormCallbackHandle, ThunkContext);
if (EFI_ERROR (Status)) {
goto Done;
}
}
if (ThunkContext->IfrPackageCount == 0) {
ASSERT (FALSE);
Status = EFI_INVALID_PARAMETER;
goto Done;
} else {
UefiHiiHandle = ThunkContext->UefiHiiHandle;
}
Status = LocateFormId (UefiHiiHandle, Label, &FormsetGuid, &FormId);
if (EFI_ERROR (Status)) {
//
// Can't find the label.
//
goto Done;
}
if (AddData) {
if (Data->DataCount != 0) {
ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);
Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, &UefiHiiUpdateData);
ASSERT_EFI_ERROR (Status);
Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, TRUE, UefiHiiUpdateData);
ASSERT_EFI_ERROR (Status);
}
} else {
//
// Delete Opcode starting from Labe in FormId found
//
UefiHiiUpdateData = AllocateZeroPool (sizeof (*UefiHiiUpdateData));
Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, FALSE, UefiHiiUpdateData);
ASSERT_EFI_ERROR (Status);
}
Done:
if (UefiHiiUpdateData != NULL) {
if (UefiHiiUpdateData->Data != NULL) {
FreePool (UefiHiiUpdateData->Data);
}
FreePool (UefiHiiUpdateData);
}
mInFrameworkUpdatePakcage = FALSE;
gBS->RestoreTPL (OldTpl);
return Status;
}

View File

@@ -0,0 +1,108 @@
#/** @file
# Component description file for HiiDatabase module which produce a Framework HII Protocol instance
# based on the avaliable UEFI HII protocol found in the platform. This modules enables modules complying
# to Framework HII specification to able to run on a UEFI HII platform with only a rebuild. This is
# to ensure that all HII packages are generated by UEFI HII package generation tools (UEFI VfrCompiler and
# String Gather Tools). This thunk layer only produces the Frameowork HII protocol interface. The binary package
# data format complying to UEFI HII specification.
#
# This module inits HII database and installs HII protocol based on the avaliable UEFI HII protocol found in the platform..
# Copyright (c) 2006 - 2008, Intel Corporation
#
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = FrameworkHiiToUefiHiiThunk
FILE_GUID = AC3435BB-B1D3-4EF8-957C-8048606FF671
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
EDK_RELEASE_VERSION = 0x00020000
EFI_SPECIFICATION_VERSION = 0x00020000
ENTRY_POINT = InitializeHiiDatabase
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources.common]
SetupBrowser.c
HiiHandle.c
HiiHandle.h
ConfigAccess.c
ConfigAccess.h
OpcodeCreation.c
UefiIfrParser.c
UefiIfrParser.h
UefiIfrParserExpression.c
UefiIfrParserExpression.h
UefiIfrDefault.c
UefiIfrDefault.h
Keyboard.c
Fonts.c
Package.c
Strings.c
Forms.c
HiiDatabase.h
HiiDatabase.c
Utility.c
Utility.h
Strings.uni
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
IntelFrameworkPkg/IntelFrameworkPkg.dec
[LibraryClasses]
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
BaseMemoryLib
MemoryAllocationLib
UefiDriverEntryPoint
DebugLib
BaseLib
HiiLib
ExtendedHiiLib
IfrSupportLib
ExtendedIfrSupportLib
PrintLib
UefiLib
PcdLib
[Protocols]
gEfiHiiImageProtocolGuid
gEfiHiiDatabaseProtocolGuid
gEfiHiiStringProtocolGuid
gEfiHiiFontProtocolGuid
gEfiHiiConfigRoutingProtocolGuid
gEfiHiiConfigAccessProtocolGuid
gEfiFormCallbackProtocolGuid
gEfiUnicodeCollation2ProtocolGuid
gEfiHiiCompatibilityProtocolGuid
gEfiFormBrowserCompatibilityProtocolGuid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformBootTimeOutDefault
[Depex]
gEfiHiiDatabaseProtocolGuid AND
gEfiHiiStringProtocolGuid AND
gEfiHiiConfigRoutingProtocolGuid AND
gEfiHiiFontProtocolGuid AND
gEfiFormBrowser2ProtocolGuid

View File

@@ -0,0 +1,528 @@
/**@file
Framework to UEFI 2.1 HII Thunk. The driver consume UEFI HII protocols
to produce a Framework HII protocol.
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiDatabase.h"
#include "HiiHandle.h"
HII_THUNK_PRIVATE_DATA *mHiiThunkPrivateData;
HII_THUNK_PRIVATE_DATA mHiiThunkPrivateDataTempate = {
HII_THUNK_PRIVATE_DATA_SIGNATURE,
(EFI_HANDLE) NULL,
{
HiiNewPack,
HiiRemovePack,
HiiFindHandles,
HiiExportDatabase,
HiiTestString,
HiiGetGlyph,
HiiGlyphToBlt,
HiiNewString,
HiiGetPrimaryLanguages,
HiiGetSecondaryLanguages,
HiiGetString,
HiiResetStrings,
HiiGetLine,
HiiGetForms,
HiiGetDefaultImage,
HiiUpdateForm,
HiiGetKeyboardLayout
},
{
///
/// HiiHandleLinkList
///
NULL, NULL
},
};
EFI_FORMBROWSER_THUNK_PRIVATE_DATA mBrowserThunkPrivateDataTemplate = {
EFI_FORMBROWSER_THUNK_PRIVATE_DATA_SIGNATURE,
(EFI_HANDLE) NULL,
(HII_THUNK_PRIVATE_DATA *) NULL,
{
ThunkSendForm,
ThunkCreatePopUp
}
};
CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;
CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;
CONST EFI_HII_FONT_PROTOCOL *mHiiFontProtocol;
CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;
CONST EFI_FORM_BROWSER2_PROTOCOL *mFormBrowser2Protocol;
/**
This routine initializes the HII Database.
@param ImageHandle Image handle for PCD DXE driver.
@param SystemTable Pointer to SystemTable.
@retval EFI_SUCCESS The entry point alwasy return successfully.
**/
EFI_STATUS
EFIAPI
InitializeHiiDatabase (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
HII_THUNK_PRIVATE_DATA *Private;
EFI_HANDLE Handle;
EFI_STATUS Status;
UINTN BufferLength;
EFI_HII_HANDLE *Buffer;
UINTN Index;
HII_THUNK_CONTEXT *ThunkContext;
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiHiiCompatibilityProtocolGuid);
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiFormBrowserCompatibilityProtocolGuid);
Private = AllocateCopyPool (sizeof (HII_THUNK_PRIVATE_DATA), &mHiiThunkPrivateDataTempate);
ASSERT (Private != NULL);
InitializeListHead (&Private->ThunkContextListHead);
InitHiiHandleDatabase ();
mHiiThunkPrivateData = Private;
Status = gBS->LocateProtocol (
&gEfiHiiDatabaseProtocolGuid,
NULL,
(VOID **) &mHiiDatabase
);
ASSERT_EFI_ERROR (Status);
Status = gBS->LocateProtocol (
&gEfiHiiStringProtocolGuid,
NULL,
(VOID **) &mHiiStringProtocol
);
ASSERT_EFI_ERROR (Status);
Status = gBS->LocateProtocol (
&gEfiHiiFontProtocolGuid,
NULL,
(VOID **) &mHiiFontProtocol
);
ASSERT_EFI_ERROR (Status);
Status = gBS->LocateProtocol (
&gEfiHiiConfigRoutingProtocolGuid,
NULL,
(VOID **) &mHiiConfigRoutingProtocol
);
ASSERT_EFI_ERROR (Status);
Status = gBS->LocateProtocol (
&gEfiFormBrowser2ProtocolGuid,
NULL,
(VOID **) &mFormBrowser2Protocol
);
ASSERT_EFI_ERROR (Status);
//
// Install protocol interface
//
Status = gBS->InstallProtocolInterface (
&Private->Handle,
&gEfiHiiCompatibilityProtocolGuid,
EFI_NATIVE_INTERFACE,
(VOID *) &Private->Hii
);
ASSERT_EFI_ERROR (Status);
Status = HiiLibListPackageLists (EFI_HII_PACKAGE_STRINGS, NULL, &BufferLength, &Buffer);
if (Status == EFI_SUCCESS) {
for (Index = 0; Index < BufferLength / sizeof (EFI_HII_HANDLE); Index++) {
ThunkContext = CreateThunkContextForUefiHiiHandle (Buffer[Index]);
ASSERT (ThunkContext!= NULL);
InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);
}
FreePool (Buffer);
}
Status = mHiiDatabase->RegisterPackageNotify (
mHiiDatabase,
EFI_HII_PACKAGE_STRINGS,
NULL,
NewOrAddPackNotify,
EFI_HII_DATABASE_NOTIFY_NEW_PACK,
&Handle
);
ASSERT_EFI_ERROR (Status);
Status = mHiiDatabase->RegisterPackageNotify (
mHiiDatabase,
EFI_HII_PACKAGE_STRINGS,
NULL,
NewOrAddPackNotify,
EFI_HII_DATABASE_NOTIFY_ADD_PACK,
&Handle
);
ASSERT_EFI_ERROR (Status);
Status = mHiiDatabase->RegisterPackageNotify (
mHiiDatabase,
EFI_HII_PACKAGE_FORMS,
NULL,
NewOrAddPackNotify,
EFI_HII_DATABASE_NOTIFY_NEW_PACK,
&Handle
);
ASSERT_EFI_ERROR (Status);
Status = mHiiDatabase->RegisterPackageNotify (
mHiiDatabase,
EFI_HII_PACKAGE_FORMS,
NULL,
NewOrAddPackNotify,
EFI_HII_DATABASE_NOTIFY_ADD_PACK,
&Handle
);
ASSERT_EFI_ERROR (Status);
Status = mHiiDatabase->RegisterPackageNotify (
mHiiDatabase,
EFI_HII_PACKAGE_STRINGS,
NULL,
RemovePackNotify,
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
&Handle
);
ASSERT_EFI_ERROR (Status);
InitSetBrowserStrings ();
mBrowserThunkPrivateDataTemplate.ThunkPrivate = Private;
Status = gBS->InstallProtocolInterface (
&mBrowserThunkPrivateDataTemplate.Handle,
&gEfiFormBrowserCompatibilityProtocolGuid,
EFI_NATIVE_INTERFACE,
(VOID *) &mBrowserThunkPrivateDataTemplate.FormBrowser
);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
Determines the handles that are currently active in the database.
This function determines the handles that are currently active in the database.
For example, a program wishing to create a Setup-like configuration utility would use this call
to determine the handles that are available. It would then use calls defined in the forms section
below to extract forms and then interpret them.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param HandleBufferLength On input, a pointer to the length of the handle buffer.
On output, the length of the handle buffer that is required for the handles found.
@param Handle An array of EFI_HII_HANDLE instances returned.
Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() in the Packages section.
@retval EFI_SUCCESS Handle was updated successfully.
@retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter indicates that Handle is too small
to support the number of handles. HandleBufferLength is updated with a value that
will enable the data to fit.
**/
EFI_STATUS
EFIAPI
HiiFindHandles (
IN EFI_HII_PROTOCOL *This,
IN OUT UINT16 *HandleBufferLength,
OUT FRAMEWORK_EFI_HII_HANDLE Handle[1]
)
{
UINT16 Count;
LIST_ENTRY *Link;
HII_THUNK_CONTEXT *ThunkContext;
HII_THUNK_PRIVATE_DATA *Private;
if (HandleBufferLength == NULL) {
return EFI_INVALID_PARAMETER;
}
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
//
// Count the number of handles.
//
Count = 0;
Link = GetFirstNode (&Private->ThunkContextListHead);
while (!IsNull (&Private->ThunkContextListHead, Link)) {
Count++;
Link = GetNextNode (&Private->ThunkContextListHead, Link);
}
if (Count > *HandleBufferLength) {
*HandleBufferLength = (UINT16) (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
return EFI_BUFFER_TOO_SMALL;
}
//
// Output the handles.
//
Count = 0;
Link = GetFirstNode (&Private->ThunkContextListHead);
while (!IsNull (&Private->ThunkContextListHead, Link)) {
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
Handle[Count] = ThunkContext->FwHiiHandle;
Count++;
Link = GetNextNode (&Private->ThunkContextListHead, Link);
}
*HandleBufferLength = (UINT16) (Count * sizeof (FRAMEWORK_EFI_HII_HANDLE));
return EFI_SUCCESS;
}
EFI_STATUS
LangCodes3066To639 (
IN CHAR8 *LangCodes3066,
IN CHAR8 **LangCodes639
)
{
CHAR8 *AsciiLangCodes;
CHAR8 Lang[RFC_3066_ENTRY_SIZE];
UINTN Index;
UINTN Count;
EFI_STATUS Status;
ASSERT (LangCodes3066 != NULL);
ASSERT (LangCodes639 != NULL);
//
// Count the number of RFC 3066 language codes.
//
Index = 0;
AsciiLangCodes = LangCodes3066;
while (AsciiStrLen (AsciiLangCodes) != 0) {
HiiLibGetNextLanguage (&AsciiLangCodes, Lang);
Index++;
}
Count = Index;
//
//
//
*LangCodes639 = AllocateZeroPool (ISO_639_2_ENTRY_SIZE * Count + 1);
if (*LangCodes639 == NULL) {
return EFI_OUT_OF_RESOURCES;
}
AsciiLangCodes = LangCodes3066;
for (Index = 0; Index < Count; Index++) {
HiiLibGetNextLanguage (&AsciiLangCodes, Lang);
Status = ConvertRfc3066LanguageToIso639Language (Lang, *LangCodes639 + Index * ISO_639_2_ENTRY_SIZE);
ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
}
/**
Allows a program to determine the primary languages that are supported on a given handle.
This routine is intended to be used by drivers to query the interface database for supported languages.
This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param Handle The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack()
in the Packages section.
@param LanguageString A string allocated by GetPrimaryLanguages() that contains a list of all primary languages
registered on the handle. The routine will not return the three-spaces language identifier used in
other functions to indicate non-language-specific strings.
@reval EFI_SUCCESS LanguageString was correctly returned.
@reval EFI_INVALID_PARAMETER The Handle was unknown.
**/
EFI_STATUS
EFIAPI
HiiGetPrimaryLanguages (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
OUT EFI_STRING *LanguageString
)
{
HII_THUNK_PRIVATE_DATA *Private;
EFI_HII_HANDLE UefiHiiHandle;
CHAR8 *LangCodes3066;
CHAR16 *UnicodeLangCodes639;
CHAR8 *LangCodes639;
EFI_STATUS Status;
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);
if (UefiHiiHandle == NULL) {
return EFI_INVALID_PARAMETER;
}
LangCodes3066 = HiiLibGetSupportedLanguages (UefiHiiHandle);
if (LangCodes3066 == NULL) {
return EFI_INVALID_PARAMETER;
}
LangCodes639 = NULL;
Status = LangCodes3066To639 (LangCodes3066, &LangCodes639);
if (EFI_ERROR (Status)) {
goto Done;
}
UnicodeLangCodes639 = AllocateZeroPool (AsciiStrSize (LangCodes639) * sizeof (CHAR16));
if (UnicodeLangCodes639 == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
//
// The language returned is in RFC 639-2 format.
//
AsciiStrToUnicodeStr (LangCodes639, UnicodeLangCodes639);
*LanguageString = UnicodeLangCodes639;
Done:
FreePool (LangCodes3066);
if (LangCodes639 != NULL) {
FreePool (LangCodes639);
}
return Status;
}
/**
Allows a program to determine which secondary languages are supported on a given handle for a given primary language
This routine is intended to be used by drivers to query the interface database for supported languages.
This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param Handle The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack()
in the Packages section.
@param PrimaryLanguage Pointer to a NULL-terminated string containing a single ISO 639-2 language identifier, indicating
the primary language.
@param LanguageString A string allocated by GetSecondaryLanguages() containing a list of all secondary languages registered
on the handle. The routine will not return the three-spaces language identifier used in other functions
to indicate non-language-specific strings, nor will it return the primary language. This function succeeds
but returns a NULL LanguageString if there are no secondary languages associated with the input Handle and
PrimaryLanguage pair. Type EFI_STRING is defined in String.
@reval EFI_SUCCESS LanguageString was correctly returned.
@reval EFI_INVALID_PARAMETER The Handle was unknown.
**/
EFI_STATUS
EFIAPI
HiiGetSecondaryLanguages (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN CHAR16 *PrimaryLanguage,
OUT EFI_STRING *LanguageString
)
{
HII_THUNK_PRIVATE_DATA *Private;
EFI_HII_HANDLE UefiHiiHandle;
CHAR8 PrimaryLang3066[RFC_3066_ENTRY_SIZE];
CHAR8 *PrimaryLang639;
CHAR8 *SecLangCodes3066;
CHAR8 *SecLangCodes639;
CHAR16 *UnicodeSecLangCodes639;
EFI_STATUS Status;
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
SecLangCodes639 = NULL;
SecLangCodes3066 = NULL;
UnicodeSecLangCodes639 = NULL;
UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);
if (UefiHiiHandle == NULL) {
return EFI_INVALID_PARAMETER;
}
PrimaryLang639 = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);
if (PrimaryLang639 == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
UnicodeStrToAsciiStr (PrimaryLanguage, PrimaryLang639);
Status = ConvertIso639LanguageToRfc3066Language (PrimaryLang639, PrimaryLang3066);
ASSERT_EFI_ERROR (Status);
SecLangCodes3066 = HiiLibGetSupportedSecondaryLanguages (UefiHiiHandle, PrimaryLang3066);
if (SecLangCodes3066 == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}
Status = LangCodes3066To639 (SecLangCodes3066, &SecLangCodes639);
if (EFI_ERROR (Status)) {
goto Done;
}
UnicodeSecLangCodes639 = AllocateZeroPool (AsciiStrSize (SecLangCodes639) * sizeof (CHAR16));
if (UnicodeSecLangCodes639 == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
//
// The language returned is in RFC 3066 format.
//
*LanguageString = AsciiStrToUnicodeStr (SecLangCodes639, UnicodeSecLangCodes639);
Done:
if (PrimaryLang639 != NULL) {
FreePool (PrimaryLang639);
}
if (SecLangCodes639 != NULL) {
FreePool (SecLangCodes639);
}
if (SecLangCodes3066 != NULL) {
FreePool (SecLangCodes3066);
}
if (UnicodeSecLangCodes639 != NULL) {
FreePool (UnicodeSecLangCodes639);
}
return Status;
}

View File

@@ -0,0 +1,464 @@
/**@file
This file contains global defines and prototype definitions
for the Framework HII to Uefi HII Thunk Module.
Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HIIDATABASE_H
#define _HIIDATABASE_H
#include <FrameworkDxe.h>
#include <Guid/GlobalVariable.h>
#include <Protocol/FrameworkFormCallback.h>
#include <Protocol/FrameworkHii.h>
#include <Protocol/FrameworkFormBrowser.h>
//
// UEFI HII Protocols
//
#include <Protocol/HiiFont.h>
#include <Protocol/HiiImage.h>
#include <Protocol/HiiString.h>
#include <Protocol/HiiDatabase.h>
#include <Protocol/HiiConfigRouting.h>
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/UgaDraw.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/HiiLib.h>
#include <Library/ExtendedHiiLib.h>
#include <Library/UefiLib.h>
#include <Library/IfrSupportLib.h>
#include <Library/ExtendedIfrSupportLib.h>
#include <Library/PcdLib.h>
#include <MdeModuleHii.h>
#include "UefiIfrParser.h"
//
// VARSTORE ID of 0 for Buffer Storage Type Storage is defined as invalid in UEFI 2.1 HII. VARSTORE ID
// 0 is the default VarStore ID for storage without explicit declaration in Framework HII 0.92. EDK II UEFI VFR compiler
// in compatible mode will assign 0x0001 as UEFI VARSTORE ID to this default storage id in Framework VFR without
// VARSTORE declaration.
//
// In addition, the Name of Default VarStore is assumed to be L"Setup" for those storage without explicit VARSTORE declaration in the formset
// by Framework HII. EDK II UEFI VFR compiler in compatible mode hard-coded L"Setup" as VARSTORE name.
//
#define FRAMEWORK_RESERVED_VARSTORE_ID 0x0001
#define FRAMEWORK_RESERVED_VARSTORE_NAME L"Setup"
#pragma pack (1)
typedef struct {
EFI_HII_PACK_HEADER FrameworkPackageHeader;
EFI_HII_PACKAGE_HEADER PackageHeader;
} TIANO_AUTOGEN_PACKAGES_HEADER;
#pragma pack ()
#define HII_THUNK_PRIVATE_DATA_FROM_THIS(Record) CR(Record, HII_THUNK_PRIVATE_DATA, Hii, HII_THUNK_PRIVATE_DATA_SIGNATURE)
#define HII_THUNK_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('H', 'i', 'I', 'T')
typedef struct {
UINTN Signature;
EFI_HANDLE Handle;
EFI_HII_PROTOCOL Hii;
//
// The head of link list for all HII_THUNK_CONTEXT.
//
LIST_ENTRY ThunkContextListHead;
EFI_HANDLE RemovePackNotifyHandle;
EFI_HANDLE AddPackNotifyHandle;
} HII_THUNK_PRIVATE_DATA;
#define QUESTION_ID_MAP_ENTRY_FROM_LINK(Record) CR(Record, QUESTION_ID_MAP_ENTRY, Link, QUESTION_ID_MAP_ENTRY_SIGNATURE)
#define QUESTION_ID_MAP_ENTRY_SIGNATURE SIGNATURE_32 ('Q', 'I', 'M', 'E')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
UINT16 FwQId;
EFI_QUESTION_ID UefiQid;
} QUESTION_ID_MAP_ENTRY;
#define QUESTION_ID_MAP_FROM_LINK(Record) CR(Record, QUESTION_ID_MAP, Link, QUESTION_ID_MAP_SIGNATURE)
#define QUESTION_ID_MAP_SIGNATURE SIGNATURE_32 ('Q', 'I', 'M', 'P')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
UINT16 VarStoreId;
UINTN VarSize;
LIST_ENTRY MapEntryListHead;
} QUESTION_ID_MAP;
#define HII_THUNK_CONTEXT_FROM_LINK(Record) CR(Record, HII_THUNK_CONTEXT, Link, HII_THUNK_CONTEXT_SIGNATURE)
#define HII_THUNK_CONTEXT_SIGNATURE SIGNATURE_32 ('H', 'T', 'H', 'M')
typedef struct {
LIST_ENTRY Link;
UINT32 Signature;
FRAMEWORK_EFI_HII_HANDLE FwHiiHandle;
EFI_HII_HANDLE UefiHiiHandle;
EFI_HANDLE UefiHiiDriverHandle;
UINTN IfrPackageCount;
UINTN StringPackageCount;
BOOLEAN ByFrameworkHiiNewPack;
//
// HII Thunk will use TagGuid to associate the String Package and Form Package togehter.
// See description for TagGuid. This field is to record if either one of the following condition
// is TRUE:
// 1) if ((SharingStringPack == TRUE) && (StringPackageCount != 0 && IfrPackageCount == 0)), then this Package List only
/// has String Packages and provides Strings to other IFR package.
// 2) if ((SharingStringPack == TRUE) && (StringPackageCount == 0 && IfrPackageCount != 1)), then this Form Package
// copied String Packages from other Package List.
// 3) if ((SharingStringPack == FALSE)), this Package does not provide String Package or copy String Packages from other
// Package List.
//
//
// When a Hii->NewString() is called for this FwHiiHandle and SharingStringPack is TRUE, then all Package List that sharing
// the same TagGuid will update or create String in there respective String Packages. If SharingStringPack is FALSE, then
// only the String from String Packages in this Package List will be updated or created.
//
BOOLEAN SharingStringPack;
//
// The HII 0.92 version of HII data implementation in EDK 1.03 and 1.04 make an the following assumption
// in both HII Database implementation and all modules that registering packages:
// If a Package List has only IFR package and no String Package, the IFR package will reference
// String in another Package List registered with the HII database with the same EFI_HII_PACKAGES.GuidId.
// TagGuid is the used to record this GuidId.
EFI_GUID TagGuid;
UINT8 *NvMapOverride;
FORM_BROWSER_FORMSET *FormSet;
} HII_THUNK_CONTEXT;
#define BUFFER_STORAGE_ENTRY_SIGNATURE SIGNATURE_32 ('H', 'T', 's', 'k')
#define BUFFER_STORAGE_ENTRY_FROM_LINK(Record) CR(Record, BUFFER_STORAGE_ENTRY, Link, BUFFER_STORAGE_ENTRY_SIGNATURE)
typedef struct {
LIST_ENTRY Link;
UINT32 Signature;
EFI_GUID Guid;
CHAR16 *Name;
UINTN Size;
UINT16 VarStoreId;
} BUFFER_STORAGE_ENTRY;
#define CONFIG_ACCESS_PRIVATE_SIGNATURE SIGNATURE_32 ('H', 'T', 'c', 'a')
#define CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL(Record) CR(Record, CONFIG_ACCESS_PRIVATE, ConfigAccessProtocol, CONFIG_ACCESS_PRIVATE_SIGNATURE)
typedef struct {
UINT32 Signature;
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccessProtocol;
//
// Framework's callback
//
EFI_FORM_CALLBACK_PROTOCOL *FormCallbackProtocol;
HII_THUNK_CONTEXT *ThunkContext;
} CONFIG_ACCESS_PRIVATE;
#define EFI_FORMBROWSER_THUNK_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('F', 'B', 'T', 'd')
#define EFI_FORMBROWSER_THUNK_PRIVATE_DATA_FROM_THIS(Record) CR(Record, EFI_FORMBROWSER_THUNK_PRIVATE_DATA, FormBrowser, EFI_FORMBROWSER_THUNK_PRIVATE_DATA_SIGNATURE)
typedef struct {
UINTN Signature;
EFI_HANDLE Handle;
HII_THUNK_PRIVATE_DATA *ThunkPrivate;
EFI_FORM_BROWSER_PROTOCOL FormBrowser;
} EFI_FORMBROWSER_THUNK_PRIVATE_DATA;
//
// Extern Variables
//
extern CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;
extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;
extern CONST EFI_HII_FONT_PROTOCOL *mHiiFontProtocol;
extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;
extern CONST EFI_FORM_BROWSER2_PROTOCOL *mFormBrowser2Protocol;
extern HII_THUNK_PRIVATE_DATA *mHiiThunkPrivateData;
extern BOOLEAN mInFrameworkUpdatePakcage;
EFI_STATUS
EFIAPI
HiiNewPack (
IN EFI_HII_PROTOCOL *This,
IN EFI_HII_PACKAGES *PackageList,
OUT FRAMEWORK_EFI_HII_HANDLE *Handle
);
EFI_STATUS
EFIAPI
HiiRemovePack (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle
);
EFI_STATUS
EFIAPI
HiiFindHandles (
IN EFI_HII_PROTOCOL *This,
IN OUT UINT16 *HandleBufferLength,
OUT FRAMEWORK_EFI_HII_HANDLE *Handle
);
EFI_STATUS
EFIAPI
HiiExportDatabase (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN OUT UINTN *BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
HiiGetGlyph (
IN EFI_HII_PROTOCOL *This,
IN CHAR16 *Source,
IN OUT UINT16 *Index,
OUT UINT8 **GlyphBuffer,
OUT UINT16 *BitWidth,
IN OUT UINT32 *InternalStatus
);
EFI_STATUS
EFIAPI
HiiGlyphToBlt (
IN EFI_HII_PROTOCOL *This,
IN UINT8 *GlyphBuffer,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
IN UINTN Count,
IN UINTN Width,
IN UINTN Height,
IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer
);
EFI_STATUS
EFIAPI
HiiNewString (
IN EFI_HII_PROTOCOL *This,
IN CHAR16 *Language,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN OUT STRING_REF *Reference,
IN CHAR16 *NewString
);
EFI_STATUS
EFIAPI
HiiGetString (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN STRING_REF Token,
IN BOOLEAN Raw,
IN CHAR16 *LanguageString,
IN OUT UINTN *BufferLength,
OUT EFI_STRING StringBuffer
);
EFI_STATUS
EFIAPI
HiiResetStrings (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle
);
EFI_STATUS
EFIAPI
HiiTestString (
IN EFI_HII_PROTOCOL *This,
IN CHAR16 *StringToTest,
IN OUT UINT32 *FirstMissing,
OUT UINT32 *GlyphBufferSize
);
EFI_STATUS
EFIAPI
HiiGetPrimaryLanguages (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
OUT EFI_STRING *LanguageString
);
EFI_STATUS
EFIAPI
HiiGetSecondaryLanguages (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN CHAR16 *PrimaryLanguage,
OUT EFI_STRING *LanguageString
);
EFI_STATUS
EFIAPI
HiiGetLine (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN STRING_REF Token,
IN OUT UINT16 *Index,
IN UINT16 LineWidth,
IN CHAR16 *LanguageString,
IN OUT UINT16 *BufferLength,
OUT EFI_STRING StringBuffer
);
EFI_STATUS
EFIAPI
HiiGetForms (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN EFI_FORM_ID FormId,
IN OUT UINTN *BufferLength,
OUT UINT8 *Buffer
);
EFI_STATUS
EFIAPI
HiiGetDefaultImage (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN UINTN DefaultMask,
OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList
);
EFI_STATUS
EFIAPI
HiiUpdateForm (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN EFI_FORM_LABEL Label,
IN BOOLEAN AddData,
IN FRAMEWORK_EFI_HII_UPDATE_DATA *Data
);
EFI_STATUS
EFIAPI
HiiGetKeyboardLayout (
IN EFI_HII_PROTOCOL *This,
OUT UINT16 *DescriptorCount,
OUT FRAMEWORK_EFI_KEY_DESCRIPTOR *Descriptor
);
EFI_STATUS
EFIAPI
ThunkSendForm (
IN EFI_FORM_BROWSER_PROTOCOL *This,
IN BOOLEAN UseDatabase,
IN FRAMEWORK_EFI_HII_HANDLE *Handle,
IN UINTN HandleCount,
IN FRAMEWORK_EFI_IFR_PACKET *Packet, OPTIONAL
IN EFI_HANDLE CallbackHandle, OPTIONAL
IN UINT8 *NvMapOverride, OPTIONAL
IN FRAMEWORK_EFI_SCREEN_DESCRIPTOR *ScreenDimensions, OPTIONAL
OUT BOOLEAN *ResetRequired OPTIONAL
);
EFI_STATUS
EFIAPI
ThunkCreatePopUp (
IN UINTN NumberOfLines,
IN BOOLEAN HotKey,
IN UINTN MaximumStringSize,
OUT CHAR16 *StringBuffer,
OUT EFI_INPUT_KEY *KeyValue,
IN CHAR16 *String,
...
);
EFI_STATUS
EFIAPI
RemovePackNotify (
IN UINT8 PackageType,
IN CONST EFI_GUID *PackageGuid,
IN CONST EFI_HII_PACKAGE_HEADER *Package,
IN EFI_HII_HANDLE Handle,
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
);
EFI_STATUS
EFIAPI
NewOrAddPackNotify (
IN UINT8 PackageType,
IN CONST EFI_GUID *PackageGuid,
IN CONST EFI_HII_PACKAGE_HEADER *Package,
IN EFI_HII_HANDLE Handle,
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
);
/**
Create a EFI_HII_UPDATE_DATA structure used to call IfrLibUpdateForm.
@param ThunkContext The HII Thunk Context.
@param FwUpdateData The Framework Update Data.
@param UefiUpdateData The UEFI Update Data.
@retval EFI_SUCCESS The UEFI Update Data is created successfully.
@retval EFI_UNSUPPORTED There is unsupported opcode in FwUpdateData.
@retval EFI_OUT_OF_RESOURCES There is not enough resource.
**/
EFI_STATUS
FwUpdateDataToUefiUpdateData (
IN HII_THUNK_CONTEXT *ThunkContext,
IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *FwUpdateData,
OUT EFI_HII_UPDATE_DATA **UefiUpdateData
)
;
/**
Initialize string packages in HII database.
**/
VOID
InitSetBrowserStrings (
VOID
)
;
#include "Utility.h"
#include "ConfigAccess.h"
#endif

View File

@@ -0,0 +1,85 @@
/**@file
This file is for functins related to assign and free Framework HII handle number.
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiHandle.h"
//
// FRAMEWORK_EFI_HII_HANDLE
//
UINT8 mHandle[1024 * 8] = {0};
/**
Initialize the Framework Hii Handle database.
**/
VOID
InitHiiHandleDatabase (
VOID
)
{
//
// FRAMEWORK_EFI_HII_HANDLE 0 is reserved.
// Set Bit 0 in mHandle[0] to 1.
//
mHandle[0] |= 1 << 0;
}
/**
Allocate a new Framework HII handle.
@param Handle Returns the new Framework HII Handle assigned.
@retval EFI_SUCCESS A new Framework HII Handle is assigned.
@retval EFI_OUT_OF_RESOURCE The Framework HII Handle database is depleted.
**/
EFI_STATUS
AllocateHiiHandle (
OUT FRAMEWORK_EFI_HII_HANDLE *Handle
)
{
UINTN Index;
for (Index = 0; Index < sizeof (mHandle) * 8; Index++) {
if ((mHandle[Index / 8] & (1 << (Index % 8))) == 0) {
mHandle[Index / 8] = (UINT8) (mHandle[Index / 8] | (1 << (Index % 8)));
*Handle = (FRAMEWORK_EFI_HII_HANDLE) Index;
ASSERT (*Handle != 0);
return EFI_SUCCESS;
}
}
return EFI_OUT_OF_RESOURCES;
}
/**
Free Framework HII handle.
@param Handle The Framework HII Handle to be freed.
**/
VOID
FreeHiiHandle (
IN FRAMEWORK_EFI_HII_HANDLE Handle
)
{
UINT16 Num;
Num = (UINT16) Handle;
ASSERT ((mHandle [Num / 8] & (1 << (Num % 8))) != 0);
mHandle [Num / 8] = (UINT8) (mHandle [Num / 8] & (~(1 << (Num % 8))));
}

View File

@@ -0,0 +1,40 @@
/**@file
This file is for functins related to assign and free Framework HII handle number.
Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HII_HANDLE_H
#define _HII_HANDLE_H
#include <FrameworkDxe.h>
#include <Protocol/FrameworkHii.h>
#include <Library/DebugLib.h>
VOID
InitHiiHandleDatabase (
VOID
);
EFI_STATUS
AllocateHiiHandle (
FRAMEWORK_EFI_HII_HANDLE *Handle
);
VOID
FreeHiiHandle (
FRAMEWORK_EFI_HII_HANDLE Handle
);
#endif

View File

@@ -0,0 +1,45 @@
/**@file
This file contains the keyboard processing code to the HII database.
Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
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 (
IN EFI_HII_PROTOCOL *This,
OUT UINT16 *DescriptorCount,
OUT FRAMEWORK_EFI_KEY_DESCRIPTOR *Descriptor
)
{
ASSERT (FALSE);
//
// In previous Framewok HII implementation, GetKeyBoardLayout is defined in HII 0.92 specification,
// but it is not implemented. We ASSERT and return UNSUPPORTED here.
//
return EFI_UNSUPPORTED;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,885 @@
/**@file
Implement protocol interface related to package registrations.
Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiDatabase.h"
#include "HiiHandle.h"
BOOLEAN mInFrameworkHiiNewPack = FALSE;
BOOLEAN mInFrameworkHiiRemovePack = FALSE;
BOOLEAN mInFrameworkUpdatePakcage = FALSE;
UINT64 mGuidCount = 0;
EFI_GUID mGuidBase = { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e }};
/**
Get the number of package IFR and STRING packages in the package list passed in.
@param Packages Package List.
@param IfrPackageCount Number of IFR Packages.
@param StringPackageCount Number of String Packages.
@retval EFI_INVALID_PARAMETER If the Package List has package with type of
EFI_HII_PACKAGE_KEYBOARD_LAYOUT, EFI_HII_PACKAGE_FONTS, EFI_HII_PACKAGE_IMAGES.
@reval EFI_SUCCESS Successfully get the number of IFR and STRING package.
**/
EFI_STATUS
GetPackageCount (
IN CONST EFI_HII_PACKAGES *Packages,
OUT UINTN *IfrPackageCount,
OUT UINTN *StringPackageCount,
OUT UINTN *FontPackageCount
)
{
UINTN Index;
TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;
ASSERT (Packages != NULL);
ASSERT (IfrPackageCount != NULL);
ASSERT (StringPackageCount != NULL);
ASSERT (FontPackageCount != NULL);
*IfrPackageCount = 0;
*StringPackageCount = 0;
*FontPackageCount = 0;
TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));
for (Index = 0; Index < Packages->NumberOfPackages; Index++) {
//
// The current UEFI HII build tool generate a binary in the format defined by
// TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in
// this binary is with same package type. So the returned IfrPackageCount and StringPackageCount
// may not be the exact number of valid package number in the binary generated
// by HII Build tool.
//
switch (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type) {
case EFI_HII_IFR:
*IfrPackageCount += 1;
break;
case EFI_HII_STRING:
*StringPackageCount += 1;
break;
case EFI_HII_FONT:
*FontPackageCount += 1;
break;
//
// The following fonts are invalid for a module that using Framework to UEFI thunk layer.
//
default:
ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
break;
}
}
return EFI_SUCCESS;
}
/**
Insert the String Package into the Package Lists which has the TAG GUID matching
the PackageListGuid of the String Package.
The Package List must have only IFR Package and no String Package.
Otherwise, ASSERT.
@param Private The HII THUNK driver context data.
@param StringPackageThunkContext The HII THUNK context data.
@param StringPackageListHeader The String Package List Header.
**/
VOID
UpdatePackListWithOnlyIfrPack (
IN HII_THUNK_PRIVATE_DATA *Private,
IN HII_THUNK_CONTEXT *StringPackageThunkContext,
IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
HII_THUNK_CONTEXT *ThunkContext;
Link = GetFirstNode (&Private->ThunkContextListHead);
while (!IsNull (&Private->ThunkContextListHead, Link)) {
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
if (StringPackageThunkContext != ThunkContext) {
//
// Skip the String Package Thunk Entry itself.
//
if (CompareGuid (&StringPackageListHeader->PackageListGuid, &ThunkContext->TagGuid)) {
ASSERT (ThunkContext->StringPackageCount == 0 && ThunkContext->IfrPackageCount == 1);
ThunkContext->StringPackageCount = GetPackageCountByType (StringPackageListHeader, EFI_HII_PACKAGE_STRINGS);
Status = mHiiDatabase->UpdatePackageList (
mHiiDatabase,
ThunkContext->UefiHiiHandle,
StringPackageListHeader
);
ASSERT_EFI_ERROR (Status);
ThunkContext->SharingStringPack = TRUE;
StringPackageThunkContext->SharingStringPack = TRUE;
}
}
Link = GetNextNode (&Private->ThunkContextListHead, Link);
}
}
/**
Caculate the size of UEFI Simple Font Package that is needed to
convert all the font a Framework Font Paackage.
ONLY Narrow Font is supported. Wide Font is discarded.
If the Package Header is not of EFI_HII_FONT type, then ASSERT.
@param The Package header of the Framework Font Package.
@return The size of the UEFI Simple Font Package.
**/
UINTN
GetUefiSimpleFontPackSize (
IN CONST EFI_HII_PACK_HEADER * PackHeader
)
{
UINTN Size;
EFI_HII_FONT_PACK *FwFontPack;
FwFontPack = (EFI_HII_FONT_PACK *) PackHeader;
ASSERT (FwFontPack->Header.Type == EFI_HII_FONT);
Size = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR)
+ (FwFontPack->NumberOfNarrowGlyphs * sizeof (EFI_NARROW_GLYPH));
return Size;
}
/**
Convert Font Package in Framework format to a newly allocated UEFI
Simple Font Package.
ONLY Narrow Font is supported. Wide Font is discarded.
If memory allocation fails, then ASSERT.
@param FwFontPack Framework Font Package.
@reture UEFI Simple Font Package.
**/
EFI_HII_SIMPLE_FONT_PACKAGE_HDR *
FrameworkFontPackToUefiSimpliedFont (
IN CONST EFI_HII_PACK_HEADER * PackHeader
)
{
EFI_HII_SIMPLE_FONT_PACKAGE_HDR *FontPack;
UINTN Size;
EFI_NARROW_GLYPH *FwNarrowGlyph;
EFI_NARROW_GLYPH *NarrowGlyph;
UINTN Idx;
EFI_HII_FONT_PACK *FwFontPack;
Size = GetUefiSimpleFontPackSize (PackHeader);
FwFontPack = (EFI_HII_FONT_PACK *) PackHeader;
FontPack = AllocateZeroPool (Size);
ASSERT (FontPack != NULL);
//
// Prepare the Header information.
//
FontPack->Header.Length = (UINT32) Size;
FontPack->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;
FontPack->NumberOfNarrowGlyphs = FwFontPack->NumberOfNarrowGlyphs;
//
// ONLY Narrow Font is supported. Wide Font is discarded.
//
FontPack->NumberOfWideGlyphs = 0;
//
// Copy Narrow Glyph
//
NarrowGlyph = (EFI_NARROW_GLYPH *) (FontPack + 1);
FwNarrowGlyph = (EFI_NARROW_GLYPH *) (FwFontPack + 1);
CopyMem (NarrowGlyph, FwNarrowGlyph, sizeof (EFI_NARROW_GLYPH) * FwFontPack->NumberOfNarrowGlyphs);
for (Idx = 0; Idx < FwFontPack->NumberOfNarrowGlyphs; Idx++) {
//
// Clear the GLYPH_NON_BREAKING (EFI_GLYPH_WIDE is used here as they are all 0x02)
// attribute which is not defined in UEFI EFI_NARROW_GLYPH
//
NarrowGlyph[Idx].Attributes = (UINT8) (NarrowGlyph[Idx].Attributes & ~(EFI_GLYPH_WIDE));
}
return FontPack;
}
/**
Prepare a UEFI Package List from a Framework HII package list registered
from a Framework HII NewPack () function.
If either Packages or PackageListGuid is NULL, then ASSERT.
@param Packages The Framework HII Package List.
@param PackageListGuid The Package List GUID.
@return The UEFI Package List.
**/
EFI_HII_PACKAGE_LIST_HEADER *
PrepareUefiPackageListFromFrameworkHiiPackages (
IN CONST EFI_HII_PACKAGES *Packages,
IN CONST EFI_GUID *PackageListGuid
)
{
UINTN NumberOfPackages;
EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
UINT8 *PackageListData;
UINT32 PackageListLength;
UINT32 PackageLength;
EFI_HII_PACKAGE_HEADER PackageHeader;
UINTN Index;
TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;
EFI_HII_SIMPLE_FONT_PACKAGE_HDR *FontPack;
ASSERT (Packages != NULL);
ASSERT (PackageListGuid != NULL);
TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) ((UINT8 *) &Packages->GuidId + sizeof (Packages->GuidId));
NumberOfPackages = Packages->NumberOfPackages;
PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
for (Index = 0; Index < NumberOfPackages; Index++) {
if (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type == EFI_HII_FONT) {
//
// There is no tool to generate Font package in Framework HII's implementation.
// Therefore, Font Package be a C structure defined in Framework HII code.
// Therefore, Font Package will be in Framework HII format defined by EFI_HII_FONT_PACK.
// We need to create a UEFI Simple Font Package and copy over all data. Hence, EFI_HII_FONT
// is handled differently than EFI_HII_IFR and EFI_HII_STRING.
//
PackageListLength = (UINT32) (PackageListLength + GetUefiSimpleFontPackSize (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader));
} else {
//
// For EFI_HII_IFR and EFI_HII_STRING, EDK II's VFR Compiler and Build.exe will generate a binary in a format
// defined by TIANO_AUTOGEN_PACKAGES_HEADER. A Framework HII's EFI_HII_PACK_HEADER is inserted before
// the UEFI package data.
//
CopyMem (&PackageLength, &TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Length, sizeof (UINT32));
//
// EFI_HII_PACK_HEADER.FrameworkPackageHeader.Length include the sizeof FrameworkPackageHeader itself.
//
PackageListLength += (PackageLength - sizeof(EFI_HII_PACK_HEADER));
}
}
//
// Include the lenght of EFI_HII_PACKAGE_END
//
PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);
PackageListHeader = AllocateZeroPool (PackageListLength);
ASSERT (PackageListHeader != NULL);
CopyMem (&PackageListHeader->PackageListGuid, PackageListGuid, sizeof (EFI_GUID));
PackageListHeader->PackageLength = PackageListLength;
PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);
//
// Build the UEFI Package List.
//
for (Index = 0; Index < NumberOfPackages; Index++) {
if (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type == EFI_HII_FONT) {
PackageLength = (UINT32) GetUefiSimpleFontPackSize (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader);
FontPack = FrameworkFontPackToUefiSimpliedFont (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader);
CopyMem (PackageListData, FontPack, PackageLength);
FreePool (FontPack);
} else {
CopyMem (&PackageLength, &(TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Length), sizeof (UINT32));
PackageLength -= sizeof (EFI_HII_PACK_HEADER);
CopyMem (PackageListData, &(TianoAutogenPackageHdrArray[Index]->PackageHeader), PackageLength);
}
PackageListData += PackageLength;
}
//
// Append EFI_HII_PACKAGE_END
//
PackageHeader.Type = EFI_HII_PACKAGE_END;
PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);
CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);
return PackageListHeader;
}
/**
Generate a Random GUID.
@param Guid On output, a Random GUID will be filled.
**/
VOID
GenerateRandomGuid (
OUT EFI_GUID * Guid
)
{
CopyGuid (Guid, &mGuidBase);
mGuidCount++;
*((UINT64 *) Guid) = *((UINT64 *) Guid) + mGuidCount;
}
/**
Given a Package List with only a IFR package, find the Package List that only has a String Package based on
the TAG GUID. Then export the String Package from the Package List and insert it
to the given IFR package.
This is to handle the case of Framework HII interface which allow String Package
and IFR package to be registered using two different NewPack () calls.
@param Private The HII THUNK driver context data.
@param IfrThunkContext Package List with only a IFR package.
@retval EFI_SUCCESS If the String Package is found and inserted to the
Package List with only a IFR package.
@retval EFI_NOT_FOUND No String Package matching the TAG GUID is found.
**/
EFI_STATUS
FindStringPackAndUpdatePackListWithOnlyIfrPack (
IN HII_THUNK_PRIVATE_DATA *Private,
IN HII_THUNK_CONTEXT *IfrThunkContext
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader;
UINTN Size;
HII_THUNK_CONTEXT *ThunkContext;
Link = GetFirstNode (&Private->ThunkContextListHead);
while (!IsNull (&Private->ThunkContextListHead, Link)) {
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
if (ThunkContext != IfrThunkContext) {
if (CompareGuid (&IfrThunkContext->TagGuid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount == 0)) {
Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &StringPackageListHeader, &Size);
ASSERT_EFI_ERROR (Status);
IfrThunkContext->StringPackageCount = GetPackageCountByType (StringPackageListHeader, EFI_HII_PACKAGE_STRINGS);
//
// Add Function to only get only String Packages from the Package List
//
Status = mHiiDatabase->UpdatePackageList (
mHiiDatabase,
IfrThunkContext->UefiHiiHandle,
StringPackageListHeader
);
ASSERT_EFI_ERROR (Status);
FreePool (StringPackageListHeader);
IfrThunkContext->SharingStringPack = TRUE;
ThunkContext->SharingStringPack = TRUE;
return EFI_SUCCESS;
}
}
Link = GetNextNode (&Private->ThunkContextListHead, Link);
}
//
// A Form Package must have a String Package to function.
// If ASSERT here, check the sequence of call to Hii->NewPack.
// String Pack must be registered before Ifr Package is registered.
//
ASSERT (FALSE);
return EFI_NOT_FOUND;
}
/**
Register the Package List passed from the Framework HII NewPack () interface.
The FRAMEWORK_EFI_HII_HANDLE will be returned.
@param This The EFI_HII_PROTOCOL context data. Only used
to call HiiRemovePack.
@param Private The HII THUNK driver context data.
@param Package Package List.
@param Handle On output, a FRAMEWORK_EFI_HII_HANDLE number is
returned.
@retval EFI_SUCCESS The Package List is registered successfull in
the database.
@retval EFI_UNSUPPORTED The number of IFR package in the package list
is greater than 1.
@retval EFI_OUT_OF_RESOURCE Not enough resouce.
**/
EFI_STATUS
UefiRegisterPackageList (
IN EFI_HII_PROTOCOL *This,
IN HII_THUNK_PRIVATE_DATA *Private,
IN EFI_HII_PACKAGES *Packages,
OUT FRAMEWORK_EFI_HII_HANDLE *Handle
)
{
EFI_STATUS Status;
UINTN StringPackageCount;
UINTN IfrPackageCount;
UINTN FontPackageCount;
EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
HII_THUNK_CONTEXT *ThunkContext;
HII_THUNK_CONTEXT *ThunkContextToRemove;
EFI_GUID GuidId;
EFI_HII_PACKAGE_HEADER *IfrPackage;
PackageListHeader = NULL;
Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount, &FontPackageCount);
ASSERT_EFI_ERROR (Status);
if (IfrPackageCount > 1) {
//
// HII Thunk only handle package with 0 or 1 IFR package.
//
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
ThunkContext = CreateThunkContext (Private, StringPackageCount, IfrPackageCount);
if (ThunkContext == NULL) {
return EFI_OUT_OF_RESOURCES;
}
ThunkContext->ByFrameworkHiiNewPack = TRUE;
if (Packages->GuidId == NULL) {
//
// UEFI HII Database require Package List GUID must be unique.
//
// 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. Formset GUID is used as the Package List
// GUID instead.
//
ASSERT ((StringPackageCount >=1 && IfrPackageCount == 1) || (FontPackageCount > 0));
if (IfrPackageCount > 0) {
IfrPackage = GetIfrPackage (Packages);
GetFormSetGuid (IfrPackage, &ThunkContext->TagGuid);
} else {
ASSERT (FontPackageCount > 0);
GenerateRandomGuid (&ThunkContext->TagGuid);
}
} else {
ThunkContextToRemove = TagGuidToIfrPackThunkContext (Private, Packages->GuidId);
if (IfrPackageCount > 0 &&
StringPackageCount > 0 &&
(ThunkContextToRemove != NULL)) {
DEBUG((EFI_D_WARN, "Framework code registers HII package list with the same GUID more than once.\n"));
DEBUG((EFI_D_WARN, "Remove the previously registered package list and register the new one.\n"));
HiiRemovePack (This, ThunkContextToRemove->FwHiiHandle);
}
CopyGuid (&ThunkContext->TagGuid, Packages->GuidId);
}
//
// 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. 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);
}
PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &ThunkContext->TagGuid);
Status = mHiiDatabase->NewPackageList (
mHiiDatabase,
PackageListHeader,
ThunkContext->UefiHiiDriverHandle,
&ThunkContext->UefiHiiHandle
);
if (Status == EFI_INVALID_PARAMETER) {
FreePool (PackageListHeader);
//
// UEFI HII database does not allow two package list with the same GUID.
// In Framework HII implementation, Packages->GuidId is used as an identifier to associate
// a PackageList with only IFR to a Package list the with String package.
//
GenerateRandomGuid (&GuidId);
PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);
Status = mHiiDatabase->NewPackageList (
mHiiDatabase,
PackageListHeader,
ThunkContext->UefiHiiDriverHandle,
&ThunkContext->UefiHiiHandle
);
}
//
// BUGBUG: Remove when development is done
//
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
goto Done;
}
if (IfrPackageCount == 0) {
if (StringPackageCount != 0) {
//
// 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,
ThunkContext,
PackageListHeader
);
}
} else {
if (StringPackageCount == 0) {
//
// 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,
ThunkContext
);
if (EFI_ERROR (Status)) {
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:
if (EFI_ERROR (Status)) {
DestroyThunkContext (ThunkContext);
} else {
InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);
*Handle = ThunkContext->FwHiiHandle;
}
if (PackageListHeader != NULL) {
FreePool (PackageListHeader);
}
return Status;
}
/**
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 (
IN EFI_HII_PROTOCOL *This,
IN EFI_HII_PACKAGES *Packages,
OUT FRAMEWORK_EFI_HII_HANDLE *Handle
)
{
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
EFI_TPL OldTpl;
if (Handle == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Packages == NULL) {
return EFI_INVALID_PARAMETER;
}
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
//
// We use a simple Global variable to inform NewOrAddPackNotify()
// that the package list registered here is already registered
// in the HII Thunk Layer. So NewOrAddPackNotify () does not need to
// call registered the Package List again.
//
mInFrameworkHiiNewPack = TRUE;
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
Status = UefiRegisterPackageList (
This,
Private,
Packages,
Handle
);
mInFrameworkHiiNewPack = FALSE;
gBS->RestoreTPL (OldTpl);
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
)
{
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT *ThunkContext;
EFI_TPL OldTpl;
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
mInFrameworkHiiRemovePack = TRUE;
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
if (ThunkContext != NULL) {
Status = mHiiDatabase->RemovePackageList (
mHiiDatabase,
ThunkContext->UefiHiiHandle
);
ASSERT_EFI_ERROR (Status);
if (ThunkContext->IfrPackageCount != 0) {
UninstallDefaultConfigAccessProtocol (ThunkContext);
}
DestroyThunkContext (ThunkContext);
}else {
Status = EFI_NOT_FOUND;
}
mInFrameworkHiiRemovePack = FALSE;
gBS->RestoreTPL (OldTpl);
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 (
IN UINT8 PackageType,
IN CONST EFI_GUID *PackageGuid,
IN CONST EFI_HII_PACKAGE_HEADER *Package,
IN EFI_HII_HANDLE Handle,
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
)
{
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT *ThunkContext;
ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS || PackageType == EFI_HII_PACKAGE_FORMS);
ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK);
Status = EFI_SUCCESS;
Private = mHiiThunkPrivateData;
if (mInFrameworkHiiNewPack || mInFrameworkUpdatePakcage) {
return EFI_SUCCESS;
}
//
// 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) {
ThunkContext = CreateThunkContextForUefiHiiHandle (Handle);
ASSERT (ThunkContext != NULL);
InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);
}
if (PackageType == EFI_HII_PACKAGE_FORMS) {
if (ThunkContext->FormSet != NULL) {
DestroyFormSet (ThunkContext->FormSet);
}
//
// Reparse the FormSet.
//
ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);
ASSERT (ThunkContext->FormSet != NULL);
}
return Status;
}
/**
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 (
IN UINT8 PackageType,
IN CONST EFI_GUID *PackageGuid,
IN CONST EFI_HII_PACKAGE_HEADER *Package,
IN EFI_HII_HANDLE Handle,
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
)
{
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
HII_THUNK_CONTEXT *ThunkContext;
EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
UINTN BufferSize;
Status = EFI_SUCCESS;
ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);
ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);
if (mInFrameworkHiiRemovePack || mInFrameworkUpdatePakcage) {
return EFI_SUCCESS;
}
Private = mHiiThunkPrivateData;
ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);
//
// BugBug: Change to ASSERT if HII Database fix the bug and to also invoke
// NEW_PACK_NOTIFY for package (String Package) created internally.
//
if (ThunkContext != NULL) {
if (!ThunkContext->ByFrameworkHiiNewPack) {
Status = HiiLibExportPackageLists (Handle, &HiiPackageList, &BufferSize);
ASSERT_EFI_ERROR (Status);
if (GetPackageCountByType (HiiPackageList, EFI_HII_PACKAGE_STRINGS) == 1) {
//
// If the string package will be removed is the last string package
// in the package list, we will remove the HII Thunk entry from the
// database.
//
DestroyThunkContextForUefiHiiHandle (Private, Handle);
}
FreePool (HiiPackageList);
}
}
return Status;
}

View File

@@ -0,0 +1,575 @@
/**@file
Framework to UEFI 2.1 Setup Browser Thunk. The file consume EFI_FORM_BROWSER2_PROTOCOL
to produce a EFI_FORM_BROWSER_PROTOCOL.
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiDatabase.h"
#include "SetupBrowser.h"
EFI_GUID gFrameworkBdsFrontPageFormsetGuid = FRAMEWORK_BDS_FRONTPAGE_FORMSET_GUID;
EFI_HII_HANDLE gStringPackHandle = NULL;
BOOLEAN mFrontPageDisplayed = FALSE;
//
// 106F3545-B788-4cb5-9D2A-CE0CDB208DF5
//
EFI_GUID gEfiHiiThunkProducerGuid = { 0x106f3545, 0xb788, 0x4cb5, { 0x9d, 0x2a, 0xce, 0xc, 0xdb, 0x20, 0x8d, 0xf5 } };
/**
Get string by string id from HII Interface
@param Id String ID.
@retval CHAR16 * String from ID.
@retval NULL If error occurs.
**/
CHAR16 *
GetStringById (
IN EFI_STRING_ID Id
)
{
CHAR16 *String;
String = NULL;
HiiLibGetStringFromHandle (gStringPackHandle, Id, &String);
return String;
}
/**
Show progress bar with title above it. It only works in Graphics mode.
@param TitleForeground Foreground color for Title.
@param TitleBackground Background color for Title.
@param Title Title above progress bar.
@param ProgressColor Progress bar color.
@param Progress Progress (0-100)
@param PreviousValue The previous value of the progress.
@retval EFI_STATUS Success update the progress bar
**/
EFI_STATUS
PlatformBdsShowProgress (
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
IN CHAR16 *Title,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
IN UINTN Progress,
IN UINTN PreviousValue
)
{
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
UINT32 SizeOfX;
UINT32 SizeOfY;
UINT32 ColorDepth;
UINT32 RefreshRate;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
UINTN BlockHeight;
UINTN BlockWidth;
UINTN BlockNum;
UINTN PosX;
UINTN PosY;
UINTN Index;
if (Progress > 100) {
return EFI_INVALID_PARAMETER;
}
UgaDraw = NULL;
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiGraphicsOutputProtocolGuid,
(VOID **) &GraphicsOutput
);
if (EFI_ERROR (Status)) {
GraphicsOutput = NULL;
Status = gBS->HandleProtocol (
gST->ConsoleOutHandle,
&gEfiUgaDrawProtocolGuid,
(VOID **) &UgaDraw
);
}
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
SizeOfX = 0;
SizeOfY = 0;
if (GraphicsOutput != NULL) {
SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
} else {
Status = UgaDraw->GetMode (
UgaDraw,
&SizeOfX,
&SizeOfY,
&ColorDepth,
&RefreshRate
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
BlockWidth = SizeOfX / 100;
BlockHeight = SizeOfY / 50;
BlockNum = Progress;
PosX = 0;
PosY = SizeOfY * 48 / 50;
if (BlockNum == 0) {
//
// Clear progress area
//
SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
if (GraphicsOutput != NULL) {
Status = GraphicsOutput->Blt (
GraphicsOutput,
&Color,
EfiBltVideoFill,
0,
0,
0,
PosY - EFI_GLYPH_HEIGHT - 1,
SizeOfX,
SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
);
} else {
Status = UgaDraw->Blt (
UgaDraw,
(EFI_UGA_PIXEL *) &Color,
EfiUgaVideoFill,
0,
0,
0,
PosY - EFI_GLYPH_HEIGHT - 1,
SizeOfX,
SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
SizeOfX * sizeof (EFI_UGA_PIXEL)
);
}
}
//
// Show progress by drawing blocks
//
for (Index = PreviousValue; Index < BlockNum; Index++) {
PosX = Index * BlockWidth;
if (GraphicsOutput != NULL) {
Status = GraphicsOutput->Blt (
GraphicsOutput,
&ProgressColor,
EfiBltVideoFill,
0,
0,
PosX,
PosY,
BlockWidth - 1,
BlockHeight,
(BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
);
} else {
Status = UgaDraw->Blt (
UgaDraw,
(EFI_UGA_PIXEL *) &ProgressColor,
EfiUgaVideoFill,
0,
0,
PosX,
PosY,
BlockWidth - 1,
BlockHeight,
(BlockWidth) * sizeof (EFI_UGA_PIXEL)
);
}
}
PrintXY (
(SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,
PosY - EFI_GLYPH_HEIGHT - 1,
&TitleForeground,
&TitleBackground,
Title
);
return EFI_SUCCESS;
}
/**
Function waits for a given event to fire, or for an optional timeout to expire.
@param Event The event to wait for
@param Timeout An optional timeout value in 100 ns units.
@retval EFI_SUCCESS Event fired before Timeout expired.
@retval EFI_TIME_OUT Timout expired before Event fired..
**/
EFI_STATUS
WaitForSingleEvent (
IN EFI_EVENT Event,
IN UINT64 Timeout OPTIONAL
)
{
EFI_STATUS Status;
UINTN Index;
EFI_EVENT TimerEvent;
EFI_EVENT WaitList[2];
if (Timeout != 0) {
//
// Create a timer event
//
Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
if (!EFI_ERROR (Status)) {
//
// Set the timer event
//
gBS->SetTimer (
TimerEvent,
TimerRelative,
Timeout
);
//
// Wait for the original event or the timer
//
WaitList[0] = Event;
WaitList[1] = TimerEvent;
Status = gBS->WaitForEvent (2, WaitList, &Index);
gBS->CloseEvent (TimerEvent);
//
// If the timer expired, change the return to timed out
//
if (!EFI_ERROR (Status) && Index == 1) {
Status = EFI_TIMEOUT;
}
}
} else {
//
// No timeout... just wait on the event
//
Status = gBS->WaitForEvent (1, &Event, &Index);
ASSERT (!EFI_ERROR (Status));
ASSERT (Index == 0);
}
return Status;
}
/**
Function show progress bar to wait for user input.
@param TimeoutDefault - The fault time out value before the system
continue to boot.
@retval EFI_SUCCESS User pressed some key except "Enter"
@retval EFI_TIME_OUT Timout expired or user press "Enter"
**/
EFI_STATUS
ShowProgress (
IN UINT16 TimeoutDefault
)
{
EFI_STATUS Status;
CHAR16 *TmpStr;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
EFI_INPUT_KEY Key;
UINT16 TimeoutRemain;
if (TimeoutDefault == 0) {
return EFI_TIMEOUT;
}
DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));
SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
//
// Clear the progress status bar first
//
TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));
if (TmpStr != NULL) {
PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
}
TimeoutRemain = TimeoutDefault;
while (TimeoutRemain != 0) {
DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
if (Status != EFI_TIMEOUT) {
break;
}
TimeoutRemain--;
//
// Show progress
//
if (TmpStr != NULL) {
PlatformBdsShowProgress (
Foreground,
Background,
TmpStr,
Color,
((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
0
);
}
}
gBS->FreePool (TmpStr);
//
// Timeout expired
//
if (TimeoutRemain == 0) {
return EFI_TIMEOUT;
}
//
// User pressed some key
//
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
if (EFI_ERROR (Status)) {
return Status;
}
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
//
// User pressed enter, equivalent to select "continue"
//
return EFI_TIMEOUT;
}
return EFI_SUCCESS;
}
/**
Return the default value for system Timeout variable.
@return Timeout value.
**/
UINT16
EFIAPI
GetTimeout (
VOID
)
{
UINT16 Timeout;
UINTN Size;
EFI_STATUS Status;
//
// Return Timeout variable or 0xffff if no valid
// Timeout variable exists.
//
Size = sizeof (UINT16);
Status = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout);
if (EFI_ERROR (Status)) {
//
// According to UEFI 2.0 spec, it should treat the Timeout value as 0xffff
// (default value PcdPlatformBootTimeOutDefault) when L"Timeout" variable is not present.
// To make the current EFI Automatic-Test activity possible, platform can choose other value
// for automatic boot when the variable is not present.
//
Timeout = PcdGet16 (PcdPlatformBootTimeOutDefault);
}
return Timeout;
}
/**
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 (
IN EFI_FORM_BROWSER_PROTOCOL *This,
IN BOOLEAN UseDatabase,
IN FRAMEWORK_EFI_HII_HANDLE *Handle,
IN UINTN HandleCount,
IN FRAMEWORK_EFI_IFR_PACKET *Packet, OPTIONAL
IN EFI_HANDLE CallbackHandle, OPTIONAL
IN UINT8 *NvMapOverride, OPTIONAL
IN FRAMEWORK_EFI_SCREEN_DESCRIPTOR *ScreenDimensions, OPTIONAL
OUT BOOLEAN *ResetRequired OPTIONAL
)
{
EFI_STATUS Status;
EFI_BROWSER_ACTION_REQUEST ActionRequest;
HII_THUNK_CONTEXT *ThunkContext;
HII_THUNK_PRIVATE_DATA *Private;
EFI_FORMBROWSER_THUNK_PRIVATE_DATA *BrowserPrivate;
if (!UseDatabase) {
//
// ThunkSendForm only support displays forms registered into the HII database.
//
return EFI_UNSUPPORTED;
}
if (HandleCount != 1 ) {
return EFI_UNSUPPORTED;
}
BrowserPrivate = EFI_FORMBROWSER_THUNK_PRIVATE_DATA_FROM_THIS (This);
Private = BrowserPrivate->ThunkPrivate;
ThunkContext = FwHiiHandleToThunkContext (Private, *Handle);
if (ThunkContext == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Following UEFI spec to do auto booting after a time-out. This feature is implemented
// in Framework Setup Browser and moved to MdeModulePkg/Universal/BdsDxe. The auto booting is
// moved here in HII Thunk module.
//
if (CompareGuid (&gFrameworkBdsFrontPageFormsetGuid, &ThunkContext->FormSet->Guid) && !mFrontPageDisplayed) {
//
// Send form is called before entering the
//
mFrontPageDisplayed = TRUE;
Status = ShowProgress (GetTimeout ());
if (EFI_ERROR (Status)) {
return Status;
}
}
if (NvMapOverride != NULL) {
ThunkContext->NvMapOverride = NvMapOverride;
}
Status = mFormBrowser2Protocol->SendForm (
mFormBrowser2Protocol,
&ThunkContext->UefiHiiHandle,
1,
NULL,
0,
(EFI_SCREEN_DESCRIPTOR *) ScreenDimensions,
&ActionRequest
);
if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
*ResetRequired = TRUE;
}
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 (
IN UINTN NumberOfLines,
IN BOOLEAN HotKey,
IN UINTN MaximumStringSize,
OUT CHAR16 *StringBuffer,
OUT EFI_INPUT_KEY *KeyValue,
IN CHAR16 *String,
...
)
{
EFI_STATUS Status;
VA_LIST Marker;
if (HotKey != TRUE) {
return EFI_UNSUPPORTED;
}
VA_START (Marker, String);
Status = IfrLibCreatePopUp2 (NumberOfLines, KeyValue, String, Marker);
VA_END (Marker);
return Status;
}
/**
Initialize string packages in HII database.
**/
VOID
InitSetBrowserStrings (
VOID
)
{
EFI_STATUS Status;
//
// Initialize strings to HII database
//
Status = HiiLibAddPackages (1, &gEfiHiiThunkProducerGuid, NULL, &gStringPackHandle, STRING_ARRAY_NAME);
ASSERT_EFI_ERROR (Status);
}

View File

@@ -0,0 +1,25 @@
/**@file
This file contains macros to be included by SetupBrowser.c.
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HIITHUNK_SETUPBROWSER_H_
#define _HIITHUNK_SETUPBROWSER_H_
//
// In order to follow UEFI spec to do auto booting after a time-out, the GUID of Formset of Frontpage must match this value.
//
#define FRAMEWORK_BDS_FRONTPAGE_FORMSET_GUID { 0x9e0c30bc, 0x3f06, 0x4ba6, {0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe }}
#define ONE_SECOND 10000000
#endif

View File

@@ -0,0 +1,493 @@
/**@file
This file implements the protocol functions related to string package.
Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiDatabase.h"
typedef struct {
CHAR8 *Iso639;
CHAR8 *Rfc3066;
} ISO639TORFC3066MAP;
ISO639TORFC3066MAP Iso639ToRfc3066Map [] = {
{"eng", "en-US"},
{"fra", "fr-FR"},
};
CHAR8 *
ConvertIso639ToRfc3066 (
CHAR8 *Iso638Lang
)
{
UINTN Index;
CHAR8 AsciiLanguage[ISO_639_2_ENTRY_SIZE + 1];
AsciiStrnCpy (AsciiLanguage, Iso638Lang, sizeof (AsciiLanguage));
for (Index = 0; Index < ISO_639_2_ENTRY_SIZE + 1; Index ++) {
if (AsciiLanguage [Index] == 0) {
break;
} else if (AsciiLanguage [Index] >= 'A' && AsciiLanguage [Index] <= 'Z') {
AsciiLanguage [Index] = (CHAR8) (AsciiLanguage [Index] - 'A' + 'a');
}
}
for (Index = 0; Index < sizeof (Iso639ToRfc3066Map) / sizeof (Iso639ToRfc3066Map[0]); Index++) {
if (AsciiStrnCmp (AsciiLanguage, Iso639ToRfc3066Map[Index].Iso639, AsciiStrSize (AsciiLanguage)) == 0) {
return Iso639ToRfc3066Map[Index].Rfc3066;
}
}
return (CHAR8 *) NULL;
}
/**
Test if all of the characters in a string have corresponding font characters.
This is a deprecated API. No Framework HII module is calling it. This function will ASSERT and
return EFI_UNSUPPORTED.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param StringToTest A pointer to a Unicode string.
@param FirstMissing A pointer to an index into the string. On input, the index of
the first character in the StringToTest to examine. On exit, the index
of the first character encountered for which a glyph is unavailable.
If all glyphs in the string are available, the index is the index of the terminator
of the string.
@param GlyphBufferSize A pointer to a value. On output, if the function returns EFI_SUCCESS,
it contains the amount of memory that is required to store the string<6E><67>s glyph equivalent.
@retval EFI_UNSUPPORTED The function performs nothing and return EFI_UNSUPPORTED.
**/
EFI_STATUS
EFIAPI
HiiTestString (
IN EFI_HII_PROTOCOL *This,
IN CHAR16 *StringToTest,
IN OUT UINT32 *FirstMissing,
OUT UINT32 *GlyphBufferSize
)
{
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
/**
Find the corressponding TAG GUID from a Framework HII Handle given.
@param Private The HII Thunk Module Private context.
@param FwHiiHandle The Framemwork HII Handle.
@param TagGuid The output of TAG GUID found.
@return NULL If Framework HII Handle is invalid.
@return The corresponding HII Thunk Context.
**/
EFI_STATUS
GetTagGuidByFwHiiHandle (
IN CONST HII_THUNK_PRIVATE_DATA *Private,
IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle,
OUT EFI_GUID *TagGuid
)
{
LIST_ENTRY *Link;
HII_THUNK_CONTEXT *ThunkContext;
ASSERT (TagGuid != NULL);
Link = GetFirstNode (&Private->ThunkContextListHead);
while (!IsNull (&Private->ThunkContextListHead, Link)) {
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
if (FwHiiHandle == ThunkContext->FwHiiHandle) {
CopyGuid (TagGuid, &ThunkContext->TagGuid);
return EFI_SUCCESS;
}
Link = GetNextNode (&Private->ThunkContextListHead, Link);
}
return EFI_NOT_FOUND;
}
/**
Create or update the String given a new string and String ID.
@param ThunkContext The Thunk Context.
@param Rfc3066AsciiLanguage The RFC 3066 Language code in ASCII string format.
@param NewString The new string.
@param StringId The String ID. If StringId is 0, a new String Token
is created. Otherwise, the String Token StringId is
updated.
@retval EFI_SUCCESS The new string is created or updated successfully.
The new String Token ID is returned in StringId if
*StringId is 0 on input.
@return Others The update of string failed.
**/
EFI_STATUS
UpdateString (
IN CONST HII_THUNK_CONTEXT *ThunkContext,
IN CONST CHAR8 *Rfc3066AsciiLanguage,
IN CHAR16 *NewString,
IN OUT STRING_REF *StringId
)
{
EFI_STRING_ID NewStringId;
EFI_STATUS Status;
NewStringId = 0;
if (*StringId == 0) {
//
// Create a new string token.
//
if (Rfc3066AsciiLanguage == NULL) {
//
// For all languages in the package list.
//
Status = HiiLibNewString (ThunkContext->UefiHiiHandle, &NewStringId, NewString);
} else {
//
// For specified language.
//
Status = mHiiStringProtocol->NewString (
mHiiStringProtocol,
ThunkContext->UefiHiiHandle,
&NewStringId,
Rfc3066AsciiLanguage,
NULL,
NewString,
NULL
);
}
} else {
//
// Update the existing string token.
//
if (Rfc3066AsciiLanguage == NULL) {
//
// For all languages in the package list.
//
Status = HiiLibSetString (ThunkContext->UefiHiiHandle, *StringId, NewString);
} else {
//
// For specified language.
//
Status = mHiiStringProtocol->SetString (
mHiiStringProtocol,
ThunkContext->UefiHiiHandle,
*StringId,
Rfc3066AsciiLanguage,
NewString,
NULL
);
}
}
if (!EFI_ERROR (Status)) {
if (*StringId == 0) {
//
// When creating new string, return the newly created String Token.
//
*StringId = NewStringId;
}
} else {
//
// Only EFI_INVALID_PARAMETER is defined in HII 0.92 specification.
//
*StringId = 0;
}
return Status;
}
/**
Create or update a String Token in a String Package.
If *Reference == 0, a new String Token is created.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param Language Pointer to a NULL-terminated string containing a single ISO 639-2 language
identifier, indicating the language to print. A string consisting of
all spaces indicates that the string is applicable to all languages.
@param Handle The handle of the language pack to which the string is to be added.
@param Token The string token assigned to the string.
@param NewString The string to be added.
@retval EFI_SUCCESS The string was effectively registered.
@retval EFI_INVALID_PARAMETER The Handle was unknown. The string is not created or updated in the
the string package.
**/
EFI_STATUS
EFIAPI
HiiNewString (
IN EFI_HII_PROTOCOL *This,
IN CHAR16 *Language,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN OUT STRING_REF *Reference,
IN CHAR16 *NewString
)
{
EFI_STATUS Status;
HII_THUNK_PRIVATE_DATA *Private;
EFI_GUID TagGuid;
LIST_ENTRY *Link;
HII_THUNK_CONTEXT *ThunkContext;
HII_THUNK_CONTEXT *StringPackThunkContext;
EFI_STRING_ID StringId;
EFI_STRING_ID LastStringId;
CHAR8 AsciiLanguage[ISO_639_2_ENTRY_SIZE + 1];
CHAR16 LanguageCopy[ISO_639_2_ENTRY_SIZE + 1];
CHAR8 *Rfc3066AsciiLanguage;
LastStringId = (EFI_STRING_ID) 0;
StringId = (EFI_STRING_ID) 0;
Rfc3066AsciiLanguage = NULL;
if (Language != NULL) {
ZeroMem (AsciiLanguage, sizeof (AsciiLanguage));;
ZeroMem (LanguageCopy, sizeof (LanguageCopy));
CopyMem (LanguageCopy, Language, ISO_639_2_ENTRY_SIZE * sizeof (CHAR16));
UnicodeStrToAsciiStr (LanguageCopy, AsciiLanguage);
Rfc3066AsciiLanguage = ConvertIso639ToRfc3066 (AsciiLanguage);
ASSERT (Rfc3066AsciiLanguage != NULL);
}
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
StringPackThunkContext = FwHiiHandleToThunkContext (Private, Handle);
if (StringPackThunkContext == NULL) {
return EFI_INVALID_PARAMETER;
}
if (StringPackThunkContext->SharingStringPack) {
Status = GetTagGuidByFwHiiHandle (Private, Handle, &TagGuid);
ASSERT_EFI_ERROR (Status);
Link = GetFirstNode (&Private->ThunkContextListHead);
while (!IsNull (&Private->ThunkContextListHead, Link)) {
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
if (CompareGuid (&TagGuid, &ThunkContext->TagGuid)) {
if (ThunkContext->SharingStringPack) {
StringId = *Reference;
Status = UpdateString (ThunkContext, Rfc3066AsciiLanguage, NewString, &StringId);
if (EFI_ERROR (Status)) {
break;
}
DEBUG_CODE_BEGIN ();
if (*Reference == 0) {
//
// When creating new string token, make sure all created token is the same
// for all string packages registered using FW HII interface.
//
if (LastStringId == (EFI_STRING_ID) 0) {
LastStringId = StringId;
} else {
if (LastStringId != StringId) {
ASSERT(FALSE);
}
}
}
DEBUG_CODE_END ();
}
}
Link = GetNextNode (&Private->ThunkContextListHead, Link);
}
} else {
StringId = *Reference;
Status = UpdateString (StringPackThunkContext, Rfc3066AsciiLanguage, NewString, &StringId);
}
if (!EFI_ERROR (Status)) {
if (*Reference == 0) {
*Reference = StringId;
}
} else {
//
// Only EFI_INVALID_PARAMETER is defined in HII 0.92 specification.
//
Status = EFI_INVALID_PARAMETER;
}
return Status;
}
/**
This function removes any new strings that were added after the initial string export for this handle.
UEFI HII String Protocol does not have Reset String function. This function perform nothing.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param Handle The HII handle on which the string resides.
@retval EFI_SUCCESS This function is a NOP and always return EFI_SUCCESS.
**/
EFI_STATUS
EFIAPI
HiiResetStrings (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle
)
{
return EFI_SUCCESS;
}
/**
This function extracts a string from a package already registered with the EFI HII database.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param Handle The HII handle on which the string resides.
@param Token The string token assigned to the string.
@param Raw If TRUE, the string is returned unedited in the internal storage format described
above. If false, the string returned is edited by replacing <cr> with <space>
and by removing special characters such as the <wide> prefix.
@param LanguageString Pointer to a NULL-terminated string containing a single ISO 639-2 language
identifier, indicating the language to print. If the LanguageString is empty (starts
with a NULL), the default system language will be used to determine the language.
@param BufferLength Length of the StringBuffer. If the status reports that the buffer width is too
small, this parameter is filled with the length of the buffer needed.
@param StringBuffer The buffer designed to receive the characters in the string. Type EFI_STRING is
defined in String.
@retval EFI_INVALID_PARAMETER If input parameter is invalid.
@retval EFI_BUFFER_TOO_SMALL If the *BufferLength is too small.
@retval EFI_SUCCESS Operation is successful.
**/
EFI_STATUS
EFIAPI
HiiGetString (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN STRING_REF Token,
IN BOOLEAN Raw,
IN CHAR16 *LanguageString,
IN OUT UINTN *BufferLengthTemp,
OUT EFI_STRING StringBuffer
)
{
CHAR8 *Iso639AsciiLanguage;
HII_THUNK_PRIVATE_DATA *Private;
CHAR8 *Rfc3066AsciiLanguage;
EFI_HII_HANDLE UefiHiiHandle;
EFI_STATUS Status;
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
Iso639AsciiLanguage = NULL;
Rfc3066AsciiLanguage = NULL;
if (LanguageString != NULL) {
Iso639AsciiLanguage = AllocateZeroPool (StrLen (LanguageString) + 1);
if (Iso639AsciiLanguage == NULL) {
return EFI_OUT_OF_RESOURCES;
}
UnicodeStrToAsciiStr (LanguageString, Iso639AsciiLanguage);
//
// Caller of Framework HII Interface uses the Language Identification String defined
// in Iso639. So map it to the Language Identifier defined in RFC3066.
//
Rfc3066AsciiLanguage = ConvertIso639ToRfc3066 (Iso639AsciiLanguage);
//
// If Rfc3066AsciiLanguage is NULL, more language mapping must be added to
// Iso639ToRfc3066Map.
//
ASSERT (Rfc3066AsciiLanguage != NULL);
}
UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);
if (UefiHiiHandle == NULL) {
Status = EFI_NOT_FOUND;
goto Done;
}
if (Rfc3066AsciiLanguage == NULL) {
Status = HiiLibGetString (UefiHiiHandle, Token, StringBuffer, BufferLengthTemp);
} else {
Status = mHiiStringProtocol->GetString (
mHiiStringProtocol,
Rfc3066AsciiLanguage,
UefiHiiHandle,
Token,
StringBuffer,
BufferLengthTemp,
NULL
);
}
Done:
if (Iso639AsciiLanguage != NULL) {
FreePool (Iso639AsciiLanguage);
}
return Status;
}
/**
This function allows a program to extract a part of a string of not more than a given width.
With repeated calls, this allows a calling program to extract "lines" of text that fit inside
columns. The effort of measuring the fit of strings inside columns is localized to this call.
This is a deprecated API. No Framework HII module is calling it. This function will ASSERT and
return EFI_UNSUPPORTED.
@param This A pointer to the EFI_HII_PROTOCOL instance.
@param Handle The HII handle on which the string resides.
@param Token The string token assigned to the string.
@param Raw If TRUE, the string is returned unedited in the internal storage format described
above. If false, the string returned is edited by replacing <cr> with <space>
and by removing special characters such as the <wide> prefix.
@param LanguageString Pointer to a NULL-terminated string containing a single ISO 639-2 language
identifier, indicating the language to print. If the LanguageString is empty (starts
with a NULL), the default system language will be used to determine the language.
@param BufferLength Length of the StringBuffer. If the status reports that the buffer width is too
small, this parameter is filled with the length of the buffer needed.
@param StringBuffer The buffer designed to receive the characters in the string. Type EFI_STRING is
defined in String.
@retval EFI_UNSUPPORTED.
**/
EFI_STATUS
EFIAPI
HiiGetLine (
IN EFI_HII_PROTOCOL *This,
IN FRAMEWORK_EFI_HII_HANDLE Handle,
IN STRING_REF Token,
IN OUT UINT16 *Index,
IN UINT16 LineWidth,
IN CHAR16 *LanguageString,
IN OUT UINT16 *BufferLength,
OUT EFI_STRING StringBuffer
)
{
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}

View File

@@ -0,0 +1,551 @@
/** @file
Function and Macro defintions for to extract default values from UEFI Form package.
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiDatabase.h"
#include "UefiIfrParser.h"
#include "UefiIfrDefault.h"
//
// Extern Variables
//
extern CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;
extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;
extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;
/**
Set the data position at Offset with Width in Node->Buffer based
the value passed in.
@param Node The Buffer Storage Node.
@param Value The input value.
@param Offset The offset in Node->Buffer for the update.
@param Width The length of the Value.
@retval VOID
**/
VOID
SetNodeBuffer (
OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node,
IN CONST EFI_HII_VALUE *Value,
IN UINTN Offset,
IN UINTN Width
)
{
ASSERT (Node->Signature == UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE);
ASSERT (Offset + Width <= Node->Size);
CopyMem (Node->Buffer + Offset, &Value->Value.u8, Width);
}
/**
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.
@retval EFI_SUCCESS Question is reset to default value.
**/
EFI_STATUS
GetQuestionDefault (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form,
IN FORM_BROWSER_STATEMENT *Question,
IN UINT16 DefaultId,
IN UINT16 VarStoreId,
OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
QUESTION_DEFAULT *Default;
QUESTION_OPTION *Option;
EFI_HII_VALUE *HiiValue;
Status = EFI_SUCCESS;
//
// Statement don't have storage, skip them
//
if (Question->QuestionId == 0) {
return Status;
}
if (Question->VarStoreId != VarStoreId) {
return Status;
}
ASSERT (Question->Storage->Type == EFI_HII_VARSTORE_BUFFER);
//
// There are three ways to specify default value for a Question:
// 1, use nested EFI_IFR_DEFAULT (highest priority)
// 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
// 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
//
HiiValue = &Question->HiiValue;
//
// EFI_IFR_DEFAULT has highest priority
//
if (!IsListEmpty (&Question->DefaultListHead)) {
Link = GetFirstNode (&Question->DefaultListHead);
while (!IsNull (&Question->DefaultListHead, Link)) {
Default = QUESTION_DEFAULT_FROM_LINK (Link);
if (Default->DefaultId == DefaultId) {
//
// 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;
}
Link = GetNextNode (&Question->DefaultListHead, Link);
}
}
//
// EFI_ONE_OF_OPTION
//
if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {
if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
//
// OneOfOption could only provide Standard and Manufacturing default
//
Link = GetFirstNode (&Question->OptionListHead);
while (!IsNull (&Question->OptionListHead, Link)) {
Option = QUESTION_OPTION_FROM_LINK (Link);
if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Option->Flags & EFI_IFR_OPTION_DEFAULT)) ||
((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG))
) {
CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));
SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);
return EFI_SUCCESS;
}
Link = GetNextNode (&Question->OptionListHead, Link);
}
}
}
//
// EFI_IFR_CHECKBOX - lowest priority
//
if (Question->Operand == EFI_IFR_CHECKBOX_OP) {
if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
//
// Checkbox could only provide Standard and Manufacturing default
//
if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT)) ||
((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG))
) {
HiiValue->Value.b = TRUE;
} else {
HiiValue->Value.b = FALSE;
}
SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);
return EFI_SUCCESS;
}
}
return Status;
}
/**
Reset Questions in a Form to their default value.
@param FormSet FormSet data structure.
@param Form The Form which to be reset.
@param DefaultId The Class of the default.
@retval EFI_SUCCESS The function completed successfully.
**/
EFI_STATUS
ExtractFormDefault (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form,
IN UINT16 DefaultId,
IN UINT16 VarStoreId,
OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Question;
Link = GetFirstNode (&Form->StatementListHead);
while (!IsNull (&Form->StatementListHead, Link)) {
Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
//
// Reset Question to its default value
//
Status = GetQuestionDefault (FormSet, Form, Question, DefaultId, VarStoreId, Node);
if (EFI_ERROR (Status)) {
continue;
}
Link = GetNextNode (&Form->StatementListHead, Link);
}
return EFI_SUCCESS;
}
/**
Destroy all the buffer allocated for the fileds of
UEFI_IFR_BUFFER_STORAGE_NODE. The Node itself
will be freed too.
@param FormSet FormSet data structure.
@param DefaultId The Class of the default.
@retval VOID
**/
VOID
DestroyDefaultNode (
IN UEFI_IFR_BUFFER_STORAGE_NODE *Node
)
{
FreePool (Node->Buffer);
FreePool (Node->Name);
FreePool (Node);
}
/**
Get the default value for Buffer Type storage named by
a Default Store and a Storage Store from a FormSet.
The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE
allocated by this function. It is inserted to the link list.
@param DefaultStore The Default Store.
@param Storage The Storage.
@param FormSet The Form Set.
@param UefiDefaultsListHead The head of link list for the output.
@retval EFI_SUCCESS Successful.
**/
EFI_STATUS
GetBufferTypeDefaultIdAndStorageId (
IN FORMSET_DEFAULTSTORE *DefaultStore,
IN FORMSET_STORAGE *Storage,
IN FORM_BROWSER_FORMSET *FormSet,
OUT LIST_ENTRY *UefiDefaultsListHead
)
{
UEFI_IFR_BUFFER_STORAGE_NODE *Node;
LIST_ENTRY *Link;
FORM_BROWSER_FORM *Form;
EFI_STATUS Status;
Node = AllocateZeroPool (sizeof (UEFI_IFR_BUFFER_STORAGE_NODE));
ASSERT (Node != NULL);
Node->Signature = UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE;
Node->Name = AllocateCopyPool (StrSize (Storage->Name), Storage->Name);
Node->DefaultId = DefaultStore->DefaultId;
Node->StoreId = Storage->VarStoreId;
CopyGuid (&Node->Guid, &Storage->Guid);
Node->Size = Storage->Size;
Node->Buffer = AllocateZeroPool (Node->Size);
//
// Extract default from IFR binary
//
Link = GetFirstNode (&FormSet->FormListHead);
while (!IsNull (&FormSet->FormListHead, Link)) {
Form = FORM_BROWSER_FORM_FROM_LINK (Link);
Status = ExtractFormDefault (FormSet, Form, DefaultStore->DefaultId, Storage->VarStoreId, Node);
ASSERT_EFI_ERROR (Status);
Link = GetNextNode (&FormSet->FormListHead, Link);
}
InsertTailList (UefiDefaultsListHead, &Node->List);
return EFI_SUCCESS;
}
/**
Get the default value for Buffer Type storage named by
a Default Store from a FormSet.
The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE
allocated by this function. The output can be multiple instances
of UEFI_IFR_BUFFER_STORAGE_NODE. It is inserted to the link list.
@param DefaultStore The Default Store.
@param FormSet The Form Set.
@param UefiDefaultsListHead The head of link list for the output.
@retval EFI_SUCCESS Successful.
**/
EFI_STATUS
GetBufferTypeDefaultId (
IN FORMSET_DEFAULTSTORE *DefaultStore,
IN FORM_BROWSER_FORMSET *FormSet,
OUT LIST_ENTRY *UefiDefaultsListHead
)
{
LIST_ENTRY *StorageLink;
FORMSET_STORAGE *Storage;
EFI_STATUS Status;
StorageLink = GetFirstNode (&FormSet->StorageListHead);
while (!IsNull (&FormSet->StorageListHead, StorageLink)) {
Storage = FORMSET_STORAGE_FROM_LINK(StorageLink);
if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
Status = GetBufferTypeDefaultIdAndStorageId (DefaultStore, Storage, FormSet, UefiDefaultsListHead);
ASSERT_EFI_ERROR (Status);
}
StorageLink = GetNextNode (&FormSet->StorageListHead, StorageLink);
}
return EFI_SUCCESS;
}
/**
Get the default value for Buffer Type storage from the first FormSet
in the Package List specified by a EFI_HII_HANDLE.
The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE.
They are inserted to the link list.
@param UefiHiiHandle The handle for the package list.
@param UefiDefaultsListHead The head of link list for the output.
@retval EFI_SUCCESS Successful.
**/
EFI_STATUS
UefiIfrGetBufferTypeDefaults (
IN HII_THUNK_CONTEXT *ThunkContext,
OUT LIST_ENTRY **UefiDefaults
)
{
LIST_ENTRY *DefaultLink;
FORMSET_DEFAULTSTORE *DefaultStore;
EFI_STATUS Status;
ASSERT (UefiDefaults != NULL);
*UefiDefaults = AllocateZeroPool (sizeof (LIST_ENTRY));
ASSERT (UefiDefaults != NULL);
InitializeListHead (*UefiDefaults);
DefaultLink = GetFirstNode (&ThunkContext->FormSet->DefaultStoreListHead);
while (!IsNull (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink)) {
DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);
Status = GetBufferTypeDefaultId (DefaultStore, ThunkContext->FormSet, *UefiDefaults);
ASSERT_EFI_ERROR (Status);
DefaultLink = GetNextNode (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink);
}
return EFI_SUCCESS;
}
/**
Convert the UEFI Buffer Type default values to a Framework HII default
values specified by a EFI_HII_VARIABLE_PACK_LIST structure.
@param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE
which contains the default values retrived from
a UEFI form set.
@param DefaultMask The default mask.
The valid values are FRAMEWORK_EFI_IFR_FLAG_DEFAULT
and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.
UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
from specification to valid default class.
@param VariablePackList The output default value in a format defined in Framework.
@retval EFI_SUCCESS Successful.
@retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or
FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.
**/
EFI_STATUS
UefiDefaultsToFwDefaults (
IN LIST_ENTRY *ListHead,
IN UINTN DefaultMask,
IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId,
OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList
)
{
LIST_ENTRY *List;
UEFI_IFR_BUFFER_STORAGE_NODE *Node;
UINTN Size;
UINTN Count;
UINT16 DefaultId;
EFI_HII_VARIABLE_PACK *Pack;
EFI_HII_VARIABLE_PACK_LIST *PackList;
UINTN Index;
if (DefaultMask == FRAMEWORK_EFI_IFR_FLAG_DEFAULT) {
DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
} else if (DefaultMask == FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING) {
DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
} else {
//
// UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
// from specification to valid default class.
//
ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
//
// Calculate the size of the output EFI_HII_VARIABLE_PACK_LIST structure
//
Size = 0;
Count = 0;
List = GetFirstNode (ListHead);
while (!IsNull (ListHead, List)) {
Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);
if (Node->DefaultId == DefaultId) {
Size += Node->Size;
Size += StrSize (Node->Name);
Count++;
}
List = GetNextNode (ListHead, List);
}
if (Count == 0) {
*VariablePackList = NULL;
return EFI_NOT_FOUND;
}
Size = Size + Count * (sizeof (EFI_HII_VARIABLE_PACK_LIST) + sizeof (EFI_HII_VARIABLE_PACK));
*VariablePackList = AllocateZeroPool (Size);
ASSERT (*VariablePackList != NULL);
List = GetFirstNode (ListHead);
PackList = (EFI_HII_VARIABLE_PACK_LIST *) *VariablePackList;
Pack = (EFI_HII_VARIABLE_PACK *) (PackList + 1);
Index = 0;
while (!IsNull (ListHead, List)) {
Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);
Size = 0;
if (Node->DefaultId == DefaultId) {
Size += Node->Size;
Size += sizeof (EFI_HII_VARIABLE_PACK);
Pack->VariableNameLength = (UINT32) StrSize (Node->Name);
if (Node->StoreId == UefiFormSetDefaultVarStoreId) {
//
// The default VARSTORE in VFR from a Framework module has Varstore ID of 0.
//
Pack->VariableId = 0;
} else {
Pack->VariableId = Node->StoreId;
}
CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK), Node->Name, StrSize (Node->Name));
Size += Pack->VariableNameLength;
//
// Initialize EFI_HII_VARIABLE_PACK
//
Pack->Header.Type = 0;
Pack->Header.Length = (UINT32) Size;
CopyMem (&Pack->VariableGuid, &Node->Guid, sizeof (EFI_GUID));
CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK) + Pack->VariableNameLength, Node->Buffer, Node->Size);
Size += sizeof (EFI_HII_VARIABLE_PACK_LIST);
//
// Initialize EFI_HII_VARIABLE_PACK_LIST
//
PackList->VariablePack = Pack;
Index++;
if (Index < Count) {
PackList->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *)((UINT8 *) PackList + Size);
PackList = PackList->NextVariablePack;
Pack = (EFI_HII_VARIABLE_PACK *) (PackList + 1);
}
}
List = GetNextNode (ListHead, List);
}
return EFI_SUCCESS;
}
/**
Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.
@param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE
which contains the default values retrived from
a UEFI form set.
@retval VOID
**/
VOID
FreeDefaultList (
IN LIST_ENTRY *ListHead
)
{
LIST_ENTRY *Link;
UEFI_IFR_BUFFER_STORAGE_NODE *Default;
while (!IsListEmpty (ListHead)) {
Link = GetFirstNode (ListHead);
Default = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(Link);
RemoveEntryList (Link);
DestroyDefaultNode (Default);
}
FreePool (ListHead);
}

View File

@@ -0,0 +1,99 @@
/** @file
Header file for Function and Macro defintions for to extract default values from UEFI Form package.
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HII_THUNK_UEFI_IFR_DEFAULT_
#define _HII_THUNK_UEFI_IFR_DEFAULT_
#define UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(a) CR(a, UEFI_IFR_BUFFER_STORAGE_NODE, List, UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE)
#define UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE SIGNATURE_32 ('I', 'b', 'S', 'n')
typedef struct {
LIST_ENTRY List;
UINT32 Signature;
EFI_GUID Guid;
CHAR16 *Name;
UINT16 DefaultId;
UINT16 StoreId;
UINTN Size;
UINT8 *Buffer;
} UEFI_IFR_BUFFER_STORAGE_NODE;
/**
Get the default value for Buffer Type storage from the first FormSet
in the Package List specified by a EFI_HII_HANDLE.
The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE.
They are inserted to the link list.
@param UefiHiiHandle The handle for the package list.
@param UefiDefaultsListHead The head of link list for the output.
@retval EFI_SUCCESS Successful.
**/
EFI_STATUS
UefiIfrGetBufferTypeDefaults (
IN HII_THUNK_CONTEXT *ThunkContext,
OUT LIST_ENTRY **UefiDefaults
);
/**
Convert the UEFI Buffer Type default values to a Framework HII default
values specified by a EFI_HII_VARIABLE_PACK_LIST structure.
@param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE
which contains the default values retrived from
a UEFI form set.
@param DefaultMask The default mask.
The valid values are FRAMEWORK_EFI_IFR_FLAG_DEFAULT
and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.
UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
from specification to valid default class.
@param VariablePackList The output default value in a format defined in Framework.
@retval EFI_SUCCESS Successful.
@retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or
FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.
**/
EFI_STATUS
UefiDefaultsToFwDefaults (
IN LIST_ENTRY *UefiIfrDefaults,
IN UINTN DefaultMask,
IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId,
OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList
);
/**
Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.
@param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE
which contains the default values retrived from
a UEFI form set.
@retval EFI_SUCCESS Successful.
@retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or
FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.
**/
VOID
FreeDefaultList (
IN LIST_ENTRY *UefiIfrDefaults
);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,344 @@
/** @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
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HII_THUNK_UEFI_IFR_PARSER_
#define _HII_THUNK_UEFI_IFR_PARSER_
//
// IFR relative definition
//
#define EFI_HII_EXPRESSION_INCONSISTENT_IF 0
#define EFI_HII_EXPRESSION_NO_SUBMIT_IF 1
#define EFI_HII_EXPRESSION_GRAY_OUT_IF 2
#define EFI_HII_EXPRESSION_SUPPRESS_IF 3
#define EFI_HII_EXPRESSION_DISABLE_IF 4
#define EFI_HII_EXPRESSION_VALUE 5
#define EFI_HII_EXPRESSION_RULE 6
#define EFI_HII_VARSTORE_BUFFER 0
#define EFI_HII_VARSTORE_NAME_VALUE 1
#define EFI_HII_VARSTORE_EFI_VARIABLE 2
#define FORM_INCONSISTENT_VALIDATION 0
#define FORM_NO_SUBMIT_VALIDATION 1
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 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 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;
EFI_IFR_TYPE_VALUE Value;
} EFI_HII_VALUE;
#define NAME_VALUE_NODE_SIGNATURE SIGNATURE_32 ('N', 'V', 'S', 'T')
#define FORMSET_STORAGE_SIGNATURE SIGNATURE_32 ('F', 'S', 'T', 'G')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT8 Type; // Storage type
UINT16 VarStoreId;
EFI_GUID Guid;
CHAR16 *Name; // For EFI_IFR_VARSTORE
UINT16 Size;
UINT32 Attributes; // For EFI_IFR_VARSTORE_EFI: EFI Variable attribute
} FORMSET_STORAGE;
#define FORMSET_STORAGE_FROM_LINK(a) CR (a, FORMSET_STORAGE, Link, FORMSET_STORAGE_SIGNATURE)
#if 0
#define EXPRESSION_OPCODE_SIGNATURE SIGNATURE_32 ('E', 'X', 'O', 'P')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT8 Operand;
UINT8 Format; // For EFI_IFR_TO_STRING, EFI_IFR_FIND
UINT8 Flags; // For EFI_IFR_SPAN
UINT8 RuleId; // For EFI_IFR_RULE_REF
EFI_HII_VALUE Value; // For EFI_IFR_EQ_ID_VAL, EFI_IFR_UINT64, EFI_IFR_UINT32, EFI_IFR_UINT16, EFI_IFR_UINT8, EFI_IFR_STRING_REF1
EFI_QUESTION_ID QuestionId; // For EFI_IFR_EQ_ID_ID, EFI_IFR_EQ_ID_LIST, EFI_IFR_QUESTION_REF1
EFI_QUESTION_ID QuestionId2;
UINT16 ListLength; // For EFI_IFR_EQ_ID_LIST
UINT16 *ValueList;
EFI_STRING_ID DevicePath; // For EFI_IFR_QUESTION_REF3_2, EFI_IFR_QUESTION_REF3_3
EFI_GUID Guid;
} EXPRESSION_OPCODE;
#define EXPRESSION_OPCODE_FROM_LINK(a) CR (a, EXPRESSION_OPCODE, Link, EXPRESSION_OPCODE_SIGNATURE)
#define FORM_EXPRESSION_SIGNATURE SIGNATURE_32 ('F', 'E', 'X', 'P')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT8 Type; // Type for this expression
UINT8 RuleId; // For EFI_IFR_RULE only
EFI_STRING_ID Error; // For EFI_IFR_NO_SUBMIT_IF, EFI_IFR_INCONSISTENT_IF only
EFI_HII_VALUE Result; // Expression evaluation result
LIST_ENTRY OpCodeListHead; // OpCodes consist of this expression (EXPRESSION_OPCODE)
} FORM_EXPRESSION;
#define FORM_EXPRESSION_FROM_LINK(a) CR (a, FORM_EXPRESSION, Link, FORM_EXPRESSION_SIGNATURE)
#endif
#define QUESTION_DEFAULT_SIGNATURE SIGNATURE_32 ('Q', 'D', 'F', 'T')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT16 DefaultId;
EFI_HII_VALUE Value; // Default value
} QUESTION_DEFAULT;
#define QUESTION_DEFAULT_FROM_LINK(a) CR (a, QUESTION_DEFAULT, Link, QUESTION_DEFAULT_SIGNATURE)
#define QUESTION_OPTION_SIGNATURE SIGNATURE_32 ('Q', 'O', 'P', 'T')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
EFI_STRING_ID Text;
UINT8 Flags;
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)
#define FORM_BROWSER_STATEMENT_SIGNATURE SIGNATURE_32 ('F', 'S', 'T', 'A')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT8 Operand; // The operand (first byte) of this Statement or Question
//
// Statement Header
//
EFI_STRING_ID Prompt;
EFI_STRING_ID Help;
EFI_STRING_ID TextTwo; // For EFI_IFR_TEXT
//
// Question Header
//
EFI_QUESTION_ID QuestionId; // The value of zero is reserved
EFI_VARSTORE_ID VarStoreId; // A value of zero indicates no variable storage
FORMSET_STORAGE *Storage;
union {
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
//
// OpCode specific members
//
UINT8 Flags; // for EFI_IFR_CHECKBOX, EFI_IFR_DATE, EFI_IFR_NUMERIC, EFI_IFR_ONE_OF,
// EFI_IFR_ORDERED_LIST, EFI_IFR_STRING,EFI_IFR_SUBTITLE,EFI_IFR_TIME, EFI_IFR_BANNER
UINT8 MaxContainers; // for EFI_IFR_ORDERED_LIST
UINT16 BannerLineNumber; // for EFI_IFR_BANNER, 1-based line number
EFI_STRING_ID QuestionConfig; // for EFI_IFR_ACTION, if 0 then no configuration string will be processed
UINT64 Minimum; // for EFI_IFR_ONE_OF/EFI_IFR_NUMERIC, it's Min/Max value
UINT64 Maximum; // for EFI_IFR_STRING/EFI_IFR_PASSWORD, it's Min/Max length
UINT64 Step;
EFI_DEFAULT_ID DefaultId; // for EFI_IFR_RESET_BUTTON
EFI_FORM_ID RefFormId; // for EFI_IFR_REF
EFI_QUESTION_ID RefQuestionId; // for EFI_IFR_REF2
EFI_GUID RefFormSetId; // for EFI_IFR_REF3
EFI_STRING_ID RefDevicePath; // for EFI_IFR_REF4
//
// 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)
EFI_IMAGE_ID ImageId; // nested EFI_IFR_IMAGE
UINT8 RefreshInterval; // nested EFI_IFR_REFRESH, refresh interval(in seconds) for Question value, 0 means no refresh
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;
#define FORM_BROWSER_STATEMENT_FROM_LINK(a) CR (a, FORM_BROWSER_STATEMENT, Link, FORM_BROWSER_STATEMENT_SIGNATURE)
#define FORM_BROWSER_FORM_SIGNATURE SIGNATURE_32 ('F', 'F', 'R', 'M')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT16 FormId;
EFI_STRING_ID FormTitle;
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;
#define FORM_BROWSER_FORM_FROM_LINK(a) CR (a, FORM_BROWSER_FORM, Link, FORM_BROWSER_FORM_SIGNATURE)
#define FORMSET_DEFAULTSTORE_SIGNATURE SIGNATURE_32 ('F', 'D', 'F', 'S')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
UINT16 DefaultId;
EFI_STRING_ID DefaultName;
} FORMSET_DEFAULTSTORE;
#define FORMSET_DEFAULTSTORE_FROM_LINK(a) CR (a, FORMSET_DEFAULTSTORE, Link, FORMSET_DEFAULTSTORE_SIGNATURE)
typedef struct {
EFI_HII_HANDLE HiiHandle;
UINTN IfrBinaryLength;
UINT8 *IfrBinaryData;
EFI_GUID Guid;
EFI_STRING_ID FormSetTitle;
EFI_STRING_ID Help;
UINT16 Class;
UINT16 SubClass;
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;
//
// Added for Framework HII Thunk.
// Default Variable Storage built from a Framework VFR file using UEFI VFR Compiler in Compatibility mode is determined
// by priority rules defined in GetFormsetDefaultVarstoreId (). See the function description for details.
//
EFI_VARSTORE_ID DefaultVarStoreId;
CHAR16 *OriginalDefaultVarStoreName;
UINTN NumberOfStatement;
} FORM_BROWSER_FORMSET;
EFI_STATUS
ParseOpCodes (
IN FORM_BROWSER_FORMSET *FormSet
);
VOID
DestroyFormSet (
IN OUT FORM_BROWSER_FORMSET *FormSet
);
#endif

View File

@@ -0,0 +1,374 @@
/** @file
Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Expression.c
Abstract:
Expression evaluation.
**/
#include <PiDxe.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/UnicodeCollation.h>
#include "UefiIfrParser.h"
//
// Global stack used to evaluate boolean expresions
//
EFI_HII_VALUE *mOpCodeScopeStack = NULL;
EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;
EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;
EFI_HII_VALUE *mExpressionEvaluationStack = NULL;
EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;
EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;
#define EXPRESSION_STACK_SIZE_INCREMENT 0x100
/**
Grow size of the stack
@param Stack On input: old stack; On output: new stack
@param StackPtr On input: old stack pointer; On output: new stack
pointer
@param StackPtr On input: old stack end; On output: new stack end
@retval EFI_SUCCESS Grow stack success.
@retval EFI_OUT_OF_RESOURCES No enough memory for stack space.
**/
STATIC
EFI_STATUS
GrowStack (
IN OUT EFI_HII_VALUE **Stack,
IN OUT EFI_HII_VALUE **StackPtr,
IN OUT EFI_HII_VALUE **StackEnd
)
{
UINTN Size;
EFI_HII_VALUE *NewStack;
Size = EXPRESSION_STACK_SIZE_INCREMENT;
if (*StackPtr != NULL) {
Size = Size + (*StackEnd - *Stack);
}
NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));
if (NewStack == NULL) {
return EFI_OUT_OF_RESOURCES;
}
if (*StackPtr != NULL) {
//
// Copy from Old Stack to the New Stack
//
CopyMem (
NewStack,
*Stack,
(*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)
);
//
// Free The Old Stack
//
gBS->FreePool (*Stack);
}
//
// Make the Stack pointer point to the old data in the new stack
//
*StackPtr = NewStack + (*StackPtr - *Stack);
*Stack = NewStack;
*StackEnd = NewStack + Size;
return EFI_SUCCESS;
}
/**
Push an element onto the Boolean Stack
@param Stack On input: old stack; On output: new stack
@param StackPtr On input: old stack pointer; On output: new stack
pointer
@param StackPtr On input: old stack end; On output: new stack end
@param Data Data to push.
@retval EFI_SUCCESS Push stack success.
**/
EFI_STATUS
PushStack (
IN OUT EFI_HII_VALUE **Stack,
IN OUT EFI_HII_VALUE **StackPtr,
IN OUT EFI_HII_VALUE **StackEnd,
IN EFI_HII_VALUE *Data
)
{
EFI_STATUS Status;
//
// Check for a stack overflow condition
//
if (*StackPtr >= *StackEnd) {
//
// Grow the stack
//
Status = GrowStack (Stack, StackPtr, StackEnd);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// Push the item onto the stack
//
CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));
*StackPtr = *StackPtr + 1;
return EFI_SUCCESS;
}
/**
Pop an element from the stack.
@param Stack On input: old stack; On output: new stack
@param StackPtr On input: old stack pointer; On output: new stack
pointer
@param StackPtr On input: old stack end; On output: new stack end
@param Data Data to pop.
@retval EFI_SUCCESS The value was popped onto the stack.
@retval EFI_ACCESS_DENIED The pop operation underflowed the stack
**/
EFI_STATUS
PopStack (
IN OUT EFI_HII_VALUE **Stack,
IN OUT EFI_HII_VALUE **StackPtr,
IN OUT EFI_HII_VALUE **StackEnd,
OUT EFI_HII_VALUE *Data
)
{
//
// Check for a stack underflow condition
//
if (*StackPtr == *Stack) {
return EFI_ACCESS_DENIED;
}
//
// Pop the item off the stack
//
*StackPtr = *StackPtr - 1;
CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));
return EFI_SUCCESS;
}
/**
Reset stack pointer to begin of the stack.
None.
@return None.
**/
VOID
ResetScopeStack (
VOID
)
{
mOpCodeScopeStackPointer = mOpCodeScopeStack;
}
/**
Push an Operand onto the Stack
@param Operand Operand to push.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
stack.
**/
EFI_STATUS
PushScope (
IN UINT8 Operand
)
{
EFI_HII_VALUE Data;
Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;
Data.Value.u8 = Operand;
return PushStack (
&mOpCodeScopeStack,
&mOpCodeScopeStackPointer,
&mOpCodeScopeStackEnd,
&Data
);
}
/**
Pop an Operand from the Stack
@param Operand Operand to pop.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
stack.
**/
EFI_STATUS
PopScope (
OUT UINT8 *Operand
)
{
EFI_STATUS Status;
EFI_HII_VALUE Data;
Status = PopStack (
&mOpCodeScopeStack,
&mOpCodeScopeStackPointer,
&mOpCodeScopeStackEnd,
&Data
);
*Operand = Data.Value.u8;
return Status;
}
/**
Reset stack pointer to begin of the stack.
None.
@return None.
**/
VOID
ResetExpressionStack (
VOID
)
{
mExpressionEvaluationStackPointer = mExpressionEvaluationStack;
}
/**
Push an Expression value onto the Stack
@param Value Expression value to push.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
stack.
**/
EFI_STATUS
PushExpression (
IN EFI_HII_VALUE *Value
)
{
return PushStack (
&mExpressionEvaluationStack,
&mExpressionEvaluationStackPointer,
&mExpressionEvaluationStackEnd,
Value
);
}
/**
Pop an Expression value from the stack.
@param Value Expression value to pop.
@retval EFI_SUCCESS The value was popped onto the stack.
@retval EFI_ACCESS_DENIED The pop operation underflowed the stack
**/
EFI_STATUS
PopExpression (
OUT EFI_HII_VALUE *Value
)
{
return PopStack (
&mExpressionEvaluationStack,
&mExpressionEvaluationStackPointer,
&mExpressionEvaluationStackEnd,
Value
);
}
/**
Zero extend integer/boolean/date/time to UINT64 for comparing.
@param Value HII Value to be converted.
@return None.
**/
VOID
ExtendValueToU64 (
IN EFI_HII_VALUE *Value
)
{
UINT64 Temp;
Temp = 0;
switch (Value->Type) {
case EFI_IFR_TYPE_NUM_SIZE_8:
Temp = Value->Value.u8;
break;
case EFI_IFR_TYPE_NUM_SIZE_16:
Temp = Value->Value.u16;
break;
case EFI_IFR_TYPE_NUM_SIZE_32:
Temp = Value->Value.u32;
break;
case EFI_IFR_TYPE_BOOLEAN:
Temp = Value->Value.b;
break;
case EFI_IFR_TYPE_TIME:
Temp = Value->Value.u32 & 0xffffff;
break;
case EFI_IFR_TYPE_DATE:
Temp = Value->Value.u32;
break;
default:
return;
}
Value->Value.u64 = Temp;
}

View File

@@ -0,0 +1,96 @@
/** @file
Internal Function and Macro defintions for IFR Expression evaluation used in Ifr Parsing. This header file should only
be included by UefiIfrParserExpression.c and UefiIfrParser.c
Copyright (c) 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_
#define _HII_THUNK_UEFI_IFR_PARSER_EXPRESSION_
/**
Reset stack pointer to begin of the stack.
None.
@return None.
**/
VOID
ResetScopeStack (
VOID
);
/**
Push an Operand onto the Stack
@param Operand Operand to push.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
stack.
**/
EFI_STATUS
PushScope (
IN UINT8 Operand
);
/**
Pop an Operand from the Stack
@param Operand Operand to pop.
@retval EFI_SUCCESS The value was pushed onto the stack.
@retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
stack.
**/
EFI_STATUS
PopScope (
OUT UINT8 *Operand
);
/**
Zero extend integer/boolean/date/time to UINT64 for comparing.
@param Value HII Value to be converted.
@return None.
**/
VOID
ExtendValueToU64 (
IN EFI_HII_VALUE *Value
);
/**
Compare two Hii value.
@param Value1 Expression value to compare on left-hand
@param Value2 Expression value to compare on right-hand
@param HiiHandle Only required for string compare
@retval EFI_INVALID_PARAMETER Could not perform comparation on two values
@retval 0 Two operators equeal
@retval 0 Value1 is greater than Value2
@retval 0 Value1 is less than Value2
**/
INTN
CompareHiiValue (
IN EFI_HII_VALUE *Value1,
IN EFI_HII_VALUE *Value2,
IN EFI_HII_HANDLE HiiHandle OPTIONAL
);
#endif

View File

@@ -0,0 +1,687 @@
/**@file
This file contains the keyboard processing code to the HII database.
Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "HiiDatabase.h"
#include "HiiHandle.h"
#include <Library/DebugLib.h>
CONST EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
CONST CHAR16 FrameworkReservedVarstoreName[] = FRAMEWORK_RESERVED_VARSTORE_NAME;
/**
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,
IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle
)
{
HII_THUNK_CONTEXT *ThunkContext;
ASSERT (FwHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);
ASSERT (Private != NULL);
ThunkContext = FwHiiHandleToThunkContext (Private, FwHiiHandle);
if (ThunkContext != NULL) {
return ThunkContext->UefiHiiHandle;
}
return (EFI_HII_HANDLE) NULL;
}
/**
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,
IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle
)
{
LIST_ENTRY *Link;
HII_THUNK_CONTEXT *ThunkContext;
Link = GetFirstNode (&Private->ThunkContextListHead);
while (!IsNull (&Private->ThunkContextListHead, Link)) {
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
if (FwHiiHandle == ThunkContext->FwHiiHandle) {
return ThunkContext;
}
Link = GetNextNode (&Private->ThunkContextListHead, Link);
}
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,
IN EFI_HII_HANDLE UefiHiiHandle
)
{
LIST_ENTRY *Link;
HII_THUNK_CONTEXT *ThunkContext;
Link = GetFirstNode (&Private->ThunkContextListHead);
while (!IsNull (&Private->ThunkContextListHead, Link)) {
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
if (UefiHiiHandle == ThunkContext->UefiHiiHandle) {
return ThunkContext;
}
Link = GetNextNode (&Private->ThunkContextListHead, Link);
}
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,
IN CONST EFI_GUID *Guid
)
{
LIST_ENTRY *Link;
HII_THUNK_CONTEXT *ThunkContext;
Link = GetFirstNode (&Private->ThunkContextListHead);
while (!IsNull (&Private->ThunkContextListHead, Link)) {
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
if (CompareGuid (Guid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount != 0)) {
return ThunkContext;
}
Link = GetNextNode (&Private->ThunkContextListHead, Link);
}
return NULL;
}
/**
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,
IN EFI_HII_HANDLE UefiHiiHandle
)
{
HII_THUNK_CONTEXT *ThunkContext;
ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);
ASSERT (ThunkContext != NULL);
DestroyThunkContext (ThunkContext);
}
/**
This function create a HII_THUNK_CONTEXT for a package list registered
by a module calling EFI_HII_DATABASE_PROTOCOL.NewPackageList. It records
the PackageListGuid in EFI_HII_PACKAGE_LIST_HEADER in the TagGuid in
HII_THUNK_CONTEXT created. This TagGuid will be used as a key to s
**/
HII_THUNK_CONTEXT *
CreateThunkContextForUefiHiiHandle (
IN EFI_HII_HANDLE UefiHiiHandle
)
{
EFI_STATUS Status;
EFI_GUID PackageGuid;
HII_THUNK_CONTEXT *ThunkContext;
ThunkContext = AllocateZeroPool (sizeof (*ThunkContext));
ASSERT (ThunkContext != NULL);
ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;
Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);
if (EFI_ERROR (Status)) {
return NULL;
}
ThunkContext->UefiHiiHandle = UefiHiiHandle;
Status = HiiLibExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid);
ASSERT_EFI_ERROR (Status);
CopyGuid(&ThunkContext->TagGuid, &PackageGuid);
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,
IN UINT8 PackageType
)
{
UINTN Count;
EFI_HII_PACKAGE_HEADER *PackageHeader;
PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageListHeader + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
Count = 0;
while (PackageHeader->Type != EFI_HII_PACKAGE_END) {
if (PackageHeader->Type == PackageType ) {
Count++;
}
PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);
}
return Count;
}
/**
Get the Form Package from a Framework Package List.
@param Packages Framework Package List.
@return The Form Package Header found.
**/
EFI_HII_PACKAGE_HEADER *
GetIfrPackage (
IN CONST EFI_HII_PACKAGES *Packages
)
{
UINTN Index;
TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;
ASSERT (Packages != NULL);
TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));
for (Index = 0; Index < Packages->NumberOfPackages; Index++) {
//
// The current UEFI HII build tool generate a binary in the format defined by
// TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in
// this binary is with same package type. So the returned IfrPackageCount and StringPackageCount
// may not be the exact number of valid package number in the binary generated
// by HII Build tool.
//
switch (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type) {
case EFI_HII_IFR:
return &TianoAutogenPackageHdrArray[Index]->PackageHeader;
break;
case EFI_HII_STRING:
case EFI_HII_FONT:
break;
default:
ASSERT (FALSE);
return NULL;
break;
}
}
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,
OUT EFI_GUID *FormSetGuid
)
{
UINTN Offset;
EFI_IFR_OP_HEADER *OpCode;
EFI_IFR_FORM_SET *FormSet;
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;
CopyGuid (FormSetGuid, (EFI_GUID *)(VOID *)&FormSet->Guid);
return;
default:
break;
}
Offset += OpCode->Length;
}
//
// A proper IFR must have a formset opcode.
//
ASSERT (FALSE);
}
/**
Creat a Thunk Context.
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,
IN UINTN StringPackageCount,
IN UINTN IfrPackageCount
)
{
EFI_STATUS Status;
HII_THUNK_CONTEXT *ThunkContext;
ThunkContext = AllocateZeroPool (sizeof (HII_THUNK_CONTEXT));
ASSERT (ThunkContext != NULL);
ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;
ThunkContext->IfrPackageCount = IfrPackageCount;
ThunkContext->StringPackageCount = StringPackageCount;
Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);
if (EFI_ERROR (Status)) {
return NULL;
}
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
)
{
ASSERT (ThunkContext != NULL);
FreeHiiHandle (ThunkContext->FwHiiHandle);
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) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01) is found, Var Store ID is used.
2) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID is not found, First Var Store ID is used
as the default Var Store ID.
@param FormSet The Form Set. The Default Varstore ID is updated if found.
**/
VOID
GetFormsetDefaultVarstoreId (
IN OUT FORM_BROWSER_FORMSET * FormSet
)
{
LIST_ENTRY *StorageList;
FORMSET_STORAGE *Storage;
FORMSET_STORAGE *DefaultStorage;
//
// VarStoreId 0 is invalid in UEFI IFR.
//
DefaultStorage= NULL;
FormSet->DefaultVarStoreId = 0;
StorageList = GetFirstNode (&FormSet->StorageListHead);
while (!IsNull (&FormSet->StorageListHead, StorageList)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
DEBUG ((EFI_D_INFO, "FormSet %g: Found Varstore ID %x Name %s Size 0x%x\n", &FormSet->Guid, Storage->VarStoreId, Storage->Name, Storage->Size));
if (Storage->VarStoreId == FRAMEWORK_RESERVED_VARSTORE_ID) {
//
// 1) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01) is found, Var Store ID is used.
//
FormSet->DefaultVarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;
DefaultStorage = Storage;
break;
}
StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);
}
if (FormSet->DefaultVarStoreId != FRAMEWORK_RESERVED_VARSTORE_ID) {
//
//
// 2) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID is not found, First Var Store ID is used
// as the default Var Store ID.
//
StorageList = GetFirstNode (&FormSet->StorageListHead);
if (!IsNull (&FormSet->StorageListHead, StorageList)) {
Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
FormSet->DefaultVarStoreId = Storage->VarStoreId;
DefaultStorage = Storage;
}
}
DEBUG_CODE_BEGIN ();
if (FormSet->DefaultVarStoreId == 0) {
DEBUG ((EFI_D_INFO, "FormSet %g: No Varstore Found\n", &FormSet->Guid));
} else {
// The name of default VARSTORE with a Explicit declaration statement will be updated to L"Setup" to make sure
// the Framework HII Setup module will run correctly. Framework HII Setup module always assumed that default
// VARSTORE to have L"Setup" as name, Formset GUID as GUID.
DEBUG ((EFI_D_INFO, "FormSet %g: Default Varstore ID (0x%x) N(%s) G(%g)\n", &FormSet->Guid, FormSet->DefaultVarStoreId, DefaultStorage->Name, &DefaultStorage->Guid));
if (StrCmp (DefaultStorage->Name, FrameworkReservedVarstoreName) != 0) {
DEBUG ((EFI_D_INFO, " : Name is updated from %s to %s.\n", DefaultStorage->Name, FrameworkReservedVarstoreName));
FormSet->OriginalDefaultVarStoreName = DefaultStorage->Name;
DefaultStorage->Name = AllocateCopyPool (StrSize (FrameworkReservedVarstoreName), FrameworkReservedVarstoreName);
}
}
DEBUG_CODE_END ();
return;
}
/**
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;
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

@@ -0,0 +1,123 @@
/**@file
This file contains utility functions by HII Thunk Modules.
Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _HII_THUNK_UTILITY_H
#define _HII_THUNK_UTILITY_H
/**
Find the UefiHiiHandle based on a Framework HII Handle returned by
the HII Thunk to Framework HII code.
@param Private The pointer to the private data of Hii Thunk.
@param FwHiiHandle Framework HII Handle returned by the HII Thunk to Framework HII code.
@retval NULL If Framework HII Handle passed in does not have matching UEFI HII handle.
@retval !NULL If the match is found.
**/
EFI_HII_HANDLE
FwHiiHandleToUefiHiiHandle (
IN CONST HII_THUNK_PRIVATE_DATA *Private,
IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle
);
HII_THUNK_CONTEXT *
FwHiiHandleToThunkContext (
IN CONST HII_THUNK_PRIVATE_DATA *Private,
IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle
);
HII_THUNK_CONTEXT *
UefiHiiHandleToThunkContext (
IN CONST HII_THUNK_PRIVATE_DATA *Private,
IN EFI_HII_HANDLE UefiHiiHandle
);
HII_THUNK_CONTEXT *
TagGuidToIfrPackThunkContext (
IN CONST HII_THUNK_PRIVATE_DATA *Private,
IN CONST EFI_GUID *Guid
);
HII_THUNK_CONTEXT *
CreateThunkContextForUefiHiiHandle (
IN EFI_HII_HANDLE UefiHiiHandle
);
VOID
DestroyThunkContextForUefiHiiHandle (
IN HII_THUNK_PRIVATE_DATA *Private,
IN EFI_HII_HANDLE UefiHiiHandle
);
UINTN
GetPackageCountByType (
IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,
IN UINT8 PackageType
);
EFI_STATUS
CreateQuestionIdMap (
IN OUT HII_THUNK_CONTEXT *ThunkContext
);
VOID
GetAttributesOfFirstFormSet (
IN OUT HII_THUNK_CONTEXT *ThunkContext
);
LIST_ENTRY *
GetMapEntryListHead (
IN CONST HII_THUNK_CONTEXT *ThunkContext,
IN UINT16 VarStoreId
);
HII_THUNK_CONTEXT *
CreateThunkContext (
IN HII_THUNK_PRIVATE_DATA *Private,
IN UINTN StringPackageCount,
IN UINTN IfrPackageCount
);
VOID
DestroyThunkContext (
IN HII_THUNK_CONTEXT *ThunkContext
);
VOID
DestoryOneOfOptionMap (
IN LIST_ENTRY *OneOfOptionMapListHead
);
VOID
GetFormSetGuid (
IN EFI_HII_PACKAGE_HEADER *Package,
OUT EFI_GUID *FormSetGuid
)
;
EFI_HII_PACKAGE_HEADER *
GetIfrPackage (
IN CONST EFI_HII_PACKAGES *Packages
)
;
FORM_BROWSER_FORMSET *
ParseFormSet (
IN EFI_HII_HANDLE UefiHiiHandle
)
;
#endif