// interopsvcdimerpcObj.cpp : Implementation of CinteropsvcdimerpcObj #include "stdafx.h" #include "interopsvcdimerpcObj.h" #include "..\soap_source\DIMEPayload.h" #include "..\soap_source\charencode.h" #include "..\wmsoapstruct\wmsoapstruct.h" #include "..\wmsoapstruct\wmsoapstruct_i.c" #include "comdef.h" #include #include using namespace std; // CinteropsvcdimerpcObj STDMETHODIMP CinteropsvcdimerpcObj::EchoAttachment(VARIANT In, VARIANT *Out) { if ((In.vt & VT_TYPEMASK) == VT_UNKNOWN) { // sent as attachment IUnknown *pIUnknownIn = In.punkVal; if (pIUnknownIn == NULL) { return E_POINTER; } 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); if (pPayloadIn == NULL) { pIStorageIn->Release(); return E_FAIL; } pIStorageIn->Release(); 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); // 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; Out->punkVal = pIStorageOut; Out->vt = VT_UNKNOWN; } else { if ((In.vt & VT_TYPEMASK) != (VT_ARRAY | VT_UI1)) { return E_INVALIDARG; } // sent in conventional manner SafeArrayCopy(In.parray, &Out->parray); Out->vt = (VT_I1 | VT_ARRAY); } return S_OK; } STDMETHODIMP CinteropsvcdimerpcObj::EchoAttachments(VARIANT In, VARIANT *Out) { vector arrAttachmentsOut; // extract info from SAFEARRAY SAFEARRAY *pArray = In.parray; long arrIndex[1]; // lock array SafeArrayLock(pArray); // iterate over array for (unsigned int i = pArray->rgsabound[0].lLbound; i < (pArray->rgsabound[0].lLbound + pArray->rgsabound[0].cElements); i++) { arrIndex[0] = i; // get pointer to attachment VARIANT *pVar = NULL; SafeArrayPtrOfIndex(pArray, arrIndex, (void **)&pVar); IStorage *pIStorageOut; if (pVar->vt == VT_UNKNOWN) { IUnknown *pIUnknownIn = pVar->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); if (pPayloadIn == NULL) { pIStorageIn->Release(); return E_FAIL; } pIStorageIn->Release(); 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); // 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; } else { // extract info from SAFEARRAY HRESULT 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) { return E_FAIL; } SAFEARRAY *pArray = pVar->parray; void *pData = NULL; SafeArrayAccessData(pArray, &pData); // now copy contents unsigned long ulBytesWritten = 0; pPayloadOut->OpenForWrite(); pPayloadOut->Write((char *)pData, pArray->rgsabound[0].cElements, &ulBytesWritten); SafeArrayUnaccessData(pArray); pPayloadOut->Close(); delete pPayloadOut; } arrAttachmentsOut.push_back(pIStorageOut); } SafeArrayUnlock(pArray); // create SAFEARRAY SAFEARRAYBOUND Bounds[1]; Bounds[0].lLbound = 0; Bounds[0].cElements = (ULONG)arrAttachmentsOut.size(); SAFEARRAY *pArrayOut = SafeArrayCreate(VT_VARIANT, 1, Bounds); if (pArray == NULL) { return E_FAIL; } Out->parray = pArrayOut; Out->vt = (VT_VARIANT | VT_ARRAY); // copy ptrs into array VARIANT varTemp; for (i = 0; i < arrAttachmentsOut.size(); i++) { varTemp.vt = VT_UNKNOWN; varTemp.punkVal = arrAttachmentsOut[i]; arrIndex[0] = i; // put it away SafeArrayPutElement(pArrayOut, arrIndex, &varTemp); arrAttachmentsOut[i]->Release(); } return S_OK; } STDMETHODIMP CinteropsvcdimerpcObj::EchoAttachmentAsBase64(VARIANT In, VARIANT *Out) { if ((In.vt & VT_TYPEMASK) == VT_UNKNOWN) { // sent as attachment IUnknown *pIUnknownIn = In.punkVal; if (pIUnknownIn == NULL) { return E_POINTER; } 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); if (pPayloadIn == NULL) { pIStorageIn->Release(); return E_FAIL; } pIStorageIn->Release(); // must open before attempting to get length pPayloadIn->OpenForRead(); unsigned long ulLength = pPayloadIn->GetDataLength(); // create SAFEARRAY SAFEARRAY *pArray = SafeArrayCreateVector(VT_UI1, 0, ulLength); if (pArray == NULL) { return E_FAIL; } char *pData; SafeArrayAccessData(pArray, (void **)&pData); // now copy contents char szTemp[4096]; unsigned long ulNumBytes = 0; unsigned long ulBytesWritten = 0; do { pPayloadIn->Read(szTemp, 4096, &ulNumBytes); memcpy(pData + ulBytesWritten, szTemp, ulNumBytes); ulBytesWritten += ulNumBytes; } while (ulNumBytes == 4096); pPayloadIn->Close(); delete pPayloadIn; SafeArrayUnaccessData(pArray); Out->parray = pArray; Out->vt = (VT_ARRAY | VT_UI1); } else { if ((In.vt & VT_TYPEMASK) != (VT_ARRAY | VT_UI1)) { return E_INVALIDARG; } // sent in conventional manner, passed in as (VT_ARRAY | VT_UI1) SafeArrayCopy(In.parray, &Out->parray); Out->vt = (VT_I1 | VT_ARRAY); } return S_OK; } STDMETHODIMP CinteropsvcdimerpcObj::EchoBase64AsAttachment(VARIANT In, VARIANT *Out) { // extract info from SAFEARRAY SAFEARRAY *pArray = In.parray; unsigned char *pData = NULL; SafeArrayAccessData(pArray, (void **)&pData); IStorage *pIStorageOut; HRESULT hRes; 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); // now copy contents pPayloadOut->OpenForWrite(); unsigned long ulBytesWritten; pPayloadOut->Write((char *)pData, pArray->rgsabound[0].cElements, &ulBytesWritten); SafeArrayUnaccessData(pArray); pPayloadOut->Close(); delete pPayloadOut; // set up output variant Out->punkVal = pIStorageOut; Out->vt = VT_UNKNOWN; return S_OK; } STDMETHODIMP CinteropsvcdimerpcObj::EchoAttachmentAsString(VARIANT In, BSTR *Out) { if ((In.vt & VT_TYPEMASK) == VT_UNKNOWN) { // sent as attachment IUnknown *pIUnknownIn = In.punkVal; if (pIUnknownIn == NULL) { return E_POINTER; } 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); if (pPayloadIn == NULL) { pIStorageIn->Release(); return E_FAIL; } pIStorageIn->Release(); // must open before attempting to get length pPayloadIn->OpenForRead(); unsigned long ulLength = pPayloadIn->GetDataLength(); unsigned long ulNumBytes = 0; // create BSTR char *pszBuffer = (char *)malloc(ulLength); pPayloadIn->Read(pszBuffer, ulLength, &ulNumBytes); pPayloadIn->Close(); delete pPayloadIn; wstring wstrTemp; UTF8ToWideString(pszBuffer, ulNumBytes, wstrTemp); free(pszBuffer); *Out = SysAllocString(wstrTemp.c_str()); } else { if ((In.vt & VT_TYPEMASK) != (VT_ARRAY | VT_UI1)) { return E_INVALIDARG; } SAFEARRAY *pArray = In.parray; void *pData = NULL; SafeArrayAccessData(pArray, &pData); // create BSTR wstring wstrTemp; UTF8ToWideString((char *)pData, pArray->rgsabound[0].cElements, wstrTemp); *Out = SysAllocString(wstrTemp.c_str()); } return S_OK; }