1 /* $Id: sysinfo.c,v 1.47 2004/09/28 19:49:20 gvg Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/sysinfo.c
6 * PURPOSE: System information functions
7 * PROGRAMMER: David Welch (welch@mcmail.com)
10 * 20/03/2003: implemented querying SystemProcessInformation,
11 * no more copying to-from the caller (Aleksey
12 * Bragin <aleksey@studiocerebral.com>)
15 /* INCLUDES *****************************************************************/
19 #include <internal/debug.h>
21 extern ULONG NtGlobalFlag
; /* FIXME: it should go in a ddk/?.h */
22 ULONGLONG STDCALL
KeQueryInterruptTime(VOID
);
24 VOID
MmPrintMemoryStatistic(VOID
);
26 extern ULONG Ke386CpuidFlags
;
27 extern ULONG Ke386Cpuid
;
29 /* FUNCTIONS *****************************************************************/
40 PHANDLE Handle OPTIONAL
51 ExGetCurrentProcessorCounts (
64 ExGetCurrentProcessorCpuUsage (
72 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
73 OUT PVOID UnsafeValue
,
75 IN OUT PULONG UnsafeReturnLength
)
83 UNICODE_STRING WValue
;
87 * Copy the name to kernel space if necessary and convert it to ANSI.
89 if (ExGetPreviousMode() != KernelMode
)
91 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
92 if (!NT_SUCCESS(Status
))
96 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
97 if (!NT_SUCCESS(Status
))
104 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
105 if (!NT_SUCCESS(Status
))
112 * Create a temporary buffer for the value
114 Value
= ExAllocatePool(NonPagedPool
, Length
);
117 RtlFreeAnsiString(&AName
);
118 if (ExGetPreviousMode() != KernelMode
)
120 RtlFreeUnicodeString(&WName
);
122 return(STATUS_NO_MEMORY
);
126 * Get the environment variable
128 Result
= HalGetEnvironmentVariable(AName
.Buffer
, Value
, Length
);
131 RtlFreeAnsiString(&AName
);
132 if (ExGetPreviousMode() != KernelMode
)
134 RtlFreeUnicodeString(&WName
);
137 return(STATUS_UNSUCCESSFUL
);
141 * Convert the result to UNICODE.
143 RtlInitAnsiString(&AValue
, Value
);
144 Status
= RtlAnsiStringToUnicodeString(&WValue
, &AValue
, TRUE
);
145 if (!NT_SUCCESS(Status
))
147 RtlFreeAnsiString(&AName
);
148 if (ExGetPreviousMode() != KernelMode
)
150 RtlFreeUnicodeString(&WName
);
155 ReturnLength
= WValue
.Length
;
158 * Copy the result back to the caller.
160 if (ExGetPreviousMode() != KernelMode
)
162 Status
= MmCopyToCaller(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
163 if (!NT_SUCCESS(Status
))
165 RtlFreeAnsiString(&AName
);
166 if (ExGetPreviousMode() != KernelMode
)
168 RtlFreeUnicodeString(&WName
);
171 RtlFreeUnicodeString(&WValue
);
175 Status
= MmCopyToCaller(UnsafeReturnLength
, &ReturnLength
,
177 if (!NT_SUCCESS(Status
))
179 RtlFreeAnsiString(&AName
);
180 if (ExGetPreviousMode() != KernelMode
)
182 RtlFreeUnicodeString(&WName
);
185 RtlFreeUnicodeString(&WValue
);
191 memcpy(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
192 memcpy(UnsafeReturnLength
, &ReturnLength
, sizeof(ULONG
));
196 * Free temporary buffers.
198 RtlFreeAnsiString(&AName
);
199 if (ExGetPreviousMode() != KernelMode
)
201 RtlFreeUnicodeString(&WName
);
204 RtlFreeUnicodeString(&WValue
);
206 return(STATUS_SUCCESS
);
211 NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
212 IN PUNICODE_STRING UnsafeValue
)
214 UNICODE_STRING WName
;
216 UNICODE_STRING WValue
;
222 * Check for required privilege.
224 /* FIXME: Not implemented. */
227 * Copy the name to kernel space if necessary and convert it to ANSI.
229 if (ExGetPreviousMode() != KernelMode
)
231 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
232 if (!NT_SUCCESS(Status
))
236 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
237 if (!NT_SUCCESS(Status
))
244 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
245 if (!NT_SUCCESS(Status
))
252 * Copy the value to kernel space and convert to ANSI.
254 if (ExGetPreviousMode() != KernelMode
)
256 Status
= RtlCaptureUnicodeString(&WValue
, UnsafeValue
);
257 if (!NT_SUCCESS(Status
))
259 RtlFreeUnicodeString(&WName
);
260 RtlFreeAnsiString(&AName
);
263 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
264 if (!NT_SUCCESS(Status
))
266 RtlFreeUnicodeString(&WName
);
267 RtlFreeAnsiString(&AName
);
268 RtlFreeUnicodeString(&WValue
);
274 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
275 if (!NT_SUCCESS(Status
))
277 RtlFreeAnsiString(&AName
);
283 * Set the environment variable
285 Result
= HalSetEnvironmentVariable(AName
.Buffer
, AValue
.Buffer
);
288 * Free everything and return status.
290 RtlFreeAnsiString(&AName
);
291 RtlFreeAnsiString(&AValue
);
292 if (ExGetPreviousMode() != KernelMode
)
294 RtlFreeUnicodeString(&WName
);
295 RtlFreeUnicodeString(&WValue
);
300 return(STATUS_UNSUCCESSFUL
);
302 return(STATUS_SUCCESS
);
306 /* --- Query/Set System Information --- */
309 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
310 * so the stack is popped only in one place on x86 platform.
312 #define QSI_USE(n) QSI##n
314 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
316 #define SSI_USE(n) SSI##n
318 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
321 /* Class 0 - Basic Information */
322 QSI_DEF(SystemBasicInformation
)
324 PSYSTEM_BASIC_INFORMATION Sbi
325 = (PSYSTEM_BASIC_INFORMATION
) Buffer
;
327 *ReqSize
= sizeof (SYSTEM_BASIC_INFORMATION
);
329 * Check user buffer's size
331 if (Size
< sizeof (SYSTEM_BASIC_INFORMATION
))
333 return (STATUS_INFO_LENGTH_MISMATCH
);
336 Sbi
->MaximumIncrement
= 100000; /* FIXME */
337 Sbi
->PhysicalPageSize
= PAGE_SIZE
; /* FIXME: it should be PAGE_SIZE */
338 Sbi
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
339 Sbi
->LowestPhysicalPage
= 0; /* FIXME */
340 Sbi
->HighestPhysicalPage
= MmStats
.NrTotalPages
; /* FIXME */
341 Sbi
->AllocationGranularity
= MM_VIRTMEM_GRANULARITY
; /* hard coded on Intel? */
342 Sbi
->LowestUserAddress
= 0x10000; /* Top of 64k */
343 Sbi
->HighestUserAddress
= (ULONG_PTR
)MmHighestUserAddress
;
344 Sbi
->ActiveProcessors
= 0x00000001; /* FIXME */
345 Sbi
->NumberProcessors
= KeNumberProcessors
;
346 return (STATUS_SUCCESS
);
349 /* Class 1 - Processor Information */
350 QSI_DEF(SystemProcessorInformation
)
352 PSYSTEM_PROCESSOR_INFORMATION Spi
353 = (PSYSTEM_PROCESSOR_INFORMATION
) Buffer
;
355 *ReqSize
= sizeof (SYSTEM_PROCESSOR_INFORMATION
);
357 * Check user buffer's size
359 if (Size
< sizeof (SYSTEM_PROCESSOR_INFORMATION
))
361 return (STATUS_INFO_LENGTH_MISMATCH
);
363 Spi
->ProcessorArchitecture
= 0; /* Intel Processor */
364 Spi
->ProcessorLevel
= ((Ke386Cpuid
>> 8) & 0xf);
365 Spi
->ProcessorRevision
= (Ke386Cpuid
& 0xf) | ((Ke386Cpuid
<< 4) & 0xf00);
367 Spi
->FeatureBits
= Ke386CpuidFlags
;
369 DPRINT("Arch %d Level %d Rev 0x%x\n", Spi
->ProcessorArchitecture
,
370 Spi
->ProcessorLevel
, Spi
->ProcessorRevision
);
372 return (STATUS_SUCCESS
);
375 /* Class 2 - Performance Information */
376 QSI_DEF(SystemPerformanceInformation
)
378 PSYSTEM_PERFORMANCE_INFORMATION Spi
379 = (PSYSTEM_PERFORMANCE_INFORMATION
) Buffer
;
381 PEPROCESS TheIdleProcess
;
383 *ReqSize
= sizeof (SYSTEM_PERFORMANCE_INFORMATION
);
385 * Check user buffer's size
387 if (Size
< sizeof (SYSTEM_PERFORMANCE_INFORMATION
))
389 return (STATUS_INFO_LENGTH_MISMATCH
);
392 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
394 Spi
->IdleTime
.QuadPart
= TheIdleProcess
->Pcb
.KernelTime
* 100000LL;
396 Spi
->ReadTransferCount
.QuadPart
= IoReadTransferCount
;
397 Spi
->WriteTransferCount
.QuadPart
= IoWriteTransferCount
;
398 Spi
->OtherTransferCount
.QuadPart
= IoOtherTransferCount
;
399 Spi
->ReadOperationCount
= IoReadOperationCount
;
400 Spi
->WriteOperationCount
= IoWriteOperationCount
;
401 Spi
->OtherOperationCount
= IoOtherOperationCount
;
403 Spi
->AvailablePages
= MmStats
.NrFreePages
;
405 Add up all the used "Commitied" memory + pagefile.
406 Not sure this is right. 8^\
408 Spi
->TotalCommittedPages
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
+
409 MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
+
410 MiMemoryConsumers
[MC_CACHE
].PagesUsed
+
411 MiMemoryConsumers
[MC_USER
].PagesUsed
+
414 Add up the full system total + pagefile.
415 All this make Taskmgr happy but not sure it is the right numbers.
416 This too, fixes some of GlobalMemoryStatusEx numbers.
418 Spi
->TotalCommitLimit
= MmStats
.NrTotalPages
+ MiFreeSwapPages
+
421 Spi
->PeakCommitment
= 0; /* FIXME */
422 Spi
->PageFaults
= 0; /* FIXME */
423 Spi
->WriteCopyFaults
= 0; /* FIXME */
424 Spi
->TransitionFaults
= 0; /* FIXME */
425 Spi
->CacheTransitionFaults
= 0; /* FIXME */
426 Spi
->DemandZeroFaults
= 0; /* FIXME */
427 Spi
->PagesRead
= 0; /* FIXME */
428 Spi
->PageReadIos
= 0; /* FIXME */
429 Spi
->CacheReads
= 0; /* FIXME */
430 Spi
->CacheIos
= 0; /* FIXME */
431 Spi
->PagefilePagesWritten
= 0; /* FIXME */
432 Spi
->PagefilePageWriteIos
= 0; /* FIXME */
433 Spi
->MappedFilePagesWritten
= 0; /* FIXME */
434 Spi
->MappedFilePageWriteIos
= 0; /* FIXME */
436 Spi
->PagedPoolUsage
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
;
437 Spi
->PagedPoolAllocs
= 0; /* FIXME */
438 Spi
->PagedPoolFrees
= 0; /* FIXME */
439 Spi
->NonPagedPoolUsage
= MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
;
440 Spi
->NonPagedPoolAllocs
= 0; /* FIXME */
441 Spi
->NonPagedPoolFrees
= 0; /* FIXME */
443 Spi
->TotalFreeSystemPtes
= 0; /* FIXME */
445 Spi
->SystemCodePage
= MmStats
.NrSystemPages
; /* FIXME */
447 Spi
->TotalSystemDriverPages
= 0; /* FIXME */
448 Spi
->TotalSystemCodePages
= 0; /* FIXME */
449 Spi
->SmallNonPagedLookasideListAllocateHits
= 0; /* FIXME */
450 Spi
->SmallPagedLookasideListAllocateHits
= 0; /* FIXME */
451 Spi
->Reserved3
= 0; /* FIXME */
453 Spi
->MmSystemCachePage
= MiMemoryConsumers
[MC_CACHE
].PagesUsed
;
454 Spi
->PagedPoolPage
= MmPagedPoolSize
; /* FIXME */
456 Spi
->SystemDriverPage
= 0; /* FIXME */
457 Spi
->FastReadNoWait
= 0; /* FIXME */
458 Spi
->FastReadWait
= 0; /* FIXME */
459 Spi
->FastReadResourceMiss
= 0; /* FIXME */
460 Spi
->FastReadNotPossible
= 0; /* FIXME */
462 Spi
->FastMdlReadNoWait
= 0; /* FIXME */
463 Spi
->FastMdlReadWait
= 0; /* FIXME */
464 Spi
->FastMdlReadResourceMiss
= 0; /* FIXME */
465 Spi
->FastMdlReadNotPossible
= 0; /* FIXME */
467 Spi
->MapDataNoWait
= 0; /* FIXME */
468 Spi
->MapDataWait
= 0; /* FIXME */
469 Spi
->MapDataNoWaitMiss
= 0; /* FIXME */
470 Spi
->MapDataWaitMiss
= 0; /* FIXME */
472 Spi
->PinMappedDataCount
= 0; /* FIXME */
473 Spi
->PinReadNoWait
= 0; /* FIXME */
474 Spi
->PinReadWait
= 0; /* FIXME */
475 Spi
->PinReadNoWaitMiss
= 0; /* FIXME */
476 Spi
->PinReadWaitMiss
= 0; /* FIXME */
477 Spi
->CopyReadNoWait
= 0; /* FIXME */
478 Spi
->CopyReadWait
= 0; /* FIXME */
479 Spi
->CopyReadNoWaitMiss
= 0; /* FIXME */
480 Spi
->CopyReadWaitMiss
= 0; /* FIXME */
482 Spi
->MdlReadNoWait
= 0; /* FIXME */
483 Spi
->MdlReadWait
= 0; /* FIXME */
484 Spi
->MdlReadNoWaitMiss
= 0; /* FIXME */
485 Spi
->MdlReadWaitMiss
= 0; /* FIXME */
486 Spi
->ReadAheadIos
= 0; /* FIXME */
487 Spi
->LazyWriteIos
= 0; /* FIXME */
488 Spi
->LazyWritePages
= 0; /* FIXME */
489 Spi
->DataFlushes
= 0; /* FIXME */
490 Spi
->DataPages
= 0; /* FIXME */
491 Spi
->ContextSwitches
= 0; /* FIXME */
492 Spi
->FirstLevelTbFills
= 0; /* FIXME */
493 Spi
->SecondLevelTbFills
= 0; /* FIXME */
494 Spi
->SystemCalls
= 0; /* FIXME */
496 ObDereferenceObject(TheIdleProcess
);
498 return (STATUS_SUCCESS
);
501 /* Class 3 - Time Of Day Information */
502 QSI_DEF(SystemTimeOfDayInformation
)
504 LARGE_INTEGER CurrentTime
;
506 PSYSTEM_TIMEOFDAY_INFORMATION Sti
507 = (PSYSTEM_TIMEOFDAY_INFORMATION
) Buffer
;
509 *ReqSize
= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
);
511 * Check user buffer's size
513 if (Size
< sizeof (SYSTEM_TIMEOFDAY_INFORMATION
))
515 return (STATUS_INFO_LENGTH_MISMATCH
);
518 KeQuerySystemTime(&CurrentTime
);
520 Sti
->BootTime
= SystemBootTime
;
521 Sti
->CurrentTime
= CurrentTime
;
522 Sti
->TimeZoneBias
.QuadPart
= _SystemTimeZoneInfo
.Bias
;
523 Sti
->TimeZoneId
= 0; /* FIXME */
524 Sti
->Reserved
= 0; /* FIXME */
526 return (STATUS_SUCCESS
);
529 /* Class 4 - Path Information */
530 QSI_DEF(SystemPathInformation
)
532 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
533 return (STATUS_BREAKPOINT
);
536 /* Class 5 - Process Information */
537 QSI_DEF(SystemProcessInformation
)
539 ULONG ovlSize
=0, nThreads
;
543 /* scan the process list */
545 PSYSTEM_PROCESSES Spi
546 = (PSYSTEM_PROCESSES
) Buffer
;
548 *ReqSize
= sizeof(SYSTEM_PROCESSES
);
550 if (Size
< sizeof(SYSTEM_PROCESSES
))
552 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
555 syspr
= PsGetNextProcess(NULL
);
557 pCur
= (unsigned char *)Spi
;
561 PSYSTEM_PROCESSES SpiCur
;
564 int inLen
=32; // image name len in bytes
565 PLIST_ENTRY current_entry
;
568 SpiCur
= (PSYSTEM_PROCESSES
)pCur
;
570 nThreads
= PsEnumThreadsByProcess(pr
);
572 // size of the structure for every process
573 curSize
= sizeof(SYSTEM_PROCESSES
)-sizeof(SYSTEM_THREADS
)+sizeof(SYSTEM_THREADS
)*nThreads
;
574 ovlSize
+= curSize
+inLen
;
579 ObDereferenceObject(pr
);
581 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
584 // fill system information
585 SpiCur
->NextEntryDelta
= curSize
+inLen
; // relative offset to the beginnnig of the next structure
586 SpiCur
->ThreadCount
= nThreads
;
587 SpiCur
->CreateTime
= pr
->CreateTime
;
588 SpiCur
->UserTime
.QuadPart
= pr
->Pcb
.UserTime
* 100000LL;
589 SpiCur
->KernelTime
.QuadPart
= pr
->Pcb
.KernelTime
* 100000LL;
590 SpiCur
->ProcessName
.Length
= strlen(pr
->ImageFileName
) * sizeof(WCHAR
);
591 SpiCur
->ProcessName
.MaximumLength
= inLen
;
592 SpiCur
->ProcessName
.Buffer
= (void*)(pCur
+curSize
);
594 // copy name to the end of the struct
595 RtlInitAnsiString(&imgName
, pr
->ImageFileName
);
596 RtlAnsiStringToUnicodeString(&SpiCur
->ProcessName
, &imgName
, FALSE
);
598 SpiCur
->BasePriority
= pr
->Pcb
.BasePriority
;
599 SpiCur
->ProcessId
= pr
->UniqueProcessId
;
600 SpiCur
->InheritedFromProcessId
= (DWORD
)(pr
->InheritedFromUniqueProcessId
);
601 SpiCur
->HandleCount
= ObpGetHandleCountByHandleTable(&pr
->HandleTable
);
602 SpiCur
->VmCounters
.PeakVirtualSize
= pr
->PeakVirtualSize
;
603 SpiCur
->VmCounters
.VirtualSize
= pr
->VirtualSize
.QuadPart
;
604 SpiCur
->VmCounters
.PageFaultCount
= pr
->LastFaultCount
;
605 SpiCur
->VmCounters
.PeakWorkingSetSize
= pr
->Vm
.PeakWorkingSetSize
; // Is this right using ->Vm. here ?
606 SpiCur
->VmCounters
.WorkingSetSize
= pr
->Vm
.WorkingSetSize
; // Is this right using ->Vm. here ?
607 SpiCur
->VmCounters
.QuotaPeakPagedPoolUsage
=
608 pr
->QuotaPeakPoolUsage
[0];
609 SpiCur
->VmCounters
.QuotaPagedPoolUsage
=
610 pr
->QuotaPoolUsage
[0];
611 SpiCur
->VmCounters
.QuotaPeakNonPagedPoolUsage
=
612 pr
->QuotaPeakPoolUsage
[1];
613 SpiCur
->VmCounters
.QuotaNonPagedPoolUsage
=
614 pr
->QuotaPoolUsage
[1];
615 SpiCur
->VmCounters
.PagefileUsage
= pr
->PagefileUsage
; // FIXME
616 SpiCur
->VmCounters
.PeakPagefileUsage
= pr
->PeakPagefileUsage
;
617 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
618 // doesn't seem to contain any equivalent field
619 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
621 current_entry
= pr
->ThreadListHead
.Flink
;
622 while (current_entry
!= &pr
->ThreadListHead
)
624 current
= CONTAINING_RECORD(current_entry
, ETHREAD
,
627 SpiCur
->Threads
[i
].KernelTime
.QuadPart
= current
->Tcb
.KernelTime
* 100000LL;
628 SpiCur
->Threads
[i
].UserTime
.QuadPart
= current
->Tcb
.UserTime
* 100000LL;
629 // SpiCur->Threads[i].CreateTime = current->CreateTime;
630 SpiCur
->Threads
[i
].WaitTime
= current
->Tcb
.WaitTime
;
631 SpiCur
->Threads
[i
].StartAddress
= (PVOID
) current
->StartAddress
;
632 SpiCur
->Threads
[i
].ClientId
= current
->Cid
;
633 SpiCur
->Threads
[i
].Priority
= current
->Tcb
.Priority
;
634 SpiCur
->Threads
[i
].BasePriority
= current
->Tcb
.BasePriority
;
635 SpiCur
->Threads
[i
].ContextSwitchCount
= current
->Tcb
.ContextSwitches
;
636 SpiCur
->Threads
[i
].State
= current
->Tcb
.State
;
637 SpiCur
->Threads
[i
].WaitReason
= current
->Tcb
.WaitReason
;
639 current_entry
= current_entry
->Flink
;
642 pr
= PsGetNextProcess(pr
);
644 if ((pr
== syspr
) || (pr
== NULL
))
646 SpiCur
->NextEntryDelta
= 0;
650 pCur
= pCur
+ curSize
+ inLen
;
651 } while ((pr
!= syspr
) && (pr
!= NULL
));
656 ObDereferenceObject(pr
);
658 return (STATUS_SUCCESS
);
661 /* Class 6 - Call Count Information */
662 QSI_DEF(SystemCallCountInformation
)
665 return (STATUS_NOT_IMPLEMENTED
);
668 /* Class 7 - Device Information */
669 QSI_DEF(SystemDeviceInformation
)
671 PSYSTEM_DEVICE_INFORMATION Sdi
672 = (PSYSTEM_DEVICE_INFORMATION
) Buffer
;
673 PCONFIGURATION_INFORMATION ConfigInfo
;
675 *ReqSize
= sizeof (SYSTEM_DEVICE_INFORMATION
);
677 * Check user buffer's size
679 if (Size
< sizeof (SYSTEM_DEVICE_INFORMATION
))
681 return (STATUS_INFO_LENGTH_MISMATCH
);
684 ConfigInfo
= IoGetConfigurationInformation ();
686 Sdi
->NumberOfDisks
= ConfigInfo
->DiskCount
;
687 Sdi
->NumberOfFloppies
= ConfigInfo
->FloppyCount
;
688 Sdi
->NumberOfCdRoms
= ConfigInfo
->CdRomCount
;
689 Sdi
->NumberOfTapes
= ConfigInfo
->TapeCount
;
690 Sdi
->NumberOfSerialPorts
= ConfigInfo
->SerialCount
;
691 Sdi
->NumberOfParallelPorts
= ConfigInfo
->ParallelCount
;
693 return (STATUS_SUCCESS
);
696 /* Class 8 - Processor Performance Information */
697 QSI_DEF(SystemProcessorPerformanceInformation
)
699 PSYSTEM_PROCESSORTIME_INFO Spi
700 = (PSYSTEM_PROCESSORTIME_INFO
) Buffer
;
702 PEPROCESS TheIdleProcess
;
705 *ReqSize
= sizeof (SYSTEM_PROCESSORTIME_INFO
);
707 * Check user buffer's size
709 if (Size
< sizeof (SYSTEM_PROCESSORTIME_INFO
))
711 return (STATUS_INFO_LENGTH_MISMATCH
);
714 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
716 CurrentTime
.QuadPart
= KeQueryInterruptTime();
718 Spi
->TotalProcessorRunTime
.QuadPart
=
719 TheIdleProcess
->Pcb
.KernelTime
* 100000LL; // IdleTime
720 Spi
->TotalProcessorTime
.QuadPart
= KiKernelTime
* 100000LL; // KernelTime
721 Spi
->TotalProcessorUserTime
.QuadPart
= KiUserTime
* 100000LL;
722 Spi
->TotalDPCTime
.QuadPart
= KiDpcTime
* 100000LL;
723 Spi
->TotalInterruptTime
= CurrentTime
;
724 Spi
->TotalInterrupts
= CurrentTime
.QuadPart
/ 100000LL; // Interrupt Count
726 ObDereferenceObject(TheIdleProcess
);
728 return (STATUS_SUCCESS
);
731 /* Class 9 - Flags Information */
732 QSI_DEF(SystemFlagsInformation
)
734 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
736 * ReqSize
= sizeof (SYSTEM_FLAGS_INFORMATION
);
737 return (STATUS_INFO_LENGTH_MISMATCH
);
739 ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
= NtGlobalFlag
;
740 return (STATUS_SUCCESS
);
743 SSI_DEF(SystemFlagsInformation
)
745 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
747 return (STATUS_INFO_LENGTH_MISMATCH
);
749 NtGlobalFlag
= ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
;
750 return (STATUS_SUCCESS
);
753 /* Class 10 - Call Time Information */
754 QSI_DEF(SystemCallTimeInformation
)
757 return (STATUS_NOT_IMPLEMENTED
);
760 /* Class 11 - Module Information */
761 QSI_DEF(SystemModuleInformation
)
763 return LdrpQueryModuleInformation(Buffer
, Size
, ReqSize
);
766 /* Class 12 - Locks Information */
767 QSI_DEF(SystemLocksInformation
)
770 return (STATUS_NOT_IMPLEMENTED
);
773 /* Class 13 - Stack Trace Information */
774 QSI_DEF(SystemStackTraceInformation
)
777 return (STATUS_NOT_IMPLEMENTED
);
780 /* Class 14 - Paged Pool Information */
781 QSI_DEF(SystemPagedPoolInformation
)
784 return (STATUS_NOT_IMPLEMENTED
);
787 /* Class 15 - Non Paged Pool Information */
788 QSI_DEF(SystemNonPagedPoolInformation
)
791 return (STATUS_NOT_IMPLEMENTED
);
794 /* Class 16 - Handle Information */
795 QSI_DEF(SystemHandleInformation
)
798 return (STATUS_NOT_IMPLEMENTED
);
801 /* Class 17 - Information */
802 QSI_DEF(SystemObjectInformation
)
805 return (STATUS_NOT_IMPLEMENTED
);
808 /* Class 18 - Information */
809 QSI_DEF(SystemPageFileInformation
)
811 SYSTEM_PAGEFILE_INFORMATION
*Spfi
= (SYSTEM_PAGEFILE_INFORMATION
*) Buffer
;
813 if (Size
< sizeof (SYSTEM_PAGEFILE_INFORMATION
))
815 * ReqSize
= sizeof (SYSTEM_PAGEFILE_INFORMATION
);
816 return (STATUS_INFO_LENGTH_MISMATCH
);
819 UNICODE_STRING FileName
; /* FIXME */
822 Spfi
->RelativeOffset
= 0;
824 Spfi
->CurrentSizePages
= MiFreeSwapPages
+ MiUsedSwapPages
;
825 Spfi
->TotalUsedPages
= MiUsedSwapPages
;
826 Spfi
->PeakUsedPages
= MiUsedSwapPages
; /* FIXME */
827 Spfi
->PagefileFileName
= FileName
;
828 return (STATUS_SUCCESS
);
831 /* Class 19 - Vdm Instemul Information */
832 QSI_DEF(SystemVdmInstemulInformation
)
835 return (STATUS_NOT_IMPLEMENTED
);
838 /* Class 20 - Vdm Bop Information */
839 QSI_DEF(SystemVdmBopInformation
)
842 return (STATUS_NOT_IMPLEMENTED
);
845 /* Class 21 - File Cache Information */
846 QSI_DEF(SystemFileCacheInformation
)
848 SYSTEM_CACHE_INFORMATION
*Sci
= (SYSTEM_CACHE_INFORMATION
*) Buffer
;
850 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
852 * ReqSize
= sizeof (SYSTEM_CACHE_INFORMATION
);
853 return (STATUS_INFO_LENGTH_MISMATCH
);
855 /* Return the Byte size not the page size. */
857 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
;
859 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
; /* FIXME */
861 Sci
->PageFaultCount
= 0; /* FIXME */
862 Sci
->MinimumWorkingSet
= 0; /* FIXME */
863 Sci
->MaximumWorkingSet
= 0; /* FIXME */
864 Sci
->TransitionSharedPages
= 0; /* FIXME */
865 Sci
->TransitionSharedPagesPeak
= 0; /* FIXME */
867 return (STATUS_SUCCESS
);
870 SSI_DEF(SystemFileCacheInformation
)
872 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
874 return (STATUS_INFO_LENGTH_MISMATCH
);
877 return (STATUS_NOT_IMPLEMENTED
);
880 /* Class 22 - Pool Tag Information */
881 QSI_DEF(SystemPoolTagInformation
)
884 return (STATUS_NOT_IMPLEMENTED
);
887 /* Class 23 - Interrupt Information */
888 QSI_DEF(SystemInterruptInformation
)
891 return (STATUS_NOT_IMPLEMENTED
);
894 /* Class 24 - DPC Behaviour Information */
895 QSI_DEF(SystemDpcBehaviourInformation
)
898 return (STATUS_NOT_IMPLEMENTED
);
901 SSI_DEF(SystemDpcBehaviourInformation
)
904 return (STATUS_NOT_IMPLEMENTED
);
907 /* Class 25 - Full Memory Information */
908 QSI_DEF(SystemFullMemoryInformation
)
910 PULONG Spi
= (PULONG
) Buffer
;
912 PEPROCESS TheIdleProcess
;
914 * ReqSize
= sizeof (ULONG
);
916 if (sizeof (ULONG
) != Size
)
918 return (STATUS_INFO_LENGTH_MISMATCH
);
920 DPRINT1("SystemFullMemoryInformation\n");
922 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
924 DbgPrint("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
925 TheIdleProcess
->UniqueProcessId
,
926 TheIdleProcess
->Pcb
.KernelTime
,
930 MmPrintMemoryStatistic();
932 *Spi
= MiMemoryConsumers
[MC_USER
].PagesUsed
;
934 ObDereferenceObject(TheIdleProcess
);
936 return (STATUS_SUCCESS
);
939 /* Class 26 - Load Image */
940 SSI_DEF(SystemLoadImage
)
942 PSYSTEM_LOAD_IMAGE Sli
= (PSYSTEM_LOAD_IMAGE
)Buffer
;
944 if (sizeof(SYSTEM_LOAD_IMAGE
) != Size
)
946 return(STATUS_INFO_LENGTH_MISMATCH
);
949 return(LdrpLoadImage(&Sli
->ModuleName
,
951 &Sli
->SectionPointer
,
953 &Sli
->ExportDirectory
));
956 /* Class 27 - Unload Image */
957 SSI_DEF(SystemUnloadImage
)
959 PSYSTEM_UNLOAD_IMAGE Sui
= (PSYSTEM_UNLOAD_IMAGE
)Buffer
;
961 if (sizeof(SYSTEM_UNLOAD_IMAGE
) != Size
)
963 return(STATUS_INFO_LENGTH_MISMATCH
);
966 return(LdrpUnloadImage(Sui
->ModuleBase
));
969 /* Class 28 - Time Adjustment Information */
970 QSI_DEF(SystemTimeAdjustmentInformation
)
972 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
974 * ReqSize
= sizeof (SYSTEM_SET_TIME_ADJUSTMENT
);
975 return (STATUS_INFO_LENGTH_MISMATCH
);
978 return (STATUS_NOT_IMPLEMENTED
);
981 SSI_DEF(SystemTimeAdjustmentInformation
)
983 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
985 return (STATUS_INFO_LENGTH_MISMATCH
);
988 return (STATUS_NOT_IMPLEMENTED
);
991 /* Class 29 - Summary Memory Information */
992 QSI_DEF(SystemSummaryMemoryInformation
)
995 return (STATUS_NOT_IMPLEMENTED
);
998 /* Class 30 - Next Event Id Information */
999 QSI_DEF(SystemNextEventIdInformation
)
1002 return (STATUS_NOT_IMPLEMENTED
);
1005 /* Class 31 - Event Ids Information */
1006 QSI_DEF(SystemEventIdsInformation
)
1009 return (STATUS_NOT_IMPLEMENTED
);
1012 /* Class 32 - Crach Dump Information */
1013 QSI_DEF(SystemCrashDumpInformation
)
1016 return (STATUS_NOT_IMPLEMENTED
);
1019 /* Class 33 - Exception Information */
1020 QSI_DEF(SystemExceptionInformation
)
1023 return (STATUS_NOT_IMPLEMENTED
);
1026 /* Class 34 - Crach Dump State Information */
1027 QSI_DEF(SystemCrashDumpStateInformation
)
1030 return (STATUS_NOT_IMPLEMENTED
);
1033 /* Class 35 - Kernel Debugger Information */
1034 QSI_DEF(SystemKernelDebuggerInformation
)
1037 return (STATUS_NOT_IMPLEMENTED
);
1040 /* Class 36 - Context Switch Information */
1041 QSI_DEF(SystemContextSwitchInformation
)
1044 return (STATUS_NOT_IMPLEMENTED
);
1047 /* Class 37 - Registry Quota Information */
1048 QSI_DEF(SystemRegistryQuotaInformation
)
1051 return (STATUS_NOT_IMPLEMENTED
);
1054 SSI_DEF(SystemRegistryQuotaInformation
)
1057 return (STATUS_NOT_IMPLEMENTED
);
1060 /* Class 38 - Load And Call Image */
1061 SSI_DEF(SystemLoadAndCallImage
)
1063 PSYSTEM_LOAD_AND_CALL_IMAGE Slci
= (PSYSTEM_LOAD_AND_CALL_IMAGE
)Buffer
;
1065 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE
) != Size
)
1067 return(STATUS_INFO_LENGTH_MISMATCH
);
1070 return(LdrpLoadAndCallImage(&Slci
->ModuleName
));
1073 /* Class 39 - Priority Seperation */
1074 SSI_DEF(SystemPrioritySeperation
)
1077 return (STATUS_NOT_IMPLEMENTED
);
1080 /* Class 40 - Plug Play Bus Information */
1081 QSI_DEF(SystemPlugPlayBusInformation
)
1084 return (STATUS_NOT_IMPLEMENTED
);
1087 /* Class 41 - Dock Information */
1088 QSI_DEF(SystemDockInformation
)
1091 return (STATUS_NOT_IMPLEMENTED
);
1094 /* Class 42 - Power Information */
1095 QSI_DEF(SystemPowerInformation
)
1098 return (STATUS_NOT_IMPLEMENTED
);
1101 /* Class 43 - Processor Speed Information */
1102 QSI_DEF(SystemProcessorSpeedInformation
)
1105 return (STATUS_NOT_IMPLEMENTED
);
1108 /* Class 44 - Current Time Zone Information */
1109 QSI_DEF(SystemCurrentTimeZoneInformation
)
1111 * ReqSize
= sizeof (TIME_ZONE_INFORMATION
);
1113 if (sizeof (TIME_ZONE_INFORMATION
) != Size
)
1115 return (STATUS_INFO_LENGTH_MISMATCH
);
1117 /* Copy the time zone information struct */
1120 & _SystemTimeZoneInfo
,
1121 sizeof (TIME_ZONE_INFORMATION
)
1124 return (STATUS_SUCCESS
);
1128 SSI_DEF(SystemCurrentTimeZoneInformation
)
1131 * Check user buffer's size
1133 if (Size
< sizeof (TIME_ZONE_INFORMATION
))
1135 return (STATUS_INFO_LENGTH_MISMATCH
);
1137 /* Copy the time zone information struct */
1139 & _SystemTimeZoneInfo
,
1140 (TIME_ZONE_INFORMATION
*) Buffer
,
1141 sizeof (TIME_ZONE_INFORMATION
)
1143 return (STATUS_SUCCESS
);
1147 /* Class 45 - Lookaside Information */
1148 QSI_DEF(SystemLookasideInformation
)
1151 return (STATUS_NOT_IMPLEMENTED
);
1155 /* Class 46 - Set time slip event */
1156 SSI_DEF(SystemSetTimeSlipEvent
)
1159 return (STATUS_NOT_IMPLEMENTED
);
1163 /* Class 47 - Create a new session (TSE) */
1164 SSI_DEF(SystemCreateSession
)
1167 return (STATUS_NOT_IMPLEMENTED
);
1171 /* Class 48 - Delete an existing session (TSE) */
1172 SSI_DEF(SystemDeleteSession
)
1175 return (STATUS_NOT_IMPLEMENTED
);
1179 /* Class 49 - UNKNOWN */
1180 QSI_DEF(SystemInvalidInfoClass4
)
1183 return (STATUS_NOT_IMPLEMENTED
);
1187 /* Class 50 - System range start address */
1188 QSI_DEF(SystemRangeStartInformation
)
1191 return (STATUS_NOT_IMPLEMENTED
);
1195 /* Class 51 - Driver verifier information */
1196 QSI_DEF(SystemVerifierInformation
)
1199 return (STATUS_NOT_IMPLEMENTED
);
1203 SSI_DEF(SystemVerifierInformation
)
1206 return (STATUS_NOT_IMPLEMENTED
);
1210 /* Class 52 - Add a driver verifier */
1211 SSI_DEF(SystemAddVerifier
)
1214 return (STATUS_NOT_IMPLEMENTED
);
1218 /* Class 53 - A session's processes */
1219 QSI_DEF(SystemSessionProcessesInformation
)
1222 return (STATUS_NOT_IMPLEMENTED
);
1226 /* Query/Set Calls Table */
1230 NTSTATUS (* Query
) (PVOID
,ULONG
,PULONG
);
1231 NTSTATUS (* Set
) (PVOID
,ULONG
);
1238 // XX unknown behaviour
1240 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1241 #define SI_QX(n) {QSI_USE(n),NULL}
1242 #define SI_XS(n) {NULL,SSI_USE(n)}
1243 #define SI_XX(n) {NULL,NULL}
1249 SI_QX(SystemBasicInformation
),
1250 SI_QX(SystemProcessorInformation
),
1251 SI_QX(SystemPerformanceInformation
),
1252 SI_QX(SystemTimeOfDayInformation
),
1253 SI_QX(SystemPathInformation
), /* should be SI_XX */
1254 SI_QX(SystemProcessInformation
),
1255 SI_QX(SystemCallCountInformation
),
1256 SI_QX(SystemDeviceInformation
),
1257 SI_QX(SystemProcessorPerformanceInformation
),
1258 SI_QS(SystemFlagsInformation
),
1259 SI_QX(SystemCallTimeInformation
), /* should be SI_XX */
1260 SI_QX(SystemModuleInformation
),
1261 SI_QX(SystemLocksInformation
),
1262 SI_QX(SystemStackTraceInformation
), /* should be SI_XX */
1263 SI_QX(SystemPagedPoolInformation
), /* should be SI_XX */
1264 SI_QX(SystemNonPagedPoolInformation
), /* should be SI_XX */
1265 SI_QX(SystemHandleInformation
),
1266 SI_QX(SystemObjectInformation
),
1267 SI_QX(SystemPageFileInformation
),
1268 SI_QX(SystemVdmInstemulInformation
),
1269 SI_QX(SystemVdmBopInformation
), /* it should be SI_XX */
1270 SI_QS(SystemFileCacheInformation
),
1271 SI_QX(SystemPoolTagInformation
),
1272 SI_QX(SystemInterruptInformation
),
1273 SI_QS(SystemDpcBehaviourInformation
),
1274 SI_QX(SystemFullMemoryInformation
), /* it should be SI_XX */
1275 SI_XS(SystemLoadImage
),
1276 SI_XS(SystemUnloadImage
),
1277 SI_QS(SystemTimeAdjustmentInformation
),
1278 SI_QX(SystemSummaryMemoryInformation
), /* it should be SI_XX */
1279 SI_QX(SystemNextEventIdInformation
), /* it should be SI_XX */
1280 SI_QX(SystemEventIdsInformation
), /* it should be SI_XX */
1281 SI_QX(SystemCrashDumpInformation
),
1282 SI_QX(SystemExceptionInformation
),
1283 SI_QX(SystemCrashDumpStateInformation
),
1284 SI_QX(SystemKernelDebuggerInformation
),
1285 SI_QX(SystemContextSwitchInformation
),
1286 SI_QS(SystemRegistryQuotaInformation
),
1287 SI_XS(SystemLoadAndCallImage
),
1288 SI_XS(SystemPrioritySeperation
),
1289 SI_QX(SystemPlugPlayBusInformation
), /* it should be SI_XX */
1290 SI_QX(SystemDockInformation
), /* it should be SI_XX */
1291 SI_QX(SystemPowerInformation
), /* it should be SI_XX */
1292 SI_QX(SystemProcessorSpeedInformation
), /* it should be SI_XX */
1293 SI_QS(SystemCurrentTimeZoneInformation
), /* it should be SI_QX */
1294 SI_QX(SystemLookasideInformation
),
1295 SI_XS(SystemSetTimeSlipEvent
),
1296 SI_XS(SystemCreateSession
),
1297 SI_XS(SystemDeleteSession
),
1298 SI_QX(SystemInvalidInfoClass4
), /* it should be SI_XX */
1299 SI_QX(SystemRangeStartInformation
),
1300 SI_QS(SystemVerifierInformation
),
1301 SI_XS(SystemAddVerifier
),
1302 SI_QX(SystemSessionProcessesInformation
)
1310 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1311 OUT PVOID UnsafeSystemInformation
,
1313 OUT PULONG UnsafeResultLength
)
1316 PVOID SystemInformation
;
1320 /* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
1321 SystemInformationClass );
1323 /*if (ExGetPreviousMode() == KernelMode)
1325 SystemInformation
= UnsafeSystemInformation
;
1329 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1330 if (SystemInformation == NULL)
1332 return(STATUS_NO_MEMORY);
1336 /* Clear user buffer. */
1337 RtlZeroMemory(SystemInformation
, Length
);
1340 * Check the request is valid.
1342 if ((SystemInformationClass
>= SystemInformationClassMin
) &&
1343 (SystemInformationClass
< SystemInformationClassMax
))
1345 if (NULL
!= CallQS
[SystemInformationClass
].Query
)
1348 * Hand the request to a subhandler.
1350 FStatus
= CallQS
[SystemInformationClass
].Query(SystemInformation
,
1353 /*if (ExGetPreviousMode() != KernelMode)
1355 Status = MmCopyToCaller(UnsafeSystemInformation,
1358 ExFreePool(SystemInformation);
1359 if (!NT_SUCCESS(Status))
1364 if (UnsafeResultLength
!= NULL
)
1366 /*if (ExGetPreviousMode() == KernelMode)
1368 *UnsafeResultLength = ResultLength;
1372 Status
= MmCopyToCaller(UnsafeResultLength
,
1375 if (!NT_SUCCESS(Status
))
1384 return (STATUS_INVALID_INFO_CLASS
);
1390 NtSetSystemInformation (
1391 IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1392 IN PVOID SystemInformation
,
1393 IN ULONG SystemInformationLength
1397 * If called from user mode, check
1398 * possible unsafe arguments.
1401 if (KernelMode
!= KeGetPreviousMode())
1405 // SystemInformation,
1415 * Check the request is valid.
1417 if ( (SystemInformationClass
>= SystemInformationClassMin
)
1418 && (SystemInformationClass
< SystemInformationClassMax
)
1421 if (NULL
!= CallQS
[SystemInformationClass
].Set
)
1424 * Hand the request to a subhandler.
1426 return CallQS
[SystemInformationClass
].Set (
1428 SystemInformationLength
1432 return (STATUS_INVALID_INFO_CLASS
);
1438 NtFlushInstructionCache (
1439 IN HANDLE ProcessHandle
,
1440 IN PVOID BaseAddress
,
1441 IN UINT NumberOfBytesToFlush
1445 return(STATUS_NOT_IMPLEMENTED
);