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;
// 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;
+ }
+
/* 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
DPRINT("SystemHandleInformation 3\n");
- /* Now get Handles from all processs. */
+ /* Now get Handles from all processes. */
syspr = PsGetNextProcess(NULL);
pr = syspr;
{
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;
}
{
AlignmentFixupCount += Prcb->KeAlignmentFixupCount;
ExceptionDispatchCount += Prcb->KeExceptionDispatchCount;
+#ifndef _M_ARM
FloatingEmulationCount += Prcb->KeFloatingEmulationCount;
+#endif // _M_ARM
}
}
/* Class 42 - Power Information */
QSI_DEF(SystemPowerInformation)
{
+ *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 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;
+}
+
+
/* Query/Set Calls Table */
typedef
struct _QSSI_CALLS
SI_QX(SystemRangeStartInformation),
SI_QS(SystemVerifierInformation),
SI_XS(SystemAddVerifier),
- SI_QX(SystemSessionProcessesInformation)
+ SI_QX(SystemSessionProcessesInformation),
+ SI_XS(SystemLoadGdiDriverInSystemSpaceInformation),
+ SI_QX(SystemNumaProcessorMap),
+ SI_QX(SystemPrefetcherInformation),
+ SI_QX(SystemExtendedProcessInformation),
+ SI_QX(SystemRecommendedSharedDataAlignment),
+ SI_XX(SystemComPlusPackage),
+ SI_QX(SystemNumaAvailableMemory)
};
C_ASSERT(SystemBasicInformation == 0);
NTSTATUS
NTAPI
-NtFlushInstructionCache(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN ULONG NumberOfBytesToFlush)
+NtFlushInstructionCache(
+ _In_ HANDLE ProcessHandle,
+ _In_opt_ PVOID BaseAddress,
+ _In_ ULONG FlushSize)
{
+ KAPC_STATE ApcState;
+ PKPROCESS Process;
+ NTSTATUS Status;
PAGED_CODE();
+ /* Is a base address given? */
+ if (BaseAddress != NULL)
+ {
+ /* If the requested size is 0, there is nothing to do */
+ if (FlushSize == 0)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ /* Is this a user mode call? */
+ if (KeGetPreviousMode() != KernelMode)
+ {
+ /* Make sure the base address is in user space */
+ if (BaseAddress > MmHighestUserAddress)
+ {
+ DPRINT1("Invalid BaseAddress 0x%p\n", BaseAddress);
+ return STATUS_ACCESS_VIOLATION;
+ }
+ }
+ }
+
+ /* Is another process requested? */
+ if (ProcessHandle != NtCurrentProcess())
+ {
+ /* Reference the process */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_WRITE,
+ PsProcessType,
+ KeGetPreviousMode(),
+ (PVOID*)&Process,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference the process %p\n", ProcessHandle);
+ return Status;
+ }
+
+ /* Attach to the process */
+ KeStackAttachProcess(Process, &ApcState);
+ }
+
+ /* FIXME: don't flush everything if a range is requested */
#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 (;;);
+ DbgBreakPoint();
#elif defined(_M_ARM)
- __asm__ __volatile__("mov r1, #0; mcr p15, 0, r1, c7, c5, 0");
+ _MoveToCoprocessor(0, CP15_ICIALLU);
#else
#error Unknown architecture
#endif
+
+ /* Check if we attached */
+ if (ProcessHandle != NtCurrentProcess())
+ {
+ /* Detach from the process */
+ KeUnstackDetachProcess(&ApcState);
+ }
+
return STATUS_SUCCESS;
}