source: trunk/dll/arccnrs.c@ 1770

Last change on this file since 1770 was 1770, checked in by Gregg Young, 11 years ago

Change to lzip code to allow a list file entry to work. Ticket 537

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 109.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: arccnrs.c 1770 2014-03-30 21:14:46Z 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
107***********************************************************************/
108
109#include <stdlib.h> // free..
110#include <string.h>
111#include <ctype.h>
112#include <direct.h> // rmdir
113#include <share.h> // SH_DENYWR
114#include <limits.h> // ULONG_MAX
115
116#if 0
117#include <malloc.h> // _heapchk
118#endif
119
120#define INCL_DOS
121#define INCL_DOSERRORS
122#define INCL_WIN
123#define INCL_LONGLONG
124
125#include "fm3dll.h"
126#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
127#include "arccnrs.h"
128#include "makelist.h" // Typedef
129#include "colors.h" // Typedef
130#include "mainwnd2.h" // Data declaration(s)
131#include "grep.h" // Data declaration(s)
132#include "dircnrs.h" // Data declaration(s)
133#include "info.h" // Data declaration(s)
134#include "init.h" // Data declaration(s)
135#include "fm3dlg.h"
136#include "fm3str.h"
137#include "mle.h"
138#include "pathutil.h" // BldFullPathName
139#include "filldir.h" // EmptyCnr...
140#include "errutil.h" // Dos_Error...
141#include "strutil.h" // GetPString
142#include "notebook.h" // CfgDlgProc
143#include "worker.h" // Action, MassAction
144#include "avv.h" // ArcReviewDlgProc, rewrite_archiverbb2
145#include "chklist.h" // CenterOverWindow, CheckListProc
146#include "common.h" // CommonCreateTextChildren, CommonFrameWndProc, CommonTextPaint
147 // CommonTextButton
148#include "draglist.h" // DoFileDrag, DragOne
149#include "valid.h" // GetDesktopName, TestCDates
150#include "mainwnd.h" // GetNextWindowPos, MakeBubble, TopWindowName
151#include "objwin.h" // MakeObjWin
152#include "shadow.h" // MakeShadows
153#include "objcnr.h" // ObjCnrDlgProc
154#include "printer.h" // PrintListThread
155#include "srchpath.h" // RunFM2Util
156#include "misc.h" // Broadcast, CheckMenu, CurrentRecord, SayFilter, SaySort
157 // DrawTargetEmphasis, IsFm2Window
158#include "select.h" // SelectAll, SelectList
159#include "findrec.h" // ShowCnrRecord
160#include "walkem.h" // WalkExtractDlgProc
161#include "droplist.h" // AcceptOneDrop, CheckPmDrgLimit, DropHelp, GetOneDrop
162#include "archive.h" // ArchiveDlgProc
163#include "common.h" // CommonTextProc
164#include "presparm.h" // CopyPresParams
165#include "defview.h" // DefaultViewKeys
166#include "systemf.h" // ExecOnList
167#include "filter.h" // PickMaskDlgProc
168#include "avl.h" // SBoxDlgProc
169#include "mkdir.h" // SetDir
170#include "collect.h" // StartCollector
171#include "viewer.h" // StartMLEEditor
172#include "newview.h" // StartViewer
173#include "i18nutil.h" // commafmt
174#include "copyf.h" // unlinkf
175#include "literal.h" // wildcard
176#include "wrappers.h" // xrealloc
177#include "misc.h" // AdjustCnrColVis, QuickPopup, SetSortChecks, SwitchCommand
178#include "select.h" // DeselectAll, InvertAll
179#include "strips.h" // bstrip
180#include "dirs.h" // save_dir2
181#include "fortify.h"
182#include "excputil.h" // 06 May 08 SHL added
183
184#define ARCFLAGS_REALDIR 0x00000001
185#define ARCFLAGS_PSEUDODIR 0x00000002
186#define CON_COLS 6
187#define EXTRA_ARCRECORD_BYTES (sizeof(ARCITEM) - sizeof(MINIRECORDCORE))
188#define NO_START_OF_ARCHIVER_LIST_STRING "None"
189#define NO_END_OF_ARCHIVER_LIST_STRING NO_START_OF_ARCHIVER_LIST_STRING
190
191#pragma data_seg(DATA1)
192static INT DefArcSortFlags;
193
194// Data definitions
195static PSZ pszSrcFile = __FILE__;
196#pragma data_seg(GLOBAL1)
197HWND ArcCnrMenu;
198HWND ArcMenu;
199CHAR ArcTempRoot[CCHMAXPATH];
200BOOL fArcStuffVisible;
201BOOL fFileNameCnrPath;
202
203#pragma data_seg(GLOBAL2)
204CHAR lastextractpath[CCHMAXPATH];
205ULONGLONG ullDATFileSpaceNeeded = 10000;
206
207typedef struct {
208
209 HWND hwndCnr; //hwnd you want the message posted to
210 HWND hwndClient; //hwnd calling this thread; NULL will work
211 ULONG RunFlags; //runemf2 flags see systemf.h
212 ULONG msg; //Message to post
213 UINT uiLineNumber;
214 PCSZ pszSrcFile;
215 CHAR filename[CCHMAXPATH]; //file passed as MP1 message parameter (file selected)
216 CHAR *pszDirectory; //Execution directory
217 CHAR *pszEnvironment; //Enviroment -- NULL passes current
218 CHAR *pszCmdLine; //Use sprintf to format multipart command line into single string
219 CHAR formatstring[40]; //Usally "%s"
220}
221WAITCHILD;
222
223/** Creates a thread to wait for a child process to complete then posts a message and closes
224 * This function should only be used for runemf2 calls that include the WAIT flag
225 */
226VOID WaitChildThread(VOID * arg)
227{
228 WAITCHILD *WaitChild;
229 HAB thab;
230 CHAR *filename;
231 INT ret;
232
233 DosError(FERR_DISABLEHARDERR);
234
235# ifdef FORTIFY
236 Fortify_EnterScope();
237# endif
238
239 WaitChild = (WAITCHILD *) arg;
240 if (WaitChild) {
241 filename = xstrdup(WaitChild->filename, pszSrcFile, __LINE__);
242 thab = WinInitialize(0);
243 if (thab) {
244 IncrThreadUsage();
245 priority_normal();
246 ret = runemf2(WaitChild->RunFlags, WaitChild->hwndClient,
247 WaitChild->pszSrcFile, WaitChild->uiLineNumber,
248 WaitChild->pszDirectory, WaitChild->pszEnvironment,
249 WaitChild->formatstring, WaitChild->pszCmdLine);
250 if (ret != -1) {
251 if (IsFile(WaitChild->filename) == 1)
252 PostMsg(WaitChild->hwndCnr, WaitChild->msg, MPFROMP(filename), MPVOID);
253 }
254 DecrThreadUsage();
255 WinTerminate(thab);
256 }
257 xfree(WaitChild->pszDirectory, pszSrcFile, __LINE__);
258 xfree(WaitChild->pszEnvironment, pszSrcFile, __LINE__);
259 xfree(WaitChild->pszCmdLine, pszSrcFile, __LINE__);
260 free(WaitChild);
261 } // if WaitChild
262# ifdef FORTIFY
263 Fortify_LeaveScope();
264# endif
265}
266
267static MRESULT EXPENTRY ArcErrProc(HWND hwnd, ULONG msg, MPARAM mp1,
268 MPARAM mp2)
269{
270 ARCDUMP *ad;
271 CHAR szQuotedArcName[CCHMAXPATH];
272
273 switch (msg) {
274 case WM_INITDLG:
275 if (!mp2)
276 WinDismissDlg(hwnd, 0);
277 else {
278 ad = (ARCDUMP *) mp2;
279 WinSetWindowPtr(hwnd, QWL_USER, ad);
280 if (ad->errmsg)
281 WinSetDlgItemText(hwnd, ARCERR_TEXT, ad->errmsg);
282 if (!ad->info->test)
283 WinEnableWindow(WinWindowFromID(hwnd, ARCERR_TEST), FALSE);
284 if (ad->listname) {
285 MLEsetlimit(WinWindowFromID(hwnd, ARCERR_MLE), -1L);
286 MLEsetformat(WinWindowFromID(hwnd, ARCERR_MLE), MLFIE_NOTRANS);
287 MLEsetcurpos(WinWindowFromID(hwnd, ARCERR_MLE),
288 MLEgetlen(WinWindowFromID(hwnd, ARCERR_MLE)));
289 MLEinsert(WinWindowFromID(hwnd, ARCERR_MLE),
290 GetPString(IDS_ARCHIVERREPORTTEXT));
291 MLEinsertfile(WinWindowFromID(hwnd, ARCERR_MLE), ad->listname);
292 }
293 }
294 break;
295
296 case WM_COMMAND:
297 switch (SHORT1FROMMP(mp1)) {
298 case DID_CANCEL:
299 WinDismissDlg(hwnd, 0);
300 break;
301
302 case IDM_HELP:
303 if (hwndHelp) {
304 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
305 MPFROM2SHORT(HELP_ARCERR, 0), MPFROMSHORT(HM_RESOURCEID));
306 }
307 break;
308
309 case DID_OK:
310 ad = WinQueryWindowPtr(hwnd, QWL_USER);
311 WinDlgBox(HWND_DESKTOP, hwnd, ArcReviewDlgProc, FM3ModHandle,
312 AD_FRAME, MPFROMP(ad));
313 WinDismissDlg(hwnd, 0);
314 break;
315
316 case ARCERR_VIEW:
317 ad = WinQueryWindowPtr(hwnd, QWL_USER);
318 {
319 CHAR *list[2];
320
321 list[0] = ad->arcname;
322 list[1] = NULL;
323 if (TestBinary(ad->arcname)) {
324 if (*binview)
325 ExecOnList((HWND) 0, binview, WINDOWED | SEPARATE, NULL, NULL, list,
326 NULL, pszSrcFile, __LINE__);
327 else
328 StartMLEEditor(HWND_DESKTOP, 16 + 4 + 1, ad->arcname, hwnd);
329 }
330 else {
331 if (*viewer) {
332 ExecOnList((HWND) 0, viewer, WINDOWED | SEPARATE |
333 (fViewChild ? CHILD : 0), NULL,
334 NULL, list, NULL, pszSrcFile, __LINE__);
335 }
336 else
337 StartMLEEditor(HWND_DESKTOP, 8 + 4 + 1, ad->arcname, hwnd);
338 }
339 }
340 break;
341
342 case ARCERR_TEST: {
343 CHAR *comspec;
344
345 ad = WinQueryWindowPtr(hwnd, QWL_USER);
346 comspec = getenv( "COMSPEC" );
347 runemf2(SEPARATEKEEP | WINDOWED | MAXIMIZED,
348 hwnd, pszSrcFile, __LINE__, NULL, NULL,
349 "%s /k %s %s",
350 comspec, ad->info->test,
351 BldQuotedFileName(szQuotedArcName, ad->arcname));
352 break;
353 }
354 }
355 return 0;
356 }
357 return WinDefDlgProc(hwnd, msg, mp1, mp2);
358}
359
360static SHORT APIENTRY ArcSort(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2,
361 PVOID pStorage)
362{
363 PARCITEM pai1 = (PARCITEM) pmrc1;
364 PARCITEM pai2 = (PARCITEM) pmrc2;
365 DIRCNRDATA *pdcd = (DIRCNRDATA *) pStorage;
366 SHORT ret = 0;
367 CHAR *pext, *ppext;
368 INT sortFlags;
369
370 if (!pdcd) {
371 HWND hwndCnr = pai1->hwndCnr;
372
373 pdcd = WinQueryWindowPtr(hwndCnr, QWL_USER);
374 if (!pdcd) {
375 Runtime_Error(pszSrcFile, __LINE__, NULL);
376 return ret;
377 }
378 }
379
380 sortFlags = pdcd->sortFlags; // Optimize
381
382 if (sortFlags) {
383 switch (sortFlags & (~SORT_REVERSE)) {
384 case SORT_FIRSTEXTENSION:
385 pext = strchr(pai1->pszFileName, '.');
386 ppext = strchr(pai2->pszFileName, '.');
387 if (!pext)
388 pext = NullStr;
389 if (!ppext)
390 ppext = NullStr;
391 ret = stricmp(pext, ppext);
392 break;
393
394 case SORT_LASTEXTENSION:
395 pext = strrchr(pai1->pszFileName, '.');
396 ppext = strrchr(pai2->pszFileName, '.');
397 if (!pext)
398 pext = NullStr;
399 if (!ppext)
400 ppext = NullStr;
401 ret = stricmp(pext, ppext);
402 break;
403
404 case SORT_LWDATE:
405 ret = TestCDates(&pai1->date, &pai1->time,
406 &pai2->date, &pai2->time);
407 break;
408
409 case SORT_SIZE:
410 ret =
411 (pai1->cbFile < pai2->cbFile) ? 1 : (pai1->cbFile ==
412 pai2->cbFile) ? 0 : -1;
413 if (!ret)
414 ret =
415 (pai1->cbComp < pai2->cbComp) ? 1 : (pai1->cbComp ==
416 pai2->cbComp) ? 0 : -1;
417 break;
418
419 case SORT_EASIZE:
420 ret =
421 (pai1->cbComp < pai2->cbComp) ? 1 : (pai1->cbComp ==
422 pai2->cbComp) ? 0 : -1;
423 if (!ret)
424 ret =
425 (pai1->cbFile < pai2->cbFile) ? 1 : (pai1->cbFile ==
426 pai2->cbFile) ? 0 : -1;
427 break;
428 }
429 if (!ret)
430 ret = (SHORT) stricmp(pai1->pszFileName, pai2->pszFileName);
431 if (ret && (sortFlags & SORT_REVERSE))
432 ret = ret > 0 ? -1 : 1;
433 return ret;
434 }
435 return (SHORT) stricmp(pai1->pszFileName, pai2->pszFileName);
436}
437
438static INT APIENTRY ArcFilter(PMINIRECORDCORE rmini, PVOID arg)
439{
440 DIRCNRDATA *dcd = (DIRCNRDATA *) arg;
441 PARCITEM r;
442 register INT x;
443 INT ret = FALSE;
444
445 if (dcd && *dcd->mask.szMask) {
446 r = (PARCITEM) rmini;
447 if (dcd->mask.pszMasks[1]) {
448 for (x = 0; dcd->mask.pszMasks[x]; x++) {
449 if (*dcd->mask.pszMasks[x]) {
450 if (*dcd->mask.pszMasks[x] != '/') {
451 if (wildcard(r->pszFileName, dcd->mask.pszMasks[x], TRUE))
452 ret = TRUE;
453 }
454 else {
455 if (wildcard(r->pszFileName, dcd->mask.pszMasks[x] + 1, TRUE)) {
456 ret = FALSE;
457 break;
458 }
459 }
460 }
461 }
462 }
463 else {
464 if (wildcard(r->pszFileName, dcd->mask.szMask, TRUE))
465 ret = TRUE;
466 }
467 }
468 else
469 ret = TRUE;
470 return ret;
471}
472
473static MRESULT EXPENTRY ArcFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
474 MPARAM mp2)
475{
476 return CommonFrameWndProc(ARC_CNR, hwnd, msg, mp1, mp2);
477}
478
479static BOOL IsArcThere(HWND hwnd, CHAR * arcname)
480{
481 if (arcname) {
482 if (IsFile(arcname) != 1) {
483 saymsg(MB_CANCEL, hwnd,
484 GetPString(IDS_SAYWHATTEXT),
485 GetPString(IDS_ARCNOTTHERETEXT), arcname);
486 return FALSE;
487 }
488 return TRUE;
489 }
490 return FALSE;
491}
492
493/**
494 * Free storage associated with archive container item
495 * Caller is responsible for correcting pointers
496 */
497
498static VOID FreeArcItemData(PARCITEM pai)
499{
500 // DbgMsg(pszSrcFile, __LINE__, "FreeArcItemData %p", pai);
501 PSZ psz;
502
503 if (pai->pszFileName && pai->pszFileName != NullStr) {
504 psz = pai->pszFileName;
505 pai->pszFileName = NULL; // 08 Jul 08 SHL was NulStr
506 free(psz);
507 }
508}
509
510/**
511 * Remove item(s) from archive container and free associated storage if requested
512 * @param paiFirst points to first item to remove or NULL to remove all
513 * @param usCnt is remove count or 0 to remove all
514 */
515
516static VOID RemoveArcItems(HWND hwnd, PARCITEM paiFirst, USHORT usCnt, USHORT usFlags)
517{
518 INT remaining = usCnt;
519 PARCITEM pai;
520
521 if ((usCnt && !paiFirst) || (!usCnt && paiFirst))
522 Runtime_Error(pszSrcFile, __LINE__, "paiFirst %p usCnt %u mismatch", paiFirst, usCnt);
523 else {
524 // Free our buffers if free requested
525 if (usFlags & CMA_FREE) {
526 if (paiFirst)
527 pai = paiFirst;
528 else {
529 pai = (PARCITEM)WinSendMsg(hwnd, CM_QUERYRECORD, MPVOID,
530 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
531 if ((INT)pai == -1) {
532 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_QUERYRECORD");
533 remaining = -1;
534 pai = NULL;
535 }
536 }
537 while (pai) {
538 FreeArcItemData(pai);
539 pai = (PARCITEM)pai->rc.preccNextRecord;
540 if (remaining && --remaining == 0)
541 break;
542 }
543 }
544 }
545
546 // DbgMsg(pszSrcFile, __LINE__, "RemoveArcItems %p %u %s", pai, usCnt, pai->pszFileName);
547
548 if (remaining != - 1) {
549 remaining = (INT)WinSendMsg(hwnd, CM_REMOVERECORD, MPFROMP(&paiFirst), MPFROM2SHORT(usCnt, usFlags));
550 if (remaining == -1) {
551 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,"CM_REMOVERECORD hwnd %x pai %p cnt %u",
552 hwnd, paiFirst, usCnt);
553 }
554 }
555}
556
557/**
558 * Empty all records from an archive container and
559 * free associated storage and free up field infos
560 */
561
562static VOID EmptyArcCnr(HWND hwnd)
563{
564#if 0 // fixme to be gone or to be configurable
565 {
566 int state = _heapchk();
567 if (state != _HEAPOK)
568 Runtime_Error(pszSrcFile, __LINE__, "heap corrupted %d", state);
569 else
570 DbgMsg(pszSrcFile, __LINE__, "_memavl %u", _memavl());
571 }
572#endif
573
574 // Remove all ARCITEM records
575 RemoveArcItems(hwnd, NULL, 0, CMA_FREE);
576
577 // Use common code to remove rest
578 EmptyCnr(hwnd);
579}
580
581//== FillArcCnr() generate archive content list and fill container window ==
582
583static INT FillArcCnr(HWND hwndCnr, CHAR * arcname, ARC_TYPE ** arcinfo,
584 ULONGLONG * pullTotalBytes, volatile PCHAR pStopFlag)
585{
586 FILE *fp;
587 HFILE oldstdout;
588 HFILE newstdout;
589 CHAR lonename[CCHMAXPATH + 2],
590 *nsize, *osize, *fdate, *fname, *p, *pp, *arctemp;
591 // Change the DosQueryAppType call below to xDosQueryAppType if "s" is no longer in low memory
592 CHAR s[CCHMAXPATH * 2];
593 CHAR TestStr[CCHMAXPATH * 2];
594 BOOL gotstart;
595 BOOL gotend;
596 BOOL wasquote;
597 BOOL nomove = FALSE; // fixme to be gone?
598 BOOL notest;
599 INT highest = 0, fieldnum, counter = 0, numarcfiles = 0;
600 PARCITEM lastpai;
601 ARC_TYPE *info;
602 ARC_TYPE *tinfo;
603 ULONG apptype;
604 APIRET rc;
605 CHAR *mode;
606 ULONG cnter = 0;
607
608 if (!arcname || !arcinfo)
609 return 0;
610
611 info = *arcinfo;
612 if (!info)
613 info = find_type(arcname, NULL);
614 arctemp = xmallocz(CCHMAXPATH, pszSrcFile, __LINE__);
615 if (CheckDriveSpaceAvail(ArcTempRoot, ullDATFileSpaceNeeded, ullTmpSpaceNeeded) == 1)
616 saymsg(MB_OK,
617 HWND_DESKTOP,
618 NullStr,
619 GetPString(IDS_ARCTMPDRIVESPACELIMITED),
620 ArcTempRoot);
621 MakeTempName(arctemp, ArcTempRoot, 2);
622
623
624ReTry:
625
626 tinfo = NULL;
627 numarcfiles = counter = highest = 0;
628 gotstart = gotend = FALSE;
629 lastpai = NULL;
630 *pullTotalBytes = 0;
631 if (!info || !info->list)
632 Runtime_Error(pszSrcFile, __LINE__, NULL);
633 else {
634 RemoveArcItems(hwndCnr, NULL, 0, CMA_FREE | CMA_INVALIDATE | CMA_ERASE);
635 *arcinfo = info;
636 highest = info->osizepos;
637 if (info->nsizepos > highest)
638 highest = info->nsizepos;
639 if (info->fdpos > highest)
640 highest = info->fdpos;
641 if (info->fnpos > highest)
642 highest = info->fnpos;
643 if (highest > 50) {
644 saymsg(MB_ENTER | MB_ICONEXCLAMATION, HWND_DESKTOP,
645 GetPString(IDS_SHAMETEXT), GetPString(IDS_BUNGEDUPTEXT));
646 }
647 if (info->fnpos == -1)
648 highest = 32767;
649
650 DosError(FERR_DISABLEHARDERR);
651 DosForceDelete(arctemp);
652 DosError(FERR_DISABLEHARDERR);
653
654 strcpy(s, info->list);
655 p = strchr(s, ' ');
656 if (p)
657 *p = 0;
658 DosError(FERR_DISABLEHARDERR);
659 if (!DosQueryAppType(s, &apptype) &&
660 (apptype & FAPPTYP_DOS ||
661 apptype & FAPPTYP_WINDOWSREAL ||
662 apptype & FAPPTYP_WINDOWSPROT ||
663 apptype & FAPPTYP_WINDOWSPROT31)) {
664 p = GetCmdSpec(TRUE);
665 runemf2(SEPARATE | INVISIBLE | MINIMIZED | BACKGROUND | WAIT,
666 hwndCnr, pszSrcFile, __LINE__, NULL, "DOS_BACKGROUND_EXECUTION=1",
667 "%s /C %s %s >%s",
668 p, // shell
669 info->list, // list command
670 BldQuotedFileName(s, arcname),
671 arctemp);
672 }
673 else {
674 mode = "w";
675 fp = xfopen(arctemp, mode, pszSrcFile, __LINE__, FALSE);
676 if (!fp) {
677 xfree(arctemp, pszSrcFile, __LINE__);
678 return 0;
679 }
680 else {
681 newstdout = -1;
682 DosError(FERR_DISABLEHARDERR);
683 rc = DosDupHandle(fileno(stdout), &newstdout);
684 if (rc) {
685 Dos_Error(MB_CANCEL, rc, hwndCnr, pszSrcFile, __LINE__,
686 PCSZ_DOSDUPHANDLE);
687 xfree(arctemp, pszSrcFile, __LINE__);
688 return 0;
689 }
690 else {
691 oldstdout = fileno(stdout);
692 DosError(FERR_DISABLEHARDERR);
693 rc = DosDupHandle(fileno(fp), &oldstdout);
694 if (rc) {
695 Dos_Error(MB_CANCEL, rc, hwndCnr, pszSrcFile, __LINE__,
696 PCSZ_DOSDUPHANDLE);
697 xfree(arctemp, pszSrcFile, __LINE__);
698 return 0;
699 }
700 else {
701 rc = 0;
702 //DbgMsg(pszSrcFile, __LINE__, "Number of tries %i", cnter);
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 DosDupHandle(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 DosForceDelete(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 DosForceDelete(arctemp);
1000 xfree(arctemp, pszSrcFile, __LINE__);
1001 }
1002
1003 if (numarcfiles)
1004 priority_normal();
1005
1006 return numarcfiles;
1007} // FillArcCnr
1008MRESULT EXPENTRY ArcTextProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1009{
1010 static BOOL emphasized = FALSE;
1011 static HWND hwndButtonPopup = (HWND) 0;
1012 static ULONG timestamp = ULONG_MAX;
1013 static USHORT lastid = 0;
1014
1015 switch (msg) {
1016 case WM_CREATE:
1017 return CommonTextProc(hwnd, msg, mp1, mp2);
1018
1019 case WM_COMMAND:
1020 return WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1021 ARC_CNR), msg, mp1, mp2);
1022
1023 case UM_CONTEXTMENU:
1024 case WM_CONTEXTMENU:
1025 {
1026 USHORT id;
1027
1028 id = WinQueryWindowUShort(hwnd, QWS_ID);
1029 switch (id) {
1030 case DIR_SELECTED:
1031 case DIR_VIEW:
1032 case DIR_SORT:
1033 {
1034 POINTL ptl = { 0, 0 };
1035 SWP swp;
1036 DIRCNRDATA *dcd;
1037
1038 if (hwndButtonPopup)
1039 WinDestroyWindow(hwndButtonPopup);
1040 if (id == DIR_SELECTED)
1041 id = DIR_RESTORE;
1042 if (id == lastid) {
1043
1044 ULONG check;
1045
1046 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &check,
1047 sizeof(check));
1048 if (check < timestamp + 500) {
1049 lastid = 0;
1050 goto MenuAbort;
1051 }
1052 }
1053 hwndButtonPopup = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
1054 if (hwndButtonPopup) {
1055 WinSetWindowUShort(hwndButtonPopup, QWS_ID, id);
1056 dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
1057 QW_PARENT),
1058 ARC_CNR), QWL_USER);
1059 if (id == DIR_SORT) {
1060 if (dcd)
1061 SetSortChecks(hwndButtonPopup, dcd->sortFlags);
1062 WinSendMsg(hwndButtonPopup,
1063 MM_DELETEITEM,
1064 MPFROM2SHORT(IDM_SORTNONE, FALSE), MPVOID);
1065 WinSendMsg(hwndButtonPopup,
1066 MM_DELETEITEM,
1067 MPFROM2SHORT(IDM_SORTNAME, FALSE), MPVOID);
1068 WinSendMsg(hwndButtonPopup,
1069 MM_DELETEITEM,
1070 MPFROM2SHORT(IDM_SORTLADATE, FALSE), MPVOID);
1071 WinSendMsg(hwndButtonPopup,
1072 MM_DELETEITEM,
1073 MPFROM2SHORT(IDM_SORTCRDATE, FALSE), MPVOID);
1074 WinSendMsg(hwndButtonPopup,
1075 MM_DELETEITEM,
1076 MPFROM2SHORT(IDM_SORTDIRSFIRST, FALSE), MPVOID);
1077 WinSendMsg(hwndButtonPopup,
1078 MM_DELETEITEM,
1079 MPFROM2SHORT(IDM_SORTDIRSLAST, FALSE), MPVOID);
1080 WinSendMsg(hwndButtonPopup,
1081 MM_DELETEITEM,
1082 MPFROM2SHORT(IDM_SORTSUBJECT, FALSE), MPVOID);
1083 WinSendMsg(hwndButtonPopup,
1084 MM_SETITEMTEXT,
1085 MPFROM2SHORT(IDM_SORTEASIZE, 0),
1086 MPFROMP(GetPString(IDS_COMPRESSEDSIZEMENUTEXT)));
1087 WinSendMsg(hwndButtonPopup,
1088 MM_SETITEMTEXT,
1089 MPFROM2SHORT(IDM_SORTLWDATE, 0),
1090 MPFROMP(GetPString(IDS_DATEMENUTEXT)));
1091 }
1092 ptl.x = 0;
1093 if (WinPopupMenu(HWND_OBJECT,
1094 HWND_OBJECT,
1095 hwndButtonPopup, -32767, -32767, 0, 0)) {
1096 WinQueryWindowPos(hwndButtonPopup, &swp);
1097 ptl.y = -(swp.cy + 2);
1098 }
1099 else {
1100 WinQueryWindowPos(hwnd, &swp);
1101 ptl.y = swp.cy + 2;
1102 }
1103 if (WinPopupMenu(hwnd,
1104 hwnd,
1105 hwndButtonPopup,
1106 ptl.x,
1107 ptl.y,
1108 0,
1109 PU_HCONSTRAIN | PU_VCONSTRAIN |
1110 PU_KEYBOARD | PU_MOUSEBUTTON1)) {
1111 CenterOverWindow(hwndButtonPopup);
1112 PaintRecessedWindow(hwnd, (HPS) 0, FALSE, FALSE);
1113 }
1114 }
1115 }
1116 break;
1117 default:
1118 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1119 ARC_CNR),
1120 WM_CONTROL, MPFROM2SHORT(ARC_CNR, CN_CONTEXTMENU), MPVOID);
1121 break;
1122 }
1123 }
1124 MenuAbort:
1125 if (msg == UM_CONTEXTMENU)
1126 return 0;
1127 break;
1128
1129 case WM_MENUEND:
1130 if (hwndButtonPopup == (HWND) mp2) {
1131 lastid = WinQueryWindowUShort((HWND) mp2, QWS_ID);
1132 WinDestroyWindow(hwndButtonPopup);
1133 hwndButtonPopup = (HWND) 0;
1134 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &timestamp,
1135 sizeof(timestamp));
1136 switch (lastid) {
1137 case DIR_VIEW:
1138 case DIR_SORT:
1139 case DIR_RESTORE:
1140 case DIR_SELECTED:
1141 PaintRecessedWindow(hwnd, (HPS) 0, TRUE, FALSE);
1142 break;
1143 }
1144 }
1145 break;
1146
1147 case WM_MOUSEMOVE:
1148 {
1149 USHORT id = WinQueryWindowUShort(hwnd, QWS_ID);
1150 PCSZ s = NULL;
1151
1152 if (fOtherHelp) {
1153 if ((!hwndBubble ||
1154 WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
1155 !WinQueryCapture(HWND_DESKTOP)) {
1156 switch (id) {
1157 case DIR_TOTALS:
1158 s = GetPString(IDS_ARCCNRTOTALSHELPTEXT);
1159 break;
1160 case DIR_SELECTED:
1161 s = GetPString(IDS_ARCCNRSELECTEDHELPTEXT);
1162 break;
1163 case DIR_VIEW:
1164 s = GetPString(IDS_ARCCNRVIEWHELPTEXT);
1165 break;
1166 case DIR_SORT:
1167 s = GetPString(IDS_DIRCNRSORTHELP);
1168 break;
1169 case DIR_FILTER:
1170 s = GetPString(IDS_DIRCNRFILTERHELP);
1171 break;
1172 case DIR_FOLDERICON:
1173 s = GetPString(IDS_ARCCNRFOLDERHELPTEXT);
1174 break;
1175 default:
1176 break;
1177 }
1178 if (s)
1179 MakeBubble(hwnd, TRUE, s);
1180 else if (hwndBubble)
1181 WinDestroyWindow(hwndBubble);
1182 }
1183 }
1184 switch (id) {
1185 case DIR_FILTER:
1186 case DIR_SORT:
1187 case DIR_VIEW:
1188 case DIR_SELECTED:
1189 case DIR_FOLDERICON:
1190 return CommonTextButton(hwnd, msg, mp1, mp2);
1191 }
1192 }
1193 break;
1194
1195 case WM_BUTTON3UP:
1196 case WM_BUTTON1UP:
1197 case WM_BUTTON1DOWN:
1198 case WM_BUTTON3DOWN:
1199 {
1200 USHORT id;
1201
1202 id = WinQueryWindowUShort(hwnd, QWS_ID);
1203 switch (id) {
1204 case DIR_FILTER:
1205 case DIR_SORT:
1206 case DIR_VIEW:
1207 case DIR_SELECTED:
1208 case DIR_FOLDERICON:
1209 return CommonTextButton(hwnd, msg, mp1, mp2);
1210 }
1211 }
1212 break;
1213
1214 case UM_CLICKED:
1215 case UM_CLICKED3:
1216 {
1217 USHORT id, cmd = 0;
1218
1219 id = WinQueryWindowUShort(hwnd, QWS_ID);
1220 switch (id) {
1221 case DIR_FOLDERICON:
1222 switch (msg) {
1223 case WM_BUTTON3CLICK:
1224 case WM_CHORD:
1225 cmd = IDM_RESCAN;
1226 break;
1227 default:
1228 if ((SHORT2FROMMP(mp2) & KC_ALT) != 0)
1229 cmd = IDM_WINDOWDLG;
1230 else
1231 cmd = IDM_WALKDIR;
1232 break;
1233 }
1234 break;
1235 case DIR_VIEW:
1236 case DIR_SORT:
1237 case DIR_SELECTED:
1238 PostMsg(hwnd, UM_CONTEXTMENU, MPVOID, MPVOID);
1239 break;
1240 case DIR_FILTER:
1241 cmd = IDM_FILTER;
1242 break;
1243 default:
1244 break;
1245 }
1246 if (cmd)
1247 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1248 ARC_CNR),
1249 WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
1250 }
1251 return 0;
1252
1253 case WM_BEGINDRAG:
1254 case DM_DROP:
1255 case DM_DRAGOVER:
1256 case DM_DRAGLEAVE:
1257 case DM_DROPHELP:
1258 if (msg == DM_DRAGOVER) {
1259 if (!emphasized) {
1260 emphasized = TRUE;
1261 DrawTargetEmphasis(hwnd, emphasized);
1262 }
1263 }
1264 else if (msg != WM_BEGINDRAG) {
1265 if (emphasized) {
1266 emphasized = FALSE;
1267 DrawTargetEmphasis(hwnd, emphasized);
1268 }
1269 }
1270 switch (WinQueryWindowUShort(hwnd, QWS_ID)) {
1271 case DIR_FOLDERICON:
1272 switch (msg) {
1273 case DM_DRAGOVER:
1274 if (AcceptOneDrop(hwnd, mp1, mp2))
1275 return MRFROM2SHORT(DOR_DROP, DO_MOVE);
1276 return MRFROM2SHORT(DOR_NODROP, 0); // Drop not valid
1277 case DM_DROPHELP:
1278 DropHelp(mp1, mp2, hwnd, GetPString(IDS_ARCCNRFOLDERDROPHELPTEXT));
1279 return 0;
1280 case DM_DROP:
1281 {
1282 char szFrom[CCHMAXPATH + 2];
1283
1284 if (emphasized) {
1285 emphasized = FALSE;
1286 DrawTargetEmphasis(hwnd, emphasized);
1287 }
1288 if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom)))
1289 WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1290 ARC_CNR),
1291 WM_COMMAND,
1292 MPFROM2SHORT(IDM_SWITCH, 0), MPFROMP(szFrom));
1293 }
1294 return 0;
1295 default:
1296 return PFNWPStatic(hwnd, msg, mp1, mp2);
1297 }
1298 default:
1299 {
1300 CNRDRAGINFO cnd;
1301 USHORT dcmd;
1302
1303 switch (msg) {
1304 case DM_DROP:
1305 dcmd = CN_DROP;
1306 break;
1307 case DM_DRAGOVER:
1308 dcmd = CN_DRAGOVER;
1309 break;
1310 case DM_DRAGLEAVE:
1311 dcmd = CN_DRAGLEAVE;
1312 break;
1313 case DM_DROPHELP:
1314 dcmd = CN_DROPHELP;
1315 break;
1316 case WM_BEGINDRAG:
1317 dcmd = CN_INITDRAG;
1318 break;
1319 }
1320 cnd.pDragInfo = (PDRAGINFO) mp1;
1321 cnd.pRecord = NULL;
1322 return WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
1323 WM_CONTROL,
1324 MPFROM2SHORT(ARC_CNR, dcmd), MPFROMP(&cnd));
1325 }
1326 }
1327 }
1328 return PFNWPStatic(hwnd, msg, mp1, mp2);
1329}
1330
1331MRESULT EXPENTRY ArcClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
1332 MPARAM mp2)
1333{
1334
1335 switch (msg) {
1336 case UM_CONTAINERHWND:
1337 return MRFROMLONG(WinWindowFromID(hwnd, ARC_CNR));
1338
1339 case UM_VIEWSMENU:
1340 // fixme to disble menu items as needed
1341 return MRFROMLONG(CheckMenu(hwnd, &ArcCnrMenu, ARCCNR_POPUP));
1342
1343 case UM_FILESMENU:
1344 // fixme to disble menu items as needed
1345 return MRFROMLONG(CheckMenu(hwnd, &ArcMenu, ARC_POPUP));
1346
1347 case MM_PORTHOLEINIT:
1348 case WM_INITMENU:
1349 case UM_INITMENU:
1350 case UM_COMMAND:
1351 case UM_LOADFILE:
1352 case UM_UPDATERECORD:
1353 case UM_UPDATERECORDLIST:
1354 case WM_COMMAND:
1355 case WM_CONTROL:
1356 case WM_CLOSE:
1357 return WinSendMsg(WinWindowFromID(hwnd, ARC_CNR), msg, mp1, mp2);
1358
1359 case WM_PSETFOCUS:
1360 case WM_SETFOCUS:
1361 if (mp2)
1362 PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
1363 break;
1364
1365 case UM_FOCUSME:
1366 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, ARC_CNR));
1367 break;
1368
1369 case WM_PAINT:
1370 {
1371 HPS hps;
1372 RECTL rcl;
1373
1374 hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
1375 if (hps) {
1376 WinQueryWindowRect(hwnd, &rcl);
1377 WinFillRect(hps, &rcl, CLR_PALEGRAY);
1378 CommonTextPaint(hwnd, hps);
1379 WinEndPaint(hps);
1380 }
1381 }
1382 break;
1383
1384 case UM_SIZE:
1385 case WM_SIZE:
1386 if (msg == UM_SIZE) {
1387
1388 SWP swp;
1389
1390 WinQueryWindowPos(hwnd, &swp);
1391 mp1 = MPFROM2SHORT(swp.cx, swp.cy);
1392 mp2 = MPFROM2SHORT(swp.cx, swp.cy);
1393 }
1394 {
1395 USHORT cx, cy, bx;
1396
1397 cx = SHORT1FROMMP(mp2);
1398 cy = SHORT2FROMMP(mp2);
1399 WinSetWindowPos(WinWindowFromID(hwnd, ARC_CNR), HWND_TOP,
1400 0,
1401 22, cx, cy - (24 + 22), SWP_SHOW | SWP_MOVE | SWP_SIZE);
1402 WinSetWindowPos(WinWindowFromID(hwnd, ARC_EXTRACTDIR), HWND_TOP,
1403 0, 0, cx, 22, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1404 WinSetWindowPos(WinWindowFromID(hwnd, DIR_FOLDERICON), HWND_TOP,
1405 2, cy - 22, 24, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1406 WinSetWindowPos(WinWindowFromID(hwnd, DIR_TOTALS), HWND_TOP,
1407 29,
1408 cy - 22,
1409 (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1410 WinSetWindowPos(WinWindowFromID(hwnd, DIR_SELECTED), HWND_TOP,
1411 29 + (cx / 3) + 2,
1412 cy - 22,
1413 (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1414 bx = (cx - (29 + (((cx / 3) + 2) * 2))) / 3;
1415 WinSetWindowPos(WinWindowFromID(hwnd, DIR_VIEW), HWND_TOP,
1416 29 + (((cx / 3) + 2) * 2),
1417 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1418 WinSetWindowPos(WinWindowFromID(hwnd, DIR_SORT), HWND_TOP,
1419 29 + (((cx / 3) + 2) * 2) + bx,
1420 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1421 WinSetWindowPos(WinWindowFromID(hwnd, DIR_FILTER), HWND_TOP,
1422 29 + (((cx / 3) + 2) * 2) + (bx * 2),
1423 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1424 }
1425 CommonTextPaint(hwnd, (HPS) 0);
1426 if (msg == UM_SIZE) {
1427 WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP, 0, 0, 0, 0,
1428 SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE);
1429 return 0;
1430 }
1431 break;
1432 }
1433 return WinDefWindowProc(hwnd, msg, mp1, mp2);
1434}
1435
1436MRESULT EXPENTRY ArcObjWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1437{
1438 DIRCNRDATA *dcd;
1439 PSZ psz;
1440 CHAR szQuotedArcName[CCHMAXPATH];
1441 CHAR szQuotedMemberName[CCHMAXPATH];
1442
1443 switch (msg) {
1444 case WM_CREATE:
1445 DbgMsg(pszSrcFile, __LINE__, "WM_CREATE mp1 %p mp2 %p", mp1, mp2); // 18 Jul 08 SHL fixme
1446 break;
1447
1448 case DM_PRINTOBJECT:
1449 case DM_DISCARDOBJECT:
1450 dcd = INSTDATA(hwnd);
1451 if (dcd) {
1452
1453 LISTINFO *li;
1454 CNRDRAGINFO cni;
1455
1456 cni.pRecord = NULL;
1457 cni.pDragInfo = (PDRAGINFO) mp1;
1458 li = DoFileDrop(dcd->hwndCnr,
1459 dcd->directory, FALSE, MPVOID, MPFROMP(&cni));
1460 CheckPmDrgLimit(cni.pDragInfo);
1461 if (li) {
1462 li->type = (msg == DM_DISCARDOBJECT) ? IDM_DELETE : IDM_PRINT;
1463 if (!li->list ||
1464 !li->list[0] || !PostMsg(hwnd, UM_ACTION, MPFROMP(li), MPVOID))
1465 FreeListInfo(li);
1466 else
1467 return MRFROMLONG(DRR_SOURCE);
1468 }
1469 }
1470 return MRFROMLONG(DRR_TARGET);
1471
1472 case DM_RENDERPREPARE:
1473 return (MRESULT) TRUE;
1474
1475 case DM_RENDER:
1476 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1477 if (dcd && dcd->info && dcd->info->extract && dcd->arcname) {
1478
1479 PDRAGTRANSFER pdt = (PDRAGTRANSFER) mp1;
1480 CHAR filename[CCHMAXPATH];
1481 ULONG len;
1482
1483 if (pdt->hwndClient && pdt->pditem && pdt->hstrSelectedRMF &&
1484 pdt->hstrRenderToName) {
1485 if (pdt->usOperation == DO_COPY || pdt->usOperation == DO_MOVE) {
1486 *filename = 0;
1487 len = DrgQueryStrName(pdt->hstrSelectedRMF, CCHMAXPATH, filename);
1488 filename[len] = 0;
1489 if (strnicmp(filename, "OS2FILE,", 8)) {
1490 *filename = 0;
1491 len = DrgQueryStrName(pdt->hstrRenderToName, CCHMAXPATH, filename);
1492 filename[len] = 0;
1493 if (len && *filename) {
1494 psz = xstrdup(filename, pszSrcFile, __LINE__);
1495 if (psz) {
1496 PostMsg(hwnd, UM_RENDER, MPFROMP(pdt), MPFROMP(psz));
1497 return (MRESULT) TRUE;
1498 }
1499 }
1500 }
1501 }
1502 pdt->fsReply = DMFL_RENDERRETRY;
1503 }
1504 }
1505 return (MRESULT) FALSE;
1506
1507 case UM_RENDER:
1508 {
1509 PDRAGTRANSFER pdt = (PDRAGTRANSFER) mp1;
1510 USHORT usRes = DMFL_RENDERFAIL;
1511
1512 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1513 if (dcd && dcd->info && dcd->info->extract && dcd->arcname) {
1514
1515 CHAR *filename = (CHAR *) mp2, *p;
1516 ULONG len;
1517 CHAR membername[CCHMAXPATH], construct[CCHMAXPATH * 2];
1518
1519 *membername = 0;
1520 len = DrgQueryStrName(pdt->pditem->hstrSourceName,
1521 CCHMAXPATH, membername);
1522 membername[len] = 0;
1523 if (*membername && len && filename) {
1524 unlinkf(filename);
1525 strcpy(construct, filename);
1526 p = strrchr(filename, '\\');
1527 if (!p)
1528 *construct = 0;
1529 else {
1530 if (p == filename || *(p - 1) == ':')
1531 p++;
1532 *p = 0;
1533 }
1534 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS | WAIT |
1535 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
1536 dcd->hwndClient, pszSrcFile, __LINE__, construct, NULL,
1537 "%s %s %s",
1538 dcd->info->extract,
1539 BldQuotedFileName(szQuotedArcName, dcd->arcname),
1540 BldQuotedFileName(szQuotedMemberName, membername));
1541 BldFullPathName(construct, construct, membername);
1542 if (IsFile(construct) != -1) {
1543 rename(construct, filename);
1544 unlinkf(construct);
1545 if (IsFile(filename) != -1)
1546 usRes = DMFL_RENDEROK;
1547 }
1548 }
1549 }
1550 xfree((CHAR *)mp2, pszSrcFile, __LINE__);
1551 PostMsg(pdt->hwndClient, DM_RENDERCOMPLETE, MPFROMP(pdt),
1552 MPFROM2SHORT(usRes, 0));
1553 }
1554 return 0;
1555
1556 case UM_SETUP:
1557# ifdef FORTIFY
1558 Fortify_EnterScope();
1559# endif
1560 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1561 if (!dcd) {
1562 Runtime_Error(pszSrcFile, __LINE__, NULL);
1563 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1564 }
1565 else {
1566# ifdef FORTIFY
1567 Fortify_BecomeOwner(dcd);
1568# endif
1569 // set unique id
1570 WinSetWindowUShort(hwnd, QWS_ID, ARCOBJ_FRAME + (ARC_FRAME - dcd->id));
1571 dcd->hwndObject = hwnd; // pass back hwnd
1572 if (ParentIsDesktop(hwnd, dcd->hwndParent))
1573 DosSleep(100); //05 Aug 07 GKY 250 // Avoid race?
1574 }
1575 return 0;
1576
1577 case UM_RESCAN:
1578 /**
1579 * populate container
1580 */
1581 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1582 if (dcd) {
1583 if (mp1)
1584 strcpy(dcd->arcname, (CHAR *) mp1); // Update name on request
1585 dcd->ullTotalBytes = dcd->totalfiles =
1586 dcd->selectedfiles = dcd->selectedbytes = 0;
1587 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, "0");
1588 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, "0 / 0k");
1589 dcd->totalfiles = FillArcCnr(dcd->hwndCnr,
1590 dcd->arcname,
1591 &dcd->info,
1592 &dcd->ullTotalBytes, &dcd->stopflag);
1593 if (!dcd->totalfiles)
1594 PostMsg(dcd->hwndCnr, WM_CLOSE, MPVOID, MPVOID);
1595 else {
1596 dcd->arcfilled = TRUE;
1597 if (!PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID))
1598 WinSendMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
1599 PostMsg(dcd->hwndCnr, UM_SETUP2, MPVOID, MPVOID);
1600 WinSendMsg(dcd->hwndCnr,
1601 CM_INVALIDATERECORD,
1602 MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
1603 }
1604 }
1605 return 0;
1606
1607 case UM_SELECT:
1608 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1609 if (dcd) {
1610 switch (SHORT1FROMMP(mp1)) {
1611 case IDM_SELECTALL:
1612 case IDM_SELECTALLFILES:
1613 SelectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, TRUE);
1614 break;
1615 case IDM_DESELECTALL:
1616 case IDM_DESELECTALLFILES:
1617 DeselectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, TRUE);
1618 break;
1619 case IDM_DESELECTMASK:
1620 case IDM_SELECTMASK:
1621 {
1622 MASK mask;
1623 PARCITEM pci = (PARCITEM) mp2;
1624
1625 memset(&mask, 0, sizeof(MASK));
1626 mask.fNoAttribs = TRUE;
1627 mask.fNoDirs = TRUE;
1628 mask.fText = TRUE;
1629 strcpy(mask.prompt,
1630 GetPString((SHORT1FROMMP(mp1) == IDM_SELECTMASK) ?
1631 IDS_SELECTFILTERTEXT : IDS_DESELECTFILTERTEXT));
1632 if (pci && (INT) pci != -1)
1633 strcpy(mask.szMask, pci->pszFileName);
1634 if (WinDlgBox(HWND_DESKTOP, dcd->hwndCnr, PickMaskDlgProc,
1635 FM3ModHandle, MSK_FRAME, MPFROMP(&mask))) {
1636 if (SHORT1FROMMP(mp1) == IDM_SELECTMASK)
1637 SelectAll(dcd->hwndCnr, TRUE, TRUE, mask.szMask, NULL, FALSE);
1638 else
1639 DeselectAll(dcd->hwndCnr, TRUE, TRUE, mask.szMask, NULL, FALSE);
1640 }
1641 }
1642 break;
1643
1644 case IDM_INVERT:
1645 InvertAll(dcd->hwndCnr);
1646 break;
1647 }
1648 }
1649 return 0;
1650
1651 case UM_ENTER:
1652 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1653 if (dcd) {
1654
1655 CHAR *s = (CHAR *) mp1, *p, *pp; // filename[CCHMAXPATH];
1656 WAITCHILD *WaitChild;
1657
1658 WaitChild = xmallocz(sizeof(WAITCHILD), pszSrcFile, __LINE__);
1659 WaitChild->pszCmdLine = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1660 if (!WaitChild)
1661 return 0;
1662 if (s) {
1663 if (!dcd->info->extract) {
1664 Runtime_Error(pszSrcFile, __LINE__, "no extract");
1665 free(s);
1666 return 0;
1667 }
1668 sprintf(WaitChild->pszCmdLine, "%s %s %s",
1669 dcd->info->exwdirs ? dcd->info->exwdirs :
1670 dcd->info->extract,
1671 BldQuotedFileName(szQuotedArcName, dcd->arcname),
1672 BldQuotedFileName(szQuotedMemberName, s));
1673 if (!dcd->info->exwdirs) {
1674 p = s;
1675 p = strrchr(s, '\\');
1676 pp = strrchr(s, '/');
1677 if (p && pp)
1678 p = max(p, pp);
1679 else if (!p)
1680 p = pp;
1681 if (p)
1682 memmove(s, p + 1, strlen(p + 1));
1683 }
1684 sprintf(WaitChild->filename, "%s\\%s", dcd->workdir, s);
1685 ForwardslashToBackslash(WaitChild->filename);
1686 free(s);
1687 WaitChild->RunFlags = SEPARATE | ASYNCHRONOUS | WAIT |
1688 (fArcStuffVisible ? 0 : BACKGROUND);
1689 WaitChild->hwndClient = dcd->hwndClient;
1690 WaitChild->msg = UM_ENTER;
1691 WaitChild->uiLineNumber = __LINE__;
1692 WaitChild->pszSrcFile = pszSrcFile;
1693 WaitChild->pszDirectory = xstrdup(dcd->workdir, pszSrcFile, __LINE__);
1694 WaitChild->pszEnvironment = NULL;
1695 strcpy(WaitChild->formatstring, "%s");
1696 WaitChild->hwndCnr = dcd->hwndCnr;
1697 xbeginthread(WaitChildThread,
1698 65536,
1699 WaitChild,
1700 pszSrcFile,
1701 __LINE__);
1702 }
1703 }
1704 return 0;
1705
1706 case UM_COMMAND:
1707 if (mp1) {
1708 if (PostMsg(hwnd, UM_ACTION, mp1, mp2))
1709 return (MRESULT) TRUE;
1710 }
1711 return 0;
1712
1713 case UM_ACTION:
1714 DosError(FERR_DISABLEHARDERR);
1715 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1716 if (dcd) {
1717
1718 LISTINFO *li = (LISTINFO *) mp1;
1719 register INT x;
1720
1721 if (li && li->list && li->list[0]) {
1722 // printf("%x/r", li->type); fflush(stdout); // 24 Sep 08 SHL
1723 switch (li->type) {
1724 case IDM_ARCHIVE:
1725 case IDM_ARCHIVEM:
1726 {
1727 DIRCNRDATA ad;
1728 CHAR szBuffer[1025], *p;
1729
1730 if (!li->list[1] && !stricmp(li->list[0], dcd->arcname)) {
1731 Runtime_Error(pszSrcFile, __LINE__, "arc to self");
1732 break;
1733 }
1734 ad = *dcd;
1735 ad.namecanchange = 0;
1736 ad.fmoving = (li->type == IDM_ARCHIVEM);
1737 if (!WinDlgBox(HWND_DESKTOP, dcd->hwndClient, ArchiveDlgProc,
1738 FM3ModHandle, ARCH_FRAME, (PVOID) & ad) || !*ad.arcname ||
1739 !*ad.command) // we blew it
1740 break;
1741 // build the sucker
1742 strcpy(szBuffer, ad.command);
1743 strcat(szBuffer, " ");
1744
1745 BldQuotedFileName(szBuffer + strlen(szBuffer), ad.arcname);
1746
1747 p = &szBuffer[strlen(szBuffer)]; // Remeber where archiver name ends
1748
1749 if (ad.mask.szMask) {
1750 strcat(szBuffer, " ");
1751
1752 BldQuotedFileName(szBuffer + strlen(szBuffer), ad.mask.szMask);
1753 }
1754 strcat(szBuffer, " ");
1755 x = 0;
1756
1757 // Run commands avoiding command line overflow
1758 while (li->list[x]) {
1759
1760 if (IsFile(li->list[x]))
1761 BldQuotedFileName(szBuffer + strlen(szBuffer), li->list[x]);
1762 else
1763 BldQuotedFullPathName(szBuffer + strlen(szBuffer), li->list[x], "*");
1764
1765 x++;
1766 if (!li->list[x] || strlen(szBuffer) +
1767 strlen(li->list[x]) + 5 > MaxComLineStrg) {
1768 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS |
1769 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
1770 hwnd, pszSrcFile, __LINE__,
1771 NULL, NULL, "%s", szBuffer);
1772 *p = 0;
1773 }
1774 strcat(szBuffer, " ");
1775 } // while
1776
1777 PostMsg(dcd->hwndCnr, UM_RESCAN, MPFROMSHORT(1), MPVOID);
1778 Broadcast(WinQueryAnchorBlock(hwnd),
1779 hwndMain, UM_UPDATERECORD, MPFROMP(ad.arcname), MPVOID);
1780 Broadcast(WinQueryAnchorBlock(hwnd),
1781 hwndMain,
1782 UM_UPDATERECORDLIST, MPFROMP(li->list), MPVOID);
1783 }
1784 break;
1785
1786 case IDM_REFRESH:
1787 case IDM_DELETE:
1788 {
1789 CHAR *endofit;
1790 PSZ pszCmdLine;
1791 INT z;
1792 CHECKLIST ck;
1793 CHAR prompt[CCHMAXPATH + 257];
1794
1795 if (!dcd->info->delete)
1796 break;
1797 memset(&ck, 0, sizeof(ck));
1798 ck.size = sizeof(ck);
1799 ck.list = li->list;
1800 ck.cmd = li->type;
1801 ck.prompt = prompt;
1802 ck.flags = CHECK_ARCHIVE;
1803 sprintf(prompt, GetPString(IDS_ARCCNRDELREFTEXT),
1804 (li->type == IDM_DELETE) ?
1805 GetPString(IDS_DELETELOWERTEXT) :
1806 GetPString(IDS_REFRESHLOWERTEXT),
1807 &"s"[li->list[1] == NULL],
1808 dcd->arcname,
1809 (li->type == IDM_DELETE) ?
1810 GetPString(IDS_DELETELOWERTEXT) :
1811 GetPString(IDS_REFRESHLOWERTEXT));
1812 if (!WinDlgBox(HWND_DESKTOP, hwnd, CheckListProc,
1813 FM3ModHandle, CHECK_FRAME, MPFROMP(&ck)))
1814 break;
1815 li->list = ck.list;
1816 if (!li->list || !li->list[0])
1817 break;
1818 pszCmdLine = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1819 if (!pszCmdLine)
1820 break;
1821 strcpy(pszCmdLine, li->type == IDM_DELETE ?
1822 dcd->info->delete :
1823 dcd->info->create);
1824 strcat(pszCmdLine, " ");
1825 BldQuotedFileName(pszCmdLine + strlen(pszCmdLine), dcd->arcname);
1826 endofit = &pszCmdLine[strlen(pszCmdLine)];
1827 z = 0;
1828 do {
1829 for (x = z; li->list[x] &&
1830 strlen(pszCmdLine) + strlen(li->list[x]) < 999; x++) {
1831 strcat(pszCmdLine, " ");
1832 BldQuotedFileName(pszCmdLine + strlen(pszCmdLine), li->list[x]);
1833 }
1834 z = x;
1835 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS | WAIT |
1836 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
1837 hwnd, pszSrcFile, __LINE__, NullStr, NULL, "%s", pszCmdLine);
1838 *endofit = 0;
1839 free(pszCmdLine);
1840 } while (li->list[x]);
1841 PostMsg(dcd->hwndCnr, UM_RESCAN, MPFROMSHORT(1), MPVOID);
1842 Broadcast(WinQueryAnchorBlock(hwnd),
1843 hwndMain,
1844 UM_UPDATERECORD, MPFROMP(dcd->arcname), MPVOID);
1845 }
1846 break;
1847
1848 case IDM_PRINT:
1849 case IDM_VIRUSSCAN:
1850 case IDM_VIEW:
1851 case IDM_MCIPLAY:
1852 case IDM_VIEWARCHIVE:
1853 case IDM_VIEWTEXT:
1854 case IDM_VIEWBINARY:
1855 case IDM_EDIT:
1856 case IDM_EDITTEXT:
1857 case IDM_EDITBINARY:
1858 case IDM_EXEC:
1859 case IDM_EXTRACTWDIRS:
1860 case IDM_EXTRACT:
1861 case IDM_OPENDEFAULT:
1862 case IDM_OPENSETTINGS:
1863 {
1864 CHAR *endofit, *ptr;
1865 PSZ pszCmdLine;
1866 INT z;
1867 if ((li->type == IDM_EXTRACT && !li->info->extract) ||
1868 ((li->type == IDM_VIEW || li->type == IDM_VIEWTEXT ||
1869 li->type == IDM_VIEWBINARY || li->type == IDM_EDIT ||
1870 li->type == IDM_VIEWARCHIVE || li->type == IDM_EDITTEXT ||
1871 li->type == IDM_EDITBINARY || li->type == IDM_MCIPLAY) &&
1872 (!li->info->extract && !li->info->exwdirs)) ||
1873 (li->type != IDM_EXTRACT && li->type != IDM_EDIT &&
1874 li->type != IDM_VIEW && li->type != IDM_VIEWTEXT &&
1875 li->type != IDM_VIEWBINARY &&
1876 li->type != IDM_VIEWARCHIVE &&
1877 li->type != IDM_EDITTEXT &&
1878 li->type != IDM_EDITBINARY &&
1879 li->type != IDM_MCIPLAY && !li->info->exwdirs)) {
1880 Runtime_Error(pszSrcFile, __LINE__, "no cmd for request");
1881 break;
1882 }
1883 if (li->type == IDM_EXTRACT || li->type == IDM_EXTRACTWDIRS) {
1884
1885 CHAR fullname[CCHMAXPATH * 2];
1886 CHAR **exfiles = NULL;
1887 UINT numfiles = 0, numalloc = 0;
1888
1889 if (li->targetpath && fFileNameCnrPath &&
1890 stricmp(lastextractpath, li->targetpath)) {
1891 strcpy(lastextractpath, li->targetpath);
1892 SetDir(dcd->hwndParent, hwnd, li->targetpath, 1);
1893 }
1894 for (x = 0; li->list[x]; x++) {
1895 BldFullPathName(fullname, li->targetpath, li->list[x]);
1896 //Check if file already exists on disk warn if it does.
1897 if (IsFile(fullname) != -1) {
1898 AddToList(li->list[x], &exfiles, &numfiles, &numalloc);
1899 li->list = RemoveFromList(li->list, li->list[x]);
1900 if (!li->list)
1901 break;
1902 x--;
1903 }
1904 }
1905 if (exfiles && numfiles) {
1906
1907 CHECKLIST ckl;
1908 CHAR prompt[(CCHMAXPATH * 2) + 256];
1909
1910 memset(&ckl, 0, sizeof(ckl));
1911 ckl.size = sizeof(ckl);
1912 ckl.list = exfiles;
1913 ckl.prompt = prompt;
1914 ckl.cmd = li->type;
1915 ckl.flags = CHECK_ARCHIVE;
1916 sprintf(prompt,
1917 GetPString(IDS_REPLACEWARNTEXT),
1918 &"s"[numfiles == 1],
1919 li->arcname, &"s"[numfiles != 1], li->targetpath);
1920 if (!WinDlgBox(HWND_DESKTOP, hwnd, CheckListProc,
1921 FM3ModHandle, CHECK_FRAME, MPFROMP(&ckl))) {
1922 if (ckl.list)
1923 FreeList(ckl.list);
1924 break;
1925 }
1926 else if (ckl.list)
1927 li->list = CombineLists(li->list, ckl.list);
1928 } // end check and warn
1929 }
1930 if (!li->list || !li->list[0])
1931 break;
1932 pszCmdLine = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1933 if (!pszCmdLine)
1934 break;
1935 strcpy(pszCmdLine,
1936 (li->type == IDM_EXTRACT ||
1937 ((li->type == IDM_VIEW ||
1938 li->type == IDM_VIEWTEXT ||
1939 li->type == IDM_VIEWBINARY ||
1940 li->type == IDM_VIEWARCHIVE ||
1941 li->type == IDM_PRINT ||
1942 li->type == IDM_EDIT ||
1943 li->type == IDM_EDITTEXT ||
1944 li->type == IDM_OPENDEFAULT ||
1945 li->type == IDM_OPENSETTINGS ||
1946 (li->type == IDM_EDITBINARY || // JBS No way for this () to be true??
1947 li->type == IDM_MCIPLAY)) ||
1948 !li->info->exwdirs)) ?
1949 li->info->extract :
1950 li->info->exwdirs);
1951 strcat(pszCmdLine, " ");
1952 BldQuotedFileName(pszCmdLine + strlen(pszCmdLine), li->arcname);
1953 endofit = &pszCmdLine[strlen(pszCmdLine)];
1954 z = 0;
1955 do {
1956 for (x = z; li->list[x] &&
1957 strlen(pszCmdLine) + strlen(li->list[x]) < MaxComLineStrg - 1 ; x++) {
1958 strcat(pszCmdLine, " ");
1959 BldQuotedFileName(pszCmdLine + strlen(pszCmdLine), li->list[x]);
1960 ptr = li->list[x];
1961 while (*ptr) {
1962 if (*ptr == '/')
1963 *ptr = '\\';
1964 ptr++;
1965 }
1966 }
1967 z = x;
1968 runemf2(SEPARATE | WINDOWED | WAIT |
1969 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
1970 hwnd, pszSrcFile, __LINE__,
1971 li->targetpath, NULL, "%s", pszCmdLine);
1972 *endofit = 0;
1973 } while (li->list[x]);
1974 if (li->type == IDM_EXTRACT || li->type == IDM_EXTRACTWDIRS) {
1975 // update windows
1976 for (x = 0; li->list[x]; x++) {
1977
1978 CHAR *temp, *p;
1979
1980 temp = li->list[x];
1981 ForwardslashToBackslash(temp);
1982 p = xmalloc(strlen(temp) + strlen(li->targetpath) + 2,
1983 pszSrcFile, __LINE__);
1984 if (p) {
1985 BldFullPathName(p, li->targetpath, temp);
1986 li->list[x] = p;
1987 free(temp);
1988 }
1989 }
1990 if (fFolderAfterExtract) {
1991
1992 CHAR objectpath[CCHMAXPATH], *p;
1993 APIRET rc;
1994
1995 GetDesktopName(objectpath, sizeof(objectpath));
1996 rc = WinDlgBox(HWND_DESKTOP, dcd->hwndParent, ObjCnrDlgProc,
1997 FM3ModHandle, OBJCNR_FRAME,
1998 MPFROMP(objectpath));
1999 if (rc) {
2000 if (rc > 1)
2001 strcpy(objectpath, "<WP_DESKTOP>");
2002 p = NULL;
2003 if (li->arcname) {
2004 p = strrchr(li->arcname, '\\');
2005 if (p)
2006 p++;
2007 }
2008 MakeShadows(dcd->hwndParent, li->list, 2, objectpath, p);
2009 }
2010 }
2011 Broadcast(WinQueryAnchorBlock(hwnd),
2012 hwndMain,
2013 UM_UPDATERECORDLIST, MPFROMP(li->list), MPVOID);
2014 }
2015 else if (li->type == IDM_EXEC)
2016 ExecOnList(hwnd,
2017 li->runfile,
2018 WINDOWED | SEPARATEKEEP | PROMPT,
2019 li->targetpath, NULL, NULL, GetPString(IDS_EXECARCFILETITLETEXT),
2020 pszSrcFile, __LINE__);
2021 else if (li->type == IDM_VIRUSSCAN)
2022 ExecOnList(hwnd, virus, PROMPT | WINDOWED | SEPARATEKEEP,
2023 li->targetpath, NULL, NULL,
2024 GetPString(IDS_VIRUSSCANARCHIVETITLETEXT),
2025 pszSrcFile, __LINE__);
2026 else if (li->type == IDM_VIEW || li->type == IDM_VIEWTEXT ||
2027 li->type == IDM_VIEWBINARY || li->type == IDM_EDIT ||
2028 li->type == IDM_EDITTEXT ||
2029 li->type == IDM_VIEWARCHIVE ||
2030 li->type == IDM_EDITBINARY ||
2031 li->type == IDM_OPENDEFAULT ||
2032 li->type == IDM_OPENSETTINGS ||
2033 li->type == IDM_MCIPLAY || li->type == IDM_PRINT) {
2034
2035 CHAR *temp, *p;
2036 for (x = 0; li->list[x]; x++) {
2037 if (!li->info->exwdirs) {
2038 temp = li->list[x];
2039 p = strrchr(li->list[x], '\\');
2040 if (p) {
2041 p++;
2042 li->list[x] = xstrdup(p, pszSrcFile, __LINE__);
2043 if (!li->list[x])
2044 li->list[x] = temp;
2045 else {
2046 xfree(temp, pszSrcFile, __LINE__);
2047 }
2048 }
2049 }
2050 BldFullPathName(pszCmdLine, li->targetpath, li->list[x]);
2051 temp = li->list[x];
2052 li->list[x] = xstrdup(pszCmdLine, pszSrcFile, __LINE__);
2053 if (!li->list[x])
2054 li->list[x] = temp;
2055 else
2056 xfree(temp, pszSrcFile, __LINE__);
2057 }
2058 free(pszCmdLine);
2059 if (li->type == IDM_VIEW || li->type == IDM_EDIT) {
2060
2061 BOOL isit = TestBinary(li->list[0]);
2062
2063 if (isit) {
2064 if (li->type == IDM_VIEW)
2065 li->type = IDM_VIEWBINARY;
2066 else
2067 li->type = IDM_EDITBINARY;
2068 }
2069 else {
2070 if (li->type == IDM_VIEW)
2071 li->type = IDM_VIEWTEXT;
2072 else
2073 li->type = IDM_EDITTEXT;
2074 }
2075 }
2076 if (li->type == IDM_MCIPLAY) {
2077
2078 FILE *fp;
2079 CHAR szTempFile[CCHMAXPATH];
2080 CHAR *modew = "w";
2081
2082 if (pTmpDir && !IsValidDir(pTmpDir))
2083 DosCreateDir(pTmpDir, 0);
2084 BldFullPathName(szTempFile, pTmpDir, PCSZ_FM2PLAYTEMP);
2085 fp = xfopen(szTempFile, modew, pszSrcFile, __LINE__, FALSE);
2086 if (fp) {
2087 fprintf(fp, "%s", ";AV/2-built FM2Play listfile\n");
2088 for (x = 0; li->list[x]; x++)
2089 fprintf(fp, "%s\n", li->list[x]);
2090 fprintf(fp, ";end\n");
2091 fclose(fp);
2092 strrev(szTempFile);
2093 strcat(szTempFile, "@/");
2094 strrev(szTempFile);
2095 RunFM2Util(PCSZ_FM2PLAYEXE, szTempFile);
2096 }
2097 }
2098 else if (li->type == IDM_PRINT) {
2099 strcpy(li->targetpath, printer);
2100 // 10 Dec 08 SHL correct error handling - looked backward
2101 if (xbeginthread(PrintListThread,
2102 65536,
2103 li,
2104 pszSrcFile,
2105 __LINE__) != -1)
2106 {
2107 li = NULL; // Ensure not freed here
2108 }
2109
2110 }
2111 else if (li->type == IDM_VIEWARCHIVE) {
2112
2113 ARC_TYPE *info;
2114
2115 for (x = 0; li->list[x]; x++) {
2116 if (IsFile(li->list[x]) == 1) {
2117 info = NULL; // Do not hide dups - fixme to know why?
2118 if (WinDlgBox(HWND_DESKTOP, HWND_DESKTOP,
2119 SBoxDlgProc, FM3ModHandle, ASEL_FRAME,
2120 (PVOID) & info) && info) {
2121 StartArcCnr(HWND_DESKTOP,
2122 HWND_DESKTOP, li->list[x], 4, info);
2123 }
2124 }
2125 }
2126 }
2127 else if ((li->type == IDM_VIEWTEXT && *viewer) ||
2128 (li->type == IDM_VIEWBINARY && *binview) ||
2129 (li->type == IDM_EDITTEXT && *editor) ||
2130 (li->type == IDM_EDITBINARY && *bined)) {
2131 //DosSleep(32); // Added WAIT to runemf2 12-12-08 GKY
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, // li->targetpath,
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); //05 Aug 07 GKY 128
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); //05 Aug 07 GKY 33
2268 wipeallf(TRUE, "%s\\*", dcd->workdir);
2269 if (rmdir(dcd->workdir)) {
2270 DosSleep(100); //05 Aug 07 GKY 256
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");
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 RestorePresParams(hwnd, PCSZ_ARCCNR);
2503 dcd->mask.fNoAttribs = TRUE;
2504 dcd->mask.fNoDirs = TRUE;
2505 *dcd->mask.prompt = 0;
2506 {
2507 PFIELDINFO pfi, pfiLastLeftCol;
2508 ULONG numcols = CON_COLS;
2509 CNRINFO cnri;
2510 ULONG size;
2511
2512 pfi = WinSendMsg(hwnd,
2513 CM_ALLOCDETAILFIELDINFO,
2514 MPFROMLONG(numcols), NULL);
2515 if (pfi) {
2516
2517 PFIELDINFO pfiFirst;
2518 FIELDINFOINSERT fii;
2519
2520 pfiFirst = pfi;
2521 pfi->flData = CFA_STRING | CFA_LEFT | CFA_FIREADONLY;
2522 pfi->flTitle = CFA_CENTER;
2523 pfi->pTitleData = (PSZ)GetPString(IDS_FILENAMECOLTEXT);
2524 pfi->offStruct = FIELDOFFSET(ARCITEM, pszDisplayName);
2525 pfiLastLeftCol = pfi;
2526 pfi = pfi->pNextFieldInfo;
2527 pfi->flData =
2528 CFA_ULONG | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
2529 pfi->flTitle = CFA_CENTER;
2530 pfi->pTitleData = (PSZ)GetPString(IDS_OLDSIZECOLTEXT);
2531 pfi->offStruct = FIELDOFFSET(ARCITEM, cbFile);
2532 pfi = pfi->pNextFieldInfo;
2533 pfi->flData =
2534 CFA_ULONG | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
2535 pfi->flTitle = CFA_CENTER;
2536 pfi->pTitleData = (PSZ)GetPString(IDS_NEWSIZECOLTEXT);
2537 pfi->offStruct = FIELDOFFSET(ARCITEM, cbComp);
2538 pfi = pfi->pNextFieldInfo;
2539 pfi->flData =
2540 CFA_STRING | CFA_CENTER | CFA_SEPARATOR | CFA_FIREADONLY;
2541 pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
2542 pfi->pTitleData = (PSZ)GetPString(IDS_DATETIMECOLTEXT);
2543 pfi->offStruct = FIELDOFFSET(ARCITEM, pszDate);
2544 pfi = pfi->pNextFieldInfo;
2545 pfi->flData = CFA_DATE | CFA_RIGHT | CFA_FIREADONLY;
2546 pfi->flTitle = CFA_CENTER;
2547 pfi->pTitleData = (PSZ)GetPString(IDS_DATECOLTEXT);
2548 pfi->offStruct = FIELDOFFSET(ARCITEM, date);
2549 pfi = pfi->pNextFieldInfo;
2550 pfi->flData = CFA_TIME | CFA_RIGHT | CFA_FIREADONLY;
2551 pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
2552 pfi->pTitleData = (PSZ)GetPString(IDS_TIMECOLTEXT);
2553 pfi->offStruct = FIELDOFFSET(ARCITEM, time);
2554 memset(&fii, 0, sizeof(FIELDINFOINSERT));
2555 fii.cb = sizeof(FIELDINFOINSERT);
2556 fii.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST;
2557 fii.cFieldInfoInsert = (SHORT) numcols;
2558 fii.fInvalidateFieldInfo = TRUE;
2559 WinSendMsg(hwnd,
2560 CM_INSERTDETAILFIELDINFO,
2561 MPFROMP(pfiFirst), MPFROMP(&fii));
2562 PostMsg(hwnd, UM_SETUP2, MPVOID, MPVOID);
2563
2564 memset(&cnri, 0, sizeof(cnri));
2565 cnri.cb = sizeof(CNRINFO);
2566 cnri.pFieldInfoLast = pfiLastLeftCol;
2567 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET + 32;
2568
2569 size = sizeof(LONG);
2570 PrfQueryProfileData(fmprof, appname, "ArcCnrSplitBar",
2571 &cnri.xVertSplitbar, &size);
2572 if (cnri.xVertSplitbar <= 0)
2573 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET + 32;
2574
2575 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT | CV_NAME));
2576 cnri.flWindowAttr |= (CV_DETAIL | CA_DETAILSVIEWTITLES | CV_FLOW);
2577 cnri.flWindowAttr &= (~(CA_ORDEREDTARGETEMPH |
2578 CA_MIXEDTARGETEMPH));
2579 cnri.pSortRecord = (PVOID) ArcSort;
2580 WinSendMsg(hwnd,
2581 CM_SETCNRINFO,
2582 MPFROMP(&cnri),
2583 MPFROMLONG(CMA_PFIELDINFOLAST |
2584 CMA_XVERTSPLITBAR |
2585 CMA_PSORTRECORD | CMA_FLWINDOWATTR));
2586 }
2587 }
2588 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(ArcSort), MPFROMP(dcd));
2589 if (xbeginthread(MakeObjWin,
2590 245760,
2591 dcd,
2592 pszSrcFile,
2593 __LINE__) == -1)
2594 {
2595 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2596 return 0;
2597 }
2598 else
2599 DosSleep(1);
2600 SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2601 DIR_FILTER), &dcd->mask, TRUE);
2602 SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2603 DIR_SORT), dcd->sortFlags, TRUE);
2604 DefArcSortFlags = dcd->sortFlags; // Remember for new windows
2605 }
2606 }
2607 return 0;
2608
2609 case UM_SETDIR:
2610 if (dcd) {
2611
2612 CHAR s[CCHMAXPATH], *p;
2613 ULONG ret = 0;
2614
2615 WinQueryDlgItemText(dcd->hwndClient, ARC_EXTRACTDIR, CCHMAXPATH, s);
2616 bstrip(s);
2617 MakeFullName(s);
2618 if (*s) {
2619 while ((p = strchr(s, '/')) != NULL)
2620 *p = '\\';
2621 while (strlen(s) > 3 && s[strlen(s) - 1] == '\\')
2622 s[strlen(s) - 1] = 0;
2623 if (stricmp(s, dcd->directory)) {
2624 if (IsFullName(s)) {
2625 if (driveflags[toupper(*s) - 'A'] &
2626 (DRIVE_NOTWRITEABLE | DRIVE_IGNORE | DRIVE_INVALID)) {
2627 Runtime_Error(pszSrcFile, __LINE__, "drive %s bad", s);
2628 WinSetDlgItemText(dcd->hwndClient,
2629 ARC_EXTRACTDIR, dcd->directory);
2630 return 0;
2631 }
2632 }
2633 if (!SetDir(dcd->hwndParent, hwnd, s, 0)) {
2634 if (stricmp(dcd->directory, s)) {
2635 //DosEnterCritSec(); //GKY 11-29-08
2636 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
2637 strcpy(lastextractpath, s);
2638 DosReleaseMutexSem(hmtxFM2Globals);
2639 //DosExitCritSec();
2640 }
2641 strcpy(dcd->directory, s);
2642 if ((!isalpha(*s) || s[1] != ':') && *s != '.')
2643 saymsg(MB_ENTER | MB_ICONASTERISK,
2644 hwnd,
2645 GetPString(IDS_WARNINGTEXT),
2646 GetPString(IDS_SPECIFYDRIVETEXT));
2647 }
2648 else
2649 ret = 1;
2650 }
2651 }
2652 WinSetDlgItemText(dcd->hwndClient, ARC_EXTRACTDIR, dcd->directory);
2653 return (MRESULT) ret;
2654 }
2655 return 0;
2656
2657 case UM_ENTER:
2658 if (WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID)) {
2659 free(mp1);
2660 return 0;
2661 }
2662 SetShiftState();
2663 if (dcd && (CHAR *) mp1) {
2664
2665 SWP swp;
2666 CHAR *filename = mp1;
2667 //printf("%s %d UM_ENTER %s\n",__FILE__, __LINE__, filename); fflush(stdout);
2668 if (IsFile(filename) != 1) {
2669 free(mp1);
2670 return 0;
2671 }
2672 WinQueryWindowPos(dcd->hwndFrame, &swp);
2673 DefaultViewKeys(hwnd, dcd->hwndFrame, dcd->hwndParent, &swp, filename);
2674 if (fUnHilite)
2675 UnHilite(hwnd, FALSE, &dcd->lastselection, 0);
2676 }
2677 free(mp1);
2678 return 0;
2679
2680 case WM_MENUEND:
2681 if (dcd) {
2682
2683 HWND hwndMenu = (HWND) mp2;
2684
2685 if (hwndMenu == ArcCnrMenu || hwndMenu == ArcMenu) {
2686 MarkAll(hwnd, TRUE, FALSE, TRUE);
2687 if (dcd->cnremphasized) {
2688 WinSendMsg(hwnd,
2689 CM_SETRECORDEMPHASIS,
2690 MPVOID, MPFROM2SHORT(FALSE, CRA_SOURCE));
2691 dcd->cnremphasized = FALSE;
2692 }
2693 }
2694 }
2695 break;
2696
2697 case MM_PORTHOLEINIT:
2698 if (dcd) {
2699 switch (SHORT1FROMMP(mp1)) {
2700 case 0:
2701 case 1:
2702 {
2703 ULONG wmsg;
2704
2705 wmsg = SHORT1FROMMP(mp1) == 0 ? UM_FILESMENU : UM_VIEWSMENU;
2706 PortholeInit((HWND) WinSendMsg(dcd->hwndClient,
2707 wmsg, MPVOID, MPVOID), mp1, mp2);
2708 }
2709 break;
2710 }
2711 }
2712 break;
2713
2714 case UM_INITMENU:
2715 case WM_INITMENU:
2716 if (dcd) {
2717 switch (SHORT1FROMMP(mp1)) {
2718 case IDM_FILESMENU:
2719 if (dcd->info) {
2720 WinEnableMenuItem((HWND) mp2,
2721 IDM_DELETE, dcd->info->delete != NULL);
2722 WinEnableMenuItem((HWND) mp2, IDM_TEST, dcd->info->test != NULL);
2723 WinEnableMenuItem((HWND) mp2, IDM_EXTRACT,
2724 dcd->info->extract != NULL && !strstr(dcd->info->ext, "TAR"));
2725 WinEnableMenuItem((HWND) mp2, IDM_ARCEXTRACT,
2726 dcd->info->extract != NULL && !strstr(dcd->info->ext, "TAR"));
2727 WinEnableMenuItem((HWND) mp2,
2728 IDM_EXTRACTWDIRS, dcd->info->exwdirs != NULL);
2729 WinEnableMenuItem((HWND) mp2,
2730 IDM_ARCEXTRACTWDIRS, dcd->info->exwdirs != NULL);
2731 WinEnableMenuItem((HWND) mp2,
2732 IDM_ARCEXTRACTWDIRSEXIT,
2733 dcd->info->exwdirs != NULL);
2734 }
2735 break;
2736
2737 case IDM_VIEWSMENU:
2738 WinEnableMenuItem((HWND) mp2, IDM_TEST, dcd->info->test != NULL);
2739 WinEnableMenuItem((HWND) mp2, IDM_ARCEXTRACT,
2740 dcd->info->extract != NULL && !strstr(dcd->info->ext, "TAR"));
2741 WinCheckMenuItem((HWND) mp2,
2742 IDM_MINIICONS, (dcd->flWindowAttr & CV_MINI) != 0);
2743 WinEnableMenuItem((HWND) mp2,
2744 IDM_RESELECT, (dcd->lastselection != NULL));
2745 break;
2746
2747 case IDM_COMMANDSMENU:
2748 SetupCommandMenu((HWND) mp2, hwnd);
2749 break;
2750
2751 case IDM_SORTSUBMENU:
2752 SetSortChecks((HWND) mp2, dcd->sortFlags);
2753 break;
2754
2755 case IDM_WINDOWSMENU:
2756 /**
2757 * add switchlist entries to end of pulldown menu
2758 */
2759 SetupWinList((HWND)mp2,
2760 hwndMain ? hwndMain : (HWND)0, dcd->hwndFrame);
2761 break;
2762 }
2763 dcd->hwndLastMenu = (HWND) mp2;
2764 }
2765 if (msg == WM_INITMENU)
2766 break;
2767 return 0;
2768
2769 case UM_LOADFILE:
2770 if (dcd && mp2) {
2771
2772 HWND hwnd;
2773
2774 if ((INT)mp1 == 5 || (INT)mp1 == 13 || (INT)mp1 == 21)
2775 hwnd = StartViewer(HWND_DESKTOP, (INT)mp1,
2776 (CHAR *)mp2, dcd->hwndFrame);
2777 else
2778 hwnd = StartMLEEditor(dcd->hwndParent,
2779 (INT)mp1, (CHAR *)mp2, dcd->hwndFrame);
2780 free((CHAR *)mp2);
2781 return MRFROMLONG(hwnd);
2782 }
2783 return 0;
2784
2785 case UM_COMMAND:
2786 if (mp1) {
2787 if (dcd) {
2788 if (!PostMsg(dcd->hwndObject, UM_COMMAND, mp1, mp2)) {
2789 Runtime_Error(pszSrcFile, __LINE__, "post");
2790 FreeListInfo((LISTINFO *) mp1);
2791 }
2792 else
2793 return (MRESULT) TRUE;
2794 }
2795 else
2796 FreeListInfo((LISTINFO *) mp1);
2797 }
2798 return 0;
2799
2800 case UM_OPENWINDOWFORME:
2801 if (dcd) {
2802 if (mp1 && !IsFile((CHAR *) mp1)) {
2803 OpenDirCnr((HWND) 0, hwndMain, dcd->hwndFrame, FALSE, (char *)mp1);
2804 }
2805 else if (mp1 && IsFile(mp1) == 1 &&
2806 CheckDriveSpaceAvail(ArcTempRoot, ullDATFileSpaceNeeded, ullTmpSpaceNeeded) != 2) {
2807 StartArcCnr(HWND_DESKTOP,
2808 dcd->hwndFrame, (CHAR *) mp1, 4, (ARC_TYPE *) mp2);
2809 }
2810 }
2811 return 0;
2812
2813 case WM_COMMAND:
2814 DosError(FERR_DISABLEHARDERR);
2815 if (dcd) {
2816 if (SwitchCommand(dcd->hwndLastMenu, SHORT1FROMMP(mp1)))
2817 return 0;
2818 if (WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID))
2819 return 0;
2820 if (!IsArcThere(hwnd, dcd->arcname)) {
2821 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2822 return 0;
2823 }
2824 switch (SHORT1FROMMP(mp1)) {
2825 case IDM_TREEVIEW:
2826
2827 break;
2828
2829 case IDM_CONTEXTMENU:
2830 {
2831 PCNRITEM pci;
2832
2833 pci = (PCNRITEM) CurrentRecord(hwnd);
2834 PostMsg(hwnd,
2835 WM_CONTROL,
2836 MPFROM2SHORT(ARC_CNR, CN_CONTEXTMENU), MPFROMP(pci));
2837 }
2838 break;
2839
2840 case IDM_NEXTWINDOW:
2841 case IDM_PREVWINDOW:
2842 {
2843 HWND hwndActive;
2844
2845 hwndActive = WinQueryFocus(HWND_DESKTOP);
2846 WinSetFocus(HWND_DESKTOP,
2847 hwndActive == hwnd ?
2848 WinWindowFromID(dcd->hwndClient, ARC_EXTRACTDIR) :
2849 hwnd);
2850 }
2851 break;
2852
2853 case IDM_FOLDERAFTEREXTRACT:
2854 fFolderAfterExtract = fFolderAfterExtract ? FALSE : TRUE;
2855 PrfWriteProfileData(fmprof, appname, "FolderAfterExtract",
2856 &fFolderAfterExtract, sizeof(BOOL));
2857 break;
2858
2859 case IDM_SHOWSELECT:
2860 QuickPopup(hwnd, dcd, CheckMenu(hwnd, &ArcCnrMenu, ARCCNR_POPUP),
2861 IDM_SELECTSUBMENU);
2862 break;
2863
2864 case IDM_SHOWSORT:
2865 QuickPopup(hwnd, dcd, CheckMenu(hwnd, &ArcCnrMenu, ARCCNR_POPUP),
2866 IDM_SORTSUBMENU);
2867 break;
2868
2869 case IDM_ARCHIVERSETTINGS:
2870 if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndParent))
2871 PostMsg(dcd->hwndParent, msg, MPFROMLONG(IDM_ARCHIVERSETTINGS), mp2);
2872 else {
2873 WinDlgBox(HWND_DESKTOP,
2874 hwnd,
2875 CfgDlgProc,
2876 FM3ModHandle,
2877 CFG_FRAME,
2878 MPFROMLONG(IDM_ARCHIVERSETTINGS));
2879 }
2880 break;
2881
2882 case IDM_RESCAN:
2883 dcd->ullTotalBytes = dcd->totalfiles =
2884 dcd->selectedfiles = dcd->selectedbytes = 0;
2885 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, "0");
2886 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, "0 / 0k");
2887 dcd->totalfiles = FillArcCnr(dcd->hwndCnr,
2888 dcd->arcname,
2889 &dcd->info,
2890 &dcd->ullTotalBytes, &dcd->stopflag);
2891 PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
2892 PostMsg(dcd->hwndCnr, UM_SETUP2, MPVOID, MPVOID);
2893 WinSendMsg(dcd->hwndCnr,
2894 CM_INVALIDATERECORD,
2895 MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
2896 break;
2897
2898 case IDM_RESELECT:
2899 SelectList(hwnd, TRUE, FALSE, FALSE, NULL, NULL, dcd->lastselection);
2900 break;
2901
2902 case IDM_HELP:
2903 if (hwndHelp)
2904 WinSendMsg(hwndHelp,
2905 HM_DISPLAY_HELP,
2906 MPFROM2SHORT(HELP_ARCLIST, 0),
2907 MPFROMSHORT(HM_RESOURCEID));
2908 break;
2909
2910 case IDM_WINDOWDLG:
2911 if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndFrame))
2912 PostMsg(dcd->hwndParent,
2913 UM_COMMAND, MPFROM2SHORT(IDM_WINDOWDLG, 0), MPVOID);
2914 break;
2915
2916 case IDM_SELECTALL:
2917 case IDM_SELECTALLFILES:
2918 case IDM_DESELECTALL:
2919 case IDM_DESELECTALLFILES:
2920 case IDM_SELECTMASK:
2921 case IDM_DESELECTMASK:
2922 case IDM_INVERT:
2923 {
2924 PARCITEM pci;
2925
2926 pci = (PARCITEM) WinSendMsg(hwnd,
2927 CM_QUERYRECORDEMPHASIS,
2928 MPFROMLONG(CMA_FIRST),
2929 MPFROMSHORT(CRA_CURSORED));
2930 if ((INT) pci == -1)
2931 pci = NULL;
2932 if (SHORT1FROMMP(mp1) == IDM_HIDEALL) {
2933 if (pci) {
2934 if (!(pci->rc.flRecordAttr & CRA_SELECTED))
2935 pci->rc.flRecordAttr |= CRA_FILTERED;
2936 WinSendMsg(hwnd,
2937 CM_INVALIDATERECORD,
2938 MPFROMP(&pci),
2939 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
2940 break;
2941 }
2942 }
2943 PostMsg(dcd->hwndObject, UM_SELECT, mp1, MPFROMP(pci));
2944 }
2945 break;
2946
2947 case IDM_SORTSMARTNAME:
2948 case IDM_SORTNAME:
2949 case IDM_SORTFILENAME:
2950 case IDM_SORTSIZE:
2951 case IDM_SORTEASIZE:
2952 case IDM_SORTFIRST:
2953 case IDM_SORTLAST:
2954 case IDM_SORTLWDATE:
2955 dcd->sortFlags &= SORT_REVERSE;
2956 // intentional fallthru
2957 case IDM_SORTREVERSE:
2958 switch (SHORT1FROMMP(mp1)) {
2959 case IDM_SORTSMARTNAME:
2960 case IDM_SORTFILENAME:
2961 dcd->sortFlags |= SORT_FILENAME;
2962 break;
2963 case IDM_SORTSIZE:
2964 dcd->sortFlags |= SORT_SIZE;
2965 break;
2966 case IDM_SORTEASIZE:
2967 dcd->sortFlags |= SORT_EASIZE;
2968 break;
2969 case IDM_SORTFIRST:
2970 dcd->sortFlags |= SORT_FIRSTEXTENSION;
2971 break;
2972 case IDM_SORTLAST:
2973 dcd->sortFlags |= SORT_LASTEXTENSION;
2974 break;
2975 case IDM_SORTLWDATE:
2976 dcd->sortFlags |= SORT_LWDATE;
2977 break;
2978 case IDM_SORTREVERSE:
2979 if (dcd->sortFlags & SORT_REVERSE)
2980 dcd->sortFlags &= (~SORT_REVERSE);
2981 else
2982 dcd->sortFlags |= SORT_REVERSE;
2983 break;
2984 }
2985 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(ArcSort), MPFROMP(dcd));
2986 SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2987 DIR_SORT), dcd->sortFlags, TRUE);
2988 DefArcSortFlags = dcd->sortFlags; // Remember for new windows
2989 break;
2990
2991 case IDM_COLLECTOR:
2992 if (!Collector) {
2993 HWND hwndC;
2994 SWP swp;
2995
2996 if (ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
2997 (!fExternalCollector && !strcmp(realappname, FM3Str)))
2998 GetNextWindowPos(dcd->hwndParent, &swp, NULL, NULL);
2999 hwndC = StartCollector(fExternalCollector ||
3000 strcmp(realappname, FM3Str) ?
3001 HWND_DESKTOP : dcd->hwndParent, 4);
3002 if (hwndC) {
3003 if (!ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
3004 (!fExternalCollector && !strcmp(realappname, FM3Str)))
3005 WinSetWindowPos(hwndC,
3006 HWND_TOP,
3007 swp.x,
3008 swp.y,
3009 swp.cx,
3010 swp.cy,
3011 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
3012 else if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3013 fAutoTile && !strcmp(realappname, FM3Str)) {
3014 TileChildren(dcd->hwndParent, TRUE);
3015 }
3016 WinSetWindowPos(hwndC, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
3017 DosSleep(100); //05 Aug 07 GKY 128
3018 }
3019 }
3020 else
3021 StartCollector(dcd->hwndParent, 4);
3022 break;
3023
3024 case IDM_ARCEXTRACTEXIT:
3025 case IDM_ARCEXTRACT:
3026 if (dcd->directory && fFileNameCnrPath &&
3027 stricmp(lastextractpath, dcd->directory)) {
3028 strcpy(lastextractpath, dcd->directory);
3029 //DbgMsg(pszSrcFile, __LINE__, "Extract dir %s", dcd->directory);
3030 SetDir(dcd->hwndParent, hwnd, dcd->directory, 1);
3031 }
3032 if (dcd->info->extract)
3033 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS |
3034 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
3035 hwnd, pszSrcFile, __LINE__,
3036 dcd->directory, NULL, "%s %s", dcd->info->extract,
3037 BldQuotedFileName(szQuotedArcName, dcd->arcname));
3038 if (SHORT1FROMMP(mp1) == IDM_ARCEXTRACTEXIT)
3039 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
3040 break;
3041
3042 case IDM_ARCEXTRACTWDIRSEXIT:
3043 case IDM_ARCEXTRACTWDIRS:
3044 if (dcd->directory && fFileNameCnrPath &&
3045 stricmp(lastextractpath, dcd->directory)) {
3046 strcpy(lastextractpath, dcd->directory);
3047 SetDir(dcd->hwndParent, hwnd, dcd->directory, 1);
3048 }
3049 if (dcd->info->exwdirs)
3050 runemf2(SEPARATE | WINDOWED | ASYNCHRONOUS |
3051 (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
3052 hwnd, pszSrcFile, __LINE__,
3053 dcd->directory, NULL, "%s %s",
3054 dcd->info->exwdirs,
3055 BldQuotedFileName(szQuotedArcName, dcd->arcname));
3056 if (SHORT1FROMMP(mp1) == IDM_ARCEXTRACTWDIRSEXIT)
3057 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
3058 break;
3059
3060 case IDM_RESORT:
3061 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(ArcSort), MPFROMP(dcd));
3062 break;
3063
3064 case IDM_FILTER:
3065 {
3066 BOOL empty = FALSE;
3067 PARCITEM pci;
3068
3069 if (!*dcd->mask.szMask) {
3070 empty = TRUE;
3071 pci = (PARCITEM) CurrentRecord(hwnd);
3072 if (pci && strchr(pci->pszFileName, '.'))
3073 strcpy(dcd->mask.szMask, pci->pszFileName);
3074 }
3075
3076 if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
3077 FM3ModHandle, MSK_FRAME, MPFROMP(&dcd->mask))) {
3078 WinSendMsg(hwnd, CM_FILTER, MPFROMP(ArcFilter), MPFROMP(dcd));
3079 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3080 }
3081 else if (empty)
3082 *dcd->mask.szMask = 0;
3083 SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
3084 DIR_FILTER), &dcd->mask, TRUE);
3085 }
3086 break;
3087
3088 case IDM_SWITCH:
3089 if (mp2) {
3090 if (stricmp(dcd->directory, (CHAR *) mp2)) {
3091 //DosEnterCritSec(); //GKY 11-29-08
3092 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
3093 strcpy(lastextractpath, (CHAR *) mp2);
3094 MakeValidDir(lastextractpath);
3095 DosReleaseMutexSem(hmtxFM2Globals);
3096 //DosExitCritSec();
3097 }
3098 strcpy(dcd->directory, (CHAR *) mp2);
3099 MakeValidDir(dcd->directory);
3100 WinSetWindowText(dcd->hwndExtract, dcd->directory);
3101 }
3102 break;
3103
3104 case IDM_WALKDIR:
3105 {
3106 CHAR newdir[CCHMAXPATH];
3107
3108 strcpy(newdir, dcd->directory);
3109 if (!WinDlgBox(HWND_DESKTOP, dcd->hwndParent, WalkExtractDlgProc,
3110 FM3ModHandle, WALK_FRAME,
3111 MPFROMP(newdir)) || !*newdir)
3112 break;
3113 if (stricmp(newdir, dcd->directory)) {
3114 strcpy(dcd->directory, newdir);
3115 if (stricmp(lastextractpath, newdir))
3116 strcpy(lastextractpath, newdir);
3117 WinSetWindowText(dcd->hwndExtract, dcd->directory);
3118 }
3119 }
3120 break;
3121
3122 case IDM_TEST:
3123 if (dcd->info->test)
3124 runemf2(SEPARATEKEEP | WINDOWED | MAXIMIZED,
3125 hwnd, pszSrcFile, __LINE__, NULL, NULL,
3126 "%s %s",dcd->info->test,
3127 BldQuotedFileName(szQuotedArcName, dcd->arcname));
3128 break;
3129
3130 case IDM_REFRESH:
3131 case IDM_DELETE:
3132 case IDM_PRINT:
3133 case IDM_VIEW:
3134 case IDM_VIEWTEXT:
3135 case IDM_VIEWBINARY:
3136 case IDM_VIEWARCHIVE:
3137 case IDM_EDIT:
3138 case IDM_EDITTEXT:
3139 case IDM_EDITBINARY:
3140 case IDM_EXTRACT:
3141 case IDM_EXTRACTWDIRS:
3142 case IDM_FIND:
3143 case IDM_EXEC:
3144 case IDM_VIRUSSCAN:
3145 case IDM_OPENDEFAULT:
3146 case IDM_OPENSETTINGS:
3147 case IDM_MCIPLAY:
3148 {
3149 LISTINFO *li;
3150# ifdef FORTIFY
3151 Fortify_EnterScope();
3152# endif
3153 li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
3154 if (li) {
3155 li->type = SHORT1FROMMP(mp1);
3156 li->hwnd = hwnd;
3157 li->list = BuildArcList(hwnd);
3158 if (li->type == IDM_DELETE)
3159 ignorereadonly = FALSE;
3160 if (li->type == IDM_REFRESH) {
3161
3162 CHAR s[CCHMAXPATH], *p;
3163 INT x, y;
3164
3165 for (x = 0; li->list && li->list[x]; x++) {
3166 BldFullPathName(s, dcd->workdir, li->list[x]);
3167 if (IsFile(s) != 1) {
3168 free(li->list[x]);
3169 li->list[x] = NULL;
3170 for (y = x; li->list[y]; y++)
3171 li->list[y] = li->list[y + 1];
3172 li->list =
3173 xrealloc(li->list, y * sizeof(CHAR *), pszSrcFile,
3174 __LINE__);
3175 x--;
3176 }
3177 else {
3178 p = xstrdup(s, pszSrcFile, __LINE__);
3179 if (p) {
3180 free(li->list[x]);
3181 li->list[x] = p;
3182 }
3183 }
3184 } // for
3185 }
3186 strcpy(li->arcname, dcd->arcname);
3187 li->info = dcd->info;
3188 {
3189 PARCITEM pai;
3190
3191 if (SHORT1FROMMP(mp1) != IDM_EXEC)
3192 pai = (PARCITEM) CurrentRecord(hwnd);
3193 else
3194 pai = (PARCITEM) WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
3195 MPFROMLONG(CMA_FIRST),
3196 MPFROMSHORT(CRA_CURSORED));
3197 if (pai && (INT) pai != -1)
3198 strcpy(li->runfile, pai->pszFileName);
3199 else
3200 strcpy(li->runfile, li->list[0]);
3201 }
3202 switch (SHORT1FROMMP(mp1)) {
3203 case IDM_VIEW:
3204 case IDM_VIEWTEXT:
3205 case IDM_VIEWBINARY:
3206 case IDM_VIEWARCHIVE:
3207 case IDM_EDIT:
3208 case IDM_EDITTEXT:
3209 case IDM_EDITBINARY:
3210 case IDM_EXEC:
3211 case IDM_PRINT:
3212 case IDM_VIRUSSCAN:
3213 case IDM_OPENDEFAULT:
3214 case IDM_OPENSETTINGS:
3215 case IDM_MCIPLAY:
3216 strcpy(li->targetpath, dcd->workdir);
3217 break;
3218 default:
3219 strcpy(li->targetpath, dcd->directory);
3220 break;
3221 }
3222 if (li->list) {
3223 if (!PostMsg(dcd->hwndObject, UM_ACTION, MPFROMP(li), MPVOID)) {
3224 Runtime_Error(pszSrcFile, __LINE__, "post");
3225 FreeListInfo(li);
3226 }
3227 else if (fUnHilite && SHORT1FROMMP(mp1) != IDM_EDIT)
3228 UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
3229 }
3230 else {
3231 free(li);
3232 }
3233 }
3234# ifdef FORTIFY
3235 Fortify_LeaveScope();
3236# endif
3237 }
3238 break;
3239 }
3240 }
3241 return 0;
3242
3243 case WM_CONTROL:
3244 DosError(FERR_DISABLEHARDERR);
3245 if (dcd) {
3246 switch (SHORT2FROMMP(mp1)) {
3247 case CN_BEGINEDIT:
3248 PostMsg(hwnd, CM_CLOSEEDIT, MPVOID, MPVOID);
3249 break;
3250
3251 case CN_ENDEDIT:
3252 if (!((PCNREDITDATA) mp2)->pRecord) {
3253
3254 PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
3255 USHORT cmd = 0;
3256
3257 if (!pfi || pfi->offStruct == FIELDOFFSET(ARCITEM, pszDisplayName))
3258 cmd = IDM_SORTSMARTNAME;
3259 else if (pfi->offStruct == FIELDOFFSET(ARCITEM, cbFile))
3260 cmd = IDM_SORTSIZE;
3261 else if (pfi->offStruct == FIELDOFFSET(ARCITEM, cbComp))
3262 cmd = IDM_SORTEASIZE;
3263 else if (pfi->offStruct == FIELDOFFSET(ARCITEM, date))
3264 cmd = IDM_SORTLWDATE;
3265 else if (pfi->offStruct == FIELDOFFSET(ARCITEM, time))
3266 cmd = IDM_SORTLWDATE;
3267 if (cmd)
3268 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
3269 }
3270 break;
3271
3272 case CN_DROPHELP:
3273 saymsg(MB_ENTER, hwnd,
3274 GetPString(IDS_DROPHELPHDRTEXT),
3275 GetPString(IDS_ARCCNRDROPHELPTEXT), dcd->arcname);
3276 return 0;
3277
3278 case CN_DRAGLEAVE:
3279 if (mp2) {
3280
3281 PDRAGINFO pDInfo;
3282
3283 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
3284 DrgAccessDraginfo(pDInfo); // Access DRAGINFO
3285 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
3286 }
3287 return 0;
3288
3289 case CN_DRAGAFTER:
3290 case CN_DRAGOVER:
3291 if (mp2) {
3292
3293 PDRAGITEM pDItem; // Pointer to DRAGITEM
3294 PDRAGINFO pDInfo; // Pointer to DRAGINFO
3295 PARCITEM pci;
3296
3297 pci = (PARCITEM) ((PCNRDRAGINFO) mp2)->pRecord;
3298 if (SHORT1FROMMP(mp1) == CN_DRAGAFTER)
3299 pci = NULL;
3300 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
3301 DrgAccessDraginfo(pDInfo); // Access DRAGINFO
3302 if (*dcd->arcname) {
3303 if ((driveflags[toupper(*dcd->arcname) - 'A'] &
3304 DRIVE_NOTWRITEABLE) || !dcd->info || !dcd->info->create) {
3305 DrgFreeDraginfo(pDInfo);
3306 return MRFROM2SHORT(DOR_NEVERDROP, 0);
3307 }
3308 }
3309 if (pci) {
3310 DrgFreeDraginfo(pDInfo);
3311 return MRFROM2SHORT(DOR_NODROP, 0);
3312 }
3313 pDItem = DrgQueryDragitemPtr(pDInfo, // Access DRAGITEM
3314 0); // Index to DRAGITEM
3315 if (DrgVerifyRMF(pDItem, // Check valid rendering
3316 (CHAR *) DRM_OS2FILE, // mechanisms and data
3317 NULL) && !(pDItem->fsControl & DC_PREPARE)) {
3318 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
3319 return MRFROM2SHORT(DOR_DROP, // Return okay to drop
3320 fCopyDefault ? DO_COPY : DO_MOVE);
3321 }
3322 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
3323 }
3324 return (MRFROM2SHORT(DOR_NEVERDROP, 0)); // Drop not valid
3325
3326 case CN_INITDRAG:
3327 if (mp2) {
3328
3329 BOOL wasemphasized = FALSE;
3330 PCNRDRAGINIT pcd = (PCNRDRAGINIT) mp2;
3331 PARCITEM pci;
3332
3333 if (pcd) {
3334 pci = (PARCITEM) pcd->pRecord;
3335 if (pci) {
3336 if (pci->rc.flRecordAttr & CRA_SELECTED)
3337 wasemphasized = TRUE;
3338 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3339 fSplitStatus && hwndStatus2)
3340 WinSetWindowText(hwndStatus2, (CHAR *) GetPString(IDS_DRAGARCMEMTEXT));
3341 if (DoFileDrag(hwnd,
3342 dcd->hwndObject,
3343 mp2, dcd->arcname, NULL, TRUE)) {
3344 if ((fUnHilite && wasemphasized) || dcd->ulItemsToUnHilite)
3345 UnHilite(hwnd, TRUE, &dcd->lastselection, dcd->ulItemsToUnHilite);
3346 }
3347 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3348 fSplitStatus && hwndStatus2) {
3349 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3350 }
3351 }
3352 else {
3353 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3354 fSplitStatus && hwndStatus2)
3355 WinSetWindowText(hwndStatus2,
3356 (CHAR *) GetPString(IDS_DRAGARCFILETEXT));
3357 DragOne(hwnd, dcd->hwndObject, dcd->arcname, FALSE);
3358 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3359 fSplitStatus && hwndStatus2)
3360 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3361 }
3362 }
3363 }
3364 return 0;
3365
3366 case CN_DROP:
3367 if (mp2) {
3368
3369 LISTINFO *li;
3370
3371 //DosBeep(500, 100); // fixme to know why beep?
3372 li = DoFileDrop(hwnd, dcd->arcname, FALSE, mp1, mp2);
3373 //DosBeep(50, 100); // fixme to know why beep?
3374 CheckPmDrgLimit(((PCNRDRAGINFO)mp2)->pDragInfo);
3375 if (li) {
3376 li->type = li->type == DO_MOVE ? IDM_ARCHIVEM : IDM_ARCHIVE;
3377 strcpy(li->targetpath, dcd->arcname);
3378 if (!li->list ||
3379 !li->list[0] ||
3380 !PostMsg(dcd->hwndObject, UM_ACTION, MPFROMP(li), MPVOID))
3381 FreeListInfo(li);
3382 }
3383 }
3384 return 0;
3385
3386 case CN_CONTEXTMENU:
3387 {
3388 PARCITEM pci = (PARCITEM) mp2;
3389
3390 if (pci) {
3391 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPFROMP(pci),
3392 MPFROM2SHORT(TRUE, CRA_CURSORED));
3393 MarkAll(hwnd, FALSE, FALSE, TRUE);
3394 dcd->hwndLastMenu = CheckMenu(hwnd, &ArcMenu, ARC_POPUP);
3395 }
3396 else {
3397 dcd->hwndLastMenu = CheckMenu(hwnd, &ArcCnrMenu, ARCCNR_POPUP);
3398 if (dcd->hwndLastMenu && !dcd->cnremphasized) {
3399 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
3400 MPFROM2SHORT(TRUE, CRA_SOURCE));
3401 dcd->cnremphasized = TRUE;
3402 }
3403 }
3404 if (dcd->hwndLastMenu) {
3405 if (dcd->hwndLastMenu == ArcCnrMenu) {
3406 if (dcd->flWindowAttr & CV_MINI)
3407 WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
3408 }
3409 WinCheckMenuItem(dcd->hwndLastMenu, IDM_FOLDERAFTEREXTRACT,
3410 fFolderAfterExtract);
3411 if (!PopupMenu(hwnd, hwnd, dcd->hwndLastMenu)) {
3412 if (dcd->cnremphasized) {
3413 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
3414 MPFROM2SHORT(FALSE, CRA_SOURCE));
3415 dcd->cnremphasized = TRUE;
3416 }
3417 MarkAll(hwnd, TRUE, FALSE, TRUE);
3418 }
3419 }
3420 }
3421 break;
3422
3423 case CN_EMPHASIS:
3424 if (mp2) {
3425
3426 PNOTIFYRECORDEMPHASIS pre = mp2;
3427 PARCITEM pci;
3428 CHAR s[CCHMAXPATHCOMP + 91], tf[81], tb[81];
3429
3430 pci = (PARCITEM)(pre ? pre->pRecord : NULL);
3431 if (!pci) {
3432 if (!ParentIsDesktop(hwnd, dcd->hwndParent)) {
3433 if (hwndStatus2)
3434 WinSetWindowText(hwndStatus2, NullStr);
3435 if (fMoreButtons)
3436 WinSetWindowText(hwndName, NullStr);
3437 }
3438 break;
3439 }
3440 if (pre->fEmphasisMask & CRA_SELECTED) {
3441 if (pci->rc.flRecordAttr & CRA_SELECTED) {
3442 dcd->selectedbytes += pci->cbFile;
3443 dcd->selectedfiles++;
3444 }
3445 else if (dcd->selectedfiles) {
3446 dcd->selectedbytes -= pci->cbFile;
3447 dcd->selectedfiles--;
3448 }
3449 commafmt(tf, sizeof(tf), dcd->selectedfiles);
3450 if (dcd->ullTotalBytes)
3451 CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, ' ');
3452 else
3453 *tb = 0;
3454 sprintf(s, "%s%s%s", tf, *tb ? " / " : NullStr, tb);
3455 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
3456 }
3457 else if (WinQueryActiveWindow(dcd->hwndParent) ==
3458 dcd->hwndFrame &&
3459 !ParentIsDesktop(hwnd, dcd->hwndParent)) {
3460 if (pre->fEmphasisMask & CRA_CURSORED) {
3461 if (pci->rc.flRecordAttr & CRA_CURSORED) {
3462 if (fSplitStatus && hwndStatus2) {
3463 if (dcd->ullTotalBytes)
3464 CommaFmtULL(tb, sizeof(tb), pci->cbFile, ' ');
3465 else
3466 *tb = 0;
3467 sprintf(s, "%s%s%s%s",
3468 *tb ? " " : NullStr,
3469 tb, *tb ? " " : NullStr, pci->pszFileName);
3470 WinSetWindowText(hwndStatus2, s);
3471 }
3472 if (fMoreButtons)
3473 WinSetWindowText(hwndName, pci->pszFileName);
3474 }
3475 }
3476 }
3477 }
3478 break;
3479
3480 case CN_ENTER:
3481 if (mp2) {
3482
3483 PARCITEM pci = (PARCITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
3484
3485 if (pci) {
3486
3487 CHAR *s;
3488
3489 if ((pci->rc.flRecordAttr & CRA_INUSE) ||
3490 (pci->flags & (ARCFLAGS_REALDIR | ARCFLAGS_PSEUDODIR)))
3491 break;
3492 s = xstrdup(pci->pszFileName, pszSrcFile, __LINE__);
3493 if (s) {
3494 if (!PostMsg(dcd->hwndObject, UM_ENTER, MPFROMP(s), MPVOID)) {
3495 Runtime_Error(pszSrcFile, __LINE__, "post");
3496 free(s);
3497 }
3498 }
3499 }
3500 }
3501 break;
3502 }
3503 }
3504 return 0;
3505
3506 case UM_FOLDUP:
3507 if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
3508 DosExit(EXIT_PROCESS, 1);
3509 return 0;
3510
3511 case UM_CLOSE:
3512 WinDestroyWindow(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
3513 QW_PARENT));
3514 return 0;
3515
3516 case WM_SAVEAPPLICATION:
3517 if (dcd && ParentIsDesktop(hwnd, dcd->hwndParent)) {
3518 SWP swp;
3519
3520 WinQueryWindowPos(dcd->hwndFrame, &swp);
3521 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE | SWP_MAXIMIZE)))
3522 PrfWriteProfileData(fmprof, appname, "AV2SizePos", &swp, sizeof(swp));
3523 }
3524 break;
3525
3526 case WM_CLOSE:
3527 WinSendMsg(hwnd, WM_SAVEAPPLICATION, MPVOID, MPVOID);
3528 if (dcd)
3529 dcd->stopflag++;
3530 if (dcd && dcd->hwndObject) {
3531 if (!PostMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID))
3532 WinSendMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID);
3533 }
3534 // In case object window frees dcd
3535 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
3536 if (!dcd ||
3537 (!dcd->dontclose &&
3538 !dcd->amextracted && ParentIsDesktop(hwnd, dcd->hwndParent))) {
3539 if (!PostMsg(hwnd, UM_FOLDUP, MPVOID, MPVOID))
3540 WinSendMsg(hwnd, UM_FOLDUP, MPVOID, MPVOID);
3541 }
3542 return 0;
3543
3544 case WM_DESTROY:
3545 if (ArcMenu)
3546 WinDestroyWindow(ArcMenu);
3547 if (ArcCnrMenu)
3548 WinDestroyWindow(ArcCnrMenu);
3549 ArcMenu = ArcCnrMenu = (HWND) 0;
3550 EmptyArcCnr(hwnd);
3551# ifdef FORTIFY
3552 Fortify_LeaveScope();
3553# endif
3554 break;
3555 }
3556 if (dcd && dcd->oldproc){
3557 return dcd->oldproc(hwnd, msg, mp1, mp2);
3558 }
3559 else
3560 return PFNWPCnr(hwnd, msg, mp1, mp2);
3561}
3562
3563MRESULT EXPENTRY ArcCnrMenuProc(HWND hwnd, ULONG msg, MPARAM mp1,
3564 MPARAM mp2)
3565{
3566 PFNWP oldMenuProc = WinQueryWindowPtr(hwnd, QWL_USER);
3567 static short sLastMenuitem;
3568
3569 switch (msg) {
3570 case WM_MOUSEMOVE: {
3571 if (fOtherHelp) {
3572 RECTL rectl;
3573 SHORT i, sCurrentMenuitem;
3574 SHORT MenuItems = 10;
3575 SHORT asMenuIDs[10] = {IDM_VIEW,
3576 IDM_DELETE,
3577 IDM_EXEC,
3578 IDM_EXTRACT,
3579 IDM_TEST,
3580 IDM_VIRUSSCAN,
3581 IDM_RESCAN,
3582 IDM_WALKDIR,
3583 IDM_FILTER,
3584 0};
3585 PCSZ szHelpString = NULL;
3586
3587
3588 for (i=0; i<MenuItems; i++) {
3589 sCurrentMenuitem = asMenuIDs[i];
3590 oldMenuProc(hwnd,MM_QUERYITEMRECT,
3591 MPFROM2SHORT(asMenuIDs[i], FALSE),
3592 &rectl);
3593
3594 if (MOUSEMSG(&msg)->x > rectl.xLeft &&
3595 MOUSEMSG(&msg)->x < rectl.xRight &&
3596 MOUSEMSG(&msg)->y > rectl.yBottom &&
3597 MOUSEMSG(&msg)->y < rectl.yTop)
3598 break;
3599 } // for
3600
3601
3602 switch (sCurrentMenuitem) {
3603 case 0:
3604 break;
3605 case IDM_VIEW:
3606 szHelpString = GetPString(IDS_ARCCNRVIEWMENUHELP);
3607 break;
3608 case IDM_DELETE:
3609 szHelpString = GetPString(IDS_ARCCNRDELETEMENUHELP);
3610 break;
3611 case IDM_EXEC:
3612 szHelpString = GetPString(IDS_ARCCNREXECMENUHELP);
3613 break;
3614 case IDM_EXTRACT:
3615 szHelpString = GetPString(IDS_ARCCNREXTRACTMENUHELP);
3616 break;
3617 case IDM_TEST:
3618 szHelpString = GetPString(IDS_ARCCNRTESTMENUHELP);
3619 break;
3620 case IDM_VIRUSSCAN:
3621 szHelpString = GetPString(IDS_ARCCNRVIRUSMENUHELP);
3622 break;
3623 case IDM_RESCAN:
3624 szHelpString = GetPString(IDS_ARCCNRRESCANMENUHELP);
3625 break;
3626 case IDM_WALKDIR:
3627 szHelpString = GetPString(IDS_ARCCNRWALKDIRMENUHELP);
3628 break;
3629 case IDM_FILTER:
3630 szHelpString = GetPString(IDS_ARCCNRFILTERMENUHELP);
3631 break;
3632 default:
3633 break;
3634 }
3635
3636 if (sLastMenuitem != sCurrentMenuitem && szHelpString) {
3637 sLastMenuitem = sCurrentMenuitem;
3638 MakeBubble(hwnd, TRUE, szHelpString);
3639 }
3640 else if (hwndBubble && !sCurrentMenuitem){
3641 sLastMenuitem = sCurrentMenuitem;
3642 WinDestroyWindow(hwndBubble);
3643 }
3644 }
3645 }
3646 }
3647 return oldMenuProc(hwnd, msg, mp1, mp2);
3648}
3649
3650HWND StartArcCnr(HWND hwndParent, HWND hwndCaller, CHAR * arcname, INT flags,
3651 ARC_TYPE * sinfo)
3652{
3653 /**
3654 * bitmapped flags:
3655 * 1 = am extracted from another archive
3656 * 4 = don't kill proc on close
3657 */
3658
3659 HWND hwndFrame = (HWND) 0, hwndClient;
3660 ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
3661 FCF_SIZEBORDER | FCF_MINMAX | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE;
3662 USHORT id;
3663 DIRCNRDATA *dcd;
3664 ARC_TYPE *info = sinfo;
3665 CHAR title[MAXNAMEL + 1] = "AV/2 - ";
3666 CHAR fullname[CCHMAXPATH + 8], *p, temp;
3667 static USHORT idinc = 0;
3668
3669
3670 if (strrchr(arcname, '.')) {
3671 if (!stricmp(strrchr(arcname, '.') + 1, "LZ") && info->list == NULL) {
3672 saymsg(MB_ENTER | MB_ICONASTERISK, HWND_DESKTOP, GetPString(IDS_LZIPLIMITATION),
3673 GetPString(IDS_LZIPNOLIST));
3674 return -1;
3675 }
3676 }
3677
3678 if (!idinc)
3679 idinc = (rand() % 256);
3680 if (ParentIsDesktop(hwndParent, hwndParent))
3681 FrameFlags |= (FCF_TASKLIST | FCF_MENU);
3682 if (arcname) {
3683 DosError(FERR_DISABLEHARDERR);
3684 if (DosQueryPathInfo(arcname,
3685 FIL_QUERYFULLNAME, fullname, sizeof(fullname)))
3686 strcpy(fullname, arcname);
3687 ForwardslashToBackslash(fullname);
3688 if (!info)
3689 info = find_type(fullname, arcsighead);
3690 if (!info)
3691 return hwndFrame;
3692 if (strlen(title) + strlen(fullname) > MAXNAMEL) {
3693 p = title + strlen(title);
3694 strncpy(p, fullname, MAXNAMEL / 2 - 5);
3695 strcpy(p + MAXNAMEL / 2 - 5, "...");
3696 strcat(title, fullname + strlen(fullname) - (MAXNAMEL / 2 - 5));
3697 }
3698 else {
3699 strcat(title, fullname);
3700 }
3701 hwndFrame = WinCreateStdWindow(hwndParent,
3702 WS_VISIBLE,
3703 &FrameFlags,
3704 (CHAR *) WC_ARCCONTAINER,
3705 title,
3706 WS_VISIBLE | fwsAnimate,
3707 FM3ModHandle, ARC_FRAME, &hwndClient);
3708 if (hwndFrame && hwndClient) {
3709 id = ARC_FRAME + idinc++;
3710 if (idinc > 512)
3711 idinc = 0;
3712 WinSetWindowUShort(hwndFrame, QWS_ID, id);
3713# ifdef FORTIFY
3714 Fortify_EnterScope();
3715# endif
3716 dcd = xmallocz(sizeof(DIRCNRDATA), pszSrcFile, __LINE__);
3717 if (!dcd) {
3718 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3719 hwndFrame = (HWND) 0;
3720 }
3721 else {
3722# ifdef FORTIFY
3723 // Will be freed by WM_DESTROY
3724 Fortify_ChangeScope(dcd, -1);
3725# endif
3726 dcd->size = sizeof(DIRCNRDATA);
3727 dcd->id = id;
3728 dcd->type = ARC_FRAME;
3729 if (pTmpDir && !IsValidDir(pTmpDir))
3730 DosCreateDir(pTmpDir, 0);
3731 MakeTempName(dcd->workdir, ArcTempRoot, 2);
3732 strcpy(dcd->arcname, fullname);
3733 if (*extractpath) {
3734 if (!strcmp(extractpath, "*")) {
3735 p = strrchr(fullname, '\\');
3736 if (p) {
3737 if (p < fullname + 3)
3738 p++;
3739 temp = *p;
3740 *p = 0;
3741 strcpy(dcd->directory, fullname);
3742 *p = temp;
3743 }
3744 }
3745 else
3746 strcpy(dcd->directory, extractpath);
3747 }
3748 if (!*dcd->directory && *lastextractpath) {
3749 //DosEnterCritSec(); //GKY 11-29-08
3750 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
3751 strcpy(dcd->directory, lastextractpath);
3752 DosReleaseMutexSem(hmtxFM2Globals);
3753 //DosExitCritSec();
3754 }
3755 if (!*dcd->directory) {
3756 if (!ParentIsDesktop(hwndParent, hwndParent))
3757 TopWindowName(hwndParent, hwndCaller, dcd->directory);
3758 if (!*dcd->directory) {
3759 p = strrchr(fullname, '\\');
3760 if (p) {
3761 if (p < fullname + 3)
3762 p++;
3763 *p = 0;
3764 strcpy(dcd->directory, fullname);
3765 }
3766 }
3767 }
3768 if (!*dcd->directory ||
3769 (IsFile(dcd->directory) == 1) ||
3770 (isalpha(*dcd->directory) &&
3771 (driveflags[toupper(*dcd->directory) - 'A'] &
3772 DRIVE_NOTWRITEABLE)))
3773 strcpy(dcd->directory, pFM2SaveDirectory);
3774 dcd->hwndParent = hwndParent ? hwndParent : HWND_DESKTOP;
3775 dcd->hwndFrame = hwndFrame;
3776 dcd->hwndClient = hwndClient;
3777 dcd->amextracted = (flags & 1) != 0;
3778 dcd->dontclose = (flags & 4) != 0;
3779 dcd->info = info;
3780 dcd->sortFlags = DefArcSortFlags;
3781 {
3782 PFNWP oldproc;
3783
3784 oldproc = WinSubclassWindow(hwndFrame, (PFNWP) ArcFrameWndProc);
3785 WinSetWindowPtr(hwndFrame, QWL_USER, (PVOID) oldproc);
3786 }
3787 dcd->hwndCnr = WinCreateWindow(hwndClient,
3788 WC_CONTAINER,
3789 NULL,
3790 CCS_AUTOPOSITION | CCS_MINIICONS |
3791 CCS_MINIRECORDCORE | ulCnrType |
3792 WS_VISIBLE,
3793 0,
3794 0,
3795 0,
3796 0,
3797 hwndClient,
3798 HWND_TOP, (ULONG) ARC_CNR, NULL, NULL);
3799 if (!dcd->hwndCnr) {
3800 Win_Error(hwndClient, hwndClient, pszSrcFile, __LINE__,
3801 PCSZ_WINCREATEWINDOW);
3802 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3803 free(dcd);
3804 hwndFrame = (HWND) 0;
3805 }
3806 else {
3807 WinSetWindowPtr(dcd->hwndCnr, QWL_USER, (PVOID) dcd);
3808 dcd->oldproc = WinSubclassWindow(dcd->hwndCnr,
3809 (PFNWP) ArcCnrWndProc);
3810 {
3811 USHORT ids[] = { DIR_TOTALS, DIR_SELECTED, DIR_VIEW, DIR_SORT,
3812 DIR_FILTER, DIR_FOLDERICON, 0
3813 };
3814
3815 CommonCreateTextChildren(dcd->hwndClient,
3816 WC_ARCSTATUS, ids);
3817 }
3818 WinEnableWindow(WinWindowFromID(dcd->hwndClient, DIR_VIEW), FALSE);
3819 dcd->hwndExtract = WinCreateWindow(dcd->hwndClient,
3820 WC_ENTRYFIELD,
3821 NULL,
3822 ES_AUTOSCROLL,
3823 0,
3824 0,
3825 0,
3826 0,
3827 dcd->hwndClient,
3828 HWND_TOP,
3829 ARC_EXTRACTDIR, NULL, NULL);
3830 WinSendMsg(dcd->hwndExtract,
3831 EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
3832 WinSetWindowText(dcd->hwndExtract, dcd->directory);
3833 if (!PostMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID))
3834 WinSendMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID);
3835 if (FrameFlags & FCF_MENU) {
3836 PFNWP oldmenuproc;
3837 HWND hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
3838
3839 oldmenuproc = WinSubclassWindow(hwndMenu, (PFNWP) ArcCnrMenuProc);
3840 WinSetWindowPtr(hwndMenu, QWL_USER, (PVOID) oldmenuproc);
3841 if (!fToolbar) {
3842
3843 if (hwndMenu) {
3844 WinSendMsg(hwndMenu, MM_DELETEITEM,
3845 MPFROM2SHORT(IDM_VIEW, FALSE), MPVOID);
3846 WinSendMsg(hwndMenu, MM_DELETEITEM,
3847 MPFROM2SHORT(IDM_EXEC, FALSE), MPVOID);
3848 WinSendMsg(hwndMenu, MM_DELETEITEM,
3849 MPFROM2SHORT(IDM_RESCAN, FALSE), MPVOID);
3850 WinSendMsg(hwndMenu, MM_DELETEITEM,
3851 MPFROM2SHORT(IDM_DELETE, FALSE), MPVOID);
3852 WinSendMsg(hwndMenu, MM_DELETEITEM,
3853 MPFROM2SHORT(IDM_EXTRACT, FALSE), MPVOID);
3854 WinSendMsg(hwndMenu, MM_DELETEITEM,
3855 MPFROM2SHORT(IDM_TEST, FALSE), MPVOID);
3856 WinSendMsg(hwndMenu, MM_DELETEITEM,
3857 MPFROM2SHORT(IDM_VIRUSSCAN, FALSE), MPVOID);
3858 WinSendMsg(hwndMenu, MM_DELETEITEM,
3859 MPFROM2SHORT(IDM_WALKDIR, FALSE), MPVOID);
3860 WinSendMsg(hwndMenu, MM_DELETEITEM,
3861 MPFROM2SHORT(IDM_FILTER, FALSE), MPVOID);
3862 }
3863 }
3864 }
3865 if (FrameFlags & FCF_TASKLIST) {
3866
3867 SWP swp, swpD;
3868 ULONG size = sizeof(swp);
3869 LONG cxScreen, cyScreen;
3870
3871 WinQueryTaskSizePos(WinQueryAnchorBlock(hwndFrame), 0, &swp);
3872 if (PrfQueryProfileData(fmprof, appname, "AV2SizePos", &swpD, &size)) {
3873 cxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
3874 cyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
3875 if (swp.x + swpD.cx > cxScreen)
3876 swp.x = cxScreen - swpD.cx;
3877 if (swp.y + swpD.cy > cyScreen)
3878 swp.y = cyScreen - swpD.cy;
3879 swp.cx = swpD.cx;
3880 swp.cy = swpD.cy;
3881 }
3882 WinSetWindowPos(hwndFrame,
3883 HWND_TOP,
3884 swp.x,
3885 swp.y,
3886 swp.cx,
3887 swp.cy,
3888 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER |
3889 SWP_ACTIVATE);
3890 }
3891 }
3892 }
3893# ifdef FORTIFY
3894 Fortify_LeaveScope();
3895# endif
3896 }
3897 }
3898 return hwndFrame;
3899}
3900
3901#pragma alloc_text(ARCCNRS,ArcCnrWndProc,ArcObjWndProc,ArcClientWndProc,BldQuotedFullPathName)
3902#pragma alloc_text(ARCCNRS,ArcTextProc,FillArcCnr,ArcFilter,BldQuotedFileName)
3903#pragma alloc_text(ARCCNRS,ArcSort,ArcFrameWndProc,IsArcThere,ArcErrProc)
3904#pragma alloc_text(STARTUP,StartArcCnr)
Note: See TracBrowser for help on using the repository browser.