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
)
42 {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}},
52 FRAMEWORK_EFI_IFR_END_FORM_SET_OP
,
53 sizeof (FRAMEWORK_EFI_IFR_END_FORM_SET
)
61 This thunk module only handles UEFI HII packages. The caller of this function
62 won¡¯t be able to parse the content. Therefore, it is not supported.
64 This function will ASSERT and return EFI_UNSUPPORTED.
68 @param BufferSize N.A.
71 @retval EFI_UNSUPPORTED
77 IN EFI_HII_PROTOCOL
*This
,
78 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
79 IN OUT UINTN
*BufferSize
,
84 return EFI_UNSUPPORTED
;
89 This function allows a program to extract a form or form package that has
90 previously been registered with the EFI HII database.
92 In this thunk module, this function will create a IFR Package with only
93 one Formset. Effectively, only the GUID of the Formset is updated and return
94 in this IFR package to caller. This is enable the Framework modules which call
95 a API named GetStringFromToken. GetStringFromToken retieves a String based on
96 a String Token from a Package List known only by the Formset GUID.
100 @param This A pointer to the EFI_HII_PROTOCOL instance.
101 @param Handle Handle on which the form resides. Type FRAMEWORK_EFI_HII_HANDLE is defined in
102 EFI_HII_PROTOCOL.NewPack() in the Packages section.
103 @param FormId Ignored by this implementation.
104 @param BufferLengthTemp On input, the size of input buffer. On output, it
105 is the size of FW_HII_FORMSET_TEMPLATE.
106 @param Buffer The buffer designed to receive the form(s).
108 @retval EFI_SUCCESS Buffer filled with the requested forms. BufferLength
110 @retval EFI_INVALID_PARAMETER The handle is unknown.
111 @retval EFI_NOT_FOUND A form on the requested handle cannot be found with the
113 @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough to allow the form to be stored.
119 IN EFI_HII_PROTOCOL
*This
,
120 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
121 IN EFI_FORM_ID FormId
,
122 IN OUT UINTN
*BufferLengthTemp
,
126 HII_THUNK_PRIVATE_DATA
*Private
;
127 HII_THUNK_CONTEXT
*ThunkContext
;
128 FW_HII_FORMSET_TEMPLATE
*OutputFormSet
;
130 if (*BufferLengthTemp
< sizeof(FW_HII_FORMSET_TEMPLATE
)) {
131 *BufferLengthTemp
= sizeof(FW_HII_FORMSET_TEMPLATE
);
132 return EFI_BUFFER_TOO_SMALL
;
135 Private
= HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
137 ThunkContext
= FwHiiHandleToThunkContext (Private
, Handle
);
139 if (ThunkContext
== NULL
) {
140 return EFI_NOT_FOUND
;
143 OutputFormSet
= (FW_HII_FORMSET_TEMPLATE
*) Buffer
;
145 CopyMem (OutputFormSet
, &FormSetTemplate
, sizeof (FW_HII_FORMSET_TEMPLATE
));
146 CopyMem (&OutputFormSet
->FormSet
.Guid
, &ThunkContext
->TagGuid
, sizeof (EFI_GUID
));
148 OutputFormSet
->FormSet
.Class
= ThunkContext
->FormSetClass
;
149 OutputFormSet
->FormSet
.SubClass
= ThunkContext
->FormSetSubClass
;
150 OutputFormSet
->FormSet
.Help
= ThunkContext
->FormSetHelp
;
151 OutputFormSet
->FormSet
.FormSetTitle
= ThunkContext
->FormSetTitle
;
159 This function allows a program to extract the NV Image
160 that represents the default storage image
163 @param This A pointer to the EFI_HII_PROTOCOL instance.
164 @param Handle The HII handle from which will have default data retrieved.
165 UINTN - Mask used to retrieve the default image.
166 @param DefaultMask EDES_TODO: Add parameter description
167 @param VariablePackList Callee allocated, tightly-packed, link list data
168 structure that contain all default varaible packs
169 from the Hii Database.
171 @retval EFI_NOT_FOUND If Hii database does not contain any default images.
172 @retval EFI_INVALID_PARAMETER Invalid input parameter.
173 @retval EFI_SUCCESS Operation successful.
179 IN EFI_HII_PROTOCOL
*This
,
180 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
181 IN UINTN DefaultMask
,
182 OUT EFI_HII_VARIABLE_PACK_LIST
**VariablePackList
185 LIST_ENTRY
*UefiDefaults
;
186 EFI_HII_HANDLE UefiHiiHandle
;
188 HII_THUNK_PRIVATE_DATA
*Private
;
190 Private
= HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
192 UefiHiiHandle
= FwHiiHandleToUefiHiiHandle (Private
, Handle
);
193 if (UefiHiiHandle
== NULL
) {
195 return EFI_INVALID_PARAMETER
;
199 Status
= UefiIfrGetBufferTypeDefaults (UefiHiiHandle
, &UefiDefaults
);
200 if (EFI_ERROR (Status
)) {
204 Status
= UefiDefaultsToFwDefaults (UefiDefaults
, DefaultMask
, VariablePackList
);
207 FreeDefaultList (UefiDefaults
);
213 EDES_TODO: Add function description.
215 @param CallbackHandle EDES_TODO: Add parameter description
216 @param ThunkContext EDES_TODO: Add parameter description
218 @return EDES_TODO: Add description for return value
223 IN EFI_HANDLE CallbackHandle
,
224 IN CONST HII_THUNK_CONTEXT
*ThunkContext
228 EFI_FORM_CALLBACK_PROTOCOL
*FormCallbackProtocol
;
229 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccessProtocol
;
230 EFI_HANDLE UefiDriverHandle
;
231 CONFIG_ACCESS_PRIVATE
*ConfigAccessPrivate
;
233 Status
= gBS
->HandleProtocol (
235 &gEfiFormCallbackProtocolGuid
,
236 (VOID
**) &FormCallbackProtocol
238 if (EFI_ERROR (Status
)) {
239 return EFI_INVALID_PARAMETER
;
242 Status
= mHiiDatabase
->GetPackageListHandle (
244 ThunkContext
->UefiHiiHandle
,
247 ASSERT_EFI_ERROR (Status
);
248 Status
= gBS
->HandleProtocol (
250 &gEfiHiiConfigAccessProtocolGuid
,
251 (VOID
**) &ConfigAccessProtocol
253 ASSERT_EFI_ERROR (Status
);
255 ConfigAccessPrivate
= CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccessProtocol
);
257 ConfigAccessPrivate
->FormCallbackProtocol
= FormCallbackProtocol
;
264 EDES_TODO: Add function description.
266 @param HiiPackageList EDES_TODO: Add parameter description
267 @param PackageIndex EDES_TODO: Add parameter description
268 @param BufferLen EDES_TODO: Add parameter description
269 @param Buffer EDES_TODO: Add parameter description
271 @return EDES_TODO: Add description for return value
277 IN EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
,
278 IN UINT32 PackageIndex
,
279 OUT UINT32
*BufferLen
,
280 OUT EFI_HII_PACKAGE_HEADER
**Buffer
284 EFI_HII_PACKAGE_HEADER
*Package
;
286 UINT32 PackageListLength
;
287 EFI_HII_PACKAGE_HEADER PackageHeader
= {0, 0};
289 ASSERT(HiiPackageList
!= NULL
);
291 if ((BufferLen
== NULL
) || (Buffer
== NULL
)) {
292 return EFI_INVALID_PARAMETER
;
297 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
298 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
299 while (Offset
< PackageListLength
) {
300 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
301 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
302 if (Index
== PackageIndex
) {
305 Offset
+= PackageHeader
.Length
;
308 if (Offset
>= PackageListLength
) {
310 // no package found in this Package List
312 return EFI_NOT_FOUND
;
315 *BufferLen
= PackageHeader
.Length
;
321 Check if Label exist in the IFR form package.
328 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
329 IN EFI_FORM_LABEL Label
,
330 OUT EFI_GUID
*FormsetGuid
,
331 OUT EFI_FORM_ID
*FormId
335 EFI_IFR_OP_HEADER
*IfrOpHdr
;
338 EFI_GUID InternalFormSetGuid
;
339 EFI_FORM_ID InternalFormId
;
343 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
344 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
347 ZeroMem (&InternalFormSetGuid
, sizeof (EFI_GUID
));
351 while (Offset
< Package
->Length
) {
352 switch (IfrOpHdr
->OpCode
) {
353 case EFI_IFR_FORM_SET_OP
:
354 CopyMem (&InternalFormSetGuid
, &((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, sizeof (EFI_GUID
));
358 case EFI_IFR_FORM_OP
:
359 CopyMem (&InternalFormId
, &((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, sizeof (EFI_FORM_ID
));
363 case EFI_IFR_GUID_OP
:
364 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
366 if (ExtendOpCode
!= EFI_IFR_EXTEND_OP_LABEL
) {
368 // Go to the next Op-Code
370 Offset
+= IfrOpHdr
->Length
;
371 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
375 CopyMem (&LabelNumber
, &((EFI_IFR_GUID_LABEL
*)IfrOpHdr
)->Number
, sizeof (UINT16
));
376 if (LabelNumber
== Label
) {
377 ASSERT (GetForm
&& GetFormSet
);
378 CopyGuid (FormsetGuid
, &InternalFormSetGuid
);
379 *FormId
= InternalFormId
;
390 // Go to the next Op-Code
392 Offset
+= IfrOpHdr
->Length
;
393 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
396 return EFI_NOT_FOUND
;
400 Find the first EFI_FORM_LABEL in FormSets for a given EFI_HII_HANLDE defined.
402 EFI_FORM_LABEL is a specific to Tiano implementation. The current implementation
403 does not restrict labels with same label value to be duplicated in either FormSet
404 scope or Form scope. This function will only locate the FIRST EFI_FORM_LABEL
405 with value as the same as the input Label in the Formset registered with UefiHiiHandle. The FormSet GUID
406 and Form ID is returned if such Label is found.
409 @retval EFI_INVALID_PARAMETER If UefiHiiHandle is not a valid handle.
410 @retval EFI_NOT_FOUND The package list identified by UefiHiiHandle deos not contain FormSet or
411 There is no Form ID with value Label found in all Form Sets in the pacakge
414 @retval EFI_SUCCESS The first found Form ID is returned in FormId.
418 IN EFI_HII_HANDLE Handle
,
419 IN EFI_FORM_LABEL Label
,
420 OUT EFI_GUID
*FormsetGuid
,
421 OUT EFI_FORM_ID
*FormId
425 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
428 EFI_HII_PACKAGE_HEADER PackageHeader
;
429 EFI_HII_PACKAGE_HEADER
*Package
;
430 UINT32 PackageLength
;
433 HiiPackageList
= NULL
;
434 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
435 if (Status
== EFI_BUFFER_TOO_SMALL
) {
436 HiiPackageList
= AllocatePool (BufferSize
);
437 ASSERT (HiiPackageList
!= NULL
);
439 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
440 if (EFI_ERROR (Status
)) {
445 for (Index
= 0; ; Index
++) {
446 Status
= GetPackageData (HiiPackageList
, Index
, &PackageLength
, &Package
);
447 if (!EFI_ERROR (Status
)) {
448 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
449 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORM
) {
450 Status
= LocateLabel (Package
, Label
, FormsetGuid
, FormId
);
451 if (!EFI_ERROR(Status
)) {
462 FreePool (HiiPackageList
);
467 This function allows the caller to update a form that has
468 previously been registered with the EFI HII database.
471 @param This EDES_TODO: Add parameter description
472 @param Handle Hii Handle associated with the Formset to modify
473 @param Label Update information starting immediately after this label in the IFR
474 @param AddData If TRUE, add data. If FALSE, remove data
475 @param Data If adding data, this is the pointer to the data to add
477 @retval EFI_SUCCESS Update success.
478 @retval Other Update fail.
484 IN EFI_HII_PROTOCOL
*This
,
485 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
486 IN EFI_FORM_LABEL Label
,
488 IN FRAMEWORK_EFI_HII_UPDATE_DATA
*Data
492 HII_THUNK_PRIVATE_DATA
*Private
;
493 HII_THUNK_CONTEXT
*ThunkContext
;
494 EFI_HII_UPDATE_DATA
*UefiHiiUpdateData
;
495 EFI_HII_HANDLE UefiHiiHandle
;
496 EFI_GUID FormsetGuid
;
500 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
502 mInFrameworkUpdatePakcage
= TRUE
;
503 Status
= EFI_SUCCESS
;
504 UefiHiiUpdateData
= NULL
;
507 Private
= HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
509 ThunkContext
= FwHiiHandleToThunkContext (Private
, Handle
);
511 if (ThunkContext
== NULL
) {
512 Status
= EFI_NOT_FOUND
;
516 if (Data
->FormSetUpdate
) {
517 Status
= UpdateFormCallBack ((EFI_HANDLE
) (UINTN
) Data
->FormCallbackHandle
, ThunkContext
);
518 if (EFI_ERROR (Status
)) {
523 if ((ThunkContext
->IfrPackageCount
== 0) && (ThunkContext
->StringPackageCount
!= 0)) {
524 UefiHiiHandle
= TagGuidToUefiHiiHandle (Private
, &ThunkContext
->TagGuid
);
526 if (UefiHiiHandle
== NULL
) {
527 Status
= EFI_INVALID_PARAMETER
;
531 UefiHiiHandle
= ThunkContext
->UefiHiiHandle
;
534 Status
= LocateFormId (UefiHiiHandle
, Label
, &FormsetGuid
, &FormId
);
535 if (EFI_ERROR (Status
)) {
537 // Can't find the label.
543 if (Data
->DataCount
!= 0) {
545 ThunkContext
= UefiHiiHandleToThunkContext (Private
, UefiHiiHandle
);
546 Status
= FwUpdateDataToUefiUpdateData (ThunkContext
, Data
, AddData
, &UefiHiiUpdateData
);
547 ASSERT_EFI_ERROR (Status
);
549 Status
= IfrLibUpdateForm (UefiHiiHandle
, &FormsetGuid
, FormId
, Label
, AddData
, UefiHiiUpdateData
);
550 ASSERT_EFI_ERROR (Status
);
555 // Delete Opcode starting from Labe in FormId found
557 UefiHiiUpdateData
= AllocateZeroPool (sizeof (*UefiHiiUpdateData
));
559 Status
= IfrLibUpdateForm (UefiHiiHandle
, &FormsetGuid
, FormId
, Label
, FALSE
, UefiHiiUpdateData
);
560 ASSERT_EFI_ERROR (Status
);
564 if (UefiHiiUpdateData
!= NULL
) {
565 SafeFreePool (UefiHiiUpdateData
->Data
);
566 SafeFreePool (UefiHiiUpdateData
);
569 mInFrameworkUpdatePakcage
= FALSE
;
571 gBS
->RestoreTPL (OldTpl
);