source: trunk/dll/killproc.c@ 1209

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

Ticket 187: Move data declarations/definitions out of fm3dll.h

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