source: trunk/dll/killproc.c@ 1188

Last change on this file since 1188 was 1188, checked in by John Small, 17 years ago

Ticket 187: Draft 2: Move remaining function declarations

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.7 KB
RevLine 
[145]1
2/***********************************************************************
3
4 $Id: killproc.c 1188 2008-09-10 21:58:30Z 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
[1188]35#include "fm3dll.h"
[2]36#include "fm3dlg.h"
37#include "fm3str.h"
[828]38#include "procstat.h"
[907]39#include "errutil.h" // Dos_Error...
40#include "strutil.h" // GetPString
[1077]41#include "pathutil.h" // BldFullPathName
[1163]42#include "killproc.h"
43#include "systemf.h" // ShowSession
[1188]44#include "common.h" // DecrThreadUsage, IncrThreadUsage
45#include "notify.h" // Notify
46#include "copyf.h" // unlinkf
47#include "wrappers.h" // xfgets
48#include "stristr.h" // stristr
49#include "misc.h" // PostMsg
[1036]50#include "fortify.h"
[2]51
52#pragma data_seg(DATA2)
53
[350]54static PSZ pszSrcFile = __FILE__;
[2]55
[551]56CHAR *GetDosPgmName(PID pid, CHAR * string)
[350]57{
[2]58 HSWITCH hs;
59 SWCNTRL swctl;
[551]60 PCH pch;
[2]61
62 *string = 0;
[551]63 hs = WinQuerySwitchHandle(0, pid);
64 if (hs) {
65 WinQuerySwitchEntry(hs, &swctl);
[2]66 pch = swctl.szSwtitle;
[551]67 while (*pch) {
68 if (*pch < 0x10)
69 if (pch != swctl.szSwtitle && *(pch - 1) == 0x20)
70 memmove(pch, pch + 1, strlen(pch));
71 else {
72 *pch = 0x20;
73 pch++;
74 }
[2]75 else
[551]76 pch++;
[2]77 }
[551]78 strcpy(string, swctl.szSwtitle);
[2]79 }
[551]80 if (!*string)
81 strcpy(string, GetPString(IDS_UNKNOWNDOSPROCTEXT));
[2]82 return string;
83}
84
[551]85static VOID FillKillListThread2(VOID * arg)
[350]86{
[551]87 HWND hwnd = *(HWND *) arg;
88 CHAR s[1036];
89 HAB thab;
90 HMQ thmq;
91 INT rc;
92 PROCESSINFO *ppi;
93 BUFFHEADER *pbh;
94 MODINFO *pmi;
[2]95
[1038]96# ifdef FORTIFY
97 Fortify_EnterScope();
[1063]98# endif
[2]99 thab = WinInitialize(0);
[551]100 thmq = WinCreateMsgQueue(thab, 0);
101 WinCancelShutdown(thmq, TRUE);
[533]102 IncrThreadUsage();
[2]103
[551]104 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
105 rc = DosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
106 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
[350]107 if (rc)
[551]108 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
109 GetPString(IDS_OUTOFMEMORY));
[350]110 else {
[829]111 rc = DosQProcStatus((ULONG *)pbh, USHRT_MAX);
[350]112 if (!rc) {
[2]113 ppi = pbh->ppi;
[551]114 while (ppi->ulEndIndicator != PROCESS_END_INDICATOR) {
115 if (ppi->pid != mypid) {
116 pmi = pbh->pmi;
117 while (pmi && ppi->hModRef != pmi->hMod)
118 pmi = pmi->pNext;
119 if (pmi) {
120 sprintf(s, "%04x ", ppi->pid);
121 if (!stricmp(pmi->szModName, "SYSINIT"))
122 GetDosPgmName(ppi->pid, s + strlen(s));
[1077]123 else {
[551]124 if (*pmi->szModName)
[1077]125 strcat(s, pmi->szModName);
[551]126 else
127 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
[350]128 }
[551]129 if (WinIsWindow(thab, hwnd)) {
130 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_INSERTITEM,
131 MPFROM2SHORT(LIT_SORTASCENDING, 0),
132 MPFROMP(s));
133 }
134 else
135 break;
136 }
137 }
138 ppi = (PPROCESSINFO) (ppi->ptiFirst + ppi->usThreadCount);
139 } // while
[2]140 }
141 DosFreeMem(pbh);
142 }
[350]143
[551]144 if (WinIsWindow(thab, hwnd))
145 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]146 WinDestroyMsgQueue(thmq);
[533]147 DecrThreadUsage();
[2]148 WinTerminate(thab);
[1038]149# ifdef FORTIFY
[1063]150 Fortify_LeaveScope();
151# endif
[2]152}
153
[828]154static VOID FillKillListThread3(VOID * arg)
155{
156 HWND hwnd = *(HWND *) arg;
157 CHAR s[1036];
158 HAB thab;
159 HMQ thmq;
160 INT rc;
161 QSPREC *ppi;
162 QSPTRREC *pbh;
163 QSLREC *pmi;
164
[1038]165# ifdef FORTIFY
166 Fortify_EnterScope();
[1063]167# endif
[828]168 thab = WinInitialize(0);
169 thmq = WinCreateMsgQueue(thab, 0);
170 WinCancelShutdown(thmq, TRUE);
171 IncrThreadUsage();
172
173 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
174 rc = DosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
175 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
176 if (rc)
177 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
178 GetPString(IDS_OUTOFMEMORY));
179 else {
180 rc = DosQuerySysState(QS_PROCESS | QS_MTE, 0, 0, 0, pbh, USHRT_MAX);
181 if (!rc) {
182 ppi = pbh->pProcRec;
183 while (ppi->RecType == 1) {
184 if (ppi->pid != mypid) {
185 pmi = pbh->pLibRec;
186 while (pmi && ppi->hMte != pmi->hmte)
187 pmi = pmi->pNextRec;
188 if (pmi) {
189 sprintf(s, "%04x ", ppi->pid);
190 if (!stricmp((CHAR *) pmi->pName, "SYSINIT"))
191 GetDosPgmName(ppi->pid, s + strlen(s));
[1077]192 else {
[828]193 if (*pmi->pName)
[1077]194 strcat(s, (CHAR *) pmi->pName);
[828]195 else
196 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
197 }
198 if (WinIsWindow(thab, hwnd)) {
199 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_INSERTITEM,
200 MPFROM2SHORT(LIT_SORTASCENDING, 0),
201 MPFROMP(s));
202 }
203 else
204 break;
205 }
206 }
[1077]207 ppi = (QSPREC *) (ppi->pThrdRec + ppi->cTCB); // 22 Jun 08 SHL fixme to know why this looks odd
[828]208 } // while
209 }
210 DosFreeMem(pbh);
211 }
212
213 if (WinIsWindow(thab, hwnd))
214 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
215 WinDestroyMsgQueue(thmq);
216 DecrThreadUsage();
217 WinTerminate(thab);
[1038]218# ifdef FORTIFY
[1063]219 Fortify_LeaveScope();
220# endif
[828]221}
222
[551]223static VOID FillKillListThread(VOID * arg)
[350]224{
[551]225 HWND hwnd = *(HWND *) arg;
226 CHAR s[1036], progname[1027], *p;
227 HAB thab;
228 HMQ thmq;
[2]229 FILE *fp;
[551]230 BOOL foundstart = FALSE;
231 INT rc;
[2]232 CHAR *startstring = "Process and Thread Information";
233 CHAR *endstring = "System Semaphore Information";
[551]234 PID pid;
235 HFILE oldstdout, newstdout;
[2]236
237 DosError(FERR_DISABLEHARDERR);
238
[1038]239# ifdef FORTIFY
240 Fortify_EnterScope();
[1063]241# endif
[2]242 thab = WinInitialize(0);
[551]243 thmq = WinCreateMsgQueue(thab, 0);
244 WinCancelShutdown(thmq, TRUE);
[533]245 IncrThreadUsage();
[2]246
[551]247 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
[1075]248 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
[551]249 unlinkf("%s", s);
250 fp = fopen(s, "w");
251 if (!fp) {
252 Win_Error(NULLHANDLE, HWND_DESKTOP, __FILE__, __LINE__,
253 GetPString(IDS_REDIRECTERRORTEXT));
[350]254 goto Abort;
255 }
256 else {
[2]257 newstdout = -1;
[551]258 rc = DosDupHandle(fileno(stdout), &newstdout);
[350]259 if (rc)
[551]260 Dos_Error(MB_CANCEL, rc, hwnd, __FILE__, __LINE__, "DosDupHandle");
[2]261 oldstdout = fileno(stdout);
[551]262 DosDupHandle(fileno(fp), &oldstdout);
[2]263 rc = runemf2(SEPARATE | INVISIBLE | FULLSCREEN | BACKGROUND | WAIT,
[1077]264 hwnd, pszSrcFile, __LINE__, NULL, NULL,
265 "%s", "PSTAT.EXE /C");
[2]266 oldstdout = fileno(stdout);
[551]267 DosDupHandle(newstdout, &oldstdout);
[2]268 DosClose(newstdout);
269 fclose(fp);
[451]270 // fixme to be gone?
[551]271 if (rc == -1) {
[2]272 saymsg(MB_CANCEL,
[551]273 hwnd,
274 GetPString(IDS_ARGHTEXT), GetPString(IDS_CANTRUNPSTATTEXT));
[2]275 goto Abort;
276 }
277 }
[551]278 fp = fopen(s, "r");
[404]279 if (fp) {
280 while (!feof(fp)) {
[551]281 strset(s, 0);
282 if (!xfgets(s, 1025, fp, pszSrcFile, __LINE__))
283 break;
[404]284 if (!foundstart) {
[551]285 if (*s == ' ' && strstr(s, startstring))
286 foundstart = TRUE;
[2]287 }
288 else {
[551]289 if (*s == ' ' && strstr(s, endstring))
290 break;
291 if (*s == ' ' && s[5] == ' ' && isxdigit(s[1]) &&
292 isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4])) {
293 p = &s[1];
294 pid = strtol(&s[1], &p, 16);
295 if (pid && pid != mypid) {
296 strcpy(progname, &s[30]);
297 p = strchr(progname, ' ');
298 if (p)
299 *p = 0;
300 if (!stristr(progname, "\\PSTAT.EXE")) {
301 sprintf(s, "%04x %s", pid, progname);
302 WinSendDlgItemMsg(hwnd,
303 KILL_LISTBOX,
304 LM_INSERTITEM,
305 MPFROM2SHORT(LIT_SORTASCENDING, 0),
306 MPFROMP(s));
307 }
308 }
309 }
[2]310 }
311 }
312 fclose(fp);
313 }
314Abort:
[1075]315 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
316 DosForceDelete(s);
[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,
[1077]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
[1077]447 WinDismissDlg(hwnd, 0);
[551]448 }
[828]449 else if (fUseQSysState)
[1077]450 if (_beginthread(FillKillListThread3,
[828]451 NULL, 65536, (PVOID) & hwnd) != -1)
452 DosSleep(100);//05 Aug 07 GKY 250
453 else
[1077]454 WinDismissDlg(hwnd, 0);
[551]455 else {
456 if (_beginthread(FillKillListThread,
457 NULL, 65536, (PVOID) & hwnd) != -1)
[1077]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.