source: trunk/dll/worker.c@ 1313

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

Improved fix to delete race condition with container updates (Ticket 304)

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