forked from Mirrors/wine-wine
webservices: Implement WsRequestReply.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>oldstable
parent
57db798965
commit
5a58080a66
|
@ -2007,6 +2007,121 @@ HRESULT WINAPI WsReceiveMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_M
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT request_reply( struct channel *channel, WS_MESSAGE *request,
|
||||||
|
const WS_MESSAGE_DESCRIPTION *request_desc, WS_WRITE_OPTION write_option,
|
||||||
|
const void *request_body, ULONG request_size, WS_MESSAGE *reply,
|
||||||
|
const WS_MESSAGE_DESCRIPTION *reply_desc, WS_READ_OPTION read_option,
|
||||||
|
WS_HEAP *heap, void *value, ULONG size )
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
WsInitializeMessage( request, WS_REQUEST_MESSAGE, NULL, NULL );
|
||||||
|
if ((hr = WsAddressMessage( request, &channel->addr, NULL )) != S_OK) return hr;
|
||||||
|
if ((hr = message_set_action( request, request_desc->action )) != S_OK) return hr;
|
||||||
|
|
||||||
|
if ((hr = init_writer( channel )) != S_OK) return hr;
|
||||||
|
if ((hr = write_message( channel, request, request_desc->bodyElementDescription, write_option, request_body,
|
||||||
|
request_size )) != S_OK) return hr;
|
||||||
|
if ((hr = send_message( channel, request )) != S_OK) return hr;
|
||||||
|
|
||||||
|
return receive_message( channel, reply, &reply_desc, 1, WS_RECEIVE_OPTIONAL_MESSAGE, read_option, heap,
|
||||||
|
value, size, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
struct request_reply
|
||||||
|
{
|
||||||
|
struct task task;
|
||||||
|
struct channel *channel;
|
||||||
|
WS_MESSAGE *request;
|
||||||
|
const WS_MESSAGE_DESCRIPTION *request_desc;
|
||||||
|
WS_WRITE_OPTION write_option;
|
||||||
|
const void *request_body;
|
||||||
|
ULONG request_size;
|
||||||
|
WS_MESSAGE *reply;
|
||||||
|
const WS_MESSAGE_DESCRIPTION *reply_desc;
|
||||||
|
WS_READ_OPTION read_option;
|
||||||
|
WS_HEAP *heap;
|
||||||
|
void *value;
|
||||||
|
ULONG size;
|
||||||
|
WS_ASYNC_CONTEXT ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void request_reply_proc( struct task *task )
|
||||||
|
{
|
||||||
|
struct request_reply *r = (struct request_reply *)task;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = request_reply( r->channel, r->request, r->request_desc, r->write_option, r->request_body, r->request_size,
|
||||||
|
r->reply, r->reply_desc, r->read_option, r->heap, r->value, r->size );
|
||||||
|
|
||||||
|
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_request_reply( struct channel *channel, WS_MESSAGE *request,
|
||||||
|
const WS_MESSAGE_DESCRIPTION *request_desc, WS_WRITE_OPTION write_option,
|
||||||
|
const void *request_body, ULONG request_size, WS_MESSAGE *reply,
|
||||||
|
const WS_MESSAGE_DESCRIPTION *reply_desc, WS_READ_OPTION read_option,
|
||||||
|
WS_HEAP *heap, void *value, ULONG size, const WS_ASYNC_CONTEXT *ctx )
|
||||||
|
{
|
||||||
|
struct request_reply *r;
|
||||||
|
|
||||||
|
if (!(r = heap_alloc( sizeof(*r) ))) return E_OUTOFMEMORY;
|
||||||
|
r->task.proc = request_reply_proc;
|
||||||
|
r->channel = channel;
|
||||||
|
r->request = request;
|
||||||
|
r->request_desc = request_desc;
|
||||||
|
r->write_option = write_option;
|
||||||
|
r->request_body = request_body;
|
||||||
|
r->request_size = request_size;
|
||||||
|
r->reply = reply;
|
||||||
|
r->reply_desc = reply_desc;
|
||||||
|
r->read_option = read_option;
|
||||||
|
r->heap = heap;
|
||||||
|
r->value = value;
|
||||||
|
r->size = size;
|
||||||
|
r->ctx = *ctx;
|
||||||
|
return queue_task( &channel->recv_q, &r->task );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* WsRequestReply [webservices.@]
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI WsRequestReply( WS_CHANNEL *handle, WS_MESSAGE *request, const WS_MESSAGE_DESCRIPTION *request_desc,
|
||||||
|
WS_WRITE_OPTION write_option, const void *request_body, ULONG request_size,
|
||||||
|
WS_MESSAGE *reply, const WS_MESSAGE_DESCRIPTION *reply_desc, WS_READ_OPTION read_option,
|
||||||
|
WS_HEAP *heap, void *value, 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 %08x %p %p %u %p %p\n", handle, request, request_desc, write_option,
|
||||||
|
request_body, request_size, reply, reply_desc, read_option, heap, value, size, ctx, error );
|
||||||
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
if (ctx) FIXME( "ignoring ctx parameter\n" );
|
||||||
|
|
||||||
|
if (!channel || !request || !reply) return E_INVALIDARG;
|
||||||
|
|
||||||
|
EnterCriticalSection( &channel->cs );
|
||||||
|
|
||||||
|
if (channel->magic != CHANNEL_MAGIC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &channel->cs );
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx)
|
||||||
|
hr = queue_request_reply( channel, request, request_desc, write_option, request_body, request_size, reply,
|
||||||
|
reply_desc, read_option, heap, value, size, ctx );
|
||||||
|
else
|
||||||
|
hr = request_reply( channel, request, request_desc, write_option, request_body, request_size, reply,
|
||||||
|
reply_desc, read_option, heap, value, size );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &channel->cs );
|
||||||
|
TRACE( "returning %08x\n", hr );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* WsReadMessageStart [webservices.@]
|
* WsReadMessageStart [webservices.@]
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -433,16 +433,21 @@ static void test_WsResetListener(void)
|
||||||
WsFreeListener( listener );
|
WsFreeListener( listener );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const WCHAR fmt_soap_udp[] =
|
||||||
|
{'s','o','a','p','.','u','d','p',':','/','/','l','o','c','a','l','h','o','s','t',':','%','u',0};
|
||||||
|
static const WCHAR fmt_net_tcp[] =
|
||||||
|
{'n','e','t','.','t','c','p',':','/','/','l','o','c','a','l','h','o','s','t',':','%','u',0};
|
||||||
|
|
||||||
struct listener_info
|
struct listener_info
|
||||||
{
|
{
|
||||||
int port;
|
int port;
|
||||||
HANDLE wait;
|
HANDLE wait;
|
||||||
WS_CHANNEL_BINDING binding;
|
WS_CHANNEL_BINDING binding;
|
||||||
WS_CHANNEL_TYPE type;
|
WS_CHANNEL_TYPE type;
|
||||||
void (*test_func)( WS_CHANNEL * );
|
void (*server_func)( WS_CHANNEL * );
|
||||||
};
|
};
|
||||||
|
|
||||||
static void client_message_read_write( WS_CHANNEL *channel )
|
static void server_message_read_write( WS_CHANNEL *channel )
|
||||||
{
|
{
|
||||||
WS_MESSAGE *msg;
|
WS_MESSAGE *msg;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -476,10 +481,8 @@ static void client_message_read_write( WS_CHANNEL *channel )
|
||||||
WsFreeMessage( msg );
|
WsFreeMessage( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_message_read_write( const struct listener_info *info )
|
static void client_message_read_write( const struct listener_info *info )
|
||||||
{
|
{
|
||||||
static const WCHAR fmt[] =
|
|
||||||
{'s','o','a','p','.','u','d','p',':','/','/','l','o','c','a','l','h','o','s','t',':','%','u',0};
|
|
||||||
WS_ENDPOINT_ADDRESS addr;
|
WS_ENDPOINT_ADDRESS addr;
|
||||||
WCHAR buf[64];
|
WCHAR buf[64];
|
||||||
WS_CHANNEL *channel;
|
WS_CHANNEL *channel;
|
||||||
|
@ -491,7 +494,7 @@ static void test_message_read_write( const struct listener_info *info )
|
||||||
ok( hr == S_OK, "got %08x\n", hr );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
memset( &addr, 0, sizeof(addr) );
|
memset( &addr, 0, sizeof(addr) );
|
||||||
addr.url.length = wsprintfW( buf, fmt, info->port );
|
addr.url.length = wsprintfW( buf, fmt_soap_udp, info->port );
|
||||||
addr.url.chars = buf;
|
addr.url.chars = buf;
|
||||||
hr = WsOpenChannel( channel, &addr, NULL, NULL );
|
hr = WsOpenChannel( channel, &addr, NULL, NULL );
|
||||||
ok( hr == S_OK, "got %08x\n", hr );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
@ -545,7 +548,7 @@ struct async_test
|
||||||
HANDLE wait;
|
HANDLE wait;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void CALLBACK callback_duplex_session( HRESULT hr, WS_CALLBACK_MODEL model, void *state )
|
static void CALLBACK async_callback( HRESULT hr, WS_CALLBACK_MODEL model, void *state )
|
||||||
{
|
{
|
||||||
struct async_test *test = state;
|
struct async_test *test = state;
|
||||||
|
|
||||||
|
@ -555,7 +558,7 @@ static void CALLBACK callback_duplex_session( HRESULT hr, WS_CALLBACK_MODEL mode
|
||||||
SetEvent( test->wait );
|
SetEvent( test->wait );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void client_duplex_session( WS_CHANNEL *channel )
|
static void server_duplex_session( WS_CHANNEL *channel )
|
||||||
{
|
{
|
||||||
WS_XML_STRING action = {6, (BYTE *)"action"}, localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"};
|
WS_XML_STRING action = {6, (BYTE *)"action"}, localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"};
|
||||||
WS_ELEMENT_DESCRIPTION desc_body;
|
WS_ELEMENT_DESCRIPTION desc_body;
|
||||||
|
@ -580,7 +583,7 @@ static void client_duplex_session( WS_CHANNEL *channel )
|
||||||
|
|
||||||
test.call_count = 0;
|
test.call_count = 0;
|
||||||
test.wait = CreateEventW( NULL, FALSE, FALSE, NULL );
|
test.wait = CreateEventW( NULL, FALSE, FALSE, NULL );
|
||||||
ctx.callback = callback_duplex_session;
|
ctx.callback = async_callback;
|
||||||
ctx.callbackState = &test;
|
ctx.callbackState = &test;
|
||||||
|
|
||||||
hr = WsReceiveMessage( channel, msg, desc, 1, WS_RECEIVE_OPTIONAL_MESSAGE, WS_READ_REQUIRED_VALUE,
|
hr = WsReceiveMessage( channel, msg, desc, 1, WS_RECEIVE_OPTIONAL_MESSAGE, WS_READ_REQUIRED_VALUE,
|
||||||
|
@ -612,10 +615,8 @@ static void client_duplex_session( WS_CHANNEL *channel )
|
||||||
WsFreeMessage( msg2 );
|
WsFreeMessage( msg2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_duplex_session( const struct listener_info *info )
|
static void client_duplex_session( const struct listener_info *info )
|
||||||
{
|
{
|
||||||
static const WCHAR fmt[] =
|
|
||||||
{'n','e','t','.','t','c','p',':','/','/','l','o','c','a','l','h','o','s','t',':','%','u',0};
|
|
||||||
WS_XML_STRING action = {6, (BYTE *)"action"}, localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"};
|
WS_XML_STRING action = {6, (BYTE *)"action"}, localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"};
|
||||||
WS_ELEMENT_DESCRIPTION desc_body;
|
WS_ELEMENT_DESCRIPTION desc_body;
|
||||||
WS_MESSAGE_DESCRIPTION desc;
|
WS_MESSAGE_DESCRIPTION desc;
|
||||||
|
@ -634,7 +635,7 @@ static void test_duplex_session( const struct listener_info *info )
|
||||||
ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
|
ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
|
||||||
|
|
||||||
memset( &addr, 0, sizeof(addr) );
|
memset( &addr, 0, sizeof(addr) );
|
||||||
addr.url.length = wsprintfW( buf, fmt, info->port );
|
addr.url.length = wsprintfW( buf, fmt_net_tcp, info->port );
|
||||||
addr.url.chars = buf;
|
addr.url.chars = buf;
|
||||||
hr = WsOpenChannel( channel, &addr, NULL, NULL );
|
hr = WsOpenChannel( channel, &addr, NULL, NULL );
|
||||||
ok( hr == S_OK, "got %08x\n", hr );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
@ -675,7 +676,7 @@ static void test_duplex_session( const struct listener_info *info )
|
||||||
WsFreeChannel( channel );
|
WsFreeChannel( channel );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void client_accept_channel( WS_CHANNEL *channel )
|
static void server_accept_channel( WS_CHANNEL *channel )
|
||||||
{
|
{
|
||||||
WS_XML_STRING localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"}, action = {6, (BYTE *)"action"};
|
WS_XML_STRING localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"}, action = {6, (BYTE *)"action"};
|
||||||
WS_ELEMENT_DESCRIPTION body;
|
WS_ELEMENT_DESCRIPTION body;
|
||||||
|
@ -704,13 +705,9 @@ static void client_accept_channel( WS_CHANNEL *channel )
|
||||||
WsFreeMessage( msg );
|
WsFreeMessage( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_WsAcceptChannel( const struct listener_info *info )
|
static void client_accept_channel( const struct listener_info *info )
|
||||||
{
|
{
|
||||||
static const WCHAR fmt_tcp[] =
|
const WCHAR *fmt = (info->binding == WS_TCP_CHANNEL_BINDING) ? fmt_net_tcp : fmt_soap_udp;
|
||||||
{'n','e','t','.','t','c','p',':','/','/','l','o','c','a','l','h','o','s','t',':','%','u',0};
|
|
||||||
static const WCHAR fmt_udp[] =
|
|
||||||
{'s','o','a','p','.','u','d','p',':','/','/','l','o','c','a','l','h','o','s','t',':','%','u',0};
|
|
||||||
const WCHAR *fmt = (info->binding == WS_TCP_CHANNEL_BINDING) ? fmt_tcp : fmt_udp;
|
|
||||||
WS_XML_STRING localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"}, action = {6, (BYTE *)"action"};
|
WS_XML_STRING localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"}, action = {6, (BYTE *)"action"};
|
||||||
WCHAR buf[64];
|
WCHAR buf[64];
|
||||||
WS_LISTENER *listener;
|
WS_LISTENER *listener;
|
||||||
|
@ -773,14 +770,104 @@ static void test_WsAcceptChannel( const struct listener_info *info )
|
||||||
WsFreeChannel( channel );
|
WsFreeChannel( channel );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void server_request_reply( WS_CHANNEL *channel )
|
||||||
|
{
|
||||||
|
WS_XML_STRING localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"};
|
||||||
|
WS_XML_STRING req_action = {7, (BYTE *)"request"}, reply_action= {5, (BYTE *)"reply"};
|
||||||
|
WS_ELEMENT_DESCRIPTION body;
|
||||||
|
WS_MESSAGE_DESCRIPTION in_desc, out_desc;
|
||||||
|
const WS_MESSAGE_DESCRIPTION *desc[1];
|
||||||
|
WS_MESSAGE *msg;
|
||||||
|
INT32 val = 0;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
body.elementLocalName = &localname;
|
||||||
|
body.elementNs = &ns;
|
||||||
|
body.type = WS_INT32_TYPE;
|
||||||
|
body.typeDescription = NULL;
|
||||||
|
|
||||||
|
in_desc.action = &req_action;
|
||||||
|
in_desc.bodyElementDescription = &body;
|
||||||
|
desc[0] = &in_desc;
|
||||||
|
|
||||||
|
hr = WsReceiveMessage( channel, msg, desc, 1, WS_RECEIVE_REQUIRED_MESSAGE, WS_READ_REQUIRED_VALUE,
|
||||||
|
NULL, &val, sizeof(val), NULL, NULL, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
ok( val == -1, "got %d\n", val );
|
||||||
|
WsFreeMessage( msg );
|
||||||
|
|
||||||
|
hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
out_desc.action = &reply_action;
|
||||||
|
out_desc.bodyElementDescription = &body;
|
||||||
|
|
||||||
|
hr = WsSendMessage( channel, msg, &out_desc, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
WsFreeMessage( msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_request_reply( const struct listener_info *info )
|
||||||
|
{
|
||||||
|
WS_XML_STRING localname = {9, (BYTE *)"localname"}, ns = {2, (BYTE *)"ns"};
|
||||||
|
WS_XML_STRING req_action = {7, (BYTE *)"request"}, reply_action= {5, (BYTE *)"reply"};
|
||||||
|
WCHAR buf[64];
|
||||||
|
WS_CHANNEL *channel;
|
||||||
|
WS_MESSAGE *req, *reply;
|
||||||
|
WS_ENDPOINT_ADDRESS addr;
|
||||||
|
WS_ELEMENT_DESCRIPTION body;
|
||||||
|
WS_MESSAGE_DESCRIPTION req_desc, reply_desc;
|
||||||
|
INT32 val_in = -1, val_out = 0;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = WsCreateChannel( info->type, info->binding, NULL, 0, NULL, &channel, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
memset( &addr, 0, sizeof(addr) );
|
||||||
|
addr.url.length = wsprintfW( buf, fmt_net_tcp, info->port );
|
||||||
|
addr.url.chars = buf;
|
||||||
|
hr = WsOpenChannel( channel, &addr, NULL, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
hr = WsCreateMessageForChannel( channel, NULL, 0, &req, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
hr = WsCreateMessageForChannel( channel, NULL, 0, &reply, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
hr = WsInitializeMessage( req, WS_BLANK_MESSAGE, NULL, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
body.elementLocalName = &localname;
|
||||||
|
body.elementNs = &ns;
|
||||||
|
body.type = WS_INT32_TYPE;
|
||||||
|
body.typeDescription = NULL;
|
||||||
|
|
||||||
|
req_desc.action = &req_action;
|
||||||
|
req_desc.bodyElementDescription = &body;
|
||||||
|
|
||||||
|
reply_desc.action = &reply_action;
|
||||||
|
reply_desc.bodyElementDescription = &body;
|
||||||
|
|
||||||
|
hr = WsRequestReply( channel, req, &req_desc, WS_WRITE_REQUIRED_VALUE, &val_in, sizeof(val_in), reply,
|
||||||
|
&reply_desc, WS_READ_REQUIRED_VALUE, NULL, &val_out, sizeof(val_out), NULL, NULL );
|
||||||
|
ok( val_out == -1, "got %d\n", val_out );
|
||||||
|
|
||||||
|
hr = WsCloseChannel( channel, NULL, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
WsFreeMessage( req );
|
||||||
|
WsFreeMessage( reply );
|
||||||
|
WsFreeChannel( channel );
|
||||||
|
}
|
||||||
|
|
||||||
static DWORD CALLBACK listener_proc( void *arg )
|
static DWORD CALLBACK listener_proc( void *arg )
|
||||||
{
|
{
|
||||||
static const WCHAR fmt_tcp[] =
|
|
||||||
{'n','e','t','.','t','c','p',':','/','/','l','o','c','a','l','h','o','s','t',':','%','u',0};
|
|
||||||
static const WCHAR fmt_udp[] =
|
|
||||||
{'s','o','a','p','.','u','d','p',':','/','/','l','o','c','a','l','h','o','s','t',':','%','u',0};
|
|
||||||
struct listener_info *info = arg;
|
struct listener_info *info = arg;
|
||||||
const WCHAR *fmt = (info->binding == WS_TCP_CHANNEL_BINDING) ? fmt_tcp : fmt_udp;
|
const WCHAR *fmt = (info->binding == WS_TCP_CHANNEL_BINDING) ? fmt_net_tcp : fmt_soap_udp;
|
||||||
WS_LISTENER *listener;
|
WS_LISTENER *listener;
|
||||||
WS_CHANNEL *channel;
|
WS_CHANNEL *channel;
|
||||||
WCHAR buf[64];
|
WCHAR buf[64];
|
||||||
|
@ -803,7 +890,7 @@ static DWORD CALLBACK listener_proc( void *arg )
|
||||||
hr = WsAcceptChannel( listener, channel, NULL, NULL );
|
hr = WsAcceptChannel( listener, channel, NULL, NULL );
|
||||||
ok( hr == S_OK, "got %08x\n", hr );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
info->test_func( channel );
|
info->server_func( channel );
|
||||||
|
|
||||||
SetEvent( info->wait );
|
SetEvent( info->wait );
|
||||||
|
|
||||||
|
@ -956,6 +1043,22 @@ START_TEST(channel)
|
||||||
struct listener_info info;
|
struct listener_info info;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
unsigned int i;
|
||||||
|
static const struct test
|
||||||
|
{
|
||||||
|
WS_CHANNEL_BINDING binding;
|
||||||
|
WS_CHANNEL_TYPE type;
|
||||||
|
void (*server_func)( WS_CHANNEL * );
|
||||||
|
void (*client_func)( const struct listener_info * );
|
||||||
|
}
|
||||||
|
tests[] =
|
||||||
|
{
|
||||||
|
{ WS_UDP_CHANNEL_BINDING, WS_CHANNEL_TYPE_DUPLEX, server_message_read_write, client_message_read_write },
|
||||||
|
{ WS_TCP_CHANNEL_BINDING, WS_CHANNEL_TYPE_DUPLEX_SESSION, server_duplex_session, client_duplex_session },
|
||||||
|
{ WS_UDP_CHANNEL_BINDING, WS_CHANNEL_TYPE_DUPLEX, server_accept_channel, client_accept_channel },
|
||||||
|
{ WS_TCP_CHANNEL_BINDING, WS_CHANNEL_TYPE_DUPLEX_SESSION, server_accept_channel, client_accept_channel },
|
||||||
|
{ WS_TCP_CHANNEL_BINDING, WS_CHANNEL_TYPE_DUPLEX_SESSION, server_request_reply, client_request_reply },
|
||||||
|
};
|
||||||
|
|
||||||
if (firewall_enabled)
|
if (firewall_enabled)
|
||||||
{
|
{
|
||||||
|
@ -979,42 +1082,20 @@ START_TEST(channel)
|
||||||
test_WsCreateChannelForListener();
|
test_WsCreateChannelForListener();
|
||||||
test_WsResetListener();
|
test_WsResetListener();
|
||||||
|
|
||||||
info.port = 7533;
|
info.port = 7533;
|
||||||
info.wait = CreateEventW( NULL, 0, 0, NULL );
|
info.wait = CreateEventW( NULL, 0, 0, NULL );
|
||||||
info.type = WS_CHANNEL_TYPE_DUPLEX;
|
|
||||||
info.binding = WS_UDP_CHANNEL_BINDING;
|
|
||||||
info.test_func = client_message_read_write;
|
|
||||||
|
|
||||||
thread = start_listener( &info );
|
for (i = 0; i < ARRAY_SIZE(tests); i++)
|
||||||
test_message_read_write( &info );
|
{
|
||||||
WaitForSingleObject( thread, 3000 );
|
info.binding = tests[i].binding;
|
||||||
CloseHandle(thread);
|
info.type = tests[i].type;
|
||||||
|
info.server_func = tests[i].server_func;
|
||||||
|
|
||||||
info.type = WS_CHANNEL_TYPE_DUPLEX_SESSION;
|
thread = start_listener( &info );
|
||||||
info.binding = WS_TCP_CHANNEL_BINDING;
|
tests[i].client_func( &info );
|
||||||
info.test_func = client_duplex_session;
|
WaitForSingleObject( thread, 3000 );
|
||||||
|
CloseHandle( thread );
|
||||||
thread = start_listener( &info );
|
}
|
||||||
test_duplex_session( &info );
|
|
||||||
WaitForSingleObject( thread, 3000 );
|
|
||||||
CloseHandle(thread);
|
|
||||||
|
|
||||||
info.type = WS_CHANNEL_TYPE_DUPLEX;
|
|
||||||
info.binding = WS_UDP_CHANNEL_BINDING;
|
|
||||||
info.test_func = client_accept_channel;
|
|
||||||
|
|
||||||
thread = start_listener( &info );
|
|
||||||
test_WsAcceptChannel( &info );
|
|
||||||
WaitForSingleObject( thread, 3000 );
|
|
||||||
CloseHandle(thread);
|
|
||||||
|
|
||||||
info.type = WS_CHANNEL_TYPE_DUPLEX_SESSION;
|
|
||||||
info.binding = WS_TCP_CHANNEL_BINDING;
|
|
||||||
|
|
||||||
thread = start_listener( &info );
|
|
||||||
test_WsAcceptChannel( &info );
|
|
||||||
WaitForSingleObject( thread, 3000 );
|
|
||||||
CloseHandle(thread);
|
|
||||||
|
|
||||||
if (firewall_enabled) set_firewall( APP_REMOVE );
|
if (firewall_enabled) set_firewall( APP_REMOVE );
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@
|
||||||
@ stdcall WsRemoveHeader(ptr long ptr)
|
@ stdcall WsRemoveHeader(ptr long ptr)
|
||||||
@ stdcall WsRemoveMappedHeader(ptr ptr ptr)
|
@ stdcall WsRemoveMappedHeader(ptr ptr ptr)
|
||||||
@ stub WsRemoveNode
|
@ stub WsRemoveNode
|
||||||
@ stub WsRequestReply
|
@ stdcall WsRequestReply(ptr ptr ptr long ptr long ptr ptr long ptr ptr long ptr ptr)
|
||||||
@ stub WsRequestSecurityToken
|
@ stub WsRequestSecurityToken
|
||||||
@ stdcall WsResetChannel(ptr ptr)
|
@ stdcall WsResetChannel(ptr ptr)
|
||||||
@ stdcall WsResetError(ptr)
|
@ stdcall WsResetError(ptr)
|
||||||
|
|
|
@ -1701,6 +1701,9 @@ HRESULT WINAPI WsRemoveCustomHeader(WS_MESSAGE*, const WS_XML_STRING*, const WS_
|
||||||
HRESULT WINAPI WsRemoveHeader(WS_MESSAGE*, WS_HEADER_TYPE, WS_ERROR*);
|
HRESULT WINAPI WsRemoveHeader(WS_MESSAGE*, WS_HEADER_TYPE, WS_ERROR*);
|
||||||
HRESULT WINAPI WsRemoveMappedHeader(WS_MESSAGE*, const WS_XML_STRING*, WS_ERROR*);
|
HRESULT WINAPI WsRemoveMappedHeader(WS_MESSAGE*, const WS_XML_STRING*, WS_ERROR*);
|
||||||
HRESULT WINAPI WsRemoveNode(const WS_XML_NODE_POSITION*, WS_ERROR*);
|
HRESULT WINAPI WsRemoveNode(const WS_XML_NODE_POSITION*, WS_ERROR*);
|
||||||
|
HRESULT WINAPI WsRequestReply(WS_CHANNEL*, WS_MESSAGE*, const WS_MESSAGE_DESCRIPTION*, WS_WRITE_OPTION,
|
||||||
|
const void*, ULONG, WS_MESSAGE*, const WS_MESSAGE_DESCRIPTION*, WS_READ_OPTION,
|
||||||
|
WS_HEAP*, void*, ULONG, const WS_ASYNC_CONTEXT*, WS_ERROR*);
|
||||||
HRESULT WINAPI WsResetChannel(WS_CHANNEL*, WS_ERROR*);
|
HRESULT WINAPI WsResetChannel(WS_CHANNEL*, WS_ERROR*);
|
||||||
HRESULT WINAPI WsResetMessage(WS_MESSAGE*, WS_ERROR*);
|
HRESULT WINAPI WsResetMessage(WS_MESSAGE*, WS_ERROR*);
|
||||||
HRESULT WINAPI WsResetError(WS_ERROR*);
|
HRESULT WINAPI WsResetError(WS_ERROR*);
|
||||||
|
|
Loading…
Reference in New Issue