mirror of
https://github.com/curl/curl.git
synced 2024-12-15 06:40:09 +08:00
b48db908e0
If libcurl is built with Unicode support for Windows then it is assumed the filename string is Unicode in UTF-8 encoding and it is converted to UTF-16 to be passed to the wide character version of the respective function (eg wstat). However the filename string may actually be in the local encoding so, even if it successfully converted to UTF-16, if it could not be stat/accessed then try again using the local code page version of the function (eg wstat fails try stat). We already do this with fopen (ie wfopen fails try fopen), so I think it makes sense to extend it to stat and access functions. Closes https://github.com/curl/curl/pull/6514
168 lines
4.0 KiB
C
168 lines
4.0 KiB
C
/***************************************************************************
|
|
* _ _ ____ _
|
|
* Project ___| | | | _ \| |
|
|
* / __| | | | |_) | |
|
|
* | (__| |_| | _ <| |___
|
|
* \___|\___/|_| \_\_____|
|
|
*
|
|
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
*
|
|
* This software is licensed as described in the file COPYING, which
|
|
* you should have received as part of this distribution. The terms
|
|
* are also available at https://curl.se/docs/copyright.html.
|
|
*
|
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
|
* copies of the Software, and permit persons to whom the Software is
|
|
* furnished to do so, under the terms of the COPYING file.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
***************************************************************************/
|
|
|
|
/*
|
|
* This file is 'mem-include-scan' clean. See test 1132.
|
|
*/
|
|
|
|
#include "curl_setup.h"
|
|
|
|
#if defined(WIN32)
|
|
|
|
#include "curl_multibyte.h"
|
|
|
|
/*
|
|
* MultiByte conversions using Windows kernel32 library.
|
|
*/
|
|
|
|
wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8)
|
|
{
|
|
wchar_t *str_w = NULL;
|
|
|
|
if(str_utf8) {
|
|
int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
|
|
str_utf8, -1, NULL, 0);
|
|
if(str_w_len > 0) {
|
|
str_w = malloc(str_w_len * sizeof(wchar_t));
|
|
if(str_w) {
|
|
if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
|
str_w_len) == 0) {
|
|
free(str_w);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return str_w;
|
|
}
|
|
|
|
char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
|
|
{
|
|
char *str_utf8 = NULL;
|
|
|
|
if(str_w) {
|
|
int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1,
|
|
NULL, 0, NULL, NULL);
|
|
if(bytes > 0) {
|
|
str_utf8 = malloc(bytes);
|
|
if(str_utf8) {
|
|
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes,
|
|
NULL, NULL) == 0) {
|
|
free(str_utf8);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return str_utf8;
|
|
}
|
|
|
|
#endif /* WIN32 */
|
|
|
|
#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES)
|
|
|
|
int curlx_win32_open(const char *filename, int oflag, ...)
|
|
{
|
|
int pmode = 0;
|
|
|
|
#ifdef _UNICODE
|
|
int result = -1;
|
|
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
|
#endif
|
|
|
|
va_list param;
|
|
va_start(param, oflag);
|
|
if(oflag & O_CREAT)
|
|
pmode = va_arg(param, int);
|
|
va_end(param);
|
|
|
|
#ifdef _UNICODE
|
|
if(filename_w)
|
|
result = _wopen(filename_w, oflag, pmode);
|
|
free(filename_w);
|
|
if(result != -1)
|
|
return result;
|
|
#endif
|
|
|
|
return (_open)(filename, oflag, pmode);
|
|
}
|
|
|
|
FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
|
{
|
|
#ifdef _UNICODE
|
|
FILE *result = NULL;
|
|
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
|
wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
|
|
if(filename_w && mode_w)
|
|
result = _wfopen(filename_w, mode_w);
|
|
free(filename_w);
|
|
free(mode_w);
|
|
if(result)
|
|
return result;
|
|
#endif
|
|
|
|
return (fopen)(filename, mode);
|
|
}
|
|
|
|
int curlx_win32_stat(const char *path, struct_stat *buffer)
|
|
{
|
|
int result = -1;
|
|
#ifdef _UNICODE
|
|
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
|
if(path_w) {
|
|
#if defined(USE_WIN32_SMALL_FILES)
|
|
result = _wstat(path_w, buffer);
|
|
#else
|
|
result = _wstati64(path_w, buffer);
|
|
#endif
|
|
free(path_w);
|
|
if(result != -1)
|
|
return result;
|
|
}
|
|
#endif /* _UNICODE */
|
|
|
|
#if defined(USE_WIN32_SMALL_FILES)
|
|
result = _stat(path, buffer);
|
|
#else
|
|
result = _stati64(path, buffer);
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
int curlx_win32_access(const char *path, int mode)
|
|
{
|
|
#if defined(_UNICODE)
|
|
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
|
if(path_w) {
|
|
int result = _waccess(path_w, mode);
|
|
free(path_w);
|
|
if(result != -1)
|
|
return result;
|
|
}
|
|
#endif /* _UNICODE */
|
|
return _access(path, mode);
|
|
}
|
|
|
|
#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
|