source: trunk/dll/killproc.c@ 1544

Last change on this file since 1544 was 1544, checked in by Gregg Young, 15 years ago

Changes to fopen and _fsopen to allow FM2 to be loaded in high memory

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.0 KB
Line 
1
2/***********************************************************************
3
4 $Id: killproc.c 1544 2010-09-30 13:00:59Z 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). Mostly cast CHAR CONSTANT * as CHAR *.
30
31***********************************************************************/
32
33#include <stdlib.h>
34#include <string.h>
35#include <ctype.h>
36// #include <process.h>
37#include <limits.h>
38
39#define INCL_DOS
40#define INCL_DOSERRORS
41#define INCL_WIN
42#define INCL_LONGLONG // dircnrs.h
43
44#include "fm3dll.h"
45#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
46#include "init.h" // Data declaration(s)
47#include "notebook.h" // Data declaration(s)
48#include "mainwnd.h" // Data declaration(s)
49#include "fm3dlg.h"
50#include "fm3str.h"
51#include "procstat.h"
52#include "errutil.h" // Dos_Error...
53#include "strutil.h" // GetPString
54#include "pathutil.h" // BldFullPathName
55#include "killproc.h"
56#include "systemf.h" // ShowSession
57#include "common.h" // DecrThreadUsage, IncrThreadUsage
58#include "notify.h" // Notify
59#include "copyf.h" // unlinkf
60#include "wrappers.h" // xfgets
61#include "stristr.h" // stristr
62#include "misc.h" // PostMsg
63#include "fortify.h"
64#include "excputil.h" // xbeginthread
65
66// Data definitions
67#pragma data_seg(DATA2)
68
69static PSZ pszSrcFile = __FILE__;
70
71#pragma data_seg(GLOBAL1)
72BOOL fUseQProcStat;
73BOOL fUseQSysState;
74PID mypid;
75
76CHAR *GetDosPgmName(PID pid, CHAR * string)
77{
78 HSWITCH hs;
79 SWCNTRL swctl;
80 PCH pch;
81
82 *string = 0;
83 hs = WinQuerySwitchHandle(0, pid);
84 if (hs) {
85 WinQuerySwitchEntry(hs, &swctl);
86 pch = swctl.szSwtitle;
87 while (*pch) {
88 if (*pch < 0x10)
89 if (pch != swctl.szSwtitle && *(pch - 1) == 0x20)
90 memmove(pch, pch + 1, strlen(pch));
91 else {
92 *pch = 0x20;
93 pch++;
94 }
95 else
96 pch++;
97 }
98 strcpy(string, swctl.szSwtitle);
99 }
100 if (!*string)
101 strcpy(string, GetPString(IDS_UNKNOWNDOSPROCTEXT));
102 return string;
103}
104
105static VOID FillKillListThread2(VOID * arg)
106{
107 HWND hwnd = *(HWND *) arg;
108 CHAR s[1036];
109 HAB thab;
110 HMQ thmq;
111 INT rc;
112 PROCESSINFO *ppi;
113 BUFFHEADER *pbh;
114 MODINFO *pmi;
115
116# ifdef FORTIFY
117 Fortify_EnterScope();
118# endif
119 thab = WinInitialize(0);
120 thmq = WinCreateMsgQueue(thab, 0);
121 WinCancelShutdown(thmq, TRUE);
122 IncrThreadUsage();
123
124 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
125 rc = xDosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
126 PAG_COMMIT | PAG_READ | PAG_WRITE, pszSrcFile, __LINE__);
127 if (rc)
128 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
129 GetPString(IDS_OUTOFMEMORY));
130 else {
131 rc = DosQProcStatus((ULONG *)pbh, USHRT_MAX);
132 if (!rc) {
133 ppi = pbh->ppi;
134 while (ppi->ulEndIndicator != PROCESS_END_INDICATOR) {
135 if (ppi->pid != mypid) {
136 pmi = pbh->pmi;
137 while (pmi && ppi->hModRef != pmi->hMod)
138 pmi = pmi->pNext;
139 if (pmi) {
140 sprintf(s, "%04x ", ppi->pid);
141 if (!stricmp(pmi->szModName, "SYSINIT"))
142 GetDosPgmName(ppi->pid, s + strlen(s));
143 else {
144 if (*pmi->szModName)
145 strcat(s, pmi->szModName);
146 else
147 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
148 }
149 if (WinIsWindow(thab, hwnd)) {
150 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_INSERTITEM,
151 MPFROM2SHORT(LIT_SORTASCENDING, 0),
152 MPFROMP(s));
153 }
154 else
155 break;
156 }
157 }
158 ppi = (PPROCESSINFO) (ppi->ptiFirst + ppi->usThreadCount);
159 } // while
160 }
161 DosFreeMem(pbh);
162 }
163
164 if (WinIsWindow(thab, hwnd))
165 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
166 WinDestroyMsgQueue(thmq);
167 DecrThreadUsage();
168 WinTerminate(thab);
169# ifdef FORTIFY
170 Fortify_LeaveScope();
171# endif
172}
173
174static VOID FillKillListThread3(VOID * arg)
175{
176 HWND hwnd = *(HWND *) arg;
177 CHAR s[1036];
178 HAB thab;
179 HMQ thmq;
180 INT rc;
181 QSPREC *ppi;
182 QSPTRREC *pbh;
183 QSLREC *pmi;
184
185# ifdef FORTIFY
186 Fortify_EnterScope();
187# endif
188 thab = WinInitialize(0);
189 thmq = WinCreateMsgQueue(thab, 0);
190 WinCancelShutdown(thmq, TRUE);
191 IncrThreadUsage();
192
193 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
194 rc = xDosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
195 PAG_COMMIT | PAG_READ | PAG_WRITE, pszSrcFile, __LINE__);
196 if (rc)
197 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
198 GetPString(IDS_OUTOFMEMORY));
199 else {
200 rc = DosQuerySysState(QS_PROCESS | QS_MTE, 0, 0, 0, pbh, USHRT_MAX);
201 if (!rc) {
202 ppi = pbh->pProcRec;
203 while (ppi->RecType == 1) {
204 if (ppi->pid != mypid) {
205 pmi = pbh->pLibRec;
206 while (pmi && ppi->hMte != pmi->hmte)
207 pmi = pmi->pNextRec;
208 if (pmi) {
209 sprintf(s, "%04x ", ppi->pid);
210 if (!stricmp((CHAR *) pmi->pName, "SYSINIT"))
211 GetDosPgmName(ppi->pid, s + strlen(s));
212 else {
213 if (*pmi->pName)
214 strcat(s, (CHAR *) pmi->pName);
215 else
216 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
217 }
218 if (WinIsWindow(thab, hwnd)) {
219 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_INSERTITEM,
220 MPFROM2SHORT(LIT_SORTASCENDING, 0),
221 MPFROMP(s));
222 }
223 else
224 break;
225 }
226 }
227 ppi = (QSPREC *) (ppi->pThrdRec + ppi->cTCB); // 22 Jun 08 SHL fixme to know why this looks odd
228 } // while
229 }
230 DosFreeMem(pbh);
231 }
232
233 if (WinIsWindow(thab, hwnd))
234 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
235 WinDestroyMsgQueue(thmq);
236 DecrThreadUsage();
237 WinTerminate(thab);
238# ifdef FORTIFY
239 Fortify_LeaveScope();
240# endif
241}
242
243static VOID FillKillListThread(VOID * arg)
244{
245 HWND hwnd = *(HWND *) arg;
246 CHAR s[1036], progname[1027], *p;
247 HAB thab;
248 HMQ thmq;
249 FILE *fp;
250 BOOL foundstart = FALSE;
251 INT rc;
252 CHAR *startstring = "Process and Thread Information";
253 CHAR *endstring = "System Semaphore Information";
254 PID pid;
255 HFILE oldstdout, newstdout;
256 CHAR *mode;
257
258 DosError(FERR_DISABLEHARDERR);
259
260# ifdef FORTIFY
261 Fortify_EnterScope();
262# endif
263 thab = WinInitialize(0);
264 thmq = WinCreateMsgQueue(thab, 0);
265 WinCancelShutdown(thmq, TRUE);
266 IncrThreadUsage();
267
268 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
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.