]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/ExtendedIfrSupportLib/Form.c
Update all files to follow doxygen style file header.
[mirror_edk2.git] / MdeModulePkg / Library / ExtendedIfrSupportLib / Form.c
CommitLineData
9226efe5 1/** @file
2
3Copyright (c) 2007, Intel Corporation
4All rights reserved. This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution. The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13
14 UefiIfrForm.c
15
16Abstract:
17
18 Common Library Routines to assist handle HII elements.
19
20
21**/
22
23#include "LibraryInternal.h"
24
25STATIC
26EFI_STATUS
27GetPackageDataFromPackageList (
28 IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,
29 IN UINT32 PackageIndex,
30 OUT UINT32 *BufferLen,
31 OUT EFI_HII_PACKAGE_HEADER **Buffer
32 )
33{
34 UINT32 Index;
35 EFI_HII_PACKAGE_HEADER *Package;
36 UINT32 Offset;
37 UINT32 PackageListLength;
38 EFI_HII_PACKAGE_HEADER PackageHeader = {0, 0};
39
40 ASSERT(HiiPackageList != NULL);
41
42 if ((BufferLen == NULL) || (Buffer == NULL)) {
43 return EFI_INVALID_PARAMETER;
44 }
45
46 Package = NULL;
47 Index = 0;
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) {
54 break;
55 }
56 Offset += PackageHeader.Length;
57 Index++;
58 }
59 if (Offset >= PackageListLength) {
60 //
61 // no package found in this Package List
62 //
63 return EFI_NOT_FOUND;
64 }
65
66 *BufferLen = PackageHeader.Length;
67 *Buffer = Package;
68 return EFI_SUCCESS;
69}
70
71STATIC
72EFI_STATUS
73EFIAPI
74UpdateFormPackageData (
75 IN EFI_GUID *FormSetGuid,
76 IN EFI_FORM_ID FormId,
77 IN EFI_HII_PACKAGE_HEADER *Package,
78 IN UINT32 PackageLength,
79 IN UINT16 Label,
80 IN BOOLEAN Insert,
81 IN EFI_HII_UPDATE_DATA *Data,
82 OUT UINT8 **TempBuffer,
83 OUT UINT32 *TempBufferSize
84 )
85{
86 UINTN AddSize;
87 UINT8 *BufferPos;
88 EFI_HII_PACKAGE_HEADER PackageHeader;
89 UINTN Offset;
90 EFI_IFR_OP_HEADER *IfrOpHdr;
91 BOOLEAN GetFormSet;
92 BOOLEAN GetForm;
93 UINT8 ExtendOpCode;
94 UINT16 LabelNumber;
95 BOOLEAN Updated;
96 EFI_IFR_OP_HEADER *AddOpCode;
97
98 if ((TempBuffer == NULL) || (TempBufferSize == NULL)) {
99 return EFI_INVALID_PARAMETER;
100 }
101
102 *TempBufferSize = PackageLength;
103 if (Data != NULL) {
104 *TempBufferSize += Data->Offset;
105 }
106 *TempBuffer = AllocateZeroPool (*TempBufferSize);
107 if (*TempBuffer == NULL) {
108 return EFI_OUT_OF_RESOURCES;
109 }
110
111 CopyMem (*TempBuffer, Package, sizeof (EFI_HII_PACKAGE_HEADER));
112 *TempBufferSize = sizeof (EFI_HII_PACKAGE_HEADER);
113 BufferPos = *TempBuffer + sizeof (EFI_HII_PACKAGE_HEADER);
114
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);
119 GetForm = FALSE;
120 Updated = FALSE;
121
122 while (Offset < PackageHeader.Length) {
123 CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
124 BufferPos += IfrOpHdr->Length;
125 *TempBufferSize += IfrOpHdr->Length;
126
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) {
131 GetFormSet = TRUE;
132 }
133 }
134 break;
135
136 case EFI_IFR_FORM_OP:
137 if (CompareMem (&((EFI_IFR_FORM *) IfrOpHdr)->FormId, &FormId, sizeof (EFI_FORM_ID)) == 0) {
138 GetForm = TRUE;
139 }
140 break;
141
142 case EFI_IFR_GUID_OP :
143 if (!GetFormSet || !GetForm || Updated) {
144 //
145 // Go to the next Op-Code
146 //
147 Offset += IfrOpHdr->Length;
148 IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
149 continue;
150 }
151
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)) {
155 //
156 // Go to the next Op-Code
157 //
158 Offset += IfrOpHdr->Length;
159 IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
160 continue;
161 }
162
163 if (Insert && (Data != NULL)) {
164 //
165 // insert the DataCount amount of opcodes to TempBuffer if Data is NULL remove
166 // DataCount amount of opcodes unless runing into a label.
167 //
168 AddOpCode = (EFI_IFR_OP_HEADER *)Data->Data;
169 AddSize = 0;
170 while (AddSize < Data->Offset) {
171 CopyMem (BufferPos, AddOpCode, AddOpCode->Length);
172 BufferPos += AddOpCode->Length;
173 *TempBufferSize += AddOpCode->Length;
174
175 AddSize += AddOpCode->Length;
176 AddOpCode = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (AddOpCode) + AddOpCode->Length);
177 }
178 } else {
179 //
180 // Search the next Label.
181 //
182 while (TRUE) {
183 Offset += IfrOpHdr->Length;
184 //
185 // Search the next label and Fail if not label found.
186 //
187 if (Offset >= PackageHeader.Length) {
188 goto Fail;
189 }
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) {
194 break;
195 }
196 }
197 }
198
199 if (Data != NULL) {
200 AddOpCode = (EFI_IFR_OP_HEADER *)Data->Data;
201 AddSize = 0;
202 while (AddSize < Data->Offset) {
203 CopyMem (BufferPos, AddOpCode, AddOpCode->Length);
204 BufferPos += AddOpCode->Length;
205 *TempBufferSize += AddOpCode->Length;
206
207 AddSize += AddOpCode->Length;
208 AddOpCode = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (AddOpCode) + AddOpCode->Length);
209 }
210 }
211
212 //
213 // copy the next label
214 //
215 CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
216 BufferPos += IfrOpHdr->Length;
217 *TempBufferSize += IfrOpHdr->Length;
218 }
219
220 Updated = TRUE;
221 break;
222 default :
223 break;
224 }
225
226 //
227 // Go to the next Op-Code
228 //
229 Offset += IfrOpHdr->Length;
230 IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
231 }
232
233 //
234 // Update the package length.
235 //
236 PackageHeader.Length = *TempBufferSize;
237 CopyMem (*TempBuffer, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));
238
239Fail:
240 if (!Updated) {
241 gBS->FreePool (*TempBuffer);
242 *TempBufferSize = 0;
243 return EFI_NOT_FOUND;
244 }
245
246 return EFI_SUCCESS;
247}
248
249
250/**
251 This function allows the caller to update a form that has
252 previously been registered with the EFI HII database.
253
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
258 label in the IFR
259 @param Insert If TRUE and Data is not NULL, insert data after
260 Label. If FALSE, replace opcodes between two
261 labels with Data
262 @param Data The adding data; If NULL, remove opcodes between
263 two Label.
264
265 @retval EFI_SUCCESS Update success.
266 @retval Other Update fail.
267
268**/
269EFI_STATUS
270EFIAPI
271IfrLibUpdateForm (
272 IN EFI_HII_HANDLE Handle,
273 IN EFI_GUID *FormSetGuid, OPTIONAL
274 IN EFI_FORM_ID FormId,
275 IN UINT16 Label,
276 IN BOOLEAN Insert,
277 IN EFI_HII_UPDATE_DATA *Data
278 )
279{
280 EFI_STATUS Status;
281 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
282 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
283 UINT32 Index;
284 EFI_HII_PACKAGE_LIST_HEADER *UpdateBuffer;
285 UINTN BufferSize;
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;
292 BOOLEAN Updated;
293
294 if (Data == NULL) {
295 return EFI_INVALID_PARAMETER;
296 }
297
298 HiiDatabase = gIfrLibHiiDatabase;
299
300 //
301 // Get the orginal package list
302 //
303 BufferSize = 0;
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);
309
310 Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
311 if (EFI_ERROR (Status)) {
312 gBS->FreePool (HiiPackageList);
313 return Status;
314 }
315 }
316
317 //
318 // Calculate and allocate space for retrieval of IFR data
319 //
320 BufferSize += Data->Offset;
321 UpdateBuffer = AllocateZeroPool (BufferSize);
322 if (UpdateBuffer == NULL) {
323 return EFI_OUT_OF_RESOURCES;
324 }
325
326 UpdateBufferPos = (UINT8 *) UpdateBuffer;
327
328 //
329 // copy the package list header
330 //
331 CopyMem (UpdateBufferPos, HiiPackageList, sizeof (EFI_HII_PACKAGE_LIST_HEADER));
332 UpdateBufferPos += sizeof (EFI_HII_PACKAGE_LIST_HEADER);
333
334 Updated = FALSE;
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) {
343 Updated = TRUE;
344 }
345 CopyMem (UpdateBufferPos, TempBuffer, TempBufferSize);
346 UpdateBufferPos += TempBufferSize;
347 gBS->FreePool (TempBuffer);
348 continue;
349 }
350 }
351
352 CopyMem (UpdateBufferPos, Package, PackageLength);
353 UpdateBufferPos += PackageLength;
354 } else if (Status == EFI_NOT_FOUND) {
355 break;
356 } else {
357 gBS->FreePool (HiiPackageList);
358 return Status;
359 }
360 }
361
362 //
363 // Update package list length
364 //
365 BufferSize = UpdateBufferPos - (UINT8 *) UpdateBuffer;
366 CopyMem (&UpdateBuffer->PackageLength, &BufferSize, sizeof (UINT32));
367
368 gBS->FreePool (HiiPackageList);
369
370 return HiiDatabase->UpdatePackageList (HiiDatabase, Handle, UpdateBuffer);
371}
372
373
374/**
375 Configure the buffer accrording to ConfigBody strings.
376
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.
381
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.
385
386**/
387EFI_STATUS
388EFIAPI
389IfrLibExtractDefault(
390 IN VOID *Buffer,
391 IN UINTN *BufferSize,
392 UINTN Number,
393 ...
394 )
395{
396 VA_LIST Args;
397 UINTN Index;
398 UINT32 TotalLen;
399 UINT8 *BufCfgArray;
400 UINT8 *BufferPos;
401 UINT16 Offset;
402 UINT16 Width;
403 UINT8 *Value;
404
405 if ((Buffer == NULL) || (BufferSize == NULL)) {
406 return EFI_INVALID_PARAMETER;
407 }
408
409 Offset = 0;
410 Width = 0;
411 Value = NULL;
412
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);
418
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);
424 Value = BufferPos;
425 BufferPos += Width;
426
427 if ((UINTN)(Offset + Width) > *BufferSize) {
428 return EFI_BUFFER_TOO_SMALL;
429 }
430
431 CopyMem ((UINT8 *)Buffer + Offset, Value, Width);
432 }
433 }
434 VA_END (Args);
435
436 *BufferSize = (UINTN)Offset;
437
438 return EFI_SUCCESS;
439}
440
441