source: trunk/dll/arccnrs.c@ 1782

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

Addition code issues found based on cppcheck warnings

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