]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curlx: add curlx_winapi_ functions
authorDaniel Stenberg <daniel@haxx.se>
Fri, 9 May 2025 08:21:53 +0000 (10:21 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 9 May 2025 08:45:36 +0000 (10:45 +0200)
Split them out from lib/strerror. Used by test code.

Closes #17299

lib/Makefile.inc
lib/curlx/curlx.h
lib/curlx/winapi.c [new file with mode: 0644]
lib/curlx/winapi.h [new file with mode: 0644]
lib/strerror.c
lib/strerror.h
lib/vtls/schannel_verify.c
tests/server/Makefile.inc
tests/server/util.c

index 921caf9ccc145111a0fef87108531f710506d24b..08147ebb42bfc5d6956d3f818ff49f45d96e0775 100644 (file)
@@ -31,7 +31,8 @@ LIB_CURLX_CFILES = \
   curlx/timediff.c \
   curlx/timeval.c  \
   curlx/version_win32.c \
-  curlx/warnless.c
+  curlx/warnless.c \
+  curlx/winapi.c
 
 LIB_CURLX_HFILES = \
   curlx/base64.h   \
@@ -43,7 +44,8 @@ LIB_CURLX_HFILES = \
   curlx/timediff.h \
   curlx/timeval.h  \
   curlx/version_win32.h \
-  curlx/warnless.h
+  curlx/warnless.h \
+  curlx/winapi.h
 
 LIB_VAUTH_CFILES =      \
   vauth/cleartext.c     \
index 1472f5d083a77003a29d4353a6715963fb6bfe7e..e8249d7f61199fbef9942e97110d7c3b20e58f65 100644 (file)
@@ -65,4 +65,7 @@
 #include "timeval.h"
 #include "timediff.h"
 
+#include "winapi.h"
+/* for curlx_winapi_strerror */
+
 #endif /* HEADER_CURL_CURLX_H */
diff --git a/lib/curlx/winapi.c b/lib/curlx/winapi.c
new file mode 100644 (file)
index 0000000..e79024c
--- /dev/null
@@ -0,0 +1,135 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "../curl_setup.h"
+
+/*
+ * curlx_winapi_strerror:
+ * Variant of Curl_strerror if the error code is definitely Windows API.
+ */
+#ifdef _WIN32
+#include "winapi.h"
+
+#ifdef BUILDING_LIBCURL
+#include <curl/mprintf.h>
+#define SNPRINTF curl_msnprintf
+#else
+/* when built for the test servers */
+
+/* adjust for old MSVC */
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+# define SNPRINTF _snprintf
+#else
+#define SNPRINTF snprintf
+#endif
+
+#endif /* !BUILDING_LIBCURL */
+
+#ifdef _WIN32
+/* This is a helper function for Curl_strerror that converts Windows API error
+ * codes (GetLastError) to error messages.
+ * Returns NULL if no error message was found for error code.
+ */
+const char *curlx_get_winapi_error(int err, char *buf, size_t buflen)
+{
+  char *p;
+  wchar_t wbuf[256];
+
+  if(!buflen)
+    return NULL;
+
+  *buf = '\0';
+  *wbuf = L'\0';
+
+  /* We return the local codepage version of the error string because if it is
+     output to the user's terminal it will likely be with functions which
+     expect the local codepage (eg fprintf, failf, infof).
+     FormatMessageW -> wcstombs is used for Windows CE compatibility. */
+  if(FormatMessageW((FORMAT_MESSAGE_FROM_SYSTEM |
+                     FORMAT_MESSAGE_IGNORE_INSERTS), NULL, (DWORD)err,
+                    LANG_NEUTRAL, wbuf, CURL_ARRAYSIZE(wbuf), NULL)) {
+    size_t written = wcstombs(buf, wbuf, buflen - 1);
+    if(written != (size_t)-1)
+      buf[written] = '\0';
+    else
+      *buf = '\0';
+  }
+
+  /* Truncate multiple lines */
+  p = strchr(buf, '\n');
+  if(p) {
+    if(p > buf && *(p-1) == '\r')
+      *(p-1) = '\0';
+    else
+      *p = '\0';
+  }
+
+  return *buf ? buf : NULL;
+}
+#endif /* _WIN32 */
+
+const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen)
+{
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  DWORD old_win_err = GetLastError();
+#endif
+  int old_errno = errno;
+
+  if(!buflen)
+    return NULL;
+
+  *buf = '\0';
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  if(!curlx_get_winapi_error((int)err, buf, buflen)) {
+#if defined(__GNUC__) && __GNUC__ >= 7
+#pragma GCC diagnostic push
+#pragma GCC diagnostic warning "-Wformat-truncation=1"
+#endif
+    /* some GCC compilers cause false positive warnings if we allow this
+       warning */
+    SNPRINTF(buf, buflen, "Unknown error %lu (0x%08lX)", err, err);
+#if defined(__GNUC__) && __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
+
+  }
+#else
+  {
+    const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
+    if(strlen(txt) < buflen)
+      strcpy(buf, txt);
+  }
+#endif
+
+  if(errno != old_errno)
+    CURL_SETERRNO(old_errno);
+
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  if(old_win_err != GetLastError())
+    SetLastError(old_win_err);
+#endif
+
+  return buf;
+}
+#endif /* _WIN32 */
diff --git a/lib/curlx/winapi.h b/lib/curlx/winapi.h
new file mode 100644 (file)
index 0000000..76ddcc5
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURLX_WINAPI_H
+#define HEADER_CURLX_WINAPI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+
+#ifdef _WIN32
+#define WINAPI_ERROR_LEN 100
+const char *curlx_get_winapi_error(int err, char *buf, size_t buflen);
+const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen);
+#endif
+
+#endif /* HEADER_CURLX_WINAPI_H */
index 922bb9c5c983761f30156b8b3f4fef013db29034..0c440136d086683887e10431f5a8d304879b253c 100644 (file)
@@ -42,6 +42,7 @@
 #include "curl_sspi.h"
 #endif
 
+#include "curlx/winapi.h"
 #include "strerror.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -782,50 +783,6 @@ get_winsock_error(int err, char *buf, size_t len)
 }
 #endif   /* USE_WINSOCK */
 
-#ifdef _WIN32
-/* This is a helper function for Curl_strerror that converts Windows API error
- * codes (GetLastError) to error messages.
- * Returns NULL if no error message was found for error code.
- */
-static const char *
-get_winapi_error(int err, char *buf, size_t buflen)
-{
-  char *p;
-  wchar_t wbuf[256];
-
-  if(!buflen)
-    return NULL;
-
-  *buf = '\0';
-  *wbuf = L'\0';
-
-  /* We return the local codepage version of the error string because if it is
-     output to the user's terminal it will likely be with functions which
-     expect the local codepage (eg fprintf, failf, infof).
-     FormatMessageW -> wcstombs is used for Windows CE compatibility. */
-  if(FormatMessageW((FORMAT_MESSAGE_FROM_SYSTEM |
-                     FORMAT_MESSAGE_IGNORE_INSERTS), NULL, (DWORD)err,
-                    LANG_NEUTRAL, wbuf, CURL_ARRAYSIZE(wbuf), NULL)) {
-    size_t written = wcstombs(buf, wbuf, buflen - 1);
-    if(written != (size_t)-1)
-      buf[written] = '\0';
-    else
-      *buf = '\0';
-  }
-
-  /* Truncate multiple lines */
-  p = strchr(buf, '\n');
-  if(p) {
-    if(p > buf && *(p-1) == '\r')
-      *(p-1) = '\0';
-    else
-      *p = '\0';
-  }
-
-  return *buf ? buf : NULL;
-}
-#endif /* _WIN32 */
-
 /*
  * Our thread-safe and smart strerror() replacement.
  *
@@ -872,9 +829,9 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
   {
     if(
 #ifdef USE_WINSOCK
-       !get_winsock_error(err, buf, buflen) &&
+      !get_winsock_error(err, buf, buflen) &&
 #endif
-       !get_winapi_error(err, buf, buflen))
+      !curlx_get_winapi_error(err, buf, buflen))
       curl_msnprintf(buf, buflen, "Unknown error %d (%#x)", err, err);
   }
 #else /* not Windows coming up */
@@ -935,47 +892,6 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
   return buf;
 }
 
-/*
- * curlx_winapi_strerror:
- * Variant of Curl_strerror if the error code is definitely Windows API.
- */
-#ifdef _WIN32
-const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen)
-{
-#ifdef PRESERVE_WINDOWS_ERROR_CODE
-  DWORD old_win_err = GetLastError();
-#endif
-  int old_errno = errno;
-
-  if(!buflen)
-    return NULL;
-
-  *buf = '\0';
-
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
-  if(!get_winapi_error((int)err, buf, buflen)) {
-    curl_msnprintf(buf, buflen, "Unknown error %lu (0x%08lX)", err, err);
-  }
-#else
-  {
-    const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
-    if(strlen(txt) < buflen)
-      strcpy(buf, txt);
-  }
-#endif
-
-  if(errno != old_errno)
-    CURL_SETERRNO(old_errno);
-
-#ifdef PRESERVE_WINDOWS_ERROR_CODE
-  if(old_win_err != GetLastError())
-    SetLastError(old_win_err);
-#endif
-
-  return buf;
-}
-#endif /* _WIN32 */
-
 #ifdef USE_WINDOWS_SSPI
 /*
  * Curl_sspi_strerror:
@@ -1098,7 +1014,7 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
   }
   else {
     char msgbuf[256];
-    if(get_winapi_error(err, msgbuf, sizeof(msgbuf)))
+    if(curlx_get_winapi_error(err, msgbuf, sizeof(msgbuf)))
       curl_msnprintf(buf, buflen, "%s (0x%08X) - %s", txt, err, msgbuf);
     else
       curl_msnprintf(buf, buflen, "%s (0x%08X)", txt, err);
index 3dd382b96a13a1a80f7154ab2a36e4c8aee05c5d..424fb5b7b5e1f205253a59726f6779e3196c5c91 100644 (file)
@@ -29,9 +29,6 @@
 #define STRERROR_LEN 256 /* a suitable length */
 
 const char *Curl_strerror(int err, char *buf, size_t buflen);
-#ifdef _WIN32
-const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen);
-#endif
 #ifdef USE_WINDOWS_SSPI
 const char *Curl_sspi_strerror(int err, char *buf, size_t buflen);
 #endif
index 01d5fb5fea9fd6db04c165d55e78e6aef9bd2694..4834fc450faa1742034096c4a8194fa17e40101e 100644 (file)
@@ -44,6 +44,7 @@
 #include "vtls_int.h"
 #include "../sendf.h"
 #include "../strerror.h"
+#include "../curlx/winapi.h"
 #include "../curlx/multibyte.h"
 #include "../curl_printf.h"
 #include "hostcheck.h"
@@ -174,7 +175,7 @@ static CURLcode add_certs_data_to_store(HCERTSTORE trust_store,
                              NULL,
                              NULL,
                              (const void **)&cert_context)) {
-          char buffer[STRERROR_LEN];
+          char buffer[WINAPI_ERROR_LEN];
           failf(data,
                 "schannel: failed to extract certificate from CA file "
                 "'%s': %s",
@@ -203,7 +204,7 @@ static CURLcode add_certs_data_to_store(HCERTSTORE trust_store,
                                                NULL);
             CertFreeCertificateContext(cert_context);
             if(!add_cert_result) {
-              char buffer[STRERROR_LEN];
+              char buffer[WINAPI_ERROR_LEN];
               failf(data,
                     "schannel: failed to add certificate from CA file '%s' "
                     "to certificate store: %s",
@@ -251,7 +252,7 @@ static CURLcode add_certs_file_to_store(HCERTSTORE trust_store,
 
   ca_file_tstr = curlx_convert_UTF8_to_tchar(ca_file);
   if(!ca_file_tstr) {
-    char buffer[STRERROR_LEN];
+    char buffer[WINAPI_ERROR_LEN];
     failf(data,
           "schannel: invalid path name for CA file '%s': %s",
           ca_file,
@@ -273,7 +274,7 @@ static CURLcode add_certs_file_to_store(HCERTSTORE trust_store,
                               FILE_ATTRIBUTE_NORMAL,
                               NULL);
   if(ca_file_handle == INVALID_HANDLE_VALUE) {
-    char buffer[STRERROR_LEN];
+    char buffer[WINAPI_ERROR_LEN];
     failf(data,
           "schannel: failed to open CA file '%s': %s",
           ca_file,
@@ -283,7 +284,7 @@ static CURLcode add_certs_file_to_store(HCERTSTORE trust_store,
   }
 
   if(!GetFileSizeEx(ca_file_handle, &file_size)) {
-    char buffer[STRERROR_LEN];
+    char buffer[WINAPI_ERROR_LEN];
     failf(data,
           "schannel: failed to determine size of CA file '%s': %s",
           ca_file,
@@ -313,7 +314,7 @@ static CURLcode add_certs_file_to_store(HCERTSTORE trust_store,
 
     if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read,
                  bytes_to_read, &bytes_read, NULL)) {
-      char buffer[STRERROR_LEN];
+      char buffer[WINAPI_ERROR_LEN];
       failf(data,
             "schannel: failed to read from CA file '%s': %s",
             ca_file,
@@ -614,7 +615,7 @@ CURLcode Curl_verify_host(struct Curl_cfilter *cf,
                                      &pCertContextServer);
 
   if((sspi_status != SEC_E_OK) || !pCertContextServer) {
-    char buffer[STRERROR_LEN];
+    char buffer[WINAPI_ERROR_LEN];
     failf(data, "schannel: Failed to read remote certificate context: %s",
           Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
     goto cleanup;
@@ -770,7 +771,7 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
                                         &pCertContextServer);
 
   if((sspi_status != SEC_E_OK) || !pCertContextServer) {
-    char buffer[STRERROR_LEN];
+    char buffer[WINAPI_ERROR_LEN];
     failf(data, "schannel: Failed to read remote certificate context: %s",
           Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
     result = CURLE_PEER_FAILED_VERIFICATION;
@@ -806,7 +807,7 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
                                     CERT_STORE_CREATE_NEW_FLAG,
                                     NULL);
         if(!trust_store) {
-          char buffer[STRERROR_LEN];
+          char buffer[WINAPI_ERROR_LEN];
           failf(data, "schannel: failed to create certificate store: %s",
                 curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
           result = CURLE_SSL_CACERT_BADFILE;
@@ -853,7 +854,7 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
         CertCreateCertificateChainEngine(
           (CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine);
       if(!create_engine_result) {
-        char buffer[STRERROR_LEN];
+        char buffer[WINAPI_ERROR_LEN];
         failf(data,
               "schannel: failed to create certificate chain engine: %s",
               curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
@@ -878,7 +879,7 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
                                  CERT_CHAIN_REVOCATION_CHECK_CHAIN),
                                 NULL,
                                 &pChainContext)) {
-      char buffer[STRERROR_LEN];
+      char buffer[WINAPI_ERROR_LEN];
       failf(data, "schannel: CertGetCertificateChain failed: %s",
             curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
       pChainContext = NULL;
index e5c6345baae19f5a868cf7d68a8378ceab213a9a..a4e26a529e162890dc9914e156595b05da0c4d3f 100644 (file)
@@ -62,8 +62,8 @@ UTIL = \
   server_setup.h \
   ../../lib/curlx/base64.c \
   ../../lib/curlx/base64.h \
-  ../../lib/strerror.c \
-  ../../lib/strerror.h
+  ../../lib/curlx/winapi.c \
+  ../../lib/curlx/winapi.h
 
 FIRSTFILES = \
   first.c \
index f884cf8f6c2863f76418f32638d027597ae2a56e..d274baf1614560f4ee21a3f30321989e3e1343ce 100644 (file)
 #include <dos.h>  /* delay() */
 #endif
 
-#ifdef _WIN32
-#include "strerror.h"
-#endif
-
 #include <curlx.h> /* from the private lib dir */
 #include "util.h"