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"
21 GetIfrAndStringPackNum (
22 IN CONST EFI_HII_PACKAGES
*Packages
,
28 TIANO_AUTOGEN_PACKAGES_HEADER
**TianoAutogenPackageHdrArray
;
30 ASSERT (Packages
!= NULL
);
31 ASSERT (IfrPackNum
!= NULL
);
32 ASSERT (StringPackNum
!= NULL
);
37 TianoAutogenPackageHdrArray
= (TIANO_AUTOGEN_PACKAGES_HEADER
**) (((UINT8
*) &Packages
->GuidId
) + sizeof (Packages
->GuidId
));
38 for (Index
= 0; Index
< Packages
->NumberOfPackages
; Index
++) {
40 // BugBug: The current UEFI HII build tool generate a binary in the format defined in:
41 // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in
42 // this binary is with same package type. So the returned IfrPackNum and StringPackNum
43 // may not be the exact number of valid package number in the binary generated
46 switch (TianoAutogenPackageHdrArray
[Index
]->PackageHeader
.Type
) {
47 case EFI_HII_PACKAGE_FORM
:
50 case EFI_HII_PACKAGE_STRINGS
:
54 case EFI_HII_PACKAGE_SIMPLE_FONTS
:
58 // The following fonts are invalid for a module that using Framework to UEFI thunk layer.
60 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT
:
61 case EFI_HII_PACKAGE_FONTS
:
62 case EFI_HII_PACKAGE_IMAGES
:
65 return EFI_INVALID_PARAMETER
;
74 LibExportPackageLists (
75 IN EFI_HII_HANDLE UefiHiiHandle
,
76 OUT EFI_HII_PACKAGE_LIST_HEADER
**PackageListHeader
,
77 OUT UINTN
*PackageListSize
82 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHdr
;
84 ASSERT (PackageListSize
!= NULL
);
85 ASSERT (PackageListHeader
!= NULL
);
88 PackageListHdr
= NULL
;
89 Status
= mUefiHiiDatabaseProtocol
->ExportPackageLists (
90 mUefiHiiDatabaseProtocol
,
95 ASSERT_EFI_ERROR (Status
== EFI_BUFFER_TOO_SMALL
);
96 if (Status
== EFI_BUFFER_TOO_SMALL
) {
97 PackageListHdr
= AllocateZeroPool (Size
);
98 ASSERT (PackageListHdr
!= NULL
);
100 if (PackageListHeader
== NULL
) {
101 return EFI_OUT_OF_RESOURCES
;
103 Status
= mUefiHiiDatabaseProtocol
->ExportPackageLists (
104 mUefiHiiDatabaseProtocol
,
109 ASSERT_EFI_ERROR (Status
);
113 if (!EFI_ERROR (Status
)) {
114 *PackageListHeader
= PackageListHdr
;
115 *PackageListSize
= Size
;
122 IsOnlyStringPackagesInPackageList (
123 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*StringPackageListHeader
126 EFI_HII_PACKAGE_HEADER
*PackageHeader
;
128 PackageHeader
= (EFI_HII_PACKAGE_HEADER
*) (StringPackageListHeader
+ 1);
130 while (PackageHeader
->Type
!= EFI_HII_PACKAGE_END
) {
131 PackageHeader
= (EFI_HII_PACKAGE_HEADER
*) (PackageHeader
);
137 InsertStringPackagesToIfrPackageList (
138 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*StringPackageListHeader
,
139 IN EFI_HII_HANDLE UefiHiiHandle
143 Status
= mUefiHiiDatabaseProtocol
->UpdatePackageList (
144 mUefiHiiDatabaseProtocol
,
146 StringPackageListHeader
154 Removes a node from a doubly linked list, and returns the node that follows
157 Removes the node Entry from a doubly linked list. It is up to the caller of
158 this function to release the memory used by this node if that is required. On
159 exit, the node following Entry in the doubly linked list is returned. If
160 Entry is the only node in the linked list, then the head node of the linked
163 If Entry is NULL, then ASSERT().
164 If Entry is the head node of an empty list, then ASSERT().
165 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
166 linked list containing Entry, including the Entry node, is greater than
167 or equal to PcdMaximumLinkedListLength, then ASSERT().
169 @param Entry A pointer to a node in a linked list
175 AddStringPackagesToMatchingIfrPackageList (
176 IN EFI_HII_THUNK_PRIVATE_DATA
*Private
,
177 IN CONST EFI_HII_PACKAGE_LIST_HEADER
*StringPackageListHeader
181 LIST_ENTRY
*ListEntry
;
182 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
;
184 for (ListEntry
= Private
->HiiThunkHandleMappingDBListHead
.ForwardLink
;
185 ListEntry
!= &Private
->HiiThunkHandleMappingDBListHead
;
186 ListEntry
= ListEntry
->ForwardLink
188 HandleMapEntry
= HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry
);
189 if (CompareGuid (&StringPackageListHeader
->PackageListGuid
, &HandleMapEntry
->TagGuid
)) {
190 Status
= InsertStringPackagesToIfrPackageList (StringPackageListHeader
, HandleMapEntry
->UefiHiiHandle
);
194 return EFI_NOT_FOUND
;
196 EFI_HII_PACKAGE_LIST_HEADER
*
197 PrepareUefiPackageListFromFrameworkHiiPackages (
198 IN CONST EFI_HII_PACKAGES
*Packages
,
199 IN CONST EFI_GUID
*GuidId OPTIONAL
202 UINTN NumberOfPackages
;
203 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
204 UINT8
*PackageListData
;
205 UINT32 PackageListLength
;
206 UINT32 PackageLength
;
207 EFI_HII_PACKAGE_HEADER PackageHeader
;
209 TIANO_AUTOGEN_PACKAGES_HEADER
**TianoAutogenPackageHdrArray
;
211 TianoAutogenPackageHdrArray
= (TIANO_AUTOGEN_PACKAGES_HEADER
**) ((UINT8
*) &Packages
->GuidId
+ sizeof (Packages
->GuidId
));
212 NumberOfPackages
= Packages
->NumberOfPackages
;
214 PackageListLength
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
216 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
217 CopyMem (&PackageLength
, &TianoAutogenPackageHdrArray
[Index
]->BinaryLength
, sizeof (UINT32
));
218 PackageListLength
+= PackageLength
;
222 // Include the lenght of EFI_HII_PACKAGE_END
224 PackageListLength
+= sizeof (EFI_HII_PACKAGE_HEADER
);
225 PackageListHeader
= AllocateZeroPool (PackageListLength
);
226 ASSERT (PackageListHeader
!= NULL
);
227 if (GuidId
== NULL
) {
228 CopyMem (&PackageListHeader
->PackageListGuid
, Packages
->GuidId
, sizeof (EFI_GUID
));
230 CopyMem (&PackageListHeader
->PackageListGuid
, GuidId
, sizeof (EFI_GUID
));
232 PackageListHeader
->PackageLength
= PackageListLength
;
234 PackageListData
= ((UINT8
*) PackageListHeader
) + sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
236 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
237 CopyMem (&PackageLength
, &(TianoAutogenPackageHdrArray
[Index
]->BinaryLength
), sizeof (UINT32
));
238 PackageLength
-= sizeof (UINT32
);
239 CopyMem (PackageListData
, &(TianoAutogenPackageHdrArray
[Index
]->PackageHeader
), PackageLength
);
240 PackageListData
+= PackageLength
;
244 // Append EFI_HII_PACKAGE_END
246 PackageHeader
.Type
= EFI_HII_PACKAGE_END
;
247 PackageHeader
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
248 CopyMem (PackageListData
, &PackageHeader
, PackageHeader
.Length
);
250 return PackageListHeader
;
254 UefiGeneratePackageListGuidId (
255 IN CONST EFI_HII_PACKAGES
* Packages
259 UINT64 MonotonicCount
;
261 Guid
= AllocateCopyPool (sizeof (EFI_GUID
), Packages
->GuidId
);
263 gBS
->GetNextMonotonicCount (&MonotonicCount
);
265 // Use Monotonic Count as a psedo random number generator.
267 *((UINT64
*) Guid
) = *((UINT64
*) Guid
) + MonotonicCount
;
273 FindAndAddStringPackageToIfrPackageList(
274 EFI_HII_THUNK_PRIVATE_DATA
*Private
,
276 EFI_HII_HANDLE UefiIfrHiiHandle
280 LIST_ENTRY
*ListEntry
;
281 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
;
282 EFI_HII_PACKAGE_LIST_HEADER
*StringPackageListHeader
;
285 for (ListEntry
= Private
->HiiThunkHandleMappingDBListHead
.ForwardLink
;
286 ListEntry
!= &Private
->HiiThunkHandleMappingDBListHead
;
287 ListEntry
= ListEntry
->ForwardLink
289 HandleMapEntry
= HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry
);
290 if (CompareGuid (GuidId
, &HandleMapEntry
->TagGuid
) && (!HandleMapEntry
->DoesPackageListImportStringPackages
)) {
291 Status
= LibExportPackageLists (HandleMapEntry
->UefiHiiHandle
, &StringPackageListHeader
, &Size
);
292 ASSERT_EFI_ERROR (Status
);
295 // Add Function to only get only String Packages from the Package List
298 Status
= InsertStringPackagesToIfrPackageList (StringPackageListHeader
, UefiIfrHiiHandle
);
299 ASSERT_EFI_ERROR (Status
);
301 FreePool (StringPackageListHeader
);
306 return EFI_NOT_FOUND
;
311 InstallDefaultUefiConfigAccessProtocol (
312 IN EFI_HII_PACKAGES
*Packages
,
313 OUT EFI_HANDLE
*Handle
320 UefiRegisterPackageList(
321 EFI_HII_THUNK_PRIVATE_DATA
*Private
,
322 EFI_HII_PACKAGES
*Packages
,
323 FRAMEWORK_EFI_HII_HANDLE
*Handle
329 EFI_HII_PACKAGE_LIST_HEADER
*UefiPackageListHeader
;
330 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMappingEntry
;
332 EFI_HANDLE UefiHiiDriverHandle
;
335 UefiHiiDriverHandle
= NULL
;
337 Status
= GetIfrAndStringPackNum (Packages
, &IfrPackNum
, &StringPackNum
);
338 ASSERT_EFI_ERROR (Status
);
340 HandleMappingEntry
= AllocateZeroPool (sizeof (*HandleMappingEntry
));
341 ASSERT (HandleMappingEntry
!= NULL
);
343 HandleMappingEntry
->Signature
= HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE
;
344 HandleMappingEntry
->FrameworkHiiHandle
= Private
->StaticHiiHandle
++;
345 CopyGuid (&HandleMappingEntry
->TagGuid
, Packages
->GuidId
);
347 if ((StringPackNum
== 0) && (IfrPackNum
!= 0)) {
349 // UEFI HII database does not allow two package list with the same GUID.
350 // In Framework HII implementation, Packages->GuidId is used as an identifier to associate
351 // a PackageList with only IFR to a Package list the with String package.
353 GuidId
= UefiGeneratePackageListGuidId (Packages
);
357 // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so
358 // that Setup Utility will load the Buffer Storage
360 if (IfrPackNum
!= 0) {
361 InstallDefaultUefiConfigAccessProtocol (Packages
, &UefiHiiDriverHandle
);
363 UefiPackageListHeader
= PrepareUefiPackageListFromFrameworkHiiPackages (Packages
, GuidId
);
364 Status
= mUefiHiiDatabaseProtocol
->NewPackageList (
365 mUefiHiiDatabaseProtocol
,
366 UefiPackageListHeader
,
368 &HandleMappingEntry
->UefiHiiHandle
370 ASSERT_EFI_ERROR (Status
);
371 if (EFI_ERROR (Status
)) {
375 if (IfrPackNum
== 0) {
376 if (StringPackNum
!= 0) {
378 // Look for a package list with IFR Pack which has already registed with HII Database
380 HandleMappingEntry
->IsPackageListWithOnlyStringPackages
= TRUE
;
381 Status
= AddStringPackagesToMatchingIfrPackageList (
383 UefiPackageListHeader
386 if (!EFI_ERROR (Status
) || Status
== EFI_NOT_FOUND
) {
388 if (Status
== EFI_NOT_FOUND
) {
389 Status
= EFI_SUCCESS
;
394 if (StringPackNum
== 0) {
396 // Register the Package List to UEFI HII first.
398 Status
= FindAndAddStringPackageToIfrPackageList (
401 HandleMappingEntry
->UefiHiiHandle
403 ASSERT_EFI_ERROR (Status
);
404 if (!EFI_ERROR (Status
)) {
405 HandleMappingEntry
->DoesPackageListImportStringPackages
= TRUE
;
410 if (!EFI_ERROR (Status
)) {
411 InsertTailList (&Private
->HiiThunkHandleMappingDBListHead
, &HandleMappingEntry
->List
);
415 if (EFI_ERROR (Status
)) {
416 FreePool (HandleMappingEntry
);
418 *Handle
= HandleMappingEntry
->FrameworkHiiHandle
;
421 FreePool (UefiPackageListHeader
);
422 SafeFreePool (GuidId
);
430 IN EFI_HII_PROTOCOL
*This
,
431 IN EFI_HII_PACKAGES
*Packages
,
432 OUT FRAMEWORK_EFI_HII_HANDLE
*Handle
438 Extracts the various packs from a package list.
442 This - Pointer of HII protocol.
443 Packages - Pointer of HII packages.
444 Handle - Handle value to be returned.
448 EFI_SUCCESS - Pacakges has added to HII database successfully.
449 EFI_INVALID_PARAMETER - Invalid parameter.
454 EFI_HII_THUNK_PRIVATE_DATA
*Private
;
456 if (Handle
== NULL
) {
457 return EFI_INVALID_PARAMETER
;
460 if (Packages
== NULL
) {
461 return EFI_INVALID_PARAMETER
;
464 Private
= EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
466 Status
= UefiRegisterPackageList (
478 IN EFI_HII_PROTOCOL
*This
,
479 IN FRAMEWORK_EFI_HII_HANDLE Handle
484 Removes the various packs from a Handle
493 EFI_HII_THUNK_PRIVATE_DATA
*Private
;
494 LIST_ENTRY
*ListEntry
;
495 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
;
497 Private
= EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
499 for (ListEntry
= Private
->HiiThunkHandleMappingDBListHead
.ForwardLink
;
500 ListEntry
!= &Private
->HiiThunkHandleMappingDBListHead
;
501 ListEntry
= ListEntry
->ForwardLink
503 HandleMapEntry
= HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry
);
505 if (Handle
== HandleMapEntry
->FrameworkHiiHandle
) {
506 Status
= mUefiHiiDatabaseProtocol
->RemovePackageList (
507 mUefiHiiDatabaseProtocol
,
508 HandleMapEntry
->UefiHiiHandle
510 ASSERT_EFI_ERROR (Status
);
512 RemoveEntryList (ListEntry
);
517 return EFI_NOT_FOUND
;