source: trunk/dll/avl.c@ 985

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

Update sizes dialog (ticket 44); Make max command line length user settable (ticket 199); use xfree for free in most cases (ticket 212); initial code to check for valid ini file (ticket 102); Some additional refactoring and structure rework; Some documentation updates;

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