[KERNEL32][KERNEL32_VISTA][KERNEL32_APITEST] Implement and export NT6+ firmware API...
authorRatin Gao <ratin@knsoft.org>
Sat, 30 Mar 2024 12:46:34 +0000 (20:46 +0800)
committerGitHub <noreply@github.com>
Sat, 30 Mar 2024 12:46:34 +0000 (15:46 +0300)
- 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 4c8a2a8815c. CORE-11954

dll/win32/kernel32/client/sysinfo.c
dll/win32/kernel32/kernel32.spec
dll/win32/kernel32/kernel32_vista/CMakeLists.txt
dll/win32/kernel32/kernel32_vista/firmware.c [new file with mode: 0644]
dll/win32/kernel32/kernel32_vista/kernel32_vista.spec
modules/rostests/apitests/kernel32/UEFIFirmware.c
sdk/include/psdk/winbase.h

index 7dbb320..a17aa19 100644 (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(
index 6c963fe..831681d 100644 (file)
 @ 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
 @ 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)
index 0ffbadc..35ac4be 100644 (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
diff --git a/dll/win32/kernel32/kernel32_vista/firmware.c b/dll/win32/kernel32/kernel32_vista/firmware.c
new file mode 100644 (file)
index 0000000..81e4389
--- /dev/null
@@ -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;
+}
index bf07432..149244a 100644 (file)
 
 @ 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)
index 4ab0ea6..51bf618 100644 (file)
 #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)
index ca5fd2a..2356d29 100644 (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);