source: trunk/dll/avl.c@ 1036

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

Fixed early memory free; Added free_... functions to make fortify checking easier; Added fortify scopes; Delete now moves to trash can on systems with the xworkplace trash can installed.

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