Microsoft Developer Network >
Forums Home
>
Windows Networking Development Forums
>
Windows Web Services API
>
How do we use WWSAPI generated functions that have a WS_XML_BUFFER* because of a 'fallback'?
How do we use WWSAPI generated functions that have a WS_XML_BUFFER* because of a 'fallback'?
- Hi,
I have a wsutil generated header file that 'fell back' to using the WS_XML_BUFFER, does anyone know how we are to generate these buffers for 'fall back' generated functions...
// operation: DLLogonSoap_ValidateLogon HRESULT WINAPI DLLogonSoap_ValidateLogon( __in WS_SERVICE_PROXY* _serviceProxy, __in_opt __nullterminated WCHAR* sCurrentSessionID, __in WS_XML_BUFFER* LogonFlags, __out int* ValidateLogonResult, __in WS_HEAP* _heap, __in_ecount_opt(_callPropertyCount) const WS_CALL_PROPERTY* _callProperties, __in const ULONG _callPropertyCount, __in_opt const WS_ASYNC_CONTEXT* _asyncContext, __in_opt WS_ERROR* _error);the LogonFlags parameter is a simple type...
<s:element name="ValidateLogon"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="sCurrentSessionID" type="s:string" /> <s:element minOccurs="1" maxOccurs="1" name="LogonFlags" type="tns:LogonType" /> </s:sequence> </s:complexType> </s:element> <s:simpleType name="LogonType"> <s:list> <s:simpleType> <s:restriction base="s:string"> <s:enumeration value="ClientSideSSL" /> <s:enumeration value="GoodPassword" /> <s:enumeration value="OkPassword" /> <s:enumeration value="NoPassword" /> <s:enumeration value="Guest" /> <s:enumeration value="UnknownORFlag6" /> <s:enumeration value="UnknownORFlag7" /> <s:enumeration value="UnknownORFlag8" /> <s:enumeration value="UnknownORFlag9" /> <s:enumeration value="UnknownORFlag10" /> <s:enumeration value="UnknownORFlag11" /> <s:enumeration value="UnknownORFlag12" /> <s:enumeration value="UnknownORFlag13" /> <s:enumeration value="UnknownORFlag14" /> <s:enumeration value="UnknownORFlag15" /> <s:enumeration value="UnknownORFlag16" /> <s:enumeration value="TrustedConsumer" /> <s:enumeration value="UnknownANDFlag2" /> <s:enumeration value="UnknownANDFlag3" /> <s:enumeration value="UnknownANDFlag4" /> <s:enumeration value="UnknownANDFlag5" /> <s:enumeration value="UnknownANDFlag6" /> <s:enumeration value="UnknownANDFlag7" /> <s:enumeration value="UnknownANDFlag8" /> <s:enumeration value="UnknownANDFlag9" /> <s:enumeration value="UnknownANDFlag10" /> <s:enumeration value="UnknownANDFlag11" /> <s:enumeration value="UnknownANDFlag12" /> <s:enumeration value="UnknownANDFlag13" /> <s:enumeration value="UnknownANDFlag14" /> </s:restriction> </s:simpleType> </s:list> </s:simpleType> <s:element name="ValidateLogonResponse"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="ValidateLogonResult" type="s:int" /> </s:sequence> </s:complexType> </s:element>
I just can't find any examples of how to use these WS_XML_BUFFER's when the generated function 'falls back' to these types?
Any help appreciated.
Answers
- Hi hegsie,
The root cause for the issue is the Flags attributes set for this enumeration type on the .Net side. You should see [Flags] attribute in the contract definition in your .Net code. The problem with this type is that C language does not have any good representation for this type. We have been thinking about several possible solutions, but at the end decided to just fallback to WS_XML_BUFFER type. In the message you can expect something like "<XML> ClientSideSSL GoodPassword UnknownANDFlag14 </XML>" or similar combination of values. You can get the string from the XML buffer using WsReadChars(), for example, and tokenize it to get the value out of it.
Regards,
Nikola
Nikola Dudar is the Program Manager for Windows Web Services API team. This post is provided "AS IS" with no warranties, and confer no rights. Use of any samples is subject to the terms specified at http://www.microsoft.com/ info/cpyright.htm- Marked As Answer byhegsie Friday, August 21, 2009 3:46 PM
All Replies
- Strange that it couldn't handle an enum. You can try WS_XML_WRITER/WsCreateWriter etc. to write to the buffer.
http://blog.voidnish.com - Any ideas on what the structure looks like for the xml?
- Hi hegsie,
The root cause for the issue is the Flags attributes set for this enumeration type on the .Net side. You should see [Flags] attribute in the contract definition in your .Net code. The problem with this type is that C language does not have any good representation for this type. We have been thinking about several possible solutions, but at the end decided to just fallback to WS_XML_BUFFER type. In the message you can expect something like "<XML> ClientSideSSL GoodPassword UnknownANDFlag14 </XML>" or similar combination of values. You can get the string from the XML buffer using WsReadChars(), for example, and tokenize it to get the value out of it.
Regards,
Nikola
Nikola Dudar is the Program Manager for Windows Web Services API team. This post is provided "AS IS" with no warranties, and confer no rights. Use of any samples is subject to the terms specified at http://www.microsoft.com/ info/cpyright.htm- Marked As Answer byhegsie Friday, August 21, 2009 3:46 PM
- Nikola,
What are the issues if you ignore the Flags attribute and treat it as a normal enum when generating the native equivalent?
http://blog.voidnish.com - Cheers Nikola,I'll give this a whirl tomorrow and let you know how I go..Regardshegsie
- Hi,
So I tried to use the following but I'm still a bit perplexed about where I get the WS_XML_BUFFER from...
WS_XML_BUFFER* xmlBuffer = NULL; WS_XML_WRITER* xmlWriter = NULL; WS_XML_READER* reader = NULL; WS_XML_STRING arrayElement = WS_XML_STRING_VALUE("XML"); WS_XML_STRING emptyNamespace = WS_XML_STRING_VALUE(""); WS_XML_WRITER_BUFFER_OUTPUT bufferOutput; ZeroMemory(&bufferOutput, sizeof(bufferOutput)); bufferOutput.output.outputType = WS_XML_WRITER_OUTPUT_TYPE_BUFFER; WS_XML_WRITER_TEXT_ENCODING writerTextEncoding; ZeroMemory(&writerTextEncoding, sizeof(writerTextEncoding)); writerTextEncoding.encoding.encodingType = WS_XML_WRITER_ENCODING_TYPE_TEXT; writerTextEncoding.charSet = WS_CHARSET_UTF8; // Create an XML writer hr = WsCreateWriter( NULL, 0, &xmlWriter, error); hr = WsSetOutput(xmlWriter, &writerTextEncoding.encoding, &bufferOutput.output, NULL, 0, error); hr = WsWriteStartElement(xmlWriter, NULL, &arrayElement, &emptyNamespace, error); // Create an XML reader hr = WsCreateReader( NULL, 0, &reader, error); hr = WsWriteChars(xmlWriter,L"GoodPassword",1,error); hr = WsWriteEndElement(xmlWriter, error); WS_BYTES buffer; hr = WsGetWriterProperty(xmlWriter, WS_XML_WRITER_PROPERTY_BYTES, &buffer, sizeof(buffer), error); // Read the xml into a WS_XML_BUFFER hr = WsReadXmlBuffer( reader, heap, &xmlBuffer, error); if (FAILED(hr)) { // Print out the error PrintError(hr, error); } WS_HTTP_BINDING_TEMPLATE templ = {}; hr = DLLogonSoap_CreateServiceProxy(&templ,NULL,0, &proxy,error); hr = WsOpenServiceProxy(proxy, &address, NULL, error); int result = 0; hr = DLLogonSoap_ValidateLogon(proxy,(WCHAR*)wLoginGUID.c_str(),xmlBuffer,&result,heap,NULL,0,NULL,error);
but the WsReadXmlBuffer always fails, is there another way to get the WS_XML_BUFFER or am I completely of track? - There is a sample in the SDK :
Windows\v7.0\Samples\Web\WWSAPI\XmlBuffer
which you may want to look at.
http://blog.voidnish.com - You guys rock, cheers for all the help...
hegsie
For the curious...
// Some xml to read and write static const char xml[] = "<XML>GoodPassword</XML>"; // Setup the reader input source WS_XML_READER_BUFFER_INPUT bufferInput; ZeroMemory( &bufferInput, sizeof(bufferInput)); bufferInput.input.inputType = WS_XML_READER_INPUT_TYPE_BUFFER; bufferInput.encodedData = (void*)xml; bufferInput.encodedDataSize = (ULONG)strlen(xml); WS_XML_READER_TEXT_ENCODING textEncoding; ZeroMemory( &textEncoding, sizeof(textEncoding)); textEncoding.encoding.encodingType = WS_XML_READER_ENCODING_TYPE_TEXT; textEncoding.charSet = WS_CHARSET_AUTO; WS_XML_READER* reader = NULL; WS_XML_BUFFER* buffer = NULL; // Create an XML reader hr = WsCreateReader(NULL,0, &reader, error); hr = WsSetInput( reader, &textEncoding.encoding, &bufferInput.input, NULL, 0, error); // Read the xml into a WS_XML_BUFFER hr = WsReadXmlBuffer(reader, heap, &buffer, error); WS_HTTP_BINDING_TEMPLATE templ = {}; hr = DLLogonSoap_CreateServiceProxy(&templ,NULL,0, &proxy,error); hr = WsOpenServiceProxy(proxy, &address, NULL, error); int result = 0; std::wstring wLoginGUID = ConvertCharToWstring(mLoginGUID.c_str()); hr = DLLogonSoap_ValidateLogon(proxy,(WCHAR*)wLoginGUID.c_str(),buffer,&result,heap,NULL,0,NULL,error); if (!FAILED(hr) && result > 0) // result contains the accountid guidValid = true;

