source: trunk/dll/killproc.c@ 1209

Last change on this file since 1209 was 1209, checked in by John Small, 17 years ago

Ticket 187: Move data declarations/definitions out of fm3dll.h

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