Index: third_party/sqlite/src/src/os_win.c |
diff --git a/third_party/sqlite/src/src/os_win.c b/third_party/sqlite/src/src/os_win.c |
index 8a688285426c3495006ae47b106908a63d284cf4..94dcd0e047f9cb98b204946a46b2b286f439e746 100644 |
--- a/third_party/sqlite/src/src/os_win.c |
+++ b/third_party/sqlite/src/src/os_win.c |
@@ -76,6 +76,10 @@ |
# define NTDDI_WINBLUE 0x06030000 |
#endif |
+#ifndef NTDDI_WINTHRESHOLD |
+# define NTDDI_WINTHRESHOLD 0x06040000 |
+#endif |
+ |
/* |
** Check to see if the GetVersionEx[AW] functions are deprecated on the |
** target system. GetVersionEx was first deprecated in Win8.1. |
@@ -89,6 +93,19 @@ |
#endif |
/* |
+** Check to see if the CreateFileMappingA function is supported on the |
+** target system. It is unavailable when using "mincore.lib" on Win10. |
+** When compiling for Windows 10, always assume "mincore.lib" is in use. |
+*/ |
+#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA |
+# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD |
+# define SQLITE_WIN32_CREATEFILEMAPPINGA 0 |
+# else |
+# define SQLITE_WIN32_CREATEFILEMAPPINGA 1 |
+# endif |
+#endif |
+ |
+/* |
** This constant should already be defined (in the "WinDef.h" SDK file). |
*/ |
#ifndef MAX_PATH |
@@ -274,6 +291,17 @@ struct winFile { |
}; |
/* |
+** The winVfsAppData structure is used for the pAppData member for all of the |
+** Win32 VFS variants. |
+*/ |
+typedef struct winVfsAppData winVfsAppData; |
+struct winVfsAppData { |
+ const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */ |
+ void *pAppData; /* The extra pAppData, if any. */ |
+ BOOL bNoLock; /* Non-zero if locking is disabled. */ |
+}; |
+ |
+/* |
** Allowed values for winFile.ctrlFlags |
*/ |
#define WINFILE_RDONLY 0x02 /* Connection is read only */ |
@@ -328,10 +356,22 @@ struct winFile { |
#endif |
/* |
+ * This is cache size used in the calculation of the initial size of the |
+ * Win32-specific heap. It cannot be negative. |
+ */ |
+#ifndef SQLITE_WIN32_CACHE_SIZE |
+# if SQLITE_DEFAULT_CACHE_SIZE>=0 |
+# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) |
+# else |
+# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) |
+# endif |
+#endif |
+ |
+/* |
* The initial size of the Win32-specific heap. This value may be zero. |
*/ |
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE |
-# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \ |
+# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ |
(SQLITE_DEFAULT_PAGE_SIZE) + 4194304) |
#endif |
@@ -494,8 +534,9 @@ static struct win_syscall { |
#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ |
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) |
-#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ |
- (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) |
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ |
+ (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \ |
+ SQLITE_WIN32_CREATEFILEMAPPINGA |
{ "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, |
#else |
{ "CreateFileMappingA", (SYSCALL)0, 0 }, |
@@ -725,8 +766,7 @@ static struct win_syscall { |
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) |
-#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \ |
- SQLITE_WIN32_GETVERSIONEX |
+#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX |
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, |
#else |
{ "GetVersionExA", (SYSCALL)0, 0 }, |
@@ -736,7 +776,7 @@ static struct win_syscall { |
LPOSVERSIONINFOA))aSyscall[34].pCurrent) |
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ |
- defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX |
+ SQLITE_WIN32_GETVERSIONEX |
{ "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, |
#else |
{ "GetVersionExW", (SYSCALL)0, 0 }, |
@@ -1205,7 +1245,7 @@ int sqlite3_win32_compact_heap(LPUINT pnLargest){ |
if( lastErrno==NO_ERROR ){ |
sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p", |
(void*)hHeap); |
- rc = SQLITE_NOMEM; |
+ rc = SQLITE_NOMEM_BKPT; |
}else{ |
sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p", |
osGetLastError(), (void*)hHeap); |
@@ -1231,8 +1271,8 @@ int sqlite3_win32_reset_heap(){ |
int rc; |
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ |
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */ |
- MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); ) |
- MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); ) |
+ MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) |
+ MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); ) |
sqlite3_mutex_enter(pMaster); |
sqlite3_mutex_enter(pMem); |
winMemAssertMagic(); |
@@ -1277,6 +1317,12 @@ void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ |
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */ |
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */ |
assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE ); |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( !zBuf ){ |
+ (void)SQLITE_MISUSE_BKPT; |
+ return; |
+ } |
+#endif |
#if defined(SQLITE_WIN32_HAS_ANSI) |
if( nMin>0 ){ |
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); |
@@ -1347,7 +1393,7 @@ DWORD sqlite3Win32Wait(HANDLE hObject){ |
** the LockFileEx() API. |
*/ |
-#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX |
+#if !SQLITE_WIN32_GETVERSIONEX |
# define osIsNT() (1) |
#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
# define osIsNT() (1) |
@@ -1368,7 +1414,7 @@ int sqlite3_win32_is_nt(void){ |
** kernel. |
*/ |
return 1; |
-#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX |
+#elif SQLITE_WIN32_GETVERSIONEX |
if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ |
#if defined(SQLITE_WIN32_HAS_ANSI) |
OSVERSIONINFOA sInfo; |
@@ -1525,7 +1571,7 @@ static int winMemInit(void *pAppData){ |
"failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", |
osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, |
dwMaximumSize); |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
pWinMemData->bOwned = TRUE; |
assert( pWinMemData->bOwned ); |
@@ -1535,7 +1581,7 @@ static int winMemInit(void *pAppData){ |
if( !pWinMemData->hHeap ){ |
sqlite3_log(SQLITE_NOMEM, |
"failed to GetProcessHeap (%lu)", osGetLastError()); |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
pWinMemData->bOwned = FALSE; |
assert( !pWinMemData->bOwned ); |
@@ -1602,147 +1648,244 @@ void sqlite3MemSetDefault(void){ |
#endif /* SQLITE_WIN32_MALLOC */ |
/* |
-** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). |
+** Convert a UTF-8 string to Microsoft Unicode. |
** |
-** Space to hold the returned string is obtained from malloc. |
+** Space to hold the returned string is obtained from sqlite3_malloc(). |
*/ |
-static LPWSTR winUtf8ToUnicode(const char *zFilename){ |
+static LPWSTR winUtf8ToUnicode(const char *zText){ |
int nChar; |
- LPWSTR zWideFilename; |
+ LPWSTR zWideText; |
- nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
+ nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0); |
if( nChar==0 ){ |
return 0; |
} |
- zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) ); |
- if( zWideFilename==0 ){ |
+ zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) ); |
+ if( zWideText==0 ){ |
return 0; |
} |
- nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, |
+ nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText, |
nChar); |
if( nChar==0 ){ |
- sqlite3_free(zWideFilename); |
- zWideFilename = 0; |
+ sqlite3_free(zWideText); |
+ zWideText = 0; |
} |
- return zWideFilename; |
+ return zWideText; |
} |
/* |
-** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is |
-** obtained from sqlite3_malloc(). |
+** Convert a Microsoft Unicode string to UTF-8. |
+** |
+** Space to hold the returned string is obtained from sqlite3_malloc(). |
*/ |
-static char *winUnicodeToUtf8(LPCWSTR zWideFilename){ |
+static char *winUnicodeToUtf8(LPCWSTR zWideText){ |
int nByte; |
- char *zFilename; |
+ char *zText; |
- nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); |
+ nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0); |
if( nByte == 0 ){ |
return 0; |
} |
- zFilename = sqlite3MallocZero( nByte ); |
- if( zFilename==0 ){ |
+ zText = sqlite3MallocZero( nByte ); |
+ if( zText==0 ){ |
return 0; |
} |
- nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, |
+ nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte, |
0, 0); |
if( nByte == 0 ){ |
- sqlite3_free(zFilename); |
- zFilename = 0; |
+ sqlite3_free(zText); |
+ zText = 0; |
} |
- return zFilename; |
+ return zText; |
} |
/* |
-** Convert an ANSI string to Microsoft Unicode, based on the |
-** current codepage settings for file apis. |
+** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM |
+** code page. |
** |
-** Space to hold the returned string is obtained |
-** from sqlite3_malloc. |
+** Space to hold the returned string is obtained from sqlite3_malloc(). |
*/ |
-static LPWSTR winMbcsToUnicode(const char *zFilename){ |
+static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ |
int nByte; |
- LPWSTR zMbcsFilename; |
- int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
+ LPWSTR zMbcsText; |
+ int codepage = useAnsi ? CP_ACP : CP_OEMCP; |
- nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, |
+ nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, |
0)*sizeof(WCHAR); |
if( nByte==0 ){ |
return 0; |
} |
- zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) ); |
- if( zMbcsFilename==0 ){ |
+ zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) ); |
+ if( zMbcsText==0 ){ |
return 0; |
} |
- nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, |
+ nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, |
nByte); |
if( nByte==0 ){ |
- sqlite3_free(zMbcsFilename); |
- zMbcsFilename = 0; |
+ sqlite3_free(zMbcsText); |
+ zMbcsText = 0; |
} |
- return zMbcsFilename; |
+ return zMbcsText; |
} |
/* |
-** Convert Microsoft Unicode to multi-byte character string, based on the |
-** user's ANSI codepage. |
+** Convert a Microsoft Unicode string to a multi-byte character string, |
+** using the ANSI or OEM code page. |
** |
-** Space to hold the returned string is obtained from |
-** sqlite3_malloc(). |
+** Space to hold the returned string is obtained from sqlite3_malloc(). |
*/ |
-static char *winUnicodeToMbcs(LPCWSTR zWideFilename){ |
+static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ |
int nByte; |
- char *zFilename; |
- int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
+ char *zText; |
+ int codepage = useAnsi ? CP_ACP : CP_OEMCP; |
- nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); |
+ nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0); |
if( nByte == 0 ){ |
return 0; |
} |
- zFilename = sqlite3MallocZero( nByte ); |
- if( zFilename==0 ){ |
+ zText = sqlite3MallocZero( nByte ); |
+ if( zText==0 ){ |
return 0; |
} |
- nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, |
+ nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText, |
nByte, 0, 0); |
if( nByte == 0 ){ |
- sqlite3_free(zFilename); |
- zFilename = 0; |
+ sqlite3_free(zText); |
+ zText = 0; |
} |
- return zFilename; |
+ return zText; |
} |
/* |
-** Convert multibyte character string to UTF-8. Space to hold the |
-** returned string is obtained from sqlite3_malloc(). |
+** Convert a multi-byte character string to UTF-8. |
+** |
+** Space to hold the returned string is obtained from sqlite3_malloc(). |
*/ |
-char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ |
- char *zFilenameUtf8; |
+static char *winMbcsToUtf8(const char *zText, int useAnsi){ |
+ char *zTextUtf8; |
LPWSTR zTmpWide; |
- zTmpWide = winMbcsToUnicode(zFilename); |
+ zTmpWide = winMbcsToUnicode(zText, useAnsi); |
if( zTmpWide==0 ){ |
return 0; |
} |
- zFilenameUtf8 = winUnicodeToUtf8(zTmpWide); |
+ zTextUtf8 = winUnicodeToUtf8(zTmpWide); |
sqlite3_free(zTmpWide); |
- return zFilenameUtf8; |
+ return zTextUtf8; |
} |
/* |
-** Convert UTF-8 to multibyte character string. Space to hold the |
-** returned string is obtained from sqlite3_malloc(). |
+** Convert a UTF-8 string to a multi-byte character string. |
+** |
+** Space to hold the returned string is obtained from sqlite3_malloc(). |
*/ |
-char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ |
- char *zFilenameMbcs; |
+static char *winUtf8ToMbcs(const char *zText, int useAnsi){ |
+ char *zTextMbcs; |
LPWSTR zTmpWide; |
- zTmpWide = winUtf8ToUnicode(zFilename); |
+ zTmpWide = winUtf8ToUnicode(zText); |
if( zTmpWide==0 ){ |
return 0; |
} |
- zFilenameMbcs = winUnicodeToMbcs(zTmpWide); |
+ zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi); |
sqlite3_free(zTmpWide); |
- return zFilenameMbcs; |
+ return zTextMbcs; |
+} |
+ |
+/* |
+** This is a public wrapper for the winUtf8ToUnicode() function. |
+*/ |
+LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){ |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( !zText ){ |
+ (void)SQLITE_MISUSE_BKPT; |
+ return 0; |
+ } |
+#endif |
+#ifndef SQLITE_OMIT_AUTOINIT |
+ if( sqlite3_initialize() ) return 0; |
+#endif |
+ return winUtf8ToUnicode(zText); |
+} |
+ |
+/* |
+** This is a public wrapper for the winUnicodeToUtf8() function. |
+*/ |
+char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( !zWideText ){ |
+ (void)SQLITE_MISUSE_BKPT; |
+ return 0; |
+ } |
+#endif |
+#ifndef SQLITE_OMIT_AUTOINIT |
+ if( sqlite3_initialize() ) return 0; |
+#endif |
+ return winUnicodeToUtf8(zWideText); |
+} |
+ |
+/* |
+** This is a public wrapper for the winMbcsToUtf8() function. |
+*/ |
+char *sqlite3_win32_mbcs_to_utf8(const char *zText){ |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( !zText ){ |
+ (void)SQLITE_MISUSE_BKPT; |
+ return 0; |
+ } |
+#endif |
+#ifndef SQLITE_OMIT_AUTOINIT |
+ if( sqlite3_initialize() ) return 0; |
+#endif |
+ return winMbcsToUtf8(zText, osAreFileApisANSI()); |
+} |
+ |
+/* |
+** This is a public wrapper for the winMbcsToUtf8() function. |
+*/ |
+char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( !zText ){ |
+ (void)SQLITE_MISUSE_BKPT; |
+ return 0; |
+ } |
+#endif |
+#ifndef SQLITE_OMIT_AUTOINIT |
+ if( sqlite3_initialize() ) return 0; |
+#endif |
+ return winMbcsToUtf8(zText, useAnsi); |
+} |
+ |
+/* |
+** This is a public wrapper for the winUtf8ToMbcs() function. |
+*/ |
+char *sqlite3_win32_utf8_to_mbcs(const char *zText){ |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( !zText ){ |
+ (void)SQLITE_MISUSE_BKPT; |
+ return 0; |
+ } |
+#endif |
+#ifndef SQLITE_OMIT_AUTOINIT |
+ if( sqlite3_initialize() ) return 0; |
+#endif |
+ return winUtf8ToMbcs(zText, osAreFileApisANSI()); |
+} |
+ |
+/* |
+** This is a public wrapper for the winUtf8ToMbcs() function. |
+*/ |
+char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){ |
+#ifdef SQLITE_ENABLE_API_ARMOR |
+ if( !zText ){ |
+ (void)SQLITE_MISUSE_BKPT; |
+ return 0; |
+ } |
+#endif |
+#ifndef SQLITE_OMIT_AUTOINIT |
+ if( sqlite3_initialize() ) return 0; |
+#endif |
+ return winUtf8ToMbcs(zText, useAnsi); |
} |
/* |
@@ -1772,7 +1915,7 @@ int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){ |
if( zValue && zValue[0] ){ |
zValueUtf8 = winUnicodeToUtf8(zValue); |
if ( zValueUtf8==0 ){ |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
} |
sqlite3_free(*ppDirectory); |
@@ -1844,7 +1987,7 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ |
if( dwLen > 0 ){ |
/* allocate a buffer and convert to UTF8 */ |
sqlite3BeginBenignMalloc(); |
- zOut = sqlite3_win32_mbcs_to_utf8(zTemp); |
+ zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); |
sqlite3EndBenignMalloc(); |
/* free the system buffer allocated by FormatMessage */ |
osLocalFree(zTemp); |
@@ -1986,16 +2129,17 @@ static void winLogIoerr(int nRetry, int lineno){ |
} |
} |
-#if SQLITE_OS_WINCE |
-/************************************************************************* |
-** This section contains code for WinCE only. |
+/* |
+** This #if does not rely on the SQLITE_OS_WINCE define because the |
+** corresponding section in "date.c" cannot use it. |
*/ |
-#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API |
+#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ |
+ (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) |
/* |
-** The MSVC CRT on Windows CE may not have a localtime() function. So |
-** create a substitute. |
+** The MSVC CRT on Windows CE may not have a localtime() function. |
+** So define a substitute. |
*/ |
-#include <time.h> |
+# include <time.h> |
struct tm *__cdecl localtime(const time_t *t) |
{ |
static struct tm y; |
@@ -2019,6 +2163,10 @@ struct tm *__cdecl localtime(const time_t *t) |
} |
#endif |
+#if SQLITE_OS_WINCE |
+/************************************************************************* |
+** This section contains code for WinCE only. |
+*/ |
#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] |
/* |
@@ -2049,7 +2197,7 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){ |
zName = winUtf8ToUnicode(zFilename); |
if( zName==0 ){ |
/* out of memory */ |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
/* Initialize the local lockdata */ |
@@ -2474,7 +2622,12 @@ static int winClose(sqlite3_file *id){ |
}while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); |
#if SQLITE_OS_WINCE |
#define WINCE_DELETION_ATTEMPTS 3 |
- winceDestroyLock(pFile); |
+ { |
+ winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData; |
+ if( pAppData==NULL || !pAppData->bNoLock ){ |
+ winceDestroyLock(pFile); |
+ } |
+ } |
if( pFile->zDeleteOnClose ){ |
int cnt = 0; |
while( |
@@ -2524,7 +2677,7 @@ static int winRead( |
"offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, |
pFile->h, pBuf, amt, offset, pFile->locktype)); |
-#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 |
+#if SQLITE_MAX_MMAP_SIZE>0 |
/* Deal with as much of this read request as possible by transfering |
** data from the memory mapping using memcpy(). */ |
if( offset<pFile->mmapSize ){ |
@@ -3032,9 +3185,8 @@ static int winLock(sqlite3_file *id, int locktype){ |
** the PENDING_LOCK byte is temporary. |
*/ |
newLocktype = pFile->locktype; |
- if( (pFile->locktype==NO_LOCK) |
- || ( (locktype==EXCLUSIVE_LOCK) |
- && (pFile->locktype==RESERVED_LOCK)) |
+ if( pFile->locktype==NO_LOCK |
+ || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK) |
){ |
int cnt = 3; |
while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, |
@@ -3207,6 +3359,44 @@ static int winUnlock(sqlite3_file *id, int locktype){ |
return rc; |
} |
+/****************************************************************************** |
+****************************** No-op Locking ********************************** |
+** |
+** Of the various locking implementations available, this is by far the |
+** simplest: locking is ignored. No attempt is made to lock the database |
+** file for reading or writing. |
+** |
+** This locking mode is appropriate for use on read-only databases |
+** (ex: databases that are burned into CD-ROM, for example.) It can |
+** also be used if the application employs some external mechanism to |
+** prevent simultaneous access of the same database by two or more |
+** database connections. But there is a serious risk of database |
+** corruption if this locking mode is used in situations where multiple |
+** database connections are accessing the same database file at the same |
+** time and one or more of those connections are writing. |
+*/ |
+ |
+static int winNolockLock(sqlite3_file *id, int locktype){ |
+ UNUSED_PARAMETER(id); |
+ UNUSED_PARAMETER(locktype); |
+ return SQLITE_OK; |
+} |
+ |
+static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){ |
+ UNUSED_PARAMETER(id); |
+ UNUSED_PARAMETER(pResOut); |
+ return SQLITE_OK; |
+} |
+ |
+static int winNolockUnlock(sqlite3_file *id, int locktype){ |
+ UNUSED_PARAMETER(id); |
+ UNUSED_PARAMETER(locktype); |
+ return SQLITE_OK; |
+} |
+ |
+/******************* End of the no-op lock implementation ********************* |
+******************************************************************************/ |
+ |
/* |
** If *pArg is initially negative then this is a query. Set *pArg to |
** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. |
@@ -3240,7 +3430,7 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ |
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
return SQLITE_OK; |
} |
- case SQLITE_LAST_ERRNO: { |
+ case SQLITE_FCNTL_LAST_ERRNO: { |
*(int*)pArg = (int)pFile->lastErrno; |
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
return SQLITE_OK; |
@@ -3298,6 +3488,12 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ |
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
return SQLITE_OK; |
} |
+ case SQLITE_FCNTL_WIN32_GET_HANDLE: { |
+ LPHANDLE phFile = (LPHANDLE)pArg; |
+ *phFile = pFile->h; |
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
+ return SQLITE_OK; |
+ } |
#ifdef SQLITE_TEST |
case SQLITE_FCNTL_WIN32_SET_HANDLE: { |
LPHANDLE phFile = (LPHANDLE)pArg; |
@@ -3485,12 +3681,12 @@ struct winShm { |
/* |
** Apply advisory locks for all n bytes beginning at ofst. |
*/ |
-#define _SHM_UNLCK 1 |
-#define _SHM_RDLCK 2 |
-#define _SHM_WRLCK 3 |
+#define WINSHM_UNLCK 1 |
+#define WINSHM_RDLCK 2 |
+#define WINSHM_WRLCK 3 |
static int winShmSystemLock( |
winShmNode *pFile, /* Apply locks to this open shared-memory segment */ |
- int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */ |
+ int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ |
int ofst, /* Offset to first byte to be locked/unlocked */ |
int nByte /* Number of bytes to lock or unlock */ |
){ |
@@ -3503,12 +3699,12 @@ static int winShmSystemLock( |
pFile->hFile.h, lockType, ofst, nByte)); |
/* Release/Acquire the system-level lock */ |
- if( lockType==_SHM_UNLCK ){ |
+ if( lockType==WINSHM_UNLCK ){ |
rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); |
}else{ |
/* Initialize the locking parameters */ |
DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; |
- if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; |
+ if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; |
rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); |
} |
@@ -3520,7 +3716,7 @@ static int winShmSystemLock( |
} |
OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", |
- pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" : |
+ pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : |
"winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); |
return rc; |
@@ -3598,12 +3794,12 @@ static int winOpenSharedMemory(winFile *pDbFd){ |
** allocate space for a new winShmNode and filename. |
*/ |
p = sqlite3MallocZero( sizeof(*p) ); |
- if( p==0 ) return SQLITE_IOERR_NOMEM; |
+ if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; |
nName = sqlite3Strlen30(pDbFd->zPath); |
pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); |
if( pNew==0 ){ |
sqlite3_free(p); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
pNew->zFilename = (char*)&pNew[1]; |
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); |
@@ -3628,10 +3824,12 @@ static int winOpenSharedMemory(winFile *pDbFd){ |
pShmNode->pNext = winShmNodeList; |
winShmNodeList = pShmNode; |
- pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); |
- if( pShmNode->mutex==0 ){ |
- rc = SQLITE_IOERR_NOMEM; |
- goto shm_open_err; |
+ if( sqlite3GlobalConfig.bCoreMutex ){ |
+ pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); |
+ if( pShmNode->mutex==0 ){ |
+ rc = SQLITE_IOERR_NOMEM_BKPT; |
+ goto shm_open_err; |
+ } |
} |
rc = winOpen(pDbFd->pVfs, |
@@ -3646,7 +3844,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ |
/* Check to see if another process is holding the dead-man switch. |
** If not, truncate the file to zero length. |
*/ |
- if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
+ if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); |
if( rc!=SQLITE_OK ){ |
rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), |
@@ -3654,8 +3852,8 @@ static int winOpenSharedMemory(winFile *pDbFd){ |
} |
} |
if( rc==SQLITE_OK ){ |
- winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); |
- rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); |
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); |
+ rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); |
} |
if( rc ) goto shm_open_err; |
} |
@@ -3684,7 +3882,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ |
/* Jump here on any error */ |
shm_open_err: |
- winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); |
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); |
winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ |
sqlite3_free(p); |
sqlite3_free(pNew); |
@@ -3773,7 +3971,7 @@ static int winShmLock( |
/* Unlock the system-level locks */ |
if( (mask & allMask)==0 ){ |
- rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n); |
+ rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n); |
}else{ |
rc = SQLITE_OK; |
} |
@@ -3801,7 +3999,7 @@ static int winShmLock( |
/* Get shared locks at the system level, if necessary */ |
if( rc==SQLITE_OK ){ |
if( (allShared & mask)==0 ){ |
- rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n); |
+ rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n); |
}else{ |
rc = SQLITE_OK; |
} |
@@ -3826,7 +4024,7 @@ static int winShmLock( |
** also mark the local connection as being locked. |
*/ |
if( rc==SQLITE_OK ){ |
- rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n); |
+ rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n); |
if( rc==SQLITE_OK ){ |
assert( (p->sharedMask & mask)==0 ); |
p->exclMask |= mask; |
@@ -3935,7 +4133,7 @@ static int winShmMap( |
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) |
); |
if( !apNew ){ |
- rc = SQLITE_IOERR_NOMEM; |
+ rc = SQLITE_IOERR_NOMEM_BKPT; |
goto shmpage_out; |
} |
pShmNode->aRegion = apNew; |
@@ -3952,7 +4150,7 @@ static int winShmMap( |
hMap = osCreateFileMappingW(pShmNode->hFile.h, |
NULL, PAGE_READWRITE, 0, nByte, NULL |
); |
-#elif defined(SQLITE_WIN32_HAS_ANSI) |
+#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA |
hMap = osCreateFileMappingA(pShmNode->hFile.h, |
NULL, PAGE_READWRITE, 0, nByte, NULL |
); |
@@ -4108,7 +4306,7 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ |
pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, |
(DWORD)((nMap>>32) & 0xffffffff), |
(DWORD)(nMap & 0xffffffff), NULL); |
-#elif defined(SQLITE_WIN32_HAS_ANSI) |
+#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA |
pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, |
(DWORD)((nMap>>32) & 0xffffffff), |
(DWORD)(nMap & 0xffffffff), NULL); |
@@ -4269,6 +4467,44 @@ static const sqlite3_io_methods winIoMethod = { |
winUnfetch /* xUnfetch */ |
}; |
+/* |
+** This vector defines all the methods that can operate on an |
+** sqlite3_file for win32 without performing any locking. |
+*/ |
+static const sqlite3_io_methods winIoNolockMethod = { |
+ 3, /* iVersion */ |
+ winClose, /* xClose */ |
+ winRead, /* xRead */ |
+ winWrite, /* xWrite */ |
+ winTruncate, /* xTruncate */ |
+ winSync, /* xSync */ |
+ winFileSize, /* xFileSize */ |
+ winNolockLock, /* xLock */ |
+ winNolockUnlock, /* xUnlock */ |
+ winNolockCheckReservedLock, /* xCheckReservedLock */ |
+ winFileControl, /* xFileControl */ |
+ winSectorSize, /* xSectorSize */ |
+ winDeviceCharacteristics, /* xDeviceCharacteristics */ |
+ winShmMap, /* xShmMap */ |
+ winShmLock, /* xShmLock */ |
+ winShmBarrier, /* xShmBarrier */ |
+ winShmUnmap, /* xShmUnmap */ |
+ winFetch, /* xFetch */ |
+ winUnfetch /* xUnfetch */ |
+}; |
+ |
+static winVfsAppData winAppData = { |
+ &winIoMethod, /* pMethod */ |
+ 0, /* pAppData */ |
+ 0 /* bNoLock */ |
+}; |
+ |
+static winVfsAppData winNolockAppData = { |
+ &winIoNolockMethod, /* pMethod */ |
+ 0, /* pAppData */ |
+ 1 /* bNoLock */ |
+}; |
+ |
/**************************************************************************** |
**************************** sqlite3_vfs methods **************************** |
** |
@@ -4289,7 +4525,7 @@ static char *winConvertToUtf8Filename(const void *zFilename){ |
} |
#ifdef SQLITE_WIN32_HAS_ANSI |
else{ |
- zConverted = sqlite3_win32_mbcs_to_utf8(zFilename); |
+ zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); |
} |
#endif |
/* caller will handle out of memory */ |
@@ -4310,7 +4546,7 @@ static void *winConvertFromUtf8Filename(const char *zFilename){ |
} |
#ifdef SQLITE_WIN32_HAS_ANSI |
else{ |
- zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
+ zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); |
} |
#endif |
/* caller will handle out of memory */ |
@@ -4365,7 +4601,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
zBuf = sqlite3MallocZero( nBuf ); |
if( !zBuf ){ |
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
/* Figure out the effective temporary directory. First, check if one |
@@ -4423,7 +4659,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
if( !zConverted ){ |
sqlite3_free(zBuf); |
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( winIsDir(zConverted) ){ |
sqlite3_snprintf(nMax, zBuf, "%s", zDir); |
@@ -4436,7 +4672,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
if( !zConverted ){ |
sqlite3_free(zBuf); |
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( cygwin_conv_path( |
osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, |
@@ -4457,7 +4693,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
sqlite3_free(zConverted); |
sqlite3_free(zBuf); |
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); |
sqlite3_free(zUtf8); |
@@ -4475,7 +4711,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
if( !zWidePath ){ |
sqlite3_free(zBuf); |
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( osGetTempPathW(nMax, zWidePath)==0 ){ |
sqlite3_free(zWidePath); |
@@ -4493,7 +4729,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
sqlite3_free(zWidePath); |
sqlite3_free(zBuf); |
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
} |
#ifdef SQLITE_WIN32_HAS_ANSI |
@@ -4503,7 +4739,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
if( !zMbcsPath ){ |
sqlite3_free(zBuf); |
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( osGetTempPathA(nMax, zMbcsPath)==0 ){ |
sqlite3_free(zBuf); |
@@ -4511,14 +4747,14 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), |
"winGetTempname3", 0); |
} |
- zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
+ zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI()); |
if( zUtf8 ){ |
sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); |
sqlite3_free(zUtf8); |
}else{ |
sqlite3_free(zBuf); |
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
} |
#endif /* SQLITE_WIN32_HAS_ANSI */ |
@@ -4601,7 +4837,7 @@ static int winIsDir(const void *zConverted){ |
** Open a file. |
*/ |
static int winOpen( |
- sqlite3_vfs *pVfs, /* Used to get maximum path name length */ |
+ sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ |
const char *zName, /* Name of the file (UTF-8) */ |
sqlite3_file *id, /* Write the SQLite file handle here */ |
int flags, /* Open mode flags */ |
@@ -4616,6 +4852,7 @@ static int winOpen( |
#if SQLITE_OS_WINCE |
int isTemp = 0; |
#endif |
+ winVfsAppData *pAppData; |
winFile *pFile = (winFile*)id; |
void *zConverted; /* Filename in OS encoding */ |
const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ |
@@ -4710,7 +4947,7 @@ static int winOpen( |
if( zConverted==0 ){ |
sqlite3_free(zTmpname); |
OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( winIsDir(zConverted) ){ |
@@ -4837,15 +5074,20 @@ static int winOpen( |
"rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? |
*pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); |
+ pAppData = (winVfsAppData*)pVfs->pAppData; |
+ |
#if SQLITE_OS_WINCE |
- if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
- && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
- ){ |
- osCloseHandle(h); |
- sqlite3_free(zConverted); |
- sqlite3_free(zTmpname); |
- OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); |
- return rc; |
+ { |
+ if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
+ && ((pAppData==NULL) || !pAppData->bNoLock) |
+ && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
+ ){ |
+ osCloseHandle(h); |
+ sqlite3_free(zConverted); |
+ sqlite3_free(zTmpname); |
+ OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); |
+ return rc; |
+ } |
} |
if( isTemp ){ |
pFile->zDeleteOnClose = zConverted; |
@@ -4856,7 +5098,7 @@ static int winOpen( |
} |
sqlite3_free(zTmpname); |
- pFile->pMethod = &winIoMethod; |
+ pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod; |
pFile->pVfs = pVfs; |
pFile->h = h; |
if( isReadonly ){ |
@@ -4910,7 +5152,7 @@ static int winDelete( |
zConverted = winConvertFromUtf8Filename(zFilename); |
if( zConverted==0 ){ |
OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( osIsNT() ){ |
do { |
@@ -5018,7 +5260,7 @@ static int winAccess( |
zConverted = winConvertFromUtf8Filename(zFilename); |
if( zConverted==0 ){ |
OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( osIsNT() ){ |
int cnt = 0; |
@@ -5131,6 +5373,18 @@ static int winFullPathname( |
int nFull, /* Size of output buffer in bytes */ |
char *zFull /* Output buffer */ |
){ |
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) |
+ DWORD nByte; |
+ void *zConverted; |
+ char *zOut; |
+#endif |
+ |
+ /* If this path name begins with "/X:", where "X" is any alphabetic |
+ ** character, discard the initial "/" from the pathname. |
+ */ |
+ if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ |
+ zRelative++; |
+ } |
#if defined(__CYGWIN__) |
SimulateIOError( return SQLITE_ERROR ); |
@@ -5145,7 +5399,7 @@ static int winFullPathname( |
*/ |
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
if( !zOut ){ |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( cygwin_conv_path( |
(osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | |
@@ -5157,7 +5411,7 @@ static int winFullPathname( |
char *zUtf8 = winConvertToUtf8Filename(zOut); |
if( !zUtf8 ){ |
sqlite3_free(zOut); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
sqlite3_data_directory, winGetDirSep(), zUtf8); |
@@ -5167,7 +5421,7 @@ static int winFullPathname( |
}else{ |
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
if( !zOut ){ |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( cygwin_conv_path( |
(osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), |
@@ -5179,7 +5433,7 @@ static int winFullPathname( |
char *zUtf8 = winConvertToUtf8Filename(zOut); |
if( !zUtf8 ){ |
sqlite3_free(zOut); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); |
sqlite3_free(zUtf8); |
@@ -5209,17 +5463,6 @@ static int winFullPathname( |
#endif |
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) |
- DWORD nByte; |
- void *zConverted; |
- char *zOut; |
- |
- /* If this path name begins with "/X:", where "X" is any alphabetic |
- ** character, discard the initial "/" from the pathname. |
- */ |
- if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ |
- zRelative++; |
- } |
- |
/* It's odd to simulate an io-error here, but really this is just |
** using the io-error infrastructure to test that SQLite handles this |
** function failing. This function could fail if, for example, the |
@@ -5239,7 +5482,7 @@ static int winFullPathname( |
} |
zConverted = winConvertFromUtf8Filename(zRelative); |
if( zConverted==0 ){ |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
if( osIsNT() ){ |
LPWSTR zTemp; |
@@ -5253,7 +5496,7 @@ static int winFullPathname( |
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
if( zTemp==0 ){ |
sqlite3_free(zConverted); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); |
if( nByte==0 ){ |
@@ -5279,7 +5522,7 @@ static int winFullPathname( |
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
if( zTemp==0 ){ |
sqlite3_free(zConverted); |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); |
if( nByte==0 ){ |
@@ -5289,7 +5532,7 @@ static int winFullPathname( |
"winFullPathname4", zRelative); |
} |
sqlite3_free(zConverted); |
- zOut = sqlite3_win32_mbcs_to_utf8(zTemp); |
+ zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); |
sqlite3_free(zTemp); |
} |
#endif |
@@ -5298,7 +5541,7 @@ static int winFullPathname( |
sqlite3_free(zOut); |
return SQLITE_OK; |
}else{ |
- return SQLITE_IOERR_NOMEM; |
+ return SQLITE_IOERR_NOMEM_BKPT; |
} |
#endif |
} |
@@ -5373,65 +5616,85 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ |
#define winDlClose 0 |
#endif |
+/* State information for the randomness gatherer. */ |
+typedef struct EntropyGatherer EntropyGatherer; |
+struct EntropyGatherer { |
+ unsigned char *a; /* Gather entropy into this buffer */ |
+ int na; /* Size of a[] in bytes */ |
+ int i; /* XOR next input into a[i] */ |
+ int nXor; /* Number of XOR operations done */ |
+}; |
+ |
+#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) |
+/* Mix sz bytes of entropy into p. */ |
+static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){ |
+ int j, k; |
+ for(j=0, k=p->i; j<sz; j++){ |
+ p->a[k++] ^= x[j]; |
+ if( k>=p->na ) k = 0; |
+ } |
+ p->i = k; |
+ p->nXor += sz; |
+} |
+#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */ |
/* |
** Write up to nBuf bytes of randomness into zBuf. |
*/ |
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
- int n = 0; |
- UNUSED_PARAMETER(pVfs); |
#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) |
- n = nBuf; |
+ UNUSED_PARAMETER(pVfs); |
memset(zBuf, 0, nBuf); |
+ return nBuf; |
#else |
- if( sizeof(SYSTEMTIME)<=nBuf-n ){ |
+ EntropyGatherer e; |
+ UNUSED_PARAMETER(pVfs); |
+ memset(zBuf, 0, nBuf); |
+#if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE |
+ rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */ |
+#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */ |
+ e.a = (unsigned char*)zBuf; |
+ e.na = nBuf; |
+ e.nXor = 0; |
+ e.i = 0; |
+ { |
SYSTEMTIME x; |
osGetSystemTime(&x); |
- memcpy(&zBuf[n], &x, sizeof(x)); |
- n += sizeof(x); |
+ xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME)); |
} |
- if( sizeof(DWORD)<=nBuf-n ){ |
+ { |
DWORD pid = osGetCurrentProcessId(); |
- memcpy(&zBuf[n], &pid, sizeof(pid)); |
- n += sizeof(pid); |
+ xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD)); |
} |
#if SQLITE_OS_WINRT |
- if( sizeof(ULONGLONG)<=nBuf-n ){ |
+ { |
ULONGLONG cnt = osGetTickCount64(); |
- memcpy(&zBuf[n], &cnt, sizeof(cnt)); |
- n += sizeof(cnt); |
+ xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG)); |
} |
#else |
- if( sizeof(DWORD)<=nBuf-n ){ |
+ { |
DWORD cnt = osGetTickCount(); |
- memcpy(&zBuf[n], &cnt, sizeof(cnt)); |
- n += sizeof(cnt); |
+ xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD)); |
} |
-#endif |
- if( sizeof(LARGE_INTEGER)<=nBuf-n ){ |
+#endif /* SQLITE_OS_WINRT */ |
+ { |
LARGE_INTEGER i; |
osQueryPerformanceCounter(&i); |
- memcpy(&zBuf[n], &i, sizeof(i)); |
- n += sizeof(i); |
+ xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER)); |
} |
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID |
- if( sizeof(UUID)<=nBuf-n ){ |
+ { |
UUID id; |
memset(&id, 0, sizeof(UUID)); |
osUuidCreate(&id); |
- memcpy(&zBuf[n], &id, sizeof(UUID)); |
- n += sizeof(UUID); |
- } |
- if( sizeof(UUID)<=nBuf-n ){ |
- UUID id; |
+ xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); |
memset(&id, 0, sizeof(UUID)); |
osUuidCreateSequential(&id); |
- memcpy(&zBuf[n], &id, sizeof(UUID)); |
- n += sizeof(UUID); |
+ xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); |
} |
-#endif |
-#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */ |
- return n; |
+#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */ |
+ return e.nXor>nBuf ? nBuf : e.nXor; |
+#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ |
} |
@@ -5547,8 +5810,10 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ |
** sqlite3_errmsg(), possibly making IO errors easier to debug. |
*/ |
static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
+ DWORD e = osGetLastError(); |
UNUSED_PARAMETER(pVfs); |
- return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); |
+ if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); |
+ return e; |
} |
/* |
@@ -5556,53 +5821,103 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
*/ |
int sqlite3_os_init(void){ |
static sqlite3_vfs winVfs = { |
- 3, /* iVersion */ |
- sizeof(winFile), /* szOsFile */ |
+ 3, /* iVersion */ |
+ sizeof(winFile), /* szOsFile */ |
SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ |
- 0, /* pNext */ |
- "win32", /* zName */ |
- 0, /* pAppData */ |
- winOpen, /* xOpen */ |
- winDelete, /* xDelete */ |
- winAccess, /* xAccess */ |
- winFullPathname, /* xFullPathname */ |
- winDlOpen, /* xDlOpen */ |
- winDlError, /* xDlError */ |
- winDlSym, /* xDlSym */ |
- winDlClose, /* xDlClose */ |
- winRandomness, /* xRandomness */ |
- winSleep, /* xSleep */ |
- winCurrentTime, /* xCurrentTime */ |
- winGetLastError, /* xGetLastError */ |
- winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
- winSetSystemCall, /* xSetSystemCall */ |
- winGetSystemCall, /* xGetSystemCall */ |
- winNextSystemCall, /* xNextSystemCall */ |
+ 0, /* pNext */ |
+ "win32", /* zName */ |
+ &winAppData, /* pAppData */ |
+ winOpen, /* xOpen */ |
+ winDelete, /* xDelete */ |
+ winAccess, /* xAccess */ |
+ winFullPathname, /* xFullPathname */ |
+ winDlOpen, /* xDlOpen */ |
+ winDlError, /* xDlError */ |
+ winDlSym, /* xDlSym */ |
+ winDlClose, /* xDlClose */ |
+ winRandomness, /* xRandomness */ |
+ winSleep, /* xSleep */ |
+ winCurrentTime, /* xCurrentTime */ |
+ winGetLastError, /* xGetLastError */ |
+ winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
+ winSetSystemCall, /* xSetSystemCall */ |
+ winGetSystemCall, /* xGetSystemCall */ |
+ winNextSystemCall, /* xNextSystemCall */ |
}; |
#if defined(SQLITE_WIN32_HAS_WIDE) |
static sqlite3_vfs winLongPathVfs = { |
- 3, /* iVersion */ |
- sizeof(winFile), /* szOsFile */ |
+ 3, /* iVersion */ |
+ sizeof(winFile), /* szOsFile */ |
+ SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ |
+ 0, /* pNext */ |
+ "win32-longpath", /* zName */ |
+ &winAppData, /* pAppData */ |
+ winOpen, /* xOpen */ |
+ winDelete, /* xDelete */ |
+ winAccess, /* xAccess */ |
+ winFullPathname, /* xFullPathname */ |
+ winDlOpen, /* xDlOpen */ |
+ winDlError, /* xDlError */ |
+ winDlSym, /* xDlSym */ |
+ winDlClose, /* xDlClose */ |
+ winRandomness, /* xRandomness */ |
+ winSleep, /* xSleep */ |
+ winCurrentTime, /* xCurrentTime */ |
+ winGetLastError, /* xGetLastError */ |
+ winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
+ winSetSystemCall, /* xSetSystemCall */ |
+ winGetSystemCall, /* xGetSystemCall */ |
+ winNextSystemCall, /* xNextSystemCall */ |
+ }; |
+#endif |
+ static sqlite3_vfs winNolockVfs = { |
+ 3, /* iVersion */ |
+ sizeof(winFile), /* szOsFile */ |
+ SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ |
+ 0, /* pNext */ |
+ "win32-none", /* zName */ |
+ &winNolockAppData, /* pAppData */ |
+ winOpen, /* xOpen */ |
+ winDelete, /* xDelete */ |
+ winAccess, /* xAccess */ |
+ winFullPathname, /* xFullPathname */ |
+ winDlOpen, /* xDlOpen */ |
+ winDlError, /* xDlError */ |
+ winDlSym, /* xDlSym */ |
+ winDlClose, /* xDlClose */ |
+ winRandomness, /* xRandomness */ |
+ winSleep, /* xSleep */ |
+ winCurrentTime, /* xCurrentTime */ |
+ winGetLastError, /* xGetLastError */ |
+ winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
+ winSetSystemCall, /* xSetSystemCall */ |
+ winGetSystemCall, /* xGetSystemCall */ |
+ winNextSystemCall, /* xNextSystemCall */ |
+ }; |
+#if defined(SQLITE_WIN32_HAS_WIDE) |
+ static sqlite3_vfs winLongPathNolockVfs = { |
+ 3, /* iVersion */ |
+ sizeof(winFile), /* szOsFile */ |
SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ |
- 0, /* pNext */ |
- "win32-longpath", /* zName */ |
- 0, /* pAppData */ |
- winOpen, /* xOpen */ |
- winDelete, /* xDelete */ |
- winAccess, /* xAccess */ |
- winFullPathname, /* xFullPathname */ |
- winDlOpen, /* xDlOpen */ |
- winDlError, /* xDlError */ |
- winDlSym, /* xDlSym */ |
- winDlClose, /* xDlClose */ |
- winRandomness, /* xRandomness */ |
- winSleep, /* xSleep */ |
- winCurrentTime, /* xCurrentTime */ |
- winGetLastError, /* xGetLastError */ |
- winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
- winSetSystemCall, /* xSetSystemCall */ |
- winGetSystemCall, /* xGetSystemCall */ |
- winNextSystemCall, /* xNextSystemCall */ |
+ 0, /* pNext */ |
+ "win32-longpath-none", /* zName */ |
+ &winNolockAppData, /* pAppData */ |
+ winOpen, /* xOpen */ |
+ winDelete, /* xDelete */ |
+ winAccess, /* xAccess */ |
+ winFullPathname, /* xFullPathname */ |
+ winDlOpen, /* xDlOpen */ |
+ winDlError, /* xDlError */ |
+ winDlSym, /* xDlSym */ |
+ winDlClose, /* xDlClose */ |
+ winRandomness, /* xRandomness */ |
+ winSleep, /* xSleep */ |
+ winCurrentTime, /* xCurrentTime */ |
+ winGetLastError, /* xGetLastError */ |
+ winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
+ winSetSystemCall, /* xSetSystemCall */ |
+ winGetSystemCall, /* xGetSystemCall */ |
+ winNextSystemCall, /* xNextSystemCall */ |
}; |
#endif |
@@ -5626,6 +5941,12 @@ int sqlite3_os_init(void){ |
sqlite3_vfs_register(&winLongPathVfs, 0); |
#endif |
+ sqlite3_vfs_register(&winNolockVfs, 0); |
+ |
+#if defined(SQLITE_WIN32_HAS_WIDE) |
+ sqlite3_vfs_register(&winLongPathNolockVfs, 0); |
+#endif |
+ |
return SQLITE_OK; |
} |