| /** @file | |
| Implementation for EFI_HII_DATABASE_PROTOCOL. | |
| Copyright (c) 2007 - 2015, 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; | |
| } | |
| AsciiStrCpyS (Language, LanguageSize / sizeof (CHAR8), (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; | |
| StrCpyS (FontInfo->FontName, (FontInfoSize - OFFSET_OF(EFI_FONT_INFO,FontName)) / sizeof (CHAR16), 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; | |
| } | |