https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d033fe9bbf03037730826f12791987935187010c

commit d033fe9bbf03037730826f12791987935187010c
Author:     Stanislav Motylkov <[email protected]>
AuthorDate: Sun Aug 5 16:39:51 2018 +0300
Commit:     Mark Jansen <[email protected]>
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);

Reply via email to