Source code

Revision control

Copy as Markdown

Other Tools

Use the single-handle *-shm locking scheme on Windows network volumes.
SQLite 3.50 split WAL shared-memory locking across two file handles, which
does not work on network filesystems; 3.51.0 added bUseSharedLockHandle to
restore the single-handle scheme, but selects it with winIsUNCPath(), which
cannot recognize a drive letter mapped to an SMB share. This asks the OS
instead. See bug 2067771.
"On Windows, use the GetDriveTypeW() interface to detect network
filesystems and always use a single shared file handle for the -shm
files on such filesystems." (drh, 2026-09-03)
Git mirror: sqlite/sqlite@28fe5623286bdb4eaf543e7be4dddee5762ee51b
Ported to the amalgamation: upstream's aSyscall[] has 59 entries
(cygwin_conv_path at 58), ours has 81 (at 80), so GetDriveTypeW is index 81
here and the ArraySize() assertion moves 81 -> 82.
Deviates from upstream in one place: the osGetDriveTypeW cast keeps WINAPI.
GetDriveTypeW is __stdcall, so calling it through a __cdecl pointer drifts
ESP by 4 bytes per call on win32 builds.
Remove this file once we vendor a SQLite release containing the upstream
check-in.
diff --git a/sqlite3.c b/sqlite3.c
index 0644a39f8734..f474acb2c2ff 100644
--- a/sqlite3.c
+++ b/sqlite3.c
@@ -49927,6 +49927,9 @@ static struct win_syscall {
#define osCygwin_conv_path ((size_t(*)(unsigned int, \
const void *, void *, size_t))aSyscall[80].pCurrent)
+ { "GetDriveTypeW", (SYSCALL)GetDriveTypeW, 0 },
+#define osGetDriveTypeW ((UINT(WINAPI*)(LPCWSTR))aSyscall[81].pCurrent)
+
}; /* End of the overrideable system calls */
/*
@@ -53054,6 +53057,23 @@ static int winIsUNCPath(const char *zFile){
return sqlite3_win_test_unc_locking;
}
+/*
+** Return true if the string passed in is the name of a file on a
+** remote (network-mounted) volume.
+*/
+static int winIsRemoteVolume(const char *zFile){
+ WCHAR zRoot[4];
+ if( strncmp(zFile, "\\\\?\\",4)==0 ) zFile += 4;
+ if( !sqlite3Isalpha(zFile[0]) ) return 0;
+ if( zFile[1]!=':' ) return 0;
+ if( !winIsDirSep(zFile[2]) ) return 0;
+ zRoot[0] = (WCHAR)zFile[0];
+ zRoot[1] = ':';
+ zRoot[2] = '\\';
+ zRoot[3] = 0;
+ return osGetDriveTypeW(zRoot)==DRIVE_REMOTE;
+}
+
/*
** Open the shared-memory area associated with database file pDbFd.
*/
@@ -53079,7 +53099,11 @@ static int winOpenSharedMemory(winFile *pDbFd){
pNew->zFilename = (char*)&pNew[1];
pNew->hSharedShm = INVALID_HANDLE_VALUE;
pNew->isUnlocked = 1;
- pNew->bUseSharedLockHandle = winIsUNCPath(pDbFd->zPath);
+ if( winIsUNCPath(pDbFd->zPath) || winIsRemoteVolume(pDbFd->zPath) ){
+ pNew->bUseSharedLockHandle = 1;
+ }else{
+ pNew->bUseSharedLockHandle = 0;
+ }
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
@@ -55261,7 +55285,7 @@ SQLITE_API int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==81 );
+ assert( ArraySize(aSyscall)==82 );
assert( strcmp(aSyscall[0].zName,"AreFileApisANSI")==0 );
assert( strcmp(aSyscall[20].zName,"GetFileAttributesA")==0 );
assert( strcmp(aSyscall[40].zName,"HeapReAlloc")==0 );