2 HII Library implementation that uses DXE protocols and services.
4 Copyright (c) 2006 - 2008, 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
= NULL
;
18 CONST EFI_HII_STRING_PROTOCOL
*mHiiStringProt
= NULL
;
22 This function locate Hii relative protocols for later usage.
32 if (mHiiStringProt
!= NULL
&& mHiiDatabaseProt
!= NULL
) {
34 // Only need to initialize the protocol instance once.
39 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &mHiiDatabaseProt
);
40 ASSERT_EFI_ERROR (Status
);
42 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &mHiiStringProt
);
43 ASSERT_EFI_ERROR (Status
);
49 This funciton build the package list based on the package number,
50 the GUID of the package list and the list of pointer which point to
51 package header that defined by UEFI VFR compiler and StringGather
54 #pragma pack (push, 1)
57 EFI_HII_PACKAGE_HEADER PackageHeader;
58 } TIANO_AUTOGEN_PACKAGES_HEADER;
61 If there is not enough resource for the new package list,
62 the function will ASSERT.
64 @param NumberOfPackages The number of packages be
65 @param GuidId The GUID for the package list to be generated.
66 @param Marker The variable argument list. Each entry represent a specific package header that is
67 generated by VFR compiler and StrGather tool. The first 4 bytes is a UINT32 value
68 that indicate the overall length of the package.
70 @return The pointer to the package list header.
73 EFI_HII_PACKAGE_LIST_HEADER
*
74 InternalHiiLibPreparePackages (
75 IN UINTN NumberOfPackages
,
76 IN CONST EFI_GUID
*GuidId
,
80 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
81 UINT8
*PackageListData
;
82 UINT32 PackageListLength
;
84 EFI_HII_PACKAGE_HEADER PackageHeader
;
89 PackageListLength
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
91 MarkerBackup
= Marker
;
94 // Count the lenth of the final package list.
96 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
97 CopyMem (&PackageLength
, VA_ARG (Marker
, VOID
*), sizeof (UINT32
));
99 // Do not count the BinaryLength field.
101 PackageListLength
+= (PackageLength
- sizeof (UINT32
));
105 // Include the lenght of EFI_HII_PACKAGE_END
107 PackageListLength
+= sizeof (EFI_HII_PACKAGE_HEADER
);
108 PackageListHeader
= AllocateZeroPool (PackageListLength
);
109 ASSERT (PackageListHeader
!= NULL
);
111 CopyGuid (&PackageListHeader
->PackageListGuid
, GuidId
);
112 PackageListHeader
->PackageLength
= PackageListLength
;
114 PackageListData
= ((UINT8
*) PackageListHeader
) + sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
116 Marker
= MarkerBackup
;
118 // Prepare the final package list.
120 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
121 PackageArray
= (UINT8
*) VA_ARG (Marker
, VOID
*);
123 // CopyMem is used for UINT32 to cover the unaligned address access.
125 CopyMem (&PackageLength
, PackageArray
, sizeof (UINT32
));
126 PackageLength
-= sizeof (UINT32
);
127 PackageArray
+= sizeof (UINT32
);
128 CopyMem (PackageListData
, PackageArray
, PackageLength
);
129 PackageListData
+= PackageLength
;
133 // Append EFI_HII_PACKAGE_END
135 PackageHeader
.Type
= EFI_HII_PACKAGE_END
;
136 PackageHeader
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
137 CopyMem (PackageListData
, &PackageHeader
, PackageHeader
.Length
);
139 return PackageListHeader
;
143 Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
145 If GuidId is NULL, then ASSERT.
146 If not enough resource to complete the operation, then ASSERT.
148 @param NumberOfPackages Number of packages.
149 @param GuidId Package GUID.
150 @param ... Variable argument list for packages to be assembled.
152 @return EFI_HII_PACKAGE_LIST_HEADER Pointer of EFI_HII_PACKAGE_LIST_HEADER. The function will ASSERT if system has
153 not enough resource to complete the operation.
156 EFI_HII_PACKAGE_LIST_HEADER
*
158 HiiLibPreparePackageList (
159 IN UINTN NumberOfPackages
,
160 IN CONST EFI_GUID
*GuidId
,
164 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
167 ASSERT (GuidId
!= NULL
);
169 VA_START (Marker
, GuidId
);
170 PackageListHeader
= InternalHiiLibPreparePackages (NumberOfPackages
, GuidId
, Marker
);
173 return PackageListHeader
;
178 This function allocates pool for an EFI_HII_PACKAGE_LIST structure
179 with additional space that is big enough to host all packages described by the variable
180 argument list of package pointers. The allocated structure is initialized using NumberOfPackages,
181 GuidId, and the variable length argument list of package pointers.
183 Then, EFI_HII_PACKAGE_LIST will be register to the default System HII Database. The
184 Handle to the newly registered Package List is returned throught HiiHandle.
186 If HiiHandle is NULL, then ASSERT.
188 @param NumberOfPackages The number of HII packages to register.
189 @param GuidId Package List GUID ID.
190 @param DriverHandle Optional. If not NULL, the DriverHandle on which an instance of DEVICE_PATH_PROTOCOL is installed.
191 This DriverHandle uniquely defines the device that the added packages are associated with.
192 @param HiiHandle On output, the HiiHandle is update with the handle which can be used to retrieve the Package
193 List later. If the functions failed to add the package to the default HII database, this value will
195 @param ... The variable argument list describing all HII Package.
197 @return EFI_SUCCESS If the packages are successfully added to the default HII database.
198 @return EFI_OUT_OF_RESOURCE Not enough resource to complete the operation.
204 IN UINTN NumberOfPackages
,
205 IN CONST EFI_GUID
*GuidId
,
206 IN EFI_HANDLE DriverHandle
, OPTIONAL
207 OUT EFI_HII_HANDLE
*HiiHandle
,
212 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
215 ASSERT (HiiHandle
!= NULL
);
217 LocateHiiProtocols ();
219 VA_START (Args
, HiiHandle
);
220 PackageListHeader
= InternalHiiLibPreparePackages (NumberOfPackages
, GuidId
, Args
);
222 Status
= mHiiDatabaseProt
->NewPackageList (mHiiDatabaseProt
, PackageListHeader
, DriverHandle
, HiiHandle
);
223 if (HiiHandle
!= NULL
) {
224 if (EFI_ERROR (Status
)) {
229 FreePool (PackageListHeader
);
236 Removes a package list from the default HII database.
238 If HiiHandle is NULL, then ASSERT.
239 If HiiHandle is not a valid EFI_HII_HANDLE in the default HII database, then ASSERT.
241 @param HiiHandle The handle that was previously registered to the data base that is requested for removal.
247 HiiLibRemovePackages (
248 IN EFI_HII_HANDLE HiiHandle
252 ASSERT (IsHiiHandleRegistered (HiiHandle
));
254 LocateHiiProtocols ();
256 Status
= mHiiDatabaseProt
->RemovePackageList (mHiiDatabaseProt
, HiiHandle
);
257 ASSERT_EFI_ERROR (Status
);
262 Determines the handles that are currently active in the database.
263 It's the caller's responsibility to free handle buffer.
265 If HandleBufferLength is NULL, then ASSERT.
266 If HiiHandleBuffer is NULL, then ASSERT.
268 @param HandleBufferLength On input, a pointer to the length of the handle
269 buffer. On output, the length of the handle buffer
270 that is required for the handles found.
271 @param HiiHandleBuffer Pointer to an array of Hii Handles returned.
273 @retval EFI_SUCCESS Get an array of Hii Handles successfully.
278 HiiLibGetHiiHandles (
279 IN OUT UINTN
*HandleBufferLength
,
280 OUT EFI_HII_HANDLE
**HiiHandleBuffer
286 ASSERT (HandleBufferLength
!= NULL
);
287 ASSERT (HiiHandleBuffer
!= NULL
);
291 LocateHiiProtocols ();
294 // Try to find the actual buffer size for HiiHandle Buffer.
296 Status
= mHiiDatabaseProt
->ListPackageLists (
298 EFI_HII_PACKAGE_TYPE_ALL
,
304 if (Status
== EFI_BUFFER_TOO_SMALL
) {
305 *HiiHandleBuffer
= AllocateZeroPool (BufferLength
);
306 ASSERT (*HiiHandleBuffer
!= NULL
);
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
)) {
369 FreePool (HiiPackageList
);
376 CopyGuid (Guid
, &HiiPackageList
->PackageListGuid
);
378 FreePool (HiiPackageList
);
384 Find HII Handle in the default HII database associated with given Device Path.
386 If DevicePath is NULL, then ASSERT.
388 @param DevicePath Device Path associated with the HII package list
391 @retval Handle HII package list Handle associated with the Device
393 @retval NULL Hii Package list handle is not found.
398 HiiLibDevicePathToHiiHandle (
399 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
403 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
410 EFI_HANDLE DriverHandle
;
411 EFI_HII_HANDLE
*HiiHandles
;
412 EFI_HII_HANDLE HiiHandle
;
414 ASSERT (DevicePath
!= NULL
);
417 // Locate Device Path Protocol handle buffer
419 Status
= gBS
->LocateHandleBuffer (
421 &gEfiDevicePathProtocolGuid
,
426 if (EFI_ERROR (Status
)) {
431 // Search Driver Handle by Device Path
434 BufferSize
= GetDevicePathSize (DevicePath
);
435 for(Index
= 0; Index
< HandleCount
; Index
++) {
436 Handle
= Handles
[Index
];
437 gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**) &TmpDevicePath
);
440 // Check whether DevicePath match
442 Size
= GetDevicePathSize (TmpDevicePath
);
443 if ((Size
== BufferSize
) && CompareMem (DevicePath
, TmpDevicePath
, Size
) == 0) {
444 DriverHandle
= Handle
;
450 if (DriverHandle
== NULL
) {
454 LocateHiiProtocols ();
457 // Retrieve all Hii Handles from HII database
460 HiiHandles
= AllocatePool (BufferSize
);
461 ASSERT (HiiHandles
!= NULL
);
462 Status
= mHiiDatabaseProt
->ListPackageLists (
464 EFI_HII_PACKAGE_TYPE_ALL
,
469 if (Status
== EFI_BUFFER_TOO_SMALL
) {
470 FreePool (HiiHandles
);
471 HiiHandles
= AllocatePool (BufferSize
);
472 ASSERT (HiiHandles
!= NULL
);
474 Status
= mHiiDatabaseProt
->ListPackageLists (
476 EFI_HII_PACKAGE_TYPE_ALL
,
483 if (EFI_ERROR (Status
)) {
484 FreePool (HiiHandles
);
489 // Search Hii Handle by Driver Handle
492 HandleCount
= BufferSize
/ sizeof (EFI_HII_HANDLE
);
493 for (Index
= 0; Index
< HandleCount
; Index
++) {
494 Status
= mHiiDatabaseProt
->GetPackageListHandle (
499 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
500 HiiHandle
= HiiHandles
[Index
];
505 FreePool (HiiHandles
);
510 Exports the contents of one or all package lists in the HII database into a buffer.
512 If Handle is not NULL and not a valid EFI_HII_HANDLE registered in the database,
514 If PackageListHeader is NULL, then ASSERT.
515 If PackageListSize is NULL, then ASSERT.
517 @param Handle The HII Handle.
518 @param PackageListHeader A pointer to a buffer that will contain the results of
520 @param PackageListSize On output, the length of the buffer that is required for the exported data.
522 @retval EFI_SUCCESS Package exported.
524 @retval EFI_OUT_OF_RESOURCES Not enought memory to complete the operations.
529 HiiLibExportPackageLists (
530 IN EFI_HII_HANDLE Handle
,
531 OUT EFI_HII_PACKAGE_LIST_HEADER
**PackageListHeader
,
532 OUT UINTN
*PackageListSize
537 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHdr
;
539 ASSERT (PackageListSize
!= NULL
);
540 ASSERT (PackageListHeader
!= NULL
);
542 LocateHiiProtocols ();
544 if (Handle
!= NULL
) {
545 ASSERT (IsHiiHandleRegistered (Handle
));
549 PackageListHdr
= NULL
;
550 Status
= mHiiDatabaseProt
->ExportPackageLists (
556 ASSERT_EFI_ERROR (Status
!= EFI_BUFFER_TOO_SMALL
);
558 if (Status
== EFI_BUFFER_TOO_SMALL
) {
559 PackageListHdr
= AllocateZeroPool (Size
);
561 if (PackageListHeader
== NULL
) {
562 return EFI_OUT_OF_RESOURCES
;
564 Status
= mHiiDatabaseProt
->ExportPackageLists (
573 if (!EFI_ERROR (Status
)) {
574 *PackageListHeader
= PackageListHdr
;
575 *PackageListSize
= Size
;
577 FreePool (PackageListHdr
);
586 HiiLibListPackageLists (
587 IN UINT8 PackageType
,
588 IN CONST EFI_GUID
*PackageGuid
,
589 IN OUT UINTN
*HandleBufferLength
,
590 OUT EFI_HII_HANDLE
**HandleBuffer
595 ASSERT (HandleBufferLength
!= NULL
);
596 ASSERT (HandleBuffer
!= NULL
);
598 *HandleBufferLength
= 0;
599 *HandleBuffer
= NULL
;
601 LocateHiiProtocols ();
603 Status
= mHiiDatabaseProt
->ListPackageLists (
610 if (EFI_ERROR (Status
) && (Status
!= EFI_BUFFER_TOO_SMALL
)) {
612 // No packages is registered to UEFI HII Database, just return EFI_SUCCESS.
618 *HandleBuffer
= AllocateZeroPool (*HandleBufferLength
);
620 if (*HandleBuffer
== NULL
) {
621 return EFI_OUT_OF_RESOURCES
;
624 return mHiiDatabaseProt
->ListPackageLists (
634 This function check if the Hii Handle is a valid handle registered
637 @param HiiHandle The HII Handle.
639 @retval TRUE If it is a valid HII handle.
640 @retval FALSE If it is a invalid HII handle.
643 IsHiiHandleRegistered (
644 EFI_HII_HANDLE HiiHandle
649 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
651 ASSERT (HiiHandle
!= NULL
);
653 HiiPackageList
= NULL
;
656 LocateHiiProtocols ();
658 Status
= mHiiDatabaseProt
->ExportPackageLists (
665 return (BOOLEAN
) (Status
== EFI_BUFFER_TOO_SMALL
);