]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrDefault.c
Bug fixes for FrameworkHiiToUefiHiiThunk;
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / UefiIfrDefault.c
CommitLineData
59336178 1/** @file\r
2 Function and Macro defintions for to extract default values from UEFI Form package.\r
3\r
4 Copyright (c) 2008, Intel Corporation\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15\r
16#include <FrameworkDxe.h>\r
17\r
18#include <Protocol/FrameworkHii.h>\r
19#include <Protocol/HiiDatabase.h>\r
20\r
21#include <Library/BaseLib.h>\r
22#include <Library/BaseMemoryLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/MemoryAllocationLib.h>\r
25#include <Library/UefiBootServicesTableLib.h>\r
26\r
27#include "UefiIfrParser.h"\r
28#include "UefiIfrDefault.h"\r
29\r
30//\r
31// Extern Variables\r
32//\r
33extern CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
59336178 34extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;\r
35extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;\r
36extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;\r
37\r
38extern EFI_GUID gZeroGuid;\r
39\r
40/**\r
41 Fetch the Ifr binary data of a FormSet.\r
42\r
43 @param Handle PackageList Handle\r
44 @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
45 GUID), take the first FormSet found in package\r
46 list.\r
47 @param BinaryLength The length of the FormSet IFR binary.\r
48 @param BinaryData The buffer designed to receive the FormSet.\r
49\r
50 @retval EFI_SUCCESS Buffer filled with the requested FormSet.\r
51 BufferLength was updated.\r
52 @retval EFI_INVALID_PARAMETER The handle is unknown.\r
53 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot\r
54 be found with the requested FormId.\r
55\r
56**/\r
57EFI_STATUS\r
58GetIfrBinaryData (\r
59 IN EFI_HII_HANDLE Handle,\r
60 IN OUT EFI_GUID *FormSetGuid,\r
61 OUT UINTN *BinaryLength,\r
62 OUT UINT8 **BinaryData\r
63 )\r
64{\r
65 EFI_STATUS Status;\r
66 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
67 UINTN BufferSize;\r
68 UINT8 *Package;\r
69 UINT8 *OpCodeData;\r
70 UINT32 Offset;\r
71 UINT32 Offset2;\r
72 BOOLEAN ReturnDefault;\r
73 UINT32 PackageListLength;\r
74 EFI_HII_PACKAGE_HEADER PackageHeader;\r
75\r
76 OpCodeData = NULL;\r
77 Package = NULL;\r
78 ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;\r
79\r
80 //\r
81 // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
82 //\r
83 if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
84 ReturnDefault = TRUE;\r
85 } else {\r
86 ReturnDefault = FALSE;\r
87 }\r
88\r
89 //\r
90 // Get HII PackageList\r
91 //\r
92 BufferSize = 0;\r
93 HiiPackageList = NULL;\r
94 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
95 if (Status == EFI_BUFFER_TOO_SMALL) {\r
96 HiiPackageList = AllocatePool (BufferSize);\r
97 ASSERT (HiiPackageList != NULL);\r
98\r
99 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
100 }\r
101 if (EFI_ERROR (Status)) {\r
102 return Status;\r
103 }\r
104\r
105 //\r
106 // Get Form package from this HII package List\r
107 //\r
108 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
109 Offset2 = 0;\r
110 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
111\r
112 while (Offset < PackageListLength) {\r
113 Package = ((UINT8 *) HiiPackageList) + Offset;\r
114 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
115\r
116 if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
117 //\r
118 // Search FormSet in this Form Package\r
119 //\r
120 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
121 while (Offset2 < PackageHeader.Length) {\r
122 OpCodeData = Package + Offset2;\r
123\r
124 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
125 //\r
126 // Check whether return default FormSet\r
127 //\r
128 if (ReturnDefault) {\r
129 break;\r
130 }\r
131\r
132 //\r
133 // FormSet GUID is specified, check it\r
134 //\r
135 if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
136 break;\r
137 }\r
138 }\r
139\r
140 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
141 }\r
142\r
143 if (Offset2 < PackageHeader.Length) {\r
144 //\r
145 // Target formset found\r
146 //\r
147 break;\r
148 }\r
149 }\r
150\r
151 Offset += PackageHeader.Length;\r
152 }\r
153\r
154 if (Offset >= PackageListLength) {\r
155 //\r
156 // Form package not found in this Package List\r
157 //\r
158 gBS->FreePool (HiiPackageList);\r
159 return EFI_NOT_FOUND;\r
160 }\r
161\r
162 if (ReturnDefault && FormSetGuid != NULL) {\r
163 //\r
164 // Return the default FormSet GUID\r
165 //\r
166 CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
167 }\r
168\r
169 //\r
170 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes\r
171 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end\r
172 // of the Form Package.\r
173 //\r
174 *BinaryLength = PackageHeader.Length - Offset2;\r
175 *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);\r
176\r
177 gBS->FreePool (HiiPackageList);\r
178\r
179 if (*BinaryData == NULL) {\r
180 return EFI_OUT_OF_RESOURCES;\r
181 }\r
182\r
183 return EFI_SUCCESS;\r
184}\r
185\r
186/**\r
187 Initialize the internal data structure of a FormSet.\r
188\r
189 @param Handle PackageList Handle\r
190 @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
191 GUID), take the first FormSet found in package\r
192 list.\r
193 @param FormSet FormSet data structure.\r
194\r
195 @retval EFI_SUCCESS The function completed successfully.\r
196 @retval EFI_NOT_FOUND The specified FormSet could not be found.\r
197\r
198**/\r
199EFI_STATUS\r
200InitializeFormSet (\r
201 IN EFI_HII_HANDLE Handle,\r
202 IN OUT EFI_GUID *FormSetGuid,\r
203 OUT FORM_BROWSER_FORMSET *FormSet\r
204 )\r
205{\r
206 EFI_STATUS Status;\r
207 EFI_HANDLE DriverHandle;\r
208\r
209 Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
210 if (EFI_ERROR (Status)) {\r
211 return Status;\r
212 }\r
213\r
214 FormSet->HiiHandle = Handle;\r
215 CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
216\r
217 //\r
218 // Retrieve ConfigAccess Protocol associated with this HiiPackageList\r
219 //\r
220 Status = mHiiDatabase->GetPackageListHandle (mHiiDatabase, Handle, &DriverHandle);\r
221 if (EFI_ERROR (Status)) {\r
222 return Status;\r
223 }\r
224 FormSet->DriverHandle = DriverHandle;\r
225 Status = gBS->HandleProtocol (\r
226 DriverHandle,\r
227 &gEfiHiiConfigAccessProtocolGuid,\r
228 (VOID **) &FormSet->ConfigAccess\r
229 );\r
230 if (EFI_ERROR (Status)) {\r
231 //\r
232 // Configuration Driver don't attach ConfigAccess protocol to its HII package\r
233 // list, then there will be no configuration action required\r
234 //\r
235 FormSet->ConfigAccess = NULL;\r
236 }\r
237\r
238 //\r
239 // Parse the IFR binary OpCodes\r
240 //\r
241 Status = ParseOpCodes (FormSet);\r
242 if (EFI_ERROR (Status)) {\r
243 return Status;\r
244 }\r
245 return Status;\r
246}\r
247\r
248/**\r
249 Set the data position at Offset with Width in Node->Buffer based \r
250 the value passed in.\r
251\r
252 @param Node The Buffer Storage Node.\r
253 @param Value The input value.\r
254 @param Offset The offset in Node->Buffer for the update.\r
255 @param Width The length of the Value.\r
256 \r
257 @retval VOID\r
258\r
259**/\r
260VOID\r
261SetNodeBuffer (\r
262 OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node,\r
263 IN CONST EFI_HII_VALUE *Value,\r
264 IN UINTN Offset,\r
265 IN UINTN Width\r
266 )\r
267{\r
268 ASSERT (Node->Signature == UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE);\r
269 ASSERT (Offset + Width <= Node->Size);\r
270\r
271 CopyMem (Node->Buffer + Offset, &Value->Value.u8, Width);\r
272}\r
273\r
274\r
275/**\r
276 Reset Question to its default value.\r
277\r
278 @param FormSet FormSet data structure.\r
279 @param DefaultId The Class of the default.\r
280\r
281 @retval EFI_SUCCESS Question is reset to default value.\r
282\r
283**/\r
284EFI_STATUS\r
285GetQuestionDefault (\r
286 IN FORM_BROWSER_FORMSET *FormSet,\r
287 IN FORM_BROWSER_FORM *Form,\r
288 IN FORM_BROWSER_STATEMENT *Question,\r
289 IN UINT16 DefaultId,\r
290 IN UINT16 VarStoreId,\r
291 OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node\r
292 )\r
293{\r
294 EFI_STATUS Status;\r
295 LIST_ENTRY *Link;\r
296 QUESTION_DEFAULT *Default;\r
297 QUESTION_OPTION *Option;\r
298 EFI_HII_VALUE *HiiValue;\r
299\r
300 Status = EFI_SUCCESS;\r
301\r
302 //\r
303 // Statement don't have storage, skip them\r
304 //\r
305 if (Question->QuestionId == 0) {\r
306 return Status;\r
307 }\r
308\r
309 if (Question->VarStoreId != VarStoreId) {\r
310 return Status;\r
311 }\r
312\r
313 ASSERT (Question->Storage->Type == EFI_HII_VARSTORE_BUFFER);\r
314\r
315 //\r
316 // There are three ways to specify default value for a Question:\r
317 // 1, use nested EFI_IFR_DEFAULT (highest priority)\r
318 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
319 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
320 //\r
321 HiiValue = &Question->HiiValue;\r
322\r
323 //\r
324 // EFI_IFR_DEFAULT has highest priority\r
325 //\r
326 if (!IsListEmpty (&Question->DefaultListHead)) {\r
327 Link = GetFirstNode (&Question->DefaultListHead);\r
328 while (!IsNull (&Question->DefaultListHead, Link)) {\r
329 Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
330\r
331 if (Default->DefaultId == DefaultId) {\r
332 if (Default->ValueExpression != NULL) {\r
333 //\r
334 // Default is provided by an Expression, evaluate it\r
335 //\r
336 Status = EvaluateExpression (FormSet, Form, Default->ValueExpression);\r
337 if (EFI_ERROR (Status)) {\r
338 return Status;\r
339 }\r
340\r
341 CopyMem (HiiValue, &Default->ValueExpression->Result, sizeof (EFI_HII_VALUE));\r
342 } else {\r
343 //\r
344 // Default value is embedded in EFI_IFR_DEFAULT\r
345 //\r
346 CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r
347 }\r
348 \r
349 SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
350 return EFI_SUCCESS;\r
351 }\r
352\r
353 Link = GetNextNode (&Question->DefaultListHead, Link);\r
354 }\r
355 }\r
356\r
357 //\r
358 // EFI_ONE_OF_OPTION\r
359 //\r
360 if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {\r
361 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
362 //\r
363 // OneOfOption could only provide Standard and Manufacturing default\r
364 //\r
365 Link = GetFirstNode (&Question->OptionListHead);\r
366 while (!IsNull (&Question->OptionListHead, Link)) {\r
367 Option = QUESTION_OPTION_FROM_LINK (Link);\r
368\r
369 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Option->Flags & EFI_IFR_OPTION_DEFAULT)) ||\r
370 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG))\r
371 ) {\r
372 CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
373\r
374 SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
375 return EFI_SUCCESS;\r
376 }\r
377\r
378 Link = GetNextNode (&Question->OptionListHead, Link);\r
379 }\r
380 }\r
381 }\r
382\r
383 //\r
384 // EFI_IFR_CHECKBOX - lowest priority\r
385 //\r
386 if (Question->Operand == EFI_IFR_CHECKBOX_OP) {\r
387 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
388 //\r
389 // Checkbox could only provide Standard and Manufacturing default\r
390 //\r
391 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT)) ||\r
392 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG))\r
393 ) {\r
394 HiiValue->Value.b = TRUE;\r
395 } else {\r
396 HiiValue->Value.b = FALSE;\r
397 }\r
398\r
399 SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
400 return EFI_SUCCESS;\r
401 }\r
402 }\r
403\r
404 return Status;\r
405}\r
406\r
407\r
408/**\r
409 Reset Questions in a Form to their default value.\r
410\r
411 @param FormSet FormSet data structure.\r
412 @param Form The Form which to be reset.\r
413 @param DefaultId The Class of the default.\r
414\r
415 @retval EFI_SUCCESS The function completed successfully.\r
416\r
417**/\r
418EFI_STATUS\r
419ExtractFormDefault (\r
420 IN FORM_BROWSER_FORMSET *FormSet,\r
421 IN FORM_BROWSER_FORM *Form,\r
422 IN UINT16 DefaultId,\r
423 IN UINT16 VarStoreId,\r
424 OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node\r
425 )\r
426{\r
427 EFI_STATUS Status;\r
428 LIST_ENTRY *Link;\r
429 FORM_BROWSER_STATEMENT *Question;\r
430\r
431 Link = GetFirstNode (&Form->StatementListHead);\r
432 while (!IsNull (&Form->StatementListHead, Link)) {\r
433 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
59336178 434 //\r
435 // Reset Question to its default value\r
436 //\r
437 Status = GetQuestionDefault (FormSet, Form, Question, DefaultId, VarStoreId, Node);\r
438 if (EFI_ERROR (Status)) {\r
439 continue;\r
440 }\r
441\r
0368663f 442 Link = GetNextNode (&Form->StatementListHead, Link);\r
59336178 443 }\r
444 return EFI_SUCCESS;\r
445}\r
446\r
447\r
448/**\r
449 Destroy all the buffer allocated for the fileds of\r
450 UEFI_IFR_BUFFER_STORAGE_NODE. The Node itself\r
451 will be freed too.\r
452\r
453 @param FormSet FormSet data structure.\r
454 @param DefaultId The Class of the default.\r
455\r
456 @retval VOID\r
457\r
458**/\r
459VOID\r
460DestroyDefaultNode (\r
461 IN UEFI_IFR_BUFFER_STORAGE_NODE *Node\r
462 )\r
463{\r
464 SafeFreePool (Node->Buffer);\r
465 SafeFreePool (Node->Name);\r
466 SafeFreePool (Node);\r
467}\r
468\r
469\r
470/**\r
471 Get the default value for Buffer Type storage named by\r
472 a Default Store and a Storage Store from a FormSet.\r
473 The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE\r
474 allocated by this function. It is inserted to the link list.\r
475 \r
476 @param DefaultStore The Default Store.\r
477 @param Storage The Storage.\r
478 @param FormSet The Form Set.\r
479 @param UefiDefaultsListHead The head of link list for the output.\r
480\r
481 @retval EFI_SUCCESS Successful.\r
482 \r
483**/\r
484EFI_STATUS\r
485GetBufferTypeDefaultIdAndStorageId (\r
486 IN FORMSET_DEFAULTSTORE *DefaultStore,\r
487 IN FORMSET_STORAGE *Storage,\r
488 IN FORM_BROWSER_FORMSET *FormSet,\r
489 OUT LIST_ENTRY *UefiDefaultsListHead\r
490 )\r
491{\r
492 UEFI_IFR_BUFFER_STORAGE_NODE *Node;\r
493 LIST_ENTRY *Link;\r
494 FORM_BROWSER_FORM *Form;\r
495 EFI_STATUS Status;\r
496\r
497 Node = AllocateZeroPool (sizeof (UEFI_IFR_BUFFER_STORAGE_NODE));\r
498 ASSERT (Node != NULL);\r
499\r
500 Node->Signature = UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE;\r
501 Node->Name = AllocateCopyPool (StrSize (Storage->Name), Storage->Name);\r
502 Node->DefaultId = DefaultStore->DefaultId;\r
b47694b9 503 Node->StoreId = Storage->VarStoreId;\r
59336178 504 CopyGuid (&Node->Guid, &Storage->Guid);\r
505 Node->Size = Storage->Size;\r
506 Node->Buffer = AllocateZeroPool (Node->Size);\r
507 //\r
508 // Extract default from IFR binary\r
509 //\r
510 Link = GetFirstNode (&FormSet->FormListHead);\r
511 while (!IsNull (&FormSet->FormListHead, Link)) {\r
512 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
513\r
514 Status = ExtractFormDefault (FormSet, Form, DefaultStore->DefaultId, Storage->VarStoreId, Node);\r
515 ASSERT_EFI_ERROR (Status);\r
516\r
517 Link = GetNextNode (&FormSet->FormListHead, Link);\r
518 }\r
519\r
520 InsertTailList (UefiDefaultsListHead, &Node->List);\r
521 \r
522 return EFI_SUCCESS;\r
523}\r
524\r
525\r
526/**\r
527 Get the default value for Buffer Type storage named by\r
528 a Default Store from a FormSet.\r
529 The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE\r
530 allocated by this function. The output can be multiple instances\r
531 of UEFI_IFR_BUFFER_STORAGE_NODE. It is inserted to the link list.\r
532 \r
533 @param DefaultStore The Default Store.\r
534 @param FormSet The Form Set.\r
535 @param UefiDefaultsListHead The head of link list for the output.\r
536\r
537 @retval EFI_SUCCESS Successful.\r
538 \r
539**/\r
540EFI_STATUS\r
541GetBufferTypeDefaultId (\r
542 IN FORMSET_DEFAULTSTORE *DefaultStore,\r
543 IN FORM_BROWSER_FORMSET *FormSet,\r
544 OUT LIST_ENTRY *UefiDefaultsListHead\r
545 )\r
546{\r
0368663f 547 LIST_ENTRY *StorageLink;\r
59336178 548 FORMSET_STORAGE *Storage;\r
549 EFI_STATUS Status;\r
550\r
0368663f 551 StorageLink = GetFirstNode (&FormSet->StorageListHead);\r
59336178 552\r
0368663f 553 while (!IsNull (&FormSet->StorageListHead, StorageLink)) {\r
554 Storage = FORMSET_STORAGE_FROM_LINK(StorageLink);\r
59336178 555\r
556 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
557 Status = GetBufferTypeDefaultIdAndStorageId (DefaultStore, Storage, FormSet, UefiDefaultsListHead);\r
558 }\r
559\r
0368663f 560 StorageLink = GetNextNode (&FormSet->StorageListHead, StorageLink);\r
59336178 561 }\r
562 \r
563 return EFI_SUCCESS;\r
564}\r
565\r
566\r
567/**\r
568 Get the default value for Buffer Type storage from the first FormSet\r
569 in the Package List specified by a EFI_HII_HANDLE.\r
570 \r
571 The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE. \r
572 They are inserted to the link list.\r
573 \r
574 @param UefiHiiHandle The handle for the package list.\r
575 @param UefiDefaultsListHead The head of link list for the output.\r
576\r
577 @retval EFI_SUCCESS Successful.\r
578 \r
579**/\r
580EFI_STATUS\r
581UefiIfrGetBufferTypeDefaults (\r
582 IN EFI_HII_HANDLE UefiHiiHandle,\r
583 OUT LIST_ENTRY **UefiDefaults\r
584 )\r
585{\r
586 FORM_BROWSER_FORMSET *FormSet;\r
587 EFI_GUID FormSetGuid;\r
0368663f 588 LIST_ENTRY *DefaultLink;\r
59336178 589 FORMSET_DEFAULTSTORE *DefaultStore;\r
590 EFI_STATUS Status;\r
591\r
592 ASSERT (UefiDefaults != NULL);\r
593\r
594 FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); \r
595 ASSERT (FormSet != NULL);\r
596\r
597 CopyGuid (&FormSetGuid, &gZeroGuid);\r
598 Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);\r
599 ASSERT_EFI_ERROR (Status);\r
600\r
601 *UefiDefaults = AllocateZeroPool (sizeof (LIST_ENTRY));\r
602 ASSERT (UefiDefaults != NULL);\r
603 InitializeListHead (*UefiDefaults);\r
604\r
0368663f 605 DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
606 while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r
607 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
59336178 608\r
609 Status = GetBufferTypeDefaultId (DefaultStore, FormSet, *UefiDefaults);\r
610 ASSERT_EFI_ERROR (Status);\r
611\r
0368663f 612 DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink); \r
59336178 613 }\r
614\r
615 DestroyFormSet (FormSet);\r
616 \r
617 return EFI_SUCCESS;\r
618}\r
619\r
620\r
621/**\r
622 Convert the UEFI Buffer Type default values to a Framework HII default\r
623 values specified by a EFI_HII_VARIABLE_PACK_LIST structure.\r
624 \r
625 @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
626 which contains the default values retrived from\r
627 a UEFI form set.\r
628 @param DefaultMask The default mask.\r
629 The valid values are FRAMEWORK_EFI_IFR_FLAG_DEFAULT\r
630 and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
631 UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING \r
632 from specification to valid default class.\r
633 @param VariablePackList The output default value in a format defined in Framework.\r
634 \r
635\r
636 @retval EFI_SUCCESS Successful.\r
637 @retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or \r
638 FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.\r
639**/\r
640EFI_STATUS\r
0368663f 641UefiDefaultsToFwDefaults (\r
59336178 642 IN LIST_ENTRY *ListHead,\r
643 IN UINTN DefaultMask,\r
644 OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList\r
645 )\r
646{\r
647 LIST_ENTRY *List;\r
648 UEFI_IFR_BUFFER_STORAGE_NODE *Node;\r
649 UINTN Size;\r
650 UINTN Count;\r
651 UINT16 DefaultId;\r
652 EFI_HII_VARIABLE_PACK *Pack;\r
653 EFI_HII_VARIABLE_PACK_LIST *PackList;\r
654\r
655 if (DefaultMask == FRAMEWORK_EFI_IFR_FLAG_DEFAULT) {\r
656 DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
657 } else if (DefaultMask == FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING) {\r
658 DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
659 } else {\r
660 //\r
661 // UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING \r
662 // from specification to valid default class.\r
663 //\r
664 ASSERT (FALSE);\r
665 return EFI_INVALID_PARAMETER;\r
666 }\r
667 \r
668 //\r
669 // Calculate the size of the output EFI_HII_VARIABLE_PACK_LIST structure\r
670 //\r
671 Size = 0;\r
672 Count = 0;\r
673 List = GetFirstNode (ListHead);\r
674 while (!IsNull (ListHead, List)) {\r
675 Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);\r
676\r
677 if (Node->DefaultId == DefaultId) {\r
678 Size += Node->Size;\r
679 Size += StrSize (Node->Name);\r
680\r
681 Count++;\r
682 }\r
683 \r
684 List = GetNextNode (ListHead, List); \r
685 }\r
686\r
687 Size = Size + Count * (sizeof (EFI_HII_VARIABLE_PACK_LIST) + sizeof (EFI_HII_VARIABLE_PACK));\r
688 \r
689 *VariablePackList = AllocateZeroPool (Size);\r
690 ASSERT (*VariablePackList != NULL);\r
691\r
692 List = GetFirstNode (ListHead);\r
693\r
694 PackList = (EFI_HII_VARIABLE_PACK_LIST *) *VariablePackList;\r
695 Pack = (EFI_HII_VARIABLE_PACK *) (PackList + 1);\r
696 while (!IsNull (ListHead, List)) {\r
697 Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);\r
698\r
699 Size = 0; \r
700 if (Node->DefaultId == DefaultId) {\r
701 Size += Node->Size;\r
702 Size += StrSize (Node->Name);\r
703 Size += sizeof (EFI_HII_VARIABLE_PACK); \r
704\r
705 //\r
706 // In UEFI, 0 is defined to be invalid for EFI_IFR_VARSTORE.VarStoreId.\r
707 // So the default storage of Var Store in VFR from a Framework module \r
708 // should be translated to 0xFFEE.\r
709 //\r
5391c4f1 710 if (Node->StoreId == RESERVED_VARSTORE_ID) {\r
59336178 711 Pack->VariableId = 0;\r
b47694b9 712 } else {\r
713 Pack->VariableId = Node->StoreId;\r
59336178 714 }\r
715 //\r
716 // Initialize EFI_HII_VARIABLE_PACK\r
717 //\r
718 Pack->Header.Type = 0;\r
dee6b58d 719 Pack->Header.Length = (UINT32) Size;\r
720 Pack->VariableNameLength = (UINT32) StrSize (Node->Name);\r
59336178 721 CopyMem (&Pack->VariableGuid, &Node->Guid, sizeof (EFI_GUID));\r
722 \r
723 CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK), Node->Name, StrSize (Node->Name));\r
724 CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK) + Pack->VariableNameLength, Node->Buffer, Node->Size);\r
725\r
726 Size += sizeof (EFI_HII_VARIABLE_PACK_LIST);\r
727\r
728 //\r
729 // initialize EFI_HII_VARIABLE_PACK_LIST\r
730 //\r
731 PackList->VariablePack = Pack;\r
732 PackList->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *)((UINT8 *) PackList + Size);\r
733 \r
734 }\r
735 \r
736 List = GetNextNode (ListHead, List); \r
737 }\r
738 \r
739 \r
740 return EFI_SUCCESS;\r
741}\r
742\r
743\r
744/**\r
745 Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.\r
746 \r
747 @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
748 which contains the default values retrived from\r
749 a UEFI form set.\r
750 \r
751\r
b47694b9 752 @retval VOID\r
59336178 753**/\r
754VOID\r
755FreeDefaultList (\r
756 IN LIST_ENTRY *ListHead\r
757 )\r
758{\r
0368663f 759 LIST_ENTRY *Link;\r
59336178 760 UEFI_IFR_BUFFER_STORAGE_NODE *Default;\r
761\r
0368663f 762 Link = GetFirstNode (ListHead);\r
59336178 763 \r
0368663f 764 while (!IsNull (ListHead, Link)) {\r
765 Default = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(Link);\r
59336178 766\r
0368663f 767 RemoveEntryList (Link);\r
59336178 768 \r
769 DestroyDefaultNode (Default);\r
770 \r
0368663f 771 Link = GetNextNode (ListHead, Link);\r
59336178 772 }\r
773\r
774 FreePool (ListHead);\r
775}\r
776\r