It makes them work in Schannel's CA bundle loader, and curl tool's
set/get file timestamp operations (e.g. in `-R`/`--remote-time`). Also
to match file open operations, that already support long filenames.
E.g. when using `--remote-time`, fixing:
```
Warning: Failed to set filetime
1741363917 on outfile: CreateFile failed:
Warning: GetLastError 0x00000003
```
The special long filename logic is necessary to support Windows releases
prior to Windows 10 v1607. With the latter, it's possible to opt-in to
this behavior via a manifest setting. Note that Windows itself also needs
to opt-in to support this. Finally note that curl itself needs passing
`--globoff` to let long filenames through, pending #20044 and #20046.
Refs:
https://learn.microsoft.com/windows/win32/api/fileapi/nf-fileapi-createfilea
https://learn.microsoft.com/windows/win32/fileio/maximum-file-path-limitation
Ref: #8361
Inspired by: #19286
Inspired-by: Mathesh V
Closes #19286
Closes #20040
atoi
atol
calloc
+ CreateFile
+ CreateFileA
+ CreateFileW
fclose
fdopen
fopen
#include <share.h> /* for _SH_DENYNO */
+#include "multibyte.h"
+
#ifdef CURLDEBUG
/*
* Use system allocators to avoid infinite recursion when called by curl's
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;
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);
#include "schannel.h"
#include "schannel_int.h"
+#include "../curlx/fopen.h"
#include "../curlx/inet_pton.h"
#include "vtls.h"
#include "vtls_int.h"
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,
CloseHandle(ca_file_handle);
}
Curl_safefree(ca_file_buffer);
- curlx_free(ca_file_tstr);
return result;
}
"atoi" => 1,
"atol" => 1,
"calloc" => 1,
+ "CreateFile" => 1,
+ "CreateFileA" => 1,
+ "CreateFileW" => 1,
"fclose" => 1,
"fdopen" => 1,
"fopen" => 1,
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)) {
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. */
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;