source: trunk/dll/killproc.c@ 1073

Last change on this file since 1073 was 1073, checked in by Gregg Young, 17 years ago

Fm2 uses TMP/TEMP directory if set for temporary files and directories. Ticket 20

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