3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. 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.
23 #include "LibraryInternal.h"
27 GetPackageDataFromPackageList (
28 IN EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
,
29 IN UINT32 PackageIndex
,
30 OUT UINT32
*BufferLen
,
31 OUT EFI_HII_PACKAGE_HEADER
**Buffer
35 EFI_HII_PACKAGE_HEADER
*Package
;
37 UINT32 PackageListLength
;
38 EFI_HII_PACKAGE_HEADER PackageHeader
= {0, 0};
40 ASSERT(HiiPackageList
!= NULL
);
42 if ((BufferLen
== NULL
) || (Buffer
== NULL
)) {
43 return EFI_INVALID_PARAMETER
;
48 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
49 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
50 while (Offset
< PackageListLength
) {
51 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
52 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
53 if (Index
== PackageIndex
) {
56 Offset
+= PackageHeader
.Length
;
59 if (Offset
>= PackageListLength
) {
61 // no package found in this Package List
66 *BufferLen
= PackageHeader
.Length
;
74 UpdateFormPackageData (
75 IN EFI_GUID
*FormSetGuid
,
76 IN EFI_FORM_ID FormId
,
77 IN EFI_HII_PACKAGE_HEADER
*Package
,
78 IN UINT32 PackageLength
,
81 IN EFI_HII_UPDATE_DATA
*Data
,
82 OUT UINT8
**TempBuffer
,
83 OUT UINT32
*TempBufferSize
88 EFI_HII_PACKAGE_HEADER PackageHeader
;
90 EFI_IFR_OP_HEADER
*IfrOpHdr
;
96 EFI_IFR_OP_HEADER
*AddOpCode
;
98 if ((TempBuffer
== NULL
) || (TempBufferSize
== NULL
)) {
99 return EFI_INVALID_PARAMETER
;
102 *TempBufferSize
= PackageLength
;
104 *TempBufferSize
+= Data
->Offset
;
106 *TempBuffer
= AllocateZeroPool (*TempBufferSize
);
107 if (*TempBuffer
== NULL
) {
108 return EFI_OUT_OF_RESOURCES
;
111 CopyMem (*TempBuffer
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
112 *TempBufferSize
= sizeof (EFI_HII_PACKAGE_HEADER
);
113 BufferPos
= *TempBuffer
+ sizeof (EFI_HII_PACKAGE_HEADER
);
115 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
116 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
117 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
118 GetFormSet
= (BOOLEAN
) ((FormSetGuid
== NULL
) ? TRUE
: FALSE
);
122 while (Offset
< PackageHeader
.Length
) {
123 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
124 BufferPos
+= IfrOpHdr
->Length
;
125 *TempBufferSize
+= IfrOpHdr
->Length
;
127 switch (IfrOpHdr
->OpCode
) {
128 case EFI_IFR_FORM_SET_OP
:
129 if (FormSetGuid
!= NULL
) {
130 if (CompareMem (&((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, FormSetGuid
, sizeof (EFI_GUID
)) == 0) {
136 case EFI_IFR_FORM_OP
:
137 if (CompareMem (&((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, &FormId
, sizeof (EFI_FORM_ID
)) == 0) {
142 case EFI_IFR_GUID_OP
:
143 if (!GetFormSet
|| !GetForm
|| Updated
) {
145 // Go to the next Op-Code
147 Offset
+= IfrOpHdr
->Length
;
148 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
152 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
153 CopyMem (&LabelNumber
, &((EFI_IFR_GUID_LABEL
*)IfrOpHdr
)->Number
, sizeof (UINT16
));
154 if ((ExtendOpCode
!= EFI_IFR_EXTEND_OP_LABEL
) || (LabelNumber
!= Label
)) {
156 // Go to the next Op-Code
158 Offset
+= IfrOpHdr
->Length
;
159 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
163 if (Insert
&& (Data
!= NULL
)) {
165 // insert the DataCount amount of opcodes to TempBuffer if Data is NULL remove
166 // DataCount amount of opcodes unless runing into a label.
168 AddOpCode
= (EFI_IFR_OP_HEADER
*)Data
->Data
;
170 while (AddSize
< Data
->Offset
) {
171 CopyMem (BufferPos
, AddOpCode
, AddOpCode
->Length
);
172 BufferPos
+= AddOpCode
->Length
;
173 *TempBufferSize
+= AddOpCode
->Length
;
175 AddSize
+= AddOpCode
->Length
;
176 AddOpCode
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (AddOpCode
) + AddOpCode
->Length
);
180 // Search the next Label.
183 Offset
+= IfrOpHdr
->Length
;
185 // Search the next label and Fail if not label found.
187 if (Offset
>= PackageHeader
.Length
) {
190 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
191 if (IfrOpHdr
->OpCode
== EFI_IFR_GUID_OP
) {
192 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
193 if (ExtendOpCode
== EFI_IFR_EXTEND_OP_LABEL
) {
200 AddOpCode
= (EFI_IFR_OP_HEADER
*)Data
->Data
;
202 while (AddSize
< Data
->Offset
) {
203 CopyMem (BufferPos
, AddOpCode
, AddOpCode
->Length
);
204 BufferPos
+= AddOpCode
->Length
;
205 *TempBufferSize
+= AddOpCode
->Length
;
207 AddSize
+= AddOpCode
->Length
;
208 AddOpCode
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (AddOpCode
) + AddOpCode
->Length
);
213 // copy the next label
215 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
216 BufferPos
+= IfrOpHdr
->Length
;
217 *TempBufferSize
+= IfrOpHdr
->Length
;
227 // Go to the next Op-Code
229 Offset
+= IfrOpHdr
->Length
;
230 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
234 // Update the package length.
236 PackageHeader
.Length
= *TempBufferSize
;
237 CopyMem (*TempBuffer
, &PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
241 gBS
->FreePool (*TempBuffer
);
243 return EFI_NOT_FOUND
;
251 This function allows the caller to update a form that has
252 previously been registered with the EFI HII database.
254 @param Handle Hii Handle
255 @param FormSetGuid The formset should be updated.
256 @param FormId The form should be updated.
257 @param Label Update information starting immediately after this
259 @param Insert If TRUE and Data is not NULL, insert data after
260 Label. If FALSE, replace opcodes between two
262 @param Data The adding data; If NULL, remove opcodes between
265 @retval EFI_SUCCESS Update success.
266 @retval Other Update fail.
272 IN EFI_HII_HANDLE Handle
,
273 IN EFI_GUID
*FormSetGuid
, OPTIONAL
274 IN EFI_FORM_ID FormId
,
277 IN EFI_HII_UPDATE_DATA
*Data
281 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
282 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
284 EFI_HII_PACKAGE_LIST_HEADER
*UpdateBuffer
;
286 UINT8
*UpdateBufferPos
;
287 EFI_HII_PACKAGE_HEADER PackageHeader
;
288 EFI_HII_PACKAGE_HEADER
*Package
;
289 UINT32 PackageLength
;
290 EFI_HII_PACKAGE_HEADER
*TempBuffer
;
291 UINT32 TempBufferSize
;
295 return EFI_INVALID_PARAMETER
;
298 HiiDatabase
= gIfrLibHiiDatabase
;
301 // Get the orginal package list
304 HiiPackageList
= NULL
;
305 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
306 if (Status
== EFI_BUFFER_TOO_SMALL
) {
307 HiiPackageList
= AllocatePool (BufferSize
);
308 ASSERT (HiiPackageList
!= NULL
);
310 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
311 if (EFI_ERROR (Status
)) {
312 gBS
->FreePool (HiiPackageList
);
318 // Calculate and allocate space for retrieval of IFR data
320 BufferSize
+= Data
->Offset
;
321 UpdateBuffer
= AllocateZeroPool (BufferSize
);
322 if (UpdateBuffer
== NULL
) {
323 return EFI_OUT_OF_RESOURCES
;
326 UpdateBufferPos
= (UINT8
*) UpdateBuffer
;
329 // copy the package list header
331 CopyMem (UpdateBufferPos
, HiiPackageList
, sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
332 UpdateBufferPos
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
335 for (Index
= 0; ; Index
++) {
336 Status
= GetPackageDataFromPackageList (HiiPackageList
, Index
, &PackageLength
, &Package
);
337 if (Status
== EFI_SUCCESS
) {
338 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
339 if ((PackageHeader
.Type
== EFI_HII_PACKAGE_FORM
) && !Updated
) {
340 Status
= UpdateFormPackageData (FormSetGuid
, FormId
, Package
, PackageLength
, Label
, Insert
, Data
, (UINT8
**)&TempBuffer
, &TempBufferSize
);
341 if (!EFI_ERROR(Status
)) {
342 if (FormSetGuid
== NULL
) {
345 CopyMem (UpdateBufferPos
, TempBuffer
, TempBufferSize
);
346 UpdateBufferPos
+= TempBufferSize
;
347 gBS
->FreePool (TempBuffer
);
352 CopyMem (UpdateBufferPos
, Package
, PackageLength
);
353 UpdateBufferPos
+= PackageLength
;
354 } else if (Status
== EFI_NOT_FOUND
) {
357 gBS
->FreePool (HiiPackageList
);
363 // Update package list length
365 BufferSize
= UpdateBufferPos
- (UINT8
*) UpdateBuffer
;
366 CopyMem (&UpdateBuffer
->PackageLength
, &BufferSize
, sizeof (UINT32
));
368 gBS
->FreePool (HiiPackageList
);
370 return HiiDatabase
->UpdatePackageList (HiiDatabase
, Handle
, UpdateBuffer
);
375 Configure the buffer accrording to ConfigBody strings.
377 @param DefaultId the ID of default.
378 @param Buffer the start address of buffer.
379 @param BufferSize the size of buffer.
380 @param Number the number of the strings.
382 @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate.
383 @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0.
384 @retval EFI_SUCCESS Operation successful.
389 IfrLibExtractDefault(
391 IN UINTN
*BufferSize
,
405 if ((Buffer
== NULL
) || (BufferSize
== NULL
)) {
406 return EFI_INVALID_PARAMETER
;
413 VA_START (Args
, Number
);
414 for (Index
= 0; Index
< Number
; Index
++) {
415 BufCfgArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
416 CopyMem (&TotalLen
, BufCfgArray
, sizeof (UINT32
));
417 BufferPos
= BufCfgArray
+ sizeof (UINT32
);
419 while ((UINT32
)(BufferPos
- BufCfgArray
) < TotalLen
) {
420 CopyMem (&Offset
, BufferPos
, sizeof (UINT16
));
421 BufferPos
+= sizeof (UINT16
);
422 CopyMem (&Width
, BufferPos
, sizeof (UINT16
));
423 BufferPos
+= sizeof (UINT16
);
427 if ((UINTN
)(Offset
+ Width
) > *BufferSize
) {
428 return EFI_BUFFER_TOO_SMALL
;
431 CopyMem ((UINT8
*)Buffer
+ Offset
, Value
, Width
);
436 *BufferSize
= (UINTN
)Offset
;