source: trunk/dll/killproc.c@ 830

Last change on this file since 830 was 830, checked in by Gregg Young, 18 years ago

minor cleanup of DosQuerySysState code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.9 KB
RevLine 
[145]1
2/***********************************************************************
3
4 $Id: killproc.c 830 2007-09-03 03:30:56Z 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,
[551]238 hwnd, NULL, NULL, "%s", "PSTAT.EXE /C");
[2]239 oldstdout = fileno(stdout);
[551]240 DosDupHandle(newstdout, &oldstdout);
[2]241 DosClose(newstdout);
242 fclose(fp);
[451]243 // fixme to be gone?
[551]244 if (rc == -1) {
[2]245 saymsg(MB_CANCEL,
[551]246 hwnd,
247 GetPString(IDS_ARGHTEXT), GetPString(IDS_CANTRUNPSTATTEXT));
[2]248 goto Abort;
249 }
250 }
[551]251 fp = fopen(s, "r");
[404]252 if (fp) {
253 while (!feof(fp)) {
[551]254 strset(s, 0);
255 if (!xfgets(s, 1025, fp, pszSrcFile, __LINE__))
256 break;
[404]257 if (!foundstart) {
[551]258 if (*s == ' ' && strstr(s, startstring))
259 foundstart = TRUE;
[2]260 }
261 else {
[551]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 }
[2]283 }
284 }
285 fclose(fp);
286 }
287Abort:
288 DosForceDelete("$PSTAT#$.#$#");
[551]289 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]290 WinDestroyMsgQueue(thmq);
[533]291 DecrThreadUsage();
[2]292 WinTerminate(thab);
293}
294
[551]295MRESULT EXPENTRY KillDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[350]296{
[551]297 SHORT sSelect;
298 PID pid;
299 static BOOL listdone;
300 static HPOINTER hptrIcon = (HPOINTER) 0;
[2]301
[551]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);
[828]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 }
[551]316 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
317 break;
[2]318
[551]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;
[2]335
[551]336 case WM_CONTROL:
337 switch (SHORT1FROMMP(mp1)) {
338 case KILL_CHECKBOX:
339 fUseQProcStat = WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX);
340 PrfWriteProfileData(fmprof,
341 FM3Str,
[828]342 "UseQProcStat", &fUseQProcStat, sizeof(BOOL));
[551]343 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
[828]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);
[551]350 break;
[828]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;
[2]364
[551]365 case KILL_LISTBOX:
366 switch (SHORT2FROMMP(mp2)) {
367 case LN_ENTER:
368 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPFROMSHORT(TRUE), MPVOID);
369 break;
[2]370 }
[551]371 break;
[2]372
[551]373 default:
[2]374 break;
[551]375 }
376 return 0;
[2]377
[551]378 case WM_ADJUSTWINDOWPOS:
379 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
380 break;
[2]381
[551]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);
[2]403 }
[551]404 }
405 return 0;
[2]406
[551]407 case WM_COMMAND:
408 switch (SHORT1FROMMP(mp1)) {
409 case KILL_RESCAN:
410 listdone = FALSE;
411 if (fUseQProcStat) {
412 if (_beginthread(FillKillListThread2,
[829]413 NULL, 65536 + 8192, (PVOID)&hwnd) != -1)
414 DosSleep(100); // 05 Aug 07 GKY 250
[551]415 else
[828]416 WinDismissDlg(hwnd, 0);
[551]417 }
[828]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);
[551]424 else {
425 if (_beginthread(FillKillListThread,
426 NULL, 65536, (PVOID) & hwnd) != -1)
[829]427 DosSleep(100); // 05 Aug 07 GKY 250
[551]428 else
429 WinDismissDlg(hwnd, 0);
430 }
431 break;
[2]432
[551]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) {
[2]440
[551]441 CHAR s[31], *p;
442 APIRET error;
[2]443
[551]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 }
[2]472 }
[551]473 break;
[2]474
[551]475 case DID_CANCEL:
476 if (!listdone)
477 Runtime_Error(pszSrcFile, __LINE__, "busy");
478 else
479 WinDismissDlg(hwnd, 0);
[2]480 break;
481
[551]482 case IDM_HELP:
483 saymsg(MB_ENTER | MB_ICONASTERISK,
484 hwnd,
485 GetPString(IDS_KILLPROCHELPTITLETEXT),
486 GetPString(IDS_KILLPROCHELPTEXT));
[2]487 break;
[551]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;
[2]503 }
[551]504 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]505}
[793]506
507#pragma alloc_text(KILLPROC,FillKillListThread,FillKillListThread2,GetDosPgmName,KillDlgProc)
[830]508#pragma alloc_text(KILLPROC,FillKillListThread3)
Note: See TracBrowser for help on using the repository browser.