source: trunk/dll/worker.c@ 1863

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

Remove recurse scan code; fix A:\ drive not ready error caused by not moving the cursor from drive A:\ fast enough. Have Flesh remove pcis that have NullStr FileNames.

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