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