source: trunk/dll/autoview.c@ 1344

Last change on this file since 1344 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: 24.2 KB
Line 
1
2/***********************************************************************
3
4 $Id: autoview.c 1335 2008-12-12 23:49:02Z stevenhl $
5
6 Auto view
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2008 Steven H.Levine
10
11 12 Sep 02 SHL AutoObjProc: catch buff2 overflows
12 25 Oct 02 SHL CreateHexDump: catch buffer overflow
13 12 Feb 03 SHL AutoObjProc: standardize EA math
14 23 May 05 SHL Use QWL_USER
15 29 May 06 SHL Sync with archiver.bb2 mods
16 22 Jul 06 SHL Check more run time errors
17 15 Aug 06 SHL Use Runtime_Error more
18 03 Nov 06 SHL Renames
19 30 Mar 07 GKY Remove GetPString for window class names
20 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
21 01 Sep 07 GKY Use xDosSetPathInfo to fix case where FS3 buffer crosses 64k boundry
22 27 Sep 07 SHL Correct ULONGLONG size formatting
23 22 Nov 07 GKY Use CopyPresParams to fix presparam inconsistencies in menus
24 30 Dec 07 GKY Use CommaFmtULL
25 29 Feb 08 GKY Use xfree where appropriate
26 10 Dec 08 SHL Integrate exception handler support
27
28***********************************************************************/
29
30#include <stdlib.h>
31#include <string.h>
32#include <ctype.h>
33// #include <process.h> // _beginthread
34
35#define INCL_DOS
36#define INCL_WIN
37#define INCL_GPI
38#define INCL_LONGLONG
39
40#include "fm3dll.h"
41#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
42#include "killproc.h" // Data declaration(s)
43#include "notebook.h" // Data declaration(s)
44#include "avl.h" // Data declaration(s)
45#include "inis.h" // Data declaration(s)
46#include "init.h" // Data declaration(s)
47#include "mainwnd.h" // Data declaration(s)
48#include "fm3dlg.h"
49#include "fm3str.h"
50#include "mle.h"
51#include "pathutil.h" // BldFullPathName
52#include "errutil.h" // Dos_Error...
53#include "strutil.h" // GetPString
54#include "autoview.h"
55#include "defview.h" // DefaultView
56#include "valid.h" // IsBinary
57#include "misc.h" // CheckMenu
58#include "common.h" // CommonTextButton
59#include "presparm.h" // CopyPresParams
60#include "eas.h" // DisplayEAsProc
61#include "chklist.h" // PopupMenu
62#include "wrappers.h" // xDosSetPathInfo
63#include "commafmt.h" // CommaFmtULL
64#include "fortify.h"
65#include "excputil.h" // 06 May 08 SHL added
66
67static BOOL PutComments(HWND hwnd, CHAR * filename, CHAR * comments);
68static BOOL WriteEA(HWND hwnd, CHAR * filename, CHAR * eaname, USHORT type,
69 CHAR * data);
70
71// Data definitions
72#pragma data_seg(GLOBAL1)
73HWND hwndAutoMLE;
74
75#pragma data_seg(GLOBAL2)
76ULONG AutoviewHeight;
77
78#pragma data_seg(DATA1)
79static PSZ pszSrcFile = __FILE__;
80
81static HWND AutoMenu;
82static HWND hwndAutoObj;
83static CHAR stopflag;
84static CHAR currfile[CCHMAXPATH];
85
86BOOL WriteEA(HWND hwnd, CHAR * filename, CHAR * eaname, USHORT type,
87 CHAR * data)
88{
89 /* save an ea to disk */
90
91 FEA2LIST *pfealist = NULL;
92 EAOP2 eaop;
93 APIRET rc;
94 ULONG ealen;
95 USHORT len, *num, *plen, usCodepage;
96 CHAR *p, *eaval;
97 BOOL ret = FALSE;
98
99 if (!filename || !eaname)
100 return ret;
101 usCodepage = (USHORT) WinQueryCp(WinQueryWindowULong(hwnd, QWL_HMQ));
102 len = (data) ? strlen(data) : 0;
103 ealen = sizeof(FEA2LIST) + 24L + strlen(eaname) + 1L + (ULONG) len + 4L;
104 switch (type) {
105 case EAT_EA:
106 case EAT_ASCII:
107 break;
108 case EAT_MVST:
109 if (data) {
110 ealen += sizeof(USHORT) * 5;
111 p = data;
112 while (*p) {
113 if (*p == '\n' && *(p + 1))
114 ealen += sizeof(USHORT);
115 p++;
116 }
117 }
118 break;
119 case EAT_MVMT:
120 if (data) {
121 ealen += sizeof(USHORT) * 5;
122 p = data;
123 while (*p) {
124 if (*p == '\n' && *(p + 1))
125 ealen += (sizeof(USHORT) * 2);
126 p++;
127 }
128 }
129 break;
130 default:
131 return ret;
132 }
133
134 rc = DosAllocMem((PPVOID) & pfealist, ealen, PAG_COMMIT | PAG_READ |
135 PAG_WRITE | OBJ_TILE);
136 if (rc || !pfealist)
137 Dos_Error(MB_CANCEL, rc, hwnd, pszSrcFile, __LINE__,
138 GetPString(IDS_OUTOFMEMORY));
139 else {
140 memset(pfealist, 0, ealen);
141 pfealist->list[0].cbName = strlen(eaname);
142 memcpy(pfealist->list[0].szName, eaname, pfealist->list[0].cbName + 1);
143 eaval = pfealist->list[0].szName + pfealist->list[0].cbName + 1;
144 switch (type) {
145 case EAT_EA:
146 case EAT_ASCII:
147 if (data) {
148 *(USHORT *) eaval = (USHORT) type;
149 eaval += sizeof(USHORT);
150 *(USHORT *) eaval = (USHORT) len;
151 eaval += sizeof(USHORT);
152 memcpy(eaval, data, len);
153 eaval += len;
154 }
155 break;
156 case EAT_MVST:
157 if (data) {
158 *(USHORT *) eaval = (USHORT) EAT_MVST;
159 eaval += sizeof(USHORT);
160 *(USHORT *) eaval = usCodepage;
161 eaval += sizeof(USHORT);
162 num = (USHORT *) eaval;
163 *num = 0;
164 eaval += sizeof(USHORT);
165 *(USHORT *) eaval = (USHORT) EAT_ASCII;
166 eaval += sizeof(USHORT);
167 plen = (USHORT *) eaval;
168 *plen = 0;
169 eaval += sizeof(USHORT);
170 p = data;
171 while (*p) {
172 while (*p) {
173 if (*p == '\n') {
174 p++;
175 break;
176 }
177 *eaval++ = *p++;
178 (*plen)++;
179 }
180 if (*p || *plen)
181 (*num)++;
182 if (*p) {
183 plen = (USHORT *) eaval;
184 *plen = 0;
185 eaval += sizeof(USHORT);
186 }
187 }
188 }
189 break;
190 case EAT_MVMT:
191 if (data) {
192 *(USHORT *) eaval = (USHORT) EAT_MVMT;
193 eaval += sizeof(USHORT);
194 *(USHORT *) eaval = usCodepage;
195 eaval += sizeof(USHORT);
196 num = (USHORT *) eaval;
197 *num = 0;
198 eaval += sizeof(USHORT);
199 *(USHORT *) eaval = (USHORT) EAT_ASCII;
200 eaval += sizeof(USHORT);
201 plen = (USHORT *) eaval;
202 *plen = 0;
203 eaval += sizeof(USHORT);
204 p = data;
205 while (*p) {
206 while (*p) {
207 if (*p == '\n') {
208 p++;
209 break;
210 }
211 *eaval++ = *p++;
212 (*plen)++;
213 }
214 if (*p || *plen)
215 (*num)++;
216 if (*p) {
217 *(USHORT *) eaval = (USHORT) EAT_ASCII;
218 eaval += sizeof(USHORT);
219 plen = (USHORT *) eaval;
220 *plen = 0;
221 eaval += sizeof(USHORT);
222 }
223 }
224 }
225 break;
226 }
227 pfealist->list[0].cbValue = /*(ULONG)*/ (eaval -
228 (pfealist->list[0].szName +
229 pfealist->list[0].cbName + 1));
230 memset(&eaop, 0, sizeof(eaop));
231 eaop.fpFEA2List = pfealist;
232 pfealist->cbList = 13 + (ULONG) pfealist->list[0].cbName +
233 (ULONG) pfealist->list[0].cbValue;
234 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
235 &eaop, sizeof(eaop), DSPI_WRTTHRU);
236 DosFreeMem(pfealist);
237 if (!rc)
238 ret = TRUE;
239 }
240 return ret;
241}
242
243BOOL PutComments(HWND hwnd, CHAR * filename, CHAR * comments)
244{
245 register CHAR *p;
246
247 if (comments) { /* check -- is it empty? */
248 p = comments;
249 while (*p && isspace(*p))
250 p++;
251 if (!*p)
252 comments = NULL;
253 }
254 return WriteEA(hwnd, filename, ".COMMENTS", EAT_MVMT, comments);
255}
256
257static PSZ pszBufOvfMsg = "Buffer overflow";
258
259ULONG CreateHexDump(CHAR * pchInBuf, ULONG cbInBuf,
260 CHAR * pchOutBuf, ULONG cbOutBuf,
261 ULONG cOffset, BOOL fLongAddr)
262{
263 register CHAR *pchIn, *pchReset, *pchOut;
264 register ULONG ibIn = 0, ibIn2, ibInFill;
265 ULONG cbOutLine = 6 + (fLongAddr ? 4 : 0) + 16 * 3 + 1 + 16 + 1;
266
267 if (pchInBuf && cbInBuf && pchOutBuf && cbOutBuf) {
268 pchIn = pchInBuf;
269 pchOut = pchOutBuf;
270 if (cOffset)
271 *pchOut++ = '\n';
272 while (ibIn < cbInBuf) {
273 if (pchOut - pchOutBuf + cbOutLine >= cbOutBuf) {
274 Runtime_Error(pszSrcFile, __LINE__, pszBufOvfMsg);
275 break;
276 }
277 pchReset = pchIn;
278 ibIn2 = ibIn;
279 if (fLongAddr)
280 sprintf(pchOut, "%08lx ", ibIn + cOffset);
281 else
282 sprintf(pchOut, "%04lx ", ibIn + cOffset);
283 pchOut += 6 + (fLongAddr ? 4 : 0);
284 do {
285 sprintf(pchOut, "%02x ", (UCHAR)*pchIn);
286 pchOut += 3;
287 pchIn++;
288 ibIn++;
289 } while (ibIn < cbInBuf && (ibIn % 16));
290 if (ibIn % 16) {
291 ibInFill = ibIn;
292 while (ibInFill % 16) {
293 *pchOut++ = ' ';
294 *pchOut++ = ' ';
295 *pchOut++ = ' ';
296 ibInFill++;
297 }
298 }
299 *pchOut++ = ' ';
300 pchIn = pchReset;
301 do {
302 if (*pchIn && *pchIn != '\n' && *pchIn != '\r' && *pchIn != '\t'
303 && *pchIn != '\x1a')
304 *pchOut++ = *pchIn++;
305 else {
306 *pchOut++ = '.';
307 pchIn++;
308 }
309 ibIn2++;
310 } while (ibIn2 < ibIn);
311 if (ibIn < cbInBuf)
312 *pchOut++ = '\n';
313 } // while ibIn
314 *pchOut = 0;
315 return (ULONG) (pchOut - pchOutBuf);
316 }
317 return 0L;
318}
319
320MRESULT EXPENTRY AutoObjProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
321{
322 switch (msg) {
323 case UM_LOADFILE:
324 *currfile = 0;
325 stopflag--;
326 if (fAutoView) {
327 WinSetWindowText((fComments) ? hwndAutoMLE : hwndAutoview, "");
328 MLEsetreadonly(hwndAutoMLE, TRUE);
329 MLEsetchanged(hwndAutoMLE, FALSE);
330 }
331 if (mp1) {
332 if (fAutoView) {
333 strcpy(currfile, (CHAR *)mp1);
334 if (!fComments) {
335 if (IsFile((CHAR *)mp1) == 1) {
336
337 HFILE handle;
338 ULONG olen, ibufflen, action, obufflen, l;
339 CHAR *ibuff, *obuff, *p;
340 // 06 Oct 07 SHL Protect against NTFS driver small buffer defect
341 // CHAR buffer[80];
342 CHAR buffer[4096];
343 ARC_TYPE *info;
344
345 if (!DosOpen((CHAR *)mp1,
346 &handle,
347 &action,
348 0,
349 0,
350 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
351 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT |
352 OPEN_FLAGS_RANDOMSEQUENTIAL | OPEN_SHARE_DENYNONE |
353 OPEN_ACCESS_READONLY, 0)) {
354 ibufflen = AutoviewHeight < 96 ? 512 : 3072;
355 // 06 Oct 07 SHL protect against NTFS driver small buffer defect
356 // ibuff = xmalloc(ibufflen + 2, pszSrcFile, __LINE__); // 05 Nov 07 SHL
357 ibuff = xmalloc(max(ibufflen + 2, 4096), pszSrcFile, __LINE__);
358 if (ibuff) {
359 // Depends on CreateHexDump line width
360 obufflen = (ibufflen / 16) * (6 + 3 * 16 + 1 + 16 + 1) + 80;
361 obuff = xmalloc(obufflen + 1, pszSrcFile, __LINE__);
362 if (obuff) {
363 *obuff = 0;
364 if (!DosRead(handle, ibuff, ibufflen, &ibufflen) &&
365 ibufflen)
366 {
367 ibuff[ibufflen] = 0;
368 p = obuff;
369 if (IsBinary(ibuff, ibufflen)) {
370 olen = ibufflen;
371 // Check archive
372 if (!arcsigsloaded)
373 load_archivers();
374 info = arcsighead;
375 while (info) {
376 if (info->signature && *info->signature) {
377 l = strlen(info->signature);
378 l = min(l, 79);
379 if (!DosChgFilePtr(handle, abs(info->file_offset),
380 (info->file_offset >= 0L) ?
381 FILE_BEGIN :
382 FILE_END, &ibufflen)) {
383 if (!DosRead(handle,
384 buffer,
385 l, &ibufflen) && ibufflen == l) {
386 if (!memcmp(info->signature, buffer, l))
387 break;
388 }
389 }
390 }
391 info = info->next;
392 }
393 if (info) {
394 sprintf(p, "**%s%s%s\n",
395 info->id ? info->id : "",
396 info->id ? " " : "",
397 GetPString(IDS_ARCHIVETEXT));
398 p += strlen(p);
399 }
400 CreateHexDump(ibuff, // Input buffer
401 olen, // Input buffer size
402 p, // Output buffer
403 obufflen - (p - obuff), // Output buffer size
404 0, // Address offest
405 FALSE); // Short addresses
406 }
407 else {
408 // Text file
409 register CHAR *src, *dest;
410 CHAR *endsrc;
411
412 src = ibuff;
413 dest = obuff;
414 endsrc = ibuff + ibufflen;
415 while (src < endsrc) {
416 if (dest == obuff && (*src == '\t' || *src == ' ' ||
417 *src == '\r' || *src == '\n')) {
418 src++;
419 }
420 else if (*src == '\t' || !*src) {
421 *dest = ' ';
422 dest++;
423 src++;
424 }
425 else if (*src == '\r' || *src == '\n') {
426 *dest = *src;
427 while (*(src + 1) == '\r' || *(src + 1) == '\n' ||
428 *(src + 1) == ' ' || *(src + 1) == '\t')
429 src++;
430 dest++;
431 src++;
432 }
433 else {
434 *dest = *src;
435 src++;
436 dest++;
437 }
438 } // while
439 *dest = 0;
440 if (dest - obuff >= obufflen)
441 Runtime_Error(pszSrcFile, __LINE__, pszBufOvfMsg);
442 }
443 if (*obuff)
444 WinSetWindowText(hwndAutoview, obuff);
445 }
446 free(obuff);
447 }
448 free(ibuff);
449 }
450 DosClose(handle);
451 }
452 }
453 else if (!IsFile(currfile)) {
454
455 static FILEFINDBUF4L ffb[130];
456 CHAR fullname[CCHMAXPATH + 4], szCmmaFmtFileSize[81];
457 HDIR hdir = HDIR_CREATE;
458 ULONG x, nm, ml, mc, bufflen;
459 PBYTE fb;
460 PFILEFINDBUF4L pffbFile;
461 PSZ pszBuf;
462 PSZ p;
463 APIRET rc;
464
465 BldFullPathName(fullname, currfile, "*");
466 //sprintf(fullname,
467 // "%s%s*",
468 // currfile,
469 // (currfile[strlen(currfile) - 1] == '\\') ? "" : "\\");
470 DosError(FERR_DISABLEHARDERR);
471 nm = sizeof(ffb) / sizeof(FILEFINDBUF4L);
472 if (AutoviewHeight < 96)
473 nm /= 2;
474 rc = xDosFindFirst(fullname,
475 &hdir,
476 FILE_NORMAL | FILE_DIRECTORY |
477 FILE_READONLY | FILE_ARCHIVED |
478 FILE_SYSTEM | FILE_HIDDEN,
479 &ffb, sizeof(ffb), &nm, FIL_QUERYEASIZEL);
480 if (!rc && nm) {
481 fb = (PBYTE) & ffb;
482 x = ml = 0;
483 while (x < nm) {
484 pffbFile = (PFILEFINDBUF4L) fb;
485 mc = (ULONG) pffbFile->cchName +
486 ((pffbFile->attrFile & FILE_DIRECTORY) != 0);
487 ml = max(ml, mc);
488 if (!pffbFile->oNextEntryOffset)
489 break;
490 fb += pffbFile->oNextEntryOffset;
491 x++;
492 }
493 bufflen = (CCHMAXPATHCOMP + 42) * nm;
494 pszBuf = xmalloc(bufflen, pszSrcFile, __LINE__);
495 if (pszBuf) {
496 p = pszBuf;
497 *p = 0;
498 fb = (PBYTE) & ffb;
499 x = 0;
500 while (x < nm) {
501 pffbFile = (PFILEFINDBUF4L) fb;
502 if (!(!*pffbFile->achName ||
503 (((pffbFile->attrFile & FILE_DIRECTORY) &&
504 pffbFile->achName[0] == '.') &&
505 (!pffbFile->achName[1] ||
506 (pffbFile->achName[1] == '.' &&
507 !pffbFile->achName[2]))))) {
508 CommaFmtULL(szCmmaFmtFileSize,
509 sizeof(szCmmaFmtFileSize),
510 pffbFile->cbFile + CBLIST_TO_EASIZE(pffbFile->cbList),
511 ' ');
512 sprintf(p,
513 "%s%-*.*s %-8s [%s%s%s%s] %04lu/%02lu/%02lu "
514 "%02lu:%02lu:%02lu\r",
515 pffbFile->attrFile & FILE_DIRECTORY ? "\\" : " ",
516 ml,
517 ml,
518 pffbFile->achName,
519 szCmmaFmtFileSize,
520 pffbFile->attrFile & FILE_READONLY ? "R" : "-",
521 pffbFile->attrFile & FILE_ARCHIVED ? "A" : "-",
522 pffbFile->attrFile & FILE_HIDDEN ? "H" : "-",
523 pffbFile->attrFile & FILE_SYSTEM ? "S" : "-",
524 pffbFile->fdateLastWrite.year + 1980,
525 pffbFile->fdateLastWrite.month,
526 pffbFile->fdateLastWrite.day,
527 pffbFile->ftimeLastWrite.hours,
528 pffbFile->ftimeLastWrite.minutes,
529 pffbFile->ftimeLastWrite.twosecs * 2);
530 p += strlen(p);
531 }
532 if (!pffbFile->oNextEntryOffset)
533 break;
534 fb += pffbFile->oNextEntryOffset;
535 x++;
536 } // while
537 if (p - pszBuf >= bufflen)
538 Runtime_Error(pszSrcFile, __LINE__, pszBufOvfMsg);
539 if (*pszBuf)
540 WinSetWindowText(hwndAutoview, pszBuf);
541 free(pszBuf);
542 }
543 }
544 if (!rc)
545 DosFindClose(hdir);
546 }
547 }
548 else {
549
550 APIRET rc;
551 EAOP2 eaop;
552 PGEA2LIST pgealist;
553 PFEA2LIST pfealist;
554 PGEA2 pgea;
555 PFEA2 pfea;
556 CHAR *value, *pszBuf, *p, *data;
557 USHORT len, type, plen, dlen;
558 BOOL readonly = FALSE;
559
560 pgealist = xmallocz(sizeof(GEA2LIST) + 64, pszSrcFile, __LINE__);
561 if (pgealist) {
562 pgea = &pgealist->list[0];
563 strcpy(pgea->szName, ".COMMENTS");
564 pgea->cbName = strlen(pgea->szName);
565 pgea->oNextEntryOffset = 0L;
566 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
567 pfealist = xmallocz(65536, pszSrcFile, __LINE__);
568 if (pfealist) {
569 pfealist->cbList = 65536;
570 eaop.fpGEA2List = pgealist;
571 eaop.fpFEA2List = pfealist;
572 eaop.oError = 0L;
573 rc = DosQueryPathInfo((CHAR *)mp1, FIL_QUERYEASFROMLIST,
574 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
575 free(pgealist);
576 if (!rc) {
577 pfea = &eaop.fpFEA2List->list[0];
578 if (pfea->cbName && pfea->cbValue) {
579 value = pfea->szName + pfea->cbName + 1;
580 value[pfea->cbValue] = 0;
581 if (*(USHORT *) value == EAT_MVMT) {
582 pszBuf = xmalloc(65536, pszSrcFile, __LINE__);
583 if (pszBuf) {
584 p = pszBuf;
585 *pszBuf = 0;
586 data = value + (sizeof(USHORT) * 3);
587 type = *(USHORT *) data;
588 data += sizeof(USHORT);
589 len = *(USHORT *) data;
590 data += sizeof(USHORT);
591 while ((data - value) - len < pfea->cbValue) {
592 if (type == EAT_ASCII) {
593 dlen = plen = 0;
594 while (dlen < len) {
595 if (data[dlen] == '\r') {
596 dlen++;
597 if (dlen < len && data[dlen] != '\n')
598 p[plen++] = '\n';
599 }
600 else
601 p[plen++] = data[dlen++];
602 }
603 if ((!len || !plen || p[plen - 1] != '\n') &&
604 (data - value) + len < pfea->cbValue)
605 p[plen++] = '\n';
606 p += plen;
607 *p = 0;
608 }
609 else
610 readonly = TRUE;
611 data += len;
612 if (data - value >= pfea->cbValue)
613 break;
614 type = *(USHORT *) data;
615 data += sizeof(USHORT);
616 len = *(USHORT *) data;
617 data += sizeof(USHORT);
618 } // while
619 if (p - pszBuf >= 65536) {
620 Runtime_Error(pszSrcFile, __LINE__, pszBufOvfMsg);
621 pszBuf[65535] = 0; // Try to stay alive
622 break;
623 }
624 WinSetWindowText(hwndAutoMLE, pszBuf);
625 free(pszBuf);
626 }
627 }
628 else
629 readonly = TRUE;
630 }
631 /* else EA not present */
632 MLEsetchanged(hwndAutoMLE, FALSE);
633 MLEsetreadonly(hwndAutoMLE, readonly);
634 }
635 else {
636 MLEsetchanged(hwndAutoMLE, FALSE);
637 MLEsetreadonly(hwndAutoMLE, FALSE);
638 }
639 free(pfealist);
640 }
641 }
642 }
643 }
644 free((CHAR *)mp1);
645# ifdef FORTIFY
646 Fortify_LeaveScope();
647# endif
648 }
649 return 0;
650
651 case UM_CLOSE:
652 if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
653 WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
654 WinDestroyWindow(hwnd);
655 return 0;
656 }
657 return WinDefWindowProc(hwnd, msg, mp1, mp2);
658}
659
660static VOID MakeAutoWinThread(VOID * args)
661{
662 HAB hab2;
663 HMQ hmq2;
664 HWND hwndParent = (HWND) args;
665 QMSG qmsg2;
666
667 hab2 = WinInitialize(0);
668 if (hab2) {
669# ifdef FORTIFY
670 Fortify_EnterScope();
671# endif
672 hmq2 = WinCreateMsgQueue(hab2, 128);
673 if (hmq2) {
674 DosError(FERR_DISABLEHARDERR);
675 WinRegisterClass(hab2,
676 WC_OBJECTWINDOW,
677 AutoObjProc, 0, sizeof(PVOID));
678 hwndAutoObj = WinCreateWindow(HWND_OBJECT,
679 WC_OBJECTWINDOW,
680 (PSZ) NULL,
681 0,
682 0L,
683 0L,
684 0L,
685 0L, 0L, HWND_TOP, OBJ_FRAME, NULL, NULL);
686 if (!hwndAutoObj) {
687 Win_Error2(HWND_OBJECT, HWND_DESKTOP, pszSrcFile, __LINE__,
688 IDS_WINCREATEWINDOW);
689 if (!PostMsg(hwndParent, UM_CLOSE, MPVOID, MPVOID))
690 WinSendMsg(hwndParent, UM_CLOSE, MPVOID, MPVOID);
691 }
692 else {
693 WinSetWindowULong(hwndAutoObj, QWL_USER, hwndParent);
694 priority_normal();
695 while (WinGetMsg(hab2, &qmsg2, (HWND) 0, 0, 0))
696 WinDispatchMsg(hab2, &qmsg2);
697 WinDestroyWindow(hwndAutoObj);
698 hwndAutoObj = (HWND) 0;
699 }
700 WinDestroyMsgQueue(hmq2);
701 }
702 // else
703 WinTerminate(hab2);
704# ifdef FORTIFY
705 Fortify_LeaveScope();
706# endif
707 }
708}
709
710MRESULT EXPENTRY AutoViewProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
711{
712 USHORT id = WinQueryWindowUShort(hwnd, QWS_ID);
713
714 switch (msg) {
715 case WM_CREATE:
716 {
717 MRESULT mr;
718
719 if (!hwndAutoObj) {
720 if (xbeginthread(MakeAutoWinThread,
721 65536,
722 (PVOID)hwnd,
723 pszSrcFile,
724 __LINE__) == -1) {
725 PostMsg(hwnd, UM_CLOSE, MPVOID, MPVOID);
726 }
727 }
728 mr = PFNWPStatic(hwnd, msg, mp1, mp2);
729 SetPresParams(hwnd,
730 &RGBGREY,
731 &RGBBLACK, &RGBGREY, GetPString(IDS_4SYSTEMVIOTEXT));
732 stopflag = 0;
733 return mr;
734 }
735
736 case UM_SETUP:
737 MLEsetlimit(hwnd, 32768);
738 MLEsetformat(hwnd, MLFIE_NOTRANS);
739 MLEsetchanged(hwnd, FALSE);
740 return 0;
741
742 case WM_BUTTON1DOWN:
743 {
744 SWP swp;
745
746 WinQueryWindowPos(hwnd, &swp);
747 if (SHORT2FROMMP(mp1) > swp.cy - 4) {
748
749 HPS hps = WinGetPS(WinQueryWindow(hwnd, QW_PARENT));
750 SWP swpC;
751 TRACKINFO track;
752
753 if (hps) {
754 WinQueryWindowPos(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
755 FID_CLIENT), &swpC);
756 track.cxBorder = 4;
757 track.cyBorder = 4;
758 track.cxGrid = 1;
759 track.cyGrid = 8;
760 track.cxKeyboard = 8;
761 track.rclTrack.yBottom = swp.y;
762 track.rclTrack.yTop = swp.y + swp.cy;
763 track.rclTrack.xLeft = swp.x;
764 track.rclTrack.xRight = swp.x + swp.cx;
765 track.rclBoundary = track.rclTrack;
766 track.rclBoundary.yTop = (swpC.cy + swp.y + swp.cy) - 116;
767 track.ptlMinTrackSize.x = swp.x + swp.cx;
768 track.ptlMinTrackSize.y = 36;
769 track.ptlMaxTrackSize.x = swp.x + swp.cx;
770 track.ptlMaxTrackSize.y = (swpC.cy + swp.cy) - 116;
771 track.fs = TF_TOP;
772 if (WinTrackRect(hwnd, hps, &track)) {
773 AutoviewHeight = track.rclTrack.yTop - track.rclTrack.yBottom;
774 PrfWriteProfileData(fmprof,
775 FM3Str,
776 "AutoviewHeight",
777 &AutoviewHeight, sizeof(ULONG));
778 WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
779 WM_UPDATEFRAME, MPFROMLONG(FCF_SIZEBORDER), MPVOID);
780 }
781 WinReleasePS(hps);
782 }
783 return (MRESULT) TRUE;
784 }
785 else if (id != MAIN_AUTOVIEWMLE)
786 return CommonTextButton(hwnd, msg, mp1, mp2);
787 }
788 break;
789
790 case WM_BUTTON3DOWN:
791 case WM_BUTTON1UP:
792 case WM_BUTTON3UP:
793 if (id != MAIN_AUTOVIEWMLE)
794 return CommonTextButton(hwnd, msg, mp1, mp2);
795 break;
796
797 case WM_MOUSEMOVE:
798 shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
799 {
800 SWP swp;
801
802 WinQueryWindowPos(hwnd, &swp);
803 if (SHORT2FROMMP(mp1) > swp.cy - 4) {
804 WinSetPointer(HWND_DESKTOP, hptrNS);
805 return (MRESULT) TRUE;
806 }
807 }
808 break;
809
810 case WM_PAINT:
811 PostMsg(hwnd, UM_PAINT, MPVOID, MPVOID);
812 break;
813
814 case UM_PAINT:
815 PaintRecessedWindow(hwnd, (HPS) 0, TRUE, TRUE);
816 return 0;
817
818 case WM_SETFOCUS:
819 switch (id) {
820 case MAIN_AUTOVIEWMLE:
821 if (!mp2 && !AutoMenu) {
822 if (*currfile) {
823 if (MLEgetchanged(hwnd)) {
824 CHAR *ea = xmalloc(32768, pszSrcFile, __LINE__);
825
826 if (ea) {
827 *ea = 0;
828 WinQueryWindowText(hwnd, 32767, ea);
829 PutComments(hwnd, currfile, ea);
830 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_RESCAN, 0), MPVOID);
831 free(ea);
832# ifdef FORTIFY
833 Fortify_LeaveScope();
834# endif
835 }
836 }
837 }
838 }
839 break;
840 default:
841 if (mp2)
842 PostMsg(hwnd, UM_FOCUSME, mp1, mp2);
843 break;
844 }
845 break;
846
847 case UM_FOCUSME:
848 if (mp2) {
849
850 PID pid;
851 TID tid;
852
853 if (WinQueryWindowProcess((HWND) mp1, &pid, &tid) && pid == mypid)
854 WinSetFocus(HWND_DESKTOP, (HWND) mp1);
855 else
856 WinSetFocus(HWND_DESKTOP, hwndTree);
857 }
858 return 0;
859
860 case UM_CLICKED:
861 case UM_CLICKED3:
862 if (id != MAIN_AUTOVIEWMLE) {
863 PostMsg(hwnd,
864 WM_COMMAND,
865 MPFROM2SHORT(((msg == UM_CLICKED3) ?
866 IDM_EAS : IDM_VIEWORARC), 0), MPVOID);
867 }
868 return 0;
869
870 case WM_COMMAND:
871 PostMsg(hwnd, UM_COMMAND, mp1, mp2);
872 return 0;
873
874 case UM_COMMAND:
875 switch (SHORT1FROMMP(mp1)) {
876 case IDM_RESCAN:
877 if (*currfile) {
878
879 CHAR *cf = xstrdup(currfile, pszSrcFile, __LINE__);
880
881 if (cf) {
882 stopflag++;
883 if (!PostMsg(hwndAutoObj, UM_LOADFILE, MPFROMP(cf), MPVOID))
884 free(cf);
885# ifdef FORTIFY
886 Fortify_LeaveScope();
887# endif
888 }
889 }
890 break;
891
892 case IDM_INFO:
893 DefaultView(hwnd, (HWND) 0, hwndMain, NULL, 16, currfile);
894 break;
895
896 case IDM_VIEW:
897 DefaultView(hwnd, (HWND) 0, hwndMain, NULL, 0, currfile);
898 break;
899
900 case IDM_EDIT:
901 DefaultView(hwnd, (HWND) 0, hwndMain, NULL, 8, currfile);
902 break;
903
904 case IDM_EAS:
905 {
906 char *list[2];
907
908 list[0] = currfile;
909 list[1] = NULL;
910
911 WinDlgBox(HWND_DESKTOP,
912 hwndMain,
913 DisplayEAsProc, FM3ModHandle, EA_FRAME, (PVOID) list);
914 }
915 break;
916
917 default:
918 PostMsg(hwndMain, msg, mp1, mp2);
919 }
920 return 0;
921
922 case WM_MENUEND:
923 if ((HWND) mp2 == AutoMenu) {
924 WinDestroyWindow(AutoMenu);
925 AutoMenu = (HWND) 0;
926 }
927 break;
928
929 case WM_CONTEXTMENU:
930 CheckMenu(hwnd, &AutoMenu, (id == MAIN_AUTOVIEWMLE) ?
931 IDM_AUTOVIEWMLE : IDM_AUTOVIEW);
932 WinCheckMenuItem(AutoMenu, IDM_AUTOVIEWFILE, !fComments);
933 WinCheckMenuItem(AutoMenu, IDM_AUTOVIEWCOMMENTS, fComments);
934 WinEnableMenuItem(AutoMenu, IDM_VIEW, (IsFile(currfile) == 1));
935 WinEnableMenuItem(AutoMenu, IDM_EDIT, (IsFile(currfile) == 1));
936 WinEnableMenuItem(AutoMenu, IDM_INFO, (*currfile != 0));
937 PopupMenu(hwnd, hwnd, AutoMenu);
938 break;
939
940 case UM_LOADFILE:
941 stopflag++;
942 if (!PostMsg(hwndAutoObj, msg, mp1, mp2)) {
943 xfree((CHAR *)mp1, pszSrcFile, __LINE__);
944# ifdef FORTIFY
945 Fortify_LeaveScope();
946# endif
947 }
948 return 0;
949
950 case UM_CLOSE:
951 if (AutoMenu) {
952 WinDestroyWindow(AutoMenu);
953 AutoMenu = (HWND) 0;
954 }
955 WinDestroyWindow(hwnd);
956 return 0;
957
958 case WM_CLOSE:
959 WinSendMsg(hwnd, UM_CLOSE, MPVOID, MPVOID);
960 return 0;
961
962 case WM_DESTROY:
963 if (id != MAIN_AUTOVIEWMLE) {
964 if (hwndAutoObj)
965 if (!PostMsg(hwndAutoObj, WM_CLOSE, MPVOID, MPVOID))
966 WinSendMsg(hwndAutoObj, WM_CLOSE, MPVOID, MPVOID);
967 break;
968 }
969 break;
970 }
971
972 if (id == MAIN_AUTOVIEWMLE)
973 return PFNWPMLE(hwnd, msg, mp1, mp2);
974 return PFNWPStatic(hwnd, msg, mp1, mp2);
975}
976
977#pragma alloc_text(AUTOVIEW,AutoViewProc,CreateHexDump,AutoObjProc)
978#pragma alloc_text(AUTOVIEW2,MakeAutoWinThread,WriteEA,PutComments)
Note: See TracBrowser for help on using the repository browser.