2 HII Library implementation that uses DXE protocols and services.
4 Copyright (c) 2006, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Protocol/HiiDatabase.h>
19 #include <Protocol/HiiString.h>
20 #include <Protocol/DevicePath.h>
22 #include <Guid/GlobalVariable.h>
24 #include <Library/BaseLib.h>
25 #include <Library/BaseMemoryLib.h>
26 #include <Library/HiiLib.h>
27 #include <Library/DebugLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/UefiBootServicesTableLib.h>
30 #include <Library/UefiRuntimeServicesTableLib.h>
31 #include <Library/PcdLib.h>
33 #include <MdeModuleHii.h>
35 #include "InternalHiiLib.h"
38 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabaseProt
;
39 EFI_HII_STRING_PROTOCOL
*mHiiStringProt
;
42 // Hii vendor device path template
44 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePathTemplate
= {
51 (UINT8
) (sizeof (HII_VENDOR_DEVICE_PATH_NODE
)),
52 (UINT8
) ((sizeof (HII_VENDOR_DEVICE_PATH_NODE
)) >> 8)
61 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
63 END_DEVICE_PATH_LENGTH
70 UefiHiiLibConstructor (
71 IN EFI_HANDLE ImageHandle
,
72 IN EFI_SYSTEM_TABLE
*SystemTable
77 Status
= gBS
->LocateProtocol (
78 &gEfiHiiDatabaseProtocolGuid
,
80 (VOID
**) &mHiiDatabaseProt
82 ASSERT_EFI_ERROR (Status
);
83 ASSERT (mHiiDatabaseProt
!= NULL
);
85 Status
= gBS
->LocateProtocol (
86 &gEfiHiiStringProtocolGuid
,
88 (VOID
**) &mHiiStringProt
90 ASSERT_EFI_ERROR (Status
);
91 ASSERT (mHiiStringProt
!= NULL
);
97 HiiLibGetCurrentLanguage (
103 Determine what is the current language setting
106 Lang - Pointer of system language
117 // Get current language setting
119 Size
= RFC_3066_ENTRY_SIZE
;
120 Status
= gRT
->GetVariable (
122 &gEfiGlobalVariableGuid
,
128 if (EFI_ERROR (Status
)) {
129 AsciiStrCpy (Lang
, (CHAR8
*) PcdGetPtr (PcdUefiVariableDefaultPlatformLang
));
136 HiiLibGetNextLanguage (
137 IN OUT CHAR8
**LangCode
,
143 Get next language from language code list (with separator ';').
146 LangCode - On input: point to first language in the list. On output: point to
147 next language in the list, or NULL if no more language in the list.
148 Lang - The first language in the list.
158 if (LangCode
== NULL
|| *LangCode
== NULL
) {
164 StringPtr
= *LangCode
;
165 while (StringPtr
[Index
] != 0 && StringPtr
[Index
] != ';') {
169 CopyMem (Lang
, StringPtr
, Index
);
172 if (StringPtr
[Index
] == ';') {
175 *LangCode
= StringPtr
+ Index
;
179 HiiLibGetSupportedLanguages (
180 IN EFI_HII_HANDLE HiiHandle
185 This function returns the list of supported languages, in the format specified
186 in UEFI specification Appendix M.
189 HiiHandle - The HII package list handle.
192 The supported languages.
198 CHAR8
*LanguageString
;
201 // Collect current supported Languages for given HII handle
204 LanguageString
= AllocatePool (BufferSize
);
205 Status
= mHiiStringProt
->GetLanguages (mHiiStringProt
, HiiHandle
, LanguageString
, &BufferSize
);
206 if (Status
== EFI_BUFFER_TOO_SMALL
) {
207 gBS
->FreePool (LanguageString
);
208 LanguageString
= AllocatePool (BufferSize
);
209 Status
= mHiiStringProt
->GetLanguages (mHiiStringProt
, HiiHandle
, LanguageString
, &BufferSize
);
212 if (EFI_ERROR (Status
)) {
213 LanguageString
= NULL
;
216 return LanguageString
;
220 HiiLibGetSupportedLanguageNumber (
221 IN EFI_HII_HANDLE HiiHandle
226 This function returns the number of supported languages
229 HiiHandle - The HII package list handle.
232 The number of supported languages.
237 CHAR8
*LanguageString
;
239 CHAR8 Lang
[RFC_3066_ENTRY_SIZE
];
241 Languages
= HiiLibGetSupportedLanguages (HiiHandle
);
242 if (Languages
== NULL
) {
247 LanguageString
= Languages
;
248 while (*LanguageString
!= 0) {
249 HiiLibGetNextLanguage (&LanguageString
, Lang
);
252 gBS
->FreePool (Languages
);
258 EFI_HII_PACKAGE_LIST_HEADER
*
259 InternalHiiLibPreparePackages (
260 IN UINTN NumberOfPackages
,
261 IN CONST EFI_GUID
*GuidId
, OPTIONAL
265 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
266 UINT8
*PackageListData
;
267 UINT32 PackageListLength
;
268 UINT32 PackageLength
;
269 EFI_HII_PACKAGE_HEADER PackageHeader
;
272 VA_LIST MarkerBackup
;
274 PackageListLength
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
276 MarkerBackup
= Marker
;
278 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
279 CopyMem (&PackageLength
, VA_ARG (Marker
, VOID
*), sizeof (UINT32
));
280 PackageListLength
+= (PackageLength
- sizeof (UINT32
));
284 // Include the lenght of EFI_HII_PACKAGE_END
286 PackageListLength
+= sizeof (EFI_HII_PACKAGE_HEADER
);
287 PackageListHeader
= AllocateZeroPool (PackageListLength
);
288 ASSERT (PackageListHeader
!= NULL
);
289 CopyMem (&PackageListHeader
->PackageListGuid
, GuidId
, sizeof (EFI_GUID
));
290 PackageListHeader
->PackageLength
= PackageListLength
;
292 PackageListData
= ((UINT8
*) PackageListHeader
) + sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
294 Marker
= MarkerBackup
;
295 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
296 PackageArray
= (UINT8
*) VA_ARG (Marker
, VOID
*);
297 CopyMem (&PackageLength
, PackageArray
, sizeof (UINT32
));
298 PackageLength
-= sizeof (UINT32
);
299 PackageArray
+= sizeof (UINT32
);
300 CopyMem (PackageListData
, PackageArray
, PackageLength
);
301 PackageListData
+= PackageLength
;
305 // Append EFI_HII_PACKAGE_END
307 PackageHeader
.Type
= EFI_HII_PACKAGE_END
;
308 PackageHeader
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
309 CopyMem (PackageListData
, &PackageHeader
, PackageHeader
.Length
);
311 return PackageListHeader
;
314 EFI_HII_PACKAGE_LIST_HEADER
*
316 HiiLibPreparePackageList (
317 IN UINTN NumberOfPackages
,
318 IN CONST EFI_GUID
*GuidId
,
324 Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
327 NumberOfPackages - Number of packages.
328 GuidId - Package GUID.
331 Pointer of EFI_HII_PACKAGE_LIST_HEADER.
335 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
338 VA_START (Marker
, GuidId
);
339 PackageListHeader
= InternalHiiLibPreparePackages (NumberOfPackages
, GuidId
, Marker
);
342 return PackageListHeader
;
347 This function allocates pool for an EFI_HII_PACKAGE_LIST structure
348 with additional space that is big enough to host all packages described by the variable
349 argument list of package pointers. The allocated structure is initialized using NumberOfPackages,
350 GuidId, and the variable length argument list of package pointers.
352 Then, EFI_HII_PACKAGE_LIST will be register to the default System HII Database. The
353 Handle to the newly registered Package List is returned throught HiiHandle.
355 @param NumberOfPackages The number of HII packages to register.
356 @param GuidId Package List GUID ID.
357 @param HiiHandle The ID used to retrieve the Package List later.
358 @param ... The variable argument list describing all HII Package.
361 The allocated and initialized packages.
367 HiiLibAddPackagesToHiiDatabase (
368 IN UINTN NumberOfPackages
,
369 IN CONST EFI_GUID
*GuidId
,
370 IN EFI_HANDLE DriverHandle
, OPTIONAL
371 OUT EFI_HII_HANDLE
*HiiHandle
, OPTIONAL
376 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
380 VA_START (Args
, HiiHandle
);
381 PackageListHeader
= InternalHiiLibPreparePackages (NumberOfPackages
, GuidId
, Args
);
383 Status
= mHiiDatabaseProt
->NewPackageList (mHiiDatabaseProt
, PackageListHeader
, DriverHandle
, HiiHandle
);
384 if (HiiHandle
!= NULL
) {
385 if (EFI_ERROR (Status
)) {
390 FreePool (PackageListHeader
);
398 HiiLibAddFontPackageToHiiDatabase (
400 IN CONST UINT8
*FontBinary
,
401 IN CONST EFI_GUID
*GuidId
,
402 OUT EFI_HII_HANDLE
*HiiHandle OPTIONAL
407 EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*SimplifiedFont
;
409 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
413 // Add 4 bytes to the header for entire length for PreparePackageList use only.
414 // Looks ugly. Might be updated when font tool is ready.
416 PackageLength
= sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
) + FontSize
+ 4;
417 Package
= AllocateZeroPool (PackageLength
);
418 if (Package
== NULL
) {
419 return EFI_OUT_OF_RESOURCES
;
421 CopyMem (Package
, &PackageLength
, 4);
422 SimplifiedFont
= (EFI_HII_SIMPLE_FONT_PACKAGE_HDR
*) (Package
+ 4);
423 SimplifiedFont
->Header
.Length
= (UINT32
) (PackageLength
- 4);
424 SimplifiedFont
->Header
.Type
= EFI_HII_PACKAGE_SIMPLE_FONTS
;
425 SimplifiedFont
->NumberOfNarrowGlyphs
= (UINT16
) (FontSize
/ sizeof (EFI_NARROW_GLYPH
));
427 Location
= (UINT8
*) (&SimplifiedFont
->NumberOfWideGlyphs
+ 1);
428 CopyMem (Location
, FontBinary
, FontSize
);
431 // Add this simplified font package to a package list then install it.
433 PackageList
= HiiLibPreparePackageList (1, GuidId
, Package
);
434 Status
= mHiiDatabaseProt
->NewPackageList (mHiiDatabaseProt
, PackageList
, NULL
, HiiHandle
);
435 ASSERT_EFI_ERROR (Status
);
436 SafeFreePool (PackageList
);
437 SafeFreePool (Package
);
444 HiiLibRemovePackagesFromHiiDatabase (
445 IN EFI_HII_HANDLE HiiHandle
448 return mHiiDatabaseProt
->RemovePackageList (mHiiDatabaseProt
, HiiHandle
);
454 IN EFI_HII_HANDLE PackageList
,
455 OUT EFI_STRING_ID
*StringId
,
456 IN CONST EFI_STRING String
462 CHAR8 Lang
[RFC_3066_ENTRY_SIZE
];
464 Status
= EFI_SUCCESS
;
466 Languages
= HiiLibGetSupportedLanguages (PackageList
);
468 LangStrings
= Languages
;
469 while (*LangStrings
!= 0) {
470 HiiLibGetNextLanguage (&LangStrings
, Lang
);
472 Status
= mHiiStringProt
->NewString (
481 if (EFI_ERROR (Status
)) {
486 FreePool (Languages
);
495 IN EFI_HII_HANDLE PackageList
,
496 IN EFI_STRING_ID StringId
,
497 IN CONST EFI_STRING String
503 CHAR8 Lang
[RFC_3066_ENTRY_SIZE
];
505 Status
= EFI_SUCCESS
;
507 Languages
= HiiLibGetSupportedLanguages (PackageList
);
509 LangStrings
= Languages
;
510 while (*LangStrings
!= 0) {
511 HiiLibGetNextLanguage (&LangStrings
, Lang
);
513 Status
= mHiiStringProt
->SetString (
521 if (EFI_ERROR (Status
)) {
526 FreePool (Languages
);
532 // //////////////////////////////////////////////////
536 // This function is Implementation Specifc. HII_VENDOR_DEVICE_PATH
537 // This should be moved to MdeModulepkg.
541 HiiLibCreateHiiDriverHandle (
542 OUT EFI_HANDLE
*DriverHandle
546 HII_VENDOR_DEVICE_PATH_NODE
*VendorDevicePath
;
547 UINT64 MonotonicCount
;
549 VendorDevicePath
= AllocateCopyPool (sizeof (HII_VENDOR_DEVICE_PATH
), &mHiiVendorDevicePathTemplate
);
550 if (VendorDevicePath
== NULL
) {
551 return EFI_OUT_OF_RESOURCES
;
554 gBS
->GetNextMonotonicCount (&MonotonicCount
);
555 VendorDevicePath
->MonotonicCount
= (UINT32
) MonotonicCount
;
557 *DriverHandle
= NULL
;
558 Status
= gBS
->InstallProtocolInterface (
560 &gEfiDevicePathProtocolGuid
,
561 EFI_NATIVE_INTERFACE
,
564 if (EFI_ERROR (Status
)) {
574 HiiLibDestroyHiiDriverHandle (
575 IN EFI_HANDLE DriverHandle
579 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
581 Status
= gBS
->HandleProtocol (
583 &gEfiDevicePathProtocolGuid
,
584 (VOID
**) &DevicePath
586 if (EFI_ERROR (Status
)) {
590 Status
= gBS
->UninstallProtocolInterface (
592 &gEfiDevicePathProtocolGuid
,
600 HiiLibExtractDefault(
602 IN UINTN
*BufferSize
,
610 Configure the buffer accrording to ConfigBody strings.
613 DefaultId - the ID of default.
614 Buffer - the start address of buffer.
615 BufferSize - the size of buffer.
616 Number - the number of the strings.
619 EFI_BUFFER_TOO_SMALL - the BufferSize is too small to operate.
620 EFI_INVALID_PARAMETER - Buffer is NULL or BufferSize is 0.
621 EFI_SUCCESS - Operation successful.
634 if ((Buffer
== NULL
) || (BufferSize
== NULL
)) {
635 return EFI_INVALID_PARAMETER
;
642 VA_START (Args
, Number
);
643 for (Index
= 0; Index
< Number
; Index
++) {
644 BufCfgArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
645 CopyMem (&TotalLen
, BufCfgArray
, sizeof (UINT32
));
646 BufferPos
= BufCfgArray
+ sizeof (UINT32
);
648 while ((UINT32
)(BufferPos
- BufCfgArray
) < TotalLen
) {
649 CopyMem (&Offset
, BufferPos
, sizeof (UINT16
));
650 BufferPos
+= sizeof (UINT16
);
651 CopyMem (&Width
, BufferPos
, sizeof (UINT16
));
652 BufferPos
+= sizeof (UINT16
);
656 if ((UINTN
)(Offset
+ Width
) > *BufferSize
) {
657 return EFI_BUFFER_TOO_SMALL
;
660 CopyMem ((UINT8
*)Buffer
+ Offset
, Value
, Width
);
665 *BufferSize
= (UINTN
)Offset
;
671 STATIC EFI_GUID mIfrVendorGuid
= EFI_IFR_TIANO_GUID
;
674 HiiLibExtractClassFromHiiHandle (
675 IN EFI_HII_HANDLE Handle
,
677 OUT EFI_STRING_ID
*FormSetTitle
,
678 OUT EFI_STRING_ID
*FormSetHelp
683 Extract formset class for given HII handle.
686 HiiHandle - Hii handle
687 Class - Class of the formset
688 FormSetTitle - Formset title string
689 FormSetHelp - Formset help string
692 EFI_SUCCESS - Successfully extract Class for specified Hii handle.
698 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
699 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
704 UINT32 PackageListLength
;
705 EFI_HII_PACKAGE_HEADER PackageHeader
;
707 *Class
= EFI_NON_DEVICE_CLASS
;
712 // Locate HII Database protocol
714 Status
= gBS
->LocateProtocol (
715 &gEfiHiiDatabaseProtocolGuid
,
717 (VOID
**) &HiiDatabase
719 if (EFI_ERROR (Status
)) {
724 // Get HII PackageList
727 HiiPackageList
= NULL
;
728 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
729 if (Status
== EFI_BUFFER_TOO_SMALL
) {
730 HiiPackageList
= AllocatePool (BufferSize
);
731 ASSERT (HiiPackageList
!= NULL
);
733 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
735 if (EFI_ERROR (Status
)) {
740 // Get Form package from this HII package List
742 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
744 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
746 while (Offset
< PackageListLength
) {
747 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
748 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
750 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORM
) {
752 // Search Class Opcode in this Form Package
754 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
755 while (Offset2
< PackageHeader
.Length
) {
756 OpCodeData
= Package
+ Offset2
;
758 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
760 // Find FormSet OpCode
762 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
763 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
766 if ((((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_GUID_OP
) &&
767 CompareGuid (&mIfrVendorGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
))) &&
768 (((EFI_IFR_GUID_CLASS
*) OpCodeData
)->ExtendOpCode
== EFI_IFR_EXTEND_OP_CLASS
)
771 // Find GUIDed Class OpCode
773 CopyMem (Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
776 // Till now, we ought to have found the formset Opcode
781 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
784 if (Offset2
< PackageHeader
.Length
) {
786 // Target formset found
792 Offset
+= PackageHeader
.Length
;
795 gBS
->FreePool (HiiPackageList
);