source: trunk/dll/worker.c@ 1354

Last change on this file since 1354 was 1354, checked in by Gregg Young, 17 years ago

Added driveflags to over ride write verify for USB removable drives that fail when it is on (Ticket 323); A flag to prevent directory name from being broadcast to drives in the tree cnr prior to a recursive scan of the drive (causes dbl directory names Ticket 321) Add option for multithreaded recursive scan of user selected drives at startup (Ticket 322).

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