wsdapi: Populate SOAP header structure.
[wine.git] / dlls / wsdapi / soap.c
blobc33c73ba252da36e6bdcc43c9d8f632d26e0ecdc
1 /*
2 * Web Services on Devices
4 * Copyright 2017-2018 Owen Rudge for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <limits.h>
24 #define COBJMACROS
26 #include "wsdapi_internal.h"
27 #include "wine/debug.h"
28 #include "wine/heap.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(wsdapi);
32 #define APP_MAX_DELAY 500
34 static const WCHAR discoveryTo[] = {
35 'u','r','n',':',
36 's','c','h','e','m','a','s','-','x','m','l','s','o','a','p','-','o','r','g',':',
37 'w','s',':','2','0','0','5',':','0','4',':',
38 'd','i','s','c','o','v','e','r','y', 0 };
40 static const WCHAR actionHello[] = {
41 'h','t','t','p',':','/','/',
42 's','c','h','e','m','a','s','.','x','m','l','s','o','a','p','.','o','r','g','/',
43 'w','s','/','2','0','0','5','/','0','4','/',
44 'd','i','s','c','o','v','e','r','y','/',
45 'H','e','l','l','o', 0 };
47 static BOOL create_guid(LPWSTR buffer)
49 const WCHAR formatString[] = { 'u','r','n',':','u','u','i','d',':','%','s', 0 };
51 WCHAR* uuidString = NULL;
52 UUID uuid;
54 if (UuidCreate(&uuid) != RPC_S_OK)
55 return FALSE;
57 UuidToStringW(&uuid, (RPC_WSTR*)&uuidString);
59 if (uuidString == NULL)
60 return FALSE;
62 wsprintfW(buffer, formatString, uuidString);
63 RpcStringFreeW((RPC_WSTR*)&uuidString);
65 return TRUE;
68 static void populate_soap_header(WSD_SOAP_HEADER *header, LPCWSTR to, LPCWSTR action, LPCWSTR message_id,
69 WSD_APP_SEQUENCE *sequence, const WSDXML_ELEMENT *any_headers)
71 ZeroMemory(header, sizeof(WSD_SOAP_HEADER));
73 header->To = to;
74 header->Action = action;
75 header->MessageID = message_id;
76 header->AppSequence = sequence;
77 header->AnyHeaders = (WSDXML_ELEMENT *)any_headers;
79 /* TODO: Implement RelatesTo, ReplyTo, From, FaultTo */
82 static HRESULT write_and_send_message(IWSDiscoveryPublisherImpl *impl, WSD_SOAP_HEADER *header, WSDXML_ELEMENT *body_element,
83 struct list *discovered_namespaces, IWSDUdpAddress *remote_address, int max_initial_delay)
85 static const char xml_header[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
86 ULONG xml_header_len = sizeof(xml_header) - 1;
87 HRESULT ret = E_FAIL;
88 char *full_xml;
90 /* TODO: Create SOAP envelope */
92 /* Prefix the XML header */
93 full_xml = heap_alloc(xml_header_len + 1);
95 if (full_xml == NULL)
96 return E_OUTOFMEMORY;
98 memcpy(full_xml, xml_header, xml_header_len);
99 full_xml[xml_header_len] = 0;
101 if (remote_address == NULL)
103 /* Send the message via UDP multicast */
104 if (send_udp_multicast(impl, full_xml, sizeof(xml_header), max_initial_delay))
105 ret = S_OK;
107 else
109 /* TODO: Send the message via UDP unicast */
110 FIXME("TODO: Send the message via UDP unicast\n");
113 heap_free(full_xml);
115 return ret;
118 HRESULT send_hello_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR id, ULONGLONG metadata_ver, ULONGLONG instance_id,
119 ULONGLONG msg_num, LPCWSTR session_id, const WSD_NAME_LIST *types_list, const WSD_URI_LIST *scopes_list,
120 const WSD_URI_LIST *xaddrs_list, const WSDXML_ELEMENT *hdr_any, const WSDXML_ELEMENT *ref_param_any,
121 const WSDXML_ELEMENT *endpoint_ref_any, const WSDXML_ELEMENT *any)
123 WSD_SOAP_HEADER soapHeader;
124 WSD_APP_SEQUENCE sequence;
125 WCHAR message_id[64];
126 HRESULT ret = E_OUTOFMEMORY;
128 sequence.InstanceId = instance_id;
129 sequence.MessageNumber = msg_num;
130 sequence.SequenceId = session_id;
132 if (!create_guid(message_id)) goto cleanup;
134 populate_soap_header(&soapHeader, discoveryTo, actionHello, message_id, &sequence, hdr_any);
136 /* TODO: Populate message body */
138 /* Write and send the message */
139 ret = write_and_send_message(impl, &soapHeader, NULL, NULL, NULL, APP_MAX_DELAY);
141 cleanup:
142 return ret;