1 /* $Id: qsi.c,v 1.1 2000/04/25 23:22:57 ea Exp $
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/)
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
19 * Partially rewritten to run as a tool to query
20 * every system information class data.
22 * Added almost all structures for getting system
23 * information (from UNDOCNT.H by Dabak et alii).
31 #define NTOS_MODE_USER
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) */
56 #define ONOFF(b) ((b)?"on":"off")
60 #define BUFFER_SIZE_DEFAULT 65536
62 #define TF(b) ((b)?"true":"false")
65 INT (* COMMAND_CALL
) (INT ArgC
,LPCSTR ArgV
[]);
69 VOID STDCALL
PrintStatus (NTSTATUS Status
);
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);}
76 struct _COMMAND_DESCRIPTOR
79 COMMAND_CALL EntryPoint
;
82 } COMMAND_DESCRIPTOR
, * PCOMMAND_DESCRIPTOR
;
89 DumpData (int Size
, PVOID pData
)
91 PBYTE Buffer
= (PBYTE
) pData
;
96 if (! Application
.Flag
.Dump
)
102 printf ("%04x: ", (Buffer
- Base
));
113 (i
% 4 == 3) ? '|' : ' '
149 FindRequiredBufferSize (int i
, int step
)
151 NTSTATUS Status
= STATUS_INFO_LENGTH_MISMATCH
;
152 BYTE Buffer
[BUFFER_SIZE_DEFAULT
];
157 Size
= step
= (step
> 0 ? step
: 1);
158 while ( (Size
< sizeof Buffer
)
159 && (Status
== STATUS_INFO_LENGTH_MISMATCH
)
162 if (Application
.Flag
.Verbose
)
164 printf ("\tTry %d", Size
);
166 RtlZeroMemory (Buffer
, sizeof Buffer
);
168 Status
= NtQuerySystemInformation (
174 if (STATUS_SUCCESS
== Status
)
176 printf ("Length = %d\n", Size
);
185 /* FIXME: slow linear search! */
189 printf ("No valid buffer length found!\n");
196 PrintStatus (NTSTATUS Status
)
198 LPCSTR StatusName
= NULL
;
202 case STATUS_INVALID_INFO_CLASS
:
203 StatusName
= "STATUS_INVALID_INFO_CLASS";
205 case STATUS_INFO_LENGTH_MISMATCH
:
206 StatusName
= "STATUS_INFO_LENGTH_MISMATCH";
208 case STATUS_ACCESS_VIOLATION
:
209 StatusName
= "STATUS_ACCESS_VIOLATION";
211 case STATUS_NOT_IMPLEMENTED
:
212 StatusName
= "STATUS_NOT_IMPLEMENTED";
214 case STATUS_BREAKPOINT
:
215 StatusName
= "STATUS_BREAKPOINT";
218 if (NULL
!= StatusName
)
220 printf ("\tStatus = %s\n", StatusName
);
223 printf ("\tStatus = 0x%08lX\n", Status
);
226 /* Auxiliary functions */
243 PrintUtcDateTime (LPCSTR Template
, PTIME UtcTime
)
245 CHAR UtcTimeString
[64];
246 TIME_FIELDS UtcTimeFields
;
248 RtlTimeToTimeFields (
249 (PLARGE_INTEGER
) UtcTime
,
254 "%s %d-%02d-%02d %02d:%02d:%02d.%03d UTC",
255 DaysOfWeek
[UtcTimeFields
.Weekday
],
260 UtcTimeFields
.Minute
,
261 UtcTimeFields
.Second
,
262 UtcTimeFields
.Milliseconds
271 /**********************************************************************
273 **********************************************************************/
276 /**********************************************************************
279 * Dump whatever we get by calling NtQuerySystemInformation with
280 * a user provided system information class id.
282 * NtQuerySystemInformation called with user class id.
286 int _id
= atoi ((char*)(argv
[0] + 1)); /* "#24" */
293 printf ("SystemInformation %d:\n", _id
);
294 /* Find buffer size */
295 Size
= FindRequiredBufferSize (_id
, 1);
298 printf("\t(no data)\n");
301 /* Allocate the buffer */
302 Buffer
= GlobalAlloc (GMEM_ZEROINIT
, Size
);
305 printf ("#%d: could not allocate %d bytes\n", _id
, Size
);
308 /* Query the executive */
309 Status
= NtQuerySystemInformation (
315 if (!NT_SUCCESS(Status
))
317 PrintStatus (Status
);
318 FindRequiredBufferSize (_id
, 1);
323 DumpData (Size
, Buffer
);
331 /**********************************************************************
341 SYSTEM_BASIC_INFORMATION Info
;
343 if (Application
.Flag
.Verbose
)
345 printf ("SystemBasicInformation:\n");
351 Status
= NtQuerySystemInformation (
352 SystemBasicInformation
,
357 if (STATUS_SUCCESS
!= Status
)
359 PrintStatus (Status
);
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
);
378 /**********************************************************************
388 SYSTEM_PROCESSOR_INFORMATION Info
;
390 if (Application
.Flag
.Verbose
)
392 printf ("SystemProcessorInformation:\n");
398 Status
= NtQuerySystemInformation (
399 SystemProcessorInformation
,
404 if (STATUS_SUCCESS
!= Status
)
406 PrintStatus (Status
);
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
)
414 printf ("\tAlwaysZero = 0x%08x\n", Info
.AlwaysZero
);
416 printf ("\tKeFeatureBits = %08x\n", Info
.KeFeatureBits
);
422 /**********************************************************************
425 * System performance information.
432 NTSTATUS Status
= STATUS_SUCCESS
;
433 PSYSTEM_PERFORMANCE_INFO Info
;
437 if (Application
.Flag
.Verbose
)
439 printf ("SystemPerformanceInformation:\n");
441 Status
= NtQuerySystemInformation (
442 SystemPerformanceInformation
,
447 if (STATUS_SUCCESS
!= Status
)
449 PrintStatus (Status
);
452 printf ("Not implemented.\n");
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
;
467 ULONG TransitionFaults
;
469 ULONG DemandZeroFaults
;
478 ULONG PoolPagedBytes
;
479 ULONG PoolNonPagedBytes
;
484 ULONG MmTotalSystemFreePtes
;
485 ULONG MmSystemCodepage
;
486 ULONG MmTotalSystemDriverPages
;
487 ULONG MmTotalSystemCodePages
;
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
;
504 ULONG CcMapDataNoWaitMiss
;
505 ULONG CcMapDataWaitMiss
;
506 ULONG CcPinMappedDataCount
;
507 ULONG CcPinReadNoWait
;
509 ULONG CcPinReadNoWaitMiss
;
510 ULONG CcPinReadWaitMiss
;
511 ULONG CcCopyReadNoWait
;
512 ULONG CcCopyReadWait
;
513 ULONG CcCopyReadNoWaitMiss
;
514 ULONG CcCopyReadWaitMiss
;
515 ULONG CcMdlReadNoWait
;
517 ULONG CcMdlReadNoWaitMiss
;
518 ULONG CcMdlReadWaitMiss
;
519 ULONG CcReadaheadIos
;
520 ULONG CcLazyWriteIos
;
521 ULONG CcLazyWritePages
;
524 ULONG ContextSwitches
;
533 /**********************************************************************
543 SYSTEM_TIME_INFORMATION Info
;
545 if (Application
.Flag
.Verbose
)
547 printf ("SystemTimeInformation:\n");
549 Status
= NtQuerySystemInformation (
550 SystemTimeInformation
,
555 if (STATUS_SUCCESS
!= Status
)
557 PrintStatus (Status
);
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
)
566 printf ("\tUnused : %08x (?)\n", Info
.Unused
);
573 /**********************************************************************
583 SYSTEM_PATH_INFORMATION Info
;
584 CHAR _Info
[_MAX_PATH
];
587 RtlZeroMemory (& Info
, _MAX_PATH
);
588 Status
= NtQuerySystemInformation (
589 SystemPathInformation
,
594 if (STATUS_SUCCESS
!= Status
)
596 PrintStatus (Status
);
597 DumpData (_MAX_PATH
, & _Info
);
600 DumpData (_MAX_PATH
, & _Info
);
605 /**********************************************************************
608 * A snapshot of the process+thread tables.
615 NTSTATUS Status
= STATUS_SUCCESS
;
616 PSYSTEM_PROCESS_INFORMATION pInfo
= NULL
;
620 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
621 /* FIXME: check NULL==pInfo */
623 if (Application
.Flag
.Verbose
)
625 printf ("SystemProcessInformation:\n");
628 * Obtain required buffer size
630 Status
= NtQuerySystemInformation (
631 SystemProcessInformation
,
636 if (STATUS_SUCCESS
!= Status
)
638 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
643 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
646 printf ("\tCould not allocate memory.\n");
652 PrintStatus (Status
);
658 * Get process+thread list from ntoskrnl.exe
660 Status
= NtQuerySystemInformation (
661 SystemProcessInformation
,
666 if (!NT_SUCCESS(Status
))
668 PrintStatus (Status
);
675 wprintf (L
"%s:\n", (pInfo
->Name
.Length
? pInfo
->Name
.Buffer
: L
"*idle*") );
676 if (Application
.Flag
.Verbose
)
678 wprintf (L
"\tRelativeOffset = 0x%08x\n", pInfo
->RelativeOffset
);
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
690 wprintf (L
"\t\tTotal: %ld\t\t\tTotal: %ld\n",
691 pInfo
->TotalVirtualSizeBytes
,
692 pInfo
->TotalWorkingSetSizeBytes
694 wprintf (L
"\tPagedPoolUsage:\t\tNonPagedPoolUsage:\n");
695 wprintf (L
"\t\tPeak : %ld\t\t\tPeak : %ld\n",
696 pInfo
->PeakPagedPoolUsagePages
,
697 pInfo
->TotalPagedPoolUsagePages
699 wprintf (L
"\t\tTotal: %ld\t\t\tTotal: %ld\n",
700 pInfo
->PeakNonPagedPoolUsagePages
,
701 pInfo
->TotalNonPagedPoolUsagePages
703 wprintf (L
"\tPageFileUsage:\n");
704 wprintf (L
"\t\tPeak : %ld\n", pInfo
->PeakPageFileUsageBytes
);
705 wprintf (L
"\t\tTotal: %ld\n", pInfo
->TotalPageFileUsageBytes
);
707 wprintf (L
"\tPageFaultCount = %ld\n", pInfo
->PageFaultCount
);
708 wprintf (L
"\tTotalPrivateBytes = %ld\n", pInfo
->TotalPrivateBytes
);
710 for ( ThreadIndex
= 0;
711 (ThreadIndex
< pInfo
->ThreadCount
);
715 wprintf (L
"\t%x in %x:\n",
716 pInfo
->ThreadSysInfo
[ThreadIndex
].ClientId
.UniqueThread
,
717 pInfo
->ThreadSysInfo
[ThreadIndex
].ClientId
.UniqueProcess
720 "\t\tKernelTime = %s\n",
721 & (pInfo
->ThreadSysInfo
[ThreadIndex
].KernelTime
)
724 "\t\tUserTime = %s\n",
725 & (pInfo
->ThreadSysInfo
[ThreadIndex
].UserTime
)
728 "\t\tCreateTime = %s\n",
729 & (pInfo
->ThreadSysInfo
[ThreadIndex
].CreateTime
)
731 wprintf (L
"\t\tTickCount = %ld\n",
732 pInfo
->ThreadSysInfo
[ThreadIndex
].TickCount
734 wprintf (L
"\t\tStartEIP = 0x%08x\n",
735 pInfo
->ThreadSysInfo
[ThreadIndex
].StartEIP
737 /* CLIENT_ID ClientId; */
738 wprintf (L
"\t\tDynamicPriority = %d\n",
739 pInfo
->ThreadSysInfo
[ThreadIndex
].DynamicPriority
741 wprintf (L
"\t\tBasePriority = %d\n",
742 pInfo
->ThreadSysInfo
[ThreadIndex
].BasePriority
744 wprintf (L
"\t\tnSwitches = %ld\n",
745 pInfo
->ThreadSysInfo
[ThreadIndex
].nSwitches
747 wprintf (L
"\t\tState = 0x%08x\n",
748 pInfo
->ThreadSysInfo
[ThreadIndex
].State
750 wprintf (L
"\t\tWaitReason = %ld\n",
751 pInfo
->ThreadSysInfo
[ThreadIndex
].WaitReason
755 if (0 == pInfo
->RelativeOffset
)
759 (ULONG
) pInfo
+= pInfo
->RelativeOffset
;
762 DumpData (Length
, pInfo
);
770 /**********************************************************************
777 CMD_DEF(ServiceDescriptorTable
)
780 SYSTEM_SDT_INFORMATION Info
;
784 if (Application
.Flag
.Verbose
)
786 printf ("SystemServiceDescriptorTableInfo:\n");
788 RtlZeroMemory (& Info
, sizeof Info
);
789 Status
= NtQuerySystemInformation (
790 SystemServiceDescriptorTableInfo
,
795 if (STATUS_SUCCESS
!= Status
)
797 PrintStatus (Status
);
798 DumpData (Length
, & Info
);
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]);
806 DumpData (Length
, & Info
);
812 /**********************************************************************
821 NTSTATUS Status
= STATUS_SUCCESS
;
822 SYSTEM_IOCONFIG_INFORMATION Info
;
825 if (Application
.Flag
.Verbose
)
827 printf ("SystemIoConfigInformation:\n");
829 Status
= NtQuerySystemInformation (
830 SystemIoConfigInformation
,
835 if (STATUS_SUCCESS
!= Status
)
837 PrintStatus (Status
);
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
);
847 DumpData (Length
, & Info
);
853 /**********************************************************************
860 CMD_DEF(ProcessorTime
)
863 SYSTEM_PROCESSORTIME_INFO Info
;
866 if (Application
.Flag
.Verbose
)
868 printf ("SystemProcessorTimeInformation:\n");
870 Status
= NtQuerySystemInformation (
871 SystemProcessorTimeInformation
,
876 if (STATUS_SUCCESS
!= Status
)
878 PrintStatus (Status
);
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
)
889 printf ("\tUnused : %08x\n", Info
.Unused
);
896 /**********************************************************************
903 CMD_DEF(NtGlobalFlag
)
906 SYSTEM_GLOBAL_FLAG_INFO Info
;
909 if (Application
.Flag
.Verbose
)
911 printf ("SystemNtGlobalFlagInformation:\n");
913 Status
= NtQuerySystemInformation (
914 SystemNtGlobalFlagInformation
,
919 if (STATUS_SUCCESS
!= Status
)
921 PrintStatus (Status
);
924 printf ("\tNtGlobalFlag: %08x\n", Info
.NtGlobalFlag
);
925 /* FIXME: decode each flag */
931 /**********************************************************************
942 /**********************************************************************
950 * Code originally in Yariv Kaplan's NtDriverList,
951 * at http://www.internals.com/, adapted to ReactOS
956 NTSTATUS Status
= STATUS_SUCCESS
;
957 PSYSTEM_MODULE_INFORMATION pInfo
= NULL
;
961 "-------- -------- -------- ---------------------------------------\n";
964 if (Application
.Flag
.Verbose
)
966 printf ("SystemModuleInformation:\n");
969 * Obtain required buffer size
971 Status
= NtQuerySystemInformation (
972 SystemModuleInformation
,
977 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
982 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, Length
);
985 printf ("Could not allocate memory.\n");
991 PrintStatus (Status
);
995 * Get module list from ntoskrnl.exe
997 Status
= NtQuerySystemInformation (
998 SystemModuleInformation
,
1003 if (!NT_SUCCESS(Status
))
1005 PrintStatus (Status
);
1006 return EXIT_FAILURE
;
1008 printf ("Index Address Size Name\n");
1012 (Index
< (int) pInfo
->Count
);
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
1028 return EXIT_SUCCESS
;
1032 /**********************************************************************
1039 CMD_DEF(ResourceLock
)
1041 NTSTATUS Status
= STATUS_SUCCESS
;
1042 PSYSTEM_RESOURCE_LOCK_INFO pInfo
= NULL
;
1046 "-------- -------- -------- -------- -------- -------- ------------\n";
1048 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
1049 /* FIXME: check NULL==pInfo */
1051 if (Application
.Flag
.Verbose
)
1053 printf ("SystemResourceLockInformation:\n");
1056 * Obtain required buffer size
1058 Status
= NtQuerySystemInformation (
1059 SystemResourceLockInformation
,
1061 BUFFER_SIZE_DEFAULT
, /* query size */
1064 if (STATUS_SUCCESS
!= Status
)
1066 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
1071 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
1074 printf ("Could not allocate memory.\n");
1075 return EXIT_FAILURE
;
1080 PrintStatus (Status
);
1082 return EXIT_FAILURE
;
1086 * Get locked resource list from ntoskrnl.exe
1088 Status
= NtQuerySystemInformation (
1089 SystemResourceLockInformation
,
1094 if (!NT_SUCCESS(Status
))
1096 PrintStatus (Status
);
1098 return EXIT_FAILURE
;
1100 printf ("Address Active # Content# Sh/Wait Exc/Wait\n");
1104 (Index
< (int) pInfo
->Count
);
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
1122 return EXIT_SUCCESS
;
1126 /**********************************************************************
1137 /**********************************************************************
1148 /**********************************************************************
1159 /**********************************************************************
1164 * Class 16. You can not pass 0 as the initial output buffer's
1165 * size to get back the needed buffer size.
1169 NTSTATUS Status
= STATUS_SUCCESS
;
1170 PSYSTEM_HANDLE_INFORMATION pInfo
= NULL
;
1174 "-------- -------- -------- -------- --------\n";
1176 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
1178 if (Application
.Flag
.Verbose
)
1180 printf ("SystemHandleInformation:\n");
1183 * Obtain required buffer size
1185 Status
= NtQuerySystemInformation (
1186 SystemHandleInformation
,
1188 BUFFER_SIZE_DEFAULT
,
1191 if (STATUS_SUCCESS
!= Status
)
1193 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
1198 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
1201 printf ("\tCould not allocate memory.\n");
1202 return EXIT_FAILURE
;
1207 PrintStatus (Status
);
1209 return EXIT_FAILURE
;
1213 * Get handle table from ntoskrnl.exe
1215 Status
= NtQuerySystemInformation (
1216 SystemHandleInformation
,
1221 if (!NT_SUCCESS(Status
))
1223 PrintStatus (Status
);
1225 return EXIT_FAILURE
;
1227 printf ("Handle OwnerPID ObjType ObjPtr Access\n");
1231 (Index
< (int) pInfo
->Count
);
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
1246 DumpData (Length
, pInfo
);
1250 return EXIT_SUCCESS
;
1254 /**********************************************************************
1265 /**********************************************************************
1275 PSYSTEM_PAGEFILE_INFORMATION pInfo
= NULL
;
1278 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
1279 /* FIXME: check pInfo */
1281 if (Application
.Flag
.Verbose
)
1283 printf ("SystemPageFileInformation:\n");
1285 Status
= NtQuerySystemInformation(
1286 SystemPageFileInformation
,
1288 BUFFER_SIZE_DEFAULT
,
1291 if (STATUS_SUCCESS
!= Status
)
1293 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
1298 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
1301 printf ("Could not allocate memory.\n");
1302 return EXIT_FAILURE
;
1307 PrintStatus (Status
);
1309 return EXIT_FAILURE
;
1312 Status
= NtQuerySystemInformation (
1313 SystemPageFileInformation
,
1318 if (!NT_SUCCESS(Status
))
1320 PrintStatus (Status
);
1322 return EXIT_FAILURE
;
1327 wprintf (L
"\t\"%s\":\n", pInfo
->PagefileFileName
.Buffer
);
1328 if (Application
.Flag
.Verbose
)
1330 wprintf (L
"\t\tRelativeOffset = %08x\n", pInfo
->RelativeOffset
);
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
);
1336 if (0 == pInfo
->RelativeOffset
)
1341 (ULONG
) pInfo
+= pInfo
->RelativeOffset
;
1344 DumpData (Length
, pInfo
);
1348 return EXIT_SUCCESS
;
1352 /**********************************************************************
1359 CMD_DEF(InstructionEmulation
)
1362 SYSTEM_VDM_INFORMATION Info
;
1364 if (Application
.Flag
.Verbose
)
1366 printf ("SystemInstructionEmulationInfo:\n");
1368 RtlZeroMemory (& Info
, sizeof Info
);
1369 Status
= NtQuerySystemInformation (
1370 SystemInstructionEmulationInfo
,
1375 if (!NT_SUCCESS(Status
))
1377 PrintStatus (Status
);
1378 return EXIT_FAILURE
;
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
);
1415 return EXIT_SUCCESS
;
1419 /**********************************************************************
1430 /**********************************************************************
1440 SYSTEM_CACHE_INFORMATION Si
;
1442 if (Application
.Flag
.Verbose
)
1444 printf ("SystemCacheInformation:\n");
1450 Status
= NtQuerySystemInformation (
1451 SystemCacheInformation
,
1456 if (!NT_SUCCESS(Status
))
1458 PrintStatus (Status
);
1459 return EXIT_FAILURE
;
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
);
1469 return EXIT_SUCCESS
;
1473 /**********************************************************************
1476 * Get statistic data about tagged pools. Not implemented in the
1485 PSYSTEM_POOL_TAG_INFO pInfo
= NULL
;
1489 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
1490 /* FIXME: check pInfo */
1492 if (Application
.Flag
.Verbose
)
1494 printf ("SystemPoolTagInformation:\n");
1496 Status
= NtQuerySystemInformation(
1497 SystemPoolTagInformation
,
1499 BUFFER_SIZE_DEFAULT
,
1502 if (STATUS_SUCCESS
!= Status
)
1504 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
1509 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
1512 printf ("Could not allocate memory.\n");
1513 return EXIT_FAILURE
;
1518 PrintStatus (Status
);
1520 return EXIT_FAILURE
;
1523 Status
= NtQuerySystemInformation (
1524 SystemPoolTagInformation
,
1529 if (!NT_SUCCESS(Status
))
1531 PrintStatus (Status
);
1533 return EXIT_FAILURE
;
1536 for ( PoolIndex
= 0;
1537 (PoolIndex
< pInfo
->Count
);
1541 wprintf (L
"\t%08x:\n", pInfo
->PoolEntry
[PoolIndex
].Tag
);
1542 wprintf (L
"\t\tPaged:\t\tNon Paged:\n");
1544 L
"\t\tAllocationCount = %ld\tAllocationCount = %ld\n",
1545 pInfo
->PoolEntry
[PoolIndex
].Paged
.AllocationCount
,
1546 pInfo
->PoolEntry
[PoolIndex
].NonPaged
.AllocationCount
1549 L
"\t\tFreeCount = %ld\tFreeCount = %ld\n",
1550 pInfo
->PoolEntry
[PoolIndex
].Paged
.FreeCount
,
1551 pInfo
->PoolEntry
[PoolIndex
].NonPaged
.FreeCount
1554 L
"\t\tSizeBytes = %ld\tSizeBytes = %ld\n",
1555 pInfo
->PoolEntry
[PoolIndex
].Paged
.SizeBytes
,
1556 pInfo
->PoolEntry
[PoolIndex
].NonPaged
.SizeBytes
1560 DumpData (Length
, pInfo
);
1564 return EXIT_SUCCESS
;
1568 /**********************************************************************
1575 CMD_DEF(ProcessorSchedule
)
1578 SYSTEM_PROCESSOR_SCHEDULE_INFO Info
;
1580 if (Application
.Flag
.Verbose
)
1582 printf ("SystemProcessorScheduleInfo:\n");
1588 Status
= NtQuerySystemInformation (
1589 SystemProcessorScheduleInfo
,
1594 if (STATUS_SUCCESS
!= Status
)
1596 PrintStatus (Status
);
1597 return EXIT_FAILURE
;
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
);
1607 DumpData (sizeof Info
, & Info
);
1609 return EXIT_SUCCESS
;
1614 /**********************************************************************
1624 SYSTEM_DPC_INFORMATION Info
;
1626 if (Application
.Flag
.Verbose
)
1628 printf ("SystemDpcInformation:\n");
1634 Status
= NtQuerySystemInformation (
1635 SystemDpcInformation
,
1640 if (STATUS_SUCCESS
!= Status
)
1642 PrintStatus (Status
);
1643 return EXIT_FAILURE
;
1646 if (Application
.Flag
.Verbose
)
1648 printf ("\tUnused = %ld\n", Info
.Unused
);
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
);
1655 DumpData (sizeof Info
, & Info
);
1657 return EXIT_SUCCESS
;
1661 /**********************************************************************
1672 /**********************************************************************
1679 INT
CMD_LoadImage (INT argc
, LPCSTR argv
[])
1682 /**********************************************************************
1689 CMD_DEF(UnloadImage
)
1693 /**********************************************************************
1700 CMD_DEF(TimeAdjustment
)
1702 NTSTATUS Status
= STATUS_SUCCESS
;
1703 SYSTEM_TIME_ADJUSTMENT_INFO Info
;
1705 if (Application
.Flag
.Verbose
)
1707 printf ("SystemTimeAdjustmentInformation:\n");
1709 RtlZeroMemory (& Info
, sizeof Info
);
1710 Status
= NtQuerySystemInformation (
1711 SystemTimeAdjustmentInformation
,
1716 if (!NT_SUCCESS(Status
))
1718 PrintStatus (Status
);
1719 return EXIT_FAILURE
;
1721 printf ("\tKeTimeAdjustment = %ld\n", Info
.KeTimeAdjustment
);
1722 printf ("\tKeMaximumIncrement = %ld\n", Info
.KeMaximumIncrement
);
1723 printf ("\tKeTimeSynchronization = %s\n", TF(Info
.KeTimeSynchronization
));
1725 return EXIT_SUCCESS
;
1729 /**********************************************************************
1740 /**********************************************************************
1751 /**********************************************************************
1762 /**********************************************************************
1769 CMD_DEF(CrashDumpSection
)
1773 /**********************************************************************
1780 CMD_DEF(ProcessorFaultCount
)
1784 /**********************************************************************
1791 CMD_DEF(CrashDumpState
)
1795 /**********************************************************************
1805 SYSTEM_DEBUGGER_INFO Info
;
1807 RtlZeroMemory (& Info
, sizeof Info
);
1808 Status
= NtQuerySystemInformation (
1809 SystemDebuggerInformation
,
1814 if (STATUS_SUCCESS
!= Status
)
1816 PrintStatus (Status
);
1817 return EXIT_FAILURE
;
1819 printf ("\tKdDebuggerEnabled = %s\n", TF(Info
.KdDebuggerEnabled
));
1820 printf ("\tKdDebuggerPresent = %s\n", TF(Info
.KdDebuggerPresent
));
1822 DumpData (sizeof Info
, & Info
);
1824 return EXIT_SUCCESS
;
1828 /**********************************************************************
1835 CMD_DEF(ThreadSwitchCounters
)
1839 /**********************************************************************
1848 NTSTATUS Status
= STATUS_SUCCESS
;
1849 SYSTEM_QUOTA_INFORMATION Info
;
1851 if (Application
.Flag
.Verbose
)
1853 printf ("SystemQuotaInformation:\n");
1855 RtlZeroMemory (& Info
, sizeof Info
);
1856 Status
= NtQuerySystemInformation (
1857 SystemQuotaInformation
,
1862 if (!NT_SUCCESS(Status
))
1864 PrintStatus (Status
);
1865 return EXIT_FAILURE
;
1867 printf ("\tCmpGlobalQuota = %ld\n", Info
.CmpGlobalQuota
);
1868 printf ("\tCmpGlobalQuotaUsed = %ld\n", Info
.CmpGlobalQuotaUsed
);
1869 printf ("\tMmSizeofPagedPoolInBytes = %ld\n", Info
.MmSizeofPagedPoolInBytes
);
1871 return EXIT_SUCCESS
;
1875 /**********************************************************************
1886 /**********************************************************************
1893 CMD_DEF(PrioritySeparation
)
1897 /**********************************************************************
1908 /**********************************************************************
1919 /**********************************************************************
1930 /**********************************************************************
1941 /**********************************************************************
1944 * Dump the system TIME_ZONE_INFORMATION object.
1953 TIME_ZONE_INFORMATION Tzi
;
1956 if (Application
.Flag
.Verbose
)
1958 printf ("SystemTimeZoneInformation:\n");
1960 RtlZeroMemory (& Tzi
, sizeof Tzi
);
1961 Status
= NtQuerySystemInformation(
1962 SystemTimeZoneInformation
,
1967 if (!NT_SUCCESS(Status
))
1969 PrintStatus (Status
);
1970 return EXIT_FAILURE
;
1973 "12h/24h.....: %dh\n",
1977 "Bias........: %d'\n",
1981 printf ("Standard\n");
1988 Tzi
.StandardName
, /* WCHAR [32] */
1992 L
"\tName: \"%s\"\n",
1998 & Tzi
.StandardDate
/* SYSTEMTIME */
2001 printf ("\tBias: %d'\n",
2002 Tzi
.StandardBias
/* LONG */
2005 printf ("Daylight\n");
2012 Tzi
.DaylightName
, /* WCHAR [32] */
2016 L
"\tName: \"%s\"\n",
2022 & Tzi
.DaylightDate
/* SYSTEMTIME */
2027 Tzi
.DaylightBias
/* LONG */
2031 return EXIT_SUCCESS
;
2035 /**********************************************************************
2046 /**********************************************************************
2047 * Miscellanea Commands
2048 **********************************************************************/
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",
2062 if (Application
.Flag
.Verbose
)
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"
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"
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"
2088 Application
.Active
= FALSE
;
2089 return EXIT_SUCCESS
;
2093 extern COMMAND_DESCRIPTOR Commands
[];
2099 if (Application
.Flag
.Verbose
)
2101 printf ("Commands:\n");
2104 (NULL
!= Commands
[i
].Name
);
2109 (strlen (Commands
[i
].Name
) > 7)
2113 Commands
[i
].Description
2116 return EXIT_SUCCESS
;
2124 "\nReactOS (http://www.reactos.com/):\n"
2125 "\tEmanuele Aliberti\n"
2129 "\tMark Russinovich (http://www.sysinternals.com/)\n\n"
2132 "\tYariv Kaplan (http://www.internals.com/)\n\n"
2134 "Undocumented SYSTEM_POOL_INFORMATION:\n"
2135 "\tKlaus P. Gerlicher\n\n"
2137 "Undocumented Windows NT:\n"
2138 "\tPrasad Dabak, Sandeep Phadke, and Milind Borate\n\n"
2140 "Windows NT/2000 Native API Reference:\n"
2143 "comp.os.ms-windows.programmer.nt.kernel-mode\n"
2144 "\t(many postings with sample code)\n"
2151 Application
.Flag
.Verbose
= ~Application
.Flag
.Verbose
;
2153 "Verbose mode is %s.\n",
2154 ONOFF(Application
.Flag
.Verbose
)
2161 Application
.Flag
.Dump
= ~Application
.Flag
.Dump
;
2163 "Dump mode is %s.\n",
2164 ONOFF(Application
.Flag
.Dump
)
2169 /**********************************************************************
2171 **********************************************************************/
2176 /* System information classes */
2181 "Basic system information"
2186 "Processor characteristics"
2190 CMD_REF(Performance
),
2191 "System performance data"
2206 "Process & thread tables"
2210 CMD_REF(ServiceDescriptorTable
),
2211 "Service descriptor table (SDT)"
2216 "I/O devices in the system, by class"
2220 CMD_REF(ProcessorTime
),
2221 "Print processor times"
2225 CMD_REF(NtGlobalFlag
),
2226 "Print the system wide flags"
2236 "Table of kernel modules"
2240 CMD_REF(ResourceLock
),
2241 "Table of locks on resources"
2261 "Table of handles (Ps Manager)"
2266 "Table of objects (Ob Manager)"
2271 "Virtual memory paging files (Cc Subsystem)"
2275 CMD_REF(InstructionEmulation
),
2276 "Virtual DOS Machine instruction emulation (VDM)"
2286 "Cache Manager Status"
2291 "Tagged pools statistics (checked build only)"
2295 CMD_REF(ProcessorSchedule
),
2296 "Processor schedule information"
2301 "Deferred procedure call (DPC)"
2308 { /* 26 S (callable) */
2311 "Load a kernel mode DLL (in PE format)"
2313 { /* 27 S (callable) */
2315 CMD_REF(UnloadImage
),
2316 "Unload a kernel mode DLL (module)"
2320 CMD_REF(TimeAdjustment
),
2340 CMD_REF(CrashDumpSection
),
2341 "Crash Dump Section"
2345 CMD_REF(ProcessorFaultCount
),
2346 "Processor fault count"
2350 CMD_REF(CrashDumpState
),
2360 CMD_REF(ThreadSwitchCounters
),
2361 "Thread switch counters"
2366 "System quota values"
2370 CMD_REF(LoadDriver
),
2371 "Load kernel driver (SYS)"
2375 CMD_REF(PrioritySeparation
),
2376 "Priority Separation"
2401 "Time zone (TZ) information"
2417 "Print this command directory"
2422 "Print the list of people and sources that made QSI possible"
2427 "Print version number and license information"
2432 "Exit to operating system"
2437 "Enable/disable dumping raw data returned by system"
2442 "Enable/disable printing unused, unknown, and service fields"
2450 /* user input --> command decoder */
2454 DecodeCommand (LPCSTR Command
)
2460 && stricmp (Commands
[i
].Name
,Command
)
2464 return Commands
[i
].EntryPoint
;
2470 LPCSTR CommandArgv
[]
2474 LPCSTR Separators
= " \t";
2476 for ( CommandArgv
[ArgC
] = strtok ((char*)CommandLine
, (char*)Separators
);
2478 CommandArgv
[ArgC
] = (LPCSTR
) strtok (NULL
, (char*)Separators
)
2481 if (NULL
== CommandArgv
[ArgC
++])
2491 main (int argc
, char * argv
[])
2493 CHAR CommandLine
[_MAX_PATH
];
2496 LPCSTR CommandArgv
[ARGV_SIZE
];
2499 * Initialize rt data.
2501 Application
.Heap
= GetProcessHeap ();
2502 Application
.Active
= TRUE
;
2506 while (Application
.Active
)
2508 /* Print the prompt string. */
2509 if (! Application
.Flag
.Batch
)
2511 printf ("\r\nsystem> ");
2513 /* Read user command. */
2515 /* Parse the user command */
2516 CommandArgc
= ParseCommandLine (
2520 if (0 != CommandArgc
)
2522 COMMAND_CALL CommandCall
= NULL
;
2525 if ((CommandCall
= DecodeCommand (CommandArgv
[0])))
2528 Application
.ExitCode
=
2536 printf ("Unknown command (type help for a list of valid commands).\n");
2541 if (! Application
.Flag
.Batch
)
2545 return (EXIT_SUCCESS
);