- Fix size check in SystemBasicInformation and SystemTimeOfDayInformation. - Add SEH protection to SystemProcessInformation. - Implement SystemKernelDebuggerInformation. - Fix returning of ResultLength in NtQuerySystemInformation. Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c _____
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c --- trunk/reactos/ntoskrnl/ex/sysinfo.c 2005-08-07 09:03:35 UTC (rev 17147) +++ trunk/reactos/ntoskrnl/ex/sysinfo.c 2005-08-07 09:12:10 UTC (rev 17148) @@ -57,7 +57,7 @@
TotalTime = Prcb->KernelTime + Prcb->UserTime; if (TotalTime != 0) *CpuUsage = 100 - (ScaledIdle / TotalTime); - else + else *CpuUsage = 0; }
@@ -360,7 +360,7 @@ /* * Check user buffer's size */ - if (Size < sizeof (SYSTEM_BASIC_INFORMATION)) + if (Size != sizeof (SYSTEM_BASIC_INFORMATION)) { return (STATUS_INFO_LENGTH_MISMATCH); } @@ -539,7 +539,7 @@ *ReqSize = sizeof (SYSTEM_TIMEOFDAY_INFORMATION);
/* Check user buffer's size */ - if (Size < sizeof (SYSTEM_TIMEOFDAY_INFORMATION)) + if (Size != sizeof (SYSTEM_TIMEOFDAY_INFORMATION)) { return STATUS_INFO_LENGTH_MISMATCH; } @@ -570,131 +570,141 @@ ULONG ovlSize=0, nThreads; PEPROCESS pr, syspr; unsigned char *pCur; + NTSTATUS Status;
- /* scan the process list */ - - PSYSTEM_PROCESS_INFORMATION Spi - = (PSYSTEM_PROCESS_INFORMATION) Buffer; - - *ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION); - - if (Size < sizeof(SYSTEM_PROCESS_INFORMATION)) + _SEH_TRY { - return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small - } + /* scan the process list */
- syspr = PsGetNextProcess(NULL); - pr = syspr; - pCur = (unsigned char *)Spi; + PSYSTEM_PROCESS_INFORMATION Spi + = (PSYSTEM_PROCESS_INFORMATION) Buffer;
- do - { - 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; + *ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION);
- SpiCur = (PSYSTEM_PROCESS_INFORMATION)pCur; - - nThreads = 0; - current_entry = pr->ThreadListHead.Flink; - while (current_entry != &pr->ThreadListHead) + if (Size < sizeof(SYSTEM_PROCESS_INFORMATION)) { - nThreads++; - current_entry = current_entry->Flink; + return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small }
- // size of the structure for every process - curSize = sizeof(SYSTEM_PROCESS_INFORMATION)-sizeof(SYSTEM_THREAD_INFORMATION)+siz eof(SYSTEM_THREAD_INFORMATION)*nThreads; - ovlSize += curSize+inLen; + syspr = PsGetNextProcess(NULL); + pr = syspr; + pCur = (unsigned char *)Spi;
- if (ovlSize > Size) + do { - *ReqSize = ovlSize; - ObDereferenceObject(pr); + 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;
- return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small - } + SpiCur = (PSYSTEM_PROCESS_INFORMATION)pCur;
- // 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); + nThreads = 0; + current_entry = pr->ThreadListHead.Flink; + while (current_entry != &pr->ThreadListHead) + { + nThreads++; + current_entry = current_entry->Flink; + }
- // 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); - } + // size of the structure for every process + curSize = sizeof(SYSTEM_PROCESS_INFORMATION)-sizeof(SYSTEM_THREAD_INFORMATION)+siz eof(SYSTEM_THREAD_INFORMATION)*nThreads; + ovlSize += curSize+inLen;
- 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; // 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; + if (ovlSize > Size) + { + *ReqSize = ovlSize; + ObDereferenceObject(pr);
- current_entry = pr->ThreadListHead.Flink; - while (current_entry != &pr->ThreadListHead) - { - current = CONTAINING_RECORD(current_entry, ETHREAD, - ThreadListEntry); + return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small + }
- 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; - } + // 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);
- pr = PsGetNextProcess(pr); - nThreads = 0; - if ((pr == syspr) || (pr == NULL)) - { - SpiCur->NextEntryOffset = 0; - break; - } - else - pCur = pCur + curSize + inLen; - } while ((pr != syspr) && (pr != NULL)); + // 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); + }
- if(pr != 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 { - ObDereferenceObject(pr); + if(pr != NULL) + ObDereferenceObject(pr); + Status = _SEH_GetExceptionCode(); } + _SEH_END
*ReqSize = ovlSize; - return (STATUS_SUCCESS); + return Status; }
/* Class 6 - Call Count Information */ @@ -1213,9 +1223,18 @@ /* Class 35 - Kernel Debugger Information */ QSI_DEF(SystemKernelDebuggerInformation) { - /* FIXME */ - DPRINT1("NtQuerySystemInformation - SystemKernelDebuggerInformation not implemented\n"); - return (STATUS_NOT_IMPLEMENTED); + PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION) Buffer; + + *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 */ @@ -1551,11 +1570,10 @@ FStatus = CallQS [SystemInformationClass].Query(SystemInformation, Length,
&ResultLength); - if (NT_SUCCESS(FStatus) && UnsafeResultLength != NULL) + if (UnsafeResultLength != NULL) { if (PreviousMode != KernelMode) { - FStatus = STATUS_SUCCESS; _SEH_TRY { *UnsafeResultLength = ResultLength;