Port DriverSample.inf, HiiDatabase.inf and SetupBrowser.inf
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2915 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
678
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Package.c
Normal file
678
IntelFrameworkModulePkg/Universal/HiiDataBaseDxe/Package.c
Normal file
@ -0,0 +1,678 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Package.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This file contains the package processing code to the HII database.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
//
|
||||
// Include common header file for this module.
|
||||
//
|
||||
#include "CommonHeader.h"
|
||||
|
||||
#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;
|
||||
|
||||
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 = (EFI_HII_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;
|
||||
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;
|
||||
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;
|
||||
|
||||
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 (; 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
|
||||
//
|
||||
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;
|
||||
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;
|
||||
}
|
Reference in New Issue
Block a user