1 /* $Id: qsi.c,v 1.2 2000/04/27 23:39:49 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
;
85 /* Fast BYTE to binary representation */
87 #define BIT(n,m) (((n)&(m))?'1':'0')
95 Binary
[7] = BIT(Byte
,0x01);
96 Binary
[6] = BIT(Byte
,0x02);
97 Binary
[5] = BIT(Byte
,0x04);
98 Binary
[4] = BIT(Byte
,0x08);
99 Binary
[3] = BIT(Byte
,0x10);
100 Binary
[2] = BIT(Byte
,0x20);
101 Binary
[1] = BIT(Byte
,0x40);
102 Binary
[0] = BIT(Byte
,0x80);
103 return (LPSTR
) Binary
;
109 DumpData (int Size
, PVOID pData
)
111 PBYTE Buffer
= (PBYTE
) pData
;
114 const int Width
= 16;
116 if (! Application
.Flag
.Dump
)
122 printf ("%04x: ", (Buffer
- Base
));
133 (i
% 4 == 3) ? '|' : ' '
169 FindRequiredBufferSize (int i
, int step
)
171 NTSTATUS Status
= STATUS_INFO_LENGTH_MISMATCH
;
172 BYTE Buffer
[BUFFER_SIZE_DEFAULT
];
177 Size
= step
= (step
> 0 ? step
: 1);
178 while ( (Size
< sizeof Buffer
)
179 && (Status
== STATUS_INFO_LENGTH_MISMATCH
)
182 if (Application
.Flag
.Verbose
)
184 printf ("\tTry %d", Size
);
186 RtlZeroMemory (Buffer
, sizeof Buffer
);
188 Status
= NtQuerySystemInformation (
194 if (STATUS_SUCCESS
== Status
)
196 printf ("Length = %d\n", Size
);
205 /* FIXME: slow linear search! */
209 printf ("No valid buffer length found!\n");
216 PrintStatus (NTSTATUS Status
)
218 LPCSTR StatusName
= NULL
;
222 case STATUS_INVALID_INFO_CLASS
:
223 StatusName
= "STATUS_INVALID_INFO_CLASS";
225 case STATUS_INFO_LENGTH_MISMATCH
:
226 StatusName
= "STATUS_INFO_LENGTH_MISMATCH";
228 case STATUS_ACCESS_VIOLATION
:
229 StatusName
= "STATUS_ACCESS_VIOLATION";
231 case STATUS_NOT_IMPLEMENTED
:
232 StatusName
= "STATUS_NOT_IMPLEMENTED";
234 case STATUS_BREAKPOINT
:
235 StatusName
= "STATUS_BREAKPOINT";
238 if (NULL
!= StatusName
)
240 printf ("\tStatus = %s\n", StatusName
);
243 printf ("\tStatus = 0x%08lX\n", Status
);
246 /* Auxiliary functions */
263 PrintUtcDateTime (LPCSTR Template
, PTIME UtcTime
)
265 CHAR UtcTimeString
[64];
266 TIME_FIELDS UtcTimeFields
;
268 RtlTimeToTimeFields (
269 (PLARGE_INTEGER
) UtcTime
,
274 "%s %d-%02d-%02d %02d:%02d:%02d.%03d UTC",
275 DaysOfWeek
[UtcTimeFields
.Weekday
],
280 UtcTimeFields
.Minute
,
281 UtcTimeFields
.Second
,
282 UtcTimeFields
.Milliseconds
291 /**********************************************************************
293 **********************************************************************/
296 /**********************************************************************
299 * Dump whatever we get by calling NtQuerySystemInformation with
300 * a user provided system information class id.
302 * NtQuerySystemInformation called with user class id.
306 int _id
= atoi ((char*)(argv
[0] + 1)); /* "#24" */
313 printf ("SystemInformation %d:\n", _id
);
314 /* Find buffer size */
315 Size
= FindRequiredBufferSize (_id
, 1);
318 printf("\t(no data)\n");
321 /* Allocate the buffer */
322 Buffer
= GlobalAlloc (GMEM_ZEROINIT
, Size
);
325 printf ("#%d: could not allocate %d bytes\n", _id
, Size
);
328 /* Query the executive */
329 Status
= NtQuerySystemInformation (
335 if (!NT_SUCCESS(Status
))
337 PrintStatus (Status
);
338 FindRequiredBufferSize (_id
, 1);
343 DumpData (Size
, Buffer
);
351 /**********************************************************************
361 SYSTEM_BASIC_INFORMATION Info
;
363 if (Application
.Flag
.Verbose
)
365 printf ("SystemBasicInformation:\n");
371 Status
= NtQuerySystemInformation (
372 SystemBasicInformation
,
377 if (STATUS_SUCCESS
!= Status
)
379 PrintStatus (Status
);
382 printf ("\tAlwaysZero = 0x%08x\n", Info
.AlwaysZero
);
383 printf ("\tKeMaximumIncrement = %ld\n", Info
.KeMaximumIncrement
);
384 printf ("\tMmPageSize = %ld\n", Info
.MmPageSize
);
385 printf ("\tMmNumberOfPhysicalPages = %ld\n", Info
.MmNumberOfPhysicalPages
);
386 printf ("\tMmLowestPhysicalPage = %ld\n", Info
.MmLowestPhysicalPage
);
387 printf ("\tMmHighestPhysicalPage = %ld\n", Info
.MmHighestPhysicalPage
);
388 printf ("\tMmLowestUserAddress = 0x%08x\n", Info
.MmLowestUserAddress
);
389 printf ("\tMmLowestUserAddress1 = 0x%08x\n", Info
.MmLowestUserAddress1
);
390 printf ("\tMmHighestUserAddress = 0x%08x\n", Info
.MmHighestUserAddress
);
391 printf ("\tKeActiveProcessors = 0x%08x\n", Info
.KeActiveProcessors
);
392 printf ("\tKeNumberProcessors = %ld\n", Info
.KeNumberProcessors
);
398 /**********************************************************************
408 SYSTEM_PROCESSOR_INFORMATION Info
;
410 if (Application
.Flag
.Verbose
)
412 printf ("SystemProcessorInformation:\n");
418 Status
= NtQuerySystemInformation (
419 SystemProcessorInformation
,
424 if (STATUS_SUCCESS
!= Status
)
426 PrintStatus (Status
);
429 printf ("\tKeProcessorArchitecture = %ld\n", Info
.KeProcessorArchitecture
);
430 printf ("\tKeProcessorLevel = %ld\n", Info
.KeProcessorLevel
);
431 printf ("\tKeProcessorRevision = %ld\n", Info
.KeProcessorRevision
);
432 if (Application
.Flag
.Verbose
)
434 printf ("\tAlwaysZero = 0x%08x\n", Info
.AlwaysZero
);
436 printf ("\tKeFeatureBits = %08x\n", Info
.KeFeatureBits
);
442 /**********************************************************************
445 * System performance information.
452 NTSTATUS Status
= STATUS_SUCCESS
;
453 PSYSTEM_PERFORMANCE_INFO Info
;
457 if (Application
.Flag
.Verbose
)
459 printf ("SystemPerformanceInformation:\n");
461 Status
= NtQuerySystemInformation (
462 SystemPerformanceInformation
,
467 if (STATUS_SUCCESS
!= Status
)
469 PrintStatus (Status
);
472 printf ("Not implemented.\n");
474 LARGE_INTEGER TotalProcessorTime
;
475 LARGE_INTEGER IoReadTransferCount
;
476 LARGE_INTEGER IoWriteTransferCount
;
477 LARGE_INTEGER IoOtherTransferCount
;
478 ULONG IoReadOperationCount
;
479 ULONG IoWriteOperationCount
;
480 ULONG IoOtherOperationCount
;
481 ULONG MmAvailablePages
;
482 ULONG MmTotalCommitedPages
;
483 ULONG MmTotalCommitLimit
;
487 ULONG TransitionFaults
;
489 ULONG DemandZeroFaults
;
498 ULONG PoolPagedBytes
;
499 ULONG PoolNonPagedBytes
;
504 ULONG MmTotalSystemFreePtes
;
505 ULONG MmSystemCodepage
;
506 ULONG MmTotalSystemDriverPages
;
507 ULONG MmTotalSystemCodePages
;
511 ULONG MmSystemCachePage
;
512 ULONG MmPagedPoolPage
;
513 ULONG MmSystemDriverPage
;
514 ULONG CcFastReadNoWait
;
515 ULONG CcFastReadWait
;
516 ULONG CcFastReadResourceMiss
;
517 ULONG CcFastReadNotPossible
;
518 ULONG CcFastMdlReadNoWait
;
519 ULONG CcFastMdlReadWait
;
520 ULONG CcFastMdlReadResourceMiss
;
521 ULONG CcFastMdlReadNotPossible
;
522 ULONG CcMapDataNoWait
;
524 ULONG CcMapDataNoWaitMiss
;
525 ULONG CcMapDataWaitMiss
;
526 ULONG CcPinMappedDataCount
;
527 ULONG CcPinReadNoWait
;
529 ULONG CcPinReadNoWaitMiss
;
530 ULONG CcPinReadWaitMiss
;
531 ULONG CcCopyReadNoWait
;
532 ULONG CcCopyReadWait
;
533 ULONG CcCopyReadNoWaitMiss
;
534 ULONG CcCopyReadWaitMiss
;
535 ULONG CcMdlReadNoWait
;
537 ULONG CcMdlReadNoWaitMiss
;
538 ULONG CcMdlReadWaitMiss
;
539 ULONG CcReadaheadIos
;
540 ULONG CcLazyWriteIos
;
541 ULONG CcLazyWritePages
;
544 ULONG ContextSwitches
;
553 /**********************************************************************
563 SYSTEM_TIME_INFORMATION Info
;
565 if (Application
.Flag
.Verbose
)
567 printf ("SystemTimeInformation:\n");
569 Status
= NtQuerySystemInformation (
570 SystemTimeInformation
,
575 if (STATUS_SUCCESS
!= Status
)
577 PrintStatus (Status
);
580 PrintUtcDateTime ("\tKeBootTime : %s\n", & Info
.KeBootTime
);
581 PrintUtcDateTime ("\tKeSystemTime : %s\n", & Info
.KeSystemTime
);
582 PrintUtcDateTime ("\tExpTimeZoneBias: %s\n", & Info
.ExpTimeZoneBias
); /* FIXME */
583 printf ("\tExpTimeZoneId : %ld\n", Info
.ExpTimeZoneId
);
584 if (Application
.Flag
.Verbose
)
586 printf ("\tUnused : %08x (?)\n", Info
.Unused
);
593 /**********************************************************************
603 SYSTEM_PATH_INFORMATION Info
;
604 CHAR _Info
[_MAX_PATH
];
607 RtlZeroMemory (& Info
, _MAX_PATH
);
608 Status
= NtQuerySystemInformation (
609 SystemPathInformation
,
614 if (STATUS_SUCCESS
!= Status
)
616 PrintStatus (Status
);
617 DumpData (_MAX_PATH
, & _Info
);
620 DumpData (_MAX_PATH
, & _Info
);
625 /**********************************************************************
628 * A snapshot of the process+thread tables.
635 NTSTATUS Status
= STATUS_SUCCESS
;
636 PSYSTEM_PROCESS_INFORMATION pInfo
= NULL
;
640 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
641 /* FIXME: check NULL==pInfo */
643 if (Application
.Flag
.Verbose
)
645 printf ("SystemProcessInformation:\n");
648 * Obtain required buffer size
650 Status
= NtQuerySystemInformation (
651 SystemProcessInformation
,
656 if (STATUS_SUCCESS
!= Status
)
658 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
663 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
666 printf ("\tCould not allocate memory.\n");
672 PrintStatus (Status
);
678 * Get process+thread list from ntoskrnl.exe
680 Status
= NtQuerySystemInformation (
681 SystemProcessInformation
,
686 if (!NT_SUCCESS(Status
))
688 PrintStatus (Status
);
695 wprintf (L
"%s:\n", (pInfo
->Name
.Length
? pInfo
->Name
.Buffer
: L
"*idle*") );
696 if (Application
.Flag
.Verbose
)
698 wprintf (L
"\tRelativeOffset = 0x%08x\n", pInfo
->RelativeOffset
);
700 wprintf (L
"\tThreads = %ld\n", pInfo
->ThreadCount
);
701 wprintf (L
"\tHandles = %ld\n", pInfo
->HandleCount
);
702 wprintf (L
"\tBasePriority = %ld\n", pInfo
->BasePriority
);
703 wprintf (L
"\tPID = %ld\n", pInfo
->ProcessId
);
704 wprintf (L
"\tPPID = %ld\n", pInfo
->ParentProcessId
);
705 wprintf (L
"\tVirtualSize:\t\tWorkingSetSize:\n");
706 wprintf (L
"\t\tPeak : %ld\t\t\tPeak : %ld\n",
707 pInfo
->PeakVirtualSizeBytes
,
708 pInfo
->PeakWorkingSetSizeBytes
710 wprintf (L
"\t\tTotal: %ld\t\t\tTotal: %ld\n",
711 pInfo
->TotalVirtualSizeBytes
,
712 pInfo
->TotalWorkingSetSizeBytes
714 wprintf (L
"\tPagedPoolUsage:\t\tNonPagedPoolUsage:\n");
715 wprintf (L
"\t\tPeak : %ld\t\t\tPeak : %ld\n",
716 pInfo
->PeakPagedPoolUsagePages
,
717 pInfo
->TotalPagedPoolUsagePages
719 wprintf (L
"\t\tTotal: %ld\t\t\tTotal: %ld\n",
720 pInfo
->PeakNonPagedPoolUsagePages
,
721 pInfo
->TotalNonPagedPoolUsagePages
723 wprintf (L
"\tPageFileUsage:\n");
724 wprintf (L
"\t\tPeak : %ld\n", pInfo
->PeakPageFileUsageBytes
);
725 wprintf (L
"\t\tTotal: %ld\n", pInfo
->TotalPageFileUsageBytes
);
727 wprintf (L
"\tPageFaultCount = %ld\n", pInfo
->PageFaultCount
);
728 wprintf (L
"\tTotalPrivateBytes = %ld\n", pInfo
->TotalPrivateBytes
);
730 for ( ThreadIndex
= 0;
731 (ThreadIndex
< pInfo
->ThreadCount
);
735 wprintf (L
"\t%x in %x:\n",
736 pInfo
->ThreadSysInfo
[ThreadIndex
].ClientId
.UniqueThread
,
737 pInfo
->ThreadSysInfo
[ThreadIndex
].ClientId
.UniqueProcess
740 "\t\tKernelTime = %s\n",
741 & (pInfo
->ThreadSysInfo
[ThreadIndex
].KernelTime
)
744 "\t\tUserTime = %s\n",
745 & (pInfo
->ThreadSysInfo
[ThreadIndex
].UserTime
)
748 "\t\tCreateTime = %s\n",
749 & (pInfo
->ThreadSysInfo
[ThreadIndex
].CreateTime
)
751 wprintf (L
"\t\tTickCount = %ld\n",
752 pInfo
->ThreadSysInfo
[ThreadIndex
].TickCount
754 wprintf (L
"\t\tStartEIP = 0x%08x\n",
755 pInfo
->ThreadSysInfo
[ThreadIndex
].StartEIP
757 /* CLIENT_ID ClientId; */
758 wprintf (L
"\t\tDynamicPriority = %d\n",
759 pInfo
->ThreadSysInfo
[ThreadIndex
].DynamicPriority
761 wprintf (L
"\t\tBasePriority = %d\n",
762 pInfo
->ThreadSysInfo
[ThreadIndex
].BasePriority
764 wprintf (L
"\t\tnSwitches = %ld\n",
765 pInfo
->ThreadSysInfo
[ThreadIndex
].nSwitches
767 wprintf (L
"\t\tState = 0x%08x\n",
768 pInfo
->ThreadSysInfo
[ThreadIndex
].State
770 wprintf (L
"\t\tWaitReason = %ld\n",
771 pInfo
->ThreadSysInfo
[ThreadIndex
].WaitReason
775 if (0 == pInfo
->RelativeOffset
)
779 (ULONG
) pInfo
+= pInfo
->RelativeOffset
;
782 DumpData (Length
, pInfo
);
790 /**********************************************************************
797 CMD_DEF(ServiceDescriptorTable
)
800 SYSTEM_SDT_INFORMATION Info
;
804 if (Application
.Flag
.Verbose
)
806 printf ("SystemServiceDescriptorTableInfo:\n");
808 RtlZeroMemory (& Info
, sizeof Info
);
809 Status
= NtQuerySystemInformation (
810 SystemServiceDescriptorTableInfo
,
815 if (STATUS_SUCCESS
!= Status
)
817 PrintStatus (Status
);
818 DumpData (Length
, & Info
);
821 printf ("\tBufferLength = %ld\n", Info
.BufferLength
);
822 printf ("\tNumberOfSystemServiceTables = %ld\n", Info
.NumberOfSystemServiceTables
);
823 printf ("\tNumberOfServices = %ld\n", Info
.NumberOfServices
[0]);
824 printf ("\tServiceCounters = %ld\n", Info
.ServiceCounters
[0]);
826 DumpData (Length
, & Info
);
832 /**********************************************************************
841 NTSTATUS Status
= STATUS_SUCCESS
;
842 SYSTEM_IOCONFIG_INFORMATION Info
;
845 if (Application
.Flag
.Verbose
)
847 printf ("SystemIoConfigInformation:\n");
849 Status
= NtQuerySystemInformation (
850 SystemIoConfigInformation
,
855 if (STATUS_SUCCESS
!= Status
)
857 PrintStatus (Status
);
860 printf ("\tDiskCount : %ld\n", Info
.DiskCount
);
861 printf ("\tFloppyCount : %ld\n", Info
.FloppyCount
);
862 printf ("\tCdRomCount : %ld\n", Info
.CdRomCount
);
863 printf ("\tTapeCount : %ld\n", Info
.TapeCount
);
864 printf ("\tSerialCount : %ld\n", Info
.SerialCount
);
865 printf ("\tParallelCount: %ld\n", Info
.ParallelCount
);
867 DumpData (Length
, & Info
);
873 /**********************************************************************
880 CMD_DEF(ProcessorTime
)
883 SYSTEM_PROCESSORTIME_INFO Info
;
886 if (Application
.Flag
.Verbose
)
888 printf ("SystemProcessorTimeInformation:\n");
890 Status
= NtQuerySystemInformation (
891 SystemProcessorTimeInformation
,
896 if (STATUS_SUCCESS
!= Status
)
898 PrintStatus (Status
);
901 PrintUtcDateTime ("\tTotalProcessorRunTime : %s\n", & Info
.TotalProcessorRunTime
);
902 PrintUtcDateTime ("\tTotalProcessorTime : %s\n", & Info
.TotalProcessorTime
);
903 PrintUtcDateTime ("\tTotalProcessorUserTime: %s\n", & Info
.TotalProcessorUserTime
);
904 PrintUtcDateTime ("\tTotalDPCTime : %s\n", & Info
.TotalDPCTime
);
905 PrintUtcDateTime ("\tTotalInterruptTime : %s\n", & Info
.TotalInterruptTime
);
906 printf ("\tTotalInterrupts : %ld\n", Info
.TotalInterrupts
);
907 if (Application
.Flag
.Verbose
)
909 printf ("\tUnused : %08x\n", Info
.Unused
);
916 /**********************************************************************
923 CMD_DEF(NtGlobalFlag
)
926 SYSTEM_GLOBAL_FLAG_INFO Info
;
929 if (Application
.Flag
.Verbose
)
931 printf ("SystemNtGlobalFlagInformation:\n");
933 Status
= NtQuerySystemInformation (
934 SystemNtGlobalFlagInformation
,
939 if (STATUS_SUCCESS
!= Status
)
941 PrintStatus (Status
);
944 printf ("\tNtGlobalFlag: %08x\n", Info
.NtGlobalFlag
);
945 /* FIXME: decode each flag */
951 /**********************************************************************
962 /**********************************************************************
970 * Code originally in Yariv Kaplan's NtDriverList,
971 * at http://www.internals.com/, adapted to ReactOS
976 NTSTATUS Status
= STATUS_SUCCESS
;
977 PSYSTEM_MODULE_INFORMATION pInfo
= NULL
;
981 "-------- -------- -------- ---------------------------------------\n";
984 if (Application
.Flag
.Verbose
)
986 printf ("SystemModuleInformation:\n");
989 * Obtain required buffer size
991 Status
= NtQuerySystemInformation (
992 SystemModuleInformation
,
997 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
1002 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, Length
);
1005 printf ("Could not allocate memory.\n");
1006 return EXIT_FAILURE
;
1011 PrintStatus (Status
);
1012 return EXIT_FAILURE
;
1015 * Get module list from ntoskrnl.exe
1017 Status
= NtQuerySystemInformation (
1018 SystemModuleInformation
,
1023 if (!NT_SUCCESS(Status
))
1025 PrintStatus (Status
);
1026 return EXIT_FAILURE
;
1028 printf ("Index Address Size Name\n");
1032 (Index
< (int) pInfo
->Count
);
1037 "%8x %08x %8x %s\n",
1038 pInfo
->Module
[Index
].ModuleEntryIndex
,
1039 pInfo
->Module
[Index
].ModuleBaseAddress
,
1040 pInfo
->Module
[Index
].ModuleSize
,
1041 pInfo
->Module
[Index
].ModuleName
1048 return EXIT_SUCCESS
;
1052 /**********************************************************************
1059 CMD_DEF(ResourceLock
)
1061 NTSTATUS Status
= STATUS_SUCCESS
;
1062 PSYSTEM_RESOURCE_LOCK_INFO pInfo
= NULL
;
1066 "-------- -------- -------- -------- -------- -------- ------------\n";
1068 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
1069 /* FIXME: check NULL==pInfo */
1071 if (Application
.Flag
.Verbose
)
1073 printf ("SystemResourceLockInformation:\n");
1076 * Obtain required buffer size
1078 Status
= NtQuerySystemInformation (
1079 SystemResourceLockInformation
,
1081 BUFFER_SIZE_DEFAULT
, /* query size */
1084 if (STATUS_SUCCESS
!= Status
)
1086 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
1091 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
1094 printf ("Could not allocate memory.\n");
1095 return EXIT_FAILURE
;
1100 PrintStatus (Status
);
1102 return EXIT_FAILURE
;
1106 * Get locked resource list from ntoskrnl.exe
1108 Status
= NtQuerySystemInformation (
1109 SystemResourceLockInformation
,
1114 if (!NT_SUCCESS(Status
))
1116 PrintStatus (Status
);
1118 return EXIT_FAILURE
;
1120 printf ("Address Active # Content# Sh/Wait Exc/Wait\n");
1124 (Index
< (int) pInfo
->Count
);
1129 "%08x %8ld %8ld %8ld %8ld %08x\n",
1130 pInfo
->Lock
[Index
].ResourceAddress
,
1131 pInfo
->Lock
[Index
].ActiveCount
,
1132 pInfo
->Lock
[Index
].ContentionCount
,
1133 pInfo
->Lock
[Index
].NumberOfSharedWaiters
,
1134 pInfo
->Lock
[Index
].NumberOfExclusiveWaiters
,
1135 pInfo
->Lock
[Index
].Unknown
1142 return EXIT_SUCCESS
;
1146 /**********************************************************************
1157 /**********************************************************************
1168 /**********************************************************************
1179 /**********************************************************************
1184 * Class 16. You can not pass 0 as the initial output buffer's
1185 * size to get back the needed buffer size.
1189 NTSTATUS Status
= STATUS_SUCCESS
;
1190 PSYSTEM_HANDLE_INFORMATION pInfo
= NULL
;
1194 "-------- -------- ---- -------- -------- --------\n";
1195 CHAR FlagsString
[9] = {0};
1197 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
1199 if (Application
.Flag
.Verbose
)
1201 printf ("SystemHandleInformation:\n");
1204 * Obtain required buffer size
1206 Status
= NtQuerySystemInformation (
1207 SystemHandleInformation
,
1209 BUFFER_SIZE_DEFAULT
,
1212 if (STATUS_SUCCESS
!= Status
)
1214 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
1219 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
1222 printf ("\tCould not allocate memory.\n");
1223 return EXIT_FAILURE
;
1228 PrintStatus (Status
);
1230 return EXIT_FAILURE
;
1234 * Get handle table from ntoskrnl.exe
1236 Status
= NtQuerySystemInformation (
1237 SystemHandleInformation
,
1242 if (!NT_SUCCESS(Status
))
1244 PrintStatus (Status
);
1246 return EXIT_FAILURE
;
1248 printf ("Handle OwnerPID Type ObjPtr Access Flags\n");
1252 (Index
< (int) pInfo
->Count
);
1257 "%8x %8x %4d %8x %8x %s\n",
1258 pInfo
->Handle
[Index
].HandleValue
,
1259 pInfo
->Handle
[Index
].OwnerPid
,
1260 pInfo
->Handle
[Index
].ObjectType
,
1261 pInfo
->Handle
[Index
].ObjectPointer
,
1262 pInfo
->Handle
[Index
].AccessMask
,
1263 ByteToBinaryString (
1264 pInfo
->Handle
[Index
].HandleFlags
,
1271 DumpData (Length
, pInfo
);
1275 return EXIT_SUCCESS
;
1279 /**********************************************************************
1290 /**********************************************************************
1300 PSYSTEM_PAGEFILE_INFORMATION pInfo
= NULL
;
1303 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
1304 /* FIXME: check pInfo */
1306 if (Application
.Flag
.Verbose
)
1308 printf ("SystemPageFileInformation:\n");
1310 Status
= NtQuerySystemInformation(
1311 SystemPageFileInformation
,
1313 BUFFER_SIZE_DEFAULT
,
1316 if (STATUS_SUCCESS
!= Status
)
1318 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
1323 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
1326 printf ("Could not allocate memory.\n");
1327 return EXIT_FAILURE
;
1332 PrintStatus (Status
);
1334 return EXIT_FAILURE
;
1337 Status
= NtQuerySystemInformation (
1338 SystemPageFileInformation
,
1343 if (!NT_SUCCESS(Status
))
1345 PrintStatus (Status
);
1347 return EXIT_FAILURE
;
1352 wprintf (L
"\t\"%s\":\n", pInfo
->PagefileFileName
.Buffer
);
1353 if (Application
.Flag
.Verbose
)
1355 wprintf (L
"\t\tRelativeOffset = %08x\n", pInfo
->RelativeOffset
);
1357 wprintf (L
"\t\tCurrentSizePages = %ld\n", pInfo
->CurrentSizePages
);
1358 wprintf (L
"\t\tTotalUsedPages = %ld\n", pInfo
->TotalUsedPages
);
1359 wprintf (L
"\t\tPeakUsedPages = %ld\n", pInfo
->PeakUsedPages
);
1361 if (0 == pInfo
->RelativeOffset
)
1366 (ULONG
) pInfo
+= pInfo
->RelativeOffset
;
1369 DumpData (Length
, pInfo
);
1373 return EXIT_SUCCESS
;
1377 /**********************************************************************
1384 CMD_DEF(InstructionEmulation
)
1387 SYSTEM_VDM_INFORMATION Info
;
1389 if (Application
.Flag
.Verbose
)
1391 printf ("SystemInstructionEmulationInfo:\n");
1393 RtlZeroMemory (& Info
, sizeof Info
);
1394 Status
= NtQuerySystemInformation (
1395 SystemInstructionEmulationInfo
,
1400 if (!NT_SUCCESS(Status
))
1402 PrintStatus (Status
);
1403 return EXIT_FAILURE
;
1405 printf ("\tVdmSegmentNotPresentCount = %ld\n", Info
.VdmSegmentNotPresentCount
);
1406 printf ("\tVdmINSWCount = %ld\n", Info
.VdmINSWCount
);
1407 printf ("\tVdmESPREFIXCount = %ld\n", Info
.VdmESPREFIXCount
);
1408 printf ("\tVdmCSPREFIXCount = %ld\n", Info
.VdmCSPREFIXCount
);
1409 printf ("\tVdmSSPREFIXCount = %ld\n", Info
.VdmSSPREFIXCount
);
1410 printf ("\tVdmDSPREFIXCount = %ld\n", Info
.VdmDSPREFIXCount
);
1411 printf ("\tVdmFSPREFIXCount = %ld\n", Info
.VdmFSPREFIXCount
);
1412 printf ("\tVdmGSPREFIXCount = %ld\n", Info
.VdmGSPREFIXCount
);
1413 printf ("\tVdmOPER32PREFIXCount = %ld\n", Info
.VdmOPER32PREFIXCount
);
1414 printf ("\tVdmADDR32PREFIXCount = %ld\n", Info
.VdmADDR32PREFIXCount
);
1415 printf ("\tVdmINSBCount = %ld\n", Info
.VdmINSBCount
);
1416 printf ("\tVdmINSWV86Count = %ld\n", Info
.VdmINSWV86Count
);
1417 printf ("\tVdmOUTSBCount = %ld\n", Info
.VdmOUTSBCount
);
1418 printf ("\tVdmOUTSWCount = %ld\n", Info
.VdmOUTSWCount
);
1419 printf ("\tVdmPUSHFCount = %ld\n", Info
.VdmPUSHFCount
);
1420 printf ("\tVdmPOPFCount = %ld\n", Info
.VdmPOPFCount
);
1421 printf ("\tVdmINTNNCount = %ld\n", Info
.VdmINTNNCount
);
1422 printf ("\tVdmINTOCount = %ld\n", Info
.VdmINTOCount
);
1423 printf ("\tVdmIRETCount = %ld\n", Info
.VdmIRETCount
);
1424 printf ("\tVdmINBIMMCount = %ld\n", Info
.VdmINBIMMCount
);
1425 printf ("\tVdmINWIMMCount = %ld\n", Info
.VdmINWIMMCount
);
1426 printf ("\tVdmOUTBIMMCount = %ld\n", Info
.VdmOUTBIMMCount
);
1427 printf ("\tVdmOUTWIMMCount = %ld\n", Info
.VdmOUTWIMMCount
);
1428 printf ("\tVdmINBCount = %ld\n", Info
.VdmINBCount
);
1429 printf ("\tVdmINWCount = %ld\n", Info
.VdmINWCount
);
1430 printf ("\tVdmOUTBCount = %ld\n", Info
.VdmOUTBCount
);
1431 printf ("\tVdmOUTWCount = %ld\n", Info
.VdmOUTWCount
);
1432 printf ("\tVdmLOCKPREFIXCount = %ld\n", Info
.VdmLOCKPREFIXCount
);
1433 printf ("\tVdmREPNEPREFIXCount = %ld\n", Info
.VdmREPNEPREFIXCount
);
1434 printf ("\tVdmREPPREFIXCount = %ld\n", Info
.VdmREPPREFIXCount
);
1435 printf ("\tVdmHLTCount = %ld\n", Info
.VdmHLTCount
);
1436 printf ("\tVdmCLICount = %ld\n", Info
.VdmCLICount
);
1437 printf ("\tVdmSTICount = %ld\n", Info
.VdmSTICount
);
1438 printf ("\tVdmBopCount = %ld\n", Info
.VdmBopCount
);
1440 return EXIT_SUCCESS
;
1444 /**********************************************************************
1455 /**********************************************************************
1465 SYSTEM_CACHE_INFORMATION Si
;
1467 if (Application
.Flag
.Verbose
)
1469 printf ("SystemCacheInformation:\n");
1475 Status
= NtQuerySystemInformation (
1476 SystemCacheInformation
,
1481 if (!NT_SUCCESS(Status
))
1483 PrintStatus (Status
);
1484 return EXIT_FAILURE
;
1486 printf ("\tSize:\n");
1487 printf ("\t\tCurrent = %ld\n", Si
.CurrentSize
);
1488 printf ("\t\tPeak = %ld\n\n", Si
.PeakSize
);
1489 printf ("\tPageFaults:\n\t\tCount = %ld\n\n", Si
.PageFaultCount
);
1490 printf ("\tWorking Set:\n");
1491 printf ("\t\tMinimum = %ld\n", Si
.MinimumWorkingSet
);
1492 printf ("\t\tMaximum = %ld\n", Si
.MaximumWorkingSet
);
1494 return EXIT_SUCCESS
;
1498 /**********************************************************************
1501 * Get statistic data about tagged pools. Not implemented in the
1510 PSYSTEM_POOL_TAG_INFO pInfo
= NULL
;
1514 pInfo
= GlobalAlloc (GMEM_ZEROINIT
, BUFFER_SIZE_DEFAULT
);
1515 /* FIXME: check pInfo */
1517 if (Application
.Flag
.Verbose
)
1519 printf ("SystemPoolTagInformation:\n");
1521 Status
= NtQuerySystemInformation(
1522 SystemPoolTagInformation
,
1524 BUFFER_SIZE_DEFAULT
,
1527 if (STATUS_SUCCESS
!= Status
)
1529 if (STATUS_INFO_LENGTH_MISMATCH
== Status
)
1534 pInfo
= GlobalReAlloc (pInfo
, Length
, GMEM_ZEROINIT
);
1537 printf ("Could not allocate memory.\n");
1538 return EXIT_FAILURE
;
1543 PrintStatus (Status
);
1545 return EXIT_FAILURE
;
1548 Status
= NtQuerySystemInformation (
1549 SystemPoolTagInformation
,
1554 if (!NT_SUCCESS(Status
))
1556 PrintStatus (Status
);
1558 return EXIT_FAILURE
;
1561 for ( PoolIndex
= 0;
1562 (PoolIndex
< pInfo
->Count
);
1566 wprintf (L
"\t%08x:\n", pInfo
->PoolEntry
[PoolIndex
].Tag
);
1567 wprintf (L
"\t\tPaged:\t\tNon Paged:\n");
1569 L
"\t\tAllocationCount = %ld\tAllocationCount = %ld\n",
1570 pInfo
->PoolEntry
[PoolIndex
].Paged
.AllocationCount
,
1571 pInfo
->PoolEntry
[PoolIndex
].NonPaged
.AllocationCount
1574 L
"\t\tFreeCount = %ld\tFreeCount = %ld\n",
1575 pInfo
->PoolEntry
[PoolIndex
].Paged
.FreeCount
,
1576 pInfo
->PoolEntry
[PoolIndex
].NonPaged
.FreeCount
1579 L
"\t\tSizeBytes = %ld\tSizeBytes = %ld\n",
1580 pInfo
->PoolEntry
[PoolIndex
].Paged
.SizeBytes
,
1581 pInfo
->PoolEntry
[PoolIndex
].NonPaged
.SizeBytes
1585 DumpData (Length
, pInfo
);
1589 return EXIT_SUCCESS
;
1593 /**********************************************************************
1600 CMD_DEF(ProcessorSchedule
)
1603 SYSTEM_PROCESSOR_SCHEDULE_INFO Info
;
1605 if (Application
.Flag
.Verbose
)
1607 printf ("SystemProcessorScheduleInfo:\n");
1613 Status
= NtQuerySystemInformation (
1614 SystemProcessorScheduleInfo
,
1619 if (STATUS_SUCCESS
!= Status
)
1621 PrintStatus (Status
);
1622 return EXIT_FAILURE
;
1625 printf ("\tnContextSwitches = %ld\n", Info
.nContextSwitches
);
1626 printf ("\tnDPCQueued = %ld\n", Info
.nDPCQueued
);
1627 printf ("\tnDPCRate = %ld\n", Info
.nDPCRate
);
1628 printf ("\tTimerResolution = %ld\n", Info
.TimerResolution
);
1629 printf ("\tnDPCBypasses = %ld\n", Info
.nDPCBypasses
);
1630 printf ("\tnAPCBypasses = %ld\n", Info
.nAPCBypasses
);
1632 DumpData (sizeof Info
, & Info
);
1634 return EXIT_SUCCESS
;
1639 /**********************************************************************
1649 SYSTEM_DPC_INFORMATION Info
;
1651 if (Application
.Flag
.Verbose
)
1653 printf ("SystemDpcInformation:\n");
1659 Status
= NtQuerySystemInformation (
1660 SystemDpcInformation
,
1665 if (STATUS_SUCCESS
!= Status
)
1667 PrintStatus (Status
);
1668 return EXIT_FAILURE
;
1671 if (Application
.Flag
.Verbose
)
1673 printf ("\tUnused = %ld\n", Info
.Unused
);
1675 printf ("\tKiMaximumDpcQueueDepth = %ld\n", Info
.KiMaximumDpcQueueDepth
);
1676 printf ("\tKiMinimumDpcRate = %ld\n", Info
.KiMinimumDpcRate
);
1677 printf ("\tKiAdjustDpcThreshold = %ld\n", Info
.KiAdjustDpcThreshold
);
1678 printf ("\tKiIdealDpcRate = %ld\n", Info
.KiIdealDpcRate
);
1680 DumpData (sizeof Info
, & Info
);
1682 return EXIT_SUCCESS
;
1686 /**********************************************************************
1697 /**********************************************************************
1704 INT
CMD_LoadImage (INT argc
, LPCSTR argv
[])
1707 /**********************************************************************
1714 CMD_DEF(UnloadImage
)
1718 /**********************************************************************
1725 CMD_DEF(TimeAdjustment
)
1727 NTSTATUS Status
= STATUS_SUCCESS
;
1728 SYSTEM_TIME_ADJUSTMENT_INFO Info
;
1730 if (Application
.Flag
.Verbose
)
1732 printf ("SystemTimeAdjustmentInformation:\n");
1734 RtlZeroMemory (& Info
, sizeof Info
);
1735 Status
= NtQuerySystemInformation (
1736 SystemTimeAdjustmentInformation
,
1741 if (!NT_SUCCESS(Status
))
1743 PrintStatus (Status
);
1744 return EXIT_FAILURE
;
1746 printf ("\tKeTimeAdjustment = %ld\n", Info
.KeTimeAdjustment
);
1747 printf ("\tKeMaximumIncrement = %ld\n", Info
.KeMaximumIncrement
);
1748 printf ("\tKeTimeSynchronization = %s\n", TF(Info
.KeTimeSynchronization
));
1750 return EXIT_SUCCESS
;
1754 /**********************************************************************
1765 /**********************************************************************
1776 /**********************************************************************
1787 /**********************************************************************
1794 CMD_DEF(CrashDumpSection
)
1798 /**********************************************************************
1805 CMD_DEF(ProcessorFaultCount
)
1809 /**********************************************************************
1816 CMD_DEF(CrashDumpState
)
1820 /**********************************************************************
1830 SYSTEM_DEBUGGER_INFO Info
;
1832 RtlZeroMemory (& Info
, sizeof Info
);
1833 Status
= NtQuerySystemInformation (
1834 SystemDebuggerInformation
,
1839 if (STATUS_SUCCESS
!= Status
)
1841 PrintStatus (Status
);
1842 return EXIT_FAILURE
;
1844 printf ("\tKdDebuggerEnabled = %s\n", TF(Info
.KdDebuggerEnabled
));
1845 printf ("\tKdDebuggerPresent = %s\n", TF(Info
.KdDebuggerPresent
));
1847 DumpData (sizeof Info
, & Info
);
1849 return EXIT_SUCCESS
;
1853 /**********************************************************************
1860 CMD_DEF(ThreadSwitchCounters
)
1864 /**********************************************************************
1873 NTSTATUS Status
= STATUS_SUCCESS
;
1874 SYSTEM_QUOTA_INFORMATION Info
;
1876 if (Application
.Flag
.Verbose
)
1878 printf ("SystemQuotaInformation:\n");
1880 RtlZeroMemory (& Info
, sizeof Info
);
1881 Status
= NtQuerySystemInformation (
1882 SystemQuotaInformation
,
1887 if (!NT_SUCCESS(Status
))
1889 PrintStatus (Status
);
1890 return EXIT_FAILURE
;
1892 printf ("\tCmpGlobalQuota = %ld\n", Info
.CmpGlobalQuota
);
1893 printf ("\tCmpGlobalQuotaUsed = %ld\n", Info
.CmpGlobalQuotaUsed
);
1894 printf ("\tMmSizeofPagedPoolInBytes = %ld\n", Info
.MmSizeofPagedPoolInBytes
);
1896 return EXIT_SUCCESS
;
1900 /**********************************************************************
1911 /**********************************************************************
1918 CMD_DEF(PrioritySeparation
)
1922 /**********************************************************************
1933 /**********************************************************************
1944 /**********************************************************************
1955 /**********************************************************************
1966 /**********************************************************************
1969 * Dump the system TIME_ZONE_INFORMATION object.
1978 TIME_ZONE_INFORMATION Tzi
;
1981 if (Application
.Flag
.Verbose
)
1983 printf ("SystemTimeZoneInformation:\n");
1985 RtlZeroMemory (& Tzi
, sizeof Tzi
);
1986 Status
= NtQuerySystemInformation(
1987 SystemTimeZoneInformation
,
1992 if (!NT_SUCCESS(Status
))
1994 PrintStatus (Status
);
1995 return EXIT_FAILURE
;
1998 "12h/24h.....: %dh\n",
2002 "Bias........: %d'\n",
2006 printf ("Standard\n");
2013 Tzi
.StandardName
, /* WCHAR [32] */
2017 L
"\tName: \"%s\"\n",
2023 & Tzi
.StandardDate
/* SYSTEMTIME */
2026 printf ("\tBias: %d'\n",
2027 Tzi
.StandardBias
/* LONG */
2030 printf ("Daylight\n");
2037 Tzi
.DaylightName
, /* WCHAR [32] */
2041 L
"\tName: \"%s\"\n",
2047 & Tzi
.DaylightDate
/* SYSTEMTIME */
2052 Tzi
.DaylightBias
/* LONG */
2056 return EXIT_SUCCESS
;
2060 /**********************************************************************
2071 /**********************************************************************
2072 * Miscellanea Commands
2073 **********************************************************************/
2081 "ReactOS Operating System - http://www.reactos.com/\n"
2082 "QSI - Query System Information (compiled on %s, %s)\n"
2083 "Copyright (c) 1999, 2000 Emanuele Aliberti et alii\n\n",
2087 if (Application
.Flag
.Verbose
)
2091 "This program is free software; you can redistribute it and/or modify\n"
2092 "it under the terms of the GNU General Public License as published by\n"
2093 "the Free Software Foundation; either version 2 of the License, or\n"
2094 "(at your option) any later version.\n\n"
2096 "This program is distributed in the hope that it will be useful,\n"
2097 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
2098 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
2099 "GNU General Public License for more details.\n\n"
2101 "You should have received a copy of the GNU General Public License\n"
2102 "along with this program; if not, write to the Free Software\n"
2103 "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
2104 "(See also http://www.fsf.org/).\n"
2113 Application
.Active
= FALSE
;
2114 return EXIT_SUCCESS
;
2118 extern COMMAND_DESCRIPTOR Commands
[];
2124 if (Application
.Flag
.Verbose
)
2126 printf ("Commands:\n");
2129 (NULL
!= Commands
[i
].Name
);
2134 (strlen (Commands
[i
].Name
) > 7)
2138 Commands
[i
].Description
2141 return EXIT_SUCCESS
;
2149 "\nReactOS (http://www.reactos.com/):\n"
2150 "\tEmanuele Aliberti\n"
2154 "\tMark Russinovich (http://www.sysinternals.com/)\n\n"
2157 "\tYariv Kaplan (http://www.internals.com/)\n\n"
2159 "Undocumented SYSTEM_POOL_INFORMATION:\n"
2160 "\tKlaus P. Gerlicher\n\n"
2162 "Undocumented Windows NT:\n"
2163 "\tPrasad Dabak, Sandeep Phadke, and Milind Borate\n\n"
2165 "Windows NT/2000 Native API Reference:\n"
2166 "\tGary Nebbett\n\n"
2168 "comp.os.ms-windows.programmer.nt.kernel-mode\n"
2169 "\t(many postings with sample code)\n"
2176 Application
.Flag
.Verbose
= ~Application
.Flag
.Verbose
;
2178 "Verbose mode is %s.\n",
2179 ONOFF(Application
.Flag
.Verbose
)
2186 Application
.Flag
.Dump
= ~Application
.Flag
.Dump
;
2188 "Dump mode is %s.\n",
2189 ONOFF(Application
.Flag
.Dump
)
2194 /**********************************************************************
2196 **********************************************************************/
2201 /* System information classes */
2206 "Basic system information"
2211 "Processor characteristics"
2215 CMD_REF(Performance
),
2216 "System performance data"
2231 "Process & thread tables"
2235 CMD_REF(ServiceDescriptorTable
),
2236 "Service descriptor table (SDT)"
2241 "I/O devices in the system, by class"
2245 CMD_REF(ProcessorTime
),
2246 "Print processor times"
2250 CMD_REF(NtGlobalFlag
),
2251 "Print the system wide flags"
2261 "Table of kernel modules"
2265 CMD_REF(ResourceLock
),
2266 "Table of locks on resources"
2286 "Table of handles (Ps Manager)"
2291 "Table of objects (Ob Manager)"
2296 "Virtual memory paging files (Cc Subsystem)"
2300 CMD_REF(InstructionEmulation
),
2301 "Virtual DOS Machine instruction emulation (VDM)"
2311 "Cache Manager Status"
2316 "Tagged pools statistics (checked build only)"
2320 CMD_REF(ProcessorSchedule
),
2321 "Processor schedule information"
2326 "Deferred procedure call (DPC)"
2333 { /* 26 S (callable) */
2336 "Load a kernel mode DLL (in PE format)"
2338 { /* 27 S (callable) */
2340 CMD_REF(UnloadImage
),
2341 "Unload a kernel mode DLL (module)"
2345 CMD_REF(TimeAdjustment
),
2365 CMD_REF(CrashDumpSection
),
2366 "Crash Dump Section"
2370 CMD_REF(ProcessorFaultCount
),
2371 "Processor fault count"
2375 CMD_REF(CrashDumpState
),
2385 CMD_REF(ThreadSwitchCounters
),
2386 "Thread switch counters"
2391 "System quota values"
2395 CMD_REF(LoadDriver
),
2396 "Load kernel driver (SYS)"
2400 CMD_REF(PrioritySeparation
),
2401 "Priority Separation"
2426 "Time zone (TZ) information"
2442 "Print this command directory"
2447 "Print the list of people and sources that made QSI possible"
2452 "Print version number and license information"
2457 "Exit to operating system"
2462 "Enable/disable dumping raw data returned by system"
2467 "Enable/disable printing unused, unknown, and service fields"
2475 /* user input --> command decoder */
2479 DecodeCommand (LPCSTR Command
)
2485 && stricmp (Commands
[i
].Name
,Command
)
2489 return Commands
[i
].EntryPoint
;
2495 LPCSTR CommandArgv
[]
2499 LPCSTR Separators
= " \t";
2501 for ( CommandArgv
[ArgC
] = strtok ((char*)CommandLine
, (char*)Separators
);
2503 CommandArgv
[ArgC
] = (LPCSTR
) strtok (NULL
, (char*)Separators
)
2506 if (NULL
== CommandArgv
[ArgC
++])
2516 main (int argc
, char * argv
[])
2518 CHAR CommandLine
[_MAX_PATH
];
2521 LPCSTR CommandArgv
[ARGV_SIZE
];
2524 * Initialize rt data.
2526 Application
.Heap
= GetProcessHeap ();
2527 Application
.Active
= TRUE
;
2531 while (Application
.Active
)
2533 /* Print the prompt string. */
2534 if (! Application
.Flag
.Batch
)
2536 printf ("\r\nsystem> ");
2538 /* Read user command. */
2540 /* Parse the user command */
2541 CommandArgc
= ParseCommandLine (
2545 if (0 != CommandArgc
)
2547 COMMAND_CALL CommandCall
= NULL
;
2550 if ((CommandCall
= DecodeCommand (CommandArgv
[0])))
2553 Application
.ExitCode
=
2561 printf ("Unknown command (type help for a list of valid commands).\n");
2566 if (! Application
.Flag
.Batch
)
2570 return (EXIT_SUCCESS
);