ReactOS 0.4.15-dev-7108-g1cf6ce6
UEFIFirmware.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Tests for UEFI Firmware functions
5 * COPYRIGHT: Copyright 2023 Ratin Gao <ratin@knsoft.org>
6 */
7
8#include "precomp.h"
9
10#include <ndk/psfuncs.h>
11#include <ndk/setypes.h>
12#include <ndk/sefuncs.h>
13#include <ndk/obfuncs.h>
14
15#define _A2W(quote) __A2W(quote)
16#define __A2W(quote) L##quote
17
18#define EFI_TEST_GUID_STRING "{8768B7AC-F82F-4120-B093-30DFA27DA3B5}"
19#define EFI_TEST_VARIABLE_NAME "RosUefiVarTest"
20
21#define EFI_DUMMY_NAMESPACE_GUID_STRING "{00000000-0000-0000-0000-000000000000}"
22#define EFI_DUMMY_VARIABLE_NAME ""
23
26
28{
29#if (_WIN32_WINNT >= 0x0602)
30 BOOL bResult;
31 FIRMWARE_TYPE FirmwareType = FirmwareTypeUnknown, FirmwareExpect;
32
33 /* Test GetFirmwareType, should return FirmwareTypeBios or FirmwareTypeUefi */
34 bResult = GetFirmwareType(&FirmwareType);
35
36 ok(bResult,
37 "GetFirmwareType failed with error: 0x%08lX\n",
38 GetLastError());
39
40 if (!bResult)
41 return;
42
43 FirmwareExpect = (bIsUEFI ? FirmwareTypeUefi : FirmwareTypeBios);
44 ok(FirmwareType == FirmwareExpect,
45 "FirmwareType is %d, but %d is expected.\n",
46 FirmwareType, FirmwareExpect);
47#else
48 skip("This test can be run only when compiled for NT >= 6.2.\n");
49#endif
50}
51
52START_TEST(UEFIFirmware)
53{
54 BOOL bResult, bResultTemp, bIsUEFI;
55 DWORD dwError, dwErrorTemp, dwLength, dwLengthTemp, dwValue;
56 HANDLE hToken;
60
61 /*
62 * Check whether this test runs on legacy BIOS-based or UEFI system
63 * by calling GetFirmwareEnvironmentVariable with dummy name and GUID.
64 * It should fail with ERROR_INVALID_FUNCTION on the former and
65 * fail with another error on the latter.
66 */
67 dwLength = GetFirmwareEnvironmentVariableW(_A2W(EFI_DUMMY_VARIABLE_NAME),
69 NULL,
70 0);
71 dwError = GetLastError();
72 ok(dwLength == 0, "dwLength = %lu, expected 0\n", dwLength);
73
74 bIsUEFI = (dwLength == 0 && dwError != ERROR_INVALID_FUNCTION);
75 test_GetFirmwareType(bIsUEFI);
76 if (!bIsUEFI)
77 {
78 skip("Skipping tests that require UEFI environment.\n");
79 return;
80 }
81
82 /* Test ANSI function too */
83 dwLengthTemp = GetFirmwareEnvironmentVariableA(EFI_DUMMY_VARIABLE_NAME,
85 NULL,
86 0);
87 dwErrorTemp = GetLastError();
88 ok(dwLengthTemp == dwLength && dwErrorTemp == dwError,
89 "dwLength = %lu, LastError = %lu, expected bResult = %lu, LastError = %lu\n",
90 dwLengthTemp,
91 dwErrorTemp,
93 dwError);
94
95 /* Generate a random variable value to be used in this test */
98
99 /* Try to set firmware variable, should fail with ERROR_PRIVILEGE_NOT_HELD,
100 * because no SE_SYSTEM_ENVIRONMENT_NAME privilege enabled by default. */
104 sizeof(EfiVariableValue));
105 dwError = GetLastError();
106 ok(!bResult && dwError == ERROR_PRIVILEGE_NOT_HELD,
107 "bResult = %d, LastError = %lu, expected bResult = 0, LastError = ERROR_PRIVILEGE_NOT_HELD\n",
108 bResult,
109 dwError);
110
111 /* Test ANSI function too */
115 sizeof(EfiVariableValue));
116 dwErrorTemp = GetLastError();
117 ok(bResultTemp == bResult && dwErrorTemp == dwError,
118 "bResult = %d, LastError = %lu, expected bResult = %d, LastError = %lu\n",
119 bResultTemp,
120 dwErrorTemp,
121 bResult,
122 dwError);
123
124 /* Enable SE_SYSTEM_ENVIRONMENT_NAME privilege required by the following tests */
126 if (!bResult)
127 {
128 skip("OpenProcessToken failed with error: 0x%08lX, aborting.\n", GetLastError());
129 return;
130 }
131 Privilege.PrivilegeCount = 1;
133 Privilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
135 if (Status != STATUS_SUCCESS)
136 {
137 skip("NtAdjustPrivilegesToken failed with status: 0x%08lX, aborting.\n", Status);
138 NtClose(hToken);
139 return;
140 }
141
142 /* Set our test variable to UEFI firmware */
146 sizeof(EfiVariableValue));
147 ok(bResult,
148 "SetFirmwareEnvironmentVariableW failed with error: 0x%08lX\n",
149 GetLastError());
150 if (bResult)
151 {
152 /* Get the variable back and verify */
153 dwLength = GetFirmwareEnvironmentVariableW(_A2W(EFI_TEST_VARIABLE_NAME),
155 &dwValue,
156 sizeof(dwValue));
157 ok(dwLength,
158 "GetFirmwareEnvironmentVariableW failed with error: 0x%08lX\n",
159 GetLastError());
160 if (dwLength)
161 {
162 ok(dwLength == sizeof(EfiVariableValue) && dwValue == EfiVariableValue,
163 "Retrieved variable different from what we set, "
164 "dwLength = %lu, dwValue = %lu, expected dwLength = %u, dwValue = %lu",
165 dwLength,
166 dwValue,
167 sizeof(EfiVariableValue),
169 }
170 }
171
172 /* Change variable value and test ANSI function */
177 sizeof(EfiVariableValue));
178 ok(bResult,
179 "SetFirmwareEnvironmentVariableA failed with error: 0x%08lX\n",
180 GetLastError());
181 if (bResult)
182 {
183 /* Get the variable back and verify */
184 dwLength = GetFirmwareEnvironmentVariableA(EFI_TEST_VARIABLE_NAME,
186 &dwValue,
187 sizeof(dwValue));
188 ok(dwLength,
189 "GetFirmwareEnvironmentVariableA failed with error: 0x%08lX\n",
190 GetLastError());
191 if (dwLength)
192 {
193 ok(dwLength == sizeof(EfiVariableValue) && dwValue == EfiVariableValue,
194 "Retrieved variable different from what we set, "
195 "dwLength = %lu, dwValue = %lu, expected dwLength = %u, dwValue = %lu",
196 dwLength,
197 dwValue,
198 sizeof(EfiVariableValue),
200 }
201 }
202
203 /* Delete the variable */
206 NULL,
207 0);
208 ok(bResult,
209 "SetFirmwareEnvironmentVariableW failed with error: 0x%08lX\n",
210 GetLastError());
211 if (bResult)
212 {
213 dwLength = GetFirmwareEnvironmentVariableW(_A2W(EFI_TEST_VARIABLE_NAME),
215 &dwValue,
216 sizeof(dwValue));
217 ok(dwLength == 0, "SetFirmwareEnvironmentVariableW didn't delete the variable!\n");
218 }
219
220 /* Restore variable and test ANSI function */
224 sizeof(EfiVariableValue));
225 if (!bResult)
226 {
227 skip("SetFirmwareEnvironmentVariableW failed to restore variable with error: 0x%08lX\n",
228 GetLastError());
229 goto _exit;
230 }
233 NULL,
234 0);
235 ok(bResult,
236 "SetFirmwareEnvironmentVariableA failed with error: 0x%08lX\n",
237 GetLastError());
238 if (bResult)
239 {
240 dwLength = GetFirmwareEnvironmentVariableA(EFI_TEST_VARIABLE_NAME,
242 &dwValue,
243 sizeof(dwValue));
244 ok(dwLength == 0, "SetFirmwareEnvironmentVariableA didn't delete the variable!\n");
245 }
246
247_exit:
248 /* Restore the privilege */
249 Privilege.Privileges[0].Attributes = 0;
251 ok(Status == STATUS_SUCCESS, "NtAdjustPrivilegesToken failed with status: 0x%08lX\n", Status);
252 NtClose(hToken);
253}
static DWORD EfiVariableValue
Definition: UEFIFirmware.c:25
static VOID test_GetFirmwareType(BOOL bIsUEFI)
Definition: UEFIFirmware.c:27
#define EFI_DUMMY_NAMESPACE_GUID_STRING
Definition: UEFIFirmware.c:21
#define EFI_TEST_VARIABLE_NAME
Definition: UEFIFirmware.c:19
#define _A2W(quote)
Definition: UEFIFirmware.c:15
#define EFI_TEST_GUID_STRING
Definition: UEFIFirmware.c:18
#define EFI_DUMMY_VARIABLE_NAME
Definition: UEFIFirmware.c:22
static ULONG RandomSeed
Definition: UEFIFirmware.c:24
void _exit(int exitcode)
Definition: _exit.c:25
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
#define GetCurrentProcess()
Definition: compat.h:759
static DWORD DWORD * dwLength
Definition: fusion.c:86
BOOL WINAPI SetFirmwareEnvironmentVariableA(_In_ LPCSTR lpName, _In_ LPCSTR lpGuid, _In_reads_bytes_opt_(nSize) PVOID pValue, _In_ DWORD nSize)
Definition: sysinfo.c:646
BOOL WINAPI SetFirmwareEnvironmentVariableW(_In_ LPCWSTR lpName, _In_ LPCWSTR lpGuid, _In_reads_bytes_opt_(nSize) PVOID pValue, _In_ DWORD nSize)
Definition: sysinfo.c:631
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE
Definition: security.c:676
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtAdjustPrivilegesToken(_In_ HANDLE TokenHandle, _In_ BOOLEAN DisableAllPrivileges, _In_opt_ PTOKEN_PRIVILEGES NewState, _In_ ULONG BufferLength, _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState, _When_(PreviousState!=NULL, _Out_) PULONG ReturnLength)
Removes a certain amount of privileges of a token based upon the request by the caller.
Definition: tokenadj.c:451
uint32_t ULONG
Definition: typedefs.h:59
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_PRIVILEGE_NOT_HELD
Definition: winerror.h:796
FIRMWARE_TYPE
Definition: extypes.h:357
FORCEINLINE LUID NTAPI_INLINE RtlConvertUlongToLuid(_In_ ULONG Val)
Definition: rtlfuncs.h:3541
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:930
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63