Hans Leidekker : webservices: Add support for incoming TCP connections.
Alexandre Julliard
julliard at winehq.org
Fri Apr 21 15:18:17 CDT 2017
Module: wine
Branch: master
Commit: 17a3dd17ce11f6d0ba51e4dbeab1882835e49499
URL: http://source.winehq.org/git/wine.git/?a=commit;h=17a3dd17ce11f6d0ba51e4dbeab1882835e49499
Author: Hans Leidekker <hans at codeweavers.com>
Date: Fri Apr 21 12:37:02 2017 +0200
webservices: Add support for incoming TCP connections.
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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)
More information about the wine-cvs
mailing list