1 /* $Id: sysinfo.c,v 1.20 2003/03/29 12:55:48 chorns 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 #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