// echofilehdrObj.cpp : Implementation of CechofilehdrObj #include "stdafx.h" #include "echofilehdrObj.h" #include "..\wmsoapmsg\wmsoapmsg_i.c" #include "..\wmsoapmsg\wmsoapmsg.h" #include "..\wmsoapstruct\wmsoapstruct.h" #include "..\wmsoapstruct\wmsoapstruct_i.c" #include "..\soap_source\DIMEPayload.h" #include "comdef.h" #include using namespace std; static wchar_t *g_pwszHeaderNS = L"http://whitemesa.net/echofile/header"; // CechofilehdrObj STDMETHODIMP CechofilehdrObj::OnProcessHeader(VARIANT SOAPMsgInterface, VARIANT_BOOL *pResult) { // get message interface ptr IDispatch *pIDispatch = SOAPMsgInterface.pdispVal; Iwmsoapmsg2 *pIwmsoapmsg; HRESULT hRes = pIDispatch->QueryInterface(IID_Iwmsoapmsg2, (void **)&pIwmsoapmsg); if (hRes != S_OK) { // trouble *pResult = VARIANT_FALSE; return S_OK; } // ok *pResult = VARIANT_TRUE; VARIANT_BOOL bResult; pIwmsoapmsg->IsRequestPhase(&bResult); // check message phase if (bResult == VARIANT_FALSE) { // this is response phase... echo request headers in response BSTR bstrTargetActorURI = SysAllocString(L""); BSTR bstrNamespaceURI = SysAllocString(g_pwszHeaderNS); BSTR bstrLocalName = SysAllocString(L"outputDataFile"); vector<_variant_t>::iterator iter; for (iter = m_arrHeaders.begin(); iter != m_arrHeaders.end(); iter++) { // get pointer to struct object IDispatch *pIDispatch = (*iter).pdispVal; if (pIDispatch == NULL) { return E_POINTER; } Iwmsoapstruct *pIwmsoapstruct; HRESULT res = pIDispatch->QueryInterface(IID_Iwmsoapstruct, (void **)&pIwmsoapstruct); if (FAILED(res)) { return E_NOINTERFACE; } _variant_t varTemp; VARIANT_BOOL bResult; wstring wstrFilename; BSTR bstrMember1 = SysAllocString(L"fileName"); BSTR bstrMember2 = SysAllocString(L"fileData"); // now get struct members pIwmsoapstruct->GetMember(bstrMember1, &varTemp, &bResult); if (bResult == VARIANT_FALSE) { return E_FAIL; } wstrFilename = varTemp.bstrVal; varTemp.Clear(); pIwmsoapstruct->GetMember(bstrMember2, &varTemp, &bResult); if (bResult == VARIANT_FALSE) { return E_FAIL; } // release interface ptr pIwmsoapstruct->Release(); // now get file data VARIANT varOutputFile; VariantInit(&varOutputFile); // test vartype to see what we have if (varTemp.vt == VT_UNKNOWN) { // binary data sent as DIME attachment IUnknown *pIUnknownIn = varTemp.punkVal; IStorage *pIStorageIn; HRESULT hRes = pIUnknownIn->QueryInterface(IID_IStorage, (void **)&pIStorageIn); if (FAILED(hRes)) { return E_NOINTERFACE; } DIMEPayload *pPayloadIn = new DIMEPayload( pIStorageIn, string(""), string(""), DIME_TYPENAME_FORMAT_UNKNOWN); pIStorageIn->Release(); if (pPayloadIn == NULL) { return E_FAIL; } // now create storage for output IStorage *pIStorageOut; hRes = StgCreateDocfile(NULL, STGM_DELETEONRELEASE | STGM_DIRECT | STGM_READWRITE| STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorageOut); if (FAILED(hRes)) { return E_FAIL; } DIMEPayload *pPayloadOut = new DIMEPayload( pIStorageOut, string(""), string(""), DIME_TYPENAME_FORMAT_UNKNOWN); if (pPayloadOut == NULL) { pIStorageOut->Release(); return E_FAIL; } // now copy contents char szTemp[4096]; unsigned long ulNumBytes = 0; unsigned long ulBytesWritten = 0; pPayloadIn->OpenForRead(); pPayloadOut->OpenForWrite(); do { pPayloadIn->Read(szTemp, 4096, &ulNumBytes); pPayloadOut->Write(szTemp, ulNumBytes, &ulBytesWritten); } while (ulNumBytes == 4096); pPayloadIn->Close(); pPayloadOut->Close(); delete pPayloadIn; delete pPayloadOut; varOutputFile.punkVal = pIStorageOut; varOutputFile.vt = VT_UNKNOWN; } else { // binary sent as type base64Binary, passed in as (VT_ARRAY | VT_UI1) SafeArrayCopy(varTemp.parray, &varOutputFile.parray); varOutputFile.vt = (VT_ARRAY | VT_UI1); } // instantiate struct object Iwmsoapstruct *pIwmsoapstructOut; res = CoCreateInstance( CLSID_wmsoapstruct, NULL, CLSCTX_SERVER, IID_Iwmsoapstruct, (void **) &pIwmsoapstructOut); if (FAILED(res)) { return E_FAIL; } varTemp.Clear(); // filename varTemp = wstrFilename.c_str(); pIwmsoapstructOut->SetMember(bstrMember1, varTemp, &bResult); // data pIwmsoapstructOut->SetMember(bstrMember2, varOutputFile, &bResult); VariantClear(&varOutputFile); SysFreeString(bstrMember1); SysFreeString(bstrMember2); // now get IDispatch pointer IDispatch *pIDispatchOut; res = pIwmsoapstructOut->QueryInterface(IID_IDispatch, (void **)&pIDispatchOut); if (FAILED(res)) { pIwmsoapstructOut->Release(); return E_NOINTERFACE; } // release pIwmsoapstructOut->Release(); // set up variant _variant_t varOut; varOut.vt = VT_DISPATCH; varOut.punkVal = pIDispatchOut; // now add the header to response message pIwmsoapmsg->AddHeaderElem( bstrNamespaceURI, bstrLocalName, varOut, VARIANT_FALSE, bstrTargetActorURI, &bResult); } SysFreeString(bstrLocalName); SysFreeString(bstrNamespaceURI); SysFreeString(bstrTargetActorURI); // done with message interface pIwmsoapmsg->Release(); // finished return S_OK; } // this is the request phase... get any "inputDataFile" request header blocks long lPosition = 0; _variant_t varTemp; BSTR bstrNamespaceURI = SysAllocString(g_pwszHeaderNS); BSTR bstrLocalName = SysAllocString(L"inputDataFile"); while (true) { pIwmsoapmsg->GetHeaderElem( bstrNamespaceURI, bstrLocalName, &varTemp, &bResult); if (bResult == VARIANT_TRUE) { // store it m_arrHeaders.push_back(_variant_t(varTemp)); varTemp.Clear(); } else { break; } } SysFreeString(bstrLocalName); SysFreeString(bstrNamespaceURI); pIwmsoapmsg->Release(); // done for now, we'll be called again in response phase return S_OK; } STDMETHODIMP CechofilehdrObj::OnTestMUHeaderBlock(BSTR bstrNamespace, BSTR bstrLocalName, VARIANT_BOOL *pResult) { *pResult = VARIANT_FALSE; if (wcscmp(bstrNamespace, g_pwszHeaderNS) == 0) { if (wcscmp(bstrLocalName, L"inputDataFile") == 0) { *pResult = VARIANT_TRUE; return S_OK; } } return S_OK; }