-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/sysinfo.c
* PURPOSE: System information functions
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
- * Aleksey Bragin (aleksey@studiocerebral.com)
+ * Aleksey Bragin (aleksey@reactos.org)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
-#include <internal/debug.h>
-
-extern PEPROCESS PsIdleProcess;
-extern ULONG NtGlobalFlag; /* FIXME: it should go in a ddk/?.h */
-ULONGLONG STDCALL KeQueryInterruptTime(VOID);
+#include <debug.h>
VOID MmPrintMemoryStatistic(VOID);
* @implemented
*/
VOID
-STDCALL
-ExGetCurrentProcessorCpuUsage (
- PULONG CpuUsage
- )
+NTAPI
+ExGetCurrentProcessorCpuUsage(PULONG CpuUsage)
{
PKPRCB Prcb;
ULONG TotalTime;
* @implemented
*/
VOID
-STDCALL
-ExGetCurrentProcessorCounts (
- PULONG ThreadKernelTime,
- PULONG TotalCpuTime,
- PULONG ProcessorNumber
- )
+NTAPI
+ExGetCurrentProcessorCounts(PULONG ThreadKernelTime,
+ PULONG TotalCpuTime,
+ PULONG ProcessorNumber)
{
PKPRCB Prcb;
* @implemented
*/
BOOLEAN
-STDCALL
+NTAPI
ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
{
/* Quick check to see if it exists at all */
* @implemented
*/
BOOLEAN
-STDCALL
+NTAPI
ExVerifySuite(SUITE_TYPE SuiteType)
{
if (SuiteType == Personal) return TRUE;
return FALSE;
}
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName,
OUT PWSTR ValueBuffer,
IN ULONG ValueBufferLength,
if(PreviousMode != KernelMode)
{
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForRead(VariableName,
sizeof(UNICODE_STRING),
ProbeForWriteUlong(ReturnLength);
}
}
- _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+ _SEH2_EXCEPT(ExSystemExceptionFilter())
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
if(!NT_SUCCESS(Status))
{
* Convert the result to UNICODE, protect with SEH in case the value buffer
* isn't NULL-terminated!
*/
- _SEH_TRY
+ _SEH2_TRY
{
RtlInitAnsiString(&AValue, Value);
Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
}
- _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+ _SEH2_EXCEPT(ExSystemExceptionFilter())
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
if(NT_SUCCESS(Status))
{
/*
* Copy the result back to the caller.
*/
- _SEH_TRY
+ _SEH2_TRY
{
RtlCopyMemory(ValueBuffer, WValue.Buffer, WValue.Length);
ValueBuffer[WValue.Length / sizeof(WCHAR)] = L'\0';
Status = STATUS_SUCCESS;
}
- _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+ _SEH2_EXCEPT(ExSystemExceptionFilter())
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
}
/*
}
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtSetSystemEnvironmentValue (IN PUNICODE_STRING VariableName,
IN PUNICODE_STRING Value)
{
{
return (STATUS_INFO_LENGTH_MISMATCH);
}
+ RtlZeroMemory(Sbi, Size);
Sbi->Reserved = 0;
Sbi->TimerResolution = KeMaximumIncrement;
Sbi->PageSize = PAGE_SIZE;
return (STATUS_INFO_LENGTH_MISMATCH);
}
Prcb = KeGetCurrentPrcb();
- Spi->ProcessorArchitecture = 0; /* Intel Processor */
- Spi->ProcessorLevel = Prcb->CpuType;
- Spi->ProcessorRevision = Prcb->CpuStep;
+ Spi->ProcessorArchitecture = KeProcessorArchitecture;
+ Spi->ProcessorLevel = KeProcessorLevel;
+ Spi->ProcessorRevision = KeProcessorRevision;
Spi->Reserved = 0;
- Spi->ProcessorFeatureBits = Prcb->FeatureBits;
+ Spi->ProcessorFeatureBits = KeFeatureBits;
DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture,
Spi->ProcessorLevel, Spi->ProcessorRevision);
/* Class 2 - Performance Information */
QSI_DEF(SystemPerformanceInformation)
{
+ ULONG IdleUser, IdleKernel;
PSYSTEM_PERFORMANCE_INFORMATION Spi
= (PSYSTEM_PERFORMANCE_INFORMATION) Buffer;
TheIdleProcess = PsIdleProcess;
- Spi->IdleProcessTime.QuadPart = TheIdleProcess->Pcb.KernelTime * 100000LL;
-
+ IdleKernel = KeQueryRuntimeProcess(&TheIdleProcess->Pcb, &IdleUser);
+ Spi->IdleProcessTime.QuadPart = UInt32x32To64(IdleKernel, KeMaximumIncrement);
Spi->IoReadTransferCount = IoReadTransferCount;
Spi->IoWriteTransferCount = IoWriteTransferCount;
Spi->IoOtherTransferCount = IoOtherTransferCount;
Spi->AvailablePages = MmStats.NrFreePages;
/*
- Add up all the used "Commitied" memory + pagefile.
+ Add up all the used "Committed" memory + pagefile.
Not sure this is right. 8^\
*/
Spi->CommittedPages = MiMemoryConsumers[MC_PPOOL].PagesUsed +
{
ULONG ovlSize = 0, nThreads;
PEPROCESS pr = NULL, syspr;
- unsigned char *pCur;
+ PUCHAR pCur;
+ ULONG TotalUser, TotalKernel;
NTSTATUS Status = STATUS_SUCCESS;
- _SEH_TRY
+ _SEH2_TRY
{
/* scan the process list */
if (Size < sizeof(SYSTEM_PROCESS_INFORMATION))
{
- _SEH_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
+ _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
}
+ RtlZeroMemory(Spi, Size);
- syspr = PsGetNextProcess(NULL);
+ syspr = PsIdleProcess;
pr = syspr;
pCur = (unsigned char *)Spi;
*ReqSize = ovlSize;
ObDereferenceObject(pr);
- _SEH_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
+ _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
}
// fill system information
SpiCur->NextEntryOffset = curSize+inLen; // relative offset to the beginnnig of the next structure
SpiCur->NumberOfThreads = nThreads;
SpiCur->CreateTime = pr->CreateTime;
- SpiCur->UserTime.QuadPart = pr->Pcb.UserTime * 100000LL;
- SpiCur->KernelTime.QuadPart = pr->Pcb.KernelTime * 100000LL;
SpiCur->ImageName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
SpiCur->ImageName.MaximumLength = (USHORT)inLen;
SpiCur->ImageName.Buffer = (void*)(pCur+curSize);
current = CONTAINING_RECORD(current_entry, ETHREAD,
ThreadListEntry);
- ThreadInfo->KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
- ThreadInfo->UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
-// SpiCur->TH[i].CreateTime = current->CreateTime;
+ ThreadInfo->KernelTime.QuadPart = UInt32x32To64(current->Tcb.KernelTime, KeMaximumIncrement);
+ ThreadInfo->UserTime.QuadPart = UInt32x32To64(current->Tcb.UserTime, KeMaximumIncrement);
+ ThreadInfo->CreateTime.QuadPart = current->CreateTime.QuadPart;
ThreadInfo->WaitTime = current->Tcb.WaitTime;
ThreadInfo->StartAddress = (PVOID) current->StartAddress;
ThreadInfo->ClientId = current->Cid;
ThreadInfo->ContextSwitches = current->Tcb.ContextSwitches;
ThreadInfo->ThreadState = current->Tcb.State;
ThreadInfo->WaitReason = current->Tcb.WaitReason;
+
ThreadInfo++;
current_entry = current_entry->Flink;
}
+ /* Query total user/kernel times of a process */
+ TotalKernel = KeQueryRuntimeProcess(&pr->Pcb, &TotalUser);
+ SpiCur->UserTime.QuadPart = UInt32x32To64(TotalUser, KeMaximumIncrement);
+ SpiCur->KernelTime.QuadPart = UInt32x32To64(TotalKernel, KeMaximumIncrement);
+
+ /* Handle idle process entry */
+ if (pr == PsIdleProcess) pr = NULL;
+
pr = PsGetNextProcess(pr);
nThreads = 0;
if ((pr == syspr) || (pr == NULL))
ObDereferenceObject(pr);
Status = STATUS_SUCCESS;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
if(pr != NULL)
ObDereferenceObject(pr);
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END
+ _SEH2_END
*ReqSize = ovlSize;
return Status;
/* Class 8 - Processor Performance Information */
QSI_DEF(SystemProcessorPerformanceInformation)
{
- PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
- = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
+ PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
+ = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
- LONG i;
- LARGE_INTEGER CurrentTime;
- PKPRCB Prcb;
+ LONG i;
+ ULONG TotalTime;
+ LARGE_INTEGER CurrentTime;
+ PKPRCB Prcb;
- *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
- /*
- * Check user buffer's size
- */
- if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))
- {
- return (STATUS_INFO_LENGTH_MISMATCH);
- }
+ *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
- CurrentTime.QuadPart = KeQueryInterruptTime();
- Prcb = ((PKPCR)KPCR_BASE)->Prcb;
- for (i = 0; i < KeNumberProcessors; i++)
- {
- Spi->IdleTime.QuadPart = (Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime) * 100000LL; // IdleTime
- Spi->KernelTime.QuadPart = Prcb->KernelTime * 100000LL; // KernelTime
- Spi->UserTime.QuadPart = Prcb->UserTime * 100000LL;
- Spi->DpcTime.QuadPart = Prcb->DpcTime * 100000LL;
- Spi->InterruptTime.QuadPart = Prcb->InterruptTime * 100000LL;
- Spi->InterruptCount = Prcb->InterruptCount; // Interrupt Count
- Spi++;
- Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
- }
+ /* Check user buffer's size */
+ if (Size < *ReqSize)
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
- return (STATUS_SUCCESS);
+ CurrentTime.QuadPart = KeQueryInterruptTime();
+ Prcb = KeGetPcr()->Prcb;
+ for (i = 0; i < KeNumberProcessors; i++)
+ {
+ /* Calculate total user and kernel times */
+ TotalTime = Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime;
+ Spi->IdleTime.QuadPart = UInt32x32To64(TotalTime, KeMaximumIncrement);
+ Spi->KernelTime.QuadPart = UInt32x32To64(Prcb->KernelTime, KeMaximumIncrement);
+ Spi->UserTime.QuadPart = UInt32x32To64(Prcb->UserTime, KeMaximumIncrement);
+ Spi->DpcTime.QuadPart = UInt32x32To64(Prcb->DpcTime, KeMaximumIncrement);
+ Spi->InterruptTime.QuadPart = UInt32x32To64(Prcb->InterruptTime, KeMaximumIncrement);
+ Spi->InterruptCount = Prcb->InterruptCount;
+ Spi++;
+ Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
+ }
+
+ return STATUS_SUCCESS;
}
/* Class 9 - Flags Information */
for (Count = 0; HandleCount > 0 ; HandleCount--)
{
- Shi->Handles[i].UniqueProcessId = (USHORT)(ULONG)pr->UniqueProcessId;
+ Shi->Handles[i].UniqueProcessId = (USHORT)(ULONG_PTR)pr->UniqueProcessId;
Count++;
i++;
}
QSI_DEF(SystemInterruptInformation)
{
PKPRCB Prcb;
+ PKPCR Pcr;
LONG i;
ULONG ti;
PSYSTEM_INTERRUPT_INFORMATION sii = (PSYSTEM_INTERRUPT_INFORMATION)Buffer;
ti = KeQueryTimeIncrement();
- Prcb = ((PKPCR)KPCR_BASE)->Prcb;
for (i = 0; i < KeNumberProcessors; i++)
{
- //sii->ContextSwitches = Prcb->KeContextSwitches;
- sii->DpcCount = 0; /* FIXME */
- sii->DpcRate = 0; /* FIXME */
+ Prcb = KiProcessorBlock[i];
+#ifdef _M_AMD64
+ Pcr = CONTAINING_RECORD(Prcb, KPCR, CurrentPrcb);
+#else
+ Pcr = CONTAINING_RECORD(Prcb, KPCR, Prcb);
+#endif
+#ifdef _M_ARM // This code should probably be done differently
+ sii->ContextSwitches = Pcr->ContextSwitches;
+#else
+ sii->ContextSwitches = ((PKIPCR)Pcr)->ContextSwitches;
+#endif
+ sii->DpcCount = Prcb->DpcData[0].DpcCount;
+ sii->DpcRate = Prcb->DpcRequestRate;
sii->TimeIncrement = ti;
- sii->DpcBypassCount = 0; /* FIXME */
- sii->ApcBypassCount = 0; /* FIXME */
+ sii->DpcBypassCount = 0;
+ sii->ApcBypassCount = 0;
sii++;
- Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
}
return STATUS_SUCCESS;
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
UNICODE_STRING ImageName;
PVOID ImageBase;
+ PLDR_DATA_TABLE_ENTRY ModuleObject;
ULONG_PTR EntryPoint;
NTSTATUS Status;
ULONG DirSize;
NULL,
NULL,
0,
- NULL,
+ (PVOID)&ModuleObject,
&ImageBase);
if (!NT_SUCCESS(Status)) return Status;
/* Class 27 - Unload Image */
SSI_DEF(SystemUnloadGdiDriverInformation)
-{
+{
PLDR_DATA_TABLE_ENTRY LdrEntry;
PLIST_ENTRY NextEntry;
PVOID BaseAddr = *((PVOID*)Buffer);
-
- if(Size != sizeof(PVOID))
+
+ if(Size != sizeof(PVOID))
return STATUS_INFO_LENGTH_MISMATCH;
-
- if(KeGetPreviousMode() != KernelMode)
+
+ if(KeGetPreviousMode() != KernelMode)
return STATUS_PRIVILEGE_NOT_HELD;
-
- // Scan the module list
+
+ // Scan the module list
NextEntry = PsLoadedModuleList.Flink;
while(NextEntry != &PsLoadedModuleList)
{
LdrEntry = CONTAINING_RECORD(NextEntry,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
-
+
if (LdrEntry->DllBase == BaseAddr)
{
// Found it.
DPRINT1("Image 0x%x not found.\n", BaseAddr);
return STATUS_DLL_NOT_FOUND;
}
-
+
}
/* Class 28 - Time Adjustment Information */
SI_QX(SystemSessionProcessesInformation)
};
+C_ASSERT(SystemBasicInformation == 0);
+#define MIN_SYSTEM_INFO_CLASS (SystemBasicInformation)
+#define MAX_SYSTEM_INFO_CLASS (sizeof(CallQS) / sizeof(CallQS[0]))
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG Length,
NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED;
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
- _SEH_TRY
+
+ _SEH2_TRY
{
if (PreviousMode != KernelMode)
{
/* SystemKernelDebuggerInformation needs only BOOLEAN alignment */
- ProbeForWrite(SystemInformation, Length, 1);
+ ProbeForWrite(SystemInformation, Length, 1);
if (UnsafeResultLength != NULL)
ProbeForWriteUlong(UnsafeResultLength);
}
- /* Clear user buffer. */
- RtlZeroMemory(SystemInformation, Length);
-
/*
* Check the request is valid.
*/
- if (SystemInformationClass >= MaxSystemInfoClass)
+ if (SystemInformationClass >= MAX_SYSTEM_INFO_CLASS)
{
- _SEH_YIELD(return STATUS_INVALID_INFO_CLASS);
+ _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS);
}
if (NULL != CallQS [SystemInformationClass].Query)
{
if (PreviousMode != KernelMode)
{
- _SEH_TRY
- {
*UnsafeResultLength = ResultLength;
- }
- _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
- {
- FStatus = _SEH_GetExceptionCode();
- }
- _SEH_END;
}
else
{
}
}
}
- _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+ _SEH2_EXCEPT(ExSystemExceptionFilter())
{
- FStatus = _SEH_GetExceptionCode();
+ FStatus = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
return (FStatus);
}
NTSTATUS
-STDCALL
+NTAPI
NtSetSystemInformation (
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN PVOID SystemInformation,
/*
* Check the request is valid.
*/
- if ( (SystemInformationClass >= SystemBasicInformation)
- && (SystemInformationClass < MaxSystemInfoClass)
+ if ( (SystemInformationClass >= MIN_SYSTEM_INFO_CLASS)
+ && (SystemInformationClass < MAX_SYSTEM_INFO_CLASS)
)
{
if (NULL != CallQS [SystemInformationClass].Set)
NTSTATUS
-STDCALL
+NTAPI
NtFlushInstructionCache (
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
#if defined(_M_IX86)
__wbinvd();
#elif defined(_M_PPC)
-#error Needs to be implemented for PPC architecture!
+ __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");
+#elif defined(_M_AMD64)
+ DPRINT1("NtFlushInstructionCache() is not implemented\n");
+ for (;;);
#else
#error Unknown architecture
#endif
return KeGetCurrentProcessorNumber();
}
-/* EOF */
+/* EOF */
\ No newline at end of file