source: trunk/dll/killproc.c@ 1188

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

Ticket 187: Draft 2: Move remaining function declarations

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.7 KB
Line 
1
2/***********************************************************************
3
4 $Id: killproc.c 1188 2008-09-10 21:58:30Z 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 "fm3dlg.h"
37#include "fm3str.h"
38#include "procstat.h"
39#include "errutil.h" // Dos_Error...
40#include "strutil.h" // GetPString
41#include "pathutil.h" // BldFullPathName
42#include "killproc.h"
43#include "systemf.h" // ShowSession
44#include "common.h" // DecrThreadUsage, IncrThreadUsage
45#include "notify.h" // Notify
46#include "copyf.h" // unlinkf
47#include "wrappers.h" // xfgets
48#include "stristr.h" // stristr
49#include "misc.h" // PostMsg
50#include "fortify.h"
51
52#pragma data_seg(DATA2)
53
54static PSZ pszSrcFile = __FILE__;
55
56CHAR *GetDosPgmName(PID pid, CHAR * string)
57{
58 HSWITCH hs;
59 SWCNTRL swctl;
60 PCH pch;
61
62 *string = 0;
63 hs = WinQuerySwitchHandle(0, pid);
64 if (hs) {
65 WinQuerySwitchEntry(hs, &swctl);
66 pch = swctl.szSwtitle;
67 while (*pch) {
68 if (*pch < 0x10)
69 if (pch != swctl.szSwtitle && *(pch - 1) == 0x20)
70 memmove(pch, pch + 1, strlen(pch));
71 else {
72 *pch = 0x20;
73 pch++;
74 }
75 else
76 pch++;
77 }
78 strcpy(string, swctl.szSwtitle);
79 }
80 if (!*string)
81 strcpy(string, GetPString(IDS_UNKNOWNDOSPROCTEXT));
82 return string;
83}
84
85static VOID FillKillListThread2(VOID * arg)
86{
87 HWND hwnd = *(HWND *) arg;
88 CHAR s[1036];
89 HAB thab;
90 HMQ thmq;
91 INT rc;
92 PROCESSINFO *ppi;
93 BUFFHEADER *pbh;
94 MODINFO *pmi;
95
96# ifdef FORTIFY
97 Fortify_EnterScope();
98# endif
99 thab = WinInitialize(0);
100 thmq = WinCreateMsgQueue(thab, 0);
101 WinCancelShutdown(thmq, TRUE);
102 IncrThreadUsage();
103
104 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
105 rc = DosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
106 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
107 if (rc)
108 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
109 GetPString(IDS_OUTOFMEMORY));
110 else {
111 rc = DosQProcStatus((ULONG *)pbh, USHRT_MAX);
112 if (!rc) {
113 ppi = pbh->ppi;
114 while (ppi->ulEndIndicator != PROCESS_END_INDICATOR) {
115 if (ppi->pid != mypid) {
116 pmi = pbh->pmi;
117 while (pmi && ppi->hModRef != pmi->hMod)
118 pmi = pmi->pNext;
119 if (pmi) {
120 sprintf(s, "%04x ", ppi->pid);
121 if (!stricmp(pmi->szModName, "SYSINIT"))
122 GetDosPgmName(ppi->pid, s + strlen(s));
123 else {
124 if (*pmi->szModName)
125 strcat(s, pmi->szModName);
126 else
127 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
128 }
129 if (WinIsWindow(thab, hwnd)) {
130 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_INSERTITEM,
131 MPFROM2SHORT(LIT_SORTASCENDING, 0),
132 MPFROMP(s));
133 }
134 else
135 break;
136 }
137 }
138 ppi = (PPROCESSINFO) (ppi->ptiFirst + ppi->usThreadCount);
139 } // while
140 }
141 DosFreeMem(pbh);
142 }
143
144 if (WinIsWindow(thab, hwnd))
145 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
146 WinDestroyMsgQueue(thmq);
147 DecrThreadUsage();
148 WinTerminate(thab);
149# ifdef FORTIFY
150 Fortify_LeaveScope();
151# endif
152}
153
154static VOID FillKillListThread3(VOID * arg)
155{
156 HWND hwnd = *(HWND *) arg;
157 CHAR s[1036];
158 HAB thab;
159 HMQ thmq;
160 INT rc;
161 QSPREC *ppi;
162 QSPTRREC *pbh;
163 QSLREC *pmi;
164
165# ifdef FORTIFY
166 Fortify_EnterScope();
167# endif
168 thab = WinInitialize(0);
169 thmq = WinCreateMsgQueue(thab, 0);
170 WinCancelShutdown(thmq, TRUE);
171 IncrThreadUsage();
172
173 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
174 rc = DosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
175 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
176 if (rc)
177 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
178 GetPString(IDS_OUTOFMEMORY));
179 else {
180 rc = DosQuerySysState(QS_PROCESS | QS_MTE, 0, 0, 0, pbh, USHRT_MAX);
181 if (!rc) {
182 ppi = pbh->pProcRec;
183 while (ppi->RecType == 1) {
184 if (ppi->pid != mypid) {
185 pmi = pbh->pLibRec;
186 while (pmi && ppi->hMte != pmi->hmte)
187 pmi = pmi->pNextRec;
188 if (pmi) {
189 sprintf(s, "%04x ", ppi->pid);
190 if (!stricmp((CHAR *) pmi->pName, "SYSINIT"))
191 GetDosPgmName(ppi->pid, s + strlen(s));
192 else {
193 if (*pmi->pName)
194 strcat(s, (CHAR *) pmi->pName);
195 else
196 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
197 }
198 if (WinIsWindow(thab, hwnd)) {
199 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_INSERTITEM,
200 MPFROM2SHORT(LIT_SORTASCENDING, 0),
201 MPFROMP(s));
202 }
203 else
204 break;
205 }
206 }
207 ppi = (QSPREC *) (ppi->pThrdRec + ppi->cTCB); // 22 Jun 08 SHL fixme to know why this looks odd
208 } // while
209 }
210 DosFreeMem(pbh);
211 }
212
213 if (WinIsWindow(thab, hwnd))
214 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
215 WinDestroyMsgQueue(thmq);
216 DecrThreadUsage();
217 WinTerminate(thab);
218# ifdef FORTIFY
219 Fortify_LeaveScope();
220# endif
221}
222
223static VOID FillKillListThread(VOID * arg)
224{
225 HWND hwnd = *(HWND *) arg;
226 CHAR s[1036], progname[1027], *p;
227 HAB thab;
228 HMQ thmq;
229 FILE *fp;
230 BOOL foundstart = FALSE;
231 INT rc;
232 CHAR *startstring = "Process and Thread Information";
233 CHAR *endstring = "System Semaphore Information";
234 PID pid;
235 HFILE oldstdout, newstdout;
236
237 DosError(FERR_DISABLEHARDERR);
238
239# ifdef FORTIFY
240 Fortify_EnterScope();
241# endif
242 thab = WinInitialize(0);
243 thmq = WinCreateMsgQueue(thab, 0);
244 WinCancelShutdown(thmq, TRUE);
245 IncrThreadUsage();
246
247 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
248 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
249 unlinkf("%s", s);
250 fp = fopen(s, "w");
251 if (!fp) {
252 Win_Error(NULLHANDLE, HWND_DESKTOP, __FILE__, __LINE__,
253 GetPString(IDS_REDIRECTERRORTEXT));
254 goto Abort;
255 }
256 else {
257 newstdout = -1;
258 rc = DosDupHandle(fileno(stdout), &newstdout);
259 if (rc)
260 Dos_Error(MB_CANCEL, rc, hwnd, __FILE__, __LINE__, "DosDupHandle");
261 oldstdout = fileno(stdout);
262 DosDupHandle(fileno(fp), &oldstdout);
263 rc = runemf2(SEPARATE | INVISIBLE | FULLSCREEN | BACKGROUND | WAIT,
264 hwnd, pszSrcFile, __LINE__, NULL, NULL,
265 "%s", "PSTAT.EXE /C");
266 oldstdout = fileno(stdout);
267 DosDupHandle(newstdout, &oldstdout);
268 DosClose(newstdout);
269 fclose(fp);
270 // fixme to be gone?
271 if (rc == -1) {
272 saymsg(MB_CANCEL,
273 hwnd,
274 GetPString(IDS_ARGHTEXT), GetPString(IDS_CANTRUNPSTATTEXT));
275 goto Abort;
276 }
277 }
278 fp = fopen(s, "r");
279 if (fp) {
280 while (!feof(fp)) {
281 strset(s, 0);
282 if (!xfgets(s, 1025, fp, pszSrcFile, __LINE__))
283 break;
284 if (!foundstart) {
285 if (*s == ' ' && strstr(s, startstring))
286 foundstart = TRUE;
287 }
288 else {
289 if (*s == ' ' && strstr(s, endstring))
290 break;
291 if (*s == ' ' && s[5] == ' ' && isxdigit(s[1]) &&
292 isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4])) {
293 p = &s[1];
294 pid = strtol(&s[1], &p, 16);
295 if (pid && pid != mypid) {
296 strcpy(progname, &s[30]);
297 p = strchr(progname, ' ');
298 if (p)
299 *p = 0;
300 if (!stristr(progname, "\\PSTAT.EXE")) {
301 sprintf(s, "%04x %s", pid, progname);
302 WinSendDlgItemMsg(hwnd,
303 KILL_LISTBOX,
304 LM_INSERTITEM,
305 MPFROM2SHORT(LIT_SORTASCENDING, 0),
306 MPFROMP(s));
307 }
308 }
309 }
310 }
311 }
312 fclose(fp);
313 }
314Abort:
315 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
316 DosForceDelete(s);
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.