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;
509 ObDereferenceObject(pr);
511 return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
514 // fill system information
515 SpiCur->NextEntryDelta = curSize+inLen; // relative offset to the beginnnig of the next structure
516 SpiCur->ThreadCount = nThreads;
517 SpiCur->CreateTime = pr->CreateTime;
518 //SpiCur->UserTime = 0; // FIXME
519 //SpiCur->KernelTime = 0; // FIXME
521 SpiCur->ProcessName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
522 SpiCur->ProcessName.MaximumLength = inLen;
523 SpiCur->ProcessName.Buffer = (void*)(pCur+curSize);
525 // copy name to the end of the struct
526 RtlInitAnsiString(&imgName, pr->ImageFileName);
527 RtlAnsiStringToUnicodeString(&SpiCur->ProcessName, &imgName, FALSE);
529 SpiCur->BasePriority = 0; // FIXME
530 SpiCur->ProcessId = pr->UniqueProcessId;
531 SpiCur->InheritedFromProcessId = (DWORD)(pr->InheritedFromUniqueProcessId);
532 SpiCur->HandleCount = 0; // FIXME
533 SpiCur->VmCounters.PeakVirtualSize = pr->PeakVirtualSize;
534 SpiCur->VmCounters.VirtualSize = 0; // FIXME
535 SpiCur->VmCounters.PageFaultCount = pr->LastFaultCount;
536 SpiCur->VmCounters.PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ?
537 SpiCur->VmCounters.WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ?
538 SpiCur->VmCounters.QuotaPeakPagedPoolUsage = 0; // FIXME
539 SpiCur->VmCounters.QuotaPagedPoolUsage = 0; // FIXME
540 SpiCur->VmCounters.QuotaPeakNonPagedPoolUsage = 0; // FIXME
541 SpiCur->VmCounters.QuotaNonPagedPoolUsage = 0; // FIXME
542 SpiCur->VmCounters.PagefileUsage = 0; // FIXME
543 SpiCur->VmCounters.PeakPagefileUsage = pr->PeakPagefileUsage;
544 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
545 // doesn't seem to contain any equivalent field
546 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
548 pr = PsGetNextProcess(pr);
550 if ((pr == syspr) || (pr == NULL))
552 SpiCur->NextEntryDelta = 0;
556 pCur = pCur + curSize + inLen;
557 } while ((pr != syspr) && (pr != NULL));
562 ObDereferenceObject(pr);
564 return (STATUS_SUCCESS);
567 /* Class 6 - Call Count Information */
568 QSI_DEF(SystemCallCountInformation)
571 return (STATUS_NOT_IMPLEMENTED);
574 /* Class 7 - Device Information */
575 QSI_DEF(SystemDeviceInformation)
577 PSYSTEM_DEVICE_INFORMATION Sdi
578 = (PSYSTEM_DEVICE_INFORMATION) Buffer;
579 PCONFIGURATION_INFORMATION ConfigInfo;
581 *ReqSize = sizeof (SYSTEM_DEVICE_INFORMATION);
583 * Check user buffer's size
585 if (Size < sizeof (SYSTEM_DEVICE_INFORMATION))
587 return (STATUS_INFO_LENGTH_MISMATCH);
590 ConfigInfo = IoGetConfigurationInformation ();
592 Sdi->NumberOfDisks = ConfigInfo->DiskCount;
593 Sdi->NumberOfFloppies = ConfigInfo->FloppyCount;
594 Sdi->NumberOfCdRoms = ConfigInfo->CdRomCount;
595 Sdi->NumberOfTapes = ConfigInfo->TapeCount;
596 Sdi->NumberOfSerialPorts = ConfigInfo->SerialCount;
597 Sdi->NumberOfParallelPorts = ConfigInfo->ParallelCount;
599 return (STATUS_SUCCESS);
602 /* Class 8 - Processor Performance Information */
603 QSI_DEF(SystemProcessorPerformanceInformation)
606 return (STATUS_NOT_IMPLEMENTED);
609 /* Class 9 - Flags Information */
610 QSI_DEF(SystemFlagsInformation)
612 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
614 * ReqSize = sizeof (SYSTEM_FLAGS_INFORMATION);
615 return (STATUS_INFO_LENGTH_MISMATCH);
617 ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag;
618 return (STATUS_SUCCESS);
621 SSI_DEF(SystemFlagsInformation)
623 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
625 return (STATUS_INFO_LENGTH_MISMATCH);
627 NtGlobalFlag = ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags;
628 return (STATUS_SUCCESS);
631 /* Class 10 - Call Time Information */
632 QSI_DEF(SystemCallTimeInformation)
635 return (STATUS_NOT_IMPLEMENTED);
638 /* Class 11 - Module Information */
639 QSI_DEF(SystemModuleInformation)
641 return LdrpQueryModuleInformation(Buffer, Size, ReqSize);
644 /* Class 12 - Locks Information */
645 QSI_DEF(SystemLocksInformation)
648 return (STATUS_NOT_IMPLEMENTED);
651 /* Class 13 - Stack Trace Information */
652 QSI_DEF(SystemStackTraceInformation)
655 return (STATUS_NOT_IMPLEMENTED);
658 /* Class 14 - Paged Pool Information */
659 QSI_DEF(SystemPagedPoolInformation)
662 return (STATUS_NOT_IMPLEMENTED);
665 /* Class 15 - Non Paged Pool Information */
666 QSI_DEF(SystemNonPagedPoolInformation)
669 return (STATUS_NOT_IMPLEMENTED);
672 /* Class 16 - Handle Information */
673 QSI_DEF(SystemHandleInformation)
676 return (STATUS_NOT_IMPLEMENTED);
679 /* Class 17 - Information */
680 QSI_DEF(SystemObjectInformation)
683 return (STATUS_NOT_IMPLEMENTED);
686 /* Class 18 - Information */
687 QSI_DEF(SystemPageFileInformation)
690 return (STATUS_NOT_IMPLEMENTED);
693 /* Class 19 - Vdm Instemul Information */
694 QSI_DEF(SystemVdmInstemulInformation)
697 return (STATUS_NOT_IMPLEMENTED);
700 /* Class 20 - Vdm Bop Information */
701 QSI_DEF(SystemVdmBopInformation)
704 return (STATUS_NOT_IMPLEMENTED);
707 /* Class 21 - File Cache Information */
708 QSI_DEF(SystemFileCacheInformation)
710 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
712 * ReqSize = sizeof (SYSTEM_CACHE_INFORMATION);
713 return (STATUS_INFO_LENGTH_MISMATCH);
716 return (STATUS_NOT_IMPLEMENTED);
719 SSI_DEF(SystemFileCacheInformation)
721 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
723 return (STATUS_INFO_LENGTH_MISMATCH);
726 return (STATUS_NOT_IMPLEMENTED);
729 /* Class 22 - Pool Tag Information */
730 QSI_DEF(SystemPoolTagInformation)
733 return (STATUS_NOT_IMPLEMENTED);
736 /* Class 23 - Interrupt Information */
737 QSI_DEF(SystemInterruptInformation)
740 return (STATUS_NOT_IMPLEMENTED);
743 /* Class 24 - DPC Behaviour Information */
744 QSI_DEF(SystemDpcBehaviourInformation)
747 return (STATUS_NOT_IMPLEMENTED);
750 SSI_DEF(SystemDpcBehaviourInformation)
753 return (STATUS_NOT_IMPLEMENTED);
756 /* Class 25 - Full Memory Information */
757 QSI_DEF(SystemFullMemoryInformation)
760 return (STATUS_NOT_IMPLEMENTED);
763 /* Class 26 - Load Image */
764 SSI_DEF(SystemLoadImage)
766 PSYSTEM_LOAD_IMAGE Sli = (PSYSTEM_LOAD_IMAGE)Buffer;
768 if (sizeof(SYSTEM_LOAD_IMAGE) != Size)
770 return(STATUS_INFO_LENGTH_MISMATCH);
773 return(LdrpLoadImage(&Sli->ModuleName,
775 &Sli->SectionPointer,
777 &Sli->ExportDirectory));
780 /* Class 27 - Unload Image */
781 SSI_DEF(SystemUnloadImage)
783 PSYSTEM_UNLOAD_IMAGE Sui = (PSYSTEM_UNLOAD_IMAGE)Buffer;
785 if (sizeof(SYSTEM_UNLOAD_IMAGE) != Size)
787 return(STATUS_INFO_LENGTH_MISMATCH);
790 return(LdrpUnloadImage(Sui->ModuleBase));
793 /* Class 28 - Time Adjustment Information */
794 QSI_DEF(SystemTimeAdjustmentInformation)
796 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT) > Size)
798 * ReqSize = sizeof (SYSTEM_SET_TIME_ADJUSTMENT);
799 return (STATUS_INFO_LENGTH_MISMATCH);
802 return (STATUS_NOT_IMPLEMENTED);
805 SSI_DEF(SystemTimeAdjustmentInformation)
807 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT) > Size)
809 return (STATUS_INFO_LENGTH_MISMATCH);
812 return (STATUS_NOT_IMPLEMENTED);
815 /* Class 29 - Summary Memory Information */
816 QSI_DEF(SystemSummaryMemoryInformation)
819 return (STATUS_NOT_IMPLEMENTED);
822 /* Class 30 - Next Event Id Information */
823 QSI_DEF(SystemNextEventIdInformation)
826 return (STATUS_NOT_IMPLEMENTED);
829 /* Class 31 - Event Ids Information */
830 QSI_DEF(SystemEventIdsInformation)
833 return (STATUS_NOT_IMPLEMENTED);
836 /* Class 32 - Crach Dump Information */
837 QSI_DEF(SystemCrashDumpInformation)
840 return (STATUS_NOT_IMPLEMENTED);
843 /* Class 33 - Exception Information */
844 QSI_DEF(SystemExceptionInformation)
847 return (STATUS_NOT_IMPLEMENTED);
850 /* Class 34 - Crach Dump State Information */
851 QSI_DEF(SystemCrashDumpStateInformation)
854 return (STATUS_NOT_IMPLEMENTED);
857 /* Class 35 - Kernel Debugger Information */
858 QSI_DEF(SystemKernelDebuggerInformation)
861 return (STATUS_NOT_IMPLEMENTED);
864 /* Class 36 - Context Switch Information */
865 QSI_DEF(SystemContextSwitchInformation)
868 return (STATUS_NOT_IMPLEMENTED);
871 /* Class 37 - Registry Quota Information */
872 QSI_DEF(SystemRegistryQuotaInformation)
875 return (STATUS_NOT_IMPLEMENTED);
878 SSI_DEF(SystemRegistryQuotaInformation)
881 return (STATUS_NOT_IMPLEMENTED);
884 /* Class 38 - Load And Call Image */
885 SSI_DEF(SystemLoadAndCallImage)
887 PSYSTEM_LOAD_AND_CALL_IMAGE Slci = (PSYSTEM_LOAD_AND_CALL_IMAGE)Buffer;
889 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE) != Size)
891 return(STATUS_INFO_LENGTH_MISMATCH);
894 return(LdrpLoadAndCallImage(&Slci->ModuleName));
897 /* Class 39 - Priority Seperation */
898 SSI_DEF(SystemPrioritySeperation)
901 return (STATUS_NOT_IMPLEMENTED);
904 /* Class 40 - Plug Play Bus Information */
905 QSI_DEF(SystemPlugPlayBusInformation)
908 return (STATUS_NOT_IMPLEMENTED);
911 /* Class 41 - Dock Information */
912 QSI_DEF(SystemDockInformation)
915 return (STATUS_NOT_IMPLEMENTED);
918 /* Class 42 - Power Information */
919 QSI_DEF(SystemPowerInformation)
922 return (STATUS_NOT_IMPLEMENTED);
925 /* Class 43 - Processor Speed Information */
926 QSI_DEF(SystemProcessorSpeedInformation)
929 return (STATUS_NOT_IMPLEMENTED);
932 /* Class 44 - Current Time Zone Information */
933 QSI_DEF(SystemCurrentTimeZoneInformation)
935 * ReqSize = sizeof (TIME_ZONE_INFORMATION);
937 if (sizeof (TIME_ZONE_INFORMATION) != Size)
939 return (STATUS_INFO_LENGTH_MISMATCH);
941 /* Copy the time zone information struct */
944 & SystemTimeZoneInfo,
945 sizeof (TIME_ZONE_INFORMATION)
948 return (STATUS_SUCCESS);
952 SSI_DEF(SystemCurrentTimeZoneInformation)
955 * Check user buffer's size
957 if (Size < sizeof (TIME_ZONE_INFORMATION))
959 return (STATUS_INFO_LENGTH_MISMATCH);
961 /* Copy the time zone information struct */
963 & SystemTimeZoneInfo,
964 (TIME_ZONE_INFORMATION *) Buffer,
965 sizeof (TIME_ZONE_INFORMATION)
967 return (STATUS_SUCCESS);
971 /* Class 45 - Lookaside Information */
972 QSI_DEF(SystemLookasideInformation)
975 return (STATUS_NOT_IMPLEMENTED);
979 /* Class 46 - Set time slip event */
980 SSI_DEF(SystemSetTimeSlipEvent)
983 return (STATUS_NOT_IMPLEMENTED);
987 /* Class 47 - Create a new session (TSE) */
988 SSI_DEF(SystemCreateSession)
991 return (STATUS_NOT_IMPLEMENTED);
995 /* Class 48 - Delete an existing session (TSE) */
996 SSI_DEF(SystemDeleteSession)
999 return (STATUS_NOT_IMPLEMENTED);
1003 /* Class 49 - UNKNOWN */
1004 QSI_DEF(SystemInvalidInfoClass4)
1007 return (STATUS_NOT_IMPLEMENTED);
1011 /* Class 50 - System range start address */
1012 QSI_DEF(SystemRangeStartInformation)
1015 return (STATUS_NOT_IMPLEMENTED);
1019 /* Class 51 - Driver verifier information */
1020 QSI_DEF(SystemVerifierInformation)
1023 return (STATUS_NOT_IMPLEMENTED);
1027 SSI_DEF(SystemVerifierInformation)
1030 return (STATUS_NOT_IMPLEMENTED);
1034 /* Class 52 - Add a driver verifier */
1035 SSI_DEF(SystemAddVerifier)
1038 return (STATUS_NOT_IMPLEMENTED);
1042 /* Class 53 - A session's processes */
1043 QSI_DEF(SystemSessionProcessesInformation)
1046 return (STATUS_NOT_IMPLEMENTED);
1050 /* Query/Set Calls Table */
1054 NTSTATUS (* Query) (PVOID,ULONG,PULONG);
1055 NTSTATUS (* Set) (PVOID,ULONG);
1062 // XX unknown behaviour
1064 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1065 #define SI_QX(n) {QSI_USE(n),NULL}
1066 #define SI_XS(n) {NULL,SSI_USE(n)}
1067 #define SI_XX(n) {NULL,NULL}
1073 SI_QX(SystemBasicInformation),
1074 SI_QX(SystemProcessorInformation),
1075 SI_QX(SystemPerformanceInformation),
1076 SI_QX(SystemTimeOfDayInformation),
1077 SI_QX(SystemPathInformation), /* should be SI_XX */
1078 SI_QX(SystemProcessInformation),
1079 SI_QX(SystemCallCountInformation),
1080 SI_QX(SystemDeviceInformation),
1081 SI_QX(SystemProcessorPerformanceInformation),
1082 SI_QS(SystemFlagsInformation),
1083 SI_QX(SystemCallTimeInformation), /* should be SI_XX */
1084 SI_QX(SystemModuleInformation),
1085 SI_QX(SystemLocksInformation),
1086 SI_QX(SystemStackTraceInformation), /* should be SI_XX */
1087 SI_QX(SystemPagedPoolInformation), /* should be SI_XX */
1088 SI_QX(SystemNonPagedPoolInformation), /* should be SI_XX */
1089 SI_QX(SystemHandleInformation),
1090 SI_QX(SystemObjectInformation),
1091 SI_QX(SystemPageFileInformation),
1092 SI_QX(SystemVdmInstemulInformation),
1093 SI_QX(SystemVdmBopInformation), /* it should be SI_XX */
1094 SI_QS(SystemFileCacheInformation),
1095 SI_QX(SystemPoolTagInformation),
1096 SI_QX(SystemInterruptInformation),
1097 SI_QS(SystemDpcBehaviourInformation),
1098 SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */
1099 SI_XS(SystemLoadImage),
1100 SI_XS(SystemUnloadImage),
1101 SI_QS(SystemTimeAdjustmentInformation),
1102 SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */
1103 SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */
1104 SI_QX(SystemEventIdsInformation), /* it should be SI_XX */
1105 SI_QX(SystemCrashDumpInformation),
1106 SI_QX(SystemExceptionInformation),
1107 SI_QX(SystemCrashDumpStateInformation),
1108 SI_QX(SystemKernelDebuggerInformation),
1109 SI_QX(SystemContextSwitchInformation),
1110 SI_QS(SystemRegistryQuotaInformation),
1111 SI_XS(SystemLoadAndCallImage),
1112 SI_XS(SystemPrioritySeperation),
1113 SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */
1114 SI_QX(SystemDockInformation), /* it should be SI_XX */
1115 SI_QX(SystemPowerInformation), /* it should be SI_XX */
1116 SI_QX(SystemProcessorSpeedInformation), /* it should be SI_XX */
1117 SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */
1118 SI_QX(SystemLookasideInformation),
1119 SI_XS(SystemSetTimeSlipEvent),
1120 SI_XS(SystemCreateSession),
1121 SI_XS(SystemDeleteSession),
1122 SI_QX(SystemInvalidInfoClass4), /* it should be SI_XX */
1123 SI_QX(SystemRangeStartInformation),
1124 SI_QS(SystemVerifierInformation),
1125 SI_XS(SystemAddVerifier),
1126 SI_QX(SystemSessionProcessesInformation)
1134 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1135 OUT PVOID UnsafeSystemInformation,
1137 OUT PULONG UnsafeResultLength)
1140 PVOID SystemInformation;
1144 /*if (ExGetPreviousMode() == KernelMode)
1146 SystemInformation = UnsafeSystemInformation;
1150 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1151 if (SystemInformation == NULL)
1153 return(STATUS_NO_MEMORY);
1157 /* Clear user buffer. */
1158 RtlZeroMemory(SystemInformation, Length);
1161 * Check the request is valid.
1163 if ((SystemInformationClass >= SystemInformationClassMin) &&
1164 (SystemInformationClass < SystemInformationClassMax))
1166 if (NULL != CallQS [SystemInformationClass].Query)
1169 * Hand the request to a subhandler.
1171 FStatus = CallQS [SystemInformationClass].Query(SystemInformation,
1174 /*if (ExGetPreviousMode() != KernelMode)
1176 Status = MmCopyToCaller(UnsafeSystemInformation,
1179 ExFreePool(SystemInformation);
1180 if (!NT_SUCCESS(Status))
1185 if (UnsafeResultLength != NULL)
1187 /*if (ExGetPreviousMode() == KernelMode)
1189 *UnsafeResultLength = ResultLength;
1193 Status = MmCopyToCaller(UnsafeResultLength,
1196 if (!NT_SUCCESS(Status))
1205 return (STATUS_INVALID_INFO_CLASS);
1211 NtSetSystemInformation (
1212 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1213 IN PVOID SystemInformation,
1214 IN ULONG SystemInformationLength
1218 * If called from user mode, check
1219 * possible unsafe arguments.
1222 if (KernelMode != KeGetPreviousMode())
1226 // SystemInformation,
1236 * Check the request is valid.
1238 if ( (SystemInformationClass >= SystemInformationClassMin)
1239 && (SystemInformationClass < SystemInformationClassMax)
1242 if (NULL != CallQS [SystemInformationClass].Set)
1245 * Hand the request to a subhandler.
1247 return CallQS [SystemInformationClass].Set (
1249 SystemInformationLength
1253 return (STATUS_INVALID_INFO_CLASS);
1259 NtFlushInstructionCache (
1260 IN HANDLE ProcessHandle,
1261 IN PVOID BaseAddress,
1262 IN UINT NumberOfBytesToFlush