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