| 1 | 
 | 
|---|
| 2 | /***********************************************************************
 | 
|---|
| 3 | 
 | 
|---|
| 4 |   $Id: update.c 1673 2012-12-30 18:51:01Z gyoung $
 | 
|---|
| 5 | 
 | 
|---|
| 6 |   Update Container record/list
 | 
|---|
| 7 | 
 | 
|---|
| 8 |   Copyright (c) 1993-98 M. Kimes
 | 
|---|
| 9 |   Copyright (c) 2003, 2008 Steven H. Levine
 | 
|---|
| 10 | 
 | 
|---|
| 11 |   12 Feb 03 SHL Standardize EA math
 | 
|---|
| 12 |   10 Jan 04 SHL Add some intermin large drive error avoidance
 | 
|---|
| 13 |   25 May 05 SHL Rework for ULONGLONG
 | 
|---|
| 14 |   25 May 05 SHL Rework for FillInRecordFromFFB
 | 
|---|
| 15 |   06 Jun 05 SHL Drop unused code
 | 
|---|
| 16 |   22 Jul 06 SHL Use wrappers
 | 
|---|
| 17 |   20 Feb 07 GKY Add SelectDriveIcon()
 | 
|---|
| 18 |   09 Mar 07 GKY Cleanup SelectDriveIcon using "driveflag =" from Steven
 | 
|---|
| 19 |   02 Aug 07 SHL Sync with CNRITEM mods
 | 
|---|
| 20 |   20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
 | 
|---|
| 21 |   14 Mar 09 GKY Prevent execution of UM_SHOWME while drive scan is occuring
 | 
|---|
| 22 |   22 Jul 09 GKY Code changes to use semaphores to serialize drive scanning
 | 
|---|
| 23 | 
 | 
|---|
| 24 | ***********************************************************************/
 | 
|---|
| 25 | 
 | 
|---|
| 26 | #include <stdlib.h>
 | 
|---|
| 27 | #include <string.h>
 | 
|---|
| 28 | #include <ctype.h>
 | 
|---|
| 29 | 
 | 
|---|
| 30 | #define INCL_DOS
 | 
|---|
| 31 | #define INCL_WIN
 | 
|---|
| 32 | #define INCL_LONGLONG
 | 
|---|
| 33 | 
 | 
|---|
| 34 | #include "fm3dll.h"
 | 
|---|
| 35 | #include "fm3dll2.h"                    // #define's for UM_*, control id's, etc.
 | 
|---|
| 36 | #include "update.h"
 | 
|---|
| 37 | #include "init.h"                       // Data declaration(s)
 | 
|---|
| 38 | #include "notebook.h"                   // Data declaration(s)
 | 
|---|
| 39 | #include "info.h"                       // Data declaration(s)
 | 
|---|
| 40 | #include "newview.h"                    // Data declarations
 | 
|---|
| 41 | #include "fm3str.h"
 | 
|---|
| 42 | #include "errutil.h"                    // Dos_Error...
 | 
|---|
| 43 | #include "filldir.h"                    // FillInRecordFromFFB
 | 
|---|
| 44 | #include "dircnrs.h"
 | 
|---|
| 45 | #include "flesh.h"                      // Flesh, Stubby
 | 
|---|
| 46 | #include "findrec.h"                    // FindCnrRecord
 | 
|---|
| 47 | #include "valid.h"                      // IsFullName
 | 
|---|
| 48 | #include "wrappers.h"                   // xDosFindFirst
 | 
|---|
| 49 | #include "misc.h"                       // PostMsg
 | 
|---|
| 50 | #include "fortify.h"
 | 
|---|
| 51 | 
 | 
|---|
| 52 | static PSZ pszSrcFile = __FILE__;
 | 
|---|
| 53 | 
 | 
|---|
| 54 | HPOINTER SelectDriveIcon(PCNRITEM pci)
 | 
|---|
| 55 | {
 | 
|---|
| 56 |     UINT driveflag = driveflags[toupper(*pci->pszFileName) - 'A'];
 | 
|---|
| 57 |     *pci->pszFileName = toupper(*pci->pszFileName);
 | 
|---|
| 58 |               if (isalpha(*pci->pszFileName) &&
 | 
|---|
| 59 |                   toupper(*pci->pszFileName) > 'B') {
 | 
|---|
| 60 |                 if (driveflag & DRIVE_CDROM)
 | 
|---|
| 61 |                   pci->rc.hptrIcon = hptrCDROM;
 | 
|---|
| 62 |                 else
 | 
|---|
| 63 |                   pci->rc.hptrIcon =
 | 
|---|
| 64 |                      (driveflag & DRIVE_REMOVABLE) ? hptrRemovable
 | 
|---|
| 65 |                     :(driveflag & DRIVE_VIRTUAL) ? hptrVirtual
 | 
|---|
| 66 |                     :(driveflag & DRIVE_REMOTE) ? hptrRemote
 | 
|---|
| 67 |                     :(driveflag & DRIVE_RAMDISK) ? hptrRamdisk
 | 
|---|
| 68 |                     :(driveflag & DRIVE_ZIPSTREAM) ? hptrZipstrm : hptrDrive;
 | 
|---|
| 69 |               }
 | 
|---|
| 70 |               else
 | 
|---|
| 71 |                 pci->rc.hptrIcon = hptrFloppy;
 | 
|---|
| 72 |                 return pci->rc.hptrIcon;
 | 
|---|
| 73 | }
 | 
|---|
| 74 | 
 | 
|---|
| 75 | /**
 | 
|---|
| 76 |  * Update/add CNRITEM record for filename
 | 
|---|
| 77 |  * Deletes existing CNRITEM if file has disappeared
 | 
|---|
| 78 |  * @returns pci pointer to CNRITEM record or NULL if not found or if stale CNRITEM deleted
 | 
|---|
| 79 |  */
 | 
|---|
| 80 | 
 | 
|---|
| 81 | PCNRITEM UpdateCnrRecord(HWND hwndCnr, CHAR *filename, BOOL partial,
 | 
|---|
| 82 |                          DIRCNRDATA *dcd)
 | 
|---|
| 83 | {
 | 
|---|
| 84 |   PCNRITEM pci;
 | 
|---|
| 85 |   FILEFINDBUF4L ffb;
 | 
|---|
| 86 |   HDIR hDir = HDIR_CREATE;
 | 
|---|
| 87 |   ULONG nm = 1;
 | 
|---|
| 88 |   ULONG oldemphasis = 0;
 | 
|---|
| 89 |   APIRET status;
 | 
|---|
| 90 | 
 | 
|---|
| 91 |   if (!filename || !*filename)
 | 
|---|
| 92 |     return (PCNRITEM) NULL;
 | 
|---|
| 93 |   if (IsFullName(filename)) {
 | 
|---|
| 94 |     if (driveflags[toupper(*filename) - 'A'] & DRIVE_NOTWRITEABLE)
 | 
|---|
| 95 |       // ignore non-writeable drives
 | 
|---|
| 96 |       return (PCNRITEM) NULL;
 | 
|---|
| 97 |   }
 | 
|---|
| 98 |   status = xDosFindFirst(filename,
 | 
|---|
| 99 |                          &hDir,
 | 
|---|
| 100 |                          FILE_NORMAL | FILE_DIRECTORY |
 | 
|---|
| 101 |                          FILE_ARCHIVED | FILE_READONLY |
 | 
|---|
| 102 |                          FILE_HIDDEN | FILE_SYSTEM,
 | 
|---|
| 103 |                          &ffb, sizeof(ffb), &nm, FIL_QUERYEASIZEL);
 | 
|---|
| 104 |   if (!status) {
 | 
|---|
| 105 |     // file exists
 | 
|---|
| 106 |     DosFindClose(hDir);
 | 
|---|
| 107 |     if (!dcd)
 | 
|---|
| 108 |       dcd = INSTDATA(hwndCnr);
 | 
|---|
| 109 |     if (dcd->type == ARC_FRAME)
 | 
|---|
| 110 |       return (PCNRITEM) NULL;
 | 
|---|
| 111 |     if (*dcd->directory) {
 | 
|---|
| 112 | 
 | 
|---|
| 113 |       CHAR *p, temp;
 | 
|---|
| 114 | 
 | 
|---|
| 115 |       p = strrchr(filename, '\\');
 | 
|---|
| 116 |       if (p) {
 | 
|---|
| 117 |         if (p < filename + 3)
 | 
|---|
| 118 |           p++;
 | 
|---|
| 119 |         temp = *p;
 | 
|---|
| 120 |         *p = 0;
 | 
|---|
| 121 |         if (stricmp(filename, dcd->directory)) {
 | 
|---|
| 122 |           *p = temp;
 | 
|---|
| 123 |           return (PCNRITEM) NULL;
 | 
|---|
| 124 |         }
 | 
|---|
| 125 |         *p = temp;
 | 
|---|
| 126 |       }
 | 
|---|
| 127 |       else
 | 
|---|
| 128 |         return (PCNRITEM) NULL;
 | 
|---|
| 129 |     }
 | 
|---|
| 130 |     pci = FindCnrRecord(hwndCnr,
 | 
|---|
| 131 |                         filename, (PCNRITEM) NULL, partial, FALSE, TRUE);
 | 
|---|
| 132 |   Update:
 | 
|---|
| 133 |     if (pci) {
 | 
|---|
| 134 |       // Check if record needs to be updated
 | 
|---|
| 135 |       if ((!fForceUpper && !fForceLower && strcmp(pci->pszFileName, filename)) ||
 | 
|---|
| 136 |           pci->cbFile != ffb.cbFile || pci->attrFile != ffb.attrFile ||
 | 
|---|
| 137 |           pci->easize != CBLIST_TO_EASIZE(ffb.cbList) || pci->date.day !=
 | 
|---|
| 138 |           ffb.fdateLastWrite.day || pci->date.month != ffb.fdateLastWrite.month ||
 | 
|---|
| 139 |           pci->date.year != ffb.fdateLastWrite.year + 1980 || pci->time.seconds !=
 | 
|---|
| 140 |           ffb.ftimeLastWrite.twosecs * 2 || pci->time.minutes != ffb.ftimeLastWrite.minutes ||
 | 
|---|
| 141 |           pci->time.hours != ffb.ftimeLastWrite.hours || pci->ladate.day !=
 | 
|---|
| 142 |           ffb.fdateLastAccess.day || pci->ladate.month != ffb.fdateLastAccess.month ||
 | 
|---|
| 143 |           pci->ladate.year != ffb.fdateLastAccess.year + 1980 || pci->latime.seconds !=
 | 
|---|
| 144 |           ffb.ftimeLastAccess.twosecs * 2 || pci->latime.minutes !=
 | 
|---|
| 145 |           ffb.ftimeLastAccess.minutes || pci->latime.hours != ffb.ftimeLastAccess.hours)
 | 
|---|
| 146 |       {
 | 
|---|
| 147 |         // Something changed - update
 | 
|---|
| 148 |         *ffb.achName = 0;       // Tell FillInRecordFromFFB that filename contains full pathname
 | 
|---|
| 149 |         ffb.cchName = 0;
 | 
|---|
| 150 |         FillInRecordFromFFB(hwndCnr, pci, filename, &ffb, partial, dcd);
 | 
|---|
| 151 |         if (strlen(pci->pszFileName) < 4)
 | 
|---|
| 152 |           SelectDriveIcon(pci);
 | 
|---|
| 153 |         oldemphasis = pci->rc.flRecordAttr & (CRA_SELECTED | CRA_CURSORED);
 | 
|---|
| 154 |         if (oldemphasis)
 | 
|---|
| 155 |           WinSendMsg(hwndCnr,
 | 
|---|
| 156 |                      CM_SETRECORDEMPHASIS,
 | 
|---|
| 157 |                      MPFROMP(pci), MPFROM2SHORT(FALSE, oldemphasis));
 | 
|---|
| 158 |         WinSendMsg(hwndCnr,
 | 
|---|
| 159 |                    CM_INVALIDATERECORD, MPFROMP(&pci), MPFROM2SHORT(1, CMA_TEXTCHANGED));
 | 
|---|
| 160 |         if (oldemphasis)
 | 
|---|
| 161 |           WinSendMsg(hwndCnr,
 | 
|---|
| 162 |                      CM_SETRECORDEMPHASIS,
 | 
|---|
| 163 |                      MPFROMP(pci), MPFROM2SHORT(TRUE, oldemphasis));
 | 
|---|
| 164 |       }
 | 
|---|
| 165 |       else                              // existed, unchanged, do nothing but return
 | 
|---|
| 166 |         return pci;
 | 
|---|
| 167 |     }
 | 
|---|
| 168 |     else {
 | 
|---|
| 169 |       // Add record
 | 
|---|
| 170 |       if (dcd->type == DIR_FRAME) {
 | 
|---|
| 171 | 
 | 
|---|
| 172 |         RECORDINSERT ri;
 | 
|---|
| 173 |         ULONGLONG ullTotalBytes;
 | 
|---|
| 174 | 
 | 
|---|
| 175 |         pci = WinSendMsg(hwndCnr,
 | 
|---|
| 176 |                          CM_ALLOCRECORD,
 | 
|---|
| 177 |                          MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
 | 
|---|
| 178 |         if (pci) {
 | 
|---|
| 179 |           *ffb.achName = 0;
 | 
|---|
| 180 |           ullTotalBytes = FillInRecordFromFFB(hwndCnr,
 | 
|---|
| 181 |                                               pci,
 | 
|---|
| 182 |                                               filename, &ffb, partial, dcd);
 | 
|---|
| 183 |           if (strlen(pci->pszFileName) < 4)
 | 
|---|
| 184 |           SelectDriveIcon(pci);
 | 
|---|
| 185 |           memset(&ri, 0, sizeof(RECORDINSERT));
 | 
|---|
| 186 |           ri.cb = sizeof(RECORDINSERT);
 | 
|---|
| 187 |           ri.pRecordOrder = (PRECORDCORE) CMA_END;
 | 
|---|
| 188 |           ri.pRecordParent = (PRECORDCORE) NULL;
 | 
|---|
| 189 |           ri.zOrder = (USHORT) CMA_TOP;
 | 
|---|
| 190 |           ri.cRecordsInsert = 1;
 | 
|---|
| 191 |           ri.fInvalidateRecord = TRUE;
 | 
|---|
| 192 |           if (WinSendMsg(hwndCnr,
 | 
|---|
| 193 |                          CM_INSERTRECORD,
 | 
|---|
| 194 |                          MPFROMP(pci), MPFROMP(&ri)) && ullTotalBytes) {
 | 
|---|
| 195 |             dcd->ullTotalBytes += ullTotalBytes;
 | 
|---|
| 196 |             PostMsg(hwndCnr, UM_RESCAN, MPVOID, MPVOID);
 | 
|---|
| 197 |             if (pci->attrFile & FILE_DIRECTORY) {
 | 
|---|
| 198 |               Stubby(hwndCnr, pci);
 | 
|---|
| 199 |             }
 | 
|---|
| 200 |           }
 | 
|---|
| 201 |         }
 | 
|---|
| 202 |       }
 | 
|---|
| 203 |       else if (ffb.attrFile & FILE_DIRECTORY) {
 | 
|---|
| 204 | 
 | 
|---|
| 205 |         // check all parts and insert as required
 | 
|---|
| 206 |         CHAR *p, temp;
 | 
|---|
| 207 |         PCNRITEM pciParent = NULL, pciT;
 | 
|---|
| 208 | 
 | 
|---|
| 209 |         p = strchr(filename, '\\');
 | 
|---|
| 210 |         if (p) {
 | 
|---|
| 211 |           while (p && *p) {
 | 
|---|
| 212 |             if (p < filename + 3)
 | 
|---|
| 213 |               p++;
 | 
|---|
| 214 |             temp = *p;
 | 
|---|
| 215 |             *p = 0;
 | 
|---|
| 216 |             pciT = FindCnrRecord(hwndCnr,
 | 
|---|
| 217 |                                  filename, NULL, partial, FALSE, TRUE);
 | 
|---|
| 218 |             if (!pciT || (INT) pciT == -1) {
 | 
|---|
| 219 |               pci = WinSendMsg(hwndCnr,
 | 
|---|
| 220 |                                CM_ALLOCRECORD,
 | 
|---|
| 221 |                                MPFROMLONG(EXTRA_RECORD_BYTES),
 | 
|---|
| 222 |                                MPFROMLONG(1));
 | 
|---|
| 223 |               if (pci) {
 | 
|---|
| 224 | 
 | 
|---|
| 225 |                 RECORDINSERT ri;
 | 
|---|
| 226 | 
 | 
|---|
| 227 |                 *ffb.achName = 0;
 | 
|---|
| 228 |                 FillInRecordFromFFB(hwndCnr,
 | 
|---|
| 229 |                                     pci, filename, &ffb, partial, dcd);
 | 
|---|
| 230 |                 if (strlen(pci->pszFileName) < 4)
 | 
|---|
| 231 |                 SelectDriveIcon(pci);
 | 
|---|
| 232 |                 memset(&ri, 0, sizeof(RECORDINSERT));
 | 
|---|
| 233 |                 ri.cb = sizeof(RECORDINSERT);
 | 
|---|
| 234 |                 ri.pRecordOrder = (PRECORDCORE) CMA_END;
 | 
|---|
| 235 |                 ri.pRecordParent = (PRECORDCORE) pciParent;
 | 
|---|
| 236 |                 ri.zOrder = (USHORT) CMA_TOP;
 | 
|---|
| 237 |                 ri.cRecordsInsert = 1;
 | 
|---|
| 238 |                 ri.fInvalidateRecord = TRUE;
 | 
|---|
| 239 |                 if (WinSendMsg(hwndCnr,
 | 
|---|
| 240 |                                CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
 | 
|---|
| 241 |                   Flesh(hwndCnr, pci);
 | 
|---|
| 242 |                   *p = temp;
 | 
|---|
| 243 |                   pci = FindCnrRecord(hwndCnr,
 | 
|---|
| 244 |                                       filename, pciT, partial, FALSE, TRUE);
 | 
|---|
| 245 |                   if (pci)
 | 
|---|
| 246 |                     goto Update;
 | 
|---|
| 247 |                 }
 | 
|---|
| 248 |               }
 | 
|---|
| 249 |             }
 | 
|---|
| 250 |             else {
 | 
|---|
| 251 |               pciParent = pciT;
 | 
|---|
| 252 |               if (!(pciT->rc.flRecordAttr & CRA_EXPANDED)) {
 | 
|---|
| 253 |                 Flesh(hwndCnr, pciT);
 | 
|---|
| 254 |                 *p = temp;
 | 
|---|
| 255 |                 pci = FindCnrRecord(hwndCnr,
 | 
|---|
| 256 |                                     filename, pciT, partial, FALSE, TRUE);
 | 
|---|
| 257 |                 if (pci)
 | 
|---|
| 258 |                   goto Update;
 | 
|---|
| 259 |               }
 | 
|---|
| 260 |             }
 | 
|---|
| 261 |             *p = temp;
 | 
|---|
| 262 |             p = strchr(p + ((temp == '\\') ? 1 : 0), '\\');
 | 
|---|
| 263 |           }
 | 
|---|
| 264 |         }
 | 
|---|
| 265 |         pci = WinSendMsg(hwndCnr,
 | 
|---|
| 266 |                          CM_ALLOCRECORD,
 | 
|---|
| 267 |                          MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
 | 
|---|
| 268 |         if (pci) {
 | 
|---|
| 269 | 
 | 
|---|
| 270 |           RECORDINSERT ri;
 | 
|---|
| 271 |           ULONGLONG ullTotalBytes;
 | 
|---|
| 272 | 
 | 
|---|
| 273 |           *ffb.achName = 0;
 | 
|---|
| 274 |           ullTotalBytes = FillInRecordFromFFB(hwndCnr,
 | 
|---|
| 275 |                                               pci,
 | 
|---|
| 276 |                                               filename, &ffb, partial, dcd);
 | 
|---|
| 277 |           if (strlen(pci->pszFileName) < 4)
 | 
|---|
| 278 |           SelectDriveIcon(pci);
 | 
|---|
| 279 |           memset(&ri, 0, sizeof(RECORDINSERT));
 | 
|---|
| 280 |           ri.cb = sizeof(RECORDINSERT);
 | 
|---|
| 281 |           ri.pRecordOrder = (PRECORDCORE) CMA_END;
 | 
|---|
| 282 |           ri.pRecordParent = (PRECORDCORE) pciParent;
 | 
|---|
| 283 |           ri.zOrder = (USHORT) CMA_TOP;
 | 
|---|
| 284 |           ri.cRecordsInsert = 1;
 | 
|---|
| 285 |           ri.fInvalidateRecord = TRUE;
 | 
|---|
| 286 |           if (WinSendMsg(hwndCnr,
 | 
|---|
| 287 |                          CM_INSERTRECORD,
 | 
|---|
| 288 |                          MPFROMP(pci), MPFROMP(&ri)) && ullTotalBytes) {
 | 
|---|
| 289 |             if (dcd->type == DIR_FRAME) {
 | 
|---|
| 290 |               dcd->ullTotalBytes += ullTotalBytes;
 | 
|---|
| 291 |             }
 | 
|---|
| 292 |             Stubby(hwndCnr, pci);
 | 
|---|
| 293 |           }
 | 
|---|
| 294 |         }
 | 
|---|
| 295 |       }
 | 
|---|
| 296 |     }
 | 
|---|
| 297 |   }
 | 
|---|
| 298 |   else if ((pci = FindCnrRecord(hwndCnr,
 | 
|---|
| 299 |                                 filename,
 | 
|---|
| 300 |                                 (PCNRITEM) NULL,
 | 
|---|
| 301 |                                 partial,
 | 
|---|
| 302 |                                 FALSE,
 | 
|---|
| 303 |                                 TRUE)) !=
 | 
|---|
| 304 |            NULL && (INT) pci != -1 && strlen(pci->pszFileName) > 3) {
 | 
|---|
| 305 |     // File has disappeared and found stale CNRITEM record delete it
 | 
|---|
| 306 |     if (!dcd)
 | 
|---|
| 307 |       dcd = INSTDATA(hwndCnr);
 | 
|---|
| 308 |     if (pci->rc.flRecordAttr & CRA_SELECTED)
 | 
|---|
| 309 |       WinSendMsg(hwndCnr,
 | 
|---|
| 310 |                  CM_SETRECORDEMPHASIS,
 | 
|---|
| 311 |                  MPFROMP(pci), MPFROM2SHORT(FALSE, CRA_SELECTED));
 | 
|---|
| 312 |     if (dcd->type == DIR_FRAME)
 | 
|---|
| 313 |       dcd->ullTotalBytes -= pci->cbFile + pci->easize;
 | 
|---|
| 314 |     RemoveCnrItems(hwndCnr, pci, 1, CMA_FREE | CMA_INVALIDATE);
 | 
|---|
| 315 |     pci = NULL;
 | 
|---|
| 316 |     PostMsg(hwndCnr, UM_RESCAN, MPVOID, MPVOID);
 | 
|---|
| 317 |   }
 | 
|---|
| 318 |   return pci;
 | 
|---|
| 319 | }
 | 
|---|
| 320 | 
 | 
|---|
| 321 | BOOL UpdateCnrList(HWND hwndCnr, CHAR ** filename, INT howmany, BOOL partial,
 | 
|---|
| 322 |                    DIRCNRDATA * dcd)
 | 
|---|
| 323 | {
 | 
|---|
| 324 |   PCNRITEM pci, *pciList = NULL;
 | 
|---|
| 325 |   FILEFINDBUF4L ffb;
 | 
|---|
| 326 |   HDIR hDir;
 | 
|---|
| 327 |   ULONG nm = (ULONG) howmany;
 | 
|---|
| 328 |   INT x;
 | 
|---|
| 329 |   INT numlist = 0;
 | 
|---|
| 330 |   INT numremain;
 | 
|---|
| 331 |   BOOL repos = FALSE;
 | 
|---|
| 332 |   BOOL ret = FALSE;
 | 
|---|
| 333 |   APIRET status;
 | 
|---|
| 334 | 
 | 
|---|
| 335 |   if (!dcd)
 | 
|---|
| 336 |     dcd = INSTDATA(hwndCnr);
 | 
|---|
| 337 |   if (!dcd) {
 | 
|---|
| 338 |     Runtime_Error(pszSrcFile, __LINE__, NULL);
 | 
|---|
| 339 |     return ret;
 | 
|---|
| 340 |   }
 | 
|---|
| 341 |   if (!filename || !howmany || !filename[0])
 | 
|---|
| 342 |     return ret;
 | 
|---|
| 343 |   {
 | 
|---|
| 344 |     CNRINFO cnri;
 | 
|---|
| 345 | 
 | 
|---|
| 346 |     memset(&cnri, 0, sizeof(CNRINFO));
 | 
|---|
| 347 |     cnri.cb = sizeof(CNRINFO);
 | 
|---|
| 348 |     WinSendMsg(hwndCnr,
 | 
|---|
| 349 |                CM_QUERYCNRINFO, MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
 | 
|---|
| 350 |     numremain = cnri.cRecords;
 | 
|---|
| 351 |   }
 | 
|---|
| 352 |   pciList = xmalloc(sizeof(PCNRITEM) * howmany, pszSrcFile, __LINE__);
 | 
|---|
| 353 |   if (pciList) {
 | 
|---|
| 354 |     for (x = 0; filename[x] && x < howmany; x++) {
 | 
|---|
| 355 |       if (IsFullName(filename[x])) {
 | 
|---|
| 356 |         if (driveflags[toupper(*filename[x]) - 'A'] & DRIVE_NOTWRITEABLE)
 | 
|---|
| 357 |           // ignore non-writeable drives
 | 
|---|
| 358 |           continue;
 | 
|---|
| 359 |       }
 | 
|---|
| 360 |       hDir = HDIR_CREATE;
 | 
|---|
| 361 |       status = xDosFindFirst(filename[x],
 | 
|---|
| 362 |                              &hDir,
 | 
|---|
| 363 |                              FILE_NORMAL | FILE_DIRECTORY |
 | 
|---|
| 364 |                              FILE_ARCHIVED | FILE_READONLY |
 | 
|---|
| 365 |                              FILE_HIDDEN | FILE_SYSTEM,
 | 
|---|
| 366 |                              &ffb, sizeof(ffb), &nm, FIL_QUERYEASIZEL);
 | 
|---|
| 367 |       if (!status) {
 | 
|---|
| 368 |         // file exists
 | 
|---|
| 369 |         DosFindClose(hDir);
 | 
|---|
| 370 |         if (dcd->type == DIR_FRAME && *dcd->directory) {
 | 
|---|
| 371 | 
 | 
|---|
| 372 |           CHAR *p, temp;
 | 
|---|
| 373 | 
 | 
|---|
| 374 |           p = strrchr(filename[x], '\\');
 | 
|---|
| 375 |           if (p) {
 | 
|---|
| 376 |             if (p < filename[x] + 3)
 | 
|---|
| 377 |               p++;
 | 
|---|
| 378 |             temp = *p;
 | 
|---|
| 379 |             *p = 0;
 | 
|---|
| 380 |             if (stricmp(filename[x], dcd->directory)) {
 | 
|---|
| 381 |               *p = temp;
 | 
|---|
| 382 |               continue;
 | 
|---|
| 383 |             }
 | 
|---|
| 384 |             *p = temp;
 | 
|---|
| 385 |           }
 | 
|---|
| 386 |           else
 | 
|---|
| 387 |             continue;
 | 
|---|
| 388 |         }
 | 
|---|
| 389 |         ret = TRUE;
 | 
|---|
| 390 |         pci = FindCnrRecord(hwndCnr,
 | 
|---|
| 391 |                             filename[x],
 | 
|---|
| 392 |                             (PCNRITEM) NULL, partial, FALSE, TRUE);
 | 
|---|
| 393 |         if (pci) {
 | 
|---|
| 394 |           // update record?
 | 
|---|
| 395 |           if ((!fForceUpper && !fForceLower &&
 | 
|---|
| 396 |                strcmp(pci->pszFileName, filename[x])) ||
 | 
|---|
| 397 |               pci->cbFile != ffb.cbFile || pci->attrFile != ffb.attrFile ||
 | 
|---|
| 398 |               pci->easize != CBLIST_TO_EASIZE(ffb.cbList) ||
 | 
|---|
| 399 |               pci->date.day != ffb.fdateLastWrite.day ||
 | 
|---|
| 400 |               pci->date.month != ffb.fdateLastWrite.month ||
 | 
|---|
| 401 |               pci->date.year != ffb.fdateLastWrite.year + 1980 ||
 | 
|---|
| 402 |               pci->time.seconds != ffb.ftimeLastWrite.twosecs * 2 ||
 | 
|---|
| 403 |               pci->time.minutes != ffb.ftimeLastWrite.minutes ||
 | 
|---|
| 404 |               pci->time.hours != ffb.ftimeLastWrite.hours ||
 | 
|---|
| 405 |               pci->ladate.day != ffb.fdateLastAccess.day ||
 | 
|---|
| 406 |               pci->ladate.month != ffb.fdateLastAccess.month ||
 | 
|---|
| 407 |               pci->ladate.year != ffb.fdateLastAccess.year + 1980 ||
 | 
|---|
| 408 |               pci->latime.seconds != ffb.ftimeLastAccess.twosecs * 2 ||
 | 
|---|
| 409 |               pci->latime.minutes != ffb.ftimeLastAccess.minutes ||
 | 
|---|
| 410 |               pci->latime.hours != ffb.ftimeLastAccess.hours) {
 | 
|---|
| 411 |             // changed; update
 | 
|---|
| 412 |             pciList[numlist++] = pci;
 | 
|---|
| 413 |             *ffb.achName = 0;
 | 
|---|
| 414 |             ffb.cchName = 0;
 | 
|---|
| 415 |             FillInRecordFromFFB(hwndCnr,
 | 
|---|
| 416 |                                 pci, filename[x], &ffb, partial, dcd);
 | 
|---|
| 417 |             if (IsRoot(pci->pszFileName))
 | 
|---|
| 418 |               SelectDriveIcon(pci);
 | 
|---|
| 419 |             WinSendMsg(hwndCnr,
 | 
|---|
| 420 |                        CM_SETRECORDEMPHASIS,
 | 
|---|
| 421 |                        MPFROMP(pci),
 | 
|---|
| 422 |                        MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED));
 | 
|---|
| 423 |           }
 | 
|---|
| 424 |         }
 | 
|---|
| 425 |         else {
 | 
|---|
| 426 |           // add record
 | 
|---|
| 427 |           if (dcd->type == DIR_FRAME) {
 | 
|---|
| 428 |             RECORDINSERT ri;
 | 
|---|
| 429 |             ULONGLONG ullTotalBytes;
 | 
|---|
| 430 | 
 | 
|---|
| 431 |             pci = WinSendMsg(hwndCnr,
 | 
|---|
| 432 |                              CM_ALLOCRECORD,
 | 
|---|
| 433 |                              MPFROMLONG(EXTRA_RECORD_BYTES), MPFROMLONG(1));
 | 
|---|
| 434 |             if (pci) {
 | 
|---|
| 435 |               ret = TRUE;
 | 
|---|
| 436 |               *ffb.achName = 0;
 | 
|---|
| 437 |               ullTotalBytes = FillInRecordFromFFB(hwndCnr,
 | 
|---|
| 438 |                                                   pci,
 | 
|---|
| 439 |                                                   filename[x],
 | 
|---|
| 440 |                                                   &ffb, partial, dcd);
 | 
|---|
| 441 |               if (strlen(pci->pszFileName) < 4)
 | 
|---|
| 442 |                 SelectDriveIcon(pci);
 | 
|---|
| 443 |               memset(&ri, 0, sizeof(RECORDINSERT));
 | 
|---|
| 444 |               ri.cb = sizeof(RECORDINSERT);
 | 
|---|
| 445 |               ri.pRecordOrder = (PRECORDCORE) CMA_END;
 | 
|---|
| 446 |               ri.pRecordParent = (PRECORDCORE) NULL;
 | 
|---|
| 447 |               ri.zOrder = (USHORT) CMA_TOP;
 | 
|---|
| 448 |               ri.cRecordsInsert = 1;
 | 
|---|
| 449 |               ri.fInvalidateRecord = FALSE;
 | 
|---|
| 450 |               if (WinSendMsg(hwndCnr,
 | 
|---|
| 451 |                              CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
 | 
|---|
| 452 |                 if (ullTotalBytes) {
 | 
|---|
| 453 |                   dcd->ullTotalBytes += ullTotalBytes;
 | 
|---|
| 454 |                   numremain++;
 | 
|---|
| 455 |                 }
 | 
|---|
| 456 |                 repos = TRUE;
 | 
|---|
| 457 |                 if (pci->attrFile & FILE_DIRECTORY) {
 | 
|---|
| 458 |                   Stubby(hwndCnr, pci);
 | 
|---|
| 459 |                 }
 | 
|---|
| 460 |               }
 | 
|---|
| 461 |               else
 | 
|---|
| 462 |                 FreeCnrItem(hwndCnr, pci);
 | 
|---|
| 463 |             }
 | 
|---|
| 464 |           }
 | 
|---|
| 465 |           else if (ffb.attrFile & FILE_DIRECTORY) {
 | 
|---|
| 466 |             // check all parts and insert as required
 | 
|---|
| 467 |             CHAR *p, temp;
 | 
|---|
| 468 |             PCNRITEM pciParent = NULL, pciT;
 | 
|---|
| 469 | 
 | 
|---|
| 470 |             p = strchr(filename[x], '\\');
 | 
|---|
| 471 |             if (p) {
 | 
|---|
| 472 |               while (p && *p) {
 | 
|---|
| 473 |                 if (p < filename[x] + 3)
 | 
|---|
| 474 |                   p++;
 | 
|---|
| 475 |                 temp = *p;
 | 
|---|
| 476 |                 *p = 0;
 | 
|---|
| 477 |                 pciT = FindCnrRecord(hwndCnr,
 | 
|---|
| 478 |                                      filename[x], NULL, partial, FALSE, TRUE);
 | 
|---|
| 479 |                 if (!pciT || (INT) pciT == -1) {
 | 
|---|
| 480 |                   pci = WinSendMsg(hwndCnr,
 | 
|---|
| 481 |                                    CM_ALLOCRECORD,
 | 
|---|
| 482 |                                    MPFROMLONG(EXTRA_RECORD_BYTES),
 | 
|---|
| 483 |                                    MPFROMLONG(1));
 | 
|---|
| 484 |                   if (pci) {
 | 
|---|
| 485 | 
 | 
|---|
| 486 |                     RECORDINSERT ri;
 | 
|---|
| 487 |                     ULONGLONG ullTotalBytes;
 | 
|---|
| 488 | 
 | 
|---|
| 489 |                     ret = TRUE;
 | 
|---|
| 490 |                     *ffb.achName = 0;
 | 
|---|
| 491 |                     ullTotalBytes = FillInRecordFromFFB(hwndCnr,
 | 
|---|
| 492 |                                                         pci,
 | 
|---|
| 493 |                                                         filename[x],
 | 
|---|
| 494 |                                                         &ffb, partial, dcd);
 | 
|---|
| 495 |                     if (strlen(pci->pszFileName) < 4)
 | 
|---|
| 496 |                       SelectDriveIcon(pci);
 | 
|---|
| 497 |                     memset(&ri, 0, sizeof(RECORDINSERT));
 | 
|---|
| 498 |                     ri.cb = sizeof(RECORDINSERT);
 | 
|---|
| 499 |                     ri.pRecordOrder = (PRECORDCORE) CMA_END;
 | 
|---|
| 500 |                     ri.pRecordParent = (PRECORDCORE) pciParent;
 | 
|---|
| 501 |                     ri.zOrder = (USHORT) CMA_TOP;
 | 
|---|
| 502 |                     ri.cRecordsInsert = 1;
 | 
|---|
| 503 |                     ri.fInvalidateRecord = FALSE;
 | 
|---|
| 504 |                     if (WinSendMsg(hwndCnr,
 | 
|---|
| 505 |                                    CM_INSERTRECORD,
 | 
|---|
| 506 |                                    MPFROMP(pci), MPFROMP(&ri))) {
 | 
|---|
| 507 |                       if (ullTotalBytes) {
 | 
|---|
| 508 |                         numremain++;
 | 
|---|
| 509 |                         if (dcd->type == DIR_FRAME)
 | 
|---|
| 510 |                           dcd->ullTotalBytes += ullTotalBytes;
 | 
|---|
| 511 |                       }
 | 
|---|
| 512 |                       repos = TRUE;
 | 
|---|
| 513 |                     }
 | 
|---|
| 514 |                     else
 | 
|---|
| 515 |                       FreeCnrItem(hwndCnr, pci);
 | 
|---|
| 516 |                   }
 | 
|---|
| 517 |                 }
 | 
|---|
| 518 |                 else
 | 
|---|
| 519 |                   pciParent = pciT;
 | 
|---|
| 520 |                 *p = temp;
 | 
|---|
| 521 |                 p = strchr(p + ((temp == '\\') ? 1 : 0), '\\');
 | 
|---|
| 522 |               }
 | 
|---|
| 523 |             }
 | 
|---|
| 524 |             {
 | 
|---|
| 525 |               pci = WinSendMsg(hwndCnr,
 | 
|---|
| 526 |                                CM_ALLOCRECORD,
 | 
|---|
| 527 |                                MPFROMLONG(EXTRA_RECORD_BYTES),
 | 
|---|
| 528 |                                MPFROMLONG(1));
 | 
|---|
| 529 |               if (pci) {
 | 
|---|
| 530 | 
 | 
|---|
| 531 |                 RECORDINSERT ri;
 | 
|---|
| 532 |                 ULONGLONG ullTotalBytes;
 | 
|---|
| 533 | 
 | 
|---|
| 534 |                 ret = TRUE;
 | 
|---|
| 535 |                 *ffb.achName = 0;
 | 
|---|
| 536 |                 ullTotalBytes = FillInRecordFromFFB(hwndCnr,
 | 
|---|
| 537 |                                                     pci,
 | 
|---|
| 538 |                                                     filename[x],
 | 
|---|
| 539 |                                                     &ffb, partial, dcd);
 | 
|---|
| 540 |                 if (strlen(pci->pszFileName) < 4)
 | 
|---|
| 541 |                   SelectDriveIcon(pci);
 | 
|---|
| 542 |                 memset(&ri, 0, sizeof(RECORDINSERT));
 | 
|---|
| 543 |                 ri.cb = sizeof(RECORDINSERT);
 | 
|---|
| 544 |                 ri.pRecordOrder = (PRECORDCORE) CMA_END;
 | 
|---|
| 545 |                 ri.pRecordParent = (PRECORDCORE) pciParent;
 | 
|---|
| 546 |                 ri.zOrder = (USHORT) CMA_TOP;
 | 
|---|
| 547 |                 ri.cRecordsInsert = 1;
 | 
|---|
| 548 |                 ri.fInvalidateRecord = FALSE;
 | 
|---|
| 549 |                 if (WinSendMsg(hwndCnr,
 | 
|---|
| 550 |                                CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri))) {
 | 
|---|
| 551 |                   if (ullTotalBytes) {
 | 
|---|
| 552 |                     numremain++;
 | 
|---|
| 553 |                     if (dcd->type == DIR_FRAME)
 | 
|---|
| 554 |                       dcd->ullTotalBytes += ullTotalBytes;
 | 
|---|
| 555 |                   }
 | 
|---|
| 556 |                   repos = TRUE;
 | 
|---|
| 557 |                   Stubby(hwndCnr, pci);
 | 
|---|
| 558 |                 }
 | 
|---|
| 559 |                 else
 | 
|---|
| 560 |                   FreeCnrItem(hwndCnr, pci);
 | 
|---|
| 561 |               }
 | 
|---|
| 562 |             }
 | 
|---|
| 563 |           }
 | 
|---|
| 564 |         }
 | 
|---|
| 565 |       }
 | 
|---|
| 566 |       else if ((pci = FindCnrRecord(hwndCnr,
 | 
|---|
| 567 |                                     filename[x],
 | 
|---|
| 568 |                                     (PCNRITEM) NULL,
 | 
|---|
| 569 |                                     partial,
 | 
|---|
| 570 |                                     FALSE,
 | 
|---|
| 571 |                                     TRUE)) != NULL &&
 | 
|---|
| 572 |                (INT) pci != -1 && !IsRoot(pci->pszFileName)) {
 | 
|---|
| 573 |         // file doesn't exist; delete record
 | 
|---|
| 574 |         if (pci->rc.flRecordAttr & CRA_SELECTED)
 | 
|---|
| 575 |           WinSendMsg(hwndCnr,
 | 
|---|
| 576 |                      CM_SETRECORDEMPHASIS,
 | 
|---|
| 577 |                      MPFROMP(pci), MPFROM2SHORT(FALSE, CRA_SELECTED));
 | 
|---|
| 578 |         if (dcd->type == DIR_FRAME)
 | 
|---|
| 579 |           dcd->ullTotalBytes -= (pci->cbFile + pci->easize);
 | 
|---|
| 580 |         // 02 Aug 07 SHL rc check was wrong
 | 
|---|
| 581 |         if (RemoveCnrItems(hwndCnr, pci, 1,
 | 
|---|
| 582 |                            CMA_FREE |
 | 
|---|
| 583 |                            numremain == 1 ? CMA_INVALIDATE : 0) != -1) {
 | 
|---|
| 584 |           pci = NULL;
 | 
|---|
| 585 |           numremain--;
 | 
|---|
| 586 |           repos = TRUE;
 | 
|---|
| 587 |         }
 | 
|---|
| 588 |       }
 | 
|---|
| 589 |     } // for x
 | 
|---|
| 590 |   }
 | 
|---|
| 591 |   if (repos || (pciList && numlist)) {
 | 
|---|
| 592 |     QUERYRECORDRECT qrr;
 | 
|---|
| 593 |     RECTL rCnr, rCItem;
 | 
|---|
| 594 | 
 | 
|---|
| 595 |     pci = WinSendMsg(hwndCnr,
 | 
|---|
| 596 |                      CM_QUERYRECORDEMPHASIS,
 | 
|---|
| 597 |                      MPFROMLONG(CMA_FIRST), MPFROMLONG(CRA_CURSORED));
 | 
|---|
| 598 |     if (pci && (INT) pci != -1) {
 | 
|---|
| 599 |       memset(&qrr, 0, sizeof(QUERYRECORDRECT));
 | 
|---|
| 600 |       qrr.cb = sizeof(QUERYRECORDRECT);
 | 
|---|
| 601 |       qrr.pRecord = (PRECORDCORE) pci;
 | 
|---|
| 602 |       qrr.fRightSplitWindow = FALSE;
 | 
|---|
| 603 |       qrr.fsExtent = CMA_TEXT;
 | 
|---|
| 604 |       if (!WinSendMsg(hwndCnr,
 | 
|---|
| 605 |                       CM_QUERYRECORDRECT, MPFROMP(&rCItem), MPFROMP(&qrr)))
 | 
|---|
| 606 |         qrr.cb = 0;
 | 
|---|
| 607 |     }
 | 
|---|
| 608 |     if (pciList && numlist && !repos) {
 | 
|---|
| 609 |       WinSendMsg(hwndCnr,
 | 
|---|
| 610 |                  CM_INVALIDATERECORD,
 | 
|---|
| 611 |                  MPFROMP(pciList),
 | 
|---|
| 612 |                  MPFROM2SHORT(numlist,
 | 
|---|
| 613 |                               (repos ? CMA_NOREPOSITION :
 | 
|---|
| 614 |                                CMA_REPOSITION | CMA_ERASE)));
 | 
|---|
| 615 |     }
 | 
|---|
| 616 |     if (repos)
 | 
|---|
| 617 |       WinSendMsg(hwndCnr,
 | 
|---|
| 618 |                  CM_INVALIDATERECORD,
 | 
|---|
| 619 |                  MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
 | 
|---|
| 620 |     if (pci && (INT) pci != -1 && qrr.cb) {
 | 
|---|
| 621 |       WinSendMsg(hwndCnr,
 | 
|---|
| 622 |                  CM_QUERYVIEWPORTRECT,
 | 
|---|
| 623 |                  MPFROMP(&rCnr), MPFROM2SHORT(CMA_WINDOW, (SHORT) FALSE));
 | 
|---|
| 624 |       WinSendMsg(hwndCnr,
 | 
|---|
| 625 |                  CM_SCROLLWINDOW,
 | 
|---|
| 626 |                  MPFROMSHORT(CMA_VERTICAL),
 | 
|---|
| 627 |                  MPFROMLONG(rCnr.yTop - rCItem.yTop));
 | 
|---|
| 628 |     }
 | 
|---|
| 629 |   }
 | 
|---|
| 630 |   PostMsg(hwndCnr, UM_RESCAN, MPVOID, MPVOID);
 | 
|---|
| 631 |   if (pciList) {
 | 
|---|
| 632 |     free(pciList);
 | 
|---|
| 633 |     DosPostEventSem(CompactSem);
 | 
|---|
| 634 |   }
 | 
|---|
| 635 |   return ret;
 | 
|---|
| 636 | }
 | 
|---|
| 637 | 
 | 
|---|
| 638 | #pragma alloc_text(UPDATECNR,UpdateCnrRecord,UpdateCnrList)
 | 
|---|