aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Aladyshev <aladyshev22@gmail.com>2022-09-23 17:48:09 +0300
committerKonstantin Aladyshev <aladyshev22@gmail.com>2022-09-23 17:48:09 +0300
commitcd5821d17e5988fcc214f34e71bf1c89ffc85e6d (patch)
treebdde2ef0c1e51c9f07abe97102a40988631ca7c5
parent7b373744d2d69c362a371533650c13fdb9f5cf82 (diff)
downloadUEFI-Lessons-cd5821d17e5988fcc214f34e71bf1c89ffc85e6d.tar.gz
UEFI-Lessons-cd5821d17e5988fcc214f34e71bf1c89ffc85e6d.tar.bz2
UEFI-Lessons-cd5821d17e5988fcc214f34e71bf1c89ffc85e6d.zip
EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL.SetData() lesson
Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_7/1.pngbin0 -> 8611 bytes
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_7/2.pngbin0 -> 8682 bytes
-rw-r--r--Lessons_uncategorized/Lesson_Configuration_Language_7/README.md202
-rw-r--r--README.md1
4 files changed, 203 insertions, 0 deletions
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_7/1.png b/Lessons_uncategorized/Lesson_Configuration_Language_7/1.png
new file mode 100644
index 0000000..82d2d45
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_7/1.png
Binary files differ
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_7/2.png b/Lessons_uncategorized/Lesson_Configuration_Language_7/2.png
new file mode 100644
index 0000000..911f0bf
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_7/2.png
Binary files differ
diff --git a/Lessons_uncategorized/Lesson_Configuration_Language_7/README.md b/Lessons_uncategorized/Lesson_Configuration_Language_7/README.md
new file mode 100644
index 0000000..769186a
--- /dev/null
+++ b/Lessons_uncategorized/Lesson_Configuration_Language_7/README.md
@@ -0,0 +1,202 @@
+In this lesson we would investigate how to modify form elements that have keyword references.
+
+But rather than change some system variables let's add keyword references to our own application.
+
+# Adding keywords to form elements
+
+For an example let's take our `HIIFormDataElements` driver. Adding keywords is very simple. The only file that we would need to modify is UNI file (`Strings.uni` in this case).
+
+First we need to add a new namespace id. It is added via the new language definition with an identificator in a format `x-UEFI-*`. Let's use `x-UEFI-OEM` in our case. The language text representation is not important, here we use `"OEM_NameSpace"` as a placeholder:
+```
+#langdef x-UEFI-OEM "OEM_NameSpace"
+```
+
+Now we need to add `#language x-UEFI-OEM "<...>"` string translations to the prompts of all form elements that we want to refer by keywords. For example let's add keys to the Checkbox, Numeric and String elements:
+```
+...
+#string CHECKBOX_PROMPT #language en-US "Checkbox prompt"
+ #language x-UEFI-OEM "CheckboxKey"
+#string NUMERIC_PROMPT #language en-US "Numeric prompt"
+ #language x-UEFI-OEM "NumericKey"
+#string STRING_PROMPT #language en-US "String prompt"
+ #language x-UEFI-OEM "StringKey"
+...
+```
+The provided values inside these translation strings would act as keywords for these elements. Just in case, it is completely allowed to use space `" "` inside a key name.
+
+Now build the updated driver and load it in the UEFI shell. Here I've decided to create a new driver `HIIFormDataElementsWithKeywords` to keep some separation between the lessons, but generally it is just a copy of `HIIFormDataElements.efi` with the modifications described above:
+```
+FS0:\> load HIIFormDataElementsWithKeywords.efi
+Image 'FS0:\HIIFormDataElementsWithKeywords.efi' loaded at 6880000 - Success
+```
+
+Now use `HIIKeyword` application to dump all the keys of our new namespace:
+```
+FS0:\> HIIKeyword.efi get "NAMESPACE=x-UEFI-OEM" ""
+Response: NAMESPACE=x-UEFI-OEM&PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400&KEYWORD=CheckboxKey&VALUE=00&NAMESPACE=x-UEFI-OEM&PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400&KEYWORD=NumericKey&VALUE=0000&NAMESPACE=x-UEFI-OEM&PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400&KEYWORD=StringKey&VALUE=000000<...>
+
+
+NAMESPACE=x-UEFI-OEM
+PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400 (VenHw(C299F575-F1DD-4D7D-B7AA-E5064B3ECBD7))
+KEYWORD=CheckboxKey
+VALUE=00
+00 | .
+
+NAMESPACE=x-UEFI-OEM
+PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400 (VenHw(C299F575-F1DD-4D7D-B7AA-E5064B3ECBD7))
+KEYWORD=NumericKey
+VALUE=0000
+00 00 | ..
+
+NAMESPACE=x-UEFI-OEM
+PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400 (VenHw(C299F575-F1DD-4D7D-B7AA-E5064B3ECBD7))
+KEYWORD=StringKey
+VALUE=0000000000000000000000000000000000000000
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
+00 00 00 00 | ....
+
+```
+
+You can verify that it is possible to access individual keys:
+```
+FS0:\> HIIKeyword.efi get "NAMESPACE=x-UEFI-OEM" "KEYWORD=NumericKey"
+Response: NAMESPACE=x-UEFI-OEM&PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400&KEYWORD=NumericKey&VALUE=0000
+
+
+NAMESPACE=x-UEFI-OEM
+PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400 (VenHw(C299F575-F1DD-4D7D-B7AA-E5064B3ECBD7))
+KEYWORD=NumericKey
+VALUE=0000
+00 00 | ..
+
+```
+
+# Use `EFI_KEYWORD_HANDLER_PROTOCOL.SetData()` to modify keyword data
+
+Now we are ready to add support for keyword data modification to the `HIIKeyword` application. For this we will need `SetData()` function from the `EFI_KEYWORD_HANDLER_PROTOCOL`:
+```cpp
+EFI_KEYWORD_HANDLER_PROTOCOL.SetData()
+
+Summary:
+Set the data associated with a particular configuration namespace keyword.
+
+Prototype:
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KEYWORD_HANDLER _SET_DATA) (
+ IN EFI_KEYWORD_HANDLER_PROTOCOL *This,
+ IN CONST EFI_STRING KeywordString,
+ OUT EFI_STRING *Progress,
+ OUT UINT32 *ProgressErr
+ );
+
+Parameters:
+This Pointer to the EFI_KEYWORD_HANDLER _PROTOCOL instance.
+KeywordString A null-terminated string in <MultiKeywordResp> format.
+Progress On return, points to a character in the KeywordString. Points to the string’s NULL terminator if the request was successful.
+ Points to the most recent ‘&’ before the first failing name / value pair (or the beginning of the string if the failure is in the first name / value pair) if the request was not successful.
+ProgressErr If during the processing of the KeywordString there was a failure, this parameter gives additional information about the possible source of the problem.
+
+Description:
+This function accepts a <MultiKeywordResp> formatted string, finds the associated keyword owners, creates a <MultiConfigResp> string from it and forwards it to the EFI_HII_ROUTING_PROTOCOL.RouteConfig function.
+```
+
+The call signature of our program would be modified like this:
+```cpp
+VOID Usage()
+{
+ Print(L"Usage:\n");
+ Print(L"HIIKeyword get <NamespaceStr> <KeywordStr>\n");
+ Print(L"HIIKeyword set <KeywordStr>\n");
+}
+```
+
+The support code is even simplier than in the `HIIKeyword get <...>` case:
+```cpp
+EFI_STRING Progress;
+UINT32 ProgressErr;
+if (!StrCmp(Argv[1], L"get")) {
+ <...>
+} else if (!StrCmp(Argv[1], L"set")) {
+ if (Argc != 3) {
+ Print(L"Wrong argument!\n");
+ Usage();
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = gHiiConfigKeywordHandler->SetData(gHiiConfigKeywordHandler,
+ Argv[2],
+ &Progress,
+ &ProgressErr);
+ if (StrCmp(Progress, L'\0')) {
+ Print(L"Part of string was unparsed %s\n", Progress);
+ }
+ if (ProgressErr) {
+ Print(L"Error! ProgressErr=%s\n", ProgressErrorStr(ProgressErr));
+ }
+ if (EFI_ERROR(Status)) {
+ Print(L"Error! SetData returned %r\n", Status);
+ return Status;
+ }
+} else {
+ Print(L"Wrong argument!\n");
+ Usage();
+ return EFI_INVALID_PARAMETER;
+}
+```
+
+So let's rebuild `HIIKeyword.efi` and test this new functionality. Once again first load our custom form driver:
+```
+FS0:\> load HIIFormDataElementsWithKeywords.efi
+Image 'FS0:\HIIFormDataElementsWithKeywords.efi' loaded at 6880000 - Success
+```
+Now with the `HIIKeyword.efi` try to change numeric element value to 7:
+```
+FS0:\> HIIKeyword.efi set "NAMESPACE=x-UEFI-OEM&KEYWORD=NumericKey&VALUE=0007"
+```
+Verify that the modification was completed successfully:
+```
+FS0:\> HIIKeyword.efi get "NAMESPACE=x-UEFI-OEM" "KEYWORD=NumericKey"
+Response: NAMESPACE=x-UEFI-OEM&PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400&KEYWORD=NumericKey&VALUE=0007
+
+
+NAMESPACE=x-UEFI-OEM
+PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400 (VenHw(C299F575-F1DD-4D7D-B7AA-E5064B3ECBD7))
+KEYWORD=NumericKey
+VALUE=0007
+07 00 | ..
+```
+
+If you want to, you can even check the form browser:
+
+![1](1.png?raw=true "1")
+
+I want to point out that like in the `RouteConfig()` case, modification through the `EFI_KEYWORD_HANDLER_PROTOCOL.SetData()` call bypasses some of the VFR checks. For example even if the current numeric value limits are `0..10`
+```
+numeric
+ ...
+ minimum = 0,
+ maximum = 10,
+ ...
+endnumeric;
+```
+it is still possible to change it to something like `0xABCD` like this:
+```
+FS0:\> HIIKeyword.efi set "NAMESPACE=x-UEFI-OEM&KEYWORD=NumericKey&VALUE=ABCD"
+```
+Once again you can verify updated value with our program:
+```
+FS0:\> HIIKeyword.efi get "NAMESPACE=x-UEFI-OEM" "KEYWORD=NumericKey"
+Response: NAMESPACE=x-UEFI-OEM&PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400&KEYWORD=NumericKey&VALUE=abcd
+
+
+NAMESPACE=x-UEFI-OEM
+PATH=0104140075f599c2ddf17d4db7aae5064b3ecbd77fff0400 (VenHw(C299F575-F1DD-4D7D-B7AA-E5064B3ECBD7))
+KEYWORD=NumericKey
+VALUE=abcd
+CD AB | ..
+```
+Or with the form browser:
+
+![2](2.png?raw=true "2")
+
diff --git a/README.md b/README.md
index 2e47495..089e735 100644
--- a/README.md
+++ b/README.md
@@ -84,6 +84,7 @@ _____
- [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_ARCH): Architecture specifier in section names
- [Lesson XX](Lessons_uncategorized/Lesson_SKU): SKU specifier in section names