source: trunk/dll/worker.c@ 1215

Last change on this file since 1215 was 1215, checked in by John Small, 17 years ago

Ticket 187: Move data declarations/definitions out of fm3dll.h

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