]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/UefiIfrDefault.c
Remove unnecessary FRAMEWORK_ prefix in IntelFrameworkPkg definitions for those defin...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / UefiIfrDefault.c
... / ...
CommitLineData
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#include "HiiDatabase.h"\r
16#include "UefiIfrParser.h"\r
17#include "UefiIfrDefault.h"\r
18\r
19//\r
20// Extern Variables\r
21//\r
22extern CONST EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
23extern CONST EFI_HII_IMAGE_PROTOCOL *mHiiImageProtocol;\r
24extern CONST EFI_HII_STRING_PROTOCOL *mHiiStringProtocol;\r
25extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRoutingProtocol;\r
26\r
27/**\r
28 Set the data position at Offset with Width in Node->Buffer based \r
29 the value passed in.\r
30\r
31 @param Node The Buffer Storage Node.\r
32 @param Value The input value.\r
33 @param Offset The offset in Node->Buffer for the update.\r
34 @param Width The length of the Value.\r
35 \r
36 @retval VOID\r
37\r
38**/\r
39VOID\r
40SetNodeBuffer (\r
41 OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node,\r
42 IN CONST EFI_HII_VALUE *Value,\r
43 IN UINTN Offset,\r
44 IN UINTN Width\r
45 )\r
46{\r
47 ASSERT (Node->Signature == UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE);\r
48 ASSERT (Offset + Width <= Node->Size);\r
49\r
50 CopyMem (Node->Buffer + Offset, &Value->Value.u8, Width);\r
51}\r
52\r
53\r
54/**\r
55 Reset Question to its default value.\r
56\r
57 Note Framework 0.92's HII Implementation does not support for default value for these opcodes:\r
58 EFI_IFR_ORDERED_LIST_OP:\r
59 EFI_IFR_PASSWORD_OP:\r
60 EFI_IFR_STRING_OP:\r
61\r
62 @param FormSet FormSet data structure.\r
63 @param DefaultId The Class of the default.\r
64\r
65 @retval EFI_SUCCESS Question is reset to default value.\r
66\r
67**/\r
68EFI_STATUS\r
69GetQuestionDefault (\r
70 IN FORM_BROWSER_FORMSET *FormSet,\r
71 IN FORM_BROWSER_FORM *Form,\r
72 IN FORM_BROWSER_STATEMENT *Question,\r
73 IN UINT16 DefaultId,\r
74 IN UINT16 VarStoreId,\r
75 OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node\r
76 )\r
77{\r
78 EFI_STATUS Status;\r
79 LIST_ENTRY *Link;\r
80 QUESTION_DEFAULT *Default;\r
81 QUESTION_OPTION *Option;\r
82 EFI_HII_VALUE *HiiValue;\r
83\r
84 Status = EFI_SUCCESS;\r
85\r
86 //\r
87 // Statement don't have storage, skip them\r
88 //\r
89 if (Question->QuestionId == 0) {\r
90 return Status;\r
91 }\r
92\r
93 if (Question->VarStoreId != VarStoreId) {\r
94 return Status;\r
95 }\r
96\r
97 ASSERT (Question->Storage->Type == EFI_HII_VARSTORE_BUFFER);\r
98\r
99 //\r
100 // There are three ways to specify default value for a Question:\r
101 // 1, use nested EFI_IFR_DEFAULT (highest priority)\r
102 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
103 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
104 //\r
105 HiiValue = &Question->HiiValue;\r
106\r
107 //\r
108 // EFI_IFR_DEFAULT has highest priority\r
109 //\r
110 if (!IsListEmpty (&Question->DefaultListHead)) {\r
111 Link = GetFirstNode (&Question->DefaultListHead);\r
112 while (!IsNull (&Question->DefaultListHead, Link)) {\r
113 Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
114\r
115 if (Default->DefaultId == DefaultId) {\r
116 //\r
117 // Default value is embedded in EFI_IFR_DEFAULT\r
118 //\r
119 CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r
120 \r
121 SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
122 return EFI_SUCCESS;\r
123 }\r
124\r
125 Link = GetNextNode (&Question->DefaultListHead, Link);\r
126 }\r
127 }\r
128\r
129 //\r
130 // EFI_ONE_OF_OPTION\r
131 //\r
132 if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {\r
133 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
134 //\r
135 // OneOfOption could only provide Standard and Manufacturing default\r
136 //\r
137 Link = GetFirstNode (&Question->OptionListHead);\r
138 while (!IsNull (&Question->OptionListHead, Link)) {\r
139 Option = QUESTION_OPTION_FROM_LINK (Link);\r
140\r
141 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Option->Flags & EFI_IFR_OPTION_DEFAULT)) ||\r
142 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG))\r
143 ) {\r
144 CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
145\r
146 SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
147 return EFI_SUCCESS;\r
148 }\r
149\r
150 Link = GetNextNode (&Question->OptionListHead, Link);\r
151 }\r
152 }\r
153 }\r
154\r
155 //\r
156 // EFI_IFR_CHECKBOX - lowest priority\r
157 //\r
158 if (Question->Operand == EFI_IFR_CHECKBOX_OP) {\r
159 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
160 //\r
161 // Checkbox could only provide Standard and Manufacturing default\r
162 //\r
163 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT)) ||\r
164 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && (Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG))\r
165 ) {\r
166 HiiValue->Value.b = TRUE;\r
167 } else {\r
168 HiiValue->Value.b = FALSE;\r
169 }\r
170\r
171 SetNodeBuffer (Node, HiiValue, Question->VarStoreInfo.VarOffset, Question->StorageWidth);\r
172 return EFI_SUCCESS;\r
173 }\r
174 }\r
175\r
176 return Status;\r
177}\r
178\r
179\r
180/**\r
181 Reset Questions in a Form to their default value.\r
182\r
183 @param FormSet FormSet data structure.\r
184 @param Form The Form which to be reset.\r
185 @param DefaultId The Class of the default.\r
186\r
187 @retval EFI_SUCCESS The function completed successfully.\r
188\r
189**/\r
190EFI_STATUS\r
191ExtractFormDefault (\r
192 IN FORM_BROWSER_FORMSET *FormSet,\r
193 IN FORM_BROWSER_FORM *Form,\r
194 IN UINT16 DefaultId,\r
195 IN UINT16 VarStoreId,\r
196 OUT UEFI_IFR_BUFFER_STORAGE_NODE *Node\r
197 )\r
198{\r
199 EFI_STATUS Status;\r
200 LIST_ENTRY *Link;\r
201 FORM_BROWSER_STATEMENT *Question;\r
202\r
203 Link = GetFirstNode (&Form->StatementListHead);\r
204 while (!IsNull (&Form->StatementListHead, Link)) {\r
205 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
206 //\r
207 // Reset Question to its default value\r
208 //\r
209 Status = GetQuestionDefault (FormSet, Form, Question, DefaultId, VarStoreId, Node);\r
210 if (EFI_ERROR (Status)) {\r
211 continue;\r
212 }\r
213\r
214 Link = GetNextNode (&Form->StatementListHead, Link);\r
215 }\r
216 return EFI_SUCCESS;\r
217}\r
218\r
219\r
220/**\r
221 Destroy all the buffer allocated for the fileds of\r
222 UEFI_IFR_BUFFER_STORAGE_NODE. The Node itself\r
223 will be freed too.\r
224\r
225 @param FormSet FormSet data structure.\r
226 @param DefaultId The Class of the default.\r
227\r
228 @retval VOID\r
229\r
230**/\r
231VOID\r
232DestroyDefaultNode (\r
233 IN UEFI_IFR_BUFFER_STORAGE_NODE *Node\r
234 )\r
235{\r
236 FreePool (Node->Buffer);\r
237 FreePool (Node->Name);\r
238 FreePool (Node);\r
239}\r
240\r
241\r
242/**\r
243 Get the default value for Buffer Type storage named by\r
244 a Default Store and a Storage Store from a FormSet.\r
245 The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE\r
246 allocated by this function. It is inserted to the link list.\r
247 \r
248 @param DefaultStore The Default Store.\r
249 @param Storage The Storage.\r
250 @param FormSet The Form Set.\r
251 @param UefiDefaultsListHead The head of link list for the output.\r
252\r
253 @retval EFI_SUCCESS Successful.\r
254 \r
255**/\r
256EFI_STATUS\r
257GetBufferTypeDefaultIdAndStorageId (\r
258 IN FORMSET_DEFAULTSTORE *DefaultStore,\r
259 IN FORMSET_STORAGE *Storage,\r
260 IN FORM_BROWSER_FORMSET *FormSet,\r
261 OUT LIST_ENTRY *UefiDefaultsListHead\r
262 )\r
263{\r
264 UEFI_IFR_BUFFER_STORAGE_NODE *Node;\r
265 LIST_ENTRY *Link;\r
266 FORM_BROWSER_FORM *Form;\r
267 EFI_STATUS Status;\r
268\r
269 Node = AllocateZeroPool (sizeof (UEFI_IFR_BUFFER_STORAGE_NODE));\r
270 ASSERT (Node != NULL);\r
271\r
272 Node->Signature = UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE;\r
273 Node->Name = AllocateCopyPool (StrSize (Storage->Name), Storage->Name);\r
274 Node->DefaultId = DefaultStore->DefaultId;\r
275 Node->StoreId = Storage->VarStoreId;\r
276 CopyGuid (&Node->Guid, &Storage->Guid);\r
277 Node->Size = Storage->Size;\r
278 Node->Buffer = AllocateZeroPool (Node->Size);\r
279 //\r
280 // Extract default from IFR binary\r
281 //\r
282 Link = GetFirstNode (&FormSet->FormListHead);\r
283 while (!IsNull (&FormSet->FormListHead, Link)) {\r
284 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
285\r
286 Status = ExtractFormDefault (FormSet, Form, DefaultStore->DefaultId, Storage->VarStoreId, Node);\r
287 ASSERT_EFI_ERROR (Status);\r
288\r
289 Link = GetNextNode (&FormSet->FormListHead, Link);\r
290 }\r
291\r
292 InsertTailList (UefiDefaultsListHead, &Node->List);\r
293 \r
294 return EFI_SUCCESS;\r
295}\r
296\r
297\r
298/**\r
299 Get the default value for Buffer Type storage named by\r
300 a Default Store from a FormSet.\r
301 The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE\r
302 allocated by this function. The output can be multiple instances\r
303 of UEFI_IFR_BUFFER_STORAGE_NODE. It is inserted to the link list.\r
304 \r
305 @param DefaultStore The Default Store.\r
306 @param FormSet The Form Set.\r
307 @param UefiDefaultsListHead The head of link list for the output.\r
308\r
309 @retval EFI_SUCCESS Successful.\r
310 \r
311**/\r
312EFI_STATUS\r
313GetBufferTypeDefaultId (\r
314 IN FORMSET_DEFAULTSTORE *DefaultStore,\r
315 IN FORM_BROWSER_FORMSET *FormSet,\r
316 OUT LIST_ENTRY *UefiDefaultsListHead\r
317 )\r
318{\r
319 LIST_ENTRY *StorageLink;\r
320 FORMSET_STORAGE *Storage;\r
321 EFI_STATUS Status;\r
322\r
323 StorageLink = GetFirstNode (&FormSet->StorageListHead);\r
324\r
325 while (!IsNull (&FormSet->StorageListHead, StorageLink)) {\r
326 Storage = FORMSET_STORAGE_FROM_LINK(StorageLink);\r
327\r
328 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
329 Status = GetBufferTypeDefaultIdAndStorageId (DefaultStore, Storage, FormSet, UefiDefaultsListHead);\r
330 ASSERT_EFI_ERROR (Status);\r
331 }\r
332\r
333 StorageLink = GetNextNode (&FormSet->StorageListHead, StorageLink);\r
334 }\r
335 \r
336 return EFI_SUCCESS;\r
337}\r
338\r
339\r
340/**\r
341 Get the default value for Buffer Type storage from the first FormSet\r
342 in the Package List specified by a EFI_HII_HANDLE.\r
343 \r
344 The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE. \r
345 They are inserted to the link list.\r
346 \r
347 @param UefiHiiHandle The handle for the package list.\r
348 @param UefiDefaultsListHead The head of link list for the output.\r
349\r
350 @retval EFI_SUCCESS Successful.\r
351 \r
352**/\r
353EFI_STATUS\r
354UefiIfrGetBufferTypeDefaults (\r
355 IN HII_THUNK_CONTEXT *ThunkContext,\r
356 OUT LIST_ENTRY **UefiDefaults\r
357 )\r
358{\r
359 LIST_ENTRY *DefaultLink;\r
360 FORMSET_DEFAULTSTORE *DefaultStore;\r
361 EFI_STATUS Status;\r
362\r
363 ASSERT (UefiDefaults != NULL);\r
364\r
365 *UefiDefaults = AllocateZeroPool (sizeof (LIST_ENTRY));\r
366 ASSERT (UefiDefaults != NULL);\r
367 InitializeListHead (*UefiDefaults);\r
368\r
369 DefaultLink = GetFirstNode (&ThunkContext->FormSet->DefaultStoreListHead);\r
370 while (!IsNull (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink)) {\r
371 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
372\r
373 Status = GetBufferTypeDefaultId (DefaultStore, ThunkContext->FormSet, *UefiDefaults);\r
374 ASSERT_EFI_ERROR (Status);\r
375\r
376 DefaultLink = GetNextNode (&ThunkContext->FormSet->DefaultStoreListHead, DefaultLink); \r
377 }\r
378\r
379 return EFI_SUCCESS;\r
380}\r
381\r
382\r
383/**\r
384 Convert the UEFI Buffer Type default values to a Framework HII default\r
385 values specified by a EFI_HII_VARIABLE_PACK_LIST structure.\r
386 \r
387 @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
388 which contains the default values retrived from\r
389 a UEFI form set.\r
390 @param DefaultMask The default mask.\r
391 The valid values are EFI_IFR_FLAG_DEFAULT\r
392 and EFI_IFR_FLAG_MANUFACTURING.\r
393 UEFI spec only map EFI_IFR_FLAG_DEFAULT and EFI_IFR_FLAG_MANUFACTURING \r
394 from specification to valid default class.\r
395 @param VariablePackList The output default value in a format defined in Framework.\r
396 \r
397\r
398 @retval EFI_SUCCESS Successful.\r
399 @retval EFI_INVALID_PARAMETER The default mask is not EFI_IFR_FLAG_DEFAULT or \r
400 EFI_IFR_FLAG_MANUFACTURING.\r
401**/\r
402EFI_STATUS\r
403UefiDefaultsToFwDefaults (\r
404 IN LIST_ENTRY *ListHead,\r
405 IN UINTN DefaultMask,\r
406 IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId,\r
407 OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList\r
408 )\r
409{\r
410 LIST_ENTRY *List;\r
411 UEFI_IFR_BUFFER_STORAGE_NODE *Node;\r
412 UINTN Size;\r
413 UINTN Count;\r
414 UINT16 DefaultId;\r
415 EFI_HII_VARIABLE_PACK *Pack;\r
416 EFI_HII_VARIABLE_PACK_LIST *PackList;\r
417 UINTN Index;\r
418\r
419 if (DefaultMask == EFI_IFR_FLAG_DEFAULT) {\r
420 DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
421 } else if (DefaultMask == EFI_IFR_FLAG_MANUFACTURING) {\r
422 DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
423 } else {\r
424 //\r
425 // UEFI spec only map EFI_IFR_FLAG_DEFAULT and EFI_IFR_FLAG_MANUFACTURING \r
426 // from specification to valid default class.\r
427 //\r
428 ASSERT (FALSE);\r
429 return EFI_INVALID_PARAMETER;\r
430 }\r
431 \r
432 //\r
433 // Calculate the size of the output EFI_HII_VARIABLE_PACK_LIST structure\r
434 //\r
435 Size = 0;\r
436 Count = 0;\r
437 List = GetFirstNode (ListHead);\r
438 while (!IsNull (ListHead, List)) {\r
439 Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);\r
440\r
441 if (Node->DefaultId == DefaultId) {\r
442 Size += Node->Size;\r
443 Size += StrSize (Node->Name);\r
444\r
445 Count++;\r
446 }\r
447 \r
448 List = GetNextNode (ListHead, List); \r
449 }\r
450\r
451 if (Count == 0) {\r
452 *VariablePackList = NULL;\r
453 return EFI_NOT_FOUND;\r
454 }\r
455\r
456 Size = Size + Count * (sizeof (EFI_HII_VARIABLE_PACK_LIST) + sizeof (EFI_HII_VARIABLE_PACK));\r
457 \r
458 *VariablePackList = AllocateZeroPool (Size);\r
459 ASSERT (*VariablePackList != NULL);\r
460\r
461 List = GetFirstNode (ListHead);\r
462\r
463 PackList = (EFI_HII_VARIABLE_PACK_LIST *) *VariablePackList;\r
464 Pack = (EFI_HII_VARIABLE_PACK *) (PackList + 1);\r
465 Index = 0;\r
466 while (!IsNull (ListHead, List)) {\r
467 Node = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List);\r
468\r
469 Size = 0; \r
470 if (Node->DefaultId == DefaultId) {\r
471 Size += Node->Size;\r
472 Size += sizeof (EFI_HII_VARIABLE_PACK); \r
473\r
474 Pack->VariableNameLength = (UINT32) StrSize (Node->Name);\r
475\r
476 if (Node->StoreId == UefiFormSetDefaultVarStoreId) {\r
477 //\r
478 // The default VARSTORE in VFR from a Framework module has Varstore ID of 0.\r
479 //\r
480 Pack->VariableId = 0;\r
481 } else {\r
482 Pack->VariableId = Node->StoreId;\r
483 }\r
484\r
485 CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK), Node->Name, StrSize (Node->Name));\r
486 Size += Pack->VariableNameLength;\r
487\r
488 //\r
489 // Initialize EFI_HII_VARIABLE_PACK\r
490 //\r
491 Pack->Header.Type = 0;\r
492 Pack->Header.Length = (UINT32) Size;\r
493 CopyMem (&Pack->VariableGuid, &Node->Guid, sizeof (EFI_GUID));\r
494 \r
495 CopyMem ((UINT8 *) Pack + sizeof (EFI_HII_VARIABLE_PACK) + Pack->VariableNameLength, Node->Buffer, Node->Size);\r
496\r
497 Size += sizeof (EFI_HII_VARIABLE_PACK_LIST);\r
498\r
499 //\r
500 // Initialize EFI_HII_VARIABLE_PACK_LIST\r
501 //\r
502 PackList->VariablePack = Pack;\r
503 Index++;\r
504 if (Index < Count) {\r
505 PackList->NextVariablePack = (EFI_HII_VARIABLE_PACK_LIST *)((UINT8 *) PackList + Size);\r
506\r
507 PackList = PackList->NextVariablePack;\r
508 Pack = (EFI_HII_VARIABLE_PACK *) (PackList + 1);\r
509 }\r
510 \r
511 }\r
512 \r
513 List = GetNextNode (ListHead, List); \r
514 }\r
515 \r
516 \r
517 return EFI_SUCCESS;\r
518}\r
519\r
520\r
521/**\r
522 Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.\r
523 \r
524 @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE\r
525 which contains the default values retrived from\r
526 a UEFI form set.\r
527 \r
528\r
529 @retval VOID\r
530**/\r
531VOID\r
532FreeDefaultList (\r
533 IN LIST_ENTRY *ListHead\r
534 )\r
535{\r
536 LIST_ENTRY *Link;\r
537 UEFI_IFR_BUFFER_STORAGE_NODE *Default;\r
538\r
539 while (!IsListEmpty (ListHead)) {\r
540 Link = GetFirstNode (ListHead);\r
541 \r
542 Default = UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(Link);\r
543\r
544 RemoveEntryList (Link);\r
545 \r
546 DestroyDefaultNode (Default);\r
547 }\r
548\r
549 FreePool (ListHead);\r
550}\r
551\r