source: trunk/dll/avl.c@ 850

Last change on this file since 850 was 850, checked in by Steven Levine, 18 years ago

Rework large file support wrappers (ticket #41)
Add code to avoid NTFS driver small file read defect (ticket #159)
Add debug code to try to catch David's drive bar exception
Another attempt to correct newview fast viewer text load failure

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.9 KB
Line 
1
2/***********************************************************************
3
4 $Id: avl.c 850 2007-10-07 02:50:15Z stevenhl $
5
6 archiver.bb2 search, load, save and date parse
7
8 Copyright (c) 1993, 1998 M. Kimes
9 Copyright (c) 2004, 2007 Steven H.Levine
10
11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 13 Aug 05 SHL Beautify with indent
13 13 Aug 05 SHL find_type: correct no sig exists bypass logic
14 13 Aug 05 SHL SBoxDlgProc: avoid dereferencing NULL signature
15 18 Aug 05 SHL Comments
16 31 Dec 05 SHL indent -i2
17 08 Dec 05 SHL load_archivers: allow empty startlist
18 30 Dec 05 SHL load_archivers: use get_archiver_line?(), clean nits
19 29 May 06 SHL SBoxDlgProc: support move, add, delete
20 30 May 06 SHL load_archivers: add reload support
21 16 Jun 06 SHL load_archivers: support signatures containing 0s
22 26 Jun 06 SHL load_archivers: remember where comments are
23 14 Jul 06 SHL Use Runtime_Error
24 29 Jul 06 SHL Use xfgets, xfgets_bstripcr
25 15 Aug 06 SHL Use Runtime_Error more
26 01 Nov 06 SHL Turn off leftover debug code
27 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limit
28 19 Apr 07 SHL Use FreeDragInfoData
29 19 Apr 07 SHL Add more drag/drop error checking
30 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
31 25 Aug 07 SHL load_archivers: add missing close on error path
32
33***********************************************************************/
34
35#define INCL_WIN
36#define INCL_WINSTDDRAG
37#define INCL_DOS
38#define INCL_LONGLONG
39#include <os2.h>
40
41#include <stdlib.h>
42#include <stdio.h>
43#include <string.h>
44#include <share.h>
45#include <ctype.h>
46
47#include "fm3dll.h"
48#include "fm3dlg.h"
49#include "fm3str.h"
50
51static PSZ pszSrcFile = __FILE__;
52
53static void free_arc_type(ARC_TYPE * pat);
54static void fill_listbox(HWND hwnd, BOOL fShowAll, SHORT sOldSelect);
55
56//=== quick_find_type() ===
57
58ARC_TYPE *quick_find_type(CHAR * filespec, ARC_TYPE * topsig)
59{
60 ARC_TYPE *info, *found = NULL;
61 CHAR *p;
62
63 if (!arcsigsloaded)
64 load_archivers();
65 p = strrchr(filespec, '.');
66 if (p) {
67 p++;
68 info = (topsig) ? topsig : arcsighead;
69 while (info) {
70 if (info->ext && *(info->ext) && !stricmp(p, info->ext)) {
71 found = find_type(filespec, topsig);
72 break;
73 }
74 info = info->next;
75 }
76 }
77 return found;
78}
79
80//=== fill_listbox() fill or refill listbox from current archiver definitions ===
81
82static VOID fill_listbox(HWND hwnd, BOOL fShowAll, SHORT sOldSelect)
83{
84 ARC_TYPE *pat;
85 BOOL found = FALSE;
86 SHORT sSelect;
87
88 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
89
90 for (pat = arcsighead; pat; pat = pat->next) {
91 /*
92 * this inner loop tests for a dup signature entry and assures
93 * that only the entry at the top of the list gets used for
94 * conversion; editing any is okay
95 */
96 if (!fShowAll) {
97 ARC_TYPE *pat2;
98 BOOL isDup = FALSE;
99
100 for (pat2 = arcsighead;
101 pat2 && pat->siglen && pat2 != pat && !isDup; pat2 = pat2->next) {
102 isDup = pat2->siglen == pat->siglen &&
103 !memcmp(pat2->signature, pat->signature, pat->siglen);
104 } // for
105 if (isDup)
106 continue;
107 }
108
109 // If caller is editing archivers or entry useful to caller, show in listbox
110 if (fShowAll || (pat->id && pat->extract && pat->create)) {
111 sSelect = (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
112 MPFROM2SHORT(LIT_END, 0),
113 MPFROMP(pat->id ? pat->id : "?"));
114 if (!found && *szDefArc && pat->id && !strcmp(szDefArc, pat->id)) {
115 // Highlight default
116 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
117 MPFROMSHORT(sSelect), MPFROMSHORT(TRUE));
118 found = TRUE;
119 }
120 }
121 else {
122 // Complain about odd entry
123 if (!pat->id || !*pat->id) {
124 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
125 MPFROM2SHORT(LIT_END, 0),
126 MPFROMP(GetPString(IDS_UNKNOWNUNUSABLETEXT)));
127 }
128 else {
129 CHAR s[81];
130
131 sprintf(s, "%0.12s %s", pat->id, GetPString(IDS_UNUSABLETEXT));
132 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
133 MPFROM2SHORT(LIT_END, 0), MPFROMP(s));
134 }
135 }
136 } // while scanning
137
138 // Try to reselect last selection unless user wants default selection
139 if (sOldSelect != LIT_NONE && !found) {
140 SHORT sItemCount =
141 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMCOUNT,
142 MPVOID, MPVOID);
143
144 if (sOldSelect >= sItemCount)
145 sOldSelect = sItemCount - 1;
146 if (sOldSelect >= 0) {
147 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
148 MPFROMSHORT(sOldSelect), MPFROMSHORT(TRUE));
149 }
150 }
151
152 if (found)
153 PosOverOkay(hwnd);
154}
155
156ARC_TYPE *find_type(CHAR * filespec, ARC_TYPE * topsig)
157{
158 HFILE handle;
159 ULONG action;
160 ULONG len;
161 ULONG l;
162 ARC_TYPE *info;
163 CHAR *p;
164 // CHAR buffer[80];
165 CHAR buffer[4096]; // 06 Oct 07 SHL Protect against NTFS defect
166
167 if (!arcsigsloaded)
168 load_archivers();
169 if (!topsig)
170 topsig = arcsighead;
171 DosError(FERR_DISABLEHARDERR);
172 if (DosOpen(filespec,
173 &handle,
174 &action,
175 0,
176 0,
177 OPEN_ACTION_FAIL_IF_NEW |
178 OPEN_ACTION_OPEN_IF_EXISTS,
179 OPEN_FLAGS_FAIL_ON_ERROR |
180 OPEN_FLAGS_NOINHERIT |
181 OPEN_FLAGS_RANDOMSEQUENTIAL |
182 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0))
183 return NULL;
184 // Scan signatures
185 for (info = topsig; info; info = info->next) {
186 if (info->siglen == 0) {
187 // No signature -- check extension
188 p = strrchr(filespec, '.');
189 if (p) {
190 p++;
191 if (info->ext && *(info->ext) && !stricmp(p, info->ext))
192 break; // Matched
193
194 }
195 continue; // Next sig
196
197 }
198 // Try signature match
199 l = info->siglen;
200 l = min(l, 79);
201 if (!DosChgFilePtr(handle,
202 abs(info->file_offset),
203 (info->file_offset >= 0) ?
204 FILE_BEGIN : FILE_END, &len)) {
205 if (!DosRead(handle, buffer, l, &len) && len == l) {
206 if (!memcmp(info->signature, buffer, l))
207 break; // Matched
208
209 }
210 }
211 } // for
212
213 DosClose(handle); /* Either way, we're done for now */
214 return info; /* Return signature, if any */
215}
216
217//=== free_arc_type() free allocated ARC_TYPE ===
218
219static void free_arc_type(ARC_TYPE * pat)
220{
221 if (pat) {
222 xfree(pat->id);
223 xfree(pat->ext);
224 xfree(pat->list);
225 xfree(pat->extract);
226 xfree(pat->create);
227 xfree(pat->move);
228 xfree(pat->delete);
229 xfree(pat->signature);
230 xfree(pat->startlist);
231 xfree(pat->endlist);
232 xfree(pat->exwdirs);
233 xfree(pat->test);
234 xfree(pat->createrecurse);
235 xfree(pat->createwdirs);
236 xfree(pat->movewdirs);
237 free(pat);
238 }
239}
240
241static UINT cur_line_num; // Input file line counter
242
243//=== get_line_strip_comments() read line, strip comments and whitespace ===
244
245#define ARCHIVER_LINE_BYTES 256
246
247static PSZ get_line_strip_comments(PSZ pszIn, FILE * fp)
248{
249 PSZ psz = xfgets(pszIn, ARCHIVER_LINE_BYTES, fp, pszSrcFile, __LINE__);
250 PSZ psz2;
251
252 if (psz) {
253 cur_line_num++;
254 psz2 = strchr(pszIn, ';');
255 if (psz2)
256 *psz2 = 0; // Chop comment
257 bstripcr(pszIn); // Strip leading white and trailing white and CR/LF
258
259 }
260 return psz;
261}
262
263//=== get_line_strip_white() read line, strip whitespace ===
264
265static PSZ get_line_strip_white(PSZ pszIn, FILE * fp)
266{
267 PSZ psz =
268 xfgets_bstripcr(pszIn, ARCHIVER_LINE_BYTES, fp, pszSrcFile, __LINE__);
269
270 if (psz)
271 cur_line_num++;
272
273 return psz;
274}
275
276//=== load_archivers() load or reload archive definitions from archiver.bb2 ===
277
278INT load_archivers(VOID)
279{
280 FILE *fp;
281 CHAR sz[ARCHIVER_LINE_BYTES + 1];
282 CHAR *psz;
283 ARC_TYPE *pat = NULL;
284 ARC_TYPE *patLast = NULL;
285 UINT lines_per_arcsig = LINES_PER_ARCSIG;
286 UINT per_sig_comment_line_num = 0;
287 INT i;
288
289 // Free current signatures
290 if (arcsighead) {
291 for (pat = arcsighead; pat;) {
292 patLast = pat;
293 pat = pat->next;
294 free_arc_type(patLast);
295 }
296 arcsighead = NULL;
297 }
298
299 arcsigsmodified = FALSE;
300 arcsigs_header_lines = 0;
301 arcsigs_trailer_line_num = 0;
302
303 DosEnterCritSec();
304 psz = searchpath(GetPString(IDS_ARCHIVERBB2));
305 if (!psz || !*psz) {
306 DosExitCritSec();
307 return -1;
308 }
309 fp = _fsopen(psz, "r", SH_DENYWR);
310 DosExitCritSec();
311 if (!fp)
312 return -2;
313 strcpy(archiverbb2, psz); // Remember full path
314
315 cur_line_num = 0;
316
317 // Line 1 must contain number of lines per signature definition
318 if (!get_line_strip_comments(sz, fp)) {
319 fclose(fp);
320 return -3;
321 }
322 if (*sz)
323 lines_per_arcsig = atoi(sz);
324 if (!*sz || lines_per_arcsig < LINES_PER_ARCSIG) {
325 fclose(fp); // 25 Aug 07 SHL
326 return -3;
327 }
328
329 // Parse rest of file
330 // 1st non-blank line starts definition
331 // Need to determine header size and start of trailer
332
333 while (!feof(fp)) {
334 // If reading header
335 if (!arcsigs_header_lines) {
336 // Reading header - find header size and start of signtures
337 if (!get_line_strip_white(sz, fp))
338 break; // Unexpected EOF
339 if (stristr(sz, "-- Current Archivers --")) {
340 arcsigs_header_lines = cur_line_num;
341 continue;
342 }
343 if (!*sz || *sz == ';')
344 continue; // Header comment or blank line
345 else {
346 // Not a comment, must be start of signatures
347 PSZ psz2 = strchr(sz, ';');
348
349 if (psz2) {
350 *psz2 = 0; // Chop trailing comment
351 bstripcr(sz); // Strip leading white and trailing white and CR/LF
352 }
353 arcsigs_header_lines = cur_line_num - 1;
354 }
355 }
356 else {
357 // Reading defintiions
358 if (!get_line_strip_comments(sz, fp))
359 break; // EOF
360 }
361
362 // fixme to avoid allocating empty fields
363
364 // Remember start of per sig comments for next definition
365 if (per_sig_comment_line_num == 0)
366 per_sig_comment_line_num = cur_line_num;
367
368 if (*sz) {
369 // At start of defintion
370
371 pat = xmallocz(sizeof(ARC_TYPE), pszSrcFile, __LINE__);
372 if (!pat)
373 break;
374 pat->id = xstrdup(sz, pszSrcFile, __LINE__);
375
376 pat->comment_line_num = per_sig_comment_line_num;
377 pat->defn_line_num = cur_line_num;
378
379 if (!get_line_strip_comments(sz, fp)) // line 2 - extension
380 break;
381 if (*sz)
382 pat->ext = xstrdup(sz, pszSrcFile, __LINE__);
383 else
384 pat->ext = NULL;
385 if (!get_line_strip_comments(sz, fp)) // line 3 - offset to signature
386 break;
387 pat->file_offset = atol(sz);
388 if (!get_line_strip_comments(sz, fp)) // line 4 - list command
389 break;
390 if (*sz)
391 pat->list = xstrdup(sz, pszSrcFile, __LINE__);
392 else
393 pat->list = NULL;
394 if (!pat->list)
395 break; // Must have list command - fixme to complain
396 if (!get_line_strip_comments(sz, fp)) // line 5
397 break;
398 if (*sz)
399 pat->extract = xstrdup(sz, pszSrcFile, __LINE__);
400 else
401 pat->extract = NULL;
402 if (!get_line_strip_comments(sz, fp)) // line 6
403 break;
404 if (*sz)
405 pat->exwdirs = xstrdup(sz, pszSrcFile, __LINE__);
406 else
407 pat->exwdirs = NULL;
408 if (!get_line_strip_comments(sz, fp)) // line 7
409 break;
410 if (*sz)
411 pat->test = xstrdup(sz, pszSrcFile, __LINE__);
412 else
413 pat->test = NULL;
414 if (!get_line_strip_comments(sz, fp)) // line 8
415 break;
416 if (*sz)
417 pat->create = xstrdup(sz, pszSrcFile, __LINE__);
418 else
419 pat->create = NULL;
420 if (!get_line_strip_comments(sz, fp)) // line 9
421 break;
422 if (*sz)
423 pat->createwdirs = xstrdup(sz, pszSrcFile, __LINE__);
424 else
425 pat->createwdirs = NULL;
426 if (!get_line_strip_comments(sz, fp)) // line 10
427 break;
428 if (*sz)
429 pat->createrecurse = xstrdup(sz, pszSrcFile, __LINE__);
430 else
431 pat->createrecurse = NULL;
432 if (!get_line_strip_comments(sz, fp)) // line 11
433 break;
434 if (*sz)
435 pat->move = xstrdup(sz, pszSrcFile, __LINE__);
436 else
437 pat->move = NULL;
438 if (!get_line_strip_comments(sz, fp)) // line 12
439 break;
440 if (*sz)
441 pat->movewdirs = xstrdup(sz, pszSrcFile, __LINE__);
442 else
443 pat->movewdirs = NULL;
444 if (!get_line_strip_comments(sz, fp)) // line 13
445 break;
446 if (*sz)
447 pat->delete = xstrdup(sz, pszSrcFile, __LINE__);
448 else
449 pat->delete = NULL;
450 if (!get_line_strip_white(sz, fp)) // line 14
451 break;
452 i = literal(sz); // Translate \ escapes
453 if (i) {
454 pat->siglen = i;
455 pat->signature = xmalloc(i, pszSrcFile, __LINE__);
456 if (!pat->signature)
457 break;
458 memcpy(pat->signature, sz, i); // signature may not be a string
459 }
460 else {
461 pat->siglen = 0;
462 pat->signature = NULL;
463 }
464 if (!get_line_strip_white(sz, fp)) // line 15
465 break;
466 if (*sz)
467 pat->startlist = xstrdup(sz, pszSrcFile, __LINE__);
468 else
469 pat->startlist = NULL;
470 if (!get_line_strip_white(sz, fp)) // line 16
471 break;
472 if (*sz)
473 pat->endlist = xstrdup(sz, pszSrcFile, __LINE__);
474 else
475 pat->endlist = NULL;
476 if (!get_line_strip_comments(sz, fp)) // line 17
477 break;
478 pat->osizepos = atoi(sz);
479 if (!get_line_strip_comments(sz, fp)) // line 18
480 break;
481 pat->nsizepos = atoi(sz);
482 if (!get_line_strip_comments(sz, fp)) // line 19
483 break;
484 pat->fdpos = atoi(sz);
485 psz = strchr(sz, ',');
486 if (psz) {
487 psz++;
488 pat->datetype = atoi(psz);
489 }
490 if (!get_line_strip_comments(sz, fp)) // line 20
491 break;
492 pat->fdflds = atoi(sz);
493 if (!get_line_strip_comments(sz, fp)) // line 21
494 break;
495 pat->fnpos = atoi(sz);
496 psz = strchr(sz, ',');
497 if (psz) {
498 psz++;
499 pat->nameislast = (BOOL) (*psz && atol(psz) == 0) ? FALSE : TRUE;
500 psz = strchr(psz, ',');
501 if (psz) {
502 psz++;
503 pat->nameisnext = (BOOL) (*psz && atol(psz) == 0) ? FALSE : TRUE;
504 psz = strchr(psz, ',');
505 if (psz) {
506 psz++;
507 pat->nameisfirst = (BOOL) (*psz && atol(psz) == 0) ? FALSE : TRUE;
508 }
509 }
510 }
511 // Ignore unknown lines - must be newer file format
512 for (i = LINES_PER_ARCSIG; i < lines_per_arcsig; i++) {
513 if (!get_line_strip_comments(sz, fp))
514 break; // Unexpected EOF - fixme to complain
515 }
516
517 // Add to list, assume next and prev already NULL
518 if (!arcsighead)
519 arcsighead = patLast = pat;
520 else {
521 patLast->next = pat;
522 pat->prev = patLast;
523 patLast = pat;
524 }
525 pat = NULL; // Done with this defintion
526
527 arcsigs_trailer_line_num = cur_line_num + 1; // In case this is last defintion
528 per_sig_comment_line_num = 0;
529 } // if got definition
530
531 } // while more lines
532
533 fclose(fp);
534
535 free_arc_type(pat); // In case partial definition in progress
536
537 if (!arcsighead)
538 return -4;
539
540 arcsigsloaded = TRUE;
541
542 return 0;
543}
544
545#define TEST_DRAG 0 // fixme to be gone or to work
546
547static MRESULT EXPENTRY SDlgListboxSubclassProc(HWND hwnd, ULONG msg,
548 MPARAM mp1, MPARAM mp2)
549{
550 PFNWP pfnOldProc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
551
552 PDRAGITEM pDItem;
553 PDRAGINFO pDInfo;
554 BOOL ok;
555
556 static BOOL emphasized = FALSE;
557 static PSZ DRMDRF_LBOX = "<DRM_LBOX,DRF_UNKNOWN>";
558 static PSZ DRM_LBOX = "DRM_LBOX";
559
560 switch (msg) {
561 case WM_BEGINDRAG:
562 {
563 LONG cur_ndx;
564 DRAGITEM ditem;
565 DRAGIMAGE dimage;
566 HWND hwndDrop;
567
568 // fprintf(stderr, "SDlgListboxSubclassProc: BEGINDRAG\n");
569 cur_ndx = WinQueryLboxSelectedItem(hwnd);
570
571 if (cur_ndx != LIT_NONE) {
572 pDInfo = DrgAllocDraginfo(1);
573 if (pDInfo) {
574 pDInfo->usOperation = DO_DEFAULT;
575 pDInfo->hwndSource = hwnd;
576
577 memset(&ditem, 0, sizeof(DRAGITEM));
578 ditem.hwndItem = hwnd;
579 ditem.ulItemID = 1;
580 ditem.hstrType = DrgAddStrHandle(DRT_UNKNOWN);
581 ditem.hstrRMF = DrgAddStrHandle(DRMDRF_LBOX);
582 ditem.hstrContainerName = DrgAddStrHandle("");
583 ditem.hstrSourceName = DrgAddStrHandle("");
584 ditem.hstrTargetName = DrgAddStrHandle("");
585 // ditem.fsControl = 0;
586 ditem.fsSupportedOps = DO_MOVEABLE;
587
588 memset(&dimage, 0, sizeof(DRAGIMAGE));
589 dimage.cb = sizeof(DRAGIMAGE);
590 dimage.hImage = hptrFile;
591 dimage.cptl = 0;
592 dimage.fl = DRG_ICON;
593 dimage.sizlStretch.cx = 32;
594 dimage.sizlStretch.cy = 32;
595 dimage.cxOffset = -16;
596 dimage.cyOffset = 0;
597 DrgSetDragitem(pDInfo, &ditem, sizeof(DRAGITEM), 0); /* Index of DRAGITEM */
598 hwndDrop = DrgDrag(hwnd, pDInfo, &dimage, 1, /* One DRAGIMAGE */
599 VK_ENDDRAG, NULL);
600 if (!hwndDrop)
601 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__, "DrgDrag");
602
603 DrgFreeDraginfo(pDInfo);
604 // WinSetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_ACTIVATE);
605 }
606 }
607 break;
608 }
609
610 case DM_DRAGOVER:
611 ok = FALSE;
612 if (!emphasized) {
613 POINTL ptl;
614 POINTL ptl2;
615
616 emphasized = TRUE;
617 ptl.x = SHORT1FROMMP(mp2);
618 ptl.y = SHORT2FROMMP(mp2);
619 ptl2 = ptl;
620 WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl2, 1);
621 // fprintf(stderr, "DRAGOVER mapped x y %d %d to %d %d\n", ptl.x, ptl.y, ptl2.x, ptl2.y);
622 WinPostMsg(hwnd, WM_BUTTON1CLICK,
623 MPFROM2SHORT((SHORT) ptl2.x, (SHORT) ptl2.y),
624 MPFROM2SHORT(HT_NORMAL, KC_NONE));
625 // fprintf(stderr, "DRAGOVER posted 0x%x WM_BUTTON1CLICK x y %d %d\n", hwnd, ptl2.x, ptl2.y);
626 }
627 pDInfo = (PDRAGINFO) mp1; /* Get DRAGINFO pointer */
628 if (pDInfo) {
629 if (!DrgAccessDraginfo(pDInfo)) {
630 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
631 "DrgAccessDraginfo");
632 }
633 else {
634 pDItem = DrgQueryDragitemPtr(pDInfo, 0);
635 /* Check valid rendering mechanisms and data format */
636 ok = DrgVerifyRMF(pDItem, DRM_LBOX, NULL);
637 DrgFreeDraginfo(pDInfo);
638 }
639 }
640 return ok ? MRFROM2SHORT(DOR_DROP, DO_MOVE) :
641 MRFROM2SHORT(DOR_NEVERDROP, 0);
642
643 case DM_DRAGLEAVE:
644 if (emphasized) {
645 emphasized = FALSE;
646 // fixme to draw listbox item emphasized
647 // DrawTargetEmphasis(hwnd, emphasized);
648 // fprintf(stderr, "DRAGLEAVE\n");
649 fflush(stderr);
650 }
651 return 0;
652
653 case DM_DROPHELP:
654 DropHelp(mp1, mp2, hwnd, "fixme to give some help");
655 return 0;
656
657 case DM_DROP:
658 ok = FALSE;
659 if (emphasized) {
660 emphasized = FALSE;
661 // DrawTargetEmphasis(hwnd, emphasized);
662 }
663 pDInfo = (PDRAGINFO) mp1; /* Get DRAGINFO pointer */
664 if (pDInfo) {
665 if (!DrgAccessDraginfo(pDInfo)) {
666 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
667 "DrgAccessDraginfo");
668 }
669 else {
670 pDItem = DrgQueryDragitemPtr(pDInfo, 0);
671 if (!pDItem)
672 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__, "DM_DROP");
673 /* Check valid rendering mechanisms and data */
674 ok = DrgVerifyRMF(pDItem, DRM_LBOX, NULL)
675 && ~pDItem->fsControl & DC_PREPARE;
676 if (ok) {
677 // ret = FullDrgName(pDItem,buffer,buflen);
678 /* note: targetfail is returned to source for all items */
679 DrgSendTransferMsg(pDInfo->hwndSource, DM_ENDCONVERSATION,
680 MPFROMLONG(pDItem->ulItemID),
681 MPFROMLONG(DMFL_TARGETSUCCESSFUL));
682 }
683 FreeDragInfoData(hwnd, pDInfo);
684 }
685 }
686 return 0;
687 } // switch
688 return pfnOldProc ? pfnOldProc(hwnd, msg, mp1, mp2) :
689 WinDefWindowProc(hwnd, msg, mp1, mp2);
690}
691
692//=== SBoxDlgProc() Select archiver to use or edit, supports list reorder too ===
693
694static PSZ pszCantFindMsg = "Can't find item %d";
695
696MRESULT EXPENTRY SBoxDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
697{
698 ARC_TYPE **ppatReturn; // Where to return selected archiver
699 ARC_TYPE *pat;
700 SHORT sSelect;
701 SHORT sItemCount;
702 CHAR szItemText[256];
703 CHAR szPCItemText[256]; // Parent or child item text
704 SHORT i;
705 BOOL fShowAll;
706
707 static SHORT sLastSelect = LIT_NONE;
708
709 switch (msg) {
710 case WM_INITDLG:
711 if (!arcsigsloaded)
712 load_archivers();
713 if (!(ARC_TYPE **) mp2) {
714 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
715 WinDismissDlg(hwnd, 0);
716 break;
717 }
718 /* Passed arg points to where to return selected archiver definition
719 * On input arg value controls selection list content
720 * If non-NULL, dup names are suppressed
721 * If NULL, all definitions are shown
722 */
723 ppatReturn = (ARC_TYPE **) mp2;
724 fShowAll = *ppatReturn == NULL;
725 if (*ppatReturn)
726 *ppatReturn = arcsighead; // Preset to first
727 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) ppatReturn);
728 fill_listbox(hwnd, fShowAll, sLastSelect);
729
730#ifdef TEST_DRAG // fixme
731 {
732 HWND hwnd2 = WinWindowFromID(hwnd, ASEL_LISTBOX);
733 PFNWP pfn = WinSubclassWindow(hwnd2,
734 SDlgListboxSubclassProc);
735
736 WinSetWindowPtr(hwnd2, QWL_USER, (PVOID) pfn);
737 }
738#endif // TEST_DRAG fixme
739
740 break;
741
742 case WM_COMMAND:
743 ppatReturn = (ARC_TYPE **) WinQueryWindowPtr(hwnd, QWL_USER);
744 switch (SHORT1FROMMP(mp1)) {
745 case DID_OK:
746 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
747 ASEL_LISTBOX,
748 LM_QUERYSELECTION,
749 MPFROMSHORT(LIT_FIRST), MPVOID);
750 if (sSelect == LIT_NONE) {
751 Runtime_Error(pszSrcFile, __LINE__, "list empty");
752 return 0;
753 }
754 pat = arcsighead;
755 if (*ppatReturn) {
756 // If dups hidden, find archiver with matching id
757 *szItemText = 0;
758 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
759 MPFROM2SHORT(sSelect, 255), MPFROMP(szItemText));
760 if (!*szItemText)
761 pat = NULL;
762 else {
763 for (; pat; pat = pat->next) {
764 if (pat->id && !strcmp(szItemText, pat->id))
765 break; // Found it
766 }
767 }
768 }
769 else {
770 // If dups not hidden, lookup by count
771 for (i = 0; pat && i < sSelect; i++, pat = pat->next) ; // Scan
772 }
773 if (pat && (!*ppatReturn || (pat->id && pat->extract && pat->create))) {
774 *ppatReturn = pat;
775 }
776 else {
777 Runtime_Error(pszSrcFile, __LINE__, "no match");
778 // Refuse to select
779 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
780 MPFROMSHORT(LIT_NONE), FALSE);
781 return 0;
782 }
783 sLastSelect = sSelect;
784 WinDismissDlg(hwnd, TRUE);
785 return 0;
786
787 case DID_CANCEL:
788 if (arcsigsmodified) {
789 if (saymsg(MB_YESNO,
790 hwnd,
791 GetPString(IDS_ADCHANGESINMEMTEXT),
792 GetPString(IDS_ADREWRITETEXT), NullStr) == MBID_YES) {
793 PSZ ab2 = searchpath(GetPString(IDS_ARCHIVERBB2)); // Rewrite without prompting
794
795 rewrite_archiverbb2(ab2);
796 }
797 }
798 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
799 ASEL_LISTBOX,
800 LM_QUERYSELECTION,
801 MPFROMSHORT(LIT_FIRST), MPVOID);
802 if (sSelect != LIT_NONE)
803 sLastSelect = sSelect;
804 *ppatReturn = NULL;
805 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID); // fixme to understand why needed
806 return 0;
807
808 case ASEL_PB_ADD:
809 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
810 ASEL_LISTBOX,
811 LM_QUERYSELECTION,
812 MPFROMSHORT(LIT_FIRST), MPVOID);
813 if (sSelect != LIT_NONE) {
814 ARCDUMP ad;
815
816 memset(&ad, 0, sizeof(ARCDUMP));
817 ad.info = xmallocz(sizeof(ARC_TYPE), pszSrcFile, __LINE__);
818 if (ad.info) {
819 if (!WinDlgBox(HWND_DESKTOP,
820 hwnd,
821 ArcReviewDlgProc,
822 FM3ModHandle, AD_FRAME, MPFROMP(&ad))) {
823 free(ad.info);
824 }
825 else {
826 // Find self - assume all archivers listed since we are editing
827 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
828
829 if (!pat) {
830 if (arcsighead)
831 Runtime_Error(pszSrcFile, __LINE__, pszCantFindMsg, sSelect);
832 else
833 arcsighead = ad.info;
834 }
835 else {
836 // Insert before
837 if (pat->prev) {
838 ad.info->next = pat;
839 ad.info->prev = pat->prev;
840 pat->prev->next = ad.info;
841 pat->prev = ad.info;
842 }
843 else {
844 arcsighead = ad.info;
845 ad.info->next = pat;
846 pat->prev = ad.info;
847 }
848 }
849 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
850 MPFROM2SHORT(sSelect, 0),
851 MPFROMP(ad.info->id ? ad.info->id : "?"));
852 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
853 MPFROMSHORT(sSelect - 1), MPFROMSHORT(TRUE));
854 arcsigsmodified = TRUE;
855 }
856 }
857 }
858 return 0;
859 case ASEL_PB_DELETE:
860 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
861 ASEL_LISTBOX,
862 LM_QUERYSELECTION,
863 MPFROMSHORT(LIT_FIRST), MPVOID);
864 if (sSelect != LIT_NONE) {
865 // Find self - assume all archivers listed since we are editing
866 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
867
868 if (!pat)
869 Runtime_Error(pszSrcFile, __LINE__, pszCantFindMsg, sSelect);
870 else {
871 // Delete current
872 if (pat->prev) {
873 pat->prev->next = pat->next;
874 if (pat->next)
875 pat->next->prev = pat->prev;
876 }
877 else {
878 arcsighead = pat->next;
879 if (pat->next)
880 pat->next->prev = pat->prev;
881 }
882 }
883 free_arc_type(pat);
884 arcsigsmodified = TRUE;
885 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_DELETEITEM,
886 MPFROM2SHORT(sSelect, 0), MPVOID);
887 sItemCount =
888 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMCOUNT,
889 MPVOID, MPVOID);
890 if (sSelect >= sItemCount)
891 sSelect--;
892 if (sSelect >= 0) {
893 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
894 MPFROMSHORT(sSelect), MPFROMSHORT(TRUE));
895 }
896 }
897 return 0;
898 case ASEL_PB_UP:
899 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
900 ASEL_LISTBOX,
901 LM_QUERYSELECTION,
902 MPFROMSHORT(LIT_FIRST), MPVOID);
903 if (sSelect != LIT_NONE && sSelect > 0) {
904 // Find self - assume all archivers listed since we are editing
905 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
906 if (!pat || !pat->prev)
907 Runtime_Error(pszSrcFile, __LINE__, pszCantFindMsg, sSelect);
908 else {
909 ARC_TYPE *patGDad;
910 ARC_TYPE *patDad;
911 ARC_TYPE *patChild;
912
913 patChild = pat->next;
914 patDad = pat->prev;
915 patGDad = patDad->prev;
916 patDad->next = patChild;
917 if (patChild)
918 patChild->prev = patDad;
919 patDad->prev = pat;
920 pat->next = patDad;
921 if (patGDad) {
922 patGDad->next = pat;
923 pat->prev = patGDad;
924 }
925 else {
926 arcsighead = pat;
927 pat->prev = NULL;
928 }
929
930 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
931 MPFROM2SHORT(sSelect, 255), MPFROMP(szItemText));
932 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
933 MPFROM2SHORT(sSelect - 1, 255),
934 MPFROMP(szPCItemText));
935 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
936 MPFROMSHORT(sSelect), MPFROMP(szPCItemText));
937 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
938 MPFROMSHORT(sSelect - 1), MPFROMP(szItemText));
939 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
940 MPFROMSHORT(sSelect - 1), MPFROMSHORT(TRUE));
941 arcsigsmodified = TRUE;
942 }
943 }
944 return 0;
945 case ASEL_PB_DOWN:
946 sSelect =
947 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYSELECTION,
948 MPFROMSHORT(LIT_FIRST), MPVOID);
949 sItemCount =
950 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMCOUNT,
951 MPVOID, MPVOID);
952 if (sSelect != LIT_NONE && sSelect < sItemCount - 1) {
953 // Find self - assume all archivers listed since we are editing
954 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
955 if (!pat || !pat->next)
956 Runtime_Error(pszSrcFile, __LINE__, "Can't find item %d of %d",
957 sSelect, sItemCount);
958 else {
959 ARC_TYPE *patDad;
960 ARC_TYPE *patChild;
961
962 patDad = pat->prev;
963 patChild = pat->next;
964 pat->next = patChild->next;
965 patChild->next = pat;
966 pat->prev = patChild;
967 patChild->prev = patDad;
968 if (patDad) {
969 patDad->next = patChild;
970 patChild->prev = patDad;
971 }
972 else {
973 arcsighead = patChild;
974 patChild->prev = NULL;
975 }
976
977 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
978 MPFROM2SHORT(sSelect, 255), MPFROMP(szItemText));
979 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
980 MPFROM2SHORT(sSelect + 1, 255),
981 MPFROMP(szPCItemText));
982 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
983 MPFROMSHORT(sSelect), MPFROMP(szPCItemText));
984 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
985 MPFROMSHORT(sSelect + 1), MPFROMP(szItemText));
986 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
987 MPFROMSHORT(sSelect + 1), MPFROMSHORT(TRUE));
988 arcsigsmodified = TRUE;
989 }
990 }
991 return 0;
992
993 case ASEL_PB_REVERT:
994 // Reload without checking in case changed outside
995 sSelect =
996 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYSELECTION,
997 MPFROMSHORT(LIT_FIRST), MPVOID);
998 load_archivers();
999 fill_listbox(hwnd, TRUE, sSelect);
1000 return 0;
1001
1002 case IDM_HELP:
1003 if (hwndHelp) {
1004 WinSendMsg(hwndHelp, HM_DISPLAY_HELP, MPFROM2SHORT(HELP_EDITARC, 0), // fixme to be HELP_SELARC
1005 MPFROMSHORT(HM_RESOURCEID));
1006 }
1007 }
1008 return 0; // WM_COMMAND
1009
1010 case WM_CONTROL:
1011 if (SHORT1FROMMP(mp1) == ASEL_LISTBOX && SHORT2FROMMP(mp1) == LN_ENTER)
1012 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), MPVOID);
1013 return 0;
1014
1015 case WM_CLOSE:
1016 WinDismissDlg(hwnd, FALSE);
1017 return 0;
1018
1019 default:
1020 break;
1021 }
1022 return WinDefDlgProc(hwnd, msg, mp1, mp2);
1023}
1024
1025/*
1026 see archiver.tmp
1027 02-08-96 23:55 1
1028 8 Feb 96 23:55:32 2
1029 8 Feb 96 11:55p 3
1030 96-02-08 23:55:32 4
1031 31-02-98 23:55 5
1032 */
1033
1034BOOL ArcDateTime(CHAR * dt, INT type, CDATE * cdate, CTIME * ctime)
1035{
1036 INT x;
1037 BOOL ret = FALSE;
1038 CHAR *p, *pp, *pd;
1039
1040 if (dt && cdate && ctime) {
1041 memset(cdate, 0, sizeof(CDATE));
1042 memset(ctime, 0, sizeof(CTIME));
1043 if (type) {
1044 p = dt;
1045 while (*p && *p == ' ')
1046 p++;
1047 pd = dt;
1048 switch (type) {
1049 case 1:
1050 cdate->month = atoi(pd);
1051 p = to_delim(pd, "-/.");
1052 if (p) {
1053 p++;
1054 cdate->day = atoi(p);
1055 pd = p;
1056 p = to_delim(pd, "-/.");
1057 if (p) {
1058 p++;
1059 cdate->year = atoi(p);
1060 if (cdate->year > 80 && cdate->year < 1900)
1061 cdate->year += 1900;
1062 else if (cdate->year < 1900)
1063 cdate->year += 2000;
1064 ret = TRUE;
1065 p = strchr(p, ' ');
1066 if (p) {
1067 while (*p && *p == ' ')
1068 p++;
1069 ctime->hours = atoi(p);
1070 p = to_delim(pd, ":.");
1071 if (p) {
1072 p++;
1073 ctime->minutes = atoi(p);
1074 p = to_delim(pd, ":.");
1075 if (p) {
1076 p++;
1077 ctime->seconds = atoi(p);
1078 }
1079 }
1080 }
1081 }
1082 }
1083 break;
1084
1085 case 2:
1086 cdate->day = atoi(p);
1087 p = strchr(p, ' ');
1088 if (p) {
1089 p++;
1090 for (x = 0; x < 12; x++) {
1091 if (!strnicmp(p, GetPString(IDS_JANUARY + x), 3))
1092 break;
1093 }
1094 if (x < 12) {
1095 cdate->month = x;
1096 p = strchr(p, ' ');
1097 if (p) {
1098 p++;
1099 cdate->year = atoi(p);
1100 if (cdate->year > 80 && cdate->year < 1900)
1101 cdate->year += 1900;
1102 else if (cdate->year < 1900)
1103 cdate->year += 2000;
1104 ret = TRUE;
1105 p = strchr(p, ' ');
1106 if (p) {
1107 while (*p && *p == ' ')
1108 p++;
1109 ctime->hours = atoi(p);
1110 p = to_delim(pd, ":.");
1111 if (p) {
1112 p++;
1113 ctime->minutes = atoi(p);
1114 p = to_delim(pd, ":.");
1115 if (p) {
1116 p++;
1117 ctime->seconds = atoi(p);
1118 }
1119 }
1120 }
1121 }
1122 }
1123 }
1124 break;
1125
1126 case 3:
1127 cdate->day = atoi(p);
1128 p = strchr(p, ' ');
1129 if (p) {
1130 p++;
1131 for (x = 0; x < 12; x++) {
1132 if (!strnicmp(p, GetPString(IDS_JANUARY + x), 3))
1133 break;
1134 }
1135 if (x < 12) {
1136 cdate->month = x;
1137 p = strchr(p, ' ');
1138 if (p) {
1139 p++;
1140 cdate->year = atoi(p);
1141 if (cdate->year > 80 && cdate->year < 1900)
1142 cdate->year += 1900;
1143 else if (cdate->year < 1900)
1144 cdate->year += 2000;
1145 ret = TRUE;
1146 p = strchr(p, ' ');
1147 if (p) {
1148 while (*p && *p == ' ')
1149 p++;
1150 ctime->hours = atoi(p);
1151 p = to_delim(pd, ":.");
1152 if (p) {
1153 p++;
1154 pp = p;
1155 ctime->minutes = atoi(p);
1156 p = to_delim(pd, ":.");
1157 if (p) {
1158 p++;
1159 ctime->seconds = atoi(p);
1160 p += 2;
1161 if (toupper(*p) == 'P')
1162 ctime->hours += 12;
1163 }
1164 else {
1165 p = pp;
1166 p += 2;
1167 if (toupper(*p) == 'P')
1168 ctime->hours += 12;
1169 }
1170 }
1171 }
1172 }
1173 }
1174 }
1175 break;
1176
1177 case 4:
1178 cdate->year = atoi(p);
1179 if (cdate->year > 80 && cdate->year < 1900)
1180 cdate->year += 1900;
1181 else if (cdate->year < 1900)
1182 cdate->year += 2000;
1183 p = to_delim(pd, "-/.");
1184 if (p) {
1185 p++;
1186 cdate->month = atoi(p);
1187 pd = p;
1188 p = to_delim(pd, "-/.");
1189 if (p) {
1190 p++;
1191 cdate->day = atoi(p);
1192 ret = TRUE;
1193 p = strchr(p, ' ');
1194 if (p) {
1195 while (*p && *p == ' ')
1196 p++;
1197 ctime->hours = atoi(p);
1198 p = to_delim(pd, ":.");
1199 if (p) {
1200 p++;
1201 ctime->minutes = atoi(p);
1202 p = to_delim(pd, ":.");
1203 if (p) {
1204 p++;
1205 ctime->seconds = atoi(p);
1206 }
1207 }
1208 }
1209 }
1210 }
1211 break;
1212
1213 case 5:
1214 cdate->day = atoi(pd);
1215 p = to_delim(pd, "-/.");
1216 if (p) {
1217 p++;
1218 cdate->month = atoi(p);
1219 pd = p;
1220 p = to_delim(pd, "-/.");
1221 if (p) {
1222 p++;
1223 cdate->year = atoi(p);
1224 if (cdate->year > 80 && cdate->year < 1900)
1225 cdate->year += 1900;
1226 else if (cdate->year < 1900)
1227 cdate->year += 2000;
1228 ret = TRUE;
1229 p = strchr(p, ' ');
1230 if (p) {
1231 while (*p && *p == ' ')
1232 p++;
1233 ctime->hours = atoi(p);
1234 p = to_delim(pd, ":.");
1235 if (p) {
1236 p++;
1237 ctime->minutes = atoi(p);
1238 p = to_delim(pd, ":.");
1239 if (p) {
1240 p++;
1241 ctime->seconds = atoi(p);
1242 }
1243 }
1244 }
1245 }
1246 }
1247 break;
1248
1249 default:
1250 break;
1251 }
1252 }
1253 }
1254 return ret;
1255}
1256
1257#pragma alloc_text(MISC9,quick_find_type,find_type)
1258#pragma alloc_text(AVL,load_archivers, get_line_strip_comments, get_line_strip_white)
1259#pragma alloc_text(FMARCHIVE,SBoxDlgProc,SDlgListboxSubclassProc)
1260#pragma alloc_text(ARCCNRS,ArcDateTime)
Note: See TracBrowser for help on using the repository browser.