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