source: trunk/dll/worker.c@ 1554

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

Check that pTmpDir IsValid and recreate if not found; Fixes hangs caused by temp file creation failures. (Ticket 440)

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