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