Fossil SCM
The same, but then with modified SQLite (minimal patch to function winFullPathname this time). This way, applications wanting to use the "win32-longpath" VFS don't have to do tricky extended-path modifications any more.
Commit
8e8e3a11bc9665c025406eddd07114e1fbdb16a9
Parent
4e3f4d26d86a9e4…
2 files changed
+1
-1
+56
-3
M
src/db.c
+1
-1
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -715,11 +715,11 @@ | ||
| 715 | 715 | |
| 716 | 716 | #if defined(__CYGWIN__) |
| 717 | 717 | /* Necessary if we want Cygwin fossil to recognize win32 file |
| 718 | 718 | * paths, as SQLite doesn't handle that (yet) */ |
| 719 | 719 | zDbName = fossil_utf8_to_filename(zDbName); |
| 720 | -#elif defined(_WIN32) | |
| 720 | +#elif 0 && defined(_WIN32) | |
| 721 | 721 | /* Only necessary when SQLite doesn't handle Extended paths. */ |
| 722 | 722 | zDbName = fossil_utf8_to_filename(zDbName); |
| 723 | 723 | zDbName = fossil_filename_to_utf8(zDbName); |
| 724 | 724 | #endif |
| 725 | 725 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 726 | 726 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -715,11 +715,11 @@ | |
| 715 | |
| 716 | #if defined(__CYGWIN__) |
| 717 | /* Necessary if we want Cygwin fossil to recognize win32 file |
| 718 | * paths, as SQLite doesn't handle that (yet) */ |
| 719 | zDbName = fossil_utf8_to_filename(zDbName); |
| 720 | #elif defined(_WIN32) |
| 721 | /* Only necessary when SQLite doesn't handle Extended paths. */ |
| 722 | zDbName = fossil_utf8_to_filename(zDbName); |
| 723 | zDbName = fossil_filename_to_utf8(zDbName); |
| 724 | #endif |
| 725 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 726 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -715,11 +715,11 @@ | |
| 715 | |
| 716 | #if defined(__CYGWIN__) |
| 717 | /* Necessary if we want Cygwin fossil to recognize win32 file |
| 718 | * paths, as SQLite doesn't handle that (yet) */ |
| 719 | zDbName = fossil_utf8_to_filename(zDbName); |
| 720 | #elif 0 && defined(_WIN32) |
| 721 | /* Only necessary when SQLite doesn't handle Extended paths. */ |
| 722 | zDbName = fossil_utf8_to_filename(zDbName); |
| 723 | zDbName = fossil_filename_to_utf8(zDbName); |
| 724 | #endif |
| 725 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 726 |
+56
-3
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -36169,14 +36169,67 @@ | ||
| 36169 | 36169 | */ |
| 36170 | 36170 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 36171 | 36171 | sqlite3_data_directory, winGetDirSep(), zRelative); |
| 36172 | 36172 | return SQLITE_OK; |
| 36173 | 36173 | } |
| 36174 | - zConverted = winConvertFromUtf8Filename(zRelative); | |
| 36175 | - if( zConverted==0 ){ | |
| 36176 | - return SQLITE_IOERR_NOMEM; | |
| 36174 | + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, NULL, 0); | |
| 36175 | + if( nByte==0 ){ | |
| 36176 | + return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)osGetLastError(), | |
| 36177 | + "winFullPathname", zRelative); | |
| 36177 | 36178 | } |
| 36179 | + if( osIsNT() ){ | |
| 36180 | + LPWSTR zWideFilename; | |
| 36181 | + | |
| 36182 | + if( nByte>SQLITE_WIN32_MAX_PATH_CHARS ){ | |
| 36183 | + /* No Win32 API functions can handle such long paths. Let's see if | |
| 36184 | + * we can do something about it. If not, just leave it as is. */ | |
| 36185 | + if( winIsDirSep(zRelative[0]) && winIsDirSep(zRelative[1]) | |
| 36186 | + && zRelative[2]!='?' ){ | |
| 36187 | + /* It's an UNC path, convert it to an extended UNC path. */ | |
| 36188 | + zWideFilename = sqlite3MallocZero( (nByte+6)*sizeof(WCHAR) ); | |
| 36189 | + if( zWideFilename==0 ){ | |
| 36190 | + return SQLITE_IOERR_NOMEM; | |
| 36191 | + } | |
| 36192 | + memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); | |
| 36193 | + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative+2, -1, | |
| 36194 | + zWideFilename+8, nByte); | |
| 36195 | + goto finished; | |
| 36196 | + }else if( winIsDriveLetterAndColon(zRelative) | |
| 36197 | + && winIsDirSep(zRelative[2]) ){ | |
| 36198 | + /* It has a correct drive prefix, convert to extended form. */ | |
| 36199 | + zWideFilename = sqlite3MallocZero( (nByte+4)*sizeof(WCHAR) ); | |
| 36200 | + if( zWideFilename==0 ){ | |
| 36201 | + return SQLITE_IOERR_NOMEM; | |
| 36202 | + } | |
| 36203 | + memcpy(zWideFilename, L"\\\\?\\", 8); | |
| 36204 | + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, | |
| 36205 | + zWideFilename+4, nByte); | |
| 36206 | + zWideFilename[6] = '\\'; | |
| 36207 | + goto finished; | |
| 36208 | + } | |
| 36209 | + /* Another form, e.g. relative path or maybe it already | |
| 36210 | + * has the '\\?\' prefix. Just leave it as-is. */ | |
| 36211 | + } | |
| 36212 | + zWideFilename = sqlite3Malloc( nByte*sizeof(WCHAR) ); | |
| 36213 | + if( zWideFilename==0 ){ | |
| 36214 | + return SQLITE_IOERR_NOMEM; | |
| 36215 | + } | |
| 36216 | + nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, | |
| 36217 | + zWideFilename, nByte); | |
| 36218 | + if( nByte==0 ){ | |
| 36219 | + sqlite3_free(zWideFilename); | |
| 36220 | + return SQLITE_IOERR_NOMEM; | |
| 36221 | + } | |
| 36222 | + finished: | |
| 36223 | + zConverted = zWideFilename; | |
| 36224 | + }else{ | |
| 36225 | + zConverted = sqlite3_win32_utf8_to_mbcs(zRelative); | |
| 36226 | + if( zConverted==0 ){ | |
| 36227 | + return SQLITE_IOERR_NOMEM; | |
| 36228 | + } | |
| 36229 | + } | |
| 36230 | + | |
| 36178 | 36231 | if( osIsNT() ){ |
| 36179 | 36232 | LPWSTR zTemp; |
| 36180 | 36233 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 36181 | 36234 | if( nByte==0 ){ |
| 36182 | 36235 | sqlite3_free(zConverted); |
| 36183 | 36236 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -36169,14 +36169,67 @@ | |
| 36169 | */ |
| 36170 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 36171 | sqlite3_data_directory, winGetDirSep(), zRelative); |
| 36172 | return SQLITE_OK; |
| 36173 | } |
| 36174 | zConverted = winConvertFromUtf8Filename(zRelative); |
| 36175 | if( zConverted==0 ){ |
| 36176 | return SQLITE_IOERR_NOMEM; |
| 36177 | } |
| 36178 | if( osIsNT() ){ |
| 36179 | LPWSTR zTemp; |
| 36180 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 36181 | if( nByte==0 ){ |
| 36182 | sqlite3_free(zConverted); |
| 36183 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -36169,14 +36169,67 @@ | |
| 36169 | */ |
| 36170 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 36171 | sqlite3_data_directory, winGetDirSep(), zRelative); |
| 36172 | return SQLITE_OK; |
| 36173 | } |
| 36174 | nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, NULL, 0); |
| 36175 | if( nByte==0 ){ |
| 36176 | return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)osGetLastError(), |
| 36177 | "winFullPathname", zRelative); |
| 36178 | } |
| 36179 | if( osIsNT() ){ |
| 36180 | LPWSTR zWideFilename; |
| 36181 | |
| 36182 | if( nByte>SQLITE_WIN32_MAX_PATH_CHARS ){ |
| 36183 | /* No Win32 API functions can handle such long paths. Let's see if |
| 36184 | * we can do something about it. If not, just leave it as is. */ |
| 36185 | if( winIsDirSep(zRelative[0]) && winIsDirSep(zRelative[1]) |
| 36186 | && zRelative[2]!='?' ){ |
| 36187 | /* It's an UNC path, convert it to an extended UNC path. */ |
| 36188 | zWideFilename = sqlite3MallocZero( (nByte+6)*sizeof(WCHAR) ); |
| 36189 | if( zWideFilename==0 ){ |
| 36190 | return SQLITE_IOERR_NOMEM; |
| 36191 | } |
| 36192 | memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); |
| 36193 | nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative+2, -1, |
| 36194 | zWideFilename+8, nByte); |
| 36195 | goto finished; |
| 36196 | }else if( winIsDriveLetterAndColon(zRelative) |
| 36197 | && winIsDirSep(zRelative[2]) ){ |
| 36198 | /* It has a correct drive prefix, convert to extended form. */ |
| 36199 | zWideFilename = sqlite3MallocZero( (nByte+4)*sizeof(WCHAR) ); |
| 36200 | if( zWideFilename==0 ){ |
| 36201 | return SQLITE_IOERR_NOMEM; |
| 36202 | } |
| 36203 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 36204 | nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, |
| 36205 | zWideFilename+4, nByte); |
| 36206 | zWideFilename[6] = '\\'; |
| 36207 | goto finished; |
| 36208 | } |
| 36209 | /* Another form, e.g. relative path or maybe it already |
| 36210 | * has the '\\?\' prefix. Just leave it as-is. */ |
| 36211 | } |
| 36212 | zWideFilename = sqlite3Malloc( nByte*sizeof(WCHAR) ); |
| 36213 | if( zWideFilename==0 ){ |
| 36214 | return SQLITE_IOERR_NOMEM; |
| 36215 | } |
| 36216 | nByte = osMultiByteToWideChar(CP_UTF8, 0, zRelative, -1, |
| 36217 | zWideFilename, nByte); |
| 36218 | if( nByte==0 ){ |
| 36219 | sqlite3_free(zWideFilename); |
| 36220 | return SQLITE_IOERR_NOMEM; |
| 36221 | } |
| 36222 | finished: |
| 36223 | zConverted = zWideFilename; |
| 36224 | }else{ |
| 36225 | zConverted = sqlite3_win32_utf8_to_mbcs(zRelative); |
| 36226 | if( zConverted==0 ){ |
| 36227 | return SQLITE_IOERR_NOMEM; |
| 36228 | } |
| 36229 | } |
| 36230 | |
| 36231 | if( osIsNT() ){ |
| 36232 | LPWSTR zTemp; |
| 36233 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 36234 | if( nByte==0 ){ |
| 36235 | sqlite3_free(zConverted); |
| 36236 |