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 #include <ddk/ntddk.h>
18 #include <ddk/exfuncs.h>
19 #include <ddk/halfuncs.h>
20 #include <ddk/iofuncs.h>
21 #include <internal/ex.h>
22 #include <internal/ldr.h>
23 #include <internal/safe.h>
24 #include <internal/ps.h>
26 #include <internal/debug.h>
28 extern ULONG NtGlobalFlag; /* FIXME: it should go in a ddk/?.h */
30 /* FUNCTIONS *****************************************************************/
33 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
34 OUT PVOID UnsafeValue,
36 IN OUT PULONG UnsafeReturnLength)
44 UNICODE_STRING WValue;
48 * Copy the name to kernel space if necessary and convert it to ANSI.
50 if (ExGetPreviousMode() != KernelMode)
52 Status = RtlCaptureUnicodeString(&WName, UnsafeName);
53 if (!NT_SUCCESS(Status))
57 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
58 if (!NT_SUCCESS(Status))
65 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
66 if (!NT_SUCCESS(Status))
73 * Create a temporary buffer for the value
75 Value = ExAllocatePool(NonPagedPool, Length);
78 RtlFreeAnsiString(&AName);
79 if (ExGetPreviousMode() != KernelMode)
81 RtlFreeUnicodeString(&WName);
83 return(STATUS_NO_MEMORY);
87 * Get the environment variable
89 Result = HalGetEnvironmentVariable(AName.Buffer, Value, Length);
92 RtlFreeAnsiString(&AName);
93 if (ExGetPreviousMode() != KernelMode)
95 RtlFreeUnicodeString(&WName);
98 return(STATUS_UNSUCCESSFUL);
102 * Convert the result to UNICODE.
104 RtlInitAnsiString(&AValue, Value);
105 Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
106 if (!NT_SUCCESS(Status))
108 RtlFreeAnsiString(&AName);
109 if (ExGetPreviousMode() != KernelMode)
111 RtlFreeUnicodeString(&WName);
116 ReturnLength = WValue.Length;
119 * Copy the result back to the caller.
121 if (ExGetPreviousMode() != KernelMode)
123 Status = MmCopyToCaller(UnsafeValue, WValue.Buffer, ReturnLength);
124 if (!NT_SUCCESS(Status))
126 RtlFreeAnsiString(&AName);
127 if (ExGetPreviousMode() != KernelMode)
129 RtlFreeUnicodeString(&WName);
132 RtlFreeUnicodeString(&WValue);
136 Status = MmCopyToCaller(UnsafeReturnLength, &ReturnLength,
138 if (!NT_SUCCESS(Status))
140 RtlFreeAnsiString(&AName);
141 if (ExGetPreviousMode() != KernelMode)
143 RtlFreeUnicodeString(&WName);
146 RtlFreeUnicodeString(&WValue);
152 memcpy(UnsafeValue, WValue.Buffer, ReturnLength);
153 memcpy(UnsafeReturnLength, &ReturnLength, sizeof(ULONG));
157 * Free temporary buffers.
159 RtlFreeAnsiString(&AName);
160 if (ExGetPreviousMode() != KernelMode)
162 RtlFreeUnicodeString(&WName);
165 RtlFreeUnicodeString(&WValue);
167 return(STATUS_SUCCESS);
172 NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
173 IN PUNICODE_STRING UnsafeValue)
175 UNICODE_STRING WName;
177 UNICODE_STRING WValue;
183 * Check for required privilege.
185 /* FIXME: Not implemented. */
188 * Copy the name to kernel space if necessary and convert it to ANSI.
190 if (ExGetPreviousMode() != KernelMode)
192 Status = RtlCaptureUnicodeString(&WName, UnsafeName);
193 if (!NT_SUCCESS(Status))
197 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
198 if (!NT_SUCCESS(Status))
205 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
206 if (!NT_SUCCESS(Status))
213 * Copy the value to kernel space and convert to ANSI.
215 if (ExGetPreviousMode() != KernelMode)
217 Status = RtlCaptureUnicodeString(&WValue, UnsafeValue);
218 if (!NT_SUCCESS(Status))
220 RtlFreeUnicodeString(&WName);
221 RtlFreeAnsiString(&AName);
224 Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
225 if (!NT_SUCCESS(Status))
227 RtlFreeUnicodeString(&WName);
228 RtlFreeAnsiString(&AName);
229 RtlFreeUnicodeString(&WValue);
235 Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
236 if (!NT_SUCCESS(Status))
238 RtlFreeAnsiString(&AName);
244 * Set the environment variable
246 Result = HalSetEnvironmentVariable(AName.Buffer, AValue.Buffer);
249 * Free everything and return status.
251 RtlFreeAnsiString(&AName);
252 RtlFreeAnsiString(&AValue);
253 if (ExGetPreviousMode() != KernelMode)
255 RtlFreeUnicodeString(&WName);
256 RtlFreeUnicodeString(&WValue);
261 return(STATUS_UNSUCCESSFUL);
263 return(STATUS_SUCCESS);
267 /* --- Query/Set System Information --- */
271 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
272 * so the stack is popped only in one place on x86 platform.
274 #define QSI_USE(n) QSI##n
276 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
278 #define SSI_USE(n) SSI##n
280 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
282 /* Class 0 - Basic Information */
283 QSI_DEF(SystemBasicInformation)
285 PSYSTEM_BASIC_INFORMATION Sbi
286 = (PSYSTEM_BASIC_INFORMATION) Buffer;
288 *ReqSize = sizeof (SYSTEM_BASIC_INFORMATION);
290 * Check user buffer's size
292 if (Size < sizeof (SYSTEM_BASIC_INFORMATION))
294 return (STATUS_INFO_LENGTH_MISMATCH);
298 Sbi->TimerResolution = 0; /* FIXME */
299 Sbi->PageSize = PAGE_SIZE; /* FIXME: it should be PAGE_SIZE */
300 Sbi->NumberOfPhysicalPages = 0; /* FIXME */
301 Sbi->LowestPhysicalPageNumber = 0; /* FIXME */
302 Sbi->HighestPhysicalPageNumber = 0; /* FIXME */
303 Sbi->AllocationGranularity = 65536; /* hard coded on Intel? */
304 Sbi->MinimumUserModeAddress = 0; /* FIXME */
305 Sbi->MaximumUserModeAddress = 0; /* FIXME */
306 Sbi->ActiveProcessorsAffinityMask = 0x00000001; /* FIXME */
307 Sbi->NumberOfProcessors = 1; /* FIXME */
309 return (STATUS_SUCCESS);
312 /* Class 1 - Processor Information */
313 QSI_DEF(SystemProcessorInformation)
315 PSYSTEM_PROCESSOR_INFORMATION Spi
316 = (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
318 *ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION);
320 * Check user buffer's size
322 if (Size < sizeof (SYSTEM_PROCESSOR_INFORMATION))
324 return (STATUS_INFO_LENGTH_MISMATCH);
327 /* FIXME: add CPU type detection code */
328 Spi->ProcessorArchitecture = 0; /* FIXME */
329 Spi->ProcessorLevel = 0; /* FIXME */
330 Spi->ProcessorRevision = 0; /* FIXME */
332 Spi->ProcessorFeatureBits = 0x00000000; /* FIXME */
334 return (STATUS_SUCCESS);
337 /* Class 2 - Performance Information */
338 QSI_DEF(SystemPerformanceInformation)
340 PSYSTEM_PERFORMANCE_INFO Spi
341 = (PSYSTEM_PERFORMANCE_INFO) Buffer;
343 *ReqSize = sizeof (SYSTEM_PERFORMANCE_INFO);
345 * Check user buffer's size
347 if (Size < sizeof (SYSTEM_PERFORMANCE_INFO))
349 return (STATUS_INFO_LENGTH_MISMATCH);
352 Spi->IdleProcessorTime.QuadPart = 0; /* FIXME */
353 Spi->IoReadTransferCount.QuadPart = 0; /* FIXME */
354 Spi->IoWriteTransferCount.QuadPart = 0; /* FIXME */
355 Spi->IoOtherTransferCount.QuadPart = 0; /* FIXME */
356 Spi->IoReadOperationCount = 0; /* FIXME */
357 Spi->IoWriteOperationCount = 0; /* FIXME */
358 Spi->IoOtherOperationCount = 0; /* FIXME */
359 Spi->AvailablePages = 0; /* FIXME */
360 Spi->CommitedPages = 0; /* FIXME */
361 Spi->CommitLimit = 0; /* FIXME */
362 Spi->PeakCommitment = 0; /* FIXME */
363 Spi->PageFaultCount = 0; /* FIXME */
364 Spi->CopyOnWriteCount = 0; /* FIXME */
365 Spi->TransitionCount = 0; /* FIXME */
366 Spi->CacheTransitionCount = 0; /* FIXME */
367 Spi->DemandZeroCount = 0; /* FIXME */
368 Spi->PageReadCount = 0; /* FIXME */
369 Spi->PageReadIoCount = 0; /* FIXME */
370 Spi->CacheReadCount = 0; /* FIXME */
371 Spi->CacheIoCount = 0; /* FIXME */
372 Spi->DirtyPagesWriteCount = 0; /* FIXME */
373 Spi->DirtyWriteIoCount = 0; /* FIXME */
374 Spi->MappedPagesWriteCount = 0; /* FIXME */
375 Spi->MappedWriteIoCount = 0; /* FIXME */
376 Spi->PagedPoolPages = 0; /* FIXME */
377 Spi->NonPagedPoolPages = 0; /* FIXME */
378 Spi->Unknown6 = 0; /* FIXME */
379 Spi->Unknown7 = 0; /* FIXME */
380 Spi->Unknown8 = 0; /* FIXME */
381 Spi->Unknown9 = 0; /* FIXME */
382 Spi->MmTotalSystemFreePtes = 0; /* FIXME */
383 Spi->MmSystemCodepage = 0; /* FIXME */
384 Spi->MmTotalSystemDriverPages = 0; /* FIXME */
385 Spi->MmTotalSystemCodePages = 0; /* FIXME */
386 Spi->Unknown10 = 0; /* FIXME */
387 Spi->Unknown11 = 0; /* FIXME */
388 Spi->Unknown12 = 0; /* FIXME */
389 Spi->MmSystemCachePage = 0; /* FIXME */
390 Spi->MmPagedPoolPage = 0; /* FIXME */
391 Spi->MmSystemDriverPage = 0; /* FIXME */
392 Spi->CcFastReadNoWait = 0; /* FIXME */
393 Spi->CcFastReadWait = 0; /* FIXME */
394 Spi->CcFastReadResourceMiss = 0; /* FIXME */
395 Spi->CcFastReadNotPossible = 0; /* FIXME */
396 Spi->CcFastMdlReadNoWait = 0; /* FIXME */
397 Spi->CcFastMdlReadWait = 0; /* FIXME */
398 Spi->CcFastMdlReadResourceMiss = 0; /* FIXME */
399 Spi->CcFastMdlReadNotPossible = 0; /* FIXME */
400 Spi->CcMapDataNoWait = 0; /* FIXME */
401 Spi->CcMapDataWait = 0; /* FIXME */
402 Spi->CcMapDataNoWaitMiss = 0; /* FIXME */
403 Spi->CcMapDataWaitMiss = 0; /* FIXME */
404 Spi->CcPinMappedDataCount = 0; /* FIXME */
405 Spi->CcPinReadNoWait = 0; /* FIXME */
406 Spi->CcPinReadWait = 0; /* FIXME */
407 Spi->CcPinReadNoWaitMiss = 0; /* FIXME */
408 Spi->CcPinReadWaitMiss = 0; /* FIXME */
409 Spi->CcCopyReadNoWait = 0; /* FIXME */
410 Spi->CcCopyReadWait = 0; /* FIXME */
411 Spi->CcCopyReadNoWaitMiss = 0; /* FIXME */
412 Spi->CcCopyReadWaitMiss = 0; /* FIXME */
413 Spi->CcMdlReadNoWait = 0; /* FIXME */
414 Spi->CcMdlReadWait = 0; /* FIXME */
415 Spi->CcMdlReadNoWaitMiss = 0; /* FIXME */
416 Spi->CcMdlReadWaitMiss = 0; /* FIXME */
417 Spi->CcReadaheadIos = 0; /* FIXME */
418 Spi->CcLazyWriteIos = 0; /* FIXME */
419 Spi->CcLazyWritePages = 0; /* FIXME */
420 Spi->CcDataFlushes = 0; /* FIXME */
421 Spi->CcDataPages = 0; /* FIXME */
422 Spi->ContextSwitches = 0; /* FIXME */
423 Spi->Unknown13 = 0; /* FIXME */
424 Spi->Unknown14 = 0; /* FIXME */
425 Spi->SystemCalls = 0; /* FIXME */
427 return (STATUS_SUCCESS);
430 /* Class 3 - Time Of Day Information */
431 QSI_DEF(SystemTimeOfDayInformation)
433 PSYSTEM_TIMEOFDAY_INFORMATION Sti
434 = (PSYSTEM_TIMEOFDAY_INFORMATION) Buffer;
436 *ReqSize = sizeof (SYSTEM_TIMEOFDAY_INFORMATION);
438 * Check user buffer's size
440 if (Size < sizeof (SYSTEM_TIMEOFDAY_INFORMATION))
442 return (STATUS_INFO_LENGTH_MISMATCH);
445 Sti->BootTime.QuadPart = 0; /* FIXME */
446 Sti->CurrentTime.QuadPart = 0; /* FIXME */
447 Sti->TimeZoneBias.QuadPart = 0; /* FIXME */
448 Sti->TimeZoneId = 0; /* FIXME */
449 Sti->Reserved = 0; /* FIXME */
451 return (STATUS_SUCCESS);
454 /* Class 4 - Path Information */
455 QSI_DEF(SystemPathInformation)
457 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
458 return (STATUS_BREAKPOINT);
461 /* Class 5 - Process Information */
462 QSI_DEF(SystemProcessInformation)
464 ULONG ovlSize=0, nThreads=1;
468 /* scan the process list */
469 // TODO: Add thread information
471 PSYSTEM_PROCESSES Spi
472 = (PSYSTEM_PROCESSES) Buffer;
474 *ReqSize = sizeof(SYSTEM_PROCESSES);
476 if (Size < sizeof(SYSTEM_PROCESSES))
478 return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
481 syspr = PsGetNextProcess(NULL);
483 pCur = (unsigned char *)Spi;
487 PSYSTEM_PROCESSES SpiCur;
490 int inLen=32; // image name len in bytes
493 SpiCur = (PSYSTEM_PROCESSES)pCur;
495 nThreads = 1; // FIXME
497 // size of the structure for every process
498 curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*nThreads;
499 ovlSize += curSize+inLen;
505 return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
508 // fill system information
509 SpiCur->NextEntryDelta = curSize+inLen; // relative offset to the beginnnig of the next structure
510 SpiCur->ThreadCount = nThreads;
511 SpiCur->CreateTime = pr->CreateTime;
512 //SpiCur->UserTime = 0; // FIXME
513 //SpiCur->KernelTime = 0; // FIXME
515 SpiCur->ProcessName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
516 SpiCur->ProcessName.MaximumLength = inLen;
517 SpiCur->ProcessName.Buffer = (void*)(pCur+curSize);
519 // copy name to the end of the struct
520 RtlInitAnsiString(&imgName, pr->ImageFileName);
521 RtlAnsiStringToUnicodeString(&SpiCur->ProcessName, &imgName, FALSE);
523 SpiCur->BasePriority = 0; // FIXME
524 SpiCur->ProcessId = pr->UniqueProcessId;
525 SpiCur->InheritedFromProcessId = 0; // FIXME
526 SpiCur->HandleCount = 0; // FIXME
527 SpiCur->VmCounters.PeakVirtualSize = pr->PeakVirtualSize;
528 SpiCur->VmCounters.VirtualSize = 0; // FIXME
529 SpiCur->VmCounters.PageFaultCount = pr->LastFaultCount;
530 SpiCur->VmCounters.PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ?
531 SpiCur->VmCounters.WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ?
532 SpiCur->VmCounters.QuotaPeakPagedPoolUsage = 0; // FIXME
533 SpiCur->VmCounters.QuotaPagedPoolUsage = 0; // FIXME
534 SpiCur->VmCounters.QuotaPeakNonPagedPoolUsage = 0; // FIXME
535 SpiCur->VmCounters.QuotaNonPagedPoolUsage = 0; // FIXME
536 SpiCur->VmCounters.PagefileUsage = 0; // FIXME
537 SpiCur->VmCounters.PeakPagefileUsage = pr->PeakPagefileUsage;
538 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
539 // doesn't seem to contain any equivalent field
540 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
542 pr = PsGetNextProcess(pr);
544 if ((pr == syspr) || (pr == NULL))
546 SpiCur->NextEntryDelta = 0;
550 pCur = pCur + curSize + inLen;
551 } while ((pr != syspr) && (pr != NULL));
555 return (STATUS_SUCCESS);
558 /* Class 6 - Call Count Information */
559 QSI_DEF(SystemCallCountInformation)
562 return (STATUS_NOT_IMPLEMENTED);
565 /* Class 7 - Device Information */
566 QSI_DEF(SystemDeviceInformation)
568 PSYSTEM_DEVICE_INFORMATION Sdi
569 = (PSYSTEM_DEVICE_INFORMATION) Buffer;
570 PCONFIGURATION_INFORMATION ConfigInfo;
572 *ReqSize = sizeof (SYSTEM_DEVICE_INFORMATION);
574 * Check user buffer's size
576 if (Size < sizeof (SYSTEM_DEVICE_INFORMATION))
578 return (STATUS_INFO_LENGTH_MISMATCH);
581 ConfigInfo = IoGetConfigurationInformation ();
583 Sdi->NumberOfDisks = ConfigInfo->DiskCount;
584 Sdi->NumberOfFloppies = ConfigInfo->FloppyCount;
585 Sdi->NumberOfCdRoms = ConfigInfo->CDRomCount;
586 Sdi->NumberOfTapes = ConfigInfo->TapeCount;
587 Sdi->NumberOfSerialPorts = ConfigInfo->SerialCount;
588 Sdi->NumberOfParallelPorts = ConfigInfo->ParallelCount;
590 return (STATUS_SUCCESS);
593 /* Class 8 - Processor Performance Information */
594 QSI_DEF(SystemProcessorPerformanceInformation)
597 return (STATUS_NOT_IMPLEMENTED);
600 /* Class 9 - Flags Information */
601 QSI_DEF(SystemFlagsInformation)
603 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
605 * ReqSize = sizeof (SYSTEM_FLAGS_INFORMATION);
606 return (STATUS_INFO_LENGTH_MISMATCH);
608 ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag;
609 return (STATUS_SUCCESS);
612 SSI_DEF(SystemFlagsInformation)
614 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
616 return (STATUS_INFO_LENGTH_MISMATCH);
618 NtGlobalFlag = ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags;
619 return (STATUS_SUCCESS);
622 /* Class 10 - Call Time Information */
623 QSI_DEF(SystemCallTimeInformation)
626 return (STATUS_NOT_IMPLEMENTED);
629 /* Class 11 - Module Information */
630 QSI_DEF(SystemModuleInformation)
632 return LdrpQueryModuleInformation(Buffer, Size, ReqSize);
635 /* Class 12 - Locks Information */
636 QSI_DEF(SystemLocksInformation)
639 return (STATUS_NOT_IMPLEMENTED);
642 /* Class 13 - Stack Trace Information */
643 QSI_DEF(SystemStackTraceInformation)
646 return (STATUS_NOT_IMPLEMENTED);
649 /* Class 14 - Paged Pool Information */
650 QSI_DEF(SystemPagedPoolInformation)
653 return (STATUS_NOT_IMPLEMENTED);
656 /* Class 15 - Non Paged Pool Information */
657 QSI_DEF(SystemNonPagedPoolInformation)
660 return (STATUS_NOT_IMPLEMENTED);
663 /* Class 16 - Handle Information */
664 QSI_DEF(SystemHandleInformation)
667 return (STATUS_NOT_IMPLEMENTED);
670 /* Class 17 - Information */
671 QSI_DEF(SystemObjectInformation)
674 return (STATUS_NOT_IMPLEMENTED);
677 /* Class 18 - Information */
678 QSI_DEF(SystemPageFileInformation)
681 return (STATUS_NOT_IMPLEMENTED);
684 /* Class 19 - Vdm Instemul Information */
685 QSI_DEF(SystemVdmInstemulInformation)
688 return (STATUS_NOT_IMPLEMENTED);
691 /* Class 20 - Vdm Bop Information */
692 QSI_DEF(SystemVdmBopInformation)
695 return (STATUS_NOT_IMPLEMENTED);
698 /* Class 21 - File Cache Information */
699 QSI_DEF(SystemFileCacheInformation)
701 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
703 * ReqSize = sizeof (SYSTEM_CACHE_INFORMATION);
704 return (STATUS_INFO_LENGTH_MISMATCH);
707 return (STATUS_NOT_IMPLEMENTED);
710 SSI_DEF(SystemFileCacheInformation)
712 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
714 return (STATUS_INFO_LENGTH_MISMATCH);
717 return (STATUS_NOT_IMPLEMENTED);
720 /* Class 22 - Pool Tag Information */
721 QSI_DEF(SystemPoolTagInformation)
724 return (STATUS_NOT_IMPLEMENTED);
727 /* Class 23 - Interrupt Information */
728 QSI_DEF(SystemInterruptInformation)
731 return (STATUS_NOT_IMPLEMENTED);
734 /* Class 24 - DPC Behaviour Information */
735 QSI_DEF(SystemDpcBehaviourInformation)
738 return (STATUS_NOT_IMPLEMENTED);
741 SSI_DEF(SystemDpcBehaviourInformation)
744 return (STATUS_NOT_IMPLEMENTED);
747 /* Class 25 - Full Memory Information */
748 QSI_DEF(SystemFullMemoryInformation)
751 return (STATUS_NOT_IMPLEMENTED);
754 /* Class 26 - Load Image */
755 SSI_DEF(SystemLoadImage)
757 PSYSTEM_LOAD_IMAGE Sli = (PSYSTEM_LOAD_IMAGE)Buffer;
759 if (sizeof(SYSTEM_LOAD_IMAGE) != Size)
761 return(STATUS_INFO_LENGTH_MISMATCH);
764 return(LdrpLoadImage(&Sli->ModuleName,
766 &Sli->SectionPointer,
768 &Sli->ExportDirectory));
771 /* Class 27 - Unload Image */
772 SSI_DEF(SystemUnloadImage)
774 PSYSTEM_UNLOAD_IMAGE Sui = (PSYSTEM_UNLOAD_IMAGE)Buffer;
776 if (sizeof(SYSTEM_UNLOAD_IMAGE) != Size)
778 return(STATUS_INFO_LENGTH_MISMATCH);
781 return(LdrpUnloadImage(Sui->ModuleBase));
784 /* Class 28 - Time Adjustment Information */
785 QSI_DEF(SystemTimeAdjustmentInformation)
787 if (sizeof (SYSTEM_TIME_ADJUSTMENT_INFO) > Size)
789 * ReqSize = sizeof (SYSTEM_TIME_ADJUSTMENT_INFO);
790 return (STATUS_INFO_LENGTH_MISMATCH);
793 return (STATUS_NOT_IMPLEMENTED);
796 SSI_DEF(SystemTimeAdjustmentInformation)
798 if (sizeof (SYSTEM_TIME_ADJUSTMENT_INFO) > Size)
800 return (STATUS_INFO_LENGTH_MISMATCH);
803 return (STATUS_NOT_IMPLEMENTED);
806 /* Class 29 - Summary Memory Information */
807 QSI_DEF(SystemSummaryMemoryInformation)
810 return (STATUS_NOT_IMPLEMENTED);
813 /* Class 30 - Next Event Id Information */
814 QSI_DEF(SystemNextEventIdInformation)
817 return (STATUS_NOT_IMPLEMENTED);
820 /* Class 31 - Event Ids Information */
821 QSI_DEF(SystemEventIdsInformation)
824 return (STATUS_NOT_IMPLEMENTED);
827 /* Class 32 - Crach Dump Information */
828 QSI_DEF(SystemCrashDumpInformation)
831 return (STATUS_NOT_IMPLEMENTED);
834 /* Class 33 - Exception Information */
835 QSI_DEF(SystemExceptionInformation)
838 return (STATUS_NOT_IMPLEMENTED);
841 /* Class 34 - Crach Dump State Information */
842 QSI_DEF(SystemCrashDumpStateInformation)
845 return (STATUS_NOT_IMPLEMENTED);
848 /* Class 35 - Kernel Debugger Information */
849 QSI_DEF(SystemKernelDebuggerInformation)
852 return (STATUS_NOT_IMPLEMENTED);
855 /* Class 36 - Context Switch Information */
856 QSI_DEF(SystemContextSwitchInformation)
859 return (STATUS_NOT_IMPLEMENTED);
862 /* Class 37 - Registry Quota Information */
863 QSI_DEF(SystemRegistryQuotaInformation)
866 return (STATUS_NOT_IMPLEMENTED);
869 SSI_DEF(SystemRegistryQuotaInformation)
872 return (STATUS_NOT_IMPLEMENTED);
875 /* Class 38 - Load And Call Image */
876 SSI_DEF(SystemLoadAndCallImage)
878 PSYSTEM_LOAD_AND_CALL_IMAGE Slci = (PSYSTEM_LOAD_AND_CALL_IMAGE)Buffer;
880 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE) != Size)
882 return(STATUS_INFO_LENGTH_MISMATCH);
885 return(LdrpLoadAndCallImage(&Slci->ModuleName));
888 /* Class 39 - Priority Seperation */
889 SSI_DEF(SystemPrioritySeperation)
892 return (STATUS_NOT_IMPLEMENTED);
895 /* Class 40 - Plug Play Bus Information */
896 QSI_DEF(SystemPlugPlayBusInformation)
899 return (STATUS_NOT_IMPLEMENTED);
902 /* Class 41 - Dock Information */
903 QSI_DEF(SystemDockInformation)
906 return (STATUS_NOT_IMPLEMENTED);
909 /* Class 42 - Power Information */
910 QSI_DEF(SystemPowerInformation)
913 return (STATUS_NOT_IMPLEMENTED);
916 /* Class 43 - Processor Speed Information */
917 QSI_DEF(SystemProcessorSpeedInformation)
920 return (STATUS_NOT_IMPLEMENTED);
923 /* Class 44 - Current Time Zone Information */
924 QSI_DEF(SystemCurrentTimeZoneInformation)
926 * ReqSize = sizeof (TIME_ZONE_INFORMATION);
928 if (sizeof (TIME_ZONE_INFORMATION) != Size)
930 return (STATUS_INFO_LENGTH_MISMATCH);
932 /* Copy the time zone information struct */
935 & SystemTimeZoneInfo,
936 sizeof (TIME_ZONE_INFORMATION)
939 return (STATUS_SUCCESS);
943 SSI_DEF(SystemCurrentTimeZoneInformation)
946 * Check user buffer's size
948 if (Size < sizeof (TIME_ZONE_INFORMATION))
950 return (STATUS_INFO_LENGTH_MISMATCH);
952 /* Copy the time zone information struct */
954 & SystemTimeZoneInfo,
955 (TIME_ZONE_INFORMATION *) Buffer,
956 sizeof (TIME_ZONE_INFORMATION)
958 return (STATUS_SUCCESS);
962 /* Class 45 - Lookaside Information */
963 QSI_DEF(SystemLookasideInformation)
966 return (STATUS_NOT_IMPLEMENTED);
970 /* Class 46 - Set time slip event */
971 SSI_DEF(SystemSetTimeSlipEvent)
974 return (STATUS_NOT_IMPLEMENTED);
978 /* Class 47 - Create a new session (TSE) */
979 SSI_DEF(SystemCreateSession)
982 return (STATUS_NOT_IMPLEMENTED);
986 /* Class 48 - Delete an existing session (TSE) */
987 SSI_DEF(SystemDeleteSession)
990 return (STATUS_NOT_IMPLEMENTED);
994 /* Class 49 - UNKNOWN */
995 QSI_DEF(SystemInvalidInfoClass4)
998 return (STATUS_NOT_IMPLEMENTED);
1002 /* Class 50 - System range start address */
1003 QSI_DEF(SystemRangeStartInformation)
1006 return (STATUS_NOT_IMPLEMENTED);
1010 /* Class 51 - Driver verifier information */
1011 QSI_DEF(SystemVerifierInformation)
1014 return (STATUS_NOT_IMPLEMENTED);
1018 SSI_DEF(SystemVerifierInformation)
1021 return (STATUS_NOT_IMPLEMENTED);
1025 /* Class 52 - Add a driver verifier */
1026 SSI_DEF(SystemAddVerifier)
1029 return (STATUS_NOT_IMPLEMENTED);
1033 /* Class 53 - A session's processes */
1034 QSI_DEF(SystemSessionProcessesInformation)
1037 return (STATUS_NOT_IMPLEMENTED);
1041 /* Query/Set Calls Table */
1045 NTSTATUS (* Query) (PVOID,ULONG,PULONG);
1046 NTSTATUS (* Set) (PVOID,ULONG);
1053 // XX unknown behaviour
1055 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1056 #define SI_QX(n) {QSI_USE(n),NULL}
1057 #define SI_XS(n) {NULL,SSI_USE(n)}
1058 #define SI_XX(n) {NULL,NULL}
1064 SI_QX(SystemBasicInformation),
1065 SI_QX(SystemProcessorInformation),
1066 SI_QX(SystemPerformanceInformation),
1067 SI_QX(SystemTimeOfDayInformation),
1068 SI_QX(SystemPathInformation), /* should be SI_XX */
1069 SI_QX(SystemProcessInformation),
1070 SI_QX(SystemCallCountInformation),
1071 SI_QX(SystemDeviceInformation),
1072 SI_QX(SystemProcessorPerformanceInformation),
1073 SI_QS(SystemFlagsInformation),
1074 SI_QX(SystemCallTimeInformation), /* should be SI_XX */
1075 SI_QX(SystemModuleInformation),
1076 SI_QX(SystemLocksInformation),
1077 SI_QX(SystemStackTraceInformation), /* should be SI_XX */
1078 SI_QX(SystemPagedPoolInformation), /* should be SI_XX */
1079 SI_QX(SystemNonPagedPoolInformation), /* should be SI_XX */
1080 SI_QX(SystemHandleInformation),
1081 SI_QX(SystemObjectInformation),
1082 SI_QX(SystemPageFileInformation),
1083 SI_QX(SystemVdmInstemulInformation),
1084 SI_QX(SystemVdmBopInformation), /* it should be SI_XX */
1085 SI_QS(SystemFileCacheInformation),
1086 SI_QX(SystemPoolTagInformation),
1087 SI_QX(SystemInterruptInformation),
1088 SI_QS(SystemDpcBehaviourInformation),
1089 SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */
1090 SI_XS(SystemLoadImage),
1091 SI_XS(SystemUnloadImage),
1092 SI_QS(SystemTimeAdjustmentInformation),
1093 SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */
1094 SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */
1095 SI_QX(SystemEventIdsInformation), /* it should be SI_XX */
1096 SI_QX(SystemCrashDumpInformation),
1097 SI_QX(SystemExceptionInformation),
1098 SI_QX(SystemCrashDumpStateInformation),
1099 SI_QX(SystemKernelDebuggerInformation),
1100 SI_QX(SystemContextSwitchInformation),
1101 SI_QS(SystemRegistryQuotaInformation),
1102 SI_XS(SystemLoadAndCallImage),
1103 SI_XS(SystemPrioritySeperation),
1104 SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */
1105 SI_QX(SystemDockInformation), /* it should be SI_XX */
1106 SI_QX(SystemPowerInformation), /* it should be SI_XX */
1107 SI_QX(SystemProcessorSpeedInformation), /* it should be SI_XX */
1108 SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */
1109 SI_QX(SystemLookasideInformation),
1110 SI_XS(SystemSetTimeSlipEvent),
1111 SI_XS(SystemCreateSession),
1112 SI_XS(SystemDeleteSession),
1113 SI_QX(SystemInvalidInfoClass4), /* it should be SI_XX */
1114 SI_QX(SystemRangeStartInformation),
1115 SI_QS(SystemVerifierInformation),
1116 SI_XS(SystemAddVerifier),
1117 SI_QX(SystemSessionProcessesInformation)
1122 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1123 OUT PVOID UnsafeSystemInformation,
1125 OUT PULONG UnsafeResultLength)
1128 PVOID SystemInformation;
1132 /*if (ExGetPreviousMode() == KernelMode)
1134 SystemInformation = UnsafeSystemInformation;
1138 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1139 if (SystemInformation == NULL)
1141 return(STATUS_NO_MEMORY);
1145 /* Clear user buffer. */
1146 RtlZeroMemory(SystemInformation, Length);
1149 * Check the request is valid.
1151 if ((SystemInformationClass >= SystemInformationClassMin) &&
1152 (SystemInformationClass < SystemInformationClassMax))
1154 if (NULL != CallQS [SystemInformationClass].Query)
1157 * Hand the request to a subhandler.
1159 FStatus = CallQS [SystemInformationClass].Query(SystemInformation,
1162 /*if (ExGetPreviousMode() != KernelMode)
1164 Status = MmCopyToCaller(UnsafeSystemInformation,
1167 ExFreePool(SystemInformation);
1168 if (!NT_SUCCESS(Status))
1173 if (UnsafeResultLength != NULL)
1175 /*if (ExGetPreviousMode() == KernelMode)
1177 *UnsafeResultLength = ResultLength;
1181 Status = MmCopyToCaller(UnsafeResultLength,
1184 if (!NT_SUCCESS(Status))
1193 return (STATUS_INVALID_INFO_CLASS);
1199 NtSetSystemInformation (
1200 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1201 IN PVOID SystemInformation,
1202 IN ULONG SystemInformationLength
1206 * If called from user mode, check
1207 * possible unsafe arguments.
1210 if (KernelMode != KeGetPreviousMode())
1214 // SystemInformation,
1224 * Check the request is valid.
1226 if ( (SystemInformationClass >= SystemInformationClassMin)
1227 && (SystemInformationClass < SystemInformationClassMax)
1230 if (NULL != CallQS [SystemInformationClass].Set)
1233 * Hand the request to a subhandler.
1235 return CallQS [SystemInformationClass].Set (
1237 SystemInformationLength
1241 return (STATUS_INVALID_INFO_CLASS);
1247 NtFlushInstructionCache (
1248 IN HANDLE ProcessHandle,
1249 IN PVOID BaseAddress,
1250 IN UINT NumberOfBytesToFlush