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
RevLine 
[145]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
[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"
[1224]36#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
[1209]37#include "init.h" // Data declaration(s)
38#include "notebook.h" // Data declaration(s)
39#include "mainwnd.h" // Data declaration(s)
[2]40#include "fm3dlg.h"
41#include "fm3str.h"
[828]42#include "procstat.h"
[907]43#include "errutil.h" // Dos_Error...
44#include "strutil.h" // GetPString
[1077]45#include "pathutil.h" // BldFullPathName
[1163]46#include "killproc.h"
47#include "systemf.h" // ShowSession
[1188]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
[1036]54#include "fortify.h"
[2]55
[1209]56// Data definitions
[2]57#pragma data_seg(DATA2)
58
[350]59static PSZ pszSrcFile = __FILE__;
[2]60
[1209]61#pragma data_seg(GLOBAL1)
62BOOL fUseQProcStat;
63BOOL fUseQSysState;
64PID mypid;
65
[551]66CHAR *GetDosPgmName(PID pid, CHAR * string)
[350]67{
[2]68 HSWITCH hs;
69 SWCNTRL swctl;
[551]70 PCH pch;
[2]71
72 *string = 0;
[551]73 hs = WinQuerySwitchHandle(0, pid);
74 if (hs) {
75 WinQuerySwitchEntry(hs, &swctl);
[2]76 pch = swctl.szSwtitle;
[551]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 }
[2]85 else
[551]86 pch++;
[2]87 }
[551]88 strcpy(string, swctl.szSwtitle);
[2]89 }
[551]90 if (!*string)
91 strcpy(string, GetPString(IDS_UNKNOWNDOSPROCTEXT));
[2]92 return string;
93}
94
[551]95static VOID FillKillListThread2(VOID * arg)
[350]96{
[551]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;
[2]105
[1038]106# ifdef FORTIFY
107 Fortify_EnterScope();
[1063]108# endif
[2]109 thab = WinInitialize(0);
[551]110 thmq = WinCreateMsgQueue(thab, 0);
111 WinCancelShutdown(thmq, TRUE);
[533]112 IncrThreadUsage();
[2]113
[551]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);
[350]117 if (rc)
[551]118 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
119 GetPString(IDS_OUTOFMEMORY));
[350]120 else {
[829]121 rc = DosQProcStatus((ULONG *)pbh, USHRT_MAX);
[350]122 if (!rc) {
[2]123 ppi = pbh->ppi;
[551]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));
[1077]133 else {
[551]134 if (*pmi->szModName)
[1077]135 strcat(s, pmi->szModName);
[551]136 else
137 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
[350]138 }
[551]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
[2]150 }
151 DosFreeMem(pbh);
152 }
[350]153
[551]154 if (WinIsWindow(thab, hwnd))
155 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]156 WinDestroyMsgQueue(thmq);
[533]157 DecrThreadUsage();
[2]158 WinTerminate(thab);
[1038]159# ifdef FORTIFY
[1063]160 Fortify_LeaveScope();
161# endif
[2]162}
163
[828]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
[1038]175# ifdef FORTIFY
176 Fortify_EnterScope();
[1063]177# endif
[828]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));
[1077]202 else {
[828]203 if (*pmi->pName)
[1077]204 strcat(s, (CHAR *) pmi->pName);
[828]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 }
[1077]217 ppi = (QSPREC *) (ppi->pThrdRec + ppi->cTCB); // 22 Jun 08 SHL fixme to know why this looks odd
[828]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);
[1038]228# ifdef FORTIFY
[1063]229 Fortify_LeaveScope();
230# endif
[828]231}
232
[551]233static VOID FillKillListThread(VOID * arg)
[350]234{
[551]235 HWND hwnd = *(HWND *) arg;
236 CHAR s[1036], progname[1027], *p;
237 HAB thab;
238 HMQ thmq;
[2]239 FILE *fp;
[551]240 BOOL foundstart = FALSE;
241 INT rc;
[2]242 CHAR *startstring = "Process and Thread Information";
243 CHAR *endstring = "System Semaphore Information";
[551]244 PID pid;
245 HFILE oldstdout, newstdout;
[2]246
247 DosError(FERR_DISABLEHARDERR);
248
[1038]249# ifdef FORTIFY
250 Fortify_EnterScope();
[1063]251# endif
[2]252 thab = WinInitialize(0);
[551]253 thmq = WinCreateMsgQueue(thab, 0);
254 WinCancelShutdown(thmq, TRUE);
[533]255 IncrThreadUsage();
[2]256
[551]257 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
[1075]258 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
[551]259 unlinkf("%s", s);
260 fp = fopen(s, "w");
261 if (!fp) {
262 Win_Error(NULLHANDLE, HWND_DESKTOP, __FILE__, __LINE__,
263 GetPString(IDS_REDIRECTERRORTEXT));
[350]264 goto Abort;
265 }
266 else {
[2]267 newstdout = -1;
[551]268 rc = DosDupHandle(fileno(stdout), &newstdout);
[350]269 if (rc)
[551]270 Dos_Error(MB_CANCEL, rc, hwnd, __FILE__, __LINE__, "DosDupHandle");
[2]271 oldstdout = fileno(stdout);
[551]272 DosDupHandle(fileno(fp), &oldstdout);
[2]273 rc = runemf2(SEPARATE | INVISIBLE | FULLSCREEN | BACKGROUND | WAIT,
[1077]274 hwnd, pszSrcFile, __LINE__, NULL, NULL,
275 "%s", "PSTAT.EXE /C");
[2]276 oldstdout = fileno(stdout);
[551]277 DosDupHandle(newstdout, &oldstdout);
[2]278 DosClose(newstdout);
279 fclose(fp);
[451]280 // fixme to be gone?
[551]281 if (rc == -1) {
[2]282 saymsg(MB_CANCEL,
[551]283 hwnd,
284 GetPString(IDS_ARGHTEXT), GetPString(IDS_CANTRUNPSTATTEXT));
[2]285 goto Abort;
286 }
287 }
[551]288 fp = fopen(s, "r");
[404]289 if (fp) {
290 while (!feof(fp)) {
[551]291 strset(s, 0);
292 if (!xfgets(s, 1025, fp, pszSrcFile, __LINE__))
293 break;
[404]294 if (!foundstart) {
[551]295 if (*s == ' ' && strstr(s, startstring))
296 foundstart = TRUE;
[2]297 }
298 else {
[551]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 }
[2]320 }
321 }
322 fclose(fp);
323 }
324Abort:
[1075]325 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
326 DosForceDelete(s);
[551]327 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]328 WinDestroyMsgQueue(thmq);
[533]329 DecrThreadUsage();
[2]330 WinTerminate(thab);
[1038]331# ifdef FORTIFY
[1063]332 Fortify_LeaveScope();
333# endif
[2]334}
335
[551]336MRESULT EXPENTRY KillDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[350]337{
[551]338 SHORT sSelect;
339 PID pid;
340 static BOOL listdone;
341 static HPOINTER hptrIcon = (HPOINTER) 0;
[2]342
[551]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);
[828]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 }
[551]357 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
358 break;
[2]359
[551]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;
[2]376
[551]377 case WM_CONTROL:
378 switch (SHORT1FROMMP(mp1)) {
379 case KILL_CHECKBOX:
380 fUseQProcStat = WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX);
381 PrfWriteProfileData(fmprof,
382 FM3Str,
[1077]383 "UseQProcStat", &fUseQProcStat, sizeof(BOOL));
[551]384 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
[828]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);
[551]391 break;
[828]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;
[2]405
[551]406 case KILL_LISTBOX:
407 switch (SHORT2FROMMP(mp2)) {
408 case LN_ENTER:
409 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPFROMSHORT(TRUE), MPVOID);
410 break;
[2]411 }
[551]412 break;
[2]413
[551]414 default:
[2]415 break;
[551]416 }
417 return 0;
[2]418
[551]419 case WM_ADJUSTWINDOWPOS:
420 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
421 break;
[2]422
[551]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);
[2]444 }
[551]445 }
446 return 0;
[2]447
[551]448 case WM_COMMAND:
449 switch (SHORT1FROMMP(mp1)) {
450 case KILL_RESCAN:
451 listdone = FALSE;
452 if (fUseQProcStat) {
453 if (_beginthread(FillKillListThread2,
[829]454 NULL, 65536 + 8192, (PVOID)&hwnd) != -1)
455 DosSleep(100); // 05 Aug 07 GKY 250
[551]456 else
[1077]457 WinDismissDlg(hwnd, 0);
[551]458 }
[828]459 else if (fUseQSysState)
[1077]460 if (_beginthread(FillKillListThread3,
[828]461 NULL, 65536, (PVOID) & hwnd) != -1)
462 DosSleep(100);//05 Aug 07 GKY 250
463 else
[1077]464 WinDismissDlg(hwnd, 0);
[551]465 else {
466 if (_beginthread(FillKillListThread,
467 NULL, 65536, (PVOID) & hwnd) != -1)
[1077]468 DosSleep(100); // 05 Aug 07 GKY 250
[551]469 else
470 WinDismissDlg(hwnd, 0);
471 }
472 break;
[2]473
[551]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) {
[2]481
[551]482 CHAR s[31], *p;
483 APIRET error;
[2]484
[551]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 }
[2]513 }
[551]514 break;
[2]515
[551]516 case DID_CANCEL:
517 if (!listdone)
518 Runtime_Error(pszSrcFile, __LINE__, "busy");
519 else
520 WinDismissDlg(hwnd, 0);
[2]521 break;
522
[551]523 case IDM_HELP:
524 saymsg(MB_ENTER | MB_ICONASTERISK,
525 hwnd,
526 GetPString(IDS_KILLPROCHELPTITLETEXT),
527 GetPString(IDS_KILLPROCHELPTEXT));
[2]528 break;
[551]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;
[2]544 }
[551]545 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]546}
[793]547
548#pragma alloc_text(KILLPROC,FillKillListThread,FillKillListThread2,GetDosPgmName,KillDlgProc)
[830]549#pragma alloc_text(KILLPROC,FillKillListThread3)
Note: See TracBrowser for help on using the repository browser.