source: trunk/dll/arccnrs.c

Last change on this file was 1892, checked in by Steven Levine, 6 years ago

Rework RemoveCnrItems to avoid possible traps on bad input.
Rework RemoveArcItems like RemoveCnrItems.
Sync source with standards.

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