source: trunk/dll/comp.c@ 1878

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

Remove some dead code and comments source files starting with A-D

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 104.2 KB
RevLine 
[1335]1
[76]2/***********************************************************************
3
4 $Id: comp.c 1878 2015-10-11 22:24:39Z gyoung $
5
6 Compare directories
7
8 Copyright (c) 1993-02 M. Kimes
[1683]9 Copyright (c) 2003, 2013 Steven H. Levine
[76]10
[145]11 16 Oct 02 MK Baseline
12 04 Nov 03 SHL Force window refresh after subdir toggle
13 01 Aug 04 SHL Rework lstrip/rstrip usage
14 24 May 05 SHL Rework Win_Error usage
[157]15 24 May 05 SHL Rework for CNRITEM.szSubject
16 25 May 05 SHL Rework with ULONGLONG
[199]17 06 Jun 05 SHL Drop unused
[362]18 12 Jul 06 SHL Renames and comments
19 13 Jul 06 SHL Use Runtime_Error
[366]20 26 Jul 06 SHL Drop unreachable CN_... code
[406]21 29 Jul 06 SHL Use xfgets_bstripcr
[448]22 15 Aug 06 SHL Turn off hide not selected on dir change
[517]23 19 Oct 06 SHL Correct . and .. detect
[535]24 03 Nov 06 SHL Count thread usage
[574]25 22 Mar 07 GKY Use QWL_USER
[742]26 29 Jul 07 SHL Use Win_Error to report container errors
[748]27 01 Aug 07 SHL Rework to sync with CNRITEM mods
28 01 Aug 07 SHL Rework to remove vast amount of duplicate code
[756]29 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
[773]30 06 Aug 07 SHL Move BldFullPathName here to be near primary caller
31 07 Aug 07 SHL COMP_COLLECT: Avoid collecting empty entries when nothing selected
[775]32 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
[783]33 13 Aug 07 SHL Sync code with other FilesToGet usage
34 13 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
[790]35 20 Aug 07 SHL Correct remaining pcil/pcir typos (we hope)
36 20 Aug 07 SHL Revert to DosSleep(0)
37 20 Aug 07 SHL Use GetMSecTimer for timing
[846]38 20 Aug 07 SHL A few more speed up tweaks. Some experimental timing code
[814]39 26 Aug 07 GKY DosSleep(1) in loops changed to (0)
[846]40 27 Sep 07 SHL Correct ULONGLONG size formatting
[897]41 30 Dec 07 GKY Use TestCDates for compare by file date/time
[907]42 04 Jan 08 SHL Avoid traps if CM_ALLOCRECORD returns less that requested
43 05 Jan 08 SHL Use WM_TIMER for progress messaging
44 05 Jan 08 SHL Use ITIMER_DESC for hogging control
[919]45 12 Jan 08 SHL Correct select count display regression
[924]46 12 Jan 08 SHL Localize SpecialSelect here and rename
47 12 Jan 08 SHL Use SleepIfNeeded
48 12 Jan 08 SHL Reduce/eliminate more DosSleep calls
[929]49 16 Jan 08 SHL Update total/select counts with WM_TIMER only
50 17 Jan 08 SHL Change hide not selected button to 3 state
51 18 Jan 08 SHL Honor filters in actions
[938]52 20 Jan 08 GKY Compare dialog now saves and restores size and position
[985]53 29 Feb 08 GKY Use xfree where appropriate
54 29 Feb 08 GKY Refactor global command line variables to notebook.h
[1000]55 16 Mar 08 GKY Prevent trap caused by files that exceed maxpath length
[1065]56 11 Jul 08 JBS Ticket 230: Simplified code and eliminated some local variables by incorporating
[1175]57 all the details view settings (both the global variables and those in the
58 DIRCNRDATA struct) into a new struct: DETAILS_SETTINGS.
59 08 Sep 08 SHL Avoid aliased pszLongName pointer in ActionCnrThread IDM_MOVE
[1335]60 10 Dec 08 SHL Integrate exception handler support
[1358]61 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis.
[1391]62 11 Jan 09 GKY Replace font names in the string file with global set at compile in init.c
[1395]63 07 Feb 09 GKY Add *DateFormat functions to format dates based on locale
[1400]64 08 Mar 09 GKY Renamed commafmt.h i18nutil.h
[1402]65 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
66 08 Mar 09 GKY Additional strings move to PCSZs in init.c & String Table
[1409]67 15 Mar 09 GKY Use WriteDetailsSwitchs to save detail switch changes to the ini file.
[1438]68 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
[1444]69 13 Jul 09 SHL Sync with renames
[1469]70 26 Sep 09 SHL Don't hide if nothing selected
71 27 Sep 09 SHL Support AND'ed selections
72 27 Sep 09 SHL Rework CompSelect for size and speed
73 27 Sep 09 SHL Allow fast cancel
74 27 Sep 09 SHL Drop unused reset logic
[1498]75 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
[1545]76 23 Oct 10 GKY Add ForwardslashToBackslash function to streamline code
[1563]77 29 May 11 SHL Rework >65K records logic - prior fix was not quite right
[1570]78 12 Jun 11 GKY Added SleepIfNeeded in the container fill loop
[1655]79 02 Jan 12 GKY Added pszFmtFileSize to container info to fix loss of file sizes on move and copy.
[1670]80 12 Aug 12 GKY Add ability to change and save PresParam
81 12 Aug 12 GKY Fix loading of a list file in the right compare container
82 12 Aug 12 GKY Allow for selection of include subdirectories or a list file on initial startup of compare dirs
[1681]83 05 Jan 13 GKY Fix snapshot file to actually load and save (with/without subdirectories) properly.
84 05 Jan 13 GKY Toggle of include subdirectories leaves snapshot file loaded.
85 05 Jan 13 GKY Added an indicator (textbox) that a list (snapshot) file is loaded.
[1682]86 06 Jan 13 GKY Added optional confirmation dialogs for delete move and copy to compare dir Ticket 277
87 06 Jan 13 GKY Added EA compare option to compare dir Ticket 80
[1683]88 06 Mar 13 SHL ActionCnrThread: need to strdup pszFmtFileSize to avoid aliased pointers
[1684]89 09 Mar 13 SHL SetButtonEnables: correct enable support for newish buttons
[1686]90 10 Mar 13 GKY Improvrd readonly check on delete to allow cancel and don't ask again options
91 Added saymsg2 for this purpose
92 10 Mar 13 GKY Fixes to snapshot file.
[1836]93 14 Jun 15 GKY Changes to prvenet access violations when cmp is freed
[76]94
95***********************************************************************/
96
[907]97#include <stdlib.h>
98#include <string.h>
99#include <share.h>
100#include <io.h>
[1354]101#include <ctype.h>
[1563]102#include <limits.h> // USHRT_MAX
[907]103
[2]104#define INCL_DOS
105#define INCL_WIN
[783]106#define INCL_DOSERRORS
[2]107#define INCL_GPI
[157]108#define INCL_LONGLONG
[2]109
[1179]110#include "fm3dll.h"
[1221]111#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
[1205]112#include "mainwnd2.h" // Data declaration(s)
113#include "inis.h" // Data declaration(s)
114#include "init.h" // Data declaration(s)
115#include "newview.h" // Data declarations
[2]116#include "fm3dlg.h"
117#include "fm3str.h"
[907]118#include "pathutil.h" // BldFullPathName
119#include "filldir.h" // EmptyCnr...
120#include "makelist.h" // AddToFileList...
121#include "errutil.h" // Dos_Error...
122#include "strutil.h" // GetPString
123#include "tmrsvcs.h" // IsITimerExpired
124#include "comp.h"
[1179]125#include "misc.h" // AddToListboxBottom, AdjustCnrColRO, AdjustCnrColVis,
126 // AdjustCnrColsForPref, CurrentRecord,
[1175]127 // AdjustDetailsSwitches, LoadDetailsSwitches, SetCnrCols
128 // SetDetailsSwitches
[1179]129#include "select.h" // Deselect, Deselect, InvertAll
[1157]130#include "mkdir.h" // MassMkdir
131#include "valid.h" // TestCDates
132#include "walkem.h" // WalkTwoCmpDlgProc
[1179]133#include "common.h" // DecrThreadUsage, IncrThreadUsage
134#include "defview.h" // DefaultViewKeys
135#include "draglist.h" // DoFileDrag
136#include "systemf.h" // ExecOnList
137#include "filter.h" // Filter
138#include "mainwnd.h" // GetNextWindowPos
139#include "shadow.h" // OpenObject
140#include "chklist.h" // PopupMenu
141#include "presparm.h" // SetPresParams
142#include "collect.h" // StartCollector
143#include "subj.h" // Subject
144#include "copyf.h" // docopyf
145#include "getnames.h" // export_filename
146#include "wrappers.h" // xDosFindNext
[1175]147#include "notebook.h" // External compare/dircompare
[1400]148#include "i18nutil.h" // CommaFmtULL
[1335]149#include "fortify.h" // 06 May 08 SHL added
150#include "excputil.h" // xbeginthread
[1469]151#include "info.h" // driveflags
[1682]152#include "worker.h" // MOVEIT
153#include "rename.h" // RenameProc
[1009]154
[551]155typedef struct
156{
157 CHAR filename[CCHMAXPATH];
158 CHAR dirname[CCHMAXPATH];
159 BOOL recurse;
160}
161SNAPSTUFF;
[2]162
[1205]163// Data definitions
[362]164static PSZ pszSrcFile = __FILE__;
165
[1205]166#pragma data_seg(GLOBAL1)
167BOOL fSelectedAlways;
168
[1469]169/**
170 * Write directory tree to snapshot file; recurse if requested
171 */
[2]172
[783]173static VOID SnapShot(char *path, FILE *fp, BOOL recurse)
[157]174{
[841]175 PFILEFINDBUF4L pffb;
[551]176 char *mask, *enddir;
177 HDIR hdir = HDIR_CREATE;
[783]178 ULONG ulFindCnt;
[1685]179 //CHAR szDate[DATE_BUF_BYTES];
[2]180
[1682]181 // 13 Aug 07 SHL fixme to use FileToGet
[841]182 pffb = xmalloc(sizeof(FILEFINDBUF4L), pszSrcFile, __LINE__);
[783]183 if (pffb) {
[551]184 mask = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
185 if (mask) {
[783]186 BldFullPathName(mask, path, "*");
[551]187 enddir = strrchr(mask, '\\');
[2]188 enddir++;
[783]189 ulFindCnt = 1;
190 // 13 Aug 07 SHL fixme to report errors
[838]191 if (!xDosFindFirst(mask,
[907]192 &hdir,
[838]193 FILE_NORMAL | FILE_DIRECTORY |
194 FILE_ARCHIVED | FILE_READONLY | FILE_HIDDEN |
195 FILE_SYSTEM,
[841]196 pffb, sizeof(FILEFINDBUF4L), &ulFindCnt, FIL_QUERYEASIZEL)) {
[551]197 do {
[783]198 strcpy(enddir, pffb->achName);
[1469]199 if (!(pffb->attrFile & FILE_DIRECTORY)) {
[1685]200 //FDateFormat(szDate, pffb->fdateLastWrite);
[551]201 fprintf(fp,
[1685]202 "\"%s\",%u,%llu,%lu/%lu/%lu,%02u:%02u:%02u,%lu,%lu,N\n",
[551]203 mask,
204 enddir - mask,
[1685]205 pffb->cbFile,
206 pffb->fdateLastWrite.year + 1980,
207 pffb->fdateLastWrite.month,
208 pffb->fdateLastWrite.day,
[1469]209 pffb->ftimeLastWrite.hours,
210 pffb->ftimeLastWrite.minutes,
[783]211 pffb->ftimeLastWrite.twosecs,
[846]212 pffb->attrFile,
[1469]213 pffb->cbList > 4 ? pffb->cbList / 2 : 0);
214 }
[517]215 // Skip . and ..
[551]216 else if (recurse &&
[783]217 (pffb->achName[0] != '.' ||
218 (pffb->achName[1] &&
219 (pffb->achName[1] != '.' || pffb->achName[2])))) {
[551]220 SnapShot(mask, fp, recurse);
221 }
[783]222 ulFindCnt = 1;
[850]223 } while (!xDosFindNext(hdir, pffb, sizeof(FILEFINDBUF4L), &ulFindCnt, FIL_QUERYEASIZEL));
[551]224 DosFindClose(hdir);
[2]225 }
[1039]226 free(mask);
[2]227 }
[1039]228 free(pffb);
[2]229 }
230}
231
[1469]232/**
233 * Write snapshot file thread
234 * Write directory tree to snapshot file
235 */
[2]236
[1469]237static VOID StartSnapThread(VOID *pargs)
[316]238{
[919]239 SNAPSTUFF *sf = (SNAPSTUFF *)pargs;
[551]240 FILE *fp;
[1544]241 CHAR *modew = "w";
[2]242
[551]243 if (sf) {
244 if (*sf->dirname && *sf->filename) {
[2]245 priority_normal();
[1545]246 ForwardslashToBackslash(sf->dirname);
247 AddBackslashToPath(sf->dirname);
[1544]248 fp = xfopen(sf->filename, modew, pszSrcFile, __LINE__, FALSE);
[362]249 if (fp) {
[1683]250 fprintf(fp, "\"%s\"\n", sf->dirname);
[551]251 SnapShot(sf->dirname, fp, sf->recurse);
252 fclose(fp);
[2]253 }
254 }
[1039]255 free(sf);
[2]256 }
257}
258
[1469]259/**
260 * Compare files thread
261 * Scan files and update container select flags
262 */
[2]263
[919]264static VOID CompareFilesThread(VOID *args)
[316]265{
[2]266 FCOMPARE fc;
[551]267 HAB hab2;
268 HMQ hmq2;
269 FILE *fp1, *fp2;
[847]270 ULONG len1, len2;
[841]271 ULONG offset = 0;
[551]272 LONG numread1, numread2;
273 CHAR s[1024], ss[1024], *p1, *p2;
[1544]274 CHAR *moderb = "rb";
[2]275
[551]276 if (args) {
[919]277 fc = *(FCOMPARE *)args;
[2]278 hab2 = WinInitialize(0);
[551]279 if (hab2) {
[1063]280# ifdef FORTIFY
281 Fortify_EnterScope();
282# endif
[1038]283 hmq2 = WinCreateMsgQueue(hab2, 0);
284 if (hmq2) {
[551]285 WinCancelShutdown(hmq2, TRUE);
[535]286 IncrThreadUsage();
[551]287 if (!IsFile(fc.file1) || IsRoot(fc.file1)) {
288 p1 = strrchr(fc.file2, '\\');
289 if (p1) {
290 if (fc.file1[strlen(fc.file1) - 1] == '\\')
291 p1++;
292 strcat(fc.file1, p1);
293 }
[362]294 }
[551]295 else if (!IsFile(fc.file2) || IsRoot(fc.file2)) {
296 p1 = strrchr(fc.file1, '\\');
297 if (p1) {
298 if (fc.file2[strlen(fc.file2) - 1] == '\\')
299 p1++;
300 strcat(fc.file2, p1);
301 }
302 }
303 sprintf(s, GetPString(IDS_COMPCOMPARETEXT), fc.file1);
304 AddToListboxBottom(fc.hwndList, s);
305 sprintf(s, GetPString(IDS_COMPTOTEXT), fc.file2);
306 AddToListboxBottom(fc.hwndList, s);
[1544]307 fp1 = xfsopen(fc.file1, moderb, SH_DENYNO, pszSrcFile, __LINE__, TRUE);
[551]308 if (!fp1) {
309 sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file1);
310 AddToListboxBottom(fc.hwndList, s);
[1498]311 WinSetWindowText(fc.hwndHelp, (CHAR *) GetPString(IDS_ERRORTEXT));
[551]312 }
[362]313 else {
[1544]314 fp2 = xfsopen(fc.file2, moderb, SH_DENYNO, pszSrcFile, __LINE__, TRUE);
[551]315 if (!fp2) {
316 sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file2);
317 AddToListboxBottom(fc.hwndList, s);
[1498]318 WinSetWindowText(fc.hwndHelp, (CHAR *) GetPString(IDS_ERRORTEXT));
[362]319 }
320 else {
[847]321 len1 = filelength(fileno(fp1));
322 len2 = filelength(fileno(fp2));
[551]323 if (len1 != len2) {
324 strcpy(s, GetPString(IDS_COMPDIFSIZESTEXT));
325 AddToListboxBottom(fc.hwndList, s);
326 sprintf(s, GetPString(IDS_COMPVSBYTESTEXT), len1, len2);
327 AddToListboxBottom(fc.hwndList, s);
328 WinSetWindowText(fc.hwndHelp,
[1498]329 (CHAR *) GetPString(IDS_COMPDONTMATCHTEXT));
[551]330 }
331 else {
332 WinSetWindowText(fc.hwndHelp,
[1498]333 (CHAR *) GetPString(IDS_COMPCOMPARINGTEXT));
[551]334 while (WinIsWindow(hab2, fc.hwndList)) {
335 numread1 = fread(s, 1, 1024, fp1);
336 numread2 = fread(ss, 1, 1024, fp2);
337 if (numread1 != numread2 || feof(fp1) != feof(fp2)) {
338 sprintf(s, GetPString(IDS_COMPREADERRORTEXT),
339 offset, offset);
340 AddToListboxBottom(fc.hwndList, s);
[1498]341 WinSetWindowText(fc.hwndHelp, (CHAR *) GetPString(IDS_ERRORTEXT));
[551]342 break;
343 }
344 else if (!numread1 && feof(fp1) && feof(fp2)) {
345 AddToListboxBottom(fc.hwndList,
346 GetPString(IDS_COMPFILESMATCHTEXT));
347 if (!stricmp(fc.file1, fc.file2))
348 AddToListboxBottom(fc.hwndList,
349 GetPString(IDS_COMPWONDERWHYTEXT));
350 WinSetWindowText(fc.hwndHelp,
[1498]351 (CHAR *) GetPString(IDS_COMPCOMPLETETEXT));
[551]352 break;
353 }
354 else if (numread1 <= 0 || numread2 <= 0) {
355 if (offset == len1)
356 break;
357 else {
358 sprintf(s, GetPString(IDS_COMPMATCHREADERRORTEXT),
359 offset, offset);
360 WinSetWindowText(fc.hwndHelp,
[1498]361 (CHAR *) GetPString(IDS_COMPODDERRORTEXT));
[551]362 AddToListboxBottom(fc.hwndList, s);
363 break;
364 }
365 }
366 else if (memcmp(s, ss, numread1)) {
367 p1 = s;
368 p2 = ss;
369 while (p1 < s + numread1) {
370 if (*p1 != *p2) {
371 sprintf(s, GetPString(IDS_COMPMISMATCHERRORTEXT),
372 offset + (p1 - s), offset + (p1 - s));
373 AddToListboxBottom(fc.hwndList, s);
374 WinSetWindowText(fc.hwndHelp,
[1498]375 (CHAR *) GetPString(IDS_COMPDONTMATCHTEXT));
[551]376 break;
377 }
378 p1++;
379 p2++;
380 }
381 break;
382 }
383 offset += numread1;
384 }
385 }
386 fclose(fp2);
387 }
388 fclose(fp1);
389 }
[535]390 DecrThreadUsage();
[551]391 WinDestroyMsgQueue(hmq2);
[2]392 }
393 WinTerminate(hab2);
[1063]394# ifdef FORTIFY
[1038]395 Fortify_LeaveScope();
[1063]396# endif
[2]397 }
398 }
399}
400
[1469]401/**
402 * Select directories to compare dialog procedure
403 */
[2]404
[551]405MRESULT EXPENTRY CFileDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[316]406{
[2]407 FCOMPARE *fc;
408
[551]409 switch (msg) {
410 case WM_INITDLG:
411 if (!mp2)
412 WinDismissDlg(hwnd, 0);
413 else {
[574]414 WinSetWindowPtr(hwnd, QWL_USER, mp2);
[919]415 fc = (FCOMPARE *)mp2;
[551]416 fc->hwndReport = hwnd;
417 fc->hwndList = WinWindowFromID(hwnd, FCMP_LISTBOX);
418 fc->hwndHelp = WinWindowFromID(hwnd, FCMP_HELP);
419 if (!*fc->file1 || !fc->file2) {
420 WinDismissDlg(hwnd, 0);
421 break;
[2]422 }
[551]423 MakeFullName(fc->file1);
424 MakeFullName(fc->file2);
425 if (!stricmp(fc->file1, fc->file2)) {
426 saymsg(MB_CANCEL, hwnd,
427 GetPString(IDS_COMPSILLYALERTTEXT),
428 GetPString(IDS_COMPTOITSELFTEXT));
429 WinDismissDlg(hwnd, 0);
430 break;
431 }
[1335]432 if (xbeginthread(CompareFilesThread,
433 65536,
434 fc,
435 pszSrcFile,
436 __LINE__) == -1)
437 {
[551]438 WinDismissDlg(hwnd, 0);
439 }
440 }
441 break;
[2]442
[551]443 case WM_ADJUSTWINDOWPOS:
444 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
445 break;
[2]446
[551]447 case UM_SETDIR:
448 PaintRecessedWindow(WinWindowFromID(hwnd, FCMP_HELP),
[919]449 (HPS)0, FALSE, TRUE);
[551]450 return 0;
[2]451
[551]452 case WM_COMMAND:
453 switch (SHORT1FROMMP(mp1)) {
454 case DID_OK:
455 WinDismissDlg(hwnd, 0);
456 break;
457 case DID_CANCEL:
458 WinDismissDlg(hwnd, 1);
459 break;
460 }
461 return 0;
[2]462
[551]463 case WM_DESTROY:
[924]464 DosSleep(50); // Let others die first
[551]465 break;
[2]466 }
[551]467 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]468}
[1682]469int ConfirmAction(HWND hwnd, CHAR *OldName, CHAR *NewName);
[2]470
[1469]471/**
[1682]472 * ConfirmAction provides an optional confirmation dialog
473 * for move and copy operations.
474 */
475int ConfirmAction(HWND hwnd, CHAR *OldName, CHAR *NewName)
476{
477 MOVEIT mv;
478 int rc;
479
480 memset(&mv, 0, sizeof(MOVEIT));
481 mv.rename = FALSE;
482 mv.source = OldName;
483 mv.compare = TRUE;
484 strcpy(mv.target, NewName);
485 rc = WinDlgBox(HWND_DESKTOP,
[1684]486 hwnd,
487 RenameProc,
488 FM3ModHandle, REN_FRAME, (PVOID) & mv);
[1682]489 if (!rc)
490 return 1;
491
492 DosSleep(1);
493 if (mv.skip || !*mv.target)
494 return 1;
495 if (mv.dontask)
496 return 2;
497 return 0;
498}
499
500/**
[1469]501 * Action Thread
502 * Do requested action on container contents
503 */
[731]504static VOID ActionCnrThread(VOID *args)
[316]505{
[731]506 COMPARE *cmp = (COMPARE *)args;
[551]507 HAB hab;
508 HMQ hmq;
509 HWND hwndCnrS, hwndCnrD;
[924]510 PCNRITEM pciS, pciD, pciNextS, pciNextD;
[769]511 CHAR szNewName[CCHMAXPATH], szDirName[CCHMAXPATH], *p;
[551]512 APIRET rc;
[924]513 ITIMER_DESC itdSleep = { 0 };
[1682]514 BOOL fConfirmAction = FALSE;
515 BOOL dontask = FALSE;
516 BOOL enddelete = FALSE;
[2]517
[748]518 if (!cmp) {
[1398]519 Runtime_Error(pszSrcFile, __LINE__, NULL);
[2]520 return;
[748]521 }
[2]522
523 DosError(FERR_DISABLEHARDERR);
524
525 hab = WinInitialize(0);
[551]526 if (hab) {
[1063]527# ifdef FORTIFY
528 Fortify_EnterScope();
529# endif
[1038]530 hmq = WinCreateMsgQueue(hab, 0);
531 if (hmq) {
[551]532 WinCancelShutdown(hmq, TRUE);
[535]533 IncrThreadUsage();
[2]534 priority_normal();
[551]535 switch (cmp->action) {
536 case COMP_DELETELEFT:
537 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
538 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
539 cmp->action = IDM_DELETE;
540 break;
541 case COMP_DELETERIGHT:
542 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
543 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
544 cmp->action = IDM_DELETE;
545 break;
546 case COMP_MOVELEFT:
547 cmp->action = IDM_MOVE;
548 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
549 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
550 break;
551 case COMP_MOVERIGHT:
552 cmp->action = IDM_MOVE;
553 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
554 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
555 break;
556 case COMP_COPYLEFT:
557 cmp->action = IDM_COPY;
558 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
559 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
560 break;
561 case COMP_COPYRIGHT:
562 cmp->action = IDM_COPY;
563 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
564 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
565 break;
566 default:
567 Runtime_Error(pszSrcFile, __LINE__, "bad case %u", cmp->action);
568 goto Abort;
[2]569 }
570
[924]571 pciS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
[551]572 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[748]573 pciD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
[1684]574 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[1682]575 fConfirmAction = WinQueryButtonCheckstate(cmp->hwnd, COMP_CONFIRMACTION);
[1175]576 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
[907]577
[924]578 while (pciS && (INT)pciS != -1 && pciD && (INT)pciD != -1) {
[748]579
[1469]580 if (cmp->cmp->stop)
581 break; // 27 Sep 09 SHL
582
[924]583 pciNextS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pciS),
[551]584 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[748]585 pciNextD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
[551]586 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[748]587
[929]588 // Process file if selected and not filtered
589 if (*pciS->pszFileName &&
590 pciS->rc.flRecordAttr & CRA_SELECTED &&
591 ~pciS->rc.flRecordAttr & CRA_FILTERED)
592 {
[748]593 // Source name not blank
[551]594 switch (cmp->action) {
[1683]595 case IDM_DELETE:
[1682]596
[1685]597 if (fConfirmAction && !dontask) {
598 rc = saymsg2(NULL, 0, cmp->hwnd, GetPString(IDS_CONFIRMDELETE), GetPString(IDS_DOYOUWISHTODELETE),
599 pciS->pszFileName);
600 if (rc == 3 || rc == 4) {
601 if (rc == 4)
602 enddelete = TRUE;
603 break;
604 }
605 else if (rc == 2)
606 dontask = TRUE;
607 }
[1402]608 if (!unlinkf(pciS->pszFileName)) {
[924]609 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
[551]610 MPFROM2SHORT(FALSE, CRA_SELECTED));
[748]611
612 if (!*pciD->pszFileName) {
[751]613 // Other side is blank - remove from both sides
[924]614 RemoveCnrItems(hwndCnrS, pciS, 1, CMA_FREE | CMA_INVALIDATE);
[748]615 if (pciD->rc.flRecordAttr & CRA_SELECTED)
616 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
[551]617 MPFROM2SHORT(FALSE, CRA_SELECTED));
[751]618 RemoveCnrItems(hwndCnrD, pciD, 1, CMA_FREE | CMA_INVALIDATE);
[551]619 }
[742]620 else {
[1132]621 // Other side is not blank - blank just this side
[924]622 FreeCnrItemData(pciS);
[1132]623 // 29 Aug 08 SHL Point pci fields at NullStr to sync with FreeCnrItemData mods
624 pciS->pszFileName = NullStr;
[924]625 pciS->pszDisplayName = pciS->pszFileName;
626 pciS->rc.pszIcon = pciS->pszFileName;
627 pciS->flags = 0; // Just on one side
628 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
[1685]629 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
630 pciD->flags = 0; // Just on one side
631 if (pciD->pszSubject != NullStr) {
632 xfree(pciD->pszSubject, pszSrcFile, __LINE__);
633 pciD->pszSubject = NullStr;
634 }
635 }
[551]636 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
637 cmp->cmp->totalleft--;
638 else
639 cmp->cmp->totalright--;
640 }
641 break;
[2]642
[1394]643 case IDM_MOVE:
644 {
645 BOOL fResetVerify = FALSE;
[751]646
[1394]647 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
648 BldFullPathName(szNewName, cmp->leftdir, pciS->pszDisplayName);
649 else
650 BldFullPathName(szNewName, cmp->rightdir, pciS->pszDisplayName);
651 // Make directory if required
652 strcpy(szDirName, szNewName);
653 p = strrchr(szDirName, '\\');
654 if (fVerify && (driveflags[toupper(*szNewName) - 'A'] & DRIVE_WRITEVERIFYOFF ||
655 driveflags[toupper(*pciS->pszFileName) - 'A'] & DRIVE_WRITEVERIFYOFF)) {
656 DosSetVerify(FALSE);
657 fResetVerify = TRUE;
658 }
659 if (p) {
660 if (p > szDirName + 2)
661 p++;
662 *p = 0;
663 if (IsFile(szDirName) == -1)
664 MassMkdir(hwndMain, szDirName);
665 }
[1683]666 if (fConfirmAction && pciS->flags & CNRITEM_EXISTS && !dontask) {
[1684]667 rc = ConfirmAction(cmp->hwnd, pciS->pszFileName, szNewName);
668 if (rc == 1)
669 break;
670 else if (rc == 2)
671 dontask = TRUE;
[1683]672 }
[1402]673 rc = docopyf(MOVE, pciS->pszFileName, szNewName);
[1394]674 if (fResetVerify) {
675 DosSetVerify(fVerify);
676 fResetVerify = FALSE;
677 }
678 if (!rc && stricmp(pciS->pszFileName, szNewName)) {
679 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
680 MPFROM2SHORT(FALSE, CRA_SELECTED));
681 if (pciD->rc.flRecordAttr & CRA_SELECTED)
682 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
683 MPFROM2SHORT(FALSE, CRA_SELECTED));
684 FreeCnrItemData(pciD);
685 pciD->pszFileName = xstrdup(szNewName, pszSrcFile, __LINE__);
686 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
687 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
688 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
689 pciD->pszDisplayName++;
690 }
691 else {
692 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
693 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
694 pciD->pszDisplayName++;
695 }
696 pciD->pszLongName = pciS->pszLongName;
697 pciS->pszLongName = NullStr; // 07 Sep 08 SHL avoid aliased pointer
698 if (pciD->pszSubject != NullStr) {
699 xfree(pciD->pszSubject, pszSrcFile, __LINE__);
700 pciD->pszSubject = NullStr;
701 }
702 pciD->attrFile = pciS->attrFile;
703 pciD->pszDispAttr = pciS->pszDispAttr;
704 pciD->flags = 0; // Just on one side
705 pciD->date = pciS->date;
706 pciD->time = pciS->time;
707 pciD->ladate = pciS->ladate;
708 pciD->latime = pciS->latime;
709 pciD->crdate = pciS->crdate;
710 pciD->crtime = pciS->crtime;
[1683]711 // 2013-03-06 SHL
712 if (pciS->pszFmtFileSize == NullStr)
713 pciD->pszFmtFileSize = pciS->pszFmtFileSize;
714 else
715 pciD->pszFmtFileSize = strdup(pciS->pszFmtFileSize);
[1394]716 pciD->cbFile = pciS->cbFile;
717 pciD->easize = pciS->easize;
[751]718
[1394]719 if (pciS->pszFileName != NullStr) {
720 xfree(pciS->pszFileName, pszSrcFile, __LINE__);
721 pciS->pszFileName = NullStr;
722 pciS->pszDisplayName = pciS->pszFileName;
723 pciS->rc.pszIcon = pciS->pszFileName;
724 }
725 if (pciS->pszSubject != NullStr) {
726 xfree(pciS->pszSubject, pszSrcFile, __LINE__);
727 pciS->pszSubject = NullStr;
728 }
729 pciS->flags = 0; // Just on one side
[924]730
[1394]731 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
732 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
[924]733
[1394]734 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
735 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
[2]736
[1394]737 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
738 cmp->cmp->totalleft--;
739 else
740 cmp->cmp->totalright--;
741 }
742 else if (rc) {
743 rc = Dos_Error(MB_ENTERCANCEL,
744 rc,
745 HWND_DESKTOP,
746 pszSrcFile,
747 __LINE__,
748 GetPString(IDS_COMPMOVEFAILEDTEXT),
749 pciS->pszFileName, szNewName);
750 if (rc == MBID_CANCEL) // Cause loop to break
751 pciNextS = NULL;
752 }
753 break;
754 }
[751]755
[1394]756 case IDM_COPY:
757 {
758 BOOL fResetVerify = FALSE;
[751]759
[1394]760 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
761 BldFullPathName(szNewName, cmp->leftdir, pciS->pszDisplayName);
762 else
763 BldFullPathName(szNewName, cmp->rightdir, pciS->pszDisplayName);
764 // Make directory if required
765 strcpy(szDirName, szNewName);
766 p = strrchr(szDirName, '\\');
767 if (fVerify && (driveflags[toupper(*szNewName) - 'A'] & DRIVE_WRITEVERIFYOFF ||
768 driveflags[toupper(*pciS->pszFileName) - 'A'] & DRIVE_WRITEVERIFYOFF)) {
769 DosSetVerify(FALSE);
770 fResetVerify = TRUE;
771 }
772 if (p) {
773 if (p > szDirName + 2)
774 p++;
775 *p = 0;
776 if (IsFile(szDirName) == -1)
777 MassMkdir(hwndMain, szDirName);
[1683]778 }
779 if (fConfirmAction && pciS->flags & CNRITEM_EXISTS && !dontask) {
[1684]780 rc = ConfirmAction(cmp->hwnd, pciS->pszFileName, szNewName);
781 if (rc == 1)
782 break;
783 else if (rc == 2)
784 dontask = TRUE;
[1683]785 }
786 rc = docopyf(COPY, pciS->pszFileName, szNewName);
[1394]787 if (fResetVerify) {
788 DosSetVerify(fVerify);
789 fResetVerify = FALSE;
790 }
791 if (rc) {
792 rc = Dos_Error(MB_ENTERCANCEL,
793 rc,
794 HWND_DESKTOP,
795 pszSrcFile,
796 __LINE__,
797 GetPString(IDS_COMPCOPYFAILEDTEXT),
798 pciS->pszFileName, szNewName);
799 if (rc == MBID_CANCEL)
800 pciNextS = NULL; // Cause loop to break
801 }
802 else {
803 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
804 MPFROM2SHORT(FALSE, CRA_SELECTED));
805 if (pciD->rc.flRecordAttr & CRA_SELECTED)
806 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
807 MPFROM2SHORT(FALSE, CRA_SELECTED));
[1469]808 if (~pciD->flags & CNRITEM_EXISTS) {
[1394]809 if (hwndCnrD == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
[1469]810 cmp->cmp->totalleft++;
[1394]811 else
[1469]812 cmp->cmp->totalright++;
[1394]813 }
814 FreeCnrItemData(pciD);
815 pciD->pszFileName = xstrdup(szNewName, pszSrcFile, __LINE__);
816 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
817 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
818 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
819 pciD->pszDisplayName++;
820 }
821 else {
822 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
823 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
824 pciD->pszDisplayName++;
825 }
826 pciD->attrFile = pciS->attrFile;
827 pciD->pszDispAttr = pciS->pszDispAttr;
828 pciD->flags = CNRITEM_EXISTS; // Now on both sides
829 pciD->date = pciS->date;
830 pciD->time = pciS->time;
831 pciD->ladate = pciS->ladate;
832 pciD->latime = pciS->latime;
833 pciD->crdate = pciS->crdate;
[1684]834 pciD->crtime = pciS->crtime;
[1683]835 // 2013-03-06 SHL
836 if (pciS->pszFmtFileSize == NullStr)
837 pciD->pszFmtFileSize = pciS->pszFmtFileSize;
838 else
839 pciD->pszFmtFileSize = strdup(pciS->pszFmtFileSize);
[1394]840 pciD->cbFile = pciS->cbFile;
841 pciD->easize = pciS->easize;
[2]842
[1394]843 // Forget status until we regenerate it
844 if (pciS->pszSubject != NullStr) {
845 xfree(pciS->pszSubject, pszSrcFile, __LINE__);
846 pciS->pszSubject = NullStr;
847 }
848 pciS->flags = CNRITEM_EXISTS; // Now on both sides
[1354]849
[1394]850 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
851 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
852 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
853 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
854 }
855 break;
856 }
[1354]857
[551]858 default:
859 break;
[748]860 } // switch
861
862 } // if have name
[1683]863 if (enddelete)
864 break;
[924]865 pciS = pciNextS;
[748]866 pciD = pciNextD;
867
[924]868 SleepIfNeeded(&itdSleep, 0);
[748]869 } // while
[1444]870 WinPostMsg(cmp->hwnd, WM_TIMER, MPFROMLONG(ID_COMP_TIMER), 0); // Force update
[551]871 Abort:
[2]872 WinDestroyMsgQueue(hmq);
873 }
[929]874 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1), MPVOID);
[535]875 DecrThreadUsage();
[1039]876 free(cmp);
[2]877 WinTerminate(hab);
[1063]878# ifdef FORTIFY
[1038]879 Fortify_LeaveScope();
[1063]880# endif
[2]881 }
[1032]882 else
883 xfree(cmp, pszSrcFile, __LINE__);
[2]884}
885
[1469]886static VOID CompSelect(HWND hwndCnrS, HWND hwndCnrD, HWND hwnd, INT action, USHORT shiftstate, BOOL *stop);
[924]887
[1469]888/**
889 * Update container selection flags thread
890 */
[2]891
[919]892static VOID SelectCnrsThread(VOID *args)
[316]893{
[919]894 COMPARE *cmp = (COMPARE *)args;
[551]895 HAB hab;
896 HMQ hmq;
[2]897
[783]898 if (!cmp) {
[1398]899 Runtime_Error(pszSrcFile, __LINE__, NULL);
[2]900 return;
[783]901 }
[2]902
903 DosError(FERR_DISABLEHARDERR);
904
905 hab = WinInitialize(0);
[551]906 if (hab) {
[1063]907# ifdef FORTIFY
908 Fortify_EnterScope();
909# endif
[1038]910 hmq = WinCreateMsgQueue(hab, 0);
911 if (hmq) {
[551]912 WinCancelShutdown(hmq, TRUE);
[535]913 IncrThreadUsage();
[2]914 priority_normal();
[551]915 switch (cmp->action) {
916 case IDM_INVERT:
917 InvertAll(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
918 InvertAll(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
919 break;
[2]920
[551]921 case IDM_DESELECTALL:
922 Deselect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
923 Deselect(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
924 break;
[2]925
[551]926 default:
[924]927 CompSelect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR),
928 WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR),
[929]929 cmp->hwnd,
930 cmp->action,
[1469]931 cmp->shiftstate,
932 &cmp->cmp->stop);
[551]933 break;
[2]934 }
[551]935 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID))
936 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID);
[2]937 WinDestroyMsgQueue(hmq);
938 }
[535]939 DecrThreadUsage();
[1039]940 free(cmp);
[2]941 WinTerminate(hab);
[1063]942# ifdef FORTIFY
[1038]943 Fortify_LeaveScope();
[1063]944# endif
[2]945 }
[1836]946 else {
947 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
[1039]948 free(cmp);
[1836]949 cmp = NULL;
950 DosReleaseMutexSem(hmtxFiltering);
951 }
[2]952}
953
[748]954/**
[1469]955 * Set item selections for CompSelect
956 */
957
958static VOID CompSelectSetSelects(PCNRITEM pciS, PCNRITEM pciD, BOOL matchS, BOOL matchD, BOOL wantAnd);
959
960static VOID CompSelectSetSelects(PCNRITEM pciS, PCNRITEM pciD, BOOL matchS, BOOL matchD, BOOL wantAnd)
961{
962 ULONG oldSel;
963 ULONG newSel;
964
965 oldSel = pciS->rc.flRecordAttr & CRA_SELECTED;
966 newSel = matchS ? (wantAnd ? oldSel : CRA_SELECTED) : (wantAnd ? 0 : oldSel);
967 if ((pciS->rc.flRecordAttr & CRA_SELECTED) != newSel)
968 WinSendMsg(pciS->hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
969 MPFROM2SHORT(newSel ? TRUE : FALSE, CRA_SELECTED));
970
971 oldSel = pciD->rc.flRecordAttr & CRA_SELECTED;
972 newSel = matchD ? (wantAnd ? oldSel : CRA_SELECTED) : (wantAnd ? 0 : oldSel);
973 if ((pciD->rc.flRecordAttr & CRA_SELECTED) != newSel) {
974 WinSendMsg(pciD->hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
975 MPFROM2SHORT(newSel ? TRUE : FALSE, CRA_SELECTED));
976 }
977}
978
979/**
980 * Clear item selections for CompSelect
981 */
982
983static BOOL CompSelectClearSelects(PCNRITEM pciS, PCNRITEM pciD, BOOL matchS, BOOL matchD);
984
985static BOOL CompSelectClearSelects(PCNRITEM pciS, PCNRITEM pciD, BOOL matchS, BOOL matchD)
986{
987 BOOL changed;
988
989 if ((pciS->rc.flRecordAttr & CRA_SELECTED) && matchS) {
990 WinSendMsg(pciS->hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
991 MPFROM2SHORT(FALSE, CRA_SELECTED));
992 changed = TRUE;
993 }
994 else
995 changed = FALSE;
996
997 if ((pciD->rc.flRecordAttr & CRA_SELECTED) && matchD) {
998 WinSendMsg(pciD->hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
999 MPFROM2SHORT(FALSE, CRA_SELECTED));
1000 changed = TRUE;
1001 }
1002
1003 return changed;
1004}
1005
1006/**
[924]1007 * Do select actions for compare directories containers
1008 * @param action is select mode
1009 */
1010
[1469]1011static VOID CompSelect(HWND hwndCnrS, HWND hwndCnrD, HWND hwnd, INT action, USHORT shiftstate, BOOL *stop)
[924]1012{
[1469]1013 PCNRITEM pciS;
1014 PCNRITEM pciD;
1015 PCNRITEM *pciSa = NULL;
1016 PCNRITEM *pciDa = NULL;
[924]1017 CNRINFO cnri;
1018 BOOL slow = FALSE;
[1469]1019 UINT x;
1020 UINT numD;
1021 UINT numS;
[924]1022 ITIMER_DESC itdSleep = { 0 };
[929]1023 BOOL fUpdateHideButton = FALSE;
[1469]1024 BOOL wantAnd = (shiftstate & (KC_SHIFT | KC_ALT | KC_CTRL)) == KC_CTRL;
1025 BOOL matched;
[924]1026
1027 if (!hwndCnrS || !hwndCnrD) {
1028 Runtime_Error(pszSrcFile, __LINE__, "hwndCnrS %p hwndCnrD %p", hwndCnrS, hwndCnrD);
1029 return;
1030 }
1031
1032 memset(&cnri, 0, sizeof(CNRINFO));
1033 cnri.cb = sizeof(CNRINFO);
1034 WinSendMsg(hwndCnrD, CM_QUERYCNRINFO, MPFROMP(&cnri),
1035 MPFROMLONG(sizeof(CNRINFO)));
1036 numD = cnri.cRecords;
1037 memset(&cnri, 0, sizeof(CNRINFO));
1038 cnri.cb = sizeof(CNRINFO);
1039 WinSendMsg(hwndCnrS, CM_QUERYCNRINFO, MPFROMP(&cnri),
1040 MPFROMLONG(sizeof(CNRINFO)));
1041 numS = cnri.cRecords;
1042 if (!numD || numS != numD) {
1043 Runtime_Error(pszSrcFile, __LINE__, "numD %u != numS %u", numD, numS);
1044 return;
1045 }
1046
1047 pciDa = xmalloc(sizeof(PCNRITEM) * numD, pszSrcFile, __LINE__);
1048 if (!pciDa)
1049 return;
1050
1051 pciSa = xmalloc(sizeof(PCNRITEM) * numS, pszSrcFile, __LINE__);
1052 if (!pciSa) {
[1039]1053 free(pciDa);
[924]1054 return;
1055 }
1056
1057 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
1058
1059Restart:
1060
1061 memset(pciDa, 0, sizeof(PCNRITEM) * numD);
1062 memset(pciSa, 0, sizeof(PCNRITEM) * numS);
1063
1064 pciD = (PCNRITEM)WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
[1469]1065 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
[924]1066 x = 0;
1067 while (pciD && (INT)pciD != -1 && x < numD) {
1068 pciDa[x] = pciD;
1069 x++;
1070 if (!slow)
1071 pciD = (PCNRITEM) pciD->rc.preccNextRecord;
1072 else
1073 pciD = (PCNRITEM) WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
1074 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1075 SleepIfNeeded(&itdSleep, 0);
1076 } // while
1077
1078 if (numD != x) {
[1469]1079 // Something out of sync - fixme to document why slow logic needed
[924]1080 if (!slow) {
1081 slow = TRUE;
1082 goto Restart;
1083 }
[1039]1084 free(pciDa);
1085 free(pciSa);
[924]1086 Runtime_Error(pszSrcFile, __LINE__, "numD %u != x %lu", numD, x);
1087 return;
1088 }
1089
1090 pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
1091 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1092 x = 0;
1093 while (pciS && (INT)pciS != -1 && x < numS) {
1094 pciSa[x] = pciS;
1095 x++;
1096 if (!slow)
1097 pciS = (PCNRITEM) pciS->rc.preccNextRecord;
1098 else
1099 pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pciS),
1100 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
1101 SleepIfNeeded(&itdSleep, 0);
1102 } // while
1103
1104 if (numS != x) {
1105 if (!slow) {
1106 slow = TRUE;
1107 goto Restart;
1108 }
[1039]1109 free(pciSa);
1110 free(pciDa);
[924]1111 Runtime_Error(pszSrcFile, __LINE__, "numS (%lu) != x (%lu)", numS, x);
1112 return;
1113 }
1114
1115 switch (action) {
1116 case IDM_SELECTIDENTICAL:
[1682]1117 // Same Date/size including EAs
[924]1118 for (x = 0; x < numS; x++) {
[1469]1119 pciS = pciSa[x];
1120 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1121 matched = pciS->flags & CNRITEM_EXISTS &&
1122 ~pciS->flags & CNRITEM_SMALLER &&
1123 ~pciS->flags & CNRITEM_LARGER &&
1124 ~pciS->flags & CNRITEM_NEWER &&
[1684]1125 ~pciS->flags & CNRITEM_OLDER &&
1126 ~pciS->flags & CNRITEM_EASDIFFER;
[1469]1127 CompSelectSetSelects(pciS, pciDa[x], matched, matched, wantAnd);
[924]1128 }
1129 SleepIfNeeded(&itdSleep, 0);
1130 } // for
1131 break;
1132
1133 case IDM_SELECTSAME:
[1682]1134 // Same Size including EAs
[924]1135 for (x = 0; x < numS; x++) {
[1469]1136 pciS = pciSa[x];
1137 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1138 matched = pciS->flags & CNRITEM_EXISTS &&
1139 ~pciS->flags & CNRITEM_SMALLER &&
[1682]1140 ~pciS->flags & CNRITEM_LARGER &&
[1684]1141 ~pciS->flags & CNRITEM_EASDIFFER;
[1469]1142 CompSelectSetSelects(pciS, pciDa[x], matched, matched, wantAnd);
[924]1143 }
1144 SleepIfNeeded(&itdSleep, 0);
1145 } // for
1146 break;
1147
1148 case IDM_SELECTSAMECONTENT:
[1469]1149 for (x = 0; x < numS && !*stop; x++) {
[924]1150
[1469]1151 pciS = pciSa[x];
1152 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1153 matched = FALSE;
1154 pciD = pciDa[x];
1155 if (pciS->flags & CNRITEM_EXISTS) {
1156 FILE *fp1 = NULL;
1157 FILE *fp2 = NULL;
1158 UINT errLineNo = 0;
1159 UINT compErrno = 0;
1160 CHAR buf1[1024];
1161 CHAR buf2[1024];
[1563]1162 HAB hab = WinQueryAnchorBlock(hwndCnrS);
1163 CHAR *moderb = "rb";
[924]1164
[1469]1165 if (!*pciS->pszFileName ||
1166 !*pciD->pszFileName) {
1167 Runtime_Error(pszSrcFile, __LINE__,
1168 "CNRITEM_EXISTS set with null file name for index %u", x);
1169 break;
1170 }
1171
[1544]1172 fp1 = xfsopen(pciS->pszFileName, moderb, SH_DENYNO, pszSrcFile, __LINE__, TRUE);
[1469]1173 if (!fp1) {
[924]1174 errLineNo = __LINE__;
1175 compErrno = errno;
1176 }
1177 else {
[1544]1178 fp2 = xfsopen(pciD->pszFileName, moderb, SH_DENYNO, pszSrcFile, __LINE__, TRUE);
[1469]1179 if (!fp2) {
1180 errLineNo = __LINE__;
1181 compErrno = errno;
1182 }
1183 else {
1184 size_t len1 = filelength(fileno(fp1));
1185 size_t len2 = filelength(fileno(fp2));
1186 if (len1 == len2) {
1187 setbuf(fp1, NULL);
1188 setbuf(fp2, NULL);
1189 while (WinIsWindow(hab, hwndCnrS)) {
1190 size_t numread1 = fread(buf1, 1, 1024, fp1);
1191 size_t numread2 = fread(buf2, 1, 1024, fp2);
[924]1192
[1469]1193 if (!numread1 || !numread2 || numread1 != numread2) {
1194 if (ferror(fp1) || ferror(fp2)) {
1195 errLineNo = __LINE__;
1196 compErrno = errno;
1197 }
1198 else if (feof(fp1) && feof(fp2))
1199 matched = TRUE;
1200 break;
1201 }
1202 else if (memcmp(buf1, buf2, numread1))
1203 break;
1204 } // while
1205 } // same len
1206 } // if open ok
1207 } // if open ok
1208 if (fp1)
1209 fclose(fp1);
1210 if (fp2)
1211 fclose(fp2);
[924]1212
[1469]1213 if (errLineNo) {
1214 Runtime_Error(pszSrcFile, errLineNo,
1215 "error %d while comparing", compErrno);
[924]1216 }
[1469]1217 } // if exists
1218 CompSelectSetSelects(pciS, pciD, matched, matched, wantAnd);
1219 } // if not filtered
[924]1220 SleepIfNeeded(&itdSleep, 0);
1221 } // for
1222 break;
1223
1224 case IDM_SELECTBOTH:
1225 for (x = 0; x < numS; x++) {
[1469]1226 pciS = pciSa[x];
1227 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1228 pciD = pciDa[x];
1229 matched = pciS->flags & CNRITEM_EXISTS;
1230 CompSelectSetSelects(pciS, pciD, matched, matched, wantAnd);
[924]1231 }
1232 SleepIfNeeded(&itdSleep, 0);
1233 } // for
1234 break;
1235
1236 case IDM_SELECTONE:
1237 for (x = 0; x < numS; x++) {
[1469]1238 pciS = pciSa[x];
1239 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1240 pciD = pciDa[x];
1241 CompSelectSetSelects(pciS,
1242 pciD,
1243 ~pciS->flags & CNRITEM_EXISTS && *pciS->pszFileName,
1244 ~pciD->flags & CNRITEM_EXISTS && *pciD->pszFileName,
1245 wantAnd);
[924]1246 }
1247 SleepIfNeeded(&itdSleep, 0);
1248 } // for
1249 break;
1250
1251 case IDM_SELECTBIGGER:
1252 for (x = 0; x < numS; x++) {
[1469]1253 pciS = pciSa[x];
1254 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1255 pciD = pciDa[x];
1256 CompSelectSetSelects(pciS,
1257 pciD,
1258 pciS->flags & CNRITEM_LARGER,
1259 pciD->flags & CNRITEM_LARGER,
1260 wantAnd);
[924]1261 }
1262 SleepIfNeeded(&itdSleep, 0);
1263 } // for
1264 break;
1265
1266 case IDM_SELECTSMALLER:
1267 for (x = 0; x < numS; x++) {
[1469]1268 pciS = pciSa[x];
1269 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1270 pciD = pciDa[x];
1271 CompSelectSetSelects(pciS,
1272 pciD,
1273 pciS->flags & CNRITEM_SMALLER,
1274 pciD->flags & CNRITEM_SMALLER,
1275 wantAnd);
[924]1276 }
1277 SleepIfNeeded(&itdSleep, 0);
1278 } // for
1279 break;
1280
1281 case IDM_SELECTNEWER:
1282 for (x = 0; x < numS; x++) {
[1469]1283 pciS = pciSa[x];
1284 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1285 pciD = pciDa[x];
1286 CompSelectSetSelects(pciS,
1287 pciD,
1288 pciS->flags & CNRITEM_NEWER,
1289 pciD->flags & CNRITEM_NEWER,
1290 wantAnd);
[924]1291 }
1292 SleepIfNeeded(&itdSleep, 0);
1293 } // for
1294 break;
1295
1296 case IDM_SELECTOLDER:
1297 for (x = 0; x < numS; x++) {
[1469]1298 pciS = pciSa[x];
1299 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1300 pciD = pciDa[x];
1301 CompSelectSetSelects(pciS,
1302 pciD,
1303 pciS->flags & CNRITEM_OLDER,
1304 pciD->flags & CNRITEM_OLDER,
1305 wantAnd);
[924]1306 }
1307 SleepIfNeeded(&itdSleep, 0);
1308 } // for
1309 break;
1310
[1682]1311 case IDM_SELECTEAS:
1312 for (x = 0; x < numS; x++) {
1313 pciS = pciSa[x];
1314 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1315 pciD = pciDa[x];
[1683]1316 CompSelectSetSelects(pciS,
[1684]1317 pciD,
1318 pciS->flags & CNRITEM_EASDIFFER,
1319 pciD->flags & CNRITEM_EASDIFFER,
1320 wantAnd);
[1682]1321 }
1322 SleepIfNeeded(&itdSleep, 0);
1323 } // for
1324 break;
1325
[924]1326 case IDM_DESELECTBOTH:
1327 for (x = 0; x < numS; x++) {
[1469]1328 pciS = pciSa[x];
1329 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1330 matched = pciS->flags & CNRITEM_EXISTS;
1331 if (CompSelectClearSelects(pciS, pciDa[x], matched, matched))
[929]1332 fUpdateHideButton = TRUE;
[924]1333 }
1334 SleepIfNeeded(&itdSleep, 0);
1335 } // for
1336 break;
1337
1338 case IDM_DESELECTONE:
1339 for (x = 0; x < numS; x++) {
[1469]1340 pciS = pciSa[x];
1341 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1342 pciD = pciDa[x];
1343 if (CompSelectClearSelects(pciS,
1344 pciD,
1345 ~pciS->flags & CNRITEM_EXISTS && *pciS->pszFileName,
1346 ~pciD->flags & CNRITEM_EXISTS && *pciD->pszFileName)) {
1347 fUpdateHideButton = TRUE;
[924]1348 }
1349 }
1350 SleepIfNeeded(&itdSleep, 0);
1351 } // for
1352 break;
1353
1354 case IDM_DESELECTBIGGER:
1355 for (x = 0; x < numS; x++) {
[1469]1356 pciS = pciSa[x];
1357 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1358 pciD = pciDa[x];
1359 if (CompSelectClearSelects(pciS,
1360 pciD,
1361 pciS->flags & CNRITEM_LARGER,
1362 pciD->flags & CNRITEM_LARGER)) {
1363 fUpdateHideButton = TRUE;
[924]1364 }
1365 }
1366 SleepIfNeeded(&itdSleep, 0);
1367 } // for
1368 break;
1369
1370 case IDM_DESELECTSMALLER:
1371 for (x = 0; x < numS; x++) {
[1469]1372 pciS = pciSa[x];
1373 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1374 pciD = pciDa[x];
1375 if (CompSelectClearSelects(pciS,
1376 pciD,
1377 pciS->flags & CNRITEM_SMALLER,
1378 pciD->flags & CNRITEM_SMALLER)) {
1379 fUpdateHideButton = TRUE;
[924]1380 }
1381 }
1382 SleepIfNeeded(&itdSleep, 0);
1383 } // for
1384 break;
1385
1386 case IDM_DESELECTNEWER:
1387 for (x = 0; x < numS; x++) {
[1469]1388 pciS = pciSa[x];
1389 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1390 pciD = pciDa[x];
1391 if (CompSelectClearSelects(pciS,
1392 pciD,
1393 pciS->flags & CNRITEM_NEWER,
1394 pciD->flags & CNRITEM_NEWER)) {
1395 fUpdateHideButton = TRUE;
[924]1396 }
1397 }
1398 SleepIfNeeded(&itdSleep, 0);
1399 } // for
1400 break;
1401
1402 case IDM_DESELECTOLDER:
1403 for (x = 0; x < numS; x++) {
[1469]1404 pciS = pciSa[x];
1405 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1406 pciD = pciDa[x];
1407 if (CompSelectClearSelects(pciS,
1408 pciD,
1409 pciS->flags & CNRITEM_OLDER,
1410 pciD->flags & CNRITEM_OLDER)) {
1411 fUpdateHideButton = TRUE;
[924]1412 }
1413 }
1414 SleepIfNeeded(&itdSleep, 0);
1415 } // for
1416 break;
1417
[1682]1418 case IDM_DESELECTEAS:
1419 for (x = 0; x < numS; x++) {
1420 pciS = pciSa[x];
1421 if (~pciS->rc.flRecordAttr & CRA_FILTERED) {
1422 pciD = pciDa[x];
1423 if (CompSelectClearSelects(pciS,
1424 pciD,
1425 pciS->flags & CNRITEM_EASDIFFER,
1426 pciD->flags & CNRITEM_EASDIFFER)) {
1427 fUpdateHideButton = TRUE;
1428 }
1429 }
1430 SleepIfNeeded(&itdSleep, 0);
1431 } // for
1432 break;
1433
[924]1434 default:
1435 break;
[1469]1436 } // switch action
[924]1437
[1039]1438 free(pciSa);
1439 free(pciDa);
[929]1440
1441 if (fUpdateHideButton) {
1442 if (WinQueryButtonCheckstate(hwnd,COMP_HIDENOTSELECTED) == 1)
1443 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 2);
1444 }
1445
[1444]1446 WinPostMsg(hwnd, WM_TIMER, MPFROMLONG(ID_COMP_TIMER), 0); // Force update
[924]1447 DosPostEventSem(CompactSem);
1448}
1449
1450/**
[748]1451 * Build FILELIST given pathname
1452 */
1453
[907]1454static VOID FillDirList(CHAR *str, UINT skiplen, BOOL recurse,
1455 FILELIST ***list, UINT *pnumfiles, UINT *pnumalloc)
[551]1456{
[748]1457 CHAR *enddir;
1458 ULONG x;
[551]1459 CHAR *maskstr;
[841]1460 PFILEFINDBUF4L pffbArray;
1461 PFILEFINDBUF4L pffbFile;
[551]1462 HDIR hDir;
[783]1463 ULONG ulFindCnt;
[841]1464 ULONG ulBufBytes = sizeof(FILEFINDBUF4L) * FilesToGet;
[551]1465 APIRET rc;
[1000]1466 static BOOL fDone;
[1570]1467 ITIMER_DESC itdSleep = { 0 }; // 30 May 11 GKY
[2]1468
[748]1469 if (!str || !*str) {
[1398]1470 Runtime_Error(pszSrcFile, __LINE__, NULL);
[2]1471 return;
[748]1472 }
1473
[1000]1474 maskstr = xmalloc(CCHMAXPATH + 100, pszSrcFile, __LINE__);
[551]1475 if (!maskstr)
[2]1476 return;
[783]1477 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
1478 if (!pffbArray) {
[1039]1479 free(maskstr);
[2]1480 return;
1481 }
1482 x = strlen(str);
[551]1483 memcpy(maskstr, str, x + 1);
[2]1484 enddir = maskstr + x;
[551]1485 if (*(enddir - 1) != '\\') {
[2]1486 *enddir = '\\';
1487 enddir++;
1488 *enddir = 0;
1489 }
1490 *enddir = '*';
1491 *(enddir + 1) = 0;
1492 hDir = HDIR_CREATE;
1493 DosError(FERR_DISABLEHARDERR);
[783]1494 ulFindCnt = FilesToGet;
[838]1495 rc = xDosFindFirst(maskstr, &hDir,
[907]1496 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
[838]1497 FILE_SYSTEM | FILE_HIDDEN |
1498 (recurse ? FILE_DIRECTORY : 0),
[841]1499 pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
[551]1500 if (!rc) {
[1570]1501 InitITimer(&itdSleep, 500);
[783]1502 do {
1503 pffbFile = pffbArray;
1504 for (x = 0; x < ulFindCnt; x++) {
1505 if (pffbFile->attrFile & FILE_DIRECTORY) {
[517]1506 // Skip . and ..
[551]1507 if (recurse &&
[783]1508 (pffbFile->achName[0] != '.' ||
1509 (pffbFile->achName[1] &&
1510 (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
[551]1511 if (fForceUpper)
[783]1512 strupr(pffbFile->achName);
[551]1513 else if (fForceLower)
[783]1514 strlwr(pffbFile->achName);
1515 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1);
[907]1516 FillDirList(maskstr, skiplen, recurse, list, pnumfiles, pnumalloc);
[551]1517 }
1518 }
1519 else {
1520 if (fForceUpper)
[783]1521 strupr(pffbFile->achName);
[551]1522 else if (fForceLower)
[783]1523 strlwr(pffbFile->achName);
[1175]1524 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1);
1525 if (strlen(maskstr) > CCHMAXPATH) {
[1000]1526 // Complain if pathnames exceeds max
1527 DosFindClose(hDir);
[1175]1528 free(pffbArray);
1529 free(maskstr);
[1000]1530 if (!fDone) {
1531 fDone = TRUE;
1532 saymsg(MB_OK | MB_ICONASTERISK,
1533 HWND_DESKTOP,
1534 GetPString(IDS_WARNINGTEXT),
[1402]1535 GetPString(IDS_LENGTHEXCEEDSMAXPATHTEXT));
[1175]1536 }
1537 return;
[1000]1538 }
[783]1539 if (AddToFileList(maskstr + skiplen,
[907]1540 pffbFile, list, pnumfiles, pnumalloc)) {
[551]1541 goto Abort;
[783]1542 }
[551]1543 }
[841]1544 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
[783]1545 } // for
[2]1546 DosError(FERR_DISABLEHARDERR);
[783]1547 ulFindCnt = FilesToGet;
[850]1548 rc = xDosFindNext(hDir, pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
[1570]1549 SleepIfNeeded(&itdSleep, 1);
[783]1550 } while (!rc);
1551
1552Abort:
1553
[2]1554 DosFindClose(hDir);
[846]1555 DosSleep(0);
[2]1556 }
[783]1557
1558 if (rc && rc != ERROR_NO_MORE_FILES) {
1559 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
1560 GetPString(IDS_CANTFINDDIRTEXT), maskstr);
1561 }
1562
[1009]1563 xfree(maskstr, pszSrcFile, __LINE__);
1564 xfree(pffbArray, pszSrcFile, __LINE__);
[2]1565}
1566
[1469]1567#define GetHwndLeft(h) (WinWindowFromID(h,COMP_LEFTDIR))
1568#define GetHwndRight(h) (WinWindowFromID(h,COMP_RIGHTDIR))
1569
[924]1570/**
1571 * Compare names for qsort
1572 */
[2]1573
[551]1574static int CompNames(const void *n1, const void *n2)
[316]1575{
[919]1576 FILELIST *fl1 = *(FILELIST **)n1;
1577 FILELIST *fl2 = *(FILELIST **)n2;
[2]1578
[551]1579 return stricmp(fl1->fname, fl2->fname);
[2]1580}
1581
[1469]1582/**
1583 * Fill left and right containers
1584 */
[2]1585
[751]1586static VOID FillCnrsThread(VOID *args)
[316]1587{
[919]1588 COMPARE *cmp = (COMPARE *)args;
[551]1589 HAB hab;
1590 HMQ hmq;
1591 BOOL notified = FALSE;
[907]1592 ITIMER_DESC itdSleep = { 0 };
[751]1593
[748]1594 CHAR szBuf[CCHMAXPATH];
1595 CNRINFO cnri;
[2]1596
[1009]1597# ifdef FORTIFY
1598 // 10 May 08 SHL fixme to suppress W111
1599 Fortify_EnterScope();
[1063]1600# endif
[1009]1601
[748]1602 if (!cmp) {
[1398]1603 Runtime_Error(pszSrcFile, __LINE__, NULL);
[1063]1604# ifdef FORTIFY
[1009]1605 // 10 May 08 SHL fixme to suppress W111
1606 Fortify_LeaveScope();
[1063]1607# endif
[1335]1608 return; // 10 Dec 08 SHL was _endthread
[748]1609 }
[2]1610
1611 DosError(FERR_DISABLEHARDERR);
1612
[907]1613 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
1614
[2]1615 hab = WinInitialize(0);
[551]1616 if (!hab)
1617 Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__, "WinInitialize");
[362]1618 else {
[551]1619 hmq = WinCreateMsgQueue(hab, 0);
1620 if (!hmq)
1621 Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__,
1622 "WinCreateMsgQueue");
[362]1623 else {
[551]1624 INT x;
[907]1625 UINT l;
1626 UINT r;
[551]1627 FILELIST **filesl = NULL;
1628 FILELIST **filesr = NULL;
[907]1629 UINT numallocl = 0;
1630 UINT numallocr = 0;
[769]1631 UINT lenl; // Directory prefix length
1632 UINT lenr;
[1563]1633 ULONG ulRecsNeeded;
[551]1634 CHAR *pch;
[1469]1635 HWND hwndLeft;
1636 HWND hwndRight;
[2]1637
[551]1638 WinCancelShutdown(hmq, TRUE);
[535]1639 IncrThreadUsage();
[907]1640
[1469]1641 hwndLeft = GetHwndLeft(cmp->hwnd);
1642 hwndRight = GetHwndRight(cmp->hwnd);
[2]1643 lenl = strlen(cmp->leftdir);
[551]1644 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
1645 lenl++;
[2]1646 lenr = strlen(cmp->rightdir);
[551]1647 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
1648 lenr++;
[2]1649 priority_normal();
[748]1650 // Clear containers
[751]1651 RemoveCnrItems(hwndRight, NULL, 0, CMA_FREE | CMA_INVALIDATE);
1652 RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
[917]1653 cmp->cmp->totalleft = 0;
1654 cmp->cmp->totalright = 0;
[2]1655
[748]1656 // Build list of all files in left directory
[551]1657 if (fForceLower)
1658 strlwr(cmp->leftdir);
1659 else if (fForceUpper)
1660 strupr(cmp->leftdir);
1661 FillDirList(cmp->leftdir, lenl, cmp->includesubdirs,
[907]1662 &filesl, &cmp->cmp->totalleft, &numallocl);
[551]1663 if (filesl)
[917]1664 qsort(filesl, cmp->cmp->totalleft, sizeof(CHAR *), CompNames);
[748]1665 // Build list of all files in right directory
[551]1666 if (!*cmp->rightlist) {
1667 if (fForceLower)
1668 strlwr(cmp->rightdir);
1669 else if (fForceUpper)
1670 strupr(cmp->rightdir);
1671 FillDirList(cmp->rightdir, lenr, cmp->includesubdirs,
[1684]1672 &filesr, &cmp->cmp->totalright, &numallocr);
[2]1673 }
[551]1674 else {
[748]1675 // Use snapshot file
[551]1676 FILE *fp;
[841]1677 FILEFINDBUF4L fb4;
[1563]1678 CHAR str[CCHMAXPATH * 2], *p;
[1683]1679 CHAR *moder = "r";
[1685]1680 BOOL fFixedSnap = TRUE;
[2]1681
[551]1682 memset(&fb4, 0, sizeof(fb4));
[1544]1683 fp = xfopen(cmp->rightlist, moder, pszSrcFile, __LINE__, FALSE);
[1683]1684 if (fp) {
[551]1685 while (!feof(fp)) {
[748]1686 // First get name of directory
[551]1687 if (!xfgets_bstripcr(str, sizeof(str), fp, pszSrcFile, __LINE__))
1688 break; // EOF
1689 p = str;
1690 if (*p == '\"') {
[748]1691 // Quoted
[551]1692 p++;
1693 if (*p && *p != '\"') {
1694 p = strchr(p, '\"');
1695 if (p) {
1696 *p = 0;
1697 if (*(str + 1)) {
1698 strcpy(cmp->rightdir, str + 1);
1699 if (fForceUpper)
1700 strupr(cmp->rightdir);
1701 else if (fForceLower)
1702 strlwr(cmp->rightdir);
1703 p = cmp->rightdir + (strlen(cmp->rightdir) - 1);
1704 if (p - cmp->rightdir > 3 && *p == '\\')
1705 *p = 0; // Chop trailing slash
1706 break;
1707 }
1708 }
1709 }
1710 }
[748]1711 } // while !EOF
[2]1712
[748]1713 memset(&cnri, 0, sizeof(cnri));
[1683]1714 cnri.cb = sizeof(cnri);
1715 WinSetDlgItemText(cmp->hwnd, COMP_LISTLOADED, "List File Loaded");
[748]1716 cnri.pszCnrTitle = cmp->rightdir;
1717 if (!WinSendMsg(hwndRight, CM_SETCNRINFO,
1718 MPFROMP(&cnri), MPFROMLONG(CMA_CNRTITLE))) {
[1683]1719 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_SETCNRINFO");
1720 WinSetDlgItemText(cmp->hwnd, COMP_LISTLOADED, "");
[551]1721 }
[748]1722
[551]1723 if (*cmp->rightdir) {
[769]1724 lenr = strlen(cmp->rightdir);
1725 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
[1683]1726 lenr++;
1727 while (!feof(fp)) {
[551]1728 if (!xfgets_bstripcr
[1684]1729 (str, sizeof(str), fp, pszSrcFile, __LINE__)) {
1730 break;
[1683]1731 }
[551]1732 p = str;
1733 if (*p == '\"') {
1734 p++;
1735 if (*p && *p != '\"') {
1736 p = strchr(p, '\"');
[1684]1737 if (p) {
[551]1738 *p = 0;
1739 p++;
[1684]1740 if (*p == ',') {
[551]1741 p++;
1742 if (!cmp->includesubdirs && atol(p) > lenr)
1743 continue;
1744 p = strchr(p, ',');
[1684]1745 if (p) {
[1685]1746 p++;
1747 if (((strchr(p, '/') ? strchr(p, '/') : strchr(p, DateSeparator[0])) - strchr(p, ',')) > 5) {
1748 CHAR szTemp[30];
1749 CHAR *q;
1750 int i;
1751
1752 memset(szTemp, 0, sizeof(szTemp));
1753 i = (strchr(p, '/') ? strchr(p, '/') : strchr(p, DateSeparator[0])) - 3 - p;
1754 strncpy(&szTemp, p, i);
1755 for (q = szTemp; q = strchr(szTemp, ',');) {
1756 strcpy(q, q + 1);
1757 }
1758 fb4.cbFile = atoll(szTemp);
1759 fFixedSnap = FALSE;
1760
1761 }
1762 else
1763 fb4.cbFile = atoll(p);
1764 if (!strchr(p, '/'))
1765 fFixedSnap = FALSE;
1766 p = (strchr(p, '/') ? strchr(p, '/') : strchr(p, DateSeparator[0])) - 6;
1767 p = strchr(p, ',');
1768 if (p) {
1769 p++;
1770 if (ulDateFmt == 2 || ulDateFmt == 3 || fFixedSnap)
1771 fb4.fdateLastWrite.year = atol(p) - 1980;
1772 else if (ulDateFmt == 1)
1773 fb4.fdateLastWrite.day = atol(p);
1774 else
1775 fb4.fdateLastWrite.month = atol(p);
1776 p = strchr(p, '/') ? strchr(p, '/') : strchr(p, DateSeparator[0]);
1777 if (p) {
1778 p++;
1779 if (ulDateFmt == 2 || ulDateFmt == 1 || fFixedSnap)
1780 fb4.fdateLastWrite.month = atol(p);
1781 else
1782 fb4.fdateLastWrite.day = atol(p);
1783 p = strchr(p, '/') ? strchr(p, '/') : strchr(p, DateSeparator[0]);
1784 if (p) {
1785 p++;
1786 if (ulDateFmt == 2 || fFixedSnap)
1787 fb4.fdateLastWrite.day = atol(p);
1788 else if (ulDateFmt == 3)
1789 fb4.fdateLastWrite.month = atol(p);
1790 else
1791 fb4.fdateLastWrite.year = atol(p) - 1980;
[551]1792 p = strchr(p, ',');
[1684]1793 if (p) {
[551]1794 p++;
1795 fb4.ftimeLastWrite.hours = atol(p);
[1685]1796 p = strchr(p, ':') ? strchr(p, ':') : strchr(p, TimeSeparator[0]);
1797 if (p) {
[551]1798 p++;
1799 fb4.ftimeLastWrite.minutes = atol(p);
[1685]1800 p = strchr(p, ':') ? strchr(p, ':') : strchr(p, TimeSeparator[0]);
[1684]1801 if (p) {
[551]1802 p++;
1803 fb4.ftimeLastWrite.twosecs = atol(p);
1804 p = strchr(p, ',');
[1684]1805 if (p) {
[551]1806 p++;
1807 fb4.attrFile = atol(p);
1808 p = strchr(p, ',');
[1684]1809 if (p) {
[551]1810 p++;
1811 fb4.cbList = atol(p) * 2;
1812 if (fForceUpper)
1813 strupr(str + 1);
1814 else if (fForceLower)
[1684]1815 strlwr(str + 1);
[551]1816 if (AddToFileList((str + 1) + lenr,
1817 &fb4,
1818 &filesr,
[917]1819 &cmp->cmp->totalright,
[551]1820 &numallocr))
1821 break;
1822 }
1823 }
1824 }
1825 }
1826 }
1827 }
1828 }
1829 }
1830 }
1831 }
1832 }
1833 }
1834 }
[748]1835 } // while
1836 } // if have rightdir
[1685]1837 fclose(fp);
1838 if (!filesr)
1839 saymsg(MB_OK | MB_ICONASTERISK, HWND_DESKTOP,
1840 GetPString(IDS_WARNINGTEXT),
1841 GetPString(IDS_SNAPSHOTFILEBADFORMAT));
1842 }
1843 else
1844 saymsg(MB_OK | MB_ICONASTERISK, HWND_DESKTOP,
1845 GetPString(IDS_WARNINGTEXT),
1846 GetPString(IDS_SNAPSHOTFILELOADFAILED), cmp->rightlist);
[748]1847 } // if snapshot file
[316]1848
[551]1849 if (filesr)
[1683]1850 qsort(filesr, cmp->cmp->totalright, sizeof(CHAR *), CompNames);
[2]1851
[748]1852 // We now have two lists of files, both sorted.
1853 // Count total number of container entries required on each side
[1563]1854 l = 0;
1855 r = 0;
1856 ulRecsNeeded = 0;
[551]1857 while ((filesl && filesl[l]) || (filesr && filesr[r])) {
[748]1858
[1469]1859 if (cmp->stop)
1860 break; // Cancel requested
1861
[748]1862 if (filesl && filesl[l]) {
1863 if (filesr && filesr[r])
1864 x = stricmp(filesl[l]->fname, filesr[r]->fname);
[551]1865 else
[748]1866 x = -1; // Left side list longer
[551]1867 }
[748]1868 else
1869 x = +1; // Right side list longer
1870
1871 if (x <= 0)
1872 l++; // On left side
1873 if (x >= 0)
1874 r++; // On right side
1875
[1563]1876 ulRecsNeeded++; // Count how many entries req'd
[748]1877
[1563]1878 } // while counting
[748]1879
[1563]1880 if (cmp->stop)
1881 ulRecsNeeded = 0;
[748]1882
[1563]1883 // Insert records into the containers
[1469]1884
[1563]1885 if (ulRecsNeeded) {
[1469]1886
[1563]1887 PCNRITEM pcilFirst;
1888 PCNRITEM pcirFirst;
1889 PCNRITEM pcil = NULL;
1890 PCNRITEM pcir = NULL;
1891 INT ret;
1892 ULONG ulRecsAllocated = 0;
1893 ULONG insertedl;
1894 ULONG insertedr;
[1469]1895
[919]1896 l = 0;
1897 r = 0;
[907]1898
[1563]1899 // Use send to get message on screen quickly
1900 WinSendMsg(cmp->hwnd, UM_CONTAINERHWND, MPVOID, MPVOID);
1901
[919]1902 cmp->cmp->totalleft = 0;
1903 cmp->cmp->totalright = 0;
[907]1904
[551]1905 while ((filesl && filesl[l]) || (filesr && filesr[r])) {
[907]1906
[1563]1907 ULONG ulRecsToInsert; // limited to USHRT_MAX
1908
[1469]1909 if (cmp->stop)
1910 break;
1911
[1563]1912 // Check alloc needed
1913 if (!pcil || !pcir) {
1914 if (pcil != pcir) {
[1682]1915 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_LEFTRIGHTOUTOFSYNC));
[1563]1916 cmp->stop = TRUE;
1917 break;
1918 }
1919 ulRecsToInsert = ulRecsNeeded - ulRecsAllocated;
1920 if (ulRecsToInsert > USHRT_MAX)
1921 ulRecsToInsert = USHRT_MAX;
[907]1922
[1563]1923 pcilFirst = WinSendMsg(hwndLeft,
1924 CM_ALLOCRECORD,
1925 MPFROMLONG(EXTRA_RECORD_BYTES),
1926 MPFROMLONG(ulRecsToInsert));
1927 if (!pcilFirst) {
1928 Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
1929 cmp->stop = TRUE;
1930 break;
1931 }
1932 pcirFirst = WinSendMsg(hwndRight, CM_ALLOCRECORD,
1933 MPFROMLONG(EXTRA_RECORD_BYTES),
1934 MPFROMLONG(ulRecsToInsert));
1935 if (!pcirFirst) {
1936 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
1937 FreeCnrItemList(hwndLeft, pcilFirst);
1938 pcilFirst = NULL;
1939 cmp->stop = TRUE;
1940 break;
1941 }
1942 pcil = pcilFirst;
1943 pcir = pcirFirst;
1944 insertedl = 0;
1945 insertedr = 0;
1946 ulRecsAllocated += ulRecsToInsert;
1947 } // if need alloc
1948
[551]1949 pcir->hwndCnr = hwndRight;
[919]1950 pcir->rc.hptrIcon = (HPOINTER)0;
[551]1951 pcil->hwndCnr = hwndLeft;
[919]1952 pcil->rc.hptrIcon = (HPOINTER)0;
[748]1953
1954 if (filesl && filesl[l]) {
1955 if (filesr && filesr[r])
1956 x = stricmp(filesl[l]->fname, filesr[r]->fname);
1957 else
1958 x = -1; // Left side list longer
1959 }
1960 else
1961 x = +1; // Right side list longer
1962
1963 if (x <= 0) {
[769]1964 // File appears on left side
[919]1965 cmp->cmp->totalleft++;
[1563]1966 insertedl++;
[769]1967 BldFullPathName(szBuf, cmp->leftdir, filesl[l]->fname);
1968 pcil->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
[748]1969 pcil->pszDisplayName = pcil->pszFileName + lenl;
1970 pcil->attrFile = filesl[l]->attrFile;
[751]1971 pcil->pszDispAttr = FileAttrToString(pcil->attrFile);
[748]1972 pcil->cbFile = filesl[l]->cbFile;
[1444]1973 // 12 Jan 08 SHL fixme to use cached size here too
[919]1974 CommaFmtULL(szBuf, sizeof(szBuf), pcil->cbFile, ' ');
1975 pcil->pszFmtFileSize = xstrdup(szBuf, pszSrcFile, __LINE__);
[748]1976 pcil->easize = filesl[l]->easize;
1977 pcil->date.day = filesl[l]->date.day;
1978 pcil->date.month = filesl[l]->date.month;
1979 pcil->date.year = filesl[l]->date.year + 1980;
1980 pcil->time.seconds = filesl[l]->time.twosecs * 2;
1981 pcil->time.minutes = filesl[l]->time.minutes;
1982 pcil->time.hours = filesl[l]->time.hours;
1983 pcil->ladate.day = filesl[l]->ladate.day;
1984 pcil->ladate.month = filesl[l]->ladate.month;
1985 pcil->ladate.year = filesl[l]->ladate.year + 1980;
1986 pcil->latime.seconds = filesl[l]->latime.twosecs * 2;
1987 pcil->latime.minutes = filesl[l]->latime.minutes;
1988 pcil->latime.hours = filesl[l]->latime.hours;
1989 pcil->crdate.day = filesl[l]->crdate.day;
1990 pcil->crdate.month = filesl[l]->crdate.month;
1991 pcil->crdate.year = filesl[l]->crdate.year + 1980;
1992 pcil->crtime.seconds = filesl[l]->crtime.twosecs * 2;
1993 pcil->crtime.minutes = filesl[l]->crtime.minutes;
[1836]1994 pcil->crtime.hours = filesl[l]->crtime.hours;
1995 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
1996 if (cmp && *cmp->dcd.mask.szMask) {
[919]1997 if (!Filter((PMINIRECORDCORE)pcil, (PVOID)&cmp->dcd.mask)) {
[748]1998 pcil->rc.flRecordAttr |= CRA_FILTERED;
1999 pcir->rc.flRecordAttr |= CRA_FILTERED;
[1836]2000 }
2001 }
2002 DosReleaseMutexSem(hmtxFiltering);
[748]2003 } // if on left
2004
2005 if (x >= 0) {
[769]2006 // File appears on right side
[919]2007 cmp->cmp->totalright++;
[1563]2008 insertedr++;
[773]2009 BldFullPathName(szBuf, cmp->rightdir, filesr[r]->fname);
[769]2010 pcir->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__); // 31 Jul 07 SHL
[748]2011 pcir->pszDisplayName = pcir->pszFileName + lenr;
2012 pcir->attrFile = filesr[r]->attrFile;
[751]2013 pcir->pszDispAttr = FileAttrToString(pcir->attrFile);
[748]2014 pcir->cbFile = filesr[r]->cbFile;
[919]2015 // 12 Jan 08 SHL fixme to used cached size here too
2016 CommaFmtULL(szBuf, sizeof(szBuf), pcir->cbFile, ' ');
2017 pcir->pszFmtFileSize = xstrdup(szBuf, pszSrcFile, __LINE__);
[748]2018 pcir->easize = filesr[r]->easize;
2019 pcir->date.day = filesr[r]->date.day;
2020 pcir->date.month = filesr[r]->date.month;
2021 pcir->date.year = filesr[r]->date.year + 1980;
2022 pcir->time.seconds = filesr[r]->time.twosecs * 2;
2023 pcir->time.minutes = filesr[r]->time.minutes;
2024 pcir->time.hours = filesr[r]->time.hours;
2025 pcir->ladate.day = filesr[r]->ladate.day;
2026 pcir->ladate.month = filesr[r]->ladate.month;
2027 pcir->ladate.year = filesr[r]->ladate.year + 1980;
2028 pcir->latime.seconds = filesr[r]->latime.twosecs * 2;
2029 pcir->latime.minutes = filesr[r]->latime.minutes;
2030 pcir->latime.hours = filesr[r]->latime.hours;
2031 pcir->crdate.day = filesr[r]->crdate.day;
2032 pcir->crdate.month = filesr[r]->crdate.month;
2033 pcir->crdate.year = filesr[r]->crdate.year + 1980;
2034 pcir->crtime.seconds = filesr[r]->crtime.twosecs * 2;
2035 pcir->crtime.minutes = filesr[r]->crtime.minutes;
2036 pcir->crtime.hours = filesr[r]->crtime.hours;
[1836]2037 // Bypass check if already filtered on left side
2038 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
2039 if (cmp && ~pcir->rc.flRecordAttr & CRA_FILTERED &&
[748]2040 *cmp->dcd.mask.szMask) {
2041 if (!Filter((PMINIRECORDCORE)pcir, (PVOID)&cmp->dcd.mask)) {
2042 pcil->rc.flRecordAttr |= CRA_FILTERED;
2043 pcir->rc.flRecordAttr |= CRA_FILTERED;
[1836]2044 }
2045 }
2046 DosReleaseMutexSem(hmtxFiltering);
[748]2047 } // if on right
2048
2049 if (x == 0) {
2050 // File appears on both sides
[769]2051 pcil->flags |= CNRITEM_EXISTS;
2052 pcir->flags |= CNRITEM_EXISTS;
2053 pch = szBuf;
[748]2054 // Subject field holds status messages
2055 *pch = 0;
[1682]2056 if (pcil->cbFile > pcir->cbFile) {
[748]2057 pcil->flags |= CNRITEM_LARGER;
2058 pcir->flags |= CNRITEM_SMALLER;
2059 strcpy(pch, GetPString(IDS_LARGERTEXT));
2060 pch += 6;
2061 }
[1682]2062 else if (pcil->cbFile < pcir->cbFile) {
[748]2063 pcil->flags |= CNRITEM_SMALLER;
2064 pcir->flags |= CNRITEM_LARGER;
2065 strcpy(pch, GetPString(IDS_SMALLERTEXT));
2066 pch += 7;
[1683]2067 }
2068 if (pcil->easize != pcir->easize) {
2069 pcil->flags |= CNRITEM_EASDIFFER;
2070 pcir->flags |= CNRITEM_EASDIFFER;
2071 if (pch != szBuf) {
[1682]2072 strcpy(pch, ", ");
2073 pch += 2;
2074 }
2075 strcpy(pch, GetPString(IDS_EASDIFFERTEXT));
[1683]2076 pch += 10;
2077 }
[907]2078 ret = TestCDates(&pcir->date, &pcir->time,
2079 &pcil->date, &pcil->time);
[1469]2080 if (ret == 1) {
[748]2081 pcil->flags |= CNRITEM_NEWER;
2082 pcir->flags |= CNRITEM_OLDER;
[769]2083 if (pch != szBuf) {
[748]2084 strcpy(pch, ", ");
2085 pch += 2;
2086 }
2087 strcpy(pch, GetPString(IDS_NEWERTEXT));
2088 pch += 5;
2089 }
[1469]2090 else if (ret == -1) {
[748]2091 pcil->flags |= CNRITEM_OLDER;
2092 pcir->flags |= CNRITEM_NEWER;
[769]2093 if (pch != szBuf) {
[748]2094 strcpy(pch, ", ");
2095 pch += 2;
2096 }
2097 strcpy(pch, GetPString(IDS_OLDERTEXT));
2098 pch += 5;
2099 }
[769]2100 pcil->pszSubject = *szBuf ?
2101 xstrdup(szBuf, pszSrcFile, __LINE__) :
[751]2102 NullStr;
[748]2103
2104 } // if on both sides
2105
[1563]2106 if (x <= 0)
[919]2107 free(filesl[l++]); // Done with item on left
[1563]2108
2109 if (x >= 0)
[1175]2110 free(filesr[r++]); // Done with item on right
[1563]2111
[748]2112 // Ensure empty buffers point somewhere
2113 if (!pcil->pszFileName) {
2114 pcil->pszFileName = NullStr;
2115 pcil->pszDisplayName = pcil->pszFileName;
2116 }
2117
2118 if (!pcir->pszFileName) {
2119 pcir->pszFileName = NullStr;
2120 pcir->pszDisplayName = pcir->pszFileName;
2121 }
2122
[751]2123 pcil->rc.pszIcon = pcil->pszDisplayName;
2124 pcir->rc.pszIcon = pcir->pszDisplayName;
[748]2125
[762]2126 pcil->pszLongName = NullStr;
2127 pcir->pszLongName = NullStr;
[751]2128
[748]2129 if (!pcil->pszSubject)
2130 if (!pcir->pszSubject)
[790]2131 pcir->pszSubject = NullStr;
[748]2132
[751]2133 if (!pcil->pszDispAttr)
2134 pcil->pszDispAttr = NullStr;
2135 if (!pcir->pszDispAttr)
[790]2136 pcir->pszDispAttr = NullStr;
[751]2137
[907]2138 // Avoid hogging systems
2139 SleepIfNeeded(&itdSleep, 0);
[748]2140
[919]2141 pcil = (PCNRITEM)pcil->rc.preccNextRecord;
2142 pcir = (PCNRITEM)pcir->rc.preccNextRecord;
[748]2143
[1563]2144 if (pcil == NULL || pcir == NULL) {
2145 RECORDINSERT ri;
2146 if (pcil != pcir) {
2147 Runtime_Error(pszSrcFile, __LINE__, "pcil and pcir out of sync");
2148 cmp->stop = TRUE;
2149 break;
2150 }
2151 // Say inserting
2152 WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID);
2153
2154 // Insert left side
2155 memset(&ri, 0, sizeof(RECORDINSERT));
2156 ri.cb = sizeof(RECORDINSERT);
2157 ri.pRecordOrder = (PRECORDCORE)CMA_END;
2158 ri.pRecordParent = (PRECORDCORE)NULL;
2159 ri.zOrder = (ULONG)CMA_TOP;
2160 ri.cRecordsInsert = ulRecsToInsert;
2161 ri.fInvalidateRecord = FALSE;
2162
2163 if (!WinSendMsg(hwndLeft, CM_INSERTRECORD,
2164 MPFROMP(pcilFirst), MPFROMP(&ri))) {
2165 Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
2166 FreeCnrItemList(hwndLeft, pcilFirst);
2167 cmp->cmp->totalleft -= insertedl;
2168 }
2169 pcilFirst = NULL;
2170
2171 // Insert right side
2172 memset(&ri, 0, sizeof(RECORDINSERT));
2173 ri.cb = sizeof(RECORDINSERT);
2174 ri.pRecordOrder = (PRECORDCORE)CMA_END;
2175 ri.pRecordParent = (PRECORDCORE)NULL;
2176 ri.zOrder = (ULONG)CMA_TOP;
2177 ri.cRecordsInsert = ulRecsToInsert;
2178 ri.fInvalidateRecord = FALSE;
2179
2180 if (!WinSendMsg(hwndRight, CM_INSERTRECORD,
2181 MPFROMP(pcirFirst), MPFROMP(&ri))) {
2182 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
2183 // 2011-05-29 SHL fixme?
2184 RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
2185 FreeCnrItemList(hwndRight, pcirFirst);
2186 cmp->cmp->totalright -= insertedr;
2187 }
2188 pcirFirst = NULL;
2189 } // if need insert
2190
[748]2191 } // while filling left or right
2192
[1563]2193 // If stopped early clean up
2194
2195 if (cmp->stop) {
2196 // Free up container records that we did not insert in container
2197 if (pcilFirst)
2198 FreeCnrItemList(hwndLeft, pcilFirst);
2199
2200 // Free up items we did not insert in container
[907]2201 if (filesl) {
[1175]2202 for(; filesl[l]; l++) {
2203 free(filesl[l]);
2204 }
[907]2205 }
[1563]2206
2207 if (pcirFirst)
2208 FreeCnrItemList(hwndRight, pcirFirst);
2209
[907]2210 if (filesr) {
[1175]2211 for (; filesr[r]; r++) {
2212 free(filesr[r]);
2213 }
[907]2214 }
2215 } // if insufficient resources
2216
[1563]2217 xfree(filesl, pszSrcFile, __LINE__); // Free header - have already freed elements
[551]2218 filesl = NULL;
[1009]2219 xfree(filesr, pszSrcFile, __LINE__);
[551]2220 filesr = NULL;
[907]2221
[1563]2222 } // if ulRecsNeeded
[748]2223
[2]2224 Deselect(hwndLeft);
2225 Deselect(hwndRight);
[748]2226
[907]2227 // Request window update
[551]2228 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID))
2229 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[2]2230 notified = TRUE;
[748]2231
[362]2232 if (filesl)
[748]2233 FreeList((CHAR **)filesl); // Must have failed to create container
[362]2234 if (filesr)
[748]2235 FreeList((CHAR **)filesr);
2236
[2]2237 WinDestroyMsgQueue(hmq);
[907]2238 } // if have queue
2239 if (!notified)
2240 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
[535]2241 DecrThreadUsage();
[2]2242 WinTerminate(hab);
2243 }
[1836]2244 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
[1039]2245 free(cmp);
[1836]2246 cmp = NULL;
2247 DosReleaseMutexSem(hmtxFiltering);
[2]2248 DosPostEventSem(CompactSem);
[846]2249
[1009]2250# ifdef FORTIFY
[1038]2251 Fortify_LeaveScope();
[1063]2252# endif
[1009]2253
[2]2254}
2255
[1469]2256/**
2257 * Find matching item in other container
2258 * @return PCNRITEM or NULL
2259 */
[2]2260
[1469]2261static PCNRITEM FindMatchingItem(PCNRITEM pciFindS, HWND hwndCnrS, HWND hwndCnrD);
[2]2262
[1469]2263static PCNRITEM FindMatchingItem(PCNRITEM pciFindS, HWND hwndCnrS, HWND hwndCnrD)
2264{
2265
2266 PCNRITEM pciS;
2267 PCNRITEM pciD;
2268
2269 pciS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
2270 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2271 pciD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
2272 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2273 while (pciS && (INT)pciS != -1 && pciD && (INT)pciD != -1) {
2274
2275 if (pciS == pciFindS)
2276 break;
2277
2278 pciS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pciS),
2279 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2280 pciD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
2281 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2282 } // while
2283
2284 if (pciS != pciFindS)
2285 pciD = NULL;
2286
2287 return pciD;
2288}
2289
2290/**
2291 * Set button/window enables
2292 */
2293
2294static VOID SetButtonEnables(COMPARE* cmp, BOOL fEnable);
2295
2296static VOID SetButtonEnables(COMPARE* cmp, BOOL fEnable)
2297{
2298 HWND hwnd = cmp->hwnd;
2299 HWND hwndLeft = GetHwndLeft(hwnd);
2300 HWND hwndRight = GetHwndRight(hwnd);
2301
2302 if (!fEnable) {
[1673]2303 // Disable before
[1469]2304 WinEnableWindowUpdate(hwndLeft, fEnable);
2305 WinEnableWindowUpdate(hwndRight, fEnable);
2306 }
2307 WinEnableWindow(hwndLeft, fEnable);
2308 WinEnableWindow(hwndRight, fEnable);
2309 if (fEnable) {
[1673]2310 // Enable after
[1469]2311 WinEnableWindowUpdate(hwndLeft, fEnable);
2312 WinEnableWindowUpdate(hwndRight, fEnable);
2313 }
2314
2315 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), fEnable);
2316 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), fEnable);
2317 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), fEnable);
2318 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), fEnable);
2319 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), fEnable);
[1684]2320 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTEAS), fEnable); // 2013-03-09 SHL
[1469]2321 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), fEnable);
2322 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), fEnable);
2323 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), fEnable);
2324 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), fEnable);
2325 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), fEnable);
2326 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), fEnable);
[1684]2327 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTEAS), fEnable); // 2013-03-09 SHL
[1469]2328 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), fEnable);
2329 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), fEnable);
2330 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), fEnable);
2331 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), fEnable);
2332 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), fEnable);
2333 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), fEnable);
2334 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), fEnable);
2335 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), fEnable);
2336 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), fEnable);
2337 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), fEnable);
2338 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), fEnable);
[1682]2339 if (!fEnable || !*cmp->rightlist) {
[1469]2340 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), fEnable);
2341 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), fEnable);
2342 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), fEnable);
2343 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), fEnable);
2344 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), fEnable);
2345 }
2346 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), fEnable);
2347 WinEnableWindow(WinWindowFromID(hwnd, COMP_HIDENOTSELECTED), fEnable);
[1684]2348 WinEnableWindow(WinWindowFromID(hwnd, COMP_CONFIRMACTION), fEnable); // 2013-03-09 SHL
[1469]2349}
2350
2351/**
2352 * Compare directories dialog procedure
2353 */
2354
[551]2355MRESULT EXPENTRY CompareDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
[316]2356{
[551]2357 COMPARE *cmp;
[773]2358 BOOL temp;
[1469]2359 CHAR szPathName[CCHMAXPATH];
[907]2360 CHAR s[81];
[362]2361
[773]2362 static HPOINTER hptr;
[2]2363
[551]2364 switch (msg) {
2365 case WM_INITDLG:
[919]2366 cmp = (COMPARE *)mp2;
[551]2367 if (!cmp) {
[1398]2368 Runtime_Error(pszSrcFile, __LINE__, NULL);
[551]2369 WinDismissDlg(hwnd, 0);
2370 }
2371 else {
2372 if (!hptr)
2373 hptr = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, COMPARE_ICON);
2374 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptr), MPVOID);
2375 cmp->hwnd = hwnd;
[919]2376 WinSetWindowPtr(hwnd, QWL_USER, (PVOID)cmp);
[938]2377 {
[1175]2378 SWP swp;
2379 ULONG size = sizeof(SWP);
[938]2380
[1505]2381 PrfQueryProfileData(fmprof, FM3Str, "CompDir.Position", (PVOID) &swp, &size);
[1394]2382 swp.fl &= ~SWP_SIZE; // 04 Feb 09 SHL ignore saved size
[1175]2383 WinSetWindowPos(hwnd,
2384 HWND_TOP,
2385 swp.x,
2386 swp.y,
2387 swp.cx,
2388 swp.cy,
2389 swp.fl);
[938]2390 }
[1469]2391 SetCnrCols(GetHwndLeft(hwnd), TRUE);
2392 SetCnrCols(GetHwndRight(hwnd), TRUE);
[1670]2393 if (cmp->listfile) {
[1683]2394 CHAR fullname[CCHMAXPATH];
[1670]2395
2396 strcpy(fullname, PCSZ_STARDOTPMD);
2397 if (insert_filename(HWND_DESKTOP, fullname, TRUE, FALSE) &&
2398 *fullname && !strchr(fullname, '*') && !strchr(fullname, '?'))
[1683]2399 strcpy(cmp->rightlist, fullname);
[1670]2400 }
[551]2401 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2402 WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2403 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
2404 {
[1683]2405 USHORT ids[] = {COMP_FRAME, COMP_LEFTDIR, COMP_RIGHTDIR, COMP_COLLECT,
[1684]2406 COMP_VIEW, COMP_NOTE, COMP_TOTALLEFT, COMP_SELLEFT, COMP_TOTALRIGHT,
2407 COMP_SELRIGHT, COMP_CNRMENU, COMP_DIRMENU, COMP_MENU,
2408 COMP_INCLUDESUBDIRS, COMP_SETDIRS, COMP_COPYLEFT, COMP_MOVELEFT,
2409 COMP_DELETELEFT, COMP_COPYRIGHT, COMP_MOVERIGHT, COMP_DELETERIGHT,
2410 COMP_TOTALLEFTHDR, COMP_SELLEFTHDR, COMP_TOTALRIGHTHDR,
2411 COMP_SELRIGHTHDR, COMP_FILTER, COMP_HIDENOTSELECTED, 0};
[919]2412 UINT x;
[1683]2413 CHAR s[24];
[1670]2414
[1394]2415 for (x = 0; ids[x]; x++) {
[1683]2416 sprintf(s, "CompDir%i", ids[x]);
2417 RestorePresParams(WinWindowFromID(hwnd, ids[x]), s);
[924]2418 }
[2]2419 }
[1444]2420 WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_COMP_TIMER, 500);
[551]2421 }
2422 break;
[2]2423
[551]2424 case UM_STRETCH:
2425 {
2426 SWP swp, swpC;
2427 LONG titl, szbx, szby, sz;
2428 HWND hwndActive;
[2]2429
[551]2430 WinQueryWindowPos(hwnd, &swp);
2431 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
2432 hwndActive = WinQueryFocus(HWND_DESKTOP);
2433 szbx = SysVal(SV_CXSIZEBORDER);
2434 szby = SysVal(SV_CYSIZEBORDER);
2435 titl = SysVal(SV_CYTITLEBAR);
2436 titl += 26;
2437 swp.cx -= (szbx * 2);
2438 sz = (swp.cx / 8);
2439 WinQueryWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), &swpC);
2440 WinSetWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), HWND_TOP,
2441 szbx + 6,
2442 swpC.y,
2443 (swp.cx / 2) - (szbx + 6),
2444 ((swp.cy - swpC.y) - titl) - szby,
2445 SWP_MOVE | SWP_SIZE);
2446 WinSetWindowPos(WinWindowFromID(hwnd, COMP_RIGHTDIR), HWND_TOP,
2447 (swp.cx / 2) + (szbx + 6),
2448 swpC.y,
2449 (swp.cx / 2) - (szbx + 6),
2450 ((swp.cy - swpC.y) - titl) - szby,
2451 SWP_MOVE | SWP_SIZE);
2452 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFTHDR), HWND_TOP,
2453 szbx + 6,
2454 ((swp.cy - titl) - szby) + 4,
2455 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2456 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFT), HWND_TOP,
2457 sz + (szbx + 6),
2458 ((swp.cy - titl) - szby) + 4,
2459 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2460 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFTHDR), HWND_TOP,
2461 (sz * 2) + (szbx + 6),
2462 ((swp.cy - titl) - szby) + 4,
2463 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2464 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFT), HWND_TOP,
2465 (sz * 3) + (szbx + 6),
2466 ((swp.cy - titl) - szby) + 4,
2467 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2468 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHTHDR), HWND_TOP,
2469 (sz * 4) + (szbx + 6),
2470 ((swp.cy - titl) - szby) + 4,
2471 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2472 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHT), HWND_TOP,
2473 (sz * 5) + (szbx + 6),
2474 ((swp.cy - titl) - szby) + 4,
2475 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2476 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHTHDR), HWND_TOP,
2477 (sz * 6) + (szbx + 6),
2478 ((swp.cy - titl) - szby) + 4,
2479 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2480 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHT), HWND_TOP,
2481 (sz * 7) + (szbx + 6),
2482 ((swp.cy - titl) - szby) + 4,
2483 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2484 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALLEFT),
[919]2485 (HPS)0, FALSE, FALSE);
[551]2486 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELLEFT),
[919]2487 (HPS)0, FALSE, FALSE);
[551]2488 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALRIGHT),
[919]2489 (HPS)0, FALSE, FALSE);
[551]2490 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELRIGHT),
[919]2491 (HPS)0, FALSE, FALSE);
[1469]2492 PaintRecessedWindow(GetHwndLeft(hwnd), (HPS)0,
2493 (hwndActive == GetHwndLeft(hwnd)), TRUE);
2494 PaintRecessedWindow(GetHwndRight(hwnd), (HPS)0,
2495 (hwndActive == GetHwndRight(hwnd)), TRUE);
[2]2496 }
[551]2497 }
2498 return 0;
[2]2499
[551]2500 case WM_ADJUSTWINDOWPOS:
2501 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
2502 break;
[2]2503
[551]2504 case UM_SETUP:
2505 {
2506 CNRINFO cnri;
2507 BOOL tempsubj;
[2]2508
[551]2509 cmp = INSTDATA(hwnd);
[919]2510 if (!cmp)
[1398]2511 Runtime_Error(pszSrcFile, __LINE__, NULL);
[919]2512 else {
[551]2513 cmp->dcd.size = sizeof(DIRCNRDATA);
2514 cmp->dcd.type = DIR_FRAME;
2515 cmp->dcd.hwndFrame = hwnd;
2516 cmp->dcd.hwndClient = hwnd;
2517 cmp->dcd.mask.attrFile = (FILE_DIRECTORY | FILE_ARCHIVED |
2518 FILE_READONLY | FILE_SYSTEM | FILE_HIDDEN);
[1409]2519 LoadDetailsSwitches(PCSZ_DIRCMP, &cmp->dcd.ds, FALSE);
[1065]2520 cmp->dcd.ds.detailslongname = FALSE;
2521 cmp->dcd.ds.detailsicon = FALSE; // TRUE;
[2]2522 }
[551]2523 memset(&cnri, 0, sizeof(CNRINFO));
2524 cnri.cb = sizeof(CNRINFO);
2525 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_QUERYCNRINFO,
2526 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
2527 cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
2528 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 68;
2529 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2530 MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
2531 memset(&cnri, 0, sizeof(CNRINFO));
2532 cnri.cb = sizeof(CNRINFO);
2533 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_QUERYCNRINFO,
2534 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
2535 cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
2536 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 54;
2537 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2538 MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
[1469]2539 AdjustCnrColRO(GetHwndLeft(hwnd), GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
2540 AdjustCnrColRO(GetHwndLeft(hwnd), GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
2541 AdjustCnrColRO(GetHwndRight(hwnd), GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
2542 AdjustCnrColRO(GetHwndRight(hwnd), GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
2543 AdjustCnrColsForPref(GetHwndLeft(hwnd), cmp->leftdir, &cmp->dcd.ds, TRUE);
[1065]2544 tempsubj = cmp->dcd.ds.detailssubject;
2545 cmp->dcd.ds.detailssubject = FALSE;
[1469]2546 AdjustCnrColsForPref(GetHwndRight(hwnd), cmp->rightdir, &cmp->dcd.ds, TRUE);
[551]2547 if (*cmp->rightlist) {
[1469]2548 AdjustCnrColVis(GetHwndRight(hwnd), GetPString(IDS_LADATECOLTEXT), FALSE,
[551]2549 FALSE);
[1469]2550 AdjustCnrColVis(GetHwndRight(hwnd), GetPString(IDS_LATIMECOLTEXT), FALSE,
[551]2551 FALSE);
[1469]2552 AdjustCnrColVis(GetHwndRight(hwnd), GetPString(IDS_CRDATECOLTEXT), FALSE,
[551]2553 FALSE);
[1469]2554 AdjustCnrColVis(GetHwndRight(hwnd), GetPString(IDS_CRTIMECOLTEXT), FALSE,
[551]2555 FALSE);
2556 }
[1065]2557 cmp->dcd.ds.detailssubject = tempsubj;
[551]2558 }
2559 return 0;
[2]2560
[551]2561 case WM_DRAWITEM:
2562 if (mp2) {
[748]2563 POWNERITEM pown = (POWNERITEM)mp2;
[551]2564 PCNRDRAWITEMINFO pcown;
2565 PCNRITEM pci;
[2]2566
[748]2567 pcown = (PCNRDRAWITEMINFO)pown->hItem;
[551]2568 if (pcown) {
[919]2569 pci = (PCNRITEM)pcown->pRecord;
[748]2570 // 01 Aug 07 SHL if field null or blank, we draw
[929]2571 // fixme to document why - probably to optimize and bypass draw?
[1836]2572 if (pci && (INT)pci != -1 && !*pci->pszFileName && pci->pszFileName != NullStr)
[551]2573 return MRFROMLONG(TRUE);
[2]2574 }
[551]2575 }
2576 return 0;
[2]2577
[551]2578 case UM_CONTAINERHWND:
[907]2579 // Building list
[1498]2580 WinSetDlgItemText(hwnd, COMP_NOTE, (CHAR *) GetPString(IDS_COMPHOLDBLDLISTTEXT));
[551]2581 return 0;
[2]2582
[551]2583 case UM_CONTAINERDIR:
[907]2584 // Filling container
[1498]2585 WinSetDlgItemText(hwnd, COMP_NOTE, (CHAR *) GetPString(IDS_COMPHOLDFILLCNRTEXT));
[551]2586 return 0;
[2]2587
[907]2588 case WM_TIMER:
2589 // Show current totals
2590 cmp = INSTDATA(hwnd);
2591 if (!cmp) {
2592 Runtime_Error(pszSrcFile, __LINE__, "pCompare NULL");
2593 WinDismissDlg(hwnd, 0);
2594 }
2595 else {
[929]2596 if (cmp->uOldTotalLeft != cmp->totalleft) {
2597 cmp->uOldTotalLeft = cmp->totalleft;
2598 sprintf(s, " %d", cmp->totalleft);
2599 WinSetDlgItemText(hwnd, COMP_TOTALLEFT, s);
2600 }
2601 if (cmp->uOldTotalRight != cmp->totalright) {
2602 cmp->uOldTotalRight = cmp->totalright;
2603 sprintf(s, " %d", cmp->totalright);
2604 WinSetDlgItemText(hwnd, COMP_TOTALRIGHT, s);
2605 }
2606 if (cmp->uOldSelLeft != cmp->selleft) {
2607 cmp->uOldSelLeft = cmp->selleft;
2608 sprintf(s, " %d", cmp->selleft);
2609 WinSetDlgItemText(hwnd, COMP_SELLEFT, s);
2610 }
2611 if (cmp->uOldSelRight != cmp->selright) {
2612 cmp->uOldSelRight = cmp->selright;
2613 sprintf(s, " %d", cmp->selright);
2614 WinSetDlgItemText(hwnd, COMP_SELRIGHT, s);
2615 }
[907]2616 }
2617 break;
2618
[551]2619 case UM_CONTAINER_FILLED:
2620 cmp = INSTDATA(hwnd);
2621 if (!cmp) {
2622 Runtime_Error(pszSrcFile, __LINE__, "pCompare NULL");
2623 WinDismissDlg(hwnd, 0);
2624 }
[1469]2625 else if (cmp->stop) {
2626 // Delayed cancel
2627 WinDismissDlg(hwnd, 1);
2628 }
[551]2629 else {
2630 cmp->filling = FALSE;
[1469]2631 SetButtonEnables(cmp, TRUE);
2632 WinPostMsg(hwnd, WM_TIMER, MPFROMLONG(ID_COMP_TIMER), 0); // Force counts to update
[919]2633 if (*cmp->dcd.mask.szMask) {
[1469]2634 sprintf(s, GetPString(IDS_COMPREADYFILTEREDTEXT), cmp->dcd.mask.szMask);
[919]2635 WinSetDlgItemText(hwnd, COMP_NOTE, s);
2636 }
[551]2637 else
[1498]2638 WinSetDlgItemText(hwnd, COMP_NOTE, (CHAR *) GetPString(IDS_COMPREADYTEXT));
[551]2639 }
2640 break;
2641
2642 case WM_INITMENU:
2643 cmp = INSTDATA(hwnd);
2644 if (cmp) {
2645 switch (SHORT1FROMMP(mp1)) {
2646 case IDM_COMMANDSMENU:
2647 SetupCommandMenu(cmp->dcd.hwndLastMenu, hwnd);
2648 break;
[2]2649 }
[551]2650 }
2651 break;
[2]2652
[551]2653 case WM_MENUEND:
2654 cmp = INSTDATA(hwnd);
2655 if (cmp) {
[919]2656 if ((HWND)mp2 == cmp->dcd.hwndLastMenu) {
[1469]2657 MarkAll(GetHwndLeft(hwnd), TRUE, FALSE, TRUE);
2658 MarkAll(GetHwndRight(hwnd), TRUE, FALSE, TRUE);
[551]2659 WinDestroyWindow(cmp->dcd.hwndLastMenu);
[919]2660 cmp->dcd.hwndLastMenu = (HWND)0;
[2]2661 }
[551]2662 }
2663 break;
[2]2664
[551]2665 case WM_CONTROL:
2666 switch (SHORT1FROMMP(mp1)) {
2667 case COMP_INCLUDESUBDIRS:
2668 switch (SHORT2FROMMP(mp1)) {
2669 case BN_CLICKED:
2670 cmp = INSTDATA(hwnd);
2671 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2672 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2673 break;
[2]2674 }
2675 break;
[551]2676 case COMP_HIDENOTSELECTED:
2677 switch (SHORT2FROMMP(mp1)) {
2678 case BN_CLICKED:
2679 WinSendMsg(hwnd, UM_HIDENOTSELECTED, MPVOID, MPVOID);
2680 break;
2681 }
2682 break;
[2]2683
[551]2684 case COMP_LEFTDIR:
2685 case COMP_RIGHTDIR:
2686 switch (SHORT2FROMMP(mp1)) {
2687 case CN_KILLFOCUS:
2688 PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
[919]2689 (HPS)0, FALSE, TRUE);
[551]2690 break;
[2]2691
[551]2692 case CN_SETFOCUS:
2693 PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
[919]2694 (HPS)0, TRUE, TRUE);
[551]2695 break;
[2]2696
[551]2697 case CN_ENTER:
2698 if (mp2) {
[2]2699
[919]2700 PCNRITEM pci = (PCNRITEM)((PNOTIFYRECORDENTER)mp2)->pRecord;
[551]2701 HWND hwndCnr = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
[2]2702
[551]2703 SetShiftState();
2704 if (pci) {
[748]2705 if (pci->rc.flRecordAttr & CRA_INUSE || !pci || !*pci->pszFileName)
[551]2706 break;
2707 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
2708 MPFROM2SHORT(TRUE, CRA_INUSE));
2709 if (pci->attrFile & FILE_DIRECTORY) {
2710 if ((shiftstate & (KC_CTRL | KC_SHIFT)) == (KC_CTRL | KC_SHIFT))
[730]2711 OpenObject(pci->pszFileName, Settings, hwnd);
[551]2712 else
[730]2713 OpenObject(pci->pszFileName, Default, hwnd);
[551]2714 }
2715 else
2716 DefaultViewKeys(hwnd, hwnd, HWND_DESKTOP, NULL,
[730]2717 pci->pszFileName);
[551]2718 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS,
2719 MPFROMP(pci),
[919]2720 MPFROM2SHORT(FALSE,
2721 CRA_INUSE | (fUnHilite ? CRA_SELECTED : 0)));
[551]2722 }
2723 }
2724 break;
[2]2725
[551]2726 case CN_CONTEXTMENU:
2727 cmp = INSTDATA(hwnd);
2728 if (cmp) {
[919]2729 PCNRITEM pci = (PCNRITEM)mp2;
[1469]2730 USHORT id = COMP_CNRMENU; // Assume container menu
[2]2731
[551]2732 if (cmp->dcd.hwndLastMenu)
2733 WinDestroyWindow(cmp->dcd.hwndLastMenu);
[919]2734 cmp->dcd.hwndLastMenu = (HWND)0;
[551]2735 cmp->hwndCalling = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
2736 if (pci) {
[748]2737 if (!pci || !*pci->pszFileName || *cmp->rightlist)
[551]2738 break;
[1469]2739 id = COMP_MENU; // Want container item menu
[551]2740 WinSendMsg(cmp->hwndCalling, CM_SETRECORDEMPHASIS,
2741 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
2742 }
2743 cmp->dcd.hwndLastMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
2744 if (cmp->dcd.hwndLastMenu) {
[1469]2745 switch (id) {
2746 case COMP_CNRMENU:
[551]2747 if (SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
2748 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2749 MPFROM2SHORT(IDM_SHOWSUBJECT, FALSE), MPVOID);
[1065]2750 SetDetailsSwitches(cmp->dcd.hwndLastMenu, &cmp->dcd.ds);
[551]2751 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR)
2752 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2753 MPFROM2SHORT(IDM_LOADLISTFILE, 0), MPVOID);
2754 else if (*cmp->rightlist)
2755 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2756 MPFROM2SHORT(IDM_SAVELISTFILE, 0), MPVOID);
[1469]2757 break;
2758 case COMP_MENU:
2759 // Can't compare what's not there
2760 if (~pci->flags & CNRITEM_EXISTS) {
2761 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2762 MPFROM2SHORT(IDM_COMPARE, 0), MPVOID);
2763 }
2764 break;
2765 } // switch
[551]2766 PopupMenu(hwnd, hwnd, cmp->dcd.hwndLastMenu);
2767 }
2768 }
2769 break;
[2]2770
[551]2771 case CN_INITDRAG:
2772 cmp = INSTDATA(hwnd);
2773 if (*cmp->rightlist && SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
2774 break;
2775 DoFileDrag(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
[919]2776 (HWND)0, mp2, NULL, NULL, TRUE);
[551]2777 break;
[2]2778
[551]2779 case CN_BEGINEDIT:
2780 case CN_REALLOCPSZ:
[929]2781 // fixme to be gone - field edits not allowed?
[551]2782 Runtime_Error(pszSrcFile, __LINE__,
2783 "CN_BEGINEDIT/CN_REALLOCPSZ unexpected");
2784 break;
[2]2785
[551]2786 case CN_EMPHASIS:
2787 {
[919]2788 PNOTIFYRECORDEMPHASIS pnre = mp2;
[929]2789 BOOL fSelected;
[919]2790 if (pnre->fEmphasisMask & CRA_SELECTED) {
[929]2791 // Select toggled
[919]2792 PCNRITEM pci = (PCNRITEM)pnre->pRecord;
[551]2793 if (pci) {
[919]2794 if (!*pci->pszFileName) {
[1470]2795 // User clicked on empty slot - just clear
[551]2796 if (pci->rc.flRecordAttr & CRA_SELECTED)
2797 WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1),
2798 CM_SETRECORDEMPHASIS,
2799 MPFROMP(pci),
2800 MPFROM2SHORT(FALSE, CRA_SELECTED));
2801 }
2802 else {
[929]2803 BOOL fUpdateHideButton = FALSE;
[551]2804 cmp = INSTDATA(hwnd);
[919]2805 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR) {
[929]2806 fSelected = pci->rc.flRecordAttr & CRA_SELECTED;
2807 cmp->selleft += fSelected ? 1 : -1;
2808 if (!fSelected)
2809 fUpdateHideButton = TRUE;
[551]2810 }
[919]2811 else if (SHORT1FROMMP(mp1) == COMP_RIGHTDIR) {
[929]2812 fSelected = pci->rc.flRecordAttr & CRA_SELECTED;
2813 cmp->selright += fSelected ? 1 : -1;
2814 if (!fSelected)
2815 fUpdateHideButton = TRUE;
[551]2816 }
[919]2817 else {
2818 Runtime_Error(pszSrcFile, __LINE__,
2819 "mp1 %u unexpected", SHORT1FROMMP(mp1));
2820 }
[929]2821 if (fUpdateHideButton) {
[1029]2822 ULONG state = WinQueryButtonCheckstate(hwnd,COMP_HIDENOTSELECTED);
[929]2823 if (state == 1) {
2824 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 2);
2825 }
2826 }
[551]2827 }
2828 }
2829 }
2830 }
2831 break;
[2]2832
[551]2833 case CN_SCROLL:
2834 cmp = INSTDATA(hwnd);
2835 if (!cmp->forcescroll) {
[2]2836
[551]2837 PNOTIFYSCROLL pns = mp2;
[2]2838
[551]2839 if (pns->fScroll & CMA_VERTICAL) {
2840 cmp->forcescroll = TRUE;
[919]2841 // Scroll other window to match
2842 WinSendDlgItemMsg(hwnd,
2843 SHORT1FROMMP(mp1) == COMP_LEFTDIR ?
2844 COMP_RIGHTDIR : COMP_LEFTDIR,
2845 CM_SCROLLWINDOW,
2846 MPFROMSHORT(CMA_VERTICAL),
[551]2847 MPFROMLONG(pns->lScrollInc));
2848 cmp->forcescroll = FALSE;
2849 }
2850 }
2851 break;
[919]2852 } // switch COMP_LEFTDIR mp1
2853 break; // COMP_LEFTDIR / COMP_RIGHTDIR
2854 } // switch WM_CONTROL mp1
[551]2855 return 0; // WM_CONTROL
[2]2856
[551]2857 case UM_SETDIR:
2858 cmp = INSTDATA(hwnd);
2859 if (cmp) {
2860 COMPARE *forthread;
2861 CNRINFO cnri;
[1670]2862 if (cmp->includesubdirs)
[1683]2863 WinCheckButton(hwnd, COMP_INCLUDESUBDIRS, TRUE);
[551]2864 cmp->includesubdirs = WinQueryButtonCheckstate(hwnd,
[1683]2865 COMP_INCLUDESUBDIRS);
[551]2866 memset(&cnri, 0, sizeof(CNRINFO));
2867 cnri.cb = sizeof(CNRINFO);
2868 cnri.pszCnrTitle = cmp->leftdir;
2869 cnri.flWindowAttr = CV_DETAIL | CV_MINI |
[751]2870 CA_CONTAINERTITLE | CA_TITLESEPARATOR |
2871 CA_DETAILSVIEWTITLES | CA_OWNERDRAW;
[551]2872 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
[1684]2873 MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
[1681]2874 WinSetDlgItemText(hwnd, COMP_LISTLOADED, "");
[551]2875 cnri.pszCnrTitle = cmp->rightdir;
2876 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2877 MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
2878 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 0);
2879 cmp->filling = TRUE;
[1063]2880# ifdef FORTIFY
2881 Fortify_EnterScope();
2882# endif
[551]2883 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2884 if (!forthread)
2885 WinDismissDlg(hwnd, 0);
2886 else {
2887 *forthread = *cmp;
2888 forthread->cmp = cmp;
[1335]2889 if (xbeginthread(FillCnrsThread,
2890 122880,
2891 forthread,
2892 pszSrcFile,
2893 __LINE__) == -1)
2894 {
[551]2895 WinDismissDlg(hwnd, 0);
[1175]2896 free(forthread);
2897# ifdef FORTIFY
2898 Fortify_LeaveScope();
2899# endif
[551]2900 }
[362]2901 else {
[551]2902 WinSetDlgItemText(hwnd, COMP_NOTE,
[1498]2903 (CHAR *) GetPString(IDS_COMPHOLDREADDISKTEXT));
[1683]2904 SetButtonEnables(cmp, FALSE);
2905 cmp->includesubdirs = FALSE;
[1469]2906 cmp->selleft = 0;
2907 cmp->selright = 0;
[551]2908 }
[2]2909 }
[551]2910 }
2911 return 0;
[2]2912
[551]2913 case UM_FILTER:
2914 cmp = INSTDATA(hwnd);
2915 if (cmp) {
[1573]2916 if (mp1)
[919]2917 SetMask((CHAR *)mp1, &cmp->dcd.mask);
[1573]2918
[919]2919 WinSetDlgItemText(hwnd, COMP_NOTE,
[1498]2920 (CHAR *) GetPString(IDS_COMPHOLDFILTERINGTEXT));
[919]2921 priority_idle(); // Don't hog resources
[1469]2922 WinSendMsg(GetHwndLeft(hwnd), CM_FILTER, MPFROMP(Filter),
[551]2923 MPFROMP(&cmp->dcd.mask));
[1469]2924 WinSendMsg(GetHwndRight(hwnd), CM_FILTER, MPFROMP(Filter),
[551]2925 MPFROMP(&cmp->dcd.mask));
[919]2926 priority_normal();
2927 if (*cmp->dcd.mask.szMask) {
2928 sprintf(s,
2929 GetPString(IDS_COMPREADYFILTEREDTEXT),
2930 cmp->dcd.mask.szMask);
2931 WinSetDlgItemText(hwnd, COMP_NOTE, s);
2932 }
[551]2933 else
[1498]2934 WinSetDlgItemText(hwnd, COMP_NOTE, (CHAR *) GetPString(IDS_COMPREADYTEXT));
[551]2935 }
2936 return 0;
[2]2937
[551]2938 case UM_HIDENOTSELECTED:
2939 cmp = INSTDATA(hwnd);
2940 if (cmp) {
[1029]2941 ULONG wasHidden = WinQueryButtonCheckstate(hwnd,
[1469]2942 COMP_HIDENOTSELECTED);
2943 ULONG nowHidden = wasHidden != 1 && (cmp->selleft || cmp->selright);
[316]2944
[1175]2945 // cmp->dcd.suspendview = 1; // 12 Jan 08 SHL appears not to be used here
[1469]2946 // 26 Sep 09 SHL Unhide if nothing selected
2947 if (nowHidden) {
2948 // Hide items not selected on both sides
[551]2949 BOOL needRefresh = FALSE;
2950 HWND hwndl = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
2951 HWND hwndr = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
2952 PCNRITEM pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPVOID,
2953 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2954 PCNRITEM pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPVOID,
2955 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2956
[919]2957 while (pcil && (INT)pcil != -1 && pcir && (INT)pcir != -1) {
[551]2958 if (~pcil->rc.flRecordAttr & CRA_SELECTED &&
2959 ~pcir->rc.flRecordAttr & CRA_SELECTED) {
[1469]2960 if (~pcil->rc.flRecordAttr & CRA_FILTERED) {
2961 needRefresh = TRUE;
2962 pcil->rc.flRecordAttr |= CRA_FILTERED;
2963 }
2964 if (~pcir->rc.flRecordAttr & CRA_FILTERED) {
2965 pcir->rc.flRecordAttr |= CRA_FILTERED;
2966 needRefresh = TRUE;
2967 }
[316]2968 }
[551]2969 pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPFROMP(pcil),
2970 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2971 pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPFROMP(pcir),
2972 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
[748]2973 } // while
[551]2974 if (needRefresh) {
2975 WinSendMsg(hwndl, CM_INVALIDATERECORD,
2976 MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
2977 WinSendMsg(hwndr, CM_INVALIDATERECORD,
2978 MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
[316]2979 }
2980 }
[551]2981 else {
[929]2982 // Unhide
[1469]2983 WinSendMsg(GetHwndLeft(hwnd), CM_FILTER, MPFROMP(Filter),
[551]2984 MPFROMP(&cmp->dcd.mask));
[1469]2985 WinSendMsg(GetHwndRight(hwnd), CM_FILTER, MPFROMP(Filter),
[551]2986 MPFROMP(&cmp->dcd.mask));
2987 }
[919]2988 if (*cmp->dcd.mask.szMask) {
2989 sprintf(s,
2990 GetPString(IDS_COMPREADYFILTEREDTEXT),
2991 cmp->dcd.mask.szMask);
2992 WinSetDlgItemText(hwnd, COMP_NOTE, s);
2993 }
[551]2994 else
[1498]2995 WinSetDlgItemText(hwnd, COMP_NOTE, (CHAR *) GetPString(IDS_COMPREADYTEXT));
[1469]2996 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, nowHidden);
[551]2997 }
2998 return 0;
[316]2999
[551]3000 case WM_COMMAND:
[1469]3001 // 29 Apr 09 SHL fixme to support more context menu items - IDM_VIEW, IDM_EDIT etc.
[551]3002 switch (SHORT1FROMMP(mp1)) {
3003 case IDM_COMPARE:
3004 cmp = INSTDATA(hwnd);
3005 if (cmp) {
3006 PCNRITEM pci;
[919]3007 pci = (PCNRITEM)WinSendMsg(cmp->hwndCalling,
3008 CM_QUERYRECORDEMPHASIS,
3009 MPFROMLONG(CMA_FIRST),
3010 MPFROMSHORT(CRA_CURSORED));
[748]3011 if (pci && *pci->pszFileName) {
[1469]3012 if (cmp->hwndCalling == GetHwndLeft(hwnd))
3013 strcpy(szPathName, cmp->rightdir);
[551]3014 else
[1469]3015 strcpy(szPathName, cmp->leftdir);
3016 AddBackslashToPath(szPathName);
3017 strcat(szPathName, pci->pszDisplayName);
[551]3018 if (*compare) {
3019 CHAR *fakelist[3];
[730]3020 fakelist[0] = pci->pszFileName;
[1469]3021 fakelist[1] = szPathName;
[551]3022 fakelist[2] = NULL;
[1563]3023 ExecOnList(hwnd, compare, WINDOWED | SEPARATEKEEP,
3024 NULL, NULL, fakelist, NULL,
[907]3025 pszSrcFile, __LINE__);
[551]3026 }
3027 else {
3028 FCOMPARE fc;
3029 memset(&fc, 0, sizeof(fc));
3030 fc.size = sizeof(fc);
3031 fc.hwndParent = hwnd;
[730]3032 strcpy(fc.file1, pci->pszFileName);
[1469]3033 strcpy(fc.file2, szPathName);
[551]3034 WinDlgBox(HWND_DESKTOP, hwnd,
[919]3035 CFileDlgProc, FM3ModHandle, FCMP_FRAME, (PVOID)&fc);
[551]3036 }
3037 }
3038 }
3039 break;
[2]3040
[1469]3041 case IDM_DELETE:
3042 cmp = INSTDATA(hwnd);
3043 if (!cmp)
3044 Runtime_Error(pszSrcFile, __LINE__, NULL);
3045 else {
3046 PCNRITEM pciS;
3047 PCNRITEM pciD;
3048 HWND hwndCnrS;
3049 HWND hwndCnrD;
3050 pciS = (PCNRITEM)WinSendMsg(cmp->hwndCalling,
3051 CM_QUERYRECORDEMPHASIS,
3052 MPFROMLONG(CMA_FIRST),
3053 MPFROMSHORT(CRA_CURSORED));
3054 if (!pciS)
3055 Runtime_Error(pszSrcFile, __LINE__, NULL);
3056 else {
3057 // Find matching record
3058 if (cmp->hwndCalling == GetHwndLeft(hwnd)) {
3059 hwndCnrS = GetHwndLeft(hwnd);
3060 hwndCnrD = GetHwndRight(hwnd);
3061 }
3062 else {
3063 hwndCnrS = GetHwndRight(hwnd);
3064 hwndCnrD = GetHwndLeft(hwnd);
3065 }
3066
3067 pciD = FindMatchingItem(pciS, hwndCnrS, hwndCnrD);
3068
3069 if (!pciD)
3070 Runtime_Error(pszSrcFile, __LINE__, NULL);
3071 else if (!pciS->pszFileName)
3072 Runtime_Error(pszSrcFile, __LINE__, NULL);
3073 else {
3074 if (!unlinkf(pciS->pszFileName)) {
3075 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
3076 MPFROM2SHORT(FALSE, CRA_SELECTED));
3077
3078 if (!*pciD->pszFileName) {
3079 // Other side is blank - remove from both sides
3080 RemoveCnrItems(hwndCnrS, pciS, 1, CMA_FREE | CMA_INVALIDATE);
3081 if (pciD->rc.flRecordAttr & CRA_SELECTED)
3082 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
3083 MPFROM2SHORT(FALSE, CRA_SELECTED));
3084 RemoveCnrItems(hwndCnrD, pciD, 1, CMA_FREE | CMA_INVALIDATE);
3085 }
3086 else {
3087 // Other side is not blank - just blank this side
3088 FreeCnrItemData(pciS);
3089 pciS->pszFileName = NullStr;
3090 pciS->pszDisplayName = pciS->pszFileName;
3091 pciS->rc.pszIcon = pciS->pszFileName;
3092 pciS->flags = 0; // Just on one side
3093 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
3094 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
3095 pciD->flags = 0; // Just on one side
3096 if (pciD->pszSubject != NullStr) {
3097 xfree(pciD->pszSubject, pszSrcFile, __LINE__);
3098 pciD->pszSubject = NullStr;
3099 }
3100 }
3101 if (hwndCnrS == GetHwndLeft(hwnd))
3102 cmp->totalleft--;
3103 else
3104 cmp->totalright--;
3105 // Force displayed counts to update
3106 WinPostMsg(hwnd, WM_TIMER, MPFROMLONG(ID_COMP_TIMER), 0);
3107 }
3108 }
3109 }
3110 }
3111 break; // IDM_DELETE
3112
[551]3113 case COMP_FILTER:
3114 case IDM_FILTER:
3115 cmp = INSTDATA(hwnd);
3116 if (cmp) {
3117 BOOL empty = FALSE;
3118 PCNRITEM pci;
3119 CHAR *p;
3120 BOOL temp;
[2]3121
[551]3122 if (!*cmp->dcd.mask.szMask) {
3123 empty = TRUE;
3124 temp = fSelectedAlways;
3125 fSelectedAlways = TRUE;
[748]3126 pci = (PCNRITEM)CurrentRecord(hwnd);
[551]3127 fSelectedAlways = temp;
[748]3128 // 01 Aug 07 SHL
3129 if (pci && ~pci->attrFile & FILE_DIRECTORY) {
[730]3130 p = strrchr(pci->pszFileName, '\\');
[551]3131 if (p) {
3132 p++;
3133 strcpy(cmp->dcd.mask.szMask, p);
3134 }
3135 }
3136 }
3137 cmp->dcd.mask.fNoAttribs = TRUE;
3138 cmp->dcd.mask.attrFile = ALLATTRS;
3139 cmp->dcd.mask.antiattr = 0;
3140 if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
3141 FM3ModHandle, MSK_FRAME, MPFROMP(&cmp->dcd.mask))) {
3142 cmp->dcd.mask.attrFile = ALLATTRS;
3143 cmp->dcd.mask.antiattr = 0;
3144 WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
3145 }
3146 else if (empty) {
3147 *cmp->dcd.mask.szMask = 0;
3148 cmp->dcd.mask.attrFile = ALLATTRS;
3149 cmp->dcd.mask.antiattr = 0;
3150 }
3151 }
3152 break;
[2]3153
[551]3154 case IDM_SHOWSUBJECT:
3155 case IDM_SHOWEAS:
3156 case IDM_SHOWSIZE:
3157 case IDM_SHOWLWDATE:
3158 case IDM_SHOWLWTIME:
3159 case IDM_SHOWLADATE:
3160 case IDM_SHOWLATIME:
3161 case IDM_SHOWCRDATE:
3162 case IDM_SHOWCRTIME:
3163 case IDM_SHOWATTR:
3164 cmp = INSTDATA(hwnd);
3165 if (cmp) {
3166 DIRCNRDATA dcd1;
3167 BOOL tempsubj;
[2]3168
[551]3169 dcd1 = cmp->dcd;
[1469]3170 AdjustDetailsSwitches(GetHwndLeft(hwnd),
[919]3171 (HWND)0, SHORT1FROMMP(mp1),
[1409]3172 cmp->leftdir, PCSZ_DIRCMP, &cmp->dcd.ds, TRUE);
[1065]3173 tempsubj = cmp->dcd.ds.detailssubject;
[551]3174 cmp->dcd = dcd1;
[1065]3175 cmp->dcd.ds.detailssubject = FALSE;
[1469]3176 AdjustDetailsSwitches(GetHwndRight(hwnd),
[551]3177 cmp->dcd.hwndLastMenu, SHORT1FROMMP(mp1),
[1409]3178 cmp->rightdir, PCSZ_DIRCMP, &cmp->dcd.ds, TRUE);
[1469]3179 cmp->dcd.ds.detailssubject = tempsubj;
3180 WriteDetailsSwitches(PCSZ_DIRCMP, &cmp->dcd.ds, TRUE);
[551]3181 }
3182 break;
[2]3183
[551]3184 case IDM_LOADLISTFILE:
3185 cmp = INSTDATA(hwnd);
3186 if (cmp) {
3187 CHAR fullname[CCHMAXPATH];
[2]3188
[1398]3189 strcpy(fullname, PCSZ_STARDOTPMD);
[551]3190 if (insert_filename(HWND_DESKTOP, fullname, TRUE, FALSE) &&
3191 *fullname && !strchr(fullname, '*') && !strchr(fullname, '?')) {
3192 strcpy(cmp->rightlist, fullname);
3193 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
3194 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
3195 }
3196 }
3197 break;
[2]3198
[551]3199 case IDM_SAVELISTFILE:
3200 cmp = INSTDATA(hwnd);
3201 if (cmp) {
3202 SNAPSTUFF *sf;
3203 CHAR fullname[CCHMAXPATH];
[2]3204
[1398]3205 strcpy(fullname, PCSZ_STARDOTPMD);
[551]3206 if (export_filename(HWND_DESKTOP, fullname, 1) && *fullname &&
3207 !strchr(fullname, '*') && !strchr(fullname, '?')) {
3208 sf = xmallocz(sizeof(SNAPSTUFF), pszSrcFile, __LINE__);
3209 if (sf) {
3210 strcpy(sf->filename, fullname);
[1469]3211 if (GetHwndLeft(hwnd) == cmp->hwndCalling)
[551]3212 strcpy(sf->dirname, cmp->leftdir);
3213 else
[1683]3214 strcpy(sf->dirname, cmp->rightdir);
3215 sf->recurse = WinQueryButtonCheckstate(hwnd, COMP_INCLUDESUBDIRS);
[1877]3216
[1469]3217 if (xbeginthread(StartSnapThread,
[1335]3218 65536,
3219 sf,
3220 pszSrcFile,
3221 __LINE__) == -1)
3222 {
[1039]3223 free(sf);
[551]3224 }
3225 }
3226 }
3227 }
3228 break;
[2]3229
[551]3230 case COMP_SETDIRS:
3231 cmp = INSTDATA(hwnd);
3232 if (cmp) {
3233 WALK2 wa;
3234 memset(&wa, 0, sizeof(wa));
3235 wa.size = sizeof(wa);
3236 strcpy(wa.szCurrentPath1, cmp->leftdir);
[1683]3237 strcpy(wa.szCurrentPath2, cmp->rightdir);
3238 wa.includesubdirs = WinQueryButtonCheckstate(hwnd,
3239 COMP_INCLUDESUBDIRS);
[919]3240 if (WinDlgBox(HWND_DESKTOP,
3241 hwnd,
3242 WalkTwoCmpDlgProc,
3243 FM3ModHandle,
3244 WALK2_FRAME,
[551]3245 MPFROMP(&wa)) &&
[769]3246 !IsFile(wa.szCurrentPath1) &&
3247 !IsFile(wa.szCurrentPath2)) {
[551]3248 strcpy(cmp->leftdir, wa.szCurrentPath1);
[1683]3249 strcpy(cmp->rightdir, wa.szCurrentPath2);
3250 cmp->includesubdirs = wa.includesubdirs;
3251 if (!cmp->includesubdirs)
3252 WinCheckButton(hwnd, COMP_INCLUDESUBDIRS, FALSE);
3253 cmp->listfile = wa.listfile;
3254 if (cmp->listfile) {
3255 CHAR fullname[CCHMAXPATH];
3256
3257 strcpy(fullname, PCSZ_STARDOTPMD);
3258 if (insert_filename(HWND_DESKTOP, fullname, TRUE, FALSE) &&
[1684]3259 *fullname && !strchr(fullname, '*') && !strchr(fullname, '?'))
[1683]3260 strcpy(cmp->rightlist, fullname);
3261 }
3262 else
3263 *cmp->rightlist = 0;
[551]3264 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
3265 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
3266 }
3267 }
3268 break;
[2]3269
[551]3270 case COMP_COPYLEFT:
3271 case COMP_MOVELEFT:
3272 case COMP_COPYRIGHT:
3273 case COMP_MOVERIGHT:
3274 case COMP_DELETELEFT:
3275 case COMP_DELETERIGHT:
3276 cmp = INSTDATA(hwnd);
3277 if (cmp) {
3278 COMPARE *forthread;
[2]3279
[551]3280 cmp->filling = TRUE;
3281 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
3282 if (forthread) {
3283 *forthread = *cmp;
3284 forthread->cmp = cmp;
3285 forthread->action = SHORT1FROMMP(mp1);
[1335]3286 if (xbeginthread(ActionCnrThread,
3287 122880,
3288 forthread,
3289 pszSrcFile,
3290 __LINE__) == -1)
3291 {
[1039]3292 free(forthread);
[551]3293 }
3294 else {
[1469]3295 WinEnableWindowUpdate(GetHwndLeft(hwnd), FALSE);
3296 WinEnableWindowUpdate(GetHwndRight(hwnd), FALSE);
[551]3297 switch (SHORT1FROMMP(mp1)) {
3298 case COMP_DELETELEFT:
3299 case COMP_DELETERIGHT:
3300 WinSetDlgItemText(hwnd, COMP_NOTE,
[1498]3301 (CHAR *) GetPString(IDS_COMPHOLDDELETINGTEXT));
[551]3302 break;
3303 case COMP_MOVELEFT:
3304 case COMP_MOVERIGHT:
3305 WinSetDlgItemText(hwnd, COMP_NOTE,
[1498]3306 (CHAR *) GetPString(IDS_COMPHOLDMOVINGTEXT));
[551]3307 break;
3308 case COMP_COPYLEFT:
3309 case COMP_COPYRIGHT:
3310 WinSetDlgItemText(hwnd, COMP_NOTE,
[1498]3311 (CHAR *) GetPString(IDS_COMPHOLDCOPYINGTEXT));
[551]3312 break;
3313 default:
[919]3314 Runtime_Error(pszSrcFile, __LINE__, "mp1 %u unexpected", SHORT1FROMMP(mp1));
[551]3315 }
[1469]3316 SetButtonEnables(cmp, FALSE);
[551]3317 }
3318 }
3319 }
3320 break;
[2]3321
[551]3322 case DID_OK:
[938]3323 {
[1175]3324 SWP swp;
3325 ULONG size = sizeof(SWP);
[1683]3326 USHORT ids[] = {COMP_FRAME, COMP_LEFTDIR, COMP_RIGHTDIR, COMP_COLLECT,
[1684]3327 COMP_VIEW, COMP_NOTE, COMP_TOTALLEFT, COMP_SELLEFT, COMP_TOTALRIGHT,
3328 COMP_SELRIGHT, COMP_CNRMENU, COMP_DIRMENU, COMP_MENU,
3329 COMP_INCLUDESUBDIRS, COMP_SETDIRS, COMP_COPYLEFT, COMP_MOVELEFT,
3330 COMP_DELETELEFT, COMP_COPYRIGHT, COMP_MOVERIGHT, COMP_DELETERIGHT,
3331 COMP_TOTALLEFTHDR, COMP_SELLEFTHDR, COMP_TOTALRIGHTHDR,
3332 COMP_SELRIGHTHDR, COMP_FILTER, COMP_HIDENOTSELECTED, 0};
[1683]3333 UINT x;
3334 CHAR s[24];
[1175]3335 WinQueryWindowPos(hwnd, &swp);
[1505]3336 PrfWriteProfileData(fmprof, FM3Str, "CompDir.Position", (PVOID) &swp,
[1684]3337 size);
[1670]3338 for (x = 0; ids[x]; x++) {
[1683]3339 sprintf(s, "CompDir%i", ids[x]);
3340 SavePresParams(WinWindowFromID(hwnd, ids[x]), s);
3341 }
[938]3342 }
[551]3343 WinDismissDlg(hwnd, 0);
3344 break;
3345 case DID_CANCEL:
[1469]3346 cmp = INSTDATA(hwnd);
3347 if (!cmp)
3348 Runtime_Error(pszSrcFile, __LINE__, NULL);
3349 else {
3350 cmp->stop = TRUE; // In case thread running
3351 if (cmp->filling)
3352 break; // UM_CONTAINER_FILLED will dismiss
3353 }
[938]3354 {
[1175]3355 SWP swp;
3356 ULONG size = sizeof(SWP);
3357 WinQueryWindowPos(hwnd, &swp);
[1505]3358 PrfWriteProfileData(fmprof, FM3Str, "CompDir.Position", (PVOID) &swp,
[1175]3359 size);
[938]3360 }
[551]3361 WinDismissDlg(hwnd, 1);
3362 break;
[2]3363
[551]3364 case IDM_HELP:
3365 if (hwndHelp)
3366 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
3367 MPFROM2SHORT(HELP_COMPARE, 0), MPFROMSHORT(HM_RESOURCEID));
3368 break;
[2]3369
[551]3370 case IDM_DESELECTALL:
3371 case IDM_SELECTNEWER:
3372 case IDM_SELECTOLDER:
3373 case IDM_SELECTBIGGER:
3374 case IDM_SELECTSMALLER:
[1682]3375 case IDM_SELECTEAS:
[551]3376 case IDM_DESELECTNEWER:
3377 case IDM_DESELECTOLDER:
3378 case IDM_DESELECTBIGGER:
3379 case IDM_DESELECTSMALLER:
3380 case IDM_DESELECTONE:
3381 case IDM_DESELECTBOTH:
[1682]3382 case IDM_DESELECTEAS:
[551]3383 case IDM_SELECTBOTH:
3384 case IDM_SELECTONE:
3385 case IDM_SELECTSAMECONTENT:
[748]3386 case IDM_SELECTIDENTICAL: // Name, size and time
3387 case IDM_SELECTSAME: // Name and size
[551]3388 case IDM_INVERT:
[1682]3389
[1683]3390
[551]3391 cmp = INSTDATA(hwnd);
3392 if (!cmp)
[1398]3393 Runtime_Error(pszSrcFile, __LINE__, NULL);
[551]3394 else {
3395 COMPARE *forthread;
3396
3397 cmp->filling = TRUE;
3398 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
3399 if (forthread) {
3400 *forthread = *cmp;
3401 forthread->cmp = cmp;
3402 forthread->action = SHORT1FROMMP(mp1);
[1469]3403 SetShiftState();
3404 forthread->shiftstate = shiftstate; // For and'ed actions
3405
[1335]3406 if (xbeginthread(SelectCnrsThread,
3407 65536,
3408 forthread,
3409 pszSrcFile,
3410 __LINE__) == -1)
3411 {
[1039]3412 free(forthread);
[551]3413 }
[362]3414 else {
[1469]3415 WinEnableWindowUpdate(GetHwndLeft(hwnd), FALSE);
3416 WinEnableWindowUpdate(GetHwndRight(hwnd), FALSE);
[551]3417 switch (SHORT1FROMMP(mp1)) {
3418 case IDM_DESELECTALL:
3419 case IDM_DESELECTNEWER:
3420 case IDM_DESELECTOLDER:
3421 case IDM_DESELECTBIGGER:
3422 case IDM_DESELECTSMALLER:
3423 case IDM_DESELECTONE:
3424 case IDM_DESELECTBOTH:
3425 WinSetDlgItemText(hwnd, COMP_NOTE,
[1498]3426 (CHAR *) GetPString(IDS_COMPHOLDDESELTEXT));
[551]3427 break;
3428 case IDM_INVERT:
3429 WinSetDlgItemText(hwnd, COMP_NOTE,
[1498]3430 (CHAR *) GetPString(IDS_COMPHOLDINVERTTEXT));
[551]3431 break;
3432 default:
3433 WinSetDlgItemText(hwnd, COMP_NOTE,
[1498]3434 (CHAR *) GetPString(IDS_COMPHOLDSELTEXT));
[551]3435 break;
3436 }
[1469]3437 SetButtonEnables(cmp, FALSE);
[551]3438 }
3439 }
3440 }
3441 break;
[2]3442
[551]3443 case COMP_COLLECT:
3444 cmp = INSTDATA(hwnd);
[773]3445 if (!cmp)
[1398]3446 Runtime_Error(pszSrcFile, __LINE__, NULL);
[773]3447 else {
3448 CHAR **listl;
3449 CHAR **listr = NULL;
[551]3450 if (!Collector) {
3451 SWP swp;
3452 HWND hwndC;
[773]3453 if (!fAutoTile &&
3454 !ParentIsDesktop(hwnd, cmp->hwndParent) &&
3455 !fExternalCollector &&
3456 !strcmp(realappname, FM3Str)) {
[551]3457 GetNextWindowPos(cmp->hwndParent, &swp, NULL, NULL);
[773]3458 }
3459 hwndC = StartCollector(fExternalCollector ||
3460 strcmp(realappname, FM3Str) ?
3461 HWND_DESKTOP :
3462 cmp->hwndParent,
3463 4);
[551]3464 if (hwndC) {
[773]3465 if (!fAutoTile &&
3466 !ParentIsDesktop(hwnd, cmp->hwndParent) &&
3467 !fExternalCollector &&
3468 !strcmp(realappname, FM3Str)) {
3469 WinSetWindowPos(hwndC, HWND_TOP,
3470 swp.x, swp.y, swp.cx, swp.cy,
3471 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
3472 }
3473 else if (!ParentIsDesktop(hwnd, cmp->hwndParent) &&
3474 fAutoTile &&
3475 !strcmp(realappname, FM3Str)) {
[551]3476 TileChildren(cmp->hwndParent, TRUE);
[773]3477 }
[924]3478 DosSleep(1); // 12 Jan 08 SHL Let screen update
[551]3479 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(COMP_COLLECT, 0), MPVOID);
3480 break;
3481 }
3482 }
3483 else
3484 StartCollector(cmp->hwndParent, 4);
[2]3485
[773]3486 temp = fSelectedAlways;
3487 fSelectedAlways = TRUE;
[1469]3488 listl = BuildList(GetHwndLeft(hwnd));
[773]3489 if (!*cmp->rightlist)
[1469]3490 listr = BuildList(GetHwndRight(hwnd));
[773]3491 fSelectedAlways = temp;
3492
[551]3493 if (listl || listr) {
3494 if (Collector) {
[773]3495 // 07 Aug 07 SHL Avoid collected from empty list
3496 if (listl && listl[0] && *listl[0]) {
3497 if (PostMsg(Collector, WM_COMMAND,
3498 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listl)))
3499 listl = NULL; // Collector will free
[551]3500 }
[773]3501 if (listr && listr[0] && *listr[0]) {
3502 if (PostMsg(Collector, WM_COMMAND,
3503 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listr)))
3504 listr = NULL; // Collector will free
[551]3505 }
3506 WinSetWindowPos(WinQueryWindow(WinQueryWindow(Collector,
3507 QW_PARENT),
[773]3508 QW_PARENT),
3509 HWND_TOP, 0, 0, 0, 0,
[551]3510 SWP_ACTIVATE);
3511 }
[773]3512 FreeList(listl);
3513 FreeList(listr);
[551]3514 }
[2]3515 }
[551]3516 break;
[1469]3517 } // switch mp1
[551]3518 return 0;
[2]3519
[551]3520 case WM_CLOSE:
[1469]3521 cmp = INSTDATA(hwnd);
3522 if (!cmp)
3523 Runtime_Error(pszSrcFile, __LINE__, NULL);
3524 else {
3525 cmp->stop = TRUE; // In case thread running
3526 if (cmp->filling)
3527 break; // UM_CONTAINER_FILLED will dismiss
3528 }
[551]3529 WinDismissDlg(hwnd, 0);
3530 return 0;
[2]3531
[551]3532 case WM_DESTROY:
3533 cmp = INSTDATA(hwnd);
3534 if (cmp) {
[929]3535 // 17 Jan 08 SHL fixme to know if stop really needed?
[1444]3536 WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_COMP_TIMER);
[551]3537 if (cmp->dcd.hwndLastMenu)
3538 WinDestroyWindow(cmp->dcd.hwndLastMenu);
3539 if (cmp->dcd.hwndObject) {
[919]3540 WinSetWindowPtr(cmp->dcd.hwndObject, QWL_USER, (PVOID)NULL);
[551]3541 if (!PostMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID))
3542 WinSendMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID);
[2]3543 }
[1836]3544 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
[1039]3545 free(cmp);
[1836]3546 cmp = NULL;
3547 DosReleaseMutexSem(hmtxFiltering);
[551]3548 }
[1469]3549 EmptyCnr(GetHwndLeft(hwnd));
3550 EmptyCnr(GetHwndRight(hwnd));
[551]3551 DosPostEventSem(CompactSem);
3552 break;
[2]3553 }
[551]3554 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]3555}
[783]3556
[1469]3557#undef GetHwndLeft
3558#undef GetHwndRight
3559
[783]3560#pragma alloc_text(COMPAREDIR,FillCnrsThread,FillDirList,CompNames,BldFullPathName)
3561#pragma alloc_text(COMPAREDIR1,CompareDlgProc)
3562#pragma alloc_text(COMPAREDIR2,SelectCnrsThread,ActionCnrThread)
3563#pragma alloc_text(COMPAREFILE,CFileDlgProc,CompareFilesThread)
[1469]3564#pragma alloc_text(SNAPSHOT,SnapShot,StartSnapThread)
3565#pragma alloc_text(COMPSELECT,CompSelect,CompSelectSetSelects,CompSelectClearSelects)
[783]3566
Note: See TracBrowser for help on using the repository browser.