/ Check-in [c94933f1]
Login

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

Overview
Comment:Cleanup of the windows VFS, including added support for Cygwin, fixes for compiler warnings under unusual configurations, and improved diagnostic error messages.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c94933f13208f3f7d6d1b117ce6d2821100655a4
User & Date: drh 2013-08-31 18:36:14
Context
2013-09-02
07:16
Fix a problem with using stat4 data to estimate the number of rows scanned by a range constraint on the second or subsequent column of any index where an affinity transformation must be applied to the constraint argument. check-in: c21f58d8 user: dan tags: trunk
2013-09-01
23:36
Merge updates from trunk. check-in: 2982725e user: mistachkin tags: toTypeFuncs
2013-08-31
18:36
Cleanup of the windows VFS, including added support for Cygwin, fixes for compiler warnings under unusual configurations, and improved diagnostic error messages. check-in: c94933f1 user: drh tags: trunk
18:06
Revise the amalgamation tool to allow 'duplicate' include files to be retained manually while still preserving the existing line numbers. Closed-Leaf check-in: aa482846 user: mistachkin tags: cygwinTempPath
17:21
Fix a problem causing SQLite not to use stat4 or stat3 data to analyze constraints of the form "column = expr COLLATE collation" (those with an explicit COLLATE on the non-column side of the comparison operator). check-in: 1e86d81d user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

  1103   1103         case SQLITE_IOERR_SHMSIZE:      zName = "SQLITE_IOERR_SHMSIZE";     break;
  1104   1104         case SQLITE_IOERR_SHMLOCK:      zName = "SQLITE_IOERR_SHMLOCK";     break;
  1105   1105         case SQLITE_IOERR_SHMMAP:       zName = "SQLITE_IOERR_SHMMAP";      break;
  1106   1106         case SQLITE_IOERR_SEEK:         zName = "SQLITE_IOERR_SEEK";        break;
  1107   1107         case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
  1108   1108         case SQLITE_IOERR_MMAP:         zName = "SQLITE_IOERR_MMAP";        break;
  1109   1109         case SQLITE_IOERR_GETTEMPPATH:  zName = "SQLITE_IOERR_GETTEMPPATH"; break;
         1110  +      case SQLITE_IOERR_CONVPATH:     zName = "SQLITE_IOERR_CONVPATH";    break;
  1110   1111         case SQLITE_CORRUPT:            zName = "SQLITE_CORRUPT";           break;
  1111   1112         case SQLITE_CORRUPT_VTAB:       zName = "SQLITE_CORRUPT_VTAB";      break;
  1112   1113         case SQLITE_NOTFOUND:           zName = "SQLITE_NOTFOUND";          break;
  1113   1114         case SQLITE_FULL:               zName = "SQLITE_FULL";              break;
  1114   1115         case SQLITE_CANTOPEN:           zName = "SQLITE_CANTOPEN";          break;
  1115   1116         case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
  1116   1117         case SQLITE_CANTOPEN_ISDIR:     zName = "SQLITE_CANTOPEN_ISDIR";    break;
  1117   1118         case SQLITE_CANTOPEN_FULLPATH:  zName = "SQLITE_CANTOPEN_FULLPATH"; break;
         1119  +      case SQLITE_CANTOPEN_CONVPATH:  zName = "SQLITE_CANTOPEN_CONVPATH"; break;
  1118   1120         case SQLITE_PROTOCOL:           zName = "SQLITE_PROTOCOL";          break;
  1119   1121         case SQLITE_EMPTY:              zName = "SQLITE_EMPTY";             break;
  1120   1122         case SQLITE_SCHEMA:             zName = "SQLITE_SCHEMA";            break;
  1121   1123         case SQLITE_TOOBIG:             zName = "SQLITE_TOOBIG";            break;
  1122   1124         case SQLITE_CONSTRAINT:         zName = "SQLITE_CONSTRAINT";        break;
  1123   1125         case SQLITE_CONSTRAINT_UNIQUE:  zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
  1124   1126         case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break;

Changes to src/mem2.c.

   344    344     struct MemBlockHdr *pOldHdr;
   345    345     void *pNew;
   346    346     assert( mem.disallow==0 );
   347    347     assert( (nByte & 7)==0 );     /* EV: R-46199-30249 */
   348    348     pOldHdr = sqlite3MemsysGetHeader(pPrior);
   349    349     pNew = sqlite3MemMalloc(nByte);
   350    350     if( pNew ){
   351         -    memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
          351  +    memcpy(pNew, pPrior, (int)(nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize));
   352    352       if( nByte>pOldHdr->iSize ){
   353    353         randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize);
   354    354       }
   355    355       sqlite3MemFree(pPrior);
   356    356     }
   357    357     return pNew;
   358    358   }

Changes to src/os_unix.c.

  5335   5335   /*
  5336   5336   ** Return the name of a directory in which to put temporary files.
  5337   5337   ** If no suitable temporary file directory can be found, return NULL.
  5338   5338   */
  5339   5339   static const char *unixTempFileDir(void){
  5340   5340     static const char *azDirs[] = {
  5341   5341        0,
         5342  +     0,
  5342   5343        0,
  5343   5344        "/var/tmp",
  5344   5345        "/usr/tmp",
  5345   5346        "/tmp",
  5346   5347        0        /* List terminator */
  5347   5348     };
  5348   5349     unsigned int i;
  5349   5350     struct stat buf;
  5350   5351     const char *zDir = 0;
  5351   5352   
  5352   5353     azDirs[0] = sqlite3_temp_directory;
  5353         -  if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
         5354  +  if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR");
         5355  +  if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR");
  5354   5356     for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
  5355   5357       if( zDir==0 ) continue;
  5356   5358       if( osStat(zDir, &buf) ) continue;
  5357   5359       if( !S_ISDIR(buf.st_mode) ) continue;
  5358   5360       if( osAccess(zDir, 07) ) continue;
  5359   5361       break;
  5360   5362     }

Changes to src/os_win.c.

    13     13   ** This file contains code that is specific to Windows.
    14     14   */
    15     15   #include "sqliteInt.h"
    16     16   #if SQLITE_OS_WIN               /* This file is used for Windows only */
    17     17   
    18     18   #ifdef __CYGWIN__
    19     19   # include <sys/cygwin.h>
    20         -# include <errno.h>
           20  +# include <errno.h> /* amalgamator: keep */
    21     21   #endif
    22     22   
    23     23   /*
    24     24   ** Include code that is common to all os_*.c files
    25     25   */
    26     26   #include "os_common.h"
    27     27   
................................................................................
    34     34    with SQLITE_OMIT_WAL."
    35     35   #endif
    36     36   
    37     37   /*
    38     38   ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
    39     39   ** based on the sub-platform)?
    40     40   */
    41         -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
           41  +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI)
    42     42   #  define SQLITE_WIN32_HAS_ANSI
    43     43   #endif
    44     44   
    45     45   /*
    46     46   ** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
    47     47   ** based on the sub-platform)?
    48     48   */
    49         -#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
           49  +#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \
           50  +    !defined(SQLITE_WIN32_NO_WIDE)
    50     51   #  define SQLITE_WIN32_HAS_WIDE
    51     52   #endif
    52     53   
           54  +/*
           55  +** Make sure at least one set of Win32 APIs is available.
           56  +*/
           57  +#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE)
           58  +#  error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\
           59  + must be defined."
           60  +#endif
           61  +
    53     62   /*
    54     63   ** Maximum pathname length (in chars) for Win32.  This should normally be
    55     64   ** MAX_PATH.
    56     65   */
    57     66   #ifndef SQLITE_WIN32_MAX_PATH_CHARS
    58     67   #  define SQLITE_WIN32_MAX_PATH_CHARS   (MAX_PATH)
    59     68   #endif
................................................................................
   157    166   #endif
   158    167   
   159    168   #ifndef FILE_ATTRIBUTE_MASK
   160    169   # define FILE_ATTRIBUTE_MASK     (0x0003FFF7)
   161    170   #endif
   162    171   
   163    172   #ifndef SQLITE_OMIT_WAL
   164         -/* Forward references */
          173  +/* Forward references to structures used for WAL */
   165    174   typedef struct winShm winShm;           /* A connection to shared-memory */
   166    175   typedef struct winShmNode winShmNode;   /* A region of shared-memory */
   167    176   #endif
   168    177   
   169    178   /*
   170    179   ** WinCE lacks native support for file locking so we have to fake it
   171    180   ** with some code of our own.
................................................................................
  1112   1121   ** Here is an interesting observation:  Win95, Win98, and WinME lack
  1113   1122   ** the LockFileEx() API.  But we can still statically link against that
  1114   1123   ** API as long as we don't call it when running Win95/98/ME.  A call to
  1115   1124   ** this routine is used to determine if the host is Win95/98/ME or
  1116   1125   ** WinNT/2K/XP so that we will know whether or not we can safely call
  1117   1126   ** the LockFileEx() API.
  1118   1127   */
  1119         -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
         1128  +#if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
  1120   1129   # define osIsNT()  (1)
  1121   1130   #elif !defined(SQLITE_WIN32_HAS_WIDE)
  1122   1131   # define osIsNT()  (0)
  1123   1132   #else
  1124   1133     static int osIsNT(void){
  1125   1134       if( sqlite3_os_type==0 ){
  1126   1135         OSVERSIONINFOA sInfo;
................................................................................
  1757   1766       if (*zTok == '\\') *zTok = '_';
  1758   1767     }
  1759   1768   
  1760   1769     /* Create/open the named mutex */
  1761   1770     pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
  1762   1771     if (!pFile->hMutex){
  1763   1772       pFile->lastErrno = osGetLastError();
  1764         -    winLogError(SQLITE_IOERR, pFile->lastErrno,
  1765         -                "winceCreateLock1", zFilename);
  1766   1773       sqlite3_free(zName);
  1767         -    return SQLITE_IOERR;
         1774  +    return winLogError(SQLITE_IOERR, pFile->lastErrno,
         1775  +                       "winceCreateLock1", zFilename);
  1768   1776     }
  1769   1777   
  1770   1778     /* Acquire the mutex before continuing */
  1771   1779     winceMutexAcquire(pFile->hMutex);
  1772   1780     
  1773   1781     /* Since the names of named mutexes, semaphores, file mappings etc are 
  1774   1782     ** case-sensitive, take advantage of that by uppercasing the mutex name
................................................................................
  2096   2104     */
  2097   2105     dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
  2098   2106   
  2099   2107     if( (dwRet==INVALID_SET_FILE_POINTER
  2100   2108         && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
  2101   2109       pFile->lastErrno = lastErrno;
  2102   2110       winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
  2103         -             "winSeekFile", pFile->zPath);
         2111  +                "winSeekFile", pFile->zPath);
  2104   2112       OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
  2105   2113       return 1;
  2106   2114     }
  2107   2115   
  2108   2116     OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
  2109   2117     return 0;
  2110   2118   #else
................................................................................
  2117   2125   
  2118   2126     x.QuadPart = iOffset;
  2119   2127     bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
  2120   2128   
  2121   2129     if(!bRet){
  2122   2130       pFile->lastErrno = osGetLastError();
  2123   2131       winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
  2124         -             "winSeekFile", pFile->zPath);
         2132  +                "winSeekFile", pFile->zPath);
  2125   2133       OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
  2126   2134       return 1;
  2127   2135     }
  2128   2136   
  2129   2137     OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
  2130   2138     return 0;
  2131   2139   #endif
  2132   2140   }
  2133   2141   
  2134   2142   #if SQLITE_MAX_MMAP_SIZE>0
  2135         -/* Forward references to VFS methods */
         2143  +/* Forward references to VFS helper methods used for memory mapped files */
         2144  +static int winMapfile(winFile*, sqlite3_int64);
  2136   2145   static int winUnmapfile(winFile*);
  2137   2146   #endif
  2138   2147   
  2139   2148   /*
  2140   2149   ** Close a file.
  2141   2150   **
  2142   2151   ** It is reported that an attempt to close a handle might sometimes
................................................................................
  2249   2258            osGetLastError()!=ERROR_HANDLE_EOF ){
  2250   2259   #endif
  2251   2260       DWORD lastErrno;
  2252   2261       if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
  2253   2262       pFile->lastErrno = lastErrno;
  2254   2263       OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h));
  2255   2264       return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
  2256         -             "winRead", pFile->zPath);
         2265  +                       "winRead", pFile->zPath);
  2257   2266     }
  2258   2267     winLogIoerr(nRetry);
  2259   2268     if( nRead<(DWORD)amt ){
  2260   2269       /* Unread parts of the buffer must be zero-filled */
  2261   2270       memset(&((char*)pBuf)[nRead], 0, amt-nRead);
  2262   2271       OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h));
  2263   2272       return SQLITE_IOERR_SHORT_READ;
................................................................................
  2355   2364       }
  2356   2365     }
  2357   2366   
  2358   2367     if( rc ){
  2359   2368       if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
  2360   2369          || ( pFile->lastErrno==ERROR_DISK_FULL )){
  2361   2370         OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h));
  2362         -      return SQLITE_FULL;
         2371  +      return winLogError(SQLITE_FULL, pFile->lastErrno,
         2372  +                         "winWrite1", pFile->zPath);
  2363   2373       }
  2364   2374       OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h));
  2365   2375       return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
  2366         -             "winWrite", pFile->zPath);
         2376  +                       "winWrite2", pFile->zPath);
  2367   2377     }else{
  2368   2378       winLogIoerr(nRetry);
  2369   2379     }
  2370   2380     OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h));
  2371   2381     return SQLITE_OK;
  2372   2382   }
  2373   2383   
................................................................................
  2483   2493     if( rc ){
  2484   2494       OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h));
  2485   2495       return SQLITE_OK;
  2486   2496     }else{
  2487   2497       pFile->lastErrno = osGetLastError();
  2488   2498       OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h));
  2489   2499       return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
  2490         -             "winSync", pFile->zPath);
         2500  +                       "winSync", pFile->zPath);
  2491   2501     }
  2492   2502   #endif
  2493   2503   }
  2494   2504   
  2495   2505   /*
  2496   2506   ** Determine the current size of a file in bytes
  2497   2507   */
................................................................................
  2524   2534   
  2525   2535       lowerBits = osGetFileSize(pFile->h, &upperBits);
  2526   2536       *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
  2527   2537       if(   (lowerBits == INVALID_FILE_SIZE)
  2528   2538          && ((lastErrno = osGetLastError())!=NO_ERROR) ){
  2529   2539         pFile->lastErrno = lastErrno;
  2530   2540         rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
  2531         -             "winFileSize", pFile->zPath);
         2541  +                       "winFileSize", pFile->zPath);
  2532   2542       }
  2533   2543     }
  2534   2544   #endif
  2535   2545     OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
  2536   2546              pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
  2537   2547     return rc;
  2538   2548   }
................................................................................
  2619   2629     else{
  2620   2630       res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
  2621   2631     }
  2622   2632   #endif
  2623   2633     if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
  2624   2634       pFile->lastErrno = lastErrno;
  2625   2635       winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
  2626         -             "winUnlockReadLock", pFile->zPath);
         2636  +                "winUnlockReadLock", pFile->zPath);
  2627   2637     }
  2628   2638     OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
  2629   2639     return res;
  2630   2640   }
  2631   2641   
  2632   2642   /*
  2633   2643   ** Lock the file with the lock specified by parameter locktype - one
................................................................................
  2832   2842     type = pFile->locktype;
  2833   2843     if( type>=EXCLUSIVE_LOCK ){
  2834   2844       winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  2835   2845       if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
  2836   2846         /* This should never happen.  We should always be able to
  2837   2847         ** reacquire the read lock */
  2838   2848         rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
  2839         -               "winUnlock", pFile->zPath);
         2849  +                       "winUnlock", pFile->zPath);
  2840   2850       }
  2841   2851     }
  2842   2852     if( type>=RESERVED_LOCK ){
  2843   2853       winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
  2844   2854     }
  2845   2855     if( locktype==NO_LOCK && type>=SHARED_LOCK ){
  2846   2856       winUnlockReadLock(pFile);
................................................................................
  2866   2876     }else if( (*pArg)==0 ){
  2867   2877       pFile->ctrlFlags &= ~mask;
  2868   2878     }else{
  2869   2879       pFile->ctrlFlags |= mask;
  2870   2880     }
  2871   2881   }
  2872   2882   
  2873         -/* Forward declaration */
         2883  +/* Forward references to VFS helper methods used for temporary files */
  2874   2884   static int winGetTempname(sqlite3_vfs *, char **);
  2875         -#if SQLITE_MAX_MMAP_SIZE>0
  2876         -static int winMapfile(winFile*, sqlite3_int64);
  2877         -#endif
         2885  +static int winIsDir(const void *);
         2886  +static BOOL winIsDriveLetterAndColon(const char *);
  2878   2887   
  2879   2888   /*
  2880   2889   ** Control and query of the open file handle.
  2881   2890   */
  2882   2891   static int winFileControl(sqlite3_file *id, int op, void *pArg){
  2883   2892     winFile *pFile = (winFile*)id;
  2884   2893     OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
................................................................................
  2948   2957       }
  2949   2958       case SQLITE_FCNTL_TEMPFILENAME: {
  2950   2959         char *zTFile = 0;
  2951   2960         int rc = winGetTempname(pFile->pVfs, &zTFile);
  2952   2961         if( rc==SQLITE_OK ){
  2953   2962           *(char**)pArg = zTFile;
  2954   2963         }
  2955         -      OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc));
         2964  +      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
  2956   2965         return rc;
  2957   2966       }
  2958   2967   #if SQLITE_MAX_MMAP_SIZE>0
  2959   2968       case SQLITE_FCNTL_MMAP_SIZE: {
  2960   2969         i64 newLimit = *(i64*)pArg;
  2961   2970         int rc = SQLITE_OK;
  2962   2971         if( newLimit>sqlite3GlobalConfig.mxMmap ){
................................................................................
  2966   2975         if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
  2967   2976           pFile->mmapSizeMax = newLimit;
  2968   2977           if( pFile->mmapSize>0 ){
  2969   2978             (void)winUnmapfile(pFile);
  2970   2979             rc = winMapfile(pFile, -1);
  2971   2980           }
  2972   2981         }
  2973         -      OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc));
         2982  +      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
  2974   2983         return rc;
  2975   2984       }
  2976   2985   #endif
  2977   2986     }
  2978   2987     OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
  2979   2988     return SQLITE_NOTFOUND;
  2980   2989   }
................................................................................
  3282   3291       /* Check to see if another process is holding the dead-man switch.
  3283   3292       ** If not, truncate the file to zero length. 
  3284   3293       */
  3285   3294       if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
  3286   3295         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
  3287   3296         if( rc!=SQLITE_OK ){
  3288   3297           rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
  3289         -                 "winOpenShm", pDbFd->zPath);
         3298  +                         "winOpenShm", pDbFd->zPath);
  3290   3299         }
  3291   3300       }
  3292   3301       if( rc==SQLITE_OK ){
  3293   3302         winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
  3294   3303         rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
  3295   3304       }
  3296   3305       if( rc ) goto shm_open_err;
................................................................................
  3542   3551       /* The requested region is not mapped into this processes address space.
  3543   3552       ** Check to see if it has been allocated (i.e. if the wal-index file is
  3544   3553       ** large enough to contain the requested region).
  3545   3554       */
  3546   3555       rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
  3547   3556       if( rc!=SQLITE_OK ){
  3548   3557         rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
  3549         -               "winShmMap1", pDbFd->zPath);
         3558  +                       "winShmMap1", pDbFd->zPath);
  3550   3559         goto shmpage_out;
  3551   3560       }
  3552   3561   
  3553   3562       if( sz<nByte ){
  3554   3563         /* The requested memory region does not exist. If isWrite is set to
  3555   3564         ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
  3556   3565         **
................................................................................
  3557   3566         ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
  3558   3567         ** the requested memory region.
  3559   3568         */
  3560   3569         if( !isWrite ) goto shmpage_out;
  3561   3570         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
  3562   3571         if( rc!=SQLITE_OK ){
  3563   3572           rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
  3564         -                 "winShmMap2", pDbFd->zPath);
         3573  +                         "winShmMap2", pDbFd->zPath);
  3565   3574           goto shmpage_out;
  3566   3575         }
  3567   3576       }
  3568   3577   
  3569   3578       /* Map the requested memory region into this processes address space. */
  3570   3579       apNew = (struct ShmRegion *)sqlite3_realloc(
  3571   3580           pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
................................................................................
  3611   3620           OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
  3612   3621                    osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
  3613   3622                    szRegion, pMap ? "ok" : "failed"));
  3614   3623         }
  3615   3624         if( !pMap ){
  3616   3625           pShmNode->lastErrno = osGetLastError();
  3617   3626           rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
  3618         -                 "winShmMap3", pDbFd->zPath);
         3627  +                         "winShmMap3", pDbFd->zPath);
  3619   3628           if( hMap ) osCloseHandle(hMap);
  3620   3629           goto shmpage_out;
  3621   3630         }
  3622   3631   
  3623   3632         pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
  3624   3633         pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
  3625   3634         pShmNode->nRegion++;
................................................................................
  3659   3668     if( pFile->pMapRegion ){
  3660   3669       if( !osUnmapViewOfFile(pFile->pMapRegion) ){
  3661   3670         pFile->lastErrno = osGetLastError();
  3662   3671         OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
  3663   3672                  "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
  3664   3673                  pFile->pMapRegion));
  3665   3674         return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
  3666         -                         "winUnmap1", pFile->zPath);
         3675  +                         "winUnmapfile1", pFile->zPath);
  3667   3676       }
  3668   3677       pFile->pMapRegion = 0;
  3669   3678       pFile->mmapSize = 0;
  3670   3679       pFile->mmapSizeActual = 0;
  3671   3680     }
  3672   3681     if( pFile->hMap!=NULL ){
  3673   3682       if( !osCloseHandle(pFile->hMap) ){
  3674   3683         pFile->lastErrno = osGetLastError();
  3675   3684         OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
  3676   3685                  osGetCurrentProcessId(), pFile, pFile->hMap));
  3677   3686         return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
  3678         -                         "winUnmap2", pFile->zPath);
         3687  +                         "winUnmapfile2", pFile->zPath);
  3679   3688       }
  3680   3689       pFile->hMap = NULL;
  3681   3690     }
  3682   3691     OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
  3683   3692              osGetCurrentProcessId(), pFile));
  3684   3693     return SQLITE_OK;
  3685   3694   }
................................................................................
  3746   3755       pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
  3747   3756                                   (DWORD)((nMap>>32) & 0xffffffff),
  3748   3757                                   (DWORD)(nMap & 0xffffffff), NULL);
  3749   3758   #endif
  3750   3759       if( pFd->hMap==NULL ){
  3751   3760         pFd->lastErrno = osGetLastError();
  3752   3761         rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
  3753         -                       "winMapfile", pFd->zPath);
         3762  +                       "winMapfile1", pFd->zPath);
  3754   3763         /* Log the error, but continue normal operation using xRead/xWrite */
  3755         -      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
  3756         -               osGetCurrentProcessId(), pFd));
         3764  +      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
         3765  +               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
  3757   3766         return SQLITE_OK;
  3758   3767       }
  3759   3768       assert( (nMap % winSysInfo.dwPageSize)==0 );
  3760   3769       assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
  3761   3770   #if SQLITE_OS_WINRT
  3762   3771       pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
  3763   3772   #else
  3764   3773       pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
  3765   3774   #endif
  3766   3775       if( pNew==NULL ){
  3767   3776         osCloseHandle(pFd->hMap);
  3768   3777         pFd->hMap = NULL;
  3769   3778         pFd->lastErrno = osGetLastError();
  3770         -      winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
  3771         -                  "winMapfile", pFd->zPath);
  3772         -      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
  3773         -               osGetCurrentProcessId(), pFd));
         3779  +      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
         3780  +                       "winMapfile2", pFd->zPath);
         3781  +      /* Log the error, but continue normal operation using xRead/xWrite */
         3782  +      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
         3783  +               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
  3774   3784         return SQLITE_OK;
  3775   3785       }
  3776   3786       pFd->pMapRegion = pNew;
  3777   3787       pFd->mmapSize = nMap;
  3778   3788       pFd->mmapSizeActual = nMap;
  3779   3789     }
  3780   3790   
................................................................................
  3904   3914   
  3905   3915   /****************************************************************************
  3906   3916   **************************** sqlite3_vfs methods ****************************
  3907   3917   **
  3908   3918   ** This division contains the implementation of methods on the
  3909   3919   ** sqlite3_vfs object.
  3910   3920   */
         3921  +
         3922  +/*
         3923  +** Convert a filename from whatever the underlying operating system
         3924  +** supports for filenames into UTF-8.  Space to hold the result is
         3925  +** obtained from malloc and must be freed by the calling function.
         3926  +*/
         3927  +static char *winConvertToUtf8Filename(const void *zFilename){
         3928  +  char *zConverted = 0;
         3929  +  if( osIsNT() ){
         3930  +    zConverted = winUnicodeToUtf8(zFilename);
         3931  +  }
         3932  +#ifdef SQLITE_WIN32_HAS_ANSI
         3933  +  else{
         3934  +    zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
         3935  +  }
         3936  +#endif
         3937  +  /* caller will handle out of memory */
         3938  +  return zConverted;
         3939  +}
  3911   3940   
  3912   3941   /*
  3913   3942   ** Convert a UTF-8 filename into whatever form the underlying
  3914   3943   ** operating system wants filenames in.  Space to hold the result
  3915   3944   ** is obtained from malloc and must be freed by the calling
  3916   3945   ** function.
  3917   3946   */
  3918         -static void *winConvertUtf8Filename(const char *zFilename){
         3947  +static void *winConvertFromUtf8Filename(const char *zFilename){
  3919   3948     void *zConverted = 0;
  3920   3949     if( osIsNT() ){
  3921   3950       zConverted = winUtf8ToUnicode(zFilename);
  3922   3951     }
  3923   3952   #ifdef SQLITE_WIN32_HAS_ANSI
  3924   3953     else{
  3925   3954       zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
................................................................................
  3976   4005     */
  3977   4006     assert( nBuf>30 );
  3978   4007     if( sqlite3_temp_directory ){
  3979   4008       sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory,
  3980   4009                        winEndsInDirSep(sqlite3_temp_directory) ? "" :
  3981   4010                        winGetDirDep());
  3982   4011     }
  3983         -#if !SQLITE_OS_WINRT
         4012  +#if defined(__CYGWIN__)
         4013  +  else{
         4014  +    static const char *azDirs[] = {
         4015  +       0, /* getenv("SQLITE_TMPDIR") */
         4016  +       0, /* getenv("TMPDIR") */
         4017  +       0, /* getenv("TMP") */
         4018  +       0, /* getenv("TEMP") */
         4019  +       0, /* getenv("USERPROFILE") */
         4020  +       "/var/tmp",
         4021  +       "/usr/tmp",
         4022  +       "/tmp",
         4023  +       ".",
         4024  +       0        /* List terminator */
         4025  +    };
         4026  +    unsigned int i;
         4027  +    const char *zDir = 0;
         4028  +
         4029  +    if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
         4030  +    if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
         4031  +    if( !azDirs[2] ) azDirs[2] = getenv("TMP");
         4032  +    if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
         4033  +    if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
         4034  +    for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
         4035  +      void *zConverted;
         4036  +      if( zDir==0 ) continue;
         4037  +      /* If the path starts with a drive letter followed by the colon
         4038  +      ** character, assume it is already a native Win32 path; otherwise,
         4039  +      ** it must be converted to a native Win32 path prior via the Cygwin
         4040  +      ** API prior to using it.
         4041  +      */
         4042  +      if( winIsDriveLetterAndColon(zDir) ){
         4043  +        zConverted = winConvertFromUtf8Filename(zDir);
         4044  +        if( !zConverted ){
         4045  +          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
         4046  +          return SQLITE_IOERR_NOMEM;
         4047  +        }
         4048  +        if( winIsDir(zConverted) ){
         4049  +          sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir);
         4050  +          sqlite3_free(zConverted);
         4051  +          break;
         4052  +        }
         4053  +        sqlite3_free(zConverted);
         4054  +      }else{
         4055  +        zConverted = sqlite3MallocZero( nBuf+1 );
         4056  +        if( !zConverted ){
         4057  +          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
         4058  +          return SQLITE_IOERR_NOMEM;
         4059  +        }
         4060  +        if( cygwin_conv_path(
         4061  +                osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
         4062  +                zConverted, nBuf+1)<0 ){
         4063  +          sqlite3_free(zConverted);
         4064  +          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
         4065  +          return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
         4066  +                             "winGetTempname1", zDir);
         4067  +        }
         4068  +        if( winIsDir(zConverted) ){
         4069  +          /* At this point, we know the candidate directory exists and should
         4070  +          ** be used.  However, we may need to convert the string containing
         4071  +          ** its name into UTF-8 (i.e. if it is UTF-16 right now).
         4072  +          */
         4073  +          if( osIsNT() ){
         4074  +            char *zUtf8 = winUnicodeToUtf8(zConverted);
         4075  +            if( !zUtf8 ){
         4076  +              sqlite3_free(zConverted);
         4077  +              OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
         4078  +              return SQLITE_IOERR_NOMEM;
         4079  +            }
         4080  +            sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
         4081  +            sqlite3_free(zUtf8);
         4082  +            sqlite3_free(zConverted);
         4083  +            break;
         4084  +          }else{
         4085  +            sqlite3_snprintf(nBuf-30, zBuf, "%s", zConverted);
         4086  +            sqlite3_free(zConverted);
         4087  +            break;
         4088  +          }
         4089  +        }
         4090  +        sqlite3_free(zConverted);
         4091  +      }
         4092  +      break;
         4093  +    }
         4094  +  }
         4095  +#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
  3984   4096     else if( osIsNT() ){
  3985   4097       char *zMulti;
  3986   4098       LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) );
  3987   4099       if( !zWidePath ){
  3988   4100         sqlite3_free(zBuf);
  3989   4101         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  3990   4102         return SQLITE_IOERR_NOMEM;
  3991   4103       }
  3992   4104       if( osGetTempPathW(nBuf, zWidePath)==0 ){
  3993   4105         sqlite3_free(zWidePath);
  3994   4106         sqlite3_free(zBuf);
  3995   4107         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
  3996         -      return SQLITE_IOERR_GETTEMPPATH;
         4108  +      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
         4109  +                         "winGetTempname1", 0);
  3997   4110       }
  3998   4111       zMulti = winUnicodeToUtf8(zWidePath);
  3999   4112       if( zMulti ){
  4000   4113         sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti);
  4001   4114         sqlite3_free(zMulti);
  4002   4115         sqlite3_free(zWidePath);
  4003   4116       }else{
................................................................................
  4015   4128         sqlite3_free(zBuf);
  4016   4129         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4017   4130         return SQLITE_IOERR_NOMEM;
  4018   4131       }
  4019   4132       if( osGetTempPathA(nBuf, zMbcsPath)==0 ){
  4020   4133         sqlite3_free(zBuf);
  4021   4134         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
  4022         -      return SQLITE_IOERR_GETTEMPPATH;
         4135  +      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
         4136  +                         "winGetTempname2", 0);
  4023   4137       }
  4024   4138       zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
  4025   4139       if( zUtf8 ){
  4026   4140         sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
  4027   4141         sqlite3_free(zUtf8);
  4028   4142       }else{
  4029   4143         sqlite3_free(zBuf);
................................................................................
  4038   4152     ** name. If it is not, return SQLITE_ERROR.
  4039   4153     */
  4040   4154     nLen = sqlite3Strlen30(zBuf);
  4041   4155   
  4042   4156     if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
  4043   4157       sqlite3_free(zBuf);
  4044   4158       OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
  4045         -    return SQLITE_ERROR;
         4159  +    return winLogError(SQLITE_ERROR, 0, "winGetTempname3", 0);
  4046   4160     }
  4047   4161   
  4048   4162     sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
  4049   4163   
  4050   4164     j = sqlite3Strlen30(zBuf);
  4051   4165     sqlite3_randomness(15, &zBuf[j]);
  4052   4166     for(i=0; i<15; i++, j++){
................................................................................
  4194   4308     ** URIs with parameters.  Hence, they can always be passed into
  4195   4309     ** sqlite3_uri_parameter().
  4196   4310     */
  4197   4311     assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
  4198   4312          zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
  4199   4313   
  4200   4314     /* Convert the filename to the system encoding. */
  4201         -  zConverted = winConvertUtf8Filename(zUtf8Name);
         4315  +  zConverted = winConvertFromUtf8Filename(zUtf8Name);
  4202   4316     if( zConverted==0 ){
  4203   4317       sqlite3_free(zTmpname);
  4204   4318       OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
  4205   4319       return SQLITE_IOERR_NOMEM;
  4206   4320     }
  4207   4321   
  4208   4322     if( winIsDir(zConverted) ){
................................................................................
  4395   4509     void *zConverted;
  4396   4510     UNUSED_PARAMETER(pVfs);
  4397   4511     UNUSED_PARAMETER(syncDir);
  4398   4512   
  4399   4513     SimulateIOError(return SQLITE_IOERR_DELETE);
  4400   4514     OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
  4401   4515   
  4402         -  zConverted = winConvertUtf8Filename(zFilename);
         4516  +  zConverted = winConvertFromUtf8Filename(zFilename);
  4403   4517     if( zConverted==0 ){
  4404   4518       OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
  4405   4519       return SQLITE_IOERR_NOMEM;
  4406   4520     }
  4407   4521     if( osIsNT() ){
  4408   4522       do {
  4409   4523   #if SQLITE_OS_WINRT
................................................................................
  4475   4589           rc = SQLITE_ERROR; /* No more retries. */
  4476   4590           break;
  4477   4591         }
  4478   4592       } while(1);
  4479   4593     }
  4480   4594   #endif
  4481   4595     if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
  4482         -    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
  4483         -             "winDelete", zFilename);
         4596  +    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
  4484   4597     }else{
  4485   4598       winLogIoerr(cnt);
  4486   4599     }
  4487   4600     sqlite3_free(zConverted);
  4488   4601     OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
  4489   4602     return rc;
  4490   4603   }
................................................................................
  4504   4617     void *zConverted;
  4505   4618     UNUSED_PARAMETER(pVfs);
  4506   4619   
  4507   4620     SimulateIOError( return SQLITE_IOERR_ACCESS; );
  4508   4621     OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
  4509   4622              zFilename, flags, pResOut));
  4510   4623   
  4511         -  zConverted = winConvertUtf8Filename(zFilename);
         4624  +  zConverted = winConvertFromUtf8Filename(zFilename);
  4512   4625     if( zConverted==0 ){
  4513   4626       OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
  4514   4627       return SQLITE_IOERR_NOMEM;
  4515   4628     }
  4516   4629     if( osIsNT() ){
  4517   4630       int cnt = 0;
  4518   4631       WIN32_FILE_ATTRIBUTE_DATA sAttrData;
................................................................................
  4530   4643           attr = INVALID_FILE_ATTRIBUTES;
  4531   4644         }else{
  4532   4645           attr = sAttrData.dwFileAttributes;
  4533   4646         }
  4534   4647       }else{
  4535   4648         winLogIoerr(cnt);
  4536   4649         if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
  4537         -        winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
  4538   4650           sqlite3_free(zConverted);
  4539         -        return SQLITE_IOERR_ACCESS;
         4651  +        return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
         4652  +                           zFilename);
  4540   4653         }else{
  4541   4654           attr = INVALID_FILE_ATTRIBUTES;
  4542   4655         }
  4543   4656       }
  4544   4657     }
  4545   4658   #ifdef SQLITE_WIN32_HAS_ANSI
  4546   4659     else{
................................................................................
  4562   4675     }
  4563   4676     *pResOut = rc;
  4564   4677     OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
  4565   4678              zFilename, pResOut, *pResOut));
  4566   4679     return SQLITE_OK;
  4567   4680   }
  4568   4681   
         4682  +/*
         4683  +** Returns non-zero if the specified path name starts with a drive letter
         4684  +** followed by a colon character.
         4685  +*/
         4686  +static BOOL winIsDriveLetterAndColon(
         4687  +  const char *zPathname
         4688  +){
         4689  +  return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
         4690  +}
  4569   4691   
  4570   4692   /*
  4571   4693   ** Returns non-zero if the specified path name should be used verbatim.  If
  4572   4694   ** non-zero is returned from this function, the calling function must simply
  4573   4695   ** use the provided path name verbatim -OR- resolve it into a full path name
  4574   4696   ** using the GetFullPathName Win32 API function (if available).
  4575   4697   */
................................................................................
  4589   4711   
  4590   4712     /*
  4591   4713     ** If the path name starts with a letter and a colon it is either a volume
  4592   4714     ** relative path or an absolute path.  Callers of this function must not
  4593   4715     ** attempt to treat it as a relative path name (i.e. they should simply use
  4594   4716     ** it verbatim).
  4595   4717     */
  4596         -  if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
         4718  +  if ( winIsDriveLetterAndColon(zPathname) ){
  4597   4719       return TRUE;
  4598   4720     }
  4599   4721   
  4600   4722     /*
  4601   4723     ** If we get to this point, the path name should almost certainly be a purely
  4602   4724     ** relative one (i.e. not a UNC name, not absolute, and not volume relative).
  4603   4725     */
................................................................................
  4625   4747       ** NOTE: We are dealing with a relative path name and the data
  4626   4748       **       directory has been set.  Therefore, use it as the basis
  4627   4749       **       for converting the relative path name to an absolute
  4628   4750       **       one by prepending the data directory and a slash.
  4629   4751       */
  4630   4752       char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
  4631   4753       if( !zOut ){
  4632         -      winLogError(SQLITE_IOERR_NOMEM, 0, "winFullPathname", zRelative);
  4633   4754         return SQLITE_IOERR_NOMEM;
  4634   4755       }
  4635   4756       if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
  4636   4757                            pVfs->mxPathname+1)<0 ){
  4637         -      winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
  4638         -                  zRelative);
  4639   4758         sqlite3_free(zOut);
  4640         -      return SQLITE_CANTOPEN_FULLPATH;
         4759  +      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
         4760  +                         "winFullPathname1", zRelative);
  4641   4761       }
  4642   4762       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
  4643   4763                        sqlite3_data_directory, winGetDirDep(), zOut);
  4644   4764       sqlite3_free(zOut);
  4645   4765     }else{
  4646   4766       if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
  4647         -      winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
  4648         -                  zRelative);
  4649         -      return SQLITE_CANTOPEN_FULLPATH;
         4767  +      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
         4768  +                         "winFullPathname2", zRelative);
  4650   4769       }
  4651   4770     }
  4652   4771     return SQLITE_OK;
  4653   4772   #endif
  4654   4773   
  4655   4774   #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
  4656   4775     SimulateIOError( return SQLITE_ERROR );
................................................................................
  4675   4794     DWORD nByte;
  4676   4795     void *zConverted;
  4677   4796     char *zOut;
  4678   4797   
  4679   4798     /* If this path name begins with "/X:", where "X" is any alphabetic
  4680   4799     ** character, discard the initial "/" from the pathname.
  4681   4800     */
  4682         -  if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
         4801  +  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
  4683   4802       zRelative++;
  4684   4803     }
  4685   4804   
  4686   4805     /* It's odd to simulate an io-error here, but really this is just
  4687   4806     ** using the io-error infrastructure to test that SQLite handles this
  4688   4807     ** function failing. This function could fail if, for example, the
  4689   4808     ** current working directory has been unlinked.
................................................................................
  4696   4815       **       for converting the relative path name to an absolute
  4697   4816       **       one by prepending the data directory and a backslash.
  4698   4817       */
  4699   4818       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
  4700   4819                        sqlite3_data_directory, winGetDirDep(), zRelative);
  4701   4820       return SQLITE_OK;
  4702   4821     }
  4703         -  zConverted = winConvertUtf8Filename(zRelative);
         4822  +  zConverted = winConvertFromUtf8Filename(zRelative);
  4704   4823     if( zConverted==0 ){
  4705   4824       return SQLITE_IOERR_NOMEM;
  4706   4825     }
  4707   4826     if( osIsNT() ){
  4708   4827       LPWSTR zTemp;
  4709   4828       nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
  4710   4829       if( nByte==0 ){
  4711         -      winLogError(SQLITE_ERROR, osGetLastError(),
  4712         -                  "GetFullPathNameW1", zConverted);
  4713   4830         sqlite3_free(zConverted);
  4714         -      return SQLITE_CANTOPEN_FULLPATH;
         4831  +      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
         4832  +                         "winFullPathname1", zRelative);
  4715   4833       }
  4716   4834       nByte += 3;
  4717   4835       zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
  4718   4836       if( zTemp==0 ){
  4719   4837         sqlite3_free(zConverted);
  4720   4838         return SQLITE_IOERR_NOMEM;
  4721   4839       }
  4722   4840       nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
  4723   4841       if( nByte==0 ){
  4724         -      winLogError(SQLITE_ERROR, osGetLastError(),
  4725         -                  "GetFullPathNameW2", zConverted);
  4726   4842         sqlite3_free(zConverted);
  4727   4843         sqlite3_free(zTemp);
  4728         -      return SQLITE_CANTOPEN_FULLPATH;
         4844  +      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
         4845  +                         "winFullPathname2", zRelative);
  4729   4846       }
  4730   4847       sqlite3_free(zConverted);
  4731   4848       zOut = winUnicodeToUtf8(zTemp);
  4732   4849       sqlite3_free(zTemp);
  4733   4850     }
  4734   4851   #ifdef SQLITE_WIN32_HAS_ANSI
  4735   4852     else{
  4736   4853       char *zTemp;
  4737   4854       nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
  4738   4855       if( nByte==0 ){
  4739         -      winLogError(SQLITE_ERROR, osGetLastError(),
  4740         -                  "GetFullPathNameA1", zConverted);
  4741   4856         sqlite3_free(zConverted);
  4742         -      return SQLITE_CANTOPEN_FULLPATH;
         4857  +      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
         4858  +                         "winFullPathname3", zRelative);
  4743   4859       }
  4744   4860       nByte += 3;
  4745   4861       zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
  4746   4862       if( zTemp==0 ){
  4747   4863         sqlite3_free(zConverted);
  4748   4864         return SQLITE_IOERR_NOMEM;
  4749   4865       }
  4750   4866       nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
  4751   4867       if( nByte==0 ){
  4752         -      winLogError(SQLITE_ERROR, osGetLastError(),
  4753         -                  "GetFullPathNameA2", zConverted);
  4754   4868         sqlite3_free(zConverted);
  4755   4869         sqlite3_free(zTemp);
  4756         -      return SQLITE_CANTOPEN_FULLPATH;
         4870  +      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
         4871  +                         "winFullPathname4", zRelative);
  4757   4872       }
  4758   4873       sqlite3_free(zConverted);
  4759   4874       zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
  4760   4875       sqlite3_free(zTemp);
  4761   4876     }
  4762   4877   #endif
  4763   4878     if( zOut ){
................................................................................
  4777   4892   */
  4778   4893   /*
  4779   4894   ** Interfaces for opening a shared library, finding entry points
  4780   4895   ** within the shared library, and closing the shared library.
  4781   4896   */
  4782   4897   static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
  4783   4898     HANDLE h;
  4784         -  void *zConverted = winConvertUtf8Filename(zFilename);
         4899  +  void *zConverted = winConvertFromUtf8Filename(zFilename);
  4785   4900     UNUSED_PARAMETER(pVfs);
  4786   4901     if( zConverted==0 ){
  4787   4902       return 0;
  4788   4903     }
  4789   4904     if( osIsNT() ){
  4790   4905   #if SQLITE_OS_WINRT
  4791   4906       h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);

Changes to src/sqlite.h.in.

   470    470   #define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
   471    471   #define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
   472    472   #define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
   473    473   #define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
   474    474   #define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
   475    475   #define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
   476    476   #define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
          477  +#define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
   477    478   #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
   478    479   #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
   479    480   #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
   480    481   #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
   481    482   #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
   482    483   #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
          484  +#define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
   483    485   #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
   484    486   #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
   485    487   #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
   486    488   #define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
   487    489   #define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
   488    490   #define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
   489    491   #define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))

Changes to tool/mksqlite3c.tcl.

   133    133     set nstar [expr {60 - $n}]
   134    134     set stars [string range $s78 0 $nstar]
   135    135     puts $out "/************** $text $stars/"
   136    136   }
   137    137   
   138    138   # Read the source file named $filename and write it into the
   139    139   # sqlite3.c output file.  If any #include statements are seen,
   140         -# process them approprately.
          140  +# process them appropriately.
   141    141   #
   142    142   proc copy_file {filename} {
   143    143     global seen_hdr available_hdr out addstatic linemacros
   144    144     set ln 0
   145    145     set tail [file tail $filename]
   146    146     section_comment "Begin file $tail"
   147    147     if {$linemacros} {puts $out "#line 1 \"$filename\""}
................................................................................
   165    165             copy_file tsrc/$hdr
   166    166             section_comment "Continuing where we left off in $tail"
   167    167             if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""}
   168    168           }
   169    169         } elseif {![info exists seen_hdr($hdr)]} {
   170    170           set seen_hdr($hdr) 1
   171    171           puts $out $line
          172  +      } elseif {[regexp {/\*\s+amalgamator:\s+keep\s+\*/} $line]} {
          173  +        # This include file must be kept because there was a "keep"
          174  +        # directive inside of a line comment.
          175  +        puts $out $line
   172    176         } else {
   173         -        puts $out "/* $line */"
          177  +        # Comment out the entire line, replacing any nested comment
          178  +        # begin/end markers with the harmless substring "**".
          179  +        puts $out "/* [string map [list /* ** */ **] $line] */"
   174    180         }
   175    181       } elseif {[regexp {^#ifdef __cplusplus} $line]} {
   176    182         puts $out "#if 0"
   177    183       } elseif {!$linemacros && [regexp {^#line} $line]} {
   178    184         # Skip #line directives.
   179    185       } elseif {$addstatic && ![regexp {^(static|typedef)} $line]} {
   180    186         regsub {^SQLITE_API } $line {} line