-/* $Id: sysinfo.c,v 1.50 2004/10/08 20:02:30 gvg Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/sysinfo.c
* PURPOSE: System information functions
- * PROGRAMMER: David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
- * Created 22/05/98
- * 20/03/2003: implemented querying SystemProcessInformation,
- * no more copying to-from the caller (Aleksey
- * Bragin <aleksey@studiocerebral.com>)
+ *
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
+ * Aleksey Bragin (aleksey@studiocerebral.com)
*/
/* INCLUDES *****************************************************************/
#define NDEBUG
#include <internal/debug.h>
+extern PEPROCESS PsIdleProcess;
extern ULONG NtGlobalFlag; /* FIXME: it should go in a ddk/?.h */
ULONGLONG STDCALL KeQueryInterruptTime(VOID);
VOID MmPrintMemoryStatistic(VOID);
-extern ULONG Ke386CpuidFlags;
-extern ULONG Ke386Cpuid;
-
/* FUNCTIONS *****************************************************************/
/*
}
/*
- * @unimplemented
+ * @implemented
*/
VOID
STDCALL
-ExGetCurrentProcessorCounts (
- PVOID IdleThreadTime,
- PVOID SystemTime,
- PVOID Number
+ExGetCurrentProcessorCpuUsage (
+ PULONG CpuUsage
)
{
- UNIMPLEMENTED;
+ PKPRCB Prcb;
+ ULONG TotalTime;
+ ULONGLONG ScaledIdle;
+
+ Prcb = KeGetCurrentPrcb();
+
+ ScaledIdle = Prcb->IdleThread->KernelTime * 100;
+ TotalTime = Prcb->KernelTime + Prcb->UserTime;
+ if (TotalTime != 0)
+ *CpuUsage = 100 - (ScaledIdle / TotalTime);
+ else
+ *CpuUsage = 0;
}
+
/*
- * @unimplemented
+ * @implemented
*/
VOID
STDCALL
-ExGetCurrentProcessorCpuUsage (
- PVOID RetVal
+ExGetCurrentProcessorCounts (
+ PULONG ThreadKernelTime,
+ PULONG TotalCpuTime,
+ PULONG ProcessorNumber
)
{
- UNIMPLEMENTED;
+ PKPRCB Prcb;
+
+ Prcb = KeGetCurrentPrcb();
+
+ *ThreadKernelTime = Prcb->KernelTime + Prcb->UserTime;
+ *TotalCpuTime = Prcb->CurrentThread->KernelTime;
+ *ProcessorNumber = KeGetCurrentKPCR()->ProcessorNumber;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
+{
+ /* Quick check to see if it exists at all */
+ if (ProcessorFeature >= PROCESSOR_FEATURE_MAX) return(FALSE);
+
+ /* Return our support for it */
+ return(SharedUserData->ProcessorFeatures[ProcessorFeature]);
}
NTSTATUS STDCALL
-NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
- OUT PVOID UnsafeValue,
- IN ULONG Length,
- IN OUT PULONG UnsafeReturnLength)
+NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName,
+ OUT PWCHAR ValueBuffer,
+ IN ULONG ValueBufferLength,
+ IN OUT PULONG ReturnLength OPTIONAL)
{
- NTSTATUS Status;
ANSI_STRING AName;
UNICODE_STRING WName;
BOOLEAN Result;
PCH Value;
ANSI_STRING AValue;
UNICODE_STRING WValue;
- ULONG ReturnLength;
-
- /*
- * Copy the name to kernel space if necessary and convert it to ANSI.
- */
- if (ExGetPreviousMode() != KernelMode)
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ PAGED_CODE();
+
+ PreviousMode = ExGetPreviousMode();
+
+ if(PreviousMode != KernelMode)
+ {
+ _SEH_TRY
{
- Status = RtlCaptureUnicodeString(&WName, UnsafeName);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
+ ProbeForRead(VariableName,
+ sizeof(UNICODE_STRING),
+ sizeof(ULONG));
+ ProbeForWrite(ValueBuffer,
+ ValueBufferLength,
+ sizeof(WCHAR));
+ if(ReturnLength != NULL)
+ {
+ ProbeForWrite(ReturnLength,
+ sizeof(ULONG),
+ sizeof(ULONG));
+ }
}
- else
+ _SEH_HANDLE
{
- Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
}
+ }
/*
- * Create a temporary buffer for the value
+ * Copy the name to kernel space if necessary and convert it to ANSI.
*/
- Value = ExAllocatePool(NonPagedPool, Length);
- if (Value == NULL)
+ Status = RtlCaptureUnicodeString(&WName,
+ PreviousMode,
+ NonPagedPool,
+ FALSE,
+ VariableName);
+ if(NT_SUCCESS(Status))
+ {
+ /*
+ * according to ntinternals the SeSystemEnvironmentName privilege is required!
+ */
+ if(!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege,
+ PreviousMode))
{
- RtlFreeAnsiString(&AName);
- if (ExGetPreviousMode() != KernelMode)
- {
- RtlFreeUnicodeString(&WName);
- }
- return(STATUS_NO_MEMORY);
+ RtlReleaseCapturedUnicodeString(&WName,
+ PreviousMode,
+ FALSE);
+ DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
+ return STATUS_PRIVILEGE_NOT_HELD;
}
-
+
+ /*
+ * convert the value name to ansi
+ */
+ Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE);
+ RtlReleaseCapturedUnicodeString(&WName,
+ PreviousMode,
+ FALSE);
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
/*
- * Get the environment variable
+ * Create a temporary buffer for the value
*/
- Result = HalGetEnvironmentVariable(AName.Buffer, Value, Length);
- if (!Result)
+ Value = ExAllocatePool(NonPagedPool, ValueBufferLength);
+ if (Value == NULL)
{
RtlFreeAnsiString(&AName);
- if (ExGetPreviousMode() != KernelMode)
- {
- RtlFreeUnicodeString(&WName);
- }
- ExFreePool(Value);
- return(STATUS_UNSUCCESSFUL);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
-
- /*
- * Convert the result to UNICODE.
- */
- RtlInitAnsiString(&AValue, Value);
- Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
- if (!NT_SUCCESS(Status))
+
+ /*
+ * Get the environment variable
+ */
+ Result = HalGetEnvironmentVariable(AName.Buffer, Value, ValueBufferLength);
+ if(!Result)
{
RtlFreeAnsiString(&AName);
- if (ExGetPreviousMode() != KernelMode)
- {
- RtlFreeUnicodeString(&WName);
- }
ExFreePool(Value);
- return(Status);
+ return STATUS_UNSUCCESSFUL;
}
- ReturnLength = WValue.Length;
-
- /*
- * Copy the result back to the caller.
- */
- if (ExGetPreviousMode() != KernelMode)
+
+ /*
+ * Convert the result to UNICODE, protect with SEH in case the value buffer
+ * isn't NULL-terminated!
+ */
+ _SEH_TRY
{
- Status = MmCopyToCaller(UnsafeValue, WValue.Buffer, ReturnLength);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeAnsiString(&AName);
- if (ExGetPreviousMode() != KernelMode)
- {
- RtlFreeUnicodeString(&WName);
- }
- ExFreePool(Value);
- RtlFreeUnicodeString(&WValue);
- return(Status);
- }
-
- Status = MmCopyToCaller(UnsafeReturnLength, &ReturnLength,
- sizeof(ULONG));
- if (!NT_SUCCESS(Status))
- {
- RtlFreeAnsiString(&AName);
- if (ExGetPreviousMode() != KernelMode)
- {
- RtlFreeUnicodeString(&WName);
- }
- ExFreePool(Value);
- RtlFreeUnicodeString(&WValue);
- return(Status);
- }
+ RtlInitAnsiString(&AValue, Value);
+ Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
}
- else
+ _SEH_HANDLE
{
- memcpy(UnsafeValue, WValue.Buffer, ReturnLength);
- memcpy(UnsafeReturnLength, &ReturnLength, sizeof(ULONG));
+ Status = _SEH_GetExceptionCode();
}
+ _SEH_END;
- /*
- * Free temporary buffers.
- */
- RtlFreeAnsiString(&AName);
- if (ExGetPreviousMode() != KernelMode)
+ if(NT_SUCCESS(Status))
{
- RtlFreeUnicodeString(&WName);
+ /*
+ * Copy the result back to the caller.
+ */
+ _SEH_TRY
+ {
+ RtlCopyMemory(ValueBuffer, WValue.Buffer, WValue.Length);
+ ValueBuffer[WValue.Length / sizeof(WCHAR)] = L'\0';
+ if(ReturnLength != NULL)
+ {
+ *ReturnLength = WValue.Length + sizeof(WCHAR);
+ }
+
+ Status = STATUS_SUCCESS;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
}
- ExFreePool(Value);
- RtlFreeUnicodeString(&WValue);
+
+ /*
+ * Cleanup allocated resources.
+ */
+ RtlFreeAnsiString(&AName);
+ ExFreePool(Value);
+ }
- return(STATUS_SUCCESS);
+ return Status;
}
NTSTATUS STDCALL
-NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
- IN PUNICODE_STRING UnsafeValue)
+NtSetSystemEnvironmentValue (IN PUNICODE_STRING VariableName,
+ IN PUNICODE_STRING Value)
{
- UNICODE_STRING WName;
- ANSI_STRING AName;
- UNICODE_STRING WValue;
- ANSI_STRING AValue;
- BOOLEAN Result;
+ UNICODE_STRING CapturedName, CapturedValue;
+ ANSI_STRING AName, AValue;
+ KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
+
+ PAGED_CODE();
+ PreviousMode = ExGetPreviousMode();
+
/*
- * Check for required privilege.
- */
- /* FIXME: Not implemented. */
-
- /*
- * Copy the name to kernel space if necessary and convert it to ANSI.
- */
- if (ExGetPreviousMode() != KernelMode)
- {
- Status = RtlCaptureUnicodeString(&WName, UnsafeName);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- }
- else
- {
- Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
- }
-
- /*
- * Copy the value to kernel space and convert to ANSI.
- */
- if (ExGetPreviousMode() != KernelMode)
- {
- Status = RtlCaptureUnicodeString(&WValue, UnsafeValue);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeUnicodeString(&WName);
- RtlFreeAnsiString(&AName);
- return(Status);
- }
- Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeUnicodeString(&WName);
- RtlFreeAnsiString(&AName);
- RtlFreeUnicodeString(&WValue);
- return(Status);
- }
- }
- else
- {
- Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeAnsiString(&AName);
- return(Status);
- }
- }
-
- /*
- * Set the environment variable
- */
- Result = HalSetEnvironmentVariable(AName.Buffer, AValue.Buffer);
-
- /*
- * Free everything and return status.
+ * Copy the strings to kernel space if necessary
*/
- RtlFreeAnsiString(&AName);
- RtlFreeAnsiString(&AValue);
- if (ExGetPreviousMode() != KernelMode)
+ Status = RtlCaptureUnicodeString(&CapturedName,
+ PreviousMode,
+ NonPagedPool,
+ FALSE,
+ VariableName);
+ if(NT_SUCCESS(Status))
+ {
+ Status = RtlCaptureUnicodeString(&CapturedValue,
+ PreviousMode,
+ NonPagedPool,
+ FALSE,
+ Value);
+ if(NT_SUCCESS(Status))
{
- RtlFreeUnicodeString(&WName);
- RtlFreeUnicodeString(&WValue);
+ /*
+ * according to ntinternals the SeSystemEnvironmentName privilege is required!
+ */
+ if(SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege,
+ PreviousMode))
+ {
+ /*
+ * convert the strings to ANSI
+ */
+ Status = RtlUnicodeStringToAnsiString(&AName,
+ &CapturedName,
+ TRUE);
+ if(NT_SUCCESS(Status))
+ {
+ Status = RtlUnicodeStringToAnsiString(&AValue,
+ &CapturedValue,
+ TRUE);
+ if(NT_SUCCESS(Status))
+ {
+ BOOLEAN Result = HalSetEnvironmentVariable(AName.Buffer,
+ AValue.Buffer);
+
+ Status = (Result ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
+ }
+ }
+ }
+ else
+ {
+ DPRINT1("NtSetSystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ }
+
+ RtlReleaseCapturedUnicodeString(&CapturedValue,
+ PreviousMode,
+ FALSE);
}
- if (!Result)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- return(STATUS_SUCCESS);
+ RtlReleaseCapturedUnicodeString(&CapturedName,
+ PreviousMode,
+ FALSE);
+ }
+
+ return Status;
}
return (STATUS_INFO_LENGTH_MISMATCH);
}
Sbi->Unknown = 0;
- Sbi->MaximumIncrement = 100000; /* FIXME */
- Sbi->PhysicalPageSize = PAGE_SIZE; /* FIXME: it should be PAGE_SIZE */
+ Sbi->MaximumIncrement = KeMaximumIncrement;
+ Sbi->PhysicalPageSize = PAGE_SIZE;
Sbi->NumberOfPhysicalPages = MmStats.NrTotalPages;
Sbi->LowestPhysicalPage = 0; /* FIXME */
Sbi->HighestPhysicalPage = MmStats.NrTotalPages; /* FIXME */
Sbi->AllocationGranularity = MM_VIRTMEM_GRANULARITY; /* hard coded on Intel? */
Sbi->LowestUserAddress = 0x10000; /* Top of 64k */
Sbi->HighestUserAddress = (ULONG_PTR)MmHighestUserAddress;
- Sbi->ActiveProcessors = 0x00000001; /* FIXME */
+ Sbi->ActiveProcessors = KeActiveProcessors;
Sbi->NumberProcessors = KeNumberProcessors;
return (STATUS_SUCCESS);
}
{
PSYSTEM_PROCESSOR_INFORMATION Spi
= (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
-
+ PKPRCB Prcb;
*ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION);
/*
* Check user buffer's size
if (Size < sizeof (SYSTEM_PROCESSOR_INFORMATION))
{
return (STATUS_INFO_LENGTH_MISMATCH);
- }
+ }
+ Prcb = KeGetCurrentPrcb();
Spi->ProcessorArchitecture = 0; /* Intel Processor */
- Spi->ProcessorLevel = ((Ke386Cpuid >> 8) & 0xf);
- Spi->ProcessorRevision = (Ke386Cpuid & 0xf) | ((Ke386Cpuid << 4) & 0xf00);
+ Spi->ProcessorLevel = Prcb->CpuType;
+ Spi->ProcessorRevision = Prcb->CpuStep;
Spi->Unknown = 0;
- Spi->FeatureBits = Ke386CpuidFlags;
+ Spi->FeatureBits = Prcb->FeatureBits;
DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture,
Spi->ProcessorLevel, Spi->ProcessorRevision);
return (STATUS_INFO_LENGTH_MISMATCH);
}
- PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
+ TheIdleProcess = PsIdleProcess;
Spi->IdleTime.QuadPart = TheIdleProcess->Pcb.KernelTime * 100000LL;
Spi->SecondLevelTbFills = 0; /* FIXME */
Spi->SystemCalls = 0; /* FIXME */
- ObDereferenceObject(TheIdleProcess);
-
return (STATUS_SUCCESS);
}
/* Class 3 - Time Of Day Information */
QSI_DEF(SystemTimeOfDayInformation)
{
- LARGE_INTEGER CurrentTime;
+ PSYSTEM_TIMEOFDAY_INFORMATION Sti;
+ LARGE_INTEGER CurrentTime;
- PSYSTEM_TIMEOFDAY_INFORMATION Sti
- = (PSYSTEM_TIMEOFDAY_INFORMATION) Buffer;
+ Sti = (PSYSTEM_TIMEOFDAY_INFORMATION)Buffer;
+ *ReqSize = sizeof (SYSTEM_TIMEOFDAY_INFORMATION);
- *ReqSize = sizeof (SYSTEM_TIMEOFDAY_INFORMATION);
- /*
- * Check user buffer's size
- */
- if (Size < sizeof (SYSTEM_TIMEOFDAY_INFORMATION))
- {
- return (STATUS_INFO_LENGTH_MISMATCH);
- }
+ /* Check user buffer's size */
+ if (Size < sizeof (SYSTEM_TIMEOFDAY_INFORMATION))
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
- KeQuerySystemTime(&CurrentTime);
+ KeQuerySystemTime(&CurrentTime);
- Sti->BootTime= SystemBootTime;
- Sti->CurrentTime = CurrentTime;
- Sti->TimeZoneBias.QuadPart = _SystemTimeZoneInfo.Bias;
- Sti->TimeZoneId = 0; /* FIXME */
- Sti->Reserved = 0; /* FIXME */
+ Sti->BootTime= SystemBootTime;
+ Sti->CurrentTime = CurrentTime;
+ Sti->TimeZoneBias.QuadPart = ExpTimeZoneBias.QuadPart;
+ Sti->TimeZoneId = ExpTimeZoneId;
+ Sti->Reserved = 0;
- return (STATUS_SUCCESS);
+ return STATUS_SUCCESS;
}
/* Class 4 - Path Information */
/* scan the process list */
- PSYSTEM_PROCESSES Spi
- = (PSYSTEM_PROCESSES) Buffer;
+ PSYSTEM_PROCESS_INFORMATION Spi
+ = (PSYSTEM_PROCESS_INFORMATION) Buffer;
- *ReqSize = sizeof(SYSTEM_PROCESSES);
+ *ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION);
- if (Size < sizeof(SYSTEM_PROCESSES))
+ if (Size < sizeof(SYSTEM_PROCESS_INFORMATION))
{
return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
}
do
{
- PSYSTEM_PROCESSES SpiCur;
+ PSYSTEM_PROCESS_INFORMATION SpiCur;
int curSize, i = 0;
ANSI_STRING imgName;
int inLen=32; // image name len in bytes
PLIST_ENTRY current_entry;
PETHREAD current;
- SpiCur = (PSYSTEM_PROCESSES)pCur;
+ SpiCur = (PSYSTEM_PROCESS_INFORMATION)pCur;
+
+ nThreads = 0;
+ current_entry = pr->ThreadListHead.Flink;
+ while (current_entry != &pr->ThreadListHead)
+ {
+ nThreads++;
+ current_entry = current_entry->Flink;
+ }
- nThreads = PsEnumThreadsByProcess(pr);
-
// size of the structure for every process
- curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*nThreads;
+ curSize = sizeof(SYSTEM_PROCESS_INFORMATION)-sizeof(SYSTEM_THREAD_INFORMATION)+sizeof(SYSTEM_THREAD_INFORMATION)*nThreads;
ovlSize += curSize+inLen;
if (ovlSize > Size)
}
// fill system information
- SpiCur->NextEntryDelta = curSize+inLen; // relative offset to the beginnnig of the next structure
- SpiCur->ThreadCount = nThreads;
+ 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->ProcessName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
- SpiCur->ProcessName.MaximumLength = inLen;
- SpiCur->ProcessName.Buffer = (void*)(pCur+curSize);
+ SpiCur->ImageName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
+ SpiCur->ImageName.MaximumLength = inLen;
+ SpiCur->ImageName.Buffer = (void*)(pCur+curSize);
// copy name to the end of the struct
- RtlInitAnsiString(&imgName, pr->ImageFileName);
- RtlAnsiStringToUnicodeString(&SpiCur->ProcessName, &imgName, FALSE);
+ if(pr != PsIdleProcess)
+ {
+ RtlInitAnsiString(&imgName, pr->ImageFileName);
+ RtlAnsiStringToUnicodeString(&SpiCur->ImageName, &imgName, FALSE);
+ }
+ else
+ {
+ RtlInitUnicodeString(&SpiCur->ImageName, NULL);
+ }
SpiCur->BasePriority = pr->Pcb.BasePriority;
- SpiCur->ProcessId = pr->UniqueProcessId;
- SpiCur->InheritedFromProcessId = (DWORD)(pr->InheritedFromUniqueProcessId);
- SpiCur->HandleCount = ObpGetHandleCountByHandleTable(&pr->HandleTable);
- SpiCur->VmCounters.PeakVirtualSize = pr->PeakVirtualSize;
- SpiCur->VmCounters.VirtualSize = pr->VirtualSize.QuadPart;
- SpiCur->VmCounters.PageFaultCount = pr->LastFaultCount;
- SpiCur->VmCounters.PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ?
- SpiCur->VmCounters.WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ?
- SpiCur->VmCounters.QuotaPeakPagedPoolUsage =
+ SpiCur->UniqueProcessId = pr->UniqueProcessId;
+ SpiCur->InheritedFromUniqueProcessId = pr->InheritedFromUniqueProcessId;
+ SpiCur->HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
+ SpiCur->PeakVirtualSize = pr->PeakVirtualSize;
+ SpiCur->VirtualSize = pr->VirtualSize.QuadPart;
+ SpiCur->PageFaultCount = pr->LastFaultCount;
+ SpiCur->PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ?
+ SpiCur->WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ?
+ SpiCur->QuotaPeakPagedPoolUsage =
pr->QuotaPeakPoolUsage[0];
- SpiCur->VmCounters.QuotaPagedPoolUsage =
+ SpiCur->QuotaPagedPoolUsage =
pr->QuotaPoolUsage[0];
- SpiCur->VmCounters.QuotaPeakNonPagedPoolUsage =
+ SpiCur->QuotaPeakNonPagedPoolUsage =
pr->QuotaPeakPoolUsage[1];
- SpiCur->VmCounters.QuotaNonPagedPoolUsage =
+ SpiCur->QuotaNonPagedPoolUsage =
pr->QuotaPoolUsage[1];
- SpiCur->VmCounters.PagefileUsage = pr->PagefileUsage; // FIXME
- SpiCur->VmCounters.PeakPagefileUsage = pr->PeakPagefileUsage;
+ SpiCur->PagefileUsage = pr->PagefileUsage; // FIXME
+ SpiCur->PeakPagefileUsage = pr->PeakPagefileUsage;
// KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
// doesn't seem to contain any equivalent field
//SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
current = CONTAINING_RECORD(current_entry, ETHREAD,
ThreadListEntry);
- SpiCur->Threads[i].KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
- SpiCur->Threads[i].UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
-// SpiCur->Threads[i].CreateTime = current->CreateTime;
- SpiCur->Threads[i].WaitTime = current->Tcb.WaitTime;
- SpiCur->Threads[i].StartAddress = (PVOID) current->StartAddress;
- SpiCur->Threads[i].ClientId = current->Cid;
- SpiCur->Threads[i].Priority = current->Tcb.Priority;
- SpiCur->Threads[i].BasePriority = current->Tcb.BasePriority;
- SpiCur->Threads[i].ContextSwitchCount = current->Tcb.ContextSwitches;
- SpiCur->Threads[i].State = current->Tcb.State;
- SpiCur->Threads[i].WaitReason = current->Tcb.WaitReason;
+ SpiCur->TH[i].KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
+ SpiCur->TH[i].UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
+// SpiCur->TH[i].CreateTime = current->CreateTime;
+ SpiCur->TH[i].WaitTime = current->Tcb.WaitTime;
+ SpiCur->TH[i].StartAddress = (PVOID) current->StartAddress;
+ SpiCur->TH[i].ClientId = current->Cid;
+ SpiCur->TH[i].Priority = current->Tcb.Priority;
+ SpiCur->TH[i].BasePriority = current->Tcb.BasePriority;
+ SpiCur->TH[i].ContextSwitches = current->Tcb.ContextSwitches;
+ SpiCur->TH[i].ThreadState = current->Tcb.State;
+ SpiCur->TH[i].WaitReason = current->Tcb.WaitReason;
i++;
current_entry = current_entry->Flink;
}
-
+
pr = PsGetNextProcess(pr);
-
+ nThreads = 0;
if ((pr == syspr) || (pr == NULL))
{
- SpiCur->NextEntryDelta = 0;
+ SpiCur->NextEntryOffset = 0;
break;
}
else
pCur = pCur + curSize + inLen;
} while ((pr != syspr) && (pr != NULL));
+
+ if(pr != NULL)
+ {
+ ObDereferenceObject(pr);
+ }
*ReqSize = ovlSize;
- if (pr != NULL)
- {
- ObDereferenceObject(pr);
- }
return (STATUS_SUCCESS);
}
/* Class 8 - Processor Performance Information */
QSI_DEF(SystemProcessorPerformanceInformation)
{
- PSYSTEM_PROCESSORTIME_INFO Spi
- = (PSYSTEM_PROCESSORTIME_INFO) Buffer;
+ PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
+ = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
- PEPROCESS TheIdleProcess;
- TIME CurrentTime;
+ ULONG i;
+ LARGE_INTEGER CurrentTime;
+ PKPRCB Prcb;
- *ReqSize = sizeof (SYSTEM_PROCESSORTIME_INFO);
+ *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
/*
- * Check user buffer's size
+ * Check user buffer's size
*/
- if (Size < sizeof (SYSTEM_PROCESSORTIME_INFO))
+ if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))
{
return (STATUS_INFO_LENGTH_MISMATCH);
}
- PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
-
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);
+ }
- Spi->TotalProcessorRunTime.QuadPart =
- TheIdleProcess->Pcb.KernelTime * 100000LL; // IdleTime
- Spi->TotalProcessorTime.QuadPart = KiKernelTime * 100000LL; // KernelTime
- Spi->TotalProcessorUserTime.QuadPart = KiUserTime * 100000LL;
- Spi->TotalDPCTime.QuadPart = KiDpcTime * 100000LL;
- Spi->TotalInterruptTime.QuadPart = KiInterruptTime * 100000LL;
- Spi->TotalInterrupts = KiInterruptCount; // Interrupt Count
-
- ObDereferenceObject(TheIdleProcess);
-
return (STATUS_SUCCESS);
}
return (STATUS_NOT_IMPLEMENTED);
}
+
+VOID
+ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
+ PEPROCESS Process,
+ int Count);
+
/* Class 16 - Handle Information */
QSI_DEF(SystemHandleInformation)
{
- /* FIXME */
- DPRINT1("NtQuerySystemInformation - SystemHandleInformation not implemented\n");
- return (STATUS_NOT_IMPLEMENTED);
+ PSYSTEM_HANDLE_INFORMATION Shi =
+ (PSYSTEM_HANDLE_INFORMATION) Buffer;
+
+ DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
+
+ if (Size < sizeof (SYSTEM_HANDLE_INFORMATION))
+ {
+ * ReqSize = sizeof (SYSTEM_HANDLE_INFORMATION);
+ return (STATUS_INFO_LENGTH_MISMATCH);
+ }
+
+ DPRINT("SystemHandleInformation 1\n");
+
+ PEPROCESS pr, syspr;
+ int curSize, i = 0;
+ ULONG hCount = 0;
+
+ /* First Calc Size from Count. */
+ syspr = PsGetNextProcess(NULL);
+ pr = syspr;
+
+ do
+ {
+ hCount = hCount + (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
+ pr = PsGetNextProcess(pr);
+
+ if ((pr == syspr) || (pr == NULL))
+ break;
+ } while ((pr != syspr) && (pr != NULL));
+
+ if(pr != NULL)
+ {
+ ObDereferenceObject(pr);
+ }
+
+ DPRINT("SystemHandleInformation 2\n");
+
+ curSize = sizeof(SYSTEM_HANDLE_INFORMATION)+
+ ( (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) -
+ (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) ));
+
+ Shi->NumberOfHandles = hCount;
+
+ if (curSize > Size)
+ {
+ *ReqSize = curSize;
+ return (STATUS_INFO_LENGTH_MISMATCH);
+ }
+
+ DPRINT("SystemHandleInformation 3\n");
+
+ /* Now get Handles from all processs. */
+ syspr = PsGetNextProcess(NULL);
+ pr = syspr;
+
+ do
+ {
+ int Count = 0, HandleCount;
+
+ HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
+
+ for (Count = 0; HandleCount > 0 ; HandleCount--)
+ {
+ ObpGetNextHandleByProcessCount( &Shi->Handles[i], pr, Count);
+ Count++;
+ i++;
+ }
+
+ pr = PsGetNextProcess(pr);
+
+ if ((pr == syspr) || (pr == NULL))
+ break;
+ } while ((pr != syspr) && (pr != NULL));
+
+ if(pr != NULL)
+ {
+ ObDereferenceObject(pr);
+ }
+
+ DPRINT("SystemHandleInformation 4\n");
+ return (STATUS_SUCCESS);
+
}
+/*
+SSI_DEF(SystemHandleInformation)
+{
+
+ return (STATUS_SUCCESS);
+}
+*/
/* Class 17 - Information */
QSI_DEF(SystemObjectInformation)
UNICODE_STRING FileName; /* FIXME */
/* FIXME */
- Spfi->RelativeOffset = 0;
+ Spfi->NextEntryOffset = 0;
- Spfi->CurrentSizePages = MiFreeSwapPages + MiUsedSwapPages;
- Spfi->TotalUsedPages = MiUsedSwapPages;
- Spfi->PeakUsedPages = MiUsedSwapPages; /* FIXME */
- Spfi->PagefileFileName = FileName;
+ Spfi->TotalSize = MiFreeSwapPages + MiUsedSwapPages;
+ Spfi->TotalInUse = MiUsedSwapPages;
+ Spfi->PeakUsage = MiUsedSwapPages; /* FIXME */
+ Spfi->PageFileName = FileName;
return (STATUS_SUCCESS);
}
return (STATUS_NOT_IMPLEMENTED);
}
-/* Class 23 - Interrupt Information */
+/* Class 23 - Interrupt Information for all processors */
QSI_DEF(SystemInterruptInformation)
{
- /* FIXME */
- DPRINT1("NtQuerySystemInformation - SystemInterruptInformation not implemented\n");
- return (STATUS_NOT_IMPLEMENTED);
+ PKPRCB Prcb;
+ UINT i;
+ ULONG ti;
+ PSYSTEM_INTERRUPT_INFORMATION sii = (PSYSTEM_INTERRUPT_INFORMATION)Buffer;
+
+ if(Size < KeNumberProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION))
+ {
+ return (STATUS_INFO_LENGTH_MISMATCH);
+ }
+
+ 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 */
+ sii->TimeIncrement = ti;
+ sii->DpcBypassCount = 0; /* FIXME */
+ sii->ApcBypassCount = 0; /* FIXME */
+ sii++;
+ Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
+ }
+
+ return STATUS_SUCCESS;
}
/* Class 24 - DPC Behaviour Information */
}
DPRINT("SystemFullMemoryInformation\n");
- PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
+ TheIdleProcess = PsIdleProcess;
DPRINT("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
TheIdleProcess->UniqueProcessId,
*Spi = MiMemoryConsumers[MC_USER].PagesUsed;
- ObDereferenceObject(TheIdleProcess);
-
return (STATUS_SUCCESS);
}
/* Class 44 - Current Time Zone Information */
QSI_DEF(SystemCurrentTimeZoneInformation)
{
- * ReqSize = sizeof (TIME_ZONE_INFORMATION);
+ * ReqSize = sizeof (TIME_ZONE_INFORMATION);
- if (sizeof (TIME_ZONE_INFORMATION) != Size)
- {
- return (STATUS_INFO_LENGTH_MISMATCH);
- }
- /* Copy the time zone information struct */
- memcpy (
- Buffer,
- & _SystemTimeZoneInfo,
- sizeof (TIME_ZONE_INFORMATION)
- );
+ if (sizeof (TIME_ZONE_INFORMATION) != Size)
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
- return (STATUS_SUCCESS);
+ /* Copy the time zone information struct */
+ memcpy(Buffer,
+ &ExpTimeZoneInfo,
+ sizeof(TIME_ZONE_INFORMATION));
+
+ return STATUS_SUCCESS;
}
SSI_DEF(SystemCurrentTimeZoneInformation)
{
- /*
- * Check user buffer's size
- */
- if (Size < sizeof (TIME_ZONE_INFORMATION))
- {
- return (STATUS_INFO_LENGTH_MISMATCH);
- }
- /* Copy the time zone information struct */
- memcpy (
- & _SystemTimeZoneInfo,
- (TIME_ZONE_INFORMATION *) Buffer,
- sizeof (TIME_ZONE_INFORMATION)
- );
- return (STATUS_SUCCESS);
+ /* Check user buffer's size */
+ if (Size < sizeof (TIME_ZONE_INFORMATION))
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ return ExpSetTimeZoneInformation((PTIME_ZONE_INFORMATION)Buffer);
}
PVOID SystemInformation;
NTSTATUS Status;
NTSTATUS FStatus;
+
+ PAGED_CODE();
/* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
SystemInformationClass );
IN ULONG SystemInformationLength
)
{
+ PAGED_CODE();
+
/*
* If called from user mode, check
* possible unsafe arguments.
IN UINT NumberOfBytesToFlush
)
{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
+ PAGED_CODE();
+
+ __asm__("wbinvd\n");
+ return STATUS_SUCCESS;
}