source: trunk/dll/arccnrs.c@ 1877

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

Remove debug code

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