source: trunk/dll/arccnrs.c@ 1411

Last change on this file since 1411 was 1411, checked in by Steven Levine, 16 years ago

Rework extended container search to use common logic
Update docs to match code
Shift now reverses configured state of extended container search enable
Backslash optional in not ambiguous

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