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