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