Jacek Caban : wininet: Initialize winsock before creating socket in Windows builds.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Feb 12 10:13:40 CST 2015


Module: wine
Branch: master
Commit: de5c1fb8e9d7712c316581fdb5635f76bef8b42e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=de5c1fb8e9d7712c316581fdb5635f76bef8b42e

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Feb 12 12:05:23 2015 +0100

wininet: Initialize winsock before creating socket in Windows builds.

---

 dlls/wininet/ftp.c           |  2 ++
 dlls/wininet/internet.c      |  1 +
 dlls/wininet/internet.h      |  2 ++
 dlls/wininet/netconnection.c | 47 +++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c
index a28865f..7f349d3 100644
--- a/dlls/wininet/ftp.c
+++ b/dlls/wininet/ftp.c
@@ -2573,6 +2573,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
     SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED,
                       szaddr, strlen(szaddr)+1);
 
+    init_winsock();
     nsocket = socket(AF_INET,SOCK_STREAM,0);
     if (nsocket == -1)
     {
@@ -2932,6 +2933,7 @@ static BOOL FTP_InitListenSocket(ftp_session_t *lpwfs)
 
     TRACE("\n");
 
+    init_winsock();
     lpwfs->lstnSocket = socket(PF_INET, SOCK_STREAM, 0);
     if (lpwfs->lstnSocket == -1)
     {
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index 4847ca0..aa9c259 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -3477,6 +3477,7 @@ BOOL WINAPI InternetCheckConnectionW( LPCWSTR lpszUrl, DWORD dwFlags, DWORD dwRe
 
       if (!GetAddress(hostW, port, (struct sockaddr *)&saddr, &sa_len))
           goto End;
+      init_winsock();
       fd = socket(saddr.ss_family, SOCK_STREAM, 0);
       if (fd != -1)
       {
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index b0a0db5..23f4a41 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -478,6 +478,8 @@ BOOL init_urlcache(void) DECLSPEC_HIDDEN;
 void free_urlcache(void) DECLSPEC_HIDDEN;
 void free_cookie(void) DECLSPEC_HIDDEN;
 
+void init_winsock(void) DECLSPEC_HIDDEN;
+
 #define MAX_REPLY_LEN	 	0x5B4
 
 /* Used for debugging - maybe need to be shared in the Wine debugging code ? */
diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index 872daec..a7cbf6a 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -27,6 +27,10 @@
 #define NONAMELESSUNION
 
 #if defined(__MINGW32__) || defined (_MSC_VER)
+#define USE_WINSOCK
+#endif
+
+#ifdef USE_WINSOCK
 #include <ws2tcpip.h>
 #endif
 
@@ -62,7 +66,7 @@
 #ifdef HAVE_NETINET_TCP_H
 # include <netinet/tcp.h>
 #endif
-#if !defined(__MINGW32__) && !defined(_MSC_VER)
+#ifndef USE_WINSOCK
 #include <errno.h>
 #endif
 
@@ -317,10 +321,38 @@ static BOOL ensure_cred_handle(void)
     return TRUE;
 }
 
+#ifdef USE_WINSOCK
+static BOOL winsock_loaded = FALSE;
+
+static BOOL WINAPI winsock_startup(INIT_ONCE *once, void *param, void **context)
+{
+    WSADATA wsa_data;
+    DWORD res;
+
+    res = WSAStartup(MAKEWORD(1,1), &wsa_data);
+    if(res == ERROR_SUCCESS)
+        winsock_loaded = TRUE;
+    else
+        ERR("WSAStartup failed: %u\n", res);
+    return TRUE;
+}
+#endif
+
+void init_winsock(void)
+{
+#ifdef USE_WINSOCK
+    static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
+    InitOnceExecuteOnce(&init_once, winsock_startup, NULL, NULL);
+#endif
+}
+
 static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD timeout)
 {
     int result;
     ULONG flag;
+    DWORD res;
+
+    init_winsock();
 
     assert(server->addr_len);
     result = netconn->socket = socket(server->addr.ss_family, SOCK_STREAM, 0);
@@ -330,7 +362,8 @@ static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD t
         result = connect(netconn->socket, (struct sockaddr*)&server->addr, server->addr_len);
         if(result == -1)
         {
-            if (sock_get_error() == WSAEINPROGRESS || sock_get_error() == WSAEWOULDBLOCK) {
+            res = sock_get_error();
+            if (res == WSAEINPROGRESS || res == WSAEWOULDBLOCK) {
                 struct pollfd pfd;
                 int res;
 
@@ -441,12 +474,16 @@ void NETCON_unload(void)
     if(have_compat_cred_handle)
         FreeCredentialsHandle(&compat_cred_handle);
     DeleteCriticalSection(&init_sechandle_cs);
+
+#ifdef USE_WINSOCK
+    WSACleanup();
+#endif
 }
 
 /* translate a unix error code into a winsock one */
 int sock_get_error(void)
 {
-#if defined(__MINGW32__) || defined(_MSC_VER)
+#ifdef USE_WINSOCK
     return WSAGetLastError();
 #else
     switch (errno)
@@ -538,7 +575,7 @@ int sock_recv(int fd, void *msg, size_t len, int flags)
 
 static void set_socket_blocking(int socket, blocking_mode_t mode)
 {
-#if defined(__MINGW32__) || defined (_MSC_VER)
+#ifdef USE_WINSOCK
     ULONG arg = mode == BLOCKING_DISALLOW;
     ioctlsocket(socket, FIONBIO, &arg);
 #endif
@@ -1041,7 +1078,7 @@ BOOL NETCON_is_alive(netconn_t *netconn)
 
     len = sock_recv(netconn->socket, &b, 1, MSG_PEEK|MSG_DONTWAIT);
     return len == 1 || (len == -1 && sock_get_error() == WSAEWOULDBLOCK);
-#elif defined(__MINGW32__) || defined(_MSC_VER)
+#elif defined(USE_WINSOCK)
     ULONG mode;
     int len;
     char b;




More information about the wine-cvs mailing list