Changeset 1563


Ignore:
Timestamp:
May 30, 2011, 9:21:53 PM (14 years ago)
Author:
Steven Levine
Message:

Rework collector and compare directories to correctly support more than 65K records.
Collector was trapping.
Compare directories was fixed to avoid the traps, but the implementation was not correctly handling all records.

Location:
trunk/dll
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/dll/collect.c

    r1562 r1563  
    77
    88  Copyright (c) 1993-98 M. Kimes
    9   Copyright (c) 2003, 2010 Steven H. Levine
     9  Copyright (c) 2003, 2011 Steven H. Levine
    1010
    1111  15 Oct 02 MK Baseline
     
    7272  17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
    7373  23 Oct 10 GKY Add menu items for opening directory cnrs based on path of selected item
    74                 including the option to use walk directories to select path
     74                including the option to use walk directories to select path
    7575  28 May 11 GKY Fixed trap caused by passing a nonexistant pci to FillInRecordFromFFB in
    7676                UM_COLLECT because pci is limited to 65535 files. (nRecord is a USHORT)
     77  29 May 11 SHL Rework UM_COLLECT >65K records logic to not require double loop
     78  29 May 11 SHL Tweak UM_COLLECT to bypass FindCnrRecord when container initially empty
    7779
    7880***********************************************************************/
     
    8284#include <ctype.h>
    8385#include <share.h>
    84 #include <limits.h>
     86#include <limits.h>                     // USHRT_MAX
    8587// #include <process.h>                 // _beginthread
    8688
     
    107109#include "notebook.h"                   // CfgDlgProc
    108110#include "command.h"                    // RunCommand
    109 #include "worker.h"             // Action, MassAction
    110 #include "notify.h"             // AddNote
     111#include "worker.h"                     // Action, MassAction
     112#include "notify.h"                     // AddNote
    111113#include "misc.h"               // AdjustCnrColsForPref, AdjustDetailsSwitches, CnrDirectEdit,
    112114                                        // LoadDetailsSwitches, OpenEdit, QuickPopup, SayFilter
     
    117119#include "collect.h"
    118120#include "common.h"                     // CommonCnrProc, CommonCreateTextChildren, CommonFrameWndProc
    119                                 // CommonTextPaint
     121                                        // CommonTextPaint
    120122#include "select.h"                     // DeselectAll, HideAll, RemoveAll, SelectAll, SelectList
    121123#include "dirsize.h"                    // DirSizeProc
     
    149151#include "fortify.h"
    150152#include "excputil.h"                   // xbeginthread
    151 #include "walkem.h"                     // WalkAllDlgProc
     153#include "walkem.h"                     // WalkAllDlgProc
    152154
    153155// Data definitions
     
    647649    if (dcd) {
    648650      LISTINFO *li = (LISTINFO *) mp1;
    649       INT x, y = 0;
     651      INT x;
    650652      FILEFINDBUF4L fb4;
    651653      HDIR hdir;
    652       ULONG nm;
    653       PCNRITEM pci, pciFirst, pciT, pciP = NULL;
    654       RECORDINSERT ri;
    655654      ULONG ulMaxFiles;
    656       ULONGLONG ullTotalBytes, ullInitialTotalBytes;
    657655      CHAR fullname[CCHMAXPATH];
    658       INT makeShort = 0;
    659656
    660657      if (!hwndStatus) {
     
    666663          WinSetWindowText(hwndStatus, (CHAR *) GetPString(IDS_COLLECTINGTEXT));
    667664      }
    668       ullInitialTotalBytes = dcd->ullTotalBytes;
    669       while (li->list[y]) {
    670         for (ulMaxFiles = 0; li->list[ulMaxFiles + y] && ulMaxFiles < USHRT_MAX; ulMaxFiles++) ;        // Count
    671 
    672         if (ulMaxFiles) {
    673          
    674           pci = WinSendMsg(dcd->hwndCnr, CM_ALLOCRECORD,
    675                            MPFROMLONG(EXTRA_RECORD_BYTES),
    676                            MPFROMLONG(ulMaxFiles));
    677           if (!pci) {
    678             Runtime_Error(pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
    679             break;
    680           }
    681           else {
    682             ITIMER_DESC itdSleep = { 0 };               // 06 Feb 08 SHL
    683             InitITimer(&itdSleep, 500);         // Sleep every 500 mSec
    684             pciFirst = pci;
    685             // 04 Jan 08 SHL fixme like comp.c if CM_ALLOCRECORD returns unexpected record count
    686             for (x = y ; li->list[x]; x++) {
    687               nm = 1;
    688               hdir = HDIR_CREATE;
    689               DosError(FERR_DISABLEHARDERR);
    690               if (ullInitialTotalBytes && !makeShort &&
    691                   FindCnrRecord(dcd->hwndCnr, li->list[x], NULL, FALSE, FALSE, TRUE)) {
    692                 pci = UpdateCnrRecord(dcd->hwndCnr, li->list[x], FALSE, dcd);
    693                 if (Filter((PMINIRECORDCORE) pci, (PVOID) & dcd->mask)) {
    694                   pci->rc.flRecordAttr &= ~CRA_FILTERED;
    695                   WinSendMsg(dcd->hwndCnr, CM_INVALIDATERECORD, MPVOID,
    696                              MPFROM2SHORT(0, CMA_REPOSITION | CMA_ERASE));
    697                 }
    698                 pci = (PCNRITEM) pci->rc.preccNextRecord;
    699                 if (pciP)
    700                   pciP->rc.preccNextRecord = (PMINIRECORDCORE) pci;
    701                 else
    702                   pciFirst = pci;
    703               }
    704               else if (*li->list[x] &&
    705                   !DosQueryPathInfo(li->list[x], FIL_QUERYFULLNAME,
    706                                     fullname, sizeof(fullname)) &&
    707                   !IsRoot(fullname) &&
    708                   !xDosFindFirst(fullname,
    709                                  &hdir,
    710                                  FILE_NORMAL | FILE_DIRECTORY |
    711                                  FILE_ARCHIVED | FILE_SYSTEM |
    712                                  FILE_HIDDEN | FILE_READONLY,
    713                                  &fb4, sizeof(fb4), &nm, FIL_QUERYEASIZEL)) {
    714                 DosFindClose(hdir);
    715                 priority_normal();
    716                 *fb4.achName = 0;
    717                 //DbgMsg(pszSrcFile, __LINE__, "hwndCnr %x pci %x fullname %s pci->rc.preccNextRecord %x x %x Max %x",
    718                 //       dcd->hwndCnr, pci, fullname, pci->rc.preccNextRecord, x, ulMaxFiles);
    719                 ullTotalBytes = FillInRecordFromFFB(dcd->hwndCnr,
    720                                                     pci,
    721                                                     fullname, &fb4, FALSE, dcd);
    722                 dcd->ullTotalBytes += ullTotalBytes;
    723                 pciP = pci;
    724                 pci = (PCNRITEM) pci->rc.preccNextRecord;
    725               }
    726               else {
    727                 // Oops - fixme to complain?
    728                 pciT = pci;
    729                 pci = (PCNRITEM) pci->rc.preccNextRecord;
    730                 if (pciP)
    731                   pciP->rc.preccNextRecord = (PMINIRECORDCORE) pci;
    732                 else
    733                   pciFirst = pci;
    734                 if (pciT)
    735                   FreeCnrItemData(pciT); // FreeCnrItem(hwnd, pciT);
    736                 ulMaxFiles--;           // Remember gone
    737               }
    738               SleepIfNeeded(&itdSleep, 1);      // 09 Feb 08 SHL
    739               // DosSleep(0); //26 Aug 07 GKY 1 // 09 Feb 08 SHL
    740               if (pciP->rc.preccNextRecord == 0) {
    741                 y = x + 1;
    742                 break;
    743               }
    744               y = x + 1;
    745             } // for
    746             if (ulMaxFiles) {
    747               //DbgMsg(pszSrcFile, __LINE__, "ri %x pciFirst %x x %x Max %x",
    748               //         ri, pciFirst, x, ulMaxFiles);
    749               // Some files OK
    750               memset(&ri, 0, sizeof(RECORDINSERT));
    751               ri.cb = sizeof(RECORDINSERT);
    752               ri.pRecordOrder = (PRECORDCORE) CMA_END;
    753               ri.pRecordParent = (PRECORDCORE) 0;
    754               ri.zOrder = (ULONG) CMA_TOP;
    755               ri.cRecordsInsert = ulMaxFiles;
    756               ri.fInvalidateRecord = TRUE;
    757               WinSendMsg(dcd->hwndCnr,
    758                          CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri));
    759               PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
    760               makeShort++;
    761               ulMaxFiles = 0;
    762             }
    763           }
    764         }
    765         if (makeShort > 1000) {
    766           Runtime_Error(pszSrcFile, __LINE__,
    767                         "You have exceeded 650,000,000 files which probably means either a momory alocation or a list creation failure. Either way contact us.");
    768           break;
    769         }
    770       } //While
    771     }
    772     if (dcd->flWindowAttr & CV_DETAIL)
    773       WinSendDlgItemMsg(hwnd,
    774                         COLLECTOR_CNR,
    775                         CM_INVALIDATERECORD,
    776                         MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
     665
     666      for (ulMaxFiles = 0; li->list[ulMaxFiles]; ulMaxFiles++) ;        // Count
     667
     668      if (ulMaxFiles) {
     669        PCNRITEM pci = NULL;
     670        PCNRITEM pciFirst = NULL;
     671        PCNRITEM pciNext;
     672        PCNRITEM pciPrev = NULL;
     673        ULONG nm;
     674        ULONG ulRecsAtStart;
     675        ULONG ulRecsToInsert;
     676        ULONG ulRecsAllocated = 0;
     677        ULONGLONG ullTotalBytes;
     678        CNRINFO cnri;
     679        RECORDINSERT ri;
     680        ITIMER_DESC itdSleep = { 0 };   // 06 Feb 08 SHL
     681
     682        InitITimer(&itdSleep, 500);     // Sleep every 500 mSec
     683
     684        // Query initial count
     685        // 2011-05-29 SHL fixme to be utility
     686        memset(&cnri, 0, sizeof(CNRINFO));
     687        cnri.cb = sizeof(CNRINFO);
     688        if (WinSendMsg(dcd->hwndCnr, CM_QUERYCNRINFO, MPFROMP(&cnri),
     689                       MPFROMLONG(sizeof(CNRINFO)))) {
     690          ulRecsAtStart = cnri.cRecords;
     691        }
     692        else {
     693          Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
     694                    "CM_QUERYCNRINFO" /* PCSZ_QUERYCNRINFO fixme */);
     695          ulRecsAtStart = 0;
     696        }
     697
     698        for (x = 0; li->list[x]; x++) {
     699          // Allocate container items if needed
     700          if (!pci) {
     701            ulRecsToInsert = ulMaxFiles - ulRecsAllocated;
     702            if (ulRecsToInsert > USHRT_MAX)
     703              ulRecsToInsert = USHRT_MAX;
     704            pciPrev = NULL;
     705            pci = WinSendMsg(dcd->hwndCnr, CM_ALLOCRECORD,
     706                             MPFROMLONG(EXTRA_RECORD_BYTES),
     707                             MPFROMLONG(ulRecsToInsert));
     708            if (!pci) {
     709              Runtime_Error(pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
     710              break;
     711            }
     712            pciFirst = pci;
     713          } // if need allocate
     714          nm = 1;
     715          hdir = HDIR_CREATE;
     716          DosError(FERR_DISABLEHARDERR);
     717          // If started with records in container, check if updating existing record
     718          if (ulRecsAtStart &&
     719              FindCnrRecord(dcd->hwndCnr,
     720                            li->list[x],
     721                            NULL,
     722                            FALSE,
     723                            FALSE,
     724                            TRUE)) {
     725            pciNext = (PCNRITEM)pci->rc.preccNextRecord;
     726            pci = UpdateCnrRecord(dcd->hwndCnr, li->list[x], FALSE, dcd);
     727            if (!pci) {
     728              Runtime_Error(pszSrcFile, __LINE__, "pci NULL for list[%u]", x);
     729              pci = pciNext;            // Try to recover
     730            }
     731            else {
     732              if (Filter((PMINIRECORDCORE) pci, (PVOID) & dcd->mask)) {
     733                pci->rc.flRecordAttr &= ~CRA_FILTERED;  // Ensure visible
     734                // 2011-05-29 SHL fixme to check fail
     735                WinSendMsg(dcd->hwndCnr, CM_INVALIDATERECORD, MPVOID,
     736                           MPFROM2SHORT(0, CMA_REPOSITION | CMA_ERASE));
     737              }
     738              // Remove extra record from chain and free
     739              if (pciPrev)
     740                pciPrev->rc.preccNextRecord = (PMINIRECORDCORE)pciNext;
     741              else
     742                pciFirst = pciNext;
     743              if (pci)
     744                FreeCnrItem(dcd->hwndCnr, pci);
     745              pci = pciNext;
     746              ulRecsToInsert--;         // Remember gone
     747              ulMaxFiles--;             // Remember gone
     748            }
     749          }
     750          // Add new entry
     751          else if (*li->list[x] &&
     752              !DosQueryPathInfo(li->list[x], FIL_QUERYFULLNAME,
     753                                fullname, sizeof(fullname)) &&
     754              !IsRoot(fullname) &&
     755              !xDosFindFirst(fullname,
     756                             &hdir,
     757                             FILE_NORMAL | FILE_DIRECTORY |
     758                             FILE_ARCHIVED | FILE_SYSTEM |
     759                             FILE_HIDDEN | FILE_READONLY,
     760                             &fb4, sizeof(fb4), &nm, FIL_QUERYEASIZEL)) {
     761            DosFindClose(hdir);
     762            priority_normal();
     763            *fb4.achName = 0;
     764            ullTotalBytes = FillInRecordFromFFB(dcd->hwndCnr,
     765                                                pci,
     766                                                fullname, &fb4, FALSE, dcd);
     767            dcd->ullTotalBytes += ullTotalBytes;
     768            pciPrev = pci;
     769            pci = (PCNRITEM) pci->rc.preccNextRecord;
     770          }
     771          else {
     772            // DosQueryPathInfo etc. failed - try to recover
     773            Runtime_Error(pszSrcFile, __LINE__, "DosQueryPathInfo failed for %s", fullname);
     774            // Remove extra CNRITEM from chain
     775            pciNext = (PCNRITEM)pci->rc.preccNextRecord;
     776            if (pciPrev)
     777              pciPrev->rc.preccNextRecord = (PMINIRECORDCORE)pciNext;
     778            else
     779              pciFirst = pciNext;
     780            if (pci)
     781              FreeCnrItem(dcd->hwndCnr, pci);
     782            pci = pciNext;
     783            ulRecsToInsert--;           // Remember gone
     784            ulMaxFiles--;               // Remember gone
     785          }
     786          // Check if time to insert
     787          if (!pci) {
     788            if (ulRecsToInsert) {
     789              memset(&ri, 0, sizeof(RECORDINSERT));
     790              ri.cb = sizeof(RECORDINSERT);
     791              ri.pRecordOrder = (PRECORDCORE) CMA_END;
     792              ri.pRecordParent = (PRECORDCORE) 0;
     793              ri.zOrder = (ULONG) CMA_TOP;
     794              ri.cRecordsInsert = ulRecsToInsert;
     795              ri.fInvalidateRecord = TRUE;
     796              WinSendMsg(dcd->hwndCnr,
     797                         CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri));
     798              // 2011-05-29 SHL fixme to complain on failure
     799              PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
     800              ulRecsAllocated += ulRecsToInsert;
     801              pciFirst = NULL;
     802              ulRecsToInsert = 0;
     803            }
     804          } // if need CM_INSERTRECORD
     805          SleepIfNeeded(&itdSleep, 1);  // 09 Feb 08 SHL
     806        } // for
     807
     808        // Clean up in case stopped early by error
     809        if (pci) {
     810          Runtime_Error(pszSrcFile, __LINE__, "pci not NULL");
     811        }
     812        if (pciFirst) {
     813          Runtime_Error(pszSrcFile, __LINE__, "pciFirst not NULL");
     814          FreeCnrItemList(dcd->hwndCnr, pciFirst);
     815        }
     816
     817      } // if have files
     818
     819      if (dcd->flWindowAttr & CV_DETAIL)
     820        WinSendDlgItemMsg(hwnd,
     821                          COLLECTOR_CNR,
     822                          CM_INVALIDATERECORD,
     823                          MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
     824    } // if dcd
    777825    return 0;
    778826
     
    844892              }
    845893              /*pci = (PCNRITEM) pci->rc.preccNextRecord;
    846               if (pciP)
    847                 pciP->rc.preccNextRecord = (PMINIRECORDCORE) pci;
     894              if (pciPrev)
     895                pciPrev->rc.preccNextRecord = (PMINIRECORDCORE) pci;
    848896              else
    849897                pciFirst = pci;*/
     
    14131461  case UM_CONTAINER_FILLED:
    14141462    if (!fAlertBeepOff)
    1415       DosBeep(1000, 50);                        // Wake up user?
     1463      DosBeep(1000, 50);                // Wake up user?
    14161464    WinSendMsg(hwnd,
    14171465               CM_INVALIDATERECORD,
     
    15111559        }
    15121560        else
    1513           DosSleep(32);         // Let object window get started
     1561          DosSleep(32);                 // Let object window get started
    15141562      }
    15151563      SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
     
    16061654#     endif
    16071655      if (!dcd) {
    1608         Runtime_Error(pszSrcFile, __LINE__, NULL);
    1609         free(mp1);
     1656        Runtime_Error(pszSrcFile, __LINE__, NULL);
     1657        free(mp1);
    16101658      }
    16111659      else {
    16121660        if (!PostMsg(dcd->hwndObject, UM_COLLECTFROMFILE, mp1, mp2)) {
    1613           Runtime_Error(pszSrcFile, __LINE__, PCSZ_POSTMSG);
    1614           free(mp1);
     1661          Runtime_Error(pszSrcFile, __LINE__, PCSZ_POSTMSG);
     1662          free(mp1);
    16151663        }
    16161664      }
     
    17701818      case IDM_RESELECT:
    17711819        SelectList(hwnd, FALSE, FALSE, FALSE, NULL, NULL, dcd->lastselection);
    1772         break;
     1820        break;
    17731821
    17741822      case IDM_WALKDIR:
     
    17871835          }
    17881836          else
    1789             strcpy(newpath, pFM2SaveDirectory);
    1790           if (*newpath) {
    1791             switch (SHORT1FROMMP(mp1)) {
    1792             case IDM_WALKDIR:
    1793               WinDlgBox(HWND_DESKTOP, dcd->hwndParent, WalkAllDlgProc,
    1794                         FM3ModHandle, WALK_FRAME, MPFROMP(newpath));
    1795               break;
    1796             case IDM_OPENDIRWINDOW:
    1797               WinSendMsg(hwnd, UM_OPENWINDOWFORME, MPFROMP(newpath), MPVOID);
    1798               break;
    1799             case IDM_OPENDIRICON:
    1800               OpenObject(newpath, PCSZ_ICON, hwnd);
    1801               break;
    1802             case IDM_OPENDIRDETAILS:
    1803               OpenObject(newpath, Details, hwnd);
    1804               break;
    1805             case IDM_OPENDIRTREE:
    1806               OpenObject(newpath, PCSZ_TREE, hwnd);
    1807               break;
    1808             default:
    1809               break;
    1810             }
    1811           }
     1837            strcpy(newpath, pFM2SaveDirectory);
     1838          if (*newpath) {
     1839            switch (SHORT1FROMMP(mp1)) {
     1840            case IDM_WALKDIR:
     1841              WinDlgBox(HWND_DESKTOP, dcd->hwndParent, WalkAllDlgProc,
     1842                        FM3ModHandle, WALK_FRAME, MPFROMP(newpath));
     1843              break;
     1844            case IDM_OPENDIRWINDOW:
     1845              WinSendMsg(hwnd, UM_OPENWINDOWFORME, MPFROMP(newpath), MPVOID);
     1846              break;
     1847            case IDM_OPENDIRICON:
     1848              OpenObject(newpath, PCSZ_ICON, hwnd);
     1849              break;
     1850            case IDM_OPENDIRDETAILS:
     1851              OpenObject(newpath, Details, hwnd);
     1852              break;
     1853            case IDM_OPENDIRTREE:
     1854              OpenObject(newpath, PCSZ_TREE, hwnd);
     1855              break;
     1856            default:
     1857              break;
     1858            }
     1859          }
    18121860        }
    18131861        break;
     
    19201968          }
    19211969#         ifdef FORTIFY
    1922           DosSleep(1);          // Let receiver take ownership
     1970          DosSleep(1);                  // Let receiver take ownership
    19231971          Fortify_LeaveScope();
    19241972#         endif
     
    23572405          INT x;
    23582406
    2359           x = SHORT1FROMMP(mp1);// - IDM_COMMANDSTART;
     2407          x = SHORT1FROMMP(mp1);        // - IDM_COMMANDSTART;
    23602408          if (x >= 0) {
    23612409            //x++;
     
    24902538      case CN_DRAGOVER:
    24912539        if (mp2) {
    2492           PDRAGITEM pDItem;     /* Pointer to DRAGITEM */
    2493           PDRAGINFO pDInfo;     /* Pointer to DRAGINFO */
     2540          PDRAGITEM pDItem;             /* Pointer to DRAGITEM */
     2541          PDRAGINFO pDInfo;             /* Pointer to DRAGINFO */
    24942542          PCNRITEM pci;
    24952543          USHORT uso;
     
    31573205    }
    31583206#   ifdef FORTIFY
    3159     DosSleep(1);                // Let receiver take ownership
     3207    DosSleep(1);                        // Let receiver take ownership
    31603208    Fortify_LeaveScope();
    31613209#   endif
  • trunk/dll/comp.c

    r1545 r1563  
    7575  17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
    7676  23 Oct 10 GKY Add ForwardslashToBackslash function to streamline code
     77  29 May 11 SHL Rework >65K records logic - prior fix was not quite right
    7778
    7879***********************************************************************/
     
    8384#include <io.h>
    8485#include <ctype.h>
     86#include <limits.h>                     // USHRT_MAX
    8587
    8688#define INCL_DOS
     
    10671069          CHAR buf1[1024];
    10681070          CHAR buf2[1024];
    1069           HAB hab = WinQueryAnchorBlock(hwndCnrS);
    1070           CHAR *moderb = "rb";
     1071          HAB hab = WinQueryAnchorBlock(hwndCnrS);
     1072          CHAR *moderb = "rb";
    10711073
    10721074          if (!*pciS->pszFileName ||
     
    15031505      UINT numallocl = 0;
    15041506      UINT numallocr = 0;
    1505       INT ret = 0;
    15061507      UINT lenl;                        // Directory prefix length
    15071508      UINT lenr;
    1508       UINT recsNeeded;
    1509       UINT recsGotten;
    1510       PCNRITEM pcilFirst;
    1511       PCNRITEM pcirFirst;
    1512       PCNRITEM pcilLast;
    1513       PCNRITEM pcirLast;
    1514       PCNRITEM pcil;
    1515       PCNRITEM pcir;
    1516       RECORDINSERT ri;
     1509      ULONG ulRecsNeeded;
    15171510      CHAR *pch;
    15181511      HWND hwndLeft;
     
    15611554        FILE *fp;
    15621555        FILEFINDBUF4L fb4;
    1563         CHAR str[CCHMAXPATH * 2], *p;
    1564         CHAR *moder = "r";
     1556        CHAR str[CCHMAXPATH * 2], *p;
     1557        CHAR *moder = "r";
    15651558
    15661559        memset(&fb4, 0, sizeof(fb4));
     
    16971690      // We now have two lists of files, both sorted.
    16981691      // Count total number of container entries required on each side
    1699       l = r = 0;
    1700       recsNeeded = 0;
     1692      l = 0;
     1693      r = 0;
     1694      ulRecsNeeded = 0;
    17011695      while ((filesl && filesl[l]) || (filesr && filesr[r])) {
    17021696
     
    17181712          r++;                          // On right side
    17191713
    1720         recsNeeded++;                   // Keep count of how many entries req'd
    1721 
    1722       } // while
    1723 
    1724       if (cmp->stop) {
    1725         recsNeeded = 0;
    1726       }
    1727 
    1728       // Now insert records into the containers
    1729 
    1730       if (recsNeeded) {
     1714        ulRecsNeeded++;                 // Count how many entries req'd
     1715
     1716      } // while counting
     1717
     1718      if (cmp->stop)
     1719        ulRecsNeeded = 0;
     1720
     1721      // Insert records into the containers
     1722
     1723      if (ulRecsNeeded) {
     1724
     1725        PCNRITEM pcilFirst;
     1726        PCNRITEM pcirFirst;
     1727        PCNRITEM pcil = NULL;
     1728        PCNRITEM pcir = NULL;
     1729        INT ret;
     1730        ULONG ulRecsAllocated = 0;
     1731        ULONG insertedl;
     1732        ULONG insertedr;
     1733
     1734        l = 0;
     1735        r = 0;
    17311736
    17321737        // Use send to get message on screen quickly
    17331738        WinSendMsg(cmp->hwnd, UM_CONTAINERHWND, MPVOID, MPVOID);
    17341739
    1735         pcilFirst = WinSendMsg(hwndLeft,
    1736                                CM_ALLOCRECORD,
    1737                                MPFROMLONG(EXTRA_RECORD_BYTES),
    1738                                MPFROMLONG(recsNeeded));
    1739         if (!pcilFirst) {
    1740           Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
    1741           recsNeeded = 0;
    1742         }
    1743       }
    1744 
    1745       if (recsNeeded) {
    1746         pcirFirst = WinSendMsg(hwndRight, CM_ALLOCRECORD,
    1747                                MPFROMLONG(EXTRA_RECORD_BYTES),
    1748                                MPFROMLONG(recsNeeded));
    1749         if (!pcirFirst) {
    1750           Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
    1751           recsNeeded = 0;
    1752           FreeCnrItemList(hwndLeft, pcilFirst);
    1753         }
    1754       }
    1755 
    1756       if (recsNeeded) {
    1757 
    1758         l = 0;
    1759         r = 0;
    1760         pcil = pcilFirst;
    1761         pcir = pcirFirst;
    1762         pcilLast = NULL;
    1763         pcirLast = NULL;
    1764 
    1765         recsGotten = 0;
    17661740        cmp->cmp->totalleft = 0;
    17671741        cmp->cmp->totalright = 0;
     
    17691743        while ((filesl && filesl[l]) || (filesr && filesr[r])) {
    17701744
     1745          ULONG ulRecsToInsert; // limited to USHRT_MAX
     1746
    17711747          if (cmp->stop)
    17721748            break;
    17731749
    1774           if (!pcil) {
    1775             Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_INSUFFICIENTMEMORY),
    1776                           recsNeeded, recsGotten);
    1777             break;
    1778           }
    1779 
    1780           if (!pcir) {
    1781             Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_INSUFFICIENTMEMORY),
    1782                           recsNeeded, recsGotten);
    1783             break;
    1784           }
    1785           recsGotten++;
     1750          // Check alloc needed
     1751          if (!pcil || !pcir) {
     1752            if (pcil != pcir) {
     1753              // 2011-05-29 SHL fixme to GetPString
     1754              Runtime_Error(pszSrcFile, __LINE__, "pcil and pcir out of sync");
     1755              cmp->stop = TRUE;
     1756              break;
     1757            }
     1758            ulRecsToInsert = ulRecsNeeded - ulRecsAllocated;
     1759            if (ulRecsToInsert > USHRT_MAX)
     1760              ulRecsToInsert = USHRT_MAX;
     1761
     1762            pcilFirst = WinSendMsg(hwndLeft,
     1763                                   CM_ALLOCRECORD,
     1764                                   MPFROMLONG(EXTRA_RECORD_BYTES),
     1765                                   MPFROMLONG(ulRecsToInsert));
     1766            if (!pcilFirst) {
     1767              Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
     1768              cmp->stop = TRUE;
     1769              break;
     1770            }
     1771            pcirFirst = WinSendMsg(hwndRight, CM_ALLOCRECORD,
     1772                                   MPFROMLONG(EXTRA_RECORD_BYTES),
     1773                                   MPFROMLONG(ulRecsToInsert));
     1774            if (!pcirFirst) {
     1775              Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
     1776              FreeCnrItemList(hwndLeft, pcilFirst);
     1777              pcilFirst = NULL;
     1778              cmp->stop = TRUE;
     1779              break;
     1780            }
     1781            pcil = pcilFirst;
     1782            pcir = pcirFirst;
     1783            insertedl = 0;
     1784            insertedr = 0;
     1785            ulRecsAllocated += ulRecsToInsert;
     1786          } // if need alloc
     1787
    17861788          pcir->hwndCnr = hwndRight;
    17871789          pcir->rc.hptrIcon = (HPOINTER)0;
     
    18011803            // File appears on left side
    18021804            cmp->cmp->totalleft++;
     1805            insertedl++;
    18031806            BldFullPathName(szBuf, cmp->leftdir, filesl[l]->fname);
    18041807            pcil->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
     
    18401843            // File appears on right side
    18411844            cmp->cmp->totalright++;
     1845            insertedr++;
    18421846            BldFullPathName(szBuf, cmp->rightdir, filesr[r]->fname);
    18431847            pcir->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);   // 31 Jul 07 SHL
     
    19271931          } // if on both sides
    19281932
    1929           if (x <= 0) {
     1933          if (x <= 0)
    19301934            free(filesl[l++]);          // Done with item on left
    1931           }
    1932           if (x >= 0) {
     1935
     1936          if (x >= 0)
    19331937            free(filesr[r++]);          // Done with item on right
    1934           }
     1938
    19351939          // Ensure empty buffers point somewhere
    19361940          if (!pcil->pszFileName) {
     
    19621966          SleepIfNeeded(&itdSleep, 0);
    19631967
    1964           pcilLast = pcil;
    1965           pcirLast = pcir;
    19661968          pcil = (PCNRITEM)pcil->rc.preccNextRecord;
    19671969          pcir = (PCNRITEM)pcir->rc.preccNextRecord;
    19681970
     1971          if (pcil == NULL || pcir == NULL) {
     1972            RECORDINSERT ri;
     1973            if (pcil != pcir) {
     1974              Runtime_Error(pszSrcFile, __LINE__, "pcil and pcir out of sync");
     1975              cmp->stop = TRUE;
     1976              break;
     1977            }
     1978            // Say inserting
     1979            WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID);
     1980
     1981            // Insert left side
     1982            memset(&ri, 0, sizeof(RECORDINSERT));
     1983            ri.cb = sizeof(RECORDINSERT);
     1984            ri.pRecordOrder = (PRECORDCORE)CMA_END;
     1985            ri.pRecordParent = (PRECORDCORE)NULL;
     1986            ri.zOrder = (ULONG)CMA_TOP;
     1987            ri.cRecordsInsert = ulRecsToInsert;
     1988            ri.fInvalidateRecord = FALSE;
     1989
     1990            if (!WinSendMsg(hwndLeft, CM_INSERTRECORD,
     1991                            MPFROMP(pcilFirst), MPFROMP(&ri))) {
     1992              Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
     1993              FreeCnrItemList(hwndLeft, pcilFirst);
     1994              cmp->cmp->totalleft -= insertedl;
     1995            }
     1996            pcilFirst = NULL;
     1997
     1998            // Insert right side
     1999            memset(&ri, 0, sizeof(RECORDINSERT));
     2000            ri.cb = sizeof(RECORDINSERT);
     2001            ri.pRecordOrder = (PRECORDCORE)CMA_END;
     2002            ri.pRecordParent = (PRECORDCORE)NULL;
     2003            ri.zOrder = (ULONG)CMA_TOP;
     2004            ri.cRecordsInsert = ulRecsToInsert;
     2005            ri.fInvalidateRecord = FALSE;
     2006
     2007            if (!WinSendMsg(hwndRight, CM_INSERTRECORD,
     2008                            MPFROMP(pcirFirst), MPFROMP(&ri))) {
     2009              Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
     2010              // 2011-05-29 SHL fixme?
     2011              RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
     2012              FreeCnrItemList(hwndRight, pcirFirst);
     2013              cmp->cmp->totalright -= insertedr;
     2014            }
     2015            pcirFirst = NULL;
     2016          } // if need insert
     2017
    19692018        } // while filling left or right
    19702019
    1971         // If stopped early CM_ALLOCATERECORD partially failed
    1972         // Free up container records we did not use on other side
    1973         // Free up items we did not insert in container
    1974         if (recsGotten < recsNeeded) {
    1975           if (pcil) {
    1976             if (pcilLast)
    1977               pcilLast->rc.preccNextRecord = NULL;
    1978             else
    1979               pcilFirst = NULL;
    1980             FreeCnrItemList(hwndLeft, pcil);
    1981           }
     2020        // If stopped early clean up
     2021
     2022        if (cmp->stop) {
     2023          // Free up container records that we did not insert in container
     2024          if (pcilFirst)
     2025            FreeCnrItemList(hwndLeft, pcilFirst);
     2026
     2027          // Free up items we did not insert in container
    19822028          if (filesl) {
    19832029            for(; filesl[l]; l++) {
     
    19852031            }
    19862032          }
    1987           if (pcir) {
    1988             if (pcirLast)
    1989               pcirLast->rc.preccNextRecord = NULL;
    1990             else
    1991               pcirFirst = NULL;
    1992             FreeCnrItemList(hwndRight, pcir);
    1993           }
     2033
     2034          if (pcirFirst)
     2035            FreeCnrItemList(hwndRight, pcirFirst);
     2036
    19942037          if (filesr) {
    19952038            for (; filesr[r]; r++) {
     
    19972040            }
    19982041          }
    1999           // Reduce count to match what is in containers
    2000           recsNeeded = recsGotten;
    20012042        } // if insufficient resources
    20022043
    2003           xfree(filesl, pszSrcFile, __LINE__);  // Free header - have already freed elements
     2044        xfree(filesl, pszSrcFile, __LINE__);    // Free header - have already freed elements
    20042045        filesl = NULL;
    20052046          xfree(filesr, pszSrcFile, __LINE__);
    20062047        filesr = NULL;
    20072048
    2008         // Say inserting
    2009         WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID);
    2010 
    2011         // Insert left side
    2012         memset(&ri, 0, sizeof(RECORDINSERT));
    2013         ri.cb = sizeof(RECORDINSERT);
    2014         ri.pRecordOrder = (PRECORDCORE)CMA_END;
    2015         ri.pRecordParent = (PRECORDCORE)NULL;
    2016         ri.zOrder = (ULONG)CMA_TOP;
    2017         ri.cRecordsInsert = recsNeeded;
    2018         ri.fInvalidateRecord = FALSE;
    2019 
    2020         if (!WinSendMsg(hwndLeft, CM_INSERTRECORD,
    2021                         MPFROMP(pcilFirst), MPFROMP(&ri))) {
    2022           Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
    2023           FreeCnrItemList(hwndLeft, pcilFirst);
    2024           cmp->cmp->totalleft = 0;
    2025         }
    2026 
    2027         // Insert right side
    2028         memset(&ri, 0, sizeof(RECORDINSERT));
    2029         ri.cb = sizeof(RECORDINSERT);
    2030         ri.pRecordOrder = (PRECORDCORE)CMA_END;
    2031         ri.pRecordParent = (PRECORDCORE)NULL;
    2032         ri.zOrder = (ULONG)CMA_TOP;
    2033         ri.cRecordsInsert = recsNeeded;
    2034         ri.fInvalidateRecord = FALSE;
    2035 
    2036         if (!WinSendMsg(hwndRight, CM_INSERTRECORD,
    2037                         MPFROMP(pcirFirst), MPFROMP(&ri))) {
    2038           Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
    2039           RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
    2040           FreeCnrItemList(hwndRight, pcirFirst);
    2041           cmp->cmp->totalright = 0;
    2042         }
    2043 
    2044       } // if recsNeeded
     2049      } // if ulRecsNeeded
    20452050
    20462051      Deselect(hwndLeft);
     
    28302835            fakelist[1] = szPathName;
    28312836            fakelist[2] = NULL;
    2832             ExecOnList(hwnd, compare, WINDOWED | SEPARATEKEEP,
    2833                        NULL, NULL, fakelist, NULL,
     2837            ExecOnList(hwnd, compare, WINDOWED | SEPARATEKEEP,
     2838                       NULL, NULL, fakelist, NULL,
    28342839                       pszSrcFile, __LINE__);
    28352840          }
Note: See TracChangeset for help on using the changeset viewer.