diff --git a/dlls/ws2_32/Makefile.in b/dlls/ws2_32/Makefile.in index 78c1633c921..8fe6eda420c 100644 --- a/dlls/ws2_32/Makefile.in +++ b/dlls/ws2_32/Makefile.in @@ -1,7 +1,7 @@ MODULE = ws2_32.dll IMPORTLIB = ws2_32 DELAYIMPORTS = advapi32 iphlpapi user32 -EXTRALIBS = $(POLL_LIBS) +EXTRALIBS = $(POLL_LIBS) -Wl,--subsystem,unixlib EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/ws2_32/protocol.c b/dlls/ws2_32/protocol.c index e7fd3595fc6..733ef102eea 100644 --- a/dlls/ws2_32/protocol.c +++ b/dlls/ws2_32/protocol.c @@ -27,6 +27,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(winsock); WINE_DECLARE_DEBUG_CHANNEL(winediag); +unixlib_handle_t ws_unix_handle = 0; + +#define WS_CALL(func, params) __wine_unix_call( ws_unix_handle, ws_unix_ ## func, params ) + static char *get_fqdn(void) { char *ret; @@ -47,28 +51,22 @@ static char *get_fqdn(void) static int do_getaddrinfo( const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **info ) { - struct addrinfo *buffer, *new_buffer; unsigned int size = 1024; + struct getaddrinfo_params params = { node, service, hints, NULL, &size }; int ret; - if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size ))) - return WSA_NOT_ENOUGH_MEMORY; - - while ((ret = unix_funcs->getaddrinfo( node, service, hints, buffer, &size )) == ERROR_INSUFFICIENT_BUFFER) + for (;;) { - if (!(new_buffer = HeapReAlloc( GetProcessHeap(), 0, buffer, size ))) - { - HeapFree( GetProcessHeap(), 0, buffer ); + if (!(params.info = HeapAlloc( GetProcessHeap(), 0, size ))) return WSA_NOT_ENOUGH_MEMORY; + if (!(ret = WS_CALL( getaddrinfo, ¶ms ))) + { + *info = params.info; + return ret; } - buffer = new_buffer; + HeapFree( GetProcessHeap(), 0, params.info ); + if (ret != ERROR_INSUFFICIENT_BUFFER) return ret; } - - if (!ret) - *info = buffer; - else - HeapFree( GetProcessHeap(), 0, buffer ); - return ret; } @@ -551,10 +549,12 @@ void WINAPI FreeAddrInfoExW( ADDRINFOEXW *ai ) int WINAPI getnameinfo( const SOCKADDR *addr, socklen_t addr_len, char *host, DWORD host_len, char *serv, DWORD serv_len, int flags ) { + struct getnameinfo_params params = { addr, addr_len, host, host_len, serv, serv_len, flags }; + TRACE( "addr %s, addr_len %d, host %p, host_len %u, serv %p, serv_len %d, flags %#x\n", debugstr_sockaddr(addr), addr_len, host, host_len, serv, serv_len, flags ); - return unix_funcs->getnameinfo( addr, addr_len, host, host_len, serv, serv_len, flags ); + return WS_CALL( getnameinfo, ¶ms ); } @@ -662,20 +662,20 @@ static struct hostent *create_hostent( char *name, int alias_count, int aliases_ struct hostent * WINAPI gethostbyaddr( const char *addr, int len, int family ) { unsigned int size = 1024; - struct hostent *host; + struct gethostbyaddr_params params = { addr, len, family, NULL, &size }; int ret; - if (!(host = get_hostent_buffer( size ))) - return NULL; - - while ((ret = unix_funcs->gethostbyaddr( addr, len, family, host, &size )) == ERROR_INSUFFICIENT_BUFFER) + for (;;) { - if (!(host = get_hostent_buffer( size ))) + if (!(params.host = get_hostent_buffer( size ))) return NULL; + + if ((ret = WS_CALL( gethostbyaddr, ¶ms )) != ERROR_INSUFFICIENT_BUFFER) + break; } SetLastError( ret ); - return ret ? NULL : host; + return ret ? NULL : params.host; } @@ -822,6 +822,7 @@ struct hostent * WINAPI gethostbyname( const char *name ) { struct hostent *host = NULL; char hostname[100]; + struct gethostname_params params = { hostname, sizeof(hostname) }; int ret; TRACE( "%s\n", debugstr_a(name) ); @@ -832,7 +833,7 @@ struct hostent * WINAPI gethostbyname( const char *name ) return NULL; } - if ((ret = unix_funcs->gethostname( hostname, 100 ))) + if ((ret = WS_CALL( gethostname, ¶ms ))) { SetLastError( ret ); return NULL; @@ -851,19 +852,20 @@ struct hostent * WINAPI gethostbyname( const char *name ) if (!host) { unsigned int size = 1024; + struct gethostbyname_params params = { name, NULL, &size }; int ret; - if (!(host = get_hostent_buffer( size ))) - return NULL; - - while ((ret = unix_funcs->gethostbyname( name, host, &size )) == ERROR_INSUFFICIENT_BUFFER) + for (;;) { - if (!(host = get_hostent_buffer( size ))) + if (!(params.host = get_hostent_buffer( size ))) return NULL; + + if ((ret = WS_CALL( gethostbyname, ¶ms )) != ERROR_INSUFFICIENT_BUFFER) + break; } SetLastError( ret ); - return ret ? NULL : host; + return ret ? NULL : params.host; } if (host && host->h_addr_list[0][0] == 127 && strcmp( name, "localhost" )) @@ -883,6 +885,7 @@ struct hostent * WINAPI gethostbyname( const char *name ) int WINAPI gethostname( char *name, int namelen ) { char buf[256]; + struct gethostname_params params = { buf, sizeof(buf) }; int len, ret; TRACE( "name %p, len %d\n", name, namelen ); @@ -893,7 +896,7 @@ int WINAPI gethostname( char *name, int namelen ) return -1; } - if ((ret = unix_funcs->gethostname( buf, sizeof(buf) ))) + if ((ret = WS_CALL( gethostname, ¶ms ))) { SetLastError( ret ); return -1; @@ -919,6 +922,7 @@ int WINAPI gethostname( char *name, int namelen ) int WINAPI GetHostNameW( WCHAR *name, int namelen ) { char buf[256]; + struct gethostname_params params = { buf, sizeof(buf) }; int ret; TRACE( "name %p, len %d\n", name, namelen ); @@ -929,7 +933,7 @@ int WINAPI GetHostNameW( WCHAR *name, int namelen ) return -1; } - if ((ret = unix_funcs->gethostname( buf, sizeof(buf) ))) + if ((ret = WS_CALL( gethostname, ¶ms ))) { SetLastError( ret ); return -1; diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 6324fc742e0..8f0ab12303a 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -35,8 +35,6 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); #define TIMEOUT_INFINITE _I64_MAX -const struct unix_funcs *unix_funcs = NULL; - static const WSAPROTOCOL_INFOW supported_protocols[] = { { @@ -552,7 +550,8 @@ BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) switch (reason) { case DLL_PROCESS_ATTACH: - return !__wine_init_unix_lib( instance, reason, NULL, &unix_funcs ); + return !NtQueryVirtualMemory( GetCurrentProcess(), instance, MemoryWineUnixFuncs, + &ws_unix_handle, sizeof(ws_unix_handle), NULL ); case DLL_THREAD_DETACH: free_per_thread_data(); diff --git a/dlls/ws2_32/unixlib.c b/dlls/ws2_32/unixlib.c index eb5b3daf401..a9a2b6939d9 100644 --- a/dlls/ws2_32/unixlib.c +++ b/dlls/ws2_32/unixlib.c @@ -652,10 +652,12 @@ static BOOL addrinfo_in_list( const struct WS_addrinfo *list, const struct WS_ad return FALSE; } -static int CDECL unix_getaddrinfo( const char *node, const char *service, const struct WS_addrinfo *hints, - struct WS_addrinfo *info, unsigned int *size ) +static NTSTATUS unix_getaddrinfo( void *args ) { #ifdef HAVE_GETADDRINFO + struct getaddrinfo_params *params = args; + const char *service = params->service; + const struct WS_addrinfo *hints = params->hints; struct addrinfo unix_hints = {0}; struct addrinfo *unix_info, *src; struct WS_addrinfo *dst, *prev = NULL; @@ -707,7 +709,7 @@ static int CDECL unix_getaddrinfo( const char *node, const char *service, const } } - ret = getaddrinfo( node, service, hints ? &unix_hints : NULL, &unix_info ); + ret = getaddrinfo( params->node, service, hints ? &unix_hints : NULL, &unix_info ); if (ret) return addrinfo_err_from_unix( ret ); @@ -719,16 +721,16 @@ static int CDECL unix_getaddrinfo( const char *node, const char *service, const needed_size += sockaddr_from_unix( (const union unix_sockaddr *)src->ai_addr, NULL, 0 ); } - if (*size < needed_size) + if (*params->size < needed_size) { - *size = needed_size; + *params->size = needed_size; freeaddrinfo( unix_info ); return ERROR_INSUFFICIENT_BUFFER; } - dst = info; + dst = params->info; - memset( info, 0, needed_size ); + memset( params->info, 0, needed_size ); for (src = unix_info; src != NULL; src = src->ai_next) { @@ -760,7 +762,7 @@ static int CDECL unix_getaddrinfo( const char *node, const char *service, const sockaddr_from_unix( (const union unix_sockaddr *)src->ai_addr, dst->ai_addr, dst->ai_addrlen ); next = (char *)dst->ai_addr + dst->ai_addrlen; - if (dst == info || !addrinfo_in_list( info, dst )) + if (dst == params->info || !addrinfo_in_list( params->info, dst )) { if (prev) prev->ai_next = dst; @@ -837,15 +839,16 @@ static int hostent_from_unix( const struct hostent *unix_host, struct WS_hostent } -static int CDECL unix_gethostbyaddr( const void *addr, int len, int family, - struct WS_hostent *const host, unsigned int *size ) +static NTSTATUS unix_gethostbyaddr( void *args ) { + struct gethostbyaddr_params *params = args; + const void *addr = params->addr; const struct in_addr loopback = { htonl( INADDR_LOOPBACK ) }; - int unix_family = family_to_unix( family ); + int unix_family = family_to_unix( params->family ); struct hostent *unix_host; int ret; - if (family == WS_AF_INET && len == 4 && !memcmp( addr, magic_loopback_addr, 4 )) + if (params->family == WS_AF_INET && params->len == 4 && !memcmp( addr, magic_loopback_addr, 4 )) addr = &loopback; #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 @@ -858,7 +861,7 @@ static int CDECL unix_gethostbyaddr( const void *addr, int len, int family, if (!(unix_buffer = malloc( unix_size ))) return WSAENOBUFS; - while (gethostbyaddr_r( addr, len, unix_family, &stack_host, unix_buffer, + while (gethostbyaddr_r( addr, params->len, unix_family, &stack_host, unix_buffer, unix_size, &unix_host, &locerr ) == ERANGE) { unix_size *= 2; @@ -873,7 +876,7 @@ static int CDECL unix_gethostbyaddr( const void *addr, int len, int family, if (!unix_host) return (locerr < 0 ? errno_from_unix( errno ) : host_errno_from_unix( locerr )); - ret = hostent_from_unix( unix_host, host, size ); + ret = hostent_from_unix( unix_host, params->host, params->size ); free( unix_buffer ); return ret; @@ -881,14 +884,14 @@ static int CDECL unix_gethostbyaddr( const void *addr, int len, int family, #else pthread_mutex_lock( &host_mutex ); - if (!(unix_host = gethostbyaddr( addr, len, unix_family ))) + if (!(unix_host = gethostbyaddr( addr, params->len, unix_family ))) { ret = (h_errno < 0 ? errno_from_unix( errno ) : host_errno_from_unix( h_errno )); pthread_mutex_unlock( &host_mutex ); return ret; } - ret = hostent_from_unix( unix_host, host, size ); + ret = hostent_from_unix( unix_host, params->host, params->size ); pthread_mutex_unlock( &host_mutex ); return ret; @@ -897,8 +900,9 @@ static int CDECL unix_gethostbyaddr( const void *addr, int len, int family, #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 -static int CDECL unix_gethostbyname( const char *name, struct WS_hostent *const host, unsigned int *size ) +static NTSTATUS unix_gethostbyname( void *args ) { + struct gethostbyname_params *params = args; struct hostent stack_host, *unix_host; char *unix_buffer, *new_buffer; int unix_size = 1024; @@ -908,7 +912,7 @@ static int CDECL unix_gethostbyname( const char *name, struct WS_hostent *const if (!(unix_buffer = malloc( unix_size ))) return WSAENOBUFS; - while (gethostbyname_r( name, &stack_host, unix_buffer, unix_size, &unix_host, &locerr ) == ERANGE) + while (gethostbyname_r( params->name, &stack_host, unix_buffer, unix_size, &unix_host, &locerr ) == ERANGE) { unix_size *= 2; if (!(new_buffer = realloc( unix_buffer, unix_size ))) @@ -922,27 +926,28 @@ static int CDECL unix_gethostbyname( const char *name, struct WS_hostent *const if (!unix_host) return (locerr < 0 ? errno_from_unix( errno ) : host_errno_from_unix( locerr )); - ret = hostent_from_unix( unix_host, host, size ); + ret = hostent_from_unix( unix_host, params->host, params->size ); free( unix_buffer ); return ret; } #else -static int CDECL unix_gethostbyname( const char *name, struct WS_hostent *const host, unsigned int *size ) +static NTSTATUS unix_gethostbyname( void *args ) { + struct gethostbyname_params *params = args; struct hostent *unix_host; int ret; pthread_mutex_lock( &host_mutex ); - if (!(unix_host = gethostbyname( name ))) + if (!(unix_host = gethostbyname( params->name ))) { ret = (h_errno < 0 ? errno_from_unix( errno ) : host_errno_from_unix( h_errno )); pthread_mutex_unlock( &host_mutex ); return ret; } - ret = hostent_from_unix( unix_host, host, size ); + ret = hostent_from_unix( unix_host, params->host, params->size ); pthread_mutex_unlock( &host_mutex ); return ret; @@ -950,28 +955,31 @@ static int CDECL unix_gethostbyname( const char *name, struct WS_hostent *const #endif -static int CDECL unix_gethostname( char *name, int len ) +static NTSTATUS unix_gethostname( void *args ) { - if (!gethostname( name, len )) + struct gethostname_params *params = args; + + if (!gethostname( params->name, params->size )) return 0; return errno_from_unix( errno ); } -static int CDECL unix_getnameinfo( const struct WS(sockaddr) *addr, int addr_len, char *host, - DWORD host_len, char *serv, DWORD serv_len, int flags ) +static NTSTATUS unix_getnameinfo( void *args ) { + struct getnameinfo_params *params = args; union unix_sockaddr unix_addr; socklen_t unix_addr_len; - unix_addr_len = sockaddr_to_unix( addr, addr_len, &unix_addr ); + unix_addr_len = sockaddr_to_unix( params->addr, params->addr_len, &unix_addr ); - return addrinfo_err_from_unix( getnameinfo( &unix_addr.addr, unix_addr_len, host, host_len, - serv, serv_len, nameinfo_flags_to_unix( flags ) ) ); + return addrinfo_err_from_unix( getnameinfo( &unix_addr.addr, unix_addr_len, params->host, params->host_len, + params->serv, params->serv_len, + nameinfo_flags_to_unix( params->flags ) ) ); } -static const struct unix_funcs funcs = +const unixlib_entry_t __wine_unix_call_funcs[] = { unix_getaddrinfo, unix_gethostbyaddr, @@ -979,11 +987,3 @@ static const struct unix_funcs funcs = unix_gethostname, unix_getnameinfo, }; - -NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) -{ - if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS; - - *(const struct unix_funcs **)ptr_out = &funcs; - return STATUS_SUCCESS; -} diff --git a/dlls/ws2_32/ws2_32_private.h b/dlls/ws2_32/ws2_32_private.h index f417c8975f4..5e2075b5c9c 100644 --- a/dlls/ws2_32/ws2_32_private.h +++ b/dlls/ws2_32/ws2_32_private.h @@ -51,6 +51,7 @@ #include "wine/debug.h" #include "wine/exception.h" #include "wine/heap.h" +#include "wine/unixlib.h" #define DECLARE_CRITICAL_SECTION(cs) \ static CRITICAL_SECTION cs; \ @@ -80,18 +81,57 @@ extern int num_startup; struct per_thread_data *get_per_thread_data(void) DECLSPEC_HIDDEN; -struct unix_funcs +struct getaddrinfo_params { - int (CDECL *getaddrinfo)( const char *node, const char *service, const struct WS(addrinfo) *hints, - struct WS(addrinfo) *info, unsigned int *size ); - int (CDECL *gethostbyaddr)( const void *addr, int len, int family, - struct WS(hostent) *host, unsigned int *size ); - int (CDECL *gethostbyname)( const char *name, struct WS(hostent) *host, unsigned int *size ); - int (CDECL *gethostname)( char *name, int len ); - int (CDECL *getnameinfo)( const struct WS(sockaddr) *addr, int addr_len, char *host, - DWORD host_len, char *serv, DWORD serv_len, int flags ); + const char *node; + const char *service; + const struct WS(addrinfo) *hints; + struct WS(addrinfo) *info; + unsigned int *size; }; -extern const struct unix_funcs *unix_funcs; +struct gethostbyaddr_params +{ + const void *addr; + int len; + int family; + struct WS(hostent) *host; + unsigned int *size; +}; + +struct gethostbyname_params +{ + const char *name; + struct WS(hostent) *host; + unsigned int *size; +}; + +struct gethostname_params +{ + char *name; + unsigned int size; +}; + +struct getnameinfo_params +{ + const struct WS(sockaddr) *addr; + int addr_len; + char *host; + DWORD host_len; + char *serv; + DWORD serv_len; + int flags; +}; + +enum ws_unix_funcs +{ + ws_unix_getaddrinfo, + ws_unix_gethostbyaddr, + ws_unix_gethostbyname, + ws_unix_gethostname, + ws_unix_getnameinfo, +}; + +extern unixlib_handle_t ws_unix_handle DECLSPEC_HIDDEN; #endif