source: trunk/dll/worker.c@ 1485

Last change on this file since 1485 was 1485, checked in by Gregg Young, 16 years ago

Fixed typo

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