2 Function and Macro defintions for to extract default values from UEFI Form package.
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
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.
15 #include "HiiDatabase.h"
16 #include "UefiIfrParser.h"
17 #include "UefiIfrDefault.h"
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
;
28 Set the data position at Offset with Width in Node->Buffer based
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.
41 OUT UEFI_IFR_BUFFER_STORAGE_NODE
*Node
,
42 IN CONST EFI_HII_VALUE
*Value
,
47 ASSERT (Node
->Signature
== UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE
);
48 ASSERT (Offset
+ Width
<= Node
->Size
);
50 CopyMem (Node
->Buffer
+ Offset
, &Value
->Value
.u8
, Width
);
55 Reset Question to its default value.
57 Note Framework 0.92's HII Implementation does not support for default value for these opcodes:
58 EFI_IFR_ORDERED_LIST_OP:
62 @param FormSet FormSet data structure.
63 @param DefaultId The Class of the default.
65 @retval EFI_SUCCESS Question is reset to default value.
70 IN FORM_BROWSER_FORMSET
*FormSet
,
71 IN FORM_BROWSER_FORM
*Form
,
72 IN FORM_BROWSER_STATEMENT
*Question
,
75 OUT UEFI_IFR_BUFFER_STORAGE_NODE
*Node
80 QUESTION_DEFAULT
*Default
;
81 QUESTION_OPTION
*Option
;
82 EFI_HII_VALUE
*HiiValue
;
87 // Statement don't have storage, skip them
89 if (Question
->QuestionId
== 0) {
93 if (Question
->VarStoreId
!= VarStoreId
) {
97 ASSERT (Question
->Storage
->Type
== EFI_HII_VARSTORE_BUFFER
);
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)
105 HiiValue
= &Question
->HiiValue
;
108 // EFI_IFR_DEFAULT has highest priority
110 if (!IsListEmpty (&Question
->DefaultListHead
)) {
111 Link
= GetFirstNode (&Question
->DefaultListHead
);
112 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
113 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
115 if (Default
->DefaultId
== DefaultId
) {
117 // Default value is embedded in EFI_IFR_DEFAULT
119 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
121 SetNodeBuffer (Node
, HiiValue
, Question
->VarStoreInfo
.VarOffset
, Question
->StorageWidth
);
125 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
132 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
133 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
135 // OneOfOption could only provide Standard and Manufacturing default
137 Link
= GetFirstNode (&Question
->OptionListHead
);
138 while (!IsNull (&Question
->OptionListHead
, Link
)) {
139 Option
= QUESTION_OPTION_FROM_LINK (Link
);
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
))
144 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
146 SetNodeBuffer (Node
, HiiValue
, Question
->VarStoreInfo
.VarOffset
, Question
->StorageWidth
);
150 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
156 // EFI_IFR_CHECKBOX - lowest priority
158 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
159 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
161 // Checkbox could only provide Standard and Manufacturing default
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
))
166 HiiValue
->Value
.b
= TRUE
;
168 HiiValue
->Value
.b
= FALSE
;
171 SetNodeBuffer (Node
, HiiValue
, Question
->VarStoreInfo
.VarOffset
, Question
->StorageWidth
);
181 Reset Questions in a Form to their default value.
183 @param FormSet FormSet data structure.
184 @param Form The Form which to be reset.
185 @param DefaultId The Class of the default.
187 @retval EFI_SUCCESS The function completed successfully.
192 IN FORM_BROWSER_FORMSET
*FormSet
,
193 IN FORM_BROWSER_FORM
*Form
,
195 IN UINT16 VarStoreId
,
196 OUT UEFI_IFR_BUFFER_STORAGE_NODE
*Node
201 FORM_BROWSER_STATEMENT
*Question
;
203 Link
= GetFirstNode (&Form
->StatementListHead
);
204 while (!IsNull (&Form
->StatementListHead
, Link
)) {
205 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
207 // Reset Question to its default value
209 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
, VarStoreId
, Node
);
210 if (EFI_ERROR (Status
)) {
214 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
221 Destroy all the buffer allocated for the fileds of
222 UEFI_IFR_BUFFER_STORAGE_NODE. The Node itself
225 @param FormSet FormSet data structure.
226 @param DefaultId The Class of the default.
233 IN UEFI_IFR_BUFFER_STORAGE_NODE
*Node
236 FreePool (Node
->Buffer
);
237 FreePool (Node
->Name
);
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.
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.
253 @retval EFI_SUCCESS Successful.
257 GetBufferTypeDefaultIdAndStorageId (
258 IN FORMSET_DEFAULTSTORE
*DefaultStore
,
259 IN FORMSET_STORAGE
*Storage
,
260 IN FORM_BROWSER_FORMSET
*FormSet
,
261 OUT LIST_ENTRY
*UefiDefaultsListHead
264 UEFI_IFR_BUFFER_STORAGE_NODE
*Node
;
266 FORM_BROWSER_FORM
*Form
;
269 Node
= AllocateZeroPool (sizeof (UEFI_IFR_BUFFER_STORAGE_NODE
));
270 ASSERT (Node
!= NULL
);
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
);
280 // Extract default from IFR binary
282 Link
= GetFirstNode (&FormSet
->FormListHead
);
283 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
284 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
286 Status
= ExtractFormDefault (FormSet
, Form
, DefaultStore
->DefaultId
, Storage
->VarStoreId
, Node
);
287 ASSERT_EFI_ERROR (Status
);
289 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
292 InsertTailList (UefiDefaultsListHead
, &Node
->List
);
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.
305 @param DefaultStore The Default Store.
306 @param FormSet The Form Set.
307 @param UefiDefaultsListHead The head of link list for the output.
309 @retval EFI_SUCCESS Successful.
313 GetBufferTypeDefaultId (
314 IN FORMSET_DEFAULTSTORE
*DefaultStore
,
315 IN FORM_BROWSER_FORMSET
*FormSet
,
316 OUT LIST_ENTRY
*UefiDefaultsListHead
319 LIST_ENTRY
*StorageLink
;
320 FORMSET_STORAGE
*Storage
;
323 StorageLink
= GetFirstNode (&FormSet
->StorageListHead
);
325 while (!IsNull (&FormSet
->StorageListHead
, StorageLink
)) {
326 Storage
= FORMSET_STORAGE_FROM_LINK(StorageLink
);
328 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
329 Status
= GetBufferTypeDefaultIdAndStorageId (DefaultStore
, Storage
, FormSet
, UefiDefaultsListHead
);
330 ASSERT_EFI_ERROR (Status
);
333 StorageLink
= GetNextNode (&FormSet
->StorageListHead
, StorageLink
);
341 Get the default value for Buffer Type storage from the first FormSet
342 in the Package List specified by a EFI_HII_HANDLE.
344 The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE.
345 They are inserted to the link list.
347 @param UefiHiiHandle The handle for the package list.
348 @param UefiDefaultsListHead The head of link list for the output.
350 @retval EFI_SUCCESS Successful.
354 UefiIfrGetBufferTypeDefaults (
355 IN HII_THUNK_CONTEXT
*ThunkContext
,
356 OUT LIST_ENTRY
**UefiDefaults
359 LIST_ENTRY
*DefaultLink
;
360 FORMSET_DEFAULTSTORE
*DefaultStore
;
363 ASSERT (UefiDefaults
!= NULL
);
365 *UefiDefaults
= AllocateZeroPool (sizeof (LIST_ENTRY
));
366 ASSERT (UefiDefaults
!= NULL
);
367 InitializeListHead (*UefiDefaults
);
369 DefaultLink
= GetFirstNode (&ThunkContext
->FormSet
->DefaultStoreListHead
);
370 while (!IsNull (&ThunkContext
->FormSet
->DefaultStoreListHead
, DefaultLink
)) {
371 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink
);
373 Status
= GetBufferTypeDefaultId (DefaultStore
, ThunkContext
->FormSet
, *UefiDefaults
);
374 ASSERT_EFI_ERROR (Status
);
376 DefaultLink
= GetNextNode (&ThunkContext
->FormSet
->DefaultStoreListHead
, DefaultLink
);
384 Convert the UEFI Buffer Type default values to a Framework HII default
385 values specified by a EFI_HII_VARIABLE_PACK_LIST structure.
387 @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE
388 which contains the default values retrived from
390 @param DefaultMask The default mask.
391 The valid values are FRAMEWORK_EFI_IFR_FLAG_DEFAULT
392 and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.
393 UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
394 from specification to valid default class.
395 @param VariablePackList The output default value in a format defined in Framework.
398 @retval EFI_SUCCESS Successful.
399 @retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or
400 FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.
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
411 UEFI_IFR_BUFFER_STORAGE_NODE
*Node
;
415 EFI_HII_VARIABLE_PACK
*Pack
;
416 EFI_HII_VARIABLE_PACK_LIST
*PackList
;
419 if (DefaultMask
== FRAMEWORK_EFI_IFR_FLAG_DEFAULT
) {
420 DefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
421 } else if (DefaultMask
== FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
) {
422 DefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
425 // UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
426 // from specification to valid default class.
429 return EFI_INVALID_PARAMETER
;
433 // Calculate the size of the output EFI_HII_VARIABLE_PACK_LIST structure
437 List
= GetFirstNode (ListHead
);
438 while (!IsNull (ListHead
, List
)) {
439 Node
= UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List
);
441 if (Node
->DefaultId
== DefaultId
) {
443 Size
+= StrSize (Node
->Name
);
448 List
= GetNextNode (ListHead
, List
);
452 *VariablePackList
= NULL
;
453 return EFI_NOT_FOUND
;
456 Size
= Size
+ Count
* (sizeof (EFI_HII_VARIABLE_PACK_LIST
) + sizeof (EFI_HII_VARIABLE_PACK
));
458 *VariablePackList
= AllocateZeroPool (Size
);
459 ASSERT (*VariablePackList
!= NULL
);
461 List
= GetFirstNode (ListHead
);
463 PackList
= (EFI_HII_VARIABLE_PACK_LIST
*) *VariablePackList
;
464 Pack
= (EFI_HII_VARIABLE_PACK
*) (PackList
+ 1);
466 while (!IsNull (ListHead
, List
)) {
467 Node
= UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List
);
470 if (Node
->DefaultId
== DefaultId
) {
472 Size
+= sizeof (EFI_HII_VARIABLE_PACK
);
474 Pack
->VariableNameLength
= (UINT32
) StrSize (Node
->Name
);
476 if (Node
->StoreId
== UefiFormSetDefaultVarStoreId
) {
478 // The default VARSTORE in VFR from a Framework module has Varstore ID of 0.
480 Pack
->VariableId
= 0;
482 Pack
->VariableId
= Node
->StoreId
;
485 CopyMem ((UINT8
*) Pack
+ sizeof (EFI_HII_VARIABLE_PACK
), Node
->Name
, StrSize (Node
->Name
));
486 Size
+= Pack
->VariableNameLength
;
489 // Initialize EFI_HII_VARIABLE_PACK
491 Pack
->Header
.Type
= 0;
492 Pack
->Header
.Length
= (UINT32
) Size
;
493 CopyMem (&Pack
->VariableGuid
, &Node
->Guid
, sizeof (EFI_GUID
));
495 CopyMem ((UINT8
*) Pack
+ sizeof (EFI_HII_VARIABLE_PACK
) + Pack
->VariableNameLength
, Node
->Buffer
, Node
->Size
);
497 Size
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
500 // Initialize EFI_HII_VARIABLE_PACK_LIST
502 PackList
->VariablePack
= Pack
;
505 PackList
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*)((UINT8
*) PackList
+ Size
);
507 PackList
= PackList
->NextVariablePack
;
508 Pack
= (EFI_HII_VARIABLE_PACK
*) (PackList
+ 1);
513 List
= GetNextNode (ListHead
, List
);
522 Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.
524 @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE
525 which contains the default values retrived from
533 IN LIST_ENTRY
*ListHead
537 UEFI_IFR_BUFFER_STORAGE_NODE
*Default
;
539 while (!IsListEmpty (ListHead
)) {
540 Link
= GetFirstNode (ListHead
);
542 Default
= UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(Link
);
544 RemoveEntryList (Link
);
546 DestroyDefaultNode (Default
);