source: trunk/dll/worker.c@ 1822

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

Fix failure to show error message when delete of a locked non-exe/dll fails. Ticket [552]

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