Module: wine Branch: master Commit: 8d9bf5375879ab3c220029966faffa4c74d4793c URL: http://source.winehq.org/git/wine.git/?a=commit;h=8d9bf5375879ab3c220029966f...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Apr 13 13:49:44 2016 +0200
webservices: Implement WsCreateChannel and WsFreeChannel.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/Makefile.in | 1 + dlls/webservices/channel.c | 158 +++++++++++++++++++++++++++++++++ dlls/webservices/webservices.spec | 4 +- dlls/webservices/webservices_private.h | 12 +++ 4 files changed, 173 insertions(+), 2 deletions(-)
diff --git a/dlls/webservices/Makefile.in b/dlls/webservices/Makefile.in index d48e3c6..c052252 100644 --- a/dlls/webservices/Makefile.in +++ b/dlls/webservices/Makefile.in @@ -3,6 +3,7 @@ IMPORTLIB = webservices IMPORTS = user32
C_SRCS = \ + channel.c \ main.c \ reader.c \ writer.c diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c new file mode 100644 index 0000000..c8a920d --- /dev/null +++ b/dlls/webservices/channel.c @@ -0,0 +1,158 @@ +/* + * Copyright 2016 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "webservices.h" + +#include "wine/debug.h" +#include "wine/list.h" +#include "webservices_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(webservices); + +static const struct +{ + ULONG size; + BOOL readonly; +} +channel_props[] = +{ + { sizeof(ULONG), FALSE }, /* WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE */ + { sizeof(UINT64), FALSE }, /* WS_CHANNEL_PROPERTY_MAX_STREAMED_MESSAGE_SIZE */ + { sizeof(ULONG), FALSE }, /* WS_CHANNEL_PROPERTY_MAX_STREAMED_START_SIZE */ + { sizeof(ULONG), FALSE }, /* WS_CHANNEL_PROPERTY_MAX_STREAMED_FLUSH_SIZE */ + { sizeof(WS_ENCODING), FALSE }, /* WS_CHANNEL_PROPERTY_ENCODING */ + { sizeof(WS_ENVELOPE_VERSION), FALSE }, /* WS_CHANNEL_PROPERTY_ENVELOPE_VERSION */ + { sizeof(WS_ADDRESSING_VERSION), FALSE }, /* WS_CHANNEL_PROPERTY_ADDRESSING_VERSION */ + { sizeof(ULONG), FALSE }, /* WS_CHANNEL_PROPERTY_MAX_SESSION_DICTIONARY_SIZE */ + { sizeof(WS_CHANNEL_STATE), TRUE }, /* WS_CHANNEL_PROPERTY_STATE */ +}; + +static struct channel *alloc_channel(void) +{ + static const ULONG count = sizeof(channel_props)/sizeof(channel_props[0]); + struct channel *ret; + ULONG i, size = sizeof(*ret) + count * sizeof(WS_CHANNEL_PROPERTY); + char *ptr; + + for (i = 0; i < count; i++) size += channel_props[i].size; + if (!(ret = heap_alloc_zero( size ))) return NULL; + + ptr = (char *)&ret->prop[count]; + for (i = 0; i < count; i++) + { + ret->prop[i].value = ptr; + ret->prop[i].valueSize = channel_props[i].size; + ptr += ret->prop[i].valueSize; + } + ret->prop_count = count; + return ret; +} + +static HRESULT set_channel_prop( struct channel *channel, WS_CHANNEL_PROPERTY_ID id, const void *value, + ULONG size ) +{ + if (id >= channel->prop_count || size != channel_props[id].size || channel_props[id].readonly) + return E_INVALIDARG; + + memcpy( channel->prop[id].value, value, size ); + return S_OK; +} + +void free_channel( struct channel *channel ) +{ + heap_free( channel ); +} + +HRESULT create_channel( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding, + const WS_CHANNEL_PROPERTY *properties, ULONG count, struct channel **ret ) +{ + struct channel *channel; + ULONG i, msg_size = 65536; + HRESULT hr; + + if (!(channel = alloc_channel())) return E_OUTOFMEMORY; + + set_channel_prop( channel, WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE, &msg_size, sizeof(msg_size) ); + + for (i = 0; i < count; i++) + { + hr = set_channel_prop( channel, properties[i].id, properties[i].value, properties[i].valueSize ); + if (hr != S_OK) + { + free_channel( channel ); + return hr; + } + } + + channel->type = type; + channel->binding = binding; + + *ret = channel; + return S_OK; +} + +/************************************************************************** + * WsCreateChannel [webservices.@] + */ +HRESULT WINAPI WsCreateChannel( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding, + const WS_CHANNEL_PROPERTY *properties, ULONG count, + const WS_SECURITY_DESCRIPTION *desc, WS_CHANNEL **handle, + WS_ERROR *error ) +{ + struct channel *channel; + HRESULT hr; + + TRACE( "%u %u %p %u %p %p %p\n", type, binding, properties, count, desc, handle, error ); + if (error) FIXME( "ignoring error parameter\n" ); + if (desc) FIXME( "ignoring security description\n" ); + + if (!handle) return E_INVALIDARG; + + if (type != WS_CHANNEL_TYPE_REQUEST) + { + FIXME( "channel type %u not implemented\n", type ); + return E_NOTIMPL; + } + if (binding != WS_HTTP_CHANNEL_BINDING) + { + FIXME( "channel binding %u not implemented\n", binding ); + return E_NOTIMPL; + } + + if ((hr = create_channel( type, binding, properties, count, &channel )) != S_OK) + return hr; + + *handle = (WS_CHANNEL *)channel; + return S_OK; +} + +/************************************************************************** + * WsFreeChannel [webservices.@] + */ +void WINAPI WsFreeChannel( WS_CHANNEL *handle ) +{ + struct channel *channel = (struct channel *)handle; + + TRACE( "%p\n", handle ); + free_channel( channel ); +} diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index 9c0b3c7..2ddda72 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -20,7 +20,7 @@ @ stub WsCombineUrl @ stub WsCopyError @ stub WsCopyNode -@ stub WsCreateChannel +@ stdcall WsCreateChannel(long long ptr long ptr ptr ptr) @ stub WsCreateChannelForListener @ stdcall WsCreateError(ptr long ptr) @ stub WsCreateFaultFromError @@ -48,7 +48,7 @@ @ stdcall WsFindAttribute(ptr ptr ptr long ptr ptr) @ stub WsFlushBody @ stub WsFlushWriter -@ stub WsFreeChannel +@ stdcall WsFreeChannel(ptr) @ stdcall WsFreeError(ptr) @ stdcall WsFreeHeap(ptr) @ stub WsFreeListener diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index c286fd2..1ec3eeb 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -50,6 +50,18 @@ static inline WS_XML_NODE_TYPE node_type( const struct node *node ) return node->hdr.node.nodeType; }
+struct channel +{ + WS_CHANNEL_TYPE type; + WS_CHANNEL_BINDING binding; + ULONG prop_count; + WS_CHANNEL_PROPERTY prop[9]; +}; + +HRESULT create_channel( WS_CHANNEL_TYPE, WS_CHANNEL_BINDING, const WS_CHANNEL_PROPERTY *, + ULONG, struct channel ** ) DECLSPEC_HIDDEN; +void free_channel( struct channel * ) DECLSPEC_HIDDEN; + static inline void *heap_alloc( SIZE_T size ) { return HeapAlloc( GetProcessHeap(), 0, size );