3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/sysinfo.c
6 * PURPOSE: System information functions
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 * Aleksey Bragin (aleksey@studiocerebral.com)
12 /* INCLUDES *****************************************************************/
16 #include <internal/debug.h>
18 extern PEPROCESS PsIdleProcess
;
19 extern ULONG NtGlobalFlag
; /* FIXME: it should go in a ddk/?.h */
20 ULONGLONG STDCALL
KeQueryInterruptTime(VOID
);
22 VOID
MmPrintMemoryStatistic(VOID
);
24 FAST_MUTEX ExpEnvironmentLock
;
25 ERESOURCE ExpFirmwareTableResource
;
26 LIST_ENTRY ExpFirmwareTableProviderListHead
;
28 /* FUNCTIONS *****************************************************************/
33 #undef ExGetPreviousMode
36 ExGetPreviousMode (VOID
)
38 return KeGetPreviousMode();
50 PHANDLE Handle OPTIONAL
61 ExGetCurrentProcessorCpuUsage (
69 Prcb
= KeGetCurrentPrcb();
71 ScaledIdle
= Prcb
->IdleThread
->KernelTime
* 100;
72 TotalTime
= Prcb
->KernelTime
+ Prcb
->UserTime
;
74 *CpuUsage
= (ULONG
)(100 - (ScaledIdle
/ TotalTime
));
84 ExGetCurrentProcessorCounts (
85 PULONG ThreadKernelTime
,
87 PULONG ProcessorNumber
92 Prcb
= KeGetCurrentPrcb();
94 *ThreadKernelTime
= Prcb
->KernelTime
+ Prcb
->UserTime
;
95 *TotalCpuTime
= Prcb
->CurrentThread
->KernelTime
;
96 *ProcessorNumber
= KeGetCurrentProcessorNumber();
104 ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature
)
106 /* Quick check to see if it exists at all */
107 if (ProcessorFeature
>= PROCESSOR_FEATURE_MAX
) return(FALSE
);
109 /* Return our support for it */
110 return(SharedUserData
->ProcessorFeatures
[ProcessorFeature
]);
118 ExVerifySuite(SUITE_TYPE SuiteType
)
120 if (SuiteType
== Personal
) return TRUE
;
125 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName
,
126 OUT PWSTR ValueBuffer
,
127 IN ULONG ValueBufferLength
,
128 IN OUT PULONG ReturnLength OPTIONAL
)
131 UNICODE_STRING WName
;
135 UNICODE_STRING WValue
;
136 KPROCESSOR_MODE PreviousMode
;
137 NTSTATUS Status
= STATUS_SUCCESS
;
141 PreviousMode
= ExGetPreviousMode();
143 if(PreviousMode
!= KernelMode
)
147 ProbeForRead(VariableName
,
148 sizeof(UNICODE_STRING
),
150 ProbeForWrite(ValueBuffer
,
153 if(ReturnLength
!= NULL
)
155 ProbeForWriteUlong(ReturnLength
);
158 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
160 Status
= _SEH_GetExceptionCode();
164 if(!NT_SUCCESS(Status
))
171 * Copy the name to kernel space if necessary and convert it to ANSI.
173 Status
= ProbeAndCaptureUnicodeString(&WName
,
176 if(NT_SUCCESS(Status
))
179 * according to ntinternals the SeSystemEnvironmentName privilege is required!
181 if(!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege
,
184 ReleaseCapturedUnicodeString(&WName
,
186 DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
187 return STATUS_PRIVILEGE_NOT_HELD
;
191 * convert the value name to ansi
193 Status
= RtlUnicodeStringToAnsiString(&AName
, &WName
, TRUE
);
194 ReleaseCapturedUnicodeString(&WName
,
196 if(!NT_SUCCESS(Status
))
202 * Create a temporary buffer for the value
204 Value
= ExAllocatePool(NonPagedPool
, ValueBufferLength
);
207 RtlFreeAnsiString(&AName
);
208 return STATUS_INSUFFICIENT_RESOURCES
;
212 * Get the environment variable
214 Result
= HalGetEnvironmentVariable(AName
.Buffer
,
215 (USHORT
)ValueBufferLength
,
219 RtlFreeAnsiString(&AName
);
221 return STATUS_UNSUCCESSFUL
;
225 * Convert the result to UNICODE, protect with SEH in case the value buffer
226 * isn't NULL-terminated!
230 RtlInitAnsiString(&AValue
, Value
);
231 Status
= RtlAnsiStringToUnicodeString(&WValue
, &AValue
, TRUE
);
233 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
235 Status
= _SEH_GetExceptionCode();
239 if(NT_SUCCESS(Status
))
242 * Copy the result back to the caller.
246 RtlCopyMemory(ValueBuffer
, WValue
.Buffer
, WValue
.Length
);
247 ValueBuffer
[WValue
.Length
/ sizeof(WCHAR
)] = L
'\0';
248 if(ReturnLength
!= NULL
)
250 *ReturnLength
= WValue
.Length
+ sizeof(WCHAR
);
253 Status
= STATUS_SUCCESS
;
255 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
257 Status
= _SEH_GetExceptionCode();
263 * Cleanup allocated resources.
265 RtlFreeAnsiString(&AName
);
274 NtSetSystemEnvironmentValue (IN PUNICODE_STRING VariableName
,
275 IN PUNICODE_STRING Value
)
277 UNICODE_STRING CapturedName
, CapturedValue
;
278 ANSI_STRING AName
, AValue
;
279 KPROCESSOR_MODE PreviousMode
;
284 PreviousMode
= ExGetPreviousMode();
287 * Copy the strings to kernel space if necessary
289 Status
= ProbeAndCaptureUnicodeString(&CapturedName
,
292 if(NT_SUCCESS(Status
))
294 Status
= ProbeAndCaptureUnicodeString(&CapturedValue
,
297 if(NT_SUCCESS(Status
))
300 * according to ntinternals the SeSystemEnvironmentName privilege is required!
302 if(SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege
,
306 * convert the strings to ANSI
308 Status
= RtlUnicodeStringToAnsiString(&AName
,
311 if(NT_SUCCESS(Status
))
313 Status
= RtlUnicodeStringToAnsiString(&AValue
,
316 if(NT_SUCCESS(Status
))
318 BOOLEAN Result
= HalSetEnvironmentVariable(AName
.Buffer
,
321 Status
= (Result
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
327 DPRINT1("NtSetSystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
328 Status
= STATUS_PRIVILEGE_NOT_HELD
;
331 ReleaseCapturedUnicodeString(&CapturedValue
,
335 ReleaseCapturedUnicodeString(&CapturedName
,
344 NtEnumerateSystemEnvironmentValuesEx(IN ULONG InformationClass
,
346 IN ULONG BufferLength
)
349 return STATUS_NOT_IMPLEMENTED
;
354 NtQuerySystemEnvironmentValueEx(IN PUNICODE_STRING VariableName
,
355 IN LPGUID VendorGuid
,
357 IN OUT PULONG ReturnLength
,
358 IN OUT PULONG Attributes
)
361 return STATUS_NOT_IMPLEMENTED
;
366 NtSetSystemEnvironmentValueEx(IN PUNICODE_STRING VariableName
,
367 IN LPGUID VendorGuid
)
370 return STATUS_NOT_IMPLEMENTED
;
373 /* --- Query/Set System Information --- */
376 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
377 * so the stack is popped only in one place on x86 platform.
379 #define QSI_USE(n) QSI##n
381 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
383 #define SSI_USE(n) SSI##n
385 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
388 /* Class 0 - Basic Information */
389 QSI_DEF(SystemBasicInformation
)
391 PSYSTEM_BASIC_INFORMATION Sbi
392 = (PSYSTEM_BASIC_INFORMATION
) Buffer
;
394 *ReqSize
= sizeof (SYSTEM_BASIC_INFORMATION
);
396 * Check user buffer's size
398 if (Size
!= sizeof (SYSTEM_BASIC_INFORMATION
))
400 return (STATUS_INFO_LENGTH_MISMATCH
);
403 Sbi
->TimerResolution
= KeMaximumIncrement
;
404 Sbi
->PageSize
= PAGE_SIZE
;
405 Sbi
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
406 Sbi
->LowestPhysicalPageNumber
= 0; /* FIXME */
407 Sbi
->HighestPhysicalPageNumber
= MmStats
.NrTotalPages
; /* FIXME */
408 Sbi
->AllocationGranularity
= MM_VIRTMEM_GRANULARITY
; /* hard coded on Intel? */
409 Sbi
->MinimumUserModeAddress
= 0x10000; /* Top of 64k */
410 Sbi
->MaximumUserModeAddress
= (ULONG_PTR
)MmHighestUserAddress
;
411 Sbi
->ActiveProcessorsAffinityMask
= KeActiveProcessors
;
412 Sbi
->NumberOfProcessors
= KeNumberProcessors
;
413 return (STATUS_SUCCESS
);
416 /* Class 1 - Processor Information */
417 QSI_DEF(SystemProcessorInformation
)
419 PSYSTEM_PROCESSOR_INFORMATION Spi
420 = (PSYSTEM_PROCESSOR_INFORMATION
) Buffer
;
422 *ReqSize
= sizeof (SYSTEM_PROCESSOR_INFORMATION
);
424 * Check user buffer's size
426 if (Size
< sizeof (SYSTEM_PROCESSOR_INFORMATION
))
428 return (STATUS_INFO_LENGTH_MISMATCH
);
430 Prcb
= KeGetCurrentPrcb();
431 Spi
->ProcessorArchitecture
= 0; /* Intel Processor */
432 Spi
->ProcessorLevel
= Prcb
->CpuType
;
433 Spi
->ProcessorRevision
= Prcb
->CpuStep
;
435 Spi
->ProcessorFeatureBits
= Prcb
->FeatureBits
;
437 DPRINT("Arch %d Level %d Rev 0x%x\n", Spi
->ProcessorArchitecture
,
438 Spi
->ProcessorLevel
, Spi
->ProcessorRevision
);
440 return (STATUS_SUCCESS
);
443 /* Class 2 - Performance Information */
444 QSI_DEF(SystemPerformanceInformation
)
446 PSYSTEM_PERFORMANCE_INFORMATION Spi
447 = (PSYSTEM_PERFORMANCE_INFORMATION
) Buffer
;
449 PEPROCESS TheIdleProcess
;
451 *ReqSize
= sizeof (SYSTEM_PERFORMANCE_INFORMATION
);
453 * Check user buffer's size
455 if (Size
< sizeof (SYSTEM_PERFORMANCE_INFORMATION
))
457 return (STATUS_INFO_LENGTH_MISMATCH
);
460 TheIdleProcess
= PsIdleProcess
;
462 Spi
->IdleProcessTime
.QuadPart
= TheIdleProcess
->Pcb
.KernelTime
* 100000LL;
464 Spi
->IoReadTransferCount
= IoReadTransferCount
;
465 Spi
->IoWriteTransferCount
= IoWriteTransferCount
;
466 Spi
->IoOtherTransferCount
= IoOtherTransferCount
;
467 Spi
->IoReadOperationCount
= IoReadOperationCount
;
468 Spi
->IoWriteOperationCount
= IoWriteOperationCount
;
469 Spi
->IoOtherOperationCount
= IoOtherOperationCount
;
471 Spi
->AvailablePages
= MmStats
.NrFreePages
;
473 Add up all the used "Commitied" memory + pagefile.
474 Not sure this is right. 8^\
476 Spi
->CommittedPages
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
+
477 MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
+
478 MiMemoryConsumers
[MC_CACHE
].PagesUsed
+
479 MiMemoryConsumers
[MC_USER
].PagesUsed
+
482 Add up the full system total + pagefile.
483 All this make Taskmgr happy but not sure it is the right numbers.
484 This too, fixes some of GlobalMemoryStatusEx numbers.
486 Spi
->CommitLimit
= MmStats
.NrTotalPages
+ MiFreeSwapPages
+
489 Spi
->PeakCommitment
= 0; /* FIXME */
490 Spi
->PageFaultCount
= 0; /* FIXME */
491 Spi
->CopyOnWriteCount
= 0; /* FIXME */
492 Spi
->TransitionCount
= 0; /* FIXME */
493 Spi
->CacheTransitionCount
= 0; /* FIXME */
494 Spi
->DemandZeroCount
= 0; /* FIXME */
495 Spi
->PageReadCount
= 0; /* FIXME */
496 Spi
->PageReadIoCount
= 0; /* FIXME */
497 Spi
->CacheReadCount
= 0; /* FIXME */
498 Spi
->CacheIoCount
= 0; /* FIXME */
499 Spi
->DirtyPagesWriteCount
= 0; /* FIXME */
500 Spi
->DirtyWriteIoCount
= 0; /* FIXME */
501 Spi
->MappedPagesWriteCount
= 0; /* FIXME */
502 Spi
->MappedWriteIoCount
= 0; /* FIXME */
504 Spi
->PagedPoolPages
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
;
505 Spi
->PagedPoolAllocs
= 0; /* FIXME */
506 Spi
->PagedPoolFrees
= 0; /* FIXME */
507 Spi
->NonPagedPoolPages
= MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
;
508 Spi
->NonPagedPoolAllocs
= 0; /* FIXME */
509 Spi
->NonPagedPoolFrees
= 0; /* FIXME */
511 Spi
->FreeSystemPtes
= 0; /* FIXME */
513 Spi
->ResidentSystemCodePage
= MmStats
.NrSystemPages
; /* FIXME */
515 Spi
->TotalSystemDriverPages
= 0; /* FIXME */
516 Spi
->TotalSystemCodePages
= 0; /* FIXME */
517 Spi
->NonPagedPoolLookasideHits
= 0; /* FIXME */
518 Spi
->PagedPoolLookasideHits
= 0; /* FIXME */
519 Spi
->Spare3Count
= 0; /* FIXME */
521 Spi
->ResidentSystemCachePage
= MiMemoryConsumers
[MC_CACHE
].PagesUsed
;
522 Spi
->ResidentPagedPoolPage
= MmPagedPoolSize
; /* FIXME */
524 Spi
->ResidentSystemDriverPage
= 0; /* FIXME */
525 Spi
->CcFastReadNoWait
= 0; /* FIXME */
526 Spi
->CcFastReadWait
= 0; /* FIXME */
527 Spi
->CcFastReadResourceMiss
= 0; /* FIXME */
528 Spi
->CcFastReadNotPossible
= 0; /* FIXME */
530 Spi
->CcFastMdlReadNoWait
= 0; /* FIXME */
531 Spi
->CcFastMdlReadWait
= 0; /* FIXME */
532 Spi
->CcFastMdlReadResourceMiss
= 0; /* FIXME */
533 Spi
->CcFastMdlReadNotPossible
= 0; /* FIXME */
535 Spi
->CcMapDataNoWait
= 0; /* FIXME */
536 Spi
->CcMapDataWait
= 0; /* FIXME */
537 Spi
->CcMapDataNoWaitMiss
= 0; /* FIXME */
538 Spi
->CcMapDataWaitMiss
= 0; /* FIXME */
540 Spi
->CcPinMappedDataCount
= 0; /* FIXME */
541 Spi
->CcPinReadNoWait
= 0; /* FIXME */
542 Spi
->CcPinReadWait
= 0; /* FIXME */
543 Spi
->CcPinReadNoWaitMiss
= 0; /* FIXME */
544 Spi
->CcPinReadWaitMiss
= 0; /* FIXME */
545 Spi
->CcCopyReadNoWait
= 0; /* FIXME */
546 Spi
->CcCopyReadWait
= 0; /* FIXME */
547 Spi
->CcCopyReadNoWaitMiss
= 0; /* FIXME */
548 Spi
->CcCopyReadWaitMiss
= 0; /* FIXME */
550 Spi
->CcMdlReadNoWait
= 0; /* FIXME */
551 Spi
->CcMdlReadWait
= 0; /* FIXME */
552 Spi
->CcMdlReadNoWaitMiss
= 0; /* FIXME */
553 Spi
->CcMdlReadWaitMiss
= 0; /* FIXME */
554 Spi
->CcReadAheadIos
= 0; /* FIXME */
555 Spi
->CcLazyWriteIos
= 0; /* FIXME */
556 Spi
->CcLazyWritePages
= 0; /* FIXME */
557 Spi
->CcDataFlushes
= 0; /* FIXME */
558 Spi
->CcDataPages
= 0; /* FIXME */
559 Spi
->ContextSwitches
= 0; /* FIXME */
560 Spi
->FirstLevelTbFills
= 0; /* FIXME */
561 Spi
->SecondLevelTbFills
= 0; /* FIXME */
562 Spi
->SystemCalls
= 0; /* FIXME */
564 return (STATUS_SUCCESS
);
567 /* Class 3 - Time Of Day Information */
568 QSI_DEF(SystemTimeOfDayInformation
)
570 PSYSTEM_TIMEOFDAY_INFORMATION Sti
;
571 LARGE_INTEGER CurrentTime
;
573 Sti
= (PSYSTEM_TIMEOFDAY_INFORMATION
)Buffer
;
574 *ReqSize
= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
);
576 /* Check user buffer's size */
577 if (Size
!= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
))
579 return STATUS_INFO_LENGTH_MISMATCH
;
582 KeQuerySystemTime(&CurrentTime
);
584 Sti
->BootTime
= KeBootTime
;
585 Sti
->CurrentTime
= CurrentTime
;
586 Sti
->TimeZoneBias
.QuadPart
= ExpTimeZoneBias
.QuadPart
;
587 Sti
->TimeZoneId
= ExpTimeZoneId
;
590 return STATUS_SUCCESS
;
593 /* Class 4 - Path Information */
594 QSI_DEF(SystemPathInformation
)
596 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
597 DPRINT1("NtQuerySystemInformation - SystemPathInformation not implemented\n");
599 return (STATUS_BREAKPOINT
);
602 /* Class 5 - Process Information */
603 QSI_DEF(SystemProcessInformation
)
605 ULONG ovlSize
= 0, nThreads
;
606 PEPROCESS pr
= NULL
, syspr
;
608 NTSTATUS Status
= STATUS_SUCCESS
;
612 /* scan the process list */
614 PSYSTEM_PROCESS_INFORMATION Spi
615 = (PSYSTEM_PROCESS_INFORMATION
) Buffer
;
617 *ReqSize
= sizeof(SYSTEM_PROCESS_INFORMATION
);
619 if (Size
< sizeof(SYSTEM_PROCESS_INFORMATION
))
621 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
624 syspr
= PsGetNextProcess(NULL
);
626 pCur
= (unsigned char *)Spi
;
630 PSYSTEM_PROCESS_INFORMATION SpiCur
;
633 int inLen
=32; // image name len in bytes
634 PLIST_ENTRY current_entry
;
636 PSYSTEM_THREAD_INFORMATION ThreadInfo
;
638 SpiCur
= (PSYSTEM_PROCESS_INFORMATION
)pCur
;
641 current_entry
= pr
->ThreadListHead
.Flink
;
642 while (current_entry
!= &pr
->ThreadListHead
)
645 current_entry
= current_entry
->Flink
;
648 // size of the structure for every process
649 curSize
= sizeof(SYSTEM_PROCESS_INFORMATION
)+sizeof(SYSTEM_THREAD_INFORMATION
)*nThreads
;
650 ovlSize
+= curSize
+inLen
;
655 ObDereferenceObject(pr
);
657 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
660 // fill system information
661 SpiCur
->NextEntryOffset
= curSize
+inLen
; // relative offset to the beginnnig of the next structure
662 SpiCur
->NumberOfThreads
= nThreads
;
663 SpiCur
->CreateTime
= pr
->CreateTime
;
664 SpiCur
->UserTime
.QuadPart
= pr
->Pcb
.UserTime
* 100000LL;
665 SpiCur
->KernelTime
.QuadPart
= pr
->Pcb
.KernelTime
* 100000LL;
666 SpiCur
->ImageName
.Length
= strlen(pr
->ImageFileName
) * sizeof(WCHAR
);
667 SpiCur
->ImageName
.MaximumLength
= inLen
;
668 SpiCur
->ImageName
.Buffer
= (void*)(pCur
+curSize
);
670 // copy name to the end of the struct
671 if(pr
!= PsIdleProcess
)
673 RtlInitAnsiString(&imgName
, pr
->ImageFileName
);
674 RtlAnsiStringToUnicodeString(&SpiCur
->ImageName
, &imgName
, FALSE
);
678 RtlInitUnicodeString(&SpiCur
->ImageName
, NULL
);
681 SpiCur
->BasePriority
= pr
->Pcb
.BasePriority
;
682 SpiCur
->UniqueProcessId
= pr
->UniqueProcessId
;
683 SpiCur
->InheritedFromUniqueProcessId
= pr
->InheritedFromUniqueProcessId
;
684 SpiCur
->HandleCount
= (pr
->ObjectTable
? ObpGetHandleCountByHandleTable(pr
->ObjectTable
) : 0);
685 SpiCur
->PeakVirtualSize
= pr
->PeakVirtualSize
;
686 SpiCur
->VirtualSize
= pr
->VirtualSize
;
687 SpiCur
->PageFaultCount
= pr
->Vm
.PageFaultCount
;
688 SpiCur
->PeakWorkingSetSize
= pr
->Vm
.PeakWorkingSetSize
;
689 SpiCur
->WorkingSetSize
= pr
->Vm
.WorkingSetSize
;
690 SpiCur
->QuotaPeakPagedPoolUsage
= pr
->QuotaPeak
[0];
691 SpiCur
->QuotaPagedPoolUsage
= pr
->QuotaUsage
[0];
692 SpiCur
->QuotaPeakNonPagedPoolUsage
= pr
->QuotaPeak
[1];
693 SpiCur
->QuotaNonPagedPoolUsage
= pr
->QuotaUsage
[1];
694 SpiCur
->PagefileUsage
= pr
->QuotaUsage
[2];
695 SpiCur
->PeakPagefileUsage
= pr
->QuotaPeak
[2];
696 SpiCur
->PrivatePageCount
= pr
->CommitCharge
;
697 ThreadInfo
= (PSYSTEM_THREAD_INFORMATION
)(SpiCur
+ 1);
699 current_entry
= pr
->ThreadListHead
.Flink
;
700 while (current_entry
!= &pr
->ThreadListHead
)
702 current
= CONTAINING_RECORD(current_entry
, ETHREAD
,
706 ThreadInfo
->KernelTime
.QuadPart
= current
->Tcb
.KernelTime
* 100000LL;
707 ThreadInfo
->UserTime
.QuadPart
= current
->Tcb
.UserTime
* 100000LL;
708 // SpiCur->TH[i].CreateTime = current->CreateTime;
709 ThreadInfo
->WaitTime
= current
->Tcb
.WaitTime
;
710 ThreadInfo
->StartAddress
= (PVOID
) current
->StartAddress
;
711 ThreadInfo
->ClientId
= current
->Cid
;
712 ThreadInfo
->Priority
= current
->Tcb
.Priority
;
713 ThreadInfo
->BasePriority
= current
->Tcb
.BasePriority
;
714 ThreadInfo
->ContextSwitches
= current
->Tcb
.ContextSwitches
;
715 ThreadInfo
->ThreadState
= current
->Tcb
.State
;
716 ThreadInfo
->WaitReason
= current
->Tcb
.WaitReason
;
718 current_entry
= current_entry
->Flink
;
721 pr
= PsGetNextProcess(pr
);
723 if ((pr
== syspr
) || (pr
== NULL
))
725 SpiCur
->NextEntryOffset
= 0;
729 pCur
= pCur
+ curSize
+ inLen
;
730 } while ((pr
!= syspr
) && (pr
!= NULL
));
733 ObDereferenceObject(pr
);
734 Status
= STATUS_SUCCESS
;
739 ObDereferenceObject(pr
);
740 Status
= _SEH_GetExceptionCode();
748 /* Class 6 - Call Count Information */
749 QSI_DEF(SystemCallCountInformation
)
752 DPRINT1("NtQuerySystemInformation - SystemCallCountInformation not implemented\n");
753 return (STATUS_NOT_IMPLEMENTED
);
756 /* Class 7 - Device Information */
757 QSI_DEF(SystemDeviceInformation
)
759 PSYSTEM_DEVICE_INFORMATION Sdi
760 = (PSYSTEM_DEVICE_INFORMATION
) Buffer
;
761 PCONFIGURATION_INFORMATION ConfigInfo
;
763 *ReqSize
= sizeof (SYSTEM_DEVICE_INFORMATION
);
765 * Check user buffer's size
767 if (Size
< sizeof (SYSTEM_DEVICE_INFORMATION
))
769 return (STATUS_INFO_LENGTH_MISMATCH
);
772 ConfigInfo
= IoGetConfigurationInformation ();
774 Sdi
->NumberOfDisks
= ConfigInfo
->DiskCount
;
775 Sdi
->NumberOfFloppies
= ConfigInfo
->FloppyCount
;
776 Sdi
->NumberOfCdRoms
= ConfigInfo
->CdRomCount
;
777 Sdi
->NumberOfTapes
= ConfigInfo
->TapeCount
;
778 Sdi
->NumberOfSerialPorts
= ConfigInfo
->SerialCount
;
779 Sdi
->NumberOfParallelPorts
= ConfigInfo
->ParallelCount
;
781 return (STATUS_SUCCESS
);
784 /* Class 8 - Processor Performance Information */
785 QSI_DEF(SystemProcessorPerformanceInformation
)
787 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
788 = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) Buffer
;
791 LARGE_INTEGER CurrentTime
;
794 *ReqSize
= KeNumberProcessors
* sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
);
796 * Check user buffer's size
798 if (Size
< KeNumberProcessors
* sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
))
800 return (STATUS_INFO_LENGTH_MISMATCH
);
803 CurrentTime
.QuadPart
= KeQueryInterruptTime();
804 Prcb
= ((PKPCR
)KPCR_BASE
)->Prcb
;
805 for (i
= 0; i
< KeNumberProcessors
; i
++)
807 Spi
->IdleTime
.QuadPart
= (Prcb
->IdleThread
->KernelTime
+ Prcb
->IdleThread
->UserTime
) * 100000LL; // IdleTime
808 Spi
->KernelTime
.QuadPart
= Prcb
->KernelTime
* 100000LL; // KernelTime
809 Spi
->UserTime
.QuadPart
= Prcb
->UserTime
* 100000LL;
810 Spi
->DpcTime
.QuadPart
= Prcb
->DpcTime
* 100000LL;
811 Spi
->InterruptTime
.QuadPart
= Prcb
->InterruptTime
* 100000LL;
812 Spi
->InterruptCount
= Prcb
->InterruptCount
; // Interrupt Count
814 Prcb
= (PKPRCB
)((ULONG_PTR
)Prcb
+ PAGE_SIZE
);
817 return (STATUS_SUCCESS
);
820 /* Class 9 - Flags Information */
821 QSI_DEF(SystemFlagsInformation
)
823 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
825 * ReqSize
= sizeof (SYSTEM_FLAGS_INFORMATION
);
826 return (STATUS_INFO_LENGTH_MISMATCH
);
828 ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
= NtGlobalFlag
;
829 return (STATUS_SUCCESS
);
832 SSI_DEF(SystemFlagsInformation
)
834 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
836 return (STATUS_INFO_LENGTH_MISMATCH
);
838 NtGlobalFlag
= ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
;
839 return (STATUS_SUCCESS
);
842 /* Class 10 - Call Time Information */
843 QSI_DEF(SystemCallTimeInformation
)
846 DPRINT1("NtQuerySystemInformation - SystemCallTimeInformation not implemented\n");
847 return (STATUS_NOT_IMPLEMENTED
);
850 /* Class 11 - Module Information */
851 QSI_DEF(SystemModuleInformation
)
853 return LdrpQueryModuleInformation(Buffer
, Size
, ReqSize
);
856 /* Class 12 - Locks Information */
857 QSI_DEF(SystemLocksInformation
)
860 DPRINT1("NtQuerySystemInformation - SystemLocksInformation not implemented\n");
861 return (STATUS_NOT_IMPLEMENTED
);
864 /* Class 13 - Stack Trace Information */
865 QSI_DEF(SystemStackTraceInformation
)
868 DPRINT1("NtQuerySystemInformation - SystemStackTraceInformation not implemented\n");
869 return (STATUS_NOT_IMPLEMENTED
);
872 /* Class 14 - Paged Pool Information */
873 QSI_DEF(SystemPagedPoolInformation
)
876 DPRINT1("NtQuerySystemInformation - SystemPagedPoolInformation not implemented\n");
877 return (STATUS_NOT_IMPLEMENTED
);
880 /* Class 15 - Non Paged Pool Information */
881 QSI_DEF(SystemNonPagedPoolInformation
)
884 DPRINT1("NtQuerySystemInformation - SystemNonPagedPoolInformation not implemented\n");
885 return (STATUS_NOT_IMPLEMENTED
);
889 /* Class 16 - Handle Information */
890 QSI_DEF(SystemHandleInformation
)
893 ULONG curSize
, i
= 0;
896 PSYSTEM_HANDLE_INFORMATION Shi
=
897 (PSYSTEM_HANDLE_INFORMATION
) Buffer
;
899 DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
901 if (Size
< sizeof (SYSTEM_HANDLE_INFORMATION
))
903 * ReqSize
= sizeof (SYSTEM_HANDLE_INFORMATION
);
904 return (STATUS_INFO_LENGTH_MISMATCH
);
907 DPRINT("SystemHandleInformation 1\n");
909 /* First Calc Size from Count. */
910 syspr
= PsGetNextProcess(NULL
);
915 hCount
= hCount
+ (pr
->ObjectTable
? ObpGetHandleCountByHandleTable(pr
->ObjectTable
) : 0);
916 pr
= PsGetNextProcess(pr
);
918 if ((pr
== syspr
) || (pr
== NULL
))
920 } while ((pr
!= syspr
) && (pr
!= NULL
));
924 ObDereferenceObject(pr
);
927 DPRINT("SystemHandleInformation 2\n");
929 curSize
= sizeof(SYSTEM_HANDLE_INFORMATION
)+
930 ( (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO
) * hCount
) -
931 (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO
) ));
933 Shi
->NumberOfHandles
= hCount
;
938 return (STATUS_INFO_LENGTH_MISMATCH
);
941 DPRINT("SystemHandleInformation 3\n");
943 /* Now get Handles from all processs. */
944 syspr
= PsGetNextProcess(NULL
);
949 int Count
= 0, HandleCount
;
951 HandleCount
= (pr
->ObjectTable
? ObpGetHandleCountByHandleTable(pr
->ObjectTable
) : 0);
953 for (Count
= 0; HandleCount
> 0 ; HandleCount
--)
955 Shi
->Handles
[i
].UniqueProcessId
= (ULONG
)pr
->UniqueProcessId
;
960 pr
= PsGetNextProcess(pr
);
962 if ((pr
== syspr
) || (pr
== NULL
))
964 } while ((pr
!= syspr
) && (pr
!= NULL
));
968 ObDereferenceObject(pr
);
971 DPRINT("SystemHandleInformation 4\n");
972 return (STATUS_SUCCESS
);
976 SSI_DEF(SystemHandleInformation)
979 return (STATUS_SUCCESS);
983 /* Class 17 - Information */
984 QSI_DEF(SystemObjectInformation
)
987 DPRINT1("NtQuerySystemInformation - SystemObjectInformation not implemented\n");
988 return (STATUS_NOT_IMPLEMENTED
);
991 /* Class 18 - Information */
992 QSI_DEF(SystemPageFileInformation
)
994 UNICODE_STRING FileName
; /* FIXME */
995 SYSTEM_PAGEFILE_INFORMATION
*Spfi
= (SYSTEM_PAGEFILE_INFORMATION
*) Buffer
;
997 if (Size
< sizeof (SYSTEM_PAGEFILE_INFORMATION
))
999 * ReqSize
= sizeof (SYSTEM_PAGEFILE_INFORMATION
);
1000 return (STATUS_INFO_LENGTH_MISMATCH
);
1003 RtlInitUnicodeString(&FileName
, NULL
); /* FIXME */
1006 Spfi
->NextEntryOffset
= 0;
1008 Spfi
->TotalSize
= MiFreeSwapPages
+ MiUsedSwapPages
;
1009 Spfi
->TotalInUse
= MiUsedSwapPages
;
1010 Spfi
->PeakUsage
= MiUsedSwapPages
; /* FIXME */
1011 Spfi
->PageFileName
= FileName
;
1012 return (STATUS_SUCCESS
);
1015 /* Class 19 - Vdm Instemul Information */
1016 QSI_DEF(SystemVdmInstemulInformation
)
1019 DPRINT1("NtQuerySystemInformation - SystemVdmInstemulInformation not implemented\n");
1020 return (STATUS_NOT_IMPLEMENTED
);
1023 /* Class 20 - Vdm Bop Information */
1024 QSI_DEF(SystemVdmBopInformation
)
1027 DPRINT1("NtQuerySystemInformation - SystemVdmBopInformation not implemented\n");
1028 return (STATUS_NOT_IMPLEMENTED
);
1031 /* Class 21 - File Cache Information */
1032 QSI_DEF(SystemFileCacheInformation
)
1034 SYSTEM_FILECACHE_INFORMATION
*Sci
= (SYSTEM_FILECACHE_INFORMATION
*) Buffer
;
1036 if (Size
< sizeof (SYSTEM_FILECACHE_INFORMATION
))
1038 * ReqSize
= sizeof (SYSTEM_FILECACHE_INFORMATION
);
1039 return (STATUS_INFO_LENGTH_MISMATCH
);
1042 RtlZeroMemory(Sci
, sizeof(SYSTEM_FILECACHE_INFORMATION
));
1044 /* Return the Byte size not the page size. */
1046 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
;
1048 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
; /* FIXME */
1050 Sci
->PageFaultCount
= 0; /* FIXME */
1051 Sci
->MinimumWorkingSet
= 0; /* FIXME */
1052 Sci
->MaximumWorkingSet
= 0; /* FIXME */
1054 return (STATUS_SUCCESS
);
1057 SSI_DEF(SystemFileCacheInformation
)
1059 if (Size
< sizeof (SYSTEM_FILECACHE_INFORMATION
))
1061 return (STATUS_INFO_LENGTH_MISMATCH
);
1064 DPRINT1("NtSetSystemInformation - SystemFileCacheInformation not implemented\n");
1065 return (STATUS_NOT_IMPLEMENTED
);
1068 /* Class 22 - Pool Tag Information */
1069 QSI_DEF(SystemPoolTagInformation
)
1072 DPRINT1("NtQuerySystemInformation - SystemPoolTagInformation not implemented\n");
1073 return (STATUS_NOT_IMPLEMENTED
);
1076 /* Class 23 - Interrupt Information for all processors */
1077 QSI_DEF(SystemInterruptInformation
)
1082 PSYSTEM_INTERRUPT_INFORMATION sii
= (PSYSTEM_INTERRUPT_INFORMATION
)Buffer
;
1084 if(Size
< KeNumberProcessors
* sizeof(SYSTEM_INTERRUPT_INFORMATION
))
1086 return (STATUS_INFO_LENGTH_MISMATCH
);
1089 ti
= KeQueryTimeIncrement();
1091 Prcb
= ((PKPCR
)KPCR_BASE
)->Prcb
;
1092 for (i
= 0; i
< KeNumberProcessors
; i
++)
1094 //sii->ContextSwitches = Prcb->KeContextSwitches;
1095 sii
->DpcCount
= 0; /* FIXME */
1096 sii
->DpcRate
= 0; /* FIXME */
1097 sii
->TimeIncrement
= ti
;
1098 sii
->DpcBypassCount
= 0; /* FIXME */
1099 sii
->ApcBypassCount
= 0; /* FIXME */
1101 Prcb
= (PKPRCB
)((ULONG_PTR
)Prcb
+ PAGE_SIZE
);
1104 return STATUS_SUCCESS
;
1107 /* Class 24 - DPC Behaviour Information */
1108 QSI_DEF(SystemDpcBehaviourInformation
)
1111 DPRINT1("NtQuerySystemInformation - SystemDpcBehaviourInformation not implemented\n");
1112 return (STATUS_NOT_IMPLEMENTED
);
1115 SSI_DEF(SystemDpcBehaviourInformation
)
1118 DPRINT1("NtSetSystemInformation - SystemDpcBehaviourInformation not implemented\n");
1119 return (STATUS_NOT_IMPLEMENTED
);
1122 /* Class 25 - Full Memory Information */
1123 QSI_DEF(SystemFullMemoryInformation
)
1125 PULONG Spi
= (PULONG
) Buffer
;
1127 PEPROCESS TheIdleProcess
;
1129 * ReqSize
= sizeof (ULONG
);
1131 if (sizeof (ULONG
) != Size
)
1133 return (STATUS_INFO_LENGTH_MISMATCH
);
1135 DPRINT("SystemFullMemoryInformation\n");
1137 TheIdleProcess
= PsIdleProcess
;
1139 DPRINT("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
1140 TheIdleProcess
->UniqueProcessId
,
1141 TheIdleProcess
->Pcb
.KernelTime
,
1146 MmPrintMemoryStatistic();
1149 *Spi
= MiMemoryConsumers
[MC_USER
].PagesUsed
;
1151 return (STATUS_SUCCESS
);
1154 /* Class 26 - Load Image */
1155 SSI_DEF(SystemLoadImage
)
1157 PSYSTEM_GDI_DRIVER_INFORMATION Sli
= (PSYSTEM_GDI_DRIVER_INFORMATION
)Buffer
;
1159 if (sizeof(SYSTEM_GDI_DRIVER_INFORMATION
) != Size
)
1161 return(STATUS_INFO_LENGTH_MISMATCH
);
1164 return(LdrpLoadImage(&Sli
->DriverName
,
1166 &Sli
->SectionPointer
,
1168 (PVOID
)&Sli
->ExportSectionPointer
));
1171 /* Class 27 - Unload Image */
1172 SSI_DEF(SystemUnloadImage
)
1174 PVOID Sui
= (PVOID
)Buffer
;
1176 if (sizeof(PVOID
) != Size
)
1178 return(STATUS_INFO_LENGTH_MISMATCH
);
1181 return(LdrpUnloadImage(Sui
));
1184 /* Class 28 - Time Adjustment Information */
1185 QSI_DEF(SystemTimeAdjustmentInformation
)
1187 if (sizeof (SYSTEM_SET_TIME_ADJUST_INFORMATION
) > Size
)
1189 * ReqSize
= sizeof (SYSTEM_SET_TIME_ADJUST_INFORMATION
);
1190 return (STATUS_INFO_LENGTH_MISMATCH
);
1193 DPRINT1("NtQuerySystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1194 return (STATUS_NOT_IMPLEMENTED
);
1197 SSI_DEF(SystemTimeAdjustmentInformation
)
1199 if (sizeof (SYSTEM_SET_TIME_ADJUST_INFORMATION
) > Size
)
1201 return (STATUS_INFO_LENGTH_MISMATCH
);
1204 DPRINT1("NtSetSystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1205 return (STATUS_NOT_IMPLEMENTED
);
1208 /* Class 29 - Summary Memory Information */
1209 QSI_DEF(SystemSummaryMemoryInformation
)
1212 DPRINT1("NtQuerySystemInformation - SystemSummaryMemoryInformation not implemented\n");
1213 return (STATUS_NOT_IMPLEMENTED
);
1216 /* Class 30 - Next Event Id Information */
1217 QSI_DEF(SystemNextEventIdInformation
)
1220 DPRINT1("NtQuerySystemInformation - SystemNextEventIdInformation not implemented\n");
1221 return (STATUS_NOT_IMPLEMENTED
);
1224 /* Class 31 - Event Ids Information */
1225 QSI_DEF(SystemEventIdsInformation
)
1228 DPRINT1("NtQuerySystemInformation - SystemEventIdsInformation not implemented\n");
1229 return (STATUS_NOT_IMPLEMENTED
);
1232 /* Class 32 - Crash Dump Information */
1233 QSI_DEF(SystemCrashDumpInformation
)
1236 DPRINT1("NtQuerySystemInformation - SystemCrashDumpInformation not implemented\n");
1237 return (STATUS_NOT_IMPLEMENTED
);
1240 /* Class 33 - Exception Information */
1241 QSI_DEF(SystemExceptionInformation
)
1244 DPRINT1("NtQuerySystemInformation - SystemExceptionInformation not implemented\n");
1245 return (STATUS_NOT_IMPLEMENTED
);
1248 /* Class 34 - Crash Dump State Information */
1249 QSI_DEF(SystemCrashDumpStateInformation
)
1252 DPRINT1("NtQuerySystemInformation - SystemCrashDumpStateInformation not implemented\n");
1253 return (STATUS_NOT_IMPLEMENTED
);
1256 /* Class 35 - Kernel Debugger Information */
1257 QSI_DEF(SystemKernelDebuggerInformation
)
1259 PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi
= (PSYSTEM_KERNEL_DEBUGGER_INFORMATION
) Buffer
;
1261 *ReqSize
= sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION
);
1262 if (Size
< sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION
))
1264 return STATUS_INFO_LENGTH_MISMATCH
;
1267 skdi
->KernelDebuggerEnabled
= KD_DEBUGGER_ENABLED
;
1268 skdi
->KernelDebuggerNotPresent
= KD_DEBUGGER_NOT_PRESENT
;
1270 return STATUS_SUCCESS
;
1273 /* Class 36 - Context Switch Information */
1274 QSI_DEF(SystemContextSwitchInformation
)
1277 DPRINT1("NtQuerySystemInformation - SystemContextSwitchInformation not implemented\n");
1278 return (STATUS_NOT_IMPLEMENTED
);
1281 /* Class 37 - Registry Quota Information */
1282 QSI_DEF(SystemRegistryQuotaInformation
)
1284 PSYSTEM_REGISTRY_QUOTA_INFORMATION srqi
= (PSYSTEM_REGISTRY_QUOTA_INFORMATION
) Buffer
;
1286 *ReqSize
= sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION
);
1287 if (Size
< sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION
))
1289 return STATUS_INFO_LENGTH_MISMATCH
;
1292 DPRINT1("Faking max registry size of 32 MB\n");
1293 srqi
->RegistryQuotaAllowed
= 0x2000000;
1294 srqi
->RegistryQuotaUsed
= 0x200000;
1295 srqi
->PagedPoolSize
= 0x200000;
1297 return STATUS_SUCCESS
;
1300 SSI_DEF(SystemRegistryQuotaInformation
)
1303 DPRINT1("NtSetSystemInformation - SystemRegistryQuotaInformation not implemented\n");
1304 return (STATUS_NOT_IMPLEMENTED
);
1307 /* Class 38 - Load And Call Image */
1308 SSI_DEF(SystemLoadAndCallImage
)
1310 PUNICODE_STRING Slci
= (PUNICODE_STRING
)Buffer
;
1312 if (sizeof(UNICODE_STRING
) != Size
)
1314 return(STATUS_INFO_LENGTH_MISMATCH
);
1317 return(LdrpLoadAndCallImage(Slci
));
1320 /* Class 39 - Priority Separation */
1321 SSI_DEF(SystemPrioritySeperation
)
1324 DPRINT1("NtSetSystemInformation - SystemPrioritySeperation not implemented\n");
1325 return (STATUS_NOT_IMPLEMENTED
);
1328 /* Class 40 - Plug Play Bus Information */
1329 QSI_DEF(SystemPlugPlayBusInformation
)
1332 DPRINT1("NtQuerySystemInformation - SystemPlugPlayBusInformation not implemented\n");
1333 return (STATUS_NOT_IMPLEMENTED
);
1336 /* Class 41 - Dock Information */
1337 QSI_DEF(SystemDockInformation
)
1340 DPRINT1("NtQuerySystemInformation - SystemDockInformation not implemented\n");
1341 return (STATUS_NOT_IMPLEMENTED
);
1344 /* Class 42 - Power Information */
1345 QSI_DEF(SystemPowerInformation
)
1348 DPRINT1("NtQuerySystemInformation - SystemPowerInformation not implemented\n");
1349 return (STATUS_NOT_IMPLEMENTED
);
1352 /* Class 43 - Processor Speed Information */
1353 QSI_DEF(SystemProcessorSpeedInformation
)
1356 DPRINT1("NtQuerySystemInformation - SystemProcessorSpeedInformation not implemented\n");
1357 return (STATUS_NOT_IMPLEMENTED
);
1360 /* Class 44 - Current Time Zone Information */
1361 QSI_DEF(SystemCurrentTimeZoneInformation
)
1363 * ReqSize
= sizeof (TIME_ZONE_INFORMATION
);
1365 if (sizeof (TIME_ZONE_INFORMATION
) != Size
)
1367 return STATUS_INFO_LENGTH_MISMATCH
;
1370 /* Copy the time zone information struct */
1373 sizeof(TIME_ZONE_INFORMATION
));
1375 return STATUS_SUCCESS
;
1379 SSI_DEF(SystemCurrentTimeZoneInformation
)
1381 /* Check user buffer's size */
1382 if (Size
< sizeof (TIME_ZONE_INFORMATION
))
1384 return STATUS_INFO_LENGTH_MISMATCH
;
1387 return ExpSetTimeZoneInformation((PTIME_ZONE_INFORMATION
)Buffer
);
1391 /* Class 45 - Lookaside Information */
1392 QSI_DEF(SystemLookasideInformation
)
1395 DPRINT1("NtQuerySystemInformation - SystemLookasideInformation not implemented\n");
1396 return (STATUS_NOT_IMPLEMENTED
);
1400 /* Class 46 - Set time slip event */
1401 SSI_DEF(SystemSetTimeSlipEvent
)
1404 DPRINT1("NtSetSystemInformation - SystemSetTimSlipEvent not implemented\n");
1405 return (STATUS_NOT_IMPLEMENTED
);
1409 /* Class 47 - Create a new session (TSE) */
1410 SSI_DEF(SystemCreateSession
)
1413 DPRINT1("NtSetSystemInformation - SystemCreateSession not implemented\n");
1414 return (STATUS_NOT_IMPLEMENTED
);
1418 /* Class 48 - Delete an existing session (TSE) */
1419 SSI_DEF(SystemDeleteSession
)
1422 DPRINT1("NtSetSystemInformation - SystemDeleteSession not implemented\n");
1423 return (STATUS_NOT_IMPLEMENTED
);
1427 /* Class 49 - UNKNOWN */
1428 QSI_DEF(SystemInvalidInfoClass4
)
1431 DPRINT1("NtQuerySystemInformation - SystemInvalidInfoClass4 not implemented\n");
1432 return (STATUS_NOT_IMPLEMENTED
);
1436 /* Class 50 - System range start address */
1437 QSI_DEF(SystemRangeStartInformation
)
1440 DPRINT1("NtQuerySystemInformation - SystemRangeStartInformation not implemented\n");
1441 return (STATUS_NOT_IMPLEMENTED
);
1445 /* Class 51 - Driver verifier information */
1446 QSI_DEF(SystemVerifierInformation
)
1449 DPRINT1("NtQuerySystemInformation - SystemVerifierInformation not implemented\n");
1450 return (STATUS_NOT_IMPLEMENTED
);
1454 SSI_DEF(SystemVerifierInformation
)
1457 DPRINT1("NtSetSystemInformation - SystemVerifierInformation not implemented\n");
1458 return (STATUS_NOT_IMPLEMENTED
);
1462 /* Class 52 - Add a driver verifier */
1463 SSI_DEF(SystemAddVerifier
)
1466 DPRINT1("NtSetSystemInformation - SystemAddVerifier not implemented\n");
1467 return (STATUS_NOT_IMPLEMENTED
);
1471 /* Class 53 - A session's processes */
1472 QSI_DEF(SystemSessionProcessesInformation
)
1475 DPRINT1("NtQuerySystemInformation - SystemSessionProcessInformation not implemented\n");
1476 return (STATUS_NOT_IMPLEMENTED
);
1480 /* Query/Set Calls Table */
1484 NTSTATUS (* Query
) (PVOID
,ULONG
,PULONG
);
1485 NTSTATUS (* Set
) (PVOID
,ULONG
);
1492 // XX unknown behaviour
1494 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1495 #define SI_QX(n) {QSI_USE(n),NULL}
1496 #define SI_XS(n) {NULL,SSI_USE(n)}
1497 #define SI_XX(n) {NULL,NULL}
1503 SI_QX(SystemBasicInformation
),
1504 SI_QX(SystemProcessorInformation
),
1505 SI_QX(SystemPerformanceInformation
),
1506 SI_QX(SystemTimeOfDayInformation
),
1507 SI_QX(SystemPathInformation
), /* should be SI_XX */
1508 SI_QX(SystemProcessInformation
),
1509 SI_QX(SystemCallCountInformation
),
1510 SI_QX(SystemDeviceInformation
),
1511 SI_QX(SystemProcessorPerformanceInformation
),
1512 SI_QS(SystemFlagsInformation
),
1513 SI_QX(SystemCallTimeInformation
), /* should be SI_XX */
1514 SI_QX(SystemModuleInformation
),
1515 SI_QX(SystemLocksInformation
),
1516 SI_QX(SystemStackTraceInformation
), /* should be SI_XX */
1517 SI_QX(SystemPagedPoolInformation
), /* should be SI_XX */
1518 SI_QX(SystemNonPagedPoolInformation
), /* should be SI_XX */
1519 SI_QX(SystemHandleInformation
),
1520 SI_QX(SystemObjectInformation
),
1521 SI_QX(SystemPageFileInformation
),
1522 SI_QX(SystemVdmInstemulInformation
),
1523 SI_QX(SystemVdmBopInformation
), /* it should be SI_XX */
1524 SI_QS(SystemFileCacheInformation
),
1525 SI_QX(SystemPoolTagInformation
),
1526 SI_QX(SystemInterruptInformation
),
1527 SI_QS(SystemDpcBehaviourInformation
),
1528 SI_QX(SystemFullMemoryInformation
), /* it should be SI_XX */
1529 SI_XS(SystemLoadImage
),
1530 SI_XS(SystemUnloadImage
),
1531 SI_QS(SystemTimeAdjustmentInformation
),
1532 SI_QX(SystemSummaryMemoryInformation
), /* it should be SI_XX */
1533 SI_QX(SystemNextEventIdInformation
), /* it should be SI_XX */
1534 SI_QX(SystemEventIdsInformation
), /* it should be SI_XX */
1535 SI_QX(SystemCrashDumpInformation
),
1536 SI_QX(SystemExceptionInformation
),
1537 SI_QX(SystemCrashDumpStateInformation
),
1538 SI_QX(SystemKernelDebuggerInformation
),
1539 SI_QX(SystemContextSwitchInformation
),
1540 SI_QS(SystemRegistryQuotaInformation
),
1541 SI_XS(SystemLoadAndCallImage
),
1542 SI_XS(SystemPrioritySeperation
),
1543 SI_QX(SystemPlugPlayBusInformation
), /* it should be SI_XX */
1544 SI_QX(SystemDockInformation
), /* it should be SI_XX */
1545 SI_QX(SystemPowerInformation
), /* it should be SI_XX */
1546 SI_QX(SystemProcessorSpeedInformation
), /* it should be SI_XX */
1547 SI_QS(SystemCurrentTimeZoneInformation
), /* it should be SI_QX */
1548 SI_QX(SystemLookasideInformation
),
1549 SI_XS(SystemSetTimeSlipEvent
),
1550 SI_XS(SystemCreateSession
),
1551 SI_XS(SystemDeleteSession
),
1552 SI_QX(SystemInvalidInfoClass4
), /* it should be SI_XX */
1553 SI_QX(SystemRangeStartInformation
),
1554 SI_QS(SystemVerifierInformation
),
1555 SI_XS(SystemAddVerifier
),
1556 SI_QX(SystemSessionProcessesInformation
)
1564 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1565 OUT PVOID SystemInformation
,
1567 OUT PULONG UnsafeResultLength
)
1569 KPROCESSOR_MODE PreviousMode
;
1571 NTSTATUS FStatus
= STATUS_NOT_IMPLEMENTED
;
1575 PreviousMode
= ExGetPreviousMode();
1579 if (PreviousMode
!= KernelMode
)
1581 /* SystemKernelDebuggerInformation needs only BOOLEAN alignment */
1582 ProbeForWrite(SystemInformation
, Length
, 1);
1583 if (UnsafeResultLength
!= NULL
)
1584 ProbeForWriteUlong(UnsafeResultLength
);
1587 /* Clear user buffer. */
1588 RtlZeroMemory(SystemInformation
, Length
);
1591 * Check the request is valid.
1593 if (SystemInformationClass
>= MaxSystemInfoClass
)
1595 return (STATUS_INVALID_INFO_CLASS
);
1598 if (NULL
!= CallQS
[SystemInformationClass
].Query
)
1601 * Hand the request to a subhandler.
1603 FStatus
= CallQS
[SystemInformationClass
].Query(SystemInformation
,
1606 if (UnsafeResultLength
!= NULL
)
1608 if (PreviousMode
!= KernelMode
)
1612 *UnsafeResultLength
= ResultLength
;
1614 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
1616 FStatus
= _SEH_GetExceptionCode();
1622 *UnsafeResultLength
= ResultLength
;
1627 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
1629 FStatus
= _SEH_GetExceptionCode();
1639 NtSetSystemInformation (
1640 IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1641 IN PVOID SystemInformation
,
1642 IN ULONG SystemInformationLength
1648 * If called from user mode, check
1649 * possible unsafe arguments.
1652 if (KernelMode
!= KeGetPreviousMode())
1656 // SystemInformation,
1666 * Check the request is valid.
1668 if ( (SystemInformationClass
>= SystemBasicInformation
)
1669 && (SystemInformationClass
< MaxSystemInfoClass
)
1672 if (NULL
!= CallQS
[SystemInformationClass
].Set
)
1675 * Hand the request to a subhandler.
1677 return CallQS
[SystemInformationClass
].Set (
1679 SystemInformationLength
1683 return (STATUS_INVALID_INFO_CLASS
);
1689 NtFlushInstructionCache (
1690 IN HANDLE ProcessHandle
,
1691 IN PVOID BaseAddress
,
1692 IN ULONG NumberOfBytesToFlush
1698 return STATUS_SUCCESS
;
1703 NtGetCurrentProcessorNumber(VOID
)
1705 /* Just return the CPU */
1706 return KeGetCurrentProcessorNumber();