3 This file contains the keyboard processing code to the HII database.
5 Copyright (c) 2006 - 2008, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "HiiDatabase.h"
20 BOOLEAN mInFrameworkHiiNewPack
= FALSE
;
21 BOOLEAN mInFrameworkHiiRemovePack
= FALSE
;
25 GetIfrAndStringPackNum (
26 IN CONST EFI_HII_PACKAGES
*Packages
,
32 TIANO_AUTOGEN_PACKAGES_HEADER
**TianoAutogenPackageHdrArray
;
34 ASSERT (Packages
!= NULL
);
35 ASSERT (IfrPackNum
!= NULL
);
36 ASSERT (StringPackNum
!= NULL
);
41 TianoAutogenPackageHdrArray
= (TIANO_AUTOGEN_PACKAGES_HEADER
**) (((UINT8
*) &Packages
->GuidId
) + sizeof (Packages
->GuidId
));
42 for (Index
= 0; Index
< Packages
->NumberOfPackages
; Index
++) {
44 // BugBug: The current UEFI HII build tool generate a binary in the format defined in:
45 // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in
46 // this binary is with same package type. So the returned IfrPackNum and StringPackNum
47 // may not be the exact number of valid package number in the binary generated
50 switch (TianoAutogenPackageHdrArray
[Index
]->PackageHeader
.Type
) {
51 case EFI_HII_PACKAGE_FORM
:
54 case EFI_HII_PACKAGE_STRINGS
:
58 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
62 // The following fonts are invalid for a module that using Framework to UEFI thunk layer.
64 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
65 case EFI_HII_PACKAGE_FONTS
:
66 case EFI_HII_PACKAGE_IMAGES
:
69 return EFI_INVALID_PARAMETER
;
78 LibExportPackageLists (
79 IN EFI_HII_HANDLE UefiHiiHandle
,
80 OUT EFI_HII_PACKAGE_LIST_HEADER
**PackageListHeader
,
81 OUT UINTN
*PackageListSize
86 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHdr
;
88 ASSERT (PackageListSize
!= NULL
);
89 ASSERT (PackageListHeader
!= NULL
);
92 PackageListHdr
= NULL
;
93 Status
= mHiiDatabase
->ExportPackageLists (
99 ASSERT_EFI_ERROR (Status
== EFI_BUFFER_TOO_SMALL
);
100 if (Status
== EFI_BUFFER_TOO_SMALL
) {
101 PackageListHdr
= AllocateZeroPool (Size
);
102 ASSERT (PackageListHdr
!= NULL
);
104 if (PackageListHeader
== NULL
) {
105 return EFI_OUT_OF_RESOURCES
;
107 Status
= mHiiDatabase
->ExportPackageLists (
113 ASSERT_EFI_ERROR (Status
);
117 if (!EFI_ERROR (Status
)) {
118 *PackageListHeader
= PackageListHdr
;
119 *PackageListSize
= Size
;
126 InsertStringPackagesToIfrPackageList (
127 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*StringPackageListHeader
,
128 IN EFI_HII_HANDLE UefiHiiHandle
132 Status
= mHiiDatabase
->UpdatePackageList (
135 StringPackageListHeader
143 Removes a node from a doubly linked list, and returns the node that follows
146 Removes the node Entry from a doubly linked list. It is up to the caller of
147 this function to release the memory used by this node if that is required. On
148 exit, the node following Entry in the doubly linked list is returned. If
149 Entry is the only node in the linked list, then the head node of the linked
152 If Entry is NULL, then ASSERT().
153 If Entry is the head node of an empty list, then ASSERT().
154 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
155 linked list containing Entry, including the Entry node, is greater than
156 or equal to PcdMaximumLinkedListLength, then ASSERT().
158 @param Entry A pointer to a node in a linked list
164 AddStringPackagesToMatchingIfrPackageList (
165 IN EFI_HII_THUNK_PRIVATE_DATA
*Private
,
166 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*StringPackageListHeader
170 LIST_ENTRY
*ListEntry
;
171 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
;
173 for (ListEntry
= Private
->HiiThunkHandleMappingDBListHead
.ForwardLink
;
174 ListEntry
!= &Private
->HiiThunkHandleMappingDBListHead
;
175 ListEntry
= ListEntry
->ForwardLink
177 HandleMapEntry
= HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry
);
178 if (CompareGuid (&StringPackageListHeader
->PackageListGuid
, &HandleMapEntry
->TagGuid
)) {
179 Status
= InsertStringPackagesToIfrPackageList (StringPackageListHeader
, HandleMapEntry
->UefiHiiHandle
);
183 return EFI_NOT_FOUND
;
185 EFI_HII_PACKAGE_LIST_HEADER
*
186 PrepareUefiPackageListFromFrameworkHiiPackages (
187 IN CONST EFI_HII_PACKAGES
*Packages
,
188 IN CONST EFI_GUID
*PackageListGuid
191 UINTN NumberOfPackages
;
192 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
193 UINT8
*PackageListData
;
194 UINT32 PackageListLength
;
195 UINT32 PackageLength
;
196 EFI_HII_PACKAGE_HEADER PackageHeader
;
198 TIANO_AUTOGEN_PACKAGES_HEADER
**TianoAutogenPackageHdrArray
;
200 ASSERT (Packages
!= NULL
);
201 ASSERT (PackageListGuid
!= NULL
);
203 TianoAutogenPackageHdrArray
= (TIANO_AUTOGEN_PACKAGES_HEADER
**) ((UINT8
*) &Packages
->GuidId
+ sizeof (Packages
->GuidId
));
204 NumberOfPackages
= Packages
->NumberOfPackages
;
206 PackageListLength
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
208 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
209 CopyMem (&PackageLength
, &TianoAutogenPackageHdrArray
[Index
]->BinaryLength
, sizeof (UINT32
));
211 //TIANO_AUTOGEN_PACKAGES_HEADER.BinaryLength include the BinaryLength itself.
213 PackageListLength
+= (PackageLength
- sizeof(UINT32
));
217 // Include the lenght of EFI_HII_PACKAGE_END
219 PackageListLength
+= sizeof (EFI_HII_PACKAGE_HEADER
);
220 PackageListHeader
= AllocateZeroPool (PackageListLength
);
221 ASSERT (PackageListHeader
!= NULL
);
223 CopyMem (&PackageListHeader
->PackageListGuid
, PackageListGuid
, sizeof (EFI_GUID
));
224 PackageListHeader
->PackageLength
= PackageListLength
;
226 PackageListData
= ((UINT8
*) PackageListHeader
) + sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
228 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
229 CopyMem (&PackageLength
, &(TianoAutogenPackageHdrArray
[Index
]->BinaryLength
), sizeof (UINT32
));
230 PackageLength
-= sizeof (UINT32
);
231 CopyMem (PackageListData
, &(TianoAutogenPackageHdrArray
[Index
]->PackageHeader
), PackageLength
);
232 PackageListData
+= PackageLength
;
236 // Append EFI_HII_PACKAGE_END
238 PackageHeader
.Type
= EFI_HII_PACKAGE_END
;
239 PackageHeader
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
240 CopyMem (PackageListData
, &PackageHeader
, PackageHeader
.Length
);
242 return PackageListHeader
;
247 IN CONST EFI_GUID
* InGuid
,
248 OUT EFI_GUID
* OutGuid
251 UINT64 MonotonicCount
;
253 CopyMem (OutGuid
, InGuid
, sizeof (EFI_GUID
));
255 gBS
->GetNextMonotonicCount (&MonotonicCount
);
257 // Use Monotonic Count as a psedo random number generator.
259 *((UINT64
*) OutGuid
) = *((UINT64
*) OutGuid
) + MonotonicCount
;
263 FindAndAddStringPackageToIfrPackageList(
264 EFI_HII_THUNK_PRIVATE_DATA
*Private
,
266 EFI_HII_HANDLE UefiIfrHiiHandle
270 LIST_ENTRY
*ListEntry
;
271 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
;
272 EFI_HII_PACKAGE_LIST_HEADER
*StringPackageListHeader
;
275 for (ListEntry
= Private
->HiiThunkHandleMappingDBListHead
.ForwardLink
;
276 ListEntry
!= &Private
->HiiThunkHandleMappingDBListHead
;
277 ListEntry
= ListEntry
->ForwardLink
279 HandleMapEntry
= HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry
);
280 if (CompareGuid (GuidId
, &HandleMapEntry
->TagGuid
) && (!HandleMapEntry
->DoesPackageListImportStringPackages
)) {
281 Status
= LibExportPackageLists (HandleMapEntry
->UefiHiiHandle
, &StringPackageListHeader
, &Size
);
282 ASSERT_EFI_ERROR (Status
);
285 // Add Function to only get only String Packages from the Package List
288 Status
= InsertStringPackagesToIfrPackageList (StringPackageListHeader
, UefiIfrHiiHandle
);
289 ASSERT_EFI_ERROR (Status
);
291 FreePool (StringPackageListHeader
);
296 return EFI_NOT_FOUND
;
300 CONST EFI_GUID mAGuid
=
301 { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e } };
304 UefiRegisterPackageList(
305 EFI_HII_THUNK_PRIVATE_DATA
*Private
,
306 EFI_HII_PACKAGES
*Packages
,
307 FRAMEWORK_EFI_HII_HANDLE
*Handle
313 EFI_HII_PACKAGE_LIST_HEADER
*UefiPackageListHeader
;
314 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMappingEntry
;
317 UefiPackageListHeader
= NULL
;
319 Status
= GetIfrAndStringPackNum (Packages
, &IfrPackNum
, &StringPackNum
);
320 ASSERT_EFI_ERROR (Status
);
322 // Thunk Layer only handle the following combinations of IfrPack, StringPkg and FontPack.
323 // Thunk Layer only allow zero or one IfrPack in the Package List.
325 if (IfrPackNum
> 1) {
326 return EFI_UNSUPPORTED
;
329 HandleMappingEntry
= AllocateZeroPool (sizeof (*HandleMappingEntry
));
330 ASSERT (HandleMappingEntry
!= NULL
);
332 HandleMappingEntry
->Signature
= HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE
;
333 Status
= AssignHiiHandle (Private
, &HandleMappingEntry
->FrameworkHiiHandle
);
334 if (EFI_ERROR (Status
)) {
339 // Packages->GuidId may be NULL. In such case, caller of FramworkHii->NewPack is registering
340 // package with StringPack and IfrPack.
342 if (Packages
->GuidId
== NULL
) {
343 Packages
->GuidId
= &GuidId
;
344 GenerateGuidId (&mAGuid
, Packages
->GuidId
);
346 CopyGuid (&GuidId
, Packages
->GuidId
);
349 CopyGuid (&HandleMappingEntry
->TagGuid
, Packages
->GuidId
);
351 if ((StringPackNum
== 0) && (IfrPackNum
!= 0)) {
353 // UEFI HII database does not allow two package list with the same GUID.
354 // In Framework HII implementation, Packages->GuidId is used as an identifier to associate
355 // a PackageList with only IFR to a Package list the with String package.
357 GenerateGuidId (Packages
->GuidId
, &GuidId
);
361 // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so
362 // that Setup Utility can load the Buffer Storage using this protocol.
364 if (IfrPackNum
!= 0) {
365 InstallDefaultUefiConfigAccessProtocol (Packages
, HandleMappingEntry
);
367 UefiPackageListHeader
= PrepareUefiPackageListFromFrameworkHiiPackages (Packages
, &GuidId
);
368 Status
= mHiiDatabase
->NewPackageList (
370 UefiPackageListHeader
,
371 HandleMappingEntry
->UefiHiiDriverHandle
,
372 &HandleMappingEntry
->UefiHiiHandle
374 ASSERT_EFI_ERROR (Status
);
375 if (EFI_ERROR (Status
)) {
379 if (IfrPackNum
== 0) {
380 if (StringPackNum
!= 0) {
382 // Look for a package list with IFR Pack which has already registed with HII Database
384 HandleMappingEntry
->IsPackageListWithOnlyStringPackages
= TRUE
;
385 Status
= AddStringPackagesToMatchingIfrPackageList (
387 UefiPackageListHeader
390 if (!EFI_ERROR (Status
) || Status
== EFI_NOT_FOUND
) {
392 if (Status
== EFI_NOT_FOUND
) {
393 Status
= EFI_SUCCESS
;
398 if (StringPackNum
== 0) {
400 // Register the Package List to UEFI HII first.
402 Status
= FindAndAddStringPackageToIfrPackageList (
405 HandleMappingEntry
->UefiHiiHandle
407 ASSERT_EFI_ERROR (Status
);
408 if (!EFI_ERROR (Status
)) {
409 HandleMappingEntry
->DoesPackageListImportStringPackages
= TRUE
;
414 if (!EFI_ERROR (Status
)) {
415 InsertTailList (&Private
->HiiThunkHandleMappingDBListHead
, &HandleMappingEntry
->List
);
419 if (EFI_ERROR (Status
)) {
420 FreePool (HandleMappingEntry
);
422 *Handle
= HandleMappingEntry
->FrameworkHiiHandle
;
425 SafeFreePool (UefiPackageListHeader
);
434 IN EFI_HII_PROTOCOL
*This
,
435 IN EFI_HII_PACKAGES
*Packages
,
436 OUT FRAMEWORK_EFI_HII_HANDLE
*Handle
442 Extracts the various packs from a package list.
446 This - Pointer of HII protocol.
447 Packages - Pointer of HII packages.
448 Handle - Handle value to be returned.
452 EFI_SUCCESS - Pacakges has added to HII database successfully.
453 EFI_INVALID_PARAMETER - Invalid parameter.
458 EFI_HII_THUNK_PRIVATE_DATA
*Private
;
461 if (Handle
== NULL
) {
462 return EFI_INVALID_PARAMETER
;
465 if (Packages
== NULL
) {
466 return EFI_INVALID_PARAMETER
;
469 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
472 // We use a simple Global variable to inform NewPackNotify
473 // that the package list registered here is already registered
474 // in the HII Thunk Layer. So NewPackNotify does not need to
475 // call RegisterUefiHiiHandle () to registered it.
477 mInFrameworkHiiNewPack
= TRUE
;
479 Private
= EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
481 Status
= UefiRegisterPackageList (
487 mInFrameworkHiiNewPack
= FALSE
;
489 gBS
->RestoreTPL (OldTpl
);
497 IN EFI_HII_PROTOCOL
*This
,
498 IN FRAMEWORK_EFI_HII_HANDLE Handle
503 Removes the various packs from a Handle
512 EFI_HII_THUNK_PRIVATE_DATA
*Private
;
513 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
;
515 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
517 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
519 mInFrameworkHiiRemovePack
= TRUE
;
521 Private
= EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
523 HandleMapEntry
= FrameworkHiiHandleToMapDatabaseEntry (Private
, Handle
);
525 if (HandleMapEntry
!= NULL
) {
526 Status
= mHiiDatabase
->RemovePackageList (
528 HandleMapEntry
->UefiHiiHandle
530 ASSERT_EFI_ERROR (Status
);
532 HiiLibDestroyHiiDriverHandle (HandleMapEntry
->UefiHiiHandle
);
534 Status
= gBS
->HandleProtocol (
535 HandleMapEntry
->UefiHiiDriverHandle
,
536 &gEfiHiiConfigAccessProtocolGuid
,
537 (VOID
**) &ConfigAccess
540 if (!EFI_ERROR (Status
)) {
541 Status
= gBS
->UninstallProtocolInterface (
542 HandleMapEntry
->UefiHiiDriverHandle
,
543 &gEfiHiiConfigAccessProtocolGuid
,
546 ASSERT_EFI_ERROR (Status
);
548 Status
= EFI_SUCCESS
;
551 RemoveEntryList (&HandleMapEntry
->List
);
553 FreePool (HandleMapEntry
);
556 Status
= EFI_NOT_FOUND
;
559 mInFrameworkHiiRemovePack
= FALSE
;
561 gBS
->RestoreTPL (OldTpl
);