[PATCH 3/5] webservices: Implement WsShutdownSessionChannel.

Hans Leidekker hans at codeweavers.com
Wed Jun 20 08:04:46 CDT 2018


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/channel.c        | 98 +++++++++++++++++++++++++++++----------
 dlls/webservices/tests/channel.c  | 12 +++++
 dlls/webservices/webservices.spec |  2 +-
 include/webservices.h             |  1 +
 4 files changed, 87 insertions(+), 26 deletions(-)

diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c
index 685e13d99d..6c7c8affa3 100644
--- a/dlls/webservices/channel.c
+++ b/dlls/webservices/channel.c
@@ -193,6 +193,7 @@ enum session_state
 {
     SESSION_STATE_UNINITIALIZED,
     SESSION_STATE_SETUP_COMPLETE,
+    SESSION_STATE_SHUTDOWN,
 };
 
 struct channel
@@ -664,6 +665,78 @@ HRESULT WINAPI WsOpenChannel( WS_CHANNEL *handle, const WS_ENDPOINT_ADDRESS *end
     return hr;
 }
 
+enum frame_record_type
+{
+    FRAME_RECORD_TYPE_VERSION,
+    FRAME_RECORD_TYPE_MODE,
+    FRAME_RECORD_TYPE_VIA,
+    FRAME_RECORD_TYPE_KNOWN_ENCODING,
+    FRAME_RECORD_TYPE_EXTENSIBLE_ENCODING,
+    FRAME_RECORD_TYPE_UNSIZED_ENVELOPE,
+    FRAME_RECORD_TYPE_SIZED_ENVELOPE,
+    FRAME_RECORD_TYPE_END,
+    FRAME_RECORD_TYPE_FAULT,
+    FRAME_RECORD_TYPE_UPGRADE_REQUEST,
+    FRAME_RECORD_TYPE_UPGRADE_RESPONSE,
+    FRAME_RECORD_TYPE_PREAMBLE_ACK,
+    FRAME_RECORD_TYPE_PREAMBLE_END,
+};
+
+static HRESULT send_byte( SOCKET socket, BYTE byte )
+{
+    int count = send( socket, (char *)&byte, 1, 0 );
+    if (count < 0) return HRESULT_FROM_WIN32( WSAGetLastError() );
+    if (count != 1) return WS_E_OTHER;
+    return S_OK;
+}
+
+static HRESULT shutdown_session( struct channel *channel )
+{
+    HRESULT hr;
+
+    if (channel->state != WS_CHANNEL_STATE_OPEN ||
+        (channel->type != WS_CHANNEL_TYPE_OUTPUT_SESSION &&
+         channel->type != WS_CHANNEL_TYPE_DUPLEX_SESSION) ||
+         channel->session_state >= SESSION_STATE_SHUTDOWN) return WS_E_INVALID_OPERATION;
+
+    switch (channel->binding)
+    {
+    case WS_TCP_CHANNEL_BINDING:
+        if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_END )) != S_OK) return hr;
+        channel->session_state = SESSION_STATE_SHUTDOWN;
+        return S_OK;
+
+    default:
+        FIXME( "unhandled binding %u\n", channel->binding );
+        return E_NOTIMPL;
+    }
+}
+
+HRESULT WINAPI WsShutdownSessionChannel( WS_CHANNEL *handle, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
+{
+    struct channel *channel = (struct channel *)handle;
+    HRESULT hr;
+
+    TRACE( "%p %p %p\n", handle, ctx, error );
+    if (error) FIXME( "ignoring error parameter\n" );
+    if (ctx) FIXME( "ignoring ctx parameter\n" );
+
+    if (!channel) return E_INVALIDARG;
+
+    EnterCriticalSection( &channel->cs );
+
+    if (channel->magic != CHANNEL_MAGIC)
+    {
+        LeaveCriticalSection( &channel->cs );
+        return E_INVALIDARG;
+    }
+
+    hr = shutdown_session( channel );
+
+    LeaveCriticalSection( &channel->cs );
+    return hr;
+}
+
 static void close_channel( struct channel *channel )
 {
     reset_channel( channel );
@@ -913,14 +986,6 @@ static HRESULT send_message_http( HINTERNET request, BYTE *data, ULONG len )
     return S_OK;
 }
 
-static HRESULT send_byte( SOCKET socket, BYTE byte )
-{
-    int count = send( socket, (char *)&byte, 1, 0 );
-    if (count < 0) return HRESULT_FROM_WIN32( WSAGetLastError() );
-    if (count != 1) return WS_E_OTHER;
-    return S_OK;
-}
-
 static HRESULT send_bytes( SOCKET socket, BYTE *bytes, int len )
 {
     int count = send( socket, (char *)bytes, len, 0 );
@@ -944,23 +1009,6 @@ static HRESULT send_size( SOCKET socket, ULONG size )
     return E_INVALIDARG;
 }
 
-enum frame_record_type
-{
-    FRAME_RECORD_TYPE_VERSION,
-    FRAME_RECORD_TYPE_MODE,
-    FRAME_RECORD_TYPE_VIA,
-    FRAME_RECORD_TYPE_KNOWN_ENCODING,
-    FRAME_RECORD_TYPE_EXTENSIBLE_ENCODING,
-    FRAME_RECORD_TYPE_UNSIZED_ENVELOPE,
-    FRAME_RECORD_TYPE_SIZED_ENVELOPE,
-    FRAME_RECORD_TYPE_END,
-    FRAME_RECORD_TYPE_FAULT,
-    FRAME_RECORD_TYPE_UPGRADE_REQUEST,
-    FRAME_RECORD_TYPE_UPGRADE_RESPONSE,
-    FRAME_RECORD_TYPE_PREAMBLE_ACK,
-    FRAME_RECORD_TYPE_PREAMBLE_END,
-};
-
 static inline ULONG size_length( ULONG size )
 {
     if (size < 0x80) return 1;
diff --git a/dlls/webservices/tests/channel.c b/dlls/webservices/tests/channel.c
index c995a08829..db17893138 100644
--- a/dlls/webservices/tests/channel.c
+++ b/dlls/webservices/tests/channel.c
@@ -496,6 +496,9 @@ static void test_message_read_write( const struct listener_info *info )
     hr = WsOpenChannel( channel, &addr, NULL, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
+    hr = WsShutdownSessionChannel( channel, NULL, NULL );
+    ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
     hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
@@ -627,6 +630,9 @@ static void test_duplex_session( const struct listener_info *info )
     hr = WsCreateChannel( info->type, info->binding, NULL, 0, NULL, &channel, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
+    hr = WsShutdownSessionChannel( channel, NULL, NULL );
+    ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
     memset( &addr, 0, sizeof(addr) );
     addr.url.length = wsprintfW( buf, fmt, info->port );
     addr.url.chars  = buf;
@@ -655,6 +661,12 @@ static void test_duplex_session( const struct listener_info *info )
     err = WaitForSingleObject( info->wait, 3000 );
     ok( err == WAIT_OBJECT_0, "wait failed %u\n", err );
 
+    hr = WsShutdownSessionChannel( channel, NULL, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsShutdownSessionChannel( channel, NULL, NULL );
+    ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
     hr = WsCloseChannel( channel, NULL, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
 
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index 55f3e2eaac..8ba34b4209 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -158,7 +158,7 @@
 @ stdcall WsSetOutputToBuffer(ptr ptr ptr long ptr)
 @ stdcall WsSetReaderPosition(ptr ptr ptr)
 @ stdcall WsSetWriterPosition(ptr ptr ptr)
-@ stub WsShutdownSessionChannel
+@ stdcall WsShutdownSessionChannel(ptr ptr ptr)
 @ stdcall WsSkipNode(ptr ptr)
 @ stub WsStartReaderCanonicalization
 @ stub WsStartWriterCanonicalization
diff --git a/include/webservices.h b/include/webservices.h
index 1f823ddc27..928819fc3d 100644
--- a/include/webservices.h
+++ b/include/webservices.h
@@ -1732,6 +1732,7 @@ HRESULT WINAPI WsSetOutputToBuffer(WS_XML_WRITER*, WS_XML_BUFFER*, const WS_XML_
                                    ULONG, WS_ERROR*);
 HRESULT WINAPI WsSetReaderPosition(WS_XML_READER*, const WS_XML_NODE_POSITION*, WS_ERROR*);
 HRESULT WINAPI WsSetWriterPosition(WS_XML_WRITER*, const WS_XML_NODE_POSITION*, WS_ERROR*);
+HRESULT WINAPI WsShutdownSessionChannel(WS_CHANNEL*, const WS_ASYNC_CONTEXT*, WS_ERROR*);
 HRESULT WINAPI WsSkipNode(WS_XML_READER*, WS_ERROR*);
 HRESULT WINAPI WsWriteArray(WS_XML_WRITER*, const WS_XML_STRING*, const WS_XML_STRING*, WS_VALUE_TYPE,
                             const void*, ULONG, ULONG, ULONG, WS_ERROR*);
-- 
2.11.0




More information about the wine-devel mailing list