From: Owen Rudge Subject: [PATCH 6/7] wsdapi: Add support for building types, scopes and xaddrs lists. Message-Id: <4634a7a6-6f4e-03ae-3ed4-c5cacbb4788f@codeweavers.com> Date: Tue, 21 Nov 2017 22:42:54 +0000 Signed-off-by: Owen Rudge --- dlls/wsdapi/soap.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/dlls/wsdapi/soap.c b/dlls/wsdapi/soap.c index 224bc60241..30c0657d9c 100644 --- a/dlls/wsdapi/soap.c +++ b/dlls/wsdapi/soap.c @@ -60,6 +60,9 @@ static const WCHAR bodyString[] = { 'B','o','d','y', 0 }; static const WCHAR helloString[] = { 'H','e','l','l','o', 0 }; static const WCHAR endpointReferenceString[] = { 'E','n','d','p','o','i','n','t','R','e','f','e','r','e','n','c','e', 0 }; static const WCHAR addressString[] = { 'A','d','d','r','e','s','s', 0 }; +static const WCHAR typesString[] = { 'T','y','p','e','s', 0 }; +static const WCHAR scopesString[] = { 'S','c','o','p','e','s', 0 }; +static const WCHAR xAddrsString[] = { 'X','A','d','d','r','s', 0 }; struct discovered_namespace { @@ -115,6 +118,67 @@ static BOOL create_guid(LPWSTR buffer) return TRUE; } +static BOOL build_types_list(LPWSTR buffer, int bufferSizeInBytes, const WSD_NAME_LIST *list) +{ + WCHAR formatString[] = { '%','s',':','%','s',' ', 0 }; + const WSD_NAME_LIST *cur = list; + LPWSTR curBufferPos = buffer; + int memoryNeeded = 0; + + ZeroMemory(buffer, bufferSizeInBytes); + + while (cur != NULL) + { + /* Calculate space needed, including NULL character, colon and potential trailing space */ + memoryNeeded = sizeof(WCHAR) * (lstrlenW(cur->Element->LocalName) + lstrlenW(cur->Element->Space->PreferredPrefix) + 3); + + if (curBufferPos + memoryNeeded > buffer + bufferSizeInBytes) + return FALSE; + + curBufferPos += wsprintfW(curBufferPos, formatString, cur->Element->Space->PreferredPrefix, cur->Element->LocalName); + cur = cur->Next; + } + + /* Remove the last trailing space */ + curBufferPos--; + *curBufferPos = 0; + + return TRUE; +} + +static BOOL build_uri_list(LPWSTR buffer, int bufferSizeInBytes, const WSD_URI_LIST *list) +{ + int memoryNeeded = 0, stringLen = 0; + const WSD_URI_LIST *cur = list; + LPWSTR curBufferPos = buffer; + + ZeroMemory(buffer, bufferSizeInBytes); + + while (cur != NULL) + { + /* Calculate space needed, including trailing space */ + stringLen = lstrlenW(cur->Element); + memoryNeeded = (stringLen + 1) * sizeof(WCHAR); + + if (curBufferPos + memoryNeeded > buffer + bufferSizeInBytes) + return FALSE; + + memcpy(curBufferPos, cur->Element, memoryNeeded); + curBufferPos += stringLen; + + *curBufferPos = ' '; + curBufferPos++; + + cur = cur->Next; + } + + /* Remove the last trailing space */ + curBufferPos--; + *curBufferPos = 0; + + return TRUE; +} + void populate_soap_header(WSD_SOAP_HEADER *header, LPCWSTR to, LPCWSTR action, LPCWSTR messageId, WSD_APP_SEQUENCE *sequence, const WSDXML_ELEMENT *anyHeaders) { @@ -241,6 +305,7 @@ HRESULT send_hello_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR pszId, ULONG WSD_SOAP_HEADER soapHeader; WSD_APP_SEQUENCE sequence; WCHAR messageId[64]; + LPWSTR buffer; HRESULT ret = E_OUTOFMEMORY; FIXME("stub\n"); @@ -278,6 +343,42 @@ HRESULT send_hello_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR pszId, ULONG if (duplicate_element(endpointReferenceElement, pEndpointReferenceAny, discoveredNamespaces) == NULL) goto cleanup; } + /* */ + if (pTypesList != NULL) + { + buffer = WSDAllocateLinkedMemory(helloElement, WSD_MAX_TEXT_LENGTH * sizeof(WCHAR)); + if (buffer == NULL) goto cleanup; + + if (!build_types_list(buffer, WSD_MAX_TEXT_LENGTH * sizeof(WCHAR), pTypesList)) + WARN("pTypesList exceeds WSD_MAX_TEXT_LENGTH; may be incomplete.\n"); + + if (add_child_element(impl->xmlContext, helloElement, discoveryNsUri, typesString, buffer) == NULL) goto cleanup; + } + + /* */ + if (pScopesList != NULL) + { + buffer = WSDAllocateLinkedMemory(helloElement, WSD_MAX_TEXT_LENGTH * sizeof(WCHAR)); + if (buffer == NULL) goto cleanup; + + if (!build_uri_list(buffer, WSD_MAX_TEXT_LENGTH * sizeof(WCHAR), pScopesList)) + WARN("pScopesList exceeds WSD_MAX_TEXT_LENGTH; may be incomplete.\n"); + + if (add_child_element(impl->xmlContext, helloElement, discoveryNsUri, scopesString, buffer) == NULL) goto cleanup; + } + + /* */ + if (pXAddrsList != NULL) + { + buffer = WSDAllocateLinkedMemory(helloElement, WSD_MAX_TEXT_LENGTH * sizeof(WCHAR)); + if (buffer == NULL) goto cleanup; + + if (!build_uri_list(buffer, WSD_MAX_TEXT_LENGTH * sizeof(WCHAR), pXAddrsList)) + WARN("pXAddrsList exceeds WSD_MAX_TEXT_LENGTH; may be incomplete.\n"); + + if (add_child_element(impl->xmlContext, helloElement, discoveryNsUri, xAddrsString, buffer) == NULL) goto cleanup; + } + ret = E_NOTIMPL; cleanup: