Commit 86895f07 authored by Shaun Ren's avatar Shaun Ren Committed by Alexandre Julliard

webservices: Handle in/out parameters properly in WsCall.

parent 5b1bb09b
......@@ -694,6 +694,108 @@ static void test_empty_response( int port )
WsFreeHeap( heap );
}
static const char req_test4[] =
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>"
"<req_test4 xmlns=\"ns\"><str>test4</str><val>1</val><val>2</val><val>3</val></req_test4>"
"</s:Body></s:Envelope>";
static const char resp_test4[] =
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>"
"<resp_test4 xmlns=\"ns\"><str>out4</str><val>4</val><val>5</val></resp_test4>"
"</s:Body></s:Envelope>";
static void test_inout_params( int port )
{
WS_XML_STRING str = {3, (BYTE *)"str"};
WS_XML_STRING req = {3, (BYTE *)"req"};
WS_XML_STRING resp = {4, (BYTE *)"resp"};
WS_XML_STRING req_elem = {9, (BYTE *)"req_test4"};
WS_XML_STRING resp_elem = {10, (BYTE *)"resp_test4"};
WS_XML_STRING req_action = {9, (BYTE *)"req_test4"};
WS_XML_STRING resp_action = {10, (BYTE *)"resp_test4"};
WS_XML_STRING val = {3, (BYTE *)"val"};
WS_XML_STRING ns = {2, (BYTE *)"ns"};
HRESULT hr;
WS_SERVICE_PROXY *proxy;
WS_OPERATION_DESCRIPTION op;
WS_MESSAGE_DESCRIPTION input_msg, output_msg;
WS_ELEMENT_DESCRIPTION input_elem, output_elem;
WS_STRUCT_DESCRIPTION input_struct, output_struct;
WS_FIELD_DESCRIPTION f, f2, *fields[2];
WS_PARAMETER_DESCRIPTION param[3];
const void *args[3];
WS_HEAP *heap;
INT32 val_array[] = {1, 2, 3};
WCHAR **str_ptr;
INT32 **val_ptr;
ULONG *count_ptr;
struct data
{
WCHAR *str;
ULONG count;
INT32 *val;
} data;
hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
ok( hr == S_OK, "got %#lx\n", hr );
hr = WsCall( NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL );
ok( hr == E_INVALIDARG, "got %#lx\n", hr );
hr = create_proxy( port, &proxy );
ok( hr == S_OK, "got %#lx\n", hr );
hr = WsCall( proxy, NULL, NULL, NULL, NULL, 0, NULL, NULL );
ok( hr == E_INVALIDARG, "got %#lx\n", hr );
set_field_desc( &f, WS_ELEMENT_FIELD_MAPPING, &str, &ns, WS_WSZ_TYPE, NULL,
FIELD_OFFSET(struct data, str), 0, 0, NULL, NULL );
set_field_desc( &f2, WS_REPEATING_ELEMENT_FIELD_MAPPING, NULL, NULL, WS_INT32_TYPE, NULL,
FIELD_OFFSET(struct data, val), 0, FIELD_OFFSET(struct data, count), &val, &ns );
fields[0] = &f;
fields[1] = &f2;
set_struct_desc( &input_struct, sizeof(struct data), TYPE_ALIGNMENT(struct data), fields, 2, &req, &ns, 0 );
set_elem_desc( &input_elem, &req_elem, &ns, WS_STRUCT_TYPE, &input_struct );
set_msg_desc( &input_msg, &req_action, &input_elem );
set_struct_desc( &output_struct, sizeof(struct data), TYPE_ALIGNMENT(struct data), fields, 2, &resp, &ns, 0 );
set_elem_desc( &output_elem, &resp_elem, &ns, WS_STRUCT_TYPE, &output_struct );
set_msg_desc( &output_msg, &resp_action, &output_elem );
set_param_desc( &param[0], WS_PARAMETER_TYPE_NORMAL, 0, 0 );
set_param_desc( &param[1], WS_PARAMETER_TYPE_ARRAY, 1, 1 );
set_param_desc( &param[2], WS_PARAMETER_TYPE_ARRAY_COUNT, 1, 1 );
set_op_desc( &op, &input_msg, &output_msg, 3, param );
data.str = (WCHAR *) L"test4";
data.count = ARRAY_SIZE(val_array);
data.val = val_array;
str_ptr = &data.str;
val_ptr = &data.val;
count_ptr = &data.count;
args[0] = &str_ptr;
args[1] = &val_ptr;
args[2] = &count_ptr;
hr = WsCall( proxy, &op, args, heap, NULL, 0, NULL, NULL );
ok( hr == S_OK, "got %#lx\n", hr );
ok( !wcscmp( data.str, L"out4" ), "wrong str\n" );
ok( data.count == 2, "got %lu\n", data.count );
ok( data.val[0] == 4, "got %u\n", data.val[0] );
ok( data.val[1] == 5, "got %u\n", data.val[1] );
hr = WsCloseServiceProxy( proxy, NULL, NULL );
ok( hr == S_OK, "got %#lx\n", hr );
WsFreeServiceProxy( proxy );
WsFreeHeap( heap );
}
static const char status_200[] = "HTTP/1.1 200 OK\r\n";
static const struct
......@@ -710,6 +812,7 @@ tests[] =
{ "req_test1", req_test1, sizeof(req_test1)-1, status_200, resp_test1, sizeof(resp_test1)-1 },
{ "req_test2", req_test2, sizeof(req_test2)-1, status_200, resp_test2, sizeof(resp_test2)-1 },
{ "req_test3", req_test3, sizeof(req_test3)-1, status_200, resp_test3, sizeof(resp_test3)-1 },
{ "req_test4", req_test4, sizeof(req_test4)-1, status_200, resp_test4, sizeof(resp_test4)-1 },
};
static void send_response( int c, const char *status, const char *data, unsigned int len )
......@@ -843,6 +946,7 @@ START_TEST(proxy)
test_WsReceiveMessage( info.port );
test_WsCall( info.port );
test_empty_response( info.port );
test_inout_params( info.port );
test_WsSendMessage( info.port, &quit );
WaitForSingleObject( thread, 3000 );
......
......@@ -4904,7 +4904,10 @@ static ULONG get_array_len( const WS_PARAMETER_DESCRIPTION *params, ULONG count,
{
if (params[i].inputMessageIndex != index || params[i].parameterType != WS_PARAMETER_TYPE_ARRAY_COUNT)
continue;
if (args[i]) ret = *(const ULONG *)args[i];
if (params[i].outputMessageIndex != INVALID_PARAMETER_INDEX)
ret = **(const ULONG **)args[i];
else
ret = *(const ULONG *)args[i];
break;
}
return ret;
......@@ -4949,12 +4952,22 @@ HRESULT write_input_params( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION
if ((hr = get_param_desc( desc_struct, params[i].inputMessageIndex, &desc_field )) != S_OK) goto done;
if (params[i].parameterType == WS_PARAMETER_TYPE_NORMAL)
{
if ((hr = write_param( writer, desc_field, args[i] )) != S_OK) goto done;
const void *ptr;
if (params[i].outputMessageIndex != INVALID_PARAMETER_INDEX)
ptr = *(const void **)args[i];
else
ptr = args[i];
if ((hr = write_param( writer, desc_field, ptr )) != S_OK) goto done;
}
else if (params[i].parameterType == WS_PARAMETER_TYPE_ARRAY)
{
const void *ptr = *(const void **)args[i];
ULONG len = get_array_len( params, count, params[i].inputMessageIndex, args );
const void *ptr;
ULONG len;
if (params[i].outputMessageIndex != INVALID_PARAMETER_INDEX)
ptr = **(const void ***)args[i];
else
ptr = *(const void **)args[i];
len = get_array_len( params, count, params[i].inputMessageIndex, args );
if ((hr = write_param_array( writer, desc_field, ptr, len )) != S_OK) goto done;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment