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.
15 #include "InternalHiiLib.h"
17 CONST EFI_HII_DATABASE_PROTOCOL
*mHiiDatabaseProt
;
18 CONST EFI_HII_STRING_PROTOCOL
*mHiiStringProt
;
19 BOOLEAN mHiiProtocolsInitialized
= FALSE
;
24 This function locate Hii relative protocols for later usage.
34 if (mHiiProtocolsInitialized
) {
36 // Only need to initialize the protocol instance once.
41 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &mHiiDatabaseProt
);
42 ASSERT_EFI_ERROR (Status
);
44 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &mHiiStringProt
);
45 ASSERT_EFI_ERROR (Status
);
47 mHiiProtocolsInitialized
= TRUE
;
53 This funciton build the package list based on the package number,
54 the GUID of the package list and the list of pointer which point to
55 package header that defined by UEFI VFR compiler and StringGather
58 #pragma pack (push, 1)
61 EFI_HII_PACKAGE_HEADER PackageHeader;
62 } TIANO_AUTOGEN_PACKAGES_HEADER;
65 If there is not enough resource for the new package list,
66 the function will ASSERT.
68 @param NumberOfPackages The number of packages be
69 @param GuidId The GUID for the package list to be generated.
70 @param Marker The variable argument list. Each entry represent a specific package header that is
71 generated by VFR compiler and StrGather tool. The first 4 bytes is a UINT32 value
72 that indicate the overall length of the package.
74 @return The pointer to the package list header.
77 EFI_HII_PACKAGE_LIST_HEADER
*
78 InternalHiiLibPreparePackages (
79 IN UINTN NumberOfPackages
,
80 IN CONST EFI_GUID
*GuidId
,
84 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
85 UINT8
*PackageListData
;
86 UINT32 PackageListLength
;
88 EFI_HII_PACKAGE_HEADER PackageHeader
;
93 PackageListLength
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
95 MarkerBackup
= Marker
;
98 // Count the lenth of the final package list.
100 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
101 CopyMem (&PackageLength
, VA_ARG (Marker
, VOID
*), sizeof (UINT32
));
103 // Do not count the BinaryLength field.
105 PackageListLength
+= (PackageLength
- sizeof (UINT32
));
109 // Include the lenght of EFI_HII_PACKAGE_END
111 PackageListLength
+= sizeof (EFI_HII_PACKAGE_HEADER
);
112 PackageListHeader
= AllocateZeroPool (PackageListLength
);
113 ASSERT (PackageListHeader
!= NULL
);
115 CopyMem (&PackageListHeader
->PackageListGuid
, GuidId
, sizeof (EFI_GUID
));
116 PackageListHeader
->PackageLength
= PackageListLength
;
118 PackageListData
= ((UINT8
*) PackageListHeader
) + sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
120 Marker
= MarkerBackup
;
122 // Prepare the final package list.
124 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
125 PackageArray
= (UINT8
*) VA_ARG (Marker
, VOID
*);
126 CopyMem (&PackageLength
, PackageArray
, sizeof (UINT32
));
127 PackageLength
-= sizeof (UINT32
);
128 PackageArray
+= sizeof (UINT32
);
129 CopyMem (PackageListData
, PackageArray
, PackageLength
);
130 PackageListData
+= PackageLength
;
134 // Append EFI_HII_PACKAGE_END
136 PackageHeader
.Type
= EFI_HII_PACKAGE_END
;
137 PackageHeader
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
138 CopyMem (PackageListData
, &PackageHeader
, PackageHeader
.Length
);
140 return PackageListHeader
;
144 Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
146 If GuidId is NULL, then ASSERT.
147 If not enough resource to complete the operation, then ASSERT.
149 @param NumberOfPackages Number of packages.
150 @param GuidId Package GUID.
151 @param ... Variable argument list for packages to be assembled.
153 @return EFI_HII_PACKAGE_LIST_HEADER Pointer of EFI_HII_PACKAGE_LIST_HEADER. The function will ASSERT if system has
154 not enough resource to complete the operation.
157 EFI_HII_PACKAGE_LIST_HEADER
*
159 HiiLibPreparePackageList (
160 IN UINTN NumberOfPackages
,
161 IN CONST EFI_GUID
*GuidId
,
165 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
168 ASSERT (GuidId
!= NULL
);
170 VA_START (Marker
, GuidId
);
171 PackageListHeader
= InternalHiiLibPreparePackages (NumberOfPackages
, GuidId
, Marker
);
174 return PackageListHeader
;
179 This function allocates pool for an EFI_HII_PACKAGE_LIST structure
180 with additional space that is big enough to host all packages described by the variable
181 argument list of package pointers. The allocated structure is initialized using NumberOfPackages,
182 GuidId, and the variable length argument list of package pointers.
184 Then, EFI_HII_PACKAGE_LIST will be register to the default System HII Database. The
185 Handle to the newly registered Package List is returned throught HiiHandle.
187 If HiiHandle is NULL, then ASSERT.
189 @param NumberOfPackages The number of HII packages to register.
190 @param GuidId Package List GUID ID.
191 @param DriverHandle Optional. If not NULL, the DriverHandle on which an instance of DEVICE_PATH_PROTOCOL is installed.
192 This DriverHandle uniquely defines the device that the added packages are associated with.
193 @param HiiHandle On output, the HiiHandle is update with the handle which can be used to retrieve the Package
194 List later. If the functions failed to add the package to the default HII database, this value will
196 @param ... The variable argument list describing all HII Package.
198 @return EFI_SUCCESS If the packages are successfully added to the default HII database.
199 @return EFI_OUT_OF_RESOURCE Not enough resource to complete the operation.
205 IN UINTN NumberOfPackages
,
206 IN CONST EFI_GUID
*GuidId
,
207 IN EFI_HANDLE DriverHandle
, OPTIONAL
208 OUT EFI_HII_HANDLE
*HiiHandle
,
213 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
216 ASSERT (HiiHandle
!= NULL
);
218 LocateHiiProtocols ();
220 VA_START (Args
, HiiHandle
);
221 PackageListHeader
= InternalHiiLibPreparePackages (NumberOfPackages
, GuidId
, Args
);
223 Status
= mHiiDatabaseProt
->NewPackageList (mHiiDatabaseProt
, PackageListHeader
, DriverHandle
, HiiHandle
);
224 if (HiiHandle
!= NULL
) {
225 if (EFI_ERROR (Status
)) {
230 FreePool (PackageListHeader
);
237 Removes a package list from the default HII database.
239 If HiiHandle is NULL, then ASSERT.
240 If HiiHandle is not a valid EFI_HII_HANDLE in the default HII database, then ASSERT.
242 @param HiiHandle The handle that was previously registered to the data base that is requested for removal.
248 HiiLibRemovePackages (
249 IN EFI_HII_HANDLE HiiHandle
253 ASSERT (IsHiiHandleRegistered (HiiHandle
));
255 LocateHiiProtocols ();
257 Status
= mHiiDatabaseProt
->RemovePackageList (mHiiDatabaseProt
, HiiHandle
);
258 ASSERT_EFI_ERROR (Status
);
263 Determines the handles that are currently active in the database.
264 It's the caller's responsibility to free handle buffer.
266 If HandleBufferLength is NULL, then ASSERT.
267 If HiiHandleBuffer is NULL, then ASSERT.
269 @param HandleBufferLength On input, a pointer to the length of the handle
270 buffer. On output, the length of the handle buffer
271 that is required for the handles found.
272 @param HiiHandleBuffer Pointer to an array of Hii Handles returned.
274 @retval EFI_SUCCESS Get an array of Hii Handles successfully.
279 HiiLibGetHiiHandles (
280 IN OUT UINTN
*HandleBufferLength
,
281 OUT EFI_HII_HANDLE
**HiiHandleBuffer
287 ASSERT (HandleBufferLength
!= NULL
);
288 ASSERT (HiiHandleBuffer
!= NULL
);
292 LocateHiiProtocols ();
295 // Try to find the actual buffer size for HiiHandle Buffer.
297 Status
= mHiiDatabaseProt
->ListPackageLists (
299 EFI_HII_PACKAGE_TYPE_ALL
,
305 if (Status
== EFI_BUFFER_TOO_SMALL
) {
306 *HiiHandleBuffer
= AllocateZeroPool (BufferLength
);
307 Status
= mHiiDatabaseProt
->ListPackageLists (
309 EFI_HII_PACKAGE_TYPE_ALL
,
315 // we should not fail here.
317 ASSERT_EFI_ERROR (Status
);
320 *HandleBufferLength
= BufferLength
;
326 Extract Hii package list GUID for given HII handle.
328 If HiiHandle could not be found in the default HII database, then ASSERT.
329 If Guid is NULL, then ASSERT.
331 @param Handle Hii handle
332 @param Guid Package list GUID
334 @retval EFI_SUCCESS Successfully extract GUID from Hii database.
339 HiiLibExtractGuidFromHiiHandle (
340 IN EFI_HII_HANDLE Handle
,
346 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
348 ASSERT (Guid
!= NULL
);
349 ASSERT (IsHiiHandleRegistered (Handle
));
352 // Get HII PackageList
355 HiiPackageList
= NULL
;
357 LocateHiiProtocols ();
359 Status
= mHiiDatabaseProt
->ExportPackageLists (mHiiDatabaseProt
, Handle
, &BufferSize
, HiiPackageList
);
360 ASSERT (Status
!= EFI_NOT_FOUND
);
362 if (Status
== EFI_BUFFER_TOO_SMALL
) {
363 HiiPackageList
= AllocatePool (BufferSize
);
364 ASSERT (HiiPackageList
!= NULL
);
366 Status
= mHiiDatabaseProt
->ExportPackageLists (mHiiDatabaseProt
, Handle
, &BufferSize
, HiiPackageList
);
368 if (EFI_ERROR (Status
)) {
375 CopyMem (Guid
, &HiiPackageList
->PackageListGuid
, sizeof (EFI_GUID
));
377 FreePool (HiiPackageList
);
383 Find HII Handle in the default HII database associated with given Device Path.
385 If DevicePath is NULL, then ASSERT.
387 @param DevicePath Device Path associated with the HII package list
390 @retval Handle HII package list Handle associated with the Device
392 @retval NULL Hii Package list handle is not found.
397 HiiLibDevicePathToHiiHandle (
398 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
402 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
409 EFI_HANDLE DriverHandle
;
410 EFI_HII_HANDLE
*HiiHandles
;
411 EFI_HII_HANDLE HiiHandle
;
413 ASSERT (DevicePath
!= NULL
);
416 // Locate Device Path Protocol handle buffer
418 Status
= gBS
->LocateHandleBuffer (
420 &gEfiDevicePathProtocolGuid
,
425 if (EFI_ERROR (Status
)) {
430 // Search Driver Handle by Device Path
433 BufferSize
= GetDevicePathSize (DevicePath
);
434 for(Index
= 0; Index
< HandleCount
; Index
++) {
435 Handle
= Handles
[Index
];
436 gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**) &TmpDevicePath
);
439 // Check whether DevicePath match
441 Size
= GetDevicePathSize (TmpDevicePath
);
442 if ((Size
== BufferSize
) && CompareMem (DevicePath
, TmpDevicePath
, Size
) == 0) {
443 DriverHandle
= Handle
;
449 if (DriverHandle
== NULL
) {
453 LocateHiiProtocols ();
456 // Retrieve all Hii Handles from HII database
459 HiiHandles
= AllocatePool (BufferSize
);
460 ASSERT (HiiHandles
!= NULL
);
461 Status
= mHiiDatabaseProt
->ListPackageLists (
463 EFI_HII_PACKAGE_TYPE_ALL
,
468 if (Status
== EFI_BUFFER_TOO_SMALL
) {
469 FreePool (HiiHandles
);
470 HiiHandles
= AllocatePool (BufferSize
);
471 ASSERT (HiiHandles
!= NULL
);
473 Status
= mHiiDatabaseProt
->ListPackageLists (
475 EFI_HII_PACKAGE_TYPE_ALL
,
482 if (EFI_ERROR (Status
)) {
483 FreePool (HiiHandles
);
488 // Search Hii Handle by Driver Handle
491 HandleCount
= BufferSize
/ sizeof (EFI_HII_HANDLE
);
492 for (Index
= 0; Index
< HandleCount
; Index
++) {
493 Status
= mHiiDatabaseProt
->GetPackageListHandle (
498 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
499 HiiHandle
= HiiHandles
[Index
];
504 FreePool (HiiHandles
);
509 Exports the contents of one or all package lists in the HII database into a buffer.
511 If Handle is not NULL and not a valid EFI_HII_HANDLE registered in the database,
513 If PackageListHeader is NULL, then ASSERT.
514 If PackageListSize is NULL, then ASSERT.
516 @param Handle The HII Handle.
517 @param PackageListHeader A pointer to a buffer that will contain the results of
519 @param PackageListSize On output, the length of the buffer that is required for the exported data.
521 @retval EFI_SUCCESS Package exported.
523 @retval EFI_OUT_OF_RESOURCES Not enought memory to complete the operations.
528 HiiLibExportPackageLists (
529 IN EFI_HII_HANDLE Handle
,
530 OUT EFI_HII_PACKAGE_LIST_HEADER
**PackageListHeader
,
531 OUT UINTN
*PackageListSize
536 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHdr
;
538 ASSERT (PackageListSize
!= NULL
);
539 ASSERT (PackageListHeader
!= NULL
);
541 LocateHiiProtocols ();
543 if (Handle
!= NULL
) {
544 ASSERT (IsHiiHandleRegistered (Handle
));
548 PackageListHdr
= NULL
;
549 Status
= mHiiDatabaseProt
->ExportPackageLists (
555 ASSERT_EFI_ERROR (Status
!= EFI_BUFFER_TOO_SMALL
);
557 if (Status
== EFI_BUFFER_TOO_SMALL
) {
558 PackageListHdr
= AllocateZeroPool (Size
);
560 if (PackageListHeader
== NULL
) {
561 return EFI_OUT_OF_RESOURCES
;
563 Status
= mHiiDatabaseProt
->ExportPackageLists (
572 if (!EFI_ERROR (Status
)) {
573 *PackageListHeader
= PackageListHdr
;
574 *PackageListSize
= Size
;
576 FreePool (PackageListHdr
);
585 HiiLibListPackageLists (
586 IN UINT8 PackageType
,
587 IN CONST EFI_GUID
*PackageGuid
,
588 IN OUT UINTN
*HandleBufferLength
,
589 OUT EFI_HII_HANDLE
**HandleBuffer
594 ASSERT (HandleBufferLength
!= NULL
);
595 ASSERT (HandleBuffer
!= NULL
);
597 *HandleBufferLength
= 0;
598 *HandleBuffer
= NULL
;
600 LocateHiiProtocols ();
602 Status
= mHiiDatabaseProt
->ListPackageLists (
609 if (EFI_ERROR (Status
) && (Status
!= EFI_BUFFER_TOO_SMALL
)) {
611 // No packages is registered to UEFI HII Database, just return EFI_SUCCESS.
617 *HandleBuffer
= AllocateZeroPool (*HandleBufferLength
);
619 if (*HandleBuffer
== NULL
) {
620 return EFI_OUT_OF_RESOURCES
;
623 return mHiiDatabaseProt
->ListPackageLists (
633 This function check if the Hii Handle is a valid handle registered
636 @param HiiHandle The HII Handle.
638 @retval TRUE If it is a valid HII handle.
639 @retval FALSE If it is a invalid HII handle.
642 IsHiiHandleRegistered (
643 EFI_HII_HANDLE HiiHandle
648 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
650 ASSERT (HiiHandle
!= NULL
);
652 HiiPackageList
= NULL
;
655 LocateHiiProtocols ();
657 Status
= mHiiDatabaseProt
->ExportPackageLists (
664 return (BOOLEAN
) (Status
== EFI_BUFFER_TOO_SMALL
);