/* 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;
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ExFreePoolWithTag(Mdl, TAG_MDL);
- return _SEH2_GetExceptionCode();
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
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 *****************************************************************/
/*
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 */
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 */
{
SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
+ /* Lock the Process */
+ KeEnterCriticalRegion();
+ ExAcquirePushLockShared(&Process->ProcessLock);
+
if ((Process->ProcessExiting) &&
(Process->Pcb.Header.SignalState) &&
!(Process->ActiveThreads) &&
Process, Process->ImageFileName, Process->UniqueProcessId);
CurrentSize = 0;
ImageNameMaximumLength = 0;
+
+ /* Unlock the Process */
+ ExReleasePushLockShared(&Process->ProcessLock);
+ KeLeaveCriticalRegion();
goto Skip;
}
ProcessImageName = NULL;
}
+ /* Unlock the Process */
+ ExReleasePushLockShared(&Process->ProcessLock);
+ KeLeaveCriticalRegion();
+
/* Handle idle process entry */
Skip:
if (Process == PsIdleProcess) Process = NULL;
/* 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)
{
return STATUS_INFO_LENGTH_MISMATCH;
}
-
+
/* FIXME */
DPRINT1("NtQuerySystemInformation - SystemPowerInformation not implemented\n");
return STATUS_NOT_IMPLEMENTED;
/* 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;
}
/* Copy the time zone information struct */
memcpy(Buffer,
&ExpTimeZoneInfo,
- sizeof(TIME_ZONE_INFORMATION));
+ sizeof(RTL_TIME_ZONE_INFORMATION));
return STATUS_SUCCESS;
}
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
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
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);
/*
* @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;