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