/ Check-in [fe603217]
Login

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

Overview
Comment:Add new extended error codes for I/O errors on seek and shared-memory map. Add sqlite3_log() calls in the windows backend to record details of errors.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fe603217fce8e3a696bd108d5ae7f7a291b7e215
User & Date: drh 2011-04-13 20:26:13
Context
2011-04-13
23:42
Remove extra CR and NL characters from FormatMessage() generated error messages in the windows VFS. check-in: 8332949c user: drh tags: trunk
20:26
Add new extended error codes for I/O errors on seek and shared-memory map. Add sqlite3_log() calls in the windows backend to record details of errors. check-in: fe603217 user: drh tags: trunk
16:52
Fix a usage comment typo in the showdb utility. check-in: 8744ced4 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

  3911   3911       while(pShmNode->nRegion<=iRegion){
  3912   3912         void *pMem;
  3913   3913         if( pShmNode->h>=0 ){
  3914   3914           pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, 
  3915   3915               MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
  3916   3916           );
  3917   3917           if( pMem==MAP_FAILED ){
  3918         -          rc = SQLITE_IOERR;
         3918  +          rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
  3919   3919             goto shmpage_out;
  3920   3920           }
  3921   3921         }else{
  3922   3922           pMem = sqlite3_malloc(szRegion);
  3923   3923           if( pMem==0 ){
  3924   3924             rc = SQLITE_NOMEM;
  3925   3925             goto shmpage_out;

Changes to src/os_win.c.

   113    113     WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */
   114    114     HANDLE hMutex;          /* Mutex used to control access to shared lock */  
   115    115     HANDLE hShared;         /* Shared memory segment used for locking */
   116    116     winceLock local;        /* Locks obtained by this instance of winFile */
   117    117     winceLock *shared;      /* Global shared lock memory for the file  */
   118    118   #endif
   119    119   };
          120  +
   120    121   
   121    122   /*
   122    123   ** Forward prototypes.
   123    124   */
   124    125   static int getSectorSize(
   125    126       sqlite3_vfs *pVfs,
   126    127       const char *zRelative     /* UTF-8 file name */
................................................................................
   294    295       return 0;
   295    296     }
   296    297     zFilenameMbcs = unicodeToMbcs(zTmpWide);
   297    298     free(zTmpWide);
   298    299     return zFilenameMbcs;
   299    300   }
   300    301   
          302  +
          303  +/*
          304  +** The return value of getLastErrorMsg
          305  +** is zero if the error message fits in the buffer, or non-zero
          306  +** otherwise (if the message was truncated).
          307  +*/
          308  +static int getLastErrorMsg(int nBuf, char *zBuf){
          309  +  /* FormatMessage returns 0 on failure.  Otherwise it
          310  +  ** returns the number of TCHARs written to the output
          311  +  ** buffer, excluding the terminating null char.
          312  +  */
          313  +  DWORD error = GetLastError();
          314  +  DWORD dwLen = 0;
          315  +  char *zOut = 0;
          316  +
          317  +  if( isNT() ){
          318  +    WCHAR *zTempWide = NULL;
          319  +    dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
          320  +                           NULL,
          321  +                           error,
          322  +                           0,
          323  +                           (LPWSTR) &zTempWide,
          324  +                           0,
          325  +                           0);
          326  +    if( dwLen > 0 ){
          327  +      /* allocate a buffer and convert to UTF8 */
          328  +      zOut = unicodeToUtf8(zTempWide);
          329  +      /* free the system buffer allocated by FormatMessage */
          330  +      LocalFree(zTempWide);
          331  +    }
          332  +/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
          333  +** Since the ASCII version of these Windows API do not exist for WINCE,
          334  +** it's important to not reference them for WINCE builds.
          335  +*/
          336  +#if SQLITE_OS_WINCE==0
          337  +  }else{
          338  +    char *zTemp = NULL;
          339  +    dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
          340  +                           NULL,
          341  +                           error,
          342  +                           0,
          343  +                           (LPSTR) &zTemp,
          344  +                           0,
          345  +                           0);
          346  +    if( dwLen > 0 ){
          347  +      /* allocate a buffer and convert to UTF8 */
          348  +      zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
          349  +      /* free the system buffer allocated by FormatMessage */
          350  +      LocalFree(zTemp);
          351  +    }
          352  +#endif
          353  +  }
          354  +  if( 0 == dwLen ){
          355  +    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
          356  +  }else{
          357  +    /* copy a maximum of nBuf chars to output buffer */
          358  +    sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
          359  +    /* free the UTF8 buffer */
          360  +    free(zOut);
          361  +  }
          362  +  return 0;
          363  +}
          364  +
          365  +/*
          366  +**
          367  +** This function - winLogErrorAtLine() - is only ever called via the macro
          368  +** winLogError().
          369  +**
          370  +** This routine is invoked after an error occurs in an OS function.
          371  +** It logs a message using sqlite3_log() containing the current value of
          372  +** error code and, if possible, the human-readable equivalent from 
          373  +** FormatMessage.
          374  +**
          375  +** The first argument passed to the macro should be the error code that
          376  +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). 
          377  +** The two subsequent arguments should be the name of the OS function that
          378  +** failed and the the associated file-system path, if any.
          379  +*/
          380  +#define winLogError(a,b,c)     winLogErrorAtLine(a,b,c,__LINE__)
          381  +static int winLogErrorAtLine(
          382  +  int errcode,                    /* SQLite error code */
          383  +  const char *zFunc,              /* Name of OS function that failed */
          384  +  const char *zPath,              /* File path associated with error */
          385  +  int iLine                       /* Source line number where error occurred */
          386  +){
          387  +  char zMsg[500];                 /* Human readable error text */
          388  +  DWORD iErrno = GetLastError();  /* Error code */
          389  +
          390  +  zMsg[0] = 0;
          391  +  getLastErrorMsg(sizeof(zMsg), zMsg);
          392  +  assert( errcode!=SQLITE_OK );
          393  +  if( zPath==0 ) zPath = "";
          394  +  sqlite3_log(errcode,
          395  +      "os_win.c:%d: (%d) %s(%s) - %s",
          396  +      iLine, iErrno, zFunc, zPath, zMsg
          397  +  );
          398  +
          399  +  return errcode;
          400  +}
          401  +
   301    402   #if SQLITE_OS_WINCE
   302    403   /*************************************************************************
   303    404   ** This section contains code for WinCE only.
   304    405   */
   305    406   /*
   306    407   ** WindowsCE does not have a localtime() function.  So create a
   307    408   ** substitute.
................................................................................
   371    472       if (*zTok == '\\') *zTok = '_';
   372    473     }
   373    474   
   374    475     /* Create/open the named mutex */
   375    476     pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
   376    477     if (!pFile->hMutex){
   377    478       pFile->lastErrno = GetLastError();
          479  +    winLogError(SQLITE_ERROR, "winceCreateLock1", zFilename);
   378    480       free(zName);
   379    481       return FALSE;
   380    482     }
   381    483   
   382    484     /* Acquire the mutex before continuing */
   383    485     winceMutexAcquire(pFile->hMutex);
   384    486     
................................................................................
   402    504     /* If we succeeded in making the shared memory handle, map it. */
   403    505     if (pFile->hShared){
   404    506       pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, 
   405    507                FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
   406    508       /* If mapping failed, close the shared memory handle and erase it */
   407    509       if (!pFile->shared){
   408    510         pFile->lastErrno = GetLastError();
          511  +      winLogError(SQLITE_ERROR, "winceCreateLock2", zFilename);
   409    512         CloseHandle(pFile->hShared);
   410    513         pFile->hShared = NULL;
   411    514       }
   412    515     }
   413    516   
   414    517     /* If shared memory could not be created, then close the mutex and fail */
   415    518     if (pFile->hShared == NULL){
................................................................................
   647    750     ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine 
   648    751     ** whether an error has actually occured, it is also necessary to call 
   649    752     ** GetLastError().
   650    753     */
   651    754     dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
   652    755     if( (dwRet==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR) ){
   653    756       pFile->lastErrno = GetLastError();
          757  +    winLogError(SQLITE_IOERR_SEEK, "seekWinFile", pFile->zPath);
   654    758       return 1;
   655    759     }
   656    760   
   657    761     return 0;
   658    762   }
   659    763   
   660    764   /*
................................................................................
   692    796          Sleep(100);  /* Wait a little before trying again */
   693    797       }
   694    798       free(pFile->zDeleteOnClose);
   695    799     }
   696    800   #endif
   697    801     OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
   698    802     OpenCounter(-1);
   699         -  return rc ? SQLITE_OK : SQLITE_IOERR;
          803  +  return rc ? SQLITE_OK
          804  +            : winLogError(SQLITE_IOERR_CLOSE, "winClose", pFile->zPath);
   700    805   }
   701    806   
   702    807   /*
   703    808   ** Read data from a file into a buffer.  Return SQLITE_OK if all
   704    809   ** bytes were read successfully and SQLITE_IOERR if anything goes
   705    810   ** wrong.
   706    811   */
................................................................................
   718    823     OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
   719    824   
   720    825     if( seekWinFile(pFile, offset) ){
   721    826       return SQLITE_FULL;
   722    827     }
   723    828     if( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
   724    829       pFile->lastErrno = GetLastError();
   725         -    return SQLITE_IOERR_READ;
          830  +    return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath);
   726    831     }
   727    832     if( nRead<(DWORD)amt ){
   728    833       /* Unread parts of the buffer must be zero-filled */
   729    834       memset(&((char*)pBuf)[nRead], 0, amt-nRead);
   730    835       return SQLITE_IOERR_SHORT_READ;
   731    836     }
   732    837   
................................................................................
   769    874       }
   770    875     }
   771    876   
   772    877     if( rc ){
   773    878       if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
   774    879         return SQLITE_FULL;
   775    880       }
   776         -    return SQLITE_IOERR_WRITE;
          881  +    return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath);
   777    882     }
   778    883     return SQLITE_OK;
   779    884   }
   780    885   
   781    886   /*
   782    887   ** Truncate an open file to a specified size
   783    888   */
................................................................................
   797    902     */
   798    903     if( pFile->szChunk ){
   799    904       nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
   800    905     }
   801    906   
   802    907     /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
   803    908     if( seekWinFile(pFile, nByte) ){
   804         -    rc = SQLITE_IOERR_TRUNCATE;
          909  +    rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath);
   805    910     }else if( 0==SetEndOfFile(pFile->h) ){
   806    911       pFile->lastErrno = GetLastError();
   807         -    rc = SQLITE_IOERR_TRUNCATE;
          912  +    rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate2", pFile->zPath);
   808    913     }
   809    914   
   810    915     OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
   811    916     return rc;
   812    917   }
   813    918   
   814    919   #ifdef SQLITE_TEST
................................................................................
   859    964   #ifdef SQLITE_NO_SYNC
   860    965     return SQLITE_OK;
   861    966   #else
   862    967     if( FlushFileBuffers(pFile->h) ){
   863    968       return SQLITE_OK;
   864    969     }else{
   865    970       pFile->lastErrno = GetLastError();
   866         -    return SQLITE_IOERR;
          971  +    return winLogError(SQLITE_IOERR_FSYNC, "winSync", pFile->zPath);
   867    972     }
   868    973   #endif
   869    974   }
   870    975   
   871    976   /*
   872    977   ** Determine the current size of a file in bytes
   873    978   */
................................................................................
   880    985     assert( id!=0 );
   881    986     SimulateIOError(return SQLITE_IOERR_FSTAT);
   882    987     lowerBits = GetFileSize(pFile->h, &upperBits);
   883    988     if(   (lowerBits == INVALID_FILE_SIZE)
   884    989        && ((error = GetLastError()) != NO_ERROR) )
   885    990     {
   886    991       pFile->lastErrno = error;
   887         -    return SQLITE_IOERR_FSTAT;
          992  +    return winLogError(SQLITE_IOERR_FSTAT, "winFileSize", pFile->zPath);
   888    993     }
   889    994     *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
   890    995     return SQLITE_OK;
   891    996   }
   892    997   
   893    998   /*
   894    999   ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
................................................................................
   919   1024       sqlite3_randomness(sizeof(lk), &lk);
   920   1025       pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
   921   1026       res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
   922   1027   #endif
   923   1028     }
   924   1029     if( res == 0 ){
   925   1030       pFile->lastErrno = GetLastError();
         1031  +    /* No need to log a failure to lock */
   926   1032     }
   927   1033     return res;
   928   1034   }
   929   1035   
   930   1036   /*
   931   1037   ** Undo a readlock
   932   1038   */
................................................................................
   939   1045   #if SQLITE_OS_WINCE==0
   940   1046     }else{
   941   1047       res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
   942   1048   #endif
   943   1049     }
   944   1050     if( res == 0 ){
   945   1051       pFile->lastErrno = GetLastError();
         1052  +    winLogError(SQLITE_IOERR_UNLOCK, "unlockReadLock", pFile->zPath);
   946   1053     }
   947   1054     return res;
   948   1055   }
   949   1056   
   950   1057   /*
   951   1058   ** Lock the file with the lock specified by parameter locktype - one
   952   1059   ** of the following:
................................................................................
  1139   1246             pFile->locktype, pFile->sharedLockByte));
  1140   1247     type = pFile->locktype;
  1141   1248     if( type>=EXCLUSIVE_LOCK ){
  1142   1249       UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  1143   1250       if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
  1144   1251         /* This should never happen.  We should always be able to
  1145   1252         ** reacquire the read lock */
  1146         -      rc = SQLITE_IOERR_UNLOCK;
         1253  +      rc = winLogError(SQLITE_IOERR_UNLOCK, "winUnlock", pFile->zPath);
  1147   1254       }
  1148   1255     }
  1149   1256     if( type>=RESERVED_LOCK ){
  1150   1257       UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
  1151   1258     }
  1152   1259     if( locktype==NO_LOCK && type>=SHARED_LOCK ){
  1153   1260       unlockReadLock(pFile);
................................................................................
  1496   1603   
  1497   1604       /* Check to see if another process is holding the dead-man switch.
  1498   1605       ** If not, truncate the file to zero length. 
  1499   1606       */
  1500   1607       if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
  1501   1608         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
  1502   1609         if( rc!=SQLITE_OK ){
  1503         -        rc = SQLITE_IOERR_SHMOPEN;
         1610  +        rc = winLogError(SQLITE_IOERR_SHMOPEN, "winOpenShm", pDbFd->zPath);
  1504   1611         }
  1505   1612       }
  1506   1613       if( rc==SQLITE_OK ){
  1507   1614         winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
  1508   1615         rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
  1509   1616       }
  1510   1617       if( rc ) goto shm_open_err;
................................................................................
  1755   1862   
  1756   1863       /* The requested region is not mapped into this processes address space.
  1757   1864       ** Check to see if it has been allocated (i.e. if the wal-index file is
  1758   1865       ** large enough to contain the requested region).
  1759   1866       */
  1760   1867       rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
  1761   1868       if( rc!=SQLITE_OK ){
  1762         -      rc = SQLITE_IOERR_SHMSIZE;
         1869  +      rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap1", pDbFd->zPath);
  1763   1870         goto shmpage_out;
  1764   1871       }
  1765   1872   
  1766   1873       if( sz<nByte ){
  1767   1874         /* The requested memory region does not exist. If isWrite is set to
  1768   1875         ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
  1769   1876         **
  1770   1877         ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
  1771   1878         ** the requested memory region.
  1772   1879         */
  1773   1880         if( !isWrite ) goto shmpage_out;
  1774   1881         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
  1775   1882         if( rc!=SQLITE_OK ){
  1776         -        rc = SQLITE_IOERR_SHMSIZE;
         1883  +        rc = winLogError(SQLITE_IOERR_SHMSIZE, "winShmMap2", pDbFd->zPath);
  1777   1884           goto shmpage_out;
  1778   1885         }
  1779   1886       }
  1780   1887   
  1781   1888       /* Map the requested memory region into this processes address space. */
  1782   1889       apNew = (struct ShmRegion *)sqlite3_realloc(
  1783   1890           pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
................................................................................
  1806   1913           );
  1807   1914           OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
  1808   1915                    (int)GetCurrentProcessId(), pShmNode->nRegion, iOffset, szRegion,
  1809   1916                    pMap ? "ok" : "failed"));
  1810   1917         }
  1811   1918         if( !pMap ){
  1812   1919           pShmNode->lastErrno = GetLastError();
  1813         -        rc = SQLITE_IOERR;
         1920  +        rc = winLogError(SQLITE_IOERR_SHMMAP, "winShmMap3", pDbFd->zPath);
  1814   1921           if( hMap ) CloseHandle(hMap);
  1815   1922           goto shmpage_out;
  1816   1923         }
  1817   1924   
  1818   1925         pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
  1819   1926         pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
  1820   1927         pShmNode->nRegion++;
................................................................................
  1968   2075     }
  1969   2076     zBuf[j] = 0;
  1970   2077   
  1971   2078     OSTRACE(("TEMP FILENAME: %s\n", zBuf));
  1972   2079     return SQLITE_OK; 
  1973   2080   }
  1974   2081   
  1975         -/*
  1976         -** The return value of getLastErrorMsg
  1977         -** is zero if the error message fits in the buffer, or non-zero
  1978         -** otherwise (if the message was truncated).
  1979         -*/
  1980         -static int getLastErrorMsg(int nBuf, char *zBuf){
  1981         -  /* FormatMessage returns 0 on failure.  Otherwise it
  1982         -  ** returns the number of TCHARs written to the output
  1983         -  ** buffer, excluding the terminating null char.
  1984         -  */
  1985         -  DWORD error = GetLastError();
  1986         -  DWORD dwLen = 0;
  1987         -  char *zOut = 0;
  1988         -
  1989         -  if( isNT() ){
  1990         -    WCHAR *zTempWide = NULL;
  1991         -    dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  1992         -                           NULL,
  1993         -                           error,
  1994         -                           0,
  1995         -                           (LPWSTR) &zTempWide,
  1996         -                           0,
  1997         -                           0);
  1998         -    if( dwLen > 0 ){
  1999         -      /* allocate a buffer and convert to UTF8 */
  2000         -      zOut = unicodeToUtf8(zTempWide);
  2001         -      /* free the system buffer allocated by FormatMessage */
  2002         -      LocalFree(zTempWide);
  2003         -    }
  2004         -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
  2005         -** Since the ASCII version of these Windows API do not exist for WINCE,
  2006         -** it's important to not reference them for WINCE builds.
  2007         -*/
  2008         -#if SQLITE_OS_WINCE==0
  2009         -  }else{
  2010         -    char *zTemp = NULL;
  2011         -    dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  2012         -                           NULL,
  2013         -                           error,
  2014         -                           0,
  2015         -                           (LPSTR) &zTemp,
  2016         -                           0,
  2017         -                           0);
  2018         -    if( dwLen > 0 ){
  2019         -      /* allocate a buffer and convert to UTF8 */
  2020         -      zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
  2021         -      /* free the system buffer allocated by FormatMessage */
  2022         -      LocalFree(zTemp);
  2023         -    }
  2024         -#endif
  2025         -  }
  2026         -  if( 0 == dwLen ){
  2027         -    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
  2028         -  }else{
  2029         -    /* copy a maximum of nBuf chars to output buffer */
  2030         -    sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
  2031         -    /* free the UTF8 buffer */
  2032         -    free(zOut);
  2033         -  }
  2034         -  return 0;
  2035         -}
  2036         -
  2037   2082   /*
  2038   2083   ** Open a file.
  2039   2084   */
  2040   2085   static int winOpen(
  2041   2086     sqlite3_vfs *pVfs,        /* Not used */
  2042   2087     const char *zName,        /* Name of the file (UTF-8) */
  2043   2088     sqlite3_file *id,         /* Write the SQLite file handle here */
................................................................................
  2201   2246   
  2202   2247     OSTRACE(("OPEN %d %s 0x%lx %s\n", 
  2203   2248              h, zName, dwDesiredAccess, 
  2204   2249              h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
  2205   2250   
  2206   2251     if( h==INVALID_HANDLE_VALUE ){
  2207   2252       pFile->lastErrno = GetLastError();
         2253  +    winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name);
  2208   2254       free(zConverted);
  2209   2255       if( isReadWrite ){
  2210   2256         return winOpen(pVfs, zName, id, 
  2211   2257                ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
  2212   2258       }else{
  2213   2259         return SQLITE_CANTOPEN_BKPT;
  2214   2260       }
................................................................................
  2304   2350     }
  2305   2351     free(zConverted);
  2306   2352     OSTRACE(("DELETE \"%s\" %s\n", zFilename,
  2307   2353          ( (rc==INVALID_FILE_ATTRIBUTES) && (error==ERROR_FILE_NOT_FOUND)) ?
  2308   2354            "ok" : "failed" ));
  2309   2355    
  2310   2356     return (   (rc == INVALID_FILE_ATTRIBUTES) 
  2311         -          && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
         2357  +          && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK :
         2358  +                 winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename);
  2312   2359   }
  2313   2360   
  2314   2361   /*
  2315   2362   ** Check the existance and status of a file.
  2316   2363   */
  2317   2364   static int winAccess(
  2318   2365     sqlite3_vfs *pVfs,         /* Not used on win32 */
................................................................................
  2344   2391             && sAttrData.nFileSizeLow==0 ){
  2345   2392           attr = INVALID_FILE_ATTRIBUTES;
  2346   2393         }else{
  2347   2394           attr = sAttrData.dwFileAttributes;
  2348   2395         }
  2349   2396       }else{
  2350   2397         if( GetLastError()!=ERROR_FILE_NOT_FOUND ){
         2398  +        winLogError(SQLITE_IOERR_ACCESS, "winAccess", zFilename);
  2351   2399           free(zConverted);
  2352   2400           return SQLITE_IOERR_ACCESS;
  2353   2401         }else{
  2354   2402           attr = INVALID_FILE_ATTRIBUTES;
  2355   2403         }
  2356   2404       }
  2357   2405   /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 

Changes to src/sqlite.h.in.

   443    443   #define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
   444    444   #define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
   445    445   #define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
   446    446   #define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
   447    447   #define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
   448    448   #define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
   449    449   #define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
          450  +#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
          451  +#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
   450    452   #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
   451    453   #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
   452    454   #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
   453    455   
   454    456   /*
   455    457   ** CAPI3REF: Flags For File Open Operations
   456    458   **