mirror of https://github.com/acidanthera/audk.git
3861 lines
131 KiB
C
3861 lines
131 KiB
C
/** @file
|
|
Implementation for EFI_HII_DATABASE_PROTOCOL.
|
|
|
|
Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
|
|
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"
|
|
|
|
/**
|
|
This function generates a HII_DATABASE_RECORD node and adds into hii database.
|
|
This is a internal function.
|
|
|
|
@param Private hii database private structure
|
|
@param DatabaseNode HII_DATABASE_RECORD node which is used to store a
|
|
package list
|
|
|
|
@retval EFI_SUCCESS A database record is generated successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
database contents.
|
|
@retval EFI_INVALID_PARAMETER Private is NULL or DatabaseRecord is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
GenerateHiiDatabaseRecord (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
OUT HII_DATABASE_RECORD **DatabaseNode
|
|
)
|
|
{
|
|
HII_DATABASE_RECORD *DatabaseRecord;
|
|
HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
|
|
HII_HANDLE *HiiHandle;
|
|
|
|
if (Private == NULL || DatabaseNode == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DatabaseRecord = (HII_DATABASE_RECORD *) AllocateZeroPool (sizeof (HII_DATABASE_RECORD));
|
|
if (DatabaseRecord == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
DatabaseRecord->Signature = HII_DATABASE_RECORD_SIGNATURE;
|
|
|
|
DatabaseRecord->PackageList = AllocateZeroPool (sizeof (HII_DATABASE_PACKAGE_LIST_INSTANCE));
|
|
if (DatabaseRecord->PackageList == NULL) {
|
|
FreePool (DatabaseRecord);
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
PackageList = DatabaseRecord->PackageList;
|
|
|
|
InitializeListHead (&PackageList->GuidPkgHdr);
|
|
InitializeListHead (&PackageList->FormPkgHdr);
|
|
InitializeListHead (&PackageList->KeyboardLayoutHdr);
|
|
InitializeListHead (&PackageList->StringPkgHdr);
|
|
InitializeListHead (&PackageList->FontPkgHdr);
|
|
InitializeListHead (&PackageList->SimpleFontPkgHdr);
|
|
PackageList->ImagePkg = NULL;
|
|
PackageList->DevicePathPkg = NULL;
|
|
|
|
//
|
|
// Create a new hii handle
|
|
//
|
|
HiiHandle = (HII_HANDLE *) AllocateZeroPool (sizeof (HII_HANDLE));
|
|
if (HiiHandle == NULL) {
|
|
FreePool (DatabaseRecord->PackageList);
|
|
FreePool (DatabaseRecord);
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
HiiHandle->Signature = HII_HANDLE_SIGNATURE;
|
|
//
|
|
// Backup the number of Hii handles
|
|
//
|
|
Private->HiiHandleCount++;
|
|
HiiHandle->Key = (UINTN) Private->HiiHandleCount;
|
|
//
|
|
// Insert the handle to hii handle list of the whole database.
|
|
//
|
|
InsertTailList (&Private->HiiHandleList, &HiiHandle->Handle);
|
|
|
|
DatabaseRecord->Handle = (EFI_HII_HANDLE) HiiHandle;
|
|
|
|
//
|
|
// Insert the Package List node to Package List link of the whole database.
|
|
//
|
|
InsertTailList (&Private->DatabaseList, &DatabaseRecord->DatabaseEntry);
|
|
|
|
*DatabaseNode = DatabaseRecord;
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
This function checks whether a handle is a valid EFI_HII_HANDLE
|
|
This is a internal function.
|
|
|
|
@param Handle Pointer to a EFI_HII_HANDLE
|
|
|
|
@retval TRUE Valid
|
|
@retval FALSE Invalid
|
|
|
|
**/
|
|
BOOLEAN
|
|
IsHiiHandleValid (
|
|
EFI_HII_HANDLE Handle
|
|
)
|
|
{
|
|
HII_HANDLE *HiiHandle;
|
|
|
|
HiiHandle = (HII_HANDLE *) Handle;
|
|
|
|
if (HiiHandle == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (HiiHandle->Signature != HII_HANDLE_SIGNATURE) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/**
|
|
This function invokes the matching registered function.
|
|
This is a internal function.
|
|
|
|
@param Private HII Database driver private structure.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageInstance Points to the package referred to by the
|
|
notification.
|
|
@param PackageType Package type
|
|
@param Handle The handle of the package list which contains the
|
|
specified package.
|
|
|
|
@retval EFI_SUCCESS Already checked all registered function and
|
|
invoked if matched.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InvokeRegisteredFunction (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN VOID *PackageInstance,
|
|
IN UINT8 PackageType,
|
|
IN EFI_HII_HANDLE Handle
|
|
)
|
|
{
|
|
HII_DATABASE_NOTIFY *Notify;
|
|
LIST_ENTRY *Link;
|
|
EFI_HII_PACKAGE_HEADER *Package;
|
|
UINT8 *Buffer;
|
|
UINT32 BufferSize;
|
|
UINT32 HeaderSize;
|
|
UINT32 ImageBlockSize;
|
|
UINT32 PaletteInfoSize;
|
|
|
|
if (Private == NULL || (NotifyType & 0xF) == 0 || PackageInstance == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (!IsHiiHandleValid (Handle)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Buffer = NULL;
|
|
Package = NULL;
|
|
|
|
//
|
|
// Convert the incoming package from hii database storage format to UEFI
|
|
// storage format. e.g. HII_GUID_PACKAGE_INSTANCE to EFI_HII_GUID_PACKAGE_HDR.
|
|
//
|
|
switch (PackageType) {
|
|
case EFI_HII_PACKAGE_TYPE_GUID:
|
|
Package = (EFI_HII_PACKAGE_HEADER *) (((HII_GUID_PACKAGE_INSTANCE *) PackageInstance)->GuidPkg);
|
|
break;
|
|
|
|
case EFI_HII_PACKAGE_FORMS:
|
|
BufferSize = ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr.Length;
|
|
Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
|
|
ASSERT (Buffer != NULL);
|
|
CopyMem (
|
|
Buffer,
|
|
&((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr,
|
|
sizeof (EFI_HII_PACKAGE_HEADER)
|
|
);
|
|
CopyMem (
|
|
Buffer + sizeof (EFI_HII_PACKAGE_HEADER),
|
|
((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->IfrData,
|
|
BufferSize - sizeof (EFI_HII_PACKAGE_HEADER)
|
|
);
|
|
Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
|
|
break;
|
|
|
|
case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
|
|
Package = (EFI_HII_PACKAGE_HEADER *) (((HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *) PackageInstance)->KeyboardPkg);
|
|
break;
|
|
|
|
case EFI_HII_PACKAGE_STRINGS:
|
|
BufferSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->Header.Length;
|
|
HeaderSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->HdrSize;
|
|
Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
|
|
ASSERT (Buffer != NULL);
|
|
CopyMem (
|
|
Buffer,
|
|
((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr,
|
|
HeaderSize
|
|
);
|
|
CopyMem (
|
|
Buffer + HeaderSize,
|
|
((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringBlock,
|
|
BufferSize - HeaderSize
|
|
);
|
|
Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
|
|
break;
|
|
|
|
case EFI_HII_PACKAGE_FONTS:
|
|
BufferSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->Header.Length;
|
|
HeaderSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->HdrSize;
|
|
Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
|
|
ASSERT (Buffer != NULL);
|
|
CopyMem (
|
|
Buffer,
|
|
((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr,
|
|
HeaderSize
|
|
);
|
|
CopyMem (
|
|
Buffer + HeaderSize,
|
|
((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->GlyphBlock,
|
|
BufferSize - HeaderSize
|
|
);
|
|
Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
|
|
break;
|
|
|
|
case EFI_HII_PACKAGE_IMAGES:
|
|
BufferSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr.Header.Length;
|
|
HeaderSize = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
|
|
Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
|
|
ASSERT (Buffer != NULL);
|
|
|
|
CopyMem (
|
|
Buffer,
|
|
&((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr,
|
|
HeaderSize
|
|
);
|
|
CopyMem (
|
|
Buffer + sizeof (EFI_HII_PACKAGE_HEADER),
|
|
&HeaderSize,
|
|
sizeof (UINT32)
|
|
);
|
|
|
|
ImageBlockSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlockSize;
|
|
if (ImageBlockSize != 0) {
|
|
CopyMem (
|
|
Buffer + HeaderSize,
|
|
((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlock,
|
|
ImageBlockSize
|
|
);
|
|
}
|
|
|
|
PaletteInfoSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteInfoSize;
|
|
if (PaletteInfoSize != 0) {
|
|
CopyMem (
|
|
Buffer + HeaderSize + ImageBlockSize,
|
|
((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteBlock,
|
|
PaletteInfoSize
|
|
);
|
|
HeaderSize += ImageBlockSize;
|
|
CopyMem (
|
|
Buffer + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT32),
|
|
&HeaderSize,
|
|
sizeof (UINT32)
|
|
);
|
|
}
|
|
Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
|
|
break;
|
|
|
|
case EFI_HII_PACKAGE_SIMPLE_FONTS:
|
|
BufferSize = ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr->Header.Length;
|
|
Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
|
|
ASSERT (Buffer != NULL);
|
|
CopyMem (
|
|
Buffer,
|
|
((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr,
|
|
BufferSize
|
|
);
|
|
Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
|
|
break;
|
|
|
|
case EFI_HII_PACKAGE_DEVICE_PATH:
|
|
Package = (EFI_HII_PACKAGE_HEADER *) PackageInstance;
|
|
break;
|
|
|
|
default:
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
for (Link = Private->DatabaseNotifyList.ForwardLink;
|
|
Link != &Private->DatabaseNotifyList;
|
|
Link = Link->ForwardLink
|
|
) {
|
|
Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);
|
|
if (Notify->NotifyType == NotifyType && Notify->PackageType == PackageType) {
|
|
//
|
|
// Check in case PackageGuid is not NULL when Package is GUID package
|
|
//
|
|
if (PackageType != EFI_HII_PACKAGE_TYPE_GUID) {
|
|
Notify->PackageGuid = NULL;
|
|
}
|
|
//
|
|
// Status of Registered Function is unknown so did not check it
|
|
//
|
|
Notify->PackageNotifyFn (
|
|
Notify->PackageType,
|
|
Notify->PackageGuid,
|
|
Package,
|
|
Handle,
|
|
NotifyType
|
|
);
|
|
}
|
|
}
|
|
|
|
if (Buffer != NULL) {
|
|
FreePool (Buffer);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function insert a GUID package to a package list node.
|
|
This is a internal function.
|
|
|
|
@param PackageHdr Pointer to a buffer stored with GUID package
|
|
information.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageList Pointer to a package list which will be inserted
|
|
to.
|
|
@param Package Created GUID pacakge
|
|
|
|
@retval EFI_SUCCESS Guid Package is inserted successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
Guid package.
|
|
@retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InsertGuidPackage (
|
|
IN VOID *PackageHdr,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
OUT HII_GUID_PACKAGE_INSTANCE **Package
|
|
)
|
|
{
|
|
HII_GUID_PACKAGE_INSTANCE *GuidPackage;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
|
|
if (PackageHdr == NULL || PackageList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
|
|
//
|
|
// Create a GUID package node
|
|
//
|
|
GuidPackage = (HII_GUID_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_GUID_PACKAGE_INSTANCE));
|
|
if (GuidPackage == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
GuidPackage->GuidPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);
|
|
if (GuidPackage->GuidPkg == NULL) {
|
|
FreePool (GuidPackage);
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
GuidPackage->Signature = HII_GUID_PACKAGE_SIGNATURE;
|
|
CopyMem (GuidPackage->GuidPkg, PackageHdr, PackageHeader.Length);
|
|
InsertTailList (&PackageList->GuidPkgHdr, &GuidPackage->GuidEntry);
|
|
*Package = GuidPackage;
|
|
|
|
if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
|
|
PackageList->PackageListHdr.PackageLength += PackageHeader.Length;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function exports GUID packages to a buffer.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param Handle Identification of a package list.
|
|
@param PackageList Pointer to a package list which will be exported.
|
|
@param UsedSize The length of buffer be used.
|
|
@param BufferSize Length of the Buffer.
|
|
@param Buffer Allocated space for storing exported data.
|
|
@param ResultSize The size of the already exported content of this
|
|
package list.
|
|
|
|
@retval EFI_SUCCESS Guid Packages are exported successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ExportGuidPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
IN UINTN UsedSize,
|
|
IN UINTN BufferSize,
|
|
IN OUT VOID *Buffer,
|
|
IN OUT UINTN *ResultSize
|
|
)
|
|
{
|
|
HII_GUID_PACKAGE_INSTANCE *GuidPackage;
|
|
LIST_ENTRY *Link;
|
|
UINTN PackageLength;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
EFI_STATUS Status;
|
|
|
|
if (PackageList == NULL || ResultSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (BufferSize > 0 && Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PackageLength = 0;
|
|
Status = EFI_SUCCESS;
|
|
|
|
for (Link = PackageList->GuidPkgHdr.ForwardLink; Link != &PackageList->GuidPkgHdr; Link = Link->ForwardLink) {
|
|
GuidPackage = CR (Link, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);
|
|
CopyMem (&PackageHeader, GuidPackage->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
PackageLength += PackageHeader.Length;
|
|
if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
|
|
(VOID *) GuidPackage,
|
|
EFI_HII_PACKAGE_TYPE_GUID,
|
|
Handle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
CopyMem (Buffer, GuidPackage->GuidPkg, PackageHeader.Length);
|
|
Buffer = (UINT8 *) Buffer + PackageHeader.Length;
|
|
}
|
|
}
|
|
|
|
*ResultSize += PackageLength;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function deletes all GUID packages from a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private data.
|
|
@param Handle Handle of the package list which contains the to
|
|
be removed GUID packages.
|
|
@param PackageList Pointer to a package list that contains removing
|
|
packages.
|
|
|
|
@retval EFI_SUCCESS GUID Package(s) is deleted successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RemoveGuidPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
LIST_ENTRY *ListHead;
|
|
HII_GUID_PACKAGE_INSTANCE *Package;
|
|
EFI_STATUS Status;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
|
|
ListHead = &PackageList->GuidPkgHdr;
|
|
|
|
while (!IsListEmpty (ListHead)) {
|
|
Package = CR (
|
|
ListHead->ForwardLink,
|
|
HII_GUID_PACKAGE_INSTANCE,
|
|
GuidEntry,
|
|
HII_GUID_PACKAGE_SIGNATURE
|
|
);
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_TYPE_GUID,
|
|
Handle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
RemoveEntryList (&Package->GuidEntry);
|
|
CopyMem (&PackageHeader, Package->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;
|
|
FreePool (Package->GuidPkg);
|
|
FreePool (Package);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function insert a Form package to a package list node.
|
|
This is a internal function.
|
|
|
|
@param PackageHdr Pointer to a buffer stored with Form package
|
|
information.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageList Pointer to a package list which will be inserted
|
|
to.
|
|
@param Package Created Form package
|
|
|
|
@retval EFI_SUCCESS Form Package is inserted successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
Form package.
|
|
@retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InsertFormPackage (
|
|
IN VOID *PackageHdr,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
OUT HII_IFR_PACKAGE_INSTANCE **Package
|
|
)
|
|
{
|
|
HII_IFR_PACKAGE_INSTANCE *FormPackage;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
|
|
if (PackageHdr == NULL || PackageList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Get the length of the package, including package header itself
|
|
//
|
|
CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
|
|
//
|
|
// Create a Form package node
|
|
//
|
|
FormPackage = (HII_IFR_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IFR_PACKAGE_INSTANCE));
|
|
if (FormPackage == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
FormPackage->IfrData = (UINT8 *) AllocateZeroPool (PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER));
|
|
if (FormPackage->IfrData == NULL) {
|
|
FreePool (FormPackage);
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
FormPackage->Signature = HII_IFR_PACKAGE_SIGNATURE;
|
|
//
|
|
// Copy Package Header
|
|
//
|
|
CopyMem (&FormPackage->FormPkgHdr, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
|
|
//
|
|
// Copy Ifr contents
|
|
//
|
|
CopyMem (
|
|
FormPackage->IfrData,
|
|
(UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER),
|
|
PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER)
|
|
);
|
|
|
|
InsertTailList (&PackageList->FormPkgHdr, &FormPackage->IfrEntry);
|
|
*Package = FormPackage;
|
|
|
|
if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
|
|
PackageList->PackageListHdr.PackageLength += FormPackage->FormPkgHdr.Length;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function exports Form packages to a buffer.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param Handle Identification of a package list.
|
|
@param PackageList Pointer to a package list which will be exported.
|
|
@param UsedSize The length of buffer be used.
|
|
@param BufferSize Length of the Buffer.
|
|
@param Buffer Allocated space for storing exported data.
|
|
@param ResultSize The size of the already exported content of this
|
|
package list.
|
|
|
|
@retval EFI_SUCCESS Form Packages are exported successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ExportFormPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
IN UINTN UsedSize,
|
|
IN UINTN BufferSize,
|
|
IN OUT VOID *Buffer,
|
|
IN OUT UINTN *ResultSize
|
|
)
|
|
{
|
|
HII_IFR_PACKAGE_INSTANCE *FormPackage;
|
|
UINTN PackageLength;
|
|
LIST_ENTRY *Link;
|
|
EFI_STATUS Status;
|
|
|
|
if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (BufferSize > 0 && Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PackageLength = 0;
|
|
Status = EFI_SUCCESS;
|
|
|
|
//
|
|
// Export Form packages.
|
|
//
|
|
for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) {
|
|
FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);
|
|
PackageLength += FormPackage->FormPkgHdr.Length;
|
|
if ((Buffer != NULL) && (PackageLength + *ResultSize + UsedSize <= BufferSize)) {
|
|
//
|
|
// Invoke registered notification if exists
|
|
//
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
|
|
(VOID *) FormPackage,
|
|
EFI_HII_PACKAGE_FORMS,
|
|
Handle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
//
|
|
// Copy the Form package content.
|
|
//
|
|
CopyMem (Buffer, (VOID *) (&FormPackage->FormPkgHdr), sizeof (EFI_HII_PACKAGE_HEADER));
|
|
Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_PACKAGE_HEADER);
|
|
CopyMem (
|
|
Buffer,
|
|
(VOID *) FormPackage->IfrData,
|
|
FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER)
|
|
);
|
|
Buffer = (UINT8 *) Buffer + FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);
|
|
}
|
|
}
|
|
|
|
*ResultSize += PackageLength;
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
This function deletes all Form packages from a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private data.
|
|
@param Handle Handle of the package list which contains the to
|
|
be removed Form packages.
|
|
@param PackageList Pointer to a package list that contains removing
|
|
packages.
|
|
|
|
@retval EFI_SUCCESS Form Package(s) is deleted successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RemoveFormPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
LIST_ENTRY *ListHead;
|
|
HII_IFR_PACKAGE_INSTANCE *Package;
|
|
EFI_STATUS Status;
|
|
|
|
ListHead = &PackageList->FormPkgHdr;
|
|
|
|
while (!IsListEmpty (ListHead)) {
|
|
Package = CR (
|
|
ListHead->ForwardLink,
|
|
HII_IFR_PACKAGE_INSTANCE,
|
|
IfrEntry,
|
|
HII_IFR_PACKAGE_SIGNATURE
|
|
);
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_FORMS,
|
|
Handle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
RemoveEntryList (&Package->IfrEntry);
|
|
PackageList->PackageListHdr.PackageLength -= Package->FormPkgHdr.Length;
|
|
FreePool (Package->IfrData);
|
|
FreePool (Package);
|
|
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
This function insert a String package to a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param PackageHdr Pointer to a buffer stored with String package
|
|
information.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageList Pointer to a package list which will be inserted
|
|
to.
|
|
@param Package Created String package
|
|
|
|
@retval EFI_SUCCESS String Package is inserted successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
String package.
|
|
@retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
|
|
@retval EFI_UNSUPPORTED A string package with the same language already
|
|
exists in current package list.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InsertStringPackage (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN VOID *PackageHdr,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
OUT HII_STRING_PACKAGE_INSTANCE **Package
|
|
)
|
|
{
|
|
HII_STRING_PACKAGE_INSTANCE *StringPackage;
|
|
UINT32 HeaderSize;
|
|
EFI_STATUS Status;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
CHAR8 *Language;
|
|
UINT32 LanguageSize;
|
|
LIST_ENTRY *Link;
|
|
|
|
if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));
|
|
|
|
//
|
|
// It is illegal to have two string packages with same language within one packagelist
|
|
// since the stringid will be duplicate if so. Check it to avoid this potential issue.
|
|
//
|
|
LanguageSize = HeaderSize - sizeof (EFI_HII_STRING_PACKAGE_HDR) + sizeof (CHAR8);
|
|
Language = (CHAR8 *) AllocateZeroPool (LanguageSize);
|
|
if (Language == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
AsciiStrCpy (Language, (CHAR8 *) PackageHdr + HeaderSize - LanguageSize);
|
|
for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {
|
|
StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
|
|
if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {
|
|
FreePool (Language);
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
FreePool (Language);
|
|
|
|
//
|
|
// Create a String package node
|
|
//
|
|
StringPackage = (HII_STRING_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));
|
|
if (StringPackage == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
|
|
StringPackage->StringPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);
|
|
if (StringPackage->StringPkgHdr == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
|
|
StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);
|
|
if (StringPackage->StringBlock == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
|
|
StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;
|
|
StringPackage->FontId = 0;
|
|
InitializeListHead (&StringPackage->FontInfoList);
|
|
|
|
//
|
|
// Copy the String package header.
|
|
//
|
|
CopyMem (StringPackage->StringPkgHdr, PackageHdr, HeaderSize);
|
|
|
|
//
|
|
// Copy the String blocks
|
|
//
|
|
CopyMem (
|
|
StringPackage->StringBlock,
|
|
(UINT8 *) PackageHdr + HeaderSize,
|
|
PackageHeader.Length - HeaderSize
|
|
);
|
|
|
|
//
|
|
// Collect all font block info
|
|
//
|
|
Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId, NULL);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Insert to String package array
|
|
//
|
|
InsertTailList (&PackageList->StringPkgHdr, &StringPackage->StringEntry);
|
|
*Package = StringPackage;
|
|
|
|
if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
|
|
PackageList->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
Error:
|
|
|
|
if (StringPackage != NULL) {
|
|
if (StringPackage->StringBlock != NULL) {
|
|
FreePool (StringPackage->StringBlock);
|
|
}
|
|
if (StringPackage->StringPkgHdr != NULL) {
|
|
FreePool (StringPackage->StringPkgHdr);
|
|
}
|
|
FreePool (StringPackage);
|
|
}
|
|
return Status;
|
|
|
|
}
|
|
|
|
/**
|
|
Adjust all string packages in a single package list to have the same max string ID.
|
|
|
|
@param PackageList Pointer to a package list which will be adjusted.
|
|
|
|
@retval EFI_SUCCESS Adjust all string packages successfully.
|
|
@retval others Can't adjust string packges.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
AdjustStringPackage (
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
HII_STRING_PACKAGE_INSTANCE *StringPackage;
|
|
UINT32 Skip2BlockSize;
|
|
UINT32 OldBlockSize;
|
|
UINT8 *StringBlock;
|
|
UINT8 *BlockPtr;
|
|
EFI_STRING_ID MaxStringId;
|
|
UINT16 SkipCount;
|
|
|
|
MaxStringId = 0;
|
|
for (Link = PackageList->StringPkgHdr.ForwardLink;
|
|
Link != &PackageList->StringPkgHdr;
|
|
Link = Link->ForwardLink
|
|
) {
|
|
StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
|
|
if (MaxStringId < StringPackage->MaxStringId) {
|
|
MaxStringId = StringPackage->MaxStringId;
|
|
}
|
|
}
|
|
|
|
for (Link = PackageList->StringPkgHdr.ForwardLink;
|
|
Link != &PackageList->StringPkgHdr;
|
|
Link = Link->ForwardLink
|
|
) {
|
|
StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
|
|
if (StringPackage->MaxStringId < MaxStringId) {
|
|
OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
|
|
//
|
|
// Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs.
|
|
//
|
|
SkipCount = (UINT16) (MaxStringId - StringPackage->MaxStringId);
|
|
Skip2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
|
|
|
|
StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Skip2BlockSize);
|
|
if (StringBlock == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
//
|
|
// Copy original string blocks, except the EFI_HII_SIBT_END.
|
|
//
|
|
CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
|
|
//
|
|
// Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks
|
|
//
|
|
BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
|
|
*BlockPtr = EFI_HII_SIBT_SKIP2;
|
|
CopyMem (BlockPtr + 1, &SkipCount, sizeof (UINT16));
|
|
BlockPtr += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
|
|
|
|
//
|
|
// Append a EFI_HII_SIBT_END block to the end.
|
|
//
|
|
*BlockPtr = EFI_HII_SIBT_END;
|
|
FreePool (StringPackage->StringBlock);
|
|
StringPackage->StringBlock = StringBlock;
|
|
StringPackage->StringPkgHdr->Header.Length += Skip2BlockSize;
|
|
PackageList->PackageListHdr.PackageLength += Skip2BlockSize;
|
|
StringPackage->MaxStringId = MaxStringId;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function exports String packages to a buffer.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param Handle Identification of a package list.
|
|
@param PackageList Pointer to a package list which will be exported.
|
|
@param UsedSize The length of buffer be used.
|
|
@param BufferSize Length of the Buffer.
|
|
@param Buffer Allocated space for storing exported data.
|
|
@param ResultSize The size of the already exported content of this
|
|
package list.
|
|
|
|
@retval EFI_SUCCESS String Packages are exported successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ExportStringPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
IN UINTN UsedSize,
|
|
IN UINTN BufferSize,
|
|
IN OUT VOID *Buffer,
|
|
IN OUT UINTN *ResultSize
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
UINTN PackageLength;
|
|
EFI_STATUS Status;
|
|
HII_STRING_PACKAGE_INSTANCE *StringPackage;
|
|
|
|
if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (BufferSize > 0 && Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PackageLength = 0;
|
|
Status = EFI_SUCCESS;
|
|
|
|
for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {
|
|
StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
|
|
PackageLength += StringPackage->StringPkgHdr->Header.Length;
|
|
if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
|
|
//
|
|
// Invoke registered notification function with EXPORT_PACK notify type
|
|
//
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
|
|
(VOID *) StringPackage,
|
|
EFI_HII_PACKAGE_STRINGS,
|
|
Handle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
//
|
|
// Copy String package header
|
|
//
|
|
CopyMem (Buffer, StringPackage->StringPkgHdr, StringPackage->StringPkgHdr->HdrSize);
|
|
Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->HdrSize;
|
|
|
|
//
|
|
// Copy String blocks information
|
|
//
|
|
CopyMem (
|
|
Buffer,
|
|
StringPackage->StringBlock,
|
|
StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize
|
|
);
|
|
Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
|
|
}
|
|
}
|
|
|
|
*ResultSize += PackageLength;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function deletes all String packages from a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private data.
|
|
@param Handle Handle of the package list which contains the to
|
|
be removed String packages.
|
|
@param PackageList Pointer to a package list that contains removing
|
|
packages.
|
|
|
|
@retval EFI_SUCCESS String Package(s) is deleted successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RemoveStringPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
LIST_ENTRY *ListHead;
|
|
HII_STRING_PACKAGE_INSTANCE *Package;
|
|
HII_FONT_INFO *FontInfo;
|
|
EFI_STATUS Status;
|
|
|
|
ListHead = &PackageList->StringPkgHdr;
|
|
|
|
while (!IsListEmpty (ListHead)) {
|
|
Package = CR (
|
|
ListHead->ForwardLink,
|
|
HII_STRING_PACKAGE_INSTANCE,
|
|
StringEntry,
|
|
HII_STRING_PACKAGE_SIGNATURE
|
|
);
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_STRINGS,
|
|
Handle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
RemoveEntryList (&Package->StringEntry);
|
|
PackageList->PackageListHdr.PackageLength -= Package->StringPkgHdr->Header.Length;
|
|
FreePool (Package->StringBlock);
|
|
FreePool (Package->StringPkgHdr);
|
|
//
|
|
// Delete font information
|
|
//
|
|
while (!IsListEmpty (&Package->FontInfoList)) {
|
|
FontInfo = CR (
|
|
Package->FontInfoList.ForwardLink,
|
|
HII_FONT_INFO,
|
|
Entry,
|
|
HII_FONT_INFO_SIGNATURE
|
|
);
|
|
RemoveEntryList (&FontInfo->Entry);
|
|
FreePool (FontInfo);
|
|
}
|
|
|
|
FreePool (Package);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function insert a Font package to a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param PackageHdr Pointer to a buffer stored with Font package
|
|
information.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageList Pointer to a package list which will be inserted
|
|
to.
|
|
@param Package Created Font package
|
|
|
|
@retval EFI_SUCCESS Font Package is inserted successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
Font package.
|
|
@retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
|
|
@retval EFI_UNSUPPORTED A font package with same EFI_FONT_INFO already
|
|
exists in current hii database.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InsertFontPackage (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN VOID *PackageHdr,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
OUT HII_FONT_PACKAGE_INSTANCE **Package
|
|
)
|
|
{
|
|
HII_FONT_PACKAGE_INSTANCE *FontPackage;
|
|
EFI_HII_FONT_PACKAGE_HDR *FontPkgHdr;
|
|
UINT32 HeaderSize;
|
|
EFI_STATUS Status;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
EFI_FONT_INFO *FontInfo;
|
|
UINT32 FontInfoSize;
|
|
HII_GLOBAL_FONT_INFO *GlobalFont;
|
|
|
|
if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));
|
|
|
|
FontInfo = NULL;
|
|
FontPackage = NULL;
|
|
GlobalFont = NULL;
|
|
|
|
//
|
|
// It is illegal to have two font packages with same EFI_FONT_INFO within hii
|
|
// database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's
|
|
// attributes and identify a font uniquely.
|
|
//
|
|
FontPkgHdr = (EFI_HII_FONT_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);
|
|
if (FontPkgHdr == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
CopyMem (FontPkgHdr, PackageHdr, HeaderSize);
|
|
|
|
FontInfoSize = sizeof (EFI_FONT_INFO) + HeaderSize - sizeof (EFI_HII_FONT_PACKAGE_HDR);
|
|
FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoSize);
|
|
if (FontInfo == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
FontInfo->FontStyle = FontPkgHdr->FontStyle;
|
|
FontInfo->FontSize = FontPkgHdr->Cell.Height;
|
|
StrCpy (FontInfo->FontName, FontPkgHdr->FontFamily);
|
|
|
|
if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) {
|
|
Status = EFI_UNSUPPORTED;
|
|
goto Error;
|
|
}
|
|
|
|
//
|
|
// Create a Font package node
|
|
//
|
|
FontPackage = (HII_FONT_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE));
|
|
if (FontPackage == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
FontPackage->Signature = HII_FONT_PACKAGE_SIGNATURE;
|
|
FontPackage->FontPkgHdr = FontPkgHdr;
|
|
InitializeListHead (&FontPackage->GlyphInfoList);
|
|
|
|
FontPackage->GlyphBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);
|
|
if (FontPackage->GlyphBlock == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
CopyMem (FontPackage->GlyphBlock, (UINT8 *) PackageHdr + HeaderSize, PackageHeader.Length - HeaderSize);
|
|
|
|
//
|
|
// Collect all default character cell information and backup in GlyphInfoList.
|
|
//
|
|
Status = FindGlyphBlock (FontPackage, (CHAR16) (-1), NULL, NULL, NULL);
|
|
if (EFI_ERROR (Status)) {
|
|
goto Error;
|
|
}
|
|
|
|
//
|
|
// This font package describes an unique EFI_FONT_INFO. Backup it in global
|
|
// font info list.
|
|
//
|
|
GlobalFont = (HII_GLOBAL_FONT_INFO *) AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO));
|
|
if (GlobalFont == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
GlobalFont->Signature = HII_GLOBAL_FONT_INFO_SIGNATURE;
|
|
GlobalFont->FontPackage = FontPackage;
|
|
GlobalFont->FontInfoSize = FontInfoSize;
|
|
GlobalFont->FontInfo = FontInfo;
|
|
InsertTailList (&Private->FontInfoList, &GlobalFont->Entry);
|
|
|
|
//
|
|
// Insert this font package to Font package array
|
|
//
|
|
InsertTailList (&PackageList->FontPkgHdr, &FontPackage->FontEntry);
|
|
*Package = FontPackage;
|
|
|
|
if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
|
|
PackageList->PackageListHdr.PackageLength += FontPackage->FontPkgHdr->Header.Length;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
Error:
|
|
|
|
if (FontPkgHdr != NULL) {
|
|
FreePool (FontPkgHdr);
|
|
}
|
|
if (FontInfo != NULL) {
|
|
FreePool (FontInfo);
|
|
}
|
|
if (FontPackage != NULL) {
|
|
if (FontPackage->GlyphBlock != NULL) {
|
|
FreePool (FontPackage->GlyphBlock);
|
|
}
|
|
FreePool (FontPackage);
|
|
}
|
|
if (GlobalFont != NULL) {
|
|
FreePool (GlobalFont);
|
|
}
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
This function exports Font packages to a buffer.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param Handle Identification of a package list.
|
|
@param PackageList Pointer to a package list which will be exported.
|
|
@param UsedSize The length of buffer be used.
|
|
@param BufferSize Length of the Buffer.
|
|
@param Buffer Allocated space for storing exported data.
|
|
@param ResultSize The size of the already exported content of this
|
|
package list.
|
|
|
|
@retval EFI_SUCCESS Font Packages are exported successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ExportFontPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
IN UINTN UsedSize,
|
|
IN UINTN BufferSize,
|
|
IN OUT VOID *Buffer,
|
|
IN OUT UINTN *ResultSize
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
UINTN PackageLength;
|
|
EFI_STATUS Status;
|
|
HII_FONT_PACKAGE_INSTANCE *Package;
|
|
|
|
|
|
if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (BufferSize > 0 && Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PackageLength = 0;
|
|
Status = EFI_SUCCESS;
|
|
|
|
for (Link = PackageList->FontPkgHdr.ForwardLink; Link != &PackageList->FontPkgHdr; Link = Link->ForwardLink) {
|
|
Package = CR (Link, HII_FONT_PACKAGE_INSTANCE, FontEntry, HII_FONT_PACKAGE_SIGNATURE);
|
|
PackageLength += Package->FontPkgHdr->Header.Length;
|
|
if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
|
|
//
|
|
// Invoke registered notification function with EXPORT_PACK notify type
|
|
//
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_FONTS,
|
|
Handle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
//
|
|
// Copy Font package header
|
|
//
|
|
CopyMem (Buffer, Package->FontPkgHdr, Package->FontPkgHdr->HdrSize);
|
|
Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->HdrSize;
|
|
|
|
//
|
|
// Copy Glyph blocks information
|
|
//
|
|
CopyMem (
|
|
Buffer,
|
|
Package->GlyphBlock,
|
|
Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize
|
|
);
|
|
Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize;
|
|
}
|
|
}
|
|
|
|
*ResultSize += PackageLength;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function deletes all Font packages from a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private data.
|
|
@param Handle Handle of the package list which contains the to
|
|
be removed Font packages.
|
|
@param PackageList Pointer to a package list that contains removing
|
|
packages.
|
|
|
|
@retval EFI_SUCCESS Font Package(s) is deleted successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RemoveFontPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
LIST_ENTRY *ListHead;
|
|
HII_FONT_PACKAGE_INSTANCE *Package;
|
|
EFI_STATUS Status;
|
|
HII_GLYPH_INFO *GlyphInfo;
|
|
LIST_ENTRY *Link;
|
|
HII_GLOBAL_FONT_INFO *GlobalFont;
|
|
|
|
ListHead = &PackageList->FontPkgHdr;
|
|
|
|
while (!IsListEmpty (ListHead)) {
|
|
Package = CR (
|
|
ListHead->ForwardLink,
|
|
HII_FONT_PACKAGE_INSTANCE,
|
|
FontEntry,
|
|
HII_FONT_PACKAGE_SIGNATURE
|
|
);
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_FONTS,
|
|
Handle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
RemoveEntryList (&Package->FontEntry);
|
|
PackageList->PackageListHdr.PackageLength -= Package->FontPkgHdr->Header.Length;
|
|
|
|
if (Package->GlyphBlock != NULL) {
|
|
FreePool (Package->GlyphBlock);
|
|
}
|
|
FreePool (Package->FontPkgHdr);
|
|
//
|
|
// Delete default character cell information
|
|
//
|
|
while (!IsListEmpty (&Package->GlyphInfoList)) {
|
|
GlyphInfo = CR (
|
|
Package->GlyphInfoList.ForwardLink,
|
|
HII_GLYPH_INFO,
|
|
Entry,
|
|
HII_GLYPH_INFO_SIGNATURE
|
|
);
|
|
RemoveEntryList (&GlyphInfo->Entry);
|
|
FreePool (GlyphInfo);
|
|
}
|
|
|
|
//
|
|
// Remove corresponding global font info
|
|
//
|
|
for (Link = Private->FontInfoList.ForwardLink; Link != &Private->FontInfoList; Link = Link->ForwardLink) {
|
|
GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
|
|
if (GlobalFont->FontPackage == Package) {
|
|
RemoveEntryList (&GlobalFont->Entry);
|
|
FreePool (GlobalFont->FontInfo);
|
|
FreePool (GlobalFont);
|
|
break;
|
|
}
|
|
}
|
|
|
|
FreePool (Package);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function insert a Image package to a package list node.
|
|
This is a internal function.
|
|
|
|
@param PackageHdr Pointer to a buffer stored with Image package
|
|
information.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageList Pointer to a package list which will be inserted
|
|
to.
|
|
@param Package Created Image package
|
|
|
|
@retval EFI_SUCCESS Image Package is inserted successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
Image package.
|
|
@retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InsertImagePackage (
|
|
IN VOID *PackageHdr,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
OUT HII_IMAGE_PACKAGE_INSTANCE **Package
|
|
)
|
|
{
|
|
HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
|
|
UINT32 PaletteSize;
|
|
UINT32 ImageSize;
|
|
UINT16 Index;
|
|
EFI_HII_IMAGE_PALETTE_INFO_HEADER *PaletteHdr;
|
|
EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo;
|
|
UINT32 PaletteInfoOffset;
|
|
UINT32 ImageInfoOffset;
|
|
UINT16 CurrentSize;
|
|
|
|
if (PackageHdr == NULL || PackageList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Less than one image package is allowed in one package list.
|
|
//
|
|
if (PackageList->ImagePkg != NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Create a Image package node
|
|
//
|
|
ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));
|
|
if (ImagePackage == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Copy the Image package header.
|
|
//
|
|
CopyMem (&ImagePackage->ImagePkgHdr, PackageHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));
|
|
|
|
PaletteInfoOffset = ImagePackage->ImagePkgHdr.PaletteInfoOffset;
|
|
ImageInfoOffset = ImagePackage->ImagePkgHdr.ImageInfoOffset;
|
|
|
|
//
|
|
// If PaletteInfoOffset is zero, there are no palettes in this image package.
|
|
//
|
|
PaletteSize = 0;
|
|
ImagePackage->PaletteBlock = NULL;
|
|
if (PaletteInfoOffset != 0) {
|
|
PaletteHdr = (EFI_HII_IMAGE_PALETTE_INFO_HEADER *) ((UINT8 *) PackageHdr + PaletteInfoOffset);
|
|
PaletteSize = sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);
|
|
PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteHdr + PaletteSize);
|
|
|
|
for (Index = 0; Index < PaletteHdr->PaletteCount; Index++) {
|
|
CopyMem (&CurrentSize, PaletteInfo, sizeof (UINT16));
|
|
CurrentSize += sizeof (UINT16);
|
|
PaletteSize += (UINT32) CurrentSize;
|
|
PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteInfo + CurrentSize);
|
|
}
|
|
|
|
ImagePackage->PaletteBlock = (UINT8 *) AllocateZeroPool (PaletteSize);
|
|
if (ImagePackage->PaletteBlock == NULL) {
|
|
FreePool (ImagePackage);
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
CopyMem (
|
|
ImagePackage->PaletteBlock,
|
|
(UINT8 *) PackageHdr + PaletteInfoOffset,
|
|
PaletteSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// If ImageInfoOffset is zero, there are no images in this package.
|
|
//
|
|
ImageSize = 0;
|
|
ImagePackage->ImageBlock = NULL;
|
|
if (ImageInfoOffset != 0) {
|
|
ImageSize = ImagePackage->ImagePkgHdr.Header.Length -
|
|
sizeof (EFI_HII_IMAGE_PACKAGE_HDR) - PaletteSize;
|
|
ImagePackage->ImageBlock = (UINT8 *) AllocateZeroPool (ImageSize);
|
|
if (ImagePackage->ImageBlock == NULL) {
|
|
FreePool (ImagePackage->PaletteBlock);
|
|
FreePool (ImagePackage);
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
CopyMem (
|
|
ImagePackage->ImageBlock,
|
|
(UINT8 *) PackageHdr + ImageInfoOffset,
|
|
ImageSize
|
|
);
|
|
}
|
|
|
|
ImagePackage->ImageBlockSize = ImageSize;
|
|
ImagePackage->PaletteInfoSize = PaletteSize;
|
|
PackageList->ImagePkg = ImagePackage;
|
|
*Package = ImagePackage;
|
|
|
|
if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
|
|
PackageList->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function exports Image packages to a buffer.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param Handle Identification of a package list.
|
|
@param PackageList Pointer to a package list which will be exported.
|
|
@param UsedSize The length of buffer be used.
|
|
@param BufferSize Length of the Buffer.
|
|
@param Buffer Allocated space for storing exported data.
|
|
@param ResultSize The size of the already exported content of this
|
|
package list.
|
|
|
|
@retval EFI_SUCCESS Image Packages are exported successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ExportImagePackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
IN UINTN UsedSize,
|
|
IN UINTN BufferSize,
|
|
IN OUT VOID *Buffer,
|
|
IN OUT UINTN *ResultSize
|
|
)
|
|
{
|
|
UINTN PackageLength;
|
|
EFI_STATUS Status;
|
|
HII_IMAGE_PACKAGE_INSTANCE *Package;
|
|
|
|
|
|
if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (BufferSize > 0 && Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Package = PackageList->ImagePkg;
|
|
|
|
if (Package == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
PackageLength = Package->ImagePkgHdr.Header.Length;
|
|
|
|
if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
|
|
//
|
|
// Invoke registered notification function with EXPORT_PACK notify type
|
|
//
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_IMAGES,
|
|
Handle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
ASSERT (Package->ImagePkgHdr.Header.Length ==
|
|
sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + Package->ImageBlockSize + Package->PaletteInfoSize);
|
|
//
|
|
// Copy Image package header,
|
|
// then justify the offset for image info and palette info in the header.
|
|
//
|
|
CopyMem (Buffer, &Package->ImagePkgHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));
|
|
Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
|
|
|
|
//
|
|
// Copy Image blocks information
|
|
//
|
|
if (Package->ImageBlockSize != 0) {
|
|
CopyMem (Buffer, Package->ImageBlock, Package->ImageBlockSize);
|
|
Buffer = (UINT8 *) Buffer + Package->ImageBlockSize;
|
|
}
|
|
//
|
|
// Copy Palette information
|
|
//
|
|
if (Package->PaletteInfoSize != 0) {
|
|
CopyMem (Buffer, Package->PaletteBlock, Package->PaletteInfoSize);
|
|
Buffer = (UINT8 *) Buffer + Package->PaletteInfoSize;
|
|
}
|
|
}
|
|
|
|
*ResultSize += PackageLength;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function deletes Image package from a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private data.
|
|
@param Handle Handle of the package list which contains the to
|
|
be removed Image packages.
|
|
@param PackageList Package List which contains the to be removed
|
|
Image package.
|
|
|
|
@retval EFI_SUCCESS Image Package(s) is deleted successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RemoveImagePackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
HII_IMAGE_PACKAGE_INSTANCE *Package;
|
|
EFI_STATUS Status;
|
|
|
|
Package = PackageList->ImagePkg;
|
|
|
|
//
|
|
// Image package does not exist, return directly.
|
|
//
|
|
if (Package == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_IMAGES,
|
|
Handle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
PackageList->PackageListHdr.PackageLength -= Package->ImagePkgHdr.Header.Length;
|
|
|
|
FreePool (Package->ImageBlock);
|
|
if (Package->PaletteBlock != NULL) {
|
|
FreePool (Package->PaletteBlock);
|
|
}
|
|
FreePool (Package);
|
|
|
|
PackageList->ImagePkg = NULL;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function insert a Simple Font package to a package list node.
|
|
This is a internal function.
|
|
|
|
@param PackageHdr Pointer to a buffer stored with Simple Font
|
|
package information.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageList Pointer to a package list which will be inserted
|
|
to.
|
|
@param Package Created Simple Font package
|
|
|
|
@retval EFI_SUCCESS Simple Font Package is inserted successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
Simple Font package.
|
|
@retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InsertSimpleFontPackage (
|
|
IN VOID *PackageHdr,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE **Package
|
|
)
|
|
{
|
|
HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;
|
|
EFI_STATUS Status;
|
|
EFI_HII_PACKAGE_HEADER Header;
|
|
|
|
if (PackageHdr == NULL || PackageList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Create a Simple Font package node
|
|
//
|
|
SimpleFontPackage = AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE));
|
|
if (SimpleFontPackage == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
SimpleFontPackage->Signature = HII_S_FONT_PACKAGE_SIGNATURE;
|
|
|
|
//
|
|
// Copy the Simple Font package.
|
|
//
|
|
CopyMem (&Header, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
|
|
SimpleFontPackage->SimpleFontPkgHdr = AllocateZeroPool (Header.Length);
|
|
if (SimpleFontPackage->SimpleFontPkgHdr == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
|
|
CopyMem (SimpleFontPackage->SimpleFontPkgHdr, PackageHdr, Header.Length);
|
|
|
|
//
|
|
// Insert to Simple Font package array
|
|
//
|
|
InsertTailList (&PackageList->SimpleFontPkgHdr, &SimpleFontPackage->SimpleFontEntry);
|
|
*Package = SimpleFontPackage;
|
|
|
|
if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
|
|
PackageList->PackageListHdr.PackageLength += Header.Length;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
Error:
|
|
|
|
if (SimpleFontPackage != NULL) {
|
|
if (SimpleFontPackage->SimpleFontPkgHdr != NULL) {
|
|
FreePool (SimpleFontPackage->SimpleFontPkgHdr);
|
|
}
|
|
FreePool (SimpleFontPackage);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function exports SimpleFont packages to a buffer.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param Handle Identification of a package list.
|
|
@param PackageList Pointer to a package list which will be exported.
|
|
@param UsedSize The length of buffer be used.
|
|
@param BufferSize Length of the Buffer.
|
|
@param Buffer Allocated space for storing exported data.
|
|
@param ResultSize The size of the already exported content of this
|
|
package list.
|
|
|
|
@retval EFI_SUCCESS SimpleFont Packages are exported successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ExportSimpleFontPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
IN UINTN UsedSize,
|
|
IN UINTN BufferSize,
|
|
IN OUT VOID *Buffer,
|
|
IN OUT UINTN *ResultSize
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
UINTN PackageLength;
|
|
EFI_STATUS Status;
|
|
HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;
|
|
|
|
if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (BufferSize > 0 && Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PackageLength = 0;
|
|
Status = EFI_SUCCESS;
|
|
|
|
for (Link = PackageList->SimpleFontPkgHdr.ForwardLink; Link != &PackageList->SimpleFontPkgHdr; Link = Link->ForwardLink) {
|
|
Package = CR (Link, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);
|
|
PackageLength += Package->SimpleFontPkgHdr->Header.Length;
|
|
if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
|
|
//
|
|
// Invoke registered notification function with EXPORT_PACK notify type
|
|
//
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_SIMPLE_FONTS,
|
|
Handle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Copy SimpleFont package
|
|
//
|
|
CopyMem (Buffer, Package->SimpleFontPkgHdr, Package->SimpleFontPkgHdr->Header.Length);
|
|
Buffer = (UINT8 *) Buffer + Package->SimpleFontPkgHdr->Header.Length;
|
|
}
|
|
}
|
|
|
|
*ResultSize += PackageLength;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function deletes all Simple Font packages from a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private data.
|
|
@param Handle Handle of the package list which contains the to
|
|
be removed Simple Font packages.
|
|
@param PackageList Pointer to a package list that contains removing
|
|
packages.
|
|
|
|
@retval EFI_SUCCESS Simple Font Package(s) is deleted successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RemoveSimpleFontPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
LIST_ENTRY *ListHead;
|
|
HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;
|
|
EFI_STATUS Status;
|
|
|
|
ListHead = &PackageList->SimpleFontPkgHdr;
|
|
|
|
while (!IsListEmpty (ListHead)) {
|
|
Package = CR (
|
|
ListHead->ForwardLink,
|
|
HII_SIMPLE_FONT_PACKAGE_INSTANCE,
|
|
SimpleFontEntry,
|
|
HII_S_FONT_PACKAGE_SIGNATURE
|
|
);
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_SIMPLE_FONTS,
|
|
Handle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
RemoveEntryList (&Package->SimpleFontEntry);
|
|
PackageList->PackageListHdr.PackageLength -= Package->SimpleFontPkgHdr->Header.Length;
|
|
FreePool (Package->SimpleFontPkgHdr);
|
|
FreePool (Package);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function insert a Device path package to a package list node.
|
|
This is a internal function.
|
|
|
|
@param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
|
|
instance
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageList Pointer to a package list which will be inserted
|
|
to.
|
|
|
|
@retval EFI_SUCCESS Device path Package is inserted successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
Device path package.
|
|
@retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InsertDevicePathPackage (
|
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
UINT32 PackageLength;
|
|
EFI_HII_PACKAGE_HEADER Header;
|
|
|
|
if (DevicePath == NULL || PackageList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
//
|
|
// Less than one device path package is allowed in one package list.
|
|
//
|
|
if (PackageList->DevicePathPkg != NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PackageLength = (UINT32) GetDevicePathSize (DevicePath) + sizeof (EFI_HII_PACKAGE_HEADER);
|
|
PackageList->DevicePathPkg = (UINT8 *) AllocateZeroPool (PackageLength);
|
|
if (PackageList->DevicePathPkg == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Header.Length = PackageLength;
|
|
Header.Type = EFI_HII_PACKAGE_DEVICE_PATH;
|
|
CopyMem (PackageList->DevicePathPkg, &Header, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
CopyMem (
|
|
PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER),
|
|
DevicePath,
|
|
PackageLength - sizeof (EFI_HII_PACKAGE_HEADER)
|
|
);
|
|
|
|
//
|
|
// Since Device Path package is created by NewPackageList, either NEW_PACK
|
|
// or ADD_PACK should increase the length of package list.
|
|
//
|
|
PackageList->PackageListHdr.PackageLength += PackageLength;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function exports device path package to a buffer.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param Handle Identification of a package list.
|
|
@param PackageList Pointer to a package list which will be exported.
|
|
@param UsedSize The length of buffer be used.
|
|
@param BufferSize Length of the Buffer.
|
|
@param Buffer Allocated space for storing exported data.
|
|
@param ResultSize The size of the already exported content of this
|
|
package list.
|
|
|
|
@retval EFI_SUCCESS Device path Package is exported successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ExportDevicePathPackage (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
IN UINTN UsedSize,
|
|
IN UINTN BufferSize,
|
|
IN OUT VOID *Buffer,
|
|
IN OUT UINTN *ResultSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *Package;
|
|
EFI_HII_PACKAGE_HEADER Header;
|
|
|
|
if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (BufferSize > 0 && Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Package = PackageList->DevicePathPkg;
|
|
|
|
if (Package == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
|
|
if (Header.Length + *ResultSize + UsedSize <= BufferSize) {
|
|
//
|
|
// Invoke registered notification function with EXPORT_PACK notify type
|
|
//
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_DEVICE_PATH,
|
|
Handle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Copy Device path package
|
|
//
|
|
CopyMem (Buffer, Package, Header.Length);
|
|
}
|
|
|
|
*ResultSize += Header.Length;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function deletes Device Path package from a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private data.
|
|
@param Handle Handle of the package list.
|
|
@param PackageList Package List which contains the to be removed
|
|
Device Path package.
|
|
|
|
@retval EFI_SUCCESS Device Path Package is deleted successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RemoveDevicePathPackage (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *Package;
|
|
EFI_HII_PACKAGE_HEADER Header;
|
|
|
|
Package = PackageList->DevicePathPkg;
|
|
|
|
//
|
|
// No device path, return directly.
|
|
//
|
|
if (Package == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_DEVICE_PATH,
|
|
Handle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
PackageList->PackageListHdr.PackageLength -= Header.Length;
|
|
|
|
FreePool (Package);
|
|
|
|
PackageList->DevicePathPkg = NULL;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function will insert a device path package to package list firstly then
|
|
invoke notification functions if any.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
|
|
instance
|
|
@param DatabaseRecord Pointer to a database record contains a package
|
|
list which will be inserted to.
|
|
|
|
@retval EFI_SUCCESS Device path Package is inserted successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
Device path package.
|
|
@retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
AddDevicePathPackage (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
|
IN OUT HII_DATABASE_RECORD *DatabaseRecord
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (DevicePath == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
ASSERT (Private != NULL);
|
|
ASSERT (DatabaseRecord != NULL);
|
|
|
|
//
|
|
// Create a device path package and insert to packagelist
|
|
//
|
|
Status = InsertDevicePathPackage (
|
|
DevicePath,
|
|
NotifyType,
|
|
DatabaseRecord->PackageList
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return InvokeRegisteredFunction (
|
|
Private,
|
|
NotifyType,
|
|
(VOID *) DatabaseRecord->PackageList->DevicePathPkg,
|
|
EFI_HII_PACKAGE_DEVICE_PATH,
|
|
DatabaseRecord->Handle
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
This function insert a Keyboard Layout package to a package list node.
|
|
This is a internal function.
|
|
|
|
@param PackageHdr Pointer to a buffer stored with Keyboard Layout
|
|
package information.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageList Pointer to a package list which will be inserted
|
|
to.
|
|
@param Package Created Keyboard Layout package
|
|
|
|
@retval EFI_SUCCESS Keyboard Layout Package is inserted successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
Keyboard Layout package.
|
|
@retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
InsertKeyboardLayoutPackage (
|
|
IN VOID *PackageHdr,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE **Package
|
|
)
|
|
{
|
|
HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
EFI_STATUS Status;
|
|
|
|
if (PackageHdr == NULL || PackageList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
|
|
//
|
|
// Create a Keyboard Layout package node
|
|
//
|
|
KeyboardLayoutPackage = AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE));
|
|
if (KeyboardLayoutPackage == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
KeyboardLayoutPackage->Signature = HII_KB_LAYOUT_PACKAGE_SIGNATURE;
|
|
|
|
KeyboardLayoutPackage->KeyboardPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);
|
|
if (KeyboardLayoutPackage->KeyboardPkg == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Error;
|
|
}
|
|
|
|
CopyMem (KeyboardLayoutPackage->KeyboardPkg, PackageHdr, PackageHeader.Length);
|
|
InsertTailList (&PackageList->KeyboardLayoutHdr, &KeyboardLayoutPackage->KeyboardEntry);
|
|
|
|
*Package = KeyboardLayoutPackage;
|
|
|
|
if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
|
|
PackageList->PackageListHdr.PackageLength += PackageHeader.Length;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
Error:
|
|
|
|
|
|
if (KeyboardLayoutPackage != NULL) {
|
|
if (KeyboardLayoutPackage->KeyboardPkg != NULL) {
|
|
FreePool (KeyboardLayoutPackage->KeyboardPkg);
|
|
}
|
|
FreePool (KeyboardLayoutPackage);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function exports Keyboard Layout packages to a buffer.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param Handle Identification of a package list.
|
|
@param PackageList Pointer to a package list which will be exported.
|
|
@param UsedSize The length of buffer be used.
|
|
@param BufferSize Length of the Buffer.
|
|
@param Buffer Allocated space for storing exported data.
|
|
@param ResultSize The size of the already exported content of this
|
|
package list.
|
|
|
|
@retval EFI_SUCCESS Keyboard Layout Packages are exported
|
|
successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ExportKeyboardLayoutPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
IN UINTN UsedSize,
|
|
IN UINTN BufferSize,
|
|
IN OUT VOID *Buffer,
|
|
IN OUT UINTN *ResultSize
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
UINTN PackageLength;
|
|
EFI_STATUS Status;
|
|
HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
|
|
if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (BufferSize > 0 && Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PackageLength = 0;
|
|
Status = EFI_SUCCESS;
|
|
|
|
for (Link = PackageList->KeyboardLayoutHdr.ForwardLink; Link != &PackageList->KeyboardLayoutHdr; Link = Link->ForwardLink) {
|
|
Package = CR (Link, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, KeyboardEntry, HII_KB_LAYOUT_PACKAGE_SIGNATURE);
|
|
CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
PackageLength += PackageHeader.Length;
|
|
if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
|
|
//
|
|
// Invoke registered notification function with EXPORT_PACK notify type
|
|
//
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
|
|
(EFI_HII_PACKAGE_HEADER *) Package,
|
|
EFI_HII_PACKAGE_KEYBOARD_LAYOUT,
|
|
Handle
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Copy Keyboard Layout package
|
|
//
|
|
CopyMem (Buffer, Package->KeyboardPkg, PackageHeader.Length);
|
|
Buffer = (UINT8 *) Buffer + PackageHeader.Length;
|
|
}
|
|
}
|
|
|
|
*ResultSize += PackageLength;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function deletes all Keyboard Layout packages from a package list node.
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private data.
|
|
@param Handle Handle of the package list which contains the to
|
|
be removed Keyboard Layout packages.
|
|
@param PackageList Pointer to a package list that contains removing
|
|
packages.
|
|
|
|
@retval EFI_SUCCESS Keyboard Layout Package(s) is deleted
|
|
successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
RemoveKeyboardLayoutPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
|
|
)
|
|
{
|
|
LIST_ENTRY *ListHead;
|
|
HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
EFI_STATUS Status;
|
|
|
|
ListHead = &PackageList->KeyboardLayoutHdr;
|
|
|
|
while (!IsListEmpty (ListHead)) {
|
|
Package = CR (
|
|
ListHead->ForwardLink,
|
|
HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
|
|
KeyboardEntry,
|
|
HII_KB_LAYOUT_PACKAGE_SIGNATURE
|
|
);
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
|
|
(VOID *) Package,
|
|
EFI_HII_PACKAGE_KEYBOARD_LAYOUT,
|
|
Handle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
RemoveEntryList (&Package->KeyboardEntry);
|
|
CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;
|
|
FreePool (Package->KeyboardPkg);
|
|
FreePool (Package);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function will insert a package list to hii database firstly then
|
|
invoke notification functions if any. It is the worker function of
|
|
HiiNewPackageList and HiiUpdatePackageList.
|
|
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param NotifyType The type of change concerning the database.
|
|
@param PackageList Pointer to a package list.
|
|
@param DatabaseRecord Pointer to a database record contains a package
|
|
list instance which will be inserted to.
|
|
|
|
@retval EFI_SUCCESS All incoming packages are inserted to current
|
|
database.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
Device path package.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
AddPackages (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
|
|
IN OUT HII_DATABASE_RECORD *DatabaseRecord
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
HII_GUID_PACKAGE_INSTANCE *GuidPackage;
|
|
HII_IFR_PACKAGE_INSTANCE *FormPackage;
|
|
HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;
|
|
HII_STRING_PACKAGE_INSTANCE *StringPackage;
|
|
HII_FONT_PACKAGE_INSTANCE *FontPackage;
|
|
HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;
|
|
HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
|
|
EFI_HII_PACKAGE_HEADER *PackageHdrPtr;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
UINT32 OldPackageListLen;
|
|
BOOLEAN StringPkgIsAdd;
|
|
|
|
//
|
|
// Initialize Variables
|
|
//
|
|
StringPkgIsAdd = FALSE;
|
|
FontPackage = NULL;
|
|
StringPackage = NULL;
|
|
GuidPackage = NULL;
|
|
FormPackage = NULL;
|
|
ImagePackage = NULL;
|
|
SimpleFontPackage = NULL;
|
|
KeyboardLayoutPackage = NULL;
|
|
|
|
//
|
|
// Process the package list header
|
|
//
|
|
OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength;
|
|
CopyMem (
|
|
&DatabaseRecord->PackageList->PackageListHdr,
|
|
(VOID *) PackageList,
|
|
sizeof (EFI_HII_PACKAGE_LIST_HEADER)
|
|
);
|
|
if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
|
|
DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen;
|
|
}
|
|
|
|
PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
|
|
CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
|
|
switch (PackageHeader.Type) {
|
|
case EFI_HII_PACKAGE_TYPE_GUID:
|
|
Status = InsertGuidPackage (
|
|
PackageHdrPtr,
|
|
NotifyType,
|
|
DatabaseRecord->PackageList,
|
|
&GuidPackage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
NotifyType,
|
|
(VOID *) GuidPackage,
|
|
(UINT8) (PackageHeader.Type),
|
|
DatabaseRecord->Handle
|
|
);
|
|
break;
|
|
case EFI_HII_PACKAGE_FORMS:
|
|
Status = InsertFormPackage (
|
|
PackageHdrPtr,
|
|
NotifyType,
|
|
DatabaseRecord->PackageList,
|
|
&FormPackage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
NotifyType,
|
|
(VOID *) FormPackage,
|
|
(UINT8) (PackageHeader.Type),
|
|
DatabaseRecord->Handle
|
|
);
|
|
break;
|
|
case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
|
|
Status = InsertKeyboardLayoutPackage (
|
|
PackageHdrPtr,
|
|
NotifyType,
|
|
DatabaseRecord->PackageList,
|
|
&KeyboardLayoutPackage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
NotifyType,
|
|
(VOID *) KeyboardLayoutPackage,
|
|
(UINT8) (PackageHeader.Type),
|
|
DatabaseRecord->Handle
|
|
);
|
|
break;
|
|
case EFI_HII_PACKAGE_STRINGS:
|
|
Status = InsertStringPackage (
|
|
Private,
|
|
PackageHdrPtr,
|
|
NotifyType,
|
|
DatabaseRecord->PackageList,
|
|
&StringPackage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
ASSERT (StringPackage != NULL);
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
NotifyType,
|
|
(VOID *) StringPackage,
|
|
(UINT8) (PackageHeader.Type),
|
|
DatabaseRecord->Handle
|
|
);
|
|
StringPkgIsAdd = TRUE;
|
|
break;
|
|
case EFI_HII_PACKAGE_FONTS:
|
|
Status = InsertFontPackage (
|
|
Private,
|
|
PackageHdrPtr,
|
|
NotifyType,
|
|
DatabaseRecord->PackageList,
|
|
&FontPackage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
NotifyType,
|
|
(VOID *) FontPackage,
|
|
(UINT8) (PackageHeader.Type),
|
|
DatabaseRecord->Handle
|
|
);
|
|
break;
|
|
case EFI_HII_PACKAGE_IMAGES:
|
|
Status = InsertImagePackage (
|
|
PackageHdrPtr,
|
|
NotifyType,
|
|
DatabaseRecord->PackageList,
|
|
&ImagePackage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
NotifyType,
|
|
(VOID *) ImagePackage,
|
|
(UINT8) (PackageHeader.Type),
|
|
DatabaseRecord->Handle
|
|
);
|
|
break;
|
|
case EFI_HII_PACKAGE_SIMPLE_FONTS:
|
|
Status = InsertSimpleFontPackage (
|
|
PackageHdrPtr,
|
|
NotifyType,
|
|
DatabaseRecord->PackageList,
|
|
&SimpleFontPackage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = InvokeRegisteredFunction (
|
|
Private,
|
|
NotifyType,
|
|
(VOID *) SimpleFontPackage,
|
|
(UINT8) (PackageHeader.Type),
|
|
DatabaseRecord->Handle
|
|
);
|
|
break;
|
|
case EFI_HII_PACKAGE_DEVICE_PATH:
|
|
Status = AddDevicePathPackage (
|
|
Private,
|
|
NotifyType,
|
|
(EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)),
|
|
DatabaseRecord
|
|
);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
//
|
|
// goto header of next package
|
|
//
|
|
PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
|
|
CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
}
|
|
|
|
//
|
|
// Adjust String Package to make sure all string packages have the same max string ID.
|
|
//
|
|
if (!EFI_ERROR (Status) && StringPkgIsAdd) {
|
|
Status = AdjustStringPackage (DatabaseRecord->PackageList);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function exports a package list to a buffer. It is the worker function
|
|
of HiiExportPackageList.
|
|
|
|
This is a internal function.
|
|
|
|
@param Private Hii database private structure.
|
|
@param Handle Identification of a package list.
|
|
@param PackageList Pointer to a package list which will be exported.
|
|
@param UsedSize The length of buffer has been used by exporting
|
|
package lists when Handle is NULL.
|
|
@param BufferSize Length of the Buffer.
|
|
@param Buffer Allocated space for storing exported data.
|
|
|
|
@retval EFI_SUCCESS Keyboard Layout Packages are exported
|
|
successfully.
|
|
@retval EFI_INVALID_PARAMETER Any input parameter is invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ExportPackageList (
|
|
IN HII_DATABASE_PRIVATE_DATA *Private,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
|
|
IN OUT UINTN *UsedSize,
|
|
IN UINTN BufferSize,
|
|
OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN ResultSize;
|
|
EFI_HII_PACKAGE_HEADER EndofPackageList;
|
|
|
|
ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL);
|
|
ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
|
|
ASSERT (IsHiiHandleValid (Handle));
|
|
|
|
if (BufferSize > 0 && Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Copy the package list header
|
|
// ResultSize indicates the length of the exported bytes of this package list
|
|
//
|
|
ResultSize = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
|
|
if (ResultSize + *UsedSize <= BufferSize) {
|
|
CopyMem ((VOID *) Buffer, PackageList, ResultSize);
|
|
}
|
|
//
|
|
// Copy the packages and invoke EXPORT_PACK notify functions if exists.
|
|
//
|
|
Status = ExportGuidPackages (
|
|
Private,
|
|
Handle,
|
|
PackageList,
|
|
*UsedSize,
|
|
BufferSize,
|
|
(VOID *) ((UINT8 *) Buffer + ResultSize),
|
|
&ResultSize
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = ExportFormPackages (
|
|
Private,
|
|
Handle,
|
|
PackageList,
|
|
*UsedSize,
|
|
BufferSize,
|
|
(VOID *) ((UINT8 *) Buffer + ResultSize),
|
|
&ResultSize
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = ExportKeyboardLayoutPackages (
|
|
Private,
|
|
Handle,
|
|
PackageList,
|
|
*UsedSize,
|
|
BufferSize,
|
|
(VOID *) ((UINT8 *) Buffer + ResultSize),
|
|
&ResultSize
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = ExportStringPackages (
|
|
Private,
|
|
Handle,
|
|
PackageList,
|
|
*UsedSize,
|
|
BufferSize,
|
|
(VOID *) ((UINT8 *) Buffer + ResultSize),
|
|
&ResultSize
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = ExportFontPackages (
|
|
Private,
|
|
Handle,
|
|
PackageList,
|
|
*UsedSize,
|
|
BufferSize,
|
|
(VOID *) ((UINT8 *) Buffer + ResultSize),
|
|
&ResultSize
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = ExportImagePackages (
|
|
Private,
|
|
Handle,
|
|
PackageList,
|
|
*UsedSize,
|
|
BufferSize,
|
|
(VOID *) ((UINT8 *) Buffer + ResultSize),
|
|
&ResultSize
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = ExportSimpleFontPackages (
|
|
Private,
|
|
Handle,
|
|
PackageList,
|
|
*UsedSize,
|
|
BufferSize,
|
|
(VOID *) ((UINT8 *) Buffer + ResultSize),
|
|
&ResultSize
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = ExportDevicePathPackage (
|
|
Private,
|
|
Handle,
|
|
PackageList,
|
|
*UsedSize,
|
|
BufferSize,
|
|
(VOID *) ((UINT8 *) Buffer + ResultSize),
|
|
&ResultSize
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
//
|
|
// Append the package list end.
|
|
//
|
|
EndofPackageList.Length = sizeof (EFI_HII_PACKAGE_HEADER);
|
|
EndofPackageList.Type = EFI_HII_PACKAGE_END;
|
|
if (ResultSize + *UsedSize + sizeof (EFI_HII_PACKAGE_HEADER) <= BufferSize) {
|
|
CopyMem (
|
|
(VOID *) ((UINT8 *) Buffer + ResultSize),
|
|
(VOID *) &EndofPackageList,
|
|
sizeof (EFI_HII_PACKAGE_HEADER)
|
|
);
|
|
}
|
|
|
|
*UsedSize += ResultSize + sizeof (EFI_HII_PACKAGE_HEADER);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function adds the packages in the package list to the database and returns a handle. If there is a
|
|
EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will
|
|
create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
|
|
structure.
|
|
@param DriverHandle Associate the package list with this EFI handle.
|
|
If a NULL is specified, this data will not be associate
|
|
with any drivers and cannot have a callback induced.
|
|
@param Handle A pointer to the EFI_HII_HANDLE instance.
|
|
|
|
@retval EFI_SUCCESS The package list associated with the Handle was
|
|
added to the HII database.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
|
|
database contents.
|
|
@retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.
|
|
@retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiNewPackageList (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
|
|
IN CONST EFI_HANDLE DriverHandle, OPTIONAL
|
|
OUT EFI_HII_HANDLE *Handle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
HII_DATABASE_RECORD *DatabaseRecord;
|
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
|
LIST_ENTRY *Link;
|
|
EFI_GUID PackageListGuid;
|
|
|
|
if (This == NULL || PackageList == NULL || Handle == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID));
|
|
|
|
//
|
|
// Check the Package list GUID to guarantee this GUID is unique in database.
|
|
//
|
|
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
|
|
DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
|
|
if (CompareGuid (
|
|
&(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),
|
|
&PackageListGuid) &&
|
|
DatabaseRecord->DriverHandle == DriverHandle) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Build a PackageList node
|
|
//
|
|
Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Fill in information of the created Package List node
|
|
// according to incoming package list.
|
|
//
|
|
Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
DatabaseRecord->DriverHandle = DriverHandle;
|
|
|
|
//
|
|
// Create a Device path package and add into the package list if exists.
|
|
//
|
|
Status = gBS->HandleProtocol (
|
|
DriverHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
(VOID **) &DevicePath
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
*Handle = DatabaseRecord->Handle;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function removes the package list that is associated with a handle Handle
|
|
from the HII database. Before removing the package, any registered functions
|
|
with the notification type REMOVE_PACK and the same package type will be called.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param Handle The handle that was registered to the data that is
|
|
requested for removal.
|
|
|
|
@retval EFI_SUCCESS The data associated with the Handle was removed
|
|
from the HII database.
|
|
@retval EFI_NOT_FOUND The specified andle is not in database.
|
|
@retval EFI_INVALID_PARAMETER The Handle was not valid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiRemovePackageList (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN EFI_HII_HANDLE Handle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
LIST_ENTRY *Link;
|
|
HII_DATABASE_RECORD *Node;
|
|
HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
|
|
HII_HANDLE *HiiHandle;
|
|
|
|
if (This == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!IsHiiHandleValid (Handle)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
|
|
//
|
|
// Get the packagelist to be removed.
|
|
//
|
|
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
|
|
Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
|
|
if (Node->Handle == Handle) {
|
|
PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
|
|
ASSERT (PackageList != NULL);
|
|
|
|
//
|
|
// Call registered functions with REMOVE_PACK before removing packages
|
|
// then remove them.
|
|
//
|
|
Status = RemoveGuidPackages (Private, Handle, PackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = RemoveFormPackages (Private, Handle, PackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = RemoveStringPackages (Private, Handle, PackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = RemoveFontPackages (Private, Handle, PackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = RemoveImagePackages (Private, Handle, PackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = RemoveSimpleFontPackages (Private, Handle, PackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = RemoveDevicePathPackage (Private, Handle, PackageList);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Free resources of the package list
|
|
//
|
|
RemoveEntryList (&Node->DatabaseEntry);
|
|
|
|
HiiHandle = (HII_HANDLE *) Handle;
|
|
RemoveEntryList (&HiiHandle->Handle);
|
|
Private->HiiHandleCount--;
|
|
ASSERT (Private->HiiHandleCount >= 0);
|
|
|
|
HiiHandle->Signature = 0;
|
|
FreePool (HiiHandle);
|
|
FreePool (Node->PackageList);
|
|
FreePool (Node);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
|
|
/**
|
|
This function updates the existing package list (which has the specified Handle)
|
|
in the HII databases, using the new package list specified by PackageList.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param Handle The handle that was registered to the data that is
|
|
requested to be updated.
|
|
@param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
|
|
package.
|
|
|
|
@retval EFI_SUCCESS The HII database was successfully updated.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated
|
|
database.
|
|
@retval EFI_INVALID_PARAMETER PackageList was NULL.
|
|
@retval EFI_NOT_FOUND The specified Handle is not in database.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiUpdatePackageList (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
LIST_ENTRY *Link;
|
|
HII_DATABASE_RECORD *Node;
|
|
EFI_HII_PACKAGE_HEADER *PackageHdrPtr;
|
|
HII_DATABASE_PACKAGE_LIST_INSTANCE *OldPackageList;
|
|
EFI_HII_PACKAGE_HEADER PackageHeader;
|
|
|
|
if (This == NULL || PackageList == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!IsHiiHandleValid (Handle)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
|
|
PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
//
|
|
// Get original packagelist to be updated
|
|
//
|
|
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
|
|
Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
|
|
if (Node->Handle == Handle) {
|
|
OldPackageList = Node->PackageList;
|
|
//
|
|
// Remove the package if its type matches one of the package types which is
|
|
// contained in the new package list.
|
|
//
|
|
CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
|
|
switch (PackageHeader.Type) {
|
|
case EFI_HII_PACKAGE_TYPE_GUID:
|
|
Status = RemoveGuidPackages (Private, Handle, OldPackageList);
|
|
break;
|
|
case EFI_HII_PACKAGE_FORMS:
|
|
Status = RemoveFormPackages (Private, Handle, OldPackageList);
|
|
break;
|
|
case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
|
|
Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);
|
|
break;
|
|
case EFI_HII_PACKAGE_STRINGS:
|
|
Status = RemoveStringPackages (Private, Handle, OldPackageList);
|
|
break;
|
|
case EFI_HII_PACKAGE_FONTS:
|
|
Status = RemoveFontPackages (Private, Handle, OldPackageList);
|
|
break;
|
|
case EFI_HII_PACKAGE_IMAGES:
|
|
Status = RemoveImagePackages (Private, Handle, OldPackageList);
|
|
break;
|
|
case EFI_HII_PACKAGE_SIMPLE_FONTS:
|
|
Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);
|
|
break;
|
|
case EFI_HII_PACKAGE_DEVICE_PATH:
|
|
Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);
|
|
break;
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
|
|
CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
|
|
}
|
|
|
|
//
|
|
// Add all of the packages within the new package list
|
|
//
|
|
return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
|
|
/**
|
|
This function returns a list of the package handles of the specified type
|
|
that are currently active in the database. The pseudo-type
|
|
EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param PackageType Specifies the package type of the packages to list
|
|
or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
|
|
listed.
|
|
@param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
|
|
this is the pointer to the GUID which must match
|
|
the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.
|
|
Otherwise, it must be NULL.
|
|
@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.
|
|
|
|
@retval EFI_SUCCESS The matching handles are outputed successfully.
|
|
HandleBufferLength is updated with the actual length.
|
|
@retval EFI_BUFFER_TO_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.
|
|
@retval EFI_NOT_FOUND No matching handle could not be found in database.
|
|
@retval EFI_INVALID_PARAMETER HandleBufferLength was NULL.
|
|
@retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not
|
|
zero and Handle was NULL.
|
|
@retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but
|
|
PackageGuid is not NULL, PackageType is a EFI_HII_
|
|
PACKAGE_TYPE_GUID but PackageGuid is NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiListPackageLists (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN UINT8 PackageType,
|
|
IN CONST EFI_GUID *PackageGuid,
|
|
IN OUT UINTN *HandleBufferLength,
|
|
OUT EFI_HII_HANDLE *Handle
|
|
)
|
|
{
|
|
HII_GUID_PACKAGE_INSTANCE *GuidPackage;
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
HII_DATABASE_RECORD *Node;
|
|
LIST_ENTRY *Link;
|
|
BOOLEAN Matched;
|
|
HII_HANDLE **Result;
|
|
UINTN ResultSize;
|
|
HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
|
|
LIST_ENTRY *Link1;
|
|
|
|
//
|
|
// Check input parameters
|
|
//
|
|
if (This == NULL || HandleBufferLength == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (*HandleBufferLength > 0 && Handle == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
|
|
(PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
Matched = FALSE;
|
|
Result = (HII_HANDLE **) Handle;
|
|
ResultSize = 0;
|
|
|
|
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
|
|
Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
|
|
PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
|
|
switch (PackageType) {
|
|
case EFI_HII_PACKAGE_TYPE_GUID:
|
|
for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {
|
|
GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);
|
|
if (CompareGuid (
|
|
(EFI_GUID *) PackageGuid,
|
|
(EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))
|
|
)) {
|
|
Matched = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case EFI_HII_PACKAGE_FORMS:
|
|
if (!IsListEmpty (&PackageList->FormPkgHdr)) {
|
|
Matched = TRUE;
|
|
}
|
|
break;
|
|
case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
|
|
if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {
|
|
Matched = TRUE;
|
|
}
|
|
break;
|
|
case EFI_HII_PACKAGE_STRINGS:
|
|
if (!IsListEmpty (&PackageList->StringPkgHdr)) {
|
|
Matched = TRUE;
|
|
}
|
|
break;
|
|
case EFI_HII_PACKAGE_FONTS:
|
|
if (!IsListEmpty (&PackageList->FontPkgHdr)) {
|
|
Matched = TRUE;
|
|
}
|
|
break;
|
|
case EFI_HII_PACKAGE_IMAGES:
|
|
if (PackageList->ImagePkg != NULL) {
|
|
Matched = TRUE;
|
|
}
|
|
break;
|
|
case EFI_HII_PACKAGE_SIMPLE_FONTS:
|
|
if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {
|
|
Matched = TRUE;
|
|
}
|
|
break;
|
|
case EFI_HII_PACKAGE_DEVICE_PATH:
|
|
if (PackageList->DevicePathPkg != NULL) {
|
|
Matched = TRUE;
|
|
}
|
|
break;
|
|
//
|
|
// Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles
|
|
// to be listed.
|
|
//
|
|
case EFI_HII_PACKAGE_TYPE_ALL:
|
|
Matched = TRUE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//
|
|
// This active package list has the specified package type, list it.
|
|
//
|
|
if (Matched) {
|
|
ResultSize += sizeof (EFI_HII_HANDLE);
|
|
if (ResultSize <= *HandleBufferLength) {
|
|
*Result++ = Node->Handle;
|
|
}
|
|
}
|
|
Matched = FALSE;
|
|
}
|
|
|
|
if (ResultSize == 0) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
if (*HandleBufferLength < ResultSize) {
|
|
*HandleBufferLength = ResultSize;
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
*HandleBufferLength = ResultSize;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This function will export one or all package lists in the database to a buffer.
|
|
For each package list exported, this function will call functions registered
|
|
with EXPORT_PACK and then copy the package list to the buffer.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param Handle An EFI_HII_HANDLE that corresponds to the desired
|
|
package list in the HII database to export or NULL
|
|
to indicate all package lists should be exported.
|
|
@param BufferSize On input, a pointer to the length of the buffer.
|
|
On output, the length of the buffer that is
|
|
required for the exported data.
|
|
@param Buffer A pointer to a buffer that will contain the
|
|
results of the export function.
|
|
|
|
@retval EFI_SUCCESS Package exported.
|
|
@retval EFI_BUFFER_TO_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.
|
|
@retval EFI_NOT_FOUND The specifiecd Handle could not be found in the
|
|
current database.
|
|
@retval EFI_INVALID_PARAMETER BufferSize was NULL.
|
|
@retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero
|
|
and Buffer was NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiExportPackageLists (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN EFI_HII_HANDLE Handle,
|
|
IN OUT UINTN *BufferSize,
|
|
OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
|
|
)
|
|
{
|
|
LIST_ENTRY *Link;
|
|
EFI_STATUS Status;
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
HII_DATABASE_RECORD *Node;
|
|
UINTN UsedSize;
|
|
|
|
if (This == NULL || BufferSize == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (*BufferSize > 0 && Buffer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if ((Handle != NULL) && (!IsHiiHandleValid (Handle))) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
UsedSize = 0;
|
|
|
|
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
|
|
Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
|
|
if (Handle == NULL) {
|
|
//
|
|
// Export all package lists in current hii database.
|
|
//
|
|
Status = ExportPackageList (
|
|
Private,
|
|
Node->Handle,
|
|
(HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),
|
|
&UsedSize,
|
|
*BufferSize,
|
|
(EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
} else if (Handle != NULL && Node->Handle == Handle) {
|
|
Status = ExportPackageList (
|
|
Private,
|
|
Handle,
|
|
(HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),
|
|
&UsedSize,
|
|
*BufferSize,
|
|
Buffer
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
if (*BufferSize < UsedSize) {
|
|
*BufferSize = UsedSize;
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (Handle == NULL && UsedSize != 0) {
|
|
if (*BufferSize < UsedSize) {
|
|
*BufferSize = UsedSize;
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
|
|
/**
|
|
This function registers a function which will be called when specified actions related to packages of
|
|
the specified type occur in the HII database. By registering a function, other HII-related drivers are
|
|
notified when specific package types are added, removed or updated in the HII database.
|
|
Each driver or application which registers a notification should use
|
|
EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param PackageType Specifies the package type of the packages to list
|
|
or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
|
|
listed.
|
|
@param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
|
|
this is the pointer to the GUID which must match
|
|
the Guid field of
|
|
EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must
|
|
be NULL.
|
|
@param PackageNotifyFn Points to the function to be called when the event
|
|
specified by
|
|
NotificationType occurs.
|
|
@param NotifyType Describes the types of notification which this
|
|
function will be receiving.
|
|
@param NotifyHandle Points to the unique handle assigned to the
|
|
registered notification. Can be used in
|
|
EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()
|
|
to stop notifications.
|
|
|
|
@retval EFI_SUCCESS Notification registered successfully.
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures
|
|
@retval EFI_INVALID_PARAMETER NotifyHandle is NULL.
|
|
@retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not
|
|
EFI_HII_PACKAGE_TYPE_GUID.
|
|
@retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is
|
|
EFI_HII_PACKAGE_TYPE_GUID.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiRegisterPackageNotify (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN UINT8 PackageType,
|
|
IN CONST EFI_GUID *PackageGuid,
|
|
IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,
|
|
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
|
|
OUT EFI_HANDLE *NotifyHandle
|
|
)
|
|
{
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
HII_DATABASE_NOTIFY *Notify;
|
|
EFI_STATUS Status;
|
|
|
|
if (This == NULL || NotifyHandle == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
|
|
(PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
|
|
//
|
|
// Allocate a notification node
|
|
//
|
|
Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));
|
|
if (Notify == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Generate a notify handle
|
|
//
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&Notify->NotifyHandle,
|
|
&gEfiCallerIdGuid,
|
|
NULL,
|
|
NULL
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Fill in the information to the notification node
|
|
//
|
|
Notify->Signature = HII_DATABASE_NOTIFY_SIGNATURE;
|
|
Notify->PackageType = PackageType;
|
|
Notify->PackageGuid = (EFI_GUID *) PackageGuid;
|
|
Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn;
|
|
Notify->NotifyType = NotifyType;
|
|
|
|
InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);
|
|
*NotifyHandle = Notify->NotifyHandle;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Removes the specified HII database package-related notification.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param NotificationHandle The handle of the notification function being
|
|
unregistered.
|
|
|
|
@retval EFI_SUCCESS Notification is unregistered successfully.
|
|
@retval EFI_INVALID_PARAMETER The Handle is invalid.
|
|
@retval EFI_NOT_FOUND The incoming notification handle does not exist
|
|
in current hii database.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiUnregisterPackageNotify (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN EFI_HANDLE NotificationHandle
|
|
)
|
|
{
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
HII_DATABASE_NOTIFY *Notify;
|
|
LIST_ENTRY *Link;
|
|
EFI_STATUS Status;
|
|
|
|
if (This == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (NotificationHandle == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Status = gBS->OpenProtocol (
|
|
NotificationHandle,
|
|
&gEfiCallerIdGuid,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
|
|
for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {
|
|
Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);
|
|
if (Notify->NotifyHandle == NotificationHandle) {
|
|
//
|
|
// Remove the matching notification node
|
|
//
|
|
RemoveEntryList (&Notify->DatabaseNotifyEntry);
|
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
|
Notify->NotifyHandle,
|
|
&gEfiCallerIdGuid,
|
|
NULL,
|
|
NULL
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
FreePool (Notify);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
|
|
/**
|
|
This routine retrieves an array of GUID values for each keyboard layout that
|
|
was previously registered in the system.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param KeyGuidBufferLength On input, a pointer to the length of the keyboard
|
|
GUID buffer. On output, the length of the handle
|
|
buffer that is required for the handles found.
|
|
@param KeyGuidBuffer An array of keyboard layout GUID instances
|
|
returned.
|
|
|
|
@retval EFI_SUCCESS KeyGuidBuffer was updated successfully.
|
|
@retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates
|
|
that KeyGuidBuffer is too small to support the
|
|
number of GUIDs. KeyGuidBufferLength is
|
|
updated with a value that will enable the data to
|
|
fit.
|
|
@retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL.
|
|
@retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not
|
|
zero and KeyGuidBuffer is NULL.
|
|
@retval EFI_NOT_FOUND There was no keyboard layout.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiFindKeyboardLayouts (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN OUT UINT16 *KeyGuidBufferLength,
|
|
OUT EFI_GUID *KeyGuidBuffer
|
|
)
|
|
{
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
HII_DATABASE_RECORD *Node;
|
|
HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
|
|
LIST_ENTRY *Link;
|
|
LIST_ENTRY *Link1;
|
|
UINT16 ResultSize;
|
|
UINTN Index;
|
|
UINT16 LayoutCount;
|
|
UINT16 LayoutLength;
|
|
UINT8 *Layout;
|
|
HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
|
|
|
|
if (This == NULL || KeyGuidBufferLength == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
ResultSize = 0;
|
|
|
|
//
|
|
// Search all package lists in whole database to retrieve keyboard layout.
|
|
//
|
|
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
|
|
Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
|
|
PackageList = Node->PackageList;
|
|
for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
|
|
Link1 != &PackageList->KeyboardLayoutHdr;
|
|
Link1 = Link1->ForwardLink
|
|
) {
|
|
//
|
|
// Find out all Keyboard Layout packages in this package list.
|
|
//
|
|
Package = CR (
|
|
Link1,
|
|
HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
|
|
KeyboardEntry,
|
|
HII_KB_LAYOUT_PACKAGE_SIGNATURE
|
|
);
|
|
Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
|
|
CopyMem (
|
|
&LayoutCount,
|
|
(UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),
|
|
sizeof (UINT16)
|
|
);
|
|
for (Index = 0; Index < LayoutCount; Index++) {
|
|
ResultSize += sizeof (EFI_GUID);
|
|
if (ResultSize <= *KeyGuidBufferLength) {
|
|
CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID));
|
|
CopyMem (&LayoutLength, Layout, sizeof (UINT16));
|
|
Layout = Layout + LayoutLength;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ResultSize == 0) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
if (*KeyGuidBufferLength < ResultSize) {
|
|
*KeyGuidBufferLength = ResultSize;
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
*KeyGuidBufferLength = ResultSize;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
This routine retrieves the requested keyboard layout. The layout is a physical description of the keys
|
|
on a keyboard and the character(s) that are associated with a particular set of key strokes.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param KeyGuid A pointer to the unique ID associated with a given
|
|
keyboard layout. If KeyGuid is NULL then the
|
|
current layout will be retrieved.
|
|
@param KeyboardLayoutLength On input, a pointer to the length of the
|
|
KeyboardLayout buffer. On output, the length of
|
|
the data placed into KeyboardLayout.
|
|
@param KeyboardLayout A pointer to a buffer containing the retrieved
|
|
keyboard layout.
|
|
|
|
@retval EFI_SUCCESS The keyboard layout was retrieved successfully.
|
|
@retval EFI_NOT_FOUND The requested keyboard layout was not found.
|
|
@retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was
|
|
NULL.
|
|
@retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates
|
|
that KeyboardLayout is too small to support the
|
|
requested keyboard layout. KeyboardLayoutLength is
|
|
updated with a value that will enable the
|
|
data to fit.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiGetKeyboardLayout (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN CONST EFI_GUID *KeyGuid,
|
|
IN OUT UINT16 *KeyboardLayoutLength,
|
|
OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout
|
|
)
|
|
{
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
HII_DATABASE_RECORD *Node;
|
|
HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
|
|
LIST_ENTRY *Link;
|
|
LIST_ENTRY *Link1;
|
|
UINTN Index;
|
|
UINT8 *Layout;
|
|
UINT16 LayoutCount;
|
|
UINT16 LayoutLength;
|
|
HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
|
|
|
|
if (This == NULL || KeyboardLayoutLength == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
//
|
|
// Retrieve the current keyboard layout.
|
|
//
|
|
if (KeyGuid == NULL) {
|
|
if (Private->CurrentLayout == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));
|
|
if (*KeyboardLayoutLength < LayoutLength) {
|
|
*KeyboardLayoutLength = LayoutLength;
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
|
|
Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
|
|
PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
|
|
for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
|
|
Link1 != &PackageList->KeyboardLayoutHdr;
|
|
Link1 = Link1->ForwardLink
|
|
) {
|
|
Package = CR (
|
|
Link1,
|
|
HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
|
|
KeyboardEntry,
|
|
HII_KB_LAYOUT_PACKAGE_SIGNATURE
|
|
);
|
|
|
|
Layout = (UINT8 *) Package->KeyboardPkg +
|
|
sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
|
|
CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));
|
|
for (Index = 0; Index < LayoutCount; Index++) {
|
|
CopyMem (&LayoutLength, Layout, sizeof (UINT16));
|
|
if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {
|
|
if (LayoutLength <= *KeyboardLayoutLength) {
|
|
CopyMem (KeyboardLayout, Layout, LayoutLength);
|
|
return EFI_SUCCESS;
|
|
} else {
|
|
*KeyboardLayoutLength = LayoutLength;
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
}
|
|
Layout = Layout + LayoutLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
|
|
/**
|
|
This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine
|
|
is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
|
|
group type. This is so that agents which are sensitive to the current keyboard layout being changed
|
|
can be notified of this change.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param KeyGuid A pointer to the unique ID associated with a given
|
|
keyboard layout.
|
|
|
|
@retval EFI_SUCCESS The current keyboard layout was successfully set.
|
|
@retval EFI_NOT_FOUND The referenced keyboard layout was not found, so
|
|
action was taken.
|
|
@retval EFI_INVALID_PARAMETER The KeyGuid was NULL.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiSetKeyboardLayout (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN CONST EFI_GUID *KeyGuid
|
|
)
|
|
{
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
|
|
UINT16 KeyboardLayoutLength;
|
|
EFI_STATUS Status;
|
|
|
|
if (This == NULL || KeyGuid == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
|
|
//
|
|
// The specified GUID equals the current keyboard layout GUID,
|
|
// return directly.
|
|
//
|
|
if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Try to find the incoming keyboard layout data in current database.
|
|
//
|
|
KeyboardLayoutLength = 0;
|
|
KeyboardLayout = NULL;
|
|
Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
return Status;
|
|
}
|
|
|
|
KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength);
|
|
ASSERT (KeyboardLayout != NULL);
|
|
Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Backup current keyboard layout.
|
|
//
|
|
CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));
|
|
if (Private->CurrentLayout != NULL) {
|
|
FreePool(Private->CurrentLayout);
|
|
}
|
|
Private->CurrentLayout = KeyboardLayout;
|
|
|
|
//
|
|
// Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify
|
|
// current keyboard layout is changed.
|
|
//
|
|
Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Return the EFI handle associated with a package list.
|
|
|
|
@param This A pointer to the EFI_HII_DATABASE_PROTOCOL
|
|
instance.
|
|
@param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired
|
|
package list in the HIIdatabase.
|
|
@param DriverHandle On return, contains the EFI_HANDLE which was
|
|
registered with the package list in
|
|
NewPackageList().
|
|
|
|
@retval EFI_SUCCESS The DriverHandle was returned successfully.
|
|
@retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or
|
|
DriverHandle was NULL.
|
|
@retval EFI_NOT_FOUND This PackageList handle can not be found in
|
|
current database.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HiiGetPackageListHandle (
|
|
IN CONST EFI_HII_DATABASE_PROTOCOL *This,
|
|
IN EFI_HII_HANDLE PackageListHandle,
|
|
OUT EFI_HANDLE *DriverHandle
|
|
)
|
|
{
|
|
HII_DATABASE_PRIVATE_DATA *Private;
|
|
HII_DATABASE_RECORD *Node;
|
|
LIST_ENTRY *Link;
|
|
|
|
if (This == NULL || DriverHandle == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!IsHiiHandleValid (PackageListHandle)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
|
|
|
|
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
|
|
Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
|
|
if (Node->Handle == PackageListHandle) {
|
|
*DriverHandle = Node->DriverHandle;
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|