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