mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 00:43:21 +00:00
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. svn path=/trunk/; revision=39704
This commit is contained in:
parent
166f97fa19
commit
0ef3ed3fb1
|
@ -241,7 +241,8 @@ void PerfDataRefresh(void)
|
|||
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 @@ void PerfDataRefresh(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
|
|
|
@ -701,7 +701,7 @@ QSI_DEF(SystemPathInformation)
|
|||
/* 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,11 +712,18 @@ QSI_DEF(SystemProcessInformation)
|
|||
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 */
|
||||
|
@ -724,22 +731,34 @@ QSI_DEF(SystemProcessInformation)
|
|||
PSYSTEM_PROCESS_INFORMATION Spi
|
||||
= (PSYSTEM_PROCESS_INFORMATION) Buffer;
|
||||
|
||||
*ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION);
|
||||
|
||||
if (Size < sizeof(SYSTEM_PROCESS_INFORMATION))
|
||||
while ((OSMode & 1) || (OSMode & 2))
|
||||
{
|
||||
//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;
|
||||
Current = (PUCHAR) Spi;
|
||||
|
||||
do
|
||||
{
|
||||
SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
|
||||
|
||||
ThreadsCount = 0;
|
||||
CurrentEntry = Process->ThreadListHead.Flink;
|
||||
while (CurrentEntry != &Process->ThreadListHead)
|
||||
|
@ -753,7 +772,7 @@ QSI_DEF(SystemProcessInformation)
|
|||
ImageNameLength = 0;
|
||||
Status = SeLocateProcessImageName(Process, &ProcessImageName);
|
||||
szSrc = NULL;
|
||||
if (NT_SUCCESS(Status))
|
||||
if (NT_SUCCESS(Status) && ProcessImageName->Length > 0)
|
||||
{
|
||||
szSrc = (PWCHAR)((PCHAR)ProcessImageName->Buffer + ProcessImageName->Length);
|
||||
/* Loop the file name*/
|
||||
|
@ -777,23 +796,20 @@ QSI_DEF(SystemProcessInformation)
|
|||
}
|
||||
|
||||
/* Round up the image name length as NT does */
|
||||
ImageNameMaximumLength = ROUND_UP(ImageNameLength, 8);
|
||||
ImageNameMaximumLength =
|
||||
(ImageNameLength > 0 ? ROUND_UP(ImageNameLength+1, 8) : 0);
|
||||
|
||||
if (OSMode & 2)
|
||||
TotalSize += CurrentSize + ImageNameMaximumLength;
|
||||
|
||||
if (TotalSize > Size)
|
||||
if ((OSMode & 1) && Buffer && 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
|
||||
}
|
||||
//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->NextEntryOffset = CurrentSize + ImageNameMaximumLength; // relative offset to the beginnnig of the next structure
|
||||
SpiCurrent->NumberOfThreads = ThreadsCount;
|
||||
SpiCurrent->CreateTime = Process->CreateTime;
|
||||
SpiCurrent->ImageName.Length = ImageNameLength;
|
||||
|
@ -806,9 +822,6 @@ QSI_DEF(SystemProcessInformation)
|
|||
if (szSrc)
|
||||
{
|
||||
RtlCopyMemory(SpiCurrent->ImageName.Buffer, szSrc, SpiCurrent->ImageName.Length);
|
||||
|
||||
/* Release the memory allocated by SeLocateProcessImageName */
|
||||
ExFreePool(ProcessImageName);
|
||||
}
|
||||
else if (Process->ImageFileName)
|
||||
{
|
||||
|
@ -865,6 +878,9 @@ QSI_DEF(SystemProcessInformation)
|
|||
TotalKernel = KeQueryRuntimeProcess(&Process->Pcb, &TotalUser);
|
||||
SpiCurrent->UserTime.QuadPart = UInt32x32To64(TotalUser, KeMaximumIncrement);
|
||||
SpiCurrent->KernelTime.QuadPart = UInt32x32To64(TotalKernel, KeMaximumIncrement);
|
||||
}
|
||||
/* Release the memory allocated by SeLocateProcessImageName */
|
||||
if (NT_SUCCESS(Status)) ExFreePool(ProcessImageName);
|
||||
|
||||
/* Handle idle process entry */
|
||||
if (Process == PsIdleProcess) Process = NULL;
|
||||
|
@ -873,15 +889,36 @@ QSI_DEF(SystemProcessInformation)
|
|||
ThreadsCount = 0;
|
||||
if ((Process == SystemProcess) || (Process == NULL))
|
||||
{
|
||||
SpiCurrent->NextEntryOffset = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Current)
|
||||
Current += CurrentSize + ImageNameMaximumLength;
|
||||
}
|
||||
} while ((Process != SystemProcess) && (Process != NULL));
|
||||
//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 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
|||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
/* SystemKernelDebuggerInformation needs only BOOLEAN alignment */
|
||||
if (SystemInformation)
|
||||
ProbeForWrite(SystemInformation, Length, 1);
|
||||
if (UnsafeResultLength != NULL)
|
||||
if (UnsafeResultLength)
|
||||
ProbeForWriteUlong(UnsafeResultLength);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue