Last Comment Bug 329898 - start page is not displayed/bookmarks is empty on Win9x if non-ascii characters in profile path
: start page is not displayed/bookmarks is empty on Win9x if non-ascii characte...
Status: VERIFIED FIXED
[cal relnote] [has patch][needs appro...
: intl, jp-critical, verified1.8.1
Product: Toolkit
Classification: Components
Component: Storage (show other bugs)
: 1.8 Branch
: x86 Windows 98
: -- normal (vote)
: mozilla1.8.1beta2
Assigned To: Vladimir Vukicevic [:vlad] [:vladv]
:
Mentors:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2006-03-09 06:03 PST by Masatoshi Kimura [:emk]
Modified: 2007-01-08 11:06 PST (History)
12 users (show)
mconnor: blocking‑firefox2+
benjamin: in‑testsuite?
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
use correct non-wide-char codepage for calling *A API functions in win32 (13.83 KB, patch)
2006-07-18 15:38 PDT, Vladimir Vukicevic [:vlad] [:vladv]
brettw: first‑review+
mtschrep: approval1.8.1+
Details | Diff | Review

Description Masatoshi Kimura [:emk] 2006-03-09 06:03:26 PST
This is a regression of bug 324311.
sqlite3_open expects UTF-8 on WinNT while it expects ANSI charset on Win9x.
Related SQLite Tickets:
http://www.sqlite.org/cvstrac/tktview?tn=1533
http://www.sqlite.org/cvstrac/tktview?tn=1592
Comment 1 Nickolay_Ponomarev 2006-03-09 11:38:58 PST
This bug is due to sqlite not following its own documentation. There is a patch in ticket 1592, so maybe it could be applied to mozilla's version of sqlite.

Asking for blocking firefox2, because I think it's supposed to support win98.
Comment 2 Dan Mosedale (:dmose) 2006-03-09 17:09:33 PST
This problem will effect Calendar also, but I don't think it's worth holding Lightning 0.1 for this.
Comment 3 Masayuki Nakano [:masayuki] (Mozilla Japan) 2006-03-10 09:59:37 PST
I confirmed this problem.
+jp-critical
Comment 4 Masatoshi Kimura [:emk] 2006-03-13 04:03:27 PST
BTW, we should use CP_ACP instead of CP_THREAD_ACP which is used by the patch in ticket 1592 because CP_THREAD_ACP is supported only on Win2k or later.
Comment 5 Mike Connor [:mconnor] 2006-03-13 09:10:24 PST
Vlad, can you take this/suggest an appropriate owner?
Comment 6 Mike Schroepfer 2006-06-27 21:27:07 PDT
Vlad - thoughts on whether this is still an issue?
Comment 7 Vladimir Vukicevic [:vlad] [:vladv] 2006-06-28 13:14:52 PDT
It is; I can take it.
Comment 8 Mike Connor [:mconnor] 2006-07-17 23:42:44 PDT
Vlad, what's up here?
Comment 9 Vladimir Vukicevic [:vlad] [:vladv] 2006-07-18 14:32:13 PDT
I'm still working on cleaning up the patch from http://www.sqlite.org/cvstrac/tktview?tn=1592 -- the problem is that it makes a bunch of boilerplate changes that I think could be handled in a cleaner way.
Comment 10 Vladimir Vukicevic [:vlad] [:vladv] 2006-07-18 15:38:07 PDT
Created attachment 229734 [details] [diff] [review]
use correct non-wide-char codepage for calling *A API functions in win32

Here's a reworking of the original patch in the sqlite tracker.  I don't really have a good way of testing this though, besides checking that it doesn't break XP.  Could anyone running win95 with a non-ascii locale try this patch out?
Comment 11 Masatoshi Kimura [:emk] 2006-07-19 06:26:54 PDT
(In reply to comment #10)
> Could anyone running win95 with a non-ascii locale try this patch out?
This patch would never work on Win95 because Win95 doesn't support CP_UTF8.
However it's fine dropping support for Win95 if SeaMonkey 1.1 doesn't use storage at all. Firefox isn't supposed to support Win95 anymore.
Cc'ing some SeaMonkey developers.
Comment 12 neil@parkwaycc.co.uk 2006-07-19 09:21:50 PDT
So what would happen if we tried to ship storage on Windows 95? Crash? Hang?

Presumably we can't use (or copy) the core UTF-8 conversion routines?
Comment 13 Masatoshi Kimura [:emk] 2006-07-19 09:48:07 PDT
At present I have no time to build and test, but probably it will start on Win95 anyway (as the summary of this bug implies).
However features depending on storage (for example, autocomplete) wouldn't work.
Did SeaMonkey autocomplete migrate to storage?
Another consideration:
Some extentions may assume that storage is available on Gecko 1.8.1.
Comment 14 Vladimir Vukicevic [:vlad] [:vladv] 2006-07-19 10:22:34 PDT
Windows 95 isn't on the supported OS list for Firefox 2, which is what this bug is blocking.  So this bug is only for Win98.
Comment 15 neil@parkwaycc.co.uk 2006-07-19 10:49:31 PDT
We're not currently shipping storage, but we don't want to find we can't ship storage if it will (say) crash on startup on Windows 95.
Comment 16 Christian :Biesinger (don't email me, ping me on IRC) 2006-07-19 21:42:27 PDT
seamonkey does use storage, doesn't it? for this whatwg dom storage thing...
Comment 17 Vladimir Vukicevic [:vlad] [:vladv] 2006-07-21 01:59:07 PDT
Sorry -- I just realized that I wrote "Win95" when I meant "win98" in my request for testing help.  I apologize for the confusion and for jumping at people when they mentioned win95 after I was the one to mention it first!

I will try to get a build made with this patch tomorrow and set up a win98 VM for a quick test.
Comment 18 Brett Wilson 2006-07-24 13:33:59 PDT
Comment on attachment 229734 [details] [diff] [review]
use correct non-wide-char codepage for calling *A API functions in win32

I don't really understand this, and the patch author says he can't test it, so we should be in great shape.

I think this seems unnecessary:

+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;
+}

Where we use it like this:

+  if( isNT() ){
+    DeleteFileW((WCHAR*)zConverted);
+  }else{
+    DeleteFileA((char*)zConverted);
+  }

It seems like we should just skip the void pointers and casts and call the correct conversion routine in the if statement. If this is what sqlite has in it, though, I guess it is fine.


>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.
> */
Comment 19 Brett Wilson 2006-07-24 13:34:28 PDT
Oops, sorry I quoted the whole patch after my comments.
Comment 20 Vladimir Vukicevic [:vlad] [:vladv] 2006-07-24 14:04:19 PDT
(In reply to comment #18)
> (From update of attachment 229734 [details] [diff] [review] [edit])
> I don't really understand this, and the patch author says he can't test it, so
> we should be in great shape.
> 
> I think this seems unnecessary:
> 
> +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;
> +}
> 
> Where we use it like this:
> 
> +  if( isNT() ){
> +    DeleteFileW((WCHAR*)zConverted);
> +  }else{
> +    DeleteFileA((char*)zConverted);
> +  }
> 
> It seems like we should just skip the void pointers and casts and call the
> correct conversion routine in the if statement. If this is what sqlite has in
> it, though, I guess it is fine.

It will only return NULL in an out of memory condition, and we still need to call sqliteFree() on the result.  So doing the casts seems cleaner than declaring new variables and freeing them separately in the different W/A code paths.

I'm trying to get a branch build with this patch applied though; I've got a Win98 VM here ready for testing and everything!
Comment 21 Vladimir Vukicevic [:vlad] [:vladv] 2006-07-24 14:48:11 PDT
Ok, checked in to trunk; I think the non-cairo trunk builds still run on win98.
Comment 22 Masatoshi Kimura [:emk] 2006-07-25 04:17:19 PDT
No, trunk builds do no longer run on Win9x due to bug 330276.
Comment 23 Vladimir Vukicevic [:vlad] [:vladv] 2006-07-26 13:43:24 PDT
Comment on attachment 229734 [details] [diff] [review]
use correct non-wide-char codepage for calling *A API functions in win32

Checked in on trunk; no adverse effects on winxp that I've seen.  I'd like to get this on the branch as well, so that people who are being affected by this can test.
Comment 24 Vladimir Vukicevic [:vlad] [:vladv] 2006-07-27 15:03:16 PDT
on branch, needs branch testing.
Comment 25 JudyLambert 2006-07-28 06:20:43 PDT
This appears to be the death knell for Windows 95 users for the sake of an obscure and esoteric Windows 9x problem.

Build 2006072801, with a virgin profile, starts with a kernel32.dll crash.

Seems like a rather ignoble end for 95'ers at such a late point in the FF 2.0 effort.
Comment 26 Masatoshi Kimura [:emk] 2006-07-28 07:11:06 PDT
I made a non-ascii user on Win98 with per-user settings.
Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.8.1b1) Gecko/20060727 BonEcho/2.0b1
Search Plug-ins (where are using storage) are not displayed at all. They are displayed if profile path has only ascii char.
Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.8.1b1) Gecko/20060728 BonEcho/2.0b1
Search Plug-ins are listed fine :-)
(In reply to comment #25)
20060727 worked perfectly on Win95, but 20060728 hanged up. I had to kill firefox using Ctrl+Alt+Del twice.
But please file another bug. This bug is now dedicated for Fx2 which dropped a support for Win95.
Comment 27 JudyLambert 2006-07-28 07:55:49 PDT
(In reply to comment #26)
> (In reply to comment #25)
> 20060727 worked perfectly on Win95, but 20060728 hanged up. I had to kill
> firefox using Ctrl+Alt+Del twice.
> But please file another bug. This bug is now dedicated for Fx2 which dropped a
> support for Win95.
> 
OK.  Filed bug 346290

Note You need to log in before you can comment on or make changes to this bug.