Implemented NtSetEnvironmentVariable
[reactos.git] / reactos / ntoskrnl / ex / sysinfo.c
1 /* $Id: sysinfo.c,v 1.13 2001/09/02 17:29:51 dwelch 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 = PAGESIZE; /* 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 Gdi Driver Information */
661 SSI_DEF(SystemLoadGdiDriverInformation)
662 {
663 PSYSTEM_GDI_DRIVER_INFORMATION Sdi
664 = (PSYSTEM_GDI_DRIVER_INFORMATION) Buffer;
665
666 if (sizeof (SYSTEM_GDI_DRIVER_INFORMATION) != Size)
667 {
668 return (STATUS_INFO_LENGTH_MISMATCH);
669 }
670
671 return LdrLoadGdiDriver (&Sdi->DriverName,
672 &Sdi->ImageAddress,
673 &Sdi->SectionPointer,
674 &Sdi->EntryPoint,
675 &Sdi->ExportSectionPointer);
676 }
677
678 /* Class 27 - Unload Gdi Driver Information */
679 SSI_DEF(SystemUnloadGdiDriverInformation)
680 {
681 /* FIXME */
682 return (STATUS_NOT_IMPLEMENTED);
683 }
684
685 /* Class 28 - Time Adjustment Information */
686 QSI_DEF(SystemTimeAdjustmentInformation)
687 {
688 if (sizeof (SYSTEM_TIME_ADJUSTMENT_INFO) > Size)
689 {
690 * ReqSize = sizeof (SYSTEM_TIME_ADJUSTMENT_INFO);
691 return (STATUS_INFO_LENGTH_MISMATCH);
692 }
693 /* FIXME: */
694 return (STATUS_NOT_IMPLEMENTED);
695 }
696
697 SSI_DEF(SystemTimeAdjustmentInformation)
698 {
699 if (sizeof (SYSTEM_TIME_ADJUSTMENT_INFO) > Size)
700 {
701 return (STATUS_INFO_LENGTH_MISMATCH);
702 }
703 /* FIXME: */
704 return (STATUS_NOT_IMPLEMENTED);
705 }
706
707 /* Class 29 - Summary Memory Information */
708 QSI_DEF(SystemSummaryMemoryInformation)
709 {
710 /* FIXME */
711 return (STATUS_NOT_IMPLEMENTED);
712 }
713
714 /* Class 30 - Next Event Id Information */
715 QSI_DEF(SystemNextEventIdInformation)
716 {
717 /* FIXME */
718 return (STATUS_NOT_IMPLEMENTED);
719 }
720
721 /* Class 31 - Event Ids Information */
722 QSI_DEF(SystemEventIdsInformation)
723 {
724 /* FIXME */
725 return (STATUS_NOT_IMPLEMENTED);
726 }
727
728 /* Class 32 - Crach Dump Information */
729 QSI_DEF(SystemCrashDumpInformation)
730 {
731 /* FIXME */
732 return (STATUS_NOT_IMPLEMENTED);
733 }
734
735 /* Class 33 - Exception Information */
736 QSI_DEF(SystemExceptionInformation)
737 {
738 /* FIXME */
739 return (STATUS_NOT_IMPLEMENTED);
740 }
741
742 /* Class 34 - Crach Dump State Information */
743 QSI_DEF(SystemCrashDumpStateInformation)
744 {
745 /* FIXME */
746 return (STATUS_NOT_IMPLEMENTED);
747 }
748
749 /* Class 35 - Kernel Debugger Information */
750 QSI_DEF(SystemKernelDebuggerInformation)
751 {
752 /* FIXME */
753 return (STATUS_NOT_IMPLEMENTED);
754 }
755
756 /* Class 36 - Context Switch Information */
757 QSI_DEF(SystemContextSwitchInformation)
758 {
759 /* FIXME */
760 return (STATUS_NOT_IMPLEMENTED);
761 }
762
763 /* Class 37 - Registry Quota Information */
764 QSI_DEF(SystemRegistryQuotaInformation)
765 {
766 /* FIXME */
767 return (STATUS_NOT_IMPLEMENTED);
768 }
769
770 SSI_DEF(SystemRegistryQuotaInformation)
771 {
772 /* FIXME */
773 return (STATUS_NOT_IMPLEMENTED);
774 }
775
776 /* Class 38 - Extend Service Table Information */
777 SSI_DEF(SystemExtendServiceTableInformation)
778 {
779 /* FIXME */
780 return (STATUS_NOT_IMPLEMENTED);
781 }
782
783 /* Class 39 - Priority Seperation */
784 SSI_DEF(SystemPrioritySeperation)
785 {
786 /* FIXME */
787 return (STATUS_NOT_IMPLEMENTED);
788 }
789
790 /* Class 40 - Plug Play Bus Information */
791 QSI_DEF(SystemPlugPlayBusInformation)
792 {
793 /* FIXME */
794 return (STATUS_NOT_IMPLEMENTED);
795 }
796
797 /* Class 41 - Dock Information */
798 QSI_DEF(SystemDockInformation)
799 {
800 /* FIXME */
801 return (STATUS_NOT_IMPLEMENTED);
802 }
803
804 /* Class 42 - Power Information */
805 QSI_DEF(SystemPowerInformation)
806 {
807 /* FIXME */
808 return (STATUS_NOT_IMPLEMENTED);
809 }
810
811 /* Class 43 - Processor Speed Information */
812 QSI_DEF(SystemProcessorSpeedInformation)
813 {
814 /* FIXME */
815 return (STATUS_NOT_IMPLEMENTED);
816 }
817
818 /* Class 44 - Current Time Zone Information */
819 QSI_DEF(SystemCurrentTimeZoneInformation)
820 {
821 * ReqSize = sizeof (TIME_ZONE_INFORMATION);
822
823 if (sizeof (TIME_ZONE_INFORMATION) != Size)
824 {
825 return (STATUS_INFO_LENGTH_MISMATCH);
826 }
827 /* Copy the time zone information struct */
828 memcpy (
829 Buffer,
830 & SystemTimeZoneInfo,
831 sizeof (TIME_ZONE_INFORMATION)
832 );
833
834 return (STATUS_SUCCESS);
835 }
836
837
838 SSI_DEF(SystemCurrentTimeZoneInformation)
839 {
840 /*
841 * Check user buffer's size
842 */
843 if (Size < sizeof (TIME_ZONE_INFORMATION))
844 {
845 return (STATUS_INFO_LENGTH_MISMATCH);
846 }
847 /* Copy the time zone information struct */
848 memcpy (
849 & SystemTimeZoneInfo,
850 (TIME_ZONE_INFORMATION *) Buffer,
851 sizeof (TIME_ZONE_INFORMATION)
852 );
853 return (STATUS_SUCCESS);
854 }
855
856
857 /* Class 45 - Lookaside Information */
858 QSI_DEF(SystemLookasideInformation)
859 {
860 /* FIXME */
861 return (STATUS_NOT_IMPLEMENTED);
862 }
863
864
865 /* Class 46 - Set time slip event */
866 SSI_DEF(SystemSetTimeSlipEvent)
867 {
868 /* FIXME */
869 return (STATUS_NOT_IMPLEMENTED);
870 }
871
872
873 /* Class 47 - Create a new session (TSE) */
874 SSI_DEF(SystemCreateSession)
875 {
876 /* FIXME */
877 return (STATUS_NOT_IMPLEMENTED);
878 }
879
880
881 /* Class 48 - Delete an existing session (TSE) */
882 SSI_DEF(SystemDeleteSession)
883 {
884 /* FIXME */
885 return (STATUS_NOT_IMPLEMENTED);
886 }
887
888
889 /* Class 49 - UNKNOWN */
890 QSI_DEF(SystemInvalidInfoClass4)
891 {
892 /* FIXME */
893 return (STATUS_NOT_IMPLEMENTED);
894 }
895
896
897 /* Class 50 - System range start address */
898 QSI_DEF(SystemRangeStartInformation)
899 {
900 /* FIXME */
901 return (STATUS_NOT_IMPLEMENTED);
902 }
903
904
905 /* Class 51 - Driver verifier information */
906 QSI_DEF(SystemVerifierInformation)
907 {
908 /* FIXME */
909 return (STATUS_NOT_IMPLEMENTED);
910 }
911
912
913 SSI_DEF(SystemVerifierInformation)
914 {
915 /* FIXME */
916 return (STATUS_NOT_IMPLEMENTED);
917 }
918
919
920 /* Class 52 - Add a driver verifier */
921 SSI_DEF(SystemAddVerifier)
922 {
923 /* FIXME */
924 return (STATUS_NOT_IMPLEMENTED);
925 }
926
927
928 /* Class 53 - A session's processes */
929 QSI_DEF(SystemSessionProcessesInformation)
930 {
931 /* FIXME */
932 return (STATUS_NOT_IMPLEMENTED);
933 }
934
935
936 /* Query/Set Calls Table */
937 typedef
938 struct _QSSI_CALLS
939 {
940 NTSTATUS (* Query) (PVOID,ULONG,PULONG);
941 NTSTATUS (* Set) (PVOID,ULONG);
942
943 } QSSI_CALLS;
944
945 // QS Query & Set
946 // QX Query
947 // XQ Set
948 // XX unknown behaviour
949 //
950 #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
951 #define SI_QX(n) {QSI_USE(n),NULL}
952 #define SI_XS(n) {NULL,SSI_USE(n)}
953 #define SI_XX(n) {NULL,NULL}
954
955 static
956 QSSI_CALLS
957 CallQS [] =
958 {
959 SI_QX(SystemBasicInformation),
960 SI_QX(SystemProcessorInformation),
961 SI_QX(SystemPerformanceInformation),
962 SI_QX(SystemTimeOfDayInformation),
963 SI_QX(SystemPathInformation), /* should be SI_XX */
964 SI_QX(SystemProcessInformation),
965 SI_QX(SystemCallCountInformation),
966 SI_QX(SystemDeviceInformation),
967 SI_QX(SystemProcessorPerformanceInformation),
968 SI_QS(SystemFlagsInformation),
969 SI_QX(SystemCallTimeInformation), /* should be SI_XX */
970 SI_QX(SystemModuleInformation),
971 SI_QX(SystemLocksInformation),
972 SI_QX(SystemStackTraceInformation), /* should be SI_XX */
973 SI_QX(SystemPagedPoolInformation), /* should be SI_XX */
974 SI_QX(SystemNonPagedPoolInformation), /* should be SI_XX */
975 SI_QX(SystemHandleInformation),
976 SI_QX(SystemObjectInformation),
977 SI_QX(SystemPageFileInformation),
978 SI_QX(SystemVdmInstemulInformation),
979 SI_QX(SystemVdmBopInformation), /* it should be SI_XX */
980 SI_QS(SystemFileCacheInformation),
981 SI_QX(SystemPoolTagInformation),
982 SI_QX(SystemInterruptInformation),
983 SI_QS(SystemDpcBehaviourInformation),
984 SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */
985 SI_XS(SystemLoadGdiDriverInformation),
986 SI_XS(SystemUnloadGdiDriverInformation),
987 SI_QS(SystemTimeAdjustmentInformation),
988 SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */
989 SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */
990 SI_QX(SystemEventIdsInformation), /* it should be SI_XX */
991 SI_QX(SystemCrashDumpInformation),
992 SI_QX(SystemExceptionInformation),
993 SI_QX(SystemCrashDumpStateInformation),
994 SI_QX(SystemKernelDebuggerInformation),
995 SI_QX(SystemContextSwitchInformation),
996 SI_QS(SystemRegistryQuotaInformation),
997 SI_XS(SystemExtendServiceTableInformation),
998 SI_XS(SystemPrioritySeperation),
999 SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */
1000 SI_QX(SystemDockInformation), /* it should be SI_XX */
1001 SI_QX(SystemPowerInformation), /* it should be SI_XX */
1002 SI_QX(SystemProcessorSpeedInformation), /* it should be SI_XX */
1003 SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */
1004 SI_QX(SystemLookasideInformation),
1005 SI_XS(SystemSetTimeSlipEvent),
1006 SI_XS(SystemCreateSession),
1007 SI_XS(SystemDeleteSession),
1008 SI_QX(SystemInvalidInfoClass4), /* it should be SI_XX */
1009 SI_QX(SystemRangeStartInformation),
1010 SI_QS(SystemVerifierInformation),
1011 SI_XS(SystemAddVerifier),
1012 SI_QX(SystemSessionProcessesInformation)
1013 };
1014
1015
1016 NTSTATUS
1017 STDCALL
1018 NtQuerySystemInformation (
1019 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1020 OUT PVOID SystemInformation,
1021 IN ULONG Length,
1022 OUT PULONG ResultLength
1023 )
1024 {
1025 /*
1026 * If called from user mode, check
1027 * possible unsafe arguments.
1028 */
1029 #if 0
1030 if (KernelMode != KeGetPreviousMode())
1031 {
1032 // Check arguments
1033 //ProbeForWrite(
1034 // SystemInformation,
1035 // Length
1036 // );
1037 //ProbeForWrite(
1038 // ResultLength,
1039 // sizeof (ULONG)
1040 // );
1041 }
1042 #endif
1043 /*
1044 * Clear the user buffer.
1045 */
1046 RtlZeroMemory (SystemInformation, Length);
1047 /*
1048 * Check the request is valid.
1049 */
1050 if ( (SystemInformationClass >= SystemInformationClassMin)
1051 && (SystemInformationClass < SystemInformationClassMax)
1052 )
1053 {
1054 if (NULL != CallQS [SystemInformationClass].Query)
1055 {
1056 /*
1057 * Hand the request to a subhandler.
1058 */
1059 return CallQS [SystemInformationClass].Query (
1060 SystemInformation,
1061 Length,
1062 ResultLength
1063 );
1064 }
1065 }
1066 return (STATUS_INVALID_INFO_CLASS);
1067 }
1068
1069
1070 NTSTATUS
1071 STDCALL
1072 NtSetSystemInformation (
1073 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
1074 IN PVOID SystemInformation,
1075 IN ULONG SystemInformationLength
1076 )
1077 {
1078 /*
1079 * If called from user mode, check
1080 * possible unsafe arguments.
1081 */
1082 #if 0
1083 if (KernelMode != KeGetPreviousMode())
1084 {
1085 // Check arguments
1086 //ProbeForWrite(
1087 // SystemInformation,
1088 // Length
1089 // );
1090 //ProbeForWrite(
1091 // ResultLength,
1092 // sizeof (ULONG)
1093 // );
1094 }
1095 #endif
1096 /*
1097 * Check the request is valid.
1098 */
1099 if ( (SystemInformationClass >= SystemInformationClassMin)
1100 && (SystemInformationClass < SystemInformationClassMax)
1101 )
1102 {
1103 if (NULL != CallQS [SystemInformationClass].Set)
1104 {
1105 /*
1106 * Hand the request to a subhandler.
1107 */
1108 return CallQS [SystemInformationClass].Set (
1109 SystemInformation,
1110 SystemInformationLength
1111 );
1112 }
1113 }
1114 return (STATUS_INVALID_INFO_CLASS);
1115 }
1116
1117
1118 NTSTATUS
1119 STDCALL
1120 NtFlushInstructionCache (
1121 IN HANDLE ProcessHandle,
1122 IN PVOID BaseAddress,
1123 IN UINT NumberOfBytesToFlush
1124 )
1125 {
1126 UNIMPLEMENTED;
1127 }
1128
1129
1130 /* EOF */