source: trunk/dll/worker.c@ 1351

Last change on this file since 1351 was 1351, checked in by Gregg Young, 17 years ago

Additional code cleanup

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