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