1 /* $Id: sysinfo.c,v 1.57 2004/11/06 01:42:04 weiden Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/sysinfo.c
6 * PURPOSE: System information functions
7 * PROGRAMMER: David Welch (welch@mcmail.com)
10 * 20/03/2003: implemented querying SystemProcessInformation,
11 * no more copying to-from the caller (Aleksey
12 * Bragin <aleksey@studiocerebral.com>)
15 /* INCLUDES *****************************************************************/
19 #include <internal/debug.h>
21 extern ULONG NtGlobalFlag
; /* FIXME: it should go in a ddk/?.h */
22 ULONGLONG STDCALL
KeQueryInterruptTime(VOID
);
24 VOID
MmPrintMemoryStatistic(VOID
);
26 extern ULONG Ke386CpuidFlags
;
27 extern ULONG Ke386Cpuid
;
29 /* FUNCTIONS *****************************************************************/
40 PHANDLE Handle OPTIONAL
51 ExGetCurrentProcessorCpuUsage (
57 ULONG PercentTime
= 0;
60 Pcr
= KeGetCurrentKPCR();
62 ScaledIdle
= Pcr
->PrcbData
.IdleThread
->KernelTime
* 100;
63 TotalTime
= Pcr
->PrcbData
.KernelTime
+ Pcr
->PrcbData
.UserTime
;
64 if (TotalTime
) PercentTime
= 100 - (ScaledIdle
/ TotalTime
);
65 CpuUsage
= &PercentTime
;
73 ExGetCurrentProcessorCounts (
74 PULONG ThreadKernelTime
,
76 PULONG ProcessorNumber
84 Pcr
= KeGetCurrentKPCR();
86 TotalTime
= Pcr
->PrcbData
.KernelTime
+ Pcr
->PrcbData
.UserTime
;
87 ThreadTime
= Pcr
->PrcbData
.CurrentThread
->KernelTime
;
88 ProcNumber
= Pcr
->ProcessorNumber
;
90 ThreadKernelTime
= &ThreadTime
;
91 TotalCpuTime
= &TotalTime
;
92 ProcessorNumber
= &ProcNumber
;
96 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
97 OUT PVOID UnsafeValue
,
99 IN OUT PULONG UnsafeReturnLength
)
103 UNICODE_STRING WName
;
107 UNICODE_STRING WValue
;
111 * Copy the name to kernel space if necessary and convert it to ANSI.
113 if (ExGetPreviousMode() != KernelMode
)
115 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
116 if (!NT_SUCCESS(Status
))
120 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
121 if (!NT_SUCCESS(Status
))
128 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
129 if (!NT_SUCCESS(Status
))
136 * Create a temporary buffer for the value
138 Value
= ExAllocatePool(NonPagedPool
, Length
);
141 RtlFreeAnsiString(&AName
);
142 if (ExGetPreviousMode() != KernelMode
)
144 RtlFreeUnicodeString(&WName
);
146 return(STATUS_NO_MEMORY
);
150 * Get the environment variable
152 Result
= HalGetEnvironmentVariable(AName
.Buffer
, Value
, Length
);
155 RtlFreeAnsiString(&AName
);
156 if (ExGetPreviousMode() != KernelMode
)
158 RtlFreeUnicodeString(&WName
);
161 return(STATUS_UNSUCCESSFUL
);
165 * Convert the result to UNICODE.
167 RtlInitAnsiString(&AValue
, Value
);
168 Status
= RtlAnsiStringToUnicodeString(&WValue
, &AValue
, TRUE
);
169 if (!NT_SUCCESS(Status
))
171 RtlFreeAnsiString(&AName
);
172 if (ExGetPreviousMode() != KernelMode
)
174 RtlFreeUnicodeString(&WName
);
179 ReturnLength
= WValue
.Length
;
182 * Copy the result back to the caller.
184 if (ExGetPreviousMode() != KernelMode
)
186 Status
= MmCopyToCaller(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
187 if (!NT_SUCCESS(Status
))
189 RtlFreeAnsiString(&AName
);
190 if (ExGetPreviousMode() != KernelMode
)
192 RtlFreeUnicodeString(&WName
);
195 RtlFreeUnicodeString(&WValue
);
199 Status
= MmCopyToCaller(UnsafeReturnLength
, &ReturnLength
,
201 if (!NT_SUCCESS(Status
))
203 RtlFreeAnsiString(&AName
);
204 if (ExGetPreviousMode() != KernelMode
)
206 RtlFreeUnicodeString(&WName
);
209 RtlFreeUnicodeString(&WValue
);
215 memcpy(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
216 memcpy(UnsafeReturnLength
, &ReturnLength
, sizeof(ULONG
));
220 * Free temporary buffers.
222 RtlFreeAnsiString(&AName
);
223 if (ExGetPreviousMode() != KernelMode
)
225 RtlFreeUnicodeString(&WName
);
228 RtlFreeUnicodeString(&WValue
);
230 return(STATUS_SUCCESS
);
235 NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
236 IN PUNICODE_STRING UnsafeValue
)
238 UNICODE_STRING WName
;
240 UNICODE_STRING WValue
;
246 * Check for required privilege.
248 /* FIXME: Not implemented. */
251 * Copy the name to kernel space if necessary and convert it to ANSI.
253 if (ExGetPreviousMode() != KernelMode
)
255 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
256 if (!NT_SUCCESS(Status
))
260 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
261 if (!NT_SUCCESS(Status
))
268 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
269 if (!NT_SUCCESS(Status
))
276 * Copy the value to kernel space and convert to ANSI.
278 if (ExGetPreviousMode() != KernelMode
)
280 Status
= RtlCaptureUnicodeString(&WValue
, UnsafeValue
);
281 if (!NT_SUCCESS(Status
))
283 RtlFreeUnicodeString(&WName
);
284 RtlFreeAnsiString(&AName
);
287 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
288 if (!NT_SUCCESS(Status
))
290 RtlFreeUnicodeString(&WName
);
291 RtlFreeAnsiString(&AName
);
292 RtlFreeUnicodeString(&WValue
);
298 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
299 if (!NT_SUCCESS(Status
))
301 RtlFreeAnsiString(&AName
);
307 * Set the environment variable
309 Result
= HalSetEnvironmentVariable(AName
.Buffer
, AValue
.Buffer
);
312 * Free everything and return status.
314 RtlFreeAnsiString(&AName
);
315 RtlFreeAnsiString(&AValue
);
316 if (ExGetPreviousMode() != KernelMode
)
318 RtlFreeUnicodeString(&WName
);
319 RtlFreeUnicodeString(&WValue
);
324 return(STATUS_UNSUCCESSFUL
);
326 return(STATUS_SUCCESS
);
330 /* --- Query/Set System Information --- */
333 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
334 * so the stack is popped only in one place on x86 platform.
336 #define QSI_USE(n) QSI##n
338 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
340 #define SSI_USE(n) SSI##n
342 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
345 /* Class 0 - Basic Information */
346 QSI_DEF(SystemBasicInformation
)
348 PSYSTEM_BASIC_INFORMATION Sbi
349 = (PSYSTEM_BASIC_INFORMATION
) Buffer
;
351 *ReqSize
= sizeof (SYSTEM_BASIC_INFORMATION
);
353 * Check user buffer's size
355 if (Size
< sizeof (SYSTEM_BASIC_INFORMATION
))
357 return (STATUS_INFO_LENGTH_MISMATCH
);
360 Sbi
->MaximumIncrement
= KeMaximumIncrement
;
361 Sbi
->PhysicalPageSize
= PAGE_SIZE
; /* FIXME: it should be PAGE_SIZE */
362 Sbi
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
363 Sbi
->LowestPhysicalPage
= 0; /* FIXME */
364 Sbi
->HighestPhysicalPage
= MmStats
.NrTotalPages
; /* FIXME */
365 Sbi
->AllocationGranularity
= MM_VIRTMEM_GRANULARITY
; /* hard coded on Intel? */
366 Sbi
->LowestUserAddress
= 0x10000; /* Top of 64k */
367 Sbi
->HighestUserAddress
= (ULONG_PTR
)MmHighestUserAddress
;
368 Sbi
->ActiveProcessors
= KeActiveProcessors
;
369 Sbi
->NumberProcessors
= KeNumberProcessors
;
370 return (STATUS_SUCCESS
);
373 /* Class 1 - Processor Information */
374 QSI_DEF(SystemProcessorInformation
)
376 PSYSTEM_PROCESSOR_INFORMATION Spi
377 = (PSYSTEM_PROCESSOR_INFORMATION
) Buffer
;
379 *ReqSize
= sizeof (SYSTEM_PROCESSOR_INFORMATION
);
381 * Check user buffer's size
383 if (Size
< sizeof (SYSTEM_PROCESSOR_INFORMATION
))
385 return (STATUS_INFO_LENGTH_MISMATCH
);
387 Spi
->ProcessorArchitecture
= 0; /* Intel Processor */
388 Spi
->ProcessorLevel
= ((Ke386Cpuid
>> 8) & 0xf);
389 Spi
->ProcessorRevision
= (Ke386Cpuid
& 0xf) | ((Ke386Cpuid
<< 4) & 0xf00);
391 Spi
->FeatureBits
= Ke386CpuidFlags
;
393 DPRINT("Arch %d Level %d Rev 0x%x\n", Spi
->ProcessorArchitecture
,
394 Spi
->ProcessorLevel
, Spi
->ProcessorRevision
);
396 return (STATUS_SUCCESS
);
399 /* Class 2 - Performance Information */
400 QSI_DEF(SystemPerformanceInformation
)
402 PSYSTEM_PERFORMANCE_INFORMATION Spi
403 = (PSYSTEM_PERFORMANCE_INFORMATION
) Buffer
;
405 PEPROCESS TheIdleProcess
;
407 *ReqSize
= sizeof (SYSTEM_PERFORMANCE_INFORMATION
);
409 * Check user buffer's size
411 if (Size
< sizeof (SYSTEM_PERFORMANCE_INFORMATION
))
413 return (STATUS_INFO_LENGTH_MISMATCH
);
416 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
418 Spi
->IdleTime
.QuadPart
= TheIdleProcess
->Pcb
.KernelTime
* 100000LL;
420 Spi
->ReadTransferCount
.QuadPart
= IoReadTransferCount
;
421 Spi
->WriteTransferCount
.QuadPart
= IoWriteTransferCount
;
422 Spi
->OtherTransferCount
.QuadPart
= IoOtherTransferCount
;
423 Spi
->ReadOperationCount
= IoReadOperationCount
;
424 Spi
->WriteOperationCount
= IoWriteOperationCount
;
425 Spi
->OtherOperationCount
= IoOtherOperationCount
;
427 Spi
->AvailablePages
= MmStats
.NrFreePages
;
429 Add up all the used "Commitied" memory + pagefile.
430 Not sure this is right. 8^\
432 Spi
->TotalCommittedPages
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
+
433 MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
+
434 MiMemoryConsumers
[MC_CACHE
].PagesUsed
+
435 MiMemoryConsumers
[MC_USER
].PagesUsed
+
438 Add up the full system total + pagefile.
439 All this make Taskmgr happy but not sure it is the right numbers.
440 This too, fixes some of GlobalMemoryStatusEx numbers.
442 Spi
->TotalCommitLimit
= MmStats
.NrTotalPages
+ MiFreeSwapPages
+
445 Spi
->PeakCommitment
= 0; /* FIXME */
446 Spi
->PageFaults
= 0; /* FIXME */
447 Spi
->WriteCopyFaults
= 0; /* FIXME */
448 Spi
->TransitionFaults
= 0; /* FIXME */
449 Spi
->CacheTransitionFaults
= 0; /* FIXME */
450 Spi
->DemandZeroFaults
= 0; /* FIXME */
451 Spi
->PagesRead
= 0; /* FIXME */
452 Spi
->PageReadIos
= 0; /* FIXME */
453 Spi
->CacheReads
= 0; /* FIXME */
454 Spi
->CacheIos
= 0; /* FIXME */
455 Spi
->PagefilePagesWritten
= 0; /* FIXME */
456 Spi
->PagefilePageWriteIos
= 0; /* FIXME */
457 Spi
->MappedFilePagesWritten
= 0; /* FIXME */
458 Spi
->MappedFilePageWriteIos
= 0; /* FIXME */
460 Spi
->PagedPoolUsage
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
;
461 Spi
->PagedPoolAllocs
= 0; /* FIXME */
462 Spi
->PagedPoolFrees
= 0; /* FIXME */
463 Spi
->NonPagedPoolUsage
= MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
;
464 Spi
->NonPagedPoolAllocs
= 0; /* FIXME */
465 Spi
->NonPagedPoolFrees
= 0; /* FIXME */
467 Spi
->TotalFreeSystemPtes
= 0; /* FIXME */
469 Spi
->SystemCodePage
= MmStats
.NrSystemPages
; /* FIXME */
471 Spi
->TotalSystemDriverPages
= 0; /* FIXME */
472 Spi
->TotalSystemCodePages
= 0; /* FIXME */
473 Spi
->SmallNonPagedLookasideListAllocateHits
= 0; /* FIXME */
474 Spi
->SmallPagedLookasideListAllocateHits
= 0; /* FIXME */
475 Spi
->Reserved3
= 0; /* FIXME */
477 Spi
->MmSystemCachePage
= MiMemoryConsumers
[MC_CACHE
].PagesUsed
;
478 Spi
->PagedPoolPage
= MmPagedPoolSize
; /* FIXME */
480 Spi
->SystemDriverPage
= 0; /* FIXME */
481 Spi
->FastReadNoWait
= 0; /* FIXME */
482 Spi
->FastReadWait
= 0; /* FIXME */
483 Spi
->FastReadResourceMiss
= 0; /* FIXME */
484 Spi
->FastReadNotPossible
= 0; /* FIXME */
486 Spi
->FastMdlReadNoWait
= 0; /* FIXME */
487 Spi
->FastMdlReadWait
= 0; /* FIXME */
488 Spi
->FastMdlReadResourceMiss
= 0; /* FIXME */
489 Spi
->FastMdlReadNotPossible
= 0; /* FIXME */
491 Spi
->MapDataNoWait
= 0; /* FIXME */
492 Spi
->MapDataWait
= 0; /* FIXME */
493 Spi
->MapDataNoWaitMiss
= 0; /* FIXME */
494 Spi
->MapDataWaitMiss
= 0; /* FIXME */
496 Spi
->PinMappedDataCount
= 0; /* FIXME */
497 Spi
->PinReadNoWait
= 0; /* FIXME */
498 Spi
->PinReadWait
= 0; /* FIXME */
499 Spi
->PinReadNoWaitMiss
= 0; /* FIXME */
500 Spi
->PinReadWaitMiss
= 0; /* FIXME */
501 Spi
->CopyReadNoWait
= 0; /* FIXME */
502 Spi
->CopyReadWait
= 0; /* FIXME */
503 Spi
->CopyReadNoWaitMiss
= 0; /* FIXME */
504 Spi
->CopyReadWaitMiss
= 0; /* FIXME */
506 Spi
->MdlReadNoWait
= 0; /* FIXME */
507 Spi
->MdlReadWait
= 0; /* FIXME */
508 Spi
->MdlReadNoWaitMiss
= 0; /* FIXME */
509 Spi
->MdlReadWaitMiss
= 0; /* FIXME */
510 Spi
->ReadAheadIos
= 0; /* FIXME */
511 Spi
->LazyWriteIos
= 0; /* FIXME */
512 Spi
->LazyWritePages
= 0; /* FIXME */
513 Spi
->DataFlushes
= 0; /* FIXME */
514 Spi
->DataPages
= 0; /* FIXME */
515 Spi
->ContextSwitches
= 0; /* FIXME */
516 Spi
->FirstLevelTbFills
= 0; /* FIXME */
517 Spi
->SecondLevelTbFills
= 0; /* FIXME */
518 Spi
->SystemCalls
= 0; /* FIXME */
520 ObDereferenceObject(TheIdleProcess
);
522 return (STATUS_SUCCESS
);
525 /* Class 3 - Time Of Day Information */
526 QSI_DEF(SystemTimeOfDayInformation
)
528 LARGE_INTEGER CurrentTime
;
530 PSYSTEM_TIMEOFDAY_INFORMATION Sti
531 = (PSYSTEM_TIMEOFDAY_INFORMATION
) Buffer
;
533 *ReqSize
= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
);
535 * Check user buffer's size
537 if (Size
< sizeof (SYSTEM_TIMEOFDAY_INFORMATION
))
539 return (STATUS_INFO_LENGTH_MISMATCH
);
542 KeQuerySystemTime(&CurrentTime
);
544 Sti
->BootTime
= SystemBootTime
;
545 Sti
->CurrentTime
= CurrentTime
;
546 Sti
->TimeZoneBias
.QuadPart
= 0; /* FIXME */
547 Sti
->TimeZoneId
= 0; /* FIXME */
548 Sti
->Reserved
= 0; /* FIXME */
550 return (STATUS_SUCCESS
);
553 /* Class 4 - Path Information */
554 QSI_DEF(SystemPathInformation
)
556 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
557 DPRINT1("NtQuerySystemInformation - SystemPathInformation not implemented\n");
559 return (STATUS_BREAKPOINT
);
562 /* Class 5 - Process Information */
563 QSI_DEF(SystemProcessInformation
)
565 ULONG ovlSize
=0, nThreads
;
569 /* scan the process list */
571 PSYSTEM_PROCESSES Spi
572 = (PSYSTEM_PROCESSES
) Buffer
;
574 *ReqSize
= sizeof(SYSTEM_PROCESSES
);
576 if (Size
< sizeof(SYSTEM_PROCESSES
))
578 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
581 syspr
= PsGetNextProcess(NULL
);
583 pCur
= (unsigned char *)Spi
;
587 PSYSTEM_PROCESSES SpiCur
;
590 int inLen
=32; // image name len in bytes
591 PLIST_ENTRY current_entry
;
594 SpiCur
= (PSYSTEM_PROCESSES
)pCur
;
596 nThreads
= PsEnumThreadsByProcess(pr
);
598 // size of the structure for every process
599 curSize
= sizeof(SYSTEM_PROCESSES
)-sizeof(SYSTEM_THREADS
)+sizeof(SYSTEM_THREADS
)*nThreads
;
600 ovlSize
+= curSize
+inLen
;
605 ObDereferenceObject(pr
);
607 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
610 // fill system information
611 SpiCur
->NextEntryDelta
= curSize
+inLen
; // relative offset to the beginnnig of the next structure
612 SpiCur
->ThreadCount
= nThreads
;
613 SpiCur
->CreateTime
= pr
->CreateTime
;
614 SpiCur
->UserTime
.QuadPart
= pr
->Pcb
.UserTime
* 100000LL;
615 SpiCur
->KernelTime
.QuadPart
= pr
->Pcb
.KernelTime
* 100000LL;
616 SpiCur
->ProcessName
.Length
= strlen(pr
->ImageFileName
) * sizeof(WCHAR
);
617 SpiCur
->ProcessName
.MaximumLength
= inLen
;
618 SpiCur
->ProcessName
.Buffer
= (void*)(pCur
+curSize
);
620 // copy name to the end of the struct
621 RtlInitAnsiString(&imgName
, pr
->ImageFileName
);
622 RtlAnsiStringToUnicodeString(&SpiCur
->ProcessName
, &imgName
, FALSE
);
624 SpiCur
->BasePriority
= pr
->Pcb
.BasePriority
;
625 SpiCur
->ProcessId
= pr
->UniqueProcessId
;
626 SpiCur
->InheritedFromProcessId
= (DWORD
)(pr
->InheritedFromUniqueProcessId
);
627 SpiCur
->HandleCount
= ObpGetHandleCountByHandleTable(&pr
->HandleTable
);
628 SpiCur
->VmCounters
.PeakVirtualSize
= pr
->PeakVirtualSize
;
629 SpiCur
->VmCounters
.VirtualSize
= pr
->VirtualSize
.QuadPart
;
630 SpiCur
->VmCounters
.PageFaultCount
= pr
->LastFaultCount
;
631 SpiCur
->VmCounters
.PeakWorkingSetSize
= pr
->Vm
.PeakWorkingSetSize
; // Is this right using ->Vm. here ?
632 SpiCur
->VmCounters
.WorkingSetSize
= pr
->Vm
.WorkingSetSize
; // Is this right using ->Vm. here ?
633 SpiCur
->VmCounters
.QuotaPeakPagedPoolUsage
=
634 pr
->QuotaPeakPoolUsage
[0];
635 SpiCur
->VmCounters
.QuotaPagedPoolUsage
=
636 pr
->QuotaPoolUsage
[0];
637 SpiCur
->VmCounters
.QuotaPeakNonPagedPoolUsage
=
638 pr
->QuotaPeakPoolUsage
[1];
639 SpiCur
->VmCounters
.QuotaNonPagedPoolUsage
=
640 pr
->QuotaPoolUsage
[1];
641 SpiCur
->VmCounters
.PagefileUsage
= pr
->PagefileUsage
; // FIXME
642 SpiCur
->VmCounters
.PeakPagefileUsage
= pr
->PeakPagefileUsage
;
643 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
644 // doesn't seem to contain any equivalent field
645 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
647 current_entry
= pr
->ThreadListHead
.Flink
;
648 while (current_entry
!= &pr
->ThreadListHead
)
650 current
= CONTAINING_RECORD(current_entry
, ETHREAD
,
653 SpiCur
->Threads
[i
].KernelTime
.QuadPart
= current
->Tcb
.KernelTime
* 100000LL;
654 SpiCur
->Threads
[i
].UserTime
.QuadPart
= current
->Tcb
.UserTime
* 100000LL;
655 // SpiCur->Threads[i].CreateTime = current->CreateTime;
656 SpiCur
->Threads
[i
].WaitTime
= current
->Tcb
.WaitTime
;
657 SpiCur
->Threads
[i
].StartAddress
= (PVOID
) current
->StartAddress
;
658 SpiCur
->Threads
[i
].ClientId
= current
->Cid
;
659 SpiCur
->Threads
[i
].Priority
= current
->Tcb
.Priority
;
660 SpiCur
->Threads
[i
].BasePriority
= current
->Tcb
.BasePriority
;
661 SpiCur
->Threads
[i
].ContextSwitchCount
= current
->Tcb
.ContextSwitches
;
662 SpiCur
->Threads
[i
].State
= current
->Tcb
.State
;
663 SpiCur
->Threads
[i
].WaitReason
= current
->Tcb
.WaitReason
;
665 current_entry
= current_entry
->Flink
;
668 pr
= PsGetNextProcess(pr
);
670 if ((pr
== syspr
) || (pr
== NULL
))
672 SpiCur
->NextEntryDelta
= 0;
676 pCur
= pCur
+ curSize
+ inLen
;
677 } while ((pr
!= syspr
) && (pr
!= NULL
));
682 ObDereferenceObject(pr
);
684 return (STATUS_SUCCESS
);
687 /* Class 6 - Call Count Information */
688 QSI_DEF(SystemCallCountInformation
)
691 DPRINT1("NtQuerySystemInformation - SystemCallCountInformation not implemented\n");
692 return (STATUS_NOT_IMPLEMENTED
);
695 /* Class 7 - Device Information */
696 QSI_DEF(SystemDeviceInformation
)
698 PSYSTEM_DEVICE_INFORMATION Sdi
699 = (PSYSTEM_DEVICE_INFORMATION
) Buffer
;
700 PCONFIGURATION_INFORMATION ConfigInfo
;
702 *ReqSize
= sizeof (SYSTEM_DEVICE_INFORMATION
);
704 * Check user buffer's size
706 if (Size
< sizeof (SYSTEM_DEVICE_INFORMATION
))
708 return (STATUS_INFO_LENGTH_MISMATCH
);
711 ConfigInfo
= IoGetConfigurationInformation ();
713 Sdi
->NumberOfDisks
= ConfigInfo
->DiskCount
;
714 Sdi
->NumberOfFloppies
= ConfigInfo
->FloppyCount
;
715 Sdi
->NumberOfCdRoms
= ConfigInfo
->CdRomCount
;
716 Sdi
->NumberOfTapes
= ConfigInfo
->TapeCount
;
717 Sdi
->NumberOfSerialPorts
= ConfigInfo
->SerialCount
;
718 Sdi
->NumberOfParallelPorts
= ConfigInfo
->ParallelCount
;
720 return (STATUS_SUCCESS
);
723 /* Class 8 - Processor Performance Information */
724 QSI_DEF(SystemProcessorPerformanceInformation
)
726 PSYSTEM_PROCESSORTIME_INFO Spi
727 = (PSYSTEM_PROCESSORTIME_INFO
) Buffer
;
733 *ReqSize
= KeNumberProcessors
* sizeof (SYSTEM_PROCESSORTIME_INFO
);
735 * Check user buffer's size
737 if (Size
< KeNumberProcessors
* sizeof(SYSTEM_PROCESSORTIME_INFO
))
739 return (STATUS_INFO_LENGTH_MISMATCH
);
742 CurrentTime
.QuadPart
= KeQueryInterruptTime();
743 Pcr
= (PKPCR
)KPCR_BASE
;
744 for (i
= 0; i
< KeNumberProcessors
; i
++)
747 Spi
->TotalProcessorRunTime
.QuadPart
= (Pcr
->PrcbData
.IdleThread
->KernelTime
+ Pcr
->PrcbData
.IdleThread
->UserTime
) * 100000LL; // IdleTime
748 Spi
->TotalProcessorTime
.QuadPart
= Pcr
->PrcbData
.KernelTime
* 100000LL; // KernelTime
749 Spi
->TotalProcessorUserTime
.QuadPart
= Pcr
->PrcbData
.UserTime
* 100000LL;
750 Spi
->TotalDPCTime
.QuadPart
= Pcr
->PrcbData
.DpcTime
* 100000LL;
751 Spi
->TotalInterruptTime
.QuadPart
= Pcr
->PrcbData
.InterruptTime
* 100000LL;
752 Spi
->TotalInterrupts
= Pcr
->PrcbData
.InterruptCount
; // Interrupt Count
755 Pcr
= (PKPCR
)((ULONG_PTR
)Pcr
+ PAGE_SIZE
);
758 return (STATUS_SUCCESS
);
761 /* Class 9 - Flags Information */
762 QSI_DEF(SystemFlagsInformation
)
764 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
766 * ReqSize
= sizeof (SYSTEM_FLAGS_INFORMATION
);
767 return (STATUS_INFO_LENGTH_MISMATCH
);
769 ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
= NtGlobalFlag
;
770 return (STATUS_SUCCESS
);
773 SSI_DEF(SystemFlagsInformation
)
775 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
777 return (STATUS_INFO_LENGTH_MISMATCH
);
779 NtGlobalFlag
= ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
;
780 return (STATUS_SUCCESS
);
783 /* Class 10 - Call Time Information */
784 QSI_DEF(SystemCallTimeInformation
)
787 DPRINT1("NtQuerySystemInformation - SystemCallTimeInformation not implemented\n");
788 return (STATUS_NOT_IMPLEMENTED
);
791 /* Class 11 - Module Information */
792 QSI_DEF(SystemModuleInformation
)
794 return LdrpQueryModuleInformation(Buffer
, Size
, ReqSize
);
797 /* Class 12 - Locks Information */
798 QSI_DEF(SystemLocksInformation
)
801 DPRINT1("NtQuerySystemInformation - SystemLocksInformation not implemented\n");
802 return (STATUS_NOT_IMPLEMENTED
);
805 /* Class 13 - Stack Trace Information */
806 QSI_DEF(SystemStackTraceInformation
)
809 DPRINT1("NtQuerySystemInformation - SystemStackTraceInformation not implemented\n");
810 return (STATUS_NOT_IMPLEMENTED
);
813 /* Class 14 - Paged Pool Information */
814 QSI_DEF(SystemPagedPoolInformation
)
817 DPRINT1("NtQuerySystemInformation - SystemPagedPoolInformation not implemented\n");
818 return (STATUS_NOT_IMPLEMENTED
);
821 /* Class 15 - Non Paged Pool Information */
822 QSI_DEF(SystemNonPagedPoolInformation
)
825 DPRINT1("NtQuerySystemInformation - SystemNonPagedPoolInformation not implemented\n");
826 return (STATUS_NOT_IMPLEMENTED
);
829 /* Class 16 - Handle Information */
830 QSI_DEF(SystemHandleInformation
)
833 DPRINT1("NtQuerySystemInformation - SystemHandleInformation not implemented\n");
834 return (STATUS_NOT_IMPLEMENTED
);
837 /* Class 17 - Information */
838 QSI_DEF(SystemObjectInformation
)
841 DPRINT1("NtQuerySystemInformation - SystemObjectInformation not implemented\n");
842 return (STATUS_NOT_IMPLEMENTED
);
845 /* Class 18 - Information */
846 QSI_DEF(SystemPageFileInformation
)
848 SYSTEM_PAGEFILE_INFORMATION
*Spfi
= (SYSTEM_PAGEFILE_INFORMATION
*) Buffer
;
850 if (Size
< sizeof (SYSTEM_PAGEFILE_INFORMATION
))
852 * ReqSize
= sizeof (SYSTEM_PAGEFILE_INFORMATION
);
853 return (STATUS_INFO_LENGTH_MISMATCH
);
856 UNICODE_STRING FileName
; /* FIXME */
859 Spfi
->NextEntryOffset
= 0;
861 Spfi
->TotalSize
= MiFreeSwapPages
+ MiUsedSwapPages
;
862 Spfi
->TotalInUse
= MiUsedSwapPages
;
863 Spfi
->PeakUsage
= MiUsedSwapPages
; /* FIXME */
864 Spfi
->PageFileName
= FileName
;
865 return (STATUS_SUCCESS
);
868 /* Class 19 - Vdm Instemul Information */
869 QSI_DEF(SystemVdmInstemulInformation
)
872 DPRINT1("NtQuerySystemInformation - SystemVdmInstemulInformation not implemented\n");
873 return (STATUS_NOT_IMPLEMENTED
);
876 /* Class 20 - Vdm Bop Information */
877 QSI_DEF(SystemVdmBopInformation
)
880 DPRINT1("NtQuerySystemInformation - SystemVdmBopInformation not implemented\n");
881 return (STATUS_NOT_IMPLEMENTED
);
884 /* Class 21 - File Cache Information */
885 QSI_DEF(SystemFileCacheInformation
)
887 SYSTEM_CACHE_INFORMATION
*Sci
= (SYSTEM_CACHE_INFORMATION
*) Buffer
;
889 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
891 * ReqSize
= sizeof (SYSTEM_CACHE_INFORMATION
);
892 return (STATUS_INFO_LENGTH_MISMATCH
);
894 /* Return the Byte size not the page size. */
896 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
;
898 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
; /* FIXME */
900 Sci
->PageFaultCount
= 0; /* FIXME */
901 Sci
->MinimumWorkingSet
= 0; /* FIXME */
902 Sci
->MaximumWorkingSet
= 0; /* FIXME */
903 Sci
->TransitionSharedPages
= 0; /* FIXME */
904 Sci
->TransitionSharedPagesPeak
= 0; /* FIXME */
906 return (STATUS_SUCCESS
);
909 SSI_DEF(SystemFileCacheInformation
)
911 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
913 return (STATUS_INFO_LENGTH_MISMATCH
);
916 DPRINT1("NtSetSystemInformation - SystemFileCacheInformation not implemented\n");
917 return (STATUS_NOT_IMPLEMENTED
);
920 /* Class 22 - Pool Tag Information */
921 QSI_DEF(SystemPoolTagInformation
)
924 DPRINT1("NtQuerySystemInformation - SystemPoolTagInformation not implemented\n");
925 return (STATUS_NOT_IMPLEMENTED
);
928 /* Class 23 - Interrupt Information */
929 QSI_DEF(SystemInterruptInformation
)
932 DPRINT1("NtQuerySystemInformation - SystemInterruptInformation not implemented\n");
933 return (STATUS_NOT_IMPLEMENTED
);
936 /* Class 24 - DPC Behaviour Information */
937 QSI_DEF(SystemDpcBehaviourInformation
)
940 DPRINT1("NtQuerySystemInformation - SystemDpcBehaviourInformation not implemented\n");
941 return (STATUS_NOT_IMPLEMENTED
);
944 SSI_DEF(SystemDpcBehaviourInformation
)
947 DPRINT1("NtSetSystemInformation - SystemDpcBehaviourInformation not implemented\n");
948 return (STATUS_NOT_IMPLEMENTED
);
951 /* Class 25 - Full Memory Information */
952 QSI_DEF(SystemFullMemoryInformation
)
954 PULONG Spi
= (PULONG
) Buffer
;
956 PEPROCESS TheIdleProcess
;
958 * ReqSize
= sizeof (ULONG
);
960 if (sizeof (ULONG
) != Size
)
962 return (STATUS_INFO_LENGTH_MISMATCH
);
964 DPRINT("SystemFullMemoryInformation\n");
966 PsLookupProcessByProcessId((PVOID
) 1, &TheIdleProcess
);
968 DPRINT("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
969 TheIdleProcess
->UniqueProcessId
,
970 TheIdleProcess
->Pcb
.KernelTime
,
975 MmPrintMemoryStatistic();
978 *Spi
= MiMemoryConsumers
[MC_USER
].PagesUsed
;
980 ObDereferenceObject(TheIdleProcess
);
982 return (STATUS_SUCCESS
);
985 /* Class 26 - Load Image */
986 SSI_DEF(SystemLoadImage
)
988 PSYSTEM_LOAD_IMAGE Sli
= (PSYSTEM_LOAD_IMAGE
)Buffer
;
990 if (sizeof(SYSTEM_LOAD_IMAGE
) != Size
)
992 return(STATUS_INFO_LENGTH_MISMATCH
);
995 return(LdrpLoadImage(&Sli
->ModuleName
,
997 &Sli
->SectionPointer
,
999 &Sli
->ExportDirectory
));
1002 /* Class 27 - Unload Image */
1003 SSI_DEF(SystemUnloadImage
)
1005 PSYSTEM_UNLOAD_IMAGE Sui
= (PSYSTEM_UNLOAD_IMAGE
)Buffer
;
1007 if (sizeof(SYSTEM_UNLOAD_IMAGE
) != Size
)
1009 return(STATUS_INFO_LENGTH_MISMATCH
);
1012 return(LdrpUnloadImage(Sui
->ModuleBase
));
1015 /* Class 28 - Time Adjustment Information */
1016 QSI_DEF(SystemTimeAdjustmentInformation
)
1018 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
1020 * ReqSize
= sizeof (SYSTEM_SET_TIME_ADJUSTMENT
);
1021 return (STATUS_INFO_LENGTH_MISMATCH
);
1024 DPRINT1("NtQuerySystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1025 return (STATUS_NOT_IMPLEMENTED
);
1028 SSI_DEF(SystemTimeAdjustmentInformation
)
1030 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
1032 return (STATUS_INFO_LENGTH_MISMATCH
);
1035 DPRINT1("NtSetSystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1036 return (STATUS_NOT_IMPLEMENTED
);
1039 /* Class 29 - Summary Memory Information */
1040 QSI_DEF(SystemSummaryMemoryInformation
)
1043 DPRINT1("NtQuerySystemInformation - SystemSummaryMemoryInformation not implemented\n");
1044 return (STATUS_NOT_IMPLEMENTED
);
1047 /* Class 30 - Next Event Id Information */
1048 QSI_DEF(SystemNextEventIdInformation
)
1051 DPRINT1("NtQuerySystemInformation - SystemNextEventIdInformation not implemented\n");
1052 return (STATUS_NOT_IMPLEMENTED
);
1055 /* Class 31 - Event Ids Information */
1056 QSI_DEF(SystemEventIdsInformation
)
1059 DPRINT1("NtQuerySystemInformation - SystemEventIdsInformation not implemented\n");
1060 return (STATUS_NOT_IMPLEMENTED
);
1063 /* Class 32 - Crash Dump Information */
1064 QSI_DEF(SystemCrashDumpInformation
)
1067 DPRINT1("NtQuerySystemInformation - SystemCrashDumpInformation not implemented\n");
1068 return (STATUS_NOT_IMPLEMENTED
);
1071 /* Class 33 - Exception Information */
1072 QSI_DEF(SystemExceptionInformation
)
1075 DPRINT1("NtQuerySystemInformation - SystemExceptionInformation not implemented\n");
1076 return (STATUS_NOT_IMPLEMENTED
);
1079 /* Class 34 - Crash Dump State Information */
1080 QSI_DEF(SystemCrashDumpStateInformation
)
1083 DPRINT1("NtQuerySystemInformation - SystemCrashDumpStateInformation not implemented\n");
1084 return (STATUS_NOT_IMPLEMENTED
);
1087 /* Class 35 - Kernel Debugger Information */
1088 QSI_DEF(SystemKernelDebuggerInformation
)
1091 DPRINT1("NtQuerySystemInformation - SystemKernelDebuggerInformation not implemented\n");
1092 return (STATUS_NOT_IMPLEMENTED
);
1095 /* Class 36 - Context Switch Information */
1096 QSI_DEF(SystemContextSwitchInformation
)
1099 DPRINT1("NtQuerySystemInformation - SystemContextSwitchInformation not implemented\n");
1100 return (STATUS_NOT_IMPLEMENTED
);
1103 /* Class 37 - Registry Quota Information */
1104 QSI_DEF(SystemRegistryQuotaInformation
)
1106 PSYSTEM_REGISTRY_QUOTA_INFORMATION srqi
= (PSYSTEM_REGISTRY_QUOTA_INFORMATION
) Buffer
;
1108 *ReqSize
= sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION
);
1109 if (Size
< sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION
))
1111 return STATUS_INFO_LENGTH_MISMATCH
;
1114 DPRINT1("Faking max registry size of 32 MB\n");
1115 srqi
->RegistryQuotaAllowed
= 0x2000000;
1116 srqi
->RegistryQuotaUsed
= 0x200000;
1117 srqi
->Reserved1
= (void*)0x200000;
1119 return STATUS_SUCCESS
;
1122 SSI_DEF(SystemRegistryQuotaInformation
)
1125 DPRINT1("NtSetSystemInformation - SystemRegistryQuotaInformation not implemented\n");
1126 return (STATUS_NOT_IMPLEMENTED
);
1129 /* Class 38 - Load And Call Image */
1130 SSI_DEF(SystemLoadAndCallImage
)
1132 PSYSTEM_LOAD_AND_CALL_IMAGE Slci
= (PSYSTEM_LOAD_AND_CALL_IMAGE
)Buffer
;
1134 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE
) != Size
)
1136 return(STATUS_INFO_LENGTH_MISMATCH
);
1139 return(LdrpLoadAndCallImage(&Slci
->ModuleName
));
1142 /* Class 39 - Priority Separation */
1143 SSI_DEF(SystemPrioritySeperation
)
1146 DPRINT1("NtSetSystemInformation - SystemPrioritySeperation not implemented\n");
1147 return (STATUS_NOT_IMPLEMENTED
);
1150 /* Class 40 - Plug Play Bus Information */
1151 QSI_DEF(SystemPlugPlayBusInformation
)
1154 DPRINT1("NtQuerySystemInformation - SystemPlugPlayBusInformation not implemented\n");
1155 return (STATUS_NOT_IMPLEMENTED
);
1158 /* Class 41 - Dock Information */
1159 QSI_DEF(SystemDockInformation
)
1162 DPRINT1("NtQuerySystemInformation - SystemDockInformation not implemented\n");
1163 return (STATUS_NOT_IMPLEMENTED
);
1166 /* Class 42 - Power Information */
1167 QSI_DEF(SystemPowerInformation
)
1170 DPRINT1("NtQuerySystemInformation - SystemPowerInformation not implemented\n");
1171 return (STATUS_NOT_IMPLEMENTED
);
1174 /* Class 43 - Processor Speed Information */
1175 QSI_DEF(SystemProcessorSpeedInformation
)
1178 DPRINT1("NtQuerySystemInformation - SystemProcessorSpeedInformation not implemented\n");
1179 return (STATUS_NOT_IMPLEMENTED
);
1182 /* Class 44 - Current Time Zone Information */
1183 QSI_DEF(SystemCurrentTimeZoneInformation
)
1185 * ReqSize
= sizeof (TIME_ZONE_INFORMATION
);
1187 if (sizeof (TIME_ZONE_INFORMATION
) != Size
)
1189 return STATUS_INFO_LENGTH_MISMATCH
;
1192 /* Copy the time zone information struct */
1195 sizeof(TIME_ZONE_INFORMATION
));
1197 return STATUS_SUCCESS
;
1201 SSI_DEF(SystemCurrentTimeZoneInformation
)
1203 /* Check user buffer's size */
1204 if (Size
< sizeof (TIME_ZONE_INFORMATION
))
1206 return STATUS_INFO_LENGTH_MISMATCH
;
1209 /* Copy the time zone information struct */
1210 memcpy(&ExpTimeZoneInfo
,
1211 (TIME_ZONE_INFORMATION
*)Buffer
,
1212 sizeof(TIME_ZONE_INFORMATION
));
1214 return STATUS_SUCCESS
;
1218 /* Class 45 - Lookaside Information */
1219 QSI_DEF(SystemLookasideInformation
)
1222 DPRINT1("NtQuerySystemInformation - SystemLookasideInformation not implemented\n");
1223 return (STATUS_NOT_IMPLEMENTED
);
1227 /* Class 46 - Set time slip event */
1228 SSI_DEF(SystemSetTimeSlipEvent
)
1231 DPRINT1("NtSetSystemInformation - SystemSetTimSlipEvent not implemented\n");
1232 return (STATUS_NOT_IMPLEMENTED
);
1236 /* Class 47 - Create a new session (TSE) */
1237 SSI_DEF(SystemCreateSession
)
1240 DPRINT1("NtSetSystemInformation - SystemCreateSession not implemented\n");
1241 return (STATUS_NOT_IMPLEMENTED
);
1245 /* Class 48 - Delete an existing session (TSE) */
1246 SSI_DEF(SystemDeleteSession
)
1249 DPRINT1("NtSetSystemInformation - SystemDeleteSession not implemented\n");
1250 return (STATUS_NOT_IMPLEMENTED
);
1254 /* Class 49 - UNKNOWN */
1255 QSI_DEF(SystemInvalidInfoClass4
)
1258 DPRINT1("NtQuerySystemInformation - SystemInvalidInfoClass4 not implemented\n");
1259 return (STATUS_NOT_IMPLEMENTED
);
1263 /* Class 50 - System range start address */
1264 QSI_DEF(SystemRangeStartInformation
)
1267 DPRINT1("NtQuerySystemInformation - SystemRangeStartInformation not implemented\n");
1268 return (STATUS_NOT_IMPLEMENTED
);
1272 /* Class 51 - Driver verifier information */
1273 QSI_DEF(SystemVerifierInformation
)
1276 DPRINT1("NtQuerySystemInformation - SystemVerifierInformation not implemented\n");
1277 return (STATUS_NOT_IMPLEMENTED
);
1281 SSI_DEF(SystemVerifierInformation
)
1284 DPRINT1("NtSetSystemInformation - SystemVerifierInformation not implemented\n");
1285 return (STATUS_NOT_IMPLEMENTED
);
1289 /* Class 52 - Add a driver verifier */
1290 SSI_DEF(SystemAddVerifier
)
1293 DPRINT1("NtSetSystemInformation - SystemAddVerifier not implemented\n");
1294 return (STATUS_NOT_IMPLEMENTED
);
1298 /* Class 53 - A session's processes */
1299 QSI_DEF(SystemSessionProcessesInformation
)
1302 DPRINT1("NtQuerySystemInformation - SystemSessionProcessInformation not implemented\n");
1303 return (STATUS_NOT_IMPLEMENTED
);
1307 /* Query/Set Calls Table */
1311 NTSTATUS (* Query
) (PVOID
,ULONG
,PULONG
);
1312 NTSTATUS (* Set
) (PVOID
,ULONG
);
1319 // XX unknown behaviour
1321 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1322 #define SI_QX(n) {QSI_USE(n),NULL}
1323 #define SI_XS(n) {NULL,SSI_USE(n)}
1324 #define SI_XX(n) {NULL,NULL}
1330 SI_QX(SystemBasicInformation
),
1331 SI_QX(SystemProcessorInformation
),
1332 SI_QX(SystemPerformanceInformation
),
1333 SI_QX(SystemTimeOfDayInformation
),
1334 SI_QX(SystemPathInformation
), /* should be SI_XX */
1335 SI_QX(SystemProcessInformation
),
1336 SI_QX(SystemCallCountInformation
),
1337 SI_QX(SystemDeviceInformation
),
1338 SI_QX(SystemProcessorPerformanceInformation
),
1339 SI_QS(SystemFlagsInformation
),
1340 SI_QX(SystemCallTimeInformation
), /* should be SI_XX */
1341 SI_QX(SystemModuleInformation
),
1342 SI_QX(SystemLocksInformation
),
1343 SI_QX(SystemStackTraceInformation
), /* should be SI_XX */
1344 SI_QX(SystemPagedPoolInformation
), /* should be SI_XX */
1345 SI_QX(SystemNonPagedPoolInformation
), /* should be SI_XX */
1346 SI_QX(SystemHandleInformation
),
1347 SI_QX(SystemObjectInformation
),
1348 SI_QX(SystemPageFileInformation
),
1349 SI_QX(SystemVdmInstemulInformation
),
1350 SI_QX(SystemVdmBopInformation
), /* it should be SI_XX */
1351 SI_QS(SystemFileCacheInformation
),
1352 SI_QX(SystemPoolTagInformation
),
1353 SI_QX(SystemInterruptInformation
),
1354 SI_QS(SystemDpcBehaviourInformation
),
1355 SI_QX(SystemFullMemoryInformation
), /* it should be SI_XX */
1356 SI_XS(SystemLoadImage
),
1357 SI_XS(SystemUnloadImage
),
1358 SI_QS(SystemTimeAdjustmentInformation
),
1359 SI_QX(SystemSummaryMemoryInformation
), /* it should be SI_XX */
1360 SI_QX(SystemNextEventIdInformation
), /* it should be SI_XX */
1361 SI_QX(SystemEventIdsInformation
), /* it should be SI_XX */
1362 SI_QX(SystemCrashDumpInformation
),
1363 SI_QX(SystemExceptionInformation
),
1364 SI_QX(SystemCrashDumpStateInformation
),
1365 SI_QX(SystemKernelDebuggerInformation
),
1366 SI_QX(SystemContextSwitchInformation
),
1367 SI_QS(SystemRegistryQuotaInformation
),
1368 SI_XS(SystemLoadAndCallImage
),
1369 SI_XS(SystemPrioritySeperation
),
1370 SI_QX(SystemPlugPlayBusInformation
), /* it should be SI_XX */
1371 SI_QX(SystemDockInformation
), /* it should be SI_XX */
1372 SI_QX(SystemPowerInformation
), /* it should be SI_XX */
1373 SI_QX(SystemProcessorSpeedInformation
), /* it should be SI_XX */
1374 SI_QS(SystemCurrentTimeZoneInformation
), /* it should be SI_QX */
1375 SI_QX(SystemLookasideInformation
),
1376 SI_XS(SystemSetTimeSlipEvent
),
1377 SI_XS(SystemCreateSession
),
1378 SI_XS(SystemDeleteSession
),
1379 SI_QX(SystemInvalidInfoClass4
), /* it should be SI_XX */
1380 SI_QX(SystemRangeStartInformation
),
1381 SI_QS(SystemVerifierInformation
),
1382 SI_XS(SystemAddVerifier
),
1383 SI_QX(SystemSessionProcessesInformation
)
1391 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1392 OUT PVOID UnsafeSystemInformation
,
1394 OUT PULONG UnsafeResultLength
)
1397 PVOID SystemInformation
;
1401 /* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
1402 SystemInformationClass );
1404 /*if (ExGetPreviousMode() == KernelMode)
1406 SystemInformation
= UnsafeSystemInformation
;
1410 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1411 if (SystemInformation == NULL)
1413 return(STATUS_NO_MEMORY);
1417 /* Clear user buffer. */
1418 RtlZeroMemory(SystemInformation
, Length
);
1421 * Check the request is valid.
1423 if ((SystemInformationClass
>= SystemInformationClassMin
) &&
1424 (SystemInformationClass
< SystemInformationClassMax
))
1426 if (NULL
!= CallQS
[SystemInformationClass
].Query
)
1429 * Hand the request to a subhandler.
1431 FStatus
= CallQS
[SystemInformationClass
].Query(SystemInformation
,
1434 /*if (ExGetPreviousMode() != KernelMode)
1436 Status = MmCopyToCaller(UnsafeSystemInformation,
1439 ExFreePool(SystemInformation);
1440 if (!NT_SUCCESS(Status))
1445 if (UnsafeResultLength
!= NULL
)
1447 /*if (ExGetPreviousMode() == KernelMode)
1449 *UnsafeResultLength = ResultLength;
1453 Status
= MmCopyToCaller(UnsafeResultLength
,
1456 if (!NT_SUCCESS(Status
))
1465 return (STATUS_INVALID_INFO_CLASS
);
1471 NtSetSystemInformation (
1472 IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1473 IN PVOID SystemInformation
,
1474 IN ULONG SystemInformationLength
1478 * If called from user mode, check
1479 * possible unsafe arguments.
1482 if (KernelMode
!= KeGetPreviousMode())
1486 // SystemInformation,
1496 * Check the request is valid.
1498 if ( (SystemInformationClass
>= SystemInformationClassMin
)
1499 && (SystemInformationClass
< SystemInformationClassMax
)
1502 if (NULL
!= CallQS
[SystemInformationClass
].Set
)
1505 * Hand the request to a subhandler.
1507 return CallQS
[SystemInformationClass
].Set (
1509 SystemInformationLength
1513 return (STATUS_INVALID_INFO_CLASS
);
1519 NtFlushInstructionCache (
1520 IN HANDLE ProcessHandle
,
1521 IN PVOID BaseAddress
,
1522 IN UINT NumberOfBytesToFlush
1526 return(STATUS_NOT_IMPLEMENTED
);