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