windows: fix `CreateFile()` calls to support long filenames
No binary (build failed)
—
(log yok)
| @@ -353,6 +353,9 @@ This is the full list of functions generally banned. | |
| atoi | |
| atol | |
| calloc | |
| + | CreateFile |
| + | CreateFileA |
| + | CreateFileW |
| fclose | |
| fdopen | |
| fopen | |
| @@ -43,6 +43,8 @@ int curlx_fseek(void *stream, curl_off_t offset, int whence) | |
| #include <share.h> /* for _SH_DENYNO */ | |
| + | #include "multibyte.h" |
| + | |
| #ifdef CURLDEBUG | |
| /* | |
| * Use system allocators to avoid infinite recursion when called by curl's | |
| @@ -248,6 +250,49 @@ cleanup: | |
| return *out ? true : false; | |
| } | |
| + | #ifndef CURL_WINDOWS_UWP |
| + | HANDLE curlx_CreateFile(const char *filename, |
| + | DWORD dwDesiredAccess, |
| + | DWORD dwShareMode, |
| + | LPSECURITY_ATTRIBUTES lpSecurityAttributes, |
| + | DWORD dwCreationDisposition, |
| + | DWORD dwFlagsAndAttributes, |
| + | HANDLE hTemplateFile) |
| + | { |
| + | HANDLE handle = INVALID_HANDLE_VALUE; |
| + | |
| + | #ifdef UNICODE |
| + | TCHAR *filename_t = curlx_convert_UTF8_to_wchar(filename); |
| + | #else |
| + | const TCHAR *filename_t = filename; |
| + | #endif |
| + | |
| + | if(filename_t) { |
| + | TCHAR *fixed = NULL; |
| + | const TCHAR *target = NULL; |
| + | |
| + | if(fix_excessive_path(filename_t, &fixed)) |
| + | target = fixed; |
| + | else |
| + | target = filename_t; |
| + | /* !checksrc! disable BANNEDFUNC 1 */ |
| + | handle = CreateFile(target, |
| + | dwDesiredAccess, |
| + | dwShareMode, |
| + | lpSecurityAttributes, |
| + | dwCreationDisposition, |
| + | dwFlagsAndAttributes, |
| + | hTemplateFile); |
| + | CURLX_FREE(fixed); |
| + | #ifdef UNICODE |
| + | curlx_free(filename_t); |
| + | #endif |
| + | } |
| + | |
| + | return handle; |
| + | } |
| + | #endif /* !CURL_WINDOWS_UWP */ |
| + | |
| int curlx_win32_open(const char *filename, int oflag, ...) | |
| { | |
| int pmode = 0; | |
| @@ -35,6 +35,15 @@ | |
| int curlx_fseek(void *stream, curl_off_t offset, int whence); | |
| #ifdef _WIN32 | |
| + | #ifndef CURL_WINDOWS_UWP |
| + | HANDLE curlx_CreateFile(const char *filename, |
| + | DWORD dwDesiredAccess, |
| + | DWORD dwShareMode, |
| + | LPSECURITY_ATTRIBUTES lpSecurityAttributes, |
| + | DWORD dwCreationDisposition, |
| + | DWORD dwFlagsAndAttributes, |
| + | HANDLE hTemplateFile); |
| + | #endif /* !CURL_WINDOWS_UWP */ |
| FILE *curlx_win32_fopen(const char *filename, const char *mode); | |
| FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fh); | |
| int curlx_win32_stat(const char *path, struct_stat *buffer); | |
| @@ -39,6 +39,7 @@ | |
| #include "schannel.h" | |
| #include "schannel_int.h" | |
| + | #include "../curlx/fopen.h" |
| #include "../curlx/inet_pton.h" | |
| #include "vtls.h" | |
| #include "vtls_int.h" | |
| @@ -254,34 +255,24 @@ static CURLcode add_certs_file_to_store(HCERTSTORE trust_store, | |
| struct Curl_easy *data) | |
| { | |
| CURLcode result; | |
| - | HANDLE ca_file_handle = INVALID_HANDLE_VALUE; |
| + | HANDLE ca_file_handle; |
| LARGE_INTEGER file_size; | |
| char *ca_file_buffer = NULL; | |
| - | TCHAR *ca_file_tstr = NULL; |
| size_t ca_file_bufsize = 0; | |
| DWORD total_bytes_read = 0; | |
| - | ca_file_tstr = curlx_convert_UTF8_to_tchar(ca_file); |
| - | if(!ca_file_tstr) { |
| - | char buffer[WINAPI_ERROR_LEN]; |
| - | failf(data, "schannel: invalid path name for CA file '%s': %s", ca_file, |
| - | curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); |
| - | result = CURLE_SSL_CACERT_BADFILE; |
| - | goto cleanup; |
| - | } |
| - | |
| /* | |
| * Read the CA file completely into memory before parsing it. This | |
| * optimizes for the common case where the CA file will be relatively | |
| * small ( < 1 MiB ). | |
| */ | |
| - | ca_file_handle = CreateFile(ca_file_tstr, |
| - | GENERIC_READ, |
| - | FILE_SHARE_READ, |
| - | NULL, |
| - | OPEN_EXISTING, |
| - | FILE_ATTRIBUTE_NORMAL, |
| - | NULL); |
| + | ca_file_handle = curlx_CreateFile(ca_file, |
| + | GENERIC_READ, |
| + | FILE_SHARE_READ, |
| + | NULL, |
| + | OPEN_EXISTING, |
| + | FILE_ATTRIBUTE_NORMAL, |
| + | NULL); |
| if(ca_file_handle == INVALID_HANDLE_VALUE) { | |
| char buffer[WINAPI_ERROR_LEN]; | |
| failf(data, "schannel: failed to open CA file '%s': %s", ca_file, | |
| @@ -347,7 +338,6 @@ cleanup: | |
| CloseHandle(ca_file_handle); | |
| } | |
| Curl_safefree(ca_file_buffer); | |
| - | curlx_free(ca_file_tstr); |
| return result; | |
| } | |
| @@ -70,6 +70,9 @@ my %banfunc = ( | |
| "atoi" => 1, | |
| "atol" => 1, | |
| "calloc" => 1, | |
| + | "CreateFile" => 1, |
| + | "CreateFileA" => 1, |
| + | "CreateFileW" => 1, |
| "fclose" => 1, | |
| "fdopen" => 1, | |
| "fopen" => 1, | |
| @@ -41,12 +41,9 @@ int getfiletime(const char *filename, curl_off_t *stamp) | |
| access to a 64-bit type we can bypass stat and get the times directly. */ | |
| #if defined(_WIN32) && !defined(CURL_WINDOWS_UWP) | |
| HANDLE hfile; | |
| - | TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar(filename); |
| - | |
| - | hfile = CreateFile(tchar_filename, FILE_READ_ATTRIBUTES, |
| - | (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), |
| - | NULL, OPEN_EXISTING, 0, NULL); |
| - | curlx_free(tchar_filename); |
| + | hfile = curlx_CreateFile(filename, FILE_READ_ATTRIBUTES, |
| + | FILE_SHARE_READ | FILE_SHARE_WRITE | |
| + | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); |
| if(hfile != INVALID_HANDLE_VALUE) { | |
| FILETIME ft; | |
| if(GetFileTime(hfile, NULL, NULL, &ft)) { | |
| @@ -93,7 +90,6 @@ void setfiletime(curl_off_t filetime, const char *filename) | |
| access to a 64-bit type we can bypass utime and set the times directly. */ | |
| #if defined(_WIN32) && !defined(CURL_WINDOWS_UWP) | |
| HANDLE hfile; | |
| - | TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar(filename); |
| /* 910670515199 is the maximum Unix filetime that can be used as a Windows | |
| FILETIME without overflow: 30827-12-31T23:59:59. */ | |
| @@ -108,10 +104,9 @@ void setfiletime(curl_off_t filetime, const char *filename) | |
| warnf("Capping set filetime to minimum to avoid overflow"); | |
| } | |
| - | hfile = CreateFile(tchar_filename, FILE_WRITE_ATTRIBUTES, |
| - | (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), |
| - | NULL, OPEN_EXISTING, 0, NULL); |
| - | curlx_free(tchar_filename); |
| + | hfile = curlx_CreateFile(filename, FILE_WRITE_ATTRIBUTES, |
| + | FILE_SHARE_READ | FILE_SHARE_WRITE | |
| + | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); |
| if(hfile != INVALID_HANDLE_VALUE) { | |
| curl_off_t converted = ((curl_off_t)filetime * 10000000) + | |
| 116444736000000000; | |