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