source: trunk/dll/avl.c@ 1158

Last change on this file since 1158 was 1158, checked in by John Small, 17 years ago

Ticket 187: Draft 1: Functions only

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