From: Viktor Szakats Date: Mon, 3 Jun 2024 21:06:56 +0000 (+0200) Subject: windows: fix UWP builds, add GHA job X-Git-Tag: curl-8_9_0~298 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=998b17ea7f0a4aecaa39c15d0e6f9ece110a41e1;p=thirdparty%2Fcurl.git windows: fix UWP builds, add GHA job Add new job to test building for UWP (aka `CURL_WINDOWS_APP`). Fix fallouts when building for UWP: - rand: do not use `BCryptGenRandom()`. - cmake: disable using win32 LDAP. - cmake: disable telnet. - version_win32: fix code before declaration. - schannel: disable `HAS_MANUAL_VERIFY_API`. - schannel: disable `SSLSUPP_PINNEDPUBKEY` and make `schannel_checksum()` a stub. Ref: e178fbd40a896f2098278ae61e1166c88e7b31d0 #1429 - schannel: make `cert_get_name_string()` a failing stub. - system_win32: make `Curl_win32_impersonating()` a failing stub. - system_win32: try to fix `Curl_win32_init()` (untested). - threads: fix to use `CreateThread()`. - src: disable searching `PATH` for the CA bundle. - src: disable bold text support and capability detection. - src: disable `getfiletime()`/`setfiletime()`. - tests: make `win32_load_system_library()` a failing stub. - tests/server/util: make it compile. - tests/server/sockfilt: make it compile. - tests/lib3026: fix to use `CreateThread()`. See individual commits for build error details. Some of these fixes may have better solutions, and some may not work as expected. The goal of this patch is to make curl build for UWP. Closes #13870 --- diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 708da4f592..1bca1bdbc8 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -156,7 +156,7 @@ jobs: cmake --build bld --config '${{ matrix.type }}' --target test-ci msys2: - name: 'msys2 (${{ matrix.build }}, ${{ matrix.sys }}, ${{ matrix.env }}, ${{ matrix.config }})' + name: 'msys2 (${{ matrix.build }}, ${{ matrix.sys }}, ${{ matrix.env }}, ${{ matrix.config }}, ${{ matrix.test }})' runs-on: windows-latest timeout-minutes: 45 strategy: @@ -170,6 +170,7 @@ jobs: - { build: 'cmake' , sys: 'mingw64', env: 'x86_64' , tflags: '~2301 ~2302' , config: '-DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=ON', type: 'Debug' } - { build: 'cmake' , sys: 'ucrt64' , env: 'ucrt-x86_64' , tflags: 'skiprun' , config: '-DENABLE_DEBUG=OFF -DBUILD_SHARED_LIBS=ON -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=ON -DENABLE_CURLDEBUG=ON', type: 'Release' } - { build: 'cmake' , sys: 'clang64', env: 'clang-x86_64', tflags: 'skiprun' , config: '-DENABLE_DEBUG=ON -DBUILD_SHARED_LIBS=OFF -DCURL_USE_OPENSSL=ON -DENABLE_UNICODE=OFF', type: 'Release' } + - { build: 'cmake' , sys: 'mingw64', env: 'x86_64' , tflags: 'skiprun' , config: '-DENABLE_DEBUG=OFF -DBUILD_SHARED_LIBS=ON -DCURL_USE_SCHANNEL=ON -DENABLE_UNICODE=ON -DBUILD_EXAMPLES=OFF', type: 'Release', test: 'uwp' } fail-fast: false steps: - run: git config --global core.autocrlf input @@ -254,7 +255,7 @@ jobs: pacman --noconfirm --ask 20 --noprogressbar --sync --needed 'mingw-w64-${{ matrix.env }}-winstorecompat-git' specs="$(realpath gcc-specs-uwp)" gcc -dumpspecs | sed -e 's/-lmingwex/-lwindowsapp -lmingwex -lwindowsapp -lwindowsappcompat/' -e 's/-lmsvcrt/-lmsvcr120_app/' > "${specs}" - cflags+=" -specs=${specs} -DWINSTORECOMPAT -DWINAPI_FAMILY=WINAPI_FAMILY_APP" + cflags+=" -specs=$(cygpath -w "${specs}") -DWINSTORECOMPAT -DWINAPI_FAMILY=WINAPI_FAMILY_APP" # CMake (as of v3.26.4) gets confused and applies the MSVC rc.exe command-line # template to windres. Reset it to the windres template manually: rcopts=' -O coff ' @@ -282,7 +283,9 @@ jobs: cmake --build bld --config '${{ matrix.type }}' --parallel 5 [[ '${{ matrix.config }}' != *'BUILD_SHARED_LIBS=OFF'* ]] && cp -f -p bld/lib/*.dll bld/src/ find . -name '*.exe' -o -name '*.dll' - bld/src/curl.exe --disable --version + if [ '${{ matrix.test }}' != 'uwp' ]; then # UWP missing 'msvcr120_app.dll', fails with exit code 0xc0000135 + bld/src/curl.exe --disable --version + fi - name: 'cmake build tests' if: ${{ matrix.build == 'cmake' && matrix.tflags != 'skipall' }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 730ad3c59c..ebbe2b1a1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -276,6 +276,10 @@ if(HTTP_ONLY) set(CURL_DISABLE_TFTP ON) endif() +if(WINDOWS_STORE) + set(CURL_DISABLE_TELNET ON) # telnet code needs fixing to compile for UWP. +endif() + option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON) mark_as_advanced(ENABLE_IPV6) if(ENABLE_IPV6 AND NOT WIN32) @@ -769,7 +773,7 @@ if(NOT CURL_DISABLE_SRP AND (HAVE_GNUTLS_SRP OR HAVE_OPENSSL_SRP)) endif() if(NOT CURL_DISABLE_LDAP) - if(WIN32) + if(WIN32 AND NOT WINDOWS_STORE) option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON) if(USE_WIN32_LDAP) list(APPEND CURL_LIBS "wldap32") diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index 796842077e..15fe806ae5 100644 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -459,7 +459,7 @@ query_complete(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlapped) * and wait on it. */ static -#if defined(_WIN32_WCE) +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) DWORD #else unsigned int @@ -527,7 +527,7 @@ CURL_STDCALL getaddrinfo_thread(void *arg) * gethostbyname_thread() resolves a name and then exits. */ static -#if defined(_WIN32_WCE) +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) DWORD #else unsigned int diff --git a/lib/curl_threads.c b/lib/curl_threads.c index 67962be31b..fb4af73d02 100644 --- a/lib/curl_threads.c +++ b/lib/curl_threads.c @@ -101,7 +101,7 @@ int Curl_thread_join(curl_thread_t *hnd) #elif defined(USE_THREADS_WIN32) curl_thread_t Curl_thread_create( -#if defined(_WIN32_WCE) +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) DWORD #else unsigned int @@ -109,14 +109,14 @@ curl_thread_t Curl_thread_create( (CURL_STDCALL *func) (void *), void *arg) { -#ifdef _WIN32_WCE +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) typedef HANDLE curl_win_thread_handle_t; #else typedef uintptr_t curl_win_thread_handle_t; #endif curl_thread_t t; curl_win_thread_handle_t thread_handle; -#ifdef _WIN32_WCE +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) thread_handle = CreateThread(NULL, 0, func, arg, 0, NULL); #else thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL); diff --git a/lib/curl_threads.h b/lib/curl_threads.h index cafff1741f..be22352dcb 100644 --- a/lib/curl_threads.h +++ b/lib/curl_threads.h @@ -53,7 +53,7 @@ #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) curl_thread_t Curl_thread_create( -#if defined(_WIN32_WCE) +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) DWORD #else unsigned int diff --git a/lib/rand.c b/lib/rand.c index 65e05e57ab..63c37d952b 100644 --- a/lib/rand.c +++ b/lib/rand.c @@ -48,7 +48,8 @@ #ifdef _WIN32 -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 && \ + !defined(CURL_WINDOWS_APP) # define HAVE_WIN_BCRYPTGENRANDOM # include # ifdef _MSC_VER diff --git a/lib/system_win32.c b/lib/system_win32.c index 354d8a1b57..9bf1a48dc6 100644 --- a/lib/system_win32.c +++ b/lib/system_win32.c @@ -112,7 +112,11 @@ CURLcode Curl_win32_init(long flags) } #ifdef USE_WINSOCK +#ifdef CURL_WINDOWS_APP + ws2_32Dll = Curl_load_library(TEXT("ws2_32.dll")); +#else ws2_32Dll = GetModuleHandleA("ws2_32"); +#endif if(ws2_32Dll) { Curl_FreeAddrInfoExW = CURLX_FUNCTION_CAST(FREEADDRINFOEXW_FN, GetProcAddress(ws2_32Dll, "FreeAddrInfoExW")); @@ -269,11 +273,13 @@ HMODULE Curl_load_library(LPCTSTR filename) bool Curl_win32_impersonating(void) { +#ifndef CURL_WINDOWS_APP HANDLE token = NULL; if(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token)) { CloseHandle(token); return TRUE; } +#endif return FALSE; } diff --git a/lib/version_win32.c b/lib/version_win32.c index da3de133dc..463ed69713 100644 --- a/lib/version_win32.c +++ b/lib/version_win32.c @@ -80,13 +80,13 @@ bool curlx_verify_windows_version(const unsigned int majorVersion, bool matched = FALSE; #if defined(CURL_WINDOWS_APP) - (void)buildVersion; - /* We have no way to determine the Windows version from Windows apps, so let's assume we're running on the target Windows version. */ const WORD fullVersion = MAKEWORD(minorVersion, majorVersion); const WORD targetVersion = (WORD)_WIN32_WINNT; + (void)buildVersion; + switch(condition) { case VERSION_LESS_THAN: matched = targetVersion < fullVersion; diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index e381f34e76..57d0c33d64 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -2682,6 +2682,13 @@ static void schannel_checksum(const unsigned char *input, DWORD provType, const unsigned int algId) { +#ifdef CURL_WINDOWS_APP + (void)input; + (void)inputlen; + (void)provType; + (void)algId; + memset(checksum, 0, checksumlen); +#else HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; DWORD cbHashSize = 0; @@ -2722,6 +2729,7 @@ static void schannel_checksum(const unsigned char *input, if(hProv) CryptReleaseContext(hProv, 0); +#endif } static CURLcode schannel_sha256sum(const unsigned char *input, @@ -2906,7 +2914,9 @@ const struct Curl_ssl Curl_ssl_schannel = { #ifdef HAS_MANUAL_VERIFY_API SSLSUPP_CAINFO_BLOB | #endif +#ifndef CURL_WINDOWS_APP SSLSUPP_PINNEDPUBKEY | +#endif SSLSUPP_TLS13_CIPHERSUITES | SSLSUPP_CA_CACHE | SSLSUPP_HTTPS_PROXY, diff --git a/lib/vtls/schannel_int.h b/lib/vtls/schannel_int.h index af29b67de0..5dffb641ab 100644 --- a/lib/vtls/schannel_int.h +++ b/lib/vtls/schannel_int.h @@ -28,7 +28,8 @@ #ifdef USE_SCHANNEL -#if defined(__MINGW32__) || defined(CERT_CHAIN_REVOCATION_CHECK_CHAIN) +#if (defined(__MINGW32__) || defined(CERT_CHAIN_REVOCATION_CHECK_CHAIN)) \ + && !defined(CURL_WINDOWS_APP) #define HAS_MANUAL_VERIFY_API #endif diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c index 179376d9b3..4933bbd0b7 100644 --- a/lib/vtls/schannel_verify.c +++ b/lib/vtls/schannel_verify.c @@ -346,6 +346,12 @@ static DWORD cert_get_name_string(struct Curl_easy *data, DWORD length) { DWORD actual_length = 0; +#if defined(CURL_WINDOWS_APP) + (void)data; + (void)cert_context; + (void)host_names; + (void)length; +#else BOOL compute_content = FALSE; CERT_INFO *cert_info = NULL; CERT_EXTENSION *extension = NULL; @@ -457,6 +463,7 @@ static DWORD cert_get_name_string(struct Curl_easy *data, /* Last string has double null-terminator. */ *current_pos = '\0'; } +#endif return actual_length; } diff --git a/src/terminal.c b/src/terminal.c index 08b1bdd2d6..7ba991d3e5 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -66,7 +66,7 @@ unsigned int get_terminal_columns(void) struct winsize ts; if(!ioctl(STDIN_FILENO, TIOCGWINSZ, &ts)) cols = (int)ts.ws_col; -#elif defined(_WIN32) +#elif defined(_WIN32) && !defined(CURL_WINDOWS_APP) { HANDLE stderr_hnd = GetStdHandle(STD_ERROR_HANDLE); CONSOLE_SCREEN_BUFFER_INFO console_info; diff --git a/src/tool_doswin.c b/src/tool_doswin.c index f36f8a6723..333b53feed 100644 --- a/src/tool_doswin.c +++ b/src/tool_doswin.c @@ -620,6 +620,11 @@ CURLcode FindWin32CACert(struct OperationConfig *config, { CURLcode result = CURLE_OK; +#ifdef CURL_WINDOWS_APP + (void)config; + (void)backend; + (void)bundle_file; +#else /* Search and set cert file only if libcurl supports SSL. * * If Schannel is the selected SSL backend then these locations are @@ -645,6 +650,7 @@ CURLcode FindWin32CACert(struct OperationConfig *config, result = CURLE_OUT_OF_MEMORY; } } +#endif return result; } @@ -703,6 +709,9 @@ cleanup: return slist; } +bool tool_term_has_bold; + +#ifndef CURL_WINDOWS_APP /* The terminal settings to restore on exit */ static struct TerminalSettings { HANDLE hStdOut; @@ -714,8 +723,6 @@ static struct TerminalSettings { #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endif -bool tool_term_has_bold; - static void restore_terminal(void) { if(InterlockedExchange(&TerminalSettings.valid, (LONG)FALSE)) @@ -770,6 +777,7 @@ static void init_terminal(void) } } } +#endif LARGE_INTEGER tool_freq; bool tool_isVistaOrGreater; @@ -786,7 +794,9 @@ CURLcode win32_init(void) QueryPerformanceFrequency(&tool_freq); +#ifndef CURL_WINDOWS_APP init_terminal(); +#endif return CURLE_OK; } diff --git a/src/tool_filetime.c b/src/tool_filetime.c index 13113886e6..b0e4cc1b5e 100644 --- a/src/tool_filetime.c +++ b/src/tool_filetime.c @@ -41,7 +41,7 @@ int getfiletime(const char *filename, struct GlobalConfig *global, /* Windows stat() may attempt to adjust the unix GMT file time by a daylight saving time offset and since it's GMT that is bad behavior. When we have access to a 64-bit type we can bypass stat and get the times directly. */ -#if defined(_WIN32) +#if defined(_WIN32) && !defined(CURL_WINDOWS_APP) HANDLE hfile; TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar((char *)filename); @@ -95,7 +95,7 @@ void setfiletime(curl_off_t filetime, const char *filename, /* Windows utime() may attempt to adjust the unix GMT file time by a daylight saving time offset and since it's GMT that is bad behavior. When we have access to a 64-bit type we can bypass utime and set the times directly. */ -#if defined(_WIN32) +#if defined(_WIN32) && !defined(CURL_WINDOWS_APP) HANDLE hfile; TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar((char *)filename); diff --git a/tests/libtest/lib3026.c b/tests/libtest/lib3026.c index 7e914010e2..74e1c32b81 100644 --- a/tests/libtest/lib3026.c +++ b/tests/libtest/lib3026.c @@ -29,7 +29,7 @@ #define NUM_THREADS 100 #ifdef _WIN32 -#ifdef _WIN32_WCE +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) static DWORD WINAPI run_thread(LPVOID ptr) #else #include @@ -47,7 +47,7 @@ static unsigned int WINAPI run_thread(void *ptr) CURLcode test(char *URL) { -#ifdef _WIN32_WCE +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) typedef HANDLE curl_win_thread_handle_t; #else typedef uintptr_t curl_win_thread_handle_t; @@ -78,7 +78,7 @@ CURLcode test(char *URL) for(i = 0; i < tid_count; i++) { curl_win_thread_handle_t th; results[i] = CURL_LAST; /* initialize with invalid value */ -#ifdef _WIN32_WCE +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) th = CreateThread(NULL, 0, run_thread, &results[i], 0, NULL); #else th = _beginthreadex(NULL, 0, run_thread, &results[i], 0, NULL); diff --git a/tests/libtest/testutil.c b/tests/libtest/testutil.c index efbbf9019c..2d334e979b 100644 --- a/tests/libtest/testutil.c +++ b/tests/libtest/testutil.c @@ -133,6 +133,10 @@ double tutil_tvdiff_secs(struct timeval newer, struct timeval older) #ifdef _WIN32 HMODULE win32_load_system_library(const TCHAR *filename) { +#ifdef CURL_WINDOWS_APP + (void)filename; + return NULL; +#else size_t filenamelen = _tcslen(filename); size_t systemdirlen = GetSystemDirectory(NULL, 0); size_t written; @@ -158,5 +162,6 @@ HMODULE win32_load_system_library(const TCHAR *filename) _tcscpy(path + written, filename); return LoadLibrary(path); +#endif } #endif diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c index eb9d8e8697..4e5cb7e4b2 100644 --- a/tests/server/sockfilt.c +++ b/tests/server/sockfilt.c @@ -152,7 +152,7 @@ enum sockmode { ACTIVE_DISCONNECT /* as a client, disconnected from server */ }; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(CURL_WINDOWS_APP) /* * read-wrapper to support reading from stdin on Windows. */ @@ -420,7 +420,7 @@ static bool read_data_block(unsigned char *buffer, ssize_t maxlen, } -#ifdef USE_WINSOCK +#if defined(USE_WINSOCK) && !defined(CURL_WINDOWS_APP) /* * WinSock select() does not support standard file descriptors, * it can only check SOCKETs. The following function is an attempt diff --git a/tests/server/util.c b/tests/server/util.c index 667c680db3..eed305d156 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -493,7 +493,7 @@ static SIGHANDLER_T old_sigterm_handler = SIG_ERR; static SIGHANDLER_T old_sigbreak_handler = SIG_ERR; #endif -#ifdef _WIN32 +#if defined(_WIN32) && !defined(CURL_WINDOWS_APP) #ifdef _WIN32_WCE static DWORD thread_main_id = 0; #else @@ -574,6 +574,9 @@ static BOOL WINAPI ctrl_event_handler(DWORD dwCtrlType) } return TRUE; } +#endif + +#if defined(_WIN32) && !defined(CURL_WINDOWS_APP) /* Window message handler for Windows applications to add support * for graceful process termination via taskkill (without /f) which * sends WM_CLOSE to all Windows of a process (even hidden ones). @@ -687,12 +690,6 @@ static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler, void install_signal_handlers(bool keep_sigalrm) { #ifdef _WIN32 -#ifdef _WIN32_WCE - typedef HANDLE curl_win_thread_handle_t; -#else - typedef uintptr_t curl_win_thread_handle_t; -#endif - curl_win_thread_handle_t thread; /* setup windows exit event before any signal can trigger */ exit_event = CreateEvent(NULL, TRUE, FALSE, NULL); if(!exit_event) @@ -741,16 +738,27 @@ void install_signal_handlers(bool keep_sigalrm) #ifdef _WIN32 if(!SetConsoleCtrlHandler(ctrl_event_handler, TRUE)) logmsg("cannot install CTRL event handler"); + +#ifndef CURL_WINDOWS_APP + { #ifdef _WIN32_WCE - thread = CreateThread(NULL, 0, &main_window_loop, - (LPVOID)GetModuleHandle(NULL), 0, &thread_main_id); + typedef HANDLE curl_win_thread_handle_t; #else - thread = _beginthreadex(NULL, 0, &main_window_loop, - (void *)GetModuleHandle(NULL), 0, &thread_main_id); + typedef uintptr_t curl_win_thread_handle_t; +#endif + curl_win_thread_handle_t thread; +#ifdef _WIN32_WCE + thread = CreateThread(NULL, 0, &main_window_loop, + (LPVOID)GetModuleHandle(NULL), 0, &thread_main_id); +#else + thread = _beginthreadex(NULL, 0, &main_window_loop, + (void *)GetModuleHandle(NULL), 0, &thread_main_id); +#endif + thread_main_window = (HANDLE)thread; + if(!thread_main_window || !thread_main_id) + logmsg("cannot start main window loop"); + } #endif - thread_main_window = (HANDLE)thread; - if(!thread_main_window || !thread_main_id) - logmsg("cannot start main window loop"); #endif } @@ -786,6 +794,7 @@ void restore_signal_handlers(bool keep_sigalrm) #endif #ifdef _WIN32 (void)SetConsoleCtrlHandler(ctrl_event_handler, FALSE); +#ifndef CURL_WINDOWS_APP if(thread_main_window && thread_main_id) { if(PostThreadMessage(thread_main_id, WM_APP, 0, 0)) { if(WaitForSingleObjectEx(thread_main_window, INFINITE, TRUE)) { @@ -802,6 +811,7 @@ void restore_signal_handlers(bool keep_sigalrm) } } #endif +#endif } #ifdef USE_UNIX_SOCKETS