source: trunk/dll/worker.c@ 1394

Last change on this file since 1394 was 1394, checked in by Steven Levine, 17 years ago

Ticket 340: Convert GetPString to use STRINGTABLE.

Drop fm3dll.str and mkstr.exe from makefiles and wpi builders

Convert many functions to expect PCSZ arguments.
Correct walk, compare and dirsizes dialog setups to ignore saved dialog size
Drop copyright.c logic from makefile

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 46.6 KB
Line 
1
2/***********************************************************************
3
4 $Id: worker.c 1394 2009-02-05 04:17:25Z stevenhl $
5
6 Worker thread
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2009 Steven H. Levine
10
11 16 Oct 02 SHL Comments
12 18 Oct 02 SHL MassAction:Archive - force extension so file found
13 06 Jun 05 SHL Indent -i2
14 06 Jun 05 SHL Rework Action for VAC3.65 compat
15 27 Jul 05 SHL IDM_DOITYOURSELF - avoid need to strip in ExecOnList
16 22 Jul 06 SHL Comments
17 22 Jul 06 SHL Check more run time errors
18 03 Nov 06 SHL Renames
19 03 Nov 06 SHL Count thread usage
20 21 Apr 07 GKY Find FM2Utils by path or utils directory
21 16 Jun 07 SHL Update for OpenWatcom
22 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
23 07 Aug 07 SHL Use BldQuotedFileName
24 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
25 26 Aug 07 SHL Revert to DosSleep(0)
26 29 Feb 08 GKY Refactor global command line variables to notebook.h
27 22 Jun 08 GKY Made Felete move to xworkplace trash can on systems that have it
28 16 JUL 08 GKY Use TMP directory for temp files
29 20 Jul 08 GKY Add save/append filename to clipboard.
30 02 Aug 08 GKY Limit use of "trash can" to local writable fixed drives or to trash can supported
31 drives list if it exists. Fix ability to deselect use of trash can.
32 01 Sep 08 GKY Add code to retry on Netdrives "pipe error"
33 04 Dec 08 GKY Add a DosSleep to allow file extract to complete before rescan
34 04 Dec 08 GKY Add mutex semaphore and disable fSyncUpdates for file deletes to prevent the creation
35 on dead CNRITEMS.
36 10 Dec 08 SHL Integrate exception handler support
37 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis
38 25 Dec 08 GKY Add DRIVE_RSCANNED flag to monitor for the first recursive drive scan per session
39 to prevent duplicate directory names in tree following a copy before initial scan.
40
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];
681 PCSZ moving, move, moved;
682 APIRET rc;
683 INT type;
684 FILESTATUS4L fs4;
685 BOOL isnewer, existed, fResetVerify = FALSE;
686
687 type = (wk->li->type == IDM_RENAME) ? MOVE :
688 (wk->li->type == IDM_MOVE) ? MOVE :
689 (wk->li->type == IDM_WPSMOVE) ? WPSMOVE :
690 (wk->li->type == IDM_WPSCOPY) ? WPSCOPY : COPY;
691 moving = (wk->li->type == IDM_RENAME) ?
692 GetPString(IDS_RENAMINGTEXT) :
693 (wk->li->type == IDM_MOVE ||
694 wk->li->type == IDM_WPSMOVE) ?
695 GetPString(IDS_MOVINGTEXT) : GetPString(IDS_COPYINGTEXT);
696 move = (wk->li->type == IDM_RENAME) ?
697 GetPString(IDS_RENAMETEXT) :
698 (wk->li->type == IDM_MOVE ||
699 wk->li->type == IDM_WPSMOVE) ?
700 GetPString(IDS_MOVETEXT) : GetPString(IDS_COPYTEXT);
701 moved = (wk->li->type == IDM_RENAME) ?
702 GetPString(IDS_RENAMEDTEXT) :
703 (wk->li->type == IDM_MOVE ||
704 wk->li->type == IDM_WPSMOVE) ?
705 GetPString(IDS_MOVEDTEXT) : GetPString(IDS_COPIEDTEXT);
706 if (*wk->li->targetpath) {
707 strcpy(newname, wk->li->targetpath);
708 if (newname[strlen(newname) - 1] != '\\')
709 strcat(newname, "\\");
710 if (plen)
711 p = wk->li->list[x] + plen;
712 else {
713 p = strrchr(wk->li->list[x], '\\');
714 if (p)
715 p++;
716 else
717 p = wk->li->list[x];
718 }
719 strcat(newname, p);
720 }
721 else
722 strcpy(newname, wk->li->list[x]);
723 if ((wildcarding || wk->li->type == IDM_RENAME) &&
724 *wildname) {
725
726 CHAR testname[CCHMAXPATH];
727
728 strcpy(testname, wildname);
729 if (AdjustWildcardName(newname, testname))
730 strcpy(newname, testname);
731 }
732 existed = (IsFile(newname) != -1);
733 isnewer = IsNewer(wk->li->list[x], newname);
734 /*
735 {
736 char temp[CCHMAXPATH * 3];
737 sprintf(temp,"Target: %s\rSource: %s\rOverold: %lu\rOvernew: %lu\rIsNewer: %lu\rExisted: %lu",newname,wk->li->list[x],overold,overnew,isnewer,existed);
738 saymsg(MB_ENTER,HWND_DESKTOP,DEBUG_STRING,temp);
739 }
740 */
741 if (existed && wk->li->type != IDM_RENAME && dontask) {
742 if (!overold && !overnew)
743 break;
744 if (!overold && !isnewer)
745 break;
746 if (!overnew && isnewer)
747 break;
748 }
749 if ((wk->li->type == IDM_RENAME &&
750 (!dontask || !*wildname)) ||
751 (!dontask && existed) ||
752 (!dontask && wildcarding) ||
753 (IsFile(newname) == 0 && IsFile(wk->li->list[x]) > 0)) {
754
755 MOVEIT mv;
756
757 memset(&mv, 0, sizeof(MOVEIT));
758 mv.rename = (wk->li->type == IDM_RENAME);
759 mv.source = wk->li->list[x];
760 strcpy(mv.target, newname);
761 rc = WinDlgBox(HWND_DESKTOP,
762 wk->hwndFrame,
763 RenameProc,
764 FM3ModHandle, REN_FRAME, (PVOID) & mv);
765 if (!rc)
766 goto Abort;
767 DosSleep(1);
768 if (mv.skip || !*mv.target)
769 break;
770 if (mv.dontask)
771 dontask = TRUE;
772 if (mv.overold)
773 overold = TRUE;
774 if (mv.overnew)
775 overnew = TRUE;
776 if (wildcarding || wk->li->type == IDM_RENAME) {
777 p = strrchr(mv.target, '\\');
778 if (p && (strchr(p, '*') || strchr(p, '?'))) {
779 strcpy(wildname, mv.target);
780 AdjustWildcardName(wk->li->list[x], mv.target);
781 }
782 else
783 *wildname = 0;
784 }
785 strcpy(newname, mv.target);
786 existed = (IsFile(newname) != -1);
787 isnewer = IsNewer(wk->li->list[x], newname);
788 if (!mv.overwrite) {
789 if (existed && wk->li->type != IDM_RENAME && dontask) {
790 if (!overold && !overnew)
791 break;
792 if (!overold && !isnewer)
793 break;
794 if (!overnew && isnewer)
795 break;
796 }
797 }
798 }
799 if (!strcmp(wk->li->list[x], newname) ||
800 (wk->li->type == IDM_COPY &&
801 !stricmp(wk->li->list[x], newname)))
802 break;
803 sprintf(message,
804 " %s \"%s\" %s\"%s\"%s",
805 moving,
806 wk->li->list[x],
807 GetPString(IDS_TOTEXT),
808 newname,
809 (usedtarget) ? GetPString(IDS_TOTARGETTEXT) :
810 NullStr);
811 AddNote(message);
812 if (fVerify && (driveflags[toupper(*wk->li->targetpath) - 'A'] & DRIVE_WRITEVERIFYOFF) |
813 (driveflags[toupper(*wk->li->list[x]) - 'A'] & DRIVE_WRITEVERIFYOFF)) {
814 DosSetVerify(FALSE);
815 fResetVerify = TRUE;
816 }
817 if (plen) {
818 /* make directory/ies, if required */
819
820 CHAR dirpart[CCHMAXPATH];
821
822 strcpy(dirpart, newname);
823 p = strrchr(dirpart, '\\');
824 if (p) {
825 *p = 0;
826 if (p > dirpart + 3)
827 MassMkdir((hwndMain) ? hwndMain : wk->hwndCnr,
828 dirpart);
829 }
830 }
831 if (fRealIdle)
832 priority_idle();
833 rc = docopyf(type, wk->li->list[x], "%s", newname);
834 if (fResetVerify) {
835 DosSetVerify(fVerify);
836 fResetVerify = FALSE;
837 }
838 priority_normal();
839 if (rc) {
840 if ((rc == ERROR_DISK_FULL ||
841 rc == ERROR_HANDLE_DISK_FULL) &&
842 isalpha(*newname) &&
843 (driveflags[toupper(*newname) - 'A'] &
844 DRIVE_REMOVABLE)
845 && !(driveflags[toupper(*newname) - 'A'] &
846 DRIVE_NOTWRITEABLE)
847 && toupper(*newname) != toupper(*wk->li->list[x])
848 && !DosQueryPathInfo(wk->li->list[x], FIL_QUERYEASIZEL,
849 &fs4, sizeof(fs4))
850 && !(fs4.attrFile & FILE_DIRECTORY)) {
851
852 FSALLOCATE fsa;
853 ULONGLONG ullFreeBytes;
854 CHAR *ptr;
855 INT cntr;
856
857 Notify(GetPString(IDS_FITTINGTEXT));
858 DosError(FERR_DISABLEHARDERR);
859 if (!DosQueryFSInfo(toupper(*newname) - '@',
860 FSIL_ALLOC,
861 &fsa, sizeof(FSALLOCATE))) {
862 // Assume large file support
863 ullFreeBytes = (ULONGLONG) fsa.cUnitAvail * fsa.cSectorUnit *
864 fsa.cbSector;
865 if (ullFreeBytes) {
866 // Find item that will fit in available space
867 for (cntr = x + 1; wk->li->list[cntr]; cntr++) {
868 DosError(FERR_DISABLEHARDERR);
869 if (!DosQueryPathInfo(wk->li->list[cntr],
870 FIL_QUERYEASIZEL,
871 &fs4,
872 sizeof(fs4)) &&
873 !(fs4.attrFile & FILE_DIRECTORY) &&
874 // fixme to use CBLIST_TO_EASIZE?
875 fs4.cbFile + fs4.cbList <= ullFreeBytes) {
876 // Swap with failing item
877 ptr = wk->li->list[x];
878 wk->li->list[x] = wk->li->list[cntr];
879 wk->li->list[cntr] = ptr;
880 goto Retry;
881 }
882 }
883 Notify(GetPString(IDS_COULDNTFITTEXT));
884 }
885 }
886 rc = saymsg(MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION,
887 wk->hwndFrame,
888 GetPString(IDS_DISKFULLTEXT),
889 "%s", GetPString(IDS_ANOTHERDISKTEXT));
890 if (rc == MBID_RETRY)
891 goto Retry;
892 if (rc == MBID_ABORT)
893 goto Abort;
894 }
895 else {
896 if (LogFileHandle)
897 fprintf(LogFileHandle,
898 GetPString(IDS_LOGTOFAILEDTEXT),
899 move, wk->li->list[x], newname, rc);
900 rc = Dos_Error(MB_ENTERCANCEL,
901 rc,
902 wk->hwndFrame,
903 pszSrcFile,
904 __LINE__,
905 "%s %s \"%s\" %s\"%s\" %s.",
906 move,
907 GetPString(IDS_OFTEXT),
908 wk->li->list[x],
909 GetPString(IDS_TOTEXT),
910 newname, GetPString(IDS_FAILEDTEXT));
911 if (rc == MBID_CANCEL)
912 goto Abort;
913 }
914 }
915 else {
916 if (LogFileHandle)
917 fprintf(LogFileHandle,
918 "%s \"%s\" %s\"%s\"\n",
919 moved,
920 wk->li->list[x],
921 GetPString(IDS_TOTEXT), newname);
922 if ((driveflags[*wk->li->targetpath - 'A'] & DRIVE_RSCANNED) &&
923 AddToList(wk->li->list[x],
924 &files, &numfiles, &numalloc))
925 Broadcast(hab2,
926 wk->hwndCnr,
927 UM_UPDATERECORD,
928 MPFROMP(wk->li->list[x]), MPVOID);
929 if ((driveflags[*wk->li->targetpath - 'A'] & DRIVE_RSCANNED) &&
930 AddToList(newname, &files, &numfiles, &numalloc))
931 Broadcast(hab2,
932 wk->hwndCnr,
933 UM_UPDATERECORD, MPFROMP(newname), MPVOID);
934 }
935 }
936 break;
937 }
938
939 case IDM_COMPARE:
940 if ((!IsFile(wk->li->targetpath) ||
941 IsRoot(wk->li->targetpath)) &&
942 (!IsFile(wk->li->list[x]) || IsRoot(wk->li->list[x]))) {
943 if (!*dircompare && WinIsWindow(hab2, wk->hwndCnr))
944 WinSendMsg(wk->hwndCnr,
945 UM_COMPARE,
946 MPFROMP(wk->li->targetpath),
947 MPFROMP(wk->li->list[x]));
948 else {
949 runemf2(SEPARATE,
950 HWND_DESKTOP, pszSrcFile, __LINE__,
951 NULL, NULL,
952 "%s %s %s",
953 dircompare,
954 BldQuotedFileName(szQuotedDirName, wk->li->targetpath),
955 BldQuotedFileName(szQuotedFileName, wk->li->list[x]));
956 }
957 }
958 else if (*compare) {
959 CHAR *fakelist[3];
960
961 fakelist[0] = wk->li->list[x];
962 fakelist[1] = wk->li->targetpath;
963 fakelist[2] = NULL;
964 ExecOnList(wk->hwndFrame,
965 compare,
966 WINDOWED | SEPARATEKEEP, NULL, fakelist, NULL,
967 pszSrcFile, __LINE__);
968 }
969 else {
970 FCOMPARE fc;
971
972 memset(&fc, 0, sizeof(fc));
973 fc.size = sizeof(fc);
974 fc.hwndParent = wk->hwndParent;
975 strcpy(fc.file1, wk->li->list[x]);
976 strcpy(fc.file2, wk->li->targetpath);
977 if (WinDlgBox(HWND_DESKTOP,
978 wk->hwndFrame,
979 CFileDlgProc,
980 FM3ModHandle, FCMP_FRAME, (PVOID) & fc))
981 goto Abort;
982 }
983 break;
984 } // switch
985 DosSleep(0);
986 } // for list
987
988 switch (wk->li->type) {
989 case IDM_MOVE:
990 case IDM_COPY:
991 case IDM_WPSMOVE:
992 case IDM_WPSCOPY:
993 case IDM_RENAME:
994 sprintf(message,
995 GetPString(IDS_OPSCOMPLETETEXT),
996 (wk->li->type == IDM_MOVE) ?
997 GetPString(IDS_MOVETEXT) :
998 (wk->li->type == IDM_COPY) ?
999 GetPString(IDS_COPYTEXT) :
1000 (wk->li->type == IDM_WPSMOVE) ?
1001 GetPString(IDS_WPSMOVETEXT) :
1002 (wk->li->type == IDM_WPSCOPY) ?
1003 GetPString(IDS_WPSCOPYTEXT) :
1004 GetPString(IDS_RENAMETEXT),
1005 &"s"[x == 1],
1006 (wk->li->type == IDM_MOVE ||
1007 wk->li->type == IDM_COPY ||
1008 wk->li->type == IDM_WPSMOVE ||
1009 wk->li->type == IDM_WPSCOPY) ?
1010 GetPString(IDS_TOTEXT) :
1011 NullStr,
1012 (wk->li->type == IDM_MOVE ||
1013 wk->li->type == IDM_COPY ||
1014 wk->li->type == IDM_WPSMOVE ||
1015 wk->li->type == IDM_WPSCOPY) ?
1016 wk->li->targetpath :
1017 NullStr,
1018 (x != 1) ?
1019 GetPString(IDS_ARETEXT) : GetPString(IDS_ISTEXT));
1020 Notify(message);
1021 if (toupper(*wk->li->targetpath) < 'C')
1022 DosBeep(1000, 25); // Wake up user
1023 DosSleep(16);//05 Aug 07 GKY 33
1024 if (wk->li->type == IDM_WPSMOVE || wk->li->type == IDM_WPSCOPY)
1025 DosSleep(48);//05 Aug 07 GKY 96
1026 break;
1027 default:
1028 break;
1029 }
1030 }
1031
1032 Abort:
1033
1034 if (files) {
1035 if (driveflags[*wk->li->targetpath - 'A'] & DRIVE_RSCANNED)
1036 Broadcast(hab2,
1037 wk->hwndCnr,
1038 UM_UPDATERECORDLIST, MPFROMP(files), MPVOID);
1039 // DbgMsg(pszSrcFile, __LINE__, "UM_UPDATERECORD %s", *files);
1040 FreeList(files);
1041 }
1042
1043 if (WinIsWindow(hab2, wk->hwndCnr))
1044 PostMsg(wk->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
1045
1046 WinDestroyMsgQueue(hmq2);
1047 }
1048 DecrThreadUsage();
1049 WinTerminate(hab2);
1050 }
1051 }
1052
1053 if (wk->li)
1054 FreeListInfo(wk->li);
1055 free(wk);
1056# ifdef FORTIFY
1057 Fortify_LeaveScope();
1058# endif
1059 DosPostEventSem(CompactSem);
1060 }
1061}
1062
1063VOID MassAction(VOID * args)
1064{
1065 WORKER *wk = (WORKER *) args;
1066 HAB hab2;
1067 HMQ hmq2;
1068 CHAR **files = NULL;
1069 register CHAR *p, *pp;
1070 UINT numfiles = 0, numalloc = 0;
1071
1072
1073 if (wk) {
1074# ifdef FORTIFY
1075 // Fortify_BecomeOwner(wk);
1076 Fortify_EnterScope();
1077# endif
1078 if (wk->li && wk->li->list && wk->li->list[0]) {
1079 hab2 = WinInitialize(0);
1080 if (hab2) {
1081 hmq2 = WinCreateMsgQueue(hab2, 0);
1082 if (hmq2) {
1083 WinCancelShutdown(hmq2, TRUE);
1084 IncrThreadUsage();
1085 DosError(FERR_DISABLEHARDERR);
1086 if (IsRoot(wk->li->list[0]) || !IsFile(wk->li->list[0])) {
1087 if (wk->li->type == IDM_VIEW)
1088 wk->li->type = IDM_INFO;
1089 if (wk->li->type == IDM_EDIT)
1090 wk->li->type = IDM_EAS;
1091 }
1092 switch (wk->li->type) {
1093 case IDM_INFO:
1094 if (WinDlgBox(HWND_DESKTOP,
1095 wk->hwndFrame,
1096 FileInfoProc,
1097 FM3ModHandle, FLE_FRAME, (PVOID) wk->li->list) != 2)
1098 {
1099 break;
1100 }
1101 /* else intentional fallthru */
1102 case IDM_UPDATE:
1103 Broadcast(hab2,
1104 wk->hwndCnr,
1105 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1106 break;
1107
1108 case IDM_EAS:
1109 if (WinDlgBox(HWND_DESKTOP,
1110 wk->hwndFrame,
1111 DisplayEAsProc,
1112 FM3ModHandle, EA_FRAME, (PVOID) wk->li->list))
1113 Broadcast(hab2,
1114 wk->hwndCnr,
1115 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1116 break;
1117
1118 case IDM_DOITYOURSELF:
1119 ExecOnList(wk->hwndFrame,
1120 "%a",
1121 WINDOWED | SEPARATE | PROMPT,
1122 NULL, wk->li->list, GetPString(IDS_DOITYOURSELFTEXT),
1123 pszSrcFile, __LINE__);
1124 break;
1125
1126 case IDM_MCIPLAY:
1127 {
1128 register INT x;
1129 register ULONG total;
1130 CHAR fbuf[CCHMAXPATH];
1131
1132 if (DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT |
1133 SEARCH_CUR_DIRECTORY,
1134 "PATH", "FM2PLAY.EXE", (PBYTE)fbuf, CCHMAXPATH - 1))
1135 total += strlen("..\\FM2UTILS\\FM2PLAY.EXE ");
1136 else
1137 total = strlen(fbuf);
1138 for (x = 0; wk->li->list[x]; x++)
1139 total += (strlen(wk->li->list[x]) + 1 +
1140 (needs_quoting(wk->li->list[x]) * 2));
1141 if (total > 1000) {
1142
1143 FILE *fp;
1144 CHAR szTempFile[CCHMAXPATH];
1145
1146 BldFullPathName(szTempFile, pTmpDir, "$FM2PLAY.$$$");
1147 fp = xfopen(szTempFile, "w", pszSrcFile, __LINE__);
1148 if (fp) {
1149 fprintf(fp, "%s", ";AV/2-built FM2Play listfile\n");
1150 for (x = 0; wk->li->list[x]; x++)
1151 fprintf(fp, "%s\n", wk->li->list[x]);
1152 fprintf(fp, ";end\n");
1153 fclose(fp);
1154 strrev(szTempFile);
1155 strcat(szTempFile, "@/");
1156 strrev(szTempFile);
1157 RunFM2Util("FM2PLAY.EXE", szTempFile);
1158 }
1159 }
1160 }
1161 /* intentional fallthru */
1162 case IDM_FAKEEXTRACT:
1163 case IDM_FAKEEXTRACTM:
1164 if (wk->li->type == IDM_MCIPLAY ||
1165 (*wk->li->arcname && wk->li->info &&
1166 wk->li->info->extract && *wk->li->targetpath)) {
1167
1168 CHAR szBuffer[1025];
1169 CHAR fbuf[CCHMAXPATH];
1170 register INT x;
1171
1172 if (wk->li->type == IDM_FAKEEXTRACT ||
1173 wk->li->type == IDM_FAKEEXTRACTM) {
1174 strcpy(szBuffer,
1175 (wk->li->info->exwdirs) ?
1176 wk->li->info->exwdirs : wk->li->info->extract);
1177 strcat(szBuffer, " ");
1178 BldQuotedFileName(szBuffer + strlen(szBuffer), wk->li->arcname);
1179 }
1180 else {
1181 if (DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT |
1182 SEARCH_CUR_DIRECTORY,
1183 "PATH", "FM2PLAY.EXE", (PBYTE)fbuf, CCHMAXPATH - 1))
1184 strcpy(szBuffer, "UTILS\\FM2PLAY.EXE");
1185 else
1186 strcpy(szBuffer, "FM2PLAY.EXE");
1187 }
1188 p = &szBuffer[strlen(szBuffer)];
1189 strcat(szBuffer, " ");
1190 x = 0;
1191 while (wk->li->list[x]) {
1192 pp = wk->li->list[x];
1193 while (*pp) {
1194 if (*pp == '/')
1195 *pp = '\\';
1196 pp++;
1197 }
1198 BldQuotedFileName(szBuffer + strlen(szBuffer), wk->li->list[x]);
1199 x++;
1200 if (!wk->li->list[x] || strlen(szBuffer) +
1201 strlen(wk->li->list[x]) + 5 > 1024) {
1202 runemf2(SEPARATE | WINDOWED | BACKGROUND | MINIMIZED | WAIT,
1203 HWND_DESKTOP, pszSrcFile, __LINE__,
1204 (wk->li->type == IDM_FAKEEXTRACT ||
1205 wk->li->type == IDM_FAKEEXTRACTM) ?
1206 wk->li->targetpath : NULL,
1207 NULL,
1208 "%s", szBuffer);
1209 DosSleep(1);
1210 *p = 0;
1211 }
1212 strcat(szBuffer, " ");
1213 }
1214 if (wk->li->type == IDM_MCIPLAY)
1215 break;
1216 strcpy(szBuffer, wk->li->targetpath);
1217 if (wk->li->targetpath[strlen(wk->li->targetpath) - 1] != '\\')
1218 strcat(szBuffer, "\\");
1219 p = szBuffer + strlen(szBuffer);
1220 for (x = 0; wk->li->list[x]; x++) {
1221 strcpy(p, wk->li->list[x]);
1222 free(wk->li->list[x]);
1223 wk->li->list[x] = xstrdup(szBuffer, pszSrcFile, __LINE__);
1224 }
1225 if (wk->li->list[0])
1226 Broadcast(hab2,
1227 wk->hwndCnr,
1228 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1229 }
1230 break;
1231
1232 case IDM_SETICON:
1233 if (*wk->li->targetpath) {
1234
1235 ICONINFO ici;
1236
1237 memset(&ici, 0, sizeof(ICONINFO));
1238 ici.cb = sizeof(ICONINFO);
1239 ici.fFormat = ICON_FILE;
1240 ici.pszFileName = wk->li->list[0];
1241 if (!WinSetFileIcon((PSZ) wk->li->targetpath,
1242 (PICONINFO) & ici)) {
1243 ici.fFormat = ICON_CLEAR;
1244 WinSetFileIcon((PSZ) wk->li->targetpath, (PICONINFO) & ici);
1245 }
1246 Broadcast(hab2,
1247 wk->hwndCnr,
1248 UM_UPDATERECORD, MPFROMP(wk->li->targetpath), MPVOID);
1249 }
1250 break;
1251
1252 case IDM_APPENDTOCLIP:
1253 case IDM_SAVETOCLIP:
1254 case IDM_SAVETOCLIPFILENAME:
1255 case IDM_APPENDTOCLIPFILENAME:
1256 ListToClipboardHab(hab2,
1257 wk->li->list,
1258 wk->li->type);
1259 break;
1260
1261 case IDM_ARCHIVEM:
1262 case IDM_ARCHIVE:
1263 {
1264 DIRCNRDATA ad;
1265 CHAR szBuffer[1025];
1266 ARC_TYPE *info = NULL;
1267 char *pch;
1268 register INT x;
1269
1270 memset(&ad, 0, sizeof(DIRCNRDATA));
1271 strcpy(ad.arcname, wk->li->targetpath);
1272 if (*wk->li->targetpath && IsFile(wk->li->targetpath) > 0) {
1273 info = find_type(wk->li->targetpath, NULL);
1274 ad.namecanchange = 0;
1275 }
1276 else {
1277 if (*wk->li->targetpath && !IsFile(wk->li->targetpath))
1278 if (wk->li->targetpath[strlen(wk->li->targetpath) - 1] !=
1279 '\\')
1280 strcat(wk->li->targetpath, "\\");
1281 ad.namecanchange = 1;
1282 }
1283 strcpy(ad.arcname, wk->li->targetpath);
1284 if (wk->li->type == IDM_ARCHIVEM)
1285 ad.fmoving = TRUE;
1286 if (!info) {
1287 ad.info = arcsighead; // Hide dups
1288 if (!WinDlgBox(HWND_DESKTOP,
1289 wk->hwndFrame,
1290 SBoxDlgProc,
1291 FM3ModHandle,
1292 ASEL_FRAME, (PVOID) & ad.info) || !ad.info) {
1293 break; /* we blew it */
1294 }
1295 }
1296 else
1297 ad.info = info;
1298 if (!ad.info || (!ad.info->create &&
1299 !ad.info->move &&
1300 !ad.info->createwdirs &&
1301 !ad.info->movewdirs &&
1302 !ad.info->createrecurse))
1303 break;
1304 if (!*wk->li->targetpath && *wk->directory) {
1305 strcpy(ad.arcname, wk->directory);
1306 if (ad.arcname[strlen(ad.arcname) - 1] != '\\')
1307 strcat(ad.arcname, "\\");
1308 }
1309 if (!WinDlgBox(HWND_DESKTOP, wk->hwndFrame, ArchiveDlgProc, FM3ModHandle,
1310 ARCH_FRAME, (PVOID) & ad) || !*ad.arcname || !*ad.command) /* we blew it */
1311 break;
1312 // Provide extension so containers work
1313 pch = strrchr(ad.arcname, '\\');
1314 if (pch)
1315 pch = strrchr(pch, '.');
1316 else
1317 pch = strrchr(ad.arcname, '.');
1318 if (!pch && ad.info->ext) {
1319 strcat(ad.arcname, ".");
1320 strcat(ad.arcname, ad.info->ext);
1321 }
1322 /* build the sucker */
1323 strcpy(szBuffer, ad.command);
1324 strcat(szBuffer, " ");
1325 BldQuotedFileName(szBuffer + strlen(szBuffer), ad.arcname);
1326 p = &szBuffer[strlen(szBuffer)];
1327 if (ad.mask.szMask) {
1328 strcat(szBuffer, " ");
1329 strcat(szBuffer, ad.mask.szMask);
1330 }
1331 strcat(szBuffer, " ");
1332 x = 0;
1333 while (wk->li->list[x]) {
1334 FILESTATUS3 fsa;
1335 memset(&fsa, 0, sizeof(FILESTATUS3));
1336 DosError(FERR_DISABLEHARDERR);
1337 DosQueryPathInfo(wk->li->list[x],
1338 FIL_STANDARD,
1339 &fsa, (ULONG) sizeof(FILESTATUS3));
1340 if (fsa.attrFile & FILE_DIRECTORY) {
1341 BldQuotedFullPathName(szBuffer + strlen(szBuffer), wk->li->list[x], "*");
1342 }
1343 else
1344 BldQuotedFileName(szBuffer + strlen(szBuffer), wk->li->list[x]);
1345 x++;
1346 if (!wk->li->list[x] ||
1347 strlen(szBuffer) + strlen(wk->li->list[x]) + 5 > 1024) {
1348 runemf2(SEPARATE | WINDOWED | WAIT |
1349 (fArcStuffVisible ? 0 : (BACKGROUND | MINIMIZED)),
1350 HWND_DESKTOP, pszSrcFile, __LINE__, NULL, NULL,
1351 "%s", szBuffer);
1352 DosSleep(1);
1353 *p = 0;
1354 }
1355 strcat(szBuffer, " ");
1356 }
1357 Broadcast(hab2,
1358 wk->hwndCnr,
1359 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1360 Broadcast(hab2,
1361 wk->hwndCnr,
1362 UM_UPDATERECORD, MPFROMP(ad.arcname), MPVOID);
1363 }
1364 break;
1365
1366 case IDM_VIEW:
1367 if (!TestBinary(wk->li->list[0])) {
1368 wk->li->type = IDM_VIEWTEXT;
1369 goto SkipViewing;
1370 }
1371 else
1372 wk->li->type = IDM_VIEWBINARY;
1373 /* intentional fallthru */
1374 case IDM_VIEWBINARY:
1375 if (*binview) {
1376 ExecOnList((HWND) 0,
1377 binview,
1378 WINDOWED | SEPARATE, NULL, wk->li->list, NULL,
1379 pszSrcFile, __LINE__);
1380 break;
1381 }
1382 /* else intentional fallthru */
1383 case IDM_VIEWTEXT:
1384 SkipViewing:
1385 if (*viewer)
1386 ExecOnList((HWND) 0, viewer,
1387 WINDOWED | SEPARATE |
1388 ((fViewChild) ? CHILD : 0),
1389 NULL, wk->li->list, NULL,
1390 pszSrcFile, __LINE__);
1391 else {
1392
1393 CHAR *temp;
1394 register INT x;
1395 ULONG viewtype;
1396
1397 viewtype = (wk->li->type == IDM_VIEWTEXT) ? 8 :
1398 (wk->li->type == IDM_VIEWBINARY) ? 16 : 0;
1399 for (x = 0; wk->li->list[x]; x++) {
1400 temp = xstrdup(wk->li->list[x], pszSrcFile, __LINE__);
1401 if (temp && WinIsWindow(hab2, wk->hwndCnr)) {
1402 if (!PostMsg(wk->hwndCnr,
1403 UM_LOADFILE,
1404 MPFROMLONG(5 + viewtype), MPFROMP(temp)))
1405 free(temp);
1406 }
1407 DosSleep(1);
1408 }
1409 }
1410 break;
1411
1412 case IDM_EDIT:
1413 if (!TestBinary(wk->li->list[0])) {
1414 wk->li->type = IDM_EDITTEXT;
1415 goto SkipEditing;
1416 }
1417 else
1418 wk->li->type = IDM_EDITBINARY;
1419 /* intentional fallthru */
1420 case IDM_EDITBINARY:
1421 if (*bined) {
1422 ExecOnList((HWND) 0,
1423 bined,
1424 WINDOWED | SEPARATE, NULL, wk->li->list, NULL,
1425 pszSrcFile, __LINE__);
1426 break;
1427 }
1428 /* else intentional fallthru */
1429 case IDM_EDITTEXT:
1430 SkipEditing:
1431 if (*editor)
1432 ExecOnList((HWND) 0,
1433 editor,
1434 WINDOWED | SEPARATE, NULL, wk->li->list, NULL,
1435 pszSrcFile, __LINE__);
1436 else {
1437
1438 CHAR *temp;
1439 register INT x;
1440 ULONG viewtype;
1441
1442 viewtype = (wk->li->type == IDM_EDITTEXT) ? 8 :
1443 (wk->li->type == IDM_EDITBINARY) ? 16 : 0;
1444 for (x = 0; wk->li->list[x]; x++) {
1445 temp = xstrdup(wk->li->list[x], pszSrcFile, __LINE__);
1446 if (temp && WinIsWindow(hab2, wk->hwndCnr)) {
1447 if (!PostMsg(wk->hwndCnr,
1448 UM_LOADFILE,
1449 MPFROMLONG(4 + viewtype), MPFROMP(temp)))
1450 free(temp);
1451 }
1452 DosSleep(1);
1453 }
1454 }
1455 break;
1456
1457 case IDM_SHADOW2:
1458 case IDM_OBJECT:
1459 case IDM_SHADOW:
1460 {
1461 CHAR objectpath[CCHMAXPATH];
1462 APIRET rc;
1463
1464 if (!*wk->li->targetpath || IsFile(wk->li->targetpath)) {
1465 GetDesktopName(objectpath, sizeof(objectpath));
1466 rc = WinDlgBox(HWND_DESKTOP,
1467 wk->hwndFrame,
1468 ObjCnrDlgProc,
1469 FM3ModHandle,
1470 OBJCNR_FRAME, MPFROMP(objectpath));
1471 if (rc) {
1472 if (rc > 1)
1473 strcpy(objectpath, "<WP_DESKTOP>");
1474 }
1475 else
1476 break;
1477 }
1478 else
1479 strcpy(objectpath, wk->li->targetpath);
1480 AddNote(GetPString(IDS_MAKINGOBJSTEXT));
1481 MakeShadows(wk->hwndFrame,
1482 wk->li->list,
1483 (wk->li->type == IDM_SHADOW) +
1484 (wk->li->type == IDM_SHADOW2) * 2,
1485 objectpath, NULL);
1486 AddNote(GetPString(IDS_MADEOBJSTEXT));
1487 }
1488 break;
1489
1490 case IDM_PRINT:
1491 if (WinDlgBox(HWND_DESKTOP,
1492 wk->hwndFrame,
1493 PrintDlgProc,
1494 FM3ModHandle, PRN_FRAME, MPFROMP(wk->li))) {
1495 if (wk->li && wk->li->list && wk->li->list[0]) {
1496 strcpy(wk->li->targetpath, printer);
1497 if (xbeginthread(PrintListThread,
1498 65536,
1499 wk->li,
1500 pszSrcFile,
1501 __LINE__) != -1)
1502 {
1503 wk->li = NULL; // prevent LISTINFO li from being freed here
1504 }
1505 }
1506 }
1507 break;
1508
1509 case IDM_ATTRS:
1510 if (WinDlgBox(HWND_DESKTOP,
1511 wk->hwndFrame,
1512 AttrListDlgProc,
1513 FM3ModHandle, ATR_FRAME, MPFROMP(wk->li))) {
1514 if (wk->li && wk->li->list && wk->li->list[0])
1515 Broadcast(hab2,
1516 wk->hwndCnr,
1517 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1518 }
1519 break;
1520
1521 case IDM_PERMDELETE:
1522 case IDM_DELETE:
1523 {
1524 CHECKLIST cl;
1525 INT isdir = 0, sysdir = 0, ro = 0, hs = 0;
1526 register INT x;
1527 FILESTATUS3 fsa;
1528 CHAR prompt[CCHMAXPATH * 3];
1529 APIRET error = 0;
1530 HOBJECT hObjectdest, hObjectofObject;
1531 BYTE G_abSupportedDrives[24] = {0};
1532 ULONG cbSupportedDrives = sizeof(G_abSupportedDrives);
1533
1534 for (x = 0; wk->li->list[x]; x++) {
1535 if (IsRoot(wk->li->list[x])) {
1536 wk->li->list = RemoveFromList(wk->li->list,
1537 wk->li->list[x]);
1538 if (!wk->li->list)
1539 break;
1540 x--;
1541 continue;
1542 }
1543 DosError(FERR_DISABLEHARDERR);
1544 if (DosQueryPathInfo(wk->li->list[x],
1545 FIL_STANDARD, &fsa,
1546 (ULONG) sizeof(FILESTATUS3))) {
1547 wk->li->list = RemoveFromList(wk->li->list,
1548 wk->li->list[x]);
1549 if (!wk->li->list)
1550 break;
1551 x--;
1552 continue;
1553 }
1554 if (fsa.attrFile & FILE_DIRECTORY) {
1555 isdir++;
1556 if (stristr(wk->li->list[x], ":\\OS2\\") ||
1557 !stricmp(wk->li->list[x] + 1, ":\\OS2"))
1558 sysdir++;
1559 }
1560 else {
1561 if (fsa.attrFile & (FILE_HIDDEN | FILE_SYSTEM))
1562 hs++;
1563 if (fsa.attrFile & FILE_READONLY)
1564 ro++;
1565 }
1566 }
1567 if (!wk->li->list)
1568 break;
1569 if (fConfirmDelete || isdir || hs || ro) {
1570 memset(&cl, 0, sizeof(cl));
1571 cl.size = sizeof(cl);
1572 cl.list = wk->li->list;
1573 cl.prompt = prompt;
1574 cl.flags |= CHECK_FILES;
1575 cl.cmd = wk->li->type;
1576 sprintf(prompt,
1577 GetPString(IDS_DELPROMPT1TEXT),
1578 (wk->li->type == IDM_DELETE) ?
1579 NullStr :
1580 GetPString(IDS_PERMANENTLYTEXT),
1581 &"s"[wk->li->list[1] == NULL]);
1582 if (isdir) {
1583 sprintf(&prompt[strlen(prompt)],
1584 GetPString(IDS_DELPROMPT2TEXT),
1585 isdir,
1586 (isdir > 1) ?
1587 GetPString(IDS_ARETEXT) :
1588 GetPString(IDS_ISTEXT),
1589 (isdir == 1) ?
1590 GetPString(IDS_ATEXT) :
1591 NullStr,
1592 (isdir > 1) ?
1593 GetPString(IDS_IESTEXT) : GetPString(IDS_YTEXT));
1594 if (sysdir)
1595 sprintf(&prompt[strlen(prompt)],
1596 GetPString(IDS_DELPROMPT3TEXT),
1597 sysdir,
1598 (sysdir == 1) ?
1599 GetPString(IDS_YTEXT) : GetPString(IDS_IESTEXT));
1600 }
1601 if (ro)
1602 sprintf(&prompt[strlen(prompt)],
1603 GetPString(IDS_DELPROMPT4TEXT),
1604 ro,
1605 &"s"[ro == 1],
1606 (ro > 1) ?
1607 GetPString(IDS_ARETEXT) : GetPString(IDS_ISTEXT));
1608 if (hs)
1609 sprintf(&prompt[strlen(prompt)],
1610 GetPString(IDS_DELPROMPT5TEXT),
1611 hs,
1612 &"s"[hs == 1],
1613 (hs > 1) ?
1614 GetPString(IDS_ARETEXT) : GetPString(IDS_ISTEXT));
1615 if (ro || hs || sysdir)
1616 DosBeep(300, 100); // Wake up user
1617 strcat(prompt, GetPString(IDS_DELPROMPT6TEXT));
1618 error = WinDlgBox(HWND_DESKTOP,
1619 wk->hwndFrame,
1620 CheckListProc,
1621 FM3ModHandle, CHECK_FRAME, MPFROMP(&cl));
1622 if (!error || error == 65535)
1623 break;
1624 wk->li->list = cl.list;
1625 if (!wk->li->list || !wk->li->list[0])
1626 break;
1627 }
1628 if (fVerify && driveflags[toupper(*wk->li->list[0]) - 'A'] & DRIVE_WRITEVERIFYOFF)
1629 DosSetVerify(FALSE);
1630 DosRequestMutexSem(hmtxFM2Delete, SEM_INDEFINITE_WAIT); // Prevent race 12-3-08 GKY
1631 for (x = 0; wk->li->list[x]; x++) {
1632 fsa.attrFile = 0;
1633 DosError(FERR_DISABLEHARDERR);
1634 DosQueryPathInfo(wk->li->list[x],
1635 FIL_STANDARD,
1636 &fsa, (ULONG) sizeof(FILESTATUS3));
1637 if (fsa.attrFile & FILE_DIRECTORY) {
1638 error = (APIRET) wipeallf("%s%s*",
1639 wk->li->list[x],
1640 (*wk->li->list[x] &&
1641 wk->li->
1642 list[x][strlen(wk->li->list[x]) - 1]
1643 != '\\') ? "\\" : NullStr);
1644 DosError(FERR_DISABLEHARDERR);
1645 if (!error)
1646 error = DosDeleteDir(wk->li->list[x]);
1647 else
1648 DosDeleteDir(wk->li->list[x]);
1649 }
1650 else {
1651
1652 DosError(FERR_DISABLEHARDERR);
1653 if (wk->li->type == IDM_DELETE) {
1654 hObjectdest = WinQueryObject("<XWP_TRASHCAN>");
1655 PrfQueryProfileData(HINI_USER,
1656 "XWorkplace",
1657 "TrashCan::Drives",
1658 G_abSupportedDrives,
1659 &cbSupportedDrives);
1660 if (hObjectdest != NULLHANDLE && fTrashCan &&
1661 (G_abSupportedDrives ? (G_abSupportedDrives[toupper(*wk->li->list[x]) - 'C'] &
1662 1):(!(driveflags[toupper(*wk->li->list[x]) - 'A'] &
1663 (DRIVE_REMOVABLE | DRIVE_IGNORE |
1664 DRIVE_REMOTE | DRIVE_VIRTUAL |
1665 DRIVE_NOTWRITEABLE | DRIVE_RAMDISK))))) {
1666 hObjectofObject = WinQueryObject(wk->li->list[x]);
1667 error = WinMoveObject(hObjectofObject, hObjectdest, 0);
1668 }
1669 else {
1670 error = DosDelete(wk->li->list[x]);
1671 }
1672 }
1673 else {
1674 error = DosForceDelete(wk->li->list[x]); ;
1675 }
1676 if (error) {
1677 DosError(FERR_DISABLEHARDERR);
1678 make_deleteable(wk->li->list[x]);
1679 if (wk->li->type == IDM_DELETE){
1680 hObjectdest = WinQueryObject("<XWP_TRASHCAN>");
1681 PrfQueryProfileData(HINI_USER,
1682 "XWorkplace",
1683 "TrashCan::Drives",
1684 G_abSupportedDrives,
1685 &cbSupportedDrives);
1686 if (hObjectdest != NULLHANDLE && fTrashCan &&
1687 (G_abSupportedDrives ? (G_abSupportedDrives[toupper(*wk->li->list[x]) - 'C'] &
1688 1):(!(driveflags[toupper(*wk->li->list[x]) - 'A'] &
1689 (DRIVE_REMOVABLE | DRIVE_IGNORE |
1690 DRIVE_REMOTE | DRIVE_VIRTUAL |
1691 DRIVE_NOTWRITEABLE | DRIVE_RAMDISK))))) {
1692 hObjectofObject = WinQueryObject(wk->li->list[x]);
1693 error = WinMoveObject(hObjectofObject, hObjectdest, 0);
1694 }
1695 else {
1696 error = DosDelete(wk->li->list[x]);
1697 }
1698 }
1699 else {
1700 error = DosForceDelete(wk->li->list[x]);
1701 }
1702 }
1703 DosReleaseMutexSem(hmtxFM2Delete);
1704 }
1705 if (error) {
1706 if (LogFileHandle)
1707 fprintf(LogFileHandle,
1708 GetPString(IDS_DELETEFAILED1TEXT),
1709 wk->li->list[x], error);
1710 if (Dos_Error(MB_ENTERCANCEL,
1711 error,
1712 wk->hwndFrame,
1713 pszSrcFile,
1714 __LINE__,
1715 GetPString(IDS_DELETEFAILED2TEXT),
1716 wk->li->list[x]) == MBID_CANCEL) {
1717 DosSetVerify(fVerify);
1718 break;
1719 }
1720 }
1721 else {
1722 if (LogFileHandle)
1723 fprintf(LogFileHandle,
1724 GetPString(IDS_DELETEDTEXT), wk->li->list[x]);
1725 sprintf(prompt,
1726 GetPString(IDS_DELETEDTEXT), wk->li->list[x]);
1727 AddNote(prompt);
1728 }
1729 if (//fSyncUpdates ||
1730 AddToList(wk->li->list[x], &files, &numfiles, &numalloc)) {
1731 Broadcast(hab2,
1732 wk->hwndCnr,
1733 UM_UPDATERECORD,
1734 MPFROMP(wk->li->list[x]), MPVOID);
1735 }
1736 } // for
1737 }
1738 if (fVerify)
1739 DosSetVerify(fVerify);
1740 break;
1741 } // switch
1742 if (files) {
1743 Broadcast(hab2,
1744 wk->hwndCnr,
1745 UM_UPDATERECORDLIST, MPFROMP(files), MPVOID);
1746 FreeList(files);
1747 }
1748 if (WinIsWindow(hab2, wk->hwndCnr))
1749 PostMsg(wk->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
1750
1751 WinDestroyMsgQueue(hmq2);
1752 }
1753 DecrThreadUsage();
1754 WinTerminate(hab2);
1755 }
1756 }
1757 FreeListInfo(wk->li);
1758 free(wk);
1759# ifdef FORTIFY
1760 Fortify_LeaveScope();
1761# endif
1762 DosPostEventSem(CompactSem);
1763 }
1764}
1765#pragma alloc_text(MASSACTION,MassAction)
1766#pragma alloc_text(ACTION,Action)
1767#pragma alloc_text(UNDO,FreeUndo,Undo)
Note: See TracBrowser for help on using the repository browser.