267 lines
6.3 KiB
C
267 lines
6.3 KiB
C
/*++
|
|
|
|
Copyright (c) 1994-1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
kill.c
|
|
|
|
Abstract:
|
|
|
|
This module implements a task killer application.
|
|
|
|
Author:
|
|
|
|
Wesley Witt (wesw) 20-May-1994
|
|
|
|
Environment:
|
|
|
|
User Mode
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
BOOL ForceKill;
|
|
|
|
struct _arg {
|
|
DWORD pid;
|
|
CHAR *pname;
|
|
} Arguments[ 64 ];
|
|
DWORD NumberOfArguments;
|
|
|
|
TASK_LIST tlist[MAX_TASKS];
|
|
|
|
|
|
VOID GetCommandLineArgs(VOID);
|
|
VOID Usage(VOID);
|
|
|
|
|
|
|
|
int __cdecl
|
|
main(
|
|
int argc,
|
|
char *argv[]
|
|
)
|
|
{
|
|
DWORD i, j;
|
|
DWORD numTasks;
|
|
TASK_LIST_ENUM te;
|
|
int rval = 0;
|
|
char tname[PROCESS_SIZE];
|
|
LPSTR p;
|
|
DWORD ThisPid;
|
|
|
|
|
|
GetCommandLineArgs();
|
|
|
|
if (NumberOfArguments == 0) {
|
|
printf( "missing pid or task name\n" );
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// lets be god
|
|
//
|
|
EnableDebugPriv();
|
|
|
|
//
|
|
// get the task list for the system
|
|
//
|
|
numTasks = GetTaskList( tlist, MAX_TASKS );
|
|
|
|
//
|
|
// enumerate all windows and try to get the window
|
|
// titles for each task
|
|
//
|
|
te.tlist = tlist;
|
|
te.numtasks = numTasks;
|
|
GetWindowTitles( &te );
|
|
|
|
ThisPid = GetCurrentProcessId();
|
|
|
|
for (i=0; i<numTasks; i++) {
|
|
//
|
|
// this prevents the user from killing KILL.EXE and
|
|
// it's parent cmd window too
|
|
//
|
|
if (ThisPid == tlist[i].dwProcessId) {
|
|
continue;
|
|
}
|
|
if (MatchPattern( tlist[i].WindowTitle, "*KILL*" )) {
|
|
continue;
|
|
}
|
|
|
|
tname[0] = 0;
|
|
strcpy( tname, tlist[i].ProcessName );
|
|
p = strchr( tname, '.' );
|
|
if (p) {
|
|
p[0] = '\0';
|
|
}
|
|
|
|
for (j=0; j<NumberOfArguments; j++) {
|
|
if (Arguments[j].pname) {
|
|
if (MatchPattern( tname, Arguments[j].pname )) {
|
|
tlist[i].flags = TRUE;
|
|
} else if (MatchPattern( tlist[i].ProcessName, Arguments[j].pname )) {
|
|
tlist[i].flags = TRUE;
|
|
} else if (MatchPattern( tlist[i].WindowTitle, Arguments[j].pname )) {
|
|
tlist[i].flags = TRUE;
|
|
}
|
|
} else if (Arguments[j].pid) {
|
|
if (tlist[i].dwProcessId == Arguments[j].pid) {
|
|
tlist[i].flags = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i=0; i<numTasks; i++) {
|
|
if (tlist[i].flags) {
|
|
if (KillProcess( &tlist[i], ForceKill )) {
|
|
printf( "process %s (%d) - '%s' killed\n",
|
|
tlist[i].ProcessName,
|
|
tlist[i].dwProcessId,
|
|
tlist[i].hwnd ? tlist[i].WindowTitle : ""
|
|
);
|
|
} else {
|
|
printf( "process %s (%d) - '%s' could not be killed\n",
|
|
tlist[i].ProcessName,
|
|
tlist[i].dwProcessId,
|
|
tlist[i].hwnd ? tlist[i].WindowTitle : ""
|
|
);
|
|
rval = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return rval;
|
|
}
|
|
|
|
VOID
|
|
GetCommandLineArgs(
|
|
VOID
|
|
)
|
|
{
|
|
char *lpstrCmd;
|
|
UCHAR ch;
|
|
DWORD pid;
|
|
char pname[MAX_PATH];
|
|
char *p;
|
|
|
|
lpstrCmd = GetCommandLine();
|
|
|
|
// skip over program name
|
|
do {
|
|
ch = *lpstrCmd++;
|
|
}
|
|
while (ch != ' ' && ch != '\t' && ch != '\0');
|
|
|
|
NumberOfArguments = 0;
|
|
while (ch != '\0') {
|
|
// skip over any following white space
|
|
while (ch != '\0' && isspace(ch)) {
|
|
ch = *lpstrCmd++;
|
|
}
|
|
if (ch == '\0') {
|
|
break;
|
|
}
|
|
|
|
// process each switch character '-' as encountered
|
|
|
|
while (ch == '-' || ch == '/') {
|
|
ch = (UCHAR)tolower(*lpstrCmd++);
|
|
// process multiple switch characters as needed
|
|
do {
|
|
switch (ch) {
|
|
case 'f':
|
|
ForceKill = TRUE;
|
|
ch = *lpstrCmd++;
|
|
break;
|
|
|
|
case '?':
|
|
Usage();
|
|
ch = *lpstrCmd++;
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
} while (ch != ' ' && ch != '\t' && ch != '\0');
|
|
|
|
while (ch == ' ' || ch == '\t') {
|
|
ch = *lpstrCmd++;
|
|
}
|
|
}
|
|
|
|
if (isdigit(ch)) {
|
|
pid = 0;
|
|
while (isdigit(ch)) {
|
|
pid = pid * 10 + ch - '0';
|
|
ch = *lpstrCmd++;
|
|
}
|
|
Arguments[NumberOfArguments].pid = pid;
|
|
Arguments[NumberOfArguments].pname = NULL;
|
|
NumberOfArguments += 1;
|
|
}
|
|
else
|
|
if (ch != '\0') {
|
|
p = pname;
|
|
do {
|
|
*p++ = ch;
|
|
ch = *lpstrCmd++;
|
|
} while (ch != ' ' && ch != '\t' && ch != '\0');
|
|
*p = '\0';
|
|
_strupr( pname );
|
|
Arguments[NumberOfArguments].pid = 0;
|
|
Arguments[NumberOfArguments].pname = malloc(strlen(pname)+1);
|
|
strcpy(Arguments[NumberOfArguments].pname, pname);
|
|
NumberOfArguments += 1;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
Usage(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Prints usage text for this tool.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
fprintf( stderr, "Microsoft (R) Windows NT (TM) Version 3.5 KILL\n" );
|
|
fprintf( stderr, "Copyright (C) 1994-1998 Microsoft Corp. All rights reserved\n\n" );
|
|
fprintf( stderr, "usage: KILL [options] <<pid> | <pattern>>*\n\n" );
|
|
fprintf( stderr, " [options]:\n" );
|
|
fprintf( stderr, " -f Force process kill\n\n" );
|
|
fprintf( stderr, " <pid>\n" );
|
|
fprintf( stderr, " This is the process id for the task\n" );
|
|
fprintf( stderr, " to be killed. Use TLIST to get a\n" );
|
|
fprintf( stderr, " valid pid\n\n" );
|
|
fprintf( stderr, " <pattern>\n" );
|
|
fprintf( stderr, " The pattern can be a complete task\n" );
|
|
fprintf( stderr, " name or a regular expression pattern\n" );
|
|
fprintf( stderr, " to use as a match. Kill matches the\n" );
|
|
fprintf( stderr, " supplied pattern against the task names\n" );
|
|
fprintf( stderr, " and the window titles.\n" );
|
|
ExitProcess(0);
|
|
}
|