← Commit list

969351bb1e

Viktor Szakats
Viktor Szakats
2025-12-20
SUCCESS Duration: 203s

Subject

windows: fix `CreateFile()` calls to support long filenames

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

docs/internals/CODE_STYLE.md+3 -0
@@ -353,6 +353,9 @@ This is the full list of functions generally banned.
atoi
atol
calloc
+ CreateFile
+ CreateFileA
+ CreateFileW
fclose
fdopen
fopen
lib/curlx/fopen.c+45 -0
@@ -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;
lib/curlx/fopen.h+9 -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);
lib/vtls/schannel_verify.c+9 -19
@@ -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;
}
scripts/checksrc.pl+3 -0
@@ -70,6 +70,9 @@ my %banfunc = (
"atoi" => 1,
"atol" => 1,
"calloc" => 1,
+ "CreateFile" => 1,
+ "CreateFileA" => 1,
+ "CreateFileW" => 1,
"fclose" => 1,
"fdopen" => 1,
"fopen" => 1,
src/tool_filetime.c+6 -11
@@ -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;