source: trunk/dll/arccnrs.c@ 1878

Last change on this file since 1878 was 1878, checked in by Gregg Young, 10 years ago

Remove some dead code and comments source files starting with A-D

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 108.8 KB
Line 
1
2/***********************************************************************
3
4 $Id: arccnrs.c 1878 2015-10-11 22:24:39Z gyoung $
5
6 Archive containers
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2013 Steven H. Levine
10
11 11 Jun 02 SHL Ensure archive name not garbage
12 22 May 03 SHL ArcObjWndProc: fix UM_RESCAN now that we understand it
13 01 Aug 04 SHL Rework lstrip/rstrip usage
14 23 May 05 SHL Use QWL_USER
15 25 May 05 SHL Rename comnam to szCommonName and fix typo
16 25 May 05 SHL Use ULONGLONG and CommaFmtULL
17 05 Jun 05 SHL Drop obsolete, localize
18 05 Jun 05 SHL Correct last sort logic
19 05 Jun 05 SHL Use QWL_USER
20 22 Jun 05 SHL ArcSort: correct typo in last sort fix
21 13 Aug 05 SHL FillArcCnr: optimize
22 08 Dec 05 SHL FillArcCnr: allow list start and end markers to be empty (i.e. tar)
23 08 Dec 05 SHL ArcCnrWndProc: suppress IDM_EXTRACT if no simple extract (i.e. tar)
24 30 Dec 05 SHL ArcCnrWndProc: correct date/time column display setup
25 29 May 06 SHL Comments
26 14 Jul 06 SHL Use Runtime_Error
27 26 Jul 06 SHL Correct SelectAll usage
28 29 Jul 06 SHL Use xfgets_bstripcr
29 31 Jul 06 SHL Lower priority for archives with more than 1000 entries
30 02 Aug 06 SHL Add logic to stop processing large archives
31 23 Aug 06 SHL Integrate John Small's switch list title logic
32 03 Nov 06 SHL Renames
33 14 Mar 07 SHL ArcObjWndProc/UM_ENTER: delay before starting viewer
34 30 Mar 07 GKY Remove GetPString for window class names
35 06 Apr 07 GKY Work around PM DragInfo and DrgFreeISH limit
36 06 Apr 07 GKY Add some error checking in drag/drop
37 20 Apr 07 SHL Sync with NumItemsToUnhilite mods
38 21 Apr 07 GKY Find FM2Utils by path or utils directory
39 12 May 07 SHL Use dcd->ulItemsToUnHilite; sync with UnHilite arg mods
40 10 Jun 07 GKY Add CheckPmDrgLimit including IsFm2Window as part of work around PM drag limit
41 16 Jun 07 SHL Use DosQueryAppType not DosQAppType
42 02 Aug 07 SHL Sync with ARCITEM mods
43 06 Aug 07 SHL Use BldFullPathName and BldQuotedFileName
44 06 Aug 07 SHL Move BldQuotedFileName and BldQuotedFullPathNamehere
45 to be near primary caller
46 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
47 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
48 26 Aug 07 GKY DosSleep(1) in loops changed to (0)
49 22 Nov 07 GKY Use CopyPresParams to fix presparam inconsistencies in menus
50 30 Dec 07 GKY Use TestCDates for sort by date
51 10 Jan 08 SHL Sync with CfgDlgProc mods
52 10 Feb 08 GKY Implement bubble help for bitmap menu items
53 15 Feb 08 SHL Sync with settings menu rework
54 29 Feb 08 GKY Use xfree where appropriate
55 14 Jul 08 JBS Ticket 126: Add support for WPS open default & open settings in arccnrs
56 16 Jul 08 GKY Fix trap on viewing multiple files from an archive (misplaced free)
57 16 Jul 08 GKY Use TMP directory for temp files if present. Use MakeTempName
58 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory
59 25 Aug 08 GKY Check TMP directory space warn if lee than 5 MiB prevent archiver from opening if
60 less than 10 KiB (It hangs and can't be closed)
61 08 Nov 08 GKY Add WaitChildThread to fix hang caused by viewer trying to open a file before
62 the archiver process closes. (Ticket 58)
63 23 Nov 08 JBS Ticket 284: Support archivers with no Start or End of list strings
64 29 Nov 08 GKY Add flag to tell CheckListProc file is in an archive so it won't try to open it.
65 29 Nov 08 GKY Remove or replace with a mutex semaphore DosEnterCriSec where appropriate.
66 30 Nov 08 GKY Add the option of creating a subdirectory from the arcname
67 for the extract path to arc container.
68 02 Dec 08 JBS Ticket 284: Changed string indicating no Start/End of list strings.
69 03 Dec 08 GKY Subdirectory from the arcname for the extract path only created if an "extract"
70 menu option is selected.
71 10 Dec 08 SHL Integrate exception handler support
72 07 Feb 09 GKY Eliminate Win_Error2 by moving function names to PCSZs used in Win_Error
73 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
74 08 Mar 09 GKY Renamed commafmt.h i18nutil.h
75 08 Mar 09 GKY Additional strings move to PCSZs in init.c
76 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
77 12 Mar 09 SHL Use common SearchContainer
78 13 Dec 09 GKY Fixed separate paramenters. Please note that appname should be used in
79 profile calls for user settings that work and are setable in more than one
80 miniapp; FM3Str should be used for setting only relavent to FM/2 or that
81 aren't user settable; realappname should be used for setting applicable to
82 one or more miniapp but not to FM/2
83 17 Jan 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
84 15 Apr 10 JBS Ticket 422: Stop hang when open archive gets deleted or moved
85 23 Oct 10 GKY Add ForwardslashToBackslash function to streamline code
86 20 Nov 10 GKY Check that pTmpDir IsValid and recreate if not found; Fixes hangs caused
87 by temp file creation failures.
88 13 Aug 11 GKY Change to Doxygen comment format
89 30 Jul 13 GKY Changes to allow 7z archiver to work with AV.
90 05 Aug 13 GKY Changes to allow Lzip to work with AV
91 11 Aug 13 GKY Removed code that attempted to use the archive name as the extract directory
92 It was never fully implemented and doesn't make sense for the container.
93 09 Feb 14 GKY Fix trap on opening a file without an extention
94 22 Feb 14 GKY Fix warn readonly yes don't ask to work when recursing directories.
95 28 Apr 14 JBS Ticket #522: Ensure use of wrapper functions where needed
96 01 Mar 14 GKY Fixed error checking in FillArcCnr only to report missing archivers after
97 all entries have been tried. Added a check b/gzip exes for TAR.B/GZ archives.
98 Use the test archive string from the first working archive description.
99 Enhance the error message. Ticket 502
100 01 Mar 14 GKY Fix a trap caused by selecting "print" from the arccontainer menu. Ticket 525
101 01 Mar 14 GKY Fix the problem with copying text from the test archive window by launching
102 it in a command shell (i.e. comspec /k archiver -t archive) Ticket 503
103 02 Mar 14 GKY Fixed typo that reversed the function of the saymsg dialog g/bzip check.
104 Added option to suppress message regarding missing bzip2.exe
105 or gzip.exe on TAR.B/GZ archives.
106 06 Apr 14 GKY Removed all BZ/GZ checks
107 28 Jun 14 GKY Fix errors identified with CPPCheck; Fix retry to create workdir code
108 12 Aug 15 JBS Ticket #522: Ensure no "highmem-unsafe" functions are called directly.
109 Calls to unsafe Dos... functions have been changed to call the wrapped xDos... functions.
110
111***********************************************************************/
112
113#include <stdlib.h> // free..
114#include <string.h>
115#include <ctype.h>
116#include <direct.h> // rmdir
117#include <share.h> // SH_DENYWR
118#include <limits.h> // ULONG_MAX
119
120#if 0
121#include <malloc.h> // _heapchk
122#endif
123
124#define INCL_DOS
125#define INCL_DOSERRORS
126#define INCL_WIN
127#define INCL_LONGLONG
128
129#include "fm3dll.h"
130#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
131#include "arccnrs.h"
132#include "makelist.h" // Typedef
133#include "colors.h" // Typedef
134#include "mainwnd2.h" // Data declaration(s)
135#include "grep.h" // Data declaration(s)
136#include "dircnrs.h" // Data declaration(s)
137#include "info.h" // Data declaration(s)
138#include "init.h" // Data declaration(s)
139#include "fm3dlg.h"
140#include "fm3str.h"
141#include "mle.h"
142#include "pathutil.h" // BldFullPathName
143#include "filldir.h" // EmptyCnr...
144#include "errutil.h" // Dos_Error...
145#include "strutil.h" // GetPString
146#include "notebook.h" // CfgDlgProc
147#include "worker.h" // Action, MassAction
148#include "avv.h" // ArcReviewDlgProc, rewrite_archiverbb2
149#include "chklist.h" // CenterOverWindow, CheckListProc
150#include "common.h" // CommonCreateTextChildren, CommonFrameWndProc, CommonTextPaint
151 // CommonTextButton
152#include "draglist.h" // DoFileDrag, DragOne
153#include "valid.h" // GetDesktopName, TestCDates
154#include "mainwnd.h" // GetNextWindowPos, MakeBubble, TopWindowName
155#include "objwin.h" // MakeObjWin
156#include "shadow.h" // MakeShadows
157#include "objcnr.h" // ObjCnrDlgProc
158#include "printer.h" // PrintListThread
159#include "srchpath.h" // RunFM2Util
160#include "misc.h" // Broadcast, CheckMenu, CurrentRecord, SayFilter, SaySort
161 // DrawTargetEmphasis, IsFm2Window
162#include "select.h" // SelectAll, SelectList
163#include "findrec.h" // ShowCnrRecord
164#include "walkem.h" // WalkExtractDlgProc
165#include "droplist.h" // AcceptOneDrop, CheckPmDrgLimit, DropHelp, GetOneDrop
166#include "archive.h" // ArchiveDlgProc
167#include "common.h" // CommonTextProc
168#include "presparm.h" // CopyPresParams
169#include "defview.h" // DefaultViewKeys
170#include "systemf.h" // ExecOnList
171#include "filter.h" // PickMaskDlgProc
172#include "avl.h" // SBoxDlgProc
173#include "mkdir.h" // SetDir
174#include "collect.h" // StartCollector
175#include "viewer.h" // StartMLEEditor
176#include "newview.h" // StartViewer
177#include "i18nutil.h" // commafmt
178#include "copyf.h" // unlinkf
179#include "literal.h" // wildcard
180#include "wrappers.h" // xrealloc
181#include "misc.h" // AdjustCnrColVis, QuickPopup, SetSortChecks, SwitchCommand
182#include "select.h" // DeselectAll, InvertAll
183#include "strips.h" // bstrip
184#include "dirs.h" // save_dir2
185#include "fortify.h"
186#include "excputil.h" // 06 May 08 SHL added
187
188#define ARCFLAGS_REALDIR 0x00000001
189#define ARCFLAGS_PSEUDODIR 0x00000002
190#define CON_COLS 6
191#define EXTRA_ARCRECORD_BYTES (sizeof(ARCITEM) - sizeof(MINIRECORDCORE))
192#define NO_START_OF_ARCHIVER_LIST_STRING "None"
193#define NO_END_OF_ARCHIVER_LIST_STRING NO_START_OF_ARCHIVER_LIST_STRING
194
195#pragma data_seg(DATA1)
196static INT DefArcSortFlags;
197
198// Data definitions
199static PSZ pszSrcFile = __FILE__;
200#pragma data_seg(GLOBAL1)
201HWND ArcCnrMenu;
202HWND ArcMenu;
203CHAR ArcTempRoot[CCHMAXPATH];
204BOOL fArcStuffVisible;
205BOOL fFileNameCnrPath;
206
207#pragma data_seg(GLOBAL2)
208CHAR lastextractpath[CCHMAXPATH];
209ULONGLONG ullDATFileSpaceNeeded = 10000;
210
211typedef struct {
212
213 HWND hwndCnr; //hwnd you want the message posted to
214 HWND hwndClient; //hwnd calling this thread; NULL will work
215 ULONG RunFlags; //runemf2 flags see systemf.h
216 ULONG msg; //Message to post
217 UINT uiLineNumber;
218 PCSZ pszSrcFile;
219 CHAR filename[CCHMAXPATH]; //file passed as MP1 message parameter (file selected)
220 CHAR *pszDirectory; //Execution directory
221 CHAR *pszEnvironment; //Enviroment -- NULL passes current
222 CHAR *pszCmdLine; //Use sprintf to format multipart command line into single string
223 CHAR formatstring[40]; //Usally "%s"
224}
225WAITCHILD;
226
227/** Creates a thread to wait for a child process to complete then posts a message and closes
228 * This function should only be used for runemf2 calls that include the WAIT flag
229 */
230VOID WaitChildThread(VOID * arg)
231{
232 WAITCHILD *WaitChild;
233 HAB thab;
234 CHAR *filename;
235 INT ret;
236
237 DosError(FERR_DISABLEHARDERR);
238
239# ifdef FORTIFY
240 Fortify_EnterScope();
241# endif
242
243 WaitChild = (WAITCHILD *) arg;
244 if (WaitChild) {
245 filename = xstrdup(WaitChild->filename, pszSrcFile, __LINE__);
246 thab = WinInitialize(0);
247 if (thab) {
248 IncrThreadUsage();
249 priority_normal();
250 ret = runemf2(WaitChild->RunFlags, WaitChild->hwndClient,
251 WaitChild->pszSrcFile, WaitChild->uiLineNumber,
252 WaitChild->pszDirectory, WaitChild->pszEnvironment,
253 WaitChild->formatstring, WaitChild->pszCmdLine);
254 if (ret != -1) {
255 if (IsFile(WaitChild->filename) == 1)
256 PostMsg(WaitChild->hwndCnr, WaitChild->msg, MPFROMP(filename), MPVOID);
257 }
258 DecrThreadUsage();
259 WinTerminate(thab);
260 }
261 xfree(WaitChild->pszDirectory, pszSrcFile, __LINE__);
262 xfree(WaitChild->pszEnvironment, pszSrcFile, __LINE__);
263 xfree(WaitChild->pszCmdLine, pszSrcFile, __LINE__);
264 free(WaitChild);
265 } // if WaitChild
266# ifdef FORTIFY
267 Fortify_LeaveScope();
268# endif
269}
270
271static MRESULT EXPENTRY ArcErrProc(HWND hwnd, ULONG msg, MPARAM mp1,
272 MPARAM mp2)
273{
274 ARCDUMP *ad;
275 CHAR szQuotedArcName[CCHMAXPATH];
276
277 switch (msg) {
278 case WM_INITDLG:
279 if (!mp2)
280 WinDismissDlg(hwnd, 0);
281 else {
282 ad = (ARCDUMP *) mp2;
283 WinSetWindowPtr(hwnd, QWL_USER, ad);
284 if (ad->errmsg)
285 WinSetDlgItemText(hwnd, ARCERR_TEXT, ad->errmsg);
286 if (!ad->info->test)
287 WinEnableWindow(WinWindowFromID(hwnd, ARCERR_TEST), FALSE);
288 if (ad->listname) {
289 MLEsetlimit(WinWindowFromID(hwnd, ARCERR_MLE), -1L);
290 MLEsetformat(WinWindowFromID(hwnd, ARCERR_MLE), MLFIE_NOTRANS);
291 MLEsetcurpos(WinWindowFromID(hwnd, ARCERR_MLE),
292 MLEgetlen(WinWindowFromID(hwnd, ARCERR_MLE)));
293 MLEinsert(WinWindowFromID(hwnd, ARCERR_MLE),
294 GetPString(IDS_ARCHIVERREPORTTEXT));
295 MLEinsertfile(WinWindowFromID(hwnd, ARCERR_MLE), ad->listname);
296 }
297 }
298 break;
299
300 case WM_COMMAND:
301 switch (SHORT1FROMMP(mp1)) {
302 case DID_CANCEL:
303 WinDismissDlg(hwnd, 0);
304 break;
305
306 case IDM_HELP:
307 if (hwndHelp) {
308 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
309 MPFROM2SHORT(HELP_ARCERR, 0), MPFROMSHORT(HM_RESOURCEID));
310 }
311 break;
312
313 case DID_OK:
314 ad = WinQueryWindowPtr(hwnd, QWL_USER);
315 WinDlgBox(HWND_DESKTOP, hwnd, ArcReviewDlgProc, FM3ModHandle,
316 AD_FRAME, MPFROMP(ad));
317 WinDismissDlg(hwnd, 0);
318 break;
319
320 case ARCERR_VIEW:
321 ad = WinQueryWindowPtr(hwnd, QWL_USER);
322 {
323 CHAR *list[2];
324
325 list[0] = ad->arcname;
326 list[1] = NULL;
327 if (TestBinary(ad->arcname)) {
328 if (*binview)
329 ExecOnList((HWND) 0, binview, WINDOWED | SEPARATE, NULL, NULL, list,
330 NULL, pszSrcFile, __LINE__);
331 else
332 StartMLEEditor(HWND_DESKTOP, 16 + 4 + 1, ad->arcname, hwnd);
333 }
334 else {
335 if (*viewer) {
336 ExecOnList((HWND) 0, viewer, WINDOWED | SEPARATE |
337 (fViewChild ? CHILD : 0), NULL,
338 NULL, list, NULL, pszSrcFile, __LINE__);
339 }
340 else
341 StartMLEEditor(HWND_DESKTOP, 8 + 4 + 1, ad->arcname, hwnd);
342 }
343 }
344 break;
345
346 case ARCERR_TEST: {
347 CHAR *comspec;
348
349 ad = WinQueryWindowPtr(hwnd, QWL_USER);
350 comspec = getenv( "COMSPEC" );
351 runemf2(SEPARATEKEEP | WINDOWED | MAXIMIZED,
352 hwnd, pszSrcFile, __LINE__, NULL, NULL,
353 "%s /k %s %s",
354 comspec, ad->info->test,
355 BldQuotedFileName(szQuotedArcName, ad->arcname));
356 break;
357 }
358 }
359 return 0;
360 }
361 return WinDefDlgProc(hwnd, msg, mp1, mp2);
362}
363
364static SHORT APIENTRY ArcSort(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2,
365 PVOID pStorage)
366{
367 PARCITEM pai1 = (PARCITEM) pmrc1;
368 PARCITEM pai2 = (PARCITEM) pmrc2;
369 DIRCNRDATA *pdcd = (DIRCNRDATA *) pStorage;
370 SHORT ret = 0;
371 CHAR *pext, *ppext;
372 INT sortFlags;
373
374 if (!pdcd) {
375 HWND hwndCnr = pai1->hwndCnr;
376
377 pdcd = WinQueryWindowPtr(hwndCnr, QWL_USER);
378 if (!pdcd) {
379 Runtime_Error(pszSrcFile, __LINE__, NULL);
380 return ret;
381 }
382 }
383
384 sortFlags = pdcd->sortFlags; // Optimize
385
386 if (sortFlags) {
387 switch (sortFlags & (~SORT_REVERSE)) {
388 case SORT_FIRSTEXTENSION:
389 pext = strchr(pai1->pszFileName, '.');
390 ppext = strchr(pai2->pszFileName, '.');
391 if (!pext)
392 pext = NullStr;
393 if (!ppext)
394 ppext = NullStr;
395 ret = stricmp(pext, ppext);
396 break;
397
398 case SORT_LASTEXTENSION:
399 pext = strrchr(pai1->pszFileName, '.');
400 ppext = strrchr(pai2->pszFileName, '.');
401 if (!pext)
402 pext = NullStr;
403 if (!ppext)
404 ppext = NullStr;
405 ret = stricmp(pext, ppext);
406 break;
407
408 case SORT_LWDATE:
409 ret = TestCDates(&pai1->date, &pai1->time,
410 &pai2->date, &pai2->time);
411 break;
412
413 case SORT_SIZE:
414 ret =
415 (pai1->cbFile < pai2->cbFile) ? 1 : (pai1->cbFile ==
416 pai2->cbFile) ? 0 : -1;
417 if (!ret)
418 ret =
419 (pai1->cbComp < pai2->cbComp) ? 1 : (pai1->cbComp ==
420 pai2->cbComp) ? 0 : -1;
421 break;
422
423 case SORT_EASIZE:
424 ret =
425 (pai1->cbComp < pai2->cbComp) ? 1 : (pai1->cbComp ==
426 pai2->cbComp) ? 0 : -1;
427 if (!ret)
428 ret =
429 (pai1->cbFile < pai2->cbFile) ? 1 : (pai1->cbFile ==
430 pai2->cbFile) ? 0 : -1;
431 break;
432 }
433 if (!ret)
434 ret = (SHORT) stricmp(pai1->pszFileName, pai2->pszFileName);
435 if (ret && (sortFlags & SORT_REVERSE))
436 ret = ret > 0 ? -1 : 1;
437 return ret;
438 }
439 return (SHORT) stricmp(pai1->pszFileName, pai2->pszFileName);
440}
441
442static INT APIENTRY ArcFilter(PMINIRECORDCORE rmini, PVOID arg)
443{
444 DIRCNRDATA *dcd = (DIRCNRDATA *) arg;
445 PARCITEM r;
446 register INT x;
447 INT ret = FALSE;
448
449 if (dcd && *dcd->mask.szMask) {
450 r = (PARCITEM) rmini;
451 if (dcd->mask.pszMasks[1]) {
452 for (x = 0; dcd->mask.pszMasks[x]; x++) {
453 if (*dcd->mask.pszMasks[x]) {
454 if (*dcd->mask.pszMasks[x] != '/') {
455 if (wildcard(r->pszFileName, dcd->mask.pszMasks[x], TRUE))
456 ret = TRUE;
457 }
458 else {
459 if (wildcard(r->pszFileName, dcd->mask.pszMasks[x] + 1, TRUE)) {
460 ret = FALSE;
461 break;
462 }
463 }
464 }
465 }
466 }
467 else {
468 if (wildcard(r->pszFileName, dcd->mask.szMask, TRUE))
469 ret = TRUE;
470 }
471 }
472 else
473 ret = TRUE;
474 return ret;
475}
476
477static MRESULT EXPENTRY ArcFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
478 MPARAM mp2)
479{
480 return CommonFrameWndProc(ARC_CNR, hwnd, msg, mp1, mp2);
481}
482
483static BOOL IsArcThere(HWND hwnd, CHAR * arcname)
484{
485 if (arcname) {
486 if (IsFile(arcname) != 1) {
487 saymsg(MB_CANCEL, hwnd,
488 GetPString(IDS_SAYWHATTEXT),
489 GetPString(IDS_ARCNOTTHERETEXT), arcname);
490 return FALSE;
491 }
492 return TRUE;
493 }
494 return FALSE;
495}
496
497/**
498 * Free storage associated with archive container item
499 * Caller is responsible for correcting pointers
500 */
501
502static VOID FreeArcItemData(PARCITEM pai)
503{
504 PSZ psz;
505
506 if (pai->pszFileName && pai->pszFileName != NullStr) {
507 psz = pai->pszFileName;
508 pai->pszFileName = NULL; // 08 Jul 08 SHL was NulStr
509 free(psz);
510 }
511}
512
513/**
514 * Remove item(s) from archive container and free associated storage if requested
515 * @param paiFirst points to first item to remove or NULL to remove all
516 * @param usCnt is remove count or 0 to remove all
517 */
518
519static VOID RemoveArcItems(HWND hwnd, PARCITEM paiFirst, USHORT usCnt, USHORT usFlags)
520{
521 INT remaining = usCnt;
522 PARCITEM pai;
523
524 if ((usCnt && !paiFirst) || (!usCnt && paiFirst))
525 Runtime_Error(pszSrcFile, __LINE__, "paiFirst %p usCnt %u mismatch", paiFirst, usCnt);
526 else {
527 // Free our buffers if free requested
528 if (usFlags & CMA_FREE) {
529 if (paiFirst)
530 pai = paiFirst;
531 else {
532 pai = (PARCITEM)WinSendMsg(hwnd, CM_QUERYRECORD, MPVOID,
533 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
534 if ((INT)pai == -1) {
535 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_QUERYRECORD");
536 remaining = -1;
537 pai = NULL;
538 }
539 }
540 while (pai) {
541 FreeArcItemData(pai);
542 pai = (PARCITEM)pai->rc.preccNextRecord;
543 if (remaining && --remaining == 0)
544 break;
545 }
546 }
547 }
548 if (remaining != - 1) {
549 remaining = (INT)WinSendMsg(hwnd, CM_REMOVERECORD, MPFROMP(&paiFirst),
550 MPFROM2SHORT(usCnt, usFlags));
551 if (remaining == -1) {
552 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,
553 "CM_REMOVERECORD hwnd %x pai %p cnt %u",
554 hwnd, paiFirst, usCnt);
555 }
556 }
557}
558
559/**
560 * Empty all records from an archive container and
561 * free associated storage and free up field infos
562 */
563
564static VOID EmptyArcCnr(HWND hwnd)
565{
566#if 0 // fixme to be gone or to be configurable
567 {
568 int state = _heapchk();
569 if (state != _HEAPOK)
570 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
571 else
572 DbgMsg(pszSrcFile, __LINE__, "_memavl %u", _memavl());
573 }
574#endif
575
576 // Remove all ARCITEM records
577 RemoveArcItems(hwnd, NULL, 0, CMA_FREE);
578
579 // Use common code to remove rest
580 EmptyCnr(hwnd);
581}
582
583//== FillArcCnr() generate archive content list and fill container window ==
584
585static INT FillArcCnr(HWND hwndCnr, CHAR * arcname, ARC_TYPE ** arcinfo,
586 ULONGLONG * pullTotalBytes, volatile PCHAR pStopFlag)
587{
588 FILE *fp;
589 HFILE oldstdout;
590 HFILE newstdout;
591 CHAR lonename[CCHMAXPATH + 2],
592 *nsize, *osize, *fdate, *fname, *p, *pp, *arctemp;
593 CHAR s[CCHMAXPATH * 2];
594 CHAR TestStr[CCHMAXPATH * 2];
595 BOOL gotstart;
596 BOOL gotend;
597 BOOL wasquote;
598 BOOL nomove = FALSE; // fixme to be gone?
599 BOOL notest;
600 INT highest = 0, fieldnum, counter = 0, numarcfiles = 0;
601 PARCITEM lastpai;
602 ARC_TYPE *info;
603 ARC_TYPE *tinfo;
604 ULONG apptype;
605 APIRET rc;
606 CHAR *mode;
607 ULONG cnter = 0;
608
609 if (!arcname || !arcinfo)
610 return 0;
611
612 info = *arcinfo;
613 if (!info)
614 info = find_type(arcname, NULL);
615 arctemp = xmallocz(CCHMAXPATH, pszSrcFile, __LINE__);
616 if (CheckDriveSpaceAvail(ArcTempRoot, ullDATFileSpaceNeeded, ullTmpSpaceNeeded) == 1)
617 saymsg(MB_OK,
618 HWND_DESKTOP,
619 NullStr,
620 GetPString(IDS_ARCTMPDRIVESPACELIMITED),
621 ArcTempRoot);
622 MakeTempName(arctemp, ArcTempRoot, 2);
623
624
625ReTry:
626
627 tinfo = NULL;
628 numarcfiles = counter = highest = 0;
629 gotstart = gotend = FALSE;
630 lastpai = NULL;
631 *pullTotalBytes = 0;
632 if (!info || !info->list)
633 Runtime_Error(pszSrcFile, __LINE__, NULL);
634 else {
635 RemoveArcItems(hwndCnr, NULL, 0, CMA_FREE | CMA_INVALIDATE | CMA_ERASE);
636 *arcinfo = info;
637 highest = info->osizepos;
638 if (info->nsizepos > highest)
639 highest = info->nsizepos;
640 if (info->fdpos > highest)
641 highest = info->fdpos;
642 if (info->fnpos > highest)
643 highest = info->fnpos;
644 if (highest > 50) {
645 saymsg(MB_ENTER | MB_ICONEXCLAMATION, HWND_DESKTOP,
646 GetPString(IDS_SHAMETEXT), GetPString(IDS_BUNGEDUPTEXT));
647 }
648 if (info->fnpos == -1)
649 highest = 32767;
650
651 DosError(FERR_DISABLEHARDERR);
652 xDosForceDelete(arctemp);
653 DosError(FERR_DISABLEHARDERR);
654
655 strcpy(s, info->list);
656 p = strchr(s, ' ');
657 if (p)
658 *p = 0;
659 DosError(FERR_DISABLEHARDERR);
660 if (!xDosQueryAppType(s, &apptype) &&
661 (apptype & FAPPTYP_DOS ||
662 apptype & FAPPTYP_WINDOWSREAL ||
663 apptype & FAPPTYP_WINDOWSPROT ||
664 apptype & FAPPTYP_WINDOWSPROT31)) {
665 p = GetCmdSpec(TRUE);
666 runemf2(SEPARATE | INVISIBLE | MINIMIZED | BACKGROUND | WAIT,
667 hwndCnr, pszSrcFile, __LINE__, NULL, "DOS_BACKGROUND_EXECUTION=1",
668 "%s /C %s %s >%s",
669 p, // shell
670 info->list, // list command
671 BldQuotedFileName(s, arcname),
672 arctemp);
673 }
674 else {
675 mode = "w";
676 fp = xfopen(arctemp, mode, pszSrcFile, __LINE__, FALSE);
677 if (!fp) {
678 xfree(arctemp, pszSrcFile, __LINE__);
679 return 0;
680 }
681 else {
682 newstdout = -1;
683 DosError(FERR_DISABLEHARDERR);
684 rc = xDosDupHandle(fileno(stdout), &newstdout);
685 if (rc) {
686 Dos_Error(MB_CANCEL, rc, hwndCnr, pszSrcFile, __LINE__,
687 PCSZ_DOSDUPHANDLE);
688 xfree(arctemp, pszSrcFile, __LINE__);
689 return 0;
690 }
691 else {
692 oldstdout = fileno(stdout);
693 DosError(FERR_DISABLEHARDERR);
694 rc = xDosDupHandle(fileno(fp), &oldstdout);
695 if (rc) {
696 Dos_Error(MB_CANCEL, rc, hwndCnr, pszSrcFile, __LINE__,
697 PCSZ_DOSDUPHANDLE);
698 xfree(arctemp, pszSrcFile, __LINE__);
699 return 0;
700 }
701 else {
702 rc = 0;
703 rc = SearchPathForFile(PCSZ_PATH, s, NULL);
704 if (!rc) {
705 cnter ++;
706 runemf2(SEPARATE | INVISIBLE | MINIMIZED | BACKGROUND | WAIT,
707 hwndCnr, pszSrcFile, __LINE__, NULL, NULL,
708 "%s %s",
709 info->list,
710 BldQuotedFileName(s, arcname));
711 if (cnter == 1) {
712 if (info->test)
713 strcpy(TestStr, info->test);
714 else {
715 strcpy(TestStr, "");
716 notest = TRUE;
717 }
718 }
719 else if (notest && info->test) {
720 strcpy(TestStr, info->test);
721 notest = FALSE;
722 }
723 }
724 oldstdout = fileno(stdout);
725 DosError(FERR_DISABLEHARDERR);
726 xDosDupHandle(newstdout, &oldstdout);
727 DosClose(newstdout);
728 fclose(fp);
729 }
730 }
731 }
732 }
733
734 DosError(FERR_DISABLEHARDERR);
735 mode = "r";
736 fp = xfsopen(arctemp, mode, SH_DENYWR, pszSrcFile, __LINE__, TRUE);
737
738 if (fp) {
739 gotstart = !info->startlist || // If list has no start marker
740 !*info->startlist ||
741 (stricmp(info->startlist, NO_START_OF_ARCHIVER_LIST_STRING) == 0);
742
743 while (!feof(fp) && !gotend && !*pStopFlag) {
744 if (!xfgets_bstripcr(s, sizeof(s), fp, pszSrcFile, __LINE__))
745 break;
746 if (!gotstart) {
747 if (!strcmp(s, info->startlist))
748 gotstart = TRUE;
749 }
750 else if (info->endlist && !strcmp(s, info->endlist))
751 gotend = TRUE;
752 else {
753 // add to container
754 fname = NULL;
755 bstrip(s);
756 if (info->nameisfirst) {
757 strncpy(lonename, s, CCHMAXPATH + 2);
758 lonename[CCHMAXPATH + 1] = 0;
759 fname = lonename;
760 if (!xfgets_bstripcr(s, sizeof(s), fp, pszSrcFile, __LINE__))
761 break;
762 if (*fname == '\"') {
763 memmove(fname, fname + 1, strlen(fname) + 1);
764 p = strchr(fname, '\"');
765 if (p)
766 *p = 0;
767 }
768 }
769 nsize = NULL;
770 osize = fdate = NullStr;
771 p = s;
772 for (fieldnum = 0; fieldnum <= highest; fieldnum++) {
773 pp = p;
774 while (*pp && (*pp == ' ' || *pp == '\t')) // skip leading
775 pp++;
776 if (!*pp) {
777 if (fieldnum == info->fnpos && (!strcmp(strupr(info->ext), "7Z") ||
778 !strcmp(strupr(info->signature), "7Z")))
779 fname = nsize;// GKY 7-30-13 Work around for missing nsize field for some members of archive
780 break;
781 }
782 wasquote = FALSE;
783 p = pp;
784 while (*p && (wasquote ||
785 ((fieldnum != info->fnpos || !info->nameislast) ?
786 (*p != ' ' && *p != '\t') : TRUE))) {
787 if (*p == '\"') {
788 if (!wasquote) {
789 wasquote = TRUE;
790 memmove(p, p + 1, strlen(p));
791 while (*p == ' ' || *p == '\t')
792 p++;
793 }
794 else {
795 memmove(p, p + 1, strlen(p));
796 break;
797 }
798 }
799 else if (*p)
800 p++;
801 }
802 if (*p) {
803 *p = 0;
804 p++;
805 }
806 if (fieldnum == info->nsizepos)
807 nsize = pp;
808 else if (fieldnum == info->osizepos)
809 osize = pp;
810 else if (fieldnum == info->fdpos) {
811 fdate = pp;
812 if (info->fdflds > 1 && info->fdflds < 24) {
813 INT y;
814
815 if (*p) {
816 p--;
817 *p = ' ';
818 for (y = 0; y < info->fdflds - 1; y++) {
819 while (*p && (*p == ' ' || *p == '\t'))
820 p++;
821 while (*p && (*p != ' ' && *p != '\t'))
822 p++;
823 fieldnum++;
824 }
825 if (*p) {
826 *p = 0;
827 p++;
828 }
829 }
830 }
831 }
832 else if (fieldnum == info->fnpos) {
833 fname = pp;
834 if (pp && *pp == '*' && !*(pp + 1)) // workaround for LH.EXE
835 fname = NULL;
836 if (info->nameislast)
837 break;
838 }
839 else if ((!p || !*p) && info->fnpos == -1) {
840 fname = pp;
841 break;
842 }
843 } // for fldnum
844 if (info->nameisnext) {
845 if (!xfgets_bstripcr
846 (lonename, sizeof(lonename), fp, pszSrcFile, __LINE__))
847 break;
848 fname = lonename;
849 }
850 // fixme to complain?
851 if (fname && *fname) {
852
853 RECORDINSERT ri;
854 PARCITEM pai;
855
856 pai = WinSendMsg(hwndCnr,
857 CM_ALLOCRECORD,
858 MPFROMLONG(EXTRA_ARCRECORD_BYTES),
859 MPFROMLONG(1L));
860 if (!pai) {
861 Runtime_Error(pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
862 break;
863 }
864 else {
865 memset(pai, 0, sizeof(ARCITEM));
866 pai->hwndCnr = hwndCnr;
867 if (*fname == '*') {
868 fname++;
869 pai->flags = ARCFLAGS_REALDIR;
870 }
871 if (fname[strlen(fname) - 1] == '\\' ||
872 fname[strlen(fname) - 1] == '/')
873 pai->flags = ARCFLAGS_REALDIR;
874 pai->pszFileName = xstrdup(fname,pszSrcFile, __LINE__);
875# ifdef FORTIFY
876 // Will be freed by WM_DESTROY
877 Fortify_SetOwner(pai->pszFileName, 1);
878 // Fortify_ChangeScope(pai->pszFileName, -1);
879# endif
880
881 pai->pszDisplayName = pai->pszFileName;
882 pai->rc.pszIcon = pai->pszDisplayName;
883 if (fdate)
884 strcpy(pai->szDate, fdate);
885 // pai->pszFileName = pai->pszFileName;
886 pai->rc.pszIcon = pai->pszFileName;
887 pai->rc.hptrIcon = (pai->flags & ARCFLAGS_REALDIR) != 0 ?
888 hptrDir : hptrFile;
889 pai->pszDate = pai->szDate;
890 if (osize)
891 pai->cbFile = atol(osize);
892 if (nsize)
893 pai->cbComp = atol(nsize);
894 if (info->datetype && fdate && *fdate)
895 ArcDateTime(fdate, info->datetype, &pai->date, &pai->time);
896 memset(&ri, 0, sizeof(RECORDINSERT));
897 ri.cb = sizeof(RECORDINSERT);
898 ri.pRecordOrder = (PRECORDCORE) CMA_END;
899 ri.pRecordParent = (PRECORDCORE) NULL;
900 ri.zOrder = (USHORT) CMA_TOP;
901 ri.cRecordsInsert = 1L;
902 ri.fInvalidateRecord = FALSE;
903 if (WinSendMsg(hwndCnr,
904 CM_INSERTRECORD, MPFROMP(pai), MPFROMP(&ri))) {
905 *pullTotalBytes += pai->cbFile;
906 }
907 numarcfiles++;
908 if (!(++counter % 50)) {
909 if (!lastpai)
910 lastpai = pai;
911 WinSendMsg(hwndCnr,
912 CM_INVALIDATERECORD,
913 lastpai,
914 MPFROM2SHORT(10, CMA_ERASE | CMA_REPOSITION));
915 lastpai = pai;
916 }
917 // Avoid hogging system for large archive
918 if (numarcfiles == 100)
919 priority_idle();
920 }
921 }
922 }
923 } // while !eof
924
925 fclose(fp);
926
927 if (*pStopFlag)
928 numarcfiles = 0; // Request close
929 else if (!numarcfiles || !gotstart
930 || (!gotend && info->endlist && *info->endlist &&
931 (stricmp(info->endlist, NO_END_OF_ARCHIVER_LIST_STRING)))) {
932 // Oops
933 ARCDUMP ad;
934 CHAR errstr[CCHMAXPATH + 256];
935
936 // Try for alternate archiver
937 tinfo = info;
938 do {
939 tinfo = tinfo->next;
940 if (tinfo)
941 tinfo = find_type(arcname, tinfo);
942 if (tinfo) {
943 DosError(FERR_DISABLEHARDERR);
944 xDosForceDelete(arctemp);
945 info = tinfo;
946 goto ReTry;
947 }
948 } while (tinfo);
949 if (!fAlertBeepOff)
950 DosBeep(750, 50); // wake up user
951
952 if (cnter > 0) {
953 CHAR Temp[CCHMAXPATH + 2];
954
955 sprintf(errstr, GetPString(IDS_ARCERRORINFOTEXT),
956 arcname,
957 !gotstart ? GetPString(IDS_NOGOTSTARTTEXT) : NullStr,
958 !numarcfiles ? GetPString(IDS_NOARCFILESFOUNDTEXT) : NullStr,
959 !gotend ? GetPString(IDS_NOENDOFLISTTEXT) : NullStr,
960 !notest ? NullStr : GetPString(IDS_ARCNOTEST));
961 memset(&ad, 0, sizeof(ARCDUMP));
962 ad.info = info;
963 strcpy(ad.listname, arctemp);
964 strcpy(ad.arcname, arcname);
965 if (!notest) {
966 strcpy(Temp, info->test);
967 info->test = xstrdup(TestStr, pszSrcFile, __LINE__);
968 }
969 else if (rc) {
970 strcpy(Temp, info->test);
971 info->test = NULL;
972 }
973 ad.errmsg = errstr;
974 WinDlgBox(HWND_DESKTOP,
975 hwndCnr,
976 ArcErrProc, FM3ModHandle, ARCERR_FRAME, MPFROMP(&ad));
977 if (!notest || rc)
978 info->test = xstrdup(Temp, pszSrcFile, __LINE__);
979 }
980 else
981 saymsg(MB_OK, HWND_DESKTOP, GetPString(IDS_ARCMISSINGEXE),
982 GetPString(IDS_ARCMISSINGEXEVERBOSE));
983 }
984 else if (!nomove && tinfo) {
985 // if we got a false hit, move working hit to top
986 tinfo = info->next;
987 info->next = arcsighead;
988 arcsighead->prev = info;
989 if (tinfo)
990 tinfo->next->prev = info->prev;
991 info->prev->next = tinfo;
992 info->prev = NULL;
993 arcsighead = info;
994 rewrite_archiverbb2(NULL); // Rewrite with warning
995 }
996 } // if opened
997
998 DosError(FERR_DISABLEHARDERR);
999 xDosForceDelete(arctemp);
1000 xfree(arctemp, pszSrcFile, __LINE__);
1001 }
1002
1003 if (numarcfiles)
1004 priority_normal();
1005
1006 return numarcfiles;
1007} // FillArcCnr
1008
1009MRESULT EXPENTRY ArcTextProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1010{
1011 static BOOL emphasized = FALSE;
1012 static HWND hwndButtonPopup = (HWND) 0;
1013 static ULONG timestamp = ULONG_MAX;
1014 static USHORT lastid = 0;
1015
1016 switch (msg) {
1017 case WM_CREATE:
1018 return CommonTextProc(hwnd, msg, mp1, mp2);
1019
1020 case WM_COMMAND:
1021 return WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1022 ARC_CNR), msg, mp1, mp2);
1023
1024 case UM_CONTEXTMENU:
1025 case WM_CONTEXTMENU:
1026 {
1027 USHORT id;
1028
1029 id = WinQueryWindowUShort(hwnd, QWS_ID);
1030 switch (id) {
1031 case DIR_SELECTED:
1032 case DIR_VIEW:
1033 case DIR_SORT:
1034 {
1035 POINTL ptl = { 0, 0 };
1036 SWP swp;
1037 DIRCNRDATA *dcd;
1038
1039 if (hwndButtonPopup)
1040 WinDestroyWindow(hwndButtonPopup);
1041 if (id == DIR_SELECTED)
1042 id = DIR_RESTORE;
1043 if (id == lastid) {
1044
1045 ULONG check;
1046
1047 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &check,
1048 sizeof(check));
1049 if (check < timestamp + 500) {
1050 lastid = 0;
1051 goto MenuAbort;
1052 }
1053 }
1054 hwndButtonPopup = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
1055 if (hwndButtonPopup) {
1056 WinSetWindowUShort(hwndButtonPopup, QWS_ID, id);
1057 dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
1058 QW_PARENT),
1059 ARC_CNR), QWL_USER);
1060 if (id == DIR_SORT) {
1061 if (dcd)
1062 SetSortChecks(hwndButtonPopup, dcd->sortFlags);
1063 WinSendMsg(hwndButtonPopup,
1064 MM_DELETEITEM,
1065 MPFROM2SHORT(IDM_SORTNONE, FALSE), MPVOID);
1066 WinSendMsg(hwndButtonPopup,
1067 MM_DELETEITEM,
1068 MPFROM2SHORT(IDM_SORTNAME, FALSE), MPVOID);
1069 WinSendMsg(hwndButtonPopup,
1070 MM_DELETEITEM,
1071 MPFROM2SHORT(IDM_SORTLADATE, FALSE), MPVOID);
1072 WinSendMsg(hwndButtonPopup,
1073 MM_DELETEITEM,
1074 MPFROM2SHORT(IDM_SORTCRDATE, FALSE), MPVOID);
1075 WinSendMsg(hwndButtonPopup,
1076 MM_DELETEITEM,
1077 MPFROM2SHORT(IDM_SORTDIRSFIRST, FALSE), MPVOID);
1078 WinSendMsg(hwndButtonPopup,
1079 MM_DELETEITEM,
1080 MPFROM2SHORT(IDM_SORTDIRSLAST, FALSE), MPVOID);
1081 WinSendMsg(hwndButtonPopup,
1082 MM_DELETEITEM,
1083 MPFROM2SHORT(IDM_SORTSUBJECT, FALSE), MPVOID);
1084 WinSendMsg(hwndButtonPopup,
1085 MM_SETITEMTEXT,
1086 MPFROM2SHORT(IDM_SORTEASIZE, 0),
1087 MPFROMP(GetPString(IDS_COMPRESSEDSIZEMENUTEXT)));
1088 WinSendMsg(hwndButtonPopup,
1089 MM_SETITEMTEXT,
1090 MPFROM2SHORT(IDM_SORTLWDATE, 0),
1091 MPFROMP(GetPString(IDS_DATEMENUTEXT)));
1092 }
1093 ptl.x = 0;
1094 if (WinPopupMenu(HWND_OBJECT,
1095 HWND_OBJECT,
1096 hwndButtonPopup, -32767, -32767, 0, 0)) {
1097 WinQueryWindowPos(hwndButtonPopup, &swp);
1098 ptl.y = -(swp.cy + 2);
1099 }
1100 else {
1101 WinQueryWindowPos(hwnd, &swp);
1102 ptl.y = swp.cy + 2;
1103 }
1104 if (WinPopupMenu(hwnd,
1105 hwnd,
1106 hwndButtonPopup,
1107 ptl.x,
1108 ptl.y,
1109 0,
1110 PU_HCONSTRAIN | PU_VCONSTRAIN |
1111 PU_KEYBOARD | PU_MOUSEBUTTON1)) {
1112 CenterOverWindow(hwndButtonPopup);
1113 PaintRecessedWindow(hwnd, (HPS) 0, FALSE, FALSE);
1114 }
1115 }
1116 }
1117 break;
1118 default:
1119 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1120 ARC_CNR),
1121 WM_CONTROL, MPFROM2SHORT(ARC_CNR, CN_CONTEXTMENU), MPVOID);
1122 break;
1123 }
1124 }
1125 MenuAbort:
1126 if (msg == UM_CONTEXTMENU)
1127 return 0;
1128 break;
1129
1130 case WM_MENUEND:
1131 if (hwndButtonPopup == (HWND) mp2) {
1132 lastid = WinQueryWindowUShort((HWND) mp2, QWS_ID);
1133 WinDestroyWindow(hwndButtonPopup);
1134 hwndButtonPopup = (HWND) 0;
1135 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &timestamp,
1136 sizeof(timestamp));
1137 switch (lastid) {
1138 case DIR_VIEW:
1139 case DIR_SORT:
1140 case DIR_RESTORE:
1141 case DIR_SELECTED:
1142 PaintRecessedWindow(hwnd, (HPS) 0, TRUE, FALSE);
1143 break;
1144 }
1145 }
1146 break;
1147
1148 case WM_MOUSEMOVE:
1149 {
1150 USHORT id = WinQueryWindowUShort(hwnd, QWS_ID);
1151 PCSZ s = NULL;
1152
1153 if (fOtherHelp) {
1154 if ((!hwndBubble ||
1155 WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
1156 !WinQueryCapture(HWND_DESKTOP)) {
1157 switch (id) {
1158 case DIR_TOTALS:
1159 s = GetPString(IDS_ARCCNRTOTALSHELPTEXT);
1160 break;
1161 case DIR_SELECTED:
1162 s = GetPString(IDS_ARCCNRSELECTEDHELPTEXT);
1163 break;
1164 case DIR_VIEW:
1165 s = GetPString(IDS_ARCCNRVIEWHELPTEXT);
1166 break;
1167 case DIR_SORT:
1168 s = GetPString(IDS_DIRCNRSORTHELP);
1169 break;
1170 case DIR_FILTER:
1171 s = GetPString(IDS_DIRCNRFILTERHELP);
1172 break;
1173 case DIR_FOLDERICON:
1174 s = GetPString(IDS_ARCCNRFOLDERHELPTEXT);
1175 break;
1176 default:
1177 break;
1178 }
1179 if (s)
1180 MakeBubble(hwnd, TRUE, s);
1181 else if (hwndBubble)
1182 WinDestroyWindow(hwndBubble);
1183 }
1184 }
1185 switch (id) {
1186 case DIR_FILTER:
1187 case DIR_SORT:
1188 case DIR_VIEW:
1189 case DIR_SELECTED:
1190 case DIR_FOLDERICON:
1191 return CommonTextButton(hwnd, msg, mp1, mp2);
1192 }
1193 }
1194 break;
1195
1196 case WM_BUTTON3UP:
1197 case WM_BUTTON1UP:
1198 case WM_BUTTON1DOWN:
1199 case WM_BUTTON3DOWN:
1200 {
1201 USHORT id;
1202
1203 id = WinQueryWindowUShort(hwnd, QWS_ID);
1204 switch (id) {
1205 case DIR_FILTER:
1206 case DIR_SORT:
1207 case DIR_VIEW:
1208 case DIR_SELECTED:
1209 case DIR_FOLDERICON:
1210 return CommonTextButton(hwnd, msg, mp1, mp2);
1211 }
1212 }
1213 break;
1214
1215 case UM_CLICKED:
1216 case UM_CLICKED3:
1217 {
1218 USHORT id, cmd = 0;
1219
1220 id = WinQueryWindowUShort(hwnd, QWS_ID);
1221 switch (id) {
1222 case DIR_FOLDERICON:
1223 switch (msg) {
1224 case WM_BUTTON3CLICK:
1225 case WM_CHORD:
1226 cmd = IDM_RESCAN;
1227 break;
1228 default:
1229 if ((SHORT2FROMMP(mp2) & KC_ALT) != 0)
1230 cmd = IDM_WINDOWDLG;
1231 else
1232 cmd = IDM_WALKDIR;
1233 break;
1234 }
1235 break;
1236 case DIR_VIEW:
1237 case DIR_SORT:
1238 case DIR_SELECTED:
1239 PostMsg(hwnd, UM_CONTEXTMENU, MPVOID, MPVOID);
1240 break;
1241 case DIR_FILTER:
1242 cmd = IDM_FILTER;
1243 break;
1244 default:
1245 break;
1246 }
1247 if (cmd)
1248 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1249 ARC_CNR),
1250 WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
1251 }
1252 return 0;
1253
1254 case WM_BEGINDRAG:
1255 case DM_DROP:
1256 case DM_DRAGOVER:
1257 case DM_DRAGLEAVE:
1258 case DM_DROPHELP:
1259 if (msg == DM_DRAGOVER) {
1260 if (!emphasized) {
1261 emphasized = TRUE;
1262 DrawTargetEmphasis(hwnd, emphasized);
1263 }
1264 }
1265 else if (msg != WM_BEGINDRAG) {
1266 if (emphasized) {
1267 emphasized = FALSE;
1268 DrawTargetEmphasis(hwnd, emphasized);
1269 }
1270 }
1271 switch (WinQueryWindowUShort(hwnd, QWS_ID)) {
1272 case DIR_FOLDERICON:
1273 switch (msg) {
1274 case DM_DRAGOVER:
1275 if (AcceptOneDrop(hwnd, mp1, mp2))
1276 return MRFROM2SHORT(DOR_DROP, DO_MOVE);
1277 return MRFROM2SHORT(DOR_NODROP, 0); // Drop not valid
1278 case DM_DROPHELP:
1279 DropHelp(mp1, mp2, hwnd, GetPString(IDS_ARCCNRFOLDERDROPHELPTEXT));
1280 return 0;
1281 case DM_DROP:
1282 {
1283 char szFrom[CCHMAXPATH + 2];
1284
1285 if (emphasized) {
1286 emphasized = FALSE;
1287 DrawTargetEmphasis(hwnd, emphasized);
1288 }
1289 if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom)))
1290 WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1291 ARC_CNR),
1292 WM_COMMAND,
1293 MPFROM2SHORT(IDM_SWITCH, 0), MPFROMP(szFrom));
1294 }
1295 return 0;
1296 default:
1297 return PFNWPStatic(hwnd, msg, mp1, mp2);
1298 }
1299 default:
1300 {
1301 CNRDRAGINFO cnd;
1302 USHORT dcmd;
1303
1304 switch (msg) {
1305 case DM_DROP:
1306 dcmd = CN_DROP;
1307 break;
1308 case DM_DRAGOVER:
1309 dcmd = CN_DRAGOVER;
1310 break;
1311 case DM_DRAGLEAVE:
1312 dcmd = CN_DRAGLEAVE;
1313 break;
1314 case DM_DROPHELP:
1315 dcmd = CN_DROPHELP;
1316 break;
1317 case WM_BEGINDRAG:
1318 dcmd = CN_INITDRAG;
1319 break;
1320 }
1321 cnd.pDragInfo = (PDRAGINFO) mp1;
1322 cnd.pRecord = NULL;
1323 return WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
1324 WM_CONTROL,
1325 MPFROM2SHORT(ARC_CNR, dcmd), MPFROMP(&cnd));
1326 }
1327 }
1328 }
1329 return PFNWPStatic(hwnd, msg, mp1, mp2);
1330}
1331
1332MRESULT EXPENTRY ArcClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
1333 MPARAM mp2)
1334{
1335
1336 switch (msg) {
1337 case UM_CONTAINERHWND:
1338 return MRFROMLONG(WinWindowFromID(hwnd, ARC_CNR));
1339
1340 case UM_VIEWSMENU:
1341 // fixme to disble menu items as needed
1342 return MRFROMLONG(CheckMenu(hwnd, &ArcCnrMenu, ARCCNR_POPUP));
1343
1344 case UM_FILESMENU:
1345 // fixme to disble menu items as needed
1346 return MRFROMLONG(CheckMenu(hwnd, &ArcMenu, ARC_POPUP));
1347
1348 case MM_PORTHOLEINIT:
1349 case WM_INITMENU:
1350 case UM_INITMENU:
1351 case UM_COMMAND:
1352 case UM_LOADFILE:
1353 case UM_UPDATERECORD:
1354 case UM_UPDATERECORDLIST:
1355 case WM_COMMAND:
1356 case WM_CONTROL:
1357 case WM_CLOSE:
1358 return WinSendMsg(WinWindowFromID(hwnd, ARC_CNR), msg, mp1, mp2);
1359
1360 case WM_PSETFOCUS:
1361 case WM_SETFOCUS:
1362 if (mp2)
1363 PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
1364 break;
1365
1366 case UM_FOCUSME:
1367 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, ARC_CNR));
1368 break;
1369
1370 case WM_PAINT:
1371 {
1372 HPS hps;
1373 RECTL rcl;
1374
1375 hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
1376 if (hps) {
1377 WinQueryWindowRect(hwnd, &rcl);
1378 WinFillRect(hps, &rcl, CLR_PALEGRAY);
1379 CommonTextPaint(hwnd, hps);
1380 WinEndPaint(hps);
1381 }
1382 }
1383 break;
1384
1385 case UM_SIZE:
1386 case WM_SIZE:
1387 if (msg == UM_SIZE) {
1388
1389 SWP swp;
1390
1391 WinQueryWindowPos(hwnd, &swp);
1392 mp1 = MPFROM2SHORT(swp.cx, swp.cy);
1393 mp2 = MPFROM2SHORT(swp.cx, swp.cy);
1394 }
1395 {
1396 USHORT cx, cy, bx;
1397
1398 cx = SHORT1FROMMP(mp2);
1399 cy = SHORT2FROMMP(mp2);
1400 WinSetWindowPos(WinWindowFromID(hwnd, ARC_CNR), HWND_TOP,
1401 0,
1402 22, cx, cy - (24 + 22), SWP_SHOW | SWP_MOVE | SWP_SIZE);
1403 WinSetWindowPos(WinWindowFromID(hwnd, ARC_EXTRACTDIR), HWND_TOP,
1404 0, 0, cx, 22, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1405 WinSetWindowPos(WinWindowFromID(hwnd, DIR_FOLDERICON), HWND_TOP,
1406 2, cy - 22, 24, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1407 WinSetWindowPos(WinWindowFromID(hwnd, DIR_TOTALS), HWND_TOP,
1408 29,
1409 cy - 22,
1410 (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1411 WinSetWindowPos(WinWindowFromID(hwnd, DIR_SELECTED), HWND_TOP,
1412 29 + (cx / 3) + 2,
1413 cy - 22,
1414 (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1415 bx = (cx - (29 + (((cx / 3) + 2) * 2))) / 3;
1416 WinSetWindowPos(WinWindowFromID(hwnd, DIR_VIEW), HWND_TOP,
1417 29 + (((cx / 3) + 2) * 2),
1418 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1419 WinSetWindowPos(WinWindowFromID(hwnd, DIR_SORT), HWND_TOP,
1420 29 + (((cx / 3) + 2) * 2) + bx,
1421 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1422 WinSetWindowPos(WinWindowFromID(hwnd, DIR_FILTER), HWND_TOP,
1423 29 + (((cx / 3) + 2) * 2) + (bx * 2),
1424 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1425 }
1426 CommonTextPaint(hwnd, (HPS) 0);
1427 if (msg == UM_SIZE) {
1428 WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP, 0, 0, 0, 0,
1429 SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE);
1430 return 0;
1431 }
1432 break;
1433 }
1434 return WinDefWindowProc(hwnd, msg, mp1, mp2);
1435}
1436
1437MRESULT EXPENTRY ArcObjWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1438{
1439 DIRCNRDATA *dcd;
1440 PSZ psz;
1441 CHAR szQuotedArcName[CCHMAXPATH];
1442 CHAR szQuotedMemberName[CCHMAXPATH];
1443
1444 switch (msg) {
1445 case WM_CREATE:
1446 DbgMsg(pszSrcFile, __LINE__, "WM_CREATE mp1 %p mp2 %p", mp1, mp2); // 18 Jul 08 SHL fixme
1447 break;
1448
1449 case DM_PRINTOBJECT:
1450 case DM_DISCARDOBJECT:
1451 dcd = INSTDATA(hwnd);
1452 if (dcd) {
1453
1454 LISTINFO *li;
1455 CNRDRAGINFO cni;
1456
1457 cni.pRecord = NULL;
1458 cni.pDragInfo = (PDRAGINFO) mp1;
1459 li = DoFileDrop(dcd->hwndCnr,
1460 dcd->directory, FALSE, MPVOID, MPFROMP(&cni));
1461 CheckPmDrgLimit(cni.pDragInfo);
1462 if (li) {
1463 li->type = (msg == DM_DISCARDOBJECT) ? IDM_DELETE : IDM_PRINT;
1464 if (!li->list ||
1465 !li->list[0] || !PostMsg(hwnd, UM_ACTION, MPFROMP(li), MPVOID))
1466 FreeListInfo(li);
1467 else
1468 return MRFROMLONG(DRR_SOURCE);
1469 }
1470 }
1471 return MRFROMLONG(DRR_TARGET);
1472
1473 case DM_RENDERPREPARE:
1474 return (MRESULT) TRUE;
1475
1476 case DM_RENDER:
1477 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1478 if (dcd && dcd->info && dcd->info->extract && dcd->arcname) {
1479
1480 PDRAGTRANSFER pdt = (PDRAGTRANSFER) mp1;
1481 CHAR filename[CCHMAXPATH];
1482 ULONG len;
1483
1484 if (pdt->hwndClient && pdt->pditem && pdt->hstrSelectedRMF &&
1485 pdt->hstrRenderToName) {
1486 if (pdt->usOperation == DO_COPY || pdt->usOperation == DO_MOVE) {
1487 *filename = 0;
1488 len = DrgQueryStrName(pdt->hstrSelectedRMF, CCHMAXPATH, filename);
1489 filename[len] = 0;
1490 if (strnicmp(filename, "OS2FILE,", 8)) {
1491 *filename = 0;
1492 len = DrgQueryStrName(pdt->hstrRenderToName, CCHMAXPATH, filename);
1493 filename[len] = 0;
1494 if (len && *filename) {
1495 psz = xstrdup(filename, pszSrcFile, __LINE__);
1496 if (psz) {
1497 PostMsg(hwnd, UM_RENDER, MPFROMP(pdt), MPFROMP(psz));
1498 return (MRESULT) TRUE;
1499 }
1500 }
1501 }
1502 }
1503 pdt->fsReply = DMFL_RENDERRETRY;
1504 }
1505 }
1506 return (MRESULT) FALSE;
1507
1508 case UM_RENDER:
1509 {
1510 PDRAGTRANSFER pdt = (PDRAGTRANSFER) mp1;
1511 USHORT usRes = DMFL_RENDERFAIL;
1512
1513 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1514 if (dcd && dcd->info && dcd->info->extract && dcd->arcname) {
1515
1516 CHAR *filename = (CHAR *) mp2, *p;
1517 ULONG len;
1518 CHAR membername[CCHMAXPATH], construct[CCHMAXPATH * 2];
1519
1520 *membername = 0;
1521 len = DrgQueryStrName(pdt->pditem->hstrSourceName,
1522 CCHMAXPATH, membername);
1523 membername[len] = 0;
1524 if (*membername && len && filename) {
1525 unlinkf(filename);
1526 strcpy(construct, filename);
1527 p = strrchr(filename, '\\');
1528 if (!p)
1529 *construct = 0;
1530 else {
1531 if (p == filename || *(p - 1) == ':')
1532 p++;
1533 *p = 0;
1534 }
1535 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS | WAIT |
1536 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
1537 dcd->hwndClient, pszSrcFile, __LINE__, construct, NULL,
1538 "%s %s %s",
1539 dcd->info->extract,
1540 BldQuotedFileName(szQuotedArcName, dcd->arcname),
1541 BldQuotedFileName(szQuotedMemberName, membername));
1542 BldFullPathName(construct, construct, membername);
1543 if (IsFile(construct) != -1) {
1544 rename(construct, filename);
1545 unlinkf(construct);
1546 if (IsFile(filename) != -1)
1547 usRes = DMFL_RENDEROK;
1548 }
1549 }
1550 }
1551 xfree((CHAR *)mp2, pszSrcFile, __LINE__);
1552 PostMsg(pdt->hwndClient, DM_RENDERCOMPLETE, MPFROMP(pdt),
1553 MPFROM2SHORT(usRes, 0));
1554 }
1555 return 0;
1556
1557 case UM_SETUP:
1558# ifdef FORTIFY
1559 Fortify_EnterScope();
1560# endif
1561 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1562 if (!dcd) {
1563 Runtime_Error(pszSrcFile, __LINE__, NULL);
1564 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1565 }
1566 else {
1567# ifdef FORTIFY
1568 Fortify_BecomeOwner(dcd);
1569# endif
1570 // set unique id
1571 WinSetWindowUShort(hwnd, QWS_ID, ARCOBJ_FRAME + (ARC_FRAME - dcd->id));
1572 dcd->hwndObject = hwnd; // pass back hwnd
1573 if (ParentIsDesktop(hwnd, dcd->hwndParent))
1574 DosSleep(100); //05 Aug 07 GKY 250 // Avoid race?
1575 }
1576 return 0;
1577
1578 case UM_RESCAN:
1579 /**
1580 * populate container
1581 */
1582 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1583 if (dcd) {
1584 if (mp1)
1585 strcpy(dcd->arcname, (CHAR *) mp1); // Update name on request
1586 dcd->ullTotalBytes = dcd->totalfiles =
1587 dcd->selectedfiles = dcd->selectedbytes = 0;
1588 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, "0");
1589 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, "0 / 0k");
1590 dcd->totalfiles = FillArcCnr(dcd->hwndCnr,
1591 dcd->arcname,
1592 &dcd->info,
1593 &dcd->ullTotalBytes, &dcd->stopflag);
1594 if (!dcd->totalfiles)
1595 PostMsg(dcd->hwndCnr, WM_CLOSE, MPVOID, MPVOID);
1596 else {
1597 dcd->arcfilled = TRUE;
1598 if (!PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID))
1599 WinSendMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
1600 PostMsg(dcd->hwndCnr, UM_SETUP2, MPVOID, MPVOID);
1601 WinSendMsg(dcd->hwndCnr,
1602 CM_INVALIDATERECORD,
1603 MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
1604 }
1605 }
1606 return 0;
1607
1608 case UM_SELECT:
1609 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1610 if (dcd) {
1611 switch (SHORT1FROMMP(mp1)) {
1612 case IDM_SELECTALL:
1613 case IDM_SELECTALLFILES:
1614 SelectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, TRUE);
1615 break;
1616 case IDM_DESELECTALL:
1617 case IDM_DESELECTALLFILES:
1618 DeselectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, TRUE);
1619 break;
1620 case IDM_DESELECTMASK:
1621 case IDM_SELECTMASK:
1622 {
1623 MASK mask;
1624 PARCITEM pci = (PARCITEM) mp2;
1625
1626 memset(&mask, 0, sizeof(MASK));
1627 mask.fNoAttribs = TRUE;
1628 mask.fNoDirs = TRUE;
1629 mask.fText = TRUE;
1630 strcpy(mask.prompt,
1631 GetPString((SHORT1FROMMP(mp1) == IDM_SELECTMASK) ?
1632 IDS_SELECTFILTERTEXT : IDS_DESELECTFILTERTEXT));
1633 if (pci && (INT) pci != -1)
1634 strcpy(mask.szMask, pci->pszFileName);
1635 if (WinDlgBox(HWND_DESKTOP, dcd->hwndCnr, PickMaskDlgProc,
1636 FM3ModHandle, MSK_FRAME, MPFROMP(&mask))) {
1637 if (SHORT1FROMMP(mp1) == IDM_SELECTMASK)
1638 SelectAll(dcd->hwndCnr, TRUE, TRUE, mask.szMask, NULL, FALSE);
1639 else
1640 DeselectAll(dcd->hwndCnr, TRUE, TRUE, mask.szMask, NULL, FALSE);
1641 }
1642 }
1643 break;
1644
1645 case IDM_INVERT:
1646 InvertAll(dcd->hwndCnr);
1647 break;
1648 }
1649 }
1650 return 0;
1651
1652 case UM_ENTER:
1653 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1654 if (dcd) {
1655
1656 CHAR *s = (CHAR *) mp1, *p, *pp; // filename[CCHMAXPATH];
1657 WAITCHILD *WaitChild;
1658
1659 WaitChild = xmallocz(sizeof(WAITCHILD), pszSrcFile, __LINE__);
1660 if (!WaitChild)
1661 return 0;
1662 WaitChild->pszCmdLine = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1663 if (s) {
1664 if (!dcd->info->extract) {
1665 Runtime_Error(pszSrcFile, __LINE__, "no extract");
1666 free(s);
1667 return 0;
1668 }
1669 sprintf(WaitChild->pszCmdLine, "%s %s %s",
1670 dcd->info->exwdirs ? dcd->info->exwdirs :
1671 dcd->info->extract,
1672 BldQuotedFileName(szQuotedArcName, dcd->arcname),
1673 BldQuotedFileName(szQuotedMemberName, s));
1674 if (!dcd->info->exwdirs) {
1675 p = s;
1676 p = strrchr(s, '\\');
1677 pp = strrchr(s, '/');
1678 if (p && pp)
1679 p = max(p, pp);
1680 else if (!p)
1681 p = pp;
1682 if (p)
1683 memmove(s, p + 1, strlen(p + 1));
1684 }
1685 sprintf(WaitChild->filename, "%s\\%s", dcd->workdir, s);
1686 ForwardslashToBackslash(WaitChild->filename);
1687 free(s);
1688 WaitChild->RunFlags = SEPARATE | ASYNCHRONOUS | WAIT |
1689 (fArcStuffVisible ? 0 : BACKGROUND);
1690 WaitChild->hwndClient = dcd->hwndClient;
1691 WaitChild->msg = UM_ENTER;
1692 WaitChild->uiLineNumber = __LINE__;
1693 WaitChild->pszSrcFile = pszSrcFile;
1694 WaitChild->pszDirectory = xstrdup(dcd->workdir, pszSrcFile, __LINE__);
1695 WaitChild->pszEnvironment = NULL;
1696 strcpy(WaitChild->formatstring, "%s");
1697 WaitChild->hwndCnr = dcd->hwndCnr;
1698 xbeginthread(WaitChildThread,
1699 65536,
1700 WaitChild,
1701 pszSrcFile,
1702 __LINE__);
1703 }
1704 }
1705 return 0;
1706
1707 case UM_COMMAND:
1708 if (mp1) {
1709 if (PostMsg(hwnd, UM_ACTION, mp1, mp2))
1710 return (MRESULT) TRUE;
1711 }
1712 return 0;
1713
1714 case UM_ACTION:
1715 DosError(FERR_DISABLEHARDERR);
1716 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1717 if (dcd) {
1718
1719 LISTINFO *li = (LISTINFO *) mp1;
1720 register INT x;
1721
1722 if (li && li->list && li->list[0]) {
1723 // printf("%x/r", li->type); fflush(stdout); // 24 Sep 08 SHL
1724 switch (li->type) {
1725 case IDM_ARCHIVE:
1726 case IDM_ARCHIVEM:
1727 {
1728 DIRCNRDATA ad;
1729 CHAR szBuffer[1025], *p;
1730
1731 if (!li->list[1] && !stricmp(li->list[0], dcd->arcname)) {
1732 Runtime_Error(pszSrcFile, __LINE__, "arc to self");
1733 break;
1734 }
1735 ad = *dcd;
1736 ad.namecanchange = 0;
1737 ad.fmoving = (li->type == IDM_ARCHIVEM);
1738 if (!WinDlgBox(HWND_DESKTOP, dcd->hwndClient, ArchiveDlgProc,
1739 FM3ModHandle, ARCH_FRAME, (PVOID) & ad) || !*ad.arcname ||
1740 !*ad.command) // we blew it
1741 break;
1742 // build the sucker
1743 strcpy(szBuffer, ad.command);
1744 strcat(szBuffer, " ");
1745
1746 BldQuotedFileName(szBuffer + strlen(szBuffer), ad.arcname);
1747
1748 p = &szBuffer[strlen(szBuffer)]; // Remeber where archiver name ends
1749
1750 if (ad.mask.szMask) {
1751 strcat(szBuffer, " ");
1752
1753 BldQuotedFileName(szBuffer + strlen(szBuffer), ad.mask.szMask);
1754 }
1755 strcat(szBuffer, " ");
1756 x = 0;
1757
1758 // Run commands avoiding command line overflow
1759 while (li->list[x]) {
1760
1761 if (IsFile(li->list[x]))
1762 BldQuotedFileName(szBuffer + strlen(szBuffer), li->list[x]);
1763 else
1764 BldQuotedFullPathName(szBuffer + strlen(szBuffer), li->list[x], "*");
1765
1766 x++;
1767 if (!li->list[x] || strlen(szBuffer) +
1768 strlen(li->list[x]) + 5 > MaxComLineStrg) {
1769 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS |
1770 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
1771 hwnd, pszSrcFile, __LINE__,
1772 NULL, NULL, "%s", szBuffer);
1773 *p = 0;
1774 }
1775 strcat(szBuffer, " ");
1776 } // while
1777
1778 PostMsg(dcd->hwndCnr, UM_RESCAN, MPFROMSHORT(1), MPVOID);
1779 Broadcast(WinQueryAnchorBlock(hwnd),
1780 hwndMain, UM_UPDATERECORD, MPFROMP(ad.arcname), MPVOID);
1781 Broadcast(WinQueryAnchorBlock(hwnd),
1782 hwndMain,
1783 UM_UPDATERECORDLIST, MPFROMP(li->list), MPVOID);
1784 }
1785 break;
1786
1787 case IDM_REFRESH:
1788 case IDM_DELETE:
1789 {
1790 CHAR *endofit;
1791 PSZ pszCmdLine;
1792 INT z;
1793 CHECKLIST ck;
1794 CHAR prompt[CCHMAXPATH + 257];
1795
1796 if (!dcd->info->delete)
1797 break;
1798 memset(&ck, 0, sizeof(ck));
1799 ck.size = sizeof(ck);
1800 ck.list = li->list;
1801 ck.cmd = li->type;
1802 ck.prompt = prompt;
1803 ck.flags = CHECK_ARCHIVE;
1804 sprintf(prompt, GetPString(IDS_ARCCNRDELREFTEXT),
1805 (li->type == IDM_DELETE) ?
1806 GetPString(IDS_DELETELOWERTEXT) :
1807 GetPString(IDS_REFRESHLOWERTEXT),
1808 &"s"[li->list[1] == NULL],
1809 dcd->arcname,
1810 (li->type == IDM_DELETE) ?
1811 GetPString(IDS_DELETELOWERTEXT) :
1812 GetPString(IDS_REFRESHLOWERTEXT));
1813 if (!WinDlgBox(HWND_DESKTOP, hwnd, CheckListProc,
1814 FM3ModHandle, CHECK_FRAME, MPFROMP(&ck)))
1815 break;
1816 li->list = ck.list;
1817 if (!li->list || !li->list[0])
1818 break;
1819 pszCmdLine = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1820 if (!pszCmdLine)
1821 break;
1822 strcpy(pszCmdLine, li->type == IDM_DELETE ?
1823 dcd->info->delete :
1824 dcd->info->create);
1825 strcat(pszCmdLine, " ");
1826 BldQuotedFileName(pszCmdLine + strlen(pszCmdLine), dcd->arcname);
1827 endofit = &pszCmdLine[strlen(pszCmdLine)];
1828 z = 0;
1829 do {
1830 for (x = z; li->list[x] &&
1831 strlen(pszCmdLine) + strlen(li->list[x]) < 999; x++) {
1832 strcat(pszCmdLine, " ");
1833 BldQuotedFileName(pszCmdLine + strlen(pszCmdLine), li->list[x]);
1834 }
1835 z = x;
1836 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS | WAIT |
1837 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
1838 hwnd, pszSrcFile, __LINE__, NullStr, NULL, "%s", pszCmdLine);
1839 *endofit = 0;
1840 free(pszCmdLine);
1841 } while (li->list[x]);
1842 PostMsg(dcd->hwndCnr, UM_RESCAN, MPFROMSHORT(1), MPVOID);
1843 Broadcast(WinQueryAnchorBlock(hwnd),
1844 hwndMain,
1845 UM_UPDATERECORD, MPFROMP(dcd->arcname), MPVOID);
1846 }
1847 break;
1848
1849 case IDM_PRINT:
1850 case IDM_VIRUSSCAN:
1851 case IDM_VIEW:
1852 case IDM_MCIPLAY:
1853 case IDM_VIEWARCHIVE:
1854 case IDM_VIEWTEXT:
1855 case IDM_VIEWBINARY:
1856 case IDM_EDIT:
1857 case IDM_EDITTEXT:
1858 case IDM_EDITBINARY:
1859 case IDM_EXEC:
1860 case IDM_EXTRACTWDIRS:
1861 case IDM_EXTRACT:
1862 case IDM_OPENDEFAULT:
1863 case IDM_OPENSETTINGS:
1864 {
1865 CHAR *endofit, *ptr;
1866 PSZ pszCmdLine;
1867 INT z;
1868 if ((li->type == IDM_EXTRACT && !li->info->extract) ||
1869 ((li->type == IDM_VIEW || li->type == IDM_VIEWTEXT ||
1870 li->type == IDM_VIEWBINARY || li->type == IDM_EDIT ||
1871 li->type == IDM_VIEWARCHIVE || li->type == IDM_EDITTEXT ||
1872 li->type == IDM_EDITBINARY || li->type == IDM_MCIPLAY) &&
1873 (!li->info->extract && !li->info->exwdirs)) ||
1874 (li->type != IDM_EXTRACT && li->type != IDM_EDIT &&
1875 li->type != IDM_VIEW && li->type != IDM_VIEWTEXT &&
1876 li->type != IDM_VIEWBINARY &&
1877 li->type != IDM_VIEWARCHIVE &&
1878 li->type != IDM_EDITTEXT &&
1879 li->type != IDM_EDITBINARY &&
1880 li->type != IDM_MCIPLAY && !li->info->exwdirs)) {
1881 Runtime_Error(pszSrcFile, __LINE__, "no cmd for request");
1882 break;
1883 }
1884 if (li->type == IDM_EXTRACT || li->type == IDM_EXTRACTWDIRS) {
1885
1886 CHAR fullname[CCHMAXPATH * 2];
1887 CHAR **exfiles = NULL;
1888 UINT numfiles = 0, numalloc = 0;
1889
1890 if (li->targetpath && fFileNameCnrPath &&
1891 stricmp(lastextractpath, li->targetpath)) {
1892 strcpy(lastextractpath, li->targetpath);
1893 SetDir(dcd->hwndParent, hwnd, li->targetpath, 1);
1894 }
1895 for (x = 0; li->list[x]; x++) {
1896 BldFullPathName(fullname, li->targetpath, li->list[x]);
1897 //Check if file already exists on disk warn if it does.
1898 if (IsFile(fullname) != -1) {
1899 AddToList(li->list[x], &exfiles, &numfiles, &numalloc);
1900 li->list = RemoveFromList(li->list, li->list[x]);
1901 if (!li->list)
1902 break;
1903 x--;
1904 }
1905 }
1906 if (exfiles && numfiles) {
1907
1908 CHECKLIST ckl;
1909 CHAR prompt[(CCHMAXPATH * 2) + 256];
1910
1911 memset(&ckl, 0, sizeof(ckl));
1912 ckl.size = sizeof(ckl);
1913 ckl.list = exfiles;
1914 ckl.prompt = prompt;
1915 ckl.cmd = li->type;
1916 ckl.flags = CHECK_ARCHIVE;
1917 sprintf(prompt,
1918 GetPString(IDS_REPLACEWARNTEXT),
1919 &"s"[numfiles == 1],
1920 li->arcname, &"s"[numfiles != 1], li->targetpath);
1921 if (!WinDlgBox(HWND_DESKTOP, hwnd, CheckListProc,
1922 FM3ModHandle, CHECK_FRAME, MPFROMP(&ckl))) {
1923 if (ckl.list)
1924 FreeList(ckl.list);
1925 break;
1926 }
1927 else if (ckl.list)
1928 li->list = CombineLists(li->list, ckl.list);
1929 } // end check and warn
1930 }
1931 if (!li->list || !li->list[0])
1932 break;
1933 pszCmdLine = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1934 if (!pszCmdLine)
1935 break;
1936 strcpy(pszCmdLine,
1937 (li->type == IDM_EXTRACT ||
1938 ((li->type == IDM_VIEW ||
1939 li->type == IDM_VIEWTEXT ||
1940 li->type == IDM_VIEWBINARY ||
1941 li->type == IDM_VIEWARCHIVE ||
1942 li->type == IDM_PRINT ||
1943 li->type == IDM_EDIT ||
1944 li->type == IDM_EDITTEXT ||
1945 li->type == IDM_OPENDEFAULT ||
1946 li->type == IDM_OPENSETTINGS ||
1947 (li->type == IDM_EDITBINARY || // JBS No way for this () to be true??
1948 li->type == IDM_MCIPLAY)) ||
1949 !li->info->exwdirs)) ?
1950 li->info->extract :
1951 li->info->exwdirs);
1952 strcat(pszCmdLine, " ");
1953 BldQuotedFileName(pszCmdLine + strlen(pszCmdLine), li->arcname);
1954 endofit = &pszCmdLine[strlen(pszCmdLine)];
1955 z = 0;
1956 do {
1957 for (x = z; li->list[x] &&
1958 strlen(pszCmdLine) + strlen(li->list[x]) < MaxComLineStrg - 1 ; x++) {
1959 strcat(pszCmdLine, " ");
1960 BldQuotedFileName(pszCmdLine + strlen(pszCmdLine), li->list[x]);
1961 ptr = li->list[x];
1962 while (*ptr) {
1963 if (*ptr == '/')
1964 *ptr = '\\';
1965 ptr++;
1966 }
1967 }
1968 z = x;
1969 runemf2(SEPARATE | WINDOWED | WAIT |
1970 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
1971 hwnd, pszSrcFile, __LINE__,
1972 li->targetpath, NULL, "%s", pszCmdLine);
1973 *endofit = 0;
1974 } while (li->list[x]);
1975 if (li->type == IDM_EXTRACT || li->type == IDM_EXTRACTWDIRS) {
1976 // update windows
1977 for (x = 0; li->list[x]; x++) {
1978
1979 CHAR *temp, *p;
1980
1981 temp = li->list[x];
1982 ForwardslashToBackslash(temp);
1983 p = xmalloc(strlen(temp) + strlen(li->targetpath) + 2,
1984 pszSrcFile, __LINE__);
1985 if (p) {
1986 BldFullPathName(p, li->targetpath, temp);
1987 li->list[x] = p;
1988 free(temp);
1989 }
1990 }
1991 if (fFolderAfterExtract) {
1992
1993 CHAR objectpath[CCHMAXPATH], *p;
1994 APIRET rc;
1995
1996 GetDesktopName(objectpath, sizeof(objectpath));
1997 rc = WinDlgBox(HWND_DESKTOP, dcd->hwndParent, ObjCnrDlgProc,
1998 FM3ModHandle, OBJCNR_FRAME,
1999 MPFROMP(objectpath));
2000 if (rc) {
2001 if (rc > 1)
2002 strcpy(objectpath, "<WP_DESKTOP>");
2003 p = NULL;
2004 if (li->arcname) {
2005 p = strrchr(li->arcname, '\\');
2006 if (p)
2007 p++;
2008 }
2009 MakeShadows(dcd->hwndParent, li->list, 2, objectpath, p);
2010 }
2011 }
2012 Broadcast(WinQueryAnchorBlock(hwnd),
2013 hwndMain,
2014 UM_UPDATERECORDLIST, MPFROMP(li->list), MPVOID);
2015 }
2016 else if (li->type == IDM_EXEC)
2017 ExecOnList(hwnd,
2018 li->runfile,
2019 WINDOWED | SEPARATEKEEP | PROMPT,
2020 li->targetpath, NULL, NULL, GetPString(IDS_EXECARCFILETITLETEXT),
2021 pszSrcFile, __LINE__);
2022 else if (li->type == IDM_VIRUSSCAN)
2023 ExecOnList(hwnd, virus, PROMPT | WINDOWED | SEPARATEKEEP,
2024 li->targetpath, NULL, NULL,
2025 GetPString(IDS_VIRUSSCANARCHIVETITLETEXT),
2026 pszSrcFile, __LINE__);
2027 else if (li->type == IDM_VIEW || li->type == IDM_VIEWTEXT ||
2028 li->type == IDM_VIEWBINARY || li->type == IDM_EDIT ||
2029 li->type == IDM_EDITTEXT ||
2030 li->type == IDM_VIEWARCHIVE ||
2031 li->type == IDM_EDITBINARY ||
2032 li->type == IDM_OPENDEFAULT ||
2033 li->type == IDM_OPENSETTINGS ||
2034 li->type == IDM_MCIPLAY || li->type == IDM_PRINT) {
2035
2036 CHAR *temp, *p;
2037 for (x = 0; li->list[x]; x++) {
2038 if (!li->info->exwdirs) {
2039 temp = li->list[x];
2040 p = strrchr(li->list[x], '\\');
2041 if (p) {
2042 p++;
2043 li->list[x] = xstrdup(p, pszSrcFile, __LINE__);
2044 if (!li->list[x])
2045 li->list[x] = temp;
2046 else {
2047 xfree(temp, pszSrcFile, __LINE__);
2048 }
2049 }
2050 }
2051 BldFullPathName(pszCmdLine, li->targetpath, li->list[x]);
2052 temp = li->list[x];
2053 li->list[x] = xstrdup(pszCmdLine, pszSrcFile, __LINE__);
2054 if (!li->list[x])
2055 li->list[x] = temp;
2056 else
2057 xfree(temp, pszSrcFile, __LINE__);
2058 }
2059 free(pszCmdLine);
2060 if (li->type == IDM_VIEW || li->type == IDM_EDIT) {
2061
2062 BOOL isit = TestBinary(li->list[0]);
2063
2064 if (isit) {
2065 if (li->type == IDM_VIEW)
2066 li->type = IDM_VIEWBINARY;
2067 else
2068 li->type = IDM_EDITBINARY;
2069 }
2070 else {
2071 if (li->type == IDM_VIEW)
2072 li->type = IDM_VIEWTEXT;
2073 else
2074 li->type = IDM_EDITTEXT;
2075 }
2076 }
2077 if (li->type == IDM_MCIPLAY) {
2078
2079 FILE *fp;
2080 CHAR szTempFile[CCHMAXPATH];
2081 CHAR *modew = "w";
2082
2083 if (pTmpDir && !IsValidDir(pTmpDir))
2084 DosCreateDir(pTmpDir, 0);
2085 BldFullPathName(szTempFile, pTmpDir, PCSZ_FM2PLAYTEMP);
2086 fp = xfopen(szTempFile, modew, pszSrcFile, __LINE__, FALSE);
2087 if (fp) {
2088 fprintf(fp, "%s", ";AV/2-built FM2Play listfile\n");
2089 for (x = 0; li->list[x]; x++)
2090 fprintf(fp, "%s\n", li->list[x]);
2091 fprintf(fp, ";end\n");
2092 fclose(fp);
2093 strrev(szTempFile);
2094 strcat(szTempFile, "@/");
2095 strrev(szTempFile);
2096 RunFM2Util(PCSZ_FM2PLAYEXE, szTempFile);
2097 }
2098 }
2099 else if (li->type == IDM_PRINT) {
2100 strcpy(li->targetpath, printer);
2101 // 10 Dec 08 SHL correct error handling - looked backward
2102 if (xbeginthread(PrintListThread,
2103 65536,
2104 li,
2105 pszSrcFile,
2106 __LINE__) != -1)
2107 {
2108 li = NULL; // Ensure not freed here
2109 }
2110
2111 }
2112 else if (li->type == IDM_VIEWARCHIVE) {
2113
2114 ARC_TYPE *info;
2115
2116 for (x = 0; li->list[x]; x++) {
2117 if (IsFile(li->list[x]) == 1) {
2118 info = NULL; // Do not hide dups - fixme to know why?
2119 if (WinDlgBox(HWND_DESKTOP, HWND_DESKTOP,
2120 SBoxDlgProc, FM3ModHandle, ASEL_FRAME,
2121 (PVOID) & info) && info) {
2122 StartArcCnr(HWND_DESKTOP,
2123 HWND_DESKTOP, li->list[x], 4, info);
2124 }
2125 }
2126 }
2127 }
2128 else if ((li->type == IDM_VIEWTEXT && *viewer) ||
2129 (li->type == IDM_VIEWBINARY && *binview) ||
2130 (li->type == IDM_EDITTEXT && *editor) ||
2131 (li->type == IDM_EDITBINARY && *bined)) {
2132 ExecOnList(hwnd, ((li->type == IDM_VIEWTEXT) ? viewer :
2133 (li->type == IDM_VIEWBINARY) ? binview :
2134 (li->type == IDM_EDITTEXT) ? editor :
2135 bined),
2136 WINDOWED | SEPARATE, NULL, NULL,
2137 li->list,
2138 NULL, pszSrcFile, __LINE__);
2139 }
2140 else if (li->type == IDM_OPENDEFAULT ||
2141 li->type == IDM_OPENSETTINGS) {
2142 WORKER *wk;
2143# ifdef FORTIFY
2144 Fortify_EnterScope();
2145# endif
2146 wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
2147 if (!wk)
2148 FreeListInfo(li);
2149 else {
2150 wk->size = sizeof(WORKER);
2151 wk->hwndCnr = dcd->hwndCnr;
2152 wk->hwndParent = dcd->hwndParent;
2153 wk->hwndFrame = dcd->hwndFrame;
2154 wk->hwndClient = dcd->hwndClient;
2155 wk->li = li;
2156 strcpy(wk->directory, dcd->directory);
2157 if (xbeginthread(Action,
2158 122880,
2159 wk,
2160 pszSrcFile,
2161 __LINE__) == -1)
2162 {
2163 free(wk);
2164 FreeListInfo((LISTINFO *) mp1);
2165 }
2166 }
2167# ifdef FORTIFY
2168 Fortify_LeaveScope();
2169# endif
2170 }
2171 else {
2172 if (li->hwnd) {
2173
2174 ULONG viewtype;
2175
2176 for (x = 0; li->list[x]; x++) {
2177 if (x == 0) {
2178 if (li->type == IDM_VIEWBINARY ||
2179 li->type == IDM_EDITBINARY)
2180 viewtype = 16;
2181 else
2182 viewtype = 8;
2183 }
2184 else
2185 viewtype = 0;
2186# ifdef FORTIFY
2187 Fortify_EnterScope();
2188# endif
2189 temp = xstrdup(li->list[x], pszSrcFile, __LINE__);
2190 if (temp) {
2191 if (!PostMsg(WinQueryWindow(li->hwnd, QW_PARENT),
2192 UM_LOADFILE,
2193 MPFROMLONG(4L +
2194 (li->type == IDM_VIEWTEXT ||
2195 li->type == IDM_VIEWBINARY) +
2196 viewtype), MPFROMP(temp)))
2197 free(temp);
2198 }
2199# ifdef FORTIFY
2200 DosSleep(1); // Allow MassAction to take ownership
2201 Fortify_LeaveScope();
2202# endif
2203 }
2204 }
2205 }
2206 }
2207 }
2208 break;
2209
2210 case IDM_FIND:
2211 {
2212 UINT numfiles = 0, numalloced = 0;
2213 CHAR **list2 = NULL, fullname[CCHMAXPATH * 2], *p;
2214
2215 for (x = 0; li->list[x]; x++) {
2216 ForwardslashToBackslash(li->list[x]);
2217 BldFullPathName(fullname, dcd->directory, li->list[x]);
2218 if (IsFile(fullname) != -1)
2219 if (AddToList(fullname, &list2, &numfiles, &numalloced))
2220 break;
2221 if (strchr(li->list[x], '\\')) {
2222 p = strrchr(li->list[x], '\\');
2223 if (p) {
2224 p++;
2225 if (*p) {
2226 BldFullPathName(fullname, dcd->directory, p);
2227 if (IsFile(fullname) != -1)
2228 if (AddToList(fullname, &list2, &numfiles, &numalloced))
2229 break;
2230 }
2231 }
2232 }
2233 }
2234 if (!numfiles || !list2)
2235 Runtime_Error(pszSrcFile, __LINE__, "no files or list");
2236 else {
2237 WinSendMsg(dcd->hwndCnr, WM_COMMAND,
2238 MPFROM2SHORT(IDM_COLLECTOR, 0), MPVOID);
2239 DosSleep(10);
2240 if (Collector) {
2241 if (!PostMsg(Collector, WM_COMMAND,
2242 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(list2)))
2243 FreeList(list2);
2244 }
2245 else
2246 FreeList(list2);
2247 }
2248 }
2249 break;
2250 } // switch
2251 }
2252 if (li && li->type != IDM_OPENDEFAULT && li->type != IDM_OPENSETTINGS)
2253 {
2254 FreeListInfo(li);
2255 }
2256 }
2257 return 0;
2258
2259 case WM_CLOSE:
2260 WinDestroyWindow(hwnd);
2261 break;
2262
2263 case WM_DESTROY:
2264 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
2265 if (dcd) {
2266 if (*dcd->workdir) {
2267 DosSleep(16);
2268 wipeallf(TRUE, "%s\\*", dcd->workdir);
2269 if (rmdir(dcd->workdir)) {
2270 DosSleep(100);
2271 wipeallf(TRUE, "%s\\*", dcd->workdir);
2272 rmdir(dcd->workdir);
2273 }
2274 }
2275 FreeList(dcd->lastselection);
2276 WinSendMsg(dcd->hwndCnr, UM_CLOSE, MPVOID, MPVOID);
2277 WinSetWindowPtr(dcd->hwndCnr, QWL_USER, NULL); // 13 Apr 10 SHL Set NULL before freeing dcd
2278 free(dcd);
2279# ifdef FORTIFY
2280 Fortify_LeaveScope();
2281# endif
2282 }
2283 if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
2284 WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
2285 break;
2286 } // switch
2287 return WinDefWindowProc(hwnd, msg, mp1, mp2);
2288}
2289
2290static MRESULT EXPENTRY ArcCnrWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
2291 MPARAM mp2)
2292{
2293 DIRCNRDATA *dcd = INSTDATA(hwnd);
2294 CHAR szQuotedArcName[CCHMAXPATH];
2295
2296 switch (msg) {
2297 case DM_PRINTOBJECT:
2298 case DM_DISCARDOBJECT:
2299 if (dcd)
2300 return WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
2301 else
2302 return MRFROMLONG(DRR_TARGET);
2303
2304 case WM_CHAR:
2305 shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
2306 if (SHORT1FROMMP(mp1) & KC_KEYUP)
2307 return (MRESULT)TRUE;
2308 if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
2309 switch (SHORT2FROMMP(mp2)) {
2310 case VK_DELETE:
2311 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DELETE, 0), MPVOID);
2312 break;
2313 }
2314 }
2315
2316 if (SearchContainer(hwnd, msg, mp1, mp2))
2317 return (MRESULT)TRUE; // Avoid default handler
2318 break; // Let default handler see key too
2319
2320 case WM_MOUSEMOVE:
2321 case WM_BUTTON1UP:
2322 case WM_BUTTON2UP:
2323 case WM_BUTTON3UP:
2324 case WM_CHORD:
2325 shiftstate = (SHORT2FROMMP(mp2) & (KC_SHIFT | KC_ALT | KC_CTRL));
2326 break;
2327
2328 case WM_BUTTON1MOTIONEND:
2329 {
2330 CNRINFO cnri;
2331
2332 memset(&cnri, 0, sizeof(CNRINFO));
2333 cnri.cb = sizeof(CNRINFO);
2334 if (WinSendMsg(hwnd,
2335 CM_QUERYCNRINFO,
2336 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)))) {
2337 if (cnri.flWindowAttr & CV_DETAIL)
2338 PrfWriteProfileData(fmprof,
2339 appname,
2340 "ArcCnrSplitBar",
2341 (PVOID) & cnri.xVertSplitbar, sizeof(LONG));
2342 }
2343 }
2344 break;
2345
2346 case WM_PRESPARAMCHANGED:
2347 PresParamChanged(hwnd, PCSZ_ARCCNR, mp1, mp2);
2348 break;
2349
2350 case UM_UPDATERECORD:
2351 case UM_UPDATERECORDLIST:
2352 if (dcd && !IsArcThere(hwnd, dcd->arcname))
2353 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2354 return 0;
2355
2356 case WM_SETFOCUS:
2357 /**
2358 * put name of our window (archive name) on status line
2359 */
2360 if (dcd && hwndStatus && mp2)
2361 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2362 break;
2363
2364 case UM_SETUP2:
2365 if (dcd && dcd->info) {
2366 if (dcd->info->fdpos == -1 || !dcd->info->datetype)
2367 dcd->sortFlags &= (~SORT_LWDATE);
2368 if (dcd->info->nsizepos == -1)
2369 dcd->sortFlags &= (~SORT_EASIZE);
2370 if (dcd->info->osizepos == -1)
2371 dcd->sortFlags &= (~SORT_SIZE);
2372 AdjustCnrColVis(hwnd,
2373 GetPString(IDS_OLDSIZECOLTEXT),
2374 dcd->info->osizepos != -1, FALSE);
2375 AdjustCnrColVis(hwnd,
2376 GetPString(IDS_NEWSIZECOLTEXT),
2377 dcd->info->nsizepos != -1, FALSE);
2378 // Display unsullied date/time string if type 0
2379 AdjustCnrColVis(hwnd,
2380 GetPString(IDS_DATETIMECOLTEXT),
2381 dcd->info->fdpos != -1 && !dcd->info->datetype, FALSE);
2382 // Display parsed date/time columns if type specified
2383 AdjustCnrColVis(hwnd,
2384 GetPString(IDS_TIMECOLTEXT),
2385 dcd->info->fdpos != -1 && dcd->info->datetype, FALSE);
2386 AdjustCnrColVis(hwnd,
2387 GetPString(IDS_DATECOLTEXT),
2388 dcd->info->fdpos != -1 && dcd->info->datetype, FALSE);
2389 WinSendMsg(hwnd, CM_INVALIDATEDETAILFIELDINFO, MPVOID, MPVOID);
2390 }
2391 return 0;
2392
2393 case UM_RESCAN:
2394 if (dcd) {
2395 CNRINFO cnri;
2396 CHAR s[CCHMAXPATH * 2], tb[81], tf[81];
2397 PARCITEM pci;
2398
2399 if (mp1) {
2400 PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPVOID);
2401 return 0;
2402 }
2403 memset(&cnri, 0, sizeof(CNRINFO));
2404 cnri.cb = sizeof(CNRINFO);
2405 WinSendMsg(hwnd,
2406 CM_QUERYCNRINFO,
2407 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
2408 dcd->totalfiles = cnri.cRecords;
2409 commafmt(tf, sizeof(tf), dcd->selectedfiles);
2410 if (dcd->ullTotalBytes)
2411 CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, 'K');
2412 else
2413 *tb = 0;
2414 sprintf(s, "%s%s%s", tf, *tb ? " / " : NullStr, tb);
2415 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
2416 commafmt(tf, sizeof(tf), dcd->totalfiles);
2417 if (dcd->ullTotalBytes)
2418 CommaFmtULL(tb, sizeof(tb), dcd->ullTotalBytes, 'K');
2419 else
2420 *tb = 0;
2421 sprintf(s, "%s%s%s", tf, *tb ? " / " : NullStr, tb);
2422 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, s);
2423 if (hwndStatus &&
2424 dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
2425 sprintf(s, " [%s%s%s]%s%s%s %s",
2426 tf,
2427 *tb ? " / " : NullStr,
2428 tb,
2429 *dcd->mask.szMask ? " (" : NullStr,
2430 *dcd->mask.szMask ? dcd->mask.szMask : NullStr,
2431 *dcd->mask.szMask ? ")" : NullStr, dcd->arcname);
2432 WinSetWindowText(hwndStatus, s);
2433 if (!ParentIsDesktop(hwnd, dcd->hwndParent)) {
2434 pci = WinSendMsg(hwnd,
2435 CM_QUERYRECORDEMPHASIS,
2436 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
2437 if (pci && (INT) pci != -1) {
2438 if (fSplitStatus && hwndStatus2) {
2439 if (dcd->ullTotalBytes)
2440 CommaFmtULL(tb, sizeof(tb), pci->cbFile, ' ');
2441 else
2442 *tb = 0;
2443 sprintf(s, "%s%s%s%s",
2444 *tb ? " " : NullStr,
2445 tb, *tb ? " " : NullStr, pci->pszFileName);
2446 WinSetWindowText(hwndStatus2, s);
2447 }
2448 if (fMoreButtons)
2449 WinSetWindowText(hwndName, pci->pszFileName);
2450 }
2451 else {
2452 WinSetWindowText(hwndStatus2, NullStr);
2453 WinSetWindowText(hwndName, NullStr);
2454 }
2455 WinSetWindowText(hwndDate, NullStr);
2456 WinSetWindowText(hwndAttr, NullStr);
2457 }
2458 }
2459 if ((dcd->arcfilled && !dcd->totalfiles) ||
2460 !IsArcThere(hwnd, dcd->arcname))
2461 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2462 }
2463 return 0;
2464
2465 case UM_SETUP:
2466 if (!dcd) {
2467 Runtime_Error(pszSrcFile, __LINE__, NULL);
2468 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2469 return 0;
2470 }
2471 else {
2472 if (!dcd->hwndObject) {
2473 /**
2474 * first time through -- set things up
2475 */
2476 {
2477 CHAR *p;
2478 ULONG z, was;
2479 APIRET rc;
2480
2481 rc = DosCreateDir(dcd->workdir, 0);
2482 if (rc) {
2483 if (rc == ERROR_ACCESS_DENIED) {
2484 p = strrchr(dcd->workdir, '.');
2485 if (p) { /* jbs: What if there is no "."? Give up? */
2486 p++;
2487 was = strtoul(p, NULL, 16);
2488 for (z = 0; z < 99; z++) {
2489 was++;
2490 sprintf(p, "%03x", was);
2491 rc = DosCreateDir(dcd->workdir, 0);
2492 if (!rc || rc != ERROR_ACCESS_DENIED)
2493 break;
2494 }
2495 }
2496 }
2497 if (rc) {
2498 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2499 return 0;
2500 }
2501 }
2502 }
2503 RestorePresParams(hwnd, PCSZ_ARCCNR);
2504 dcd->mask.fNoAttribs = TRUE;
2505 dcd->mask.fNoDirs = TRUE;
2506 *dcd->mask.prompt = 0;
2507 {
2508 PFIELDINFO pfi, pfiLastLeftCol;
2509 ULONG numcols = CON_COLS;
2510 CNRINFO cnri;
2511 ULONG size;
2512
2513 pfi = WinSendMsg(hwnd,
2514 CM_ALLOCDETAILFIELDINFO,
2515 MPFROMLONG(numcols), NULL);
2516 if (pfi) {
2517
2518 PFIELDINFO pfiFirst;
2519 FIELDINFOINSERT fii;
2520
2521 pfiFirst = pfi;
2522 pfi->flData = CFA_STRING | CFA_LEFT | CFA_FIREADONLY;
2523 pfi->flTitle = CFA_CENTER;
2524 pfi->pTitleData = (PSZ)GetPString(IDS_FILENAMECOLTEXT);
2525 pfi->offStruct = FIELDOFFSET(ARCITEM, pszDisplayName);
2526 pfiLastLeftCol = pfi;
2527 pfi = pfi->pNextFieldInfo;
2528 pfi->flData =
2529 CFA_ULONG | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
2530 pfi->flTitle = CFA_CENTER;
2531 pfi->pTitleData = (PSZ)GetPString(IDS_OLDSIZECOLTEXT);
2532 pfi->offStruct = FIELDOFFSET(ARCITEM, cbFile);
2533 pfi = pfi->pNextFieldInfo;
2534 pfi->flData =
2535 CFA_ULONG | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
2536 pfi->flTitle = CFA_CENTER;
2537 pfi->pTitleData = (PSZ)GetPString(IDS_NEWSIZECOLTEXT);
2538 pfi->offStruct = FIELDOFFSET(ARCITEM, cbComp);
2539 pfi = pfi->pNextFieldInfo;
2540 pfi->flData =
2541 CFA_STRING | CFA_CENTER | CFA_SEPARATOR | CFA_FIREADONLY;
2542 pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
2543 pfi->pTitleData = (PSZ)GetPString(IDS_DATETIMECOLTEXT);
2544 pfi->offStruct = FIELDOFFSET(ARCITEM, pszDate);
2545 pfi = pfi->pNextFieldInfo;
2546 pfi->flData = CFA_DATE | CFA_RIGHT | CFA_FIREADONLY;
2547 pfi->flTitle = CFA_CENTER;
2548 pfi->pTitleData = (PSZ)GetPString(IDS_DATECOLTEXT);
2549 pfi->offStruct = FIELDOFFSET(ARCITEM, date);
2550 pfi = pfi->pNextFieldInfo;
2551 pfi->flData = CFA_TIME | CFA_RIGHT | CFA_FIREADONLY;
2552 pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
2553 pfi->pTitleData = (PSZ)GetPString(IDS_TIMECOLTEXT);
2554 pfi->offStruct = FIELDOFFSET(ARCITEM, time);
2555 memset(&fii, 0, sizeof(FIELDINFOINSERT));
2556 fii.cb = sizeof(FIELDINFOINSERT);
2557 fii.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST;
2558 fii.cFieldInfoInsert = (SHORT) numcols;
2559 fii.fInvalidateFieldInfo = TRUE;
2560 WinSendMsg(hwnd,
2561 CM_INSERTDETAILFIELDINFO,
2562 MPFROMP(pfiFirst), MPFROMP(&fii));
2563 PostMsg(hwnd, UM_SETUP2, MPVOID, MPVOID);
2564
2565 memset(&cnri, 0, sizeof(cnri));
2566 cnri.cb = sizeof(CNRINFO);
2567 cnri.pFieldInfoLast = pfiLastLeftCol;
2568 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET + 32;
2569
2570 size = sizeof(LONG);
2571 PrfQueryProfileData(fmprof, appname, "ArcCnrSplitBar",
2572 &cnri.xVertSplitbar, &size);
2573 if (cnri.xVertSplitbar <= 0)
2574 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET + 32;
2575
2576 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT | CV_NAME));
2577 cnri.flWindowAttr |= (CV_DETAIL | CA_DETAILSVIEWTITLES | CV_FLOW);
2578 cnri.flWindowAttr &= (~(CA_ORDEREDTARGETEMPH |
2579 CA_MIXEDTARGETEMPH));
2580 cnri.pSortRecord = (PVOID) ArcSort;
2581 WinSendMsg(hwnd,
2582 CM_SETCNRINFO,
2583 MPFROMP(&cnri),
2584 MPFROMLONG(CMA_PFIELDINFOLAST |
2585 CMA_XVERTSPLITBAR |
2586 CMA_PSORTRECORD | CMA_FLWINDOWATTR));
2587 }
2588 }
2589 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(ArcSort), MPFROMP(dcd));
2590 if (xbeginthread(MakeObjWin,
2591 245760,
2592 dcd,
2593 pszSrcFile,
2594 __LINE__) == -1)
2595 {
2596 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2597 return 0;
2598 }
2599 else
2600 DosSleep(1);
2601 SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2602 DIR_FILTER), &dcd->mask, TRUE);
2603 SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2604 DIR_SORT), dcd->sortFlags, TRUE);
2605 DefArcSortFlags = dcd->sortFlags; // Remember for new windows
2606 }
2607 }
2608 return 0;
2609
2610 case UM_SETDIR:
2611 if (dcd) {
2612
2613 CHAR s[CCHMAXPATH], *p;
2614 ULONG ret = 0;
2615
2616 WinQueryDlgItemText(dcd->hwndClient, ARC_EXTRACTDIR, CCHMAXPATH, s);
2617 bstrip(s);
2618 MakeFullName(s);
2619 if (*s) {
2620 while ((p = strchr(s, '/')) != NULL)
2621 *p = '\\';
2622 while (strlen(s) > 3 && s[strlen(s) - 1] == '\\')
2623 s[strlen(s) - 1] = 0;
2624 if (stricmp(s, dcd->directory)) {
2625 if (IsFullName(s)) {
2626 if (driveflags[toupper(*s) - 'A'] &
2627 (DRIVE_NOTWRITEABLE | DRIVE_IGNORE | DRIVE_INVALID)) {
2628 Runtime_Error(pszSrcFile, __LINE__, "drive %s bad", s);
2629 WinSetDlgItemText(dcd->hwndClient,
2630 ARC_EXTRACTDIR, dcd->directory);
2631 return 0;
2632 }
2633 }
2634 if (!SetDir(dcd->hwndParent, hwnd, s, 0)) {
2635 if (stricmp(dcd->directory, s)) {
2636 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
2637 strcpy(lastextractpath, s);
2638 DosReleaseMutexSem(hmtxFM2Globals);
2639 }
2640 strcpy(dcd->directory, s);
2641 if ((!isalpha(*s) || s[1] != ':') && *s != '.')
2642 saymsg(MB_ENTER | MB_ICONASTERISK,
2643 hwnd,
2644 GetPString(IDS_WARNINGTEXT),
2645 GetPString(IDS_SPECIFYDRIVETEXT));
2646 }
2647 else
2648 ret = 1;
2649 }
2650 }
2651 WinSetDlgItemText(dcd->hwndClient, ARC_EXTRACTDIR, dcd->directory);
2652 return (MRESULT) ret;
2653 }
2654 return 0;
2655
2656 case UM_ENTER:
2657 if (WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID)) {
2658 free(mp1);
2659 return 0;
2660 }
2661 SetShiftState();
2662 if (dcd && (CHAR *) mp1) {
2663
2664 SWP swp;
2665 CHAR *filename = mp1;
2666 if (IsFile(filename) != 1) {
2667 free(mp1);
2668 return 0;
2669 }
2670 WinQueryWindowPos(dcd->hwndFrame, &swp);
2671 DefaultViewKeys(hwnd, dcd->hwndFrame, dcd->hwndParent, &swp, filename);
2672 if (fUnHilite)
2673 UnHilite(hwnd, FALSE, &dcd->lastselection, 0);
2674 }
2675 free(mp1);
2676 return 0;
2677
2678 case WM_MENUEND:
2679 if (dcd) {
2680
2681 HWND hwndMenu = (HWND) mp2;
2682
2683 if (hwndMenu == ArcCnrMenu || hwndMenu == ArcMenu) {
2684 MarkAll(hwnd, TRUE, FALSE, TRUE);
2685 if (dcd->cnremphasized) {
2686 WinSendMsg(hwnd,
2687 CM_SETRECORDEMPHASIS,
2688 MPVOID, MPFROM2SHORT(FALSE, CRA_SOURCE));
2689 dcd->cnremphasized = FALSE;
2690 }
2691 }
2692 }
2693 break;
2694
2695 case MM_PORTHOLEINIT:
2696 if (dcd) {
2697 switch (SHORT1FROMMP(mp1)) {
2698 case 0:
2699 case 1:
2700 {
2701 ULONG wmsg;
2702
2703 wmsg = SHORT1FROMMP(mp1) == 0 ? UM_FILESMENU : UM_VIEWSMENU;
2704 PortholeInit((HWND) WinSendMsg(dcd->hwndClient,
2705 wmsg, MPVOID, MPVOID), mp1, mp2);
2706 }
2707 break;
2708 }
2709 }
2710 break;
2711
2712 case UM_INITMENU:
2713 case WM_INITMENU:
2714 if (dcd) {
2715 switch (SHORT1FROMMP(mp1)) {
2716 case IDM_FILESMENU:
2717 if (dcd->info) {
2718 WinEnableMenuItem((HWND) mp2,
2719 IDM_DELETE, dcd->info->delete != NULL);
2720 WinEnableMenuItem((HWND) mp2, IDM_TEST, dcd->info->test != NULL);
2721 WinEnableMenuItem((HWND) mp2, IDM_EXTRACT,
2722 dcd->info->extract != NULL && !strstr(dcd->info->ext, "TAR"));
2723 WinEnableMenuItem((HWND) mp2, IDM_ARCEXTRACT,
2724 dcd->info->extract != NULL && !strstr(dcd->info->ext, "TAR"));
2725 WinEnableMenuItem((HWND) mp2,
2726 IDM_EXTRACTWDIRS, dcd->info->exwdirs != NULL);
2727 WinEnableMenuItem((HWND) mp2,
2728 IDM_ARCEXTRACTWDIRS, dcd->info->exwdirs != NULL);
2729 WinEnableMenuItem((HWND) mp2,
2730 IDM_ARCEXTRACTWDIRSEXIT,
2731 dcd->info->exwdirs != NULL);
2732 }
2733 break;
2734
2735 case IDM_VIEWSMENU:
2736 WinEnableMenuItem((HWND) mp2, IDM_TEST, dcd->info->test != NULL);
2737 WinEnableMenuItem((HWND) mp2, IDM_ARCEXTRACT,
2738 dcd->info->extract != NULL && !strstr(dcd->info->ext, "TAR"));
2739 WinCheckMenuItem((HWND) mp2,
2740 IDM_MINIICONS, (dcd->flWindowAttr & CV_MINI) != 0);
2741 WinEnableMenuItem((HWND) mp2,
2742 IDM_RESELECT, (dcd->lastselection != NULL));
2743 break;
2744
2745 case IDM_COMMANDSMENU:
2746 SetupCommandMenu((HWND) mp2, hwnd);
2747 break;
2748
2749 case IDM_SORTSUBMENU:
2750 SetSortChecks((HWND) mp2, dcd->sortFlags);
2751 break;
2752
2753 case IDM_WINDOWSMENU:
2754 /**
2755 * add switchlist entries to end of pulldown menu
2756 */
2757 SetupWinList((HWND)mp2,
2758 hwndMain ? hwndMain : (HWND)0, dcd->hwndFrame);
2759 break;
2760 }
2761 dcd->hwndLastMenu = (HWND) mp2;
2762 }
2763 if (msg == WM_INITMENU)
2764 break;
2765 return 0;
2766
2767 case UM_LOADFILE:
2768 if (dcd && mp2) {
2769
2770 HWND hwnd;
2771
2772 if ((INT)mp1 == 5 || (INT)mp1 == 13 || (INT)mp1 == 21)
2773 hwnd = StartViewer(HWND_DESKTOP, (INT)mp1,
2774 (CHAR *)mp2, dcd->hwndFrame);
2775 else
2776 hwnd = StartMLEEditor(dcd->hwndParent,
2777 (INT)mp1, (CHAR *)mp2, dcd->hwndFrame);
2778 free((CHAR *)mp2);
2779 return MRFROMLONG(hwnd);
2780 }
2781 return 0;
2782
2783 case UM_COMMAND:
2784 if (mp1) {
2785 if (dcd) {
2786 if (!PostMsg(dcd->hwndObject, UM_COMMAND, mp1, mp2)) {
2787 Runtime_Error(pszSrcFile, __LINE__, "post");
2788 FreeListInfo((LISTINFO *) mp1);
2789 }
2790 else
2791 return (MRESULT) TRUE;
2792 }
2793 else
2794 FreeListInfo((LISTINFO *) mp1);
2795 }
2796 return 0;
2797
2798 case UM_OPENWINDOWFORME:
2799 if (dcd) {
2800 if (mp1 && !IsFile((CHAR *) mp1)) {
2801 OpenDirCnr((HWND) 0, hwndMain, dcd->hwndFrame, FALSE, (char *)mp1);
2802 }
2803 else if (mp1 && IsFile(mp1) == 1 &&
2804 CheckDriveSpaceAvail(ArcTempRoot, ullDATFileSpaceNeeded, ullTmpSpaceNeeded) != 2) {
2805 StartArcCnr(HWND_DESKTOP,
2806 dcd->hwndFrame, (CHAR *) mp1, 4, (ARC_TYPE *) mp2);
2807 }
2808 }
2809 return 0;
2810
2811 case WM_COMMAND:
2812 DosError(FERR_DISABLEHARDERR);
2813 if (dcd) {
2814 if (SwitchCommand(dcd->hwndLastMenu, SHORT1FROMMP(mp1)))
2815 return 0;
2816 if (WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID))
2817 return 0;
2818 if (!IsArcThere(hwnd, dcd->arcname)) {
2819 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2820 return 0;
2821 }
2822 switch (SHORT1FROMMP(mp1)) {
2823 case IDM_TREEVIEW:
2824
2825 break;
2826
2827 case IDM_CONTEXTMENU:
2828 {
2829 PCNRITEM pci;
2830
2831 pci = (PCNRITEM) CurrentRecord(hwnd);
2832 PostMsg(hwnd,
2833 WM_CONTROL,
2834 MPFROM2SHORT(ARC_CNR, CN_CONTEXTMENU), MPFROMP(pci));
2835 }
2836 break;
2837
2838 case IDM_NEXTWINDOW:
2839 case IDM_PREVWINDOW:
2840 {
2841 HWND hwndActive;
2842
2843 hwndActive = WinQueryFocus(HWND_DESKTOP);
2844 WinSetFocus(HWND_DESKTOP,
2845 hwndActive == hwnd ?
2846 WinWindowFromID(dcd->hwndClient, ARC_EXTRACTDIR) :
2847 hwnd);
2848 }
2849 break;
2850
2851 case IDM_FOLDERAFTEREXTRACT:
2852 fFolderAfterExtract = fFolderAfterExtract ? FALSE : TRUE;
2853 PrfWriteProfileData(fmprof, appname, "FolderAfterExtract",
2854 &fFolderAfterExtract, sizeof(BOOL));
2855 break;
2856
2857 case IDM_SHOWSELECT:
2858 QuickPopup(hwnd, dcd, CheckMenu(hwnd, &ArcCnrMenu, ARCCNR_POPUP),
2859 IDM_SELECTSUBMENU);
2860 break;
2861
2862 case IDM_SHOWSORT:
2863 QuickPopup(hwnd, dcd, CheckMenu(hwnd, &ArcCnrMenu, ARCCNR_POPUP),
2864 IDM_SORTSUBMENU);
2865 break;
2866
2867 case IDM_ARCHIVERSETTINGS:
2868 if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndParent))
2869 PostMsg(dcd->hwndParent, msg, MPFROMLONG(IDM_ARCHIVERSETTINGS), mp2);
2870 else {
2871 WinDlgBox(HWND_DESKTOP,
2872 hwnd,
2873 CfgDlgProc,
2874 FM3ModHandle,
2875 CFG_FRAME,
2876 MPFROMLONG(IDM_ARCHIVERSETTINGS));
2877 }
2878 break;
2879
2880 case IDM_RESCAN:
2881 dcd->ullTotalBytes = dcd->totalfiles =
2882 dcd->selectedfiles = dcd->selectedbytes = 0;
2883 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, "0");
2884 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, "0 / 0k");
2885 dcd->totalfiles = FillArcCnr(dcd->hwndCnr,
2886 dcd->arcname,
2887 &dcd->info,
2888 &dcd->ullTotalBytes, &dcd->stopflag);
2889 PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
2890 PostMsg(dcd->hwndCnr, UM_SETUP2, MPVOID, MPVOID);
2891 WinSendMsg(dcd->hwndCnr,
2892 CM_INVALIDATERECORD,
2893 MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
2894 break;
2895
2896 case IDM_RESELECT:
2897 SelectList(hwnd, TRUE, FALSE, FALSE, NULL, NULL, dcd->lastselection);
2898 break;
2899
2900 case IDM_HELP:
2901 if (hwndHelp)
2902 WinSendMsg(hwndHelp,
2903 HM_DISPLAY_HELP,
2904 MPFROM2SHORT(HELP_ARCLIST, 0),
2905 MPFROMSHORT(HM_RESOURCEID));
2906 break;
2907
2908 case IDM_WINDOWDLG:
2909 if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndFrame))
2910 PostMsg(dcd->hwndParent,
2911 UM_COMMAND, MPFROM2SHORT(IDM_WINDOWDLG, 0), MPVOID);
2912 break;
2913
2914 case IDM_SELECTALL:
2915 case IDM_SELECTALLFILES:
2916 case IDM_DESELECTALL:
2917 case IDM_DESELECTALLFILES:
2918 case IDM_SELECTMASK:
2919 case IDM_DESELECTMASK:
2920 case IDM_INVERT:
2921 {
2922 PARCITEM pci;
2923
2924 pci = (PARCITEM) WinSendMsg(hwnd,
2925 CM_QUERYRECORDEMPHASIS,
2926 MPFROMLONG(CMA_FIRST),
2927 MPFROMSHORT(CRA_CURSORED));
2928 if ((INT) pci == -1)
2929 pci = NULL;
2930 if (SHORT1FROMMP(mp1) == IDM_HIDEALL) {
2931 if (pci) {
2932 if (!(pci->rc.flRecordAttr & CRA_SELECTED))
2933 pci->rc.flRecordAttr |= CRA_FILTERED;
2934 WinSendMsg(hwnd,
2935 CM_INVALIDATERECORD,
2936 MPFROMP(&pci),
2937 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
2938 break;
2939 }
2940 }
2941 PostMsg(dcd->hwndObject, UM_SELECT, mp1, MPFROMP(pci));
2942 }
2943 break;
2944
2945 case IDM_SORTSMARTNAME:
2946 case IDM_SORTNAME:
2947 case IDM_SORTFILENAME:
2948 case IDM_SORTSIZE:
2949 case IDM_SORTEASIZE:
2950 case IDM_SORTFIRST:
2951 case IDM_SORTLAST:
2952 case IDM_SORTLWDATE:
2953 dcd->sortFlags &= SORT_REVERSE;
2954 // intentional fallthru
2955 case IDM_SORTREVERSE:
2956 switch (SHORT1FROMMP(mp1)) {
2957 case IDM_SORTSMARTNAME:
2958 case IDM_SORTFILENAME:
2959 dcd->sortFlags |= SORT_FILENAME;
2960 break;
2961 case IDM_SORTSIZE:
2962 dcd->sortFlags |= SORT_SIZE;
2963 break;
2964 case IDM_SORTEASIZE:
2965 dcd->sortFlags |= SORT_EASIZE;
2966 break;
2967 case IDM_SORTFIRST:
2968 dcd->sortFlags |= SORT_FIRSTEXTENSION;
2969 break;
2970 case IDM_SORTLAST:
2971 dcd->sortFlags |= SORT_LASTEXTENSION;
2972 break;
2973 case IDM_SORTLWDATE:
2974 dcd->sortFlags |= SORT_LWDATE;
2975 break;
2976 case IDM_SORTREVERSE:
2977 if (dcd->sortFlags & SORT_REVERSE)
2978 dcd->sortFlags &= (~SORT_REVERSE);
2979 else
2980 dcd->sortFlags |= SORT_REVERSE;
2981 break;
2982 }
2983 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(ArcSort), MPFROMP(dcd));
2984 SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2985 DIR_SORT), dcd->sortFlags, TRUE);
2986 DefArcSortFlags = dcd->sortFlags; // Remember for new windows
2987 break;
2988
2989 case IDM_COLLECTOR:
2990 if (!Collector) {
2991 HWND hwndC;
2992 SWP swp;
2993
2994 if (ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
2995 (!fExternalCollector && !strcmp(realappname, FM3Str)))
2996 GetNextWindowPos(dcd->hwndParent, &swp, NULL, NULL);
2997 hwndC = StartCollector(fExternalCollector ||
2998 strcmp(realappname, FM3Str) ?
2999 HWND_DESKTOP : dcd->hwndParent, 4);
3000 if (hwndC) {
3001 if (!ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
3002 (!fExternalCollector && !strcmp(realappname, FM3Str)))
3003 WinSetWindowPos(hwndC,
3004 HWND_TOP,
3005 swp.x,
3006 swp.y,
3007 swp.cx,
3008 swp.cy,
3009 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
3010 else if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3011 fAutoTile && !strcmp(realappname, FM3Str)) {
3012 TileChildren(dcd->hwndParent, TRUE);
3013 }
3014 WinSetWindowPos(hwndC, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
3015 DosSleep(100);
3016 }
3017 }
3018 else
3019 StartCollector(dcd->hwndParent, 4);
3020 break;
3021
3022 case IDM_ARCEXTRACTEXIT:
3023 case IDM_ARCEXTRACT:
3024 if (dcd->directory && fFileNameCnrPath &&
3025 stricmp(lastextractpath, dcd->directory)) {
3026 strcpy(lastextractpath, dcd->directory);
3027 SetDir(dcd->hwndParent, hwnd, dcd->directory, 1);
3028 }
3029 if (dcd->info->extract)
3030 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS |
3031 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
3032 hwnd, pszSrcFile, __LINE__,
3033 dcd->directory, NULL, "%s %s", dcd->info->extract,
3034 BldQuotedFileName(szQuotedArcName, dcd->arcname));
3035 if (SHORT1FROMMP(mp1) == IDM_ARCEXTRACTEXIT)
3036 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
3037 break;
3038
3039 case IDM_ARCEXTRACTWDIRSEXIT:
3040 case IDM_ARCEXTRACTWDIRS:
3041 if (dcd->directory && fFileNameCnrPath &&
3042 stricmp(lastextractpath, dcd->directory)) {
3043 strcpy(lastextractpath, dcd->directory);
3044 SetDir(dcd->hwndParent, hwnd, dcd->directory, 1);
3045 }
3046 if (dcd->info->exwdirs)
3047 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS |
3048 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
3049 hwnd, pszSrcFile, __LINE__,
3050 dcd->directory, NULL, "%s %s",
3051 dcd->info->exwdirs,
3052 BldQuotedFileName(szQuotedArcName, dcd->arcname));
3053 if (SHORT1FROMMP(mp1) == IDM_ARCEXTRACTWDIRSEXIT)
3054 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
3055 break;
3056
3057 case IDM_RESORT:
3058 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(ArcSort), MPFROMP(dcd));
3059 break;
3060
3061 case IDM_FILTER:
3062 {
3063 BOOL empty = FALSE;
3064 PARCITEM pci;
3065
3066 if (!*dcd->mask.szMask) {
3067 empty = TRUE;
3068 pci = (PARCITEM) CurrentRecord(hwnd);
3069 if (pci && (INT) pci != -1 && strchr(pci->pszFileName, '.'))
3070 strcpy(dcd->mask.szMask, pci->pszFileName);
3071 }
3072
3073 if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
3074 FM3ModHandle, MSK_FRAME, MPFROMP(&dcd->mask))) {
3075 WinSendMsg(hwnd, CM_FILTER, MPFROMP(ArcFilter), MPFROMP(dcd));
3076 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3077 }
3078 else if (empty)
3079 *dcd->mask.szMask = 0;
3080 SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
3081 DIR_FILTER), &dcd->mask, TRUE);
3082 }
3083 break;
3084
3085 case IDM_SWITCH:
3086 if (mp2) {
3087 if (stricmp(dcd->directory, (CHAR *) mp2)) {
3088 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
3089 strcpy(lastextractpath, (CHAR *) mp2);
3090 MakeValidDir(lastextractpath);
3091 DosReleaseMutexSem(hmtxFM2Globals);
3092 }
3093 strcpy(dcd->directory, (CHAR *) mp2);
3094 MakeValidDir(dcd->directory);
3095 WinSetWindowText(dcd->hwndExtract, dcd->directory);
3096 }
3097 break;
3098
3099 case IDM_WALKDIR:
3100 {
3101 CHAR newdir[CCHMAXPATH];
3102
3103 strcpy(newdir, dcd->directory);
3104 if (!WinDlgBox(HWND_DESKTOP, dcd->hwndParent, WalkExtractDlgProc,
3105 FM3ModHandle, WALK_FRAME,
3106 MPFROMP(newdir)) || !*newdir)
3107 break;
3108 if (stricmp(newdir, dcd->directory)) {
3109 strcpy(dcd->directory, newdir);
3110 if (stricmp(lastextractpath, newdir))
3111 strcpy(lastextractpath, newdir);
3112 WinSetWindowText(dcd->hwndExtract, dcd->directory);
3113 }
3114 }
3115 break;
3116
3117 case IDM_TEST:
3118 if (dcd->info->test)
3119 runemf2(SEPARATEKEEP | WINDOWED | MAXIMIZED,
3120 hwnd, pszSrcFile, __LINE__, NULL, NULL,
3121 "%s %s",dcd->info->test,
3122 BldQuotedFileName(szQuotedArcName, dcd->arcname));
3123 break;
3124
3125 case IDM_REFRESH:
3126 case IDM_DELETE:
3127 case IDM_PRINT:
3128 case IDM_VIEW:
3129 case IDM_VIEWTEXT:
3130 case IDM_VIEWBINARY:
3131 case IDM_VIEWARCHIVE:
3132 case IDM_EDIT:
3133 case IDM_EDITTEXT:
3134 case IDM_EDITBINARY:
3135 case IDM_EXTRACT:
3136 case IDM_EXTRACTWDIRS:
3137 case IDM_FIND:
3138 case IDM_EXEC:
3139 case IDM_VIRUSSCAN:
3140 case IDM_OPENDEFAULT:
3141 case IDM_OPENSETTINGS:
3142 case IDM_MCIPLAY:
3143 {
3144 LISTINFO *li;
3145# ifdef FORTIFY
3146 Fortify_EnterScope();
3147# endif
3148 li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
3149 if (li) {
3150 li->type = SHORT1FROMMP(mp1);
3151 li->hwnd = hwnd;
3152 li->list = BuildArcList(hwnd);
3153 if (li->type == IDM_DELETE)
3154 ignorereadonly = FALSE;
3155 if (li->type == IDM_REFRESH) {
3156
3157 CHAR s[CCHMAXPATH], *p;
3158 INT x, y;
3159
3160 for (x = 0; li->list && li->list[x]; x++) {
3161 BldFullPathName(s, dcd->workdir, li->list[x]);
3162 if (IsFile(s) != 1) {
3163 free(li->list[x]);
3164 li->list[x] = NULL;
3165 for (y = x; li->list[y]; y++)
3166 li->list[y] = li->list[y + 1];
3167 li->list =
3168 xrealloc(li->list, y * sizeof(CHAR *), pszSrcFile,
3169 __LINE__);
3170 x--;
3171 }
3172 else {
3173 p = xstrdup(s, pszSrcFile, __LINE__);
3174 if (p) {
3175 free(li->list[x]);
3176 li->list[x] = p;
3177 }
3178 }
3179 } // for
3180 }
3181 strcpy(li->arcname, dcd->arcname);
3182 li->info = dcd->info;
3183 {
3184 PARCITEM pai;
3185
3186 if (SHORT1FROMMP(mp1) != IDM_EXEC)
3187 pai = (PARCITEM) CurrentRecord(hwnd);
3188 else
3189 pai = (PARCITEM) WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
3190 MPFROMLONG(CMA_FIRST),
3191 MPFROMSHORT(CRA_CURSORED));
3192 if (pai && (INT) pai != -1)
3193 strcpy(li->runfile, pai->pszFileName);
3194 else
3195 strcpy(li->runfile, li->list[0]);
3196 }
3197 switch (SHORT1FROMMP(mp1)) {
3198 case IDM_VIEW:
3199 case IDM_VIEWTEXT:
3200 case IDM_VIEWBINARY:
3201 case IDM_VIEWARCHIVE:
3202 case IDM_EDIT:
3203 case IDM_EDITTEXT:
3204 case IDM_EDITBINARY:
3205 case IDM_EXEC:
3206 case IDM_PRINT:
3207 case IDM_VIRUSSCAN:
3208 case IDM_OPENDEFAULT:
3209 case IDM_OPENSETTINGS:
3210 case IDM_MCIPLAY:
3211 strcpy(li->targetpath, dcd->workdir);
3212 break;
3213 default:
3214 strcpy(li->targetpath, dcd->directory);
3215 break;
3216 }
3217 if (li->list) {
3218 if (!PostMsg(dcd->hwndObject, UM_ACTION, MPFROMP(li), MPVOID)) {
3219 Runtime_Error(pszSrcFile, __LINE__, "post");
3220 FreeListInfo(li);
3221 }
3222 else if (fUnHilite && SHORT1FROMMP(mp1) != IDM_EDIT)
3223 UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
3224 }
3225 else {
3226 free(li);
3227 }
3228 }
3229# ifdef FORTIFY
3230 Fortify_LeaveScope();
3231# endif
3232 }
3233 break;
3234 }
3235 }
3236 return 0;
3237
3238 case WM_CONTROL:
3239 DosError(FERR_DISABLEHARDERR);
3240 if (dcd) {
3241 switch (SHORT2FROMMP(mp1)) {
3242 case CN_BEGINEDIT:
3243 PostMsg(hwnd, CM_CLOSEEDIT, MPVOID, MPVOID);
3244 break;
3245
3246 case CN_ENDEDIT:
3247 if (!((PCNREDITDATA) mp2)->pRecord) {
3248
3249 PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
3250 USHORT cmd = 0;
3251
3252 if (!pfi || pfi->offStruct == FIELDOFFSET(ARCITEM, pszDisplayName))
3253 cmd = IDM_SORTSMARTNAME;
3254 else if (pfi->offStruct == FIELDOFFSET(ARCITEM, cbFile))
3255 cmd = IDM_SORTSIZE;
3256 else if (pfi->offStruct == FIELDOFFSET(ARCITEM, cbComp))
3257 cmd = IDM_SORTEASIZE;
3258 else if (pfi->offStruct == FIELDOFFSET(ARCITEM, date))
3259 cmd = IDM_SORTLWDATE;
3260 else if (pfi->offStruct == FIELDOFFSET(ARCITEM, time))
3261 cmd = IDM_SORTLWDATE;
3262 if (cmd)
3263 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
3264 }
3265 break;
3266
3267 case CN_DROPHELP:
3268 saymsg(MB_ENTER, hwnd,
3269 GetPString(IDS_DROPHELPHDRTEXT),
3270 GetPString(IDS_ARCCNRDROPHELPTEXT), dcd->arcname);
3271 return 0;
3272
3273 case CN_DRAGLEAVE:
3274 if (mp2) {
3275
3276 PDRAGINFO pDInfo;
3277
3278 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
3279 DrgAccessDraginfo(pDInfo); // Access DRAGINFO
3280 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
3281 }
3282 return 0;
3283
3284 case CN_DRAGAFTER:
3285 case CN_DRAGOVER:
3286 if (mp2) {
3287
3288 PDRAGITEM pDItem; // Pointer to DRAGITEM
3289 PDRAGINFO pDInfo; // Pointer to DRAGINFO
3290 PARCITEM pci;
3291
3292 pci = (PARCITEM) ((PCNRDRAGINFO) mp2)->pRecord;
3293 if (SHORT1FROMMP(mp1) == CN_DRAGAFTER)
3294 pci = NULL;
3295 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
3296 DrgAccessDraginfo(pDInfo); // Access DRAGINFO
3297 if (*dcd->arcname) {
3298 if ((driveflags[toupper(*dcd->arcname) - 'A'] &
3299 DRIVE_NOTWRITEABLE) || !dcd->info || !dcd->info->create) {
3300 DrgFreeDraginfo(pDInfo);
3301 return MRFROM2SHORT(DOR_NEVERDROP, 0);
3302 }
3303 }
3304 if (pci && (INT) pci != -1) {
3305 DrgFreeDraginfo(pDInfo);
3306 return MRFROM2SHORT(DOR_NODROP, 0);
3307 }
3308 pDItem = DrgQueryDragitemPtr(pDInfo, // Access DRAGITEM
3309 0); // Index to DRAGITEM
3310 if (DrgVerifyRMF(pDItem, // Check valid rendering
3311 (CHAR *) DRM_OS2FILE, // mechanisms and data
3312 NULL) && !(pDItem->fsControl & DC_PREPARE)) {
3313 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
3314 return MRFROM2SHORT(DOR_DROP, // Return okay to drop
3315 fCopyDefault ? DO_COPY : DO_MOVE);
3316 }
3317 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
3318 }
3319 return (MRFROM2SHORT(DOR_NEVERDROP, 0)); // Drop not valid
3320
3321 case CN_INITDRAG:
3322 if (mp2) {
3323
3324 BOOL wasemphasized = FALSE;
3325 PCNRDRAGINIT pcd = (PCNRDRAGINIT) mp2;
3326 PARCITEM pci;
3327
3328 if (pcd) {
3329 pci = (PARCITEM) pcd->pRecord;
3330 if (pci && (INT) pci != -1) {
3331 if (pci->rc.flRecordAttr & CRA_SELECTED)
3332 wasemphasized = TRUE;
3333 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3334 fSplitStatus && hwndStatus2)
3335 WinSetWindowText(hwndStatus2, (CHAR *) GetPString(IDS_DRAGARCMEMTEXT));
3336 if (DoFileDrag(hwnd,
3337 dcd->hwndObject,
3338 mp2, dcd->arcname, NULL, TRUE)) {
3339 if ((fUnHilite && wasemphasized) || dcd->ulItemsToUnHilite)
3340 UnHilite(hwnd, TRUE, &dcd->lastselection, dcd->ulItemsToUnHilite);
3341 }
3342 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3343 fSplitStatus && hwndStatus2) {
3344 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3345 }
3346 }
3347 else {
3348 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3349 fSplitStatus && hwndStatus2)
3350 WinSetWindowText(hwndStatus2,
3351 (CHAR *) GetPString(IDS_DRAGARCFILETEXT));
3352 DragOne(hwnd, dcd->hwndObject, dcd->arcname, FALSE);
3353 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3354 fSplitStatus && hwndStatus2)
3355 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3356 }
3357 }
3358 }
3359 return 0;
3360
3361 case CN_DROP:
3362 if (mp2) {
3363
3364 LISTINFO *li;
3365
3366 li = DoFileDrop(hwnd, dcd->arcname, FALSE, mp1, mp2);
3367 CheckPmDrgLimit(((PCNRDRAGINFO)mp2)->pDragInfo);
3368 if (li) {
3369 li->type = li->type == DO_MOVE ? IDM_ARCHIVEM : IDM_ARCHIVE;
3370 strcpy(li->targetpath, dcd->arcname);
3371 if (!li->list ||
3372 !li->list[0] ||
3373 !PostMsg(dcd->hwndObject, UM_ACTION, MPFROMP(li), MPVOID))
3374 FreeListInfo(li);
3375 }
3376 }
3377 return 0;
3378
3379 case CN_CONTEXTMENU:
3380 {
3381 PARCITEM pci = (PARCITEM) mp2;
3382
3383 if (pci && (INT) pci != -1) {
3384 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPFROMP(pci),
3385 MPFROM2SHORT(TRUE, CRA_CURSORED));
3386 MarkAll(hwnd, FALSE, FALSE, TRUE);
3387 dcd->hwndLastMenu = CheckMenu(hwnd, &ArcMenu, ARC_POPUP);
3388 }
3389 else {
3390 dcd->hwndLastMenu = CheckMenu(hwnd, &ArcCnrMenu, ARCCNR_POPUP);
3391 if (dcd->hwndLastMenu && !dcd->cnremphasized) {
3392 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
3393 MPFROM2SHORT(TRUE, CRA_SOURCE));
3394 dcd->cnremphasized = TRUE;
3395 }
3396 }
3397 if (dcd->hwndLastMenu) {
3398 if (dcd->hwndLastMenu == ArcCnrMenu) {
3399 if (dcd->flWindowAttr & CV_MINI)
3400 WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
3401 }
3402 WinCheckMenuItem(dcd->hwndLastMenu, IDM_FOLDERAFTEREXTRACT,
3403 fFolderAfterExtract);
3404 if (!PopupMenu(hwnd, hwnd, dcd->hwndLastMenu)) {
3405 if (dcd->cnremphasized) {
3406 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
3407 MPFROM2SHORT(FALSE, CRA_SOURCE));
3408 dcd->cnremphasized = TRUE;
3409 }
3410 MarkAll(hwnd, TRUE, FALSE, TRUE);
3411 }
3412 }
3413 }
3414 break;
3415
3416 case CN_EMPHASIS:
3417 if (mp2) {
3418
3419 PNOTIFYRECORDEMPHASIS pre = mp2;
3420 PARCITEM pci;
3421 CHAR s[CCHMAXPATHCOMP + 91], tf[81], tb[81];
3422
3423 pci = (PARCITEM)(pre ? pre->pRecord : NULL);
3424 if (!pci) {
3425 if (!ParentIsDesktop(hwnd, dcd->hwndParent)) {
3426 if (hwndStatus2)
3427 WinSetWindowText(hwndStatus2, NullStr);
3428 if (fMoreButtons)
3429 WinSetWindowText(hwndName, NullStr);
3430 }
3431 break;
3432 }
3433 if (pre->fEmphasisMask & CRA_SELECTED) {
3434 if (pci->rc.flRecordAttr & CRA_SELECTED) {
3435 dcd->selectedbytes += pci->cbFile;
3436 dcd->selectedfiles++;
3437 }
3438 else if (dcd->selectedfiles) {
3439 dcd->selectedbytes -= pci->cbFile;
3440 dcd->selectedfiles--;
3441 }
3442 commafmt(tf, sizeof(tf), dcd->selectedfiles);
3443 if (dcd->ullTotalBytes)
3444 CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, ' ');
3445 else
3446 *tb = 0;
3447 sprintf(s, "%s%s%s", tf, *tb ? " / " : NullStr, tb);
3448 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
3449 }
3450 else if (WinQueryActiveWindow(dcd->hwndParent) ==
3451 dcd->hwndFrame &&
3452 !ParentIsDesktop(hwnd, dcd->hwndParent)) {
3453 if (pre->fEmphasisMask & CRA_CURSORED) {
3454 if (pci->rc.flRecordAttr & CRA_CURSORED) {
3455 if (fSplitStatus && hwndStatus2) {
3456 if (dcd->ullTotalBytes)
3457 CommaFmtULL(tb, sizeof(tb), pci->cbFile, ' ');
3458 else
3459 *tb = 0;
3460 sprintf(s, "%s%s%s%s",
3461 *tb ? " " : NullStr,
3462 tb, *tb ? " " : NullStr, pci->pszFileName);
3463 WinSetWindowText(hwndStatus2, s);
3464 }
3465 if (fMoreButtons)
3466 WinSetWindowText(hwndName, pci->pszFileName);
3467 }
3468 }
3469 }
3470 }
3471 break;
3472
3473 case CN_ENTER:
3474 if (mp2) {
3475
3476 PARCITEM pci = (PARCITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
3477
3478 if (pci && (INT) pci != -1) {
3479
3480 CHAR *s;
3481
3482 if ((pci->rc.flRecordAttr & CRA_INUSE) ||
3483 (pci->flags & (ARCFLAGS_REALDIR | ARCFLAGS_PSEUDODIR)))
3484 break;
3485 s = xstrdup(pci->pszFileName, pszSrcFile, __LINE__);
3486 if (s) {
3487 if (!PostMsg(dcd->hwndObject, UM_ENTER, MPFROMP(s), MPVOID)) {
3488 Runtime_Error(pszSrcFile, __LINE__, "post");
3489 free(s);
3490 }
3491 }
3492 }
3493 }
3494 break;
3495 }
3496 }
3497 return 0;
3498
3499 case UM_FOLDUP:
3500 if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
3501 DosExit(EXIT_PROCESS, 1);
3502 return 0;
3503
3504 case UM_CLOSE:
3505 WinDestroyWindow(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
3506 QW_PARENT));
3507 return 0;
3508
3509 case WM_SAVEAPPLICATION:
3510 if (dcd && ParentIsDesktop(hwnd, dcd->hwndParent)) {
3511 SWP swp;
3512
3513 WinQueryWindowPos(dcd->hwndFrame, &swp);
3514 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE | SWP_MAXIMIZE)))
3515 PrfWriteProfileData(fmprof, appname, "AV2SizePos", &swp, sizeof(swp));
3516 }
3517 break;
3518
3519 case WM_CLOSE:
3520 WinSendMsg(hwnd, WM_SAVEAPPLICATION, MPVOID, MPVOID);
3521 if (dcd)
3522 dcd->stopflag++;
3523 if (dcd && dcd->hwndObject) {
3524 if (!PostMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID))
3525 WinSendMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID);
3526 }
3527 // In case object window frees dcd
3528 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
3529 if (!dcd ||
3530 (!dcd->dontclose &&
3531 !dcd->amextracted && ParentIsDesktop(hwnd, dcd->hwndParent))) {
3532 if (!PostMsg(hwnd, UM_FOLDUP, MPVOID, MPVOID))
3533 WinSendMsg(hwnd, UM_FOLDUP, MPVOID, MPVOID);
3534 }
3535 return 0;
3536
3537 case WM_DESTROY:
3538 if (ArcMenu)
3539 WinDestroyWindow(ArcMenu);
3540 if (ArcCnrMenu)
3541 WinDestroyWindow(ArcCnrMenu);
3542 ArcMenu = ArcCnrMenu = (HWND) 0;
3543 EmptyArcCnr(hwnd);
3544# ifdef FORTIFY
3545 Fortify_LeaveScope();
3546# endif
3547 break;
3548 }
3549 if (dcd && dcd->oldproc){
3550 return dcd->oldproc(hwnd, msg, mp1, mp2);
3551 }
3552 else
3553 return PFNWPCnr(hwnd, msg, mp1, mp2);
3554}
3555
3556MRESULT EXPENTRY ArcCnrMenuProc(HWND hwnd, ULONG msg, MPARAM mp1,
3557 MPARAM mp2)
3558{
3559 PFNWP oldMenuProc = WinQueryWindowPtr(hwnd, QWL_USER);
3560 static short sLastMenuitem;
3561
3562 switch (msg) {
3563 case WM_MOUSEMOVE: {
3564 if (fOtherHelp) {
3565 RECTL rectl;
3566 SHORT i, sCurrentMenuitem;
3567 SHORT MenuItems = 10;
3568 SHORT asMenuIDs[10] = {IDM_VIEW,
3569 IDM_DELETE,
3570 IDM_EXEC,
3571 IDM_EXTRACT,
3572 IDM_TEST,
3573 IDM_VIRUSSCAN,
3574 IDM_RESCAN,
3575 IDM_WALKDIR,
3576 IDM_FILTER,
3577 0};
3578 PCSZ szHelpString = NULL;
3579
3580
3581 for (i=0; i<MenuItems; i++) {
3582 sCurrentMenuitem = asMenuIDs[i];
3583 oldMenuProc(hwnd,MM_QUERYITEMRECT,
3584 MPFROM2SHORT(asMenuIDs[i], FALSE),
3585 &rectl);
3586
3587 if (MOUSEMSG(&msg)->x > rectl.xLeft &&
3588 MOUSEMSG(&msg)->x < rectl.xRight &&
3589 MOUSEMSG(&msg)->y > rectl.yBottom &&
3590 MOUSEMSG(&msg)->y < rectl.yTop)
3591 break;
3592 } // for
3593
3594
3595 switch (sCurrentMenuitem) {
3596 case 0:
3597 break;
3598 case IDM_VIEW:
3599 szHelpString = GetPString(IDS_ARCCNRVIEWMENUHELP);
3600 break;
3601 case IDM_DELETE:
3602 szHelpString = GetPString(IDS_ARCCNRDELETEMENUHELP);
3603 break;
3604 case IDM_EXEC:
3605 szHelpString = GetPString(IDS_ARCCNREXECMENUHELP);
3606 break;
3607 case IDM_EXTRACT:
3608 szHelpString = GetPString(IDS_ARCCNREXTRACTMENUHELP);
3609 break;
3610 case IDM_TEST:
3611 szHelpString = GetPString(IDS_ARCCNRTESTMENUHELP);
3612 break;
3613 case IDM_VIRUSSCAN:
3614 szHelpString = GetPString(IDS_ARCCNRVIRUSMENUHELP);
3615 break;
3616 case IDM_RESCAN:
3617 szHelpString = GetPString(IDS_ARCCNRRESCANMENUHELP);
3618 break;
3619 case IDM_WALKDIR:
3620 szHelpString = GetPString(IDS_ARCCNRWALKDIRMENUHELP);
3621 break;
3622 case IDM_FILTER:
3623 szHelpString = GetPString(IDS_ARCCNRFILTERMENUHELP);
3624 break;
3625 default:
3626 break;
3627 }
3628
3629 if (sLastMenuitem != sCurrentMenuitem && szHelpString) {
3630 sLastMenuitem = sCurrentMenuitem;
3631 MakeBubble(hwnd, TRUE, szHelpString);
3632 }
3633 else if (hwndBubble && !sCurrentMenuitem){
3634 sLastMenuitem = sCurrentMenuitem;
3635 WinDestroyWindow(hwndBubble);
3636 }
3637 }
3638 }
3639 }
3640 return oldMenuProc(hwnd, msg, mp1, mp2);
3641}
3642
3643HWND StartArcCnr(HWND hwndParent, HWND hwndCaller, CHAR * arcname, INT flags,
3644 ARC_TYPE * sinfo)
3645{
3646 /**
3647 * bitmapped flags:
3648 * 1 = am extracted from another archive
3649 * 4 = don't kill proc on close
3650 */
3651
3652 HWND hwndFrame = (HWND) 0, hwndClient;
3653 ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
3654 FCF_SIZEBORDER | FCF_MINMAX | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE;
3655 USHORT id;
3656 DIRCNRDATA *dcd;
3657 ARC_TYPE *info = sinfo;
3658 CHAR title[MAXNAMEL + 1] = "AV/2 - ";
3659 CHAR fullname[CCHMAXPATH + 8], *p, temp;
3660 static USHORT idinc = 0;
3661
3662 if (!idinc)
3663 idinc = (rand() % 256);
3664 if (ParentIsDesktop(hwndParent, hwndParent))
3665 FrameFlags |= (FCF_TASKLIST | FCF_MENU);
3666 if (arcname) {
3667 DosError(FERR_DISABLEHARDERR);
3668 if (DosQueryPathInfo(arcname,
3669 FIL_QUERYFULLNAME, fullname, sizeof(fullname)))
3670 strcpy(fullname, arcname);
3671 ForwardslashToBackslash(fullname);
3672 if (!info)
3673 info = find_type(fullname, arcsighead);
3674 if (!info)
3675 return hwndFrame;
3676 if (strlen(title) + strlen(fullname) > MAXNAMEL) {
3677 p = title + strlen(title);
3678 strncpy(p, fullname, MAXNAMEL / 2 - 5);
3679 strcpy(p + MAXNAMEL / 2 - 5, "...");
3680 strcat(title, fullname + strlen(fullname) - (MAXNAMEL / 2 - 5));
3681 }
3682 else {
3683 strcat(title, fullname);
3684 }
3685 hwndFrame = WinCreateStdWindow(hwndParent,
3686 WS_VISIBLE,
3687 &FrameFlags,
3688 (CHAR *) WC_ARCCONTAINER,
3689 title,
3690 WS_VISIBLE | fwsAnimate,
3691 FM3ModHandle, ARC_FRAME, &hwndClient);
3692 if (hwndFrame && hwndClient) {
3693 id = ARC_FRAME + idinc++;
3694 if (idinc > 512)
3695 idinc = 0;
3696 WinSetWindowUShort(hwndFrame, QWS_ID, id);
3697# ifdef FORTIFY
3698 Fortify_EnterScope();
3699# endif
3700 dcd = xmallocz(sizeof(DIRCNRDATA), pszSrcFile, __LINE__);
3701 if (!dcd) {
3702 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3703 hwndFrame = (HWND) 0;
3704 }
3705 else {
3706# ifdef FORTIFY
3707 // Will be freed by WM_DESTROY
3708 Fortify_ChangeScope(dcd, -1);
3709# endif
3710 dcd->size = sizeof(DIRCNRDATA);
3711 dcd->id = id;
3712 dcd->type = ARC_FRAME;
3713 if (pTmpDir && !IsValidDir(pTmpDir))
3714 DosCreateDir(pTmpDir, 0);
3715 MakeTempName(dcd->workdir, ArcTempRoot, 2);
3716 strcpy(dcd->arcname, fullname);
3717 if (*extractpath) {
3718 if (!strcmp(extractpath, "*")) {
3719 p = strrchr(fullname, '\\');
3720 if (p) {
3721 if (p < fullname + 3)
3722 p++;
3723 temp = *p;
3724 *p = 0;
3725 strcpy(dcd->directory, fullname);
3726 *p = temp;
3727 }
3728 }
3729 else
3730 strcpy(dcd->directory, extractpath);
3731 }
3732 if (!*dcd->directory && *lastextractpath) {
3733 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
3734 strcpy(dcd->directory, lastextractpath);
3735 DosReleaseMutexSem(hmtxFM2Globals);
3736 }
3737 if (!*dcd->directory) {
3738 if (!ParentIsDesktop(hwndParent, hwndParent))
3739 TopWindowName(hwndParent, hwndCaller, dcd->directory);
3740 if (!*dcd->directory) {
3741 p = strrchr(fullname, '\\');
3742 if (p) {
3743 if (p < fullname + 3)
3744 p++;
3745 *p = 0;
3746 strcpy(dcd->directory, fullname);
3747 }
3748 }
3749 }
3750 if (!*dcd->directory ||
3751 (IsFile(dcd->directory) == 1) ||
3752 (isalpha(*dcd->directory) &&
3753 (driveflags[toupper(*dcd->directory) - 'A'] &
3754 DRIVE_NOTWRITEABLE)))
3755 strcpy(dcd->directory, pFM2SaveDirectory);
3756 dcd->hwndParent = hwndParent ? hwndParent : HWND_DESKTOP;
3757 dcd->hwndFrame = hwndFrame;
3758 dcd->hwndClient = hwndClient;
3759 dcd->amextracted = (flags & 1) != 0;
3760 dcd->dontclose = (flags & 4) != 0;
3761 dcd->info = info;
3762 dcd->sortFlags = DefArcSortFlags;
3763 {
3764 PFNWP oldproc;
3765
3766 oldproc = WinSubclassWindow(hwndFrame, (PFNWP) ArcFrameWndProc);
3767 WinSetWindowPtr(hwndFrame, QWL_USER, (PVOID) oldproc);
3768 }
3769 dcd->hwndCnr = WinCreateWindow(hwndClient,
3770 WC_CONTAINER,
3771 NULL,
3772 CCS_AUTOPOSITION | CCS_MINIICONS |
3773 CCS_MINIRECORDCORE | ulCnrType |
3774 WS_VISIBLE,
3775 0,
3776 0,
3777 0,
3778 0,
3779 hwndClient,
3780 HWND_TOP, (ULONG) ARC_CNR, NULL, NULL);
3781 if (!dcd->hwndCnr) {
3782 Win_Error(hwndClient, hwndClient, pszSrcFile, __LINE__,
3783 PCSZ_WINCREATEWINDOW);
3784 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3785 free(dcd);
3786 hwndFrame = (HWND) 0;
3787 }
3788 else {
3789 WinSetWindowPtr(dcd->hwndCnr, QWL_USER, (PVOID) dcd);
3790 dcd->oldproc = WinSubclassWindow(dcd->hwndCnr,
3791 (PFNWP) ArcCnrWndProc);
3792 {
3793 USHORT ids[] = { DIR_TOTALS, DIR_SELECTED, DIR_VIEW, DIR_SORT,
3794 DIR_FILTER, DIR_FOLDERICON, 0
3795 };
3796
3797 CommonCreateTextChildren(dcd->hwndClient,
3798 WC_ARCSTATUS, ids);
3799 }
3800 WinEnableWindow(WinWindowFromID(dcd->hwndClient, DIR_VIEW), FALSE);
3801 dcd->hwndExtract = WinCreateWindow(dcd->hwndClient,
3802 WC_ENTRYFIELD,
3803 NULL,
3804 ES_AUTOSCROLL,
3805 0,
3806 0,
3807 0,
3808 0,
3809 dcd->hwndClient,
3810 HWND_TOP,
3811 ARC_EXTRACTDIR, NULL, NULL);
3812 WinSendMsg(dcd->hwndExtract,
3813 EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
3814 WinSetWindowText(dcd->hwndExtract, dcd->directory);
3815 if (!PostMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID))
3816 WinSendMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID);
3817 if (FrameFlags & FCF_MENU) {
3818 PFNWP oldmenuproc;
3819 HWND hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
3820
3821 oldmenuproc = WinSubclassWindow(hwndMenu, (PFNWP) ArcCnrMenuProc);
3822 WinSetWindowPtr(hwndMenu, QWL_USER, (PVOID) oldmenuproc);
3823 if (!fToolbar) {
3824
3825 if (hwndMenu) {
3826 WinSendMsg(hwndMenu, MM_DELETEITEM,
3827 MPFROM2SHORT(IDM_VIEW, FALSE), MPVOID);
3828 WinSendMsg(hwndMenu, MM_DELETEITEM,
3829 MPFROM2SHORT(IDM_EXEC, FALSE), MPVOID);
3830 WinSendMsg(hwndMenu, MM_DELETEITEM,
3831 MPFROM2SHORT(IDM_RESCAN, FALSE), MPVOID);
3832 WinSendMsg(hwndMenu, MM_DELETEITEM,
3833 MPFROM2SHORT(IDM_DELETE, FALSE), MPVOID);
3834 WinSendMsg(hwndMenu, MM_DELETEITEM,
3835 MPFROM2SHORT(IDM_EXTRACT, FALSE), MPVOID);
3836 WinSendMsg(hwndMenu, MM_DELETEITEM,
3837 MPFROM2SHORT(IDM_TEST, FALSE), MPVOID);
3838 WinSendMsg(hwndMenu, MM_DELETEITEM,
3839 MPFROM2SHORT(IDM_VIRUSSCAN, FALSE), MPVOID);
3840 WinSendMsg(hwndMenu, MM_DELETEITEM,
3841 MPFROM2SHORT(IDM_WALKDIR, FALSE), MPVOID);
3842 WinSendMsg(hwndMenu, MM_DELETEITEM,
3843 MPFROM2SHORT(IDM_FILTER, FALSE), MPVOID);
3844 }
3845 }
3846 }
3847 if (FrameFlags & FCF_TASKLIST) {
3848
3849 SWP swp, swpD;
3850 ULONG size = sizeof(swp);
3851 LONG cxScreen, cyScreen;
3852
3853 WinQueryTaskSizePos(WinQueryAnchorBlock(hwndFrame), 0, &swp);
3854 if (PrfQueryProfileData(fmprof, appname, "AV2SizePos", &swpD, &size)) {
3855 cxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
3856 cyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
3857 if (swp.x + swpD.cx > cxScreen)
3858 swp.x = cxScreen - swpD.cx;
3859 if (swp.y + swpD.cy > cyScreen)
3860 swp.y = cyScreen - swpD.cy;
3861 swp.cx = swpD.cx;
3862 swp.cy = swpD.cy;
3863 }
3864 WinSetWindowPos(hwndFrame,
3865 HWND_TOP,
3866 swp.x,
3867 swp.y,
3868 swp.cx,
3869 swp.cy,
3870 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER |
3871 SWP_ACTIVATE);
3872 }
3873 }
3874 }
3875# ifdef FORTIFY
3876 Fortify_LeaveScope();
3877# endif
3878 }
3879 }
3880 return hwndFrame;
3881}
3882
3883#pragma alloc_text(ARCCNRS,ArcCnrWndProc,ArcObjWndProc,ArcClientWndProc,BldQuotedFullPathName)
3884#pragma alloc_text(ARCCNRS,ArcTextProc,FillArcCnr,ArcFilter,BldQuotedFileName)
3885#pragma alloc_text(ARCCNRS,ArcSort,ArcFrameWndProc,IsArcThere,ArcErrProc)
3886#pragma alloc_text(STARTUP,StartArcCnr)
Note: See TracBrowser for help on using the repository browser.