Commit 1eefa7ea authored by Antoine Cellerier's avatar Antoine Cellerier

Win95/98/Me file opening and stat "fix". Thanks to Quovodis for the help (even...

Win95/98/Me file opening and stat "fix". Thanks to Quovodis for the help (even though we finaly came back to an easy solution).
parent 346168e0
...@@ -319,22 +319,22 @@ FILE *utf8_fopen( const char *filename, const char *mode ) ...@@ -319,22 +319,22 @@ FILE *utf8_fopen( const char *filename, const char *mode )
errno = ENOENT; errno = ENOENT;
return NULL; return NULL;
#else #else
wchar_t wpath[MAX_PATH + 1];
size_t len = strlen( mode ) + 1;
wchar_t wmode[len];
if( !MultiByteToWideChar( CP_UTF8, 0, filename, -1, wpath, MAX_PATH )
|| !MultiByteToWideChar( CP_ACP, 0, mode, len, wmode, len ) )
{
errno = ENOENT;
return NULL;
}
wpath[MAX_PATH] = L'\0';
/* retrieve OS version */ /* retrieve OS version */
if( GetVersion() < 0x80000000 ) if( GetVersion() < 0x80000000 )
{ {
/* for Windows NT and above */ /* for Windows NT and above */
wchar_t wpath[MAX_PATH + 1];
size_t len = strlen( mode ) + 1;
wchar_t wmode[len];
if( !MultiByteToWideChar( CP_UTF8, 0, filename, -1, wpath, MAX_PATH )
|| !MultiByteToWideChar( CP_ACP, 0, mode, len, wmode, len ) )
{
errno = ENOENT;
return NULL;
}
wpath[MAX_PATH] = L'\0';
/* /*
* fopen() cannot open files with non-“ANSI” characters on Windows. * fopen() cannot open files with non-“ANSI” characters on Windows.
* We use _wfopen() instead. Same thing for mkdir() and stat(). * We use _wfopen() instead. Same thing for mkdir() and stat().
...@@ -344,17 +344,38 @@ FILE *utf8_fopen( const char *filename, const char *mode ) ...@@ -344,17 +344,38 @@ FILE *utf8_fopen( const char *filename, const char *mode )
else else
{ {
/* for Windows Me/98/95 */ /* for Windows Me/98/95 */
const char *local_name = ToLocale( filename );
if( local_name != NULL )
{
FILE *p_file = fopen( local_name, mode );
LocaleFree( local_name );
return p_file;
}
errno = ENOENT;
return NULL;
#if 0
/* Following code might work better in most cases but fails if file
doesn't already exist on call to GetShortPathNameW.
I'll keep it here in case we ever decide to try this first and
then fallback to previous solution if it fails. */
/* we use GetShortFileNameW to get the DOS 8.3 version of the file we need to open */ /* we use GetShortFileNameW to get the DOS 8.3 version of the file we need to open */
char spath[MAX_PATH + 1]; wchar_t spath[MAX_PATH + 1];
if( GetShortPathNameW( wpath, spath, MAX_PATH ) ) if( GetShortPathNameW( wpath, spath, MAX_PATH ) )
{ {
fprintf( stderr, "A fopen path: %s -> %s\n", wpath, spath ); char path[ MAX_PATH + 1 ];
fwprintf( stderr, "W fopen path: %s -> %s\n", wpath, spath ); int len;
return fopen( spath, wmode ); UINT i_codepage = AreFileApisANSI()?GetACP():GetOEMCP();
len = WideCharToMultiByte( i_codepage, 0, spath, -1, NULL, 0, NULL, NULL );
if( len == 0 )
return NULL;
WideCharToMultiByte( i_codepage, 0, spath, -1, path, len, NULL, NULL );
return fopen( path, mode );
} }
fprintf( stderr, "GetShortPathName for %s failed\n", wpath );
errno = ENOENT; errno = ENOENT;
return NULL; return NULL;
#endif
} }
#endif #endif
} }
...@@ -528,34 +549,56 @@ static int utf8_statEx( const char *filename, void *buf, ...@@ -528,34 +549,56 @@ static int utf8_statEx( const char *filename, void *buf,
# endif # endif
return -1; return -1;
#else #else
wchar_t wpath[MAX_PATH + 1];
if( !MultiByteToWideChar( CP_UTF8, 0, filename, -1, wpath, MAX_PATH ) )
{
errno = ENOENT;
return -1;
}
wpath[MAX_PATH] = L'\0';
/* retrieve Windows OS version */ /* retrieve Windows OS version */
if( GetVersion() < 0x80000000 ) if( GetVersion() < 0x80000000 )
{ {
/* for Windows NT and above */ /* for Windows NT and above */
wchar_t wpath[MAX_PATH + 1];
if( !MultiByteToWideChar( CP_UTF8, 0, filename, -1, wpath, MAX_PATH ) )
{
errno = ENOENT;
return -1;
}
wpath[MAX_PATH] = L'\0';
return _wstati64( wpath, (struct _stati64 *)buf ); return _wstati64( wpath, (struct _stati64 *)buf );
} }
else else
{ {
/* for Windows Me/98/95 */ /* for Windows Me/98/95 */
const char *local_name = ToLocale( filename );
if( local_name != NULL )
{
int res = _stati64( local_name, (struct stat *)buf );
LocaleFree( local_name );
return res;
}
errno = ENOENT;
return -1;
#if 0
/* Following code might work better in most cases but fails if file
doesn't already exist on call to GetShortPathNameW.
I'll keep it here in case we ever decide to try this first and
then fallback to previous solution if it fails. */
/* we use GetShortFileNameW to get the DOS 8.3 version */ /* we use GetShortFileNameW to get the DOS 8.3 version */
char spath[MAX_PATH + 1]; wchar_t spath[MAX_PATH + 1];
if( GetShortPathNameW( wpath, spath, MAX_PATH ) ) if( GetShortPathNameW( wpath, spath, MAX_PATH ) )
{ {
fprintf( stderr, "stati path: %s -> %s\n", wpath, spath ); char path[ MAX_PATH + 1 ];
return _stati64( spath, (struct _stati64 *)buf ); int len;
UINT i_codepage = AreFileApisANSI()?GetACP():GetOEMCP();
len = WideCharToMultiByte( i_codepage, 0, spath, -1, NULL, 0, NULL, NULL );
if( len == 0 )
return -1;
WideCharToMultiByte( i_codepage, 0, spath, -1, path, len, NULL, NULL );
return _stati64( path, (struct _stati64 *)buf );
} }
fprintf( stderr, "GetShortPathName for %s failed\n", wpath );
errno = ENOENT; errno = ENOENT;
return -1; return -1;
#endif
} }
#endif #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment