fa6989ed57f0543e45aff78c318fd930a12cc67f
[reactos.git] / rosapps / sysutils / qsi.c
1 /* $Id: qsi.c,v 1.1 2000/04/25 23:22:57 ea Exp $
2 *
3 * PROJECT : ReactOS Operating System (see http://www.reactos.com/)
4 * DESCRIPTION: Tool to query system information
5 * FILE : rosapps/sysutils/qsi.c
6 * AUTHOR : Emanuele Aliberti
7 * LICENSE : GNU GPL (see http://www.gnu.org/)
8 * DATE : 1999-07-28
9 *
10 * BUILD INSTRUCTIONS
11 * If you got this code directly from the CVS repository on
12 * mok.lcvm.com, it should be ok to run "make sqi.exe" from the
13 * current directory. Otherwise, be sure the directories
14 * "rosapps" and "reactos" are siblings (see the FILE file
15 * in the header).
16 *
17 * REVISIONS
18 * 2000-02-12 (ea)
19 * Partially rewritten to run as a tool to query
20 * every system information class data.
21 * 2000-04-23 (ea)
22 * Added almost all structures for getting system
23 * information (from UNDOCNT.H by Dabak et alii).
24 */
25 #include <windows.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <wchar.h>
30
31 #define NTOS_MODE_USER
32 #include <ntos.h>
33
34 typedef
35 struct _FLAGS
36 {
37 DWORD Verbose:1; /* print unknown, unused, service fields */
38 DWORD Dump:1; /* raw dump output buffer */
39 DWORD Batch:1; /* no shell (for future use) */
40 } FLAGS;
41
42 static
43 struct
44 {
45 FLAGS Flag;
46 BOOL Active;
47 HANDLE Heap;
48 INT ExitCode;
49
50 } Application =
51 {
52 {0, 0},
53 FALSE
54 };
55
56 #define ONOFF(b) ((b)?"on":"off")
57
58 #define ARGV_SIZE 64
59
60 #define BUFFER_SIZE_DEFAULT 65536
61
62 #define TF(b) ((b)?"true":"false")
63
64 typedef
65 INT (* COMMAND_CALL) (INT ArgC,LPCSTR ArgV []);
66
67
68
69 VOID STDCALL PrintStatus (NTSTATUS Status);
70
71 #define CMD_REF(n) CMD_##n
72 #define CMD_DEF(n) INT CMD_REF(n) (INT argc, LPCSTR argv [])
73 #define CMD_NOT_IMPLEMENTED {printf("%s not implemented\n", argv[0]);return(0);}
74
75 typedef
76 struct _COMMAND_DESCRIPTOR
77 {
78 LPCSTR Name;
79 COMMAND_CALL EntryPoint;
80 LPCSTR Description;
81
82 } COMMAND_DESCRIPTOR, * PCOMMAND_DESCRIPTOR;
83
84
85
86 /* --- */
87 VOID
88 STDCALL
89 DumpData (int Size, PVOID pData )
90 {
91 PBYTE Buffer = (PBYTE) pData;
92 PBYTE Base = Buffer;
93 int i;
94 const int Width = 16;
95
96 if (! Application.Flag.Dump)
97 {
98 return;
99 }
100 while (Size > 0)
101 {
102 printf ("%04x: ", (Buffer - Base));
103 for ( i = 0;
104 (i < Width);
105 ++i
106 )
107 {
108 if (Size - i > 0)
109 {
110 printf (
111 "%02x%c",
112 Buffer[i],
113 (i % 4 == 3) ? '|' : ' '
114 );
115 }
116 else
117 {
118 printf (" ");
119 }
120 }
121 printf (" ");
122 for ( i = 0;
123 (i < Width);
124 ++i
125 )
126 {
127 if (Size - i > 0)
128 {
129 printf (
130 "%c",
131 ( (Buffer[i] > ' ')
132 && (Buffer[i] < 127)
133 )
134 ? Buffer[i]
135 : ' '
136 );
137 }
138 }
139 printf ("\n");
140 Buffer += Width;
141 Size -= Width;
142 }
143 printf ("\n");
144 }
145
146
147 int
148 STDCALL
149 FindRequiredBufferSize (int i, int step)
150 {
151 NTSTATUS Status = STATUS_INFO_LENGTH_MISMATCH;
152 BYTE Buffer [BUFFER_SIZE_DEFAULT];
153 INT Size;
154 LONG Length = 0;
155
156
157 Size = step = (step > 0 ? step : 1);
158 while ( (Size < sizeof Buffer)
159 && (Status == STATUS_INFO_LENGTH_MISMATCH)
160 )
161 {
162 if (Application.Flag.Verbose)
163 {
164 printf ("\tTry %d", Size);
165 }
166 RtlZeroMemory (Buffer, sizeof Buffer);
167 Length = 0;
168 Status = NtQuerySystemInformation (
169 i,
170 & Buffer,
171 Size,
172 & Length
173 );
174 if (STATUS_SUCCESS == Status)
175 {
176 printf ("Length = %d\n", Size);
177 return Size;
178 }
179 if (Length > 0)
180 {
181 Size = Length;
182 }
183 else
184 {
185 /* FIXME: slow linear search! */
186 Size += step;
187 }
188 }
189 printf ("No valid buffer length found!\n");
190 return -1;
191 }
192
193
194 VOID
195 STDCALL
196 PrintStatus (NTSTATUS Status)
197 {
198 LPCSTR StatusName = NULL;
199
200 switch (Status)
201 {
202 case STATUS_INVALID_INFO_CLASS:
203 StatusName = "STATUS_INVALID_INFO_CLASS";
204 break;
205 case STATUS_INFO_LENGTH_MISMATCH:
206 StatusName = "STATUS_INFO_LENGTH_MISMATCH";
207 break;
208 case STATUS_ACCESS_VIOLATION:
209 StatusName = "STATUS_ACCESS_VIOLATION";
210 break;
211 case STATUS_NOT_IMPLEMENTED:
212 StatusName = "STATUS_NOT_IMPLEMENTED";
213 break;
214 case STATUS_BREAKPOINT:
215 StatusName = "STATUS_BREAKPOINT";
216 break;
217 }
218 if (NULL != StatusName)
219 {
220 printf ("\tStatus = %s\n", StatusName);
221 return;
222 }
223 printf ("\tStatus = 0x%08lX\n", Status );
224 }
225
226 /* Auxiliary functions */
227
228 PCHAR
229 DaysOfWeek [] =
230 {
231 "Sunday",
232 "Monday",
233 "Tuesday",
234 "Wednesday",
235 "Thursday",
236 "Friday",
237 "Saturday",
238 "Sunday"
239 };
240
241 VOID
242 STDCALL
243 PrintUtcDateTime (LPCSTR Template, PTIME UtcTime)
244 {
245 CHAR UtcTimeString [64];
246 TIME_FIELDS UtcTimeFields;
247
248 RtlTimeToTimeFields (
249 (PLARGE_INTEGER) UtcTime,
250 & UtcTimeFields
251 );
252 sprintf (
253 UtcTimeString,
254 "%s %d-%02d-%02d %02d:%02d:%02d.%03d UTC",
255 DaysOfWeek[UtcTimeFields.Weekday],
256 UtcTimeFields.Year,
257 UtcTimeFields.Month,
258 UtcTimeFields.Day,
259 UtcTimeFields.Hour,
260 UtcTimeFields.Minute,
261 UtcTimeFields.Second,
262 UtcTimeFields.Milliseconds
263 );
264 printf (
265 Template,
266 UtcTimeString
267 );
268 }
269
270
271 /**********************************************************************
272 * Dumpers
273 **********************************************************************/
274
275
276 /**********************************************************************
277 *
278 * DESCRIPTION
279 * Dump whatever we get by calling NtQuerySystemInformation with
280 * a user provided system information class id.
281 * NOTE
282 * NtQuerySystemInformation called with user class id.
283 */
284 CMD_DEF(unknown)
285 {
286 int _id = atoi ((char*)(argv[0] + 1)); /* "#24" */
287 /* ^ */
288 int Size = -1;
289 PBYTE Buffer = NULL;
290 NTSTATUS Status;
291
292
293 printf ("SystemInformation %d:\n", _id);
294 /* Find buffer size */
295 Size = FindRequiredBufferSize (_id, 1);
296 if (-1 == Size)
297 {
298 printf("\t(no data)\n");
299 return EXIT_FAILURE;
300 }
301 /* Allocate the buffer */
302 Buffer = GlobalAlloc (GMEM_ZEROINIT, Size);
303 if (NULL == Buffer)
304 {
305 printf ("#%d: could not allocate %d bytes\n", _id, Size);
306 return EXIT_FAILURE;
307 }
308 /* Query the executive */
309 Status = NtQuerySystemInformation (
310 _id,
311 Buffer,
312 Size,
313 NULL
314 );
315 if (!NT_SUCCESS(Status))
316 {
317 PrintStatus (Status);
318 FindRequiredBufferSize (_id, 1);
319 GlobalFree (Buffer);
320 return EXIT_FAILURE;
321 }
322 /* Print the data */
323 DumpData (Size, Buffer);
324 /* --- */
325 GlobalFree (Buffer);
326
327 return EXIT_SUCCESS;
328 }
329
330
331 /**********************************************************************
332 *
333 * DESCRIPTION
334 *
335 * NOTE
336 * Class 0.
337 */
338 CMD_DEF(Basic)
339 {
340 NTSTATUS Status;
341 SYSTEM_BASIC_INFORMATION Info;
342
343 if (Application.Flag.Verbose)
344 {
345 printf ("SystemBasicInformation:\n");
346 }
347 RtlZeroMemory (
348 (PVOID) & Info,
349 sizeof Info
350 );
351 Status = NtQuerySystemInformation (
352 SystemBasicInformation,
353 & Info,
354 sizeof Info,
355 NULL
356 );
357 if (STATUS_SUCCESS != Status)
358 {
359 PrintStatus (Status);
360 return EXIT_FAILURE;
361 }
362 printf ("\tAlwaysZero = 0x%08x\n", Info.AlwaysZero);
363 printf ("\tKeMaximumIncrement = %ld\n", Info.KeMaximumIncrement);
364 printf ("\tMmPageSize = %ld\n", Info.MmPageSize);
365 printf ("\tMmNumberOfPhysicalPages = %ld\n", Info.MmNumberOfPhysicalPages);
366 printf ("\tMmLowestPhysicalPage = %ld\n", Info.MmLowestPhysicalPage);
367 printf ("\tMmHighestPhysicalPage = %ld\n", Info.MmHighestPhysicalPage);
368 printf ("\tMmLowestUserAddress = 0x%08x\n", Info.MmLowestUserAddress);
369 printf ("\tMmLowestUserAddress1 = 0x%08x\n", Info.MmLowestUserAddress1);
370 printf ("\tMmHighestUserAddress = 0x%08x\n", Info.MmHighestUserAddress);
371 printf ("\tKeActiveProcessors = 0x%08x\n", Info.KeActiveProcessors);
372 printf ("\tKeNumberProcessors = %ld\n", Info.KeNumberProcessors);
373
374 return EXIT_SUCCESS;
375 }
376
377
378 /**********************************************************************
379 *
380 * DESCRIPTION
381 *
382 * NOTE
383 * Class 1.
384 */
385 CMD_DEF(Processor)
386 {
387 NTSTATUS Status;
388 SYSTEM_PROCESSOR_INFORMATION Info;
389
390 if (Application.Flag.Verbose)
391 {
392 printf ("SystemProcessorInformation:\n");
393 }
394 RtlZeroMemory (
395 (PVOID) & Info,
396 sizeof Info
397 );
398 Status = NtQuerySystemInformation (
399 SystemProcessorInformation,
400 & Info,
401 sizeof Info,
402 NULL
403 );
404 if (STATUS_SUCCESS != Status)
405 {
406 PrintStatus (Status);
407 return EXIT_FAILURE;
408 }
409 printf ("\tKeProcessorArchitecture = %ld\n", Info.KeProcessorArchitecture);
410 printf ("\tKeProcessorLevel = %ld\n", Info.KeProcessorLevel);
411 printf ("\tKeProcessorRevision = %ld\n", Info.KeProcessorRevision);
412 if (Application.Flag.Verbose)
413 {
414 printf ("\tAlwaysZero = 0x%08x\n", Info.AlwaysZero);
415 }
416 printf ("\tKeFeatureBits = %08x\n", Info.KeFeatureBits);
417
418 return EXIT_SUCCESS;
419 }
420
421
422 /**********************************************************************
423 *
424 * DESCRIPTION
425 * System performance information.
426 *
427 * NOTE
428 * Class 2.
429 */
430 CMD_DEF(Performance)
431 {
432 NTSTATUS Status = STATUS_SUCCESS;
433 PSYSTEM_PERFORMANCE_INFO Info;
434 LONG Length = 0;
435
436
437 if (Application.Flag.Verbose)
438 {
439 printf ("SystemPerformanceInformation:\n");
440 }
441 Status = NtQuerySystemInformation (
442 SystemPerformanceInformation,
443 & Info,
444 sizeof Info,
445 & Length
446 );
447 if (STATUS_SUCCESS != Status)
448 {
449 PrintStatus (Status);
450 return EXIT_FAILURE;
451 }
452 printf ("Not implemented.\n");
453 #if 0
454 LARGE_INTEGER TotalProcessorTime;
455 LARGE_INTEGER IoReadTransferCount;
456 LARGE_INTEGER IoWriteTransferCount;
457 LARGE_INTEGER IoOtherTransferCount;
458 ULONG IoReadOperationCount;
459 ULONG IoWriteOperationCount;
460 ULONG IoOtherOperationCount;
461 ULONG MmAvailablePages;
462 ULONG MmTotalCommitedPages;
463 ULONG MmTotalCommitLimit;
464 ULONG MmPeakLimit;
465 ULONG PageFaults;
466 ULONG WriteCopies;
467 ULONG TransitionFaults;
468 ULONG Unknown1;
469 ULONG DemandZeroFaults;
470 ULONG PagesInput;
471 ULONG PagesRead;
472 ULONG Unknown2;
473 ULONG Unknown3;
474 ULONG PagesOutput;
475 ULONG PageWrites;
476 ULONG Unknown4;
477 ULONG Unknown5;
478 ULONG PoolPagedBytes;
479 ULONG PoolNonPagedBytes;
480 ULONG Unknown6;
481 ULONG Unknown7;
482 ULONG Unknown8;
483 ULONG Unknown9;
484 ULONG MmTotalSystemFreePtes;
485 ULONG MmSystemCodepage;
486 ULONG MmTotalSystemDriverPages;
487 ULONG MmTotalSystemCodePages;
488 ULONG Unknown10;
489 ULONG Unknown11;
490 ULONG Unknown12;
491 ULONG MmSystemCachePage;
492 ULONG MmPagedPoolPage;
493 ULONG MmSystemDriverPage;
494 ULONG CcFastReadNoWait;
495 ULONG CcFastReadWait;
496 ULONG CcFastReadResourceMiss;
497 ULONG CcFastReadNotPossible;
498 ULONG CcFastMdlReadNoWait;
499 ULONG CcFastMdlReadWait;
500 ULONG CcFastMdlReadResourceMiss;
501 ULONG CcFastMdlReadNotPossible;
502 ULONG CcMapDataNoWait;
503 ULONG CcMapDataWait;
504 ULONG CcMapDataNoWaitMiss;
505 ULONG CcMapDataWaitMiss;
506 ULONG CcPinMappedDataCount;
507 ULONG CcPinReadNoWait;
508 ULONG CcPinReadWait;
509 ULONG CcPinReadNoWaitMiss;
510 ULONG CcPinReadWaitMiss;
511 ULONG CcCopyReadNoWait;
512 ULONG CcCopyReadWait;
513 ULONG CcCopyReadNoWaitMiss;
514 ULONG CcCopyReadWaitMiss;
515 ULONG CcMdlReadNoWait;
516 ULONG CcMdlReadWait;
517 ULONG CcMdlReadNoWaitMiss;
518 ULONG CcMdlReadWaitMiss;
519 ULONG CcReadaheadIos;
520 ULONG CcLazyWriteIos;
521 ULONG CcLazyWritePages;
522 ULONG CcDataFlushes;
523 ULONG CcDataPages;
524 ULONG ContextSwitches;
525 ULONG Unknown13;
526 ULONG Unknown14;
527 ULONG SystemCalls;
528 #endif
529 return EXIT_SUCCESS;
530 }
531
532
533 /**********************************************************************
534 *
535 * DESCRIPTION
536 *
537 * NOTE
538 * Class 3.
539 */
540 CMD_DEF(Time)
541 {
542 NTSTATUS Status;
543 SYSTEM_TIME_INFORMATION Info;
544
545 if (Application.Flag.Verbose)
546 {
547 printf ("SystemTimeInformation:\n");
548 }
549 Status = NtQuerySystemInformation (
550 SystemTimeInformation,
551 & Info,
552 sizeof Info,
553 NULL
554 );
555 if (STATUS_SUCCESS != Status)
556 {
557 PrintStatus (Status);
558 return EXIT_FAILURE;
559 }
560 PrintUtcDateTime ("\tKeBootTime : %s\n", & Info.KeBootTime);
561 PrintUtcDateTime ("\tKeSystemTime : %s\n", & Info.KeSystemTime);
562 PrintUtcDateTime ("\tExpTimeZoneBias: %s\n", & Info.ExpTimeZoneBias); /* FIXME */
563 printf ("\tExpTimeZoneId : %ld\n", Info.ExpTimeZoneId);
564 if (Application.Flag.Verbose)
565 {
566 printf ("\tUnused : %08x (?)\n", Info.Unused);
567 }
568
569 return EXIT_SUCCESS;
570 }
571
572
573 /**********************************************************************
574 *
575 * DESCRIPTION
576 *
577 * NOTE
578 * Class 4.
579 */
580 CMD_DEF(Path)
581 {
582 NTSTATUS Status;
583 SYSTEM_PATH_INFORMATION Info;
584 CHAR _Info [_MAX_PATH];
585 ULONG Length = 0;
586
587 RtlZeroMemory (& Info, _MAX_PATH);
588 Status = NtQuerySystemInformation (
589 SystemPathInformation,
590 & _Info,
591 _MAX_PATH,
592 & Length
593 );
594 if (STATUS_SUCCESS != Status)
595 {
596 PrintStatus (Status);
597 DumpData (_MAX_PATH, & _Info);
598 return EXIT_FAILURE;
599 }
600 DumpData (_MAX_PATH, & _Info);
601 return EXIT_SUCCESS;
602 }
603
604
605 /**********************************************************************
606 *
607 * DESCRIPTION
608 * A snapshot of the process+thread tables.
609 *
610 * NOTE
611 * Class 5.
612 */
613 CMD_DEF(Process)
614 {
615 NTSTATUS Status = STATUS_SUCCESS;
616 PSYSTEM_PROCESS_INFORMATION pInfo = NULL;
617 LONG Length = 0;
618 ULONG ThreadIndex;
619
620 pInfo = GlobalAlloc (GMEM_ZEROINIT, BUFFER_SIZE_DEFAULT);
621 /* FIXME: check NULL==pInfo */
622
623 if (Application.Flag.Verbose)
624 {
625 printf ("SystemProcessInformation:\n");
626 }
627 /*
628 * Obtain required buffer size
629 */
630 Status = NtQuerySystemInformation (
631 SystemProcessInformation,
632 pInfo,
633 BUFFER_SIZE_DEFAULT,
634 & Length
635 );
636 if (STATUS_SUCCESS != Status)
637 {
638 if (STATUS_INFO_LENGTH_MISMATCH == Status)
639 {
640 /*
641 * Allocate buffer
642 */
643 pInfo = GlobalReAlloc (pInfo, Length, GMEM_ZEROINIT);
644 if (NULL == pInfo)
645 {
646 printf ("\tCould not allocate memory.\n");
647 return EXIT_FAILURE;
648 }
649 }
650 else
651 {
652 PrintStatus (Status);
653 GlobalFree (pInfo);
654 return EXIT_FAILURE;
655 }
656 }
657 /*
658 * Get process+thread list from ntoskrnl.exe
659 */
660 Status = NtQuerySystemInformation (
661 SystemProcessInformation,
662 pInfo,
663 Length,
664 & Length
665 );
666 if (!NT_SUCCESS(Status))
667 {
668 PrintStatus (Status);
669 GlobalFree (pInfo);
670 return EXIT_FAILURE;
671 }
672
673 while (1)
674 {
675 wprintf (L"%s:\n", (pInfo->Name.Length ? pInfo->Name.Buffer : L"*idle*") );
676 if (Application.Flag.Verbose)
677 {
678 wprintf (L"\tRelativeOffset = 0x%08x\n", pInfo->RelativeOffset);
679 }
680 wprintf (L"\tThreads = %ld\n", pInfo->ThreadCount);
681 wprintf (L"\tHandles = %ld\n", pInfo->HandleCount);
682 wprintf (L"\tBasePriority = %ld\n", pInfo->BasePriority);
683 wprintf (L"\tPID = %ld\n", pInfo->ProcessId);
684 wprintf (L"\tPPID = %ld\n", pInfo->ParentProcessId);
685 wprintf (L"\tVirtualSize:\t\tWorkingSetSize:\n");
686 wprintf (L"\t\tPeak : %ld\t\t\tPeak : %ld\n",
687 pInfo->PeakVirtualSizeBytes,
688 pInfo->PeakWorkingSetSizeBytes
689 );
690 wprintf (L"\t\tTotal: %ld\t\t\tTotal: %ld\n",
691 pInfo->TotalVirtualSizeBytes,
692 pInfo->TotalWorkingSetSizeBytes
693 );
694 wprintf (L"\tPagedPoolUsage:\t\tNonPagedPoolUsage:\n");
695 wprintf (L"\t\tPeak : %ld\t\t\tPeak : %ld\n",
696 pInfo->PeakPagedPoolUsagePages,
697 pInfo->TotalPagedPoolUsagePages
698 );
699 wprintf (L"\t\tTotal: %ld\t\t\tTotal: %ld\n",
700 pInfo->PeakNonPagedPoolUsagePages,
701 pInfo->TotalNonPagedPoolUsagePages
702 );
703 wprintf (L"\tPageFileUsage:\n");
704 wprintf (L"\t\tPeak : %ld\n", pInfo->PeakPageFileUsageBytes);
705 wprintf (L"\t\tTotal: %ld\n", pInfo->TotalPageFileUsageBytes);
706
707 wprintf (L"\tPageFaultCount = %ld\n", pInfo->PageFaultCount);
708 wprintf (L"\tTotalPrivateBytes = %ld\n", pInfo->TotalPrivateBytes);
709 /* Threads */
710 for ( ThreadIndex = 0;
711 (ThreadIndex < pInfo->ThreadCount);
712 ThreadIndex ++
713 )
714 {
715 wprintf (L"\t%x in %x:\n",
716 pInfo->ThreadSysInfo[ThreadIndex].ClientId.UniqueThread,
717 pInfo->ThreadSysInfo[ThreadIndex].ClientId.UniqueProcess
718 );
719 PrintUtcDateTime (
720 "\t\tKernelTime = %s\n",
721 & (pInfo->ThreadSysInfo[ThreadIndex].KernelTime)
722 );
723 PrintUtcDateTime (
724 "\t\tUserTime = %s\n",
725 & (pInfo->ThreadSysInfo[ThreadIndex].UserTime)
726 );
727 PrintUtcDateTime (
728 "\t\tCreateTime = %s\n",
729 & (pInfo->ThreadSysInfo[ThreadIndex].CreateTime)
730 );
731 wprintf (L"\t\tTickCount = %ld\n",
732 pInfo->ThreadSysInfo[ThreadIndex].TickCount
733 );
734 wprintf (L"\t\tStartEIP = 0x%08x\n",
735 pInfo->ThreadSysInfo[ThreadIndex].StartEIP
736 );
737 /* CLIENT_ID ClientId; */
738 wprintf (L"\t\tDynamicPriority = %d\n",
739 pInfo->ThreadSysInfo[ThreadIndex].DynamicPriority
740 );
741 wprintf (L"\t\tBasePriority = %d\n",
742 pInfo->ThreadSysInfo[ThreadIndex].BasePriority
743 );
744 wprintf (L"\t\tnSwitches = %ld\n",
745 pInfo->ThreadSysInfo[ThreadIndex].nSwitches
746 );
747 wprintf (L"\t\tState = 0x%08x\n",
748 pInfo->ThreadSysInfo[ThreadIndex].State
749 );
750 wprintf (L"\t\tWaitReason = %ld\n",
751 pInfo->ThreadSysInfo[ThreadIndex].WaitReason
752 );
753 }
754 /* Next */
755 if (0 == pInfo->RelativeOffset)
756 {
757 break;
758 }
759 (ULONG) pInfo += pInfo->RelativeOffset;
760 }
761
762 DumpData (Length, pInfo);
763
764 GlobalFree (pInfo);
765
766 return EXIT_SUCCESS;
767 }
768
769
770 /**********************************************************************
771 *
772 * DESCRIPTION
773 *
774 * NOTE
775 * Class 6.
776 */
777 CMD_DEF(ServiceDescriptorTable)
778 {
779 NTSTATUS Status;
780 SYSTEM_SDT_INFORMATION Info;
781 ULONG Length = 0;
782
783 /* FIXME */
784 if (Application.Flag.Verbose)
785 {
786 printf ("SystemServiceDescriptorTableInfo:\n");
787 }
788 RtlZeroMemory (& Info, sizeof Info);
789 Status = NtQuerySystemInformation (
790 SystemServiceDescriptorTableInfo,
791 & Info,
792 sizeof Info,
793 & Length
794 );
795 if (STATUS_SUCCESS != Status)
796 {
797 PrintStatus (Status);
798 DumpData (Length, & Info);
799 return EXIT_FAILURE;
800 }
801 printf ("\tBufferLength = %ld\n", Info.BufferLength);
802 printf ("\tNumberOfSystemServiceTables = %ld\n", Info.NumberOfSystemServiceTables);
803 printf ("\tNumberOfServices = %ld\n", Info.NumberOfServices [0]);
804 printf ("\tServiceCounters = %ld\n", Info.ServiceCounters [0]);
805
806 DumpData (Length, & Info);
807
808 return EXIT_SUCCESS;
809 }
810
811
812 /**********************************************************************
813 *
814 * DESCRIPTION
815 *
816 * NOTE
817 * Class 7.
818 */
819 CMD_DEF(IoConfig)
820 {
821 NTSTATUS Status = STATUS_SUCCESS;
822 SYSTEM_IOCONFIG_INFORMATION Info;
823 ULONG Length = 0;
824
825 if (Application.Flag.Verbose)
826 {
827 printf ("SystemIoConfigInformation:\n");
828 }
829 Status = NtQuerySystemInformation (
830 SystemIoConfigInformation,
831 & Info,
832 sizeof Info,
833 & Length
834 );
835 if (STATUS_SUCCESS != Status)
836 {
837 PrintStatus (Status);
838 return EXIT_FAILURE;
839 }
840 printf ("\tDiskCount : %ld\n", Info.DiskCount);
841 printf ("\tFloppyCount : %ld\n", Info.FloppyCount);
842 printf ("\tCdRomCount : %ld\n", Info.CdRomCount);
843 printf ("\tTapeCount : %ld\n", Info.TapeCount);
844 printf ("\tSerialCount : %ld\n", Info.SerialCount);
845 printf ("\tParallelCount: %ld\n", Info.ParallelCount);
846
847 DumpData (Length, & Info);
848
849 return EXIT_SUCCESS;
850 }
851
852
853 /**********************************************************************
854 *
855 * DESCRIPTION
856 *
857 * NOTE
858 * Class 8.
859 */
860 CMD_DEF(ProcessorTime)
861 {
862 NTSTATUS Status;
863 SYSTEM_PROCESSORTIME_INFO Info;
864 ULONG Length = 0;
865
866 if (Application.Flag.Verbose)
867 {
868 printf ("SystemProcessorTimeInformation:\n");
869 }
870 Status = NtQuerySystemInformation (
871 SystemProcessorTimeInformation,
872 & Info,
873 sizeof Info,
874 & Length
875 );
876 if (STATUS_SUCCESS != Status)
877 {
878 PrintStatus (Status);
879 return EXIT_FAILURE;
880 }
881 PrintUtcDateTime ("\tTotalProcessorRunTime : %s\n", & Info.TotalProcessorRunTime);
882 PrintUtcDateTime ("\tTotalProcessorTime : %s\n", & Info.TotalProcessorTime);
883 PrintUtcDateTime ("\tTotalProcessorUserTime: %s\n", & Info.TotalProcessorUserTime);
884 PrintUtcDateTime ("\tTotalDPCTime : %s\n", & Info.TotalDPCTime);
885 PrintUtcDateTime ("\tTotalInterruptTime : %s\n", & Info.TotalInterruptTime);
886 printf ("\tTotalInterrupts : %ld\n", Info.TotalInterrupts);
887 if (Application.Flag.Verbose)
888 {
889 printf ("\tUnused : %08x\n", Info.Unused);
890 }
891
892 return EXIT_SUCCESS;
893 }
894
895
896 /**********************************************************************
897 *
898 * DESCRIPTION
899 *
900 * NOTE
901 * Class 9.
902 */
903 CMD_DEF(NtGlobalFlag)
904 {
905 NTSTATUS Status;
906 SYSTEM_GLOBAL_FLAG_INFO Info;
907 ULONG Length = 0;
908
909 if (Application.Flag.Verbose)
910 {
911 printf ("SystemNtGlobalFlagInformation:\n");
912 }
913 Status = NtQuerySystemInformation (
914 SystemNtGlobalFlagInformation,
915 & Info,
916 sizeof Info,
917 & Length
918 );
919 if (STATUS_SUCCESS != Status)
920 {
921 PrintStatus (Status);
922 return EXIT_FAILURE;
923 }
924 printf ("\tNtGlobalFlag: %08x\n", Info.NtGlobalFlag);
925 /* FIXME: decode each flag */
926
927 return EXIT_SUCCESS;
928 }
929
930
931 /**********************************************************************
932 *
933 * DESCRIPTION
934 *
935 * NOTE
936 * Class 10.
937 */
938 CMD_DEF(10)
939 CMD_NOT_IMPLEMENTED
940
941
942 /**********************************************************************
943 *
944 * DESCRIPTION
945 *
946 * NOTE
947 * Class 11.
948 *
949 * NOTE
950 * Code originally in Yariv Kaplan's NtDriverList,
951 * at http://www.internals.com/, adapted to ReactOS
952 * structures layout.
953 */
954 CMD_DEF(Module)
955 {
956 NTSTATUS Status = STATUS_SUCCESS;
957 PSYSTEM_MODULE_INFORMATION pInfo = NULL;
958 LONG Length = 0;
959 INT Index;
960 const PCHAR hr =
961 "-------- -------- -------- ---------------------------------------\n";
962
963
964 if (Application.Flag.Verbose)
965 {
966 printf ("SystemModuleInformation:\n");
967 }
968 /*
969 * Obtain required buffer size
970 */
971 Status = NtQuerySystemInformation (
972 SystemModuleInformation,
973 & pInfo,
974 0, /* query size */
975 & Length
976 );
977 if (STATUS_INFO_LENGTH_MISMATCH == Status)
978 {
979 /*
980 * Allocate buffer
981 */
982 pInfo = GlobalAlloc (GMEM_ZEROINIT, Length);
983 if (NULL == pInfo)
984 {
985 printf ("Could not allocate memory.\n");
986 return EXIT_FAILURE;
987 }
988 }
989 else
990 {
991 PrintStatus (Status);
992 return EXIT_FAILURE;
993 }
994 /*
995 * Get module list from ntoskrnl.exe
996 */
997 Status = NtQuerySystemInformation (
998 SystemModuleInformation,
999 pInfo,
1000 Length,
1001 & Length
1002 );
1003 if (!NT_SUCCESS(Status))
1004 {
1005 PrintStatus (Status);
1006 return EXIT_FAILURE;
1007 }
1008 printf ("Index Address Size Name\n");
1009 printf (hr);
1010
1011 for ( Index = 0;
1012 (Index < (int) pInfo->Count);
1013 Index ++
1014 )
1015 {
1016 printf (
1017 "%8x %08x %8x %s\n",
1018 pInfo->Module[Index].ModuleEntryIndex,
1019 pInfo->Module[Index].ModuleBaseAddress,
1020 pInfo->Module[Index].ModuleSize,
1021 pInfo->Module[Index].ModuleName
1022 );
1023 }
1024 printf (hr);
1025
1026 GlobalFree (pInfo);
1027
1028 return EXIT_SUCCESS;
1029 }
1030
1031
1032 /**********************************************************************
1033 *
1034 * DESCRIPTION
1035 *
1036 * NOTE
1037 * Class 12.
1038 */
1039 CMD_DEF(ResourceLock)
1040 {
1041 NTSTATUS Status = STATUS_SUCCESS;
1042 PSYSTEM_RESOURCE_LOCK_INFO pInfo = NULL;
1043 LONG Length = 0;
1044 INT Index;
1045 const PCHAR hr =
1046 "-------- -------- -------- -------- -------- -------- ------------\n";
1047
1048 pInfo = GlobalAlloc (GMEM_ZEROINIT, BUFFER_SIZE_DEFAULT);
1049 /* FIXME: check NULL==pInfo */
1050
1051 if (Application.Flag.Verbose)
1052 {
1053 printf ("SystemResourceLockInformation:\n");
1054 }
1055 /*
1056 * Obtain required buffer size
1057 */
1058 Status = NtQuerySystemInformation (
1059 SystemResourceLockInformation,
1060 pInfo,
1061 BUFFER_SIZE_DEFAULT, /* query size */
1062 & Length
1063 );
1064 if (STATUS_SUCCESS != Status)
1065 {
1066 if (STATUS_INFO_LENGTH_MISMATCH == Status)
1067 {
1068 /*
1069 * Allocate buffer
1070 */
1071 pInfo = GlobalReAlloc (pInfo, Length, GMEM_ZEROINIT);
1072 if (NULL == pInfo)
1073 {
1074 printf ("Could not allocate memory.\n");
1075 return EXIT_FAILURE;
1076 }
1077 }
1078 else
1079 {
1080 PrintStatus (Status);
1081 GlobalFree (pInfo);
1082 return EXIT_FAILURE;
1083 }
1084 }
1085 /*
1086 * Get locked resource list from ntoskrnl.exe
1087 */
1088 Status = NtQuerySystemInformation (
1089 SystemResourceLockInformation,
1090 pInfo,
1091 Length,
1092 & Length
1093 );
1094 if (!NT_SUCCESS(Status))
1095 {
1096 PrintStatus (Status);
1097 GlobalFree (pInfo);
1098 return EXIT_FAILURE;
1099 }
1100 printf ("Address Active # Content# Sh/Wait Exc/Wait\n");
1101 printf (hr);
1102
1103 for ( Index = 0;
1104 (Index < (int) pInfo->Count);
1105 Index ++
1106 )
1107 {
1108 printf (
1109 "%08x %8ld %8ld %8ld %8ld %08x\n",
1110 pInfo->Lock[Index].ResourceAddress,
1111 pInfo->Lock[Index].ActiveCount,
1112 pInfo->Lock[Index].ContentionCount,
1113 pInfo->Lock[Index].NumberOfSharedWaiters,
1114 pInfo->Lock[Index].NumberOfExclusiveWaiters,
1115 pInfo->Lock[Index].Unknown
1116 );
1117 }
1118 printf (hr);
1119
1120 GlobalFree (pInfo);
1121
1122 return EXIT_SUCCESS;
1123 }
1124
1125
1126 /**********************************************************************
1127 *
1128 * DESCRIPTION
1129 *
1130 * NOTE
1131 * Class 13.
1132 */
1133 CMD_DEF(13)
1134 CMD_NOT_IMPLEMENTED
1135
1136
1137 /**********************************************************************
1138 *
1139 * DESCRIPTION
1140 *
1141 * NOTE
1142 * Class 14.
1143 */
1144 CMD_DEF(14)
1145 CMD_NOT_IMPLEMENTED
1146
1147
1148 /**********************************************************************
1149 *
1150 * DESCRIPTION
1151 *
1152 * NOTE
1153 * Class 15.
1154 */
1155 CMD_DEF(15)
1156 CMD_NOT_IMPLEMENTED
1157
1158
1159 /**********************************************************************
1160 *
1161 * DESCRIPTION
1162 *
1163 * NOTE
1164 * Class 16. You can not pass 0 as the initial output buffer's
1165 * size to get back the needed buffer size.
1166 */
1167 CMD_DEF(Handle)
1168 {
1169 NTSTATUS Status = STATUS_SUCCESS;
1170 PSYSTEM_HANDLE_INFORMATION pInfo = NULL;
1171 LONG Length = 0;
1172 INT Index;
1173 const PCHAR hr =
1174 "-------- -------- -------- -------- --------\n";
1175
1176 pInfo = GlobalAlloc (GMEM_ZEROINIT, BUFFER_SIZE_DEFAULT);
1177
1178 if (Application.Flag.Verbose)
1179 {
1180 printf ("SystemHandleInformation:\n");
1181 }
1182 /*
1183 * Obtain required buffer size
1184 */
1185 Status = NtQuerySystemInformation (
1186 SystemHandleInformation,
1187 pInfo,
1188 BUFFER_SIZE_DEFAULT,
1189 & Length
1190 );
1191 if (STATUS_SUCCESS != Status)
1192 {
1193 if (STATUS_INFO_LENGTH_MISMATCH == Status)
1194 {
1195 /*
1196 * Allocate buffer
1197 */
1198 pInfo = GlobalReAlloc (pInfo, Length, GMEM_ZEROINIT);
1199 if (NULL == pInfo)
1200 {
1201 printf ("\tCould not allocate memory.\n");
1202 return EXIT_FAILURE;
1203 }
1204 }
1205 else
1206 {
1207 PrintStatus (Status);
1208 GlobalFree (pInfo);
1209 return EXIT_FAILURE;
1210 }
1211 }
1212 /*
1213 * Get handle table from ntoskrnl.exe
1214 */
1215 Status = NtQuerySystemInformation (
1216 SystemHandleInformation,
1217 pInfo,
1218 Length,
1219 & Length
1220 );
1221 if (!NT_SUCCESS(Status))
1222 {
1223 PrintStatus (Status);
1224 GlobalFree (pInfo);
1225 return EXIT_FAILURE;
1226 }
1227 printf ("Handle OwnerPID ObjType ObjPtr Access\n");
1228 printf (hr);
1229
1230 for ( Index = 0;
1231 (Index < (int) pInfo->Count);
1232 Index ++
1233 )
1234 {
1235 printf (
1236 "%8x %8x %8x %8x %8x\n",
1237 pInfo->Handle[Index].HandleValue,
1238 pInfo->Handle[Index].OwnerPid,
1239 pInfo->Handle[Index].ObjectType,
1240 pInfo->Handle[Index].ObjectPointer,
1241 pInfo->Handle[Index].AccessMask
1242 );
1243 }
1244 printf (hr);
1245
1246 DumpData (Length, pInfo);
1247
1248 GlobalFree (pInfo);
1249
1250 return EXIT_SUCCESS;
1251 }
1252
1253
1254 /**********************************************************************
1255 *
1256 * DESCRIPTION
1257 *
1258 * NOTE
1259 * Class 17.
1260 */
1261 CMD_DEF(Object)
1262 CMD_NOT_IMPLEMENTED
1263
1264
1265 /**********************************************************************
1266 *
1267 * DESCRIPTION
1268 *
1269 * NOTE
1270 * Class 18.
1271 */
1272 CMD_DEF(PageFile)
1273 {
1274 NTSTATUS Status;
1275 PSYSTEM_PAGEFILE_INFORMATION pInfo = NULL;
1276 LONG Length = 0;
1277
1278 pInfo = GlobalAlloc (GMEM_ZEROINIT, BUFFER_SIZE_DEFAULT);
1279 /* FIXME: check pInfo */
1280
1281 if (Application.Flag.Verbose)
1282 {
1283 printf ("SystemPageFileInformation:\n");
1284 }
1285 Status = NtQuerySystemInformation(
1286 SystemPageFileInformation,
1287 pInfo,
1288 BUFFER_SIZE_DEFAULT,
1289 & Length
1290 );
1291 if (STATUS_SUCCESS != Status)
1292 {
1293 if (STATUS_INFO_LENGTH_MISMATCH == Status)
1294 {
1295 /*
1296 * Allocate buffer
1297 */
1298 pInfo = GlobalReAlloc (pInfo, Length, GMEM_ZEROINIT);
1299 if (NULL == pInfo)
1300 {
1301 printf ("Could not allocate memory.\n");
1302 return EXIT_FAILURE;
1303 }
1304 }
1305 else
1306 {
1307 PrintStatus (Status);
1308 GlobalFree (pInfo);
1309 return EXIT_FAILURE;
1310 }
1311 }
1312 Status = NtQuerySystemInformation (
1313 SystemPageFileInformation,
1314 pInfo,
1315 Length,
1316 & Length
1317 );
1318 if (!NT_SUCCESS(Status))
1319 {
1320 PrintStatus (Status);
1321 GlobalFree (pInfo);
1322 return EXIT_FAILURE;
1323 }
1324
1325 while (1)
1326 {
1327 wprintf (L"\t\"%s\":\n", pInfo->PagefileFileName.Buffer);
1328 if (Application.Flag.Verbose)
1329 {
1330 wprintf (L"\t\tRelativeOffset = %08x\n", pInfo->RelativeOffset);
1331 }
1332 wprintf (L"\t\tCurrentSizePages = %ld\n", pInfo->CurrentSizePages);
1333 wprintf (L"\t\tTotalUsedPages = %ld\n", pInfo->TotalUsedPages);
1334 wprintf (L"\t\tPeakUsedPages = %ld\n", pInfo->PeakUsedPages);
1335
1336 if (0 == pInfo->RelativeOffset)
1337 {
1338 break;
1339 }
1340 printf ("\n");
1341 (ULONG) pInfo += pInfo->RelativeOffset;
1342 }
1343
1344 DumpData (Length, pInfo);
1345
1346 GlobalFree (pInfo);
1347
1348 return EXIT_SUCCESS;
1349 }
1350
1351
1352 /**********************************************************************
1353 *
1354 * DESCRIPTION
1355 *
1356 * NOTE
1357 * Class 19.
1358 */
1359 CMD_DEF(InstructionEmulation)
1360 {
1361 NTSTATUS Status;
1362 SYSTEM_VDM_INFORMATION Info;
1363
1364 if (Application.Flag.Verbose)
1365 {
1366 printf ("SystemInstructionEmulationInfo:\n");
1367 }
1368 RtlZeroMemory (& Info, sizeof Info);
1369 Status = NtQuerySystemInformation (
1370 SystemInstructionEmulationInfo,
1371 & Info,
1372 sizeof Info,
1373 NULL
1374 );
1375 if (!NT_SUCCESS(Status))
1376 {
1377 PrintStatus (Status);
1378 return EXIT_FAILURE;
1379 }
1380 printf ("\tVdmSegmentNotPresentCount = %ld\n", Info.VdmSegmentNotPresentCount);
1381 printf ("\tVdmINSWCount = %ld\n", Info.VdmINSWCount);
1382 printf ("\tVdmESPREFIXCount = %ld\n", Info.VdmESPREFIXCount);
1383 printf ("\tVdmCSPREFIXCount = %ld\n", Info.VdmCSPREFIXCount);
1384 printf ("\tVdmSSPREFIXCount = %ld\n", Info.VdmSSPREFIXCount);
1385 printf ("\tVdmDSPREFIXCount = %ld\n", Info.VdmDSPREFIXCount);
1386 printf ("\tVdmFSPREFIXCount = %ld\n", Info.VdmFSPREFIXCount);
1387 printf ("\tVdmGSPREFIXCount = %ld\n", Info.VdmGSPREFIXCount);
1388 printf ("\tVdmOPER32PREFIXCount = %ld\n", Info.VdmOPER32PREFIXCount);
1389 printf ("\tVdmADDR32PREFIXCount = %ld\n", Info.VdmADDR32PREFIXCount);
1390 printf ("\tVdmINSBCount = %ld\n", Info.VdmINSBCount);
1391 printf ("\tVdmINSWV86Count = %ld\n", Info.VdmINSWV86Count);
1392 printf ("\tVdmOUTSBCount = %ld\n", Info.VdmOUTSBCount);
1393 printf ("\tVdmOUTSWCount = %ld\n", Info.VdmOUTSWCount);
1394 printf ("\tVdmPUSHFCount = %ld\n", Info.VdmPUSHFCount);
1395 printf ("\tVdmPOPFCount = %ld\n", Info.VdmPOPFCount);
1396 printf ("\tVdmINTNNCount = %ld\n", Info.VdmINTNNCount);
1397 printf ("\tVdmINTOCount = %ld\n", Info.VdmINTOCount);
1398 printf ("\tVdmIRETCount = %ld\n", Info.VdmIRETCount);
1399 printf ("\tVdmINBIMMCount = %ld\n", Info.VdmINBIMMCount);
1400 printf ("\tVdmINWIMMCount = %ld\n", Info.VdmINWIMMCount);
1401 printf ("\tVdmOUTBIMMCount = %ld\n", Info.VdmOUTBIMMCount);
1402 printf ("\tVdmOUTWIMMCount = %ld\n", Info.VdmOUTWIMMCount);
1403 printf ("\tVdmINBCount = %ld\n", Info.VdmINBCount);
1404 printf ("\tVdmINWCount = %ld\n", Info.VdmINWCount);
1405 printf ("\tVdmOUTBCount = %ld\n", Info.VdmOUTBCount);
1406 printf ("\tVdmOUTWCount = %ld\n", Info.VdmOUTWCount);
1407 printf ("\tVdmLOCKPREFIXCount = %ld\n", Info.VdmLOCKPREFIXCount);
1408 printf ("\tVdmREPNEPREFIXCount = %ld\n", Info.VdmREPNEPREFIXCount);
1409 printf ("\tVdmREPPREFIXCount = %ld\n", Info.VdmREPPREFIXCount);
1410 printf ("\tVdmHLTCount = %ld\n", Info.VdmHLTCount);
1411 printf ("\tVdmCLICount = %ld\n", Info.VdmCLICount);
1412 printf ("\tVdmSTICount = %ld\n", Info.VdmSTICount);
1413 printf ("\tVdmBopCount = %ld\n", Info.VdmBopCount);
1414
1415 return EXIT_SUCCESS;
1416 }
1417
1418
1419 /**********************************************************************
1420 *
1421 * DESCRIPTION
1422 *
1423 * NOTE
1424 * Class 20.
1425 */
1426 CMD_DEF(20)
1427 CMD_NOT_IMPLEMENTED
1428
1429
1430 /**********************************************************************
1431 *
1432 * DESCRIPTION
1433 *
1434 * NOTE
1435 * Class 21.
1436 */
1437 CMD_DEF(Cache)
1438 {
1439 NTSTATUS Status;
1440 SYSTEM_CACHE_INFORMATION Si;
1441
1442 if (Application.Flag.Verbose)
1443 {
1444 printf ("SystemCacheInformation:\n");
1445 }
1446 RtlZeroMemory (
1447 (PVOID) & Si,
1448 sizeof Si
1449 );
1450 Status = NtQuerySystemInformation (
1451 SystemCacheInformation,
1452 & Si,
1453 sizeof Si,
1454 0
1455 );
1456 if (!NT_SUCCESS(Status))
1457 {
1458 PrintStatus (Status);
1459 return EXIT_FAILURE;
1460 }
1461 printf ("\tSize:\n");
1462 printf ("\t\tCurrent = %ld\n", Si.CurrentSize);
1463 printf ("\t\tPeak = %ld\n\n", Si.PeakSize);
1464 printf ("\tPageFaults:\n\t\tCount = %ld\n\n", Si.PageFaultCount);
1465 printf ("\tWorking Set:\n");
1466 printf ("\t\tMinimum = %ld\n", Si.MinimumWorkingSet );
1467 printf ("\t\tMaximum = %ld\n", Si.MaximumWorkingSet );
1468
1469 return EXIT_SUCCESS;
1470 }
1471
1472
1473 /**********************************************************************
1474 *
1475 * DESCRIPTION
1476 * Get statistic data about tagged pools. Not implemented in the
1477 * free build.
1478 *
1479 * NOTE
1480 * Class 22.
1481 */
1482 CMD_DEF(PoolTag)
1483 {
1484 NTSTATUS Status;
1485 PSYSTEM_POOL_TAG_INFO pInfo = NULL;
1486 ULONG Length;
1487 ULONG PoolIndex;
1488
1489 pInfo = GlobalAlloc (GMEM_ZEROINIT, BUFFER_SIZE_DEFAULT);
1490 /* FIXME: check pInfo */
1491
1492 if (Application.Flag.Verbose)
1493 {
1494 printf ("SystemPoolTagInformation:\n");
1495 }
1496 Status = NtQuerySystemInformation(
1497 SystemPoolTagInformation,
1498 pInfo,
1499 BUFFER_SIZE_DEFAULT,
1500 & Length
1501 );
1502 if (STATUS_SUCCESS != Status)
1503 {
1504 if (STATUS_INFO_LENGTH_MISMATCH == Status)
1505 {
1506 /*
1507 * Allocate buffer
1508 */
1509 pInfo = GlobalReAlloc (pInfo, Length, GMEM_ZEROINIT);
1510 if (NULL == pInfo)
1511 {
1512 printf ("Could not allocate memory.\n");
1513 return EXIT_FAILURE;
1514 }
1515 }
1516 else
1517 {
1518 PrintStatus (Status);
1519 GlobalFree (pInfo);
1520 return EXIT_FAILURE;
1521 }
1522 }
1523 Status = NtQuerySystemInformation (
1524 SystemPoolTagInformation,
1525 pInfo,
1526 Length,
1527 & Length
1528 );
1529 if (!NT_SUCCESS(Status))
1530 {
1531 PrintStatus (Status);
1532 GlobalFree (pInfo);
1533 return EXIT_FAILURE;
1534 }
1535
1536 for ( PoolIndex = 0;
1537 (PoolIndex < pInfo->Count);
1538 PoolIndex ++
1539 )
1540 {
1541 wprintf (L"\t%08x:\n", pInfo->PoolEntry[PoolIndex].Tag);
1542 wprintf (L"\t\tPaged:\t\tNon Paged:\n");
1543 wprintf (
1544 L"\t\tAllocationCount = %ld\tAllocationCount = %ld\n",
1545 pInfo->PoolEntry[PoolIndex].Paged.AllocationCount,
1546 pInfo->PoolEntry[PoolIndex].NonPaged.AllocationCount
1547 );
1548 wprintf (
1549 L"\t\tFreeCount = %ld\tFreeCount = %ld\n",
1550 pInfo->PoolEntry[PoolIndex].Paged.FreeCount,
1551 pInfo->PoolEntry[PoolIndex].NonPaged.FreeCount
1552 );
1553 wprintf (
1554 L"\t\tSizeBytes = %ld\tSizeBytes = %ld\n",
1555 pInfo->PoolEntry[PoolIndex].Paged.SizeBytes,
1556 pInfo->PoolEntry[PoolIndex].NonPaged.SizeBytes
1557 );
1558 }
1559
1560 DumpData (Length, pInfo);
1561
1562 GlobalFree (pInfo);
1563
1564 return EXIT_SUCCESS;
1565 }
1566
1567
1568 /**********************************************************************
1569 *
1570 * DESCRIPTION
1571 *
1572 * NOTE
1573 * Class 23.
1574 */
1575 CMD_DEF(ProcessorSchedule)
1576 {
1577 NTSTATUS Status;
1578 SYSTEM_PROCESSOR_SCHEDULE_INFO Info;
1579
1580 if (Application.Flag.Verbose)
1581 {
1582 printf ("SystemProcessorScheduleInfo:\n");
1583 }
1584 RtlZeroMemory (
1585 & Info,
1586 sizeof Info
1587 );
1588 Status = NtQuerySystemInformation (
1589 SystemProcessorScheduleInfo,
1590 & Info,
1591 sizeof Info,
1592 NULL
1593 );
1594 if (STATUS_SUCCESS != Status)
1595 {
1596 PrintStatus (Status);
1597 return EXIT_FAILURE;
1598 }
1599
1600 printf ("\tnContextSwitches = %ld\n", Info.nContextSwitches);
1601 printf ("\tnDPCQueued = %ld\n", Info.nDPCQueued);
1602 printf ("\tnDPCRate = %ld\n", Info.nDPCRate);
1603 printf ("\tTimerResolution = %ld\n", Info.TimerResolution);
1604 printf ("\tnDPCBypasses = %ld\n", Info.nDPCBypasses);
1605 printf ("\tnAPCBypasses = %ld\n", Info.nAPCBypasses);
1606
1607 DumpData (sizeof Info, & Info);
1608
1609 return EXIT_SUCCESS;
1610
1611 }
1612
1613
1614 /**********************************************************************
1615 *
1616 * DESCRIPTION
1617 *
1618 * NOTE
1619 * Class 24.
1620 */
1621 CMD_DEF(Dpc)
1622 {
1623 NTSTATUS Status;
1624 SYSTEM_DPC_INFORMATION Info;
1625
1626 if (Application.Flag.Verbose)
1627 {
1628 printf ("SystemDpcInformation:\n");
1629 }
1630 RtlZeroMemory (
1631 & Info,
1632 sizeof Info
1633 );
1634 Status = NtQuerySystemInformation (
1635 SystemDpcInformation,
1636 & Info,
1637 sizeof Info,
1638 NULL
1639 );
1640 if (STATUS_SUCCESS != Status)
1641 {
1642 PrintStatus (Status);
1643 return EXIT_FAILURE;
1644 }
1645
1646 if (Application.Flag.Verbose)
1647 {
1648 printf ("\tUnused = %ld\n", Info.Unused);
1649 }
1650 printf ("\tKiMaximumDpcQueueDepth = %ld\n", Info.KiMaximumDpcQueueDepth);
1651 printf ("\tKiMinimumDpcRate = %ld\n", Info.KiMinimumDpcRate);
1652 printf ("\tKiAdjustDpcThreshold = %ld\n", Info.KiAdjustDpcThreshold);
1653 printf ("\tKiIdealDpcRate = %ld\n", Info.KiIdealDpcRate);
1654
1655 DumpData (sizeof Info, & Info);
1656
1657 return EXIT_SUCCESS;
1658 }
1659
1660
1661 /**********************************************************************
1662 *
1663 * DESCRIPTION
1664 *
1665 * NOTE
1666 * Class 25.
1667 */
1668 CMD_DEF(25)
1669 CMD_NOT_IMPLEMENTED
1670
1671
1672 /**********************************************************************
1673 *
1674 * DESCRIPTION
1675 *
1676 * NOTE
1677 * Class 26.
1678 */
1679 INT CMD_LoadImage (INT argc, LPCSTR argv [])
1680 CMD_NOT_IMPLEMENTED
1681
1682 /**********************************************************************
1683 *
1684 * DESCRIPTION
1685 *
1686 * NOTE
1687 * Class 27.
1688 */
1689 CMD_DEF(UnloadImage)
1690 CMD_NOT_IMPLEMENTED
1691
1692
1693 /**********************************************************************
1694 *
1695 * DESCRIPTION
1696 *
1697 * NOTE
1698 * Class 28.
1699 */
1700 CMD_DEF(TimeAdjustment)
1701 {
1702 NTSTATUS Status = STATUS_SUCCESS;
1703 SYSTEM_TIME_ADJUSTMENT_INFO Info;
1704
1705 if (Application.Flag.Verbose)
1706 {
1707 printf ("SystemTimeAdjustmentInformation:\n");
1708 }
1709 RtlZeroMemory (& Info, sizeof Info);
1710 Status = NtQuerySystemInformation (
1711 SystemTimeAdjustmentInformation,
1712 & Info,
1713 sizeof Info,
1714 0
1715 );
1716 if (!NT_SUCCESS(Status))
1717 {
1718 PrintStatus (Status);
1719 return EXIT_FAILURE;
1720 }
1721 printf ("\tKeTimeAdjustment = %ld\n", Info.KeTimeAdjustment);
1722 printf ("\tKeMaximumIncrement = %ld\n", Info.KeMaximumIncrement);
1723 printf ("\tKeTimeSynchronization = %s\n", TF(Info.KeTimeSynchronization));
1724
1725 return EXIT_SUCCESS;
1726 }
1727
1728
1729 /**********************************************************************
1730 *
1731 * DESCRIPTION
1732 *
1733 * NOTE
1734 * Class 29.
1735 */
1736 CMD_DEF(29)
1737 CMD_NOT_IMPLEMENTED
1738
1739
1740 /**********************************************************************
1741 *
1742 * DESCRIPTION
1743 *
1744 * NOTE
1745 * Class 30.
1746 */
1747 CMD_DEF(30)
1748 CMD_NOT_IMPLEMENTED
1749
1750
1751 /**********************************************************************
1752 *
1753 * DESCRIPTION
1754 *
1755 * NOTE
1756 * Class 31.
1757 */
1758 CMD_DEF(31)
1759 CMD_NOT_IMPLEMENTED
1760
1761
1762 /**********************************************************************
1763 *
1764 * DESCRIPTION
1765 *
1766 * NOTE
1767 * Class 32.
1768 */
1769 CMD_DEF(CrashDumpSection)
1770 CMD_NOT_IMPLEMENTED
1771
1772
1773 /**********************************************************************
1774 *
1775 * DESCRIPTION
1776 *
1777 * NOTE
1778 * Class 33.
1779 */
1780 CMD_DEF(ProcessorFaultCount)
1781 CMD_NOT_IMPLEMENTED
1782
1783
1784 /**********************************************************************
1785 *
1786 * DESCRIPTION
1787 *
1788 * NOTE
1789 * Class 34.
1790 */
1791 CMD_DEF(CrashDumpState)
1792 CMD_NOT_IMPLEMENTED
1793
1794
1795 /**********************************************************************
1796 *
1797 * DESCRIPTION
1798 *
1799 * NOTE
1800 * Class 35.
1801 */
1802 CMD_DEF(Debugger)
1803 {
1804 NTSTATUS Status;
1805 SYSTEM_DEBUGGER_INFO Info;
1806
1807 RtlZeroMemory (& Info, sizeof Info);
1808 Status = NtQuerySystemInformation (
1809 SystemDebuggerInformation,
1810 & Info,
1811 sizeof Info,
1812 NULL
1813 );
1814 if (STATUS_SUCCESS != Status)
1815 {
1816 PrintStatus (Status);
1817 return EXIT_FAILURE;
1818 }
1819 printf ("\tKdDebuggerEnabled = %s\n", TF(Info.KdDebuggerEnabled));
1820 printf ("\tKdDebuggerPresent = %s\n", TF(Info.KdDebuggerPresent));
1821
1822 DumpData (sizeof Info, & Info);
1823
1824 return EXIT_SUCCESS;
1825 }
1826
1827
1828 /**********************************************************************
1829 *
1830 * DESCRIPTION
1831 *
1832 * NOTE
1833 * Class 36.
1834 */
1835 CMD_DEF(ThreadSwitchCounters)
1836 CMD_NOT_IMPLEMENTED
1837
1838
1839 /**********************************************************************
1840 *
1841 * DESCRIPTION
1842 *
1843 * NOTE
1844 * Class 37.
1845 */
1846 CMD_DEF(Quota)
1847 {
1848 NTSTATUS Status = STATUS_SUCCESS;
1849 SYSTEM_QUOTA_INFORMATION Info;
1850
1851 if (Application.Flag.Verbose)
1852 {
1853 printf ("SystemQuotaInformation:\n");
1854 }
1855 RtlZeroMemory (& Info, sizeof Info);
1856 Status = NtQuerySystemInformation (
1857 SystemQuotaInformation,
1858 & Info,
1859 sizeof Info,
1860 0
1861 );
1862 if (!NT_SUCCESS(Status))
1863 {
1864 PrintStatus (Status);
1865 return EXIT_FAILURE;
1866 }
1867 printf ("\tCmpGlobalQuota = %ld\n", Info.CmpGlobalQuota);
1868 printf ("\tCmpGlobalQuotaUsed = %ld\n", Info.CmpGlobalQuotaUsed);
1869 printf ("\tMmSizeofPagedPoolInBytes = %ld\n", Info.MmSizeofPagedPoolInBytes);
1870
1871 return EXIT_SUCCESS;
1872 }
1873
1874
1875 /**********************************************************************
1876 *
1877 * DESCRIPTION
1878 *
1879 * NOTE
1880 * Class 38.
1881 */
1882 CMD_DEF(LoadDriver)
1883 CMD_NOT_IMPLEMENTED
1884
1885
1886 /**********************************************************************
1887 *
1888 * DESCRIPTION
1889 *
1890 * NOTE
1891 * Class 39.
1892 */
1893 CMD_DEF(PrioritySeparation)
1894 CMD_NOT_IMPLEMENTED
1895
1896
1897 /**********************************************************************
1898 *
1899 * DESCRIPTION
1900 *
1901 * NOTE
1902 * Class 40.
1903 */
1904 CMD_DEF(40)
1905 CMD_NOT_IMPLEMENTED
1906
1907
1908 /**********************************************************************
1909 *
1910 * DESCRIPTION
1911 *
1912 * NOTE
1913 * Class 41.
1914 */
1915 CMD_DEF(41)
1916 CMD_NOT_IMPLEMENTED
1917
1918
1919 /**********************************************************************
1920 *
1921 * DESCRIPTION
1922 *
1923 * NOTE
1924 * Class 42.
1925 */
1926 CMD_DEF(42)
1927 CMD_NOT_IMPLEMENTED
1928
1929
1930 /**********************************************************************
1931 *
1932 * DESCRIPTION
1933 *
1934 * NOTE
1935 * Class 43.
1936 */
1937 CMD_DEF(43)
1938 CMD_NOT_IMPLEMENTED
1939
1940
1941 /**********************************************************************
1942 *
1943 * DESCRIPTION
1944 * Dump the system TIME_ZONE_INFORMATION object.
1945 *
1946 * NOTE
1947 * Class 44.
1948 */
1949 CMD_DEF(TimeZone)
1950 {
1951 #if 0
1952 NTSTATUS Status;
1953 TIME_ZONE_INFORMATION Tzi;
1954 WCHAR Name [33];
1955
1956 if (Application.Flag.Verbose)
1957 {
1958 printf ("SystemTimeZoneInformation:\n");
1959 }
1960 RtlZeroMemory (& Tzi, sizeof Tzi);
1961 Status = NtQuerySystemInformation(
1962 SystemTimeZoneInformation,
1963 & Tzi,
1964 sizeof Tzi,
1965 0
1966 );
1967 if (!NT_SUCCESS(Status))
1968 {
1969 PrintStatus (Status);
1970 return EXIT_FAILURE;
1971 }
1972 printf (
1973 "12h/24h.....: %dh\n",
1974 0 /* FIXME: */
1975 );
1976 printf (
1977 "Bias........: %d'\n",
1978 Tzi.Bias /* LONG */
1979 );
1980
1981 printf ("Standard\n");
1982 RtlZeroMemory (
1983 (PVOID) Name,
1984 sizeof Name
1985 );
1986 lstrcpynW (
1987 Name,
1988 Tzi.StandardName, /* WCHAR [32] */
1989 32
1990 );
1991 wprintf (
1992 L"\tName: \"%s\"\n",
1993 Name
1994 );
1995
1996 PrintUtcDateTime (
1997 "\tDate: %s\n",
1998 & Tzi.StandardDate /* SYSTEMTIME */
1999 );
2000
2001 printf ("\tBias: %d'\n",
2002 Tzi.StandardBias /* LONG */
2003 );
2004
2005 printf ("Daylight\n");
2006 RtlZeroMemory (
2007 (PVOID) Name,
2008 sizeof Name
2009 );
2010 lstrcpynW (
2011 Name,
2012 Tzi.DaylightName, /* WCHAR [32] */
2013 32
2014 );
2015 wprintf (
2016 L"\tName: \"%s\"\n",
2017 Name
2018 );
2019
2020 PrintUtcDateTime (
2021 "\tDate: %s\n",
2022 & Tzi.DaylightDate /* SYSTEMTIME */
2023 );
2024
2025 printf (
2026 "\tBias: %d'\n",
2027 Tzi.DaylightBias /* LONG */
2028 );
2029
2030 #endif
2031 return EXIT_SUCCESS;
2032 }
2033
2034
2035 /**********************************************************************
2036 *
2037 * DESCRIPTION
2038 *
2039 * NOTE
2040 * Class 45.
2041 */
2042 CMD_DEF(Lookaside)
2043 CMD_NOT_IMPLEMENTED
2044
2045
2046 /**********************************************************************
2047 * Miscellanea Commands
2048 **********************************************************************/
2049
2050 CMD_DEF(ver)
2051 {
2052 INT Total = 0;
2053
2054 Total =
2055 printf (
2056 "ReactOS Operating System - http://www.reactos.com/\n"
2057 "QSI - Query System Information (compiled on %s, %s)\n"
2058 "Copyright (c) 1999, 2000 Emanuele Aliberti et alii\n\n",
2059 __DATE__, __TIME__
2060 );
2061
2062 if (Application.Flag.Verbose)
2063 {
2064 Total +=
2065 printf (
2066 "This program is free software; you can redistribute it and/or modify\n"
2067 "it under the terms of the GNU General Public License as published by\n"
2068 "the Free Software Foundation; either version 2 of the License, or\n"
2069 "(at your option) any later version.\n\n"
2070
2071 "This program is distributed in the hope that it will be useful,\n"
2072 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
2073 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
2074 "GNU General Public License for more details.\n\n"
2075
2076 "You should have received a copy of the GNU General Public License\n"
2077 "along with this program; if not, write to the Free Software\n"
2078 "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
2079 "(See also http://www.fsf.org/).\n"
2080 );
2081 }
2082 return (Total);
2083 }
2084
2085
2086 CMD_DEF(exit)
2087 {
2088 Application.Active = FALSE;
2089 return EXIT_SUCCESS;
2090 }
2091
2092
2093 extern COMMAND_DESCRIPTOR Commands [];
2094
2095 CMD_DEF(help)
2096 {
2097 int i;
2098
2099 if (Application.Flag.Verbose)
2100 {
2101 printf ("Commands:\n");
2102 }
2103 for ( i = 0;
2104 (NULL != Commands[i].Name);
2105 i ++
2106 )
2107 {
2108 printf (
2109 (strlen (Commands[i].Name) > 7)
2110 ? "%s\t: %s\n"
2111 : "%s\t\t: %s\n",
2112 Commands[i].Name,
2113 Commands[i].Description
2114 );
2115 }
2116 return EXIT_SUCCESS;
2117 }
2118
2119
2120 CMD_DEF(credits)
2121 {
2122 return
2123 printf (
2124 "\nReactOS (http://www.reactos.com/):\n"
2125 "\tEmanuele Aliberti\n"
2126 "\tEric Kohl\n\n"
2127
2128 "HandleEx:\n"
2129 "\tMark Russinovich (http://www.sysinternals.com/)\n\n"
2130
2131 "NtDriverList:\n"
2132 "\tYariv Kaplan (http://www.internals.com/)\n\n"
2133
2134 "Undocumented SYSTEM_POOL_INFORMATION:\n"
2135 "\tKlaus P. Gerlicher\n\n"
2136
2137 "Undocumented Windows NT:\n"
2138 "\tPrasad Dabak, Sandeep Phadke, and Milind Borate\n\n"
2139
2140 "Windows NT/2000 Native API Reference:\n"
2141 "\tGary Nebbet\n\n"
2142
2143 "comp.os.ms-windows.programmer.nt.kernel-mode\n"
2144 "\t(many postings with sample code)\n"
2145 );
2146 }
2147
2148
2149 CMD_DEF(verbose)
2150 {
2151 Application.Flag.Verbose = ~Application.Flag.Verbose;
2152 return printf (
2153 "Verbose mode is %s.\n",
2154 ONOFF(Application.Flag.Verbose)
2155 );
2156 }
2157
2158
2159 CMD_DEF(dump)
2160 {
2161 Application.Flag.Dump = ~Application.Flag.Dump;
2162 return printf (
2163 "Dump mode is %s.\n",
2164 ONOFF(Application.Flag.Dump)
2165 );
2166 }
2167
2168
2169 /**********************************************************************
2170 * Commands table
2171 **********************************************************************/
2172
2173 COMMAND_DESCRIPTOR
2174 Commands [] =
2175 {
2176 /* System information classes */
2177
2178 { /* 0 Q */
2179 "basic",
2180 CMD_REF(Basic),
2181 "Basic system information"
2182 },
2183 { /* 1 Q */
2184 "processor",
2185 CMD_REF(Processor),
2186 "Processor characteristics"
2187 },
2188 { /* 2 Q */
2189 "perf",
2190 CMD_REF(Performance),
2191 "System performance data"
2192 },
2193 { /* 3 Q */
2194 "time",
2195 CMD_REF(Time),
2196 "System times"
2197 },
2198 { /* 4 Q */
2199 "path",
2200 CMD_REF(Path),
2201 "unknown"
2202 },
2203 { /* 5 Q */
2204 "process",
2205 CMD_REF(Process),
2206 "Process & thread tables"
2207 },
2208 { /* 6 Q */
2209 "sdt",
2210 CMD_REF(ServiceDescriptorTable),
2211 "Service descriptor table (SDT)"
2212 },
2213 { /* 7 Q */
2214 "ioconfig",
2215 CMD_REF(IoConfig),
2216 "I/O devices in the system, by class"
2217 },
2218 { /* 8 Q */
2219 "proctime",
2220 CMD_REF(ProcessorTime),
2221 "Print processor times"
2222 },
2223 { /* 9 QS */
2224 "flag",
2225 CMD_REF(NtGlobalFlag),
2226 "Print the system wide flags"
2227 },
2228 { /* 10 */
2229 "#10",
2230 CMD_REF(10),
2231 "UNKNOWN"
2232 },
2233 { /* 11 Q */
2234 "module",
2235 CMD_REF(Module),
2236 "Table of kernel modules"
2237 },
2238 { /* 12 Q */
2239 "reslock",
2240 CMD_REF(ResourceLock),
2241 "Table of locks on resources"
2242 },
2243 { /* 13 */
2244 "#13",
2245 CMD_REF(13),
2246 "UNKNOWN"
2247 },
2248 { /* 14 */
2249 "#14",
2250 CMD_REF(14),
2251 "UNKNOWN"
2252 },
2253 { /* 15 */
2254 "#15",
2255 CMD_REF(15),
2256 "UNKNOWN"
2257 },
2258 { /* 16 Q */
2259 "handle",
2260 CMD_REF(Handle),
2261 "Table of handles (Ps Manager)"
2262 },
2263 { /* 17 Q */
2264 "object",
2265 CMD_REF(Object),
2266 "Table of objects (Ob Manager)"
2267 },
2268 { /* 18 Q */
2269 "pagefile",
2270 CMD_REF(PageFile),
2271 "Virtual memory paging files (Cc Subsystem)"
2272 },
2273 { /* 19 Q */
2274 "emulation",
2275 CMD_REF(InstructionEmulation),
2276 "Virtual DOS Machine instruction emulation (VDM)"
2277 },
2278 { /* 20 */
2279 "#20",
2280 CMD_REF(20),
2281 "UNKNOWN"
2282 },
2283 { /* 21 QS */
2284 "cache",
2285 CMD_REF(Cache),
2286 "Cache Manager Status"
2287 },
2288 { /* 22 Q */
2289 "pooltag",
2290 CMD_REF(PoolTag),
2291 "Tagged pools statistics (checked build only)"
2292 },
2293 { /* 23 Q */
2294 "procsched",
2295 CMD_REF(ProcessorSchedule),
2296 "Processor schedule information"
2297 },
2298 { /* 24 QS */
2299 "dpc",
2300 CMD_REF(Dpc),
2301 "Deferred procedure call (DPC)"
2302 },
2303 { /* 25 */
2304 "#25",
2305 CMD_REF(25),
2306 "UNKNOWN"
2307 },
2308 { /* 26 S (callable) */
2309 "loadpe",
2310 CMD_REF(LoadImage),
2311 "Load a kernel mode DLL (in PE format)"
2312 },
2313 { /* 27 S (callable) */
2314 "unloadpe",
2315 CMD_REF(UnloadImage),
2316 "Unload a kernel mode DLL (module)"
2317 },
2318 { /* 28 QS */
2319 "timeadj",
2320 CMD_REF(TimeAdjustment),
2321 "Time adjustment"
2322 },
2323 { /* 29 */
2324 "#29",
2325 CMD_REF(29),
2326 "UNKNOWN"
2327 },
2328 { /* 30 */
2329 "#30",
2330 CMD_REF(30),
2331 "UNKNOWN"
2332 },
2333 { /* 31 */
2334 "#31",
2335 CMD_REF(31),
2336 "UNKNOWN"
2337 },
2338 { /* 32 Q */
2339 "crashsect",
2340 CMD_REF(CrashDumpSection),
2341 "Crash Dump Section"
2342 },
2343 { /* 33 Q */
2344 "procfault",
2345 CMD_REF(ProcessorFaultCount),
2346 "Processor fault count"
2347 },
2348 { /* 34 Q */
2349 "crashstate",
2350 CMD_REF(CrashDumpState),
2351 "Crash Dump State"
2352 },
2353 { /* 35 Q */
2354 "debugger",
2355 CMD_REF(Debugger),
2356 "System debugger"
2357 },
2358 { /* 36 Q */
2359 "threadsw",
2360 CMD_REF(ThreadSwitchCounters),
2361 "Thread switch counters"
2362 },
2363 { /* 37 QS */
2364 "quota",
2365 CMD_REF(Quota),
2366 "System quota values"
2367 },
2368 { /* 38 S */
2369 "loaddrv",
2370 CMD_REF(LoadDriver),
2371 "Load kernel driver (SYS)"
2372 },
2373 { /* 39 S */
2374 "prisep",
2375 CMD_REF(PrioritySeparation),
2376 "Priority Separation"
2377 },
2378 { /* 40 */
2379 "#40",
2380 CMD_REF(40),
2381 "UNKNOWN"
2382 },
2383 { /* 41 */
2384 "#41",
2385 CMD_REF(41),
2386 "UNKNOWN"
2387 },
2388 { /* 42 */
2389 "#42",
2390 CMD_REF(42),
2391 "UNKNOWN"
2392 },
2393 { /* 43 */
2394 "#43",
2395 CMD_REF(43),
2396 "UNKNOWN"
2397 },
2398 { /* 44 QS */
2399 "tz",
2400 CMD_REF(TimeZone),
2401 "Time zone (TZ) information"
2402 },
2403 { /* 45 Q */
2404 "lookaside",
2405 CMD_REF(Lookaside),
2406 "Lookaside"
2407 },
2408 /* User commands */
2409 {
2410 "?",
2411 CMD_REF(help),
2412 "Same as 'help'"
2413 },
2414 {
2415 "help",
2416 CMD_REF(help),
2417 "Print this command directory"
2418 },
2419 {
2420 "credits",
2421 CMD_REF(credits),
2422 "Print the list of people and sources that made QSI possible"
2423 },
2424 {
2425 "ver",
2426 CMD_REF(ver),
2427 "Print version number and license information"
2428 },
2429 {
2430 "exit",
2431 CMD_REF(exit),
2432 "Exit to operating system"
2433 },
2434 {
2435 "dump",
2436 CMD_REF(dump),
2437 "Enable/disable dumping raw data returned by system"
2438 },
2439 {
2440 "verbose",
2441 CMD_REF(verbose),
2442 "Enable/disable printing unused, unknown, and service fields"
2443 },
2444
2445 { NULL, NULL }
2446 };
2447
2448
2449
2450 /* user input --> command decoder */
2451
2452
2453 COMMAND_CALL
2454 DecodeCommand (LPCSTR Command)
2455 {
2456 int i;
2457
2458 for ( i = 0;
2459 ( Commands[i].Name
2460 && stricmp (Commands[i].Name,Command)
2461 );
2462 ++i
2463 );
2464 return Commands[i].EntryPoint;
2465 }
2466
2467 INT
2468 ParseCommandLine (
2469 LPCSTR CommandLine,
2470 LPCSTR CommandArgv []
2471 )
2472 {
2473 INT ArgC = 0;
2474 LPCSTR Separators = " \t";
2475
2476 for ( CommandArgv [ArgC] = strtok ((char*)CommandLine, (char*)Separators);
2477 (ArgC < ARGV_SIZE);
2478 CommandArgv [ArgC] = (LPCSTR) strtok (NULL, (char*)Separators)
2479 )
2480 {
2481 if (NULL == CommandArgv [ArgC++])
2482 {
2483 break;
2484 }
2485 }
2486 return (ArgC);
2487 }
2488
2489
2490 int
2491 main (int argc, char * argv [])
2492 {
2493 CHAR CommandLine [_MAX_PATH];
2494
2495 INT CommandArgc;
2496 LPCSTR CommandArgv [ARGV_SIZE];
2497
2498 /*
2499 * Initialize rt data.
2500 */
2501 Application.Heap = GetProcessHeap ();
2502 Application.Active = TRUE;
2503 /*
2504 * r-e-p loop.
2505 */
2506 while (Application.Active)
2507 {
2508 /* Print the prompt string. */
2509 if (! Application.Flag.Batch)
2510 {
2511 printf ("\r\nsystem> ");
2512 }
2513 /* Read user command. */
2514 gets (CommandLine);
2515 /* Parse the user command */
2516 CommandArgc = ParseCommandLine (
2517 CommandLine,
2518 CommandArgv
2519 );
2520 if (0 != CommandArgc)
2521 {
2522 COMMAND_CALL CommandCall = NULL;
2523
2524 /* decode */
2525 if ((CommandCall = DecodeCommand (CommandArgv[0])))
2526 {
2527 /* execute */
2528 Application.ExitCode =
2529 CommandCall (
2530 CommandArgc,
2531 CommandArgv
2532 );
2533 }
2534 else
2535 {
2536 printf ("Unknown command (type help for a list of valid commands).\n");
2537 }
2538 }
2539
2540 }
2541 if (! Application.Flag.Batch)
2542 {
2543 printf ("Bye\n");
2544 }
2545 return (EXIT_SUCCESS);
2546 }
2547
2548 /* EOF */