source: trunk/dll/killproc.c@ 1075

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

Debulked TMP code; Added comments;

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