source: trunk/dll/worker.c@ 1438

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

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 46.9 KB
Line 
1
2/***********************************************************************
3
4 $Id: worker.c 1438 2009-06-28 20:47:00Z gyoung $
5
6 Worker thread
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2009 Steven H. Levine
10
11 16 Oct 02 SHL Comments
12 18 Oct 02 SHL MassAction:Archive - force extension so file found
13 06 Jun 05 SHL Indent -i2
14 06 Jun 05 SHL Rework Action for VAC3.65 compat
15 27 Jul 05 SHL IDM_DOITYOURSELF - avoid need to strip in ExecOnList
16 22 Jul 06 SHL Comments
17 22 Jul 06 SHL Check more run time errors
18 03 Nov 06 SHL Renames
19 03 Nov 06 SHL Count thread usage
20 21 Apr 07 GKY Find FM2Utils by path or utils directory
21 16 Jun 07 SHL Update for OpenWatcom
22 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
23 07 Aug 07 SHL Use BldQuotedFileName
24 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
25 26 Aug 07 SHL Revert to DosSleep(0)
26 29 Feb 08 GKY Refactor global command line variables to notebook.h
27 22 Jun 08 GKY Made Felete move to xworkplace trash can on systems that have it
28 16 JUL 08 GKY Use TMP directory for temp files
29 20 Jul 08 GKY Add save/append filename to clipboard.
30 02 Aug 08 GKY Limit use of "trash can" to local writable fixed drives or to trash can supported
31 drives list if it exists. Fix ability to deselect use of trash can.
32 01 Sep 08 GKY Add code to retry on Netdrives "pipe error"
33 04 Dec 08 GKY Add a DosSleep to allow file extract to complete before rescan
34 04 Dec 08 GKY Add mutex semaphore and disable fSyncUpdates for file deletes to prevent the creation
35 on dead CNRITEMS.
36 10 Dec 08 SHL Integrate exception handler support
37 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis
38 25 Dec 08 GKY Add DRIVE_RSCANNED flag to monitor for the first recursive drive scan per session
39 to prevent duplicate directory names in tree following a copy before initial scan.
40 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
41 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
42 08 Mar 09 GKY Additional strings move to PCSZs
43 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
44
45***********************************************************************/
46
47#include <stdlib.h>
48#include <string.h>
49#include <ctype.h>
50#include <share.h>
51#include <process.h> // _beginthread // 10 Dec 08 SHL
52#include <time.h>
53
54#define INCL_DOS
55#define INCL_DOSERRORS
56#define INCL_WINPROGRAMLIST
57#define INCL_WINHELP
58#define INCL_LONGLONG
59#define INCL_WINPOINTERS
60#define INCL_WINWORKPLACE
61#define INCL_WINSHELLDATA
62
63#include "fm3dll.h"
64#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
65#include "mainwnd2.h" // Data declaration(s)
66#include "arccnrs.h" // Data declaration(s)
67#include "init.h" // Data declaration(s)
68#include "defview.h" // Data declaration(s)
69#include "newview.h" // Data declarations
70#include "fm3dlg.h"
71#include "fm3str.h"
72#include "comp.h" // FCOMPARE
73#include "pathutil.h" // BldQuotedFileName
74#include "makelist.h" // AddToList
75#include "errutil.h" // Dos_Error...
76#include "strutil.h" // GetPString
77#include "notebook.h" // External viewers
78#include "worker.h" // Action
79#include "notify.h" // AddNote
80#include "copyf.h" // AdjustWildcardName, make_deleteable
81#include "attribs.h" // AttrListDlgProc
82#include "chklist.h" // CheckListProc
83#include "info.h" // DrvInfoProc
84#include "extract.h" // ExtractDlgProc
85#include "info.h" // FileInfoProc
86#include "valid.h" // GetDesktopName, IsNewer
87#include "saveclip.h" // ListToClipboardHab
88#include "shadow.h" // MakeShadows
89#include "mkdir.h" // MassMkdir
90#include "uudecode.h" // MergeDlgProc
91#include "objcnr.h" // ObjCnrDlgProc
92#include "printer.h" // PrintDlgProc, PrintListThread
93#include "rename.h" // RenameProc
94#include "srchpath.h" // RunFM2Util
95#include "mainwnd.h" // TopWindowName
96#include "uudecode.h" // UUD
97#include "walkem.h" // WalkCopyDlgProc, WalkDlgProc, WalkMoveDlgProc
98#include "archive.h" // ArchiveDlgProc
99#include "misc.h" // Broadcast
100#include "common.h" // DecrThreadUsage, IncrThreadUsage
101#include "eas.h" // DisplayEAsProc
102#include "systemf.h" // ExecOnList
103#include "avl.h" // SBoxDlgProc
104#include "subj.h" // Subject
105#include "stristr.h" // stristr
106#include "wrappers.h" // xfopen
107#include "fortify.h"
108#include "excputil.h" // 06 May 08 SHL added
109
110// Data definitions
111#pragma data_seg(GLOBAL2)
112FILE *LogFileHandle;
113
114#pragma data_seg(DATA2)
115
116static PSZ pszSrcFile = __FILE__;
117
118#ifdef UNDO
119
120static VOID LINFO undo;
121
122VOID FreeUndo(VOID)
123{
124 if (undo->list)
125 FreeList(undo->list);
126 memset(&undo, 0, sizeof(undo));
127}
128
129VOID Undo(HWND hwndCnr, HWND hwndFrame, HWND hwndClient, HWND hwndParent)
130{
131 LISTINFO *li;
132 WORKER *wk;
133
134 if (undo->type && undo->list && undo->list[0]) {
135 switch (undo->type) {
136 case IDM_MOVE:
137 case IDM_COPY:
138 case IDM_EXTRACT:
139 {
140# ifdef FORTIFY
141 Fortify_EnterScope();
142# endif
143 li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
144 if (li) {
145 wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
146 if (wk) {
147 wk->size = sizeof(WORKER);
148 wk->hwndCnr = hwndCnr;
149 wk->hwndParent = hwndParent;
150 wk->hwndFrame = hwndFrame;
151 wk->hwndClient = hwndClient;
152 wk->li = li;
153 *wk->li = *undo;
154 switch (undo->type) {
155 case IDM_COPY:
156 case IDM_EXTRACT:
157 li->type = IDM_PERMDELETE;
158 break;
159 }
160 if (xbeginthread(MassAction,
161 122880,
162 wk,
163 pszSrcFile,
164 __LINE__) == -1)
165 {
166 FreeListInfo(wk->li);
167 free(wk);
168# ifdef FORTIFY
169 Fortify_LeaveScope();
170# endif
171 }
172 }
173 else
174 FreeListInfo(li);
175 }
176 }
177 break;
178 } // switch
179 }
180 FreeUndo();
181# ifdef FORTIFY
182 Fortify_LeaveScope();
183# endif
184}
185
186#endif // defined(UNDO)
187
188VOID Action(VOID * args)
189{
190 WORKER *wk = (WORKER *)args;
191 HAB hab2;
192 HMQ hmq2;
193 CHAR **files = NULL;
194 UINT numfiles = 0, numalloc = 0;
195 INT plen = 0;
196 CHAR *p, *pp;
197 CHAR szQuotedDirName[CCHMAXPATH];
198 CHAR szQuotedFileName[CCHMAXPATH];
199
200
201 if (wk) {
202# ifdef FORTIFY
203 Fortify_EnterScope();
204# endif
205 if (wk->li && wk->li->list && wk->li->list[0]) {
206 hab2 = WinInitialize(0);
207 if (hab2) {
208 hmq2 = WinCreateMsgQueue(hab2, 0);
209 if (hmq2) {
210 CHAR message[(CCHMAXPATH * 2) + 80], wildname[CCHMAXPATH];
211 INT x;
212 BOOL dontask = FALSE, wildcarding = FALSE, overold =
213 FALSE, overnew = FALSE, usedtarget;
214
215 WinCancelShutdown(hmq2, TRUE);
216 IncrThreadUsage();
217 *wildname = 0;
218 switch (wk->li->type) {
219 case IDM_MERGE:
220 if (wk->li->type == IDM_MERGE) {
221 if (TestBinary(wk->li->list[0]))
222 wk->li->type = IDM_MERGEBINARY;
223 else
224 wk->li->type = IDM_MERGETEXT;
225 }
226 strcpy(wk->li->targetpath, wk->li->list[0]);
227 p = strrchr(wk->li->targetpath, '\\');
228 if (p) {
229 p++;
230 *p = 0;
231 }
232 else
233 strcat(wk->li->targetpath, PCSZ_BACKSLASH);
234 sprintf(wk->li->targetpath + strlen(wk->li->targetpath),
235 "MERGE.%03x", (clock() & 4095L));
236 if (!WinDlgBox(HWND_DESKTOP,
237 wk->hwndFrame,
238 MergeDlgProc, FM3ModHandle, MRG_FRAME, (PVOID) wk))
239 goto Abort;
240 if (!wk->li->type ||
241 !*wk->li->targetpath || !wk->li->list || !wk->li->list[0])
242 goto Abort;
243 if (IsFile(wk->li->targetpath) != 1 && !wk->li->list[1]) {
244 saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
245 wk->hwndFrame,
246 GetPString(IDS_AHEMTEXT),
247 GetPString(IDS_SILLYMERGETEXT));
248 goto Abort;
249 }
250 break;
251 case IDM_WILDMOVE:
252 wildcarding = TRUE;
253 wk->li->type = IDM_MOVE;
254 break;
255 case IDM_WILDRENAME:
256 wildcarding = TRUE;
257 wk->li->type = IDM_RENAME;
258 break;
259 case IDM_WILDCOPY:
260 wildcarding = TRUE;
261 wk->li->type = IDM_COPY;
262 break;
263 case IDM_MOVEPRESERVE:
264 {
265 CHAR preserve[CCHMAXPATH], *end;
266
267 wk->li->type = IDM_MOVE;
268 strcpy(preserve, wk->li->list[0] + 2);
269 end = strrchr(preserve, '\\');
270 if (end) {
271 end++;
272 for (x = 1; wk->li->list[x]; x++) {
273 p = preserve;
274 pp = wk->li->list[x] + 2;
275 while (p < end && toupper(*p) == toupper(*pp)) {
276 p++;
277 pp++;
278 }
279 if (*p == '\\')
280 p++;
281 if (p < end)
282 end = p;
283 }
284 *end = 0;
285 }
286 else
287 *preserve = 0;
288 plen = strlen(preserve);
289 if (plen)
290 plen += 2;
291 }
292 break;
293 case IDM_COPYPRESERVE:
294 {
295 CHAR preserve[CCHMAXPATH], *end;
296
297 wk->li->type = IDM_COPY;
298 strcpy(preserve, wk->li->list[0] + 2);
299 end = strrchr(preserve, '\\');
300 if (end) {
301 end++;
302 for (x = 1; wk->li->list[x]; x++) {
303 p = preserve;
304 pp = wk->li->list[x] + 2;
305 while (p < end && toupper(*p) == toupper(*pp)) {
306 p++;
307 pp++;
308 }
309 if (*p == '\\')
310 p++;
311 if (p < end)
312 end = p;
313 }
314 *end = 0;
315 }
316 else
317 *preserve = 0;
318 plen = strlen(preserve);
319 if (plen)
320 plen += 2;
321 }
322 break;
323 }
324 if (wk->li && wk->li->list && wk->li->list[0]) {
325 for (x = 0; wk->li->list[x]; x++) {
326 switch (wk->li->type) {
327 case IDM_COLLECTFROMFILE:
328 if (Collector) {
329
330 CHAR *temp = xstrdup(wk->li->list[x], pszSrcFile, __LINE__);
331
332 if (temp) {
333 if (!PostMsg(Collector,
334 UM_COLLECTFROMFILE, MPFROMP(temp), MPVOID))
335 free(temp);
336 }
337 }
338 break;
339
340 case IDM_MERGEBINARY:
341 case IDM_MERGETEXT:
342 case IDM_MERGEBINARYAPPEND:
343 case IDM_MERGETEXTAPPEND:
344 {
345 FILE *in, *out;
346 CHAR *moder, *modew;
347 int c;
348
349 switch (wk->li->type) {
350 case IDM_MERGEBINARY:
351 moder = "rb";
352 modew = "wb";
353 break;
354 case IDM_MERGEBINARYAPPEND:
355 moder = "rb";
356 modew = "a+b";
357 break;
358 case IDM_MERGETEXTAPPEND:
359 moder = "r";
360 modew = "a+";
361 break;
362 default:
363 moder = "r";
364 modew = "w";
365 break;
366 }
367 in = _fsopen(wk->li->list[x], moder, SH_DENYWR);
368 if (!in) {
369 if (saymsg(MB_ENTERCANCEL,
370 HWND_DESKTOP,
371 GetPString(IDS_MERGEERRORTEXT),
372 GetPString(IDS_CANTOPENINPUTTEXT),
373 wk->li->list[x]) == MBID_CANCEL)
374 goto Abort;
375 }
376 else {
377 out = _fsopen(wk->li->targetpath, modew, SH_DENYWR);
378 if (out) {
379 fseek(out, 0L, SEEK_END);
380 switch (wk->li->type) {
381 case IDM_MERGEBINARY:
382 wk->li->type = IDM_MERGEBINARYAPPEND;
383 break;
384 default:
385 wk->li->type = IDM_MERGETEXTAPPEND;
386 break;
387 }
388 sprintf(message,
389 GetPString(IDS_MERGINGTEXT),
390 wk->li->list[x], wk->li->targetpath);
391 AddNote(message);
392 while ((c = fgetc(in)) != EOF)
393 fputc(c, out);
394 fclose(out);
395 sprintf(message,
396 GetPString(IDS_MERGECOMPLETETEXT),
397 wk->li->list[x], wk->li->targetpath);
398 AddNote(message);
399 }
400 else {
401 saymsg(MB_CANCEL,
402 HWND_DESKTOP,
403 GetPString(IDS_MERGEERRORTEXT),
404 GetPString(IDS_CANTOPENOUTPUTTEXT),
405 wk->li->targetpath);
406 fclose(in);
407 goto Abort;
408 }
409 fclose(in);
410 }
411 }
412 break;
413
414 case IDM_UUDECODE:
415 {
416 CHAR outname[CCHMAXPATH + 2];
417
418 sprintf(message,
419 GetPString(IDS_UUDECODINGTEXT), wk->li->list[x]);
420 AddNote(message);
421 if (UUD(wk->li->list[x], outname) && *outname) {
422 sprintf(message,
423 GetPString(IDS_UUDECODECOMPLETETEXT),
424 wk->li->list[x]);
425 AddNote(message);
426 if (//fSyncUpdates ||
427 AddToList(outname, &files, &numfiles, &numalloc))
428 Broadcast(hab2,
429 wk->hwndCnr,
430 UM_UPDATERECORD, MPFROMP(outname), MPVOID);
431 }
432 else {
433 sprintf(message,
434 GetPString(IDS_UUDECODEABORTEDTEXT),
435 wk->li->list[x]);
436 AddNote(message);
437 }
438 }
439 break;
440
441 case IDM_VIEWARCHIVE:
442 if (IsFile(wk->li->list[x]) > 0) {
443
444 ARC_TYPE *info = NULL; // Say calling for editing - fixme to know why?
445
446 if (WinDlgBox(HWND_DESKTOP,
447 wk->hwndFrame,
448 SBoxDlgProc,
449 FM3ModHandle,
450 ASEL_FRAME, (PVOID) & info) && info) {
451 WinSendMsg(wk->hwndCnr,
452 UM_OPENWINDOWFORME,
453 MPFROMP(wk->li->list[x]), MPFROMP(info));
454 }
455 }
456 break;
457
458 case IDM_EXTRACT:
459 {
460 EXTRDATA ex;
461 BOOL maskspaces = FALSE;
462
463 memset(&ex, 0, sizeof(EXTRDATA));
464 ex.info = find_type(wk->li->list[x], NULL);
465 if (!ex.info || (!ex.info->extract && !ex.info->exwdirs))
466 break;
467 ex.size = sizeof(EXTRDATA);
468 ex.arcname = wk->li->list[x];
469 strcpy(ex.masks, "*");
470 strcpy(ex.extractdir, wk->li->targetpath);
471 if (!WinDlgBox(HWND_DESKTOP,
472 wk->hwndFrame,
473 ExtractDlgProc,
474 FM3ModHandle,
475 EXT_FRAME,
476 (PVOID) & ex) ||
477 !ex.ret ||
478 !*ex.command || !*ex.arcname || !*ex.extractdir)
479 goto Abort;
480 {
481 FILESTATUS3 fsa;
482
483 DosError(FERR_DISABLEHARDERR);
484 if (DosQueryPathInfo(ex.extractdir,
485 FIL_STANDARD,
486 &fsa,
487 (ULONG) sizeof(FILESTATUS3)) ||
488 !(fsa.attrFile & FILE_DIRECTORY))
489 goto Abort;
490 }
491 if (needs_quoting(ex.masks) && !strchr(ex.masks, '\"'))
492 maskspaces = TRUE;
493 if (!runemf2(SEPARATE | WINDOWED | WAIT |
494 fArcStuffVisible ? 0 : (BACKGROUND | MINIMIZED),
495 HWND_DESKTOP, pszSrcFile, __LINE__, ex.extractdir, NULL,
496 "%s %s %s%s%s",
497 ex.command,
498 ex.arcname,
499 maskspaces ? "\"" : NullStr,
500 *ex.masks ? ex.masks : "\"*\"",
501 maskspaces ? "\"" : NullStr) &&
502 !stricmp(ex.extractdir, wk->directory)) {
503 DosSleep(100); // wait for runemf2 to complete so rescan will actually show something
504 if (WinIsWindow((HAB) 0, wk->hwndCnr))
505 WinSendMsg(wk->hwndCnr,
506 WM_COMMAND,
507 MPFROM2SHORT(IDM_RESCAN, 0), MPVOID);
508 }
509 }
510 break;
511
512 case IDM_SUBJECT:
513 {
514 INT ret;
515
516 ret = Subject(wk->hwndFrame, wk->li->list[x]);
517 if (!ret)
518 goto Abort;
519 if (ret == 1) {
520 if (//fSyncUpdates ||
521 AddToList(wk->li->list[x],
522 &files, &numfiles, &numalloc))
523 Broadcast(hab2,
524 wk->hwndCnr,
525 UM_UPDATERECORD,
526 MPFROMP(wk->li->list[x]), MPVOID);
527 }
528 }
529 break;
530
531 case IDM_INFO:
532 if (IsFullName(wk->li->list[x]) &&
533 !(driveflags[toupper(*wk->li->list[x]) - 'A'] &
534 DRIVE_INVALID)) {
535 if (!IsRoot(wk->li->list[x])) {
536
537 CHAR *list[2];
538
539 list[0] = wk->li->list[x];
540 list[1] = NULL;
541 if (!WinDlgBox(HWND_DESKTOP,
542 HWND_DESKTOP,
543 FileInfoProc,
544 FM3ModHandle, FLE_FRAME, (PVOID) list)) {
545 goto Abort;
546 }
547 }
548 else {
549 if (!WinDlgBox(HWND_DESKTOP,
550 HWND_DESKTOP,
551 DrvInfoProc,
552 FM3ModHandle,
553 INFO_FRAME, (PVOID) wk->li->list[x]))
554 goto Abort;
555 }
556 }
557 break;
558
559 case IDM_OPENWINDOW:
560 if (!IsFile(wk->li->list[x]) &&
561 WinIsWindow(hab2, wk->hwndCnr))
562 WinSendMsg(wk->hwndCnr,
563 UM_OPENWINDOWFORME,
564 MPFROMP(wk->li->list[x]), MPVOID);
565 break;
566
567 case IDM_OPENICON:
568 case IDM_OPENDETAILS:
569 case IDM_OPENTREE:
570 {
571 FILESTATUS3 fsa;
572
573 DosError(FERR_DISABLEHARDERR);
574 if (DosQueryPathInfo(wk->li->list[x],
575 FIL_STANDARD,
576 &fsa,
577 (ULONG) sizeof(FILESTATUS3)) ||
578 !(fsa.attrFile & FILE_DIRECTORY))
579 break;
580 }
581 /* else intentional fallthru */
582 case IDM_OPENDEFAULT:
583 case IDM_OPENSETTINGS:
584 {
585 CHAR *s;
586
587 switch (wk->li->type) {
588 case IDM_OPENICON:
589 s = (PSZ) PCSZ_ICON;
590 break;
591 case IDM_OPENDETAILS:
592 s = (PSZ) Details;
593 break;
594 case IDM_OPENTREE:
595 s = (PSZ) PCSZ_TREE;
596 break;
597 case IDM_OPENSETTINGS:
598 s = (PSZ) Settings;
599 break;
600 default:
601 s = (PSZ) Default;
602 break;
603 }
604 OpenObject(wk->li->list[x], s, wk->hwndFrame);
605 }
606 break;
607
608 case IDM_WPSMOVE:
609 case IDM_WPSCOPY:
610 case IDM_MOVE:
611 case IDM_COPY:
612 case IDM_RENAME:
613 {
614
615 if (!*wk->li->targetpath && (wk->li->type == IDM_MOVE ||
616 wk->li->type == IDM_COPY ||
617 wk->li->type == IDM_WPSMOVE ||
618 wk->li->type == IDM_WPSCOPY)) {
619
620 APIRET rc = 1;
621
622 usedtarget = FALSE;
623 if (hwndMain) {
624 if (!*targetdir)
625 TopWindowName(hwndMain,
626 wk->hwndFrame, wk->li->targetpath);
627 else {
628 strcpy(wk->li->targetpath, targetdir);
629 usedtarget = TRUE;
630 }
631 }
632 if (!*wk->li->targetpath)
633 strcpy(wk->li->targetpath, wk->directory);
634 if (!*wk->li->targetpath) {
635 strcpy(wk->li->targetpath, wk->li->list[0]);
636 p = strrchr(wk->li->targetpath, '\\');
637 if (p) {
638 if (*(p - 1) == ':')
639 p++;
640 *p = 0;
641 }
642 }
643 MakeValidDir(wk->li->targetpath);
644 if (fConfirmTarget ||
645 (!*targetdir && strcmp(realappname, "FM/4"))) {
646 RetryPath:
647 usedtarget = FALSE;
648 if (wk->li->type == IDM_MOVE ||
649 wk->li->type == IDM_WPSMOVE) {
650 rc = WinDlgBox(HWND_DESKTOP,
651 wk->hwndFrame,
652 WalkMoveDlgProc,
653 FM3ModHandle,
654 WALK_FRAME, MPFROMP(wk->li->targetpath));
655 }
656 else if (wk->li->type == IDM_COPY ||
657 wk->li->type == IDM_WPSCOPY) {
658 rc = WinDlgBox(HWND_DESKTOP,
659 wk->hwndFrame,
660 WalkCopyDlgProc,
661 FM3ModHandle,
662 WALK_FRAME, MPFROMP(wk->li->targetpath));
663 }
664 else
665 rc = WinDlgBox(HWND_DESKTOP,
666 wk->hwndFrame,
667 WalkDlgProc,
668 FM3ModHandle,
669 WALK_FRAME, MPFROMP(wk->li->targetpath));
670 }
671 if (!rc || !*wk->li->targetpath)
672 goto Abort;
673 if (driveflags[toupper(*wk->li->targetpath) - 'A'] &
674 DRIVE_NOTWRITEABLE) {
675 saymsg(MB_CANCEL,
676 wk->hwndFrame,
677 GetPString(IDS_ERRORTEXT),
678 GetPString(IDS_NOTWRITENOTARGETTEXT));
679 goto RetryPath;
680 }
681 }
682 Retry:
683 {
684 CHAR newname[CCHMAXPATH];
685 PCSZ moving, move, moved;
686 APIRET rc;
687 INT type;
688 FILESTATUS4L fs4;
689 BOOL isnewer, existed, fResetVerify = FALSE;
690
691 type = (wk->li->type == IDM_RENAME) ? MOVE :
692 (wk->li->type == IDM_MOVE) ? MOVE :
693 (wk->li->type == IDM_WPSMOVE) ? WPSMOVE :
694 (wk->li->type == IDM_WPSCOPY) ? WPSCOPY : COPY;
695 moving = (wk->li->type == IDM_RENAME) ?
696 GetPString(IDS_RENAMINGTEXT) :
697 (wk->li->type == IDM_MOVE ||
698 wk->li->type == IDM_WPSMOVE) ?
699 GetPString(IDS_MOVINGTEXT) : GetPString(IDS_COPYINGTEXT);
700 move = (wk->li->type == IDM_RENAME) ?
701 GetPString(IDS_RENAMETEXT) :
702 (wk->li->type == IDM_MOVE ||
703 wk->li->type == IDM_WPSMOVE) ?
704 GetPString(IDS_MOVETEXT) : GetPString(IDS_COPYTEXT);
705 moved = (wk->li->type == IDM_RENAME) ?
706 GetPString(IDS_RENAMEDTEXT) :
707 (wk->li->type == IDM_MOVE ||
708 wk->li->type == IDM_WPSMOVE) ?
709 GetPString(IDS_MOVEDTEXT) : GetPString(IDS_COPIEDTEXT);
710 if (*wk->li->targetpath) {
711 strcpy(newname, wk->li->targetpath);
712 AddBackslashToPath(newname);
713 //if (newname[strlen(newname) - 1] != '\\')
714 // strcat(newname, "\\");
715 if (plen)
716 p = wk->li->list[x] + plen;
717 else {
718 p = strrchr(wk->li->list[x], '\\');
719 if (p)
720 p++;
721 else
722 p = wk->li->list[x];
723 }
724 strcat(newname, p);
725 }
726 else
727 strcpy(newname, wk->li->list[x]);
728 if ((wildcarding || wk->li->type == IDM_RENAME) &&
729 *wildname) {
730
731 CHAR testname[CCHMAXPATH];
732
733 strcpy(testname, wildname);
734 if (AdjustWildcardName(newname, testname))
735 strcpy(newname, testname);
736 }
737 existed = (IsFile(newname) != -1);
738 isnewer = IsNewer(wk->li->list[x], newname);
739 if (existed && wk->li->type != IDM_RENAME && dontask) {
740 if (!overold && !overnew)
741 break;
742 if (!overold && !isnewer)
743 break;
744 if (!overnew && isnewer)
745 break;
746 }
747 if ((wk->li->type == IDM_RENAME &&
748 (!dontask || !*wildname)) ||
749 (!dontask && existed) ||
750 (!dontask && wildcarding) ||
751 (IsFile(newname) == 0 && IsFile(wk->li->list[x]) > 0)) {
752
753 MOVEIT mv;
754
755 memset(&mv, 0, sizeof(MOVEIT));
756 mv.rename = (wk->li->type == IDM_RENAME);
757 mv.source = wk->li->list[x];
758 strcpy(mv.target, newname);
759 rc = WinDlgBox(HWND_DESKTOP,
760 wk->hwndFrame,
761 RenameProc,
762 FM3ModHandle, REN_FRAME, (PVOID) & mv);
763 if (!rc)
764 goto Abort;
765 DosSleep(1);
766 if (mv.skip || !*mv.target)
767 break;
768 if (mv.dontask)
769 dontask = TRUE;
770 if (mv.overold)
771 overold = TRUE;
772 if (mv.overnew)
773 overnew = TRUE;
774 if (wildcarding || wk->li->type == IDM_RENAME) {
775 p = strrchr(mv.target, '\\');
776 if (p && (strchr(p, '*') || strchr(p, '?'))) {
777 strcpy(wildname, mv.target);
778 AdjustWildcardName(wk->li->list[x], mv.target);
779 }
780 else
781 *wildname = 0;
782 }
783 strcpy(newname, mv.target);
784 existed = (IsFile(newname) != -1);
785 isnewer = IsNewer(wk->li->list[x], newname);
786 if (!mv.overwrite) {
787 if (existed && wk->li->type != IDM_RENAME && dontask) {
788 if (!overold && !overnew)
789 break;
790 if (!overold && !isnewer)
791 break;
792 if (!overnew && isnewer)
793 break;
794 }
795 }
796 }
797 if (!strcmp(wk->li->list[x], newname) ||
798 (wk->li->type == IDM_COPY &&
799 !stricmp(wk->li->list[x], newname)))
800 break;
801 sprintf(message,
802 " %s \"%s\" %s\"%s\"%s",
803 moving,
804 wk->li->list[x],
805 GetPString(IDS_TOTEXT),
806 newname,
807 (usedtarget) ? GetPString(IDS_TOTARGETTEXT) :
808 NullStr);
809 AddNote(message);
810 if (fVerify && (driveflags[toupper(*wk->li->targetpath) - 'A'] & DRIVE_WRITEVERIFYOFF) |
811 (driveflags[toupper(*wk->li->list[x]) - 'A'] & DRIVE_WRITEVERIFYOFF)) {
812 DosSetVerify(FALSE);
813 fResetVerify = TRUE;
814 }
815 if (plen) {
816 /* make directory/ies, if required */
817
818 CHAR dirpart[CCHMAXPATH];
819
820 strcpy(dirpart, newname);
821 p = strrchr(dirpart, '\\');
822 if (p) {
823 *p = 0;
824 if (p > dirpart + 3)
825 MassMkdir((hwndMain) ? hwndMain : wk->hwndCnr,
826 dirpart);
827 }
828 }
829 if (fRealIdle)
830 priority_idle();
831 rc = docopyf(type, wk->li->list[x], newname);
832 if (fResetVerify) {
833 DosSetVerify(fVerify);
834 fResetVerify = FALSE;
835 }
836 priority_normal();
837 if (rc) {
838 if ((rc == ERROR_DISK_FULL ||
839 rc == ERROR_HANDLE_DISK_FULL) &&
840 isalpha(*newname) &&
841 (driveflags[toupper(*newname) - 'A'] &
842 DRIVE_REMOVABLE)
843 && !(driveflags[toupper(*newname) - 'A'] &
844 DRIVE_NOTWRITEABLE)
845 && toupper(*newname) != toupper(*wk->li->list[x])
846 && !DosQueryPathInfo(wk->li->list[x], FIL_QUERYEASIZEL,
847 &fs4, sizeof(fs4))
848 && !(fs4.attrFile & FILE_DIRECTORY)) {
849
850 FSALLOCATE fsa;
851 ULONGLONG ullFreeBytes;
852 CHAR *ptr;
853 INT cntr;
854
855 Notify(GetPString(IDS_FITTINGTEXT));
856 DosError(FERR_DISABLEHARDERR);
857 if (!DosQueryFSInfo(toupper(*newname) - '@',
858 FSIL_ALLOC,
859 &fsa, sizeof(FSALLOCATE))) {
860 // Assume large file support
861 ullFreeBytes = (ULONGLONG) fsa.cUnitAvail * fsa.cSectorUnit *
862 fsa.cbSector;
863 if (ullFreeBytes) {
864 // Find item that will fit in available space
865 for (cntr = x + 1; wk->li->list[cntr]; cntr++) {
866 DosError(FERR_DISABLEHARDERR);
867 if (!DosQueryPathInfo(wk->li->list[cntr],
868 FIL_QUERYEASIZEL,
869 &fs4,
870 sizeof(fs4)) &&
871 !(fs4.attrFile & FILE_DIRECTORY) &&
872 // fixme to use CBLIST_TO_EASIZE?
873 fs4.cbFile + fs4.cbList <= ullFreeBytes) {
874 // Swap with failing item
875 ptr = wk->li->list[x];
876 wk->li->list[x] = wk->li->list[cntr];
877 wk->li->list[cntr] = ptr;
878 goto Retry;
879 }
880 }
881 Notify(GetPString(IDS_COULDNTFITTEXT));
882 }
883 }
884 rc = saymsg(MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION,
885 wk->hwndFrame,
886 GetPString(IDS_DISKFULLTEXT),
887 GetPString(IDS_ANOTHERDISKTEXT));
888 if (rc == MBID_RETRY)
889 goto Retry;
890 if (rc == MBID_ABORT)
891 goto Abort;
892 }
893 else {
894 if (LogFileHandle)
895 fprintf(LogFileHandle,
896 GetPString(IDS_LOGTOFAILEDTEXT),
897 move, wk->li->list[x], newname, rc);
898 rc = Dos_Error(MB_ENTERCANCEL,
899 rc,
900 wk->hwndFrame,
901 pszSrcFile,
902 __LINE__,
903 "%s %s \"%s\" %s\"%s\" %s.",
904 move,
905 GetPString(IDS_OFTEXT),
906 wk->li->list[x],
907 GetPString(IDS_TOTEXT),
908 newname, GetPString(IDS_FAILEDTEXT));
909 if (rc == MBID_CANCEL)
910 goto Abort;
911 }
912 }
913 else {
914 if (LogFileHandle)
915 fprintf(LogFileHandle,
916 "%s \"%s\" %s\"%s\"\n",
917 moved,
918 wk->li->list[x],
919 GetPString(IDS_TOTEXT), newname);
920 if ((driveflags[*wk->li->targetpath - 'A'] & DRIVE_RSCANNED) &&
921 AddToList(wk->li->list[x],
922 &files, &numfiles, &numalloc))
923 Broadcast(hab2,
924 wk->hwndCnr,
925 UM_UPDATERECORD,
926 MPFROMP(wk->li->list[x]), MPVOID);
927 if ((driveflags[*wk->li->targetpath - 'A'] & DRIVE_RSCANNED) &&
928 AddToList(newname, &files, &numfiles, &numalloc))
929 Broadcast(hab2,
930 wk->hwndCnr,
931 UM_UPDATERECORD, MPFROMP(newname), MPVOID);
932 }
933 }
934 break;
935 }
936
937 case IDM_COMPARE:
938 if ((!IsFile(wk->li->targetpath) ||
939 IsRoot(wk->li->targetpath)) &&
940 (!IsFile(wk->li->list[x]) || IsRoot(wk->li->list[x]))) {
941 if (!*dircompare && WinIsWindow(hab2, wk->hwndCnr))
942 WinSendMsg(wk->hwndCnr,
943 UM_COMPARE,
944 MPFROMP(wk->li->targetpath),
945 MPFROMP(wk->li->list[x]));
946 else {
947 runemf2(SEPARATE,
948 HWND_DESKTOP, pszSrcFile, __LINE__,
949 NULL, NULL,
950 "%s %s %s",
951 dircompare,
952 BldQuotedFileName(szQuotedDirName, wk->li->targetpath),
953 BldQuotedFileName(szQuotedFileName, wk->li->list[x]));
954 }
955 }
956 else if (*compare) {
957 CHAR *fakelist[3];
958
959 fakelist[0] = wk->li->list[x];
960 fakelist[1] = wk->li->targetpath;
961 fakelist[2] = NULL;
962 ExecOnList(wk->hwndFrame,
963 compare,
964 WINDOWED | SEPARATEKEEP, NULL, fakelist, NULL,
965 pszSrcFile, __LINE__);
966 }
967 else {
968 FCOMPARE fc;
969
970 memset(&fc, 0, sizeof(fc));
971 fc.size = sizeof(fc);
972 fc.hwndParent = wk->hwndParent;
973 strcpy(fc.file1, wk->li->list[x]);
974 strcpy(fc.file2, wk->li->targetpath);
975 if (WinDlgBox(HWND_DESKTOP,
976 wk->hwndFrame,
977 CFileDlgProc,
978 FM3ModHandle, FCMP_FRAME, (PVOID) & fc))
979 goto Abort;
980 }
981 break;
982 } // switch
983 DosSleep(0);
984 } // for list
985
986 switch (wk->li->type) {
987 case IDM_MOVE:
988 case IDM_COPY:
989 case IDM_WPSMOVE:
990 case IDM_WPSCOPY:
991 case IDM_RENAME:
992 sprintf(message,
993 GetPString(IDS_OPSCOMPLETETEXT),
994 (wk->li->type == IDM_MOVE) ?
995 GetPString(IDS_MOVETEXT) :
996 (wk->li->type == IDM_COPY) ?
997 GetPString(IDS_COPYTEXT) :
998 (wk->li->type == IDM_WPSMOVE) ?
999 GetPString(IDS_WPSMOVETEXT) :
1000 (wk->li->type == IDM_WPSCOPY) ?
1001 GetPString(IDS_WPSCOPYTEXT) :
1002 GetPString(IDS_RENAMETEXT),
1003 &"s"[x == 1],
1004 (wk->li->type == IDM_MOVE ||
1005 wk->li->type == IDM_COPY ||
1006 wk->li->type == IDM_WPSMOVE ||
1007 wk->li->type == IDM_WPSCOPY) ?
1008 GetPString(IDS_TOTEXT) :
1009 NullStr,
1010 (wk->li->type == IDM_MOVE ||
1011 wk->li->type == IDM_COPY ||
1012 wk->li->type == IDM_WPSMOVE ||
1013 wk->li->type == IDM_WPSCOPY) ?
1014 wk->li->targetpath :
1015 NullStr,
1016 (x != 1) ?
1017 GetPString(IDS_ARETEXT) : GetPString(IDS_ISTEXT));
1018 Notify(message);
1019 if (toupper(*wk->li->targetpath) < 'C' && !fAlertBeepOff)
1020 DosBeep(1000, 25); // Wake up user
1021 DosSleep(16);//05 Aug 07 GKY 33
1022 if (wk->li->type == IDM_WPSMOVE || wk->li->type == IDM_WPSCOPY)
1023 DosSleep(48);//05 Aug 07 GKY 96
1024 break;
1025 default:
1026 break;
1027 }
1028 }
1029
1030 Abort:
1031
1032 if (files) {
1033 if (driveflags[*wk->li->targetpath - 'A'] & DRIVE_RSCANNED)
1034 Broadcast(hab2,
1035 wk->hwndCnr,
1036 UM_UPDATERECORDLIST, MPFROMP(files), MPVOID);
1037 FreeList(files);
1038 }
1039
1040 if (WinIsWindow(hab2, wk->hwndCnr))
1041 PostMsg(wk->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
1042
1043 WinDestroyMsgQueue(hmq2);
1044 }
1045 DecrThreadUsage();
1046 WinTerminate(hab2);
1047 }
1048 }
1049
1050 if (wk->li)
1051 FreeListInfo(wk->li);
1052 free(wk);
1053# ifdef FORTIFY
1054 Fortify_LeaveScope();
1055# endif
1056 DosPostEventSem(CompactSem);
1057 }
1058}
1059
1060VOID MassAction(VOID * args)
1061{
1062 WORKER *wk = (WORKER *) args;
1063 HAB hab2;
1064 HMQ hmq2;
1065 CHAR **files = NULL;
1066 register CHAR *p, *pp;
1067 UINT numfiles = 0, numalloc = 0;
1068
1069
1070 if (wk) {
1071# ifdef FORTIFY
1072 // Fortify_BecomeOwner(wk);
1073 Fortify_EnterScope();
1074# endif
1075 if (wk->li && wk->li->list && wk->li->list[0]) {
1076 hab2 = WinInitialize(0);
1077 if (hab2) {
1078 hmq2 = WinCreateMsgQueue(hab2, 0);
1079 if (hmq2) {
1080 WinCancelShutdown(hmq2, TRUE);
1081 IncrThreadUsage();
1082 DosError(FERR_DISABLEHARDERR);
1083 if (IsRoot(wk->li->list[0]) || !IsFile(wk->li->list[0])) {
1084 if (wk->li->type == IDM_VIEW)
1085 wk->li->type = IDM_INFO;
1086 if (wk->li->type == IDM_EDIT)
1087 wk->li->type = IDM_EAS;
1088 }
1089 switch (wk->li->type) {
1090 case IDM_INFO:
1091 if (WinDlgBox(HWND_DESKTOP,
1092 wk->hwndFrame,
1093 FileInfoProc,
1094 FM3ModHandle, FLE_FRAME, (PVOID) wk->li->list) != 2)
1095 {
1096 break;
1097 }
1098 /* else intentional fallthru */
1099 case IDM_UPDATE:
1100 Broadcast(hab2,
1101 wk->hwndCnr,
1102 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1103 break;
1104
1105 case IDM_EAS:
1106 if (WinDlgBox(HWND_DESKTOP,
1107 wk->hwndFrame,
1108 DisplayEAsProc,
1109 FM3ModHandle, EA_FRAME, (PVOID) wk->li->list))
1110 Broadcast(hab2,
1111 wk->hwndCnr,
1112 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1113 break;
1114
1115 case IDM_DOITYOURSELF:
1116 ExecOnList(wk->hwndFrame,
1117 "%a",
1118 WINDOWED | SEPARATE | PROMPT,
1119 NULL, wk->li->list, GetPString(IDS_DOITYOURSELFTEXT),
1120 pszSrcFile, __LINE__);
1121 break;
1122
1123 case IDM_MCIPLAY:
1124 {
1125 INT x, MaxFM2playStrLen = 24;
1126 ULONG total;
1127 CHAR fbuf[CCHMAXPATH];
1128
1129 if (DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT |
1130 SEARCH_CUR_DIRECTORY,
1131 PCSZ_PATH, PCSZ_FM2PLAYEXE, (PBYTE)fbuf, CCHMAXPATH - 1))
1132 total += MaxFM2playStrLen;
1133 else
1134 total = strlen(fbuf);
1135 for (x = 0; wk->li->list[x]; x++)
1136 total += (strlen(wk->li->list[x]) + 1 +
1137 (needs_quoting(wk->li->list[x]) * 2));
1138 if (total > 1000) {
1139
1140 FILE *fp;
1141 CHAR szTempFile[CCHMAXPATH];
1142
1143 BldFullPathName(szTempFile, pTmpDir, PCSZ_FM2PLAYTEMP);
1144 fp = xfopen(szTempFile, "w", pszSrcFile, __LINE__);
1145 if (fp) {
1146 fprintf(fp, "%s", ";AV/2-built FM2Play listfile\n");
1147 for (x = 0; wk->li->list[x]; x++)
1148 fprintf(fp, "%s\n", wk->li->list[x]);
1149 fprintf(fp, ";end\n");
1150 fclose(fp);
1151 strrev(szTempFile);
1152 strcat(szTempFile, "@/");
1153 strrev(szTempFile);
1154 RunFM2Util(PCSZ_FM2PLAYEXE, szTempFile);
1155 }
1156 }
1157 }
1158 /* intentional fallthru */
1159 case IDM_FAKEEXTRACT:
1160 case IDM_FAKEEXTRACTM:
1161 if (wk->li->type == IDM_MCIPLAY ||
1162 (*wk->li->arcname && wk->li->info &&
1163 wk->li->info->extract && *wk->li->targetpath)) {
1164
1165 CHAR szBuffer[1025];
1166 CHAR fbuf[CCHMAXPATH];
1167 register INT x;
1168
1169 if (wk->li->type == IDM_FAKEEXTRACT ||
1170 wk->li->type == IDM_FAKEEXTRACTM) {
1171 strcpy(szBuffer,
1172 (wk->li->info->exwdirs) ?
1173 wk->li->info->exwdirs : wk->li->info->extract);
1174 strcat(szBuffer, " ");
1175 BldQuotedFileName(szBuffer + strlen(szBuffer), wk->li->arcname);
1176 }
1177 else {
1178 if (DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT |
1179 SEARCH_CUR_DIRECTORY,
1180 PCSZ_PATH, PCSZ_FM2PLAYEXE, (PBYTE)fbuf, CCHMAXPATH - 1))
1181 strcpy(szBuffer, "UTILS\\FM2PLAY.EXE");
1182 else
1183 strcpy(szBuffer, PCSZ_FM2PLAYEXE);
1184 }
1185 p = &szBuffer[strlen(szBuffer)];
1186 strcat(szBuffer, " ");
1187 x = 0;
1188 while (wk->li->list[x]) {
1189 pp = wk->li->list[x];
1190 while (*pp) {
1191 if (*pp == '/')
1192 *pp = '\\';
1193 pp++;
1194 }
1195 BldQuotedFileName(szBuffer + strlen(szBuffer), wk->li->list[x]);
1196 x++;
1197 if (!wk->li->list[x] || strlen(szBuffer) +
1198 strlen(wk->li->list[x]) + 5 > 1024) {
1199 runemf2(SEPARATE | WINDOWED | BACKGROUND | MINIMIZED | WAIT,
1200 HWND_DESKTOP, pszSrcFile, __LINE__,
1201 (wk->li->type == IDM_FAKEEXTRACT ||
1202 wk->li->type == IDM_FAKEEXTRACTM) ?
1203 wk->li->targetpath : NULL,
1204 NULL,
1205 "%s", szBuffer);
1206 DosSleep(1);
1207 *p = 0;
1208 }
1209 strcat(szBuffer, " ");
1210 }
1211 if (wk->li->type == IDM_MCIPLAY)
1212 break;
1213 strcpy(szBuffer, wk->li->targetpath);
1214 AddBackslashToPath(wk->li->targetpath);
1215 //if (wk->li->targetpath[strlen(wk->li->targetpath) - 1] != '\\')
1216 // strcat(szBuffer, "\\");
1217 p = szBuffer + strlen(szBuffer);
1218 for (x = 0; wk->li->list[x]; x++) {
1219 strcpy(p, wk->li->list[x]);
1220 free(wk->li->list[x]);
1221 wk->li->list[x] = xstrdup(szBuffer, pszSrcFile, __LINE__);
1222 }
1223 if (wk->li->list[0])
1224 Broadcast(hab2,
1225 wk->hwndCnr,
1226 UM_UPDATERECORDLIST, MPFROMP(wk->li->list), MPVOID);
1227 }
1228 break;
1229
1230 case IDM_SETICON:
1231 if (*wk->li->targetpath) {
1232
1233 ICONINFO ici;
1234
1235 memset(&ici, 0, sizeof(ICONINFO));
1236 ici.cb = sizeof(ICONINFO);
1237 ici.fFormat = ICON_FILE;
1238 ici.pszFileName = wk->li->list[0];
1239 if (!WinSetFileIcon((PSZ) wk->li->targetpath,
1240 (PICONINFO) & ici)) {
1241 ici.fFormat = ICON_CLEAR;
1242 WinSetFileIcon((PSZ) wk->li->targetpath, (PICONINFO) & ici);
1243 }
1244 Broadcast(hab2,
1245 wk->hwndCnr,
1246 UM_UPDATERECORD, MPFROMP(wk->li->targetpath), MPVOID);
1247 }
1248 break;
1249
1250 case IDM_APPENDTOCLIP:
1251 case IDM_SAVETOCLIP:
1252 case IDM_SAVETOCLIPFILENAME:
1253 case IDM_APPENDTOCLIPFILENAME:
1254 ListToClipboardHab(hab2,
1255 wk->li->list,
1256 wk->li->type);
1257 break;
1258
1259 case IDM_ARCHIVEM:
1260 case IDM_ARCHIVE:
1261 {
1262 DIRCNRDATA ad;
1263 CHAR szBuffer[1025];
1264 ARC_TYPE *info = NULL;
1265 char *pch;
1266 register INT x;
1267
1268 memset(&ad, 0, sizeof(DIRCNRDATA));
1269 strcpy(ad.arcname, wk->li->targetpath);
1270 if (*wk->li->targetpath && IsFile(wk->li->targetpath) > 0) {
1271 info = find_type(wk->li->targetpath, NULL);
1272 ad.namecanchange = 0;
1273 }
1274 else {
1275 if (*wk->li->targetpath && !IsFile(wk->li->targetpath))
1276 AddBackslashToPath(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 AddBackslashToPath(ad.arcname);
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) && !fAlertBeepOff)
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 != '\\') ? PCSZ_BACKSLASH : 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.