source: trunk/dll/worker.c@ 1158

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

Ticket 187: Draft 1: Functions only

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