source: trunk/dll/worker.c@ 1544

Last change on this file since 1544 was 1544, checked in by Gregg Young, 15 years ago

Changes to fopen and _fsopen to allow FM2 to be loaded in high memory

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