1 /* $Id: sysinfo.c,v 1.35 2004/05/26 19:56:35 navaraf 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 VOID STDCALL
KeQueryInterruptTime(PLARGE_INTEGER CurrentTime
);
33 VOID
MmPrintMemoryStatistic(VOID
);
35 extern ULONG Ke386CpuidFlags
;
36 extern ULONG Ke386Cpuid
;
38 /* FUNCTIONS *****************************************************************/
41 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
42 OUT PVOID UnsafeValue
,
44 IN OUT PULONG UnsafeReturnLength
)
52 UNICODE_STRING WValue
;
56 * Copy the name to kernel space if necessary and convert it to ANSI.
58 if (ExGetPreviousMode() != KernelMode
)
60 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
61 if (!NT_SUCCESS(Status
))
65 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
66 if (!NT_SUCCESS(Status
))
73 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
74 if (!NT_SUCCESS(Status
))
81 * Create a temporary buffer for the value
83 Value
= ExAllocatePool(NonPagedPool
, Length
);
86 RtlFreeAnsiString(&AName
);
87 if (ExGetPreviousMode() != KernelMode
)
89 RtlFreeUnicodeString(&WName
);
91 return(STATUS_NO_MEMORY
);
95 * Get the environment variable
97 Result
= HalGetEnvironmentVariable(AName
.Buffer
, Value
, Length
);
100 RtlFreeAnsiString(&AName
);
101 if (ExGetPreviousMode() != KernelMode
)
103 RtlFreeUnicodeString(&WName
);
106 return(STATUS_UNSUCCESSFUL
);
110 * Convert the result to UNICODE.
112 RtlInitAnsiString(&AValue
, Value
);
113 Status
= RtlAnsiStringToUnicodeString(&WValue
, &AValue
, TRUE
);
114 if (!NT_SUCCESS(Status
))
116 RtlFreeAnsiString(&AName
);
117 if (ExGetPreviousMode() != KernelMode
)
119 RtlFreeUnicodeString(&WName
);
124 ReturnLength
= WValue
.Length
;
127 * Copy the result back to the caller.
129 if (ExGetPreviousMode() != KernelMode
)
131 Status
= MmCopyToCaller(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
132 if (!NT_SUCCESS(Status
))
134 RtlFreeAnsiString(&AName
);
135 if (ExGetPreviousMode() != KernelMode
)
137 RtlFreeUnicodeString(&WName
);
140 RtlFreeUnicodeString(&WValue
);
144 Status
= MmCopyToCaller(UnsafeReturnLength
, &ReturnLength
,
146 if (!NT_SUCCESS(Status
))
148 RtlFreeAnsiString(&AName
);
149 if (ExGetPreviousMode() != KernelMode
)
151 RtlFreeUnicodeString(&WName
);
154 RtlFreeUnicodeString(&WValue
);
160 memcpy(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
161 memcpy(UnsafeReturnLength
, &ReturnLength
, sizeof(ULONG
));
165 * Free temporary buffers.
167 RtlFreeAnsiString(&AName
);
168 if (ExGetPreviousMode() != KernelMode
)
170 RtlFreeUnicodeString(&WName
);
173 RtlFreeUnicodeString(&WValue
);
175 return(STATUS_SUCCESS
);
180 NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
181 IN PUNICODE_STRING UnsafeValue
)
183 UNICODE_STRING WName
;
185 UNICODE_STRING WValue
;
191 * Check for required privilege.
193 /* FIXME: Not implemented. */
196 * Copy the name to kernel space if necessary and convert it to ANSI.
198 if (ExGetPreviousMode() != KernelMode
)
200 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
201 if (!NT_SUCCESS(Status
))
205 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
206 if (!NT_SUCCESS(Status
))
213 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
214 if (!NT_SUCCESS(Status
))
221 * Copy the value to kernel space and convert to ANSI.
223 if (ExGetPreviousMode() != KernelMode
)
225 Status
= RtlCaptureUnicodeString(&WValue
, UnsafeValue
);
226 if (!NT_SUCCESS(Status
))
228 RtlFreeUnicodeString(&WName
);
229 RtlFreeAnsiString(&AName
);
232 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
233 if (!NT_SUCCESS(Status
))
235 RtlFreeUnicodeString(&WName
);
236 RtlFreeAnsiString(&AName
);
237 RtlFreeUnicodeString(&WValue
);
243 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
244 if (!NT_SUCCESS(Status
))
246 RtlFreeAnsiString(&AName
);
252 * Set the environment variable
254 Result
= HalSetEnvironmentVariable(AName
.Buffer
, AValue
.Buffer
);
257 * Free everything and return status.
259 RtlFreeAnsiString(&AName
);
260 RtlFreeAnsiString(&AValue
);
261 if (ExGetPreviousMode() != KernelMode
)
263 RtlFreeUnicodeString(&WName
);
264 RtlFreeUnicodeString(&WValue
);
269 return(STATUS_UNSUCCESSFUL
);
271 return(STATUS_SUCCESS
);
275 /* --- Query/Set System Information --- */
278 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
279 * so the stack is popped only in one place on x86 platform.
281 #define QSI_USE(n) QSI##n
283 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
285 #define SSI_USE(n) SSI##n
287 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
290 /* Class 0 - Basic Information */
291 QSI_DEF(SystemBasicInformation
)
293 PSYSTEM_BASIC_INFORMATION Sbi
294 = (PSYSTEM_BASIC_INFORMATION
) Buffer
;
296 *ReqSize
= sizeof (SYSTEM_BASIC_INFORMATION
);
298 * Check user buffer's size
300 if (Size
< sizeof (SYSTEM_BASIC_INFORMATION
))
302 return (STATUS_INFO_LENGTH_MISMATCH
);
305 Sbi
->MaximumIncrement
= 100000; /* FIXME */
306 Sbi
->PhysicalPageSize
= PAGE_SIZE
; /* FIXME: it should be PAGE_SIZE */
307 Sbi
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
308 Sbi
->LowestPhysicalPage
= 0; /* FIXME */
309 Sbi
->HighestPhysicalPage
= MmStats
.NrTotalPages
; /* FIXME */
310 Sbi
->AllocationGranularity
= 65536; /* hard coded on Intel? */
311 Sbi
->LowestUserAddress
= 0x10000; /* Top of 64k */
312 Sbi
->HighestUserAddress
= 0x7ffeffff; /* From mm/mminit.c */
313 Sbi
->ActiveProcessors
= 0x00000001; /* FIXME */
314 Sbi
->NumberProcessors
= KeNumberProcessors
;
315 return (STATUS_SUCCESS
);
318 /* Class 1 - Processor Information */
319 QSI_DEF(SystemProcessorInformation
)
321 PSYSTEM_PROCESSOR_INFORMATION Spi
322 = (PSYSTEM_PROCESSOR_INFORMATION
) Buffer
;
324 *ReqSize
= sizeof (SYSTEM_PROCESSOR_INFORMATION
);
326 * Check user buffer's size
328 if (Size
< sizeof (SYSTEM_PROCESSOR_INFORMATION
))
330 return (STATUS_INFO_LENGTH_MISMATCH
);
332 Spi
->ProcessorArchitecture
= 0; /* Intel Processor */
333 Spi
->ProcessorLevel
= ((Ke386Cpuid
>> 8) & 0xf);
334 Spi
->ProcessorRevision
= (Ke386Cpuid
& 0xf) | ((Ke386Cpuid
<< 4) & 0xf00);
336 Spi
->FeatureBits
= Ke386CpuidFlags
;
338 DPRINT("Arch %d Level %d Rev 0x%x\n", Spi
->ProcessorArchitecture
,
339 Spi
->ProcessorLevel
, Spi
->ProcessorRevision
);
341 return (STATUS_SUCCESS
);
344 /* Class 2 - Performance Information */
345 QSI_DEF(SystemPerformanceInformation
)
347 PSYSTEM_PERFORMANCE_INFORMATION Spi
348 = (PSYSTEM_PERFORMANCE_INFORMATION
) Buffer
;
350 PEPROCESS TheIdleProcess
;
352 *ReqSize
= sizeof (SYSTEM_PERFORMANCE_INFORMATION
);
354 * Check user buffer's size
356 if (Size
< sizeof (SYSTEM_PERFORMANCE_INFORMATION
))
358 return (STATUS_INFO_LENGTH_MISMATCH
);
361 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
363 Spi
->IdleTime
.QuadPart
= TheIdleProcess
->Pcb
.KernelTime
* 100000;
365 Spi
->ReadTransferCount
.QuadPart
= IoReadTransferCount
;
366 Spi
->WriteTransferCount
.QuadPart
= IoWriteTransferCount
;
367 Spi
->OtherTransferCount
.QuadPart
= IoOtherTransferCount
;
368 Spi
->ReadOperationCount
= IoReadOperationCount
;
369 Spi
->WriteOperationCount
= IoWriteOperationCount
;
370 Spi
->OtherOperationCount
= IoOtherOperationCount
;
372 Spi
->AvailablePages
= MiNrAvailablePages
;
373 Spi
->TotalCommittedPages
= MiUsedSwapPages
;
374 Spi
->TotalCommitLimit
= MiFreeSwapPages
+ MiUsedSwapPages
; /* FIXME */
376 Spi
->PeakCommitment
= 0; /* FIXME */
377 Spi
->PageFaults
= 0; /* FIXME */
378 Spi
->WriteCopyFaults
= 0; /* FIXME */
379 Spi
->TransitionFaults
= 0; /* FIXME */
380 Spi
->CacheTransitionFaults
= 0; /* FIXME */
381 Spi
->DemandZeroFaults
= 0; /* FIXME */
382 Spi
->PagesRead
= 0; /* FIXME */
383 Spi
->PageReadIos
= 0; /* FIXME */
384 Spi
->CacheReads
= 0; /* FIXME */
385 Spi
->CacheIos
= 0; /* FIXME */
386 Spi
->PagefilePagesWritten
= 0; /* FIXME */
387 Spi
->PagefilePageWriteIos
= 0; /* FIXME */
388 Spi
->MappedFilePagesWritten
= 0; /* FIXME */
389 Spi
->MappedFilePageWriteIos
= 0; /* FIXME */
391 Spi
->PagedPoolUsage
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
;
392 Spi
->PagedPoolAllocs
= 0; /* FIXME */
393 Spi
->PagedPoolFrees
= 0; /* FIXME */
394 Spi
->NonPagedPoolUsage
= MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
;
395 Spi
->NonPagedPoolAllocs
= 0; /* FIXME */
396 Spi
->NonPagedPoolFrees
= 0; /* FIXME */
398 Spi
->TotalFreeSystemPtes
= 0; /* FIXME */
400 Spi
->SystemCodePage
= MmStats
.NrSystemPages
; /* FIXME */
402 Spi
->TotalSystemDriverPages
= 0; /* FIXME */
403 Spi
->TotalSystemCodePages
= 0; /* FIXME */
404 Spi
->SmallNonPagedLookasideListAllocateHits
= 0; /* FIXME */
405 Spi
->SmallPagedLookasideListAllocateHits
= 0; /* FIXME */
406 Spi
->Reserved3
= 0; /* FIXME */
408 Spi
->MmSystemCachePage
= MiMemoryConsumers
[MC_CACHE
].PagesUsed
;
409 Spi
->PagedPoolPage
= MmPagedPoolSize
; /* FIXME */
411 Spi
->SystemDriverPage
= 0; /* FIXME */
412 Spi
->FastReadNoWait
= 0; /* FIXME */
413 Spi
->FastReadWait
= 0; /* FIXME */
414 Spi
->FastReadResourceMiss
= 0; /* FIXME */
415 Spi
->FastReadNotPossible
= 0; /* FIXME */
417 Spi
->FastMdlReadNoWait
= 0; /* FIXME */
418 Spi
->FastMdlReadWait
= 0; /* FIXME */
419 Spi
->FastMdlReadResourceMiss
= 0; /* FIXME */
420 Spi
->FastMdlReadNotPossible
= 0; /* FIXME */
422 Spi
->MapDataNoWait
= 0; /* FIXME */
423 Spi
->MapDataWait
= 0; /* FIXME */
424 Spi
->MapDataNoWaitMiss
= 0; /* FIXME */
425 Spi
->MapDataWaitMiss
= 0; /* FIXME */
427 Spi
->PinMappedDataCount
= 0; /* FIXME */
428 Spi
->PinReadNoWait
= 0; /* FIXME */
429 Spi
->PinReadWait
= 0; /* FIXME */
430 Spi
->PinReadNoWaitMiss
= 0; /* FIXME */
431 Spi
->PinReadWaitMiss
= 0; /* FIXME */
432 Spi
->CopyReadNoWait
= 0; /* FIXME */
433 Spi
->CopyReadWait
= 0; /* FIXME */
434 Spi
->CopyReadNoWaitMiss
= 0; /* FIXME */
435 Spi
->CopyReadWaitMiss
= 0; /* FIXME */
437 Spi
->MdlReadNoWait
= 0; /* FIXME */
438 Spi
->MdlReadWait
= 0; /* FIXME */
439 Spi
->MdlReadNoWaitMiss
= 0; /* FIXME */
440 Spi
->MdlReadWaitMiss
= 0; /* FIXME */
441 Spi
->ReadAheadIos
= 0; /* FIXME */
442 Spi
->LazyWriteIos
= 0; /* FIXME */
443 Spi
->LazyWritePages
= 0; /* FIXME */
444 Spi
->DataFlushes
= 0; /* FIXME */
445 Spi
->DataPages
= 0; /* FIXME */
446 Spi
->ContextSwitches
= 0; /* FIXME */
447 Spi
->FirstLevelTbFills
= 0; /* FIXME */
448 Spi
->SecondLevelTbFills
= 0; /* FIXME */
449 Spi
->SystemCalls
= 0; /* FIXME */
451 ObDereferenceObject(TheIdleProcess
);
453 return (STATUS_SUCCESS
);
456 /* Class 3 - Time Of Day Information */
457 QSI_DEF(SystemTimeOfDayInformation
)
459 LARGE_INTEGER CurrentTime
;
461 PSYSTEM_TIMEOFDAY_INFORMATION Sti
462 = (PSYSTEM_TIMEOFDAY_INFORMATION
) Buffer
;
464 *ReqSize
= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
);
466 * Check user buffer's size
468 if (Size
< sizeof (SYSTEM_TIMEOFDAY_INFORMATION
))
470 return (STATUS_INFO_LENGTH_MISMATCH
);
473 KeQuerySystemTime(&CurrentTime
);
475 Sti
->BootTime
= SystemBootTime
;
476 Sti
->CurrentTime
= CurrentTime
;
477 Sti
->TimeZoneBias
.QuadPart
= _SystemTimeZoneInfo
.Bias
;
478 Sti
->TimeZoneId
= 0; /* FIXME */
479 Sti
->Reserved
= 0; /* FIXME */
481 return (STATUS_SUCCESS
);
484 /* Class 4 - Path Information */
485 QSI_DEF(SystemPathInformation
)
487 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
488 return (STATUS_BREAKPOINT
);
491 /* Class 5 - Process Information */
492 QSI_DEF(SystemProcessInformation
)
494 ULONG ovlSize
=0, nThreads
=1;
498 /* scan the process list */
499 // TODO: Add thread information
501 PSYSTEM_PROCESSES Spi
502 = (PSYSTEM_PROCESSES
) Buffer
;
504 *ReqSize
= sizeof(SYSTEM_PROCESSES
);
506 if (Size
< sizeof(SYSTEM_PROCESSES
))
508 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
511 syspr
= PsGetNextProcess(NULL
);
513 pCur
= (unsigned char *)Spi
;
517 PSYSTEM_PROCESSES SpiCur
;
520 int inLen
=32; // image name len in bytes
523 SpiCur
= (PSYSTEM_PROCESSES
)pCur
;
525 nThreads
= 1; // FIXME
527 // size of the structure for every process
528 curSize
= sizeof(SYSTEM_PROCESSES
)-sizeof(SYSTEM_THREADS
)+sizeof(SYSTEM_THREADS
)*nThreads
;
529 ovlSize
+= curSize
+inLen
;
534 ObDereferenceObject(pr
);
536 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
539 // fill system information
540 SpiCur
->NextEntryDelta
= curSize
+inLen
; // relative offset to the beginnnig of the next structure
541 SpiCur
->ThreadCount
= nThreads
;
542 SpiCur
->CreateTime
= pr
->CreateTime
;
543 SpiCur
->UserTime
.QuadPart
= pr
->Pcb
.UserTime
* 100000;
544 SpiCur
->KernelTime
.QuadPart
= pr
->Pcb
.KernelTime
* 100000;
545 SpiCur
->ProcessName
.Length
= strlen(pr
->ImageFileName
) * sizeof(WCHAR
);
546 SpiCur
->ProcessName
.MaximumLength
= inLen
;
547 SpiCur
->ProcessName
.Buffer
= (void*)(pCur
+curSize
);
549 // copy name to the end of the struct
550 RtlInitAnsiString(&imgName
, pr
->ImageFileName
);
551 RtlAnsiStringToUnicodeString(&SpiCur
->ProcessName
, &imgName
, FALSE
);
553 SpiCur
->BasePriority
= pr
->Pcb
.BasePriority
;
554 SpiCur
->ProcessId
= pr
->UniqueProcessId
;
555 SpiCur
->InheritedFromProcessId
= (DWORD
)(pr
->InheritedFromUniqueProcessId
);
556 SpiCur
->HandleCount
= ObpGetHandleCountbyHandleTable(&pr
->HandleTable
);
557 SpiCur
->VmCounters
.PeakVirtualSize
= pr
->PeakVirtualSize
;
558 SpiCur
->VmCounters
.VirtualSize
= pr
->VirtualSize
.QuadPart
;
559 SpiCur
->VmCounters
.PageFaultCount
= pr
->LastFaultCount
;
560 SpiCur
->VmCounters
.PeakWorkingSetSize
= pr
->Vm
.PeakWorkingSetSize
; // Is this right using ->Vm. here ?
561 SpiCur
->VmCounters
.WorkingSetSize
= pr
->Vm
.WorkingSetSize
; // Is this right using ->Vm. here ?
562 SpiCur
->VmCounters
.QuotaPeakPagedPoolUsage
=
563 pr
->QuotaPeakPoolUsage
[0];
564 SpiCur
->VmCounters
.QuotaPagedPoolUsage
=
565 pr
->QuotaPoolUsage
[0];
566 SpiCur
->VmCounters
.QuotaPeakNonPagedPoolUsage
=
567 pr
->QuotaPeakPoolUsage
[1];
568 SpiCur
->VmCounters
.QuotaNonPagedPoolUsage
=
569 pr
->QuotaPoolUsage
[1];
570 SpiCur
->VmCounters
.PagefileUsage
= pr
->PagefileUsage
; // FIXME
571 SpiCur
->VmCounters
.PeakPagefileUsage
= pr
->PeakPagefileUsage
;
572 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
573 // doesn't seem to contain any equivalent field
574 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
576 pr
= PsGetNextProcess(pr
);
578 if ((pr
== syspr
) || (pr
== NULL
))
580 SpiCur
->NextEntryDelta
= 0;
584 pCur
= pCur
+ curSize
+ inLen
;
585 } while ((pr
!= syspr
) && (pr
!= NULL
));
590 ObDereferenceObject(pr
);
592 return (STATUS_SUCCESS
);
595 /* Class 6 - Call Count Information */
596 QSI_DEF(SystemCallCountInformation
)
599 return (STATUS_NOT_IMPLEMENTED
);
602 /* Class 7 - Device Information */
603 QSI_DEF(SystemDeviceInformation
)
605 PSYSTEM_DEVICE_INFORMATION Sdi
606 = (PSYSTEM_DEVICE_INFORMATION
) Buffer
;
607 PCONFIGURATION_INFORMATION ConfigInfo
;
609 *ReqSize
= sizeof (SYSTEM_DEVICE_INFORMATION
);
611 * Check user buffer's size
613 if (Size
< sizeof (SYSTEM_DEVICE_INFORMATION
))
615 return (STATUS_INFO_LENGTH_MISMATCH
);
618 ConfigInfo
= IoGetConfigurationInformation ();
620 Sdi
->NumberOfDisks
= ConfigInfo
->DiskCount
;
621 Sdi
->NumberOfFloppies
= ConfigInfo
->FloppyCount
;
622 Sdi
->NumberOfCdRoms
= ConfigInfo
->CdRomCount
;
623 Sdi
->NumberOfTapes
= ConfigInfo
->TapeCount
;
624 Sdi
->NumberOfSerialPorts
= ConfigInfo
->SerialCount
;
625 Sdi
->NumberOfParallelPorts
= ConfigInfo
->ParallelCount
;
627 return (STATUS_SUCCESS
);
630 /* Class 8 - Processor Performance Information */
631 QSI_DEF(SystemProcessorPerformanceInformation
)
633 PSYSTEM_PROCESSORTIME_INFO Spi
634 = (PSYSTEM_PROCESSORTIME_INFO
) Buffer
;
636 PEPROCESS TheIdleProcess
;
639 *ReqSize
= sizeof (SYSTEM_PROCESSORTIME_INFO
);
641 * Check user buffer's size
643 if (Size
< sizeof (SYSTEM_PROCESSORTIME_INFO
))
645 return (STATUS_INFO_LENGTH_MISMATCH
);
648 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
650 KeQueryInterruptTime((PLARGE_INTEGER
) &CurrentTime
);
652 Spi
->TotalProcessorRunTime
.QuadPart
=
653 TheIdleProcess
->Pcb
.KernelTime
* 100000; // IdleTime
654 Spi
->TotalProcessorTime
.QuadPart
= KiKernelTime
* 100000; // KernelTime
655 Spi
->TotalProcessorUserTime
.QuadPart
= KiUserTime
* 100000;
656 Spi
->TotalDPCTime
.QuadPart
= KiDpcTime
* 100000;
657 Spi
->TotalInterruptTime
= CurrentTime
;
658 Spi
->TotalInterrupts
= CurrentTime
.QuadPart
/ 100000; // Interrupt Count
660 ObDereferenceObject(TheIdleProcess
);
662 return (STATUS_SUCCESS
);
665 /* Class 9 - Flags Information */
666 QSI_DEF(SystemFlagsInformation
)
668 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
670 * ReqSize
= sizeof (SYSTEM_FLAGS_INFORMATION
);
671 return (STATUS_INFO_LENGTH_MISMATCH
);
673 ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
= NtGlobalFlag
;
674 return (STATUS_SUCCESS
);
677 SSI_DEF(SystemFlagsInformation
)
679 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
681 return (STATUS_INFO_LENGTH_MISMATCH
);
683 NtGlobalFlag
= ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
;
684 return (STATUS_SUCCESS
);
687 /* Class 10 - Call Time Information */
688 QSI_DEF(SystemCallTimeInformation
)
691 return (STATUS_NOT_IMPLEMENTED
);
694 /* Class 11 - Module Information */
695 QSI_DEF(SystemModuleInformation
)
697 return LdrpQueryModuleInformation(Buffer
, Size
, ReqSize
);
700 /* Class 12 - Locks Information */
701 QSI_DEF(SystemLocksInformation
)
704 return (STATUS_NOT_IMPLEMENTED
);
707 /* Class 13 - Stack Trace Information */
708 QSI_DEF(SystemStackTraceInformation
)
711 return (STATUS_NOT_IMPLEMENTED
);
714 /* Class 14 - Paged Pool Information */
715 QSI_DEF(SystemPagedPoolInformation
)
718 return (STATUS_NOT_IMPLEMENTED
);
721 /* Class 15 - Non Paged Pool Information */
722 QSI_DEF(SystemNonPagedPoolInformation
)
725 return (STATUS_NOT_IMPLEMENTED
);
728 /* Class 16 - Handle Information */
729 QSI_DEF(SystemHandleInformation
)
732 return (STATUS_NOT_IMPLEMENTED
);
735 /* Class 17 - Information */
736 QSI_DEF(SystemObjectInformation
)
739 return (STATUS_NOT_IMPLEMENTED
);
742 /* Class 18 - Information */
743 QSI_DEF(SystemPageFileInformation
)
746 return (STATUS_NOT_IMPLEMENTED
);
749 /* Class 19 - Vdm Instemul Information */
750 QSI_DEF(SystemVdmInstemulInformation
)
753 return (STATUS_NOT_IMPLEMENTED
);
756 /* Class 20 - Vdm Bop Information */
757 QSI_DEF(SystemVdmBopInformation
)
760 return (STATUS_NOT_IMPLEMENTED
);
763 /* Class 21 - File Cache Information */
764 QSI_DEF(SystemFileCacheInformation
)
766 SYSTEM_CACHE_INFORMATION
*Sci
= (SYSTEM_CACHE_INFORMATION
*) Buffer
;
768 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
770 * ReqSize
= sizeof (SYSTEM_CACHE_INFORMATION
);
771 return (STATUS_INFO_LENGTH_MISMATCH
);
774 Sci
->CurrentSize
= 0; /* FIXME */
775 Sci
->PeakSize
= 0; /* FIXME */
776 Sci
->PageFaultCount
= 0; /* FIXME */
777 Sci
->MinimumWorkingSet
= 0; /* FIXME */
778 Sci
->MaximumWorkingSet
= 0; /* FIXME */
779 Sci
->TransitionSharedPages
= 0; /* FIXME */
780 Sci
->TransitionSharedPagesPeak
= 0; /* FIXME */
782 return (STATUS_SUCCESS
);
785 SSI_DEF(SystemFileCacheInformation
)
787 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
789 return (STATUS_INFO_LENGTH_MISMATCH
);
792 return (STATUS_NOT_IMPLEMENTED
);
795 /* Class 22 - Pool Tag Information */
796 QSI_DEF(SystemPoolTagInformation
)
799 return (STATUS_NOT_IMPLEMENTED
);
802 /* Class 23 - Interrupt Information */
803 QSI_DEF(SystemInterruptInformation
)
806 return (STATUS_NOT_IMPLEMENTED
);
809 /* Class 24 - DPC Behaviour Information */
810 QSI_DEF(SystemDpcBehaviourInformation
)
813 return (STATUS_NOT_IMPLEMENTED
);
816 SSI_DEF(SystemDpcBehaviourInformation
)
819 return (STATUS_NOT_IMPLEMENTED
);
822 /* Class 25 - Full Memory Information */
823 QSI_DEF(SystemFullMemoryInformation
)
825 PULONG Spi
= (PULONG
) Buffer
;
827 PEPROCESS TheIdleProcess
;
829 * ReqSize
= sizeof (ULONG
);
831 if (sizeof (ULONG
) != Size
)
833 return (STATUS_INFO_LENGTH_MISMATCH
);
835 DPRINT1("SystemFullMemoryInformation\n");
837 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
839 DbgPrint("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
840 TheIdleProcess
->UniqueProcessId
,
841 TheIdleProcess
->Pcb
.KernelTime
,
845 MmPrintMemoryStatistic();
847 *Spi
= MiMemoryConsumers
[MC_USER
].PagesUsed
;
849 ObDereferenceObject(TheIdleProcess
);
851 return (STATUS_SUCCESS
);
854 /* Class 26 - Load Image */
855 SSI_DEF(SystemLoadImage
)
857 PSYSTEM_LOAD_IMAGE Sli
= (PSYSTEM_LOAD_IMAGE
)Buffer
;
859 if (sizeof(SYSTEM_LOAD_IMAGE
) != Size
)
861 return(STATUS_INFO_LENGTH_MISMATCH
);
864 return(LdrpLoadImage(&Sli
->ModuleName
,
866 &Sli
->SectionPointer
,
868 &Sli
->ExportDirectory
));
871 /* Class 27 - Unload Image */
872 SSI_DEF(SystemUnloadImage
)
874 PSYSTEM_UNLOAD_IMAGE Sui
= (PSYSTEM_UNLOAD_IMAGE
)Buffer
;
876 if (sizeof(SYSTEM_UNLOAD_IMAGE
) != Size
)
878 return(STATUS_INFO_LENGTH_MISMATCH
);
881 return(LdrpUnloadImage(Sui
->ModuleBase
));
884 /* Class 28 - Time Adjustment Information */
885 QSI_DEF(SystemTimeAdjustmentInformation
)
887 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
889 * ReqSize
= sizeof (SYSTEM_SET_TIME_ADJUSTMENT
);
890 return (STATUS_INFO_LENGTH_MISMATCH
);
893 return (STATUS_NOT_IMPLEMENTED
);
896 SSI_DEF(SystemTimeAdjustmentInformation
)
898 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
900 return (STATUS_INFO_LENGTH_MISMATCH
);
903 return (STATUS_NOT_IMPLEMENTED
);
906 /* Class 29 - Summary Memory Information */
907 QSI_DEF(SystemSummaryMemoryInformation
)
910 return (STATUS_NOT_IMPLEMENTED
);
913 /* Class 30 - Next Event Id Information */
914 QSI_DEF(SystemNextEventIdInformation
)
917 return (STATUS_NOT_IMPLEMENTED
);
920 /* Class 31 - Event Ids Information */
921 QSI_DEF(SystemEventIdsInformation
)
924 return (STATUS_NOT_IMPLEMENTED
);
927 /* Class 32 - Crach Dump Information */
928 QSI_DEF(SystemCrashDumpInformation
)
931 return (STATUS_NOT_IMPLEMENTED
);
934 /* Class 33 - Exception Information */
935 QSI_DEF(SystemExceptionInformation
)
938 return (STATUS_NOT_IMPLEMENTED
);
941 /* Class 34 - Crach Dump State Information */
942 QSI_DEF(SystemCrashDumpStateInformation
)
945 return (STATUS_NOT_IMPLEMENTED
);
948 /* Class 35 - Kernel Debugger Information */
949 QSI_DEF(SystemKernelDebuggerInformation
)
952 return (STATUS_NOT_IMPLEMENTED
);
955 /* Class 36 - Context Switch Information */
956 QSI_DEF(SystemContextSwitchInformation
)
959 return (STATUS_NOT_IMPLEMENTED
);
962 /* Class 37 - Registry Quota Information */
963 QSI_DEF(SystemRegistryQuotaInformation
)
966 return (STATUS_NOT_IMPLEMENTED
);
969 SSI_DEF(SystemRegistryQuotaInformation
)
972 return (STATUS_NOT_IMPLEMENTED
);
975 /* Class 38 - Load And Call Image */
976 SSI_DEF(SystemLoadAndCallImage
)
978 PSYSTEM_LOAD_AND_CALL_IMAGE Slci
= (PSYSTEM_LOAD_AND_CALL_IMAGE
)Buffer
;
980 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE
) != Size
)
982 return(STATUS_INFO_LENGTH_MISMATCH
);
985 return(LdrpLoadAndCallImage(&Slci
->ModuleName
));
988 /* Class 39 - Priority Seperation */
989 SSI_DEF(SystemPrioritySeperation
)
992 return (STATUS_NOT_IMPLEMENTED
);
995 /* Class 40 - Plug Play Bus Information */
996 QSI_DEF(SystemPlugPlayBusInformation
)
999 return (STATUS_NOT_IMPLEMENTED
);
1002 /* Class 41 - Dock Information */
1003 QSI_DEF(SystemDockInformation
)
1006 return (STATUS_NOT_IMPLEMENTED
);
1009 /* Class 42 - Power Information */
1010 QSI_DEF(SystemPowerInformation
)
1013 return (STATUS_NOT_IMPLEMENTED
);
1016 /* Class 43 - Processor Speed Information */
1017 QSI_DEF(SystemProcessorSpeedInformation
)
1020 return (STATUS_NOT_IMPLEMENTED
);
1023 /* Class 44 - Current Time Zone Information */
1024 QSI_DEF(SystemCurrentTimeZoneInformation
)
1026 * ReqSize
= sizeof (TIME_ZONE_INFORMATION
);
1028 if (sizeof (TIME_ZONE_INFORMATION
) != Size
)
1030 return (STATUS_INFO_LENGTH_MISMATCH
);
1032 /* Copy the time zone information struct */
1035 & _SystemTimeZoneInfo
,
1036 sizeof (TIME_ZONE_INFORMATION
)
1039 return (STATUS_SUCCESS
);
1043 SSI_DEF(SystemCurrentTimeZoneInformation
)
1046 * Check user buffer's size
1048 if (Size
< sizeof (TIME_ZONE_INFORMATION
))
1050 return (STATUS_INFO_LENGTH_MISMATCH
);
1052 /* Copy the time zone information struct */
1054 & _SystemTimeZoneInfo
,
1055 (TIME_ZONE_INFORMATION
*) Buffer
,
1056 sizeof (TIME_ZONE_INFORMATION
)
1058 return (STATUS_SUCCESS
);
1062 /* Class 45 - Lookaside Information */
1063 QSI_DEF(SystemLookasideInformation
)
1066 return (STATUS_NOT_IMPLEMENTED
);
1070 /* Class 46 - Set time slip event */
1071 SSI_DEF(SystemSetTimeSlipEvent
)
1074 return (STATUS_NOT_IMPLEMENTED
);
1078 /* Class 47 - Create a new session (TSE) */
1079 SSI_DEF(SystemCreateSession
)
1082 return (STATUS_NOT_IMPLEMENTED
);
1086 /* Class 48 - Delete an existing session (TSE) */
1087 SSI_DEF(SystemDeleteSession
)
1090 return (STATUS_NOT_IMPLEMENTED
);
1094 /* Class 49 - UNKNOWN */
1095 QSI_DEF(SystemInvalidInfoClass4
)
1098 return (STATUS_NOT_IMPLEMENTED
);
1102 /* Class 50 - System range start address */
1103 QSI_DEF(SystemRangeStartInformation
)
1106 return (STATUS_NOT_IMPLEMENTED
);
1110 /* Class 51 - Driver verifier information */
1111 QSI_DEF(SystemVerifierInformation
)
1114 return (STATUS_NOT_IMPLEMENTED
);
1118 SSI_DEF(SystemVerifierInformation
)
1121 return (STATUS_NOT_IMPLEMENTED
);
1125 /* Class 52 - Add a driver verifier */
1126 SSI_DEF(SystemAddVerifier
)
1129 return (STATUS_NOT_IMPLEMENTED
);
1133 /* Class 53 - A session's processes */
1134 QSI_DEF(SystemSessionProcessesInformation
)
1137 return (STATUS_NOT_IMPLEMENTED
);
1141 /* Query/Set Calls Table */
1145 NTSTATUS (* Query
) (PVOID
,ULONG
,PULONG
);
1146 NTSTATUS (* Set
) (PVOID
,ULONG
);
1153 // XX unknown behaviour
1155 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1156 #define SI_QX(n) {QSI_USE(n),NULL}
1157 #define SI_XS(n) {NULL,SSI_USE(n)}
1158 #define SI_XX(n) {NULL,NULL}
1164 SI_QX(SystemBasicInformation
),
1165 SI_QX(SystemProcessorInformation
),
1166 SI_QX(SystemPerformanceInformation
),
1167 SI_QX(SystemTimeOfDayInformation
),
1168 SI_QX(SystemPathInformation
), /* should be SI_XX */
1169 SI_QX(SystemProcessInformation
),
1170 SI_QX(SystemCallCountInformation
),
1171 SI_QX(SystemDeviceInformation
),
1172 SI_QX(SystemProcessorPerformanceInformation
),
1173 SI_QS(SystemFlagsInformation
),
1174 SI_QX(SystemCallTimeInformation
), /* should be SI_XX */
1175 SI_QX(SystemModuleInformation
),
1176 SI_QX(SystemLocksInformation
),
1177 SI_QX(SystemStackTraceInformation
), /* should be SI_XX */
1178 SI_QX(SystemPagedPoolInformation
), /* should be SI_XX */
1179 SI_QX(SystemNonPagedPoolInformation
), /* should be SI_XX */
1180 SI_QX(SystemHandleInformation
),
1181 SI_QX(SystemObjectInformation
),
1182 SI_QX(SystemPageFileInformation
),
1183 SI_QX(SystemVdmInstemulInformation
),
1184 SI_QX(SystemVdmBopInformation
), /* it should be SI_XX */
1185 SI_QS(SystemFileCacheInformation
),
1186 SI_QX(SystemPoolTagInformation
),
1187 SI_QX(SystemInterruptInformation
),
1188 SI_QS(SystemDpcBehaviourInformation
),
1189 SI_QX(SystemFullMemoryInformation
), /* it should be SI_XX */
1190 SI_XS(SystemLoadImage
),
1191 SI_XS(SystemUnloadImage
),
1192 SI_QS(SystemTimeAdjustmentInformation
),
1193 SI_QX(SystemSummaryMemoryInformation
), /* it should be SI_XX */
1194 SI_QX(SystemNextEventIdInformation
), /* it should be SI_XX */
1195 SI_QX(SystemEventIdsInformation
), /* it should be SI_XX */
1196 SI_QX(SystemCrashDumpInformation
),
1197 SI_QX(SystemExceptionInformation
),
1198 SI_QX(SystemCrashDumpStateInformation
),
1199 SI_QX(SystemKernelDebuggerInformation
),
1200 SI_QX(SystemContextSwitchInformation
),
1201 SI_QS(SystemRegistryQuotaInformation
),
1202 SI_XS(SystemLoadAndCallImage
),
1203 SI_XS(SystemPrioritySeperation
),
1204 SI_QX(SystemPlugPlayBusInformation
), /* it should be SI_XX */
1205 SI_QX(SystemDockInformation
), /* it should be SI_XX */
1206 SI_QX(SystemPowerInformation
), /* it should be SI_XX */
1207 SI_QX(SystemProcessorSpeedInformation
), /* it should be SI_XX */
1208 SI_QS(SystemCurrentTimeZoneInformation
), /* it should be SI_QX */
1209 SI_QX(SystemLookasideInformation
),
1210 SI_XS(SystemSetTimeSlipEvent
),
1211 SI_XS(SystemCreateSession
),
1212 SI_XS(SystemDeleteSession
),
1213 SI_QX(SystemInvalidInfoClass4
), /* it should be SI_XX */
1214 SI_QX(SystemRangeStartInformation
),
1215 SI_QS(SystemVerifierInformation
),
1216 SI_XS(SystemAddVerifier
),
1217 SI_QX(SystemSessionProcessesInformation
)
1225 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1226 OUT PVOID UnsafeSystemInformation
,
1228 OUT PULONG UnsafeResultLength
)
1231 PVOID SystemInformation
;
1235 /* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
1236 SystemInformationClass );
1238 /*if (ExGetPreviousMode() == KernelMode)
1240 SystemInformation
= UnsafeSystemInformation
;
1244 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1245 if (SystemInformation == NULL)
1247 return(STATUS_NO_MEMORY);
1251 /* Clear user buffer. */
1252 RtlZeroMemory(SystemInformation
, Length
);
1255 * Check the request is valid.
1257 if ((SystemInformationClass
>= SystemInformationClassMin
) &&
1258 (SystemInformationClass
< SystemInformationClassMax
))
1260 if (NULL
!= CallQS
[SystemInformationClass
].Query
)
1263 * Hand the request to a subhandler.
1265 FStatus
= CallQS
[SystemInformationClass
].Query(SystemInformation
,
1268 /*if (ExGetPreviousMode() != KernelMode)
1270 Status = MmCopyToCaller(UnsafeSystemInformation,
1273 ExFreePool(SystemInformation);
1274 if (!NT_SUCCESS(Status))
1279 if (UnsafeResultLength
!= NULL
)
1281 /*if (ExGetPreviousMode() == KernelMode)
1283 *UnsafeResultLength = ResultLength;
1287 Status
= MmCopyToCaller(UnsafeResultLength
,
1290 if (!NT_SUCCESS(Status
))
1299 return (STATUS_INVALID_INFO_CLASS
);
1305 NtSetSystemInformation (
1306 IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1307 IN PVOID SystemInformation
,
1308 IN ULONG SystemInformationLength
1312 * If called from user mode, check
1313 * possible unsafe arguments.
1316 if (KernelMode
!= KeGetPreviousMode())
1320 // SystemInformation,
1330 * Check the request is valid.
1332 if ( (SystemInformationClass
>= SystemInformationClassMin
)
1333 && (SystemInformationClass
< SystemInformationClassMax
)
1336 if (NULL
!= CallQS
[SystemInformationClass
].Set
)
1339 * Hand the request to a subhandler.
1341 return CallQS
[SystemInformationClass
].Set (
1343 SystemInformationLength
1347 return (STATUS_INVALID_INFO_CLASS
);
1353 NtFlushInstructionCache (
1354 IN HANDLE ProcessHandle
,
1355 IN PVOID BaseAddress
,
1356 IN UINT NumberOfBytesToFlush
1360 return(STATUS_NOT_IMPLEMENTED
);