// ========================================================================== // Class Implementation : COXDispatchMarshaller // ========================================================================== // Source file : OXDispatchMarshaller.h // This software along with its related components, documentation and files ("The Libraries") // is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is // governed by a software license agreement ("Agreement"). Copies of the Agreement are // available at The Code Project (www.codeproject.com), as part of the package you downloaded // to obtain this file, or directly from our office. For a copy of the license governing // this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900. // ////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "OXDispatchMarshaller.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif const LARGE_INTEGER bZero = {0,0}; COXDispatchMarshaller::COXDispatchMarshaller() : m_pStream(NULL), m_hMutexEvent(NULL) { HRESULT hr; m_hMutexEvent = CreateEvent(NULL,FALSE,TRUE,NULL); // create an IStream to be used for marshalling new objects between // the worker and the CClassFactory hr = CreateStreamOnHGlobal(NULL, TRUE, &m_pStream); if (hr!=S_OK) m_pStream=NULL; } COXDispatchMarshaller::~COXDispatchMarshaller() { if (m_pStream != NULL) m_pStream->Release(); CloseHandle(m_hMutexEvent); } HRESULT COXDispatchMarshaller::Marshal(IDispatch* pDisp) { HRESULT hResult; WaitForSingleObject(m_hMutexEvent, INFINITE); hResult = m_pStream->Seek(bZero, STREAM_SEEK_SET, NULL); if (hResult==S_OK) { hResult = CoMarshalInterface(m_pStream, IID_IDispatch, pDisp, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); if (hResult==S_OK) { // pDisp is now referenced by its marshal-data in vpstmMarshalling. // we release our local reference here so the unmarshaller will // have the sole reference. a common mistake is to forget this // release and end up with orphaned objects in the server. pDisp->Release(); } } return hResult; } HRESULT COXDispatchMarshaller::Unmarshal(void** pDisp) { HRESULT hResult; ASSERT(WaitForSingleObject(m_hMutexEvent, 0)==WAIT_TIMEOUT); hResult = m_pStream->Seek(bZero, STREAM_SEEK_SET, NULL); if (hResult==S_OK) hResult = CoUnmarshalInterface(m_pStream, IID_IDispatch, pDisp); SetEvent(m_hMutexEvent); return hResult; } BOOL COXDispatchMarshaller::CheckStream() { return (m_pStream!=NULL); }