source: trunk/dll/avl.c@ 793

Last change on this file since 793 was 793, checked in by Gregg Young, 18 years ago

Move #pragma alloc_text to end for OpenWatcom compat

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