diff --git a/dll/win32/kernel32/client/sysinfo.c b/dll/win32/kernel32/client/sysinfo.c index 7dbb320c118..a17aa193227 100644 --- a/dll/win32/kernel32/client/sysinfo.c +++ b/dll/win32/kernel32/client/sysinfo.c @@ -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( diff --git a/dll/win32/kernel32/kernel32.spec b/dll/win32/kernel32/kernel32.spec index 6c963fe5b6e..831681d1aaa 100644 --- a/dll/win32/kernel32/kernel32.spec +++ b/dll/win32/kernel32/kernel32.spec @@ -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) diff --git a/dll/win32/kernel32/kernel32_vista/CMakeLists.txt b/dll/win32/kernel32/kernel32_vista/CMakeLists.txt index 0ffbadc1ad6..35ac4be550e 100644 --- a/dll/win32/kernel32/kernel32_vista/CMakeLists.txt +++ b/dll/win32/kernel32/kernel32_vista/CMakeLists.txt @@ -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 index 00000000000..81e43899fb2 --- /dev/null +++ b/dll/win32/kernel32/kernel32_vista/firmware.c @@ -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 + */ + +/* We need NT6+ Ex definitions */ +#undef NTDDI_VERSION +#define NTDDI_VERSION NTDDI_VISTA +#include + +#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; +} diff --git a/dll/win32/kernel32/kernel32_vista/kernel32_vista.spec b/dll/win32/kernel32/kernel32_vista/kernel32_vista.spec index bf074328323..149244a94e4 100644 --- a/dll/win32/kernel32/kernel32_vista/kernel32_vista.spec +++ b/dll/win32/kernel32/kernel32_vista/kernel32_vista.spec @@ -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) diff --git a/modules/rostests/apitests/kernel32/UEFIFirmware.c b/modules/rostests/apitests/kernel32/UEFIFirmware.c index 4ab0ea6ea73..51bf618d681 100644 --- a/modules/rostests/apitests/kernel32/UEFIFirmware.c +++ b/modules/rostests/apitests/kernel32/UEFIFirmware.c @@ -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) diff --git a/sdk/include/psdk/winbase.h b/sdk/include/psdk/winbase.h index ca5fd2a3c58..2356d2915d1 100644 --- a/sdk/include/psdk/winbase.h +++ b/sdk/include/psdk/winbase.h @@ -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);