/*
 * 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 "rpc.h"
#include "webservices.h"

#include "wine/debug.h"
#include "wine/list.h"
#include "wine/unicode.h"
#include "webservices_private.h"
#include "sock.h"

WINE_DEFAULT_DEBUG_CHANNEL(webservices);

static const struct prop_desc 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), TRUE },                          /* 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 */
    { sizeof(WS_CALLBACK_MODEL), FALSE },                   /* WS_CHANNEL_PROPERTY_ASYNC_CALLBACK_MODEL */
    { sizeof(WS_IP_VERSION), FALSE },                       /* WS_CHANNEL_PROPERTY_IP_VERSION */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_RESOLVE_TIMEOUT */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_CONNECT_TIMEOUT */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_SEND_TIMEOUT */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_RECEIVE_RESPONSE_TIMEOUT */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_RECEIVE_TIMEOUT */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_CLOSE_TIMEOUT */
    { sizeof(BOOL), FALSE },                                /* WS_CHANNEL_PROPERTY_ENABLE_TIMEOUTS */
    { sizeof(WS_TRANSFER_MODE), FALSE },                    /* WS_CHANNEL_PROPERTY_TRANSFER_MODE */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_MULTICAST_INTERFACE */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_MULTICAST_HOPS */
    { sizeof(WS_ENDPOINT_ADDRESS), TRUE },                  /* WS_CHANNEL_PROPERTY_REMOTE_ADDRESS */
    { sizeof(SOCKADDR_STORAGE), TRUE },                     /* WS_CHANNEL_PROPERTY_REMOTE_IP_ADDRESS */
    { sizeof(ULONGLONG), TRUE },                            /* WS_CHANNEL_PROPERTY_HTTP_CONNECTION_ID */
    { sizeof(WS_CUSTOM_CHANNEL_CALLBACKS), FALSE },         /* WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_CALLBACKS */
    { 0, FALSE },                                           /* WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_PARAMETERS */
    { sizeof(void *), FALSE },                              /* WS_CHANNEL_PROPERTY_CUSTOM_CHANNEL_INSTANCE */
    { sizeof(WS_STRING), TRUE },                            /* WS_CHANNEL_PROPERTY_TRANSPORT_URL */
    { sizeof(BOOL), FALSE },                                /* WS_CHANNEL_PROPERTY_NO_DELAY */
    { sizeof(BOOL), FALSE },                                /* WS_CHANNEL_PROPERTY_SEND_KEEP_ALIVES */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_KEEP_ALIVE_TIME */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_KEEP_ALIVE_INTERVAL */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_MAX_HTTP_SERVER_CONNECTIONS */
    { sizeof(BOOL), TRUE },                                 /* WS_CHANNEL_PROPERTY_IS_SESSION_SHUT_DOWN */
    { sizeof(WS_CHANNEL_TYPE), TRUE },                      /* WS_CHANNEL_PROPERTY_CHANNEL_TYPE */
    { sizeof(ULONG), FALSE },                               /* WS_CHANNEL_PROPERTY_TRIM_BUFFERED_MESSAGE_SIZE */
    { sizeof(WS_CHANNEL_ENCODER), FALSE },                  /* WS_CHANNEL_PROPERTY_ENCODER */
    { sizeof(WS_CHANNEL_DECODER), FALSE },                  /* WS_CHANNEL_PROPERTY_DECODER */
    { sizeof(WS_PROTECTION_LEVEL), TRUE },                  /* WS_CHANNEL_PROPERTY_PROTECTION_LEVEL */
    { sizeof(WS_COOKIE_MODE), FALSE },                      /* WS_CHANNEL_PROPERTY_COOKIE_MODE */
    { sizeof(WS_HTTP_PROXY_SETTING_MODE), FALSE },          /* WS_CHANNEL_PROPERTY_HTTP_PROXY_SETTING_MODE */
    { sizeof(WS_CUSTOM_HTTP_PROXY), FALSE },                /* WS_CHANNEL_PROPERTY_CUSTOM_HTTP_PROXY */
    { sizeof(WS_HTTP_MESSAGE_MAPPING), FALSE },             /* WS_CHANNEL_PROPERTY_HTTP_MESSAGE_MAPPING */
    { sizeof(BOOL), FALSE },                                /* WS_CHANNEL_PROPERTY_ENABLE_HTTP_REDIRECT */
    { sizeof(WS_HTTP_REDIRECT_CALLBACK_CONTEXT), FALSE },   /* WS_CHANNEL_PROPERTY_HTTP_REDIRECT_CALLBACK_CONTEXT */
    { sizeof(BOOL), FALSE },                                /* WS_CHANNEL_PROPERTY_FAULTS_AS_ERRORS */
    { sizeof(BOOL), FALSE },                                /* WS_CHANNEL_PROPERTY_ALLOW_UNSECURED_FAULTS */
    { sizeof(WCHAR *), TRUE },                              /* WS_CHANNEL_PROPERTY_HTTP_SERVER_SPN */
    { sizeof(WCHAR *), TRUE },                              /* WS_CHANNEL_PROPERTY_HTTP_PROXY_SPN */
    { sizeof(ULONG), FALSE }                                /* WS_CHANNEL_PROPERTY_MAX_HTTP_REQUEST_HEADERS_BUFFER_SIZE */
};

struct task
{
    struct list   entry;
    void        (*proc)( struct task * );
};

struct queue
{
    CRITICAL_SECTION cs;
    HANDLE           wait;
    HANDLE           cancel;
    HANDLE           ready;
    struct list      tasks;
};

static struct task *dequeue_task( struct queue *queue )
{
    struct task *task;

    EnterCriticalSection( &queue->cs );
    TRACE( "%u tasks queued\n", list_count( &queue->tasks ) );
    task = LIST_ENTRY( list_head( &queue->tasks ), struct task, entry );
    if (task) list_remove( &task->entry );
    LeaveCriticalSection( &queue->cs );

    TRACE( "returning task %p\n", task );
    return task;
}

static void CALLBACK queue_runner( TP_CALLBACK_INSTANCE *instance, void *ctx )
{
    struct queue *queue = ctx;
    HANDLE handles[] = { queue->wait, queue->cancel };

    SetEvent( queue->ready );
    for (;;)
    {
        DWORD err = WaitForMultipleObjects( 2, handles, FALSE, INFINITE );
        switch (err)
        {
        case WAIT_OBJECT_0:
        {
            struct task *task;
            while ((task = dequeue_task( queue )))
            {
                task->proc( task );
                heap_free( task );
            }
            break;
        }
        case WAIT_OBJECT_0 + 1:
            TRACE( "cancelled\n" );
            SetEvent( queue->ready );
            return;

        default:
            ERR( "wait failed %u\n", err );
            return;
        }
    }
}

static HRESULT start_queue( struct queue *queue )
{
    HRESULT hr = E_OUTOFMEMORY;

    if (queue->wait) return S_OK;
    list_init( &queue->tasks );
    if (!(queue->wait = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error;
    if (!(queue->cancel = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error;
    if (!(queue->ready = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error;
    if (!TrySubmitThreadpoolCallback( queue_runner, queue, NULL )) hr = HRESULT_FROM_WIN32( GetLastError() );
    else
    {
        WaitForSingleObject( queue->ready, INFINITE );
        return S_OK;
    }

error:
    CloseHandle( queue->wait );
    CloseHandle( queue->cancel );
    CloseHandle( queue->ready );
    return hr;
}

static HRESULT queue_task( struct queue *queue, struct task *task )
{
    HRESULT hr;
    if ((hr = start_queue( queue )) != S_OK) return hr;

    EnterCriticalSection( &queue->cs );
    TRACE( "queueing task %p\n", task );
    list_add_tail( &queue->tasks, &task->entry );
    LeaveCriticalSection( &queue->cs );

    SetEvent( queue->wait );
    return WS_S_ASYNC;
};

enum session_state
{
    SESSION_STATE_UNINITIALIZED,
    SESSION_STATE_SETUP_COMPLETE,
};

struct channel
{
    ULONG                   magic;
    CRITICAL_SECTION        cs;
    WS_CHANNEL_TYPE         type;
    WS_CHANNEL_BINDING      binding;
    WS_CHANNEL_STATE        state;
    WS_ENDPOINT_ADDRESS     addr;
    WS_XML_WRITER          *writer;
    WS_XML_READER          *reader;
    WS_MESSAGE             *msg;
    WS_ENCODING             encoding;
    enum session_state      session_state;
    struct dictionary       dict_send;
    struct dictionary       dict_recv;
    struct queue            send_q;
    struct queue            recv_q;
    union
    {
        struct
        {
            HINTERNET session;
            HINTERNET connect;
            HINTERNET request;
            WCHAR    *path;
            DWORD     flags;
        } http;
        struct
        {
            SOCKET socket;
        } tcp;
        struct
        {
            SOCKET socket;
        } udp;
    } u;
    char                   *read_buf;
    ULONG                   read_buflen;
    ULONG                   read_size;
    ULONG                   prop_count;
    struct prop             prop[sizeof(channel_props)/sizeof(channel_props[0])];
};

#define CHANNEL_MAGIC (('C' << 24) | ('H' << 16) | ('A' << 8) | 'N')

static struct channel *alloc_channel(void)
{
    static const ULONG count = sizeof(channel_props)/sizeof(channel_props[0]);
    struct channel *ret;
    ULONG size = sizeof(*ret) + prop_size( channel_props, count );

    if (!(ret = heap_alloc_zero( size ))) return NULL;

    ret->magic      = CHANNEL_MAGIC;
    InitializeCriticalSection( &ret->cs );
    ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": channel.cs");

    InitializeCriticalSection( &ret->send_q.cs );
    ret->send_q.cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": channel.send_q.cs");

    InitializeCriticalSection( &ret->recv_q.cs );
    ret->recv_q.cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": channel.recv_q.cs");

    prop_init( channel_props, count, ret->prop, &ret[1] );
    ret->prop_count = count;
    return ret;
}

static void clear_addr( WS_ENDPOINT_ADDRESS *addr )
{
    heap_free( addr->url.chars );
    addr->url.chars  = NULL;
    addr->url.length = 0;
}

static void clear_queue( struct queue *queue )
{
    struct list *ptr;

    SetEvent( queue->cancel );
    WaitForSingleObject( queue->ready, INFINITE );

    while ((ptr = list_head( &queue->tasks )))
    {
        struct task *task = LIST_ENTRY( ptr, struct task, entry );
        list_remove( &task->entry );
        heap_free( task );
    }

    CloseHandle( queue->wait );
    queue->wait   = NULL;
    CloseHandle( queue->cancel );
    queue->cancel = NULL;
    CloseHandle( queue->ready );
    queue->ready   = NULL;
}

static void reset_channel( struct channel *channel )
{
    clear_queue( &channel->send_q );
    clear_queue( &channel->recv_q );
    channel->state         = WS_CHANNEL_STATE_CREATED;
    channel->session_state = SESSION_STATE_UNINITIALIZED;
    clear_addr( &channel->addr );
    clear_dict( &channel->dict_send );
    clear_dict( &channel->dict_recv );
    channel->msg           = NULL;
    channel->read_size     = 0;

    switch (channel->binding)
    {
    case WS_HTTP_CHANNEL_BINDING:
        WinHttpCloseHandle( channel->u.http.request );
        channel->u.http.request = NULL;
        WinHttpCloseHandle( channel->u.http.connect );
        channel->u.http.connect = NULL;
        WinHttpCloseHandle( channel->u.http.session );
        channel->u.http.session = NULL;
        heap_free( channel->u.http.path );
        channel->u.http.path    = NULL;
        channel->u.http.flags   = 0;
        break;

    case WS_TCP_CHANNEL_BINDING:
        closesocket( channel->u.tcp.socket );
        channel->u.tcp.socket = -1;
        break;

    case WS_UDP_CHANNEL_BINDING:
        closesocket( channel->u.udp.socket );
        channel->u.udp.socket = -1;
        break;

    default: break;
    }
}

static void free_channel( struct channel *channel )
{
    reset_channel( channel );

    WsFreeWriter( channel->writer );
    WsFreeReader( channel->reader );

    heap_free( channel->read_buf );

    channel->send_q.cs.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection( &channel->send_q.cs );

    channel->recv_q.cs.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection( &channel->recv_q.cs );

    channel->cs.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection( &channel->cs );
    heap_free( channel );
}

static 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;
    WS_ENVELOPE_VERSION env_version = WS_ENVELOPE_VERSION_SOAP_1_2;
    WS_ADDRESSING_VERSION addr_version = WS_ADDRESSING_VERSION_1_0;
    HRESULT hr;

    if (!(channel = alloc_channel())) return E_OUTOFMEMORY;

    prop_set( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE,
              &msg_size, sizeof(msg_size) );
    prop_set( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_ENVELOPE_VERSION,
              &env_version, sizeof(env_version) );
    prop_set( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_ADDRESSING_VERSION,
              &addr_version, sizeof(addr_version) );

    channel->type    = type;
    channel->binding = binding;

    switch (channel->binding)
    {
    case WS_HTTP_CHANNEL_BINDING:
        channel->encoding = WS_ENCODING_XML_UTF8;
        break;

    case WS_TCP_CHANNEL_BINDING:
        channel->u.tcp.socket = -1;
        channel->encoding     = WS_ENCODING_XML_BINARY_SESSION_1;
        break;

    case WS_UDP_CHANNEL_BINDING:
        channel->u.udp.socket = -1;
        channel->encoding     = WS_ENCODING_XML_UTF8;
        break;

    default: break;
    }

    for (i = 0; i < count; i++)
    {
        switch (properties[i].id)
        {
        case WS_CHANNEL_PROPERTY_ENCODING:
            if (!properties[i].value || properties[i].valueSize != sizeof(channel->encoding))
            {
                free_channel( channel );
                return E_INVALIDARG;
            }
            channel->encoding = *(WS_ENCODING *)properties[i].value;
            break;

        default:
            if ((hr = prop_set( channel->prop, channel->prop_count, properties[i].id, properties[i].value,
                                properties[i].valueSize )) != S_OK)
            {
                free_channel( channel );
                return hr;
            }
            break;
        }
    }

    *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 && type != WS_CHANNEL_TYPE_DUPLEX &&
        type != WS_CHANNEL_TYPE_DUPLEX_SESSION)
    {
        FIXME( "channel type %u not implemented\n", type );
        return E_NOTIMPL;
    }
    if (binding != WS_HTTP_CHANNEL_BINDING && binding != WS_TCP_CHANNEL_BINDING &&
        binding != WS_UDP_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;

    TRACE( "created %p\n", channel );
    *handle = (WS_CHANNEL *)channel;
    return S_OK;
}

/**************************************************************************
 *          WsCreateChannelForListener		[webservices.@]
 */
HRESULT WINAPI WsCreateChannelForListener( WS_LISTENER *listener_handle, const WS_CHANNEL_PROPERTY *properties,
                                           ULONG count, WS_CHANNEL **handle, WS_ERROR *error )
{
    struct channel *channel;
    WS_CHANNEL_TYPE type;
    WS_CHANNEL_BINDING binding;
    HRESULT hr;

    TRACE( "%p %p %u %p %p\n", listener_handle, properties, count, handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!listener_handle || !handle) return E_INVALIDARG;

    if ((hr = WsGetListenerProperty( listener_handle, WS_LISTENER_PROPERTY_CHANNEL_TYPE, &type,
                                     sizeof(type), NULL )) != S_OK) return hr;

    if ((hr = WsGetListenerProperty( listener_handle, WS_LISTENER_PROPERTY_CHANNEL_BINDING, &binding,
                                     sizeof(binding), NULL )) != S_OK) return hr;

    if ((hr = create_channel( type, binding, properties, count, &channel )) != S_OK) return hr;

    TRACE( "created %p\n", channel );
    *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 );

    if (!channel) return;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return;
    }

    channel->magic = 0;

    LeaveCriticalSection( &channel->cs );
    free_channel( channel );
}

/**************************************************************************
 *          WsResetChannel		[webservices.@]
 */
HRESULT WINAPI WsResetChannel( WS_CHANNEL *handle, WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;

    TRACE( "%p %p\n", handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!channel) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    if (channel->state != WS_CHANNEL_STATE_CREATED && channel->state != WS_CHANNEL_STATE_CLOSED)
    {
        LeaveCriticalSection( &channel->cs );
        return WS_E_INVALID_OPERATION;
    }

    reset_channel( channel );

    LeaveCriticalSection( &channel->cs );
    return S_OK;
}

/**************************************************************************
 *          WsGetChannelProperty		[webservices.@]
 */
HRESULT WINAPI WsGetChannelProperty( WS_CHANNEL *handle, WS_CHANNEL_PROPERTY_ID id, void *buf,
                                     ULONG size, WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr = S_OK;

    TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!channel) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    switch (id)
    {
    case WS_CHANNEL_PROPERTY_CHANNEL_TYPE:
        if (!buf || size != sizeof(channel->type)) hr = E_INVALIDARG;
        else *(WS_CHANNEL_TYPE *)buf = channel->type;
        break;

    case WS_CHANNEL_PROPERTY_ENCODING:
        if (!buf || size != sizeof(channel->encoding)) hr = E_INVALIDARG;
        else *(WS_ENCODING *)buf = channel->encoding;
        break;

    default:
        hr = prop_get( channel->prop, channel->prop_count, id, buf, size );
    }

    LeaveCriticalSection( &channel->cs );
    return hr;
}

/**************************************************************************
 *          WsSetChannelProperty		[webservices.@]
 */
HRESULT WINAPI WsSetChannelProperty( WS_CHANNEL *handle, WS_CHANNEL_PROPERTY_ID id, const void *value,
                                     ULONG size, WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    TRACE( "%p %u %p %u\n", handle, id, value, size );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!channel) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    hr = prop_set( channel->prop, channel->prop_count, id, value, size );

    LeaveCriticalSection( &channel->cs );
    return hr;
}

static HRESULT open_channel( struct channel *channel, const WS_ENDPOINT_ADDRESS *endpoint )
{
    if (endpoint->headers || endpoint->extensions || endpoint->identity)
    {
        FIXME( "headers, extensions or identity not supported\n" );
        return E_NOTIMPL;
    }

    if (!(channel->addr.url.chars = heap_alloc( endpoint->url.length * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
    memcpy( channel->addr.url.chars, endpoint->url.chars, endpoint->url.length * sizeof(WCHAR) );
    channel->addr.url.length = endpoint->url.length;

    channel->state = WS_CHANNEL_STATE_OPEN;
    return S_OK;
}

/**************************************************************************
 *          WsOpenChannel		[webservices.@]
 */
HRESULT WINAPI WsOpenChannel( WS_CHANNEL *handle, const WS_ENDPOINT_ADDRESS *endpoint,
                              const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    TRACE( "%p %p %p %p\n", handle, endpoint, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!channel || !endpoint) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    if (channel->state != WS_CHANNEL_STATE_CREATED)
    {
        LeaveCriticalSection( &channel->cs );
        return WS_E_INVALID_OPERATION;
    }

    hr = open_channel( channel, endpoint );

    LeaveCriticalSection( &channel->cs );
    return hr;
}

static void close_channel( struct channel *channel )
{
    reset_channel( channel );
    channel->state = WS_CHANNEL_STATE_CLOSED;
}

/**************************************************************************
 *          WsCloseChannel		[webservices.@]
 */
HRESULT WINAPI WsCloseChannel( WS_CHANNEL *handle, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;

    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;
    }

    close_channel( channel );

    LeaveCriticalSection( &channel->cs );
    return S_OK;
}

static HRESULT parse_http_url( const WCHAR *url, ULONG len, URL_COMPONENTS *uc )
{
    HRESULT hr = E_OUTOFMEMORY;
    WCHAR *tmp;
    DWORD err;

    memset( uc, 0, sizeof(*uc) );
    uc->dwStructSize      = sizeof(*uc);
    uc->dwHostNameLength  = 128;
    uc->lpszHostName      = heap_alloc( uc->dwHostNameLength * sizeof(WCHAR) );
    uc->dwUrlPathLength   = 128;
    uc->lpszUrlPath       = heap_alloc( uc->dwUrlPathLength * sizeof(WCHAR) );
    uc->dwExtraInfoLength = 128;
    uc->lpszExtraInfo     = heap_alloc( uc->dwExtraInfoLength * sizeof(WCHAR) );
    if (!uc->lpszHostName || !uc->lpszUrlPath || !uc->lpszExtraInfo) goto error;

    if (!WinHttpCrackUrl( url, len, ICU_DECODE, uc ))
    {
        if ((err = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
        {
            hr = HRESULT_FROM_WIN32( err );
            goto error;
        }
        if (!(tmp = heap_realloc( uc->lpszHostName, uc->dwHostNameLength * sizeof(WCHAR) ))) goto error;
        uc->lpszHostName = tmp;
        if (!(tmp = heap_realloc( uc->lpszUrlPath, uc->dwUrlPathLength * sizeof(WCHAR) ))) goto error;
        uc->lpszUrlPath = tmp;
        if (!(tmp = heap_realloc( uc->lpszExtraInfo, uc->dwExtraInfoLength * sizeof(WCHAR) ))) goto error;
        uc->lpszExtraInfo = tmp;
        WinHttpCrackUrl( url, len, ICU_DECODE, uc );
    }

    return S_OK;

error:
    heap_free( uc->lpszHostName );
    heap_free( uc->lpszUrlPath );
    heap_free( uc->lpszExtraInfo );
    return hr;
}

static HRESULT connect_channel_http( struct channel *channel )
{
    static const WCHAR agentW[] =
        {'M','S','-','W','e','b','S','e','r','v','i','c','e','s','/','1','.','0',0};
    HINTERNET ses = NULL, con = NULL;
    URL_COMPONENTS uc;
    HRESULT hr;

    if (channel->u.http.connect) return S_OK;

    if ((hr = parse_http_url( channel->addr.url.chars, channel->addr.url.length, &uc )) != S_OK) return hr;
    if (!(channel->u.http.path = heap_alloc( (uc.dwUrlPathLength + uc.dwExtraInfoLength + 1) * sizeof(WCHAR) )))
    {
        hr = E_OUTOFMEMORY;
        goto done;
    }
    else
    {
        strcpyW( channel->u.http.path, uc.lpszUrlPath );
        if (uc.dwExtraInfoLength) strcatW( channel->u.http.path, uc.lpszExtraInfo );
    }

    channel->u.http.flags = WINHTTP_FLAG_REFRESH;
    switch (uc.nScheme)
    {
    case INTERNET_SCHEME_HTTP: break;
    case INTERNET_SCHEME_HTTPS:
        channel->u.http.flags |= WINHTTP_FLAG_SECURE;
        break;

    default:
        hr = WS_E_INVALID_ENDPOINT_URL;
        goto done;
    }

    if (!(ses = WinHttpOpen( agentW, 0, NULL, NULL, 0 )))
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        goto done;
    }
    if (!(con = WinHttpConnect( ses, uc.lpszHostName, uc.nPort, 0 )))
    {
        hr = HRESULT_FROM_WIN32( GetLastError() );
        goto done;
    }

    channel->u.http.session = ses;
    channel->u.http.connect = con;

done:
    if (hr != S_OK)
    {
        WinHttpCloseHandle( con );
        WinHttpCloseHandle( ses );
    }
    heap_free( uc.lpszHostName );
    heap_free( uc.lpszUrlPath );
    heap_free( uc.lpszExtraInfo );
    return hr;
}

static HRESULT connect_channel_tcp( struct channel *channel )
{
    struct sockaddr_storage storage;
    struct sockaddr *addr = (struct sockaddr *)&storage;
    int addr_len;
    WS_URL_SCHEME_TYPE scheme;
    WCHAR *host;
    USHORT port;
    HRESULT hr;

    if (channel->u.tcp.socket != -1) return S_OK;

    if ((hr = parse_url( &channel->addr.url, &scheme, &host, &port )) != S_OK) return hr;
    if (scheme != WS_URL_NETTCP_SCHEME_TYPE)
    {
        heap_free( host );
        return WS_E_INVALID_ENDPOINT_URL;
    }

    winsock_init();

    hr = resolve_hostname( host, port, addr, &addr_len, 0 );
    heap_free( host );
    if (hr != S_OK) return hr;

    if ((channel->u.tcp.socket = socket( addr->sa_family, SOCK_STREAM, 0 )) == -1)
        return HRESULT_FROM_WIN32( WSAGetLastError() );

    if (connect( channel->u.tcp.socket, addr, addr_len ) < 0)
    {
        closesocket( channel->u.tcp.socket );
        channel->u.tcp.socket = -1;
        return HRESULT_FROM_WIN32( WSAGetLastError() );
    }

    return S_OK;
}

static HRESULT connect_channel_udp( struct channel *channel )
{
    struct sockaddr_storage storage;
    struct sockaddr *addr = (struct sockaddr *)&storage;
    int addr_len;
    WS_URL_SCHEME_TYPE scheme;
    WCHAR *host;
    USHORT port;
    HRESULT hr;

    if (channel->u.udp.socket != -1) return S_OK;

    if ((hr = parse_url( &channel->addr.url, &scheme, &host, &port )) != S_OK) return hr;
    if (scheme != WS_URL_SOAPUDP_SCHEME_TYPE)
    {
        heap_free( host );
        return WS_E_INVALID_ENDPOINT_URL;
    }

    winsock_init();

    hr = resolve_hostname( host, port, addr, &addr_len, 0 );
    heap_free( host );
    if (hr != S_OK) return hr;

    if ((channel->u.udp.socket = socket( addr->sa_family, SOCK_DGRAM, 0 )) == -1)
        return HRESULT_FROM_WIN32( WSAGetLastError() );

    if (connect( channel->u.udp.socket, addr, addr_len ) < 0)
    {
        closesocket( channel->u.udp.socket );
        channel->u.udp.socket = -1;
        return HRESULT_FROM_WIN32( WSAGetLastError() );
    }

    return S_OK;
}

static HRESULT connect_channel( struct channel *channel )
{
    switch (channel->binding)
    {
    case WS_HTTP_CHANNEL_BINDING:
        return connect_channel_http( channel );

    case WS_TCP_CHANNEL_BINDING:
        return connect_channel_tcp( channel );

    case WS_UDP_CHANNEL_BINDING:
        return connect_channel_udp( channel );

    default:
        ERR( "unhandled binding %u\n", channel->binding );
        return E_NOTIMPL;
    }
}

static HRESULT write_message( WS_MESSAGE *handle, WS_XML_WRITER *writer, const WS_ELEMENT_DESCRIPTION *desc,
                              WS_WRITE_OPTION option, const void *body, ULONG size )
{
    HRESULT hr;
    if ((hr = WsWriteEnvelopeStart( handle, writer, NULL, NULL, NULL )) != S_OK) return hr;
    if ((hr = WsWriteBody( handle, desc, option, body, size, NULL )) != S_OK) return hr;
    return WsWriteEnvelopeEnd( handle, NULL );
}

static HRESULT send_message_http( HINTERNET request, BYTE *data, ULONG len )
{
    if (!WinHttpSendRequest( request, NULL, 0, data, len, len, 0 ))
        return HRESULT_FROM_WIN32( GetLastError() );

    if (!WinHttpReceiveResponse( request, NULL ))
        return HRESULT_FROM_WIN32( GetLastError() );
    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 );
    if (count < 0) return HRESULT_FROM_WIN32( WSAGetLastError() );
    if (count != len) return WS_E_OTHER;
    return S_OK;
}

static HRESULT send_size( SOCKET socket, ULONG size )
{
    HRESULT hr;
    if (size < 0x80) return send_byte( socket, size );
    if ((hr = send_byte( socket, (size & 0x7f) | 0x80 )) != S_OK) return hr;
    if ((size >>= 7) < 0x80) return send_byte( socket, size );
    if ((hr = send_byte( socket, (size & 0x7f) | 0x80 )) != S_OK) return hr;
    if ((size >>= 7) < 0x80) return send_byte( socket, size );
    if ((hr = send_byte( socket, (size & 0x7f) | 0x80 )) != S_OK) return hr;
    if ((size >>= 7) < 0x80) return send_byte( socket, size );
    if ((hr = send_byte( socket, (size & 0x7f) | 0x80 )) != S_OK) return hr;
    if ((size >>= 7) < 0x08) return send_byte( socket, 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;
    if (size < 0x4000) return 2;
    if (size < 0x200000) return 3;
    if (size < 0x10000000) return 4;
    return 5;
}

static ULONG string_table_size( const WS_XML_DICTIONARY *dict )
{
    ULONG i, size = 0;
    for (i = 0; i < dict->stringCount; i++)
        size += size_length( dict->strings[i].length ) + dict->strings[i].length;
    return size;
}

static HRESULT send_string_table( SOCKET socket, const WS_XML_DICTIONARY *dict )
{
    ULONG i;
    HRESULT hr;
    for (i = 0; i < dict->stringCount; i++)
    {
        if ((hr = send_size( socket, dict->strings[i].length )) != S_OK) return hr;
        if ((hr = send_bytes( socket, dict->strings[i].bytes, dict->strings[i].length )) != S_OK) return hr;
    }
    return S_OK;
}

static HRESULT string_to_utf8( const WS_STRING *str, unsigned char **ret, int *len )
{
    *len = WideCharToMultiByte( CP_UTF8, 0, str->chars, str->length, NULL, 0, NULL, NULL );
    if (!(*ret = heap_alloc( *len ))) return E_OUTOFMEMORY;
    WideCharToMultiByte( CP_UTF8, 0, str->chars, str->length, (char *)*ret, *len, NULL, NULL );
    return S_OK;
}

enum session_mode
{
    SESSION_MODE_INVALID    = 0,
    SESSION_MODE_SINGLETON  = 1,
    SESSION_MODE_DUPLEX     = 2,
    SESSION_MODE_SIMPLEX    = 3,
};

static enum session_mode map_channel_type( struct channel *channel )
{
    switch (channel->type)
    {
    case WS_CHANNEL_TYPE_DUPLEX_SESSION: return SESSION_MODE_DUPLEX;
    default:
        FIXME( "unhandled channel type %08x\n", channel->type );
        return SESSION_MODE_INVALID;
    }
}

enum known_encoding
{
    KNOWN_ENCODING_SOAP11_UTF8           = 0x00,
    KNOWN_ENCODING_SOAP11_UTF16          = 0x01,
    KNOWN_ENCODING_SOAP11_UTF16LE        = 0x02,
    KNOWN_ENCODING_SOAP12_UTF8           = 0x03,
    KNOWN_ENCODING_SOAP12_UTF16          = 0x04,
    KNOWN_ENCODING_SOAP12_UTF16LE        = 0x05,
    KNOWN_ENCODING_SOAP12_MTOM           = 0x06,
    KNOWN_ENCODING_SOAP12_BINARY         = 0x07,
    KNOWN_ENCODING_SOAP12_BINARY_SESSION = 0x08,
};

static enum known_encoding map_channel_encoding( struct channel *channel )
{
    WS_ENVELOPE_VERSION version;

    prop_get( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_ENVELOPE_VERSION, &version, sizeof(version) );

    switch (version)
    {
    case WS_ENVELOPE_VERSION_SOAP_1_1:
        switch (channel->encoding)
        {
        case WS_ENCODING_XML_UTF8:      return KNOWN_ENCODING_SOAP11_UTF8;
        case WS_ENCODING_XML_UTF16LE:   return KNOWN_ENCODING_SOAP11_UTF16LE;
        default:
            FIXME( "unhandled version/encoding %u/%u\n", version, channel->encoding );
            return 0;
        }
    case WS_ENVELOPE_VERSION_SOAP_1_2:
        switch (channel->encoding)
        {
        case WS_ENCODING_XML_UTF8:              return KNOWN_ENCODING_SOAP12_UTF8;
        case WS_ENCODING_XML_UTF16LE:           return KNOWN_ENCODING_SOAP12_UTF16LE;
        case WS_ENCODING_XML_BINARY_1:          return KNOWN_ENCODING_SOAP12_BINARY;
        case WS_ENCODING_XML_BINARY_SESSION_1:  return KNOWN_ENCODING_SOAP12_BINARY_SESSION;
        default:
            FIXME( "unhandled version/encoding %u/%u\n", version, channel->encoding );
            return 0;
        }
    default:
        ERR( "unhandled version %u\n", version );
        return 0;
    }
}

#define FRAME_VERSION_MAJOR 1
#define FRAME_VERSION_MINOR 1

static HRESULT send_preamble( struct channel *channel )
{
    unsigned char *url;
    HRESULT hr;
    int len;

    if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_VERSION )) != S_OK) return hr;
    if ((hr = send_byte( channel->u.tcp.socket, FRAME_VERSION_MAJOR )) != S_OK) return hr;
    if ((hr = send_byte( channel->u.tcp.socket, FRAME_VERSION_MINOR )) != S_OK) return hr;

    if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_MODE )) != S_OK) return hr;
    if ((hr = send_byte( channel->u.tcp.socket, map_channel_type(channel) )) != S_OK) return hr;

    if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_VIA )) != S_OK) return hr;
    if ((hr = string_to_utf8( &channel->addr.url, &url, &len )) != S_OK) return hr;
    if ((hr = send_size( channel->u.tcp.socket, len )) != S_OK) goto done;
    if ((hr = send_bytes( channel->u.tcp.socket, url, len )) != S_OK) goto done;

    if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_KNOWN_ENCODING )) != S_OK) goto done;
    if ((hr = send_byte( channel->u.tcp.socket, map_channel_encoding(channel) )) != S_OK) goto done;
    hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_PREAMBLE_END );

done:
    heap_free( url );
    return hr;
}

static HRESULT receive_bytes( struct channel *channel, unsigned char *bytes, int len )
{
    int count = recv( channel->u.tcp.socket, (char *)bytes, len, 0 );
    if (count < 0) return HRESULT_FROM_WIN32( WSAGetLastError() );
    if (count != len) return WS_E_INVALID_FORMAT;
    return S_OK;
}

static HRESULT receive_preamble_ack( struct channel *channel )
{
    unsigned char byte;
    HRESULT hr;

    if ((hr = receive_bytes( channel, &byte, 1 )) != S_OK) return hr;
    if (byte != FRAME_RECORD_TYPE_PREAMBLE_ACK) return WS_E_INVALID_FORMAT;
    channel->session_state = SESSION_STATE_SETUP_COMPLETE;
    return S_OK;
}

static HRESULT send_sized_envelope( struct channel *channel, BYTE *data, ULONG len )
{
    ULONG table_size = string_table_size( &channel->dict_send.dict );
    HRESULT hr;

    if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_SIZED_ENVELOPE )) != S_OK) return hr;
    if ((hr = send_size( channel->u.tcp.socket, size_length(table_size) + table_size + len )) != S_OK) return hr;
    if ((hr = send_size( channel->u.tcp.socket, table_size )) != S_OK) return hr;
    if ((hr = send_string_table( channel->u.tcp.socket, &channel->dict_send.dict )) != S_OK) return hr;
    return send_bytes( channel->u.tcp.socket, data, len );
}

static HRESULT open_http_request( struct channel *channel, HINTERNET *req )
{
    static const WCHAR postW[] = {'P','O','S','T',0};
    if ((*req = WinHttpOpenRequest( channel->u.http.connect, postW, channel->u.http.path,
                                    NULL, NULL, NULL, channel->u.http.flags ))) return S_OK;
    return HRESULT_FROM_WIN32( GetLastError() );
}

static HRESULT send_message( struct channel *channel, WS_MESSAGE *msg )
{
    WS_XML_WRITER *writer;
    WS_BYTES buf;
    HRESULT hr;

    channel->msg = msg;
    if ((hr = connect_channel( channel )) != S_OK) return hr;

    WsGetMessageProperty( channel->msg, WS_MESSAGE_PROPERTY_BODY_WRITER, &writer, sizeof(writer), NULL );
    WsGetWriterProperty( writer, WS_XML_WRITER_PROPERTY_BYTES, &buf, sizeof(buf), NULL );

    switch (channel->binding)
    {
    case WS_HTTP_CHANNEL_BINDING:
        if (channel->u.http.request)
        {
            WinHttpCloseHandle( channel->u.http.request );
            channel->u.http.request = NULL;
        }
        if ((hr = open_http_request( channel, &channel->u.http.request )) != S_OK) return hr;
        if ((hr = message_insert_http_headers( msg, channel->u.http.request )) != S_OK) return hr;
        return send_message_http( channel->u.http.request, buf.bytes, buf.length );

    case WS_TCP_CHANNEL_BINDING:
        if (channel->encoding == WS_ENCODING_XML_BINARY_SESSION_1)
        {
            switch (channel->session_state)
            {
            case SESSION_STATE_UNINITIALIZED:
                if ((hr = send_preamble( channel )) != S_OK) return hr;
                if ((hr = receive_preamble_ack( channel )) != S_OK) return hr;
                /* fall through */

            case SESSION_STATE_SETUP_COMPLETE:
                return send_sized_envelope( channel, buf.bytes, buf.length );

            default:
                ERR( "unhandled session state %u\n", channel->session_state );
                return WS_E_OTHER;
            }
        }
        return send_bytes( channel->u.tcp.socket, buf.bytes, buf.length );

    case WS_UDP_CHANNEL_BINDING:
        return send_bytes( channel->u.udp.socket, buf.bytes, buf.length );

    default:
        ERR( "unhandled binding %u\n", channel->binding );
        return E_NOTIMPL;
    }
}

HRESULT channel_send_message( WS_CHANNEL *handle, WS_MESSAGE *msg )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    hr = send_message( channel, msg );

    LeaveCriticalSection( &channel->cs );
    return hr;
}

static HRESULT CALLBACK dict_cb( void *state, const WS_XML_STRING *str, BOOL *found, ULONG *id, WS_ERROR *error )
{
    struct dictionary *dict = state;
    HRESULT hr = S_OK;
    int index;

    if ((index = find_string( dict, str->bytes, str->length, id )) == -1 ||
        (hr = insert_string( dict, str->bytes, str->length, index, id )) == S_OK)
    {
        *found = TRUE;
        return S_OK;
    }
    *found = FALSE;
    return hr;
}

static HRESULT init_writer( struct channel *channel )
{
    WS_XML_WRITER_BUFFER_OUTPUT buf = {{WS_XML_WRITER_OUTPUT_TYPE_BUFFER}};
    WS_XML_WRITER_TEXT_ENCODING text = {{WS_XML_WRITER_ENCODING_TYPE_TEXT}};
    WS_XML_WRITER_BINARY_ENCODING bin = {{WS_XML_WRITER_ENCODING_TYPE_BINARY}};
    WS_XML_WRITER_ENCODING *encoding;
    HRESULT hr;

    if (!channel->writer && (hr = WsCreateWriter( NULL, 0, &channel->writer, NULL )) != S_OK) return hr;

    switch (channel->encoding)
    {
    case WS_ENCODING_XML_UTF8:
        text.charSet = WS_CHARSET_UTF8;
        encoding = &text.encoding;
        break;

    case WS_ENCODING_XML_BINARY_SESSION_1:
        if ((hr = writer_enable_lookup( channel->writer )) != S_OK) return hr;
        clear_dict( &channel->dict_send );
        bin.staticDictionary           = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
        bin.dynamicStringCallback      = dict_cb;
        bin.dynamicStringCallbackState = &channel->dict_send;
        encoding = &bin.encoding;
        break;

    case WS_ENCODING_XML_BINARY_1:
        encoding = &bin.encoding;
        break;

    default:
        FIXME( "unhandled encoding %u\n", channel->encoding );
        return WS_E_NOT_SUPPORTED;
    }

    return WsSetOutput( channel->writer, encoding, &buf.output, NULL, 0, NULL );
}

/**************************************************************************
 *          WsSendMessage		[webservices.@]
 */
HRESULT WINAPI WsSendMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_MESSAGE_DESCRIPTION *desc,
                              WS_WRITE_OPTION option, const void *body, ULONG size, const WS_ASYNC_CONTEXT *ctx,
                              WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    TRACE( "%p %p %p %08x %p %u %p %p\n", handle, msg, desc, option, body, size, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!channel || !msg || !desc) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    if ((hr = WsInitializeMessage( msg, WS_REQUEST_MESSAGE, NULL, NULL )) != S_OK) goto done;
    if ((hr = WsAddressMessage( msg, &channel->addr, NULL )) != S_OK) goto done;
    if ((hr = message_set_action( msg, desc->action )) != S_OK) goto done;

    if ((hr = init_writer( channel )) != S_OK) goto done;
    if ((hr = write_message( msg, channel->writer, desc->bodyElementDescription, option, body, size )) != S_OK)
        goto done;
    hr = send_message( channel, msg );

done:
    LeaveCriticalSection( &channel->cs );
    return hr;
}

/**************************************************************************
 *          WsSendReplyMessage		[webservices.@]
 */
HRESULT WINAPI WsSendReplyMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_MESSAGE_DESCRIPTION *desc,
                                   WS_WRITE_OPTION option, const void *body, ULONG size, WS_MESSAGE *request,
                                   const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    GUID req_id;
    HRESULT hr;

    TRACE( "%p %p %p %08x %p %u %p %p %p\n", handle, msg, desc, option, body, size, request, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!channel || !msg || !desc || !request) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    if ((hr = WsInitializeMessage( msg, WS_REPLY_MESSAGE, NULL, NULL )) != S_OK) goto done;
    if ((hr = WsAddressMessage( msg, &channel->addr, NULL )) != S_OK) goto done;
    if ((hr = message_set_action( msg, desc->action )) != S_OK) goto done;
    if ((hr = message_get_id( request, &req_id )) != S_OK) goto done;
    if ((hr = message_set_request_id( msg, &req_id )) != S_OK) goto done;

    if ((hr = init_writer( channel )) != S_OK) goto done;
    if ((hr = write_message( msg, channel->writer, desc->bodyElementDescription, option, body, size )) != S_OK)
        goto done;
    hr = send_message( channel, msg );

done:
    LeaveCriticalSection( &channel->cs );
    FIXME( "returning %08x\n", hr );
    return hr;
}

static HRESULT resize_read_buffer( struct channel *channel, ULONG size )
{
    if (!channel->read_buf)
    {
        if (!(channel->read_buf = heap_alloc( size ))) return E_OUTOFMEMORY;
        channel->read_buflen = size;
        return S_OK;
    }
    if (channel->read_buflen < size)
    {
        char *tmp;
        ULONG new_size = max( size, channel->read_buflen * 2 );
        if (!(tmp = heap_realloc( channel->read_buf, new_size ))) return E_OUTOFMEMORY;
        channel->read_buf = tmp;
        channel->read_buflen = new_size;
    }
    return S_OK;
}

static HRESULT init_reader( struct channel *channel )
{
    WS_XML_READER_BUFFER_INPUT buf = {{WS_XML_READER_INPUT_TYPE_BUFFER}};
    WS_XML_READER_TEXT_ENCODING text = {{WS_XML_READER_ENCODING_TYPE_TEXT}};
    WS_XML_READER_BINARY_ENCODING bin = {{WS_XML_READER_ENCODING_TYPE_BINARY}};
    WS_XML_READER_ENCODING *encoding;
    HRESULT hr;

    if (!channel->reader && (hr = WsCreateReader( NULL, 0, &channel->reader, NULL )) != S_OK) return hr;

    switch (channel->encoding)
    {
    case WS_ENCODING_XML_UTF8:
        text.charSet = WS_CHARSET_UTF8;
        encoding = &text.encoding;
        break;

    case WS_ENCODING_XML_BINARY_SESSION_1:
        bin.staticDictionary  = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
        bin.dynamicDictionary = &channel->dict_recv.dict;
        /* fall through */

    case WS_ENCODING_XML_BINARY_1:
        encoding = &bin.encoding;
        break;

    default:
        FIXME( "unhandled encoding %u\n", channel->encoding );
        return WS_E_NOT_SUPPORTED;
    }

    buf.encodedData     = channel->read_buf;
    buf.encodedDataSize = channel->read_size;
    return WsSetInput( channel->reader, encoding, &buf.input, NULL, 0, NULL );
}

#define INITIAL_READ_BUFFER_SIZE 4096
static HRESULT receive_message_http( struct channel *channel )
{
    DWORD len, bytes_read, offset = 0, size = INITIAL_READ_BUFFER_SIZE;
    ULONG max_len;
    HRESULT hr;

    prop_get( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE,
              &max_len, sizeof(max_len) );

    if ((hr = resize_read_buffer( channel, size )) != S_OK) return hr;
    channel->read_size = 0;
    for (;;)
    {
        if (!WinHttpQueryDataAvailable( channel->u.http.request, &len ))
        {
            return HRESULT_FROM_WIN32( GetLastError() );
        }
        if (!len) break;
        if (channel->read_size + len > max_len) return WS_E_QUOTA_EXCEEDED;
        if ((hr = resize_read_buffer( channel, channel->read_size + len )) != S_OK) return hr;

        if (!WinHttpReadData( channel->u.http.request, channel->read_buf + offset, len, &bytes_read ))
        {
            return HRESULT_FROM_WIN32( GetLastError() );
        }
        if (!bytes_read) break;
        channel->read_size += bytes_read;
        offset += bytes_read;
    }

    return init_reader( channel );
}

static HRESULT receive_message_unsized( struct channel *channel, SOCKET socket )
{
    int bytes_read;
    ULONG max_len;
    HRESULT hr;

    prop_get( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE,
              &max_len, sizeof(max_len) );

    if ((hr = resize_read_buffer( channel, max_len )) != S_OK) return hr;

    channel->read_size = 0;
    if ((bytes_read = recv( socket, channel->read_buf, max_len, 0 )) < 0)
    {
        return HRESULT_FROM_WIN32( WSAGetLastError() );
    }
    channel->read_size = bytes_read;
    return S_OK;
}

static HRESULT receive_message_sized( struct channel *channel, unsigned int size )
{
    unsigned int offset = 0, to_read = size;
    int bytes_read;
    HRESULT hr;

    if ((hr = resize_read_buffer( channel, size )) != S_OK) return hr;

    channel->read_size = 0;
    while (channel->read_size < size)
    {
        if ((bytes_read = recv( channel->u.tcp.socket, channel->read_buf + offset, to_read, 0 )) < 0)
        {
            return HRESULT_FROM_WIN32( WSAGetLastError() );
        }
        if (!bytes_read) break;
        channel->read_size += bytes_read;
        to_read -= bytes_read;
        offset += bytes_read;
    }
    if (channel->read_size != size) return WS_E_INVALID_FORMAT;
    return S_OK;
}

static HRESULT receive_size( struct channel *channel, unsigned int *size )
{
    unsigned char byte;
    HRESULT hr;

    if ((hr = receive_bytes( channel, &byte, 1 )) != S_OK) return hr;
    *size = byte & 0x7f;
    if (!(byte & 0x80)) return S_OK;

    if ((hr = receive_bytes( channel, &byte, 1 )) != S_OK) return hr;
    *size += (byte & 0x7f) << 7;
    if (!(byte & 0x80)) return S_OK;

    if ((hr = receive_bytes( channel, &byte, 1 )) != S_OK) return hr;
    *size += (byte & 0x7f) << 14;
    if (!(byte & 0x80)) return S_OK;

    if ((hr = receive_bytes( channel, &byte, 1 )) != S_OK) return hr;
    *size += (byte & 0x7f) << 21;
    if (!(byte & 0x80)) return S_OK;

    if ((hr = receive_bytes( channel, &byte, 1 )) != S_OK) return hr;
    if (byte & ~0x0f) return WS_E_INVALID_FORMAT;
    *size += byte << 28;
    return S_OK;
}

static WS_ENCODING map_known_encoding( enum known_encoding encoding )
{
    switch (encoding)
    {
    case KNOWN_ENCODING_SOAP11_UTF8:
    case KNOWN_ENCODING_SOAP12_UTF8:           return WS_ENCODING_XML_UTF8;
    case KNOWN_ENCODING_SOAP11_UTF16:
    case KNOWN_ENCODING_SOAP12_UTF16:          return WS_ENCODING_XML_UTF16BE;
    case KNOWN_ENCODING_SOAP11_UTF16LE:
    case KNOWN_ENCODING_SOAP12_UTF16LE:        return WS_ENCODING_XML_UTF16LE;
    case KNOWN_ENCODING_SOAP12_BINARY:         return WS_ENCODING_XML_BINARY_1;
    case KNOWN_ENCODING_SOAP12_BINARY_SESSION: return WS_ENCODING_XML_BINARY_SESSION_1;
    default:
        WARN( "unhandled encoding %u, assuming UTF8\n", encoding );
        return WS_ENCODING_XML_UTF8;
    }
}

static HRESULT receive_preamble( struct channel *channel )
{
    unsigned char type;
    HRESULT hr;

    for (;;)
    {
        if ((hr = receive_bytes( channel, &type, 1 )) != S_OK) return hr;
        if (type == FRAME_RECORD_TYPE_PREAMBLE_END) break;
        switch (type)
        {
        case FRAME_RECORD_TYPE_VERSION:
        {
            unsigned char major, minor;
            if ((hr = receive_bytes( channel, &major, 1 )) != S_OK) return hr;
            if ((hr = receive_bytes( channel, &minor, 1 )) != S_OK) return hr;
            TRACE( "major %u minor %u\n", major, major );
            break;
        }
        case FRAME_RECORD_TYPE_MODE:
        {
            unsigned char mode;
            if ((hr = receive_bytes( channel, &mode, 1 )) != S_OK) return hr;
            TRACE( "mode %u\n", mode );
            break;
        }
        case FRAME_RECORD_TYPE_VIA:
        {
            unsigned int size;
            unsigned char *url;

            if ((hr = receive_size( channel, &size )) != S_OK) return hr;
            if (!(url = heap_alloc( size ))) return E_OUTOFMEMORY;
            if ((hr = receive_bytes( channel, url, size )) != S_OK)
            {
                heap_free( url );
                return hr;
            }
            TRACE( "transport URL %s\n", debugstr_an((char *)url, size) );
            heap_free( url ); /* FIXME: verify */
            break;
        }
        case FRAME_RECORD_TYPE_KNOWN_ENCODING:
        {
            unsigned char encoding;
            if ((hr = receive_bytes( channel, &encoding, 1 )) != S_OK) return hr;
            TRACE( "encoding %u\n", encoding );
            channel->encoding = map_known_encoding( encoding );
            break;
        }
        default:
            WARN( "unhandled record type %u\n", type );
            return WS_E_INVALID_FORMAT;
        }
    }

    return S_OK;
}

static HRESULT receive_sized_envelope( struct channel *channel )
{
    unsigned char type;
    unsigned int size;
    HRESULT hr;

    if ((hr = receive_bytes( channel, &type, 1 )) != S_OK) return hr;
    if (type != FRAME_RECORD_TYPE_SIZED_ENVELOPE) return WS_E_INVALID_FORMAT;
    if ((hr = receive_size( channel, &size )) != S_OK) return hr;
    if ((hr = receive_message_sized( channel, size )) != S_OK) return hr;
    return S_OK;
}

static HRESULT read_size( const BYTE **ptr, ULONG len, ULONG *size )
{
    const BYTE *buf = *ptr;

    if (len < 1) return WS_E_INVALID_FORMAT;
    *size = buf[0] & 0x7f;
    if (!(buf[0] & 0x80))
    {
        *ptr += 1;
        return S_OK;
    }
    if (len < 2) return WS_E_INVALID_FORMAT;
    *size += (buf[1] & 0x7f) << 7;
    if (!(buf[1] & 0x80))
    {
        *ptr += 2;
        return S_OK;
    }
    if (len < 3) return WS_E_INVALID_FORMAT;
    *size += (buf[2] & 0x7f) << 14;
    if (!(buf[2] & 0x80))
    {
        *ptr += 3;
        return S_OK;
    }
    if (len < 4) return WS_E_INVALID_FORMAT;
    *size += (buf[3] & 0x7f) << 21;
    if (!(buf[3] & 0x80))
    {
        *ptr += 4;
        return S_OK;
    }
    if (len < 5 || (buf[4] & ~0x07)) return WS_E_INVALID_FORMAT;
    *size += buf[4] << 28;
    *ptr += 5;
    return S_OK;
}

static HRESULT build_dict( const BYTE *buf, ULONG buflen, struct dictionary *dict, ULONG *used )
{
    ULONG size, strings_size, strings_offset;
    const BYTE *ptr = buf;
    BYTE *bytes;
    int index;
    HRESULT hr;

    if ((hr = read_size( &ptr, buflen, &strings_size )) != S_OK) return hr;
    strings_offset = ptr - buf;
    if (buflen < strings_offset + strings_size) return WS_E_INVALID_FORMAT;
    *used = strings_offset + strings_size;
    if (!strings_size) return S_OK;

    UuidCreate( &dict->dict.guid );
    dict->dict.isConst = FALSE;

    buflen -= strings_offset;
    ptr = buf + strings_offset;
    while (ptr < buf + strings_size)
    {
        if ((hr = read_size( &ptr, buflen, &size )) != S_OK)
        {
            clear_dict( dict );
            return hr;
        }
        if (size > buflen)
        {
            clear_dict( dict );
            return WS_E_INVALID_FORMAT;
        }
        buflen -= size;
        if (!(bytes = heap_alloc( size )))
        {
            hr = E_OUTOFMEMORY;
            goto error;
        }
        memcpy( bytes, ptr, size );
        if ((index = find_string( dict, bytes, size, NULL )) == -1) /* duplicate */
        {
            heap_free( bytes );
            ptr += size;
            continue;
        }
        if ((hr = insert_string( dict, bytes, size, index, NULL )) != S_OK)
        {
            clear_dict( dict );
            return hr;
        }
        ptr += size;
    }
    return S_OK;

error:
    clear_dict( dict );
    return hr;
}

static HRESULT send_preamble_ack( struct channel *channel )
{
    HRESULT hr;
    if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_PREAMBLE_ACK )) != S_OK) return hr;
    channel->session_state = SESSION_STATE_SETUP_COMPLETE;
    return S_OK;
}

static HRESULT receive_message_session( struct channel *channel )
{
    HRESULT hr;

    if ((hr = receive_sized_envelope( channel )) != S_OK) return hr;
    if (channel->encoding == WS_ENCODING_XML_BINARY_SESSION_1)
    {
        ULONG size;
        if ((hr = build_dict( (const BYTE *)channel->read_buf, channel->read_size, &channel->dict_recv,
                              &size )) != S_OK) return hr;
        channel->read_size -= size;
        memmove( channel->read_buf, channel->read_buf + size, channel->read_size );
    }

    return init_reader( channel );
}

static HRESULT receive_message_sock( struct channel *channel, SOCKET socket )
{
    HRESULT hr;
    if ((hr = receive_message_unsized( channel, socket )) != S_OK) return hr;
    return init_reader( channel );
}

static HRESULT receive_message_bytes( struct channel *channel )
{
    HRESULT hr;
    if ((hr = connect_channel( channel )) != S_OK) return hr;

    switch (channel->binding)
    {
    case WS_HTTP_CHANNEL_BINDING:
        return receive_message_http( channel );

    case WS_TCP_CHANNEL_BINDING:
        if (channel->encoding == WS_ENCODING_XML_BINARY_SESSION_1)
        {
            switch (channel->session_state)
            {
            case SESSION_STATE_UNINITIALIZED:
                if ((hr = receive_preamble( channel )) != S_OK) return hr;
                if ((hr = send_preamble_ack( channel )) != S_OK) return hr;
                /* fall through */

            case SESSION_STATE_SETUP_COMPLETE:
                return receive_message_session( channel );

            default:
                ERR( "unhandled session state %u\n", channel->session_state );
                return WS_E_OTHER;
            }
        }
        return receive_message_sock( channel, channel->u.tcp.socket );

    case WS_UDP_CHANNEL_BINDING:
        return receive_message_sock( channel, channel->u.udp.socket );

    default:
        ERR( "unhandled binding %u\n", channel->binding );
        return E_NOTIMPL;
    }
}

HRESULT channel_receive_message( WS_CHANNEL *handle )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    hr = receive_message_bytes( channel );

    LeaveCriticalSection( &channel->cs );
    return hr;
}

HRESULT channel_get_reader( WS_CHANNEL *handle, WS_XML_READER **reader )
{
    struct channel *channel = (struct channel *)handle;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    *reader = channel->reader;

    LeaveCriticalSection( &channel->cs );
    return S_OK;
}

static HRESULT read_message( WS_MESSAGE *handle, WS_XML_READER *reader, const WS_ELEMENT_DESCRIPTION *desc,
                             WS_READ_OPTION option, WS_HEAP *heap, void *body, ULONG size )
{
    HRESULT hr;
    if ((hr = WsReadEnvelopeStart( handle, reader, NULL, NULL, NULL )) != S_OK) return hr;
    if ((hr = WsReadBody( handle, desc, option, heap, body, size, NULL )) != S_OK) return hr;
    return WsReadEnvelopeEnd( handle, NULL );
}

static HRESULT receive_message( struct channel *channel, WS_MESSAGE *msg, const WS_MESSAGE_DESCRIPTION **desc,
                                ULONG count, WS_RECEIVE_OPTION option, WS_READ_OPTION read_option, WS_HEAP *heap,
                                void *value, ULONG size, ULONG *index )
{
    HRESULT hr;
    ULONG i;

    if ((hr = receive_message_bytes( channel )) != S_OK) return hr;
    for (i = 0; i < count; i++)
    {
        const WS_ELEMENT_DESCRIPTION *body = desc[i]->bodyElementDescription;
        if ((hr = read_message( msg, channel->reader, body, read_option, heap, value, size )) == S_OK)
        {
            if (index) *index = i;
            break;
        }
        if ((hr = WsResetMessage( msg, NULL )) != S_OK) return hr;
        if ((hr = init_reader( channel )) != S_OK) return hr;
    }
    return (i == count) ? WS_E_INVALID_FORMAT : S_OK;
}

struct receive_message
{
    struct task                    task;
    struct channel                *channel;
    WS_MESSAGE                    *msg;
    const WS_MESSAGE_DESCRIPTION **desc;
    ULONG                          count;
    WS_RECEIVE_OPTION              option;
    WS_READ_OPTION                 read_option;
    WS_HEAP                       *heap;
    void                          *value;
    ULONG                          size;
    ULONG                         *index;
    const WS_ASYNC_CONTEXT        *ctx;
};

static void receive_message_proc( struct task *task )
{
    struct receive_message *r = (struct receive_message *)task;
    HRESULT hr;

    hr = receive_message( r->channel, r->msg, r->desc, r->count, r->option, r->read_option, r->heap, r->value,
                          r->size, r->index );

    TRACE( "calling %p(%08x)\n", r->ctx->callback, hr );
    r->ctx->callback( hr, WS_LONG_CALLBACK, r->ctx->callbackState );
    TRACE( "%p returned\n", r->ctx->callback );
}

static HRESULT queue_receive_message( struct channel *channel, WS_MESSAGE *msg, const WS_MESSAGE_DESCRIPTION **desc,
                                      ULONG count, WS_RECEIVE_OPTION option, WS_READ_OPTION read_option,
                                      WS_HEAP *heap, void *value, ULONG size, ULONG *index,
                                      const WS_ASYNC_CONTEXT *ctx )
{
    struct receive_message *r;

    if (!(r = heap_alloc( sizeof(*r) ))) return E_OUTOFMEMORY;
    r->task.proc   = receive_message_proc;
    r->channel     = channel;
    r->msg         = msg;
    r->desc        = desc;
    r->count       = count;
    r->option      = option;
    r->read_option = read_option;
    r->heap        = heap;
    r->value       = value;
    r->size        = size;
    r->index       = index;
    r->ctx         = ctx;
    return queue_task( &channel->recv_q, &r->task );
}

/**************************************************************************
 *          WsReceiveMessage		[webservices.@]
 */
HRESULT WINAPI WsReceiveMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_MESSAGE_DESCRIPTION **desc,
                                 ULONG count, WS_RECEIVE_OPTION option, WS_READ_OPTION read_option, WS_HEAP *heap,
                                 void *value, ULONG size, ULONG *index, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    TRACE( "%p %p %p %u %08x %08x %p %p %u %p %p %p\n", handle, msg, desc, count, option, read_option, heap,
           value, size, index, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!channel || !msg || !desc || !count) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    if (ctx)
        hr = queue_receive_message( channel, msg, desc, count, option, read_option, heap, value, size, index, ctx );
    else
        hr = receive_message( channel, msg, desc, count, option, read_option, heap, value, size, index );

    LeaveCriticalSection( &channel->cs );
    return hr;
}

/**************************************************************************
 *          WsReadMessageStart		[webservices.@]
 */
HRESULT WINAPI WsReadMessageStart( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_ASYNC_CONTEXT *ctx,
                                   WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    TRACE( "%p %p %p %p\n", handle, msg, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!channel || !msg) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    if ((hr = receive_message_bytes( channel )) == S_OK)
    {
        hr = WsReadEnvelopeStart( msg, channel->reader, NULL, NULL, NULL );
    }

    LeaveCriticalSection( &channel->cs );
    return hr;
}

/**************************************************************************
 *          WsReadMessageEnd		[webservices.@]
 */
HRESULT WINAPI WsReadMessageEnd( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_ASYNC_CONTEXT *ctx,
                                 WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    TRACE( "%p %p %p %p\n", handle, msg, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!channel || !msg) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    hr = WsReadEnvelopeEnd( msg, NULL );

    LeaveCriticalSection( &channel->cs );
    return hr;
}

/**************************************************************************
 *          WsWriteMessageStart		[webservices.@]
 */
HRESULT WINAPI WsWriteMessageStart( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_ASYNC_CONTEXT *ctx,
                                    WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    TRACE( "%p %p %p %p\n", handle, msg, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!channel || !msg) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    if ((hr = init_writer( channel )) != S_OK) goto done;
    if ((hr = WsAddressMessage( msg, &channel->addr, NULL )) != S_OK) goto done;
    hr = WsWriteEnvelopeStart( msg, channel->writer, NULL, NULL, NULL );

done:
    LeaveCriticalSection( &channel->cs );
    return hr;
}

/**************************************************************************
 *          WsWriteMessageEnd		[webservices.@]
 */
HRESULT WINAPI WsWriteMessageEnd( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_ASYNC_CONTEXT *ctx,
                                  WS_ERROR *error )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    TRACE( "%p %p %p %p\n", handle, msg, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!channel || !msg) return E_INVALIDARG;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    if ((hr = WsWriteEnvelopeEnd( msg, NULL )) == S_OK) hr = send_message( channel, msg );

    LeaveCriticalSection( &channel->cs );
    return hr;
}

static HRESULT sock_accept( SOCKET socket, HANDLE wait, HANDLE cancel, SOCKET *ret )
{
    HANDLE handles[] = { wait, cancel };
    ULONG nonblocking = 0;
    HRESULT hr = S_OK;

    if (WSAEventSelect( socket, handles[0], FD_ACCEPT )) return HRESULT_FROM_WIN32( WSAGetLastError() );

    switch (WSAWaitForMultipleEvents( 2, handles, FALSE, WSA_INFINITE, FALSE ))
    {
    case 0:
        if ((*ret = accept( socket, NULL, NULL )) != -1)
        {
            WSAEventSelect( *ret, NULL, 0 );
            ioctlsocket( *ret, FIONBIO, &nonblocking );
            break;
        }
        hr = HRESULT_FROM_WIN32( WSAGetLastError() );
        break;

    case 1:
        hr = WS_E_OPERATION_ABORTED;
        break;

    default:
        hr = HRESULT_FROM_WIN32( WSAGetLastError() );
        break;
    }

    return hr;
}

HRESULT channel_accept_tcp( SOCKET socket, HANDLE wait, HANDLE cancel, WS_CHANNEL *handle )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    hr = sock_accept( socket, wait, cancel, &channel->u.tcp.socket );

    LeaveCriticalSection( &channel->cs );
    return hr;
}

static HRESULT sock_wait( SOCKET socket, HANDLE wait, HANDLE cancel )
{
    HANDLE handles[] = { wait, cancel };
    ULONG nonblocking = 0;
    HRESULT hr;

    if (WSAEventSelect( socket, handles[0], FD_READ )) return HRESULT_FROM_WIN32( WSAGetLastError() );

    switch (WSAWaitForMultipleEvents( 2, handles, FALSE, WSA_INFINITE, FALSE ))
    {
    case 0:
        hr = S_OK;
        break;

    case 1:
        hr = WS_E_OPERATION_ABORTED;
        break;

    default:
        hr = HRESULT_FROM_WIN32( WSAGetLastError() );
        break;
    }

    WSAEventSelect( socket, NULL, 0 );
    ioctlsocket( socket, FIONBIO, &nonblocking );
    return hr;
}

HRESULT channel_accept_udp( SOCKET socket, HANDLE wait, HANDLE cancel, WS_CHANNEL *handle )
{
    struct channel *channel = (struct channel *)handle;
    HRESULT hr;

    EnterCriticalSection( &channel->cs );

    if (channel->magic != CHANNEL_MAGIC)
    {
        LeaveCriticalSection( &channel->cs );
        return E_INVALIDARG;
    }

    if ((hr = sock_wait( socket, wait, cancel )) == S_OK) channel->u.udp.socket = socket;

    LeaveCriticalSection( &channel->cs );
    return hr;
}
