1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * ReactOS ps - process list console viewer
3*c2c66affSColin Finck *
4*c2c66affSColin Finck * ps.c
5*c2c66affSColin Finck *
6*c2c66affSColin Finck * This program is free software; you can redistribute it and/or modify
7*c2c66affSColin Finck * it under the terms of the GNU General Public License as published by
8*c2c66affSColin Finck * the Free Software Foundation; either version 2 of the License, or
9*c2c66affSColin Finck * (at your option) any later version.
10*c2c66affSColin Finck *
11*c2c66affSColin Finck * This program is distributed in the hope that it will be useful,
12*c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*c2c66affSColin Finck * GNU General Public License for more details.
15*c2c66affSColin Finck *
16*c2c66affSColin Finck * You should have received a copy of the GNU General Public License
17*c2c66affSColin Finck * along with this program; if not, write to the Free Software
18*c2c66affSColin Finck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*c2c66affSColin Finck */
20*c2c66affSColin Finck /*
21*c2c66affSColin Finck Thanks to Filip Navara patch for fixing the Xp crash problem.
22*c2c66affSColin Finck */
23*c2c66affSColin Finck
24*c2c66affSColin Finck #define NTOS_MODE_USER
25*c2c66affSColin Finck #define WIN32_NO_STATUS
26*c2c66affSColin Finck #include <windows.h>
27*c2c66affSColin Finck #include <ndk/ntndk.h>
28*c2c66affSColin Finck
29*c2c66affSColin Finck typedef struct _SYSTEM_THREADS
30*c2c66affSColin Finck {
31*c2c66affSColin Finck LARGE_INTEGER KernelTime;
32*c2c66affSColin Finck LARGE_INTEGER UserTime;
33*c2c66affSColin Finck LARGE_INTEGER CreateTime;
34*c2c66affSColin Finck ULONG WaitTime;
35*c2c66affSColin Finck PVOID StartAddress;
36*c2c66affSColin Finck CLIENT_ID ClientId;
37*c2c66affSColin Finck KPRIORITY Priority;
38*c2c66affSColin Finck LONG BasePriority;
39*c2c66affSColin Finck ULONG ContextSwitches;
40*c2c66affSColin Finck ULONG ThreadState;
41*c2c66affSColin Finck ULONG WaitReason;
42*c2c66affSColin Finck } SYSTEM_THREADS, *PSYSTEM_THREADS;
43*c2c66affSColin Finck
44*c2c66affSColin Finck typedef struct _SYSTEM_PROCESSES
45*c2c66affSColin Finck {
46*c2c66affSColin Finck ULONG NextEntryOffset;
47*c2c66affSColin Finck ULONG NumberOfThreads;
48*c2c66affSColin Finck LARGE_INTEGER SpareLi1;
49*c2c66affSColin Finck LARGE_INTEGER SpareLi2;
50*c2c66affSColin Finck LARGE_INTEGER SpareLi3;
51*c2c66affSColin Finck LARGE_INTEGER CreateTime;
52*c2c66affSColin Finck LARGE_INTEGER UserTime;
53*c2c66affSColin Finck LARGE_INTEGER KernelTime;
54*c2c66affSColin Finck UNICODE_STRING ImageName;
55*c2c66affSColin Finck KPRIORITY BasePriority;
56*c2c66affSColin Finck HANDLE UniqueProcessId;
57*c2c66affSColin Finck HANDLE InheritedFromUniqueProcessId;
58*c2c66affSColin Finck ULONG HandleCount;
59*c2c66affSColin Finck ULONG SessionId;
60*c2c66affSColin Finck ULONG PageDirectoryFrame;
61*c2c66affSColin Finck
62*c2c66affSColin Finck /*
63*c2c66affSColin Finck * This part corresponds to VM_COUNTERS_EX.
64*c2c66affSColin Finck * NOTE: *NOT* THE SAME AS VM_COUNTERS!
65*c2c66affSColin Finck */
66*c2c66affSColin Finck ULONG PeakVirtualSize;
67*c2c66affSColin Finck ULONG VirtualSize;
68*c2c66affSColin Finck ULONG PageFaultCount;
69*c2c66affSColin Finck ULONG PeakWorkingSetSize;
70*c2c66affSColin Finck ULONG WorkingSetSize;
71*c2c66affSColin Finck ULONG QuotaPeakPagedPoolUsage;
72*c2c66affSColin Finck ULONG QuotaPagedPoolUsage;
73*c2c66affSColin Finck ULONG QuotaPeakNonPagedPoolUsage;
74*c2c66affSColin Finck ULONG QuotaNonPagedPoolUsage;
75*c2c66affSColin Finck ULONG PagefileUsage;
76*c2c66affSColin Finck ULONG PeakPagefileUsage;
77*c2c66affSColin Finck ULONG PrivateUsage;
78*c2c66affSColin Finck
79*c2c66affSColin Finck /* This part corresponds to IO_COUNTERS */
80*c2c66affSColin Finck LARGE_INTEGER ReadOperationCount;
81*c2c66affSColin Finck LARGE_INTEGER WriteOperationCount;
82*c2c66affSColin Finck LARGE_INTEGER OtherOperationCount;
83*c2c66affSColin Finck LARGE_INTEGER ReadTransferCount;
84*c2c66affSColin Finck LARGE_INTEGER WriteTransferCount;
85*c2c66affSColin Finck LARGE_INTEGER OtherTransferCount;
86*c2c66affSColin Finck
87*c2c66affSColin Finck SYSTEM_THREADS Threads [1];
88*c2c66affSColin Finck } SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
89*c2c66affSColin Finck
90*c2c66affSColin Finck
91*c2c66affSColin Finck // x00000000 00000000 000:00:00 000:00:00 ()
92*c2c66affSColin Finck static char title[] = "P PID PPID KTime UTime NAME\n";
93*c2c66affSColin Finck static char title1[] = "t TID KTime UTime State WaitResson\n";
94*c2c66affSColin Finck static char title2[] = "w PID Hwnd WndStile TID WndName\n";
95*c2c66affSColin Finck
96*c2c66affSColin Finck
97*c2c66affSColin Finck struct status {
98*c2c66affSColin Finck DWORD state;
99*c2c66affSColin Finck const char desc[10];
100*c2c66affSColin Finck } thread_stat[8 + 1] = {
101*c2c66affSColin Finck {0, "Init "},
102*c2c66affSColin Finck {1, "Ready "},
103*c2c66affSColin Finck {2, "Running "},
104*c2c66affSColin Finck {3, "Standby "},
105*c2c66affSColin Finck {4, "Terminated"},
106*c2c66affSColin Finck {5, "Wait "},
107*c2c66affSColin Finck {6, "Transition"},
108*c2c66affSColin Finck {7, "Unknown "},
109*c2c66affSColin Finck {-1," ? "}
110*c2c66affSColin Finck };
111*c2c66affSColin Finck
112*c2c66affSColin Finck struct waitres {
113*c2c66affSColin Finck DWORD state;
114*c2c66affSColin Finck char desc[17];
115*c2c66affSColin Finck } waitreason[35 + 1] = {
116*c2c66affSColin Finck {0, "Executive "},
117*c2c66affSColin Finck {1, "FreePage "},
118*c2c66affSColin Finck {2, "PageIn "},
119*c2c66affSColin Finck {3, "PoolAllocation "},
120*c2c66affSColin Finck {4, "DelayExecution "},
121*c2c66affSColin Finck {5, "Suspended "},
122*c2c66affSColin Finck {6, "UserRequest "},
123*c2c66affSColin Finck {7, "WrExecutive "},
124*c2c66affSColin Finck {8, "WrFreePage "},
125*c2c66affSColin Finck {9, "WrPageIn "},
126*c2c66affSColin Finck {10,"WrPoolAllocation "},
127*c2c66affSColin Finck {11,"WrDelayExecution "},
128*c2c66affSColin Finck {12,"WrSuspended "},
129*c2c66affSColin Finck {13,"WrUserRequest "},
130*c2c66affSColin Finck {14,"WrEventPair "},
131*c2c66affSColin Finck {15,"WrQueue "},
132*c2c66affSColin Finck {16,"WrLpcReceive "},
133*c2c66affSColin Finck {17,"WrLpcReply "},
134*c2c66affSColin Finck {18,"WrVirtualMemory "},
135*c2c66affSColin Finck {19,"WrPageOut "},
136*c2c66affSColin Finck {20,"WrRendezvous "},
137*c2c66affSColin Finck {21,"Spare2 "},
138*c2c66affSColin Finck {22,"WrGuardedMutex "},
139*c2c66affSColin Finck {23,"Spare4 "},
140*c2c66affSColin Finck {24,"Spare5 "},
141*c2c66affSColin Finck {25,"Spare6 "},
142*c2c66affSColin Finck {26,"WrKernel "},
143*c2c66affSColin Finck {27,"WrResource "},
144*c2c66affSColin Finck {28,"WrPushLock "},
145*c2c66affSColin Finck {29,"WrMutex "},
146*c2c66affSColin Finck {30,"WrQuantumEnd "},
147*c2c66affSColin Finck {31,"WrDispatchInt "},
148*c2c66affSColin Finck {32,"WrPreempted "},
149*c2c66affSColin Finck {33,"WrYieldExecution "},
150*c2c66affSColin Finck {34,"MaximumWaitReason"},
151*c2c66affSColin Finck {-1," ? "}
152*c2c66affSColin Finck };
153*c2c66affSColin Finck
154*c2c66affSColin Finck static BOOL CALLBACK
EnumThreadProc(HWND hwnd,LPARAM lp)155*c2c66affSColin Finck EnumThreadProc(HWND hwnd, LPARAM lp)
156*c2c66affSColin Finck {
157*c2c66affSColin Finck DWORD r, pid, tid;
158*c2c66affSColin Finck LONG style;
159*c2c66affSColin Finck char buf[256];
160*c2c66affSColin Finck HANDLE Stdout = GetStdHandle(STD_OUTPUT_HANDLE);
161*c2c66affSColin Finck
162*c2c66affSColin Finck GetWindowText(hwnd, (LPTSTR)lp, 30);
163*c2c66affSColin Finck
164*c2c66affSColin Finck if(hwnd != 0)
165*c2c66affSColin Finck {
166*c2c66affSColin Finck style = GetWindowLong(hwnd, GWL_STYLE);
167*c2c66affSColin Finck
168*c2c66affSColin Finck tid = GetWindowThreadProcessId(hwnd, &pid);
169*c2c66affSColin Finck
170*c2c66affSColin Finck wsprintf (buf,"w%8d %8x %08x %8d %s\n",pid, hwnd , style, tid, lp );
171*c2c66affSColin Finck WriteFile(Stdout, buf, lstrlen(buf), &r, NULL);
172*c2c66affSColin Finck }
173*c2c66affSColin Finck return (TRUE);
174*c2c66affSColin Finck }
175*c2c66affSColin Finck
main()176*c2c66affSColin Finck int main()
177*c2c66affSColin Finck {
178*c2c66affSColin Finck DWORD r;
179*c2c66affSColin Finck ANSI_STRING astring;
180*c2c66affSColin Finck HANDLE Stdout = GetStdHandle(STD_OUTPUT_HANDLE);
181*c2c66affSColin Finck PSYSTEM_PROCESSES SystemProcesses = NULL;
182*c2c66affSColin Finck PSYSTEM_PROCESSES CurrentProcess;
183*c2c66affSColin Finck ULONG BufferSize, ReturnSize;
184*c2c66affSColin Finck NTSTATUS Status;
185*c2c66affSColin Finck char buf[256];
186*c2c66affSColin Finck char buf1[256];
187*c2c66affSColin Finck
188*c2c66affSColin Finck WriteFile(Stdout, title, lstrlen(title), &r, NULL);
189*c2c66affSColin Finck WriteFile(Stdout, title1, lstrlen(title1), &r, NULL);
190*c2c66affSColin Finck WriteFile(Stdout, title2, lstrlen(title2), &r, NULL);
191*c2c66affSColin Finck
192*c2c66affSColin Finck /* Get process information. */
193*c2c66affSColin Finck BufferSize = 0;
194*c2c66affSColin Finck do
195*c2c66affSColin Finck {
196*c2c66affSColin Finck BufferSize += 0x10000;
197*c2c66affSColin Finck SystemProcesses = HeapAlloc(GetProcessHeap(), 0, BufferSize);
198*c2c66affSColin Finck Status = NtQuerySystemInformation(SystemProcessInformation,
199*c2c66affSColin Finck SystemProcesses, BufferSize,
200*c2c66affSColin Finck &ReturnSize);
201*c2c66affSColin Finck if (Status == STATUS_INFO_LENGTH_MISMATCH)
202*c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, SystemProcesses);
203*c2c66affSColin Finck } while (Status == STATUS_INFO_LENGTH_MISMATCH);
204*c2c66affSColin Finck
205*c2c66affSColin Finck /* If querying system information failed, bail out. */
206*c2c66affSColin Finck if (!NT_SUCCESS(Status))
207*c2c66affSColin Finck return 1;
208*c2c66affSColin Finck
209*c2c66affSColin Finck /* For every process print the information. */
210*c2c66affSColin Finck CurrentProcess = SystemProcesses;
211*c2c66affSColin Finck while (CurrentProcess->NextEntryOffset != 0)
212*c2c66affSColin Finck {
213*c2c66affSColin Finck int hour, hour1, thour, thour1;
214*c2c66affSColin Finck unsigned char minute, minute1, tmin, tmin1;
215*c2c66affSColin Finck unsigned char seconds, seconds1, tsec, tsec1;
216*c2c66affSColin Finck
217*c2c66affSColin Finck unsigned int ti;
218*c2c66affSColin Finck LARGE_INTEGER ptime;
219*c2c66affSColin Finck
220*c2c66affSColin Finck ptime.QuadPart = CurrentProcess->KernelTime.QuadPart;
221*c2c66affSColin Finck hour = (ptime.QuadPart / (10000000LL * 3600LL));
222*c2c66affSColin Finck minute = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
223*c2c66affSColin Finck seconds = (ptime.QuadPart / 10000000LL) % 60LL;
224*c2c66affSColin Finck
225*c2c66affSColin Finck ptime.QuadPart = CurrentProcess->UserTime.QuadPart;
226*c2c66affSColin Finck hour1 = (ptime.QuadPart / (10000000LL * 3600LL));
227*c2c66affSColin Finck minute1 = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
228*c2c66affSColin Finck seconds1 = (ptime.QuadPart / 10000000LL) % 60LL;
229*c2c66affSColin Finck
230*c2c66affSColin Finck RtlUnicodeStringToAnsiString(&astring, &CurrentProcess->ImageName, TRUE);
231*c2c66affSColin Finck
232*c2c66affSColin Finck wsprintf(buf,"P%8d %8d %3d:%02d:%02d %3d:%02d:%02d ProcName: %s\n",
233*c2c66affSColin Finck CurrentProcess->UniqueProcessId, CurrentProcess->InheritedFromUniqueProcessId,
234*c2c66affSColin Finck hour, minute, seconds, hour1, minute1, seconds1,
235*c2c66affSColin Finck astring.Buffer);
236*c2c66affSColin Finck WriteFile(stdout, buf, lstrlen(buf), &r, NULL);
237*c2c66affSColin Finck
238*c2c66affSColin Finck RtlFreeAnsiString(&astring);
239*c2c66affSColin Finck
240*c2c66affSColin Finck for (ti = 0; ti < CurrentProcess->NumberOfThreads; ti++)
241*c2c66affSColin Finck {
242*c2c66affSColin Finck struct status *statt;
243*c2c66affSColin Finck struct waitres *waitt;
244*c2c66affSColin Finck char szWindowName[30] = {" "};
245*c2c66affSColin Finck
246*c2c66affSColin Finck ptime = CurrentProcess->Threads[ti].KernelTime;
247*c2c66affSColin Finck thour = (ptime.QuadPart / (10000000LL * 3600LL));
248*c2c66affSColin Finck tmin = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
249*c2c66affSColin Finck tsec = (ptime.QuadPart / 10000000LL) % 60LL;
250*c2c66affSColin Finck
251*c2c66affSColin Finck ptime = CurrentProcess->Threads[ti].UserTime;
252*c2c66affSColin Finck thour1 = (ptime.QuadPart / (10000000LL * 3600LL));
253*c2c66affSColin Finck tmin1 = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
254*c2c66affSColin Finck tsec1 = (ptime.QuadPart / 10000000LL) % 60LL;
255*c2c66affSColin Finck
256*c2c66affSColin Finck statt = thread_stat;
257*c2c66affSColin Finck while (statt->state != CurrentProcess->Threads[ti].ThreadState && statt->state >= 0)
258*c2c66affSColin Finck statt++;
259*c2c66affSColin Finck
260*c2c66affSColin Finck waitt = waitreason;
261*c2c66affSColin Finck while (waitt->state != CurrentProcess->Threads[ti].WaitReason && waitt->state >= 0)
262*c2c66affSColin Finck waitt++;
263*c2c66affSColin Finck
264*c2c66affSColin Finck wsprintf (buf1,
265*c2c66affSColin Finck "t% %8d %3d:%02d:%02d %3d:%02d:%02d %s %s\n",
266*c2c66affSColin Finck CurrentProcess->Threads[ti].ClientId.UniqueThread,
267*c2c66affSColin Finck thour, tmin, tsec, thour1, tmin1, tsec1,
268*c2c66affSColin Finck statt->desc , waitt->desc);
269*c2c66affSColin Finck WriteFile(stdout, buf1, lstrlen(buf1), &r, NULL);
270*c2c66affSColin Finck
271*c2c66affSColin Finck EnumThreadWindows(PtrToUlong(CurrentProcess->Threads[ti].ClientId.UniqueThread),
272*c2c66affSColin Finck (WNDENUMPROC) EnumThreadProc,
273*c2c66affSColin Finck (LPARAM)(LPTSTR) szWindowName );
274*c2c66affSColin Finck }
275*c2c66affSColin Finck
276*c2c66affSColin Finck CurrentProcess = (PSYSTEM_PROCESSES)((ULONG_PTR)CurrentProcess +
277*c2c66affSColin Finck (ULONG_PTR)CurrentProcess->NextEntryOffset);
278*c2c66affSColin Finck }
279*c2c66affSColin Finck return (0);
280*c2c66affSColin Finck }
281