source: trunk/dll/worker.c@ 1498

Last change on this file since 1498 was 1498, checked in by Gregg Young, 16 years ago

Changes to get FM2 to compile with the latest watcom 1.9 beta (mostly type casts of CHAR CONSTANT * to CHAR *). Changes to get the environment settings working everywhere again (broken by the change that moved commands to the INI); Added an environment size variable (set to 2048 which was the largest I found hard coded). Still need to find everywhere the environment size is set and use this variable.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 48.0 KB
Line 
1
2/***********************************************************************
3
4 $Id: worker.c 1498 2010-01-18 00:57:01Z gyoung $
5
6 Worker thread
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2009 Steven H. Levine
10
11 16 Oct 02 SHL Comments
12 18 Oct 02 SHL MassAction:Archive - force extension so file found
13 06 Jun 05 SHL Indent -i2
14 06 Jun 05 SHL Rework Action for VAC3.65 compat
15 27 Jul 05 SHL IDM_DOITYOURSELF - avoid need to strip in ExecOnList
16 22 Jul 06 SHL Comments
17 22 Jul 06 SHL Check more run time errors
18 03 Nov 06 SHL Renames
19 03 Nov 06 SHL Count thread usage
20 21 Apr 07 GKY Find FM2Utils by path or utils directory
21 16 Jun 07 SHL Update for OpenWatcom
22 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
23 07 Aug 07 SHL Use BldQuotedFileName
24 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
25 26 Aug 07 SHL Revert to DosSleep(0)
26 29 Feb 08 GKY Refactor global command line variables to notebook.h
27 22 Jun 08 GKY Made Felete move to xworkplace trash can on systems that have it
28 16 JUL 08 GKY Use TMP directory for temp files
29 20 Jul 08 GKY Add save/append filename to clipboard.
30 02 Aug 08 GKY Limit use of "trash can" to local writable fixed drives or to trash can supported
31 drives list if it exists. Fix ability to deselect use of trash can.
32 01 Sep 08 GKY Add code to retry on Netdrives "pipe error"
33 04 Dec 08 GKY Add a DosSleep to allow file extract to complete before rescan
34 04 Dec 08 GKY Add mutex semaphore and disable fSyncUpdates for file deletes to prevent the creation
35 on dead CNRITEMS.
36 10 Dec 08 SHL Integrate exception handler support
37 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis
38 25 Dec 08 GKY Add DRIVE_RSCANNED flag to monitor for the first recursive drive scan per session
39 to prevent duplicate directory names in tree following a copy before initial scan.
40 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
41 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
42 08 Mar 09 GKY Additional strings move to PCSZs
43 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
44 26 Jul 09 GKY Fix failure of containers to update when Tree container isn't open in FM2 lite
45 13 Dec 09 GKY Attempt to fix container update issues with FM/2 lite
46 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
47
48***********************************************************************/
49
50#include <stdlib.h>
51#include <string.h>
52#include <ctype.h>
53#include <share.h>
54#include <process.h> // _beginthread // 10 Dec 08 SHL
55#include <time.h>
56
57#define INCL_DOS
58#define INCL_DOSERRORS
59// #define INCL_WINPROGRAMLIST // 13 Jul 09 SHL dropped
60// #define INCL_WINHELP // 13 Jul 09 SHL dropped
61#define INCL_LONGLONG
62#define INCL_WINPOINTERS // WinSetFileIcon
63// #define INCL_WINWORKPLACE // 13 Jul 09 SHL dropped
64#define INCL_WINSHELLDATA // PrfQueryProfileData
65
66#include "fm3dll.h"
67#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
68#include "mainwnd2.h" // Data declaration(s)
69#include "arccnrs.h" // Data declaration(s)
70#include "init.h" // Data declaration(s)
71#include "defview.h" // Data declaration(s)
72#include "newview.h" // Data declarations
73#include "fm3dlg.h"
74#include "fm3str.h"
75#include "comp.h" // FCOMPARE
76#include "pathutil.h" // BldQuotedFileName
77#include "makelist.h" // AddToList
78#include "errutil.h" // Dos_Error...
79#include "strutil.h" // GetPString
80#include "notebook.h" // External viewers
81#include "worker.h" // Action
82#include "notify.h" // AddNote
83#include "copyf.h" // AdjustWildcardName, make_deleteable
84#include "attribs.h" // AttrListDlgProc
85#include "chklist.h" // CheckListProc
86#include "info.h" // DrvInfoProc
87#include "extract.h" // ExtractDlgProc
88#include "info.h" // FileInfoProc
89#include "valid.h" // GetDesktopName, IsNewer
90#include "saveclip.h" // ListToClipboardHab
91#include "shadow.h" // MakeShadows
92#include "mkdir.h" // MassMkdir
93#include "uudecode.h" // MergeDlgProc
94#include "objcnr.h" // ObjCnrDlgProc
95#include "printer.h" // PrintDlgProc, PrintListThread
96#include "rename.h" // RenameProc
97#include "srchpath.h" // RunFM2Util
98#include "mainwnd.h" // TopWindowName
99#include "uudecode.h" // UUD
100#include "walkem.h" // WalkCopyDlgProc, WalkDlgProc, WalkMoveDlgProc
101#include "archive.h" // ArchiveDlgProc
102#include "misc.h" // Broadcast
103#include "common.h" // DecrThreadUsage, IncrThreadUsage
104#include "eas.h" // DisplayEAsProc
105#include "systemf.h" // ExecOnList
106#include "avl.h" // SBoxDlgProc
107#include "subj.h" // Subject
108#include "stristr.h" // stristr
109#include "wrappers.h" // xfopen
110#include "fortify.h"
111#include "excputil.h" // 06 May 08 SHL added
112
113// Data definitions
114#pragma data_seg(GLOBAL2)
115FILE *LogFileHandle;
116
117#pragma data_seg(DATA2)
118
119static PSZ pszSrcFile = __FILE__;
120
121#ifdef UNDO
122
123static VOID LINFO undo;
124
125VOID FreeUndo(VOID)
126{
127 if (undo->list)
128 FreeList(undo->list);
129 memset(&undo, 0, sizeof(undo));
130}
131
132VOID Undo(HWND hwndCnr, HWND hwndFrame, HWND hwndClient, HWND hwndParent)
133{
134 LISTINFO *li;
135 WORKER *wk;
136
137 if (undo->type && undo->list && undo->list[0]) {
138 switch (undo->type) {
139 case IDM_MOVE:
140 case IDM_COPY:
141 case IDM_EXTRACT:
142 {
143# ifdef FORTIFY
144 Fortify_EnterScope();
145# endif
146 li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
147 if (li) {
148 wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
149 if (wk) {
150 wk->size = sizeof(WORKER);
151 wk->hwndCnr = hwndCnr;
152 wk->hwndParent = hwndParent;
153 wk->hwndFrame = hwndFrame;
154 wk->hwndClient = hwndClient;
155 wk->li = li;
156 *wk->li = *undo;
157 switch (undo->type) {
158 case IDM_COPY:
159 case IDM_EXTRACT:
160 li->type = IDM_PERMDELETE;
161 break;
162 }
163 if (xbeginthread(MassAction,
164 122880,
165 wk,
166 pszSrcFile,
167 __LINE__) == -1)
168 {
169 FreeListInfo(wk->li);
170 free(wk);
171# ifdef FORTIFY
172 Fortify_LeaveScope();
173# endif
174 }
175 }
176 else
177 FreeListInfo(li);
178 }
179 }
180 break;
181 } // switch
182 }
183 FreeUndo();
184# ifdef FORTIFY
185 Fortify_LeaveScope();
186# endif
187}
188
189#endif // defined(UNDO)
190
191/**
192 * Apply action to file list
193 * Action repeated for each item in list
194 */
195
196VOID Action(VOID * args)
197{
198 WORKER *wk = (WORKER *)args;
199 HAB hab2;
200 HMQ hmq2;
201 CHAR **files = NULL;
202 INT plen = 0;
203 CHAR *p, *pp;
204 CHAR szQuotedDirName[CCHMAXPATH];
205 CHAR szQuotedFileName[CCHMAXPATH];
206
207
208 if (wk) {
209# ifdef FORTIFY
210 Fortify_EnterScope();
211# endif
212 if (wk->li && wk->li->list && wk->li->list[0]) {
213 hab2 = WinInitialize(0);
214 if (hab2) {
215 hmq2 = WinCreateMsgQueue(hab2, 0);
216 if (hmq2) {
217 CHAR message[(CCHMAXPATH * 2) + 80], wildname[CCHMAXPATH];
218 UINT x;
219 BOOL dontask = FALSE, wildcarding = FALSE, overold =
220 FALSE, overnew = FALSE, usedtarget;
221
222 WinCancelShutdown(hmq2, TRUE);
223 IncrThreadUsage();
224 *wildname = 0;
225 // Do action specific preprocessing
226 switch (wk->li->type) {
227 case IDM_MERGE:
228 if (wk->li->type == IDM_MERGE) {
229 if (TestBinary(wk->li->list[0]))
230 wk->li->type = IDM_MERGEBINARY;
231 else
232 wk->li->type = IDM_MERGETEXT;
233 }
234 strcpy(wk->li->targetpath, wk->li->list[0]);
235 p = strrchr(wk->li->targetpath, '\\');
236 if (p) {
237 p++;
238 *p = 0;
239 }
240 else
241 strcat(wk->li->targetpath, PCSZ_BACKSLASH);
242 sprintf(wk->li->targetpath + strlen(wk->li->targetpath),
243 "MERGE.%03x", (clock() & 4095L));
244 if (!WinDlgBox(HWND_DESKTOP,
245 wk->hwndFrame,
246 MergeDlgProc, FM3ModHandle, MRG_FRAME, (PVOID) wk))
247 goto Abort;
248 if (!wk->li->type ||
249 !*wk->li->targetpath || !wk->li->list || !wk->li->list[0])
250 goto Abort;
251 if (IsFile(wk->li->targetpath) != 1 && !wk->li->list[1]) {
252 saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
253 wk->hwndFrame,
254 GetPString(IDS_AHEMTEXT),
255 GetPString(IDS_SILLYMERGETEXT));
256 goto Abort;
257 }
258 break;
259 case IDM_WILDMOVE:
260 wildcarding = TRUE;
261 wk->li->type = IDM_MOVE;
262 break;
263 case IDM_WILDRENAME:
264 wildcarding = TRUE;
265 wk->li->type = IDM_RENAME;
266 break;
267 case IDM_WILDCOPY:
268 wildcarding = TRUE;
269 wk->li->type = IDM_COPY;
270 break;
271 case IDM_MOVEPRESERVE:
272 {
273 CHAR preserve[CCHMAXPATH], *end;
274
275 wk->li->type = IDM_MOVE;
276 strcpy(preserve, wk->li->list[0] + 2);
277 end = strrchr(preserve, '\\');
278 if (end) {
279 end++;
280 for (x = 1; wk->li->list[x]; x++) {
281 p = preserve;
282 pp = wk->li->list[x] + 2;
283 while (p < end && toupper(*p) == toupper(*pp)) {
284 p++;
285 pp++;
286 }
287 if (*p == '\\')
288 p++;
289 if (p < end)
290 end = p;
291 }
292 *end = 0;
293 }
294 else
295 *preserve = 0;
296 plen = strlen(preserve);
297 if (plen)
298 plen += 2;
299 }
300 break;
301 case IDM_COPYPRESERVE:
302 {
303 CHAR preserve[CCHMAXPATH], *end;
304
305 wk->li->type = IDM_COPY;
306 strcpy(preserve, wk->li->list[0] + 2);
307 end = strrchr(preserve, '\\');
308 if (end) {
309 end++;
310 for (x = 1; wk->li->list[x]; x++) {
311 p = preserve;
312 pp = wk->li->list[x] + 2;
313 while (p < end && toupper(*p) == toupper(*pp)) {
314 p++;
315 pp++;
316 }
317 if (*p == '\\')
318 p++;
319 if (p < end)
320 end = p;
321 }
322 *end = 0;
323 }
324 else
325 *preserve = 0;
326 plen = strlen(preserve);
327 if (plen)
328 plen += 2;
329 }
330 break;
331 }
332 // Process each list item
333 if (wk->li && wk->li->list && wk->li->list[0]) {
334 UINT cFilesModified = 0; // Required for AddToList
335 UINT cItemsAllocated = 0; // Required for AddToList
336 UINT cItemsInList;
337 for (cItemsInList = 0; wk->li->list[cItemsInList]; cItemsInList++); // Count
338 for (x = 0; wk->li->list[x]; x++) {
339 switch (wk->li->type) {
340 case IDM_COLLECTFROMFILE:
341 if (Collector) {
342
343 CHAR *temp = xstrdup(wk->li->list[x], pszSrcFile, __LINE__);
344
345 if (temp) {
346 if (!PostMsg(Collector,
347 UM_COLLECTFROMFILE, MPFROMP(temp), MPVOID))
348 free(temp);
349 }
350 }
351 break;
352
353 case IDM_MERGEBINARY:
354 case IDM_MERGETEXT:
355 case IDM_MERGEBINARYAPPEND:
356 case IDM_MERGETEXTAPPEND:
357 {
358 FILE *in, *out;
359 CHAR *moder, *modew;
360 int c;
361
362 switch (wk->li->type) {
363 case IDM_MERGEBINARY:
364 moder = "rb";
365 modew = "wb";
366 break;
367 case IDM_MERGEBINARYAPPEND:
368 moder = "rb";
369 modew = "a+b";
370 break;
371 case IDM_MERGETEXTAPPEND:
372 moder = "r";
373 modew = "a+";
374 break;
375 default:
376 moder = "r";
377 modew = "w";
378 break;
379 }
380 in = _fsopen(wk->li->list[x], moder, SH_DENYWR);
381 if (!in) {
382 if (saymsg(MB_ENTERCANCEL,
383 HWND_DESKTOP,
384 GetPString(IDS_MERGEERRORTEXT),
385 GetPString(IDS_CANTOPENINPUTTEXT),
386 wk->li->list[x]) == MBID_CANCEL)
387 goto Abort;
388 }
389 else {
390 out = _fsopen(wk->li->targetpath, modew, SH_DENYWR);
391 if (out) {
392 fseek(out, 0L, SEEK_END);
393 switch (wk->li->type) {
394 case IDM_MERGEBINARY:
395 wk->li->type = IDM_MERGEBINARYAPPEND;
396 break;
397 default:
398 wk->li->type = IDM_MERGETEXTAPPEND;
399 break;
400 }
401 sprintf(message,
402 GetPString(IDS_MERGINGTEXT),
403 wk->li->list[x], wk->li->targetpath);
404 AddNote(message);
405 while ((c = fgetc(in)) != EOF)
406 fputc(c, out);
407 fclose(out);
408 sprintf(message,
409 GetPString(IDS_MERGECOMPLETETEXT),
410 wk->li->list[x], wk->li->targetpath);
411 AddNote(message);
412 }
413 else {
414 saymsg(MB_CANCEL,
415 HWND_DESKTOP,
416 GetPString(IDS_MERGEERRORTEXT),
417 GetPString(IDS_CANTOPENOUTPUTTEXT),
418 wk->li->targetpath);
419 fclose(in);
420 goto Abort;
421 }
422 fclose(in);
423 }
424 }
425 break;
426
427 case IDM_UUDECODE:
428 {
429 CHAR outname[CCHMAXPATH + 2];
430
431 sprintf(message,
432 GetPString(IDS_UUDECODINGTEXT), wk->li->list[x]);
433 AddNote(message);
434 if (UUD(wk->li->list[x], outname) && *outname) {
435 sprintf(message,
436 GetPString(IDS_UUDECODECOMPLETETEXT),
437 wk->li->list[x]);
438 AddNote(message);
439 if (//fSyncUpdates ||
440 AddToList(outname, &files, &cFilesModified, &cItemsAllocated))
441 Broadcast(hab2,
442 wk->hwndCnr,
443 UM_UPDATERECORD, MPFROMP(outname), MPVOID);
444 }
445 else {
446 sprintf(message,
447 GetPString(IDS_UUDECODEABORTEDTEXT),
448 wk->li->list[x]);
449 AddNote(message);
450 }
451 }
452 break;
453
454 case IDM_VIEWARCHIVE:
455 if (IsFile(wk->li->list[x]) > 0) {
456
457 ARC_TYPE *info = NULL; // Say calling for editing - fixme to know why?
458
459 if (WinDlgBox(HWND_DESKTOP,
460 wk->hwndFrame,
461 SBoxDlgProc,
462 FM3ModHandle,
463 ASEL_FRAME, (PVOID) & info) && info) {
464 WinSendMsg(wk->hwndCnr,
465 UM_OPENWINDOWFORME,
466 MPFROMP(wk->li->list[x]), MPFROMP(info));
467 }
468 }
469 break;
470
471 case IDM_EXTRACT:
472 {
473 EXTRDATA ex;
474 BOOL maskspaces = FALSE;
475
476 memset(&ex, 0, sizeof(EXTRDATA));
477 ex.info = find_type(wk->li->list[x], NULL);
478 if (!ex.info || (!ex.info->extract && !ex.info->exwdirs))
479 break;
480 ex.size = sizeof(EXTRDATA);
481 ex.arcname = wk->li->list[x];
482 strcpy(ex.masks, "*");
483 strcpy(ex.extractdir, wk->li->targetpath);
484 if (!WinDlgBox(HWND_DESKTOP,
485 wk->hwndFrame,
486 ExtractDlgProc,
487 FM3ModHandle,
488 EXT_FRAME,
489 (PVOID) & ex) ||
490 !ex.ret ||
491 !*ex.command || !*ex.arcname || !*ex.extractdir)
492 goto Abort;
493 {
494 FILESTATUS3 fsa;
495
496 DosError(FERR_DISABLEHARDERR);
497 if (DosQueryPathInfo(ex.extractdir,
498 FIL_STANDARD,
499 &fsa,
500 (ULONG) sizeof(FILESTATUS3)) ||
501 !(fsa.attrFile & FILE_DIRECTORY))
502 goto Abort;
503 }
504 if (needs_quoting(ex.masks) && !strchr(ex.masks, '\"'))
505 maskspaces = TRUE;
506 if (!runemf2(SEPARATE | WINDOWED | WAIT |
507 fArcStuffVisible ? 0 : (BACKGROUND | MINIMIZED),
508 HWND_DESKTOP, pszSrcFile, __LINE__, ex.extractdir, NULL,
509 "%s %s %s%s%s",
510 ex.command,
511 ex.arcname,
512 maskspaces ? "\"" : NullStr,
513 *ex.masks ? ex.masks : "\"*\"",
514 maskspaces ? "\"" : NullStr) &&
515 !stricmp(ex.extractdir, wk->directory)) {
516 DosSleep(100); // wait for runemf2 to complete so rescan will actually show something
517 if (WinIsWindow((HAB) 0, wk->hwndCnr))
518 WinSendMsg(wk->hwndCnr,
519 WM_COMMAND,
520 MPFROM2SHORT(IDM_RESCAN, 0), MPVOID);
521 }
522 }
523 break;
524
525 case IDM_SUBJECT:
526 {
527 INT ret;
528
529 ret = Subject(wk->hwndFrame, wk->li->list[x]);
530 if (!ret)
531 goto Abort;
532 if (ret == 1) {
533 if (//fSyncUpdates ||
534 AddToList(wk->li->list[x],
535 &files, &cFilesModified, &cItemsAllocated))
536 Broadcast(hab2,
537 wk->hwndCnr,
538 UM_UPDATERECORD,
539 MPFROMP(wk->li->list[x]), MPVOID);
540 }
541 }
542 break;
543
544 case IDM_INFO:
545 if (IsFullName(wk->li->list[x]) &&
546 !(driveflags[toupper(*wk->li->list[x]) - 'A'] &
547 DRIVE_INVALID)) {
548 if (!IsRoot(wk->li->list[x])) {
549
550 CHAR *list[2];
551
552 list[0] = wk->li->list[x];
553 list[1] = NULL;
554 if (!WinDlgBox(HWND_DESKTOP,
555 HWND_DESKTOP,
556 FileInfoProc,
557 FM3ModHandle, FLE_FRAME, (PVOID) list)) {
558 goto Abort;
559 }
560 }
561 else {
562 if (!WinDlgBox(HWND_DESKTOP,
563 HWND_DESKTOP,
564 DrvInfoProc,
565 FM3ModHandle,
566 INFO_FRAME, (PVOID) wk->li->list[x]))
567 goto Abort;
568 }
569 }
570 break;
571
572 case IDM_OPENWINDOW:
573 if (!IsFile(wk->li->list[x]) &&
574 WinIsWindow(hab2, wk->hwndCnr))
575 WinSendMsg(wk->hwndCnr,
576 UM_OPENWINDOWFORME,
577 MPFROMP(wk->li->list[x]), MPVOID);
578 break;
579
580 case IDM_OPENICON:
581 case IDM_OPENDETAILS:
582 case IDM_OPENTREE:
583 {
584 FILESTATUS3 fsa;
585
586 DosError(FERR_DISABLEHARDERR);
587 if (DosQueryPathInfo(wk->li->list[x],
588 FIL_STANDARD,
589 &fsa,
590 (ULONG) sizeof(FILESTATUS3)) ||
591 !(fsa.attrFile & FILE_DIRECTORY))
592 break;
593 }
594 /* else intentional fallthru */
595 case IDM_OPENDEFAULT:
596 case IDM_OPENSETTINGS:
597 {
598 CHAR *s;
599
600 switch (wk->li->type) {
601 case IDM_OPENICON:
602 s = (PSZ) PCSZ_ICON;
603 break;
604 case IDM_OPENDETAILS:
605 s = (PSZ) Details;
606 break;
607 case IDM_OPENTREE:
608 s = (PSZ) PCSZ_TREE;
609 break;
610 case IDM_OPENSETTINGS:
611 s = (PSZ) Settings;
612 break;
613 default:
614 s = (PSZ) Default;
615 break;
616 }
617 OpenObject(wk->li->list[x], s, wk->hwndFrame);
618 }
619 break;
620
621 case IDM_WPSMOVE:
622 case IDM_WPSCOPY:
623 case IDM_MOVE:
624 case IDM_COPY:
625 case IDM_RENAME:
626 {
627
628 // Select target
629 if (!*wk->li->targetpath && (wk->li->type == IDM_MOVE ||
630 wk->li->type == IDM_COPY ||
631 wk->li->type == IDM_WPSMOVE ||
632 wk->li->type == IDM_WPSCOPY)) {
633
634 APIRET rc = 1;
635 usedtarget = FALSE;
636 if (hwndMain) {
637 if (!*targetdir)
638 TopWindowName(hwndMain,
639 wk->hwndFrame, wk->li->targetpath);
640 else {
641 strcpy(wk->li->targetpath, targetdir);
642 usedtarget = TRUE;
643 }
644 }
645 if (!*wk->li->targetpath)
646 strcpy(wk->li->targetpath, wk->directory);
647 if (!*wk->li->targetpath) {
648 strcpy(wk->li->targetpath, wk->li->list[0]);
649 p = strrchr(wk->li->targetpath, '\\');
650 if (p) {
651 if (*(p - 1) == ':')
652 p++;
653 *p = 0;
654 }
655 }
656 MakeValidDir(wk->li->targetpath);
657 if (fConfirmTarget ||
658 (!*targetdir && strcmp(realappname, "FM/4"))) {
659 RetryPath:
660 // Confirm target
661 usedtarget = FALSE;
662 if (wk->li->type == IDM_MOVE ||
663 wk->li->type == IDM_WPSMOVE) {
664 rc = WinDlgBox(HWND_DESKTOP,
665 wk->hwndFrame,
666 WalkMoveDlgProc,
667 FM3ModHandle,
668 WALK_FRAME, MPFROMP(wk->li->targetpath));
669 }
670 else if (wk->li->type == IDM_COPY ||
671 wk->li->type == IDM_WPSCOPY) {
672 rc = WinDlgBox(HWND_DESKTOP,
673 wk->hwndFrame,
674 WalkCopyDlgProc,
675 FM3ModHandle,
676 WALK_FRAME, MPFROMP(wk->li->targetpath));
677 }
678 else
679 rc = WinDlgBox(HWND_DESKTOP,
680 wk->hwndFrame,
681 WalkDlgProc,
682 FM3ModHandle,
683 WALK_FRAME, MPFROMP(wk->li->targetpath));
684 }
685 if (!rc || !*wk->li->targetpath)
686 goto Abort;
687 // Check target OK
688 if (driveflags[toupper(*wk->li->targetpath) - 'A'] &
689 DRIVE_NOTWRITEABLE) {
690 saymsg(MB_CANCEL,
691 wk->hwndFrame,
692 GetPString(IDS_ERRORTEXT),
693 GetPString(IDS_NOTWRITENOTARGETTEXT));
694 goto RetryPath;
695 }
696 }
697 Retry:
698 {
699 // Target OK so far
700 CHAR newname[CCHMAXPATH];
701 APIRET rc;
702 FILESTATUS4L fs4;
703 BOOL isnewer;
704 BOOL existed;
705 BOOL fResetVerify = FALSE;
706 INT type = wk->li->type == IDM_RENAME ?
707 MOVE :
708 wk->li->type == IDM_MOVE ?
709 MOVE : (wk->li->type == IDM_WPSMOVE) ?
710 WPSMOVE : wk->li->type == IDM_WPSCOPY ?
711 WPSCOPY : COPY;
712 PCSZ moving = wk->li->type == IDM_RENAME ?
713 GetPString(IDS_RENAMINGTEXT) :
714 wk->li->type == IDM_MOVE || wk->li->type == IDM_WPSMOVE ?
715 GetPString(IDS_MOVINGTEXT) : GetPString(IDS_COPYINGTEXT);
716 PCSZ move = wk->li->type == IDM_RENAME ?
717 GetPString(IDS_RENAMETEXT) :
718 wk->li->type == IDM_MOVE ||
719 wk->li->type == IDM_WPSMOVE ?
720 GetPString(IDS_MOVETEXT) : GetPString(IDS_COPYTEXT);
721 PCSZ moved = wk->li->type == IDM_RENAME ?
722 GetPString(IDS_RENAMEDTEXT) :
723 wk->li->type == IDM_MOVE || wk->li->type == IDM_WPSMOVE ?
724 GetPString(IDS_MOVEDTEXT) : GetPString(IDS_COPIEDTEXT);
725
726 if (*wk->li->targetpath) {
727 strcpy(newname, wk->li->targetpath);
728 AddBackslashToPath(newname);
729 if (plen)
730 p = wk->li->list[x] + plen;
731 else {
732 p = strrchr(wk->li->list[x], '\\');
733 if (p)
734 p++;
735 else
736 p = wk->li->list[x];
737 }
738 strcat(newname, p);
739 }
740 else
741 strcpy(newname, wk->li->list[x]);
742 if ((wildcarding || wk->li->type == IDM_RENAME) &&
743 *wildname)
744 {
745 CHAR testname[CCHMAXPATH];
746 strcpy(testname, wildname);
747 if (AdjustWildcardName(newname, testname))
748 strcpy(newname, testname);
749 }
750 existed = IsFile(newname) != -1;
751 isnewer = IsNewer(wk->li->list[x], newname);
752 if (existed && wk->li->type != IDM_RENAME && dontask) {
753 if (!overold && !overnew)
754 break;
755 if (!overold && !isnewer)
756 break;
757 if (!overnew && isnewer)
758 break;
759 }
760 // Confirm overwrite unless bypassed
761 if ((wk->li->type == IDM_RENAME &&
762 (!dontask || !*wildname)) ||
763 (!dontask && existed) ||
764 (!dontask && wildcarding) ||
765 (IsFile(newname) == 0 && IsFile(wk->li->list[x]) > 0))
766 {
767 MOVEIT mv;
768 memset(&mv, 0, sizeof(MOVEIT));
769 mv.rename = (wk->li->type == IDM_RENAME);
770 mv.source = wk->li->list[x];
771 strcpy(mv.target, newname);
772 rc = WinDlgBox(HWND_DESKTOP,
773 wk->hwndFrame,
774 RenameProc,
775 FM3ModHandle, REN_FRAME, (PVOID) & mv);
776 if (!rc)
777 goto Abort;
778
779 DosSleep(1);
780 if (mv.skip || !*mv.target)
781 break;
782 if (mv.dontask)
783 dontask = TRUE;
784 if (mv.overold)
785 overold = TRUE;
786 if (mv.overnew)
787 overnew = TRUE;
788 if (wildcarding || wk->li->type == IDM_RENAME) {
789 p = strrchr(mv.target, '\\');
790 if (p && (strchr(p, '*') || strchr(p, '?'))) {
791 strcpy(wildname, mv.target);
792 AdjustWildcardName(wk->li->list[x], mv.target);
793 }
794 else
795 *wildname = 0;
796 }
797 strcpy(newname, mv.target);
798 existed = (IsFile(newname) != -1);
799 isnewer = IsNewer(wk->li->list[x], newname);
800 if (!mv.overwrite) {
801 if (existed && wk->li->type != IDM_RENAME && dontask) {
802 if (!overold && !overnew)
803 break;
804 if (!overold && !isnewer)
805 break;
806 if (!overnew && isnewer)
807 break;
808 }
809 }
810 }
811 if (!strcmp(wk->li->list[x], newname) ||
812 (wk->li->type == IDM_COPY &&
813 !stricmp(wk->li->list[x], newname)))
814 break;
815 sprintf(message,
816 " %s \"%s\" %s\"%s\"%s [%u %s%u]",
817 moving,
818 wk->li->list[x],
819 GetPString(IDS_TOTEXT), // Has trailing space
820 newname,
821 usedtarget ?
822 GetPString(IDS_TOTARGETTEXT) :
823 NullStr,
824 x + 1,
825 GetPString(IDS_OFTEXT), // Has trailing space
826 cItemsInList);
827 AddNote(message);
828 if (fVerify && (driveflags[toupper(*wk->li->targetpath) - 'A'] & DRIVE_WRITEVERIFYOFF) |
829 (driveflags[toupper(*wk->li->list[x]) - 'A'] & DRIVE_WRITEVERIFYOFF)) {
830 DosSetVerify(FALSE);
831 fResetVerify = TRUE;
832 }
833 if (plen) {
834 /* make directory/ies, if required */
835
836 CHAR dirpart[CCHMAXPATH];
837
838 strcpy(dirpart, newname);
839 p = strrchr(dirpart, '\\');
840 if (p) {
841 *p = 0;
842 if (p > dirpart + 3)
843 MassMkdir((hwndMain) ? hwndMain : wk->hwndCnr,
844 dirpart);
845 }
846 }
847 if (fRealIdle)
848 priority_idle();
849
850 rc = docopyf(type, wk->li->list[x], newname);
851 if (fResetVerify) {
852 DosSetVerify(fVerify);
853 fResetVerify = FALSE;
854 }
855 priority_normal();
856 if (rc) {
857 if ((rc == ERROR_DISK_FULL ||
858 rc == ERROR_HANDLE_DISK_FULL) &&
859 isalpha(*newname) &&
860 (driveflags[toupper(*newname) - 'A'] &
861 DRIVE_REMOVABLE)
862 && !(driveflags[toupper(*newname) - 'A'] &
863 DRIVE_NOTWRITEABLE)
864 && toupper(*newname) != toupper(*wk->li->list[x])
865 && !DosQueryPathInfo(wk->li->list[x], FIL_QUERYEASIZEL,
866 &fs4, sizeof(fs4))
867 && !(fs4.attrFile & FILE_DIRECTORY)) {
868
869 FSALLOCATE fsa;
870 ULONGLONG ullFreeBytes;
871 CHAR *ptr;
872 INT cntr;
873
874 Notify(GetPString(IDS_FITTINGTEXT));
875 DosError(FERR_DISABLEHARDERR);
876 if (!DosQueryFSInfo(toupper(*newname) - '@',
877 FSIL_ALLOC,
878 &fsa, sizeof(FSALLOCATE))) {
879 // Assume large file support
880 ullFreeBytes = (ULONGLONG) fsa.cUnitAvail * fsa.cSectorUnit *
881 fsa.cbSector;
882 if (ullFreeBytes) {
883 // Find item that will fit in available space
884 for (cntr = x + 1; wk->li->list[cntr]; cntr++) {
885 DosError(FERR_DISABLEHARDERR);
886 if (!DosQueryPathInfo(wk->li->list[cntr],
887 FIL_QUERYEASIZEL,
888 &fs4,
889 sizeof(fs4)) &&
890 !(fs4.attrFile & FILE_DIRECTORY) &&
891 // fixme to use CBLIST_TO_EASIZE?
892 fs4.cbFile + fs4.cbList <= ullFreeBytes) {
893 // Swap with failing item
894 ptr = wk->li->list[x];
895 wk->li->list[x] = wk->li->list[cntr];
896 wk->li->list[cntr] = ptr;
897 goto Retry;
898 }
899 }
900 Notify(GetPString(IDS_COULDNTFITTEXT));
901 }
902 }
903 rc = saymsg(MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION,
904 wk->hwndFrame,
905 GetPString(IDS_DISKFULLTEXT),
906 GetPString(IDS_ANOTHERDISKTEXT));
907 if (rc == MBID_RETRY)
908 goto Retry;
909 if (rc == MBID_ABORT)
910 goto Abort;
911 }
912 else {
913 if (LogFileHandle) {
914 fprintf(LogFileHandle,
915 GetPString(IDS_LOGTOFAILEDTEXT),
916 move, wk->li->list[x], newname, rc);
917 }
918 rc = Dos_Error(MB_ENTERCANCEL,
919 rc,
920 wk->hwndFrame,
921 pszSrcFile,
922 __LINE__,
923 "%s %s\"%s\" %s\"%s\" %s.",
924 move,
925 GetPString(IDS_OFTEXT), // Has trailing space
926 wk->li->list[x],
927 GetPString(IDS_TOTEXT),
928 newname, GetPString(IDS_FAILEDTEXT));
929 if (rc == MBID_CANCEL)
930 goto Abort;
931 }
932 }
933 else {
934 if (LogFileHandle) {
935 fprintf(LogFileHandle,
936 "%s \"%s\" %s\"%s\"\n",
937 moved,
938 wk->li->list[x],
939 GetPString(IDS_TOTEXT), newname);
940 }
941 if (!strcmp(realappname, "FM/4") ||
942 ((driveflags[*wk->li->targetpath - 'A'] & DRIVE_RSCANNED) &&
943 AddToList(wk->li->list[x],
944 &files, &cFilesModified, &cItemsAllocated)))
945 Broadcast(hab2,
946 wk->hwndCnr,
947 UM_UPDATERECORD,
948 MPFROMP(wk->li->list[x]), MPVOID);
949 if (!strcmp(realappname, "FM/4") ||
950 (driveflags[*wk->li->targetpath - 'A'] & DRIVE_RSCANNED) &&
951 AddToList(newname, &files, &cFilesModified, &cItemsAllocated))
952 Broadcast(hab2,
953 wk->hwndCnr,
954 UM_UPDATERECORD, MPFROMP(newname), MPVOID);
955 }
956 }
957 break;
958 }
959
960 case IDM_COMPARE:
961 if ((!IsFile(wk->li->targetpath) ||
962 IsRoot(wk->li->targetpath)) &&
963 (!IsFile(wk->li->list[x]) || IsRoot(wk->li->list[x]))) {
964 if (!*dircompare && WinIsWindow(hab2, wk->hwndCnr))
965 WinSendMsg(wk->hwndCnr,
966 UM_COMPARE,
967 MPFROMP(wk->li->targetpath),
968 MPFROMP(wk->li->list[x]));
969 else {
970 runemf2(SEPARATE,
971 HWND_DESKTOP, pszSrcFile, __LINE__,
972 NULL, NULL,
973 "%s %s %s",
974 dircompare,
975 BldQuotedFileName(szQuotedDirName, wk->li->targetpath),
976 BldQuotedFileName(szQuotedFileName, wk->li->list[x]));
977 }
978 }
979 else if (*compare) {
980 CHAR *fakelist[3];
981
982 fakelist[0] = wk->li->list[x];
983 fakelist[1] = wk->li->targetpath;
984 fakelist[2] = NULL;
985 ExecOnList(wk->hwndFrame,
986 compare,
987 WINDOWED | SEPARATEKEEP, NULL, NULL, fakelist, NULL,
988 pszSrcFile, __LINE__);
989 }
990 else {
991 FCOMPARE fc;
992
993 memset(&fc, 0, sizeof(fc));
994 fc.size = sizeof(fc);
995 fc.hwndParent = wk->hwndParent;
996 strcpy(fc.file1, wk->li->list[x]);
997 strcpy(fc.file2, wk->li->targetpath);
998 if (WinDlgBox(HWND_DESKTOP,
999 wk->hwndFrame,
1000 CFileDlgProc,
1001 FM3ModHandle, FCMP_FRAME, (PVOID) & fc))
1002 goto Abort;
1003 }
1004 break;
1005 } // switch
1006 DosSleep(0);
1007 } // for list
1008
1009 // Do action specific post-processing
1010 switch (wk->li->type) {
1011 case IDM_MOVE:
1012 case IDM_COPY:
1013 case IDM_WPSMOVE:
1014 case IDM_WPSCOPY:
1015 case IDM_RENAME:
1016 sprintf(message,
1017 GetPString(IDS_OPSCOMPLETETEXT),
1018 wk->li->type == IDM_MOVE ?
1019 GetPString(IDS_MOVETEXT) :
1020 wk->li->type == IDM_COPY ?
1021 GetPString(IDS_COPYTEXT) :
1022 wk->li->type == IDM_WPSMOVE ?
1023 GetPString(IDS_WPSMOVETEXT) :
1024 wk->li->type == IDM_WPSCOPY ?
1025 GetPString(IDS_WPSCOPYTEXT) :
1026 GetPString(IDS_RENAMETEXT),
1027 &"s"[x == 1], /* s or nul */
1028 (wk->li->type == IDM_MOVE ||
1029 wk->li->type == IDM_COPY ||
1030 wk->li->type == IDM_WPSMOVE ||
1031 wk->li->type == IDM_WPSCOPY) ?
1032 GetPString(IDS_TOTEXT) : NullStr,
1033 (wk->li->type == IDM_MOVE ||
1034 wk->li->type == IDM_COPY ||
1035 wk->li->type == IDM_WPSMOVE ||
1036 wk->li->type == IDM_WPSCOPY) ?
1037 wk->li->targetpath : NullStr,
1038 GetPString(x != 1 ? IDS_ARETEXT : IDS_ISTEXT));
1039 Notify(message);
1040 if (toupper(*wk->li->targetpath) < 'C' && !fAlertBeepOff)
1041 DosBeep(1000, 25); // Wake up user
1042 DosSleep(16);//05 Aug 07 GKY 33
1043 if (wk->li->type == IDM_WPSMOVE || wk->li->type == IDM_WPSCOPY)
1044 DosSleep(48);//05 Aug 07 GKY 96
1045 break;
1046 default:
1047 break;
1048 }
1049 } // if have non-empty list
1050
1051 Abort:
1052
1053 if (files) {
1054 if (!strcmp(realappname, "FM/4") || !hwndTree ||
1055 (driveflags[*wk->li->targetpath - 'A'] & DRIVE_RSCANNED))
1056 Broadcast(hab2,
1057 wk->hwndCnr,
1058 UM_UPDATERECORDLIST, MPFROMP(files), MPVOID);
1059 FreeList(files);
1060 }
1061
1062 if (WinIsWindow(hab2, wk->hwndCnr))
1063 PostMsg(wk->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
1064
1065 WinDestroyMsgQueue(hmq2);
1066 } // if queue
1067 DecrThreadUsage();
1068 WinTerminate(hab2);
1069 } // if hab2
1070 } // if list not empty
1071
1072 if (wk->li)
1073 FreeListInfo(wk->li);
1074 free(wk);
1075# ifdef FORTIFY
1076 Fortify_LeaveScope();
1077# endif
1078 DosPostEventSem(CompactSem);
1079 }
1080}
1081
1082/**
1083 * Apply file list to action
1084 * All items in list processed as a group, if possible
1085 */
1086
1087VOID MassAction(VOID * args)
1088{
1089 WORKER *wk = (WORKER *) args;
1090 HAB hab2;
1091 HMQ hmq2;
1092 CHAR **files = NULL;
1093 CHAR *p, *pp;
1094 UINT numfiles = 0, numalloc = 0;
1095
1096
1097 if (wk) {
1098# ifdef FORTIFY
1099 // Fortify_BecomeOwner(wk);
1100 Fortify_EnterScope();
1101# endif
1102 if (wk->li && wk->li->list && wk->li->list[0]) {
1103 hab2 = WinInitialize(0);
1104 if (hab2) {
1105 hmq2 = WinCreateMsgQueue(hab2, 0);
1106 if (hmq2) {
1107 WinCancelShutdown(hmq2, TRUE);
1108 IncrThreadUsage();
1109 DosError(FERR_DISABLEHARDERR);
1110 if (IsRoot(wk->li->list[0]) || !IsFile(wk->li->list[0])) {
1111 if (wk->li->type == IDM_VIEW)
1112 wk->li->type = IDM_INFO;
1113 if (wk->li->type == IDM_EDIT)
1114 wk->li->type = IDM_EAS;
1115 }
1116 switch (wk->li->type) {
1117 case IDM_INFO:
1118 if (WinDlgBox(HWND_DESKTOP,
1119 wk->hwndFrame,
1120 FileInfoProc,
1121 FM3ModHandle, FLE_FRAME, (PVOID) wk->li->list) != 2)
1122 {
1123 break;
1124 }
1125 /* else intentional fallthru */
1126 case IDM_UPDATE:
1127 Broadcast(hab2,
1128 wk->hwndCnr,
1129 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1130 break;
1131
1132 case IDM_EAS:
1133 if (WinDlgBox(HWND_DESKTOP,
1134 wk->hwndFrame,
1135 DisplayEAsProc,
1136 FM3ModHandle, EA_FRAME, (PVOID) wk->li->list))
1137 Broadcast(hab2,
1138 wk->hwndCnr,
1139 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1140 break;
1141
1142 case IDM_DOITYOURSELF:
1143 ExecOnList(wk->hwndFrame,
1144 "%a",
1145 WINDOWED | SEPARATE | PROMPT, NULL,
1146 NULL, wk->li->list, GetPString(IDS_DOITYOURSELFTEXT),
1147 pszSrcFile, __LINE__);
1148 break;
1149
1150 case IDM_MCIPLAY:
1151 {
1152 UINT x;
1153 UINT MaxFM2playStrLen = 24;
1154 ULONG total;
1155 CHAR fbuf[CCHMAXPATH];
1156
1157 if (DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT |
1158 SEARCH_CUR_DIRECTORY,
1159 (CHAR *) PCSZ_PATH, (CHAR *) PCSZ_FM2PLAYEXE, (PBYTE)fbuf, CCHMAXPATH - 1))
1160 total += MaxFM2playStrLen;
1161 else
1162 total = strlen(fbuf);
1163 for (x = 0; wk->li->list[x]; x++)
1164 total += (strlen(wk->li->list[x]) + 1 +
1165 (needs_quoting(wk->li->list[x]) * 2));
1166 if (total > 1000) {
1167
1168 FILE *fp;
1169 CHAR szTempFile[CCHMAXPATH];
1170
1171 BldFullPathName(szTempFile, pTmpDir, PCSZ_FM2PLAYTEMP);
1172 fp = xfopen(szTempFile, "w", pszSrcFile, __LINE__);
1173 if (fp) {
1174 fprintf(fp, "%s", ";AV/2-built FM2Play listfile\n");
1175 for (x = 0; wk->li->list[x]; x++)
1176 fprintf(fp, "%s\n", wk->li->list[x]);
1177 fprintf(fp, ";end\n");
1178 fclose(fp);
1179 strrev(szTempFile);
1180 strcat(szTempFile, "@/");
1181 strrev(szTempFile);
1182 RunFM2Util(PCSZ_FM2PLAYEXE, szTempFile);
1183 }
1184 }
1185 }
1186 /* intentional fallthru */
1187 case IDM_FAKEEXTRACT:
1188 case IDM_FAKEEXTRACTM:
1189 if (wk->li->type == IDM_MCIPLAY ||
1190 (*wk->li->arcname && wk->li->info &&
1191 wk->li->info->extract && *wk->li->targetpath)) {
1192
1193 CHAR szBuffer[1025];
1194 CHAR fbuf[CCHMAXPATH];
1195 UINT x;
1196
1197 if (wk->li->type == IDM_FAKEEXTRACT ||
1198 wk->li->type == IDM_FAKEEXTRACTM) {
1199 strcpy(szBuffer,
1200 (wk->li->info->exwdirs) ?
1201 wk->li->info->exwdirs : wk->li->info->extract);
1202 strcat(szBuffer, " ");
1203 BldQuotedFileName(szBuffer + strlen(szBuffer), wk->li->arcname);
1204 }
1205 else {
1206 if (DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT |
1207 SEARCH_CUR_DIRECTORY,
1208 (CHAR *) PCSZ_PATH, (CHAR *) PCSZ_FM2PLAYEXE, (PBYTE)fbuf, CCHMAXPATH - 1))
1209 strcpy(szBuffer, "UTILS\\FM2PLAY.EXE");
1210 else
1211 strcpy(szBuffer, PCSZ_FM2PLAYEXE);
1212 }
1213 p = &szBuffer[strlen(szBuffer)];
1214 strcat(szBuffer, " ");
1215 x = 0;
1216 while (wk->li->list[x]) {
1217 pp = wk->li->list[x];
1218 while (*pp) {
1219 if (*pp == '/')
1220 *pp = '\\';
1221 pp++;
1222 }
1223 BldQuotedFileName(szBuffer + strlen(szBuffer), wk->li->list[x]);
1224 x++;
1225 if (!wk->li->list[x] || strlen(szBuffer) +
1226 strlen(wk->li->list[x]) + 5 > 1024) {
1227 runemf2(SEPARATE | WINDOWED | BACKGROUND | MINIMIZED | WAIT,
1228 HWND_DESKTOP, pszSrcFile, __LINE__,
1229 (wk->li->type == IDM_FAKEEXTRACT ||
1230 wk->li->type == IDM_FAKEEXTRACTM) ?
1231 wk->li->targetpath : NULL,
1232 NULL,
1233 "%s", szBuffer);
1234 DosSleep(1);
1235 *p = 0;
1236 }
1237 strcat(szBuffer, " ");
1238 }
1239 if (wk->li->type == IDM_MCIPLAY)
1240 break;
1241 strcpy(szBuffer, wk->li->targetpath);
1242 AddBackslashToPath(wk->li->targetpath);
1243 //if (wk->li->targetpath[strlen(wk->li->targetpath) - 1] != '\\')
1244 // strcat(szBuffer, "\\");
1245 p = szBuffer + strlen(szBuffer);
1246 for (x = 0; wk->li->list[x]; x++) {
1247 strcpy(p, wk->li->list[x]);
1248 free(wk->li->list[x]);
1249 wk->li->list[x] = xstrdup(szBuffer, pszSrcFile, __LINE__);
1250 }
1251 if (wk->li->list[0])
1252 Broadcast(hab2,
1253 wk->hwndCnr,
1254 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1255 }
1256 break;
1257
1258 case IDM_SETICON:
1259 if (*wk->li->targetpath) {
1260
1261 ICONINFO ici;
1262
1263 memset(&ici, 0, sizeof(ICONINFO));
1264 ici.cb = sizeof(ICONINFO);
1265 ici.fFormat = ICON_FILE;
1266 ici.pszFileName = wk->li->list[0];
1267 if (!WinSetFileIcon((PSZ) wk->li->targetpath,
1268 (PICONINFO) & ici)) {
1269 ici.fFormat = ICON_CLEAR;
1270 WinSetFileIcon((PSZ) wk->li->targetpath, (PICONINFO) & ici);
1271 }
1272 Broadcast(hab2,
1273 wk->hwndCnr,
1274 UM_UPDATERECORD, MPFROMP(wk->li->targetpath), MPVOID);
1275 }
1276 break;
1277
1278 case IDM_APPENDTOCLIP:
1279 case IDM_SAVETOCLIP:
1280 case IDM_SAVETOCLIPFILENAME:
1281 case IDM_APPENDTOCLIPFILENAME:
1282 ListToClipboardHab(hab2,
1283 wk->li->list,
1284 wk->li->type);
1285 break;
1286
1287 case IDM_ARCHIVEM:
1288 case IDM_ARCHIVE:
1289 {
1290 DIRCNRDATA ad;
1291 CHAR szBuffer[1025];
1292 ARC_TYPE *info = NULL;
1293 char *pch;
1294 UINT x;
1295
1296 memset(&ad, 0, sizeof(DIRCNRDATA));
1297 strcpy(ad.arcname, wk->li->targetpath);
1298 if (*wk->li->targetpath && IsFile(wk->li->targetpath) > 0) {
1299 info = find_type(wk->li->targetpath, NULL);
1300 ad.namecanchange = 0;
1301 }
1302 else {
1303 if (*wk->li->targetpath && !IsFile(wk->li->targetpath))
1304 AddBackslashToPath(wk->li->targetpath);
1305 //if (wk->li->targetpath[strlen(wk->li->targetpath) - 1] !=
1306 // '\\')
1307 // strcat(wk->li->targetpath, "\\");
1308 ad.namecanchange = 1;
1309 }
1310 strcpy(ad.arcname, wk->li->targetpath);
1311 if (wk->li->type == IDM_ARCHIVEM)
1312 ad.fmoving = TRUE;
1313 if (!info) {
1314 ad.info = arcsighead; // Hide dups
1315 if (!WinDlgBox(HWND_DESKTOP,
1316 wk->hwndFrame,
1317 SBoxDlgProc,
1318 FM3ModHandle,
1319 ASEL_FRAME, (PVOID) & ad.info) || !ad.info) {
1320 break; /* we blew it */
1321 }
1322 }
1323 else
1324 ad.info = info;
1325 if (!ad.info || (!ad.info->create &&
1326 !ad.info->move &&
1327 !ad.info->createwdirs &&
1328 !ad.info->movewdirs &&
1329 !ad.info->createrecurse))
1330 break;
1331 if (!*wk->li->targetpath && *wk->directory) {
1332 strcpy(ad.arcname, wk->directory);
1333 AddBackslashToPath(ad.arcname);
1334 //if (ad.arcname[strlen(ad.arcname) - 1] != '\\')
1335 // strcat(ad.arcname, "\\");
1336 }
1337 if (!WinDlgBox(HWND_DESKTOP, wk->hwndFrame, ArchiveDlgProc, FM3ModHandle,
1338 ARCH_FRAME, (PVOID) & ad) || !*ad.arcname || !*ad.command) /* we blew it */
1339 break;
1340 // Provide extension so containers work
1341 pch = strrchr(ad.arcname, '\\');
1342 if (pch)
1343 pch = strrchr(pch, '.');
1344 else
1345 pch = strrchr(ad.arcname, '.');
1346 if (!pch && ad.info->ext) {
1347 strcat(ad.arcname, ".");
1348 strcat(ad.arcname, ad.info->ext);
1349 }
1350 /* build the sucker */
1351 strcpy(szBuffer, ad.command);
1352 strcat(szBuffer, " ");
1353 BldQuotedFileName(szBuffer + strlen(szBuffer), ad.arcname);
1354 p = &szBuffer[strlen(szBuffer)];
1355 if (ad.mask.szMask) {
1356 strcat(szBuffer, " ");
1357 strcat(szBuffer, ad.mask.szMask);
1358 }
1359 strcat(szBuffer, " ");
1360 x = 0;
1361 while (wk->li->list[x]) {
1362 FILESTATUS3 fsa;
1363 memset(&fsa, 0, sizeof(FILESTATUS3));
1364 DosError(FERR_DISABLEHARDERR);
1365 DosQueryPathInfo(wk->li->list[x],
1366 FIL_STANDARD,
1367 &fsa, (ULONG) sizeof(FILESTATUS3));
1368 if (fsa.attrFile & FILE_DIRECTORY) {
1369 BldQuotedFullPathName(szBuffer + strlen(szBuffer), wk->li->list[x], "*");
1370 }
1371 else
1372 BldQuotedFileName(szBuffer + strlen(szBuffer), wk->li->list[x]);
1373 x++;
1374 if (!wk->li->list[x] ||
1375 strlen(szBuffer) + strlen(wk->li->list[x]) + 5 > 1024) {
1376 runemf2(SEPARATE | WINDOWED | WAIT |
1377 (fArcStuffVisible ? 0 : (BACKGROUND | MINIMIZED)),
1378 HWND_DESKTOP, pszSrcFile, __LINE__, NULL, NULL,
1379 "%s", szBuffer);
1380 DosSleep(1);
1381 *p = 0;
1382 }
1383 strcat(szBuffer, " ");
1384 }
1385 Broadcast(hab2,
1386 wk->hwndCnr,
1387 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1388 Broadcast(hab2,
1389 wk->hwndCnr,
1390 UM_UPDATERECORD, MPFROMP(ad.arcname), MPVOID);
1391 }
1392 break;
1393
1394 case IDM_VIEW:
1395 if (!TestBinary(wk->li->list[0])) {
1396 wk->li->type = IDM_VIEWTEXT;
1397 goto SkipViewing;
1398 }
1399 else
1400 wk->li->type = IDM_VIEWBINARY;
1401 /* intentional fallthru */
1402 case IDM_VIEWBINARY:
1403 if (*binview) {
1404 ExecOnList((HWND) 0,
1405 binview,
1406 WINDOWED | SEPARATE, NULL, NULL, wk->li->list, NULL,
1407 pszSrcFile, __LINE__);
1408 break;
1409 }
1410 /* else intentional fallthru */
1411 case IDM_VIEWTEXT:
1412 SkipViewing:
1413 if (*viewer)
1414 ExecOnList((HWND) 0, viewer,
1415 WINDOWED | SEPARATE |
1416 ((fViewChild) ? CHILD : 0),
1417 NULL, NULL, wk->li->list, NULL,
1418 pszSrcFile, __LINE__);
1419 else {
1420
1421 CHAR *temp;
1422 UINT x;
1423 ULONG viewtype;
1424
1425 viewtype = (wk->li->type == IDM_VIEWTEXT) ? 8 :
1426 (wk->li->type == IDM_VIEWBINARY) ? 16 : 0;
1427 for (x = 0; wk->li->list[x]; x++) {
1428 temp = xstrdup(wk->li->list[x], pszSrcFile, __LINE__);
1429 if (temp && WinIsWindow(hab2, wk->hwndCnr)) {
1430 if (!PostMsg(wk->hwndCnr,
1431 UM_LOADFILE,
1432 MPFROMLONG(5 + viewtype), MPFROMP(temp)))
1433 free(temp);
1434 }
1435 DosSleep(1);
1436 }
1437 }
1438 break;
1439
1440 case IDM_EDIT:
1441 if (!TestBinary(wk->li->list[0])) {
1442 wk->li->type = IDM_EDITTEXT;
1443 goto SkipEditing;
1444 }
1445 else
1446 wk->li->type = IDM_EDITBINARY;
1447 /* intentional fallthru */
1448 case IDM_EDITBINARY:
1449 if (*bined) {
1450 ExecOnList((HWND) 0,
1451 bined,
1452 WINDOWED | SEPARATE, NULL, NULL, wk->li->list, NULL,
1453 pszSrcFile, __LINE__);
1454 break;
1455 }
1456 /* else intentional fallthru */
1457 case IDM_EDITTEXT:
1458 SkipEditing:
1459 if (*editor)
1460 ExecOnList((HWND) 0,
1461 editor,
1462 WINDOWED | SEPARATE, NULL, NULL, wk->li->list, NULL,
1463 pszSrcFile, __LINE__);
1464 else {
1465
1466 CHAR *temp;
1467 UINT x;
1468 ULONG viewtype;
1469
1470 viewtype = (wk->li->type == IDM_EDITTEXT) ? 8 :
1471 (wk->li->type == IDM_EDITBINARY) ? 16 : 0;
1472 for (x = 0; wk->li->list[x]; x++) {
1473 temp = xstrdup(wk->li->list[x], pszSrcFile, __LINE__);
1474 if (temp && WinIsWindow(hab2, wk->hwndCnr)) {
1475 if (!PostMsg(wk->hwndCnr,
1476 UM_LOADFILE,
1477 MPFROMLONG(4 + viewtype), MPFROMP(temp)))
1478 free(temp);
1479 }
1480 DosSleep(1);
1481 }
1482 }
1483 break;
1484
1485 case IDM_SHADOW2:
1486 case IDM_OBJECT:
1487 case IDM_SHADOW:
1488 {
1489 CHAR objectpath[CCHMAXPATH];
1490 APIRET rc;
1491
1492 if (!*wk->li->targetpath || IsFile(wk->li->targetpath)) {
1493 GetDesktopName(objectpath, sizeof(objectpath));
1494 rc = WinDlgBox(HWND_DESKTOP,
1495 wk->hwndFrame,
1496 ObjCnrDlgProc,
1497 FM3ModHandle,
1498 OBJCNR_FRAME, MPFROMP(objectpath));
1499 if (rc) {
1500 if (rc > 1)
1501 strcpy(objectpath, "<WP_DESKTOP>");
1502 }
1503 else
1504 break;
1505 }
1506 else
1507 strcpy(objectpath, wk->li->targetpath);
1508 AddNote(GetPString(IDS_MAKINGOBJSTEXT));
1509 MakeShadows(wk->hwndFrame,
1510 wk->li->list,
1511 (wk->li->type == IDM_SHADOW) +
1512 (wk->li->type == IDM_SHADOW2) * 2,
1513 objectpath, NULL);
1514 AddNote(GetPString(IDS_MADEOBJSTEXT));
1515 }
1516 break;
1517
1518 case IDM_PRINT:
1519 if (WinDlgBox(HWND_DESKTOP,
1520 wk->hwndFrame,
1521 PrintDlgProc,
1522 FM3ModHandle, PRN_FRAME, MPFROMP(wk->li))) {
1523 if (wk->li && wk->li->list && wk->li->list[0]) {
1524 strcpy(wk->li->targetpath, printer);
1525 if (xbeginthread(PrintListThread,
1526 65536,
1527 wk->li,
1528 pszSrcFile,
1529 __LINE__) != -1)
1530 {
1531 wk->li = NULL; // prevent LISTINFO li from being freed here
1532 }
1533 }
1534 }
1535 break;
1536
1537 case IDM_ATTRS:
1538 if (WinDlgBox(HWND_DESKTOP,
1539 wk->hwndFrame,
1540 AttrListDlgProc,
1541 FM3ModHandle, ATR_FRAME, MPFROMP(wk->li))) {
1542 if (wk->li && wk->li->list && wk->li->list[0])
1543 Broadcast(hab2,
1544 wk->hwndCnr,
1545 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1546 }
1547 break;
1548
1549 case IDM_PERMDELETE:
1550 case IDM_DELETE:
1551 {
1552 CHECKLIST cl;
1553 INT isdir = 0, sysdir = 0, ro = 0, hs = 0;
1554 UINT x;
1555 FILESTATUS3 fsa;
1556 CHAR prompt[CCHMAXPATH * 3];
1557 APIRET error = 0;
1558 HOBJECT hObjectdest, hObjectofObject;
1559 BYTE G_abSupportedDrives[24] = {0};
1560 ULONG cbSupportedDrives = sizeof(G_abSupportedDrives);
1561
1562 for (x = 0; wk->li->list[x]; x++) {
1563 if (IsRoot(wk->li->list[x])) {
1564 wk->li->list = RemoveFromList(wk->li->list,
1565 wk->li->list[x]);
1566 if (!wk->li->list)
1567 break;
1568 x--;
1569 continue;
1570 }
1571 DosError(FERR_DISABLEHARDERR);
1572 if (DosQueryPathInfo(wk->li->list[x],
1573 FIL_STANDARD, &fsa,
1574 (ULONG) sizeof(FILESTATUS3))) {
1575 wk->li->list = RemoveFromList(wk->li->list,
1576 wk->li->list[x]);
1577 if (!wk->li->list)
1578 break;
1579 x--;
1580 continue;
1581 }
1582 if (fsa.attrFile & FILE_DIRECTORY) {
1583 isdir++;
1584 if (stristr(wk->li->list[x], ":\\OS2\\") ||
1585 !stricmp(wk->li->list[x] + 1, ":\\OS2"))
1586 sysdir++;
1587 }
1588 else {
1589 if (fsa.attrFile & (FILE_HIDDEN | FILE_SYSTEM))
1590 hs++;
1591 if (fsa.attrFile & FILE_READONLY)
1592 ro++;
1593 }
1594 }
1595 if (!wk->li->list)
1596 break;
1597 if (fConfirmDelete || isdir || hs || ro) {
1598 memset(&cl, 0, sizeof(cl));
1599 cl.size = sizeof(cl);
1600 cl.list = wk->li->list;
1601 cl.prompt = prompt;
1602 cl.flags |= CHECK_FILES;
1603 cl.cmd = wk->li->type;
1604 sprintf(prompt,
1605 GetPString(IDS_DELPROMPT1TEXT),
1606 (wk->li->type == IDM_DELETE) ?
1607 NullStr :
1608 GetPString(IDS_PERMANENTLYTEXT),
1609 &"s"[wk->li->list[1] == NULL]);
1610 if (isdir) {
1611 sprintf(&prompt[strlen(prompt)],
1612 GetPString(IDS_DELPROMPT2TEXT),
1613 isdir,
1614 (isdir > 1) ?
1615 GetPString(IDS_ARETEXT) :
1616 GetPString(IDS_ISTEXT),
1617 (isdir == 1) ?
1618 GetPString(IDS_ATEXT) :
1619 NullStr,
1620 (isdir > 1) ?
1621 GetPString(IDS_IESTEXT) : GetPString(IDS_YTEXT));
1622 if (sysdir)
1623 sprintf(&prompt[strlen(prompt)],
1624 GetPString(IDS_DELPROMPT3TEXT),
1625 sysdir,
1626 (sysdir == 1) ?
1627 GetPString(IDS_YTEXT) : GetPString(IDS_IESTEXT));
1628 }
1629 if (ro)
1630 sprintf(&prompt[strlen(prompt)],
1631 GetPString(IDS_DELPROMPT4TEXT),
1632 ro,
1633 &"s"[ro == 1],
1634 (ro > 1) ?
1635 GetPString(IDS_ARETEXT) : GetPString(IDS_ISTEXT));
1636 if (hs)
1637 sprintf(&prompt[strlen(prompt)],
1638 GetPString(IDS_DELPROMPT5TEXT),
1639 hs,
1640 &"s"[hs == 1],
1641 (hs > 1) ?
1642 GetPString(IDS_ARETEXT) : GetPString(IDS_ISTEXT));
1643 if ((ro || hs || sysdir) && !fAlertBeepOff)
1644 DosBeep(300, 100); // Wake up user
1645 strcat(prompt, GetPString(IDS_DELPROMPT6TEXT));
1646 error = WinDlgBox(HWND_DESKTOP,
1647 wk->hwndFrame,
1648 CheckListProc,
1649 FM3ModHandle, CHECK_FRAME, MPFROMP(&cl));
1650 if (!error || error == 65535)
1651 break;
1652 wk->li->list = cl.list;
1653 if (!wk->li->list || !wk->li->list[0])
1654 break;
1655 }
1656 if (fVerify && driveflags[toupper(*wk->li->list[0]) - 'A'] & DRIVE_WRITEVERIFYOFF)
1657 DosSetVerify(FALSE);
1658 DosRequestMutexSem(hmtxFM2Delete, SEM_INDEFINITE_WAIT); // Prevent race 12-3-08 GKY
1659 for (x = 0; wk->li->list[x]; x++) {
1660 fsa.attrFile = 0;
1661 DosError(FERR_DISABLEHARDERR);
1662 DosQueryPathInfo(wk->li->list[x],
1663 FIL_STANDARD,
1664 &fsa, (ULONG) sizeof(FILESTATUS3));
1665 if (fsa.attrFile & FILE_DIRECTORY) {
1666 error = (APIRET) wipeallf("%s%s*",
1667 wk->li->list[x],
1668 (*wk->li->list[x] &&
1669 wk->li->
1670 list[x][strlen(wk->li->list[x]) - 1]
1671 != '\\') ? PCSZ_BACKSLASH : NullStr);
1672 DosError(FERR_DISABLEHARDERR);
1673 if (!error)
1674 error = DosDeleteDir(wk->li->list[x]);
1675 else
1676 DosDeleteDir(wk->li->list[x]);
1677 }
1678 else {
1679
1680 DosError(FERR_DISABLEHARDERR);
1681 if (wk->li->type == IDM_DELETE) {
1682 hObjectdest = WinQueryObject("<XWP_TRASHCAN>");
1683 PrfQueryProfileData(HINI_USER,
1684 "XWorkplace",
1685 "TrashCan::Drives",
1686 G_abSupportedDrives,
1687 &cbSupportedDrives);
1688 if (hObjectdest != NULLHANDLE && fTrashCan &&
1689 (G_abSupportedDrives ? (G_abSupportedDrives[toupper(*wk->li->list[x]) - 'C'] &
1690 1):(!(driveflags[toupper(*wk->li->list[x]) - 'A'] &
1691 (DRIVE_REMOVABLE | DRIVE_IGNORE |
1692 DRIVE_REMOTE | DRIVE_VIRTUAL |
1693 DRIVE_NOTWRITEABLE | DRIVE_RAMDISK))))) {
1694 hObjectofObject = WinQueryObject(wk->li->list[x]);
1695 error = WinMoveObject(hObjectofObject, hObjectdest, 0);
1696 }
1697 else {
1698 error = DosDelete(wk->li->list[x]);
1699 }
1700 }
1701 else {
1702 error = DosForceDelete(wk->li->list[x]); ;
1703 }
1704 if (error) {
1705 DosError(FERR_DISABLEHARDERR);
1706 make_deleteable(wk->li->list[x]);
1707 if (wk->li->type == IDM_DELETE){
1708 hObjectdest = WinQueryObject("<XWP_TRASHCAN>");
1709 PrfQueryProfileData(HINI_USER,
1710 "XWorkplace",
1711 "TrashCan::Drives",
1712 G_abSupportedDrives,
1713 &cbSupportedDrives);
1714 if (hObjectdest != NULLHANDLE && fTrashCan &&
1715 (G_abSupportedDrives ? (G_abSupportedDrives[toupper(*wk->li->list[x]) - 'C'] &
1716 1):(!(driveflags[toupper(*wk->li->list[x]) - 'A'] &
1717 (DRIVE_REMOVABLE | DRIVE_IGNORE |
1718 DRIVE_REMOTE | DRIVE_VIRTUAL |
1719 DRIVE_NOTWRITEABLE | DRIVE_RAMDISK))))) {
1720 hObjectofObject = WinQueryObject(wk->li->list[x]);
1721 error = WinMoveObject(hObjectofObject, hObjectdest, 0);
1722 }
1723 else {
1724 error = DosDelete(wk->li->list[x]);
1725 }
1726 }
1727 else {
1728 error = DosForceDelete(wk->li->list[x]);
1729 }
1730 }
1731 DosReleaseMutexSem(hmtxFM2Delete);
1732 }
1733 if (error) {
1734 if (LogFileHandle)
1735 fprintf(LogFileHandle,
1736 GetPString(IDS_DELETEFAILED1TEXT),
1737 wk->li->list[x], error);
1738 if (Dos_Error(MB_ENTERCANCEL,
1739 error,
1740 wk->hwndFrame,
1741 pszSrcFile,
1742 __LINE__,
1743 GetPString(IDS_DELETEFAILED2TEXT),
1744 wk->li->list[x]) == MBID_CANCEL) {
1745 DosSetVerify(fVerify);
1746 break;
1747 }
1748 }
1749 else {
1750 if (LogFileHandle)
1751 fprintf(LogFileHandle,
1752 GetPString(IDS_DELETEDTEXT), wk->li->list[x]);
1753 sprintf(prompt,
1754 GetPString(IDS_DELETEDTEXT), wk->li->list[x]);
1755 AddNote(prompt);
1756 }
1757 if (//fSyncUpdates ||
1758 AddToList(wk->li->list[x], &files, &numfiles, &numalloc)) {
1759 Broadcast(hab2,
1760 wk->hwndCnr,
1761 UM_UPDATERECORD,
1762 MPFROMP(wk->li->list[x]), MPVOID);
1763 }
1764 } // for
1765 }
1766 if (fVerify)
1767 DosSetVerify(fVerify);
1768 break;
1769 } // switch
1770 if (files) {
1771 Broadcast(hab2,
1772 wk->hwndCnr,
1773 UM_UPDATERECORDLIST, MPFROMP(files), MPVOID);
1774 FreeList(files);
1775 }
1776 if (WinIsWindow(hab2, wk->hwndCnr))
1777 PostMsg(wk->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
1778
1779 WinDestroyMsgQueue(hmq2);
1780 }
1781 DecrThreadUsage();
1782 WinTerminate(hab2);
1783 }
1784 }
1785 FreeListInfo(wk->li);
1786 free(wk);
1787# ifdef FORTIFY
1788 Fortify_LeaveScope();
1789# endif
1790 DosPostEventSem(CompactSem);
1791 }
1792}
1793
1794#pragma alloc_text(MASSACTION,MassAction)
1795#pragma alloc_text(ACTION,Action)
1796#pragma alloc_text(UNDO,FreeUndo,Undo)
Note: See TracBrowser for help on using the repository browser.