881431a0f2ab14fdb6793cca91248e9d6ca45f98
[reactos.git] / reactos / apps / utils / ps / ps.c
1 /* $Id$
2 *
3 * ReactOS ps - process list console viewer
4 *
5 * ps.c
6 *
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.
11 *
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.
16 *
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.
20 */
21 /*
22 Thanks to Filip Navara patch for fixing the Xp crash problem.
23 */
24
25 #include <windows.h>
26 /* NOTE: W32API ddk/ntapi.h header has wrong definition of SYSTEM_PROCESSES. */
27 #include <ntos/types.h>
28
29
30 // x00000000 00000000 000:00:00 000:00:00 ()
31 static char* title = "P PID PPID KTime UTime NAME\n";
32 static char* title1 = "t TID KTime UTime State WaitResson\n";
33 static char* title2 = "w PID Hwnd WndStile TID WndName\n";
34
35
36 struct status {
37 DWORD state;
38 char desc[10];
39 } thread_stat[8 + 1] = {
40 {0, "Init "},
41 {1, "Ready "},
42 {2, "Running "},
43 {3, "Standby "},
44 {4, "Terminated"},
45 {5, "Wait "},
46 {6, "Transition"},
47 {7, "Unknown "},
48 {-1," ? "}
49 };
50
51 struct waitres {
52 DWORD state;
53 char desc[11];
54 } waitreason[28 + 1] = {
55 {0, "Executive "},
56 {1, "FreePage "},
57 {2, "PageIn "},
58 {3, "PoolAlloc "},
59 {4, "DelayExec "},
60 {5, "Suspended "},
61 {6, "UserReq "},
62 {7, "WrExecutive"},
63 {8, "WrFreePage "},
64 {9, "WrPageIn "},
65 {10,"WrPoolAlloc"},
66 {11,"WrDelayExec"},
67 {12,"WrSuspended"},
68 {13,"WrUserReq "},
69 {14,"WrEventPair"},
70 {15,"WrQueue "},
71 {16,"WrLpcRec "},
72 {17,"WrLpcReply "},
73 {18,"WrVirtualMm"},
74 {19,"WrPageOut "},
75 {20,"WrRendez "},
76 {21,"Spare1 "},
77 {22,"Spare2 "},
78 {23,"Spare3 "},
79 {24,"Spare4 "},
80 {25,"Spare5 "},
81 {26,"Spare6 "},
82 {27,"WrKernel "},
83 {-1," ? "}
84 };
85
86 BOOL CALLBACK
87 EnumThreadProc(HWND hwnd, LPARAM lp)
88 {
89 DWORD r, pid, tid;
90 LONG style;
91 HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
92 char buf[256];
93
94 GetWindowText(hwnd, (LPTSTR)lp, 30);
95
96 if(hwnd != 0)
97 {
98 style = GetWindowLong(hwnd, GWL_STYLE);
99
100 tid = GetWindowThreadProcessId(hwnd, &pid);
101
102 wsprintf (buf,"w%8d %8x %08x %8d %s\n",pid, hwnd , style, tid, lp );
103 WriteFile(stdout, buf, lstrlen(buf), &r, NULL);
104 }
105 return (TRUE);
106 }
107
108 int main()
109 {
110 DWORD r;
111 ANSI_STRING astring;
112 HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
113 PSYSTEM_PROCESS_INFORMATION SystemProcesses = NULL;
114 PSYSTEM_PROCESS_INFORMATION CurrentProcess;
115 ULONG BufferSize, ReturnSize;
116 NTSTATUS Status;
117 char buf[256];
118 char buf1[256];
119
120 WriteFile(stdout, title, lstrlen(title), &r, NULL);
121 WriteFile(stdout, title1, lstrlen(title1), &r, NULL);
122 WriteFile(stdout, title2, lstrlen(title2), &r, NULL);
123
124 /* Get process information. */
125 BufferSize = 0;
126 do
127 {
128 BufferSize += 0x10000;
129 SystemProcesses = HeapAlloc(GetProcessHeap(), 0, BufferSize);
130 Status = NtQuerySystemInformation(SystemProcessInformation,
131 SystemProcesses, BufferSize,
132 &ReturnSize);
133 if (Status == STATUS_INFO_LENGTH_MISMATCH)
134 HeapFree(GetProcessHeap(), 0, SystemProcesses);
135 } while (Status == STATUS_INFO_LENGTH_MISMATCH);
136
137 /* If querying system information failed, bail out. */
138 if (!NT_SUCCESS(Status))
139 return 1;
140
141 /* For every process print the information. */
142 CurrentProcess = SystemProcesses;
143 while (CurrentProcess->NextEntryOffset != 0)
144 {
145 int hour, hour1, thour, thour1;
146 unsigned char minute, minute1, tmin, tmin1;
147 unsigned char seconds, seconds1, tsec, tsec1;
148
149 int ti;
150 LARGE_INTEGER ptime;
151
152 ptime.QuadPart = CurrentProcess->KernelTime.QuadPart;
153 hour = (ptime.QuadPart / (10000000LL * 3600LL));
154 minute = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
155 seconds = (ptime.QuadPart / 10000000LL) % 60LL;
156
157 ptime.QuadPart = CurrentProcess->UserTime.QuadPart;
158 hour1 = (ptime.QuadPart / (10000000LL * 3600LL));
159 minute1 = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
160 seconds1 = (ptime.QuadPart / 10000000LL) % 60LL;
161
162 RtlUnicodeStringToAnsiString(&astring, &CurrentProcess->ImageName, TRUE);
163
164 wsprintf(buf,"P%8d %8d %3d:%02d:%02d %3d:%02d:%02d ProcName: %s\n",
165 CurrentProcess->UniqueProcessId, CurrentProcess->InheritedFromUniqueProcessId,
166 hour, minute, seconds, hour1, minute1, seconds1,
167 astring.Buffer);
168 WriteFile(stdout, buf, lstrlen(buf), &r, NULL);
169
170 RtlFreeAnsiString(&astring);
171
172 for (ti = 0; ti < CurrentProcess->NumberOfThreads; ti++)
173 {
174 struct status *statt;
175 struct waitres *waitt;
176 char szWindowName[30] = {" "};
177
178 ptime = CurrentProcess->TH[ti].KernelTime;
179 thour = (ptime.QuadPart / (10000000LL * 3600LL));
180 tmin = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
181 tsec = (ptime.QuadPart / 10000000LL) % 60LL;
182
183 ptime = CurrentProcess->TH[ti].UserTime;
184 thour1 = (ptime.QuadPart / (10000000LL * 3600LL));
185 tmin1 = (ptime.QuadPart / (10000000LL * 60LL)) % 60LL;
186 tsec1 = (ptime.QuadPart / 10000000LL) % 60LL;
187
188 statt = thread_stat;
189 while (statt->state != CurrentProcess->TH[ti].ThreadState && statt->state >= 0)
190 statt++;
191
192 waitt = waitreason;
193 while (waitt->state != CurrentProcess->TH[ti].WaitReason && waitt->state >= 0)
194 waitt++;
195
196 wsprintf (buf1,
197 "t% %8d %3d:%02d:%02d %3d:%02d:%02d %s %s\n",
198 CurrentProcess->TH[ti].ClientId.UniqueThread,
199 thour, tmin, tsec, thour1, tmin1, tsec1,
200 statt->desc , waitt->desc);
201 WriteFile(stdout, buf1, lstrlen(buf1), &r, NULL);
202
203 EnumThreadWindows((DWORD)CurrentProcess->TH[ti].ClientId.UniqueThread,
204 (ENUMWINDOWSPROC) EnumThreadProc,
205 (LPARAM)(LPTSTR) szWindowName );
206 }
207 CurrentProcess = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)CurrentProcess +
208 CurrentProcess->NextEntryOffset);
209 }
210 return (0);
211 }