source: trunk/dll/worker.c@ 1666

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

Added an accel key for Unlock;minor code cleanup

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