2 Implementation for EFI_HII_DATABASE_PROTOCOL.
4 Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "HiiDatabase.h"
12 #define BASE_NUMBER 10
14 EFI_HII_PACKAGE_LIST_HEADER
*gRTDatabaseInfoBuffer
= NULL
;
15 EFI_STRING gRTConfigRespBuffer
= NULL
;
16 UINTN gDatabaseInfoSize
= 0;
17 UINTN gConfigRespSize
= 0;
18 BOOLEAN gExportConfigResp
= FALSE
;
19 UINTN gNvDefaultStoreSize
= 0;
20 SKU_ID gSkuId
= 0xFFFFFFFFFFFFFFFF;
21 LIST_ENTRY gVarStorageList
= INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList
);
26 EFI_LOCK mHiiDatabaseLock
= EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY
);
29 This function generates a HII_DATABASE_RECORD node and adds into hii database.
30 This is a internal function.
32 @param Private hii database private structure
33 @param DatabaseNode HII_DATABASE_RECORD node which is used to store a
36 @retval EFI_SUCCESS A database record is generated successfully.
37 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
39 @retval EFI_INVALID_PARAMETER Private is NULL or DatabaseRecord is NULL.
43 GenerateHiiDatabaseRecord (
44 IN HII_DATABASE_PRIVATE_DATA
*Private
,
45 OUT HII_DATABASE_RECORD
**DatabaseNode
48 HII_DATABASE_RECORD
*DatabaseRecord
;
49 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
50 HII_HANDLE
*HiiHandle
;
52 if (Private
== NULL
|| DatabaseNode
== NULL
) {
53 return EFI_INVALID_PARAMETER
;
56 DatabaseRecord
= (HII_DATABASE_RECORD
*) AllocateZeroPool (sizeof (HII_DATABASE_RECORD
));
57 if (DatabaseRecord
== NULL
) {
58 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
;
88 HiiHandle
->Signature
= HII_HANDLE_SIGNATURE
;
90 // Backup the number of Hii handles
92 Private
->HiiHandleCount
++;
93 HiiHandle
->Key
= (UINTN
) Private
->HiiHandleCount
;
95 // Insert the handle to hii handle list of the whole database.
97 InsertTailList (&Private
->HiiHandleList
, &HiiHandle
->Handle
);
99 DatabaseRecord
->Handle
= (EFI_HII_HANDLE
) HiiHandle
;
102 // Insert the Package List node to Package List link of the whole database.
104 InsertTailList (&Private
->DatabaseList
, &DatabaseRecord
->DatabaseEntry
);
106 *DatabaseNode
= DatabaseRecord
;
114 This function checks whether a handle is a valid EFI_HII_HANDLE
115 This is a internal function.
117 @param Handle Pointer to a EFI_HII_HANDLE
120 @retval FALSE Invalid
125 EFI_HII_HANDLE Handle
128 HII_HANDLE
*HiiHandle
;
130 HiiHandle
= (HII_HANDLE
*) Handle
;
132 if (HiiHandle
== NULL
) {
136 if (HiiHandle
->Signature
!= HII_HANDLE_SIGNATURE
) {
145 This function invokes the matching registered function.
146 This is a internal function.
148 @param Private HII Database driver private structure.
149 @param NotifyType The type of change concerning the database.
150 @param PackageInstance Points to the package referred to by the
152 @param PackageType Package type
153 @param Handle The handle of the package list which contains the
156 @retval EFI_SUCCESS Already checked all registered function and
158 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
162 InvokeRegisteredFunction (
163 IN HII_DATABASE_PRIVATE_DATA
*Private
,
164 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
165 IN VOID
*PackageInstance
,
166 IN UINT8 PackageType
,
167 IN EFI_HII_HANDLE Handle
170 HII_DATABASE_NOTIFY
*Notify
;
172 EFI_HII_PACKAGE_HEADER
*Package
;
176 UINT32 ImageBlockSize
;
177 UINT32 PaletteInfoSize
;
179 if (Private
== NULL
|| (NotifyType
& 0xF) == 0 || PackageInstance
== NULL
) {
180 return EFI_INVALID_PARAMETER
;
182 if (Private
->Signature
!= HII_DATABASE_PRIVATE_DATA_SIGNATURE
) {
183 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
),
298 Package
= (EFI_HII_PACKAGE_HEADER
*) Buffer
;
301 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
302 BufferSize
= ((HII_SIMPLE_FONT_PACKAGE_INSTANCE
*) PackageInstance
)->SimpleFontPkgHdr
->Header
.Length
;
303 Buffer
= (UINT8
*) AllocateZeroPool (BufferSize
);
304 ASSERT (Buffer
!= NULL
);
307 ((HII_SIMPLE_FONT_PACKAGE_INSTANCE
*) PackageInstance
)->SimpleFontPkgHdr
,
310 Package
= (EFI_HII_PACKAGE_HEADER
*) Buffer
;
313 case EFI_HII_PACKAGE_DEVICE_PATH
:
314 Package
= (EFI_HII_PACKAGE_HEADER
*) PackageInstance
;
318 return EFI_INVALID_PARAMETER
;
321 for (Link
= Private
->DatabaseNotifyList
.ForwardLink
;
322 Link
!= &Private
->DatabaseNotifyList
;
323 Link
= Link
->ForwardLink
325 Notify
= CR (Link
, HII_DATABASE_NOTIFY
, DatabaseNotifyEntry
, HII_DATABASE_NOTIFY_SIGNATURE
);
326 if (Notify
->NotifyType
== NotifyType
&& Notify
->PackageType
== PackageType
) {
328 // Check in case PackageGuid is not NULL when Package is GUID package
330 if (PackageType
!= EFI_HII_PACKAGE_TYPE_GUID
) {
331 Notify
->PackageGuid
= NULL
;
334 // Status of Registered Function is unknown so did not check it
336 Notify
->PackageNotifyFn (
346 if (Buffer
!= NULL
) {
355 This function insert a GUID package to a package list node.
356 This is a internal function.
358 @param PackageHdr Pointer to a buffer stored with GUID package
360 @param NotifyType The type of change concerning the database.
361 @param PackageList Pointer to a package list which will be inserted
363 @param Package Created GUID package
365 @retval EFI_SUCCESS Guid Package is inserted successfully.
366 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
368 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
374 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
375 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
376 OUT HII_GUID_PACKAGE_INSTANCE
**Package
379 HII_GUID_PACKAGE_INSTANCE
*GuidPackage
;
380 EFI_HII_PACKAGE_HEADER PackageHeader
;
382 if (PackageHdr
== NULL
|| PackageList
== NULL
) {
383 return EFI_INVALID_PARAMETER
;
386 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
389 // Create a GUID package node
391 GuidPackage
= (HII_GUID_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_GUID_PACKAGE_INSTANCE
));
392 if (GuidPackage
== NULL
) {
393 return EFI_OUT_OF_RESOURCES
;
395 GuidPackage
->GuidPkg
= (UINT8
*) AllocateZeroPool (PackageHeader
.Length
);
396 if (GuidPackage
->GuidPkg
== NULL
) {
397 FreePool (GuidPackage
);
398 return EFI_OUT_OF_RESOURCES
;
401 GuidPackage
->Signature
= HII_GUID_PACKAGE_SIGNATURE
;
402 CopyMem (GuidPackage
->GuidPkg
, PackageHdr
, PackageHeader
.Length
);
403 InsertTailList (&PackageList
->GuidPkgHdr
, &GuidPackage
->GuidEntry
);
404 *Package
= GuidPackage
;
406 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
407 PackageList
->PackageListHdr
.PackageLength
+= PackageHeader
.Length
;
415 This function exports GUID packages to a buffer.
416 This is a internal function.
418 @param Private Hii database private structure.
419 @param Handle Identification of a package list.
420 @param PackageList Pointer to a package list which will be exported.
421 @param UsedSize The length of buffer be used.
422 @param BufferSize Length of the Buffer.
423 @param Buffer Allocated space for storing exported data.
424 @param ResultSize The size of the already exported content of this
427 @retval EFI_SUCCESS Guid Packages are exported successfully.
428 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
433 IN HII_DATABASE_PRIVATE_DATA
*Private
,
434 IN EFI_HII_HANDLE Handle
,
435 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
439 IN OUT UINTN
*ResultSize
442 HII_GUID_PACKAGE_INSTANCE
*GuidPackage
;
445 EFI_HII_PACKAGE_HEADER PackageHeader
;
448 if (PackageList
== NULL
|| ResultSize
== NULL
) {
449 return EFI_INVALID_PARAMETER
;
452 if (BufferSize
> 0 && Buffer
== NULL
) {
453 return EFI_INVALID_PARAMETER
;
457 Status
= EFI_SUCCESS
;
459 for (Link
= PackageList
->GuidPkgHdr
.ForwardLink
; Link
!= &PackageList
->GuidPkgHdr
; Link
= Link
->ForwardLink
) {
460 GuidPackage
= CR (Link
, HII_GUID_PACKAGE_INSTANCE
, GuidEntry
, HII_GUID_PACKAGE_SIGNATURE
);
461 CopyMem (&PackageHeader
, GuidPackage
->GuidPkg
, sizeof (EFI_HII_PACKAGE_HEADER
));
462 PackageLength
+= PackageHeader
.Length
;
463 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
464 Status
= InvokeRegisteredFunction (
466 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
467 (VOID
*) GuidPackage
,
468 EFI_HII_PACKAGE_TYPE_GUID
,
471 ASSERT_EFI_ERROR (Status
);
472 CopyMem (Buffer
, GuidPackage
->GuidPkg
, PackageHeader
.Length
);
473 Buffer
= (UINT8
*) Buffer
+ PackageHeader
.Length
;
477 *ResultSize
+= PackageLength
;
483 This function deletes all GUID packages from a package list node.
484 This is a internal function.
486 @param Private Hii database private data.
487 @param Handle Handle of the package list which contains the to
488 be removed GUID packages.
489 @param PackageList Pointer to a package list that contains removing
492 @retval EFI_SUCCESS GUID Package(s) is deleted successfully.
493 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
498 IN HII_DATABASE_PRIVATE_DATA
*Private
,
499 IN EFI_HII_HANDLE Handle
,
500 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
503 LIST_ENTRY
*ListHead
;
504 HII_GUID_PACKAGE_INSTANCE
*Package
;
506 EFI_HII_PACKAGE_HEADER PackageHeader
;
508 ListHead
= &PackageList
->GuidPkgHdr
;
510 while (!IsListEmpty (ListHead
)) {
512 ListHead
->ForwardLink
,
513 HII_GUID_PACKAGE_INSTANCE
,
515 HII_GUID_PACKAGE_SIGNATURE
517 Status
= InvokeRegisteredFunction (
519 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
521 EFI_HII_PACKAGE_TYPE_GUID
,
524 if (EFI_ERROR (Status
)) {
528 RemoveEntryList (&Package
->GuidEntry
);
529 CopyMem (&PackageHeader
, Package
->GuidPkg
, sizeof (EFI_HII_PACKAGE_HEADER
));
530 PackageList
->PackageListHdr
.PackageLength
-= PackageHeader
.Length
;
531 FreePool (Package
->GuidPkg
);
539 Check the input question related to EFI variable
541 @param IfrQuestionHdr Point to Question header
542 @param EfiVarStoreList Point to EFI VarStore List
543 @param EfiVarStoreNumber The number of EFI VarStore
545 @retval Index The index of the found EFI varstore in EFI varstore list
546 EfiVarStoreNumber will return if no EFI varstore is found.
549 IsEfiVarStoreQuestion (
550 EFI_IFR_QUESTION_HEADER
*IfrQuestionHdr
,
551 EFI_IFR_VARSTORE_EFI
**EfiVarStoreList
,
552 UINTN EfiVarStoreNumber
556 for (Index
= 0; Index
< EfiVarStoreNumber
; Index
++) {
557 if (IfrQuestionHdr
->VarStoreId
== EfiVarStoreList
[Index
]->VarStoreId
) {
562 return EfiVarStoreNumber
;
566 Find the matched variable from the input variable storage.
568 @param[in] VariableStorage Point to the variable storage header.
569 @param[in] VarGuid A unique identifier for the variable.
570 @param[in] VarAttribute The attributes bitmask for the variable.
571 @param[in] VarName A Null-terminated ascii string that is the name of the variable.
573 @return Pointer to the matched variable header or NULL if not found.
577 IN VARIABLE_STORE_HEADER
*VariableStorage
,
578 IN EFI_GUID
*VarGuid
,
579 IN UINT32 VarAttribute
,
583 VARIABLE_HEADER
*VariableHeader
;
584 VARIABLE_HEADER
*VariableEnd
;
586 VariableEnd
= (VARIABLE_HEADER
*) ((UINT8
*) VariableStorage
+ VariableStorage
->Size
);
587 VariableHeader
= (VARIABLE_HEADER
*) (VariableStorage
+ 1);
588 VariableHeader
= (VARIABLE_HEADER
*) HEADER_ALIGN (VariableHeader
);
589 while (VariableHeader
< VariableEnd
) {
590 if (CompareGuid (&VariableHeader
->VendorGuid
, VarGuid
) &&
591 VariableHeader
->Attributes
== VarAttribute
&&
592 StrCmp (VarName
, (CHAR16
*) (VariableHeader
+ 1)) == 0) {
593 return VariableHeader
;
595 VariableHeader
= (VARIABLE_HEADER
*) ((UINT8
*) VariableHeader
+ sizeof (VARIABLE_HEADER
) + VariableHeader
->NameSize
+ VariableHeader
->DataSize
);
596 VariableHeader
= (VARIABLE_HEADER
*) HEADER_ALIGN (VariableHeader
);
603 Find question default value from PcdNvStoreDefaultValueBuffer
605 @param DefaultId Default store ID
606 @param EfiVarStore Point to EFI VarStore header
607 @param IfrQuestionHdr Point to Question header
608 @param ValueBuffer Point to Buffer includes the found default setting
609 @param Width Width of the default value
610 @param BitFieldQuestion Whether the Question is stored in Bit field.
612 @retval EFI_SUCCESS Question default value is found.
613 @retval EFI_NOT_FOUND Question default value is not found.
616 FindQuestionDefaultSetting (
618 IN EFI_IFR_VARSTORE_EFI
*EfiVarStore
,
619 IN EFI_IFR_QUESTION_HEADER
*IfrQuestionHdr
,
620 OUT VOID
*ValueBuffer
,
622 IN BOOLEAN BitFieldQuestion
625 VARIABLE_HEADER
*VariableHeader
;
626 VARIABLE_STORE_HEADER
*VariableStorage
;
628 VARSTORAGE_DEFAULT_DATA
*Entry
;
629 VARIABLE_STORE_HEADER
*NvStoreBuffer
;
641 PCD_DEFAULT_DATA
*DataHeader
;
642 PCD_DEFAULT_INFO
*DefaultInfo
;
643 PCD_DATA_DELTA
*DeltaData
;
645 if (gSkuId
== 0xFFFFFFFFFFFFFFFF) {
646 gSkuId
= LibPcdGetSku ();
650 // Find the DefaultId setting from the full DefaultSetting
652 VariableStorage
= NULL
;
653 Link
= gVarStorageList
.ForwardLink
;
654 while (Link
!= &gVarStorageList
) {
655 Entry
= BASE_CR (Link
, VARSTORAGE_DEFAULT_DATA
, Entry
);
656 if (Entry
->DefaultId
== DefaultId
) {
657 VariableStorage
= Entry
->VariableStorage
;
660 Link
= Link
->ForwardLink
;
663 if (Link
== &gVarStorageList
) {
664 DataBuffer
= (UINT8
*) PcdGetPtr (PcdNvStoreDefaultValueBuffer
);
665 gNvDefaultStoreSize
= ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER
*)DataBuffer
)->Length
;
667 // The first section data includes NV storage default setting.
669 DataHeader
= (PCD_DEFAULT_DATA
*) (DataBuffer
+ sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
));
670 NvStoreBuffer
= (VARIABLE_STORE_HEADER
*) ((UINT8
*) DataHeader
+ sizeof (DataHeader
->DataSize
) + DataHeader
->HeaderSize
);
671 VariableStorage
= AllocatePool (NvStoreBuffer
->Size
);
672 ASSERT (VariableStorage
!= NULL
);
673 CopyMem (VariableStorage
, NvStoreBuffer
, NvStoreBuffer
->Size
);
676 // Find the matched SkuId and DefaultId in the first section
679 DefaultInfo
= &(DataHeader
->DefaultInfo
[0]);
680 BufferEnd
= (UINT8
*) DataHeader
+ sizeof (DataHeader
->DataSize
) + DataHeader
->HeaderSize
;
681 while ((UINT8
*) DefaultInfo
< BufferEnd
) {
682 if (DefaultInfo
->DefaultId
== DefaultId
&& DefaultInfo
->SkuId
== gSkuId
) {
689 // Find the matched SkuId and DefaultId in the remaining section
691 Index
= sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
) + ((DataHeader
->DataSize
+ 7) & (~7));
692 DataHeader
= (PCD_DEFAULT_DATA
*) (DataBuffer
+ Index
);
693 while (!IsFound
&& Index
< gNvDefaultStoreSize
&& DataHeader
->DataSize
!= 0xFFFF) {
694 DefaultInfo
= &(DataHeader
->DefaultInfo
[0]);
695 BufferEnd
= (UINT8
*) DataHeader
+ sizeof (DataHeader
->DataSize
) + DataHeader
->HeaderSize
;
696 while ((UINT8
*) DefaultInfo
< BufferEnd
) {
697 if (DefaultInfo
->DefaultId
== DefaultId
&& DefaultInfo
->SkuId
== gSkuId
) {
704 DeltaData
= (PCD_DATA_DELTA
*) BufferEnd
;
705 BufferEnd
= (UINT8
*) DataHeader
+ DataHeader
->DataSize
;
706 while ((UINT8
*) DeltaData
< BufferEnd
) {
707 *((UINT8
*) VariableStorage
+ DeltaData
->Offset
) = (UINT8
) DeltaData
->Value
;
712 Index
= (Index
+ DataHeader
->DataSize
+ 7) & (~7);
713 DataHeader
= (PCD_DEFAULT_DATA
*) (DataBuffer
+ Index
);
716 // Cache the found result in VarStorageList
719 FreePool (VariableStorage
);
720 VariableStorage
= NULL
;
722 Entry
= AllocatePool (sizeof (VARSTORAGE_DEFAULT_DATA
));
724 Entry
->DefaultId
= DefaultId
;
725 Entry
->VariableStorage
= VariableStorage
;
726 InsertTailList (&gVarStorageList
, &Entry
->Entry
);
727 } else if (VariableStorage
!= NULL
) {
728 FreePool (VariableStorage
);
729 VariableStorage
= NULL
;
733 // The matched variable storage is not found.
735 if (VariableStorage
== NULL
) {
736 return EFI_NOT_FOUND
;
740 // Find the question default value from the variable storage
742 VariableHeader
= FindVariableData (VariableStorage
, &EfiVarStore
->Guid
, EfiVarStore
->Attributes
, (CHAR16
*) EfiVarStore
->Name
);
743 if (VariableHeader
== NULL
) {
744 return EFI_NOT_FOUND
;
748 ByteOffset
= IfrQuestionHdr
->VarStoreInfo
.VarOffset
;
749 if (BitFieldQuestion
) {
750 BitOffset
= IfrQuestionHdr
->VarStoreInfo
.VarOffset
;
751 ByteOffset
= BitOffset
/ 8;
753 StartBit
= BitOffset
% 8;
754 EndBit
= StartBit
+ BitWidth
- 1;
755 Width
= EndBit
/ 8 + 1;
757 if (VariableHeader
->DataSize
< ByteOffset
+ Width
) {
758 return EFI_INVALID_PARAMETER
;
762 // Copy the question value
764 if (ValueBuffer
!= NULL
) {
765 if (BitFieldQuestion
) {
766 CopyMem (&BufferValue
, (UINT8
*) VariableHeader
+ sizeof (VARIABLE_HEADER
) + VariableHeader
->NameSize
+ ByteOffset
, Width
);
767 BitFieldVal
= BitFieldRead32 (BufferValue
, StartBit
, EndBit
);
768 CopyMem (ValueBuffer
, &BitFieldVal
, Width
);
770 CopyMem (ValueBuffer
, (UINT8
*) VariableHeader
+ sizeof (VARIABLE_HEADER
) + VariableHeader
->NameSize
+ IfrQuestionHdr
->VarStoreInfo
.VarOffset
, Width
);
778 Update IFR default setting in Form Package.
780 @param FormPackage Form Package to be updated
784 UpdateDefaultSettingInFormPackage (
785 HII_IFR_PACKAGE_INSTANCE
*FormPackage
790 EFI_IFR_VARSTORE_EFI
*IfrEfiVarStore
;
791 EFI_IFR_OP_HEADER
*IfrOpHdr
;
792 EFI_IFR_ONE_OF_OPTION
*IfrOneOfOption
;
793 UINT8 IfrQuestionType
;
795 EFI_IFR_QUESTION_HEADER
*IfrQuestionHdr
;
796 EFI_IFR_VARSTORE_EFI
**EfiVarStoreList
;
797 UINTN EfiVarStoreMaxNum
;
798 UINTN EfiVarStoreNumber
;
799 UINT16
*DefaultIdList
;
800 UINTN DefaultIdNumber
;
801 UINTN DefaultIdMaxNum
;
803 UINTN EfiVarStoreIndex
;
804 EFI_IFR_TYPE_VALUE IfrValue
;
805 EFI_IFR_TYPE_VALUE IfrManufactValue
;
806 BOOLEAN StandardDefaultIsSet
;
807 BOOLEAN ManufactDefaultIsSet
;
808 EFI_IFR_CHECKBOX
*IfrCheckBox
;
810 EFI_IFR_DEFAULT
*IfrDefault
;
812 EFI_IFR_QUESTION_HEADER VarStoreQuestionHeader
;
813 BOOLEAN QuestionReferBitField
;
816 // If no default setting, do nothing
818 if (gNvDefaultStoreSize
== 0) {
819 gNvDefaultStoreSize
= PcdGetSize (PcdNvStoreDefaultValueBuffer
);
821 if (gNvDefaultStoreSize
< sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER
)) {
825 ZeroMem (&VarStoreQuestionHeader
, sizeof (VarStoreQuestionHeader
));
826 PackageLength
= FormPackage
->FormPkgHdr
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
);
830 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) FormPackage
->IfrData
;
831 IfrQuestionHdr
= NULL
;
833 EfiVarStoreMaxNum
= 0;
834 EfiVarStoreNumber
= 0;
837 EfiVarStoreList
= NULL
;
838 DefaultIdList
= NULL
;
839 StandardDefaultIsSet
= FALSE
;
840 ManufactDefaultIsSet
= FALSE
;
841 QuestionReferBitField
= FALSE
;
843 while (IfrOffset
< PackageLength
) {
844 switch (IfrOpHdr
->OpCode
) {
845 case EFI_IFR_VARSTORE_EFI_OP
:
846 if (EfiVarStoreNumber
>= EfiVarStoreMaxNum
) {
848 // Reallocate EFI VarStore Buffer
850 EfiVarStoreList
= ReallocatePool (EfiVarStoreMaxNum
* sizeof (UINTN
), (EfiVarStoreMaxNum
+ BASE_NUMBER
) * sizeof (UINTN
), EfiVarStoreList
);
851 if (EfiVarStoreList
== NULL
) {
854 EfiVarStoreMaxNum
= EfiVarStoreMaxNum
+ BASE_NUMBER
;
856 IfrEfiVarStore
= (EFI_IFR_VARSTORE_EFI
*) IfrOpHdr
;
858 // Convert VarStore Name from ASCII string to Unicode string.
860 EfiVarStoreList
[EfiVarStoreNumber
] = AllocatePool (IfrEfiVarStore
->Header
.Length
+ AsciiStrSize ((CHAR8
*)IfrEfiVarStore
->Name
));
861 if (EfiVarStoreList
[EfiVarStoreNumber
] == NULL
) {
864 CopyMem (EfiVarStoreList
[EfiVarStoreNumber
], IfrEfiVarStore
, IfrEfiVarStore
->Header
.Length
);
865 AsciiStrToUnicodeStrS ((CHAR8
*)IfrEfiVarStore
->Name
, (CHAR16
*) &(EfiVarStoreList
[EfiVarStoreNumber
]->Name
[0]), AsciiStrSize ((CHAR8
*)IfrEfiVarStore
->Name
) * sizeof (CHAR16
));
866 Status
= FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD
, EfiVarStoreList
[EfiVarStoreNumber
], &VarStoreQuestionHeader
, NULL
, IfrEfiVarStore
->Size
, FALSE
);
867 if (!EFI_ERROR (Status
)) {
868 EfiVarStoreNumber
++;
870 FreePool (EfiVarStoreList
[EfiVarStoreNumber
]);
871 EfiVarStoreList
[EfiVarStoreNumber
] = NULL
;
874 case EFI_IFR_DEFAULTSTORE_OP
:
875 if (DefaultIdNumber
>= DefaultIdMaxNum
) {
877 // Reallocate DefaultIdNumber
879 DefaultIdList
= ReallocatePool (DefaultIdMaxNum
* sizeof (UINT16
), (DefaultIdMaxNum
+ BASE_NUMBER
) * sizeof (UINT16
), DefaultIdList
);
880 if (DefaultIdList
== NULL
) {
883 DefaultIdMaxNum
= DefaultIdMaxNum
+ BASE_NUMBER
;
885 DefaultIdList
[DefaultIdNumber
++] = ((EFI_IFR_DEFAULTSTORE
*) IfrOpHdr
)->DefaultId
;
887 case EFI_IFR_FORM_OP
:
888 case EFI_IFR_FORM_MAP_OP
:
890 // No EFI varstore is found and directly return.
892 if (EfiVarStoreNumber
== 0 || DefaultIdNumber
== 0) {
896 case EFI_IFR_CHECKBOX_OP
:
897 IfrScope
= IfrOpHdr
->Scope
;
898 IfrQuestionType
= IfrOpHdr
->OpCode
;
899 IfrQuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (IfrOpHdr
+ 1);
900 IfrCheckBox
= (EFI_IFR_CHECKBOX
*) IfrOpHdr
;
901 EfiVarStoreIndex
= IsEfiVarStoreQuestion (IfrQuestionHdr
, EfiVarStoreList
, EfiVarStoreNumber
);
902 Width
= sizeof (BOOLEAN
);
903 if (EfiVarStoreIndex
< EfiVarStoreNumber
) {
904 for (Index
= 0; Index
< DefaultIdNumber
; Index
++) {
905 if (DefaultIdList
[Index
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
906 Status
= FindQuestionDefaultSetting (DefaultIdList
[Index
], EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrValue
, sizeof (BOOLEAN
), QuestionReferBitField
);
907 if (!EFI_ERROR (Status
)) {
909 IfrCheckBox
->Flags
= IfrCheckBox
->Flags
| EFI_IFR_CHECKBOX_DEFAULT
;
911 IfrCheckBox
->Flags
= IfrCheckBox
->Flags
& (~EFI_IFR_CHECKBOX_DEFAULT
);
914 } else if (DefaultIdList
[Index
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
915 Status
= FindQuestionDefaultSetting (DefaultIdList
[Index
], EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrValue
, sizeof (BOOLEAN
), QuestionReferBitField
);
916 if (!EFI_ERROR (Status
)) {
918 IfrCheckBox
->Flags
= IfrCheckBox
->Flags
| EFI_IFR_CHECKBOX_DEFAULT_MFG
;
920 IfrCheckBox
->Flags
= IfrCheckBox
->Flags
& (~EFI_IFR_CHECKBOX_DEFAULT_MFG
);
927 case EFI_IFR_NUMERIC_OP
:
928 IfrScope
= IfrOpHdr
->Scope
;
929 IfrQuestionType
= IfrOpHdr
->OpCode
;
930 IfrQuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (IfrOpHdr
+ 1);
931 if (QuestionReferBitField
) {
932 Width
= (UINTN
) (((EFI_IFR_ONE_OF
*) IfrOpHdr
)->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
);
934 Width
= (UINTN
) ((UINT32
) 1 << (((EFI_IFR_ONE_OF
*) IfrOpHdr
)->Flags
& EFI_IFR_NUMERIC_SIZE
));
937 case EFI_IFR_ONE_OF_OP
:
938 IfrScope
= IfrOpHdr
->Scope
;
939 IfrQuestionType
= IfrOpHdr
->OpCode
;
940 IfrQuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (IfrOpHdr
+ 1);
941 if (QuestionReferBitField
) {
942 Width
= (UINTN
) (((EFI_IFR_ONE_OF
*) IfrOpHdr
)->Flags
& EDKII_IFR_NUMERIC_SIZE_BIT
);
944 Width
= (UINTN
) ((UINT32
) 1 << (((EFI_IFR_ONE_OF
*) IfrOpHdr
)->Flags
& EFI_IFR_NUMERIC_SIZE
));
946 EfiVarStoreIndex
= IsEfiVarStoreQuestion (IfrQuestionHdr
, EfiVarStoreList
, EfiVarStoreNumber
);
947 StandardDefaultIsSet
= FALSE
;
948 ManufactDefaultIsSet
= FALSE
;
950 // Find Default and Manufacturing default for OneOf question
952 if (EfiVarStoreIndex
< EfiVarStoreNumber
) {
953 for (Index
= 0; Index
< DefaultIdNumber
; Index
++) {
954 if (DefaultIdList
[Index
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
955 Status
= FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD
, EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrValue
, Width
, QuestionReferBitField
);
956 if (!EFI_ERROR (Status
)) {
957 StandardDefaultIsSet
= TRUE
;
959 } else if (DefaultIdList
[Index
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
960 Status
= FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_MANUFACTURING
, EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrManufactValue
, Width
, QuestionReferBitField
);
961 if (!EFI_ERROR (Status
)) {
962 ManufactDefaultIsSet
= TRUE
;
968 case EFI_IFR_ORDERED_LIST_OP
:
969 IfrScope
= IfrOpHdr
->Scope
;
970 IfrQuestionType
= IfrOpHdr
->OpCode
;
971 IfrQuestionHdr
= (EFI_IFR_QUESTION_HEADER
*) (IfrOpHdr
+ 1);
973 case EFI_IFR_ONE_OF_OPTION_OP
:
974 if (IfrQuestionHdr
!= NULL
&& IfrScope
> 0) {
975 IfrOneOfOption
= (EFI_IFR_ONE_OF_OPTION
*) IfrOpHdr
;
976 if (IfrQuestionType
== EFI_IFR_ONE_OF_OP
) {
977 Width
= (UINTN
) ((UINT32
) 1 << (IfrOneOfOption
->Flags
& EFI_IFR_NUMERIC_SIZE
));
978 if (StandardDefaultIsSet
) {
979 if (CompareMem (&IfrOneOfOption
->Value
, &IfrValue
, Width
) == 0) {
980 IfrOneOfOption
->Flags
|= EFI_IFR_OPTION_DEFAULT
;
982 IfrOneOfOption
->Flags
&= ~EFI_IFR_OPTION_DEFAULT
;
985 if (ManufactDefaultIsSet
) {
986 if (CompareMem (&IfrOneOfOption
->Value
, &IfrManufactValue
, Width
) == 0) {
987 IfrOneOfOption
->Flags
|= EFI_IFR_OPTION_DEFAULT_MFG
;
989 IfrOneOfOption
->Flags
&= ~EFI_IFR_OPTION_DEFAULT_MFG
;
995 case EFI_IFR_DEFAULT_OP
:
996 if (IfrQuestionHdr
!= NULL
&& IfrScope
> 0) {
997 IfrDefault
= (EFI_IFR_DEFAULT
*) IfrOpHdr
;
999 // Collect default value width
1001 if (!QuestionReferBitField
) {
1003 if (IfrDefault
->Type
== EFI_IFR_TYPE_NUM_SIZE_8
|| IfrDefault
->Type
== EFI_IFR_TYPE_BOOLEAN
) {
1005 } else if (IfrDefault
->Type
== EFI_IFR_TYPE_NUM_SIZE_16
) {
1007 } else if (IfrDefault
->Type
== EFI_IFR_TYPE_NUM_SIZE_32
) {
1009 } else if (IfrDefault
->Type
== EFI_IFR_TYPE_NUM_SIZE_64
) {
1011 } else if (IfrDefault
->Type
== EFI_IFR_TYPE_BUFFER
) {
1012 Width
= IfrDefault
->Header
.Length
- OFFSET_OF (EFI_IFR_DEFAULT
, Value
);
1016 // Update the default value
1019 EfiVarStoreIndex
= IsEfiVarStoreQuestion (IfrQuestionHdr
, EfiVarStoreList
, EfiVarStoreNumber
);
1020 if (EfiVarStoreIndex
< EfiVarStoreNumber
) {
1021 Status
= FindQuestionDefaultSetting (IfrDefault
->DefaultId
, EfiVarStoreList
[EfiVarStoreIndex
], IfrQuestionHdr
, &IfrDefault
->Value
, Width
, QuestionReferBitField
);
1026 case EFI_IFR_END_OP
:
1027 if (IfrQuestionHdr
!= NULL
) {
1031 if (IfrScope
== 0) {
1032 IfrQuestionHdr
= NULL
;
1033 QuestionReferBitField
= FALSE
;
1037 case EFI_IFR_GUID_OP
:
1038 if (CompareGuid ((EFI_GUID
*)((UINT8
*)IfrOpHdr
+ sizeof (EFI_IFR_OP_HEADER
)), &gEdkiiIfrBitVarstoreGuid
)) {
1039 QuestionReferBitField
= TRUE
;
1045 IfrOffset
= IfrOffset
+ IfrOpHdr
->Length
;
1046 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((UINT8
*) IfrOpHdr
+ IfrOpHdr
->Length
);
1048 IfrScope
+= IfrOpHdr
->Scope
;
1053 if (EfiVarStoreList
!= NULL
) {
1054 for (Index
= 0; Index
< EfiVarStoreNumber
; Index
++) {
1055 FreePool (EfiVarStoreList
[Index
]);
1062 This function insert a Form package to a package list node.
1063 This is a internal function.
1065 @param PackageHdr Pointer to a buffer stored with Form package
1067 @param NotifyType The type of change concerning the database.
1068 @param PackageList Pointer to a package list which will be inserted
1070 @param Package Created Form package
1072 @retval EFI_SUCCESS Form Package is inserted successfully.
1073 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1075 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1080 IN VOID
*PackageHdr
,
1081 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
1082 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1083 OUT HII_IFR_PACKAGE_INSTANCE
**Package
1086 HII_IFR_PACKAGE_INSTANCE
*FormPackage
;
1087 EFI_HII_PACKAGE_HEADER PackageHeader
;
1089 if (PackageHdr
== NULL
|| PackageList
== NULL
) {
1090 return EFI_INVALID_PARAMETER
;
1094 // Get the length of the package, including package header itself
1096 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
1099 // Create a Form package node
1101 FormPackage
= (HII_IFR_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_IFR_PACKAGE_INSTANCE
));
1102 if (FormPackage
== NULL
) {
1103 return EFI_OUT_OF_RESOURCES
;
1106 FormPackage
->IfrData
= (UINT8
*) AllocateZeroPool (PackageHeader
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
));
1107 if (FormPackage
->IfrData
== NULL
) {
1108 FreePool (FormPackage
);
1109 return EFI_OUT_OF_RESOURCES
;
1112 FormPackage
->Signature
= HII_IFR_PACKAGE_SIGNATURE
;
1114 // Copy Package Header
1116 CopyMem (&FormPackage
->FormPkgHdr
, &PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
1119 // Copy Ifr contents
1122 FormPackage
->IfrData
,
1123 (UINT8
*) PackageHdr
+ sizeof (EFI_HII_PACKAGE_HEADER
),
1124 PackageHeader
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
)
1127 InsertTailList (&PackageList
->FormPkgHdr
, &FormPackage
->IfrEntry
);
1128 *Package
= FormPackage
;
1131 // Update FormPackage with the default setting
1133 UpdateDefaultSettingInFormPackage (FormPackage
);
1135 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
1136 PackageList
->PackageListHdr
.PackageLength
+= FormPackage
->FormPkgHdr
.Length
;
1143 This function exports Form packages to a buffer.
1144 This is a internal function.
1146 @param Private Hii database private structure.
1147 @param Handle Identification of a package list.
1148 @param PackageList Pointer to a package list which will be exported.
1149 @param UsedSize The length of buffer be used.
1150 @param BufferSize Length of the Buffer.
1151 @param Buffer Allocated space for storing exported data.
1152 @param ResultSize The size of the already exported content of this
1155 @retval EFI_SUCCESS Form Packages are exported successfully.
1156 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1160 ExportFormPackages (
1161 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1162 IN EFI_HII_HANDLE Handle
,
1163 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1165 IN UINTN BufferSize
,
1166 IN OUT VOID
*Buffer
,
1167 IN OUT UINTN
*ResultSize
1170 HII_IFR_PACKAGE_INSTANCE
*FormPackage
;
1171 UINTN PackageLength
;
1175 if (Private
== NULL
|| PackageList
== NULL
|| ResultSize
== NULL
) {
1176 return EFI_INVALID_PARAMETER
;
1179 if (BufferSize
> 0 && Buffer
== NULL
) {
1180 return EFI_INVALID_PARAMETER
;
1184 Status
= EFI_SUCCESS
;
1187 // Export Form packages.
1189 for (Link
= PackageList
->FormPkgHdr
.ForwardLink
; Link
!= &PackageList
->FormPkgHdr
; Link
= Link
->ForwardLink
) {
1190 FormPackage
= CR (Link
, HII_IFR_PACKAGE_INSTANCE
, IfrEntry
, HII_IFR_PACKAGE_SIGNATURE
);
1191 PackageLength
+= FormPackage
->FormPkgHdr
.Length
;
1192 if ((Buffer
!= NULL
) && (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
)) {
1194 // Invoke registered notification if exists
1196 Status
= InvokeRegisteredFunction (
1198 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
1199 (VOID
*) FormPackage
,
1200 EFI_HII_PACKAGE_FORMS
,
1203 ASSERT_EFI_ERROR (Status
);
1205 // Copy the Form package content.
1207 CopyMem (Buffer
, (VOID
*) (&FormPackage
->FormPkgHdr
), sizeof (EFI_HII_PACKAGE_HEADER
));
1208 Buffer
= (UINT8
*) Buffer
+ sizeof (EFI_HII_PACKAGE_HEADER
);
1211 (VOID
*) FormPackage
->IfrData
,
1212 FormPackage
->FormPkgHdr
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
)
1214 Buffer
= (UINT8
*) Buffer
+ FormPackage
->FormPkgHdr
.Length
- sizeof (EFI_HII_PACKAGE_HEADER
);
1218 *ResultSize
+= PackageLength
;
1226 This function deletes all Form packages from a package list node.
1227 This is a internal function.
1229 @param Private Hii database private data.
1230 @param Handle Handle of the package list which contains the to
1231 be removed Form packages.
1232 @param PackageList Pointer to a package list that contains removing
1235 @retval EFI_SUCCESS Form Package(s) is deleted successfully.
1236 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1240 RemoveFormPackages (
1241 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1242 IN EFI_HII_HANDLE Handle
,
1243 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
1246 LIST_ENTRY
*ListHead
;
1247 HII_IFR_PACKAGE_INSTANCE
*Package
;
1250 ListHead
= &PackageList
->FormPkgHdr
;
1252 while (!IsListEmpty (ListHead
)) {
1254 ListHead
->ForwardLink
,
1255 HII_IFR_PACKAGE_INSTANCE
,
1257 HII_IFR_PACKAGE_SIGNATURE
1259 Status
= InvokeRegisteredFunction (
1261 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
1263 EFI_HII_PACKAGE_FORMS
,
1266 if (EFI_ERROR (Status
)) {
1270 RemoveEntryList (&Package
->IfrEntry
);
1271 PackageList
->PackageListHdr
.PackageLength
-= Package
->FormPkgHdr
.Length
;
1272 FreePool (Package
->IfrData
);
1275 // If Hii runtime support feature is enabled,
1276 // will export Hii info for runtime use after ReadyToBoot event triggered.
1277 // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
1278 // will need to export the content of HiiDatabase.
1279 // But if form packages removed, also need to export the ConfigResp string
1281 if (gExportAfterReadyToBoot
) {
1282 gExportConfigResp
= TRUE
;
1292 This function insert a String package to a package list node.
1293 This is a internal function.
1295 @param Private Hii database private structure.
1296 @param PackageHdr Pointer to a buffer stored with String package
1298 @param NotifyType The type of change concerning the database.
1299 @param PackageList Pointer to a package list which will be inserted
1301 @param Package Created String package
1303 @retval EFI_SUCCESS String Package is inserted successfully.
1304 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1306 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1307 @retval EFI_UNSUPPORTED A string package with the same language already
1308 exists in current package list.
1312 InsertStringPackage (
1313 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1314 IN VOID
*PackageHdr
,
1315 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
1316 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1317 OUT HII_STRING_PACKAGE_INSTANCE
**Package
1320 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1323 EFI_HII_PACKAGE_HEADER PackageHeader
;
1325 UINT32 LanguageSize
;
1328 if (Private
== NULL
|| PackageHdr
== NULL
|| PackageList
== NULL
) {
1329 return EFI_INVALID_PARAMETER
;
1331 if (Private
->Signature
!= HII_DATABASE_PRIVATE_DATA_SIGNATURE
) {
1332 return EFI_INVALID_PARAMETER
;
1335 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
1336 CopyMem (&HeaderSize
, (UINT8
*) PackageHdr
+ sizeof (EFI_HII_PACKAGE_HEADER
), sizeof (UINT32
));
1339 // It is illegal to have two string packages with same language within one packagelist
1340 // since the stringid will be duplicate if so. Check it to avoid this potential issue.
1342 LanguageSize
= HeaderSize
- sizeof (EFI_HII_STRING_PACKAGE_HDR
) + sizeof (CHAR8
);
1343 Language
= (CHAR8
*) AllocateZeroPool (LanguageSize
);
1344 if (Language
== NULL
) {
1345 return EFI_OUT_OF_RESOURCES
;
1347 AsciiStrCpyS (Language
, LanguageSize
/ sizeof (CHAR8
), (CHAR8
*) PackageHdr
+ HeaderSize
- LanguageSize
);
1348 for (Link
= PackageList
->StringPkgHdr
.ForwardLink
; Link
!= &PackageList
->StringPkgHdr
; Link
= Link
->ForwardLink
) {
1349 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1350 if (HiiCompareLanguage (Language
, StringPackage
->StringPkgHdr
->Language
)) {
1351 FreePool (Language
);
1352 return EFI_UNSUPPORTED
;
1355 FreePool (Language
);
1358 // Create a String package node
1360 StringPackage
= (HII_STRING_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE
));
1361 if (StringPackage
== NULL
) {
1362 Status
= EFI_OUT_OF_RESOURCES
;
1366 StringPackage
->StringPkgHdr
= (EFI_HII_STRING_PACKAGE_HDR
*) AllocateZeroPool (HeaderSize
);
1367 if (StringPackage
->StringPkgHdr
== NULL
) {
1368 Status
= EFI_OUT_OF_RESOURCES
;
1372 StringPackage
->StringBlock
= (UINT8
*) AllocateZeroPool (PackageHeader
.Length
- HeaderSize
);
1373 if (StringPackage
->StringBlock
== NULL
) {
1374 Status
= EFI_OUT_OF_RESOURCES
;
1378 StringPackage
->Signature
= HII_STRING_PACKAGE_SIGNATURE
;
1379 StringPackage
->FontId
= 0;
1380 InitializeListHead (&StringPackage
->FontInfoList
);
1383 // Copy the String package header.
1385 CopyMem (StringPackage
->StringPkgHdr
, PackageHdr
, HeaderSize
);
1388 // Copy the String blocks
1391 StringPackage
->StringBlock
,
1392 (UINT8
*) PackageHdr
+ HeaderSize
,
1393 PackageHeader
.Length
- HeaderSize
1397 // Collect all font block info
1399 Status
= FindStringBlock (Private
, StringPackage
, (EFI_STRING_ID
) (-1), NULL
, NULL
, NULL
, &StringPackage
->MaxStringId
, NULL
);
1400 if (EFI_ERROR (Status
)) {
1405 // Insert to String package array
1407 InsertTailList (&PackageList
->StringPkgHdr
, &StringPackage
->StringEntry
);
1408 *Package
= StringPackage
;
1410 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
1411 PackageList
->PackageListHdr
.PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
;
1418 if (StringPackage
!= NULL
) {
1419 if (StringPackage
->StringBlock
!= NULL
) {
1420 FreePool (StringPackage
->StringBlock
);
1422 if (StringPackage
->StringPkgHdr
!= NULL
) {
1423 FreePool (StringPackage
->StringPkgHdr
);
1425 FreePool (StringPackage
);
1432 Adjust all string packages in a single package list to have the same max string ID.
1434 @param PackageList Pointer to a package list which will be adjusted.
1436 @retval EFI_SUCCESS Adjust all string packages successfully.
1437 @retval others Can't adjust string packages.
1441 AdjustStringPackage (
1442 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
1446 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1447 UINT32 Skip2BlockSize
;
1448 UINT32 OldBlockSize
;
1451 EFI_STRING_ID MaxStringId
;
1455 for (Link
= PackageList
->StringPkgHdr
.ForwardLink
;
1456 Link
!= &PackageList
->StringPkgHdr
;
1457 Link
= Link
->ForwardLink
1459 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1460 if (MaxStringId
< StringPackage
->MaxStringId
) {
1461 MaxStringId
= StringPackage
->MaxStringId
;
1465 for (Link
= PackageList
->StringPkgHdr
.ForwardLink
;
1466 Link
!= &PackageList
->StringPkgHdr
;
1467 Link
= Link
->ForwardLink
1469 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1470 if (StringPackage
->MaxStringId
< MaxStringId
) {
1471 OldBlockSize
= StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1473 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs.
1475 SkipCount
= (UINT16
) (MaxStringId
- StringPackage
->MaxStringId
);
1476 Skip2BlockSize
= (UINT32
) sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
1478 StringBlock
= (UINT8
*) AllocateZeroPool (OldBlockSize
+ Skip2BlockSize
);
1479 if (StringBlock
== NULL
) {
1480 return EFI_OUT_OF_RESOURCES
;
1483 // Copy original string blocks, except the EFI_HII_SIBT_END.
1485 CopyMem (StringBlock
, StringPackage
->StringBlock
, OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
));
1487 // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks
1489 BlockPtr
= StringBlock
+ OldBlockSize
- sizeof (EFI_HII_SIBT_END_BLOCK
);
1490 *BlockPtr
= EFI_HII_SIBT_SKIP2
;
1491 CopyMem (BlockPtr
+ 1, &SkipCount
, sizeof (UINT16
));
1492 BlockPtr
+= sizeof (EFI_HII_SIBT_SKIP2_BLOCK
);
1495 // Append a EFI_HII_SIBT_END block to the end.
1497 *BlockPtr
= EFI_HII_SIBT_END
;
1498 FreePool (StringPackage
->StringBlock
);
1499 StringPackage
->StringBlock
= StringBlock
;
1500 StringPackage
->StringPkgHdr
->Header
.Length
+= Skip2BlockSize
;
1501 PackageList
->PackageListHdr
.PackageLength
+= Skip2BlockSize
;
1502 StringPackage
->MaxStringId
= MaxStringId
;
1510 This function exports String packages to a buffer.
1511 This is a internal function.
1513 @param Private Hii database private structure.
1514 @param Handle Identification of a package list.
1515 @param PackageList Pointer to a package list which will be exported.
1516 @param UsedSize The length of buffer be used.
1517 @param BufferSize Length of the Buffer.
1518 @param Buffer Allocated space for storing exported data.
1519 @param ResultSize The size of the already exported content of this
1522 @retval EFI_SUCCESS String Packages are exported successfully.
1523 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1527 ExportStringPackages (
1528 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1529 IN EFI_HII_HANDLE Handle
,
1530 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1532 IN UINTN BufferSize
,
1533 IN OUT VOID
*Buffer
,
1534 IN OUT UINTN
*ResultSize
1538 UINTN PackageLength
;
1540 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
1542 if (Private
== NULL
|| PackageList
== NULL
|| ResultSize
== NULL
) {
1543 return EFI_INVALID_PARAMETER
;
1546 if (BufferSize
> 0 && Buffer
== NULL
) {
1547 return EFI_INVALID_PARAMETER
;
1551 Status
= EFI_SUCCESS
;
1553 for (Link
= PackageList
->StringPkgHdr
.ForwardLink
; Link
!= &PackageList
->StringPkgHdr
; Link
= Link
->ForwardLink
) {
1554 StringPackage
= CR (Link
, HII_STRING_PACKAGE_INSTANCE
, StringEntry
, HII_STRING_PACKAGE_SIGNATURE
);
1555 PackageLength
+= StringPackage
->StringPkgHdr
->Header
.Length
;
1556 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
1558 // Invoke registered notification function with EXPORT_PACK notify type
1560 Status
= InvokeRegisteredFunction (
1562 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
1563 (VOID
*) StringPackage
,
1564 EFI_HII_PACKAGE_STRINGS
,
1567 ASSERT_EFI_ERROR (Status
);
1569 // Copy String package header
1571 CopyMem (Buffer
, StringPackage
->StringPkgHdr
, StringPackage
->StringPkgHdr
->HdrSize
);
1572 Buffer
= (UINT8
*) Buffer
+ StringPackage
->StringPkgHdr
->HdrSize
;
1575 // Copy String blocks information
1579 StringPackage
->StringBlock
,
1580 StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
1582 Buffer
= (UINT8
*) Buffer
+ StringPackage
->StringPkgHdr
->Header
.Length
- StringPackage
->StringPkgHdr
->HdrSize
;
1586 *ResultSize
+= PackageLength
;
1592 This function deletes all String packages from a package list node.
1593 This is a internal function.
1595 @param Private Hii database private data.
1596 @param Handle Handle of the package list which contains the to
1597 be removed String packages.
1598 @param PackageList Pointer to a package list that contains removing
1601 @retval EFI_SUCCESS String Package(s) is deleted successfully.
1602 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1606 RemoveStringPackages (
1607 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1608 IN EFI_HII_HANDLE Handle
,
1609 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
1612 LIST_ENTRY
*ListHead
;
1613 HII_STRING_PACKAGE_INSTANCE
*Package
;
1614 HII_FONT_INFO
*FontInfo
;
1617 ListHead
= &PackageList
->StringPkgHdr
;
1619 while (!IsListEmpty (ListHead
)) {
1621 ListHead
->ForwardLink
,
1622 HII_STRING_PACKAGE_INSTANCE
,
1624 HII_STRING_PACKAGE_SIGNATURE
1626 Status
= InvokeRegisteredFunction (
1628 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
1630 EFI_HII_PACKAGE_STRINGS
,
1633 if (EFI_ERROR (Status
)) {
1637 RemoveEntryList (&Package
->StringEntry
);
1638 PackageList
->PackageListHdr
.PackageLength
-= Package
->StringPkgHdr
->Header
.Length
;
1639 FreePool (Package
->StringBlock
);
1640 FreePool (Package
->StringPkgHdr
);
1642 // Delete font information
1644 while (!IsListEmpty (&Package
->FontInfoList
)) {
1646 Package
->FontInfoList
.ForwardLink
,
1649 HII_FONT_INFO_SIGNATURE
1651 RemoveEntryList (&FontInfo
->Entry
);
1652 FreePool (FontInfo
);
1663 This function insert a Font package to a package list node.
1664 This is a internal function.
1666 @param Private Hii database private structure.
1667 @param PackageHdr Pointer to a buffer stored with Font package
1669 @param NotifyType The type of change concerning the database.
1670 @param PackageList Pointer to a package list which will be inserted
1672 @param Package Created Font package
1674 @retval EFI_SUCCESS Font Package is inserted successfully.
1675 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
1677 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
1678 @retval EFI_UNSUPPORTED A font package with same EFI_FONT_INFO already
1679 exists in current hii database.
1684 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1685 IN VOID
*PackageHdr
,
1686 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
1687 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1688 OUT HII_FONT_PACKAGE_INSTANCE
**Package
1691 HII_FONT_PACKAGE_INSTANCE
*FontPackage
;
1692 EFI_HII_FONT_PACKAGE_HDR
*FontPkgHdr
;
1695 EFI_HII_PACKAGE_HEADER PackageHeader
;
1696 EFI_FONT_INFO
*FontInfo
;
1697 UINT32 FontInfoSize
;
1698 HII_GLOBAL_FONT_INFO
*GlobalFont
;
1700 if (Private
== NULL
|| PackageHdr
== NULL
|| PackageList
== NULL
) {
1701 return EFI_INVALID_PARAMETER
;
1704 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
1705 CopyMem (&HeaderSize
, (UINT8
*) PackageHdr
+ sizeof (EFI_HII_PACKAGE_HEADER
), sizeof (UINT32
));
1712 // It is illegal to have two font packages with same EFI_FONT_INFO within hii
1713 // database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's
1714 // attributes and identify a font uniquely.
1716 FontPkgHdr
= (EFI_HII_FONT_PACKAGE_HDR
*) AllocateZeroPool (HeaderSize
);
1717 if (FontPkgHdr
== NULL
) {
1718 Status
= EFI_OUT_OF_RESOURCES
;
1721 CopyMem (FontPkgHdr
, PackageHdr
, HeaderSize
);
1723 FontInfoSize
= sizeof (EFI_FONT_INFO
) + HeaderSize
- sizeof (EFI_HII_FONT_PACKAGE_HDR
);
1724 FontInfo
= (EFI_FONT_INFO
*) AllocateZeroPool (FontInfoSize
);
1725 if (FontInfo
== NULL
) {
1726 Status
= EFI_OUT_OF_RESOURCES
;
1729 FontInfo
->FontStyle
= FontPkgHdr
->FontStyle
;
1730 FontInfo
->FontSize
= FontPkgHdr
->Cell
.Height
;
1731 StrCpyS (FontInfo
->FontName
, (FontInfoSize
- OFFSET_OF(EFI_FONT_INFO
,FontName
)) / sizeof (CHAR16
), FontPkgHdr
->FontFamily
);
1733 if (IsFontInfoExisted (Private
, FontInfo
, NULL
, NULL
, NULL
)) {
1734 Status
= EFI_UNSUPPORTED
;
1739 // Create a Font package node
1741 FontPackage
= (HII_FONT_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE
));
1742 if (FontPackage
== NULL
) {
1743 Status
= EFI_OUT_OF_RESOURCES
;
1746 FontPackage
->Signature
= HII_FONT_PACKAGE_SIGNATURE
;
1747 FontPackage
->FontPkgHdr
= FontPkgHdr
;
1748 InitializeListHead (&FontPackage
->GlyphInfoList
);
1750 FontPackage
->GlyphBlock
= (UINT8
*) AllocateZeroPool (PackageHeader
.Length
- HeaderSize
);
1751 if (FontPackage
->GlyphBlock
== NULL
) {
1752 Status
= EFI_OUT_OF_RESOURCES
;
1755 CopyMem (FontPackage
->GlyphBlock
, (UINT8
*) PackageHdr
+ HeaderSize
, PackageHeader
.Length
- HeaderSize
);
1758 // Collect all default character cell information and backup in GlyphInfoList.
1760 Status
= FindGlyphBlock (FontPackage
, (CHAR16
) (-1), NULL
, NULL
, NULL
);
1761 if (EFI_ERROR (Status
)) {
1766 // This font package describes an unique EFI_FONT_INFO. Backup it in global
1769 GlobalFont
= (HII_GLOBAL_FONT_INFO
*) AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO
));
1770 if (GlobalFont
== NULL
) {
1771 Status
= EFI_OUT_OF_RESOURCES
;
1774 GlobalFont
->Signature
= HII_GLOBAL_FONT_INFO_SIGNATURE
;
1775 GlobalFont
->FontPackage
= FontPackage
;
1776 GlobalFont
->FontInfoSize
= FontInfoSize
;
1777 GlobalFont
->FontInfo
= FontInfo
;
1778 InsertTailList (&Private
->FontInfoList
, &GlobalFont
->Entry
);
1781 // Insert this font package to Font package array
1783 InsertTailList (&PackageList
->FontPkgHdr
, &FontPackage
->FontEntry
);
1784 *Package
= FontPackage
;
1786 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
1787 PackageList
->PackageListHdr
.PackageLength
+= FontPackage
->FontPkgHdr
->Header
.Length
;
1794 if (FontPkgHdr
!= NULL
) {
1795 FreePool (FontPkgHdr
);
1797 if (FontInfo
!= NULL
) {
1798 FreePool (FontInfo
);
1800 if (FontPackage
!= NULL
) {
1801 if (FontPackage
->GlyphBlock
!= NULL
) {
1802 FreePool (FontPackage
->GlyphBlock
);
1804 FreePool (FontPackage
);
1806 if (GlobalFont
!= NULL
) {
1807 FreePool (GlobalFont
);
1816 This function exports Font packages to a buffer.
1817 This is a internal function.
1819 @param Private Hii database private structure.
1820 @param Handle Identification of a package list.
1821 @param PackageList Pointer to a package list which will be exported.
1822 @param UsedSize The length of buffer be used.
1823 @param BufferSize Length of the Buffer.
1824 @param Buffer Allocated space for storing exported data.
1825 @param ResultSize The size of the already exported content of this
1828 @retval EFI_SUCCESS Font Packages are exported successfully.
1829 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1833 ExportFontPackages (
1834 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1835 IN EFI_HII_HANDLE Handle
,
1836 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
1838 IN UINTN BufferSize
,
1839 IN OUT VOID
*Buffer
,
1840 IN OUT UINTN
*ResultSize
1844 UINTN PackageLength
;
1846 HII_FONT_PACKAGE_INSTANCE
*Package
;
1849 if (Private
== NULL
|| PackageList
== NULL
|| ResultSize
== NULL
) {
1850 return EFI_INVALID_PARAMETER
;
1853 if (BufferSize
> 0 && Buffer
== NULL
) {
1854 return EFI_INVALID_PARAMETER
;
1858 Status
= EFI_SUCCESS
;
1860 for (Link
= PackageList
->FontPkgHdr
.ForwardLink
; Link
!= &PackageList
->FontPkgHdr
; Link
= Link
->ForwardLink
) {
1861 Package
= CR (Link
, HII_FONT_PACKAGE_INSTANCE
, FontEntry
, HII_FONT_PACKAGE_SIGNATURE
);
1862 PackageLength
+= Package
->FontPkgHdr
->Header
.Length
;
1863 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
1865 // Invoke registered notification function with EXPORT_PACK notify type
1867 Status
= InvokeRegisteredFunction (
1869 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
1871 EFI_HII_PACKAGE_FONTS
,
1874 ASSERT_EFI_ERROR (Status
);
1876 // Copy Font package header
1878 CopyMem (Buffer
, Package
->FontPkgHdr
, Package
->FontPkgHdr
->HdrSize
);
1879 Buffer
= (UINT8
*) Buffer
+ Package
->FontPkgHdr
->HdrSize
;
1882 // Copy Glyph blocks information
1886 Package
->GlyphBlock
,
1887 Package
->FontPkgHdr
->Header
.Length
- Package
->FontPkgHdr
->HdrSize
1889 Buffer
= (UINT8
*) Buffer
+ Package
->FontPkgHdr
->Header
.Length
- Package
->FontPkgHdr
->HdrSize
;
1893 *ResultSize
+= PackageLength
;
1899 This function deletes all Font packages from a package list node.
1900 This is a internal function.
1902 @param Private Hii database private data.
1903 @param Handle Handle of the package list which contains the to
1904 be removed Font packages.
1905 @param PackageList Pointer to a package list that contains removing
1908 @retval EFI_SUCCESS Font Package(s) is deleted successfully.
1909 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
1913 RemoveFontPackages (
1914 IN HII_DATABASE_PRIVATE_DATA
*Private
,
1915 IN EFI_HII_HANDLE Handle
,
1916 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
1919 LIST_ENTRY
*ListHead
;
1920 HII_FONT_PACKAGE_INSTANCE
*Package
;
1922 HII_GLYPH_INFO
*GlyphInfo
;
1924 HII_GLOBAL_FONT_INFO
*GlobalFont
;
1926 ListHead
= &PackageList
->FontPkgHdr
;
1928 while (!IsListEmpty (ListHead
)) {
1930 ListHead
->ForwardLink
,
1931 HII_FONT_PACKAGE_INSTANCE
,
1933 HII_FONT_PACKAGE_SIGNATURE
1935 Status
= InvokeRegisteredFunction (
1937 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
1939 EFI_HII_PACKAGE_FONTS
,
1942 if (EFI_ERROR (Status
)) {
1946 RemoveEntryList (&Package
->FontEntry
);
1947 PackageList
->PackageListHdr
.PackageLength
-= Package
->FontPkgHdr
->Header
.Length
;
1949 if (Package
->GlyphBlock
!= NULL
) {
1950 FreePool (Package
->GlyphBlock
);
1952 FreePool (Package
->FontPkgHdr
);
1954 // Delete default character cell information
1956 while (!IsListEmpty (&Package
->GlyphInfoList
)) {
1958 Package
->GlyphInfoList
.ForwardLink
,
1961 HII_GLYPH_INFO_SIGNATURE
1963 RemoveEntryList (&GlyphInfo
->Entry
);
1964 FreePool (GlyphInfo
);
1968 // Remove corresponding global font info
1970 for (Link
= Private
->FontInfoList
.ForwardLink
; Link
!= &Private
->FontInfoList
; Link
= Link
->ForwardLink
) {
1971 GlobalFont
= CR (Link
, HII_GLOBAL_FONT_INFO
, Entry
, HII_GLOBAL_FONT_INFO_SIGNATURE
);
1972 if (GlobalFont
->FontPackage
== Package
) {
1973 RemoveEntryList (&GlobalFont
->Entry
);
1974 FreePool (GlobalFont
->FontInfo
);
1975 FreePool (GlobalFont
);
1988 This function insert a Image package to a package list node.
1989 This is a internal function.
1991 @param PackageHdr Pointer to a buffer stored with Image package
1993 @param NotifyType The type of change concerning the database.
1994 @param PackageList Pointer to a package list which will be inserted
1996 @param Package Created Image package
1998 @retval EFI_SUCCESS Image Package is inserted successfully.
1999 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2001 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2005 InsertImagePackage (
2006 IN VOID
*PackageHdr
,
2007 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2008 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2009 OUT HII_IMAGE_PACKAGE_INSTANCE
**Package
2012 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
2016 EFI_HII_IMAGE_PALETTE_INFO_HEADER
*PaletteHdr
;
2017 EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
;
2018 UINT32 PaletteInfoOffset
;
2019 UINT32 ImageInfoOffset
;
2022 if (PackageHdr
== NULL
|| PackageList
== NULL
) {
2023 return EFI_INVALID_PARAMETER
;
2027 // Less than one image package is allowed in one package list.
2029 if (PackageList
->ImagePkg
!= NULL
) {
2030 return EFI_INVALID_PARAMETER
;
2034 // Create a Image package node
2036 ImagePackage
= (HII_IMAGE_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE
));
2037 if (ImagePackage
== NULL
) {
2038 return EFI_OUT_OF_RESOURCES
;
2042 // Copy the Image package header.
2044 CopyMem (&ImagePackage
->ImagePkgHdr
, PackageHdr
, sizeof (EFI_HII_IMAGE_PACKAGE_HDR
));
2046 PaletteInfoOffset
= ImagePackage
->ImagePkgHdr
.PaletteInfoOffset
;
2047 ImageInfoOffset
= ImagePackage
->ImagePkgHdr
.ImageInfoOffset
;
2050 // If PaletteInfoOffset is zero, there are no palettes in this image package.
2053 ImagePackage
->PaletteBlock
= NULL
;
2054 if (PaletteInfoOffset
!= 0) {
2055 PaletteHdr
= (EFI_HII_IMAGE_PALETTE_INFO_HEADER
*) ((UINT8
*) PackageHdr
+ PaletteInfoOffset
);
2056 PaletteSize
= sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER
);
2057 PaletteInfo
= (EFI_HII_IMAGE_PALETTE_INFO
*) ((UINT8
*) PaletteHdr
+ PaletteSize
);
2059 for (Index
= 0; Index
< PaletteHdr
->PaletteCount
; Index
++) {
2060 CopyMem (&CurrentSize
, PaletteInfo
, sizeof (UINT16
));
2061 CurrentSize
+= sizeof (UINT16
);
2062 PaletteSize
+= (UINT32
) CurrentSize
;
2063 PaletteInfo
= (EFI_HII_IMAGE_PALETTE_INFO
*) ((UINT8
*) PaletteInfo
+ CurrentSize
);
2066 ImagePackage
->PaletteBlock
= (UINT8
*) AllocateZeroPool (PaletteSize
);
2067 if (ImagePackage
->PaletteBlock
== NULL
) {
2068 FreePool (ImagePackage
);
2069 return EFI_OUT_OF_RESOURCES
;
2072 ImagePackage
->PaletteBlock
,
2073 (UINT8
*) PackageHdr
+ PaletteInfoOffset
,
2079 // If ImageInfoOffset is zero, there are no images in this package.
2082 ImagePackage
->ImageBlock
= NULL
;
2083 if (ImageInfoOffset
!= 0) {
2084 ImageSize
= ImagePackage
->ImagePkgHdr
.Header
.Length
-
2085 sizeof (EFI_HII_IMAGE_PACKAGE_HDR
) - PaletteSize
;
2086 ImagePackage
->ImageBlock
= AllocateZeroPool (ImageSize
);
2087 if (ImagePackage
->ImageBlock
== NULL
) {
2088 FreePool (ImagePackage
->PaletteBlock
);
2089 FreePool (ImagePackage
);
2090 return EFI_OUT_OF_RESOURCES
;
2093 ImagePackage
->ImageBlock
,
2094 (UINT8
*) PackageHdr
+ ImageInfoOffset
,
2099 ImagePackage
->ImageBlockSize
= ImageSize
;
2100 ImagePackage
->PaletteInfoSize
= PaletteSize
;
2101 PackageList
->ImagePkg
= ImagePackage
;
2102 *Package
= ImagePackage
;
2104 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
2105 PackageList
->PackageListHdr
.PackageLength
+= ImagePackage
->ImagePkgHdr
.Header
.Length
;
2113 This function exports Image packages to a buffer.
2114 This is a internal function.
2116 @param Private Hii database private structure.
2117 @param Handle Identification of a package list.
2118 @param PackageList Pointer to a package list which will be exported.
2119 @param UsedSize The length of buffer be used.
2120 @param BufferSize Length of the Buffer.
2121 @param Buffer Allocated space for storing exported data.
2122 @param ResultSize The size of the already exported content of this
2125 @retval EFI_SUCCESS Image Packages are exported successfully.
2126 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2130 ExportImagePackages (
2131 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2132 IN EFI_HII_HANDLE Handle
,
2133 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2135 IN UINTN BufferSize
,
2136 IN OUT VOID
*Buffer
,
2137 IN OUT UINTN
*ResultSize
2140 UINTN PackageLength
;
2142 HII_IMAGE_PACKAGE_INSTANCE
*Package
;
2145 if (Private
== NULL
|| PackageList
== NULL
|| ResultSize
== NULL
) {
2146 return EFI_INVALID_PARAMETER
;
2149 if (BufferSize
> 0 && Buffer
== NULL
) {
2150 return EFI_INVALID_PARAMETER
;
2153 Package
= PackageList
->ImagePkg
;
2155 if (Package
== NULL
) {
2159 PackageLength
= Package
->ImagePkgHdr
.Header
.Length
;
2161 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
2163 // Invoke registered notification function with EXPORT_PACK notify type
2165 Status
= InvokeRegisteredFunction (
2167 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
2169 EFI_HII_PACKAGE_IMAGES
,
2172 ASSERT_EFI_ERROR (Status
);
2173 ASSERT (Package
->ImagePkgHdr
.Header
.Length
==
2174 sizeof (EFI_HII_IMAGE_PACKAGE_HDR
) + Package
->ImageBlockSize
+ Package
->PaletteInfoSize
);
2176 // Copy Image package header,
2177 // then justify the offset for image info and palette info in the header.
2179 CopyMem (Buffer
, &Package
->ImagePkgHdr
, sizeof (EFI_HII_IMAGE_PACKAGE_HDR
));
2180 Buffer
= (UINT8
*) Buffer
+ sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
2183 // Copy Image blocks information
2185 if (Package
->ImageBlockSize
!= 0) {
2186 CopyMem (Buffer
, Package
->ImageBlock
, Package
->ImageBlockSize
);
2187 Buffer
= (UINT8
*) Buffer
+ Package
->ImageBlockSize
;
2190 // Copy Palette information
2192 if (Package
->PaletteInfoSize
!= 0) {
2193 CopyMem (Buffer
, Package
->PaletteBlock
, Package
->PaletteInfoSize
);
2194 Buffer
= (UINT8
*) Buffer
+ Package
->PaletteInfoSize
;
2198 *ResultSize
+= PackageLength
;
2204 This function deletes Image package from a package list node.
2205 This is a internal function.
2207 @param Private Hii database private data.
2208 @param Handle Handle of the package list which contains the to
2209 be removed Image packages.
2210 @param PackageList Package List which contains the to be removed
2213 @retval EFI_SUCCESS Image Package(s) is deleted successfully.
2214 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2218 RemoveImagePackages (
2219 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2220 IN EFI_HII_HANDLE Handle
,
2221 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2224 HII_IMAGE_PACKAGE_INSTANCE
*Package
;
2227 Package
= PackageList
->ImagePkg
;
2230 // Image package does not exist, return directly.
2232 if (Package
== NULL
) {
2236 Status
= InvokeRegisteredFunction (
2238 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2240 EFI_HII_PACKAGE_IMAGES
,
2243 if (EFI_ERROR (Status
)) {
2247 PackageList
->PackageListHdr
.PackageLength
-= Package
->ImagePkgHdr
.Header
.Length
;
2249 FreePool (Package
->ImageBlock
);
2250 if (Package
->PaletteBlock
!= NULL
) {
2251 FreePool (Package
->PaletteBlock
);
2255 PackageList
->ImagePkg
= NULL
;
2262 This function insert a Simple Font package to a package list node.
2263 This is a internal function.
2265 @param PackageHdr Pointer to a buffer stored with Simple Font
2266 package information.
2267 @param NotifyType The type of change concerning the database.
2268 @param PackageList Pointer to a package list which will be inserted
2270 @param Package Created Simple Font package
2272 @retval EFI_SUCCESS Simple Font Package is inserted successfully.
2273 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2274 Simple Font package.
2275 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2279 InsertSimpleFontPackage (
2280 IN VOID
*PackageHdr
,
2281 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2282 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2283 OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE
**Package
2286 HII_SIMPLE_FONT_PACKAGE_INSTANCE
*SimpleFontPackage
;
2288 EFI_HII_PACKAGE_HEADER Header
;
2290 if (PackageHdr
== NULL
|| PackageList
== NULL
) {
2291 return EFI_INVALID_PARAMETER
;
2295 // Create a Simple Font package node
2297 SimpleFontPackage
= AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE
));
2298 if (SimpleFontPackage
== NULL
) {
2299 Status
= EFI_OUT_OF_RESOURCES
;
2302 SimpleFontPackage
->Signature
= HII_S_FONT_PACKAGE_SIGNATURE
;
2305 // Copy the Simple Font package.
2307 CopyMem (&Header
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
2309 SimpleFontPackage
->SimpleFontPkgHdr
= AllocateZeroPool (Header
.Length
);
2310 if (SimpleFontPackage
->SimpleFontPkgHdr
== NULL
) {
2311 Status
= EFI_OUT_OF_RESOURCES
;
2315 CopyMem (SimpleFontPackage
->SimpleFontPkgHdr
, PackageHdr
, Header
.Length
);
2318 // Insert to Simple Font package array
2320 InsertTailList (&PackageList
->SimpleFontPkgHdr
, &SimpleFontPackage
->SimpleFontEntry
);
2321 *Package
= SimpleFontPackage
;
2323 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
2324 PackageList
->PackageListHdr
.PackageLength
+= Header
.Length
;
2331 if (SimpleFontPackage
!= NULL
) {
2332 if (SimpleFontPackage
->SimpleFontPkgHdr
!= NULL
) {
2333 FreePool (SimpleFontPackage
->SimpleFontPkgHdr
);
2335 FreePool (SimpleFontPackage
);
2342 This function exports SimpleFont packages to a buffer.
2343 This is a internal function.
2345 @param Private Hii database private structure.
2346 @param Handle Identification of a package list.
2347 @param PackageList Pointer to a package list which will be exported.
2348 @param UsedSize The length of buffer be used.
2349 @param BufferSize Length of the Buffer.
2350 @param Buffer Allocated space for storing exported data.
2351 @param ResultSize The size of the already exported content of this
2354 @retval EFI_SUCCESS SimpleFont Packages are exported successfully.
2355 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2359 ExportSimpleFontPackages (
2360 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2361 IN EFI_HII_HANDLE Handle
,
2362 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2364 IN UINTN BufferSize
,
2365 IN OUT VOID
*Buffer
,
2366 IN OUT UINTN
*ResultSize
2370 UINTN PackageLength
;
2372 HII_SIMPLE_FONT_PACKAGE_INSTANCE
*Package
;
2374 if (Private
== NULL
|| PackageList
== NULL
|| ResultSize
== NULL
) {
2375 return EFI_INVALID_PARAMETER
;
2378 if (BufferSize
> 0 && Buffer
== NULL
) {
2379 return EFI_INVALID_PARAMETER
;
2383 Status
= EFI_SUCCESS
;
2385 for (Link
= PackageList
->SimpleFontPkgHdr
.ForwardLink
; Link
!= &PackageList
->SimpleFontPkgHdr
; Link
= Link
->ForwardLink
) {
2386 Package
= CR (Link
, HII_SIMPLE_FONT_PACKAGE_INSTANCE
, SimpleFontEntry
, HII_S_FONT_PACKAGE_SIGNATURE
);
2387 PackageLength
+= Package
->SimpleFontPkgHdr
->Header
.Length
;
2388 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
2390 // Invoke registered notification function with EXPORT_PACK notify type
2392 Status
= InvokeRegisteredFunction (
2394 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
2396 EFI_HII_PACKAGE_SIMPLE_FONTS
,
2399 ASSERT_EFI_ERROR (Status
);
2402 // Copy SimpleFont package
2404 CopyMem (Buffer
, Package
->SimpleFontPkgHdr
, Package
->SimpleFontPkgHdr
->Header
.Length
);
2405 Buffer
= (UINT8
*) Buffer
+ Package
->SimpleFontPkgHdr
->Header
.Length
;
2409 *ResultSize
+= PackageLength
;
2415 This function deletes all Simple Font packages from a package list node.
2416 This is a internal function.
2418 @param Private Hii database private data.
2419 @param Handle Handle of the package list which contains the to
2420 be removed Simple Font packages.
2421 @param PackageList Pointer to a package list that contains removing
2424 @retval EFI_SUCCESS Simple Font Package(s) is deleted successfully.
2425 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2429 RemoveSimpleFontPackages (
2430 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2431 IN EFI_HII_HANDLE Handle
,
2432 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2435 LIST_ENTRY
*ListHead
;
2436 HII_SIMPLE_FONT_PACKAGE_INSTANCE
*Package
;
2439 ListHead
= &PackageList
->SimpleFontPkgHdr
;
2441 while (!IsListEmpty (ListHead
)) {
2443 ListHead
->ForwardLink
,
2444 HII_SIMPLE_FONT_PACKAGE_INSTANCE
,
2446 HII_S_FONT_PACKAGE_SIGNATURE
2448 Status
= InvokeRegisteredFunction (
2450 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2452 EFI_HII_PACKAGE_SIMPLE_FONTS
,
2455 if (EFI_ERROR (Status
)) {
2459 RemoveEntryList (&Package
->SimpleFontEntry
);
2460 PackageList
->PackageListHdr
.PackageLength
-= Package
->SimpleFontPkgHdr
->Header
.Length
;
2461 FreePool (Package
->SimpleFontPkgHdr
);
2470 This function insert a Device path package to a package list node.
2471 This is a internal function.
2473 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
2475 @param NotifyType The type of change concerning the database.
2476 @param PackageList Pointer to a package list which will be inserted
2479 @retval EFI_SUCCESS Device path Package is inserted successfully.
2480 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2481 Device path package.
2482 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
2486 InsertDevicePathPackage (
2487 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
2488 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2489 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2492 UINT32 PackageLength
;
2493 EFI_HII_PACKAGE_HEADER Header
;
2495 if (DevicePath
== NULL
|| PackageList
== NULL
) {
2496 return EFI_INVALID_PARAMETER
;
2499 // Less than one device path package is allowed in one package list.
2501 if (PackageList
->DevicePathPkg
!= NULL
) {
2502 return EFI_INVALID_PARAMETER
;
2505 PackageLength
= (UINT32
) GetDevicePathSize (DevicePath
) + sizeof (EFI_HII_PACKAGE_HEADER
);
2506 PackageList
->DevicePathPkg
= (UINT8
*) AllocateZeroPool (PackageLength
);
2507 if (PackageList
->DevicePathPkg
== NULL
) {
2508 return EFI_OUT_OF_RESOURCES
;
2511 Header
.Length
= PackageLength
;
2512 Header
.Type
= EFI_HII_PACKAGE_DEVICE_PATH
;
2513 CopyMem (PackageList
->DevicePathPkg
, &Header
, sizeof (EFI_HII_PACKAGE_HEADER
));
2515 PackageList
->DevicePathPkg
+ sizeof (EFI_HII_PACKAGE_HEADER
),
2517 PackageLength
- sizeof (EFI_HII_PACKAGE_HEADER
)
2521 // Since Device Path package is created by NewPackageList, either NEW_PACK
2522 // or ADD_PACK should increase the length of package list.
2524 PackageList
->PackageListHdr
.PackageLength
+= PackageLength
;
2530 This function exports device path package to a buffer.
2531 This is a internal function.
2533 @param Private Hii database private structure.
2534 @param Handle Identification of a package list.
2535 @param PackageList Pointer to a package list which will be exported.
2536 @param UsedSize The length of buffer be used.
2537 @param BufferSize Length of the Buffer.
2538 @param Buffer Allocated space for storing exported data.
2539 @param ResultSize The size of the already exported content of this
2542 @retval EFI_SUCCESS Device path Package is exported successfully.
2543 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2547 ExportDevicePathPackage (
2548 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2549 IN EFI_HII_HANDLE Handle
,
2550 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2552 IN UINTN BufferSize
,
2553 IN OUT VOID
*Buffer
,
2554 IN OUT UINTN
*ResultSize
2559 EFI_HII_PACKAGE_HEADER Header
;
2561 if (Private
== NULL
|| PackageList
== NULL
|| ResultSize
== NULL
) {
2562 return EFI_INVALID_PARAMETER
;
2564 if (BufferSize
> 0 && Buffer
== NULL
) {
2565 return EFI_INVALID_PARAMETER
;
2568 Package
= PackageList
->DevicePathPkg
;
2570 if (Package
== NULL
) {
2574 CopyMem (&Header
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2576 if (Header
.Length
+ *ResultSize
+ UsedSize
<= BufferSize
) {
2578 // Invoke registered notification function with EXPORT_PACK notify type
2580 Status
= InvokeRegisteredFunction (
2582 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
2584 EFI_HII_PACKAGE_DEVICE_PATH
,
2587 ASSERT_EFI_ERROR (Status
);
2590 // Copy Device path package
2592 CopyMem (Buffer
, Package
, Header
.Length
);
2595 *ResultSize
+= Header
.Length
;
2601 This function deletes Device Path package from a package list node.
2602 This is a internal function.
2604 @param Private Hii database private data.
2605 @param Handle Handle of the package list.
2606 @param PackageList Package List which contains the to be removed
2607 Device Path package.
2609 @retval EFI_SUCCESS Device Path Package is deleted successfully.
2610 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2614 RemoveDevicePathPackage (
2615 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2616 IN EFI_HII_HANDLE Handle
,
2617 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2622 EFI_HII_PACKAGE_HEADER Header
;
2624 Package
= PackageList
->DevicePathPkg
;
2627 // No device path, return directly.
2629 if (Package
== NULL
) {
2633 Status
= InvokeRegisteredFunction (
2635 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2637 EFI_HII_PACKAGE_DEVICE_PATH
,
2640 if (EFI_ERROR (Status
)) {
2644 CopyMem (&Header
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2645 PackageList
->PackageListHdr
.PackageLength
-= Header
.Length
;
2649 PackageList
->DevicePathPkg
= NULL
;
2656 This function will insert a device path package to package list firstly then
2657 invoke notification functions if any.
2658 This is a internal function.
2660 @param Private Hii database private structure.
2661 @param NotifyType The type of change concerning the database.
2662 @param DevicePath Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
2664 @param DatabaseRecord Pointer to a database record contains a package
2665 list which will be inserted to.
2667 @retval EFI_SUCCESS Device path Package is inserted successfully.
2668 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2669 Device path package.
2670 @retval EFI_INVALID_PARAMETER DevicePath is NULL or PackageList is NULL.
2674 AddDevicePathPackage (
2675 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2676 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2677 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
2678 IN OUT HII_DATABASE_RECORD
*DatabaseRecord
2683 if (DevicePath
== NULL
) {
2687 ASSERT (Private
!= NULL
);
2688 ASSERT (DatabaseRecord
!= NULL
);
2691 // Create a device path package and insert to packagelist
2693 Status
= InsertDevicePathPackage (
2696 DatabaseRecord
->PackageList
2698 if (EFI_ERROR (Status
)) {
2702 return InvokeRegisteredFunction (
2705 (VOID
*) DatabaseRecord
->PackageList
->DevicePathPkg
,
2706 EFI_HII_PACKAGE_DEVICE_PATH
,
2707 DatabaseRecord
->Handle
2713 This function insert a Keyboard Layout package to a package list node.
2714 This is a internal function.
2716 @param PackageHdr Pointer to a buffer stored with Keyboard Layout
2717 package information.
2718 @param NotifyType The type of change concerning the database.
2719 @param PackageList Pointer to a package list which will be inserted
2721 @param Package Created Keyboard Layout package
2723 @retval EFI_SUCCESS Keyboard Layout Package is inserted successfully.
2724 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2725 Keyboard Layout package.
2726 @retval EFI_INVALID_PARAMETER PackageHdr is NULL or PackageList is NULL.
2730 InsertKeyboardLayoutPackage (
2731 IN VOID
*PackageHdr
,
2732 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2733 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2734 OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
**Package
2737 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*KeyboardLayoutPackage
;
2738 EFI_HII_PACKAGE_HEADER PackageHeader
;
2741 if (PackageHdr
== NULL
|| PackageList
== NULL
) {
2742 return EFI_INVALID_PARAMETER
;
2745 CopyMem (&PackageHeader
, PackageHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
2748 // Create a Keyboard Layout package node
2750 KeyboardLayoutPackage
= AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
));
2751 if (KeyboardLayoutPackage
== NULL
) {
2752 Status
= EFI_OUT_OF_RESOURCES
;
2755 KeyboardLayoutPackage
->Signature
= HII_KB_LAYOUT_PACKAGE_SIGNATURE
;
2757 KeyboardLayoutPackage
->KeyboardPkg
= (UINT8
*) AllocateZeroPool (PackageHeader
.Length
);
2758 if (KeyboardLayoutPackage
->KeyboardPkg
== NULL
) {
2759 Status
= EFI_OUT_OF_RESOURCES
;
2763 CopyMem (KeyboardLayoutPackage
->KeyboardPkg
, PackageHdr
, PackageHeader
.Length
);
2764 InsertTailList (&PackageList
->KeyboardLayoutHdr
, &KeyboardLayoutPackage
->KeyboardEntry
);
2766 *Package
= KeyboardLayoutPackage
;
2768 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
2769 PackageList
->PackageListHdr
.PackageLength
+= PackageHeader
.Length
;
2777 if (KeyboardLayoutPackage
!= NULL
) {
2778 if (KeyboardLayoutPackage
->KeyboardPkg
!= NULL
) {
2779 FreePool (KeyboardLayoutPackage
->KeyboardPkg
);
2781 FreePool (KeyboardLayoutPackage
);
2789 This function exports Keyboard Layout packages to a buffer.
2790 This is a internal function.
2792 @param Private Hii database private structure.
2793 @param Handle Identification of a package list.
2794 @param PackageList Pointer to a package list which will be exported.
2795 @param UsedSize The length of buffer be used.
2796 @param BufferSize Length of the Buffer.
2797 @param Buffer Allocated space for storing exported data.
2798 @param ResultSize The size of the already exported content of this
2801 @retval EFI_SUCCESS Keyboard Layout Packages are exported
2803 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2807 ExportKeyboardLayoutPackages (
2808 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2809 IN EFI_HII_HANDLE Handle
,
2810 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
2812 IN UINTN BufferSize
,
2813 IN OUT VOID
*Buffer
,
2814 IN OUT UINTN
*ResultSize
2818 UINTN PackageLength
;
2820 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*Package
;
2821 EFI_HII_PACKAGE_HEADER PackageHeader
;
2823 if (Private
== NULL
|| PackageList
== NULL
|| ResultSize
== NULL
) {
2824 return EFI_INVALID_PARAMETER
;
2827 if (BufferSize
> 0 && Buffer
== NULL
) {
2828 return EFI_INVALID_PARAMETER
;
2832 Status
= EFI_SUCCESS
;
2834 for (Link
= PackageList
->KeyboardLayoutHdr
.ForwardLink
; Link
!= &PackageList
->KeyboardLayoutHdr
; Link
= Link
->ForwardLink
) {
2835 Package
= CR (Link
, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
, KeyboardEntry
, HII_KB_LAYOUT_PACKAGE_SIGNATURE
);
2836 CopyMem (&PackageHeader
, Package
->KeyboardPkg
, sizeof (EFI_HII_PACKAGE_HEADER
));
2837 PackageLength
+= PackageHeader
.Length
;
2838 if (PackageLength
+ *ResultSize
+ UsedSize
<= BufferSize
) {
2840 // Invoke registered notification function with EXPORT_PACK notify type
2842 Status
= InvokeRegisteredFunction (
2844 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK
,
2845 (EFI_HII_PACKAGE_HEADER
*) Package
,
2846 EFI_HII_PACKAGE_KEYBOARD_LAYOUT
,
2849 ASSERT_EFI_ERROR (Status
);
2852 // Copy Keyboard Layout package
2854 CopyMem (Buffer
, Package
->KeyboardPkg
, PackageHeader
.Length
);
2855 Buffer
= (UINT8
*) Buffer
+ PackageHeader
.Length
;
2859 *ResultSize
+= PackageLength
;
2865 This function deletes all Keyboard Layout packages from a package list node.
2866 This is a internal function.
2868 @param Private Hii database private data.
2869 @param Handle Handle of the package list which contains the to
2870 be removed Keyboard Layout packages.
2871 @param PackageList Pointer to a package list that contains removing
2874 @retval EFI_SUCCESS Keyboard Layout Package(s) is deleted
2876 @retval EFI_INVALID_PARAMETER Any input parameter is not valid.
2880 RemoveKeyboardLayoutPackages (
2881 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2882 IN EFI_HII_HANDLE Handle
,
2883 IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
2886 LIST_ENTRY
*ListHead
;
2887 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*Package
;
2888 EFI_HII_PACKAGE_HEADER PackageHeader
;
2891 ListHead
= &PackageList
->KeyboardLayoutHdr
;
2893 while (!IsListEmpty (ListHead
)) {
2895 ListHead
->ForwardLink
,
2896 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
,
2898 HII_KB_LAYOUT_PACKAGE_SIGNATURE
2900 Status
= InvokeRegisteredFunction (
2902 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2904 EFI_HII_PACKAGE_KEYBOARD_LAYOUT
,
2907 if (EFI_ERROR (Status
)) {
2911 RemoveEntryList (&Package
->KeyboardEntry
);
2912 CopyMem (&PackageHeader
, Package
->KeyboardPkg
, sizeof (EFI_HII_PACKAGE_HEADER
));
2913 PackageList
->PackageListHdr
.PackageLength
-= PackageHeader
.Length
;
2914 FreePool (Package
->KeyboardPkg
);
2923 This function will insert a package list to hii database firstly then
2924 invoke notification functions if any. It is the worker function of
2925 HiiNewPackageList and HiiUpdatePackageList.
2927 This is a internal function.
2929 @param Private Hii database private structure.
2930 @param NotifyType The type of change concerning the database.
2931 @param PackageList Pointer to a package list.
2932 @param DatabaseRecord Pointer to a database record contains a package
2933 list instance which will be inserted to.
2935 @retval EFI_SUCCESS All incoming packages are inserted to current
2937 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
2938 Device path package.
2939 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
2944 IN HII_DATABASE_PRIVATE_DATA
*Private
,
2945 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
2946 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*PackageList
,
2947 IN OUT HII_DATABASE_RECORD
*DatabaseRecord
2951 HII_GUID_PACKAGE_INSTANCE
*GuidPackage
;
2952 HII_IFR_PACKAGE_INSTANCE
*FormPackage
;
2953 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*KeyboardLayoutPackage
;
2954 HII_STRING_PACKAGE_INSTANCE
*StringPackage
;
2955 HII_FONT_PACKAGE_INSTANCE
*FontPackage
;
2956 HII_SIMPLE_FONT_PACKAGE_INSTANCE
*SimpleFontPackage
;
2957 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
2958 EFI_HII_PACKAGE_HEADER
*PackageHdrPtr
;
2959 EFI_HII_PACKAGE_HEADER PackageHeader
;
2960 UINT32 OldPackageListLen
;
2961 BOOLEAN StringPkgIsAdd
;
2964 // Initialize Variables
2966 StringPkgIsAdd
= FALSE
;
2968 StringPackage
= NULL
;
2971 ImagePackage
= NULL
;
2972 SimpleFontPackage
= NULL
;
2973 KeyboardLayoutPackage
= NULL
;
2976 // Process the package list header
2978 OldPackageListLen
= DatabaseRecord
->PackageList
->PackageListHdr
.PackageLength
;
2980 &DatabaseRecord
->PackageList
->PackageListHdr
,
2981 (VOID
*) PackageList
,
2982 sizeof (EFI_HII_PACKAGE_LIST_HEADER
)
2984 if (NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK
) {
2985 DatabaseRecord
->PackageList
->PackageListHdr
.PackageLength
= OldPackageListLen
;
2988 PackageHdrPtr
= (EFI_HII_PACKAGE_HEADER
*) ((UINT8
*) PackageList
+ sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
2989 CopyMem (&PackageHeader
, PackageHdrPtr
, sizeof (EFI_HII_PACKAGE_HEADER
));
2991 Status
= EFI_SUCCESS
;
2993 while (PackageHeader
.Type
!= EFI_HII_PACKAGE_END
) {
2994 switch (PackageHeader
.Type
) {
2995 case EFI_HII_PACKAGE_TYPE_GUID
:
2996 Status
= InsertGuidPackage (
2999 DatabaseRecord
->PackageList
,
3002 if (EFI_ERROR (Status
)) {
3005 Status
= InvokeRegisteredFunction (
3008 (VOID
*) GuidPackage
,
3009 (UINT8
) (PackageHeader
.Type
),
3010 DatabaseRecord
->Handle
3013 case EFI_HII_PACKAGE_FORMS
:
3014 Status
= InsertFormPackage (
3017 DatabaseRecord
->PackageList
,
3020 if (EFI_ERROR (Status
)) {
3023 Status
= InvokeRegisteredFunction (
3026 (VOID
*) FormPackage
,
3027 (UINT8
) (PackageHeader
.Type
),
3028 DatabaseRecord
->Handle
3031 // If Hii runtime support feature is enabled,
3032 // will export Hii info for runtime use after ReadyToBoot event triggered.
3033 // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
3034 // will need to export the content of HiiDatabase.
3035 // But if form packages added/updated, also need to export the ConfigResp string.
3037 if (gExportAfterReadyToBoot
) {
3038 gExportConfigResp
= TRUE
;
3041 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
3042 Status
= InsertKeyboardLayoutPackage (
3045 DatabaseRecord
->PackageList
,
3046 &KeyboardLayoutPackage
3048 if (EFI_ERROR (Status
)) {
3051 Status
= InvokeRegisteredFunction (
3054 (VOID
*) KeyboardLayoutPackage
,
3055 (UINT8
) (PackageHeader
.Type
),
3056 DatabaseRecord
->Handle
3059 case EFI_HII_PACKAGE_STRINGS
:
3060 Status
= InsertStringPackage (
3064 DatabaseRecord
->PackageList
,
3067 if (EFI_ERROR (Status
)) {
3070 ASSERT (StringPackage
!= NULL
);
3071 Status
= InvokeRegisteredFunction (
3074 (VOID
*) StringPackage
,
3075 (UINT8
) (PackageHeader
.Type
),
3076 DatabaseRecord
->Handle
3078 StringPkgIsAdd
= TRUE
;
3080 case EFI_HII_PACKAGE_FONTS
:
3081 Status
= InsertFontPackage (
3085 DatabaseRecord
->PackageList
,
3088 if (EFI_ERROR (Status
)) {
3091 Status
= InvokeRegisteredFunction (
3094 (VOID
*) FontPackage
,
3095 (UINT8
) (PackageHeader
.Type
),
3096 DatabaseRecord
->Handle
3099 case EFI_HII_PACKAGE_IMAGES
:
3100 Status
= InsertImagePackage (
3103 DatabaseRecord
->PackageList
,
3106 if (EFI_ERROR (Status
)) {
3109 Status
= InvokeRegisteredFunction (
3112 (VOID
*) ImagePackage
,
3113 (UINT8
) (PackageHeader
.Type
),
3114 DatabaseRecord
->Handle
3117 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
3118 Status
= InsertSimpleFontPackage (
3121 DatabaseRecord
->PackageList
,
3124 if (EFI_ERROR (Status
)) {
3127 Status
= InvokeRegisteredFunction (
3130 (VOID
*) SimpleFontPackage
,
3131 (UINT8
) (PackageHeader
.Type
),
3132 DatabaseRecord
->Handle
3135 case EFI_HII_PACKAGE_DEVICE_PATH
:
3136 Status
= AddDevicePathPackage (
3139 (EFI_DEVICE_PATH_PROTOCOL
*) ((UINT8
*) PackageHdrPtr
+ sizeof (EFI_HII_PACKAGE_HEADER
)),
3147 if (EFI_ERROR (Status
)) {
3151 // goto header of next package
3153 PackageHdrPtr
= (EFI_HII_PACKAGE_HEADER
*) ((UINT8
*) PackageHdrPtr
+ PackageHeader
.Length
);
3154 CopyMem (&PackageHeader
, PackageHdrPtr
, sizeof (EFI_HII_PACKAGE_HEADER
));
3158 // Adjust String Package to make sure all string packages have the same max string ID.
3160 if (!EFI_ERROR (Status
) && StringPkgIsAdd
) {
3161 Status
= AdjustStringPackage (DatabaseRecord
->PackageList
);
3169 This function exports a package list to a buffer. It is the worker function
3170 of HiiExportPackageList.
3172 This is a internal function.
3174 @param Private Hii database private structure.
3175 @param Handle Identification of a package list.
3176 @param PackageList Pointer to a package list which will be exported.
3177 @param UsedSize The length of buffer has been used by exporting
3178 package lists when Handle is NULL.
3179 @param BufferSize Length of the Buffer.
3180 @param Buffer Allocated space for storing exported data.
3182 @retval EFI_SUCCESS Keyboard Layout Packages are exported
3184 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
3189 IN HII_DATABASE_PRIVATE_DATA
*Private
,
3190 IN EFI_HII_HANDLE Handle
,
3191 IN HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
,
3192 IN OUT UINTN
*UsedSize
,
3193 IN UINTN BufferSize
,
3194 OUT EFI_HII_PACKAGE_LIST_HEADER
*Buffer
3199 EFI_HII_PACKAGE_HEADER EndofPackageList
;
3201 ASSERT (Private
!= NULL
&& PackageList
!= NULL
&& UsedSize
!= NULL
);
3202 ASSERT (Private
->Signature
== HII_DATABASE_PRIVATE_DATA_SIGNATURE
);
3203 ASSERT (IsHiiHandleValid (Handle
));
3205 if (BufferSize
> 0 && Buffer
== NULL
) {
3206 return EFI_INVALID_PARAMETER
;
3210 // Copy the package list header
3211 // ResultSize indicates the length of the exported bytes of this package list
3213 ResultSize
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
3214 if (ResultSize
+ *UsedSize
<= BufferSize
) {
3215 CopyMem ((VOID
*) Buffer
, PackageList
, ResultSize
);
3218 // Copy the packages and invoke EXPORT_PACK notify functions if exists.
3220 Status
= ExportGuidPackages (
3226 (VOID
*) ((UINT8
*) Buffer
+ ResultSize
),
3229 if (EFI_ERROR (Status
)) {
3232 Status
= ExportFormPackages (
3238 (VOID
*) ((UINT8
*) Buffer
+ ResultSize
),
3241 if (EFI_ERROR (Status
)) {
3244 Status
= ExportKeyboardLayoutPackages (
3250 (VOID
*) ((UINT8
*) Buffer
+ ResultSize
),
3253 if (EFI_ERROR (Status
)) {
3256 Status
= ExportStringPackages (
3262 (VOID
*) ((UINT8
*) Buffer
+ ResultSize
),
3265 if (EFI_ERROR (Status
)) {
3268 Status
= ExportFontPackages (
3274 (VOID
*) ((UINT8
*) Buffer
+ ResultSize
),
3277 if (EFI_ERROR (Status
)) {
3280 Status
= ExportImagePackages (
3286 (VOID
*) ((UINT8
*) Buffer
+ ResultSize
),
3289 if (EFI_ERROR (Status
)) {
3292 Status
= ExportSimpleFontPackages (
3298 (VOID
*) ((UINT8
*) Buffer
+ ResultSize
),
3301 if (EFI_ERROR (Status
)) {
3304 Status
= ExportDevicePathPackage (
3310 (VOID
*) ((UINT8
*) Buffer
+ ResultSize
),
3313 if (EFI_ERROR (Status
)) {
3317 // Append the package list end.
3319 EndofPackageList
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
3320 EndofPackageList
.Type
= EFI_HII_PACKAGE_END
;
3321 if (ResultSize
+ *UsedSize
+ sizeof (EFI_HII_PACKAGE_HEADER
) <= BufferSize
) {
3323 (VOID
*) ((UINT8
*) Buffer
+ ResultSize
),
3324 (VOID
*) &EndofPackageList
,
3325 sizeof (EFI_HII_PACKAGE_HEADER
)
3329 *UsedSize
+= ResultSize
+ sizeof (EFI_HII_PACKAGE_HEADER
);
3335 This function mainly use to get and update ConfigResp string.
3337 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
3339 @retval EFI_SUCCESS Get the information successfully.
3340 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the Configuration Setting data.
3344 HiiGetConfigRespInfo(
3345 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
3349 HII_DATABASE_PRIVATE_DATA
*Private
;
3350 EFI_STRING ConfigAltResp
;
3353 ConfigAltResp
= NULL
;
3356 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
3359 // Get ConfigResp string
3361 Status
= HiiConfigRoutingExportConfig(&Private
->ConfigRouting
,&ConfigAltResp
);
3363 if (!EFI_ERROR (Status
)){
3364 ConfigSize
= StrSize(ConfigAltResp
);
3365 if (ConfigSize
> gConfigRespSize
){
3367 // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
3368 // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
3370 gConfigRespSize
= ConfigSize
+ (ConfigSize
>> 2);
3371 if (gRTConfigRespBuffer
!= NULL
){
3372 FreePool(gRTConfigRespBuffer
);
3373 DEBUG ((DEBUG_WARN
, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
3375 gRTConfigRespBuffer
= (EFI_STRING
) AllocateRuntimeZeroPool (gConfigRespSize
);
3376 if (gRTConfigRespBuffer
== NULL
){
3377 FreePool(ConfigAltResp
);
3378 DEBUG ((DEBUG_ERROR
, "[HiiDatabase]: No enough memory resource to store the ConfigResp string.\n"));
3379 return EFI_OUT_OF_RESOURCES
;
3382 ZeroMem(gRTConfigRespBuffer
,gConfigRespSize
);
3384 CopyMem(gRTConfigRespBuffer
,ConfigAltResp
,ConfigSize
);
3385 gBS
->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid
, gRTConfigRespBuffer
);
3386 FreePool(ConfigAltResp
);
3394 This is an internal function,mainly use to get HiiDatabase information.
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 Hiidatabase data.
3404 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
3408 EFI_HII_PACKAGE_LIST_HEADER
*DatabaseInfo
;
3409 UINTN DatabaseInfoSize
;
3411 DatabaseInfo
= NULL
;
3412 DatabaseInfoSize
= 0;
3415 // Get HiiDatabase information.
3417 Status
= HiiExportPackageLists(This
, NULL
, &DatabaseInfoSize
, DatabaseInfo
);
3419 ASSERT(Status
== EFI_BUFFER_TOO_SMALL
);
3421 if(DatabaseInfoSize
> gDatabaseInfoSize
) {
3423 // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
3424 // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
3426 gDatabaseInfoSize
= DatabaseInfoSize
+ (DatabaseInfoSize
>> 2);
3427 if (gRTDatabaseInfoBuffer
!= NULL
){
3428 FreePool(gRTDatabaseInfoBuffer
);
3429 DEBUG ((DEBUG_WARN
, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
3431 gRTDatabaseInfoBuffer
= AllocateRuntimeZeroPool (gDatabaseInfoSize
);
3432 if (gRTDatabaseInfoBuffer
== NULL
){
3433 DEBUG ((DEBUG_ERROR
, "[HiiDatabase]: No enough memory resource to store the HiiDatabase info.\n"));
3434 return EFI_OUT_OF_RESOURCES
;
3437 ZeroMem(gRTDatabaseInfoBuffer
,gDatabaseInfoSize
);
3439 Status
= HiiExportPackageLists(This
, NULL
, &DatabaseInfoSize
, gRTDatabaseInfoBuffer
);
3440 ASSERT_EFI_ERROR (Status
);
3441 gBS
->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid
, gRTDatabaseInfoBuffer
);
3448 This function adds the packages in the package list to the database and returns a handle. If there is a
3449 EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will
3450 create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.
3452 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3454 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
3456 @param DriverHandle Associate the package list with this EFI handle.
3457 If a NULL is specified, this data will not be associate
3458 with any drivers and cannot have a callback induced.
3459 @param Handle A pointer to the EFI_HII_HANDLE instance.
3461 @retval EFI_SUCCESS The package list associated with the Handle was
3462 added to the HII database.
3463 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary resources for the new
3465 @retval EFI_INVALID_PARAMETER PackageList is NULL or Handle is NULL.
3466 @retval EFI_INVALID_PARAMETER PackageListGuid already exists in database.
3472 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
3473 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*PackageList
,
3474 IN CONST EFI_HANDLE DriverHandle
, OPTIONAL
3475 OUT EFI_HII_HANDLE
*Handle
3479 HII_DATABASE_PRIVATE_DATA
*Private
;
3480 HII_DATABASE_RECORD
*DatabaseRecord
;
3481 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
3483 EFI_GUID PackageListGuid
;
3485 if (This
== NULL
|| PackageList
== NULL
|| Handle
== NULL
) {
3486 return EFI_INVALID_PARAMETER
;
3489 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
3490 CopyMem (&PackageListGuid
, (VOID
*) PackageList
, sizeof (EFI_GUID
));
3493 // Check the Package list GUID to guarantee this GUID is unique in database.
3495 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
3496 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
3498 &(DatabaseRecord
->PackageList
->PackageListHdr
.PackageListGuid
),
3499 &PackageListGuid
) &&
3500 DatabaseRecord
->DriverHandle
== DriverHandle
) {
3501 return EFI_INVALID_PARAMETER
;
3505 EfiAcquireLock (&mHiiDatabaseLock
);
3508 // Build a PackageList node
3510 Status
= GenerateHiiDatabaseRecord (Private
, &DatabaseRecord
);
3511 if (EFI_ERROR (Status
)) {
3512 EfiReleaseLock (&mHiiDatabaseLock
);
3517 // Fill in information of the created Package List node
3518 // according to incoming package list.
3520 Status
= AddPackages (Private
, EFI_HII_DATABASE_NOTIFY_NEW_PACK
, PackageList
, DatabaseRecord
);
3521 if (EFI_ERROR (Status
)) {
3522 EfiReleaseLock (&mHiiDatabaseLock
);
3526 DatabaseRecord
->DriverHandle
= DriverHandle
;
3529 // Create a Device path package and add into the package list if exists.
3531 Status
= gBS
->HandleProtocol (
3533 &gEfiDevicePathProtocolGuid
,
3534 (VOID
**) &DevicePath
3536 if (!EFI_ERROR (Status
)) {
3537 Status
= AddDevicePathPackage (Private
, EFI_HII_DATABASE_NOTIFY_NEW_PACK
, DevicePath
, DatabaseRecord
);
3538 ASSERT_EFI_ERROR (Status
);
3541 *Handle
= DatabaseRecord
->Handle
;
3544 // Check whether need to get the Database info.
3545 // Only after ReadyToBoot, need to do the export.
3547 if (gExportAfterReadyToBoot
) {
3548 HiiGetDatabaseInfo (This
);
3550 EfiReleaseLock (&mHiiDatabaseLock
);
3554 // HiiGetDatabaseInfo () will get the contents of HII data base,
3555 // belong to the atomic behavior of Hii Database update.
3556 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
3557 // we can not think it belong to the atomic behavior of Hii Database update.
3558 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
3561 // Check whether need to get the configuration setting info from HII drivers.
3562 // When after ReadyToBoot and need to do the export for form package add.
3564 if (gExportAfterReadyToBoot
&& gExportConfigResp
) {
3565 HiiGetConfigRespInfo (This
);
3573 This function removes the package list that is associated with Handle
3574 from the HII database. Before removing the package, any registered functions
3575 with the notification type REMOVE_PACK and the same package type will be called.
3577 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3579 @param Handle The handle that was registered to the data that is
3580 requested for removal.
3582 @retval EFI_SUCCESS The data associated with the Handle was removed
3583 from the HII database.
3584 @retval EFI_NOT_FOUND The specified handle is not in database.
3585 @retval EFI_INVALID_PARAMETER The Handle was not valid.
3590 HiiRemovePackageList (
3591 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
3592 IN EFI_HII_HANDLE Handle
3596 HII_DATABASE_PRIVATE_DATA
*Private
;
3598 HII_DATABASE_RECORD
*Node
;
3599 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
3600 HII_HANDLE
*HiiHandle
;
3603 return EFI_INVALID_PARAMETER
;
3606 if (!IsHiiHandleValid (Handle
)) {
3607 return EFI_NOT_FOUND
;
3610 EfiAcquireLock (&mHiiDatabaseLock
);
3612 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
3615 // Get the packagelist to be removed.
3617 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
3618 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
3619 if (Node
->Handle
== Handle
) {
3620 PackageList
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (Node
->PackageList
);
3621 ASSERT (PackageList
!= NULL
);
3624 // Call registered functions with REMOVE_PACK before removing packages
3625 // then remove them.
3627 Status
= RemoveGuidPackages (Private
, Handle
, PackageList
);
3628 if (EFI_ERROR (Status
)) {
3629 EfiReleaseLock (&mHiiDatabaseLock
);
3632 Status
= RemoveFormPackages (Private
, Handle
, PackageList
);
3633 if (EFI_ERROR (Status
)) {
3634 EfiReleaseLock (&mHiiDatabaseLock
);
3637 Status
= RemoveKeyboardLayoutPackages (Private
, Handle
, PackageList
);
3638 if (EFI_ERROR (Status
)) {
3639 EfiReleaseLock (&mHiiDatabaseLock
);
3642 Status
= RemoveStringPackages (Private
, Handle
, PackageList
);
3643 if (EFI_ERROR (Status
)) {
3644 EfiReleaseLock (&mHiiDatabaseLock
);
3647 Status
= RemoveFontPackages (Private
, Handle
, PackageList
);
3648 if (EFI_ERROR (Status
)) {
3649 EfiReleaseLock (&mHiiDatabaseLock
);
3652 Status
= RemoveImagePackages (Private
, Handle
, PackageList
);
3653 if (EFI_ERROR (Status
)) {
3654 EfiReleaseLock (&mHiiDatabaseLock
);
3657 Status
= RemoveSimpleFontPackages (Private
, Handle
, PackageList
);
3658 if (EFI_ERROR (Status
)) {
3659 EfiReleaseLock (&mHiiDatabaseLock
);
3662 Status
= RemoveDevicePathPackage (Private
, Handle
, PackageList
);
3663 if (EFI_ERROR (Status
)) {
3664 EfiReleaseLock (&mHiiDatabaseLock
);
3669 // Free resources of the package list
3671 RemoveEntryList (&Node
->DatabaseEntry
);
3673 HiiHandle
= (HII_HANDLE
*) Handle
;
3674 RemoveEntryList (&HiiHandle
->Handle
);
3675 Private
->HiiHandleCount
--;
3676 ASSERT (Private
->HiiHandleCount
>= 0);
3678 HiiHandle
->Signature
= 0;
3679 FreePool (HiiHandle
);
3680 FreePool (Node
->PackageList
);
3684 // Check whether need to get the Database info.
3685 // Only after ReadyToBoot, need to do the export.
3687 if (gExportAfterReadyToBoot
) {
3688 HiiGetDatabaseInfo (This
);
3690 EfiReleaseLock (&mHiiDatabaseLock
);
3694 // HiiGetDatabaseInfo () will get the contents of HII data base,
3695 // belong to the atomic behavior of Hii Database update.
3696 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
3697 // we can not think it belong to the atomic behavior of Hii Database update.
3698 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
3702 // Check whether need to get the configuration setting info from HII drivers.
3703 // When after ReadyToBoot and need to do the export for form package remove.
3705 if (gExportAfterReadyToBoot
&& gExportConfigResp
) {
3706 HiiGetConfigRespInfo (This
);
3712 EfiReleaseLock (&mHiiDatabaseLock
);
3713 return EFI_NOT_FOUND
;
3718 This function updates the existing package list (which has the specified Handle)
3719 in the HII databases, using the new package list specified by PackageList.
3721 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3723 @param Handle The handle that was registered to the data that is
3724 requested to be updated.
3725 @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER
3728 @retval EFI_SUCCESS The HII database was successfully updated.
3729 @retval EFI_OUT_OF_RESOURCES Unable to allocate enough memory for the updated
3731 @retval EFI_INVALID_PARAMETER PackageList was NULL.
3732 @retval EFI_NOT_FOUND The specified Handle is not in database.
3737 HiiUpdatePackageList (
3738 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
3739 IN EFI_HII_HANDLE Handle
,
3740 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*PackageList
3744 HII_DATABASE_PRIVATE_DATA
*Private
;
3746 HII_DATABASE_RECORD
*Node
;
3747 EFI_HII_PACKAGE_HEADER
*PackageHdrPtr
;
3748 HII_DATABASE_PACKAGE_LIST_INSTANCE
*OldPackageList
;
3749 EFI_HII_PACKAGE_HEADER PackageHeader
;
3751 if (This
== NULL
|| PackageList
== NULL
) {
3752 return EFI_INVALID_PARAMETER
;
3755 if (!IsHiiHandleValid (Handle
)) {
3756 return EFI_NOT_FOUND
;
3759 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
3761 PackageHdrPtr
= (EFI_HII_PACKAGE_HEADER
*) ((UINT8
*) PackageList
+ sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
3763 Status
= EFI_SUCCESS
;
3765 EfiAcquireLock (&mHiiDatabaseLock
);
3767 // Get original packagelist to be updated
3769 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
3770 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
3771 if (Node
->Handle
== Handle
) {
3772 OldPackageList
= Node
->PackageList
;
3774 // Remove the package if its type matches one of the package types which is
3775 // contained in the new package list.
3777 CopyMem (&PackageHeader
, PackageHdrPtr
, sizeof (EFI_HII_PACKAGE_HEADER
));
3778 while (PackageHeader
.Type
!= EFI_HII_PACKAGE_END
) {
3779 switch (PackageHeader
.Type
) {
3780 case EFI_HII_PACKAGE_TYPE_GUID
:
3781 Status
= RemoveGuidPackages (Private
, Handle
, OldPackageList
);
3783 case EFI_HII_PACKAGE_FORMS
:
3784 Status
= RemoveFormPackages (Private
, Handle
, OldPackageList
);
3786 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
3787 Status
= RemoveKeyboardLayoutPackages (Private
, Handle
, OldPackageList
);
3789 case EFI_HII_PACKAGE_STRINGS
:
3790 Status
= RemoveStringPackages (Private
, Handle
, OldPackageList
);
3792 case EFI_HII_PACKAGE_FONTS
:
3793 Status
= RemoveFontPackages (Private
, Handle
, OldPackageList
);
3795 case EFI_HII_PACKAGE_IMAGES
:
3796 Status
= RemoveImagePackages (Private
, Handle
, OldPackageList
);
3798 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
3799 Status
= RemoveSimpleFontPackages (Private
, Handle
, OldPackageList
);
3801 case EFI_HII_PACKAGE_DEVICE_PATH
:
3802 Status
= RemoveDevicePathPackage (Private
, Handle
, OldPackageList
);
3806 if (EFI_ERROR (Status
)) {
3807 EfiReleaseLock (&mHiiDatabaseLock
);
3811 PackageHdrPtr
= (EFI_HII_PACKAGE_HEADER
*) ((UINT8
*) PackageHdrPtr
+ PackageHeader
.Length
);
3812 CopyMem (&PackageHeader
, PackageHdrPtr
, sizeof (EFI_HII_PACKAGE_HEADER
));
3816 // Add all of the packages within the new package list
3818 Status
= AddPackages (Private
, EFI_HII_DATABASE_NOTIFY_ADD_PACK
, PackageList
, Node
);
3821 // Check whether need to get the Database info.
3822 // Only after ReadyToBoot, need to do the export.
3824 if (gExportAfterReadyToBoot
&& Status
== EFI_SUCCESS
) {
3825 HiiGetDatabaseInfo (This
);
3827 EfiReleaseLock (&mHiiDatabaseLock
);
3831 // HiiGetDatabaseInfo () will get the contents of HII data base,
3832 // belong to the atomic behavior of Hii Database update.
3833 // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
3834 // we can not think it belong to the atomic behavior of Hii Database update.
3835 // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
3839 // Check whether need to get the configuration setting info from HII drivers.
3840 // When after ReadyToBoot and need to do the export for form package update.
3842 if (gExportAfterReadyToBoot
&& gExportConfigResp
&& Status
== EFI_SUCCESS
) {
3843 HiiGetConfigRespInfo (This
);
3849 EfiReleaseLock (&mHiiDatabaseLock
);
3850 return EFI_NOT_FOUND
;
3855 This function returns a list of the package handles of the specified type
3856 that are currently active in the database. The pseudo-type
3857 EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.
3859 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
3861 @param PackageType Specifies the package type of the packages to list
3862 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
3864 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
3865 this is the pointer to the GUID which must match
3866 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.
3867 Otherwise, it must be NULL.
3868 @param HandleBufferLength On input, a pointer to the length of the handle
3869 buffer. On output, the length of the handle
3870 buffer that is required for the handles found.
3871 @param Handle An array of EFI_HII_HANDLE instances returned.
3873 @retval EFI_SUCCESS The matching handles are outputted successfully.
3874 HandleBufferLength is updated with the actual length.
3875 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
3876 Handle is too small to support the number of
3877 handles. HandleBufferLength is updated with a
3878 value that will enable the data to fit.
3879 @retval EFI_NOT_FOUND No matching handle could not be found in database.
3880 @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL.
3881 @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not
3882 zero and Handle was NULL.
3883 @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but
3884 PackageGuid is not NULL, PackageType is a EFI_HII_
3885 PACKAGE_TYPE_GUID but PackageGuid is NULL.
3890 HiiListPackageLists (
3891 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
3892 IN UINT8 PackageType
,
3893 IN CONST EFI_GUID
*PackageGuid
,
3894 IN OUT UINTN
*HandleBufferLength
,
3895 OUT EFI_HII_HANDLE
*Handle
3898 HII_GUID_PACKAGE_INSTANCE
*GuidPackage
;
3899 HII_DATABASE_PRIVATE_DATA
*Private
;
3900 HII_DATABASE_RECORD
*Node
;
3903 HII_HANDLE
**Result
;
3905 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
3909 // Check input parameters
3911 if (This
== NULL
|| HandleBufferLength
== NULL
) {
3912 return EFI_INVALID_PARAMETER
;
3914 if (*HandleBufferLength
> 0 && Handle
== NULL
) {
3915 return EFI_INVALID_PARAMETER
;
3917 if ((PackageType
== EFI_HII_PACKAGE_TYPE_GUID
&& PackageGuid
== NULL
) ||
3918 (PackageType
!= EFI_HII_PACKAGE_TYPE_GUID
&& PackageGuid
!= NULL
)) {
3919 return EFI_INVALID_PARAMETER
;
3922 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
3924 Result
= (HII_HANDLE
**) Handle
;
3927 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
3928 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
3929 PackageList
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (Node
->PackageList
);
3930 switch (PackageType
) {
3931 case EFI_HII_PACKAGE_TYPE_GUID
:
3932 for (Link1
= PackageList
->GuidPkgHdr
.ForwardLink
; Link1
!= &PackageList
->GuidPkgHdr
; Link1
= Link1
->ForwardLink
) {
3933 GuidPackage
= CR (Link1
, HII_GUID_PACKAGE_INSTANCE
, GuidEntry
, HII_GUID_PACKAGE_SIGNATURE
);
3935 (EFI_GUID
*) PackageGuid
,
3936 (EFI_GUID
*) (GuidPackage
->GuidPkg
+ sizeof (EFI_HII_PACKAGE_HEADER
))
3943 case EFI_HII_PACKAGE_FORMS
:
3944 if (!IsListEmpty (&PackageList
->FormPkgHdr
)) {
3948 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
3949 if (!IsListEmpty (&PackageList
->KeyboardLayoutHdr
)) {
3953 case EFI_HII_PACKAGE_STRINGS
:
3954 if (!IsListEmpty (&PackageList
->StringPkgHdr
)) {
3958 case EFI_HII_PACKAGE_FONTS
:
3959 if (!IsListEmpty (&PackageList
->FontPkgHdr
)) {
3963 case EFI_HII_PACKAGE_IMAGES
:
3964 if (PackageList
->ImagePkg
!= NULL
) {
3968 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
3969 if (!IsListEmpty (&PackageList
->SimpleFontPkgHdr
)) {
3973 case EFI_HII_PACKAGE_DEVICE_PATH
:
3974 if (PackageList
->DevicePathPkg
!= NULL
) {
3979 // Pseudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles
3982 case EFI_HII_PACKAGE_TYPE_ALL
:
3990 // This active package list has the specified package type, list it.
3993 ResultSize
+= sizeof (EFI_HII_HANDLE
);
3994 if (ResultSize
<= *HandleBufferLength
) {
3995 *Result
++ = Node
->Handle
;
4001 if (ResultSize
== 0) {
4002 return EFI_NOT_FOUND
;
4005 if (*HandleBufferLength
< ResultSize
) {
4006 *HandleBufferLength
= ResultSize
;
4007 return EFI_BUFFER_TOO_SMALL
;
4010 *HandleBufferLength
= ResultSize
;
4016 This function will export one or all package lists in the database to a buffer.
4017 For each package list exported, this function will call functions registered
4018 with EXPORT_PACK and then copy the package list to the buffer.
4020 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4022 @param Handle An EFI_HII_HANDLE that corresponds to the desired
4023 package list in the HII database to export or NULL
4024 to indicate all package lists should be exported.
4025 @param BufferSize On input, a pointer to the length of the buffer.
4026 On output, the length of the buffer that is
4027 required for the exported data.
4028 @param Buffer A pointer to a buffer that will contain the
4029 results of the export function.
4031 @retval EFI_SUCCESS Package exported.
4032 @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that
4033 Handle is too small to support the number of
4034 handles. HandleBufferLength is updated with a
4035 value that will enable the data to fit.
4036 @retval EFI_NOT_FOUND The specified Handle could not be found in the
4038 @retval EFI_INVALID_PARAMETER BufferSize was NULL.
4039 @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero
4040 and Buffer was NULL.
4045 HiiExportPackageLists (
4046 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4047 IN EFI_HII_HANDLE Handle
,
4048 IN OUT UINTN
*BufferSize
,
4049 OUT EFI_HII_PACKAGE_LIST_HEADER
*Buffer
4054 HII_DATABASE_PRIVATE_DATA
*Private
;
4055 HII_DATABASE_RECORD
*Node
;
4058 if (This
== NULL
|| BufferSize
== NULL
) {
4059 return EFI_INVALID_PARAMETER
;
4061 if (*BufferSize
> 0 && Buffer
== NULL
) {
4062 return EFI_INVALID_PARAMETER
;
4064 if ((Handle
!= NULL
) && (!IsHiiHandleValid (Handle
))) {
4065 return EFI_NOT_FOUND
;
4068 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4071 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
4072 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
4073 if (Handle
== NULL
) {
4075 // Export all package lists in current hii database.
4077 Status
= ExportPackageList (
4080 (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (Node
->PackageList
),
4083 (EFI_HII_PACKAGE_LIST_HEADER
*)((UINT8
*) Buffer
+ UsedSize
)
4085 ASSERT_EFI_ERROR (Status
);
4086 } else if (Handle
!= NULL
&& Node
->Handle
== Handle
) {
4087 Status
= ExportPackageList (
4090 (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (Node
->PackageList
),
4095 ASSERT_EFI_ERROR (Status
);
4096 if (*BufferSize
< UsedSize
) {
4097 *BufferSize
= UsedSize
;
4098 return EFI_BUFFER_TOO_SMALL
;
4104 if (Handle
== NULL
&& UsedSize
!= 0) {
4105 if (*BufferSize
< UsedSize
) {
4106 *BufferSize
= UsedSize
;
4107 return EFI_BUFFER_TOO_SMALL
;
4112 return EFI_NOT_FOUND
;
4117 This function registers a function which will be called when specified actions related to packages of
4118 the specified type occur in the HII database. By registering a function, other HII-related drivers are
4119 notified when specific package types are added, removed or updated in the HII database.
4120 Each driver or application which registers a notification should use
4121 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.
4123 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4125 @param PackageType Specifies the package type of the packages to list
4126 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
4128 @param PackageGuid If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
4129 this is the pointer to the GUID which must match
4131 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must
4133 @param PackageNotifyFn Points to the function to be called when the event
4135 NotificationType occurs.
4136 @param NotifyType Describes the types of notification which this
4137 function will be receiving.
4138 @param NotifyHandle Points to the unique handle assigned to the
4139 registered notification. Can be used in
4140 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()
4141 to stop notifications.
4143 @retval EFI_SUCCESS Notification registered successfully.
4144 @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures
4145 @retval EFI_INVALID_PARAMETER NotifyHandle is NULL.
4146 @retval EFI_INVALID_PARAMETER PackageGuid is not NULL when PackageType is not
4147 EFI_HII_PACKAGE_TYPE_GUID.
4148 @retval EFI_INVALID_PARAMETER PackageGuid is NULL when PackageType is
4149 EFI_HII_PACKAGE_TYPE_GUID.
4154 HiiRegisterPackageNotify (
4155 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4156 IN UINT8 PackageType
,
4157 IN CONST EFI_GUID
*PackageGuid
,
4158 IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn
,
4159 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
,
4160 OUT EFI_HANDLE
*NotifyHandle
4163 HII_DATABASE_PRIVATE_DATA
*Private
;
4164 HII_DATABASE_NOTIFY
*Notify
;
4167 if (This
== NULL
|| NotifyHandle
== NULL
) {
4168 return EFI_INVALID_PARAMETER
;
4170 if ((PackageType
== EFI_HII_PACKAGE_TYPE_GUID
&& PackageGuid
== NULL
) ||
4171 (PackageType
!= EFI_HII_PACKAGE_TYPE_GUID
&& PackageGuid
!= NULL
)) {
4172 return EFI_INVALID_PARAMETER
;
4175 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4178 // Allocate a notification node
4180 Notify
= (HII_DATABASE_NOTIFY
*) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY
));
4181 if (Notify
== NULL
) {
4182 return EFI_OUT_OF_RESOURCES
;
4186 // Generate a notify handle
4188 Status
= gBS
->InstallMultipleProtocolInterfaces (
4189 &Notify
->NotifyHandle
,
4194 ASSERT_EFI_ERROR (Status
);
4197 // Fill in the information to the notification node
4199 Notify
->Signature
= HII_DATABASE_NOTIFY_SIGNATURE
;
4200 Notify
->PackageType
= PackageType
;
4201 Notify
->PackageGuid
= (EFI_GUID
*) PackageGuid
;
4202 Notify
->PackageNotifyFn
= (EFI_HII_DATABASE_NOTIFY
) PackageNotifyFn
;
4203 Notify
->NotifyType
= NotifyType
;
4205 InsertTailList (&Private
->DatabaseNotifyList
, &Notify
->DatabaseNotifyEntry
);
4206 *NotifyHandle
= Notify
->NotifyHandle
;
4213 Removes the specified HII database package-related notification.
4215 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4217 @param NotificationHandle The handle of the notification function being
4220 @retval EFI_SUCCESS Notification is unregistered successfully.
4221 @retval EFI_INVALID_PARAMETER The Handle is invalid.
4222 @retval EFI_NOT_FOUND The incoming notification handle does not exist
4223 in current hii database.
4228 HiiUnregisterPackageNotify (
4229 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4230 IN EFI_HANDLE NotificationHandle
4233 HII_DATABASE_PRIVATE_DATA
*Private
;
4234 HII_DATABASE_NOTIFY
*Notify
;
4239 return EFI_INVALID_PARAMETER
;
4242 if (NotificationHandle
== NULL
) {
4243 return EFI_NOT_FOUND
;
4246 Status
= gBS
->OpenProtocol (
4252 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
4254 if (EFI_ERROR (Status
)) {
4255 return EFI_NOT_FOUND
;
4258 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4260 for (Link
= Private
->DatabaseNotifyList
.ForwardLink
; Link
!= &Private
->DatabaseNotifyList
; Link
= Link
->ForwardLink
) {
4261 Notify
= CR (Link
, HII_DATABASE_NOTIFY
, DatabaseNotifyEntry
, HII_DATABASE_NOTIFY_SIGNATURE
);
4262 if (Notify
->NotifyHandle
== NotificationHandle
) {
4264 // Remove the matching notification node
4266 RemoveEntryList (&Notify
->DatabaseNotifyEntry
);
4267 Status
= gBS
->UninstallMultipleProtocolInterfaces (
4268 Notify
->NotifyHandle
,
4273 ASSERT_EFI_ERROR (Status
);
4280 return EFI_NOT_FOUND
;
4285 This routine retrieves an array of GUID values for each keyboard layout that
4286 was previously registered in the system.
4288 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4290 @param KeyGuidBufferLength On input, a pointer to the length of the keyboard
4291 GUID buffer. On output, the length of the handle
4292 buffer that is required for the handles found.
4293 @param KeyGuidBuffer An array of keyboard layout GUID instances
4296 @retval EFI_SUCCESS KeyGuidBuffer was updated successfully.
4297 @retval EFI_BUFFER_TOO_SMALL The KeyGuidBufferLength parameter indicates
4298 that KeyGuidBuffer is too small to support the
4299 number of GUIDs. KeyGuidBufferLength is
4300 updated with a value that will enable the data to
4302 @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL.
4303 @retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not
4304 zero and KeyGuidBuffer is NULL.
4305 @retval EFI_NOT_FOUND There was no keyboard layout.
4310 HiiFindKeyboardLayouts (
4311 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4312 IN OUT UINT16
*KeyGuidBufferLength
,
4313 OUT EFI_GUID
*KeyGuidBuffer
4316 HII_DATABASE_PRIVATE_DATA
*Private
;
4317 HII_DATABASE_RECORD
*Node
;
4318 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
4324 UINT16 LayoutLength
;
4326 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*Package
;
4328 if (This
== NULL
|| KeyGuidBufferLength
== NULL
) {
4329 return EFI_INVALID_PARAMETER
;
4332 if (*KeyGuidBufferLength
> 0 && KeyGuidBuffer
== NULL
) {
4333 return EFI_INVALID_PARAMETER
;
4336 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4340 // Search all package lists in whole database to retrieve keyboard layout.
4342 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
4343 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
4344 PackageList
= Node
->PackageList
;
4345 for (Link1
= PackageList
->KeyboardLayoutHdr
.ForwardLink
;
4346 Link1
!= &PackageList
->KeyboardLayoutHdr
;
4347 Link1
= Link1
->ForwardLink
4350 // Find out all Keyboard Layout packages in this package list.
4354 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
,
4356 HII_KB_LAYOUT_PACKAGE_SIGNATURE
4358 Layout
= (UINT8
*) Package
->KeyboardPkg
+ sizeof (EFI_HII_PACKAGE_HEADER
) + sizeof (UINT16
);
4361 (UINT8
*) Package
->KeyboardPkg
+ sizeof (EFI_HII_PACKAGE_HEADER
),
4364 for (Index
= 0; Index
< LayoutCount
; Index
++) {
4365 ResultSize
+= sizeof (EFI_GUID
);
4366 if (ResultSize
<= *KeyGuidBufferLength
) {
4367 CopyMem (KeyGuidBuffer
+ (ResultSize
/ sizeof (EFI_GUID
) - 1), Layout
+ sizeof (UINT16
), sizeof (EFI_GUID
));
4368 CopyMem (&LayoutLength
, Layout
, sizeof (UINT16
));
4369 Layout
= Layout
+ LayoutLength
;
4375 if (ResultSize
== 0) {
4376 return EFI_NOT_FOUND
;
4379 if (*KeyGuidBufferLength
< ResultSize
) {
4380 *KeyGuidBufferLength
= ResultSize
;
4381 return EFI_BUFFER_TOO_SMALL
;
4384 *KeyGuidBufferLength
= ResultSize
;
4390 This routine retrieves the requested keyboard layout. The layout is a physical description of the keys
4391 on a keyboard and the character(s) that are associated with a particular set of key strokes.
4393 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4395 @param KeyGuid A pointer to the unique ID associated with a given
4396 keyboard layout. If KeyGuid is NULL then the
4397 current layout will be retrieved.
4398 @param KeyboardLayoutLength On input, a pointer to the length of the
4399 KeyboardLayout buffer. On output, the length of
4400 the data placed into KeyboardLayout.
4401 @param KeyboardLayout A pointer to a buffer containing the retrieved
4404 @retval EFI_SUCCESS The keyboard layout was retrieved successfully.
4405 @retval EFI_NOT_FOUND The requested keyboard layout was not found.
4406 @retval EFI_INVALID_PARAMETER The KeyboardLayout or KeyboardLayoutLength was
4408 @retval EFI_BUFFER_TOO_SMALL The KeyboardLayoutLength parameter indicates
4409 that KeyboardLayout is too small to support the
4410 requested keyboard layout. KeyboardLayoutLength is
4411 updated with a value that will enable the
4417 HiiGetKeyboardLayout (
4418 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4419 IN CONST EFI_GUID
*KeyGuid
,
4420 IN OUT UINT16
*KeyboardLayoutLength
,
4421 OUT EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
4424 HII_DATABASE_PRIVATE_DATA
*Private
;
4425 HII_DATABASE_RECORD
*Node
;
4426 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageList
;
4432 UINT16 LayoutLength
;
4433 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
*Package
;
4435 if (This
== NULL
|| KeyboardLayoutLength
== NULL
) {
4436 return EFI_INVALID_PARAMETER
;
4438 if (*KeyboardLayoutLength
> 0 && KeyboardLayout
== NULL
) {
4439 return EFI_INVALID_PARAMETER
;
4442 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4444 // Retrieve the current keyboard layout.
4446 if (KeyGuid
== NULL
) {
4447 if (Private
->CurrentLayout
== NULL
) {
4448 return EFI_NOT_FOUND
;
4450 CopyMem (&LayoutLength
, Private
->CurrentLayout
, sizeof (UINT16
));
4451 if (*KeyboardLayoutLength
< LayoutLength
) {
4452 *KeyboardLayoutLength
= LayoutLength
;
4453 return EFI_BUFFER_TOO_SMALL
;
4455 CopyMem (KeyboardLayout
, Private
->CurrentLayout
, LayoutLength
);
4459 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
4460 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
4461 PackageList
= (HII_DATABASE_PACKAGE_LIST_INSTANCE
*) (Node
->PackageList
);
4462 for (Link1
= PackageList
->KeyboardLayoutHdr
.ForwardLink
;
4463 Link1
!= &PackageList
->KeyboardLayoutHdr
;
4464 Link1
= Link1
->ForwardLink
4468 HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE
,
4470 HII_KB_LAYOUT_PACKAGE_SIGNATURE
4473 Layout
= (UINT8
*) Package
->KeyboardPkg
+
4474 sizeof (EFI_HII_PACKAGE_HEADER
) + sizeof (UINT16
);
4475 CopyMem (&LayoutCount
, Layout
- sizeof (UINT16
), sizeof (UINT16
));
4476 for (Index
= 0; Index
< LayoutCount
; Index
++) {
4477 CopyMem (&LayoutLength
, Layout
, sizeof (UINT16
));
4478 if (CompareMem (Layout
+ sizeof (UINT16
), KeyGuid
, sizeof (EFI_GUID
)) == 0) {
4479 if (LayoutLength
<= *KeyboardLayoutLength
) {
4480 CopyMem (KeyboardLayout
, Layout
, LayoutLength
);
4483 *KeyboardLayoutLength
= LayoutLength
;
4484 return EFI_BUFFER_TOO_SMALL
;
4487 Layout
= Layout
+ LayoutLength
;
4492 return EFI_NOT_FOUND
;
4497 This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine
4498 is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
4499 group type. This is so that agents which are sensitive to the current keyboard layout being changed
4500 can be notified of this change.
4502 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4504 @param KeyGuid A pointer to the unique ID associated with a given
4507 @retval EFI_SUCCESS The current keyboard layout was successfully set.
4508 @retval EFI_NOT_FOUND The referenced keyboard layout was not found, so
4510 @retval EFI_INVALID_PARAMETER The KeyGuid was NULL.
4515 HiiSetKeyboardLayout (
4516 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4517 IN CONST EFI_GUID
*KeyGuid
4520 HII_DATABASE_PRIVATE_DATA
*Private
;
4521 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
4522 UINT16 KeyboardLayoutLength
;
4525 if (This
== NULL
|| KeyGuid
== NULL
) {
4526 return EFI_INVALID_PARAMETER
;
4529 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4532 // The specified GUID equals the current keyboard layout GUID,
4535 if (CompareGuid (&Private
->CurrentLayoutGuid
, KeyGuid
)) {
4540 // Try to find the incoming keyboard layout data in current database.
4542 KeyboardLayoutLength
= 0;
4543 KeyboardLayout
= NULL
;
4544 Status
= HiiGetKeyboardLayout (This
, KeyGuid
, &KeyboardLayoutLength
, KeyboardLayout
);
4545 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
4549 KeyboardLayout
= (EFI_HII_KEYBOARD_LAYOUT
*) AllocateZeroPool (KeyboardLayoutLength
);
4550 ASSERT (KeyboardLayout
!= NULL
);
4551 Status
= HiiGetKeyboardLayout (This
, KeyGuid
, &KeyboardLayoutLength
, KeyboardLayout
);
4552 ASSERT_EFI_ERROR (Status
);
4555 // Backup current keyboard layout.
4557 CopyMem (&Private
->CurrentLayoutGuid
, KeyGuid
, sizeof (EFI_GUID
));
4558 if (Private
->CurrentLayout
!= NULL
) {
4559 FreePool(Private
->CurrentLayout
);
4561 Private
->CurrentLayout
= KeyboardLayout
;
4564 // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify
4565 // current keyboard layout is changed.
4567 Status
= gBS
->SignalEvent (gHiiKeyboardLayoutChanged
);
4568 ASSERT_EFI_ERROR (Status
);
4575 Return the EFI handle associated with a package list.
4577 @param This A pointer to the EFI_HII_DATABASE_PROTOCOL
4579 @param PackageListHandle An EFI_HII_HANDLE that corresponds to the desired
4580 package list in the HIIdatabase.
4581 @param DriverHandle On return, contains the EFI_HANDLE which was
4582 registered with the package list in
4585 @retval EFI_SUCCESS The DriverHandle was returned successfully.
4586 @retval EFI_INVALID_PARAMETER The PackageListHandle was not valid or
4587 DriverHandle was NULL.
4588 @retval EFI_NOT_FOUND This PackageList handle can not be found in
4594 HiiGetPackageListHandle (
4595 IN CONST EFI_HII_DATABASE_PROTOCOL
*This
,
4596 IN EFI_HII_HANDLE PackageListHandle
,
4597 OUT EFI_HANDLE
*DriverHandle
4600 HII_DATABASE_PRIVATE_DATA
*Private
;
4601 HII_DATABASE_RECORD
*Node
;
4604 if (This
== NULL
|| DriverHandle
== NULL
) {
4605 return EFI_INVALID_PARAMETER
;
4608 if (!IsHiiHandleValid (PackageListHandle
)) {
4609 return EFI_INVALID_PARAMETER
;
4612 Private
= HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
4614 for (Link
= Private
->DatabaseList
.ForwardLink
; Link
!= &Private
->DatabaseList
; Link
= Link
->ForwardLink
) {
4615 Node
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
4616 if (Node
->Handle
== PackageListHandle
) {
4617 *DriverHandle
= Node
->DriverHandle
;
4622 return EFI_NOT_FOUND
;