source: trunk/dll/killproc.c@ 1075

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

Debulked TMP code; Added comments;

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