source: trunk/dll/killproc.c@ 888

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

runemf2 now quotes executable strings if needed (Ticket 180); it also reports where it was called from on errors

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