2 Process Killer for NSIS script
6 Released under terms of IBM Open Source agreement for OpenAFS
16 char strProcessName[256];
18 typedef BOOL (CALLBACK *PROCENUMPROC)(DWORD, WORD, LPSTR, LPARAM);
27 BOOL WINAPI EnumProcs(PROCENUMPROC lpProc, LPARAM lParam);
29 BOOL WINAPI Enum16(DWORD dwThreadId, WORD hMod16, WORD hTask16,
30 PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined);
33 // The EnumProcs function takes a pointer to a callback function
34 // that will be called once per process with the process filename
37 // lpProc -- Address of callback routine.
39 // lParam -- A user-defined LPARAM value to be passed to
40 // the callback routine.
42 // Callback function definition:
43 // BOOL CALLBACK Proc(DWORD dw, WORD w, LPCSTR lpstr, LPARAM lParam);
45 BOOL WINAPI EnumProcs(PROCENUMPROC lpProc, LPARAM lParam) {
48 HINSTANCE hInstLib = NULL;
49 HINSTANCE hInstLib2 = NULL;
50 HANDLE hSnapShot = NULL;
51 LPDWORD lpdwPIDs = NULL;
52 PROCESSENTRY32 procentry;
59 char szFileName[MAX_PATH];
62 // ToolHelp Function Pointers.
63 HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD, DWORD);
64 BOOL (WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32);
65 BOOL (WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32);
67 // PSAPI Function Pointers.
68 BOOL (WINAPI *lpfEnumProcesses)(DWORD *, DWORD, DWORD *);
69 BOOL (WINAPI *lpfEnumProcessModules)(HANDLE, HMODULE *, DWORD,
71 DWORD (WINAPI *lpfGetModuleBaseName)(HANDLE, HMODULE, LPTSTR, DWORD);
73 // VDMDBG Function Pointers.
74 INT (WINAPI *lpfVDMEnumTaskWOWEx)(DWORD, TASKENUMPROCEX, LPARAM);
76 // Retrieve the OS version
77 osver.dwOSVersionInfoSize = sizeof(osver);
78 if (!GetVersionEx(&osver))
82 if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT
83 && osver.dwMajorVersion == 4) {
87 // Get the procedure addresses explicitly. We do
88 // this so we don't have to worry about modules
89 // failing to load under OSes other than Windows NT 4.0
90 // because references to PSAPI.DLL can't be resolved.
91 hInstLib = LoadLibraryA("PSAPI.DLL");
95 hInstLib2 = LoadLibraryA("VDMDBG.DLL");
96 if (hInstLib2 == NULL)
99 // Get procedure addresses.
100 lpfEnumProcesses = (BOOL (WINAPI *)(DWORD *, DWORD, DWORD*))
101 GetProcAddress(hInstLib, "EnumProcesses");
103 lpfEnumProcessModules = (BOOL (WINAPI *)(HANDLE, HMODULE *,
104 DWORD, LPDWORD)) GetProcAddress(hInstLib,
105 "EnumProcessModules");
107 lpfGetModuleBaseName = (DWORD (WINAPI *)(HANDLE, HMODULE,
108 LPTSTR, DWORD)) GetProcAddress(hInstLib,
109 "GetModuleBaseNameA");
111 lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX,
112 LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx");
114 if (lpfEnumProcesses == NULL
115 || lpfEnumProcessModules == NULL
116 || lpfGetModuleBaseName == NULL
117 || lpfVDMEnumTaskWOWEx == NULL)
121 // Call the PSAPI function EnumProcesses to get all of the
122 // ProcID's currently in the system.
124 // NOTE: In the documentation, the third parameter of
125 // EnumProcesses is named cbNeeded, which implies that you
126 // can call the function once to find out how much space to
127 // allocate for a buffer and again to fill the buffer.
128 // This is not the case. The cbNeeded parameter returns
129 // the number of PIDs returned, so if your buffer size is
130 // zero cbNeeded returns zero.
132 // NOTE: The "HeapAlloc" loop here ensures that we
133 // actually allocate a buffer large enough for all the
134 // PIDs in the system.
136 dwSize2 = 256 * sizeof(DWORD);
140 HeapFree(GetProcessHeap(), 0, lpdwPIDs);
144 lpdwPIDs = (LPDWORD) HeapAlloc(GetProcessHeap(), 0,
146 if (lpdwPIDs == NULL)
149 if (!lpfEnumProcesses(lpdwPIDs, dwSize2, &dwSize))
152 } while (dwSize == dwSize2);
154 // How many ProcID's did we get?
155 dwSize /= sizeof(DWORD);
157 // Loop through each ProcID.
158 for (dwIndex = 0; dwIndex < dwSize; dwIndex++) {
162 // Open the process (if we can... security does not
163 // permit every process in the system to be opened).
164 hProcess = OpenProcess(
165 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
166 FALSE, lpdwPIDs[dwIndex]);
167 if (hProcess != NULL) {
169 // Here we call EnumProcessModules to get only the
170 // first module in the process. This will be the
171 // EXE module for which we will retrieve the name.
172 if (lpfEnumProcessModules(hProcess, &hMod,
173 sizeof(hMod), &dwSize2)) {
175 // Get the module name
176 if (!lpfGetModuleBaseName(hProcess, hMod,
177 szFileName, sizeof(szFileName)))
180 CloseHandle(hProcess);
182 // Regardless of OpenProcess success or failure, we
183 // still call the enum func with the ProcID.
184 if (!lpProc(lpdwPIDs[dwIndex], 0, szFileName, lParam))
187 // Did we just bump into an NTVDM?
188 if (_stricmp(szFileName, "NTVDM.EXE") == 0) {
190 // Fill in some info for the 16-bit enum proc.
191 sInfo.dwPID = lpdwPIDs[dwIndex];
192 sInfo.lpProc = lpProc;
193 sInfo.lParam = (DWORD) lParam;
196 // Enum the 16-bit stuff.
197 lpfVDMEnumTaskWOWEx(lpdwPIDs[dwIndex],
198 (TASKENUMPROCEX) Enum16, (LPARAM) &sInfo);
200 // Did our main enum func say quit?
209 FreeLibrary(hInstLib);
212 FreeLibrary(hInstLib2);
215 HeapFree(GetProcessHeap(), 0, lpdwPIDs);
218 // If any OS other than Windows NT 4.0.
219 } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
220 || (osver.dwPlatformId == VER_PLATFORM_WIN32_NT
221 && osver.dwMajorVersion > 4)) {
225 hInstLib = LoadLibraryA("Kernel32.DLL");
226 if (hInstLib == NULL)
229 // If NT-based OS, load VDMDBG.DLL.
230 if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
231 hInstLib2 = LoadLibraryA("VDMDBG.DLL");
232 if (hInstLib2 == NULL)
236 // Get procedure addresses. We are linking to
237 // these functions explicitly, because a module using
238 // this code would fail to load under Windows NT,
239 // which does not have the Toolhelp32
240 // functions in KERNEL32.DLL.
241 lpfCreateToolhelp32Snapshot =
242 (HANDLE (WINAPI *)(DWORD,DWORD))
243 GetProcAddress(hInstLib, "CreateToolhelp32Snapshot");
246 (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32))
247 GetProcAddress(hInstLib, "Process32First");
250 (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32))
251 GetProcAddress(hInstLib, "Process32Next");
253 if (lpfProcess32Next == NULL
254 || lpfProcess32First == NULL
255 || lpfCreateToolhelp32Snapshot == NULL)
258 if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
259 lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX,
260 LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx");
261 if (lpfVDMEnumTaskWOWEx == NULL)
265 // Get a handle to a Toolhelp snapshot of all processes.
266 hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
267 if (hSnapShot == INVALID_HANDLE_VALUE) {
268 FreeLibrary(hInstLib);
272 // Get the first process' information.
273 procentry.dwSize = sizeof(PROCESSENTRY32);
274 bFlag = lpfProcess32First(hSnapShot, &procentry);
276 // While there are processes, keep looping.
279 // Call the enum func with the filename and ProcID.
280 if (lpProc(procentry.th32ProcessID, 0,
281 procentry.szExeFile, lParam)) {
283 // Did we just bump into an NTVDM?
284 if (_stricmp(procentry.szExeFile, "NTVDM.EXE") == 0) {
286 // Fill in some info for the 16-bit enum proc.
287 sInfo.dwPID = procentry.th32ProcessID;
288 sInfo.lpProc = lpProc;
289 sInfo.lParam = (DWORD) lParam;
292 // Enum the 16-bit stuff.
293 lpfVDMEnumTaskWOWEx(procentry.th32ProcessID,
294 (TASKENUMPROCEX) Enum16, (LPARAM) &sInfo);
296 // Did our main enum func say quit?
301 procentry.dwSize = sizeof(PROCESSENTRY32);
302 bFlag = lpfProcess32Next(hSnapShot, &procentry);
311 FreeLibrary(hInstLib);
314 FreeLibrary(hInstLib2);
321 FreeLibrary(hInstLib);
327 BOOL WINAPI Enum16(DWORD dwThreadId, WORD hMod16, WORD hTask16,
328 PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined) {
332 EnumInfoStruct *psInfo = (EnumInfoStruct *)lpUserDefined;
334 bRet = psInfo->lpProc(psInfo->dwPID, hTask16, pszFileName,
344 BOOL CALLBACK MyProcessEnumerator(DWORD dwPID, WORD wTask,
345 LPCSTR szProcess, LPARAM lParam) {
348 printf("%5u %s\n", dwPID, szProcess);
350 printf(" %5u %s\n", wTask, szProcess);*/
352 if(stricmp(szProcess,strProcessName)==0)
354 HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
356 TerminateProcess(hProcess,0);
357 CloseHandle(hProcess);
364 void main(int argc, char *argv[])
368 printf("Please specify the process name to kill\n");
373 if(strlen((argv[1]))<255)
374 strcpy(strProcessName,(argv[1]));
378 EnumProcs((PROCENUMPROC) MyProcessEnumerator, 0);