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"
23 IN EFI_HII_PROTOCOL
*This
,
24 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
25 IN OUT UINTN
*BufferSize
,
32 This function allows a program to extract a form or form package that has
33 previously been registered with the EFI HII database.
42 return EFI_UNSUPPORTED
;
48 IN EFI_HII_PROTOCOL
*This
,
49 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
50 IN EFI_FORM_ID FormId
,
51 IN OUT UINTN
*BufferLengthTemp
,
58 This function allows a program to extract a form or form package that has
59 previously been registered with the EFI HII database.
62 This - A pointer to the EFI_HII_PROTOCOL instance.
64 Handle - Handle on which the form resides. Type FRAMEWORK_EFI_HII_HANDLE is defined in
65 EFI_HII_PROTOCOL.NewPack() in the Packages section.
67 FormId - The ID of the form to return. If the ID is zero, the entire form package is returned.
68 Type EFI_FORM_ID is defined in "Related Definitions" below.
70 BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if
71 the length was sufficient and, if it was not, the length that is required to fit the
74 Buffer - The buffer designed to receive the form(s).
78 EFI_SUCCESS - Buffer filled with the requested forms. BufferLength
81 EFI_INVALID_PARAMETER - The handle is unknown.
83 EFI_NOT_FOUND - A form on the requested handle cannot be found with the
86 EFI_BUFFER_TOO_SMALL - The buffer provided was not large enough to allow the form to be stored.
91 return EFI_UNSUPPORTED
;
98 IN EFI_HII_PROTOCOL
*This
,
99 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
100 IN UINTN DefaultMask
,
101 OUT EFI_HII_VARIABLE_PACK_LIST
**VariablePackList
107 This function allows a program to extract the NV Image
108 that represents the default storage image
111 This - A pointer to the EFI_HII_PROTOCOL instance.
112 Handle - The HII handle from which will have default data retrieved.
113 UINTN - Mask used to retrieve the default image.
114 VariablePackList - Callee allocated, tightly-packed, link list data
115 structure that contain all default varaible packs
116 from the Hii Database.
119 EFI_NOT_FOUND - If Hii database does not contain any default images.
120 EFI_INVALID_PARAMETER - Invalid input parameter.
121 EFI_SUCCESS - Operation successful.
125 LIST_ENTRY
*UefiDefaults
;
126 EFI_HII_HANDLE UefiHiiHandle
;
128 EFI_HII_THUNK_PRIVATE_DATA
*Private
;
130 Private
= EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
132 UefiHiiHandle
= FrameworkHiiHandleToUefiHiiHandle (Private
, Handle
);
133 if (UefiHiiHandle
== NULL
) {
135 return EFI_INVALID_PARAMETER
;
139 Status
= UefiIfrGetBufferTypeDefaults (UefiHiiHandle
, &UefiDefaults
);
140 if (EFI_ERROR (Status
)) {
144 Status
= UefiDefaultsToFrameworkDefaults (UefiDefaults
, DefaultMask
, VariablePackList
);
147 FreeDefaultList (UefiDefaults
);
153 ThunkUpdateFormCallBack (
154 IN EFI_HANDLE CallbackHandle
,
155 IN CONST HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
159 EFI_FORM_CALLBACK_PROTOCOL
*FrameworkFormCallbackProtocol
;
160 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccessProtocol
;
161 EFI_HANDLE UefiDriverHandle
;
162 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE
*ConfigAccessProtocolInstance
;
164 Status
= gBS
->HandleProtocol (
166 &gEfiFormCallbackProtocolGuid
,
167 (VOID
**) &FrameworkFormCallbackProtocol
169 if (EFI_ERROR (Status
)) {
170 return EFI_INVALID_PARAMETER
;
173 Status
= mHiiDatabase
->GetPackageListHandle (
175 HandleMapEntry
->UefiHiiHandle
,
178 ASSERT_EFI_ERROR (Status
);
179 Status
= gBS
->HandleProtocol (
181 &gEfiHiiConfigAccessProtocolGuid
,
182 (VOID
**) &ConfigAccessProtocol
184 ASSERT_EFI_ERROR (Status
);
186 ConfigAccessProtocolInstance
= HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (ConfigAccessProtocol
);
188 ConfigAccessProtocolInstance
->FrameworkFormCallbackProtocol
= FrameworkFormCallbackProtocol
;
196 GetPackageDataFromPackageList (
197 IN EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
,
198 IN UINT32 PackageIndex
,
199 OUT UINT32
*BufferLen
,
200 OUT EFI_HII_PACKAGE_HEADER
**Buffer
204 EFI_HII_PACKAGE_HEADER
*Package
;
206 UINT32 PackageListLength
;
207 EFI_HII_PACKAGE_HEADER PackageHeader
= {0, 0};
209 ASSERT(HiiPackageList
!= NULL
);
211 if ((BufferLen
== NULL
) || (Buffer
== NULL
)) {
212 return EFI_INVALID_PARAMETER
;
217 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
218 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
219 while (Offset
< PackageListLength
) {
220 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
221 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
222 if (Index
== PackageIndex
) {
225 Offset
+= PackageHeader
.Length
;
228 if (Offset
>= PackageListLength
) {
230 // no package found in this Package List
232 return EFI_NOT_FOUND
;
235 *BufferLen
= PackageHeader
.Length
;
241 Check if Label exist in the IFR form package.
248 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
249 IN EFI_FORM_LABEL Label
,
250 OUT EFI_GUID
*FormsetGuid
,
251 OUT EFI_FORM_ID
*FormId
255 EFI_IFR_OP_HEADER
*IfrOpHdr
;
258 EFI_GUID InternalFormSetGuid
;
259 EFI_FORM_ID InternalFormId
;
263 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
264 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
267 ZeroMem (&InternalFormSetGuid
, sizeof (EFI_GUID
));
271 while (Offset
< Package
->Length
) {
272 switch (IfrOpHdr
->OpCode
) {
273 case EFI_IFR_FORM_SET_OP
:
274 CopyMem (&InternalFormSetGuid
, &((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, sizeof (EFI_GUID
));
278 case EFI_IFR_FORM_OP
:
279 CopyMem (&InternalFormId
, &((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, sizeof (EFI_FORM_ID
));
283 case EFI_IFR_GUID_OP
:
284 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
286 if (ExtendOpCode
!= EFI_IFR_EXTEND_OP_LABEL
) {
288 // Go to the next Op-Code
290 Offset
+= IfrOpHdr
->Length
;
291 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
295 CopyMem (&LabelNumber
, &((EFI_IFR_GUID_LABEL
*)IfrOpHdr
)->Number
, sizeof (UINT16
));
296 if (LabelNumber
== Label
) {
297 ASSERT (GetForm
&& GetFormSet
);
298 CopyGuid (FormsetGuid
, &InternalFormSetGuid
);
299 *FormId
= InternalFormId
;
310 // Go to the next Op-Code
312 Offset
+= IfrOpHdr
->Length
;
313 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
316 return EFI_NOT_FOUND
;
320 Find the first EFI_FORM_LABEL in FormSets for a given EFI_HII_HANLDE defined.
322 EFI_FORM_LABEL is a specific to Tiano implementation. The current implementation
323 does not restrict labels with same label value to be duplicated in either FormSet
324 scope or Form scope. This function will only locate the FIRST EFI_FORM_LABEL
325 with value as the same as the input Label in the Formset registered with UefiHiiHandle. The FormSet GUID
326 and Form ID is returned if such Label is found.
329 @retval EFI_INVALID_PARAMETER If UefiHiiHandle is not a valid handle.
330 @retval EFI_NOT_FOUND The package list identified by UefiHiiHandle deos not contain FormSet or
331 There is no Form ID with value Label found in all Form Sets in the pacakge
334 @retval EFI_SUCCESS The first found Form ID is returned in FormId.
338 IN EFI_HII_HANDLE Handle
,
339 IN EFI_FORM_LABEL Label
,
340 OUT EFI_GUID
*FormsetGuid
,
341 OUT EFI_FORM_ID
*FormId
345 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
348 EFI_HII_PACKAGE_HEADER PackageHeader
;
349 EFI_HII_PACKAGE_HEADER
*Package
;
350 UINT32 PackageLength
;
353 HiiPackageList
= NULL
;
354 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
355 if (Status
== EFI_BUFFER_TOO_SMALL
) {
356 HiiPackageList
= AllocatePool (BufferSize
);
357 ASSERT (HiiPackageList
!= NULL
);
359 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
360 if (EFI_ERROR (Status
)) {
365 for (Index
= 0; ; Index
++) {
366 Status
= GetPackageDataFromPackageList (HiiPackageList
, Index
, &PackageLength
, &Package
);
367 if (!EFI_ERROR (Status
)) {
368 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
369 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORM
) {
370 Status
= LocateLabel (Package
, Label
, FormsetGuid
, FormId
);
371 if (!EFI_ERROR(Status
)) {
382 FreePool (HiiPackageList
);
389 IN EFI_HII_PROTOCOL
*This
,
390 IN FRAMEWORK_EFI_HII_HANDLE Handle
,
391 IN EFI_FORM_LABEL Label
,
393 IN FRAMEWORK_EFI_HII_UPDATE_DATA
*Data
398 This function allows the caller to update a form that has
399 previously been registered with the EFI HII database.
402 Handle - Hii Handle associated with the Formset to modify
403 Label - Update information starting immediately after this label in the IFR
404 AddData - If TRUE, add data. If FALSE, remove data
405 Data - If adding data, this is the pointer to the data to add
408 EFI_SUCCESS - Update success.
414 EFI_HII_THUNK_PRIVATE_DATA
*Private
;
415 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY
*HandleMapEntry
;
416 EFI_HII_UPDATE_DATA
*UefiHiiUpdateData
;
417 EFI_HII_HANDLE UefiHiiHandle
;
418 EFI_GUID FormsetGuid
;
421 Status
= EFI_SUCCESS
;
423 Private
= EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This
);
425 HandleMapEntry
= FrameworkHiiHandleToMapDatabaseEntry (Private
, Handle
);
427 if (HandleMapEntry
== NULL
) {
428 return EFI_NOT_FOUND
;
431 if (Data
->FormSetUpdate
) {
432 Status
= ThunkUpdateFormCallBack ((EFI_HANDLE
) (UINTN
) Data
->FormCallbackHandle
, HandleMapEntry
);
433 if (EFI_ERROR (Status
)) {
438 if (HandleMapEntry
->IsPackageListWithOnlyStringPackages
) {
439 UefiHiiHandle
= TagGuidToUefiIfrHiiHandle (Private
, &HandleMapEntry
->TagGuid
);
441 if (UefiHiiHandle
== NULL
) {
442 return EFI_INVALID_PARAMETER
;
445 UefiHiiHandle
= HandleMapEntry
->UefiHiiHandle
;
448 UefiHiiUpdateData
= NULL
;
451 if (Data
->DataCount
!= 0) {
453 Status
= ThunkFrameworkUpdateDataToUefiUpdateData (Data
, AddData
, &UefiHiiUpdateData
);
454 ASSERT_EFI_ERROR (Status
);
456 Status
= ThunkLocateFormId (UefiHiiHandle
, Label
, &FormsetGuid
, &FormId
);
457 ASSERT_EFI_ERROR (Status
);
459 Status
= IfrLibUpdateForm (UefiHiiHandle
, &FormsetGuid
, FormId
, Label
, AddData
, UefiHiiUpdateData
);
460 ASSERT_EFI_ERROR (Status
);
464 return EFI_INVALID_PARAMETER
;
468 Status
= ThunkLocateFormId (UefiHiiHandle
, Label
, &FormsetGuid
, &FormId
);
469 ASSERT_EFI_ERROR (Status
);
472 // Delete Opcode starting from Labe in FormId found
475 Status
= IfrLibUpdateForm (UefiHiiHandle
, &FormsetGuid
, FormId
, Label
, FALSE
, NULL
);
476 ASSERT_EFI_ERROR (Status
);
479 if (UefiHiiUpdateData
!= NULL
) {
480 SafeFreePool (UefiHiiUpdateData
->Data
);
481 SafeFreePool (UefiHiiUpdateData
);