2 This file contains the form processing code to the HII database.
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.
16 #include "HiiDatabase.h"
17 #include "UefiIfrDefault.h"
18 #include "OpcodeCreation.h"
21 // This structure is only intended to be used in this file.
25 EFI_HII_PACK_HEADER PackageHeader
;
26 FRAMEWORK_EFI_IFR_FORM_SET FormSet
;
27 FRAMEWORK_EFI_IFR_END_FORM_SET EndFormSet
;
28 } FW_HII_FORMSET_TEMPLATE
;
31 FW_HII_FORMSET_TEMPLATE FormSetTemplate
= {
33 sizeof (FW_HII_FORMSET_TEMPLATE
),
38 FRAMEWORK_EFI_IFR_FORM_SET_OP
,
39 sizeof (FRAMEWORK_EFI_IFR_FORM_SET
)
41 {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}, //Guid
51 FRAMEWORK_EFI_IFR_END_FORM_SET_OP
,
52 sizeof (FRAMEWORK_EFI_IFR_END_FORM_SET
)
60 This thunk module only handles UEFI HII packages. The caller of this function
61 won¡¯t be able to parse the content. Therefore, it is not supported.
63 This function will ASSERT and return EFI_UNSUPPORTED.
67 @param BufferSize N.A.
70 @retval EFI_UNSUPPORTED
76 IN EFI_HII_PROTOCOL
*This
,
77 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
78 IN OUT UINTN
*BufferSize
,
83 return EFI_UNSUPPORTED
;
88 This function allows a program to extract a form or form package that has
89 previously been registered with the EFI HII database.
91 In this thunk module, this function will create a IFR Package with only
92 one Formset. Effectively, only the GUID of the Formset is updated and return
93 in this IFR package to caller. This is enable the Framework modules which call
94 a API named GetStringFromToken. GetStringFromToken retieves a String based on
95 a String Token from a Package List known only by the Formset GUID.
99 @param This A pointer to the EFI_HII_PROTOCOL instance.
100 @param Handle Handle on which the form resides. Type FRAMEWORK_EFI_HII_HANDLE is defined in
101 EFI_HII_PROTOCOL.NewPack() in the Packages section.
102 @param FormId Ignored by this implementation.
103 @param BufferLengthTemp On input, the size of input buffer. On output, it
104 is the size of FW_HII_FORMSET_TEMPLATE.
105 @param Buffer The buffer designed to receive the form(s).
107 @retval EFI_SUCCESS Buffer filled with the requested forms. BufferLength
109 @retval EFI_INVALID_PARAMETER The handle is unknown.
110 @retval EFI_NOT_FOUND A form on the requested handle cannot be found with the
112 @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough to allow the form to be stored.
118 IN EFI_HII_PROTOCOL
*This
,
119 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
120 IN EFI_FORM_ID FormId
,
121 IN OUT UINTN
*BufferLengthTemp
,
125 HII_THUNK_PRIVATE_DATA
*Private
;
126 HII_THUNK_CONTEXT
*ThunkContext
;
127 FW_HII_FORMSET_TEMPLATE
*OutputFormSet
;
129 if (*BufferLengthTemp
< sizeof(FW_HII_FORMSET_TEMPLATE
)) {
130 *BufferLengthTemp
= sizeof(FW_HII_FORMSET_TEMPLATE
);
131 return EFI_BUFFER_TOO_SMALL
;
134 Private
= HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
136 ThunkContext
= FwHiiHandleToThunkContext (Private
, Handle
);
138 if (ThunkContext
== NULL
) {
139 return EFI_NOT_FOUND
;
142 OutputFormSet
= (FW_HII_FORMSET_TEMPLATE
*) Buffer
;
144 CopyMem (OutputFormSet
, &FormSetTemplate
, sizeof (FW_HII_FORMSET_TEMPLATE
));
145 CopyMem (&OutputFormSet
->FormSet
.Guid
, &ThunkContext
->TagGuid
, sizeof (EFI_GUID
));
147 OutputFormSet
->FormSet
.Class
= ThunkContext
->FormSetClass
;
148 OutputFormSet
->FormSet
.SubClass
= ThunkContext
->FormSetSubClass
;
149 OutputFormSet
->FormSet
.Help
= ThunkContext
->FormSetHelp
;
150 OutputFormSet
->FormSet
.FormSetTitle
= ThunkContext
->FormSetTitle
;
158 This function allows a program to extract the NV Image
159 that represents the default storage image
162 @param This A pointer to the EFI_HII_PROTOCOL instance.
163 @param Handle The HII handle from which will have default data retrieved.
164 UINTN - Mask used to retrieve the default image.
165 @param DefaultMask EDES_TODO: Add parameter description
166 @param VariablePackList Callee allocated, tightly-packed, link list data
167 structure that contain all default varaible packs
168 from the Hii Database.
170 @retval EFI_NOT_FOUND If Hii database does not contain any default images.
171 @retval EFI_INVALID_PARAMETER Invalid input parameter.
172 @retval EFI_SUCCESS Operation successful.
178 IN EFI_HII_PROTOCOL
*This
,
179 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
180 IN UINTN DefaultMask
,
181 OUT EFI_HII_VARIABLE_PACK_LIST
**VariablePackList
184 LIST_ENTRY
*UefiDefaults
;
185 EFI_HII_HANDLE UefiHiiHandle
;
187 HII_THUNK_PRIVATE_DATA
*Private
;
189 Private
= HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
191 UefiHiiHandle
= FwHiiHandleToUefiHiiHandle (Private
, Handle
);
192 if (UefiHiiHandle
== NULL
) {
194 return EFI_INVALID_PARAMETER
;
198 Status
= UefiIfrGetBufferTypeDefaults (UefiHiiHandle
, &UefiDefaults
);
199 if (EFI_ERROR (Status
)) {
203 Status
= UefiDefaultsToFwDefaults (UefiDefaults
, DefaultMask
, VariablePackList
);
206 FreeDefaultList (UefiDefaults
);
212 EDES_TODO: Add function description.
214 @param CallbackHandle EDES_TODO: Add parameter description
215 @param ThunkContext EDES_TODO: Add parameter description
217 @return EDES_TODO: Add description for return value
222 IN EFI_HANDLE CallbackHandle
,
223 IN CONST HII_THUNK_CONTEXT
*ThunkContext
227 EFI_FORM_CALLBACK_PROTOCOL
*FormCallbackProtocol
;
228 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccessProtocol
;
229 EFI_HANDLE UefiDriverHandle
;
230 CONFIG_ACCESS_PRIVATE
*ConfigAccessPrivate
;
232 Status
= gBS
->HandleProtocol (
234 &gEfiFormCallbackProtocolGuid
,
235 (VOID
**) &FormCallbackProtocol
237 if (EFI_ERROR (Status
)) {
238 return EFI_INVALID_PARAMETER
;
241 Status
= mHiiDatabase
->GetPackageListHandle (
243 ThunkContext
->UefiHiiHandle
,
246 ASSERT_EFI_ERROR (Status
);
247 Status
= gBS
->HandleProtocol (
249 &gEfiHiiConfigAccessProtocolGuid
,
250 (VOID
**) &ConfigAccessProtocol
252 ASSERT_EFI_ERROR (Status
);
254 ConfigAccessPrivate
= CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccessProtocol
);
256 ConfigAccessPrivate
->FormCallbackProtocol
= FormCallbackProtocol
;
263 EDES_TODO: Add function description.
265 @param HiiPackageList EDES_TODO: Add parameter description
266 @param PackageIndex EDES_TODO: Add parameter description
267 @param BufferLen EDES_TODO: Add parameter description
268 @param Buffer EDES_TODO: Add parameter description
270 @return EDES_TODO: Add description for return value
276 IN EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
,
277 IN UINT32 PackageIndex
,
278 OUT UINT32
*BufferLen
,
279 OUT EFI_HII_PACKAGE_HEADER
**Buffer
283 EFI_HII_PACKAGE_HEADER
*Package
;
285 UINT32 PackageListLength
;
286 EFI_HII_PACKAGE_HEADER PackageHeader
= {0, 0};
288 ASSERT(HiiPackageList
!= NULL
);
290 if ((BufferLen
== NULL
) || (Buffer
== NULL
)) {
291 return EFI_INVALID_PARAMETER
;
296 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
297 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
298 while (Offset
< PackageListLength
) {
299 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
300 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
301 if (Index
== PackageIndex
) {
304 Offset
+= PackageHeader
.Length
;
307 if (Offset
>= PackageListLength
) {
309 // no package found in this Package List
311 return EFI_NOT_FOUND
;
314 *BufferLen
= PackageHeader
.Length
;
320 Check if Label exist in the IFR form package.
327 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
328 IN EFI_FORM_LABEL Label
,
329 OUT EFI_GUID
*FormsetGuid
,
330 OUT EFI_FORM_ID
*FormId
334 EFI_IFR_OP_HEADER
*IfrOpHdr
;
337 EFI_GUID InternalFormSetGuid
;
338 EFI_FORM_ID InternalFormId
;
342 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
343 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
346 ZeroMem (&InternalFormSetGuid
, sizeof (EFI_GUID
));
350 while (Offset
< Package
->Length
) {
351 switch (IfrOpHdr
->OpCode
) {
352 case EFI_IFR_FORM_SET_OP
:
353 CopyMem (&InternalFormSetGuid
, &((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, sizeof (EFI_GUID
));
357 case EFI_IFR_FORM_OP
:
358 CopyMem (&InternalFormId
, &((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, sizeof (EFI_FORM_ID
));
362 case EFI_IFR_GUID_OP
:
363 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
365 if (ExtendOpCode
!= EFI_IFR_EXTEND_OP_LABEL
) {
367 // Go to the next Op-Code
369 Offset
+= IfrOpHdr
->Length
;
370 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
374 CopyMem (&LabelNumber
, &((EFI_IFR_GUID_LABEL
*)IfrOpHdr
)->Number
, sizeof (UINT16
));
375 if (LabelNumber
== Label
) {
376 ASSERT (GetForm
&& GetFormSet
);
377 CopyGuid (FormsetGuid
, &InternalFormSetGuid
);
378 *FormId
= InternalFormId
;
389 // Go to the next Op-Code
391 Offset
+= IfrOpHdr
->Length
;
392 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
395 return EFI_NOT_FOUND
;
399 Find the first EFI_FORM_LABEL in FormSets for a given EFI_HII_HANLDE defined.
401 EFI_FORM_LABEL is a specific to Tiano implementation. The current implementation
402 does not restrict labels with same label value to be duplicated in either FormSet
403 scope or Form scope. This function will only locate the FIRST EFI_FORM_LABEL
404 with value as the same as the input Label in the Formset registered with UefiHiiHandle. The FormSet GUID
405 and Form ID is returned if such Label is found.
408 @retval EFI_INVALID_PARAMETER If UefiHiiHandle is not a valid handle.
409 @retval EFI_NOT_FOUND The package list identified by UefiHiiHandle deos not contain FormSet or
410 There is no Form ID with value Label found in all Form Sets in the pacakge
413 @retval EFI_SUCCESS The first found Form ID is returned in FormId.
417 IN EFI_HII_HANDLE Handle
,
418 IN EFI_FORM_LABEL Label
,
419 OUT EFI_GUID
*FormsetGuid
,
420 OUT EFI_FORM_ID
*FormId
424 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
427 EFI_HII_PACKAGE_HEADER PackageHeader
;
428 EFI_HII_PACKAGE_HEADER
*Package
;
429 UINT32 PackageLength
;
432 HiiPackageList
= NULL
;
433 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
434 if (Status
== EFI_BUFFER_TOO_SMALL
) {
435 HiiPackageList
= AllocatePool (BufferSize
);
436 ASSERT (HiiPackageList
!= NULL
);
438 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
439 if (EFI_ERROR (Status
)) {
444 for (Index
= 0; ; Index
++) {
445 Status
= GetPackageData (HiiPackageList
, Index
, &PackageLength
, &Package
);
446 if (!EFI_ERROR (Status
)) {
447 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
448 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORM
) {
449 Status
= LocateLabel (Package
, Label
, FormsetGuid
, FormId
);
450 if (!EFI_ERROR(Status
)) {
461 FreePool (HiiPackageList
);
466 This function allows the caller to update a form that has
467 previously been registered with the EFI HII database.
470 @param This EDES_TODO: Add parameter description
471 @param Handle Hii Handle associated with the Formset to modify
472 @param Label Update information starting immediately after this label in the IFR
473 @param AddData If TRUE, add data. If FALSE, remove data
474 @param Data If adding data, this is the pointer to the data to add
476 @retval EFI_SUCCESS Update success.
477 @retval Other Update fail.
483 IN EFI_HII_PROTOCOL
*This
,
484 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
485 IN EFI_FORM_LABEL Label
,
487 IN FRAMEWORK_EFI_HII_UPDATE_DATA
*Data
491 HII_THUNK_PRIVATE_DATA
*Private
;
492 HII_THUNK_CONTEXT
*ThunkContext
;
493 EFI_HII_UPDATE_DATA
*UefiHiiUpdateData
;
494 EFI_HII_HANDLE UefiHiiHandle
;
495 EFI_GUID FormsetGuid
;
499 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
501 mInFrameworkUpdatePakcage
= TRUE
;
502 Status
= EFI_SUCCESS
;
503 UefiHiiUpdateData
= NULL
;
506 Private
= HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
508 ThunkContext
= FwHiiHandleToThunkContext (Private
, Handle
);
510 if (ThunkContext
== NULL
) {
511 Status
= EFI_NOT_FOUND
;
515 if (Data
->FormSetUpdate
) {
516 Status
= UpdateFormCallBack ((EFI_HANDLE
) (UINTN
) Data
->FormCallbackHandle
, ThunkContext
);
517 if (EFI_ERROR (Status
)) {
522 if (ThunkContext
->IfrPackageCount
== 0) {
524 Status
= EFI_INVALID_PARAMETER
;
527 UefiHiiHandle
= ThunkContext
->UefiHiiHandle
;
530 Status
= LocateFormId (UefiHiiHandle
, Label
, &FormsetGuid
, &FormId
);
531 if (EFI_ERROR (Status
)) {
533 // Can't find the label.
539 if (Data
->DataCount
!= 0) {
541 ThunkContext
= UefiHiiHandleToThunkContext (Private
, UefiHiiHandle
);
542 Status
= FwUpdateDataToUefiUpdateData (ThunkContext
, Data
, AddData
, &UefiHiiUpdateData
);
543 ASSERT_EFI_ERROR (Status
);
545 Status
= IfrLibUpdateForm (UefiHiiHandle
, &FormsetGuid
, FormId
, Label
, AddData
, UefiHiiUpdateData
);
546 ASSERT_EFI_ERROR (Status
);
551 // Delete Opcode starting from Labe in FormId found
553 UefiHiiUpdateData
= AllocateZeroPool (sizeof (*UefiHiiUpdateData
));
555 Status
= IfrLibUpdateForm (UefiHiiHandle
, &FormsetGuid
, FormId
, Label
, FALSE
, UefiHiiUpdateData
);
556 ASSERT_EFI_ERROR (Status
);
560 if (UefiHiiUpdateData
!= NULL
) {
561 SafeFreePool (UefiHiiUpdateData
->Data
);
562 SafeFreePool (UefiHiiUpdateData
);
565 mInFrameworkUpdatePakcage
= FALSE
;
567 gBS
->RestoreTPL (OldTpl
);