source: trunk/dll/viewinf.c@ 1335

Last change on this file since 1335 was 1335, checked in by Steven Levine, 17 years ago

Ticket 26: Add exception handlers to all threads using xbeginthread

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.0 KB
Line 
1
2/***********************************************************************
3
4 $Id: viewinf.c 1335 2008-12-12 23:49:02Z stevenhl $
5
6 Launch inf viewer
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2004, 2008 Steven H.Levine
10
11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 17 Jul 06 SHL Use Runtime_Error
13 03 Nov 06 SHL Renames
14 03 Nov 06 SHL Count thread usage
15 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
16 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory and use BldFullPathName
17 10 Dec 08 SHL Integrate exception handler support
18
19***********************************************************************/
20
21/* offset 107: title of INF file */
22
23#include <stdlib.h>
24#include <string.h>
25#include <share.h>
26// #include <process.h> // _beginthread
27
28#define INCL_DOS
29#define INCL_WIN
30#define INCL_LONGLONG
31
32#include "fm3dll.h"
33#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
34#include "notebook.h" // Data declaration(s)
35#include "init.h" // Data declaration(s)
36#include "mainwnd.h" // Data declaration(s)
37#include "fm3dlg.h"
38#include "fm3str.h"
39#include "errutil.h" // Dos_Error...
40#include "strutil.h" // GetPString
41#include "pathutil.h" // BldFullPathName
42#include "common.h" // DecrThreadUsage, IncrThreadUsage
43#include "viewinf.h"
44#include "misc.h" // ViewHelp
45#include "strips.h" // bstrip
46#include "systemf.h" // runemf2
47#include "dirs.h" // save_dir2
48#include "wrappers.h" // xfopen
49#include "fortify.h"
50#include "excputil.h" // xbeginthread
51
52#pragma data_seg(DATA1)
53
54static PSZ pszSrcFile = __FILE__;
55
56typedef struct
57{
58 USHORT size;
59 USHORT help;
60 HWND hwnd;
61}
62DUMMY;
63
64static VOID FillListboxThread(VOID * args)
65{
66 HWND hwnd;
67 DUMMY *dummy = (DUMMY *) args;
68 HAB hab2;
69 HMQ hmq2;
70 BOOL repeating = FALSE;
71
72 if (!dummy)
73 return;
74# ifdef FORTIFY
75 Fortify_EnterScope();
76# endif
77 hwnd = dummy->hwnd;
78 hab2 = WinInitialize(0);
79 if (hab2) {
80 hmq2 = WinCreateMsgQueue(hab2, 0);
81 if (hmq2) {
82
83 CHAR *env, *p, *holdenv;
84
85 WinCancelShutdown(hmq2, TRUE);
86 IncrThreadUsage();
87 priority_normal();
88 if (!dummy->help)
89 env = getenv("BOOKSHELF");
90 else
91 env = getenv("HELP");
92 if (!env) {
93 saymsg(MB_CANCEL,
94 hwnd,
95 GetPString(IDS_SYSERRORTEXT),
96 GetPString(IDS_ENVPATHERRORTEXT),
97 (dummy->help) ? "HELP" : "BOOKSHELF",
98 (dummy->help) ? ".HLP" : ".INF");
99 goto NoEnv;
100 }
101 else {
102 holdenv = xmalloc(strlen(env) + 2, pszSrcFile, __LINE__);
103 if (holdenv) {
104 strcpy(holdenv, env);
105 Repeat:
106 if (holdenv[strlen(holdenv) - 1] != ';')
107 strcat(holdenv, ";");
108 p = strtok(holdenv, ";");
109 while (p) {
110 bstrip(p);
111 if (*p) {
112
113 CHAR mask[CCHMAXPATH], *enddir, text[CCHMAXPATH * 2];
114 FILEFINDBUF3 ffb;
115 HDIR hdir;
116 ULONG nm;
117
118 strcpy(mask, p);
119 if (mask[strlen(mask) - 1] != '\\')
120 strcat(mask, "\\");
121 enddir = mask + strlen(mask);
122 if (dummy->help)
123 strcat(mask, "*.HLP");
124 else
125 strcat(mask, "*.INF");
126 hdir = HDIR_CREATE;
127 nm = 1;
128 DosError(FERR_DISABLEHARDERR);
129 if (!DosFindFirst(mask, &hdir, FILE_NORMAL | FILE_ARCHIVED,
130 &ffb, sizeof(ffb), &nm, FIL_STANDARD)) {
131 do {
132 priority_normal();
133 strcpy(enddir, ffb.achName);
134 {
135 FILE *fp;
136 CHAR title[CCHMAXPATH];
137
138 *title = 0;
139 fp = _fsopen(mask, "rb", SH_DENYNO);
140 if (fp) {
141 fread(title, 1, 3, fp);
142 if (*title != 'H' || title[1] != 'S' || title[2] != 'P') {
143 fclose(fp);
144 goto Continue;
145 }
146 *title = 0;
147 fseek(fp, 107, SEEK_SET);
148 fread(title, 1, CCHMAXPATH - 2, fp);
149 title[CCHMAXPATH - 3] = 0;
150 bstrip(title);
151 fclose(fp);
152 }
153 p = strchr(ffb.achName, '.');
154 if (p)
155 *p = 0;
156 sprintf(text,
157 "%-10.10s %-42.42s > %s",
158 ffb.achName, title, mask);
159 }
160 if (!WinIsWindow(hab2, hwnd))
161 break;
162 WinSendDlgItemMsg(hwnd,
163 VINF_LISTBOX,
164 LM_INSERTITEM,
165 MPFROM2SHORT(LIT_SORTASCENDING, 0),
166 MPFROMP(text));
167 Continue:
168 nm = 1;
169 } while (!DosFindNext(hdir, &ffb, sizeof(ffb), &nm));
170 DosFindClose(hdir);
171 priority_normal();
172 }
173 }
174 if (!WinIsWindow(hab2, hwnd))
175 break;
176 p = strtok(NULL, ";");
177 }
178 free(holdenv);
179 NoEnv:
180 if (WinIsWindow(hab2, hwnd) && !repeating) {
181
182 ULONG size;
183 CHAR *key = "INFPaths";
184
185 if (dummy->help)
186 key = "HLPPaths";
187 repeating = TRUE;
188 if (PrfQueryProfileSize(fmprof, FM3Str, key, &size) && size) {
189 holdenv = xmalloc(size + 2, pszSrcFile, __LINE__);
190 if (holdenv) {
191 if (!PrfQueryProfileData(fmprof, FM3Str, key, holdenv, &size)) {
192 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
193 "PrfQueryProfileData");
194 free(holdenv);
195 }
196 else
197 goto Repeat;
198 }
199 }
200 }
201 }
202 }
203 WinDestroyMsgQueue(hmq2);
204 }
205 PostMsg(hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
206 DecrThreadUsage();
207 WinTerminate(hab2);
208 }
209 free(dummy);
210# ifdef FORTIFY
211 Fortify_LeaveScope();
212# endif
213}
214
215MRESULT EXPENTRY ViewInfProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
216{
217 static HWND hwndMe = (HWND) 0;
218 static BOOL help = FALSE;
219 static BOOL threaddone = TRUE;
220 static LONG ypos = 0;
221 static HPOINTER hptrIcon = (HPOINTER) 0;
222
223 switch (msg) {
224 case WM_INITDLG:
225 WinSendDlgItemMsg(hwnd, VINF_ENTRY, EM_SETTEXTLIMIT,
226 MPFROM2SHORT(1000, 0), MPVOID);
227 WinSendDlgItemMsg(hwnd, VINF_TOPIC, EM_SETTEXTLIMIT,
228 MPFROM2SHORT(CCHMAXPATH * 2, 0), MPVOID);
229 if (hwndMe) {
230 WinSetWindowPos(hwndMe, HWND_TOP, 0, 0, 0, 0, SWP_RESTORE | SWP_ZORDER |
231 SWP_ACTIVATE);
232 WinDismissDlg(hwnd, 0);
233 break;
234 }
235 help = (mp2 != (MPARAM) 0);
236 if (help) {
237
238 SWP swp;
239
240 WinQueryWindowPos(WinWindowFromID(hwnd, VINF_LISTBOX), &swp);
241 WinDestroyWindow(WinWindowFromID(hwnd, VINF_LISTBOX));
242 if (!WinCreateWindow(hwnd,
243 WC_LISTBOX,
244 (PSZ) NULL,
245 WS_VISIBLE | LS_HORZSCROLL,
246 swp.x,
247 swp.y,
248 swp.cx,
249 swp.cy,
250 hwnd, HWND_TOP, VINF_LISTBOX, NULL, NULL)) {
251 Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
252 }
253 else {
254 WinSetPresParam(WinWindowFromID(hwnd, VINF_LISTBOX),
255 PP_FONTNAMESIZE,
256 strlen(GetPString(IDS_10SYSTEMMONOTEXT)) + 1,
257 (PVOID) GetPString(IDS_10SYSTEMMONOTEXT));
258 }
259 WinSetWindowText(hwnd, GetPString(IDS_VIEWHELPFILESTEXT));
260 WinShowWindow(WinWindowFromID(hwnd, VINF_SRCH), FALSE);
261 WinShowWindow(WinWindowFromID(hwnd, VINF_FILTER), FALSE);
262 WinShowWindow(WinWindowFromID(hwnd, VINF_TOPIC), FALSE);
263 WinShowWindow(WinWindowFromID(hwnd, VINF_TOPICHDR), FALSE);
264 }
265 hptrIcon = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, VINF_FRAME);
266 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptrIcon), MPVOID);
267 hwndMe = hwnd;
268 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
269 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
270 break;
271
272 case UM_RESCAN:
273 WinSendDlgItemMsg(hwnd, VINF_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
274 {
275 DUMMY *d;
276
277 d = xmallocz(sizeof(DUMMY), pszSrcFile, __LINE__);
278 if (!d) {
279 WinDismissDlg(hwnd, 0);
280 return 0;
281 }
282 else {
283 d->size = sizeof(DUMMY);
284 d->hwnd = hwnd;
285 if (help)
286 d->help = 1;
287 if (xbeginthread(FillListboxThread,
288 65536,
289 d,
290 pszSrcFile,
291 __LINE__) == -1)
292 {
293 free(d);
294 WinDismissDlg(hwnd, 0);
295 return 0;
296 }
297 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
298 threaddone = FALSE;
299 }
300 }
301 return 0;
302
303 case UM_CONTAINER_FILLED:
304 if (!(SHORT) WinSendDlgItemMsg(hwnd,
305 VINF_LISTBOX,
306 LM_QUERYITEMCOUNT, MPVOID, MPVOID)) {
307 saymsg(MB_CANCEL,
308 hwnd,
309 GetPString(IDS_ERRORTEXT), GetPString(IDS_NOFILESFOUNDTEXT));
310 hwndMe = (HWND) 0;
311 WinDismissDlg(hwnd, 0);
312 }
313 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), TRUE);
314 threaddone = TRUE;
315 return 0;
316
317 case WM_CONTROL:
318 switch (SHORT1FROMMP(mp1)) {
319 case VINF_LISTBOX:
320 switch (SHORT2FROMMP(mp1)) {
321 case LN_ENTER:
322 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), MPVOID);
323 break;
324 }
325 break;
326 case VINF_ENTRY:
327 switch (SHORT2FROMMP(mp1)) {
328 case EN_CHANGE:
329 {
330 SHORT sSelect;
331 CHAR szBuffer[CCHMAXPATH];
332
333 WinQueryDlgItemText(hwnd, VINF_ENTRY, CCHMAXPATH, szBuffer);
334 bstrip(szBuffer);
335 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
336 VINF_LISTBOX,
337 LM_SEARCHSTRING,
338 MPFROM2SHORT(LSS_SUBSTRING,
339 LIT_FIRST),
340 MPFROMP(szBuffer));
341 if (sSelect >= 0)
342 WinSendDlgItemMsg(hwnd,
343 VINF_LISTBOX,
344 LM_SETTOPINDEX,
345 MPFROM2SHORT(sSelect, 0), MPVOID);
346 }
347 break;
348 }
349 break;
350 }
351 return 0;
352
353 case WM_ADJUSTWINDOWPOS:
354 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
355 break;
356
357 case UM_STRETCH:
358 {
359 SWP swpC, swp;
360
361 WinQueryWindowPos(hwnd, &swp);
362 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
363 WinQueryWindowPos(WinWindowFromID(hwnd, VINF_LISTBOX), &swpC);
364 if (!ypos)
365 ypos = swpC.y;
366 WinSetWindowPos(WinWindowFromID(hwnd, VINF_LISTBOX), HWND_TOP,
367 SysVal(SV_CXSIZEBORDER),
368 ypos,
369 swp.cx - (SysVal(SV_CXSIZEBORDER) * 2),
370 (swp.cy - ypos) - (SysVal(SV_CYTITLEBAR) +
371 SysVal(SV_CYSIZEBORDER)),
372 SWP_MOVE | SWP_SIZE);
373 }
374 }
375 return 0;
376
377 case WM_COMMAND:
378 switch (SHORT1FROMMP(mp1)) {
379 case VINF_RESCAN:
380 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
381 break;
382
383 case VINF_SRCH:
384 {
385 SHORT sSelect, sLast = LIT_FIRST;
386 CHAR szBuffer[CCHMAXPATH];
387
388 *szBuffer = 0;
389 WinQueryDlgItemText(hwnd, VINF_ENTRY, CCHMAXPATH, szBuffer);
390 rstrip(szBuffer);
391 if (!*szBuffer) {
392 sLast = (SHORT) WinSendDlgItemMsg(hwnd,
393 VINF_LISTBOX,
394 LM_QUERYITEMCOUNT,
395 MPVOID, MPVOID);
396 for (sSelect = 0; sSelect < sLast; sSelect++)
397 WinSendDlgItemMsg(hwnd,
398 VINF_LISTBOX,
399 LM_SELECTITEM,
400 MPFROM2SHORT(sSelect, 0),
401 MPFROM2SHORT(FALSE, 0));
402 break;
403 }
404 for (;;) {
405 sSelect = (SHORT) WinSendDlgItemMsg(hwnd, VINF_LISTBOX,
406 LM_SEARCHSTRING,
407 MPFROM2SHORT(LSS_SUBSTRING,
408 sLast),
409 MPFROMP(szBuffer));
410 if (sSelect <= sLast)
411 break;
412 if (sSelect >= 0)
413 WinSendDlgItemMsg(hwnd,
414 VINF_LISTBOX,
415 LM_SELECTITEM,
416 MPFROM2SHORT(sSelect, 0),
417 MPFROM2SHORT(TRUE, 0));
418 else
419 break;
420 sLast = sSelect;
421 }
422 }
423 break;
424
425 case VINF_FILTER:
426 {
427 SHORT sSelect, sTotal;
428
429 sTotal = (SHORT) WinSendDlgItemMsg(hwnd,
430 VINF_LISTBOX,
431 LM_QUERYITEMCOUNT, MPVOID, MPVOID);
432 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
433 VINF_LISTBOX,
434 LM_QUERYSELECTION,
435 MPFROM2SHORT(LIT_FIRST, 0),
436 MPVOID);
437 if (sSelect == LIT_NONE) {
438 DosBeep(50, 100);
439 break;
440 }
441#ifdef BUGFIXED
442 sSelect = 0;
443 while (sSelect < sTotal) {
444 if (!WinSendDlgItemMsg(hwnd,
445 VINF_LISTBOX,
446 LM_SELECTITEM,
447 MPFROM2SHORT(sSelect, 0),
448 MPFROM2SHORT(FALSE, 0))) {
449 WinSendDlgItemMsg(hwnd,
450 VINF_LISTBOX,
451 LM_DELETEITEM,
452 MPFROM2SHORT(sSelect, 0), MPVOID);
453 sTotal--;
454 }
455 else
456 sSelect++;
457 }
458#else // !BUGIFIXED
459 for (sSelect = 0; sSelect < sTotal; sSelect++)
460 WinSendDlgItemMsg(hwnd,
461 VINF_LISTBOX,
462 LM_SETITEMHANDLE,
463 MPFROM2SHORT(sSelect, 0), MPVOID);
464 sSelect = LIT_FIRST;
465 for (;;) {
466 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
467 VINF_LISTBOX,
468 LM_QUERYSELECTION,
469 MPFROM2SHORT(sSelect, 0),
470 MPVOID);
471 if (sSelect >= 0)
472 WinSendDlgItemMsg(hwnd,
473 VINF_LISTBOX,
474 LM_SETITEMHANDLE,
475 MPFROM2SHORT(sSelect, 0), MPFROMLONG(1));
476 else
477 break;
478 }
479 for (sSelect = 0; sSelect < sTotal; sSelect++)
480 WinSendDlgItemMsg(hwnd,
481 VINF_LISTBOX,
482 LM_SELECTITEM,
483 MPFROM2SHORT(sSelect, 0), MPFROM2SHORT(FALSE, 0));
484 sSelect = 0;
485 while (sSelect < sTotal) {
486 if (!WinSendDlgItemMsg(hwnd,
487 VINF_LISTBOX,
488 LM_QUERYITEMHANDLE,
489 MPFROM2SHORT(sSelect, 0), MPVOID)) {
490 WinSendDlgItemMsg(hwnd,
491 VINF_LISTBOX,
492 LM_DELETEITEM,
493 MPFROM2SHORT(sSelect, 0), MPVOID);
494 sTotal--;
495 }
496 else
497 sSelect++;
498 }
499#endif // BUGFIXED
500 }
501 break;
502
503 case VINF_DIRS:
504 {
505 CHAR szBuffer[1001], *key = "INFPaths";
506
507 if (help)
508 key = "HLPPaths";
509 *szBuffer = 0;
510 WinQueryDlgItemText(hwnd, VINF_ENTRY, 1000, szBuffer);
511 bstrip(szBuffer);
512 PrfWriteProfileData(fmprof,
513 FM3Str,
514 key,
515 (*szBuffer) ? szBuffer : NULL, strlen(szBuffer));
516 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
517 }
518 break;
519
520 case DID_CANCEL:
521 hwndMe = (HWND) 0;
522 WinDismissDlg(hwnd, 0);
523 break;
524
525 case DID_OK:
526 {
527 SHORT sSelect;
528 CHAR text[CCHMAXPATH * 2], filename[CCHMAXPATH], *p;
529 FILE *fp;
530 BOOL notfirst = FALSE;
531
532 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
533 VINF_LISTBOX,
534 LM_QUERYSELECTION,
535 MPFROM2SHORT(LIT_FIRST, 0),
536 MPVOID);
537 if (sSelect < 0) {
538 DosBeep(50, 100);
539 }
540 else {
541 if (help) {
542 *text = 0;
543 WinSendDlgItemMsg(hwnd,
544 VINF_LISTBOX,
545 LM_QUERYITEMTEXT,
546 MPFROM2SHORT(sSelect, CCHMAXPATH),
547 MPFROMP(text));
548 p = strchr(text, '>');
549 if (!p) {
550 DosBeep(50, 100);
551 break;
552 }
553 p++;
554 bstrip(p);
555 if (!*p)
556 DosBeep(50, 100);
557 else
558 ViewHelp(p);
559 break;
560 }
561 BldFullPathName(filename, pFM2SaveDirectory, "FM2VINF.CMD");
562 fp = xfopen(filename, "w", pszSrcFile, __LINE__);
563 if (fp) {
564 fprintf(fp, "@ECHO OFF\nSET FM2REF=");
565 while (sSelect >= 0) {
566 *text = 0;
567 WinSendDlgItemMsg(hwnd,
568 VINF_LISTBOX,
569 LM_QUERYITEMTEXT,
570 MPFROM2SHORT(sSelect,
571 CCHMAXPATH), MPFROMP(text));
572 p = strchr(text, '>');
573 if (p) {
574 p++;
575 bstrip(p);
576 if (*p) {
577 if (notfirst)
578 fprintf(fp, "+");
579 notfirst = TRUE;
580 fprintf(fp, "%s", p);
581 }
582 }
583 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
584 VINF_LISTBOX,
585 LM_QUERYSELECTION,
586 MPFROM2SHORT(sSelect, 0),
587 MPVOID);
588 } // while
589 *text = 0;
590 WinQueryDlgItemText(hwnd, VINF_TOPIC, CCHMAXPATH * 2, text);
591 bstrip(text);
592 fprintf(fp,
593 "\nVIEW FM2REF%s%s\nDEL %s\n",
594 (*text) ? " " : NullStr, text, filename);
595 fclose(fp);
596 runemf2(SEPARATE | WINDOWED | MINIMIZED |
597 BACKGROUND | INVISIBLE,
598 hwnd, pszSrcFile, __LINE__,
599 NULL, NULL, "%s /C %s", GetCmdSpec(FALSE), filename);
600 }
601 }
602 }
603 break;
604
605 case IDM_HELP:
606 if (hwndHelp) {
607 if (help)
608 WinSendMsg(hwndHelp,
609 HM_DISPLAY_HELP,
610 MPFROM2SHORT(HELP_VIEWHELPS, 0),
611 MPFROMSHORT(HM_RESOURCEID));
612 else
613 WinSendMsg(hwndHelp,
614 HM_DISPLAY_HELP,
615 MPFROM2SHORT(HELP_VIEWINF, 0),
616 MPFROMSHORT(HM_RESOURCEID));
617 }
618 break;
619 }
620 return 0;
621
622 case WM_CLOSE:
623 if (!threaddone)
624 return 0;
625 break;
626
627 case WM_DESTROY:
628 if (hwndMe == hwnd) {
629 hwndMe = (HWND) 0;
630 if (hptrIcon)
631 WinDestroyPointer(hptrIcon);
632 hptrIcon = (HPOINTER) 0;
633 }
634 break;
635 }
636 return WinDefDlgProc(hwnd, msg, mp1, mp2);
637}
638
639#pragma alloc_text(VIEWINFS,FillListboxThread,ViewInfProc)
Note: See TracBrowser for help on using the repository browser.