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
;
97 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
98 CopyMem (&PackageLength
, VA_ARG (Marker
, VOID
*), sizeof (UINT32
));
100 // Do not count the BinaryLength field.
102 PackageListLength
+= (PackageLength
- sizeof (UINT32
));
106 // Include the lenght of EFI_HII_PACKAGE_END
108 PackageListLength
+= sizeof (EFI_HII_PACKAGE_HEADER
);
109 PackageListHeader
= AllocateZeroPool (PackageListLength
);
110 ASSERT (PackageListHeader
!= NULL
);
112 CopyMem (&PackageListHeader
->PackageListGuid
, GuidId
, sizeof (EFI_GUID
));
113 PackageListHeader
->PackageLength
= PackageListLength
;
115 PackageListData
= ((UINT8
*) PackageListHeader
) + sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
117 Marker
= MarkerBackup
;
118 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
119 PackageArray
= (UINT8
*) VA_ARG (Marker
, VOID
*);
120 CopyMem (&PackageLength
, PackageArray
, sizeof (UINT32
));
121 PackageLength
-= sizeof (UINT32
);
122 PackageArray
+= sizeof (UINT32
);
123 CopyMem (PackageListData
, PackageArray
, PackageLength
);
124 PackageListData
+= PackageLength
;
128 // Append EFI_HII_PACKAGE_END
130 PackageHeader
.Type
= EFI_HII_PACKAGE_END
;
131 PackageHeader
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
132 CopyMem (PackageListData
, &PackageHeader
, PackageHeader
.Length
);
134 return PackageListHeader
;
138 Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
140 If GuidId is NULL, then ASSERT.
141 If not enough resource to complete the operation, then ASSERT.
143 @param NumberOfPackages Number of packages.
144 @param GuidId Package GUID.
145 @param ... Variable argument list for packages to be assembled.
147 @return EFI_HII_PACKAGE_LIST_HEADER Pointer of EFI_HII_PACKAGE_LIST_HEADER. The function will ASSERT if system has
148 not enough resource to complete the operation.
151 EFI_HII_PACKAGE_LIST_HEADER
*
153 HiiLibPreparePackageList (
154 IN UINTN NumberOfPackages
,
155 IN CONST EFI_GUID
*GuidId
,
159 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
162 ASSERT (GuidId
!= NULL
);
164 VA_START (Marker
, GuidId
);
165 PackageListHeader
= InternalHiiLibPreparePackages (NumberOfPackages
, GuidId
, Marker
);
168 return PackageListHeader
;
173 This function allocates pool for an EFI_HII_PACKAGE_LIST structure
174 with additional space that is big enough to host all packages described by the variable
175 argument list of package pointers. The allocated structure is initialized using NumberOfPackages,
176 GuidId, and the variable length argument list of package pointers.
178 Then, EFI_HII_PACKAGE_LIST will be register to the default System HII Database. The
179 Handle to the newly registered Package List is returned throught HiiHandle.
181 If HiiHandle is NULL, then ASSERT.
183 @param NumberOfPackages The number of HII packages to register.
184 @param GuidId Package List GUID ID.
185 @param DriverHandle Optional. If not NULL, the DriverHandle on which an instance of DEVICE_PATH_PROTOCOL is installed.
186 This DriverHandle uniquely defines the device that the added packages are associated with.
187 @param HiiHandle On output, the HiiHandle is update with the handle which can be used to retrieve the Package
188 List later. If the functions failed to add the package to the default HII database, this value will
190 @param ... The variable argument list describing all HII Package.
192 @return EFI_SUCCESS If the packages are successfully added to the default HII database.
193 @return EFI_OUT_OF_RESOURCE Not enough resource to complete the operation.
199 IN UINTN NumberOfPackages
,
200 IN CONST EFI_GUID
*GuidId
,
201 IN EFI_HANDLE DriverHandle
, OPTIONAL
202 OUT EFI_HII_HANDLE
*HiiHandle
,
207 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
210 ASSERT (HiiHandle
!= NULL
);
212 LocateHiiProtocols ();
214 VA_START (Args
, HiiHandle
);
215 PackageListHeader
= InternalHiiLibPreparePackages (NumberOfPackages
, GuidId
, Args
);
217 Status
= mHiiDatabaseProt
->NewPackageList (mHiiDatabaseProt
, PackageListHeader
, DriverHandle
, HiiHandle
);
218 if (HiiHandle
!= NULL
) {
219 if (EFI_ERROR (Status
)) {
224 FreePool (PackageListHeader
);
231 Removes a package list from the default HII database.
233 If HiiHandle is NULL, then ASSERT.
234 If HiiHandle is not a valid EFI_HII_HANDLE in the default HII database, then ASSERT.
236 @param HiiHandle The handle that was previously registered to the data base that is requested for removal.
242 HiiLibRemovePackages (
243 IN EFI_HII_HANDLE HiiHandle
247 ASSERT (IsHiiHandleRegistered (HiiHandle
));
249 LocateHiiProtocols ();
251 Status
= mHiiDatabaseProt
->RemovePackageList (mHiiDatabaseProt
, HiiHandle
);
252 ASSERT_EFI_ERROR (Status
);
257 Determines the handles that are currently active in the database.
258 It's the caller's responsibility to free handle buffer.
260 If HandleBufferLength is NULL, then ASSERT.
261 If HiiHandleBuffer is NULL, then ASSERT.
263 @param HandleBufferLength On input, a pointer to the length of the handle
264 buffer. On output, the length of the handle buffer
265 that is required for the handles found.
266 @param HiiHandleBuffer Pointer to an array of Hii Handles returned.
268 @retval EFI_SUCCESS Get an array of Hii Handles successfully.
273 HiiLibGetHiiHandles (
274 IN OUT UINTN
*HandleBufferLength
,
275 OUT EFI_HII_HANDLE
**HiiHandleBuffer
281 ASSERT (HandleBufferLength
!= NULL
);
282 ASSERT (HiiHandleBuffer
!= NULL
);
286 LocateHiiProtocols ();
289 // Try to find the actual buffer size for HiiHandle Buffer.
291 Status
= mHiiDatabaseProt
->ListPackageLists (
293 EFI_HII_PACKAGE_TYPE_ALL
,
299 if (Status
== EFI_BUFFER_TOO_SMALL
) {
300 *HiiHandleBuffer
= AllocateZeroPool (BufferLength
);
301 Status
= mHiiDatabaseProt
->ListPackageLists (
303 EFI_HII_PACKAGE_TYPE_ALL
,
309 // we should not fail here.
311 ASSERT_EFI_ERROR (Status
);
314 *HandleBufferLength
= BufferLength
;
320 Extract Hii package list GUID for given HII handle.
322 If HiiHandle could not be found in the default HII database, then ASSERT.
323 If Guid is NULL, then ASSERT.
325 @param Handle Hii handle
326 @param Guid Package list GUID
328 @retval EFI_SUCCESS Successfully extract GUID from Hii database.
333 HiiLibExtractGuidFromHiiHandle (
334 IN EFI_HII_HANDLE Handle
,
340 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
342 ASSERT (Guid
!= NULL
);
343 ASSERT (IsHiiHandleRegistered (Handle
));
346 // Get HII PackageList
349 HiiPackageList
= NULL
;
351 LocateHiiProtocols ();
353 Status
= mHiiDatabaseProt
->ExportPackageLists (mHiiDatabaseProt
, Handle
, &BufferSize
, HiiPackageList
);
354 ASSERT (Status
!= EFI_NOT_FOUND
);
356 if (Status
== EFI_BUFFER_TOO_SMALL
) {
357 HiiPackageList
= AllocatePool (BufferSize
);
358 ASSERT (HiiPackageList
!= NULL
);
360 Status
= mHiiDatabaseProt
->ExportPackageLists (mHiiDatabaseProt
, Handle
, &BufferSize
, HiiPackageList
);
362 if (EFI_ERROR (Status
)) {
369 CopyMem (Guid
, &HiiPackageList
->PackageListGuid
, sizeof (EFI_GUID
));
371 FreePool (HiiPackageList
);
377 Find HII Handle in the default HII database associated with given Device Path.
379 If DevicePath is NULL, then ASSERT.
381 @param DevicePath Device Path associated with the HII package list
384 @retval Handle HII package list Handle associated with the Device
386 @retval NULL Hii Package list handle is not found.
391 HiiLibDevicePathToHiiHandle (
392 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
396 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
403 EFI_HANDLE DriverHandle
;
404 EFI_HII_HANDLE
*HiiHandles
;
405 EFI_HII_HANDLE HiiHandle
;
407 ASSERT (DevicePath
!= NULL
);
410 // Locate Device Path Protocol handle buffer
412 Status
= gBS
->LocateHandleBuffer (
414 &gEfiDevicePathProtocolGuid
,
419 if (EFI_ERROR (Status
)) {
424 // Search Driver Handle by Device Path
427 BufferSize
= GetDevicePathSize (DevicePath
);
428 for(Index
= 0; Index
< HandleCount
; Index
++) {
429 Handle
= Handles
[Index
];
430 gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**) &TmpDevicePath
);
433 // Check whether DevicePath match
435 Size
= GetDevicePathSize (TmpDevicePath
);
436 if ((Size
== BufferSize
) && CompareMem (DevicePath
, TmpDevicePath
, Size
) == 0) {
437 DriverHandle
= Handle
;
443 if (DriverHandle
== NULL
) {
447 LocateHiiProtocols ();
450 // Retrieve all Hii Handles from HII database
453 HiiHandles
= AllocatePool (BufferSize
);
454 ASSERT (HiiHandles
!= NULL
);
455 Status
= mHiiDatabaseProt
->ListPackageLists (
457 EFI_HII_PACKAGE_TYPE_ALL
,
462 if (Status
== EFI_BUFFER_TOO_SMALL
) {
463 FreePool (HiiHandles
);
464 HiiHandles
= AllocatePool (BufferSize
);
465 ASSERT (HiiHandles
!= NULL
);
467 Status
= mHiiDatabaseProt
->ListPackageLists (
469 EFI_HII_PACKAGE_TYPE_ALL
,
476 if (EFI_ERROR (Status
)) {
477 FreePool (HiiHandles
);
482 // Search Hii Handle by Driver Handle
485 HandleCount
= BufferSize
/ sizeof (EFI_HII_HANDLE
);
486 for (Index
= 0; Index
< HandleCount
; Index
++) {
487 Status
= mHiiDatabaseProt
->GetPackageListHandle (
492 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
493 HiiHandle
= HiiHandles
[Index
];
498 FreePool (HiiHandles
);
503 This function check if the Hii Handle is a valid handle registered
506 @param HiiHandle The HII Handle.
508 @retval TRUE If it is a valid HII handle.
509 @retval FALSE If it is a invalid HII handle.
512 IsHiiHandleRegistered (
513 EFI_HII_HANDLE HiiHandle
518 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
520 ASSERT (HiiHandle
!= NULL
);
522 HiiPackageList
= NULL
;
525 LocateHiiProtocols ();
527 Status
= mHiiDatabaseProt
->ExportPackageLists (
534 return (BOOLEAN
) (Status
== EFI_BUFFER_TOO_SMALL
);