From e6a90b38c0f25d94d9a874f20fbb63d3151da033 Mon Sep 17 00:00:00 2001 From: Konstantin Aladyshev Date: Mon, 21 Mar 2022 17:59:51 +0300 Subject: Add lesson 67 Signed-off-by: Konstantin Aladyshev --- Lessons/Lesson_67/Date1.png | Bin 0 -> 5652 bytes Lessons/Lesson_67/README.md | 85 +++++++++++++ Lessons/Lesson_67/Time1.png | Bin 0 -> 5944 bytes .../UefiLessonsPkg/HIIFormDataElements/Data.h | 18 +++ .../UefiLessonsPkg/HIIFormDataElements/Form.vfr | 54 ++++++++ .../HIIFormDataElements/HIIFormDataElements.c | 140 +++++++++++++++++++++ .../HIIFormDataElements/HIIFormDataElements.inf | 22 ++++ .../UefiLessonsPkg/HIIFormDataElements/Strings.uni | 21 ++++ 8 files changed, 340 insertions(+) create mode 100644 Lessons/Lesson_67/Date1.png create mode 100644 Lessons/Lesson_67/README.md create mode 100644 Lessons/Lesson_67/Time1.png create mode 100644 Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Data.h create mode 100644 Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Form.vfr create mode 100644 Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.c create mode 100644 Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.inf create mode 100644 Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Strings.uni (limited to 'Lessons/Lesson_67') diff --git a/Lessons/Lesson_67/Date1.png b/Lessons/Lesson_67/Date1.png new file mode 100644 index 0000000..92d4669 Binary files /dev/null and b/Lessons/Lesson_67/Date1.png differ diff --git a/Lessons/Lesson_67/README.md b/Lessons/Lesson_67/README.md new file mode 100644 index 0000000..5ad10a6 --- /dev/null +++ b/Lessons/Lesson_67/README.md @@ -0,0 +1,85 @@ +# `date` element + +`date` input element is used to store date (https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.6.9-vfr-date-statement-definition) + +Add this code to `UefiLessonsPkg/HIIFormDataElements/Form.vfr`: +``` +date + varid = FormData.DateValue, + prompt = STRING_TOKEN(DATE_PROMPT), + help = STRING_TOKEN(DATE_HELP), +enddate; +``` + +Add strings to `UefiLessonsPkg/HIIFormDataElements/Strings.uni` +``` +#string DATE_PROMPT #language en-US "Date prompt" +#string DATE_HELP #language en-US "Date help" +``` + +Date is encoded in special `EFI_HII_DATE` type (https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Uefi/UefiInternalFormRepresentation.h): +``` +typedef struct { + UINT16 Year; + UINT8 Month; + UINT8 Day; +} EFI_HII_DATE; +``` + +Therefore add it to our structure in `UefiLessonsPkg/HIIFormDataElements/Data.h`: +``` +typedef struct { + ... + EFI_HII_DATE DateValue; +} UEFI_VARIABLE_STRUCTURE; +``` + +This will result to this element: + +![Date1](Date1.png?raw=true "Date1") + +The value is displayed in `MM/DD/YYYY` format. So it is possible to store `02/20/2022`, but not `20/02/2022`. + +As for checks, even the leap year is checked. You can enter `02/29/2020`, but not `02/29/2021`. + +# `time` element + +`time` VFR input element is used to store time (https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.6.10-vfr-time-statement-definition) + +Add this code to `UefiLessonsPkg/HIIFormDataElements/Form.vfr`: +``` +time + varid = FormData.TimeValue, + prompt = STRING_TOKEN(TIME_PROMPT), + help = STRING_TOKEN(TIME_HELP), +endtime; +``` + +Add strings to `UefiLessonsPkg/HIIFormDataElements/Strings.uni` +``` +#string TIME_PROMPT #language en-US "Time prompt" +#string TIME_HELP #language en-US "Time help" +``` + +Time is encoded in special `EFI_HII_TIME` type (https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Uefi/UefiInternalFormRepresentation.h): +``` +typedef struct { + UINT8 Hour; + UINT8 Minute; + UINT8 Second; +} EFI_HII_TIME; +``` + +Therefore add it to our structure in `UefiLessonsPkg/HIIFormDataElements/Data.h`: +``` +typedef struct { + ... + EFI_HII_TIME TimeValue; +} UEFI_VARIABLE_STRUCTURE; +``` + +This will result to this element: + +![Time1](Time1.png?raw=true "Time1") + +As with `date` element HII Form Browser doesn't allow to set invalid time values. diff --git a/Lessons/Lesson_67/Time1.png b/Lessons/Lesson_67/Time1.png new file mode 100644 index 0000000..50493a1 Binary files /dev/null and b/Lessons/Lesson_67/Time1.png differ diff --git a/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Data.h b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Data.h new file mode 100644 index 0000000..89eee4e --- /dev/null +++ b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Data.h @@ -0,0 +1,18 @@ +#ifndef _DATA_H_ +#define _DATA_H_ + +#define FORMSET_GUID {0x531bc507, 0x9191, 0x4fa2, {0x94, 0x46, 0xb8, 0x44, 0xe3, 0x5d, 0xd1, 0x2a}} + +#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; +} UEFI_VARIABLE_STRUCTURE; +#pragma pack() + +#endif diff --git a/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Form.vfr b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Form.vfr new file mode 100644 index 0000000..c796243 --- /dev/null +++ b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Form.vfr @@ -0,0 +1,54 @@ +#include +#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 = FORMSET_GUID; + + form + formid = 1, + title = STRING_TOKEN(FORMID1_TITLE); + + checkbox + varid = FormData.CheckboxValue, + prompt = STRING_TOKEN(CHECKBOX_PROMPT), + help = STRING_TOKEN(CHECKBOX_HELP), + endcheckbox; + + numeric + varid = FormData.NumericValue, + prompt = STRING_TOKEN(NUMERIC_PROMPT), + help = STRING_TOKEN(NUMERIC_HELP), + flags = NUMERIC_SIZE_2 | DISPLAY_UINT_HEX, + minimum = 0x1234, + maximum = 0xaa55, + step = 2, + endnumeric; + + string + varid = FormData.StringValue, + prompt = STRING_TOKEN(STRING_PROMPT), + help = STRING_TOKEN(STRING_HELP), + minsize = 5, + maxsize = 10, + endstring; + + date + varid = FormData.DateValue, + prompt = STRING_TOKEN(DATE_PROMPT), + help = STRING_TOKEN(DATE_HELP), + enddate; + + time + varid = FormData.TimeValue, + prompt = STRING_TOKEN(TIME_PROMPT), + help = STRING_TOKEN(TIME_HELP), + endtime; + endform; +endformset; diff --git a/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.c b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.c new file mode 100644 index 0000000..5920b58 --- /dev/null +++ b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include +#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) + } + }, + FORMSET_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_STATUS +EFIAPI +HIIFormDataElementsUnload ( + 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, + &mHiiVendorDevicePath.VendorDevicePath.Guid, + NULL, + &BufferSize, + &EfiVarstore); + if (!EFI_ERROR(Status)) { + Status = gRT->SetVariable( + UEFIVariableName, + &mHiiVendorDevicePath.VendorDevicePath.Guid, + 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 +HIIFormDataElementsEntryPoint ( + 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; + } + + UINTN BufferSize; + UEFI_VARIABLE_STRUCTURE EfiVarstore; + BufferSize = sizeof(UEFI_VARIABLE_STRUCTURE); + Status = gRT->GetVariable ( + UEFIVariableName, + &mHiiVendorDevicePath.VendorDevicePath.Guid, + NULL, + &BufferSize, + &EfiVarstore); + if (EFI_ERROR(Status)) { + ZeroMem(&EfiVarstore, sizeof(EfiVarstore)); + Status = gRT->SetVariable( + UEFIVariableName, + &mHiiVendorDevicePath.VendorDevicePath.Guid, + 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); + } + } + + mHiiHandle = HiiAddPackages( + &gEfiCallerIdGuid, + mDriverHandle, + HIIFormDataElementsStrings, + FormBin, + NULL + ); + if (mHiiHandle == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.inf b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.inf new file mode 100644 index 0000000..b9c0652 --- /dev/null +++ b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.inf @@ -0,0 +1,22 @@ +[Defines] + INF_VERSION = 1.25 + BASE_NAME = HIIFormDataElements + FILE_GUID = ab971f73-f582-4f90-a48d-88ff7c884bd9 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = HIIFormDataElementsEntryPoint + UNLOAD_IMAGE = HIIFormDataElementsUnload + +[Sources] + HIIFormDataElements.c + Strings.uni + Form.vfr + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiLib + HiiLib diff --git a/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Strings.uni b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Strings.uni new file mode 100644 index 0000000..44c6aa6 --- /dev/null +++ b/Lessons/Lesson_67/UefiLessonsPkg/HIIFormDataElements/Strings.uni @@ -0,0 +1,21 @@ +// +// Copyright (c) 2021, Konstantin Aladyshev +// +// SPDX-License-Identifier: MIT +// + +#langdef en-US "English" + +#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" +#string CHECKBOX_HELP #language en-US "Checkbox help" +#string NUMERIC_PROMPT #language en-US "Numeric prompt" +#string NUMERIC_HELP #language en-US "Numeric help" +#string STRING_PROMPT #language en-US "String prompt" +#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" -- cgit v1.2.3-18-g5258