From 4c8a2a8815c5ac1e92d0c8cf3c2893a05b567dc9 Mon Sep 17 00:00:00 2001 From: Ratin Gao Date: Fri, 15 Sep 2023 03:14:07 +0800 Subject: [PATCH] [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 | 307 ++++++++++++++---- .../rostests/apitests/kernel32/CMakeLists.txt | 1 + .../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, 618 insertions(+), 102 deletions(-) create mode 100644 modules/rostests/apitests/kernel32/UEFIFirmware.c 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@gmail.com) * Mark Jansen (mark.jansen@reactos.org) + * Copyright 2023 Ratin Gao */ /* 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 -WINAPI -SetFirmwareEnvironmentVariableW(IN LPCWSTR lpName, - IN LPCWSTR lpGuid, - IN PVOID pValue, - IN DWORD nSize) -{ - STUB; - return 0; -} - -/* - * @unimplemented - */ +_Success_(return > 0) DWORD WINAPI -GetFirmwareEnvironmentVariableA(IN LPCSTR lpName, - IN LPCSTR 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; +} + +_Success_(return > 0) +DWORD +WINAPI +GetFirmwareEnvironmentVariableW( + _In_ LPCWSTR lpName, + _In_ LPCWSTR lpGuid, + _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer, + _In_ DWORD nSize) +{ + 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).aspx + * https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-enumsystemfirmwaretables * * @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).aspx + * https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemfirmwaretable * * @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 + */ + +#include "precomp.h" + +#include +#include +#include +#include + +#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