Fossil SCM
Make "win32-longpath" the default VFS on win32, eliminating all path limitations (up to ~32767 chars). TODO: eliminate use of the the function _wstati64(), that appears to be the only Win32 function left which cannot handle such long paths. Everything else needed is done.
Commit
1b9893bdc8e8ec9885f3c181752105259885f8ff
Parent
bb440899d387093…
9 files changed
+5
-1
+15
-3
+11
-11
+11
-11
-5
+36
-3
+36
-3
+14
-3
+14
-3
M
src/db.c
+5
-1
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -715,11 +715,15 @@ | ||
| 715 | 715 | |
| 716 | 716 | #if defined(__CYGWIN__) |
| 717 | 717 | zDbName = fossil_utf8_to_filename(zDbName); |
| 718 | 718 | #endif |
| 719 | 719 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 720 | - rc = sqlite3_open(zDbName, &db); | |
| 720 | + rc = sqlite3_open_v2( | |
| 721 | + zDbName, &db, | |
| 722 | + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, | |
| 723 | + g.zVfsName | |
| 724 | + ); | |
| 721 | 725 | if( rc!=SQLITE_OK ){ |
| 722 | 726 | db_err("[%s]: %s", zDbName, sqlite3_errmsg(db)); |
| 723 | 727 | } |
| 724 | 728 | sqlite3_busy_timeout(db, 5000); |
| 725 | 729 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 726 | 730 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -715,11 +715,15 @@ | |
| 715 | |
| 716 | #if defined(__CYGWIN__) |
| 717 | zDbName = fossil_utf8_to_filename(zDbName); |
| 718 | #endif |
| 719 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 720 | rc = sqlite3_open(zDbName, &db); |
| 721 | if( rc!=SQLITE_OK ){ |
| 722 | db_err("[%s]: %s", zDbName, sqlite3_errmsg(db)); |
| 723 | } |
| 724 | sqlite3_busy_timeout(db, 5000); |
| 725 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 726 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -715,11 +715,15 @@ | |
| 715 | |
| 716 | #if defined(__CYGWIN__) |
| 717 | zDbName = fossil_utf8_to_filename(zDbName); |
| 718 | #endif |
| 719 | if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName); |
| 720 | rc = sqlite3_open_v2( |
| 721 | zDbName, &db, |
| 722 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 723 | g.zVfsName |
| 724 | ); |
| 725 | if( rc!=SQLITE_OK ){ |
| 726 | db_err("[%s]: %s", zDbName, sqlite3_errmsg(db)); |
| 727 | } |
| 728 | sqlite3_busy_timeout(db, 5000); |
| 729 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 730 |
+15
-3
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -695,11 +695,15 @@ | ||
| 695 | 695 | "SELECT value FROM config WHERE name='peer-repo-%q'", |
| 696 | 696 | zCode |
| 697 | 697 | ); |
| 698 | 698 | if( zOtherRepo==0 ) return 0; /* No such peer repository */ |
| 699 | 699 | |
| 700 | - rc = sqlite3_open(zOtherRepo, &pOther); | |
| 700 | + rc = sqlite3_open_v2( | |
| 701 | + zOtherRepo, &pOther, | |
| 702 | + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, | |
| 703 | + g.zVfsName | |
| 704 | + ); | |
| 701 | 705 | if( rc==SQLITE_OK ){ |
| 702 | 706 | sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0); |
| 703 | 707 | sqlite3_create_function(pOther, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 704 | 708 | constant_time_cmp_function, 0, 0); |
| 705 | 709 | sqlite3_busy_timeout(pOther, 5000); |
| @@ -1372,11 +1376,15 @@ | ||
| 1372 | 1376 | "DELETE FROM config WHERE name GLOB 'peer-*-%q'", |
| 1373 | 1377 | &zLabel[10] |
| 1374 | 1378 | ); |
| 1375 | 1379 | continue; |
| 1376 | 1380 | } |
| 1377 | - rc = sqlite3_open_v2(zRepoName, &pPeer, SQLITE_OPEN_READWRITE, 0); | |
| 1381 | + rc = sqlite3_open_v2( | |
| 1382 | + zRepoName, &pPeer, | |
| 1383 | + SQLITE_OPEN_READWRITE, | |
| 1384 | + g.zVfsName | |
| 1385 | + ); | |
| 1378 | 1386 | if( rc!=SQLITE_OK ){ |
| 1379 | 1387 | blob_appendf(&err, "%s%s: %s%s", zPrefix, zRepoName, |
| 1380 | 1388 | sqlite3_errmsg(pPeer), zSuffix); |
| 1381 | 1389 | nErr++; |
| 1382 | 1390 | sqlite3_close(pPeer); |
| @@ -1459,11 +1467,15 @@ | ||
| 1459 | 1467 | /* Make sure the other repository is a valid Fossil database */ |
| 1460 | 1468 | if( file_size(zRepo)<0 ){ |
| 1461 | 1469 | *pzErrMsg = mprintf("repository file \"%s\" does not exist", zRepo); |
| 1462 | 1470 | return; |
| 1463 | 1471 | } |
| 1464 | - rc = sqlite3_open(zRepo, &pOther); | |
| 1472 | + rc = sqlite3_open_v2( | |
| 1473 | + zRepo, &pOther, | |
| 1474 | + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, | |
| 1475 | + g.zVfsName | |
| 1476 | + ); | |
| 1465 | 1477 | if( rc!=SQLITE_OK ){ |
| 1466 | 1478 | *pzErrMsg = mprintf(sqlite3_errmsg(pOther)); |
| 1467 | 1479 | }else{ |
| 1468 | 1480 | rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg); |
| 1469 | 1481 | } |
| 1470 | 1482 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -695,11 +695,15 @@ | |
| 695 | "SELECT value FROM config WHERE name='peer-repo-%q'", |
| 696 | zCode |
| 697 | ); |
| 698 | if( zOtherRepo==0 ) return 0; /* No such peer repository */ |
| 699 | |
| 700 | rc = sqlite3_open(zOtherRepo, &pOther); |
| 701 | if( rc==SQLITE_OK ){ |
| 702 | sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0); |
| 703 | sqlite3_create_function(pOther, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 704 | constant_time_cmp_function, 0, 0); |
| 705 | sqlite3_busy_timeout(pOther, 5000); |
| @@ -1372,11 +1376,15 @@ | |
| 1372 | "DELETE FROM config WHERE name GLOB 'peer-*-%q'", |
| 1373 | &zLabel[10] |
| 1374 | ); |
| 1375 | continue; |
| 1376 | } |
| 1377 | rc = sqlite3_open_v2(zRepoName, &pPeer, SQLITE_OPEN_READWRITE, 0); |
| 1378 | if( rc!=SQLITE_OK ){ |
| 1379 | blob_appendf(&err, "%s%s: %s%s", zPrefix, zRepoName, |
| 1380 | sqlite3_errmsg(pPeer), zSuffix); |
| 1381 | nErr++; |
| 1382 | sqlite3_close(pPeer); |
| @@ -1459,11 +1467,15 @@ | |
| 1459 | /* Make sure the other repository is a valid Fossil database */ |
| 1460 | if( file_size(zRepo)<0 ){ |
| 1461 | *pzErrMsg = mprintf("repository file \"%s\" does not exist", zRepo); |
| 1462 | return; |
| 1463 | } |
| 1464 | rc = sqlite3_open(zRepo, &pOther); |
| 1465 | if( rc!=SQLITE_OK ){ |
| 1466 | *pzErrMsg = mprintf(sqlite3_errmsg(pOther)); |
| 1467 | }else{ |
| 1468 | rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg); |
| 1469 | } |
| 1470 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -695,11 +695,15 @@ | |
| 695 | "SELECT value FROM config WHERE name='peer-repo-%q'", |
| 696 | zCode |
| 697 | ); |
| 698 | if( zOtherRepo==0 ) return 0; /* No such peer repository */ |
| 699 | |
| 700 | rc = sqlite3_open_v2( |
| 701 | zOtherRepo, &pOther, |
| 702 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 703 | g.zVfsName |
| 704 | ); |
| 705 | if( rc==SQLITE_OK ){ |
| 706 | sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0); |
| 707 | sqlite3_create_function(pOther, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 708 | constant_time_cmp_function, 0, 0); |
| 709 | sqlite3_busy_timeout(pOther, 5000); |
| @@ -1372,11 +1376,15 @@ | |
| 1376 | "DELETE FROM config WHERE name GLOB 'peer-*-%q'", |
| 1377 | &zLabel[10] |
| 1378 | ); |
| 1379 | continue; |
| 1380 | } |
| 1381 | rc = sqlite3_open_v2( |
| 1382 | zRepoName, &pPeer, |
| 1383 | SQLITE_OPEN_READWRITE, |
| 1384 | g.zVfsName |
| 1385 | ); |
| 1386 | if( rc!=SQLITE_OK ){ |
| 1387 | blob_appendf(&err, "%s%s: %s%s", zPrefix, zRepoName, |
| 1388 | sqlite3_errmsg(pPeer), zSuffix); |
| 1389 | nErr++; |
| 1390 | sqlite3_close(pPeer); |
| @@ -1459,11 +1467,15 @@ | |
| 1467 | /* Make sure the other repository is a valid Fossil database */ |
| 1468 | if( file_size(zRepo)<0 ){ |
| 1469 | *pzErrMsg = mprintf("repository file \"%s\" does not exist", zRepo); |
| 1470 | return; |
| 1471 | } |
| 1472 | rc = sqlite3_open_v2( |
| 1473 | zRepo, &pOther, |
| 1474 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, |
| 1475 | g.zVfsName |
| 1476 | ); |
| 1477 | if( rc!=SQLITE_OK ){ |
| 1478 | *pzErrMsg = mprintf(sqlite3_errmsg(pOther)); |
| 1479 | }else{ |
| 1480 | rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg); |
| 1481 | } |
| 1482 |
+11
-11
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -119,10 +119,11 @@ | ||
| 119 | 119 | struct Global { |
| 120 | 120 | int argc; char **argv; /* Command-line arguments to the program */ |
| 121 | 121 | char *nameOfExe; /* Full path of executable. */ |
| 122 | 122 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 123 | 123 | int isConst; /* True if the output is unchanging */ |
| 124 | + const char *zVfsName; /* The VFS to use for database connections */ | |
| 124 | 125 | sqlite3 *db; /* The connection to the databases */ |
| 125 | 126 | sqlite3 *dbConfig; /* Separate connection for global_config table */ |
| 126 | 127 | int useAttach; /* True if global_config is attached to repository */ |
| 127 | 128 | const char *zConfigDbName;/* Path of the config database. NULL if not open */ |
| 128 | 129 | sqlite3_int64 now; /* Seconds since 1970 */ |
| @@ -549,11 +550,10 @@ | ||
| 549 | 550 | #endif |
| 550 | 551 | int main(int argc, char **argv) |
| 551 | 552 | #endif |
| 552 | 553 | { |
| 553 | 554 | const char *zCmdName = "unknown"; |
| 554 | - const char *zVfsName; | |
| 555 | 555 | int idx; |
| 556 | 556 | int rc; |
| 557 | 557 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
| 558 | 558 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 559 | 559 | memset(&g, 0, sizeof(g)); |
| @@ -577,25 +577,25 @@ | ||
| 577 | 577 | memset(&g.tcl, 0, sizeof(TclContext)); |
| 578 | 578 | g.tcl.argc = g.argc; |
| 579 | 579 | g.tcl.argv = copy_args(g.argc, g.argv); /* save full arguments */ |
| 580 | 580 | #endif |
| 581 | 581 | g.mainTimerId = fossil_timer_start(); |
| 582 | - zVfsName = find_option("vfs",0,1); | |
| 583 | - if( zVfsName==0 ){ | |
| 584 | - zVfsName = fossil_getenv("FOSSIL_VFS"); | |
| 585 | - } | |
| 582 | + g.zVfsName = find_option("vfs",0,1); | |
| 583 | + if( g.zVfsName==0 ){ | |
| 584 | + g.zVfsName = fossil_getenv("FOSSIL_VFS"); | |
| 586 | 585 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 587 | - if( zVfsName==0 && sqlite3_libversion_number()>=3008001 ){ | |
| 588 | - zVfsName = "win32-longpath"; | |
| 589 | - } | |
| 586 | + if( g.zVfsName==0 && sqlite3_libversion_number()>=3008001 ){ | |
| 587 | + g.zVfsName = "win32-longpath"; | |
| 588 | + } | |
| 590 | 589 | #endif |
| 591 | - if( zVfsName ){ | |
| 592 | - sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfsName); | |
| 590 | + } | |
| 591 | + if( g.zVfsName ){ | |
| 592 | + sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName); | |
| 593 | 593 | if( pVfs ){ |
| 594 | 594 | sqlite3_vfs_register(pVfs, 1); |
| 595 | 595 | }else{ |
| 596 | - fossil_fatal("no such VFS: \"%s\"", zVfsName); | |
| 596 | + fossil_fatal("no such VFS: \"%s\"", g.zVfsName); | |
| 597 | 597 | } |
| 598 | 598 | } |
| 599 | 599 | if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 600 | 600 | zCmdName = "cgi"; |
| 601 | 601 | g.isHTTP = 1; |
| 602 | 602 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -119,10 +119,11 @@ | |
| 119 | struct Global { |
| 120 | int argc; char **argv; /* Command-line arguments to the program */ |
| 121 | char *nameOfExe; /* Full path of executable. */ |
| 122 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 123 | int isConst; /* True if the output is unchanging */ |
| 124 | sqlite3 *db; /* The connection to the databases */ |
| 125 | sqlite3 *dbConfig; /* Separate connection for global_config table */ |
| 126 | int useAttach; /* True if global_config is attached to repository */ |
| 127 | const char *zConfigDbName;/* Path of the config database. NULL if not open */ |
| 128 | sqlite3_int64 now; /* Seconds since 1970 */ |
| @@ -549,11 +550,10 @@ | |
| 549 | #endif |
| 550 | int main(int argc, char **argv) |
| 551 | #endif |
| 552 | { |
| 553 | const char *zCmdName = "unknown"; |
| 554 | const char *zVfsName; |
| 555 | int idx; |
| 556 | int rc; |
| 557 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
| 558 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 559 | memset(&g, 0, sizeof(g)); |
| @@ -577,25 +577,25 @@ | |
| 577 | memset(&g.tcl, 0, sizeof(TclContext)); |
| 578 | g.tcl.argc = g.argc; |
| 579 | g.tcl.argv = copy_args(g.argc, g.argv); /* save full arguments */ |
| 580 | #endif |
| 581 | g.mainTimerId = fossil_timer_start(); |
| 582 | zVfsName = find_option("vfs",0,1); |
| 583 | if( zVfsName==0 ){ |
| 584 | zVfsName = fossil_getenv("FOSSIL_VFS"); |
| 585 | } |
| 586 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 587 | if( zVfsName==0 && sqlite3_libversion_number()>=3008001 ){ |
| 588 | zVfsName = "win32-longpath"; |
| 589 | } |
| 590 | #endif |
| 591 | if( zVfsName ){ |
| 592 | sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfsName); |
| 593 | if( pVfs ){ |
| 594 | sqlite3_vfs_register(pVfs, 1); |
| 595 | }else{ |
| 596 | fossil_fatal("no such VFS: \"%s\"", zVfsName); |
| 597 | } |
| 598 | } |
| 599 | if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 600 | zCmdName = "cgi"; |
| 601 | g.isHTTP = 1; |
| 602 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -119,10 +119,11 @@ | |
| 119 | struct Global { |
| 120 | int argc; char **argv; /* Command-line arguments to the program */ |
| 121 | char *nameOfExe; /* Full path of executable. */ |
| 122 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 123 | int isConst; /* True if the output is unchanging */ |
| 124 | const char *zVfsName; /* The VFS to use for database connections */ |
| 125 | sqlite3 *db; /* The connection to the databases */ |
| 126 | sqlite3 *dbConfig; /* Separate connection for global_config table */ |
| 127 | int useAttach; /* True if global_config is attached to repository */ |
| 128 | const char *zConfigDbName;/* Path of the config database. NULL if not open */ |
| 129 | sqlite3_int64 now; /* Seconds since 1970 */ |
| @@ -549,11 +550,10 @@ | |
| 550 | #endif |
| 551 | int main(int argc, char **argv) |
| 552 | #endif |
| 553 | { |
| 554 | const char *zCmdName = "unknown"; |
| 555 | int idx; |
| 556 | int rc; |
| 557 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
| 558 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 559 | memset(&g, 0, sizeof(g)); |
| @@ -577,25 +577,25 @@ | |
| 577 | memset(&g.tcl, 0, sizeof(TclContext)); |
| 578 | g.tcl.argc = g.argc; |
| 579 | g.tcl.argv = copy_args(g.argc, g.argv); /* save full arguments */ |
| 580 | #endif |
| 581 | g.mainTimerId = fossil_timer_start(); |
| 582 | g.zVfsName = find_option("vfs",0,1); |
| 583 | if( g.zVfsName==0 ){ |
| 584 | g.zVfsName = fossil_getenv("FOSSIL_VFS"); |
| 585 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 586 | if( g.zVfsName==0 && sqlite3_libversion_number()>=3008001 ){ |
| 587 | g.zVfsName = "win32-longpath"; |
| 588 | } |
| 589 | #endif |
| 590 | } |
| 591 | if( g.zVfsName ){ |
| 592 | sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName); |
| 593 | if( pVfs ){ |
| 594 | sqlite3_vfs_register(pVfs, 1); |
| 595 | }else{ |
| 596 | fossil_fatal("no such VFS: \"%s\"", g.zVfsName); |
| 597 | } |
| 598 | } |
| 599 | if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 600 | zCmdName = "cgi"; |
| 601 | g.isHTTP = 1; |
| 602 |
+11
-11
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -119,10 +119,11 @@ | ||
| 119 | 119 | struct Global { |
| 120 | 120 | int argc; char **argv; /* Command-line arguments to the program */ |
| 121 | 121 | char *nameOfExe; /* Full path of executable. */ |
| 122 | 122 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 123 | 123 | int isConst; /* True if the output is unchanging */ |
| 124 | + const char *zVfsName; /* The VFS to use for database connections */ | |
| 124 | 125 | sqlite3 *db; /* The connection to the databases */ |
| 125 | 126 | sqlite3 *dbConfig; /* Separate connection for global_config table */ |
| 126 | 127 | int useAttach; /* True if global_config is attached to repository */ |
| 127 | 128 | const char *zConfigDbName;/* Path of the config database. NULL if not open */ |
| 128 | 129 | sqlite3_int64 now; /* Seconds since 1970 */ |
| @@ -549,11 +550,10 @@ | ||
| 549 | 550 | #endif |
| 550 | 551 | int main(int argc, char **argv) |
| 551 | 552 | #endif |
| 552 | 553 | { |
| 553 | 554 | const char *zCmdName = "unknown"; |
| 554 | - const char *zVfsName; | |
| 555 | 555 | int idx; |
| 556 | 556 | int rc; |
| 557 | 557 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
| 558 | 558 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 559 | 559 | memset(&g, 0, sizeof(g)); |
| @@ -577,25 +577,25 @@ | ||
| 577 | 577 | memset(&g.tcl, 0, sizeof(TclContext)); |
| 578 | 578 | g.tcl.argc = g.argc; |
| 579 | 579 | g.tcl.argv = copy_args(g.argc, g.argv); /* save full arguments */ |
| 580 | 580 | #endif |
| 581 | 581 | g.mainTimerId = fossil_timer_start(); |
| 582 | - zVfsName = find_option("vfs",0,1); | |
| 583 | - if( zVfsName==0 ){ | |
| 584 | - zVfsName = fossil_getenv("FOSSIL_VFS"); | |
| 585 | - } | |
| 582 | + g.zVfsName = find_option("vfs",0,1); | |
| 583 | + if( g.zVfsName==0 ){ | |
| 584 | + g.zVfsName = fossil_getenv("FOSSIL_VFS"); | |
| 586 | 585 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 587 | - if( zVfsName==0 && sqlite3_libversion_number()>=3008001 ){ | |
| 588 | - zVfsName = "win32-longpath"; | |
| 589 | - } | |
| 586 | + if( g.zVfsName==0 && sqlite3_libversion_number()>=3008001 ){ | |
| 587 | + g.zVfsName = "win32-longpath"; | |
| 588 | + } | |
| 590 | 589 | #endif |
| 591 | - if( zVfsName ){ | |
| 592 | - sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfsName); | |
| 590 | + } | |
| 591 | + if( g.zVfsName ){ | |
| 592 | + sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName); | |
| 593 | 593 | if( pVfs ){ |
| 594 | 594 | sqlite3_vfs_register(pVfs, 1); |
| 595 | 595 | }else{ |
| 596 | - fossil_fatal("no such VFS: \"%s\"", zVfsName); | |
| 596 | + fossil_fatal("no such VFS: \"%s\"", g.zVfsName); | |
| 597 | 597 | } |
| 598 | 598 | } |
| 599 | 599 | if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 600 | 600 | zCmdName = "cgi"; |
| 601 | 601 | g.isHTTP = 1; |
| 602 | 602 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -119,10 +119,11 @@ | |
| 119 | struct Global { |
| 120 | int argc; char **argv; /* Command-line arguments to the program */ |
| 121 | char *nameOfExe; /* Full path of executable. */ |
| 122 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 123 | int isConst; /* True if the output is unchanging */ |
| 124 | sqlite3 *db; /* The connection to the databases */ |
| 125 | sqlite3 *dbConfig; /* Separate connection for global_config table */ |
| 126 | int useAttach; /* True if global_config is attached to repository */ |
| 127 | const char *zConfigDbName;/* Path of the config database. NULL if not open */ |
| 128 | sqlite3_int64 now; /* Seconds since 1970 */ |
| @@ -549,11 +550,10 @@ | |
| 549 | #endif |
| 550 | int main(int argc, char **argv) |
| 551 | #endif |
| 552 | { |
| 553 | const char *zCmdName = "unknown"; |
| 554 | const char *zVfsName; |
| 555 | int idx; |
| 556 | int rc; |
| 557 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
| 558 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 559 | memset(&g, 0, sizeof(g)); |
| @@ -577,25 +577,25 @@ | |
| 577 | memset(&g.tcl, 0, sizeof(TclContext)); |
| 578 | g.tcl.argc = g.argc; |
| 579 | g.tcl.argv = copy_args(g.argc, g.argv); /* save full arguments */ |
| 580 | #endif |
| 581 | g.mainTimerId = fossil_timer_start(); |
| 582 | zVfsName = find_option("vfs",0,1); |
| 583 | if( zVfsName==0 ){ |
| 584 | zVfsName = fossil_getenv("FOSSIL_VFS"); |
| 585 | } |
| 586 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 587 | if( zVfsName==0 && sqlite3_libversion_number()>=3008001 ){ |
| 588 | zVfsName = "win32-longpath"; |
| 589 | } |
| 590 | #endif |
| 591 | if( zVfsName ){ |
| 592 | sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfsName); |
| 593 | if( pVfs ){ |
| 594 | sqlite3_vfs_register(pVfs, 1); |
| 595 | }else{ |
| 596 | fossil_fatal("no such VFS: \"%s\"", zVfsName); |
| 597 | } |
| 598 | } |
| 599 | if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 600 | zCmdName = "cgi"; |
| 601 | g.isHTTP = 1; |
| 602 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -119,10 +119,11 @@ | |
| 119 | struct Global { |
| 120 | int argc; char **argv; /* Command-line arguments to the program */ |
| 121 | char *nameOfExe; /* Full path of executable. */ |
| 122 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 123 | int isConst; /* True if the output is unchanging */ |
| 124 | const char *zVfsName; /* The VFS to use for database connections */ |
| 125 | sqlite3 *db; /* The connection to the databases */ |
| 126 | sqlite3 *dbConfig; /* Separate connection for global_config table */ |
| 127 | int useAttach; /* True if global_config is attached to repository */ |
| 128 | const char *zConfigDbName;/* Path of the config database. NULL if not open */ |
| 129 | sqlite3_int64 now; /* Seconds since 1970 */ |
| @@ -549,11 +550,10 @@ | |
| 550 | #endif |
| 551 | int main(int argc, char **argv) |
| 552 | #endif |
| 553 | { |
| 554 | const char *zCmdName = "unknown"; |
| 555 | int idx; |
| 556 | int rc; |
| 557 | sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
| 558 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 559 | memset(&g, 0, sizeof(g)); |
| @@ -577,25 +577,25 @@ | |
| 577 | memset(&g.tcl, 0, sizeof(TclContext)); |
| 578 | g.tcl.argc = g.argc; |
| 579 | g.tcl.argv = copy_args(g.argc, g.argv); /* save full arguments */ |
| 580 | #endif |
| 581 | g.mainTimerId = fossil_timer_start(); |
| 582 | g.zVfsName = find_option("vfs",0,1); |
| 583 | if( g.zVfsName==0 ){ |
| 584 | g.zVfsName = fossil_getenv("FOSSIL_VFS"); |
| 585 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 586 | if( g.zVfsName==0 && sqlite3_libversion_number()>=3008001 ){ |
| 587 | g.zVfsName = "win32-longpath"; |
| 588 | } |
| 589 | #endif |
| 590 | } |
| 591 | if( g.zVfsName ){ |
| 592 | sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName); |
| 593 | if( pVfs ){ |
| 594 | sqlite3_vfs_register(pVfs, 1); |
| 595 | }else{ |
| 596 | fossil_fatal("no such VFS: \"%s\"", g.zVfsName); |
| 597 | } |
| 598 | } |
| 599 | if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 600 | zCmdName = "cgi"; |
| 601 | g.isHTTP = 1; |
| 602 |
-5
| --- src/sqlcmd.c | ||
| +++ src/sqlcmd.c | ||
| @@ -124,12 +124,10 @@ | ||
| 124 | 124 | g.repositoryOpen = 1; |
| 125 | 125 | g.db = db; |
| 126 | 126 | return SQLITE_OK; |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | -static sqlite3_vfs *pDefaultVfs = 0; | |
| 130 | - | |
| 131 | 129 | /* |
| 132 | 130 | ** COMMAND: sqlite3 |
| 133 | 131 | ** |
| 134 | 132 | ** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS? |
| 135 | 133 | ** |
| @@ -143,12 +141,10 @@ | ||
| 143 | 141 | */ |
| 144 | 142 | void sqlite3_cmd(void){ |
| 145 | 143 | extern int sqlite3_shell(int, char**); |
| 146 | 144 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 147 | 145 | db_close(1); |
| 148 | - /* Determine default VFS and keep it after shutdown */ | |
| 149 | - pDefaultVfs = sqlite3_vfs_find(0); | |
| 150 | 146 | sqlite3_shutdown(); |
| 151 | 147 | sqlite3_shell(g.argc-1, g.argv+1); |
| 152 | 148 | g.db = 0; |
| 153 | 149 | } |
| 154 | 150 | |
| @@ -155,9 +151,8 @@ | ||
| 155 | 151 | /* |
| 156 | 152 | ** This routine is called by the patched sqlite3 command-line shell in order |
| 157 | 153 | ** to load the name and database connection for the open Fossil database. |
| 158 | 154 | */ |
| 159 | 155 | void fossil_open(const char **pzRepoName){ |
| 160 | - if( pDefaultVfs ) sqlite3_vfs_register(pDefaultVfs, 1); | |
| 161 | 156 | sqlite3_auto_extension((void(*)(void))sqlcmd_autoinit); |
| 162 | 157 | *pzRepoName = g.zRepositoryName; |
| 163 | 158 | } |
| 164 | 159 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -124,12 +124,10 @@ | |
| 124 | g.repositoryOpen = 1; |
| 125 | g.db = db; |
| 126 | return SQLITE_OK; |
| 127 | } |
| 128 | |
| 129 | static sqlite3_vfs *pDefaultVfs = 0; |
| 130 | |
| 131 | /* |
| 132 | ** COMMAND: sqlite3 |
| 133 | ** |
| 134 | ** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS? |
| 135 | ** |
| @@ -143,12 +141,10 @@ | |
| 143 | */ |
| 144 | void sqlite3_cmd(void){ |
| 145 | extern int sqlite3_shell(int, char**); |
| 146 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 147 | db_close(1); |
| 148 | /* Determine default VFS and keep it after shutdown */ |
| 149 | pDefaultVfs = sqlite3_vfs_find(0); |
| 150 | sqlite3_shutdown(); |
| 151 | sqlite3_shell(g.argc-1, g.argv+1); |
| 152 | g.db = 0; |
| 153 | } |
| 154 | |
| @@ -155,9 +151,8 @@ | |
| 155 | /* |
| 156 | ** This routine is called by the patched sqlite3 command-line shell in order |
| 157 | ** to load the name and database connection for the open Fossil database. |
| 158 | */ |
| 159 | void fossil_open(const char **pzRepoName){ |
| 160 | if( pDefaultVfs ) sqlite3_vfs_register(pDefaultVfs, 1); |
| 161 | sqlite3_auto_extension((void(*)(void))sqlcmd_autoinit); |
| 162 | *pzRepoName = g.zRepositoryName; |
| 163 | } |
| 164 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -124,12 +124,10 @@ | |
| 124 | g.repositoryOpen = 1; |
| 125 | g.db = db; |
| 126 | return SQLITE_OK; |
| 127 | } |
| 128 | |
| 129 | /* |
| 130 | ** COMMAND: sqlite3 |
| 131 | ** |
| 132 | ** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS? |
| 133 | ** |
| @@ -143,12 +141,10 @@ | |
| 141 | */ |
| 142 | void sqlite3_cmd(void){ |
| 143 | extern int sqlite3_shell(int, char**); |
| 144 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 145 | db_close(1); |
| 146 | sqlite3_shutdown(); |
| 147 | sqlite3_shell(g.argc-1, g.argv+1); |
| 148 | g.db = 0; |
| 149 | } |
| 150 | |
| @@ -155,9 +151,8 @@ | |
| 151 | /* |
| 152 | ** This routine is called by the patched sqlite3 command-line shell in order |
| 153 | ** to load the name and database connection for the open Fossil database. |
| 154 | */ |
| 155 | void fossil_open(const char **pzRepoName){ |
| 156 | sqlite3_auto_extension((void(*)(void))sqlcmd_autoinit); |
| 157 | *pzRepoName = g.zRepositoryName; |
| 158 | } |
| 159 |
+36
-3
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -35125,16 +35125,45 @@ | ||
| 35125 | 35125 | |
| 35126 | 35126 | /* |
| 35127 | 35127 | ** Convert a UTF-8 filename into whatever form the underlying |
| 35128 | 35128 | ** operating system wants filenames in. Space to hold the result |
| 35129 | 35129 | ** is obtained from malloc and must be freed by the calling |
| 35130 | -** function. | |
| 35130 | +** function. When running on NT and zFilename is absolute, the | |
| 35131 | +** resulting path is guaranteed to start with "\\?\". | |
| 35131 | 35132 | */ |
| 35132 | 35133 | static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 35133 | 35134 | void *zConverted = 0; |
| 35134 | 35135 | if( osIsNT() ){ |
| 35135 | - zConverted = winUtf8ToUnicode(zFilename); | |
| 35136 | + int nChar; | |
| 35137 | + LPWSTR zWideFilename; | |
| 35138 | + | |
| 35139 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); | |
| 35140 | + if( nChar==0 ){ | |
| 35141 | + return 0; | |
| 35142 | + } | |
| 35143 | + zWideFilename = sqlite3MallocZero( (nChar*sizeof(zWideFilename[0]))+12 ); | |
| 35144 | + if( zWideFilename==0 ){ | |
| 35145 | + return 0; | |
| 35146 | + } | |
| 35147 | + if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) ){ | |
| 35148 | + memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); | |
| 35149 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+6, | |
| 35150 | + nChar); | |
| 35151 | + }else if( winIsDriveLetterAndColon(zFilename) && winIsDirSep(zFilename[2])) { | |
| 35152 | + memcpy(zWideFilename, L"\\\\?\\", 8); | |
| 35153 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+4, | |
| 35154 | + nChar); | |
| 35155 | + zWideFilename[6] = '\\'; | |
| 35156 | + }else{ | |
| 35157 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, | |
| 35158 | + nChar); | |
| 35159 | + } | |
| 35160 | + if( nChar==0 ){ | |
| 35161 | + sqlite3_free(zWideFilename); | |
| 35162 | + zWideFilename = 0; | |
| 35163 | + } | |
| 35164 | + zConverted = zWideFilename; | |
| 35136 | 35165 | } |
| 35137 | 35166 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35138 | 35167 | else{ |
| 35139 | 35168 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 35140 | 35169 | } |
| @@ -36061,11 +36090,15 @@ | ||
| 36061 | 36090 | */ |
| 36062 | 36091 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 36063 | 36092 | sqlite3_data_directory, winGetDirSep(), zRelative); |
| 36064 | 36093 | return SQLITE_OK; |
| 36065 | 36094 | } |
| 36066 | - zConverted = winConvertFromUtf8Filename(zRelative); | |
| 36095 | + if( osIsNT() ){ | |
| 36096 | + zConverted = winUtf8ToUnicode(zRelative); | |
| 36097 | + }else{ | |
| 36098 | + zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);; | |
| 36099 | + } | |
| 36067 | 36100 | if( zConverted==0 ){ |
| 36068 | 36101 | return SQLITE_IOERR_NOMEM; |
| 36069 | 36102 | } |
| 36070 | 36103 | if( osIsNT() ){ |
| 36071 | 36104 | LPWSTR zTemp; |
| 36072 | 36105 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -35125,16 +35125,45 @@ | |
| 35125 | |
| 35126 | /* |
| 35127 | ** Convert a UTF-8 filename into whatever form the underlying |
| 35128 | ** operating system wants filenames in. Space to hold the result |
| 35129 | ** is obtained from malloc and must be freed by the calling |
| 35130 | ** function. |
| 35131 | */ |
| 35132 | static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 35133 | void *zConverted = 0; |
| 35134 | if( osIsNT() ){ |
| 35135 | zConverted = winUtf8ToUnicode(zFilename); |
| 35136 | } |
| 35137 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35138 | else{ |
| 35139 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 35140 | } |
| @@ -36061,11 +36090,15 @@ | |
| 36061 | */ |
| 36062 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 36063 | sqlite3_data_directory, winGetDirSep(), zRelative); |
| 36064 | return SQLITE_OK; |
| 36065 | } |
| 36066 | zConverted = winConvertFromUtf8Filename(zRelative); |
| 36067 | if( zConverted==0 ){ |
| 36068 | return SQLITE_IOERR_NOMEM; |
| 36069 | } |
| 36070 | if( osIsNT() ){ |
| 36071 | LPWSTR zTemp; |
| 36072 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -35125,16 +35125,45 @@ | |
| 35125 | |
| 35126 | /* |
| 35127 | ** Convert a UTF-8 filename into whatever form the underlying |
| 35128 | ** operating system wants filenames in. Space to hold the result |
| 35129 | ** is obtained from malloc and must be freed by the calling |
| 35130 | ** function. When running on NT and zFilename is absolute, the |
| 35131 | ** resulting path is guaranteed to start with "\\?\". |
| 35132 | */ |
| 35133 | static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 35134 | void *zConverted = 0; |
| 35135 | if( osIsNT() ){ |
| 35136 | int nChar; |
| 35137 | LPWSTR zWideFilename; |
| 35138 | |
| 35139 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 35140 | if( nChar==0 ){ |
| 35141 | return 0; |
| 35142 | } |
| 35143 | zWideFilename = sqlite3MallocZero( (nChar*sizeof(zWideFilename[0]))+12 ); |
| 35144 | if( zWideFilename==0 ){ |
| 35145 | return 0; |
| 35146 | } |
| 35147 | if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) ){ |
| 35148 | memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); |
| 35149 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+6, |
| 35150 | nChar); |
| 35151 | }else if( winIsDriveLetterAndColon(zFilename) && winIsDirSep(zFilename[2])) { |
| 35152 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 35153 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+4, |
| 35154 | nChar); |
| 35155 | zWideFilename[6] = '\\'; |
| 35156 | }else{ |
| 35157 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, |
| 35158 | nChar); |
| 35159 | } |
| 35160 | if( nChar==0 ){ |
| 35161 | sqlite3_free(zWideFilename); |
| 35162 | zWideFilename = 0; |
| 35163 | } |
| 35164 | zConverted = zWideFilename; |
| 35165 | } |
| 35166 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35167 | else{ |
| 35168 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 35169 | } |
| @@ -36061,11 +36090,15 @@ | |
| 36090 | */ |
| 36091 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 36092 | sqlite3_data_directory, winGetDirSep(), zRelative); |
| 36093 | return SQLITE_OK; |
| 36094 | } |
| 36095 | if( osIsNT() ){ |
| 36096 | zConverted = winUtf8ToUnicode(zRelative); |
| 36097 | }else{ |
| 36098 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);; |
| 36099 | } |
| 36100 | if( zConverted==0 ){ |
| 36101 | return SQLITE_IOERR_NOMEM; |
| 36102 | } |
| 36103 | if( osIsNT() ){ |
| 36104 | LPWSTR zTemp; |
| 36105 |
+36
-3
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -35125,16 +35125,45 @@ | ||
| 35125 | 35125 | |
| 35126 | 35126 | /* |
| 35127 | 35127 | ** Convert a UTF-8 filename into whatever form the underlying |
| 35128 | 35128 | ** operating system wants filenames in. Space to hold the result |
| 35129 | 35129 | ** is obtained from malloc and must be freed by the calling |
| 35130 | -** function. | |
| 35130 | +** function. When running on NT and zFilename is absolute, the | |
| 35131 | +** resulting path is guaranteed to start with "\\?\". | |
| 35131 | 35132 | */ |
| 35132 | 35133 | static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 35133 | 35134 | void *zConverted = 0; |
| 35134 | 35135 | if( osIsNT() ){ |
| 35135 | - zConverted = winUtf8ToUnicode(zFilename); | |
| 35136 | + int nChar; | |
| 35137 | + LPWSTR zWideFilename; | |
| 35138 | + | |
| 35139 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); | |
| 35140 | + if( nChar==0 ){ | |
| 35141 | + return 0; | |
| 35142 | + } | |
| 35143 | + zWideFilename = sqlite3MallocZero( (nChar*sizeof(zWideFilename[0]))+12 ); | |
| 35144 | + if( zWideFilename==0 ){ | |
| 35145 | + return 0; | |
| 35146 | + } | |
| 35147 | + if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) ){ | |
| 35148 | + memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); | |
| 35149 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+6, | |
| 35150 | + nChar); | |
| 35151 | + }else if( winIsDriveLetterAndColon(zFilename) && winIsDirSep(zFilename[2])) { | |
| 35152 | + memcpy(zWideFilename, L"\\\\?\\", 8); | |
| 35153 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+4, | |
| 35154 | + nChar); | |
| 35155 | + zWideFilename[6] = '\\'; | |
| 35156 | + }else{ | |
| 35157 | + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, | |
| 35158 | + nChar); | |
| 35159 | + } | |
| 35160 | + if( nChar==0 ){ | |
| 35161 | + sqlite3_free(zWideFilename); | |
| 35162 | + zWideFilename = 0; | |
| 35163 | + } | |
| 35164 | + zConverted = zWideFilename; | |
| 35136 | 35165 | } |
| 35137 | 35166 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35138 | 35167 | else{ |
| 35139 | 35168 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 35140 | 35169 | } |
| @@ -36061,11 +36090,15 @@ | ||
| 36061 | 36090 | */ |
| 36062 | 36091 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 36063 | 36092 | sqlite3_data_directory, winGetDirSep(), zRelative); |
| 36064 | 36093 | return SQLITE_OK; |
| 36065 | 36094 | } |
| 36066 | - zConverted = winConvertFromUtf8Filename(zRelative); | |
| 36095 | + if( osIsNT() ){ | |
| 36096 | + zConverted = winUtf8ToUnicode(zRelative); | |
| 36097 | + }else{ | |
| 36098 | + zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);; | |
| 36099 | + } | |
| 36067 | 36100 | if( zConverted==0 ){ |
| 36068 | 36101 | return SQLITE_IOERR_NOMEM; |
| 36069 | 36102 | } |
| 36070 | 36103 | if( osIsNT() ){ |
| 36071 | 36104 | LPWSTR zTemp; |
| 36072 | 36105 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -35125,16 +35125,45 @@ | |
| 35125 | |
| 35126 | /* |
| 35127 | ** Convert a UTF-8 filename into whatever form the underlying |
| 35128 | ** operating system wants filenames in. Space to hold the result |
| 35129 | ** is obtained from malloc and must be freed by the calling |
| 35130 | ** function. |
| 35131 | */ |
| 35132 | static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 35133 | void *zConverted = 0; |
| 35134 | if( osIsNT() ){ |
| 35135 | zConverted = winUtf8ToUnicode(zFilename); |
| 35136 | } |
| 35137 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35138 | else{ |
| 35139 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 35140 | } |
| @@ -36061,11 +36090,15 @@ | |
| 36061 | */ |
| 36062 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 36063 | sqlite3_data_directory, winGetDirSep(), zRelative); |
| 36064 | return SQLITE_OK; |
| 36065 | } |
| 36066 | zConverted = winConvertFromUtf8Filename(zRelative); |
| 36067 | if( zConverted==0 ){ |
| 36068 | return SQLITE_IOERR_NOMEM; |
| 36069 | } |
| 36070 | if( osIsNT() ){ |
| 36071 | LPWSTR zTemp; |
| 36072 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -35125,16 +35125,45 @@ | |
| 35125 | |
| 35126 | /* |
| 35127 | ** Convert a UTF-8 filename into whatever form the underlying |
| 35128 | ** operating system wants filenames in. Space to hold the result |
| 35129 | ** is obtained from malloc and must be freed by the calling |
| 35130 | ** function. When running on NT and zFilename is absolute, the |
| 35131 | ** resulting path is guaranteed to start with "\\?\". |
| 35132 | */ |
| 35133 | static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 35134 | void *zConverted = 0; |
| 35135 | if( osIsNT() ){ |
| 35136 | int nChar; |
| 35137 | LPWSTR zWideFilename; |
| 35138 | |
| 35139 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 35140 | if( nChar==0 ){ |
| 35141 | return 0; |
| 35142 | } |
| 35143 | zWideFilename = sqlite3MallocZero( (nChar*sizeof(zWideFilename[0]))+12 ); |
| 35144 | if( zWideFilename==0 ){ |
| 35145 | return 0; |
| 35146 | } |
| 35147 | if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) ){ |
| 35148 | memcpy(zWideFilename, L"\\\\?\\UNC\\", 16); |
| 35149 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+6, |
| 35150 | nChar); |
| 35151 | }else if( winIsDriveLetterAndColon(zFilename) && winIsDirSep(zFilename[2])) { |
| 35152 | memcpy(zWideFilename, L"\\\\?\\", 8); |
| 35153 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+4, |
| 35154 | nChar); |
| 35155 | zWideFilename[6] = '\\'; |
| 35156 | }else{ |
| 35157 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, |
| 35158 | nChar); |
| 35159 | } |
| 35160 | if( nChar==0 ){ |
| 35161 | sqlite3_free(zWideFilename); |
| 35162 | zWideFilename = 0; |
| 35163 | } |
| 35164 | zConverted = zWideFilename; |
| 35165 | } |
| 35166 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35167 | else{ |
| 35168 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 35169 | } |
| @@ -36061,11 +36090,15 @@ | |
| 36090 | */ |
| 36091 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 36092 | sqlite3_data_directory, winGetDirSep(), zRelative); |
| 36093 | return SQLITE_OK; |
| 36094 | } |
| 36095 | if( osIsNT() ){ |
| 36096 | zConverted = winUtf8ToUnicode(zRelative); |
| 36097 | }else{ |
| 36098 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);; |
| 36099 | } |
| 36100 | if( zConverted==0 ){ |
| 36101 | return SQLITE_IOERR_NOMEM; |
| 36102 | } |
| 36103 | if( osIsNT() ){ |
| 36104 | LPWSTR zTemp; |
| 36105 |
+14
-3
| --- src/utf8.c | ||
| +++ src/utf8.c | ||
| @@ -191,21 +191,32 @@ | ||
| 191 | 191 | ** |
| 192 | 192 | */ |
| 193 | 193 | void *fossil_utf8_to_filename(const char *zUtf8){ |
| 194 | 194 | #ifdef _WIN32 |
| 195 | 195 | int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0); |
| 196 | - wchar_t *zUnicode = sqlite3_malloc( nChar * 2 ); | |
| 196 | + wchar_t *zUnicode = sqlite3_malloc( (nChar+6) * 2 ); | |
| 197 | 197 | wchar_t *wUnicode = zUnicode; |
| 198 | 198 | if( zUnicode==0 ){ |
| 199 | 199 | return 0; |
| 200 | 200 | } |
| 201 | - MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); | |
| 202 | 201 | /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */ |
| 203 | 202 | if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':' |
| 204 | 203 | && (zUtf8[2]=='\\' || zUtf8[2]=='/')) { |
| 205 | - zUnicode[2] = '\\'; | |
| 204 | + /* Convert to extended path. */ | |
| 205 | + memcpy(zUnicode, L"\\\\?\\", 8); | |
| 206 | + wUnicode += 4; | |
| 207 | + MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); | |
| 208 | + wUnicode[2] = '\\'; | |
| 206 | 209 | wUnicode += 3; |
| 210 | + }else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') && | |
| 211 | + (zUtf8[1]=='\\' || zUtf8[1]=='/') && zUtf8[2]!='?' ) { | |
| 212 | + /* Convert to extended UNC path. */ | |
| 213 | + memcpy(zUnicode, L"\\\\?\\UNC\\", 16); | |
| 214 | + wUnicode += 8; | |
| 215 | + MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, wUnicode, nChar); | |
| 216 | + }else{ | |
| 217 | + MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); | |
| 207 | 218 | } |
| 208 | 219 | while( *wUnicode != '\0' ){ |
| 209 | 220 | if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){ |
| 210 | 221 | *wUnicode |= 0xF000; |
| 211 | 222 | }else if( *wUnicode == '/' ){ |
| 212 | 223 |
| --- src/utf8.c | |
| +++ src/utf8.c | |
| @@ -191,21 +191,32 @@ | |
| 191 | ** |
| 192 | */ |
| 193 | void *fossil_utf8_to_filename(const char *zUtf8){ |
| 194 | #ifdef _WIN32 |
| 195 | int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0); |
| 196 | wchar_t *zUnicode = sqlite3_malloc( nChar * 2 ); |
| 197 | wchar_t *wUnicode = zUnicode; |
| 198 | if( zUnicode==0 ){ |
| 199 | return 0; |
| 200 | } |
| 201 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); |
| 202 | /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */ |
| 203 | if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':' |
| 204 | && (zUtf8[2]=='\\' || zUtf8[2]=='/')) { |
| 205 | zUnicode[2] = '\\'; |
| 206 | wUnicode += 3; |
| 207 | } |
| 208 | while( *wUnicode != '\0' ){ |
| 209 | if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){ |
| 210 | *wUnicode |= 0xF000; |
| 211 | }else if( *wUnicode == '/' ){ |
| 212 |
| --- src/utf8.c | |
| +++ src/utf8.c | |
| @@ -191,21 +191,32 @@ | |
| 191 | ** |
| 192 | */ |
| 193 | void *fossil_utf8_to_filename(const char *zUtf8){ |
| 194 | #ifdef _WIN32 |
| 195 | int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0); |
| 196 | wchar_t *zUnicode = sqlite3_malloc( (nChar+6) * 2 ); |
| 197 | wchar_t *wUnicode = zUnicode; |
| 198 | if( zUnicode==0 ){ |
| 199 | return 0; |
| 200 | } |
| 201 | /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */ |
| 202 | if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':' |
| 203 | && (zUtf8[2]=='\\' || zUtf8[2]=='/')) { |
| 204 | /* Convert to extended path. */ |
| 205 | memcpy(zUnicode, L"\\\\?\\", 8); |
| 206 | wUnicode += 4; |
| 207 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 208 | wUnicode[2] = '\\'; |
| 209 | wUnicode += 3; |
| 210 | }else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') && |
| 211 | (zUtf8[1]=='\\' || zUtf8[1]=='/') && zUtf8[2]!='?' ) { |
| 212 | /* Convert to extended UNC path. */ |
| 213 | memcpy(zUnicode, L"\\\\?\\UNC\\", 16); |
| 214 | wUnicode += 8; |
| 215 | MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, wUnicode, nChar); |
| 216 | }else{ |
| 217 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 218 | } |
| 219 | while( *wUnicode != '\0' ){ |
| 220 | if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){ |
| 221 | *wUnicode |= 0xF000; |
| 222 | }else if( *wUnicode == '/' ){ |
| 223 |
+14
-3
| --- src/utf8.c | ||
| +++ src/utf8.c | ||
| @@ -191,21 +191,32 @@ | ||
| 191 | 191 | ** |
| 192 | 192 | */ |
| 193 | 193 | void *fossil_utf8_to_filename(const char *zUtf8){ |
| 194 | 194 | #ifdef _WIN32 |
| 195 | 195 | int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0); |
| 196 | - wchar_t *zUnicode = sqlite3_malloc( nChar * 2 ); | |
| 196 | + wchar_t *zUnicode = sqlite3_malloc( (nChar+6) * 2 ); | |
| 197 | 197 | wchar_t *wUnicode = zUnicode; |
| 198 | 198 | if( zUnicode==0 ){ |
| 199 | 199 | return 0; |
| 200 | 200 | } |
| 201 | - MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); | |
| 202 | 201 | /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */ |
| 203 | 202 | if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':' |
| 204 | 203 | && (zUtf8[2]=='\\' || zUtf8[2]=='/')) { |
| 205 | - zUnicode[2] = '\\'; | |
| 204 | + /* Convert to extended path. */ | |
| 205 | + memcpy(zUnicode, L"\\\\?\\", 8); | |
| 206 | + wUnicode += 4; | |
| 207 | + MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); | |
| 208 | + wUnicode[2] = '\\'; | |
| 206 | 209 | wUnicode += 3; |
| 210 | + }else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') && | |
| 211 | + (zUtf8[1]=='\\' || zUtf8[1]=='/') && zUtf8[2]!='?' ) { | |
| 212 | + /* Convert to extended UNC path. */ | |
| 213 | + memcpy(zUnicode, L"\\\\?\\UNC\\", 16); | |
| 214 | + wUnicode += 8; | |
| 215 | + MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, wUnicode, nChar); | |
| 216 | + }else{ | |
| 217 | + MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); | |
| 207 | 218 | } |
| 208 | 219 | while( *wUnicode != '\0' ){ |
| 209 | 220 | if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){ |
| 210 | 221 | *wUnicode |= 0xF000; |
| 211 | 222 | }else if( *wUnicode == '/' ){ |
| 212 | 223 |
| --- src/utf8.c | |
| +++ src/utf8.c | |
| @@ -191,21 +191,32 @@ | |
| 191 | ** |
| 192 | */ |
| 193 | void *fossil_utf8_to_filename(const char *zUtf8){ |
| 194 | #ifdef _WIN32 |
| 195 | int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0); |
| 196 | wchar_t *zUnicode = sqlite3_malloc( nChar * 2 ); |
| 197 | wchar_t *wUnicode = zUnicode; |
| 198 | if( zUnicode==0 ){ |
| 199 | return 0; |
| 200 | } |
| 201 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); |
| 202 | /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */ |
| 203 | if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':' |
| 204 | && (zUtf8[2]=='\\' || zUtf8[2]=='/')) { |
| 205 | zUnicode[2] = '\\'; |
| 206 | wUnicode += 3; |
| 207 | } |
| 208 | while( *wUnicode != '\0' ){ |
| 209 | if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){ |
| 210 | *wUnicode |= 0xF000; |
| 211 | }else if( *wUnicode == '/' ){ |
| 212 |
| --- src/utf8.c | |
| +++ src/utf8.c | |
| @@ -191,21 +191,32 @@ | |
| 191 | ** |
| 192 | */ |
| 193 | void *fossil_utf8_to_filename(const char *zUtf8){ |
| 194 | #ifdef _WIN32 |
| 195 | int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0); |
| 196 | wchar_t *zUnicode = sqlite3_malloc( (nChar+6) * 2 ); |
| 197 | wchar_t *wUnicode = zUnicode; |
| 198 | if( zUnicode==0 ){ |
| 199 | return 0; |
| 200 | } |
| 201 | /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */ |
| 202 | if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':' |
| 203 | && (zUtf8[2]=='\\' || zUtf8[2]=='/')) { |
| 204 | /* Convert to extended path. */ |
| 205 | memcpy(zUnicode, L"\\\\?\\", 8); |
| 206 | wUnicode += 4; |
| 207 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 208 | wUnicode[2] = '\\'; |
| 209 | wUnicode += 3; |
| 210 | }else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') && |
| 211 | (zUtf8[1]=='\\' || zUtf8[1]=='/') && zUtf8[2]!='?' ) { |
| 212 | /* Convert to extended UNC path. */ |
| 213 | memcpy(zUnicode, L"\\\\?\\UNC\\", 16); |
| 214 | wUnicode += 8; |
| 215 | MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, wUnicode, nChar); |
| 216 | }else{ |
| 217 | MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar); |
| 218 | } |
| 219 | while( *wUnicode != '\0' ){ |
| 220 | if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){ |
| 221 | *wUnicode |= 0xF000; |
| 222 | }else if( *wUnicode == '/' ){ |
| 223 |