source: trunk/dll/worker.c@ 1358

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

Comments for CS 1354/55

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