https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4c8a2a8815c5ac1e92d0c…
commit 4c8a2a8815c5ac1e92d0c8cf3c2893a05b567dc9
Author: Ratin Gao <ratin(a)knsoft.org>
AuthorDate: Fri Sep 15 03:14:07 2023 +0800
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Sep 14 22:14:07 2023 +0300
[KERNEL32][KERNEL32_APITEST] Implement user-mode UEFI / Firmware API (#5149)
- Implement firmware environment variable read/write APIs
- Add, fix and improve related definitions and declarations
- Add kernel32:UEFIFirmware apitest
CORE-11954
---
dll/win32/kernel32/client/sysinfo.c | 299 ++++++++++++++++++----
modules/rostests/apitests/kernel32/CMakeLists.txt | 1 +
modules/rostests/apitests/kernel32/UEFIFirmware.c | 253 ++++++++++++++++++
modules/rostests/apitests/kernel32/testlist.c | 2 +
ntoskrnl/ex/sysinfo.c | 22 +-
sdk/include/ndk/exfuncs.h | 10 +-
sdk/include/ndk/extypes.h | 35 ++-
sdk/include/psdk/winbase.h | 78 ++++--
sdk/include/xdk/extypes.h | 11 +
sdk/include/xdk/winnt.template.h | 1 +
10 files changed, 614 insertions(+), 98 deletions(-)
diff --git a/dll/win32/kernel32/client/sysinfo.c b/dll/win32/kernel32/client/sysinfo.c
index 3b25a19a1e4..7dbb320c118 100644
--- a/dll/win32/kernel32/client/sysinfo.c
+++ b/dll/win32/kernel32/client/sysinfo.c
@@ -1,14 +1,14 @@
/*
* PROJECT: ReactOS Win32 Base API
- * LICENSE: See COPYING in the top level directory
- * FILE: dll/win32/kernel32/client/sysinfo.c
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: System Information Functions
- * PROGRAMMERS: Emanuele Aliberti
+ * COPYRIGHT: Emanuele Aliberti
* Christoph von Wittich
* Thomas Weidenmueller
* Gunnar Andre Dalsnes
* Stanislav Motylkov (x86corez(a)gmail.com)
* Mark Jansen (mark.jansen(a)reactos.org)
+ * Copyright 2023 Ratin Gao <ratin(a)knsoft.org>
*/
/* INCLUDES *******************************************************************/
@@ -78,11 +78,12 @@ GetSystemInfoInternal(IN PSYSTEM_BASIC_INFORMATION BasicInfo,
static
UINT
-BaseQuerySystemFirmware(IN DWORD FirmwareTableProviderSignature,
- IN DWORD FirmwareTableID,
- OUT PVOID pFirmwareTableBuffer,
- IN DWORD BufferSize,
- IN SYSTEM_FIRMWARE_TABLE_ACTION Action)
+BaseQuerySystemFirmware(
+ _In_ DWORD FirmwareTableProviderSignature,
+ _In_ DWORD FirmwareTableID,
+ _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableBuffer,
+ _In_ DWORD BufferSize,
+ _In_ SYSTEM_FIRMWARE_TABLE_ACTION Action)
{
SYSTEM_FIRMWARE_TABLE_INFORMATION* SysFirmwareInfo;
ULONG Result = 0, ReturnedSize;
@@ -413,60 +414,246 @@ GetNumaAvailableMemoryNode(IN UCHAR Node,
return TRUE;
}
-/*
- * @unimplemented
- */
+_Success_(return > 0)
DWORD
WINAPI
-GetFirmwareEnvironmentVariableW(IN LPCWSTR lpName,
- IN LPCWSTR lpGuid,
- IN PVOID pValue,
- IN DWORD nSize)
+GetFirmwareEnvironmentVariableExW(
+ _In_ LPCWSTR lpName,
+ _In_ LPCWSTR lpGuid,
+ _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
+ _In_ DWORD nSize,
+ _Out_opt_ PDWORD pdwAttribubutes)
{
- STUB;
- return 0;
+ NTSTATUS Status;
+ UNICODE_STRING VariableName, Namespace;
+ GUID VendorGuid;
+ ULONG Length;
+
+ /* Check input parameters and build NT strings */
+ if (!lpName || !lpGuid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ RtlInitUnicodeString(&VariableName, lpName);
+ RtlInitUnicodeString(&Namespace, lpGuid);
+ Status = RtlGUIDFromString(&Namespace, &VendorGuid);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ return 0;
+ }
+
+ /* Query firmware system environment variable value */
+ Length = nSize;
+ Status = NtQuerySystemEnvironmentValueEx(&VariableName,
+ &VendorGuid,
+ pBuffer,
+ &Length,
+ pdwAttribubutes);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ return 0;
+ }
+
+ return Length;
}
-/*
- * @unimplemented
- */
-BOOL
+_Success_(return > 0)
+DWORD
WINAPI
-SetFirmwareEnvironmentVariableW(IN LPCWSTR lpName,
- IN LPCWSTR lpGuid,
- IN PVOID pValue,
- IN DWORD nSize)
+GetFirmwareEnvironmentVariableExA(
+ _In_ LPCSTR lpName,
+ _In_ LPCSTR lpGuid,
+ _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
+ _In_ DWORD nSize,
+ _Out_opt_ PDWORD pdwAttribubutes)
{
- STUB;
- return 0;
+ NTSTATUS Status;
+ DWORD Length;
+ UNICODE_STRING VariableName, Namespace;
+ ANSI_STRING AnsiVariableName, AnsiNamespace;
+
+ /* Check input parameters and build NT strings */
+ if (!lpName || !lpGuid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ RtlInitString(&AnsiVariableName, lpName);
+ Status = RtlAnsiStringToUnicodeString(&VariableName, &AnsiVariableName,
TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ return 0;
+ }
+ RtlInitString(&AnsiNamespace, lpGuid);
+ Status = RtlAnsiStringToUnicodeString(&Namespace, &AnsiNamespace, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&VariableName);
+ BaseSetLastNTError(Status);
+ return 0;
+ }
+
+ /* Call unicode version interface */
+ Length = GetFirmwareEnvironmentVariableExW(VariableName.Buffer,
+ Namespace.Buffer,
+ pBuffer,
+ nSize,
+ pdwAttribubutes);
+
+ /* Cleanup and return */
+ RtlFreeUnicodeString(&Namespace);
+ RtlFreeUnicodeString(&VariableName);
+ return Length;
}
-/*
- * @unimplemented
- */
+_Success_(return > 0)
DWORD
WINAPI
-GetFirmwareEnvironmentVariableA(IN LPCSTR lpName,
- IN LPCSTR lpGuid,
- IN PVOID pValue,
- IN DWORD nSize)
+GetFirmwareEnvironmentVariableW(
+ _In_ LPCWSTR lpName,
+ _In_ LPCWSTR lpGuid,
+ _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
+ _In_ DWORD nSize)
{
- STUB;
- return 0;
+ return GetFirmwareEnvironmentVariableExW(lpName, lpGuid, pBuffer, nSize, NULL);
+}
+
+_Success_(return > 0)
+DWORD
+WINAPI
+GetFirmwareEnvironmentVariableA(
+ _In_ LPCSTR lpName,
+ _In_ LPCSTR lpGuid,
+ _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
+ _In_ DWORD nSize)
+{
+ return GetFirmwareEnvironmentVariableExA(lpName, lpGuid, pBuffer, nSize, NULL);
}
-/*
- * @unimplemented
- */
BOOL
WINAPI
-SetFirmwareEnvironmentVariableA(IN LPCSTR lpName,
- IN LPCSTR lpGuid,
- IN PVOID pValue,
- IN DWORD nSize)
+SetFirmwareEnvironmentVariableExW(
+ _In_ LPCWSTR lpName,
+ _In_ LPCWSTR lpGuid,
+ _In_reads_bytes_opt_(nSize) PVOID pValue,
+ _In_ DWORD nSize,
+ _In_ DWORD dwAttributes)
{
- STUB;
- return 0;
+ NTSTATUS Status;
+ UNICODE_STRING VariableName, Namespace;
+ GUID VendorGuid;
+
+ /* Check input parameters and build NT strings */
+ if (!lpName || !lpGuid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ RtlInitUnicodeString(&VariableName, lpName);
+ RtlInitUnicodeString(&Namespace, lpGuid);
+ Status = RtlGUIDFromString(&Namespace, &VendorGuid);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ return FALSE;
+ }
+
+ /* Set firmware system environment variable value */
+ Status = NtSetSystemEnvironmentValueEx(&VariableName,
+ &VendorGuid,
+ pValue,
+ nSize,
+ dwAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL
+WINAPI
+SetFirmwareEnvironmentVariableExA(
+ _In_ LPCSTR lpName,
+ _In_ LPCSTR lpGuid,
+ _In_reads_bytes_opt_(nSize) PVOID pValue,
+ _In_ DWORD nSize,
+ _In_ DWORD dwAttributes)
+{
+ NTSTATUS Status;
+ BOOL Result;
+ UNICODE_STRING VariableName, Namespace;
+ ANSI_STRING AnsiVariableName, AnsiNamespace;
+
+ /* Check input parameters and build NT strings */
+ if (!lpName || !lpGuid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ RtlInitString(&AnsiVariableName, lpName);
+ Status = RtlAnsiStringToUnicodeString(&VariableName, &AnsiVariableName,
TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ BaseSetLastNTError(Status);
+ return FALSE;
+ }
+ RtlInitString(&AnsiNamespace, lpGuid);
+ Status = RtlAnsiStringToUnicodeString(&Namespace, &AnsiNamespace, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&VariableName);
+ BaseSetLastNTError(Status);
+ return FALSE;
+ }
+
+ /* Call unicode version interface */
+ Result = SetFirmwareEnvironmentVariableExW(VariableName.Buffer,
+ Namespace.Buffer,
+ pValue,
+ nSize,
+ dwAttributes);
+
+ /* Cleanup and return */
+ RtlFreeUnicodeString(&Namespace);
+ RtlFreeUnicodeString(&VariableName);
+ return Result;
+}
+
+BOOL
+WINAPI
+SetFirmwareEnvironmentVariableW(
+ _In_ LPCWSTR lpName,
+ _In_ LPCWSTR lpGuid,
+ _In_reads_bytes_opt_(nSize) PVOID pValue,
+ _In_ DWORD nSize)
+{
+ return SetFirmwareEnvironmentVariableExW(lpName,
+ lpGuid,
+ pValue,
+ nSize,
+ VARIABLE_ATTRIBUTE_NON_VOLATILE);
+}
+
+BOOL
+WINAPI
+SetFirmwareEnvironmentVariableA(
+ _In_ LPCSTR lpName,
+ _In_ LPCSTR lpGuid,
+ _In_reads_bytes_opt_(nSize) PVOID pValue,
+ _In_ DWORD nSize)
+{
+ return SetFirmwareEnvironmentVariableExA(lpName,
+ lpGuid,
+ pValue,
+ nSize,
+ VARIABLE_ATTRIBUTE_NON_VOLATILE);
}
/**
@@ -474,7 +661,7 @@ SetFirmwareEnvironmentVariableA(IN LPCSTR lpName,
* @implemented
*
* Obtains firmware table identifiers.
- *
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724259(v=vs.85).…
+ *
https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoap…
*
* @param FirmwareTableProviderSignature
* Can be either ACPI, FIRM, or RSMB.
@@ -498,13 +685,14 @@ SetFirmwareEnvironmentVariableA(IN LPCSTR lpName,
*/
UINT
WINAPI
-EnumSystemFirmwareTables(IN DWORD FirmwareTableProviderSignature,
- OUT PVOID pFirmwareTableBuffer,
- IN DWORD BufferSize)
+EnumSystemFirmwareTables(
+ _In_ DWORD FirmwareTableProviderSignature,
+ _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableEnumBuffer,
+ _In_ DWORD BufferSize)
{
return BaseQuerySystemFirmware(FirmwareTableProviderSignature,
0,
- pFirmwareTableBuffer,
+ pFirmwareTableEnumBuffer,
BufferSize,
SystemFirmwareTable_Enumerate);
}
@@ -514,7 +702,7 @@ EnumSystemFirmwareTables(IN DWORD FirmwareTableProviderSignature,
* @implemented
*
* Obtains the firmware table data.
- *
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724379(v=vs.85).…
+ *
https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoap…
*
* @param FirmwareTableProviderSignature
* Can be either ACPI, FIRM, or RSMB.
@@ -545,10 +733,11 @@ EnumSystemFirmwareTables(IN DWORD FirmwareTableProviderSignature,
*/
UINT
WINAPI
-GetSystemFirmwareTable(IN DWORD FirmwareTableProviderSignature,
- IN DWORD FirmwareTableID,
- OUT PVOID pFirmwareTableBuffer,
- IN DWORD BufferSize)
+GetSystemFirmwareTable(
+ _In_ DWORD FirmwareTableProviderSignature,
+ _In_ DWORD FirmwareTableID,
+ _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableBuffer,
+ _In_ DWORD BufferSize)
{
return BaseQuerySystemFirmware(FirmwareTableProviderSignature,
FirmwareTableID,
diff --git a/modules/rostests/apitests/kernel32/CMakeLists.txt
b/modules/rostests/apitests/kernel32/CMakeLists.txt
index 8c26b340edc..582d3f5627f 100644
--- a/modules/rostests/apitests/kernel32/CMakeLists.txt
+++ b/modules/rostests/apitests/kernel32/CMakeLists.txt
@@ -36,6 +36,7 @@ list(APPEND SOURCE
SystemFirmware.c
TerminateProcess.c
TunnelCache.c
+ UEFIFirmware.c
WideCharToMultiByte.c)
list(APPEND PCH_SKIP_SOURCE
diff --git a/modules/rostests/apitests/kernel32/UEFIFirmware.c
b/modules/rostests/apitests/kernel32/UEFIFirmware.c
new file mode 100644
index 00000000000..4ab0ea6ea73
--- /dev/null
+++ b/modules/rostests/apitests/kernel32/UEFIFirmware.c
@@ -0,0 +1,253 @@
+/*
+ * PROJECT: ReactOS API Tests
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Tests for UEFI Firmware functions
+ * COPYRIGHT: Copyright 2023 Ratin Gao <ratin(a)knsoft.org>
+ */
+
+#include "precomp.h"
+
+#include <ndk/psfuncs.h>
+#include <ndk/setypes.h>
+#include <ndk/sefuncs.h>
+#include <ndk/obfuncs.h>
+
+#define _A2W(quote) __A2W(quote)
+#define __A2W(quote) L##quote
+
+#define EFI_TEST_GUID_STRING "{8768B7AC-F82F-4120-B093-30DFA27DA3B5}"
+#define EFI_TEST_VARIABLE_NAME "RosUefiVarTest"
+
+#define EFI_DUMMY_NAMESPACE_GUID_STRING
"{00000000-0000-0000-0000-000000000000}"
+#define EFI_DUMMY_VARIABLE_NAME ""
+
+static ULONG RandomSeed;
+static DWORD EfiVariableValue;
+
+static VOID test_GetFirmwareType(BOOL bIsUEFI)
+{
+#if (_WIN32_WINNT >= 0x0602)
+ BOOL bResult;
+ FIRMWARE_TYPE FirmwareType = FirmwareTypeUnknown, FirmwareExpect;
+
+ /* Test GetFirmwareType, should return FirmwareTypeBios or FirmwareTypeUefi */
+ bResult = GetFirmwareType(&FirmwareType);
+
+ ok(bResult,
+ "GetFirmwareType failed with error: 0x%08lX\n",
+ GetLastError());
+
+ if (!bResult)
+ return;
+
+ FirmwareExpect = (bIsUEFI ? FirmwareTypeUefi : FirmwareTypeBios);
+ ok(FirmwareType == FirmwareExpect,
+ "FirmwareType is %d, but %d is expected.\n",
+ FirmwareType, FirmwareExpect);
+#else
+ skip("This test can be run only when compiled for NT >= 6.2.\n");
+#endif
+}
+
+START_TEST(UEFIFirmware)
+{
+ BOOL bResult, bResultTemp, bIsUEFI;
+ DWORD dwError, dwErrorTemp, dwLength, dwLengthTemp, dwValue;
+ HANDLE hToken;
+ TOKEN_PRIVILEGES Privilege;
+ NTSTATUS Status;
+ ULONG ReturnLength;
+
+ /*
+ * Check whether this test runs on legacy BIOS-based or UEFI system
+ * by calling GetFirmwareEnvironmentVariable with dummy name and GUID.
+ * It should fail with ERROR_INVALID_FUNCTION on the former and
+ * fail with another error on the latter.
+ */
+ dwLength = GetFirmwareEnvironmentVariableW(_A2W(EFI_DUMMY_VARIABLE_NAME),
+ _A2W(EFI_DUMMY_NAMESPACE_GUID_STRING),
+ NULL,
+ 0);
+ dwError = GetLastError();
+ ok(dwLength == 0, "dwLength = %lu, expected 0\n", dwLength);
+
+ bIsUEFI = (dwLength == 0 && dwError != ERROR_INVALID_FUNCTION);
+ test_GetFirmwareType(bIsUEFI);
+ if (!bIsUEFI)
+ {
+ skip("Skipping tests that require UEFI environment.\n");
+ return;
+ }
+
+ /* Test ANSI function too */
+ dwLengthTemp = GetFirmwareEnvironmentVariableA(EFI_DUMMY_VARIABLE_NAME,
+ EFI_DUMMY_NAMESPACE_GUID_STRING,
+ NULL,
+ 0);
+ dwErrorTemp = GetLastError();
+ ok(dwLengthTemp == dwLength && dwErrorTemp == dwError,
+ "dwLength = %lu, LastError = %lu, expected bResult = %lu, LastError =
%lu\n",
+ dwLengthTemp,
+ dwErrorTemp,
+ dwLength,
+ dwError);
+
+ /* Generate a random variable value to be used in this test */
+ RandomSeed = GetTickCount();
+ EfiVariableValue = RtlRandom(&RandomSeed);
+
+ /* Try to set firmware variable, should fail with ERROR_PRIVILEGE_NOT_HELD,
+ * because no SE_SYSTEM_ENVIRONMENT_NAME privilege enabled by default. */
+ bResult = SetFirmwareEnvironmentVariableW(_A2W(EFI_TEST_VARIABLE_NAME),
+ _A2W(EFI_TEST_GUID_STRING),
+ &EfiVariableValue,
+ sizeof(EfiVariableValue));
+ dwError = GetLastError();
+ ok(!bResult && dwError == ERROR_PRIVILEGE_NOT_HELD,
+ "bResult = %d, LastError = %lu, expected bResult = 0, LastError =
ERROR_PRIVILEGE_NOT_HELD\n",
+ bResult,
+ dwError);
+
+ /* Test ANSI function too */
+ bResultTemp = SetFirmwareEnvironmentVariableA(EFI_TEST_VARIABLE_NAME,
+ EFI_TEST_GUID_STRING,
+ &EfiVariableValue,
+ sizeof(EfiVariableValue));
+ dwErrorTemp = GetLastError();
+ ok(bResultTemp == bResult && dwErrorTemp == dwError,
+ "bResult = %d, LastError = %lu, expected bResult = %d, LastError =
%lu\n",
+ bResultTemp,
+ dwErrorTemp,
+ bResult,
+ dwError);
+
+ /* Enable SE_SYSTEM_ENVIRONMENT_NAME privilege required by the following tests */
+ bResult = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
&hToken);
+ if (!bResult)
+ {
+ skip("OpenProcessToken failed with error: 0x%08lX, aborting.\n",
GetLastError());
+ return;
+ }
+ Privilege.PrivilegeCount = 1;
+ Privilege.Privileges[0].Luid =
RtlConvertUlongToLuid(SE_SYSTEM_ENVIRONMENT_PRIVILEGE);
+ Privilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ Status = NtAdjustPrivilegesToken(hToken, FALSE, &Privilege, sizeof(Privilege),
NULL, &ReturnLength);
+ if (Status != STATUS_SUCCESS)
+ {
+ skip("NtAdjustPrivilegesToken failed with status: 0x%08lX,
aborting.\n", Status);
+ NtClose(hToken);
+ return;
+ }
+
+ /* Set our test variable to UEFI firmware */
+ bResult = SetFirmwareEnvironmentVariableW(_A2W(EFI_TEST_VARIABLE_NAME),
+ _A2W(EFI_TEST_GUID_STRING),
+ &EfiVariableValue,
+ sizeof(EfiVariableValue));
+ ok(bResult,
+ "SetFirmwareEnvironmentVariableW failed with error: 0x%08lX\n",
+ GetLastError());
+ if (bResult)
+ {
+ /* Get the variable back and verify */
+ dwLength = GetFirmwareEnvironmentVariableW(_A2W(EFI_TEST_VARIABLE_NAME),
+ _A2W(EFI_TEST_GUID_STRING),
+ &dwValue,
+ sizeof(dwValue));
+ ok(dwLength,
+ "GetFirmwareEnvironmentVariableW failed with error: 0x%08lX\n",
+ GetLastError());
+ if (dwLength)
+ {
+ ok(dwLength == sizeof(EfiVariableValue) && dwValue ==
EfiVariableValue,
+ "Retrieved variable different from what we set, "
+ "dwLength = %lu, dwValue = %lu, expected dwLength = %u, dwValue =
%lu",
+ dwLength,
+ dwValue,
+ sizeof(EfiVariableValue),
+ EfiVariableValue);
+ }
+ }
+
+ /* Change variable value and test ANSI function */
+ EfiVariableValue = RtlRandom(&RandomSeed);
+ bResult = SetFirmwareEnvironmentVariableA(EFI_TEST_VARIABLE_NAME,
+ EFI_TEST_GUID_STRING,
+ &EfiVariableValue,
+ sizeof(EfiVariableValue));
+ ok(bResult,
+ "SetFirmwareEnvironmentVariableA failed with error: 0x%08lX\n",
+ GetLastError());
+ if (bResult)
+ {
+ /* Get the variable back and verify */
+ dwLength = GetFirmwareEnvironmentVariableA(EFI_TEST_VARIABLE_NAME,
+ EFI_TEST_GUID_STRING,
+ &dwValue,
+ sizeof(dwValue));
+ ok(dwLength,
+ "GetFirmwareEnvironmentVariableA failed with error: 0x%08lX\n",
+ GetLastError());
+ if (dwLength)
+ {
+ ok(dwLength == sizeof(EfiVariableValue) && dwValue ==
EfiVariableValue,
+ "Retrieved variable different from what we set, "
+ "dwLength = %lu, dwValue = %lu, expected dwLength = %u, dwValue =
%lu",
+ dwLength,
+ dwValue,
+ sizeof(EfiVariableValue),
+ EfiVariableValue);
+ }
+ }
+
+ /* Delete the variable */
+ bResult = SetFirmwareEnvironmentVariableW(_A2W(EFI_TEST_VARIABLE_NAME),
+ _A2W(EFI_TEST_GUID_STRING),
+ NULL,
+ 0);
+ ok(bResult,
+ "SetFirmwareEnvironmentVariableW failed with error: 0x%08lX\n",
+ GetLastError());
+ if (bResult)
+ {
+ dwLength = GetFirmwareEnvironmentVariableW(_A2W(EFI_TEST_VARIABLE_NAME),
+ _A2W(EFI_TEST_GUID_STRING),
+ &dwValue,
+ sizeof(dwValue));
+ ok(dwLength == 0, "SetFirmwareEnvironmentVariableW didn't delete the
variable!\n");
+ }
+
+ /* Restore variable and test ANSI function */
+ bResult = SetFirmwareEnvironmentVariableW(_A2W(EFI_TEST_VARIABLE_NAME),
+ _A2W(EFI_TEST_GUID_STRING),
+ &EfiVariableValue,
+ sizeof(EfiVariableValue));
+ if (!bResult)
+ {
+ skip("SetFirmwareEnvironmentVariableW failed to restore variable with error:
0x%08lX\n",
+ GetLastError());
+ goto _exit;
+ }
+ bResult = SetFirmwareEnvironmentVariableA(EFI_TEST_VARIABLE_NAME,
+ EFI_TEST_GUID_STRING,
+ NULL,
+ 0);
+ ok(bResult,
+ "SetFirmwareEnvironmentVariableA failed with error: 0x%08lX\n",
+ GetLastError());
+ if (bResult)
+ {
+ dwLength = GetFirmwareEnvironmentVariableA(EFI_TEST_VARIABLE_NAME,
+ EFI_TEST_GUID_STRING,
+ &dwValue,
+ sizeof(dwValue));
+ ok(dwLength == 0, "SetFirmwareEnvironmentVariableA didn't delete the
variable!\n");
+ }
+
+_exit:
+ /* Restore the privilege */
+ Privilege.Privileges[0].Attributes = 0;
+ Status = NtAdjustPrivilegesToken(hToken, FALSE, &Privilege, sizeof(Privilege),
NULL, &ReturnLength);
+ ok(Status == STATUS_SUCCESS, "NtAdjustPrivilegesToken failed with status:
0x%08lX\n", Status);
+ NtClose(hToken);
+}
diff --git a/modules/rostests/apitests/kernel32/testlist.c
b/modules/rostests/apitests/kernel32/testlist.c
index 4802d88079c..a0a11a88d1a 100644
--- a/modules/rostests/apitests/kernel32/testlist.c
+++ b/modules/rostests/apitests/kernel32/testlist.c
@@ -36,6 +36,7 @@ extern void func_SetUnhandledExceptionFilter(void);
extern void func_SystemFirmware(void);
extern void func_TerminateProcess(void);
extern void func_TunnelCache(void);
+extern void func_UEFIFirmware(void);
extern void func_WideCharToMultiByte(void);
const struct test winetest_testlist[] =
@@ -72,6 +73,7 @@ const struct test winetest_testlist[] =
{ "SystemFirmware", func_SystemFirmware },
{ "TerminateProcess", func_TerminateProcess },
{ "TunnelCache", func_TunnelCache },
+ { "UEFIFirmware", func_UEFIFirmware },
{ "WideCharToMultiByte", func_WideCharToMultiByte },
{ "ActCtxWithXmlNamespaces", func_ActCtxWithXmlNamespaces },
{ 0, 0 }
diff --git a/ntoskrnl/ex/sysinfo.c b/ntoskrnl/ex/sysinfo.c
index d6692bc83f6..58b023466a1 100644
--- a/ntoskrnl/ex/sysinfo.c
+++ b/ntoskrnl/ex/sysinfo.c
@@ -564,11 +564,12 @@ NtEnumerateSystemEnvironmentValuesEx(IN ULONG InformationClass,
NTSTATUS
NTAPI
-NtQuerySystemEnvironmentValueEx(IN PUNICODE_STRING VariableName,
- IN LPGUID VendorGuid,
- IN PVOID Value,
- IN OUT PULONG ReturnLength,
- IN OUT PULONG Attributes)
+NtQuerySystemEnvironmentValueEx(
+ _In_ PUNICODE_STRING VariableName,
+ _In_ LPGUID VendorGuid,
+ _Out_opt_ PVOID Value,
+ _Inout_ PULONG ReturnLength,
+ _Out_opt_ PULONG Attributes)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
@@ -576,11 +577,12 @@ NtQuerySystemEnvironmentValueEx(IN PUNICODE_STRING VariableName,
NTSTATUS
NTAPI
-NtSetSystemEnvironmentValueEx(IN PUNICODE_STRING VariableName,
- IN LPGUID VendorGuid,
- IN PVOID Value,
- IN OUT PULONG ReturnLength,
- IN OUT PULONG Attributes)
+NtSetSystemEnvironmentValueEx(
+ _In_ PUNICODE_STRING VariableName,
+ _In_ LPGUID VendorGuid,
+ _In_reads_bytes_opt_(ValueLength) PVOID Value,
+ _In_ ULONG ValueLength,
+ _In_ ULONG Attributes)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
diff --git a/sdk/include/ndk/exfuncs.h b/sdk/include/ndk/exfuncs.h
index bca4e87010c..d3dd33bb1d7 100644
--- a/sdk/include/ndk/exfuncs.h
+++ b/sdk/include/ndk/exfuncs.h
@@ -396,9 +396,9 @@ NTAPI
NtQuerySystemEnvironmentValueEx(
_In_ PUNICODE_STRING VariableName,
_In_ LPGUID VendorGuid,
- _In_ PVOID Value,
+ _Out_opt_ PVOID Value,
_Inout_ PULONG ReturnLength,
- _Inout_ PULONG Attributes
+ _Out_opt_ PULONG Attributes
);
__kernel_entry
@@ -550,9 +550,9 @@ NTAPI
NtSetSystemEnvironmentValueEx(
_In_ PUNICODE_STRING VariableName,
_In_ LPGUID VendorGuid,
- _In_ PVOID Value,
- _Inout_ PULONG ReturnLength,
- _Inout_ PULONG Attributes
+ _In_reads_bytes_opt_(ValueLength) PVOID Value,
+ _In_ ULONG ValueLength,
+ _In_ ULONG Attributes
);
__kernel_entry
diff --git a/sdk/include/ndk/extypes.h b/sdk/include/ndk/extypes.h
index 6cc77cb1d7c..2b190f1ca30 100644
--- a/sdk/include/ndk/extypes.h
+++ b/sdk/include/ndk/extypes.h
@@ -1432,7 +1432,29 @@ typedef struct _SYSTEM_HANDLE_INFORMATION_EX
SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handle[1];
} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
-// FIXME: Class 65-97
+// FIXME: Class 65-89
+
+// Class 90
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
+{
+ GUID BootIdentifier;
+ FIRMWARE_TYPE FirmwareType;
+#if (NTDDI_VERSION >= NTDDI_WIN8)
+ ULONGLONG BootFlags;
+#endif
+} SYSTEM_BOOT_ENVIRONMENT_INFORMATION, *PSYSTEM_BOOT_ENVIRONMENT_INFORMATION;
+#endif
+
+#if (NTDDI_VERSION >= NTDDI_WIN8)
+typedef struct _SYSTEM_BOOT_ENVIRONMENT_V1
+{
+ GUID BootIdentifier;
+ FIRMWARE_TYPE FirmwareType;
+} SYSTEM_BOOT_ENVIRONMENT_V1, *PSYSTEM_BOOT_ENVIRONMENT_V1;
+#endif
+
+// FIXME: Class 91-97
//
// Hotpatch flags
@@ -1540,6 +1562,17 @@ typedef struct _SYSTEM_MEMORY_LIST_INFORMATION
SIZE_T ModifiedPageCountPageFile;
} SYSTEM_MEMORY_LIST_INFORMATION, *PSYSTEM_MEMORY_LIST_INFORMATION;
+//
+// Firmware variable attributes
+//
+#define VARIABLE_ATTRIBUTE_NON_VOLATILE 0x00000001
+#define VARIABLE_ATTRIBUTE_BOOTSERVICE_ACCESS 0x00000002
+#define VARIABLE_ATTRIBUTE_RUNTIME_ACCESS 0x00000004
+#define VARIABLE_ATTRIBUTE_HARDWARE_ERROR_RECORD 0x00000008
+#define VARIABLE_ATTRIBUTE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+#define VARIABLE_ATTRIBUTE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
+#define VARIABLE_ATTRIBUTE_APPEND_WRITE 0x00000040
+
#ifdef __cplusplus
}; // extern "C"
#endif
diff --git a/sdk/include/psdk/winbase.h b/sdk/include/psdk/winbase.h
index 6b616b07b39..397ad4d92cc 100644
--- a/sdk/include/psdk/winbase.h
+++ b/sdk/include/psdk/winbase.h
@@ -2004,25 +2004,7 @@ _Ret_maybenull_ HRSRC WINAPI FindResourceA(_In_opt_ HMODULE,_In_
LPCSTR, _In_ LP
_Ret_maybenull_ HRSRC WINAPI FindResourceW(_In_opt_ HMODULE,_In_ LPCWSTR, _In_ LPCWSTR);
_Ret_maybenull_ HRSRC WINAPI FindResourceExA(_In_opt_ HMODULE, _In_ LPCSTR, _In_ LPCSTR,
_In_ WORD);
HRSRC WINAPI FindResourceExW(HINSTANCE,LPCWSTR,LPCWSTR,WORD);
-#if (_WIN32_WINNT >= 0x0502)
-
-DWORD
-WINAPI
-GetFirmwareEnvironmentVariableA(
- _In_ LPCSTR lpName,
- _In_ LPCSTR lpGuid,
- _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
- _In_ DWORD nSize);
-
-DWORD
-WINAPI
-GetFirmwareEnvironmentVariableW(
- _In_ LPCWSTR lpName,
- _In_ LPCWSTR lpGuid,
- _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
- _In_ DWORD nSize);
-#endif
BOOL WINAPI FlushFileBuffers(HANDLE);
BOOL WINAPI FlushInstructionCache(HANDLE,LPCVOID,SIZE_T);
BOOL WINAPI FlushViewOfFile(LPCVOID,SIZE_T);
@@ -2430,15 +2412,6 @@ HANDLE WINAPI GetStdHandle(_In_ DWORD);
UINT WINAPI GetSystemDirectoryA(LPSTR,UINT);
UINT WINAPI GetSystemDirectoryW(LPWSTR,UINT);
-WINBASEAPI
-UINT
-WINAPI
-GetSystemFirmwareTable(
- _In_ DWORD FirmwareTableProviderSignature,
- _In_ DWORD FirmwareTableID,
- _Out_writes_bytes_to_opt_(BufferSize,return) PVOID pFirmwareTableBuffer,
- _In_ DWORD BufferSize);
-
VOID WINAPI GetSystemInfo(LPSYSTEM_INFO);
BOOL WINAPI GetSystemPowerStatus(_Out_ LPSYSTEM_POWER_STATUS);
#if (_WIN32_WINNT >= 0x0502)
@@ -3170,6 +3143,50 @@ BOOL WINAPI SetFileValidData(HANDLE,LONGLONG);
#if (_WIN32_WINNT >= 0x0502)
+WINBASEAPI
+UINT
+WINAPI
+EnumSystemFirmwareTables(
+ _In_ DWORD FirmwareTableProviderSignature,
+ _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableEnumBuffer,
+ _In_ DWORD BufferSize);
+
+WINBASEAPI
+UINT
+WINAPI
+GetSystemFirmwareTable(
+ _In_ DWORD FirmwareTableProviderSignature,
+ _In_ DWORD FirmwareTableID,
+ _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableBuffer,
+ _In_ DWORD BufferSize);
+
+_Success_(return > 0)
+WINBASEAPI
+DWORD
+WINAPI
+GetFirmwareEnvironmentVariableA(
+ _In_ LPCSTR lpName,
+ _In_ LPCSTR lpGuid,
+ _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
+ _In_ DWORD nSize);
+
+_Success_(return > 0)
+WINBASEAPI
+DWORD
+WINAPI
+GetFirmwareEnvironmentVariableW(
+ _In_ LPCWSTR lpName,
+ _In_ LPCWSTR lpGuid,
+ _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
+ _In_ DWORD nSize);
+
+#ifdef UNICODE
+#define GetFirmwareEnvironmentVariable GetFirmwareEnvironmentVariableW
+#else
+#define GetFirmwareEnvironmentVariable GetFirmwareEnvironmentVariableA
+#endif
+
+WINBASEAPI
BOOL
WINAPI
SetFirmwareEnvironmentVariableA(
@@ -3178,6 +3195,7 @@ SetFirmwareEnvironmentVariableA(
_In_reads_bytes_opt_(nSize) PVOID pValue,
_In_ DWORD nSize);
+WINBASEAPI
BOOL
WINAPI
SetFirmwareEnvironmentVariableW(
@@ -3186,8 +3204,14 @@ SetFirmwareEnvironmentVariableW(
_In_reads_bytes_opt_(nSize) PVOID pValue,
_In_ DWORD nSize);
+#ifdef UNICODE
+#define SetFirmwareEnvironmentVariable SetFirmwareEnvironmentVariableW
+#else
+#define SetFirmwareEnvironmentVariable SetFirmwareEnvironmentVariableA
#endif
+#endif /* _WIN32_WINNT >= 0x0502 */
+
UINT WINAPI SetHandleCount(UINT);
BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD);
diff --git a/sdk/include/xdk/extypes.h b/sdk/include/xdk/extypes.h
index a8c5fa87dc2..a5311330872 100644
--- a/sdk/include/xdk/extypes.h
+++ b/sdk/include/xdk/extypes.h
@@ -346,3 +346,14 @@ $if (_NTIFS_)
#define EX_PUSH_LOCK ULONG_PTR
#define PEX_PUSH_LOCK PULONG_PTR
$endif (_NTIFS_)
+
+$if (_WINNT_ || _WDMDDK_)
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+typedef enum _FIRMWARE_TYPE {
+ FirmwareTypeUnknown,
+ FirmwareTypeBios,
+ FirmwareTypeUefi,
+ FirmwareTypeMax
+} FIRMWARE_TYPE, *PFIRMWARE_TYPE;
+#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
+$endif (_WINNT_ || _WDMDDK_)
diff --git a/sdk/include/xdk/winnt.template.h b/sdk/include/xdk/winnt.template.h
index dd28aee4238..75a85102e08 100644
--- a/sdk/include/xdk/winnt.template.h
+++ b/sdk/include/xdk/winnt.template.h
@@ -73,6 +73,7 @@ $define(UCHAR=BYTE)
$include(ntbasedef.h)
$include(interlocked.h)
$include(ketypes.h)
+$include(extypes.h)
$include(winnt_old.h)
#ifdef __cplusplus