/ Changes On Branch win32heap
Login

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

Changes In Branch win32heap Excluding Merge-Ins

This is equivalent to a diff from 0077c0772a to 3fefe4dd43

2013-11-09
22:08
Add the sqlite3_win32_compact_heap() function for cleaning up memory allocations on Win32 system. Also cleanup the winGetTempname() function. Changes to the Win32 VFS only. (check-in: d06d9fdb6e user: drh tags: trunk)
21:11
Use the UNICODE_STRING_MAX_CHARS constant from WinNT.h. (Closed-Leaf check-in: 3fefe4dd43 user: mistachkin tags: win32heap)
21:10
Furhter cleanup of the winGetTempname function. (check-in: 674de36bca user: mistachkin tags: win32heap)
18:15
Throw an error if AUTOINCREMENT appears in a WITHOUT ROWID table. Updates to API documentation to discuss WITHOUT ROWID. (check-in: b1abb2b078 user: drh tags: trunk)
2013-11-08
18:13
Enhancements to the Win32 native heap integration. (check-in: c54dc9672b user: mistachkin tags: win32heap)
17:13
Fix harmless compiler warnings. (check-in: 0077c0772a user: drh tags: trunk)
17:03
Merge the Cygwin directory separator fix. Also fix a C++-ism in the multiplexor code so that it will compile on MSVC. (check-in: 830629d31d user: drh tags: trunk)

Changes to src/os_win.c.

    65     65   */
    66     66   #ifndef SQLITE_WIN32_MAX_PATH_CHARS
    67     67   #  define SQLITE_WIN32_MAX_PATH_CHARS   (MAX_PATH)
    68     68   #endif
    69     69   
    70     70   /*
    71     71   ** Maximum pathname length (in chars) for WinNT.  This should normally be
    72         -** 32767.
           72  +** UNICODE_STRING_MAX_CHARS.
    73     73   */
    74     74   #ifndef SQLITE_WINNT_MAX_PATH_CHARS
    75         -#  define SQLITE_WINNT_MAX_PATH_CHARS   (32767)
           75  +#  define SQLITE_WINNT_MAX_PATH_CHARS   (UNICODE_STRING_MAX_CHARS)
    76     76   #endif
    77     77   
    78     78   /*
    79     79   ** Maximum pathname length (in bytes) for Win32.  The MAX_PATH macro is in
    80     80   ** characters, so we allocate 3 bytes per character assuming worst-case of
    81     81   ** 4-bytes-per-character for UTF8.
    82     82   */
    83     83   #ifndef SQLITE_WIN32_MAX_PATH_BYTES
    84     84   #  define SQLITE_WIN32_MAX_PATH_BYTES   (SQLITE_WIN32_MAX_PATH_CHARS*4)
    85     85   #endif
    86     86   
    87     87   /*
    88     88   ** Maximum pathname length (in bytes) for WinNT.  This should normally be
    89         -** 32767 * sizeof(WCHAR).
           89  +** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR).
    90     90   */
    91     91   #ifndef SQLITE_WINNT_MAX_PATH_BYTES
    92     92   #  define SQLITE_WINNT_MAX_PATH_BYTES   \
    93     93                               (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS)
    94     94   #endif
    95     95   
    96     96   /*
................................................................................
   308    308   /*
   309    309   ** The winMemData structure stores information required by the Win32-specific
   310    310   ** sqlite3_mem_methods implementation.
   311    311   */
   312    312   typedef struct winMemData winMemData;
   313    313   struct winMemData {
   314    314   #ifndef NDEBUG
   315         -  u32 magic;    /* Magic number to detect structure corruption. */
          315  +  u32 magic1;   /* Magic number to detect structure corruption. */
   316    316   #endif
   317    317     HANDLE hHeap; /* The handle to our heap. */
   318    318     BOOL bOwned;  /* Do we own the heap (i.e. destroy it on shutdown)? */
          319  +#ifndef NDEBUG
          320  +  u32 magic2;   /* Magic number to detect structure corruption. */
          321  +#endif
   319    322   };
   320    323   
   321    324   #ifndef NDEBUG
   322         -#define WINMEM_MAGIC     0x42b2830b
          325  +#define WINMEM_MAGIC1     0x42b2830b
          326  +#define WINMEM_MAGIC2     0xbd4d7cf4
   323    327   #endif
   324    328   
   325    329   static struct winMemData win_mem_data = {
   326    330   #ifndef NDEBUG
   327         -  WINMEM_MAGIC,
          331  +  WINMEM_MAGIC1,
   328    332   #endif
   329    333     NULL, FALSE
          334  +#ifndef NDEBUG
          335  +  ,WINMEM_MAGIC2
          336  +#endif
   330    337   };
   331    338   
   332    339   #ifndef NDEBUG
   333         -#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
          340  +#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 )
          341  +#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 )
          342  +#define winMemAssertMagic()  winMemAssertMagic1(); winMemAssertMagic2();
   334    343   #else
   335    344   #define winMemAssertMagic()
   336    345   #endif
   337    346   
   338         -#define winMemGetHeap() win_mem_data.hHeap
          347  +#define winMemGetDataPtr()  &win_mem_data
          348  +#define winMemGetHeap()     win_mem_data.hHeap
          349  +#define winMemGetOwned()    win_mem_data.bOwned
   339    350   
   340    351   static void *winMemMalloc(int nBytes);
   341    352   static void winMemFree(void *pPrior);
   342    353   static void *winMemRealloc(void *pPrior, int nBytes);
   343    354   static int winMemSize(void *p);
   344    355   static int winMemRoundup(int n);
   345    356   static int winMemInit(void *pAppData);
................................................................................
   728    739   #else
   729    740     { "HeapValidate",            (SYSCALL)0,                       0 },
   730    741   #endif
   731    742   
   732    743   #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
   733    744           LPCVOID))aSyscall[42].pCurrent)
   734    745   
          746  +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
          747  +  { "HeapCompact",             (SYSCALL)HeapCompact,             0 },
          748  +#else
          749  +  { "HeapCompact",             (SYSCALL)0,                       0 },
          750  +#endif
          751  +
          752  +#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
          753  +
   735    754   #if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   736    755     { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
   737    756   #else
   738    757     { "LoadLibraryA",            (SYSCALL)0,                       0 },
   739    758   #endif
   740    759   
   741         -#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[43].pCurrent)
          760  +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
   742    761   
   743    762   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
   744    763           !defined(SQLITE_OMIT_LOAD_EXTENSION)
   745    764     { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
   746    765   #else
   747    766     { "LoadLibraryW",            (SYSCALL)0,                       0 },
   748    767   #endif
   749    768   
   750         -#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[44].pCurrent)
          769  +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
   751    770   
   752    771   #if !SQLITE_OS_WINRT
   753    772     { "LocalFree",               (SYSCALL)LocalFree,               0 },
   754    773   #else
   755    774     { "LocalFree",               (SYSCALL)0,                       0 },
   756    775   #endif
   757    776   
   758         -#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[45].pCurrent)
          777  +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
   759    778   
   760    779   #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
   761    780     { "LockFile",                (SYSCALL)LockFile,                0 },
   762    781   #else
   763    782     { "LockFile",                (SYSCALL)0,                       0 },
   764    783   #endif
   765    784   
   766    785   #ifndef osLockFile
   767    786   #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   768         -        DWORD))aSyscall[46].pCurrent)
          787  +        DWORD))aSyscall[47].pCurrent)
   769    788   #endif
   770    789   
   771    790   #if !SQLITE_OS_WINCE
   772    791     { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
   773    792   #else
   774    793     { "LockFileEx",              (SYSCALL)0,                       0 },
   775    794   #endif
   776    795   
   777    796   #ifndef osLockFileEx
   778    797   #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
   779         -        LPOVERLAPPED))aSyscall[47].pCurrent)
          798  +        LPOVERLAPPED))aSyscall[48].pCurrent)
   780    799   #endif
   781    800   
   782    801   #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
   783    802     { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
   784    803   #else
   785    804     { "MapViewOfFile",           (SYSCALL)0,                       0 },
   786    805   #endif
   787    806   
   788    807   #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   789         -        SIZE_T))aSyscall[48].pCurrent)
          808  +        SIZE_T))aSyscall[49].pCurrent)
   790    809   
   791    810     { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
   792    811   
   793    812   #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
   794         -        int))aSyscall[49].pCurrent)
          813  +        int))aSyscall[50].pCurrent)
   795    814   
   796    815     { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
   797    816   
   798    817   #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
   799         -        LARGE_INTEGER*))aSyscall[50].pCurrent)
          818  +        LARGE_INTEGER*))aSyscall[51].pCurrent)
   800    819   
   801    820     { "ReadFile",                (SYSCALL)ReadFile,                0 },
   802    821   
   803    822   #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
   804         -        LPOVERLAPPED))aSyscall[51].pCurrent)
          823  +        LPOVERLAPPED))aSyscall[52].pCurrent)
   805    824   
   806    825     { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
   807    826   
   808         -#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[52].pCurrent)
          827  +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
   809    828   
   810    829   #if !SQLITE_OS_WINRT
   811    830     { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
   812    831   #else
   813    832     { "SetFilePointer",          (SYSCALL)0,                       0 },
   814    833   #endif
   815    834   
   816    835   #define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
   817         -        DWORD))aSyscall[53].pCurrent)
          836  +        DWORD))aSyscall[54].pCurrent)
   818    837   
   819    838   #if !SQLITE_OS_WINRT
   820    839     { "Sleep",                   (SYSCALL)Sleep,                   0 },
   821    840   #else
   822    841     { "Sleep",                   (SYSCALL)0,                       0 },
   823    842   #endif
   824    843   
   825         -#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[54].pCurrent)
          844  +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
   826    845   
   827    846     { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
   828    847   
   829    848   #define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
   830         -        LPFILETIME))aSyscall[55].pCurrent)
          849  +        LPFILETIME))aSyscall[56].pCurrent)
   831    850   
   832    851   #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
   833    852     { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
   834    853   #else
   835    854     { "UnlockFile",              (SYSCALL)0,                       0 },
   836    855   #endif
   837    856   
   838    857   #ifndef osUnlockFile
   839    858   #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   840         -        DWORD))aSyscall[56].pCurrent)
          859  +        DWORD))aSyscall[57].pCurrent)
   841    860   #endif
   842    861   
   843    862   #if !SQLITE_OS_WINCE
   844    863     { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
   845    864   #else
   846    865     { "UnlockFileEx",            (SYSCALL)0,                       0 },
   847    866   #endif
   848    867   
   849    868   #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   850         -        LPOVERLAPPED))aSyscall[57].pCurrent)
          869  +        LPOVERLAPPED))aSyscall[58].pCurrent)
   851    870   
   852    871   #if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
   853    872     { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
   854    873   #else
   855    874     { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
   856    875   #endif
   857    876   
   858         -#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[58].pCurrent)
          877  +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
   859    878   
   860    879     { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
   861    880   
   862    881   #define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
   863         -        LPCSTR,LPBOOL))aSyscall[59].pCurrent)
          882  +        LPCSTR,LPBOOL))aSyscall[60].pCurrent)
   864    883   
   865    884     { "WriteFile",               (SYSCALL)WriteFile,               0 },
   866    885   
   867    886   #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
   868         -        LPOVERLAPPED))aSyscall[60].pCurrent)
          887  +        LPOVERLAPPED))aSyscall[61].pCurrent)
   869    888   
   870    889   #if SQLITE_OS_WINRT
   871    890     { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
   872    891   #else
   873    892     { "CreateEventExW",          (SYSCALL)0,                       0 },
   874    893   #endif
   875    894   
   876    895   #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
   877         -        DWORD,DWORD))aSyscall[61].pCurrent)
          896  +        DWORD,DWORD))aSyscall[62].pCurrent)
   878    897   
   879    898   #if !SQLITE_OS_WINRT
   880    899     { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
   881    900   #else
   882    901     { "WaitForSingleObject",     (SYSCALL)0,                       0 },
   883    902   #endif
   884    903   
   885    904   #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
   886         -        DWORD))aSyscall[62].pCurrent)
          905  +        DWORD))aSyscall[63].pCurrent)
   887    906   
   888    907   #if SQLITE_OS_WINRT
   889    908     { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
   890    909   #else
   891    910     { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
   892    911   #endif
   893    912   
   894    913   #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
   895         -        BOOL))aSyscall[63].pCurrent)
          914  +        BOOL))aSyscall[64].pCurrent)
   896    915   
   897    916   #if SQLITE_OS_WINRT
   898    917     { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
   899    918   #else
   900    919     { "SetFilePointerEx",        (SYSCALL)0,                       0 },
   901    920   #endif
   902    921   
   903    922   #define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
   904         -        PLARGE_INTEGER,DWORD))aSyscall[64].pCurrent)
          923  +        PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
   905    924   
   906    925   #if SQLITE_OS_WINRT
   907    926     { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
   908    927   #else
   909    928     { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
   910    929   #endif
   911    930   
   912    931   #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
   913         -        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[65].pCurrent)
          932  +        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
   914    933   
   915    934   #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
   916    935     { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
   917    936   #else
   918    937     { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
   919    938   #endif
   920    939   
   921    940   #define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
   922         -        SIZE_T))aSyscall[66].pCurrent)
          941  +        SIZE_T))aSyscall[67].pCurrent)
   923    942   
   924    943   #if SQLITE_OS_WINRT
   925    944     { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
   926    945   #else
   927    946     { "CreateFile2",             (SYSCALL)0,                       0 },
   928    947   #endif
   929    948   
   930    949   #define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
   931         -        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[67].pCurrent)
          950  +        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
   932    951   
   933    952   #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   934    953     { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
   935    954   #else
   936    955     { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
   937    956   #endif
   938    957   
   939    958   #define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
   940         -        DWORD))aSyscall[68].pCurrent)
          959  +        DWORD))aSyscall[69].pCurrent)
   941    960   
   942    961   #if SQLITE_OS_WINRT
   943    962     { "GetTickCount64",          (SYSCALL)GetTickCount64,          0 },
   944    963   #else
   945    964     { "GetTickCount64",          (SYSCALL)0,                       0 },
   946    965   #endif
   947    966   
   948         -#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[69].pCurrent)
          967  +#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
   949    968   
   950    969   #if SQLITE_OS_WINRT
   951    970     { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
   952    971   #else
   953    972     { "GetNativeSystemInfo",     (SYSCALL)0,                       0 },
   954    973   #endif
   955    974   
   956    975   #define osGetNativeSystemInfo ((VOID(WINAPI*)( \
   957         -        LPSYSTEM_INFO))aSyscall[70].pCurrent)
          976  +        LPSYSTEM_INFO))aSyscall[71].pCurrent)
   958    977   
   959    978   #if defined(SQLITE_WIN32_HAS_ANSI)
   960    979     { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
   961    980   #else
   962    981     { "OutputDebugStringA",      (SYSCALL)0,                       0 },
   963    982   #endif
   964    983   
   965         -#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[71].pCurrent)
          984  +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
   966    985   
   967    986   #if defined(SQLITE_WIN32_HAS_WIDE)
   968    987     { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
   969    988   #else
   970    989     { "OutputDebugStringW",      (SYSCALL)0,                       0 },
   971    990   #endif
   972    991   
   973         -#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[72].pCurrent)
          992  +#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
   974    993   
   975    994     { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
   976    995   
   977         -#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[73].pCurrent)
          996  +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
   978    997   
   979    998   #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
   980    999     { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
   981   1000   #else
   982   1001     { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
   983   1002   #endif
   984   1003   
   985   1004   #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
   986         -        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[74].pCurrent)
         1005  +        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
   987   1006   
   988   1007   }; /* End of the overrideable system calls */
   989   1008   
   990   1009   /*
   991   1010   ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
   992   1011   ** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
   993   1012   ** system call pointer, or SQLITE_NOTFOUND if there is no configurable
................................................................................
  1066   1085     }
  1067   1086     for(i++; i<ArraySize(aSyscall); i++){
  1068   1087       if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
  1069   1088     }
  1070   1089     return 0;
  1071   1090   }
  1072   1091   
         1092  +#ifdef SQLITE_WIN32_MALLOC
         1093  +/*
         1094  +** If a Win32 native heap has been configured, this function will attempt to
         1095  +** compact it.  Upon success, SQLITE_OK will be returned.  Upon failure, one
         1096  +** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned.  The
         1097  +** "pnLargest" argument, if non-zero, will be used to return the size of the
         1098  +** largest committed free block in the heap, in bytes.
         1099  +*/
         1100  +int sqlite3_win32_compact_heap(LPUINT pnLargest){
         1101  +  int rc = SQLITE_OK;
         1102  +  UINT nLargest = 0;
         1103  +  HANDLE hHeap;
         1104  +
         1105  +  winMemAssertMagic();
         1106  +  hHeap = winMemGetHeap();
         1107  +  assert( hHeap!=0 );
         1108  +  assert( hHeap!=INVALID_HANDLE_VALUE );
         1109  +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
         1110  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
         1111  +#endif
         1112  +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
         1113  +  if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
         1114  +    DWORD lastErrno = osGetLastError();
         1115  +    if( lastErrno==NO_ERROR ){
         1116  +      sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
         1117  +                  (void*)hHeap);
         1118  +      rc = SQLITE_NOMEM;
         1119  +    }else{
         1120  +      sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
         1121  +                  osGetLastError(), (void*)hHeap);
         1122  +      rc = SQLITE_ERROR;
         1123  +    }
         1124  +  }
         1125  +#else
         1126  +  sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
         1127  +              (void*)hHeap);
         1128  +  rc = SQLITE_NOTFOUND;
         1129  +#endif
         1130  +  if( pnLargest ) *pnLargest = nLargest;
         1131  +  return rc;
         1132  +}
         1133  +
         1134  +/*
         1135  +** If a Win32 native heap has been configured, this function will attempt to
         1136  +** destroy and recreate it.  If the Win32 native heap is not isolated and/or
         1137  +** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
         1138  +** be returned and no changes will be made to the Win32 native heap.
         1139  +*/
         1140  +int sqlite3_win32_reset_heap(){
         1141  +  int rc;
         1142  +  MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
         1143  +  MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
         1144  +  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
         1145  +  MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
         1146  +  sqlite3_mutex_enter(pMaster);
         1147  +  sqlite3_mutex_enter(pMem);
         1148  +  winMemAssertMagic();
         1149  +  if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
         1150  +    /*
         1151  +    ** At this point, there should be no outstanding memory allocations on
         1152  +    ** the heap.  Also, since both the master and memsys locks are currently
         1153  +    ** being held by us, no other function (i.e. from another thread) should
         1154  +    ** be able to even access the heap.  Attempt to destroy and recreate our
         1155  +    ** isolated Win32 native heap now.
         1156  +    */
         1157  +    assert( winMemGetHeap()!=NULL );
         1158  +    assert( winMemGetOwned() );
         1159  +    assert( sqlite3_memory_used()==0 );
         1160  +    winMemShutdown(winMemGetDataPtr());
         1161  +    assert( winMemGetHeap()==NULL );
         1162  +    assert( !winMemGetOwned() );
         1163  +    assert( sqlite3_memory_used()==0 );
         1164  +    rc = winMemInit(winMemGetDataPtr());
         1165  +    assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
         1166  +    assert( rc!=SQLITE_OK || winMemGetOwned() );
         1167  +    assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
         1168  +  }else{
         1169  +    /*
         1170  +    ** The Win32 native heap cannot be modified because it may be in use.
         1171  +    */
         1172  +    rc = SQLITE_BUSY;
         1173  +  }
         1174  +  sqlite3_mutex_leave(pMem);
         1175  +  sqlite3_mutex_leave(pMaster);
         1176  +  return rc;
         1177  +}
         1178  +#endif /* SQLITE_WIN32_MALLOC */
         1179  +
  1073   1180   /*
  1074   1181   ** This function outputs the specified (ANSI) string to the Win32 debugger
  1075   1182   ** (if available).
  1076   1183   */
  1077   1184   
  1078   1185   void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
  1079   1186     char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
................................................................................
  1174   1281     void *p;
  1175   1282   
  1176   1283     winMemAssertMagic();
  1177   1284     hHeap = winMemGetHeap();
  1178   1285     assert( hHeap!=0 );
  1179   1286     assert( hHeap!=INVALID_HANDLE_VALUE );
  1180   1287   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1181         -  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
         1288  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
  1182   1289   #endif
  1183   1290     assert( nBytes>=0 );
  1184   1291     p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
  1185   1292     if( !p ){
  1186   1293       sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
  1187   1294                   nBytes, osGetLastError(), (void*)hHeap);
  1188   1295     }
................................................................................
  1196   1303     HANDLE hHeap;
  1197   1304   
  1198   1305     winMemAssertMagic();
  1199   1306     hHeap = winMemGetHeap();
  1200   1307     assert( hHeap!=0 );
  1201   1308     assert( hHeap!=INVALID_HANDLE_VALUE );
  1202   1309   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1203         -  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
         1310  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
  1204   1311   #endif
  1205   1312     if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
  1206   1313     if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
  1207   1314       sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
  1208   1315                   pPrior, osGetLastError(), (void*)hHeap);
  1209   1316     }
  1210   1317   }
................................................................................
  1217   1324     void *p;
  1218   1325   
  1219   1326     winMemAssertMagic();
  1220   1327     hHeap = winMemGetHeap();
  1221   1328     assert( hHeap!=0 );
  1222   1329     assert( hHeap!=INVALID_HANDLE_VALUE );
  1223   1330   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1224         -  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
         1331  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
  1225   1332   #endif
  1226   1333     assert( nBytes>=0 );
  1227   1334     if( !pPrior ){
  1228   1335       p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
  1229   1336     }else{
  1230   1337       p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
  1231   1338     }
................................................................................
  1245   1352     SIZE_T n;
  1246   1353   
  1247   1354     winMemAssertMagic();
  1248   1355     hHeap = winMemGetHeap();
  1249   1356     assert( hHeap!=0 );
  1250   1357     assert( hHeap!=INVALID_HANDLE_VALUE );
  1251   1358   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1252         -  assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
         1359  +  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
  1253   1360   #endif
  1254   1361     if( !p ) return 0;
  1255   1362     n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
  1256   1363     if( n==(SIZE_T)-1 ){
  1257   1364       sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
  1258   1365                   p, osGetLastError(), (void*)hHeap);
  1259   1366       return 0;
................................................................................
  1271   1378   /*
  1272   1379   ** Initialize this module.
  1273   1380   */
  1274   1381   static int winMemInit(void *pAppData){
  1275   1382     winMemData *pWinMemData = (winMemData *)pAppData;
  1276   1383   
  1277   1384     if( !pWinMemData ) return SQLITE_ERROR;
  1278         -  assert( pWinMemData->magic==WINMEM_MAGIC );
         1385  +  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
         1386  +  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
  1279   1387   
  1280   1388   #if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
  1281   1389     if( !pWinMemData->hHeap ){
  1282   1390       pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
  1283   1391                                         SQLITE_WIN32_HEAP_INIT_SIZE,
  1284   1392                                         SQLITE_WIN32_HEAP_MAX_SIZE);
  1285   1393       if( !pWinMemData->hHeap ){
................................................................................
  1313   1421   /*
  1314   1422   ** Deinitialize this module.
  1315   1423   */
  1316   1424   static void winMemShutdown(void *pAppData){
  1317   1425     winMemData *pWinMemData = (winMemData *)pAppData;
  1318   1426   
  1319   1427     if( !pWinMemData ) return;
         1428  +  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
         1429  +  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
         1430  +
  1320   1431     if( pWinMemData->hHeap ){
  1321   1432       assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
  1322   1433   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
  1323   1434       assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
  1324   1435   #endif
  1325   1436       if( pWinMemData->bOwned ){
  1326   1437         if( !osHeapDestroy(pWinMemData->hHeap) ){
................................................................................
  4011   4122   */
  4012   4123   static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
  4013   4124     static char zChars[] =
  4014   4125       "abcdefghijklmnopqrstuvwxyz"
  4015   4126       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4016   4127       "0123456789";
  4017   4128     size_t i, j;
  4018         -  int nBuf, nLen;
         4129  +  int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
         4130  +  int nMax, nBuf, nDir, nLen;
  4019   4131     char *zBuf;
  4020   4132   
  4021   4133     /* It's odd to simulate an io-error here, but really this is just
  4022   4134     ** using the io-error infrastructure to test that SQLite handles this
  4023   4135     ** function failing. 
  4024   4136     */
  4025   4137     SimulateIOError( return SQLITE_IOERR );
  4026   4138   
  4027   4139     /* Allocate a temporary buffer to store the fully qualified file
  4028   4140     ** name for the temporary file.  If this fails, we cannot continue.
  4029   4141     */
  4030         -  nBuf = pVfs->mxPathname;
  4031         -  zBuf = sqlite3MallocZero( nBuf+3 );
         4142  +  nMax = pVfs->mxPathname; nBuf = nMax + 2;
         4143  +  zBuf = sqlite3MallocZero( nBuf );
  4032   4144     if( !zBuf ){
  4033   4145       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4034   4146       return SQLITE_IOERR_NOMEM;
  4035   4147     }
  4036   4148   
  4037   4149     /* Figure out the effective temporary directory.  First, check if one
  4038   4150     ** has been explicitly set by the application; otherwise, use the one
  4039   4151     ** configured by the operating system.
  4040   4152     */
  4041         -  assert( nBuf>30 );
         4153  +  nDir = nMax - (nPre + 15);
         4154  +  assert( nDir>0 );
  4042   4155     if( sqlite3_temp_directory ){
  4043         -    sqlite3_snprintf(nBuf-30, zBuf, "%s", sqlite3_temp_directory);
  4044         -    winMakeEndInDirSep(nBuf-30, zBuf);
         4156  +    int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
         4157  +    if( nDirLen>0 ){
         4158  +      if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
         4159  +        nDirLen++;
         4160  +      }
         4161  +      if( nDirLen>nDir ){
         4162  +        sqlite3_free(zBuf);
         4163  +        OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
         4164  +        return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
         4165  +      }
         4166  +      sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
         4167  +    }
  4045   4168     }
  4046   4169   #if defined(__CYGWIN__)
  4047   4170     else{
  4048   4171       static const char *azDirs[] = {
  4049   4172          0, /* getenv("SQLITE_TMPDIR") */
  4050   4173          0, /* getenv("TMPDIR") */
  4051   4174          0, /* getenv("TMP") */
................................................................................
  4077   4200           zConverted = winConvertFromUtf8Filename(zDir);
  4078   4201           if( !zConverted ){
  4079   4202             sqlite3_free(zBuf);
  4080   4203             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4081   4204             return SQLITE_IOERR_NOMEM;
  4082   4205           }
  4083   4206           if( winIsDir(zConverted) ){
  4084         -          sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir);
  4085         -          winMakeEndInDirSep(nBuf-30, zBuf);
         4207  +          sqlite3_snprintf(nMax, zBuf, "%s", zDir);
  4086   4208             sqlite3_free(zConverted);
  4087   4209             break;
  4088   4210           }
  4089   4211           sqlite3_free(zConverted);
  4090   4212         }else{
  4091         -        zConverted = sqlite3MallocZero( nBuf+1 );
         4213  +        zConverted = sqlite3MallocZero( nMax+1 );
  4092   4214           if( !zConverted ){
  4093   4215             sqlite3_free(zBuf);
  4094   4216             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4095   4217             return SQLITE_IOERR_NOMEM;
  4096   4218           }
  4097   4219           if( cygwin_conv_path(
  4098   4220                   osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
  4099         -                zConverted, nBuf+1)<0 ){
         4221  +                zConverted, nMax+1)<0 ){
  4100   4222             sqlite3_free(zConverted);
  4101   4223             sqlite3_free(zBuf);
  4102   4224             OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
  4103   4225             return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
  4104         -                             "winGetTempname1", zDir);
         4226  +                             "winGetTempname2", zDir);
  4105   4227           }
  4106   4228           if( winIsDir(zConverted) ){
  4107   4229             /* At this point, we know the candidate directory exists and should
  4108   4230             ** be used.  However, we may need to convert the string containing
  4109   4231             ** its name into UTF-8 (i.e. if it is UTF-16 right now).
  4110   4232             */
  4111   4233             if( osIsNT() ){
................................................................................
  4112   4234               char *zUtf8 = winUnicodeToUtf8(zConverted);
  4113   4235               if( !zUtf8 ){
  4114   4236                 sqlite3_free(zConverted);
  4115   4237                 sqlite3_free(zBuf);
  4116   4238                 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4117   4239                 return SQLITE_IOERR_NOMEM;
  4118   4240               }
  4119         -            sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
  4120         -            winMakeEndInDirSep(nBuf-30, zBuf);
         4241  +            sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
  4121   4242               sqlite3_free(zUtf8);
  4122   4243               sqlite3_free(zConverted);
  4123   4244               break;
  4124   4245             }else{
  4125         -            sqlite3_snprintf(nBuf-30, zBuf, "%s", zConverted);
  4126         -            winMakeEndInDirSep(nBuf-30, zBuf);
         4246  +            sqlite3_snprintf(nMax, zBuf, "%s", zConverted);
  4127   4247               sqlite3_free(zConverted);
  4128   4248               break;
  4129   4249             }
  4130   4250           }
  4131   4251           sqlite3_free(zConverted);
  4132   4252         }
  4133   4253       }
  4134   4254     }
  4135   4255   #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
  4136   4256     else if( osIsNT() ){
  4137   4257       char *zMulti;
  4138         -    LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) );
         4258  +    LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
  4139   4259       if( !zWidePath ){
  4140   4260         sqlite3_free(zBuf);
  4141   4261         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4142   4262         return SQLITE_IOERR_NOMEM;
  4143   4263       }
  4144         -    if( osGetTempPathW(nBuf, zWidePath)==0 ){
         4264  +    if( osGetTempPathW(nMax, zWidePath)==0 ){
  4145   4265         sqlite3_free(zWidePath);
  4146   4266         sqlite3_free(zBuf);
  4147   4267         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
  4148   4268         return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
  4149         -                         "winGetTempname1", 0);
         4269  +                         "winGetTempname2", 0);
  4150   4270       }
  4151   4271       zMulti = winUnicodeToUtf8(zWidePath);
  4152   4272       if( zMulti ){
  4153         -      sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti);
  4154         -      winMakeEndInDirSep(nBuf-30, zBuf);
         4273  +      sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
  4155   4274         sqlite3_free(zMulti);
  4156   4275         sqlite3_free(zWidePath);
  4157   4276       }else{
  4158   4277         sqlite3_free(zWidePath);
  4159   4278         sqlite3_free(zBuf);
  4160   4279         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4161   4280         return SQLITE_IOERR_NOMEM;
  4162   4281       }
  4163   4282     }
  4164   4283   #ifdef SQLITE_WIN32_HAS_ANSI
  4165   4284     else{
  4166   4285       char *zUtf8;
  4167         -    char *zMbcsPath = sqlite3MallocZero( nBuf );
         4286  +    char *zMbcsPath = sqlite3MallocZero( nMax );
  4168   4287       if( !zMbcsPath ){
  4169   4288         sqlite3_free(zBuf);
  4170   4289         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4171   4290         return SQLITE_IOERR_NOMEM;
  4172   4291       }
  4173         -    if( osGetTempPathA(nBuf, zMbcsPath)==0 ){
         4292  +    if( osGetTempPathA(nMax, zMbcsPath)==0 ){
  4174   4293         sqlite3_free(zBuf);
  4175   4294         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
  4176   4295         return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
  4177         -                         "winGetTempname2", 0);
         4296  +                         "winGetTempname3", 0);
  4178   4297       }
  4179   4298       zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
  4180   4299       if( zUtf8 ){
  4181         -      sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
  4182         -      winMakeEndInDirSep(nBuf-30, zBuf);
         4300  +      sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
  4183   4301         sqlite3_free(zUtf8);
  4184   4302       }else{
  4185   4303         sqlite3_free(zBuf);
  4186   4304         OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
  4187   4305         return SQLITE_IOERR_NOMEM;
  4188   4306       }
  4189   4307     }
  4190   4308   #endif /* SQLITE_WIN32_HAS_ANSI */
  4191   4309   #endif /* !SQLITE_OS_WINRT */
  4192   4310   
  4193         -  /* Check that the output buffer is large enough for the temporary file 
  4194         -  ** name. If it is not, return SQLITE_ERROR.
         4311  +  /*
         4312  +  ** Check to make sure the temporary directory ends with an appropriate
         4313  +  ** separator.  If it does not and there is not enough space left to add
         4314  +  ** one, fail.
         4315  +  */
         4316  +  if( !winMakeEndInDirSep(nDir+1, zBuf) ){
         4317  +    sqlite3_free(zBuf);
         4318  +    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
         4319  +    return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
         4320  +  }
         4321  +
         4322  +  /*
         4323  +  ** Check that the output buffer is large enough for the temporary file 
         4324  +  ** name in the following format:
         4325  +  **
         4326  +  **   "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
         4327  +  **
         4328  +  ** If not, return SQLITE_ERROR.  The number 17 is used here in order to
         4329  +  ** account for the space used by the 15 character random suffix and the
         4330  +  ** two trailing NUL characters.  The final directory separator character
         4331  +  ** has already added if it was not already present.
  4195   4332     */
  4196   4333     nLen = sqlite3Strlen30(zBuf);
  4197         -
  4198         -  if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
         4334  +  if( (nLen + nPre + 17) > nBuf ){
  4199   4335       sqlite3_free(zBuf);
  4200   4336       OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
  4201         -    return winLogError(SQLITE_ERROR, 0, "winGetTempname3", 0);
         4337  +    return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
  4202   4338     }
  4203   4339   
  4204         -  sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
         4340  +  sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
  4205   4341   
  4206   4342     j = sqlite3Strlen30(zBuf);
  4207   4343     sqlite3_randomness(15, &zBuf[j]);
  4208   4344     for(i=0; i<15; i++, j++){
  4209   4345       zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
  4210   4346     }
  4211   4347     zBuf[j] = 0;
................................................................................
  5192   5328       winGetSystemCall,    /* xGetSystemCall */
  5193   5329       winNextSystemCall,   /* xNextSystemCall */
  5194   5330     };
  5195   5331   #endif
  5196   5332   
  5197   5333     /* Double-check that the aSyscall[] array has been constructed
  5198   5334     ** correctly.  See ticket [bb3a86e890c8e96ab] */
  5199         -  assert( ArraySize(aSyscall)==75 );
         5335  +  assert( ArraySize(aSyscall)==76 );
  5200   5336   
  5201   5337     /* get memory map allocation granularity */
  5202   5338     memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
  5203   5339   #if SQLITE_OS_WINRT
  5204   5340     osGetNativeSystemInfo(&winSysInfo);
  5205   5341   #else
  5206   5342     osGetSystemInfo(&winSysInfo);