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