source: trunk/dll/killproc.c@ 1344

Last change on this file since 1344 was 1335, checked in by Steven Levine, 17 years ago

Ticket 26: Add exception handlers to all threads using xbeginthread

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