summaryrefslogtreecommitdiffstats
path: root/lib/libsqlite3/src/os_win.c
diff options
context:
space:
mode:
authorjturner <jturner@openbsd.org>2014-03-24 01:37:28 +0000
committerjturner <jturner@openbsd.org>2014-03-24 01:37:28 +0000
commit29ebcee2452a131560f5220abaf585648f84ce40 (patch)
tree844ef4fe135beff619b9e7b632f3b6722d6367e4 /lib/libsqlite3/src/os_win.c
parentannotate some packed structures with the alignment the hardware (diff)
downloadwireguard-openbsd-29ebcee2452a131560f5220abaf585648f84ce40.tar.xz
wireguard-openbsd-29ebcee2452a131560f5220abaf585648f84ce40.zip
Update sqlite to 3.8.4. A list of changes are available here:
http://sqlite.org/changes.html. Tested in a bulk and ok landry@
Diffstat (limited to 'lib/libsqlite3/src/os_win.c')
-rw-r--r--lib/libsqlite3/src/os_win.c1091
1 files changed, 796 insertions, 295 deletions
diff --git a/lib/libsqlite3/src/os_win.c b/lib/libsqlite3/src/os_win.c
index 10c4316448f..287dad3b571 100644
--- a/lib/libsqlite3/src/os_win.c
+++ b/lib/libsqlite3/src/os_win.c
@@ -17,7 +17,7 @@
#ifdef __CYGWIN__
# include <sys/cygwin.h>
-# include <errno.h>
+# include <errno.h> /* amalgamator: keep */
#endif
/*
@@ -30,7 +30,7 @@
** available in Windows platforms based on the NT kernel.
*/
#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
-# error "WAL mode requires support from the Windows NT kernel, compile\
+# error "WAL mode requires support from the Windows NT kernel, compile\
with SQLITE_OMIT_WAL."
#endif
@@ -38,7 +38,7 @@
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI)
# define SQLITE_WIN32_HAS_ANSI
#endif
@@ -46,11 +46,126 @@
** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
-#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
+#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \
+ !defined(SQLITE_WIN32_NO_WIDE)
# define SQLITE_WIN32_HAS_WIDE
#endif
/*
+** Make sure at least one set of Win32 APIs is available.
+*/
+#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE)
+# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\
+ must be defined."
+#endif
+
+/*
+** Define the required Windows SDK version constants if they are not
+** already available.
+*/
+#ifndef NTDDI_WIN8
+# define NTDDI_WIN8 0x06020000
+#endif
+
+#ifndef NTDDI_WINBLUE
+# define NTDDI_WINBLUE 0x06030000
+#endif
+
+/*
+** Check if the GetVersionEx[AW] functions should be considered deprecated
+** and avoid using them in that case. It should be noted here that if the
+** value of the SQLITE_WIN32_GETVERSIONEX pre-processor macro is zero
+** (whether via this block or via being manually specified), that implies
+** the underlying operating system will always be based on the Windows NT
+** Kernel.
+*/
+#ifndef SQLITE_WIN32_GETVERSIONEX
+# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE
+# define SQLITE_WIN32_GETVERSIONEX 0
+# else
+# define SQLITE_WIN32_GETVERSIONEX 1
+# endif
+#endif
+
+/*
+** This constant should already be defined (in the "WinDef.h" SDK file).
+*/
+#ifndef MAX_PATH
+# define MAX_PATH (260)
+#endif
+
+/*
+** Maximum pathname length (in chars) for Win32. This should normally be
+** MAX_PATH.
+*/
+#ifndef SQLITE_WIN32_MAX_PATH_CHARS
+# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH)
+#endif
+
+/*
+** This constant should already be defined (in the "WinNT.h" SDK file).
+*/
+#ifndef UNICODE_STRING_MAX_CHARS
+# define UNICODE_STRING_MAX_CHARS (32767)
+#endif
+
+/*
+** Maximum pathname length (in chars) for WinNT. This should normally be
+** UNICODE_STRING_MAX_CHARS.
+*/
+#ifndef SQLITE_WINNT_MAX_PATH_CHARS
+# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS)
+#endif
+
+/*
+** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in
+** characters, so we allocate 4 bytes per character assuming worst-case of
+** 4-bytes-per-character for UTF8.
+*/
+#ifndef SQLITE_WIN32_MAX_PATH_BYTES
+# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4)
+#endif
+
+/*
+** Maximum pathname length (in bytes) for WinNT. This should normally be
+** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR).
+*/
+#ifndef SQLITE_WINNT_MAX_PATH_BYTES
+# define SQLITE_WINNT_MAX_PATH_BYTES \
+ (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS)
+#endif
+
+/*
+** Maximum error message length (in chars) for WinRT.
+*/
+#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS
+# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024)
+#endif
+
+/*
+** Returns non-zero if the character should be treated as a directory
+** separator.
+*/
+#ifndef winIsDirSep
+# define winIsDirSep(a) (((a) == '/') || ((a) == '\\'))
+#endif
+
+/*
+** This macro is used when a local variable is set to a value that is
+** [sometimes] not used by the code (e.g. via conditional compilation).
+*/
+#ifndef UNUSED_VARIABLE_VALUE
+# define UNUSED_VARIABLE_VALUE(x) (void)(x)
+#endif
+
+/*
+** Returns the character that should be used as the directory separator.
+*/
+#ifndef winGetDirSep
+# define winGetDirSep() '\\'
+#endif
+
+/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
** are not present in the header file)?
@@ -101,7 +216,7 @@ WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif
#ifndef SQLITE_OMIT_WAL
-/* Forward references */
+/* Forward references to structures used for WAL */
typedef struct winShm winShm; /* A connection to shared-memory */
typedef struct winShmNode winShmNode; /* A region of shared-memory */
#endif
@@ -239,30 +354,41 @@ struct winFile {
typedef struct winMemData winMemData;
struct winMemData {
#ifndef NDEBUG
- u32 magic; /* Magic number to detect structure corruption. */
+ u32 magic1; /* Magic number to detect structure corruption. */
#endif
HANDLE hHeap; /* The handle to our heap. */
BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */
+#ifndef NDEBUG
+ u32 magic2; /* Magic number to detect structure corruption. */
+#endif
};
#ifndef NDEBUG
-#define WINMEM_MAGIC 0x42b2830b
+#define WINMEM_MAGIC1 0x42b2830b
+#define WINMEM_MAGIC2 0xbd4d7cf4
#endif
static struct winMemData win_mem_data = {
#ifndef NDEBUG
- WINMEM_MAGIC,
+ WINMEM_MAGIC1,
#endif
NULL, FALSE
+#ifndef NDEBUG
+ ,WINMEM_MAGIC2
+#endif
};
#ifndef NDEBUG
-#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
+#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 )
+#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 )
+#define winMemAssertMagic() winMemAssertMagic1(); winMemAssertMagic2();
#else
#define winMemAssertMagic()
#endif
-#define winMemGetHeap() win_mem_data.hHeap
+#define winMemGetDataPtr() &win_mem_data
+#define winMemGetHeap() win_mem_data.hHeap
+#define winMemGetOwned() win_mem_data.bOwned
static void *winMemMalloc(int nBytes);
static void winMemFree(void *pPrior);
@@ -289,7 +415,8 @@ const sqlite3_mem_methods *sqlite3MemGetWin32(void);
*/
#ifdef SQLITE_TEST
int sqlite3_os_type = 0;
-#else
+#elif !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
+ defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_HAS_WIDE)
static int sqlite3_os_type = 0;
#endif
@@ -595,7 +722,8 @@ static struct win_syscall {
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
-#if defined(SQLITE_WIN32_HAS_ANSI)
+#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
+ SQLITE_WIN32_GETVERSIONEX
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
#else
{ "GetVersionExA", (SYSCALL)0, 0 },
@@ -604,10 +732,20 @@ static struct win_syscall {
#define osGetVersionExA ((BOOL(WINAPI*)( \
LPOSVERSIONINFOA))aSyscall[34].pCurrent)
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+ defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
+ { "GetVersionExW", (SYSCALL)GetVersionExW, 0 },
+#else
+ { "GetVersionExW", (SYSCALL)0, 0 },
+#endif
+
+#define osGetVersionExW ((BOOL(WINAPI*)( \
+ LPOSVERSIONINFOW))aSyscall[35].pCurrent)
+
{ "HeapAlloc", (SYSCALL)HeapAlloc, 0 },
#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
- SIZE_T))aSyscall[35].pCurrent)
+ SIZE_T))aSyscall[36].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapCreate", (SYSCALL)HeapCreate, 0 },
@@ -616,7 +754,7 @@ static struct win_syscall {
#endif
#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
- SIZE_T))aSyscall[36].pCurrent)
+ SIZE_T))aSyscall[37].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapDestroy", (SYSCALL)HeapDestroy, 0 },
@@ -624,21 +762,21 @@ static struct win_syscall {
{ "HeapDestroy", (SYSCALL)0, 0 },
#endif
-#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
+#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent)
{ "HeapFree", (SYSCALL)HeapFree, 0 },
-#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
+#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent)
{ "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 },
#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
- SIZE_T))aSyscall[39].pCurrent)
+ SIZE_T))aSyscall[40].pCurrent)
{ "HeapSize", (SYSCALL)HeapSize, 0 },
#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
- LPCVOID))aSyscall[40].pCurrent)
+ LPCVOID))aSyscall[41].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapValidate", (SYSCALL)HeapValidate, 0 },
@@ -647,7 +785,15 @@ static struct win_syscall {
#endif
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
- LPCVOID))aSyscall[41].pCurrent)
+ LPCVOID))aSyscall[42].pCurrent)
+
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+ { "HeapCompact", (SYSCALL)HeapCompact, 0 },
+#else
+ { "HeapCompact", (SYSCALL)0, 0 },
+#endif
+
+#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
@@ -655,7 +801,7 @@ static struct win_syscall {
{ "LoadLibraryA", (SYSCALL)0, 0 },
#endif
-#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
+#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
!defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -664,7 +810,7 @@ static struct win_syscall {
{ "LoadLibraryW", (SYSCALL)0, 0 },
#endif
-#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
+#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
#if !SQLITE_OS_WINRT
{ "LocalFree", (SYSCALL)LocalFree, 0 },
@@ -672,7 +818,7 @@ static struct win_syscall {
{ "LocalFree", (SYSCALL)0, 0 },
#endif
-#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
+#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "LockFile", (SYSCALL)LockFile, 0 },
@@ -682,7 +828,7 @@ static struct win_syscall {
#ifndef osLockFile
#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[45].pCurrent)
+ DWORD))aSyscall[47].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@@ -693,7 +839,7 @@ static struct win_syscall {
#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[46].pCurrent)
+ LPOVERLAPPED))aSyscall[48].pCurrent)
#endif
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
@@ -703,26 +849,26 @@ static struct win_syscall {
#endif
#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- SIZE_T))aSyscall[47].pCurrent)
+ SIZE_T))aSyscall[49].pCurrent)
{ "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 },
#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
- int))aSyscall[48].pCurrent)
+ int))aSyscall[50].pCurrent)
{ "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
- LARGE_INTEGER*))aSyscall[49].pCurrent)
+ LARGE_INTEGER*))aSyscall[51].pCurrent)
{ "ReadFile", (SYSCALL)ReadFile, 0 },
#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[50].pCurrent)
+ LPOVERLAPPED))aSyscall[52].pCurrent)
{ "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 },
-#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
+#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
#if !SQLITE_OS_WINRT
{ "SetFilePointer", (SYSCALL)SetFilePointer, 0 },
@@ -731,7 +877,7 @@ static struct win_syscall {
#endif
#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
- DWORD))aSyscall[52].pCurrent)
+ DWORD))aSyscall[54].pCurrent)
#if !SQLITE_OS_WINRT
{ "Sleep", (SYSCALL)Sleep, 0 },
@@ -739,12 +885,12 @@ static struct win_syscall {
{ "Sleep", (SYSCALL)0, 0 },
#endif
-#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
+#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
{ "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 },
#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
- LPFILETIME))aSyscall[54].pCurrent)
+ LPFILETIME))aSyscall[56].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "UnlockFile", (SYSCALL)UnlockFile, 0 },
@@ -754,7 +900,7 @@ static struct win_syscall {
#ifndef osUnlockFile
#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[55].pCurrent)
+ DWORD))aSyscall[57].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@@ -764,7 +910,7 @@ static struct win_syscall {
#endif
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[56].pCurrent)
+ LPOVERLAPPED))aSyscall[58].pCurrent)
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
@@ -772,17 +918,17 @@ static struct win_syscall {
{ "UnmapViewOfFile", (SYSCALL)0, 0 },
#endif
-#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
+#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
{ "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 },
#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
- LPCSTR,LPBOOL))aSyscall[58].pCurrent)
+ LPCSTR,LPBOOL))aSyscall[60].pCurrent)
{ "WriteFile", (SYSCALL)WriteFile, 0 },
#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[59].pCurrent)
+ LPOVERLAPPED))aSyscall[61].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateEventExW", (SYSCALL)CreateEventExW, 0 },
@@ -791,7 +937,7 @@ static struct win_syscall {
#endif
#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
- DWORD,DWORD))aSyscall[60].pCurrent)
+ DWORD,DWORD))aSyscall[62].pCurrent)
#if !SQLITE_OS_WINRT
{ "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 },
@@ -800,7 +946,7 @@ static struct win_syscall {
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
- DWORD))aSyscall[61].pCurrent)
+ DWORD))aSyscall[63].pCurrent)
#if SQLITE_OS_WINRT
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
@@ -809,7 +955,7 @@ static struct win_syscall {
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
- BOOL))aSyscall[62].pCurrent)
+ BOOL))aSyscall[64].pCurrent)
#if SQLITE_OS_WINRT
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
@@ -818,7 +964,7 @@ static struct win_syscall {
#endif
#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
- PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent)
+ PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
#if SQLITE_OS_WINRT
{ "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
@@ -827,7 +973,7 @@ static struct win_syscall {
#endif
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
- FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent)
+ FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
@@ -836,7 +982,7 @@ static struct win_syscall {
#endif
#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
- SIZE_T))aSyscall[65].pCurrent)
+ SIZE_T))aSyscall[67].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFile2", (SYSCALL)CreateFile2, 0 },
@@ -845,7 +991,7 @@ static struct win_syscall {
#endif
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
- LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
+ LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
@@ -854,7 +1000,7 @@ static struct win_syscall {
#endif
#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
- DWORD))aSyscall[67].pCurrent)
+ DWORD))aSyscall[69].pCurrent)
#if SQLITE_OS_WINRT
{ "GetTickCount64", (SYSCALL)GetTickCount64, 0 },
@@ -862,7 +1008,7 @@ static struct win_syscall {
{ "GetTickCount64", (SYSCALL)0, 0 },
#endif
-#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent)
+#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
#if SQLITE_OS_WINRT
{ "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 },
@@ -871,7 +1017,7 @@ static struct win_syscall {
#endif
#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
- LPSYSTEM_INFO))aSyscall[69].pCurrent)
+ LPSYSTEM_INFO))aSyscall[71].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 },
@@ -879,7 +1025,7 @@ static struct win_syscall {
{ "OutputDebugStringA", (SYSCALL)0, 0 },
#endif
-#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent)
+#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 },
@@ -887,11 +1033,11 @@ static struct win_syscall {
{ "OutputDebugStringW", (SYSCALL)0, 0 },
#endif
-#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent)
+#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
{ "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 },
-#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent)
+#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
@@ -900,7 +1046,7 @@ static struct win_syscall {
#endif
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
- LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent)
+ LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
}; /* End of the overrideable system calls */
@@ -987,6 +1133,94 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
return 0;
}
+#ifdef SQLITE_WIN32_MALLOC
+/*
+** If a Win32 native heap has been configured, this function will attempt to
+** compact it. Upon success, SQLITE_OK will be returned. Upon failure, one
+** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned. The
+** "pnLargest" argument, if non-zero, will be used to return the size of the
+** largest committed free block in the heap, in bytes.
+*/
+int sqlite3_win32_compact_heap(LPUINT pnLargest){
+ int rc = SQLITE_OK;
+ UINT nLargest = 0;
+ HANDLE hHeap;
+
+ winMemAssertMagic();
+ hHeap = winMemGetHeap();
+ assert( hHeap!=0 );
+ assert( hHeap!=INVALID_HANDLE_VALUE );
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+#endif
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+ if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
+ DWORD lastErrno = osGetLastError();
+ if( lastErrno==NO_ERROR ){
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
+ (void*)hHeap);
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
+ osGetLastError(), (void*)hHeap);
+ rc = SQLITE_ERROR;
+ }
+ }
+#else
+ sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
+ (void*)hHeap);
+ rc = SQLITE_NOTFOUND;
+#endif
+ if( pnLargest ) *pnLargest = nLargest;
+ return rc;
+}
+
+/*
+** If a Win32 native heap has been configured, this function will attempt to
+** destroy and recreate it. If the Win32 native heap is not isolated and/or
+** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
+** be returned and no changes will be made to the Win32 native heap.
+*/
+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 = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
+ MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
+ sqlite3_mutex_enter(pMaster);
+ sqlite3_mutex_enter(pMem);
+ winMemAssertMagic();
+ if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
+ /*
+ ** At this point, there should be no outstanding memory allocations on
+ ** the heap. Also, since both the master and memsys locks are currently
+ ** being held by us, no other function (i.e. from another thread) should
+ ** be able to even access the heap. Attempt to destroy and recreate our
+ ** isolated Win32 native heap now.
+ */
+ assert( winMemGetHeap()!=NULL );
+ assert( winMemGetOwned() );
+ assert( sqlite3_memory_used()==0 );
+ winMemShutdown(winMemGetDataPtr());
+ assert( winMemGetHeap()==NULL );
+ assert( !winMemGetOwned() );
+ assert( sqlite3_memory_used()==0 );
+ rc = winMemInit(winMemGetDataPtr());
+ assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
+ assert( rc!=SQLITE_OK || winMemGetOwned() );
+ assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
+ }else{
+ /*
+ ** The Win32 native heap cannot be modified because it may be in use.
+ */
+ rc = SQLITE_BUSY;
+ }
+ sqlite3_mutex_leave(pMem);
+ sqlite3_mutex_leave(pMaster);
+ return rc;
+}
+#endif /* SQLITE_WIN32_MALLOC */
+
/*
** This function outputs the specified (ANSI) string to the Win32 debugger
** (if available).
@@ -1056,16 +1290,25 @@ void sqlite3_win32_sleep(DWORD milliseconds){
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
-#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
-# define isNT() (1)
+
+#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
+# define osIsNT() (1)
+#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
+# define osIsNT() (1)
#elif !defined(SQLITE_WIN32_HAS_WIDE)
-# define isNT() (0)
+# define osIsNT() (0)
#else
- static int isNT(void){
+ static int osIsNT(void){
if( sqlite3_os_type==0 ){
+#if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8
+ OSVERSIONINFOW sInfo;
+ sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+ osGetVersionExW(&sInfo);
+#else
OSVERSIONINFOA sInfo;
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
osGetVersionExA(&sInfo);
+#endif
sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
}
return sqlite3_os_type==2;
@@ -1085,12 +1328,12 @@ static void *winMemMalloc(int nBytes){
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
assert( nBytes>=0 );
p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
if( !p ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
nBytes, osGetLastError(), (void*)hHeap);
}
return p;
@@ -1107,11 +1350,11 @@ static void winMemFree(void *pPrior){
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
pPrior, osGetLastError(), (void*)hHeap);
}
}
@@ -1128,7 +1371,7 @@ static void *winMemRealloc(void *pPrior, int nBytes){
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
assert( nBytes>=0 );
if( !pPrior ){
@@ -1137,7 +1380,7 @@ static void *winMemRealloc(void *pPrior, int nBytes){
p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
}
if( !p ){
- sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p",
pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
(void*)hHeap);
}
@@ -1156,12 +1399,12 @@ static int winMemSize(void *p){
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) );
#endif
if( !p ) return 0;
n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
if( n==(SIZE_T)-1 ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
p, osGetLastError(), (void*)hHeap);
return 0;
}
@@ -1182,18 +1425,25 @@ static int winMemInit(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return SQLITE_ERROR;
- assert( pWinMemData->magic==WINMEM_MAGIC );
+ assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+ assert( pWinMemData->magic2==WINMEM_MAGIC2 );
#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
if( !pWinMemData->hHeap ){
+ DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
+ DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
+ if( dwMaximumSize==0 ){
+ dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
+ }else if( dwInitialSize>dwMaximumSize ){
+ dwInitialSize = dwMaximumSize;
+ }
pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
- SQLITE_WIN32_HEAP_INIT_SIZE,
- SQLITE_WIN32_HEAP_MAX_SIZE);
+ dwInitialSize, dwMaximumSize);
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
- "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
- osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
- SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
+ "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
+ osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
+ dwMaximumSize);
return SQLITE_NOMEM;
}
pWinMemData->bOwned = TRUE;
@@ -1203,7 +1453,7 @@ static int winMemInit(void *pAppData){
pWinMemData->hHeap = osGetProcessHeap();
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
- "failed to GetProcessHeap (%d)", osGetLastError());
+ "failed to GetProcessHeap (%lu)", osGetLastError());
return SQLITE_NOMEM;
}
pWinMemData->bOwned = FALSE;
@@ -1224,6 +1474,9 @@ static void winMemShutdown(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return;
+ assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+ assert( pWinMemData->magic2==WINMEM_MAGIC2 );
+
if( pWinMemData->hHeap ){
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
@@ -1231,7 +1484,7 @@ static void winMemShutdown(void *pAppData){
#endif
if( pWinMemData->bOwned ){
if( !osHeapDestroy(pWinMemData->hHeap) ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p",
osGetLastError(), (void*)pWinMemData->hHeap);
}
pWinMemData->bOwned = FALSE;
@@ -1272,7 +1525,7 @@ void sqlite3MemSetDefault(void){
**
** Space to hold the returned string is obtained from malloc.
*/
-static LPWSTR utf8ToUnicode(const char *zFilename){
+static LPWSTR winUtf8ToUnicode(const char *zFilename){
int nChar;
LPWSTR zWideFilename;
@@ -1297,7 +1550,7 @@ static LPWSTR utf8ToUnicode(const char *zFilename){
** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is
** obtained from sqlite3_malloc().
*/
-static char *unicodeToUtf8(LPCWSTR zWideFilename){
+static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
int nByte;
char *zFilename;
@@ -1325,7 +1578,7 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){
** Space to hold the returned string is obtained
** from sqlite3_malloc.
*/
-static LPWSTR mbcsToUnicode(const char *zFilename){
+static LPWSTR winMbcsToUnicode(const char *zFilename){
int nByte;
LPWSTR zMbcsFilename;
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
@@ -1355,7 +1608,7 @@ static LPWSTR mbcsToUnicode(const char *zFilename){
** Space to hold the returned string is obtained from
** sqlite3_malloc().
*/
-static char *unicodeToMbcs(LPCWSTR zWideFilename){
+static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
int nByte;
char *zFilename;
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
@@ -1385,11 +1638,11 @@ char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
char *zFilenameUtf8;
LPWSTR zTmpWide;
- zTmpWide = mbcsToUnicode(zFilename);
+ zTmpWide = winMbcsToUnicode(zFilename);
if( zTmpWide==0 ){
return 0;
}
- zFilenameUtf8 = unicodeToUtf8(zTmpWide);
+ zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
sqlite3_free(zTmpWide);
return zFilenameUtf8;
}
@@ -1402,11 +1655,11 @@ char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
char *zFilenameMbcs;
LPWSTR zTmpWide;
- zTmpWide = utf8ToUnicode(zFilename);
+ zTmpWide = winUtf8ToUnicode(zFilename);
if( zTmpWide==0 ){
return 0;
}
- zFilenameMbcs = unicodeToMbcs(zTmpWide);
+ zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
sqlite3_free(zTmpWide);
return zFilenameMbcs;
}
@@ -1436,7 +1689,7 @@ int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
if( ppDirectory ){
char *zValueUtf8 = 0;
if( zValue && zValue[0] ){
- zValueUtf8 = unicodeToUtf8(zValue);
+ zValueUtf8 = winUnicodeToUtf8(zValue);
if ( zValueUtf8==0 ){
return SQLITE_NOMEM;
}
@@ -1449,11 +1702,11 @@ int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
}
/*
-** The return value of getLastErrorMsg
+** The return value of winGetLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero
** otherwise (if the message was truncated).
*/
-static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
+static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
/* FormatMessage returns 0 on failure. Otherwise it
** returns the number of TCHARs written to the output
** buffer, excluding the terminating null char.
@@ -1461,16 +1714,16 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
DWORD dwLen = 0;
char *zOut = 0;
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINRT
- WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */
+ WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1];
dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
zTempWide,
- MAX_PATH,
+ SQLITE_WIN32_MAX_ERRMSG_CHARS,
0);
#else
LPWSTR zTempWide = NULL;
@@ -1487,7 +1740,7 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
- zOut = unicodeToUtf8(zTempWide);
+ zOut = winUnicodeToUtf8(zTempWide);
sqlite3EndBenignMalloc();
#if !SQLITE_OS_WINRT
/* free the system buffer allocated by FormatMessage */
@@ -1555,7 +1808,7 @@ static int winLogErrorAtLine(
int i; /* Loop counter */
zMsg[0] = 0;
- getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
+ winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
assert( errcode!=SQLITE_OK );
if( zPath==0 ) zPath = "";
for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
@@ -1580,17 +1833,17 @@ static int winLogErrorAtLine(
#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
#endif
-static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY;
-static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
+static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
+static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
/*
** If a ReadFile() or WriteFile() error occurs, invoke this routine
** to see if it should be retried. Return TRUE to retry. Return FALSE
** to give up with an error.
*/
-static int retryIoerr(int *pnRetry, DWORD *pError){
+static int winRetryIoerr(int *pnRetry, DWORD *pError){
DWORD e = osGetLastError();
- if( *pnRetry>=win32IoerrRetry ){
+ if( *pnRetry>=winIoerrRetry ){
if( pError ){
*pError = e;
}
@@ -1599,7 +1852,7 @@ static int retryIoerr(int *pnRetry, DWORD *pError){
if( e==ERROR_ACCESS_DENIED ||
e==ERROR_LOCK_VIOLATION ||
e==ERROR_SHARING_VIOLATION ){
- sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry));
+ sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
++*pnRetry;
return 1;
}
@@ -1612,11 +1865,11 @@ static int retryIoerr(int *pnRetry, DWORD *pError){
/*
** Log a I/O error retry episode.
*/
-static void logIoerr(int nRetry){
+static void winLogIoerr(int nRetry){
if( nRetry ){
sqlite3_log(SQLITE_IOERR,
"delayed %dms for lock/sharing conflict",
- win32IoerrRetryDelay*nRetry*(nRetry+1)/2
+ winIoerrRetryDelay*nRetry*(nRetry+1)/2
);
}
}
@@ -1681,7 +1934,7 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){
BOOL bLogged = FALSE;
BOOL bInit = TRUE;
- zName = utf8ToUnicode(zFilename);
+ zName = winUtf8ToUnicode(zFilename);
if( zName==0 ){
/* out of memory */
return SQLITE_IOERR_NOMEM;
@@ -1701,10 +1954,9 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){
pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
if (!pFile->hMutex){
pFile->lastErrno = osGetLastError();
- winLogError(SQLITE_IOERR, pFile->lastErrno,
- "winceCreateLock1", zFilename);
sqlite3_free(zName);
- return SQLITE_IOERR;
+ return winLogError(SQLITE_IOERR, pFile->lastErrno,
+ "winceCreateLock1", zFilename);
}
/* Acquire the mutex before continuing */
@@ -1954,7 +2206,7 @@ static BOOL winLockFile(
return winceLockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
- if( isNT() ){
+ if( osIsNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
@@ -1985,7 +2237,7 @@ static BOOL winUnlockFile(
return winceUnlockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
- if( isNT() ){
+ if( osIsNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
@@ -2015,7 +2267,7 @@ static BOOL winUnlockFile(
** argument to offset iOffset within the file. If successful, return 0.
** Otherwise, set pFile->lastErrno and return non-zero.
*/
-static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
+static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){
#if !SQLITE_OS_WINRT
LONG upperBits; /* Most sig. 32 bits of new offset */
LONG lowerBits; /* Least sig. 32 bits of new offset */
@@ -2040,7 +2292,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
&& ((lastErrno = osGetLastError())!=NO_ERROR)) ){
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
- "seekWinFile", pFile->zPath);
+ "winSeekFile", pFile->zPath);
OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
return 1;
}
@@ -2061,7 +2313,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
if(!bRet){
pFile->lastErrno = osGetLastError();
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
- "seekWinFile", pFile->zPath);
+ "winSeekFile", pFile->zPath);
OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
return 1;
}
@@ -2072,7 +2324,8 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
}
#if SQLITE_MAX_MMAP_SIZE>0
-/* Forward references to VFS methods */
+/* Forward references to VFS helper methods used for memory mapped files */
+static int winMapfile(winFile*, sqlite3_int64);
static int winUnmapfile(winFile*);
#endif
@@ -2099,8 +2352,7 @@ static int winClose(sqlite3_file *id){
OSTRACE(("CLOSE file=%p\n", pFile->h));
#if SQLITE_MAX_MMAP_SIZE>0
- rc = winUnmapfile(pFile);
- if( rc!=SQLITE_OK ) return rc;
+ winUnmapfile(pFile);
#endif
do{
@@ -2176,7 +2428,7 @@ static int winRead(
#endif
#if SQLITE_OS_WINCE
- if( seekWinFile(pFile, offset) ){
+ if( winSeekFile(pFile, offset) ){
OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
return SQLITE_FULL;
}
@@ -2189,13 +2441,13 @@ static int winRead(
osGetLastError()!=ERROR_HANDLE_EOF ){
#endif
DWORD lastErrno;
- if( retryIoerr(&nRetry, &lastErrno) ) continue;
+ if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
pFile->lastErrno = lastErrno;
OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h));
return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
- "winRead", pFile->zPath);
+ "winRead", pFile->zPath);
}
- logIoerr(nRetry);
+ winLogIoerr(nRetry);
if( nRead<(DWORD)amt ){
/* Unread parts of the buffer must be zero-filled */
memset(&((char*)pBuf)[nRead], 0, amt-nRead);
@@ -2248,7 +2500,7 @@ static int winWrite(
#endif
#if SQLITE_OS_WINCE
- rc = seekWinFile(pFile, offset);
+ rc = winSeekFile(pFile, offset);
if( rc==0 ){
#else
{
@@ -2273,7 +2525,7 @@ static int winWrite(
#else
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
#endif
- if( retryIoerr(&nRetry, &lastErrno) ) continue;
+ if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
break;
}
assert( nWrite==0 || nWrite<=(DWORD)nRem );
@@ -2299,13 +2551,14 @@ static int winWrite(
if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
|| ( pFile->lastErrno==ERROR_DISK_FULL )){
OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h));
- return SQLITE_FULL;
+ return winLogError(SQLITE_FULL, pFile->lastErrno,
+ "winWrite1", pFile->zPath);
}
OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h));
return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
- "winWrite", pFile->zPath);
+ "winWrite2", pFile->zPath);
}else{
- logIoerr(nRetry);
+ winLogIoerr(nRetry);
}
OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
@@ -2334,7 +2587,7 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
}
/* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
- if( seekWinFile(pFile, nByte) ){
+ if( winSeekFile(pFile, nByte) ){
rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
"winTruncate1", pFile->zPath);
}else if( 0==osSetEndOfFile(pFile->h) &&
@@ -2415,6 +2668,7 @@ static int winSync(sqlite3_file *id, int flags){
** no-op
*/
#ifdef SQLITE_NO_SYNC
+ OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
#else
rc = osFlushFileBuffers(pFile->h);
@@ -2426,7 +2680,7 @@ static int winSync(sqlite3_file *id, int flags){
pFile->lastErrno = osGetLastError();
OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h));
return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
- "winSync", pFile->zPath);
+ "winSync", pFile->zPath);
}
#endif
}
@@ -2467,7 +2721,7 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
&& ((lastErrno = osGetLastError())!=NO_ERROR) ){
pFile->lastErrno = lastErrno;
rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
- "winFileSize", pFile->zPath);
+ "winFileSize", pFile->zPath);
}
}
#endif
@@ -2512,10 +2766,10 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
** Different API routines are called depending on whether or not this
** is Win9x or WinNT.
*/
-static int getReadLock(winFile *pFile){
+static int winGetReadLock(winFile *pFile){
int res;
OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINCE
/*
** NOTE: Windows CE is handled differently here due its lack of the Win32
@@ -2547,11 +2801,11 @@ static int getReadLock(winFile *pFile){
/*
** Undo a readlock
*/
-static int unlockReadLock(winFile *pFile){
+static int winUnlockReadLock(winFile *pFile){
int res;
DWORD lastErrno;
OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
- if( isNT() ){
+ if( osIsNT() ){
res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
}
#ifdef SQLITE_WIN32_HAS_ANSI
@@ -2562,7 +2816,7 @@ static int unlockReadLock(winFile *pFile){
if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
- "unlockReadLock", pFile->zPath);
+ "winUnlockReadLock", pFile->zPath);
}
OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
return res;
@@ -2653,7 +2907,7 @@ static int winLock(sqlite3_file *id, int locktype){
*/
if( locktype==SHARED_LOCK && res ){
assert( pFile->locktype==NO_LOCK );
- res = getReadLock(pFile);
+ res = winGetReadLock(pFile);
if( res ){
newLocktype = SHARED_LOCK;
}else{
@@ -2684,14 +2938,14 @@ static int winLock(sqlite3_file *id, int locktype){
*/
if( locktype==EXCLUSIVE_LOCK && res ){
assert( pFile->locktype>=SHARED_LOCK );
- res = unlockReadLock(pFile);
+ res = winUnlockReadLock(pFile);
res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
SHARED_SIZE, 0);
if( res ){
newLocktype = EXCLUSIVE_LOCK;
}else{
lastErrno = osGetLastError();
- getReadLock(pFile);
+ winGetReadLock(pFile);
}
}
@@ -2708,10 +2962,10 @@ static int winLock(sqlite3_file *id, int locktype){
if( res ){
rc = SQLITE_OK;
}else{
- OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
- pFile->h, locktype, newLocktype));
pFile->lastErrno = lastErrno;
rc = SQLITE_BUSY;
+ OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
+ pFile->h, locktype, newLocktype));
}
pFile->locktype = (u8)newLocktype;
OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
@@ -2771,18 +3025,18 @@ static int winUnlock(sqlite3_file *id, int locktype){
type = pFile->locktype;
if( type>=EXCLUSIVE_LOCK ){
winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
- if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
+ if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
/* This should never happen. We should always be able to
** reacquire the read lock */
rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
- "winUnlock", pFile->zPath);
+ "winUnlock", pFile->zPath);
}
}
if( type>=RESERVED_LOCK ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
if( locktype==NO_LOCK && type>=SHARED_LOCK ){
- unlockReadLock(pFile);
+ winUnlockReadLock(pFile);
}
if( type>=PENDING_LOCK ){
winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
@@ -2809,11 +3063,10 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
}
}
-/* Forward declaration */
-static int getTempname(int nBuf, char *zBuf);
-#if SQLITE_MAX_MMAP_SIZE>0
-static int winMapfile(winFile*, sqlite3_int64);
-#endif
+/* Forward references to VFS helper methods used for temporary files */
+static int winGetTempname(sqlite3_vfs *, char **);
+static int winIsDir(const void *);
+static BOOL winIsDriveLetterAndColon(const char *);
/*
** Control and query of the open file handle.
@@ -2866,33 +3119,33 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
return SQLITE_OK;
}
case SQLITE_FCNTL_VFSNAME: {
- *(char**)pArg = sqlite3_mprintf("win32");
+ *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_FCNTL_WIN32_AV_RETRY: {
int *a = (int*)pArg;
if( a[0]>0 ){
- win32IoerrRetry = a[0];
+ winIoerrRetry = a[0];
}else{
- a[0] = win32IoerrRetry;
+ a[0] = winIoerrRetry;
}
if( a[1]>0 ){
- win32IoerrRetryDelay = a[1];
+ winIoerrRetryDelay = a[1];
}else{
- a[1] = win32IoerrRetryDelay;
+ a[1] = winIoerrRetryDelay;
}
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
- char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
- if( zTFile ){
- getTempname(pFile->pVfs->mxPathname, zTFile);
+ char *zTFile = 0;
+ int rc = winGetTempname(pFile->pVfs, &zTFile);
+ if( rc==SQLITE_OK ){
*(char**)pArg = zTFile;
}
- OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
- return SQLITE_OK;
+ OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+ return rc;
}
#if SQLITE_MAX_MMAP_SIZE>0
case SQLITE_FCNTL_MMAP_SIZE: {
@@ -2905,11 +3158,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
pFile->mmapSizeMax = newLimit;
if( pFile->mmapSize>0 ){
- (void)winUnmapfile(pFile);
+ winUnmapfile(pFile);
rc = winMapfile(pFile, -1);
}
}
- OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc));
+ OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
return rc;
}
#endif
@@ -2948,7 +3201,7 @@ static int winDeviceCharacteristics(sqlite3_file *id){
** During sqlite3_os_init() we do a GetSystemInfo()
** to get the granularity size.
*/
-SYSTEM_INFO winSysInfo;
+static SYSTEM_INFO winSysInfo;
#ifndef SQLITE_OMIT_WAL
@@ -2971,7 +3224,7 @@ static void winShmEnterMutex(void){
static void winShmLeaveMutex(void){
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
-#ifdef SQLITE_DEBUG
+#ifndef NDEBUG
static int winShmMutexHeld(void) {
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
@@ -3115,7 +3368,6 @@ static int winDelete(sqlite3_vfs *,const char*,int);
static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
winShmNode **pp;
winShmNode *p;
- BOOL bRc;
assert( winShmMutexHeld() );
OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
osGetCurrentProcessId(), deleteFlag));
@@ -3123,14 +3375,16 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
while( (p = *pp)!=0 ){
if( p->nRef==0 ){
int i;
- if( p->mutex ) sqlite3_mutex_free(p->mutex);
+ if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
for(i=0; i<p->nRegion; i++){
- bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
+ BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
+ UNUSED_VARIABLE_VALUE(bRc);
bRc = osCloseHandle(p->aRegion[i].hMap);
OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
+ UNUSED_VARIABLE_VALUE(bRc);
}
if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
SimulateIOErrorBenign(1);
@@ -3225,7 +3479,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
if( rc!=SQLITE_OK ){
rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
- "winOpenShm", pDbFd->zPath);
+ "winOpenShm", pDbFd->zPath);
}
}
if( rc==SQLITE_OK ){
@@ -3485,7 +3739,7 @@ static int winShmMap(
rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
if( rc!=SQLITE_OK ){
rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
- "winShmMap1", pDbFd->zPath);
+ "winShmMap1", pDbFd->zPath);
goto shmpage_out;
}
@@ -3500,7 +3754,7 @@ static int winShmMap(
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
if( rc!=SQLITE_OK ){
rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
- "winShmMap2", pDbFd->zPath);
+ "winShmMap2", pDbFd->zPath);
goto shmpage_out;
}
}
@@ -3554,7 +3808,7 @@ static int winShmMap(
if( !pMap ){
pShmNode->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
- "winShmMap3", pDbFd->zPath);
+ "winShmMap3", pDbFd->zPath);
if( hMap ) osCloseHandle(hMap);
goto shmpage_out;
}
@@ -3602,7 +3856,7 @@ static int winUnmapfile(winFile *pFile){
"rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
pFile->pMapRegion));
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
- "winUnmap1", pFile->zPath);
+ "winUnmapfile1", pFile->zPath);
}
pFile->pMapRegion = 0;
pFile->mmapSize = 0;
@@ -3614,7 +3868,7 @@ static int winUnmapfile(winFile *pFile){
OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
osGetCurrentProcessId(), pFile, pFile->hMap));
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
- "winUnmap2", pFile->zPath);
+ "winUnmapfile2", pFile->zPath);
}
pFile->hMap = NULL;
}
@@ -3689,10 +3943,10 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
if( pFd->hMap==NULL ){
pFd->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
- "winMapfile", pFd->zPath);
+ "winMapfile1", pFd->zPath);
/* Log the error, but continue normal operation using xRead/xWrite */
- OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
- osGetCurrentProcessId(), pFd));
+ OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
+ osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
return SQLITE_OK;
}
assert( (nMap % winSysInfo.dwPageSize)==0 );
@@ -3706,10 +3960,11 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
osCloseHandle(pFd->hMap);
pFd->hMap = NULL;
pFd->lastErrno = osGetLastError();
- winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
- "winMapfile", pFd->zPath);
- OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
- osGetCurrentProcessId(), pFd));
+ rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
+ "winMapfile2", pFd->zPath);
+ /* Log the error, but continue normal operation using xRead/xWrite */
+ OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
+ osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
return SQLITE_OK;
}
pFd->pMapRegion = pNew;
@@ -3848,16 +4103,37 @@ static const sqlite3_io_methods winIoMethod = {
** sqlite3_vfs object.
*/
+#if defined(__CYGWIN__)
+/*
+** Convert a filename from whatever the underlying operating system
+** supports for filenames into UTF-8. Space to hold the result is
+** obtained from malloc and must be freed by the calling function.
+*/
+static char *winConvertToUtf8Filename(const void *zFilename){
+ char *zConverted = 0;
+ if( osIsNT() ){
+ zConverted = winUnicodeToUtf8(zFilename);
+ }
+#ifdef SQLITE_WIN32_HAS_ANSI
+ else{
+ zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
+ }
+#endif
+ /* caller will handle out of memory */
+ return zConverted;
+}
+#endif
+
/*
** Convert a UTF-8 filename into whatever form the underlying
** operating system wants filenames in. Space to hold the result
** is obtained from malloc and must be freed by the calling
** function.
*/
-static void *convertUtf8Filename(const char *zFilename){
+static void *winConvertFromUtf8Filename(const char *zFilename){
void *zConverted = 0;
- if( isNT() ){
- zConverted = utf8ToUnicode(zFilename);
+ if( osIsNT() ){
+ zConverted = winUtf8ToUnicode(zFilename);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
@@ -3869,26 +4145,39 @@ static void *convertUtf8Filename(const char *zFilename){
}
/*
-** Maximum pathname length (in bytes) for windows. The MAX_PATH macro is
-** in characters, so we allocate 3 bytes per character assuming worst-case
-** 3-bytes-per-character UTF8.
+** This function returns non-zero if the specified UTF-8 string buffer
+** ends with a directory separator character or one was successfully
+** added to it.
*/
-#ifndef SQLITE_WIN32_MAX_PATH
-# define SQLITE_WIN32_MAX_PATH (MAX_PATH*3)
-#endif
+static int winMakeEndInDirSep(int nBuf, char *zBuf){
+ if( zBuf ){
+ int nLen = sqlite3Strlen30(zBuf);
+ if( nLen>0 ){
+ if( winIsDirSep(zBuf[nLen-1]) ){
+ return 1;
+ }else if( nLen+1<nBuf ){
+ zBuf[nLen] = winGetDirSep();
+ zBuf[nLen+1] = '\0';
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
/*
-** Create a temporary file name in zBuf. zBuf must be big enough to
-** hold at pVfs->mxPathname characters.
+** Create a temporary file name and store the resulting pointer into pzBuf.
+** The pointer returned in pzBuf must be freed via sqlite3_free().
*/
-static int getTempname(int nBuf, char *zBuf){
+static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
size_t i, j;
- int nTempPath;
- char zTempPath[SQLITE_WIN32_MAX_PATH+2];
+ int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
+ int nMax, nBuf, nDir, nLen;
+ char *zBuf;
/* 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
@@ -3896,23 +4185,140 @@ static int getTempname(int nBuf, char *zBuf){
*/
SimulateIOError( return SQLITE_IOERR );
+ /* Allocate a temporary buffer to store the fully qualified file
+ ** name for the temporary file. If this fails, we cannot continue.
+ */
+ nMax = pVfs->mxPathname; nBuf = nMax + 2;
+ zBuf = sqlite3MallocZero( nBuf );
+ if( !zBuf ){
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+
+ /* Figure out the effective temporary directory. First, check if one
+ ** has been explicitly set by the application; otherwise, use the one
+ ** configured by the operating system.
+ */
+ nDir = nMax - (nPre + 15);
+ assert( nDir>0 );
if( sqlite3_temp_directory ){
- sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s",
- sqlite3_temp_directory);
+ int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
+ if( nDirLen>0 ){
+ if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
+ nDirLen++;
+ }
+ if( nDirLen>nDir ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
+ }
+ sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
+ }
}
-#if !SQLITE_OS_WINRT
- else if( isNT() ){
+#if defined(__CYGWIN__)
+ else{
+ static const char *azDirs[] = {
+ 0, /* getenv("SQLITE_TMPDIR") */
+ 0, /* getenv("TMPDIR") */
+ 0, /* getenv("TMP") */
+ 0, /* getenv("TEMP") */
+ 0, /* getenv("USERPROFILE") */
+ "/var/tmp",
+ "/usr/tmp",
+ "/tmp",
+ ".",
+ 0 /* List terminator */
+ };
+ unsigned int i;
+ const char *zDir = 0;
+
+ if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
+ if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
+ if( !azDirs[2] ) azDirs[2] = getenv("TMP");
+ if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
+ if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
+ for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
+ void *zConverted;
+ if( zDir==0 ) continue;
+ /* If the path starts with a drive letter followed by the colon
+ ** character, assume it is already a native Win32 path; otherwise,
+ ** it must be converted to a native Win32 path via the Cygwin API
+ ** prior to using it.
+ */
+ if( winIsDriveLetterAndColon(zDir) ){
+ zConverted = winConvertFromUtf8Filename(zDir);
+ if( !zConverted ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( winIsDir(zConverted) ){
+ sqlite3_snprintf(nMax, zBuf, "%s", zDir);
+ sqlite3_free(zConverted);
+ break;
+ }
+ sqlite3_free(zConverted);
+ }else{
+ zConverted = sqlite3MallocZero( nMax+1 );
+ if( !zConverted ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
+ zConverted, nMax+1)<0 ){
+ sqlite3_free(zConverted);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
+ return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
+ "winGetTempname2", zDir);
+ }
+ if( winIsDir(zConverted) ){
+ /* At this point, we know the candidate directory exists and should
+ ** be used. However, we may need to convert the string containing
+ ** its name into UTF-8 (i.e. if it is UTF-16 right now).
+ */
+ char *zUtf8 = winConvertToUtf8Filename(zConverted);
+ if( !zUtf8 ){
+ sqlite3_free(zConverted);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zConverted);
+ break;
+ }
+ sqlite3_free(zConverted);
+ }
+ }
+ }
+#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
+ else if( osIsNT() ){
char *zMulti;
- WCHAR zWidePath[MAX_PATH];
- if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){
+ LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
+ if( !zWidePath ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( osGetTempPathW(nMax, zWidePath)==0 ){
+ sqlite3_free(zWidePath);
+ sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
- return SQLITE_IOERR_GETTEMPPATH;
+ return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+ "winGetTempname2", 0);
}
- zMulti = unicodeToUtf8(zWidePath);
+ zMulti = winUnicodeToUtf8(zWidePath);
if( zMulti ){
- sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti);
+ sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
sqlite3_free(zMulti);
+ sqlite3_free(zWidePath);
}else{
+ sqlite3_free(zWidePath);
+ sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM;
}
@@ -3920,55 +4326,62 @@ static int getTempname(int nBuf, char *zBuf){
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zUtf8;
- char zMbcsPath[SQLITE_WIN32_MAX_PATH];
- if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){
+ char *zMbcsPath = sqlite3MallocZero( nMax );
+ if( !zMbcsPath ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( osGetTempPathA(nMax, zMbcsPath)==0 ){
+ sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
- return SQLITE_IOERR_GETTEMPPATH;
+ return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+ "winGetTempname3", 0);
}
zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
if( zUtf8 ){
- sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", 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;
}
}
-#else
- else{
- /*
- ** Compiled without ANSI support and the current operating system
- ** is not Windows NT; therefore, just zero the temporary buffer.
- */
- memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
- }
#endif /* SQLITE_WIN32_HAS_ANSI */
-#else
- else{
- /*
- ** Compiled for WinRT and the sqlite3_temp_directory is not set;
- ** therefore, just zero the temporary buffer.
- */
- memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
- }
#endif /* !SQLITE_OS_WINRT */
- /* Check that the output buffer is large enough for the temporary file
- ** name. If it is not, return SQLITE_ERROR.
+ /*
+ ** Check to make sure the temporary directory ends with an appropriate
+ ** separator. If it does not and there is not enough space left to add
+ ** one, fail.
*/
- nTempPath = sqlite3Strlen30(zTempPath);
+ if( !winMakeEndInDirSep(nDir+1, zBuf) ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
+ }
- if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
+ /*
+ ** Check that the output buffer is large enough for the temporary file
+ ** name in the following format:
+ **
+ ** "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
+ **
+ ** If not, return SQLITE_ERROR. The number 17 is used here in order to
+ ** account for the space used by the 15 character random suffix and the
+ ** two trailing NUL characters. The final directory separator character
+ ** has already added if it was not already present.
+ */
+ nLen = sqlite3Strlen30(zBuf);
+ if( (nLen + nPre + 17) > nBuf ){
+ sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
- return SQLITE_ERROR;
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
}
- for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){}
- zTempPath[i] = 0;
+ sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
- sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ?
- "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX,
- zTempPath);
j = sqlite3Strlen30(zBuf);
sqlite3_randomness(15, &zBuf[j]);
for(i=0; i<15; i++, j++){
@@ -3976,6 +4389,7 @@ static int getTempname(int nBuf, char *zBuf){
}
zBuf[j] = 0;
zBuf[j+1] = 0;
+ *pzBuf = zBuf;
OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
return SQLITE_OK;
@@ -3991,13 +4405,13 @@ static int winIsDir(const void *zConverted){
int rc = 0;
DWORD lastErrno;
- if( isNT() ){
+ if( osIsNT() ){
int cnt = 0;
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
GetFileExInfoStandard,
- &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
+ &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
if( !rc ){
return 0; /* Invalid name? */
}
@@ -4014,14 +4428,14 @@ static int winIsDir(const void *zConverted){
** Open a file.
*/
static int winOpen(
- sqlite3_vfs *pVfs, /* Not used */
+ sqlite3_vfs *pVfs, /* Used to get maximum path name length */
const char *zName, /* Name of the file (UTF-8) */
sqlite3_file *id, /* Write the SQLite file handle here */
int flags, /* Open mode flags */
int *pOutFlags /* Status return flags */
){
HANDLE h;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
DWORD dwDesiredAccess;
DWORD dwShareMode;
DWORD dwCreationDisposition;
@@ -4037,7 +4451,7 @@ static int winOpen(
/* If argument zPath is a NULL pointer, this function is required to open
** a temporary file. Use this buffer to store the file name in.
*/
- char zTmpname[SQLITE_WIN32_MAX_PATH+2]; /* Buffer used to create temp filename */
+ char *zTmpname = 0; /* For temporary filename, if necessary. */
int rc = SQLITE_OK; /* Function Return Code */
#if !defined(NDEBUG) || SQLITE_OS_WINCE
@@ -4092,7 +4506,7 @@ static int winOpen(
pFile->h = INVALID_HANDLE_VALUE;
#if SQLITE_OS_WINRT
- if( !sqlite3_temp_directory ){
+ if( !zUtf8Name && !sqlite3_temp_directory ){
sqlite3_log(SQLITE_ERROR,
"sqlite3_temp_directory variable should be set for WinRT");
}
@@ -4102,8 +4516,8 @@ static int winOpen(
** temporary file name to use
*/
if( !zUtf8Name ){
- assert(isDelete && !isOpenJournal);
- rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname);
+ assert( isDelete && !isOpenJournal );
+ rc = winGetTempname(pVfs, &zTmpname);
if( rc!=SQLITE_OK ){
OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
return rc;
@@ -4116,17 +4530,19 @@ static int winOpen(
** sqlite3_uri_parameter().
*/
assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
- zUtf8Name[strlen(zUtf8Name)+1]==0 );
+ zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
/* Convert the filename to the system encoding. */
- zConverted = convertUtf8Filename(zUtf8Name);
+ zConverted = winConvertFromUtf8Filename(zUtf8Name);
if( zConverted==0 ){
+ sqlite3_free(zTmpname);
OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
return SQLITE_IOERR_NOMEM;
}
if( winIsDir(zConverted) ){
sqlite3_free(zConverted);
+ sqlite3_free(zTmpname);
OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
return SQLITE_CANTOPEN_ISDIR;
}
@@ -4173,7 +4589,7 @@ static int winOpen(
dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
#endif
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINRT
CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
@@ -4188,7 +4604,7 @@ static int winOpen(
dwShareMode,
dwCreationDisposition,
&extendedParameters))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
+ winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#else
@@ -4198,7 +4614,7 @@ static int winOpen(
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
+ winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#endif
@@ -4211,12 +4627,12 @@ static int winOpen(
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
+ winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
}
#endif
- logIoerr(cnt);
+ winLogIoerr(cnt);
OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
@@ -4225,6 +4641,7 @@ static int winOpen(
pFile->lastErrno = lastErrno;
winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
sqlite3_free(zConverted);
+ sqlite3_free(zTmpname);
if( isReadWrite && !isExclusive ){
return winOpen(pVfs, zName, id,
((flags|SQLITE_OPEN_READONLY) &
@@ -4253,6 +4670,7 @@ static int winOpen(
){
osCloseHandle(h);
sqlite3_free(zConverted);
+ sqlite3_free(zTmpname);
OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
return rc;
}
@@ -4264,6 +4682,7 @@ static int winOpen(
sqlite3_free(zConverted);
}
+ sqlite3_free(zTmpname);
pFile->pMethod = &winIoMethod;
pFile->pVfs = pVfs;
pFile->h = h;
@@ -4307,7 +4726,7 @@ static int winDelete(
int cnt = 0;
int rc;
DWORD attr;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(syncDir);
@@ -4315,11 +4734,12 @@ static int winDelete(
SimulateIOError(return SQLITE_IOERR_DELETE);
OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
- zConverted = convertUtf8Filename(zFilename);
+ zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
+ OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
return SQLITE_IOERR_NOMEM;
}
- if( isNT() ){
+ if( osIsNT() ){
do {
#if SQLITE_OS_WINRT
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
@@ -4358,7 +4778,7 @@ static int winDelete(
rc = SQLITE_OK; /* Deleted OK. */
break;
}
- if ( !retryIoerr(&cnt, &lastErrno) ){
+ if ( !winRetryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
@@ -4386,7 +4806,7 @@ static int winDelete(
rc = SQLITE_OK; /* Deleted OK. */
break;
}
- if ( !retryIoerr(&cnt, &lastErrno) ){
+ if ( !winRetryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
@@ -4394,10 +4814,9 @@ static int winDelete(
}
#endif
if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
- rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
- "winDelete", zFilename);
+ rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
}else{
- logIoerr(cnt);
+ winLogIoerr(cnt);
}
sqlite3_free(zConverted);
OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
@@ -4415,7 +4834,7 @@ static int winAccess(
){
DWORD attr;
int rc = 0;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
@@ -4423,18 +4842,18 @@ static int winAccess(
OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
zFilename, flags, pResOut));
- zConverted = convertUtf8Filename(zFilename);
+ zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
return SQLITE_IOERR_NOMEM;
}
- if( isNT() ){
+ if( osIsNT() ){
int cnt = 0;
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
GetFileExInfoStandard,
- &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
+ &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
if( rc ){
/* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
** as if it does not exist.
@@ -4447,11 +4866,11 @@ static int winAccess(
attr = sAttrData.dwFileAttributes;
}
}else{
- logIoerr(cnt);
+ winLogIoerr(cnt);
if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
- winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
sqlite3_free(zConverted);
- return SQLITE_IOERR_ACCESS;
+ return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
+ zFilename);
}else{
attr = INVALID_FILE_ATTRIBUTES;
}
@@ -4481,6 +4900,15 @@ static int winAccess(
return SQLITE_OK;
}
+/*
+** Returns non-zero if the specified path name starts with a drive letter
+** followed by a colon character.
+*/
+static BOOL winIsDriveLetterAndColon(
+ const char *zPathname
+){
+ return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
+}
/*
** Returns non-zero if the specified path name should be used verbatim. If
@@ -4498,7 +4926,7 @@ static BOOL winIsVerbatimPathname(
** the final two cases; therefore, we return the safer return value of TRUE
** so that callers of this function will simply use it verbatim.
*/
- if ( zPathname[0]=='/' || zPathname[0]=='\\' ){
+ if ( winIsDirSep(zPathname[0]) ){
return TRUE;
}
@@ -4508,7 +4936,7 @@ static BOOL winIsVerbatimPathname(
** attempt to treat it as a relative path name (i.e. they should simply use
** it verbatim).
*/
- if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
+ if ( winIsDriveLetterAndColon(zPathname) ){
return TRUE;
}
@@ -4534,7 +4962,6 @@ static int winFullPathname(
#if defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
UNUSED_PARAMETER(nFull);
- assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH );
assert( nFull>=pVfs->mxPathname );
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
@@ -4543,20 +4970,47 @@ static int winFullPathname(
** for converting the relative path name to an absolute
** one by prepending the data directory and a slash.
*/
- char zOut[SQLITE_WIN32_MAX_PATH+1];
- if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
- SQLITE_WIN32_MAX_PATH+1)<0 ){
- winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
- zRelative);
- return SQLITE_CANTOPEN_FULLPATH;
+ char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+ if( !zOut ){
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
+ CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
+ sqlite3_free(zOut);
+ return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
+ "winFullPathname1", zRelative);
+ }else{
+ char *zUtf8 = winConvertToUtf8Filename(zOut);
+ if( !zUtf8 ){
+ sqlite3_free(zOut);
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zOut);
}
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
- sqlite3_data_directory, zOut);
}else{
- if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
- winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
- zRelative);
- return SQLITE_CANTOPEN_FULLPATH;
+ char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+ if( !zOut ){
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
+ zRelative, zOut, pVfs->mxPathname+1)<0 ){
+ sqlite3_free(zOut);
+ return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
+ "winFullPathname2", zRelative);
+ }else{
+ char *zUtf8 = winConvertToUtf8Filename(zOut);
+ if( !zUtf8 ){
+ sqlite3_free(zOut);
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zOut);
}
}
return SQLITE_OK;
@@ -4573,8 +5027,8 @@ static int winFullPathname(
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
- sqlite3_data_directory, zRelative);
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zRelative);
}else{
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
}
@@ -4589,7 +5043,7 @@ static int winFullPathname(
/* If this path name begins with "/X:", where "X" is any alphabetic
** character, discard the initial "/" from the pathname.
*/
- if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
+ if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
zRelative++;
}
@@ -4606,22 +5060,21 @@ static int winFullPathname(
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
- sqlite3_data_directory, zRelative);
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zRelative);
return SQLITE_OK;
}
- zConverted = convertUtf8Filename(zRelative);
+ zConverted = winConvertFromUtf8Filename(zRelative);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
- if( isNT() ){
+ if( osIsNT() ){
LPWSTR zTemp;
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameW1", zConverted);
sqlite3_free(zConverted);
- return SQLITE_CANTOPEN_FULLPATH;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname1", zRelative);
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
@@ -4631,14 +5084,13 @@ static int winFullPathname(
}
nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameW2", zConverted);
sqlite3_free(zConverted);
sqlite3_free(zTemp);
- return SQLITE_CANTOPEN_FULLPATH;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname2", zRelative);
}
sqlite3_free(zConverted);
- zOut = unicodeToUtf8(zTemp);
+ zOut = winUnicodeToUtf8(zTemp);
sqlite3_free(zTemp);
}
#ifdef SQLITE_WIN32_HAS_ANSI
@@ -4646,10 +5098,9 @@ static int winFullPathname(
char *zTemp;
nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameA1", zConverted);
sqlite3_free(zConverted);
- return SQLITE_CANTOPEN_FULLPATH;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname3", zRelative);
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
@@ -4659,11 +5110,10 @@ static int winFullPathname(
}
nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameA2", zConverted);
sqlite3_free(zConverted);
sqlite3_free(zTemp);
- return SQLITE_CANTOPEN_FULLPATH;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname4", zRelative);
}
sqlite3_free(zConverted);
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
@@ -4685,18 +5135,32 @@ static int winFullPathname(
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
-/*
-** Interfaces for opening a shared library, finding entry points
-** within the shared library, and closing the shared library.
-*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
- void *zConverted = convertUtf8Filename(zFilename);
+#if defined(__CYGWIN__)
+ int nFull = pVfs->mxPathname+1;
+ char *zFull = sqlite3MallocZero( nFull );
+ void *zConverted = 0;
+ if( zFull==0 ){
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
+ return 0;
+ }
+ if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
+ sqlite3_free(zFull);
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
+ return 0;
+ }
+ zConverted = winConvertFromUtf8Filename(zFull);
+ sqlite3_free(zFull);
+#else
+ void *zConverted = winConvertFromUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
+#endif
if( zConverted==0 ){
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINRT
h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
#else
@@ -4708,20 +5172,26 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
h = osLoadLibraryA((char*)zConverted);
}
#endif
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
sqlite3_free(zConverted);
return (void*)h;
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
UNUSED_PARAMETER(pVfs);
- getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
+ winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
+ FARPROC proc;
UNUSED_PARAMETER(pVfs);
- return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
+ proc = osGetProcAddressA((HANDLE)pH, zSym);
+ OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
+ (void*)pH, zSym, (void*)proc));
+ return (void(*)(void))proc;
}
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
UNUSED_PARAMETER(pVfs);
osFreeLibrary((HANDLE)pHandle);
+ OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
}
#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
#define winDlOpen 0
@@ -4889,7 +5359,7 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
*/
static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
UNUSED_PARAMETER(pVfs);
- return getLastErrorMsg(osGetLastError(), nBuf, zBuf);
+ return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
}
/*
@@ -4899,7 +5369,7 @@ int sqlite3_os_init(void){
static sqlite3_vfs winVfs = {
3, /* iVersion */
sizeof(winFile), /* szOsFile */
- SQLITE_WIN32_MAX_PATH, /* mxPathname */
+ SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
0, /* pNext */
"win32", /* zName */
0, /* pAppData */
@@ -4920,10 +5390,36 @@ int sqlite3_os_init(void){
winGetSystemCall, /* xGetSystemCall */
winNextSystemCall, /* xNextSystemCall */
};
+#if defined(SQLITE_WIN32_HAS_WIDE)
+ static sqlite3_vfs winLongPathVfs = {
+ 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 */
+ };
+#endif
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==74 );
+ assert( ArraySize(aSyscall)==76 );
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
@@ -4936,6 +5432,11 @@ int sqlite3_os_init(void){
assert( winSysInfo.dwPageSize>0 );
sqlite3_vfs_register(&winVfs, 1);
+
+#if defined(SQLITE_WIN32_HAS_WIDE)
+ sqlite3_vfs_register(&winLongPathVfs, 0);
+#endif
+
return SQLITE_OK;
}