source: trunk/dll/worker.c@ 1402

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

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

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