diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 0cfc844275c..85a6dc90baa 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -407,25 +407,6 @@ static void clear_prefixes( struct prefix *prefixes, ULONG count )
}
}
-HRESULT copy_node( WS_XML_READER *handle, struct node **node )
-{
- struct reader *reader = (struct reader *)handle;
- 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 )
{
if (str)
@@ -1654,6 +1635,44 @@ static HRESULT read_node( struct reader *reader )
}
}
+HRESULT copy_node( WS_XML_READER *handle, struct node **node )
+{
+ struct reader *reader = (struct reader *)handle;
+ const struct list *ptr;
+ const struct node *start;
+ HRESULT hr;
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ if (reader->current != reader->root) ptr = &reader->current->entry;
+ else /* copy whole tree */
+ {
+ if (!read_end_of_data( reader ))
+ {
+ for (;;)
+ {
+ if ((hr = read_node( reader )) != S_OK) goto done;
+ if (node_type( reader->current ) == WS_XML_NODE_TYPE_EOF) break;
+ }
+ }
+ ptr = list_head( &reader->root->children );
+ }
+
+ start = LIST_ENTRY( ptr, struct node, entry );
+ if (node_type( start ) == WS_XML_NODE_TYPE_EOF) hr = WS_E_INVALID_OPERATION;
+ else hr = dup_tree( node, start );
+
+done:
+ LeaveCriticalSection( &reader->cs );
+ return hr;
+}
+
/**************************************************************************
* WsReadEndElement [webservices.@]
*/
diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c
index 531976999cc..5c865950f31 100644
--- a/dlls/webservices/tests/writer.c
+++ b/dlls/webservices/tests/writer.c
@@ -2003,6 +2003,41 @@ static void test_WsCopyNode(void)
ok( hr == S_OK, "got %08x\n", hr );
ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
+ /* reader positioned at EOF */
+ hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsCopyNode( writer, reader, NULL );
+ ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
+ /* reader positioned at BOF */
+ hr = set_input( reader, "", sizeof("") - 1 );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsFillReader( reader, sizeof("") - 1, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsGetReaderNode( reader, &node, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType );
+
+ hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsCopyNode( writer, reader, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ check_output_buffer( buffer, "", __LINE__ );
+
+ hr = WsGetReaderNode( reader, &node, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
+
WsFreeReader( reader );
WsFreeWriter( writer );
WsFreeHeap( heap );