1 /* $Id: tlist.c,v 1.6 2003/08/03 18:06:02 ea Exp $
6 * Copyright (c) 2000,2001 Emanuele Aliberti
8 #include <reactos/buildno.h>
21 #define PAGE_SIZE 4096
24 #define ALREADY_PROCESSED ((DWORD)-1)
26 LPWSTR ThreadStateName
[] =
39 void *PsaiMalloc(SIZE_T size
)
44 nErrCode
= NtAllocateVirtualMemory
54 if(NT_SUCCESS(nErrCode
)) return pBuf
;
58 void PsaiFree(void *ptr
)
62 NtFreeVirtualMemory(NtCurrentProcess(), &ptr
, &nSize
, MEM_RELEASE
);
65 int STDCALL
PrintBanner (VOID
)
67 printf ("ReactOS "KERNEL_RELEASE_STR
" T(ask)List\n");
68 printf ("Copyright (c) 2000,2001 Emanuele Aliberti\n\n");
72 int STDCALL
PrintSynopsys (int nRetVal
)
75 printf ("Usage: tlist [-t | PID | -l]\n\n"
76 " -t print the task list tree\n"
77 " PID print module information for this ID\n"
78 " -l print license information\n");
82 int STDCALL
PrintLicense (VOID
)
86 "This program is free software; you can redistribute it and/or modify\n"
87 "it under the terms of the GNU General Public License as published by\n"
88 "the Free Software Foundation; either version 2 of the License, or\n"
89 "(at your option) any later version.\n\n");
91 "This program is distributed in the hope that it will be useful,\n"
92 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
93 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
94 "GNU General Public License for more details.\n\n");
96 "You should have received a copy of the GNU General Public License\n"
97 "along with this program; if not, write to the Free Software\n"
98 "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n");
102 BOOL STDCALL
AcquirePrivileges (VOID
)
104 /* TODO: implement it */
109 ProcessHasDescendants (
111 PSYSTEM_PROCESSES pInfo
116 if (NULL
== pInfo
) return 0;
119 if (ALREADY_PROCESSED
!= pInfo
->InheritedFromProcessId
)
121 if ((Pid
!= pInfo
->ProcessId
) && (Pid
== pInfo
->InheritedFromProcessId
))
126 (PBYTE
) pInfo
+= pInfo
->NextEntryDelta
;
128 } while (0 != pInfo
->NextEntryDelta
);
136 PSYSTEM_PROCESSES pInfo
,
141 *Module
= (pInfo
->ProcessName
.Length
? pInfo
->ProcessName
.Buffer
: L
"System process");
142 *Title
= L
""; /* TODO: check if the process has any window */
146 int STDCALL
PrintProcessInfoDepth (
147 PSYSTEM_PROCESSES pInfo
,
155 for (d
= 0; d
< Depth
; d
++) printf (" ");
156 GetProcessInfo (pInfo
, & Module
, & Title
);
161 pInfo
->InheritedFromProcessId
,
168 PrintProcessAndDescendants (
169 PSYSTEM_PROCESSES pInfo
,
170 PSYSTEM_PROCESSES pInfoBase
,
176 if (NULL
== pInfo
) return EXIT_FAILURE
;
177 /* Print current pInfo process */
178 PrintProcessInfoDepth (pInfo
, Depth
++);
179 pInfo
->InheritedFromProcessId
= ALREADY_PROCESSED
;
180 /* Save current process' PID */
181 Pid
= pInfo
->ProcessId
;
182 /* Scan and print possible children */
185 if (ALREADY_PROCESSED
!= pInfo
->InheritedFromProcessId
)
187 if (Pid
== pInfo
->InheritedFromProcessId
)
189 if (ProcessHasDescendants (Pid
, pInfoBase
))
191 PrintProcessAndDescendants (
199 PrintProcessInfoDepth (pInfo
, Depth
);
200 pInfo
->InheritedFromProcessId
= ALREADY_PROCESSED
;
204 (PBYTE
) pInfo
+= pInfo
->NextEntryDelta
;
206 } while (0 != pInfo
->NextEntryDelta
);
211 int STDCALL
PrintProcessList (BOOL DisplayTree
)
213 PSYSTEM_PROCESSES pInfo
= NULL
;
214 PSYSTEM_PROCESSES pInfoBase
= NULL
;
219 if (!NT_SUCCESS(PsaCaptureProcessesAndThreads(&pInfoBase
)))
222 pInfo
= PsaWalkFirstProcess(pInfoBase
);
226 if (FALSE
== DisplayTree
)
228 GetProcessInfo (pInfo
, & Module
, & Title
);
234 pInfo
->InheritedFromProcessId
239 if (ALREADY_PROCESSED
!= pInfo
->InheritedFromProcessId
)
241 PrintProcessAndDescendants (pInfo
, pInfoBase
, 0);
245 pInfo
= PsaWalkNextProcess(pInfo
);
248 PsaFreeCapture(pInfoBase
);
254 int STDCALL
PrintThreads (PSYSTEM_PROCESSES pInfo
)
257 NTSTATUS Status
= STATUS_SUCCESS
;
258 HANDLE hThread
= INVALID_HANDLE_VALUE
;
259 OBJECT_ATTRIBUTES Oa
= {0};
260 PVOID Win32StartAddress
= NULL
;
261 THREAD_BASIC_INFORMATION tInfo
= {0};
262 ULONG ReturnLength
= 0;
263 PSYSTEM_THREADS CurThread
;
265 if (NULL
== pInfo
) return EXIT_FAILURE
;
267 CurThread
= PsaWalkFirstThread(pInfo
);
269 wprintf (L
" NumberOfThreads: %d\n", pInfo
->ThreadCount
);
271 for (i
= 0; i
< pInfo
->ThreadCount
; i
++, CurThread
= PsaWalkNextThread(CurThread
))
273 Status
= NtOpenThread (
275 THREAD_QUERY_INFORMATION
,
277 & CurThread
->ClientId
279 if (!NT_SUCCESS(Status
))
284 Status
= NtQueryInformationThread (
286 ThreadBasicInformation
,
291 if (!NT_SUCCESS(Status
))
297 Status
= NtQueryInformationThread (
299 ThreadQuerySetWin32StartAddress
,
300 (PVOID
) & Win32StartAddress
,
301 sizeof Win32StartAddress
,
304 if (!NT_SUCCESS(Status
))
312 /* Now print the collected information */
313 wprintf (L
" %4d Win32StartAddr:0x%08x LastErr:0x%08x State:%s\n",
314 CurThread
->ClientId
.UniqueThread
,
316 0 /* FIXME: ((PTEB) tInfo.TebBaseAddress)->LastErrorValue */,
317 ThreadStateName
[CurThread
->State
]
323 int STDCALL
PrintModules (VOID
)
329 PSYSTEM_PROCESSES STDCALL
331 PSYSTEM_PROCESSES pInfoBase
,
335 if (NULL
== pInfoBase
) return NULL
;
337 pInfoBase
= PsaWalkFirstProcess(pInfoBase
);
341 if (Pid
== pInfoBase
->ProcessId
)
346 pInfoBase
= PsaWalkNextProcess(pInfoBase
);
352 int STDCALL
PrintProcess (char * PidStr
)
356 OBJECT_ATTRIBUTES Oa
= {0};
357 CLIENT_ID ClientId
= {0, 0};
360 ClientId
.UniqueProcess
= (PVOID
) atol (PidStr
);
362 if (FALSE
== AcquirePrivileges ())
367 Status
= NtOpenProcess (
369 PROCESS_QUERY_INFORMATION
,
373 if (NT_SUCCESS(Status
))
375 ULONG ReturnLength
= 0;
376 PROCESS_BASIC_INFORMATION PsBasic
;
378 PSYSTEM_PROCESSES pInfo
= NULL
;
379 PSYSTEM_PROCESSES pInfoBase
= NULL
;
380 LONG pInfoBaseLength
= 0;
384 Status
= NtQueryInformationProcess (
386 ProcessBasicInformation
,
391 if (!NT_SUCCESS(Status
))
395 Status
= NtQueryInformationProcess (
402 if (!NT_SUCCESS(Status
))
407 if (!NT_SUCCESS(PsaCaptureProcessesAndThreads (&pInfoBase
)))
410 pInfo
= GetProcessInfoPid (pInfoBase
, (DWORD
) ClientId
.UniqueProcess
);
411 if (NULL
== pInfo
) return EXIT_FAILURE
;
413 GetProcessInfo (pInfo
, & Module
, & Title
);
415 wprintf (L
"%4d %s\n", ClientId
.UniqueProcess
, Module
);
417 printf (" CWD: %s\n", ""); /* it won't appear if empty */
418 printf (" CmdLine: %s\n", ""); /* it won't appear if empty */
420 printf (" VirtualSize: %5ld kb PeakVirtualSize: %5ld kb\n",
421 ((LONG
) PsVm
.VirtualSize
/ 1024),
422 ((LONG
) PsVm
.PeakVirtualSize
/ 1024)
424 printf (" WorkingSetSize: %5ld kb PeakWorkingSetSize: %5ld kb\n",
425 ((LONG
) PsVm
.WorkingSetSize
/ 1024),
426 ((LONG
) PsVm
.PeakWorkingSetSize
/ 1024)
429 PrintThreads (pInfo
);
433 PsaFreeCapture(pInfoBase
);
443 int main (int argc
, char * argv
[])
447 if(1 == argc
) return PrintProcessList(FALSE
);
449 while((c
= getopt(argc
, argv
, "tl")) != -1)
453 case 't': return PrintProcessList(TRUE
);
454 case 'l': return PrintLicense();
455 default: return PrintSynopsys(EXIT_FAILURE
);
459 if(isdigit(argv
[optind
][0]))
460 return PrintProcess (argv
[1]);
462 return PrintSynopsys(EXIT_SUCCESS
);