mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-31 03:03:46 +01:00 
			
		
		
		
	REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			4723 lines
		
	
	
		
			161 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			4723 lines
		
	
	
		
			161 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| Implementation for EFI_HII_DATABASE_PROTOCOL.
 | |
| 
 | |
| Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
 | |
| SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "HiiDatabase.h"
 | |
| 
 | |
| #define BASE_NUMBER  10
 | |
| 
 | |
| EFI_HII_PACKAGE_LIST_HEADER  *gRTDatabaseInfoBuffer = NULL;
 | |
| EFI_STRING                   gRTConfigRespBuffer    = NULL;
 | |
| UINTN                        gDatabaseInfoSize      = 0;
 | |
| UINTN                        gConfigRespSize        = 0;
 | |
| BOOLEAN                      gExportConfigResp      = FALSE;
 | |
| UINTN                        gNvDefaultStoreSize    = 0;
 | |
| SKU_ID                       gSkuId                 = 0xFFFFFFFFFFFFFFFF;
 | |
| LIST_ENTRY                   gVarStorageList        = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);
 | |
| 
 | |
| //
 | |
| // HII database lock.
 | |
| //
 | |
| EFI_LOCK  mHiiDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
 | |
| 
 | |
| /**
 | |
|   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 package
 | |
| 
 | |
|   @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;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Check the input question related to EFI variable
 | |
| 
 | |
|   @param IfrQuestionHdr     Point to Question header
 | |
|   @param EfiVarStoreList    Point to EFI VarStore List
 | |
|   @param EfiVarStoreNumber  The number of EFI VarStore
 | |
| 
 | |
|   @retval Index             The index of the found EFI varstore in EFI varstore list
 | |
|                             EfiVarStoreNumber will return if no EFI varstore is found.
 | |
| **/
 | |
| UINTN
 | |
| IsEfiVarStoreQuestion (
 | |
|   EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr,
 | |
|   EFI_IFR_VARSTORE_EFI     **EfiVarStoreList,
 | |
|   UINTN                    EfiVarStoreNumber
 | |
|   )
 | |
| {
 | |
|   UINTN  Index;
 | |
| 
 | |
|   for (Index = 0; Index < EfiVarStoreNumber; Index++) {
 | |
|     if (IfrQuestionHdr->VarStoreId == EfiVarStoreList[Index]->VarStoreId) {
 | |
|       return Index;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EfiVarStoreNumber;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Find the matched variable from the input variable storage.
 | |
| 
 | |
|   @param[in] VariableStorage Point to the variable storage header.
 | |
|   @param[in] VarGuid         A unique identifier for the variable.
 | |
|   @param[in] VarAttribute    The attributes bitmask for the variable.
 | |
|   @param[in] VarName         A Null-terminated ascii string that is the name of the variable.
 | |
| 
 | |
|   @return Pointer to the matched variable header or NULL if not found.
 | |
| **/
 | |
| VARIABLE_HEADER *
 | |
| FindVariableData (
 | |
|   IN  VARIABLE_STORE_HEADER  *VariableStorage,
 | |
|   IN  EFI_GUID               *VarGuid,
 | |
|   IN  UINT32                 VarAttribute,
 | |
|   IN  CHAR16                 *VarName
 | |
|   )
 | |
| {
 | |
|   VARIABLE_HEADER  *VariableHeader;
 | |
|   VARIABLE_HEADER  *VariableEnd;
 | |
| 
 | |
|   VariableEnd    = (VARIABLE_HEADER *)((UINT8 *)VariableStorage + VariableStorage->Size);
 | |
|   VariableHeader = (VARIABLE_HEADER *)(VariableStorage + 1);
 | |
|   VariableHeader = (VARIABLE_HEADER *)HEADER_ALIGN (VariableHeader);
 | |
|   while (VariableHeader < VariableEnd) {
 | |
|     if (CompareGuid (&VariableHeader->VendorGuid, VarGuid) &&
 | |
|         (VariableHeader->Attributes == VarAttribute) &&
 | |
|         (StrCmp (VarName, (CHAR16 *)(VariableHeader + 1)) == 0))
 | |
|     {
 | |
|       return VariableHeader;
 | |
|     }
 | |
| 
 | |
|     VariableHeader = (VARIABLE_HEADER *)((UINT8 *)VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + VariableHeader->DataSize);
 | |
|     VariableHeader = (VARIABLE_HEADER *)HEADER_ALIGN (VariableHeader);
 | |
|   }
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Find question default value from PcdNvStoreDefaultValueBuffer
 | |
| 
 | |
|   @param DefaultId          Default store ID
 | |
|   @param EfiVarStore        Point to EFI VarStore header
 | |
|   @param IfrQuestionHdr     Point to Question header
 | |
|   @param ValueBuffer        Point to Buffer includes the found default setting
 | |
|   @param Width              Width of the default value
 | |
|   @param BitFieldQuestion   Whether the Question is stored in Bit field.
 | |
| 
 | |
|   @retval EFI_SUCCESS       Question default value is found.
 | |
|   @retval EFI_NOT_FOUND     Question default value is not found.
 | |
| **/
 | |
| EFI_STATUS
 | |
| FindQuestionDefaultSetting (
 | |
|   IN  UINT16                   DefaultId,
 | |
|   IN  EFI_IFR_VARSTORE_EFI     *EfiVarStore,
 | |
|   IN  EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr,
 | |
|   OUT VOID                     *ValueBuffer,
 | |
|   IN  UINTN                    Width,
 | |
|   IN  BOOLEAN                  BitFieldQuestion
 | |
|   )
 | |
| {
 | |
|   VARIABLE_HEADER          *VariableHeader;
 | |
|   VARIABLE_STORE_HEADER    *VariableStorage;
 | |
|   LIST_ENTRY               *Link;
 | |
|   VARSTORAGE_DEFAULT_DATA  *Entry;
 | |
|   VARIABLE_STORE_HEADER    *NvStoreBuffer;
 | |
|   UINT8                    *DataBuffer;
 | |
|   UINT8                    *BufferEnd;
 | |
|   BOOLEAN                  IsFound;
 | |
|   UINTN                    Index;
 | |
|   UINT32                   BufferValue;
 | |
|   UINT32                   BitFieldVal;
 | |
|   UINTN                    BitOffset;
 | |
|   UINTN                    ByteOffset;
 | |
|   UINTN                    BitWidth;
 | |
|   UINTN                    StartBit;
 | |
|   UINTN                    EndBit;
 | |
|   PCD_DEFAULT_DATA         *DataHeader;
 | |
|   PCD_DEFAULT_INFO         *DefaultInfo;
 | |
|   PCD_DATA_DELTA           *DeltaData;
 | |
| 
 | |
|   if (gSkuId == 0xFFFFFFFFFFFFFFFF) {
 | |
|     gSkuId = LibPcdGetSku ();
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Find the DefaultId setting from the full DefaultSetting
 | |
|   //
 | |
|   VariableStorage = NULL;
 | |
|   Link            = gVarStorageList.ForwardLink;
 | |
|   while (Link != &gVarStorageList) {
 | |
|     Entry = BASE_CR (Link, VARSTORAGE_DEFAULT_DATA, Entry);
 | |
|     if (Entry->DefaultId == DefaultId) {
 | |
|       VariableStorage = Entry->VariableStorage;
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     Link = Link->ForwardLink;
 | |
|   }
 | |
| 
 | |
|   if (Link == &gVarStorageList) {
 | |
|     DataBuffer          = (UINT8 *)PcdGetPtr (PcdNvStoreDefaultValueBuffer);
 | |
|     gNvDefaultStoreSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)DataBuffer)->Length;
 | |
|     //
 | |
|     // The first section data includes NV storage default setting.
 | |
|     //
 | |
|     DataHeader      = (PCD_DEFAULT_DATA *)(DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER));
 | |
|     NvStoreBuffer   = (VARIABLE_STORE_HEADER *)((UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize);
 | |
|     VariableStorage = AllocatePool (NvStoreBuffer->Size);
 | |
|     ASSERT (VariableStorage != NULL);
 | |
|     CopyMem (VariableStorage, NvStoreBuffer, NvStoreBuffer->Size);
 | |
| 
 | |
|     //
 | |
|     // Find the matched SkuId and DefaultId in the first section
 | |
|     //
 | |
|     IsFound     = FALSE;
 | |
|     DefaultInfo = &(DataHeader->DefaultInfo[0]);
 | |
|     BufferEnd   = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;
 | |
|     while ((UINT8 *)DefaultInfo < BufferEnd) {
 | |
|       if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == gSkuId)) {
 | |
|         IsFound = TRUE;
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       DefaultInfo++;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Find the matched SkuId and DefaultId in the remaining section
 | |
|     //
 | |
|     Index      = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7));
 | |
|     DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index);
 | |
|     while (!IsFound && Index < gNvDefaultStoreSize && DataHeader->DataSize != 0xFFFF) {
 | |
|       DefaultInfo = &(DataHeader->DefaultInfo[0]);
 | |
|       BufferEnd   = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;
 | |
|       while ((UINT8 *)DefaultInfo < BufferEnd) {
 | |
|         if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == gSkuId)) {
 | |
|           IsFound = TRUE;
 | |
|           break;
 | |
|         }
 | |
| 
 | |
|         DefaultInfo++;
 | |
|       }
 | |
| 
 | |
|       if (IsFound) {
 | |
|         DeltaData = (PCD_DATA_DELTA *)BufferEnd;
 | |
|         BufferEnd = (UINT8 *)DataHeader + DataHeader->DataSize;
 | |
|         while ((UINT8 *)DeltaData < BufferEnd) {
 | |
|           *((UINT8 *)VariableStorage + DeltaData->Offset) = (UINT8)DeltaData->Value;
 | |
|           DeltaData++;
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       Index      = (Index + DataHeader->DataSize + 7) & (~7);
 | |
|       DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index);
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Cache the found result in VarStorageList
 | |
|     //
 | |
|     if (!IsFound) {
 | |
|       FreePool (VariableStorage);
 | |
|       VariableStorage = NULL;
 | |
|     }
 | |
| 
 | |
|     Entry = AllocatePool (sizeof (VARSTORAGE_DEFAULT_DATA));
 | |
|     if (Entry != NULL) {
 | |
|       Entry->DefaultId       = DefaultId;
 | |
|       Entry->VariableStorage = VariableStorage;
 | |
|       InsertTailList (&gVarStorageList, &Entry->Entry);
 | |
|     } else if (VariableStorage != NULL) {
 | |
|       FreePool (VariableStorage);
 | |
|       VariableStorage = NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // The matched variable storage is not found.
 | |
|   //
 | |
|   if (VariableStorage == NULL) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Find the question default value from the variable storage
 | |
|   //
 | |
|   VariableHeader = FindVariableData (VariableStorage, &EfiVarStore->Guid, EfiVarStore->Attributes, (CHAR16 *)EfiVarStore->Name);
 | |
|   if (VariableHeader == NULL) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   StartBit   = 0;
 | |
|   EndBit     = 0;
 | |
|   ByteOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
 | |
|   if (BitFieldQuestion) {
 | |
|     BitOffset  = IfrQuestionHdr->VarStoreInfo.VarOffset;
 | |
|     ByteOffset = BitOffset / 8;
 | |
|     BitWidth   = Width;
 | |
|     StartBit   = BitOffset % 8;
 | |
|     EndBit     = StartBit + BitWidth - 1;
 | |
|     Width      = EndBit / 8 + 1;
 | |
|   }
 | |
| 
 | |
|   if (VariableHeader->DataSize < ByteOffset + Width) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Copy the question value
 | |
|   //
 | |
|   if (ValueBuffer != NULL) {
 | |
|     if (BitFieldQuestion) {
 | |
|       CopyMem (&BufferValue, (UINT8 *)VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + ByteOffset, Width);
 | |
|       BitFieldVal = BitFieldRead32 (BufferValue, StartBit, EndBit);
 | |
|       CopyMem (ValueBuffer, &BitFieldVal, Width);
 | |
|     } else {
 | |
|       CopyMem (ValueBuffer, (UINT8 *)VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + IfrQuestionHdr->VarStoreInfo.VarOffset, Width);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Update IFR default setting in Form Package.
 | |
| 
 | |
|   @param  FormPackage              Form Package to be updated
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| UpdateDefaultSettingInFormPackage (
 | |
|   HII_IFR_PACKAGE_INSTANCE  *FormPackage
 | |
|   )
 | |
| {
 | |
|   UINTN                    IfrOffset;
 | |
|   UINTN                    PackageLength;
 | |
|   EFI_IFR_VARSTORE_EFI     *IfrEfiVarStore;
 | |
|   EFI_IFR_OP_HEADER        *IfrOpHdr;
 | |
|   EFI_IFR_ONE_OF_OPTION    *IfrOneOfOption;
 | |
|   UINT8                    IfrQuestionType;
 | |
|   UINT8                    IfrScope;
 | |
|   EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr;
 | |
|   EFI_IFR_VARSTORE_EFI     **EfiVarStoreList;
 | |
|   UINTN                    EfiVarStoreMaxNum;
 | |
|   UINTN                    EfiVarStoreNumber;
 | |
|   UINT16                   *DefaultIdList;
 | |
|   UINTN                    DefaultIdNumber;
 | |
|   UINTN                    DefaultIdMaxNum;
 | |
|   UINTN                    Index;
 | |
|   UINTN                    EfiVarStoreIndex;
 | |
|   EFI_IFR_TYPE_VALUE       IfrValue;
 | |
|   EFI_IFR_TYPE_VALUE       IfrManufactValue;
 | |
|   BOOLEAN                  StandardDefaultIsSet;
 | |
|   BOOLEAN                  ManufactDefaultIsSet;
 | |
|   EFI_IFR_CHECKBOX         *IfrCheckBox;
 | |
|   EFI_STATUS               Status;
 | |
|   EFI_IFR_DEFAULT          *IfrDefault;
 | |
|   UINTN                    Width;
 | |
|   EFI_IFR_QUESTION_HEADER  VarStoreQuestionHeader;
 | |
|   BOOLEAN                  QuestionReferBitField;
 | |
| 
 | |
|   //
 | |
|   // If no default setting, do nothing
 | |
|   //
 | |
|   if (gNvDefaultStoreSize == 0) {
 | |
|     gNvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);
 | |
|   }
 | |
| 
 | |
|   if (gNvDefaultStoreSize < sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   ZeroMem (&VarStoreQuestionHeader, sizeof (VarStoreQuestionHeader));
 | |
|   PackageLength         = FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);
 | |
|   Width                 = 0;
 | |
|   IfrOffset             = 0;
 | |
|   IfrScope              = 0;
 | |
|   IfrOpHdr              = (EFI_IFR_OP_HEADER *)FormPackage->IfrData;
 | |
|   IfrQuestionHdr        = NULL;
 | |
|   IfrQuestionType       = 0;
 | |
|   EfiVarStoreMaxNum     = 0;
 | |
|   EfiVarStoreNumber     = 0;
 | |
|   DefaultIdMaxNum       = 0;
 | |
|   DefaultIdNumber       = 0;
 | |
|   EfiVarStoreList       = NULL;
 | |
|   DefaultIdList         = NULL;
 | |
|   StandardDefaultIsSet  = FALSE;
 | |
|   ManufactDefaultIsSet  = FALSE;
 | |
|   QuestionReferBitField = FALSE;
 | |
| 
 | |
|   while (IfrOffset < PackageLength) {
 | |
|     switch (IfrOpHdr->OpCode) {
 | |
|       case EFI_IFR_VARSTORE_EFI_OP:
 | |
|         if (EfiVarStoreNumber >= EfiVarStoreMaxNum) {
 | |
|           //
 | |
|           // Reallocate EFI VarStore Buffer
 | |
|           //
 | |
|           EfiVarStoreList = ReallocatePool (EfiVarStoreMaxNum * sizeof (UINTN), (EfiVarStoreMaxNum + BASE_NUMBER) * sizeof (UINTN), EfiVarStoreList);
 | |
|           if (EfiVarStoreList == NULL) {
 | |
|             goto Done;
 | |
|           }
 | |
| 
 | |
|           EfiVarStoreMaxNum = EfiVarStoreMaxNum + BASE_NUMBER;
 | |
|         }
 | |
| 
 | |
|         IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;
 | |
|         //
 | |
|         // Convert VarStore Name from ASCII string to Unicode string.
 | |
|         //
 | |
|         EfiVarStoreList[EfiVarStoreNumber] = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));
 | |
|         if (EfiVarStoreList[EfiVarStoreNumber] == NULL) {
 | |
|           break;
 | |
|         }
 | |
| 
 | |
|         CopyMem (EfiVarStoreList[EfiVarStoreNumber], IfrEfiVarStore, IfrEfiVarStore->Header.Length);
 | |
|         AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *)&(EfiVarStoreList[EfiVarStoreNumber]->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));
 | |
|         Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreNumber], &VarStoreQuestionHeader, NULL, IfrEfiVarStore->Size, FALSE);
 | |
|         if (!EFI_ERROR (Status)) {
 | |
|           EfiVarStoreNumber++;
 | |
|         } else {
 | |
|           FreePool (EfiVarStoreList[EfiVarStoreNumber]);
 | |
|           EfiVarStoreList[EfiVarStoreNumber] = NULL;
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case EFI_IFR_DEFAULTSTORE_OP:
 | |
|         if (DefaultIdNumber >= DefaultIdMaxNum) {
 | |
|           //
 | |
|           // Reallocate DefaultIdNumber
 | |
|           //
 | |
|           DefaultIdList = ReallocatePool (DefaultIdMaxNum * sizeof (UINT16), (DefaultIdMaxNum + BASE_NUMBER) * sizeof (UINT16), DefaultIdList);
 | |
|           if (DefaultIdList == NULL) {
 | |
|             goto Done;
 | |
|           }
 | |
| 
 | |
|           DefaultIdMaxNum = DefaultIdMaxNum + BASE_NUMBER;
 | |
|         }
 | |
| 
 | |
|         DefaultIdList[DefaultIdNumber++] = ((EFI_IFR_DEFAULTSTORE *)IfrOpHdr)->DefaultId;
 | |
|         break;
 | |
|       case EFI_IFR_FORM_OP:
 | |
|       case EFI_IFR_FORM_MAP_OP:
 | |
|         //
 | |
|         // No EFI varstore is found and directly return.
 | |
|         //
 | |
|         if ((EfiVarStoreNumber == 0) || (DefaultIdNumber == 0)) {
 | |
|           goto Done;
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case EFI_IFR_CHECKBOX_OP:
 | |
|         IfrScope         = IfrOpHdr->Scope;
 | |
|         IfrQuestionType  = IfrOpHdr->OpCode;
 | |
|         IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
 | |
|         IfrCheckBox      = (EFI_IFR_CHECKBOX *)IfrOpHdr;
 | |
|         EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);
 | |
|         Width            = sizeof (BOOLEAN);
 | |
|         if (EfiVarStoreIndex < EfiVarStoreNumber) {
 | |
|           for (Index = 0; Index < DefaultIdNumber; Index++) {
 | |
|             if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {
 | |
|               Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);
 | |
|               if (!EFI_ERROR (Status)) {
 | |
|                 if (IfrValue.b) {
 | |
|                   IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT;
 | |
|                 } else {
 | |
|                   IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT);
 | |
|                 }
 | |
|               }
 | |
|             } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
 | |
|               Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);
 | |
|               if (!EFI_ERROR (Status)) {
 | |
|                 if (IfrValue.b) {
 | |
|                   IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT_MFG;
 | |
|                 } else {
 | |
|                   IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT_MFG);
 | |
|                 }
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case EFI_IFR_NUMERIC_OP:
 | |
|         IfrScope        = IfrOpHdr->Scope;
 | |
|         IfrQuestionType = IfrOpHdr->OpCode;
 | |
|         IfrQuestionHdr  = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
 | |
|         if (QuestionReferBitField) {
 | |
|           Width = (UINTN)(((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);
 | |
|         } else {
 | |
|           Width = (UINTN)((UINT32)1 << (((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case EFI_IFR_ONE_OF_OP:
 | |
|         IfrScope        = IfrOpHdr->Scope;
 | |
|         IfrQuestionType = IfrOpHdr->OpCode;
 | |
|         IfrQuestionHdr  = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
 | |
|         if (QuestionReferBitField) {
 | |
|           Width = (UINTN)(((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);
 | |
|         } else {
 | |
|           Width = (UINTN)((UINT32)1 << (((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));
 | |
|         }
 | |
| 
 | |
|         EfiVarStoreIndex     = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);
 | |
|         StandardDefaultIsSet = FALSE;
 | |
|         ManufactDefaultIsSet = FALSE;
 | |
|         //
 | |
|         // Find Default and Manufacturing default for OneOf question
 | |
|         //
 | |
|         if (EfiVarStoreIndex < EfiVarStoreNumber) {
 | |
|           for (Index = 0; Index < DefaultIdNumber; Index++) {
 | |
|             if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {
 | |
|               Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, Width, QuestionReferBitField);
 | |
|               if (!EFI_ERROR (Status)) {
 | |
|                 StandardDefaultIsSet = TRUE;
 | |
|               }
 | |
|             } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
 | |
|               Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_MANUFACTURING, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrManufactValue, Width, QuestionReferBitField);
 | |
|               if (!EFI_ERROR (Status)) {
 | |
|                 ManufactDefaultIsSet = TRUE;
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case EFI_IFR_ORDERED_LIST_OP:
 | |
|         IfrScope        = IfrOpHdr->Scope;
 | |
|         IfrQuestionType = IfrOpHdr->OpCode;
 | |
|         IfrQuestionHdr  = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
 | |
|         break;
 | |
|       case EFI_IFR_ONE_OF_OPTION_OP:
 | |
|         if ((IfrQuestionHdr != NULL) && (IfrScope > 0)) {
 | |
|           IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpHdr;
 | |
|           if (IfrQuestionType == EFI_IFR_ONE_OF_OP) {
 | |
|             Width = (UINTN)((UINT32)1 << (IfrOneOfOption->Flags & EFI_IFR_NUMERIC_SIZE));
 | |
|             if (StandardDefaultIsSet) {
 | |
|               if (CompareMem (&IfrOneOfOption->Value, &IfrValue, Width) == 0) {
 | |
|                 IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT;
 | |
|               } else {
 | |
|                 IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT;
 | |
|               }
 | |
|             }
 | |
| 
 | |
|             if (ManufactDefaultIsSet) {
 | |
|               if (CompareMem (&IfrOneOfOption->Value, &IfrManufactValue, Width) == 0) {
 | |
|                 IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT_MFG;
 | |
|               } else {
 | |
|                 IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT_MFG;
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case EFI_IFR_DEFAULT_OP:
 | |
|         if ((IfrQuestionHdr != NULL) && (IfrScope > 0)) {
 | |
|           IfrDefault = (EFI_IFR_DEFAULT *)IfrOpHdr;
 | |
|           //
 | |
|           // Collect default value width
 | |
|           //
 | |
|           if (!QuestionReferBitField) {
 | |
|             Width = 0;
 | |
|             if ((IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_8) || (IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN)) {
 | |
|               Width = 1;
 | |
|             } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_16) {
 | |
|               Width = 2;
 | |
|             } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_32) {
 | |
|               Width = 4;
 | |
|             } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
 | |
|               Width = 8;
 | |
|             } else if (IfrDefault->Type == EFI_IFR_TYPE_BUFFER) {
 | |
|               Width = IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value);
 | |
|             }
 | |
|           }
 | |
| 
 | |
|           //
 | |
|           // Update the default value
 | |
|           //
 | |
|           if (Width > 0) {
 | |
|             EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);
 | |
|             if (EfiVarStoreIndex < EfiVarStoreNumber) {
 | |
|               Status = FindQuestionDefaultSetting (IfrDefault->DefaultId, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrDefault->Value, Width, QuestionReferBitField);
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case EFI_IFR_END_OP:
 | |
|         if (IfrQuestionHdr != NULL) {
 | |
|           if (IfrScope > 0) {
 | |
|             IfrScope--;
 | |
|           }
 | |
| 
 | |
|           if (IfrScope == 0) {
 | |
|             IfrQuestionHdr        = NULL;
 | |
|             QuestionReferBitField = FALSE;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case EFI_IFR_GUID_OP:
 | |
|         if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
 | |
|           QuestionReferBitField = TRUE;
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       default:
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     IfrOffset = IfrOffset + IfrOpHdr->Length;
 | |
|     IfrOpHdr  = (EFI_IFR_OP_HEADER *)((UINT8 *)IfrOpHdr + IfrOpHdr->Length);
 | |
|     if (IfrScope > 0) {
 | |
|       IfrScope += IfrOpHdr->Scope;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| Done:
 | |
|   if (EfiVarStoreList != NULL) {
 | |
|     for (Index = 0; Index < EfiVarStoreNumber; Index++) {
 | |
|       FreePool (EfiVarStoreList[Index]);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   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;
 | |
| 
 | |
|   //
 | |
|   // Update FormPackage with the default setting
 | |
|   //
 | |
|   UpdateDefaultSettingInFormPackage (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);
 | |
|     //
 | |
|     // If Hii runtime support feature is enabled,
 | |
|     // will export Hii info for runtime use after ReadyToBoot event triggered.
 | |
|     // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
 | |
|     // will need to export the content of HiiDatabase.
 | |
|     // But if form packages removed, also need to export the ConfigResp string
 | |
|     //
 | |
|     if (gExportAfterReadyToBoot) {
 | |
|       gExportConfigResp = TRUE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   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 packages.
 | |
| 
 | |
| **/
 | |
| 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 = 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
 | |
|                    );
 | |
|         //
 | |
|         // If Hii runtime support feature is enabled,
 | |
|         // will export Hii info for runtime use after ReadyToBoot event triggered.
 | |
|         // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
 | |
|         // will need to export the content of HiiDatabase.
 | |
|         // But if form packages added/updated, also need to export the ConfigResp string.
 | |
|         //
 | |
|         if (gExportAfterReadyToBoot) {
 | |
|           gExportConfigResp = TRUE;
 | |
|         }
 | |
| 
 | |
|         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 mainly use to get and update ConfigResp string.
 | |
| 
 | |
| @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
 | |
| 
 | |
| @retval EFI_SUCCESS            Get the information successfully.
 | |
| @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the Configuration Setting data.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| HiiGetConfigRespInfo (
 | |
|   IN CONST EFI_HII_DATABASE_PROTOCOL  *This
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                 Status;
 | |
|   HII_DATABASE_PRIVATE_DATA  *Private;
 | |
|   EFI_STRING                 ConfigAltResp;
 | |
|   UINTN                      ConfigSize;
 | |
| 
 | |
|   ConfigAltResp = NULL;
 | |
|   ConfigSize    = 0;
 | |
| 
 | |
|   Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
 | |
| 
 | |
|   //
 | |
|   // Get ConfigResp string
 | |
|   //
 | |
|   Status = HiiConfigRoutingExportConfig (&Private->ConfigRouting, &ConfigAltResp);
 | |
| 
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     ConfigSize = StrSize (ConfigAltResp);
 | |
|     if (ConfigSize > gConfigRespSize) {
 | |
|       //
 | |
|       // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
 | |
|       // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
 | |
|       //
 | |
|       gConfigRespSize = ConfigSize + (ConfigSize >> 2);
 | |
|       if (gRTConfigRespBuffer != NULL) {
 | |
|         FreePool (gRTConfigRespBuffer);
 | |
|         DEBUG ((DEBUG_WARN, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
 | |
|       }
 | |
| 
 | |
|       gRTConfigRespBuffer = (EFI_STRING)AllocateRuntimeZeroPool (gConfigRespSize);
 | |
|       if (gRTConfigRespBuffer == NULL) {
 | |
|         FreePool (ConfigAltResp);
 | |
|         DEBUG ((DEBUG_ERROR, "[HiiDatabase]: No enough memory resource to store the ConfigResp string.\n"));
 | |
|         //
 | |
|         // Remove from the System Table when the configuration runtime buffer is freed.
 | |
|         //
 | |
|         gBS->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid, NULL);
 | |
|         return EFI_OUT_OF_RESOURCES;
 | |
|       }
 | |
|     } else {
 | |
|       ZeroMem (gRTConfigRespBuffer, gConfigRespSize);
 | |
|     }
 | |
| 
 | |
|     CopyMem (gRTConfigRespBuffer, ConfigAltResp, ConfigSize);
 | |
|     gBS->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid, gRTConfigRespBuffer);
 | |
|     FreePool (ConfigAltResp);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
| This is an internal function,mainly use to get HiiDatabase information.
 | |
| 
 | |
| @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
 | |
| 
 | |
| @retval EFI_SUCCESS            Get the information successfully.
 | |
| @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the Hiidatabase data.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| HiiGetDatabaseInfo (
 | |
|   IN CONST EFI_HII_DATABASE_PROTOCOL  *This
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                   Status;
 | |
|   EFI_HII_PACKAGE_LIST_HEADER  *DatabaseInfo;
 | |
|   UINTN                        DatabaseInfoSize;
 | |
| 
 | |
|   DatabaseInfo     = NULL;
 | |
|   DatabaseInfoSize = 0;
 | |
| 
 | |
|   //
 | |
|   // Get HiiDatabase information.
 | |
|   //
 | |
|   Status = HiiExportPackageLists (This, NULL, &DatabaseInfoSize, DatabaseInfo);
 | |
| 
 | |
|   ASSERT (Status == EFI_BUFFER_TOO_SMALL);
 | |
| 
 | |
|   if (DatabaseInfoSize > gDatabaseInfoSize ) {
 | |
|     //
 | |
|     // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
 | |
|     // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
 | |
|     //
 | |
|     gDatabaseInfoSize = DatabaseInfoSize + (DatabaseInfoSize >> 2);
 | |
|     if (gRTDatabaseInfoBuffer != NULL) {
 | |
|       FreePool (gRTDatabaseInfoBuffer);
 | |
|       DEBUG ((DEBUG_WARN, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
 | |
|     }
 | |
| 
 | |
|     gRTDatabaseInfoBuffer = AllocateRuntimeZeroPool (gDatabaseInfoSize);
 | |
|     if (gRTDatabaseInfoBuffer == NULL) {
 | |
|       DEBUG ((DEBUG_ERROR, "[HiiDatabase]: No enough memory resource to store the HiiDatabase info.\n"));
 | |
|       //
 | |
|       // Remove from the System Table when the configuration runtime buffer is freed.
 | |
|       //
 | |
|       gBS->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid, NULL);
 | |
|       return EFI_OUT_OF_RESOURCES;
 | |
|     }
 | |
|   } else {
 | |
|     ZeroMem (gRTDatabaseInfoBuffer, gDatabaseInfoSize);
 | |
|   }
 | |
| 
 | |
|   Status = HiiExportPackageLists (This, NULL, &DatabaseInfoSize, gRTDatabaseInfoBuffer);
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
|   gBS->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid, gRTDatabaseInfoBuffer);
 | |
| 
 | |
|   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;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   EfiAcquireLock (&mHiiDatabaseLock);
 | |
| 
 | |
|   //
 | |
|   // Build a PackageList node
 | |
|   //
 | |
|   Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     EfiReleaseLock (&mHiiDatabaseLock);
 | |
|     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)) {
 | |
|     EfiReleaseLock (&mHiiDatabaseLock);
 | |
|     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;
 | |
| 
 | |
|   //
 | |
|   // Check whether need to get the Database info.
 | |
|   // Only after ReadyToBoot, need to do the export.
 | |
|   //
 | |
|   if (gExportAfterReadyToBoot) {
 | |
|     HiiGetDatabaseInfo (This);
 | |
|   }
 | |
| 
 | |
|   EfiReleaseLock (&mHiiDatabaseLock);
 | |
| 
 | |
|   //
 | |
|   // Notes:
 | |
|   // HiiGetDatabaseInfo () will get the contents of HII data base,
 | |
|   // belong to the atomic behavior of Hii Database update.
 | |
|   // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
 | |
|   // we can not think it belong to the atomic behavior of Hii Database update.
 | |
|   // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
 | |
|   //
 | |
| 
 | |
|   // Check whether need to get the configuration setting info from HII drivers.
 | |
|   // When after ReadyToBoot and need to do the export for form package add.
 | |
|   //
 | |
|   if (gExportAfterReadyToBoot && gExportConfigResp) {
 | |
|     HiiGetConfigRespInfo (This);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function removes the package list that is associated with 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 handle 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;
 | |
|   }
 | |
| 
 | |
|   EfiAcquireLock (&mHiiDatabaseLock);
 | |
| 
 | |
|   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)) {
 | |
|         EfiReleaseLock (&mHiiDatabaseLock);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       Status = RemoveFormPackages (Private, Handle, PackageList);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         EfiReleaseLock (&mHiiDatabaseLock);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         EfiReleaseLock (&mHiiDatabaseLock);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       Status = RemoveStringPackages (Private, Handle, PackageList);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         EfiReleaseLock (&mHiiDatabaseLock);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       Status = RemoveFontPackages (Private, Handle, PackageList);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         EfiReleaseLock (&mHiiDatabaseLock);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       Status = RemoveImagePackages (Private, Handle, PackageList);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         EfiReleaseLock (&mHiiDatabaseLock);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       Status = RemoveSimpleFontPackages (Private, Handle, PackageList);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         EfiReleaseLock (&mHiiDatabaseLock);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       Status = RemoveDevicePathPackage (Private, Handle, PackageList);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         EfiReleaseLock (&mHiiDatabaseLock);
 | |
|         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);
 | |
| 
 | |
|       //
 | |
|       // Check whether need to get the Database info.
 | |
|       // Only after ReadyToBoot, need to do the export.
 | |
|       //
 | |
|       if (gExportAfterReadyToBoot) {
 | |
|         HiiGetDatabaseInfo (This);
 | |
|       }
 | |
| 
 | |
|       EfiReleaseLock (&mHiiDatabaseLock);
 | |
| 
 | |
|       //
 | |
|       // Notes:
 | |
|       // HiiGetDatabaseInfo () will get the contents of HII data base,
 | |
|       // belong to the atomic behavior of Hii Database update.
 | |
|       // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
 | |
|       // we can not think it belong to the atomic behavior of Hii Database update.
 | |
|       // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
 | |
|       //
 | |
| 
 | |
|       //
 | |
|       // Check whether need to get the configuration setting info from HII drivers.
 | |
|       // When after ReadyToBoot and need to do the export for form package remove.
 | |
|       //
 | |
|       if (gExportAfterReadyToBoot && gExportConfigResp) {
 | |
|         HiiGetConfigRespInfo (This);
 | |
|       }
 | |
| 
 | |
|       return EFI_SUCCESS;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   EfiReleaseLock (&mHiiDatabaseLock);
 | |
|   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;
 | |
| 
 | |
|   EfiAcquireLock (&mHiiDatabaseLock);
 | |
|   //
 | |
|   // 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)) {
 | |
|           EfiReleaseLock (&mHiiDatabaseLock);
 | |
|           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
 | |
|       //
 | |
|       Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);
 | |
| 
 | |
|       //
 | |
|       // Check whether need to get the Database info.
 | |
|       // Only after ReadyToBoot, need to do the export.
 | |
|       //
 | |
|       if (gExportAfterReadyToBoot && (Status == EFI_SUCCESS)) {
 | |
|         HiiGetDatabaseInfo (This);
 | |
|       }
 | |
| 
 | |
|       EfiReleaseLock (&mHiiDatabaseLock);
 | |
| 
 | |
|       //
 | |
|       // Notes:
 | |
|       // HiiGetDatabaseInfo () will get the contents of HII data base,
 | |
|       // belong to the atomic behavior of Hii Database update.
 | |
|       // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
 | |
|       // we can not think it belong to the atomic behavior of Hii Database update.
 | |
|       // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
 | |
|       //
 | |
| 
 | |
|       //
 | |
|       // Check whether need to get the configuration setting info from HII drivers.
 | |
|       // When after ReadyToBoot and need to do the export for form package update.
 | |
|       //
 | |
|       if (gExportAfterReadyToBoot && gExportConfigResp && (Status == EFI_SUCCESS)) {
 | |
|         HiiGetConfigRespInfo (This);
 | |
|       }
 | |
| 
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   EfiReleaseLock (&mHiiDatabaseLock);
 | |
|   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 outputted 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;
 | |
|       //
 | |
|       // Pseudo-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 specified 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;
 | |
| }
 |