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
= mHiiDatabase
->ExportPackageLists (
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
= mHiiDatabase
->ExportPackageLists (
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
= mHiiDatabase
->UpdatePackageList (
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
));
219 //TIANO_AUTOGEN_PACKAGES_HEADER.BinaryLength include the BinaryLength itself.
221 PackageListLength
+= (PackageLength
- sizeof(UINT32
));
225 // Include the lenght of EFI_HII_PACKAGE_END
227 PackageListLength
+= sizeof (EFI_HII_PACKAGE_HEADER
);
228 PackageListHeader
= AllocateZeroPool (PackageListLength
);
229 ASSERT (PackageListHeader
!= NULL
);
230 if (GuidId
== NULL
) {
231 CopyMem (&PackageListHeader
->PackageListGuid
, Packages
->GuidId
, sizeof (EFI_GUID
));
233 CopyMem (&PackageListHeader
->PackageListGuid
, GuidId
, sizeof (EFI_GUID
));
235 PackageListHeader
->PackageLength
= PackageListLength
;
237 PackageListData
= ((UINT8
*) PackageListHeader
) + sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
239 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
240 CopyMem (&PackageLength
, &(TianoAutogenPackageHdrArray
[Index
]->BinaryLength
), sizeof (UINT32
));
241 PackageLength
-= sizeof (UINT32
);
242 CopyMem (PackageListData
, &(TianoAutogenPackageHdrArray
[Index
]->PackageHeader
), PackageLength
);
243 PackageListData
+= PackageLength
;
247 // Append EFI_HII_PACKAGE_END
249 PackageHeader
.Type
= EFI_HII_PACKAGE_END
;
250 PackageHeader
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
251 CopyMem (PackageListData
, &PackageHeader
, PackageHeader
.Length
);
253 return PackageListHeader
;
258 IN CONST EFI_GUID
* InGuid
,
259 OUT EFI_GUID
* OutGuid
262 UINT64 MonotonicCount
;
264 CopyMem (OutGuid
, InGuid
, sizeof (EFI_GUID
));
266 gBS
->GetNextMonotonicCount (&MonotonicCount
);
268 // Use Monotonic Count as a psedo random number generator.
270 *((UINT64
*) OutGuid
) = *((UINT64
*) OutGuid
) + MonotonicCount
;
274 FindAndAddStringPackageToIfrPackageList(
275 EFI_HII_THUNK_PRIVATE_DATA
*Private
,
277 EFI_HII_HANDLE UefiIfrHiiHandle
281 LIST_ENTRY
*ListEntry
;
282 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
;
283 EFI_HII_PACKAGE_LIST_HEADER
*StringPackageListHeader
;
286 for (ListEntry
= Private
->HiiThunkHandleMappingDBListHead
.ForwardLink
;
287 ListEntry
!= &Private
->HiiThunkHandleMappingDBListHead
;
288 ListEntry
= ListEntry
->ForwardLink
290 HandleMapEntry
= HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry
);
291 if (CompareGuid (GuidId
, &HandleMapEntry
->TagGuid
) && (!HandleMapEntry
->DoesPackageListImportStringPackages
)) {
292 Status
= LibExportPackageLists (HandleMapEntry
->UefiHiiHandle
, &StringPackageListHeader
, &Size
);
293 ASSERT_EFI_ERROR (Status
);
296 // Add Function to only get only String Packages from the Package List
299 Status
= InsertStringPackagesToIfrPackageList (StringPackageListHeader
, UefiIfrHiiHandle
);
300 ASSERT_EFI_ERROR (Status
);
302 FreePool (StringPackageListHeader
);
307 return EFI_NOT_FOUND
;
311 CONST EFI_GUID mAGuid
=
312 { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e } };
315 UefiRegisterPackageList(
316 EFI_HII_THUNK_PRIVATE_DATA
*Private
,
317 EFI_HII_PACKAGES
*Packages
,
318 FRAMEWORK_EFI_HII_HANDLE
*Handle
324 EFI_HII_PACKAGE_LIST_HEADER
*UefiPackageListHeader
;
325 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMappingEntry
;
327 EFI_HANDLE UefiHiiDriverHandle
;
329 UefiHiiDriverHandle
= NULL
;
331 Status
= GetIfrAndStringPackNum (Packages
, &IfrPackNum
, &StringPackNum
);
332 ASSERT_EFI_ERROR (Status
);
334 // Thunk Layer only handle the following combinations of IfrPack, StringPkg and FontPack.
335 // Thunk Layer only allow zero or one IfrPack in the Package List.
337 if (IfrPackNum
> 1) {
338 return EFI_UNSUPPORTED
;
341 HandleMappingEntry
= AllocateZeroPool (sizeof (*HandleMappingEntry
));
342 ASSERT (HandleMappingEntry
!= NULL
);
344 HandleMappingEntry
->Signature
= HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE
;
345 HandleMappingEntry
->FrameworkHiiHandle
= Private
->StaticHiiHandle
++;
348 // Packages->GuidId may be NULL. In such case, caller of FramworkHii->NewPack is registering
349 // package with StringPack and IfrPack.
351 if (Packages
->GuidId
== NULL
) {
352 Packages
->GuidId
= &GuidId
;
353 GenerateGuidId (&mAGuid
, Packages
->GuidId
);
356 CopyGuid (&HandleMappingEntry
->TagGuid
, Packages
->GuidId
);
358 if ((StringPackNum
== 0) && (IfrPackNum
!= 0)) {
360 // UEFI HII database does not allow two package list with the same GUID.
361 // In Framework HII implementation, Packages->GuidId is used as an identifier to associate
362 // a PackageList with only IFR to a Package list the with String package.
364 GenerateGuidId (Packages
->GuidId
, &GuidId
);
368 // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so
369 // that Setup Utility can load the Buffer Storage using this protocol.
371 if (IfrPackNum
!= 0) {
372 InstallDefaultUefiConfigAccessProtocol (Packages
, &UefiHiiDriverHandle
, HandleMappingEntry
);
374 UefiPackageListHeader
= PrepareUefiPackageListFromFrameworkHiiPackages (Packages
, &GuidId
);
375 Status
= mHiiDatabase
->NewPackageList (
377 UefiPackageListHeader
,
379 &HandleMappingEntry
->UefiHiiHandle
381 ASSERT_EFI_ERROR (Status
);
382 if (EFI_ERROR (Status
)) {
386 if (IfrPackNum
== 0) {
387 if (StringPackNum
!= 0) {
389 // Look for a package list with IFR Pack which has already registed with HII Database
391 HandleMappingEntry
->IsPackageListWithOnlyStringPackages
= TRUE
;
392 Status
= AddStringPackagesToMatchingIfrPackageList (
394 UefiPackageListHeader
397 if (!EFI_ERROR (Status
) || Status
== EFI_NOT_FOUND
) {
399 if (Status
== EFI_NOT_FOUND
) {
400 Status
= EFI_SUCCESS
;
405 if (StringPackNum
== 0) {
407 // Register the Package List to UEFI HII first.
409 Status
= FindAndAddStringPackageToIfrPackageList (
412 HandleMappingEntry
->UefiHiiHandle
414 ASSERT_EFI_ERROR (Status
);
415 if (!EFI_ERROR (Status
)) {
416 HandleMappingEntry
->DoesPackageListImportStringPackages
= TRUE
;
421 if (!EFI_ERROR (Status
)) {
422 InsertTailList (&Private
->HiiThunkHandleMappingDBListHead
, &HandleMappingEntry
->List
);
426 if (EFI_ERROR (Status
)) {
427 FreePool (HandleMappingEntry
);
429 *Handle
= HandleMappingEntry
->FrameworkHiiHandle
;
432 FreePool (UefiPackageListHeader
);
440 IN EFI_HII_PROTOCOL
*This
,
441 IN EFI_HII_PACKAGES
*Packages
,
442 OUT FRAMEWORK_EFI_HII_HANDLE
*Handle
448 Extracts the various packs from a package list.
452 This - Pointer of HII protocol.
453 Packages - Pointer of HII packages.
454 Handle - Handle value to be returned.
458 EFI_SUCCESS - Pacakges has added to HII database successfully.
459 EFI_INVALID_PARAMETER - Invalid parameter.
464 EFI_HII_THUNK_PRIVATE_DATA
*Private
;
466 if (Handle
== NULL
) {
467 return EFI_INVALID_PARAMETER
;
470 if (Packages
== NULL
) {
471 return EFI_INVALID_PARAMETER
;
474 Private
= EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
476 Status
= UefiRegisterPackageList (
488 IN EFI_HII_PROTOCOL
*This
,
489 IN FRAMEWORK_EFI_HII_HANDLE Handle
494 Removes the various packs from a Handle
503 EFI_HII_THUNK_PRIVATE_DATA
*Private
;
504 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
;
505 EFI_DEVICE_PATH_PROTOCOL
*Path
;
507 Private
= EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
509 HandleMapEntry
= FrameworkHiiHandleToMapDatabaseEntry (Private
, Handle
);
511 if (HandleMapEntry
->UefiHiiHandle
!= NULL
) {
512 Status
= mHiiDatabase
->RemovePackageList (
514 HandleMapEntry
->UefiHiiHandle
516 ASSERT_EFI_ERROR (Status
);
518 Status
= gBS
->HandleProtocol (
519 HandleMapEntry
->UefiHiiHandle
,
520 &gEfiDevicePathProtocolGuid
,
524 if (!EFI_ERROR (Status
)) {
525 Status
= gBS
->UninstallProtocolInterface (
526 HandleMapEntry
->UefiHiiHandle
,
527 &gEfiDevicePathProtocolGuid
,
530 if (!EFI_ERROR (Status
)) {
535 RemoveEntryList (&HandleMapEntry
->List
);
537 FreePool (HandleMapEntry
);
541 return EFI_NOT_FOUND
;