diff options
-rw-r--r-- | Lessons_uncategorized/Lesson_RegisterProtocolNotify/README.md | 470 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.c | 99 | ||||
-rw-r--r-- | UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.inf | 28 | ||||
-rw-r--r-- | UefiLessonsPkg/UefiLessonsPkg.dsc | 1 | ||||
-rw-r--r-- | bin/ProtocolEventDriver.efi | bin | 0 -> 9344 bytes |
6 files changed, 599 insertions, 0 deletions
diff --git a/Lessons_uncategorized/Lesson_RegisterProtocolNotify/README.md b/Lessons_uncategorized/Lesson_RegisterProtocolNotify/README.md new file mode 100644 index 0000000..72f4e65 --- /dev/null +++ b/Lessons_uncategorized/Lesson_RegisterProtocolNotify/README.md @@ -0,0 +1,470 @@ +In this lesson we would investigate the `EFI_BOOT_SERVICES.RegisterProtocolNotify()` function. This API can be usefull to create callbacks that are executed when certain protocols are installed in the system. + +For our investigation let's create a simple driver `ProtocolEventDriver`: +``` +./createNewDriver.sh ProtocolEventDriver +``` + +Add the following code to create a callback function `NotifyFunc` executed when the local `EFI_EVENT Event` is signaled: +```cpp +EFI_EVENT Event; +UINTN NotifyData = 0; + +VOID EFIAPI NotifyFunc(EFI_EVENT Event, VOID* Context) +{ + ... +} + + +EFI_STATUS +EFIAPI +ProtocolEventDriverUnload ( + EFI_HANDLE ImageHandle + ) +{ + gBS->CloseEvent(Event); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +ProtocolEventDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + Status = gBS->CreateEvent(EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + &NotifyFunc, + &NotifyData, + &Event); + if (EFI_ERROR(Status)) { + Print(L"Error! CreateEvent returned: %r\n", Status); + return Status; + } + + return EFI_SUCCESS; +} +``` + +Here we pass `UINTN NotifyData` to the callback function. Let's increment it inside the callback code, so we can understand how many times the callback was called: +```cpp + if (Context == NULL) + return; + + Print(L"\nEvent is signaled! Context = %d\n", *(UINTN*)Context); + *(UINTN*)Context += 1; +``` + +Right now no one can signal our event, therefore the callback code would never be executed. Let's register the protocol install notifier. Here we would monitor installation of our own `SIMPLE_CLASS_PROTOCOL` which we've created in the earlier lesson. + +In case you don't remember check out the protocol API in the `UefiLessonsPkg/Include/Protocol/SimpleClass.h` +```cpp +typedef +EFI_STATUS +(EFIAPI* SIMPLE_CLASS_GET_NUMBER)( + UINTN* Number + ); + + +typedef +EFI_STATUS +(EFIAPI* SIMPLE_CLASS_SET_NUMBER)( + UINTN Number + ); + + +struct _SIMPLE_CLASS_PROTOCOL { + SIMPLE_CLASS_GET_NUMBER GetNumber; + SIMPLE_CLASS_SET_NUMBER SetNumber; +}; +``` + +In the nutshell this protocol is a simple abstraction to the `UINTN Number` field. + +Now to the `RegisterProtocolNotify()`. Here is its description from the UEFI specification: +``` +EFI_BOOT_SERVICES.RegisterProtocolNotify() + +Summary: +Creates an event that is to be signaled whenever an interface is installed for a specified protocol. + +Prototype: +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY) ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration +); + +Parameters: +Protocol - The numeric ID of the protocol for which the event is to be registered +Event - Event that is to be signaled whenever a protocol interface is registered for Protocol. + The same EFI_EVENT may be used for multiple protocol notify registrations +Registration - A pointer to a memory location to receive the registration value. This value must be saved and used by the notification function + of Event to retrieve the list of handles that have added a protocol interface of type Protocol + +Description: +The RegisterProtocolNotify() function creates an event that is to be signaled whenever a protocol interface is installed for Protocol by InstallProtocolInterface() or EFI_BOOT_SERVICES.ReinstallProtocolInterface(). + +Once Event has been signaled, the EFI_BOOT_SERVICES.LocateHandle() function can be called to identify the newly installed, or reinstalled, handles that support Protocol. The Registration parameter in EFI_BOOT_SERVICES.RegisterProtocolNotify() corresponds to the SearchKey parameter in LocateHandle(). +``` + +And this is how we would use it: +```cpp +#include <Protocol/SimpleClass.h> + +STATIC VOID *mRegistrationTracker; + +EFI_STATUS +EFIAPI +ProtocolEventDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + ... + + Status = gBS->RegisterProtocolNotify(&gSimpleClassProtocolGuid, + Event, + &mRegistrationTracker); + if (EFI_ERROR(Status)) { + Print(L"Error! RegisterProtocolNotify returned: %r\n", Status); + return Status; + } + + return EFI_SUCCESS; +} +``` +Don't mind the `Registration` parameter for now, we'll investigate it later. + +Also don't forget to add the necessary code to the `INF` file to be able to use our `SIMPLE_CLASS_PROTOCOL` in the driver code: +``` +[Packages] + ... + UefiLessonsPkg/UefiLessonsPkg.dec + +[Protocols] + gSimpleClassProtocolGuid +``` + +Now when we load `SimpleClassProtocol.efi` driver (created in the earlier lesson) that installs the `SIMPLE_CLASS_PROTOCOL` protocol we would see that our callback code is executed: +``` +FS0:\> load ProtocolEventDriver.efi +Image 'FS0:\ProtocolEventDriver.efi' loaded at 6415000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 0 +, handle=640FB98 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 640C000 - Success +``` + +The strings +``` +Hello from SimpleClassProtocol driver +, handle=640FB98 +``` + +Are printed from the `SimpleClassProtocol` driver. Here is its code: +```cpp +EFI_STATUS +EFIAPI +SimpleClassProtocolDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + Print(L"Hello from SimpleClassProtocol driver"); + + EFI_STATUS Status = gBS->InstallMultipleProtocolInterfaces( + &mSimpleClassHandle, + &gSimpleClassProtocolGuid, + &mSimpleClass, + NULL + ); + if (!EFI_ERROR(Status)) + Print(L", handle=%p\n", mSimpleClassHandle); + else + Print(L"\n", mSimpleClassHandle); + + return Status; +} +``` + +You can see how the `\nEvent is signaled! Context = 0\n` from the `ProtocolEventDriver` was printed in between the prints of `SimpleClassProtocol` driver. That means that as soon as the `SIMPLE_CLASS_PROTOCOL` was installed, our callback was executed interrupting the `SimpleClassProtocol` driver code. + +You can execute the `load SimpleClassProtocol.efi` again and see that our callback would be called on each protocol install: +``` +FS0:\> load ProtocolEventDriver.efi +Image 'FS0:\ProtocolEventDriver.efi' loaded at 6415000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 0 +, handle=640FB98 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 640C000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 1 +, handle=641AB18 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 6408000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 2 +, handle=6419918 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 63E3000 - Success +``` + +You can also see that as we've coded earlier, the `UINTN NotifyData` (aka `Context`) is incremented on each callback execution. + +Now let's check the `dh` output: +``` +FS0:\> dh +... +A4: ImageDevicePath(..C1)/\ProtocolEventDriver.efi) LoadedImage(\ProtocolEventDriver.efi) +A5: ImageDevicePath(..C1)/\SimpleClassProtocol.efi) LoadedImage(\SimpleClassProtocol.efi) +A6: B5510EEA-6F11-4E4B-AD0F-35CE17BD7A67 +A7: ImageDevicePath(..C1)/\SimpleClassProtocol.efi) LoadedImage(\SimpleClassProtocol.efi) +A8: B5510EEA-6F11-4E4B-AD0F-35CE17BD7A67 +A9: ImageDevicePath(..C1)/\SimpleClassProtocol.efi) LoadedImage(\SimpleClassProtocol.efi) +AA: B5510EEA-6F11-4E4B-AD0F-35CE17BD7A67 +``` +You can see that each `load SimpleClassProtocol.efi` command installs a separate `SIMPLE_CLASS_PROTOCOL` protocol to the system. + +Now let's try to actually use the `SIMPLE_CLASS_PROTOCOL` inside the callback function. We would use the `gBS->LocateProtocol` to find the protocol and perform `+5` operation on its internal number via the protocol `SIMPLE_CLASS_GET_NUMBER/SIMPLE_CLASS_SET_NUMBER` functions. +```cpp +VOID EFIAPI NotifyFunc(EFI_EVENT Event, VOID* Context) +{ + ... + + EFI_STATUS Status; + SIMPLE_CLASS_PROTOCOL* SimpleClass; + Status = gBS->LocateProtocol(&gSimpleClassProtocolGuid, + NULL, + (VOID**)&SimpleClass); + if (EFI_ERROR(Status)) { + Print(L"Error! LocateProtocol returned: %r\n", Status); + return; + } + + UINTN Number; + Status = SimpleClass->GetNumber(&Number); + if (!EFI_ERROR(Status)) { + Print(L"Current number = %d\n", Number); + } else { + Print(L"Error! Can't get number: %r\n", Status); + return; + } + + Status = SimpleClass->SetNumber(Number+5); + if (EFI_ERROR(Status)) { + Print(L"Error! Can't set number: %r\n", Status); + return; + } +} +``` + +This is what we would get from this code: +``` +FS0:\> load ProtocolEventDriver.efi +Image 'FS0:\ProtocolEventDriver.efi' loaded at 6415000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 0 +Current number = 0 +, handle=640FB98 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 640C000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 1 +Current number = 5 +, handle=646A818 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 6408000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 2 +Current number = 10 +, handle=6419918 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 63E3000 - Success +``` + +You can see the problem here. Each time we perform `load SimpleClassProtocol.efi` we install additional protocol to the system. We saw that in the `dh` command output. +But `gBS->LocateProtocol` always finds the first installed protocol. So how can we call the callback code on the newly installed protocol that caused the callback in the first place? + +To fix that we can utilize `Registration` parameter of the `RegisterProtocolNotify/LocateProtocol` functions. + +With it the `LocateProtocol` function would return the next handle that is new for the registration. + +Here is a description of the `EFI_BOOT_SERVICES.LocateProtocol()` function from the specification. We've already saw it, and used it many times, but now pay attention to the `Registration` parameter: +``` +EFI_BOOT_SERVICES.LocateProtocol() + +Summary: +Returns the first protocol instance that matches the given protocol. + +Prototype: +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_PROTOCOL) ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface +); + +Parameters: +Protocol - Provides the protocol to search for +Registration - Optional registration key returned from EFI_BOOT_SERVICES.RegisterProtocolNotify(). If Registration is NULL, then it is ignored +Interface - On return, a pointer to the first interface that matches Protocol and Registration + +Description: +The LocateProtocol() function finds the first device handle that support Protocol, and returns a pointer to the protocol interface from that handle in Interface. If no protocol instances are found, then Interface is set to NULL. + +If Registration is not NULL, and there are no new handles for Registration, then EFI_NOT_FOUND is returned. +``` + +All we need to do now to fix the problem is to use `mRegistrationTracker` instead of `NULL` in the `gBS->LocateProtocol` call. In the nutshell the registration variable is used in 3 places: +```cpp +STATIC VOID *mRegistrationTracker; // <----- + +VOID EFIAPI NotifyFunc(EFI_EVENT Event, VOID* Context) +{ + ... + Status = gBS->LocateProtocol(&gSimpleClassProtocolGuid, + mRegistrationTracker, // <----- + (VOID**)&SimpleClass); + ... +} + +... + +EFI_STATUS +EFIAPI +ProtocolEventDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + ... + Status = gBS->RegisterProtocolNotify(&gSimpleClassProtocolGuid, + Event, + &mRegistrationTracker); // <----- + ... +} +``` + +Now on each callback we would work with the newly installed protocol: +``` +FS0:\> load ProtocolEventDriver.efi +Image 'FS0:\ProtocolEventDriver.efi' loaded at 6415000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 0 +Current number = 0 +, handle=640FB98 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 640C000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 1 +Current number = 0 +, handle=646C218 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 6408000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 2 +Current number = 0 +, handle=6419918 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 63E3000 - Success +``` + +# `EfiCreateProtocolNotifyEvent` + +To ease creation process of the protocol notification callbacks the [UefiLib](https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/UefiLib.h) offers a `EfiCreateProtocolNotifyEvent` function: +```cpp +/** + Creates and returns a notification event and registers that event with all the protocol + instances specified by ProtocolGuid. + + This function causes the notification function to be executed for every protocol of type + ProtocolGuid instance that exists in the system when this function is invoked. If there are + no instances of ProtocolGuid in the handle database at the time this function is invoked, + then the notification function is still executed one time. In addition, every time a protocol + of type ProtocolGuid instance is installed or reinstalled, the notification function is also + executed. This function returns the notification event that was created. + If ProtocolGuid is NULL, then ASSERT(). + If NotifyTpl is not a legal TPL value, then ASSERT(). + If NotifyFunction is NULL, then ASSERT(). + If Registration is NULL, then ASSERT(). + + + @param ProtocolGuid Supplies GUID of the protocol upon whose installation the event is fired. + @param NotifyTpl Supplies the task priority level of the event notifications. + @param NotifyFunction Supplies the function to notify when the event is signaled. + @param NotifyContext The context parameter to pass to NotifyFunction. + @param Registration A pointer to a memory location to receive the registration value. + This value is passed to LocateHandle() to obtain new handles that + have been added that support the ProtocolGuid-specified protocol. + + @return The notification event that was created. + +**/ +EFI_EVENT +EFIAPI +EfiCreateProtocolNotifyEvent ( + IN EFI_GUID *ProtocolGuid, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext OPTIONAL, + OUT VOID **Registration + ) +``` + +This API abstracts the calling of `CreateEvent/RegisterProtocolNotify` functions. + +Keep in mind that `EfiCreateProtocolNotifyEvent` also immediately signals the callback function `NotifyFunction` manually right after the `RegisterProtocolNotify` call. So your notification function can be executed even if there are no target protocols in the system. + +You can see how the `EfiCreateProtocolNotifyEvent` can simplify our main code: +```cpp +EFI_STATUS +EFIAPI +ProtocolEventDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + Event = EfiCreateProtocolNotifyEvent(&gSimpleClassProtocolGuid, + TPL_NOTIFY, + &NotifyFunc, + &NotifyData, + &mRegistrationTracker); + return EFI_SUCCESS; +} +``` + +If you'll test this application you'll see that opposed to our own code before, here the created event is signaled one time even when there are no `SIMPLE_CLASS_PROTOCOL` protocols in the system. +``` +FS0:\> load ProtocolEventDriver.efi + +Event is signaled! Context = 0 <------- +Error! LocateProtocol returned: Not Found <------- +Image 'FS0:\ProtocolEventDriver.efi' loaded at 6415000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 1 +Current number = 0 +, handle=640FB98 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 640C000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 2 +Current number = 0 +, handle=641A918 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 6408000 - Success +FS0:\> load SimpleClassProtocol.efi +Hello from SimpleClassProtocol driver +Event is signaled! Context = 3 +Current number = 0 +, handle=6419918 +Image 'FS0:\SimpleClassProtocol.efi' loaded at 63E3000 - Success +``` @@ -78,6 +78,7 @@ These series of lessons are intendend to get you started with UEFI programming i - [Lesson 72](Lessons/Lesson_72): Dynamically add elements to HII forms with a help of a `label` keyword - [Lesson 73](Lessons/Lesson_73): Setting defaults for the VFR questions: `default`/`defaultstore`/`resetbutton` keywords _____ +- [Lesson XX](Lessons_uncategorized/Lesson_RegisterProtocolNotify): Register protocol installation callbacks with the `EFI_BOOT_SERVICES.RegisterProtocolNotify()` and `EfiCreateProtocolNotifyEvent` functions - [Lesson XX](Lessons_uncategorized/Lesson_Configuration_Language_1): UEFI Configuration language. Dump current HII Database settings with the `EFI_HII_CONFIG_ROUTING_PROTOCOL.ExportConfig()` function - [Lesson XX](Lessons_uncategorized/Lesson_Configuration_Language_2): UEFI Configuration language. Create a function to prettify configuration string data - [Lesson XX](Lessons_uncategorized/Lesson_Configuration_Language_3): UEFI Configuration language. Extract individual form element configurations with the `EFI_HII_CONFIG_ROUTING_PROTOCOL.ExtractConfig()` function diff --git a/UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.c b/UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.c new file mode 100644 index 0000000..02ed0f9 --- /dev/null +++ b/UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024, Konstantin Aladyshev <aladyshev22@gmail.com> + * + * SPDX-License-Identifier: MIT + */ + +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +#include <Protocol/SimpleClass.h> + +EFI_EVENT Event; +STATIC VOID *mRegistrationTracker; +UINTN NotifyData = 0; + +VOID EFIAPI NotifyFunc(EFI_EVENT Event, VOID* Context) +{ + if (Context == NULL) + return; + + Print(L"\nEvent is signaled! Context = %d\n", *(UINTN*)Context); + *(UINTN*)Context += 1; + + SIMPLE_CLASS_PROTOCOL* SimpleClass; + EFI_STATUS Status; + Status = gBS->LocateProtocol(&gSimpleClassProtocolGuid, + // NULL, + mRegistrationTracker, + (VOID**)&SimpleClass); + if (EFI_ERROR(Status)) { + Print(L"Error! LocateProtocol returned: %r\n", Status); + return; + } + + UINTN Number; + Status = SimpleClass->GetNumber(&Number); + if (!EFI_ERROR(Status)) { + Print(L"Current number = %d\n", Number); + } else { + Print(L"Error! Can't get number: %r\n", Status); + return; + } + + Status = SimpleClass->SetNumber(Number+5); + if (EFI_ERROR(Status)) { + Print(L"Error! Can't set number: %r\n", Status); + return; + } +} + + +EFI_STATUS +EFIAPI +ProtocolEventDriverUnload ( + EFI_HANDLE ImageHandle + ) +{ + gBS->CloseEvent(Event); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +ProtocolEventDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + + EFI_STATUS Status; + + Status = gBS->CreateEvent(EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + &NotifyFunc, + &NotifyData, + &Event); + if (EFI_ERROR(Status)) { + Print(L"Error! CreateEvent returned: %r\n", Status); + return Status; + } + + Status = gBS->RegisterProtocolNotify(&gSimpleClassProtocolGuid, + Event, + &mRegistrationTracker); + if (EFI_ERROR(Status)) { + Print(L"Error! RegisterProtocolNotify returned: %r\n", Status); + return Status; + } + +/* + Event = EfiCreateProtocolNotifyEvent(&gSimpleClassProtocolGuid, + TPL_NOTIFY, + &NotifyFunc, + &NotifyData, + &mRegistrationTracker); +*/ + return EFI_SUCCESS; +} diff --git a/UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.inf b/UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.inf new file mode 100644 index 0000000..b05651f --- /dev/null +++ b/UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.inf @@ -0,0 +1,28 @@ +## +# Copyright (c) 2024, Konstantin Aladyshev <aladyshev22@gmail.com> +# +# SPDX-License-Identifier: MIT +## + +[Defines] + INF_VERSION = 1.25 + BASE_NAME = ProtocolEventDriver + FILE_GUID = 0b59d62a-3250-42eb-9859-364faf5bc9c8 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = ProtocolEventDriverEntryPoint + UNLOAD_IMAGE = ProtocolEventDriverUnload + +[Sources] + ProtocolEventDriver.c + +[Packages] + MdePkg/MdePkg.dec + UefiLessonsPkg/UefiLessonsPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiLib + +[Protocols] + gSimpleClassProtocolGuid diff --git a/UefiLessonsPkg/UefiLessonsPkg.dsc b/UefiLessonsPkg/UefiLessonsPkg.dsc index d0cc2df..970b5a6 100644 --- a/UefiLessonsPkg/UefiLessonsPkg.dsc +++ b/UefiLessonsPkg/UefiLessonsPkg.dsc @@ -93,6 +93,7 @@ UefiLessonsPkg/SetSku/SetSku.inf UefiLessonsPkg/HiddenSettings/HiddenSettings.inf UefiLessonsPkg/ShowHIIext/ShowHIIext.inf + UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.inf #[PcdsFixedAtBuild] # gUefiLessonsPkgTokenSpaceGuid.PcdInt8|0x88|UINT8|0x3B81CDF1 diff --git a/bin/ProtocolEventDriver.efi b/bin/ProtocolEventDriver.efi Binary files differnew file mode 100644 index 0000000..cd568ff --- /dev/null +++ b/bin/ProtocolEventDriver.efi |