[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
This commit is contained in:
Ratin Gao 2023-09-15 03:14:07 +08:00 committed by GitHub
parent 961893a712
commit 4c8a2a8815
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 618 additions and 102 deletions

View file

@ -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 <ratin@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
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,

View file

@ -36,6 +36,7 @@ list(APPEND SOURCE
SystemFirmware.c
TerminateProcess.c
TunnelCache.c
UEFIFirmware.c
WideCharToMultiByte.c)
list(APPEND PCH_SKIP_SOURCE

View file

@ -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@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);
}

View file

@ -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 }

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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_)

View file

@ -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