/ Check-in [1bbbf857]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Pull over all the latest changes from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental-pcache
Files: files | file ages | folders
SHA1: 1bbbf8574a820c5f787a937f02a8e2a91264ace0
User & Date: drh 2011-11-11 14:12:36
Context
2011-11-16
23:29
Back out the [ceee03c79a] change. check-in: 69ec53fc user: drh tags: trunk
2011-11-12
23:10
Attempt to modify btree.c so that it assumes that calls to sqlite3PagerWrite() will reallocate the page buffer. As there is not good way to test this assumption yet, probably a few spots were missed. check-in: ceee03c7 user: drh tags: experimental-pcache
2011-11-11
14:12
Pull over all the latest changes from trunk. check-in: 1bbbf857 user: drh tags: experimental-pcache
00:27
Make sure a corrupt index does not cause a buffer overread in sqlite3VdbeRecordCompare(). check-in: 471cf0d8 user: drh tags: trunk
2011-11-10
02:39
Follow-on to the previous check-in to prevent a division by zero if the lookahead slot size is something goofy like 6 on a 32-bit machine. check-in: 6bda711f user: drh tags: experimental-pcache
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

   855    855   ** Given a btree page and a cell index (0 means the first cell on
   856    856   ** the page, 1 means the second cell, and so forth) return a pointer
   857    857   ** to the cell content.
   858    858   **
   859    859   ** This routine works only for pages that do not contain overflow cells.
   860    860   */
   861    861   #define findCell(P,I) \
   862         -  ((P)->aData + ((P)->maskPage & get2byte(&(P)->aData[(P)->cellOffset+2*(I)])))
          862  +  ((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)])))
   863    863   #define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I)))))
   864    864   
   865    865   
   866    866   /*
   867    867   ** This a more complex version of findCell() that works for
   868    868   ** pages that do contain overflow cells.
   869    869   */
................................................................................
  1405   1405       data = pPage->aData;
  1406   1406       if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
  1407   1407       assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
  1408   1408       pPage->maskPage = (u16)(pBt->pageSize - 1);
  1409   1409       pPage->nOverflow = 0;
  1410   1410       usableSize = pBt->usableSize;
  1411   1411       pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
         1412  +    pPage->aDataEnd = &data[usableSize];
         1413  +    pPage->aCellIdx = &data[cellOffset];
  1412   1414       top = get2byteNotZero(&data[hdr+5]);
  1413   1415       pPage->nCell = get2byte(&data[hdr+3]);
  1414   1416       if( pPage->nCell>MX_CELL(pBt) ){
  1415   1417         /* To many cells for a single page.  The page must be corrupt */
  1416   1418         return SQLITE_CORRUPT_BKPT;
  1417   1419       }
  1418   1420       testcase( pPage->nCell==MX_CELL(pBt) );
................................................................................
  1508   1510     memset(&data[hdr+1], 0, 4);
  1509   1511     data[hdr+7] = 0;
  1510   1512     put2byte(&data[hdr+5], pBt->usableSize);
  1511   1513     pPage->nFree = (u16)(pBt->usableSize - first);
  1512   1514     decodeFlags(pPage, flags);
  1513   1515     pPage->hdrOffset = hdr;
  1514   1516     pPage->cellOffset = first;
         1517  +  pPage->aDataEnd = &data[pBt->usableSize];
         1518  +  pPage->aCellIdx = &data[first];
  1515   1519     pPage->nOverflow = 0;
  1516   1520     assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
  1517   1521     pPage->maskPage = (u16)(pBt->pageSize - 1);
  1518   1522     pPage->nCell = 0;
  1519   1523     pPage->isInit = 1;
  1520   1524   }
  1521   1525   
................................................................................
  4546   4550           ** page is less than 16384 bytes and may be stored as a 2-byte
  4547   4551           ** varint. This information is used to attempt to avoid parsing 
  4548   4552           ** the entire cell by checking for the cases where the record is 
  4549   4553           ** stored entirely within the b-tree page by inspecting the first 
  4550   4554           ** 2 bytes of the cell.
  4551   4555           */
  4552   4556           int nCell = pCell[0];
  4553         -        if( !(nCell & 0x80) && nCell<=pPage->maxLocal ){
         4557  +        if( !(nCell & 0x80)
         4558  +         && nCell<=pPage->maxLocal
         4559  +         && (pCell+nCell+1)<=pPage->aDataEnd
         4560  +        ){
  4554   4561             /* This branch runs if the record-size field of the cell is a
  4555   4562             ** single byte varint and the record fits entirely on the main
  4556   4563             ** b-tree page.  */
         4564  +          testcase( pCell+nCell+1==pPage->aDataEnd );
  4557   4565             c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
  4558   4566           }else if( !(pCell[1] & 0x80) 
  4559   4567             && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
         4568  +          && (pCell+nCell+2)<=pPage->aDataEnd
  4560   4569           ){
  4561   4570             /* The record-size field is a 2 byte varint and the record 
  4562   4571             ** fits entirely on the main b-tree page.  */
         4572  +          testcase( pCell+nCell+2==pPage->aDataEnd );
  4563   4573             c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
  4564   4574           }else{
  4565   4575             /* The record flows over onto one or more overflow pages. In
  4566   4576             ** this case the whole cell needs to be parsed, a buffer allocated
  4567   4577             ** and accessPayload() used to retrieve the record into the
  4568   4578             ** buffer before VdbeRecordCompare() can be called. */
  4569   4579             void *pCellKey;
................................................................................
  5450   5460     if( *pRC ) return;
  5451   5461   
  5452   5462     assert( idx>=0 && idx<pPage->nCell );
  5453   5463     assert( sz==cellSize(pPage, idx) );
  5454   5464     assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  5455   5465     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  5456   5466     data = pPage->aData;
  5457         -  ptr = &data[pPage->cellOffset + 2*idx];
         5467  +  ptr = &pPage->aCellIdx[2*idx];
  5458   5468     pc = get2byte(ptr);
  5459   5469     hdr = pPage->hdrOffset;
  5460   5470     testcase( pc==get2byte(&data[hdr+5]) );
  5461   5471     testcase( pc+sz==pPage->pBt->usableSize );
  5462   5472     if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){
  5463   5473       *pRC = SQLITE_CORRUPT_BKPT;
  5464   5474       return;
  5465   5475     }
  5466   5476     rc = freeSpace(pPage, pc, sz);
  5467   5477     if( rc ){
  5468   5478       *pRC = rc;
  5469   5479       return;
  5470   5480     }
  5471         -  endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2];
         5481  +  endPtr = &pPage->aCellIdx[2*pPage->nCell - 2];
  5472   5482     assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 );  /* ptr is always 2-byte aligned */
  5473   5483     while( ptr<endPtr ){
  5474   5484       *(u16*)ptr = *(u16*)&ptr[2];
  5475   5485       ptr += 2;
  5476   5486     }
  5477   5487     pPage->nCell--;
  5478   5488     put2byte(&data[hdr+3], pPage->nCell);
................................................................................
  5606   5616               && (int)MX_CELL(pPage->pBt)<=10921);
  5607   5617     assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  5608   5618   
  5609   5619     /* Check that the page has just been zeroed by zeroPage() */
  5610   5620     assert( pPage->nCell==0 );
  5611   5621     assert( get2byteNotZero(&data[hdr+5])==nUsable );
  5612   5622   
  5613         -  pCellptr = &data[pPage->cellOffset + nCell*2];
         5623  +  pCellptr = &pPage->aCellIdx[nCell*2];
  5614   5624     cellbody = nUsable;
  5615   5625     for(i=nCell-1; i>=0; i--){
  5616   5626       u16 sz = aSize[i];
  5617   5627       pCellptr -= 2;
  5618   5628       cellbody -= sz;
  5619   5629       put2byte(pCellptr, cellbody);
  5620   5630       memcpy(&data[cellbody], apCell[i], sz);

Changes to src/btreeInt.h.

   285    285     u16 maskPage;        /* Mask for page offset */
   286    286     struct _OvflCell {   /* Cells that will not fit on aData[] */
   287    287       u8 *pCell;          /* Pointers to the body of the overflow cell */
   288    288       u16 idx;            /* Insert this cell before idx-th non-overflow cell */
   289    289     } aOvfl[5];
   290    290     BtShared *pBt;       /* Pointer to BtShared that this page is part of */
   291    291     u8 *aData;           /* Pointer to disk image of the page data */
          292  +  u8 *aDataEnd;        /* One byte past the end of usable data */
          293  +  u8 *aCellIdx;        /* The cell index area */
   292    294     DbPage *pDbPage;     /* Pager page handle */
   293    295     Pgno pgno;           /* Page number for this page */
   294    296   };
   295    297   
   296    298   /*
   297    299   ** The in-memory image of a disk page has the auxiliary information appended
   298    300   ** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold

Changes to src/os_win.c.

    44     44   
    45     45   #include <winbase.h>
    46     46   
    47     47   #ifdef __CYGWIN__
    48     48   # include <sys/cygwin.h>
    49     49   #endif
    50     50   
    51         -/*
    52         -** Macros used to determine whether or not to use threads.
    53         -*/
    54         -#if defined(THREADSAFE) && THREADSAFE
    55         -# define SQLITE_W32_THREADS 1
    56         -#endif
    57         -
    58     51   /*
    59     52   ** Include code that is common to all os_*.c files
    60     53   */
    61     54   #include "os_common.h"
    62     55   
    63     56   /*
    64     57   ** Some microsoft compilers lack this definition.
................................................................................
   554    547   
   555    548   
   556    549   /*
   557    550   ** The return value of getLastErrorMsg
   558    551   ** is zero if the error message fits in the buffer, or non-zero
   559    552   ** otherwise (if the message was truncated).
   560    553   */
   561         -static int getLastErrorMsg(int nBuf, char *zBuf){
          554  +static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
   562    555     /* FormatMessage returns 0 on failure.  Otherwise it
   563    556     ** returns the number of TCHARs written to the output
   564    557     ** buffer, excluding the terminating null char.
   565    558     */
   566         -  DWORD error = GetLastError();
   567    559     DWORD dwLen = 0;
   568    560     char *zOut = 0;
   569    561   
   570    562     if( isNT() ){
   571    563       WCHAR *zTempWide = NULL;
   572         -    dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
          564  +    dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
          565  +                           FORMAT_MESSAGE_FROM_SYSTEM |
          566  +                           FORMAT_MESSAGE_IGNORE_INSERTS,
   573    567                              NULL,
   574         -                           error,
          568  +                           lastErrno,
   575    569                              0,
   576    570                              (LPWSTR) &zTempWide,
   577    571                              0,
   578    572                              0);
   579    573       if( dwLen > 0 ){
   580    574         /* allocate a buffer and convert to UTF8 */
   581    575         zOut = unicodeToUtf8(zTempWide);
................................................................................
   585    579   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
   586    580   ** Since the ASCII version of these Windows API do not exist for WINCE,
   587    581   ** it's important to not reference them for WINCE builds.
   588    582   */
   589    583   #if SQLITE_OS_WINCE==0
   590    584     }else{
   591    585       char *zTemp = NULL;
   592         -    dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
          586  +    dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
          587  +                           FORMAT_MESSAGE_FROM_SYSTEM |
          588  +                           FORMAT_MESSAGE_IGNORE_INSERTS,
   593    589                              NULL,
   594         -                           error,
          590  +                           lastErrno,
   595    591                              0,
   596    592                              (LPSTR) &zTemp,
   597    593                              0,
   598    594                              0);
   599    595       if( dwLen > 0 ){
   600    596         /* allocate a buffer and convert to UTF8 */
   601    597         zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
   602    598         /* free the system buffer allocated by FormatMessage */
   603    599         LocalFree(zTemp);
   604    600       }
   605    601   #endif
   606    602     }
   607    603     if( 0 == dwLen ){
   608         -    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
          604  +    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno);
   609    605     }else{
   610    606       /* copy a maximum of nBuf chars to output buffer */
   611    607       sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
   612    608       /* free the UTF8 buffer */
   613    609       free(zOut);
   614    610     }
   615    611     return 0;
................................................................................
   626    622   ** FormatMessage.
   627    623   **
   628    624   ** The first argument passed to the macro should be the error code that
   629    625   ** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). 
   630    626   ** The two subsequent arguments should be the name of the OS function that
   631    627   ** failed and the the associated file-system path, if any.
   632    628   */
   633         -#define winLogError(a,b,c)     winLogErrorAtLine(a,b,c,__LINE__)
          629  +#define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
   634    630   static int winLogErrorAtLine(
   635    631     int errcode,                    /* SQLite error code */
          632  +  DWORD lastErrno,                /* Win32 last error */
   636    633     const char *zFunc,              /* Name of OS function that failed */
   637    634     const char *zPath,              /* File path associated with error */
   638    635     int iLine                       /* Source line number where error occurred */
   639    636   ){
   640    637     char zMsg[500];                 /* Human readable error text */
   641    638     int i;                          /* Loop counter */
   642         -  DWORD iErrno = GetLastError();  /* Error code */
   643    639   
   644    640     zMsg[0] = 0;
   645         -  getLastErrorMsg(sizeof(zMsg), zMsg);
          641  +  getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
   646    642     assert( errcode!=SQLITE_OK );
   647    643     if( zPath==0 ) zPath = "";
   648    644     for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
   649    645     zMsg[i] = 0;
   650    646     sqlite3_log(errcode,
   651    647         "os_win.c:%d: (%d) %s(%s) - %s",
   652         -      iLine, iErrno, zFunc, zPath, zMsg
          648  +      iLine, lastErrno, zFunc, zPath, zMsg
   653    649     );
   654    650   
   655    651     return errcode;
   656    652   }
   657    653   
   658    654   /*
   659    655   ** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
................................................................................
   776    772       if (*zTok == '\\') *zTok = '_';
   777    773     }
   778    774   
   779    775     /* Create/open the named mutex */
   780    776     pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
   781    777     if (!pFile->hMutex){
   782    778       pFile->lastErrno = GetLastError();
   783         -    winLogError(SQLITE_ERROR, "winceCreateLock1", zFilename);
          779  +    winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename);
   784    780       free(zName);
   785    781       return FALSE;
   786    782     }
   787    783   
   788    784     /* Acquire the mutex before continuing */
   789    785     winceMutexAcquire(pFile->hMutex);
   790    786     
................................................................................
   808    804     /* If we succeeded in making the shared memory handle, map it. */
   809    805     if (pFile->hShared){
   810    806       pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, 
   811    807                FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
   812    808       /* If mapping failed, close the shared memory handle and erase it */
   813    809       if (!pFile->shared){
   814    810         pFile->lastErrno = GetLastError();
   815         -      winLogError(SQLITE_ERROR, "winceCreateLock2", zFilename);
          811  +      winLogError(SQLITE_ERROR, pFile->lastErrno,
          812  +               "winceCreateLock2", zFilename);
   816    813         CloseHandle(pFile->hShared);
   817    814         pFile->hShared = NULL;
   818    815       }
   819    816     }
   820    817   
   821    818     /* If shared memory could not be created, then close the mutex and fail */
   822    819     if (pFile->hShared == NULL){
................................................................................
  1054   1051     ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine 
  1055   1052     ** whether an error has actually occured, it is also necessary to call 
  1056   1053     ** GetLastError().
  1057   1054     */
  1058   1055     dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
  1059   1056     if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
  1060   1057       pFile->lastErrno = GetLastError();
  1061         -    winLogError(SQLITE_IOERR_SEEK, "seekWinFile", pFile->zPath);
         1058  +    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
         1059  +             "seekWinFile", pFile->zPath);
  1062   1060       return 1;
  1063   1061     }
  1064   1062   
  1065   1063     return 0;
  1066   1064   }
  1067   1065   
  1068   1066   /*
................................................................................
  1101   1099       }
  1102   1100       free(pFile->zDeleteOnClose);
  1103   1101     }
  1104   1102   #endif
  1105   1103     OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
  1106   1104     OpenCounter(-1);
  1107   1105     return rc ? SQLITE_OK
  1108         -            : winLogError(SQLITE_IOERR_CLOSE, "winClose", pFile->zPath);
         1106  +            : winLogError(SQLITE_IOERR_CLOSE, GetLastError(),
         1107  +                          "winClose", pFile->zPath);
  1109   1108   }
  1110   1109   
  1111   1110   /*
  1112   1111   ** Read data from a file into a buffer.  Return SQLITE_OK if all
  1113   1112   ** bytes were read successfully and SQLITE_IOERR if anything goes
  1114   1113   ** wrong.
  1115   1114   */
................................................................................
  1129   1128   
  1130   1129     if( seekWinFile(pFile, offset) ){
  1131   1130       return SQLITE_FULL;
  1132   1131     }
  1133   1132     while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
  1134   1133       if( retryIoerr(&nRetry) ) continue;
  1135   1134       pFile->lastErrno = GetLastError();
  1136         -    return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath);
         1135  +    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
         1136  +             "winRead", pFile->zPath);
  1137   1137     }
  1138   1138     logIoerr(nRetry);
  1139   1139     if( nRead<(DWORD)amt ){
  1140   1140       /* Unread parts of the buffer must be zero-filled */
  1141   1141       memset(&((char*)pBuf)[nRead], 0, amt-nRead);
  1142   1142       return SQLITE_IOERR_SHORT_READ;
  1143   1143     }
................................................................................
  1188   1188     }
  1189   1189   
  1190   1190     if( rc ){
  1191   1191       if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
  1192   1192          || ( pFile->lastErrno==ERROR_DISK_FULL )){
  1193   1193         return SQLITE_FULL;
  1194   1194       }
  1195         -    return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath);
         1195  +    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
         1196  +             "winWrite", pFile->zPath);
  1196   1197     }else{
  1197   1198       logIoerr(nRetry);
  1198   1199     }
  1199   1200     return SQLITE_OK;
  1200   1201   }
  1201   1202   
  1202   1203   /*
................................................................................
  1218   1219     */
  1219   1220     if( pFile->szChunk>0 ){
  1220   1221       nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
  1221   1222     }
  1222   1223   
  1223   1224     /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
  1224   1225     if( seekWinFile(pFile, nByte) ){
  1225         -    rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath);
         1226  +    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
         1227  +             "winTruncate1", pFile->zPath);
  1226   1228     }else if( 0==SetEndOfFile(pFile->h) ){
  1227   1229       pFile->lastErrno = GetLastError();
  1228         -    rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate2", pFile->zPath);
         1230  +    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
         1231  +             "winTruncate2", pFile->zPath);
  1229   1232     }
  1230   1233   
  1231   1234     OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
  1232   1235     return rc;
  1233   1236   }
  1234   1237   
  1235   1238   #ifdef SQLITE_TEST
................................................................................
  1292   1295   #else
  1293   1296     rc = FlushFileBuffers(pFile->h);
  1294   1297     SimulateIOError( rc=FALSE );
  1295   1298     if( rc ){
  1296   1299       return SQLITE_OK;
  1297   1300     }else{
  1298   1301       pFile->lastErrno = GetLastError();
  1299         -    return winLogError(SQLITE_IOERR_FSYNC, "winSync", pFile->zPath);
         1302  +    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
         1303  +             "winSync", pFile->zPath);
  1300   1304     }
  1301   1305   #endif
  1302   1306   }
  1303   1307   
  1304   1308   /*
  1305   1309   ** Determine the current size of a file in bytes
  1306   1310   */
................................................................................
  1313   1317     assert( id!=0 );
  1314   1318     SimulateIOError(return SQLITE_IOERR_FSTAT);
  1315   1319     lowerBits = GetFileSize(pFile->h, &upperBits);
  1316   1320     if(   (lowerBits == INVALID_FILE_SIZE)
  1317   1321        && ((error = GetLastError()) != NO_ERROR) )
  1318   1322     {
  1319   1323       pFile->lastErrno = error;
  1320         -    return winLogError(SQLITE_IOERR_FSTAT, "winFileSize", pFile->zPath);
         1324  +    return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
         1325  +             "winFileSize", pFile->zPath);
  1321   1326     }
  1322   1327     *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
  1323   1328     return SQLITE_OK;
  1324   1329   }
  1325   1330   
  1326   1331   /*
  1327   1332   ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
................................................................................
  1373   1378   #if SQLITE_OS_WINCE==0
  1374   1379     }else{
  1375   1380       res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
  1376   1381   #endif
  1377   1382     }
  1378   1383     if( res==0 && GetLastError()!=ERROR_NOT_LOCKED ){
  1379   1384       pFile->lastErrno = GetLastError();
  1380         -    winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile->zPath);
         1385  +    winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
         1386  +             "unlockReadLock", pFile->zPath);
  1381   1387     }
  1382   1388     return res;
  1383   1389   }
  1384   1390   
  1385   1391   /*
  1386   1392   ** Lock the file with the lock specified by parameter locktype - one
  1387   1393   ** of the following:
................................................................................
  1441   1447     newLocktype = pFile->locktype;
  1442   1448     if(   (pFile->locktype==NO_LOCK)
  1443   1449        || (   (locktype==EXCLUSIVE_LOCK)
  1444   1450            && (pFile->locktype==RESERVED_LOCK))
  1445   1451     ){
  1446   1452       int cnt = 3;
  1447   1453       while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
  1448         -      /* Try 3 times to get the pending lock.  The pending lock might be
  1449         -      ** held by another reader process who will release it momentarily.
         1454  +      /* Try 3 times to get the pending lock.  This is needed to work
         1455  +      ** around problems caused by anti-virus software on windows system.
         1456  +      ** If you are using this code as a model for alternative VFSes, do not
         1457  +      ** copy this retry logic.  It is a hack intended for windows only.
  1450   1458         */
  1451   1459         OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt));
  1452         -      Sleep(1);
         1460  +      if( cnt ) Sleep(1);
  1453   1461       }
  1454   1462       gotPendingLock = res;
  1455   1463       if( !res ){
  1456   1464         error = GetLastError();
  1457   1465       }
  1458   1466     }
  1459   1467   
................................................................................
  1574   1582             pFile->locktype, pFile->sharedLockByte));
  1575   1583     type = pFile->locktype;
  1576   1584     if( type>=EXCLUSIVE_LOCK ){
  1577   1585       UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  1578   1586       if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
  1579   1587         /* This should never happen.  We should always be able to
  1580   1588         ** reacquire the read lock */
  1581         -      rc = winLogError(SQLITE_IOERR_UNLOCK, "winUnlock", pFile->zPath);
         1589  +      rc = winLogError(SQLITE_IOERR_UNLOCK, GetLastError(),
         1590  +               "winUnlock", pFile->zPath);
  1582   1591       }
  1583   1592     }
  1584   1593     if( type>=RESERVED_LOCK ){
  1585   1594       UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
  1586   1595     }
  1587   1596     if( locktype==NO_LOCK && type>=SHARED_LOCK ){
  1588   1597       unlockReadLock(pFile);
................................................................................
  1965   1974   
  1966   1975       /* Check to see if another process is holding the dead-man switch.
  1967   1976       ** If not, truncate the file to zero length. 
  1968   1977       */
  1969   1978       if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
  1970   1979         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
  1971   1980         if( rc!=SQLITE_OK ){
  1972         -        rc = winLogError(SQLITE_IOERR_SHMOPEN, "winOpenShm", pDbFd->zPath);
         1981  +        rc = winLogError(SQLITE_IOERR_SHMOPEN, GetLastError(),
         1982  +                 "winOpenShm", pDbFd->zPath);
  1973   1983         }
  1974   1984       }
  1975   1985       if( rc==SQLITE_OK ){
  1976   1986         winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
  1977   1987         rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
  1978   1988       }
  1979   1989       if( rc ) goto shm_open_err;
................................................................................
  2224   2234   
  2225   2235       /* The requested region is not mapped into this processes address space.
  2226   2236       ** Check to see if it has been allocated (i.e. if the wal-index file is
  2227   2237       ** large enough to contain the requested region).
  2228   2238       */
  2229   2239       rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
  2230   2240       if( rc!=SQLITE_OK ){
  2231         -      rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap1", pDbFd->zPath);
         2241  +      rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(),
         2242  +               "winShmMap1", pDbFd->zPath);
  2232   2243         goto shmpage_out;
  2233   2244       }
  2234   2245   
  2235   2246       if( sz<nByte ){
  2236   2247         /* The requested memory region does not exist. If isWrite is set to
  2237   2248         ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
  2238   2249         **
  2239   2250         ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
  2240   2251         ** the requested memory region.
  2241   2252         */
  2242   2253         if( !isWrite ) goto shmpage_out;
  2243   2254         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
  2244   2255         if( rc!=SQLITE_OK ){
  2245         -        rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap2", pDbFd->zPath);
         2256  +        rc = winLogError(SQLITE_IOERR_SHMSIZE, GetLastError(),
         2257  +                 "winShmMap2", pDbFd->zPath);
  2246   2258           goto shmpage_out;
  2247   2259         }
  2248   2260       }
  2249   2261   
  2250   2262       /* Map the requested memory region into this processes address space. */
  2251   2263       apNew = (struct ShmRegion *)sqlite3_realloc(
  2252   2264           pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
................................................................................
  2275   2287           );
  2276   2288           OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
  2277   2289                    (int)GetCurrentProcessId(), pShmNode->nRegion, iOffset, szRegion,
  2278   2290                    pMap ? "ok" : "failed"));
  2279   2291         }
  2280   2292         if( !pMap ){
  2281   2293           pShmNode->lastErrno = GetLastError();
  2282         -        rc = winLogError(SQLITE_IOERR_SHMMAP, "winShmMap3", pDbFd->zPath);
         2294  +        rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
         2295  +                 "winShmMap3", pDbFd->zPath);
  2283   2296           if( hMap ) CloseHandle(hMap);
  2284   2297           goto shmpage_out;
  2285   2298         }
  2286   2299   
  2287   2300         pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
  2288   2301         pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
  2289   2302         pShmNode->nRegion++;
................................................................................
  2609   2622   
  2610   2623     OSTRACE(("OPEN %d %s 0x%lx %s\n", 
  2611   2624              h, zName, dwDesiredAccess, 
  2612   2625              h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
  2613   2626   
  2614   2627     if( h==INVALID_HANDLE_VALUE ){
  2615   2628       pFile->lastErrno = GetLastError();
  2616         -    winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name);
         2629  +    winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
  2617   2630       free(zConverted);
  2618   2631       if( isReadWrite && !isExclusive ){
  2619   2632         return winOpen(pVfs, zName, id, 
  2620   2633                ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
  2621   2634       }else{
  2622   2635         return SQLITE_CANTOPEN_BKPT;
  2623   2636       }
................................................................................
  2702   2715       rc = 1;
  2703   2716       while( GetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES &&
  2704   2717              (rc = DeleteFileA(zConverted))==0 && retryIoerr(&cnt) ){}
  2705   2718       rc = rc ? SQLITE_OK : SQLITE_ERROR;
  2706   2719   #endif
  2707   2720     }
  2708   2721     if( rc ){
  2709         -    rc = winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename);
         2722  +    rc = winLogError(SQLITE_IOERR_DELETE, GetLastError(),
         2723  +             "winDelete", zFilename);
  2710   2724     }else{
  2711   2725       logIoerr(cnt);
  2712   2726     }
  2713   2727     free(zConverted);
  2714   2728     OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" )));
  2715   2729     return rc;
  2716   2730   }
................................................................................
  2749   2763             && sAttrData.nFileSizeHigh==0 
  2750   2764             && sAttrData.nFileSizeLow==0 ){
  2751   2765           attr = INVALID_FILE_ATTRIBUTES;
  2752   2766         }else{
  2753   2767           attr = sAttrData.dwFileAttributes;
  2754   2768         }
  2755   2769       }else{
         2770  +      DWORD lastErrno = GetLastError();
  2756   2771         logIoerr(cnt);
  2757         -      if( GetLastError()!=ERROR_FILE_NOT_FOUND ){
  2758         -        winLogError(SQLITE_IOERR_ACCESS, "winAccess", zFilename);
         2772  +      if( lastErrno!=ERROR_FILE_NOT_FOUND ){
         2773  +        winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
  2759   2774           free(zConverted);
  2760   2775           return SQLITE_IOERR_ACCESS;
  2761   2776         }else{
  2762   2777           attr = INVALID_FILE_ATTRIBUTES;
  2763   2778         }
  2764   2779       }
  2765   2780   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
................................................................................
  2975   2990   #endif
  2976   2991     }
  2977   2992     free(zConverted);
  2978   2993     return (void*)h;
  2979   2994   }
  2980   2995   static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
  2981   2996     UNUSED_PARAMETER(pVfs);
  2982         -  getLastErrorMsg(nBuf, zBufOut);
         2997  +  getLastErrorMsg(GetLastError(), nBuf, zBufOut);
  2983   2998   }
  2984   2999   static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
  2985   3000     UNUSED_PARAMETER(pVfs);
  2986   3001   #if SQLITE_OS_WINCE
  2987   3002     /* The GetProcAddressA() routine is only available on wince. */
  2988   3003     return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
  2989   3004   #else
................................................................................
  3149   3164   **
  3150   3165   ** However if an error message is supplied, it will be incorporated
  3151   3166   ** by sqlite into the error message available to the user using
  3152   3167   ** sqlite3_errmsg(), possibly making IO errors easier to debug.
  3153   3168   */
  3154   3169   static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
  3155   3170     UNUSED_PARAMETER(pVfs);
  3156         -  return getLastErrorMsg(nBuf, zBuf);
         3171  +  return getLastErrorMsg(GetLastError(), nBuf, zBuf);
  3157   3172   }
  3158   3173   
  3159   3174   
  3160   3175   
  3161   3176   /*
  3162   3177   ** Initialize and deinitialize the operating system interface.
  3163   3178   */