source: trunk/dll/worker.c@ 1664

Last change on this file since 1664 was 1664, checked in by Gregg Young, 13 years ago

Changes to use Unlock to unlock files if Unlock.exe is in path both from menu/toolbar and as part of copy, move and delete operations. Changes to allow copy and move over readonly files with a warning dialog; also added a warning dialog for delete of readonly files

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