source: trunk/dll/killproc.c@ 1859

Last change on this file since 1859 was 1859, checked in by John Small, 10 years ago

Corrected typo in previous comment.

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