webservices: Protect readers with a critical section.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2017-03-08 11:26:00 +01:00 committed by Alexandre Julliard
parent dea8708079
commit 36c5252265
1 changed files with 488 additions and 104 deletions

View File

@ -834,6 +834,8 @@ struct prefix
struct reader
{
ULONG magic;
CRITICAL_SECTION cs;
ULONG read_size;
ULONG read_pos;
const unsigned char *read_bufptr;
@ -854,6 +856,8 @@ struct reader
struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])];
};
#define READER_MAGIC (('R' << 24) | ('E' << 16) | ('A' << 8) | 'D')
static struct reader *alloc_reader(void)
{
static const ULONG count = sizeof(reader_props)/sizeof(reader_props[0]);
@ -868,6 +872,10 @@ static struct reader *alloc_reader(void)
}
ret->nb_prefixes = ret->nb_prefixes_allocated = 1;
ret->magic = READER_MAGIC;
InitializeCriticalSection( &ret->cs );
ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": reader.cs");
prop_init( reader_props, count, ret->prop, &ret[1] );
ret->prop_count = count;
return ret;
@ -888,19 +896,23 @@ static void clear_prefixes( struct prefix *prefixes, ULONG count )
}
}
static void free_reader( struct reader *reader )
{
if (!reader) return;
destroy_nodes( reader->root );
clear_prefixes( reader->prefixes, reader->nb_prefixes );
heap_free( reader->prefixes );
heap_free( reader );
}
HRESULT copy_node( WS_XML_READER *handle, struct node **node )
{
struct reader *reader = (struct reader *)handle;
return dup_tree( node, reader->current );
HRESULT hr;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
hr = dup_tree( node, reader->current );
LeaveCriticalSection( &reader->cs );
return hr;
}
static HRESULT set_prefix( struct prefix *prefix, const WS_XML_STRING *str, const WS_XML_STRING *ns )
@ -981,18 +993,28 @@ static void read_insert_node( struct reader *reader, struct node *parent, struct
reader->current = reader->last = node;
}
static HRESULT read_init_state( struct reader *reader )
static void free_reader( struct reader *reader )
{
destroy_nodes( reader->root );
clear_prefixes( reader->prefixes, reader->nb_prefixes );
heap_free( reader->prefixes );
reader->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection( &reader->cs );
heap_free( reader );
}
static HRESULT init_reader( struct reader *reader )
{
struct node *node;
reader->state = READER_STATE_INITIAL;
destroy_nodes( reader->root );
reader->root = NULL;
reader->input_buf = NULL;
reader->root = reader->current = NULL;
reader->current_attr = 0;
clear_prefixes( reader->prefixes, reader->nb_prefixes );
reader->nb_prefixes = 1;
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
read_insert_eof( reader, node );
reader->state = READER_STATE_INITIAL;
return S_OK;
}
@ -1031,7 +1053,7 @@ HRESULT WINAPI WsCreateReader( const WS_XML_READER_PROPERTY *properties, ULONG c
}
}
if ((hr = read_init_state( reader )) != S_OK)
if ((hr = init_reader( reader )) != S_OK)
{
free_reader( reader );
return hr;
@ -1049,6 +1071,20 @@ void WINAPI WsFreeReader( WS_XML_READER *handle )
struct reader *reader = (struct reader *)handle;
TRACE( "%p\n", handle );
if (!reader) return;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return;
}
reader->magic = 0;
LeaveCriticalSection( &reader->cs );
free_reader( reader );
}
@ -1065,10 +1101,19 @@ HRESULT WINAPI WsFillReader( WS_XML_READER *handle, ULONG min_size, const WS_ASY
if (!reader) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
/* FIXME: add support for stream input */
reader->read_size = min( min_size, reader->input_size );
reader->read_pos = 0;
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -1090,7 +1135,20 @@ HRESULT WINAPI WsGetNamespaceFromPrefix( WS_XML_READER *handle, const WS_XML_STR
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !prefix || !ns) return E_INVALIDARG;
if (reader->state != READER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (reader->state != READER_STATE_STARTELEMENT)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
}
if (!prefix->length)
{
@ -1130,6 +1188,8 @@ HRESULT WINAPI WsGetNamespaceFromPrefix( WS_XML_READER *handle, const WS_XML_STR
*ns = NULL;
return S_FALSE;
}
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -1146,7 +1206,17 @@ HRESULT WINAPI WsGetReaderNode( WS_XML_READER *handle, const WS_XML_NODE **node,
if (!reader || !node) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
*node = &reader->current->hdr.node;
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -1157,23 +1227,44 @@ HRESULT WINAPI WsGetReaderProperty( WS_XML_READER *handle, WS_XML_READER_PROPERT
void *buf, ULONG size, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
HRESULT hr;
TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader->input_type) return WS_E_INVALID_OPERATION;
if (!reader) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (!reader->input_type)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
}
if (id == WS_XML_READER_PROPERTY_CHARSET)
{
WS_CHARSET charset;
HRESULT hr;
if ((hr = prop_get( reader->prop, reader->prop_count, id, &charset, size )) != S_OK) return hr;
if (!charset) return WS_E_INVALID_FORMAT;
*(WS_CHARSET *)buf = charset;
return S_OK;
if ((hr = prop_get( reader->prop, reader->prop_count, id, &charset, size )) != S_OK) goto done;
if (!charset)
{
hr = WS_E_INVALID_FORMAT;
goto done;
}
return prop_get( reader->prop, reader->prop_count, id, buf, size );
*(WS_CHARSET *)buf = charset;
hr = S_OK;
}
else hr = prop_get( reader->prop, reader->prop_count, id, buf, size );
done:
LeaveCriticalSection( &reader->cs );
return hr;
}
/**************************************************************************
@ -1391,8 +1482,7 @@ static HRESULT parse_name( const unsigned char *str, unsigned int len,
static int codepoint_to_utf8( int cp, unsigned char *dst )
{
if (!cp)
return -1;
if (!cp) return -1;
if (cp < 0x80)
{
*dst = cp;
@ -1476,7 +1566,7 @@ static HRESULT decode_text( const unsigned char *str, ULONG len, unsigned char *
p++; len--;
if (!len) return WS_E_INVALID_FORMAT;
else if (*p == 'x')
if (*p == 'x')
{
p++; len--;
@ -2040,12 +2130,25 @@ static HRESULT read_node( struct reader *reader )
HRESULT WINAPI WsReadEndElement( WS_XML_READER *handle, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
HRESULT hr;
TRACE( "%p %p\n", handle, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
return read_endelement( reader );
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
hr = read_endelement( reader );
LeaveCriticalSection( &reader->cs );
return hr;
}
/**************************************************************************
@ -2054,12 +2157,25 @@ HRESULT WINAPI WsReadEndElement( WS_XML_READER *handle, WS_ERROR *error )
HRESULT WINAPI WsReadNode( WS_XML_READER *handle, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
HRESULT hr;
TRACE( "%p %p\n", handle, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
return read_node( reader );
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
hr = read_node( reader );
LeaveCriticalSection( &reader->cs );
return hr;
}
/**************************************************************************
@ -2068,12 +2184,25 @@ HRESULT WINAPI WsReadNode( WS_XML_READER *handle, WS_ERROR *error )
HRESULT WINAPI WsReadStartElement( WS_XML_READER *handle, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
HRESULT hr;
TRACE( "%p %p\n", handle, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
return read_startelement( reader );
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
hr = read_startelement( reader );
LeaveCriticalSection( &reader->cs );
return hr;
}
/**************************************************************************
@ -2083,6 +2212,7 @@ HRESULT WINAPI WsReadToStartElement( WS_XML_READER *handle, const WS_XML_STRING
const WS_XML_STRING *ns, BOOL *found, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
HRESULT hr;
TRACE( "%p %s %s %p %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns), found, error );
if (error) FIXME( "ignoring error parameter\n" );
@ -2090,7 +2220,18 @@ HRESULT WINAPI WsReadToStartElement( WS_XML_READER *handle, const WS_XML_STRING
if (!reader) return E_INVALIDARG;
if (localname || ns) FIXME( "name and/or namespace not verified\n" );
return read_to_startelement( reader, found );
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
hr = read_to_startelement( reader, found );
LeaveCriticalSection( &reader->cs );
return hr;
}
BOOL move_to_root_element( struct node *root, struct node **current )
@ -2369,14 +2510,31 @@ static HRESULT read_move_to( struct reader *reader, WS_MOVE_TO move, BOOL *found
HRESULT WINAPI WsMoveReader( WS_XML_READER *handle, WS_MOVE_TO move, BOOL *found, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
HRESULT hr;
TRACE( "%p %u %p %p\n", handle, move, found, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
if (!reader->input_type) return WS_E_INVALID_OPERATION;
return read_move_to( reader, move, found );
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (!reader->input_type)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
}
hr = read_move_to( reader, move, found );
LeaveCriticalSection( &reader->cs );
return hr;
}
/**************************************************************************
@ -2385,19 +2543,32 @@ HRESULT WINAPI WsMoveReader( WS_XML_READER *handle, WS_MOVE_TO move, BOOL *found
HRESULT WINAPI WsReadStartAttribute( WS_XML_READER *handle, ULONG index, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
WS_XML_ELEMENT_NODE *elem;
const WS_XML_ELEMENT_NODE *elem;
TRACE( "%p %u %p\n", handle, index, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
elem = &reader->current->hdr;
if (reader->state != READER_STATE_STARTELEMENT || index >= elem->attributeCount)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_FORMAT;
}
reader->current_attr = index;
reader->state = READER_STATE_STARTATTRIBUTE;
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -2413,10 +2584,23 @@ HRESULT WINAPI WsReadEndAttribute( WS_XML_READER *handle, WS_ERROR *error )
if (!reader) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (reader->state != READER_STATE_STARTATTRIBUTE)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_FORMAT;
}
reader->state = READER_STATE_STARTELEMENT;
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -3010,6 +3194,7 @@ HRESULT WINAPI WsFindAttribute( WS_XML_READER *handle, const WS_XML_STRING *loca
WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
HRESULT hr = S_OK;
TRACE( "%p %s %s %d %p %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns),
required, index, error );
@ -3017,16 +3202,32 @@ HRESULT WINAPI WsFindAttribute( WS_XML_READER *handle, const WS_XML_STRING *loca
if (!reader || !localname || !ns || !index) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (node_type( reader->current ) != WS_XML_NODE_TYPE_ELEMENT)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
}
if (!find_attribute( reader, localname, ns, index ))
{
if (required) return WS_E_INVALID_FORMAT;
if (required) hr = WS_E_INVALID_FORMAT;
else
{
*index = ~0u;
return S_FALSE;
hr = S_FALSE;
}
return S_OK;
}
LeaveCriticalSection( &reader->cs );
return hr;
}
static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping,
@ -4485,21 +4686,34 @@ HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TY
if (!reader || !value) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if ((hr = read_type( reader, mapping, type, NULL, NULL, desc, option, heap, value, size )) != S_OK)
{
LeaveCriticalSection( &reader->cs );
return hr;
}
switch (mapping)
{
case WS_ELEMENT_TYPE_MAPPING:
if ((hr = read_node( reader )) != S_OK) return hr;
hr = read_node( reader );
break;
default:
break;
}
if (!read_end_of_data( reader )) return WS_E_INVALID_FORMAT;
return S_OK;
if (hr == S_OK && !read_end_of_data( reader )) hr = WS_E_INVALID_FORMAT;
LeaveCriticalSection( &reader->cs );
return hr;
}
/**************************************************************************
@ -4510,14 +4724,26 @@ HRESULT WINAPI WsReadElement( WS_XML_READER *handle, const WS_ELEMENT_DESCRIPTIO
WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
HRESULT hr;
TRACE( "%p %p %u %p %p %u %p\n", handle, desc, option, heap, value, size, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !desc || !value) return E_INVALIDARG;
return read_type( reader, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->elementLocalName,
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->elementLocalName,
desc->elementNs, desc->typeDescription, option, heap, value, size );
LeaveCriticalSection( &reader->cs );
return hr;
}
/**************************************************************************
@ -4528,14 +4754,26 @@ HRESULT WINAPI WsReadValue( WS_XML_READER *handle, WS_VALUE_TYPE value_type, voi
{
struct reader *reader = (struct reader *)handle;
WS_TYPE type = map_value_type( value_type );
HRESULT hr;
TRACE( "%p %u %p %u %p\n", handle, type, value, size, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !value || type == ~0u) return E_INVALIDARG;
return read_type( reader, WS_ELEMENT_TYPE_MAPPING, type, NULL, NULL, NULL, WS_READ_REQUIRED_VALUE,
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, type, NULL, NULL, NULL, WS_READ_REQUIRED_VALUE,
NULL, value, size );
LeaveCriticalSection( &reader->cs );
return hr;
}
static inline BOOL is_utf8( const unsigned char *data, ULONG size, ULONG *offset )
@ -4584,6 +4822,8 @@ static void set_input_buffer( struct reader *reader, struct xmlbuf *buf, const u
reader->read_size = reader->input_size;
reader->read_pos = 0;
reader->read_bufptr = reader->input_data;
reader->text_conv_offset = 0;
}
/**************************************************************************
@ -4595,22 +4835,30 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
{
struct reader *reader = (struct reader *)handle;
struct node *node;
HRESULT hr;
ULONG i, offset = 0;
HRESULT hr;
TRACE( "%p %p %p %p %u %p\n", handle, encoding, input, properties, count, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
for (i = 0; i < count; i++)
{
hr = prop_set( reader->prop, reader->prop_count, properties[i].id, properties[i].value,
properties[i].valueSize );
if (hr != S_OK) return hr;
if (hr != S_OK) goto done;
}
if ((hr = read_init_state( reader )) != S_OK) return hr;
if ((hr = init_reader( reader )) != S_OK) goto done;
switch (encoding->encodingType)
{
@ -4623,7 +4871,8 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
if (input->inputType != WS_XML_READER_INPUT_TYPE_BUFFER)
{
FIXME( "charset detection on input type %u not supported\n", input->inputType );
return E_NOTIMPL;
hr = E_NOTIMPL;
goto done;
}
if (charset == WS_CHARSET_AUTO)
@ -4631,13 +4880,15 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET,
&charset, sizeof(charset) );
if (hr != S_OK) return hr;
if (hr != S_OK) goto done;
break;
}
default:
FIXME( "encoding type %u not supported\n", encoding->encodingType );
return E_NOTIMPL;
hr = E_NOTIMPL;
goto done;
}
switch (input->inputType)
{
case WS_XML_READER_INPUT_TYPE_BUFFER:
@ -4649,12 +4900,16 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
}
default:
FIXME( "input type %u not supported\n", input->inputType );
return E_NOTIMPL;
hr = E_NOTIMPL;
goto done;
}
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
read_insert_bof( reader, node );
return S_OK;
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
else read_insert_bof( reader, node );
done:
LeaveCriticalSection( &reader->cs );
return hr;
}
/**************************************************************************
@ -4668,32 +4923,43 @@ HRESULT WINAPI WsSetInputToBuffer( WS_XML_READER *handle, WS_XML_BUFFER *buffer,
struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer;
WS_CHARSET charset;
struct node *node;
HRESULT hr;
ULONG i, offset = 0;
HRESULT hr;
TRACE( "%p %p %p %u %p\n", handle, buffer, properties, count, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !xmlbuf) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
for (i = 0; i < count; i++)
{
hr = prop_set( reader->prop, reader->prop_count, properties[i].id, properties[i].value,
properties[i].valueSize );
if (hr != S_OK) return hr;
if (hr != S_OK) goto done;
}
if ((hr = read_init_state( reader )) != S_OK) return hr;
if ((hr = init_reader( reader )) != S_OK) goto done;
charset = detect_charset( xmlbuf->ptr, xmlbuf->size, &offset );
hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET,
&charset, sizeof(charset) );
if (hr != S_OK) return hr;
hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET, &charset,
sizeof(charset) );
if (hr != S_OK) goto done;
set_input_buffer( reader, xmlbuf, (const unsigned char *)xmlbuf->ptr + offset, xmlbuf->size - offset );
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
read_insert_bof( reader, node );
return S_OK;
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
else read_insert_bof( reader, node );
done:
LeaveCriticalSection( &reader->cs );
return hr;
}
/**************************************************************************
@ -4722,10 +4988,25 @@ HRESULT WINAPI WsGetReaderPosition( WS_XML_READER *handle, WS_XML_NODE_POSITION
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !pos) return E_INVALIDARG;
if (!reader->input_buf) return WS_E_INVALID_OPERATION;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (!reader->input_buf)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
}
pos->buffer = (WS_XML_BUFFER *)reader->input_buf;
pos->node = reader->current;
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -4739,10 +5020,25 @@ HRESULT WINAPI WsSetReaderPosition( WS_XML_READER *handle, const WS_XML_NODE_POS
TRACE( "%p %p %p\n", handle, pos, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !pos || (struct xmlbuf *)pos->buffer != reader->input_buf) return E_INVALIDARG;
if (!reader->input_buf) return WS_E_INVALID_OPERATION;
if (!reader || !pos) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC || (struct xmlbuf *)pos->buffer != reader->input_buf)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (!reader->input_buf)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
}
reader->current = pos->node;
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -4766,8 +5062,26 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count,
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
if (!reader->input_type) return WS_E_INVALID_OPERATION;
if (!count) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (!reader->input_type)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
}
if (!count)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
*count = 0;
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes)
@ -4775,11 +5089,17 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count,
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current;
WS_XML_BASE64_TEXT base64;
if ((hr = utf8_to_base64( (const WS_XML_UTF8_TEXT *)text->text, &base64 )) != S_OK) return hr;
if ((hr = utf8_to_base64( (const WS_XML_UTF8_TEXT *)text->text, &base64 )) != S_OK)
{
LeaveCriticalSection( &reader->cs );
return hr;
}
if (reader->text_conv_offset == base64.length)
{
heap_free( base64.bytes );
return read_node( reader );
hr = read_node( reader );
LeaveCriticalSection( &reader->cs );
return hr;
}
*count = min( base64.length - reader->text_conv_offset, max_count );
memcpy( bytes, base64.bytes + reader->text_conv_offset, *count );
@ -4787,6 +5107,7 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count,
heap_free( base64.bytes );
}
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -4810,8 +5131,26 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
if (!reader->input_type) return WS_E_INVALID_OPERATION;
if (!count) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (!reader->input_type)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
}
if (!count)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
*count = 0;
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && chars)
@ -4820,11 +5159,17 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
WS_XML_UTF16_TEXT utf16;
HRESULT hr;
if ((hr = utf8_to_utf16( (const WS_XML_UTF8_TEXT *)text->text, &utf16 )) != S_OK) return hr;
if ((hr = utf8_to_utf16( (const WS_XML_UTF8_TEXT *)text->text, &utf16 )) != S_OK)
{
LeaveCriticalSection( &reader->cs );
return hr;
}
if (reader->text_conv_offset == utf16.byteCount / sizeof(WCHAR))
{
heap_free( utf16.bytes );
return read_node( reader );
hr = read_node( reader );
LeaveCriticalSection( &reader->cs );
return hr;
}
*count = min( utf16.byteCount / sizeof(WCHAR) - reader->text_conv_offset, max_count );
memcpy( chars, utf16.bytes + reader->text_conv_offset * sizeof(WCHAR), *count * sizeof(WCHAR) );
@ -4832,6 +5177,7 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
heap_free( utf16.bytes );
}
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -4841,13 +5187,32 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
HRESULT WINAPI WsReadCharsUtf8( WS_XML_READER *handle, BYTE *bytes, ULONG max_count, ULONG *count, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
HRESULT hr;
TRACE( "%p %p %u %p %p\n", handle, bytes, max_count, count, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
if (!reader->input_type) return WS_E_INVALID_OPERATION;
if (!count) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if (!reader->input_type)
{
LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
}
if (!count)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
*count = 0;
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes)
@ -4855,12 +5220,18 @@ HRESULT WINAPI WsReadCharsUtf8( WS_XML_READER *handle, BYTE *bytes, ULONG max_co
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current;
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text->text;
if (reader->text_conv_offset == utf8->value.length) return read_node( reader );
if (reader->text_conv_offset == utf8->value.length)
{
hr = read_node( reader );
LeaveCriticalSection( &reader->cs );
return hr;
}
*count = min( utf8->value.length - reader->text_conv_offset, max_count );
memcpy( bytes, utf8->value.bytes + reader->text_conv_offset, *count );
reader->text_conv_offset += *count;
}
LeaveCriticalSection( &reader->cs );
return S_OK;
}
@ -4934,8 +5305,16 @@ HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEME
if (desc->type != WS_STRUCT_TYPE || !(desc_struct = desc->typeDescription)) return E_INVALIDARG;
EnterCriticalSection( &reader->cs );
if (reader->magic != READER_MAGIC)
{
LeaveCriticalSection( &reader->cs );
return E_INVALIDARG;
}
if ((hr = start_mapping( reader, WS_ELEMENT_TYPE_MAPPING, desc->elementLocalName, desc->elementNs )) != S_OK)
return hr;
goto done;
for (i = 0; i < count; i++)
{
@ -4943,18 +5322,19 @@ HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEME
if (params[i].parameterType == WS_PARAMETER_TYPE_MESSAGES)
{
FIXME( "messages type not supported\n" );
return E_NOTIMPL;
hr = E_NOTIMPL;
goto done;
}
if ((hr = get_param_desc( desc_struct, params[i].outputMessageIndex, &desc_field )) != S_OK) return hr;
if ((hr = get_param_desc( desc_struct, params[i].outputMessageIndex, &desc_field )) != S_OK) goto done;
if (params[i].parameterType == WS_PARAMETER_TYPE_NORMAL)
{
void *ptr = *(void **)args[i];
if ((hr = read_param( reader, desc_field, heap, ptr )) != S_OK) return hr;
if ((hr = read_param( reader, desc_field, heap, ptr )) != S_OK) goto done;
}
else if (params[i].parameterType == WS_PARAMETER_TYPE_ARRAY)
{
void **ptr = *(void ***)args[i];
if ((hr = read_param_array( reader, desc_field, heap, ptr, &len )) != S_OK) return hr;
if ((hr = read_param_array( reader, desc_field, heap, ptr, &len )) != S_OK) goto done;
set_array_len( params, count, params[i].outputMessageIndex, len, args );
}
}
@ -4965,5 +5345,9 @@ HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEME
parent->flags |= NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT;
}
return end_mapping( reader, WS_ELEMENT_TYPE_MAPPING );
hr = end_mapping( reader, WS_ELEMENT_TYPE_MAPPING );
done:
LeaveCriticalSection( &reader->cs );
return hr;
}