[3/8] webservices: Implement WsGetHeader.

Hans Leidekker hans at codeweavers.com
Tue Jun 6 02:55:56 CDT 2017


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/msg.c                 |  63 ++++++++++++++++++++
 dlls/webservices/reader.c              |  22 +++++++
 dlls/webservices/tests/msg.c           | 105 +++++++++++++++++++++++++++++++++
 dlls/webservices/webservices.spec      |   2 +-
 dlls/webservices/webservices_private.h |   2 +
 5 files changed, 193 insertions(+), 1 deletion(-)

diff --git a/dlls/webservices/msg.c b/dlls/webservices/msg.c
index 156060d50d..6d61aa066a 100644
--- a/dlls/webservices/msg.c
+++ b/dlls/webservices/msg.c
@@ -1081,6 +1081,69 @@ done:
     return hr;
 }
 
+static HRESULT get_standard_header( struct msg *msg, WS_HEADER_TYPE type, WS_TYPE value_type,
+                                    WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size )
+{
+    const WS_XML_STRING *localname = get_header_name( type );
+    const WS_XML_STRING *ns = get_addr_namespace( msg->version_addr );
+    const WS_XML_ELEMENT_NODE *elem;
+    const WS_XML_NODE *node;
+    HRESULT hr;
+
+    if (!heap) heap = msg->heap;
+    if (!msg->reader && (hr = WsCreateReader( NULL, 0, &msg->reader, NULL )) != S_OK) return hr;
+    if ((hr = WsSetInputToBuffer( msg->reader, msg->buf, NULL, 0, NULL )) != S_OK) return hr;
+
+    for (;;)
+    {
+        if ((hr = WsReadNode( msg->reader, NULL )) != S_OK) return hr;
+        if ((hr = WsGetReaderNode( msg->reader, &node, NULL )) != S_OK) return hr;
+        if (node->nodeType == WS_XML_NODE_TYPE_EOF) return WS_E_INVALID_FORMAT;
+        if (node->nodeType != WS_XML_NODE_TYPE_ELEMENT) continue;
+
+        elem = (const WS_XML_ELEMENT_NODE *)node;
+        if (WsXmlStringEquals( elem->localName, localname, NULL ) == S_OK &&
+            WsXmlStringEquals( elem->ns, ns, NULL ) == S_OK) break;
+    }
+
+    return read_header( msg->reader, localname, ns, value_type, NULL, option, heap, value, size );
+}
+
+/**************************************************************************
+ *          WsGetHeader		[webservices.@]
+ */
+HRESULT WINAPI WsGetHeader( WS_MESSAGE *handle, WS_HEADER_TYPE type, WS_TYPE value_type, WS_READ_OPTION option,
+                            WS_HEAP *heap, void *value, ULONG size, WS_ERROR *error )
+{
+    struct msg *msg = (struct msg *)handle;
+    HRESULT hr;
+
+    TRACE( "%p %u %u %08x %p %p %u %p\n", handle, type, value_type, option, heap, value, size, error );
+    if (error) FIXME( "ignoring error parameter\n" );
+
+    if (!msg || type < WS_ACTION_HEADER || type > WS_FAULT_TO_HEADER || option < WS_READ_REQUIRED_VALUE ||
+        option > WS_READ_OPTIONAL_POINTER) return E_INVALIDARG;
+
+    EnterCriticalSection( &msg->cs );
+
+    if (msg->magic != MSG_MAGIC)
+    {
+        LeaveCriticalSection( &msg->cs );
+        return E_INVALIDARG;
+    }
+
+    if (msg->state < WS_MESSAGE_STATE_INITIALIZED)
+    {
+        LeaveCriticalSection( &msg->cs );
+        return WS_E_INVALID_OPERATION;
+    }
+
+    hr = get_standard_header( msg, type, value_type, option, heap, value, size );
+
+    LeaveCriticalSection( &msg->cs );
+    return hr;
+}
+
 static void remove_header( struct msg *msg, ULONG i )
 {
     free_header( msg->header[i] );
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index d59de3bad0..7c0a2eb3fa 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -5242,6 +5242,28 @@ HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TY
     return hr;
 }
 
+HRESULT read_header( WS_XML_READER *handle, const WS_XML_STRING *localname, const WS_XML_STRING *ns,
+                     WS_TYPE type, const void *desc, WS_READ_OPTION option, WS_HEAP *heap, void *value,
+                     ULONG size )
+{
+    struct reader *reader = (struct reader *)handle;
+    HRESULT hr;
+
+    EnterCriticalSection( &reader->cs );
+
+    if (reader->magic != READER_MAGIC)
+    {
+        LeaveCriticalSection( &reader->cs );
+        return E_INVALIDARG;
+    }
+
+    hr = read_type( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, type, localname, ns, desc, option, heap,
+                    value, size );
+
+    LeaveCriticalSection( &reader->cs );
+    return hr;
+}
+
 /**************************************************************************
  *          WsReadElement		[webservices.@]
  */
diff --git a/dlls/webservices/tests/msg.c b/dlls/webservices/tests/msg.c
index 4d25265930..4b33b55163 100644
--- a/dlls/webservices/tests/msg.c
+++ b/dlls/webservices/tests/msg.c
@@ -1164,6 +1164,110 @@ static void test_WsResetMessage(void)
     WsFreeMessage( msg );
 }
 
+static void test_WsGetHeader(void)
+{
+    static char expected[] =
+        "<s:Envelope xmlns:a=\"http://www.w3.org/2005/08/addressing\" "
+        "xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header>"
+        "<a:MessageID>urn:uuid:00000000-0000-0000-0000-000000000000</a:MessageID>"
+        "<a:Action s:mustUnderstand=\"1\">action</a:Action></s:Header><s:Body/></s:Envelope>";
+    static char expected2[] =
+        "<Envelope><Header><Action mustUnderstand=\"1\" "
+        "xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">action</Action>"
+        "</Header><Body/></Envelope>";
+    static char expected3[] =
+        "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header>"
+        "<Action s:mustUnderstand=\"1\" "
+        "xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">action</Action>"
+        "</s:Header><s:Body/></s:Envelope>";
+    static WCHAR action[] = {'a','c','t','i','o','n',0};
+    WS_MESSAGE *msg;
+    WCHAR *ptr;
+    HRESULT hr;
+
+    hr = WsGetHeader( NULL, 0, 0, 0, NULL, NULL, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsCreateMessage( WS_ENVELOPE_VERSION_SOAP_1_2, WS_ADDRESSING_VERSION_1_0, NULL, 0, &msg, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsGetHeader( msg, 0, 0, 0, NULL, NULL, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsInitializeMessage( msg,  WS_REQUEST_MESSAGE, NULL, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsGetHeader( msg, 0, 0, 0, NULL, NULL, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsGetHeader( msg, WS_ACTION_HEADER, 0, 0, NULL, NULL, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsGetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, 0, NULL, NULL, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsGetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_READ_NILLABLE_POINTER, NULL, NULL, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    hr = WsGetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_READ_REQUIRED_POINTER, NULL, NULL, 0, NULL );
+    ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
+
+    ptr = action;
+    hr = WsSetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_WRITE_REQUIRED_POINTER, &ptr, sizeof(ptr), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    check_output_header( msg, expected, -1, strstr(expected, "urn:uuid:") - expected, 46, __LINE__ );
+
+    hr = WsGetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_READ_REQUIRED_POINTER, NULL, NULL, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    ptr = NULL;
+    hr = WsGetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_READ_REQUIRED_POINTER, NULL, &ptr, 0, NULL );
+    ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+    ptr = NULL;
+    hr = WsGetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_READ_REQUIRED_POINTER, NULL, &ptr, sizeof(ptr), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ptr != NULL, "ptr not set\n" );
+    ok( !memcmp( ptr, action, sizeof(action) ), "wrong data\n" );
+    WsFreeMessage( msg );
+
+    hr = WsCreateMessage( WS_ENVELOPE_VERSION_NONE, WS_ADDRESSING_VERSION_TRANSPORT, NULL, 0, &msg, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsInitializeMessage( msg,  WS_REQUEST_MESSAGE, NULL, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    ptr = action;
+    hr = WsSetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_WRITE_REQUIRED_POINTER, &ptr, sizeof(ptr), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    if (hr == S_OK) check_output_header( msg, expected2, -1, 0, 0, __LINE__ );
+
+    ptr = NULL;
+    hr = WsGetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_READ_REQUIRED_POINTER, NULL, &ptr, sizeof(ptr), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ptr != NULL, "ptr not set\n" );
+    ok( !memcmp( ptr, action, sizeof(action) ), "wrong data\n" );
+    WsFreeMessage( msg );
+
+    hr = WsCreateMessage( WS_ENVELOPE_VERSION_SOAP_1_2, WS_ADDRESSING_VERSION_TRANSPORT, NULL, 0, &msg, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsInitializeMessage( msg,  WS_REQUEST_MESSAGE, NULL, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    ptr = action;
+    hr = WsSetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_WRITE_REQUIRED_POINTER, &ptr, sizeof(ptr), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    if (hr == S_OK) check_output_header( msg, expected3, -1, 0, 0, __LINE__ );
+
+    ptr = NULL;
+    hr = WsGetHeader( msg, WS_ACTION_HEADER, WS_WSZ_TYPE, WS_READ_REQUIRED_POINTER, NULL, &ptr, sizeof(ptr), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( ptr != NULL, "ptr not set\n" );
+    ok( !memcmp( ptr, action, sizeof(action) ), "wrong data\n" );
+    WsFreeMessage( msg );
+}
+
 START_TEST(msg)
 {
     test_WsCreateMessage();
@@ -1183,4 +1287,5 @@ START_TEST(msg)
     test_WsReadEnvelopeEnd();
     test_WsReadBody();
     test_WsResetMessage();
+    test_WsGetHeader();
 }
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index c88935aa75..b6f246c417 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -66,7 +66,7 @@
 @ stdcall WsGetErrorString(ptr long ptr)
 @ stub WsGetFaultErrorDetail
 @ stub WsGetFaultErrorProperty
-@ stub WsGetHeader
+@ stdcall WsGetHeader(ptr long long long ptr ptr long ptr)
 @ stub WsGetHeaderAttributes
 @ stdcall WsGetHeapProperty(ptr long ptr long ptr)
 @ stdcall WsGetListenerProperty(ptr long ptr long ptr)
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index db839b447a..30bce24d6b 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -45,6 +45,8 @@ BOOL set_fpword( unsigned short, unsigned short * ) DECLSPEC_HIDDEN;
 void restore_fpword( unsigned short ) DECLSPEC_HIDDEN;
 HRESULT set_output( WS_XML_WRITER * ) DECLSPEC_HIDDEN;
 ULONG get_type_size( WS_TYPE, const WS_STRUCT_DESCRIPTION * ) DECLSPEC_HIDDEN;
+HRESULT read_header( WS_XML_READER *, const WS_XML_STRING *, const WS_XML_STRING *, WS_TYPE,
+                     const void *, WS_READ_OPTION, WS_HEAP *, void *, ULONG ) DECLSPEC_HIDDEN;
 
 #define INVALID_PARAMETER_INDEX 0xffff
 HRESULT get_param_desc( const WS_STRUCT_DESCRIPTION *, USHORT, const WS_FIELD_DESCRIPTION ** ) DECLSPEC_HIDDEN;
-- 
2.11.0




More information about the wine-patches mailing list