3 * ReactOS ps - process list console viewer
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 Thanks to Filip Navara patch for fixing the Xp crash problem.
26 #define NTOS_MODE_USER
27 #include <ndk/ntndk.h>
29 typedef struct _SYSTEM_THREADS
31 LARGE_INTEGER KernelTime
;
32 LARGE_INTEGER UserTime
;
33 LARGE_INTEGER CreateTime
;
39 ULONG ContextSwitches
;
42 } SYSTEM_THREADS
, *PSYSTEM_THREADS
;
44 typedef struct _SYSTEM_PROCESSES
46 ULONG NextEntryOffset
;
47 ULONG NumberOfThreads
;
48 LARGE_INTEGER SpareLi1
;
49 LARGE_INTEGER SpareLi2
;
50 LARGE_INTEGER SpareLi3
;
51 LARGE_INTEGER CreateTime
;
52 LARGE_INTEGER UserTime
;
53 LARGE_INTEGER KernelTime
;
54 UNICODE_STRING ImageName
;
55 KPRIORITY BasePriority
;
56 HANDLE UniqueProcessId
;
57 HANDLE InheritedFromUniqueProcessId
;
60 ULONG PageDirectoryFrame
;
63 * This part corresponds to VM_COUNTERS_EX.
64 * NOTE: *NOT* THE SAME AS VM_COUNTERS!
66 ULONG PeakVirtualSize
;
69 ULONG PeakWorkingSetSize
;
71 ULONG QuotaPeakPagedPoolUsage
;
72 ULONG QuotaPagedPoolUsage
;
73 ULONG QuotaPeakNonPagedPoolUsage
;
74 ULONG QuotaNonPagedPoolUsage
;
76 ULONG PeakPagefileUsage
;
79 /* This part corresponds to IO_COUNTERS */
80 LARGE_INTEGER ReadOperationCount
;
81 LARGE_INTEGER WriteOperationCount
;
82 LARGE_INTEGER OtherOperationCount
;
83 LARGE_INTEGER ReadTransferCount
;
84 LARGE_INTEGER WriteTransferCount
;
85 LARGE_INTEGER OtherTransferCount
;
87 SYSTEM_THREADS Threads
[1];
88 } SYSTEM_PROCESSES
, *PSYSTEM_PROCESSES
;
91 // x00000000 00000000 000:00:00 000:00:00 ()
92 static char* title
= "P PID PPID KTime UTime NAME\n";
93 static char* title1
= "t TID KTime UTime State WaitResson\n";
94 static char* title2
= "w PID Hwnd WndStile TID WndName\n";
100 } thread_stat
[8 + 1] = {
115 } waitreason
[35 + 1] = {
119 {3, "PoolAllocation "},
120 {4, "DelayExecution "},
126 {10,"WrPoolAllocation "},
127 {11,"WrDelayExecution "},
129 {13,"WrUserRequest "},
132 {16,"WrLpcReceive "},
134 {18,"WrVirtualMemory "},
136 {20,"WrRendezvous "},
138 {22,"WrGuardedMutex "},
146 {30,"WrQuantumEnd "},
147 {31,"WrDispatchInt "},
149 {33,"WrYieldExecution "},
150 {34,"MaximumWaitReason"},
154 EnumThreadProc(HWND hwnd
, LPARAM lp
)
158 HANDLE stdout
= GetStdHandle(STD_OUTPUT_HANDLE
);
161 GetWindowText(hwnd
, (LPTSTR
)lp
, 30);
165 style
= GetWindowLong(hwnd
, GWL_STYLE
);
167 tid
= GetWindowThreadProcessId(hwnd
, &pid
);
169 wsprintf (buf
,"w%8d %8x %08x %8d %s\n",pid
, hwnd
, style
, tid
, lp
);
170 WriteFile(stdout
, buf
, lstrlen(buf
), &r
, NULL
);
179 HANDLE stdout
= GetStdHandle(STD_OUTPUT_HANDLE
);
180 PSYSTEM_PROCESSES SystemProcesses
= NULL
;
181 PSYSTEM_PROCESSES CurrentProcess
;
182 ULONG BufferSize
, ReturnSize
;
187 WriteFile(stdout
, title
, lstrlen(title
), &r
, NULL
);
188 WriteFile(stdout
, title1
, lstrlen(title1
), &r
, NULL
);
189 WriteFile(stdout
, title2
, lstrlen(title2
), &r
, NULL
);
191 /* Get process information. */
195 BufferSize
+= 0x10000;
196 SystemProcesses
= HeapAlloc(GetProcessHeap(), 0, BufferSize
);
197 Status
= NtQuerySystemInformation(SystemProcessInformation
,
198 SystemProcesses
, BufferSize
,
200 if (Status
== STATUS_INFO_LENGTH_MISMATCH
)
201 HeapFree(GetProcessHeap(), 0, SystemProcesses
);
202 } while (Status
== STATUS_INFO_LENGTH_MISMATCH
);
204 /* If querying system information failed, bail out. */
205 if (!NT_SUCCESS(Status
))
208 /* For every process print the information. */
209 CurrentProcess
= SystemProcesses
;
210 while (CurrentProcess
->NextEntryOffset
!= 0)
212 int hour
, hour1
, thour
, thour1
;
213 unsigned char minute
, minute1
, tmin
, tmin1
;
214 unsigned char seconds
, seconds1
, tsec
, tsec1
;
219 ptime
.QuadPart
= CurrentProcess
->KernelTime
.QuadPart
;
220 hour
= (ptime
.QuadPart
/ (10000000LL * 3600LL));
221 minute
= (ptime
.QuadPart
/ (10000000LL * 60LL)) % 60LL;
222 seconds
= (ptime
.QuadPart
/ 10000000LL) % 60LL;
224 ptime
.QuadPart
= CurrentProcess
->UserTime
.QuadPart
;
225 hour1
= (ptime
.QuadPart
/ (10000000LL * 3600LL));
226 minute1
= (ptime
.QuadPart
/ (10000000LL * 60LL)) % 60LL;
227 seconds1
= (ptime
.QuadPart
/ 10000000LL) % 60LL;
229 RtlUnicodeStringToAnsiString(&astring
, &CurrentProcess
->ImageName
, TRUE
);
231 wsprintf(buf
,"P%8d %8d %3d:%02d:%02d %3d:%02d:%02d ProcName: %s\n",
232 CurrentProcess
->UniqueProcessId
, CurrentProcess
->InheritedFromUniqueProcessId
,
233 hour
, minute
, seconds
, hour1
, minute1
, seconds1
,
235 WriteFile(stdout
, buf
, lstrlen(buf
), &r
, NULL
);
237 RtlFreeAnsiString(&astring
);
239 for (ti
= 0; ti
< CurrentProcess
->NumberOfThreads
; ti
++)
241 struct status
*statt
;
242 struct waitres
*waitt
;
243 char szWindowName
[30] = {" "};
245 ptime
= CurrentProcess
->Threads
[ti
].KernelTime
;
246 thour
= (ptime
.QuadPart
/ (10000000LL * 3600LL));
247 tmin
= (ptime
.QuadPart
/ (10000000LL * 60LL)) % 60LL;
248 tsec
= (ptime
.QuadPart
/ 10000000LL) % 60LL;
250 ptime
= CurrentProcess
->Threads
[ti
].UserTime
;
251 thour1
= (ptime
.QuadPart
/ (10000000LL * 3600LL));
252 tmin1
= (ptime
.QuadPart
/ (10000000LL * 60LL)) % 60LL;
253 tsec1
= (ptime
.QuadPart
/ 10000000LL) % 60LL;
256 while (statt
->state
!= CurrentProcess
->Threads
[ti
].ThreadState
&& statt
->state
>= 0)
260 while (waitt
->state
!= CurrentProcess
->Threads
[ti
].WaitReason
&& waitt
->state
>= 0)
264 "t% %8d %3d:%02d:%02d %3d:%02d:%02d %s %s\n",
265 CurrentProcess
->Threads
[ti
].ClientId
.UniqueThread
,
266 thour
, tmin
, tsec
, thour1
, tmin1
, tsec1
,
267 statt
->desc
, waitt
->desc
);
268 WriteFile(stdout
, buf1
, lstrlen(buf1
), &r
, NULL
);
270 EnumThreadWindows((DWORD
)CurrentProcess
->Threads
[ti
].ClientId
.UniqueThread
,
271 (ENUMWINDOWSPROC
) EnumThreadProc
,
272 (LPARAM
)(LPTSTR
) szWindowName
);
274 CurrentProcess
= (PSYSTEM_PROCESSES
)((ULONG_PTR
)CurrentProcess
+
275 CurrentProcess
->NextEntryOffset
);