- Fix size check in SystemBasicInformation and SystemTimeOfDayInformation.

- Add SEH protection to SystemProcessInformation.
- Implement SystemKernelDebuggerInformation.
- Fix returning of ResultLength in NtQuerySystemInformation.

svn path=/trunk/; revision=17148
This commit is contained in:
Filip Navara 2005-08-07 09:12:10 +00:00
parent 6e9638b203
commit 26d1cb6272

View file

@ -57,7 +57,7 @@ ExGetCurrentProcessorCpuUsage (
TotalTime = Prcb->KernelTime + Prcb->UserTime; TotalTime = Prcb->KernelTime + Prcb->UserTime;
if (TotalTime != 0) if (TotalTime != 0)
*CpuUsage = 100 - (ScaledIdle / TotalTime); *CpuUsage = 100 - (ScaledIdle / TotalTime);
else else
*CpuUsage = 0; *CpuUsage = 0;
} }
@ -360,7 +360,7 @@ QSI_DEF(SystemBasicInformation)
/* /*
* Check user buffer's size * Check user buffer's size
*/ */
if (Size < sizeof (SYSTEM_BASIC_INFORMATION)) if (Size != sizeof (SYSTEM_BASIC_INFORMATION))
{ {
return (STATUS_INFO_LENGTH_MISMATCH); return (STATUS_INFO_LENGTH_MISMATCH);
} }
@ -539,7 +539,7 @@ QSI_DEF(SystemTimeOfDayInformation)
*ReqSize = sizeof (SYSTEM_TIMEOFDAY_INFORMATION); *ReqSize = sizeof (SYSTEM_TIMEOFDAY_INFORMATION);
/* Check user buffer's size */ /* Check user buffer's size */
if (Size < sizeof (SYSTEM_TIMEOFDAY_INFORMATION)) if (Size != sizeof (SYSTEM_TIMEOFDAY_INFORMATION))
{ {
return STATUS_INFO_LENGTH_MISMATCH; return STATUS_INFO_LENGTH_MISMATCH;
} }
@ -570,131 +570,141 @@ QSI_DEF(SystemProcessInformation)
ULONG ovlSize=0, nThreads; ULONG ovlSize=0, nThreads;
PEPROCESS pr, syspr; PEPROCESS pr, syspr;
unsigned char *pCur; unsigned char *pCur;
NTSTATUS Status;
/* scan the process list */ _SEH_TRY
PSYSTEM_PROCESS_INFORMATION Spi
= (PSYSTEM_PROCESS_INFORMATION) Buffer;
*ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION);
if (Size < sizeof(SYSTEM_PROCESS_INFORMATION))
{ {
return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small /* scan the process list */
}
syspr = PsGetNextProcess(NULL); PSYSTEM_PROCESS_INFORMATION Spi
pr = syspr; = (PSYSTEM_PROCESS_INFORMATION) Buffer;
pCur = (unsigned char *)Spi;
do *ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION);
{
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_PROCESS_INFORMATION)pCur; if (Size < sizeof(SYSTEM_PROCESS_INFORMATION))
nThreads = 0;
current_entry = pr->ThreadListHead.Flink;
while (current_entry != &pr->ThreadListHead)
{ {
nThreads++;
current_entry = current_entry->Flink;
}
// size of the structure for every process
curSize = sizeof(SYSTEM_PROCESS_INFORMATION)-sizeof(SYSTEM_THREAD_INFORMATION)+sizeof(SYSTEM_THREAD_INFORMATION)*nThreads;
ovlSize += curSize+inLen;
if (ovlSize > Size)
{
*ReqSize = ovlSize;
ObDereferenceObject(pr);
return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
} }
// fill system information syspr = PsGetNextProcess(NULL);
SpiCur->NextEntryOffset = curSize+inLen; // relative offset to the beginnnig of the next structure pr = syspr;
SpiCur->NumberOfThreads = nThreads; pCur = (unsigned char *)Spi;
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 = inLen;
SpiCur->ImageName.Buffer = (void*)(pCur+curSize);
// copy name to the end of the struct do
if(pr != PsIdleProcess)
{ {
RtlInitAnsiString(&imgName, pr->ImageFileName); PSYSTEM_PROCESS_INFORMATION SpiCur;
RtlAnsiStringToUnicodeString(&SpiCur->ImageName, &imgName, FALSE); int curSize, i = 0;
} ANSI_STRING imgName;
else int inLen=32; // image name len in bytes
{ PLIST_ENTRY current_entry;
RtlInitUnicodeString(&SpiCur->ImageName, NULL); PETHREAD current;
}
SpiCur->BasePriority = pr->Pcb.BasePriority; SpiCur = (PSYSTEM_PROCESS_INFORMATION)pCur;
SpiCur->UniqueProcessId = pr->UniqueProcessId;
SpiCur->InheritedFromUniqueProcessId = pr->InheritedFromUniqueProcessId;
SpiCur->HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
SpiCur->PeakVirtualSize = pr->PeakVirtualSize;
SpiCur->VirtualSize = pr->VirtualSize;
SpiCur->PageFaultCount = pr->Vm.PageFaultCount;
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->QuotaPeak[0];
SpiCur->QuotaPagedPoolUsage = pr->QuotaUsage[0];
SpiCur->QuotaPeakNonPagedPoolUsage = pr->QuotaPeak[1];
SpiCur->QuotaNonPagedPoolUsage = pr->QuotaUsage[1];
SpiCur->PagefileUsage = pr->QuotaUsage[3];
SpiCur->PeakPagefileUsage = pr->QuotaPeak[3];
SpiCur->PrivateUsage = pr->CommitCharge;
current_entry = pr->ThreadListHead.Flink; nThreads = 0;
while (current_entry != &pr->ThreadListHead) current_entry = pr->ThreadListHead.Flink;
{ while (current_entry != &pr->ThreadListHead)
current = CONTAINING_RECORD(current_entry, ETHREAD, {
ThreadListEntry); nThreads++;
current_entry = current_entry->Flink;
}
SpiCur->TH[i].KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL; // size of the structure for every process
SpiCur->TH[i].UserTime.QuadPart = current->Tcb.UserTime * 100000LL; curSize = sizeof(SYSTEM_PROCESS_INFORMATION)-sizeof(SYSTEM_THREAD_INFORMATION)+sizeof(SYSTEM_THREAD_INFORMATION)*nThreads;
// SpiCur->TH[i].CreateTime = current->CreateTime; ovlSize += curSize+inLen;
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); if (ovlSize > Size)
nThreads = 0; {
if ((pr == syspr) || (pr == NULL)) *ReqSize = ovlSize;
{ ObDereferenceObject(pr);
SpiCur->NextEntryOffset = 0;
break;
}
else
pCur = pCur + curSize + inLen;
} while ((pr != syspr) && (pr != NULL));
if(pr != NULL) return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
{ }
ObDereferenceObject(pr);
// 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 = inLen;
SpiCur->ImageName.Buffer = (void*)(pCur+curSize);
// copy name to the end of the struct
if(pr != PsIdleProcess)
{
RtlInitAnsiString(&imgName, pr->ImageFileName);
RtlAnsiStringToUnicodeString(&SpiCur->ImageName, &imgName, FALSE);
}
else
{
RtlInitUnicodeString(&SpiCur->ImageName, NULL);
}
SpiCur->BasePriority = pr->Pcb.BasePriority;
SpiCur->UniqueProcessId = pr->UniqueProcessId;
SpiCur->InheritedFromUniqueProcessId = pr->InheritedFromUniqueProcessId;
SpiCur->HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
SpiCur->PeakVirtualSize = pr->PeakVirtualSize;
SpiCur->VirtualSize = pr->VirtualSize;
SpiCur->PageFaultCount = pr->Vm.PageFaultCount;
SpiCur->PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize;
SpiCur->WorkingSetSize = pr->Vm.WorkingSetSize;
SpiCur->QuotaPeakPagedPoolUsage = pr->QuotaPeak[0];
SpiCur->QuotaPagedPoolUsage = pr->QuotaUsage[0];
SpiCur->QuotaPeakNonPagedPoolUsage = pr->QuotaPeak[1];
SpiCur->QuotaNonPagedPoolUsage = pr->QuotaUsage[1];
SpiCur->PagefileUsage = pr->QuotaUsage[3];
SpiCur->PeakPagefileUsage = pr->QuotaPeak[3];
SpiCur->PrivateUsage = pr->CommitCharge;
current_entry = pr->ThreadListHead.Flink;
while (current_entry != &pr->ThreadListHead)
{
current = CONTAINING_RECORD(current_entry, ETHREAD,
ThreadListEntry);
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->NextEntryOffset = 0;
break;
}
else
pCur = pCur + curSize + inLen;
} while ((pr != syspr) && (pr != NULL));
if(pr != NULL)
ObDereferenceObject(pr);
Status = STATUS_SUCCESS;
} }
_SEH_HANDLE
{
if(pr != NULL)
ObDereferenceObject(pr);
Status = _SEH_GetExceptionCode();
}
_SEH_END
*ReqSize = ovlSize; *ReqSize = ovlSize;
return (STATUS_SUCCESS); return Status;
} }
/* Class 6 - Call Count Information */ /* Class 6 - Call Count Information */
@ -1213,9 +1223,18 @@ QSI_DEF(SystemCrashDumpStateInformation)
/* Class 35 - Kernel Debugger Information */ /* Class 35 - Kernel Debugger Information */
QSI_DEF(SystemKernelDebuggerInformation) QSI_DEF(SystemKernelDebuggerInformation)
{ {
/* FIXME */ PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION) Buffer;
DPRINT1("NtQuerySystemInformation - SystemKernelDebuggerInformation not implemented\n");
return (STATUS_NOT_IMPLEMENTED); *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION);
if (Size < sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION))
{
return STATUS_INFO_LENGTH_MISMATCH;
}
skdi->KernelDebuggerEnabled = KD_DEBUGGER_ENABLED;
skdi->KernelDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT;
return STATUS_SUCCESS;
} }
/* Class 36 - Context Switch Information */ /* Class 36 - Context Switch Information */
@ -1551,11 +1570,10 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
FStatus = CallQS [SystemInformationClass].Query(SystemInformation, FStatus = CallQS [SystemInformationClass].Query(SystemInformation,
Length, Length,
&ResultLength); &ResultLength);
if (NT_SUCCESS(FStatus) && UnsafeResultLength != NULL) if (UnsafeResultLength != NULL)
{ {
if (PreviousMode != KernelMode) if (PreviousMode != KernelMode)
{ {
FStatus = STATUS_SUCCESS;
_SEH_TRY _SEH_TRY
{ {
*UnsafeResultLength = ResultLength; *UnsafeResultLength = ResultLength;