source: trunk/dll/killproc.c@ 1402

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

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.2 KB
Line 
1
2/***********************************************************************
3
4 $Id: killproc.c 1402 2009-03-14 17:17:59Z gyoung $
5
6 Kill a process
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2005, 2008 Steven H. Levine
10
11 24 May 05 SHL Rework Win_Error usage
12 14 Jul 06 SHL Use Runtime_Error
13 29 Jul 06 SHL Use xfgets
14 03 Nov 06 SHL Renames
15 03 Nov 06 SHL Count thread usage
16 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
17 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
18 02 Sep 07 GKY Replaced DosQProcStatus with DosQuerySysState to fix trap in thunk code
19 02 Sep 07 SHL Expand FillKillListThread2 stack to avoid exception in __TNK
20 16 JUL 08 GKY Use TMP directory for temp files
21 10 Dec 08 SHL Integrate exception handler support
22 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
23
24***********************************************************************/
25
26#include <stdlib.h>
27#include <string.h>
28#include <ctype.h>
29// #include <process.h>
30#include <limits.h>
31
32#define INCL_DOS
33#define INCL_DOSERRORS
34#define INCL_WIN
35#define INCL_LONGLONG // dircnrs.h
36
37#include "fm3dll.h"
38#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
39#include "init.h" // Data declaration(s)
40#include "notebook.h" // Data declaration(s)
41#include "mainwnd.h" // Data declaration(s)
42#include "fm3dlg.h"
43#include "fm3str.h"
44#include "procstat.h"
45#include "errutil.h" // Dos_Error...
46#include "strutil.h" // GetPString
47#include "pathutil.h" // BldFullPathName
48#include "killproc.h"
49#include "systemf.h" // ShowSession
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
56#include "fortify.h"
57#include "excputil.h" // xbeginthread
58
59// Data definitions
60#pragma data_seg(DATA2)
61
62static PSZ pszSrcFile = __FILE__;
63
64#pragma data_seg(GLOBAL1)
65BOOL fUseQProcStat;
66BOOL fUseQSysState;
67PID mypid;
68
69CHAR *GetDosPgmName(PID pid, CHAR * string)
70{
71 HSWITCH hs;
72 SWCNTRL swctl;
73 PCH pch;
74
75 *string = 0;
76 hs = WinQuerySwitchHandle(0, pid);
77 if (hs) {
78 WinQuerySwitchEntry(hs, &swctl);
79 pch = swctl.szSwtitle;
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 }
88 else
89 pch++;
90 }
91 strcpy(string, swctl.szSwtitle);
92 }
93 if (!*string)
94 strcpy(string, GetPString(IDS_UNKNOWNDOSPROCTEXT));
95 return string;
96}
97
98static VOID FillKillListThread2(VOID * arg)
99{
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;
108
109# ifdef FORTIFY
110 Fortify_EnterScope();
111# endif
112 thab = WinInitialize(0);
113 thmq = WinCreateMsgQueue(thab, 0);
114 WinCancelShutdown(thmq, TRUE);
115 IncrThreadUsage();
116
117 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
118 rc = DosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
119 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
120 if (rc)
121 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
122 GetPString(IDS_OUTOFMEMORY));
123 else {
124 rc = DosQProcStatus((ULONG *)pbh, USHRT_MAX);
125 if (!rc) {
126 ppi = pbh->ppi;
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));
136 else {
137 if (*pmi->szModName)
138 strcat(s, pmi->szModName);
139 else
140 strcat(s, GetPString(IDS_UNKNOWNPROCTEXT));
141 }
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
153 }
154 DosFreeMem(pbh);
155 }
156
157 if (WinIsWindow(thab, hwnd))
158 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
159 WinDestroyMsgQueue(thmq);
160 DecrThreadUsage();
161 WinTerminate(thab);
162# ifdef FORTIFY
163 Fortify_LeaveScope();
164# endif
165}
166
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
178# ifdef FORTIFY
179 Fortify_EnterScope();
180# endif
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);
187 rc = DosAllocMem((PVOID) & pbh, USHRT_MAX + 4096,
188 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE);
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));
205 else {
206 if (*pmi->pName)
207 strcat(s, (CHAR *) pmi->pName);
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 }
220 ppi = (QSPREC *) (ppi->pThrdRec + ppi->cTCB); // 22 Jun 08 SHL fixme to know why this looks odd
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);
231# ifdef FORTIFY
232 Fortify_LeaveScope();
233# endif
234}
235
236static VOID FillKillListThread(VOID * arg)
237{
238 HWND hwnd = *(HWND *) arg;
239 CHAR s[1036], progname[1027], *p;
240 HAB thab;
241 HMQ thmq;
242 FILE *fp;
243 BOOL foundstart = FALSE;
244 INT rc;
245 CHAR *startstring = "Process and Thread Information";
246 CHAR *endstring = "System Semaphore Information";
247 PID pid;
248 HFILE oldstdout, newstdout;
249
250 DosError(FERR_DISABLEHARDERR);
251
252# ifdef FORTIFY
253 Fortify_EnterScope();
254# endif
255 thab = WinInitialize(0);
256 thmq = WinCreateMsgQueue(thab, 0);
257 WinCancelShutdown(thmq, TRUE);
258 IncrThreadUsage();
259
260 WinSendDlgItemMsg(hwnd, KILL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
261 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
262 unlinkf(s);
263 fp = fopen(s, "w");
264 if (!fp) {
265 Win_Error(NULLHANDLE, HWND_DESKTOP, __FILE__, __LINE__,
266 GetPString(IDS_REDIRECTERRORTEXT));
267 goto Abort;
268 }
269 else {
270 newstdout = -1;
271 rc = DosDupHandle(fileno(stdout), &newstdout);
272 if (rc)
273 Dos_Error(MB_CANCEL, rc, hwnd, __FILE__, __LINE__, PCSZ_DOSDUPHANDLE);
274 oldstdout = fileno(stdout);
275 DosDupHandle(fileno(fp), &oldstdout);
276 rc = runemf2(SEPARATE | INVISIBLE | FULLSCREEN | BACKGROUND | WAIT,
277 hwnd, pszSrcFile, __LINE__, NULL, NULL,
278 "%s", "PSTAT.EXE /C");
279 oldstdout = fileno(stdout);
280 DosDupHandle(newstdout, &oldstdout);
281 DosClose(newstdout);
282 fclose(fp);
283 // fixme to be gone?
284 if (rc == -1) {
285 saymsg(MB_CANCEL,
286 hwnd,
287 GetPString(IDS_ARGHTEXT), GetPString(IDS_CANTRUNPSTATTEXT));
288 goto Abort;
289 }
290 }
291 fp = fopen(s, "r");
292 if (fp) {
293 while (!feof(fp)) {
294 strset(s, 0);
295 if (!xfgets(s, 1025, fp, pszSrcFile, __LINE__))
296 break;
297 if (!foundstart) {
298 if (*s == ' ' && strstr(s, startstring))
299 foundstart = TRUE;
300 }
301 else {
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 }
323 }
324 }
325 fclose(fp);
326 }
327Abort:
328 BldFullPathName(s, pTmpDir, "$PSTAT#$.#$#");
329 DosForceDelete(s);
330 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
331 WinDestroyMsgQueue(thmq);
332 DecrThreadUsage();
333 WinTerminate(thab);
334# ifdef FORTIFY
335 Fortify_LeaveScope();
336# endif
337}
338
339MRESULT EXPENTRY KillDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
340{
341 SHORT sSelect;
342 PID pid;
343 static BOOL listdone;
344 static HPOINTER hptrIcon = (HPOINTER) 0;
345
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);
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 }
360 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
361 break;
362
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;
379
380 case WM_CONTROL:
381 switch (SHORT1FROMMP(mp1)) {
382 case KILL_CHECKBOX:
383 fUseQProcStat = WinQueryButtonCheckstate(hwnd, KILL_CHECKBOX);
384 PrfWriteProfileData(fmprof,
385 FM3Str,
386 "UseQProcStat", &fUseQProcStat, sizeof(BOOL));
387 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(KILL_RESCAN, 0), MPVOID);
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);
394 break;
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;
408
409 case KILL_LISTBOX:
410 switch (SHORT2FROMMP(mp2)) {
411 case LN_ENTER:
412 WinSendDlgItemMsg(hwnd, DID_OK, BM_CLICK, MPFROMSHORT(TRUE), MPVOID);
413 break;
414 }
415 break;
416
417 default:
418 break;
419 }
420 return 0;
421
422 case WM_ADJUSTWINDOWPOS:
423 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
424 break;
425
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);
447 }
448 }
449 return 0;
450
451 case WM_COMMAND:
452 switch (SHORT1FROMMP(mp1)) {
453 case KILL_RESCAN:
454 listdone = FALSE;
455 if (fUseQProcStat) {
456 if (xbeginthread(FillKillListThread2,
457 65536 + 8192,
458 &hwnd,
459 pszSrcFile,
460 __LINE__) == -1)
461 {
462 WinDismissDlg(hwnd, 0);
463 }
464 else
465 DosSleep(100); // 05 Aug 07 GKY 250
466 }
467 else if (fUseQSysState)
468 if (xbeginthread(FillKillListThread3,
469 65536,
470 &hwnd,
471 pszSrcFile,
472 __LINE__) == -1)
473 {
474 WinDismissDlg(hwnd, 0);
475 }
476 else
477 DosSleep(100);//05 Aug 07 GKY 250
478 else {
479 if (xbeginthread(FillKillListThread,
480 65536,
481 &hwnd,
482 pszSrcFile,
483 __LINE__) == -1)
484 {
485 WinDismissDlg(hwnd, 0);
486 }
487 else
488 DosSleep(100); // 05 Aug 07 GKY 250
489 }
490 break;
491
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) {
499
500 CHAR s[31], *p;
501 APIRET error;
502
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 }
531 }
532 break;
533
534 case DID_CANCEL:
535 if (!listdone)
536 Runtime_Error(pszSrcFile, __LINE__, "busy");
537 else
538 WinDismissDlg(hwnd, 0);
539 break;
540
541 case IDM_HELP:
542 saymsg(MB_ENTER | MB_ICONASTERISK,
543 hwnd,
544 GetPString(IDS_KILLPROCHELPTITLETEXT),
545 GetPString(IDS_KILLPROCHELPTEXT));
546 break;
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;
562 }
563 return WinDefDlgProc(hwnd, msg, mp1, mp2);
564}
565
566#pragma alloc_text(KILLPROC,FillKillListThread,FillKillListThread2,GetDosPgmName,KillDlgProc)
567#pragma alloc_text(KILLPROC,FillKillListThread3)
Note: See TracBrowser for help on using the repository browser.