https://git.reactos.org/?p=reactos.git;a=commitdiff;h=844483504b94b6f187b22…
commit 844483504b94b6f187b22209c42cece07077a43a
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Sun Aug 5 11:48:25 2018 +0300
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Aug 19 20:27:59 2018 +0200
[KERNEL32] Implement system firmware functions properly
---
dll/win32/kernel32/client/sysinfo.c | 239 +++++++-----------------------------
1 file changed, 41 insertions(+), 198 deletions(-)
diff --git a/dll/win32/kernel32/client/sysinfo.c b/dll/win32/kernel32/client/sysinfo.c
index 92474d050a..0e588b3e44 100644
--- a/dll/win32/kernel32/client/sysinfo.c
+++ b/dll/win32/kernel32/client/sysinfo.c
@@ -7,7 +7,8 @@
* Christoph von Wittich
* Thomas Weidenmueller
* Gunnar Andre Dalsnes
- * Stanislav Motylkov
+ * Stanislav Motylkov (x86corez(a)gmail.com)
+ * Mark Jansen (mark.jansen(a)reactos.org)
*/
/* INCLUDES *******************************************************************/
@@ -75,80 +76,50 @@ GetSystemInfoInternal(IN PSYSTEM_BASIC_INFORMATION BasicInfo,
}
}
+static
UINT
-WINAPI
-GetRawSMBiosTableFromRegistry(OUT PVOID pData)
+BaseQuerySystemFirmware(IN DWORD FirmwareTableProviderSignature,
+ 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";
- static const LPCWSTR ValueNameStr = L"SMBiosData";
-
- PKEY_VALUE_PARTIAL_INFORMATION KeyInfo = NULL;
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName;
- UNICODE_STRING ValueName;
- HANDLE KeyHandle;
- ULONG KeyInfoSize;
- ULONG ReturnSize = 0;
+ SYSTEM_FIRMWARE_TABLE_INFORMATION* SysFirmwareInfo;
+ ULONG Result = 0, ReturnedSize;
+ ULONG TotalSize = BufferSize + sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION);
NTSTATUS Status;
- RtlInitUnicodeString(&KeyName, RegistryKey);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- Status = NtOpenKey(&KeyHandle,
- KEY_READ,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
+ SysFirmwareInfo = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, TotalSize);
+ if (!SysFirmwareInfo)
{
+ SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
-
- // 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)
+ _SEH2_TRY
{
- NtClose(KeyHandle);
- goto cleanup;
- }
+ SysFirmwareInfo->ProviderSignature = FirmwareTableProviderSignature;
+ SysFirmwareInfo->TableID = FirmwareTableID;
+ SysFirmwareInfo->Action = Action;
+ SysFirmwareInfo->TableBufferLength = BufferSize;
- RtlInitUnicodeString(&ValueName, ValueNameStr);
+ Status = NtQuerySystemInformation(SystemFirmwareTableInformation,
SysFirmwareInfo, TotalSize, &ReturnedSize);
- Status = NtQueryValueKey(KeyHandle,
- &ValueName,
- KeyValuePartialInformation,
- KeyInfo,
- KeyInfoSize,
- &ReturnSize);
-
- NtClose(KeyHandle);
- ReturnSize = 0;
-
- if (!NT_SUCCESS(Status))
- {
- goto cleanup;
- }
+ if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
+ Result = SysFirmwareInfo->TableBufferLength;
- if (KeyInfo->Type != REG_BINARY)
- {
- goto cleanup;
+ if (NT_SUCCESS(Status) && pFirmwareTableBuffer)
+ {
+ RtlCopyMemory(pFirmwareTableBuffer, SysFirmwareInfo->TableBuffer,
SysFirmwareInfo->TableBufferLength);
+ }
}
-
- ReturnSize = KeyInfo->DataLength;
- if (pData)
+ _SEH2_FINALLY
{
- RtlCopyMemory(pData, KeyInfo->Data, KeyInfo->DataLength);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, SysFirmwareInfo);
}
+ _SEH2_END;
-cleanup:
- if (KeyInfo)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
- }
- return ReturnSize;
+ BaseSetLastNTError(Status);
+ return Result;
}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -533,69 +504,11 @@ EnumSystemFirmwareTables(IN DWORD FirmwareTableProviderSignature,
OUT PVOID pFirmwareTableBuffer,
IN DWORD BufferSize)
{
- UINT uSize = 0;
- UINT uCount = 0;
- DWORD dwError = ERROR_SUCCESS;
- PDWORD 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':
- {
- 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;
+ return BaseQuerySystemFirmware(FirmwareTableProviderSignature,
+ 0,
+ pFirmwareTableBuffer,
+ BufferSize,
+ SystemFirmwareTable_Enumerate);
}
/**
@@ -639,81 +552,11 @@ GetSystemFirmwareTable(IN DWORD FirmwareTableProviderSignature,
OUT PVOID pFirmwareTableBuffer,
IN DWORD BufferSize)
{
- /* This function currently obtains data using a hack (registry workaround)
- which is located here: drivers/input/i8042prt/hwhacks.c
- i8042StoreSMBiosTables is responsible for writing SMBIOS table into registry
-
- Should be implemented correctly using NtQuerySystemInformation
- 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;
+ return BaseQuerySystemFirmware(FirmwareTableProviderSignature,
+ FirmwareTableID,
+ pFirmwareTableBuffer,
+ BufferSize,
+ SystemFirmwareTable_Get);
}
/*