]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Utility.c
Code scrub for Universal\Console\GraphicsConsoleDxe.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / Utility.c
... / ...
CommitLineData
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
18#include "HiiHandle.h"\r
19#include <Library/DebugLib.h>\r
20\r
21CONST EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
22CONST CHAR16 FrameworkReservedVarstoreName[] = FRAMEWORK_RESERVED_VARSTORE_NAME;\r
23\r
24\r
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
30\r
31 @return NULL If Framework HII Handle is invalid.\r
32 @return The corresponding UEFI HII Handle.\r
33**/\r
34EFI_HII_HANDLE\r
35FwHiiHandleToUefiHiiHandle (\r
36 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
37 IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
38 )\r
39{\r
40 HII_THUNK_CONTEXT *ThunkContext;\r
41\r
42 ASSERT (FwHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);\r
43 ASSERT (Private != NULL);\r
44\r
45 ThunkContext = FwHiiHandleToThunkContext (Private, FwHiiHandle);\r
46\r
47 if (ThunkContext != NULL) {\r
48 return ThunkContext->UefiHiiHandle;\r
49 }\r
50 \r
51 return (EFI_HII_HANDLE) NULL;\r
52}\r
53\r
54\r
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
64HII_THUNK_CONTEXT *\r
65FwHiiHandleToThunkContext (\r
66 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
67 IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
68 )\r
69{\r
70 LIST_ENTRY *Link;\r
71 HII_THUNK_CONTEXT *ThunkContext;\r
72\r
73\r
74 Link = GetFirstNode (&Private->ThunkContextListHead);\r
75\r
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
81 }\r
82\r
83 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
84 }\r
85\r
86 return NULL;\r
87}\r
88\r
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
98HII_THUNK_CONTEXT *\r
99UefiHiiHandleToThunkContext (\r
100 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
101 IN EFI_HII_HANDLE UefiHiiHandle\r
102 )\r
103{\r
104 LIST_ENTRY *Link;\r
105 HII_THUNK_CONTEXT *ThunkContext;\r
106\r
107 Link = GetFirstNode (&Private->ThunkContextListHead);\r
108\r
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
114 }\r
115 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
116 }\r
117\r
118 return NULL;\r
119}\r
120\r
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
130HII_THUNK_CONTEXT *\r
131TagGuidToIfrPackThunkContext (\r
132 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
133 IN CONST EFI_GUID *Guid\r
134 )\r
135{\r
136 LIST_ENTRY *Link;\r
137 HII_THUNK_CONTEXT *ThunkContext;\r
138\r
139 Link = GetFirstNode (&Private->ThunkContextListHead);\r
140\r
141 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
142 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
143\r
144 if (CompareGuid (Guid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount != 0)) {\r
145 return ThunkContext;\r
146 }\r
147\r
148 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
149 }\r
150\r
151 return NULL;\r
152 \r
153}\r
154\r
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
160\r
161**/\r
162VOID\r
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
173 DestroyThunkContext (ThunkContext);\r
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
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
198 Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
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
210 return ThunkContext;\r
211}\r
212\r
213\r
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
222UINTN\r
223GetPackageCountByType (\r
224 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,\r
225 IN UINT8 PackageType\r
226 )\r
227{\r
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
245/**\r
246 Get the Form Package from a Framework Package List.\r
247\r
248 @param Packages Framework Package List.\r
249\r
250 @return The Form Package Header found.\r
251**/\r
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
272 switch (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type) {\r
273 case EFI_HII_IFR:\r
274 return &TianoAutogenPackageHdrArray[Index]->PackageHeader;\r
275 break;\r
276 case EFI_HII_STRING:\r
277 case EFI_HII_FONT:\r
278 break;\r
279\r
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
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
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
316 CopyGuid (FormSetGuid, (EFI_GUID *)(VOID *)&FormSet->Guid);\r
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
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
372\r
373 @param ThunkContext The HII Thunk Private Context to be freed.\r
374\r
375**/\r
376VOID\r
377DestroyThunkContext (\r
378 IN HII_THUNK_CONTEXT *ThunkContext\r
379 )\r
380{\r
381 ASSERT (ThunkContext != NULL);\r
382\r
383 FreeHiiHandle (ThunkContext->FwHiiHandle);\r
384\r
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
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
400\r
401 @param FormSet The Form Set. The Default Varstore ID is updated if found.\r
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
411 FORMSET_STORAGE *DefaultStorage;\r
412\r
413 //\r
414 // VarStoreId 0 is invalid in UEFI IFR.\r
415 //\r
416 DefaultStorage= NULL;\r
417 FormSet->DefaultVarStoreId = 0;\r
418 StorageList = GetFirstNode (&FormSet->StorageListHead);\r
419\r
420 while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
421 Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
422\r
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
424\r
425 if (Storage->VarStoreId == FRAMEWORK_RESERVED_VARSTORE_ID) {\r
426 //\r
427 // 1) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01) is found, Var Store ID is used.\r
428 //\r
429 FormSet->DefaultVarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;\r
430 DefaultStorage = Storage;\r
431 break;\r
432 }\r
433\r
434 StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
435 }\r
436\r
437 if (FormSet->DefaultVarStoreId != FRAMEWORK_RESERVED_VARSTORE_ID) {\r
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
443 StorageList = GetFirstNode (&FormSet->StorageListHead);\r
444 if (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
445 Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
446 FormSet->DefaultVarStoreId = Storage->VarStoreId;\r
447 DefaultStorage = Storage;\r
448 }\r
449 \r
450 }\r
451\r
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
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
467 }\r
468 DEBUG_CODE_END ();\r
469 \r
470 return;\r
471}\r
472\r
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
482\r
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
490EFI_STATUS\r
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
496 )\r
497{\r
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
512\r
513 //\r
514 // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
515 //\r
516 if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
517 ReturnDefault = TRUE;\r
518 } else {\r
519 ReturnDefault = FALSE;\r
520 }\r
521\r
522 //\r
523 // Get HII PackageList\r
524 //\r
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
537\r
538 //\r
539 // Get Form package from this HII package List\r
540 //\r
541 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
542 Offset2 = 0;\r
543 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
544\r
545 while (Offset < PackageListLength) {\r
546 Package = ((UINT8 *) HiiPackageList) + Offset;\r
547 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
548\r
549 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
550 //\r
551 // Search FormSet in this Form Package\r
552 //\r
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
558 //\r
559 // Check whether return default FormSet\r
560 //\r
561 if (ReturnDefault) {\r
562 break;\r
563 }\r
564\r
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
570 }\r
571 }\r
572\r
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
581 }\r
582 }\r
583\r
584 Offset += PackageHeader.Length;\r
585 }\r
586\r
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
594\r
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
600 }\r
601\r
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
609\r
610 gBS->FreePool (HiiPackageList);\r
611\r
612 if (*BinaryData == NULL) {\r
613 return EFI_OUT_OF_RESOURCES;\r
614 }\r
615\r
616 return EFI_SUCCESS;\r
617}\r
618\r
619/**\r
620 Initialize the internal data structure of a FormSet.\r
621\r
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
627\r
628 @retval EFI_SUCCESS The function completed successfully.\r
629 @retval EFI_NOT_FOUND The specified FormSet could not be found.\r
630\r
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
637 )\r
638{\r
639 EFI_STATUS Status;\r
640\r
641 Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
642 if (EFI_ERROR (Status)) {\r
643 return Status;\r
644 }\r
645\r
646 FormSet->HiiHandle = Handle;\r
647 CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
648\r
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
655 }\r
656\r
657 GetFormsetDefaultVarstoreId (FormSet);\r
658 return Status;\r
659}\r
660\r
661/**\r
662 Parse the Form Package and build a FORM_BROWSER_FORMSET structure.\r
663\r
664 @param UefiHiiHandle PackageList Handle\r
665\r
666 @return A pointer to FORM_BROWSER_FORMSET.\r
667\r
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
680\r
681 CopyGuid (&FormSetGuid, &gZeroGuid);\r
682 Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);\r
683 ASSERT_EFI_ERROR (Status);\r
684\r
685 return FormSet;\r
686}\r
687\r