source: trunk/dll/worker.c@ 1646

Last change on this file since 1646 was 1646, checked in by Gregg Young, 14 years ago

Fix popup file menu extract failure on arc file with spaces in its name. Ticket 481

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