diff --git a/docs/internals/CODE_STYLE.md b/docs/internals/CODE_STYLE.md index d8f97594f5..9a2709885a 100644 --- a/docs/internals/CODE_STYLE.md +++ b/docs/internals/CODE_STYLE.md @@ -353,6 +353,9 @@ This is the full list of functions generally banned. atoi atol calloc + CreateFile + CreateFileA + CreateFileW fclose fdopen fopen diff --git a/lib/curlx/fopen.c b/lib/curlx/fopen.c index 5de9a13a79..c1399135b3 100644 --- a/lib/curlx/fopen.c +++ b/lib/curlx/fopen.c @@ -43,6 +43,8 @@ int curlx_fseek(void *stream, curl_off_t offset, int whence) #include /* 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; diff --git a/lib/curlx/fopen.h b/lib/curlx/fopen.h index fb3277a17e..bc10812007 100644 --- a/lib/curlx/fopen.h +++ b/lib/curlx/fopen.h @@ -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); diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c index 4f939ea4cb..bb8a30919b 100644 --- a/lib/vtls/schannel_verify.c +++ b/lib/vtls/schannel_verify.c @@ -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; } diff --git a/scripts/checksrc.pl b/scripts/checksrc.pl index 54436b8358..978959008f 100755 --- a/scripts/checksrc.pl +++ b/scripts/checksrc.pl @@ -70,6 +70,9 @@ my %banfunc = ( "atoi" => 1, "atol" => 1, "calloc" => 1, + "CreateFile" => 1, + "CreateFileA" => 1, + "CreateFileW" => 1, "fclose" => 1, "fdopen" => 1, "fopen" => 1, diff --git a/src/tool_filetime.c b/src/tool_filetime.c index a959af9937..afe308f8ad 100644 --- a/src/tool_filetime.c +++ b/src/tool_filetime.c @@ -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;