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
= KeGetCurrentKPCR()->ProcessorNumber
;
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
]);
99 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName
,
100 OUT PWCHAR ValueBuffer
,
101 IN ULONG ValueBufferLength
,
102 IN OUT PULONG ReturnLength OPTIONAL
)
105 UNICODE_STRING WName
;
109 UNICODE_STRING WValue
;
110 KPROCESSOR_MODE PreviousMode
;
111 NTSTATUS Status
= STATUS_SUCCESS
;
115 PreviousMode
= ExGetPreviousMode();
117 if(PreviousMode
!= KernelMode
)
121 ProbeForRead(VariableName
,
122 sizeof(UNICODE_STRING
),
124 ProbeForWrite(ValueBuffer
,
127 if(ReturnLength
!= NULL
)
129 ProbeForWrite(ReturnLength
,
136 Status
= _SEH_GetExceptionCode();
140 if(!NT_SUCCESS(Status
))
147 * Copy the name to kernel space if necessary and convert it to ANSI.
149 Status
= RtlCaptureUnicodeString(&WName
,
154 if(NT_SUCCESS(Status
))
157 * according to ntinternals the SeSystemEnvironmentName privilege is required!
159 if(!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege
,
162 RtlReleaseCapturedUnicodeString(&WName
,
165 DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
166 return STATUS_PRIVILEGE_NOT_HELD
;
170 * convert the value name to ansi
172 Status
= RtlUnicodeStringToAnsiString(&AName
, &WName
, TRUE
);
173 RtlReleaseCapturedUnicodeString(&WName
,
176 if(!NT_SUCCESS(Status
))
182 * Create a temporary buffer for the value
184 Value
= ExAllocatePool(NonPagedPool
, ValueBufferLength
);
187 RtlFreeAnsiString(&AName
);
188 return STATUS_INSUFFICIENT_RESOURCES
;
192 * Get the environment variable
194 Result
= HalGetEnvironmentVariable(AName
.Buffer
, Value
, ValueBufferLength
);
197 RtlFreeAnsiString(&AName
);
199 return STATUS_UNSUCCESSFUL
;
203 * Convert the result to UNICODE, protect with SEH in case the value buffer
204 * isn't NULL-terminated!
208 RtlInitAnsiString(&AValue
, Value
);
209 Status
= RtlAnsiStringToUnicodeString(&WValue
, &AValue
, TRUE
);
213 Status
= _SEH_GetExceptionCode();
217 if(NT_SUCCESS(Status
))
220 * Copy the result back to the caller.
224 RtlCopyMemory(ValueBuffer
, WValue
.Buffer
, WValue
.Length
);
225 ValueBuffer
[WValue
.Length
/ sizeof(WCHAR
)] = L
'\0';
226 if(ReturnLength
!= NULL
)
228 *ReturnLength
= WValue
.Length
+ sizeof(WCHAR
);
231 Status
= STATUS_SUCCESS
;
235 Status
= _SEH_GetExceptionCode();
241 * Cleanup allocated resources.
243 RtlFreeAnsiString(&AName
);
252 NtSetSystemEnvironmentValue (IN PUNICODE_STRING VariableName
,
253 IN PUNICODE_STRING Value
)
255 UNICODE_STRING CapturedName
, CapturedValue
;
256 ANSI_STRING AName
, AValue
;
257 KPROCESSOR_MODE PreviousMode
;
262 PreviousMode
= ExGetPreviousMode();
265 * Copy the strings to kernel space if necessary
267 Status
= RtlCaptureUnicodeString(&CapturedName
,
272 if(NT_SUCCESS(Status
))
274 Status
= RtlCaptureUnicodeString(&CapturedValue
,
279 if(NT_SUCCESS(Status
))
282 * according to ntinternals the SeSystemEnvironmentName privilege is required!
284 if(SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege
,
288 * convert the strings to ANSI
290 Status
= RtlUnicodeStringToAnsiString(&AName
,
293 if(NT_SUCCESS(Status
))
295 Status
= RtlUnicodeStringToAnsiString(&AValue
,
298 if(NT_SUCCESS(Status
))
300 BOOLEAN Result
= HalSetEnvironmentVariable(AName
.Buffer
,
303 Status
= (Result
? STATUS_SUCCESS
: STATUS_UNSUCCESSFUL
);
309 DPRINT1("NtSetSystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
310 Status
= STATUS_PRIVILEGE_NOT_HELD
;
313 RtlReleaseCapturedUnicodeString(&CapturedValue
,
318 RtlReleaseCapturedUnicodeString(&CapturedName
,
327 /* --- Query/Set System Information --- */
330 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
331 * so the stack is popped only in one place on x86 platform.
333 #define QSI_USE(n) QSI##n
335 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
337 #define SSI_USE(n) SSI##n
339 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
342 /* Class 0 - Basic Information */
343 QSI_DEF(SystemBasicInformation
)
345 PSYSTEM_BASIC_INFORMATION Sbi
346 = (PSYSTEM_BASIC_INFORMATION
) Buffer
;
348 *ReqSize
= sizeof (SYSTEM_BASIC_INFORMATION
);
350 * Check user buffer's size
352 if (Size
< sizeof (SYSTEM_BASIC_INFORMATION
))
354 return (STATUS_INFO_LENGTH_MISMATCH
);
357 Sbi
->MaximumIncrement
= KeMaximumIncrement
;
358 Sbi
->PhysicalPageSize
= PAGE_SIZE
;
359 Sbi
->NumberOfPhysicalPages
= MmStats
.NrTotalPages
;
360 Sbi
->LowestPhysicalPage
= 0; /* FIXME */
361 Sbi
->HighestPhysicalPage
= MmStats
.NrTotalPages
; /* FIXME */
362 Sbi
->AllocationGranularity
= MM_VIRTMEM_GRANULARITY
; /* hard coded on Intel? */
363 Sbi
->LowestUserAddress
= 0x10000; /* Top of 64k */
364 Sbi
->HighestUserAddress
= (ULONG_PTR
)MmHighestUserAddress
;
365 Sbi
->ActiveProcessors
= KeActiveProcessors
;
366 Sbi
->NumberProcessors
= KeNumberProcessors
;
367 return (STATUS_SUCCESS
);
370 /* Class 1 - Processor Information */
371 QSI_DEF(SystemProcessorInformation
)
373 PSYSTEM_PROCESSOR_INFORMATION Spi
374 = (PSYSTEM_PROCESSOR_INFORMATION
) Buffer
;
376 *ReqSize
= sizeof (SYSTEM_PROCESSOR_INFORMATION
);
378 * Check user buffer's size
380 if (Size
< sizeof (SYSTEM_PROCESSOR_INFORMATION
))
382 return (STATUS_INFO_LENGTH_MISMATCH
);
384 Prcb
= KeGetCurrentPrcb();
385 Spi
->ProcessorArchitecture
= 0; /* Intel Processor */
386 Spi
->ProcessorLevel
= Prcb
->CpuType
;
387 Spi
->ProcessorRevision
= Prcb
->CpuStep
;
389 Spi
->FeatureBits
= Prcb
->FeatureBits
;
391 DPRINT("Arch %d Level %d Rev 0x%x\n", Spi
->ProcessorArchitecture
,
392 Spi
->ProcessorLevel
, Spi
->ProcessorRevision
);
394 return (STATUS_SUCCESS
);
397 /* Class 2 - Performance Information */
398 QSI_DEF(SystemPerformanceInformation
)
400 PSYSTEM_PERFORMANCE_INFORMATION Spi
401 = (PSYSTEM_PERFORMANCE_INFORMATION
) Buffer
;
403 PEPROCESS TheIdleProcess
;
405 *ReqSize
= sizeof (SYSTEM_PERFORMANCE_INFORMATION
);
407 * Check user buffer's size
409 if (Size
< sizeof (SYSTEM_PERFORMANCE_INFORMATION
))
411 return (STATUS_INFO_LENGTH_MISMATCH
);
414 TheIdleProcess
= PsIdleProcess
;
416 Spi
->IdleTime
.QuadPart
= TheIdleProcess
->Pcb
.KernelTime
* 100000LL;
418 Spi
->ReadTransferCount
.QuadPart
= IoReadTransferCount
;
419 Spi
->WriteTransferCount
.QuadPart
= IoWriteTransferCount
;
420 Spi
->OtherTransferCount
.QuadPart
= IoOtherTransferCount
;
421 Spi
->ReadOperationCount
= IoReadOperationCount
;
422 Spi
->WriteOperationCount
= IoWriteOperationCount
;
423 Spi
->OtherOperationCount
= IoOtherOperationCount
;
425 Spi
->AvailablePages
= MmStats
.NrFreePages
;
427 Add up all the used "Commitied" memory + pagefile.
428 Not sure this is right. 8^\
430 Spi
->TotalCommittedPages
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
+
431 MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
+
432 MiMemoryConsumers
[MC_CACHE
].PagesUsed
+
433 MiMemoryConsumers
[MC_USER
].PagesUsed
+
436 Add up the full system total + pagefile.
437 All this make Taskmgr happy but not sure it is the right numbers.
438 This too, fixes some of GlobalMemoryStatusEx numbers.
440 Spi
->TotalCommitLimit
= MmStats
.NrTotalPages
+ MiFreeSwapPages
+
443 Spi
->PeakCommitment
= 0; /* FIXME */
444 Spi
->PageFaults
= 0; /* FIXME */
445 Spi
->WriteCopyFaults
= 0; /* FIXME */
446 Spi
->TransitionFaults
= 0; /* FIXME */
447 Spi
->CacheTransitionFaults
= 0; /* FIXME */
448 Spi
->DemandZeroFaults
= 0; /* FIXME */
449 Spi
->PagesRead
= 0; /* FIXME */
450 Spi
->PageReadIos
= 0; /* FIXME */
451 Spi
->CacheReads
= 0; /* FIXME */
452 Spi
->CacheIos
= 0; /* FIXME */
453 Spi
->PagefilePagesWritten
= 0; /* FIXME */
454 Spi
->PagefilePageWriteIos
= 0; /* FIXME */
455 Spi
->MappedFilePagesWritten
= 0; /* FIXME */
456 Spi
->MappedFilePageWriteIos
= 0; /* FIXME */
458 Spi
->PagedPoolUsage
= MiMemoryConsumers
[MC_PPOOL
].PagesUsed
;
459 Spi
->PagedPoolAllocs
= 0; /* FIXME */
460 Spi
->PagedPoolFrees
= 0; /* FIXME */
461 Spi
->NonPagedPoolUsage
= MiMemoryConsumers
[MC_NPPOOL
].PagesUsed
;
462 Spi
->NonPagedPoolAllocs
= 0; /* FIXME */
463 Spi
->NonPagedPoolFrees
= 0; /* FIXME */
465 Spi
->TotalFreeSystemPtes
= 0; /* FIXME */
467 Spi
->SystemCodePage
= MmStats
.NrSystemPages
; /* FIXME */
469 Spi
->TotalSystemDriverPages
= 0; /* FIXME */
470 Spi
->TotalSystemCodePages
= 0; /* FIXME */
471 Spi
->SmallNonPagedLookasideListAllocateHits
= 0; /* FIXME */
472 Spi
->SmallPagedLookasideListAllocateHits
= 0; /* FIXME */
473 Spi
->Reserved3
= 0; /* FIXME */
475 Spi
->MmSystemCachePage
= MiMemoryConsumers
[MC_CACHE
].PagesUsed
;
476 Spi
->PagedPoolPage
= MmPagedPoolSize
; /* FIXME */
478 Spi
->SystemDriverPage
= 0; /* FIXME */
479 Spi
->FastReadNoWait
= 0; /* FIXME */
480 Spi
->FastReadWait
= 0; /* FIXME */
481 Spi
->FastReadResourceMiss
= 0; /* FIXME */
482 Spi
->FastReadNotPossible
= 0; /* FIXME */
484 Spi
->FastMdlReadNoWait
= 0; /* FIXME */
485 Spi
->FastMdlReadWait
= 0; /* FIXME */
486 Spi
->FastMdlReadResourceMiss
= 0; /* FIXME */
487 Spi
->FastMdlReadNotPossible
= 0; /* FIXME */
489 Spi
->MapDataNoWait
= 0; /* FIXME */
490 Spi
->MapDataWait
= 0; /* FIXME */
491 Spi
->MapDataNoWaitMiss
= 0; /* FIXME */
492 Spi
->MapDataWaitMiss
= 0; /* FIXME */
494 Spi
->PinMappedDataCount
= 0; /* FIXME */
495 Spi
->PinReadNoWait
= 0; /* FIXME */
496 Spi
->PinReadWait
= 0; /* FIXME */
497 Spi
->PinReadNoWaitMiss
= 0; /* FIXME */
498 Spi
->PinReadWaitMiss
= 0; /* FIXME */
499 Spi
->CopyReadNoWait
= 0; /* FIXME */
500 Spi
->CopyReadWait
= 0; /* FIXME */
501 Spi
->CopyReadNoWaitMiss
= 0; /* FIXME */
502 Spi
->CopyReadWaitMiss
= 0; /* FIXME */
504 Spi
->MdlReadNoWait
= 0; /* FIXME */
505 Spi
->MdlReadWait
= 0; /* FIXME */
506 Spi
->MdlReadNoWaitMiss
= 0; /* FIXME */
507 Spi
->MdlReadWaitMiss
= 0; /* FIXME */
508 Spi
->ReadAheadIos
= 0; /* FIXME */
509 Spi
->LazyWriteIos
= 0; /* FIXME */
510 Spi
->LazyWritePages
= 0; /* FIXME */
511 Spi
->DataFlushes
= 0; /* FIXME */
512 Spi
->DataPages
= 0; /* FIXME */
513 Spi
->ContextSwitches
= 0; /* FIXME */
514 Spi
->FirstLevelTbFills
= 0; /* FIXME */
515 Spi
->SecondLevelTbFills
= 0; /* FIXME */
516 Spi
->SystemCalls
= 0; /* FIXME */
518 return (STATUS_SUCCESS
);
521 /* Class 3 - Time Of Day Information */
522 QSI_DEF(SystemTimeOfDayInformation
)
524 PSYSTEM_TIMEOFDAY_INFORMATION Sti
;
525 LARGE_INTEGER CurrentTime
;
527 Sti
= (PSYSTEM_TIMEOFDAY_INFORMATION
)Buffer
;
528 *ReqSize
= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
);
530 /* Check user buffer's size */
531 if (Size
< sizeof (SYSTEM_TIMEOFDAY_INFORMATION
))
533 return STATUS_INFO_LENGTH_MISMATCH
;
536 KeQuerySystemTime(&CurrentTime
);
538 Sti
->BootTime
= SystemBootTime
;
539 Sti
->CurrentTime
= CurrentTime
;
540 Sti
->TimeZoneBias
.QuadPart
= ExpTimeZoneBias
.QuadPart
;
541 Sti
->TimeZoneId
= ExpTimeZoneId
;
544 return STATUS_SUCCESS
;
547 /* Class 4 - Path Information */
548 QSI_DEF(SystemPathInformation
)
550 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
551 DPRINT1("NtQuerySystemInformation - SystemPathInformation not implemented\n");
553 return (STATUS_BREAKPOINT
);
556 /* Class 5 - Process Information */
557 QSI_DEF(SystemProcessInformation
)
559 ULONG ovlSize
=0, nThreads
;
563 /* scan the process list */
565 PSYSTEM_PROCESS_INFORMATION Spi
566 = (PSYSTEM_PROCESS_INFORMATION
) Buffer
;
568 *ReqSize
= sizeof(SYSTEM_PROCESS_INFORMATION
);
570 if (Size
< sizeof(SYSTEM_PROCESS_INFORMATION
))
572 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
575 syspr
= PsGetNextProcess(NULL
);
577 pCur
= (unsigned char *)Spi
;
581 PSYSTEM_PROCESS_INFORMATION SpiCur
;
584 int inLen
=32; // image name len in bytes
585 PLIST_ENTRY current_entry
;
588 SpiCur
= (PSYSTEM_PROCESS_INFORMATION
)pCur
;
591 current_entry
= pr
->ThreadListHead
.Flink
;
592 while (current_entry
!= &pr
->ThreadListHead
)
595 current_entry
= current_entry
->Flink
;
598 // size of the structure for every process
599 curSize
= sizeof(SYSTEM_PROCESS_INFORMATION
)-sizeof(SYSTEM_THREAD_INFORMATION
)+sizeof(SYSTEM_THREAD_INFORMATION
)*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
->NextEntryOffset
= curSize
+inLen
; // relative offset to the beginnnig of the next structure
612 SpiCur
->NumberOfThreads
= nThreads
;
613 SpiCur
->CreateTime
= pr
->CreateTime
;
614 SpiCur
->UserTime
.QuadPart
= pr
->Pcb
.UserTime
* 100000LL;
615 SpiCur
->KernelTime
.QuadPart
= pr
->Pcb
.KernelTime
* 100000LL;
616 SpiCur
->ImageName
.Length
= strlen(pr
->ImageFileName
) * sizeof(WCHAR
);
617 SpiCur
->ImageName
.MaximumLength
= inLen
;
618 SpiCur
->ImageName
.Buffer
= (void*)(pCur
+curSize
);
620 // copy name to the end of the struct
621 if(pr
!= PsIdleProcess
)
623 RtlInitAnsiString(&imgName
, pr
->ImageFileName
);
624 RtlAnsiStringToUnicodeString(&SpiCur
->ImageName
, &imgName
, FALSE
);
628 RtlInitUnicodeString(&SpiCur
->ImageName
, NULL
);
631 SpiCur
->BasePriority
= pr
->Pcb
.BasePriority
;
632 SpiCur
->UniqueProcessId
= pr
->UniqueProcessId
;
633 SpiCur
->InheritedFromUniqueProcessId
= pr
->InheritedFromUniqueProcessId
;
634 SpiCur
->HandleCount
= (pr
->ObjectTable
? ObpGetHandleCountByHandleTable(pr
->ObjectTable
) : 0);
635 SpiCur
->PeakVirtualSize
= pr
->PeakVirtualSize
;
636 SpiCur
->VirtualSize
= pr
->VirtualSize
.QuadPart
;
637 SpiCur
->PageFaultCount
= pr
->LastFaultCount
;
638 SpiCur
->PeakWorkingSetSize
= pr
->Vm
.PeakWorkingSetSize
; // Is this right using ->Vm. here ?
639 SpiCur
->WorkingSetSize
= pr
->Vm
.WorkingSetSize
; // Is this right using ->Vm. here ?
640 SpiCur
->QuotaPeakPagedPoolUsage
=
641 pr
->QuotaPeakPoolUsage
[0];
642 SpiCur
->QuotaPagedPoolUsage
=
643 pr
->QuotaPoolUsage
[0];
644 SpiCur
->QuotaPeakNonPagedPoolUsage
=
645 pr
->QuotaPeakPoolUsage
[1];
646 SpiCur
->QuotaNonPagedPoolUsage
=
647 pr
->QuotaPoolUsage
[1];
648 SpiCur
->PagefileUsage
= pr
->PagefileUsage
; // FIXME
649 SpiCur
->PeakPagefileUsage
= pr
->PeakPagefileUsage
;
650 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
651 // doesn't seem to contain any equivalent field
652 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
654 current_entry
= pr
->ThreadListHead
.Flink
;
655 while (current_entry
!= &pr
->ThreadListHead
)
657 current
= CONTAINING_RECORD(current_entry
, ETHREAD
,
660 SpiCur
->TH
[i
].KernelTime
.QuadPart
= current
->Tcb
.KernelTime
* 100000LL;
661 SpiCur
->TH
[i
].UserTime
.QuadPart
= current
->Tcb
.UserTime
* 100000LL;
662 // SpiCur->TH[i].CreateTime = current->CreateTime;
663 SpiCur
->TH
[i
].WaitTime
= current
->Tcb
.WaitTime
;
664 SpiCur
->TH
[i
].StartAddress
= (PVOID
) current
->StartAddress
;
665 SpiCur
->TH
[i
].ClientId
= current
->Cid
;
666 SpiCur
->TH
[i
].Priority
= current
->Tcb
.Priority
;
667 SpiCur
->TH
[i
].BasePriority
= current
->Tcb
.BasePriority
;
668 SpiCur
->TH
[i
].ContextSwitches
= current
->Tcb
.ContextSwitches
;
669 SpiCur
->TH
[i
].ThreadState
= current
->Tcb
.State
;
670 SpiCur
->TH
[i
].WaitReason
= current
->Tcb
.WaitReason
;
672 current_entry
= current_entry
->Flink
;
675 pr
= PsGetNextProcess(pr
);
677 if ((pr
== syspr
) || (pr
== NULL
))
679 SpiCur
->NextEntryOffset
= 0;
683 pCur
= pCur
+ curSize
+ inLen
;
684 } while ((pr
!= syspr
) && (pr
!= NULL
));
688 ObDereferenceObject(pr
);
692 return (STATUS_SUCCESS
);
695 /* Class 6 - Call Count Information */
696 QSI_DEF(SystemCallCountInformation
)
699 DPRINT1("NtQuerySystemInformation - SystemCallCountInformation not implemented\n");
700 return (STATUS_NOT_IMPLEMENTED
);
703 /* Class 7 - Device Information */
704 QSI_DEF(SystemDeviceInformation
)
706 PSYSTEM_DEVICE_INFORMATION Sdi
707 = (PSYSTEM_DEVICE_INFORMATION
) Buffer
;
708 PCONFIGURATION_INFORMATION ConfigInfo
;
710 *ReqSize
= sizeof (SYSTEM_DEVICE_INFORMATION
);
712 * Check user buffer's size
714 if (Size
< sizeof (SYSTEM_DEVICE_INFORMATION
))
716 return (STATUS_INFO_LENGTH_MISMATCH
);
719 ConfigInfo
= IoGetConfigurationInformation ();
721 Sdi
->NumberOfDisks
= ConfigInfo
->DiskCount
;
722 Sdi
->NumberOfFloppies
= ConfigInfo
->FloppyCount
;
723 Sdi
->NumberOfCdRoms
= ConfigInfo
->CdRomCount
;
724 Sdi
->NumberOfTapes
= ConfigInfo
->TapeCount
;
725 Sdi
->NumberOfSerialPorts
= ConfigInfo
->SerialCount
;
726 Sdi
->NumberOfParallelPorts
= ConfigInfo
->ParallelCount
;
728 return (STATUS_SUCCESS
);
731 /* Class 8 - Processor Performance Information */
732 QSI_DEF(SystemProcessorPerformanceInformation
)
734 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
735 = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) Buffer
;
738 LARGE_INTEGER CurrentTime
;
741 *ReqSize
= KeNumberProcessors
* sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
);
743 * Check user buffer's size
745 if (Size
< KeNumberProcessors
* sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
))
747 return (STATUS_INFO_LENGTH_MISMATCH
);
750 CurrentTime
.QuadPart
= KeQueryInterruptTime();
751 Prcb
= ((PKPCR
)KPCR_BASE
)->Prcb
;
752 for (i
= 0; i
< KeNumberProcessors
; i
++)
754 Spi
->IdleTime
.QuadPart
= (Prcb
->IdleThread
->KernelTime
+ Prcb
->IdleThread
->UserTime
) * 100000LL; // IdleTime
755 Spi
->KernelTime
.QuadPart
= Prcb
->KernelTime
* 100000LL; // KernelTime
756 Spi
->UserTime
.QuadPart
= Prcb
->UserTime
* 100000LL;
757 Spi
->DpcTime
.QuadPart
= Prcb
->DpcTime
* 100000LL;
758 Spi
->InterruptTime
.QuadPart
= Prcb
->InterruptTime
* 100000LL;
759 Spi
->InterruptCount
= Prcb
->InterruptCount
; // Interrupt Count
761 Prcb
= (PKPRCB
)((ULONG_PTR
)Prcb
+ PAGE_SIZE
);
764 return (STATUS_SUCCESS
);
767 /* Class 9 - Flags Information */
768 QSI_DEF(SystemFlagsInformation
)
770 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
772 * ReqSize
= sizeof (SYSTEM_FLAGS_INFORMATION
);
773 return (STATUS_INFO_LENGTH_MISMATCH
);
775 ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
= NtGlobalFlag
;
776 return (STATUS_SUCCESS
);
779 SSI_DEF(SystemFlagsInformation
)
781 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
783 return (STATUS_INFO_LENGTH_MISMATCH
);
785 NtGlobalFlag
= ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
;
786 return (STATUS_SUCCESS
);
789 /* Class 10 - Call Time Information */
790 QSI_DEF(SystemCallTimeInformation
)
793 DPRINT1("NtQuerySystemInformation - SystemCallTimeInformation not implemented\n");
794 return (STATUS_NOT_IMPLEMENTED
);
797 /* Class 11 - Module Information */
798 QSI_DEF(SystemModuleInformation
)
800 return LdrpQueryModuleInformation(Buffer
, Size
, ReqSize
);
803 /* Class 12 - Locks Information */
804 QSI_DEF(SystemLocksInformation
)
807 DPRINT1("NtQuerySystemInformation - SystemLocksInformation not implemented\n");
808 return (STATUS_NOT_IMPLEMENTED
);
811 /* Class 13 - Stack Trace Information */
812 QSI_DEF(SystemStackTraceInformation
)
815 DPRINT1("NtQuerySystemInformation - SystemStackTraceInformation not implemented\n");
816 return (STATUS_NOT_IMPLEMENTED
);
819 /* Class 14 - Paged Pool Information */
820 QSI_DEF(SystemPagedPoolInformation
)
823 DPRINT1("NtQuerySystemInformation - SystemPagedPoolInformation not implemented\n");
824 return (STATUS_NOT_IMPLEMENTED
);
827 /* Class 15 - Non Paged Pool Information */
828 QSI_DEF(SystemNonPagedPoolInformation
)
831 DPRINT1("NtQuerySystemInformation - SystemNonPagedPoolInformation not implemented\n");
832 return (STATUS_NOT_IMPLEMENTED
);
837 ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi
,
841 /* Class 16 - Handle Information */
842 QSI_DEF(SystemHandleInformation
)
844 PSYSTEM_HANDLE_INFORMATION Shi
=
845 (PSYSTEM_HANDLE_INFORMATION
) Buffer
;
847 DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
849 if (Size
< sizeof (SYSTEM_HANDLE_INFORMATION
))
851 * ReqSize
= sizeof (SYSTEM_HANDLE_INFORMATION
);
852 return (STATUS_INFO_LENGTH_MISMATCH
);
855 DPRINT("SystemHandleInformation 1\n");
861 /* First Calc Size from Count. */
862 syspr
= PsGetNextProcess(NULL
);
867 hCount
= hCount
+ (pr
->ObjectTable
? ObpGetHandleCountByHandleTable(pr
->ObjectTable
) : 0);
868 pr
= PsGetNextProcess(pr
);
870 if ((pr
== syspr
) || (pr
== NULL
))
872 } while ((pr
!= syspr
) && (pr
!= NULL
));
876 ObDereferenceObject(pr
);
879 DPRINT("SystemHandleInformation 2\n");
881 curSize
= sizeof(SYSTEM_HANDLE_INFORMATION
)+
882 ( (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO
) * hCount
) -
883 (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO
) ));
885 Shi
->NumberOfHandles
= hCount
;
890 return (STATUS_INFO_LENGTH_MISMATCH
);
893 DPRINT("SystemHandleInformation 3\n");
895 /* Now get Handles from all processs. */
896 syspr
= PsGetNextProcess(NULL
);
901 int Count
= 0, HandleCount
;
903 HandleCount
= (pr
->ObjectTable
? ObpGetHandleCountByHandleTable(pr
->ObjectTable
) : 0);
905 for (Count
= 0; HandleCount
> 0 ; HandleCount
--)
907 ObpGetNextHandleByProcessCount( &Shi
->Handles
[i
], pr
, Count
);
912 pr
= PsGetNextProcess(pr
);
914 if ((pr
== syspr
) || (pr
== NULL
))
916 } while ((pr
!= syspr
) && (pr
!= NULL
));
920 ObDereferenceObject(pr
);
923 DPRINT("SystemHandleInformation 4\n");
924 return (STATUS_SUCCESS
);
928 SSI_DEF(SystemHandleInformation)
931 return (STATUS_SUCCESS);
935 /* Class 17 - Information */
936 QSI_DEF(SystemObjectInformation
)
939 DPRINT1("NtQuerySystemInformation - SystemObjectInformation not implemented\n");
940 return (STATUS_NOT_IMPLEMENTED
);
943 /* Class 18 - Information */
944 QSI_DEF(SystemPageFileInformation
)
946 SYSTEM_PAGEFILE_INFORMATION
*Spfi
= (SYSTEM_PAGEFILE_INFORMATION
*) Buffer
;
948 if (Size
< sizeof (SYSTEM_PAGEFILE_INFORMATION
))
950 * ReqSize
= sizeof (SYSTEM_PAGEFILE_INFORMATION
);
951 return (STATUS_INFO_LENGTH_MISMATCH
);
954 UNICODE_STRING FileName
; /* FIXME */
955 RtlInitUnicodeString(&FileName
, NULL
); /* FIXME */
958 Spfi
->NextEntryOffset
= 0;
960 Spfi
->TotalSize
= MiFreeSwapPages
+ MiUsedSwapPages
;
961 Spfi
->TotalInUse
= MiUsedSwapPages
;
962 Spfi
->PeakUsage
= MiUsedSwapPages
; /* FIXME */
963 Spfi
->PageFileName
= FileName
;
964 return (STATUS_SUCCESS
);
967 /* Class 19 - Vdm Instemul Information */
968 QSI_DEF(SystemVdmInstemulInformation
)
971 DPRINT1("NtQuerySystemInformation - SystemVdmInstemulInformation not implemented\n");
972 return (STATUS_NOT_IMPLEMENTED
);
975 /* Class 20 - Vdm Bop Information */
976 QSI_DEF(SystemVdmBopInformation
)
979 DPRINT1("NtQuerySystemInformation - SystemVdmBopInformation not implemented\n");
980 return (STATUS_NOT_IMPLEMENTED
);
983 /* Class 21 - File Cache Information */
984 QSI_DEF(SystemFileCacheInformation
)
986 SYSTEM_CACHE_INFORMATION
*Sci
= (SYSTEM_CACHE_INFORMATION
*) Buffer
;
988 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
990 * ReqSize
= sizeof (SYSTEM_CACHE_INFORMATION
);
991 return (STATUS_INFO_LENGTH_MISMATCH
);
993 /* Return the Byte size not the page size. */
995 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
;
997 MiMemoryConsumers
[MC_CACHE
].PagesUsed
* PAGE_SIZE
; /* FIXME */
999 Sci
->PageFaultCount
= 0; /* FIXME */
1000 Sci
->MinimumWorkingSet
= 0; /* FIXME */
1001 Sci
->MaximumWorkingSet
= 0; /* FIXME */
1002 Sci
->TransitionSharedPages
= 0; /* FIXME */
1003 Sci
->TransitionSharedPagesPeak
= 0; /* FIXME */
1005 return (STATUS_SUCCESS
);
1008 SSI_DEF(SystemFileCacheInformation
)
1010 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
1012 return (STATUS_INFO_LENGTH_MISMATCH
);
1015 DPRINT1("NtSetSystemInformation - SystemFileCacheInformation not implemented\n");
1016 return (STATUS_NOT_IMPLEMENTED
);
1019 /* Class 22 - Pool Tag Information */
1020 QSI_DEF(SystemPoolTagInformation
)
1023 DPRINT1("NtQuerySystemInformation - SystemPoolTagInformation not implemented\n");
1024 return (STATUS_NOT_IMPLEMENTED
);
1027 /* Class 23 - Interrupt Information for all processors */
1028 QSI_DEF(SystemInterruptInformation
)
1033 PSYSTEM_INTERRUPT_INFORMATION sii
= (PSYSTEM_INTERRUPT_INFORMATION
)Buffer
;
1035 if(Size
< KeNumberProcessors
* sizeof(SYSTEM_INTERRUPT_INFORMATION
))
1037 return (STATUS_INFO_LENGTH_MISMATCH
);
1040 ti
= KeQueryTimeIncrement();
1042 Prcb
= ((PKPCR
)KPCR_BASE
)->Prcb
;
1043 for (i
= 0; i
< KeNumberProcessors
; i
++)
1045 sii
->ContextSwitches
= Prcb
->KeContextSwitches
;
1046 sii
->DpcCount
= 0; /* FIXME */
1047 sii
->DpcRate
= 0; /* FIXME */
1048 sii
->TimeIncrement
= ti
;
1049 sii
->DpcBypassCount
= 0; /* FIXME */
1050 sii
->ApcBypassCount
= 0; /* FIXME */
1052 Prcb
= (PKPRCB
)((ULONG_PTR
)Prcb
+ PAGE_SIZE
);
1055 return STATUS_SUCCESS
;
1058 /* Class 24 - DPC Behaviour Information */
1059 QSI_DEF(SystemDpcBehaviourInformation
)
1062 DPRINT1("NtQuerySystemInformation - SystemDpcBehaviourInformation not implemented\n");
1063 return (STATUS_NOT_IMPLEMENTED
);
1066 SSI_DEF(SystemDpcBehaviourInformation
)
1069 DPRINT1("NtSetSystemInformation - SystemDpcBehaviourInformation not implemented\n");
1070 return (STATUS_NOT_IMPLEMENTED
);
1073 /* Class 25 - Full Memory Information */
1074 QSI_DEF(SystemFullMemoryInformation
)
1076 PULONG Spi
= (PULONG
) Buffer
;
1078 PEPROCESS TheIdleProcess
;
1080 * ReqSize
= sizeof (ULONG
);
1082 if (sizeof (ULONG
) != Size
)
1084 return (STATUS_INFO_LENGTH_MISMATCH
);
1086 DPRINT("SystemFullMemoryInformation\n");
1088 TheIdleProcess
= PsIdleProcess
;
1090 DPRINT("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
1091 TheIdleProcess
->UniqueProcessId
,
1092 TheIdleProcess
->Pcb
.KernelTime
,
1097 MmPrintMemoryStatistic();
1100 *Spi
= MiMemoryConsumers
[MC_USER
].PagesUsed
;
1102 return (STATUS_SUCCESS
);
1105 /* Class 26 - Load Image */
1106 SSI_DEF(SystemLoadImage
)
1108 PSYSTEM_LOAD_IMAGE Sli
= (PSYSTEM_LOAD_IMAGE
)Buffer
;
1110 if (sizeof(SYSTEM_LOAD_IMAGE
) != Size
)
1112 return(STATUS_INFO_LENGTH_MISMATCH
);
1115 return(LdrpLoadImage(&Sli
->ModuleName
,
1117 &Sli
->SectionPointer
,
1119 &Sli
->ExportDirectory
));
1122 /* Class 27 - Unload Image */
1123 SSI_DEF(SystemUnloadImage
)
1125 PSYSTEM_UNLOAD_IMAGE Sui
= (PSYSTEM_UNLOAD_IMAGE
)Buffer
;
1127 if (sizeof(SYSTEM_UNLOAD_IMAGE
) != Size
)
1129 return(STATUS_INFO_LENGTH_MISMATCH
);
1132 return(LdrpUnloadImage(Sui
->ModuleBase
));
1135 /* Class 28 - Time Adjustment Information */
1136 QSI_DEF(SystemTimeAdjustmentInformation
)
1138 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
1140 * ReqSize
= sizeof (SYSTEM_SET_TIME_ADJUSTMENT
);
1141 return (STATUS_INFO_LENGTH_MISMATCH
);
1144 DPRINT1("NtQuerySystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1145 return (STATUS_NOT_IMPLEMENTED
);
1148 SSI_DEF(SystemTimeAdjustmentInformation
)
1150 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
1152 return (STATUS_INFO_LENGTH_MISMATCH
);
1155 DPRINT1("NtSetSystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1156 return (STATUS_NOT_IMPLEMENTED
);
1159 /* Class 29 - Summary Memory Information */
1160 QSI_DEF(SystemSummaryMemoryInformation
)
1163 DPRINT1("NtQuerySystemInformation - SystemSummaryMemoryInformation not implemented\n");
1164 return (STATUS_NOT_IMPLEMENTED
);
1167 /* Class 30 - Next Event Id Information */
1168 QSI_DEF(SystemNextEventIdInformation
)
1171 DPRINT1("NtQuerySystemInformation - SystemNextEventIdInformation not implemented\n");
1172 return (STATUS_NOT_IMPLEMENTED
);
1175 /* Class 31 - Event Ids Information */
1176 QSI_DEF(SystemEventIdsInformation
)
1179 DPRINT1("NtQuerySystemInformation - SystemEventIdsInformation not implemented\n");
1180 return (STATUS_NOT_IMPLEMENTED
);
1183 /* Class 32 - Crash Dump Information */
1184 QSI_DEF(SystemCrashDumpInformation
)
1187 DPRINT1("NtQuerySystemInformation - SystemCrashDumpInformation not implemented\n");
1188 return (STATUS_NOT_IMPLEMENTED
);
1191 /* Class 33 - Exception Information */
1192 QSI_DEF(SystemExceptionInformation
)
1195 DPRINT1("NtQuerySystemInformation - SystemExceptionInformation not implemented\n");
1196 return (STATUS_NOT_IMPLEMENTED
);
1199 /* Class 34 - Crash Dump State Information */
1200 QSI_DEF(SystemCrashDumpStateInformation
)
1203 DPRINT1("NtQuerySystemInformation - SystemCrashDumpStateInformation not implemented\n");
1204 return (STATUS_NOT_IMPLEMENTED
);
1207 /* Class 35 - Kernel Debugger Information */
1208 QSI_DEF(SystemKernelDebuggerInformation
)
1211 DPRINT1("NtQuerySystemInformation - SystemKernelDebuggerInformation not implemented\n");
1212 return (STATUS_NOT_IMPLEMENTED
);
1215 /* Class 36 - Context Switch Information */
1216 QSI_DEF(SystemContextSwitchInformation
)
1219 DPRINT1("NtQuerySystemInformation - SystemContextSwitchInformation not implemented\n");
1220 return (STATUS_NOT_IMPLEMENTED
);
1223 /* Class 37 - Registry Quota Information */
1224 QSI_DEF(SystemRegistryQuotaInformation
)
1226 PSYSTEM_REGISTRY_QUOTA_INFORMATION srqi
= (PSYSTEM_REGISTRY_QUOTA_INFORMATION
) Buffer
;
1228 *ReqSize
= sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION
);
1229 if (Size
< sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION
))
1231 return STATUS_INFO_LENGTH_MISMATCH
;
1234 DPRINT1("Faking max registry size of 32 MB\n");
1235 srqi
->RegistryQuotaAllowed
= 0x2000000;
1236 srqi
->RegistryQuotaUsed
= 0x200000;
1237 srqi
->Reserved1
= (void*)0x200000;
1239 return STATUS_SUCCESS
;
1242 SSI_DEF(SystemRegistryQuotaInformation
)
1245 DPRINT1("NtSetSystemInformation - SystemRegistryQuotaInformation not implemented\n");
1246 return (STATUS_NOT_IMPLEMENTED
);
1249 /* Class 38 - Load And Call Image */
1250 SSI_DEF(SystemLoadAndCallImage
)
1252 PSYSTEM_LOAD_AND_CALL_IMAGE Slci
= (PSYSTEM_LOAD_AND_CALL_IMAGE
)Buffer
;
1254 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE
) != Size
)
1256 return(STATUS_INFO_LENGTH_MISMATCH
);
1259 return(LdrpLoadAndCallImage(&Slci
->ModuleName
));
1262 /* Class 39 - Priority Separation */
1263 SSI_DEF(SystemPrioritySeperation
)
1266 DPRINT1("NtSetSystemInformation - SystemPrioritySeperation not implemented\n");
1267 return (STATUS_NOT_IMPLEMENTED
);
1270 /* Class 40 - Plug Play Bus Information */
1271 QSI_DEF(SystemPlugPlayBusInformation
)
1274 DPRINT1("NtQuerySystemInformation - SystemPlugPlayBusInformation not implemented\n");
1275 return (STATUS_NOT_IMPLEMENTED
);
1278 /* Class 41 - Dock Information */
1279 QSI_DEF(SystemDockInformation
)
1282 DPRINT1("NtQuerySystemInformation - SystemDockInformation not implemented\n");
1283 return (STATUS_NOT_IMPLEMENTED
);
1286 /* Class 42 - Power Information */
1287 QSI_DEF(SystemPowerInformation
)
1290 DPRINT1("NtQuerySystemInformation - SystemPowerInformation not implemented\n");
1291 return (STATUS_NOT_IMPLEMENTED
);
1294 /* Class 43 - Processor Speed Information */
1295 QSI_DEF(SystemProcessorSpeedInformation
)
1298 DPRINT1("NtQuerySystemInformation - SystemProcessorSpeedInformation not implemented\n");
1299 return (STATUS_NOT_IMPLEMENTED
);
1302 /* Class 44 - Current Time Zone Information */
1303 QSI_DEF(SystemCurrentTimeZoneInformation
)
1305 * ReqSize
= sizeof (TIME_ZONE_INFORMATION
);
1307 if (sizeof (TIME_ZONE_INFORMATION
) != Size
)
1309 return STATUS_INFO_LENGTH_MISMATCH
;
1312 /* Copy the time zone information struct */
1315 sizeof(TIME_ZONE_INFORMATION
));
1317 return STATUS_SUCCESS
;
1321 SSI_DEF(SystemCurrentTimeZoneInformation
)
1323 /* Check user buffer's size */
1324 if (Size
< sizeof (TIME_ZONE_INFORMATION
))
1326 return STATUS_INFO_LENGTH_MISMATCH
;
1329 return ExpSetTimeZoneInformation((PTIME_ZONE_INFORMATION
)Buffer
);
1333 /* Class 45 - Lookaside Information */
1334 QSI_DEF(SystemLookasideInformation
)
1337 DPRINT1("NtQuerySystemInformation - SystemLookasideInformation not implemented\n");
1338 return (STATUS_NOT_IMPLEMENTED
);
1342 /* Class 46 - Set time slip event */
1343 SSI_DEF(SystemSetTimeSlipEvent
)
1346 DPRINT1("NtSetSystemInformation - SystemSetTimSlipEvent not implemented\n");
1347 return (STATUS_NOT_IMPLEMENTED
);
1351 /* Class 47 - Create a new session (TSE) */
1352 SSI_DEF(SystemCreateSession
)
1355 DPRINT1("NtSetSystemInformation - SystemCreateSession not implemented\n");
1356 return (STATUS_NOT_IMPLEMENTED
);
1360 /* Class 48 - Delete an existing session (TSE) */
1361 SSI_DEF(SystemDeleteSession
)
1364 DPRINT1("NtSetSystemInformation - SystemDeleteSession not implemented\n");
1365 return (STATUS_NOT_IMPLEMENTED
);
1369 /* Class 49 - UNKNOWN */
1370 QSI_DEF(SystemInvalidInfoClass4
)
1373 DPRINT1("NtQuerySystemInformation - SystemInvalidInfoClass4 not implemented\n");
1374 return (STATUS_NOT_IMPLEMENTED
);
1378 /* Class 50 - System range start address */
1379 QSI_DEF(SystemRangeStartInformation
)
1382 DPRINT1("NtQuerySystemInformation - SystemRangeStartInformation not implemented\n");
1383 return (STATUS_NOT_IMPLEMENTED
);
1387 /* Class 51 - Driver verifier information */
1388 QSI_DEF(SystemVerifierInformation
)
1391 DPRINT1("NtQuerySystemInformation - SystemVerifierInformation not implemented\n");
1392 return (STATUS_NOT_IMPLEMENTED
);
1396 SSI_DEF(SystemVerifierInformation
)
1399 DPRINT1("NtSetSystemInformation - SystemVerifierInformation not implemented\n");
1400 return (STATUS_NOT_IMPLEMENTED
);
1404 /* Class 52 - Add a driver verifier */
1405 SSI_DEF(SystemAddVerifier
)
1408 DPRINT1("NtSetSystemInformation - SystemAddVerifier not implemented\n");
1409 return (STATUS_NOT_IMPLEMENTED
);
1413 /* Class 53 - A session's processes */
1414 QSI_DEF(SystemSessionProcessesInformation
)
1417 DPRINT1("NtQuerySystemInformation - SystemSessionProcessInformation not implemented\n");
1418 return (STATUS_NOT_IMPLEMENTED
);
1422 /* Query/Set Calls Table */
1426 NTSTATUS (* Query
) (PVOID
,ULONG
,PULONG
);
1427 NTSTATUS (* Set
) (PVOID
,ULONG
);
1434 // XX unknown behaviour
1436 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1437 #define SI_QX(n) {QSI_USE(n),NULL}
1438 #define SI_XS(n) {NULL,SSI_USE(n)}
1439 #define SI_XX(n) {NULL,NULL}
1445 SI_QX(SystemBasicInformation
),
1446 SI_QX(SystemProcessorInformation
),
1447 SI_QX(SystemPerformanceInformation
),
1448 SI_QX(SystemTimeOfDayInformation
),
1449 SI_QX(SystemPathInformation
), /* should be SI_XX */
1450 SI_QX(SystemProcessInformation
),
1451 SI_QX(SystemCallCountInformation
),
1452 SI_QX(SystemDeviceInformation
),
1453 SI_QX(SystemProcessorPerformanceInformation
),
1454 SI_QS(SystemFlagsInformation
),
1455 SI_QX(SystemCallTimeInformation
), /* should be SI_XX */
1456 SI_QX(SystemModuleInformation
),
1457 SI_QX(SystemLocksInformation
),
1458 SI_QX(SystemStackTraceInformation
), /* should be SI_XX */
1459 SI_QX(SystemPagedPoolInformation
), /* should be SI_XX */
1460 SI_QX(SystemNonPagedPoolInformation
), /* should be SI_XX */
1461 SI_QX(SystemHandleInformation
),
1462 SI_QX(SystemObjectInformation
),
1463 SI_QX(SystemPageFileInformation
),
1464 SI_QX(SystemVdmInstemulInformation
),
1465 SI_QX(SystemVdmBopInformation
), /* it should be SI_XX */
1466 SI_QS(SystemFileCacheInformation
),
1467 SI_QX(SystemPoolTagInformation
),
1468 SI_QX(SystemInterruptInformation
),
1469 SI_QS(SystemDpcBehaviourInformation
),
1470 SI_QX(SystemFullMemoryInformation
), /* it should be SI_XX */
1471 SI_XS(SystemLoadImage
),
1472 SI_XS(SystemUnloadImage
),
1473 SI_QS(SystemTimeAdjustmentInformation
),
1474 SI_QX(SystemSummaryMemoryInformation
), /* it should be SI_XX */
1475 SI_QX(SystemNextEventIdInformation
), /* it should be SI_XX */
1476 SI_QX(SystemEventIdsInformation
), /* it should be SI_XX */
1477 SI_QX(SystemCrashDumpInformation
),
1478 SI_QX(SystemExceptionInformation
),
1479 SI_QX(SystemCrashDumpStateInformation
),
1480 SI_QX(SystemKernelDebuggerInformation
),
1481 SI_QX(SystemContextSwitchInformation
),
1482 SI_QS(SystemRegistryQuotaInformation
),
1483 SI_XS(SystemLoadAndCallImage
),
1484 SI_XS(SystemPrioritySeperation
),
1485 SI_QX(SystemPlugPlayBusInformation
), /* it should be SI_XX */
1486 SI_QX(SystemDockInformation
), /* it should be SI_XX */
1487 SI_QX(SystemPowerInformation
), /* it should be SI_XX */
1488 SI_QX(SystemProcessorSpeedInformation
), /* it should be SI_XX */
1489 SI_QS(SystemCurrentTimeZoneInformation
), /* it should be SI_QX */
1490 SI_QX(SystemLookasideInformation
),
1491 SI_XS(SystemSetTimeSlipEvent
),
1492 SI_XS(SystemCreateSession
),
1493 SI_XS(SystemDeleteSession
),
1494 SI_QX(SystemInvalidInfoClass4
), /* it should be SI_XX */
1495 SI_QX(SystemRangeStartInformation
),
1496 SI_QS(SystemVerifierInformation
),
1497 SI_XS(SystemAddVerifier
),
1498 SI_QX(SystemSessionProcessesInformation
)
1506 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1507 OUT PVOID UnsafeSystemInformation
,
1509 OUT PULONG UnsafeResultLength
)
1512 PVOID SystemInformation
;
1518 /* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
1519 SystemInformationClass );
1521 /*if (ExGetPreviousMode() == KernelMode)
1523 SystemInformation
= UnsafeSystemInformation
;
1527 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1528 if (SystemInformation == NULL)
1530 return(STATUS_NO_MEMORY);
1534 /* Clear user buffer. */
1535 RtlZeroMemory(SystemInformation
, Length
);
1538 * Check the request is valid.
1540 if ((SystemInformationClass
>= SystemInformationClassMin
) &&
1541 (SystemInformationClass
< SystemInformationClassMax
))
1543 if (NULL
!= CallQS
[SystemInformationClass
].Query
)
1546 * Hand the request to a subhandler.
1548 FStatus
= CallQS
[SystemInformationClass
].Query(SystemInformation
,
1551 /*if (ExGetPreviousMode() != KernelMode)
1553 Status = MmCopyToCaller(UnsafeSystemInformation,
1556 ExFreePool(SystemInformation);
1557 if (!NT_SUCCESS(Status))
1562 if (UnsafeResultLength
!= NULL
)
1564 /*if (ExGetPreviousMode() == KernelMode)
1566 *UnsafeResultLength = ResultLength;
1570 Status
= MmCopyToCaller(UnsafeResultLength
,
1573 if (!NT_SUCCESS(Status
))
1582 return (STATUS_INVALID_INFO_CLASS
);
1588 NtSetSystemInformation (
1589 IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1590 IN PVOID SystemInformation
,
1591 IN ULONG SystemInformationLength
1597 * If called from user mode, check
1598 * possible unsafe arguments.
1601 if (KernelMode
!= KeGetPreviousMode())
1605 // SystemInformation,
1615 * Check the request is valid.
1617 if ( (SystemInformationClass
>= SystemInformationClassMin
)
1618 && (SystemInformationClass
< SystemInformationClassMax
)
1621 if (NULL
!= CallQS
[SystemInformationClass
].Set
)
1624 * Hand the request to a subhandler.
1626 return CallQS
[SystemInformationClass
].Set (
1628 SystemInformationLength
1632 return (STATUS_INVALID_INFO_CLASS
);
1638 NtFlushInstructionCache (
1639 IN HANDLE ProcessHandle
,
1640 IN PVOID BaseAddress
,
1641 IN UINT NumberOfBytesToFlush
1646 __asm__("wbinvd\n");
1647 return STATUS_SUCCESS
;