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