source: trunk/dll/worker.c@ 1458

Last change on this file since 1458 was 1458, checked in by Steven Levine, 16 years ago

Show copy progress counts in Thread notes window
Update window layout help

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