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
RevLine 
[145]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
[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
[1075]20 16 JUL 08 GKY Use TMP directory for temp files
[145]21
22***********************************************************************/
23
[2]24#include <stdlib.h>
25#include <string.h>
26#include <ctype.h>
27#include <process.h>
28#include <limits.h>
[350]29
[907]30#define INCL_DOS
31#define INCL_DOSERRORS
32#define INCL_WIN
33#define INCL_LONGLONG // dircnrs.h
34
[2]35#include "fm3dlg.h"
36#include "fm3str.h"
[828]37#include "procstat.h"
[907]38#include "errutil.h" // Dos_Error...
39#include "strutil.h" // GetPString
[1077]40#include "pathutil.h" // BldFullPathName
[1163]41#include "killproc.h"
42#include "systemf.h" // ShowSession
[907]43#include "fm3dll.h"
[1036]44#include "fortify.h"
[2]45
46#pragma data_seg(DATA2)
47
[350]48static PSZ pszSrcFile = __FILE__;
[2]49
[551]50CHAR *GetDosPgmName(PID pid, CHAR * string)
[350]51{
[2]52 HSWITCH hs;
53 SWCNTRL swctl;
[551]54 PCH pch;
[2]55
56 *string = 0;
[551]57 hs = WinQuerySwitchHandle(0, pid);
58 if (hs) {
59 WinQuerySwitchEntry(hs, &swctl);
[2]60 pch = swctl.szSwtitle;
[551]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 }
[2]69 else
[551]70 pch++;
[2]71 }
[551]72 strcpy(string, swctl.szSwtitle);
[2]73 }
[551]74 if (!*string)
75 strcpy(string, GetPString(IDS_UNKNOWNDOSPROCTEXT));
[2]76 return string;
77}
78
[551]79static VOID FillKillListThread2(VOID * arg)
[350]80{
[551]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;
[2]89
[1038]90# ifdef FORTIFY
91 Fortify_EnterScope();
[1063]92# endif
[2]93 thab = WinInitialize(0);
[551]94 thmq = WinCreateMsgQueue(thab, 0);
95 WinCancelShutdown(thmq, TRUE);
[533]96 IncrThreadUsage();
[2]97
[551]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);
[350]101 if (rc)
[551]102 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
103 GetPString(IDS_OUTOFMEMORY));
[350]104 else {
[829]105 rc = DosQProcStatus((ULONG *)pbh, USHRT_MAX);
[350]106 if (!rc) {
[2]107 ppi = pbh->ppi;
[551]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));
[1077]117 else {
[551]118 if (*pmi->szModName)
[1077]119 strcat(s, pmi->szModName);
[551]120 else
121 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
[350]122 }
[551]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
[2]134 }
135 DosFreeMem(pbh);
136 }
[350]137
[551]138 if (WinIsWindow(thab, hwnd))
139 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]140 WinDestroyMsgQueue(thmq);
[533]141 DecrThreadUsage();
[2]142 WinTerminate(thab);
[1038]143# ifdef FORTIFY
[1063]144 Fortify_LeaveScope();
145# endif
[2]146}
147
[828]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
[1038]159# ifdef FORTIFY
160 Fortify_EnterScope();
[1063]161# endif
[828]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));
[1077]186 else {
[828]187 if (*pmi->pName)
[1077]188 strcat(s, (CHAR *) pmi->pName);
[828]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 }
[1077]201 ppi = (QSPREC *) (ppi->pThrdRec + ppi->cTCB); // 22 Jun 08 SHL fixme to know why this looks odd
[828]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);
[1038]212# ifdef FORTIFY
[1063]213 Fortify_LeaveScope();
214# endif
[828]215}
216
[551]217static VOID FillKillListThread(VOID * arg)
[350]218{
[551]219 HWND hwnd = *(HWND *) arg;
220 CHAR s[1036], progname[1027], *p;
221 HAB thab;
222 HMQ thmq;
[2]223 FILE *fp;
[551]224 BOOL foundstart = FALSE;
225 INT rc;
[2]226 CHAR *startstring = "Process and Thread Information";
227 CHAR *endstring = "System Semaphore Information";
[551]228 PID pid;
229 HFILE oldstdout, newstdout;
[2]230
231 DosError(FERR_DISABLEHARDERR);
232
[1038]233# ifdef FORTIFY
234 Fortify_EnterScope();
[1063]235# endif
[2]236 thab = WinInitialize(0);
[551]237 thmq = WinCreateMsgQueue(thab, 0);
238 WinCancelShutdown(thmq, TRUE);
[533]239 IncrThreadUsage();
[2]240
[551]241 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
[1075]242 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
[551]243 unlinkf("%s", s);
244 fp = fopen(s, "w");
245 if (!fp) {
246 Win_Error(NULLHANDLE, HWND_DESKTOP, __FILE__, __LINE__,
247 GetPString(IDS_REDIRECTERRORTEXT));
[350]248 goto Abort;
249 }
250 else {
[2]251 newstdout = -1;
[551]252 rc = DosDupHandle(fileno(stdout), &newstdout);
[350]253 if (rc)
[551]254 Dos_Error(MB_CANCEL, rc, hwnd, __FILE__, __LINE__, "DosDupHandle");
[2]255 oldstdout = fileno(stdout);
[551]256 DosDupHandle(fileno(fp), &oldstdout);
[2]257 rc = runemf2(SEPARATE | INVISIBLE | FULLSCREEN | BACKGROUND | WAIT,
[1077]258 hwnd, pszSrcFile, __LINE__, NULL, NULL,
259 "%s", "PSTAT.EXE /C");
[2]260 oldstdout = fileno(stdout);
[551]261 DosDupHandle(newstdout, &oldstdout);
[2]262 DosClose(newstdout);
263 fclose(fp);
[451]264 // fixme to be gone?
[551]265 if (rc == -1) {
[2]266 saymsg(MB_CANCEL,
[551]267 hwnd,
268 GetPString(IDS_ARGHTEXT), GetPString(IDS_CANTRUNPSTATTEXT));
[2]269 goto Abort;
270 }
271 }
[551]272 fp = fopen(s, "r");
[404]273 if (fp) {
274 while (!feof(fp)) {
[551]275 strset(s, 0);
276 if (!xfgets(s, 1025, fp, pszSrcFile, __LINE__))
277 break;
[404]278 if (!foundstart) {
[551]279 if (*s == ' ' && strstr(s, startstring))
280 foundstart = TRUE;
[2]281 }
282 else {
[551]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 }
[2]304 }
305 }
306 fclose(fp);
307 }
308Abort:
[1075]309 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
310 DosForceDelete(s);
[551]311 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]312 WinDestroyMsgQueue(thmq);
[533]313 DecrThreadUsage();
[2]314 WinTerminate(thab);
[1038]315# ifdef FORTIFY
[1063]316 Fortify_LeaveScope();
317# endif
[2]318}
319
[551]320MRESULT EXPENTRY KillDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[350]321{
[551]322 SHORT sSelect;
323 PID pid;
324 static BOOL listdone;
325 static HPOINTER hptrIcon = (HPOINTER) 0;
[2]326
[551]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);
[828]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 }
[551]341 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
342 break;
[2]343
[551]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;
[2]360
[551]361 case WM_CONTROL:
362 switch (SHORT1FROMMP(mp1)) {
363 case KILL_CHECKBOX:
364 fUseQProcStat = WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX);
365 PrfWriteProfileData(fmprof,
366 FM3Str,
[1077]367 "UseQProcStat", &fUseQProcStat, sizeof(BOOL));
[551]368 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
[828]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);
[551]375 break;
[828]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;
[2]389
[551]390 case KILL_LISTBOX:
391 switch (SHORT2FROMMP(mp2)) {
392 case LN_ENTER:
393 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPFROMSHORT(TRUE), MPVOID);
394 break;
[2]395 }
[551]396 break;
[2]397
[551]398 default:
[2]399 break;
[551]400 }
401 return 0;
[2]402
[551]403 case WM_ADJUSTWINDOWPOS:
404 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
405 break;
[2]406
[551]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);
[2]428 }
[551]429 }
430 return 0;
[2]431
[551]432 case WM_COMMAND:
433 switch (SHORT1FROMMP(mp1)) {
434 case KILL_RESCAN:
435 listdone = FALSE;
436 if (fUseQProcStat) {
437 if (_beginthread(FillKillListThread2,
[829]438 NULL, 65536 + 8192, (PVOID)&hwnd) != -1)
439 DosSleep(100); // 05 Aug 07 GKY 250
[551]440 else
[1077]441 WinDismissDlg(hwnd, 0);
[551]442 }
[828]443 else if (fUseQSysState)
[1077]444 if (_beginthread(FillKillListThread3,
[828]445 NULL, 65536, (PVOID) & hwnd) != -1)
446 DosSleep(100);//05 Aug 07 GKY 250
447 else
[1077]448 WinDismissDlg(hwnd, 0);
[551]449 else {
450 if (_beginthread(FillKillListThread,
451 NULL, 65536, (PVOID) & hwnd) != -1)
[1077]452 DosSleep(100); // 05 Aug 07 GKY 250
[551]453 else
454 WinDismissDlg(hwnd, 0);
455 }
456 break;
[2]457
[551]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) {
[2]465
[551]466 CHAR s[31], *p;
467 APIRET error;
[2]468
[551]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 }
[2]497 }
[551]498 break;
[2]499
[551]500 case DID_CANCEL:
501 if (!listdone)
502 Runtime_Error(pszSrcFile, __LINE__, "busy");
503 else
504 WinDismissDlg(hwnd, 0);
[2]505 break;
506
[551]507 case IDM_HELP:
508 saymsg(MB_ENTER | MB_ICONASTERISK,
509 hwnd,
510 GetPString(IDS_KILLPROCHELPTITLETEXT),
511 GetPString(IDS_KILLPROCHELPTEXT));
[2]512 break;
[551]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;
[2]528 }
[551]529 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]530}
[793]531
532#pragma alloc_text(KILLPROC,FillKillListThread,FillKillListThread2,GetDosPgmName,KillDlgProc)
[830]533#pragma alloc_text(KILLPROC,FillKillListThread3)
Note: See TracBrowser for help on using the repository browser.