source: trunk/dll/killproc.c@ 1505

Last change on this file since 1505 was 1505, checked in by Gregg Young, 15 years ago

Remove unnecessary type casts; minor formating cleanup.

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