source: trunk/dll/viewinf.c@ 1036

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

Fixed early memory free; Added free_... functions to make fortify checking easier; Added fortify scopes; Delete now moves to trash can on systems with the xworkplace trash can installed.

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