From 136d503c2ae924782f231de488f04f6980f41ed6 Mon Sep 17 00:00:00 2001 From: "vladimir%pobox.com" Date: Thu, 27 Jul 2006 21:58:42 +0000 Subject: [PATCH] b=329898, start page is not displayed/bookmarks empty on win9x with non-ascii chars in profile path, r=brettw,a=drivers git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_BRANCH@204995 18797224-902f-48f8-a5cc-f745e15eee43 --- .../sqlite3/sqlite-fix-non-unicode-win.patch | 531 ++++++++++++++++++ mozilla/db/sqlite3/src/os_win.c | 265 ++++++--- 2 files changed, 713 insertions(+), 83 deletions(-) create mode 100644 mozilla/db/sqlite3/sqlite-fix-non-unicode-win.patch diff --git a/mozilla/db/sqlite3/sqlite-fix-non-unicode-win.patch b/mozilla/db/sqlite3/sqlite-fix-non-unicode-win.patch new file mode 100644 index 00000000000..cf02bc5a213 --- /dev/null +++ b/mozilla/db/sqlite3/sqlite-fix-non-unicode-win.patch @@ -0,0 +1,531 @@ +Index: os_win.c +=================================================================== +RCS file: /cvsroot/mozilla/db/sqlite3/src/os_win.c,v +retrieving revision 1.2.8.4 +diff -u -8 -p -r1.2.8.4 os_win.c +--- os_win.c 22 May 2006 19:12:32 -0000 1.2.8.4 ++++ os_win.c 18 Jul 2006 22:33:46 -0000 +@@ -126,19 +126,16 @@ int sqlite3_os_type = 0; + /* + ** Convert a UTF-8 string to UTF-32. Space to hold the returned string + ** is obtained from sqliteMalloc. + */ + static WCHAR *utf8ToUnicode(const char *zFilename){ + int nChar; + WCHAR *zWideFilename; + +- if( !isNT() ){ +- return 0; +- } + nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) ); + if( zWideFilename==0 ){ + return 0; + } + nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); + if( nChar==0 ){ + sqliteFree(zWideFilename); +@@ -164,16 +161,93 @@ static char *unicodeToUtf8(const WCHAR * + 0, 0); + if( nByte == 0 ){ + sqliteFree(zFilename); + zFilename = 0; + } + return zFilename; + } + ++/* ++** Convert a multibyte character string to UTF-32, based on the current Ansi codepage (CP_ACP). ++** Space to hold the returned string is obtained from sqliteMalloc. ++*/ ++static WCHAR *mbcsToUnicode(const char *zFilename){ ++ int nByte; ++ WCHAR *zMbcsFilename; ++ ++ nByte = MultiByteToWideChar(CP_ACP, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR); ++ zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) ); ++ if( zMbcsFilename==0 ){ ++ return 0; ++ } ++ nByte = MultiByteToWideChar(CP_ACP, 0, zFilename, -1, zMbcsFilename, nByte); ++ if( nByte==0 ){ ++ sqliteFree(zMbcsFilename); ++ zMbcsFilename = 0; ++ } ++ return zMbcsFilename; ++} ++ ++/* ++** Convert UTF-32 to multibyte character string, based on the user's Ansi codepage (CP_ACP). ++** Space to hold the returned string is obtained from sqliteMalloc(). ++*/ ++static char *unicodeToMbcs(const WCHAR *zWideFilename){ ++ int nByte; ++ char *zFilename; ++ ++ nByte = WideCharToMultiByte(CP_ACP, 0, zWideFilename, -1, 0, 0, 0, 0); ++ zFilename = sqliteMalloc( nByte ); ++ if( zFilename==0 ){ ++ return 0; ++ } ++ nByte = WideCharToMultiByte(CP_ACP, 0, zWideFilename, -1, zFilename, nByte, ++ 0, 0); ++ if( nByte == 0 ){ ++ sqliteFree(zFilename); ++ zFilename = 0; ++ } ++ return zFilename; ++} ++ ++/* ++** Convert multibyte character string to UTF-8. Space to hold the returned string is ++** obtained from sqliteMalloc(). ++*/ ++static char *mbcsToUtf8(const char *zFilename){ ++ char *zFilenameUtf8; ++ WCHAR *zTmpWide; ++ ++ zTmpWide = mbcsToUnicode(zFilename); ++ if( zTmpWide==0 ){ ++ return 0; ++ } ++ zFilenameUtf8 = unicodeToUtf8(zTmpWide); ++ sqliteFree(zTmpWide); ++ return zFilenameUtf8; ++} ++ ++/* ++** Convert UTF-8 to multibyte character string. Space to hold the returned string is ++** obtained from sqliteMalloc(). ++*/ ++static char *utf8ToMbcs(const char *zFilename){ ++ char *zFilenameMbcs; ++ WCHAR *zTmpWide; ++ ++ zTmpWide = utf8ToUnicode(zFilename); ++ if( zTmpWide==0 ){ ++ return 0; ++ } ++ zFilenameMbcs = unicodeToMbcs(zTmpWide); ++ sqliteFree(zTmpWide); ++ return zFilenameMbcs; ++} ++ + #if OS_WINCE + /************************************************************************* + ** This section contains code for WinCE only. + */ + /* + ** WindowsCE does not have a localtime() function. So create a + ** substitute. + */ +@@ -470,51 +544,58 @@ static BOOL winceLockFileEx( + } + return FALSE; + } + /* + ** End of the special code for wince + *****************************************************************************/ + #endif /* OS_WINCE */ + ++static void *convertUtf8Filename(const char *zFilename){ ++ void *zConverted = 0; ++ if( isNT() ){ ++ zConverted = utf8ToUnicode(zFilename); ++ }else{ ++ zConverted = utf8ToMbcs(zFilename); ++ } ++ /* caller will handle out of memory */ ++ return zConverted; ++} ++ + /* + ** Delete the named file + */ + int sqlite3WinDelete(const char *zFilename){ +- WCHAR *zWide = utf8ToUnicode(zFilename); +- if( zWide ){ +- DeleteFileW(zWide); +- sqliteFree(zWide); +- }else{ +-#if OS_WINCE ++ void *zConverted = convertUtf8Filename(zFilename); ++ if( zConverted==0 ) + return SQLITE_NOMEM; +-#else +- DeleteFileA(zFilename); +-#endif ++ if( isNT() ){ ++ DeleteFileW((WCHAR*)zConverted); ++ }else{ ++ DeleteFileA((char*)zConverted); + } ++ sqliteFree(zConverted); + TRACE2("DELETE \"%s\"\n", zFilename); + return SQLITE_OK; + } + + /* + ** Return TRUE if the named file exists. + */ + int sqlite3WinFileExists(const char *zFilename){ + int exists = 0; +- WCHAR *zWide = utf8ToUnicode(zFilename); +- if( zWide ){ +- exists = GetFileAttributesW(zWide) != 0xffffffff; +- sqliteFree(zWide); +- }else{ +-#if OS_WINCE ++ void *zConverted = convertUtf8Filename(zFilename); ++ if( zConverted==0 ) + return SQLITE_NOMEM; +-#else +- exists = GetFileAttributesA(zFilename) != 0xffffffff; +-#endif ++ if( isNT() ){ ++ exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff; ++ }else{ ++ exists = GetFileAttributesA((char*)zConverted) != 0xffffffff; + } ++ sqliteFree(zConverted); + return exists; + } + + /* Forward declaration */ + static int allocateWinFile(winFile *pInit, OsFile **pId); + + /* + ** Attempt to open a file for both reading and writing. If that +@@ -531,82 +612,84 @@ static int allocateWinFile(winFile *pIni + */ + int sqlite3WinOpenReadWrite( + const char *zFilename, + OsFile **pId, + int *pReadonly + ){ + winFile f; + HANDLE h; +- WCHAR *zWide = utf8ToUnicode(zFilename); ++ void *zConverted = convertUtf8Filename(zFilename); ++ if( zConverted==0 ) ++ return SQLITE_NOMEM; + assert( *pId==0 ); +- if( zWide ){ +- h = CreateFileW(zWide, ++ ++ if( isNT() ){ ++ h = CreateFileW((WCHAR*)zConverted, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, + NULL + ); + if( h==INVALID_HANDLE_VALUE ){ +- h = CreateFileW(zWide, ++ h = CreateFileW((WCHAR*)zConverted, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, + NULL + ); + if( h==INVALID_HANDLE_VALUE ){ +- sqliteFree(zWide); ++ sqliteFree(zConverted); + return SQLITE_CANTOPEN; + } + *pReadonly = 1; + }else{ + *pReadonly = 0; + } + #if OS_WINCE + if (!winceCreateLock(zFilename, &f)){ + CloseHandle(h); +- sqliteFree(zWide); ++ sqliteFree(zConverted); + return SQLITE_CANTOPEN; + } + #endif +- sqliteFree(zWide); + }else{ +-#if OS_WINCE +- return SQLITE_NOMEM; +-#else +- h = CreateFileA(zFilename, ++ h = CreateFileA((char*)zConverted, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, + NULL + ); + if( h==INVALID_HANDLE_VALUE ){ +- h = CreateFileA(zFilename, ++ h = CreateFileA((char*)zConverted, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, + NULL + ); + if( h==INVALID_HANDLE_VALUE ){ ++ sqliteFree(zConverted); + return SQLITE_CANTOPEN; + } + *pReadonly = 1; + }else{ + *pReadonly = 0; + } +-#endif /* OS_WINCE */ + } ++ ++ sqliteFree(zConverted); ++ + f.h = h; + #if OS_WINCE + f.zDeleteOnClose = 0; + #endif + TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename); + return allocateWinFile(&f, pId); + } + +@@ -624,48 +707,46 @@ int sqlite3WinOpenReadWrite( + ** On success, write the file handle into *id and return SQLITE_OK. + ** + ** On failure, return SQLITE_CANTOPEN. + */ + int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ + winFile f; + HANDLE h; + int fileflags; +- WCHAR *zWide = utf8ToUnicode(zFilename); ++ void *zConverted = convertUtf8Filename(zFilename); ++ if( zConverted==0 ) ++ return SQLITE_NOMEM; + assert( *pId == 0 ); + fileflags = FILE_FLAG_RANDOM_ACCESS; + #if !OS_WINCE + if( delFlag ){ + fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE; + } + #endif +- if( zWide ){ +- h = CreateFileW(zWide, ++ if( isNT() ){ ++ h = CreateFileW((WCHAR*)zConverted, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + fileflags, + NULL + ); +- sqliteFree(zWide); + }else{ +-#if OS_WINCE +- return SQLITE_NOMEM; +-#else +- h = CreateFileA(zFilename, ++ h = CreateFileA((char*)zConverted, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + fileflags, + NULL + ); +-#endif /* OS_WINCE */ + } ++ sqliteFree(zConverted); + if( h==INVALID_HANDLE_VALUE ){ + return SQLITE_CANTOPEN; + } + f.h = h; + #if OS_WINCE + f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0; + f.hMutex = NULL; + #endif +@@ -678,42 +759,40 @@ int sqlite3WinOpenExclusive(const char * + ** + ** On success, write the file handle into *id and return SQLITE_OK. + ** + ** On failure, return SQLITE_CANTOPEN. + */ + int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ + winFile f; + HANDLE h; +- WCHAR *zWide = utf8ToUnicode(zFilename); ++ void *zConverted = convertUtf8Filename(zFilename); ++ if( zConverted==0 ) ++ return SQLITE_NOMEM; + assert( *pId==0 ); +- if( zWide ){ +- h = CreateFileW(zWide, ++ if( isNT() ){ ++ h = CreateFileW((WCHAR*)zConverted, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, + NULL + ); +- sqliteFree(zWide); + }else{ +-#if OS_WINCE +- return SQLITE_NOMEM; +-#else +- h = CreateFileA(zFilename, ++ h = CreateFileA((char*)zConverted, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, + NULL + ); +-#endif + } ++ sqliteFree(zConverted); + if( h==INVALID_HANDLE_VALUE ){ + return SQLITE_CANTOPEN; + } + f.h = h; + #if OS_WINCE + f.zDeleteOnClose = 0; + f.hMutex = NULL; + #endif +@@ -769,19 +848,31 @@ int sqlite3WinTempFileName(char *zBuf){ + char *zMulti; + WCHAR zWidePath[SQLITE_TEMPNAME_SIZE]; + GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath); + zMulti = unicodeToUtf8(zWidePath); + if( zMulti ){ + strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30); + zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0; + sqliteFree(zMulti); ++ }else{ ++ return SQLITE_NOMEM; + } + }else{ +- GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath); ++ char *zUtf8; ++ char zMbcsPath[SQLITE_TEMPNAME_SIZE]; ++ GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zMbcsPath); ++ zUtf8 = mbcsToUtf8(zMbcsPath); ++ if( zUtf8 ){ ++ strncpy(zTempPath, zUtf8, SQLITE_TEMPNAME_SIZE-30); ++ zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0; ++ sqliteFree(zUtf8); ++ }else{ ++ return SQLITE_NOMEM; ++ } + } + for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} + zTempPath[i] = 0; + for(;;){ + sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath); + j = strlen(zBuf); + sqlite3Randomness(15, &zBuf[j]); + for(i=0; i<15; i++, j++){ +@@ -977,30 +1068,29 @@ static int unlockReadLock(winFile *pFile + + #ifndef SQLITE_OMIT_PAGER_PRAGMAS + /* + ** Check that a given pathname is a directory and is writable + ** + */ + int sqlite3WinIsDirWritable(char *zDirname){ + int fileAttr; +- WCHAR *zWide; ++ void *zConverted; + if( zDirname==0 ) return 0; + if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0; +- zWide = utf8ToUnicode(zDirname); +- if( zWide ){ +- fileAttr = GetFileAttributesW(zWide); +- sqliteFree(zWide); ++ ++ zConverted = convertUtf8Filename(zDirname); ++ if( zConverted==0 ) ++ return SQLITE_NOMEM; ++ if( isNT() ){ ++ fileAttr = GetFileAttributesW((WCHAR*)zConverted); + }else{ +-#if OS_WINCE +- return 0; +-#else +- fileAttr = GetFileAttributesA(zDirname); +-#endif ++ fileAttr = GetFileAttributesA((char*)zConverted); + } ++ sqliteFree(zConverted); + if( fileAttr == 0xffffffff ) return 0; + if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){ + return 0; + } + return 1; + } + #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + +@@ -1213,34 +1303,43 @@ char *sqlite3WinFullPathname(const char + nByte = strlen(zRelative) + MAX_PATH + 1001; + zFull = sqliteMalloc( nByte ); + if( zFull==0 ) return 0; + if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0; + #elif OS_WINCE + /* WinCE has no concept of a relative pathname, or so I am told. */ + zFull = sqliteStrDup(zRelative); + #else +- char *zNotUsed; +- WCHAR *zWide; + int nByte; +- zWide = utf8ToUnicode(zRelative); +- if( zWide ){ ++ void *zConverted; ++ zConverted = convertUtf8Filename(zRelative); ++ if( isNT() ){ + WCHAR *zTemp, *zNotUsedW; +- nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1; ++ nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, &zNotUsedW) + 1; + zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) ); +- if( zTemp==0 ) return 0; +- GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW); +- sqliteFree(zWide); ++ if( zTemp==0 ){ ++ sqliteFree(zConverted); ++ return 0; ++ } ++ GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, &zNotUsedW); ++ sqliteFree(zConverted); + zFull = unicodeToUtf8(zTemp); + sqliteFree(zTemp); + }else{ +- nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1; +- zFull = sqliteMalloc( nByte*sizeof(zFull[0]) ); +- if( zFull==0 ) return 0; +- GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed); ++ char *zTemp, *zNotUsed; ++ nByte = GetFullPathNameA((char*)zConverted, 0, 0, &zNotUsed) + 1; ++ zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) ); ++ if( zTemp==0 ){ ++ sqliteFree(zConverted); ++ return 0; ++ } ++ GetFullPathNameA((char*)zConverted, nByte, zTemp, &zNotUsed); ++ sqliteFree(zConverted); ++ zFull = mbcsToUtf8(zTemp); ++ sqliteFree(zTemp); + } + #endif + return zFull; + } + + /* + ** The fullSync option is meaningless on windows. This is a no-op. + */ diff --git a/mozilla/db/sqlite3/src/os_win.c b/mozilla/db/sqlite3/src/os_win.c index def901e5038..5515b1cda7a 100644 --- a/mozilla/db/sqlite3/src/os_win.c +++ b/mozilla/db/sqlite3/src/os_win.c @@ -131,9 +131,6 @@ static WCHAR *utf8ToUnicode(const char *zFilename){ int nChar; WCHAR *zWideFilename; - if( !isNT() ){ - return 0; - } nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ @@ -169,6 +166,83 @@ static char *unicodeToUtf8(const WCHAR *zWideFilename){ return zFilename; } +/* +** Convert a multibyte character string to UTF-32, based on the current Ansi codepage (CP_ACP). +** Space to hold the returned string is obtained from sqliteMalloc. +*/ +static WCHAR *mbcsToUnicode(const char *zFilename){ + int nByte; + WCHAR *zMbcsFilename; + + nByte = MultiByteToWideChar(CP_ACP, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR); + zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) ); + if( zMbcsFilename==0 ){ + return 0; + } + nByte = MultiByteToWideChar(CP_ACP, 0, zFilename, -1, zMbcsFilename, nByte); + if( nByte==0 ){ + sqliteFree(zMbcsFilename); + zMbcsFilename = 0; + } + return zMbcsFilename; +} + +/* +** Convert UTF-32 to multibyte character string, based on the user's Ansi codepage (CP_ACP). +** Space to hold the returned string is obtained from sqliteMalloc(). +*/ +static char *unicodeToMbcs(const WCHAR *zWideFilename){ + int nByte; + char *zFilename; + + nByte = WideCharToMultiByte(CP_ACP, 0, zWideFilename, -1, 0, 0, 0, 0); + zFilename = sqliteMalloc( nByte ); + if( zFilename==0 ){ + return 0; + } + nByte = WideCharToMultiByte(CP_ACP, 0, zWideFilename, -1, zFilename, nByte, + 0, 0); + if( nByte == 0 ){ + sqliteFree(zFilename); + zFilename = 0; + } + return zFilename; +} + +/* +** Convert multibyte character string to UTF-8. Space to hold the returned string is +** obtained from sqliteMalloc(). +*/ +static char *mbcsToUtf8(const char *zFilename){ + char *zFilenameUtf8; + WCHAR *zTmpWide; + + zTmpWide = mbcsToUnicode(zFilename); + if( zTmpWide==0 ){ + return 0; + } + zFilenameUtf8 = unicodeToUtf8(zTmpWide); + sqliteFree(zTmpWide); + return zFilenameUtf8; +} + +/* +** Convert UTF-8 to multibyte character string. Space to hold the returned string is +** obtained from sqliteMalloc(). +*/ +static char *utf8ToMbcs(const char *zFilename){ + char *zFilenameMbcs; + WCHAR *zTmpWide; + + zTmpWide = utf8ToUnicode(zFilename); + if( zTmpWide==0 ){ + return 0; + } + zFilenameMbcs = unicodeToMbcs(zTmpWide); + sqliteFree(zTmpWide); + return zFilenameMbcs; +} + #if OS_WINCE /************************************************************************* ** This section contains code for WinCE only. @@ -475,21 +549,30 @@ static BOOL winceLockFileEx( *****************************************************************************/ #endif /* OS_WINCE */ +static void *convertUtf8Filename(const char *zFilename){ + void *zConverted = 0; + if( isNT() ){ + zConverted = utf8ToUnicode(zFilename); + }else{ + zConverted = utf8ToMbcs(zFilename); + } + /* caller will handle out of memory */ + return zConverted; +} + /* ** Delete the named file */ int sqlite3WinDelete(const char *zFilename){ - WCHAR *zWide = utf8ToUnicode(zFilename); - if( zWide ){ - DeleteFileW(zWide); - sqliteFree(zWide); - }else{ -#if OS_WINCE + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ) return SQLITE_NOMEM; -#else - DeleteFileA(zFilename); -#endif + if( isNT() ){ + DeleteFileW((WCHAR*)zConverted); + }else{ + DeleteFileA((char*)zConverted); } + sqliteFree(zConverted); TRACE2("DELETE \"%s\"\n", zFilename); return SQLITE_OK; } @@ -499,17 +582,15 @@ int sqlite3WinDelete(const char *zFilename){ */ int sqlite3WinFileExists(const char *zFilename){ int exists = 0; - WCHAR *zWide = utf8ToUnicode(zFilename); - if( zWide ){ - exists = GetFileAttributesW(zWide) != 0xffffffff; - sqliteFree(zWide); - }else{ -#if OS_WINCE + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ) return SQLITE_NOMEM; -#else - exists = GetFileAttributesA(zFilename) != 0xffffffff; -#endif + if( isNT() ){ + exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff; + }else{ + exists = GetFileAttributesA((char*)zConverted) != 0xffffffff; } + sqliteFree(zConverted); return exists; } @@ -536,10 +617,13 @@ int sqlite3WinOpenReadWrite( ){ winFile f; HANDLE h; - WCHAR *zWide = utf8ToUnicode(zFilename); + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ) + return SQLITE_NOMEM; assert( *pId==0 ); - if( zWide ){ - h = CreateFileW(zWide, + + if( isNT() ){ + h = CreateFileW((WCHAR*)zConverted, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, @@ -548,7 +632,7 @@ int sqlite3WinOpenReadWrite( NULL ); if( h==INVALID_HANDLE_VALUE ){ - h = CreateFileW(zWide, + h = CreateFileW((WCHAR*)zConverted, GENERIC_READ, FILE_SHARE_READ, NULL, @@ -557,7 +641,7 @@ int sqlite3WinOpenReadWrite( NULL ); if( h==INVALID_HANDLE_VALUE ){ - sqliteFree(zWide); + sqliteFree(zConverted); return SQLITE_CANTOPEN; } *pReadonly = 1; @@ -567,16 +651,12 @@ int sqlite3WinOpenReadWrite( #if OS_WINCE if (!winceCreateLock(zFilename, &f)){ CloseHandle(h); - sqliteFree(zWide); + sqliteFree(zConverted); return SQLITE_CANTOPEN; } #endif - sqliteFree(zWide); }else{ -#if OS_WINCE - return SQLITE_NOMEM; -#else - h = CreateFileA(zFilename, + h = CreateFileA((char*)zConverted, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, @@ -585,7 +665,7 @@ int sqlite3WinOpenReadWrite( NULL ); if( h==INVALID_HANDLE_VALUE ){ - h = CreateFileA(zFilename, + h = CreateFileA((char*)zConverted, GENERIC_READ, FILE_SHARE_READ, NULL, @@ -594,14 +674,17 @@ int sqlite3WinOpenReadWrite( NULL ); if( h==INVALID_HANDLE_VALUE ){ + sqliteFree(zConverted); return SQLITE_CANTOPEN; } *pReadonly = 1; }else{ *pReadonly = 0; } -#endif /* OS_WINCE */ } + + sqliteFree(zConverted); + f.h = h; #if OS_WINCE f.zDeleteOnClose = 0; @@ -629,7 +712,9 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ winFile f; HANDLE h; int fileflags; - WCHAR *zWide = utf8ToUnicode(zFilename); + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ) + return SQLITE_NOMEM; assert( *pId == 0 ); fileflags = FILE_FLAG_RANDOM_ACCESS; #if !OS_WINCE @@ -637,8 +722,8 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE; } #endif - if( zWide ){ - h = CreateFileW(zWide, + if( isNT() ){ + h = CreateFileW((WCHAR*)zConverted, GENERIC_READ | GENERIC_WRITE, 0, NULL, @@ -646,12 +731,8 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ fileflags, NULL ); - sqliteFree(zWide); }else{ -#if OS_WINCE - return SQLITE_NOMEM; -#else - h = CreateFileA(zFilename, + h = CreateFileA((char*)zConverted, GENERIC_READ | GENERIC_WRITE, 0, NULL, @@ -659,8 +740,8 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ fileflags, NULL ); -#endif /* OS_WINCE */ } + sqliteFree(zConverted); if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } @@ -683,23 +764,21 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ winFile f; HANDLE h; - WCHAR *zWide = utf8ToUnicode(zFilename); - assert( *pId==0 ); - if( zWide ){ - h = CreateFileW(zWide, - GENERIC_READ, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, - NULL - ); - sqliteFree(zWide); - }else{ -#if OS_WINCE + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ) return SQLITE_NOMEM; -#else - h = CreateFileA(zFilename, + assert( *pId==0 ); + if( isNT() ){ + h = CreateFileW((WCHAR*)zConverted, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, + NULL + ); + }else{ + h = CreateFileA((char*)zConverted, GENERIC_READ, 0, NULL, @@ -707,8 +786,8 @@ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL ); -#endif } + sqliteFree(zConverted); if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } @@ -774,9 +853,21 @@ int sqlite3WinTempFileName(char *zBuf){ strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30); zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0; sqliteFree(zMulti); + }else{ + return SQLITE_NOMEM; } }else{ - GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath); + char *zUtf8; + char zMbcsPath[SQLITE_TEMPNAME_SIZE]; + GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zMbcsPath); + zUtf8 = mbcsToUtf8(zMbcsPath); + if( zUtf8 ){ + strncpy(zTempPath, zUtf8, SQLITE_TEMPNAME_SIZE-30); + zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0; + sqliteFree(zUtf8); + }else{ + return SQLITE_NOMEM; + } } for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; @@ -982,20 +1073,19 @@ static int unlockReadLock(winFile *pFile){ */ int sqlite3WinIsDirWritable(char *zDirname){ int fileAttr; - WCHAR *zWide; + void *zConverted; if( zDirname==0 ) return 0; if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0; - zWide = utf8ToUnicode(zDirname); - if( zWide ){ - fileAttr = GetFileAttributesW(zWide); - sqliteFree(zWide); + + zConverted = convertUtf8Filename(zDirname); + if( zConverted==0 ) + return SQLITE_NOMEM; + if( isNT() ){ + fileAttr = GetFileAttributesW((WCHAR*)zConverted); }else{ -#if OS_WINCE - return 0; -#else - fileAttr = GetFileAttributesA(zDirname); -#endif + fileAttr = GetFileAttributesA((char*)zConverted); } + sqliteFree(zConverted); if( fileAttr == 0xffffffff ) return 0; if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){ return 0; @@ -1218,24 +1308,33 @@ char *sqlite3WinFullPathname(const char *zRelative){ /* WinCE has no concept of a relative pathname, or so I am told. */ zFull = sqliteStrDup(zRelative); #else - char *zNotUsed; - WCHAR *zWide; int nByte; - zWide = utf8ToUnicode(zRelative); - if( zWide ){ + void *zConverted; + zConverted = convertUtf8Filename(zRelative); + if( isNT() ){ WCHAR *zTemp, *zNotUsedW; - nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1; + nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, &zNotUsedW) + 1; zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) ); - if( zTemp==0 ) return 0; - GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW); - sqliteFree(zWide); + if( zTemp==0 ){ + sqliteFree(zConverted); + return 0; + } + GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, &zNotUsedW); + sqliteFree(zConverted); zFull = unicodeToUtf8(zTemp); sqliteFree(zTemp); }else{ - nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1; - zFull = sqliteMalloc( nByte*sizeof(zFull[0]) ); - if( zFull==0 ) return 0; - GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed); + char *zTemp, *zNotUsed; + nByte = GetFullPathNameA((char*)zConverted, 0, 0, &zNotUsed) + 1; + zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqliteFree(zConverted); + return 0; + } + GetFullPathNameA((char*)zConverted, nByte, zTemp, &zNotUsed); + sqliteFree(zConverted); + zFull = mbcsToUtf8(zTemp); + sqliteFree(zTemp); } #endif return zFull;