mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
Merge branch 'firmware' into 'master'
Implement NtQuerySystemEnvironmentValueEx, NtQuerySystemInformation SystemBootEnvironmentInformation, GetFirmwareType, GetFirmwareEnvironmentVariable* See merge request wine/wine!6423
This commit is contained in:
commit
b480be235d
9 changed files with 783 additions and 9 deletions
|
@ -695,7 +695,9 @@
|
||||||
@ stdcall -import GetFileType(long)
|
@ stdcall -import GetFileType(long)
|
||||||
@ stdcall -import GetFinalPathNameByHandleA(long ptr long long)
|
@ stdcall -import GetFinalPathNameByHandleA(long ptr long long)
|
||||||
@ stdcall -import GetFinalPathNameByHandleW(long ptr long long)
|
@ stdcall -import GetFinalPathNameByHandleW(long ptr long long)
|
||||||
|
@ stdcall GetFirmwareEnvironmentVariableExA(str str ptr long ptr)
|
||||||
@ stdcall GetFirmwareEnvironmentVariableA(str str ptr long)
|
@ stdcall GetFirmwareEnvironmentVariableA(str str ptr long)
|
||||||
|
@ stdcall GetFirmwareEnvironmentVariableExW(wstr wstr ptr long ptr)
|
||||||
@ stdcall GetFirmwareEnvironmentVariableW(wstr wstr ptr long)
|
@ stdcall GetFirmwareEnvironmentVariableW(wstr wstr ptr long)
|
||||||
@ stdcall GetFirmwareType(ptr)
|
@ stdcall GetFirmwareType(ptr)
|
||||||
@ stdcall -import GetFullPathNameA(str long ptr ptr)
|
@ stdcall -import GetFullPathNameA(str long ptr ptr)
|
||||||
|
|
|
@ -719,13 +719,43 @@ WORD WINAPI GetMaximumProcessorGroupCount(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GetFirmwareEnvironmentVariableA (KERNEL32.@)
|
* GetFirmwareEnvironmentVariableExW (KERNEL32.@)
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetFirmwareEnvironmentVariableA(LPCSTR name, LPCSTR guid, PVOID buffer, DWORD size)
|
DWORD WINAPI GetFirmwareEnvironmentVariableExW(LPCWSTR name, LPCWSTR guid, PVOID buffer, DWORD size, PDWORD attributes)
|
||||||
{
|
{
|
||||||
FIXME("stub: %s %s %p %lu\n", debugstr_a(name), debugstr_a(guid), buffer, size);
|
GUID vendor = {0};
|
||||||
SetLastError(ERROR_INVALID_FUNCTION);
|
NTSTATUS status;
|
||||||
return 0;
|
UNICODE_STRING uname;
|
||||||
|
UNICODE_STRING uguid;
|
||||||
|
DWORD ret_size = size;
|
||||||
|
|
||||||
|
if(!name || !guid || !attributes)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&uguid, guid);
|
||||||
|
|
||||||
|
if (!set_ntstatus(RtlGUIDFromString(&uguid, &vendor)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&uname, name);
|
||||||
|
|
||||||
|
status = NtQuerySystemEnvironmentValueEx(&uname, &vendor, buffer,
|
||||||
|
&ret_size, attributes);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
if(status == STATUS_VARIABLE_NOT_FOUND)
|
||||||
|
SetLastError(ERROR_ENVVAR_NOT_FOUND);
|
||||||
|
else if(status == STATUS_NOT_IMPLEMENTED)
|
||||||
|
SetLastError(ERROR_INVALID_FUNCTION);
|
||||||
|
else
|
||||||
|
SetLastError(RtlNtStatusToDosError(status));
|
||||||
|
ret_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -733,9 +763,61 @@ DWORD WINAPI GetFirmwareEnvironmentVariableA(LPCSTR name, LPCSTR guid, PVOID buf
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetFirmwareEnvironmentVariableW(LPCWSTR name, LPCWSTR guid, PVOID buffer, DWORD size)
|
DWORD WINAPI GetFirmwareEnvironmentVariableW(LPCWSTR name, LPCWSTR guid, PVOID buffer, DWORD size)
|
||||||
{
|
{
|
||||||
FIXME("stub: %s %s %p %lu\n", debugstr_w(name), debugstr_w(guid), buffer, size);
|
DWORD attributes;
|
||||||
SetLastError(ERROR_INVALID_FUNCTION);
|
return GetFirmwareEnvironmentVariableExW(name, guid, buffer, size, &attributes);
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetFirmwareEnvironmentVariableExA (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
DWORD WINAPI GetFirmwareEnvironmentVariableExA(LPCSTR name, LPCSTR guid, PVOID buffer, DWORD size, PDWORD attributes)
|
||||||
|
{
|
||||||
|
int nsize;
|
||||||
|
LPWSTR wname;
|
||||||
|
LPWSTR wguid;
|
||||||
|
DWORD ret_size;
|
||||||
|
|
||||||
|
if(!name || !guid || !attributes)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsize = MultiByteToWideChar(CP_ACP, 0, guid, -1, NULL, 0);
|
||||||
|
|
||||||
|
if (!(wguid = HeapAlloc(GetProcessHeap(), 0, nsize * sizeof(wguid))))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, guid, -1, wguid, nsize);
|
||||||
|
|
||||||
|
nsize = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
|
||||||
|
|
||||||
|
if (!(wname = HeapAlloc(GetProcessHeap(), 0, nsize * sizeof(wname))))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, name, -1, wname, nsize);
|
||||||
|
|
||||||
|
ret_size = GetFirmwareEnvironmentVariableExW(wname, wguid, buffer, size, attributes);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, wname);
|
||||||
|
HeapFree(GetProcessHeap(), 0, wguid);
|
||||||
|
|
||||||
|
return ret_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetFirmwareEnvironmentVariableA (KERNEL32.@)
|
||||||
|
*/
|
||||||
|
DWORD WINAPI GetFirmwareEnvironmentVariableA(LPCSTR name, LPCSTR guid, PVOID buffer, DWORD size)
|
||||||
|
{
|
||||||
|
DWORD attributes;
|
||||||
|
return GetFirmwareEnvironmentVariableExA(name, guid, buffer, size, &attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -763,10 +845,20 @@ BOOL WINAPI SetFirmwareEnvironmentVariableW(const WCHAR *name, const WCHAR *guid
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetFirmwareType(FIRMWARE_TYPE *type)
|
BOOL WINAPI GetFirmwareType(FIRMWARE_TYPE *type)
|
||||||
{
|
{
|
||||||
|
SYSTEM_BOOT_ENVIRONMENT_INFORMATION boot_info = {0};
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!set_ntstatus(NtQuerySystemInformation(SystemBootEnvironmentInformation,
|
||||||
|
&boot_info, sizeof(boot_info), NULL)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
*type = FirmwareTypeUnknown;
|
*type = boot_info.FirmwareType;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ SOURCES = \
|
||||||
environ.c \
|
environ.c \
|
||||||
fiber.c \
|
fiber.c \
|
||||||
file.c \
|
file.c \
|
||||||
|
firmware.c \
|
||||||
format_msg.c \
|
format_msg.c \
|
||||||
generated.c \
|
generated.c \
|
||||||
heap.c \
|
heap.c \
|
||||||
|
|
350
dlls/kernel32/tests/firmware.c
Normal file
350
dlls/kernel32/tests/firmware.c
Normal file
|
@ -0,0 +1,350 @@
|
||||||
|
/* Unit test suite for *Information* Registry API functions
|
||||||
|
*
|
||||||
|
* Copyright 2024 Grigory Vasilyev
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ntstatus.h"
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
|
#include "wine/test.h"
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "winerror.h"
|
||||||
|
#include "winuser.h"
|
||||||
|
#include "winternl.h"
|
||||||
|
|
||||||
|
static void test_get_firmware_type(void)
|
||||||
|
{
|
||||||
|
FIRMWARE_TYPE ft;
|
||||||
|
BOOL status;
|
||||||
|
|
||||||
|
status = GetFirmwareType(&ft);
|
||||||
|
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareType not implemented.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(status == TRUE, "Expected TRUE.\n");
|
||||||
|
|
||||||
|
ok(ft == FirmwareTypeBios || ft == FirmwareTypeUefi,
|
||||||
|
"Expected FirmwareTypeBios or FirmwareTypeUefi, got %08x\n", ft);
|
||||||
|
|
||||||
|
status = GetFirmwareType(NULL);
|
||||||
|
ok(status == FALSE && GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected FALSE and GetLastError() == ERROR_INVALID_PARAMETER\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL EnableTokenPrivilege(HANDLE hToken, const char *pszPrivilegesName, BOOL bEnabled)
|
||||||
|
{
|
||||||
|
LUID luid;
|
||||||
|
TOKEN_PRIVILEGES tp;
|
||||||
|
|
||||||
|
if (!LookupPrivilegeValueA(NULL, pszPrivilegesName, &luid))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp.PrivilegeCount = 1;
|
||||||
|
tp.Privileges[0].Luid = luid;
|
||||||
|
tp.Privileges[0].Attributes = bEnabled ? SE_PRIVILEGE_ENABLED : 0;
|
||||||
|
|
||||||
|
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_get_firmware_environment(void)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
BOOLEAN secureboot;
|
||||||
|
DWORD attributes;
|
||||||
|
HANDLE hToken;
|
||||||
|
HANDLE hProcess;
|
||||||
|
BOOL privileged = FALSE;
|
||||||
|
|
||||||
|
hProcess = GetCurrentProcess();
|
||||||
|
if(hProcess && OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)
|
||||||
|
&& EnableTokenPrivilege(hToken, SE_SYSTEM_ENVIRONMENT_NAME, TRUE))
|
||||||
|
privileged = TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetFirmwareEnvironmentVariableA
|
||||||
|
*/
|
||||||
|
status = GetFirmwareEnvironmentVariableA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, sizeof(BOOLEAN));
|
||||||
|
|
||||||
|
if(!privileged && !status && GetLastError() == ERROR_PRIVILEGE_NOT_HELD)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareEnvironmentVariable* demand privileges SE_SYSTEM_ENVIRONMENT_NAME.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!status && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareEnvironmentVariableA call NtQuerySystemEnvironmentValueEx"
|
||||||
|
"and NtQuerySystemEnvironmentValueEx not implemented.\n");
|
||||||
|
goto get_firmware_environment_variable_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!status && GetLastError() == ERROR_INVALID_FUNCTION)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareEnvironmentVariableA call NtQuerySystemEnvironmentValueEx"
|
||||||
|
" and NtQuerySystemEnvironmentValueEx returned ERROR_INVALID_FUNCTION.\n"
|
||||||
|
"This behavior matches the behavior of Windows for non-UEFI boots and older versions of Windows.\n");
|
||||||
|
goto get_firmware_environment_variable_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0 or GetLastError() == ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableA(NULL, NULL, &secureboot, sizeof(secureboot));
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableA(NULL, "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, sizeof(secureboot));
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableA("SecureBoot", NULL, &secureboot, sizeof(secureboot));
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}", NULL, 0);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, 0);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
NULL, sizeof(secureboot));
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0 or GetLastError() == ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableA("DummyName", "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
&secureboot, sizeof(secureboot));
|
||||||
|
ok(GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetFirmwareEnvironmentVariableW
|
||||||
|
*/
|
||||||
|
get_firmware_environment_variable_w:
|
||||||
|
status = GetFirmwareEnvironmentVariableW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, sizeof(BOOLEAN));
|
||||||
|
|
||||||
|
if (!status && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareEnvironmentVariableW call NtQuerySystemEnvironmentValueEx"
|
||||||
|
"and NtQuerySystemEnvironmentValueEx not implemented.\n");
|
||||||
|
goto get_firmware_environment_variable_ex_a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!status && GetLastError() == ERROR_INVALID_FUNCTION)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareEnvironmentVariableW call NtQuerySystemEnvironmentValueEx"
|
||||||
|
" and NtQuerySystemEnvironmentValueEx returned ERROR_INVALID_FUNCTION.\n"
|
||||||
|
"This behavior matches the behavior of Windows for non-UEFI boots and older versions of Windows.\n");
|
||||||
|
goto get_firmware_environment_variable_ex_a;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0, got error %ld\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableW(NULL, NULL, &secureboot, sizeof(secureboot));
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableW(NULL, L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, sizeof(secureboot));
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableW(L"SecureBoot", NULL, &secureboot, sizeof(secureboot));
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
NULL, 0);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, 0);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
NULL, sizeof(secureboot));
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0 or GetLastError() == ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableW(L"DummyName", L"{00000000-0000-0000-0000-000000000000}",
|
||||||
|
&secureboot, sizeof(secureboot));
|
||||||
|
ok(GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetFirmwareEnvironmentVariableExA
|
||||||
|
*/
|
||||||
|
get_firmware_environment_variable_ex_a:
|
||||||
|
status = GetFirmwareEnvironmentVariableExA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, sizeof(BOOLEAN), &attributes);
|
||||||
|
|
||||||
|
if (!status && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareEnvironmentVariableExA call NtQuerySystemEnvironmentValueEx"
|
||||||
|
"and NtQuerySystemEnvironmentValueEx not implemented.\n");
|
||||||
|
goto get_firmware_environment_variable_ex_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!status && GetLastError() == ERROR_INVALID_FUNCTION)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareEnvironmentVariableExA call NtQuerySystemEnvironmentValueEx"
|
||||||
|
" and NtQuerySystemEnvironmentValueEx returned ERROR_INVALID_FUNCTION.\n"
|
||||||
|
"This behavior matches the behavior of Windows for non-UEFI boots and older versions of Windows.\n");
|
||||||
|
goto get_firmware_environment_variable_ex_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0, got error %ld\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExA(NULL, NULL, &secureboot, sizeof(secureboot), &attributes);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExA(NULL, "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, sizeof(secureboot), &attributes);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExA("SecureBoot", NULL, &secureboot,
|
||||||
|
sizeof(secureboot), &attributes);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
NULL, 0, NULL);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, 0, NULL);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, 0, &attributes);
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0 or GetLastError() == ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
NULL, sizeof(secureboot), NULL);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExA("SecureBoot", "{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
NULL, sizeof(secureboot), &attributes);
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0 or GetLastError() == ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExA("DummyName", "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
&secureboot, sizeof(secureboot), &attributes);
|
||||||
|
ok(GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetFirmwareEnvironmentVariableExW
|
||||||
|
*/
|
||||||
|
get_firmware_environment_variable_ex_w:
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, sizeof(BOOLEAN), &attributes);
|
||||||
|
|
||||||
|
if (!status && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareEnvironmentVariableExW call NtQuerySystemEnvironmentValueEx"
|
||||||
|
"and NtQuerySystemEnvironmentValueEx not implemented.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!status && GetLastError() == ERROR_INVALID_FUNCTION)
|
||||||
|
{
|
||||||
|
skip("GetFirmwareEnvironmentVariableExW call NtQuerySystemEnvironmentValueEx"
|
||||||
|
" and NtQuerySystemEnvironmentValueEx returned ERROR_INVALID_FUNCTION.\n"
|
||||||
|
"This behavior matches the behavior of Windows for non-UEFI boots and older versions of Windows.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0, got error %ld\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(NULL, NULL, &secureboot, sizeof(secureboot), &attributes);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(NULL, L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, sizeof(secureboot), &attributes);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(L"SecureBoot", NULL, &secureboot, sizeof(secureboot), &attributes);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
NULL, 0, NULL);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, 0, NULL);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
&secureboot, 0, &attributes);
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0 or GetLastError() == ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
NULL, sizeof(secureboot), NULL);
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(L"SecureBoot", L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}",
|
||||||
|
NULL, sizeof(secureboot), &attributes);
|
||||||
|
ok(status > 0 || GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected status > 0 or GetLastError() == ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
|
||||||
|
status = GetFirmwareEnvironmentVariableExW(L"DummyName", L"{00000000-0000-0000-0000-000000000000}",
|
||||||
|
&secureboot, sizeof(secureboot), &attributes);
|
||||||
|
ok(GetLastError() == ERROR_ENVVAR_NOT_FOUND,
|
||||||
|
"Expected ERROR_ENVVAR_NOT_FOUND, got error %ld.\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(firmware)
|
||||||
|
{
|
||||||
|
test_get_firmware_type();
|
||||||
|
test_get_firmware_environment();
|
||||||
|
}
|
|
@ -34,6 +34,7 @@
|
||||||
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
||||||
static NTSTATUS (WINAPI * pNtSetSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG);
|
static NTSTATUS (WINAPI * pNtSetSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG);
|
||||||
static NTSTATUS (WINAPI * pRtlGetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
static NTSTATUS (WINAPI * pRtlGetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
||||||
|
static NTSTATUS (WINAPI * pNtQuerySystemEnvironmentValueEx)(PUNICODE_STRING, LPGUID, PVOID, PULONG, PULONG);
|
||||||
static NTSTATUS (WINAPI * pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS, void*, ULONG, void*, ULONG, ULONG*);
|
static NTSTATUS (WINAPI * pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS, void*, ULONG, void*, ULONG, ULONG*);
|
||||||
static NTSTATUS (WINAPI * pNtPowerInformation)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG);
|
static NTSTATUS (WINAPI * pNtPowerInformation)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG);
|
||||||
static NTSTATUS (WINAPI * pNtQueryInformationThread)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG);
|
static NTSTATUS (WINAPI * pNtQueryInformationThread)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG);
|
||||||
|
@ -91,6 +92,7 @@ static void InitFunctionPtrs(void)
|
||||||
|
|
||||||
NTDLL_GET_PROC(NtQuerySystemInformation);
|
NTDLL_GET_PROC(NtQuerySystemInformation);
|
||||||
NTDLL_GET_PROC(NtQuerySystemInformationEx);
|
NTDLL_GET_PROC(NtQuerySystemInformationEx);
|
||||||
|
NTDLL_GET_PROC(NtQuerySystemEnvironmentValueEx);
|
||||||
NTDLL_GET_PROC(NtSetSystemInformation);
|
NTDLL_GET_PROC(NtSetSystemInformation);
|
||||||
NTDLL_GET_PROC(RtlGetNativeSystemInformation);
|
NTDLL_GET_PROC(RtlGetNativeSystemInformation);
|
||||||
NTDLL_GET_PROC(NtPowerInformation);
|
NTDLL_GET_PROC(NtPowerInformation);
|
||||||
|
@ -322,6 +324,83 @@ static void test_query_basic(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_query_boot_and_system_env(void)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
ULONG ret_size;
|
||||||
|
BOOLEAN secureboot;
|
||||||
|
DWORD attributes;
|
||||||
|
UNICODE_STRING secureboot_name;
|
||||||
|
GUID secureboot_guid = {0x8be4df61, 0x93ca, 0x11d2, {0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c}};
|
||||||
|
SYSTEM_BOOT_ENVIRONMENT_INFORMATION bi = {0};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NtQuerySystemInformation - SystemBootEnvironmentInformation
|
||||||
|
*/
|
||||||
|
status = pNtQuerySystemInformation(SystemBootEnvironmentInformation, &bi, sizeof(bi), &ret_size);
|
||||||
|
if (status == STATUS_NOT_IMPLEMENTED)
|
||||||
|
{
|
||||||
|
skip("NtQuerySystemInformation - SystemBootEnvironmentInformation not implemented.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS.\n");
|
||||||
|
|
||||||
|
ok(ret_size == sizeof(bi), "Expected ret_size == sizeof(SYSTEM_BOOT_ENVIRONMENT_INFORMATION).\n");
|
||||||
|
|
||||||
|
ok(bi.FirmwareType == FirmwareTypeBios || bi.FirmwareType == FirmwareTypeUefi,
|
||||||
|
"Expected FirmwareTypeBios or FirmwareTypeUefi, got %02x\n", bi.FirmwareType);
|
||||||
|
|
||||||
|
ok(bi.BootIdentifier.Data1 != 0, "A non-zero BootIdentifier value is expected.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemInformation(SystemBootEnvironmentInformation, NULL, sizeof(bi), NULL);
|
||||||
|
ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemInformation(SystemBootEnvironmentInformation, NULL, 0, NULL);
|
||||||
|
ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH.\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NtQuerySystemEnvironmentValueEx
|
||||||
|
*/
|
||||||
|
RtlInitUnicodeString(&secureboot_name, L"SecureBoot");
|
||||||
|
ret_size = sizeof(secureboot);
|
||||||
|
|
||||||
|
status = pNtQuerySystemEnvironmentValueEx(&secureboot_name, &secureboot_guid, &secureboot, &ret_size, &attributes);
|
||||||
|
if(bi.FirmwareType != FirmwareTypeUefi)
|
||||||
|
ok(status == STATUS_NOT_IMPLEMENTED, "Expected STATUS_NOT_IMPLEMENTED on non-UEFI boots.\n");
|
||||||
|
|
||||||
|
if (status == STATUS_NOT_IMPLEMENTED)
|
||||||
|
{
|
||||||
|
skip("NtQuerySystemEnvironmentValueEx not implemented.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(status == STATUS_SUCCESS || status == STATUS_VARIABLE_NOT_FOUND, "Expected STATUS_SUCCESS or STATUS_VARIABLE_NOT_FOUND.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemEnvironmentValueEx(NULL, NULL, &secureboot, &ret_size, &attributes);
|
||||||
|
ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemEnvironmentValueEx(NULL, &secureboot_guid, &secureboot, &ret_size, &attributes);
|
||||||
|
ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemEnvironmentValueEx(&secureboot_name, NULL, &secureboot, &ret_size, &attributes);
|
||||||
|
ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemEnvironmentValueEx(&secureboot_name, &secureboot_guid, NULL, NULL, NULL);
|
||||||
|
ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemEnvironmentValueEx(&secureboot_name, &secureboot_guid, &secureboot, NULL, NULL);
|
||||||
|
ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemEnvironmentValueEx(&secureboot_name, &secureboot_guid, &secureboot, NULL, &attributes);
|
||||||
|
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemEnvironmentValueEx(&secureboot_name, &secureboot_guid, NULL, &ret_size, NULL);
|
||||||
|
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS.\n");
|
||||||
|
|
||||||
|
status = pNtQuerySystemEnvironmentValueEx(&secureboot_name, &secureboot_guid, NULL, &ret_size, &attributes);
|
||||||
|
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS.\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void test_query_cpu(void)
|
static void test_query_cpu(void)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
@ -4103,6 +4182,7 @@ START_TEST(info)
|
||||||
|
|
||||||
/* NtQuerySystemInformation */
|
/* NtQuerySystemInformation */
|
||||||
test_query_basic();
|
test_query_basic();
|
||||||
|
test_query_boot_and_system_env();
|
||||||
test_query_cpu();
|
test_query_cpu();
|
||||||
test_query_performance();
|
test_query_performance();
|
||||||
test_query_timeofday();
|
test_query_timeofday();
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -2950,6 +2951,101 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SystemBootEnvironmentInformation: /* 90 */
|
||||||
|
{
|
||||||
|
static SYSTEM_BOOT_ENVIRONMENT_INFORMATION boot_info = {0};
|
||||||
|
struct stat stat_info = {0};
|
||||||
|
ssize_t ssz;
|
||||||
|
#if defined(__linux__) || defined(__gnu_linux__)
|
||||||
|
int fd;
|
||||||
|
char buffer[32];
|
||||||
|
#endif
|
||||||
|
len = sizeof(boot_info);
|
||||||
|
if (size == len)
|
||||||
|
{
|
||||||
|
#if defined(__linux__) || defined(__gnu_linux__)
|
||||||
|
if (boot_info.FirmwareType == FirmwareTypeUnknown)
|
||||||
|
{
|
||||||
|
if (!stat("/sys/firmware/efi", &stat_info))
|
||||||
|
boot_info.FirmwareType = FirmwareTypeUefi;
|
||||||
|
else
|
||||||
|
boot_info.FirmwareType = FirmwareTypeBios;
|
||||||
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
/*
|
||||||
|
* Since 2006, Mac computers use Extensible Firmware Interface (EFI).
|
||||||
|
* Reference: https://support.apple.com/guide/security/uefi-firmware-security-in-an-intel-based-mac-seced055bcf6/web
|
||||||
|
*/
|
||||||
|
boot_info.FirmwareType = FirmwareTypeUefi;
|
||||||
|
#else
|
||||||
|
boot_info.FirmwareType = FirmwareTypeBios;
|
||||||
|
#endif
|
||||||
|
if (boot_info.BootIdentifier.Data1 == 0)
|
||||||
|
{
|
||||||
|
#if defined(__linux__) || defined(__gnu_linux__)
|
||||||
|
if (!stat("/etc/machine-id", &stat_info) && stat_info.st_size >= 32)
|
||||||
|
{
|
||||||
|
fd = open("/etc/machine-id", O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
goto try_read_hostid;
|
||||||
|
ssz = read(fd, &buffer, 32);
|
||||||
|
if (ssz < 0)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
goto try_read_hostid;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
if (sscanf(buffer,
|
||||||
|
"%08X%04hX%04hX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
|
||||||
|
(unsigned int *)&boot_info.BootIdentifier.Data1, &boot_info.BootIdentifier.Data2,
|
||||||
|
&boot_info.BootIdentifier.Data3, &boot_info.BootIdentifier.Data4[0],
|
||||||
|
&boot_info.BootIdentifier.Data4[1], &boot_info.BootIdentifier.Data4[2],
|
||||||
|
&boot_info.BootIdentifier.Data4[3], &boot_info.BootIdentifier.Data4[4],
|
||||||
|
&boot_info.BootIdentifier.Data4[5], &boot_info.BootIdentifier.Data4[6],
|
||||||
|
&boot_info.BootIdentifier.Data4[7]) != 11)
|
||||||
|
goto try_read_hostid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try_read_hostid:
|
||||||
|
#endif
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (!stat("/Users", &stat_info) || !stat("/System", &stat_info))
|
||||||
|
#else
|
||||||
|
if (!stat("/home", &stat_info) || !stat("/usr", &stat_info))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
boot_info.BootIdentifier.Data1 = gethostid() & 0xFFFFFFFF;
|
||||||
|
boot_info.BootIdentifier.Data2 = stat_info.st_dev & 0xFFFF;
|
||||||
|
boot_info.BootIdentifier.Data3 = stat_info.st_ino & 0xFFFF;
|
||||||
|
boot_info.BootIdentifier.Data4[0] = 'W' ^ (boot_info.BootIdentifier.Data1 & 0xFF);
|
||||||
|
boot_info.BootIdentifier.Data4[1] = 'I' ^ ((boot_info.BootIdentifier.Data1 >> 4) & 0xFF);
|
||||||
|
boot_info.BootIdentifier.Data4[2] = 'N' ^ ((boot_info.BootIdentifier.Data1 >> 8) & 0xFF);
|
||||||
|
boot_info.BootIdentifier.Data4[3] = 'E' ^ ((boot_info.BootIdentifier.Data1 >> 12) & 0xFF);
|
||||||
|
boot_info.BootIdentifier.Data4[4] = 'B' ^ ((boot_info.BootIdentifier.Data1 >> 16) & 0xFF);
|
||||||
|
boot_info.BootIdentifier.Data4[5] = 'O' ^ ((boot_info.BootIdentifier.Data1 >> 20) & 0xFF);
|
||||||
|
boot_info.BootIdentifier.Data4[6] = 'O' ^ ((boot_info.BootIdentifier.Data1 >> 24) & 0xFF);
|
||||||
|
boot_info.BootIdentifier.Data4[7] = 'T' ^ ((boot_info.BootIdentifier.Data1 >> 28) & 0xFF);
|
||||||
|
}
|
||||||
|
#if defined(__linux__) || defined(__gnu_linux__)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
boot_info.BootIdentifier.Data3 &= 0x0fff;
|
||||||
|
boot_info.BootIdentifier.Data3 |= (4 << 12);
|
||||||
|
/* Set the topmost bits of Data4 (clock_seq_hi_and_reserved) as
|
||||||
|
* specified in RFC 4122, section 4.4.
|
||||||
|
*/
|
||||||
|
boot_info.BootIdentifier.Data4[0] &= 0x3f;
|
||||||
|
boot_info.BootIdentifier.Data4[0] |= 0x80;
|
||||||
|
}
|
||||||
|
if (!info) ret = STATUS_ACCESS_VIOLATION;
|
||||||
|
else memcpy(info, &boot_info, len);
|
||||||
|
}
|
||||||
|
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
if (ret_size) *ret_size = len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SystemCpuInformation: /* 1 */
|
case SystemCpuInformation: /* 1 */
|
||||||
if (size >= (len = sizeof(cpu_info))) memcpy(info, &cpu_info, len);
|
if (size >= (len = sizeof(cpu_info))) memcpy(info, &cpu_info, len);
|
||||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
@ -3842,9 +3938,133 @@ NTSTATUS WINAPI NtQuerySystemEnvironmentValue( UNICODE_STRING *name, WCHAR *buff
|
||||||
NTSTATUS WINAPI NtQuerySystemEnvironmentValueEx( UNICODE_STRING *name, GUID *vendor, void *buffer,
|
NTSTATUS WINAPI NtQuerySystemEnvironmentValueEx( UNICODE_STRING *name, GUID *vendor, void *buffer,
|
||||||
ULONG *retlen, ULONG *attrib )
|
ULONG *retlen, ULONG *attrib )
|
||||||
{
|
{
|
||||||
|
#if defined(__linux__) || defined(__gnu_linux__)
|
||||||
|
int fd, rc;
|
||||||
|
size_t bytes, pos = 0;
|
||||||
|
ssize_t ssz;
|
||||||
|
char buff[4];
|
||||||
|
char *cname;
|
||||||
|
char filename[PATH_MAX + 1];
|
||||||
|
NTSTATUS status;
|
||||||
|
struct stat stat_info = {0};
|
||||||
|
static SYSTEM_BOOT_ENVIRONMENT_INFORMATION boot_info = {0};
|
||||||
|
|
||||||
|
if(boot_info.FirmwareType == FirmwareTypeUnknown)
|
||||||
|
{
|
||||||
|
status = NtQuerySystemInformation(SystemBootEnvironmentInformation,
|
||||||
|
&boot_info, sizeof(boot_info), NULL);
|
||||||
|
if(status != STATUS_SUCCESS) return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(boot_info.FirmwareType != FirmwareTypeUefi)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This behavior matches the behavior of Windows for non-UEFI boots,
|
||||||
|
* and older versions of Windows.
|
||||||
|
*/
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!name || !vendor || (name && vendor && !retlen && !attrib))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
cname = (char *) malloc(wcslen(name->Buffer) * 3 + 1);
|
||||||
|
if(!cname)
|
||||||
|
return STATUS_MEMORY_NOT_ALLOCATED;
|
||||||
|
|
||||||
|
rc = ntdll_wcstoumbs(name->Buffer, wcslen(name->Buffer) + 1, cname, wcslen(name->Buffer) * 3 + 1, TRUE);
|
||||||
|
if(rc <= 0) {
|
||||||
|
free(cname);
|
||||||
|
return STATUS_SOME_NOT_MAPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(filename, sizeof(filename),
|
||||||
|
"/sys/firmware/efi/efivars/%s-%08lx-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
|
||||||
|
cname, (unsigned long)vendor->Data1, vendor->Data2, vendor->Data3,
|
||||||
|
vendor->Data4[0], vendor->Data4[1], vendor->Data4[2], vendor->Data4[3],
|
||||||
|
vendor->Data4[4], vendor->Data4[5], vendor->Data4[6], vendor->Data4[7]);
|
||||||
|
|
||||||
|
fd = open(filename, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
free(cname);
|
||||||
|
return STATUS_VARIABLE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = fstat(fd, &stat_info);
|
||||||
|
if (rc < 0 || stat_info.st_size == 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if(attrib) ssz = read(fd, attrib, 4);
|
||||||
|
else ssz = read(fd, buff, 4); // lseek not work in efifs.
|
||||||
|
if (ssz < 0) goto done;
|
||||||
|
|
||||||
|
if(buffer && retlen)
|
||||||
|
{
|
||||||
|
if (stat_info.st_size - 4 < *retlen)
|
||||||
|
bytes = stat_info.st_size - 4;
|
||||||
|
else
|
||||||
|
bytes = *retlen;
|
||||||
|
while (pos < bytes)
|
||||||
|
{
|
||||||
|
ssz = read(fd, (char *) buffer + pos, bytes - pos);
|
||||||
|
if (ssz < 0) goto done;
|
||||||
|
pos += ssz;
|
||||||
|
}
|
||||||
|
*retlen = ssz & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
else if(retlen) *retlen = (stat_info.st_size - 4) & 0xFFFFFFFF;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
free(cname);
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
int rc;
|
||||||
|
char *cname;
|
||||||
|
GUID secureboot_guid = {0x8be4df61, 0x93ca, 0x11d2, {0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c}};
|
||||||
|
if(!name || !vendor || (name && vendor && !retlen && !attrib))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
cname = (char *) malloc(wcslen(name->Buffer) * 3 + 1);
|
||||||
|
if(!cname)
|
||||||
|
return STATUS_MEMORY_NOT_ALLOCATED;
|
||||||
|
|
||||||
|
rc = ntdll_wcstoumbs(name->Buffer, wcslen(name->Buffer) + 1, cname, wcslen(name->Buffer) * 3 + 1, TRUE);
|
||||||
|
if(rc <= 0) {
|
||||||
|
free(cname);
|
||||||
|
return STATUS_SOME_NOT_MAPPED;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Since 2006, Mac computers use Extensible Firmware Interface (EFI).
|
||||||
|
* Apple requires a developer account and mandatory code signing,
|
||||||
|
* and the entire system boot process is verified, we can return SecureBoot enabled.
|
||||||
|
* Reference: https://support.apple.com/guide/security/uefi-firmware-security-in-an-intel-based-mac-seced055bcf6/web
|
||||||
|
*/
|
||||||
|
if(!memcmp(vendor, &secureboot_guid, sizeof(secureboot_guid)) && !strcmp(cname, "SecureBoot"))
|
||||||
|
{
|
||||||
|
if(attrib) *attrib = 0x06;
|
||||||
|
if(buffer && retlen && *retlen == sizeof(BOOLEAN)) *((BOOLEAN *)buffer) = 1;
|
||||||
|
else if(retlen) *retlen = sizeof(BOOLEAN) & 0xFFFFFFFF;
|
||||||
|
free(cname);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cname);
|
||||||
|
return STATUS_VARIABLE_NOT_FOUND;
|
||||||
|
#else
|
||||||
FIXME( "(%s, %s, %p, %p, %p), stub\n", debugstr_us(name),
|
FIXME( "(%s, %s, %p, %p, %p), stub\n", debugstr_us(name),
|
||||||
debugstr_guid(vendor), buffer, retlen, attrib );
|
debugstr_guid(vendor), buffer, retlen, attrib );
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -356,6 +356,9 @@ NTSTATUS WINAPI wow64_NtQuerySystemInformation( UINT *args )
|
||||||
if (retlen) *retlen = sizeof(SYSTEM_BASIC_INFORMATION32);
|
if (retlen) *retlen = sizeof(SYSTEM_BASIC_INFORMATION32);
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
case SystemBootEnvironmentInformation: /* SYSTEM_BOOT_ENVIRONMENT_INFORMATION */
|
||||||
|
return NtQuerySystemInformation(class, ptr, len, retlen);
|
||||||
|
|
||||||
case SystemProcessInformation: /* SYSTEM_PROCESS_INFORMATION */
|
case SystemProcessInformation: /* SYSTEM_PROCESS_INFORMATION */
|
||||||
case SystemExtendedProcessInformation: /* SYSTEM_PROCESS_INFORMATION */
|
case SystemExtendedProcessInformation: /* SYSTEM_PROCESS_INFORMATION */
|
||||||
{
|
{
|
||||||
|
|
|
@ -2219,6 +2219,10 @@ WINBASEAPI DWORD WINAPI GetFileSize(HANDLE,LPDWORD);
|
||||||
WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE,PLARGE_INTEGER);
|
WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE,PLARGE_INTEGER);
|
||||||
WINBASEAPI BOOL WINAPI GetFileTime(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME);
|
WINBASEAPI BOOL WINAPI GetFileTime(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME);
|
||||||
WINBASEAPI DWORD WINAPI GetFileType(HANDLE);
|
WINBASEAPI DWORD WINAPI GetFileType(HANDLE);
|
||||||
|
WINBASEAPI DWORD WINAPI GetFirmwareEnvironmentVariableA(LPCSTR,LPCSTR,PVOID,DWORD);
|
||||||
|
WINBASEAPI DWORD WINAPI GetFirmwareEnvironmentVariableExA(LPCSTR,LPCSTR,PVOID,DWORD,PDWORD);
|
||||||
|
WINBASEAPI DWORD WINAPI GetFirmwareEnvironmentVariableW(LPCWSTR,LPCWSTR,PVOID,DWORD);
|
||||||
|
WINBASEAPI DWORD WINAPI GetFirmwareEnvironmentVariableExW(LPCWSTR,LPCWSTR,PVOID,DWORD,PDWORD);
|
||||||
WINBASEAPI BOOL WINAPI GetFirmwareType(PFIRMWARE_TYPE);
|
WINBASEAPI BOOL WINAPI GetFirmwareType(PFIRMWARE_TYPE);
|
||||||
#define GetFreeSpace(w) (__MSABI_LONG(0x100000))
|
#define GetFreeSpace(w) (__MSABI_LONG(0x100000))
|
||||||
WINBASEAPI DWORD WINAPI GetFullPathNameA(LPCSTR,DWORD,LPSTR,LPSTR*);
|
WINBASEAPI DWORD WINAPI GetFullPathNameA(LPCSTR,DWORD,LPSTR,LPSTR*);
|
||||||
|
|
|
@ -2739,6 +2739,28 @@ typedef struct _SYSTEM_BASIC_INFORMATION {
|
||||||
#endif
|
#endif
|
||||||
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
|
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
/* System Information Class 0x90 */
|
||||||
|
typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
|
||||||
|
{
|
||||||
|
GUID BootIdentifier;
|
||||||
|
FIRMWARE_TYPE FirmwareType;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ULONGLONG BootFlags;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONGLONG DbgMenuOsSelection : 1;
|
||||||
|
ULONGLONG DbgHiberBoot : 1;
|
||||||
|
ULONGLONG DbgSoftBoot : 1;
|
||||||
|
ULONGLONG DbgMeasuredLaunch : 1;
|
||||||
|
ULONGLONG DbgMeasuredLaunchCapable : 1;
|
||||||
|
ULONGLONG DbgSystemHiveReplace : 1;
|
||||||
|
ULONGLONG DbgMeasuredLaunchSmmProtections : 1;
|
||||||
|
ULONGLONG DbgMeasuredLaunchSmmLevel : 7;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION, *PSYSTEM_BOOT_ENVIRONMENT_INFORMATION;
|
||||||
|
|
||||||
/* System Information Class 0x01 */
|
/* System Information Class 0x01 */
|
||||||
|
|
||||||
typedef struct _SYSTEM_CPU_INFORMATION {
|
typedef struct _SYSTEM_CPU_INFORMATION {
|
||||||
|
|
Loading…
Reference in a new issue