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