3 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Common Library Routines to assist handle HII elements.
22 #include "UefiIfrLibrary.h"
25 // Hii vendor device path template
27 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePathTemplate
= {
34 (UINT8
) (sizeof (HII_VENDOR_DEVICE_PATH_NODE
)),
35 (UINT8
) ((sizeof (HII_VENDOR_DEVICE_PATH_NODE
)) >> 8)
44 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
46 END_DEVICE_PATH_LENGTH
52 // Hii relative protocols
54 BOOLEAN mHiiProtocolsInitialized
= FALSE
;
56 EFI_HII_DATABASE_PROTOCOL
*gIfrLibHiiDatabase
;
57 EFI_HII_STRING_PROTOCOL
*gIfrLibHiiString
;
66 This function locate Hii relative protocols for later usage.
78 if (mHiiProtocolsInitialized
) {
82 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, (VOID
**) &gIfrLibHiiDatabase
);
83 ASSERT_EFI_ERROR (Status
);
85 Status
= gBS
->LocateProtocol (&gEfiHiiStringProtocolGuid
, NULL
, (VOID
**) &gIfrLibHiiString
);
86 ASSERT_EFI_ERROR (Status
);
88 mHiiProtocolsInitialized
= TRUE
;
91 EFI_HII_PACKAGE_LIST_HEADER
*
93 IN UINTN NumberOfPackages
,
100 Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
103 NumberOfPackages - Number of packages.
104 GuidId - Package GUID.
107 Pointer of EFI_HII_PACKAGE_LIST_HEADER.
112 EFI_HII_PACKAGE_LIST_HEADER
*PackageListHeader
;
113 UINT8
*PackageListData
;
114 UINT32 PackageListLength
;
115 UINT32 PackageLength
;
116 EFI_HII_PACKAGE_HEADER PackageHeader
;
120 PackageListLength
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
122 VA_START (Marker
, GuidId
);
123 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
124 EfiCopyMem (&PackageLength
, VA_ARG (Marker
, VOID
*), sizeof (UINT32
));
125 PackageListLength
+= (PackageLength
- sizeof (UINT32
));
130 // Include the lenght of EFI_HII_PACKAGE_END
132 PackageListLength
+= sizeof (EFI_HII_PACKAGE_HEADER
);
133 PackageListHeader
= EfiLibAllocateZeroPool (PackageListLength
);
134 ASSERT (PackageListHeader
!= NULL
);
135 EfiCopyMem (&PackageListHeader
->PackageListGuid
, GuidId
, sizeof (EFI_GUID
));
136 PackageListHeader
->PackageLength
= PackageListLength
;
138 PackageListData
= ((UINT8
*) PackageListHeader
) + sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
140 VA_START (Marker
, GuidId
);
141 for (Index
= 0; Index
< NumberOfPackages
; Index
++) {
142 PackageArray
= (UINT8
*) VA_ARG (Marker
, VOID
*);
143 EfiCopyMem (&PackageLength
, PackageArray
, sizeof (UINT32
));
144 PackageLength
-= sizeof (UINT32
);
145 PackageArray
+= sizeof (UINT32
);
146 EfiCopyMem (PackageListData
, PackageArray
, PackageLength
);
147 PackageListData
+= PackageLength
;
152 // Append EFI_HII_PACKAGE_END
154 PackageHeader
.Type
= EFI_HII_PACKAGE_END
;
155 PackageHeader
.Length
= sizeof (EFI_HII_PACKAGE_HEADER
);
156 EfiCopyMem (PackageListData
, &PackageHeader
, PackageHeader
.Length
);
158 return PackageListHeader
;
162 CreateHiiDriverHandle (
163 OUT EFI_HANDLE
*DriverHandle
168 The HII driver handle passed in for HiiDatabase.NewPackageList() requires
169 that there should be DevicePath Protocol installed on it.
170 This routine create a virtual Driver Handle by installing a vendor device
171 path on it, so as to use it to invoke HiiDatabase.NewPackageList().
174 DriverHandle - Handle to be returned
177 EFI_SUCCESS - Handle destroy success.
178 EFI_OUT_OF_RESOURCES - Not enough memory.
183 HII_VENDOR_DEVICE_PATH_NODE
*VendorDevicePath
;
184 UINT64 MonotonicCount
;
186 VendorDevicePath
= EfiLibAllocateCopyPool (sizeof (HII_VENDOR_DEVICE_PATH
), &mHiiVendorDevicePathTemplate
);
187 if (VendorDevicePath
== NULL
) {
188 return EFI_OUT_OF_RESOURCES
;
191 gBS
->GetNextMonotonicCount (&MonotonicCount
);
192 VendorDevicePath
->MonotonicCount
= (UINT32
) MonotonicCount
;
194 *DriverHandle
= NULL
;
195 Status
= gBS
->InstallProtocolInterface (
197 &gEfiDevicePathProtocolGuid
,
198 EFI_NATIVE_INTERFACE
,
201 if (EFI_ERROR (Status
)) {
209 DestroyHiiDriverHandle (
210 IN EFI_HANDLE DriverHandle
215 Destroy the Driver Handle created by CreateHiiDriverHandle().
218 DriverHandle - Handle returned by CreateHiiDriverHandle()
221 EFI_SUCCESS - Handle destroy success.
222 other - Handle destroy fail.
227 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
229 Status
= gBS
->HandleProtocol (
231 &gEfiDevicePathProtocolGuid
,
232 (VOID
**) &DevicePath
234 if (EFI_ERROR (Status
)) {
238 Status
= gBS
->UninstallProtocolInterface (
240 &gEfiDevicePathProtocolGuid
,
248 DevicePathToHiiHandle (
249 IN EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
,
250 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
255 Find HII Handle associated with given Device Path.
258 HiiDatabase - Point to EFI_HII_DATABASE_PROTOCOL instance.
259 DevicePath - Device Path associated with the HII package list handle.
262 Handle - HII package list Handle associated with the Device Path.
263 NULL - Hii Package list handle is not found.
268 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
275 EFI_HANDLE DriverHandle
;
276 EFI_HII_HANDLE
*HiiHandles
;
277 EFI_HII_HANDLE HiiHandle
;
280 // Locate Device Path Protocol handle buffer
282 Status
= gBS
->LocateHandleBuffer (
284 &gEfiDevicePathProtocolGuid
,
289 if (EFI_ERROR (Status
)) {
294 // Search Driver Handle by Device Path
297 BufferSize
= EfiDevicePathSize (DevicePath
);
298 for(Index
= 0; Index
< HandleCount
; Index
++) {
299 Handle
= Handles
[Index
];
300 gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**) &TmpDevicePath
);
303 // Check whether DevicePath match
305 Size
= EfiDevicePathSize (TmpDevicePath
);
306 if ((Size
== BufferSize
) && EfiCompareMem (DevicePath
, TmpDevicePath
, Size
) == 0) {
307 DriverHandle
= Handle
;
311 gBS
->FreePool (Handles
);
313 if (DriverHandle
== NULL
) {
318 // Retrieve all Hii Handles from HII database
321 HiiHandles
= EfiLibAllocatePool (BufferSize
);
322 ASSERT (HiiHandles
!= NULL
);
323 Status
= HiiDatabase
->ListPackageLists (
325 EFI_HII_PACKAGE_TYPE_ALL
,
330 if (Status
== EFI_BUFFER_TOO_SMALL
) {
331 gBS
->FreePool (HiiHandles
);
332 HiiHandles
= EfiLibAllocatePool (BufferSize
);
333 ASSERT (HiiHandles
!= NULL
);
335 Status
= HiiDatabase
->ListPackageLists (
337 EFI_HII_PACKAGE_TYPE_ALL
,
344 if (EFI_ERROR (Status
)) {
345 gBS
->FreePool (HiiHandles
);
350 // Search Hii Handle by Driver Handle
353 HandleCount
= BufferSize
/ sizeof (EFI_HII_HANDLE
);
354 for (Index
= 0; Index
< HandleCount
; Index
++) {
355 Status
= HiiDatabase
->GetPackageListHandle (
360 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
361 HiiHandle
= HiiHandles
[Index
];
366 gBS
->FreePool (HiiHandles
);
372 IN OUT UINTN
*HandleBufferLength
,
373 OUT EFI_HII_HANDLE
**HiiHandleBuffer
378 Determines the handles that are currently active in the database.
379 It's the caller's responsibility to free handle buffer.
382 HiiDatabase - A pointer to the EFI_HII_DATABASE_PROTOCOL instance.
383 HandleBufferLength - On input, a pointer to the length of the handle buffer. On output,
384 the length of the handle buffer that is required for the handles found.
385 HiiHandleBuffer - Pointer to an array of Hii Handles returned.
388 EFI_SUCCESS - Get an array of Hii Handles successfully.
389 EFI_INVALID_PARAMETER - Hii is NULL.
390 EFI_NOT_FOUND - Database not found.
399 LocateHiiProtocols ();
402 // Try to find the actual buffer size for HiiHandle Buffer.
404 Status
= gIfrLibHiiDatabase
->ListPackageLists (
406 EFI_HII_PACKAGE_TYPE_ALL
,
412 if (Status
== EFI_BUFFER_TOO_SMALL
) {
413 *HiiHandleBuffer
= EfiLibAllocateZeroPool (BufferLength
);
414 Status
= gIfrLibHiiDatabase
->ListPackageLists (
416 EFI_HII_PACKAGE_TYPE_ALL
,
422 // we should not fail here.
424 ASSERT_EFI_ERROR (Status
);
427 *HandleBufferLength
= BufferLength
;
433 ExtractGuidFromHiiHandle (
434 IN EFI_HII_HANDLE Handle
,
440 Extract Hii package list GUID for given HII handle.
443 HiiHandle - Hii handle
444 Guid - Package list GUID
447 EFI_SUCCESS - Successfully extract GUID from Hii database.
453 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
454 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
457 // Locate HII Database protocol
459 Status
= gBS
->LocateProtocol (
460 &gEfiHiiDatabaseProtocolGuid
,
462 (VOID
**) &HiiDatabase
464 if (EFI_ERROR (Status
)) {
469 // Get HII PackageList
472 HiiPackageList
= NULL
;
473 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
474 if (Status
== EFI_BUFFER_TOO_SMALL
) {
475 HiiPackageList
= EfiLibAllocatePool (BufferSize
);
476 ASSERT (HiiPackageList
!= NULL
);
478 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
480 if (EFI_ERROR (Status
)) {
487 EfiCopyMem (Guid
, &HiiPackageList
->PackageListGuid
, sizeof (EFI_GUID
));
489 gBS
->FreePool (HiiPackageList
);
495 ExtractClassFromHiiHandle (
496 IN EFI_HII_HANDLE Handle
,
498 OUT EFI_STRING_ID
*FormSetTitle
,
499 OUT EFI_STRING_ID
*FormSetHelp
504 Extract formset class for given HII handle.
507 HiiHandle - Hii handle
508 Class - Class of the formset
509 FormSetTitle - Formset title string
510 FormSetHelp - Formset help string
513 EFI_SUCCESS - Successfully extract Class for specified Hii handle.
519 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
520 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
526 UINT32 PackageListLength
;
527 EFI_HII_PACKAGE_HEADER PackageHeader
;
529 *Class
= EFI_NON_DEVICE_CLASS
;
534 // Locate HII Database protocol
536 Status
= gBS
->LocateProtocol (
537 &gEfiHiiDatabaseProtocolGuid
,
539 (VOID
**) &HiiDatabase
541 if (EFI_ERROR (Status
)) {
546 // Get HII PackageList
549 HiiPackageList
= NULL
;
550 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
551 if (Status
== EFI_BUFFER_TOO_SMALL
) {
552 HiiPackageList
= EfiLibAllocatePool (BufferSize
);
553 ASSERT (HiiPackageList
!= NULL
);
555 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
557 if (EFI_ERROR (Status
)) {
562 // Get Form package from this HII package List
564 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
567 EfiCopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
569 while (Offset
< PackageListLength
) {
570 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
571 EfiCopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
573 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORM
) {
575 // Search Class Opcode in this Form Package
577 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
578 while (Offset2
< PackageHeader
.Length
) {
579 OpCodeData
= Package
+ Offset2
;
581 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
583 // Find FormSet OpCode
585 EfiCopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
586 EfiCopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
589 if ((((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_GUID_OP
) &&
590 (EfiCompareGuid (&mIfrVendorGuid
, &((EFI_IFR_GUID
*) OpCodeData
)->Guid
)) &&
591 (((EFI_IFR_GUID_CLASS
*) OpCodeData
)->ExtendOpCode
== EFI_IFR_EXTEND_OP_CLASS
)
594 // Find GUIDed Class OpCode
596 EfiCopyMem (Class
, &((EFI_IFR_GUID_CLASS
*) OpCodeData
)->Class
, sizeof (UINT16
));
599 // Till now, we ought to have found the formset Opcode
604 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
607 if (Offset2
< PackageHeader
.Length
) {
609 // Target formset found
615 Offset
+= PackageHeader
.Length
;
618 gBS
->FreePool (HiiPackageList
);