1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23/*
24 * This file is 'mem-include-scan' clean, which means memdebug.h and
25 * curl_memory.h are purposely not included in this file. See test 1132.
26 *
27 * The functions in this file are curlx functions which are not tracked by the
28 * curl memory tracker memdebug.
29 */
30
31#include "curl_setup.h"
32
33#if defined(WIN32)
34
35#include "curl_multibyte.h"
36
37/*
38 * MultiByte conversions using Windows kernel32 library.
39 */
40
41wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8)
42{
43 wchar_t *str_w = NULL;
44
45 if(str_utf8) {
46 int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
47 str_utf8, -1, NULL, 0);
48 if(str_w_len > 0) {
49 str_w = malloc(str_w_len * sizeof(wchar_t));
50 if(str_w) {
51 if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
52 str_w_len) == 0) {
53 free(str_w);
54 return NULL;
55 }
56 }
57 }
58 }
59
60 return str_w;
61}
62
63char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
64{
65 char *str_utf8 = NULL;
66
67 if(str_w) {
68 int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1,
69 NULL, 0, NULL, NULL);
70 if(bytes > 0) {
71 str_utf8 = malloc(bytes);
72 if(str_utf8) {
73 if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes,
74 NULL, NULL) == 0) {
75 free(str_utf8);
76 return NULL;
77 }
78 }
79 }
80 }
81
82 return str_utf8;
83}
84
85#endif /* WIN32 */
86
87#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES)
88
89int curlx_win32_open(const char *filename, int oflag, ...)
90{
91 int pmode = 0;
92
93#ifdef _UNICODE
94 int result = -1;
95 wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
96#endif
97
98 va_list param;
99 va_start(param, oflag);
100 if(oflag & O_CREAT)
101 pmode = va_arg(param, int);
102 va_end(param);
103
104#ifdef _UNICODE
105 if(filename_w) {
106 result = _wopen(filename_w, oflag, pmode);
107 free(filename_w);
108 }
109 else
110 errno = EINVAL;
111 return result;
112#else
113 return (_open)(filename, oflag, pmode);
114#endif
115}
116
117FILE *curlx_win32_fopen(const char *filename, const char *mode)
118{
119#ifdef _UNICODE
120 FILE *result = NULL;
121 wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
122 wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
123 if(filename_w && mode_w)
124 result = _wfopen(filename_w, mode_w);
125 else
126 errno = EINVAL;
127 free(filename_w);
128 free(mode_w);
129 return result;
130#else
131 return (fopen)(filename, mode);
132#endif
133}
134
135int curlx_win32_stat(const char *path, struct_stat *buffer)
136{
137#ifdef _UNICODE
138 int result = -1;
139 wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
140 if(path_w) {
141#if defined(USE_WIN32_SMALL_FILES)
142 result = _wstat(path_w, buffer);
143#else
144 result = _wstati64(path_w, buffer);
145#endif
146 free(path_w);
147 }
148 else
149 errno = EINVAL;
150 return result;
151#else
152#if defined(USE_WIN32_SMALL_FILES)
153 return _stat(path, buffer);
154#else
155 return _stati64(path, buffer);
156#endif
157#endif
158}
159
160int curlx_win32_access(const char *path, int mode)
161{
162#if defined(_UNICODE)
163 int result = -1;
164 wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
165 if(path_w) {
166 result = _waccess(path_w, mode);
167 free(path_w);
168 }
169 else
170 errno = EINVAL;
171 return result;
172#else
173 return _access(path, mode);
174#endif
175}
176
177#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
178