https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d033fe9bbf03037730826…
commit d033fe9bbf03037730826f12791987935187010c
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Sun Aug 5 16:39:51 2018 +0300
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Aug 19 20:27:59 2018 +0200
[NTOS:EX] Implement SystemFirmwareTableInformation class
---
ntoskrnl/ex/sysinfo.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 187 insertions(+)
diff --git a/ntoskrnl/ex/sysinfo.c b/ntoskrnl/ex/sysinfo.c
index 016ac5b1d9..ab8481b328 100644
--- a/ntoskrnl/ex/sysinfo.c
+++ b/ntoskrnl/ex/sysinfo.c
@@ -11,12 +11,18 @@
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
+#include <wmidata.h>
+#include <wmistr.h>
#define NDEBUG
#include <debug.h>
/* The maximum size of an environment value (in bytes) */
#define MAX_ENVVAL_SIZE 1024
+#define SIG_ACPI 0x41435049
+#define SIG_FIRM 0x4649524D
+#define SIG_RSMB 0x52534D42
+
extern LIST_ENTRY HandleTableListHead;
extern EX_PUSH_LOCK HandleTableListLock;
@@ -239,6 +245,75 @@ ExLockUserBuffer(
return STATUS_SUCCESS;
}
+NTSTATUS
+NTAPI
+ExpGetRawSMBiosTable(
+ _Out_opt_ PVOID Buffer,
+ _Out_ ULONG * OutSize,
+ _In_ ULONG BufferSize)
+{
+ NTSTATUS Status;
+ PVOID DataBlockObject;
+ PWNODE_ALL_DATA AllData;
+ ULONG WMIBufSize;
+
+ ASSERT(OutSize != NULL);
+ *OutSize = 0;
+
+ /* Open the data block object for the SMBIOS table */
+ Status = IoWMIOpenBlock(&MSSmBios_RawSMBiosTables_GUID,
+ WMIGUID_QUERY,
+ &DataBlockObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
+ return Status;
+ }
+
+ /* Query the required buffer size */
+ WMIBufSize = 0;
+ Status = IoWMIQueryAllData(DataBlockObject, &WMIBufSize, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
+ return Status;
+ }
+
+ AllData = ExAllocatePoolWithTag(PagedPool, WMIBufSize, 'itfS');
+ if (AllData == NULL)
+ {
+ DPRINT1("Failed to allocate %lu bytes for SMBIOS tables\n",
WMIBufSize);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Query the buffer data */
+ Status = IoWMIQueryAllData(DataBlockObject, &WMIBufSize, AllData);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
+ ExFreePoolWithTag(AllData, 'itfS');
+ return Status;
+ }
+
+ Status = STATUS_SUCCESS;
+ *OutSize = AllData->FixedInstanceSize;
+ if (Buffer != NULL)
+ {
+ if (BufferSize >= *OutSize)
+ {
+ RtlMoveMemory(Buffer, AllData + 1, *OutSize);
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ }
+
+ /* Free the buffer */
+ ExFreePoolWithTag(AllData, 'itfS');
+ return Status;
+}
+
/* FUNCTIONS *****************************************************************/
/*
@@ -2503,6 +2578,106 @@ QSI_DEF(SystemExtendedHandleInformation)
return Status;
}
+/* Class 76 - System firmware table information */
+QSI_DEF(SystemFirmwareTableInformation)
+{
+ PSYSTEM_FIRMWARE_TABLE_INFORMATION SysFirmwareInfo =
(PSYSTEM_FIRMWARE_TABLE_INFORMATION)Buffer;
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG InputBufSize;
+ ULONG DataSize = 0;
+ ULONG TableCount = 0;
+
+ DPRINT("NtQuerySystemInformation - SystemFirmwareTableInformation\n");
+
+ /* Set initial required buffer size */
+ *ReqSize = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
+
+ /* Check user's buffer size */
+ if (Size < *ReqSize)
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ InputBufSize = SysFirmwareInfo->TableBufferLength;
+ switch (SysFirmwareInfo->ProviderSignature)
+ {
+ /*
+ * ExpFirmwareTableResource and ExpFirmwareTableProviderListHead
+ * variables should be used there somehow...
+ */
+ case SIG_ACPI:
+ {
+ /* FIXME: Not implemented yet */
+ DPRINT1("ACPI provider not implemented\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+ case SIG_FIRM:
+ {
+ /* FIXME: Not implemented yet */
+ DPRINT1("FIRM provider not implemented\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+ case SIG_RSMB:
+ {
+ Status = ExpGetRawSMBiosTable(NULL, &DataSize, 0);
+ if (DataSize > 0)
+ {
+ TableCount = 1;
+ if (SysFirmwareInfo->Action == SystemFirmwareTable_Enumerate)
+ {
+ DataSize = TableCount * sizeof(ULONG);
+ if (DataSize <= InputBufSize)
+ {
+ *(ULONG *)SysFirmwareInfo->TableBuffer = 0;
+ }
+ }
+ else if (SysFirmwareInfo->Action == SystemFirmwareTable_Get
+ && DataSize <= InputBufSize)
+ {
+ Status = ExpGetRawSMBiosTable(SysFirmwareInfo->TableBuffer,
&DataSize, InputBufSize);
+ }
+ SysFirmwareInfo->TableBufferLength = DataSize;
+ }
+ break;
+ }
+ default:
+ {
+ DPRINT1("SystemFirmwareTableInformation: Unsupported provider
(0x%x)\n",
+ SysFirmwareInfo->ProviderSignature);
+ Status = STATUS_ILLEGAL_FUNCTION;
+ }
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ switch (SysFirmwareInfo->Action)
+ {
+ case SystemFirmwareTable_Enumerate:
+ case SystemFirmwareTable_Get:
+ {
+ if (SysFirmwareInfo->TableBufferLength > InputBufSize)
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ break;
+ }
+ default:
+ {
+ DPRINT1("SystemFirmwareTableInformation: Unsupported action
(0x%x)\n",
+ SysFirmwareInfo->Action);
+ Status = STATUS_ILLEGAL_FUNCTION;
+ }
+ }
+ }
+ else
+ {
+ SysFirmwareInfo->TableBufferLength = 0;
+ }
+ return Status;
+}
+
/* Query/Set Calls Table */
typedef
struct _QSSI_CALLS
@@ -2590,6 +2765,18 @@ CallQS [] =
SI_XX(SystemEmulationBasicInformation), /* FIXME: not implemented */
SI_XX(SystemEmulationProcessorInformation), /* FIXME: not implemented */
SI_QX(SystemExtendedHandleInformation),
+ SI_XX(SystemLostDelayedWriteInformation), /* FIXME: not implemented */
+ SI_XX(SystemBigPoolInformation), /* FIXME: not implemented */
+ SI_XX(SystemSessionPoolTagInformation), /* FIXME: not implemented */
+ SI_XX(SystemSessionMappedViewInformation), /* FIXME: not implemented */
+ SI_XX(SystemHotpatchInformation), /* FIXME: not implemented */
+ SI_XX(SystemObjectSecurityMode), /* FIXME: not implemented */
+ SI_XX(SystemWatchdogTimerHandler), /* FIXME: not implemented */
+ SI_XX(SystemWatchdogTimerInformation), /* FIXME: not implemented */
+ SI_XX(SystemLogicalProcessorInformation), /* FIXME: not implemented */
+ SI_XX(SystemWow64SharedInformation), /* FIXME: not implemented */
+ SI_XX(SystemRegisterFirmwareTableInformationHandler), /* FIXME: not implemented */
+ SI_QX(SystemFirmwareTableInformation),
};
C_ASSERT(SystemBasicInformation == 0);