source: trunk/dll/killproc.c@ 1554

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

Check that pTmpDir IsValid and recreate if not found; Fixes hangs caused by temp file creation failures. (Ticket 440)

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