aboutsummaryrefslogtreecommitdiff
path: root/src/os_win.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/os_win.c')
-rw-r--r--src/os_win.c313
1 files changed, 106 insertions, 207 deletions
diff --git a/src/os_win.c b/src/os_win.c
index 0dd56af58..623e30104 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -2722,7 +2722,11 @@ static int winHandleLockTimeout(
if( res==WAIT_OBJECT_0 ){
ret = TRUE;
}else if( res==WAIT_TIMEOUT ){
+#if SQLITE_ENABLE_SETLK_TIMEOUT==1
rc = SQLITE_BUSY_TIMEOUT;
+#else
+ rc = SQLITE_BUSY;
+#endif
}else{
/* Some other error has occurred */
rc = SQLITE_IOERR_LOCK;
@@ -3986,6 +3990,103 @@ static int winDeviceCharacteristics(sqlite3_file *id){
*/
static SYSTEM_INFO winSysInfo;
+/*
+** 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
+**
+** On Cygwin, 3 possible input forms are accepted:
+** - If the filename starts with "<drive>:/" or "<drive>:\",
+** it is converted to UTF-16 as-is.
+** - If the filename contains '/', it is assumed to be a
+** Cygwin absolute path, it is converted to a win32
+** absolute path in UTF-16.
+** - Otherwise it must be a filename only, the win32 filename
+** is returned in UTF-16.
+** Note: If the function cygwin_conv_path() fails, only
+** UTF-8 -> UTF-16 conversion will be done. This can only
+** happen when the file path >32k, in which case winUtf8ToUnicode()
+** will fail too.
+*/
+static void *winConvertFromUtf8Filename(const char *zFilename){
+ void *zConverted = 0;
+ if( osIsNT() ){
+#ifdef __CYGWIN__
+ int nChar;
+ LPWSTR zWideFilename;
+
+ if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename)
+ && winIsDirSep(zFilename[2])) ){
+ i64 nByte;
+ int convertflag = CCP_POSIX_TO_WIN_W;
+ if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE;
+ nByte = (i64)osCygwin_conv_path(convertflag,
+ zFilename, 0, 0);
+ if( nByte>0 ){
+ zConverted = sqlite3MallocZero(12+(u64)nByte);
+ if ( zConverted==0 ){
+ return zConverted;
+ }
+ zWideFilename = zConverted;
+ /* Filenames should be prefixed, except when converted
+ * full path already starts with "\\?\". */
+ if( osCygwin_conv_path(convertflag, zFilename,
+ zWideFilename+4, nByte)==0 ){
+ if( (convertflag&CCP_RELATIVE) ){
+ memmove(zWideFilename, zWideFilename+4, nByte);
+ }else if( memcmp(zWideFilename+4, L"\\\\", 4) ){
+ memcpy(zWideFilename, L"\\\\?\\", 8);
+ }else if( zWideFilename[6]!='?' ){
+ memmove(zWideFilename+6, zWideFilename+4, nByte);
+ memcpy(zWideFilename, L"\\\\?\\UNC", 14);
+ }else{
+ memmove(zWideFilename, zWideFilename+4, nByte);
+ }
+ return zConverted;
+ }
+ sqlite3_free(zConverted);
+ }
+ }
+ nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
+ if( nChar==0 ){
+ return 0;
+ }
+ zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 );
+ if( zWideFilename==0 ){
+ return 0;
+ }
+ nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1,
+ zWideFilename, nChar);
+ if( nChar==0 ){
+ sqlite3_free(zWideFilename);
+ zWideFilename = 0;
+ }else if( nChar>MAX_PATH
+ && winIsDriveLetterAndColon(zFilename)
+ && winIsDirSep(zFilename[2]) ){
+ memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR));
+ zWideFilename[2] = '\\';
+ memcpy(zWideFilename, L"\\\\?\\", 8);
+ }else if( nChar>MAX_PATH
+ && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1])
+ && zFilename[2] != '?' ){
+ memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR));
+ memcpy(zWideFilename, L"\\\\?\\UNC", 14);
+ }
+ zConverted = zWideFilename;
+#else
+ zConverted = winUtf8ToUnicode(zFilename);
+#endif /* __CYGWIN__ */
+ }
+#if defined(SQLITE_WIN32_HAS_ANSI) && defined(_WIN32)
+ else{
+ zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI());
+ }
+#endif
+ /* caller will handle out of memory */
+ return zConverted;
+}
+
#ifndef SQLITE_OMIT_WAL
/*
@@ -4181,103 +4282,6 @@ static int winLockSharedMemory(winShmNode *pShmNode, DWORD nMs){
/*
-** 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
-**
-** On Cygwin, 3 possible input forms are accepted:
-** - If the filename starts with "<drive>:/" or "<drive>:\",
-** it is converted to UTF-16 as-is.
-** - If the filename contains '/', it is assumed to be a
-** Cygwin absolute path, it is converted to a win32
-** absolute path in UTF-16.
-** - Otherwise it must be a filename only, the win32 filename
-** is returned in UTF-16.
-** Note: If the function cygwin_conv_path() fails, only
-** UTF-8 -> UTF-16 conversion will be done. This can only
-** happen when the file path >32k, in which case winUtf8ToUnicode()
-** will fail too.
-*/
-static void *winConvertFromUtf8Filename(const char *zFilename){
- void *zConverted = 0;
- if( osIsNT() ){
-#ifdef __CYGWIN__
- int nChar;
- LPWSTR zWideFilename;
-
- if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename)
- && winIsDirSep(zFilename[2])) ){
- int nByte;
- int convertflag = CCP_POSIX_TO_WIN_W;
- if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE;
- nByte = (int)osCygwin_conv_path(convertflag,
- zFilename, 0, 0);
- if( nByte>0 ){
- zConverted = sqlite3MallocZero(nByte+12);
- if ( zConverted==0 ){
- return zConverted;
- }
- zWideFilename = zConverted;
- /* Filenames should be prefixed, except when converted
- * full path already starts with "\\?\". */
- if( osCygwin_conv_path(convertflag, zFilename,
- zWideFilename+4, nByte)==0 ){
- if( (convertflag&CCP_RELATIVE) ){
- memmove(zWideFilename, zWideFilename+4, nByte);
- }else if( memcmp(zWideFilename+4, L"\\\\", 4) ){
- memcpy(zWideFilename, L"\\\\?\\", 8);
- }else if( zWideFilename[6]!='?' ){
- memmove(zWideFilename+6, zWideFilename+4, nByte);
- memcpy(zWideFilename, L"\\\\?\\UNC", 14);
- }else{
- memmove(zWideFilename, zWideFilename+4, nByte);
- }
- return zConverted;
- }
- sqlite3_free(zConverted);
- }
- }
- nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
- if( nChar==0 ){
- return 0;
- }
- zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 );
- if( zWideFilename==0 ){
- return 0;
- }
- nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1,
- zWideFilename, nChar);
- if( nChar==0 ){
- sqlite3_free(zWideFilename);
- zWideFilename = 0;
- }else if( nChar>MAX_PATH
- && winIsDriveLetterAndColon(zFilename)
- && winIsDirSep(zFilename[2]) ){
- memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR));
- zWideFilename[2] = '\\';
- memcpy(zWideFilename, L"\\\\?\\", 8);
- }else if( nChar>MAX_PATH
- && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1])
- && zFilename[2] != '?' ){
- memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR));
- memcpy(zWideFilename, L"\\\\?\\UNC", 14);
- }
- zConverted = zWideFilename;
-#else
- zConverted = winUtf8ToUnicode(zFilename);
-#endif /* __CYGWIN__ */
- }
-#if defined(SQLITE_WIN32_HAS_ANSI) && defined(_WIN32)
- else{
- zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI());
- }
-#endif
- /* caller will handle out of memory */
- return zConverted;
-}
-
-/*
** This function is used to open a handle on a *-shm file.
**
** If SQLITE_ENABLE_SETLK_TIMEOUT is defined at build time, then the file
@@ -4533,21 +4537,20 @@ static int winShmLock(
/* Check that, if this to be a blocking lock, no locks that occur later
** in the following list than the lock being obtained are already held:
**
- ** 1. Checkpointer lock (ofst==1).
- ** 2. Write lock (ofst==0).
- ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
+ ** 1. Recovery lock (ofst==2).
+ ** 2. Checkpointer lock (ofst==1).
+ ** 3. Write lock (ofst==0).
+ ** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
**
** In other words, if this is a blocking lock, none of the locks that
** occur later in the above list than the lock being obtained may be
** held.
- **
- ** It is not permitted to block on the RECOVER lock.
*/
#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG)
{
u16 lockMask = (p->exclMask|p->sharedMask);
assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
- (ofst!=2) /* not RECOVER */
+ (ofst!=2 || lockMask==0)
&& (ofst!=1 || lockMask==0 || lockMask==2)
&& (ofst!=0 || lockMask<3)
&& (ofst<3 || lockMask<(1<<ofst))
@@ -5097,27 +5100,6 @@ static winVfsAppData winNolockAppData = {
** sqlite3_vfs object.
*/
-#if 0 /* No longer necessary */
-/*
-** 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 = winMbcsToUtf8(zFilename, osAreFileApisANSI());
- }
-#endif
- /* caller will handle out of memory */
- return zConverted;
-}
-#endif
-
/*
** This function returns non-zero if the specified UTF-8 string buffer
** ends with a directory separator character or one was successfully
@@ -5257,42 +5239,6 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
break;
}
sqlite3_free(zConverted);
-#if 0 /* No longer necessary */
- }else{
- zConverted = sqlite3MallocZero( nMax+1 );
- if( !zConverted ){
- sqlite3_free(zBuf);
- OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM_BKPT;
- }
- if( osCygwin_conv_path(
- CCP_POSIX_TO_WIN_W, 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_BKPT;
- }
- sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
- sqlite3_free(zUtf8);
- sqlite3_free(zConverted);
- break;
- }
- sqlite3_free(zConverted);
-#endif /* No longer necessary */
}
}
}
@@ -6191,34 +6137,6 @@ static int winFullPathnameNoMutex(
}
}
#endif /* __CYGWIN__ */
-#if 0 /* This doesn't work correctly at all! See:
- <https://marc.info/?l=sqlite-users&m=139299149416314&w=2>
-*/
- SimulateIOError( return SQLITE_ERROR );
- UNUSED_PARAMETER(nFull);
- assert( nFull>=pVfs->mxPathname );
- char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
- if( !zOut ){
- return SQLITE_IOERR_NOMEM_BKPT;
- }
- if( osCygwin_conv_path(
- CCP_POSIX_TO_WIN_W,
- 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_BKPT;
- }
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
- sqlite3_free(zUtf8);
- sqlite3_free(zOut);
- }
- return SQLITE_OK;
-#endif
#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32)
SimulateIOError( return SQLITE_ERROR );
@@ -6364,27 +6282,8 @@ static int winFullPathname(
*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
-#if 0 /* This doesn't work correctly at all! See:
- <https://marc.info/?l=sqlite-users&m=139299149416314&w=2>
-*/
- 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;