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