2008-04-03 12:36:52 +02:00
|
|
|
/**@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"
|
2008-08-20 16:17:24 +02:00
|
|
|
#include "HiiHandle.h"
|
2008-11-10 13:40:07 +01:00
|
|
|
#include <Library/DebugLib.h>
|
2008-04-03 12:36:52 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
CONST EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
2008-12-16 14:09:12 +01:00
|
|
|
CONST CHAR16 FrameworkReservedVarstoreName[] = FRAMEWORK_RESERVED_VARSTORE_NAME;
|
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
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.
|
2008-08-18 07:56:23 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
@return NULL If Framework HII Handle is invalid.
|
|
|
|
@return The corresponding UEFI HII Handle.
|
|
|
|
**/
|
2008-04-14 08:57:09 +02:00
|
|
|
EFI_HII_HANDLE
|
2008-08-18 07:56:23 +02:00
|
|
|
FwHiiHandleToUefiHiiHandle (
|
|
|
|
IN CONST HII_THUNK_PRIVATE_DATA *Private,
|
|
|
|
IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle
|
2008-04-14 08:57:09 +02:00
|
|
|
)
|
|
|
|
{
|
2008-08-18 07:56:23 +02:00
|
|
|
HII_THUNK_CONTEXT *ThunkContext;
|
2008-04-14 08:57:09 +02:00
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
ASSERT (FwHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);
|
2008-04-14 08:57:09 +02:00
|
|
|
ASSERT (Private != NULL);
|
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
ThunkContext = FwHiiHandleToThunkContext (Private, FwHiiHandle);
|
2008-04-14 08:57:09 +02:00
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
if (ThunkContext != NULL) {
|
|
|
|
return ThunkContext->UefiHiiHandle;
|
2008-04-14 08:57:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return (EFI_HII_HANDLE) NULL;
|
|
|
|
}
|
|
|
|
|
2008-04-16 09:36:51 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
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.
|
|
|
|
**/
|
2008-08-18 07:56:23 +02:00
|
|
|
HII_THUNK_CONTEXT *
|
|
|
|
FwHiiHandleToThunkContext (
|
|
|
|
IN CONST HII_THUNK_PRIVATE_DATA *Private,
|
|
|
|
IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle
|
2008-04-16 09:36:51 +02:00
|
|
|
)
|
|
|
|
{
|
2008-08-18 07:56:23 +02:00
|
|
|
LIST_ENTRY *Link;
|
|
|
|
HII_THUNK_CONTEXT *ThunkContext;
|
|
|
|
|
2008-04-16 09:36:51 +02:00
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
Link = GetFirstNode (&Private->ThunkContextListHead);
|
2008-04-16 09:36:51 +02:00
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
while (!IsNull (&Private->ThunkContextListHead, Link)) {
|
|
|
|
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
|
|
|
|
|
|
|
|
if (FwHiiHandle == ThunkContext->FwHiiHandle) {
|
|
|
|
return ThunkContext;
|
2008-04-16 09:36:51 +02:00
|
|
|
}
|
2008-08-18 07:56:23 +02:00
|
|
|
|
|
|
|
Link = GetNextNode (&Private->ThunkContextListHead, Link);
|
2008-04-16 09:36:51 +02:00
|
|
|
}
|
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
return NULL;
|
2008-04-16 09:36:51 +02:00
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
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.
|
|
|
|
**/
|
2008-08-18 07:56:23 +02:00
|
|
|
HII_THUNK_CONTEXT *
|
|
|
|
UefiHiiHandleToThunkContext (
|
|
|
|
IN CONST HII_THUNK_PRIVATE_DATA *Private,
|
2008-05-07 10:49:04 +02:00
|
|
|
IN EFI_HII_HANDLE UefiHiiHandle
|
|
|
|
)
|
|
|
|
{
|
2008-08-18 07:56:23 +02:00
|
|
|
LIST_ENTRY *Link;
|
|
|
|
HII_THUNK_CONTEXT *ThunkContext;
|
2008-05-07 10:49:04 +02:00
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
Link = GetFirstNode (&Private->ThunkContextListHead);
|
2008-05-07 10:49:04 +02:00
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
while (!IsNull (&Private->ThunkContextListHead, Link)) {
|
|
|
|
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
|
|
|
|
|
|
|
|
if (UefiHiiHandle == ThunkContext->UefiHiiHandle) {
|
|
|
|
return ThunkContext;
|
2008-05-07 10:49:04 +02:00
|
|
|
}
|
2008-08-18 07:56:23 +02:00
|
|
|
Link = GetNextNode (&Private->ThunkContextListHead, Link);
|
2008-05-07 10:49:04 +02:00
|
|
|
}
|
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
return NULL;
|
2008-05-07 10:49:04 +02:00
|
|
|
}
|
2008-04-17 15:28:36 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
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.
|
|
|
|
**/
|
2008-09-04 12:15:50 +02:00
|
|
|
HII_THUNK_CONTEXT *
|
|
|
|
TagGuidToIfrPackThunkContext (
|
2008-08-18 07:56:23 +02:00
|
|
|
IN CONST HII_THUNK_PRIVATE_DATA *Private,
|
2008-04-17 15:28:36 +02:00
|
|
|
IN CONST EFI_GUID *Guid
|
|
|
|
)
|
|
|
|
{
|
2008-08-18 07:56:23 +02:00
|
|
|
LIST_ENTRY *Link;
|
|
|
|
HII_THUNK_CONTEXT *ThunkContext;
|
|
|
|
|
|
|
|
Link = GetFirstNode (&Private->ThunkContextListHead);
|
2008-04-17 15:28:36 +02:00
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
while (!IsNull (&Private->ThunkContextListHead, Link)) {
|
|
|
|
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
|
2008-04-17 15:28:36 +02:00
|
|
|
|
2008-09-04 12:15:50 +02:00
|
|
|
if (CompareGuid (Guid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount != 0)) {
|
|
|
|
return ThunkContext;
|
2008-04-17 15:28:36 +02:00
|
|
|
}
|
2008-08-18 07:56:23 +02:00
|
|
|
|
|
|
|
Link = GetNextNode (&Private->ThunkContextListHead, Link);
|
2008-04-17 15:28:36 +02:00
|
|
|
}
|
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
return NULL;
|
2008-04-17 15:28:36 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
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.
|
2008-08-18 07:56:23 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
**/
|
2008-08-20 16:17:24 +02:00
|
|
|
VOID
|
2008-08-18 07:56:23 +02:00
|
|
|
DestroyThunkContextForUefiHiiHandle (
|
|
|
|
IN HII_THUNK_PRIVATE_DATA *Private,
|
|
|
|
IN EFI_HII_HANDLE UefiHiiHandle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
HII_THUNK_CONTEXT *ThunkContext;
|
|
|
|
|
|
|
|
ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);
|
|
|
|
ASSERT (ThunkContext != NULL);
|
|
|
|
|
2008-08-20 16:17:24 +02:00
|
|
|
DestroyThunkContext (ThunkContext);
|
2008-08-18 07:56:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
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;
|
|
|
|
|
2008-08-20 16:17:24 +02:00
|
|
|
Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);
|
2008-08-18 07:56:23 +02:00
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThunkContext->UefiHiiHandle = UefiHiiHandle;
|
|
|
|
|
|
|
|
Status = HiiLibExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid);
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
|
|
|
|
CopyGuid(&ThunkContext->TagGuid, &PackageGuid);
|
|
|
|
|
|
|
|
return ThunkContext;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
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.
|
|
|
|
**/
|
2008-08-18 07:56:23 +02:00
|
|
|
UINTN
|
|
|
|
GetPackageCountByType (
|
|
|
|
IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,
|
|
|
|
IN UINT8 PackageType
|
2008-05-07 10:49:04 +02:00
|
|
|
)
|
|
|
|
{
|
2008-08-18 07:56:23 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
Get the Form Package from a Framework Package List.
|
2008-08-18 07:56:23 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
@param Packages Framework Package List.
|
2008-04-17 15:28:36 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
@return The Form Package Header found.
|
|
|
|
**/
|
2008-09-16 08:47:08 +02:00
|
|
|
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.
|
|
|
|
//
|
2008-11-21 16:07:50 +01:00
|
|
|
switch (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type) {
|
|
|
|
case EFI_HII_IFR:
|
2008-09-16 08:47:08 +02:00
|
|
|
return &TianoAutogenPackageHdrArray[Index]->PackageHeader;
|
|
|
|
break;
|
2008-11-21 16:07:50 +01:00
|
|
|
case EFI_HII_STRING:
|
|
|
|
case EFI_HII_FONT:
|
2008-09-16 08:47:08 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ASSERT (FALSE);
|
|
|
|
return NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
Get FormSet GUID.
|
|
|
|
|
|
|
|
ASSERT if no FormSet Opcode is found.
|
|
|
|
|
|
|
|
@param Packages Form Framework Package.
|
|
|
|
@param FormSetGuid Return the FormSet Guid.
|
|
|
|
|
|
|
|
**/
|
2008-09-16 08:47:08 +02:00
|
|
|
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;
|
2008-09-18 11:14:00 +02:00
|
|
|
CopyGuid (FormSetGuid, (EFI_GUID *)(VOID *)&FormSet->Guid);
|
2008-09-16 08:47:08 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
Offset += OpCode->Length;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// A proper IFR must have a formset opcode.
|
|
|
|
//
|
|
|
|
ASSERT (FALSE);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
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.
|
2008-09-16 08:47:08 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
@param ThunkContext The HII Thunk Private Context to be freed.
|
|
|
|
|
|
|
|
**/
|
2008-08-21 04:33:00 +02:00
|
|
|
VOID
|
2008-11-10 13:40:07 +01:00
|
|
|
DestroyThunkContext (
|
|
|
|
IN HII_THUNK_CONTEXT *ThunkContext
|
2008-08-21 04:33:00 +02:00
|
|
|
)
|
|
|
|
{
|
2008-11-10 13:40:07 +01:00
|
|
|
ASSERT (ThunkContext != NULL);
|
2008-08-21 04:33:00 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
FreeHiiHandle (ThunkContext->FwHiiHandle);
|
2008-08-21 04:33:00 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
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):
|
|
|
|
|
2008-12-01 08:16:55 +01:00
|
|
|
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.
|
2008-11-10 13:40:07 +01:00
|
|
|
|
2008-12-01 08:16:55 +01:00
|
|
|
@param FormSet The Form Set. The Default Varstore ID is updated if found.
|
2008-11-10 13:40:07 +01:00
|
|
|
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
GetFormsetDefaultVarstoreId (
|
|
|
|
IN OUT FORM_BROWSER_FORMSET * FormSet
|
|
|
|
)
|
|
|
|
{
|
|
|
|
LIST_ENTRY *StorageList;
|
|
|
|
FORMSET_STORAGE *Storage;
|
2008-12-16 14:09:12 +01:00
|
|
|
FORMSET_STORAGE *DefaultStorage;
|
2008-08-21 04:33:00 +02:00
|
|
|
|
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
// VarStoreId 0 is invalid in UEFI IFR.
|
2008-08-21 04:33:00 +02:00
|
|
|
//
|
2008-12-16 14:09:12 +01:00
|
|
|
DefaultStorage= NULL;
|
2008-11-10 13:40:07 +01:00
|
|
|
FormSet->DefaultVarStoreId = 0;
|
|
|
|
StorageList = GetFirstNode (&FormSet->StorageListHead);
|
2008-08-21 04:33:00 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
while (!IsNull (&FormSet->StorageListHead, StorageList)) {
|
|
|
|
Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
|
2008-08-21 04:33:00 +02:00
|
|
|
|
2008-12-16 06:27:24 +01:00
|
|
|
DEBUG ((EFI_D_INFO, "FormSet %g: Found Varstore ID %x Name %s Size 0x%x\n", &FormSet->Guid, Storage->VarStoreId, Storage->Name, Storage->Size));
|
2008-08-21 04:33:00 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
if (Storage->VarStoreId == FRAMEWORK_RESERVED_VARSTORE_ID) {
|
2008-12-16 06:27:24 +01:00
|
|
|
//
|
|
|
|
// 1) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01) is found, Var Store ID is used.
|
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
FormSet->DefaultVarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;
|
2008-12-16 14:09:12 +01:00
|
|
|
DefaultStorage = Storage;
|
2008-08-21 04:33:00 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FormSet->DefaultVarStoreId != FRAMEWORK_RESERVED_VARSTORE_ID) {
|
2008-12-16 06:27:24 +01:00
|
|
|
//
|
|
|
|
//
|
|
|
|
// 2) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID is not found, First Var Store ID is used
|
|
|
|
// as the default Var Store ID.
|
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
StorageList = GetFirstNode (&FormSet->StorageListHead);
|
|
|
|
if (!IsNull (&FormSet->StorageListHead, StorageList)) {
|
|
|
|
Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
|
2008-11-10 14:27:09 +01:00
|
|
|
FormSet->DefaultVarStoreId = Storage->VarStoreId;
|
2008-12-16 14:09:12 +01:00
|
|
|
DefaultStorage = Storage;
|
2008-11-10 13:40:07 +01:00
|
|
|
}
|
|
|
|
|
2008-08-21 04:33:00 +02:00
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
DEBUG_CODE_BEGIN ();
|
|
|
|
if (FormSet->DefaultVarStoreId == 0) {
|
|
|
|
DEBUG ((EFI_D_INFO, "FormSet %g: No Varstore Found\n", &FormSet->Guid));
|
|
|
|
} else {
|
2008-12-16 14:09:12 +01:00
|
|
|
// 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);
|
|
|
|
}
|
2008-11-10 13:40:07 +01:00
|
|
|
}
|
|
|
|
DEBUG_CODE_END ();
|
|
|
|
|
|
|
|
return;
|
2008-08-21 04:33:00 +02:00
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
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.
|
2008-04-17 15:28:36 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
@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.
|
|
|
|
|
|
|
|
**/
|
2008-08-18 07:56:23 +02:00
|
|
|
EFI_STATUS
|
2008-11-10 13:40:07 +01:00
|
|
|
GetIfrBinaryData (
|
|
|
|
IN EFI_HII_HANDLE Handle,
|
|
|
|
IN OUT EFI_GUID *FormSetGuid,
|
|
|
|
OUT UINTN *BinaryLength,
|
|
|
|
OUT UINT8 **BinaryData
|
2008-08-18 07:56:23 +02:00
|
|
|
)
|
|
|
|
{
|
2008-11-10 13:40:07 +01:00
|
|
|
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));;
|
2008-09-02 03:25:55 +02:00
|
|
|
|
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
// if FormSetGuid is NULL or zero GUID, return first FormSet in the package list
|
2008-09-02 03:25:55 +02:00
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {
|
|
|
|
ReturnDefault = TRUE;
|
|
|
|
} else {
|
|
|
|
ReturnDefault = FALSE;
|
2008-05-07 10:49:04 +02:00
|
|
|
}
|
2008-04-17 15:28:36 +02:00
|
|
|
|
2008-08-18 07:56:23 +02:00
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
// Get HII PackageList
|
2008-08-18 07:56:23 +02:00
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
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;
|
|
|
|
}
|
2008-08-18 07:56:23 +02:00
|
|
|
|
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
// Get Form package from this HII package List
|
2008-08-18 07:56:23 +02:00
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
|
|
|
|
Offset2 = 0;
|
|
|
|
CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
|
2008-08-18 07:56:23 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
while (Offset < PackageListLength) {
|
|
|
|
Package = ((UINT8 *) HiiPackageList) + Offset;
|
|
|
|
CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
|
2008-08-18 07:56:23 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
|
2008-08-18 07:56:23 +02:00
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
// Search FormSet in this Form Package
|
2008-08-18 07:56:23 +02:00
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
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) {
|
2008-08-18 07:56:23 +02:00
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
// Check whether return default FormSet
|
2008-08-18 07:56:23 +02:00
|
|
|
//
|
2008-11-10 13:40:07 +01:00
|
|
|
if (ReturnDefault) {
|
|
|
|
break;
|
2008-09-02 03:25:55 +02:00
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
//
|
|
|
|
// FormSet GUID is specified, check it
|
|
|
|
//
|
|
|
|
if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
|
|
|
|
break;
|
2008-08-18 07:56:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Offset2 < PackageHeader.Length) {
|
|
|
|
//
|
|
|
|
// Target formset found
|
|
|
|
//
|
|
|
|
break;
|
2008-08-18 07:56:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
Offset += PackageHeader.Length;
|
2008-08-18 07:56:23 +02:00
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
if (Offset >= PackageListLength) {
|
|
|
|
//
|
|
|
|
// Form package not found in this Package List
|
|
|
|
//
|
|
|
|
gBS->FreePool (HiiPackageList);
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
2008-08-18 07:56:23 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
if (ReturnDefault && FormSetGuid != NULL) {
|
|
|
|
//
|
|
|
|
// Return the default FormSet GUID
|
|
|
|
//
|
|
|
|
CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));
|
2008-08-18 07:56:23 +02:00
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
//
|
|
|
|
// 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);
|
2008-08-18 07:56:23 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
gBS->FreePool (HiiPackageList);
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
if (*BinaryData == NULL) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
2008-08-20 16:17:24 +02:00
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
return EFI_SUCCESS;
|
2008-08-20 16:17:24 +02:00
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
Initialize the internal data structure of a FormSet.
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
@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.
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
@retval EFI_SUCCESS The function completed successfully.
|
|
|
|
@retval EFI_NOT_FOUND The specified FormSet could not be found.
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
InitializeFormSet (
|
|
|
|
IN EFI_HII_HANDLE Handle,
|
|
|
|
IN OUT EFI_GUID *FormSetGuid,
|
|
|
|
OUT FORM_BROWSER_FORMSET *FormSet
|
2008-08-20 16:17:24 +02:00
|
|
|
)
|
|
|
|
{
|
2008-11-10 13:40:07 +01:00
|
|
|
EFI_STATUS Status;
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return Status;
|
|
|
|
}
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
FormSet->HiiHandle = Handle;
|
|
|
|
CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
//
|
|
|
|
// Parse the IFR binary OpCodes
|
|
|
|
//
|
|
|
|
Status = ParseOpCodes (FormSet);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return Status;
|
2008-08-20 16:17:24 +02:00
|
|
|
}
|
2008-11-10 13:40:07 +01:00
|
|
|
|
|
|
|
GetFormsetDefaultVarstoreId (FormSet);
|
|
|
|
return Status;
|
2008-08-20 16:17:24 +02:00
|
|
|
}
|
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
/**
|
|
|
|
Parse the Form Package and build a FORM_BROWSER_FORMSET structure.
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
@param UefiHiiHandle PackageList Handle
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
@return A pointer to FORM_BROWSER_FORMSET.
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
**/
|
|
|
|
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);
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
CopyGuid (&FormSetGuid, &gZeroGuid);
|
|
|
|
Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
2008-08-20 16:17:24 +02:00
|
|
|
|
2008-11-10 13:40:07 +01:00
|
|
|
return FormSet;
|
2008-08-20 16:17:24 +02:00
|
|
|
}
|
|
|
|
|