source: trunk/dll/worker.c@ 1455

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

Blink thread LEDs while worker threads are working
Drop expermental code

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