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