2 Implementation for EFI_HII_DATABASE_PROTOCOL.
4 Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "HiiDatabase.h"
11 #define BASE_NUMBER 10
13 EFI_HII_PACKAGE_LIST_HEADER
*gRTDatabaseInfoBuffer
= NULL
;
14 EFI_STRING gRTConfigRespBuffer
= NULL
;
15 UINTN gDatabaseInfoSize
= 0;
16 UINTN gConfigRespSize
= 0;
17 BOOLEAN gExportConfigResp
= FALSE
;
18 UINTN gNvDefaultStoreSize
= 0;
19 SKU_ID gSkuId
= 0xFFFFFFFFFFFFFFFF;
20 LIST_ENTRY gVarStorageList
= INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList
);
25 EFI_LOCK mHiiDatabaseLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY
);
28 This function generates a HII_DATABASE_RECORD node and adds into hii database.
29 This is a internal function.
31 @param Private hii database private structure
32 @param DatabaseNode HII_DATABASE_RECORD node which is used to store a
35 @retval EFI_SUCCESS A database record is generated successfully.
36 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
38 @retval EFI_INVALID_PARAMETER Private is NULL or DatabaseRecord is NULL.
42 GenerateHiiDatabaseRecord (
43 IN HII_DATABASE_PRIVATE_DATA
*Private
,
44 OUT HII_DATABASE_RECORD
**DatabaseNode
47 HII_DATABASE_RECORD
*DatabaseRecord
;
48 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
49 HII_HANDLE
*HiiHandle
;
51 if ((Private
== NULL
) || (DatabaseNode
== NULL
)) {
52 return EFI_INVALID_PARAMETER
;
55 DatabaseRecord
= (HII_DATABASE_RECORD
*)AllocateZeroPool (sizeof (HII_DATABASE_RECORD
));
56 if (DatabaseRecord
== NULL
) {
57 return EFI_OUT_OF_RESOURCES
;
60 DatabaseRecord
->Signature
= HII_DATABASE_RECORD_SIGNATURE
;
62 DatabaseRecord
->PackageList
= AllocateZeroPool (sizeof (HII_DATABASE_PACKAGE_LIST_INSTANCE
));
63 if (DatabaseRecord
->PackageList
== NULL
) {
64 FreePool (DatabaseRecord
);
65 return EFI_OUT_OF_RESOURCES
;
68 PackageList
= DatabaseRecord
->PackageList
;
70 InitializeListHead (&PackageList
->GuidPkgHdr
);
71 InitializeListHead (&PackageList
->FormPkgHdr
);
72 InitializeListHead (&PackageList
->KeyboardLayoutHdr
);
73 InitializeListHead (&PackageList
->StringPkgHdr
);
74 InitializeListHead (&PackageList
->FontPkgHdr
);
75 InitializeListHead (&PackageList
->SimpleFontPkgHdr
);
76 PackageList
->ImagePkg
= NULL
;
77 PackageList
->DevicePathPkg
= NULL
;
80 // Create a new hii handle
82 HiiHandle
= (HII_HANDLE
*)AllocateZeroPool (sizeof (HII_HANDLE
));
83 if (HiiHandle
== NULL
) {
84 FreePool (DatabaseRecord
->PackageList
);
85 FreePool (DatabaseRecord
);
86 return EFI_OUT_OF_RESOURCES
;
89 HiiHandle
->Signature
= HII_HANDLE_SIGNATURE
;
91 // Backup the number of Hii handles
93 Private
->HiiHandleCount
++;
94 HiiHandle
->Key
= (UINTN
)Private
->HiiHandleCount
;
96 // Insert the handle to hii handle list of the whole database.
98 InsertTailList (&Private
->HiiHandleList
, &HiiHandle
->Handle
);
100 DatabaseRecord
->Handle
= (EFI_HII_HANDLE
)HiiHandle
;
103 // Insert the Package List node to Package List link of the whole database.
105 InsertTailList (&Private
->DatabaseList
, &DatabaseRecord
->DatabaseEntry
);
107 *DatabaseNode
= DatabaseRecord
;
113 This function checks whether a handle is a valid EFI_HII_HANDLE
114 This is a internal function.
116 @param Handle Pointer to a EFI_HII_HANDLE
119 @retval FALSE Invalid
124 EFI_HII_HANDLE Handle
127 HII_HANDLE
*HiiHandle
;
129 HiiHandle
= (HII_HANDLE
*)Handle
;
131 if (HiiHandle
== NULL
) {
135 if (HiiHandle
->Signature
!= HII_HANDLE_SIGNATURE
) {
143 This function invokes the matching registered function.
144 This is a internal function.
146 @param Private HII Database driver private structure.
147 @param NotifyType The type of change concerning the database.
148 @param PackageInstance Points to the package referred to by the
150 @param PackageType Package type
151 @param Handle The handle of the package list which contains the
154 @retval EFI_SUCCESS Already checked all registered function and
156 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
160 InvokeRegisteredFunction (
161 IN HII_DATABASE_PRIVATE_DATA
*Private
,
162 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
163 IN VOID
*PackageInstance
,
164 IN UINT8 PackageType
,
165 IN EFI_HII_HANDLE Handle
168 HII_DATABASE_NOTIFY
*Notify
;
170 EFI_HII_PACKAGE_HEADER
*Package
;
174 UINT32 ImageBlockSize
;
175 UINT32 PaletteInfoSize
;
177 if ((Private
== NULL
) || ((NotifyType
& 0xF) == 0) || (PackageInstance
== NULL
)) {
178 return EFI_INVALID_PARAMETER
;
181 if (Private
->Signature
!= HII_DATABASE_PRIVATE_DATA_SIGNATURE
) {
182 return EFI_INVALID_PARAMETER
;
185 if (!IsHiiHandleValid (Handle
)) {
186 return EFI_INVALID_PARAMETER
;
193 // Convert the incoming package from hii database storage format to UEFI
194 // storage format. e.g. HII_GUID_PACKAGE_INSTANCE to EFI_HII_GUID_PACKAGE_HDR.
196 switch (PackageType
) {
197 case EFI_HII_PACKAGE_TYPE_GUID
:
198 Package
= (EFI_HII_PACKAGE_HEADER
*)(((HII_GUID_PACKAGE_INSTANCE
*)PackageInstance
)->GuidPkg
);
201 case EFI_HII_PACKAGE_FORMS
:
202 BufferSize
= ((HII_IFR_PACKAGE_INSTANCE
*)PackageInstance
)->FormPkgHdr
.Length
;
203 Buffer
= (UINT8
*)AllocateZeroPool (BufferSize
);
204 ASSERT (Buffer
!= NULL
);
207 &((HII_IFR_PACKAGE_INSTANCE
*)PackageInstance
)->FormPkgHdr
,
208 sizeof (EFI_HII_PACKAGE_HEADER
)
211 Buffer
+ sizeof (EFI_HII_PACKAGE_HEADER
),
212 ((HII_IFR_PACKAGE_INSTANCE
*)PackageInstance
)->IfrData
,
213 BufferSize
- sizeof (EFI_HII_PACKAGE_HEADER
)
215 Package
= (EFI_HII_PACKAGE_HEADER
*)Buffer
;
218 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
219 Package
= (EFI_HII_PACKAGE_HEADER
*)(((HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*)PackageInstance
)->KeyboardPkg
);
222 case EFI_HII_PACKAGE_STRINGS
:
223 BufferSize
= ((HII_STRING_PACKAGE_INSTANCE
*)PackageInstance
)->StringPkgHdr
->Header
.Length
;
224 HeaderSize
= ((HII_STRING_PACKAGE_INSTANCE
*)PackageInstance
)->StringPkgHdr
->HdrSize
;
225 Buffer
= (UINT8
*)AllocateZeroPool (BufferSize
);
226 ASSERT (Buffer
!= NULL
);
229 ((HII_STRING_PACKAGE_INSTANCE
*)PackageInstance
)->StringPkgHdr
,
234 ((HII_STRING_PACKAGE_INSTANCE
*)PackageInstance
)->StringBlock
,
235 BufferSize
- HeaderSize
237 Package
= (EFI_HII_PACKAGE_HEADER
*)Buffer
;
240 case EFI_HII_PACKAGE_FONTS
:
241 BufferSize
= ((HII_FONT_PACKAGE_INSTANCE
*)PackageInstance
)->FontPkgHdr
->Header
.Length
;
242 HeaderSize
= ((HII_FONT_PACKAGE_INSTANCE
*)PackageInstance
)->FontPkgHdr
->HdrSize
;
243 Buffer
= (UINT8
*)AllocateZeroPool (BufferSize
);
244 ASSERT (Buffer
!= NULL
);
247 ((HII_FONT_PACKAGE_INSTANCE
*)PackageInstance
)->FontPkgHdr
,
252 ((HII_FONT_PACKAGE_INSTANCE
*)PackageInstance
)->GlyphBlock
,
253 BufferSize
- HeaderSize
255 Package
= (EFI_HII_PACKAGE_HEADER
*)Buffer
;
258 case EFI_HII_PACKAGE_IMAGES
:
259 BufferSize
= ((HII_IMAGE_PACKAGE_INSTANCE
*)PackageInstance
)->ImagePkgHdr
.Header
.Length
;
260 HeaderSize
= sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
261 Buffer
= (UINT8
*)AllocateZeroPool (BufferSize
);
262 ASSERT (Buffer
!= NULL
);
266 &((HII_IMAGE_PACKAGE_INSTANCE
*)PackageInstance
)->ImagePkgHdr
,
270 Buffer
+ sizeof (EFI_HII_PACKAGE_HEADER
),
275 ImageBlockSize
= ((HII_IMAGE_PACKAGE_INSTANCE
*)PackageInstance
)->ImageBlockSize
;
276 if (ImageBlockSize
!= 0) {
279 ((HII_IMAGE_PACKAGE_INSTANCE
*)PackageInstance
)->ImageBlock
,
284 PaletteInfoSize
= ((HII_IMAGE_PACKAGE_INSTANCE
*)PackageInstance
)->PaletteInfoSize
;
285 if (PaletteInfoSize
!= 0) {
287 Buffer
+ HeaderSize
+ ImageBlockSize
,
288 ((HII_IMAGE_PACKAGE_INSTANCE
*)PackageInstance
)->PaletteBlock
,
291 HeaderSize
+= ImageBlockSize
;
293 Buffer
+ sizeof (EFI_HII_PACKAGE_HEADER
) + sizeof (UINT32
),
299 Package
= (EFI_HII_PACKAGE_HEADER
*)Buffer
;
302 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
303 BufferSize
= ((HII_SIMPLE_FONT_PACKAGE_INSTANCE
*)PackageInstance
)->SimpleFontPkgHdr
->Header
.Length
;
304 Buffer
= (UINT8
*)AllocateZeroPool (BufferSize
);
305 ASSERT (Buffer
!= NULL
);
308 ((HII_SIMPLE_FONT_PACKAGE_INSTANCE
*)PackageInstance
)->SimpleFontPkgHdr
,
311 Package
= (EFI_HII_PACKAGE_HEADER
*)Buffer
;
314 case EFI_HII_PACKAGE_DEVICE_PATH
:
315 Package
= (EFI_HII_PACKAGE_HEADER
*)PackageInstance
;
319 return EFI_INVALID_PARAMETER
;
322 for (Link
= Private
->DatabaseNotifyList
.ForwardLink
;
323 Link
!= &Private
->DatabaseNotifyList
;
324 Link
= Link
->ForwardLink
327 Notify
= CR (Link
, HII_DATABASE_NOTIFY
, DatabaseNotifyEntry
, HII_DATABASE_NOTIFY_SIGNATURE
);
328 if ((Notify
->NotifyType
== NotifyType
) && (Notify
->PackageType
== PackageType
)) {
330 // Check in case PackageGuid is not NULL when Package is GUID package
332 if (PackageType
!= EFI_HII_PACKAGE_TYPE_GUID
) {
333 Notify
->PackageGuid
= NULL
;
337 // Status of Registered Function is unknown so did not check it
339 Notify
->PackageNotifyFn (
349 if (Buffer
!= NULL
) {
357 This function insert a GUID package to a package list node.
358 This is a internal function.
360 @param PackageHdr Pointer to a buffer stored with GUID package
362 @param NotifyType The type of change concerning the database.
363 @param PackageList Pointer to a package list which will be inserted
365 @param Package Created GUID package
367 @retval EFI_SUCCESS Guid Package is inserted successfully.
368 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
370 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
376 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
377 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
378 OUT HII_GUID_PACKAGE_INSTANCE
**Package
381 HII_GUID_PACKAGE_INSTANCE
*GuidPackage
;
382 EFI_HII_PACKAGE_HEADER PackageHeader
;
384 if ((PackageHdr
== NULL
) || (PackageList
== NULL
)) {
385 return EFI_INVALID_PARAMETER
;
388 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
391 // Create a GUID package node
393 GuidPackage
= (HII_GUID_PACKAGE_INSTANCE
*)AllocateZeroPool (sizeof (HII_GUID_PACKAGE_INSTANCE
));
394 if (GuidPackage
== NULL
) {
395 return EFI_OUT_OF_RESOURCES
;
398 GuidPackage
->GuidPkg
= (UINT8
*)AllocateZeroPool (PackageHeader
.Length
);
399 if (GuidPackage
->GuidPkg
== NULL
) {
400 FreePool (GuidPackage
);
401 return EFI_OUT_OF_RESOURCES
;
404 GuidPackage
->Signature
= HII_GUID_PACKAGE_SIGNATURE
;
405 CopyMem (GuidPackage
->GuidPkg
, PackageHdr
, PackageHeader
.Length
);
406 InsertTailList (&PackageList
->GuidPkgHdr
, &GuidPackage
->GuidEntry
);
407 *Package
= GuidPackage
;
409 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
410 PackageList
->PackageListHdr
.PackageLength
+= PackageHeader
.Length
;
417 This function exports GUID packages to a buffer.
418 This is a internal function.
420 @param Private Hii database private structure.
421 @param Handle Identification of a package list.
422 @param PackageList Pointer to a package list which will be exported.
423 @param UsedSize The length of buffer be used.
424 @param BufferSize Length of the Buffer.
425 @param Buffer Allocated space for storing exported data.
426 @param ResultSize The size of the already exported content of this
429 @retval EFI_SUCCESS Guid Packages are exported successfully.
430 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
435 IN HII_DATABASE_PRIVATE_DATA
*Private
,
436 IN EFI_HII_HANDLE Handle
,
437 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
441 IN OUT UINTN
*ResultSize
444 HII_GUID_PACKAGE_INSTANCE
*GuidPackage
;
447 EFI_HII_PACKAGE_HEADER PackageHeader
;
450 if ((PackageList
== NULL
) || (ResultSize
== NULL
)) {
451 return EFI_INVALID_PARAMETER
;
454 if ((BufferSize
> 0) && (Buffer
== NULL
)) {
455 return EFI_INVALID_PARAMETER
;
459 Status
= EFI_SUCCESS
;
461 for (Link
= PackageList
->GuidPkgHdr
.ForwardLink
; Link
!= &PackageList
->GuidPkgHdr
; Link
= Link
->ForwardLink
) {
462 GuidPackage
= CR (Link
, HII_GUID_PACKAGE_INSTANCE
, GuidEntry
, HII_GUID_PACKAGE_SIGNATURE
);
463 CopyMem (&PackageHeader
, GuidPackage
->GuidPkg
, sizeof (EFI_HII_PACKAGE_HEADER
));
464 PackageLength
+= PackageHeader
.Length
;
465 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
466 Status
= InvokeRegisteredFunction (
468 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
470 EFI_HII_PACKAGE_TYPE_GUID
,
473 ASSERT_EFI_ERROR (Status
);
474 CopyMem (Buffer
, GuidPackage
->GuidPkg
, PackageHeader
.Length
);
475 Buffer
= (UINT8
*)Buffer
+ PackageHeader
.Length
;
479 *ResultSize
+= PackageLength
;
484 This function deletes all GUID packages from a package list node.
485 This is a internal function.
487 @param Private Hii database private data.
488 @param Handle Handle of the package list which contains the to
489 be removed GUID packages.
490 @param PackageList Pointer to a package list that contains removing
493 @retval EFI_SUCCESS GUID Package(s) is deleted successfully.
494 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
499 IN HII_DATABASE_PRIVATE_DATA
*Private
,
500 IN EFI_HII_HANDLE Handle
,
501 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
504 LIST_ENTRY
*ListHead
;
505 HII_GUID_PACKAGE_INSTANCE
*Package
;
507 EFI_HII_PACKAGE_HEADER PackageHeader
;
509 ListHead
= &PackageList
->GuidPkgHdr
;
511 while (!IsListEmpty (ListHead
)) {
513 ListHead
->ForwardLink
,
514 HII_GUID_PACKAGE_INSTANCE
,
516 HII_GUID_PACKAGE_SIGNATURE
518 Status
= InvokeRegisteredFunction (
520 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
522 EFI_HII_PACKAGE_TYPE_GUID
,
525 if (EFI_ERROR (Status
)) {
529 RemoveEntryList (&Package
->GuidEntry
);
530 CopyMem (&PackageHeader
, Package
->GuidPkg
, sizeof (EFI_HII_PACKAGE_HEADER
));
531 PackageList
->PackageListHdr
.PackageLength
-= PackageHeader
.Length
;
532 FreePool (Package
->GuidPkg
);
540 Check the input question related to EFI variable
542 @param IfrQuestionHdr Point to Question header
543 @param EfiVarStoreList Point to EFI VarStore List
544 @param EfiVarStoreNumber The number of EFI VarStore
546 @retval Index The index of the found EFI varstore in EFI varstore list
547 EfiVarStoreNumber will return if no EFI varstore is found.
550 IsEfiVarStoreQuestion (
551 EFI_IFR_QUESTION_HEADER
*IfrQuestionHdr
,
552 EFI_IFR_VARSTORE_EFI
**EfiVarStoreList
,
553 UINTN EfiVarStoreNumber
558 for (Index
= 0; Index
< EfiVarStoreNumber
; Index
++) {
559 if (IfrQuestionHdr
->VarStoreId
== EfiVarStoreList
[Index
]->VarStoreId
) {
564 return EfiVarStoreNumber
;
568 Find the matched variable from the input variable storage.
570 @param[in] VariableStorage Point to the variable storage header.
571 @param[in] VarGuid A unique identifier for the variable.
572 @param[in] VarAttribute The attributes bitmask for the variable.
573 @param[in] VarName A Null-terminated ascii string that is the name of the variable.
575 @return Pointer to the matched variable header or NULL if not found.
579 IN VARIABLE_STORE_HEADER
*VariableStorage
,
580 IN EFI_GUID
*VarGuid
,
581 IN UINT32 VarAttribute
,
585 VARIABLE_HEADER
*VariableHeader
;
586 VARIABLE_HEADER
*VariableEnd
;
588 VariableEnd
= (VARIABLE_HEADER
*)((UINT8
*)VariableStorage
+ VariableStorage
->Size
);
589 VariableHeader
= (VARIABLE_HEADER
*)(VariableStorage
+ 1);
590 VariableHeader
= (VARIABLE_HEADER
*)HEADER_ALIGN (VariableHeader
);
591 while (VariableHeader
< VariableEnd
) {
592 if (CompareGuid (&VariableHeader
->VendorGuid
, VarGuid
) &&
593 (VariableHeader
->Attributes
== VarAttribute
) &&
594 (StrCmp (VarName
, (CHAR16
*)(VariableHeader
+ 1)) == 0))
596 return VariableHeader
;
599 VariableHeader
= (VARIABLE_HEADER
*)((UINT8
*)VariableHeader
+ sizeof (VARIABLE_HEADER
) + VariableHeader
->NameSize
+ VariableHeader
->DataSize
);
600 VariableHeader
= (VARIABLE_HEADER
*)HEADER_ALIGN (VariableHeader
);
607 Find question default value from PcdNvStoreDefaultValueBuffer
609 @param DefaultId Default store ID
610 @param EfiVarStore Point to EFI VarStore header
611 @param IfrQuestionHdr Point to Question header
612 @param ValueBuffer Point to Buffer includes the found default setting
613 @param Width Width of the default value
614 @param BitFieldQuestion Whether the Question is stored in Bit field.
616 @retval EFI_SUCCESS Question default value is found.
617 @retval EFI_NOT_FOUND Question default value is not found.
620 FindQuestionDefaultSetting (
622 IN EFI_IFR_VARSTORE_EFI
*EfiVarStore
,
623 IN EFI_IFR_QUESTION_HEADER
*IfrQuestionHdr
,
624 OUT VOID
*ValueBuffer
,
626 IN BOOLEAN BitFieldQuestion
629 VARIABLE_HEADER
*VariableHeader
;
630 VARIABLE_STORE_HEADER
*VariableStorage
;
632 VARSTORAGE_DEFAULT_DATA
*Entry
;
633 VARIABLE_STORE_HEADER
*NvStoreBuffer
;
645 PCD_DEFAULT_DATA
*DataHeader
;
646 PCD_DEFAULT_INFO
*DefaultInfo
;
647 PCD_DATA_DELTA
*DeltaData
;
649 if (gSkuId
== 0xFFFFFFFFFFFFFFFF) {
650 gSkuId
= LibPcdGetSku ();
654 // Find the DefaultId setting from the full DefaultSetting
656 VariableStorage
= NULL
;
657 Link
= gVarStorageList
.ForwardLink
;
658 while (Link
!= &gVarStorageList
) {
659 Entry
= BASE_CR (Link
, VARSTORAGE_DEFAULT_DATA
, Entry
);
660 if (Entry
->DefaultId
== DefaultId
) {
661 VariableStorage
= Entry
->VariableStorage
;
665 Link
= Link
->ForwardLink
;
668 if (Link
== &gVarStorageList
) {
669 DataBuffer
= (UINT8
*)PcdGetPtr (PcdNvStoreDefaultValueBuffer
);
670 gNvDefaultStoreSize
= ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER
*)DataBuffer
)->Length
;
672 // The first section data includes NV storage default setting.
674 DataHeader
= (PCD_DEFAULT_DATA
*)(DataBuffer
+ sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
));
675 NvStoreBuffer
= (VARIABLE_STORE_HEADER
*)((UINT8
*)DataHeader
+ sizeof (DataHeader
->DataSize
) + DataHeader
->HeaderSize
);
676 VariableStorage
= AllocatePool (NvStoreBuffer
->Size
);
677 ASSERT (VariableStorage
!= NULL
);
678 CopyMem (VariableStorage
, NvStoreBuffer
, NvStoreBuffer
->Size
);
681 // Find the matched SkuId and DefaultId in the first section
684 DefaultInfo
= &(DataHeader
->DefaultInfo
[0]);
685 BufferEnd
= (UINT8
*)DataHeader
+ sizeof (DataHeader
->DataSize
) + DataHeader
->HeaderSize
;
686 while ((UINT8
*)DefaultInfo
< BufferEnd
) {
687 if ((DefaultInfo
->DefaultId
== DefaultId
) && (DefaultInfo
->SkuId
== gSkuId
)) {
696 // Find the matched SkuId and DefaultId in the remaining section
698 Index
= sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
) + ((DataHeader
->DataSize
+ 7) & (~7));
699 DataHeader
= (PCD_DEFAULT_DATA
*)(DataBuffer
+ Index
);
700 while (!IsFound
&& Index
< gNvDefaultStoreSize
&& DataHeader
->DataSize
!= 0xFFFF) {
701 DefaultInfo
= &(DataHeader
->DefaultInfo
[0]);
702 BufferEnd
= (UINT8
*)DataHeader
+ sizeof (DataHeader
->DataSize
) + DataHeader
->HeaderSize
;
703 while ((UINT8
*)DefaultInfo
< BufferEnd
) {
704 if ((DefaultInfo
->DefaultId
== DefaultId
) && (DefaultInfo
->SkuId
== gSkuId
)) {
713 DeltaData
= (PCD_DATA_DELTA
*)BufferEnd
;
714 BufferEnd
= (UINT8
*)DataHeader
+ DataHeader
->DataSize
;
715 while ((UINT8
*)DeltaData
< BufferEnd
) {
716 *((UINT8
*)VariableStorage
+ DeltaData
->Offset
) = (UINT8
)DeltaData
->Value
;
723 Index
= (Index
+ DataHeader
->DataSize
+ 7) & (~7);
724 DataHeader
= (PCD_DEFAULT_DATA
*)(DataBuffer
+ Index
);
728 // Cache the found result in VarStorageList
731 FreePool (VariableStorage
);
732 VariableStorage
= NULL
;
735 Entry
= AllocatePool (sizeof (VARSTORAGE_DEFAULT_DATA
));
737 Entry
->DefaultId
= DefaultId
;
738 Entry
->VariableStorage
= VariableStorage
;
739 InsertTailList (&gVarStorageList
, &Entry
->Entry
);
740 } else if (VariableStorage
!= NULL
) {
741 FreePool (VariableStorage
);
742 VariableStorage
= NULL
;
747 // The matched variable storage is not found.
749 if (VariableStorage
== NULL
) {
750 return EFI_NOT_FOUND
;
754 // Find the question default value from the variable storage
756 VariableHeader
= FindVariableData (VariableStorage
, &EfiVarStore
->Guid
, EfiVarStore
->Attributes
, (CHAR16
*)EfiVarStore
->Name
);
757 if (VariableHeader
== NULL
) {
758 return EFI_NOT_FOUND
;
763 ByteOffset
= IfrQuestionHdr
->VarStoreInfo
.VarOffset
;
764 if (BitFieldQuestion
) {
765 BitOffset
= IfrQuestionHdr
->VarStoreInfo
.VarOffset
;
766 ByteOffset
= BitOffset
/ 8;
768 StartBit
= BitOffset
% 8;
769 EndBit
= StartBit
+ BitWidth
- 1;
770 Width
= EndBit
/ 8 + 1;
773 if (VariableHeader
->DataSize
< ByteOffset
+ Width
) {
774 return EFI_INVALID_PARAMETER
;
778 // Copy the question value
780 if (ValueBuffer
!= NULL
) {
781 if (BitFieldQuestion
) {
782 CopyMem (&BufferValue
, (UINT8
*)VariableHeader
+ sizeof (VARIABLE_HEADER
) + VariableHeader
->NameSize
+ ByteOffset
, Width
);
783 BitFieldVal
= BitFieldRead32 (BufferValue
, StartBit
, EndBit
);
784 CopyMem (ValueBuffer
, &BitFieldVal
, Width
);
786 CopyMem (ValueBuffer
, (UINT8
*)VariableHeader
+ sizeof (VARIABLE_HEADER
) + VariableHeader
->NameSize
+ IfrQuestionHdr
->VarStoreInfo
.VarOffset
, Width
);
794 Update IFR default setting in Form Package.
796 @param FormPackage Form Package to be updated
800 UpdateDefaultSettingInFormPackage (
801 HII_IFR_PACKAGE_INSTANCE
*FormPackage
806 EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
;
807 EFI_IFR_OP_HEADER
*IfrOpHdr
;
808 EFI_IFR_ONE_OF_OPTION
*IfrOneOfOption
;
809 UINT8 IfrQuestionType
;
811 EFI_IFR_QUESTION_HEADER
*IfrQuestionHdr
;
812 EFI_IFR_VARSTORE_EFI
**EfiVarStoreList
;
813 UINTN EfiVarStoreMaxNum
;
814 UINTN EfiVarStoreNumber
;
815 UINT16
*DefaultIdList
;
816 UINTN DefaultIdNumber
;
817 UINTN DefaultIdMaxNum
;
819 UINTN EfiVarStoreIndex
;
820 EFI_IFR_TYPE_VALUE IfrValue
;
821 EFI_IFR_TYPE_VALUE IfrManufactValue
;
822 BOOLEAN StandardDefaultIsSet
;
823 BOOLEAN ManufactDefaultIsSet
;
824 EFI_IFR_CHECKBOX
*IfrCheckBox
;
826 EFI_IFR_DEFAULT
*IfrDefault
;
828 EFI_IFR_QUESTION_HEADER VarStoreQuestionHeader
;
829 BOOLEAN QuestionReferBitField
;
832 // If no default setting, do nothing
834 if (gNvDefaultStoreSize
== 0) {
835 gNvDefaultStoreSize
= PcdGetSize (PcdNvStoreDefaultValueBuffer
);
838 if (gNvDefaultStoreSize
< sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
)) {
842 ZeroMem (&VarStoreQuestionHeader
, sizeof (VarStoreQuestionHeader
));
843 PackageLength
= FormPackage
->FormPkgHdr
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
);
847 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)FormPackage
->IfrData
;
848 IfrQuestionHdr
= NULL
;
850 EfiVarStoreMaxNum
= 0;
851 EfiVarStoreNumber
= 0;
854 EfiVarStoreList
= NULL
;
855 DefaultIdList
= NULL
;
856 StandardDefaultIsSet
= FALSE
;
857 ManufactDefaultIsSet
= FALSE
;
858 QuestionReferBitField
= FALSE
;
860 while (IfrOffset
< PackageLength
) {
861 switch (IfrOpHdr
->OpCode
) {
862 case EFI_IFR_VARSTORE_EFI_OP
:
863 if (EfiVarStoreNumber
>= EfiVarStoreMaxNum
) {
865 // Reallocate EFI VarStore Buffer
867 EfiVarStoreList
= ReallocatePool (EfiVarStoreMaxNum
* sizeof (UINTN
), (EfiVarStoreMaxNum
+ BASE_NUMBER
) * sizeof (UINTN
), EfiVarStoreList
);
868 if (EfiVarStoreList
== NULL
) {
872 EfiVarStoreMaxNum
= EfiVarStoreMaxNum
+ BASE_NUMBER
;
875 IfrEfiVarStore
= (EFI_IFR_VARSTORE_EFI
*)IfrOpHdr
;
877 // Convert VarStore Name from ASCII string to Unicode string.
879 EfiVarStoreList
[EfiVarStoreNumber
] = AllocatePool (IfrEfiVarStore
->Header
.Length
+ AsciiStrSize ((CHAR8
*)IfrEfiVarStore
->Name
));
880 if (EfiVarStoreList
[EfiVarStoreNumber
] == NULL
) {
884 CopyMem (EfiVarStoreList
[EfiVarStoreNumber
], IfrEfiVarStore
, IfrEfiVarStore
->Header
.Length
);
885 AsciiStrToUnicodeStrS ((CHAR8
*)IfrEfiVarStore
->Name
, (CHAR16
*)&(EfiVarStoreList
[EfiVarStoreNumber
]->Name
[0]), AsciiStrSize ((CHAR8
*)IfrEfiVarStore
->Name
) * sizeof (CHAR16
));
886 Status
= FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD
, EfiVarStoreList
[EfiVarStoreNumber
], &VarStoreQuestionHeader
, NULL
, IfrEfiVarStore
->Size
, FALSE
);
887 if (!EFI_ERROR (Status
)) {
890 FreePool (EfiVarStoreList
[EfiVarStoreNumber
]);
891 EfiVarStoreList
[EfiVarStoreNumber
] = NULL
;
895 case EFI_IFR_DEFAULTSTORE_OP
:
896 if (DefaultIdNumber
>= DefaultIdMaxNum
) {
898 // Reallocate DefaultIdNumber
900 DefaultIdList
= ReallocatePool (DefaultIdMaxNum
* sizeof (UINT16
), (DefaultIdMaxNum
+ BASE_NUMBER
) * sizeof (UINT16
), DefaultIdList
);
901 if (DefaultIdList
== NULL
) {
905 DefaultIdMaxNum
= DefaultIdMaxNum
+ BASE_NUMBER
;
908 DefaultIdList
[DefaultIdNumber
++] = ((EFI_IFR_DEFAULTSTORE
*)IfrOpHdr
)->DefaultId
;
910 case EFI_IFR_FORM_OP
:
911 case EFI_IFR_FORM_MAP_OP
:
913 // No EFI varstore is found and directly return.
915 if ((EfiVarStoreNumber
== 0) || (DefaultIdNumber
== 0)) {
920 case EFI_IFR_CHECKBOX_OP
:
921 IfrScope
= IfrOpHdr
->Scope
;
922 IfrQuestionType
= IfrOpHdr
->OpCode
;
923 IfrQuestionHdr
= (EFI_IFR_QUESTION_HEADER
*)(IfrOpHdr
+ 1);
924 IfrCheckBox
= (EFI_IFR_CHECKBOX
*)IfrOpHdr
;
925 EfiVarStoreIndex
= IsEfiVarStoreQuestion (IfrQuestionHdr
, EfiVarStoreList
, EfiVarStoreNumber
);
926 Width
= sizeof (BOOLEAN
);
927 if (EfiVarStoreIndex
< EfiVarStoreNumber
) {
928 for (Index
= 0; Index
< DefaultIdNumber
; Index
++) {
929 if (DefaultIdList
[Index
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
930 Status
= FindQuestionDefaultSetting (DefaultIdList
[Index
], EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrValue
, sizeof (BOOLEAN
), QuestionReferBitField
);
931 if (!EFI_ERROR (Status
)) {
933 IfrCheckBox
->Flags
= IfrCheckBox
->Flags
| EFI_IFR_CHECKBOX_DEFAULT
;
935 IfrCheckBox
->Flags
= IfrCheckBox
->Flags
& (~EFI_IFR_CHECKBOX_DEFAULT
);
938 } else if (DefaultIdList
[Index
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
939 Status
= FindQuestionDefaultSetting (DefaultIdList
[Index
], EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrValue
, sizeof (BOOLEAN
), QuestionReferBitField
);
940 if (!EFI_ERROR (Status
)) {
942 IfrCheckBox
->Flags
= IfrCheckBox
->Flags
| EFI_IFR_CHECKBOX_DEFAULT_MFG
;
944 IfrCheckBox
->Flags
= IfrCheckBox
->Flags
& (~EFI_IFR_CHECKBOX_DEFAULT_MFG
);
952 case EFI_IFR_NUMERIC_OP
:
953 IfrScope
= IfrOpHdr
->Scope
;
954 IfrQuestionType
= IfrOpHdr
->OpCode
;
955 IfrQuestionHdr
= (EFI_IFR_QUESTION_HEADER
*)(IfrOpHdr
+ 1);
956 if (QuestionReferBitField
) {
957 Width
= (UINTN
)(((EFI_IFR_ONE_OF
*)IfrOpHdr
)->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
);
959 Width
= (UINTN
)((UINT32
)1 << (((EFI_IFR_ONE_OF
*)IfrOpHdr
)->Flags
& EFI_IFR_NUMERIC_SIZE
));
963 case EFI_IFR_ONE_OF_OP
:
964 IfrScope
= IfrOpHdr
->Scope
;
965 IfrQuestionType
= IfrOpHdr
->OpCode
;
966 IfrQuestionHdr
= (EFI_IFR_QUESTION_HEADER
*)(IfrOpHdr
+ 1);
967 if (QuestionReferBitField
) {
968 Width
= (UINTN
)(((EFI_IFR_ONE_OF
*)IfrOpHdr
)->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
);
970 Width
= (UINTN
)((UINT32
)1 << (((EFI_IFR_ONE_OF
*)IfrOpHdr
)->Flags
& EFI_IFR_NUMERIC_SIZE
));
973 EfiVarStoreIndex
= IsEfiVarStoreQuestion (IfrQuestionHdr
, EfiVarStoreList
, EfiVarStoreNumber
);
974 StandardDefaultIsSet
= FALSE
;
975 ManufactDefaultIsSet
= FALSE
;
977 // Find Default and Manufacturing default for OneOf question
979 if (EfiVarStoreIndex
< EfiVarStoreNumber
) {
980 for (Index
= 0; Index
< DefaultIdNumber
; Index
++) {
981 if (DefaultIdList
[Index
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
982 Status
= FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD
, EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrValue
, Width
, QuestionReferBitField
);
983 if (!EFI_ERROR (Status
)) {
984 StandardDefaultIsSet
= TRUE
;
986 } else if (DefaultIdList
[Index
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
987 Status
= FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_MANUFACTURING
, EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrManufactValue
, Width
, QuestionReferBitField
);
988 if (!EFI_ERROR (Status
)) {
989 ManufactDefaultIsSet
= TRUE
;
996 case EFI_IFR_ORDERED_LIST_OP
:
997 IfrScope
= IfrOpHdr
->Scope
;
998 IfrQuestionType
= IfrOpHdr
->OpCode
;
999 IfrQuestionHdr
= (EFI_IFR_QUESTION_HEADER
*)(IfrOpHdr
+ 1);
1001 case EFI_IFR_ONE_OF_OPTION_OP
:
1002 if ((IfrQuestionHdr
!= NULL
) && (IfrScope
> 0)) {
1003 IfrOneOfOption
= (EFI_IFR_ONE_OF_OPTION
*)IfrOpHdr
;
1004 if (IfrQuestionType
== EFI_IFR_ONE_OF_OP
) {
1005 Width
= (UINTN
)((UINT32
)1 << (IfrOneOfOption
->Flags
& EFI_IFR_NUMERIC_SIZE
));
1006 if (StandardDefaultIsSet
) {
1007 if (CompareMem (&IfrOneOfOption
->Value
, &IfrValue
, Width
) == 0) {
1008 IfrOneOfOption
->Flags
|= EFI_IFR_OPTION_DEFAULT
;
1010 IfrOneOfOption
->Flags
&= ~EFI_IFR_OPTION_DEFAULT
;
1014 if (ManufactDefaultIsSet
) {
1015 if (CompareMem (&IfrOneOfOption
->Value
, &IfrManufactValue
, Width
) == 0) {
1016 IfrOneOfOption
->Flags
|= EFI_IFR_OPTION_DEFAULT_MFG
;
1018 IfrOneOfOption
->Flags
&= ~EFI_IFR_OPTION_DEFAULT_MFG
;
1025 case EFI_IFR_DEFAULT_OP
:
1026 if ((IfrQuestionHdr
!= NULL
) && (IfrScope
> 0)) {
1027 IfrDefault
= (EFI_IFR_DEFAULT
*)IfrOpHdr
;
1029 // Collect default value width
1031 if (!QuestionReferBitField
) {
1033 if ((IfrDefault
->Type
== EFI_IFR_TYPE_NUM_SIZE_8
) || (IfrDefault
->Type
== EFI_IFR_TYPE_BOOLEAN
)) {
1035 } else if (IfrDefault
->Type
== EFI_IFR_TYPE_NUM_SIZE_16
) {
1037 } else if (IfrDefault
->Type
== EFI_IFR_TYPE_NUM_SIZE_32
) {
1039 } else if (IfrDefault
->Type
== EFI_IFR_TYPE_NUM_SIZE_64
) {
1041 } else if (IfrDefault
->Type
== EFI_IFR_TYPE_BUFFER
) {
1042 Width
= IfrDefault
->Header
.Length
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
);
1047 // Update the default value
1050 EfiVarStoreIndex
= IsEfiVarStoreQuestion (IfrQuestionHdr
, EfiVarStoreList
, EfiVarStoreNumber
);
1051 if (EfiVarStoreIndex
< EfiVarStoreNumber
) {
1052 Status
= FindQuestionDefaultSetting (IfrDefault
->DefaultId
, EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrDefault
->Value
, Width
, QuestionReferBitField
);
1058 case EFI_IFR_END_OP
:
1059 if (IfrQuestionHdr
!= NULL
) {
1064 if (IfrScope
== 0) {
1065 IfrQuestionHdr
= NULL
;
1066 QuestionReferBitField
= FALSE
;
1071 case EFI_IFR_GUID_OP
:
1072 if (CompareGuid ((EFI_GUID
*)((UINT8
*)IfrOpHdr
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
1073 QuestionReferBitField
= TRUE
;
1081 IfrOffset
= IfrOffset
+ IfrOpHdr
->Length
;
1082 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*)IfrOpHdr
+ IfrOpHdr
->Length
);
1084 IfrScope
+= IfrOpHdr
->Scope
;
1089 if (EfiVarStoreList
!= NULL
) {
1090 for (Index
= 0; Index
< EfiVarStoreNumber
; Index
++) {
1091 FreePool (EfiVarStoreList
[Index
]);
1099 This function insert a Form package to a package list node.
1100 This is a internal function.
1102 @param PackageHdr Pointer to a buffer stored with Form package
1104 @param NotifyType The type of change concerning the database.
1105 @param PackageList Pointer to a package list which will be inserted
1107 @param Package Created Form package
1109 @retval EFI_SUCCESS Form Package is inserted successfully.
1110 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1112 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1117 IN VOID
*PackageHdr
,
1118 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
1119 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1120 OUT HII_IFR_PACKAGE_INSTANCE
**Package
1123 HII_IFR_PACKAGE_INSTANCE
*FormPackage
;
1124 EFI_HII_PACKAGE_HEADER PackageHeader
;
1126 if ((PackageHdr
== NULL
) || (PackageList
== NULL
)) {
1127 return EFI_INVALID_PARAMETER
;
1131 // Get the length of the package, including package header itself
1133 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
1136 // Create a Form package node
1138 FormPackage
= (HII_IFR_PACKAGE_INSTANCE
*)AllocateZeroPool (sizeof (HII_IFR_PACKAGE_INSTANCE
));
1139 if (FormPackage
== NULL
) {
1140 return EFI_OUT_OF_RESOURCES
;
1143 FormPackage
->IfrData
= (UINT8
*)AllocateZeroPool (PackageHeader
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
));
1144 if (FormPackage
->IfrData
== NULL
) {
1145 FreePool (FormPackage
);
1146 return EFI_OUT_OF_RESOURCES
;
1149 FormPackage
->Signature
= HII_IFR_PACKAGE_SIGNATURE
;
1151 // Copy Package Header
1153 CopyMem (&FormPackage
->FormPkgHdr
, &PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
1156 // Copy Ifr contents
1159 FormPackage
->IfrData
,
1160 (UINT8
*)PackageHdr
+ sizeof (EFI_HII_PACKAGE_HEADER
),
1161 PackageHeader
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
)
1164 InsertTailList (&PackageList
->FormPkgHdr
, &FormPackage
->IfrEntry
);
1165 *Package
= FormPackage
;
1168 // Update FormPackage with the default setting
1170 UpdateDefaultSettingInFormPackage (FormPackage
);
1172 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
1173 PackageList
->PackageListHdr
.PackageLength
+= FormPackage
->FormPkgHdr
.Length
;
1180 This function exports Form packages to a buffer.
1181 This is a internal function.
1183 @param Private Hii database private structure.
1184 @param Handle Identification of a package list.
1185 @param PackageList Pointer to a package list which will be exported.
1186 @param UsedSize The length of buffer be used.
1187 @param BufferSize Length of the Buffer.
1188 @param Buffer Allocated space for storing exported data.
1189 @param ResultSize The size of the already exported content of this
1192 @retval EFI_SUCCESS Form Packages are exported successfully.
1193 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1197 ExportFormPackages (
1198 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1199 IN EFI_HII_HANDLE Handle
,
1200 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1202 IN UINTN BufferSize
,
1203 IN OUT VOID
*Buffer
,
1204 IN OUT UINTN
*ResultSize
1207 HII_IFR_PACKAGE_INSTANCE
*FormPackage
;
1208 UINTN PackageLength
;
1212 if ((Private
== NULL
) || (PackageList
== NULL
) || (ResultSize
== NULL
)) {
1213 return EFI_INVALID_PARAMETER
;
1216 if ((BufferSize
> 0) && (Buffer
== NULL
)) {
1217 return EFI_INVALID_PARAMETER
;
1221 Status
= EFI_SUCCESS
;
1224 // Export Form packages.
1226 for (Link
= PackageList
->FormPkgHdr
.ForwardLink
; Link
!= &PackageList
->FormPkgHdr
; Link
= Link
->ForwardLink
) {
1227 FormPackage
= CR (Link
, HII_IFR_PACKAGE_INSTANCE
, IfrEntry
, HII_IFR_PACKAGE_SIGNATURE
);
1228 PackageLength
+= FormPackage
->FormPkgHdr
.Length
;
1229 if ((Buffer
!= NULL
) && (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
)) {
1231 // Invoke registered notification if exists
1233 Status
= InvokeRegisteredFunction (
1235 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
1236 (VOID
*)FormPackage
,
1237 EFI_HII_PACKAGE_FORMS
,
1240 ASSERT_EFI_ERROR (Status
);
1242 // Copy the Form package content.
1244 CopyMem (Buffer
, (VOID
*)(&FormPackage
->FormPkgHdr
), sizeof (EFI_HII_PACKAGE_HEADER
));
1245 Buffer
= (UINT8
*)Buffer
+ sizeof (EFI_HII_PACKAGE_HEADER
);
1248 (VOID
*)FormPackage
->IfrData
,
1249 FormPackage
->FormPkgHdr
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
)
1251 Buffer
= (UINT8
*)Buffer
+ FormPackage
->FormPkgHdr
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
);
1255 *ResultSize
+= PackageLength
;
1261 This function deletes all Form packages from a package list node.
1262 This is a internal function.
1264 @param Private Hii database private data.
1265 @param Handle Handle of the package list which contains the to
1266 be removed Form packages.
1267 @param PackageList Pointer to a package list that contains removing
1270 @retval EFI_SUCCESS Form Package(s) is deleted successfully.
1271 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1275 RemoveFormPackages (
1276 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1277 IN EFI_HII_HANDLE Handle
,
1278 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
1281 LIST_ENTRY
*ListHead
;
1282 HII_IFR_PACKAGE_INSTANCE
*Package
;
1285 ListHead
= &PackageList
->FormPkgHdr
;
1287 while (!IsListEmpty (ListHead
)) {
1289 ListHead
->ForwardLink
,
1290 HII_IFR_PACKAGE_INSTANCE
,
1292 HII_IFR_PACKAGE_SIGNATURE
1294 Status
= InvokeRegisteredFunction (
1296 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
1298 EFI_HII_PACKAGE_FORMS
,
1301 if (EFI_ERROR (Status
)) {
1305 RemoveEntryList (&Package
->IfrEntry
);
1306 PackageList
->PackageListHdr
.PackageLength
-= Package
->FormPkgHdr
.Length
;
1307 FreePool (Package
->IfrData
);
1310 // If Hii runtime support feature is enabled,
1311 // will export Hii info for runtime use after ReadyToBoot event triggered.
1312 // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
1313 // will need to export the content of HiiDatabase.
1314 // But if form packages removed, also need to export the ConfigResp string
1316 if (gExportAfterReadyToBoot
) {
1317 gExportConfigResp
= TRUE
;
1325 This function insert a String package to a package list node.
1326 This is a internal function.
1328 @param Private Hii database private structure.
1329 @param PackageHdr Pointer to a buffer stored with String package
1331 @param NotifyType The type of change concerning the database.
1332 @param PackageList Pointer to a package list which will be inserted
1334 @param Package Created String package
1336 @retval EFI_SUCCESS String Package is inserted successfully.
1337 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1339 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1340 @retval EFI_UNSUPPORTED A string package with the same language already
1341 exists in current package list.
1345 InsertStringPackage (
1346 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1347 IN VOID
*PackageHdr
,
1348 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
1349 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1350 OUT HII_STRING_PACKAGE_INSTANCE
**Package
1353 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1356 EFI_HII_PACKAGE_HEADER PackageHeader
;
1358 UINT32 LanguageSize
;
1361 if ((Private
== NULL
) || (PackageHdr
== NULL
) || (PackageList
== NULL
)) {
1362 return EFI_INVALID_PARAMETER
;
1365 if (Private
->Signature
!= HII_DATABASE_PRIVATE_DATA_SIGNATURE
) {
1366 return EFI_INVALID_PARAMETER
;
1369 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
1370 CopyMem (&HeaderSize
, (UINT8
*)PackageHdr
+ sizeof (EFI_HII_PACKAGE_HEADER
), sizeof (UINT32
));
1373 // It is illegal to have two string packages with same language within one packagelist
1374 // since the stringid will be duplicate if so. Check it to avoid this potential issue.
1376 LanguageSize
= HeaderSize
- sizeof (EFI_HII_STRING_PACKAGE_HDR
) + sizeof (CHAR8
);
1377 Language
= (CHAR8
*)AllocateZeroPool (LanguageSize
);
1378 if (Language
== NULL
) {
1379 return EFI_OUT_OF_RESOURCES
;
1382 AsciiStrCpyS (Language
, LanguageSize
/ sizeof (CHAR8
), (CHAR8
*)PackageHdr
+ HeaderSize
- LanguageSize
);
1383 for (Link
= PackageList
->StringPkgHdr
.ForwardLink
; Link
!= &PackageList
->StringPkgHdr
; Link
= Link
->ForwardLink
) {
1384 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1385 if (HiiCompareLanguage (Language
, StringPackage
->StringPkgHdr
->Language
)) {
1386 FreePool (Language
);
1387 return EFI_UNSUPPORTED
;
1391 FreePool (Language
);
1394 // Create a String package node
1396 StringPackage
= (HII_STRING_PACKAGE_INSTANCE
*)AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE
));
1397 if (StringPackage
== NULL
) {
1398 Status
= EFI_OUT_OF_RESOURCES
;
1402 StringPackage
->StringPkgHdr
= (EFI_HII_STRING_PACKAGE_HDR
*)AllocateZeroPool (HeaderSize
);
1403 if (StringPackage
->StringPkgHdr
== NULL
) {
1404 Status
= EFI_OUT_OF_RESOURCES
;
1408 StringPackage
->StringBlock
= (UINT8
*)AllocateZeroPool (PackageHeader
.Length
- HeaderSize
);
1409 if (StringPackage
->StringBlock
== NULL
) {
1410 Status
= EFI_OUT_OF_RESOURCES
;
1414 StringPackage
->Signature
= HII_STRING_PACKAGE_SIGNATURE
;
1415 StringPackage
->FontId
= 0;
1416 InitializeListHead (&StringPackage
->FontInfoList
);
1419 // Copy the String package header.
1421 CopyMem (StringPackage
->StringPkgHdr
, PackageHdr
, HeaderSize
);
1424 // Copy the String blocks
1427 StringPackage
->StringBlock
,
1428 (UINT8
*)PackageHdr
+ HeaderSize
,
1429 PackageHeader
.Length
- HeaderSize
1433 // Collect all font block info
1435 Status
= FindStringBlock (Private
, StringPackage
, (EFI_STRING_ID
)(-1), NULL
, NULL
, NULL
, &StringPackage
->MaxStringId
, NULL
);
1436 if (EFI_ERROR (Status
)) {
1441 // Insert to String package array
1443 InsertTailList (&PackageList
->StringPkgHdr
, &StringPackage
->StringEntry
);
1444 *Package
= StringPackage
;
1446 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
1447 PackageList
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
;
1454 if (StringPackage
!= NULL
) {
1455 if (StringPackage
->StringBlock
!= NULL
) {
1456 FreePool (StringPackage
->StringBlock
);
1459 if (StringPackage
->StringPkgHdr
!= NULL
) {
1460 FreePool (StringPackage
->StringPkgHdr
);
1463 FreePool (StringPackage
);
1470 Adjust all string packages in a single package list to have the same max string ID.
1472 @param PackageList Pointer to a package list which will be adjusted.
1474 @retval EFI_SUCCESS Adjust all string packages successfully.
1475 @retval others Can't adjust string packages.
1479 AdjustStringPackage (
1480 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
1484 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1485 UINT32 Skip2BlockSize
;
1486 UINT32 OldBlockSize
;
1489 EFI_STRING_ID MaxStringId
;
1493 for (Link
= PackageList
->StringPkgHdr
.ForwardLink
;
1494 Link
!= &PackageList
->StringPkgHdr
;
1495 Link
= Link
->ForwardLink
1498 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1499 if (MaxStringId
< StringPackage
->MaxStringId
) {
1500 MaxStringId
= StringPackage
->MaxStringId
;
1504 for (Link
= PackageList
->StringPkgHdr
.ForwardLink
;
1505 Link
!= &PackageList
->StringPkgHdr
;
1506 Link
= Link
->ForwardLink
1509 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1510 if (StringPackage
->MaxStringId
< MaxStringId
) {
1511 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1513 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs.
1515 SkipCount
= (UINT16
)(MaxStringId
- StringPackage
->MaxStringId
);
1516 Skip2BlockSize
= (UINT32
)sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
1518 StringBlock
= (UINT8
*)AllocateZeroPool (OldBlockSize
+ Skip2BlockSize
);
1519 if (StringBlock
== NULL
) {
1520 return EFI_OUT_OF_RESOURCES
;
1524 // Copy original string blocks, except the EFI_HII_SIBT_END.
1526 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1528 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks
1530 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1531 *BlockPtr
= EFI_HII_SIBT_SKIP2
;
1532 CopyMem (BlockPtr
+ 1, &SkipCount
, sizeof (UINT16
));
1533 BlockPtr
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
1536 // Append a EFI_HII_SIBT_END block to the end.
1538 *BlockPtr
= EFI_HII_SIBT_END
;
1539 FreePool (StringPackage
->StringBlock
);
1540 StringPackage
->StringBlock
= StringBlock
;
1541 StringPackage
->StringPkgHdr
->Header
.Length
+= Skip2BlockSize
;
1542 PackageList
->PackageListHdr
.PackageLength
+= Skip2BlockSize
;
1543 StringPackage
->MaxStringId
= MaxStringId
;
1551 This function exports String packages to a buffer.
1552 This is a internal function.
1554 @param Private Hii database private structure.
1555 @param Handle Identification of a package list.
1556 @param PackageList Pointer to a package list which will be exported.
1557 @param UsedSize The length of buffer be used.
1558 @param BufferSize Length of the Buffer.
1559 @param Buffer Allocated space for storing exported data.
1560 @param ResultSize The size of the already exported content of this
1563 @retval EFI_SUCCESS String Packages are exported successfully.
1564 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1568 ExportStringPackages (
1569 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1570 IN EFI_HII_HANDLE Handle
,
1571 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1573 IN UINTN BufferSize
,
1574 IN OUT VOID
*Buffer
,
1575 IN OUT UINTN
*ResultSize
1579 UINTN PackageLength
;
1581 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1583 if ((Private
== NULL
) || (PackageList
== NULL
) || (ResultSize
== NULL
)) {
1584 return EFI_INVALID_PARAMETER
;
1587 if ((BufferSize
> 0) && (Buffer
== NULL
)) {
1588 return EFI_INVALID_PARAMETER
;
1592 Status
= EFI_SUCCESS
;
1594 for (Link
= PackageList
->StringPkgHdr
.ForwardLink
; Link
!= &PackageList
->StringPkgHdr
; Link
= Link
->ForwardLink
) {
1595 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1596 PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
;
1597 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
1599 // Invoke registered notification function with EXPORT_PACK notify type
1601 Status
= InvokeRegisteredFunction (
1603 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
1604 (VOID
*)StringPackage
,
1605 EFI_HII_PACKAGE_STRINGS
,
1608 ASSERT_EFI_ERROR (Status
);
1610 // Copy String package header
1612 CopyMem (Buffer
, StringPackage
->StringPkgHdr
, StringPackage
->StringPkgHdr
->HdrSize
);
1613 Buffer
= (UINT8
*)Buffer
+ StringPackage
->StringPkgHdr
->HdrSize
;
1616 // Copy String blocks information
1620 StringPackage
->StringBlock
,
1621 StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
1623 Buffer
= (UINT8
*)Buffer
+ StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1627 *ResultSize
+= PackageLength
;
1632 This function deletes all String packages from a package list node.
1633 This is a internal function.
1635 @param Private Hii database private data.
1636 @param Handle Handle of the package list which contains the to
1637 be removed String packages.
1638 @param PackageList Pointer to a package list that contains removing
1641 @retval EFI_SUCCESS String Package(s) is deleted successfully.
1642 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1646 RemoveStringPackages (
1647 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1648 IN EFI_HII_HANDLE Handle
,
1649 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
1652 LIST_ENTRY
*ListHead
;
1653 HII_STRING_PACKAGE_INSTANCE
*Package
;
1654 HII_FONT_INFO
*FontInfo
;
1657 ListHead
= &PackageList
->StringPkgHdr
;
1659 while (!IsListEmpty (ListHead
)) {
1661 ListHead
->ForwardLink
,
1662 HII_STRING_PACKAGE_INSTANCE
,
1664 HII_STRING_PACKAGE_SIGNATURE
1666 Status
= InvokeRegisteredFunction (
1668 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
1670 EFI_HII_PACKAGE_STRINGS
,
1673 if (EFI_ERROR (Status
)) {
1677 RemoveEntryList (&Package
->StringEntry
);
1678 PackageList
->PackageListHdr
.PackageLength
-= Package
->StringPkgHdr
->Header
.Length
;
1679 FreePool (Package
->StringBlock
);
1680 FreePool (Package
->StringPkgHdr
);
1682 // Delete font information
1684 while (!IsListEmpty (&Package
->FontInfoList
)) {
1686 Package
->FontInfoList
.ForwardLink
,
1689 HII_FONT_INFO_SIGNATURE
1691 RemoveEntryList (&FontInfo
->Entry
);
1692 FreePool (FontInfo
);
1702 This function insert a Font package to a package list node.
1703 This is a internal function.
1705 @param Private Hii database private structure.
1706 @param PackageHdr Pointer to a buffer stored with Font package
1708 @param NotifyType The type of change concerning the database.
1709 @param PackageList Pointer to a package list which will be inserted
1711 @param Package Created Font package
1713 @retval EFI_SUCCESS Font Package is inserted successfully.
1714 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1716 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1717 @retval EFI_UNSUPPORTED A font package with same EFI_FONT_INFO already
1718 exists in current hii database.
1723 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1724 IN VOID
*PackageHdr
,
1725 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
1726 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1727 OUT HII_FONT_PACKAGE_INSTANCE
**Package
1730 HII_FONT_PACKAGE_INSTANCE
*FontPackage
;
1731 EFI_HII_FONT_PACKAGE_HDR
*FontPkgHdr
;
1734 EFI_HII_PACKAGE_HEADER PackageHeader
;
1735 EFI_FONT_INFO
*FontInfo
;
1736 UINT32 FontInfoSize
;
1737 HII_GLOBAL_FONT_INFO
*GlobalFont
;
1739 if ((Private
== NULL
) || (PackageHdr
== NULL
) || (PackageList
== NULL
)) {
1740 return EFI_INVALID_PARAMETER
;
1743 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
1744 CopyMem (&HeaderSize
, (UINT8
*)PackageHdr
+ sizeof (EFI_HII_PACKAGE_HEADER
), sizeof (UINT32
));
1751 // It is illegal to have two font packages with same EFI_FONT_INFO within hii
1752 // database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's
1753 // attributes and identify a font uniquely.
1755 FontPkgHdr
= (EFI_HII_FONT_PACKAGE_HDR
*)AllocateZeroPool (HeaderSize
);
1756 if (FontPkgHdr
== NULL
) {
1757 Status
= EFI_OUT_OF_RESOURCES
;
1761 CopyMem (FontPkgHdr
, PackageHdr
, HeaderSize
);
1763 FontInfoSize
= sizeof (EFI_FONT_INFO
) + HeaderSize
- sizeof (EFI_HII_FONT_PACKAGE_HDR
);
1764 FontInfo
= (EFI_FONT_INFO
*)AllocateZeroPool (FontInfoSize
);
1765 if (FontInfo
== NULL
) {
1766 Status
= EFI_OUT_OF_RESOURCES
;
1770 FontInfo
->FontStyle
= FontPkgHdr
->FontStyle
;
1771 FontInfo
->FontSize
= FontPkgHdr
->Cell
.Height
;
1772 StrCpyS (FontInfo
->FontName
, (FontInfoSize
- OFFSET_OF (EFI_FONT_INFO
, FontName
)) / sizeof (CHAR16
), FontPkgHdr
->FontFamily
);
1774 if (IsFontInfoExisted (Private
, FontInfo
, NULL
, NULL
, NULL
)) {
1775 Status
= EFI_UNSUPPORTED
;
1780 // Create a Font package node
1782 FontPackage
= (HII_FONT_PACKAGE_INSTANCE
*)AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE
));
1783 if (FontPackage
== NULL
) {
1784 Status
= EFI_OUT_OF_RESOURCES
;
1788 FontPackage
->Signature
= HII_FONT_PACKAGE_SIGNATURE
;
1789 FontPackage
->FontPkgHdr
= FontPkgHdr
;
1790 InitializeListHead (&FontPackage
->GlyphInfoList
);
1792 FontPackage
->GlyphBlock
= (UINT8
*)AllocateZeroPool (PackageHeader
.Length
- HeaderSize
);
1793 if (FontPackage
->GlyphBlock
== NULL
) {
1794 Status
= EFI_OUT_OF_RESOURCES
;
1798 CopyMem (FontPackage
->GlyphBlock
, (UINT8
*)PackageHdr
+ HeaderSize
, PackageHeader
.Length
- HeaderSize
);
1801 // Collect all default character cell information and backup in GlyphInfoList.
1803 Status
= FindGlyphBlock (FontPackage
, (CHAR16
)(-1), NULL
, NULL
, NULL
);
1804 if (EFI_ERROR (Status
)) {
1809 // This font package describes an unique EFI_FONT_INFO. Backup it in global
1812 GlobalFont
= (HII_GLOBAL_FONT_INFO
*)AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO
));
1813 if (GlobalFont
== NULL
) {
1814 Status
= EFI_OUT_OF_RESOURCES
;
1818 GlobalFont
->Signature
= HII_GLOBAL_FONT_INFO_SIGNATURE
;
1819 GlobalFont
->FontPackage
= FontPackage
;
1820 GlobalFont
->FontInfoSize
= FontInfoSize
;
1821 GlobalFont
->FontInfo
= FontInfo
;
1822 InsertTailList (&Private
->FontInfoList
, &GlobalFont
->Entry
);
1825 // Insert this font package to Font package array
1827 InsertTailList (&PackageList
->FontPkgHdr
, &FontPackage
->FontEntry
);
1828 *Package
= FontPackage
;
1830 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
1831 PackageList
->PackageListHdr
.PackageLength
+= FontPackage
->FontPkgHdr
->Header
.Length
;
1838 if (FontPkgHdr
!= NULL
) {
1839 FreePool (FontPkgHdr
);
1842 if (FontInfo
!= NULL
) {
1843 FreePool (FontInfo
);
1846 if (FontPackage
!= NULL
) {
1847 if (FontPackage
->GlyphBlock
!= NULL
) {
1848 FreePool (FontPackage
->GlyphBlock
);
1851 FreePool (FontPackage
);
1854 if (GlobalFont
!= NULL
) {
1855 FreePool (GlobalFont
);
1862 This function exports Font packages to a buffer.
1863 This is a internal function.
1865 @param Private Hii database private structure.
1866 @param Handle Identification of a package list.
1867 @param PackageList Pointer to a package list which will be exported.
1868 @param UsedSize The length of buffer be used.
1869 @param BufferSize Length of the Buffer.
1870 @param Buffer Allocated space for storing exported data.
1871 @param ResultSize The size of the already exported content of this
1874 @retval EFI_SUCCESS Font Packages are exported successfully.
1875 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1879 ExportFontPackages (
1880 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1881 IN EFI_HII_HANDLE Handle
,
1882 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1884 IN UINTN BufferSize
,
1885 IN OUT VOID
*Buffer
,
1886 IN OUT UINTN
*ResultSize
1890 UINTN PackageLength
;
1892 HII_FONT_PACKAGE_INSTANCE
*Package
;
1894 if ((Private
== NULL
) || (PackageList
== NULL
) || (ResultSize
== NULL
)) {
1895 return EFI_INVALID_PARAMETER
;
1898 if ((BufferSize
> 0) && (Buffer
== NULL
)) {
1899 return EFI_INVALID_PARAMETER
;
1903 Status
= EFI_SUCCESS
;
1905 for (Link
= PackageList
->FontPkgHdr
.ForwardLink
; Link
!= &PackageList
->FontPkgHdr
; Link
= Link
->ForwardLink
) {
1906 Package
= CR (Link
, HII_FONT_PACKAGE_INSTANCE
, FontEntry
, HII_FONT_PACKAGE_SIGNATURE
);
1907 PackageLength
+= Package
->FontPkgHdr
->Header
.Length
;
1908 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
1910 // Invoke registered notification function with EXPORT_PACK notify type
1912 Status
= InvokeRegisteredFunction (
1914 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
1916 EFI_HII_PACKAGE_FONTS
,
1919 ASSERT_EFI_ERROR (Status
);
1921 // Copy Font package header
1923 CopyMem (Buffer
, Package
->FontPkgHdr
, Package
->FontPkgHdr
->HdrSize
);
1924 Buffer
= (UINT8
*)Buffer
+ Package
->FontPkgHdr
->HdrSize
;
1927 // Copy Glyph blocks information
1931 Package
->GlyphBlock
,
1932 Package
->FontPkgHdr
->Header
.Length
- Package
->FontPkgHdr
->HdrSize
1934 Buffer
= (UINT8
*)Buffer
+ Package
->FontPkgHdr
->Header
.Length
- Package
->FontPkgHdr
->HdrSize
;
1938 *ResultSize
+= PackageLength
;
1943 This function deletes all Font packages from a package list node.
1944 This is a internal function.
1946 @param Private Hii database private data.
1947 @param Handle Handle of the package list which contains the to
1948 be removed Font packages.
1949 @param PackageList Pointer to a package list that contains removing
1952 @retval EFI_SUCCESS Font Package(s) is deleted successfully.
1953 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1957 RemoveFontPackages (
1958 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1959 IN EFI_HII_HANDLE Handle
,
1960 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
1963 LIST_ENTRY
*ListHead
;
1964 HII_FONT_PACKAGE_INSTANCE
*Package
;
1966 HII_GLYPH_INFO
*GlyphInfo
;
1968 HII_GLOBAL_FONT_INFO
*GlobalFont
;
1970 ListHead
= &PackageList
->FontPkgHdr
;
1972 while (!IsListEmpty (ListHead
)) {
1974 ListHead
->ForwardLink
,
1975 HII_FONT_PACKAGE_INSTANCE
,
1977 HII_FONT_PACKAGE_SIGNATURE
1979 Status
= InvokeRegisteredFunction (
1981 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
1983 EFI_HII_PACKAGE_FONTS
,
1986 if (EFI_ERROR (Status
)) {
1990 RemoveEntryList (&Package
->FontEntry
);
1991 PackageList
->PackageListHdr
.PackageLength
-= Package
->FontPkgHdr
->Header
.Length
;
1993 if (Package
->GlyphBlock
!= NULL
) {
1994 FreePool (Package
->GlyphBlock
);
1997 FreePool (Package
->FontPkgHdr
);
1999 // Delete default character cell information
2001 while (!IsListEmpty (&Package
->GlyphInfoList
)) {
2003 Package
->GlyphInfoList
.ForwardLink
,
2006 HII_GLYPH_INFO_SIGNATURE
2008 RemoveEntryList (&GlyphInfo
->Entry
);
2009 FreePool (GlyphInfo
);
2013 // Remove corresponding global font info
2015 for (Link
= Private
->FontInfoList
.ForwardLink
; Link
!= &Private
->FontInfoList
; Link
= Link
->ForwardLink
) {
2016 GlobalFont
= CR (Link
, HII_GLOBAL_FONT_INFO
, Entry
, HII_GLOBAL_FONT_INFO_SIGNATURE
);
2017 if (GlobalFont
->FontPackage
== Package
) {
2018 RemoveEntryList (&GlobalFont
->Entry
);
2019 FreePool (GlobalFont
->FontInfo
);
2020 FreePool (GlobalFont
);
2032 This function insert a Image package to a package list node.
2033 This is a internal function.
2035 @param PackageHdr Pointer to a buffer stored with Image package
2037 @param NotifyType The type of change concerning the database.
2038 @param PackageList Pointer to a package list which will be inserted
2040 @param Package Created Image package
2042 @retval EFI_SUCCESS Image Package is inserted successfully.
2043 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2045 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2049 InsertImagePackage (
2050 IN VOID
*PackageHdr
,
2051 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2052 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2053 OUT HII_IMAGE_PACKAGE_INSTANCE
**Package
2056 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
2060 EFI_HII_IMAGE_PALETTE_INFO_HEADER
*PaletteHdr
;
2061 EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
;
2062 UINT32 PaletteInfoOffset
;
2063 UINT32 ImageInfoOffset
;
2066 if ((PackageHdr
== NULL
) || (PackageList
== NULL
)) {
2067 return EFI_INVALID_PARAMETER
;
2071 // Less than one image package is allowed in one package list.
2073 if (PackageList
->ImagePkg
!= NULL
) {
2074 return EFI_INVALID_PARAMETER
;
2078 // Create a Image package node
2080 ImagePackage
= (HII_IMAGE_PACKAGE_INSTANCE
*)AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE
));
2081 if (ImagePackage
== NULL
) {
2082 return EFI_OUT_OF_RESOURCES
;
2086 // Copy the Image package header.
2088 CopyMem (&ImagePackage
->ImagePkgHdr
, PackageHdr
, sizeof (EFI_HII_IMAGE_PACKAGE_HDR
));
2090 PaletteInfoOffset
= ImagePackage
->ImagePkgHdr
.PaletteInfoOffset
;
2091 ImageInfoOffset
= ImagePackage
->ImagePkgHdr
.ImageInfoOffset
;
2094 // If PaletteInfoOffset is zero, there are no palettes in this image package.
2097 ImagePackage
->PaletteBlock
= NULL
;
2098 if (PaletteInfoOffset
!= 0) {
2099 PaletteHdr
= (EFI_HII_IMAGE_PALETTE_INFO_HEADER
*)((UINT8
*)PackageHdr
+ PaletteInfoOffset
);
2100 PaletteSize
= sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER
);
2101 PaletteInfo
= (EFI_HII_IMAGE_PALETTE_INFO
*)((UINT8
*)PaletteHdr
+ PaletteSize
);
2103 for (Index
= 0; Index
< PaletteHdr
->PaletteCount
; Index
++) {
2104 CopyMem (&CurrentSize
, PaletteInfo
, sizeof (UINT16
));
2105 CurrentSize
+= sizeof (UINT16
);
2106 PaletteSize
+= (UINT32
)CurrentSize
;
2107 PaletteInfo
= (EFI_HII_IMAGE_PALETTE_INFO
*)((UINT8
*)PaletteInfo
+ CurrentSize
);
2110 ImagePackage
->PaletteBlock
= (UINT8
*)AllocateZeroPool (PaletteSize
);
2111 if (ImagePackage
->PaletteBlock
== NULL
) {
2112 FreePool (ImagePackage
);
2113 return EFI_OUT_OF_RESOURCES
;
2117 ImagePackage
->PaletteBlock
,
2118 (UINT8
*)PackageHdr
+ PaletteInfoOffset
,
2124 // If ImageInfoOffset is zero, there are no images in this package.
2127 ImagePackage
->ImageBlock
= NULL
;
2128 if (ImageInfoOffset
!= 0) {
2129 ImageSize
= ImagePackage
->ImagePkgHdr
.Header
.Length
-
2130 sizeof (EFI_HII_IMAGE_PACKAGE_HDR
) - PaletteSize
;
2131 ImagePackage
->ImageBlock
= AllocateZeroPool (ImageSize
);
2132 if (ImagePackage
->ImageBlock
== NULL
) {
2133 FreePool (ImagePackage
->PaletteBlock
);
2134 FreePool (ImagePackage
);
2135 return EFI_OUT_OF_RESOURCES
;
2139 ImagePackage
->ImageBlock
,
2140 (UINT8
*)PackageHdr
+ ImageInfoOffset
,
2145 ImagePackage
->ImageBlockSize
= ImageSize
;
2146 ImagePackage
->PaletteInfoSize
= PaletteSize
;
2147 PackageList
->ImagePkg
= ImagePackage
;
2148 *Package
= ImagePackage
;
2150 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
2151 PackageList
->PackageListHdr
.PackageLength
+= ImagePackage
->ImagePkgHdr
.Header
.Length
;
2158 This function exports Image packages to a buffer.
2159 This is a internal function.
2161 @param Private Hii database private structure.
2162 @param Handle Identification of a package list.
2163 @param PackageList Pointer to a package list which will be exported.
2164 @param UsedSize The length of buffer be used.
2165 @param BufferSize Length of the Buffer.
2166 @param Buffer Allocated space for storing exported data.
2167 @param ResultSize The size of the already exported content of this
2170 @retval EFI_SUCCESS Image Packages are exported successfully.
2171 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2175 ExportImagePackages (
2176 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2177 IN EFI_HII_HANDLE Handle
,
2178 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2180 IN UINTN BufferSize
,
2181 IN OUT VOID
*Buffer
,
2182 IN OUT UINTN
*ResultSize
2185 UINTN PackageLength
;
2187 HII_IMAGE_PACKAGE_INSTANCE
*Package
;
2189 if ((Private
== NULL
) || (PackageList
== NULL
) || (ResultSize
== NULL
)) {
2190 return EFI_INVALID_PARAMETER
;
2193 if ((BufferSize
> 0) && (Buffer
== NULL
)) {
2194 return EFI_INVALID_PARAMETER
;
2197 Package
= PackageList
->ImagePkg
;
2199 if (Package
== NULL
) {
2203 PackageLength
= Package
->ImagePkgHdr
.Header
.Length
;
2205 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
2207 // Invoke registered notification function with EXPORT_PACK notify type
2209 Status
= InvokeRegisteredFunction (
2211 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
2213 EFI_HII_PACKAGE_IMAGES
,
2216 ASSERT_EFI_ERROR (Status
);
2218 Package
->ImagePkgHdr
.Header
.Length
==
2219 sizeof (EFI_HII_IMAGE_PACKAGE_HDR
) + Package
->ImageBlockSize
+ Package
->PaletteInfoSize
2222 // Copy Image package header,
2223 // then justify the offset for image info and palette info in the header.
2225 CopyMem (Buffer
, &Package
->ImagePkgHdr
, sizeof (EFI_HII_IMAGE_PACKAGE_HDR
));
2226 Buffer
= (UINT8
*)Buffer
+ sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
2229 // Copy Image blocks information
2231 if (Package
->ImageBlockSize
!= 0) {
2232 CopyMem (Buffer
, Package
->ImageBlock
, Package
->ImageBlockSize
);
2233 Buffer
= (UINT8
*)Buffer
+ Package
->ImageBlockSize
;
2237 // Copy Palette information
2239 if (Package
->PaletteInfoSize
!= 0) {
2240 CopyMem (Buffer
, Package
->PaletteBlock
, Package
->PaletteInfoSize
);
2241 Buffer
= (UINT8
*)Buffer
+ Package
->PaletteInfoSize
;
2245 *ResultSize
+= PackageLength
;
2250 This function deletes Image package from a package list node.
2251 This is a internal function.
2253 @param Private Hii database private data.
2254 @param Handle Handle of the package list which contains the to
2255 be removed Image packages.
2256 @param PackageList Package List which contains the to be removed
2259 @retval EFI_SUCCESS Image Package(s) is deleted successfully.
2260 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2264 RemoveImagePackages (
2265 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2266 IN EFI_HII_HANDLE Handle
,
2267 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2270 HII_IMAGE_PACKAGE_INSTANCE
*Package
;
2273 Package
= PackageList
->ImagePkg
;
2276 // Image package does not exist, return directly.
2278 if (Package
== NULL
) {
2282 Status
= InvokeRegisteredFunction (
2284 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2286 EFI_HII_PACKAGE_IMAGES
,
2289 if (EFI_ERROR (Status
)) {
2293 PackageList
->PackageListHdr
.PackageLength
-= Package
->ImagePkgHdr
.Header
.Length
;
2295 FreePool (Package
->ImageBlock
);
2296 if (Package
->PaletteBlock
!= NULL
) {
2297 FreePool (Package
->PaletteBlock
);
2302 PackageList
->ImagePkg
= NULL
;
2308 This function insert a Simple Font package to a package list node.
2309 This is a internal function.
2311 @param PackageHdr Pointer to a buffer stored with Simple Font
2312 package information.
2313 @param NotifyType The type of change concerning the database.
2314 @param PackageList Pointer to a package list which will be inserted
2316 @param Package Created Simple Font package
2318 @retval EFI_SUCCESS Simple Font Package is inserted successfully.
2319 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2320 Simple Font package.
2321 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2325 InsertSimpleFontPackage (
2326 IN VOID
*PackageHdr
,
2327 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2328 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2329 OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE
**Package
2332 HII_SIMPLE_FONT_PACKAGE_INSTANCE
*SimpleFontPackage
;
2334 EFI_HII_PACKAGE_HEADER Header
;
2336 if ((PackageHdr
== NULL
) || (PackageList
== NULL
)) {
2337 return EFI_INVALID_PARAMETER
;
2341 // Create a Simple Font package node
2343 SimpleFontPackage
= AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE
));
2344 if (SimpleFontPackage
== NULL
) {
2345 Status
= EFI_OUT_OF_RESOURCES
;
2349 SimpleFontPackage
->Signature
= HII_S_FONT_PACKAGE_SIGNATURE
;
2352 // Copy the Simple Font package.
2354 CopyMem (&Header
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
2356 SimpleFontPackage
->SimpleFontPkgHdr
= AllocateZeroPool (Header
.Length
);
2357 if (SimpleFontPackage
->SimpleFontPkgHdr
== NULL
) {
2358 Status
= EFI_OUT_OF_RESOURCES
;
2362 CopyMem (SimpleFontPackage
->SimpleFontPkgHdr
, PackageHdr
, Header
.Length
);
2365 // Insert to Simple Font package array
2367 InsertTailList (&PackageList
->SimpleFontPkgHdr
, &SimpleFontPackage
->SimpleFontEntry
);
2368 *Package
= SimpleFontPackage
;
2370 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
2371 PackageList
->PackageListHdr
.PackageLength
+= Header
.Length
;
2378 if (SimpleFontPackage
!= NULL
) {
2379 if (SimpleFontPackage
->SimpleFontPkgHdr
!= NULL
) {
2380 FreePool (SimpleFontPackage
->SimpleFontPkgHdr
);
2383 FreePool (SimpleFontPackage
);
2390 This function exports SimpleFont packages to a buffer.
2391 This is a internal function.
2393 @param Private Hii database private structure.
2394 @param Handle Identification of a package list.
2395 @param PackageList Pointer to a package list which will be exported.
2396 @param UsedSize The length of buffer be used.
2397 @param BufferSize Length of the Buffer.
2398 @param Buffer Allocated space for storing exported data.
2399 @param ResultSize The size of the already exported content of this
2402 @retval EFI_SUCCESS SimpleFont Packages are exported successfully.
2403 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2407 ExportSimpleFontPackages (
2408 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2409 IN EFI_HII_HANDLE Handle
,
2410 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2412 IN UINTN BufferSize
,
2413 IN OUT VOID
*Buffer
,
2414 IN OUT UINTN
*ResultSize
2418 UINTN PackageLength
;
2420 HII_SIMPLE_FONT_PACKAGE_INSTANCE
*Package
;
2422 if ((Private
== NULL
) || (PackageList
== NULL
) || (ResultSize
== NULL
)) {
2423 return EFI_INVALID_PARAMETER
;
2426 if ((BufferSize
> 0) && (Buffer
== NULL
)) {
2427 return EFI_INVALID_PARAMETER
;
2431 Status
= EFI_SUCCESS
;
2433 for (Link
= PackageList
->SimpleFontPkgHdr
.ForwardLink
; Link
!= &PackageList
->SimpleFontPkgHdr
; Link
= Link
->ForwardLink
) {
2434 Package
= CR (Link
, HII_SIMPLE_FONT_PACKAGE_INSTANCE
, SimpleFontEntry
, HII_S_FONT_PACKAGE_SIGNATURE
);
2435 PackageLength
+= Package
->SimpleFontPkgHdr
->Header
.Length
;
2436 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
2438 // Invoke registered notification function with EXPORT_PACK notify type
2440 Status
= InvokeRegisteredFunction (
2442 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
2444 EFI_HII_PACKAGE_SIMPLE_FONTS
,
2447 ASSERT_EFI_ERROR (Status
);
2450 // Copy SimpleFont package
2452 CopyMem (Buffer
, Package
->SimpleFontPkgHdr
, Package
->SimpleFontPkgHdr
->Header
.Length
);
2453 Buffer
= (UINT8
*)Buffer
+ Package
->SimpleFontPkgHdr
->Header
.Length
;
2457 *ResultSize
+= PackageLength
;
2462 This function deletes all Simple Font packages from a package list node.
2463 This is a internal function.
2465 @param Private Hii database private data.
2466 @param Handle Handle of the package list which contains the to
2467 be removed Simple Font packages.
2468 @param PackageList Pointer to a package list that contains removing
2471 @retval EFI_SUCCESS Simple Font Package(s) is deleted successfully.
2472 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2476 RemoveSimpleFontPackages (
2477 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2478 IN EFI_HII_HANDLE Handle
,
2479 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2482 LIST_ENTRY
*ListHead
;
2483 HII_SIMPLE_FONT_PACKAGE_INSTANCE
*Package
;
2486 ListHead
= &PackageList
->SimpleFontPkgHdr
;
2488 while (!IsListEmpty (ListHead
)) {
2490 ListHead
->ForwardLink
,
2491 HII_SIMPLE_FONT_PACKAGE_INSTANCE
,
2493 HII_S_FONT_PACKAGE_SIGNATURE
2495 Status
= InvokeRegisteredFunction (
2497 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2499 EFI_HII_PACKAGE_SIMPLE_FONTS
,
2502 if (EFI_ERROR (Status
)) {
2506 RemoveEntryList (&Package
->SimpleFontEntry
);
2507 PackageList
->PackageListHdr
.PackageLength
-= Package
->SimpleFontPkgHdr
->Header
.Length
;
2508 FreePool (Package
->SimpleFontPkgHdr
);
2516 This function insert a Device path package to a package list node.
2517 This is a internal function.
2519 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
2521 @param NotifyType The type of change concerning the database.
2522 @param PackageList Pointer to a package list which will be inserted
2525 @retval EFI_SUCCESS Device path Package is inserted successfully.
2526 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2527 Device path package.
2528 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
2532 InsertDevicePathPackage (
2533 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
2534 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2535 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2538 UINT32 PackageLength
;
2539 EFI_HII_PACKAGE_HEADER Header
;
2541 if ((DevicePath
== NULL
) || (PackageList
== NULL
)) {
2542 return EFI_INVALID_PARAMETER
;
2546 // Less than one device path package is allowed in one package list.
2548 if (PackageList
->DevicePathPkg
!= NULL
) {
2549 return EFI_INVALID_PARAMETER
;
2552 PackageLength
= (UINT32
)GetDevicePathSize (DevicePath
) + sizeof (EFI_HII_PACKAGE_HEADER
);
2553 PackageList
->DevicePathPkg
= (UINT8
*)AllocateZeroPool (PackageLength
);
2554 if (PackageList
->DevicePathPkg
== NULL
) {
2555 return EFI_OUT_OF_RESOURCES
;
2558 Header
.Length
= PackageLength
;
2559 Header
.Type
= EFI_HII_PACKAGE_DEVICE_PATH
;
2560 CopyMem (PackageList
->DevicePathPkg
, &Header
, sizeof (EFI_HII_PACKAGE_HEADER
));
2562 PackageList
->DevicePathPkg
+ sizeof (EFI_HII_PACKAGE_HEADER
),
2564 PackageLength
- sizeof (EFI_HII_PACKAGE_HEADER
)
2568 // Since Device Path package is created by NewPackageList, either NEW_PACK
2569 // or ADD_PACK should increase the length of package list.
2571 PackageList
->PackageListHdr
.PackageLength
+= PackageLength
;
2576 This function exports device path package to a buffer.
2577 This is a internal function.
2579 @param Private Hii database private structure.
2580 @param Handle Identification of a package list.
2581 @param PackageList Pointer to a package list which will be exported.
2582 @param UsedSize The length of buffer be used.
2583 @param BufferSize Length of the Buffer.
2584 @param Buffer Allocated space for storing exported data.
2585 @param ResultSize The size of the already exported content of this
2588 @retval EFI_SUCCESS Device path Package is exported successfully.
2589 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2593 ExportDevicePathPackage (
2594 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2595 IN EFI_HII_HANDLE Handle
,
2596 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2598 IN UINTN BufferSize
,
2599 IN OUT VOID
*Buffer
,
2600 IN OUT UINTN
*ResultSize
2605 EFI_HII_PACKAGE_HEADER Header
;
2607 if ((Private
== NULL
) || (PackageList
== NULL
) || (ResultSize
== NULL
)) {
2608 return EFI_INVALID_PARAMETER
;
2611 if ((BufferSize
> 0) && (Buffer
== NULL
)) {
2612 return EFI_INVALID_PARAMETER
;
2615 Package
= PackageList
->DevicePathPkg
;
2617 if (Package
== NULL
) {
2621 CopyMem (&Header
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2623 if (Header
.Length
+ *ResultSize
+ UsedSize
<= BufferSize
) {
2625 // Invoke registered notification function with EXPORT_PACK notify type
2627 Status
= InvokeRegisteredFunction (
2629 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
2631 EFI_HII_PACKAGE_DEVICE_PATH
,
2634 ASSERT_EFI_ERROR (Status
);
2637 // Copy Device path package
2639 CopyMem (Buffer
, Package
, Header
.Length
);
2642 *ResultSize
+= Header
.Length
;
2647 This function deletes Device Path package from a package list node.
2648 This is a internal function.
2650 @param Private Hii database private data.
2651 @param Handle Handle of the package list.
2652 @param PackageList Package List which contains the to be removed
2653 Device Path package.
2655 @retval EFI_SUCCESS Device Path Package is deleted successfully.
2656 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2660 RemoveDevicePathPackage (
2661 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2662 IN EFI_HII_HANDLE Handle
,
2663 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2668 EFI_HII_PACKAGE_HEADER Header
;
2670 Package
= PackageList
->DevicePathPkg
;
2673 // No device path, return directly.
2675 if (Package
== NULL
) {
2679 Status
= InvokeRegisteredFunction (
2681 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2683 EFI_HII_PACKAGE_DEVICE_PATH
,
2686 if (EFI_ERROR (Status
)) {
2690 CopyMem (&Header
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2691 PackageList
->PackageListHdr
.PackageLength
-= Header
.Length
;
2695 PackageList
->DevicePathPkg
= NULL
;
2701 This function will insert a device path package to package list firstly then
2702 invoke notification functions if any.
2703 This is a internal function.
2705 @param Private Hii database private structure.
2706 @param NotifyType The type of change concerning the database.
2707 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
2709 @param DatabaseRecord Pointer to a database record contains a package
2710 list which will be inserted to.
2712 @retval EFI_SUCCESS Device path Package is inserted successfully.
2713 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2714 Device path package.
2715 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
2719 AddDevicePathPackage (
2720 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2721 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2722 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
2723 IN OUT HII_DATABASE_RECORD
*DatabaseRecord
2728 if (DevicePath
== NULL
) {
2732 ASSERT (Private
!= NULL
);
2733 ASSERT (DatabaseRecord
!= NULL
);
2736 // Create a device path package and insert to packagelist
2738 Status
= InsertDevicePathPackage (
2741 DatabaseRecord
->PackageList
2743 if (EFI_ERROR (Status
)) {
2747 return InvokeRegisteredFunction (
2750 (VOID
*)DatabaseRecord
->PackageList
->DevicePathPkg
,
2751 EFI_HII_PACKAGE_DEVICE_PATH
,
2752 DatabaseRecord
->Handle
2757 This function insert a Keyboard Layout package to a package list node.
2758 This is a internal function.
2760 @param PackageHdr Pointer to a buffer stored with Keyboard Layout
2761 package information.
2762 @param NotifyType The type of change concerning the database.
2763 @param PackageList Pointer to a package list which will be inserted
2765 @param Package Created Keyboard Layout package
2767 @retval EFI_SUCCESS Keyboard Layout Package is inserted successfully.
2768 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2769 Keyboard Layout package.
2770 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2774 InsertKeyboardLayoutPackage (
2775 IN VOID
*PackageHdr
,
2776 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2777 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2778 OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
**Package
2781 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*KeyboardLayoutPackage
;
2782 EFI_HII_PACKAGE_HEADER PackageHeader
;
2785 if ((PackageHdr
== NULL
) || (PackageList
== NULL
)) {
2786 return EFI_INVALID_PARAMETER
;
2789 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
2792 // Create a Keyboard Layout package node
2794 KeyboardLayoutPackage
= AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
));
2795 if (KeyboardLayoutPackage
== NULL
) {
2796 Status
= EFI_OUT_OF_RESOURCES
;
2800 KeyboardLayoutPackage
->Signature
= HII_KB_LAYOUT_PACKAGE_SIGNATURE
;
2802 KeyboardLayoutPackage
->KeyboardPkg
= (UINT8
*)AllocateZeroPool (PackageHeader
.Length
);
2803 if (KeyboardLayoutPackage
->KeyboardPkg
== NULL
) {
2804 Status
= EFI_OUT_OF_RESOURCES
;
2808 CopyMem (KeyboardLayoutPackage
->KeyboardPkg
, PackageHdr
, PackageHeader
.Length
);
2809 InsertTailList (&PackageList
->KeyboardLayoutHdr
, &KeyboardLayoutPackage
->KeyboardEntry
);
2811 *Package
= KeyboardLayoutPackage
;
2813 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
2814 PackageList
->PackageListHdr
.PackageLength
+= PackageHeader
.Length
;
2821 if (KeyboardLayoutPackage
!= NULL
) {
2822 if (KeyboardLayoutPackage
->KeyboardPkg
!= NULL
) {
2823 FreePool (KeyboardLayoutPackage
->KeyboardPkg
);
2826 FreePool (KeyboardLayoutPackage
);
2833 This function exports Keyboard Layout packages to a buffer.
2834 This is a internal function.
2836 @param Private Hii database private structure.
2837 @param Handle Identification of a package list.
2838 @param PackageList Pointer to a package list which will be exported.
2839 @param UsedSize The length of buffer be used.
2840 @param BufferSize Length of the Buffer.
2841 @param Buffer Allocated space for storing exported data.
2842 @param ResultSize The size of the already exported content of this
2845 @retval EFI_SUCCESS Keyboard Layout Packages are exported
2847 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2851 ExportKeyboardLayoutPackages (
2852 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2853 IN EFI_HII_HANDLE Handle
,
2854 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2856 IN UINTN BufferSize
,
2857 IN OUT VOID
*Buffer
,
2858 IN OUT UINTN
*ResultSize
2862 UINTN PackageLength
;
2864 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*Package
;
2865 EFI_HII_PACKAGE_HEADER PackageHeader
;
2867 if ((Private
== NULL
) || (PackageList
== NULL
) || (ResultSize
== NULL
)) {
2868 return EFI_INVALID_PARAMETER
;
2871 if ((BufferSize
> 0) && (Buffer
== NULL
)) {
2872 return EFI_INVALID_PARAMETER
;
2876 Status
= EFI_SUCCESS
;
2878 for (Link
= PackageList
->KeyboardLayoutHdr
.ForwardLink
; Link
!= &PackageList
->KeyboardLayoutHdr
; Link
= Link
->ForwardLink
) {
2879 Package
= CR (Link
, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
, KeyboardEntry
, HII_KB_LAYOUT_PACKAGE_SIGNATURE
);
2880 CopyMem (&PackageHeader
, Package
->KeyboardPkg
, sizeof (EFI_HII_PACKAGE_HEADER
));
2881 PackageLength
+= PackageHeader
.Length
;
2882 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
2884 // Invoke registered notification function with EXPORT_PACK notify type
2886 Status
= InvokeRegisteredFunction (
2888 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
2889 (EFI_HII_PACKAGE_HEADER
*)Package
,
2890 EFI_HII_PACKAGE_KEYBOARD_LAYOUT
,
2893 ASSERT_EFI_ERROR (Status
);
2896 // Copy Keyboard Layout package
2898 CopyMem (Buffer
, Package
->KeyboardPkg
, PackageHeader
.Length
);
2899 Buffer
= (UINT8
*)Buffer
+ PackageHeader
.Length
;
2903 *ResultSize
+= PackageLength
;
2908 This function deletes all Keyboard Layout packages from a package list node.
2909 This is a internal function.
2911 @param Private Hii database private data.
2912 @param Handle Handle of the package list which contains the to
2913 be removed Keyboard Layout packages.
2914 @param PackageList Pointer to a package list that contains removing
2917 @retval EFI_SUCCESS Keyboard Layout Package(s) is deleted
2919 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2923 RemoveKeyboardLayoutPackages (
2924 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2925 IN EFI_HII_HANDLE Handle
,
2926 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2929 LIST_ENTRY
*ListHead
;
2930 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*Package
;
2931 EFI_HII_PACKAGE_HEADER PackageHeader
;
2934 ListHead
= &PackageList
->KeyboardLayoutHdr
;
2936 while (!IsListEmpty (ListHead
)) {
2938 ListHead
->ForwardLink
,
2939 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
,
2941 HII_KB_LAYOUT_PACKAGE_SIGNATURE
2943 Status
= InvokeRegisteredFunction (
2945 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2947 EFI_HII_PACKAGE_KEYBOARD_LAYOUT
,
2950 if (EFI_ERROR (Status
)) {
2954 RemoveEntryList (&Package
->KeyboardEntry
);
2955 CopyMem (&PackageHeader
, Package
->KeyboardPkg
, sizeof (EFI_HII_PACKAGE_HEADER
));
2956 PackageList
->PackageListHdr
.PackageLength
-= PackageHeader
.Length
;
2957 FreePool (Package
->KeyboardPkg
);
2965 This function will insert a package list to hii database firstly then
2966 invoke notification functions if any. It is the worker function of
2967 HiiNewPackageList and HiiUpdatePackageList.
2969 This is a internal function.
2971 @param Private Hii database private structure.
2972 @param NotifyType The type of change concerning the database.
2973 @param PackageList Pointer to a package list.
2974 @param DatabaseRecord Pointer to a database record contains a package
2975 list instance which will be inserted to.
2977 @retval EFI_SUCCESS All incoming packages are inserted to current
2979 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2980 Device path package.
2981 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2986 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2987 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2988 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*PackageList
,
2989 IN OUT HII_DATABASE_RECORD
*DatabaseRecord
2993 HII_GUID_PACKAGE_INSTANCE
*GuidPackage
;
2994 HII_IFR_PACKAGE_INSTANCE
*FormPackage
;
2995 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*KeyboardLayoutPackage
;
2996 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
2997 HII_FONT_PACKAGE_INSTANCE
*FontPackage
;
2998 HII_SIMPLE_FONT_PACKAGE_INSTANCE
*SimpleFontPackage
;
2999 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
3000 EFI_HII_PACKAGE_HEADER
*PackageHdrPtr
;
3001 EFI_HII_PACKAGE_HEADER PackageHeader
;
3002 UINT32 OldPackageListLen
;
3003 BOOLEAN StringPkgIsAdd
;
3006 // Initialize Variables
3008 StringPkgIsAdd
= FALSE
;
3010 StringPackage
= NULL
;
3013 ImagePackage
= NULL
;
3014 SimpleFontPackage
= NULL
;
3015 KeyboardLayoutPackage
= NULL
;
3018 // Process the package list header
3020 OldPackageListLen
= DatabaseRecord
->PackageList
->PackageListHdr
.PackageLength
;
3022 &DatabaseRecord
->PackageList
->PackageListHdr
,
3023 (VOID
*)PackageList
,
3024 sizeof (EFI_HII_PACKAGE_LIST_HEADER
)
3026 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
3027 DatabaseRecord
->PackageList
->PackageListHdr
.PackageLength
= OldPackageListLen
;
3030 PackageHdrPtr
= (EFI_HII_PACKAGE_HEADER
*)((UINT8
*)PackageList
+ sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
3031 CopyMem (&PackageHeader
, PackageHdrPtr
, sizeof (EFI_HII_PACKAGE_HEADER
));
3033 Status
= EFI_SUCCESS
;
3035 while (PackageHeader
.Type
!= EFI_HII_PACKAGE_END
) {
3036 switch (PackageHeader
.Type
) {
3037 case EFI_HII_PACKAGE_TYPE_GUID
:
3038 Status
= InsertGuidPackage (
3041 DatabaseRecord
->PackageList
,
3044 if (EFI_ERROR (Status
)) {
3048 Status
= InvokeRegisteredFunction (
3051 (VOID
*)GuidPackage
,
3052 (UINT8
)(PackageHeader
.Type
),
3053 DatabaseRecord
->Handle
3056 case EFI_HII_PACKAGE_FORMS
:
3057 Status
= InsertFormPackage (
3060 DatabaseRecord
->PackageList
,
3063 if (EFI_ERROR (Status
)) {
3067 Status
= InvokeRegisteredFunction (
3070 (VOID
*)FormPackage
,
3071 (UINT8
)(PackageHeader
.Type
),
3072 DatabaseRecord
->Handle
3075 // If Hii runtime support feature is enabled,
3076 // will export Hii info for runtime use after ReadyToBoot event triggered.
3077 // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
3078 // will need to export the content of HiiDatabase.
3079 // But if form packages added/updated, also need to export the ConfigResp string.
3081 if (gExportAfterReadyToBoot
) {
3082 gExportConfigResp
= TRUE
;
3086 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
3087 Status
= InsertKeyboardLayoutPackage (
3090 DatabaseRecord
->PackageList
,
3091 &KeyboardLayoutPackage
3093 if (EFI_ERROR (Status
)) {
3097 Status
= InvokeRegisteredFunction (
3100 (VOID
*)KeyboardLayoutPackage
,
3101 (UINT8
)(PackageHeader
.Type
),
3102 DatabaseRecord
->Handle
3105 case EFI_HII_PACKAGE_STRINGS
:
3106 Status
= InsertStringPackage (
3110 DatabaseRecord
->PackageList
,
3113 if (EFI_ERROR (Status
)) {
3117 ASSERT (StringPackage
!= NULL
);
3118 Status
= InvokeRegisteredFunction (
3121 (VOID
*)StringPackage
,
3122 (UINT8
)(PackageHeader
.Type
),
3123 DatabaseRecord
->Handle
3125 StringPkgIsAdd
= TRUE
;
3127 case EFI_HII_PACKAGE_FONTS
:
3128 Status
= InsertFontPackage (
3132 DatabaseRecord
->PackageList
,
3135 if (EFI_ERROR (Status
)) {
3139 Status
= InvokeRegisteredFunction (
3142 (VOID
*)FontPackage
,
3143 (UINT8
)(PackageHeader
.Type
),
3144 DatabaseRecord
->Handle
3147 case EFI_HII_PACKAGE_IMAGES
:
3148 Status
= InsertImagePackage (
3151 DatabaseRecord
->PackageList
,
3154 if (EFI_ERROR (Status
)) {
3158 Status
= InvokeRegisteredFunction (
3161 (VOID
*)ImagePackage
,
3162 (UINT8
)(PackageHeader
.Type
),
3163 DatabaseRecord
->Handle
3166 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
3167 Status
= InsertSimpleFontPackage (
3170 DatabaseRecord
->PackageList
,
3173 if (EFI_ERROR (Status
)) {
3177 Status
= InvokeRegisteredFunction (
3180 (VOID
*)SimpleFontPackage
,
3181 (UINT8
)(PackageHeader
.Type
),
3182 DatabaseRecord
->Handle
3185 case EFI_HII_PACKAGE_DEVICE_PATH
:
3186 Status
= AddDevicePathPackage (
3189 (EFI_DEVICE_PATH_PROTOCOL
*)((UINT8
*)PackageHdrPtr
+ sizeof (EFI_HII_PACKAGE_HEADER
)),
3197 if (EFI_ERROR (Status
)) {
3202 // goto header of next package
3204 PackageHdrPtr
= (EFI_HII_PACKAGE_HEADER
*)((UINT8
*)PackageHdrPtr
+ PackageHeader
.Length
);
3205 CopyMem (&PackageHeader
, PackageHdrPtr
, sizeof (EFI_HII_PACKAGE_HEADER
));
3209 // Adjust String Package to make sure all string packages have the same max string ID.
3211 if (!EFI_ERROR (Status
) && StringPkgIsAdd
) {
3212 Status
= AdjustStringPackage (DatabaseRecord
->PackageList
);
3219 This function exports a package list to a buffer. It is the worker function
3220 of HiiExportPackageList.
3222 This is a internal function.
3224 @param Private Hii database private structure.
3225 @param Handle Identification of a package list.
3226 @param PackageList Pointer to a package list which will be exported.
3227 @param UsedSize The length of buffer has been used by exporting
3228 package lists when Handle is NULL.
3229 @param BufferSize Length of the Buffer.
3230 @param Buffer Allocated space for storing exported data.
3232 @retval EFI_SUCCESS Keyboard Layout Packages are exported
3234 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
3239 IN HII_DATABASE_PRIVATE_DATA
*Private
,
3240 IN EFI_HII_HANDLE Handle
,
3241 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
3242 IN OUT UINTN
*UsedSize
,
3243 IN UINTN BufferSize
,
3244 OUT EFI_HII_PACKAGE_LIST_HEADER
*Buffer
3249 EFI_HII_PACKAGE_HEADER EndofPackageList
;
3251 ASSERT (Private
!= NULL
&& PackageList
!= NULL
&& UsedSize
!= NULL
);
3252 ASSERT (Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
3253 ASSERT (IsHiiHandleValid (Handle
));
3255 if ((BufferSize
> 0) && (Buffer
== NULL
)) {
3256 return EFI_INVALID_PARAMETER
;
3260 // Copy the package list header
3261 // ResultSize indicates the length of the exported bytes of this package list
3263 ResultSize
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
3264 if (ResultSize
+ *UsedSize
<= BufferSize
) {
3265 CopyMem ((VOID
*)Buffer
, PackageList
, ResultSize
);
3269 // Copy the packages and invoke EXPORT_PACK notify functions if exists.
3271 Status
= ExportGuidPackages (
3277 (VOID
*)((UINT8
*)Buffer
+ ResultSize
),
3280 if (EFI_ERROR (Status
)) {
3284 Status
= ExportFormPackages (
3290 (VOID
*)((UINT8
*)Buffer
+ ResultSize
),
3293 if (EFI_ERROR (Status
)) {
3297 Status
= ExportKeyboardLayoutPackages (
3303 (VOID
*)((UINT8
*)Buffer
+ ResultSize
),
3306 if (EFI_ERROR (Status
)) {
3310 Status
= ExportStringPackages (
3316 (VOID
*)((UINT8
*)Buffer
+ ResultSize
),
3319 if (EFI_ERROR (Status
)) {
3323 Status
= ExportFontPackages (
3329 (VOID
*)((UINT8
*)Buffer
+ ResultSize
),
3332 if (EFI_ERROR (Status
)) {
3336 Status
= ExportImagePackages (
3342 (VOID
*)((UINT8
*)Buffer
+ ResultSize
),
3345 if (EFI_ERROR (Status
)) {
3349 Status
= ExportSimpleFontPackages (
3355 (VOID
*)((UINT8
*)Buffer
+ ResultSize
),
3358 if (EFI_ERROR (Status
)) {
3362 Status
= ExportDevicePathPackage (
3368 (VOID
*)((UINT8
*)Buffer
+ ResultSize
),
3371 if (EFI_ERROR (Status
)) {
3376 // Append the package list end.
3378 EndofPackageList
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
3379 EndofPackageList
.Type
= EFI_HII_PACKAGE_END
;
3380 if (ResultSize
+ *UsedSize
+ sizeof (EFI_HII_PACKAGE_HEADER
) <= BufferSize
) {
3382 (VOID
*)((UINT8
*)Buffer
+ ResultSize
),
3383 (VOID
*)&EndofPackageList
,
3384 sizeof (EFI_HII_PACKAGE_HEADER
)
3388 *UsedSize
+= ResultSize
+ sizeof (EFI_HII_PACKAGE_HEADER
);
3394 This function mainly use to get and update ConfigResp string.
3396 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
3398 @retval EFI_SUCCESS Get the information successfully.
3399 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the Configuration Setting data.
3403 HiiGetConfigRespInfo (
3404 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
3408 HII_DATABASE_PRIVATE_DATA
*Private
;
3409 EFI_STRING ConfigAltResp
;
3412 ConfigAltResp
= NULL
;
3415 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
3418 // Get ConfigResp string
3420 Status
= HiiConfigRoutingExportConfig (&Private
->ConfigRouting
, &ConfigAltResp
);
3422 if (!EFI_ERROR (Status
)) {
3423 ConfigSize
= StrSize (ConfigAltResp
);
3424 if (ConfigSize
> gConfigRespSize
) {
3426 // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
3427 // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
3429 gConfigRespSize
= ConfigSize
+ (ConfigSize
>> 2);
3430 if (gRTConfigRespBuffer
!= NULL
) {
3431 FreePool (gRTConfigRespBuffer
);
3432 DEBUG ((DEBUG_WARN
, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
3435 gRTConfigRespBuffer
= (EFI_STRING
)AllocateRuntimeZeroPool (gConfigRespSize
);
3436 if (gRTConfigRespBuffer
== NULL
) {
3437 FreePool (ConfigAltResp
);
3438 DEBUG ((DEBUG_ERROR
, "[HiiDatabase]: No enough memory resource to store the ConfigResp string.\n"));
3440 // Remove from the System Table when the configuration runtime buffer is freed.
3442 gBS
->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid
, NULL
);
3443 return EFI_OUT_OF_RESOURCES
;
3446 ZeroMem (gRTConfigRespBuffer
, gConfigRespSize
);
3449 CopyMem (gRTConfigRespBuffer
, ConfigAltResp
, ConfigSize
);
3450 gBS
->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid
, gRTConfigRespBuffer
);
3451 FreePool (ConfigAltResp
);
3458 This is an internal function,mainly use to get HiiDatabase information.
3460 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
3462 @retval EFI_SUCCESS Get the information successfully.
3463 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the Hiidatabase data.
3467 HiiGetDatabaseInfo (
3468 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
3472 EFI_HII_PACKAGE_LIST_HEADER
*DatabaseInfo
;
3473 UINTN DatabaseInfoSize
;
3475 DatabaseInfo
= NULL
;
3476 DatabaseInfoSize
= 0;
3479 // Get HiiDatabase information.
3481 Status
= HiiExportPackageLists (This
, NULL
, &DatabaseInfoSize
, DatabaseInfo
);
3483 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
3485 if (DatabaseInfoSize
> gDatabaseInfoSize
) {
3487 // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
3488 // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
3490 gDatabaseInfoSize
= DatabaseInfoSize
+ (DatabaseInfoSize
>> 2);
3491 if (gRTDatabaseInfoBuffer
!= NULL
) {
3492 FreePool (gRTDatabaseInfoBuffer
);
3493 DEBUG ((DEBUG_WARN
, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
3496 gRTDatabaseInfoBuffer
= AllocateRuntimeZeroPool (gDatabaseInfoSize
);
3497 if (gRTDatabaseInfoBuffer
== NULL
) {
3498 DEBUG ((DEBUG_ERROR
, "[HiiDatabase]: No enough memory resource to store the HiiDatabase info.\n"));
3500 // Remove from the System Table when the configuration runtime buffer is freed.
3502 gBS
->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid
, NULL
);
3503 return EFI_OUT_OF_RESOURCES
;
3506 ZeroMem (gRTDatabaseInfoBuffer
, gDatabaseInfoSize
);
3509 Status
= HiiExportPackageLists (This
, NULL
, &DatabaseInfoSize
, gRTDatabaseInfoBuffer
);
3510 ASSERT_EFI_ERROR (Status
);
3511 gBS
->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid
, gRTDatabaseInfoBuffer
);
3517 This function adds the packages in the package list to the database and returns a handle. If there is a
3518 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will
3519 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.
3521 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3523 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
3525 @param DriverHandle Associate the package list with this EFI handle.
3526 If a NULL is specified, this data will not be associate
3527 with any drivers and cannot have a callback induced.
3528 @param Handle A pointer to the EFI_HII_HANDLE instance.
3530 @retval EFI_SUCCESS The package list associated with the Handle was
3531 added to the HII database.
3532 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
3534 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.
3535 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.
3541 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
3542 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*PackageList
,
3543 IN CONST EFI_HANDLE DriverHandle OPTIONAL
,
3544 OUT EFI_HII_HANDLE
*Handle
3548 HII_DATABASE_PRIVATE_DATA
*Private
;
3549 HII_DATABASE_RECORD
*DatabaseRecord
;
3550 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
3552 EFI_GUID PackageListGuid
;
3554 if ((This
== NULL
) || (PackageList
== NULL
) || (Handle
== NULL
)) {
3555 return EFI_INVALID_PARAMETER
;
3558 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
3559 CopyMem (&PackageListGuid
, (VOID
*)PackageList
, sizeof (EFI_GUID
));
3562 // Check the Package list GUID to guarantee this GUID is unique in database.
3564 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
3565 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
3567 &(DatabaseRecord
->PackageList
->PackageListHdr
.PackageListGuid
),
3570 (DatabaseRecord
->DriverHandle
== DriverHandle
))
3572 return EFI_INVALID_PARAMETER
;
3576 EfiAcquireLock (&mHiiDatabaseLock
);
3579 // Build a PackageList node
3581 Status
= GenerateHiiDatabaseRecord (Private
, &DatabaseRecord
);
3582 if (EFI_ERROR (Status
)) {
3583 EfiReleaseLock (&mHiiDatabaseLock
);
3588 // Fill in information of the created Package List node
3589 // according to incoming package list.
3591 Status
= AddPackages (Private
, EFI_HII_DATABASE_NOTIFY_NEW_PACK
, PackageList
, DatabaseRecord
);
3592 if (EFI_ERROR (Status
)) {
3593 EfiReleaseLock (&mHiiDatabaseLock
);
3597 DatabaseRecord
->DriverHandle
= DriverHandle
;
3600 // Create a Device path package and add into the package list if exists.
3602 Status
= gBS
->HandleProtocol (
3604 &gEfiDevicePathProtocolGuid
,
3605 (VOID
**)&DevicePath
3607 if (!EFI_ERROR (Status
)) {
3608 Status
= AddDevicePathPackage (Private
, EFI_HII_DATABASE_NOTIFY_NEW_PACK
, DevicePath
, DatabaseRecord
);
3609 ASSERT_EFI_ERROR (Status
);
3612 *Handle
= DatabaseRecord
->Handle
;
3615 // Check whether need to get the Database info.
3616 // Only after ReadyToBoot, need to do the export.
3618 if (gExportAfterReadyToBoot
) {
3619 HiiGetDatabaseInfo (This
);
3622 EfiReleaseLock (&mHiiDatabaseLock
);
3626 // HiiGetDatabaseInfo () will get the contents of HII data base,
3627 // belong to the atomic behavior of Hii Database update.
3628 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
3629 // we can not think it belong to the atomic behavior of Hii Database update.
3630 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
3633 // Check whether need to get the configuration setting info from HII drivers.
3634 // When after ReadyToBoot and need to do the export for form package add.
3636 if (gExportAfterReadyToBoot
&& gExportConfigResp
) {
3637 HiiGetConfigRespInfo (This
);
3644 This function removes the package list that is associated with Handle
3645 from the HII database. Before removing the package, any registered functions
3646 with the notification type REMOVE_PACK and the same package type will be called.
3648 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3650 @param Handle The handle that was registered to the data that is
3651 requested for removal.
3653 @retval EFI_SUCCESS The data associated with the Handle was removed
3654 from the HII database.
3655 @retval EFI_NOT_FOUND The specified handle is not in database.
3656 @retval EFI_INVALID_PARAMETER The Handle was not valid.
3661 HiiRemovePackageList (
3662 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
3663 IN EFI_HII_HANDLE Handle
3667 HII_DATABASE_PRIVATE_DATA
*Private
;
3669 HII_DATABASE_RECORD
*Node
;
3670 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
3671 HII_HANDLE
*HiiHandle
;
3674 return EFI_INVALID_PARAMETER
;
3677 if (!IsHiiHandleValid (Handle
)) {
3678 return EFI_NOT_FOUND
;
3681 EfiAcquireLock (&mHiiDatabaseLock
);
3683 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
3686 // Get the packagelist to be removed.
3688 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
3689 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
3690 if (Node
->Handle
== Handle
) {
3691 PackageList
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*)(Node
->PackageList
);
3692 ASSERT (PackageList
!= NULL
);
3695 // Call registered functions with REMOVE_PACK before removing packages
3696 // then remove them.
3698 Status
= RemoveGuidPackages (Private
, Handle
, PackageList
);
3699 if (EFI_ERROR (Status
)) {
3700 EfiReleaseLock (&mHiiDatabaseLock
);
3704 Status
= RemoveFormPackages (Private
, Handle
, PackageList
);
3705 if (EFI_ERROR (Status
)) {
3706 EfiReleaseLock (&mHiiDatabaseLock
);
3710 Status
= RemoveKeyboardLayoutPackages (Private
, Handle
, PackageList
);
3711 if (EFI_ERROR (Status
)) {
3712 EfiReleaseLock (&mHiiDatabaseLock
);
3716 Status
= RemoveStringPackages (Private
, Handle
, PackageList
);
3717 if (EFI_ERROR (Status
)) {
3718 EfiReleaseLock (&mHiiDatabaseLock
);
3722 Status
= RemoveFontPackages (Private
, Handle
, PackageList
);
3723 if (EFI_ERROR (Status
)) {
3724 EfiReleaseLock (&mHiiDatabaseLock
);
3728 Status
= RemoveImagePackages (Private
, Handle
, PackageList
);
3729 if (EFI_ERROR (Status
)) {
3730 EfiReleaseLock (&mHiiDatabaseLock
);
3734 Status
= RemoveSimpleFontPackages (Private
, Handle
, PackageList
);
3735 if (EFI_ERROR (Status
)) {
3736 EfiReleaseLock (&mHiiDatabaseLock
);
3740 Status
= RemoveDevicePathPackage (Private
, Handle
, PackageList
);
3741 if (EFI_ERROR (Status
)) {
3742 EfiReleaseLock (&mHiiDatabaseLock
);
3747 // Free resources of the package list
3749 RemoveEntryList (&Node
->DatabaseEntry
);
3751 HiiHandle
= (HII_HANDLE
*)Handle
;
3752 RemoveEntryList (&HiiHandle
->Handle
);
3753 Private
->HiiHandleCount
--;
3754 ASSERT (Private
->HiiHandleCount
>= 0);
3756 HiiHandle
->Signature
= 0;
3757 FreePool (HiiHandle
);
3758 FreePool (Node
->PackageList
);
3762 // Check whether need to get the Database info.
3763 // Only after ReadyToBoot, need to do the export.
3765 if (gExportAfterReadyToBoot
) {
3766 HiiGetDatabaseInfo (This
);
3769 EfiReleaseLock (&mHiiDatabaseLock
);
3773 // HiiGetDatabaseInfo () will get the contents of HII data base,
3774 // belong to the atomic behavior of Hii Database update.
3775 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
3776 // we can not think it belong to the atomic behavior of Hii Database update.
3777 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
3781 // Check whether need to get the configuration setting info from HII drivers.
3782 // When after ReadyToBoot and need to do the export for form package remove.
3784 if (gExportAfterReadyToBoot
&& gExportConfigResp
) {
3785 HiiGetConfigRespInfo (This
);
3792 EfiReleaseLock (&mHiiDatabaseLock
);
3793 return EFI_NOT_FOUND
;
3797 This function updates the existing package list (which has the specified Handle)
3798 in the HII databases, using the new package list specified by PackageList.
3800 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3802 @param Handle The handle that was registered to the data that is
3803 requested to be updated.
3804 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
3807 @retval EFI_SUCCESS The HII database was successfully updated.
3808 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated
3810 @retval EFI_INVALID_PARAMETER PackageList was NULL.
3811 @retval EFI_NOT_FOUND The specified Handle is not in database.
3816 HiiUpdatePackageList (
3817 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
3818 IN EFI_HII_HANDLE Handle
,
3819 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*PackageList
3823 HII_DATABASE_PRIVATE_DATA
*Private
;
3825 HII_DATABASE_RECORD
*Node
;
3826 EFI_HII_PACKAGE_HEADER
*PackageHdrPtr
;
3827 HII_DATABASE_PACKAGE_LIST_INSTANCE
*OldPackageList
;
3828 EFI_HII_PACKAGE_HEADER PackageHeader
;
3830 if ((This
== NULL
) || (PackageList
== NULL
)) {
3831 return EFI_INVALID_PARAMETER
;
3834 if (!IsHiiHandleValid (Handle
)) {
3835 return EFI_NOT_FOUND
;
3838 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
3840 PackageHdrPtr
= (EFI_HII_PACKAGE_HEADER
*)((UINT8
*)PackageList
+ sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
3842 Status
= EFI_SUCCESS
;
3844 EfiAcquireLock (&mHiiDatabaseLock
);
3846 // Get original packagelist to be updated
3848 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
3849 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
3850 if (Node
->Handle
== Handle
) {
3851 OldPackageList
= Node
->PackageList
;
3853 // Remove the package if its type matches one of the package types which is
3854 // contained in the new package list.
3856 CopyMem (&PackageHeader
, PackageHdrPtr
, sizeof (EFI_HII_PACKAGE_HEADER
));
3857 while (PackageHeader
.Type
!= EFI_HII_PACKAGE_END
) {
3858 switch (PackageHeader
.Type
) {
3859 case EFI_HII_PACKAGE_TYPE_GUID
:
3860 Status
= RemoveGuidPackages (Private
, Handle
, OldPackageList
);
3862 case EFI_HII_PACKAGE_FORMS
:
3863 Status
= RemoveFormPackages (Private
, Handle
, OldPackageList
);
3865 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
3866 Status
= RemoveKeyboardLayoutPackages (Private
, Handle
, OldPackageList
);
3868 case EFI_HII_PACKAGE_STRINGS
:
3869 Status
= RemoveStringPackages (Private
, Handle
, OldPackageList
);
3871 case EFI_HII_PACKAGE_FONTS
:
3872 Status
= RemoveFontPackages (Private
, Handle
, OldPackageList
);
3874 case EFI_HII_PACKAGE_IMAGES
:
3875 Status
= RemoveImagePackages (Private
, Handle
, OldPackageList
);
3877 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
3878 Status
= RemoveSimpleFontPackages (Private
, Handle
, OldPackageList
);
3880 case EFI_HII_PACKAGE_DEVICE_PATH
:
3881 Status
= RemoveDevicePathPackage (Private
, Handle
, OldPackageList
);
3885 if (EFI_ERROR (Status
)) {
3886 EfiReleaseLock (&mHiiDatabaseLock
);
3890 PackageHdrPtr
= (EFI_HII_PACKAGE_HEADER
*)((UINT8
*)PackageHdrPtr
+ PackageHeader
.Length
);
3891 CopyMem (&PackageHeader
, PackageHdrPtr
, sizeof (EFI_HII_PACKAGE_HEADER
));
3895 // Add all of the packages within the new package list
3897 Status
= AddPackages (Private
, EFI_HII_DATABASE_NOTIFY_ADD_PACK
, PackageList
, Node
);
3900 // Check whether need to get the Database info.
3901 // Only after ReadyToBoot, need to do the export.
3903 if (gExportAfterReadyToBoot
&& (Status
== EFI_SUCCESS
)) {
3904 HiiGetDatabaseInfo (This
);
3907 EfiReleaseLock (&mHiiDatabaseLock
);
3911 // HiiGetDatabaseInfo () will get the contents of HII data base,
3912 // belong to the atomic behavior of Hii Database update.
3913 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
3914 // we can not think it belong to the atomic behavior of Hii Database update.
3915 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
3919 // Check whether need to get the configuration setting info from HII drivers.
3920 // When after ReadyToBoot and need to do the export for form package update.
3922 if (gExportAfterReadyToBoot
&& gExportConfigResp
&& (Status
== EFI_SUCCESS
)) {
3923 HiiGetConfigRespInfo (This
);
3930 EfiReleaseLock (&mHiiDatabaseLock
);
3931 return EFI_NOT_FOUND
;
3935 This function returns a list of the package handles of the specified type
3936 that are currently active in the database. The pseudo-type
3937 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.
3939 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3941 @param PackageType Specifies the package type of the packages to list
3942 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
3944 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
3945 this is the pointer to the GUID which must match
3946 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.
3947 Otherwise, it must be NULL.
3948 @param HandleBufferLength On input, a pointer to the length of the handle
3949 buffer. On output, the length of the handle
3950 buffer that is required for the handles found.
3951 @param Handle An array of EFI_HII_HANDLE instances returned.
3953 @retval EFI_SUCCESS The matching handles are outputted successfully.
3954 HandleBufferLength is updated with the actual length.
3955 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
3956 Handle is too small to support the number of
3957 handles. HandleBufferLength is updated with a
3958 value that will enable the data to fit.
3959 @retval EFI_NOT_FOUND No matching handle could not be found in database.
3960 @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL.
3961 @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not
3962 zero and Handle was NULL.
3963 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but
3964 PackageGuid is not NULL, PackageType is a EFI_HII_
3965 PACKAGE_TYPE_GUID but PackageGuid is NULL.
3970 HiiListPackageLists (
3971 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
3972 IN UINT8 PackageType
,
3973 IN CONST EFI_GUID
*PackageGuid
,
3974 IN OUT UINTN
*HandleBufferLength
,
3975 OUT EFI_HII_HANDLE
*Handle
3978 HII_GUID_PACKAGE_INSTANCE
*GuidPackage
;
3979 HII_DATABASE_PRIVATE_DATA
*Private
;
3980 HII_DATABASE_RECORD
*Node
;
3983 HII_HANDLE
**Result
;
3985 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
3989 // Check input parameters
3991 if ((This
== NULL
) || (HandleBufferLength
== NULL
)) {
3992 return EFI_INVALID_PARAMETER
;
3995 if ((*HandleBufferLength
> 0) && (Handle
== NULL
)) {
3996 return EFI_INVALID_PARAMETER
;
3999 if (((PackageType
== EFI_HII_PACKAGE_TYPE_GUID
) && (PackageGuid
== NULL
)) ||
4000 ((PackageType
!= EFI_HII_PACKAGE_TYPE_GUID
) && (PackageGuid
!= NULL
)))
4002 return EFI_INVALID_PARAMETER
;
4005 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4007 Result
= (HII_HANDLE
**)Handle
;
4010 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
4011 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
4012 PackageList
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*)(Node
->PackageList
);
4013 switch (PackageType
) {
4014 case EFI_HII_PACKAGE_TYPE_GUID
:
4015 for (Link1
= PackageList
->GuidPkgHdr
.ForwardLink
; Link1
!= &PackageList
->GuidPkgHdr
; Link1
= Link1
->ForwardLink
) {
4016 GuidPackage
= CR (Link1
, HII_GUID_PACKAGE_INSTANCE
, GuidEntry
, HII_GUID_PACKAGE_SIGNATURE
);
4018 (EFI_GUID
*)PackageGuid
,
4019 (EFI_GUID
*)(GuidPackage
->GuidPkg
+ sizeof (EFI_HII_PACKAGE_HEADER
))
4028 case EFI_HII_PACKAGE_FORMS
:
4029 if (!IsListEmpty (&PackageList
->FormPkgHdr
)) {
4034 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
4035 if (!IsListEmpty (&PackageList
->KeyboardLayoutHdr
)) {
4040 case EFI_HII_PACKAGE_STRINGS
:
4041 if (!IsListEmpty (&PackageList
->StringPkgHdr
)) {
4046 case EFI_HII_PACKAGE_FONTS
:
4047 if (!IsListEmpty (&PackageList
->FontPkgHdr
)) {
4052 case EFI_HII_PACKAGE_IMAGES
:
4053 if (PackageList
->ImagePkg
!= NULL
) {
4058 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
4059 if (!IsListEmpty (&PackageList
->SimpleFontPkgHdr
)) {
4064 case EFI_HII_PACKAGE_DEVICE_PATH
:
4065 if (PackageList
->DevicePathPkg
!= NULL
) {
4071 // Pseudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles
4074 case EFI_HII_PACKAGE_TYPE_ALL
:
4082 // This active package list has the specified package type, list it.
4085 ResultSize
+= sizeof (EFI_HII_HANDLE
);
4086 if (ResultSize
<= *HandleBufferLength
) {
4087 *Result
++ = Node
->Handle
;
4094 if (ResultSize
== 0) {
4095 return EFI_NOT_FOUND
;
4098 if (*HandleBufferLength
< ResultSize
) {
4099 *HandleBufferLength
= ResultSize
;
4100 return EFI_BUFFER_TOO_SMALL
;
4103 *HandleBufferLength
= ResultSize
;
4108 This function will export one or all package lists in the database to a buffer.
4109 For each package list exported, this function will call functions registered
4110 with EXPORT_PACK and then copy the package list to the buffer.
4112 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4114 @param Handle An EFI_HII_HANDLE that corresponds to the desired
4115 package list in the HII database to export or NULL
4116 to indicate all package lists should be exported.
4117 @param BufferSize On input, a pointer to the length of the buffer.
4118 On output, the length of the buffer that is
4119 required for the exported data.
4120 @param Buffer A pointer to a buffer that will contain the
4121 results of the export function.
4123 @retval EFI_SUCCESS Package exported.
4124 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
4125 Handle is too small to support the number of
4126 handles. HandleBufferLength is updated with a
4127 value that will enable the data to fit.
4128 @retval EFI_NOT_FOUND The specified Handle could not be found in the
4130 @retval EFI_INVALID_PARAMETER BufferSize was NULL.
4131 @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero
4132 and Buffer was NULL.
4137 HiiExportPackageLists (
4138 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4139 IN EFI_HII_HANDLE Handle
,
4140 IN OUT UINTN
*BufferSize
,
4141 OUT EFI_HII_PACKAGE_LIST_HEADER
*Buffer
4146 HII_DATABASE_PRIVATE_DATA
*Private
;
4147 HII_DATABASE_RECORD
*Node
;
4150 if ((This
== NULL
) || (BufferSize
== NULL
)) {
4151 return EFI_INVALID_PARAMETER
;
4154 if ((*BufferSize
> 0) && (Buffer
== NULL
)) {
4155 return EFI_INVALID_PARAMETER
;
4158 if ((Handle
!= NULL
) && (!IsHiiHandleValid (Handle
))) {
4159 return EFI_NOT_FOUND
;
4162 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4165 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
4166 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
4167 if (Handle
== NULL
) {
4169 // Export all package lists in current hii database.
4171 Status
= ExportPackageList (
4174 (HII_DATABASE_PACKAGE_LIST_INSTANCE
*)(Node
->PackageList
),
4177 (EFI_HII_PACKAGE_LIST_HEADER
*)((UINT8
*)Buffer
+ UsedSize
)
4179 ASSERT_EFI_ERROR (Status
);
4180 } else if ((Handle
!= NULL
) && (Node
->Handle
== Handle
)) {
4181 Status
= ExportPackageList (
4184 (HII_DATABASE_PACKAGE_LIST_INSTANCE
*)(Node
->PackageList
),
4189 ASSERT_EFI_ERROR (Status
);
4190 if (*BufferSize
< UsedSize
) {
4191 *BufferSize
= UsedSize
;
4192 return EFI_BUFFER_TOO_SMALL
;
4199 if ((Handle
== NULL
) && (UsedSize
!= 0)) {
4200 if (*BufferSize
< UsedSize
) {
4201 *BufferSize
= UsedSize
;
4202 return EFI_BUFFER_TOO_SMALL
;
4208 return EFI_NOT_FOUND
;
4212 This function registers a function which will be called when specified actions related to packages of
4213 the specified type occur in the HII database. By registering a function, other HII-related drivers are
4214 notified when specific package types are added, removed or updated in the HII database.
4215 Each driver or application which registers a notification should use
4216 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.
4218 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4220 @param PackageType Specifies the package type of the packages to list
4221 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
4223 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
4224 this is the pointer to the GUID which must match
4226 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must
4228 @param PackageNotifyFn Points to the function to be called when the event
4230 NotificationType occurs.
4231 @param NotifyType Describes the types of notification which this
4232 function will be receiving.
4233 @param NotifyHandle Points to the unique handle assigned to the
4234 registered notification. Can be used in
4235 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()
4236 to stop notifications.
4238 @retval EFI_SUCCESS Notification registered successfully.
4239 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures
4240 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.
4241 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not
4242 EFI_HII_PACKAGE_TYPE_GUID.
4243 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is
4244 EFI_HII_PACKAGE_TYPE_GUID.
4249 HiiRegisterPackageNotify (
4250 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4251 IN UINT8 PackageType
,
4252 IN CONST EFI_GUID
*PackageGuid
,
4253 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn
,
4254 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
4255 OUT EFI_HANDLE
*NotifyHandle
4258 HII_DATABASE_PRIVATE_DATA
*Private
;
4259 HII_DATABASE_NOTIFY
*Notify
;
4262 if ((This
== NULL
) || (NotifyHandle
== NULL
)) {
4263 return EFI_INVALID_PARAMETER
;
4266 if (((PackageType
== EFI_HII_PACKAGE_TYPE_GUID
) && (PackageGuid
== NULL
)) ||
4267 ((PackageType
!= EFI_HII_PACKAGE_TYPE_GUID
) && (PackageGuid
!= NULL
)))
4269 return EFI_INVALID_PARAMETER
;
4272 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4275 // Allocate a notification node
4277 Notify
= (HII_DATABASE_NOTIFY
*)AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY
));
4278 if (Notify
== NULL
) {
4279 return EFI_OUT_OF_RESOURCES
;
4283 // Generate a notify handle
4285 Status
= gBS
->InstallMultipleProtocolInterfaces (
4286 &Notify
->NotifyHandle
,
4291 ASSERT_EFI_ERROR (Status
);
4294 // Fill in the information to the notification node
4296 Notify
->Signature
= HII_DATABASE_NOTIFY_SIGNATURE
;
4297 Notify
->PackageType
= PackageType
;
4298 Notify
->PackageGuid
= (EFI_GUID
*)PackageGuid
;
4299 Notify
->PackageNotifyFn
= (EFI_HII_DATABASE_NOTIFY
)PackageNotifyFn
;
4300 Notify
->NotifyType
= NotifyType
;
4302 InsertTailList (&Private
->DatabaseNotifyList
, &Notify
->DatabaseNotifyEntry
);
4303 *NotifyHandle
= Notify
->NotifyHandle
;
4309 Removes the specified HII database package-related notification.
4311 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4313 @param NotificationHandle The handle of the notification function being
4316 @retval EFI_SUCCESS Notification is unregistered successfully.
4317 @retval EFI_INVALID_PARAMETER The Handle is invalid.
4318 @retval EFI_NOT_FOUND The incoming notification handle does not exist
4319 in current hii database.
4324 HiiUnregisterPackageNotify (
4325 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4326 IN EFI_HANDLE NotificationHandle
4329 HII_DATABASE_PRIVATE_DATA
*Private
;
4330 HII_DATABASE_NOTIFY
*Notify
;
4335 return EFI_INVALID_PARAMETER
;
4338 if (NotificationHandle
== NULL
) {
4339 return EFI_NOT_FOUND
;
4342 Status
= gBS
->OpenProtocol (
4348 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
4350 if (EFI_ERROR (Status
)) {
4351 return EFI_NOT_FOUND
;
4354 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4356 for (Link
= Private
->DatabaseNotifyList
.ForwardLink
; Link
!= &Private
->DatabaseNotifyList
; Link
= Link
->ForwardLink
) {
4357 Notify
= CR (Link
, HII_DATABASE_NOTIFY
, DatabaseNotifyEntry
, HII_DATABASE_NOTIFY_SIGNATURE
);
4358 if (Notify
->NotifyHandle
== NotificationHandle
) {
4360 // Remove the matching notification node
4362 RemoveEntryList (&Notify
->DatabaseNotifyEntry
);
4363 Status
= gBS
->UninstallMultipleProtocolInterfaces (
4364 Notify
->NotifyHandle
,
4369 ASSERT_EFI_ERROR (Status
);
4376 return EFI_NOT_FOUND
;
4380 This routine retrieves an array of GUID values for each keyboard layout that
4381 was previously registered in the system.
4383 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4385 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard
4386 GUID buffer. On output, the length of the handle
4387 buffer that is required for the handles found.
4388 @param KeyGuidBuffer An array of keyboard layout GUID instances
4391 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.
4392 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates
4393 that KeyGuidBuffer is too small to support the
4394 number of GUIDs. KeyGuidBufferLength is
4395 updated with a value that will enable the data to
4397 @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL.
4398 @retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not
4399 zero and KeyGuidBuffer is NULL.
4400 @retval EFI_NOT_FOUND There was no keyboard layout.
4405 HiiFindKeyboardLayouts (
4406 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4407 IN OUT UINT16
*KeyGuidBufferLength
,
4408 OUT EFI_GUID
*KeyGuidBuffer
4411 HII_DATABASE_PRIVATE_DATA
*Private
;
4412 HII_DATABASE_RECORD
*Node
;
4413 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
4419 UINT16 LayoutLength
;
4421 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*Package
;
4423 if ((This
== NULL
) || (KeyGuidBufferLength
== NULL
)) {
4424 return EFI_INVALID_PARAMETER
;
4427 if ((*KeyGuidBufferLength
> 0) && (KeyGuidBuffer
== NULL
)) {
4428 return EFI_INVALID_PARAMETER
;
4431 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4435 // Search all package lists in whole database to retrieve keyboard layout.
4437 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
4438 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
4439 PackageList
= Node
->PackageList
;
4440 for (Link1
= PackageList
->KeyboardLayoutHdr
.ForwardLink
;
4441 Link1
!= &PackageList
->KeyboardLayoutHdr
;
4442 Link1
= Link1
->ForwardLink
4446 // Find out all Keyboard Layout packages in this package list.
4450 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
,
4452 HII_KB_LAYOUT_PACKAGE_SIGNATURE
4454 Layout
= (UINT8
*)Package
->KeyboardPkg
+ sizeof (EFI_HII_PACKAGE_HEADER
) + sizeof (UINT16
);
4457 (UINT8
*)Package
->KeyboardPkg
+ sizeof (EFI_HII_PACKAGE_HEADER
),
4460 for (Index
= 0; Index
< LayoutCount
; Index
++) {
4461 ResultSize
+= sizeof (EFI_GUID
);
4462 if (ResultSize
<= *KeyGuidBufferLength
) {
4463 CopyMem (KeyGuidBuffer
+ (ResultSize
/ sizeof (EFI_GUID
) - 1), Layout
+ sizeof (UINT16
), sizeof (EFI_GUID
));
4464 CopyMem (&LayoutLength
, Layout
, sizeof (UINT16
));
4465 Layout
= Layout
+ LayoutLength
;
4471 if (ResultSize
== 0) {
4472 return EFI_NOT_FOUND
;
4475 if (*KeyGuidBufferLength
< ResultSize
) {
4476 *KeyGuidBufferLength
= ResultSize
;
4477 return EFI_BUFFER_TOO_SMALL
;
4480 *KeyGuidBufferLength
= ResultSize
;
4485 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys
4486 on a keyboard and the character(s) that are associated with a particular set of key strokes.
4488 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4490 @param KeyGuid A pointer to the unique ID associated with a given
4491 keyboard layout. If KeyGuid is NULL then the
4492 current layout will be retrieved.
4493 @param KeyboardLayoutLength On input, a pointer to the length of the
4494 KeyboardLayout buffer. On output, the length of
4495 the data placed into KeyboardLayout.
4496 @param KeyboardLayout A pointer to a buffer containing the retrieved
4499 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.
4500 @retval EFI_NOT_FOUND The requested keyboard layout was not found.
4501 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was
4503 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates
4504 that KeyboardLayout is too small to support the
4505 requested keyboard layout. KeyboardLayoutLength is
4506 updated with a value that will enable the
4512 HiiGetKeyboardLayout (
4513 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4514 IN CONST EFI_GUID
*KeyGuid
,
4515 IN OUT UINT16
*KeyboardLayoutLength
,
4516 OUT EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
4519 HII_DATABASE_PRIVATE_DATA
*Private
;
4520 HII_DATABASE_RECORD
*Node
;
4521 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
4527 UINT16 LayoutLength
;
4528 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*Package
;
4530 if ((This
== NULL
) || (KeyboardLayoutLength
== NULL
)) {
4531 return EFI_INVALID_PARAMETER
;
4534 if ((*KeyboardLayoutLength
> 0) && (KeyboardLayout
== NULL
)) {
4535 return EFI_INVALID_PARAMETER
;
4538 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4540 // Retrieve the current keyboard layout.
4542 if (KeyGuid
== NULL
) {
4543 if (Private
->CurrentLayout
== NULL
) {
4544 return EFI_NOT_FOUND
;
4547 CopyMem (&LayoutLength
, Private
->CurrentLayout
, sizeof (UINT16
));
4548 if (*KeyboardLayoutLength
< LayoutLength
) {
4549 *KeyboardLayoutLength
= LayoutLength
;
4550 return EFI_BUFFER_TOO_SMALL
;
4553 CopyMem (KeyboardLayout
, Private
->CurrentLayout
, LayoutLength
);
4557 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
4558 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
4559 PackageList
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*)(Node
->PackageList
);
4560 for (Link1
= PackageList
->KeyboardLayoutHdr
.ForwardLink
;
4561 Link1
!= &PackageList
->KeyboardLayoutHdr
;
4562 Link1
= Link1
->ForwardLink
4567 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
,
4569 HII_KB_LAYOUT_PACKAGE_SIGNATURE
4572 Layout
= (UINT8
*)Package
->KeyboardPkg
+
4573 sizeof (EFI_HII_PACKAGE_HEADER
) + sizeof (UINT16
);
4574 CopyMem (&LayoutCount
, Layout
- sizeof (UINT16
), sizeof (UINT16
));
4575 for (Index
= 0; Index
< LayoutCount
; Index
++) {
4576 CopyMem (&LayoutLength
, Layout
, sizeof (UINT16
));
4577 if (CompareMem (Layout
+ sizeof (UINT16
), KeyGuid
, sizeof (EFI_GUID
)) == 0) {
4578 if (LayoutLength
<= *KeyboardLayoutLength
) {
4579 CopyMem (KeyboardLayout
, Layout
, LayoutLength
);
4582 *KeyboardLayoutLength
= LayoutLength
;
4583 return EFI_BUFFER_TOO_SMALL
;
4587 Layout
= Layout
+ LayoutLength
;
4592 return EFI_NOT_FOUND
;
4596 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine
4597 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
4598 group type. This is so that agents which are sensitive to the current keyboard layout being changed
4599 can be notified of this change.
4601 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4603 @param KeyGuid A pointer to the unique ID associated with a given
4606 @retval EFI_SUCCESS The current keyboard layout was successfully set.
4607 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so
4609 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.
4614 HiiSetKeyboardLayout (
4615 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4616 IN CONST EFI_GUID
*KeyGuid
4619 HII_DATABASE_PRIVATE_DATA
*Private
;
4620 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
4621 UINT16 KeyboardLayoutLength
;
4624 if ((This
== NULL
) || (KeyGuid
== NULL
)) {
4625 return EFI_INVALID_PARAMETER
;
4628 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4631 // The specified GUID equals the current keyboard layout GUID,
4634 if (CompareGuid (&Private
->CurrentLayoutGuid
, KeyGuid
)) {
4639 // Try to find the incoming keyboard layout data in current database.
4641 KeyboardLayoutLength
= 0;
4642 KeyboardLayout
= NULL
;
4643 Status
= HiiGetKeyboardLayout (This
, KeyGuid
, &KeyboardLayoutLength
, KeyboardLayout
);
4644 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
4648 KeyboardLayout
= (EFI_HII_KEYBOARD_LAYOUT
*)AllocateZeroPool (KeyboardLayoutLength
);
4649 ASSERT (KeyboardLayout
!= NULL
);
4650 Status
= HiiGetKeyboardLayout (This
, KeyGuid
, &KeyboardLayoutLength
, KeyboardLayout
);
4651 ASSERT_EFI_ERROR (Status
);
4654 // Backup current keyboard layout.
4656 CopyMem (&Private
->CurrentLayoutGuid
, KeyGuid
, sizeof (EFI_GUID
));
4657 if (Private
->CurrentLayout
!= NULL
) {
4658 FreePool (Private
->CurrentLayout
);
4661 Private
->CurrentLayout
= KeyboardLayout
;
4664 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify
4665 // current keyboard layout is changed.
4667 Status
= gBS
->SignalEvent (gHiiKeyboardLayoutChanged
);
4668 ASSERT_EFI_ERROR (Status
);
4674 Return the EFI handle associated with a package list.
4676 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4678 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired
4679 package list in the HIIdatabase.
4680 @param DriverHandle On return, contains the EFI_HANDLE which was
4681 registered with the package list in
4684 @retval EFI_SUCCESS The DriverHandle was returned successfully.
4685 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or
4686 DriverHandle was NULL.
4687 @retval EFI_NOT_FOUND This PackageList handle can not be found in
4693 HiiGetPackageListHandle (
4694 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4695 IN EFI_HII_HANDLE PackageListHandle
,
4696 OUT EFI_HANDLE
*DriverHandle
4699 HII_DATABASE_PRIVATE_DATA
*Private
;
4700 HII_DATABASE_RECORD
*Node
;
4703 if ((This
== NULL
) || (DriverHandle
== NULL
)) {
4704 return EFI_INVALID_PARAMETER
;
4707 if (!IsHiiHandleValid (PackageListHandle
)) {
4708 return EFI_INVALID_PARAMETER
;
4711 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4713 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
4714 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
4715 if (Node
->Handle
== PackageListHandle
) {
4716 *DriverHandle
= Node
->DriverHandle
;
4721 return EFI_NOT_FOUND
;