2 Library Routines to create IFR on-the-fly
4 Copyright (c) 2006, 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 "IfrSupportLibInternal.h"
20 The form package is a collection of forms that are intended to describe the pages that will be
21 displayed to the user.
23 @param FormSetTitle Title of formset
24 @param Guid Guid of formset
25 @param Class Class of formset
26 @param SubClass Sub class of formset
27 @param FormBuffer Pointer of the formset created
28 @param StringBuffer Pointer of FormSetTitile string created
30 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
31 @retval EFI_SUCCESS Formset successfully created
35 IN CHAR16
*FormSetTitle
,
39 IN OUT VOID
**FormBuffer
,
40 IN OUT VOID
**StringBuffer
44 EFI_HII_IFR_PACK IfrPack
;
45 FRAMEWORK_EFI_IFR_FORM_SET FormSet
;
46 FRAMEWORK_EFI_IFR_END_FORM_SET EndFormSet
;
48 CHAR16 CurrentLanguage
[4];
49 STRING_REF StringToken
;
52 // Pre-allocate a buffer sufficient for us to work from.
54 FormBuffer
= AllocateZeroPool (DEFAULT_FORM_BUFFER_SIZE
);
55 if (FormBuffer
== NULL
) {
56 return EFI_OUT_OF_RESOURCES
;
60 // Pre-allocate a buffer sufficient for us to work from.
62 StringBuffer
= AllocateZeroPool (DEFAULT_STRING_BUFFER_SIZE
);
63 if (StringBuffer
== NULL
) {
64 gBS
->FreePool (FormBuffer
);
65 return EFI_OUT_OF_RESOURCES
;
69 // Obtain current language value
71 GetCurrentLanguage (CurrentLanguage
);
74 // Add the FormSetTitle to the string buffer and get the StringToken
76 Status
= AddString (*StringBuffer
, CurrentLanguage
, FormSetTitle
, &StringToken
);
78 if (EFI_ERROR (Status
)) {
83 // Initialize the Ifr Package header data
85 IfrPack
.Header
.Length
= sizeof (EFI_HII_PACK_HEADER
) + sizeof (FRAMEWORK_EFI_IFR_FORM_SET
) + sizeof (FRAMEWORK_EFI_IFR_END_FORM_SET
);
86 IfrPack
.Header
.Type
= EFI_HII_IFR
;
89 // Initialize FormSet with the appropriate information
91 FormSet
.Header
.OpCode
= FRAMEWORK_EFI_IFR_FORM_SET_OP
;
92 FormSet
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_FORM_SET
);
93 FormSet
.FormSetTitle
= StringToken
;
94 FormSet
.Class
= Class
;
95 FormSet
.SubClass
= SubClass
;
96 CopyMem (&FormSet
.Guid
, Guid
, sizeof (EFI_GUID
));
99 // Initialize the end formset data
101 EndFormSet
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_END_FORM_SET
);
102 EndFormSet
.Header
.OpCode
= FRAMEWORK_EFI_IFR_END_FORM_SET_OP
;
104 Destination
= (UINT8
*) *FormBuffer
;
107 // Copy the formset/endformset data to the form buffer
109 CopyMem (Destination
, &IfrPack
, sizeof (EFI_HII_PACK_HEADER
));
111 Destination
= Destination
+ sizeof (EFI_HII_PACK_HEADER
);
113 CopyMem (Destination
, &FormSet
, sizeof (FRAMEWORK_EFI_IFR_FORM_SET
));
115 Destination
= Destination
+ sizeof (FRAMEWORK_EFI_IFR_FORM_SET
);
117 CopyMem (Destination
, &EndFormSet
, sizeof (FRAMEWORK_EFI_IFR_END_FORM_SET
));
123 A form is the encapsulation of what amounts to a browser page. The header defines a FormId,
124 which is referenced by the form package, among others. It also defines a FormTitle, which is a
125 string to be used as the title for the form
127 @param FormTitle Title of the form
128 @param FormId Id of the form
129 @param FormBuffer Pointer of the form created
130 @param StringBuffer Pointer of FormTitil string created
132 @retval EFI_SUCCESS Form successfully created
136 IN CHAR16
*FormTitle
,
138 IN OUT VOID
*FormBuffer
,
139 IN OUT VOID
*StringBuffer
143 FRAMEWORK_EFI_IFR_FORM Form
;
144 FRAMEWORK_EFI_IFR_END_FORM EndForm
;
145 CHAR16 CurrentLanguage
[4];
146 STRING_REF StringToken
;
149 // Obtain current language value
151 GetCurrentLanguage (CurrentLanguage
);
153 Status
= AddString (StringBuffer
, CurrentLanguage
, FormTitle
, &StringToken
);
155 if (EFI_ERROR (Status
)) {
159 Form
.Header
.OpCode
= FRAMEWORK_EFI_IFR_FORM_OP
;
160 Form
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_FORM
);
161 Form
.FormId
= FormId
;
162 Form
.FormTitle
= StringToken
;
164 Status
= AddOpCode (FormBuffer
, &Form
);
166 if (EFI_ERROR (Status
)) {
170 EndForm
.Header
.OpCode
= FRAMEWORK_EFI_IFR_END_FORM_OP
;
171 EndForm
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_END_FORM
);
173 Status
= AddOpCode (FormBuffer
, &EndForm
);
181 Subtitle strings are intended to be used by authors to separate sections of questions into semantic
184 @param SubTitle Sub title to be created
185 @param FormBuffer Where this subtitle to add to
186 @param StringBuffer String buffer created for subtitle
188 @retval EFI_SUCCESS Subtitle successfully created
193 IN OUT VOID
*FormBuffer
,
194 IN OUT VOID
*StringBuffer
198 FRAMEWORK_EFI_IFR_SUBTITLE Subtitle
;
199 CHAR16 CurrentLanguage
[4];
200 STRING_REF StringToken
;
203 // Obtain current language value
205 GetCurrentLanguage (CurrentLanguage
);
207 Status
= AddString (StringBuffer
, CurrentLanguage
, SubTitle
, &StringToken
);
209 if (EFI_ERROR (Status
)) {
213 Subtitle
.Header
.OpCode
= FRAMEWORK_EFI_IFR_SUBTITLE_OP
;
214 Subtitle
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_SUBTITLE
);
215 Subtitle
.SubTitle
= StringToken
;
217 Status
= AddOpCode (FormBuffer
, &Subtitle
);
223 Create a line of text
224 Unlike HTML, text is simply another tag.
225 This tag type enables IFR to be more easily localized.
227 @param String - First string of the text
228 @param String2 - Second string of the text
229 @param String3 - Help string of the text
230 @param Flags - Flag of the text
231 @param Key - Key of the text
232 @param FormBuffer - The form where this text adds to
233 @param StringBuffer - String buffer created for String, String2 and String3
235 @retval EFI_SUCCESS - Text successfully created
244 IN OUT VOID
*FormBuffer
,
245 IN OUT VOID
*StringBuffer
249 FRAMEWORK_EFI_IFR_TEXT Text
;
250 CHAR16 CurrentLanguage
[4];
251 STRING_REF StringToken
;
254 // Obtain current language value
256 GetCurrentLanguage (CurrentLanguage
);
259 // Add first string, get first string's token
261 Status
= AddString (StringBuffer
, CurrentLanguage
, String
, &StringToken
);
263 if (EFI_ERROR (Status
)) {
267 Text
.Header
.OpCode
= FRAMEWORK_EFI_IFR_TEXT_OP
;
268 Text
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_TEXT
);
269 Text
.Text
= StringToken
;
272 // Add second string, get first string's token
274 Status
= AddString (StringBuffer
, CurrentLanguage
, String2
, &StringToken
);
276 if (EFI_ERROR (Status
)) {
280 Text
.TextTwo
= StringToken
;
282 Text
.Flags
= (UINT8
) (Flags
| FRAMEWORK_EFI_IFR_FLAG_CREATED
);
286 // Add second string, get first string's token
288 Status
= AddString (StringBuffer
, CurrentLanguage
, String3
, &StringToken
);
290 if (EFI_ERROR (Status
)) {
294 Text
.Help
= StringToken
;
296 Status
= AddOpCode (FormBuffer
, &Text
);
304 @param FormId Form ID of the hyperlink
305 @param Prompt Prompt of the hyperlink
306 @param FormBuffer The form where this hyperlink adds to
307 @param StringBuffer String buffer created for Prompt
309 @retval EFI_SUCCESS Hyperlink successfully created
315 IN OUT VOID
*FormBuffer
,
316 IN OUT VOID
*StringBuffer
320 FRAMEWORK_EFI_IFR_REF Hyperlink
;
321 CHAR16 CurrentLanguage
[4];
322 STRING_REF StringToken
;
325 // Obtain current language value
327 GetCurrentLanguage (CurrentLanguage
);
329 Status
= AddString (StringBuffer
, CurrentLanguage
, Prompt
, &StringToken
);
331 if (EFI_ERROR (Status
)) {
335 Hyperlink
.Header
.OpCode
= FRAMEWORK_EFI_IFR_REF_OP
;
336 Hyperlink
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_REF
);
337 Hyperlink
.FormId
= FormId
;
338 Hyperlink
.Prompt
= StringToken
;
340 Status
= AddOpCode (FormBuffer
, &Hyperlink
);
346 Create a one-of question with a set of options to choose from. The
347 OptionsList is a pointer to a null-terminated list of option descriptions.
349 @param QuestionId - Question ID of the one-of box
350 @param DataWidth - DataWidth of the one-of box
351 @param Prompt - Prompt of the one-of box
352 @param Help - Help of the one-of box
353 @param OptionsList - Each string in it is an option of the one-of box
354 @param OptionCount - Option string count
355 @param FormBuffer - The form where this one-of box adds to
356 @param StringBuffer - String buffer created for Prompt, Help and Option strings
358 @retval EFI_DEVICE_ERROR - DataWidth > 2
359 @retval EFI_SUCCESS - One-Of box successfully created.
363 IN UINT16 QuestionId
,
367 IN IFR_OPTION
*OptionsList
,
368 IN UINTN OptionCount
,
369 IN OUT VOID
*FormBuffer
,
370 IN OUT VOID
*StringBuffer
375 FRAMEWORK_EFI_IFR_ONE_OF OneOf
;
376 FRAMEWORK_EFI_IFR_ONE_OF_OPTION OneOfOption
;
377 FRAMEWORK_EFI_IFR_END_ONE_OF EndOneOf
;
378 CHAR16 CurrentLanguage
[4];
379 STRING_REF StringToken
;
382 // We do not create op-code storage widths for one-of in excess of 16 bits for now
385 return EFI_DEVICE_ERROR
;
389 // Obtain current language value
391 GetCurrentLanguage (CurrentLanguage
);
394 // Add first string, get first string's token
396 Status
= AddString (StringBuffer
, CurrentLanguage
, Prompt
, &StringToken
);
398 if (EFI_ERROR (Status
)) {
402 OneOf
.Header
.OpCode
= FRAMEWORK_EFI_IFR_ONE_OF_OP
;
403 OneOf
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_ONE_OF
);
404 OneOf
.QuestionId
= QuestionId
;
405 OneOf
.Width
= DataWidth
;
406 OneOf
.Prompt
= StringToken
;
409 // Add second string, get first string's token
411 Status
= AddString (StringBuffer
, CurrentLanguage
, Help
, &StringToken
);
413 if (EFI_ERROR (Status
)) {
417 OneOf
.Help
= StringToken
;
419 Status
= AddOpCode (FormBuffer
, &OneOf
);
421 if (EFI_ERROR (Status
)) {
425 for (Index
= 0; Index
< OptionCount
; Index
++) {
426 OneOfOption
.Header
.OpCode
= FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
;
427 OneOfOption
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
);
430 // Add string and get token back
432 Status
= AddString (StringBuffer
, CurrentLanguage
, OptionsList
[Index
].OptionString
, &StringToken
);
434 OneOfOption
.Option
= StringToken
;
435 OneOfOption
.Value
= OptionsList
[Index
].Value
;
436 OneOfOption
.Flags
= (UINT8
) (OptionsList
[Index
].Flags
| FRAMEWORK_EFI_IFR_FLAG_CREATED
);
437 OneOfOption
.Key
= OptionsList
[Index
].Key
;
439 Status
= AddOpCode (FormBuffer
, &OneOfOption
);
441 if (EFI_ERROR (Status
)) {
446 EndOneOf
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_END_ONE_OF
);
447 EndOneOf
.Header
.OpCode
= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
;
449 Status
= AddOpCode (FormBuffer
, &EndOneOf
);
451 if (EFI_ERROR (Status
)) {
459 Create a one-of question with a set of options to choose from. The
460 OptionsList is a pointer to a null-terminated list of option descriptions.
462 @param QuestionId - Question ID of the ordered list
463 @param MaxEntries - MaxEntries of the ordered list
464 @param Prompt - Prompt of the ordered list
465 @param Help - Help of the ordered list
466 @param OptionsList - Each string in it is an option of the ordered list
467 @param OptionCount - Option string count
468 @param FormBuffer - The form where this ordered list adds to
469 @param StringBuffer - String buffer created for Prompt, Help and Option strings
471 @retval EFI_SUCCESS - Ordered list successfully created.
475 IN UINT16 QuestionId
,
479 IN IFR_OPTION
*OptionsList
,
480 IN UINTN OptionCount
,
481 IN OUT VOID
*FormBuffer
,
482 IN OUT VOID
*StringBuffer
487 FRAMEWORK_EFI_IFR_ORDERED_LIST OrderedList
;
488 FRAMEWORK_EFI_IFR_ONE_OF_OPTION OrderedListOption
;
489 FRAMEWORK_EFI_IFR_END_ONE_OF EndOrderedList
;
490 CHAR16 CurrentLanguage
[4];
491 STRING_REF StringToken
;
494 // Obtain current language value
496 GetCurrentLanguage (CurrentLanguage
);
499 // Add first string, get first string's token
501 Status
= AddString (StringBuffer
, CurrentLanguage
, Prompt
, &StringToken
);
503 if (EFI_ERROR (Status
)) {
507 OrderedList
.Header
.OpCode
= FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
;
508 OrderedList
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_ORDERED_LIST
);
509 OrderedList
.QuestionId
= QuestionId
;
510 OrderedList
.MaxEntries
= MaxEntries
;
511 OrderedList
.Prompt
= StringToken
;
514 // Add second string, get first string's token
516 Status
= AddString (StringBuffer
, CurrentLanguage
, Help
, &StringToken
);
518 if (EFI_ERROR (Status
)) {
522 OrderedList
.Help
= StringToken
;
524 Status
= AddOpCode (FormBuffer
, &OrderedList
);
526 if (EFI_ERROR (Status
)) {
530 for (Index
= 0; Index
< OptionCount
; Index
++) {
531 OrderedListOption
.Header
.OpCode
= FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
;
532 OrderedListOption
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
);
535 // Add string and get token back
537 Status
= AddString (StringBuffer
, CurrentLanguage
, OptionsList
[Index
].OptionString
, &StringToken
);
539 OrderedListOption
.Option
= StringToken
;
540 OrderedListOption
.Value
= OptionsList
[Index
].Value
;
541 OrderedListOption
.Flags
= (UINT8
) (OptionsList
[Index
].Flags
| FRAMEWORK_EFI_IFR_FLAG_CREATED
);
542 OrderedListOption
.Key
= OptionsList
[Index
].Key
;
544 Status
= AddOpCode (FormBuffer
, &OrderedListOption
);
546 if (EFI_ERROR (Status
)) {
551 EndOrderedList
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_END_ONE_OF
);
552 EndOrderedList
.Header
.OpCode
= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
;
554 Status
= AddOpCode (FormBuffer
, &EndOrderedList
);
562 @param QuestionId Question ID of the check box
563 @param DataWidth DataWidth of the check box
564 @param Prompt Prompt of the check box
565 @param Help Help of the check box
566 @param Flags Flags of the check box
567 @param FormBuffer The form where this check box adds to
568 @param StringBuffer String buffer created for Prompt and Help.
570 @retval EFI_DEVICE_ERROR DataWidth > 1
571 @retval EFI_SUCCESS Check box successfully created
575 IN UINT16 QuestionId
,
580 IN OUT VOID
*FormBuffer
,
581 IN OUT VOID
*StringBuffer
585 FRAMEWORK_EFI_IFR_CHECKBOX CheckBox
;
586 CHAR16 CurrentLanguage
[4];
587 STRING_REF StringToken
;
590 // We do not create op-code storage widths for checkbox in excess of 8 bits for now
593 return EFI_DEVICE_ERROR
;
597 // Obtain current language value
599 GetCurrentLanguage (CurrentLanguage
);
602 // Add first string, get first string's token
604 Status
= AddString (StringBuffer
, CurrentLanguage
, Prompt
, &StringToken
);
606 if (EFI_ERROR (Status
)) {
610 CheckBox
.Header
.OpCode
= FRAMEWORK_EFI_IFR_CHECKBOX_OP
;
611 CheckBox
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_CHECKBOX
);
612 CheckBox
.QuestionId
= QuestionId
;
613 CheckBox
.Width
= DataWidth
;
614 CheckBox
.Prompt
= StringToken
;
617 // Add second string, get first string's token
619 Status
= AddString (StringBuffer
, CurrentLanguage
, Help
, &StringToken
);
621 if (EFI_ERROR (Status
)) {
625 CheckBox
.Help
= StringToken
;
626 CheckBox
.Flags
= (UINT8
) (Flags
| FRAMEWORK_EFI_IFR_FLAG_CREATED
);
628 Status
= AddOpCode (FormBuffer
, &CheckBox
);
636 @param QuestionId Question ID of the numeric
637 @param DataWidth DataWidth of the numeric
638 @param Prompt Prompt of the numeric
639 @param Help Help of the numeric
640 @param Minimum Minumun boundary of the numeric
641 @param Maximum Maximum boundary of the numeric
642 @param Step Step of the numeric
643 @param Default Default value
644 @param Flags Flags of the numeric
645 @param Key Key of the numeric
646 @param FormBuffer The form where this numeric adds to
647 @param StringBuffer String buffer created for Prompt and Help.
649 @retval EFI_DEVICE_ERROR DataWidth > 2
650 @retval EFI_SUCCESS Numeric is successfully created
654 IN UINT16 QuestionId
,
664 IN OUT VOID
*FormBuffer
,
665 IN OUT VOID
*StringBuffer
669 FRAMEWORK_EFI_IFR_NUMERIC Numeric
;
670 CHAR16 CurrentLanguage
[4];
671 STRING_REF StringToken
;
674 // We do not create op-code storage widths for numerics in excess of 16 bits for now
677 return EFI_DEVICE_ERROR
;
681 // Obtain current language value
683 GetCurrentLanguage (CurrentLanguage
);
686 // Add first string, get first string's token
688 Status
= AddString (StringBuffer
, CurrentLanguage
, Prompt
, &StringToken
);
690 if (EFI_ERROR (Status
)) {
694 Numeric
.Header
.OpCode
= FRAMEWORK_EFI_IFR_NUMERIC_OP
;
695 Numeric
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_NUMERIC
);
696 Numeric
.QuestionId
= QuestionId
;
697 Numeric
.Width
= DataWidth
;
698 Numeric
.Prompt
= StringToken
;
701 // Add second string, get first string's token
703 Status
= AddString (StringBuffer
, CurrentLanguage
, Help
, &StringToken
);
705 if (EFI_ERROR (Status
)) {
709 Numeric
.Help
= StringToken
;
710 Numeric
.Minimum
= Minimum
;
711 Numeric
.Maximum
= Maximum
;
713 Numeric
.Default
= Default
;
714 Numeric
.Flags
= (UINT8
) (Flags
| FRAMEWORK_EFI_IFR_FLAG_CREATED
);
717 Status
= AddOpCode (FormBuffer
, &Numeric
);
725 @param QuestionId - Question ID of the string
726 @param DataWidth - DataWidth of the string
727 @param Prompt - Prompt of the string
728 @param Help - Help of the string
729 @param MinSize - Min size boundary of the string
730 @param MaxSize - Max size boundary of the string
731 @param Flags - Flags of the string
732 @param Key - Key of the string
733 @param FormBuffer - The form where this string adds to
734 @param StringBuffer - String buffer created for Prompt and Help.
735 @retval EFI_SUCCESS - String successfully created.
739 IN UINT16 QuestionId
,
747 IN OUT VOID
*FormBuffer
,
748 IN OUT VOID
*StringBuffer
752 FRAMEWORK_EFI_IFR_STRING String
;
753 CHAR16 CurrentLanguage
[4];
754 STRING_REF StringToken
;
757 // Obtain current language value
759 GetCurrentLanguage (CurrentLanguage
);
762 // Add first string, get first string's token
764 Status
= AddString (StringBuffer
, CurrentLanguage
, Prompt
, &StringToken
);
766 if (EFI_ERROR (Status
)) {
770 String
.Header
.OpCode
= FRAMEWORK_EFI_IFR_STRING_OP
;
771 String
.Header
.Length
= sizeof (FRAMEWORK_EFI_IFR_STRING
);
772 String
.QuestionId
= QuestionId
;
773 String
.Width
= DataWidth
;
774 String
.Prompt
= StringToken
;
777 // Add second string, get first string's token
779 Status
= AddString (StringBuffer
, CurrentLanguage
, Help
, &StringToken
);
781 if (EFI_ERROR (Status
)) {
785 String
.Help
= StringToken
;
786 String
.MinSize
= MinSize
;
787 String
.MaxSize
= MaxSize
;
788 String
.Flags
= (UINT8
) (Flags
| FRAMEWORK_EFI_IFR_FLAG_CREATED
);
791 Status
= AddOpCode (FormBuffer
, &String
);