home *** CD-ROM | disk | FTP | other *** search
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
-
- #ifdef AFX_OLE_SEG
- #pragma code_seg(AFX_OLE_SEG)
- #endif
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- #define new DEBUG_NEW
-
- #pragma inline_depth(0)
-
- /////////////////////////////////////////////////////////////////////////////
- // _AfxBindStatusCallback for CAsyncMonikerFile implementation
-
- class _AfxBindStatusCallback: public IBindStatusCallback
- {
- private:
- class CInnerUnknown : public IUnknown
- {
- protected:
- _AfxBindStatusCallback* m_pThis;
- friend class _AfxBindStatusCallback;
-
- public:
- inline CInnerUnknown() { }
- inline void SetpThis(_AfxBindStatusCallback* pThis) { ASSERT(pThis != NULL); m_pThis = pThis; }
-
- STDMETHOD_(ULONG, AddRef)()
- {
- return InterlockedIncrement((long*)&m_pThis->m_dwRef);
- }
-
- STDMETHOD_(ULONG, Release)()
- {
- unsigned long lResult = InterlockedDecrement((long*)&m_pThis->m_dwRef);
- if (lResult == 0)
- delete m_pThis;
- return lResult;
- }
-
- STDMETHOD(QueryInterface)(REFIID iid, void** ppvObject)
- {
- if (!ppvObject)
- return E_POINTER;
-
- // check for the interfaces this object knows about
- if (iid == IID_IUnknown)
- {
- *ppvObject = (IUnknown*)this;
- AddRef();
- return S_OK;
- }
- if (iid == IID_IBindStatusCallback)
- {
- *ppvObject = (IBindStatusCallback*)m_pThis;
- m_pThis->AddRef();
- return S_OK;
- }
-
- // otherwise, incorrect IID, and thus error
- return E_NOINTERFACE;
- }
- };
-
- public:
- inline _AfxBindStatusCallback(CAsyncMonikerFile* pOwner, IUnknown* pUnkControlling)
- : m_pOwner(pOwner), m_dwRef(0)
- {
- m_UnkInner.SetpThis(this);
- ASSERT(pOwner);
- #ifdef _AFXDLL
- m_pModuleState = AfxGetModuleState();
- ASSERT(m_pModuleState != NULL);
- #endif
- m_pUnkControlling = pUnkControlling ? pUnkControlling : (IUnknown*)&m_UnkInner;
-
- AfxOleLockApp();
- }
-
- inline ~_AfxBindStatusCallback()
- {
- AFX_MANAGE_STATE(m_pModuleState);
- AfxOleUnlockApp();
- }
-
- inline void Orphan() { m_pOwner = NULL; }
-
- STDMETHOD_(ULONG, AddRef)()
- { return m_pUnkControlling->AddRef(); }
- STDMETHOD_(ULONG, Release)()
- { return m_pUnkControlling->Release(); }
- STDMETHOD(QueryInterface)(REFIID iid, void** ppvObject)
- { return m_pUnkControlling->QueryInterface(iid, ppvObject); }
-
-
- const CAsyncMonikerFile* GetOwner() const{ return m_pOwner; }
- DWORD GetRefcount() const { return m_dwRef; }
- const IUnknown* GetControllingUnknown() const { return m_pUnkControlling; }
- IUnknown* GetControllingUnknown() { return m_pUnkControlling; }
- const IUnknown* GetInnerUnknown() const { return &m_UnkInner; }
- IUnknown* GetInnerUnknown() { return &m_UnkInner; }
- const _AfxBindStatusCallback* GetpThisOfInnerUnknown() const { return m_UnkInner.m_pThis; }
- #ifdef _AFXDLL
- const AFX_MODULE_STATE* GetModuleState() const { return m_pModuleState; }
- #endif
- protected:
- friend class CInnerUnknown;
- DWORD m_dwRef;
- private:
- IUnknown* m_pUnkControlling;
- CInnerUnknown m_UnkInner;
- CAsyncMonikerFile* m_pOwner;
- #ifdef _AFXDLL
- AFX_MODULE_STATE* m_pModuleState;
- #endif
-
- STDMETHOD(GetBindInfo)(
- DWORD __RPC_FAR *pgrfBINDF, BINDINFO __RPC_FAR *pbindinfo)
- {
- ASSERT(m_pOwner);
- if (!pgrfBINDF || !pbindinfo)
- return E_POINTER;
- if (pbindinfo->cbSize<sizeof(BINDINFO))
- return E_INVALIDARG;
- if (!m_pOwner)
- return E_FAIL;
-
- AFX_MANAGE_STATE(m_pModuleState);
- pbindinfo->szExtraInfo = NULL;
- TRY
- {
- *pgrfBINDF = m_pOwner->GetBindInfo();
- }
- CATCH_ALL(e)
- {
- HRESULT hr = ResultFromScode(COleException::Process(e));
- DELETE_EXCEPTION(e);
- return hr;
- }
- END_CATCH_ALL
- return S_OK;
- }
-
- STDMETHOD(OnStartBinding)(
- DWORD dwReserved, IBinding __RPC_FAR *pBinding)
- {
- ASSERT(m_pOwner);
- UNUSED_ALWAYS(dwReserved);
- if (!pBinding)
- return E_POINTER;
- if (!m_pOwner)
- return E_FAIL;
-
- AFX_MANAGE_STATE(m_pModuleState);
- TRY
- {
- m_pOwner->SetBinding(pBinding);
- m_pOwner->OnStartBinding();
- }
- CATCH_ALL(e)
- {
- HRESULT hr = ResultFromScode(COleException::Process(e));
- DELETE_EXCEPTION(e);
- return hr;
- }
- END_CATCH_ALL
- return S_OK;
- }
-
- STDMETHOD(GetPriority)(LONG __RPC_FAR *pnPriority)
- {
- ASSERT(m_pOwner);
- if (!pnPriority)
- return E_POINTER;
- if (!m_pOwner)
- return E_FAIL;
- AFX_MANAGE_STATE(m_pModuleState);
- TRY
- {
- *pnPriority = m_pOwner->GetPriority();
- }
- CATCH_ALL(e)
- {
- HRESULT hr = ResultFromScode(COleException::Process(e));
- DELETE_EXCEPTION(e);
- return hr;
- }
- END_CATCH_ALL
- return S_OK;
- }
-
- STDMETHOD(OnProgress)(
- ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode,
- LPCOLESTR szStatusText)
- {
- ASSERT(m_pOwner);
- if (!m_pOwner)
- return E_FAIL;
- USES_CONVERSION;
- AFX_MANAGE_STATE(m_pModuleState);
- TRY
- {
- m_pOwner->OnProgress(ulProgress, ulProgressMax, ulStatusCode, OLE2CT(szStatusText));
- }
- CATCH_ALL(e)
- {
- HRESULT hr = ResultFromScode(COleException::Process(e));
- DELETE_EXCEPTION(e);
- return hr;
- }
- END_CATCH_ALL
- return S_OK;
- }
-
- STDMETHOD(OnDataAvailable)(
- DWORD grfBSCF, DWORD dwSize, FORMATETC __RPC_FAR *pformatetc,
- STGMEDIUM __RPC_FAR *pstgmed)
- {
- ASSERT(m_pOwner);
- if (!m_pOwner)
- return E_FAIL;
- AFX_MANAGE_STATE(m_pModuleState);
- TRY
- {
- m_pOwner->SetFormatEtc(pformatetc);
- if (grfBSCF&BSCF_FIRSTDATANOTIFICATION)
- {
- if (!pstgmed || !pformatetc)
- return E_POINTER;
- if ((pstgmed->tymed != TYMED_ISTREAM) ||
- !pstgmed->pstm)
- return E_UNEXPECTED;
- ASSERT(!m_pOwner->GetStream());
- m_pOwner->COleStreamFile::Attach(pstgmed->pstm);
- pstgmed->pstm->AddRef();
- }
-
- m_pOwner->OnDataAvailable(dwSize, grfBSCF);
- }
- CATCH_ALL(e)
- {
- m_pOwner->SetFormatEtc(NULL);
- HRESULT hr = ResultFromScode(COleException::Process(e));
- DELETE_EXCEPTION(e);
- return hr;
- }
- END_CATCH_ALL
- m_pOwner->SetFormatEtc(NULL);
- return S_OK;
- }
-
- STDMETHOD(OnLowResource)(DWORD dwReserved)
- {
- ASSERT(m_pOwner);
- if (!m_pOwner)
- return E_FAIL;
- AFX_MANAGE_STATE(m_pModuleState);
- UNUSED_ALWAYS(dwReserved);
- TRY
- {
- m_pOwner->OnLowResource();
- }
- CATCH_ALL(e)
- {
- HRESULT hr = ResultFromScode(COleException::Process(e));
- DELETE_EXCEPTION(e);
- return hr;
- }
- END_CATCH_ALL
- return S_OK;
- }
-
- STDMETHOD(OnStopBinding)(HRESULT hresult, LPCOLESTR szError)
- {
- //Does not ASSERT(m_pOwner) because this can be called
- //after it has been Orphan()ed.
- if (!m_pOwner)
- return E_FAIL;
- USES_CONVERSION;
- AFX_MANAGE_STATE(m_pModuleState);
- ASSERT(m_pOwner->GetBinding());
- TRY
- {
- m_pOwner->m_bStopBindingReceived = TRUE;
- m_pOwner->OnStopBinding(hresult, OLE2CT(szError));
-
- if (m_pOwner)
- {
- // Calling EndCallbacks will result in a inner Release. Our
- // caller has an inner refcount on us, possibly through the
- // controlling unknown, and we have an inner refcount from
- // m_pOwner, so m_dwRef > 1 and it's safe to call EndCallbacks.
- ASSERT(m_dwRef > 1);
- m_pOwner->EndCallbacks();
- }
- }
- CATCH_ALL(e)
- {
- HRESULT hr = ResultFromScode(COleException::Process(e));
- DELETE_EXCEPTION(e);
- return hr;
- }
- END_CATCH_ALL
- return S_OK;
- }
-
- STDMETHOD(OnObjectAvailable)(REFIID riid, IUnknown __RPC_FAR *punk)
- {
- #ifdef _DEBUG
- AFX_MANAGE_STATE(m_pModuleState);
- ASSERT(FALSE); // This function should never be called.
- #endif //_DEBUG
- UNUSED_ALWAYS(riid);
- UNUSED_ALWAYS(punk);
- return E_UNEXPECTED;
- }
- };
-
- /////////////////////////////////////////////////////////////////////////////
- // Helper functions for CAsyncMonikerFile implementation
-
- AFX_STATIC inline IBindHost* AFXAPI _AfxTrySPForBindHost(IServiceProvider* pServiceProvider)
- {
- ASSERT(pServiceProvider);
- IBindHost* pBindHost;
- HRESULT hr=pServiceProvider->QueryService(SID_IBindHost, IID_IBindHost,
- (void**)&pBindHost);
- if (SUCCEEDED(hr))
- return pBindHost;
- else
- return NULL;
- }
-
- AFX_STATIC inline IBindHost* AFXAPI _AfxTryQIForBindHost(IUnknown* pUnk)
- {
- ASSERT(pUnk);
- IPTR(IBindHost) pBindHost;
- HRESULT hr = pBindHost.QueryInterface(pUnk);
- if (SUCCEEDED(hr))
- return pBindHost;
- else
- return NULL;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CAsyncMonikerFile implementation
-
- CAsyncMonikerFile::CAsyncMonikerFile() : m_pFormatEtc(NULL),
- m_pAfxBSCCurrent(NULL)
- {
- }
-
- CAsyncMonikerFile::~CAsyncMonikerFile()
- {
- CAsyncMonikerFile::Close();
- }
-
- void CAsyncMonikerFile::EndCallbacks()
- {
- if (m_pAfxBSCCurrent)
- {
- m_pAfxBSCCurrent->Orphan();
- IUnknown* pUnkInner = m_pAfxBSCCurrent->GetInnerUnknown();
- ASSERT(pUnkInner != NULL);
- pUnkInner->Release();
- m_pAfxBSCCurrent = NULL;
- }
- }
-
- UINT CAsyncMonikerFile::Read(void* lpBuf, UINT nCount)
- {
- ASSERT_VALID(this);
- ASSERT(m_lpStream != NULL);
-
- DWORD dwBytesRead;
- HRESULT hr = _AfxReadFromStream(m_lpStream, lpBuf, nCount, dwBytesRead);
-
- if ((hr != S_OK) && (hr != S_ASYNCHRONOUS) && (hr != E_PENDING))
- _AfxThrowOleFileException(hr);
-
- // always return number of bytes read
- return (UINT)dwBytesRead;
- }
-
- void CAsyncMonikerFile::Close()
- {
- ASSERT_VALID(this);
- if (m_Binding.GetInterfacePtr())
- {
- if (!m_bStopBindingReceived)
- m_Binding->Abort();
- m_Binding.Release();
- }
- EndCallbacks();
- CMonikerFile::Close();
- }
-
- BOOL CAsyncMonikerFile::Open(IMoniker* pMoniker, IBindHost* pBindHost, CFileException* pError)
- {
- if (!pBindHost)
- return CAsyncMonikerFile::Open(pMoniker, pError);
- Close();
- IPTR(IBindCtx) pBindCtx(CreateBindContext(pError), FALSE);
- if (pError && (pError->m_cause != CFileException::none))
- return FALSE;
- IPTR(IUnknown) pBSCUnk(CreateBindStatusCallback(NULL), FALSE);
- IPTR(IBindStatusCallback) pBSC;
- pBSC.QueryInterface(pBSCUnk);
-
- m_bStopBindingReceived = FALSE;
- return Attach(pMoniker, pBindHost, pBSC, pBindCtx, pError);
- }
-
- BOOL CAsyncMonikerFile::Open(LPCTSTR lpszURL, IBindHost* pBindHost, CFileException* pError)
- {
- if (!pBindHost)
- return CAsyncMonikerFile::Open(lpszURL, pError);
- Close();
- IPTR(IBindCtx) pBindCtx(CreateBindContext(pError), FALSE);
- if (pError && (pError->m_cause != CFileException::none))
- return FALSE;
- IPTR(IUnknown) pBSCUnk(CreateBindStatusCallback(NULL), FALSE);
- IPTR(IBindStatusCallback) pBSC;
- pBSC.QueryInterface(pBSCUnk);
-
- m_bStopBindingReceived = FALSE;
- return Attach(lpszURL, pBindHost, pBSC, pBindCtx, pError);
- }
-
- BOOL CAsyncMonikerFile::Open(LPCTSTR lpszURL, CFileException* pError)
- {
- IPTR(IBindHost) pBindHost(CreateBindHost(), FALSE);
-
- return Open(lpszURL, static_cast<IBindHost*>(pBindHost), pError);
- }
-
- BOOL CAsyncMonikerFile::Open(IMoniker* pMoniker, CFileException* pError)
- {
- IPTR(IBindHost) pBindHost(CreateBindHost(), FALSE);
-
- return Open(pMoniker, (IBindHost*)pBindHost, pError);
- }
-
- BOOL CAsyncMonikerFile::Open(LPCTSTR lpszURL,
- IServiceProvider* pServiceProvider, CFileException* pError)
- {
- if (!pServiceProvider)
- return CAsyncMonikerFile::Open(lpszURL, pError);
- IPTR(IBindHost) pBindHost;
- pBindHost = _AfxTrySPForBindHost(pServiceProvider);
- if (!pBindHost.GetInterfacePtr())
- pBindHost = _AfxTryQIForBindHost(pServiceProvider);
- if (pBindHost.GetInterfacePtr())
- return Open(lpszURL, (IBindHost*)pBindHost, pError);
- return CAsyncMonikerFile::Open(lpszURL, pError);
- }
-
- BOOL CAsyncMonikerFile::Open(LPCTSTR lpszURL,
- IUnknown* pUnknown, CFileException* pError)
- {
- if (!pUnknown)
- return CAsyncMonikerFile::Open(lpszURL, pError);
- IPTR(IBindHost) pBindHost;
- IPTR(IServiceProvider) pServiceProvider;
- HRESULT hr=pServiceProvider.QueryInterface(pUnknown);
- if (SUCCEEDED(hr) && pServiceProvider.GetInterfacePtr())
- pBindHost = _AfxTrySPForBindHost(pServiceProvider);
- if (!pBindHost.GetInterfacePtr())
- pBindHost = _AfxTryQIForBindHost(pUnknown);
- if (pBindHost.GetInterfacePtr())
- return Open(lpszURL, (IBindHost*)pBindHost, pError);
-
- return CAsyncMonikerFile::Open(lpszURL, pError);
- }
-
- BOOL CAsyncMonikerFile::Open(IMoniker* pMoniker,
- IServiceProvider* pServiceProvider, CFileException* pError)
- {
- if (!pServiceProvider)
- return Open(pMoniker, pError);
- IPTR(IBindHost) pBindHost;
- pBindHost = _AfxTrySPForBindHost(pServiceProvider);
- if (!pBindHost.GetInterfacePtr())
- pBindHost = _AfxTryQIForBindHost(pServiceProvider);
- if (pBindHost.GetInterfacePtr())
- return Open(pMoniker, (IBindHost*)pBindHost, pError);
- return Open(pMoniker, pError);
- }
-
- BOOL CAsyncMonikerFile::Open(IMoniker* pMoniker,
- IUnknown* pUnknown, CFileException* pError)
- {
- if (!pUnknown)
- return Open(pMoniker, pError);
- IPTR(IBindHost) pBindHost;
- IPTR(IServiceProvider) pServiceProvider;
- HRESULT hr=pServiceProvider.QueryInterface(pUnknown);
- if (SUCCEEDED(hr) && pServiceProvider.GetInterfacePtr())
- pBindHost = _AfxTrySPForBindHost(pServiceProvider);
- if (!pBindHost.GetInterfacePtr())
- pBindHost = _AfxTryQIForBindHost(pServiceProvider);
- if (pBindHost.GetInterfacePtr())
- return Open(pMoniker, (IBindHost*)pBindHost, pError);
- return Open(pMoniker, pError);
- }
-
- BOOL CAsyncMonikerFile::PostBindToStream(CFileException* pError)
- {
- if (S_OK == IsAsyncMoniker(GetMoniker()))
- return TRUE;
- return CMonikerFile::PostBindToStream(pError);
- }
-
- IUnknown* CAsyncMonikerFile::CreateBindStatusCallback(IUnknown* pUnkControlling)
- {
- ASSERT(NULL == m_pAfxBSCCurrent); // Set by Close()
- m_pAfxBSCCurrent = new _AfxBindStatusCallback(this, pUnkControlling);
- IUnknown* pUnkInner = m_pAfxBSCCurrent->GetInnerUnknown();
- ASSERT(pUnkInner != NULL);
- //Reference inner unknown for m_pAfxBSCCurrent
- pUnkInner->AddRef();
- //Reference inner unknown for return value.
- pUnkInner->AddRef();
- return pUnkInner;
- }
-
- DWORD CAsyncMonikerFile::GetBindInfo() const
- {
- return BINDF_ASYNCHRONOUS|BINDF_ASYNCSTORAGE;
- }
-
- LONG CAsyncMonikerFile::GetPriority() const
- {
- return THREAD_PRIORITY_NORMAL;
- }
-
- void CAsyncMonikerFile::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)
- {
- UNUSED_ALWAYS(dwSize);
- UNUSED_ALWAYS(bscfFlag);
- }
-
- void CAsyncMonikerFile::OnLowResource()
- {
- }
-
- void CAsyncMonikerFile::OnStartBinding()
- {
- }
-
- void CAsyncMonikerFile::OnStopBinding(HRESULT hresult, LPCTSTR szError)
- {
- UNUSED_ALWAYS(hresult);
- UNUSED_ALWAYS(szError);
- }
-
- void CAsyncMonikerFile::OnProgress(ULONG ulProgress, ULONG ulProgressMax,
- ULONG ulStatusCode, LPCTSTR szStatusText)
- {
- UNUSED_ALWAYS(ulProgress);
- UNUSED_ALWAYS(ulProgressMax);
- UNUSED_ALWAYS(ulStatusCode);
- UNUSED_ALWAYS(szStatusText);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CAsyncMonikerFile diagnostics
-
- #ifdef _DEBUG
- void CAsyncMonikerFile::AssertValid() const
- {
- if (m_pAfxBSCCurrent)
- {
- ASSERT(m_pAfxBSCCurrent->GetOwner() == this);
- ASSERT(m_pAfxBSCCurrent->GetRefcount() > 0);
- #ifdef _AFXDLL
- ASSERT(m_pAfxBSCCurrent->GetModuleState() == AfxGetModuleState());
- #endif
- ASSERT(m_pAfxBSCCurrent->GetpThisOfInnerUnknown() == m_pAfxBSCCurrent);
- }
- CMonikerFile::AssertValid();
- }
-
- void CAsyncMonikerFile::Dump(CDumpContext& dc) const
- {
- CMonikerFile::Dump(dc);
-
- dc << "\nm_Binding = " << m_Binding.GetInterfacePtr();
- dc << "\nm_pFormatEtc = " << m_pFormatEtc;
- dc << "\nm_pAfxBSCCurrent = " << m_pAfxBSCCurrent;
- if (m_pAfxBSCCurrent)
- {
- dc << "\nm_pAfxBSCCurrent->GetOwner() = " << m_pAfxBSCCurrent->GetOwner();
- dc << "\nm_pAfxBSCCurrent->GetRefcount() = " << m_pAfxBSCCurrent->GetRefcount();
- dc << "\nm_pAfxBSCCurrent->GetControllingUnknown() = " << m_pAfxBSCCurrent->GetControllingUnknown();
- dc << "\nm_pAfxBSCCurrent->GetInnerUnknown() = " << m_pAfxBSCCurrent->GetInnerUnknown();
- dc << "\nm_pAfxBSCCurrent->GetpThisOfInnerUnknown() = " << m_pAfxBSCCurrent->GetpThisOfInnerUnknown();
- #ifdef _AFXDLL
- dc << "\nm_pAfxBSCCurrent->GetModuleState() = " << m_pAfxBSCCurrent->GetModuleState();
- #endif
- }
- dc << "\n";
- }
- #endif
-
- ////////////////////////////////////////////////////////////////////////////
-
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
-
- IMPLEMENT_DYNAMIC(CAsyncMonikerFile, CMonikerFile)
-
- ////////////////////////////////////////////////////////////////////////////
-