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 /* FUNCTIONS *****************************************************************/
35 PHANDLE Handle OPTIONAL
46 ExGetCurrentProcessorCpuUsage (
54 Prcb
= KeGetCurrentPrcb();
56 ScaledIdle
= Prcb
->IdleThread
->KernelTime
* 100;
57 TotalTime
= Prcb
->KernelTime
+ Prcb
->UserTime
;
59 *CpuUsage
= 100 - (ScaledIdle
/ TotalTime
);
69 ExGetCurrentProcessorCounts (
70 PULONG ThreadKernelTime
,
72 PULONG ProcessorNumber
77 Prcb
= KeGetCurrentPrcb();
79 *ThreadKernelTime
= Prcb
->KernelTime
+ Prcb
->UserTime
;
80 *TotalCpuTime
= Prcb
->CurrentThread
->KernelTime
;
81 *ProcessorNumber
= KeGetCurrentProcessorNumber();
89 ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature
)
91 /* Quick check to see if it exists at all */
92 if (ProcessorFeature
>= PROCESSOR_FEATURE_MAX
) return(FALSE
);
94 /* Return our support for it */
95 return(SharedUserData
->ProcessorFeatures
[ProcessorFeature
]);
103 ExVerifySuite(SUITE_TYPE SuiteType
)
105 if (SuiteType
== Personal
) return TRUE
;
110 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName
,
111 OUT PWSTR ValueBuffer
,
112 IN ULONG ValueBufferLength
,
113 IN OUT PULONG ReturnLength OPTIONAL
)
116 UNICODE_STRING WName
;
120 UNICODE_STRING WValue
;
121 KPROCESSOR_MODE PreviousMode
;
122 NTSTATUS Status
= STATUS_SUCCESS
;
126 PreviousMode
= ExGetPreviousMode();
128 if(PreviousMode
!= KernelMode
)
132 ProbeForRead(VariableName
,
133 sizeof(UNICODE_STRING
),
135 ProbeForWrite(ValueBuffer
,
138 if(ReturnLength
!= NULL
)
140 ProbeForWriteUlong(ReturnLength
);
143 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
145 Status
= _SEH_GetExceptionCode();
149 if(!NT_SUCCESS(Status
))
156 * Copy the name to kernel space if necessary and convert it to ANSI.
158 Status
= ProbeAndCaptureUnicodeString(&WName
,
161 if(NT_SUCCESS(Status
))
164 * according to ntinternals the SeSystemEnvironmentName privilege is required!
166 if(!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege
,
169 ReleaseCapturedUnicodeString(&WName
,
171 DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
172 return STATUS_PRIVILEGE_NOT_HELD
;
176 * convert the value name to ansi
178 Status
= RtlUnicodeStringToAnsiString(&AName
, &WName
, TRUE
);
179 ReleaseCapturedUnicodeString(&WName
,
181 if(!NT_SUCCESS(Status
))
187 * Create a temporary buffer for the value
189 Value
= ExAllocatePool(NonPagedPool
, ValueBufferLength
);
192 RtlFreeAnsiString(&AName
);
193 return STATUS_INSUFFICIENT_RESOURCES
;
197 * Get the environment variable
199 Result
= HalGetEnvironmentVariable(AName
.Buffer
, Value
, ValueBufferLength
);
202 RtlFreeAnsiString(&AName
);
204 return STATUS_UNSUCCESSFUL
;
208 * Convert the result to UNICODE, protect with SEH in case the value buffer
209 * isn't NULL-terminated!
213 RtlInitAnsiString(&AValue
, Value
);
214 Status
= RtlAnsiStringToUnicodeString(&WValue
, &AValue
, TRUE
);
216 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
218 Status
= _SEH_GetExceptionCode();
222 if(NT_SUCCESS(Status
))
225 * Copy the result back to the caller.
229 RtlCopyMemory(ValueBuffer
, WValue
.Buffer
, WValue
.Length
);
230 ValueBuffer
[WValue
.Length
/ sizeof(WCHAR
)] = L
'\0';
231 if(ReturnLength
!= NULL
)
233 *ReturnLength
= WValue
.Length
+ sizeof(WCHAR
);
236 Status
= STATUS_SUCCESS
;
238 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
240 Status
= _SEH_GetExceptionCode();
246 * Cleanup allocated resources.
248 RtlFreeAnsiString(&AName
);
257 NtSetSystemEnvironmentValue (IN PUNICODE_STRING VariableName
,
258 IN PUNICODE_STRING Value
)
260 UNICODE_STRING CapturedName
, CapturedValue
;
261 ANSI_STRING AName
, AValue
;
262 KPROCESSOR_MODE PreviousMode
;
267 PreviousMode
= ExGetPreviousMode();
270 * Copy the strings to kernel space if necessary
272 Status
= ProbeAndCaptureUnicodeString(&CapturedName
,
275 if(NT_SUCCESS(Status
))
277 Status
= ProbeAndCaptureUnicodeString(&CapturedValue
,
280 if(NT_SUCCESS(Status
))
283 * according to ntinternals the SeSystemEnvironmentName privilege is required!
285 if(SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege
,
289 * convert the strings to ANSI
291 Status
= RtlUnicodeStringToAnsiString(&AName
,
294 if(NT_SUCCESS(Status
))
296 Status
= RtlUnicodeStringToAnsiString(&AValue
,
299 if(NT_SUCCESS(Status
))
301 BOOLEAN Result
= HalSetEnvironmentVariable(AName
.Buffer
,
304 Status
= (Result
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
310 DPRINT1("NtSetSystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
311 Status
= STATUS_PRIVILEGE_NOT_HELD
;
314 ReleaseCapturedUnicodeString(&CapturedValue
,
318 ReleaseCapturedUnicodeString(&CapturedName
,
326 /* --- Query/Set System Information --- */
329 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
330 * so the stack is popped only in one place on x86 platform.
332 #define QSI_USE(n) QSI##n
334 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
336 #define SSI_USE(n) SSI##n
338 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
341 /* Class 0 - Basic Information */
342 QSI_DEF(SystemBasicInformation
)
344 PSYSTEM_BASIC_INFORMATION Sbi
345 = (PSYSTEM_BASIC_INFORMATION
) Buffer
;
347 *ReqSize
= sizeof (SYSTEM_BASIC_INFORMATION
);
349 * Check user buffer's size
351 if (Size
!= sizeof (SYSTEM_BASIC_INFORMATION
))
353 return (STATUS_INFO_LENGTH_MISMATCH
);
356 Sbi
->TimerResolution
= KeMaximumIncrement
;
357 Sbi
->PageSize
= PAGE_SIZE
;
358 Sbi
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
359 Sbi
->LowestPhysicalPageNumber
= 0; /* FIXME */
360 Sbi
->HighestPhysicalPageNumber
= MmStats
.NrTotalPages
; /* FIXME */
361 Sbi
->AllocationGranularity
= MM_VIRTMEM_GRANULARITY
; /* hard coded on Intel? */
362 Sbi
->MinimumUserModeAddress
= 0x10000; /* Top of 64k */
363 Sbi
->MaximumUserModeAddress
= (ULONG_PTR
)MmHighestUserAddress
;
364 Sbi
->ActiveProcessorsAffinityMask
= KeActiveProcessors
;
365 Sbi
->NumberOfProcessors
= KeNumberProcessors
;
366 return (STATUS_SUCCESS
);
369 /* Class 1 - Processor Information */
370 QSI_DEF(SystemProcessorInformation
)
372 PSYSTEM_PROCESSOR_INFORMATION Spi
373 = (PSYSTEM_PROCESSOR_INFORMATION
) Buffer
;
375 *ReqSize
= sizeof (SYSTEM_PROCESSOR_INFORMATION
);
377 * Check user buffer's size
379 if (Size
< sizeof (SYSTEM_PROCESSOR_INFORMATION
))
381 return (STATUS_INFO_LENGTH_MISMATCH
);
383 Prcb
= KeGetCurrentPrcb();
384 Spi
->ProcessorArchitecture
= 0; /* Intel Processor */
385 Spi
->ProcessorLevel
= Prcb
->CpuType
;
386 Spi
->ProcessorRevision
= Prcb
->CpuStep
;
388 Spi
->ProcessorFeatureBits
= Prcb
->FeatureBits
;
390 DPRINT("Arch %d Level %d Rev 0x%x\n", Spi
->ProcessorArchitecture
,
391 Spi
->ProcessorLevel
, Spi
->ProcessorRevision
);
393 return (STATUS_SUCCESS
);
396 /* Class 2 - Performance Information */
397 QSI_DEF(SystemPerformanceInformation
)
399 PSYSTEM_PERFORMANCE_INFORMATION Spi
400 = (PSYSTEM_PERFORMANCE_INFORMATION
) Buffer
;
402 PEPROCESS TheIdleProcess
;
404 *ReqSize
= sizeof (SYSTEM_PERFORMANCE_INFORMATION
);
406 * Check user buffer's size
408 if (Size
< sizeof (SYSTEM_PERFORMANCE_INFORMATION
))
410 return (STATUS_INFO_LENGTH_MISMATCH
);
413 TheIdleProcess
= PsIdleProcess
;
415 Spi
->IdleProcessTime
.QuadPart
= TheIdleProcess
->Pcb
.KernelTime
* 100000LL;
417 Spi
->IoReadTransferCount
= IoReadTransferCount
;
418 Spi
->IoWriteTransferCount
= IoWriteTransferCount
;
419 Spi
->IoOtherTransferCount
= IoOtherTransferCount
;
420 Spi
->IoReadOperationCount
= IoReadOperationCount
;
421 Spi
->IoWriteOperationCount
= IoWriteOperationCount
;
422 Spi
->IoOtherOperationCount
= IoOtherOperationCount
;
424 Spi
->AvailablePages
= MmStats
.NrFreePages
;
426 Add up all the used "Commitied" memory + pagefile.
427 Not sure this is right. 8^\
429 Spi
->CommittedPages
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
+
430 MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
+
431 MiMemoryConsumers
[MC_CACHE
].PagesUsed
+
432 MiMemoryConsumers
[MC_USER
].PagesUsed
+
435 Add up the full system total + pagefile.
436 All this make Taskmgr happy but not sure it is the right numbers.
437 This too, fixes some of GlobalMemoryStatusEx numbers.
439 Spi
->CommitLimit
= MmStats
.NrTotalPages
+ MiFreeSwapPages
+
442 Spi
->PeakCommitment
= 0; /* FIXME */
443 Spi
->PageFaultCount
= 0; /* FIXME */
444 Spi
->CopyOnWriteCount
= 0; /* FIXME */
445 Spi
->TransitionCount
= 0; /* FIXME */
446 Spi
->CacheTransitionCount
= 0; /* FIXME */
447 Spi
->DemandZeroCount
= 0; /* FIXME */
448 Spi
->PageReadCount
= 0; /* FIXME */
449 Spi
->PageReadIoCount
= 0; /* FIXME */
450 Spi
->CacheReadCount
= 0; /* FIXME */
451 Spi
->CacheIoCount
= 0; /* FIXME */
452 Spi
->DirtyPagesWriteCount
= 0; /* FIXME */
453 Spi
->DirtyWriteIoCount
= 0; /* FIXME */
454 Spi
->MappedPagesWriteCount
= 0; /* FIXME */
455 Spi
->MappedWriteIoCount
= 0; /* FIXME */
457 Spi
->PagedPoolPages
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
;
458 Spi
->PagedPoolAllocs
= 0; /* FIXME */
459 Spi
->PagedPoolFrees
= 0; /* FIXME */
460 Spi
->NonPagedPoolPages
= MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
;
461 Spi
->NonPagedPoolAllocs
= 0; /* FIXME */
462 Spi
->NonPagedPoolFrees
= 0; /* FIXME */
464 Spi
->FreeSystemPtes
= 0; /* FIXME */
466 Spi
->ResidentSystemCodePage
= MmStats
.NrSystemPages
; /* FIXME */
468 Spi
->TotalSystemDriverPages
= 0; /* FIXME */
469 Spi
->TotalSystemCodePages
= 0; /* FIXME */
470 Spi
->NonPagedPoolLookasideHits
= 0; /* FIXME */
471 Spi
->PagedPoolLookasideHits
= 0; /* FIXME */
472 Spi
->Spare3Count
= 0; /* FIXME */
474 Spi
->ResidentSystemCachePage
= MiMemoryConsumers
[MC_CACHE
].PagesUsed
;
475 Spi
->ResidentPagedPoolPage
= MmPagedPoolSize
; /* FIXME */
477 Spi
->ResidentSystemDriverPage
= 0; /* FIXME */
478 Spi
->CcFastReadNoWait
= 0; /* FIXME */
479 Spi
->CcFastReadWait
= 0; /* FIXME */
480 Spi
->CcFastReadResourceMiss
= 0; /* FIXME */
481 Spi
->CcFastReadNotPossible
= 0; /* FIXME */
483 Spi
->CcFastMdlReadNoWait
= 0; /* FIXME */
484 Spi
->CcFastMdlReadWait
= 0; /* FIXME */
485 Spi
->CcFastMdlReadResourceMiss
= 0; /* FIXME */
486 Spi
->CcFastMdlReadNotPossible
= 0; /* FIXME */
488 Spi
->CcMapDataNoWait
= 0; /* FIXME */
489 Spi
->CcMapDataWait
= 0; /* FIXME */
490 Spi
->CcMapDataNoWaitMiss
= 0; /* FIXME */
491 Spi
->CcMapDataWaitMiss
= 0; /* FIXME */
493 Spi
->CcPinMappedDataCount
= 0; /* FIXME */
494 Spi
->CcPinReadNoWait
= 0; /* FIXME */
495 Spi
->CcPinReadWait
= 0; /* FIXME */
496 Spi
->CcPinReadNoWaitMiss
= 0; /* FIXME */
497 Spi
->CcPinReadWaitMiss
= 0; /* FIXME */
498 Spi
->CcCopyReadNoWait
= 0; /* FIXME */
499 Spi
->CcCopyReadWait
= 0; /* FIXME */
500 Spi
->CcCopyReadNoWaitMiss
= 0; /* FIXME */
501 Spi
->CcCopyReadWaitMiss
= 0; /* FIXME */
503 Spi
->CcMdlReadNoWait
= 0; /* FIXME */
504 Spi
->CcMdlReadWait
= 0; /* FIXME */
505 Spi
->CcMdlReadNoWaitMiss
= 0; /* FIXME */
506 Spi
->CcMdlReadWaitMiss
= 0; /* FIXME */
507 Spi
->CcReadAheadIos
= 0; /* FIXME */
508 Spi
->CcLazyWriteIos
= 0; /* FIXME */
509 Spi
->CcLazyWritePages
= 0; /* FIXME */
510 Spi
->CcDataFlushes
= 0; /* FIXME */
511 Spi
->CcDataPages
= 0; /* FIXME */
512 Spi
->ContextSwitches
= 0; /* FIXME */
513 Spi
->FirstLevelTbFills
= 0; /* FIXME */
514 Spi
->SecondLevelTbFills
= 0; /* FIXME */
515 Spi
->SystemCalls
= 0; /* FIXME */
517 return (STATUS_SUCCESS
);
520 /* Class 3 - Time Of Day Information */
521 QSI_DEF(SystemTimeOfDayInformation
)
523 PSYSTEM_TIMEOFDAY_INFORMATION Sti
;
524 LARGE_INTEGER CurrentTime
;
526 Sti
= (PSYSTEM_TIMEOFDAY_INFORMATION
)Buffer
;
527 *ReqSize
= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
);
529 /* Check user buffer's size */
530 if (Size
!= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
))
532 return STATUS_INFO_LENGTH_MISMATCH
;
535 KeQuerySystemTime(&CurrentTime
);
537 Sti
->BootTime
= SystemBootTime
;
538 Sti
->CurrentTime
= CurrentTime
;
539 Sti
->TimeZoneBias
.QuadPart
= ExpTimeZoneBias
.QuadPart
;
540 Sti
->TimeZoneId
= ExpTimeZoneId
;
543 return STATUS_SUCCESS
;
546 /* Class 4 - Path Information */
547 QSI_DEF(SystemPathInformation
)
549 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
550 DPRINT1("NtQuerySystemInformation - SystemPathInformation not implemented\n");
552 return (STATUS_BREAKPOINT
);
555 /* Class 5 - Process Information */
556 QSI_DEF(SystemProcessInformation
)
558 ULONG ovlSize
= 0, nThreads
;
559 PEPROCESS pr
= NULL
, syspr
;
561 NTSTATUS Status
= STATUS_SUCCESS
;
565 /* scan the process list */
567 PSYSTEM_PROCESS_INFORMATION Spi
568 = (PSYSTEM_PROCESS_INFORMATION
) Buffer
;
570 *ReqSize
= sizeof(SYSTEM_PROCESS_INFORMATION
);
572 if (Size
< sizeof(SYSTEM_PROCESS_INFORMATION
))
574 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
577 syspr
= PsGetNextProcess(NULL
);
579 pCur
= (unsigned char *)Spi
;
583 PSYSTEM_PROCESS_INFORMATION SpiCur
;
586 int inLen
=32; // image name len in bytes
587 PLIST_ENTRY current_entry
;
590 SpiCur
= (PSYSTEM_PROCESS_INFORMATION
)pCur
;
593 current_entry
= pr
->ThreadListHead
.Flink
;
594 while (current_entry
!= &pr
->ThreadListHead
)
597 current_entry
= current_entry
->Flink
;
600 // size of the structure for every process
601 curSize
= sizeof(SYSTEM_PROCESS_INFORMATION
)-sizeof(SYSTEM_THREAD_INFORMATION
)+sizeof(SYSTEM_THREAD_INFORMATION
)*nThreads
;
602 ovlSize
+= curSize
+inLen
;
607 ObDereferenceObject(pr
);
609 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
612 // fill system information
613 SpiCur
->NextEntryOffset
= curSize
+inLen
; // relative offset to the beginnnig of the next structure
614 SpiCur
->NumberOfThreads
= nThreads
;
615 SpiCur
->CreateTime
= pr
->CreateTime
;
616 SpiCur
->UserTime
.QuadPart
= pr
->Pcb
.UserTime
* 100000LL;
617 SpiCur
->KernelTime
.QuadPart
= pr
->Pcb
.KernelTime
* 100000LL;
618 SpiCur
->ImageName
.Length
= strlen(pr
->ImageFileName
) * sizeof(WCHAR
);
619 SpiCur
->ImageName
.MaximumLength
= inLen
;
620 SpiCur
->ImageName
.Buffer
= (void*)(pCur
+curSize
);
622 // copy name to the end of the struct
623 if(pr
!= PsIdleProcess
)
625 RtlInitAnsiString(&imgName
, pr
->ImageFileName
);
626 RtlAnsiStringToUnicodeString(&SpiCur
->ImageName
, &imgName
, FALSE
);
630 RtlInitUnicodeString(&SpiCur
->ImageName
, NULL
);
633 SpiCur
->BasePriority
= pr
->Pcb
.BasePriority
;
634 SpiCur
->UniqueProcessId
= pr
->UniqueProcessId
;
635 SpiCur
->InheritedFromUniqueProcessId
= pr
->InheritedFromUniqueProcessId
;
636 SpiCur
->HandleCount
= (pr
->ObjectTable
? ObpGetHandleCountByHandleTable(pr
->ObjectTable
) : 0);
637 SpiCur
->PeakVirtualSize
= pr
->PeakVirtualSize
;
638 SpiCur
->VirtualSize
= pr
->VirtualSize
;
639 SpiCur
->PageFaultCount
= pr
->Vm
.PageFaultCount
;
640 SpiCur
->PeakWorkingSetSize
= pr
->Vm
.PeakWorkingSetSize
;
641 SpiCur
->WorkingSetSize
= pr
->Vm
.WorkingSetSize
;
642 SpiCur
->QuotaPeakPagedPoolUsage
= pr
->QuotaPeak
[0];
643 SpiCur
->QuotaPagedPoolUsage
= pr
->QuotaUsage
[0];
644 SpiCur
->QuotaPeakNonPagedPoolUsage
= pr
->QuotaPeak
[1];
645 SpiCur
->QuotaNonPagedPoolUsage
= pr
->QuotaUsage
[1];
646 SpiCur
->PagefileUsage
= pr
->QuotaUsage
[3];
647 SpiCur
->PeakPagefileUsage
= pr
->QuotaPeak
[3];
648 SpiCur
->PrivateUsage
= pr
->CommitCharge
;
650 current_entry
= pr
->ThreadListHead
.Flink
;
651 while (current_entry
!= &pr
->ThreadListHead
)
653 current
= CONTAINING_RECORD(current_entry
, ETHREAD
,
656 SpiCur
->TH
[i
].KernelTime
.QuadPart
= current
->Tcb
.KernelTime
* 100000LL;
657 SpiCur
->TH
[i
].UserTime
.QuadPart
= current
->Tcb
.UserTime
* 100000LL;
658 // SpiCur->TH[i].CreateTime = current->CreateTime;
659 SpiCur
->TH
[i
].WaitTime
= current
->Tcb
.WaitTime
;
660 SpiCur
->TH
[i
].StartAddress
= (PVOID
) current
->StartAddress
;
661 SpiCur
->TH
[i
].ClientId
= current
->Cid
;
662 SpiCur
->TH
[i
].Priority
= current
->Tcb
.Priority
;
663 SpiCur
->TH
[i
].BasePriority
= current
->Tcb
.BasePriority
;
664 SpiCur
->TH
[i
].ContextSwitches
= current
->Tcb
.ContextSwitches
;
665 SpiCur
->TH
[i
].ThreadState
= current
->Tcb
.State
;
666 SpiCur
->TH
[i
].WaitReason
= current
->Tcb
.WaitReason
;
668 current_entry
= current_entry
->Flink
;
671 pr
= PsGetNextProcess(pr
);
673 if ((pr
== syspr
) || (pr
== NULL
))
675 SpiCur
->NextEntryOffset
= 0;
679 pCur
= pCur
+ curSize
+ inLen
;
680 } while ((pr
!= syspr
) && (pr
!= NULL
));
683 ObDereferenceObject(pr
);
684 Status
= STATUS_SUCCESS
;
689 ObDereferenceObject(pr
);
690 Status
= _SEH_GetExceptionCode();
698 /* Class 6 - Call Count Information */
699 QSI_DEF(SystemCallCountInformation
)
702 DPRINT1("NtQuerySystemInformation - SystemCallCountInformation not implemented\n");
703 return (STATUS_NOT_IMPLEMENTED
);
706 /* Class 7 - Device Information */
707 QSI_DEF(SystemDeviceInformation
)
709 PSYSTEM_DEVICE_INFORMATION Sdi
710 = (PSYSTEM_DEVICE_INFORMATION
) Buffer
;
711 PCONFIGURATION_INFORMATION ConfigInfo
;
713 *ReqSize
= sizeof (SYSTEM_DEVICE_INFORMATION
);
715 * Check user buffer's size
717 if (Size
< sizeof (SYSTEM_DEVICE_INFORMATION
))
719 return (STATUS_INFO_LENGTH_MISMATCH
);
722 ConfigInfo
= IoGetConfigurationInformation ();
724 Sdi
->NumberOfDisks
= ConfigInfo
->DiskCount
;
725 Sdi
->NumberOfFloppies
= ConfigInfo
->FloppyCount
;
726 Sdi
->NumberOfCdRoms
= ConfigInfo
->CdRomCount
;
727 Sdi
->NumberOfTapes
= ConfigInfo
->TapeCount
;
728 Sdi
->NumberOfSerialPorts
= ConfigInfo
->SerialCount
;
729 Sdi
->NumberOfParallelPorts
= ConfigInfo
->ParallelCount
;
731 return (STATUS_SUCCESS
);
734 /* Class 8 - Processor Performance Information */
735 QSI_DEF(SystemProcessorPerformanceInformation
)
737 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
738 = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) Buffer
;
741 LARGE_INTEGER CurrentTime
;
744 *ReqSize
= KeNumberProcessors
* sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
);
746 * Check user buffer's size
748 if (Size
< KeNumberProcessors
* sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
))
750 return (STATUS_INFO_LENGTH_MISMATCH
);
753 CurrentTime
.QuadPart
= KeQueryInterruptTime();
754 Prcb
= ((PKPCR
)KPCR_BASE
)->Prcb
;
755 for (i
= 0; i
< KeNumberProcessors
; i
++)
757 Spi
->IdleTime
.QuadPart
= (Prcb
->IdleThread
->KernelTime
+ Prcb
->IdleThread
->UserTime
) * 100000LL; // IdleTime
758 Spi
->KernelTime
.QuadPart
= Prcb
->KernelTime
* 100000LL; // KernelTime
759 Spi
->UserTime
.QuadPart
= Prcb
->UserTime
* 100000LL;
760 Spi
->DpcTime
.QuadPart
= Prcb
->DpcTime
* 100000LL;
761 Spi
->InterruptTime
.QuadPart
= Prcb
->InterruptTime
* 100000LL;
762 Spi
->InterruptCount
= Prcb
->InterruptCount
; // Interrupt Count
764 Prcb
= (PKPRCB
)((ULONG_PTR
)Prcb
+ PAGE_SIZE
);
767 return (STATUS_SUCCESS
);
770 /* Class 9 - Flags Information */
771 QSI_DEF(SystemFlagsInformation
)
773 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
775 * ReqSize
= sizeof (SYSTEM_FLAGS_INFORMATION
);
776 return (STATUS_INFO_LENGTH_MISMATCH
);
778 ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
= NtGlobalFlag
;
779 return (STATUS_SUCCESS
);
782 SSI_DEF(SystemFlagsInformation
)
784 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
786 return (STATUS_INFO_LENGTH_MISMATCH
);
788 NtGlobalFlag
= ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
;
789 return (STATUS_SUCCESS
);
792 /* Class 10 - Call Time Information */
793 QSI_DEF(SystemCallTimeInformation
)
796 DPRINT1("NtQuerySystemInformation - SystemCallTimeInformation not implemented\n");
797 return (STATUS_NOT_IMPLEMENTED
);
800 /* Class 11 - Module Information */
801 QSI_DEF(SystemModuleInformation
)
803 return LdrpQueryModuleInformation(Buffer
, Size
, ReqSize
);
806 /* Class 12 - Locks Information */
807 QSI_DEF(SystemLocksInformation
)
810 DPRINT1("NtQuerySystemInformation - SystemLocksInformation not implemented\n");
811 return (STATUS_NOT_IMPLEMENTED
);
814 /* Class 13 - Stack Trace Information */
815 QSI_DEF(SystemStackTraceInformation
)
818 DPRINT1("NtQuerySystemInformation - SystemStackTraceInformation not implemented\n");
819 return (STATUS_NOT_IMPLEMENTED
);
822 /* Class 14 - Paged Pool Information */
823 QSI_DEF(SystemPagedPoolInformation
)
826 DPRINT1("NtQuerySystemInformation - SystemPagedPoolInformation not implemented\n");
827 return (STATUS_NOT_IMPLEMENTED
);
830 /* Class 15 - Non Paged Pool Information */
831 QSI_DEF(SystemNonPagedPoolInformation
)
834 DPRINT1("NtQuerySystemInformation - SystemNonPagedPoolInformation not implemented\n");
835 return (STATUS_NOT_IMPLEMENTED
);
840 ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi
,
844 /* Class 16 - Handle Information */
845 QSI_DEF(SystemHandleInformation
)
848 ULONG curSize
, i
= 0;
851 PSYSTEM_HANDLE_INFORMATION Shi
=
852 (PSYSTEM_HANDLE_INFORMATION
) Buffer
;
854 DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
856 if (Size
< sizeof (SYSTEM_HANDLE_INFORMATION
))
858 * ReqSize
= sizeof (SYSTEM_HANDLE_INFORMATION
);
859 return (STATUS_INFO_LENGTH_MISMATCH
);
862 DPRINT("SystemHandleInformation 1\n");
864 /* First Calc Size from Count. */
865 syspr
= PsGetNextProcess(NULL
);
870 hCount
= hCount
+ (pr
->ObjectTable
? ObpGetHandleCountByHandleTable(pr
->ObjectTable
) : 0);
871 pr
= PsGetNextProcess(pr
);
873 if ((pr
== syspr
) || (pr
== NULL
))
875 } while ((pr
!= syspr
) && (pr
!= NULL
));
879 ObDereferenceObject(pr
);
882 DPRINT("SystemHandleInformation 2\n");
884 curSize
= sizeof(SYSTEM_HANDLE_INFORMATION
)+
885 ( (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO
) * hCount
) -
886 (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO
) ));
888 Shi
->NumberOfHandles
= hCount
;
893 return (STATUS_INFO_LENGTH_MISMATCH
);
896 DPRINT("SystemHandleInformation 3\n");
898 /* Now get Handles from all processs. */
899 syspr
= PsGetNextProcess(NULL
);
904 int Count
= 0, HandleCount
;
906 HandleCount
= (pr
->ObjectTable
? ObpGetHandleCountByHandleTable(pr
->ObjectTable
) : 0);
908 for (Count
= 0; HandleCount
> 0 ; HandleCount
--)
910 ObpGetNextHandleByProcessCount( &Shi
->Handles
[i
], pr
, Count
);
915 pr
= PsGetNextProcess(pr
);
917 if ((pr
== syspr
) || (pr
== NULL
))
919 } while ((pr
!= syspr
) && (pr
!= NULL
));
923 ObDereferenceObject(pr
);
926 DPRINT("SystemHandleInformation 4\n");
927 return (STATUS_SUCCESS
);
931 SSI_DEF(SystemHandleInformation)
934 return (STATUS_SUCCESS);
938 /* Class 17 - Information */
939 QSI_DEF(SystemObjectInformation
)
942 DPRINT1("NtQuerySystemInformation - SystemObjectInformation not implemented\n");
943 return (STATUS_NOT_IMPLEMENTED
);
946 /* Class 18 - Information */
947 QSI_DEF(SystemPageFileInformation
)
949 UNICODE_STRING FileName
; /* FIXME */
950 SYSTEM_PAGEFILE_INFORMATION
*Spfi
= (SYSTEM_PAGEFILE_INFORMATION
*) Buffer
;
952 if (Size
< sizeof (SYSTEM_PAGEFILE_INFORMATION
))
954 * ReqSize
= sizeof (SYSTEM_PAGEFILE_INFORMATION
);
955 return (STATUS_INFO_LENGTH_MISMATCH
);
958 RtlInitUnicodeString(&FileName
, NULL
); /* FIXME */
961 Spfi
->NextEntryOffset
= 0;
963 Spfi
->TotalSize
= MiFreeSwapPages
+ MiUsedSwapPages
;
964 Spfi
->TotalInUse
= MiUsedSwapPages
;
965 Spfi
->PeakUsage
= MiUsedSwapPages
; /* FIXME */
966 Spfi
->PageFileName
= FileName
;
967 return (STATUS_SUCCESS
);
970 /* Class 19 - Vdm Instemul Information */
971 QSI_DEF(SystemVdmInstemulInformation
)
974 DPRINT1("NtQuerySystemInformation - SystemVdmInstemulInformation not implemented\n");
975 return (STATUS_NOT_IMPLEMENTED
);
978 /* Class 20 - Vdm Bop Information */
979 QSI_DEF(SystemVdmBopInformation
)
982 DPRINT1("NtQuerySystemInformation - SystemVdmBopInformation not implemented\n");
983 return (STATUS_NOT_IMPLEMENTED
);
986 /* Class 21 - File Cache Information */
987 QSI_DEF(SystemFileCacheInformation
)
989 SYSTEM_CACHE_INFORMATION
*Sci
= (SYSTEM_CACHE_INFORMATION
*) Buffer
;
991 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
993 * ReqSize
= sizeof (SYSTEM_CACHE_INFORMATION
);
994 return (STATUS_INFO_LENGTH_MISMATCH
);
997 RtlZeroMemory(Sci
, sizeof(SYSTEM_CACHE_INFORMATION
));
999 /* Return the Byte size not the page size. */
1001 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
;
1003 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
; /* FIXME */
1005 Sci
->PageFaultCount
= 0; /* FIXME */
1006 Sci
->MinimumWorkingSet
= 0; /* FIXME */
1007 Sci
->MaximumWorkingSet
= 0; /* FIXME */
1009 return (STATUS_SUCCESS
);
1012 SSI_DEF(SystemFileCacheInformation
)
1014 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
1016 return (STATUS_INFO_LENGTH_MISMATCH
);
1019 DPRINT1("NtSetSystemInformation - SystemFileCacheInformation not implemented\n");
1020 return (STATUS_NOT_IMPLEMENTED
);
1023 /* Class 22 - Pool Tag Information */
1024 QSI_DEF(SystemPoolTagInformation
)
1027 DPRINT1("NtQuerySystemInformation - SystemPoolTagInformation not implemented\n");
1028 return (STATUS_NOT_IMPLEMENTED
);
1031 /* Class 23 - Interrupt Information for all processors */
1032 QSI_DEF(SystemInterruptInformation
)
1037 PSYSTEM_INTERRUPT_INFORMATION sii
= (PSYSTEM_INTERRUPT_INFORMATION
)Buffer
;
1039 if(Size
< KeNumberProcessors
* sizeof(SYSTEM_INTERRUPT_INFORMATION
))
1041 return (STATUS_INFO_LENGTH_MISMATCH
);
1044 ti
= KeQueryTimeIncrement();
1046 Prcb
= ((PKPCR
)KPCR_BASE
)->Prcb
;
1047 for (i
= 0; i
< KeNumberProcessors
; i
++)
1049 sii
->ContextSwitches
= Prcb
->KeContextSwitches
;
1050 sii
->DpcCount
= 0; /* FIXME */
1051 sii
->DpcRate
= 0; /* FIXME */
1052 sii
->TimeIncrement
= ti
;
1053 sii
->DpcBypassCount
= 0; /* FIXME */
1054 sii
->ApcBypassCount
= 0; /* FIXME */
1056 Prcb
= (PKPRCB
)((ULONG_PTR
)Prcb
+ PAGE_SIZE
);
1059 return STATUS_SUCCESS
;
1062 /* Class 24 - DPC Behaviour Information */
1063 QSI_DEF(SystemDpcBehaviourInformation
)
1066 DPRINT1("NtQuerySystemInformation - SystemDpcBehaviourInformation not implemented\n");
1067 return (STATUS_NOT_IMPLEMENTED
);
1070 SSI_DEF(SystemDpcBehaviourInformation
)
1073 DPRINT1("NtSetSystemInformation - SystemDpcBehaviourInformation not implemented\n");
1074 return (STATUS_NOT_IMPLEMENTED
);
1077 /* Class 25 - Full Memory Information */
1078 QSI_DEF(SystemFullMemoryInformation
)
1080 PULONG Spi
= (PULONG
) Buffer
;
1082 PEPROCESS TheIdleProcess
;
1084 * ReqSize
= sizeof (ULONG
);
1086 if (sizeof (ULONG
) != Size
)
1088 return (STATUS_INFO_LENGTH_MISMATCH
);
1090 DPRINT("SystemFullMemoryInformation\n");
1092 TheIdleProcess
= PsIdleProcess
;
1094 DPRINT("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
1095 TheIdleProcess
->UniqueProcessId
,
1096 TheIdleProcess
->Pcb
.KernelTime
,
1101 MmPrintMemoryStatistic();
1104 *Spi
= MiMemoryConsumers
[MC_USER
].PagesUsed
;
1106 return (STATUS_SUCCESS
);
1109 /* Class 26 - Load Image */
1110 SSI_DEF(SystemLoadImage
)
1112 PSYSTEM_GDI_DRIVER_INFORMATION Sli
= (PSYSTEM_GDI_DRIVER_INFORMATION
)Buffer
;
1114 if (sizeof(SYSTEM_GDI_DRIVER_INFORMATION
) != Size
)
1116 return(STATUS_INFO_LENGTH_MISMATCH
);
1119 return(LdrpLoadImage(&Sli
->DriverName
,
1121 &Sli
->SectionPointer
,
1123 (PVOID
)&Sli
->ExportSectionPointer
));
1126 /* Class 27 - Unload Image */
1127 SSI_DEF(SystemUnloadImage
)
1129 PVOID Sui
= (PVOID
)Buffer
;
1131 if (sizeof(PVOID
) != Size
)
1133 return(STATUS_INFO_LENGTH_MISMATCH
);
1136 return(LdrpUnloadImage(Sui
));
1139 /* Class 28 - Time Adjustment Information */
1140 QSI_DEF(SystemTimeAdjustmentInformation
)
1142 if (sizeof (SYSTEM_SET_TIME_ADJUST_INFORMATION
) > Size
)
1144 * ReqSize
= sizeof (SYSTEM_SET_TIME_ADJUST_INFORMATION
);
1145 return (STATUS_INFO_LENGTH_MISMATCH
);
1148 DPRINT1("NtQuerySystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1149 return (STATUS_NOT_IMPLEMENTED
);
1152 SSI_DEF(SystemTimeAdjustmentInformation
)
1154 if (sizeof (SYSTEM_SET_TIME_ADJUST_INFORMATION
) > Size
)
1156 return (STATUS_INFO_LENGTH_MISMATCH
);
1159 DPRINT1("NtSetSystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1160 return (STATUS_NOT_IMPLEMENTED
);
1163 /* Class 29 - Summary Memory Information */
1164 QSI_DEF(SystemSummaryMemoryInformation
)
1167 DPRINT1("NtQuerySystemInformation - SystemSummaryMemoryInformation not implemented\n");
1168 return (STATUS_NOT_IMPLEMENTED
);
1171 /* Class 30 - Next Event Id Information */
1172 QSI_DEF(SystemNextEventIdInformation
)
1175 DPRINT1("NtQuerySystemInformation - SystemNextEventIdInformation not implemented\n");
1176 return (STATUS_NOT_IMPLEMENTED
);
1179 /* Class 31 - Event Ids Information */
1180 QSI_DEF(SystemEventIdsInformation
)
1183 DPRINT1("NtQuerySystemInformation - SystemEventIdsInformation not implemented\n");
1184 return (STATUS_NOT_IMPLEMENTED
);
1187 /* Class 32 - Crash Dump Information */
1188 QSI_DEF(SystemCrashDumpInformation
)
1191 DPRINT1("NtQuerySystemInformation - SystemCrashDumpInformation not implemented\n");
1192 return (STATUS_NOT_IMPLEMENTED
);
1195 /* Class 33 - Exception Information */
1196 QSI_DEF(SystemExceptionInformation
)
1199 DPRINT1("NtQuerySystemInformation - SystemExceptionInformation not implemented\n");
1200 return (STATUS_NOT_IMPLEMENTED
);
1203 /* Class 34 - Crash Dump State Information */
1204 QSI_DEF(SystemCrashDumpStateInformation
)
1207 DPRINT1("NtQuerySystemInformation - SystemCrashDumpStateInformation not implemented\n");
1208 return (STATUS_NOT_IMPLEMENTED
);
1211 /* Class 35 - Kernel Debugger Information */
1212 QSI_DEF(SystemKernelDebuggerInformation
)
1214 PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi
= (PSYSTEM_KERNEL_DEBUGGER_INFORMATION
) Buffer
;
1216 *ReqSize
= sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION
);
1217 if (Size
< sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION
))
1219 return STATUS_INFO_LENGTH_MISMATCH
;
1222 skdi
->KernelDebuggerEnabled
= KD_DEBUGGER_ENABLED
;
1223 skdi
->KernelDebuggerNotPresent
= KD_DEBUGGER_NOT_PRESENT
;
1225 return STATUS_SUCCESS
;
1228 /* Class 36 - Context Switch Information */
1229 QSI_DEF(SystemContextSwitchInformation
)
1232 DPRINT1("NtQuerySystemInformation - SystemContextSwitchInformation not implemented\n");
1233 return (STATUS_NOT_IMPLEMENTED
);
1236 /* Class 37 - Registry Quota Information */
1237 QSI_DEF(SystemRegistryQuotaInformation
)
1239 PSYSTEM_REGISTRY_QUOTA_INFORMATION srqi
= (PSYSTEM_REGISTRY_QUOTA_INFORMATION
) Buffer
;
1241 *ReqSize
= sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION
);
1242 if (Size
< sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION
))
1244 return STATUS_INFO_LENGTH_MISMATCH
;
1247 DPRINT1("Faking max registry size of 32 MB\n");
1248 srqi
->RegistryQuotaAllowed
= 0x2000000;
1249 srqi
->RegistryQuotaUsed
= 0x200000;
1250 srqi
->PagedPoolSize
= 0x200000;
1252 return STATUS_SUCCESS
;
1255 SSI_DEF(SystemRegistryQuotaInformation
)
1258 DPRINT1("NtSetSystemInformation - SystemRegistryQuotaInformation not implemented\n");
1259 return (STATUS_NOT_IMPLEMENTED
);
1262 /* Class 38 - Load And Call Image */
1263 SSI_DEF(SystemLoadAndCallImage
)
1265 PUNICODE_STRING Slci
= (PUNICODE_STRING
)Buffer
;
1267 if (sizeof(UNICODE_STRING
) != Size
)
1269 return(STATUS_INFO_LENGTH_MISMATCH
);
1272 return(LdrpLoadAndCallImage(Slci
));
1275 /* Class 39 - Priority Separation */
1276 SSI_DEF(SystemPrioritySeperation
)
1279 DPRINT1("NtSetSystemInformation - SystemPrioritySeperation not implemented\n");
1280 return (STATUS_NOT_IMPLEMENTED
);
1283 /* Class 40 - Plug Play Bus Information */
1284 QSI_DEF(SystemPlugPlayBusInformation
)
1287 DPRINT1("NtQuerySystemInformation - SystemPlugPlayBusInformation not implemented\n");
1288 return (STATUS_NOT_IMPLEMENTED
);
1291 /* Class 41 - Dock Information */
1292 QSI_DEF(SystemDockInformation
)
1295 DPRINT1("NtQuerySystemInformation - SystemDockInformation not implemented\n");
1296 return (STATUS_NOT_IMPLEMENTED
);
1299 /* Class 42 - Power Information */
1300 QSI_DEF(SystemPowerInformation
)
1303 DPRINT1("NtQuerySystemInformation - SystemPowerInformation not implemented\n");
1304 return (STATUS_NOT_IMPLEMENTED
);
1307 /* Class 43 - Processor Speed Information */
1308 QSI_DEF(SystemProcessorSpeedInformation
)
1311 DPRINT1("NtQuerySystemInformation - SystemProcessorSpeedInformation not implemented\n");
1312 return (STATUS_NOT_IMPLEMENTED
);
1315 /* Class 44 - Current Time Zone Information */
1316 QSI_DEF(SystemCurrentTimeZoneInformation
)
1318 * ReqSize
= sizeof (TIME_ZONE_INFORMATION
);
1320 if (sizeof (TIME_ZONE_INFORMATION
) != Size
)
1322 return STATUS_INFO_LENGTH_MISMATCH
;
1325 /* Copy the time zone information struct */
1328 sizeof(TIME_ZONE_INFORMATION
));
1330 return STATUS_SUCCESS
;
1334 SSI_DEF(SystemCurrentTimeZoneInformation
)
1336 /* Check user buffer's size */
1337 if (Size
< sizeof (TIME_ZONE_INFORMATION
))
1339 return STATUS_INFO_LENGTH_MISMATCH
;
1342 return ExpSetTimeZoneInformation((PTIME_ZONE_INFORMATION
)Buffer
);
1346 /* Class 45 - Lookaside Information */
1347 QSI_DEF(SystemLookasideInformation
)
1350 DPRINT1("NtQuerySystemInformation - SystemLookasideInformation not implemented\n");
1351 return (STATUS_NOT_IMPLEMENTED
);
1355 /* Class 46 - Set time slip event */
1356 SSI_DEF(SystemSetTimeSlipEvent
)
1359 DPRINT1("NtSetSystemInformation - SystemSetTimSlipEvent not implemented\n");
1360 return (STATUS_NOT_IMPLEMENTED
);
1364 /* Class 47 - Create a new session (TSE) */
1365 SSI_DEF(SystemCreateSession
)
1368 DPRINT1("NtSetSystemInformation - SystemCreateSession not implemented\n");
1369 return (STATUS_NOT_IMPLEMENTED
);
1373 /* Class 48 - Delete an existing session (TSE) */
1374 SSI_DEF(SystemDeleteSession
)
1377 DPRINT1("NtSetSystemInformation - SystemDeleteSession not implemented\n");
1378 return (STATUS_NOT_IMPLEMENTED
);
1382 /* Class 49 - UNKNOWN */
1383 QSI_DEF(SystemInvalidInfoClass4
)
1386 DPRINT1("NtQuerySystemInformation - SystemInvalidInfoClass4 not implemented\n");
1387 return (STATUS_NOT_IMPLEMENTED
);
1391 /* Class 50 - System range start address */
1392 QSI_DEF(SystemRangeStartInformation
)
1395 DPRINT1("NtQuerySystemInformation - SystemRangeStartInformation not implemented\n");
1396 return (STATUS_NOT_IMPLEMENTED
);
1400 /* Class 51 - Driver verifier information */
1401 QSI_DEF(SystemVerifierInformation
)
1404 DPRINT1("NtQuerySystemInformation - SystemVerifierInformation not implemented\n");
1405 return (STATUS_NOT_IMPLEMENTED
);
1409 SSI_DEF(SystemVerifierInformation
)
1412 DPRINT1("NtSetSystemInformation - SystemVerifierInformation not implemented\n");
1413 return (STATUS_NOT_IMPLEMENTED
);
1417 /* Class 52 - Add a driver verifier */
1418 SSI_DEF(SystemAddVerifier
)
1421 DPRINT1("NtSetSystemInformation - SystemAddVerifier not implemented\n");
1422 return (STATUS_NOT_IMPLEMENTED
);
1426 /* Class 53 - A session's processes */
1427 QSI_DEF(SystemSessionProcessesInformation
)
1430 DPRINT1("NtQuerySystemInformation - SystemSessionProcessInformation not implemented\n");
1431 return (STATUS_NOT_IMPLEMENTED
);
1435 /* Query/Set Calls Table */
1439 NTSTATUS (* Query
) (PVOID
,ULONG
,PULONG
);
1440 NTSTATUS (* Set
) (PVOID
,ULONG
);
1447 // XX unknown behaviour
1449 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1450 #define SI_QX(n) {QSI_USE(n),NULL}
1451 #define SI_XS(n) {NULL,SSI_USE(n)}
1452 #define SI_XX(n) {NULL,NULL}
1458 SI_QX(SystemBasicInformation
),
1459 SI_QX(SystemProcessorInformation
),
1460 SI_QX(SystemPerformanceInformation
),
1461 SI_QX(SystemTimeOfDayInformation
),
1462 SI_QX(SystemPathInformation
), /* should be SI_XX */
1463 SI_QX(SystemProcessInformation
),
1464 SI_QX(SystemCallCountInformation
),
1465 SI_QX(SystemDeviceInformation
),
1466 SI_QX(SystemProcessorPerformanceInformation
),
1467 SI_QS(SystemFlagsInformation
),
1468 SI_QX(SystemCallTimeInformation
), /* should be SI_XX */
1469 SI_QX(SystemModuleInformation
),
1470 SI_QX(SystemLocksInformation
),
1471 SI_QX(SystemStackTraceInformation
), /* should be SI_XX */
1472 SI_QX(SystemPagedPoolInformation
), /* should be SI_XX */
1473 SI_QX(SystemNonPagedPoolInformation
), /* should be SI_XX */
1474 SI_QX(SystemHandleInformation
),
1475 SI_QX(SystemObjectInformation
),
1476 SI_QX(SystemPageFileInformation
),
1477 SI_QX(SystemVdmInstemulInformation
),
1478 SI_QX(SystemVdmBopInformation
), /* it should be SI_XX */
1479 SI_QS(SystemFileCacheInformation
),
1480 SI_QX(SystemPoolTagInformation
),
1481 SI_QX(SystemInterruptInformation
),
1482 SI_QS(SystemDpcBehaviourInformation
),
1483 SI_QX(SystemFullMemoryInformation
), /* it should be SI_XX */
1484 SI_XS(SystemLoadImage
),
1485 SI_XS(SystemUnloadImage
),
1486 SI_QS(SystemTimeAdjustmentInformation
),
1487 SI_QX(SystemSummaryMemoryInformation
), /* it should be SI_XX */
1488 SI_QX(SystemNextEventIdInformation
), /* it should be SI_XX */
1489 SI_QX(SystemEventIdsInformation
), /* it should be SI_XX */
1490 SI_QX(SystemCrashDumpInformation
),
1491 SI_QX(SystemExceptionInformation
),
1492 SI_QX(SystemCrashDumpStateInformation
),
1493 SI_QX(SystemKernelDebuggerInformation
),
1494 SI_QX(SystemContextSwitchInformation
),
1495 SI_QS(SystemRegistryQuotaInformation
),
1496 SI_XS(SystemLoadAndCallImage
),
1497 SI_XS(SystemPrioritySeperation
),
1498 SI_QX(SystemPlugPlayBusInformation
), /* it should be SI_XX */
1499 SI_QX(SystemDockInformation
), /* it should be SI_XX */
1500 SI_QX(SystemPowerInformation
), /* it should be SI_XX */
1501 SI_QX(SystemProcessorSpeedInformation
), /* it should be SI_XX */
1502 SI_QS(SystemCurrentTimeZoneInformation
), /* it should be SI_QX */
1503 SI_QX(SystemLookasideInformation
),
1504 SI_XS(SystemSetTimeSlipEvent
),
1505 SI_XS(SystemCreateSession
),
1506 SI_XS(SystemDeleteSession
),
1507 SI_QX(SystemInvalidInfoClass4
), /* it should be SI_XX */
1508 SI_QX(SystemRangeStartInformation
),
1509 SI_QS(SystemVerifierInformation
),
1510 SI_XS(SystemAddVerifier
),
1511 SI_QX(SystemSessionProcessesInformation
)
1519 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1520 OUT PVOID SystemInformation
,
1522 OUT PULONG UnsafeResultLength
)
1524 KPROCESSOR_MODE PreviousMode
;
1526 NTSTATUS FStatus
= STATUS_NOT_IMPLEMENTED
;
1530 PreviousMode
= ExGetPreviousMode();
1534 if (PreviousMode
!= KernelMode
)
1536 /* SystemKernelDebuggerInformation needs only BOOLEAN alignment */
1537 ProbeForWrite(SystemInformation
, Length
, 1);
1538 if (UnsafeResultLength
!= NULL
)
1539 ProbeForWriteUlong(UnsafeResultLength
);
1542 /* Clear user buffer. */
1543 RtlZeroMemory(SystemInformation
, Length
);
1546 * Check the request is valid.
1548 if (SystemInformationClass
>= SystemInformationClassMax
)
1550 return (STATUS_INVALID_INFO_CLASS
);
1553 if (NULL
!= CallQS
[SystemInformationClass
].Query
)
1556 * Hand the request to a subhandler.
1558 FStatus
= CallQS
[SystemInformationClass
].Query(SystemInformation
,
1561 if (UnsafeResultLength
!= NULL
)
1563 if (PreviousMode
!= KernelMode
)
1567 *UnsafeResultLength
= ResultLength
;
1569 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
1571 FStatus
= _SEH_GetExceptionCode();
1577 *UnsafeResultLength
= ResultLength
;
1582 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
1584 FStatus
= _SEH_GetExceptionCode();
1594 NtSetSystemInformation (
1595 IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1596 IN PVOID SystemInformation
,
1597 IN ULONG SystemInformationLength
1603 * If called from user mode, check
1604 * possible unsafe arguments.
1607 if (KernelMode
!= KeGetPreviousMode())
1611 // SystemInformation,
1621 * Check the request is valid.
1623 if ( (SystemInformationClass
>= SystemBasicInformation
)
1624 && (SystemInformationClass
< SystemInformationClassMax
)
1627 if (NULL
!= CallQS
[SystemInformationClass
].Set
)
1630 * Hand the request to a subhandler.
1632 return CallQS
[SystemInformationClass
].Set (
1634 SystemInformationLength
1638 return (STATUS_INVALID_INFO_CLASS
);
1644 NtFlushInstructionCache (
1645 IN HANDLE ProcessHandle
,
1646 IN PVOID BaseAddress
,
1647 IN ULONG NumberOfBytesToFlush
1652 __asm__("wbinvd\n");
1653 return STATUS_SUCCESS
;