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