source: trunk/dll/killproc.c@ 1163

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

Ticket 187: Draft 1: Functions only

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