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