Fix Process/Thread information structures to match Windows 2000 and have proper struc...
[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 PEPROCESS PsIdleProcess;
19 extern ULONG NtGlobalFlag; /* FIXME: it should go in a ddk/?.h */
20 ULONGLONG STDCALL KeQueryInterruptTime(VOID);
21
22 VOID MmPrintMemoryStatistic(VOID);
23
24 /* FUNCTIONS *****************************************************************/
25
26 /*
27 * @unimplemented
28 */
29 VOID
30 STDCALL
31 ExEnumHandleTable (
32 PULONG HandleTable,
33 PVOID Callback,
34 PVOID Param,
35 PHANDLE Handle OPTIONAL
36 )
37 {
38 UNIMPLEMENTED;
39 }
40
41 /*
42 * @implemented
43 */
44 VOID
45 STDCALL
46 ExGetCurrentProcessorCpuUsage (
47 PULONG CpuUsage
48 )
49 {
50 PKPRCB Prcb;
51 ULONG TotalTime;
52 ULONGLONG ScaledIdle;
53
54 Prcb = KeGetCurrentPrcb();
55
56 ScaledIdle = Prcb->IdleThread->KernelTime * 100;
57 TotalTime = Prcb->KernelTime + Prcb->UserTime;
58 if (TotalTime != 0)
59 *CpuUsage = 100 - (ScaledIdle / TotalTime);
60 else
61 *CpuUsage = 0;
62 }
63
64 /*
65 * @implemented
66 */
67 VOID
68 STDCALL
69 ExGetCurrentProcessorCounts (
70 PULONG ThreadKernelTime,
71 PULONG TotalCpuTime,
72 PULONG ProcessorNumber
73 )
74 {
75 PKPRCB Prcb;
76
77 Prcb = KeGetCurrentPrcb();
78
79 *ThreadKernelTime = Prcb->KernelTime + Prcb->UserTime;
80 *TotalCpuTime = Prcb->CurrentThread->KernelTime;
81 *ProcessorNumber = KeGetCurrentKPCR()->ProcessorNumber;
82 }
83
84 /*
85 * @implemented
86 */
87 BOOLEAN
88 STDCALL
89 ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
90 {
91 /* Quick check to see if it exists at all */
92 if (ProcessorFeature >= PROCESSOR_FEATURE_MAX) return(FALSE);
93
94 /* Return our support for it */
95 return(SharedUserData->ProcessorFeatures[ProcessorFeature]);
96 }
97
98 NTSTATUS STDCALL
99 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName,
100 OUT PWCHAR ValueBuffer,
101 IN ULONG ValueBufferLength,
102 IN OUT PULONG ReturnLength OPTIONAL)
103 {
104 ANSI_STRING AName;
105 UNICODE_STRING WName;
106 BOOLEAN Result;
107 PCH Value;
108 ANSI_STRING AValue;
109 UNICODE_STRING WValue;
110 KPROCESSOR_MODE PreviousMode;
111 NTSTATUS Status = STATUS_SUCCESS;
112
113 PAGED_CODE();
114
115 PreviousMode = ExGetPreviousMode();
116
117 if(PreviousMode != KernelMode)
118 {
119 _SEH_TRY
120 {
121 ProbeForRead(VariableName,
122 sizeof(UNICODE_STRING),
123 sizeof(ULONG));
124 ProbeForWrite(ValueBuffer,
125 ValueBufferLength,
126 sizeof(WCHAR));
127 if(ReturnLength != NULL)
128 {
129 ProbeForWrite(ReturnLength,
130 sizeof(ULONG),
131 sizeof(ULONG));
132 }
133 }
134 _SEH_HANDLE
135 {
136 Status = _SEH_GetExceptionCode();
137 }
138 _SEH_END;
139
140 if(!NT_SUCCESS(Status))
141 {
142 return Status;
143 }
144 }
145
146 /*
147 * Copy the name to kernel space if necessary and convert it to ANSI.
148 */
149 Status = RtlCaptureUnicodeString(&WName,
150 PreviousMode,
151 NonPagedPool,
152 FALSE,
153 VariableName);
154 if(NT_SUCCESS(Status))
155 {
156 /*
157 * according to ntinternals the SeSystemEnvironmentName privilege is required!
158 */
159 if(!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege,
160 PreviousMode))
161 {
162 RtlReleaseCapturedUnicodeString(&WName,
163 PreviousMode,
164 FALSE);
165 DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
166 return STATUS_PRIVILEGE_NOT_HELD;
167 }
168
169 /*
170 * convert the value name to ansi
171 */
172 Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE);
173 RtlReleaseCapturedUnicodeString(&WName,
174 PreviousMode,
175 FALSE);
176 if(!NT_SUCCESS(Status))
177 {
178 return Status;
179 }
180
181 /*
182 * Create a temporary buffer for the value
183 */
184 Value = ExAllocatePool(NonPagedPool, ValueBufferLength);
185 if (Value == NULL)
186 {
187 RtlFreeAnsiString(&AName);
188 return STATUS_INSUFFICIENT_RESOURCES;
189 }
190
191 /*
192 * Get the environment variable
193 */
194 Result = HalGetEnvironmentVariable(AName.Buffer, Value, ValueBufferLength);
195 if(!Result)
196 {
197 RtlFreeAnsiString(&AName);
198 ExFreePool(Value);
199 return STATUS_UNSUCCESSFUL;
200 }
201
202 /*
203 * Convert the result to UNICODE, protect with SEH in case the value buffer
204 * isn't NULL-terminated!
205 */
206 _SEH_TRY
207 {
208 RtlInitAnsiString(&AValue, Value);
209 Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
210 }
211 _SEH_HANDLE
212 {
213 Status = _SEH_GetExceptionCode();
214 }
215 _SEH_END;
216
217 if(NT_SUCCESS(Status))
218 {
219 /*
220 * Copy the result back to the caller.
221 */
222 _SEH_TRY
223 {
224 RtlCopyMemory(ValueBuffer, WValue.Buffer, WValue.Length);
225 ValueBuffer[WValue.Length / sizeof(WCHAR)] = L'\0';
226 if(ReturnLength != NULL)
227 {
228 *ReturnLength = WValue.Length + sizeof(WCHAR);
229 }
230
231 Status = STATUS_SUCCESS;
232 }
233 _SEH_HANDLE
234 {
235 Status = _SEH_GetExceptionCode();
236 }
237 _SEH_END;
238 }
239
240 /*
241 * Cleanup allocated resources.
242 */
243 RtlFreeAnsiString(&AName);
244 ExFreePool(Value);
245 }
246
247 return Status;
248 }
249
250
251 NTSTATUS STDCALL
252 NtSetSystemEnvironmentValue (IN PUNICODE_STRING VariableName,
253 IN PUNICODE_STRING Value)
254 {
255 UNICODE_STRING CapturedName, CapturedValue;
256 ANSI_STRING AName, AValue;
257 KPROCESSOR_MODE PreviousMode;
258 NTSTATUS Status;
259
260 PAGED_CODE();
261
262 PreviousMode = ExGetPreviousMode();
263
264 /*
265 * Copy the strings to kernel space if necessary
266 */
267 Status = RtlCaptureUnicodeString(&CapturedName,
268 PreviousMode,
269 NonPagedPool,
270 FALSE,
271 VariableName);
272 if(NT_SUCCESS(Status))
273 {
274 Status = RtlCaptureUnicodeString(&CapturedValue,
275 PreviousMode,
276 NonPagedPool,
277 FALSE,
278 Value);
279 if(NT_SUCCESS(Status))
280 {
281 /*
282 * according to ntinternals the SeSystemEnvironmentName privilege is required!
283 */
284 if(SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege,
285 PreviousMode))
286 {
287 /*
288 * convert the strings to ANSI
289 */
290 Status = RtlUnicodeStringToAnsiString(&AName,
291 &CapturedName,
292 TRUE);
293 if(NT_SUCCESS(Status))
294 {
295 Status = RtlUnicodeStringToAnsiString(&AValue,
296 &CapturedValue,
297 TRUE);
298 if(NT_SUCCESS(Status))
299 {
300 BOOLEAN Result = HalSetEnvironmentVariable(AName.Buffer,
301 AValue.Buffer);
302
303 Status = (Result ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
304 }
305 }
306 }
307 else
308 {
309 DPRINT1("NtSetSystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
310 Status = STATUS_PRIVILEGE_NOT_HELD;
311 }
312
313 RtlReleaseCapturedUnicodeString(&CapturedValue,
314 PreviousMode,
315 FALSE);
316 }
317
318 RtlReleaseCapturedUnicodeString(&CapturedName,
319 PreviousMode,
320 FALSE);
321 }
322
323 return Status;
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 PKPRCB Prcb;
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 Prcb = KeGetCurrentPrcb();
385 Spi->ProcessorArchitecture = 0; /* Intel Processor */
386 Spi->ProcessorLevel = Prcb->CpuType;
387 Spi->ProcessorRevision = Prcb->CpuStep;
388 Spi->Unknown = 0;
389 Spi->FeatureBits = Prcb->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 TheIdleProcess = PsIdleProcess;
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 return (STATUS_SUCCESS);
519 }
520
521 /* Class 3 - Time Of Day Information */
522 QSI_DEF(SystemTimeOfDayInformation)
523 {
524 PSYSTEM_TIMEOFDAY_INFORMATION Sti;
525 LARGE_INTEGER CurrentTime;
526
527 Sti = (PSYSTEM_TIMEOFDAY_INFORMATION)Buffer;
528 *ReqSize = sizeof (SYSTEM_TIMEOFDAY_INFORMATION);
529
530 /* Check user buffer's size */
531 if (Size < sizeof (SYSTEM_TIMEOFDAY_INFORMATION))
532 {
533 return STATUS_INFO_LENGTH_MISMATCH;
534 }
535
536 KeQuerySystemTime(&CurrentTime);
537
538 Sti->BootTime= SystemBootTime;
539 Sti->CurrentTime = CurrentTime;
540 Sti->TimeZoneBias.QuadPart = ExpTimeZoneBias.QuadPart;
541 Sti->TimeZoneId = ExpTimeZoneId;
542 Sti->Reserved = 0;
543
544 return STATUS_SUCCESS;
545 }
546
547 /* Class 4 - Path Information */
548 QSI_DEF(SystemPathInformation)
549 {
550 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
551 DPRINT1("NtQuerySystemInformation - SystemPathInformation not implemented\n");
552
553 return (STATUS_BREAKPOINT);
554 }
555
556 /* Class 5 - Process Information */
557 QSI_DEF(SystemProcessInformation)
558 {
559 ULONG ovlSize=0, nThreads;
560 PEPROCESS pr, syspr;
561 unsigned char *pCur;
562
563 /* scan the process list */
564
565 PSYSTEM_PROCESS_INFORMATION Spi
566 = (PSYSTEM_PROCESS_INFORMATION) Buffer;
567
568 *ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION);
569
570 if (Size < sizeof(SYSTEM_PROCESS_INFORMATION))
571 {
572 return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
573 }
574
575 syspr = PsGetNextProcess(NULL);
576 pr = syspr;
577 pCur = (unsigned char *)Spi;
578
579 do
580 {
581 PSYSTEM_PROCESS_INFORMATION SpiCur;
582 int curSize, i = 0;
583 ANSI_STRING imgName;
584 int inLen=32; // image name len in bytes
585 PLIST_ENTRY current_entry;
586 PETHREAD current;
587
588 SpiCur = (PSYSTEM_PROCESS_INFORMATION)pCur;
589
590 current_entry = pr->ThreadListHead.Flink;
591 while (current_entry != &pr->ThreadListHead)
592 {
593 nThreads++;
594 current_entry = current_entry->Flink;
595 }
596
597 // size of the structure for every process
598 curSize = sizeof(SYSTEM_PROCESS_INFORMATION)-sizeof(SYSTEM_THREAD_INFORMATION)+sizeof(SYSTEM_THREAD_INFORMATION)*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->NextEntryOffset = curSize+inLen; // relative offset to the beginnnig of the next structure
611 SpiCur->NumberOfThreads = nThreads;
612 SpiCur->CreateTime = pr->CreateTime;
613 SpiCur->UserTime.QuadPart = pr->Pcb.UserTime * 100000LL;
614 SpiCur->KernelTime.QuadPart = pr->Pcb.KernelTime * 100000LL;
615 SpiCur->ImageName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
616 SpiCur->ImageName.MaximumLength = inLen;
617 SpiCur->ImageName.Buffer = (void*)(pCur+curSize);
618
619 // copy name to the end of the struct
620 if(pr != PsIdleProcess)
621 {
622 RtlInitAnsiString(&imgName, pr->ImageFileName);
623 RtlAnsiStringToUnicodeString(&SpiCur->ImageName, &imgName, FALSE);
624 }
625 else
626 {
627 RtlInitUnicodeString(&SpiCur->ImageName, NULL);
628 }
629
630 SpiCur->BasePriority = pr->Pcb.BasePriority;
631 SpiCur->UniqueProcessId = pr->UniqueProcessId;
632 SpiCur->InheritedFromUniqueProcessId = pr->InheritedFromUniqueProcessId;
633 SpiCur->HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
634 SpiCur->PeakVirtualSize = pr->PeakVirtualSize;
635 SpiCur->VirtualSize = pr->VirtualSize.QuadPart;
636 SpiCur->PageFaultCount = pr->LastFaultCount;
637 SpiCur->PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ?
638 SpiCur->WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ?
639 SpiCur->QuotaPeakPagedPoolUsage =
640 pr->QuotaPeakPoolUsage[0];
641 SpiCur->QuotaPagedPoolUsage =
642 pr->QuotaPoolUsage[0];
643 SpiCur->QuotaPeakNonPagedPoolUsage =
644 pr->QuotaPeakPoolUsage[1];
645 SpiCur->QuotaNonPagedPoolUsage =
646 pr->QuotaPoolUsage[1];
647 SpiCur->PagefileUsage = pr->PagefileUsage; // FIXME
648 SpiCur->PeakPagefileUsage = pr->PeakPagefileUsage;
649 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
650 // doesn't seem to contain any equivalent field
651 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
652
653 current_entry = pr->ThreadListHead.Flink;
654 while (current_entry != &pr->ThreadListHead)
655 {
656 current = CONTAINING_RECORD(current_entry, ETHREAD,
657 ThreadListEntry);
658
659 SpiCur->TH[i].KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
660 SpiCur->TH[i].UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
661 // SpiCur->TH[i].CreateTime = current->CreateTime;
662 SpiCur->TH[i].WaitTime = current->Tcb.WaitTime;
663 SpiCur->TH[i].StartAddress = (PVOID) current->StartAddress;
664 SpiCur->TH[i].ClientId = current->Cid;
665 SpiCur->TH[i].Priority = current->Tcb.Priority;
666 SpiCur->TH[i].BasePriority = current->Tcb.BasePriority;
667 SpiCur->TH[i].ContextSwitches = current->Tcb.ContextSwitches;
668 SpiCur->TH[i].ThreadState = current->Tcb.State;
669 SpiCur->TH[i].WaitReason = current->Tcb.WaitReason;
670 i++;
671 current_entry = current_entry->Flink;
672 }
673
674 pr = PsGetNextProcess(pr);
675 nThreads = 0;
676 if ((pr == syspr) || (pr == NULL))
677 {
678 SpiCur->NextEntryOffset = 0;
679 break;
680 }
681 else
682 pCur = pCur + curSize + inLen;
683 } while ((pr != syspr) && (pr != NULL));
684
685 if(pr != NULL)
686 {
687 ObDereferenceObject(pr);
688 }
689
690 *ReqSize = ovlSize;
691 return (STATUS_SUCCESS);
692 }
693
694 /* Class 6 - Call Count Information */
695 QSI_DEF(SystemCallCountInformation)
696 {
697 /* FIXME */
698 DPRINT1("NtQuerySystemInformation - SystemCallCountInformation not implemented\n");
699 return (STATUS_NOT_IMPLEMENTED);
700 }
701
702 /* Class 7 - Device Information */
703 QSI_DEF(SystemDeviceInformation)
704 {
705 PSYSTEM_DEVICE_INFORMATION Sdi
706 = (PSYSTEM_DEVICE_INFORMATION) Buffer;
707 PCONFIGURATION_INFORMATION ConfigInfo;
708
709 *ReqSize = sizeof (SYSTEM_DEVICE_INFORMATION);
710 /*
711 * Check user buffer's size
712 */
713 if (Size < sizeof (SYSTEM_DEVICE_INFORMATION))
714 {
715 return (STATUS_INFO_LENGTH_MISMATCH);
716 }
717
718 ConfigInfo = IoGetConfigurationInformation ();
719
720 Sdi->NumberOfDisks = ConfigInfo->DiskCount;
721 Sdi->NumberOfFloppies = ConfigInfo->FloppyCount;
722 Sdi->NumberOfCdRoms = ConfigInfo->CdRomCount;
723 Sdi->NumberOfTapes = ConfigInfo->TapeCount;
724 Sdi->NumberOfSerialPorts = ConfigInfo->SerialCount;
725 Sdi->NumberOfParallelPorts = ConfigInfo->ParallelCount;
726
727 return (STATUS_SUCCESS);
728 }
729
730 /* Class 8 - Processor Performance Information */
731 QSI_DEF(SystemProcessorPerformanceInformation)
732 {
733 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
734 = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
735
736 ULONG i;
737 LARGE_INTEGER CurrentTime;
738 PKPRCB Prcb;
739
740 *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
741 /*
742 * Check user buffer's size
743 */
744 if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))
745 {
746 return (STATUS_INFO_LENGTH_MISMATCH);
747 }
748
749 CurrentTime.QuadPart = KeQueryInterruptTime();
750 Prcb = ((PKPCR)KPCR_BASE)->Prcb;
751 for (i = 0; i < KeNumberProcessors; i++)
752 {
753 Spi->IdleTime.QuadPart = (Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime) * 100000LL; // IdleTime
754 Spi->KernelTime.QuadPart = Prcb->KernelTime * 100000LL; // KernelTime
755 Spi->UserTime.QuadPart = Prcb->UserTime * 100000LL;
756 Spi->DpcTime.QuadPart = Prcb->DpcTime * 100000LL;
757 Spi->InterruptTime.QuadPart = Prcb->InterruptTime * 100000LL;
758 Spi->InterruptCount = Prcb->InterruptCount; // Interrupt Count
759 Spi++;
760 Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
761 }
762
763 return (STATUS_SUCCESS);
764 }
765
766 /* Class 9 - Flags Information */
767 QSI_DEF(SystemFlagsInformation)
768 {
769 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
770 {
771 * ReqSize = sizeof (SYSTEM_FLAGS_INFORMATION);
772 return (STATUS_INFO_LENGTH_MISMATCH);
773 }
774 ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag;
775 return (STATUS_SUCCESS);
776 }
777
778 SSI_DEF(SystemFlagsInformation)
779 {
780 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
781 {
782 return (STATUS_INFO_LENGTH_MISMATCH);
783 }
784 NtGlobalFlag = ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags;
785 return (STATUS_SUCCESS);
786 }
787
788 /* Class 10 - Call Time Information */
789 QSI_DEF(SystemCallTimeInformation)
790 {
791 /* FIXME */
792 DPRINT1("NtQuerySystemInformation - SystemCallTimeInformation not implemented\n");
793 return (STATUS_NOT_IMPLEMENTED);
794 }
795
796 /* Class 11 - Module Information */
797 QSI_DEF(SystemModuleInformation)
798 {
799 return LdrpQueryModuleInformation(Buffer, Size, ReqSize);
800 }
801
802 /* Class 12 - Locks Information */
803 QSI_DEF(SystemLocksInformation)
804 {
805 /* FIXME */
806 DPRINT1("NtQuerySystemInformation - SystemLocksInformation not implemented\n");
807 return (STATUS_NOT_IMPLEMENTED);
808 }
809
810 /* Class 13 - Stack Trace Information */
811 QSI_DEF(SystemStackTraceInformation)
812 {
813 /* FIXME */
814 DPRINT1("NtQuerySystemInformation - SystemStackTraceInformation not implemented\n");
815 return (STATUS_NOT_IMPLEMENTED);
816 }
817
818 /* Class 14 - Paged Pool Information */
819 QSI_DEF(SystemPagedPoolInformation)
820 {
821 /* FIXME */
822 DPRINT1("NtQuerySystemInformation - SystemPagedPoolInformation not implemented\n");
823 return (STATUS_NOT_IMPLEMENTED);
824 }
825
826 /* Class 15 - Non Paged Pool Information */
827 QSI_DEF(SystemNonPagedPoolInformation)
828 {
829 /* FIXME */
830 DPRINT1("NtQuerySystemInformation - SystemNonPagedPoolInformation not implemented\n");
831 return (STATUS_NOT_IMPLEMENTED);
832 }
833
834
835 VOID
836 ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
837 PEPROCESS Process,
838 int Count);
839
840 /* Class 16 - Handle Information */
841 QSI_DEF(SystemHandleInformation)
842 {
843 PSYSTEM_HANDLE_INFORMATION Shi =
844 (PSYSTEM_HANDLE_INFORMATION) Buffer;
845
846 DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
847
848 if (Size < sizeof (SYSTEM_HANDLE_INFORMATION))
849 {
850 * ReqSize = sizeof (SYSTEM_HANDLE_INFORMATION);
851 return (STATUS_INFO_LENGTH_MISMATCH);
852 }
853
854 DPRINT("SystemHandleInformation 1\n");
855
856 PEPROCESS pr, syspr;
857 int curSize, i = 0;
858 ULONG hCount = 0;
859
860 /* First Calc Size from Count. */
861 syspr = PsGetNextProcess(NULL);
862 pr = syspr;
863
864 do
865 {
866 hCount = hCount + (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
867 pr = PsGetNextProcess(pr);
868
869 if ((pr == syspr) || (pr == NULL))
870 break;
871 } while ((pr != syspr) && (pr != NULL));
872
873 if(pr != NULL)
874 {
875 ObDereferenceObject(pr);
876 }
877
878 DPRINT("SystemHandleInformation 2\n");
879
880 curSize = sizeof(SYSTEM_HANDLE_INFORMATION)+
881 ( (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) -
882 (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) ));
883
884 Shi->NumberOfHandles = hCount;
885
886 if (curSize > Size)
887 {
888 *ReqSize = curSize;
889 return (STATUS_INFO_LENGTH_MISMATCH);
890 }
891
892 DPRINT("SystemHandleInformation 3\n");
893
894 /* Now get Handles from all processs. */
895 syspr = PsGetNextProcess(NULL);
896 pr = syspr;
897
898 do
899 {
900 int Count = 0, HandleCount;
901
902 HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
903
904 for (Count = 0; HandleCount > 0 ; HandleCount--)
905 {
906 ObpGetNextHandleByProcessCount( &Shi->Handles[i], pr, Count);
907 Count++;
908 i++;
909 }
910
911 pr = PsGetNextProcess(pr);
912
913 if ((pr == syspr) || (pr == NULL))
914 break;
915 } while ((pr != syspr) && (pr != NULL));
916
917 if(pr != NULL)
918 {
919 ObDereferenceObject(pr);
920 }
921
922 DPRINT("SystemHandleInformation 4\n");
923 return (STATUS_SUCCESS);
924
925 }
926 /*
927 SSI_DEF(SystemHandleInformation)
928 {
929
930 return (STATUS_SUCCESS);
931 }
932 */
933
934 /* Class 17 - Information */
935 QSI_DEF(SystemObjectInformation)
936 {
937 /* FIXME */
938 DPRINT1("NtQuerySystemInformation - SystemObjectInformation not implemented\n");
939 return (STATUS_NOT_IMPLEMENTED);
940 }
941
942 /* Class 18 - Information */
943 QSI_DEF(SystemPageFileInformation)
944 {
945 SYSTEM_PAGEFILE_INFORMATION *Spfi = (SYSTEM_PAGEFILE_INFORMATION *) Buffer;
946
947 if (Size < sizeof (SYSTEM_PAGEFILE_INFORMATION))
948 {
949 * ReqSize = sizeof (SYSTEM_PAGEFILE_INFORMATION);
950 return (STATUS_INFO_LENGTH_MISMATCH);
951 }
952
953 UNICODE_STRING FileName; /* FIXME */
954
955 /* FIXME */
956 Spfi->NextEntryOffset = 0;
957
958 Spfi->TotalSize = MiFreeSwapPages + MiUsedSwapPages;
959 Spfi->TotalInUse = MiUsedSwapPages;
960 Spfi->PeakUsage = MiUsedSwapPages; /* FIXME */
961 Spfi->PageFileName = FileName;
962 return (STATUS_SUCCESS);
963 }
964
965 /* Class 19 - Vdm Instemul Information */
966 QSI_DEF(SystemVdmInstemulInformation)
967 {
968 /* FIXME */
969 DPRINT1("NtQuerySystemInformation - SystemVdmInstemulInformation not implemented\n");
970 return (STATUS_NOT_IMPLEMENTED);
971 }
972
973 /* Class 20 - Vdm Bop Information */
974 QSI_DEF(SystemVdmBopInformation)
975 {
976 /* FIXME */
977 DPRINT1("NtQuerySystemInformation - SystemVdmBopInformation not implemented\n");
978 return (STATUS_NOT_IMPLEMENTED);
979 }
980
981 /* Class 21 - File Cache Information */
982 QSI_DEF(SystemFileCacheInformation)
983 {
984 SYSTEM_CACHE_INFORMATION *Sci = (SYSTEM_CACHE_INFORMATION *) Buffer;
985
986 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
987 {
988 * ReqSize = sizeof (SYSTEM_CACHE_INFORMATION);
989 return (STATUS_INFO_LENGTH_MISMATCH);
990 }
991 /* Return the Byte size not the page size. */
992 Sci->CurrentSize =
993 MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE;
994 Sci->PeakSize =
995 MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE; /* FIXME */
996
997 Sci->PageFaultCount = 0; /* FIXME */
998 Sci->MinimumWorkingSet = 0; /* FIXME */
999 Sci->MaximumWorkingSet = 0; /* FIXME */
1000 Sci->TransitionSharedPages = 0; /* FIXME */
1001 Sci->TransitionSharedPagesPeak = 0; /* FIXME */
1002
1003 return (STATUS_SUCCESS);
1004 }
1005
1006 SSI_DEF(SystemFileCacheInformation)
1007 {
1008 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
1009 {
1010 return (STATUS_INFO_LENGTH_MISMATCH);
1011 }
1012 /* FIXME */
1013 DPRINT1("NtSetSystemInformation - SystemFileCacheInformation not implemented\n");
1014 return (STATUS_NOT_IMPLEMENTED);
1015 }
1016
1017 /* Class 22 - Pool Tag Information */
1018 QSI_DEF(SystemPoolTagInformation)
1019 {
1020 /* FIXME */
1021 DPRINT1("NtQuerySystemInformation - SystemPoolTagInformation not implemented\n");
1022 return (STATUS_NOT_IMPLEMENTED);
1023 }
1024
1025 /* Class 23 - Interrupt Information for all processors */
1026 QSI_DEF(SystemInterruptInformation)
1027 {
1028 PKPRCB Prcb;
1029 UINT i;
1030 ULONG ti;
1031 PSYSTEM_INTERRUPT_INFORMATION sii = (PSYSTEM_INTERRUPT_INFORMATION)Buffer;
1032
1033 if(Size < KeNumberProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION))
1034 {
1035 return (STATUS_INFO_LENGTH_MISMATCH);
1036 }
1037
1038 ti = KeQueryTimeIncrement();
1039
1040 Prcb = ((PKPCR)KPCR_BASE)->Prcb;
1041 for (i = 0; i < KeNumberProcessors; i++)
1042 {
1043 sii->ContextSwitches = Prcb->KeContextSwitches;
1044 sii->DpcCount = 0; /* FIXME */
1045 sii->DpcRate = 0; /* FIXME */
1046 sii->TimeIncrement = ti;
1047 sii->DpcBypassCount = 0; /* FIXME */
1048 sii->ApcBypassCount = 0; /* FIXME */
1049 sii++;
1050 Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
1051 }
1052
1053 return STATUS_SUCCESS;
1054 }
1055
1056 /* Class 24 - DPC Behaviour Information */
1057 QSI_DEF(SystemDpcBehaviourInformation)
1058 {
1059 /* FIXME */
1060 DPRINT1("NtQuerySystemInformation - SystemDpcBehaviourInformation not implemented\n");
1061 return (STATUS_NOT_IMPLEMENTED);
1062 }
1063
1064 SSI_DEF(SystemDpcBehaviourInformation)
1065 {
1066 /* FIXME */
1067 DPRINT1("NtSetSystemInformation - SystemDpcBehaviourInformation not implemented\n");
1068 return (STATUS_NOT_IMPLEMENTED);
1069 }
1070
1071 /* Class 25 - Full Memory Information */
1072 QSI_DEF(SystemFullMemoryInformation)
1073 {
1074 PULONG Spi = (PULONG) Buffer;
1075
1076 PEPROCESS TheIdleProcess;
1077
1078 * ReqSize = sizeof (ULONG);
1079
1080 if (sizeof (ULONG) != Size)
1081 {
1082 return (STATUS_INFO_LENGTH_MISMATCH);
1083 }
1084 DPRINT("SystemFullMemoryInformation\n");
1085
1086 TheIdleProcess = PsIdleProcess;
1087
1088 DPRINT("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
1089 TheIdleProcess->UniqueProcessId,
1090 TheIdleProcess->Pcb.KernelTime,
1091 MiFreeSwapPages,
1092 MiUsedSwapPages);
1093
1094 #ifndef NDEBUG
1095 MmPrintMemoryStatistic();
1096 #endif
1097
1098 *Spi = MiMemoryConsumers[MC_USER].PagesUsed;
1099
1100 return (STATUS_SUCCESS);
1101 }
1102
1103 /* Class 26 - Load Image */
1104 SSI_DEF(SystemLoadImage)
1105 {
1106 PSYSTEM_LOAD_IMAGE Sli = (PSYSTEM_LOAD_IMAGE)Buffer;
1107
1108 if (sizeof(SYSTEM_LOAD_IMAGE) != Size)
1109 {
1110 return(STATUS_INFO_LENGTH_MISMATCH);
1111 }
1112
1113 return(LdrpLoadImage(&Sli->ModuleName,
1114 &Sli->ModuleBase,
1115 &Sli->SectionPointer,
1116 &Sli->EntryPoint,
1117 &Sli->ExportDirectory));
1118 }
1119
1120 /* Class 27 - Unload Image */
1121 SSI_DEF(SystemUnloadImage)
1122 {
1123 PSYSTEM_UNLOAD_IMAGE Sui = (PSYSTEM_UNLOAD_IMAGE)Buffer;
1124
1125 if (sizeof(SYSTEM_UNLOAD_IMAGE) != Size)
1126 {
1127 return(STATUS_INFO_LENGTH_MISMATCH);
1128 }
1129
1130 return(LdrpUnloadImage(Sui->ModuleBase));
1131 }
1132
1133 /* Class 28 - Time Adjustment Information */
1134 QSI_DEF(SystemTimeAdjustmentInformation)
1135 {
1136 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT) > Size)
1137 {
1138 * ReqSize = sizeof (SYSTEM_SET_TIME_ADJUSTMENT);
1139 return (STATUS_INFO_LENGTH_MISMATCH);
1140 }
1141 /* FIXME: */
1142 DPRINT1("NtQuerySystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1143 return (STATUS_NOT_IMPLEMENTED);
1144 }
1145
1146 SSI_DEF(SystemTimeAdjustmentInformation)
1147 {
1148 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT) > Size)
1149 {
1150 return (STATUS_INFO_LENGTH_MISMATCH);
1151 }
1152 /* FIXME: */
1153 DPRINT1("NtSetSystemInformation - SystemTimeAdjustmentInformation not implemented\n");
1154 return (STATUS_NOT_IMPLEMENTED);
1155 }
1156
1157 /* Class 29 - Summary Memory Information */
1158 QSI_DEF(SystemSummaryMemoryInformation)
1159 {
1160 /* FIXME */
1161 DPRINT1("NtQuerySystemInformation - SystemSummaryMemoryInformation not implemented\n");
1162 return (STATUS_NOT_IMPLEMENTED);
1163 }
1164
1165 /* Class 30 - Next Event Id Information */
1166 QSI_DEF(SystemNextEventIdInformation)
1167 {
1168 /* FIXME */
1169 DPRINT1("NtQuerySystemInformation - SystemNextEventIdInformation not implemented\n");
1170 return (STATUS_NOT_IMPLEMENTED);
1171 }
1172
1173 /* Class 31 - Event Ids Information */
1174 QSI_DEF(SystemEventIdsInformation)
1175 {
1176 /* FIXME */
1177 DPRINT1("NtQuerySystemInformation - SystemEventIdsInformation not implemented\n");
1178 return (STATUS_NOT_IMPLEMENTED);
1179 }
1180
1181 /* Class 32 - Crash Dump Information */
1182 QSI_DEF(SystemCrashDumpInformation)
1183 {
1184 /* FIXME */
1185 DPRINT1("NtQuerySystemInformation - SystemCrashDumpInformation not implemented\n");
1186 return (STATUS_NOT_IMPLEMENTED);
1187 }
1188
1189 /* Class 33 - Exception Information */
1190 QSI_DEF(SystemExceptionInformation)
1191 {
1192 /* FIXME */
1193 DPRINT1("NtQuerySystemInformation - SystemExceptionInformation not implemented\n");
1194 return (STATUS_NOT_IMPLEMENTED);
1195 }
1196
1197 /* Class 34 - Crash Dump State Information */
1198 QSI_DEF(SystemCrashDumpStateInformation)
1199 {
1200 /* FIXME */
1201 DPRINT1("NtQuerySystemInformation - SystemCrashDumpStateInformation not implemented\n");
1202 return (STATUS_NOT_IMPLEMENTED);
1203 }
1204
1205 /* Class 35 - Kernel Debugger Information */
1206 QSI_DEF(SystemKernelDebuggerInformation)
1207 {
1208 /* FIXME */
1209 DPRINT1("NtQuerySystemInformation - SystemKernelDebuggerInformation not implemented\n");
1210 return (STATUS_NOT_IMPLEMENTED);
1211 }
1212
1213 /* Class 36 - Context Switch Information */
1214 QSI_DEF(SystemContextSwitchInformation)
1215 {
1216 /* FIXME */
1217 DPRINT1("NtQuerySystemInformation - SystemContextSwitchInformation not implemented\n");
1218 return (STATUS_NOT_IMPLEMENTED);
1219 }
1220
1221 /* Class 37 - Registry Quota Information */
1222 QSI_DEF(SystemRegistryQuotaInformation)
1223 {
1224 PSYSTEM_REGISTRY_QUOTA_INFORMATION srqi = (PSYSTEM_REGISTRY_QUOTA_INFORMATION) Buffer;
1225
1226 *ReqSize = sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION);
1227 if (Size < sizeof(SYSTEM_REGISTRY_QUOTA_INFORMATION))
1228 {
1229 return STATUS_INFO_LENGTH_MISMATCH;
1230 }
1231
1232 DPRINT1("Faking max registry size of 32 MB\n");
1233 srqi->RegistryQuotaAllowed = 0x2000000;
1234 srqi->RegistryQuotaUsed = 0x200000;
1235 srqi->Reserved1 = (void*)0x200000;
1236
1237 return STATUS_SUCCESS;
1238 }
1239
1240 SSI_DEF(SystemRegistryQuotaInformation)
1241 {
1242 /* FIXME */
1243 DPRINT1("NtSetSystemInformation - SystemRegistryQuotaInformation not implemented\n");
1244 return (STATUS_NOT_IMPLEMENTED);
1245 }
1246
1247 /* Class 38 - Load And Call Image */
1248 SSI_DEF(SystemLoadAndCallImage)
1249 {
1250 PSYSTEM_LOAD_AND_CALL_IMAGE Slci = (PSYSTEM_LOAD_AND_CALL_IMAGE)Buffer;
1251
1252 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE) != Size)
1253 {
1254 return(STATUS_INFO_LENGTH_MISMATCH);
1255 }
1256
1257 return(LdrpLoadAndCallImage(&Slci->ModuleName));
1258 }
1259
1260 /* Class 39 - Priority Separation */
1261 SSI_DEF(SystemPrioritySeperation)
1262 {
1263 /* FIXME */
1264 DPRINT1("NtSetSystemInformation - SystemPrioritySeperation not implemented\n");
1265 return (STATUS_NOT_IMPLEMENTED);
1266 }
1267
1268 /* Class 40 - Plug Play Bus Information */
1269 QSI_DEF(SystemPlugPlayBusInformation)
1270 {
1271 /* FIXME */
1272 DPRINT1("NtQuerySystemInformation - SystemPlugPlayBusInformation not implemented\n");
1273 return (STATUS_NOT_IMPLEMENTED);
1274 }
1275
1276 /* Class 41 - Dock Information */
1277 QSI_DEF(SystemDockInformation)
1278 {
1279 /* FIXME */
1280 DPRINT1("NtQuerySystemInformation - SystemDockInformation not implemented\n");
1281 return (STATUS_NOT_IMPLEMENTED);
1282 }
1283
1284 /* Class 42 - Power Information */
1285 QSI_DEF(SystemPowerInformation)
1286 {
1287 /* FIXME */
1288 DPRINT1("NtQuerySystemInformation - SystemPowerInformation not implemented\n");
1289 return (STATUS_NOT_IMPLEMENTED);
1290 }
1291
1292 /* Class 43 - Processor Speed Information */
1293 QSI_DEF(SystemProcessorSpeedInformation)
1294 {
1295 /* FIXME */
1296 DPRINT1("NtQuerySystemInformation - SystemProcessorSpeedInformation not implemented\n");
1297 return (STATUS_NOT_IMPLEMENTED);
1298 }
1299
1300 /* Class 44 - Current Time Zone Information */
1301 QSI_DEF(SystemCurrentTimeZoneInformation)
1302 {
1303 * ReqSize = sizeof (TIME_ZONE_INFORMATION);
1304
1305 if (sizeof (TIME_ZONE_INFORMATION) != Size)
1306 {
1307 return STATUS_INFO_LENGTH_MISMATCH;
1308 }
1309
1310 /* Copy the time zone information struct */
1311 memcpy(Buffer,
1312 &ExpTimeZoneInfo,
1313 sizeof(TIME_ZONE_INFORMATION));
1314
1315 return STATUS_SUCCESS;
1316 }
1317
1318
1319 SSI_DEF(SystemCurrentTimeZoneInformation)
1320 {
1321 /* Check user buffer's size */
1322 if (Size < sizeof (TIME_ZONE_INFORMATION))
1323 {
1324 return STATUS_INFO_LENGTH_MISMATCH;
1325 }
1326
1327 return ExpSetTimeZoneInformation((PTIME_ZONE_INFORMATION)Buffer);
1328 }
1329
1330
1331 /* Class 45 - Lookaside Information */
1332 QSI_DEF(SystemLookasideInformation)
1333 {
1334 /* FIXME */
1335 DPRINT1("NtQuerySystemInformation - SystemLookasideInformation not implemented\n");
1336 return (STATUS_NOT_IMPLEMENTED);
1337 }
1338
1339
1340 /* Class 46 - Set time slip event */
1341 SSI_DEF(SystemSetTimeSlipEvent)
1342 {
1343 /* FIXME */
1344 DPRINT1("NtSetSystemInformation - SystemSetTimSlipEvent not implemented\n");
1345 return (STATUS_NOT_IMPLEMENTED);
1346 }
1347
1348
1349 /* Class 47 - Create a new session (TSE) */
1350 SSI_DEF(SystemCreateSession)
1351 {
1352 /* FIXME */
1353 DPRINT1("NtSetSystemInformation - SystemCreateSession not implemented\n");
1354 return (STATUS_NOT_IMPLEMENTED);
1355 }
1356
1357
1358 /* Class 48 - Delete an existing session (TSE) */
1359 SSI_DEF(SystemDeleteSession)
1360 {
1361 /* FIXME */
1362 DPRINT1("NtSetSystemInformation - SystemDeleteSession not implemented\n");
1363 return (STATUS_NOT_IMPLEMENTED);
1364 }
1365
1366
1367 /* Class 49 - UNKNOWN */
1368 QSI_DEF(SystemInvalidInfoClass4)
1369 {
1370 /* FIXME */
1371 DPRINT1("NtQuerySystemInformation - SystemInvalidInfoClass4 not implemented\n");
1372 return (STATUS_NOT_IMPLEMENTED);
1373 }
1374
1375
1376 /* Class 50 - System range start address */
1377 QSI_DEF(SystemRangeStartInformation)
1378 {
1379 /* FIXME */
1380 DPRINT1("NtQuerySystemInformation - SystemRangeStartInformation not implemented\n");
1381 return (STATUS_NOT_IMPLEMENTED);
1382 }
1383
1384
1385 /* Class 51 - Driver verifier information */
1386 QSI_DEF(SystemVerifierInformation)
1387 {
1388 /* FIXME */
1389 DPRINT1("NtQuerySystemInformation - SystemVerifierInformation not implemented\n");
1390 return (STATUS_NOT_IMPLEMENTED);
1391 }
1392
1393
1394 SSI_DEF(SystemVerifierInformation)
1395 {
1396 /* FIXME */
1397 DPRINT1("NtSetSystemInformation - SystemVerifierInformation not implemented\n");
1398 return (STATUS_NOT_IMPLEMENTED);
1399 }
1400
1401
1402 /* Class 52 - Add a driver verifier */
1403 SSI_DEF(SystemAddVerifier)
1404 {
1405 /* FIXME */
1406 DPRINT1("NtSetSystemInformation - SystemAddVerifier not implemented\n");
1407 return (STATUS_NOT_IMPLEMENTED);
1408 }
1409
1410
1411 /* Class 53 - A session's processes */
1412 QSI_DEF(SystemSessionProcessesInformation)
1413 {
1414 /* FIXME */
1415 DPRINT1("NtQuerySystemInformation - SystemSessionProcessInformation not implemented\n");
1416 return (STATUS_NOT_IMPLEMENTED);
1417 }
1418
1419
1420 /* Query/Set Calls Table */
1421 typedef
1422 struct _QSSI_CALLS
1423 {
1424 NTSTATUS (* Query) (PVOID,ULONG,PULONG);
1425 NTSTATUS (* Set) (PVOID,ULONG);
1426
1427 } QSSI_CALLS;
1428
1429 // QS Query & Set
1430 // QX Query
1431 // XS Set
1432 // XX unknown behaviour
1433 //
1434 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1435 #define SI_QX(n) {QSI_USE(n),NULL}
1436 #define SI_XS(n) {NULL,SSI_USE(n)}
1437 #define SI_XX(n) {NULL,NULL}
1438
1439 static
1440 QSSI_CALLS
1441 CallQS [] =
1442 {
1443 SI_QX(SystemBasicInformation),
1444 SI_QX(SystemProcessorInformation),
1445 SI_QX(SystemPerformanceInformation),
1446 SI_QX(SystemTimeOfDayInformation),
1447 SI_QX(SystemPathInformation), /* should be SI_XX */
1448 SI_QX(SystemProcessInformation),
1449 SI_QX(SystemCallCountInformation),
1450 SI_QX(SystemDeviceInformation),
1451 SI_QX(SystemProcessorPerformanceInformation),
1452 SI_QS(SystemFlagsInformation),
1453 SI_QX(SystemCallTimeInformation), /* should be SI_XX */
1454 SI_QX(SystemModuleInformation),
1455 SI_QX(SystemLocksInformation),
1456 SI_QX(SystemStackTraceInformation), /* should be SI_XX */
1457 SI_QX(SystemPagedPoolInformation), /* should be SI_XX */
1458 SI_QX(SystemNonPagedPoolInformation), /* should be SI_XX */
1459 SI_QX(SystemHandleInformation),
1460 SI_QX(SystemObjectInformation),
1461 SI_QX(SystemPageFileInformation),
1462 SI_QX(SystemVdmInstemulInformation),
1463 SI_QX(SystemVdmBopInformation), /* it should be SI_XX */
1464 SI_QS(SystemFileCacheInformation),
1465 SI_QX(SystemPoolTagInformation),
1466 SI_QX(SystemInterruptInformation),
1467 SI_QS(SystemDpcBehaviourInformation),
1468 SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */
1469 SI_XS(SystemLoadImage),
1470 SI_XS(SystemUnloadImage),
1471 SI_QS(SystemTimeAdjustmentInformation),
1472 SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */
1473 SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */
1474 SI_QX(SystemEventIdsInformation), /* it should be SI_XX */
1475 SI_QX(SystemCrashDumpInformation),
1476 SI_QX(SystemExceptionInformation),
1477 SI_QX(SystemCrashDumpStateInformation),
1478 SI_QX(SystemKernelDebuggerInformation),
1479 SI_QX(SystemContextSwitchInformation),
1480 SI_QS(SystemRegistryQuotaInformation),
1481 SI_XS(SystemLoadAndCallImage),
1482 SI_XS(SystemPrioritySeperation),
1483 SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */
1484 SI_QX(SystemDockInformation), /* it should be SI_XX */
1485 SI_QX(SystemPowerInformation), /* it should be SI_XX */
1486 SI_QX(SystemProcessorSpeedInformation), /* it should be SI_XX */
1487 SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */
1488 SI_QX(SystemLookasideInformation),
1489 SI_XS(SystemSetTimeSlipEvent),
1490 SI_XS(SystemCreateSession),
1491 SI_XS(SystemDeleteSession),
1492 SI_QX(SystemInvalidInfoClass4), /* it should be SI_XX */
1493 SI_QX(SystemRangeStartInformation),
1494 SI_QS(SystemVerifierInformation),
1495 SI_XS(SystemAddVerifier),
1496 SI_QX(SystemSessionProcessesInformation)
1497 };
1498
1499
1500 /*
1501 * @implemented
1502 */
1503 NTSTATUS STDCALL
1504 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1505 OUT PVOID UnsafeSystemInformation,
1506 IN ULONG Length,
1507 OUT PULONG UnsafeResultLength)
1508 {
1509 ULONG ResultLength;
1510 PVOID SystemInformation;
1511 NTSTATUS Status;
1512 NTSTATUS FStatus;
1513
1514 PAGED_CODE();
1515
1516 /* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
1517 SystemInformationClass );
1518 */
1519 /*if (ExGetPreviousMode() == KernelMode)
1520 {*/
1521 SystemInformation = UnsafeSystemInformation;
1522 /*}
1523 else
1524 {
1525 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1526 if (SystemInformation == NULL)
1527 {
1528 return(STATUS_NO_MEMORY);
1529 }
1530 }*/
1531
1532 /* Clear user buffer. */
1533 RtlZeroMemory(SystemInformation, Length);
1534
1535 /*
1536 * Check the request is valid.
1537 */
1538 if ((SystemInformationClass >= SystemInformationClassMin) &&
1539 (SystemInformationClass < SystemInformationClassMax))
1540 {
1541 if (NULL != CallQS [SystemInformationClass].Query)
1542 {
1543 /*
1544 * Hand the request to a subhandler.
1545 */
1546 FStatus = CallQS [SystemInformationClass].Query(SystemInformation,
1547 Length,
1548 &ResultLength);
1549 /*if (ExGetPreviousMode() != KernelMode)
1550 {
1551 Status = MmCopyToCaller(UnsafeSystemInformation,
1552 SystemInformation,
1553 Length);
1554 ExFreePool(SystemInformation);
1555 if (!NT_SUCCESS(Status))
1556 {
1557 return(Status);
1558 }
1559 }*/
1560 if (UnsafeResultLength != NULL)
1561 {
1562 /*if (ExGetPreviousMode() == KernelMode)
1563 {
1564 *UnsafeResultLength = ResultLength;
1565 }
1566 else
1567 {*/
1568 Status = MmCopyToCaller(UnsafeResultLength,
1569 &ResultLength,
1570 sizeof(ULONG));
1571 if (!NT_SUCCESS(Status))
1572 {
1573 return(Status);
1574 }
1575 /*}*/
1576 }
1577 return(FStatus);
1578 }
1579 }
1580 return (STATUS_INVALID_INFO_CLASS);
1581 }
1582
1583
1584 NTSTATUS
1585 STDCALL
1586 NtSetSystemInformation (
1587 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1588 IN PVOID SystemInformation,
1589 IN ULONG SystemInformationLength
1590 )
1591 {
1592 PAGED_CODE();
1593
1594 /*
1595 * If called from user mode, check
1596 * possible unsafe arguments.
1597 */
1598 #if 0
1599 if (KernelMode != KeGetPreviousMode())
1600 {
1601 // Check arguments
1602 //ProbeForWrite(
1603 // SystemInformation,
1604 // Length
1605 // );
1606 //ProbeForWrite(
1607 // ResultLength,
1608 // sizeof (ULONG)
1609 // );
1610 }
1611 #endif
1612 /*
1613 * Check the request is valid.
1614 */
1615 if ( (SystemInformationClass >= SystemInformationClassMin)
1616 && (SystemInformationClass < SystemInformationClassMax)
1617 )
1618 {
1619 if (NULL != CallQS [SystemInformationClass].Set)
1620 {
1621 /*
1622 * Hand the request to a subhandler.
1623 */
1624 return CallQS [SystemInformationClass].Set (
1625 SystemInformation,
1626 SystemInformationLength
1627 );
1628 }
1629 }
1630 return (STATUS_INVALID_INFO_CLASS);
1631 }
1632
1633
1634 NTSTATUS
1635 STDCALL
1636 NtFlushInstructionCache (
1637 IN HANDLE ProcessHandle,
1638 IN PVOID BaseAddress,
1639 IN UINT NumberOfBytesToFlush
1640 )
1641 {
1642 PAGED_CODE();
1643
1644 __asm__("wbinvd\n");
1645 return STATUS_SUCCESS;
1646 }
1647
1648
1649 /* EOF */