1 /* $Id: sysinfo.c,v 1.38 2004/07/16 19:49:15 ekohl 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 *****************************************************************/
17 #define NTOS_MODE_KERNEL
19 #include <ddk/halfuncs.h>
20 #include <internal/ex.h>
21 #include <internal/io.h>
22 #include <internal/ldr.h>
23 #include <internal/safe.h>
24 #include <internal/ps.h>
25 #include <internal/mm.h>
28 #include <internal/debug.h>
30 extern ULONG NtGlobalFlag
; /* FIXME: it should go in a ddk/?.h */
31 ULONGLONG STDCALL
KeQueryInterruptTime(VOID
);
33 VOID
MmPrintMemoryStatistic(VOID
);
35 extern ULONG Ke386CpuidFlags
;
36 extern ULONG Ke386Cpuid
;
38 /* FUNCTIONS *****************************************************************/
49 PHANDLE Handle OPTIONAL
60 ExGetCurrentProcessorCounts (
73 ExGetCurrentProcessorCpuUsage (
81 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
82 OUT PVOID UnsafeValue
,
84 IN OUT PULONG UnsafeReturnLength
)
92 UNICODE_STRING WValue
;
96 * Copy the name to kernel space if necessary and convert it to ANSI.
98 if (ExGetPreviousMode() != KernelMode
)
100 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
101 if (!NT_SUCCESS(Status
))
105 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
106 if (!NT_SUCCESS(Status
))
113 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
114 if (!NT_SUCCESS(Status
))
121 * Create a temporary buffer for the value
123 Value
= ExAllocatePool(NonPagedPool
, Length
);
126 RtlFreeAnsiString(&AName
);
127 if (ExGetPreviousMode() != KernelMode
)
129 RtlFreeUnicodeString(&WName
);
131 return(STATUS_NO_MEMORY
);
135 * Get the environment variable
137 Result
= HalGetEnvironmentVariable(AName
.Buffer
, Value
, Length
);
140 RtlFreeAnsiString(&AName
);
141 if (ExGetPreviousMode() != KernelMode
)
143 RtlFreeUnicodeString(&WName
);
146 return(STATUS_UNSUCCESSFUL
);
150 * Convert the result to UNICODE.
152 RtlInitAnsiString(&AValue
, Value
);
153 Status
= RtlAnsiStringToUnicodeString(&WValue
, &AValue
, TRUE
);
154 if (!NT_SUCCESS(Status
))
156 RtlFreeAnsiString(&AName
);
157 if (ExGetPreviousMode() != KernelMode
)
159 RtlFreeUnicodeString(&WName
);
164 ReturnLength
= WValue
.Length
;
167 * Copy the result back to the caller.
169 if (ExGetPreviousMode() != KernelMode
)
171 Status
= MmCopyToCaller(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
172 if (!NT_SUCCESS(Status
))
174 RtlFreeAnsiString(&AName
);
175 if (ExGetPreviousMode() != KernelMode
)
177 RtlFreeUnicodeString(&WName
);
180 RtlFreeUnicodeString(&WValue
);
184 Status
= MmCopyToCaller(UnsafeReturnLength
, &ReturnLength
,
186 if (!NT_SUCCESS(Status
))
188 RtlFreeAnsiString(&AName
);
189 if (ExGetPreviousMode() != KernelMode
)
191 RtlFreeUnicodeString(&WName
);
194 RtlFreeUnicodeString(&WValue
);
200 memcpy(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
201 memcpy(UnsafeReturnLength
, &ReturnLength
, sizeof(ULONG
));
205 * Free temporary buffers.
207 RtlFreeAnsiString(&AName
);
208 if (ExGetPreviousMode() != KernelMode
)
210 RtlFreeUnicodeString(&WName
);
213 RtlFreeUnicodeString(&WValue
);
215 return(STATUS_SUCCESS
);
220 NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
221 IN PUNICODE_STRING UnsafeValue
)
223 UNICODE_STRING WName
;
225 UNICODE_STRING WValue
;
231 * Check for required privilege.
233 /* FIXME: Not implemented. */
236 * Copy the name to kernel space if necessary and convert it to ANSI.
238 if (ExGetPreviousMode() != KernelMode
)
240 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
241 if (!NT_SUCCESS(Status
))
245 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
246 if (!NT_SUCCESS(Status
))
253 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
254 if (!NT_SUCCESS(Status
))
261 * Copy the value to kernel space and convert to ANSI.
263 if (ExGetPreviousMode() != KernelMode
)
265 Status
= RtlCaptureUnicodeString(&WValue
, UnsafeValue
);
266 if (!NT_SUCCESS(Status
))
268 RtlFreeUnicodeString(&WName
);
269 RtlFreeAnsiString(&AName
);
272 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
273 if (!NT_SUCCESS(Status
))
275 RtlFreeUnicodeString(&WName
);
276 RtlFreeAnsiString(&AName
);
277 RtlFreeUnicodeString(&WValue
);
283 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
284 if (!NT_SUCCESS(Status
))
286 RtlFreeAnsiString(&AName
);
292 * Set the environment variable
294 Result
= HalSetEnvironmentVariable(AName
.Buffer
, AValue
.Buffer
);
297 * Free everything and return status.
299 RtlFreeAnsiString(&AName
);
300 RtlFreeAnsiString(&AValue
);
301 if (ExGetPreviousMode() != KernelMode
)
303 RtlFreeUnicodeString(&WName
);
304 RtlFreeUnicodeString(&WValue
);
309 return(STATUS_UNSUCCESSFUL
);
311 return(STATUS_SUCCESS
);
315 /* --- Query/Set System Information --- */
318 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
319 * so the stack is popped only in one place on x86 platform.
321 #define QSI_USE(n) QSI##n
323 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
325 #define SSI_USE(n) SSI##n
327 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
330 /* Class 0 - Basic Information */
331 QSI_DEF(SystemBasicInformation
)
333 PSYSTEM_BASIC_INFORMATION Sbi
334 = (PSYSTEM_BASIC_INFORMATION
) Buffer
;
336 *ReqSize
= sizeof (SYSTEM_BASIC_INFORMATION
);
338 * Check user buffer's size
340 if (Size
< sizeof (SYSTEM_BASIC_INFORMATION
))
342 return (STATUS_INFO_LENGTH_MISMATCH
);
345 Sbi
->MaximumIncrement
= 100000; /* FIXME */
346 Sbi
->PhysicalPageSize
= PAGE_SIZE
; /* FIXME: it should be PAGE_SIZE */
347 Sbi
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
348 Sbi
->LowestPhysicalPage
= 0; /* FIXME */
349 Sbi
->HighestPhysicalPage
= MmStats
.NrTotalPages
; /* FIXME */
350 Sbi
->AllocationGranularity
= 65536; /* hard coded on Intel? */
351 Sbi
->LowestUserAddress
= 0x10000; /* Top of 64k */
352 Sbi
->HighestUserAddress
= 0x7ffeffff; /* From mm/mminit.c */
353 Sbi
->ActiveProcessors
= 0x00000001; /* FIXME */
354 Sbi
->NumberProcessors
= KeNumberProcessors
;
355 return (STATUS_SUCCESS
);
358 /* Class 1 - Processor Information */
359 QSI_DEF(SystemProcessorInformation
)
361 PSYSTEM_PROCESSOR_INFORMATION Spi
362 = (PSYSTEM_PROCESSOR_INFORMATION
) Buffer
;
364 *ReqSize
= sizeof (SYSTEM_PROCESSOR_INFORMATION
);
366 * Check user buffer's size
368 if (Size
< sizeof (SYSTEM_PROCESSOR_INFORMATION
))
370 return (STATUS_INFO_LENGTH_MISMATCH
);
372 Spi
->ProcessorArchitecture
= 0; /* Intel Processor */
373 Spi
->ProcessorLevel
= ((Ke386Cpuid
>> 8) & 0xf);
374 Spi
->ProcessorRevision
= (Ke386Cpuid
& 0xf) | ((Ke386Cpuid
<< 4) & 0xf00);
376 Spi
->FeatureBits
= Ke386CpuidFlags
;
378 DPRINT("Arch %d Level %d Rev 0x%x\n", Spi
->ProcessorArchitecture
,
379 Spi
->ProcessorLevel
, Spi
->ProcessorRevision
);
381 return (STATUS_SUCCESS
);
384 /* Class 2 - Performance Information */
385 QSI_DEF(SystemPerformanceInformation
)
387 PSYSTEM_PERFORMANCE_INFORMATION Spi
388 = (PSYSTEM_PERFORMANCE_INFORMATION
) Buffer
;
390 PEPROCESS TheIdleProcess
;
392 *ReqSize
= sizeof (SYSTEM_PERFORMANCE_INFORMATION
);
394 * Check user buffer's size
396 if (Size
< sizeof (SYSTEM_PERFORMANCE_INFORMATION
))
398 return (STATUS_INFO_LENGTH_MISMATCH
);
401 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
403 Spi
->IdleTime
.QuadPart
= TheIdleProcess
->Pcb
.KernelTime
* 100000;
405 Spi
->ReadTransferCount
.QuadPart
= IoReadTransferCount
;
406 Spi
->WriteTransferCount
.QuadPart
= IoWriteTransferCount
;
407 Spi
->OtherTransferCount
.QuadPart
= IoOtherTransferCount
;
408 Spi
->ReadOperationCount
= IoReadOperationCount
;
409 Spi
->WriteOperationCount
= IoWriteOperationCount
;
410 Spi
->OtherOperationCount
= IoOtherOperationCount
;
412 Spi
->AvailablePages
= MiNrAvailablePages
;
413 Spi
->TotalCommittedPages
= MiUsedSwapPages
;
414 Spi
->TotalCommitLimit
= MiFreeSwapPages
+ MiUsedSwapPages
; /* FIXME */
416 Spi
->PeakCommitment
= 0; /* FIXME */
417 Spi
->PageFaults
= 0; /* FIXME */
418 Spi
->WriteCopyFaults
= 0; /* FIXME */
419 Spi
->TransitionFaults
= 0; /* FIXME */
420 Spi
->CacheTransitionFaults
= 0; /* FIXME */
421 Spi
->DemandZeroFaults
= 0; /* FIXME */
422 Spi
->PagesRead
= 0; /* FIXME */
423 Spi
->PageReadIos
= 0; /* FIXME */
424 Spi
->CacheReads
= 0; /* FIXME */
425 Spi
->CacheIos
= 0; /* FIXME */
426 Spi
->PagefilePagesWritten
= 0; /* FIXME */
427 Spi
->PagefilePageWriteIos
= 0; /* FIXME */
428 Spi
->MappedFilePagesWritten
= 0; /* FIXME */
429 Spi
->MappedFilePageWriteIos
= 0; /* FIXME */
431 Spi
->PagedPoolUsage
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
;
432 Spi
->PagedPoolAllocs
= 0; /* FIXME */
433 Spi
->PagedPoolFrees
= 0; /* FIXME */
434 Spi
->NonPagedPoolUsage
= MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
;
435 Spi
->NonPagedPoolAllocs
= 0; /* FIXME */
436 Spi
->NonPagedPoolFrees
= 0; /* FIXME */
438 Spi
->TotalFreeSystemPtes
= 0; /* FIXME */
440 Spi
->SystemCodePage
= MmStats
.NrSystemPages
; /* FIXME */
442 Spi
->TotalSystemDriverPages
= 0; /* FIXME */
443 Spi
->TotalSystemCodePages
= 0; /* FIXME */
444 Spi
->SmallNonPagedLookasideListAllocateHits
= 0; /* FIXME */
445 Spi
->SmallPagedLookasideListAllocateHits
= 0; /* FIXME */
446 Spi
->Reserved3
= 0; /* FIXME */
448 Spi
->MmSystemCachePage
= MiMemoryConsumers
[MC_CACHE
].PagesUsed
;
449 Spi
->PagedPoolPage
= MmPagedPoolSize
; /* FIXME */
451 Spi
->SystemDriverPage
= 0; /* FIXME */
452 Spi
->FastReadNoWait
= 0; /* FIXME */
453 Spi
->FastReadWait
= 0; /* FIXME */
454 Spi
->FastReadResourceMiss
= 0; /* FIXME */
455 Spi
->FastReadNotPossible
= 0; /* FIXME */
457 Spi
->FastMdlReadNoWait
= 0; /* FIXME */
458 Spi
->FastMdlReadWait
= 0; /* FIXME */
459 Spi
->FastMdlReadResourceMiss
= 0; /* FIXME */
460 Spi
->FastMdlReadNotPossible
= 0; /* FIXME */
462 Spi
->MapDataNoWait
= 0; /* FIXME */
463 Spi
->MapDataWait
= 0; /* FIXME */
464 Spi
->MapDataNoWaitMiss
= 0; /* FIXME */
465 Spi
->MapDataWaitMiss
= 0; /* FIXME */
467 Spi
->PinMappedDataCount
= 0; /* FIXME */
468 Spi
->PinReadNoWait
= 0; /* FIXME */
469 Spi
->PinReadWait
= 0; /* FIXME */
470 Spi
->PinReadNoWaitMiss
= 0; /* FIXME */
471 Spi
->PinReadWaitMiss
= 0; /* FIXME */
472 Spi
->CopyReadNoWait
= 0; /* FIXME */
473 Spi
->CopyReadWait
= 0; /* FIXME */
474 Spi
->CopyReadNoWaitMiss
= 0; /* FIXME */
475 Spi
->CopyReadWaitMiss
= 0; /* FIXME */
477 Spi
->MdlReadNoWait
= 0; /* FIXME */
478 Spi
->MdlReadWait
= 0; /* FIXME */
479 Spi
->MdlReadNoWaitMiss
= 0; /* FIXME */
480 Spi
->MdlReadWaitMiss
= 0; /* FIXME */
481 Spi
->ReadAheadIos
= 0; /* FIXME */
482 Spi
->LazyWriteIos
= 0; /* FIXME */
483 Spi
->LazyWritePages
= 0; /* FIXME */
484 Spi
->DataFlushes
= 0; /* FIXME */
485 Spi
->DataPages
= 0; /* FIXME */
486 Spi
->ContextSwitches
= 0; /* FIXME */
487 Spi
->FirstLevelTbFills
= 0; /* FIXME */
488 Spi
->SecondLevelTbFills
= 0; /* FIXME */
489 Spi
->SystemCalls
= 0; /* FIXME */
491 ObDereferenceObject(TheIdleProcess
);
493 return (STATUS_SUCCESS
);
496 /* Class 3 - Time Of Day Information */
497 QSI_DEF(SystemTimeOfDayInformation
)
499 LARGE_INTEGER CurrentTime
;
501 PSYSTEM_TIMEOFDAY_INFORMATION Sti
502 = (PSYSTEM_TIMEOFDAY_INFORMATION
) Buffer
;
504 *ReqSize
= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
);
506 * Check user buffer's size
508 if (Size
< sizeof (SYSTEM_TIMEOFDAY_INFORMATION
))
510 return (STATUS_INFO_LENGTH_MISMATCH
);
513 KeQuerySystemTime(&CurrentTime
);
515 Sti
->BootTime
= SystemBootTime
;
516 Sti
->CurrentTime
= CurrentTime
;
517 Sti
->TimeZoneBias
.QuadPart
= _SystemTimeZoneInfo
.Bias
;
518 Sti
->TimeZoneId
= 0; /* FIXME */
519 Sti
->Reserved
= 0; /* FIXME */
521 return (STATUS_SUCCESS
);
524 /* Class 4 - Path Information */
525 QSI_DEF(SystemPathInformation
)
527 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
528 return (STATUS_BREAKPOINT
);
531 /* Class 5 - Process Information */
532 QSI_DEF(SystemProcessInformation
)
534 ULONG ovlSize
=0, nThreads
=1;
538 /* scan the process list */
539 // TODO: Add thread information
541 PSYSTEM_PROCESSES Spi
542 = (PSYSTEM_PROCESSES
) Buffer
;
544 *ReqSize
= sizeof(SYSTEM_PROCESSES
);
546 if (Size
< sizeof(SYSTEM_PROCESSES
))
548 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
551 syspr
= PsGetNextProcess(NULL
);
553 pCur
= (unsigned char *)Spi
;
557 PSYSTEM_PROCESSES SpiCur
;
560 int inLen
=32; // image name len in bytes
563 SpiCur
= (PSYSTEM_PROCESSES
)pCur
;
565 nThreads
= 1; // FIXME
567 // size of the structure for every process
568 curSize
= sizeof(SYSTEM_PROCESSES
)-sizeof(SYSTEM_THREADS
)+sizeof(SYSTEM_THREADS
)*nThreads
;
569 ovlSize
+= curSize
+inLen
;
574 ObDereferenceObject(pr
);
576 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
579 // fill system information
580 SpiCur
->NextEntryDelta
= curSize
+inLen
; // relative offset to the beginnnig of the next structure
581 SpiCur
->ThreadCount
= nThreads
;
582 SpiCur
->CreateTime
= pr
->CreateTime
;
583 SpiCur
->UserTime
.QuadPart
= pr
->Pcb
.UserTime
* 100000;
584 SpiCur
->KernelTime
.QuadPart
= pr
->Pcb
.KernelTime
* 100000;
585 SpiCur
->ProcessName
.Length
= strlen(pr
->ImageFileName
) * sizeof(WCHAR
);
586 SpiCur
->ProcessName
.MaximumLength
= inLen
;
587 SpiCur
->ProcessName
.Buffer
= (void*)(pCur
+curSize
);
589 // copy name to the end of the struct
590 RtlInitAnsiString(&imgName
, pr
->ImageFileName
);
591 RtlAnsiStringToUnicodeString(&SpiCur
->ProcessName
, &imgName
, FALSE
);
593 SpiCur
->BasePriority
= pr
->Pcb
.BasePriority
;
594 SpiCur
->ProcessId
= pr
->UniqueProcessId
;
595 SpiCur
->InheritedFromProcessId
= (DWORD
)(pr
->InheritedFromUniqueProcessId
);
596 SpiCur
->HandleCount
= ObpGetHandleCountByHandleTable(&pr
->HandleTable
);
597 SpiCur
->VmCounters
.PeakVirtualSize
= pr
->PeakVirtualSize
;
598 SpiCur
->VmCounters
.VirtualSize
= pr
->VirtualSize
.QuadPart
;
599 SpiCur
->VmCounters
.PageFaultCount
= pr
->LastFaultCount
;
600 SpiCur
->VmCounters
.PeakWorkingSetSize
= pr
->Vm
.PeakWorkingSetSize
; // Is this right using ->Vm. here ?
601 SpiCur
->VmCounters
.WorkingSetSize
= pr
->Vm
.WorkingSetSize
; // Is this right using ->Vm. here ?
602 SpiCur
->VmCounters
.QuotaPeakPagedPoolUsage
=
603 pr
->QuotaPeakPoolUsage
[0];
604 SpiCur
->VmCounters
.QuotaPagedPoolUsage
=
605 pr
->QuotaPoolUsage
[0];
606 SpiCur
->VmCounters
.QuotaPeakNonPagedPoolUsage
=
607 pr
->QuotaPeakPoolUsage
[1];
608 SpiCur
->VmCounters
.QuotaNonPagedPoolUsage
=
609 pr
->QuotaPoolUsage
[1];
610 SpiCur
->VmCounters
.PagefileUsage
= pr
->PagefileUsage
; // FIXME
611 SpiCur
->VmCounters
.PeakPagefileUsage
= pr
->PeakPagefileUsage
;
612 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
613 // doesn't seem to contain any equivalent field
614 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
616 pr
= PsGetNextProcess(pr
);
618 if ((pr
== syspr
) || (pr
== NULL
))
620 SpiCur
->NextEntryDelta
= 0;
624 pCur
= pCur
+ curSize
+ inLen
;
625 } while ((pr
!= syspr
) && (pr
!= NULL
));
630 ObDereferenceObject(pr
);
632 return (STATUS_SUCCESS
);
635 /* Class 6 - Call Count Information */
636 QSI_DEF(SystemCallCountInformation
)
639 return (STATUS_NOT_IMPLEMENTED
);
642 /* Class 7 - Device Information */
643 QSI_DEF(SystemDeviceInformation
)
645 PSYSTEM_DEVICE_INFORMATION Sdi
646 = (PSYSTEM_DEVICE_INFORMATION
) Buffer
;
647 PCONFIGURATION_INFORMATION ConfigInfo
;
649 *ReqSize
= sizeof (SYSTEM_DEVICE_INFORMATION
);
651 * Check user buffer's size
653 if (Size
< sizeof (SYSTEM_DEVICE_INFORMATION
))
655 return (STATUS_INFO_LENGTH_MISMATCH
);
658 ConfigInfo
= IoGetConfigurationInformation ();
660 Sdi
->NumberOfDisks
= ConfigInfo
->DiskCount
;
661 Sdi
->NumberOfFloppies
= ConfigInfo
->FloppyCount
;
662 Sdi
->NumberOfCdRoms
= ConfigInfo
->CdRomCount
;
663 Sdi
->NumberOfTapes
= ConfigInfo
->TapeCount
;
664 Sdi
->NumberOfSerialPorts
= ConfigInfo
->SerialCount
;
665 Sdi
->NumberOfParallelPorts
= ConfigInfo
->ParallelCount
;
667 return (STATUS_SUCCESS
);
670 /* Class 8 - Processor Performance Information */
671 QSI_DEF(SystemProcessorPerformanceInformation
)
673 PSYSTEM_PROCESSORTIME_INFO Spi
674 = (PSYSTEM_PROCESSORTIME_INFO
) Buffer
;
676 PEPROCESS TheIdleProcess
;
679 *ReqSize
= sizeof (SYSTEM_PROCESSORTIME_INFO
);
681 * Check user buffer's size
683 if (Size
< sizeof (SYSTEM_PROCESSORTIME_INFO
))
685 return (STATUS_INFO_LENGTH_MISMATCH
);
688 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
690 CurrentTime
.QuadPart
= KeQueryInterruptTime();
692 Spi
->TotalProcessorRunTime
.QuadPart
=
693 TheIdleProcess
->Pcb
.KernelTime
* 100000; // IdleTime
694 Spi
->TotalProcessorTime
.QuadPart
= KiKernelTime
* 100000; // KernelTime
695 Spi
->TotalProcessorUserTime
.QuadPart
= KiUserTime
* 100000;
696 Spi
->TotalDPCTime
.QuadPart
= KiDpcTime
* 100000;
697 Spi
->TotalInterruptTime
= CurrentTime
;
698 Spi
->TotalInterrupts
= CurrentTime
.QuadPart
/ 100000; // Interrupt Count
700 ObDereferenceObject(TheIdleProcess
);
702 return (STATUS_SUCCESS
);
705 /* Class 9 - Flags Information */
706 QSI_DEF(SystemFlagsInformation
)
708 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
710 * ReqSize
= sizeof (SYSTEM_FLAGS_INFORMATION
);
711 return (STATUS_INFO_LENGTH_MISMATCH
);
713 ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
= NtGlobalFlag
;
714 return (STATUS_SUCCESS
);
717 SSI_DEF(SystemFlagsInformation
)
719 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
721 return (STATUS_INFO_LENGTH_MISMATCH
);
723 NtGlobalFlag
= ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
;
724 return (STATUS_SUCCESS
);
727 /* Class 10 - Call Time Information */
728 QSI_DEF(SystemCallTimeInformation
)
731 return (STATUS_NOT_IMPLEMENTED
);
734 /* Class 11 - Module Information */
735 QSI_DEF(SystemModuleInformation
)
737 return LdrpQueryModuleInformation(Buffer
, Size
, ReqSize
);
740 /* Class 12 - Locks Information */
741 QSI_DEF(SystemLocksInformation
)
744 return (STATUS_NOT_IMPLEMENTED
);
747 /* Class 13 - Stack Trace Information */
748 QSI_DEF(SystemStackTraceInformation
)
751 return (STATUS_NOT_IMPLEMENTED
);
754 /* Class 14 - Paged Pool Information */
755 QSI_DEF(SystemPagedPoolInformation
)
758 return (STATUS_NOT_IMPLEMENTED
);
761 /* Class 15 - Non Paged Pool Information */
762 QSI_DEF(SystemNonPagedPoolInformation
)
765 return (STATUS_NOT_IMPLEMENTED
);
768 /* Class 16 - Handle Information */
769 QSI_DEF(SystemHandleInformation
)
772 return (STATUS_NOT_IMPLEMENTED
);
775 /* Class 17 - Information */
776 QSI_DEF(SystemObjectInformation
)
779 return (STATUS_NOT_IMPLEMENTED
);
782 /* Class 18 - Information */
783 QSI_DEF(SystemPageFileInformation
)
786 return (STATUS_NOT_IMPLEMENTED
);
789 /* Class 19 - Vdm Instemul Information */
790 QSI_DEF(SystemVdmInstemulInformation
)
793 return (STATUS_NOT_IMPLEMENTED
);
796 /* Class 20 - Vdm Bop Information */
797 QSI_DEF(SystemVdmBopInformation
)
800 return (STATUS_NOT_IMPLEMENTED
);
803 /* Class 21 - File Cache Information */
804 QSI_DEF(SystemFileCacheInformation
)
806 SYSTEM_CACHE_INFORMATION
*Sci
= (SYSTEM_CACHE_INFORMATION
*) Buffer
;
808 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
810 * ReqSize
= sizeof (SYSTEM_CACHE_INFORMATION
);
811 return (STATUS_INFO_LENGTH_MISMATCH
);
814 Sci
->CurrentSize
= 0; /* FIXME */
815 Sci
->PeakSize
= 0; /* FIXME */
816 Sci
->PageFaultCount
= 0; /* FIXME */
817 Sci
->MinimumWorkingSet
= 0; /* FIXME */
818 Sci
->MaximumWorkingSet
= 0; /* FIXME */
819 Sci
->TransitionSharedPages
= 0; /* FIXME */
820 Sci
->TransitionSharedPagesPeak
= 0; /* FIXME */
822 return (STATUS_SUCCESS
);
825 SSI_DEF(SystemFileCacheInformation
)
827 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
829 return (STATUS_INFO_LENGTH_MISMATCH
);
832 return (STATUS_NOT_IMPLEMENTED
);
835 /* Class 22 - Pool Tag Information */
836 QSI_DEF(SystemPoolTagInformation
)
839 return (STATUS_NOT_IMPLEMENTED
);
842 /* Class 23 - Interrupt Information */
843 QSI_DEF(SystemInterruptInformation
)
846 return (STATUS_NOT_IMPLEMENTED
);
849 /* Class 24 - DPC Behaviour Information */
850 QSI_DEF(SystemDpcBehaviourInformation
)
853 return (STATUS_NOT_IMPLEMENTED
);
856 SSI_DEF(SystemDpcBehaviourInformation
)
859 return (STATUS_NOT_IMPLEMENTED
);
862 /* Class 25 - Full Memory Information */
863 QSI_DEF(SystemFullMemoryInformation
)
865 PULONG Spi
= (PULONG
) Buffer
;
867 PEPROCESS TheIdleProcess
;
869 * ReqSize
= sizeof (ULONG
);
871 if (sizeof (ULONG
) != Size
)
873 return (STATUS_INFO_LENGTH_MISMATCH
);
875 DPRINT1("SystemFullMemoryInformation\n");
877 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
879 DbgPrint("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
880 TheIdleProcess
->UniqueProcessId
,
881 TheIdleProcess
->Pcb
.KernelTime
,
885 MmPrintMemoryStatistic();
887 *Spi
= MiMemoryConsumers
[MC_USER
].PagesUsed
;
889 ObDereferenceObject(TheIdleProcess
);
891 return (STATUS_SUCCESS
);
894 /* Class 26 - Load Image */
895 SSI_DEF(SystemLoadImage
)
897 PSYSTEM_LOAD_IMAGE Sli
= (PSYSTEM_LOAD_IMAGE
)Buffer
;
899 if (sizeof(SYSTEM_LOAD_IMAGE
) != Size
)
901 return(STATUS_INFO_LENGTH_MISMATCH
);
904 return(LdrpLoadImage(&Sli
->ModuleName
,
906 &Sli
->SectionPointer
,
908 &Sli
->ExportDirectory
));
911 /* Class 27 - Unload Image */
912 SSI_DEF(SystemUnloadImage
)
914 PSYSTEM_UNLOAD_IMAGE Sui
= (PSYSTEM_UNLOAD_IMAGE
)Buffer
;
916 if (sizeof(SYSTEM_UNLOAD_IMAGE
) != Size
)
918 return(STATUS_INFO_LENGTH_MISMATCH
);
921 return(LdrpUnloadImage(Sui
->ModuleBase
));
924 /* Class 28 - Time Adjustment Information */
925 QSI_DEF(SystemTimeAdjustmentInformation
)
927 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
929 * ReqSize
= sizeof (SYSTEM_SET_TIME_ADJUSTMENT
);
930 return (STATUS_INFO_LENGTH_MISMATCH
);
933 return (STATUS_NOT_IMPLEMENTED
);
936 SSI_DEF(SystemTimeAdjustmentInformation
)
938 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
940 return (STATUS_INFO_LENGTH_MISMATCH
);
943 return (STATUS_NOT_IMPLEMENTED
);
946 /* Class 29 - Summary Memory Information */
947 QSI_DEF(SystemSummaryMemoryInformation
)
950 return (STATUS_NOT_IMPLEMENTED
);
953 /* Class 30 - Next Event Id Information */
954 QSI_DEF(SystemNextEventIdInformation
)
957 return (STATUS_NOT_IMPLEMENTED
);
960 /* Class 31 - Event Ids Information */
961 QSI_DEF(SystemEventIdsInformation
)
964 return (STATUS_NOT_IMPLEMENTED
);
967 /* Class 32 - Crach Dump Information */
968 QSI_DEF(SystemCrashDumpInformation
)
971 return (STATUS_NOT_IMPLEMENTED
);
974 /* Class 33 - Exception Information */
975 QSI_DEF(SystemExceptionInformation
)
978 return (STATUS_NOT_IMPLEMENTED
);
981 /* Class 34 - Crach Dump State Information */
982 QSI_DEF(SystemCrashDumpStateInformation
)
985 return (STATUS_NOT_IMPLEMENTED
);
988 /* Class 35 - Kernel Debugger Information */
989 QSI_DEF(SystemKernelDebuggerInformation
)
992 return (STATUS_NOT_IMPLEMENTED
);
995 /* Class 36 - Context Switch Information */
996 QSI_DEF(SystemContextSwitchInformation
)
999 return (STATUS_NOT_IMPLEMENTED
);
1002 /* Class 37 - Registry Quota Information */
1003 QSI_DEF(SystemRegistryQuotaInformation
)
1006 return (STATUS_NOT_IMPLEMENTED
);
1009 SSI_DEF(SystemRegistryQuotaInformation
)
1012 return (STATUS_NOT_IMPLEMENTED
);
1015 /* Class 38 - Load And Call Image */
1016 SSI_DEF(SystemLoadAndCallImage
)
1018 PSYSTEM_LOAD_AND_CALL_IMAGE Slci
= (PSYSTEM_LOAD_AND_CALL_IMAGE
)Buffer
;
1020 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE
) != Size
)
1022 return(STATUS_INFO_LENGTH_MISMATCH
);
1025 return(LdrpLoadAndCallImage(&Slci
->ModuleName
));
1028 /* Class 39 - Priority Seperation */
1029 SSI_DEF(SystemPrioritySeperation
)
1032 return (STATUS_NOT_IMPLEMENTED
);
1035 /* Class 40 - Plug Play Bus Information */
1036 QSI_DEF(SystemPlugPlayBusInformation
)
1039 return (STATUS_NOT_IMPLEMENTED
);
1042 /* Class 41 - Dock Information */
1043 QSI_DEF(SystemDockInformation
)
1046 return (STATUS_NOT_IMPLEMENTED
);
1049 /* Class 42 - Power Information */
1050 QSI_DEF(SystemPowerInformation
)
1053 return (STATUS_NOT_IMPLEMENTED
);
1056 /* Class 43 - Processor Speed Information */
1057 QSI_DEF(SystemProcessorSpeedInformation
)
1060 return (STATUS_NOT_IMPLEMENTED
);
1063 /* Class 44 - Current Time Zone Information */
1064 QSI_DEF(SystemCurrentTimeZoneInformation
)
1066 * ReqSize
= sizeof (TIME_ZONE_INFORMATION
);
1068 if (sizeof (TIME_ZONE_INFORMATION
) != Size
)
1070 return (STATUS_INFO_LENGTH_MISMATCH
);
1072 /* Copy the time zone information struct */
1075 & _SystemTimeZoneInfo
,
1076 sizeof (TIME_ZONE_INFORMATION
)
1079 return (STATUS_SUCCESS
);
1083 SSI_DEF(SystemCurrentTimeZoneInformation
)
1086 * Check user buffer's size
1088 if (Size
< sizeof (TIME_ZONE_INFORMATION
))
1090 return (STATUS_INFO_LENGTH_MISMATCH
);
1092 /* Copy the time zone information struct */
1094 & _SystemTimeZoneInfo
,
1095 (TIME_ZONE_INFORMATION
*) Buffer
,
1096 sizeof (TIME_ZONE_INFORMATION
)
1098 return (STATUS_SUCCESS
);
1102 /* Class 45 - Lookaside Information */
1103 QSI_DEF(SystemLookasideInformation
)
1106 return (STATUS_NOT_IMPLEMENTED
);
1110 /* Class 46 - Set time slip event */
1111 SSI_DEF(SystemSetTimeSlipEvent
)
1114 return (STATUS_NOT_IMPLEMENTED
);
1118 /* Class 47 - Create a new session (TSE) */
1119 SSI_DEF(SystemCreateSession
)
1122 return (STATUS_NOT_IMPLEMENTED
);
1126 /* Class 48 - Delete an existing session (TSE) */
1127 SSI_DEF(SystemDeleteSession
)
1130 return (STATUS_NOT_IMPLEMENTED
);
1134 /* Class 49 - UNKNOWN */
1135 QSI_DEF(SystemInvalidInfoClass4
)
1138 return (STATUS_NOT_IMPLEMENTED
);
1142 /* Class 50 - System range start address */
1143 QSI_DEF(SystemRangeStartInformation
)
1146 return (STATUS_NOT_IMPLEMENTED
);
1150 /* Class 51 - Driver verifier information */
1151 QSI_DEF(SystemVerifierInformation
)
1154 return (STATUS_NOT_IMPLEMENTED
);
1158 SSI_DEF(SystemVerifierInformation
)
1161 return (STATUS_NOT_IMPLEMENTED
);
1165 /* Class 52 - Add a driver verifier */
1166 SSI_DEF(SystemAddVerifier
)
1169 return (STATUS_NOT_IMPLEMENTED
);
1173 /* Class 53 - A session's processes */
1174 QSI_DEF(SystemSessionProcessesInformation
)
1177 return (STATUS_NOT_IMPLEMENTED
);
1181 /* Query/Set Calls Table */
1185 NTSTATUS (* Query
) (PVOID
,ULONG
,PULONG
);
1186 NTSTATUS (* Set
) (PVOID
,ULONG
);
1193 // XX unknown behaviour
1195 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1196 #define SI_QX(n) {QSI_USE(n),NULL}
1197 #define SI_XS(n) {NULL,SSI_USE(n)}
1198 #define SI_XX(n) {NULL,NULL}
1204 SI_QX(SystemBasicInformation
),
1205 SI_QX(SystemProcessorInformation
),
1206 SI_QX(SystemPerformanceInformation
),
1207 SI_QX(SystemTimeOfDayInformation
),
1208 SI_QX(SystemPathInformation
), /* should be SI_XX */
1209 SI_QX(SystemProcessInformation
),
1210 SI_QX(SystemCallCountInformation
),
1211 SI_QX(SystemDeviceInformation
),
1212 SI_QX(SystemProcessorPerformanceInformation
),
1213 SI_QS(SystemFlagsInformation
),
1214 SI_QX(SystemCallTimeInformation
), /* should be SI_XX */
1215 SI_QX(SystemModuleInformation
),
1216 SI_QX(SystemLocksInformation
),
1217 SI_QX(SystemStackTraceInformation
), /* should be SI_XX */
1218 SI_QX(SystemPagedPoolInformation
), /* should be SI_XX */
1219 SI_QX(SystemNonPagedPoolInformation
), /* should be SI_XX */
1220 SI_QX(SystemHandleInformation
),
1221 SI_QX(SystemObjectInformation
),
1222 SI_QX(SystemPageFileInformation
),
1223 SI_QX(SystemVdmInstemulInformation
),
1224 SI_QX(SystemVdmBopInformation
), /* it should be SI_XX */
1225 SI_QS(SystemFileCacheInformation
),
1226 SI_QX(SystemPoolTagInformation
),
1227 SI_QX(SystemInterruptInformation
),
1228 SI_QS(SystemDpcBehaviourInformation
),
1229 SI_QX(SystemFullMemoryInformation
), /* it should be SI_XX */
1230 SI_XS(SystemLoadImage
),
1231 SI_XS(SystemUnloadImage
),
1232 SI_QS(SystemTimeAdjustmentInformation
),
1233 SI_QX(SystemSummaryMemoryInformation
), /* it should be SI_XX */
1234 SI_QX(SystemNextEventIdInformation
), /* it should be SI_XX */
1235 SI_QX(SystemEventIdsInformation
), /* it should be SI_XX */
1236 SI_QX(SystemCrashDumpInformation
),
1237 SI_QX(SystemExceptionInformation
),
1238 SI_QX(SystemCrashDumpStateInformation
),
1239 SI_QX(SystemKernelDebuggerInformation
),
1240 SI_QX(SystemContextSwitchInformation
),
1241 SI_QS(SystemRegistryQuotaInformation
),
1242 SI_XS(SystemLoadAndCallImage
),
1243 SI_XS(SystemPrioritySeperation
),
1244 SI_QX(SystemPlugPlayBusInformation
), /* it should be SI_XX */
1245 SI_QX(SystemDockInformation
), /* it should be SI_XX */
1246 SI_QX(SystemPowerInformation
), /* it should be SI_XX */
1247 SI_QX(SystemProcessorSpeedInformation
), /* it should be SI_XX */
1248 SI_QS(SystemCurrentTimeZoneInformation
), /* it should be SI_QX */
1249 SI_QX(SystemLookasideInformation
),
1250 SI_XS(SystemSetTimeSlipEvent
),
1251 SI_XS(SystemCreateSession
),
1252 SI_XS(SystemDeleteSession
),
1253 SI_QX(SystemInvalidInfoClass4
), /* it should be SI_XX */
1254 SI_QX(SystemRangeStartInformation
),
1255 SI_QS(SystemVerifierInformation
),
1256 SI_XS(SystemAddVerifier
),
1257 SI_QX(SystemSessionProcessesInformation
)
1265 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1266 OUT PVOID UnsafeSystemInformation
,
1268 OUT PULONG UnsafeResultLength
)
1271 PVOID SystemInformation
;
1275 /* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
1276 SystemInformationClass );
1278 /*if (ExGetPreviousMode() == KernelMode)
1280 SystemInformation
= UnsafeSystemInformation
;
1284 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1285 if (SystemInformation == NULL)
1287 return(STATUS_NO_MEMORY);
1291 /* Clear user buffer. */
1292 RtlZeroMemory(SystemInformation
, Length
);
1295 * Check the request is valid.
1297 if ((SystemInformationClass
>= SystemInformationClassMin
) &&
1298 (SystemInformationClass
< SystemInformationClassMax
))
1300 if (NULL
!= CallQS
[SystemInformationClass
].Query
)
1303 * Hand the request to a subhandler.
1305 FStatus
= CallQS
[SystemInformationClass
].Query(SystemInformation
,
1308 /*if (ExGetPreviousMode() != KernelMode)
1310 Status = MmCopyToCaller(UnsafeSystemInformation,
1313 ExFreePool(SystemInformation);
1314 if (!NT_SUCCESS(Status))
1319 if (UnsafeResultLength
!= NULL
)
1321 /*if (ExGetPreviousMode() == KernelMode)
1323 *UnsafeResultLength = ResultLength;
1327 Status
= MmCopyToCaller(UnsafeResultLength
,
1330 if (!NT_SUCCESS(Status
))
1339 return (STATUS_INVALID_INFO_CLASS
);
1345 NtSetSystemInformation (
1346 IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1347 IN PVOID SystemInformation
,
1348 IN ULONG SystemInformationLength
1352 * If called from user mode, check
1353 * possible unsafe arguments.
1356 if (KernelMode
!= KeGetPreviousMode())
1360 // SystemInformation,
1370 * Check the request is valid.
1372 if ( (SystemInformationClass
>= SystemInformationClassMin
)
1373 && (SystemInformationClass
< SystemInformationClassMax
)
1376 if (NULL
!= CallQS
[SystemInformationClass
].Set
)
1379 * Hand the request to a subhandler.
1381 return CallQS
[SystemInformationClass
].Set (
1383 SystemInformationLength
1387 return (STATUS_INVALID_INFO_CLASS
);
1393 NtFlushInstructionCache (
1394 IN HANDLE ProcessHandle
,
1395 IN PVOID BaseAddress
,
1396 IN UINT NumberOfBytesToFlush
1400 return(STATUS_NOT_IMPLEMENTED
);