source: trunk/dll/killproc.c@ 1224

Last change on this file since 1224 was 1224, checked in by John Small, 17 years ago

Ticket 187: Moved typedef's and some #define's from fm3dll.h

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.0 KB
Line 
1
2/***********************************************************************
3
4 $Id: killproc.c 1224 2008-09-13 23:11:41Z jbs $
5
6 Kill a process
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2005, 2006 Steven H. Levine
10
11 24 May 05 SHL Rework Win_Error usage
12 14 Jul 06 SHL Use Runtime_Error
13 29 Jul 06 SHL Use xfgets
14 03 Nov 06 SHL Renames
15 03 Nov 06 SHL Count thread usage
16 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
17 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
18 02 Sep 07 GKY Replaced DosQProcStatus with DosQuerySysState to fix trap in thunk code
19 02 Sep 07 SHL Expand FillKillListThread2 stack to avoid exception in __TNK
20 16 JUL 08 GKY Use TMP directory for temp files
21
22***********************************************************************/
23
24#include <stdlib.h>
25#include <string.h>
26#include <ctype.h>
27#include <process.h>
28#include <limits.h>
29
30#define INCL_DOS
31#define INCL_DOSERRORS
32#define INCL_WIN
33#define INCL_LONGLONG // dircnrs.h
34
35#include "fm3dll.h"
36#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
37#include "init.h" // Data declaration(s)
38#include "notebook.h" // Data declaration(s)
39#include "mainwnd.h" // Data declaration(s)
40#include "fm3dlg.h"
41#include "fm3str.h"
42#include "procstat.h"
43#include "errutil.h" // Dos_Error...
44#include "strutil.h" // GetPString
45#include "pathutil.h" // BldFullPathName
46#include "killproc.h"
47#include "systemf.h" // ShowSession
48#include "common.h" // DecrThreadUsage, IncrThreadUsage
49#include "notify.h" // Notify
50#include "copyf.h" // unlinkf
51#include "wrappers.h" // xfgets
52#include "stristr.h" // stristr
53#include "misc.h" // PostMsg
54#include "fortify.h"
55
56// Data definitions
57#pragma data_seg(DATA2)
58
59static PSZ pszSrcFile = __FILE__;
60
61#pragma data_seg(GLOBAL1)
62BOOL fUseQProcStat;
63BOOL fUseQSysState;
64PID mypid;
65
66CHAR *GetDosPgmName(PID pid, CHAR * string)
67{
68 HSWITCH hs;
69 SWCNTRL swctl;
70 PCH pch;
71
72 *string = 0;
73 hs = WinQuerySwitchHandle(0, pid);
74 if (hs) {
75 WinQuerySwitchEntry(hs, &swctl);
76 pch = swctl.szSwtitle;
77 while (*pch) {
78 if (*pch < 0x10)
79 if (pch != swctl.szSwtitle && *(pch - 1) == 0x20)
80 memmove(pch, pch + 1, strlen(pch));
81 else {
82 *pch = 0x20;
83 pch++;
84 }
85 else
86 pch++;
87 }
88 strcpy(string, swctl.szSwtitle);
89 }
90 if (!*string)
91 strcpy(string, GetPString(IDS_UNKNOWNDOSPROCTEXT));
92 return string;
93}
94
95static VOID FillKillListThread2(VOID * arg)
96{
97 HWND hwnd = *(HWND *) arg;
98 CHAR s[1036];
99 HAB thab;
100 HMQ thmq;
101 INT rc;
102 PROCESSINFO *ppi;
103 BUFFHEADER *pbh;
104 MODINFO *pmi;
105
106# ifdef FORTIFY
107 Fortify_EnterScope();
108# endif
109 thab = WinInitialize(0);
110 thmq = WinCreateMsgQueue(thab, 0);
111 WinCancelShutdown(thmq, TRUE);
112 IncrThreadUsage();
113
114 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
115 rc = DosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
116 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
117 if (rc)
118 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
119 GetPString(IDS_OUTOFMEMORY));
120 else {
121 rc = DosQProcStatus((ULONG *)pbh, USHRT_MAX);
122 if (!rc) {
123 ppi = pbh->ppi;
124 while (ppi->ulEndIndicator != PROCESS_END_INDICATOR) {
125 if (ppi->pid != mypid) {
126 pmi = pbh->pmi;
127 while (pmi && ppi->hModRef != pmi->hMod)
128 pmi = pmi->pNext;
129 if (pmi) {
130 sprintf(s, "%04x ", ppi->pid);
131 if (!stricmp(pmi->szModName, "SYSINIT"))
132 GetDosPgmName(ppi->pid, s + strlen(s));
133 else {
134 if (*pmi->szModName)
135 strcat(s, pmi->szModName);
136 else
137 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
138 }
139 if (WinIsWindow(thab, hwnd)) {
140 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_INSERTITEM,
141 MPFROM2SHORT(LIT_SORTASCENDING, 0),
142 MPFROMP(s));
143 }
144 else
145 break;
146 }
147 }
148 ppi = (PPROCESSINFO) (ppi->ptiFirst + ppi->usThreadCount);
149 } // while
150 }
151 DosFreeMem(pbh);
152 }
153
154 if (WinIsWindow(thab, hwnd))
155 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
156 WinDestroyMsgQueue(thmq);
157 DecrThreadUsage();
158 WinTerminate(thab);
159# ifdef FORTIFY
160 Fortify_LeaveScope();
161# endif
162}
163
164static VOID FillKillListThread3(VOID * arg)
165{
166 HWND hwnd = *(HWND *) arg;
167 CHAR s[1036];
168 HAB thab;
169 HMQ thmq;
170 INT rc;
171 QSPREC *ppi;
172 QSPTRREC *pbh;
173 QSLREC *pmi;
174
175# ifdef FORTIFY
176 Fortify_EnterScope();
177# endif
178 thab = WinInitialize(0);
179 thmq = WinCreateMsgQueue(thab, 0);
180 WinCancelShutdown(thmq, TRUE);
181 IncrThreadUsage();
182
183 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
184 rc = DosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
185 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
186 if (rc)
187 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
188 GetPString(IDS_OUTOFMEMORY));
189 else {
190 rc = DosQuerySysState(QS_PROCESS | QS_MTE, 0, 0, 0, pbh, USHRT_MAX);
191 if (!rc) {
192 ppi = pbh->pProcRec;
193 while (ppi->RecType == 1) {
194 if (ppi->pid != mypid) {
195 pmi = pbh->pLibRec;
196 while (pmi && ppi->hMte != pmi->hmte)
197 pmi = pmi->pNextRec;
198 if (pmi) {
199 sprintf(s, "%04x ", ppi->pid);
200 if (!stricmp((CHAR *) pmi->pName, "SYSINIT"))
201 GetDosPgmName(ppi->pid, s + strlen(s));
202 else {
203 if (*pmi->pName)
204 strcat(s, (CHAR *) pmi->pName);
205 else
206 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
207 }
208 if (WinIsWindow(thab, hwnd)) {
209 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_INSERTITEM,
210 MPFROM2SHORT(LIT_SORTASCENDING, 0),
211 MPFROMP(s));
212 }
213 else
214 break;
215 }
216 }
217 ppi = (QSPREC *) (ppi->pThrdRec + ppi->cTCB); // 22 Jun 08 SHL fixme to know why this looks odd
218 } // while
219 }
220 DosFreeMem(pbh);
221 }
222
223 if (WinIsWindow(thab, hwnd))
224 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
225 WinDestroyMsgQueue(thmq);
226 DecrThreadUsage();
227 WinTerminate(thab);
228# ifdef FORTIFY
229 Fortify_LeaveScope();
230# endif
231}
232
233static VOID FillKillListThread(VOID * arg)
234{
235 HWND hwnd = *(HWND *) arg;
236 CHAR s[1036], progname[1027], *p;
237 HAB thab;
238 HMQ thmq;
239 FILE *fp;
240 BOOL foundstart = FALSE;
241 INT rc;
242 CHAR *startstring = "Process and Thread Information";
243 CHAR *endstring = "System Semaphore Information";
244 PID pid;
245 HFILE oldstdout, newstdout;
246
247 DosError(FERR_DISABLEHARDERR);
248
249# ifdef FORTIFY
250 Fortify_EnterScope();
251# endif
252 thab = WinInitialize(0);
253 thmq = WinCreateMsgQueue(thab, 0);
254 WinCancelShutdown(thmq, TRUE);
255 IncrThreadUsage();
256
257 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
258 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
259 unlinkf("%s", s);
260 fp = fopen(s, "w");
261 if (!fp) {
262 Win_Error(NULLHANDLE, HWND_DESKTOP, __FILE__, __LINE__,
263 GetPString(IDS_REDIRECTERRORTEXT));
264 goto Abort;
265 }
266 else {
267 newstdout = -1;
268 rc = DosDupHandle(fileno(stdout), &newstdout);
269 if (rc)
270 Dos_Error(MB_CANCEL, rc, hwnd, __FILE__, __LINE__, "DosDupHandle");
271 oldstdout = fileno(stdout);
272 DosDupHandle(fileno(fp), &oldstdout);
273 rc = runemf2(SEPARATE | INVISIBLE | FULLSCREEN | BACKGROUND | WAIT,
274 hwnd, pszSrcFile, __LINE__, NULL, NULL,
275 "%s", "PSTAT.EXE /C");
276 oldstdout = fileno(stdout);
277 DosDupHandle(newstdout, &oldstdout);
278 DosClose(newstdout);
279 fclose(fp);
280 // fixme to be gone?
281 if (rc == -1) {
282 saymsg(MB_CANCEL,
283 hwnd,
284 GetPString(IDS_ARGHTEXT), GetPString(IDS_CANTRUNPSTATTEXT));
285 goto Abort;
286 }
287 }
288 fp = fopen(s, "r");
289 if (fp) {
290 while (!feof(fp)) {
291 strset(s, 0);
292 if (!xfgets(s, 1025, fp, pszSrcFile, __LINE__))
293 break;
294 if (!foundstart) {
295 if (*s == ' ' && strstr(s, startstring))
296 foundstart = TRUE;
297 }
298 else {
299 if (*s == ' ' && strstr(s, endstring))
300 break;
301 if (*s == ' ' && s[5] == ' ' && isxdigit(s[1]) &&
302 isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4])) {
303 p = &s[1];
304 pid = strtol(&s[1], &p, 16);
305 if (pid && pid != mypid) {
306 strcpy(progname, &s[30]);
307 p = strchr(progname, ' ');
308 if (p)
309 *p = 0;
310 if (!stristr(progname, "\\PSTAT.EXE")) {
311 sprintf(s, "%04x %s", pid, progname);
312 WinSendDlgItemMsg(hwnd,
313 KILL_LISTBOX,
314 LM_INSERTITEM,
315 MPFROM2SHORT(LIT_SORTASCENDING, 0),
316 MPFROMP(s));
317 }
318 }
319 }
320 }
321 }
322 fclose(fp);
323 }
324Abort:
325 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
326 DosForceDelete(s);
327 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
328 WinDestroyMsgQueue(thmq);
329 DecrThreadUsage();
330 WinTerminate(thab);
331# ifdef FORTIFY
332 Fortify_LeaveScope();
333# endif
334}
335
336MRESULT EXPENTRY KillDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
337{
338 SHORT sSelect;
339 PID pid;
340 static BOOL listdone;
341 static HPOINTER hptrIcon = (HPOINTER) 0;
342
343 switch (msg) {
344 case WM_INITDLG:
345 hptrIcon = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, KILL_FRAME);
346 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptrIcon), MPVOID);
347 WinCheckButton(hwnd, KILL_CHECKBOX, fUseQProcStat);
348 WinCheckButton(hwnd, KILL2_CHECKBOX, fUseQSysState);
349 if (WinQueryButtonCheckstate(hwnd, KILL2_CHECKBOX)) {
350 WinCheckButton(hwnd, KILL_CHECKBOX, FALSE);
351 WinEnableWindow(WinWindowFromID(hwnd, KILL_CHECKBOX), FALSE);
352 }
353 if (WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX)) {
354 WinCheckButton(hwnd, KILL2_CHECKBOX, FALSE);
355 WinEnableWindow(WinWindowFromID(hwnd, KILL2_CHECKBOX), FALSE);
356 }
357 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
358 break;
359
360 case UM_CONTAINER_FILLED:
361 listdone = TRUE;
362 if ((SHORT) WinSendDlgItemMsg(hwnd,
363 KILL_LISTBOX,
364 LM_QUERYITEMCOUNT, MPVOID, MPVOID) == 0) {
365 if (!fUseQProcStat)
366 saymsg(MB_CANCEL,
367 hwnd,
368 GetPString(IDS_ICHOKEDTEXT), GetPString(IDS_ISPSTATTHERETEXT));
369 else
370 saymsg(MB_CANCEL,
371 hwnd,
372 GetPString(IDS_ICHOKEDTEXT),
373 GetPString(IDS_DOSQPROCSTATFAILEDTEXT));
374 }
375 return 0;
376
377 case WM_CONTROL:
378 switch (SHORT1FROMMP(mp1)) {
379 case KILL_CHECKBOX:
380 fUseQProcStat = WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX);
381 PrfWriteProfileData(fmprof,
382 FM3Str,
383 "UseQProcStat", &fUseQProcStat, sizeof(BOOL));
384 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
385 if (WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX)) {
386 WinCheckButton(hwnd, KILL2_CHECKBOX, FALSE);
387 WinEnableWindow(WinWindowFromID(hwnd, KILL2_CHECKBOX), FALSE);
388 }
389 else
390 WinEnableWindow(WinWindowFromID(hwnd, KILL2_CHECKBOX), TRUE);
391 break;
392 case KILL2_CHECKBOX:
393 fUseQSysState = WinQueryButtonCheckstate(hwnd, KILL2_CHECKBOX);
394 PrfWriteProfileData(fmprof,
395 FM3Str,
396 "UseQSysState", &fUseQSysState, sizeof(BOOL));
397 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
398 if (WinQueryButtonCheckstate(hwnd, KILL2_CHECKBOX)) {
399 WinCheckButton(hwnd, KILL_CHECKBOX, FALSE);
400 WinEnableWindow(WinWindowFromID(hwnd, KILL_CHECKBOX), FALSE);
401 }
402 else
403 WinEnableWindow(WinWindowFromID(hwnd, KILL_CHECKBOX), TRUE);
404 break;
405
406 case KILL_LISTBOX:
407 switch (SHORT2FROMMP(mp2)) {
408 case LN_ENTER:
409 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPFROMSHORT(TRUE), MPVOID);
410 break;
411 }
412 break;
413
414 default:
415 break;
416 }
417 return 0;
418
419 case WM_ADJUSTWINDOWPOS:
420 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
421 break;
422
423 case UM_STRETCH:
424 {
425 SWP swpC, swp, swpH;
426
427 WinQueryWindowPos(hwnd, &swp);
428 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
429 WinQueryWindowPos(WinWindowFromID(hwnd, KILL_LISTBOX), &swpC);
430 WinQueryWindowPos(WinWindowFromID(hwnd, KILL_HDR), &swpH);
431 WinSetWindowPos(WinWindowFromID(hwnd, KILL_LISTBOX), HWND_TOP,
432 SysVal(SV_CXSIZEBORDER),
433 swpC.y,
434 swp.cx - (SysVal(SV_CXSIZEBORDER) * 2),
435 ((swp.cy - swpC.y) - (SysVal(SV_CYTITLEBAR) +
436 SysVal(SV_CYSIZEBORDER)) -
437 (swpH.cy + 8)), SWP_MOVE | SWP_SIZE);
438 WinSetWindowPos(WinWindowFromID(hwnd, KILL_HDR), HWND_TOP,
439 SysVal(SV_CXSIZEBORDER) + 4,
440 swpC.y + ((swp.cy - swpC.y) -
441 (SysVal(SV_CYTITLEBAR) +
442 SysVal(SV_CYSIZEBORDER)) -
443 (swpH.cy + 4)), swpH.cx, swpH.cy, SWP_MOVE);
444 }
445 }
446 return 0;
447
448 case WM_COMMAND:
449 switch (SHORT1FROMMP(mp1)) {
450 case KILL_RESCAN:
451 listdone = FALSE;
452 if (fUseQProcStat) {
453 if (_beginthread(FillKillListThread2,
454 NULL, 65536 + 8192, (PVOID)&hwnd) != -1)
455 DosSleep(100); // 05 Aug 07 GKY 250
456 else
457 WinDismissDlg(hwnd, 0);
458 }
459 else if (fUseQSysState)
460 if (_beginthread(FillKillListThread3,
461 NULL, 65536, (PVOID) & hwnd) != -1)
462 DosSleep(100);//05 Aug 07 GKY 250
463 else
464 WinDismissDlg(hwnd, 0);
465 else {
466 if (_beginthread(FillKillListThread,
467 NULL, 65536, (PVOID) & hwnd) != -1)
468 DosSleep(100); // 05 Aug 07 GKY 250
469 else
470 WinDismissDlg(hwnd, 0);
471 }
472 break;
473
474 case KILL_SHOW:
475 case DID_OK:
476 sSelect = (USHORT) WinSendDlgItemMsg(hwnd,
477 KILL_LISTBOX,
478 LM_QUERYSELECTION,
479 MPFROMSHORT(LIT_FIRST), MPVOID);
480 if (sSelect >= 0) {
481
482 CHAR s[31], *p;
483 APIRET error;
484
485 *s = 0;
486 WinSendDlgItemMsg(hwnd,
487 KILL_LISTBOX,
488 LM_QUERYITEMTEXT,
489 MPFROM2SHORT(sSelect, 30), MPFROMP(s));
490 if (*s) {
491 p = s;
492 pid = strtol(s, &p, 16);
493 if (pid) {
494 if (SHORT1FROMMP(mp1) == DID_OK) {
495 error = DosKillProcess(DKP_PROCESS, pid);
496 if (error && error != ERROR_INVALID_PROCID) {
497 Dos_Error(MB_CANCEL,
498 error,
499 hwnd,
500 __FILE__,
501 __LINE__, GetPString(IDS_DOSKILLFAILEDTEXT));
502 }
503 else
504 WinSendDlgItemMsg(hwnd,
505 KILL_LISTBOX,
506 LM_DELETEITEM,
507 MPFROM2SHORT(sSelect, 0), MPVOID);
508 }
509 else if (!ShowSession(hwnd, pid))
510 Notify(GetPString(IDS_SORRYCANTSHOWTEXT));
511 }
512 }
513 }
514 break;
515
516 case DID_CANCEL:
517 if (!listdone)
518 Runtime_Error(pszSrcFile, __LINE__, "busy");
519 else
520 WinDismissDlg(hwnd, 0);
521 break;
522
523 case IDM_HELP:
524 saymsg(MB_ENTER | MB_ICONASTERISK,
525 hwnd,
526 GetPString(IDS_KILLPROCHELPTITLETEXT),
527 GetPString(IDS_KILLPROCHELPTEXT));
528 break;
529 }
530 return 0;
531
532 case WM_CLOSE:
533 if (!listdone) {
534 Runtime_Error(pszSrcFile, __LINE__, "busy");
535 return 0;
536 }
537 break;
538
539 case WM_DESTROY:
540 if (hptrIcon)
541 WinDestroyPointer(hptrIcon);
542 hptrIcon = (HPOINTER) 0;
543 break;
544 }
545 return WinDefDlgProc(hwnd, msg, mp1, mp2);
546}
547
548#pragma alloc_text(KILLPROC,FillKillListThread,FillKillListThread2,GetDosPgmName,KillDlgProc)
549#pragma alloc_text(KILLPROC,FillKillListThread3)
Note: See TracBrowser for help on using the repository browser.