2 Common Library Routines to assist handle HII elements.
4 Copyright (c) 2007 - 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.
15 #include "LibraryInternal.h"
19 GetPackageDataFromPackageList (
20 IN EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
,
21 IN UINT32 PackageIndex
,
22 OUT UINT32
*BufferLen
,
23 OUT EFI_HII_PACKAGE_HEADER
**Buffer
27 EFI_HII_PACKAGE_HEADER
*Package
;
29 UINT32 PackageListLength
;
30 EFI_HII_PACKAGE_HEADER PackageHeader
= {0, 0};
32 ASSERT(HiiPackageList
!= NULL
);
34 if ((BufferLen
== NULL
) || (Buffer
== NULL
)) {
35 return EFI_INVALID_PARAMETER
;
40 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
41 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
42 while (Offset
< PackageListLength
) {
43 Package
= (EFI_HII_PACKAGE_HEADER
*) (((UINT8
*) HiiPackageList
) + Offset
);
44 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
45 if (Index
== PackageIndex
) {
48 Offset
+= PackageHeader
.Length
;
51 if (Offset
>= PackageListLength
) {
53 // no package found in this Package List
58 *BufferLen
= PackageHeader
.Length
;
66 UpdateFormPackageData (
67 IN EFI_GUID
*FormSetGuid
,
68 IN EFI_FORM_ID FormId
,
69 IN EFI_HII_PACKAGE_HEADER
*Package
,
70 IN UINT32 PackageLength
,
73 IN EFI_HII_UPDATE_DATA
*Data
,
74 OUT UINT8
**TempBuffer
,
75 OUT UINT32
*TempBufferSize
80 EFI_HII_PACKAGE_HEADER PackageHeader
;
82 EFI_IFR_OP_HEADER
*IfrOpHdr
;
88 EFI_IFR_OP_HEADER
*AddOpCode
;
90 if ((TempBuffer
== NULL
) || (TempBufferSize
== NULL
)) {
91 return EFI_INVALID_PARAMETER
;
94 *TempBufferSize
= PackageLength
;
96 *TempBufferSize
+= Data
->Offset
;
98 *TempBuffer
= AllocateZeroPool (*TempBufferSize
);
99 if (*TempBuffer
== NULL
) {
100 return EFI_OUT_OF_RESOURCES
;
103 CopyMem (*TempBuffer
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
104 *TempBufferSize
= sizeof (EFI_HII_PACKAGE_HEADER
);
105 BufferPos
= *TempBuffer
+ sizeof (EFI_HII_PACKAGE_HEADER
);
107 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
108 IfrOpHdr
= (EFI_IFR_OP_HEADER
*)((UINT8
*) Package
+ sizeof (EFI_HII_PACKAGE_HEADER
));
109 Offset
= sizeof (EFI_HII_PACKAGE_HEADER
);
110 GetFormSet
= (BOOLEAN
) ((FormSetGuid
== NULL
) ? TRUE
: FALSE
);
114 while (Offset
< PackageHeader
.Length
) {
115 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
116 BufferPos
+= IfrOpHdr
->Length
;
117 *TempBufferSize
+= IfrOpHdr
->Length
;
119 switch (IfrOpHdr
->OpCode
) {
120 case EFI_IFR_FORM_SET_OP
:
121 if (FormSetGuid
!= NULL
) {
122 if (CompareMem (&((EFI_IFR_FORM_SET
*) IfrOpHdr
)->Guid
, FormSetGuid
, sizeof (EFI_GUID
)) == 0) {
128 case EFI_IFR_FORM_OP
:
129 if (CompareMem (&((EFI_IFR_FORM
*) IfrOpHdr
)->FormId
, &FormId
, sizeof (EFI_FORM_ID
)) == 0) {
134 case EFI_IFR_GUID_OP
:
135 if (!GetFormSet
|| !GetForm
|| Updated
) {
137 // Go to the next Op-Code
139 Offset
+= IfrOpHdr
->Length
;
140 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
144 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
145 CopyMem (&LabelNumber
, &((EFI_IFR_GUID_LABEL
*)IfrOpHdr
)->Number
, sizeof (UINT16
));
146 if ((ExtendOpCode
!= EFI_IFR_EXTEND_OP_LABEL
) || (LabelNumber
!= Label
)) {
148 // Go to the next Op-Code
150 Offset
+= IfrOpHdr
->Length
;
151 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
155 if (Insert
&& (Data
!= NULL
)) {
157 // insert the DataCount amount of opcodes to TempBuffer if Data is NULL remove
158 // DataCount amount of opcodes unless runing into a label.
160 AddOpCode
= (EFI_IFR_OP_HEADER
*)Data
->Data
;
162 while (AddSize
< Data
->Offset
) {
163 CopyMem (BufferPos
, AddOpCode
, AddOpCode
->Length
);
164 BufferPos
+= AddOpCode
->Length
;
165 *TempBufferSize
+= AddOpCode
->Length
;
167 AddSize
+= AddOpCode
->Length
;
168 AddOpCode
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (AddOpCode
) + AddOpCode
->Length
);
172 // Search the next Label.
175 Offset
+= IfrOpHdr
->Length
;
177 // Search the next label and Fail if not label found.
179 if (Offset
>= PackageHeader
.Length
) {
182 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
183 if (IfrOpHdr
->OpCode
== EFI_IFR_GUID_OP
) {
184 ExtendOpCode
= ((EFI_IFR_GUID_LABEL
*) IfrOpHdr
)->ExtendOpCode
;
185 if (ExtendOpCode
== EFI_IFR_EXTEND_OP_LABEL
) {
192 AddOpCode
= (EFI_IFR_OP_HEADER
*)Data
->Data
;
194 while (AddSize
< Data
->Offset
) {
195 CopyMem (BufferPos
, AddOpCode
, AddOpCode
->Length
);
196 BufferPos
+= AddOpCode
->Length
;
197 *TempBufferSize
+= AddOpCode
->Length
;
199 AddSize
+= AddOpCode
->Length
;
200 AddOpCode
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (AddOpCode
) + AddOpCode
->Length
);
205 // copy the next label
207 CopyMem (BufferPos
, IfrOpHdr
, IfrOpHdr
->Length
);
208 BufferPos
+= IfrOpHdr
->Length
;
209 *TempBufferSize
+= IfrOpHdr
->Length
;
219 // Go to the next Op-Code
221 Offset
+= IfrOpHdr
->Length
;
222 IfrOpHdr
= (EFI_IFR_OP_HEADER
*) ((CHAR8
*) (IfrOpHdr
) + IfrOpHdr
->Length
);
226 // Update the package length.
228 PackageHeader
.Length
= *TempBufferSize
;
229 CopyMem (*TempBuffer
, &PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
233 gBS
->FreePool (*TempBuffer
);
235 return EFI_NOT_FOUND
;
243 This function allows the caller to update a form that has
244 previously been registered with the EFI HII database.
246 @param Handle Hii Handle
247 @param FormSetGuid The formset should be updated.
248 @param FormId The form should be updated.
249 @param Label Update information starting immediately after this
251 @param Insert If TRUE and Data is not NULL, insert data after
252 Label. If FALSE, replace opcodes between two
254 @param Data The adding data; If NULL, remove opcodes between
257 @retval EFI_SUCCESS Update success.
258 @retval Other Update fail.
264 IN EFI_HII_HANDLE Handle
,
265 IN EFI_GUID
*FormSetGuid
, OPTIONAL
266 IN EFI_FORM_ID FormId
,
269 IN EFI_HII_UPDATE_DATA
*Data
273 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
274 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
276 EFI_HII_PACKAGE_LIST_HEADER
*UpdateBuffer
;
278 UINT8
*UpdateBufferPos
;
279 EFI_HII_PACKAGE_HEADER PackageHeader
;
280 EFI_HII_PACKAGE_HEADER
*Package
;
281 UINT32 PackageLength
;
282 EFI_HII_PACKAGE_HEADER
*TempBuffer
;
283 UINT32 TempBufferSize
;
287 return EFI_INVALID_PARAMETER
;
290 HiiDatabase
= gIfrLibHiiDatabase
;
293 // Get the orginal package list
296 HiiPackageList
= NULL
;
297 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
298 if (Status
== EFI_BUFFER_TOO_SMALL
) {
299 HiiPackageList
= AllocatePool (BufferSize
);
300 ASSERT (HiiPackageList
!= NULL
);
302 Status
= HiiDatabase
->ExportPackageLists (HiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
303 if (EFI_ERROR (Status
)) {
304 gBS
->FreePool (HiiPackageList
);
310 // Calculate and allocate space for retrieval of IFR data
312 BufferSize
+= Data
->Offset
;
313 UpdateBuffer
= AllocateZeroPool (BufferSize
);
314 if (UpdateBuffer
== NULL
) {
315 return EFI_OUT_OF_RESOURCES
;
318 UpdateBufferPos
= (UINT8
*) UpdateBuffer
;
321 // copy the package list header
323 CopyMem (UpdateBufferPos
, HiiPackageList
, sizeof (EFI_HII_PACKAGE_LIST_HEADER
));
324 UpdateBufferPos
+= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
327 for (Index
= 0; ; Index
++) {
328 Status
= GetPackageDataFromPackageList (HiiPackageList
, Index
, &PackageLength
, &Package
);
329 if (Status
== EFI_SUCCESS
) {
330 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
331 if ((PackageHeader
.Type
== EFI_HII_PACKAGE_FORM
) && !Updated
) {
332 Status
= UpdateFormPackageData (FormSetGuid
, FormId
, Package
, PackageLength
, Label
, Insert
, Data
, (UINT8
**)&TempBuffer
, &TempBufferSize
);
333 if (!EFI_ERROR(Status
)) {
334 if (FormSetGuid
== NULL
) {
337 CopyMem (UpdateBufferPos
, TempBuffer
, TempBufferSize
);
338 UpdateBufferPos
+= TempBufferSize
;
339 gBS
->FreePool (TempBuffer
);
344 CopyMem (UpdateBufferPos
, Package
, PackageLength
);
345 UpdateBufferPos
+= PackageLength
;
346 } else if (Status
== EFI_NOT_FOUND
) {
349 gBS
->FreePool (HiiPackageList
);
355 // Update package list length
357 BufferSize
= UpdateBufferPos
- (UINT8
*) UpdateBuffer
;
358 CopyMem (&UpdateBuffer
->PackageLength
, &BufferSize
, sizeof (UINT32
));
360 gBS
->FreePool (HiiPackageList
);
362 return HiiDatabase
->UpdatePackageList (HiiDatabase
, Handle
, UpdateBuffer
);
367 Configure the buffer accrording to ConfigBody strings.
369 @param DefaultId the ID of default.
370 @param Buffer the start address of buffer.
371 @param BufferSize the size of buffer.
372 @param Number the number of the strings.
374 @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate.
375 @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0.
376 @retval EFI_SUCCESS Operation successful.
381 IfrLibExtractDefault(
383 IN UINTN
*BufferSize
,
397 if ((Buffer
== NULL
) || (BufferSize
== NULL
)) {
398 return EFI_INVALID_PARAMETER
;
405 VA_START (Args
, Number
);
406 for (Index
= 0; Index
< Number
; Index
++) {
407 BufCfgArray
= (UINT8
*) VA_ARG (Args
, VOID
*);
408 CopyMem (&TotalLen
, BufCfgArray
, sizeof (UINT32
));
409 BufferPos
= BufCfgArray
+ sizeof (UINT32
);
411 while ((UINT32
)(BufferPos
- BufCfgArray
) < TotalLen
) {
412 CopyMem (&Offset
, BufferPos
, sizeof (UINT16
));
413 BufferPos
+= sizeof (UINT16
);
414 CopyMem (&Width
, BufferPos
, sizeof (UINT16
));
415 BufferPos
+= sizeof (UINT16
);
419 if ((UINTN
)(Offset
+ Width
) > *BufferSize
) {
420 return EFI_BUFFER_TOO_SMALL
;
423 CopyMem ((UINT8
*)Buffer
+ Offset
, Value
, Width
);
428 *BufferSize
= (UINTN
)Offset
;