NtAllocateVirtualMemory() should return 64k aligned areas
[reactos.git] / reactos / ntoskrnl / ex / sysinfo.c
1 /* $Id: sysinfo.c,v 1.47 2004/09/28 19:49:20 gvg Exp $
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 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 * 20/03/2003: implemented querying SystemProcessInformation,
11 * no more copying to-from the caller (Aleksey
12 * Bragin <aleksey@studiocerebral.com>)
13 */
14
15 /* INCLUDES *****************************************************************/
16
17 #include <ntoskrnl.h>
18 #define NDEBUG
19 #include <internal/debug.h>
20
21 extern ULONG NtGlobalFlag; /* FIXME: it should go in a ddk/?.h */
22 ULONGLONG STDCALL KeQueryInterruptTime(VOID);
23
24 VOID MmPrintMemoryStatistic(VOID);
25
26 extern ULONG Ke386CpuidFlags;
27 extern ULONG Ke386Cpuid;
28
29 /* FUNCTIONS *****************************************************************/
30
31 /*
32 * @unimplemented
33 */
34 VOID
35 STDCALL
36 ExEnumHandleTable (
37 PULONG HandleTable,
38 PVOID Callback,
39 PVOID Param,
40 PHANDLE Handle OPTIONAL
41 )
42 {
43 UNIMPLEMENTED;
44 }
45
46 /*
47 * @unimplemented
48 */
49 VOID
50 STDCALL
51 ExGetCurrentProcessorCounts (
52 PVOID IdleThreadTime,
53 PVOID SystemTime,
54 PVOID Number
55 )
56 {
57 UNIMPLEMENTED;
58 }
59 /*
60 * @unimplemented
61 */
62 VOID
63 STDCALL
64 ExGetCurrentProcessorCpuUsage (
65 PVOID RetVal
66 )
67 {
68 UNIMPLEMENTED;
69 }
70
71 NTSTATUS STDCALL
72 NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
73 OUT PVOID UnsafeValue,
74 IN ULONG Length,
75 IN OUT PULONG UnsafeReturnLength)
76 {
77 NTSTATUS Status;
78 ANSI_STRING AName;
79 UNICODE_STRING WName;
80 BOOLEAN Result;
81 PCH Value;
82 ANSI_STRING AValue;
83 UNICODE_STRING WValue;
84 ULONG ReturnLength;
85
86 /*
87 * Copy the name to kernel space if necessary and convert it to ANSI.
88 */
89 if (ExGetPreviousMode() != KernelMode)
90 {
91 Status = RtlCaptureUnicodeString(&WName, UnsafeName);
92 if (!NT_SUCCESS(Status))
93 {
94 return(Status);
95 }
96 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
97 if (!NT_SUCCESS(Status))
98 {
99 return(Status);
100 }
101 }
102 else
103 {
104 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
105 if (!NT_SUCCESS(Status))
106 {
107 return(Status);
108 }
109 }
110
111 /*
112 * Create a temporary buffer for the value
113 */
114 Value = ExAllocatePool(NonPagedPool, Length);
115 if (Value == NULL)
116 {
117 RtlFreeAnsiString(&AName);
118 if (ExGetPreviousMode() != KernelMode)
119 {
120 RtlFreeUnicodeString(&WName);
121 }
122 return(STATUS_NO_MEMORY);
123 }
124
125 /*
126 * Get the environment variable
127 */
128 Result = HalGetEnvironmentVariable(AName.Buffer, Value, Length);
129 if (!Result)
130 {
131 RtlFreeAnsiString(&AName);
132 if (ExGetPreviousMode() != KernelMode)
133 {
134 RtlFreeUnicodeString(&WName);
135 }
136 ExFreePool(Value);
137 return(STATUS_UNSUCCESSFUL);
138 }
139
140 /*
141 * Convert the result to UNICODE.
142 */
143 RtlInitAnsiString(&AValue, Value);
144 Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
145 if (!NT_SUCCESS(Status))
146 {
147 RtlFreeAnsiString(&AName);
148 if (ExGetPreviousMode() != KernelMode)
149 {
150 RtlFreeUnicodeString(&WName);
151 }
152 ExFreePool(Value);
153 return(Status);
154 }
155 ReturnLength = WValue.Length;
156
157 /*
158 * Copy the result back to the caller.
159 */
160 if (ExGetPreviousMode() != KernelMode)
161 {
162 Status = MmCopyToCaller(UnsafeValue, WValue.Buffer, ReturnLength);
163 if (!NT_SUCCESS(Status))
164 {
165 RtlFreeAnsiString(&AName);
166 if (ExGetPreviousMode() != KernelMode)
167 {
168 RtlFreeUnicodeString(&WName);
169 }
170 ExFreePool(Value);
171 RtlFreeUnicodeString(&WValue);
172 return(Status);
173 }
174
175 Status = MmCopyToCaller(UnsafeReturnLength, &ReturnLength,
176 sizeof(ULONG));
177 if (!NT_SUCCESS(Status))
178 {
179 RtlFreeAnsiString(&AName);
180 if (ExGetPreviousMode() != KernelMode)
181 {
182 RtlFreeUnicodeString(&WName);
183 }
184 ExFreePool(Value);
185 RtlFreeUnicodeString(&WValue);
186 return(Status);
187 }
188 }
189 else
190 {
191 memcpy(UnsafeValue, WValue.Buffer, ReturnLength);
192 memcpy(UnsafeReturnLength, &ReturnLength, sizeof(ULONG));
193 }
194
195 /*
196 * Free temporary buffers.
197 */
198 RtlFreeAnsiString(&AName);
199 if (ExGetPreviousMode() != KernelMode)
200 {
201 RtlFreeUnicodeString(&WName);
202 }
203 ExFreePool(Value);
204 RtlFreeUnicodeString(&WValue);
205
206 return(STATUS_SUCCESS);
207 }
208
209
210 NTSTATUS STDCALL
211 NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
212 IN PUNICODE_STRING UnsafeValue)
213 {
214 UNICODE_STRING WName;
215 ANSI_STRING AName;
216 UNICODE_STRING WValue;
217 ANSI_STRING AValue;
218 BOOLEAN Result;
219 NTSTATUS Status;
220
221 /*
222 * Check for required privilege.
223 */
224 /* FIXME: Not implemented. */
225
226 /*
227 * Copy the name to kernel space if necessary and convert it to ANSI.
228 */
229 if (ExGetPreviousMode() != KernelMode)
230 {
231 Status = RtlCaptureUnicodeString(&WName, UnsafeName);
232 if (!NT_SUCCESS(Status))
233 {
234 return(Status);
235 }
236 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
237 if (!NT_SUCCESS(Status))
238 {
239 return(Status);
240 }
241 }
242 else
243 {
244 Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
245 if (!NT_SUCCESS(Status))
246 {
247 return(Status);
248 }
249 }
250
251 /*
252 * Copy the value to kernel space and convert to ANSI.
253 */
254 if (ExGetPreviousMode() != KernelMode)
255 {
256 Status = RtlCaptureUnicodeString(&WValue, UnsafeValue);
257 if (!NT_SUCCESS(Status))
258 {
259 RtlFreeUnicodeString(&WName);
260 RtlFreeAnsiString(&AName);
261 return(Status);
262 }
263 Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
264 if (!NT_SUCCESS(Status))
265 {
266 RtlFreeUnicodeString(&WName);
267 RtlFreeAnsiString(&AName);
268 RtlFreeUnicodeString(&WValue);
269 return(Status);
270 }
271 }
272 else
273 {
274 Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
275 if (!NT_SUCCESS(Status))
276 {
277 RtlFreeAnsiString(&AName);
278 return(Status);
279 }
280 }
281
282 /*
283 * Set the environment variable
284 */
285 Result = HalSetEnvironmentVariable(AName.Buffer, AValue.Buffer);
286
287 /*
288 * Free everything and return status.
289 */
290 RtlFreeAnsiString(&AName);
291 RtlFreeAnsiString(&AValue);
292 if (ExGetPreviousMode() != KernelMode)
293 {
294 RtlFreeUnicodeString(&WName);
295 RtlFreeUnicodeString(&WValue);
296 }
297
298 if (!Result)
299 {
300 return(STATUS_UNSUCCESSFUL);
301 }
302 return(STATUS_SUCCESS);
303 }
304
305
306 /* --- Query/Set System Information --- */
307
308 /*
309 * NOTE: QSI_DEF(n) and SSI_DEF(n) define _cdecl function symbols
310 * so the stack is popped only in one place on x86 platform.
311 */
312 #define QSI_USE(n) QSI##n
313 #define QSI_DEF(n) \
314 static NTSTATUS QSI_USE(n) (PVOID Buffer, ULONG Size, PULONG ReqSize)
315
316 #define SSI_USE(n) SSI##n
317 #define SSI_DEF(n) \
318 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
319
320
321 /* Class 0 - Basic Information */
322 QSI_DEF(SystemBasicInformation)
323 {
324 PSYSTEM_BASIC_INFORMATION Sbi
325 = (PSYSTEM_BASIC_INFORMATION) Buffer;
326
327 *ReqSize = sizeof (SYSTEM_BASIC_INFORMATION);
328 /*
329 * Check user buffer's size
330 */
331 if (Size < sizeof (SYSTEM_BASIC_INFORMATION))
332 {
333 return (STATUS_INFO_LENGTH_MISMATCH);
334 }
335 Sbi->Unknown = 0;
336 Sbi->MaximumIncrement = 100000; /* FIXME */
337 Sbi->PhysicalPageSize = PAGE_SIZE; /* FIXME: it should be PAGE_SIZE */
338 Sbi->NumberOfPhysicalPages = MmStats.NrTotalPages;
339 Sbi->LowestPhysicalPage = 0; /* FIXME */
340 Sbi->HighestPhysicalPage = MmStats.NrTotalPages; /* FIXME */
341 Sbi->AllocationGranularity = MM_VIRTMEM_GRANULARITY; /* hard coded on Intel? */
342 Sbi->LowestUserAddress = 0x10000; /* Top of 64k */
343 Sbi->HighestUserAddress = (ULONG_PTR)MmHighestUserAddress;
344 Sbi->ActiveProcessors = 0x00000001; /* FIXME */
345 Sbi->NumberProcessors = KeNumberProcessors;
346 return (STATUS_SUCCESS);
347 }
348
349 /* Class 1 - Processor Information */
350 QSI_DEF(SystemProcessorInformation)
351 {
352 PSYSTEM_PROCESSOR_INFORMATION Spi
353 = (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
354
355 *ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION);
356 /*
357 * Check user buffer's size
358 */
359 if (Size < sizeof (SYSTEM_PROCESSOR_INFORMATION))
360 {
361 return (STATUS_INFO_LENGTH_MISMATCH);
362 }
363 Spi->ProcessorArchitecture = 0; /* Intel Processor */
364 Spi->ProcessorLevel = ((Ke386Cpuid >> 8) & 0xf);
365 Spi->ProcessorRevision = (Ke386Cpuid & 0xf) | ((Ke386Cpuid << 4) & 0xf00);
366 Spi->Unknown = 0;
367 Spi->FeatureBits = Ke386CpuidFlags;
368
369 DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture,
370 Spi->ProcessorLevel, Spi->ProcessorRevision);
371
372 return (STATUS_SUCCESS);
373 }
374
375 /* Class 2 - Performance Information */
376 QSI_DEF(SystemPerformanceInformation)
377 {
378 PSYSTEM_PERFORMANCE_INFORMATION Spi
379 = (PSYSTEM_PERFORMANCE_INFORMATION) Buffer;
380
381 PEPROCESS TheIdleProcess;
382
383 *ReqSize = sizeof (SYSTEM_PERFORMANCE_INFORMATION);
384 /*
385 * Check user buffer's size
386 */
387 if (Size < sizeof (SYSTEM_PERFORMANCE_INFORMATION))
388 {
389 return (STATUS_INFO_LENGTH_MISMATCH);
390 }
391
392 PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
393
394 Spi->IdleTime.QuadPart = TheIdleProcess->Pcb.KernelTime * 100000LL;
395
396 Spi->ReadTransferCount.QuadPart = IoReadTransferCount;
397 Spi->WriteTransferCount.QuadPart = IoWriteTransferCount;
398 Spi->OtherTransferCount.QuadPart = IoOtherTransferCount;
399 Spi->ReadOperationCount = IoReadOperationCount;
400 Spi->WriteOperationCount = IoWriteOperationCount;
401 Spi->OtherOperationCount = IoOtherOperationCount;
402
403 Spi->AvailablePages = MmStats.NrFreePages;
404 /*
405 Add up all the used "Commitied" memory + pagefile.
406 Not sure this is right. 8^\
407 */
408 Spi->TotalCommittedPages = MiMemoryConsumers[MC_PPOOL].PagesUsed +
409 MiMemoryConsumers[MC_NPPOOL].PagesUsed+
410 MiMemoryConsumers[MC_CACHE].PagesUsed+
411 MiMemoryConsumers[MC_USER].PagesUsed+
412 MiUsedSwapPages;
413 /*
414 Add up the full system total + pagefile.
415 All this make Taskmgr happy but not sure it is the right numbers.
416 This too, fixes some of GlobalMemoryStatusEx numbers.
417 */
418 Spi->TotalCommitLimit = MmStats.NrTotalPages + MiFreeSwapPages +
419 MiUsedSwapPages;
420
421 Spi->PeakCommitment = 0; /* FIXME */
422 Spi->PageFaults = 0; /* FIXME */
423 Spi->WriteCopyFaults = 0; /* FIXME */
424 Spi->TransitionFaults = 0; /* FIXME */
425 Spi->CacheTransitionFaults = 0; /* FIXME */
426 Spi->DemandZeroFaults = 0; /* FIXME */
427 Spi->PagesRead = 0; /* FIXME */
428 Spi->PageReadIos = 0; /* FIXME */
429 Spi->CacheReads = 0; /* FIXME */
430 Spi->CacheIos = 0; /* FIXME */
431 Spi->PagefilePagesWritten = 0; /* FIXME */
432 Spi->PagefilePageWriteIos = 0; /* FIXME */
433 Spi->MappedFilePagesWritten = 0; /* FIXME */
434 Spi->MappedFilePageWriteIos = 0; /* FIXME */
435
436 Spi->PagedPoolUsage = MiMemoryConsumers[MC_PPOOL].PagesUsed;
437 Spi->PagedPoolAllocs = 0; /* FIXME */
438 Spi->PagedPoolFrees = 0; /* FIXME */
439 Spi->NonPagedPoolUsage = MiMemoryConsumers[MC_NPPOOL].PagesUsed;
440 Spi->NonPagedPoolAllocs = 0; /* FIXME */
441 Spi->NonPagedPoolFrees = 0; /* FIXME */
442
443 Spi->TotalFreeSystemPtes = 0; /* FIXME */
444
445 Spi->SystemCodePage = MmStats.NrSystemPages; /* FIXME */
446
447 Spi->TotalSystemDriverPages = 0; /* FIXME */
448 Spi->TotalSystemCodePages = 0; /* FIXME */
449 Spi->SmallNonPagedLookasideListAllocateHits = 0; /* FIXME */
450 Spi->SmallPagedLookasideListAllocateHits = 0; /* FIXME */
451 Spi->Reserved3 = 0; /* FIXME */
452
453 Spi->MmSystemCachePage = MiMemoryConsumers[MC_CACHE].PagesUsed;
454 Spi->PagedPoolPage = MmPagedPoolSize; /* FIXME */
455
456 Spi->SystemDriverPage = 0; /* FIXME */
457 Spi->FastReadNoWait = 0; /* FIXME */
458 Spi->FastReadWait = 0; /* FIXME */
459 Spi->FastReadResourceMiss = 0; /* FIXME */
460 Spi->FastReadNotPossible = 0; /* FIXME */
461
462 Spi->FastMdlReadNoWait = 0; /* FIXME */
463 Spi->FastMdlReadWait = 0; /* FIXME */
464 Spi->FastMdlReadResourceMiss = 0; /* FIXME */
465 Spi->FastMdlReadNotPossible = 0; /* FIXME */
466
467 Spi->MapDataNoWait = 0; /* FIXME */
468 Spi->MapDataWait = 0; /* FIXME */
469 Spi->MapDataNoWaitMiss = 0; /* FIXME */
470 Spi->MapDataWaitMiss = 0; /* FIXME */
471
472 Spi->PinMappedDataCount = 0; /* FIXME */
473 Spi->PinReadNoWait = 0; /* FIXME */
474 Spi->PinReadWait = 0; /* FIXME */
475 Spi->PinReadNoWaitMiss = 0; /* FIXME */
476 Spi->PinReadWaitMiss = 0; /* FIXME */
477 Spi->CopyReadNoWait = 0; /* FIXME */
478 Spi->CopyReadWait = 0; /* FIXME */
479 Spi->CopyReadNoWaitMiss = 0; /* FIXME */
480 Spi->CopyReadWaitMiss = 0; /* FIXME */
481
482 Spi->MdlReadNoWait = 0; /* FIXME */
483 Spi->MdlReadWait = 0; /* FIXME */
484 Spi->MdlReadNoWaitMiss = 0; /* FIXME */
485 Spi->MdlReadWaitMiss = 0; /* FIXME */
486 Spi->ReadAheadIos = 0; /* FIXME */
487 Spi->LazyWriteIos = 0; /* FIXME */
488 Spi->LazyWritePages = 0; /* FIXME */
489 Spi->DataFlushes = 0; /* FIXME */
490 Spi->DataPages = 0; /* FIXME */
491 Spi->ContextSwitches = 0; /* FIXME */
492 Spi->FirstLevelTbFills = 0; /* FIXME */
493 Spi->SecondLevelTbFills = 0; /* FIXME */
494 Spi->SystemCalls = 0; /* FIXME */
495
496 ObDereferenceObject(TheIdleProcess);
497
498 return (STATUS_SUCCESS);
499 }
500
501 /* Class 3 - Time Of Day Information */
502 QSI_DEF(SystemTimeOfDayInformation)
503 {
504 LARGE_INTEGER CurrentTime;
505
506 PSYSTEM_TIMEOFDAY_INFORMATION Sti
507 = (PSYSTEM_TIMEOFDAY_INFORMATION) Buffer;
508
509 *ReqSize = sizeof (SYSTEM_TIMEOFDAY_INFORMATION);
510 /*
511 * Check user buffer's size
512 */
513 if (Size < sizeof (SYSTEM_TIMEOFDAY_INFORMATION))
514 {
515 return (STATUS_INFO_LENGTH_MISMATCH);
516 }
517
518 KeQuerySystemTime(&CurrentTime);
519
520 Sti->BootTime= SystemBootTime;
521 Sti->CurrentTime = CurrentTime;
522 Sti->TimeZoneBias.QuadPart = _SystemTimeZoneInfo.Bias;
523 Sti->TimeZoneId = 0; /* FIXME */
524 Sti->Reserved = 0; /* FIXME */
525
526 return (STATUS_SUCCESS);
527 }
528
529 /* Class 4 - Path Information */
530 QSI_DEF(SystemPathInformation)
531 {
532 /* FIXME: QSI returns STATUS_BREAKPOINT. Why? */
533 return (STATUS_BREAKPOINT);
534 }
535
536 /* Class 5 - Process Information */
537 QSI_DEF(SystemProcessInformation)
538 {
539 ULONG ovlSize=0, nThreads;
540 PEPROCESS pr, syspr;
541 unsigned char *pCur;
542
543 /* scan the process list */
544
545 PSYSTEM_PROCESSES Spi
546 = (PSYSTEM_PROCESSES) Buffer;
547
548 *ReqSize = sizeof(SYSTEM_PROCESSES);
549
550 if (Size < sizeof(SYSTEM_PROCESSES))
551 {
552 return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
553 }
554
555 syspr = PsGetNextProcess(NULL);
556 pr = syspr;
557 pCur = (unsigned char *)Spi;
558
559 do
560 {
561 PSYSTEM_PROCESSES SpiCur;
562 int curSize, i = 0;
563 ANSI_STRING imgName;
564 int inLen=32; // image name len in bytes
565 PLIST_ENTRY current_entry;
566 PETHREAD current;
567
568 SpiCur = (PSYSTEM_PROCESSES)pCur;
569
570 nThreads = PsEnumThreadsByProcess(pr);
571
572 // size of the structure for every process
573 curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*nThreads;
574 ovlSize += curSize+inLen;
575
576 if (ovlSize > Size)
577 {
578 *ReqSize = ovlSize;
579 ObDereferenceObject(pr);
580
581 return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
582 }
583
584 // fill system information
585 SpiCur->NextEntryDelta = curSize+inLen; // relative offset to the beginnnig of the next structure
586 SpiCur->ThreadCount = nThreads;
587 SpiCur->CreateTime = pr->CreateTime;
588 SpiCur->UserTime.QuadPart = pr->Pcb.UserTime * 100000LL;
589 SpiCur->KernelTime.QuadPart = pr->Pcb.KernelTime * 100000LL;
590 SpiCur->ProcessName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
591 SpiCur->ProcessName.MaximumLength = inLen;
592 SpiCur->ProcessName.Buffer = (void*)(pCur+curSize);
593
594 // copy name to the end of the struct
595 RtlInitAnsiString(&imgName, pr->ImageFileName);
596 RtlAnsiStringToUnicodeString(&SpiCur->ProcessName, &imgName, FALSE);
597
598 SpiCur->BasePriority = pr->Pcb.BasePriority;
599 SpiCur->ProcessId = pr->UniqueProcessId;
600 SpiCur->InheritedFromProcessId = (DWORD)(pr->InheritedFromUniqueProcessId);
601 SpiCur->HandleCount = ObpGetHandleCountByHandleTable(&pr->HandleTable);
602 SpiCur->VmCounters.PeakVirtualSize = pr->PeakVirtualSize;
603 SpiCur->VmCounters.VirtualSize = pr->VirtualSize.QuadPart;
604 SpiCur->VmCounters.PageFaultCount = pr->LastFaultCount;
605 SpiCur->VmCounters.PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ?
606 SpiCur->VmCounters.WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ?
607 SpiCur->VmCounters.QuotaPeakPagedPoolUsage =
608 pr->QuotaPeakPoolUsage[0];
609 SpiCur->VmCounters.QuotaPagedPoolUsage =
610 pr->QuotaPoolUsage[0];
611 SpiCur->VmCounters.QuotaPeakNonPagedPoolUsage =
612 pr->QuotaPeakPoolUsage[1];
613 SpiCur->VmCounters.QuotaNonPagedPoolUsage =
614 pr->QuotaPoolUsage[1];
615 SpiCur->VmCounters.PagefileUsage = pr->PagefileUsage; // FIXME
616 SpiCur->VmCounters.PeakPagefileUsage = pr->PeakPagefileUsage;
617 // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
618 // doesn't seem to contain any equivalent field
619 //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
620
621 current_entry = pr->ThreadListHead.Flink;
622 while (current_entry != &pr->ThreadListHead)
623 {
624 current = CONTAINING_RECORD(current_entry, ETHREAD,
625 ThreadListEntry);
626
627 SpiCur->Threads[i].KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
628 SpiCur->Threads[i].UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
629 // SpiCur->Threads[i].CreateTime = current->CreateTime;
630 SpiCur->Threads[i].WaitTime = current->Tcb.WaitTime;
631 SpiCur->Threads[i].StartAddress = (PVOID) current->StartAddress;
632 SpiCur->Threads[i].ClientId = current->Cid;
633 SpiCur->Threads[i].Priority = current->Tcb.Priority;
634 SpiCur->Threads[i].BasePriority = current->Tcb.BasePriority;
635 SpiCur->Threads[i].ContextSwitchCount = current->Tcb.ContextSwitches;
636 SpiCur->Threads[i].State = current->Tcb.State;
637 SpiCur->Threads[i].WaitReason = current->Tcb.WaitReason;
638 i++;
639 current_entry = current_entry->Flink;
640 }
641
642 pr = PsGetNextProcess(pr);
643
644 if ((pr == syspr) || (pr == NULL))
645 {
646 SpiCur->NextEntryDelta = 0;
647 break;
648 }
649 else
650 pCur = pCur + curSize + inLen;
651 } while ((pr != syspr) && (pr != NULL));
652
653 *ReqSize = ovlSize;
654 if (pr != NULL)
655 {
656 ObDereferenceObject(pr);
657 }
658 return (STATUS_SUCCESS);
659 }
660
661 /* Class 6 - Call Count Information */
662 QSI_DEF(SystemCallCountInformation)
663 {
664 /* FIXME */
665 return (STATUS_NOT_IMPLEMENTED);
666 }
667
668 /* Class 7 - Device Information */
669 QSI_DEF(SystemDeviceInformation)
670 {
671 PSYSTEM_DEVICE_INFORMATION Sdi
672 = (PSYSTEM_DEVICE_INFORMATION) Buffer;
673 PCONFIGURATION_INFORMATION ConfigInfo;
674
675 *ReqSize = sizeof (SYSTEM_DEVICE_INFORMATION);
676 /*
677 * Check user buffer's size
678 */
679 if (Size < sizeof (SYSTEM_DEVICE_INFORMATION))
680 {
681 return (STATUS_INFO_LENGTH_MISMATCH);
682 }
683
684 ConfigInfo = IoGetConfigurationInformation ();
685
686 Sdi->NumberOfDisks = ConfigInfo->DiskCount;
687 Sdi->NumberOfFloppies = ConfigInfo->FloppyCount;
688 Sdi->NumberOfCdRoms = ConfigInfo->CdRomCount;
689 Sdi->NumberOfTapes = ConfigInfo->TapeCount;
690 Sdi->NumberOfSerialPorts = ConfigInfo->SerialCount;
691 Sdi->NumberOfParallelPorts = ConfigInfo->ParallelCount;
692
693 return (STATUS_SUCCESS);
694 }
695
696 /* Class 8 - Processor Performance Information */
697 QSI_DEF(SystemProcessorPerformanceInformation)
698 {
699 PSYSTEM_PROCESSORTIME_INFO Spi
700 = (PSYSTEM_PROCESSORTIME_INFO) Buffer;
701
702 PEPROCESS TheIdleProcess;
703 TIME CurrentTime;
704
705 *ReqSize = sizeof (SYSTEM_PROCESSORTIME_INFO);
706 /*
707 * Check user buffer's size
708 */
709 if (Size < sizeof (SYSTEM_PROCESSORTIME_INFO))
710 {
711 return (STATUS_INFO_LENGTH_MISMATCH);
712 }
713
714 PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
715
716 CurrentTime.QuadPart = KeQueryInterruptTime();
717
718 Spi->TotalProcessorRunTime.QuadPart =
719 TheIdleProcess->Pcb.KernelTime * 100000LL; // IdleTime
720 Spi->TotalProcessorTime.QuadPart = KiKernelTime * 100000LL; // KernelTime
721 Spi->TotalProcessorUserTime.QuadPart = KiUserTime * 100000LL;
722 Spi->TotalDPCTime.QuadPart = KiDpcTime * 100000LL;
723 Spi->TotalInterruptTime = CurrentTime;
724 Spi->TotalInterrupts = CurrentTime.QuadPart / 100000LL; // Interrupt Count
725
726 ObDereferenceObject(TheIdleProcess);
727
728 return (STATUS_SUCCESS);
729 }
730
731 /* Class 9 - Flags Information */
732 QSI_DEF(SystemFlagsInformation)
733 {
734 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
735 {
736 * ReqSize = sizeof (SYSTEM_FLAGS_INFORMATION);
737 return (STATUS_INFO_LENGTH_MISMATCH);
738 }
739 ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag;
740 return (STATUS_SUCCESS);
741 }
742
743 SSI_DEF(SystemFlagsInformation)
744 {
745 if (sizeof (SYSTEM_FLAGS_INFORMATION) != Size)
746 {
747 return (STATUS_INFO_LENGTH_MISMATCH);
748 }
749 NtGlobalFlag = ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags;
750 return (STATUS_SUCCESS);
751 }
752
753 /* Class 10 - Call Time Information */
754 QSI_DEF(SystemCallTimeInformation)
755 {
756 /* FIXME */
757 return (STATUS_NOT_IMPLEMENTED);
758 }
759
760 /* Class 11 - Module Information */
761 QSI_DEF(SystemModuleInformation)
762 {
763 return LdrpQueryModuleInformation(Buffer, Size, ReqSize);
764 }
765
766 /* Class 12 - Locks Information */
767 QSI_DEF(SystemLocksInformation)
768 {
769 /* FIXME */
770 return (STATUS_NOT_IMPLEMENTED);
771 }
772
773 /* Class 13 - Stack Trace Information */
774 QSI_DEF(SystemStackTraceInformation)
775 {
776 /* FIXME */
777 return (STATUS_NOT_IMPLEMENTED);
778 }
779
780 /* Class 14 - Paged Pool Information */
781 QSI_DEF(SystemPagedPoolInformation)
782 {
783 /* FIXME */
784 return (STATUS_NOT_IMPLEMENTED);
785 }
786
787 /* Class 15 - Non Paged Pool Information */
788 QSI_DEF(SystemNonPagedPoolInformation)
789 {
790 /* FIXME */
791 return (STATUS_NOT_IMPLEMENTED);
792 }
793
794 /* Class 16 - Handle Information */
795 QSI_DEF(SystemHandleInformation)
796 {
797 /* FIXME */
798 return (STATUS_NOT_IMPLEMENTED);
799 }
800
801 /* Class 17 - Information */
802 QSI_DEF(SystemObjectInformation)
803 {
804 /* FIXME */
805 return (STATUS_NOT_IMPLEMENTED);
806 }
807
808 /* Class 18 - Information */
809 QSI_DEF(SystemPageFileInformation)
810 {
811 SYSTEM_PAGEFILE_INFORMATION *Spfi = (SYSTEM_PAGEFILE_INFORMATION *) Buffer;
812
813 if (Size < sizeof (SYSTEM_PAGEFILE_INFORMATION))
814 {
815 * ReqSize = sizeof (SYSTEM_PAGEFILE_INFORMATION);
816 return (STATUS_INFO_LENGTH_MISMATCH);
817 }
818
819 UNICODE_STRING FileName; /* FIXME */
820
821 /* FIXME */
822 Spfi->RelativeOffset = 0;
823
824 Spfi->CurrentSizePages = MiFreeSwapPages + MiUsedSwapPages;
825 Spfi->TotalUsedPages = MiUsedSwapPages;
826 Spfi->PeakUsedPages = MiUsedSwapPages; /* FIXME */
827 Spfi->PagefileFileName = FileName;
828 return (STATUS_SUCCESS);
829 }
830
831 /* Class 19 - Vdm Instemul Information */
832 QSI_DEF(SystemVdmInstemulInformation)
833 {
834 /* FIXME */
835 return (STATUS_NOT_IMPLEMENTED);
836 }
837
838 /* Class 20 - Vdm Bop Information */
839 QSI_DEF(SystemVdmBopInformation)
840 {
841 /* FIXME */
842 return (STATUS_NOT_IMPLEMENTED);
843 }
844
845 /* Class 21 - File Cache Information */
846 QSI_DEF(SystemFileCacheInformation)
847 {
848 SYSTEM_CACHE_INFORMATION *Sci = (SYSTEM_CACHE_INFORMATION *) Buffer;
849
850 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
851 {
852 * ReqSize = sizeof (SYSTEM_CACHE_INFORMATION);
853 return (STATUS_INFO_LENGTH_MISMATCH);
854 }
855 /* Return the Byte size not the page size. */
856 Sci->CurrentSize =
857 MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE;
858 Sci->PeakSize =
859 MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE; /* FIXME */
860
861 Sci->PageFaultCount = 0; /* FIXME */
862 Sci->MinimumWorkingSet = 0; /* FIXME */
863 Sci->MaximumWorkingSet = 0; /* FIXME */
864 Sci->TransitionSharedPages = 0; /* FIXME */
865 Sci->TransitionSharedPagesPeak = 0; /* FIXME */
866
867 return (STATUS_SUCCESS);
868 }
869
870 SSI_DEF(SystemFileCacheInformation)
871 {
872 if (Size < sizeof (SYSTEM_CACHE_INFORMATION))
873 {
874 return (STATUS_INFO_LENGTH_MISMATCH);
875 }
876 /* FIXME */
877 return (STATUS_NOT_IMPLEMENTED);
878 }
879
880 /* Class 22 - Pool Tag Information */
881 QSI_DEF(SystemPoolTagInformation)
882 {
883 /* FIXME */
884 return (STATUS_NOT_IMPLEMENTED);
885 }
886
887 /* Class 23 - Interrupt Information */
888 QSI_DEF(SystemInterruptInformation)
889 {
890 /* FIXME */
891 return (STATUS_NOT_IMPLEMENTED);
892 }
893
894 /* Class 24 - DPC Behaviour Information */
895 QSI_DEF(SystemDpcBehaviourInformation)
896 {
897 /* FIXME */
898 return (STATUS_NOT_IMPLEMENTED);
899 }
900
901 SSI_DEF(SystemDpcBehaviourInformation)
902 {
903 /* FIXME */
904 return (STATUS_NOT_IMPLEMENTED);
905 }
906
907 /* Class 25 - Full Memory Information */
908 QSI_DEF(SystemFullMemoryInformation)
909 {
910 PULONG Spi = (PULONG) Buffer;
911
912 PEPROCESS TheIdleProcess;
913
914 * ReqSize = sizeof (ULONG);
915
916 if (sizeof (ULONG) != Size)
917 {
918 return (STATUS_INFO_LENGTH_MISMATCH);
919 }
920 DPRINT1("SystemFullMemoryInformation\n");
921
922 PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
923
924 DbgPrint("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
925 TheIdleProcess->UniqueProcessId,
926 TheIdleProcess->Pcb.KernelTime,
927 MiFreeSwapPages,
928 MiUsedSwapPages);
929
930 MmPrintMemoryStatistic();
931
932 *Spi = MiMemoryConsumers[MC_USER].PagesUsed;
933
934 ObDereferenceObject(TheIdleProcess);
935
936 return (STATUS_SUCCESS);
937 }
938
939 /* Class 26 - Load Image */
940 SSI_DEF(SystemLoadImage)
941 {
942 PSYSTEM_LOAD_IMAGE Sli = (PSYSTEM_LOAD_IMAGE)Buffer;
943
944 if (sizeof(SYSTEM_LOAD_IMAGE) != Size)
945 {
946 return(STATUS_INFO_LENGTH_MISMATCH);
947 }
948
949 return(LdrpLoadImage(&Sli->ModuleName,
950 &Sli->ModuleBase,
951 &Sli->SectionPointer,
952 &Sli->EntryPoint,
953 &Sli->ExportDirectory));
954 }
955
956 /* Class 27 - Unload Image */
957 SSI_DEF(SystemUnloadImage)
958 {
959 PSYSTEM_UNLOAD_IMAGE Sui = (PSYSTEM_UNLOAD_IMAGE)Buffer;
960
961 if (sizeof(SYSTEM_UNLOAD_IMAGE) != Size)
962 {
963 return(STATUS_INFO_LENGTH_MISMATCH);
964 }
965
966 return(LdrpUnloadImage(Sui->ModuleBase));
967 }
968
969 /* Class 28 - Time Adjustment Information */
970 QSI_DEF(SystemTimeAdjustmentInformation)
971 {
972 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT) > Size)
973 {
974 * ReqSize = sizeof (SYSTEM_SET_TIME_ADJUSTMENT);
975 return (STATUS_INFO_LENGTH_MISMATCH);
976 }
977 /* FIXME: */
978 return (STATUS_NOT_IMPLEMENTED);
979 }
980
981 SSI_DEF(SystemTimeAdjustmentInformation)
982 {
983 if (sizeof (SYSTEM_SET_TIME_ADJUSTMENT) > Size)
984 {
985 return (STATUS_INFO_LENGTH_MISMATCH);
986 }
987 /* FIXME: */
988 return (STATUS_NOT_IMPLEMENTED);
989 }
990
991 /* Class 29 - Summary Memory Information */
992 QSI_DEF(SystemSummaryMemoryInformation)
993 {
994 /* FIXME */
995 return (STATUS_NOT_IMPLEMENTED);
996 }
997
998 /* Class 30 - Next Event Id Information */
999 QSI_DEF(SystemNextEventIdInformation)
1000 {
1001 /* FIXME */
1002 return (STATUS_NOT_IMPLEMENTED);
1003 }
1004
1005 /* Class 31 - Event Ids Information */
1006 QSI_DEF(SystemEventIdsInformation)
1007 {
1008 /* FIXME */
1009 return (STATUS_NOT_IMPLEMENTED);
1010 }
1011
1012 /* Class 32 - Crach Dump Information */
1013 QSI_DEF(SystemCrashDumpInformation)
1014 {
1015 /* FIXME */
1016 return (STATUS_NOT_IMPLEMENTED);
1017 }
1018
1019 /* Class 33 - Exception Information */
1020 QSI_DEF(SystemExceptionInformation)
1021 {
1022 /* FIXME */
1023 return (STATUS_NOT_IMPLEMENTED);
1024 }
1025
1026 /* Class 34 - Crach Dump State Information */
1027 QSI_DEF(SystemCrashDumpStateInformation)
1028 {
1029 /* FIXME */
1030 return (STATUS_NOT_IMPLEMENTED);
1031 }
1032
1033 /* Class 35 - Kernel Debugger Information */
1034 QSI_DEF(SystemKernelDebuggerInformation)
1035 {
1036 /* FIXME */
1037 return (STATUS_NOT_IMPLEMENTED);
1038 }
1039
1040 /* Class 36 - Context Switch Information */
1041 QSI_DEF(SystemContextSwitchInformation)
1042 {
1043 /* FIXME */
1044 return (STATUS_NOT_IMPLEMENTED);
1045 }
1046
1047 /* Class 37 - Registry Quota Information */
1048 QSI_DEF(SystemRegistryQuotaInformation)
1049 {
1050 /* FIXME */
1051 return (STATUS_NOT_IMPLEMENTED);
1052 }
1053
1054 SSI_DEF(SystemRegistryQuotaInformation)
1055 {
1056 /* FIXME */
1057 return (STATUS_NOT_IMPLEMENTED);
1058 }
1059
1060 /* Class 38 - Load And Call Image */
1061 SSI_DEF(SystemLoadAndCallImage)
1062 {
1063 PSYSTEM_LOAD_AND_CALL_IMAGE Slci = (PSYSTEM_LOAD_AND_CALL_IMAGE)Buffer;
1064
1065 if (sizeof(SYSTEM_LOAD_AND_CALL_IMAGE) != Size)
1066 {
1067 return(STATUS_INFO_LENGTH_MISMATCH);
1068 }
1069
1070 return(LdrpLoadAndCallImage(&Slci->ModuleName));
1071 }
1072
1073 /* Class 39 - Priority Seperation */
1074 SSI_DEF(SystemPrioritySeperation)
1075 {
1076 /* FIXME */
1077 return (STATUS_NOT_IMPLEMENTED);
1078 }
1079
1080 /* Class 40 - Plug Play Bus Information */
1081 QSI_DEF(SystemPlugPlayBusInformation)
1082 {
1083 /* FIXME */
1084 return (STATUS_NOT_IMPLEMENTED);
1085 }
1086
1087 /* Class 41 - Dock Information */
1088 QSI_DEF(SystemDockInformation)
1089 {
1090 /* FIXME */
1091 return (STATUS_NOT_IMPLEMENTED);
1092 }
1093
1094 /* Class 42 - Power Information */
1095 QSI_DEF(SystemPowerInformation)
1096 {
1097 /* FIXME */
1098 return (STATUS_NOT_IMPLEMENTED);
1099 }
1100
1101 /* Class 43 - Processor Speed Information */
1102 QSI_DEF(SystemProcessorSpeedInformation)
1103 {
1104 /* FIXME */
1105 return (STATUS_NOT_IMPLEMENTED);
1106 }
1107
1108 /* Class 44 - Current Time Zone Information */
1109 QSI_DEF(SystemCurrentTimeZoneInformation)
1110 {
1111 * ReqSize = sizeof (TIME_ZONE_INFORMATION);
1112
1113 if (sizeof (TIME_ZONE_INFORMATION) != Size)
1114 {
1115 return (STATUS_INFO_LENGTH_MISMATCH);
1116 }
1117 /* Copy the time zone information struct */
1118 memcpy (
1119 Buffer,
1120 & _SystemTimeZoneInfo,
1121 sizeof (TIME_ZONE_INFORMATION)
1122 );
1123
1124 return (STATUS_SUCCESS);
1125 }
1126
1127
1128 SSI_DEF(SystemCurrentTimeZoneInformation)
1129 {
1130 /*
1131 * Check user buffer's size
1132 */
1133 if (Size < sizeof (TIME_ZONE_INFORMATION))
1134 {
1135 return (STATUS_INFO_LENGTH_MISMATCH);
1136 }
1137 /* Copy the time zone information struct */
1138 memcpy (
1139 & _SystemTimeZoneInfo,
1140 (TIME_ZONE_INFORMATION *) Buffer,
1141 sizeof (TIME_ZONE_INFORMATION)
1142 );
1143 return (STATUS_SUCCESS);
1144 }
1145
1146
1147 /* Class 45 - Lookaside Information */
1148 QSI_DEF(SystemLookasideInformation)
1149 {
1150 /* FIXME */
1151 return (STATUS_NOT_IMPLEMENTED);
1152 }
1153
1154
1155 /* Class 46 - Set time slip event */
1156 SSI_DEF(SystemSetTimeSlipEvent)
1157 {
1158 /* FIXME */
1159 return (STATUS_NOT_IMPLEMENTED);
1160 }
1161
1162
1163 /* Class 47 - Create a new session (TSE) */
1164 SSI_DEF(SystemCreateSession)
1165 {
1166 /* FIXME */
1167 return (STATUS_NOT_IMPLEMENTED);
1168 }
1169
1170
1171 /* Class 48 - Delete an existing session (TSE) */
1172 SSI_DEF(SystemDeleteSession)
1173 {
1174 /* FIXME */
1175 return (STATUS_NOT_IMPLEMENTED);
1176 }
1177
1178
1179 /* Class 49 - UNKNOWN */
1180 QSI_DEF(SystemInvalidInfoClass4)
1181 {
1182 /* FIXME */
1183 return (STATUS_NOT_IMPLEMENTED);
1184 }
1185
1186
1187 /* Class 50 - System range start address */
1188 QSI_DEF(SystemRangeStartInformation)
1189 {
1190 /* FIXME */
1191 return (STATUS_NOT_IMPLEMENTED);
1192 }
1193
1194
1195 /* Class 51 - Driver verifier information */
1196 QSI_DEF(SystemVerifierInformation)
1197 {
1198 /* FIXME */
1199 return (STATUS_NOT_IMPLEMENTED);
1200 }
1201
1202
1203 SSI_DEF(SystemVerifierInformation)
1204 {
1205 /* FIXME */
1206 return (STATUS_NOT_IMPLEMENTED);
1207 }
1208
1209
1210 /* Class 52 - Add a driver verifier */
1211 SSI_DEF(SystemAddVerifier)
1212 {
1213 /* FIXME */
1214 return (STATUS_NOT_IMPLEMENTED);
1215 }
1216
1217
1218 /* Class 53 - A session's processes */
1219 QSI_DEF(SystemSessionProcessesInformation)
1220 {
1221 /* FIXME */
1222 return (STATUS_NOT_IMPLEMENTED);
1223 }
1224
1225
1226 /* Query/Set Calls Table */
1227 typedef
1228 struct _QSSI_CALLS
1229 {
1230 NTSTATUS (* Query) (PVOID,ULONG,PULONG);
1231 NTSTATUS (* Set) (PVOID,ULONG);
1232
1233 } QSSI_CALLS;
1234
1235 // QS Query & Set
1236 // QX Query
1237 // XQ Set
1238 // XX unknown behaviour
1239 //
1240 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
1241 #define SI_QX(n) {QSI_USE(n),NULL}
1242 #define SI_XS(n) {NULL,SSI_USE(n)}
1243 #define SI_XX(n) {NULL,NULL}
1244
1245 static
1246 QSSI_CALLS
1247 CallQS [] =
1248 {
1249 SI_QX(SystemBasicInformation),
1250 SI_QX(SystemProcessorInformation),
1251 SI_QX(SystemPerformanceInformation),
1252 SI_QX(SystemTimeOfDayInformation),
1253 SI_QX(SystemPathInformation), /* should be SI_XX */
1254 SI_QX(SystemProcessInformation),
1255 SI_QX(SystemCallCountInformation),
1256 SI_QX(SystemDeviceInformation),
1257 SI_QX(SystemProcessorPerformanceInformation),
1258 SI_QS(SystemFlagsInformation),
1259 SI_QX(SystemCallTimeInformation), /* should be SI_XX */
1260 SI_QX(SystemModuleInformation),
1261 SI_QX(SystemLocksInformation),
1262 SI_QX(SystemStackTraceInformation), /* should be SI_XX */
1263 SI_QX(SystemPagedPoolInformation), /* should be SI_XX */
1264 SI_QX(SystemNonPagedPoolInformation), /* should be SI_XX */
1265 SI_QX(SystemHandleInformation),
1266 SI_QX(SystemObjectInformation),
1267 SI_QX(SystemPageFileInformation),
1268 SI_QX(SystemVdmInstemulInformation),
1269 SI_QX(SystemVdmBopInformation), /* it should be SI_XX */
1270 SI_QS(SystemFileCacheInformation),
1271 SI_QX(SystemPoolTagInformation),
1272 SI_QX(SystemInterruptInformation),
1273 SI_QS(SystemDpcBehaviourInformation),
1274 SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */
1275 SI_XS(SystemLoadImage),
1276 SI_XS(SystemUnloadImage),
1277 SI_QS(SystemTimeAdjustmentInformation),
1278 SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */
1279 SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */
1280 SI_QX(SystemEventIdsInformation), /* it should be SI_XX */
1281 SI_QX(SystemCrashDumpInformation),
1282 SI_QX(SystemExceptionInformation),
1283 SI_QX(SystemCrashDumpStateInformation),
1284 SI_QX(SystemKernelDebuggerInformation),
1285 SI_QX(SystemContextSwitchInformation),
1286 SI_QS(SystemRegistryQuotaInformation),
1287 SI_XS(SystemLoadAndCallImage),
1288 SI_XS(SystemPrioritySeperation),
1289 SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */
1290 SI_QX(SystemDockInformation), /* it should be SI_XX */
1291 SI_QX(SystemPowerInformation), /* it should be SI_XX */
1292 SI_QX(SystemProcessorSpeedInformation), /* it should be SI_XX */
1293 SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */
1294 SI_QX(SystemLookasideInformation),
1295 SI_XS(SystemSetTimeSlipEvent),
1296 SI_XS(SystemCreateSession),
1297 SI_XS(SystemDeleteSession),
1298 SI_QX(SystemInvalidInfoClass4), /* it should be SI_XX */
1299 SI_QX(SystemRangeStartInformation),
1300 SI_QS(SystemVerifierInformation),
1301 SI_XS(SystemAddVerifier),
1302 SI_QX(SystemSessionProcessesInformation)
1303 };
1304
1305
1306 /*
1307 * @implemented
1308 */
1309 NTSTATUS STDCALL
1310 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1311 OUT PVOID UnsafeSystemInformation,
1312 IN ULONG Length,
1313 OUT PULONG UnsafeResultLength)
1314 {
1315 ULONG ResultLength;
1316 PVOID SystemInformation;
1317 NTSTATUS Status;
1318 NTSTATUS FStatus;
1319
1320 /* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
1321 SystemInformationClass );
1322 */
1323 /*if (ExGetPreviousMode() == KernelMode)
1324 {*/
1325 SystemInformation = UnsafeSystemInformation;
1326 /*}
1327 else
1328 {
1329 SystemInformation = ExAllocatePool(NonPagedPool, Length);
1330 if (SystemInformation == NULL)
1331 {
1332 return(STATUS_NO_MEMORY);
1333 }
1334 }*/
1335
1336 /* Clear user buffer. */
1337 RtlZeroMemory(SystemInformation, Length);
1338
1339 /*
1340 * Check the request is valid.
1341 */
1342 if ((SystemInformationClass >= SystemInformationClassMin) &&
1343 (SystemInformationClass < SystemInformationClassMax))
1344 {
1345 if (NULL != CallQS [SystemInformationClass].Query)
1346 {
1347 /*
1348 * Hand the request to a subhandler.
1349 */
1350 FStatus = CallQS [SystemInformationClass].Query(SystemInformation,
1351 Length,
1352 &ResultLength);
1353 /*if (ExGetPreviousMode() != KernelMode)
1354 {
1355 Status = MmCopyToCaller(UnsafeSystemInformation,
1356 SystemInformation,
1357 Length);
1358 ExFreePool(SystemInformation);
1359 if (!NT_SUCCESS(Status))
1360 {
1361 return(Status);
1362 }
1363 }*/
1364 if (UnsafeResultLength != NULL)
1365 {
1366 /*if (ExGetPreviousMode() == KernelMode)
1367 {
1368 *UnsafeResultLength = ResultLength;
1369 }
1370 else
1371 {*/
1372 Status = MmCopyToCaller(UnsafeResultLength,
1373 &ResultLength,
1374 sizeof(ULONG));
1375 if (!NT_SUCCESS(Status))
1376 {
1377 return(Status);
1378 }
1379 /*}*/
1380 }
1381 return(FStatus);
1382 }
1383 }
1384 return (STATUS_INVALID_INFO_CLASS);
1385 }
1386
1387
1388 NTSTATUS
1389 STDCALL
1390 NtSetSystemInformation (
1391 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1392 IN PVOID SystemInformation,
1393 IN ULONG SystemInformationLength
1394 )
1395 {
1396 /*
1397 * If called from user mode, check
1398 * possible unsafe arguments.
1399 */
1400 #if 0
1401 if (KernelMode != KeGetPreviousMode())
1402 {
1403 // Check arguments
1404 //ProbeForWrite(
1405 // SystemInformation,
1406 // Length
1407 // );
1408 //ProbeForWrite(
1409 // ResultLength,
1410 // sizeof (ULONG)
1411 // );
1412 }
1413 #endif
1414 /*
1415 * Check the request is valid.
1416 */
1417 if ( (SystemInformationClass >= SystemInformationClassMin)
1418 && (SystemInformationClass < SystemInformationClassMax)
1419 )
1420 {
1421 if (NULL != CallQS [SystemInformationClass].Set)
1422 {
1423 /*
1424 * Hand the request to a subhandler.
1425 */
1426 return CallQS [SystemInformationClass].Set (
1427 SystemInformation,
1428 SystemInformationLength
1429 );
1430 }
1431 }
1432 return (STATUS_INVALID_INFO_CLASS);
1433 }
1434
1435
1436 NTSTATUS
1437 STDCALL
1438 NtFlushInstructionCache (
1439 IN HANDLE ProcessHandle,
1440 IN PVOID BaseAddress,
1441 IN UINT NumberOfBytesToFlush
1442 )
1443 {
1444 UNIMPLEMENTED;
1445 return(STATUS_NOT_IMPLEMENTED);
1446 }
1447
1448
1449 /* EOF */