aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lessons/Lesson_58/README.md300
-rw-r--r--Lessons/Lesson_58/Subtitle1.pngbin0 -> 2984 bytes
-rw-r--r--Lessons/Lesson_58/Subtitle2.pngbin0 -> 3113 bytes
-rw-r--r--Lessons/Lesson_58/Subtitle3.pngbin0 -> 3432 bytes
-rw-r--r--Lessons/Lesson_58/Subtitle4.pngbin0 -> 3708 bytes
-rw-r--r--Lessons/Lesson_58/Subtitle5.pngbin0 -> 3709 bytes
-rw-r--r--Lessons/Lesson_58/Text1.pngbin0 -> 4168 bytes
-rw-r--r--Lessons/Lesson_58/Text2.pngbin0 -> 4385 bytes
-rw-r--r--Lessons/Lesson_58/Text3.pngbin0 -> 4647 bytes
-rw-r--r--Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/Form.vfr37
-rw-r--r--Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.c54
-rw-r--r--Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf30
-rw-r--r--Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/Strings.uni25
-rw-r--r--Lessons/Lesson_58/UefiLessonsPkg/UefiLessonsPkg.dec45
-rw-r--r--Lessons/Lesson_58/UefiLessonsPkg/UefiLessonsPkg.dsc80
-rw-r--r--README.md1
-rw-r--r--UefiLessonsPkg/HIIStaticForm/Form.vfr37
-rw-r--r--UefiLessonsPkg/HIIStaticForm/HIIStaticForm.c54
-rw-r--r--UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf30
-rw-r--r--UefiLessonsPkg/HIIStaticForm/Strings.uni25
-rw-r--r--UefiLessonsPkg/UefiLessonsPkg.dsc1
21 files changed, 719 insertions, 0 deletions
diff --git a/Lessons/Lesson_58/README.md b/Lessons/Lesson_58/README.md
new file mode 100644
index 0000000..710a1d1
--- /dev/null
+++ b/Lessons/Lesson_58/README.md
@@ -0,0 +1,300 @@
+Let's start to investigate form elements.
+
+Create new app `HIIStaticForm` with a content similar to our `HIISimpleForm` app. I won't repeat all the steps, as in this lesson we would only change form content.
+
+So we start with this VFR:
+```
+#define HIISTATICFORM_FORMSET_GUID {0x32783cc5, 0xe551, 0x4b61, {0xb7, 0xbd, 0x41, 0xba, 0x71, 0x7f, 0xba, 0x81}}
+
+formset
+ guid = HIISTATICFORM_FORMSET_GUID,
+ title = STRING_TOKEN(HIISTATICFORM_FORMSET_TITLE),
+ help = STRING_TOKEN(HIISTATICFORM_FORMSET_HELP),
+ form
+ formid = 1,
+ title = STRING_TOKEN(HIISTATICFORM_FORMID1_TITLE);
+ endform;
+endformset;
+```
+And it produces the folowing code:
+```
+formset
+>00000000: 0E A7 C5 3C 78 32 51 E5 61 4B B7 BD 41 BA 71 7F BA 81 02 00 03 00 01 71 99 03 93 45 85 04 4B B4 5E 32 EB 83 26 04 0E
+>00000027: 5C 06 00 00 00 00
+>0000002D: 5C 06 00 00 01 00
+ guid = {0x32783cc5, 0xe551, 0x4b61, {0xb7, 0xbd, 0x41, 0xba, 0x71, 0x7f, 0xba, 0x81}},
+ title = STRING_TOKEN(0x0002),
+ help = STRING_TOKEN(0x0003),
+ form
+>00000033: 01 86 01 00 04 00
+ formid = 1,
+ title = STRING_TOKEN(0x0004);
+ endform;
+>00000039: 29 02
+endformset;
+>0000003B: 29 02
+```
+And as you remember this creates an empty form with a title.
+
+# Subtitle
+
+The most simple form element is subtitle (https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.5.1-vfr-subtitle-definition). It is a non-interactive text to display some information to the user. Is is not possible to select this element. In EDKII form browser it is also displayed in a blue color (opposed to the interactive elements, that would be displayed in black color).
+
+You can add subtitle with this code:
+```
+subtitle
+ text = STRING_TOKEN(SUBTITLE1),
+endsubtitle;
+```
+But it is most common to use a short form:
+```
+subtitle text = STRING_TOKEN(SUBTITLE1);
+```
+
+Simply embed this string inside our form code:
+```
+...
+form
+ formid = 1,
+ title = STRING_TOKEN(HIISTATICFORM_FORMID1_TITLE);
+
+ subtitle text = STRING_TOKEN(SUBTITLE1);
+endform;
+...
+```
+
+Off course you should declare this string in the UNI file:
+```
+#string SUBTITLE1 #language en-US "Subtitle1"
+```
+
+This VFR would produce following picture:
+
+![Subtitle1](Subtitle1.png?raw=true "Subtitle1")
+
+# IFR
+
+```
+formset
+>00000000: 0E A7 C5 3C 78 32 51 E5 61 4B B7 BD 41 BA 71 7F BA 81 02 00 03 00 01 71 99 03 93 45 85 04 4B B4 5E 32 EB 83 26 04 0E
+>00000027: 5C 06 00 00 00 00
+>0000002D: 5C 06 00 00 01 00
+ guid = {0x32783cc5, 0xe551, 0x4b61, {0xb7, 0xbd, 0x41, 0xba, 0x71, 0x7f, 0xba, 0x81}},
+ title = STRING_TOKEN(0x0002),
+ help = STRING_TOKEN(0x0003),
+ form
+>00000033: 01 86 01 00 04 00
+ formid = 1,
+ title = STRING_TOKEN(0x0004);
+ subtitle text = STRING_TOKEN(0x0005);
+>00000039: 02 87 05 00 00 00 00
+>00000040: 29 02
+ endform;
+>00000042: 29 02
+endformset;
+>00000044: 29 02
+```
+
+If you compare output before and after you could see that the difference is:
+```
+ subtitle text = STRING_TOKEN(0x0005);
+>00000039: 02 87 05 00 00 00 00
+>00000040: 29 02
+```
+
+It is two opcodes: `EFI_IFR_SUBTITLE` and our `EFI_IFR_END`. We've already seen the structure for the `EFI_IFR_END`, so let's look at the `EFI_IFR_SUBTITLE`:
+```
+EFI_IFR_SUBTITLE
+
+Summary:
+Creates a sub-title in the current form.
+
+Prototype:
+
+#define EFI_IFR_SUBTITLE_OP 0x02
+
+typedef struct _EFI_IFR_SUBTITLE {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_STATEMENT_HEADER Statement;
+ UINT8 Flags;
+} EFI_IFR_SUBTITLE;
+
+Members:
+Header The sequence that defines the type of opcode as well as the length of the opcode being defined.
+ For this tag, Header.OpCode = EFI_IFR_SUBTITLE_OP.
+Flags Identifies specific behavior for the sub-title.
+```
+
+
+# Another subtitle
+
+If you add another subtitle similar to like we did it above:
+```
+...
+form
+ formid = 1,
+ title = STRING_TOKEN(HIISTATICFORM_FORMID1_TITLE);
+
+ subtitle text = STRING_TOKEN(SUBTITLE1);
+ subtitle text = STRING_TOKEN(SUBTITLE2);
+endform;
+...
+```
+
+This subtitle will be simply printed on the next string. This principle is true for all form elements. Next element by default will simply go to another string.
+
+![Subtitle2](Subtitle2.png?raw=true "Subtitle2")
+
+# Utilizing subtitle scope
+
+As we saw above, `EFI_IFR_SUBTITLE` opens a scope which is later closed by the `EFI_IFR_END`.
+
+It is possible to define elements inside subtitle scope which will indent all the elements inside the scope.
+
+Add this construction to our form:
+```
+subtitle
+ text = STRING_TOKEN(SUBTITLE3),
+
+ subtitle text = STRING_TOKEN(SUBTITLE4);
+endsubtitle;
+```
+
+If you look at the `Form.lst` you would see that
+```
+ subtitle
+>0000004B: 02 87 07 00 00 00 00
+ text = STRING_TOKEN(0x0007),
+ subtitle text = STRING_TOKEN(0x0008);
+>00000052: 02 87 08 00 00 00 00
+>00000059: 29 02
+ endsubtitle;
+>0000005B: 29 02
+```
+Here you can see opcodes `EFI_IFR_SUBTITLE`-`EFI_IFR_SUBTITLE`-`EFI_IFR_END`-`EFI_IFR_END`. If we didn't put `SUBTITLE4` in the `SUBTITLE3` scope, the output would be `EFI_IFR_SUBTITLE`-`EFI_IFR_END`-`EFI_IFR_SUBTITLE`-`EFI_IFR_END`.
+
+
+![Subtitle3](Subtitle3.png?raw=true "Subtitle3")
+
+To get more deeper understanding add another subtitle inside the scope of `SUBTITLE3` and another after the scope:
+```
+subtitle
+ text = STRING_TOKEN(SUBTITLE3),
+
+ subtitle text = STRING_TOKEN(SUBTITLE4);
+ subtitle text = STRING_TOKEN(SUBTITLE5);
+endsubtitle;
+
+subtitle text = STRING_TOKEN(SUBTITLE6);
+```
+
+![Subtitle4](Subtitle4.png?raw=true "Subtitle4")
+
+# Empty string
+
+Subtitle element is an easy way to add an empty string to your form.
+
+Insert this code right before the `SUBTITLE6` definition
+```
+subtitle text = STRING_TOKEN(STR_NULL);
+```
+And define `STR_NULL` as:
+```
+#string STR_NULL #language en-US ""
+```
+
+This would give you:
+
+![Subtitle5](Subtitle5.png?raw=true "Subtitle5")
+
+# Text element
+
+The next element that we will discuss is `text` (https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.5.2-vfr-text-definition). Add following code to our form right after the last subtitle:
+```
+text
+ help = STRING_TOKEN(TEXT1_help),
+ text = STRING_TOKEN(TEXT1_text);
+```
+
+If you would look at the `Form.lst`, you'll see that `text` doesn't open a scope, therefore only one IFR is produced - `EFI_IFR_TEXT`:
+```
+ text
+>00000078: 03 08 0C 00 0D 00 00 00
+ help = STRING_TOKEN(0x000D),
+ text = STRING_TOKEN(0x000C);
+```
+
+```
+EFI_IFR_TEXT
+
+Summary:
+Creates a static text and image.
+
+Prototype:
+
+#define EFI_IFR_TEXT_OP 0x03
+
+typedef struct _EFI_IFR_TEXT {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_STATEMENT_HEADER Statement;
+ EFI_STRING_ID TextTwo;
+} EFI_IFR_TEXT;
+
+Members:
+Header The sequence that defines the type of opcode as well as the length of the opcode being defined.
+ For this tag, Header.OpCode = EFI_IFR_TEXT_OP.
+Statement Standard statement header.
+TextTwo The string token reference to the secondary string for this opcode.
+
+Description:
+This is a static text/image statement.
+```
+And here is a definition for the `EFI_IFR_STATEMENT_HEADER` field:
+```
+EFI_IFR_STATEMENT_HEADER
+
+Summary:
+Standard statement header.
+
+Prototype:
+typedef struct _EFI_IFR_STATEMENT_HEADER {
+ EFI_STRING_ID Prompt;
+ EFI_STRING_ID Help;
+} EFI_IFR_STATEMENT_HEADER;
+
+Members:
+Prompt The string identifier of the prompt string for this particular statement. The value 0 indicates no prompt string.
+Help The string identifier of the help string for this particular statement. The value 0 indicates no help string
+
+Description:
+This is the standard header for statements, including questions.
+```
+
+On the screen `text` element looks like this:
+
+![Text1](Text1.png?raw=true "Text1")
+
+The main difference of the `text` element from the `subtitle` element is that you can select `text` elements.
+
+This is more obvious if you'll add another text element right after the first one:
+
+![Text2](Text2.png?raw=true "Text2")
+
+Now you can use arrow keys to select either `Text1 title` or `Text2 title`. And when you would do this help text for title would change automatically.
+
+# Another text field
+
+It is possible to add another text field to the text element:
+```
+text
+ help = STRING_TOKEN(TEXT3_HELP),
+ text = STRING_TOKEN(TEXT3_TEXT);
+ text = STRING_TOKEN(TEXT3_TEXT_TWO);
+```
+Its string would go to the `EFI_IFR_TEXT.TextTwo` field.
+
+In the browser it would like this. The second string is placed in a choice place for the menu item:
+
+![Text3](Text3.png?raw=true "Text3")
+
+
diff --git a/Lessons/Lesson_58/Subtitle1.png b/Lessons/Lesson_58/Subtitle1.png
new file mode 100644
index 0000000..c0825eb
--- /dev/null
+++ b/Lessons/Lesson_58/Subtitle1.png
Binary files differ
diff --git a/Lessons/Lesson_58/Subtitle2.png b/Lessons/Lesson_58/Subtitle2.png
new file mode 100644
index 0000000..c29d8fb
--- /dev/null
+++ b/Lessons/Lesson_58/Subtitle2.png
Binary files differ
diff --git a/Lessons/Lesson_58/Subtitle3.png b/Lessons/Lesson_58/Subtitle3.png
new file mode 100644
index 0000000..e477613
--- /dev/null
+++ b/Lessons/Lesson_58/Subtitle3.png
Binary files differ
diff --git a/Lessons/Lesson_58/Subtitle4.png b/Lessons/Lesson_58/Subtitle4.png
new file mode 100644
index 0000000..e267c01
--- /dev/null
+++ b/Lessons/Lesson_58/Subtitle4.png
Binary files differ
diff --git a/Lessons/Lesson_58/Subtitle5.png b/Lessons/Lesson_58/Subtitle5.png
new file mode 100644
index 0000000..e6f0329
--- /dev/null
+++ b/Lessons/Lesson_58/Subtitle5.png
Binary files differ
diff --git a/Lessons/Lesson_58/Text1.png b/Lessons/Lesson_58/Text1.png
new file mode 100644
index 0000000..c8822a9
--- /dev/null
+++ b/Lessons/Lesson_58/Text1.png
Binary files differ
diff --git a/Lessons/Lesson_58/Text2.png b/Lessons/Lesson_58/Text2.png
new file mode 100644
index 0000000..9a7064b
--- /dev/null
+++ b/Lessons/Lesson_58/Text2.png
Binary files differ
diff --git a/Lessons/Lesson_58/Text3.png b/Lessons/Lesson_58/Text3.png
new file mode 100644
index 0000000..9b0c513
--- /dev/null
+++ b/Lessons/Lesson_58/Text3.png
Binary files differ
diff --git a/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/Form.vfr b/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/Form.vfr
new file mode 100644
index 0000000..68a8ef0
--- /dev/null
+++ b/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/Form.vfr
@@ -0,0 +1,37 @@
+#define HIISTATICFORM_FORMSET_GUID {0x32783cc5, 0xe551, 0x4b61, {0xb7, 0xbd, 0x41, 0xba, 0x71, 0x7f, 0xba, 0x81}}
+
+formset
+ guid = HIISTATICFORM_FORMSET_GUID,
+ title = STRING_TOKEN(HIISTATICFORM_FORMSET_TITLE),
+ help = STRING_TOKEN(HIISTATICFORM_FORMSET_HELP),
+ form
+ formid = 1,
+ title = STRING_TOKEN(HIISTATICFORM_FORMID1_TITLE);
+
+ subtitle text = STRING_TOKEN(SUBTITLE1);
+ subtitle text = STRING_TOKEN(SUBTITLE2);
+
+ subtitle
+ text = STRING_TOKEN(SUBTITLE3),
+
+ subtitle text = STRING_TOKEN(SUBTITLE4);
+ subtitle text = STRING_TOKEN(SUBTITLE5);
+ endsubtitle;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ subtitle text = STRING_TOKEN(SUBTITLE6);
+
+ text
+ help = STRING_TOKEN(TEXT1_HELP),
+ text = STRING_TOKEN(TEXT1_TEXT);
+
+ text
+ help = STRING_TOKEN(TEXT2_HELP),
+ text = STRING_TOKEN(TEXT2_TEXT);
+
+ text
+ help = STRING_TOKEN(TEXT3_HELP),
+ text = STRING_TOKEN(TEXT3_TEXT),
+ text = STRING_TOKEN(TEXT3_TEXT_TWO);
+ endform;
+endformset;
diff --git a/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.c b/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.c
new file mode 100644
index 0000000..45d992a
--- /dev/null
+++ b/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Library/HiiLib.h>
+#include <Protocol/FormBrowser2.h>
+
+extern UINT8 FormBin[];
+
+
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_HII_HANDLE Handle = HiiAddPackages(
+ &gEfiCallerIdGuid,
+ NULL,
+ HIIStaticFormStrings,
+ FormBin,
+ NULL
+ );
+ if (Handle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EFI_STATUS Status;
+ EFI_FORM_BROWSER2_PROTOCOL* FormBrowser2;
+ Status = gBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, (VOID**)&FormBrowser2);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = FormBrowser2->SendForm (
+ FormBrowser2,
+ &Handle,
+ 1,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ );
+
+ HiiRemovePackages(Handle);
+
+ return EFI_SUCCESS;
+}
diff --git a/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf b/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf
new file mode 100644
index 0000000..9aca4a8
--- /dev/null
+++ b/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf
@@ -0,0 +1,30 @@
+##
+# Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+#
+# SPDX-License-Identifier: MIT
+##
+
+[Defines]
+ INF_VERSION = 1.25
+ BASE_NAME = HIIStaticForm
+ FILE_GUID = 8f21815a-958f-4215-abff-bee9ae16a436
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+[Sources]
+ HIIStaticForm.c
+ Strings.uni
+ Form.vfr
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ HiiLib
+
+[Protocols]
+ gEfiFormBrowser2ProtocolGuid
diff --git a/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/Strings.uni b/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/Strings.uni
new file mode 100644
index 0000000..3bada64
--- /dev/null
+++ b/Lessons/Lesson_58/UefiLessonsPkg/HIIStaticForm/Strings.uni
@@ -0,0 +1,25 @@
+//
+// Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+//
+// SPDX-License-Identifier: MIT
+//
+
+#langdef en-US "English"
+
+#string HIISTATICFORM_FORMSET_TITLE #language en-US "Static Formset"
+#string HIISTATICFORM_FORMSET_HELP #language en-US "This is a static formset"
+#string HIISTATICFORM_FORMID1_TITLE #language en-US "Static Form"
+#string SUBTITLE1 #language en-US "Subtitle1"
+#string SUBTITLE2 #language en-US "Subtitle2"
+#string SUBTITLE3 #language en-US "Subtitle3"
+#string SUBTITLE4 #language en-US "Subtitle4"
+#string SUBTITLE5 #language en-US "Subtitle5"
+#string SUBTITLE6 #language en-US "Subtitle6"
+#string STR_NULL #language en-US ""
+#string TEXT1_TEXT #language en-US "Text1 title"
+#string TEXT1_HELP #language en-US "Text1 help"
+#string TEXT2_TEXT #language en-US "Text2 title"
+#string TEXT2_HELP #language en-US "Text2 help"
+#string TEXT3_TEXT #language en-US "Text3 title"
+#string TEXT3_TEXT_TWO #language en-US "Text3 value"
+#string TEXT3_HELP #language en-US "Text3 help"
diff --git a/Lessons/Lesson_58/UefiLessonsPkg/UefiLessonsPkg.dec b/Lessons/Lesson_58/UefiLessonsPkg/UefiLessonsPkg.dec
new file mode 100644
index 0000000..40b351c
--- /dev/null
+++ b/Lessons/Lesson_58/UefiLessonsPkg/UefiLessonsPkg.dec
@@ -0,0 +1,45 @@
+##
+# Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+#
+# SPDX-License-Identifier: MIT
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = UefiLessonsPkg
+ PACKAGE_GUID = 7e7edbba-ca2c-4177-a3f0-d3371358773a
+ PACKAGE_VERSION = 1.01
+
+[Includes]
+ Include
+
+[Guids]
+ # FILE_GUID as defined in UefiLessonsPkg/HelloWorld/HelloWorld.inf
+ gHelloWorldFileGuid = {0x2e55fa38, 0xf148, 0x42d3, {0xaf, 0x90, 0x1b, 0xe2, 0x47, 0x32, 0x3e, 0x30}}
+ gUefiLessonsPkgTokenSpaceGuid = {0x150cab53, 0xad47, 0x4385, {0xb5, 0xdd, 0xbc, 0xfc, 0x76, 0xba, 0xca, 0xf0}}
+ gHIIStringsCGuid = { 0x8e0b8ed3, 0x14f7, 0x499d, { 0xa2, 0x24, 0xae, 0xe8, 0x9d, 0xc9, 0x7f, 0xa3 }}
+ gHIIStringsUNIGuid = { 0x6ee19058, 0x0fe2, 0x44ed, { 0x89, 0x1c, 0xa5, 0xd7, 0xe1, 0x08, 0xee, 0x1a }}
+ gHIIStringsUNIRCGuid = { 0x785693b4, 0x623e, 0x40fa, { 0x9a, 0x45, 0x68, 0xda, 0x38, 0x30, 0x89, 0xdd }}
+ gHIIAddRussianFontGuid = { 0x9fe2f616, 0x323c, 0x45a7, { 0x87, 0xa2, 0xdf, 0xef, 0xf5, 0x17, 0xcc, 0x66 }}
+
+[Protocols]
+ gSimpleClassProtocolGuid = { 0xb5510eea, 0x6f11, 0x4e4b, { 0xad, 0x0f, 0x35, 0xce, 0x17, 0xbd, 0x7a, 0x67 }}
+
+[PcdsFixedAtBuild]
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32|42|UINT32|0x00000001
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_1|42|UINT32|0x00000002
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_2|42|UINT32|0x00000003
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyVarBool|FALSE|BOOLEAN|0x00000004
+
+[PcdsPatchableInModule]
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyPatchableVar32|0x31313131|UINT32|0x10000001
+
+[PcdsFeatureFlag]
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyFeatureFlagVar|FALSE|BOOLEAN|0x20000001
+
+[PcdsDynamic]
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyDynamicVar32|0x38323232|UINT32|0x30000001
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyDynamicVar32_1|42|UINT32|0x30000002
+
+[PcdsDynamicEx]
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyDynamicExVar32|0x38333333|UINT32|0x40000001
diff --git a/Lessons/Lesson_58/UefiLessonsPkg/UefiLessonsPkg.dsc b/Lessons/Lesson_58/UefiLessonsPkg/UefiLessonsPkg.dsc
new file mode 100644
index 0000000..8b2ff85
--- /dev/null
+++ b/Lessons/Lesson_58/UefiLessonsPkg/UefiLessonsPkg.dsc
@@ -0,0 +1,80 @@
+##
+# Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+#
+# SPDX-License-Identifier: MIT
+##
+
+[Defines]
+ DSC_SPECIFICATION = 0x0001001C
+ PLATFORM_GUID = 3db7270f-ffac-4139-90a4-0ae68f3f8167
+ PLATFORM_VERSION = 0.01
+ PLATFORM_NAME = UefiLessonsPkg
+ SKUID_IDENTIFIER = DEFAULT
+ SUPPORTED_ARCHITECTURES = X64
+ BUILD_TARGETS = RELEASE
+
+
+[LibraryClasses]
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ #PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ #SimpleLibrary|UefiLessonsPkg/Library/SimpleLibrary/SimpleLibrary.inf
+ #SimpleLibrary|UefiLessonsPkg/Library/SimpleLibraryWithConstructor/SimpleLibraryWithConstructor.inf
+ SimpleLibrary|UefiLessonsPkg/Library/SimpleLibraryWithConstructorAndDestructor/SimpleLibraryWithConstructorAndDestructor.inf
+
+[Components]
+ UefiLessonsPkg/SimplestApp/SimplestApp.inf
+ UefiLessonsPkg/HelloWorld/HelloWorld.inf
+ UefiLessonsPkg/ImageHandle/ImageHandle.inf
+ UefiLessonsPkg/ImageInfo/ImageInfo.inf
+ UefiLessonsPkg/MemoryInfo/MemoryInfo.inf
+ UefiLessonsPkg/SimpleShellApp/SimpleShellApp.inf
+ UefiLessonsPkg/ListVariables/ListVariables.inf
+ UefiLessonsPkg/ShowBootVariables/ShowBootVariables.inf
+ UefiLessonsPkg/InteractiveApp/InteractiveApp.inf
+ UefiLessonsPkg/PCDLesson/PCDLesson.inf
+ UefiLessonsPkg/SmbiosInfo/SmbiosInfo.inf
+ UefiLessonsPkg/ShowTables/ShowTables.inf
+ UefiLessonsPkg/AcpiInfo/AcpiInfo.inf
+ UefiLessonsPkg/SaveBGRT/SaveBGRT.inf
+ UefiLessonsPkg/ListPCI/ListPCI.inf
+ UefiLessonsPkg/SimpleDriver/SimpleDriver.inf
+ UefiLessonsPkg/PCIRomInfo/PCIRomInfo.inf
+ UefiLessonsPkg/Library/SimpleLibrary/SimpleLibrary.inf
+ UefiLessonsPkg/Library/SimpleLibraryWithConstructor/SimpleLibraryWithConstructor.inf
+ UefiLessonsPkg/SimpleLibraryUser/SimpleLibraryUser.inf
+ UefiLessonsPkg/SimpleClassProtocol/SimpleClassProtocol.inf
+ UefiLessonsPkg/SimpleClassUser/SimpleClassUser.inf
+ UefiLessonsPkg/HotKeyDriver/HotKeyDriver.inf
+ UefiLessonsPkg/ShowHII/ShowHII.inf
+ UefiLessonsPkg/HIIStringsC/HIIStringsC.inf
+ UefiLessonsPkg/HIIStringsUNI/HIIStringsUNI.inf
+ UefiLessonsPkg/HIIStringsUNIRC/HIIStringsUNIRC.inf
+ UefiLessonsPkg/HIIStringsMan/HIIStringsMan.inf
+ UefiLessonsPkg/HIIAddRussianFont/HIIAddRussianFont.inf
+ UefiLessonsPkg/HIIAddLocalization/HIIAddLocalization.inf
+ UefiLessonsPkg/AddNewLanguage/AddNewLanguage.inf
+ UefiLessonsPkg/HIISimpleForm/HIISimpleForm.inf
+ UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf
+
+[PcdsFixedAtBuild]
+ gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_2|44
+
diff --git a/README.md b/README.md
index e94ef1c..8110854 100644
--- a/README.md
+++ b/README.md
@@ -61,6 +61,7 @@ These series of lessons are intendend to get you started with UEFI programming i
- [Lesson 55](Lessons/Lesson_55): Try to modify `PlatformLangCodes` EFI variable and add another language dynamically. Variable protection with a help of `EDKII_VARIABLE_POLICY_PROTOCOL`
- [Lesson 56](Lessons/Lesson_56): How to get module `FILE_GUID` and `BASE_NAME` in code. Autoconf variables `gEfiCallerIdGuid`/`gEdkiiDscPlatformGuid`/`gEfiCallerBaseName`
- [Lesson 57](Lessons/Lesson_57): Use VFR to create a simple form and display it with a help of `EFI_FORM_BROWSER2_PROTOCOL.SendForm()`. IFR data investigation
+- [Lesson 58](Lessons/Lesson_58): `subtitle` and `text` VFR elements
_____
diff --git a/UefiLessonsPkg/HIIStaticForm/Form.vfr b/UefiLessonsPkg/HIIStaticForm/Form.vfr
new file mode 100644
index 0000000..68a8ef0
--- /dev/null
+++ b/UefiLessonsPkg/HIIStaticForm/Form.vfr
@@ -0,0 +1,37 @@
+#define HIISTATICFORM_FORMSET_GUID {0x32783cc5, 0xe551, 0x4b61, {0xb7, 0xbd, 0x41, 0xba, 0x71, 0x7f, 0xba, 0x81}}
+
+formset
+ guid = HIISTATICFORM_FORMSET_GUID,
+ title = STRING_TOKEN(HIISTATICFORM_FORMSET_TITLE),
+ help = STRING_TOKEN(HIISTATICFORM_FORMSET_HELP),
+ form
+ formid = 1,
+ title = STRING_TOKEN(HIISTATICFORM_FORMID1_TITLE);
+
+ subtitle text = STRING_TOKEN(SUBTITLE1);
+ subtitle text = STRING_TOKEN(SUBTITLE2);
+
+ subtitle
+ text = STRING_TOKEN(SUBTITLE3),
+
+ subtitle text = STRING_TOKEN(SUBTITLE4);
+ subtitle text = STRING_TOKEN(SUBTITLE5);
+ endsubtitle;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ subtitle text = STRING_TOKEN(SUBTITLE6);
+
+ text
+ help = STRING_TOKEN(TEXT1_HELP),
+ text = STRING_TOKEN(TEXT1_TEXT);
+
+ text
+ help = STRING_TOKEN(TEXT2_HELP),
+ text = STRING_TOKEN(TEXT2_TEXT);
+
+ text
+ help = STRING_TOKEN(TEXT3_HELP),
+ text = STRING_TOKEN(TEXT3_TEXT),
+ text = STRING_TOKEN(TEXT3_TEXT_TWO);
+ endform;
+endformset;
diff --git a/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.c b/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.c
new file mode 100644
index 0000000..45d992a
--- /dev/null
+++ b/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Library/HiiLib.h>
+#include <Protocol/FormBrowser2.h>
+
+extern UINT8 FormBin[];
+
+
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_HII_HANDLE Handle = HiiAddPackages(
+ &gEfiCallerIdGuid,
+ NULL,
+ HIIStaticFormStrings,
+ FormBin,
+ NULL
+ );
+ if (Handle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EFI_STATUS Status;
+ EFI_FORM_BROWSER2_PROTOCOL* FormBrowser2;
+ Status = gBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, (VOID**)&FormBrowser2);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = FormBrowser2->SendForm (
+ FormBrowser2,
+ &Handle,
+ 1,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ );
+
+ HiiRemovePackages(Handle);
+
+ return EFI_SUCCESS;
+}
diff --git a/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf b/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf
new file mode 100644
index 0000000..9aca4a8
--- /dev/null
+++ b/UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf
@@ -0,0 +1,30 @@
+##
+# Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+#
+# SPDX-License-Identifier: MIT
+##
+
+[Defines]
+ INF_VERSION = 1.25
+ BASE_NAME = HIIStaticForm
+ FILE_GUID = 8f21815a-958f-4215-abff-bee9ae16a436
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+[Sources]
+ HIIStaticForm.c
+ Strings.uni
+ Form.vfr
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ HiiLib
+
+[Protocols]
+ gEfiFormBrowser2ProtocolGuid
diff --git a/UefiLessonsPkg/HIIStaticForm/Strings.uni b/UefiLessonsPkg/HIIStaticForm/Strings.uni
new file mode 100644
index 0000000..3bada64
--- /dev/null
+++ b/UefiLessonsPkg/HIIStaticForm/Strings.uni
@@ -0,0 +1,25 @@
+//
+// Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+//
+// SPDX-License-Identifier: MIT
+//
+
+#langdef en-US "English"
+
+#string HIISTATICFORM_FORMSET_TITLE #language en-US "Static Formset"
+#string HIISTATICFORM_FORMSET_HELP #language en-US "This is a static formset"
+#string HIISTATICFORM_FORMID1_TITLE #language en-US "Static Form"
+#string SUBTITLE1 #language en-US "Subtitle1"
+#string SUBTITLE2 #language en-US "Subtitle2"
+#string SUBTITLE3 #language en-US "Subtitle3"
+#string SUBTITLE4 #language en-US "Subtitle4"
+#string SUBTITLE5 #language en-US "Subtitle5"
+#string SUBTITLE6 #language en-US "Subtitle6"
+#string STR_NULL #language en-US ""
+#string TEXT1_TEXT #language en-US "Text1 title"
+#string TEXT1_HELP #language en-US "Text1 help"
+#string TEXT2_TEXT #language en-US "Text2 title"
+#string TEXT2_HELP #language en-US "Text2 help"
+#string TEXT3_TEXT #language en-US "Text3 title"
+#string TEXT3_TEXT_TWO #language en-US "Text3 value"
+#string TEXT3_HELP #language en-US "Text3 help"
diff --git a/UefiLessonsPkg/UefiLessonsPkg.dsc b/UefiLessonsPkg/UefiLessonsPkg.dsc
index aec7768..8b2ff85 100644
--- a/UefiLessonsPkg/UefiLessonsPkg.dsc
+++ b/UefiLessonsPkg/UefiLessonsPkg.dsc
@@ -73,6 +73,7 @@
UefiLessonsPkg/HIIAddLocalization/HIIAddLocalization.inf
UefiLessonsPkg/AddNewLanguage/AddNewLanguage.inf
UefiLessonsPkg/HIISimpleForm/HIISimpleForm.inf
+ UefiLessonsPkg/HIIStaticForm/HIIStaticForm.inf
[PcdsFixedAtBuild]
gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_2|44