source: trunk/dll/killproc.c@ 1438

Last change on this file since 1438 was 1438, checked in by Gregg Young, 16 years ago

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

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