source: trunk/dll/worker.c@ 1228

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

Ticket 187: Moved typedef's and some #define's from fm3dll.h

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