[5/8] webservices: Protect writers with a critical section.
Hans Leidekker
hans at codeweavers.com
Wed Mar 8 04:25:57 CST 2017
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/writer.c | 625 ++++++++++++++++++++++++++++++++++++++--------
1 file changed, 515 insertions(+), 110 deletions(-)
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index 852cfdb..20cbace 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -71,19 +71,23 @@ enum writer_state
struct writer
{
- ULONG write_pos;
- unsigned char *write_bufptr;
- enum writer_state state;
- struct node *root;
- struct node *current;
- WS_XML_STRING *current_ns;
- WS_XML_WRITER_OUTPUT_TYPE output_type;
- struct xmlbuf *output_buf;
- WS_HEAP *output_heap;
- ULONG prop_count;
- struct prop prop[sizeof(writer_props)/sizeof(writer_props[0])];
+ ULONG magic;
+ CRITICAL_SECTION cs;
+ ULONG write_pos;
+ unsigned char *write_bufptr;
+ enum writer_state state;
+ struct node *root;
+ struct node *current;
+ WS_XML_STRING *current_ns;
+ WS_XML_WRITER_OUTPUT_TYPE output_type;
+ struct xmlbuf *output_buf;
+ WS_HEAP *output_heap;
+ ULONG prop_count;
+ struct prop prop[sizeof(writer_props)/sizeof(writer_props[0])];
};
+#define WRITER_MAGIC (('W' << 24) | ('R' << 16) | ('I' << 8) | 'T')
+
static struct writer *alloc_writer(void)
{
static const ULONG count = sizeof(writer_props)/sizeof(writer_props[0]);
@@ -91,6 +95,11 @@ static struct writer *alloc_writer(void)
ULONG size = sizeof(*ret) + prop_size( writer_props, count );
if (!(ret = heap_alloc_zero( size ))) return NULL;
+
+ ret->magic = WRITER_MAGIC;
+ InitializeCriticalSection( &ret->cs );
+ ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": writer.cs");
+
prop_init( writer_props, count, ret->prop, &ret[1] );
ret->prop_count = count;
return ret;
@@ -98,10 +107,12 @@ static struct writer *alloc_writer(void)
static void free_writer( struct writer *writer )
{
- if (!writer) return;
destroy_nodes( writer->root );
heap_free( writer->current_ns );
WsFreeHeap( writer->output_heap );
+
+ writer->cs.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection( &writer->cs );
heap_free( writer );
}
@@ -137,18 +148,20 @@ static struct node *find_parent( struct writer *writer )
return NULL;
}
-static HRESULT write_init_state( struct writer *writer )
+static HRESULT init_writer( struct writer *writer )
{
struct node *node;
- heap_free( writer->current_ns );
- writer->current_ns = NULL;
+ writer->write_pos = 0;
+ writer->write_bufptr = NULL;
destroy_nodes( writer->root );
- writer->root = NULL;
+ writer->root = writer->current = NULL;
+ heap_free( writer->current_ns );
+ writer->current_ns = NULL;
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
write_insert_eof( writer, node );
- writer->state = WRITER_STATE_INITIAL;
+ writer->state = WRITER_STATE_INITIAL;
return S_OK;
}
@@ -203,7 +216,7 @@ HRESULT WINAPI WsCreateWriter( const WS_XML_WRITER_PROPERTY *properties, ULONG c
return hr;
}
- hr = write_init_state( writer );
+ hr = init_writer( writer );
if (hr != S_OK)
{
free_writer( writer );
@@ -222,6 +235,20 @@ void WINAPI WsFreeWriter( WS_XML_WRITER *handle )
struct writer *writer = (struct writer *)handle;
TRACE( "%p\n", handle );
+
+ if (!writer) return;
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return;
+ }
+
+ writer->magic = 0;
+
+ LeaveCriticalSection( &writer->cs );
free_writer( writer );
}
@@ -273,25 +300,46 @@ HRESULT WINAPI WsGetWriterProperty( WS_XML_WRITER *handle, WS_XML_WRITER_PROPERT
void *buf, ULONG size, WS_ERROR *error )
{
struct writer *writer = (struct writer *)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 (!writer->output_type) return WS_E_INVALID_OPERATION;
+ if (!writer) return E_INVALIDARG;
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!writer->output_type)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
switch (id)
{
case WS_XML_WRITER_PROPERTY_BYTES:
{
WS_BYTES *bytes = buf;
- if (size != sizeof(*bytes)) return E_INVALIDARG;
- bytes->bytes = writer->output_buf->ptr;
- bytes->length = writer->output_buf->size;
- return S_OK;
+ if (size != sizeof(*bytes)) hr = E_INVALIDARG;
+ else
+ {
+ bytes->bytes = writer->output_buf->ptr;
+ bytes->length = writer->output_buf->size;
+ }
+ break;
}
default:
- return prop_get( writer->prop, writer->prop_count, id, buf, size );
+ hr = prop_get( writer->prop, writer->prop_count, id, buf, size );
}
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static void set_output_buffer( struct writer *writer, struct xmlbuf *xmlbuf )
@@ -324,14 +372,22 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING
if (!writer) return E_INVALIDARG;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
for (i = 0; i < count; i++)
{
hr = prop_set( writer->prop, writer->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 = write_init_state( writer )) != S_OK) return hr;
+ if ((hr = init_writer( writer )) != S_OK) goto done;
switch (encoding->encodingType)
{
@@ -341,32 +397,39 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING
if (text->charSet != WS_CHARSET_UTF8)
{
FIXME( "charset %u not supported\n", text->charSet );
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
+ goto done;
}
break;
}
default:
FIXME( "encoding type %u not supported\n", encoding->encodingType );
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
+ goto done;
}
+
switch (output->outputType)
{
case WS_XML_WRITER_OUTPUT_TYPE_BUFFER:
{
struct xmlbuf *xmlbuf;
- if (!(xmlbuf = alloc_xmlbuf( writer->output_heap ))) return WS_E_QUOTA_EXCEEDED;
- set_output_buffer( writer, xmlbuf );
+ if (!(xmlbuf = alloc_xmlbuf( writer->output_heap ))) hr = WS_E_QUOTA_EXCEEDED;
+ else set_output_buffer( writer, xmlbuf );
break;
}
default:
FIXME( "output type %u not supported\n", output->outputType );
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
+ goto done;
}
- if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
- write_insert_bof( writer, node );
- return S_OK;
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
+ else write_insert_bof( writer, node );
+
+done:
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
/**************************************************************************
@@ -387,19 +450,30 @@ HRESULT WINAPI WsSetOutputToBuffer( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer
if (!writer || !xmlbuf) return E_INVALIDARG;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
for (i = 0; i < count; i++)
{
hr = prop_set( writer->prop, writer->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 = write_init_state( writer )) != S_OK) return hr;
+ if ((hr = init_writer( writer )) != S_OK) goto done;
set_output_buffer( writer, xmlbuf );
- if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
- write_insert_bof( writer, node );
- return S_OK;
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
+ else write_insert_bof( writer, node );
+
+done:
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static HRESULT write_grow_buffer( struct writer *writer, ULONG size )
@@ -526,25 +600,40 @@ HRESULT WINAPI WsGetPrefixFromNamespace( WS_XML_WRITER *handle, const WS_XML_STR
struct writer *writer = (struct writer *)handle;
WS_XML_ELEMENT_NODE *elem;
BOOL found = FALSE;
+ HRESULT hr = S_OK;
TRACE( "%p %s %d %p %p\n", handle, debugstr_xmlstr(ns), required, prefix, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!writer || !ns || !prefix) return E_INVALIDARG;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
elem = &writer->current->hdr;
if (elem->prefix && is_current_namespace( writer, ns ))
{
*prefix = elem->prefix;
found = TRUE;
}
+
if (!found)
{
- if (required) return WS_E_INVALID_FORMAT;
- *prefix = NULL;
- return S_FALSE;
+ if (required) hr = WS_E_INVALID_FORMAT;
+ else
+ {
+ *prefix = NULL;
+ hr = S_FALSE;
+ }
}
- return S_OK;
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static HRESULT set_current_namespace( struct writer *writer, const WS_XML_STRING *ns )
@@ -663,7 +752,17 @@ HRESULT WINAPI WsWriteEndAttribute( WS_XML_WRITER *handle, WS_ERROR *error )
if (!writer) return E_INVALIDARG;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
writer->state = WRITER_STATE_STARTELEMENT;
+
+ LeaveCriticalSection( &writer->cs );
return S_OK;
}
@@ -783,12 +882,25 @@ static HRESULT write_endelement_node( struct writer *writer )
HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error )
{
struct writer *writer = (struct writer *)handle;
+ HRESULT hr;
TRACE( "%p %p\n", handle, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!writer) return E_INVALIDARG;
- return write_endelement_node( writer );
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = write_endelement_node( writer );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static HRESULT write_endstartelement( struct writer *writer )
@@ -811,13 +923,28 @@ HRESULT WINAPI WsWriteEndStartElement( WS_XML_WRITER *handle, WS_ERROR *error )
if (error) FIXME( "ignoring error parameter\n" );
if (!writer) return E_INVALIDARG;
- if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;
- if ((hr = write_set_element_namespace( writer )) != S_OK) return hr;
- if ((hr = write_startelement( writer )) != S_OK) return hr;
- if ((hr = write_endstartelement( writer )) != S_OK) return hr;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+ if (writer->state != WRITER_STATE_STARTELEMENT)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ if ((hr = write_set_element_namespace( writer )) != S_OK) goto done;
+ if ((hr = write_startelement( writer )) != S_OK) goto done;
+ if ((hr = write_endstartelement( writer )) != S_OK) goto done;
writer->state = WRITER_STATE_ENDSTARTELEMENT;
+
+done:
+ LeaveCriticalSection( &writer->cs );
return S_OK;
}
@@ -873,10 +1000,24 @@ HRESULT WINAPI WsWriteStartAttribute( WS_XML_WRITER *handle, const WS_XML_STRING
if (!writer || !localname || !ns) return E_INVALIDARG;
- if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;
+ EnterCriticalSection( &writer->cs );
- if ((hr = write_add_attribute( writer, prefix, localname, ns, single )) != S_OK) return hr;
- writer->state = WRITER_STATE_STARTATTRIBUTE;
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (writer->state != WRITER_STATE_STARTELEMENT)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ if ((hr = write_add_attribute( writer, prefix, localname, ns, single )) == S_OK)
+ writer->state = WRITER_STATE_STARTATTRIBUTE;
+
+ LeaveCriticalSection( &writer->cs );
return S_OK;
}
@@ -937,12 +1078,25 @@ static HRESULT write_cdata_node( struct writer *writer )
HRESULT WINAPI WsWriteStartCData( WS_XML_WRITER *handle, WS_ERROR *error )
{
struct writer *writer = (struct writer *)handle;
+ HRESULT hr;
TRACE( "%p %p\n", handle, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!writer) return E_INVALIDARG;
- return write_cdata_node( writer );
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = write_cdata_node( writer );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static HRESULT write_endcdata( struct writer *writer )
@@ -968,14 +1122,31 @@ static HRESULT write_endcdata_node( struct writer *writer )
HRESULT WINAPI WsWriteEndCData( WS_XML_WRITER *handle, WS_ERROR *error )
{
struct writer *writer = (struct writer *)handle;
+ HRESULT hr;
TRACE( "%p %p\n", handle, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!writer) return E_INVALIDARG;
- if (writer->state != WRITER_STATE_TEXT) return WS_E_INVALID_OPERATION;
- return write_endcdata_node( writer );
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (writer->state != WRITER_STATE_TEXT)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ hr = write_endcdata_node( writer );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static HRESULT write_add_element_node( struct writer *writer, const WS_XML_STRING *prefix,
@@ -1042,13 +1213,26 @@ HRESULT WINAPI WsWriteStartElement( WS_XML_WRITER *handle, const WS_XML_STRING *
WS_ERROR *error )
{
struct writer *writer = (struct writer *)handle;
+ HRESULT hr;
TRACE( "%p %s %s %s %p\n", handle, debugstr_xmlstr(prefix), debugstr_xmlstr(localname),
debugstr_xmlstr(ns), error );
if (error) FIXME( "ignoring error parameter\n" );
if (!writer || !localname || !ns) return E_INVALIDARG;
- return write_element_node( writer, prefix, localname, ns );
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = write_element_node( writer, prefix, localname, ns );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static ULONG format_bool( const BOOL *ptr, unsigned char *buf )
@@ -1479,13 +1663,25 @@ static HRESULT write_text_node( struct writer *writer, const WS_XML_TEXT *text )
HRESULT WINAPI WsWriteText( WS_XML_WRITER *handle, const WS_XML_TEXT *text, WS_ERROR *error )
{
struct writer *writer = (struct writer *)handle;
+ HRESULT hr;
TRACE( "%p %p %p\n", handle, text, error );
if (!writer || !text) return E_INVALIDARG;
- if (writer->state == WRITER_STATE_STARTATTRIBUTE) return write_set_attribute_value( writer, text );
- return write_text_node( writer, text );
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (writer->state == WRITER_STATE_STARTATTRIBUTE) hr = write_set_attribute_value( writer, text );
+ else hr = write_text_node( writer, text );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static HRESULT write_type_text( struct writer *writer, WS_TYPE_MAPPING mapping, const WS_XML_TEXT *text )
@@ -2211,14 +2407,31 @@ HRESULT WINAPI WsWriteAttribute( WS_XML_WRITER *handle, const WS_ATTRIBUTE_DESCR
if (!writer || !desc || !desc->attributeLocalName || !desc->attributeNs || !value)
return E_INVALIDARG;
- if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (writer->state != WRITER_STATE_STARTELEMENT)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
- if ((hr = write_add_attribute( writer, NULL, desc->attributeLocalName, desc->attributeNs,
- FALSE )) != S_OK) return hr;
+ if ((hr = write_add_attribute( writer, NULL, desc->attributeLocalName, desc->attributeNs, FALSE )) != S_OK)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return hr;
+ }
writer->state = WRITER_STATE_STARTATTRIBUTE;
- return write_type( writer, WS_ATTRIBUTE_TYPE_MAPPING, desc->type, desc->typeDescription,
- option, value, size );
+ hr = write_type( writer, WS_ATTRIBUTE_TYPE_MAPPING, desc->type, desc->typeDescription, option, value, size );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
/**************************************************************************
@@ -2237,12 +2450,24 @@ HRESULT WINAPI WsWriteElement( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTI
if (!writer || !desc || !desc->elementLocalName || !desc->elementNs || !value)
return E_INVALIDARG;
- if ((hr = write_element_node( writer, NULL, desc->elementLocalName, desc->elementNs )) != S_OK) return hr;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if ((hr = write_element_node( writer, NULL, desc->elementLocalName, desc->elementNs )) != S_OK) goto done;
if ((hr = write_type( writer, WS_ANY_ELEMENT_TYPE_MAPPING, desc->type, desc->typeDescription,
- option, value, size )) != S_OK) return hr;
+ option, value, size )) != S_OK) goto done;
+
+ hr = write_endelement_node( writer );
- return write_endelement_node( writer );
+done:
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
/**************************************************************************
@@ -2261,17 +2486,25 @@ HRESULT WINAPI WsWriteType( WS_XML_WRITER *handle, WS_TYPE_MAPPING mapping, WS_T
if (!writer || !value) return E_INVALIDARG;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
switch (mapping)
{
case WS_ATTRIBUTE_TYPE_MAPPING:
- if (writer->state != WRITER_STATE_STARTATTRIBUTE) return WS_E_INVALID_FORMAT;
- hr = write_type( writer, mapping, type, desc, option, value, size );
+ if (writer->state != WRITER_STATE_STARTATTRIBUTE) hr = WS_E_INVALID_FORMAT;
+ else hr = write_type( writer, mapping, type, desc, option, value, size );
break;
case WS_ELEMENT_TYPE_MAPPING:
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
- if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_FORMAT;
- hr = write_type( writer, mapping, type, desc, option, value, size );
+ if (writer->state != WRITER_STATE_STARTELEMENT) hr = WS_E_INVALID_FORMAT;
+ else hr = write_type( writer, mapping, type, desc, option, value, size );
break;
case WS_ANY_ELEMENT_TYPE_MAPPING:
@@ -2280,9 +2513,10 @@ HRESULT WINAPI WsWriteType( WS_XML_WRITER *handle, WS_TYPE_MAPPING mapping, WS_T
default:
FIXME( "mapping %u not implemented\n", mapping );
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
}
+ LeaveCriticalSection( &writer->cs );
return hr;
}
@@ -2319,6 +2553,7 @@ HRESULT WINAPI WsWriteValue( WS_XML_WRITER *handle, WS_VALUE_TYPE value_type, co
{
struct writer *writer = (struct writer *)handle;
WS_TYPE_MAPPING mapping;
+ HRESULT hr = S_OK;
WS_TYPE type;
TRACE( "%p %u %p %u %p\n", handle, value_type, value, size, error );
@@ -2326,6 +2561,14 @@ HRESULT WINAPI WsWriteValue( WS_XML_WRITER *handle, WS_VALUE_TYPE value_type, co
if (!writer || !value || (type = map_value_type( value_type )) == ~0u) return E_INVALIDARG;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
switch (writer->state)
{
case WRITER_STATE_STARTATTRIBUTE:
@@ -2337,10 +2580,13 @@ HRESULT WINAPI WsWriteValue( WS_XML_WRITER *handle, WS_VALUE_TYPE value_type, co
break;
default:
- return WS_E_INVALID_FORMAT;
+ hr = WS_E_INVALID_FORMAT;
}
- return write_type( writer, mapping, type, NULL, WS_WRITE_REQUIRED_VALUE, value, size );
+ if (hr == S_OK) hr = write_type( writer, mapping, type, NULL, WS_WRITE_REQUIRED_VALUE, value, size );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
/**************************************************************************
@@ -2360,22 +2606,46 @@ HRESULT WINAPI WsWriteArray( WS_XML_WRITER *handle, const WS_XML_STRING *localna
if (error) FIXME( "ignoring error parameter\n" );
if (!writer) return E_INVALIDARG;
- if (!writer->output_type) return WS_E_INVALID_OPERATION;
- if (!localname || !ns || (type = map_value_type( value_type )) == ~0u) return E_INVALIDARG;
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!writer->output_type)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ if (!localname || !ns || (type = map_value_type( value_type )) == ~0u)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
type_size = get_type_size( type, NULL );
- if (size % type_size || (offset + count) * type_size > size || (count && !array)) return E_INVALIDARG;
+ if (size % type_size || (offset + count) * type_size > size || (count && !array))
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
for (i = offset; i < count; i++)
{
const char *ptr = (const char *)array + (offset + i) * type_size;
- if ((hr = write_element_node( writer, NULL, localname, ns )) != S_OK) return hr;
+ if ((hr = write_element_node( writer, NULL, localname, ns )) != S_OK) goto done;
if ((hr = write_type( writer, WS_ELEMENT_TYPE_MAPPING, type, NULL, WS_WRITE_REQUIRED_POINTER,
- &ptr, sizeof(ptr) )) != S_OK) return hr;
- if ((hr = write_endelement_node( writer )) != S_OK) return hr;
+ &ptr, sizeof(ptr) )) != S_OK) goto done;
+ if ((hr = write_endelement_node( writer )) != S_OK) goto done;
}
- return S_OK;
+done:
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
/**************************************************************************
@@ -2392,9 +2662,20 @@ HRESULT WINAPI WsWriteXmlBuffer( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer, W
if (!writer || !xmlbuf) return E_INVALIDARG;
- if ((hr = write_flush( writer )) != S_OK) return hr;
- if ((hr = write_grow_buffer( writer, xmlbuf->size )) != S_OK) return hr;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if ((hr = write_flush( writer )) != S_OK) goto done;
+ if ((hr = write_grow_buffer( writer, xmlbuf->size )) != S_OK) goto done;
write_bytes( writer, xmlbuf->ptr, xmlbuf->size );
+
+done:
+ LeaveCriticalSection( &writer->cs );
return S_OK;
}
@@ -2408,7 +2689,7 @@ HRESULT WINAPI WsWriteXmlBufferToBytes( WS_XML_WRITER *handle, WS_XML_BUFFER *bu
{
struct writer *writer = (struct writer *)handle;
struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer;
- HRESULT hr;
+ HRESULT hr = S_OK;
char *buf;
ULONG i;
@@ -2424,18 +2705,32 @@ HRESULT WINAPI WsWriteXmlBufferToBytes( WS_XML_WRITER *handle, WS_XML_BUFFER *bu
return E_NOTIMPL;
}
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
for (i = 0; i < count; i++)
{
hr = prop_set( writer->prop, writer->prop_count, properties[i].id, properties[i].value,
properties[i].valueSize );
- if (hr != S_OK) return hr;
+ if (hr != S_OK) goto done;
}
- if (!(buf = ws_alloc( heap, xmlbuf->size ))) return WS_E_QUOTA_EXCEEDED;
- memcpy( buf, xmlbuf->ptr, xmlbuf->size );
- *bytes = buf;
- *size = xmlbuf->size;
- return S_OK;
+ if (!(buf = ws_alloc( heap, xmlbuf->size ))) hr = WS_E_QUOTA_EXCEEDED;
+ else
+ {
+ memcpy( buf, xmlbuf->ptr, xmlbuf->size );
+ *bytes = buf;
+ *size = xmlbuf->size;
+ }
+
+done:
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
/**************************************************************************
@@ -2445,16 +2740,33 @@ HRESULT WINAPI WsWriteXmlnsAttribute( WS_XML_WRITER *handle, const WS_XML_STRING
const WS_XML_STRING *ns, BOOL single, WS_ERROR *error )
{
struct writer *writer = (struct writer *)handle;
+ HRESULT hr = S_OK;
TRACE( "%p %s %s %d %p\n", handle, debugstr_xmlstr(prefix), debugstr_xmlstr(ns),
single, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!writer || !ns) return E_INVALIDARG;
- if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;
- if (namespace_in_scope( &writer->current->hdr, prefix, ns )) return S_OK;
- return write_add_namespace_attribute( writer, prefix, ns, single );
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (writer->state != WRITER_STATE_STARTELEMENT)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ if (!namespace_in_scope( &writer->current->hdr, prefix, ns ))
+ hr = write_add_namespace_attribute( writer, prefix, ns, single );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static HRESULT write_move_to( struct writer *writer, WS_MOVE_TO move, BOOL *found )
@@ -2534,14 +2846,31 @@ static HRESULT write_move_to( struct writer *writer, WS_MOVE_TO move, BOOL *foun
HRESULT WINAPI WsMoveWriter( WS_XML_WRITER *handle, WS_MOVE_TO move, BOOL *found, WS_ERROR *error )
{
struct writer *writer = (struct writer *)handle;
+ HRESULT hr;
TRACE( "%p %u %p %p\n", handle, move, found, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!writer) return E_INVALIDARG;
- if (!writer->output_type) return WS_E_INVALID_OPERATION;
- return write_move_to( writer, move, found );
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!writer->output_type)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ hr = write_move_to( writer, move, found );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
/**************************************************************************
@@ -2555,10 +2884,25 @@ HRESULT WINAPI WsGetWriterPosition( WS_XML_WRITER *handle, WS_XML_NODE_POSITION
if (error) FIXME( "ignoring error parameter\n" );
if (!writer || !pos) return E_INVALIDARG;
- if (!writer->output_type) return WS_E_INVALID_OPERATION;
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!writer->output_type)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
pos->buffer = (WS_XML_BUFFER *)writer->output_buf;
pos->node = writer->current;
+
+ LeaveCriticalSection( &writer->cs );
return S_OK;
}
@@ -2572,10 +2916,25 @@ HRESULT WINAPI WsSetWriterPosition( WS_XML_WRITER *handle, const WS_XML_NODE_POS
TRACE( "%p %p %p\n", handle, pos, error );
if (error) FIXME( "ignoring error parameter\n" );
- if (!writer || !pos || (struct xmlbuf *)pos->buffer != writer->output_buf) return E_INVALIDARG;
- if (!writer->output_type) return WS_E_INVALID_OPERATION;
+ if (!writer || !pos) return E_INVALIDARG;
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC || (struct xmlbuf *)pos->buffer != writer->output_buf)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!writer->output_type)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
writer->current = pos->node;
+
+ LeaveCriticalSection( &writer->cs );
return S_OK;
}
@@ -2683,14 +3042,31 @@ static HRESULT write_node( struct writer *writer, const WS_XML_NODE *node )
HRESULT WINAPI WsWriteNode( WS_XML_WRITER *handle, const WS_XML_NODE *node, WS_ERROR *error )
{
struct writer *writer = (struct writer *)handle;
+ HRESULT hr;
TRACE( "%p %p %p\n", handle, node, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!writer || !node) return E_INVALIDARG;
- if (!writer->output_type) return WS_E_INVALID_OPERATION;
- return write_node( writer, node );
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!writer->output_type)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ hr = write_node( writer, node );
+
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static HRESULT write_tree_node( struct writer *writer )
@@ -2788,23 +3164,39 @@ static void write_rewind( struct writer *writer )
HRESULT WINAPI WsCopyNode( WS_XML_WRITER *handle, WS_XML_READER *reader, WS_ERROR *error )
{
struct writer *writer = (struct writer *)handle;
- struct node *parent, *current = writer->current, *node = NULL;
+ struct node *parent, *current, *node = NULL;
HRESULT hr;
TRACE( "%p %p %p\n", handle, reader, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!writer) return E_INVALIDARG;
- if (!(parent = find_parent( writer ))) return WS_E_INVALID_FORMAT;
- if ((hr = copy_node( reader, &node )) != S_OK) return hr;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!(parent = find_parent( writer )))
+ {
+ LeaveCriticalSection( &writer->cs );
+ return WS_E_INVALID_FORMAT;
+ }
+
+ if ((hr = copy_node( reader, &node )) != S_OK) goto done;
+ current = writer->current;
write_insert_node( writer, parent, node );
write_rewind( writer );
- if ((hr = write_tree( writer )) != S_OK) return hr;
-
+ if ((hr = write_tree( writer )) != S_OK) goto done;
writer->current = current;
- return S_OK;
+
+done:
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
static HRESULT write_param( struct writer *writer, const WS_FIELD_DESCRIPTION *desc, const void *value )
@@ -2842,7 +3234,15 @@ HRESULT write_input_params( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION
if (desc->type != WS_STRUCT_TYPE || !(desc_struct = desc->typeDescription)) return E_INVALIDARG;
- if ((hr = write_element_node( writer, NULL, desc->elementLocalName, desc->elementNs )) != S_OK) return hr;
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ if ((hr = write_element_node( writer, NULL, desc->elementLocalName, desc->elementNs )) != S_OK) goto done;
for (i = 0; i < count; i++)
{
@@ -2850,20 +3250,25 @@ HRESULT write_input_params( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION
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].inputMessageIndex, &desc_field )) != S_OK) return hr;
+ 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) return hr;
+ if ((hr = write_param( writer, desc_field, args[i] )) != 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 );
- if ((hr = write_param_array( writer, desc_field, ptr, len )) != S_OK) return hr;
+ if ((hr = write_param_array( writer, desc_field, ptr, len )) != S_OK) goto done;
}
}
- return write_endelement_node( writer );
+ hr = write_endelement_node( writer );
+
+done:
+ LeaveCriticalSection( &writer->cs );
+ return hr;
}
--
2.1.4
More information about the wine-patches
mailing list