mirror of https://github.com/acidanthera/audk.git
678 lines
21 KiB
C
678 lines
21 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 2006, Intel Corporation
|
||
|
All rights reserved. This program and the accompanying materials
|
||
|
are licensed and made available under the terms and conditions of the BSD License
|
||
|
which accompanies this distribution. The full text of the license may be found at
|
||
|
http://opensource.org/licenses/bsd-license.php
|
||
|
|
||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
Package.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file contains the package processing code to the HII database.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
#include "HiiDatabase.h"
|
||
|
|
||
|
EFI_STATUS
|
||
|
GetPackSize (
|
||
|
IN VOID *Pack,
|
||
|
OUT UINTN *PackSize,
|
||
|
OUT UINT32 *NumberOfTokens
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
Determines the passed in Pack's size and returns the value.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Returns:
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
EFI_HII_STRING_PACK *StringPack;
|
||
|
UINT16 Type;
|
||
|
UINT32 Length;
|
||
|
|
||
|
*PackSize = 0;
|
||
|
|
||
|
Type = EFI_HII_IFR;
|
||
|
if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {
|
||
|
//
|
||
|
// The header contains the full IFR length
|
||
|
//
|
||
|
CopyMem (&Length, &((EFI_HII_PACK_HEADER *) Pack)->Length, sizeof (Length));
|
||
|
*PackSize = (UINTN) Length;
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
Type = EFI_HII_STRING;
|
||
|
if (!CompareMem (&((EFI_HII_PACK_HEADER *) Pack)->Type, &Type, sizeof (UINT16))) {
|
||
|
//
|
||
|
// The header contains the STRING package length
|
||
|
// The assumption is that the strings for all languages
|
||
|
// are a contiguous block of data and there is a series of
|
||
|
// these package instances which will terminate with a NULL package
|
||
|
// instance.
|
||
|
//
|
||
|
StringPack = (EFI_HII_STRING_PACK *) Pack;
|
||
|
|
||
|
//
|
||
|
// There may be multiple instances packed together of strings
|
||
|
// so we must walk the self describing structures until we encounter
|
||
|
// the NULL structure to determine the full size.
|
||
|
//
|
||
|
CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));
|
||
|
if (NumberOfTokens != NULL) {
|
||
|
CopyMem (NumberOfTokens, &StringPack->NumStringPointers, sizeof (UINT32));
|
||
|
}
|
||
|
|
||
|
while (Length != 0) {
|
||
|
*PackSize = *PackSize + Length;
|
||
|
StringPack = (EFI_HII_STRING_PACK *) ((CHAR8 *) StringPack + Length);
|
||
|
CopyMem (&Length, &StringPack->Header.Length, sizeof (Length));
|
||
|
}
|
||
|
//
|
||
|
// Encountered a length of 0, so let's add the space for the NULL terminator
|
||
|
// pack's length and call it done.
|
||
|
//
|
||
|
*PackSize = *PackSize + sizeof (EFI_HII_STRING_PACK);
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
//
|
||
|
// We only determine the size of the non-global Package types.
|
||
|
// If neither IFR or STRING data were found, return an error
|
||
|
//
|
||
|
return EFI_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
EFI_STATUS
|
||
|
ValidatePack (
|
||
|
IN EFI_HII_PROTOCOL *This,
|
||
|
IN EFI_HII_PACKAGE_INSTANCE *PackageInstance,
|
||
|
OUT EFI_HII_PACKAGE_INSTANCE **StringPackageInstance,
|
||
|
OUT UINT32 *TotalStringCount
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
Verifies that the package instance is using the correct handle for string operations.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Returns:
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
EFI_HII_DATA *HiiData;
|
||
|
EFI_HII_HANDLE_DATABASE *HandleDatabase;
|
||
|
EFI_HII_PACKAGE_INSTANCE *HandlePackageInstance;
|
||
|
UINT8 *RawData;
|
||
|
EFI_GUID Guid;
|
||
|
EFI_HII_IFR_PACK *FormPack;
|
||
|
UINTN Index;
|
||
|
|
||
|
if (This == NULL) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
HiiData = EFI_HII_DATA_FROM_THIS (This);
|
||
|
|
||
|
HandleDatabase = HiiData->DatabaseHead;
|
||
|
ZeroMem (&Guid, sizeof (EFI_GUID));
|
||
|
|
||
|
*StringPackageInstance = PackageInstance;
|
||
|
|
||
|
//
|
||
|
// Based on if there is IFR data in this package instance, determine
|
||
|
// what the location is of the beginning of the string data.
|
||
|
//
|
||
|
if (PackageInstance->IfrSize > 0) {
|
||
|
FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&PackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
|
||
|
} else {
|
||
|
//
|
||
|
// If there is no IFR data assume the caller knows what they are doing.
|
||
|
//
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
RawData = (UINT8 *) FormPack;
|
||
|
|
||
|
for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
|
||
|
if (RawData[Index] == EFI_IFR_FORM_SET_OP) {
|
||
|
//
|
||
|
// Cache the guid for this formset
|
||
|
//
|
||
|
CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Index = RawData[Index + 1] + Index;
|
||
|
}
|
||
|
//
|
||
|
// If there is no string package, and the PackageInstance->IfrPack.Guid and PackageInstance->Guid are
|
||
|
// different, we should return the correct handle for the caller to use for strings.
|
||
|
//
|
||
|
if ((PackageInstance->StringSize == 0) && (!CompareGuid (&Guid, &PackageInstance->Guid))) {
|
||
|
//
|
||
|
// Search the database for a handle that matches the PackageInstance->Guid
|
||
|
//
|
||
|
for (; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
|
||
|
//
|
||
|
// Get Ifrdata and extract the Guid for it
|
||
|
//
|
||
|
HandlePackageInstance = HandleDatabase->Buffer;
|
||
|
|
||
|
ASSERT (HandlePackageInstance->IfrSize != 0);
|
||
|
|
||
|
FormPack = (EFI_HII_IFR_PACK *) ((CHAR8 *) (&HandlePackageInstance->IfrData) + sizeof (EFI_HII_PACK_HEADER));
|
||
|
RawData = (UINT8 *) FormPack;
|
||
|
|
||
|
for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
|
||
|
if (RawData[Index] == EFI_IFR_FORM_SET_OP) {
|
||
|
//
|
||
|
// Cache the guid for this formset
|
||
|
//
|
||
|
CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Index = RawData[Index + 1] + Index;
|
||
|
}
|
||
|
//
|
||
|
// If the Guid from the new handle matches the original Guid referenced in the original package data
|
||
|
// return the appropriate package instance data to use.
|
||
|
//
|
||
|
if (CompareGuid (&Guid, &PackageInstance->Guid)) {
|
||
|
if (TotalStringCount != NULL) {
|
||
|
*TotalStringCount = HandleDatabase->NumberOfTokens;
|
||
|
}
|
||
|
|
||
|
*StringPackageInstance = HandlePackageInstance;
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
// end for
|
||
|
//
|
||
|
} else {
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
HiiNewPack (
|
||
|
IN EFI_HII_PROTOCOL *This,
|
||
|
IN EFI_HII_PACKAGES *Packages,
|
||
|
OUT EFI_HII_HANDLE *Handle
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Extracts the various packs from a package list.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
This - Pointer of HII protocol.
|
||
|
Packages - Pointer of HII packages.
|
||
|
Handle - Handle value to be returned.
|
||
|
|
||
|
Returns:
|
||
|
|
||
|
EFI_SUCCESS - Pacakges has added to HII database successfully.
|
||
|
EFI_INVALID_PARAMETER - Invalid parameter.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
EFI_HII_PACKAGE_INSTANCE *PackageInstance;
|
||
|
EFI_HII_DATA *HiiData;
|
||
|
EFI_HII_HANDLE_DATABASE *HandleDatabase;
|
||
|
EFI_HII_HANDLE_DATABASE *Database;
|
||
|
EFI_HII_PACK_HEADER *PackageHeader;
|
||
|
EFI_HII_GLOBAL_DATA *GlobalData;
|
||
|
EFI_HII_IFR_PACK *IfrPack;
|
||
|
EFI_HII_STRING_PACK *StringPack;
|
||
|
EFI_HII_FONT_PACK *FontPack;
|
||
|
EFI_HII_KEYBOARD_PACK *KeyboardPack;
|
||
|
EFI_STATUS Status;
|
||
|
UINTN IfrSize;
|
||
|
UINTN StringSize;
|
||
|
UINTN TotalStringSize;
|
||
|
UINTN InstanceSize;
|
||
|
UINTN Count;
|
||
|
UINTN Index;
|
||
|
UINT16 Member;
|
||
|
EFI_GUID Guid;
|
||
|
EFI_FORM_SET_STUB FormSetStub;
|
||
|
UINT8 *Location;
|
||
|
UINT16 Unicode;
|
||
|
UINT16 NumWideGlyphs;
|
||
|
UINT16 NumNarrowGlyphs;
|
||
|
UINT32 NumberOfTokens;
|
||
|
UINT32 TotalTokenNumber;
|
||
|
UINT8 *Local;
|
||
|
EFI_NARROW_GLYPH *NarrowGlyph;
|
||
|
EFI_WIDE_GLYPH *WideGlyph;
|
||
|
|
||
|
if (Packages->NumberOfPackages == 0 || This == NULL) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
HiiData = EFI_HII_DATA_FROM_THIS (This);
|
||
|
|
||
|
GlobalData = HiiData->GlobalData;
|
||
|
|
||
|
Database = HiiData->DatabaseHead;
|
||
|
|
||
|
PackageInstance = NULL;
|
||
|
IfrPack = NULL;
|
||
|
StringPack = NULL;
|
||
|
InstanceSize = 0;
|
||
|
IfrSize = 0;
|
||
|
StringSize = 0;
|
||
|
TotalStringSize = 0;
|
||
|
NumberOfTokens = 0;
|
||
|
TotalTokenNumber = 0;
|
||
|
|
||
|
//
|
||
|
// Search through the passed in Packages for the IfrPack and any StringPack.
|
||
|
//
|
||
|
for (Index = 0; Index < Packages->NumberOfPackages; Index++) {
|
||
|
|
||
|
PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));
|
||
|
|
||
|
switch (PackageHeader->Type) {
|
||
|
case EFI_HII_IFR:
|
||
|
//
|
||
|
// There shoule be only one Ifr package.
|
||
|
//
|
||
|
ASSERT (IfrPack == NULL);
|
||
|
IfrPack = (EFI_HII_IFR_PACK *) PackageHeader;
|
||
|
break;
|
||
|
|
||
|
case EFI_HII_STRING:
|
||
|
StringPack = (EFI_HII_STRING_PACK *) PackageHeader;
|
||
|
//
|
||
|
// Sending me a String Package. Get its size.
|
||
|
//
|
||
|
Status = GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);
|
||
|
ASSERT (!EFI_ERROR (Status));
|
||
|
|
||
|
//
|
||
|
// The size which GetPackSize() returns include the null terminator. So if multiple
|
||
|
// string packages are passed in, merge all these packages, and only pad one null terminator.
|
||
|
//
|
||
|
if (TotalStringSize > 0) {
|
||
|
TotalStringSize -= sizeof (EFI_HII_STRING_PACK);
|
||
|
}
|
||
|
|
||
|
TotalStringSize += StringSize;
|
||
|
TotalTokenNumber += NumberOfTokens;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
// If sending a StringPack without an IfrPack, you must include a GuidId
|
||
|
//
|
||
|
if ((StringPack != NULL) && (IfrPack == NULL)) {
|
||
|
if (Packages->GuidId == NULL) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
// If passing in an IfrPack and a GuidId is provided, ensure they are the same value.
|
||
|
//
|
||
|
if ((IfrPack != NULL) && (Packages->GuidId != NULL)) {
|
||
|
Location = ((UINT8 *) IfrPack);
|
||
|
Location = (UINT8 *) (((UINTN) Location) + sizeof (EFI_HII_PACK_HEADER));
|
||
|
|
||
|
//
|
||
|
// Advance to the Form Set Op-code
|
||
|
//
|
||
|
for (Count = 0; ((EFI_IFR_OP_HEADER *) &Location[Count])->OpCode != EFI_IFR_FORM_SET_OP;) {
|
||
|
Count = Count + ((EFI_IFR_OP_HEADER *) &Location[Count])->Length;
|
||
|
}
|
||
|
//
|
||
|
// Copy to local variable
|
||
|
//
|
||
|
CopyMem (&Guid, &((EFI_IFR_FORM_SET *) &Location[Count])->Guid, sizeof (EFI_GUID));
|
||
|
|
||
|
//
|
||
|
// Check to see if IfrPack->Guid != GuidId
|
||
|
//
|
||
|
if (!CompareGuid (&Guid, Packages->GuidId)) {
|
||
|
//
|
||
|
// If a string package is present, the GUIDs should have agreed. Return an error
|
||
|
//
|
||
|
if (StringPack != NULL) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
// If someone is passing in a string only, create a dummy IfrPack with a Guid
|
||
|
// to enable future searching of this data.
|
||
|
//
|
||
|
if ((IfrPack == NULL) && (StringPack != NULL)) {
|
||
|
ZeroMem (&FormSetStub, sizeof (FormSetStub));
|
||
|
|
||
|
FormSetStub.Header.Type = EFI_HII_IFR;
|
||
|
FormSetStub.Header.Length = sizeof (EFI_FORM_SET_STUB);
|
||
|
|
||
|
FormSetStub.FormSet.Header.OpCode = EFI_IFR_FORM_SET_OP;
|
||
|
FormSetStub.FormSet.Header.Length = (UINT8) sizeof (EFI_IFR_FORM_SET);
|
||
|
//
|
||
|
// Dummy string
|
||
|
//
|
||
|
FormSetStub.FormSet.FormSetTitle = 0x02;
|
||
|
CopyMem (&FormSetStub.FormSet.Guid, Packages->GuidId, sizeof (EFI_GUID));
|
||
|
|
||
|
FormSetStub.EndFormSet.Header.OpCode = EFI_IFR_END_FORM_SET_OP;
|
||
|
FormSetStub.EndFormSet.Header.Length = (UINT8) sizeof (EFI_IFR_END_FORM_SET);
|
||
|
IfrPack = (EFI_HII_IFR_PACK *) &FormSetStub;
|
||
|
}
|
||
|
|
||
|
if (IfrPack != NULL) {
|
||
|
//
|
||
|
// Sending me an IFR Package. Get its size.
|
||
|
//
|
||
|
Status = GetPackSize ((VOID *) IfrPack, &IfrSize, NULL);
|
||
|
ASSERT (!EFI_ERROR (Status));
|
||
|
}
|
||
|
//
|
||
|
// Prepare the internal package instace buffer to store package data.
|
||
|
//
|
||
|
InstanceSize = IfrSize + TotalStringSize;
|
||
|
|
||
|
if (InstanceSize != 0) {
|
||
|
PackageInstance = AllocateZeroPool (InstanceSize + sizeof (EFI_HII_PACKAGE_INSTANCE));
|
||
|
|
||
|
ASSERT (PackageInstance);
|
||
|
|
||
|
//
|
||
|
// If there is no DatabaseHead allocated - allocate one
|
||
|
//
|
||
|
if (HiiData->DatabaseHead == NULL) {
|
||
|
HiiData->DatabaseHead = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));
|
||
|
ASSERT (HiiData->DatabaseHead);
|
||
|
}
|
||
|
//
|
||
|
// If the head is being used (Handle is non-zero), allocate next Database and
|
||
|
// add it to the linked-list
|
||
|
//
|
||
|
if (HiiData->DatabaseHead->Handle != 0) {
|
||
|
HandleDatabase = AllocateZeroPool (sizeof (EFI_HII_HANDLE_DATABASE));
|
||
|
|
||
|
ASSERT (HandleDatabase);
|
||
|
|
||
|
for (; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase)
|
||
|
;
|
||
|
|
||
|
//
|
||
|
// We are sitting on the Database entry which contains the null Next pointer. Fix it.
|
||
|
//
|
||
|
Database->NextHandleDatabase = HandleDatabase;
|
||
|
|
||
|
}
|
||
|
|
||
|
Database = HiiData->DatabaseHead;
|
||
|
|
||
|
//
|
||
|
// Initialize this instance data
|
||
|
//
|
||
|
for (*Handle = 1; Database->NextHandleDatabase != NULL; Database = Database->NextHandleDatabase) {
|
||
|
//
|
||
|
// Since the first Database instance will have a passed back handle of 1, we will continue
|
||
|
// down the linked list of entries until we encounter the end of the linked list. Each time
|
||
|
// we go down one level deeper, increment the handle value that will be passed back.
|
||
|
//
|
||
|
if (Database->Handle >= *Handle) {
|
||
|
*Handle = Database->Handle + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PackageInstance->Handle = *Handle;
|
||
|
PackageInstance->IfrSize = IfrSize;
|
||
|
PackageInstance->StringSize = TotalStringSize;
|
||
|
if (Packages->GuidId != NULL) {
|
||
|
CopyMem (&PackageInstance->Guid, Packages->GuidId, sizeof (EFI_GUID));
|
||
|
}
|
||
|
|
||
|
Database->Buffer = PackageInstance;
|
||
|
Database->Handle = PackageInstance->Handle;
|
||
|
Database->NumberOfTokens = TotalTokenNumber;
|
||
|
Database->NextHandleDatabase = NULL;
|
||
|
}
|
||
|
//
|
||
|
// Copy the Ifr package data into package instance.
|
||
|
//
|
||
|
if (IfrSize > 0) {
|
||
|
CopyMem (&PackageInstance->IfrData, IfrPack, IfrSize);
|
||
|
}
|
||
|
//
|
||
|
// Main loop to store package data into HII database.
|
||
|
//
|
||
|
StringSize = 0;
|
||
|
TotalStringSize = 0;
|
||
|
|
||
|
for (Index = 0; Index < Packages->NumberOfPackages; Index++) {
|
||
|
|
||
|
PackageHeader = *(EFI_HII_PACK_HEADER **) (((UINT8 *) Packages) + sizeof (EFI_HII_PACKAGES) + Index * sizeof (VOID *));
|
||
|
|
||
|
switch (PackageHeader->Type) {
|
||
|
case EFI_HII_STRING:
|
||
|
StringPack = (EFI_HII_STRING_PACK *) PackageHeader;
|
||
|
//
|
||
|
// The size which GetPackSize() returns include the null terminator. So if multiple
|
||
|
// string packages are passed in, merge all these packages, and only pad one null terminator.
|
||
|
//
|
||
|
if (TotalStringSize > 0) {
|
||
|
TotalStringSize -= sizeof (EFI_HII_STRING_PACK);
|
||
|
}
|
||
|
|
||
|
GetPackSize ((VOID *) StringPack, &StringSize, &NumberOfTokens);
|
||
|
CopyMem ((CHAR8 *) (&PackageInstance->IfrData) + IfrSize + TotalStringSize, StringPack, StringSize);
|
||
|
|
||
|
TotalStringSize += StringSize;
|
||
|
break;
|
||
|
|
||
|
case EFI_HII_HANDLES:
|
||
|
CopyMem (&PackageInstance->HandlePack, PackageHeader, sizeof (EFI_HII_HANDLE_PACK));
|
||
|
break;
|
||
|
|
||
|
case EFI_HII_FONT:
|
||
|
FontPack = (EFI_HII_FONT_PACK *) PackageHeader;
|
||
|
//
|
||
|
// Add whatever narrow glyphs were passed to us if undefined
|
||
|
//
|
||
|
CopyMem (&NumNarrowGlyphs, &FontPack->NumberOfNarrowGlyphs, sizeof (UINT16));
|
||
|
for (Count = 0; Count <= NumNarrowGlyphs; Count++) {
|
||
|
Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) + (sizeof (EFI_NARROW_GLYPH)) * Count;
|
||
|
NarrowGlyph = (EFI_NARROW_GLYPH *) Local;
|
||
|
CopyMem (&Member, &NarrowGlyph->UnicodeWeight, sizeof (UINT16));
|
||
|
//
|
||
|
// If the glyph is already defined, do not overwrite it. It is what it is.
|
||
|
//
|
||
|
CopyMem (&Unicode, &GlobalData->NarrowGlyphs[Member].UnicodeWeight, sizeof (UINT16));
|
||
|
if (Unicode == 0) {
|
||
|
CopyMem (&GlobalData->NarrowGlyphs[Member], Local, sizeof (EFI_NARROW_GLYPH));
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
// Add whatever wide glyphs were passed to us if undefined
|
||
|
//
|
||
|
CopyMem (&NumWideGlyphs, &FontPack->NumberOfWideGlyphs, sizeof (UINT16));
|
||
|
for (Count = 0; Count <= NumWideGlyphs; Count++) {
|
||
|
Local = (UINT8 *) (&FontPack->NumberOfWideGlyphs + sizeof (UINT8)) +
|
||
|
(sizeof (EFI_NARROW_GLYPH)) *
|
||
|
NumNarrowGlyphs;
|
||
|
WideGlyph = (EFI_WIDE_GLYPH *) Local;
|
||
|
CopyMem (
|
||
|
&Member,
|
||
|
(UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),
|
||
|
sizeof (UINT16)
|
||
|
);
|
||
|
//
|
||
|
// If the glyph is already defined, do not overwrite it. It is what it is.
|
||
|
//
|
||
|
CopyMem (&Unicode, &GlobalData->WideGlyphs[Member].UnicodeWeight, sizeof (UINT16));
|
||
|
if (Unicode == 0) {
|
||
|
Local = (UINT8*)(&FontPack->NumberOfWideGlyphs + sizeof(UINT8)) + (sizeof(EFI_NARROW_GLYPH)) * NumNarrowGlyphs;
|
||
|
WideGlyph = (EFI_WIDE_GLYPH *) Local;
|
||
|
CopyMem (
|
||
|
&GlobalData->WideGlyphs[Member],
|
||
|
(UINTN *) (Local + sizeof (EFI_WIDE_GLYPH) * Count),
|
||
|
sizeof (EFI_WIDE_GLYPH)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case EFI_HII_KEYBOARD:
|
||
|
KeyboardPack = (EFI_HII_KEYBOARD_PACK *) PackageHeader;
|
||
|
//
|
||
|
// Sending me a Keyboard Package
|
||
|
//
|
||
|
if (KeyboardPack->DescriptorCount > 105) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
//
|
||
|
// If someone updates the Descriptors with a count of 0, blow aware the overrides.
|
||
|
//
|
||
|
if (KeyboardPack->DescriptorCount == 0) {
|
||
|
ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);
|
||
|
}
|
||
|
|
||
|
if (KeyboardPack->DescriptorCount < 106 && KeyboardPack->DescriptorCount > 0) {
|
||
|
//
|
||
|
// If SystemKeyboard was updated already, then steer changes to the override database
|
||
|
//
|
||
|
if (GlobalData->SystemKeyboardUpdate) {
|
||
|
ZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);
|
||
|
for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {
|
||
|
CopyMem (&Member, &KeyboardPack->Descriptor[Count].Key, sizeof (UINT16));
|
||
|
CopyMem (
|
||
|
&GlobalData->OverrideKeyboardLayout[Member],
|
||
|
&KeyboardPack->Descriptor[Count],
|
||
|
sizeof (EFI_KEY_DESCRIPTOR)
|
||
|
);
|
||
|
}
|
||
|
} else {
|
||
|
//
|
||
|
// SystemKeyboard was never updated, so this is likely the keyboard driver setting the System database.
|
||
|
//
|
||
|
ZeroMem (GlobalData->SystemKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);
|
||
|
for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {
|
||
|
CopyMem (&Member, &KeyboardPack->Descriptor->Key, sizeof (UINT16));
|
||
|
CopyMem (
|
||
|
&GlobalData->SystemKeyboardLayout[Member],
|
||
|
&KeyboardPack->Descriptor[Count],
|
||
|
sizeof (EFI_KEY_DESCRIPTOR)
|
||
|
);
|
||
|
}
|
||
|
//
|
||
|
// Just updated the system keyboard database, reflect that in the global flag.
|
||
|
//
|
||
|
GlobalData->SystemKeyboardUpdate = TRUE;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
HiiRemovePack (
|
||
|
IN EFI_HII_PROTOCOL *This,
|
||
|
IN EFI_HII_HANDLE Handle
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
Removes the various packs from a Handle
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Returns:
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
EFI_HII_PACKAGE_INSTANCE *PackageInstance;
|
||
|
EFI_HII_DATA *HiiData;
|
||
|
EFI_HII_HANDLE_DATABASE *HandleDatabase;
|
||
|
EFI_HII_HANDLE_DATABASE *PreviousHandleDatabase;
|
||
|
UINTN Count;
|
||
|
|
||
|
if (This == NULL || Handle == 0) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
HiiData = EFI_HII_DATA_FROM_THIS (This);
|
||
|
|
||
|
HandleDatabase = HiiData->DatabaseHead;
|
||
|
PackageInstance = NULL;
|
||
|
|
||
|
//
|
||
|
// Initialize the Previous with the Head of the Database
|
||
|
//
|
||
|
PreviousHandleDatabase = HandleDatabase;
|
||
|
|
||
|
for (Count = 0; HandleDatabase != NULL; HandleDatabase = HandleDatabase->NextHandleDatabase) {
|
||
|
//
|
||
|
// Match the numeric value with the database entry - if matched,
|
||
|
// free the package instance and apply fix-up to database linked list
|
||
|
//
|
||
|
if (Handle == HandleDatabase->Handle) {
|
||
|
PackageInstance = HandleDatabase->Buffer;
|
||
|
|
||
|
//
|
||
|
// Free the Package Instance
|
||
|
//
|
||
|
gBS->FreePool (PackageInstance);
|
||
|
|
||
|
//
|
||
|
// If this was the only Handle in the database
|
||
|
//
|
||
|
if (HiiData->DatabaseHead == HandleDatabase) {
|
||
|
HiiData->DatabaseHead = NULL;
|
||
|
}
|
||
|
//
|
||
|
// Make the parent->Next point to the current->Next
|
||
|
//
|
||
|
PreviousHandleDatabase->NextHandleDatabase = HandleDatabase->NextHandleDatabase;
|
||
|
gBS->FreePool (HandleDatabase);
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
//
|
||
|
// If this was not the HandleDatabase entry we were looking for, cache it just in case the next one is
|
||
|
//
|
||
|
PreviousHandleDatabase = HandleDatabase;
|
||
|
}
|
||
|
//
|
||
|
// No handle was found - error condition
|
||
|
//
|
||
|
if (PackageInstance == NULL) {
|
||
|
return EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|