source: trunk/dll/killproc.c@ 1073

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

Fm2 uses TMP/TEMP directory if set for temporary files and directories. Ticket 20

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