aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Aladyshev <aladyshev22@gmail.com>2022-09-26 15:35:40 +0300
committerKonstantin Aladyshev <aladyshev22@gmail.com>2022-09-26 15:35:40 +0300
commit03acca6a5ac17372e17336a01069a1d97771d392 (patch)
tree6fde894630334e523570ded217939a299b7f21d4
parent3d2f384ed46ecf9a6128418035928aebda36a03a (diff)
downloadUEFI-Lessons-03acca6a5ac17372e17336a01069a1d97771d392.tar.gz
UEFI-Lessons-03acca6a5ac17372e17336a01069a1d97771d392.tar.bz2
UEFI-Lessons-03acca6a5ac17372e17336a01069a1d97771d392.zip
Use function to set defaults
Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_8/1.pngbin0 -> 8845 bytes
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_8/README.md151
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Data.h25
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Form.vfr106
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.c152
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.inf30
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Strings.uni46
-rw-r--r--README.md9
-rw-r--r--UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Data.h25
-rw-r--r--UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Form.vfr106
-rw-r--r--UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.c152
-rw-r--r--UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.inf30
-rw-r--r--UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Strings.uni46
-rw-r--r--UefiLessonsPkg/UefiLessonsPkg.dsc1
14 files changed, 875 insertions, 4 deletions
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_8/1.png b/Lessons_uncategorized/Lesson_Configuration_Language_8/1.png
new file mode 100644
index 0000000..1049f88
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_8/1.png
Binary files differ
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_8/README.md b/Lessons_uncategorized/Lesson_Configuration_Language_8/README.md
new file mode 100644
index 0000000..b1297b6
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_8/README.md
@@ -0,0 +1,151 @@
+When we load our HII form drivers with `efivarstore` for the first time, we need to create a variable for the form storage. Up until now we've used the following pattern in the driver's entry point code:
+```cpp
+UINTN BufferSize;
+UEFI_VARIABLE_STRUCTURE EfiVarstore;
+BufferSize = sizeof(UEFI_VARIABLE_STRUCTURE);
+Status = gRT->GetVariable (
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ NULL,
+ &BufferSize,
+ &EfiVarstore);
+if (EFI_ERROR(Status)) {
+ ZeroMem(&EfiVarstore, sizeof(EfiVarstore)); <---- Data structure initialization
+ Status = gRT->SetVariable(
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(EfiVarstore),
+ &EfiVarstore);
+ if (EFI_ERROR(Status)) {
+ Print(L"Error! Can't create variable! %r\n", Status);
+ }
+}
+```
+Here we create an UEFI variable for the form storage structure if it is not already present in the system. When we create a new variable we use `ZeroMem` for the structure initialization. This is why when we look at our form for the first time we see that checkbox is unset, numeric is equal to 0, string element is empty and so on.
+
+If we want to start not from this, but from some sane defaults, instead of `ZeroMem` we can use some custom function that would initialize the structure fields as we want to. But the thing is that we already have a method to declare default values. VFR syntax allow us to set defaults for the form elements with the `default` keyword. You already know how to set elements to these defaults interactively from the Form Browser. But what if we want to start from these values?
+
+Let's investigate how we can use the `default` data from the VFR to initialize form fields non-interactively.
+
+Basically we already know that. We need to:
+- use `EFI_HII_CONFIG_ROUTING_PROTOCOL.ExtractConfig()` to get Form storage configuration,
+- strip default configuration part (`ALTCFG=0000&...`) from the response,
+- use it to constuct configuration request for the `EFI_HII_CONFIG_ROUTING_PROTOCOL.RouteConfig()` function to set elements to their default values.
+
+Stripping the necessary part from the configuration string can be a burden, this is why UEFI specification offers a helper function for that:
+```
+EFI_HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg()
+
+Summary:
+This helper function is to be called by drivers to extract portions of a larger configuration string.
+
+Prototype:
+typedef
+EFI_STATUS
+ (EFIAPI * EFI_HII_GET_ALT_CFG ) (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigResp,
+ IN CONST EFI_GUID *Guid,
+ IN CONST EFI_STRING Name,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_STRING AltCfgId,
+ OUT EFI_STRING *AltCfgResp
+ );
+
+Parameters:
+This Points to the EFI_HII_CONFIG_ROUTING_PROTOCOL instance
+ConfigResp A null-terminated string in <ConfigAltResp> format
+Guid A pointer to the GUID value to search for in the routing portion of the ConfigResp
+ string when retrieving the requested data. If Guid is NULL, then all GUID values will be searched for
+Name A pointer to the NAME value to search for in the routing portion of the ConfigResp
+ string when retrieving the requested data. If Name is NULL, then all Name values will be searched for
+DevicePath A pointer to the PATH value to search for in the routing portion of the ConfigResp
+ string when retrieving the requested data. If DevicePath is NULL, then all DevicePath values will be searched for
+AltCfgId A pointer to the ALTCFG value to search for in the routing portion of the
+ ConfigResp string when retrieving the requested data. If this parameter is NULL, then the current setting will be retrieved
+AltCfgResp A pointer to a buffer which will be allocated by the function which contains the
+ retrieved string as requested. This buffer is only allocated if the call was successful.
+ The null-terminated string will be in <ConfigResp> format
+
+Description:
+This function retrieves the requested portion of the configuration string from a larger configuration string. This function will use the Guid, Name, and DevicePath parameters to find the appropriate
+section of the ConfigResp string. Upon finding this portion of the string, it will use the AltCfgId parameter to find the appropriate instance of data in the ConfigResp string. Once found, the found
+data will be copied to a buffer which is allocated by the function so that it can be returned to the caller. The caller is responsible for freeing this allocated buffer.
+```
+
+With that our steps would be:
+- use `EFI_HII_CONFIG_ROUTING_PROTOCOL.ExtractConfig()` to get Form storage configuration
+- use `EFI_HII_CONFIG_ROUTING_PROTOCOL.GetAltCfg()` to get necessary default configuration
+- use `EFI_HII_CONFIG_ROUTING_PROTOCOL.RouteConfig()` to set elements to their default values
+
+But fortunately we don't have to do any of that as `HiiLib` offers us the `HiiSetToDefaults` function [https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/UefiHiiLib/HiiLib.c](https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/UefiHiiLib/HiiLib.c):
+```
+/**
+ Reset the default value specified by DefaultId to the driver
+ configuration got by Request string.
+ NULL request string support depends on the ExportConfig interface of
+ HiiConfigRouting protocol in UEFI specification.
+ @param Request A null-terminated Unicode string in
+ <MultiConfigRequest> format. It can be NULL.
+ If it is NULL, all configuration for the
+ entirety of the current HII database will be reset.
+ @param DefaultId Specifies the type of defaults to retrieve.
+ @retval TRUE The default value is set successfully.
+ @retval FALSE The default value can't be found and set.
+**/
+BOOLEAN
+EFIAPI
+HiiSetToDefaults (
+ IN CONST EFI_STRING Request OPTIONAL,
+ IN UINT16 DefaultId
+ )
+```
+So all we need to do is to construct configuration header for the driver storage and call this function. And practically we already know how to do it.
+
+# `HIIFormDataElementsWithDefaultsSet`
+
+To keep lessons separate I would create a new driver `HIIFormDataElementsWithDefaultsSet`. But basically it based on our `HIIFormDataElements` driver code, so I would explain only things that differ.
+
+We need to add new code only if the respective UEFI variable is not set:
+```cpp
+Status = gRT->GetVariable(...)
+if (EFI_ERROR(Status)) {
+ ZeroMem(...);
+ Status = gRT->SetVariable(...);
+ if (EFI_ERROR(Status)) {
+ Print(L"Error! Can't create variable! %r\n", Status);
+ }
+ <...> <------ add code that would set defaults to form elements
+}
+```
+As in this code we would call `EFI_HII_CONFIG_ROUTING_PROTOCOL` functions expecting output from our form, the code above must be after the `HiiAddPackages` call:
+```cpp
+mHiiHandle = HiiAddPackages(...);
+
+Status = gRT->GetVariable(...)
+if (EFI_ERROR(Status)) {
+ ZeroMem(...);
+ Status = gRT->SetVariable(...);
+ if (EFI_ERROR(Status)) {
+ Print(L"Error! Can't create variable! %r\n", Status);
+ }
+ <...>
+}
+```
+I point out that fact, because earlier we did things in the opposite way.
+
+Now let's get to our initialization code. As in our driver code we already have the `DriverHandle` and storage `GUID` and `Name` we can just call `HiiConstructConfigHdr` function to create necessary confugartion header string. After that we just use it with necessary `DefaultId` number to set defaults. Let's use 0 as `DefaultId` to set standard defaults:
+```
+EFI_STRING ConfigStr = HiiConstructConfigHdr(&UEFIVariableGuid, UEFIVariableName, mDriverHandle);
+UINT16 DefaultId = 0;
+if (!HiiSetToDefaults(ConfigStr, DefaultId)) {
+ Print(L"Error! Can't set default configuration #%d\n", DefaultId);
+}
+```
+This is all we need to add. And if we want to set `Manufacture defaults`, all we need to do is replace `DefaultId = 0` to `DefaultId = 1`.
+
+If you build our driver and load it in UEFI shell, you'll see that now the respective form is filled with default values even at the first launch:
+
+![1](1.png?raw=true "1")
+
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Data.h b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Data.h
new file mode 100644
index 0000000..2ba2665
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Data.h
@@ -0,0 +1,25 @@
+#ifndef _DATA_H_
+#define _DATA_H_
+
+#define FORMSET_GUID {0xdfdb4e02, 0x32ca, 0x4f50, {0xa1, 0xf1, 0x07, 0xdc, 0xfb, 0xf5, 0xb4, 0x5a}}
+#define DATAPATH_GUID {0xec8952af, 0x0779, 0x4e39, {0xb1, 0x6c, 0x69, 0x7c, 0xb3, 0xc7, 0x89, 0x0d}}
+#define STORAGE_GUID {0x430d7be9, 0x60bd, 0x4081, {0x99, 0xc1, 0x01, 0xf4, 0xf7, 0x1f, 0xdf, 0x80}}
+
+#define UEFI_VARIABLE_STRUCTURE_NAME L"FormData"
+
+#pragma pack(1)
+typedef struct {
+ UINT8 CheckboxValue;
+ UINT16 NumericValue;
+ CHAR16 StringValue[11];
+ EFI_HII_DATE DateValue;
+ EFI_HII_TIME TimeValue;
+ UINT8 OneOfValue;
+ UINT8 OrderedListValue[3];
+} UEFI_VARIABLE_STRUCTURE;
+#pragma pack()
+
+#define LABEL_START 0x1111
+#define LABEL_END 0x2222
+
+#endif
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Form.vfr b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Form.vfr
new file mode 100644
index 0000000..930a84a
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Form.vfr
@@ -0,0 +1,106 @@
+#include <Uefi/UefiMultiPhase.h>
+#include "Data.h"
+
+formset
+ guid = FORMSET_GUID,
+ title = STRING_TOKEN(FORMSET_TITLE),
+ help = STRING_TOKEN(FORMSET_HELP),
+
+ efivarstore UEFI_VARIABLE_STRUCTURE,
+ attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ name = FormData,
+ guid = STORAGE_GUID;
+
+ defaultstore StandardDefault,
+ prompt = STRING_TOKEN(STANDARD_DEFAULT_PROMPT),
+ attribute = 0x0000;
+
+ defaultstore ManufactureDefault,
+ prompt = STRING_TOKEN(MFG_DEFAULT_PROMPT),
+ attribute = 0x0001;
+
+ form
+ formid = 1,
+ title = STRING_TOKEN(FORMID1_TITLE);
+
+ checkbox
+ varid = FormData.CheckboxValue,
+ prompt = STRING_TOKEN(CHECKBOX_PROMPT),
+ help = STRING_TOKEN(CHECKBOX_HELP),
+ default = TRUE, defaultstore = StandardDefault,
+ default = FALSE, defaultstore = ManufactureDefault,
+ endcheckbox;
+
+ numeric
+ name = NumericQuestion,
+ varid = FormData.NumericValue,
+ prompt = STRING_TOKEN(NUMERIC_PROMPT),
+ help = STRING_TOKEN(NUMERIC_HELP),
+ flags = NUMERIC_SIZE_2 | DISPLAY_UINT_HEX,
+ //minimum = 0x1234,
+ //maximum = 0xaa55,
+ minimum = 0,
+ maximum = 10,
+ step = 1,
+ default = 7, defaultstore = StandardDefault,
+ default = 8, defaultstore = ManufactureDefault,
+ endnumeric;
+
+ string
+ name = StringQuestion,
+ varid = FormData.StringValue,
+ prompt = STRING_TOKEN(STRING_PROMPT),
+ help = STRING_TOKEN(STRING_HELP),
+ minsize = 5,
+ maxsize = 10,
+ default = STRING_TOKEN(STRING_DEFAULT), defaultstore = StandardDefault,
+ default = STRING_TOKEN(STRING_PROMPT), defaultstore = ManufactureDefault,
+ endstring;
+
+ date
+ varid = FormData.DateValue,
+ prompt = STRING_TOKEN(DATE_PROMPT),
+ help = STRING_TOKEN(DATE_HELP),
+ default = 2021/05/22,
+ enddate;
+
+ time
+ varid = FormData.TimeValue,
+ prompt = STRING_TOKEN(TIME_PROMPT),
+ help = STRING_TOKEN(TIME_HELP),
+ default = 23:55:33,
+ endtime;
+
+ oneof
+ name = OneOfQuestion,
+ varid = FormData.OneOfValue,
+ prompt = STRING_TOKEN(ONEOF_PROMPT),
+ help = STRING_TOKEN(ONEOF_HELP),
+ option text = STRING_TOKEN(ONEOF_OPTION1), value = 0x00, flags = 0;
+ option text = STRING_TOKEN(ONEOF_OPTION2), value = 0x33, flags = MANUFACTURING;
+ option text = STRING_TOKEN(ONEOF_OPTION3), value = 0x55, flags = DEFAULT;
+ endoneof;
+
+ orderedlist
+ varid = FormData.OrderedListValue,
+ prompt = STRING_TOKEN(ORDERED_LIST_PROMPT),
+ help = STRING_TOKEN(ORDERED_LIST_HELP),
+ option text = STRING_TOKEN(ORDERED_LIST_OPTION1), value = 0x0A, flags = 0;
+ option text = STRING_TOKEN(ORDERED_LIST_OPTION2), value = 0x0B, flags = 0;
+ option text = STRING_TOKEN(ORDERED_LIST_OPTION3), value = 0x0C, flags = 0;
+ default = {0x0c, 0x0b, 0x0a},
+ endlist;
+
+ resetbutton
+ defaultstore = StandardDefault,
+ prompt = STRING_TOKEN(BTN_STANDARD_DEFAULT_PROMPT),
+ help = STRING_TOKEN(BTN_STANDARD_DEFAULT_HELP),
+ endresetbutton;
+
+ resetbutton
+ defaultstore = ManufactureDefault,
+ prompt = STRING_TOKEN(BTN_MFG_DEFAULT_PROMPT),
+ help = STRING_TOKEN(BTN_MFG_DEFAULT_HELP),
+ endresetbutton;
+ endform;
+endformset;
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.c b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.c
new file mode 100644
index 0000000..c527510
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2022, Konstantin Aladyshev <aladyshev22@gmail.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include "Data.h"
+
+extern UINT8 FormBin[];
+
+#pragma pack(1)
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+#pragma pack()
+
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ DATAPATH_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH),
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+
+EFI_HII_HANDLE mHiiHandle = NULL;
+EFI_HANDLE mDriverHandle = NULL;
+EFI_STRING UEFIVariableName = UEFI_VARIABLE_STRUCTURE_NAME;
+EFI_GUID UEFIVariableGuid = STORAGE_GUID;
+
+
+EFI_STATUS
+EFIAPI
+HIIFormDataElementsWithDefaultsSetUnload (
+ EFI_HANDLE ImageHandle
+ )
+{
+ if (mHiiHandle != NULL)
+ HiiRemovePackages(mHiiHandle);
+
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ UEFI_VARIABLE_STRUCTURE EfiVarstore;
+
+ BufferSize = sizeof(UEFI_VARIABLE_STRUCTURE);
+ Status = gRT->GetVariable(
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ NULL,
+ &BufferSize,
+ &EfiVarstore);
+ if (!EFI_ERROR(Status)) {
+ Status = gRT->SetVariable(
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ 0,
+ 0,
+ NULL);
+ if (EFI_ERROR(Status)) {
+ Print(L"Error! Can't delete variable! %r\n", Status);
+ }
+ }
+
+ Status = gBS->UninstallMultipleProtocolInterfaces(
+ mDriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ NULL
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+HIIFormDataElementsWithDefaultsSetEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &mDriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ mHiiHandle = HiiAddPackages(
+ &gEfiCallerIdGuid,
+ mDriverHandle,
+ HIIFormDataElementsWithDefaultsSetStrings,
+ FormBin,
+ NULL
+ );
+ if (mHiiHandle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ UINTN BufferSize;
+ UEFI_VARIABLE_STRUCTURE EfiVarstore;
+ BufferSize = sizeof(UEFI_VARIABLE_STRUCTURE);
+ Status = gRT->GetVariable (
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ NULL,
+ &BufferSize,
+ &EfiVarstore);
+ if (EFI_ERROR(Status)) {
+ ZeroMem(&EfiVarstore, sizeof(EfiVarstore));
+ Status = gRT->SetVariable(
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(EfiVarstore),
+ &EfiVarstore);
+ if (EFI_ERROR(Status)) {
+ Print(L"Error! Can't create variable! %r\n", Status);
+ }
+ EFI_STRING ConfigStr = HiiConstructConfigHdr(&UEFIVariableGuid, UEFIVariableName, mDriverHandle);
+ UINT16 DefaultId = 0;
+ if (!HiiSetToDefaults(ConfigStr, DefaultId)) {
+ Print(L"Error! Can't set default configuration #%d\n", DefaultId);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.inf b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.inf
new file mode 100644
index 0000000..881aba3
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.inf
@@ -0,0 +1,30 @@
+##
+# Copyright (c) 2022, Konstantin Aladyshev <aladyshev22@gmail.com>
+#
+# SPDX-License-Identifier: MIT
+##
+
+[Defines]
+ INF_VERSION = 1.25
+ BASE_NAME = HIIFormDataElementsWithDefaultsSet
+ FILE_GUID = 162201c9-1208-4567-bab6-e9d32ae90e84
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HIIFormDataElementsWithDefaultsSetEntryPoint
+ UNLOAD_IMAGE = HIIFormDataElementsWithDefaultsSetUnload
+
+[Sources]
+ HIIFormDataElementsWithDefaultsSet.c
+ Strings.uni
+ Form.vfr
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiLessonsPkg/UefiLessonsPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiLib
+ HiiLib
+
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Strings.uni b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Strings.uni
new file mode 100644
index 0000000..10a410e
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_8/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Strings.uni
@@ -0,0 +1,46 @@
+//
+// Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+//
+// SPDX-License-Identifier: MIT
+//
+
+#langdef en-US "English"
+#langdef x-UEFI-OEM "OEM_NameSpace"
+
+#string FORMSET_TITLE #language en-US "Simple Formset"
+#string FORMSET_HELP #language en-US "This is a very simple formset"
+#string FORMID1_TITLE #language en-US "Simple Form"
+#string CHECKBOX_PROMPT #language en-US "Checkbox prompt"
+ #language x-UEFI-OEM "CheckboxKey"
+#string CHECKBOX_HELP #language en-US "Checkbox help"
+#string NUMERIC_PROMPT #language en-US "Numeric prompt"
+ #language x-UEFI-OEM "NumericKey"
+#string NUMERIC_HELP #language en-US "Numeric help"
+#string STRING_PROMPT #language en-US "String prompt"
+ #language x-UEFI-OEM "StringKey"
+#string STRING_HELP #language en-US "String help"
+#string DATE_PROMPT #language en-US "Date prompt"
+#string DATE_HELP #language en-US "Date help"
+#string TIME_PROMPT #language en-US "Time prompt"
+#string TIME_HELP #language en-US "Time help"
+#string ONEOF_PROMPT #language en-US "OneOf list prompt"
+#string ONEOF_HELP #language en-US "OneOf list help"
+#string ONEOF_OPTION1 #language en-US "OneOf list option 1"
+#string ONEOF_OPTION2 #language en-US "OneOf list option 2"
+#string ONEOF_OPTION3 #language en-US "OneOf list option 3"
+#string ORDERED_LIST_PROMPT #language en-US "Ordered list prompt"
+#string ORDERED_LIST_HELP #language en-US "Ordered list help"
+#string ORDERED_LIST_OPTION1 #language en-US "Ordered list option 1"
+#string ORDERED_LIST_OPTION2 #language en-US "Ordered list option 2"
+#string ORDERED_LIST_OPTION3 #language en-US "Ordered list option 3"
+#string WARNING_IF_PROMPT #language en-US "WarningIf prompt"
+#string NOSUBMIT_IF_PROMPT #language en-US "NoSubmitIf prompt"
+#string INCONSISTENT_IF_PROMPT #language en-US "InconsistentIf prompt"
+#string TEST_STRING #language en-US "EDKII"
+#string STRING_DEFAULT #language en-US "String default"
+#string STANDARD_DEFAULT_PROMPT #language en-US "Standard default"
+#string MFG_DEFAULT_PROMPT #language en-US "Manufacture default"
+#string BTN_STANDARD_DEFAULT_PROMPT #language en-US "Reset to standard default prompt"
+#string BTN_STANDARD_DEFAULT_HELP #language en-US "Reset to standard default help"
+#string BTN_MFG_DEFAULT_PROMPT #language en-US "Reset to manufacture default prompt"
+#string BTN_MFG_DEFAULT_HELP #language en-US "Reset to manufacture default help"
diff --git a/README.md b/README.md
index 089e735..cc43f58 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ These series of lessons are intendend to get you started with UEFI programming i
- [Lesson 28](Lessons/Lesson_28): Get ACPI tables and save them to files with a help of `EFI_SHELL_PROTOCOL`
- [Lesson 29](Lessons/Lesson_29): Use `EFI_ACPI_SDT_PROTOCOL` and `ShellLib` to save a BMP image from the ACPI BGRT table
- [Lesson 30](Lessons/Lesson_30): Find all PCI root bridges in the system with a help of `LocateHandleBuffer`/`OpenProtocol` functions and use
-`EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL` to get all PCI functions in the system.
+`EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL` to get all PCI functions in the system
- [Lesson 31](Lessons/Lesson_31): Search `pci.ids` database to get PCI Vendor/Device information with a help of `ShellLib`/`PrintLib` functions
- [Lesson 32](Lessons/Lesson_32): Show PCI Option ROM images with the help of `EFI_PCI_IO_PROTOCOL` protocol
- [Lesson 33](Lessons/Lesson_33): Use `EfiRom` utility for parsing and creation of PCI Option ROM images
@@ -44,7 +44,7 @@ These series of lessons are intendend to get you started with UEFI programming i
- [Lesson 38](Lessons/Lesson_38): Create and use your custom protocol. `InstallMultipleProtocolInterfaces` and `UninstallMultipleProtocolInterfaces` functions
- [Lesson 39](Lessons/Lesson_39): Create a driver that adds hot key functionality with a help of `RegisterKeyNotify`/`UnregisterKeyNotify` functions
- [Lesson 40](Lessons/Lesson_40): `Key####` NVRAM variables
-- [Lesson 41](Lessons/Lesson_41): `DEBUG` print statement internals. `EFI_D_*` log levels and all the PCDs for the `DEBUG` statement control. Getting and parsing OVMF boot log.
+- [Lesson 41](Lessons/Lesson_41): `DEBUG` print statement internals. `EFI_D_*` log levels and all the PCDs for the `DEBUG` statement control. Getting and parsing OVMF boot log
- [Lesson 42](Lessons/Lesson_42): Debug your drivers/applications and OVMF itself with GDB
- [Lesson 43](Lessons/Lesson_43): Intro to the HII. Create an application to display HII database content
- [Lesson 44](Lessons/Lesson_44): HII database internals
@@ -84,12 +84,13 @@ _____
- [Lesson XX](Lessons_uncategorized/Lesson_Configuration_Language_4): UEFI Configuration language. Explore `ExtractConfig` request syntax on custom forms
- [Lesson XX](Lessons_uncategorized/Lesson_Configuration_Language_5): UEFI Configuration language. Change form data with the `EFI_HII_CONFIG_ROUTING_PROTOCOL.RouteConfig()` function
- [Lesson XX](Lessons_uncategorized/Lesson_Configuration_Language_6): UEFI Configuration language. Keyword handler protocol. Get keyword values with the `EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL.GetData()` function
-- [Lesson XX](Lessons_uncategorized/Lesson_Configuration_Language_7): UEFI Configuration language. Keyword handler protocol. Add keywords to you Form elements. Use `EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL.SetData()` function to chage data referred by keywords.
+- [Lesson XX](Lessons_uncategorized/Lesson_Configuration_Language_7): UEFI Configuration language. Keyword handler protocol. Add keywords to you Form elements. Use `EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL.SetData()` function to chage data referred by keywords
+- [Lesson XX](Lessons_uncategorized/Lesson_Configuration_Language_8): Use `HiiSetToDefaults` function to set form elements to their default values non-interactively
_____
- [Lesson XX](Lessons_uncategorized/Lesson_ARCH): Architecture specifier in section names
- [Lesson XX](Lessons_uncategorized/Lesson_SKU): SKU specifier in section names
- [Lesson XX](Lessons_uncategorized/Lesson_Build_tools): Build tools configuration via `Conf/tools_def.txt` file and `[BuildOptions]` section usage in INF and DSC files
-- [Lesson XX](Lessons_uncategorized/Lesson_FDF): Intro to FDF file format. Flash Device Image `[FD]` sections: flash chip defines and regions definition. OVMF image FDF file analysis.
+- [Lesson XX](Lessons_uncategorized/Lesson_FDF): Intro to FDF file format. Flash Device Image `[FD]` sections: flash chip defines and regions definition. OVMF image FDF file analysis
- [Lesson XX](Lessons_uncategorized/Lesson_FDF_FV/README.md): Firmware Volume (`FV`), FFS, files. Create simple FV with `RAW` files
- [Lesson XX](Lessons_uncategorized/Lesson_FDF_FV_2/README.md): File sections - Part 1: `FREEFORM` file and `RAW` section type. FV build process (`GenSec`/`GenFfs`/`GenFv` tools)
- [Lesson XX](Lessons_uncategorized/Lesson_FDF_FV_3/README.md): File sections - Part 2: Other leaf sections: `USER_INTERFACE`/`VERSION`/`FREEFORM_SUBTYPE_GUID`/`PE32`/`PIC`/`COMPATIBILITY16`/`TE`/`DISPOSABLE`/`PEI_DEPEX`/`DXE_DEPEX`
diff --git a/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Data.h b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Data.h
new file mode 100644
index 0000000..2ba2665
--- /dev/null
+++ b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Data.h
@@ -0,0 +1,25 @@
+#ifndef _DATA_H_
+#define _DATA_H_
+
+#define FORMSET_GUID {0xdfdb4e02, 0x32ca, 0x4f50, {0xa1, 0xf1, 0x07, 0xdc, 0xfb, 0xf5, 0xb4, 0x5a}}
+#define DATAPATH_GUID {0xec8952af, 0x0779, 0x4e39, {0xb1, 0x6c, 0x69, 0x7c, 0xb3, 0xc7, 0x89, 0x0d}}
+#define STORAGE_GUID {0x430d7be9, 0x60bd, 0x4081, {0x99, 0xc1, 0x01, 0xf4, 0xf7, 0x1f, 0xdf, 0x80}}
+
+#define UEFI_VARIABLE_STRUCTURE_NAME L"FormData"
+
+#pragma pack(1)
+typedef struct {
+ UINT8 CheckboxValue;
+ UINT16 NumericValue;
+ CHAR16 StringValue[11];
+ EFI_HII_DATE DateValue;
+ EFI_HII_TIME TimeValue;
+ UINT8 OneOfValue;
+ UINT8 OrderedListValue[3];
+} UEFI_VARIABLE_STRUCTURE;
+#pragma pack()
+
+#define LABEL_START 0x1111
+#define LABEL_END 0x2222
+
+#endif
diff --git a/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Form.vfr b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Form.vfr
new file mode 100644
index 0000000..930a84a
--- /dev/null
+++ b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Form.vfr
@@ -0,0 +1,106 @@
+#include <Uefi/UefiMultiPhase.h>
+#include "Data.h"
+
+formset
+ guid = FORMSET_GUID,
+ title = STRING_TOKEN(FORMSET_TITLE),
+ help = STRING_TOKEN(FORMSET_HELP),
+
+ efivarstore UEFI_VARIABLE_STRUCTURE,
+ attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ name = FormData,
+ guid = STORAGE_GUID;
+
+ defaultstore StandardDefault,
+ prompt = STRING_TOKEN(STANDARD_DEFAULT_PROMPT),
+ attribute = 0x0000;
+
+ defaultstore ManufactureDefault,
+ prompt = STRING_TOKEN(MFG_DEFAULT_PROMPT),
+ attribute = 0x0001;
+
+ form
+ formid = 1,
+ title = STRING_TOKEN(FORMID1_TITLE);
+
+ checkbox
+ varid = FormData.CheckboxValue,
+ prompt = STRING_TOKEN(CHECKBOX_PROMPT),
+ help = STRING_TOKEN(CHECKBOX_HELP),
+ default = TRUE, defaultstore = StandardDefault,
+ default = FALSE, defaultstore = ManufactureDefault,
+ endcheckbox;
+
+ numeric
+ name = NumericQuestion,
+ varid = FormData.NumericValue,
+ prompt = STRING_TOKEN(NUMERIC_PROMPT),
+ help = STRING_TOKEN(NUMERIC_HELP),
+ flags = NUMERIC_SIZE_2 | DISPLAY_UINT_HEX,
+ //minimum = 0x1234,
+ //maximum = 0xaa55,
+ minimum = 0,
+ maximum = 10,
+ step = 1,
+ default = 7, defaultstore = StandardDefault,
+ default = 8, defaultstore = ManufactureDefault,
+ endnumeric;
+
+ string
+ name = StringQuestion,
+ varid = FormData.StringValue,
+ prompt = STRING_TOKEN(STRING_PROMPT),
+ help = STRING_TOKEN(STRING_HELP),
+ minsize = 5,
+ maxsize = 10,
+ default = STRING_TOKEN(STRING_DEFAULT), defaultstore = StandardDefault,
+ default = STRING_TOKEN(STRING_PROMPT), defaultstore = ManufactureDefault,
+ endstring;
+
+ date
+ varid = FormData.DateValue,
+ prompt = STRING_TOKEN(DATE_PROMPT),
+ help = STRING_TOKEN(DATE_HELP),
+ default = 2021/05/22,
+ enddate;
+
+ time
+ varid = FormData.TimeValue,
+ prompt = STRING_TOKEN(TIME_PROMPT),
+ help = STRING_TOKEN(TIME_HELP),
+ default = 23:55:33,
+ endtime;
+
+ oneof
+ name = OneOfQuestion,
+ varid = FormData.OneOfValue,
+ prompt = STRING_TOKEN(ONEOF_PROMPT),
+ help = STRING_TOKEN(ONEOF_HELP),
+ option text = STRING_TOKEN(ONEOF_OPTION1), value = 0x00, flags = 0;
+ option text = STRING_TOKEN(ONEOF_OPTION2), value = 0x33, flags = MANUFACTURING;
+ option text = STRING_TOKEN(ONEOF_OPTION3), value = 0x55, flags = DEFAULT;
+ endoneof;
+
+ orderedlist
+ varid = FormData.OrderedListValue,
+ prompt = STRING_TOKEN(ORDERED_LIST_PROMPT),
+ help = STRING_TOKEN(ORDERED_LIST_HELP),
+ option text = STRING_TOKEN(ORDERED_LIST_OPTION1), value = 0x0A, flags = 0;
+ option text = STRING_TOKEN(ORDERED_LIST_OPTION2), value = 0x0B, flags = 0;
+ option text = STRING_TOKEN(ORDERED_LIST_OPTION3), value = 0x0C, flags = 0;
+ default = {0x0c, 0x0b, 0x0a},
+ endlist;
+
+ resetbutton
+ defaultstore = StandardDefault,
+ prompt = STRING_TOKEN(BTN_STANDARD_DEFAULT_PROMPT),
+ help = STRING_TOKEN(BTN_STANDARD_DEFAULT_HELP),
+ endresetbutton;
+
+ resetbutton
+ defaultstore = ManufactureDefault,
+ prompt = STRING_TOKEN(BTN_MFG_DEFAULT_PROMPT),
+ help = STRING_TOKEN(BTN_MFG_DEFAULT_HELP),
+ endresetbutton;
+ endform;
+endformset;
diff --git a/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.c b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.c
new file mode 100644
index 0000000..c527510
--- /dev/null
+++ b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2022, Konstantin Aladyshev <aladyshev22@gmail.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include "Data.h"
+
+extern UINT8 FormBin[];
+
+#pragma pack(1)
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+#pragma pack()
+
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ DATAPATH_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH),
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+
+EFI_HII_HANDLE mHiiHandle = NULL;
+EFI_HANDLE mDriverHandle = NULL;
+EFI_STRING UEFIVariableName = UEFI_VARIABLE_STRUCTURE_NAME;
+EFI_GUID UEFIVariableGuid = STORAGE_GUID;
+
+
+EFI_STATUS
+EFIAPI
+HIIFormDataElementsWithDefaultsSetUnload (
+ EFI_HANDLE ImageHandle
+ )
+{
+ if (mHiiHandle != NULL)
+ HiiRemovePackages(mHiiHandle);
+
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ UEFI_VARIABLE_STRUCTURE EfiVarstore;
+
+ BufferSize = sizeof(UEFI_VARIABLE_STRUCTURE);
+ Status = gRT->GetVariable(
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ NULL,
+ &BufferSize,
+ &EfiVarstore);
+ if (!EFI_ERROR(Status)) {
+ Status = gRT->SetVariable(
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ 0,
+ 0,
+ NULL);
+ if (EFI_ERROR(Status)) {
+ Print(L"Error! Can't delete variable! %r\n", Status);
+ }
+ }
+
+ Status = gBS->UninstallMultipleProtocolInterfaces(
+ mDriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ NULL
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+HIIFormDataElementsWithDefaultsSetEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &mDriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ mHiiHandle = HiiAddPackages(
+ &gEfiCallerIdGuid,
+ mDriverHandle,
+ HIIFormDataElementsWithDefaultsSetStrings,
+ FormBin,
+ NULL
+ );
+ if (mHiiHandle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ UINTN BufferSize;
+ UEFI_VARIABLE_STRUCTURE EfiVarstore;
+ BufferSize = sizeof(UEFI_VARIABLE_STRUCTURE);
+ Status = gRT->GetVariable (
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ NULL,
+ &BufferSize,
+ &EfiVarstore);
+ if (EFI_ERROR(Status)) {
+ ZeroMem(&EfiVarstore, sizeof(EfiVarstore));
+ Status = gRT->SetVariable(
+ UEFIVariableName,
+ &UEFIVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(EfiVarstore),
+ &EfiVarstore);
+ if (EFI_ERROR(Status)) {
+ Print(L"Error! Can't create variable! %r\n", Status);
+ }
+ EFI_STRING ConfigStr = HiiConstructConfigHdr(&UEFIVariableGuid, UEFIVariableName, mDriverHandle);
+ UINT16 DefaultId = 0;
+ if (!HiiSetToDefaults(ConfigStr, DefaultId)) {
+ Print(L"Error! Can't set default configuration #%d\n", DefaultId);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.inf b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.inf
new file mode 100644
index 0000000..881aba3
--- /dev/null
+++ b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.inf
@@ -0,0 +1,30 @@
+##
+# Copyright (c) 2022, Konstantin Aladyshev <aladyshev22@gmail.com>
+#
+# SPDX-License-Identifier: MIT
+##
+
+[Defines]
+ INF_VERSION = 1.25
+ BASE_NAME = HIIFormDataElementsWithDefaultsSet
+ FILE_GUID = 162201c9-1208-4567-bab6-e9d32ae90e84
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HIIFormDataElementsWithDefaultsSetEntryPoint
+ UNLOAD_IMAGE = HIIFormDataElementsWithDefaultsSetUnload
+
+[Sources]
+ HIIFormDataElementsWithDefaultsSet.c
+ Strings.uni
+ Form.vfr
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiLessonsPkg/UefiLessonsPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiLib
+ HiiLib
+
diff --git a/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Strings.uni b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Strings.uni
new file mode 100644
index 0000000..10a410e
--- /dev/null
+++ b/UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/Strings.uni
@@ -0,0 +1,46 @@
+//
+// Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+//
+// SPDX-License-Identifier: MIT
+//
+
+#langdef en-US "English"
+#langdef x-UEFI-OEM "OEM_NameSpace"
+
+#string FORMSET_TITLE #language en-US "Simple Formset"
+#string FORMSET_HELP #language en-US "This is a very simple formset"
+#string FORMID1_TITLE #language en-US "Simple Form"
+#string CHECKBOX_PROMPT #language en-US "Checkbox prompt"
+ #language x-UEFI-OEM "CheckboxKey"
+#string CHECKBOX_HELP #language en-US "Checkbox help"
+#string NUMERIC_PROMPT #language en-US "Numeric prompt"
+ #language x-UEFI-OEM "NumericKey"
+#string NUMERIC_HELP #language en-US "Numeric help"
+#string STRING_PROMPT #language en-US "String prompt"
+ #language x-UEFI-OEM "StringKey"
+#string STRING_HELP #language en-US "String help"
+#string DATE_PROMPT #language en-US "Date prompt"
+#string DATE_HELP #language en-US "Date help"
+#string TIME_PROMPT #language en-US "Time prompt"
+#string TIME_HELP #language en-US "Time help"
+#string ONEOF_PROMPT #language en-US "OneOf list prompt"
+#string ONEOF_HELP #language en-US "OneOf list help"
+#string ONEOF_OPTION1 #language en-US "OneOf list option 1"
+#string ONEOF_OPTION2 #language en-US "OneOf list option 2"
+#string ONEOF_OPTION3 #language en-US "OneOf list option 3"
+#string ORDERED_LIST_PROMPT #language en-US "Ordered list prompt"
+#string ORDERED_LIST_HELP #language en-US "Ordered list help"
+#string ORDERED_LIST_OPTION1 #language en-US "Ordered list option 1"
+#string ORDERED_LIST_OPTION2 #language en-US "Ordered list option 2"
+#string ORDERED_LIST_OPTION3 #language en-US "Ordered list option 3"
+#string WARNING_IF_PROMPT #language en-US "WarningIf prompt"
+#string NOSUBMIT_IF_PROMPT #language en-US "NoSubmitIf prompt"
+#string INCONSISTENT_IF_PROMPT #language en-US "InconsistentIf prompt"
+#string TEST_STRING #language en-US "EDKII"
+#string STRING_DEFAULT #language en-US "String default"
+#string STANDARD_DEFAULT_PROMPT #language en-US "Standard default"
+#string MFG_DEFAULT_PROMPT #language en-US "Manufacture default"
+#string BTN_STANDARD_DEFAULT_PROMPT #language en-US "Reset to standard default prompt"
+#string BTN_STANDARD_DEFAULT_HELP #language en-US "Reset to standard default help"
+#string BTN_MFG_DEFAULT_PROMPT #language en-US "Reset to manufacture default prompt"
+#string BTN_MFG_DEFAULT_HELP #language en-US "Reset to manufacture default help"
diff --git a/UefiLessonsPkg/UefiLessonsPkg.dsc b/UefiLessonsPkg/UefiLessonsPkg.dsc
index 5397974..4b9b2ad 100644
--- a/UefiLessonsPkg/UefiLessonsPkg.dsc
+++ b/UefiLessonsPkg/UefiLessonsPkg.dsc
@@ -85,6 +85,7 @@
UefiLessonsPkg/HIIConfig/HIIConfig.inf
UefiLessonsPkg/HIIKeyword/HIIKeyword.inf
UefiLessonsPkg/HIIFormDataElementsWithKeywords/HIIFormDataElementsWithKeywords.inf
+ UefiLessonsPkg/HIIFormDataElementsWithDefaultsSet/HIIFormDataElementsWithDefaultsSet.inf
UefiLessonsPkg/FfsFile/FfsFile.inf
UefiLessonsPkg/SetSku/SetSku.inf