source: trunk/dll/worker.c @ 766

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

format cleanup

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