From 8355a96dd3d55e6253cbb281214ab8ba7eb2cd2e Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Wed, 20 Jun 2018 15:04:46 +0200 Subject: [PATCH] webservices: Implement WsShutdownSessionChannel. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- 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 685e13d99d7..6c7c8affa3c 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 c995a08829a..db17893138e 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 55f3e2eaaca..8ba34b42090 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 1f823ddc273..928819fc3d3 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*);