Author: mkupfer
Date: Sun Feb 22 01:41:14 2009
New Revision: 39704
URL:
http://svn.reactos.org/svn/reactos?rev=39704&view=rev
Log:
Evgeniy Boltik <bstsoft AT narod DOT ru>
Jan Roeloffzen <jroeloffzen AT hotmail DOT com>
- Fixes task manager process list names and kernel sysinfo.
- See issue #4087 for details.
Modified:
trunk/reactos/base/applications/taskmgr/perfdata.c
trunk/reactos/ntoskrnl/ex/sysinfo.c
Modified: trunk/reactos/base/applications/taskmgr/perfdata.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/taskmgr/…
==============================================================================
--- trunk/reactos/base/applications/taskmgr/perfdata.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/taskmgr/perfdata.c [iso-8859-1] Sun Feb 22 01:41:14
2009
@@ -241,7 +241,8 @@
HeapFree(GetProcessHeap(), 0, pPerfDataOld);
}
pPerfDataOld = pPerfData;
- pPerfData = (PPERFDATA)HeapAlloc(GetProcessHeap(), 0, sizeof(PERFDATA) *
ProcessCount);
+ /* Clear out process perf data structures with HEAP_ZERO_MEMORY flag: */
+ pPerfData = (PPERFDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PERFDATA)
* ProcessCount);
pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
for (Idx=0; Idx<ProcessCount; Idx++) {
/* Get the old perf data for this process (if any) */
@@ -254,14 +255,16 @@
}
}
- /* Clear out process perf data structure */
- memset(&pPerfData[Idx], 0, sizeof(PERFDATA));
-
- if (pSPI->ImageName.Buffer)
- wcscpy(pPerfData[Idx].ImageName, pSPI->ImageName.Buffer);
- else
+ if (pSPI->ImageName.Buffer) {
+ /* Don't assume a UNICODE_STRING Buffer is zero terminated: */
+ int len = pSPI->ImageName.Length / 2;
+ /* Check against max size and allow for terminating zero (already zeroed):
*/
+ if(len >= MAX_PATH)len=MAX_PATH - 1;
+ wcsncpy(pPerfData[Idx].ImageName, pSPI->ImageName.Buffer, len);
+ } else {
LoadStringW(hInst, IDS_IDLE_PROCESS, pPerfData[Idx].ImageName,
sizeof(pPerfData[Idx].ImageName) /
sizeof(pPerfData[Idx].ImageName[0]));
+ }
pPerfData[Idx].ProcessId = pSPI->UniqueProcessId;
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/sysinfo.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] Sun Feb 22 01:41:14 2009
@@ -701,7 +701,7 @@
/* Class 5 - Process Information */
QSI_DEF(SystemProcessInformation)
{
- PSYSTEM_PROCESS_INFORMATION SpiCurrent;
+ PSYSTEM_PROCESS_INFORMATION SpiCurrent = NULL;
PSYSTEM_THREAD_INFORMATION ThreadInfo;
PEPROCESS Process = NULL, SystemProcess;
PETHREAD CurrentThread;
@@ -712,176 +712,213 @@
PLIST_ENTRY CurrentEntry;
ULONG TotalSize = 0, ThreadsCount;
ULONG TotalUser, TotalKernel;
- PUCHAR Current;
+ PUCHAR Current = NULL;
NTSTATUS Status = STATUS_SUCCESS;
PUNICODE_STRING ProcessImageName;
PWCHAR szSrc;
+ //1 Write in to bufer
+ //2 Calc size buffer
+ //4 Vista compatible
+ //Flags always start write and calculate size
+ //For Vista compatible add "| 4"
+ USHORT OSMode = 1 | 2;
+
_SEH2_TRY
{
/* scan the process list */
PSYSTEM_PROCESS_INFORMATION Spi
- = (PSYSTEM_PROCESS_INFORMATION) Buffer;
-
- *ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION);
-
- if (Size < sizeof(SYSTEM_PROCESS_INFORMATION))
+ = (PSYSTEM_PROCESS_INFORMATION) Buffer;
+
+ while ((OSMode & 1) || (OSMode & 2))
{
- _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is
too small
- }
- RtlZeroMemory(Spi, Size);
-
- SystemProcess = PsIdleProcess;
- Process = SystemProcess;
- Current = (PUCHAR) Spi;
-
- do
- {
- SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
-
- ThreadsCount = 0;
- CurrentEntry = Process->ThreadListHead.Flink;
- while (CurrentEntry != &Process->ThreadListHead)
- {
+ //Vista first cycle only calc size and readonly
+ if (OSMode & 4 && OSMode & 1)
+ OSMode ^= 1;
+ //not exists byffer or size protect write, only calc size
+ if (OSMode & 1 && ((Size == 0) || (!Buffer)))
+ OSMode ^= 1;
+
+ if (OSMode & 1)
+ {
+ //Only in second cycle and vista compatible
+ if (TotalSize > 0 && TotalSize > Size)
+ {
+ *ReqSize = TotalSize;
+ _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size
is too small
+ }
+ if (Size > 0)
+ RtlZeroMemory(Spi, Size);
+ Current = (PUCHAR) Spi;
+ SpiCurrent = NULL;
+ }
+
+ SystemProcess = PsIdleProcess;
+ Process = SystemProcess;
+
+ do
+ {
+ ThreadsCount = 0;
+ CurrentEntry = Process->ThreadListHead.Flink;
+ while (CurrentEntry != &Process->ThreadListHead)
+ {
ThreadsCount++;
CurrentEntry = CurrentEntry->Flink;
- }
-
- // size of the structure for every process
- CurrentSize = sizeof(SYSTEM_PROCESS_INFORMATION) +
sizeof(SYSTEM_THREAD_INFORMATION) * ThreadsCount;
- ImageNameLength = 0;
- Status = SeLocateProcessImageName(Process, &ProcessImageName);
- szSrc = NULL;
- if (NT_SUCCESS(Status))
- {
- szSrc = (PWCHAR)((PCHAR)ProcessImageName->Buffer +
ProcessImageName->Length);
- /* Loop the file name*/
- while (szSrc > ProcessImageName->Buffer)
+ }
+
+ // size of the structure for every process
+ CurrentSize = sizeof(SYSTEM_PROCESS_INFORMATION) +
sizeof(SYSTEM_THREAD_INFORMATION) * ThreadsCount;
+ ImageNameLength = 0;
+ Status = SeLocateProcessImageName(Process, &ProcessImageName);
+ szSrc = NULL;
+ if (NT_SUCCESS(Status) && ProcessImageName->Length > 0)
{
- /* Make sure this isn't a backslash */
- if (*--szSrc == OBJ_NAME_PATH_SEPARATOR)
+ szSrc = (PWCHAR)((PCHAR)ProcessImageName->Buffer +
ProcessImageName->Length);
+ /* Loop the file name*/
+ while (szSrc > ProcessImageName->Buffer)
{
+ /* Make sure this isn't a backslash */
+ if (*--szSrc == OBJ_NAME_PATH_SEPARATOR)
+ {
szSrc++;
break;
+ }
+ else
+ {
+ ImageNameLength += sizeof(WCHAR);
+ }
+ }
+ }
+ if (!ImageNameLength && Process != PsIdleProcess &&
Process->ImageFileName)
+ {
+ ImageNameLength = strlen(Process->ImageFileName) * sizeof(WCHAR);
+ }
+
+ /* Round up the image name length as NT does */
+ ImageNameMaximumLength =
+ (ImageNameLength > 0 ? ROUND_UP(ImageNameLength+1, 8) : 0);
+
+ if (OSMode & 2)
+ TotalSize += CurrentSize + ImageNameMaximumLength;
+
+ if ((OSMode & 1) && Buffer && TotalSize <= Size)
+ {
+ //Set prev structure NextEntryOffset next structure only exists write
buffer
+ if (SpiCurrent && TotalSize <= Size)
+ SpiCurrent->NextEntryOffset = Current - (PUCHAR)SpiCurrent;//
relative offset to the beginnnig of the next structure
+ SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
+
+ /* Fill system information */
+ SpiCurrent->NumberOfThreads = ThreadsCount;
+ SpiCurrent->CreateTime = Process->CreateTime;
+ SpiCurrent->ImageName.Length = ImageNameLength;
+ SpiCurrent->ImageName.MaximumLength = ImageNameMaximumLength;
+ SpiCurrent->ImageName.Buffer = (void*)(Current + CurrentSize);
+
+ /* Copy name to the end of the struct */
+ if(Process != PsIdleProcess)
+ {
+ if (szSrc)
+ {
+ RtlCopyMemory(SpiCurrent->ImageName.Buffer, szSrc,
SpiCurrent->ImageName.Length);
+ }
+ else if (Process->ImageFileName)
+ {
+ RtlInitAnsiString(&ImageName, Process->ImageFileName);
+ RtlAnsiStringToUnicodeString(&SpiCurrent->ImageName,
&ImageName, FALSE);
+ }
}
else
{
- ImageNameLength += sizeof(WCHAR);
+ RtlInitUnicodeString(&SpiCurrent->ImageName, NULL);
}
+
+ SpiCurrent->BasePriority = Process->Pcb.BasePriority;
+ SpiCurrent->UniqueProcessId = Process->UniqueProcessId;
+ SpiCurrent->InheritedFromUniqueProcessId =
Process->InheritedFromUniqueProcessId;
+ SpiCurrent->HandleCount = ObGetProcessHandleCount(Process);
+ SpiCurrent->PeakVirtualSize = Process->PeakVirtualSize;
+ SpiCurrent->VirtualSize = Process->VirtualSize;
+ SpiCurrent->PageFaultCount = Process->Vm.PageFaultCount;
+ SpiCurrent->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
+ SpiCurrent->WorkingSetSize = Process->Vm.WorkingSetSize;
+ SpiCurrent->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0];
+ SpiCurrent->QuotaPagedPoolUsage = Process->QuotaUsage[0];
+ SpiCurrent->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
+ SpiCurrent->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
+ SpiCurrent->PagefileUsage = Process->QuotaUsage[2];
+ SpiCurrent->PeakPagefileUsage = Process->QuotaPeak[2];
+ SpiCurrent->PrivatePageCount = Process->CommitCharge;
+ ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(SpiCurrent + 1);
+
+ CurrentEntry = Process->ThreadListHead.Flink;
+ while (CurrentEntry != &Process->ThreadListHead)
+ {
+ CurrentThread = CONTAINING_RECORD(CurrentEntry, ETHREAD,
+ ThreadListEntry);
+
+ ThreadInfo->KernelTime.QuadPart =
UInt32x32To64(CurrentThread->Tcb.KernelTime, KeMaximumIncrement);
+ ThreadInfo->UserTime.QuadPart =
UInt32x32To64(CurrentThread->Tcb.UserTime, KeMaximumIncrement);
+ ThreadInfo->CreateTime.QuadPart =
CurrentThread->CreateTime.QuadPart;
+ ThreadInfo->WaitTime = CurrentThread->Tcb.WaitTime;
+ ThreadInfo->StartAddress = (PVOID)
CurrentThread->StartAddress;
+ ThreadInfo->ClientId = CurrentThread->Cid;
+ ThreadInfo->Priority = CurrentThread->Tcb.Priority;
+ ThreadInfo->BasePriority = CurrentThread->Tcb.BasePriority;
+ ThreadInfo->ContextSwitches =
CurrentThread->Tcb.ContextSwitches;
+ ThreadInfo->ThreadState = CurrentThread->Tcb.State;
+ ThreadInfo->WaitReason = CurrentThread->Tcb.WaitReason;
+
+ ThreadInfo++;
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ /* Query total user/kernel times of a process */
+ TotalKernel = KeQueryRuntimeProcess(&Process->Pcb,
&TotalUser);
+ SpiCurrent->UserTime.QuadPart = UInt32x32To64(TotalUser,
KeMaximumIncrement);
+ SpiCurrent->KernelTime.QuadPart = UInt32x32To64(TotalKernel,
KeMaximumIncrement);
}
- }
- if (!ImageNameLength && Process != PsIdleProcess &&
Process->ImageFileName)
- {
- ImageNameLength = strlen(Process->ImageFileName) * sizeof(WCHAR);
- }
-
- /* Round up the image name length as NT does */
- ImageNameMaximumLength = ROUND_UP(ImageNameLength, 8);
-
- TotalSize += CurrentSize + ImageNameMaximumLength;
-
- if (TotalSize > Size)
- {
- *ReqSize = TotalSize;
- ObDereferenceObject(Process);
-
- /* Release the memory allocated by SeLocateProcessImageName */
- if (NT_SUCCESS(Status)) ExFreePool(ProcessImageName);
-
- _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size
is too small
- }
-
- /* Fill system information */
- SpiCurrent->NextEntryOffset = CurrentSize + ImageNameMaximumLength; //
relative offset to the beginnnig of the next structure
- SpiCurrent->NumberOfThreads = ThreadsCount;
- SpiCurrent->CreateTime = Process->CreateTime;
- SpiCurrent->ImageName.Length = ImageNameLength;
- SpiCurrent->ImageName.MaximumLength = ImageNameMaximumLength;
- SpiCurrent->ImageName.Buffer = (void*)(Current + CurrentSize);
-
- /* Copy name to the end of the struct */
- if(Process != PsIdleProcess)
- {
- if (szSrc)
+ /* Release the memory allocated by SeLocateProcessImageName */
+ if (NT_SUCCESS(Status)) ExFreePool(ProcessImageName);
+
+ /* Handle idle process entry */
+ if (Process == PsIdleProcess) Process = NULL;
+
+ Process = PsGetNextProcess(Process);
+ ThreadsCount = 0;
+ if ((Process == SystemProcess) || (Process == NULL))
{
- RtlCopyMemory(SpiCurrent->ImageName.Buffer, szSrc,
SpiCurrent->ImageName.Length);
-
- /* Release the memory allocated by SeLocateProcessImageName */
- ExFreePool(ProcessImageName);
+ break;
}
- else if (Process->ImageFileName)
+ else
{
- RtlInitAnsiString(&ImageName, Process->ImageFileName);
- RtlAnsiStringToUnicodeString(&SpiCurrent->ImageName,
&ImageName, FALSE);
+ if (Current)
+ Current += CurrentSize + ImageNameMaximumLength;
}
- }
- else
- {
- RtlInitUnicodeString(&SpiCurrent->ImageName, NULL);
- }
-
- SpiCurrent->BasePriority = Process->Pcb.BasePriority;
- SpiCurrent->UniqueProcessId = Process->UniqueProcessId;
- SpiCurrent->InheritedFromUniqueProcessId =
Process->InheritedFromUniqueProcessId;
- SpiCurrent->HandleCount = ObGetProcessHandleCount(Process);
- SpiCurrent->PeakVirtualSize = Process->PeakVirtualSize;
- SpiCurrent->VirtualSize = Process->VirtualSize;
- SpiCurrent->PageFaultCount = Process->Vm.PageFaultCount;
- SpiCurrent->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
- SpiCurrent->WorkingSetSize = Process->Vm.WorkingSetSize;
- SpiCurrent->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0];
- SpiCurrent->QuotaPagedPoolUsage = Process->QuotaUsage[0];
- SpiCurrent->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
- SpiCurrent->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
- SpiCurrent->PagefileUsage = Process->QuotaUsage[2];
- SpiCurrent->PeakPagefileUsage = Process->QuotaPeak[2];
- SpiCurrent->PrivatePageCount = Process->CommitCharge;
- ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(SpiCurrent + 1);
-
- CurrentEntry = Process->ThreadListHead.Flink;
- while (CurrentEntry != &Process->ThreadListHead)
- {
- CurrentThread = CONTAINING_RECORD(CurrentEntry, ETHREAD,
- ThreadListEntry);
-
- ThreadInfo->KernelTime.QuadPart =
UInt32x32To64(CurrentThread->Tcb.KernelTime, KeMaximumIncrement);
- ThreadInfo->UserTime.QuadPart =
UInt32x32To64(CurrentThread->Tcb.UserTime, KeMaximumIncrement);
- ThreadInfo->CreateTime.QuadPart =
CurrentThread->CreateTime.QuadPart;
- ThreadInfo->WaitTime = CurrentThread->Tcb.WaitTime;
- ThreadInfo->StartAddress = (PVOID) CurrentThread->StartAddress;
- ThreadInfo->ClientId = CurrentThread->Cid;
- ThreadInfo->Priority = CurrentThread->Tcb.Priority;
- ThreadInfo->BasePriority = CurrentThread->Tcb.BasePriority;
- ThreadInfo->ContextSwitches = CurrentThread->Tcb.ContextSwitches;
- ThreadInfo->ThreadState = CurrentThread->Tcb.State;
- ThreadInfo->WaitReason = CurrentThread->Tcb.WaitReason;
-
- ThreadInfo++;
- CurrentEntry = CurrentEntry->Flink;
- }
-
- /* Query total user/kernel times of a process */
- TotalKernel = KeQueryRuntimeProcess(&Process->Pcb, &TotalUser);
- SpiCurrent->UserTime.QuadPart = UInt32x32To64(TotalUser,
KeMaximumIncrement);
- SpiCurrent->KernelTime.QuadPart = UInt32x32To64(TotalKernel,
KeMaximumIncrement);
-
- /* Handle idle process entry */
- if (Process == PsIdleProcess) Process = NULL;
-
- Process = PsGetNextProcess(Process);
- ThreadsCount = 0;
- if ((Process == SystemProcess) || (Process == NULL))
- {
- SpiCurrent->NextEntryOffset = 0;
- break;
- }
- else
- Current += CurrentSize + ImageNameMaximumLength;
} while ((Process != SystemProcess) && (Process != NULL));
-
- if(Process != NULL)
- ObDereferenceObject(Process);
+ //Break parameters information for only calc size
+ if ((Size == 0) || (!Buffer))
+ break;
+ //Stop write in to buffer
+ if (OSMode & 1)
+ OSMode ^= 1;
+ //Only first cycle calc size
+ if (OSMode & 2)
+ OSMode ^= 2;
+ //Vista next cycle write in to Buffer
+ if (OSMode & 4)
+ {
+ OSMode |= 1;
+ OSMode ^= 4;
+ }
+ };
+
+ if(Process != NULL)
+ ObDereferenceObject(Process);
+ if ((Size == 0) || (!Buffer) || (TotalSize > Size))
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ else
Status = STATUS_SUCCESS;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -1888,8 +1925,9 @@
if (PreviousMode != KernelMode)
{
/* SystemKernelDebuggerInformation needs only BOOLEAN alignment */
- ProbeForWrite(SystemInformation, Length, 1);
- if (UnsafeResultLength != NULL)
+ if (SystemInformation)
+ ProbeForWrite(SystemInformation, Length, 1);
+ if (UnsafeResultLength)
ProbeForWriteUlong(UnsafeResultLength);
}