<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: bekoo</title>
    <description>The latest articles on DEV Community by bekoo (@bekoo).</description>
    <link>https://dev.to/bekoo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F545869%2F6daa2575-150d-4508-a9fd-e47b5d767588.jpeg</url>
      <title>DEV Community: bekoo</title>
      <link>https://dev.to/bekoo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bekoo"/>
    <language>en</language>
    <item>
      <title>Working on Single-Step Breakpoints in a Debugger</title>
      <dc:creator>bekoo</dc:creator>
      <pubDate>Wed, 03 Jun 2026 22:50:54 +0000</pubDate>
      <link>https://dev.to/bekoo/working-on-single-step-breakpoints-in-a-debugger-2f48</link>
      <guid>https://dev.to/bekoo/working-on-single-step-breakpoints-in-a-debugger-2f48</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Single-step breakpoints are fundamental debugging mechanism that allows execution to pause after every single instruction. Unlike hardware breakpoints which trigger at a specific address, single-step mode traces every instruction sequentially.&lt;/p&gt;

&lt;p&gt;In this post, we will see these breakpoints in detail with NASM + QEMU.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Single-Step Breakpoints and Trap Flag&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A debugger can determine single-step breakpoints with DR6 register. DR6 register holds BS (Single-Step Bit) and a debugger can use this bit. BS is 14 bit of DR6 register:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fii0b5yd0znaodrfp3dwf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fii0b5yd0znaodrfp3dwf.png" alt=" " width="800" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But that's not all. This bit just shows the breakpoint is triggered in 'single-step progress'. We can't change if we want 'single-step'. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TF (Trap Flag)&lt;/strong&gt; is the real mechanism behind single-step execution. It lives at bit 8 of the RFLAGS register and cannot be set directly with a MOV instruction. Instead, we manipulate it indirectly through the stack.&lt;/p&gt;

&lt;p&gt;When a #DB exception occurs, the CPU pushes the current RFLAGS onto &lt;br&gt;
the stack as part of the exception frame. This saved copy is what &lt;strong&gt;IRETQ&lt;/strong&gt; will restore when returning from the handler. By modifying bit 8 of this saved RFLAGS before executing IRETQ, we control whether single-step continues after the handler returns.&lt;/p&gt;

&lt;p&gt;The CPU automatically clears TF before delivering the #DB exception. This is by design — without this behavior, the handler itself would be single-stepped, causing an infinite recursive exception loop. By clearing TF on entry and only restoring it in the saved RFLAGS, we ensure single-step applies only to the code being debugged, not to the handler.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Simple Project in NASM&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here's an example from my NASM Project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DbHandler:
    push rax
    push rbx
    push rcx
    push rdx
    push rsi
    push rdi
    push rbp
    push r8
    push r9
    push r10
    push r11
    push r12
    push r13
    push r14
    push r15

    mov rbx, dr6

    ; Start single-step progress
    test rbx, (1 &amp;lt;&amp;lt; 0)
    jnz .hw_bp_hit

    ; BS set → single-step fired
    ; After the first execution of #DB (with TF=1),
    ; CPU will set BS bit of DR6
    test rbx, (1 &amp;lt;&amp;lt; 14)
    jnz .single_step


    jmp Exit

.hw_bp_hit:
    xor  rax, rax
    mov  dr6, rax
    xor  rax, rax
    mov  dr7, rax

    ; Enable TF flag and exit (CPU will generate #DB again)
    or   qword [rsp + 136], (1 &amp;lt;&amp;lt; 8)
    jmp  Exit

.single_step:
    ; In each single-step, write the value of RIP 
    mov rax, [rsp + 120]
    call serial_hex64

    dec qword [step_count]
    jz .stop_stepping

    ; Pass 1 to TF (for Single-Step)
    or qword [rsp + 136], (1 &amp;lt;&amp;lt; 8)
    jmp Exit

.stop_stepping:
    ; Pass 0 to stop
    and qword [rsp + 136], ~(1 &amp;lt;&amp;lt; 8)
    xor rax, rax
    mov dr6, rax
    jmp Exit

Exit:
    pop r15
    pop r14
    pop r13
    pop r12
    pop r11
    pop r10
    pop r9
    pop r8
    pop rbp
    pop rdi
    pop rsi
    pop rdx
    pop rcx
    pop rbx
    pop rax
    iretq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is simple: In the first execution of #DB exception, we set TF flag to 1 and exit from the handler. Then CPU generates #DB exception with BS=1. In the handler, we check this bit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; After the first execution of #DB (with TF=1),
; CPU will set BS bit of DR6
test rbx, (1 &amp;lt;&amp;lt; 14)
jnz .single_step
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;.single-step&lt;/strong&gt;, we just print the value of RIP, decrease the step_count and pass 1 to TF flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.single_step:
    ; In each single-step, write the value of RIP 
    mov rax, [rsp + 120]
    call serial_hex64

    ; step_count = 0x5
    dec qword [step_count]
    jz .stop_stepping

    ; Pass 1 to TF (for Single-Step)
    or qword [rsp + 136], (1 &amp;lt;&amp;lt; 8)
    jmp Exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, the idea is simple. Here's the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7my5t6om0aqkyusxv1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7my5t6om0aqkyusxv1y.png" alt=" " width="410" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I assigned the value 0x5 to the step_count variable, so each step is performed based on this value. Also my breakpoint is based on DebugTarget function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DebugTarget:
    mov  rax, 0x1
    mov  rbx, 0x2
    add  rax, rbx
    mov  rcx, rax
    mov  rdx, 0x0
    ret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>debugger</category>
      <category>debugging</category>
      <category>nasm</category>
      <category>assembly</category>
    </item>
    <item>
      <title>UEFI to Windows Communication via NVRAM Variables</title>
      <dc:creator>bekoo</dc:creator>
      <pubDate>Sun, 20 Jul 2025 21:19:28 +0000</pubDate>
      <link>https://dev.to/bekoo/uefi-to-windows-communication-via-nvram-variables-3lin</link>
      <guid>https://dev.to/bekoo/uefi-to-windows-communication-via-nvram-variables-3lin</guid>
      <description>&lt;p&gt;In this article, we will discuss how to establish communication between a UEFI driver and a Windows driver. Specifically, we’ll explore how to use NVRAM-based UEFI variables to exchange data between the two environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is NVRAM?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;NVRAM (Non-Volatile RAM) is a key component in UEFI-based systems, used to store persistent configuration and system state data. Unlike regular RAM, NVRAM retains its contents across reboots and power-offs, making it essential for managing firmware-level settings.&lt;/p&gt;

&lt;p&gt;In UEFI, NVRAM is organized into variables—structured key-value pairs that include metadata (attributes) defining how and when they can be accessed. These variables are used for critical system functions such as boot management, secure boot key storage, hardware configuration, and OEM-specific settings. &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;UEFI Variables&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;UEFI Variables &lt;strong&gt;is specified with a combination of a GUID and Unicode String&lt;/strong&gt;. The GUID of a variable can prevent name collisions between different vendors. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Boot Manager Chapter&lt;/strong&gt; of UEFI Specification defines the EFIGLOBAL_VARIABLE_GUID, also known &lt;em&gt;gEfiGlobalVariableGuid&lt;/em&gt; in EDK II. If we want to use a global variable, such as SecureBoot Status  in our UEFI Driver, we need to benefit from the gEfiGlobalVariableGuid. Here are some global variable list from &lt;a href="https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Guid/GlobalVariable.h" rel="noopener noreferrer"&gt;EDK II Repo&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;EFI_PLATFORM_LANG_CODES_VARIABLE_NAME  L"PlatformLangCodes"&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EFI_BOOT_CURRENT_VARIABLE_NAME  L"BootCurrent"&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EFI_SIGNATURE_SUPPORT_NAME  L"SignatureSupport"&lt;/strong&gt; 
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[...] &lt;/p&gt;

&lt;p&gt;Each UEFI Variable has attributes that the describe visibility persistence. Here's list of the attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;BOOTSERVICE_ACCESS&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The variable has permissions for write and read access at the pre-boot before &lt;strong&gt;ExitBootServices()&lt;/strong&gt; called, which means that the variable is not available after called ExitBootServices() and the contents of the variable will be deleted on the next system reset. &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;BOOTSERVICE_ACCESS | RUNTIME_ACCESS&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The variable has permissions for write and read access before ExitBootServices() called, but its contents will remain as &lt;strong&gt;read-only&lt;/strong&gt; when ExitBootServices() called, also the contents will be deleted on the next system reboot. &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;NON_VOLATILE | BOOTSERVICE_ACCESS&lt;/em&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The variable has permissions for write and read access before ExitBootServices() called and its contents are persistent through system reset. &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;NON_VOLATILE | BOOTSERVICE_ACCESS | RUNTIME_ACCESS&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The variable has permissions for write and read in both pre-boot and OS Runtime environment. Its contents are persistent through system reset. &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Access UEFI Variables with Services&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When a UEFI Driver store configuration information via UEFI Variables, it can access them with services provided by &lt;em&gt;EFI_HII_CONFIG_ACCESS_PROTOCOL&lt;/em&gt; The Services &lt;em&gt;SetVariable()&lt;/em&gt; and &lt;em&gt;GetVariable()&lt;/em&gt; are used to set and get configuration information. We will see these two services through the article. &lt;br&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1 - SetVariable()&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;SetVariable()&lt;/em&gt; service sets the contents of the variable, also it can be used to create a new variable, modify the variable or to delete an existing variable. Here are parameters of the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt; &lt;span class="k"&gt;typedef&lt;/span&gt;
 &lt;span class="n"&gt;EFI_STATUS&lt;/span&gt;
 &lt;span class="nf"&gt;SetVariable&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;CHAR16&lt;/span&gt;            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;VariableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_GUID&lt;/span&gt;          &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;VendorGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;UINT32&lt;/span&gt;            &lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;UINTN&lt;/span&gt;             &lt;span class="n"&gt;DataSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;VOID&lt;/span&gt;              &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a project for &lt;strong&gt;SetVariable&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiApplicationEntryPoint.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/PcdLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiBootServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiRuntimeServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;CHAR16&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;VariableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;L"MyUEFIVar"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;EFI_GUID&lt;/span&gt; &lt;span class="n"&gt;VendorGuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mh"&gt;0xa1b2c3d4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x5678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mh"&gt;0x9a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xbc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xde&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x67&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x89&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="n"&gt;UINT8&lt;/span&gt; &lt;span class="n"&gt;ContentOfVariable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mh"&gt;0xDE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xAD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xBE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xEF&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="n"&gt;UINTN&lt;/span&gt; &lt;span class="n"&gt;DataSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContentOfVariable&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;Attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_NON_VOLATILE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="n"&gt;EFI_VARIABLE_BOOTSERVICE_ACCESS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="n"&gt;EFI_VARIABLE_RUNTIME_ACCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


  &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gRT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SetVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;VariableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VendorGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;DataSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ContentOfVariable&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFI_ERROR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"Write Operation Failed!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"The content successfully written!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code, we wrote the content of ContentOfVariable. Firstly, we created a variable name, GUID and values for UEFI Variable, then we executed the SetVariable. As a result of these processes, our UEFI Variable has these information: &lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UEFI Variable Name: &lt;strong&gt;MyUEFIVar&lt;/strong&gt; 
&lt;/li&gt;
&lt;li&gt;GUID: &lt;strong&gt;A1B2C3D4-1234-5678-9ABC-DEF123456789&lt;/strong&gt; 
&lt;/li&gt;
&lt;li&gt;Content: &lt;strong&gt;0xDEADBEEF&lt;/strong&gt; 
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5p2m9towf4bm5b5c9xq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5p2m9towf4bm5b5c9xq.png" alt=" " width="308" height="102"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can access it with these information. &lt;/p&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;2 - GetVariable()&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;GetVariable()&lt;/em&gt; service get content of the variable. Here are parameters of the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt;
&lt;span class="nf"&gt;GetVariable&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;CHAR16&lt;/span&gt;           &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;VariableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_GUID&lt;/span&gt;         &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;VendorGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;OUT&lt;/span&gt; &lt;span class="n"&gt;UINT32&lt;/span&gt;          &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt; &lt;span class="n"&gt;OPTIONAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;OUT&lt;/span&gt; &lt;span class="n"&gt;UINTN&lt;/span&gt;        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;DataSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;OUT&lt;/span&gt; &lt;span class="n"&gt;VOID&lt;/span&gt;            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;OPTIONAL&lt;/span&gt;
 &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's develop the project with GetVariable service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiApplicationEntryPoint.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/PcdLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiBootServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiRuntimeServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;CHAR16&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;VariableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;L"MyUEFIVar"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;EFI_GUID&lt;/span&gt; &lt;span class="n"&gt;VendorGuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mh"&gt;0xa1b2c3d4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x5678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mh"&gt;0x9a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xbc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xde&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x67&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x89&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="n"&gt;UINT8&lt;/span&gt; &lt;span class="n"&gt;ContentOfVariable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mh"&gt;0xDE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xAD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xBE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xEF&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="n"&gt;UINTN&lt;/span&gt; &lt;span class="n"&gt;DataSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContentOfVariable&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;Attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_NON_VOLATILE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="n"&gt;EFI_VARIABLE_BOOTSERVICE_ACCESS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="n"&gt;EFI_VARIABLE_RUNTIME_ACCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


  &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gRT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SetVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;VariableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VendorGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;DataSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ContentOfVariable&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFI_ERROR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"Failed to write!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"The content successfully written!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;UINT8&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="n"&gt;DataSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gRT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;GetVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;VariableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VendorGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;DataSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFI_ERROR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"Failed to read the variable!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DataSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"Content: 0x%02x&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After &lt;strong&gt;SetVariable&lt;/strong&gt; called, we called GetVariable service to get content of the our UEFI Variable, then we printed the result. Here's the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30hdkysywu6gbixsz5gu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30hdkysywu6gbixsz5gu.png" alt=" " width="280" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now we can focus our Windows Driver. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Coding Windows Driver&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Essentially there's a routine which we can use for our purpose in ntoskrnl. &lt;strong&gt;ExGetFirmwareEnvironmentVariable&lt;/strong&gt; can be used to read UEFI Variables. So coding of the windows driver will not be difficult. We can call this routine with UEFI Variable information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;ntddk.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;NTSTATUS&lt;/span&gt; &lt;span class="nf"&gt;DriverUnload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PDRIVER_OBJECT&lt;/span&gt; &lt;span class="n"&gt;DriverObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UNREFERENCED_PARAMETER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DriverObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;DbgPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Driver unloaded.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;NTSTATUS&lt;/span&gt; &lt;span class="nf"&gt;DriverEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PDRIVER_OBJECT&lt;/span&gt; &lt;span class="n"&gt;DriverObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PUNICODE_STRING&lt;/span&gt; &lt;span class="n"&gt;RegistryPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UNREFERENCED_PARAMETER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RegistryPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;DriverObject&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;DriverUnload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DriverUnload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;UNICODE_STRING&lt;/span&gt; &lt;span class="n"&gt;VariableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RTL_CONSTANT_STRING&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"MyUEFIVar"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;UINT8&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;ULONG&lt;/span&gt; &lt;span class="n"&gt;BufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;GUID&lt;/span&gt; &lt;span class="n"&gt;VendorGuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mh"&gt;0xa1b2c3d4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x5678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mh"&gt;0x9a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xbc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xde&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x67&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x89&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;NTSTATUS&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ExGetFirmwareEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VariableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VendorGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;BufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;NT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;DbgPrintEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Failed to Read Data!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ULONG&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;BufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;DbgPrintEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"The value from UEFI Variable: 0x%02x&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the project, we accessed the content of the our UEFI Variable with ExGetFirmwareEnvironmentVariable routine. Here's result: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdxnopxwqwklzf1a12fhl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdxnopxwqwklzf1a12fhl.png" alt=" " width="508" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When ExGetFirmwareEnvironmentVariable called, The following routines are called after the routine: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u4uh6jb3hnrtnv04s8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u4uh6jb3hnrtnv04s8n.png" alt=" " width="800" height="930"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First of all it calls &lt;strong&gt;ExpGetFirmwareEnvironmentVariable&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0nmurpujfa9j2ow98koi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0nmurpujfa9j2ow98koi.png" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then the parameters of the ExGetFirmwareEnvironmentVariable are passed to IoGetEnvironmentVariableEx:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngop2d72jht8804cc33m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngop2d72jht8804cc33m.png" alt=" " width="416" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Creating UEFI Variable from Windows Driver&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Also we can create and set UEFI Variable from Windows Driver. &lt;strong&gt;ExSetFirmwareEnvironmentVariable&lt;/strong&gt; can be used for these purpose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;ntddk.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#pragma warning(disable: 4057)
&lt;/span&gt;
&lt;span class="cp"&gt;#define EFI_VARIABLE_NON_VOLATILE        0x00000001
#define EFI_VARIABLE_BOOTSERVICE_ACCESS  0x00000002
#define EFI_VARIABLE_RUNTIME_ACCESS      0x00000004
&lt;/span&gt;
&lt;span class="n"&gt;NTSTATUS&lt;/span&gt; &lt;span class="nf"&gt;DriverUnload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PDRIVER_OBJECT&lt;/span&gt; &lt;span class="n"&gt;DriverObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UNREFERENCED_PARAMETER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DriverObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;DbgPrintEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Driver unloaded.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;NTSTATUS&lt;/span&gt; &lt;span class="nf"&gt;DriverEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PDRIVER_OBJECT&lt;/span&gt; &lt;span class="n"&gt;DriverObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PUNICODE_STRING&lt;/span&gt; &lt;span class="n"&gt;RegistryPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UNREFERENCED_PARAMETER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RegistryPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;DriverObject&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;DriverUnload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DriverUnload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;UNICODE_STRING&lt;/span&gt; &lt;span class="n"&gt;VariableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RTL_CONSTANT_STRING&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"YUPIIIIIII"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;WCHAR&lt;/span&gt; &lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;L"HELLOOO from Windows!!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;ULONG&lt;/span&gt; &lt;span class="n"&gt;BufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;GUID&lt;/span&gt; &lt;span class="n"&gt;VendorGuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mh"&gt;0xa1b2c3d4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x5678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mh"&gt;0x9a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xbc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xde&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x67&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x89&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;NTSTATUS&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;Attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_NON_VOLATILE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_BOOTSERVICE_ACCESS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_RUNTIME_ACCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ExSetFirmwareEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VariableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VendorGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;NT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;DbgPrintEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Failed to write the value! Error Code: 0x%x&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;DbgPrintEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Done!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And UEFI Driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiApplicationEntryPoint.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/PcdLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiBootServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiRuntimeServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;CHAR16&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;VariableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;L"YUPIIIIIII"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;EFI_GUID&lt;/span&gt; &lt;span class="n"&gt;VendorGuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mh"&gt;0xa1b2c3d4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x5678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mh"&gt;0x9a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xbc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xde&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0xf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x67&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x89&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="n"&gt;CHAR16&lt;/span&gt; &lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="n"&gt;UINTN&lt;/span&gt; &lt;span class="n"&gt;DataSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;Attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_NON_VOLATILE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="n"&gt;EFI_VARIABLE_BOOTSERVICE_ACCESS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="n"&gt;EFI_VARIABLE_RUNTIME_ACCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gRT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;GetVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VariableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;VendorGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;DataSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFI_ERROR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"Failed to read the data!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"The Content: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foam21nu15p8g5e5b6sig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foam21nu15p8g5e5b6sig.png" alt=" " width="310" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this article, we demonstrated how UEFI and Windows drivers can communicate with each other using NVRAM variables. By leveraging SetVariable and GetVariable in UEFI, and ExGetFirmwareEnvironmentVariable / ExSetFirmwareEnvironmentVariable in Windows, we established a persistent and reliable data channel between the two environments.&lt;/p&gt;

&lt;p&gt;This method enables developers to build seamless integrations between firmware and the OS, allowing for flexible configurations, feature toggles, or telemetry mechanisms across reboots.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;References&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://uefi.org/specs/UEFI/2.10/08_Services_Runtime_Services.html" rel="noopener noreferrer"&gt;UEFI.org - Runtime Services&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://tianocore-docs.github.io/edk2-UefiDriverWritersGuide/draft/5_uefi_services/52_services_that_uefi_drivers_rarely_use/525_getvariable_and_setvariable.html" rel="noopener noreferrer"&gt;TianoCore Docs - GetVariable() and SetVariable()&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>uefi</category>
      <category>edk2</category>
      <category>windev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
