- 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)+sizeof(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)+sizeof(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;