1 /* $Id: sysinfo.c,v 1.23 2003/07/17 16:57:38 silverblade Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/sysinfo.c
6 * PURPOSE: System information functions
7 * PROGRAMMER: David Welch (welch@mcmail.com)
10 * 20/03/2003: implemented querying SystemProcessInformation,
11 * no more copying to-from the caller (Aleksey
12 * Bragin <aleksey@studiocerebral.com>)
15 /* INCLUDES *****************************************************************/
17 #define NTOS_MODE_KERNEL
19 #include <ddk/halfuncs.h>
20 #include <internal/ex.h>
21 #include <internal/ldr.h>
22 #include <internal/safe.h>
23 #include <internal/ps.h>
25 #include <internal/debug.h>
27 extern ULONG NtGlobalFlag
; /* FIXME: it should go in a ddk/?.h */
29 /* FUNCTIONS *****************************************************************/
32 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
33 OUT PVOID UnsafeValue
,
35 IN OUT PULONG UnsafeReturnLength
)
43 UNICODE_STRING WValue
;
47 * Copy the name to kernel space if necessary and convert it to ANSI.
49 if (ExGetPreviousMode() != KernelMode
)
51 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
52 if (!NT_SUCCESS(Status
))
56 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
57 if (!NT_SUCCESS(Status
))
64 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
65 if (!NT_SUCCESS(Status
))
72 * Create a temporary buffer for the value
74 Value
= ExAllocatePool(NonPagedPool
, Length
);
77 RtlFreeAnsiString(&AName
);
78 if (ExGetPreviousMode() != KernelMode
)
80 RtlFreeUnicodeString(&WName
);
82 return(STATUS_NO_MEMORY
);
86 * Get the environment variable
88 Result
= HalGetEnvironmentVariable(AName
.Buffer
, Value
, Length
);
91 RtlFreeAnsiString(&AName
);
92 if (ExGetPreviousMode() != KernelMode
)
94 RtlFreeUnicodeString(&WName
);
97 return(STATUS_UNSUCCESSFUL
);
101 * Convert the result to UNICODE.
103 RtlInitAnsiString(&AValue
, Value
);
104 Status
= RtlAnsiStringToUnicodeString(&WValue
, &AValue
, TRUE
);
105 if (!NT_SUCCESS(Status
))
107 RtlFreeAnsiString(&AName
);
108 if (ExGetPreviousMode() != KernelMode
)
110 RtlFreeUnicodeString(&WName
);
115 ReturnLength
= WValue
.Length
;
118 * Copy the result back to the caller.
120 if (ExGetPreviousMode() != KernelMode
)
122 Status
= MmCopyToCaller(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
123 if (!NT_SUCCESS(Status
))
125 RtlFreeAnsiString(&AName
);
126 if (ExGetPreviousMode() != KernelMode
)
128 RtlFreeUnicodeString(&WName
);
131 RtlFreeUnicodeString(&WValue
);
135 Status
= MmCopyToCaller(UnsafeReturnLength
, &ReturnLength
,
137 if (!NT_SUCCESS(Status
))
139 RtlFreeAnsiString(&AName
);
140 if (ExGetPreviousMode() != KernelMode
)
142 RtlFreeUnicodeString(&WName
);
145 RtlFreeUnicodeString(&WValue
);
151 memcpy(UnsafeValue
, WValue
.Buffer
, ReturnLength
);
152 memcpy(UnsafeReturnLength
, &ReturnLength
, sizeof(ULONG
));
156 * Free temporary buffers.
158 RtlFreeAnsiString(&AName
);
159 if (ExGetPreviousMode() != KernelMode
)
161 RtlFreeUnicodeString(&WName
);
164 RtlFreeUnicodeString(&WValue
);
166 return(STATUS_SUCCESS
);
171 NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName
,
172 IN PUNICODE_STRING UnsafeValue
)
174 UNICODE_STRING WName
;
176 UNICODE_STRING WValue
;
182 * Check for required privilege.
184 /* FIXME: Not implemented. */
187 * Copy the name to kernel space if necessary and convert it to ANSI.
189 if (ExGetPreviousMode() != KernelMode
)
191 Status
= RtlCaptureUnicodeString(&WName
, UnsafeName
);
192 if (!NT_SUCCESS(Status
))
196 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
197 if (!NT_SUCCESS(Status
))
204 Status
= RtlUnicodeStringToAnsiString(&AName
, UnsafeName
, TRUE
);
205 if (!NT_SUCCESS(Status
))
212 * Copy the value to kernel space and convert to ANSI.
214 if (ExGetPreviousMode() != KernelMode
)
216 Status
= RtlCaptureUnicodeString(&WValue
, UnsafeValue
);
217 if (!NT_SUCCESS(Status
))
219 RtlFreeUnicodeString(&WName
);
220 RtlFreeAnsiString(&AName
);
223 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
224 if (!NT_SUCCESS(Status
))
226 RtlFreeUnicodeString(&WName
);
227 RtlFreeAnsiString(&AName
);
228 RtlFreeUnicodeString(&WValue
);
234 Status
= RtlUnicodeStringToAnsiString(&AValue
, UnsafeValue
, TRUE
);
235 if (!NT_SUCCESS(Status
))
237 RtlFreeAnsiString(&AName
);
243 * Set the environment variable
245 Result
= HalSetEnvironmentVariable(AName
.Buffer
, AValue
.Buffer
);
248 * Free everything and return status.
250 RtlFreeAnsiString(&AName
);
251 RtlFreeAnsiString(&AValue
);
252 if (ExGetPreviousMode() != KernelMode
)
254 RtlFreeUnicodeString(&WName
);
255 RtlFreeUnicodeString(&WValue
);
260 return(STATUS_UNSUCCESSFUL
);
262 return(STATUS_SUCCESS
);
266 /* --- Query/Set System Information --- */
270 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
271 * so the stack is popped only in one place on x86 platform.
273 #define QSI_USE(n) QSI##n
275 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
277 #define SSI_USE(n) SSI##n
279 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
281 /* Class 0 - Basic Information */
282 QSI_DEF(SystemBasicInformation
)
284 PSYSTEM_BASIC_INFORMATION Sbi
285 = (PSYSTEM_BASIC_INFORMATION
) Buffer
;
287 *ReqSize
= sizeof (SYSTEM_BASIC_INFORMATION
);
289 * Check user buffer's size
291 if (Size
< sizeof (SYSTEM_BASIC_INFORMATION
))
293 return (STATUS_INFO_LENGTH_MISMATCH
);
297 Sbi
->MaximumIncrement
= 0; /* FIXME */
298 Sbi
->PhysicalPageSize
= PAGE_SIZE
; /* FIXME: it should be PAGE_SIZE */
299 Sbi
->NumberOfPhysicalPages
= 0; /* FIXME */
300 Sbi
->LowestPhysicalPage
= 0; /* FIXME */
301 Sbi
->HighestPhysicalPage
= 0; /* FIXME */
302 Sbi
->AllocationGranularity
= 65536; /* hard coded on Intel? */
303 Sbi
->LowestUserAddress
= 0; /* FIXME */
304 Sbi
->HighestUserAddress
= 0; /* FIXME */
305 Sbi
->ActiveProcessors
= 0x00000001; /* FIXME */
306 Sbi
->NumberProcessors
= 1; /* FIXME */
308 return (STATUS_SUCCESS
);
311 /* Class 1 - Processor Information */
312 QSI_DEF(SystemProcessorInformation
)
314 PSYSTEM_PROCESSOR_INFORMATION Spi
315 = (PSYSTEM_PROCESSOR_INFORMATION
) Buffer
;
317 *ReqSize
= sizeof (SYSTEM_PROCESSOR_INFORMATION
);
319 * Check user buffer's size
321 if (Size
< sizeof (SYSTEM_PROCESSOR_INFORMATION
))
323 return (STATUS_INFO_LENGTH_MISMATCH
);
326 /* FIXME: add CPU type detection code */
327 Spi
->ProcessorArchitecture
= 0; /* FIXME */
328 Spi
->ProcessorLevel
= 0; /* FIXME */
329 Spi
->ProcessorRevision
= 0; /* FIXME */
331 Spi
->FeatureBits
= 0x00000000; /* FIXME */
333 return (STATUS_SUCCESS
);
336 /* Class 2 - Performance Information */
337 QSI_DEF(SystemPerformanceInformation
)
339 PSYSTEM_PERFORMANCE_INFORMATION Spi
340 = (PSYSTEM_PERFORMANCE_INFORMATION
) Buffer
;
342 *ReqSize
= sizeof (SYSTEM_PERFORMANCE_INFORMATION
);
344 * Check user buffer's size
346 if (Size
< sizeof (SYSTEM_PERFORMANCE_INFORMATION
))
348 return (STATUS_INFO_LENGTH_MISMATCH
);
351 Spi
->IdleTime
.QuadPart
= 0; /* FIXME */
352 Spi
->ReadTransferCount
.QuadPart
= 0; /* FIXME */
353 Spi
->WriteTransferCount
.QuadPart
= 0; /* FIXME */
354 Spi
->OtherTransferCount
.QuadPart
= 0; /* FIXME */
355 Spi
->ReadOperationCount
= 0; /* FIXME */
356 Spi
->WriteOperationCount
= 0; /* FIXME */
357 Spi
->OtherOperationCount
= 0; /* FIXME */
358 Spi
->AvailablePages
= 0; /* FIXME */
359 Spi
->TotalCommittedPages
= 0; /* FIXME */
360 Spi
->TotalCommitLimit
= 0; /* FIXME */
361 Spi
->PeakCommitment
= 0; /* FIXME */
362 Spi
->PageFaults
= 0; /* FIXME */
363 Spi
->WriteCopyFaults
= 0; /* FIXME */
364 Spi
->TransitionFaults
= 0; /* FIXME */
365 Spi
->CacheTransitionFaults
= 0; /* FIXME */
366 Spi
->DemandZeroFaults
= 0; /* FIXME */
367 Spi
->PagesRead
= 0; /* FIXME */
368 Spi
->PageReadIos
= 0; /* FIXME */
369 Spi
->CacheReads
= 0; /* FIXME */
370 Spi
->CacheIos
= 0; /* FIXME */
371 Spi
->PagefilePagesWritten
= 0; /* FIXME */
372 Spi
->PagefilePageWriteIos
= 0; /* FIXME */
373 Spi
->MappedFilePagesWritten
= 0; /* FIXME */
374 Spi
->MappedFilePageWriteIos
= 0; /* FIXME */
375 Spi
->PagedPoolUsage
= 0; /* FIXME */
376 Spi
->NonPagedPoolUsage
= 0; /* FIXME */
377 Spi
->PagedPoolAllocs
= 0; /* FIXME */
378 Spi
->PagedPoolFrees
= 0; /* FIXME */
379 Spi
->NonPagedPoolAllocs
= 0; /* FIXME */
380 Spi
->NonPagedPoolFrees
= 0; /* FIXME */
381 Spi
->TotalFreeSystemPtes
= 0; /* FIXME */
382 Spi
->SystemCodePage
= 0; /* FIXME */
383 Spi
->TotalSystemDriverPages
= 0; /* FIXME */
384 Spi
->TotalSystemCodePages
= 0; /* FIXME */
385 Spi
->SmallNonPagedLookasideListAllocateHits
= 0; /* FIXME */
386 Spi
->SmallPagedLookasideListAllocateHits
= 0; /* FIXME */
387 Spi
->Reserved3
= 0; /* FIXME */
389 Spi
->MmSystemCachePage
= 0; /* FIXME */
390 Spi
->PagedPoolPage
= 0; /* FIXME */
391 Spi
->SystemDriverPage
= 0; /* FIXME */
393 Spi
->FastReadNoWait
= 0; /* FIXME */
394 Spi
->FastReadWait
= 0; /* FIXME */
395 Spi
->FastReadResourceMiss
= 0; /* FIXME */
396 Spi
->FastReadNotPossible
= 0; /* FIXME */
398 Spi
->FastMdlReadNoWait
= 0; /* FIXME */
399 Spi
->FastMdlReadWait
= 0; /* FIXME */
400 Spi
->FastMdlReadResourceMiss
= 0; /* FIXME */
401 Spi
->FastMdlReadNotPossible
= 0; /* FIXME */
403 Spi
->MapDataNoWait
= 0; /* FIXME */
404 Spi
->MapDataWait
= 0; /* FIXME */
405 Spi
->MapDataNoWaitMiss
= 0; /* FIXME */
406 Spi
->MapDataWaitMiss
= 0; /* FIXME */
408 Spi
->PinMappedDataCount
= 0; /* FIXME */
409 Spi
->PinReadNoWait
= 0; /* FIXME */
410 Spi
->PinReadWait
= 0; /* FIXME */
411 Spi
->PinReadNoWaitMiss
= 0; /* FIXME */
412 Spi
->PinReadWaitMiss
= 0; /* FIXME */
413 Spi
->CopyReadNoWait
= 0; /* FIXME */
414 Spi
->CopyReadWait
= 0; /* FIXME */
415 Spi
->CopyReadNoWaitMiss
= 0; /* FIXME */
416 Spi
->CopyReadWaitMiss
= 0; /* FIXME */
418 Spi
->MdlReadNoWait
= 0; /* FIXME */
419 Spi
->MdlReadWait
= 0; /* FIXME */
420 Spi
->MdlReadNoWaitMiss
= 0; /* FIXME */
421 Spi
->MdlReadWaitMiss
= 0; /* FIXME */
422 Spi
->ReadAheadIos
= 0; /* FIXME */
423 Spi
->LazyWriteIos
= 0; /* FIXME */
424 Spi
->LazyWritePages
= 0; /* FIXME */
425 Spi
->DataFlushes
= 0; /* FIXME */
426 Spi
->DataPages
= 0; /* FIXME */
427 Spi
->ContextSwitches
= 0; /* FIXME */
428 Spi
->FirstLevelTbFills
= 0; /* FIXME */
429 Spi
->SecondLevelTbFills
= 0; /* FIXME */
430 Spi
->SystemCalls
= 0; /* FIXME */
432 return (STATUS_SUCCESS
);
435 /* Class 3 - Time Of Day Information */
436 QSI_DEF(SystemTimeOfDayInformation
)
438 PSYSTEM_TIMEOFDAY_INFORMATION Sti
439 = (PSYSTEM_TIMEOFDAY_INFORMATION
) Buffer
;
441 *ReqSize
= sizeof (SYSTEM_TIMEOFDAY_INFORMATION
);
443 * Check user buffer's size
445 if (Size
< sizeof (SYSTEM_TIMEOFDAY_INFORMATION
))
447 return (STATUS_INFO_LENGTH_MISMATCH
);
450 Sti
->BootTime
.QuadPart
= 0; /* FIXME */
451 Sti
->CurrentTime
.QuadPart
= 0; /* FIXME */
452 Sti
->TimeZoneBias
.QuadPart
= 0; /* FIXME */
453 Sti
->TimeZoneId
= 0; /* FIXME */
454 Sti
->Reserved
= 0; /* FIXME */
456 return (STATUS_SUCCESS
);
459 /* Class 4 - Path Information */
460 QSI_DEF(SystemPathInformation
)
462 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
463 return (STATUS_BREAKPOINT
);
466 /* Class 5 - Process Information */
467 QSI_DEF(SystemProcessInformation
)
469 ULONG ovlSize
=0, nThreads
=1;
473 /* scan the process list */
474 // TODO: Add thread information
476 PSYSTEM_PROCESSES Spi
477 = (PSYSTEM_PROCESSES
) Buffer
;
479 *ReqSize
= sizeof(SYSTEM_PROCESSES
);
481 if (Size
< sizeof(SYSTEM_PROCESSES
))
483 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
486 syspr
= PsGetNextProcess(NULL
);
488 pCur
= (unsigned char *)Spi
;
492 PSYSTEM_PROCESSES SpiCur
;
495 int inLen
=32; // image name len in bytes
498 SpiCur
= (PSYSTEM_PROCESSES
)pCur
;
500 nThreads
= 1; // FIXME
502 // size of the structure for every process
503 curSize
= sizeof(SYSTEM_PROCESSES
)-sizeof(SYSTEM_THREADS
)+sizeof(SYSTEM_THREADS
)*nThreads
;
504 ovlSize
+= curSize
+inLen
;
510 return (STATUS_INFO_LENGTH_MISMATCH
); // in case buffer size is too small
513 // fill system information
514 SpiCur
->NextEntryDelta
= curSize
+inLen
; // relative offset to the beginnnig of the next structure
515 SpiCur
->ThreadCount
= nThreads
;
516 SpiCur
->CreateTime
= pr
->CreateTime
;
517 //SpiCur->UserTime = 0; // FIXME
518 //SpiCur->KernelTime = 0; // FIXME
520 SpiCur
->ProcessName
.Length
= strlen(pr
->ImageFileName
) * sizeof(WCHAR
);
521 SpiCur
->ProcessName
.MaximumLength
= inLen
;
522 SpiCur
->ProcessName
.Buffer
= (void*)(pCur
+curSize
);
524 // copy name to the end of the struct
525 RtlInitAnsiString(&imgName
, pr
->ImageFileName
);
526 RtlAnsiStringToUnicodeString(&SpiCur
->ProcessName
, &imgName
, FALSE
);
528 SpiCur
->BasePriority
= 0; // FIXME
529 SpiCur
->ProcessId
= pr
->UniqueProcessId
;
530 SpiCur
->InheritedFromProcessId
= 0; // FIXME
531 SpiCur
->HandleCount
= 0; // FIXME
532 SpiCur
->VmCounters
.PeakVirtualSize
= pr
->PeakVirtualSize
;
533 SpiCur
->VmCounters
.VirtualSize
= 0; // FIXME
534 SpiCur
->VmCounters
.PageFaultCount
= pr
->LastFaultCount
;
535 SpiCur
->VmCounters
.PeakWorkingSetSize
= pr
->Vm
.PeakWorkingSetSize
; // Is this right using ->Vm. here ?
536 SpiCur
->VmCounters
.WorkingSetSize
= pr
->Vm
.WorkingSetSize
; // Is this right using ->Vm. here ?
537 SpiCur
->VmCounters
.QuotaPeakPagedPoolUsage
= 0; // FIXME
538 SpiCur
->VmCounters
.QuotaPagedPoolUsage
= 0; // FIXME
539 SpiCur
->VmCounters
.QuotaPeakNonPagedPoolUsage
= 0; // FIXME
540 SpiCur
->VmCounters
.QuotaNonPagedPoolUsage
= 0; // FIXME
541 SpiCur
->VmCounters
.PagefileUsage
= 0; // FIXME
542 SpiCur
->VmCounters
.PeakPagefileUsage
= pr
->PeakPagefileUsage
;
543 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
544 // doesn't seem to contain any equivalent field
545 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
547 pr
= PsGetNextProcess(pr
);
549 if ((pr
== syspr
) || (pr
== NULL
))
551 SpiCur
->NextEntryDelta
= 0;
555 pCur
= pCur
+ curSize
+ inLen
;
556 } while ((pr
!= syspr
) && (pr
!= NULL
));
560 return (STATUS_SUCCESS
);
563 /* Class 6 - Call Count Information */
564 QSI_DEF(SystemCallCountInformation
)
567 return (STATUS_NOT_IMPLEMENTED
);
570 /* Class 7 - Device Information */
571 QSI_DEF(SystemDeviceInformation
)
573 PSYSTEM_DEVICE_INFORMATION Sdi
574 = (PSYSTEM_DEVICE_INFORMATION
) Buffer
;
575 PCONFIGURATION_INFORMATION ConfigInfo
;
577 *ReqSize
= sizeof (SYSTEM_DEVICE_INFORMATION
);
579 * Check user buffer's size
581 if (Size
< sizeof (SYSTEM_DEVICE_INFORMATION
))
583 return (STATUS_INFO_LENGTH_MISMATCH
);
586 ConfigInfo
= IoGetConfigurationInformation ();
588 Sdi
->NumberOfDisks
= ConfigInfo
->DiskCount
;
589 Sdi
->NumberOfFloppies
= ConfigInfo
->FloppyCount
;
590 Sdi
->NumberOfCdRoms
= ConfigInfo
->CdRomCount
;
591 Sdi
->NumberOfTapes
= ConfigInfo
->TapeCount
;
592 Sdi
->NumberOfSerialPorts
= ConfigInfo
->SerialCount
;
593 Sdi
->NumberOfParallelPorts
= ConfigInfo
->ParallelCount
;
595 return (STATUS_SUCCESS
);
598 /* Class 8 - Processor Performance Information */
599 QSI_DEF(SystemProcessorPerformanceInformation
)
602 return (STATUS_NOT_IMPLEMENTED
);
605 /* Class 9 - Flags Information */
606 QSI_DEF(SystemFlagsInformation
)
608 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
610 * ReqSize
= sizeof (SYSTEM_FLAGS_INFORMATION
);
611 return (STATUS_INFO_LENGTH_MISMATCH
);
613 ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
= NtGlobalFlag
;
614 return (STATUS_SUCCESS
);
617 SSI_DEF(SystemFlagsInformation
)
619 if (sizeof (SYSTEM_FLAGS_INFORMATION
) != Size
)
621 return (STATUS_INFO_LENGTH_MISMATCH
);
623 NtGlobalFlag
= ((PSYSTEM_FLAGS_INFORMATION
) Buffer
)->Flags
;
624 return (STATUS_SUCCESS
);
627 /* Class 10 - Call Time Information */
628 QSI_DEF(SystemCallTimeInformation
)
631 return (STATUS_NOT_IMPLEMENTED
);
634 /* Class 11 - Module Information */
635 QSI_DEF(SystemModuleInformation
)
637 return LdrpQueryModuleInformation(Buffer
, Size
, ReqSize
);
640 /* Class 12 - Locks Information */
641 QSI_DEF(SystemLocksInformation
)
644 return (STATUS_NOT_IMPLEMENTED
);
647 /* Class 13 - Stack Trace Information */
648 QSI_DEF(SystemStackTraceInformation
)
651 return (STATUS_NOT_IMPLEMENTED
);
654 /* Class 14 - Paged Pool Information */
655 QSI_DEF(SystemPagedPoolInformation
)
658 return (STATUS_NOT_IMPLEMENTED
);
661 /* Class 15 - Non Paged Pool Information */
662 QSI_DEF(SystemNonPagedPoolInformation
)
665 return (STATUS_NOT_IMPLEMENTED
);
668 /* Class 16 - Handle Information */
669 QSI_DEF(SystemHandleInformation
)
672 return (STATUS_NOT_IMPLEMENTED
);
675 /* Class 17 - Information */
676 QSI_DEF(SystemObjectInformation
)
679 return (STATUS_NOT_IMPLEMENTED
);
682 /* Class 18 - Information */
683 QSI_DEF(SystemPageFileInformation
)
686 return (STATUS_NOT_IMPLEMENTED
);
689 /* Class 19 - Vdm Instemul Information */
690 QSI_DEF(SystemVdmInstemulInformation
)
693 return (STATUS_NOT_IMPLEMENTED
);
696 /* Class 20 - Vdm Bop Information */
697 QSI_DEF(SystemVdmBopInformation
)
700 return (STATUS_NOT_IMPLEMENTED
);
703 /* Class 21 - File Cache Information */
704 QSI_DEF(SystemFileCacheInformation
)
706 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
708 * ReqSize
= sizeof (SYSTEM_CACHE_INFORMATION
);
709 return (STATUS_INFO_LENGTH_MISMATCH
);
712 return (STATUS_NOT_IMPLEMENTED
);
715 SSI_DEF(SystemFileCacheInformation
)
717 if (Size
< sizeof (SYSTEM_CACHE_INFORMATION
))
719 return (STATUS_INFO_LENGTH_MISMATCH
);
722 return (STATUS_NOT_IMPLEMENTED
);
725 /* Class 22 - Pool Tag Information */
726 QSI_DEF(SystemPoolTagInformation
)
729 return (STATUS_NOT_IMPLEMENTED
);
732 /* Class 23 - Interrupt Information */
733 QSI_DEF(SystemInterruptInformation
)
736 return (STATUS_NOT_IMPLEMENTED
);
739 /* Class 24 - DPC Behaviour Information */
740 QSI_DEF(SystemDpcBehaviourInformation
)
743 return (STATUS_NOT_IMPLEMENTED
);
746 SSI_DEF(SystemDpcBehaviourInformation
)
749 return (STATUS_NOT_IMPLEMENTED
);
752 /* Class 25 - Full Memory Information */
753 QSI_DEF(SystemFullMemoryInformation
)
756 return (STATUS_NOT_IMPLEMENTED
);
759 /* Class 26 - Load Image */
760 SSI_DEF(SystemLoadImage
)
762 PSYSTEM_LOAD_IMAGE Sli
= (PSYSTEM_LOAD_IMAGE
)Buffer
;
764 if (sizeof(SYSTEM_LOAD_IMAGE
) != Size
)
766 return(STATUS_INFO_LENGTH_MISMATCH
);
769 return(LdrpLoadImage(&Sli
->ModuleName
,
771 &Sli
->SectionPointer
,
773 &Sli
->ExportDirectory
));
776 /* Class 27 - Unload Image */
777 SSI_DEF(SystemUnloadImage
)
779 PSYSTEM_UNLOAD_IMAGE Sui
= (PSYSTEM_UNLOAD_IMAGE
)Buffer
;
781 if (sizeof(SYSTEM_UNLOAD_IMAGE
) != Size
)
783 return(STATUS_INFO_LENGTH_MISMATCH
);
786 return(LdrpUnloadImage(Sui
->ModuleBase
));
789 /* Class 28 - Time Adjustment Information */
790 QSI_DEF(SystemTimeAdjustmentInformation
)
792 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
794 * ReqSize
= sizeof (SYSTEM_SET_TIME_ADJUSTMENT
);
795 return (STATUS_INFO_LENGTH_MISMATCH
);
798 return (STATUS_NOT_IMPLEMENTED
);
801 SSI_DEF(SystemTimeAdjustmentInformation
)
803 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT
) > Size
)
805 return (STATUS_INFO_LENGTH_MISMATCH
);
808 return (STATUS_NOT_IMPLEMENTED
);
811 /* Class 29 - Summary Memory Information */
812 QSI_DEF(SystemSummaryMemoryInformation
)
815 return (STATUS_NOT_IMPLEMENTED
);
818 /* Class 30 - Next Event Id Information */
819 QSI_DEF(SystemNextEventIdInformation
)
822 return (STATUS_NOT_IMPLEMENTED
);
825 /* Class 31 - Event Ids Information */
826 QSI_DEF(SystemEventIdsInformation
)
829 return (STATUS_NOT_IMPLEMENTED
);
832 /* Class 32 - Crach Dump Information */
833 QSI_DEF(SystemCrashDumpInformation
)
836 return (STATUS_NOT_IMPLEMENTED
);
839 /* Class 33 - Exception Information */
840 QSI_DEF(SystemExceptionInformation
)
843 return (STATUS_NOT_IMPLEMENTED
);
846 /* Class 34 - Crach Dump State Information */
847 QSI_DEF(SystemCrashDumpStateInformation
)
850 return (STATUS_NOT_IMPLEMENTED
);
853 /* Class 35 - Kernel Debugger Information */
854 QSI_DEF(SystemKernelDebuggerInformation
)
857 return (STATUS_NOT_IMPLEMENTED
);
860 /* Class 36 - Context Switch Information */
861 QSI_DEF(SystemContextSwitchInformation
)
864 return (STATUS_NOT_IMPLEMENTED
);
867 /* Class 37 - Registry Quota Information */
868 QSI_DEF(SystemRegistryQuotaInformation
)
871 return (STATUS_NOT_IMPLEMENTED
);
874 SSI_DEF(SystemRegistryQuotaInformation
)
877 return (STATUS_NOT_IMPLEMENTED
);
880 /* Class 38 - Load And Call Image */
881 SSI_DEF(SystemLoadAndCallImage
)
883 PSYSTEM_LOAD_AND_CALL_IMAGE Slci
= (PSYSTEM_LOAD_AND_CALL_IMAGE
)Buffer
;
885 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE
) != Size
)
887 return(STATUS_INFO_LENGTH_MISMATCH
);
890 return(LdrpLoadAndCallImage(&Slci
->ModuleName
));
893 /* Class 39 - Priority Seperation */
894 SSI_DEF(SystemPrioritySeperation
)
897 return (STATUS_NOT_IMPLEMENTED
);
900 /* Class 40 - Plug Play Bus Information */
901 QSI_DEF(SystemPlugPlayBusInformation
)
904 return (STATUS_NOT_IMPLEMENTED
);
907 /* Class 41 - Dock Information */
908 QSI_DEF(SystemDockInformation
)
911 return (STATUS_NOT_IMPLEMENTED
);
914 /* Class 42 - Power Information */
915 QSI_DEF(SystemPowerInformation
)
918 return (STATUS_NOT_IMPLEMENTED
);
921 /* Class 43 - Processor Speed Information */
922 QSI_DEF(SystemProcessorSpeedInformation
)
925 return (STATUS_NOT_IMPLEMENTED
);
928 /* Class 44 - Current Time Zone Information */
929 QSI_DEF(SystemCurrentTimeZoneInformation
)
931 * ReqSize
= sizeof (TIME_ZONE_INFORMATION
);
933 if (sizeof (TIME_ZONE_INFORMATION
) != Size
)
935 return (STATUS_INFO_LENGTH_MISMATCH
);
937 /* Copy the time zone information struct */
940 & SystemTimeZoneInfo
,
941 sizeof (TIME_ZONE_INFORMATION
)
944 return (STATUS_SUCCESS
);
948 SSI_DEF(SystemCurrentTimeZoneInformation
)
951 * Check user buffer's size
953 if (Size
< sizeof (TIME_ZONE_INFORMATION
))
955 return (STATUS_INFO_LENGTH_MISMATCH
);
957 /* Copy the time zone information struct */
959 & SystemTimeZoneInfo
,
960 (TIME_ZONE_INFORMATION
*) Buffer
,
961 sizeof (TIME_ZONE_INFORMATION
)
963 return (STATUS_SUCCESS
);
967 /* Class 45 - Lookaside Information */
968 QSI_DEF(SystemLookasideInformation
)
971 return (STATUS_NOT_IMPLEMENTED
);
975 /* Class 46 - Set time slip event */
976 SSI_DEF(SystemSetTimeSlipEvent
)
979 return (STATUS_NOT_IMPLEMENTED
);
983 /* Class 47 - Create a new session (TSE) */
984 SSI_DEF(SystemCreateSession
)
987 return (STATUS_NOT_IMPLEMENTED
);
991 /* Class 48 - Delete an existing session (TSE) */
992 SSI_DEF(SystemDeleteSession
)
995 return (STATUS_NOT_IMPLEMENTED
);
999 /* Class 49 - UNKNOWN */
1000 QSI_DEF(SystemInvalidInfoClass4
)
1003 return (STATUS_NOT_IMPLEMENTED
);
1007 /* Class 50 - System range start address */
1008 QSI_DEF(SystemRangeStartInformation
)
1011 return (STATUS_NOT_IMPLEMENTED
);
1015 /* Class 51 - Driver verifier information */
1016 QSI_DEF(SystemVerifierInformation
)
1019 return (STATUS_NOT_IMPLEMENTED
);
1023 SSI_DEF(SystemVerifierInformation
)
1026 return (STATUS_NOT_IMPLEMENTED
);
1030 /* Class 52 - Add a driver verifier */
1031 SSI_DEF(SystemAddVerifier
)
1034 return (STATUS_NOT_IMPLEMENTED
);
1038 /* Class 53 - A session's processes */
1039 QSI_DEF(SystemSessionProcessesInformation
)
1042 return (STATUS_NOT_IMPLEMENTED
);
1046 /* Query/Set Calls Table */
1050 NTSTATUS (* Query
) (PVOID
,ULONG
,PULONG
);
1051 NTSTATUS (* Set
) (PVOID
,ULONG
);
1058 // XX unknown behaviour
1060 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1061 #define SI_QX(n) {QSI_USE(n),NULL}
1062 #define SI_XS(n) {NULL,SSI_USE(n)}
1063 #define SI_XX(n) {NULL,NULL}
1069 SI_QX(SystemBasicInformation
),
1070 SI_QX(SystemProcessorInformation
),
1071 SI_QX(SystemPerformanceInformation
),
1072 SI_QX(SystemTimeOfDayInformation
),
1073 SI_QX(SystemPathInformation
), /* should be SI_XX */
1074 SI_QX(SystemProcessInformation
),
1075 SI_QX(SystemCallCountInformation
),
1076 SI_QX(SystemDeviceInformation
),
1077 SI_QX(SystemProcessorPerformanceInformation
),
1078 SI_QS(SystemFlagsInformation
),
1079 SI_QX(SystemCallTimeInformation
), /* should be SI_XX */
1080 SI_QX(SystemModuleInformation
),
1081 SI_QX(SystemLocksInformation
),
1082 SI_QX(SystemStackTraceInformation
), /* should be SI_XX */
1083 SI_QX(SystemPagedPoolInformation
), /* should be SI_XX */
1084 SI_QX(SystemNonPagedPoolInformation
), /* should be SI_XX */
1085 SI_QX(SystemHandleInformation
),
1086 SI_QX(SystemObjectInformation
),
1087 SI_QX(SystemPageFileInformation
),
1088 SI_QX(SystemVdmInstemulInformation
),
1089 SI_QX(SystemVdmBopInformation
), /* it should be SI_XX */
1090 SI_QS(SystemFileCacheInformation
),
1091 SI_QX(SystemPoolTagInformation
),
1092 SI_QX(SystemInterruptInformation
),
1093 SI_QS(SystemDpcBehaviourInformation
),
1094 SI_QX(SystemFullMemoryInformation
), /* it should be SI_XX */
1095 SI_XS(SystemLoadImage
),
1096 SI_XS(SystemUnloadImage
),
1097 SI_QS(SystemTimeAdjustmentInformation
),
1098 SI_QX(SystemSummaryMemoryInformation
), /* it should be SI_XX */
1099 SI_QX(SystemNextEventIdInformation
), /* it should be SI_XX */
1100 SI_QX(SystemEventIdsInformation
), /* it should be SI_XX */
1101 SI_QX(SystemCrashDumpInformation
),
1102 SI_QX(SystemExceptionInformation
),
1103 SI_QX(SystemCrashDumpStateInformation
),
1104 SI_QX(SystemKernelDebuggerInformation
),
1105 SI_QX(SystemContextSwitchInformation
),
1106 SI_QS(SystemRegistryQuotaInformation
),
1107 SI_XS(SystemLoadAndCallImage
),
1108 SI_XS(SystemPrioritySeperation
),
1109 SI_QX(SystemPlugPlayBusInformation
), /* it should be SI_XX */
1110 SI_QX(SystemDockInformation
), /* it should be SI_XX */
1111 SI_QX(SystemPowerInformation
), /* it should be SI_XX */
1112 SI_QX(SystemProcessorSpeedInformation
), /* it should be SI_XX */
1113 SI_QS(SystemCurrentTimeZoneInformation
), /* it should be SI_QX */
1114 SI_QX(SystemLookasideInformation
),
1115 SI_XS(SystemSetTimeSlipEvent
),
1116 SI_XS(SystemCreateSession
),
1117 SI_XS(SystemDeleteSession
),
1118 SI_QX(SystemInvalidInfoClass4
), /* it should be SI_XX */
1119 SI_QX(SystemRangeStartInformation
),
1120 SI_QS(SystemVerifierInformation
),
1121 SI_XS(SystemAddVerifier
),
1122 SI_QX(SystemSessionProcessesInformation
)
1130 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1131 OUT PVOID UnsafeSystemInformation
,
1133 OUT PULONG UnsafeResultLength
)
1136 PVOID SystemInformation
;
1140 /*if (ExGetPreviousMode() == KernelMode)
1142 SystemInformation
= UnsafeSystemInformation
;
1146 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1147 if (SystemInformation == NULL)
1149 return(STATUS_NO_MEMORY);
1153 /* Clear user buffer. */
1154 RtlZeroMemory(SystemInformation
, Length
);
1157 * Check the request is valid.
1159 if ((SystemInformationClass
>= SystemInformationClassMin
) &&
1160 (SystemInformationClass
< SystemInformationClassMax
))
1162 if (NULL
!= CallQS
[SystemInformationClass
].Query
)
1165 * Hand the request to a subhandler.
1167 FStatus
= CallQS
[SystemInformationClass
].Query(SystemInformation
,
1170 /*if (ExGetPreviousMode() != KernelMode)
1172 Status = MmCopyToCaller(UnsafeSystemInformation,
1175 ExFreePool(SystemInformation);
1176 if (!NT_SUCCESS(Status))
1181 if (UnsafeResultLength
!= NULL
)
1183 /*if (ExGetPreviousMode() == KernelMode)
1185 *UnsafeResultLength = ResultLength;
1189 Status
= MmCopyToCaller(UnsafeResultLength
,
1192 if (!NT_SUCCESS(Status
))
1201 return (STATUS_INVALID_INFO_CLASS
);
1207 NtSetSystemInformation (
1208 IN SYSTEM_INFORMATION_CLASS SystemInformationClass
,
1209 IN PVOID SystemInformation
,
1210 IN ULONG SystemInformationLength
1214 * If called from user mode, check
1215 * possible unsafe arguments.
1218 if (KernelMode
!= KeGetPreviousMode())
1222 // SystemInformation,
1232 * Check the request is valid.
1234 if ( (SystemInformationClass
>= SystemInformationClassMin
)
1235 && (SystemInformationClass
< SystemInformationClassMax
)
1238 if (NULL
!= CallQS
[SystemInformationClass
].Set
)
1241 * Hand the request to a subhandler.
1243 return CallQS
[SystemInformationClass
].Set (
1245 SystemInformationLength
1249 return (STATUS_INVALID_INFO_CLASS
);
1255 NtFlushInstructionCache (
1256 IN HANDLE ProcessHandle
,
1257 IN PVOID BaseAddress
,
1258 IN UINT NumberOfBytesToFlush