[3/6] webservices: Add support for incoming TCP connections.

Hans Leidekker hans at codeweavers.com
Fri Apr 21 05:37:02 CDT 2017


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 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 6c4b3d0892..3663fdf29d 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 9d16ed1b22..a82897e589 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 dd36a790a7..f420b027ef 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 f55bef848e..c55e30445f 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)
-- 
2.11.0




More information about the wine-patches mailing list