]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/Utility.c
remove the DEBUG_CODE_BEGIN and DEBUG_CODE_END due to the logic between them are...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / 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 This function returns a list of the package handles of the \r
27 specified type that are currently active in the HII database. The \r
28 pseudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package \r
29 handles to be listed.\r
30\r
31 If HandleBufferLength is NULL, then ASSERT.\r
32 If HandleBuffer is NULL, the ASSERT.\r
33 If PackageType is EFI_HII_PACKAGE_TYPE_GUID and PackageGuid is\r
34 NULL, then ASSERT.\r
35 If PackageType is not EFI_HII_PACKAGE_TYPE_GUID and PackageGuid is not\r
36 NULL, then ASSERT.\r
37 \r
38 \r
39 @param PackageType Specifies the package type of the packages\r
40 to list or EFI_HII_PACKAGE_TYPE_ALL for\r
41 all packages to be listed.\r
42 \r
43 @param PackageGuid If PackageType is\r
44 EFI_HII_PACKAGE_TYPE_GUID, then this is\r
45 the pointer to the GUID which must match\r
46 the Guid field of\r
47 EFI_HII_PACKAGE_GUID_HEADER. Otherwise, it\r
48 must be NULL.\r
49 \r
50 @param HandleBufferLength On output, the length of the handle buffer\r
51 that is required for the handles found.\r
52\r
53 @param HandleBuffer On output, an array of EFI_HII_HANDLE instances returned.\r
54 The caller is responcible to free this pointer allocated.\r
55\r
56 @retval EFI_SUCCESS The matching handles are outputed successfully.\r
57 HandleBufferLength is updated with the actual length.\r
58 @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operation.\r
59 @retval EFI_NOT_FOUND No matching handle could not be found in database.\r
60**/\r
61EFI_STATUS\r
62EFIAPI\r
63ListPackageLists (\r
64 IN UINT8 PackageType,\r
65 IN CONST EFI_GUID *PackageGuid,\r
66 IN OUT UINTN *HandleBufferLength,\r
67 OUT EFI_HII_HANDLE **HandleBuffer\r
68 )\r
69{\r
70 EFI_STATUS Status;\r
71 \r
72 ASSERT (HandleBufferLength != NULL);\r
73 ASSERT (HandleBuffer != NULL);\r
74 \r
75 *HandleBufferLength = 0;\r
76 *HandleBuffer = NULL;\r
77\r
78 if (PackageType == EFI_HII_PACKAGE_TYPE_GUID) {\r
79 ASSERT (PackageGuid != NULL);\r
80 } else {\r
81 ASSERT (PackageGuid == NULL);\r
82 }\r
83\r
84 Status = mHiiDatabase->ListPackageLists (\r
85 mHiiDatabase,\r
86 PackageType,\r
87 PackageGuid,\r
88 HandleBufferLength,\r
89 *HandleBuffer\r
90 );\r
91 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {\r
92 //\r
93 // No packages is registered to UEFI HII Database, just return.\r
94 // \r
95 //\r
96 return Status;\r
97 }\r
98\r
99 *HandleBuffer = AllocateZeroPool (*HandleBufferLength);\r
100 \r
101 if (*HandleBuffer == NULL) {\r
102 return EFI_OUT_OF_RESOURCES;\r
103 }\r
104 \r
105 return mHiiDatabase->ListPackageLists (\r
106 mHiiDatabase,\r
107 PackageType,\r
108 PackageGuid,\r
109 HandleBufferLength,\r
110 *HandleBuffer\r
111 );\r
112 \r
113}\r
114\r
115/**\r
116 Exports the contents of one or all package lists in the HII database into a buffer.\r
117\r
118 If Handle is not NULL and not a valid EFI_HII_HANDLE registered in the database, \r
119 then ASSERT.\r
120 If PackageListHeader is NULL, then ASSERT.\r
121 If PackageListSize is NULL, then ASSERT.\r
122\r
123 @param Handle The HII Handle.\r
124 @param PackageListHeader A pointer to a buffer that will contain the results of \r
125 the export function.\r
126 @param PackageListSize On output, the length of the buffer that is required for the exported data.\r
127\r
128 @retval EFI_SUCCESS Package exported.\r
129\r
130 @retval EFI_OUT_OF_RESOURCES Not enought memory to complete the operations.\r
131\r
132**/\r
133EFI_STATUS \r
134EFIAPI\r
135ExportPackageLists (\r
136 IN EFI_HII_HANDLE Handle,\r
137 OUT EFI_HII_PACKAGE_LIST_HEADER **PackageListHeader,\r
138 OUT UINTN *PackageListSize\r
139 )\r
140{\r
141 EFI_STATUS Status;\r
142 UINTN Size;\r
143 EFI_HII_PACKAGE_LIST_HEADER *PackageListHdr;\r
144\r
145 ASSERT (PackageListSize != NULL);\r
146 ASSERT (PackageListHeader != NULL);\r
147\r
148 Size = 0;\r
149 PackageListHdr = NULL;\r
150 Status = mHiiDatabase->ExportPackageLists (\r
151 mHiiDatabase,\r
152 Handle,\r
153 &Size,\r
154 PackageListHdr\r
155 );\r
156 ASSERT_EFI_ERROR (Status != EFI_BUFFER_TOO_SMALL);\r
157 \r
158 if (Status == EFI_BUFFER_TOO_SMALL) {\r
159 PackageListHdr = AllocateZeroPool (Size);\r
160 \r
161 if (PackageListHeader == NULL) {\r
162 return EFI_OUT_OF_RESOURCES;\r
163 } else {\r
164 Status = mHiiDatabase->ExportPackageLists (\r
165 mHiiDatabase,\r
166 Handle,\r
167 &Size,\r
168 PackageListHdr\r
169 );\r
170 }\r
171 }\r
172\r
173 if (!EFI_ERROR (Status)) {\r
174 *PackageListHeader = PackageListHdr;\r
175 *PackageListSize = Size;\r
176 } else {\r
177 FreePool (PackageListHdr);\r
178 }\r
179\r
180 return Status;\r
181}\r
182\r
183/**\r
184 Extract Hii package list GUID for given HII handle.\r
185\r
186 If HiiHandle could not be found in the HII database, then ASSERT.\r
187 If Guid is NULL, then ASSERT.\r
188\r
189 @param Handle Hii handle\r
190 @param Guid Package list GUID\r
191\r
192 @retval EFI_SUCCESS Successfully extract GUID from Hii database.\r
193\r
194**/\r
195EFI_STATUS\r
196EFIAPI\r
197ExtractGuidFromHiiHandle (\r
198 IN EFI_HII_HANDLE Handle,\r
199 OUT EFI_GUID *Guid\r
200 )\r
201{\r
202 EFI_STATUS Status;\r
203 UINTN BufferSize;\r
204 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
205\r
206 ASSERT (Guid != NULL);\r
207 ASSERT (Handle != NULL);\r
208\r
209 //\r
210 // Get HII PackageList\r
211 //\r
212 BufferSize = 0;\r
213 HiiPackageList = NULL;\r
214\r
215 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
216 ASSERT (Status != EFI_NOT_FOUND);\r
217 \r
218 if (Status == EFI_BUFFER_TOO_SMALL) {\r
219 HiiPackageList = AllocatePool (BufferSize);\r
220 ASSERT (HiiPackageList != NULL);\r
221\r
222 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
223 }\r
224 if (EFI_ERROR (Status)) {\r
225 FreePool (HiiPackageList);\r
226 return Status;\r
227 }\r
228\r
229 //\r
230 // Extract GUID\r
231 //\r
232 CopyGuid (Guid, &HiiPackageList->PackageListGuid);\r
233\r
234 FreePool (HiiPackageList);\r
235\r
236 return EFI_SUCCESS;\r
237}\r
238\r
239/**\r
240 Find the corressponding UEFI HII Handle from a Framework HII Handle given.\r
241\r
242 @param Private The HII Thunk Module Private context.\r
243 @param FwHiiHandle The Framemwork HII Handle.\r
244\r
245 @return NULL If Framework HII Handle is invalid.\r
246 @return The corresponding UEFI HII Handle.\r
247**/\r
248EFI_HII_HANDLE\r
249FwHiiHandleToUefiHiiHandle (\r
250 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
251 IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
252 )\r
253{\r
254 HII_THUNK_CONTEXT *ThunkContext;\r
255\r
256 ASSERT (FwHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);\r
257 ASSERT (Private != NULL);\r
258\r
259 ThunkContext = FwHiiHandleToThunkContext (Private, FwHiiHandle);\r
260\r
261 if (ThunkContext != NULL) {\r
262 return ThunkContext->UefiHiiHandle;\r
263 }\r
264 \r
265 return (EFI_HII_HANDLE) NULL;\r
266}\r
267\r
268\r
269/**\r
270 Find the corressponding HII Thunk Context from a Framework HII Handle given.\r
271\r
272 @param Private The HII Thunk Module Private context.\r
273 @param FwHiiHandle The Framemwork HII Handle.\r
274\r
275 @return NULL If Framework HII Handle is invalid.\r
276 @return The corresponding HII Thunk Context.\r
277**/\r
278HII_THUNK_CONTEXT *\r
279FwHiiHandleToThunkContext (\r
280 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
281 IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
282 )\r
283{\r
284 LIST_ENTRY *Link;\r
285 HII_THUNK_CONTEXT *ThunkContext;\r
286\r
287\r
288 Link = GetFirstNode (&Private->ThunkContextListHead);\r
289\r
290 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
291 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
292\r
293 if (FwHiiHandle == ThunkContext->FwHiiHandle) {\r
294 return ThunkContext;\r
295 }\r
296\r
297 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
298 }\r
299\r
300 return NULL;\r
301}\r
302\r
303/**\r
304 Find the corressponding HII Thunk Context from a UEFI HII Handle given.\r
305\r
306 @param Private The HII Thunk Module Private context.\r
307 @param UEFIHiiHandle The UEFI HII Handle.\r
308\r
309 @return NULL If UEFI HII Handle is invalid.\r
310 @return The corresponding HII Thunk Context.\r
311**/\r
312HII_THUNK_CONTEXT *\r
313UefiHiiHandleToThunkContext (\r
314 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
315 IN EFI_HII_HANDLE UefiHiiHandle\r
316 )\r
317{\r
318 LIST_ENTRY *Link;\r
319 HII_THUNK_CONTEXT *ThunkContext;\r
320\r
321 Link = GetFirstNode (&Private->ThunkContextListHead);\r
322\r
323 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
324 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
325\r
326 if (UefiHiiHandle == ThunkContext->UefiHiiHandle) {\r
327 return ThunkContext;\r
328 }\r
329 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
330 }\r
331\r
332 return NULL;\r
333}\r
334\r
335/**\r
336 Find the corressponding HII Thunk Context from a Tag GUID.\r
337\r
338 @param Private The HII Thunk Module Private context.\r
339 @param Guid The Tag GUID.\r
340\r
341 @return NULL No HII Thunk Context matched the Tag GUID.\r
342 @return The corresponding HII Thunk Context.\r
343**/\r
344HII_THUNK_CONTEXT *\r
345TagGuidToIfrPackThunkContext (\r
346 IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
347 IN CONST EFI_GUID *Guid\r
348 )\r
349{\r
350 LIST_ENTRY *Link;\r
351 HII_THUNK_CONTEXT *ThunkContext;\r
352\r
353 Link = GetFirstNode (&Private->ThunkContextListHead);\r
354\r
355 while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
356 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
357\r
358 if (CompareGuid (Guid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount != 0)) {\r
359 return ThunkContext;\r
360 }\r
361\r
362 Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
363 }\r
364\r
365 return NULL;\r
366 \r
367}\r
368\r
369/**\r
370 Clean up the HII Thunk Context for a UEFI HII Handle.\r
371\r
372 @param Private The HII Thunk Module Private context.\r
373 @param UEFIHiiHandle The UEFI HII Handle.\r
374\r
375**/\r
376VOID\r
377DestroyThunkContextForUefiHiiHandle (\r
378 IN HII_THUNK_PRIVATE_DATA *Private,\r
379 IN EFI_HII_HANDLE UefiHiiHandle\r
380 )\r
381{\r
382 HII_THUNK_CONTEXT *ThunkContext;\r
383\r
384 ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);\r
385 ASSERT (ThunkContext != NULL);\r
386\r
387 DestroyThunkContext (ThunkContext);\r
388}\r
389\r
390\r
391/**\r
392 This function create a HII_THUNK_CONTEXT for a package list registered\r
393 by a module calling EFI_HII_DATABASE_PROTOCOL.NewPackageList. It records\r
394 the PackageListGuid in EFI_HII_PACKAGE_LIST_HEADER in the TagGuid in \r
395 HII_THUNK_CONTEXT created. This TagGuid will be used as a key to s\r
396\r
397**/\r
398HII_THUNK_CONTEXT *\r
399CreateThunkContextForUefiHiiHandle (\r
400 IN EFI_HII_HANDLE UefiHiiHandle\r
401 )\r
402{\r
403 EFI_STATUS Status;\r
404 EFI_GUID PackageGuid;\r
405 HII_THUNK_CONTEXT *ThunkContext;\r
406\r
407 ThunkContext = AllocateZeroPool (sizeof (*ThunkContext));\r
408 ASSERT (ThunkContext != NULL);\r
409 \r
410 ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
411\r
412 Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
413 if (EFI_ERROR (Status)) {\r
414 return NULL;\r
415 }\r
416 \r
417 ThunkContext->UefiHiiHandle = UefiHiiHandle;\r
418 \r
419 Status = ExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid);\r
420 ASSERT_EFI_ERROR (Status);\r
421 \r
422 CopyGuid(&ThunkContext->TagGuid, &PackageGuid);\r
423\r
424 return ThunkContext;\r
425}\r
426\r
427\r
428/**\r
429 Get the number of HII Package for a Package type.\r
430\r
431 @param PackageListHeader The Package List.\r
432 @param PackageType The Package Type.\r
433\r
434 @return The number of Package for given type.\r
435**/\r
436UINTN\r
437GetPackageCountByType (\r
438 IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,\r
439 IN UINT8 PackageType\r
440 )\r
441{\r
442 UINTN Count;\r
443 EFI_HII_PACKAGE_HEADER *PackageHeader;\r
444\r
445 PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageListHeader + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
446 Count = 0;\r
447 \r
448 while (PackageHeader->Type != EFI_HII_PACKAGE_END) {\r
449 if (PackageHeader->Type == PackageType ) {\r
450 Count++;\r
451 }\r
452 PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);\r
453 }\r
454 \r
455 \r
456 return Count;\r
457}\r
458\r
459/**\r
460 Get the Form Package from a Framework Package List.\r
461\r
462 @param Packages Framework Package List.\r
463\r
464 @return The Form Package Header found.\r
465**/\r
466EFI_HII_PACKAGE_HEADER *\r
467GetIfrPackage (\r
468 IN CONST EFI_HII_PACKAGES *Packages\r
469 )\r
470{\r
471 UINTN Index;\r
472 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
473\r
474 ASSERT (Packages != NULL);\r
475\r
476 TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
477 \r
478 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
479 //\r
480 // The current UEFI HII build tool generate a binary in the format defined by \r
481 // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
482 // this binary is with same package type. So the returned IfrPackageCount and StringPackageCount\r
483 // may not be the exact number of valid package number in the binary generated \r
484 // by HII Build tool.\r
485 //\r
486 switch (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type) {\r
487 case EFI_HII_IFR:\r
488 return &TianoAutogenPackageHdrArray[Index]->PackageHeader;\r
489 break;\r
490 case EFI_HII_STRING:\r
491 case EFI_HII_FONT:\r
492 break;\r
493\r
494 default:\r
495 ASSERT (FALSE);\r
496 return NULL;\r
497 break;\r
498 }\r
499 }\r
500\r
501 return NULL;\r
502}\r
503\r
504/**\r
505 Get FormSet GUID.\r
506\r
507 ASSERT if no FormSet Opcode is found.\r
508\r
509 @param Packages Form Framework Package.\r
510 @param FormSetGuid Return the FormSet Guid.\r
511\r
512**/\r
513VOID\r
514GetFormSetGuid (\r
515 IN EFI_HII_PACKAGE_HEADER *Package,\r
516 OUT EFI_GUID *FormSetGuid\r
517 )\r
518{\r
519 UINTN Offset;\r
520 EFI_IFR_OP_HEADER *OpCode;\r
521 EFI_IFR_FORM_SET *FormSet;\r
522\r
523 Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
524 while (Offset < Package->Length) {\r
525 OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\r
526\r
527 switch (OpCode->OpCode) {\r
528 case EFI_IFR_FORM_SET_OP:\r
529 FormSet = (EFI_IFR_FORM_SET *) OpCode;\r
530 CopyGuid (FormSetGuid, (EFI_GUID *)(VOID *)&FormSet->Guid);\r
531 return;\r
532 \r
533 default:\r
534 break;\r
535 \r
536 }\r
537 Offset += OpCode->Length;\r
538 }\r
539\r
540 //\r
541 // A proper IFR must have a formset opcode.\r
542 //\r
543 ASSERT (FALSE);\r
544\r
545}\r
546\r
547/**\r
548 Creat a Thunk Context.\r
549\r
550 ASSERT if no FormSet Opcode is found.\r
551\r
552 @param Private The HII Thunk Private Context.\r
553 @param StringPackageCount The String package count.\r
554 @param FormSetGuid The IFR Package count.\r
555\r
556 @return A newly created Thunk Context.\r
557 @retval NULL No resource to create a new Thunk Context.\r
558**/\r
559HII_THUNK_CONTEXT *\r
560CreateThunkContext (\r
561 IN HII_THUNK_PRIVATE_DATA *Private,\r
562 IN UINTN StringPackageCount,\r
563 IN UINTN IfrPackageCount\r
564 )\r
565{\r
566 EFI_STATUS Status;\r
567 HII_THUNK_CONTEXT *ThunkContext;\r
568\r
569 ThunkContext = AllocateZeroPool (sizeof (HII_THUNK_CONTEXT));\r
570 ASSERT (ThunkContext != NULL);\r
571 \r
572 ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
573 ThunkContext->IfrPackageCount = IfrPackageCount;\r
574 ThunkContext->StringPackageCount = StringPackageCount;\r
575 Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
576 if (EFI_ERROR (Status)) {\r
577 return NULL;\r
578 }\r
579\r
580 return ThunkContext;\r
581 \r
582}\r
583\r
584/**\r
585 Destroy the Thunk Context and free up all resource.\r
586\r
587 @param ThunkContext The HII Thunk Private Context to be freed.\r
588\r
589**/\r
590VOID\r
591DestroyThunkContext (\r
592 IN HII_THUNK_CONTEXT *ThunkContext\r
593 )\r
594{\r
595 ASSERT (ThunkContext != NULL);\r
596\r
597 FreeHiiHandle (ThunkContext->FwHiiHandle);\r
598\r
599 RemoveEntryList (&ThunkContext->Link);\r
600\r
601 if (ThunkContext->FormSet != NULL) {\r
602 DestroyFormSet (ThunkContext->FormSet);\r
603 }\r
604\r
605 FreePool (ThunkContext);\r
606}\r
607\r
608/**\r
609 Get the FormSet's Default Varstore ID based on the rule (Descending Priority):\r
610\r
611 1) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01) is found, Var Store ID is used.\r
612 2) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID is not found, First Var Store ID is used \r
613 as the default Var Store ID.\r
614\r
615 @param FormSet The Form Set. The Default Varstore ID is updated if found.\r
616 \r
617**/\r
618VOID\r
619GetFormsetDefaultVarstoreId (\r
620 IN OUT FORM_BROWSER_FORMSET * FormSet\r
621 )\r
622{\r
623 LIST_ENTRY *StorageList;\r
624 FORMSET_STORAGE *Storage;\r
625 FORMSET_STORAGE *DefaultStorage;\r
626\r
627 //\r
628 // VarStoreId 0 is invalid in UEFI IFR.\r
629 //\r
630 DefaultStorage= NULL;\r
631 FormSet->DefaultVarStoreId = 0;\r
632 StorageList = GetFirstNode (&FormSet->StorageListHead);\r
633\r
634 while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
635 Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
636\r
637 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
638\r
639 if (Storage->VarStoreId == FRAMEWORK_RESERVED_VARSTORE_ID) {\r
640 //\r
641 // 1) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01) is found, Var Store ID is used.\r
642 //\r
643 FormSet->DefaultVarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;\r
644 DefaultStorage = Storage;\r
645 break;\r
646 }\r
647\r
648 StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
649 }\r
650\r
651 if (FormSet->DefaultVarStoreId != FRAMEWORK_RESERVED_VARSTORE_ID) {\r
652 //\r
653 // \r
654 // 2) If VarStore ID of FRAMEWORK_RESERVED_VARSTORE_ID is not found, First Var Store ID is used \r
655 // as the default Var Store ID.\r
656 //\r
657 StorageList = GetFirstNode (&FormSet->StorageListHead);\r
658 if (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
659 Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
660 FormSet->DefaultVarStoreId = Storage->VarStoreId;\r
661 DefaultStorage = Storage;\r
662 }\r
663 \r
664 }\r
665\r
666 if (FormSet->DefaultVarStoreId == 0) {\r
667 DEBUG ((EFI_D_INFO, "FormSet %g: No Varstore Found\n", &FormSet->Guid));\r
668 } else {\r
669 // The name of default VARSTORE with a Explicit declaration statement will be updated to L"Setup" to make sure\r
670 // the Framework HII Setup module will run correctly. Framework HII Setup module always assumed that default\r
671 // VARSTORE to have L"Setup" as name, Formset GUID as GUID. \r
672\r
673 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
674\r
675 if (StrCmp (DefaultStorage->Name, FrameworkReservedVarstoreName) != 0) {\r
676 DEBUG ((EFI_D_INFO, " : Name is updated from %s to %s.\n", DefaultStorage->Name, FrameworkReservedVarstoreName));\r
677 FormSet->OriginalDefaultVarStoreName = DefaultStorage->Name;\r
678 DefaultStorage->Name = AllocateCopyPool (StrSize (FrameworkReservedVarstoreName), FrameworkReservedVarstoreName);\r
679 }\r
680 }\r
681 \r
682 return;\r
683}\r
684\r
685/**\r
686 Fetch the Ifr binary data of a FormSet.\r
687\r
688 @param Handle PackageList Handle\r
689 @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
690 GUID), take the first FormSet found in package\r
691 list.\r
692 @param BinaryLength The length of the FormSet IFR binary.\r
693 @param BinaryData The buffer designed to receive the FormSet.\r
694\r
695 @retval EFI_SUCCESS Buffer filled with the requested FormSet.\r
696 BufferLength was updated.\r
697 @retval EFI_INVALID_PARAMETER The handle is unknown.\r
698 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot\r
699 be found with the requested FormId.\r
700\r
701**/\r
702EFI_STATUS\r
703GetIfrBinaryData (\r
704 IN EFI_HII_HANDLE Handle,\r
705 IN OUT EFI_GUID *FormSetGuid,\r
706 OUT UINTN *BinaryLength,\r
707 OUT UINT8 **BinaryData\r
708 )\r
709{\r
710 EFI_STATUS Status;\r
711 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
712 UINTN BufferSize;\r
713 UINT8 *Package;\r
714 UINT8 *OpCodeData;\r
715 UINT32 Offset;\r
716 UINT32 Offset2;\r
717 BOOLEAN ReturnDefault;\r
718 UINT32 PackageListLength;\r
719 EFI_HII_PACKAGE_HEADER PackageHeader;\r
720\r
721 OpCodeData = NULL;\r
722 Package = NULL;\r
723 ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;\r
724\r
725 //\r
726 // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
727 //\r
728 if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
729 ReturnDefault = TRUE;\r
730 } else {\r
731 ReturnDefault = FALSE;\r
732 }\r
733\r
734 //\r
735 // Get HII PackageList\r
736 //\r
737 BufferSize = 0;\r
738 HiiPackageList = NULL;\r
739 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
740 if (Status == EFI_BUFFER_TOO_SMALL) {\r
741 HiiPackageList = AllocatePool (BufferSize);\r
742 ASSERT (HiiPackageList != NULL);\r
743\r
744 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
745 }\r
746 if (EFI_ERROR (Status)) {\r
747 return Status;\r
748 }\r
749\r
750 //\r
751 // Get Form package from this HII package List\r
752 //\r
753 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
754 Offset2 = 0;\r
755 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
756\r
757 while (Offset < PackageListLength) {\r
758 Package = ((UINT8 *) HiiPackageList) + Offset;\r
759 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
760\r
761 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
762 //\r
763 // Search FormSet in this Form Package\r
764 //\r
765 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
766 while (Offset2 < PackageHeader.Length) {\r
767 OpCodeData = Package + Offset2;\r
768\r
769 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
770 //\r
771 // Check whether return default FormSet\r
772 //\r
773 if (ReturnDefault) {\r
774 break;\r
775 }\r
776\r
777 //\r
778 // FormSet GUID is specified, check it\r
779 //\r
780 if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
781 break;\r
782 }\r
783 }\r
784\r
785 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
786 }\r
787\r
788 if (Offset2 < PackageHeader.Length) {\r
789 //\r
790 // Target formset found\r
791 //\r
792 break;\r
793 }\r
794 }\r
795\r
796 Offset += PackageHeader.Length;\r
797 }\r
798\r
799 if (Offset >= PackageListLength) {\r
800 //\r
801 // Form package not found in this Package List\r
802 //\r
803 gBS->FreePool (HiiPackageList);\r
804 return EFI_NOT_FOUND;\r
805 }\r
806\r
807 if (ReturnDefault && FormSetGuid != NULL) {\r
808 //\r
809 // Return the default FormSet GUID\r
810 //\r
811 CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
812 }\r
813\r
814 //\r
815 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes\r
816 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end\r
817 // of the Form Package.\r
818 //\r
819 *BinaryLength = PackageHeader.Length - Offset2;\r
820 *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);\r
821\r
822 gBS->FreePool (HiiPackageList);\r
823\r
824 if (*BinaryData == NULL) {\r
825 return EFI_OUT_OF_RESOURCES;\r
826 }\r
827\r
828 return EFI_SUCCESS;\r
829}\r
830\r
831/**\r
832 Initialize the internal data structure of a FormSet.\r
833\r
834 @param Handle PackageList Handle\r
835 @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
836 GUID), take the first FormSet found in package\r
837 list.\r
838 @param FormSet FormSet data structure.\r
839\r
840 @retval EFI_SUCCESS The function completed successfully.\r
841 @retval EFI_NOT_FOUND The specified FormSet could not be found.\r
842\r
843**/\r
844EFI_STATUS\r
845InitializeFormSet (\r
846 IN EFI_HII_HANDLE Handle,\r
847 IN OUT EFI_GUID *FormSetGuid,\r
848 OUT FORM_BROWSER_FORMSET *FormSet\r
849 )\r
850{\r
851 EFI_STATUS Status;\r
852\r
853 Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
854 if (EFI_ERROR (Status)) {\r
855 return Status;\r
856 }\r
857\r
858 FormSet->HiiHandle = Handle;\r
859 CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
860\r
861 //\r
862 // Parse the IFR binary OpCodes\r
863 //\r
864 Status = ParseOpCodes (FormSet);\r
865 if (EFI_ERROR (Status)) {\r
866 return Status;\r
867 }\r
868\r
869 GetFormsetDefaultVarstoreId (FormSet);\r
870 return Status;\r
871}\r
872\r
873/**\r
874 Parse the Form Package and build a FORM_BROWSER_FORMSET structure.\r
875\r
876 @param UefiHiiHandle PackageList Handle\r
877\r
878 @return A pointer to FORM_BROWSER_FORMSET.\r
879\r
880**/\r
881FORM_BROWSER_FORMSET *\r
882ParseFormSet (\r
883 IN EFI_HII_HANDLE UefiHiiHandle\r
884 )\r
885{\r
886 FORM_BROWSER_FORMSET *FormSet;\r
887 EFI_GUID FormSetGuid;\r
888 EFI_STATUS Status;\r
889 \r
890 FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); \r
891 ASSERT (FormSet != NULL);\r
892\r
893 CopyGuid (&FormSetGuid, &gZeroGuid);\r
894 Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);\r
895 if (EFI_ERROR (Status)) {\r
896 FreePool (FormSet);\r
897 return NULL;\r
898 }\r
899\r
900 return FormSet;\r
901}\r
902\r