1 /* $Id: sysinfo.c,v 1.29 2004/04/23 05:37:10 jimtabor 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/ldr.h>
22 #include <internal/safe.h>
23 #include <internal/ps.h>
24 #include <internal/mm.h>
27 #include <internal/debug.h>
29 extern ULONG NtGlobalFlag
; /* FIXME: it should go in a ddk/?.h */
30 VOID STDCALL
KeQueryInterruptTime(PLARGE_INTEGER CurrentTime
);
32 VOID
MmPrintMemoryStatistic(VOID
);
34 extern ULONG Ke386CpuidFlags
;
35 extern ULONG Ke386Cpuid
;
37 /* FUNCTIONS *****************************************************************/
40 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
41 OUT PVOID UnsafeValue
,
43 IN OUT PULONG UnsafeReturnLength
)
51 UNICODE_STRING WValue
;
55 * Copy the name to kernel space if necessary and convert it to ANSI.
57 if (ExGetPreviousMode() != KernelMode
)
59 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
60 if (!NT_SUCCESS(Status
))
64 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
65 if (!NT_SUCCESS(Status
))
72 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
73 if (!NT_SUCCESS(Status
))
80 * Create a temporary buffer for the value
82 Value
= ExAllocatePool(NonPagedPool
, Length
);
85 RtlFreeAnsiString(&AName
);
86 if (ExGetPreviousMode() != KernelMode
)
88 RtlFreeUnicodeString(&WName
);
90 return(STATUS_NO_MEMORY
);
94 * Get the environment variable
96 Result
= HalGetEnvironmentVariable(AName
.Buffer
, Value
, Length
);
99 RtlFreeAnsiString(&AName
);
100 if (ExGetPreviousMode() != KernelMode
)
102 RtlFreeUnicodeString(&WName
);
105 return(STATUS_UNSUCCESSFUL
);
109 * Convert the result to UNICODE.
111 RtlInitAnsiString(&AValue
, Value
);
112 Status
= RtlAnsiStringToUnicodeString(&WValue
, &AValue
, TRUE
);
113 if (!NT_SUCCESS(Status
))
115 RtlFreeAnsiString(&AName
);
116 if (ExGetPreviousMode() != KernelMode
)
118 RtlFreeUnicodeString(&WName
);
123 ReturnLength
= WValue
.Length
;
126 * Copy the result back to the caller.
128 if (ExGetPreviousMode() != KernelMode
)
130 Status
= MmCopyToCaller(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
131 if (!NT_SUCCESS(Status
))
133 RtlFreeAnsiString(&AName
);
134 if (ExGetPreviousMode() != KernelMode
)
136 RtlFreeUnicodeString(&WName
);
139 RtlFreeUnicodeString(&WValue
);
143 Status
= MmCopyToCaller(UnsafeReturnLength
, &ReturnLength
,
145 if (!NT_SUCCESS(Status
))
147 RtlFreeAnsiString(&AName
);
148 if (ExGetPreviousMode() != KernelMode
)
150 RtlFreeUnicodeString(&WName
);
153 RtlFreeUnicodeString(&WValue
);
159 memcpy(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
160 memcpy(UnsafeReturnLength
, &ReturnLength
, sizeof(ULONG
));
164 * Free temporary buffers.
166 RtlFreeAnsiString(&AName
);
167 if (ExGetPreviousMode() != KernelMode
)
169 RtlFreeUnicodeString(&WName
);
172 RtlFreeUnicodeString(&WValue
);
174 return(STATUS_SUCCESS
);
179 NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
180 IN PUNICODE_STRING UnsafeValue
)
182 UNICODE_STRING WName
;
184 UNICODE_STRING WValue
;
190 * Check for required privilege.
192 /* FIXME: Not implemented. */
195 * Copy the name to kernel space if necessary and convert it to ANSI.
197 if (ExGetPreviousMode() != KernelMode
)
199 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
200 if (!NT_SUCCESS(Status
))
204 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
205 if (!NT_SUCCESS(Status
))
212 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
213 if (!NT_SUCCESS(Status
))
220 * Copy the value to kernel space and convert to ANSI.
222 if (ExGetPreviousMode() != KernelMode
)
224 Status
= RtlCaptureUnicodeString(&WValue
, UnsafeValue
);
225 if (!NT_SUCCESS(Status
))
227 RtlFreeUnicodeString(&WName
);
228 RtlFreeAnsiString(&AName
);
231 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
232 if (!NT_SUCCESS(Status
))
234 RtlFreeUnicodeString(&WName
);
235 RtlFreeAnsiString(&AName
);
236 RtlFreeUnicodeString(&WValue
);
242 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
243 if (!NT_SUCCESS(Status
))
245 RtlFreeAnsiString(&AName
);
251 * Set the environment variable
253 Result
= HalSetEnvironmentVariable(AName
.Buffer
, AValue
.Buffer
);
256 * Free everything and return status.
258 RtlFreeAnsiString(&AName
);
259 RtlFreeAnsiString(&AValue
);
260 if (ExGetPreviousMode() != KernelMode
)
262 RtlFreeUnicodeString(&WName
);
263 RtlFreeUnicodeString(&WValue
);
268 return(STATUS_UNSUCCESSFUL
);
270 return(STATUS_SUCCESS
);
274 /* --- Query/Set System Information --- */
277 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
278 * so the stack is popped only in one place on x86 platform.
280 #define QSI_USE(n) QSI##n
282 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
284 #define SSI_USE(n) SSI##n
286 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
289 /* Class 0 - Basic Information */
290 QSI_DEF(SystemBasicInformation
)
292 PSYSTEM_BASIC_INFORMATION Sbi
293 = (PSYSTEM_BASIC_INFORMATION
) Buffer
;
295 *ReqSize
= sizeof (SYSTEM_BASIC_INFORMATION
);
297 * Check user buffer's size
299 if (Size
< sizeof (SYSTEM_BASIC_INFORMATION
))
301 return (STATUS_INFO_LENGTH_MISMATCH
);
304 Sbi
->MaximumIncrement
= 100000; /* FIXME */
305 Sbi
->PhysicalPageSize
= PAGE_SIZE
; /* FIXME: it should be PAGE_SIZE */
306 Sbi
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
307 Sbi
->LowestPhysicalPage
= 0; /* FIXME */
308 Sbi
->HighestPhysicalPage
= MmStats
.NrTotalPages
; /* FIXME */
309 Sbi
->AllocationGranularity
= 65536; /* hard coded on Intel? */
310 Sbi
->LowestUserAddress
= 0x10000; /* Top of 64k */
311 Sbi
->HighestUserAddress
= 0x7ffeffff; /* From mm/mminit.c */
312 Sbi
->ActiveProcessors
= 0x00000001; /* FIXME */
313 Sbi
->NumberProcessors
= KeNumberProcessors
;
314 return (STATUS_SUCCESS
);
317 /* Class 1 - Processor Information */
318 QSI_DEF(SystemProcessorInformation
)
320 PSYSTEM_PROCESSOR_INFORMATION Spi
321 = (PSYSTEM_PROCESSOR_INFORMATION
) Buffer
;
323 *ReqSize
= sizeof (SYSTEM_PROCESSOR_INFORMATION
);
325 * Check user buffer's size
327 if (Size
< sizeof (SYSTEM_PROCESSOR_INFORMATION
))
329 return (STATUS_INFO_LENGTH_MISMATCH
);
331 Spi
->ProcessorArchitecture
= ((Ke386Cpuid
>> 8) & 0xf);
332 Spi
->ProcessorLevel
= ((Ke386Cpuid
>> 4) & 0xf);
333 Spi
->ProcessorRevision
= (Ke386Cpuid
& 0xf) | ((Ke386Cpuid
>> 4) & 0x300);
335 Spi
->FeatureBits
= Ke386CpuidFlags
;
337 DPRINT("Arch %d Level %d Rev %d\n", Spi
->ProcessorArchitecture
,
338 Spi
->ProcessorLevel
, Spi
->ProcessorRevision
);
340 return (STATUS_SUCCESS
);
343 /* Class 2 - Performance Information */
344 QSI_DEF(SystemPerformanceInformation
)
346 PSYSTEM_PERFORMANCE_INFORMATION Spi
347 = (PSYSTEM_PERFORMANCE_INFORMATION
) Buffer
;
349 PEPROCESS TheIdleProcess
;
351 *ReqSize
= sizeof (SYSTEM_PERFORMANCE_INFORMATION
);
353 * Check user buffer's size
355 if (Size
< sizeof (SYSTEM_PERFORMANCE_INFORMATION
))
357 return (STATUS_INFO_LENGTH_MISMATCH
);
360 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
362 Spi
->IdleTime
.QuadPart
= TheIdleProcess
->Pcb
.KernelTime
* 100000;
364 Spi
->ReadTransferCount
.QuadPart
= 0; /* FIXME */
365 Spi
->WriteTransferCount
.QuadPart
= 0; /* FIXME */
366 Spi
->OtherTransferCount
.QuadPart
= 0; /* FIXME */
367 Spi
->ReadOperationCount
= 0; /* FIXME */
368 Spi
->WriteOperationCount
= 0; /* FIXME */
369 Spi
->OtherOperationCount
= 0; /* FIXME */
371 Spi
->AvailablePages
= MiNrAvailablePages
;
372 Spi
->TotalCommittedPages
= MiUsedSwapPages
;
373 Spi
->TotalCommitLimit
= MiFreeSwapPages
+ MiUsedSwapPages
; /* FIXME */
375 Spi
->PeakCommitment
= 0; /* FIXME */
376 Spi
->PageFaults
= 0; /* FIXME */
377 Spi
->WriteCopyFaults
= 0; /* FIXME */
378 Spi
->TransitionFaults
= 0; /* FIXME */
379 Spi
->CacheTransitionFaults
= 0; /* FIXME */
380 Spi
->DemandZeroFaults
= 0; /* FIXME */
381 Spi
->PagesRead
= 0; /* FIXME */
382 Spi
->PageReadIos
= 0; /* FIXME */
383 Spi
->CacheReads
= 0; /* FIXME */
384 Spi
->CacheIos
= 0; /* FIXME */
385 Spi
->PagefilePagesWritten
= 0; /* FIXME */
386 Spi
->PagefilePageWriteIos
= 0; /* FIXME */
387 Spi
->MappedFilePagesWritten
= 0; /* FIXME */
388 Spi
->MappedFilePageWriteIos
= 0; /* FIXME */
390 Spi
->PagedPoolUsage
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
;
391 Spi
->PagedPoolAllocs
= 0; /* FIXME */
392 Spi
->PagedPoolFrees
= 0; /* FIXME */
393 Spi
->NonPagedPoolUsage
= MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
;
394 Spi
->NonPagedPoolAllocs
= 0; /* FIXME */
395 Spi
->NonPagedPoolFrees
= 0; /* FIXME */
397 Spi
->TotalFreeSystemPtes
= 0; /* FIXME */
399 Spi
->SystemCodePage
= MmStats
.NrSystemPages
; /* FIXME */
401 Spi
->TotalSystemDriverPages
= 0; /* FIXME */
402 Spi
->TotalSystemCodePages
= 0; /* FIXME */
403 Spi
->SmallNonPagedLookasideListAllocateHits
= 0; /* FIXME */
404 Spi
->SmallPagedLookasideListAllocateHits
= 0; /* FIXME */
405 Spi
->Reserved3
= 0; /* FIXME */
407 Spi
->MmSystemCachePage
= MiMemoryConsumers
[MC_CACHE
].PagesUsed
;
408 Spi
->PagedPoolPage
= MmPagedPoolSize
; /* FIXME */
410 Spi
->SystemDriverPage
= 0; /* FIXME */
411 Spi
->FastReadNoWait
= 0; /* FIXME */
412 Spi
->FastReadWait
= 0; /* FIXME */
413 Spi
->FastReadResourceMiss
= 0; /* FIXME */
414 Spi
->FastReadNotPossible
= 0; /* FIXME */
416 Spi
->FastMdlReadNoWait
= 0; /* FIXME */
417 Spi
->FastMdlReadWait
= 0; /* FIXME */
418 Spi
->FastMdlReadResourceMiss
= 0; /* FIXME */
419 Spi
->FastMdlReadNotPossible
= 0; /* FIXME */
421 Spi
->MapDataNoWait
= 0; /* FIXME */
422 Spi
->MapDataWait
= 0; /* FIXME */
423 Spi
->MapDataNoWaitMiss
= 0; /* FIXME */
424 Spi
->MapDataWaitMiss
= 0; /* FIXME */
426 Spi
->PinMappedDataCount
= 0; /* FIXME */
427 Spi
->PinReadNoWait
= 0; /* FIXME */
428 Spi
->PinReadWait
= 0; /* FIXME */
429 Spi
->PinReadNoWaitMiss
= 0; /* FIXME */
430 Spi
->PinReadWaitMiss
= 0; /* FIXME */
431 Spi
->CopyReadNoWait
= 0; /* FIXME */
432 Spi
->CopyReadWait
= 0; /* FIXME */
433 Spi
->CopyReadNoWaitMiss
= 0; /* FIXME */
434 Spi
->CopyReadWaitMiss
= 0; /* FIXME */
436 Spi
->MdlReadNoWait
= 0; /* FIXME */
437 Spi
->MdlReadWait
= 0; /* FIXME */
438 Spi
->MdlReadNoWaitMiss
= 0; /* FIXME */
439 Spi
->MdlReadWaitMiss
= 0; /* FIXME */
440 Spi
->ReadAheadIos
= 0; /* FIXME */
441 Spi
->LazyWriteIos
= 0; /* FIXME */
442 Spi
->LazyWritePages
= 0; /* FIXME */
443 Spi
->DataFlushes
= 0; /* FIXME */
444 Spi
->DataPages
= 0; /* FIXME */
445 Spi
->ContextSwitches
= 0; /* FIXME */
446 Spi
->FirstLevelTbFills
= 0; /* FIXME */
447 Spi
->SecondLevelTbFills
= 0; /* FIXME */
448 Spi
->SystemCalls
= 0; /* FIXME */
450 return (STATUS_SUCCESS
);
453 /* Class 3 - Time Of Day Information */
454 QSI_DEF(SystemTimeOfDayInformation
)
456 LARGE_INTEGER CurrentTime
;
458 PSYSTEM_TIMEOFDAY_INFORMATION Sti
459 = (PSYSTEM_TIMEOFDAY_INFORMATION
) Buffer
;
461 *ReqSize
= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
);
463 * Check user buffer's size
465 if (Size
< sizeof (SYSTEM_TIMEOFDAY_INFORMATION
))
467 return (STATUS_INFO_LENGTH_MISMATCH
);
470 KeQuerySystemTime(&CurrentTime
);
472 Sti
->BootTime
= SystemBootTime
;
473 Sti
->CurrentTime
= CurrentTime
;
474 Sti
->TimeZoneBias
.QuadPart
= _SystemTimeZoneInfo
.Bias
;
475 Sti
->TimeZoneId
= 0; /* FIXME */
476 Sti
->Reserved
= 0; /* FIXME */
478 return (STATUS_SUCCESS
);
481 /* Class 4 - Path Information */
482 QSI_DEF(SystemPathInformation
)
484 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
485 return (STATUS_BREAKPOINT
);
488 /* Class 5 - Process Information */
489 QSI_DEF(SystemProcessInformation
)
491 ULONG ovlSize
=0, nThreads
=1;
495 /* scan the process list */
496 // TODO: Add thread information
498 PSYSTEM_PROCESSES Spi
499 = (PSYSTEM_PROCESSES
) Buffer
;
501 *ReqSize
= sizeof(SYSTEM_PROCESSES
);
503 if (Size
< sizeof(SYSTEM_PROCESSES
))
505 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
508 syspr
= PsGetNextProcess(NULL
);
510 pCur
= (unsigned char *)Spi
;
514 PSYSTEM_PROCESSES SpiCur
;
517 int inLen
=32; // image name len in bytes
520 SpiCur
= (PSYSTEM_PROCESSES
)pCur
;
522 nThreads
= 1; // FIXME
524 // size of the structure for every process
525 curSize
= sizeof(SYSTEM_PROCESSES
)-sizeof(SYSTEM_THREADS
)+sizeof(SYSTEM_THREADS
)*nThreads
;
526 ovlSize
+= curSize
+inLen
;
531 ObDereferenceObject(pr
);
533 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
536 // fill system information
537 SpiCur
->NextEntryDelta
= curSize
+inLen
; // relative offset to the beginnnig of the next structure
538 SpiCur
->ThreadCount
= nThreads
;
539 SpiCur
->CreateTime
= pr
->CreateTime
;
540 SpiCur
->UserTime
.QuadPart
= pr
->Pcb
.UserTime
* 100000;
541 SpiCur
->KernelTime
.QuadPart
= pr
->Pcb
.KernelTime
* 100000;
542 SpiCur
->ProcessName
.Length
= strlen(pr
->ImageFileName
) * sizeof(WCHAR
);
543 SpiCur
->ProcessName
.MaximumLength
= inLen
;
544 SpiCur
->ProcessName
.Buffer
= (void*)(pCur
+curSize
);
546 // copy name to the end of the struct
547 RtlInitAnsiString(&imgName
, pr
->ImageFileName
);
548 RtlAnsiStringToUnicodeString(&SpiCur
->ProcessName
, &imgName
, FALSE
);
550 SpiCur
->BasePriority
= pr
->Pcb
.BasePriority
;
551 SpiCur
->ProcessId
= pr
->UniqueProcessId
;
552 SpiCur
->InheritedFromProcessId
= (DWORD
)(pr
->InheritedFromUniqueProcessId
);
553 SpiCur
->HandleCount
= 0; // FIXME
554 SpiCur
->VmCounters
.PeakVirtualSize
= pr
->PeakVirtualSize
;
555 SpiCur
->VmCounters
.VirtualSize
= pr
->VirtualSize
.QuadPart
;
556 SpiCur
->VmCounters
.PageFaultCount
= pr
->LastFaultCount
;
557 SpiCur
->VmCounters
.PeakWorkingSetSize
= pr
->Vm
.PeakWorkingSetSize
; // Is this right using ->Vm. here ?
558 SpiCur
->VmCounters
.WorkingSetSize
= pr
->Vm
.WorkingSetSize
; // Is this right using ->Vm. here ?
559 SpiCur
->VmCounters
.QuotaPeakPagedPoolUsage
=
560 pr
->QuotaPeakPoolUsage
[0];
561 SpiCur
->VmCounters
.QuotaPagedPoolUsage
=
562 pr
->QuotaPoolUsage
[0];
563 SpiCur
->VmCounters
.QuotaPeakNonPagedPoolUsage
=
564 pr
->QuotaPeakPoolUsage
[1];
565 SpiCur
->VmCounters
.QuotaNonPagedPoolUsage
=
566 pr
->QuotaPoolUsage
[1];
567 SpiCur
->VmCounters
.PagefileUsage
= pr
->PagefileUsage
; // FIXME
568 SpiCur
->VmCounters
.PeakPagefileUsage
= pr
->PeakPagefileUsage
;
569 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
570 // doesn't seem to contain any equivalent field
571 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
573 pr
= PsGetNextProcess(pr
);
575 if ((pr
== syspr
) || (pr
== NULL
))
577 SpiCur
->NextEntryDelta
= 0;
581 pCur
= pCur
+ curSize
+ inLen
;
582 } while ((pr
!= syspr
) && (pr
!= NULL
));
587 ObDereferenceObject(pr
);
589 return (STATUS_SUCCESS
);
592 /* Class 6 - Call Count Information */
593 QSI_DEF(SystemCallCountInformation
)
596 return (STATUS_NOT_IMPLEMENTED
);
599 /* Class 7 - Device Information */
600 QSI_DEF(SystemDeviceInformation
)
602 PSYSTEM_DEVICE_INFORMATION Sdi
603 = (PSYSTEM_DEVICE_INFORMATION
) Buffer
;
604 PCONFIGURATION_INFORMATION ConfigInfo
;
606 *ReqSize
= sizeof (SYSTEM_DEVICE_INFORMATION
);
608 * Check user buffer's size
610 if (Size
< sizeof (SYSTEM_DEVICE_INFORMATION
))
612 return (STATUS_INFO_LENGTH_MISMATCH
);
615 ConfigInfo
= IoGetConfigurationInformation ();
617 Sdi
->NumberOfDisks
= ConfigInfo
->DiskCount
;
618 Sdi
->NumberOfFloppies
= ConfigInfo
->FloppyCount
;
619 Sdi
->NumberOfCdRoms
= ConfigInfo
->CdRomCount
;
620 Sdi
->NumberOfTapes
= ConfigInfo
->TapeCount
;
621 Sdi
->NumberOfSerialPorts
= ConfigInfo
->SerialCount
;
622 Sdi
->NumberOfParallelPorts
= ConfigInfo
->ParallelCount
;
624 return (STATUS_SUCCESS
);
627 /* Class 8 - Processor Performance Information */
628 QSI_DEF(SystemProcessorPerformanceInformation
)
630 PSYSTEM_PROCESSORTIME_INFO Spi
631 = (PSYSTEM_PROCESSORTIME_INFO
) Buffer
;
633 PEPROCESS TheIdleProcess
;
636 *ReqSize
= sizeof (SYSTEM_PROCESSORTIME_INFO
);
638 * Check user buffer's size
640 if (Size
< sizeof (SYSTEM_PROCESSORTIME_INFO
))
642 return (STATUS_INFO_LENGTH_MISMATCH
);
645 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
647 KeQueryInterruptTime((PLARGE_INTEGER
) &CurrentTime
);
649 Spi
->TotalProcessorRunTime
.QuadPart
=
650 TheIdleProcess
->Pcb
.KernelTime
* 100000; // IdleTime
651 Spi
->TotalProcessorTime
.QuadPart
= KiKernelTime
* 100000; // KernelTime
652 Spi
->TotalProcessorUserTime
.QuadPart
= KiUserTime
* 100000;
653 Spi
->TotalDPCTime
.QuadPart
= KiDpcTime
* 100000;
654 Spi
->TotalInterruptTime
= CurrentTime
;
655 Spi
->TotalInterrupts
= CurrentTime
.QuadPart
/ 100000; // Interrupt Count
657 return (STATUS_SUCCESS
);
660 /* Class 9 - Flags Information */
661 QSI_DEF(SystemFlagsInformation
)
663 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
665 * ReqSize
= sizeof (SYSTEM_FLAGS_INFORMATION
);
666 return (STATUS_INFO_LENGTH_MISMATCH
);
668 ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
= NtGlobalFlag
;
669 return (STATUS_SUCCESS
);
672 SSI_DEF(SystemFlagsInformation
)
674 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
676 return (STATUS_INFO_LENGTH_MISMATCH
);
678 NtGlobalFlag
= ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
;
679 return (STATUS_SUCCESS
);
682 /* Class 10 - Call Time Information */
683 QSI_DEF(SystemCallTimeInformation
)
686 return (STATUS_NOT_IMPLEMENTED
);
689 /* Class 11 - Module Information */
690 QSI_DEF(SystemModuleInformation
)
692 return LdrpQueryModuleInformation(Buffer
, Size
, ReqSize
);
695 /* Class 12 - Locks Information */
696 QSI_DEF(SystemLocksInformation
)
699 return (STATUS_NOT_IMPLEMENTED
);
702 /* Class 13 - Stack Trace Information */
703 QSI_DEF(SystemStackTraceInformation
)
706 return (STATUS_NOT_IMPLEMENTED
);
709 /* Class 14 - Paged Pool Information */
710 QSI_DEF(SystemPagedPoolInformation
)
713 return (STATUS_NOT_IMPLEMENTED
);
716 /* Class 15 - Non Paged Pool Information */
717 QSI_DEF(SystemNonPagedPoolInformation
)
720 return (STATUS_NOT_IMPLEMENTED
);
723 /* Class 16 - Handle Information */
724 QSI_DEF(SystemHandleInformation
)
727 return (STATUS_NOT_IMPLEMENTED
);
730 /* Class 17 - Information */
731 QSI_DEF(SystemObjectInformation
)
734 return (STATUS_NOT_IMPLEMENTED
);
737 /* Class 18 - Information */
738 QSI_DEF(SystemPageFileInformation
)
741 return (STATUS_NOT_IMPLEMENTED
);
744 /* Class 19 - Vdm Instemul Information */
745 QSI_DEF(SystemVdmInstemulInformation
)
748 return (STATUS_NOT_IMPLEMENTED
);
751 /* Class 20 - Vdm Bop Information */
752 QSI_DEF(SystemVdmBopInformation
)
755 return (STATUS_NOT_IMPLEMENTED
);
758 /* Class 21 - File Cache Information */
759 QSI_DEF(SystemFileCacheInformation
)
761 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
763 * ReqSize
= sizeof (SYSTEM_CACHE_INFORMATION
);
764 return (STATUS_INFO_LENGTH_MISMATCH
);
767 return (STATUS_NOT_IMPLEMENTED
);
770 SSI_DEF(SystemFileCacheInformation
)
772 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
774 return (STATUS_INFO_LENGTH_MISMATCH
);
777 return (STATUS_NOT_IMPLEMENTED
);
780 /* Class 22 - Pool Tag Information */
781 QSI_DEF(SystemPoolTagInformation
)
784 return (STATUS_NOT_IMPLEMENTED
);
787 /* Class 23 - Interrupt Information */
788 QSI_DEF(SystemInterruptInformation
)
791 return (STATUS_NOT_IMPLEMENTED
);
794 /* Class 24 - DPC Behaviour Information */
795 QSI_DEF(SystemDpcBehaviourInformation
)
798 return (STATUS_NOT_IMPLEMENTED
);
801 SSI_DEF(SystemDpcBehaviourInformation
)
804 return (STATUS_NOT_IMPLEMENTED
);
807 /* Class 25 - Full Memory Information */
808 QSI_DEF(SystemFullMemoryInformation
)
810 PULONG Spi
= (PULONG
) Buffer
;
812 PEPROCESS TheIdleProcess
;
814 * ReqSize
= sizeof (ULONG
);
816 if (sizeof (ULONG
) != Size
)
818 return (STATUS_INFO_LENGTH_MISMATCH
);
820 DPRINT1("SystemFullMemoryInformation\n");
822 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
824 DbgPrint("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
825 TheIdleProcess
->UniqueProcessId
,
826 TheIdleProcess
->Pcb
.KernelTime
,
830 MmPrintMemoryStatistic();
832 *Spi
= MiMemoryConsumers
[MC_USER
].PagesUsed
;
834 return (STATUS_SUCCESS
);
837 /* Class 26 - Load Image */
838 SSI_DEF(SystemLoadImage
)
840 PSYSTEM_LOAD_IMAGE Sli
= (PSYSTEM_LOAD_IMAGE
)Buffer
;
842 if (sizeof(SYSTEM_LOAD_IMAGE
) != Size
)
844 return(STATUS_INFO_LENGTH_MISMATCH
);
847 return(LdrpLoadImage(&Sli
->ModuleName
,
849 &Sli
->SectionPointer
,
851 &Sli
->ExportDirectory
));
854 /* Class 27 - Unload Image */
855 SSI_DEF(SystemUnloadImage
)
857 PSYSTEM_UNLOAD_IMAGE Sui
= (PSYSTEM_UNLOAD_IMAGE
)Buffer
;
859 if (sizeof(SYSTEM_UNLOAD_IMAGE
) != Size
)
861 return(STATUS_INFO_LENGTH_MISMATCH
);
864 return(LdrpUnloadImage(Sui
->ModuleBase
));
867 /* Class 28 - Time Adjustment Information */
868 QSI_DEF(SystemTimeAdjustmentInformation
)
870 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
872 * ReqSize
= sizeof (SYSTEM_SET_TIME_ADJUSTMENT
);
873 return (STATUS_INFO_LENGTH_MISMATCH
);
876 return (STATUS_NOT_IMPLEMENTED
);
879 SSI_DEF(SystemTimeAdjustmentInformation
)
881 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
883 return (STATUS_INFO_LENGTH_MISMATCH
);
886 return (STATUS_NOT_IMPLEMENTED
);
889 /* Class 29 - Summary Memory Information */
890 QSI_DEF(SystemSummaryMemoryInformation
)
893 return (STATUS_NOT_IMPLEMENTED
);
896 /* Class 30 - Next Event Id Information */
897 QSI_DEF(SystemNextEventIdInformation
)
900 return (STATUS_NOT_IMPLEMENTED
);
903 /* Class 31 - Event Ids Information */
904 QSI_DEF(SystemEventIdsInformation
)
907 return (STATUS_NOT_IMPLEMENTED
);
910 /* Class 32 - Crach Dump Information */
911 QSI_DEF(SystemCrashDumpInformation
)
914 return (STATUS_NOT_IMPLEMENTED
);
917 /* Class 33 - Exception Information */
918 QSI_DEF(SystemExceptionInformation
)
921 return (STATUS_NOT_IMPLEMENTED
);
924 /* Class 34 - Crach Dump State Information */
925 QSI_DEF(SystemCrashDumpStateInformation
)
928 return (STATUS_NOT_IMPLEMENTED
);
931 /* Class 35 - Kernel Debugger Information */
932 QSI_DEF(SystemKernelDebuggerInformation
)
935 return (STATUS_NOT_IMPLEMENTED
);
938 /* Class 36 - Context Switch Information */
939 QSI_DEF(SystemContextSwitchInformation
)
942 return (STATUS_NOT_IMPLEMENTED
);
945 /* Class 37 - Registry Quota Information */
946 QSI_DEF(SystemRegistryQuotaInformation
)
949 return (STATUS_NOT_IMPLEMENTED
);
952 SSI_DEF(SystemRegistryQuotaInformation
)
955 return (STATUS_NOT_IMPLEMENTED
);
958 /* Class 38 - Load And Call Image */
959 SSI_DEF(SystemLoadAndCallImage
)
961 PSYSTEM_LOAD_AND_CALL_IMAGE Slci
= (PSYSTEM_LOAD_AND_CALL_IMAGE
)Buffer
;
963 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE
) != Size
)
965 return(STATUS_INFO_LENGTH_MISMATCH
);
968 return(LdrpLoadAndCallImage(&Slci
->ModuleName
));
971 /* Class 39 - Priority Seperation */
972 SSI_DEF(SystemPrioritySeperation
)
975 return (STATUS_NOT_IMPLEMENTED
);
978 /* Class 40 - Plug Play Bus Information */
979 QSI_DEF(SystemPlugPlayBusInformation
)
982 return (STATUS_NOT_IMPLEMENTED
);
985 /* Class 41 - Dock Information */
986 QSI_DEF(SystemDockInformation
)
989 return (STATUS_NOT_IMPLEMENTED
);
992 /* Class 42 - Power Information */
993 QSI_DEF(SystemPowerInformation
)
996 return (STATUS_NOT_IMPLEMENTED
);
999 /* Class 43 - Processor Speed Information */
1000 QSI_DEF(SystemProcessorSpeedInformation
)
1003 return (STATUS_NOT_IMPLEMENTED
);
1006 /* Class 44 - Current Time Zone Information */
1007 QSI_DEF(SystemCurrentTimeZoneInformation
)
1009 * ReqSize
= sizeof (TIME_ZONE_INFORMATION
);
1011 if (sizeof (TIME_ZONE_INFORMATION
) != Size
)
1013 return (STATUS_INFO_LENGTH_MISMATCH
);
1015 /* Copy the time zone information struct */
1018 & _SystemTimeZoneInfo
,
1019 sizeof (TIME_ZONE_INFORMATION
)
1022 return (STATUS_SUCCESS
);
1026 SSI_DEF(SystemCurrentTimeZoneInformation
)
1029 * Check user buffer's size
1031 if (Size
< sizeof (TIME_ZONE_INFORMATION
))
1033 return (STATUS_INFO_LENGTH_MISMATCH
);
1035 /* Copy the time zone information struct */
1037 & _SystemTimeZoneInfo
,
1038 (TIME_ZONE_INFORMATION
*) Buffer
,
1039 sizeof (TIME_ZONE_INFORMATION
)
1041 return (STATUS_SUCCESS
);
1045 /* Class 45 - Lookaside Information */
1046 QSI_DEF(SystemLookasideInformation
)
1049 return (STATUS_NOT_IMPLEMENTED
);
1053 /* Class 46 - Set time slip event */
1054 SSI_DEF(SystemSetTimeSlipEvent
)
1057 return (STATUS_NOT_IMPLEMENTED
);
1061 /* Class 47 - Create a new session (TSE) */
1062 SSI_DEF(SystemCreateSession
)
1065 return (STATUS_NOT_IMPLEMENTED
);
1069 /* Class 48 - Delete an existing session (TSE) */
1070 SSI_DEF(SystemDeleteSession
)
1073 return (STATUS_NOT_IMPLEMENTED
);
1077 /* Class 49 - UNKNOWN */
1078 QSI_DEF(SystemInvalidInfoClass4
)
1081 return (STATUS_NOT_IMPLEMENTED
);
1085 /* Class 50 - System range start address */
1086 QSI_DEF(SystemRangeStartInformation
)
1089 return (STATUS_NOT_IMPLEMENTED
);
1093 /* Class 51 - Driver verifier information */
1094 QSI_DEF(SystemVerifierInformation
)
1097 return (STATUS_NOT_IMPLEMENTED
);
1101 SSI_DEF(SystemVerifierInformation
)
1104 return (STATUS_NOT_IMPLEMENTED
);
1108 /* Class 52 - Add a driver verifier */
1109 SSI_DEF(SystemAddVerifier
)
1112 return (STATUS_NOT_IMPLEMENTED
);
1116 /* Class 53 - A session's processes */
1117 QSI_DEF(SystemSessionProcessesInformation
)
1120 return (STATUS_NOT_IMPLEMENTED
);
1124 /* Query/Set Calls Table */
1128 NTSTATUS (* Query
) (PVOID
,ULONG
,PULONG
);
1129 NTSTATUS (* Set
) (PVOID
,ULONG
);
1136 // XX unknown behaviour
1138 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1139 #define SI_QX(n) {QSI_USE(n),NULL}
1140 #define SI_XS(n) {NULL,SSI_USE(n)}
1141 #define SI_XX(n) {NULL,NULL}
1147 SI_QX(SystemBasicInformation
),
1148 SI_QX(SystemProcessorInformation
),
1149 SI_QX(SystemPerformanceInformation
),
1150 SI_QX(SystemTimeOfDayInformation
),
1151 SI_QX(SystemPathInformation
), /* should be SI_XX */
1152 SI_QX(SystemProcessInformation
),
1153 SI_QX(SystemCallCountInformation
),
1154 SI_QX(SystemDeviceInformation
),
1155 SI_QX(SystemProcessorPerformanceInformation
),
1156 SI_QS(SystemFlagsInformation
),
1157 SI_QX(SystemCallTimeInformation
), /* should be SI_XX */
1158 SI_QX(SystemModuleInformation
),
1159 SI_QX(SystemLocksInformation
),
1160 SI_QX(SystemStackTraceInformation
), /* should be SI_XX */
1161 SI_QX(SystemPagedPoolInformation
), /* should be SI_XX */
1162 SI_QX(SystemNonPagedPoolInformation
), /* should be SI_XX */
1163 SI_QX(SystemHandleInformation
),
1164 SI_QX(SystemObjectInformation
),
1165 SI_QX(SystemPageFileInformation
),
1166 SI_QX(SystemVdmInstemulInformation
),
1167 SI_QX(SystemVdmBopInformation
), /* it should be SI_XX */
1168 SI_QS(SystemFileCacheInformation
),
1169 SI_QX(SystemPoolTagInformation
),
1170 SI_QX(SystemInterruptInformation
),
1171 SI_QS(SystemDpcBehaviourInformation
),
1172 SI_QX(SystemFullMemoryInformation
), /* it should be SI_XX */
1173 SI_XS(SystemLoadImage
),
1174 SI_XS(SystemUnloadImage
),
1175 SI_QS(SystemTimeAdjustmentInformation
),
1176 SI_QX(SystemSummaryMemoryInformation
), /* it should be SI_XX */
1177 SI_QX(SystemNextEventIdInformation
), /* it should be SI_XX */
1178 SI_QX(SystemEventIdsInformation
), /* it should be SI_XX */
1179 SI_QX(SystemCrashDumpInformation
),
1180 SI_QX(SystemExceptionInformation
),
1181 SI_QX(SystemCrashDumpStateInformation
),
1182 SI_QX(SystemKernelDebuggerInformation
),
1183 SI_QX(SystemContextSwitchInformation
),
1184 SI_QS(SystemRegistryQuotaInformation
),
1185 SI_XS(SystemLoadAndCallImage
),
1186 SI_XS(SystemPrioritySeperation
),
1187 SI_QX(SystemPlugPlayBusInformation
), /* it should be SI_XX */
1188 SI_QX(SystemDockInformation
), /* it should be SI_XX */
1189 SI_QX(SystemPowerInformation
), /* it should be SI_XX */
1190 SI_QX(SystemProcessorSpeedInformation
), /* it should be SI_XX */
1191 SI_QS(SystemCurrentTimeZoneInformation
), /* it should be SI_QX */
1192 SI_QX(SystemLookasideInformation
),
1193 SI_XS(SystemSetTimeSlipEvent
),
1194 SI_XS(SystemCreateSession
),
1195 SI_XS(SystemDeleteSession
),
1196 SI_QX(SystemInvalidInfoClass4
), /* it should be SI_XX */
1197 SI_QX(SystemRangeStartInformation
),
1198 SI_QS(SystemVerifierInformation
),
1199 SI_XS(SystemAddVerifier
),
1200 SI_QX(SystemSessionProcessesInformation
)
1208 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1209 OUT PVOID UnsafeSystemInformation
,
1211 OUT PULONG UnsafeResultLength
)
1214 PVOID SystemInformation
;
1218 /* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
1219 SystemInformationClass );
1221 /*if (ExGetPreviousMode() == KernelMode)
1223 SystemInformation
= UnsafeSystemInformation
;
1227 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1228 if (SystemInformation == NULL)
1230 return(STATUS_NO_MEMORY);
1234 /* Clear user buffer. */
1235 RtlZeroMemory(SystemInformation
, Length
);
1238 * Check the request is valid.
1240 if ((SystemInformationClass
>= SystemInformationClassMin
) &&
1241 (SystemInformationClass
< SystemInformationClassMax
))
1243 if (NULL
!= CallQS
[SystemInformationClass
].Query
)
1246 * Hand the request to a subhandler.
1248 FStatus
= CallQS
[SystemInformationClass
].Query(SystemInformation
,
1251 /*if (ExGetPreviousMode() != KernelMode)
1253 Status = MmCopyToCaller(UnsafeSystemInformation,
1256 ExFreePool(SystemInformation);
1257 if (!NT_SUCCESS(Status))
1262 if (UnsafeResultLength
!= NULL
)
1264 /*if (ExGetPreviousMode() == KernelMode)
1266 *UnsafeResultLength = ResultLength;
1270 Status
= MmCopyToCaller(UnsafeResultLength
,
1273 if (!NT_SUCCESS(Status
))
1282 return (STATUS_INVALID_INFO_CLASS
);
1288 NtSetSystemInformation (
1289 IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1290 IN PVOID SystemInformation
,
1291 IN ULONG SystemInformationLength
1295 * If called from user mode, check
1296 * possible unsafe arguments.
1299 if (KernelMode
!= KeGetPreviousMode())
1303 // SystemInformation,
1313 * Check the request is valid.
1315 if ( (SystemInformationClass
>= SystemInformationClassMin
)
1316 && (SystemInformationClass
< SystemInformationClassMax
)
1319 if (NULL
!= CallQS
[SystemInformationClass
].Set
)
1322 * Hand the request to a subhandler.
1324 return CallQS
[SystemInformationClass
].Set (
1326 SystemInformationLength
1330 return (STATUS_INVALID_INFO_CLASS
);
1336 NtFlushInstructionCache (
1337 IN HANDLE ProcessHandle
,
1338 IN PVOID BaseAddress
,
1339 IN UINT NumberOfBytesToFlush
1343 return(STATUS_NOT_IMPLEMENTED
);