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.
16 #include <FrameworkDxe.h>
18 #include <Protocol/FrameworkHii.h>
19 #include <Protocol/HiiDatabase.h>
21 #include <Library/BaseLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/MemoryAllocationLib.h>
25 #include <Library/UefiBootServicesTableLib.h>
27 #include "HiiDatabase.h"
28 #include "UefiIfrParser.h"
29 #include "UefiIfrDefault.h"
34 extern CONST EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
35 extern CONST EFI_HII_IMAGE_PROTOCOL
*mHiiImageProtocol
;
36 extern CONST EFI_HII_STRING_PROTOCOL
*mHiiStringProtocol
;
37 extern CONST EFI_HII_CONFIG_ROUTING_PROTOCOL
*mHiiConfigRoutingProtocol
;
40 Set the data position at Offset with Width in Node->Buffer based
43 @param Node The Buffer Storage Node.
44 @param Value The input value.
45 @param Offset The offset in Node->Buffer for the update.
46 @param Width The length of the Value.
53 OUT UEFI_IFR_BUFFER_STORAGE_NODE
*Node
,
54 IN CONST EFI_HII_VALUE
*Value
,
59 ASSERT (Node
->Signature
== UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE
);
60 ASSERT (Offset
+ Width
<= Node
->Size
);
62 CopyMem (Node
->Buffer
+ Offset
, &Value
->Value
.u8
, Width
);
67 Reset Question to its default value.
69 Note Framework 0.92's HII Implementation does not support for default value for these opcodes:
70 EFI_IFR_ORDERED_LIST_OP:
74 @param FormSet FormSet data structure.
75 @param DefaultId The Class of the default.
77 @retval EFI_SUCCESS Question is reset to default value.
82 IN FORM_BROWSER_FORMSET
*FormSet
,
83 IN FORM_BROWSER_FORM
*Form
,
84 IN FORM_BROWSER_STATEMENT
*Question
,
87 OUT UEFI_IFR_BUFFER_STORAGE_NODE
*Node
92 QUESTION_DEFAULT
*Default
;
93 QUESTION_OPTION
*Option
;
94 EFI_HII_VALUE
*HiiValue
;
99 // Statement don't have storage, skip them
101 if (Question
->QuestionId
== 0) {
105 if (Question
->VarStoreId
!= VarStoreId
) {
109 ASSERT (Question
->Storage
->Type
== EFI_HII_VARSTORE_BUFFER
);
112 // There are three ways to specify default value for a Question:
113 // 1, use nested EFI_IFR_DEFAULT (highest priority)
114 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
115 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
117 HiiValue
= &Question
->HiiValue
;
120 // EFI_IFR_DEFAULT has highest priority
122 if (!IsListEmpty (&Question
->DefaultListHead
)) {
123 Link
= GetFirstNode (&Question
->DefaultListHead
);
124 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
125 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
127 if (Default
->DefaultId
== DefaultId
) {
129 // Default value is embedded in EFI_IFR_DEFAULT
131 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
133 SetNodeBuffer (Node
, HiiValue
, Question
->VarStoreInfo
.VarOffset
, Question
->StorageWidth
);
137 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
144 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
145 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
147 // OneOfOption could only provide Standard and Manufacturing default
149 Link
= GetFirstNode (&Question
->OptionListHead
);
150 while (!IsNull (&Question
->OptionListHead
, Link
)) {
151 Option
= QUESTION_OPTION_FROM_LINK (Link
);
153 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && (Option
->Flags
& EFI_IFR_OPTION_DEFAULT
)) ||
154 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && (Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
))
156 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
158 SetNodeBuffer (Node
, HiiValue
, Question
->VarStoreInfo
.VarOffset
, Question
->StorageWidth
);
162 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
168 // EFI_IFR_CHECKBOX - lowest priority
170 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
171 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
173 // Checkbox could only provide Standard and Manufacturing default
175 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && (Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
)) ||
176 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && (Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
))
178 HiiValue
->Value
.b
= TRUE
;
180 HiiValue
->Value
.b
= FALSE
;
183 SetNodeBuffer (Node
, HiiValue
, Question
->VarStoreInfo
.VarOffset
, Question
->StorageWidth
);
193 Reset Questions in a Form to their default value.
195 @param FormSet FormSet data structure.
196 @param Form The Form which to be reset.
197 @param DefaultId The Class of the default.
199 @retval EFI_SUCCESS The function completed successfully.
204 IN FORM_BROWSER_FORMSET
*FormSet
,
205 IN FORM_BROWSER_FORM
*Form
,
207 IN UINT16 VarStoreId
,
208 OUT UEFI_IFR_BUFFER_STORAGE_NODE
*Node
213 FORM_BROWSER_STATEMENT
*Question
;
215 Link
= GetFirstNode (&Form
->StatementListHead
);
216 while (!IsNull (&Form
->StatementListHead
, Link
)) {
217 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
219 // Reset Question to its default value
221 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
, VarStoreId
, Node
);
222 if (EFI_ERROR (Status
)) {
226 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
233 Destroy all the buffer allocated for the fileds of
234 UEFI_IFR_BUFFER_STORAGE_NODE. The Node itself
237 @param FormSet FormSet data structure.
238 @param DefaultId The Class of the default.
245 IN UEFI_IFR_BUFFER_STORAGE_NODE
*Node
248 FreePool (Node
->Buffer
);
249 FreePool (Node
->Name
);
255 Get the default value for Buffer Type storage named by
256 a Default Store and a Storage Store from a FormSet.
257 The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE
258 allocated by this function. It is inserted to the link list.
260 @param DefaultStore The Default Store.
261 @param Storage The Storage.
262 @param FormSet The Form Set.
263 @param UefiDefaultsListHead The head of link list for the output.
265 @retval EFI_SUCCESS Successful.
269 GetBufferTypeDefaultIdAndStorageId (
270 IN FORMSET_DEFAULTSTORE
*DefaultStore
,
271 IN FORMSET_STORAGE
*Storage
,
272 IN FORM_BROWSER_FORMSET
*FormSet
,
273 OUT LIST_ENTRY
*UefiDefaultsListHead
276 UEFI_IFR_BUFFER_STORAGE_NODE
*Node
;
278 FORM_BROWSER_FORM
*Form
;
281 Node
= AllocateZeroPool (sizeof (UEFI_IFR_BUFFER_STORAGE_NODE
));
282 ASSERT (Node
!= NULL
);
284 Node
->Signature
= UEFI_IFR_BUFFER_STORAGE_NODE_SIGNATURE
;
285 Node
->Name
= AllocateCopyPool (StrSize (Storage
->Name
), Storage
->Name
);
286 Node
->DefaultId
= DefaultStore
->DefaultId
;
287 Node
->StoreId
= Storage
->VarStoreId
;
288 CopyGuid (&Node
->Guid
, &Storage
->Guid
);
289 Node
->Size
= Storage
->Size
;
290 Node
->Buffer
= AllocateZeroPool (Node
->Size
);
292 // Extract default from IFR binary
294 Link
= GetFirstNode (&FormSet
->FormListHead
);
295 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
296 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
298 Status
= ExtractFormDefault (FormSet
, Form
, DefaultStore
->DefaultId
, Storage
->VarStoreId
, Node
);
299 ASSERT_EFI_ERROR (Status
);
301 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
304 InsertTailList (UefiDefaultsListHead
, &Node
->List
);
311 Get the default value for Buffer Type storage named by
312 a Default Store from a FormSet.
313 The result is in the a instance of UEFI_IFR_BUFFER_STORAGE_NODE
314 allocated by this function. The output can be multiple instances
315 of UEFI_IFR_BUFFER_STORAGE_NODE. It is inserted to the link list.
317 @param DefaultStore The Default Store.
318 @param FormSet The Form Set.
319 @param UefiDefaultsListHead The head of link list for the output.
321 @retval EFI_SUCCESS Successful.
325 GetBufferTypeDefaultId (
326 IN FORMSET_DEFAULTSTORE
*DefaultStore
,
327 IN FORM_BROWSER_FORMSET
*FormSet
,
328 OUT LIST_ENTRY
*UefiDefaultsListHead
331 LIST_ENTRY
*StorageLink
;
332 FORMSET_STORAGE
*Storage
;
335 StorageLink
= GetFirstNode (&FormSet
->StorageListHead
);
337 while (!IsNull (&FormSet
->StorageListHead
, StorageLink
)) {
338 Storage
= FORMSET_STORAGE_FROM_LINK(StorageLink
);
340 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
341 Status
= GetBufferTypeDefaultIdAndStorageId (DefaultStore
, Storage
, FormSet
, UefiDefaultsListHead
);
342 ASSERT_EFI_ERROR (Status
);
345 StorageLink
= GetNextNode (&FormSet
->StorageListHead
, StorageLink
);
353 Get the default value for Buffer Type storage from the first FormSet
354 in the Package List specified by a EFI_HII_HANDLE.
356 The results can be multiple instances of UEFI_IFR_BUFFER_STORAGE_NODE.
357 They are inserted to the link list.
359 @param UefiHiiHandle The handle for the package list.
360 @param UefiDefaultsListHead The head of link list for the output.
362 @retval EFI_SUCCESS Successful.
366 UefiIfrGetBufferTypeDefaults (
367 IN HII_THUNK_CONTEXT
*ThunkContext
,
368 OUT LIST_ENTRY
**UefiDefaults
371 LIST_ENTRY
*DefaultLink
;
372 FORMSET_DEFAULTSTORE
*DefaultStore
;
375 ASSERT (UefiDefaults
!= NULL
);
377 *UefiDefaults
= AllocateZeroPool (sizeof (LIST_ENTRY
));
378 ASSERT (UefiDefaults
!= NULL
);
379 InitializeListHead (*UefiDefaults
);
381 DefaultLink
= GetFirstNode (&ThunkContext
->FormSet
->DefaultStoreListHead
);
382 while (!IsNull (&ThunkContext
->FormSet
->DefaultStoreListHead
, DefaultLink
)) {
383 DefaultStore
= FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink
);
385 Status
= GetBufferTypeDefaultId (DefaultStore
, ThunkContext
->FormSet
, *UefiDefaults
);
386 ASSERT_EFI_ERROR (Status
);
388 DefaultLink
= GetNextNode (&ThunkContext
->FormSet
->DefaultStoreListHead
, DefaultLink
);
396 Convert the UEFI Buffer Type default values to a Framework HII default
397 values specified by a EFI_HII_VARIABLE_PACK_LIST structure.
399 @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE
400 which contains the default values retrived from
402 @param DefaultMask The default mask.
403 The valid values are FRAMEWORK_EFI_IFR_FLAG_DEFAULT
404 and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.
405 UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
406 from specification to valid default class.
407 @param VariablePackList The output default value in a format defined in Framework.
410 @retval EFI_SUCCESS Successful.
411 @retval EFI_INVALID_PARAMETER The default mask is not FRAMEWORK_EFI_IFR_FLAG_DEFAULT or
412 FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING.
415 UefiDefaultsToFwDefaults (
416 IN LIST_ENTRY
*ListHead
,
417 IN UINTN DefaultMask
,
418 IN EFI_VARSTORE_ID UefiFormSetDefaultVarStoreId
,
419 OUT EFI_HII_VARIABLE_PACK_LIST
**VariablePackList
423 UEFI_IFR_BUFFER_STORAGE_NODE
*Node
;
427 EFI_HII_VARIABLE_PACK
*Pack
;
428 EFI_HII_VARIABLE_PACK_LIST
*PackList
;
431 if (DefaultMask
== FRAMEWORK_EFI_IFR_FLAG_DEFAULT
) {
432 DefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
433 } else if (DefaultMask
== FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
) {
434 DefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
437 // UEFI spec only map FRAMEWORK_EFI_IFR_FLAG_DEFAULT and FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
438 // from specification to valid default class.
441 return EFI_INVALID_PARAMETER
;
445 // Calculate the size of the output EFI_HII_VARIABLE_PACK_LIST structure
449 List
= GetFirstNode (ListHead
);
450 while (!IsNull (ListHead
, List
)) {
451 Node
= UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List
);
453 if (Node
->DefaultId
== DefaultId
) {
455 Size
+= StrSize (Node
->Name
);
460 List
= GetNextNode (ListHead
, List
);
464 *VariablePackList
= NULL
;
465 return EFI_NOT_FOUND
;
468 Size
= Size
+ Count
* (sizeof (EFI_HII_VARIABLE_PACK_LIST
) + sizeof (EFI_HII_VARIABLE_PACK
));
470 *VariablePackList
= AllocateZeroPool (Size
);
471 ASSERT (*VariablePackList
!= NULL
);
473 List
= GetFirstNode (ListHead
);
475 PackList
= (EFI_HII_VARIABLE_PACK_LIST
*) *VariablePackList
;
476 Pack
= (EFI_HII_VARIABLE_PACK
*) (PackList
+ 1);
478 while (!IsNull (ListHead
, List
)) {
479 Node
= UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(List
);
482 if (Node
->DefaultId
== DefaultId
) {
484 Size
+= StrSize (Node
->Name
);
485 Size
+= sizeof (EFI_HII_VARIABLE_PACK
);
488 // In UEFI, 0 is defined to be invalid for EFI_IFR_VARSTORE.VarStoreId.
489 // So the default storage of Var Store in VFR from a Framework module
490 // should be translated to the default Varstore ID.
492 if (Node
->StoreId
== UefiFormSetDefaultVarStoreId
) {
493 Pack
->VariableId
= 0;
495 Pack
->VariableId
= Node
->StoreId
;
498 // Initialize EFI_HII_VARIABLE_PACK
500 Pack
->Header
.Type
= 0;
501 Pack
->Header
.Length
= (UINT32
) Size
;
502 Pack
->VariableNameLength
= (UINT32
) StrSize (Node
->Name
);
503 CopyMem (&Pack
->VariableGuid
, &Node
->Guid
, sizeof (EFI_GUID
));
505 CopyMem ((UINT8
*) Pack
+ sizeof (EFI_HII_VARIABLE_PACK
), Node
->Name
, StrSize (Node
->Name
));
506 CopyMem ((UINT8
*) Pack
+ sizeof (EFI_HII_VARIABLE_PACK
) + Pack
->VariableNameLength
, Node
->Buffer
, Node
->Size
);
508 Size
+= sizeof (EFI_HII_VARIABLE_PACK_LIST
);
511 // Initialize EFI_HII_VARIABLE_PACK_LIST
513 PackList
->VariablePack
= Pack
;
516 PackList
->NextVariablePack
= (EFI_HII_VARIABLE_PACK_LIST
*)((UINT8
*) PackList
+ Size
);
521 List
= GetNextNode (ListHead
, List
);
530 Free up all buffer allocated for the link list of UEFI_IFR_BUFFER_STORAGE_NODE.
532 @param ListHead The link list of UEFI_IFR_BUFFER_STORAGE_NODE
533 which contains the default values retrived from
541 IN LIST_ENTRY
*ListHead
545 UEFI_IFR_BUFFER_STORAGE_NODE
*Default
;
547 while (!IsListEmpty (ListHead
)) {
548 Link
= GetFirstNode (ListHead
);
550 Default
= UEFI_IFR_BUFFER_STORAGE_NODE_FROM_LIST(Link
);
552 RemoveEntryList (Link
);
554 DestroyDefaultNode (Default
);