source: trunk/dll/killproc.c@ 897

Last change on this file since 897 was 888, checked in by Gregg Young, 18 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
RevLine 
[145]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
[350]9 Copyright (c) 2005, 2006 Steven H. Levine
[145]10
11 24 May 05 SHL Rework Win_Error usage
[350]12 14 Jul 06 SHL Use Runtime_Error
[404]13 29 Jul 06 SHL Use xfgets
[533]14 03 Nov 06 SHL Renames
15 03 Nov 06 SHL Count thread usage
[775]16 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[793]17 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[828]18 02 Sep 07 GKY Replaced DosQProcStatus with DosQuerySysState to fix trap in thunk code
[829]19 02 Sep 07 SHL Expand FillKillListThread2 stack to avoid exception in __TNK
[145]20
21***********************************************************************/
22
[2]23#define INCL_DOSERRORS
24#define INCL_DOS
25#define INCL_WIN
[350]26#include <os2.h>
[2]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>
[350]35
[2]36#include "fm3dll.h"
37#include "fm3dlg.h"
38#include "fm3str.h"
[828]39#include "procstat.h"
[2]40
41#pragma data_seg(DATA2)
42
[350]43static PSZ pszSrcFile = __FILE__;
[2]44
[551]45CHAR *GetDosPgmName(PID pid, CHAR * string)
[350]46{
[2]47 HSWITCH hs;
48 SWCNTRL swctl;
[551]49 PCH pch;
[2]50
51 *string = 0;
[551]52 hs = WinQuerySwitchHandle(0, pid);
53 if (hs) {
54 WinQuerySwitchEntry(hs, &swctl);
[2]55 pch = swctl.szSwtitle;
[551]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 }
[2]64 else
[551]65 pch++;
[2]66 }
[551]67 strcpy(string, swctl.szSwtitle);
[2]68 }
[551]69 if (!*string)
70 strcpy(string, GetPString(IDS_UNKNOWNDOSPROCTEXT));
[2]71 return string;
72}
73
[551]74static VOID FillKillListThread2(VOID * arg)
[350]75{
[551]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;
[2]84
85 thab = WinInitialize(0);
[551]86 thmq = WinCreateMsgQueue(thab, 0);
87 WinCancelShutdown(thmq, TRUE);
[533]88 IncrThreadUsage();
[2]89
[551]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);
[350]93 if (rc)
[551]94 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
95 GetPString(IDS_OUTOFMEMORY));
[350]96 else {
[829]97 rc = DosQProcStatus((ULONG *)pbh, USHRT_MAX);
[350]98 if (!rc) {
[2]99 ppi = pbh->ppi;
[551]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));
[830]109 else {
[551]110 if (*pmi->szModName)
[830]111 strcat(s, pmi->szModName);
[551]112 else
113 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
[350]114 }
[551]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
[2]126 }
127 DosFreeMem(pbh);
128 }
[350]129
[551]130 if (WinIsWindow(thab, hwnd))
131 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]132 WinDestroyMsgQueue(thmq);
[533]133 DecrThreadUsage();
[2]134 WinTerminate(thab);
135}
136
[828]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));
[830]172 else {
[828]173 if (*pmi->pName)
[830]174 strcat(s, (CHAR *) pmi->pName);
[828]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
[551]200static VOID FillKillListThread(VOID * arg)
[350]201{
[551]202 HWND hwnd = *(HWND *) arg;
203 CHAR s[1036], progname[1027], *p;
204 HAB thab;
205 HMQ thmq;
[2]206 FILE *fp;
[551]207 BOOL foundstart = FALSE;
208 INT rc;
[2]209 CHAR *startstring = "Process and Thread Information";
210 CHAR *endstring = "System Semaphore Information";
[551]211 PID pid;
212 HFILE oldstdout, newstdout;
[2]213
214 DosError(FERR_DISABLEHARDERR);
215
216 thab = WinInitialize(0);
[551]217 thmq = WinCreateMsgQueue(thab, 0);
218 WinCancelShutdown(thmq, TRUE);
[533]219 IncrThreadUsage();
[2]220
[551]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));
[350]228 goto Abort;
229 }
230 else {
[2]231 newstdout = -1;
[551]232 rc = DosDupHandle(fileno(stdout), &newstdout);
[350]233 if (rc)
[551]234 Dos_Error(MB_CANCEL, rc, hwnd, __FILE__, __LINE__, "DosDupHandle");
[2]235 oldstdout = fileno(stdout);
[551]236 DosDupHandle(fileno(fp), &oldstdout);
[2]237 rc = runemf2(SEPARATE | INVISIBLE | FULLSCREEN | BACKGROUND | WAIT,
[888]238 hwnd, pszSrcFile, __LINE__, NULL, NULL,
239 "%s", "PSTAT.EXE /C");
[2]240 oldstdout = fileno(stdout);
[551]241 DosDupHandle(newstdout, &oldstdout);
[2]242 DosClose(newstdout);
243 fclose(fp);
[451]244 // fixme to be gone?
[551]245 if (rc == -1) {
[2]246 saymsg(MB_CANCEL,
[551]247 hwnd,
248 GetPString(IDS_ARGHTEXT), GetPString(IDS_CANTRUNPSTATTEXT));
[2]249 goto Abort;
250 }
251 }
[551]252 fp = fopen(s, "r");
[404]253 if (fp) {
254 while (!feof(fp)) {
[551]255 strset(s, 0);
256 if (!xfgets(s, 1025, fp, pszSrcFile, __LINE__))
257 break;
[404]258 if (!foundstart) {
[551]259 if (*s == ' ' && strstr(s, startstring))
260 foundstart = TRUE;
[2]261 }
262 else {
[551]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 }
[2]284 }
285 }
286 fclose(fp);
287 }
288Abort:
289 DosForceDelete("$PSTAT#$.#$#");
[551]290 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]291 WinDestroyMsgQueue(thmq);
[533]292 DecrThreadUsage();
[2]293 WinTerminate(thab);
294}
295
[551]296MRESULT EXPENTRY KillDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[350]297{
[551]298 SHORT sSelect;
299 PID pid;
300 static BOOL listdone;
301 static HPOINTER hptrIcon = (HPOINTER) 0;
[2]302
[551]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);
[828]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 }
[551]317 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
318 break;
[2]319
[551]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;
[2]336
[551]337 case WM_CONTROL:
338 switch (SHORT1FROMMP(mp1)) {
339 case KILL_CHECKBOX:
340 fUseQProcStat = WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX);
341 PrfWriteProfileData(fmprof,
342 FM3Str,
[828]343 "UseQProcStat", &fUseQProcStat, sizeof(BOOL));
[551]344 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
[828]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);
[551]351 break;
[828]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;
[2]365
[551]366 case KILL_LISTBOX:
367 switch (SHORT2FROMMP(mp2)) {
368 case LN_ENTER:
369 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPFROMSHORT(TRUE), MPVOID);
370 break;
[2]371 }
[551]372 break;
[2]373
[551]374 default:
[2]375 break;
[551]376 }
377 return 0;
[2]378
[551]379 case WM_ADJUSTWINDOWPOS:
380 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
381 break;
[2]382
[551]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);
[2]404 }
[551]405 }
406 return 0;
[2]407
[551]408 case WM_COMMAND:
409 switch (SHORT1FROMMP(mp1)) {
410 case KILL_RESCAN:
411 listdone = FALSE;
412 if (fUseQProcStat) {
413 if (_beginthread(FillKillListThread2,
[829]414 NULL, 65536 + 8192, (PVOID)&hwnd) != -1)
415 DosSleep(100); // 05 Aug 07 GKY 250
[551]416 else
[828]417 WinDismissDlg(hwnd, 0);
[551]418 }
[828]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);
[551]425 else {
426 if (_beginthread(FillKillListThread,
427 NULL, 65536, (PVOID) & hwnd) != -1)
[829]428 DosSleep(100); // 05 Aug 07 GKY 250
[551]429 else
430 WinDismissDlg(hwnd, 0);
431 }
432 break;
[2]433
[551]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) {
[2]441
[551]442 CHAR s[31], *p;
443 APIRET error;
[2]444
[551]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 }
[2]473 }
[551]474 break;
[2]475
[551]476 case DID_CANCEL:
477 if (!listdone)
478 Runtime_Error(pszSrcFile, __LINE__, "busy");
479 else
480 WinDismissDlg(hwnd, 0);
[2]481 break;
482
[551]483 case IDM_HELP:
484 saymsg(MB_ENTER | MB_ICONASTERISK,
485 hwnd,
486 GetPString(IDS_KILLPROCHELPTITLETEXT),
487 GetPString(IDS_KILLPROCHELPTEXT));
[2]488 break;
[551]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;
[2]504 }
[551]505 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]506}
[793]507
508#pragma alloc_text(KILLPROC,FillKillListThread,FillKillListThread2,GetDosPgmName,KillDlgProc)
[830]509#pragma alloc_text(KILLPROC,FillKillListThread3)
Note: See TracBrowser for help on using the repository browser.