source: trunk/dll/killproc.c@ 829

Last change on this file since 829 was 829, checked in by Steven Levine, 18 years ago

Update DosQProcStatus declarations for OpenWatcom compat
Layout KILL_FRAME to avoid text overlap

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.9 KB
Line 
1
2/***********************************************************************
3
4 $Id: killproc.c 829 2007-09-03 02:48:29Z stevenhl $
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, NULL, NULL, "%s", "PSTAT.EXE /C");
239 oldstdout = fileno(stdout);
240 DosDupHandle(newstdout, &oldstdout);
241 DosClose(newstdout);
242 fclose(fp);
243 // fixme to be gone?
244 if (rc == -1) {
245 saymsg(MB_CANCEL,
246 hwnd,
247 GetPString(IDS_ARGHTEXT), GetPString(IDS_CANTRUNPSTATTEXT));
248 goto Abort;
249 }
250 }
251 fp = fopen(s, "r");
252 if (fp) {
253 while (!feof(fp)) {
254 strset(s, 0);
255 if (!xfgets(s, 1025, fp, pszSrcFile, __LINE__))
256 break;
257 if (!foundstart) {
258 if (*s == ' ' && strstr(s, startstring))
259 foundstart = TRUE;
260 }
261 else {
262 if (*s == ' ' && strstr(s, endstring))
263 break;
264 if (*s == ' ' && s[5] == ' ' && isxdigit(s[1]) &&
265 isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4])) {
266 p = &s[1];
267 pid = strtol(&s[1], &p, 16);
268 if (pid && pid != mypid) {
269 strcpy(progname, &s[30]);
270 p = strchr(progname, ' ');
271 if (p)
272 *p = 0;
273 if (!stristr(progname, "\\PSTAT.EXE")) {
274 sprintf(s, "%04x %s", pid, progname);
275 WinSendDlgItemMsg(hwnd,
276 KILL_LISTBOX,
277 LM_INSERTITEM,
278 MPFROM2SHORT(LIT_SORTASCENDING, 0),
279 MPFROMP(s));
280 }
281 }
282 }
283 }
284 }
285 fclose(fp);
286 }
287Abort:
288 DosForceDelete("$PSTAT#$.#$#");
289 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
290 WinDestroyMsgQueue(thmq);
291 DecrThreadUsage();
292 WinTerminate(thab);
293}
294
295MRESULT EXPENTRY KillDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
296{
297 SHORT sSelect;
298 PID pid;
299 static BOOL listdone;
300 static HPOINTER hptrIcon = (HPOINTER) 0;
301
302 switch (msg) {
303 case WM_INITDLG:
304 hptrIcon = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, KILL_FRAME);
305 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptrIcon), MPVOID);
306 WinCheckButton(hwnd, KILL_CHECKBOX, fUseQProcStat);
307 WinCheckButton(hwnd, KILL2_CHECKBOX, fUseQSysState);
308 if (WinQueryButtonCheckstate(hwnd, KILL2_CHECKBOX)) {
309 WinCheckButton(hwnd, KILL_CHECKBOX, FALSE);
310 WinEnableWindow(WinWindowFromID(hwnd, KILL_CHECKBOX), FALSE);
311 }
312 if (WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX)) {
313 WinCheckButton(hwnd, KILL2_CHECKBOX, FALSE);
314 WinEnableWindow(WinWindowFromID(hwnd, KILL2_CHECKBOX), FALSE);
315 }
316 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
317 break;
318
319 case UM_CONTAINER_FILLED:
320 listdone = TRUE;
321 if ((SHORT) WinSendDlgItemMsg(hwnd,
322 KILL_LISTBOX,
323 LM_QUERYITEMCOUNT, MPVOID, MPVOID) == 0) {
324 if (!fUseQProcStat)
325 saymsg(MB_CANCEL,
326 hwnd,
327 GetPString(IDS_ICHOKEDTEXT), GetPString(IDS_ISPSTATTHERETEXT));
328 else
329 saymsg(MB_CANCEL,
330 hwnd,
331 GetPString(IDS_ICHOKEDTEXT),
332 GetPString(IDS_DOSQPROCSTATFAILEDTEXT));
333 }
334 return 0;
335
336 case WM_CONTROL:
337 switch (SHORT1FROMMP(mp1)) {
338 case KILL_CHECKBOX:
339 fUseQProcStat = WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX);
340 PrfWriteProfileData(fmprof,
341 FM3Str,
342 "UseQProcStat", &fUseQProcStat, sizeof(BOOL));
343 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
344 if (WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX)) {
345 WinCheckButton(hwnd, KILL2_CHECKBOX, FALSE);
346 WinEnableWindow(WinWindowFromID(hwnd, KILL2_CHECKBOX), FALSE);
347 }
348 else
349 WinEnableWindow(WinWindowFromID(hwnd, KILL2_CHECKBOX), TRUE);
350 break;
351 case KILL2_CHECKBOX:
352 fUseQSysState = WinQueryButtonCheckstate(hwnd, KILL2_CHECKBOX);
353 PrfWriteProfileData(fmprof,
354 FM3Str,
355 "UseQSysState", &fUseQSysState, sizeof(BOOL));
356 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
357 if (WinQueryButtonCheckstate(hwnd, KILL2_CHECKBOX)) {
358 WinCheckButton(hwnd, KILL_CHECKBOX, FALSE);
359 WinEnableWindow(WinWindowFromID(hwnd, KILL_CHECKBOX), FALSE);
360 }
361 else
362 WinEnableWindow(WinWindowFromID(hwnd, KILL_CHECKBOX), TRUE);
363 break;
364
365 case KILL_LISTBOX:
366 switch (SHORT2FROMMP(mp2)) {
367 case LN_ENTER:
368 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPFROMSHORT(TRUE), MPVOID);
369 break;
370 }
371 break;
372
373 default:
374 break;
375 }
376 return 0;
377
378 case WM_ADJUSTWINDOWPOS:
379 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
380 break;
381
382 case UM_STRETCH:
383 {
384 SWP swpC, swp, swpH;
385
386 WinQueryWindowPos(hwnd, &swp);
387 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
388 WinQueryWindowPos(WinWindowFromID(hwnd, KILL_LISTBOX), &swpC);
389 WinQueryWindowPos(WinWindowFromID(hwnd, KILL_HDR), &swpH);
390 WinSetWindowPos(WinWindowFromID(hwnd, KILL_LISTBOX), HWND_TOP,
391 SysVal(SV_CXSIZEBORDER),
392 swpC.y,
393 swp.cx - (SysVal(SV_CXSIZEBORDER) * 2),
394 ((swp.cy - swpC.y) - (SysVal(SV_CYTITLEBAR) +
395 SysVal(SV_CYSIZEBORDER)) -
396 (swpH.cy + 8)), SWP_MOVE | SWP_SIZE);
397 WinSetWindowPos(WinWindowFromID(hwnd, KILL_HDR), HWND_TOP,
398 SysVal(SV_CXSIZEBORDER) + 4,
399 swpC.y + ((swp.cy - swpC.y) -
400 (SysVal(SV_CYTITLEBAR) +
401 SysVal(SV_CYSIZEBORDER)) -
402 (swpH.cy + 4)), swpH.cx, swpH.cy, SWP_MOVE);
403 }
404 }
405 return 0;
406
407 case WM_COMMAND:
408 switch (SHORT1FROMMP(mp1)) {
409 case KILL_RESCAN:
410 listdone = FALSE;
411 if (fUseQProcStat) {
412 if (_beginthread(FillKillListThread2,
413 NULL, 65536 + 8192, (PVOID)&hwnd) != -1)
414 DosSleep(100); // 05 Aug 07 GKY 250
415 else
416 WinDismissDlg(hwnd, 0);
417 }
418 else if (fUseQSysState)
419 if (_beginthread(FillKillListThread3,
420 NULL, 65536, (PVOID) & hwnd) != -1)
421 DosSleep(100);//05 Aug 07 GKY 250
422 else
423 WinDismissDlg(hwnd, 0);
424 else {
425 if (_beginthread(FillKillListThread,
426 NULL, 65536, (PVOID) & hwnd) != -1)
427 DosSleep(100); // 05 Aug 07 GKY 250
428 else
429 WinDismissDlg(hwnd, 0);
430 }
431 break;
432
433 case KILL_SHOW:
434 case DID_OK:
435 sSelect = (USHORT) WinSendDlgItemMsg(hwnd,
436 KILL_LISTBOX,
437 LM_QUERYSELECTION,
438 MPFROMSHORT(LIT_FIRST), MPVOID);
439 if (sSelect >= 0) {
440
441 CHAR s[31], *p;
442 APIRET error;
443
444 *s = 0;
445 WinSendDlgItemMsg(hwnd,
446 KILL_LISTBOX,
447 LM_QUERYITEMTEXT,
448 MPFROM2SHORT(sSelect, 30), MPFROMP(s));
449 if (*s) {
450 p = s;
451 pid = strtol(s, &p, 16);
452 if (pid) {
453 if (SHORT1FROMMP(mp1) == DID_OK) {
454 error = DosKillProcess(DKP_PROCESS, pid);
455 if (error && error != ERROR_INVALID_PROCID) {
456 Dos_Error(MB_CANCEL,
457 error,
458 hwnd,
459 __FILE__,
460 __LINE__, GetPString(IDS_DOSKILLFAILEDTEXT));
461 }
462 else
463 WinSendDlgItemMsg(hwnd,
464 KILL_LISTBOX,
465 LM_DELETEITEM,
466 MPFROM2SHORT(sSelect, 0), MPVOID);
467 }
468 else if (!ShowSession(hwnd, pid))
469 Notify(GetPString(IDS_SORRYCANTSHOWTEXT));
470 }
471 }
472 }
473 break;
474
475 case DID_CANCEL:
476 if (!listdone)
477 Runtime_Error(pszSrcFile, __LINE__, "busy");
478 else
479 WinDismissDlg(hwnd, 0);
480 break;
481
482 case IDM_HELP:
483 saymsg(MB_ENTER | MB_ICONASTERISK,
484 hwnd,
485 GetPString(IDS_KILLPROCHELPTITLETEXT),
486 GetPString(IDS_KILLPROCHELPTEXT));
487 break;
488 }
489 return 0;
490
491 case WM_CLOSE:
492 if (!listdone) {
493 Runtime_Error(pszSrcFile, __LINE__, "busy");
494 return 0;
495 }
496 break;
497
498 case WM_DESTROY:
499 if (hptrIcon)
500 WinDestroyPointer(hptrIcon);
501 hptrIcon = (HPOINTER) 0;
502 break;
503 }
504 return WinDefDlgProc(hwnd, msg, mp1, mp2);
505}
506
507#pragma alloc_text(KILLPROC,FillKillListThread,FillKillListThread2,GetDosPgmName,KillDlgProc)
508#pragma alloc_text(KILLPROC,FillKillListThread)
Note: See TracBrowser for help on using the repository browser.