mirror of
https://github.com/reactos/reactos.git
synced 2025-05-07 18:56:48 +00:00
[KERNEL32] Implement system firmware functions properly
This commit is contained in:
parent
b851d7e1d3
commit
844483504b
1 changed files with 44 additions and 201 deletions
|
@ -7,7 +7,8 @@
|
||||||
* Christoph von Wittich
|
* Christoph von Wittich
|
||||||
* Thomas Weidenmueller
|
* Thomas Weidenmueller
|
||||||
* Gunnar Andre Dalsnes
|
* Gunnar Andre Dalsnes
|
||||||
* Stanislav Motylkov
|
* Stanislav Motylkov (x86corez@gmail.com)
|
||||||
|
* Mark Jansen (mark.jansen@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
|
@ -75,80 +76,50 @@ GetSystemInfoInternal(IN PSYSTEM_BASIC_INFORMATION BasicInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
UINT
|
UINT
|
||||||
WINAPI
|
BaseQuerySystemFirmware(IN DWORD FirmwareTableProviderSignature,
|
||||||
GetRawSMBiosTableFromRegistry(OUT PVOID pData)
|
IN DWORD FirmwareTableID,
|
||||||
|
OUT PVOID pFirmwareTableBuffer,
|
||||||
|
IN DWORD BufferSize,
|
||||||
|
IN SYSTEM_FIRMWARE_TABLE_ACTION Action)
|
||||||
{
|
{
|
||||||
static const LPCWSTR RegistryKey = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\mssmbios\\Data";
|
SYSTEM_FIRMWARE_TABLE_INFORMATION* SysFirmwareInfo;
|
||||||
static const LPCWSTR ValueNameStr = L"SMBiosData";
|
ULONG Result = 0, ReturnedSize;
|
||||||
|
ULONG TotalSize = BufferSize + sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION);
|
||||||
PKEY_VALUE_PARTIAL_INFORMATION KeyInfo = NULL;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
UNICODE_STRING KeyName;
|
|
||||||
UNICODE_STRING ValueName;
|
|
||||||
HANDLE KeyHandle;
|
|
||||||
ULONG KeyInfoSize;
|
|
||||||
ULONG ReturnSize = 0;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
RtlInitUnicodeString(&KeyName, RegistryKey);
|
SysFirmwareInfo = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, TotalSize);
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
if (!SysFirmwareInfo)
|
||||||
&KeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Status = NtOpenKey(&KeyHandle,
|
|
||||||
KEY_READ,
|
|
||||||
&ObjectAttributes);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
_SEH2_TRY
|
||||||
// 256 KiB is more than enough for raw SMBIOS dump
|
|
||||||
KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256 * 1024;
|
|
||||||
KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, KeyInfoSize);
|
|
||||||
if (KeyInfo == NULL)
|
|
||||||
{
|
{
|
||||||
NtClose(KeyHandle);
|
SysFirmwareInfo->ProviderSignature = FirmwareTableProviderSignature;
|
||||||
goto cleanup;
|
SysFirmwareInfo->TableID = FirmwareTableID;
|
||||||
|
SysFirmwareInfo->Action = Action;
|
||||||
|
SysFirmwareInfo->TableBufferLength = BufferSize;
|
||||||
|
|
||||||
|
Status = NtQuerySystemInformation(SystemFirmwareTableInformation, SysFirmwareInfo, TotalSize, &ReturnedSize);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
|
||||||
|
Result = SysFirmwareInfo->TableBufferLength;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status) && pFirmwareTableBuffer)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(pFirmwareTableBuffer, SysFirmwareInfo->TableBuffer, SysFirmwareInfo->TableBufferLength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_SEH2_FINALLY
|
||||||
RtlInitUnicodeString(&ValueName, ValueNameStr);
|
|
||||||
|
|
||||||
Status = NtQueryValueKey(KeyHandle,
|
|
||||||
&ValueName,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
KeyInfo,
|
|
||||||
KeyInfoSize,
|
|
||||||
&ReturnSize);
|
|
||||||
|
|
||||||
NtClose(KeyHandle);
|
|
||||||
ReturnSize = 0;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
goto cleanup;
|
RtlFreeHeap(RtlGetProcessHeap(), 0, SysFirmwareInfo);
|
||||||
}
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
if (KeyInfo->Type != REG_BINARY)
|
BaseSetLastNTError(Status);
|
||||||
{
|
return Result;
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnSize = KeyInfo->DataLength;
|
|
||||||
if (pData)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(pData, KeyInfo->Data, KeyInfo->DataLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (KeyInfo)
|
|
||||||
{
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
|
|
||||||
}
|
|
||||||
return ReturnSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
@ -533,69 +504,11 @@ EnumSystemFirmwareTables(IN DWORD FirmwareTableProviderSignature,
|
||||||
OUT PVOID pFirmwareTableBuffer,
|
OUT PVOID pFirmwareTableBuffer,
|
||||||
IN DWORD BufferSize)
|
IN DWORD BufferSize)
|
||||||
{
|
{
|
||||||
UINT uSize = 0;
|
return BaseQuerySystemFirmware(FirmwareTableProviderSignature,
|
||||||
UINT uCount = 0;
|
0,
|
||||||
DWORD dwError = ERROR_SUCCESS;
|
pFirmwareTableBuffer,
|
||||||
PDWORD pBuffer = NULL;
|
BufferSize,
|
||||||
|
SystemFirmwareTable_Enumerate);
|
||||||
switch (FirmwareTableProviderSignature)
|
|
||||||
{
|
|
||||||
case 'ACPI':
|
|
||||||
{
|
|
||||||
/* FIXME: Not implemented yet */
|
|
||||||
dwError = ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'FIRM':
|
|
||||||
{
|
|
||||||
/* FIXME: Not implemented yet */
|
|
||||||
dwError = ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'RSMB':
|
|
||||||
{
|
|
||||||
if (GetRawSMBiosTableFromRegistry(NULL) > 0)
|
|
||||||
{
|
|
||||||
uCount = 1;
|
|
||||||
uSize = uCount * sizeof(DWORD);
|
|
||||||
pBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, uSize);
|
|
||||||
if (!pBuffer)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*pBuffer = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
dwError = ERROR_INVALID_FUNCTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwError == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
if (uSize > 0 && BufferSize >= uSize)
|
|
||||||
{
|
|
||||||
/* Write to buffer */
|
|
||||||
if (pFirmwareTableBuffer)
|
|
||||||
{
|
|
||||||
RtlMoveMemory(pFirmwareTableBuffer, pBuffer, uSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (BufferSize < uSize)
|
|
||||||
{
|
|
||||||
dwError = ERROR_INSUFFICIENT_BUFFER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pBuffer)
|
|
||||||
{
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, pBuffer);
|
|
||||||
}
|
|
||||||
SetLastError(dwError);
|
|
||||||
return uSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -639,81 +552,11 @@ GetSystemFirmwareTable(IN DWORD FirmwareTableProviderSignature,
|
||||||
OUT PVOID pFirmwareTableBuffer,
|
OUT PVOID pFirmwareTableBuffer,
|
||||||
IN DWORD BufferSize)
|
IN DWORD BufferSize)
|
||||||
{
|
{
|
||||||
/* This function currently obtains data using a hack (registry workaround)
|
return BaseQuerySystemFirmware(FirmwareTableProviderSignature,
|
||||||
which is located here: drivers/input/i8042prt/hwhacks.c
|
FirmwareTableID,
|
||||||
i8042StoreSMBiosTables is responsible for writing SMBIOS table into registry
|
pFirmwareTableBuffer,
|
||||||
|
BufferSize,
|
||||||
Should be implemented correctly using NtQuerySystemInformation
|
SystemFirmwareTable_Get);
|
||||||
along with SystemFirmwareTableInformation class
|
|
||||||
|
|
||||||
Reference: https://github.com/hfiref0x/VMDE/blob/master/src/vmde/sup.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
UINT uSize = 0;
|
|
||||||
DWORD dwError = ERROR_SUCCESS;
|
|
||||||
PVOID pBuffer = NULL;
|
|
||||||
|
|
||||||
switch (FirmwareTableProviderSignature)
|
|
||||||
{
|
|
||||||
case 'ACPI':
|
|
||||||
{
|
|
||||||
/* FIXME: Not implemented yet */
|
|
||||||
dwError = ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'FIRM':
|
|
||||||
{
|
|
||||||
/* FIXME: Not implemented yet */
|
|
||||||
dwError = ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'RSMB':
|
|
||||||
{
|
|
||||||
uSize = GetRawSMBiosTableFromRegistry(NULL);
|
|
||||||
if (uSize > 0)
|
|
||||||
{
|
|
||||||
pBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, uSize);
|
|
||||||
if (!pBuffer)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
GetRawSMBiosTableFromRegistry(pBuffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dwError = ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
dwError = ERROR_INVALID_FUNCTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwError == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
if (uSize > 0 && BufferSize >= uSize)
|
|
||||||
{
|
|
||||||
/* Write to buffer */
|
|
||||||
if (pFirmwareTableBuffer)
|
|
||||||
{
|
|
||||||
RtlMoveMemory(pFirmwareTableBuffer, pBuffer, uSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (BufferSize < uSize)
|
|
||||||
{
|
|
||||||
dwError = ERROR_INSUFFICIENT_BUFFER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pBuffer)
|
|
||||||
{
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, pBuffer);
|
|
||||||
}
|
|
||||||
SetLastError(dwError);
|
|
||||||
return uSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue