Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
6.6 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name:
  4. kill.c
  5. Abstract:
  6. This module implements a task killer application.
  7. Author:
  8. Wesley Witt (wesw) 20-May-1994
  9. Environment:
  10. User Mode
  11. --*/
  12. #include "pch.h"
  13. #pragma hdrstop
  14. BOOL ForceKill;
  15. struct _arg {
  16. DWORD pid;
  17. CHAR *pname;
  18. } Arguments[ 64 ];
  19. DWORD NumberOfArguments;
  20. TASK_LIST tlist[MAX_TASKS];
  21. VOID GetCommandLineArgs(VOID);
  22. VOID Usage(VOID);
  23. int __cdecl
  24. main(
  25. int argc,
  26. char *argv[]
  27. )
  28. {
  29. DWORD i, j;
  30. DWORD numTasks;
  31. TASK_LIST_ENUM te;
  32. int rval = 0;
  33. char tname[PROCESS_SIZE];
  34. LPSTR p;
  35. DWORD ThisPid;
  36. GetCommandLineArgs();
  37. if (NumberOfArguments == 0) {
  38. printf( "missing pid or task name\n" );
  39. return 1;
  40. }
  41. //
  42. // lets be god
  43. //
  44. EnableDebugPriv();
  45. //
  46. // get the task list for the system
  47. //
  48. numTasks = GetTaskList( tlist, MAX_TASKS );
  49. //
  50. // enumerate all windows and try to get the window
  51. // titles for each task
  52. //
  53. te.tlist = tlist;
  54. te.numtasks = numTasks;
  55. GetWindowTitles( &te );
  56. ThisPid = GetCurrentProcessId();
  57. for (i=0; i<numTasks; i++) {
  58. //
  59. // this prevents the user from killing KILL.EXE and
  60. // it's parent cmd window too
  61. //
  62. if (ThisPid == tlist[i].dwProcessId) {
  63. continue;
  64. }
  65. if (MatchPattern( tlist[i].WindowTitle, "*KILL*" )) {
  66. continue;
  67. }
  68. tname[0] = 0;
  69. strcpy( tname, tlist[i].ProcessName );
  70. p = strchr( tname, '.' );
  71. if (p) {
  72. p[0] = '\0';
  73. }
  74. for (j=0; j<NumberOfArguments; j++) {
  75. if (Arguments[j].pname) {
  76. if (MatchPattern( tname, Arguments[j].pname )) {
  77. tlist[i].flags = TRUE;
  78. } else if (MatchPattern( tlist[i].ProcessName, Arguments[j].pname )) {
  79. tlist[i].flags = TRUE;
  80. } else if (MatchPattern( tlist[i].WindowTitle, Arguments[j].pname )) {
  81. tlist[i].flags = TRUE;
  82. }
  83. } else if (Arguments[j].pid) {
  84. if (tlist[i].dwProcessId == Arguments[j].pid) {
  85. tlist[i].flags = TRUE;
  86. }
  87. }
  88. }
  89. }
  90. for (i=0; i<numTasks; i++) {
  91. if (tlist[i].flags) {
  92. if (KillProcess( &tlist[i], ForceKill )) {
  93. printf( "process %s (%d) - '%s' killed\n",
  94. tlist[i].ProcessName,
  95. tlist[i].dwProcessId,
  96. tlist[i].hwnd ? tlist[i].WindowTitle : ""
  97. );
  98. } else {
  99. printf( "process %s (%d) - '%s' could not be killed\n",
  100. tlist[i].ProcessName,
  101. tlist[i].dwProcessId,
  102. tlist[i].hwnd ? tlist[i].WindowTitle : ""
  103. );
  104. rval = 1;
  105. }
  106. }
  107. }
  108. return rval;
  109. }
  110. VOID
  111. GetCommandLineArgs(
  112. VOID
  113. )
  114. {
  115. char *lpstrCmd;
  116. UCHAR ch;
  117. DWORD pid;
  118. char pname[MAX_PATH];
  119. char *p;
  120. lpstrCmd = GetCommandLine();
  121. // skip over program name
  122. do {
  123. ch = *lpstrCmd++;
  124. }
  125. while (ch != ' ' && ch != '\t' && ch != '\0');
  126. NumberOfArguments = 0;
  127. while (ch != '\0') {
  128. // skip over any following white space
  129. while (ch != '\0' && isspace(ch)) {
  130. ch = *lpstrCmd++;
  131. }
  132. if (ch == '\0') {
  133. break;
  134. }
  135. // process each switch character '-' as encountered
  136. while (ch == '-' || ch == '/') {
  137. ch = (UCHAR)tolower(*lpstrCmd++);
  138. // process multiple switch characters as needed
  139. do {
  140. switch (ch) {
  141. case 'f':
  142. ForceKill = TRUE;
  143. ch = *lpstrCmd++;
  144. break;
  145. case '?':
  146. Usage();
  147. ch = *lpstrCmd++;
  148. break;
  149. default:
  150. return;
  151. }
  152. } while (ch != ' ' && ch != '\t' && ch != '\0');
  153. while (ch == ' ' || ch == '\t') {
  154. ch = *lpstrCmd++;
  155. }
  156. }
  157. if (isdigit(ch)) {
  158. pid = 0;
  159. while (isdigit(ch)) {
  160. pid = pid * 10 + ch - '0';
  161. ch = *lpstrCmd++;
  162. }
  163. Arguments[NumberOfArguments].pid = pid;
  164. Arguments[NumberOfArguments].pname = NULL;
  165. NumberOfArguments += 1;
  166. }
  167. else
  168. if (ch != '\0') {
  169. p = pname;
  170. do {
  171. *p++ = ch;
  172. ch = *lpstrCmd++;
  173. } while (ch != ' ' && ch != '\t' && ch != '\0');
  174. *p = '\0';
  175. _strupr( pname );
  176. Arguments[NumberOfArguments].pid = 0;
  177. Arguments[NumberOfArguments].pname = malloc(strlen(pname)+1);
  178. strcpy(Arguments[NumberOfArguments].pname, pname);
  179. NumberOfArguments += 1;
  180. }
  181. }
  182. return;
  183. }
  184. VOID
  185. Usage(
  186. VOID
  187. )
  188. /*++
  189. Routine Description:
  190. Prints usage text for this tool.
  191. Arguments:
  192. None.
  193. Return Value:
  194. None.
  195. --*/
  196. {
  197. fprintf( stderr, "Microsoft (R) Windows NT (TM) Version 3.5 KILL\n" );
  198. fprintf( stderr, "Copyright (C) 1994-1998 Microsoft Corp. All rights reserved\n\n" );
  199. fprintf( stderr, "usage: KILL [options] <<pid> | <pattern>>*\n\n" );
  200. fprintf( stderr, " [options]:\n" );
  201. fprintf( stderr, " -f Force process kill\n\n" );
  202. fprintf( stderr, " <pid>\n" );
  203. fprintf( stderr, " This is the process id for the task\n" );
  204. fprintf( stderr, " to be killed. Use TLIST to get a\n" );
  205. fprintf( stderr, " valid pid\n\n" );
  206. fprintf( stderr, " <pattern>\n" );
  207. fprintf( stderr, " The pattern can be a complete task\n" );
  208. fprintf( stderr, " name or a regular expression pattern\n" );
  209. fprintf( stderr, " to use as a match. Kill matches the\n" );
  210. fprintf( stderr, " supplied pattern against the task names\n" );
  211. fprintf( stderr, " and the window titles.\n" );
  212. ExitProcess(0);
  213. }