Module: wine Branch: master Commit: 17a3dd17ce11f6d0ba51e4dbeab1882835e49499 URL: http://source.winehq.org/git/wine.git/?a=commit;h=17a3dd17ce11f6d0ba51e4dbea...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Apr 21 12:37:02 2017 +0200
webservices: Add support for incoming TCP connections.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/channel.c | 22 ++++++++ dlls/webservices/listener.c | 106 +++++++++++++++++++++++++++++++++----- dlls/webservices/sock.h | 1 + dlls/webservices/webservices.spec | 2 +- 4 files changed, 117 insertions(+), 14 deletions(-)
diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c index 6c4b3d0..3663fdf 100644 --- a/dlls/webservices/channel.c +++ b/dlls/webservices/channel.c @@ -1045,3 +1045,25 @@ done: LeaveCriticalSection( &channel->cs ); return hr; } + +HRESULT channel_accept_tcp( SOCKET socket, WS_CHANNEL *handle ) +{ + struct channel *channel = (struct channel *)handle; + + EnterCriticalSection( &channel->cs ); + + if (channel->magic != CHANNEL_MAGIC) + { + LeaveCriticalSection( &channel->cs ); + return E_INVALIDARG; + } + + if ((channel->u.tcp.socket = accept( socket, NULL, NULL )) == -1) + { + LeaveCriticalSection( &channel->cs ); + return HRESULT_FROM_WIN32( WSAGetLastError() ); + } + + LeaveCriticalSection( &channel->cs ); + return S_OK; +} diff --git a/dlls/webservices/listener.c b/dlls/webservices/listener.c index 9d16ed1..a82897e 100644 --- a/dlls/webservices/listener.c +++ b/dlls/webservices/listener.c @@ -75,7 +75,13 @@ struct listener WS_CHANNEL_TYPE type; WS_CHANNEL_BINDING binding; WS_LISTENER_STATE state; - SOCKET socket; + union + { + struct + { + SOCKET socket; + } tcp; + } u; ULONG prop_count; struct prop prop[sizeof(listener_props)/sizeof(listener_props[0])]; }; @@ -101,9 +107,17 @@ static struct listener *alloc_listener(void)
static void reset_listener( struct listener *listener ) { - closesocket( listener->socket ); - listener->socket = -1; - listener->state = WS_LISTENER_STATE_CREATED; + listener->state = WS_LISTENER_STATE_CREATED; + + switch (listener->binding) + { + case WS_TCP_CHANNEL_BINDING: + closesocket( listener->u.tcp.socket ); + listener->u.tcp.socket = -1; + break; + + default: break; + } }
static void free_listener( struct listener *listener ) @@ -136,7 +150,15 @@ static HRESULT create_listener( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding
listener->type = type; listener->binding = binding; - listener->socket = -1; + + switch (listener->binding) + { + case WS_TCP_CHANNEL_BINDING: + listener->u.tcp.socket = -1; + break; + + default: break; + }
*ret = listener; return S_OK; @@ -256,7 +278,7 @@ HRESULT parse_url( const WS_STRING *str, WS_URL_SCHEME_TYPE *scheme, WCHAR **hos return hr; }
-static HRESULT open_listener( struct listener *listener, const WS_STRING *url ) +static HRESULT open_listener_tcp( struct listener *listener, const WS_STRING *url ) { struct sockaddr_storage storage; struct sockaddr *addr = (struct sockaddr *)&storage; @@ -279,20 +301,20 @@ static HRESULT open_listener( struct listener *listener, const WS_STRING *url ) heap_free( host ); if (hr != S_OK) return hr;
- if ((listener->socket = socket( addr->sa_family, SOCK_STREAM, 0 )) == -1) + if ((listener->u.tcp.socket = socket( addr->sa_family, SOCK_STREAM, 0 )) == -1) return HRESULT_FROM_WIN32( WSAGetLastError() );
- if (bind( listener->socket, addr, addr_len ) < 0) + if (bind( listener->u.tcp.socket, addr, addr_len ) < 0) { - closesocket( listener->socket ); - listener->socket = -1; + closesocket( listener->u.tcp.socket ); + listener->u.tcp.socket = -1; return HRESULT_FROM_WIN32( WSAGetLastError() ); }
- if (listen( listener->socket, 0 ) < 0) + if (listen( listener->u.tcp.socket, 0 ) < 0) { - closesocket( listener->socket ); - listener->socket = -1; + closesocket( listener->u.tcp.socket ); + listener->u.tcp.socket = -1; return HRESULT_FROM_WIN32( WSAGetLastError() ); }
@@ -300,6 +322,19 @@ static HRESULT open_listener( struct listener *listener, const WS_STRING *url ) return S_OK; }
+static HRESULT open_listener( struct listener *listener, const WS_STRING *url ) +{ + switch (listener->binding) + { + case WS_TCP_CHANNEL_BINDING: + return open_listener_tcp( listener, url ); + + default: + ERR( "unhandled binding %u\n", listener->binding ); + return E_NOTIMPL; + } +} + /************************************************************************** * WsOpenListener [webservices.@] */ @@ -473,3 +508,48 @@ HRESULT WINAPI WsSetListenerProperty( WS_LISTENER *handle, WS_LISTENER_PROPERTY_ LeaveCriticalSection( &listener->cs ); return hr; } + +/************************************************************************** + * WsAcceptChannel [webservices.@] + */ +HRESULT WINAPI WsAcceptChannel( WS_LISTENER *handle, WS_CHANNEL *channel_handle, const WS_ASYNC_CONTEXT *ctx, + WS_ERROR *error ) +{ + struct listener *listener = (struct listener *)handle; + HRESULT hr; + + TRACE( "%p %p %p %p\n", handle, channel_handle, ctx, error ); + if (error) FIXME( "ignoring error parameter\n" ); + if (ctx) FIXME( "ignoring ctx parameter\n" ); + + if (!listener || !channel_handle) return E_INVALIDARG; + + EnterCriticalSection( &listener->cs ); + + if (listener->magic != LISTENER_MAGIC) + { + LeaveCriticalSection( &listener->cs ); + return E_INVALIDARG; + } + + if (listener->state != WS_LISTENER_STATE_OPEN) + { + LeaveCriticalSection( &listener->cs ); + return WS_E_INVALID_OPERATION; + } + + switch (listener->binding) + { + case WS_TCP_CHANNEL_BINDING: + hr = channel_accept_tcp( listener->u.tcp.socket, channel_handle ); + break; + + default: + FIXME( "listener binding %u not supported\n", listener->binding ); + hr = E_NOTIMPL; + break; + } + + LeaveCriticalSection( &listener->cs ); + return hr; +} diff --git a/dlls/webservices/sock.h b/dlls/webservices/sock.h index dd36a79..f420b02 100644 --- a/dlls/webservices/sock.h +++ b/dlls/webservices/sock.h @@ -20,3 +20,4 @@
void winsock_init(void) DECLSPEC_HIDDEN; HRESULT resolve_hostname( const WCHAR *, USHORT, struct sockaddr *, int * ) DECLSPEC_HIDDEN; +HRESULT channel_accept_tcp( SOCKET, WS_CHANNEL * ) DECLSPEC_HIDDEN; diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index f55bef8..c55e304 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -4,7 +4,7 @@ @ stub WsAbortListener @ stub WsAbortServiceHost @ stdcall WsAbortServiceProxy(ptr ptr) -@ stub WsAcceptChannel +@ stdcall WsAcceptChannel(ptr ptr ptr ptr) @ stdcall WsAddCustomHeader(ptr ptr long ptr long long ptr) @ stub WsAddErrorString @ stdcall WsAddMappedHeader(ptr ptr long long ptr long ptr)