source: trunk/dll/killproc.c@ 1482

Last change on this file since 1482 was 1482, checked in by Gregg Young, 16 years ago

Fixed separate parameters; added the ability to set it either globally or for just one app; some files only contain white space changes.

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