source: trunk/dll/worker.c@ 1803

Last change on this file since 1803 was 1803, checked in by Gregg Young, 10 years ago

Changes to allow a JAVA executable object to be created using "Real object" menu item on a jar file. (Ticket [37]) Eliminate redundant prompts and error messages when telling FM/2 not to delete a R/O file. (Ticket [548]) Limit attempts to unlock files to exes and dlls. (Ticket [549])

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