source: trunk/dll/arccnrs.c@ 1799

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

Add fix for trap on close while filtered dir container was still populating to collector, arc container and tree container after collector experienced the same trap. Ticket [535]

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