source: trunk/dll/arccnrs.c@ 1773

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

Remove bzip check added in CS [1690] Ticket [537]

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