]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.c
code scrub:
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / Utility.c
CommitLineData
4259256b 1/**@file\r
2\r
3 This file contains the keyboard processing code to the HII database.\r
4\r
5Copyright (c) 2006 - 2008, Intel Corporation\r
6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16\r
17#include "HiiDatabase.h"\r
d4775f2a 18#include "HiiHandle.h"\r
a9d85320 19#include <Library/DebugLib.h>\r
4259256b 20\r
a9d85320 21CONST EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
0368663f 22\r
a9d85320 23/**\r
24 Find the corressponding UEFI HII Handle from a Framework HII Handle given.\r
25\r
26 @param Private The HII Thunk Module Private context.\r
27 @param FwHiiHandle The Framemwork HII Handle.\r
0368663f 28\r
a9d85320 29 @return NULL If Framework HII Handle is invalid.\r
30 @return The corresponding UEFI HII Handle.\r
31**/\r
ee3428bb 32EFI_HII_HANDLE\r
0368663f 33FwHiiHandleToUefiHiiHandle (\r
34 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
35 IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
ee3428bb 36 )\r
37{\r
0368663f 38 HII_THUNK_CONTEXT *ThunkContext;\r
ee3428bb 39\r
0368663f 40 ASSERT (FwHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);\r
ee3428bb 41 ASSERT (Private != NULL);\r
42\r
0368663f 43 ThunkContext = FwHiiHandleToThunkContext (Private, FwHiiHandle);\r
ee3428bb 44\r
0368663f 45 if (ThunkContext != NULL) {\r
46 return ThunkContext->UefiHiiHandle;\r
ee3428bb 47 }\r
48 \r
49 return (EFI_HII_HANDLE) NULL;\r
50}\r
51\r
ebbd2793 52\r
a9d85320 53/**\r
54 Find the corressponding HII Thunk Context from a Framework HII Handle given.\r
55\r
56 @param Private The HII Thunk Module Private context.\r
57 @param FwHiiHandle The Framemwork HII Handle.\r
58\r
59 @return NULL If Framework HII Handle is invalid.\r
60 @return The corresponding HII Thunk Context.\r
61**/\r
0368663f 62HII_THUNK_CONTEXT *\r
63FwHiiHandleToThunkContext (\r
64 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
65 IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
ebbd2793 66 )\r
67{\r
0368663f 68 LIST_ENTRY *Link;\r
69 HII_THUNK_CONTEXT *ThunkContext;\r
70\r
ebbd2793 71\r
0368663f 72 Link = GetFirstNode (&Private->ThunkContextListHead);\r
ebbd2793 73\r
0368663f 74 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
75 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
76\r
77 if (FwHiiHandle == ThunkContext->FwHiiHandle) {\r
78 return ThunkContext;\r
ebbd2793 79 }\r
0368663f 80\r
81 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
ebbd2793 82 }\r
83\r
0368663f 84 return NULL;\r
ebbd2793 85}\r
86\r
a9d85320 87/**\r
88 Find the corressponding HII Thunk Context from a UEFI HII Handle given.\r
89\r
90 @param Private The HII Thunk Module Private context.\r
91 @param UEFIHiiHandle The UEFI HII Handle.\r
92\r
93 @return NULL If UEFI HII Handle is invalid.\r
94 @return The corresponding HII Thunk Context.\r
95**/\r
0368663f 96HII_THUNK_CONTEXT *\r
97UefiHiiHandleToThunkContext (\r
98 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
ea58467b 99 IN EFI_HII_HANDLE UefiHiiHandle\r
100 )\r
101{\r
0368663f 102 LIST_ENTRY *Link;\r
103 HII_THUNK_CONTEXT *ThunkContext;\r
ea58467b 104\r
0368663f 105 Link = GetFirstNode (&Private->ThunkContextListHead);\r
ea58467b 106\r
0368663f 107 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
108 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
109\r
110 if (UefiHiiHandle == ThunkContext->UefiHiiHandle) {\r
111 return ThunkContext;\r
ea58467b 112 }\r
0368663f 113 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
ea58467b 114 }\r
115\r
0368663f 116 return NULL;\r
ea58467b 117}\r
99a83b4c 118\r
a9d85320 119/**\r
120 Find the corressponding HII Thunk Context from a Tag GUID.\r
121\r
122 @param Private The HII Thunk Module Private context.\r
123 @param Guid The Tag GUID.\r
124\r
125 @return NULL No HII Thunk Context matched the Tag GUID.\r
126 @return The corresponding HII Thunk Context.\r
127**/\r
8ea58c07 128HII_THUNK_CONTEXT *\r
129TagGuidToIfrPackThunkContext (\r
0368663f 130 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
99a83b4c 131 IN CONST EFI_GUID *Guid\r
132 )\r
133{\r
0368663f 134 LIST_ENTRY *Link;\r
135 HII_THUNK_CONTEXT *ThunkContext;\r
136\r
137 Link = GetFirstNode (&Private->ThunkContextListHead);\r
99a83b4c 138\r
0368663f 139 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
140 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
99a83b4c 141\r
8ea58c07 142 if (CompareGuid (Guid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount != 0)) {\r
143 return ThunkContext;\r
99a83b4c 144 }\r
0368663f 145\r
146 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
99a83b4c 147 }\r
148\r
0368663f 149 return NULL;\r
99a83b4c 150 \r
151}\r
152\r
a9d85320 153/**\r
154 Clean up the HII Thunk Context for a UEFI HII Handle.\r
155\r
156 @param Private The HII Thunk Module Private context.\r
157 @param UEFIHiiHandle The UEFI HII Handle.\r
0368663f 158\r
a9d85320 159**/\r
d4775f2a 160VOID\r
0368663f 161DestroyThunkContextForUefiHiiHandle (\r
162 IN HII_THUNK_PRIVATE_DATA *Private,\r
163 IN EFI_HII_HANDLE UefiHiiHandle\r
164 )\r
165{\r
166 HII_THUNK_CONTEXT *ThunkContext;\r
167\r
168 ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);\r
169 ASSERT (ThunkContext != NULL);\r
170\r
d4775f2a 171 DestroyThunkContext (ThunkContext);\r
0368663f 172}\r
173\r
174\r
175/**\r
176 This function create a HII_THUNK_CONTEXT for a package list registered\r
177 by a module calling EFI_HII_DATABASE_PROTOCOL.NewPackageList. It records\r
178 the PackageListGuid in EFI_HII_PACKAGE_LIST_HEADER in the TagGuid in \r
179 HII_THUNK_CONTEXT created. This TagGuid will be used as a key to s\r
180\r
181**/\r
182HII_THUNK_CONTEXT *\r
183CreateThunkContextForUefiHiiHandle (\r
0368663f 184 IN EFI_HII_HANDLE UefiHiiHandle\r
185 )\r
186{\r
187 EFI_STATUS Status;\r
188 EFI_GUID PackageGuid;\r
189 HII_THUNK_CONTEXT *ThunkContext;\r
190\r
191 ThunkContext = AllocateZeroPool (sizeof (*ThunkContext));\r
192 ASSERT (ThunkContext != NULL);\r
193 \r
194 ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
195\r
d4775f2a 196 Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
0368663f 197 if (EFI_ERROR (Status)) {\r
198 return NULL;\r
199 }\r
200 \r
201 ThunkContext->UefiHiiHandle = UefiHiiHandle;\r
202 \r
203 Status = HiiLibExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid);\r
204 ASSERT_EFI_ERROR (Status);\r
205 \r
206 CopyGuid(&ThunkContext->TagGuid, &PackageGuid);\r
207\r
0368663f 208 return ThunkContext;\r
209}\r
210\r
211\r
a9d85320 212/**\r
213 Get the number of HII Package for a Package type.\r
214\r
215 @param PackageListHeader The Package List.\r
216 @param PackageType The Package Type.\r
217\r
218 @return The number of Package for given type.\r
219**/\r
0368663f 220UINTN\r
221GetPackageCountByType (\r
222 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,\r
223 IN UINT8 PackageType\r
ea58467b 224 )\r
225{\r
0368663f 226 UINTN Count;\r
227 EFI_HII_PACKAGE_HEADER *PackageHeader;\r
228\r
229 PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageListHeader + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
230 Count = 0;\r
231 \r
232 while (PackageHeader->Type != EFI_HII_PACKAGE_END) {\r
233 if (PackageHeader->Type == PackageType ) {\r
234 Count++;\r
235 }\r
236 PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);\r
237 }\r
238 \r
239 \r
240 return Count;\r
241}\r
242\r
a9d85320 243/**\r
244 Get the Form Package from a Framework Package List.\r
0368663f 245\r
a9d85320 246 @param Packages Framework Package List.\r
99a83b4c 247\r
a9d85320 248 @return The Form Package Header found.\r
249**/\r
bc226416 250EFI_HII_PACKAGE_HEADER *\r
251GetIfrPackage (\r
252 IN CONST EFI_HII_PACKAGES *Packages\r
253 )\r
254{\r
255 UINTN Index;\r
256 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
257\r
258 ASSERT (Packages != NULL);\r
259\r
260 TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
261 \r
262 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
263 //\r
264 // The current UEFI HII build tool generate a binary in the format defined by \r
265 // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
266 // this binary is with same package type. So the returned IfrPackageCount and StringPackageCount\r
267 // may not be the exact number of valid package number in the binary generated \r
268 // by HII Build tool.\r
269 //\r
70d72ba9 270 switch (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type) {\r
271 case EFI_HII_IFR:\r
bc226416 272 return &TianoAutogenPackageHdrArray[Index]->PackageHeader;\r
273 break;\r
70d72ba9 274 case EFI_HII_STRING:\r
275 case EFI_HII_FONT:\r
bc226416 276 break;\r
277\r
bc226416 278 default:\r
279 ASSERT (FALSE);\r
280 return NULL;\r
281 break;\r
282 }\r
283 }\r
284\r
285 return NULL;\r
286}\r
287\r
a9d85320 288/**\r
289 Get FormSet GUID.\r
290\r
291 ASSERT if no FormSet Opcode is found.\r
292\r
293 @param Packages Form Framework Package.\r
294 @param FormSetGuid Return the FormSet Guid.\r
295\r
296**/\r
bc226416 297VOID\r
298GetFormSetGuid (\r
299 IN EFI_HII_PACKAGE_HEADER *Package,\r
300 OUT EFI_GUID *FormSetGuid\r
301 )\r
302{\r
303 UINTN Offset;\r
304 EFI_IFR_OP_HEADER *OpCode;\r
305 EFI_IFR_FORM_SET *FormSet;\r
306\r
307 Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
308 while (Offset < Package->Length) {\r
309 OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\r
310\r
311 switch (OpCode->OpCode) {\r
312 case EFI_IFR_FORM_SET_OP:\r
313 FormSet = (EFI_IFR_FORM_SET *) OpCode;\r
66df2531 314 CopyGuid (FormSetGuid, (EFI_GUID *)(VOID *)&FormSet->Guid);\r
bc226416 315 return;\r
316 \r
317 default:\r
318 break;\r
319 \r
320 }\r
321 Offset += OpCode->Length;\r
322 }\r
323\r
324 //\r
325 // A proper IFR must have a formset opcode.\r
326 //\r
327 ASSERT (FALSE);\r
328\r
329}\r
330\r
a9d85320 331/**\r
332 Creat a Thunk Context.\r
333\r
334 ASSERT if no FormSet Opcode is found.\r
335\r
336 @param Private The HII Thunk Private Context.\r
337 @param StringPackageCount The String package count.\r
338 @param FormSetGuid The IFR Package count.\r
339\r
340 @return A newly created Thunk Context.\r
341 @retval NULL No resource to create a new Thunk Context.\r
342**/\r
343HII_THUNK_CONTEXT *\r
344CreateThunkContext (\r
345 IN HII_THUNK_PRIVATE_DATA *Private,\r
346 IN UINTN StringPackageCount,\r
347 IN UINTN IfrPackageCount\r
348 )\r
349{\r
350 EFI_STATUS Status;\r
351 HII_THUNK_CONTEXT *ThunkContext;\r
352\r
353 ThunkContext = AllocateZeroPool (sizeof (HII_THUNK_CONTEXT));\r
354 ASSERT (ThunkContext != NULL);\r
355 \r
356 ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
357 ThunkContext->IfrPackageCount = IfrPackageCount;\r
358 ThunkContext->StringPackageCount = StringPackageCount;\r
359 Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
360 if (EFI_ERROR (Status)) {\r
361 return NULL;\r
362 }\r
363\r
364 return ThunkContext;\r
365 \r
366}\r
367\r
368/**\r
369 Destroy the Thunk Context and free up all resource.\r
bc226416 370\r
a9d85320 371 @param ThunkContext The HII Thunk Private Context to be freed.\r
372\r
373**/\r
59930165 374VOID\r
a9d85320 375DestroyThunkContext (\r
376 IN HII_THUNK_CONTEXT *ThunkContext\r
59930165 377 )\r
378{\r
a9d85320 379 ASSERT (ThunkContext != NULL);\r
59930165 380\r
a9d85320 381 FreeHiiHandle (ThunkContext->FwHiiHandle);\r
59930165 382\r
a9d85320 383 RemoveEntryList (&ThunkContext->Link);\r
384\r
385 if (ThunkContext->FormSet != NULL) {\r
386 DestroyFormSet (ThunkContext->FormSet);\r
387 }\r
388\r
389 FreePool (ThunkContext);\r
390}\r
391\r
392/**\r
393 Get the FormSet's Default Varstore ID based on the rule (Descending Priority):\r
394\r
03254710 395 1) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01) is found, Var Store ID is used.\r
396 2) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID is not found, First Var Store ID is used \r
397 as the default Var Store ID.\r
a9d85320 398\r
03254710 399 @param FormSet The Form Set. The Default Varstore ID is updated if found.\r
a9d85320 400 \r
401**/\r
402VOID\r
403GetFormsetDefaultVarstoreId (\r
404 IN OUT FORM_BROWSER_FORMSET * FormSet\r
405 )\r
406{\r
407 LIST_ENTRY *StorageList;\r
408 FORMSET_STORAGE *Storage;\r
59930165 409\r
410 //\r
a9d85320 411 // VarStoreId 0 is invalid in UEFI IFR.\r
59930165 412 //\r
a9d85320 413 FormSet->DefaultVarStoreId = 0;\r
414 StorageList = GetFirstNode (&FormSet->StorageListHead);\r
59930165 415\r
a9d85320 416 while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
417 Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
59930165 418\r
73d1dcbb 419 DEBUG ((EFI_D_INFO, "FormSet %g: Found Varstore ID %x Name %s Size 0x%x\n", &FormSet->Guid, Storage->VarStoreId, Storage->Name, Storage->Size));\r
59930165 420\r
a9d85320 421 if (Storage->VarStoreId == FRAMEWORK_RESERVED_VARSTORE_ID) {\r
73d1dcbb 422 //\r
423 // 1) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01) is found, Var Store ID is used.\r
424 //\r
a9d85320 425 FormSet->DefaultVarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;\r
59930165 426 break;\r
427 }\r
428\r
a9d85320 429 StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
430 }\r
431\r
432 if (FormSet->DefaultVarStoreId != FRAMEWORK_RESERVED_VARSTORE_ID) {\r
73d1dcbb 433 //\r
434 // \r
435 // 2) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID is not found, First Var Store ID is used \r
436 // as the default Var Store ID.\r
437 //\r
a9d85320 438 StorageList = GetFirstNode (&FormSet->StorageListHead);\r
439 if (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
440 Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
98b16b9d 441 FormSet->DefaultVarStoreId = Storage->VarStoreId;\r
a9d85320 442 }\r
443 \r
59930165 444 }\r
445\r
a9d85320 446 DEBUG_CODE_BEGIN ();\r
447 if (FormSet->DefaultVarStoreId == 0) {\r
448 DEBUG ((EFI_D_INFO, "FormSet %g: No Varstore Found\n", &FormSet->Guid));\r
449 } else {\r
450 DEBUG ((EFI_D_INFO, "FormSet %g: Default Varstore ID is %x\n", &FormSet->Guid, FormSet->DefaultVarStoreId));\r
451 }\r
452 DEBUG_CODE_END ();\r
453 \r
454 return;\r
59930165 455}\r
456\r
a9d85320 457/**\r
458 Fetch the Ifr binary data of a FormSet.\r
459\r
460 @param Handle PackageList Handle\r
461 @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
462 GUID), take the first FormSet found in package\r
463 list.\r
464 @param BinaryLength The length of the FormSet IFR binary.\r
465 @param BinaryData The buffer designed to receive the FormSet.\r
99a83b4c 466\r
a9d85320 467 @retval EFI_SUCCESS Buffer filled with the requested FormSet.\r
468 BufferLength was updated.\r
469 @retval EFI_INVALID_PARAMETER The handle is unknown.\r
470 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot\r
471 be found with the requested FormId.\r
472\r
473**/\r
0368663f 474EFI_STATUS\r
a9d85320 475GetIfrBinaryData (\r
476 IN EFI_HII_HANDLE Handle,\r
477 IN OUT EFI_GUID *FormSetGuid,\r
478 OUT UINTN *BinaryLength,\r
479 OUT UINT8 **BinaryData\r
0368663f 480 )\r
481{\r
a9d85320 482 EFI_STATUS Status;\r
483 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
484 UINTN BufferSize;\r
485 UINT8 *Package;\r
486 UINT8 *OpCodeData;\r
487 UINT32 Offset;\r
488 UINT32 Offset2;\r
489 BOOLEAN ReturnDefault;\r
490 UINT32 PackageListLength;\r
491 EFI_HII_PACKAGE_HEADER PackageHeader;\r
492\r
493 OpCodeData = NULL;\r
494 Package = NULL;\r
495 ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;\r
59e87364 496\r
497 //\r
a9d85320 498 // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
59e87364 499 //\r
a9d85320 500 if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
501 ReturnDefault = TRUE;\r
502 } else {\r
503 ReturnDefault = FALSE;\r
ea58467b 504 }\r
99a83b4c 505\r
0368663f 506 //\r
a9d85320 507 // Get HII PackageList\r
0368663f 508 //\r
a9d85320 509 BufferSize = 0;\r
510 HiiPackageList = NULL;\r
511 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
512 if (Status == EFI_BUFFER_TOO_SMALL) {\r
513 HiiPackageList = AllocatePool (BufferSize);\r
514 ASSERT (HiiPackageList != NULL);\r
515\r
516 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
517 }\r
518 if (EFI_ERROR (Status)) {\r
519 return Status;\r
520 }\r
0368663f 521\r
522 //\r
a9d85320 523 // Get Form package from this HII package List\r
0368663f 524 //\r
a9d85320 525 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
526 Offset2 = 0;\r
527 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
0368663f 528\r
a9d85320 529 while (Offset < PackageListLength) {\r
530 Package = ((UINT8 *) HiiPackageList) + Offset;\r
531 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
0368663f 532\r
a9d85320 533 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
0368663f 534 //\r
a9d85320 535 // Search FormSet in this Form Package\r
0368663f 536 //\r
a9d85320 537 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
538 while (Offset2 < PackageHeader.Length) {\r
539 OpCodeData = Package + Offset2;\r
540\r
541 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
0368663f 542 //\r
a9d85320 543 // Check whether return default FormSet\r
0368663f 544 //\r
a9d85320 545 if (ReturnDefault) {\r
546 break;\r
59e87364 547 }\r
548\r
a9d85320 549 //\r
550 // FormSet GUID is specified, check it\r
551 //\r
552 if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
553 break;\r
0368663f 554 }\r
0368663f 555 }\r
556\r
a9d85320 557 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
558 }\r
559\r
560 if (Offset2 < PackageHeader.Length) {\r
561 //\r
562 // Target formset found\r
563 //\r
564 break;\r
0368663f 565 }\r
0368663f 566 }\r
567\r
a9d85320 568 Offset += PackageHeader.Length;\r
0368663f 569 }\r
570\r
a9d85320 571 if (Offset >= PackageListLength) {\r
572 //\r
573 // Form package not found in this Package List\r
574 //\r
575 gBS->FreePool (HiiPackageList);\r
576 return EFI_NOT_FOUND;\r
577 }\r
0368663f 578\r
a9d85320 579 if (ReturnDefault && FormSetGuid != NULL) {\r
580 //\r
581 // Return the default FormSet GUID\r
582 //\r
583 CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
0368663f 584 }\r
0368663f 585\r
a9d85320 586 //\r
587 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes\r
588 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end\r
589 // of the Form Package.\r
590 //\r
591 *BinaryLength = PackageHeader.Length - Offset2;\r
592 *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);\r
0368663f 593\r
a9d85320 594 gBS->FreePool (HiiPackageList);\r
d4775f2a 595\r
a9d85320 596 if (*BinaryData == NULL) {\r
597 return EFI_OUT_OF_RESOURCES;\r
d4775f2a 598 }\r
599\r
a9d85320 600 return EFI_SUCCESS;\r
d4775f2a 601}\r
602\r
a9d85320 603/**\r
604 Initialize the internal data structure of a FormSet.\r
d4775f2a 605\r
a9d85320 606 @param Handle PackageList Handle\r
607 @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
608 GUID), take the first FormSet found in package\r
609 list.\r
610 @param FormSet FormSet data structure.\r
d4775f2a 611\r
a9d85320 612 @retval EFI_SUCCESS The function completed successfully.\r
613 @retval EFI_NOT_FOUND The specified FormSet could not be found.\r
d4775f2a 614\r
a9d85320 615**/\r
616EFI_STATUS\r
617InitializeFormSet (\r
618 IN EFI_HII_HANDLE Handle,\r
619 IN OUT EFI_GUID *FormSetGuid,\r
620 OUT FORM_BROWSER_FORMSET *FormSet\r
d4775f2a 621 )\r
622{\r
a9d85320 623 EFI_STATUS Status;\r
d4775f2a 624\r
a9d85320 625 Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
626 if (EFI_ERROR (Status)) {\r
627 return Status;\r
628 }\r
d4775f2a 629\r
a9d85320 630 FormSet->HiiHandle = Handle;\r
631 CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
d4775f2a 632\r
a9d85320 633 //\r
634 // Parse the IFR binary OpCodes\r
635 //\r
636 Status = ParseOpCodes (FormSet);\r
637 if (EFI_ERROR (Status)) {\r
638 return Status;\r
d4775f2a 639 }\r
a9d85320 640\r
641 GetFormsetDefaultVarstoreId (FormSet);\r
642 return Status;\r
d4775f2a 643}\r
644\r
a9d85320 645/**\r
646 Parse the Form Package and build a FORM_BROWSER_FORMSET structure.\r
d4775f2a 647\r
a9d85320 648 @param UefiHiiHandle PackageList Handle\r
d4775f2a 649\r
a9d85320 650 @return A pointer to FORM_BROWSER_FORMSET.\r
d4775f2a 651\r
a9d85320 652**/\r
653FORM_BROWSER_FORMSET *\r
654ParseFormSet (\r
655 IN EFI_HII_HANDLE UefiHiiHandle\r
656 )\r
657{\r
658 FORM_BROWSER_FORMSET *FormSet;\r
659 EFI_GUID FormSetGuid;\r
660 EFI_STATUS Status;\r
661 \r
662 FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); \r
663 ASSERT (FormSet != NULL);\r
d4775f2a 664\r
a9d85320 665 CopyGuid (&FormSetGuid, &gZeroGuid);\r
666 Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);\r
667 ASSERT_EFI_ERROR (Status);\r
d4775f2a 668\r
a9d85320 669 return FormSet;\r
d4775f2a 670}\r
671\r