Index: src/json.c ================================================================== --- src/json.c +++ src/json.c @@ -1979,11 +1979,11 @@ cson_object_set(jo, "compiler", cson_value_new_string(COMPILER_NAME, strlen(COMPILER_NAME))); jv2 = cson_value_new_object(); jo2 = cson_value_get_object(jv2); cson_object_set(jo, "sqlite", jv2); - sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)", + sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s win32-longpath)", sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion()); SETBUF(jo2, "version"); zDb = db_name("repository"); cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_count", zDb))); cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA %s.page_size", zDb))); Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -856,11 +856,11 @@ int rc; const char *zRc; #endif fossil_print("Compiled on %s %s using %s (%d-bit)\n", __DATE__, __TIME__, COMPILER_NAME, sizeof(void*)*8); - fossil_print("SQLite %s %.30s\n", sqlite3_libversion(), sqlite3_sourceid()); + fossil_print("SQLite %s (win32-longpath) %.30s\n", sqlite3_libversion(), sqlite3_sourceid()); fossil_print("Schema version %s\n", AUX_SCHEMA); fossil_print("zlib %s, loaded %s\n", ZLIB_VERSION, zlibVersion()); #if defined(FOSSIL_ENABLE_SSL) fossil_print("SSL (%s)\n", SSLeay_version(SSLEAY_VERSION)); #endif Index: src/shell.c ================================================================== --- src/shell.c +++ src/shell.c @@ -3282,11 +3282,11 @@ } #endif }else if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ - fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/, + fprintf(p->out, "SQLite %s (win32-longpath) %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); }else if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ const char *zDbName = nArg==2 ? azArg[1] : "main"; @@ -3883,11 +3883,11 @@ }else if( strcmp(z,"-stats")==0 ){ data.statsOn = 1; }else if( strcmp(z,"-bail")==0 ){ bail_on_error = 1; }else if( strcmp(z,"-version")==0 ){ - printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); + printf("%s (win32-longpath) %s\n", sqlite3_libversion(), sqlite3_sourceid()); return 0; }else if( strcmp(z,"-interactive")==0 ){ stdin_is_interactive = 1; }else if( strcmp(z,"-batch")==0 ){ stdin_is_interactive = 0; Index: src/sqlite3.c ================================================================== --- src/sqlite3.c +++ src/sqlite3.c @@ -35806,11 +35806,40 @@ ** function. */ static void *winConvertFromUtf8Filename(const char *zFilename){ void *zConverted = 0; if( osIsNT() ){ - zConverted = winUtf8ToUnicode(zFilename); + int nChar; + LPWSTR zWideFilename; + + 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); + return 0; + } + if( nChar>MAX_PATH ){ + if( winIsDriveLetterAndColon(zFilename) + && winIsDirSep(zFilename[2]) ){ + memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); + zWideFilename[2] = '\\'; + memcpy(zWideFilename, L"\\\\?\\", 8); + }else if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) + && zFilename[2] != '?' ){ + memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); + memcpy(zWideFilename, L"\\\\?\\UNC", 14); + } + } + zConverted = zWideFilename; } #ifdef SQLITE_WIN32_HAS_ANSI else{ zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); } Index: src/stat.c ================================================================== --- src/stat.c +++ src/stat.c @@ -126,11 +126,11 @@ @ Fossil Version: @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) @ (%h(RELEASE_VERSION)) [compiled using %h(COMPILER_NAME)] @ @ SQLite Version:%.19s(sqlite3_sourceid()) - @ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion())) + @ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()) win32-longpath) @ Repository Rebuilt: @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) @ By Fossil %h(db_get("rebuilt","Unknown")) @ Database Stats: zDb = db_name("repository"); @@ -224,11 +224,11 @@ fossil_print("%*s%s\n", colWidth, "project-id:", db_get("project-code","")); fossil_print("%*s%s %s [%s] (%s)\n", colWidth, "fossil-version:", MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION, COMPILER_NAME); - fossil_print("%*s%.19s [%.10s] (%s)\n", + fossil_print("%*s%.19s [%.10s] (%s win32-longpath)\n", colWidth, "sqlite-version:", sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion()); zDb = db_name("repository"); fossil_print("%*s%d pages, %d bytes/pg, %d free pages, " ADDED test/win32-longpath.test Index: test/win32-longpath.test ================================================================== --- test/win32-longpath.test +++ test/win32-longpath.test @@ -0,0 +1,32 @@ +# +# Tests for 'win32-longpath' VFS, using a repo path >260 chars. +# +# Actually, this test should pass on any platform. +# + +# Fossil will write data on $HOME, running 'fossil new' here. +# We need not to clutter the $HOME of the test caller. +# +set env(HOME) [pwd] + +# Create the repo +# +set x [string repeat x 132] +set longpath [pwd]/$x +file mkdir $longpath +catch { + # Use "cygpath" for converting it to win32 path. If not + # in Msys or Cygwin shell, nothing needs to be done. + set longpath [exec cygpath -w $longpath] +} + +test win32-longpath-test.1 { + ![regexp CANTOPEN [fossil new $longpath/$x.fossil]] +} + +# Try to remove the file/dir various ways, different +# Shells/Tcl versions expect it differently. +catch {file delete \\\\?\\$longpath\\$x.fossil} +catch {file delete $longpath/$x.fossil} +catch {file delete [pwd]/$x/$x.fossil} +catch {file delete [pwd]/$x} Index: win/fossil.rc ================================================================== --- win/fossil.rc +++ win/fossil.rc @@ -85,11 +85,11 @@ BLOCK "040904b0" BEGIN VALUE "CompanyName", "Fossil Development Team\0" VALUE "FileDescription", "Simple, high-reliability, distributed software configuration management system.\0" VALUE "ProductName", "Fossil\0" - VALUE "ProductVersion", "Fossil " RELEASE_VERSION " " MANIFEST_VERSION " " MANIFEST_DATE " UTC\0" + VALUE "ProductVersion", "Fossil " RELEASE_VERSION " (win32-longpath) " MANIFEST_VERSION " " MANIFEST_DATE " UTC\0" VALUE "FileVersion", "Fossil " RELEASE_VERSION " " MANIFEST_VERSION " " MANIFEST_DATE " UTC\0" VALUE "InternalName", "fossil\0" VALUE "LegalCopyright", "Copyright © " MANIFEST_YEAR " by D. Richard Hipp. All rights reserved.\0" VALUE "OriginalFilename", "fossil.exe\0" VALUE "CompilerName", COMPILER_NAME "\0"