Hi,
Firstly if this isnt the place to post this question, kindly point me to the right place and ill bother them with my problems
I am developing an application to consume a XML/SOAP service provided by a 3rd party, so there really isnt any scope for changing/testing anything at the server end (although i do access to a development/test server, but not to any source code etc).
I am writing the client in VC++ 6, (Visual Studio 6.0) and before everyone says why not use .Net, it just isnt an option, so I have to use VC++ 6. I am using the MSSOAP Toolkit v3.0. The client machine is a Windows XP Desktop and the webserver hosting the
service is running IIS on and XP desktop install (the server OS will probably be different in the wild).
The problem I am having is the service can be accessed using normal http, with no encryption/authentication and also using Server Side SSL Certs, but no client certs or client authentication (so SSL is being used purely for encryption, not validation). Everything
appears to work correctly when using plain http, but when using https I get an E_INVALIDARG exception/_com_error thrown.
<br/>
Here is the abbreviated source code to make the connection and call to the service:
<div style="color:Black;background-color:White; <pre>
UINT __cdecl CCapitaBalanceChecker::GetBalanceThread(LPVOID pParam) {
UINT retVal = 0;
<span style="color:Blue; bool CoInitOK = FALSE;
BALANCE_RESPONSE *resp = (BALANCE_RESPONSE *)pParam;
<span style="color:Blue; try {
<span style="color:Blue; if(resp) {
ASSERT(resp->fundCode.GetLength() > 0);
ASSERT(resp->reference.GetLength() > 0);
<span style="color:Blue; if(resp->m_sema) {
<span style="color:Blue; if(!resp->m_sema->Lock(2000)) {
<span style="color:Green; //failed to get lock
AfxThrowResourceException();
}
}
CoInitOK = (CoInitialize(NULL) == S_OK);
HRESULT hr;
ISoapSerializerPtr Serializer;
ISoapReaderPtr Reader;
ISoapConnectorPtr Connector;
IXMLDOMElementPtr Element;
<span style="color:Green; // Connect to the service.
Connector.CreateInstance(__uuidof(HttpConnector30));
CString url;
url.Format(<span style="color:#A31515; "%s://%s%s",useSSL?<span style="color:#A31515; "https":<span style="color:#A31515; "http", m_serverAddress, CAPITA_BALANCE_CHECK_PATH);
Connector->Property[<span style="color:#A31515; "EndPointURL"] = (LPCSTR)url;
Connector->Property[<span style="color:#A31515; "Timeout"] = CAPITA_BALANCE_CHECK_TIMEOUT;
Connector->Property[<span style="color:#A31515; "UseSSL"] = _variant_t(useSSL);
Connector->Property[<span style="color:#A31515; "WinHTTPAuthScheme"] = _variant_t((<span style="color:Blue; short)1);
hr = Connector->Connect();
<span style="color:Blue; if(SUCCEEDED(hr)) {
<span style="color:Green; // Begin the message.
CString action;
action.Format(<span style="color:#A31515; "%s%s", CAPITA_SOAP_CBL_ACTION_BASE, CAPITA_SOAP_CBL_ACTIONS[CCapitaBalanceChecker::CAP_GET_BALANCE]);
Connector->Property[<span style="color:#A31515; "SoapAction"] = (LPCSTR)action;
hr = Connector->BeginMessage();
<span style="color:Blue; if(SUCCEEDED(hr)) {
<span style="color:Green; // Create the SoapSerializer object.
Serializer.CreateInstance(__uuidof(SoapSerializer30));
<span style="color:Green; // Connect the serializer object to the input stream of the connector object.
IStream *inputstream;
Connector->get_InputStream(&inputstream);
_variant_t stream = inputstream;
Serializer->Init(stream);
<span style="color:Green; //Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));
<span style="color:Green; // Build the SOAP Message.
Serializer->StartEnvelope(<span style="color:#A31515; "soap",<span style="color:#A31515; "NONE",<span style="color:#A31515; "UTF-8");
<span style="color:Green; //Serializer->SoapAttribute("xsi", "", "http://www.w3.org/2001/XMLSchema-instance", "xmlns");
Serializer->SoapNamespace(<span style="color:#A31515; "xsi", <span style="color:#A31515; "http://www.w3.org/2001/XMLSchema-instance");
Serializer->SoapNamespace(<span style="color:#A31515; "xsd", <span style="color:#A31515; "http://www.w3.org/2001/XMLSchema");
Serializer->StartBody(<span style="color:#A31515; "NONE");
Serializer->StartElement(<span style="color:#A31515; "GetBalance",<span style="color:#A31515; "",<span style="color:#A31515; "NONE", <span style="color:#A31515; "");
Serializer->SoapAttribute(<span style="color:#A31515; "xmlns", <span style="color:#A31515; "", <span style="color:#A31515; "http://AXISCommonBusinessLogic/", <span style="color:#A31515; "");
Serializer->StartElement(<span style="color:#A31515; "getBalanceRequest",<span style="color:#A31515; "",<span style="color:#A31515; "NONE",<span style="color:#A31515; "");
Serializer->WriteString(_bstr_t(GetBalanceCheckXMLStr(resp->fundCode, resp->reference)));
Serializer->EndElement();
Serializer->EndElement();
Serializer->EndBody();
<span style="color:Green; //this is the call that seems to spend the most time blocking....
Serializer->EndEnvelope();
<span style="color:Green; // Send the message to the XML Web service.
Serializer->Finished();
Reader.CreateInstance(__uuidof(SoapReader30));
<span style="color:Green; // Connect the reader to the output stream of the connector object.
IStream *outputstream;
Connector->get_OutputStream(&outputstream);
_variant_t outstream = outputstream;
Reader->Load(outstream,<span style="color:#A31515; ""); <span style="color:Green; //<~~~~~~Exception is thrown during this call.
<span style="color:Blue; if(Reader->Fault != NULL) {
<span style="color:Green; //Handle Error/Faults....
} <span style="color:Blue; else {
<span style="color:Green; //Proccess response...
}
} <span style="color:Blue; else {
<span style="color:Green; //
resp->statusStr = <span style="color:#A31515; "Call to BeginMessage failed!";
resp->balanceFound = <span style="color:Blue; false;
}
} <span style="color:Blue; else {
resp->statusStr = <span style="color:#A31515; "Connection to CBL server failed!";
resp->balanceFound = <span style="color:Blue; false;
}
} <span style="color:Blue; else {
<span style="color:Green; //null parameter passed.
AfxThrowResourceException();
}
} <span style="color:Blue; catch (CException *e) {
<span style="color:Blue; if(resp) {
CString tmpStr;
e->GetErrorMessage(tmpStr.GetBufferSetLength(512), 512);
tmpStr.ReleaseBuffer(tmpStr.GetLength());
resp->statusStr.Format(<span style="color:#A31515; "CException caught checking for errors: %s", tmpStr);
}
e->Delete();
<span style="color:Blue; if(CoInitOK)
CoUninitialize();
<span style="color:Blue; if(resp) {
resp->balanceFound = <span style="color:Blue; false;
resp->responseCode = -1;
<span style="color:Blue; if(resp->m_sema)
resp->m_sema->Unlock();
}
<span style="color:Blue; return (UINT)100;
} <span style="color:Blue; catch (_com_error e) {
<span style="color:Blue; if(resp) {
resp->statusStr.Format(<span style="color:#A31515; "COM Error %ld caught checking for errors: %s", e.Error(), e.ErrorMessage());
}
<span style="color:Blue; if(CoInitOK)
CoUninitialize();
<span style="color:Blue; if(resp) {
resp->balanceFound = <span style="color:Blue; false;
resp->responseCode = -1;
<span style="color:Blue; if(resp->m_sema)
resp->m_sema->Unlock();
}
<span style="color:Blue; return (UINT)100;
} <span style="color:Blue; catch (...) {
<span style="color:Blue; if(resp) {
resp->statusStr = <span style="color:#A31515; "Exception caught checking for errors";
}
<span style="color:Blue; if(CoInitOK)
CoUninitialize();
<span style="color:Blue; if(resp) {
resp->balanceFound = <span style="color:Blue; false;
resp->responseCode = -1;
<span style="color:Blue; if(resp->m_sema)
resp->m_sema->Unlock();
}
<span style="color:Blue; return (UINT)100;
}
<span style="color:Blue; if(resp) {
<span style="color:Blue; if(resp->m_sema) {
resp->m_sema->Unlock();
}
}
<span style="color:Blue; return retVal;
}
[/code]
<br/>
As you can see from the code, this is being run inside its own thread, but i dont think this should create the problem I am seeing here.
The code gets as far as sending, the request, but fails when trying to create a SoapReader30 object and attach it to the output stream of the connector (HttpConnector30) object.
Once again, I realise that im being forced into using out of date libraries, etc... but like most devs, I dont really get a say in that.
If you need more information to help me then please ask.
View the full article
Firstly if this isnt the place to post this question, kindly point me to the right place and ill bother them with my problems

I am developing an application to consume a XML/SOAP service provided by a 3rd party, so there really isnt any scope for changing/testing anything at the server end (although i do access to a development/test server, but not to any source code etc).
I am writing the client in VC++ 6, (Visual Studio 6.0) and before everyone says why not use .Net, it just isnt an option, so I have to use VC++ 6. I am using the MSSOAP Toolkit v3.0. The client machine is a Windows XP Desktop and the webserver hosting the
service is running IIS on and XP desktop install (the server OS will probably be different in the wild).
The problem I am having is the service can be accessed using normal http, with no encryption/authentication and also using Server Side SSL Certs, but no client certs or client authentication (so SSL is being used purely for encryption, not validation). Everything
appears to work correctly when using plain http, but when using https I get an E_INVALIDARG exception/_com_error thrown.
<br/>
Here is the abbreviated source code to make the connection and call to the service:
<div style="color:Black;background-color:White; <pre>
UINT __cdecl CCapitaBalanceChecker::GetBalanceThread(LPVOID pParam) {
UINT retVal = 0;
<span style="color:Blue; bool CoInitOK = FALSE;
BALANCE_RESPONSE *resp = (BALANCE_RESPONSE *)pParam;
<span style="color:Blue; try {
<span style="color:Blue; if(resp) {
ASSERT(resp->fundCode.GetLength() > 0);
ASSERT(resp->reference.GetLength() > 0);
<span style="color:Blue; if(resp->m_sema) {
<span style="color:Blue; if(!resp->m_sema->Lock(2000)) {
<span style="color:Green; //failed to get lock
AfxThrowResourceException();
}
}
CoInitOK = (CoInitialize(NULL) == S_OK);
HRESULT hr;
ISoapSerializerPtr Serializer;
ISoapReaderPtr Reader;
ISoapConnectorPtr Connector;
IXMLDOMElementPtr Element;
<span style="color:Green; // Connect to the service.
Connector.CreateInstance(__uuidof(HttpConnector30));
CString url;
url.Format(<span style="color:#A31515; "%s://%s%s",useSSL?<span style="color:#A31515; "https":<span style="color:#A31515; "http", m_serverAddress, CAPITA_BALANCE_CHECK_PATH);
Connector->Property[<span style="color:#A31515; "EndPointURL"] = (LPCSTR)url;
Connector->Property[<span style="color:#A31515; "Timeout"] = CAPITA_BALANCE_CHECK_TIMEOUT;
Connector->Property[<span style="color:#A31515; "UseSSL"] = _variant_t(useSSL);
Connector->Property[<span style="color:#A31515; "WinHTTPAuthScheme"] = _variant_t((<span style="color:Blue; short)1);
hr = Connector->Connect();
<span style="color:Blue; if(SUCCEEDED(hr)) {
<span style="color:Green; // Begin the message.
CString action;
action.Format(<span style="color:#A31515; "%s%s", CAPITA_SOAP_CBL_ACTION_BASE, CAPITA_SOAP_CBL_ACTIONS[CCapitaBalanceChecker::CAP_GET_BALANCE]);
Connector->Property[<span style="color:#A31515; "SoapAction"] = (LPCSTR)action;
hr = Connector->BeginMessage();
<span style="color:Blue; if(SUCCEEDED(hr)) {
<span style="color:Green; // Create the SoapSerializer object.
Serializer.CreateInstance(__uuidof(SoapSerializer30));
<span style="color:Green; // Connect the serializer object to the input stream of the connector object.
IStream *inputstream;
Connector->get_InputStream(&inputstream);
_variant_t stream = inputstream;
Serializer->Init(stream);
<span style="color:Green; //Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));
<span style="color:Green; // Build the SOAP Message.
Serializer->StartEnvelope(<span style="color:#A31515; "soap",<span style="color:#A31515; "NONE",<span style="color:#A31515; "UTF-8");
<span style="color:Green; //Serializer->SoapAttribute("xsi", "", "http://www.w3.org/2001/XMLSchema-instance", "xmlns");
Serializer->SoapNamespace(<span style="color:#A31515; "xsi", <span style="color:#A31515; "http://www.w3.org/2001/XMLSchema-instance");
Serializer->SoapNamespace(<span style="color:#A31515; "xsd", <span style="color:#A31515; "http://www.w3.org/2001/XMLSchema");
Serializer->StartBody(<span style="color:#A31515; "NONE");
Serializer->StartElement(<span style="color:#A31515; "GetBalance",<span style="color:#A31515; "",<span style="color:#A31515; "NONE", <span style="color:#A31515; "");
Serializer->SoapAttribute(<span style="color:#A31515; "xmlns", <span style="color:#A31515; "", <span style="color:#A31515; "http://AXISCommonBusinessLogic/", <span style="color:#A31515; "");
Serializer->StartElement(<span style="color:#A31515; "getBalanceRequest",<span style="color:#A31515; "",<span style="color:#A31515; "NONE",<span style="color:#A31515; "");
Serializer->WriteString(_bstr_t(GetBalanceCheckXMLStr(resp->fundCode, resp->reference)));
Serializer->EndElement();
Serializer->EndElement();
Serializer->EndBody();
<span style="color:Green; //this is the call that seems to spend the most time blocking....
Serializer->EndEnvelope();
<span style="color:Green; // Send the message to the XML Web service.
Serializer->Finished();
Reader.CreateInstance(__uuidof(SoapReader30));
<span style="color:Green; // Connect the reader to the output stream of the connector object.
IStream *outputstream;
Connector->get_OutputStream(&outputstream);
_variant_t outstream = outputstream;
Reader->Load(outstream,<span style="color:#A31515; ""); <span style="color:Green; //<~~~~~~Exception is thrown during this call.
<span style="color:Blue; if(Reader->Fault != NULL) {
<span style="color:Green; //Handle Error/Faults....
} <span style="color:Blue; else {
<span style="color:Green; //Proccess response...
}
} <span style="color:Blue; else {
<span style="color:Green; //
resp->statusStr = <span style="color:#A31515; "Call to BeginMessage failed!";
resp->balanceFound = <span style="color:Blue; false;
}
} <span style="color:Blue; else {
resp->statusStr = <span style="color:#A31515; "Connection to CBL server failed!";
resp->balanceFound = <span style="color:Blue; false;
}
} <span style="color:Blue; else {
<span style="color:Green; //null parameter passed.
AfxThrowResourceException();
}
} <span style="color:Blue; catch (CException *e) {
<span style="color:Blue; if(resp) {
CString tmpStr;
e->GetErrorMessage(tmpStr.GetBufferSetLength(512), 512);
tmpStr.ReleaseBuffer(tmpStr.GetLength());
resp->statusStr.Format(<span style="color:#A31515; "CException caught checking for errors: %s", tmpStr);
}
e->Delete();
<span style="color:Blue; if(CoInitOK)
CoUninitialize();
<span style="color:Blue; if(resp) {
resp->balanceFound = <span style="color:Blue; false;
resp->responseCode = -1;
<span style="color:Blue; if(resp->m_sema)
resp->m_sema->Unlock();
}
<span style="color:Blue; return (UINT)100;
} <span style="color:Blue; catch (_com_error e) {
<span style="color:Blue; if(resp) {
resp->statusStr.Format(<span style="color:#A31515; "COM Error %ld caught checking for errors: %s", e.Error(), e.ErrorMessage());
}
<span style="color:Blue; if(CoInitOK)
CoUninitialize();
<span style="color:Blue; if(resp) {
resp->balanceFound = <span style="color:Blue; false;
resp->responseCode = -1;
<span style="color:Blue; if(resp->m_sema)
resp->m_sema->Unlock();
}
<span style="color:Blue; return (UINT)100;
} <span style="color:Blue; catch (...) {
<span style="color:Blue; if(resp) {
resp->statusStr = <span style="color:#A31515; "Exception caught checking for errors";
}
<span style="color:Blue; if(CoInitOK)
CoUninitialize();
<span style="color:Blue; if(resp) {
resp->balanceFound = <span style="color:Blue; false;
resp->responseCode = -1;
<span style="color:Blue; if(resp->m_sema)
resp->m_sema->Unlock();
}
<span style="color:Blue; return (UINT)100;
}
<span style="color:Blue; if(resp) {
<span style="color:Blue; if(resp->m_sema) {
resp->m_sema->Unlock();
}
}
<span style="color:Blue; return retVal;
}
[/code]
<br/>
As you can see from the code, this is being run inside its own thread, but i dont think this should create the problem I am seeing here.
The code gets as far as sending, the request, but fails when trying to create a SoapReader30 object and attach it to the output stream of the connector (HttpConnector30) object.
Once again, I realise that im being forced into using out of date libraries, etc... but like most devs, I dont really get a say in that.
If you need more information to help me then please ask.
View the full article