[NTOSKRNL] Add the CcPinMappedDataCount counter
[reactos.git] / ntoskrnl / ex / sysinfo.c
index 2f6195f..09b9a63 100644 (file)
 /* 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;
+
 FAST_MUTEX ExpEnvironmentLock;
 ERESOURCE ExpFirmwareTableResource;
 LIST_ENTRY ExpFirmwareTableProviderListHead;
@@ -219,7 +228,7 @@ ExLockUserBuffer(
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
         ExFreePoolWithTag(Mdl, TAG_MDL);
-        return _SEH2_GetExceptionCode();
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
     _SEH2_END;
 
@@ -236,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 *****************************************************************/
 
 /*
@@ -684,14 +762,14 @@ QSI_DEF(SystemPerformanceInformation)
     Spi->CcFastMdlReadResourceMiss = 0; /* FIXME */
     Spi->CcFastMdlReadNotPossible = 0; /* FIXME */
 
-    Spi->CcMapDataNoWait = 0; /* FIXME */
-    Spi->CcMapDataWait = 0; /* FIXME */
+    Spi->CcMapDataNoWait = CcMapDataNoWait;
+    Spi->CcMapDataWait = CcMapDataWait;
     Spi->CcMapDataNoWaitMiss = 0; /* FIXME */
     Spi->CcMapDataWaitMiss = 0; /* FIXME */
 
-    Spi->CcPinMappedDataCount = 0; /* FIXME */
-    Spi->CcPinReadNoWait = 0; /* FIXME */
-    Spi->CcPinReadWait = 0; /* FIXME */
+    Spi->CcPinMappedDataCount = CcPinMappedDataCount;
+    Spi->CcPinReadNoWait = CcPinReadNoWait;
+    Spi->CcPinReadWait = CcPinReadWait;
     Spi->CcPinReadNoWaitMiss = 0; /* FIXME */
     Spi->CcPinReadWaitMiss = 0; /* FIXME */
     Spi->CcCopyReadNoWait = 0; /* FIXME */
@@ -704,10 +782,10 @@ QSI_DEF(SystemPerformanceInformation)
     Spi->CcMdlReadNoWaitMiss = 0; /* FIXME */
     Spi->CcMdlReadWaitMiss = 0; /* FIXME */
     Spi->CcReadAheadIos = 0; /* FIXME */
-    Spi->CcLazyWriteIos = 0; /* FIXME */
-    Spi->CcLazyWritePages = 0; /* FIXME */
-    Spi->CcDataFlushes = 0; /* FIXME */
-    Spi->CcDataPages = 0; /* FIXME */
+    Spi->CcLazyWriteIos = CcLazyWriteIos;
+    Spi->CcLazyWritePages = CcLazyWritePages;
+    Spi->CcDataFlushes = CcDataFlushes;
+    Spi->CcDataPages = CcDataPages;
     Spi->ContextSwitches = 0; /* FIXME */
     Spi->FirstLevelTbFills = 0; /* FIXME */
     Spi->SecondLevelTbFills = 0; /* FIXME */
@@ -809,6 +887,10 @@ QSI_DEF(SystemProcessInformation)
         {
             SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
 
+            /* Lock the Process */
+            KeEnterCriticalRegion();
+            ExAcquirePushLockShared(&Process->ProcessLock);
+
             if ((Process->ProcessExiting) &&
                 (Process->Pcb.Header.SignalState) &&
                 !(Process->ActiveThreads) &&
@@ -818,6 +900,10 @@ QSI_DEF(SystemProcessInformation)
                         Process, Process->ImageFileName, Process->UniqueProcessId);
                 CurrentSize = 0;
                 ImageNameMaximumLength = 0;
+
+                /* Unlock the Process */
+                ExReleasePushLockShared(&Process->ProcessLock);
+                KeLeaveCriticalRegion();
                 goto Skip;
             }
 
@@ -952,6 +1038,10 @@ QSI_DEF(SystemProcessInformation)
                 ProcessImageName = NULL;
             }
 
+            /* Unlock the Process */
+            ExReleasePushLockShared(&Process->ProcessLock);
+            KeLeaveCriticalRegion();
+
             /* Handle idle process entry */
 Skip:
             if (Process == PsIdleProcess) Process = NULL;
@@ -1167,93 +1257,131 @@ QSI_DEF(SystemNonPagedPoolInformation)
 /* Class 16 - Handle Information */
 QSI_DEF(SystemHandleInformation)
 {
-    PEPROCESS pr, syspr;
-    ULONG curSize, i = 0;
-    ULONG hCount = 0;
-
-    PSYSTEM_HANDLE_INFORMATION Shi =
-        (PSYSTEM_HANDLE_INFORMATION) Buffer;
+    PSYSTEM_HANDLE_INFORMATION HandleInformation;
+    PLIST_ENTRY NextTableEntry;
+    PHANDLE_TABLE HandleTable;
+    PHANDLE_TABLE_ENTRY HandleTableEntry;
+    EXHANDLE Handle;
+    ULONG Index = 0;
+    NTSTATUS Status;
+    PMDL Mdl;
+    PAGED_CODE();
 
     DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
 
-    if (Size < sizeof(SYSTEM_HANDLE_INFORMATION))
+    /* Set initial required buffer size */
+    *ReqSize = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handles);
+
+    /* Check user's buffer size */
+    if (Size < *ReqSize)
     {
-        *ReqSize = sizeof(SYSTEM_HANDLE_INFORMATION);
         return STATUS_INFO_LENGTH_MISMATCH;
     }
 
-    DPRINT("SystemHandleInformation 1\n");
+    /* We need to lock down the memory */
+    Status = ExLockUserBuffer(Buffer,
+                              Size,
+                              ExGetPreviousMode(),
+                              IoWriteAccess,
+                              (PVOID*)&HandleInformation,
+                              &Mdl);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to lock the user buffer: 0x%lx\n", Status);
+        return Status;
+    }
+
+    /* Reset of count of handles */
+    HandleInformation->NumberOfHandles = 0;
 
-    /* First Calc Size from Count. */
-    syspr = PsGetNextProcess(NULL);
-    pr = syspr;
+    /* Enter a critical region */
+    KeEnterCriticalRegion();
 
-    do
+    /* Acquire the handle table lock */
+    ExAcquirePushLockShared(&HandleTableListLock);
+
+    /* Enumerate all system handles */
+    for (NextTableEntry = HandleTableListHead.Flink;
+         NextTableEntry != &HandleTableListHead;
+         NextTableEntry = NextTableEntry->Flink)
     {
-        hCount = hCount + ObGetProcessHandleCount(pr);
-        pr = PsGetNextProcess(pr);
+        /* Get current handle table */
+        HandleTable = CONTAINING_RECORD(NextTableEntry, HANDLE_TABLE, HandleTableList);
 
-        if ((pr == syspr) || (pr == NULL)) break;
-    }
-    while ((pr != syspr) && (pr != NULL));
+        /* Set the initial value and loop the entries */
+        Handle.Value = 0;
+        while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
+        {
+            /* Validate the entry */
+            if ((HandleTableEntry->Object) &&
+                (HandleTableEntry->NextFreeTableEntry != -2))
+            {
+                /* Increase of count of handles */
+                ++HandleInformation->NumberOfHandles;
 
-    if(pr != NULL)
-    {
-        ObDereferenceObject(pr);
-    }
+                /* Lock the entry */
+                if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
+                {
+                    /* Increase required buffer size */
+                    *ReqSize += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO);
 
-    DPRINT("SystemHandleInformation 2\n");
+                    /* Check user's buffer size */
+                    if (*ReqSize > Size)
+                    {
+                        Status = STATUS_INFO_LENGTH_MISMATCH;
+                    }
+                    else
+                    {
+                        POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
 
-    curSize = sizeof(SYSTEM_HANDLE_INFORMATION) +
-                     ((sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) -
-                     (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO)));
+                        /* Filling handle information */
+                        HandleInformation->Handles[Index].UniqueProcessId =
+                            (USHORT)(ULONG_PTR) HandleTable->UniqueProcessId;
 
-    Shi->NumberOfHandles = hCount;
+                        HandleInformation->Handles[Index].CreatorBackTraceIndex = 0;
 
-    if (curSize > Size)
-    {
-        *ReqSize = curSize;
-        return (STATUS_INFO_LENGTH_MISMATCH);
-    }
+#if 0 /* FIXME!!! Type field currupted */
+                        HandleInformation->Handles[Index].ObjectTypeIndex =
+                            (UCHAR) ObjectHeader->Type->Index;
+#else
+                        HandleInformation->Handles[Index].ObjectTypeIndex = 0;
+#endif
 
-    DPRINT("SystemHandleInformation 3\n");
+                        HandleInformation->Handles[Index].HandleAttributes =
+                            HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
 
-    /* Now get Handles from all processes. */
-    syspr = PsGetNextProcess(NULL);
-    pr = syspr;
+                        HandleInformation->Handles[Index].HandleValue =
+                            (USHORT)(ULONG_PTR) Handle.GenericHandleOverlay;
 
-    do
-    {
-        int Count = 0, HandleCount;
+                        HandleInformation->Handles[Index].Object = &ObjectHeader->Body;
 
-        HandleCount = ObGetProcessHandleCount(pr);
+                        HandleInformation->Handles[Index].GrantedAccess =
+                            HandleTableEntry->GrantedAccess;
 
-        for (Count = 0; HandleCount > 0 ; HandleCount--)
-        {
-            Shi->Handles[i].UniqueProcessId = (USHORT)(ULONG_PTR)pr->UniqueProcessId;
-            Count++;
-            i++;
-        }
+                        ++Index;
+                    }
 
-        pr = PsGetNextProcess(pr);
+                    /* Unlock it */
+                    ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
+                }
+            }
 
-        if ((pr == syspr) || (pr == NULL)) break;
+            /* Go to the next entry */
+            Handle.Value += sizeof(HANDLE);
+        }
     }
-    while ((pr != syspr) && (pr != NULL));
 
-    if(pr != NULL) ObDereferenceObject(pr);
+    /* Release the lock */
+    ExReleasePushLockShared(&HandleTableListLock);
 
-    DPRINT("SystemHandleInformation 4\n");
-    return STATUS_SUCCESS;
+    /* Leave the critical region */
+    KeLeaveCriticalRegion();
 
-}
-/*
-SSI_DEF(SystemHandleInformation)
-{
+    /* Release the locked user buffer */
+    ExUnlockUserBuffer(Mdl);
 
-    return STATUS_SUCCESS;
+    return Status;
 }
-*/
 
 /* Class 17 -  Information */
 QSI_DEF(SystemObjectInformation)
@@ -1869,7 +1997,7 @@ QSI_DEF(SystemProcessorIdleInformation)
     {
         return STATUS_INFO_LENGTH_MISMATCH;
     }
-    
+
     /* FIXME */
     DPRINT1("NtQuerySystemInformation - SystemPowerInformation not implemented\n");
     return STATUS_NOT_IMPLEMENTED;
@@ -1886,9 +2014,9 @@ QSI_DEF(SystemLegacyDriverInformation)
 /* Class 44 - Current Time Zone Information */
 QSI_DEF(SystemCurrentTimeZoneInformation)
 {
-    *ReqSize = sizeof(TIME_ZONE_INFORMATION);
+    *ReqSize = sizeof(RTL_TIME_ZONE_INFORMATION);
 
-    if (sizeof(TIME_ZONE_INFORMATION) != Size)
+    if (sizeof(RTL_TIME_ZONE_INFORMATION) != Size)
     {
         return STATUS_INFO_LENGTH_MISMATCH;
     }
@@ -1896,7 +2024,7 @@ QSI_DEF(SystemCurrentTimeZoneInformation)
     /* Copy the time zone information struct */
     memcpy(Buffer,
            &ExpTimeZoneInfo,
-           sizeof(TIME_ZONE_INFORMATION));
+           sizeof(RTL_TIME_ZONE_INFORMATION));
 
     return STATUS_SUCCESS;
 }
@@ -1905,12 +2033,12 @@ QSI_DEF(SystemCurrentTimeZoneInformation)
 SSI_DEF(SystemCurrentTimeZoneInformation)
 {
     /* Check user buffer's size */
-    if (Size < sizeof(TIME_ZONE_INFORMATION))
+    if (Size < sizeof(RTL_TIME_ZONE_INFORMATION))
     {
         return STATUS_INFO_LENGTH_MISMATCH;
     }
 
-    return ExpSetTimeZoneInformation((PTIME_ZONE_INFORMATION)Buffer);
+    return ExpSetTimeZoneInformation((PRTL_TIME_ZONE_INFORMATION)Buffer);
 }
 
 static
@@ -2319,6 +2447,236 @@ QSI_DEF(SystemNumaAvailableMemory)
     return STATUS_SUCCESS;
 }
 
+/* Class 64 - Extended handle information  */
+QSI_DEF(SystemExtendedHandleInformation)
+{
+    PSYSTEM_HANDLE_INFORMATION_EX HandleInformation;
+    PLIST_ENTRY NextTableEntry;
+    PHANDLE_TABLE HandleTable;
+    PHANDLE_TABLE_ENTRY HandleTableEntry;
+    EXHANDLE Handle;
+    ULONG Index = 0;
+    NTSTATUS Status;
+    PMDL Mdl;
+    PAGED_CODE();
+
+    DPRINT("NtQuerySystemInformation - SystemExtendedHandleInformation\n");
+
+    /* Set initial required buffer size */
+    *ReqSize = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handle);
+
+    /* Check user's buffer size */
+    if (Size < *ReqSize)
+    {
+        return STATUS_INFO_LENGTH_MISMATCH;
+    }
+
+    /* We need to lock down the memory */
+    Status = ExLockUserBuffer(Buffer,
+                              Size,
+                              ExGetPreviousMode(),
+                              IoWriteAccess,
+                              (PVOID*)&HandleInformation,
+                              &Mdl);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to lock the user buffer: 0x%lx\n", Status);
+        return Status;
+    }
+
+    /* Reset of count of handles */
+    HandleInformation->Count = 0;
+
+    /* Enter a critical region */
+    KeEnterCriticalRegion();
+
+    /* Acquire the handle table lock */
+    ExAcquirePushLockShared(&HandleTableListLock);
+
+    /* Enumerate all system handles */
+    for (NextTableEntry = HandleTableListHead.Flink;
+         NextTableEntry != &HandleTableListHead;
+         NextTableEntry = NextTableEntry->Flink)
+    {
+        /* Get current handle table */
+        HandleTable = CONTAINING_RECORD(NextTableEntry, HANDLE_TABLE, HandleTableList);
+
+        /* Set the initial value and loop the entries */
+        Handle.Value = 0;
+        while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
+        {
+            /* Validate the entry */
+            if ((HandleTableEntry->Object) &&
+                (HandleTableEntry->NextFreeTableEntry != -2))
+            {
+                /* Increase of count of handles */
+                ++HandleInformation->Count;
+
+                /* Lock the entry */
+                if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
+                {
+                    /* Increase required buffer size */
+                    *ReqSize += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX);
+
+                    /* Check user's buffer size */
+                    if (*ReqSize > Size)
+                    {
+                        Status = STATUS_INFO_LENGTH_MISMATCH;
+                    }
+                    else
+                    {
+                        POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
+
+                        /* Filling handle information */
+                        HandleInformation->Handle[Index].UniqueProcessId =
+                            (USHORT)(ULONG_PTR) HandleTable->UniqueProcessId;
+
+                        HandleInformation->Handle[Index].CreatorBackTraceIndex = 0;
+
+#if 0 /* FIXME!!! Type field currupted */
+                        HandleInformation->Handles[Index].ObjectTypeIndex =
+                            (UCHAR) ObjectHeader->Type->Index;
+#else
+                        HandleInformation->Handle[Index].ObjectTypeIndex = 0;
+#endif
+
+                        HandleInformation->Handle[Index].HandleAttributes =
+                            HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
+
+                        HandleInformation->Handle[Index].HandleValue =
+                            (USHORT)(ULONG_PTR) Handle.GenericHandleOverlay;
+
+                        HandleInformation->Handle[Index].Object = &ObjectHeader->Body;
+
+                        HandleInformation->Handle[Index].GrantedAccess =
+                            HandleTableEntry->GrantedAccess;
+
+                        HandleInformation->Handle[Index].Reserved = 0;
+
+                        ++Index;
+                    }
+
+                    /* Unlock it */
+                    ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
+                }
+            }
+
+            /* Go to the next entry */
+            Handle.Value += sizeof(HANDLE);
+        }
+    }
+
+    /* Release the lock */
+    ExReleasePushLockShared(&HandleTableListLock);
+
+    /* Leave the critical region */
+    KeLeaveCriticalRegion();
+
+    /* Release the locked user buffer */
+    ExUnlockUserBuffer(Mdl);
+
+    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
@@ -2402,7 +2760,23 @@ CallQS [] =
     SI_QX(SystemExtendedProcessInformation),
     SI_QX(SystemRecommendedSharedDataAlignment),
     SI_XX(SystemComPlusPackage),
-    SI_QX(SystemNumaAvailableMemory)
+    SI_QX(SystemNumaAvailableMemory),
+    SI_XX(SystemProcessorPowerInformation), /* FIXME: not implemented */
+    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);
@@ -2412,11 +2786,14 @@ C_ASSERT(SystemBasicInformation == 0);
 /*
  * @implemented
  */
-NTSTATUS NTAPI
-NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
-                         OUT PVOID SystemInformation,
-                         IN ULONG Length,
-                         OUT PULONG UnsafeResultLength)
+__kernel_entry
+NTSTATUS
+NTAPI
+NtQuerySystemInformation(
+    _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
+    _Out_writes_bytes_to_opt_(SystemInformationLength, *ReturnLength) PVOID SystemInformation,
+    _In_ ULONG Length,
+    _Out_opt_ PULONG UnsafeResultLength)
 {
     KPROCESSOR_MODE PreviousMode;
     ULONG ResultLength = 0;