ws2_32: Convert the Unix library to the __wine_unix_call interface.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
948e791928
commit
d327527cec
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue