source: trunk/dll/avl.c@ 806

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

load_archivers: add missing close on error path

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