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