/* The maximum size of an environment value (in bytes) */
#define MAX_ENVVAL_SIZE 1024
+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;
NTSTATUS
NTAPI
NtSetSystemEnvironmentValueEx(IN PUNICODE_STRING VariableName,
- IN LPGUID VendorGuid)
+ IN LPGUID VendorGuid,
+ IN PVOID Value,
+ IN OUT PULONG ReturnLength,
+ IN OUT PULONG Attributes)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
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->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 */
PETHREAD CurrentThread;
ANSI_STRING ImageName;
ULONG CurrentSize;
- USHORT ImageNameMaximumLength; // image name len in bytes
+ USHORT ImageNameMaximumLength; // image name length in bytes
USHORT ImageNameLength;
PLIST_ENTRY CurrentEntry;
ULONG TotalSize = 0, ThreadsCount;
ULONG TotalUser, TotalKernel;
PUCHAR Current;
NTSTATUS Status = STATUS_SUCCESS;
- PUNICODE_STRING ProcessImageName;
+ PUNICODE_STRING TempProcessImageName;
+ _SEH2_VOLATILE PUNICODE_STRING ProcessImageName = NULL;
PWCHAR szSrc;
BOOLEAN Overflow = FALSE;
{
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;
}
// size of the structure for every process
CurrentSize = sizeof(SYSTEM_PROCESS_INFORMATION) + sizeof(SYSTEM_THREAD_INFORMATION) * ThreadsCount;
ImageNameLength = 0;
- Status = SeLocateProcessImageName(Process, &ProcessImageName);
+ Status = SeLocateProcessImageName(Process, &TempProcessImageName);
+ ProcessImageName = TempProcessImageName;
szSrc = NULL;
if (NT_SUCCESS(Status) && (ProcessImageName->Length > 0))
{
/* Fill system information */
if (!Overflow)
{
- SpiCurrent->NextEntryOffset = CurrentSize + ImageNameMaximumLength; // relative offset to the beginnnig of the next structure
+ SpiCurrent->NextEntryOffset = CurrentSize + ImageNameMaximumLength; // relative offset to the beginning of the next structure
SpiCurrent->NumberOfThreads = ThreadsCount;
SpiCurrent->CreateTime = Process->CreateTime;
SpiCurrent->ImageName.Length = ImageNameLength;
if (szSrc)
{
RtlCopyMemory(SpiCurrent->ImageName.Buffer, szSrc, SpiCurrent->ImageName.Length);
-
- /* Release the memory allocated by SeLocateProcessImageName */
- ExFreePoolWithTag(ProcessImageName, TAG_SEPA);
}
else
{
CurrentEntry = Process->Pcb.ThreadListHead.Flink;
while (CurrentEntry != &Process->Pcb.ThreadListHead)
{
- CurrentThread = (PETHREAD)CONTAINING_RECORD(CurrentEntry, KTHREAD,
- ThreadListEntry);
+ CurrentThread = CONTAINING_RECORD(CurrentEntry, ETHREAD, Tcb.ThreadListEntry);
ThreadInfo->KernelTime.QuadPart = UInt32x32To64(CurrentThread->Tcb.KernelTime, KeMaximumIncrement);
ThreadInfo->UserTime.QuadPart = UInt32x32To64(CurrentThread->Tcb.UserTime, KeMaximumIncrement);
SpiCurrent->KernelTime.QuadPart = UInt32x32To64(TotalKernel, KeMaximumIncrement);
}
+ if (ProcessImageName)
+ {
+ /* Release the memory allocated by SeLocateProcessImageName */
+ ExFreePoolWithTag(ProcessImageName, TAG_SEPA);
+ ProcessImageName = NULL;
+ }
+
+ /* Unlock the Process */
+ ExReleasePushLockShared(&Process->ProcessLock);
+ KeLeaveCriticalRegion();
+
/* Handle idle process entry */
Skip:
if (Process == PsIdleProcess) Process = NULL;
{
if(Process != NULL)
ObDereferenceObject(Process);
+ if (ProcessImageName)
+ {
+ /* Release the memory allocated by SeLocateProcessImageName */
+ ExFreePoolWithTag(ProcessImageName, TAG_SEPA);
+ }
+
Status = _SEH2_GetExceptionCode();
}
_SEH2_END
/* Class 9 - Flags Information */
QSI_DEF(SystemFlagsInformation)
{
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
+#endif
+
if (sizeof(SYSTEM_FLAGS_INFORMATION) != Size)
{
- *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
- return (STATUS_INFO_LENGTH_MISMATCH);
+ return STATUS_INFO_LENGTH_MISMATCH;
}
+
((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag;
+#if (NTDDI_VERSION < NTDDI_VISTA)
+ *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
+#endif
+
return STATUS_SUCCESS;
}
{
return STATUS_INFO_LENGTH_MISMATCH;
}
+
+ if (!SeSinglePrivilegeCheck(SeDebugPrivilege, ExGetPreviousMode()))
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
NtGlobalFlag = ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags;
return STATUS_SUCCESS;
}
/* 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;
+ }
- /* First Calc Size from Count. */
- syspr = PsGetNextProcess(NULL);
- pr = syspr;
+ /* Reset of count of handles */
+ HandleInformation->NumberOfHandles = 0;
- do
- {
- hCount = hCount + ObGetProcessHandleCount(pr);
- pr = PsGetNextProcess(pr);
+ /* Enter a critical region */
+ KeEnterCriticalRegion();
- if ((pr == syspr) || (pr == NULL)) break;
- }
- while ((pr != syspr) && (pr != NULL));
+ /* Acquire the handle table lock */
+ ExAcquirePushLockShared(&HandleTableListLock);
- if(pr != NULL)
+ /* Enumerate all system handles */
+ for (NextTableEntry = HandleTableListHead.Flink;
+ NextTableEntry != &HandleTableListHead;
+ NextTableEntry = NextTableEntry->Flink)
{
- ObDereferenceObject(pr);
- }
+ /* Get current handle table */
+ HandleTable = CONTAINING_RECORD(NextTableEntry, HANDLE_TABLE, HandleTableList);
- DPRINT("SystemHandleInformation 2\n");
+ /* 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;
- curSize = sizeof(SYSTEM_HANDLE_INFORMATION) +
- ((sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) -
- (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO)));
+ /* Lock the entry */
+ if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
+ {
+ /* Increase required buffer size */
+ *ReqSize += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO);
- Shi->NumberOfHandles = hCount;
+ /* Check user's buffer size */
+ if (*ReqSize > Size)
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ else
+ {
+ POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
- if (curSize > Size)
- {
- *ReqSize = curSize;
- return (STATUS_INFO_LENGTH_MISMATCH);
- }
+ /* Filling handle information */
+ HandleInformation->Handles[Index].UniqueProcessId =
+ (USHORT)(ULONG_PTR) HandleTable->UniqueProcessId;
- DPRINT("SystemHandleInformation 3\n");
+ HandleInformation->Handles[Index].CreatorBackTraceIndex = 0;
- /* Now get Handles from all processs. */
- syspr = PsGetNextProcess(NULL);
- pr = syspr;
+#if 0 /* FIXME!!! Type field currupted */
+ HandleInformation->Handles[Index].ObjectTypeIndex =
+ (UCHAR) ObjectHeader->Type->Index;
+#else
+ HandleInformation->Handles[Index].ObjectTypeIndex = 0;
+#endif
- do
- {
- int Count = 0, HandleCount;
+ HandleInformation->Handles[Index].HandleAttributes =
+ HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
- HandleCount = ObGetProcessHandleCount(pr);
+ HandleInformation->Handles[Index].HandleValue =
+ (USHORT)(ULONG_PTR) Handle.GenericHandleOverlay;
- for (Count = 0; HandleCount > 0 ; HandleCount--)
- {
- Shi->Handles[i].UniqueProcessId = (USHORT)(ULONG_PTR)pr->UniqueProcessId;
- Count++;
- i++;
- }
+ HandleInformation->Handles[Index].Object = &ObjectHeader->Body;
- pr = PsGetNextProcess(pr);
+ HandleInformation->Handles[Index].GrantedAccess =
+ HandleTableEntry->GrantedAccess;
- if ((pr == syspr) || (pr == NULL)) break;
+ ++Index;
+ }
+
+ /* Unlock it */
+ ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
+ }
+ }
+
+ /* 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)
{
SYSTEM_FILECACHE_INFORMATION *Sci = (SYSTEM_FILECACHE_INFORMATION *) Buffer;
- if (Size < sizeof(SYSTEM_FILECACHE_INFORMATION))
+ *ReqSize = sizeof(SYSTEM_FILECACHE_INFORMATION);
+
+ if (Size < *ReqSize)
{
- *ReqSize = sizeof(SYSTEM_FILECACHE_INFORMATION);
return STATUS_INFO_LENGTH_MISMATCH;
}
return STATUS_NOT_IMPLEMENTED;
}
-/* Class 31 - Event Ids Information */
-QSI_DEF(SystemEventIdsInformation)
+/* Class 31 */
+QSI_DEF(SystemPerformanceTraceInformation)
{
/* FIXME */
- DPRINT1("NtQuerySystemInformation - SystemEventIdsInformation not implemented\n");
+ DPRINT1("NtQuerySystemInformation - SystemPerformanceTraceInformation not implemented\n");
return STATUS_NOT_IMPLEMENTED;
}
{
AlignmentFixupCount += Prcb->KeAlignmentFixupCount;
ExceptionDispatchCount += Prcb->KeExceptionDispatchCount;
+#ifndef _M_ARM
FloatingEmulationCount += Prcb->KeFloatingEmulationCount;
+#endif // _M_ARM
}
}
{
PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION) Buffer;
+#if (NTDDI_VERSION >= NTDDI_VISTA)
*ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION);
+#endif
+
if (Size < sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION))
{
return STATUS_INFO_LENGTH_MISMATCH;
skdi->KernelDebuggerEnabled = KD_DEBUGGER_ENABLED;
skdi->KernelDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT;
+#if (NTDDI_VERSION < NTDDI_VISTA)
+ *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION);
+#endif
+
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
-/* Class 40 - Plug Play Bus Information */
-QSI_DEF(SystemPlugPlayBusInformation)
+/* Class 40 */
+QSI_DEF(SystemVerifierAddDriverInformation)
{
/* FIXME */
- DPRINT1("NtQuerySystemInformation - SystemPlugPlayBusInformation not implemented\n");
+ DPRINT1("NtQuerySystemInformation - SystemVerifierAddDriverInformation not implemented\n");
return STATUS_NOT_IMPLEMENTED;
}
-/* Class 41 - Dock Information */
-QSI_DEF(SystemDockInformation)
+/* Class 41 */
+QSI_DEF(SystemVerifierRemoveDriverInformation)
{
/* FIXME */
- DPRINT1("NtQuerySystemInformation - SystemDockInformation not implemented\n");
+ DPRINT1("NtQuerySystemInformation - SystemVerifierRemoveDriverInformation not implemented\n");
return STATUS_NOT_IMPLEMENTED;
}
/* Class 42 - Power Information */
-QSI_DEF(SystemPowerInformation)
+QSI_DEF(SystemProcessorIdleInformation)
{
+ *ReqSize = sizeof(PROCESSOR_POWER_INFORMATION) * KeNumberProcessors;
+
+ if (sizeof(PROCESSOR_POWER_INFORMATION) * KeNumberProcessors > Size)
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+
/* FIXME */
DPRINT1("NtQuerySystemInformation - SystemPowerInformation not implemented\n");
return STATUS_NOT_IMPLEMENTED;
}
-/* Class 43 - Processor Speed Information */
-QSI_DEF(SystemProcessorSpeedInformation)
+/* Class 43 */
+QSI_DEF(SystemLegacyDriverInformation)
{
/* FIXME */
- DPRINT1("NtQuerySystemInformation - SystemProcessorSpeedInformation not implemented\n");
+ DPRINT1("NtQuerySystemInformation - SystemLegacyDriverInformation 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
/* Class 46 - Set time slip event */
-SSI_DEF(SystemSetTimeSlipEvent)
+SSI_DEF(SystemTimeSlipNotification)
{
/* FIXME */
- DPRINT1("NtSetSystemInformation - SystemSetTimSlipEvent not implemented\n");
+ DPRINT1("NtSetSystemInformation - SystemTimeSlipNotification not implemented\n");
return STATUS_NOT_IMPLEMENTED;
}
MmSessionDelete(IN ULONG SessionId);
/* Class 47 - Create a new session (TSE) */
-SSI_DEF(SystemCreateSession)
+SSI_DEF(SystemSessionCreate)
{
ULONG SessionId;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
{
return STATUS_PRIVILEGE_NOT_HELD;
}
+
+ ProbeForWriteUlong(Buffer);
}
Status = MmSessionCreate(&SessionId);
/* Class 48 - Delete an existing session (TSE) */
-SSI_DEF(SystemDeleteSession)
+SSI_DEF(SystemSessionDetach)
{
ULONG SessionId;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
/* Class 49 - UNKNOWN */
-QSI_DEF(SystemInvalidInfoClass4)
+QSI_DEF(SystemSessionInformation)
{
/* FIXME */
- DPRINT1("NtQuerySystemInformation - SystemInvalidInfoClass4 not implemented\n");
+ DPRINT1("NtQuerySystemInformation - SystemSessionInformation not implemented\n");
return STATUS_NOT_IMPLEMENTED;
}
}
-/* Class 52 - Add a driver verifier */
-SSI_DEF(SystemAddVerifier)
+/* Class 52 */
+SSI_DEF(SystemVerifierThunkExtend)
{
/* FIXME */
- DPRINT1("NtSetSystemInformation - SystemAddVerifier not implemented\n");
+ DPRINT1("NtSetSystemInformation - SystemVerifierThunkExtend not implemented\n");
return STATUS_NOT_IMPLEMENTED;
}
}
+/* Class 54 - Load & map in system space */
+SSI_DEF(SystemLoadGdiDriverInSystemSpaceInformation)
+{
+ /* FIXME */
+ DPRINT1("NtSetSystemInformation - SystemLoadGdiDriverInSystemSpaceInformation not implemented\n");
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Class 55 - NUMA processor information */
+QSI_DEF(SystemNumaProcessorMap)
+{
+ ULONG MaxEntries, Node;
+ PSYSTEM_NUMA_INFORMATION NumaInformation = (PSYSTEM_NUMA_INFORMATION)Buffer;
+
+ /* Validate input size */
+ if (Size < sizeof(ULONG))
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ /* Return highest node */
+ NumaInformation->HighestNodeNumber = KeNumberNodes - 1;
+
+ /* Compute how much entries we will be able to put in output structure */
+ MaxEntries = (Size - FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, ActiveProcessorsAffinityMask)) / sizeof(ULONGLONG);
+ /* Make sure we don't overflow KeNodeBlock */
+ if (MaxEntries > KeNumberNodes)
+ {
+ MaxEntries = KeNumberNodes;
+ }
+
+ /* If we have entries to write, and room for it */
+ if (Size >= FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, ActiveProcessorsAffinityMask) &&
+ MaxEntries != 0)
+ {
+ /* Already set size we return */
+ *ReqSize = FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, ActiveProcessorsAffinityMask) +
+ MaxEntries * sizeof(ULONGLONG);
+
+ /* For each node, return processor mask */
+ for (Node = 0; Node < MaxEntries; ++Node)
+ {
+ NumaInformation->ActiveProcessorsAffinityMask[Node] = KeNodeBlock[Node]->ProcessorMask;
+ }
+ }
+ else
+ {
+ /* We only returned highest node number */
+ *ReqSize = sizeof(ULONG);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+/* Class 56 - Prefetcher information */
+QSI_DEF(SystemPrefetcherInformation)
+{
+ /* FIXME */
+ DPRINT1("NtQuerySystemInformation - SystemPrefetcherInformation not implemented\n");
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Class 57 - Extended process information */
+QSI_DEF(SystemExtendedProcessInformation)
+{
+ /* FIXME */
+ DPRINT1("NtQuerySystemInformation - SystemExtendedProcessInformation not implemented\n");
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Class 58 - Recommended shared ata alignment */
+QSI_DEF(SystemRecommendedSharedDataAlignment)
+{
+ /* FIXME */
+ DPRINT1("NtQuerySystemInformation - SystemRecommendedSharedDataAlignment not implemented\n");
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/* Class 60 - NUMA memory information */
+QSI_DEF(SystemNumaAvailableMemory)
+{
+ ULONG MaxEntries, Node;
+ PSYSTEM_NUMA_INFORMATION NumaInformation = (PSYSTEM_NUMA_INFORMATION)Buffer;
+
+ /* Validate input size */
+ if (Size < sizeof(ULONG))
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ /* Return highest node */
+ NumaInformation->HighestNodeNumber = KeNumberNodes - 1;
+
+ /* Compute how much entries we will be able to put in output structure */
+ MaxEntries = (Size - FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, AvailableMemory)) / sizeof(ULONGLONG);
+ /* Make sure we don't overflow KeNodeBlock */
+ if (MaxEntries > KeNumberNodes)
+ {
+ MaxEntries = KeNumberNodes;
+ }
+
+ /* If we have entries to write, and room for it */
+ if (Size >= FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, AvailableMemory) &&
+ MaxEntries != 0)
+ {
+ /* Already set size we return */
+ *ReqSize = FIELD_OFFSET(SYSTEM_NUMA_INFORMATION, AvailableMemory) +
+ MaxEntries * sizeof(ULONGLONG);
+
+ /* If we have a single entry (us), directly return MM information */
+ if (MaxEntries == 1)
+ {
+ NumaInformation->AvailableMemory[0] = MmAvailablePages << PAGE_SHIFT;
+ }
+ else
+ {
+ /* Otherwise, for each node, return available bytes */
+ for (Node = 0; Node < MaxEntries; ++Node)
+ {
+ NumaInformation->AvailableMemory[Node] = (KeNodeBlock[Node]->FreeCount[0] + KeNodeBlock[Node]->FreeCount[1]) << PAGE_SHIFT;
+ }
+ }
+ }
+ else
+ {
+ /* We only returned highest node number */
+ *ReqSize = sizeof(ULONG);
+ }
+
+ 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;
+}
+
/* Query/Set Calls Table */
typedef
struct _QSSI_CALLS
{
NTSTATUS (* Query) (PVOID,ULONG,PULONG);
NTSTATUS (* Set) (PVOID,ULONG);
-
} QSSI_CALLS;
// QS Query & Set
SI_QX(SystemPerformanceInformation),
SI_QX(SystemTimeOfDayInformation),
SI_QX(SystemPathInformation), /* should be SI_XX */
- SI_QX(SystemProcessInformation), // aka SystemProcessesAndThreadsInformation
- SI_QX(SystemCallCountInformation), // aka SystemCallCounts
- SI_QX(SystemDeviceInformation), // aka SystemConfigurationInformation
- SI_QX(SystemProcessorPerformanceInformation), // aka SystemProcessorTimes
- SI_QS(SystemFlagsInformation), // aka SystemGlobalFlag
+ SI_QX(SystemProcessInformation),
+ SI_QX(SystemCallCountInformation),
+ SI_QX(SystemDeviceInformation),
+ SI_QX(SystemProcessorPerformanceInformation),
+ SI_QS(SystemFlagsInformation),
SI_QX(SystemCallTimeInformation), /* should be SI_XX */
SI_QX(SystemModuleInformation),
- SI_QX(SystemLocksInformation), // aka SystemLockInformation
+ SI_QX(SystemLocksInformation),
SI_QX(SystemStackTraceInformation), /* should be SI_XX */
SI_QX(SystemPagedPoolInformation), /* should be SI_XX */
SI_QX(SystemNonPagedPoolInformation), /* should be SI_XX */
SI_QX(SystemHandleInformation),
SI_QX(SystemObjectInformation),
- SI_QX(SystemPageFileInformation), // aka SystemPagefileInformation
- SI_QX(SystemVdmInstemulInformation), // aka SystemInstructionEmulationCounts
+ SI_QX(SystemPageFileInformation),
+ SI_QX(SystemVdmInstemulInformation),
SI_QX(SystemVdmBopInformation), /* it should be SI_XX */
- SI_QS(SystemFileCacheInformation), // aka SystemCacheInformation
+ SI_QS(SystemFileCacheInformation),
SI_QX(SystemPoolTagInformation),
- SI_QX(SystemInterruptInformation), // aka SystemProcessorStatistics
- SI_QS(SystemDpcBehaviourInformation), // aka SystemDpcInformation
+ SI_QX(SystemInterruptInformation),
+ SI_QS(SystemDpcBehaviourInformation),
SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */
- SI_XS(SystemLoadGdiDriverInformation), // correct: SystemLoadImage
- SI_XS(SystemUnloadGdiDriverInformation), // correct: SystemUnloadImage
- SI_QS(SystemTimeAdjustmentInformation), // aka SystemTimeAdjustment
+ SI_XS(SystemLoadGdiDriverInformation),
+ SI_XS(SystemUnloadGdiDriverInformation),
+ SI_QS(SystemTimeAdjustmentInformation),
SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */
SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */
- SI_QX(SystemEventIdsInformation), /* it should be SI_XX */ // SystemPerformanceTraceInformation
+ SI_QX(SystemPerformanceTraceInformation), /* it should be SI_XX */
SI_QX(SystemCrashDumpInformation),
SI_QX(SystemExceptionInformation),
SI_QX(SystemCrashDumpStateInformation),
SI_QX(SystemKernelDebuggerInformation),
SI_QX(SystemContextSwitchInformation),
SI_QS(SystemRegistryQuotaInformation),
- SI_XS(SystemExtendServiceTableInformation), // correct: SystemLoadAndCallImage
+ SI_XS(SystemExtendServiceTableInformation),
SI_XS(SystemPrioritySeperation),
- SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */
- SI_QX(SystemDockInformation), /* it should be SI_XX */
- SI_QX(SystemPowerInformation), /* it should be SI_XX */ // SystemPowerInformationNative? SystemInvalidInfoClass2
- SI_QX(SystemProcessorSpeedInformation), /* it should be SI_XX */
- SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */ // aka SystemTimeZoneInformation
+ SI_QX(SystemVerifierAddDriverInformation), /* it should be SI_XX */
+ SI_QX(SystemVerifierRemoveDriverInformation), /* it should be SI_XX */
+ SI_QX(SystemProcessorIdleInformation), /* it should be SI_XX */
+ SI_QX(SystemLegacyDriverInformation), /* it should be SI_XX */
+ SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */
SI_QX(SystemLookasideInformation),
- SI_XS(SystemSetTimeSlipEvent),
- SI_XS(SystemCreateSession),
- SI_XS(SystemDeleteSession),
- SI_QX(SystemInvalidInfoClass4), /* it should be SI_XX */ // SystemSessionInformation?
+ SI_XS(SystemTimeSlipNotification),
+ SI_XS(SystemSessionCreate),
+ SI_XS(SystemSessionDetach),
+ SI_QX(SystemSessionInformation), /* it should be SI_XX */
SI_QX(SystemRangeStartInformation),
SI_QS(SystemVerifierInformation),
- SI_XS(SystemAddVerifier),
- SI_QX(SystemSessionProcessesInformation)
+ SI_XS(SystemVerifierThunkExtend),
+ SI_QX(SystemSessionProcessesInformation),
+ SI_XS(SystemLoadGdiDriverInSystemSpaceInformation),
+ SI_QX(SystemNumaProcessorMap),
+ SI_QX(SystemPrefetcherInformation),
+ SI_QX(SystemExtendedProcessInformation),
+ SI_QX(SystemRecommendedSharedDataAlignment),
+ SI_XX(SystemComPlusPackage),
+ SI_QX(SystemNumaAvailableMemory),
+ SI_XX(SystemProcessorPowerInformation), /* FIXME: not implemented */
+ SI_XX(SystemEmulationBasicInformation), /* FIXME: not implemented */
+ SI_XX(SystemEmulationProcessorInformation), /* FIXME: not implemented */
+ SI_QX(SystemExtendedHandleInformation),
};
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;
+ ULONG Alignment = TYPE_ALIGNMENT(ULONG);
NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED;
PAGED_CODE();
_SEH2_TRY
{
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ /*
+ * Check if the request is valid.
+ */
+ if (SystemInformationClass >= MAX_SYSTEM_INFO_CLASS)
+ {
+ _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS);
+ }
+#endif
+
if (PreviousMode != KernelMode)
{
/* SystemKernelDebuggerInformation needs only BOOLEAN alignment */
- ProbeForWrite(SystemInformation, Length, 1);
+ if (SystemInformationClass == SystemKernelDebuggerInformation)
+ Alignment = TYPE_ALIGNMENT(BOOLEAN);
+
+ ProbeForWrite(SystemInformation, Length, Alignment);
if (UnsafeResultLength != NULL)
ProbeForWriteUlong(UnsafeResultLength);
}
if (UnsafeResultLength)
*UnsafeResultLength = 0;
+#if (NTDDI_VERSION < NTDDI_VISTA)
/*
* Check if the request is valid.
*/
{
_SEH2_YIELD(return STATUS_INVALID_INFO_CLASS);
}
+#endif
if (NULL != CallQS [SystemInformationClass].Query)
{
IN PVOID SystemInformation,
IN ULONG SystemInformationLength)
{
+ NTSTATUS Status = STATUS_INVALID_INFO_CLASS;
+ KPROCESSOR_MODE PreviousMode;
+
PAGED_CODE();
- /*
- * If called from user mode, check
- * possible unsafe arguments.
- */
-#if 0
- if (KernelMode != KeGetPreviousMode())
- {
- // Check arguments
- //ProbeForWrite(
- // SystemInformation,
- // Length
- // );
- //ProbeForWrite(
- // ResultLength,
- // sizeof (ULONG)
- // );
- }
-#endif
- /*
- * Check the request is valid.
- */
- if ((SystemInformationClass >= MIN_SYSTEM_INFO_CLASS) &&
- (SystemInformationClass < MAX_SYSTEM_INFO_CLASS))
+ PreviousMode = ExGetPreviousMode();
+
+ _SEH2_TRY
{
- if (NULL != CallQS [SystemInformationClass].Set)
+ /*
+ * If called from user mode, check
+ * possible unsafe arguments.
+ */
+ if (PreviousMode != KernelMode)
{
- /*
- * Hand the request to a subhandler.
- */
- return CallQS [SystemInformationClass].Set(SystemInformation,
- SystemInformationLength);
+ ProbeForRead(SystemInformation, SystemInformationLength, sizeof(ULONG));
}
- }
-
- return STATUS_INVALID_INFO_CLASS;
-}
-NTSTATUS
-NTAPI
-NtFlushInstructionCache(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN ULONG NumberOfBytesToFlush)
-{
- PAGED_CODE();
+ /*
+ * Check the request is valid.
+ */
+ if ((SystemInformationClass >= MIN_SYSTEM_INFO_CLASS) &&
+ (SystemInformationClass < MAX_SYSTEM_INFO_CLASS))
+ {
+ if (NULL != CallQS [SystemInformationClass].Set)
+ {
+ /*
+ * Hand the request to a subhandler.
+ */
+ Status = CallQS [SystemInformationClass].Set(SystemInformation,
+ SystemInformationLength);
+ }
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
-#if defined(_M_IX86) || defined(_M_AMD64)
- __wbinvd();
-#elif defined(_M_PPC)
- __asm__ __volatile__("tlbsync");
-#elif defined(_M_MIPS)
- DPRINT1("NtFlushInstructionCache() is not implemented\n");
- for (;;);
-#elif defined(_M_ARM)
- __asm__ __volatile__("mov r1, #0; mcr p15, 0, r1, c7, c5, 0");
-#else
-#error Unknown architecture
-#endif
- return STATUS_SUCCESS;
+ return Status;
}
ULONG
NTAPI
NtGetCurrentProcessorNumber(VOID)
{
- /* Just return the CPU */
+ /* Just use Ke */
return KeGetCurrentProcessorNumber();
}
-/*
- * @implemented
- */
#undef ExGetPreviousMode
KPROCESSOR_MODE
NTAPI
-ExGetPreviousMode (VOID)
+ExGetPreviousMode(VOID)
{
+ /* Just use Ke */
return KeGetPreviousMode();
}