From c28cd7e7867f856318c121a15f73f2b499dd2bb9 Mon Sep 17 00:00:00 2001
From: Konstantin Aladyshev <aladyshev22@gmail.com>
Date: Mon, 21 Mar 2022 17:18:32 +0300
Subject: Add lesson 66

Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
---
 .../UefiLessonsPkg/HIIFormDataElements/Data.h      |  16 +++
 .../UefiLessonsPkg/HIIFormDataElements/Form.vfr    |  34 +++++
 .../HIIFormDataElements/HIIFormDataElements.c      | 140 +++++++++++++++++++++
 .../HIIFormDataElements/HIIFormDataElements.inf    |  22 ++++
 .../UefiLessonsPkg/HIIFormDataElements/Strings.uni |  17 +++
 5 files changed, 229 insertions(+)
 create mode 100644 Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Data.h
 create mode 100644 Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Form.vfr
 create mode 100644 Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.c
 create mode 100644 Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.inf
 create mode 100644 Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Strings.uni

(limited to 'Lessons/Lesson_66/UefiLessonsPkg')

diff --git a/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Data.h b/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Data.h
new file mode 100644
index 0000000..80bd3dc
--- /dev/null
+++ b/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Data.h
@@ -0,0 +1,16 @@
+#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];
+} UEFI_VARIABLE_STRUCTURE;
+#pragma pack()
+
+#endif
diff --git a/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Form.vfr b/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Form.vfr
new file mode 100644
index 0000000..42affd4
--- /dev/null
+++ b/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Form.vfr
@@ -0,0 +1,34 @@
+#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  = 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;
+  endform;
+endformset;
diff --git a/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.c b/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.c
new file mode 100644
index 0000000..5920b58
--- /dev/null
+++ b/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.c
@@ -0,0 +1,140 @@
+#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)
+      }
+    },
+    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_66/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.inf b/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements.inf
new file mode 100644
index 0000000..b9c0652
--- /dev/null
+++ b/Lessons/Lesson_66/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_66/UefiLessonsPkg/HIIFormDataElements/Strings.uni b/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Strings.uni
new file mode 100644
index 0000000..4e283e1
--- /dev/null
+++ b/Lessons/Lesson_66/UefiLessonsPkg/HIIFormDataElements/Strings.uni
@@ -0,0 +1,17 @@
+//
+// Copyright (c) 2021, Konstantin Aladyshev <aladyshev22@gmail.com>
+//
+// 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"
-- 
cgit v1.2.3-18-g5258