Commit f3f163243a for openssl.org

commit f3f163243a4fd6f5caea7bdb5ecc655f8c600cbb
Author: Tomas Mraz <tomas@openssl.foundation>
Date:   Tue Jun 16 12:45:19 2026 +0200

    Revert "convert CRYPTO_THREAD_run_once to use InitOnceExecuteOnce api"

    This reverts commit d053fe41a4add4e55dc5633e8aef6602a6a4b90b.

    Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
    Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
    MergeDate: Wed Jun 17 12:14:58 2026
    (Merged from https://github.com/openssl/openssl/pull/31539)

diff --git a/crypto/threads_win.c b/crypto/threads_win.c
index d803b7221d..4fedf24e90 100644
--- a/crypto/threads_win.c
+++ b/crypto/threads_win.c
@@ -512,28 +512,32 @@ void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
     return;
 }

-struct init_once_cb_info {
-    void (*init)(void);
-};
-
-static BOOL CALLBACK init_wrapper(PINIT_ONCE InitOnce, PVOID param, PVOID *context)
-{
-    struct init_once_cb_info *info = (struct init_once_cb_info *)param;
-
-    info->init();
-    return TRUE;
-}
+#define ONCE_UNINITED 0
+#define ONCE_ININIT 1
+#define ONCE_DONE 2

+/*
+ * We don't use InitOnceExecuteOnce because that isn't available in WinXP which
+ * we still have to support.
+ */
 int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
 {
-    INIT_ONCE *myonce = (INIT_ONCE *)once;
-    struct init_once_cb_info info = { init };
-    BOOL bstatus;
+    LONG volatile *lock = (LONG *)once;
+    LONG result;

-    bstatus = InitOnceExecuteOnce(myonce, init_wrapper, (void *)&info, NULL);
-    if (bstatus == TRUE)
+    if (*lock == ONCE_DONE)
         return 1;
-    return 0;
+
+    do {
+        result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED);
+        if (result == ONCE_UNINITED) {
+            init();
+            *lock = ONCE_DONE;
+            return 1;
+        }
+    } while (result == ONCE_ININIT);
+
+    return (*lock == ONCE_DONE);
 }

 int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
diff --git a/include/internal/e_os.h b/include/internal/e_os.h
index f0de2f363c..3ea75209cf 100644
--- a/include/internal/e_os.h
+++ b/include/internal/e_os.h
@@ -109,7 +109,7 @@
  *	0x0603 // Windows 8.1
  *	0x0A00 // Windows 10
  */
-#define _WIN32_WINNT 0x0600
+#define _WIN32_WINNT 0x0501
 #endif
 #include <windows.h>
 #include <stdio.h>
diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in
index 071b11b3bc..a9ade25b15 100644
--- a/include/openssl/crypto.h.in
+++ b/include/openssl/crypto.h.in
@@ -543,8 +543,8 @@ void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings);
 typedef DWORD CRYPTO_THREAD_LOCAL;
 typedef DWORD CRYPTO_THREAD_ID;

-typedef INIT_ONCE CRYPTO_ONCE;
-#define CRYPTO_ONCE_STATIC_INIT INIT_ONCE_STATIC_INIT
+typedef LONG CRYPTO_ONCE;
+#define CRYPTO_ONCE_STATIC_INIT 0
 #endif
 #else
 #if defined(__TANDEM) && defined(_SPT_MODEL_)
diff --git a/include/openssl/e_os2.h b/include/openssl/e_os2.h
index 698f2da26b..bacc161bd6 100644
--- a/include/openssl/e_os2.h
+++ b/include/openssl/e_os2.h
@@ -58,7 +58,6 @@ extern "C" {
 #define OPENSSL_SYS_WIN32_CYGWIN
 #else
 #if defined(_WIN32) || defined(OPENSSL_SYS_WIN32)
-#include "windows.h"
 #undef OPENSSL_SYS_UNIX
 #if !defined(OPENSSL_SYS_WIN32)
 #define OPENSSL_SYS_WIN32
diff --git a/providers/implementations/rands/seeding/rand_win.c b/providers/implementations/rands/seeding/rand_win.c
index 5a0815042d..63b523b729 100644
--- a/providers/implementations/rands/seeding/rand_win.c
+++ b/providers/implementations/rands/seeding/rand_win.c
@@ -70,7 +70,7 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
     buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
     if (buffer != NULL) {
         size_t bytes = 0;
-        if (BCryptGenRandom(NULL, buffer, (ULONG)bytes_needed,
+        if (BCryptGenRandom(NULL, buffer, bytes_needed,
                 BCRYPT_USE_SYSTEM_PREFERRED_RNG)
             == STATUS_SUCCESS)
             bytes = bytes_needed;
diff --git a/ssl/rio/rio_notifier.c b/ssl/rio/rio_notifier.c
index 9d28614406..ab635aa7a0 100644
--- a/ssl/rio/rio_notifier.c
+++ b/ssl/rio/rio_notifier.c
@@ -31,21 +31,63 @@ static int set_cloexec(int fd)
 #if defined(OPENSSL_SYS_WINDOWS)

 static CRYPTO_ONCE ensure_wsa_startup_once = CRYPTO_ONCE_STATIC_INIT;
+static CRYPTO_RWLOCK *wsa_lock;
+static int wsa_started;
+static int wsa_ref;
+
+static void ossl_wsa_cleanup(void)
+{
+    if (wsa_started) {
+        wsa_started = 0;
+        WSACleanup();
+    }
+
+    CRYPTO_THREAD_lock_free(wsa_lock);
+    wsa_lock = NULL;
+}

 DEFINE_RUN_ONCE_STATIC(do_wsa_startup)
 {
     WORD versionreq = 0x0202; /* Version 2.2 */
     WSADATA wsadata;

-    if (WSAStartup(versionreq, &wsadata) != 0)
+    wsa_lock = CRYPTO_THREAD_lock_new();
+    if (wsa_lock == NULL)
         return 0;

+    if (WSAStartup(versionreq, &wsadata) != 0) {
+        CRYPTO_THREAD_lock_free(wsa_lock);
+        wsa_lock = NULL;
+        return 0;
+    }
+    wsa_started = 1;
+
     return 1;
 }

 static ossl_inline int ensure_wsa_startup(void)
 {
-    return RUN_ONCE(&ensure_wsa_startup_once, do_wsa_startup);
+    int rv, unused;
+
+    rv = RUN_ONCE(&ensure_wsa_startup_once, do_wsa_startup);
+    if (rv != 0)
+        CRYPTO_atomic_add(&wsa_ref, 1, &unused, wsa_lock);
+
+    return rv;
+}
+
+static void wsa_done(void)
+{
+    int ref;
+
+    if (wsa_lock != NULL) {
+        CRYPTO_atomic_add(&wsa_ref, -1, &ref, wsa_lock);
+        if (ref == 0) {
+            ossl_wsa_cleanup();
+            ensure_wsa_startup_once = CRYPTO_ONCE_STATIC_INIT;
+            wsa_lock = NULL;
+        }
+    }
 }

 #endif
@@ -146,6 +188,8 @@ int ossl_rio_notifier_init(RIO_NOTIFIER *nfy)
     if (!ensure_wsa_startup()) {
         ERR_raise_data(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR,
             "Cannot start Windows sockets");
+
+        wsa_done();
         return 0;
     }
 #endif
@@ -332,6 +376,9 @@ void ossl_rio_notifier_cleanup(RIO_NOTIFIER *nfy)
     BIO_closesocket(nfy->wfd);
     BIO_closesocket(nfy->rfd);
     nfy->rfd = nfy->wfd = -1;
+#if defined(OPENSSL_SYS_WINDOWS)
+    wsa_done();
+#endif
 }

 int ossl_rio_notifier_signal(RIO_NOTIFIER *nfy)
diff --git a/util/platform_symbols/windows-symbols.txt b/util/platform_symbols/windows-symbols.txt
index 7ae58a3f18..0f6cc11450 100644
--- a/util/platform_symbols/windows-symbols.txt
+++ b/util/platform_symbols/windows-symbols.txt
@@ -1,6 +1,5 @@
 AcquireSRWLockExclusive
 AcquireSRWLockShared
-BCryptGenRandom
 CertCloseStore
 CertFindCertificateInStore
 CertFreeCertificateContext