source: trunk/dll/worker.c@ 1335

Last change on this file since 1335 was 1335, checked in by Steven Levine, 17 years ago

Ticket 26: Add exception handlers to all threads using xbeginthread

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