source: trunk/dll/worker.c@ 1181

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

Ticket 187: Draft 2: Move remaining function declarations

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