source: trunk/dll/killproc.c@ 1627

Last change on this file since 1627 was 1627, checked in by Gregg Young, 14 years ago

Add a low mem version of xDosAlloc* wrappers; move error checking into all the xDosAlloc* wrappers. Ticket 471

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