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)
-
- /////////////////////////////////////////////////////////////////////////////
- // _AfxBindHost for CMonikerFile implementation
-
- class _AfxBindHost: public IBindHost
- {
- private:
- long m_dwRef;
- public:
- inline _AfxBindHost() : m_dwRef(0) {}
-
- inline ~_AfxBindHost() { ASSERT(m_dwRef == 0); }
-
- STDMETHOD_(ULONG, AddRef)()
- {
- return InterlockedIncrement(&m_dwRef);
- }
-
- STDMETHOD_(ULONG, Release)()
- {
- unsigned long lResult = InterlockedDecrement(&m_dwRef);
- if (lResult == 0)
- delete this;
- 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 || iid == IID_IBindHost)
- {
- *ppvObject = (IBindHost*)this;
- InterlockedIncrement(&m_dwRef);
- return S_OK;
- }
-
- // otherwise, incorrect IID, and thus error
- return E_NOINTERFACE;
- }
-
- STDMETHOD(CreateMoniker)(
- /* [in] */ LPOLESTR szName,
- /* [in] */ IBindCtx __RPC_FAR *pBC,
- /* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmk,
- /* [in] */ DWORD dwReserved)
- {
- UNUSED_ALWAYS(dwReserved);
- UNUSED_ALWAYS(pBC);
-
- if (!szName || !ppmk) return E_POINTER;
- if (!*szName) return E_INVALIDARG;
-
- *ppmk = NULL;
- HRESULT hr = S_OK;
-
- hr = CreateURLMoniker(NULL, szName, ppmk);
- if (SUCCEEDED(hr) && !*ppmk)
- hr = E_FAIL;
- return hr;
- }
-
- STDMETHOD(MonikerBindToStorage)(
- /* [in] */ IMoniker __RPC_FAR *pMk,
- /* [in] */ IBindCtx __RPC_FAR *pBC,
- /* [in] */ IBindStatusCallback __RPC_FAR *pBSC,
- /* [in] */ REFIID riid,
- /* [out] */ void __RPC_FAR *__RPC_FAR *ppvObj)
- {
- if (!pMk || !ppvObj) return E_POINTER;
-
- *ppvObj = NULL;
- HRESULT hr = S_OK;
- IPTR(IBindCtx) BindCtx;
- if (pBC)
- {
- BindCtx = pBC;
- if (pBSC)
- {
- #ifdef _DEBUG
- IPTR(IBindStatusCallback) pBSCPrev;
- #endif
- hr = RegisterBindStatusCallback(BindCtx, pBSC,
- #ifdef _DEBUG
- &pBSCPrev,
- #else
- NULL,
- #endif
- 0);
- ASSERT(!pBSCPrev);
- if (FAILED(hr))
- return hr;
- }
- }
- else
- {
- if (pBSC)
- hr = CreateAsyncBindCtx(0, pBSC, NULL, &BindCtx);
- else
- hr = CreateBindCtx(0, &BindCtx);
- if (SUCCEEDED(hr) && !BindCtx)
- hr = E_FAIL;
- if (FAILED(hr))
- return hr;
- }
- return pMk->BindToStorage(BindCtx, NULL, riid, ppvObj);
- }
-
- private:
- STDMETHOD(MonikerBindToObject)(
- /* [in] */ IMoniker __RPC_FAR *pMk,
- /* [in] */ IBindCtx __RPC_FAR *pBC,
- /* [in] */ IBindStatusCallback __RPC_FAR *pBSC,
- /* [in] */ REFIID riid,
- /* [out] */ void __RPC_FAR *__RPC_FAR *ppvObj)
- {
- ASSERT(FALSE);
- UNUSED_ALWAYS(pMk);
- UNUSED_ALWAYS(pBC);
- UNUSED_ALWAYS(pBSC);
- UNUSED_ALWAYS(riid);
- UNUSED_ALWAYS(ppvObj);
- return E_NOTIMPL;
- }
- };
-
- /////////////////////////////////////////////////////////////////////////////
- // CMonikerFile implementation
-
- CMonikerFile::~CMonikerFile()
- {
- ASSERT_VALID(this);
- Close();
- }
-
- void CMonikerFile::Flush()
- {
- ASSERT_VALID(this);
- ASSERT(GetStream() != NULL);
-
- GetStream()->Commit(0);
- }
-
- BOOL CMonikerFile::Open(LPCTSTR lpszUrl, IBindHost* pBindHost,
- IBindStatusCallback* pBSC, IBindCtx* pBindCtx, CFileException* pError)
- {
- ASSERT_VALID(this);
- Close(); // These objects are reopenable
- return Attach(lpszUrl, pBindHost, pBSC, pBindCtx, pError);
- }
-
- BOOL CMonikerFile::Attach(LPCTSTR lpszUrl, IBindHost* pBindHost,
- IBindStatusCallback* pBSC, IBindCtx* pBindCtx, CFileException* pError)
- {
- ASSERT(!m_Moniker);
- ASSERT(!GetStream());
- USES_CONVERSION;
-
- ASSERT(NULL == lpszUrl || AfxIsValidString(lpszUrl));
- ASSERT(NULL == pError ||
- AfxIsValidAddress(pError, sizeof(CFileException)));
- ASSERT(NULL != pBindHost);
-
- // Check for empty path
- if (!lpszUrl || !*lpszUrl)
- {
- if (pError)
- {
- pError->m_cause=CFileException::badPath;
- pError->m_strFileName=lpszUrl;
- }
- return FALSE;
- }
-
- // Create the moniker
- HRESULT hr;
- IPTR(IMoniker) pMoniker;
-
- hr = pBindHost->CreateMoniker(T2OLE((LPTSTR) lpszUrl), pBindCtx,
- reinterpret_cast<IMoniker**>(&pMoniker), 0);
-
- if (FAILED(hr))
- {
- if (pError) _AfxFillOleFileException(pError, hr);
- return FALSE;
- }
-
- return Attach(pMoniker, pBindHost, pBSC, pBindCtx, pError);
- }
-
- BOOL CMonikerFile::Open(LPCTSTR lpszUrl, CFileException* pError)
- {
- IPTR(IBindHost) pBindHost(CreateBindHost(), FALSE);
- IPTR(IBindCtx) pBindCtx(CreateBindContext(pError), FALSE);
-
- return Open(lpszUrl, pBindHost, NULL, pBindCtx, pError);
- }
-
- BOOL CMonikerFile::Open(IMoniker* pMoniker, CFileException* pError)
- {
- Close(); // These objects are reopenable
- IPTR(IBindHost) pBindHost(CreateBindHost(), FALSE);
- IPTR(IBindCtx) pBindCtx(CreateBindContext(pError), FALSE);
-
- return Attach(pMoniker, pBindHost, NULL, pBindCtx, pError);
- }
-
- BOOL CMonikerFile::Open(IMoniker* pMoniker, IBindHost* pBindHost,
- IBindStatusCallback* pBSC, IBindCtx* pBindCtx, CFileException* pError)
- {
- Close();
- return Attach(pMoniker, pBindHost, pBSC, pBindCtx, pError);
- }
-
- BOOL CMonikerFile::Attach(IMoniker* pMoniker, IBindHost* pBindHost,
- IBindStatusCallback* pBSC, IBindCtx* pBindCtx, CFileException* pError)
- {
- ASSERT_VALID(this);
- ASSERT(pMoniker);
- ASSERT(!m_Moniker);
- ASSERT(!GetStream());
- m_Moniker=pMoniker;
-
- IPTR(IStream) pStream;
- HRESULT hr=pBindHost->MonikerBindToStorage(pMoniker, pBindCtx, pBSC,
- IID_IStream, reinterpret_cast<void**>(&pStream));
- if (FAILED(hr))
- {
- if (pError) _AfxFillOleFileException(pError, hr);
- return FALSE;
- }
-
- // If this is really a CAsyncMonikerFile, then we may have attached to the stream
- // within MonikerBindToStorage, in which case we want to avoid doing so here.
- if (pStream.GetInterfacePtr() && !GetStream())
- {
- // Attach this to the stream, transferring the reference
- // COleStreamFile::Attach doesn't increment pStream's refcount
- COleStreamFile::Attach(pStream);
- pStream.Detach();
- }
-
- return PostBindToStream(pError);
- }
-
- void CMonikerFile::Close()
- {
- if (m_Moniker.GetInterfacePtr())
- m_Moniker.Release();
- COleStreamFile::Close();
- }
-
- BOOL CMonikerFile::Detach(CFileException* pError)
- {
- ASSERT_VALID(this);
- ASSERT(!!m_Moniker);
-
- TRY
- {
- Close();
- }
- CATCH (CFileException, e)
- {
- if (pError)
- {
- pError->m_cause=e->m_cause;
- pError->m_lOsError=e->m_lOsError;
- pError->m_strFileName=e->m_strFileName;
- }
- DELETE_EXCEPTION(e);
- return FALSE;
- }
- END_CATCH;
-
- return TRUE;
- }
-
- IBindHost* CMonikerFile::CreateBindHost()
- {
- IBindHost* pBindHost = new _AfxBindHost();
- pBindHost->AddRef();
- return pBindHost;
- }
-
- IBindCtx* CMonikerFile::CreateBindContext(CFileException* pError)
- {
- UNUSED_ALWAYS(pError);
- return NULL;
- }
-
- // So that CMonikerFile can check for a null pStream and CAsyncMonikerFile can ignore it
- BOOL CMonikerFile::PostBindToStream(CFileException* pError)
- {
- if (!GetStream())
- {
- if (pError) _AfxFillOleFileException(pError, E_UNEXPECTED);
- TRY
- {
- Close();
- }
- CATCH_ALL(e)
- {
- DELETE_EXCEPTION(e);
- }
- END_CATCH_ALL
- return FALSE;
- }
- return TRUE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CMonikerFile diagnostics
-
- #ifdef _DEBUG
- void CMonikerFile::AssertValid() const
- {
- COleStreamFile::AssertValid();
- }
-
- void CMonikerFile::Dump(CDumpContext& dc) const
- {
- COleStreamFile::Dump(dc);
-
- dc << "\nm_Moniker = " << m_Moniker.GetInterfacePtr();
- dc << "\n";
- }
- #endif
-
- ////////////////////////////////////////////////////////////////////////////
-
- #ifndef _AFX_ENABLE_INLINES
-
- // expand inlines for OLE general APIs
- static char _szAfxOleInl[] = "afxole.inl";
- #undef THIS_FILE
- #define THIS_FILE _szAfxOleInl
- #define _AFXOLEMONIKER_INLINE
- #include "afxole.inl"
-
- #endif //!_AFX_ENABLE_INLINES
-
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
-
- IMPLEMENT_DYNAMIC(CMonikerFile, COleStreamFile)
-
- ////////////////////////////////////////////////////////////////////////////
-