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