package.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 679 行 · 第 1/2 页
C
679 行
//
// 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
//
EfiCopyMem (&Guid, &((EFI_IFR_FORM_SET *) &Location[Count])->Guid, sizeof (EFI_GUID));
//
// Check to see if IfrPack->Guid != GuidId
//
if (!EfiCompareGuid (&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)) {
EfiZeroMem (&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;
EfiCopyMem (&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 = EfiLibAllocateZeroPool (InstanceSize + sizeof (EFI_HII_PACKAGE_INSTANCE));
ASSERT (PackageInstance);
//
// If there is no DatabaseHead allocated - allocate one
//
if (HiiData->DatabaseHead == NULL) {
HiiData->DatabaseHead = EfiLibAllocateZeroPool (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 = EfiLibAllocateZeroPool (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) {
EfiCopyMem (&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) {
EfiCopyMem (&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);
EfiCopyMem ((CHAR8 *) (&PackageInstance->IfrData) + IfrSize + TotalStringSize, StringPack, StringSize);
TotalStringSize += StringSize;
break;
case EFI_HII_HANDLES:
Handlepack = (EFI_HII_HANDLE_PACK *) PackageHeader;
PackageInstance->HandlePack = *Handlepack;
break;
case EFI_HII_FONT:
FontPack = (EFI_HII_FONT_PACK *) PackageHeader;
//
// Add whatever narrow glyphs were passed to us if undefined
//
EfiCopyMem (&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;
EfiCopyMem (&Member, &NarrowGlyph->UnicodeWeight, sizeof (UINT16));
//
// If the glyph is already defined, do not overwrite it. It is what it is.
//
EfiCopyMem (&Unicode, &GlobalData->NarrowGlyphs[Member].UnicodeWeight, sizeof (UINT16));
if (Unicode == 0) {
EfiCopyMem (&GlobalData->NarrowGlyphs[Member], Local, sizeof (EFI_NARROW_GLYPH));
}
}
//
// Add whatever wide glyphs were passed to us if undefined
//
EfiCopyMem (&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;
EfiCopyMem (
&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.
//
EfiCopyMem (&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;
EfiCopyMem (
&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) {
EfiZeroMem (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) {
EfiZeroMem (GlobalData->OverrideKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);
for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {
EfiCopyMem (&Member, &KeyboardPack->Descriptor[Count].Key, sizeof (UINT16));
EfiCopyMem (
&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.
//
EfiZeroMem (GlobalData->SystemKeyboardLayout, sizeof (EFI_KEY_DESCRIPTOR) * 106);
for (Count = 0; Count < KeyboardPack->DescriptorCount; Count++) {
EfiCopyMem (&Member, &KeyboardPack->Descriptor->Key, sizeof (UINT16));
EfiCopyMem (
&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;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?