source: trunk/dll/worker.c@ 1324

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

Turn off fSynUpdates for file moves. This prevents double free warnings.

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