Fix up SystemPageFileInfo and SystemCacheInfo. May not have all the right data.
[reactos.git] / reactos / ntoskrnl / ex / sysinfo.c
1 /* $Id: sysinfo.c,v 1.42 2004/07/31 00:14:39 jimtabor Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 * 20/03/2003: implemented querying SystemProcessInformation,
11 * no more copying to-from the caller (Aleksey
12 * Bragin <aleksey@studiocerebral.com>)
13 */
14
15 /* INCLUDES *****************************************************************/
16
17 #define NTOS_MODE_KERNEL
18 #include <ntos.h>
19 #include <ddk/halfuncs.h>
20 #include <internal/ex.h>
21 #include <internal/io.h>
22 #include <internal/ldr.h>
23 #include <internal/safe.h>
24 #include <internal/ps.h>
25 #include <internal/mm.h>
26
27 #define NDEBUG
28 #include <internal/debug.h>
29
30 extern ULONG NtGlobalFlag; /* FIXME: it should go in a ddk/?.h */
31 ULONGLONG STDCALL KeQueryInterruptTime(VOID);
32
33 VOID MmPrintMemoryStatistic(VOID);
34
35 extern ULONG Ke386CpuidFlags;
36 extern ULONG Ke386Cpuid;
37
38 /* FUNCTIONS *****************************************************************/
39
40 /*
41 * @unimplemented
42 */
43 VOID
44 STDCALL
45 ExEnumHandleTable (
46 PULONG HandleTable,
47 PVOID Callback,
48 PVOID Param,
49 PHANDLE Handle OPTIONAL
50 )
51 {
52 UNIMPLEMENTED;
53 }
54
55 /*
56 * @unimplemented
57 */
58 VOID
59 STDCALL
60 ExGetCurrentProcessorCounts (
61 PVOID IdleThreadTime,
62 PVOID SystemTime,
63 PVOID Number
64 )
65 {
66 UNIMPLEMENTED;
67 }
68 /*
69 * @unimplemented
70 */
71 VOID
72 STDCALL
73 ExGetCurrentProcessorCpuUsage (
74 PVOID RetVal
75 )
76 {
77 UNIMPLEMENTED;
78 }
79
80 NTSTATUS STDCALL
81 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
82 OUT PVOID UnsafeValue,
83 IN ULONG Length,
84 IN OUT PULONG UnsafeReturnLength)
85 {
86 NTSTATUS Status;
87 ANSI_STRING AName;
88 UNICODE_STRING WName;
89 BOOLEAN Result;
90 PCH Value;
91 ANSI_STRING AValue;
92 UNICODE_STRING WValue;
93 ULONG ReturnLength;
94
95 /*
96 * Copy the name to kernel space if necessary and convert it to ANSI.
97 */
98 if (ExGetPreviousMode() != KernelMode)
99 {
100 Status = RtlCaptureUnicodeString(&WName, UnsafeName);
101 if (!NT_SUCCESS(Status))
102 {
103 return(Status);
104 }
105 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
106 if (!NT_SUCCESS(Status))
107 {
108 return(Status);
109 }
110 }
111 else
112 {
113 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
114 if (!NT_SUCCESS(Status))
115 {
116 return(Status);
117 }
118 }
119
120 /*
121 * Create a temporary buffer for the value
122 */
123 Value = ExAllocatePool(NonPagedPool, Length);
124 if (Value == NULL)
125 {
126 RtlFreeAnsiString(&AName);
127 if (ExGetPreviousMode() != KernelMode)
128 {
129 RtlFreeUnicodeString(&WName);
130 }
131 return(STATUS_NO_MEMORY);
132 }
133
134 /*
135 * Get the environment variable
136 */
137 Result = HalGetEnvironmentVariable(AName.Buffer, Value, Length);
138 if (!Result)
139 {
140 RtlFreeAnsiString(&AName);
141 if (ExGetPreviousMode() != KernelMode)
142 {
143 RtlFreeUnicodeString(&WName);
144 }
145 ExFreePool(Value);
146 return(STATUS_UNSUCCESSFUL);
147 }
148
149 /*
150 * Convert the result to UNICODE.
151 */
152 RtlInitAnsiString(&AValue, Value);
153 Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
154 if (!NT_SUCCESS(Status))
155 {
156 RtlFreeAnsiString(&AName);
157 if (ExGetPreviousMode() != KernelMode)
158 {
159 RtlFreeUnicodeString(&WName);
160 }
161 ExFreePool(Value);
162 return(Status);
163 }
164 ReturnLength = WValue.Length;
165
166 /*
167 * Copy the result back to the caller.
168 */
169 if (ExGetPreviousMode() != KernelMode)
170 {
171 Status = MmCopyToCaller(UnsafeValue, WValue.Buffer, ReturnLength);
172 if (!NT_SUCCESS(Status))
173 {
174 RtlFreeAnsiString(&AName);
175 if (ExGetPreviousMode() != KernelMode)
176 {
177 RtlFreeUnicodeString(&WName);
178 }
179 ExFreePool(Value);
180 RtlFreeUnicodeString(&WValue);
181 return(Status);
182 }
183
184 Status = MmCopyToCaller(UnsafeReturnLength, &ReturnLength,
185 sizeof(ULONG));
186 if (!NT_SUCCESS(Status))
187 {
188 RtlFreeAnsiString(&AName);
189 if (ExGetPreviousMode() != KernelMode)
190 {
191 RtlFreeUnicodeString(&WName);
192 }
193 ExFreePool(Value);
194 RtlFreeUnicodeString(&WValue);
195 return(Status);
196 }
197 }
198 else
199 {
200 memcpy(UnsafeValue, WValue.Buffer, ReturnLength);
201 memcpy(UnsafeReturnLength, &ReturnLength, sizeof(ULONG));
202 }
203
204 /*
205 * Free temporary buffers.
206 */
207 RtlFreeAnsiString(&AName);
208 if (ExGetPreviousMode() != KernelMode)
209 {
210 RtlFreeUnicodeString(&WName);
211 }
212 ExFreePool(Value);
213 RtlFreeUnicodeString(&WValue);
214
215 return(STATUS_SUCCESS);
216 }
217
218
219 NTSTATUS STDCALL
220 NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
221 IN PUNICODE_STRING UnsafeValue)
222 {
223 UNICODE_STRING WName;
224 ANSI_STRING AName;
225 UNICODE_STRING WValue;
226 ANSI_STRING AValue;
227 BOOLEAN Result;
228 NTSTATUS Status;
229
230 /*
231 * Check for required privilege.
232 */
233 /* FIXME: Not implemented. */
234
235 /*
236 * Copy the name to kernel space if necessary and convert it to ANSI.
237 */
238 if (ExGetPreviousMode() != KernelMode)
239 {
240 Status = RtlCaptureUnicodeString(&WName, UnsafeName);
241 if (!NT_SUCCESS(Status))
242 {
243 return(Status);
244 }
245 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
246 if (!NT_SUCCESS(Status))
247 {
248 return(Status);
249 }
250 }
251 else
252 {
253 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
254 if (!NT_SUCCESS(Status))
255 {
256 return(Status);
257 }
258 }
259
260 /*
261 * Copy the value to kernel space and convert to ANSI.
262 */
263 if (ExGetPreviousMode() != KernelMode)
264 {
265 Status = RtlCaptureUnicodeString(&WValue, UnsafeValue);
266 if (!NT_SUCCESS(Status))
267 {
268 RtlFreeUnicodeString(&WName);
269 RtlFreeAnsiString(&AName);
270 return(Status);
271 }
272 Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
273 if (!NT_SUCCESS(Status))
274 {
275 RtlFreeUnicodeString(&WName);
276 RtlFreeAnsiString(&AName);
277 RtlFreeUnicodeString(&WValue);
278 return(Status);
279 }
280 }
281 else
282 {
283 Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
284 if (!NT_SUCCESS(Status))
285 {
286 RtlFreeAnsiString(&AName);
287 return(Status);
288 }
289 }
290
291 /*
292 * Set the environment variable
293 */
294 Result = HalSetEnvironmentVariable(AName.Buffer, AValue.Buffer);
295
296 /*
297 * Free everything and return status.
298 */
299 RtlFreeAnsiString(&AName);
300 RtlFreeAnsiString(&AValue);
301 if (ExGetPreviousMode() != KernelMode)
302 {
303 RtlFreeUnicodeString(&WName);
304 RtlFreeUnicodeString(&WValue);
305 }
306
307 if (!Result)
308 {
309 return(STATUS_UNSUCCESSFUL);
310 }
311 return(STATUS_SUCCESS);
312 }
313
314
315 /* --- Query/Set System Information --- */
316
317 /*
318 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
319 * so the stack is popped only in one place on x86 platform.
320 */
321 #define QSI_USE(n) QSI##n
322 #define QSI_DEF(n) \
323 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
324
325 #define SSI_USE(n) SSI##n
326 #define SSI_DEF(n) \
327 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
328
329
330 /* Class 0 - Basic Information */
331 QSI_DEF(SystemBasicInformation)
332 {
333 PSYSTEM_BASIC_INFORMATION Sbi
334 = (PSYSTEM_BASIC_INFORMATION) Buffer;
335
336 *ReqSize = sizeof (SYSTEM_BASIC_INFORMATION);
337 /*
338 * Check user buffer's size
339 */
340 if (Size < sizeof (SYSTEM_BASIC_INFORMATION))
341 {
342 return (STATUS_INFO_LENGTH_MISMATCH);
343 }
344 Sbi->Unknown = 0;
345 Sbi->MaximumIncrement = 100000; /* FIXME */
346 Sbi->PhysicalPageSize = PAGE_SIZE; /* FIXME: it should be PAGE_SIZE */
347 Sbi->NumberOfPhysicalPages = MmStats.NrTotalPages;
348 Sbi->LowestPhysicalPage = 0; /* FIXME */
349 Sbi->HighestPhysicalPage = MmStats.NrTotalPages; /* FIXME */
350 Sbi->AllocationGranularity = 65536; /* hard coded on Intel? */
351 Sbi->LowestUserAddress = 0x10000; /* Top of 64k */
352 Sbi->HighestUserAddress = 0x7ffeffff; /* From mm/mminit.c */
353 Sbi->ActiveProcessors = 0x00000001; /* FIXME */
354 Sbi->NumberProcessors = KeNumberProcessors;
355 return (STATUS_SUCCESS);
356 }
357
358 /* Class 1 - Processor Information */
359 QSI_DEF(SystemProcessorInformation)
360 {
361 PSYSTEM_PROCESSOR_INFORMATION Spi
362 = (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
363
364 *ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION);
365 /*
366 * Check user buffer's size
367 */
368 if (Size < sizeof (SYSTEM_PROCESSOR_INFORMATION))
369 {
370 return (STATUS_INFO_LENGTH_MISMATCH);
371 }
372 Spi->ProcessorArchitecture = 0; /* Intel Processor */
373 Spi->ProcessorLevel = ((Ke386Cpuid >> 8) & 0xf);
374 Spi->ProcessorRevision = (Ke386Cpuid & 0xf) | ((Ke386Cpuid << 4) & 0xf00);
375 Spi->Unknown = 0;
376 Spi->FeatureBits = Ke386CpuidFlags;
377
378 DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture,
379 Spi->ProcessorLevel, Spi->ProcessorRevision);
380
381 return (STATUS_SUCCESS);
382 }
383
384 /* Class 2 - Performance Information */
385 QSI_DEF(SystemPerformanceInformation)
386 {
387 PSYSTEM_PERFORMANCE_INFORMATION Spi
388 = (PSYSTEM_PERFORMANCE_INFORMATION) Buffer;
389
390 PEPROCESS TheIdleProcess;
391
392 *ReqSize = sizeof (SYSTEM_PERFORMANCE_INFORMATION);
393 /*
394 * Check user buffer's size
395 */
396 if (Size < sizeof (SYSTEM_PERFORMANCE_INFORMATION))
397 {
398 return (STATUS_INFO_LENGTH_MISMATCH);
399 }
400
401 PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
402
403 Spi->IdleTime.QuadPart = TheIdleProcess->Pcb.KernelTime * 100000LL;
404
405 Spi->ReadTransferCount.QuadPart = IoReadTransferCount;
406 Spi->WriteTransferCount.QuadPart = IoWriteTransferCount;
407 Spi->OtherTransferCount.QuadPart = IoOtherTransferCount;
408 Spi->ReadOperationCount = IoReadOperationCount;
409 Spi->WriteOperationCount = IoWriteOperationCount;
410 Spi->OtherOperationCount = IoOtherOperationCount;
411
412 Spi->AvailablePages = MiNrAvailablePages;
413 /*
414 Add up all the used "Commitied" memory + pagefile.
415 Not sure this is right. 8^\
416 */
417 Spi->TotalCommittedPages = MiMemoryConsumers[MC_PPOOL].PagesUsed +
418 MiMemoryConsumers[MC_NPPOOL].PagesUsed+
419 MiMemoryConsumers[MC_CACHE].PagesUsed+
420 MiMemoryConsumers[MC_USER].PagesUsed+
421 MiUsedSwapPages;
422 /*
423 Add up the full system total + pagefile.
424 All this make Taskmgr happy but not sure it is the right numbers.
425 This too, fixes some of GlobalMemoryStatusEx numbers.
426 */
427 Spi->TotalCommitLimit = MmStats.NrTotalPages + MiFreeSwapPages +
428 MiUsedSwapPages;
429
430 Spi->PeakCommitment = 0; /* FIXME */
431 Spi->PageFaults = 0; /* FIXME */
432 Spi->WriteCopyFaults = 0; /* FIXME */
433 Spi->TransitionFaults = 0; /* FIXME */
434 Spi->CacheTransitionFaults = 0; /* FIXME */
435 Spi->DemandZeroFaults = 0; /* FIXME */
436 Spi->PagesRead = 0; /* FIXME */
437 Spi->PageReadIos = 0; /* FIXME */
438 Spi->CacheReads = 0; /* FIXME */
439 Spi->CacheIos = 0; /* FIXME */
440 Spi->PagefilePagesWritten = 0; /* FIXME */
441 Spi->PagefilePageWriteIos = 0; /* FIXME */
442 Spi->MappedFilePagesWritten = 0; /* FIXME */
443 Spi->MappedFilePageWriteIos = 0; /* FIXME */
444
445 Spi->PagedPoolUsage = MiMemoryConsumers[MC_PPOOL].PagesUsed;
446 Spi->PagedPoolAllocs = 0; /* FIXME */
447 Spi->PagedPoolFrees = 0; /* FIXME */
448 Spi->NonPagedPoolUsage = MiMemoryConsumers[MC_NPPOOL].PagesUsed;
449 Spi->NonPagedPoolAllocs = 0; /* FIXME */
450 Spi->NonPagedPoolFrees = 0; /* FIXME */
451
452 Spi->TotalFreeSystemPtes = 0; /* FIXME */
453
454 Spi->SystemCodePage = MmStats.NrSystemPages; /* FIXME */
455
456 Spi->TotalSystemDriverPages = 0; /* FIXME */
457 Spi->TotalSystemCodePages = 0; /* FIXME */
458 Spi->SmallNonPagedLookasideListAllocateHits = 0; /* FIXME */
459 Spi->SmallPagedLookasideListAllocateHits = 0; /* FIXME */
460 Spi->Reserved3 = 0; /* FIXME */
461
462 Spi->MmSystemCachePage = MiMemoryConsumers[MC_CACHE].PagesUsed;
463 Spi->PagedPoolPage = MmPagedPoolSize; /* FIXME */
464
465 Spi->SystemDriverPage = 0; /* FIXME */
466 Spi->FastReadNoWait = 0; /* FIXME */
467 Spi->FastReadWait = 0; /* FIXME */
468 Spi->FastReadResourceMiss = 0; /* FIXME */
469 Spi->FastReadNotPossible = 0; /* FIXME */
470
471 Spi->FastMdlReadNoWait = 0; /* FIXME */
472 Spi->FastMdlReadWait = 0; /* FIXME */
473 Spi->FastMdlReadResourceMiss = 0; /* FIXME */
474 Spi->FastMdlReadNotPossible = 0; /* FIXME */
475
476 Spi->MapDataNoWait = 0; /* FIXME */
477 Spi->MapDataWait = 0; /* FIXME */
478 Spi->MapDataNoWaitMiss = 0; /* FIXME */
479 Spi->MapDataWaitMiss = 0; /* FIXME */
480
481 Spi->PinMappedDataCount = 0; /* FIXME */
482 Spi->PinReadNoWait = 0; /* FIXME */
483 Spi->PinReadWait = 0; /* FIXME */
484 Spi->PinReadNoWaitMiss = 0; /* FIXME */
485 Spi->PinReadWaitMiss = 0; /* FIXME */
486 Spi->CopyReadNoWait = 0; /* FIXME */
487 Spi->CopyReadWait = 0; /* FIXME */
488 Spi->CopyReadNoWaitMiss = 0; /* FIXME */
489 Spi->CopyReadWaitMiss = 0; /* FIXME */
490
491 Spi->MdlReadNoWait = 0; /* FIXME */
492 Spi->MdlReadWait = 0; /* FIXME */
493 Spi->MdlReadNoWaitMiss = 0; /* FIXME */
494 Spi->MdlReadWaitMiss = 0; /* FIXME */
495 Spi->ReadAheadIos = 0; /* FIXME */
496 Spi->LazyWriteIos = 0; /* FIXME */
497 Spi->LazyWritePages = 0; /* FIXME */
498 Spi->DataFlushes = 0; /* FIXME */
499 Spi->DataPages = 0; /* FIXME */
500 Spi->ContextSwitches = 0; /* FIXME */
501 Spi->FirstLevelTbFills = 0; /* FIXME */
502 Spi->SecondLevelTbFills = 0; /* FIXME */
503 Spi->SystemCalls = 0; /* FIXME */
504
505 ObDereferenceObject(TheIdleProcess);
506
507 return (STATUS_SUCCESS);
508 }
509
510 /* Class 3 - Time Of Day Information */
511 QSI_DEF(SystemTimeOfDayInformation)
512 {
513 LARGE_INTEGER CurrentTime;
514
515 PSYSTEM_TIMEOFDAY_INFORMATION Sti
516 = (PSYSTEM_TIMEOFDAY_INFORMATION) Buffer;
517
518 *ReqSize = sizeof (SYSTEM_TIMEOFDAY_INFORMATION);
519 /*
520 * Check user buffer's size
521 */
522 if (Size < sizeof (SYSTEM_TIMEOFDAY_INFORMATION))
523 {
524 return (STATUS_INFO_LENGTH_MISMATCH);
525 }
526
527 KeQuerySystemTime(&CurrentTime);
528
529 Sti->BootTime= SystemBootTime;
530 Sti->CurrentTime = CurrentTime;
531 Sti->TimeZoneBias.QuadPart = _SystemTimeZoneInfo.Bias;
532 Sti->TimeZoneId = 0; /* FIXME */
533 Sti->Reserved = 0; /* FIXME */
534
535 return (STATUS_SUCCESS);
536 }
537
538 /* Class 4 - Path Information */
539 QSI_DEF(SystemPathInformation)
540 {
541 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
542 return (STATUS_BREAKPOINT);
543 }
544
545 /* Class 5 - Process Information */
546 QSI_DEF(SystemProcessInformation)
547 {
548 ULONG ovlSize=0, nThreads;
549 PEPROCESS pr, syspr;
550 unsigned char *pCur;
551
552 /* scan the process list */
553
554 PSYSTEM_PROCESSES Spi
555 = (PSYSTEM_PROCESSES) Buffer;
556
557 *ReqSize = sizeof(SYSTEM_PROCESSES);
558
559 if (Size < sizeof(SYSTEM_PROCESSES))
560 {
561 return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
562 }
563
564 syspr = PsGetNextProcess(NULL);
565 pr = syspr;
566 pCur = (unsigned char *)Spi;
567
568 do
569 {
570 PSYSTEM_PROCESSES SpiCur;
571 int curSize, i = 0;
572 ANSI_STRING imgName;
573 int inLen=32; // image name len in bytes
574 PLIST_ENTRY current_entry;
575 PETHREAD current;
576
577 SpiCur = (PSYSTEM_PROCESSES)pCur;
578
579 nThreads = PsEnumThreadsByProcess(pr);
580
581 // size of the structure for every process
582 curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*nThreads;
583 ovlSize += curSize+inLen;
584
585 if (ovlSize > Size)
586 {
587 *ReqSize = ovlSize;
588 ObDereferenceObject(pr);
589
590 return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
591 }
592
593 // fill system information
594 SpiCur->NextEntryDelta = curSize+inLen; // relative offset to the beginnnig of the next structure
595 SpiCur->ThreadCount = nThreads;
596 SpiCur->CreateTime = pr->CreateTime;
597 SpiCur->UserTime.QuadPart = pr->Pcb.UserTime * 100000LL;
598 SpiCur->KernelTime.QuadPart = pr->Pcb.KernelTime * 100000LL;
599 SpiCur->ProcessName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
600 SpiCur->ProcessName.MaximumLength = inLen;
601 SpiCur->ProcessName.Buffer = (void*)(pCur+curSize);
602
603 // copy name to the end of the struct
604 RtlInitAnsiString(&imgName, pr->ImageFileName);
605 RtlAnsiStringToUnicodeString(&SpiCur->ProcessName, &imgName, FALSE);
606
607 SpiCur->BasePriority = pr->Pcb.BasePriority;
608 SpiCur->ProcessId = pr->UniqueProcessId;
609 SpiCur->InheritedFromProcessId = (DWORD)(pr->InheritedFromUniqueProcessId);
610 SpiCur->HandleCount = ObpGetHandleCountByHandleTable(&pr->HandleTable);
611 SpiCur->VmCounters.PeakVirtualSize = pr->PeakVirtualSize;
612 SpiCur->VmCounters.VirtualSize = pr->VirtualSize.QuadPart;
613 SpiCur->VmCounters.PageFaultCount = pr->LastFaultCount;
614 SpiCur->VmCounters.PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ?
615 SpiCur->VmCounters.WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ?
616 SpiCur->VmCounters.QuotaPeakPagedPoolUsage =
617 pr->QuotaPeakPoolUsage[0];
618 SpiCur->VmCounters.QuotaPagedPoolUsage =
619 pr->QuotaPoolUsage[0];
620 SpiCur->VmCounters.QuotaPeakNonPagedPoolUsage =
621 pr->QuotaPeakPoolUsage[1];
622 SpiCur->VmCounters.QuotaNonPagedPoolUsage =
623 pr->QuotaPoolUsage[1];
624 SpiCur->VmCounters.PagefileUsage = pr->PagefileUsage; // FIXME
625 SpiCur->VmCounters.PeakPagefileUsage = pr->PeakPagefileUsage;
626 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
627 // doesn't seem to contain any equivalent field
628 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
629
630 current_entry = pr->ThreadListHead.Flink;
631 while (current_entry != &pr->ThreadListHead)
632 {
633 current = CONTAINING_RECORD(current_entry, ETHREAD,
634 Tcb.ProcessThreadListEntry);
635
636 SpiCur->Threads[i].KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
637 SpiCur->Threads[i].UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
638 // SpiCur->Threads[i].CreateTime = current->CreateTime;
639 SpiCur->Threads[i].WaitTime = current->Tcb.WaitTime;
640 SpiCur->Threads[i].StartAddress = (PVOID) current->StartAddress;
641 SpiCur->Threads[i].ClientId = current->Cid;
642 SpiCur->Threads[i].Priority = current->Tcb.Priority;
643 SpiCur->Threads[i].BasePriority = current->Tcb.BasePriority;
644 SpiCur->Threads[i].ContextSwitchCount = current->Tcb.ContextSwitches;
645 SpiCur->Threads[i].State = current->Tcb.State;
646 SpiCur->Threads[i].WaitReason = current->Tcb.WaitReason;
647 i++;
648 current_entry = current_entry->Flink;
649 }
650
651 pr = PsGetNextProcess(pr);
652
653 if ((pr == syspr) || (pr == NULL))
654 {
655 SpiCur->NextEntryDelta = 0;
656 break;
657 }
658 else
659 pCur = pCur + curSize + inLen;
660 } while ((pr != syspr) && (pr != NULL));
661
662 *ReqSize = ovlSize;
663 if (pr != NULL)
664 {
665 ObDereferenceObject(pr);
666 }
667 return (STATUS_SUCCESS);
668 }
669
670 /* Class 6 - Call Count Information */
671 QSI_DEF(SystemCallCountInformation)
672 {
673 /* FIXME */
674 return (STATUS_NOT_IMPLEMENTED);
675 }
676
677 /* Class 7 - Device Information */
678 QSI_DEF(SystemDeviceInformation)
679 {
680 PSYSTEM_DEVICE_INFORMATION Sdi
681 = (PSYSTEM_DEVICE_INFORMATION) Buffer;
682 PCONFIGURATION_INFORMATION ConfigInfo;
683
684 *ReqSize = sizeof (SYSTEM_DEVICE_INFORMATION);
685 /*
686 * Check user buffer's size
687 */
688 if (Size < sizeof (SYSTEM_DEVICE_INFORMATION))
689 {
690 return (STATUS_INFO_LENGTH_MISMATCH);
691 }
692
693 ConfigInfo = IoGetConfigurationInformation ();
694
695 Sdi->NumberOfDisks = ConfigInfo->DiskCount;
696 Sdi->NumberOfFloppies = ConfigInfo->FloppyCount;
697 Sdi->NumberOfCdRoms = ConfigInfo->CdRomCount;
698 Sdi->NumberOfTapes = ConfigInfo->TapeCount;
699 Sdi->NumberOfSerialPorts = ConfigInfo->SerialCount;
700 Sdi->NumberOfParallelPorts = ConfigInfo->ParallelCount;
701
702 return (STATUS_SUCCESS);
703 }
704
705 /* Class 8 - Processor Performance Information */
706 QSI_DEF(SystemProcessorPerformanceInformation)
707 {
708 PSYSTEM_PROCESSORTIME_INFO Spi
709 = (PSYSTEM_PROCESSORTIME_INFO) Buffer;
710
711 PEPROCESS TheIdleProcess;
712 TIME CurrentTime;
713
714 *ReqSize = sizeof (SYSTEM_PROCESSORTIME_INFO);
715 /*
716 * Check user buffer's size
717 */
718 if (Size < sizeof (SYSTEM_PROCESSORTIME_INFO))
719 {
720 return (STATUS_INFO_LENGTH_MISMATCH);
721 }
722
723 PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
724
725 CurrentTime.QuadPart = KeQueryInterruptTime();
726
727 Spi->TotalProcessorRunTime.QuadPart =
728 TheIdleProcess->Pcb.KernelTime * 100000LL; // IdleTime
729 Spi->TotalProcessorTime.QuadPart = KiKernelTime * 100000LL; // KernelTime
730 Spi->TotalProcessorUserTime.QuadPart = KiUserTime * 100000LL;
731 Spi->TotalDPCTime.QuadPart = KiDpcTime * 100000LL;
732 Spi->TotalInterruptTime = CurrentTime;
733 Spi->TotalInterrupts = CurrentTime.QuadPart / 100000LL; // Interrupt Count
734
735 ObDereferenceObject(TheIdleProcess);
736
737 return (STATUS_SUCCESS);
738 }
739
740 /* Class 9 - Flags Information */
741 QSI_DEF(SystemFlagsInformation)
742 {
743 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
744 {
745 * ReqSize = sizeof (SYSTEM_FLAGS_INFORMATION);
746 return (STATUS_INFO_LENGTH_MISMATCH);
747 }
748 ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag;
749 return (STATUS_SUCCESS);
750 }
751
752 SSI_DEF(SystemFlagsInformation)
753 {
754 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
755 {
756 return (STATUS_INFO_LENGTH_MISMATCH);
757 }
758 NtGlobalFlag = ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags;
759 return (STATUS_SUCCESS);
760 }
761
762 /* Class 10 - Call Time Information */
763 QSI_DEF(SystemCallTimeInformation)
764 {
765 /* FIXME */
766 return (STATUS_NOT_IMPLEMENTED);
767 }
768
769 /* Class 11 - Module Information */
770 QSI_DEF(SystemModuleInformation)
771 {
772 return LdrpQueryModuleInformation(Buffer, Size, ReqSize);
773 }
774
775 /* Class 12 - Locks Information */
776 QSI_DEF(SystemLocksInformation)
777 {
778 /* FIXME */
779 return (STATUS_NOT_IMPLEMENTED);
780 }
781
782 /* Class 13 - Stack Trace Information */
783 QSI_DEF(SystemStackTraceInformation)
784 {
785 /* FIXME */
786 return (STATUS_NOT_IMPLEMENTED);
787 }
788
789 /* Class 14 - Paged Pool Information */
790 QSI_DEF(SystemPagedPoolInformation)
791 {
792 /* FIXME */
793 return (STATUS_NOT_IMPLEMENTED);
794 }
795
796 /* Class 15 - Non Paged Pool Information */
797 QSI_DEF(SystemNonPagedPoolInformation)
798 {
799 /* FIXME */
800 return (STATUS_NOT_IMPLEMENTED);
801 }
802
803 /* Class 16 - Handle Information */
804 QSI_DEF(SystemHandleInformation)
805 {
806 /* FIXME */
807 return (STATUS_NOT_IMPLEMENTED);
808 }
809
810 /* Class 17 - Information */
811 QSI_DEF(SystemObjectInformation)
812 {
813 /* FIXME */
814 return (STATUS_NOT_IMPLEMENTED);
815 }
816
817 /* Class 18 - Information */
818 QSI_DEF(SystemPageFileInformation)
819 {
820 SYSTEM_PAGEFILE_INFORMATION *Spfi = (SYSTEM_PAGEFILE_INFORMATION *) Buffer;
821
822 if (Size < sizeof (SYSTEM_PAGEFILE_INFORMATION))
823 {
824 * ReqSize = sizeof (SYSTEM_PAGEFILE_INFORMATION);
825 return (STATUS_INFO_LENGTH_MISMATCH);
826 }
827
828 UNICODE_STRING FileName; /* FIXME */
829
830 /* FIXME */
831 Spfi->RelativeOffset = 0;
832
833 Spfi->CurrentSizePages = MiFreeSwapPages + MiUsedSwapPages;
834 Spfi->TotalUsedPages = MiUsedSwapPages;
835 Spfi->PeakUsedPages = MiUsedSwapPages; /* FIXME */
836 Spfi->PagefileFileName = FileName;
837 return (STATUS_SUCCESS);
838 }
839
840 /* Class 19 - Vdm Instemul Information */
841 QSI_DEF(SystemVdmInstemulInformation)
842 {
843 /* FIXME */
844 return (STATUS_NOT_IMPLEMENTED);
845 }
846
847 /* Class 20 - Vdm Bop Information */
848 QSI_DEF(SystemVdmBopInformation)
849 {
850 /* FIXME */
851 return (STATUS_NOT_IMPLEMENTED);
852 }
853
854 /* Class 21 - File Cache Information */
855 QSI_DEF(SystemFileCacheInformation)
856 {
857 SYSTEM_CACHE_INFORMATION *Sci = (SYSTEM_CACHE_INFORMATION *) Buffer;
858
859 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
860 {
861 * ReqSize = sizeof (SYSTEM_CACHE_INFORMATION);
862 return (STATUS_INFO_LENGTH_MISMATCH);
863 }
864 /* Return the Byte size not the page size. */
865 Sci->CurrentSize =
866 MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE;
867 Sci->PeakSize =
868 MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE; /* FIXME */
869
870 Sci->PageFaultCount = 0; /* FIXME */
871 Sci->MinimumWorkingSet = 0; /* FIXME */
872 Sci->MaximumWorkingSet = 0; /* FIXME */
873 Sci->TransitionSharedPages = 0; /* FIXME */
874 Sci->TransitionSharedPagesPeak = 0; /* FIXME */
875
876 return (STATUS_SUCCESS);
877 }
878
879 SSI_DEF(SystemFileCacheInformation)
880 {
881 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
882 {
883 return (STATUS_INFO_LENGTH_MISMATCH);
884 }
885 /* FIXME */
886 return (STATUS_NOT_IMPLEMENTED);
887 }
888
889 /* Class 22 - Pool Tag Information */
890 QSI_DEF(SystemPoolTagInformation)
891 {
892 /* FIXME */
893 return (STATUS_NOT_IMPLEMENTED);
894 }
895
896 /* Class 23 - Interrupt Information */
897 QSI_DEF(SystemInterruptInformation)
898 {
899 /* FIXME */
900 return (STATUS_NOT_IMPLEMENTED);
901 }
902
903 /* Class 24 - DPC Behaviour Information */
904 QSI_DEF(SystemDpcBehaviourInformation)
905 {
906 /* FIXME */
907 return (STATUS_NOT_IMPLEMENTED);
908 }
909
910 SSI_DEF(SystemDpcBehaviourInformation)
911 {
912 /* FIXME */
913 return (STATUS_NOT_IMPLEMENTED);
914 }
915
916 /* Class 25 - Full Memory Information */
917 QSI_DEF(SystemFullMemoryInformation)
918 {
919 PULONG Spi = (PULONG) Buffer;
920
921 PEPROCESS TheIdleProcess;
922
923 * ReqSize = sizeof (ULONG);
924
925 if (sizeof (ULONG) != Size)
926 {
927 return (STATUS_INFO_LENGTH_MISMATCH);
928 }
929 DPRINT1("SystemFullMemoryInformation\n");
930
931 PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
932
933 DbgPrint("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
934 TheIdleProcess->UniqueProcessId,
935 TheIdleProcess->Pcb.KernelTime,
936 MiFreeSwapPages,
937 MiUsedSwapPages);
938
939 MmPrintMemoryStatistic();
940
941 *Spi = MiMemoryConsumers[MC_USER].PagesUsed;
942
943 ObDereferenceObject(TheIdleProcess);
944
945 return (STATUS_SUCCESS);
946 }
947
948 /* Class 26 - Load Image */
949 SSI_DEF(SystemLoadImage)
950 {
951 PSYSTEM_LOAD_IMAGE Sli = (PSYSTEM_LOAD_IMAGE)Buffer;
952
953 if (sizeof(SYSTEM_LOAD_IMAGE) != Size)
954 {
955 return(STATUS_INFO_LENGTH_MISMATCH);
956 }
957
958 return(LdrpLoadImage(&Sli->ModuleName,
959 &Sli->ModuleBase,
960 &Sli->SectionPointer,
961 &Sli->EntryPoint,
962 &Sli->ExportDirectory));
963 }
964
965 /* Class 27 - Unload Image */
966 SSI_DEF(SystemUnloadImage)
967 {
968 PSYSTEM_UNLOAD_IMAGE Sui = (PSYSTEM_UNLOAD_IMAGE)Buffer;
969
970 if (sizeof(SYSTEM_UNLOAD_IMAGE) != Size)
971 {
972 return(STATUS_INFO_LENGTH_MISMATCH);
973 }
974
975 return(LdrpUnloadImage(Sui->ModuleBase));
976 }
977
978 /* Class 28 - Time Adjustment Information */
979 QSI_DEF(SystemTimeAdjustmentInformation)
980 {
981 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT) > Size)
982 {
983 * ReqSize = sizeof (SYSTEM_SET_TIME_ADJUSTMENT);
984 return (STATUS_INFO_LENGTH_MISMATCH);
985 }
986 /* FIXME: */
987 return (STATUS_NOT_IMPLEMENTED);
988 }
989
990 SSI_DEF(SystemTimeAdjustmentInformation)
991 {
992 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT) > Size)
993 {
994 return (STATUS_INFO_LENGTH_MISMATCH);
995 }
996 /* FIXME: */
997 return (STATUS_NOT_IMPLEMENTED);
998 }
999
1000 /* Class 29 - Summary Memory Information */
1001 QSI_DEF(SystemSummaryMemoryInformation)
1002 {
1003 /* FIXME */
1004 return (STATUS_NOT_IMPLEMENTED);
1005 }
1006
1007 /* Class 30 - Next Event Id Information */
1008 QSI_DEF(SystemNextEventIdInformation)
1009 {
1010 /* FIXME */
1011 return (STATUS_NOT_IMPLEMENTED);
1012 }
1013
1014 /* Class 31 - Event Ids Information */
1015 QSI_DEF(SystemEventIdsInformation)
1016 {
1017 /* FIXME */
1018 return (STATUS_NOT_IMPLEMENTED);
1019 }
1020
1021 /* Class 32 - Crach Dump Information */
1022 QSI_DEF(SystemCrashDumpInformation)
1023 {
1024 /* FIXME */
1025 return (STATUS_NOT_IMPLEMENTED);
1026 }
1027
1028 /* Class 33 - Exception Information */
1029 QSI_DEF(SystemExceptionInformation)
1030 {
1031 /* FIXME */
1032 return (STATUS_NOT_IMPLEMENTED);
1033 }
1034
1035 /* Class 34 - Crach Dump State Information */
1036 QSI_DEF(SystemCrashDumpStateInformation)
1037 {
1038 /* FIXME */
1039 return (STATUS_NOT_IMPLEMENTED);
1040 }
1041
1042 /* Class 35 - Kernel Debugger Information */
1043 QSI_DEF(SystemKernelDebuggerInformation)
1044 {
1045 /* FIXME */
1046 return (STATUS_NOT_IMPLEMENTED);
1047 }
1048
1049 /* Class 36 - Context Switch Information */
1050 QSI_DEF(SystemContextSwitchInformation)
1051 {
1052 /* FIXME */
1053 return (STATUS_NOT_IMPLEMENTED);
1054 }
1055
1056 /* Class 37 - Registry Quota Information */
1057 QSI_DEF(SystemRegistryQuotaInformation)
1058 {
1059 /* FIXME */
1060 return (STATUS_NOT_IMPLEMENTED);
1061 }
1062
1063 SSI_DEF(SystemRegistryQuotaInformation)
1064 {
1065 /* FIXME */
1066 return (STATUS_NOT_IMPLEMENTED);
1067 }
1068
1069 /* Class 38 - Load And Call Image */
1070 SSI_DEF(SystemLoadAndCallImage)
1071 {
1072 PSYSTEM_LOAD_AND_CALL_IMAGE Slci = (PSYSTEM_LOAD_AND_CALL_IMAGE)Buffer;
1073
1074 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE) != Size)
1075 {
1076 return(STATUS_INFO_LENGTH_MISMATCH);
1077 }
1078
1079 return(LdrpLoadAndCallImage(&Slci->ModuleName));
1080 }
1081
1082 /* Class 39 - Priority Seperation */
1083 SSI_DEF(SystemPrioritySeperation)
1084 {
1085 /* FIXME */
1086 return (STATUS_NOT_IMPLEMENTED);
1087 }
1088
1089 /* Class 40 - Plug Play Bus Information */
1090 QSI_DEF(SystemPlugPlayBusInformation)
1091 {
1092 /* FIXME */
1093 return (STATUS_NOT_IMPLEMENTED);
1094 }
1095
1096 /* Class 41 - Dock Information */
1097 QSI_DEF(SystemDockInformation)
1098 {
1099 /* FIXME */
1100 return (STATUS_NOT_IMPLEMENTED);
1101 }
1102
1103 /* Class 42 - Power Information */
1104 QSI_DEF(SystemPowerInformation)
1105 {
1106 /* FIXME */
1107 return (STATUS_NOT_IMPLEMENTED);
1108 }
1109
1110 /* Class 43 - Processor Speed Information */
1111 QSI_DEF(SystemProcessorSpeedInformation)
1112 {
1113 /* FIXME */
1114 return (STATUS_NOT_IMPLEMENTED);
1115 }
1116
1117 /* Class 44 - Current Time Zone Information */
1118 QSI_DEF(SystemCurrentTimeZoneInformation)
1119 {
1120 * ReqSize = sizeof (TIME_ZONE_INFORMATION);
1121
1122 if (sizeof (TIME_ZONE_INFORMATION) != Size)
1123 {
1124 return (STATUS_INFO_LENGTH_MISMATCH);
1125 }
1126 /* Copy the time zone information struct */
1127 memcpy (
1128 Buffer,
1129 & _SystemTimeZoneInfo,
1130 sizeof (TIME_ZONE_INFORMATION)
1131 );
1132
1133 return (STATUS_SUCCESS);
1134 }
1135
1136
1137 SSI_DEF(SystemCurrentTimeZoneInformation)
1138 {
1139 /*
1140 * Check user buffer's size
1141 */
1142 if (Size < sizeof (TIME_ZONE_INFORMATION))
1143 {
1144 return (STATUS_INFO_LENGTH_MISMATCH);
1145 }
1146 /* Copy the time zone information struct */
1147 memcpy (
1148 & _SystemTimeZoneInfo,
1149 (TIME_ZONE_INFORMATION *) Buffer,
1150 sizeof (TIME_ZONE_INFORMATION)
1151 );
1152 return (STATUS_SUCCESS);
1153 }
1154
1155
1156 /* Class 45 - Lookaside Information */
1157 QSI_DEF(SystemLookasideInformation)
1158 {
1159 /* FIXME */
1160 return (STATUS_NOT_IMPLEMENTED);
1161 }
1162
1163
1164 /* Class 46 - Set time slip event */
1165 SSI_DEF(SystemSetTimeSlipEvent)
1166 {
1167 /* FIXME */
1168 return (STATUS_NOT_IMPLEMENTED);
1169 }
1170
1171
1172 /* Class 47 - Create a new session (TSE) */
1173 SSI_DEF(SystemCreateSession)
1174 {
1175 /* FIXME */
1176 return (STATUS_NOT_IMPLEMENTED);
1177 }
1178
1179
1180 /* Class 48 - Delete an existing session (TSE) */
1181 SSI_DEF(SystemDeleteSession)
1182 {
1183 /* FIXME */
1184 return (STATUS_NOT_IMPLEMENTED);
1185 }
1186
1187
1188 /* Class 49 - UNKNOWN */
1189 QSI_DEF(SystemInvalidInfoClass4)
1190 {
1191 /* FIXME */
1192 return (STATUS_NOT_IMPLEMENTED);
1193 }
1194
1195
1196 /* Class 50 - System range start address */
1197 QSI_DEF(SystemRangeStartInformation)
1198 {
1199 /* FIXME */
1200 return (STATUS_NOT_IMPLEMENTED);
1201 }
1202
1203
1204 /* Class 51 - Driver verifier information */
1205 QSI_DEF(SystemVerifierInformation)
1206 {
1207 /* FIXME */
1208 return (STATUS_NOT_IMPLEMENTED);
1209 }
1210
1211
1212 SSI_DEF(SystemVerifierInformation)
1213 {
1214 /* FIXME */
1215 return (STATUS_NOT_IMPLEMENTED);
1216 }
1217
1218
1219 /* Class 52 - Add a driver verifier */
1220 SSI_DEF(SystemAddVerifier)
1221 {
1222 /* FIXME */
1223 return (STATUS_NOT_IMPLEMENTED);
1224 }
1225
1226
1227 /* Class 53 - A session's processes */
1228 QSI_DEF(SystemSessionProcessesInformation)
1229 {
1230 /* FIXME */
1231 return (STATUS_NOT_IMPLEMENTED);
1232 }
1233
1234
1235 /* Query/Set Calls Table */
1236 typedef
1237 struct _QSSI_CALLS
1238 {
1239 NTSTATUS (* Query) (PVOID,ULONG,PULONG);
1240 NTSTATUS (* Set) (PVOID,ULONG);
1241
1242 } QSSI_CALLS;
1243
1244 // QS Query & Set
1245 // QX Query
1246 // XQ Set
1247 // XX unknown behaviour
1248 //
1249 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1250 #define SI_QX(n) {QSI_USE(n),NULL}
1251 #define SI_XS(n) {NULL,SSI_USE(n)}
1252 #define SI_XX(n) {NULL,NULL}
1253
1254 static
1255 QSSI_CALLS
1256 CallQS [] =
1257 {
1258 SI_QX(SystemBasicInformation),
1259 SI_QX(SystemProcessorInformation),
1260 SI_QX(SystemPerformanceInformation),
1261 SI_QX(SystemTimeOfDayInformation),
1262 SI_QX(SystemPathInformation), /* should be SI_XX */
1263 SI_QX(SystemProcessInformation),
1264 SI_QX(SystemCallCountInformation),
1265 SI_QX(SystemDeviceInformation),
1266 SI_QX(SystemProcessorPerformanceInformation),
1267 SI_QS(SystemFlagsInformation),
1268 SI_QX(SystemCallTimeInformation), /* should be SI_XX */
1269 SI_QX(SystemModuleInformation),
1270 SI_QX(SystemLocksInformation),
1271 SI_QX(SystemStackTraceInformation), /* should be SI_XX */
1272 SI_QX(SystemPagedPoolInformation), /* should be SI_XX */
1273 SI_QX(SystemNonPagedPoolInformation), /* should be SI_XX */
1274 SI_QX(SystemHandleInformation),
1275 SI_QX(SystemObjectInformation),
1276 SI_QX(SystemPageFileInformation),
1277 SI_QX(SystemVdmInstemulInformation),
1278 SI_QX(SystemVdmBopInformation), /* it should be SI_XX */
1279 SI_QS(SystemFileCacheInformation),
1280 SI_QX(SystemPoolTagInformation),
1281 SI_QX(SystemInterruptInformation),
1282 SI_QS(SystemDpcBehaviourInformation),
1283 SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */
1284 SI_XS(SystemLoadImage),
1285 SI_XS(SystemUnloadImage),
1286 SI_QS(SystemTimeAdjustmentInformation),
1287 SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */
1288 SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */
1289 SI_QX(SystemEventIdsInformation), /* it should be SI_XX */
1290 SI_QX(SystemCrashDumpInformation),
1291 SI_QX(SystemExceptionInformation),
1292 SI_QX(SystemCrashDumpStateInformation),
1293 SI_QX(SystemKernelDebuggerInformation),
1294 SI_QX(SystemContextSwitchInformation),
1295 SI_QS(SystemRegistryQuotaInformation),
1296 SI_XS(SystemLoadAndCallImage),
1297 SI_XS(SystemPrioritySeperation),
1298 SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */
1299 SI_QX(SystemDockInformation), /* it should be SI_XX */
1300 SI_QX(SystemPowerInformation), /* it should be SI_XX */
1301 SI_QX(SystemProcessorSpeedInformation), /* it should be SI_XX */
1302 SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */
1303 SI_QX(SystemLookasideInformation),
1304 SI_XS(SystemSetTimeSlipEvent),
1305 SI_XS(SystemCreateSession),
1306 SI_XS(SystemDeleteSession),
1307 SI_QX(SystemInvalidInfoClass4), /* it should be SI_XX */
1308 SI_QX(SystemRangeStartInformation),
1309 SI_QS(SystemVerifierInformation),
1310 SI_XS(SystemAddVerifier),
1311 SI_QX(SystemSessionProcessesInformation)
1312 };
1313
1314
1315 /*
1316 * @implemented
1317 */
1318 NTSTATUS STDCALL
1319 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1320 OUT PVOID UnsafeSystemInformation,
1321 IN ULONG Length,
1322 OUT PULONG UnsafeResultLength)
1323 {
1324 ULONG ResultLength;
1325 PVOID SystemInformation;
1326 NTSTATUS Status;
1327 NTSTATUS FStatus;
1328
1329 /* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
1330 SystemInformationClass );
1331 */
1332 /*if (ExGetPreviousMode() == KernelMode)
1333 {*/
1334 SystemInformation = UnsafeSystemInformation;
1335 /*}
1336 else
1337 {
1338 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1339 if (SystemInformation == NULL)
1340 {
1341 return(STATUS_NO_MEMORY);
1342 }
1343 }*/
1344
1345 /* Clear user buffer. */
1346 RtlZeroMemory(SystemInformation, Length);
1347
1348 /*
1349 * Check the request is valid.
1350 */
1351 if ((SystemInformationClass >= SystemInformationClassMin) &&
1352 (SystemInformationClass < SystemInformationClassMax))
1353 {
1354 if (NULL != CallQS [SystemInformationClass].Query)
1355 {
1356 /*
1357 * Hand the request to a subhandler.
1358 */
1359 FStatus = CallQS [SystemInformationClass].Query(SystemInformation,
1360 Length,
1361 &ResultLength);
1362 /*if (ExGetPreviousMode() != KernelMode)
1363 {
1364 Status = MmCopyToCaller(UnsafeSystemInformation,
1365 SystemInformation,
1366 Length);
1367 ExFreePool(SystemInformation);
1368 if (!NT_SUCCESS(Status))
1369 {
1370 return(Status);
1371 }
1372 }*/
1373 if (UnsafeResultLength != NULL)
1374 {
1375 /*if (ExGetPreviousMode() == KernelMode)
1376 {
1377 *UnsafeResultLength = ResultLength;
1378 }
1379 else
1380 {*/
1381 Status = MmCopyToCaller(UnsafeResultLength,
1382 &ResultLength,
1383 sizeof(ULONG));
1384 if (!NT_SUCCESS(Status))
1385 {
1386 return(Status);
1387 }
1388 /*}*/
1389 }
1390 return(FStatus);
1391 }
1392 }
1393 return (STATUS_INVALID_INFO_CLASS);
1394 }
1395
1396
1397 NTSTATUS
1398 STDCALL
1399 NtSetSystemInformation (
1400 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1401 IN PVOID SystemInformation,
1402 IN ULONG SystemInformationLength
1403 )
1404 {
1405 /*
1406 * If called from user mode, check
1407 * possible unsafe arguments.
1408 */
1409 #if 0
1410 if (KernelMode != KeGetPreviousMode())
1411 {
1412 // Check arguments
1413 //ProbeForWrite(
1414 // SystemInformation,
1415 // Length
1416 // );
1417 //ProbeForWrite(
1418 // ResultLength,
1419 // sizeof (ULONG)
1420 // );
1421 }
1422 #endif
1423 /*
1424 * Check the request is valid.
1425 */
1426 if ( (SystemInformationClass >= SystemInformationClassMin)
1427 && (SystemInformationClass < SystemInformationClassMax)
1428 )
1429 {
1430 if (NULL != CallQS [SystemInformationClass].Set)
1431 {
1432 /*
1433 * Hand the request to a subhandler.
1434 */
1435 return CallQS [SystemInformationClass].Set (
1436 SystemInformation,
1437 SystemInformationLength
1438 );
1439 }
1440 }
1441 return (STATUS_INVALID_INFO_CLASS);
1442 }
1443
1444
1445 NTSTATUS
1446 STDCALL
1447 NtFlushInstructionCache (
1448 IN HANDLE ProcessHandle,
1449 IN PVOID BaseAddress,
1450 IN UINT NumberOfBytesToFlush
1451 )
1452 {
1453 UNIMPLEMENTED;
1454 return(STATUS_NOT_IMPLEMENTED);
1455 }
1456
1457
1458 /* EOF */