Index: openssl/crypto/bio/bss_file.c |
=================================================================== |
--- openssl/crypto/bio/bss_file.c (revision 105093) |
+++ openssl/crypto/bio/bss_file.c (working copy) |
@@ -118,11 +118,54 @@ |
BIO *BIO_new_file(const char *filename, const char *mode) |
{ |
- BIO *ret; |
- FILE *file; |
+ BIO *ret; |
+ FILE *file=NULL; |
- if ((file=fopen(filename,mode)) == NULL) |
+#if defined(_WIN32) && defined(CP_UTF8) |
+ int sz, len_0 = (int)strlen(filename)+1; |
+ DWORD flags; |
+ |
+ /* |
+ * Basically there are three cases to cover: a) filename is |
+ * pure ASCII string; b) actual UTF-8 encoded string and |
+ * c) locale-ized string, i.e. one containing 8-bit |
+ * characters that are meaningful in current system locale. |
+ * If filename is pure ASCII or real UTF-8 encoded string, |
+ * MultiByteToWideChar succeeds and _wfopen works. If |
+ * filename is locale-ized string, chances are that |
+ * MultiByteToWideChar fails reporting |
+ * ERROR_NO_UNICODE_TRANSLATION, in which case we fall |
+ * back to fopen... |
+ */ |
+ if ((sz=MultiByteToWideChar(CP_UTF8,(flags=MB_ERR_INVALID_CHARS), |
+ filename,len_0,NULL,0))>0 || |
+ (GetLastError()==ERROR_INVALID_FLAGS && |
+ (sz=MultiByteToWideChar(CP_UTF8,(flags=0), |
+ filename,len_0,NULL,0))>0) |
+ ) |
{ |
+ WCHAR wmode[8]; |
+ WCHAR *wfilename = _alloca(sz*sizeof(WCHAR)); |
+ |
+ if (MultiByteToWideChar(CP_UTF8,flags, |
+ filename,len_0,wfilename,sz) && |
+ MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1, |
+ wmode,sizeof(wmode)/sizeof(wmode[0])) && |
+ (file=_wfopen(wfilename,wmode))==NULL && |
+ (errno==ENOENT || errno==EBADF) |
+ ) /* UTF-8 decode succeeded, but no file, filename |
+ * could still have been locale-ized... */ |
+ file = fopen(filename,mode); |
+ } |
+ else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION) |
+ { |
+ file = fopen(filename,mode); |
+ } |
+#else |
+ file=fopen(filename,mode); |
+#endif |
+ if (file == NULL) |
+ { |
SYSerr(SYS_F_FOPEN,get_last_sys_error()); |
ERR_add_error_data(5,"fopen('",filename,"','",mode,"')"); |
if (errno == ENOENT) |
@@ -131,7 +174,7 @@ |
BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB); |
return(NULL); |
} |
- if ((ret=BIO_new(BIO_s_file_internal())) == NULL) |
+ if ((ret=BIO_new(BIO_s_file())) == NULL) |
{ |
fclose(file); |
return(NULL); |
@@ -286,8 +329,7 @@ |
_setmode(fd,_O_BINARY); |
#elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) |
int fd = fileno((FILE*)ptr); |
- /* Under CLib there are differences in file modes |
- */ |
+ /* Under CLib there are differences in file modes */ |
if (num & BIO_FP_TEXT) |
setmode(fd,O_TEXT); |
else |
@@ -308,7 +350,7 @@ |
else |
_setmode(fd,_O_BINARY); |
} |
-#elif defined(OPENSSL_SYS_OS2) |
+#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) |
int fd = fileno((FILE*)ptr); |
if (num & BIO_FP_TEXT) |
setmode(fd, O_TEXT); |