[KERNEL32][KERNEL32_VISTA][KERNEL32_APITEST] Implement and export NT6+ firmware API (#6580)

- Implement `GetFirmwareType` and improve existing API test for it
- Move (Get/Set)FirmwareEnvironmentVariableEx(A/W) to kernel32_vista_static and export them when NT version >= 6.2

Addendum to 4c8a2a8815. CORE-11954
This commit is contained in:
Ratin Gao 2024-03-30 20:46:34 +08:00 committed by GitHub
parent a68406bccf
commit 1cf8759d69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 357 additions and 174 deletions

View file

@ -422,43 +422,7 @@ GetFirmwareEnvironmentVariableExW(
_In_ LPCWSTR lpGuid,
_Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
_In_ DWORD nSize,
_Out_opt_ PDWORD pdwAttribubutes)
{
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;
}
_Out_opt_ PDWORD pdwAttribubutes);
_Success_(return > 0)
DWORD
@ -468,47 +432,25 @@ GetFirmwareEnvironmentVariableExA(
_In_ LPCSTR lpGuid,
_Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
_In_ DWORD nSize,
_Out_opt_ PDWORD pdwAttribubutes)
{
NTSTATUS Status;
DWORD Length;
UNICODE_STRING VariableName, Namespace;
ANSI_STRING AnsiVariableName, AnsiNamespace;
_Out_opt_ PDWORD pdwAttribubutes);
/* 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;
}
BOOL
WINAPI
SetFirmwareEnvironmentVariableExW(
_In_ LPCWSTR lpName,
_In_ LPCWSTR lpGuid,
_In_reads_bytes_opt_(nSize) PVOID pValue,
_In_ DWORD nSize,
_In_ DWORD dwAttributes);
/* Call unicode version interface */
Length = GetFirmwareEnvironmentVariableExW(VariableName.Buffer,
Namespace.Buffer,
pBuffer,
nSize,
pdwAttribubutes);
/* Cleanup and return */
RtlFreeUnicodeString(&Namespace);
RtlFreeUnicodeString(&VariableName);
return Length;
}
BOOL
WINAPI
SetFirmwareEnvironmentVariableExA(
_In_ LPCSTR lpName,
_In_ LPCSTR lpGuid,
_In_reads_bytes_opt_(nSize) PVOID pValue,
_In_ DWORD nSize,
_In_ DWORD dwAttributes);
_Success_(return > 0)
DWORD
@ -534,98 +476,6 @@ GetFirmwareEnvironmentVariableA(
return GetFirmwareEnvironmentVariableExA(lpName, lpGuid, pBuffer, nSize, NULL);
}
BOOL
WINAPI
SetFirmwareEnvironmentVariableExW(
_In_ LPCWSTR lpName,
_In_ LPCWSTR lpGuid,
_In_reads_bytes_opt_(nSize) PVOID pValue,
_In_ DWORD nSize,
_In_ DWORD dwAttributes)
{
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(

View file

@ -483,7 +483,10 @@
@ stdcall -version=0x600+ GetFinalPathNameByHandleA(ptr str long long)
@ stdcall -version=0x600+ GetFinalPathNameByHandleW(ptr wstr long long)
@ stdcall GetFirmwareEnvironmentVariableA(str str ptr long)
@ stdcall -version=0x602+ GetFirmwareEnvironmentVariableExA(str str ptr long long)
@ stdcall -version=0x602+ GetFirmwareEnvironmentVariableExW(wstr wstr ptr long long)
@ stdcall GetFirmwareEnvironmentVariableW(wstr wstr ptr long)
@ stdcall -version=0x602+ GetFirmwareType(ptr)
@ stdcall GetFullPathNameA(str long ptr ptr)
@ stub -version=0x600+ GetFullPathNameTransactedA
@ stub -version=0x600+ GetFullPathNameTransactedW
@ -1037,6 +1040,8 @@
@ stdcall SetFileTime(long ptr ptr ptr)
@ stdcall SetFileValidData(long double)
@ stdcall SetFirmwareEnvironmentVariableA(str str ptr long)
@ stdcall -version=0x602+ SetFirmwareEnvironmentVariableExA(str str ptr long long)
@ stdcall -version=0x602+ SetFirmwareEnvironmentVariableExW(str str ptr long long)
@ stdcall SetFirmwareEnvironmentVariableW(wstr wstr ptr long)
@ stdcall -i386 SetHandleContext(long long)
@ stdcall SetHandleCount(long)

View file

@ -7,6 +7,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/subsys ..)
spec2def(kernel32_vista.dll kernel32_vista.spec ADD_IMPORTLIB)
list(APPEND SOURCE
firmware.c
GetFileInformationByHandleEx.c
GetTickCount64.c
InitOnce.c

View file

@ -0,0 +1,231 @@
/*
* PROJECT: ReactOS Win32 Base API
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: NT6+ Firmware API
* COPYRIGHT: Copyright 2023-2024 Ratin Gao <ratin@knsoft.org>
*/
/* We need NT6+ Ex definitions */
#undef NTDDI_VERSION
#define NTDDI_VERSION NTDDI_VISTA
#include <ndk/exfuncs.h>
#include "k32_vista.h"
_Success_(return > 0)
DWORD
WINAPI
GetFirmwareEnvironmentVariableExW(
_In_ LPCWSTR lpName,
_In_ LPCWSTR lpGuid,
_Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
_In_ DWORD nSize,
_Out_opt_ PDWORD pdwAttribubutes)
{
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;
}
_Success_(return > 0)
DWORD
WINAPI
GetFirmwareEnvironmentVariableExA(
_In_ LPCSTR lpName,
_In_ LPCSTR lpGuid,
_Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
_In_ DWORD nSize,
_Out_opt_ PDWORD pdwAttribubutes)
{
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;
}
BOOL
WINAPI
SetFirmwareEnvironmentVariableExW(
_In_ LPCWSTR lpName,
_In_ LPCWSTR lpGuid,
_In_reads_bytes_opt_(nSize) PVOID pValue,
_In_ DWORD nSize,
_In_ DWORD dwAttributes)
{
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;
}
_Success_(return)
BOOL
WINAPI
GetFirmwareType(_Out_ PFIRMWARE_TYPE FirmwareType)
{
NTSTATUS Status;
SYSTEM_BOOT_ENVIRONMENT_INFORMATION BootInfo;
/* Check input parameters */
if (FirmwareType == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
/* Query firmware type */
Status = NtQuerySystemInformation(SystemBootEnvironmentInformation,
&BootInfo,
sizeof(BootInfo),
0);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
*FirmwareType = BootInfo.FirmwareType;
return TRUE;
}

View file

@ -21,6 +21,12 @@
@ stdcall InitializeCriticalSectionEx(ptr long long)
@ stdcall GetFirmwareEnvironmentVariableExA(str str ptr long long)
@ stdcall GetFirmwareEnvironmentVariableExW(wstr wstr ptr long long)
@ stdcall GetFirmwareType(ptr)
@ stdcall SetFirmwareEnvironmentVariableExA(str str ptr long long)
@ stdcall SetFirmwareEnvironmentVariableExW(str str ptr long long)
@ stdcall ApplicationRecoveryFinished(long)
@ stdcall ApplicationRecoveryInProgress(ptr)
@ stdcall CreateSymbolicLinkA(str str long)

View file

@ -21,18 +21,46 @@
#define EFI_DUMMY_NAMESPACE_GUID_STRING "{00000000-0000-0000-0000-000000000000}"
#define EFI_DUMMY_VARIABLE_NAME ""
typedef enum _FIRMWARE_TYPE
{
FirmwareTypeUnknown,
FirmwareTypeBios,
FirmwareTypeUefi,
FirmwareTypeMax
} FIRMWARE_TYPE, *PFIRMWARE_TYPE;
typedef
_Success_(return)
BOOL
WINAPI
FN_GetFirmwareType(_Out_ PFIRMWARE_TYPE FirmwareType);
static ULONG RandomSeed;
static DWORD EfiVariableValue;
static VOID test_GetFirmwareType(BOOL bIsUEFI)
{
#if (_WIN32_WINNT >= 0x0602)
BOOL bResult;
HMODULE hKernel32;
FN_GetFirmwareType* pfnGetFirmwareType;
FIRMWARE_TYPE FirmwareType = FirmwareTypeUnknown, FirmwareExpect;
/* Test GetFirmwareType, should return FirmwareTypeBios or FirmwareTypeUefi */
bResult = GetFirmwareType(&FirmwareType);
/* Load functions */
hKernel32 = GetModuleHandleW(L"kernel32.dll");
if (hKernel32 == NULL)
{
skip("Module kernel32 not found\n");
return;
}
pfnGetFirmwareType = (FN_GetFirmwareType*)GetProcAddress(hKernel32, "GetFirmwareType");
if (pfnGetFirmwareType == NULL)
{
skip("GetFirmwareType (NT6.2+ API) not found\n");
return;
}
/* Test GetFirmwareType, should return FirmwareTypeBios or FirmwareTypeUefi */
bResult = pfnGetFirmwareType(&FirmwareType);
ok(bResult,
"GetFirmwareType failed with error: 0x%08lX\n",
GetLastError());
@ -44,9 +72,6 @@ static VOID test_GetFirmwareType(BOOL bIsUEFI)
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)

View file

@ -3222,6 +3222,71 @@ SetFirmwareEnvironmentVariableW(
#endif /* _WIN32_WINNT >= 0x0502 */
#if (_WIN32_WINNT >= 0x0602)
_Success_(return > 0)
WINBASEAPI
DWORD
WINAPI
GetFirmwareEnvironmentVariableExW(
_In_ LPCWSTR lpName,
_In_ LPCWSTR lpGuid,
_Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
_In_ DWORD nSize,
_Out_opt_ PDWORD pdwAttribubutes);
_Success_(return > 0)
WINBASEAPI
DWORD
WINAPI
GetFirmwareEnvironmentVariableExA(
_In_ LPCSTR lpName,
_In_ LPCSTR lpGuid,
_Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
_In_ DWORD nSize,
_Out_opt_ PDWORD pdwAttribubutes);
#ifdef UNICODE
#define GetFirmwareEnvironmentVariableEx GetFirmwareEnvironmentVariableExW
#else
#define GetFirmwareEnvironmentVariableEx GetFirmwareEnvironmentVariableExA
#endif
WINBASEAPI
BOOL
WINAPI
SetFirmwareEnvironmentVariableExW(
_In_ LPCWSTR lpName,
_In_ LPCWSTR lpGuid,
_In_reads_bytes_opt_(nSize) PVOID pValue,
_In_ DWORD nSize,
_In_ DWORD dwAttributes);
WINBASEAPI
BOOL
WINAPI
SetFirmwareEnvironmentVariableExA(
_In_ LPCSTR lpName,
_In_ LPCSTR lpGuid,
_In_reads_bytes_opt_(nSize) PVOID pValue,
_In_ DWORD nSize,
_In_ DWORD dwAttributes);
#ifdef UNICODE
#define SetFirmwareEnvironmentVariableEx SetFirmwareEnvironmentVariableExW
#else
#define SetFirmwareEnvironmentVariableEx SetFirmwareEnvironmentVariableExA
#endif
_Success_(return)
WINBASEAPI
BOOL
WINAPI
GetFirmwareType(
_Out_ PFIRMWARE_TYPE FirmwareType);
#endif /* _WIN32_WINNT >= 0x0602 */
UINT WINAPI SetHandleCount(UINT);
BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD);