home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap09 / linksrc / fileobj.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  8KB  |  378 lines

  1. /*
  2.  * FILEOBJ.CPP
  3.  * File Object for Link Source, Chapter 9
  4.  *
  5.  * Implementation of a "file" object named with a file moniker,
  6.  * which implements IPersistFile, IOleItemContainer, and
  7.  * IDescription.  The latter two interfaces are implemented
  8.  * generically in IOLECONT.CPP and IDESCRIP.CPP.
  9.  *
  10.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  11.  *
  12.  * Kraig Brockschmidt, Microsoft
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include "linksrc.h"
  19.  
  20. #ifdef WIN32ANSI
  21. /*
  22.  * This is to turn off the mapping to ANSI wrapper APIs because
  23.  * we're actually using wide char strings under Win32 all the time
  24.  * in parts of this code.
  25.  */
  26. #undef StgOpenStorage
  27. #define StgOpenStorage StgOpenStorage
  28.  
  29. #undef CreateFileMoniker
  30. #define CreateFileMoniker CreateFileMoniker
  31. #endif
  32.  
  33.  
  34. /*
  35.  * CFileObject::CFileObject
  36.  * CFileObject::~CFileObject
  37.  *
  38.  * Parameters (Constructor):
  39.  *  pUnkOuter       LPUNKNOWN of a controlling unknown.
  40.  *  pfnDestroy      PFNDESTROYED to call when an object
  41.  *                  is destroyed.
  42.  */
  43.  
  44. CFileObject::CFileObject(LPUNKNOWN pUnkOuter
  45.     , PFNDESTROYED pfnDestroy)
  46.     {
  47.     m_cRef=0;
  48.     m_pUnkOuter=pUnkOuter;
  49.     m_pfnDestroy=pfnDestroy;
  50.  
  51.     m_clsID=CLSID_LinkedFile;
  52.     m_szFile[0]=(OLECHAR)0;
  53.     m_pIStorage=NULL;
  54.     m_pmk=NULL;
  55.     m_dwRegROT=0;
  56.  
  57.     m_pImpIPersistFile=NULL;
  58.     m_pImpIOleItemContainer=NULL;
  59.     m_pImpIDescription=NULL;
  60.  
  61.     return;
  62.     }
  63.  
  64. CFileObject::~CFileObject(void)
  65.     {
  66.     //Remove us from the running object table
  67.     if (0!=m_dwRegROT)
  68.         {
  69.         IRunningObjectTable    *pROT;
  70.  
  71.         if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
  72.             {
  73.             pROT->Revoke(m_dwRegROT);
  74.             pROT->Release();
  75.             }
  76.         }
  77.  
  78.     ReleaseInterface(m_pmk);
  79.     ReleaseInterface(m_pIStorage);
  80.     DeleteInterfaceImp(m_pImpIDescription);
  81.     DeleteInterfaceImp(m_pImpIOleItemContainer);
  82.     DeleteInterfaceImp(m_pImpIPersistFile);
  83.     return;
  84.     }
  85.  
  86.  
  87.  
  88. /*
  89.  * CFileObject::Init
  90.  *
  91.  * Purpose:
  92.  *  Performs any intiailization of a CFileObject that's prone to
  93.  *  failure that we also use internally before exposing the object
  94.  *  outside.
  95.  *
  96.  * Parameters:
  97.  *  None
  98.  *
  99.  * Return Value:
  100.  *  BOOL            TRUE if the function is successful,
  101.  *                  FALSE otherwise.
  102.  */
  103.  
  104. BOOL CFileObject::Init(void)
  105.     {
  106.     IUnknown   *pUnk=this;
  107.  
  108.     if (NULL!=m_pUnkOuter)
  109.         pUnk=m_pUnkOuter;
  110.  
  111.     m_pImpIPersistFile=new CImpIPersistFile(this, pUnk);
  112.  
  113.     if (NULL==m_pImpIPersistFile)
  114.         return FALSE;
  115.  
  116.     m_pImpIOleItemContainer=new CImpIOleItemContainer(this, pUnk
  117.         , TRUE);
  118.  
  119.     if (NULL==m_pImpIOleItemContainer)
  120.         return FALSE;
  121.  
  122.     m_pImpIDescription=new CImpIDescription(pUnk);
  123.  
  124.     if (NULL==m_pImpIDescription)
  125.         return FALSE;
  126.  
  127.     return TRUE;
  128.     }
  129.  
  130.  
  131.  
  132.  
  133. /*
  134.  * CFileObject::QueryInterface
  135.  * CFileObject::AddRef
  136.  * CFileObject::Release
  137.  *
  138.  * Purpose:
  139.  *  IUnknown members for CFileObject object.
  140.  */
  141.  
  142. STDMETHODIMP CFileObject::QueryInterface(REFIID riid, PPVOID ppv)
  143.     {
  144.     *ppv=NULL;
  145.  
  146.     if (IID_IUnknown==riid)
  147.         *ppv=this;
  148.  
  149.     if (IID_IPersist==riid || IID_IPersistFile==riid)
  150.         *ppv=m_pImpIPersistFile;
  151.  
  152.     if (IID_IParseDisplayName==riid || IID_IOleContainer==riid
  153.         || IID_IOleItemContainer==riid)
  154.         *ppv=m_pImpIOleItemContainer;
  155.  
  156.     if (IID_IDescription==riid)
  157.         *ppv=m_pImpIDescription;
  158.  
  159.     if (NULL!=*ppv)
  160.         {
  161.         ((LPUNKNOWN)*ppv)->AddRef();
  162.         return NOERROR;
  163.         }
  164.  
  165.     return ResultFromScode(E_NOINTERFACE);
  166.     }
  167.  
  168.  
  169. STDMETHODIMP_(ULONG) CFileObject::AddRef(void)
  170.     {
  171.     return ++m_cRef;
  172.     }
  173.  
  174.  
  175. STDMETHODIMP_(ULONG) CFileObject::Release(void)
  176.     {
  177.     if (0L!=--m_cRef)
  178.         return m_cRef;
  179.  
  180.     if (NULL!=m_pfnDestroy)
  181.         (*m_pfnDestroy)();
  182.  
  183.     delete this;
  184.     return 0;
  185.     }
  186.  
  187.  
  188.  
  189.  
  190. /**
  191.  ** IPersistFile implementation
  192.  **/
  193.  
  194. /*
  195.  * CImpIPersistFile:CImpIPersistFile
  196.  * CImpIPersistFile::~CImpIPersistFile
  197.  * CImpIPersistFile::QueryInterface
  198.  * CImpIPersistFile::AddRef
  199.  * CImpIPersistFile::Release
  200.  *
  201.  * Basic object members.
  202.  */
  203.  
  204. CImpIPersistFile::CImpIPersistFile(PCFileObject pObj
  205.     , LPUNKNOWN pUnkOuter)
  206.     {
  207.     m_cRef=0;
  208.     m_pObj=pObj;
  209.     m_pUnkOuter=pUnkOuter;
  210.     return;
  211.     }
  212.  
  213. CImpIPersistFile::~CImpIPersistFile(void)
  214.     {
  215.     return;
  216.     }
  217.  
  218. STDMETHODIMP CImpIPersistFile::QueryInterface(REFIID riid
  219.     , LPVOID *ppv)
  220.     {
  221.     return m_pUnkOuter->QueryInterface(riid, ppv);
  222.     }
  223.  
  224. STDMETHODIMP_(ULONG) CImpIPersistFile::AddRef(void)
  225.     {
  226.     ++m_cRef;
  227.     return m_pUnkOuter->AddRef();
  228.     }
  229.  
  230. STDMETHODIMP_(ULONG) CImpIPersistFile::Release(void)
  231.     {
  232.     --m_cRef;
  233.     return m_pUnkOuter->Release();
  234.     }
  235.  
  236.  
  237.  
  238.  
  239.  
  240. /*
  241.  * CImpIPersistFile::GetClassID
  242.  * CImpIPersistFile::IsDirty
  243.  * CImpIPersistFile::Save
  244.  * CImpIPersistFile::SaveCompleted
  245.  *
  246.  * Trivial or unimplemented members.
  247.  */
  248.  
  249. STDMETHODIMP CImpIPersistFile::GetClassID(LPCLSID pClsID)
  250.     {
  251.     *pClsID=m_pObj->m_clsID;
  252.     return NOERROR;
  253.     }
  254.  
  255. STDMETHODIMP CImpIPersistFile::IsDirty(void)
  256.     {
  257.     //We're never dirty
  258.     return ResultFromScode(S_FALSE);
  259.     }
  260.  
  261. STDMETHODIMP CImpIPersistFile::Save(LPCOLESTR pszFile, BOOL fRemember)
  262.     {
  263.     return ResultFromScode(E_NOTIMPL);
  264.     }
  265.  
  266. STDMETHODIMP CImpIPersistFile::SaveCompleted(LPCOLESTR pszFile)
  267.     {
  268.     return NOERROR;
  269.     }
  270.  
  271.  
  272.  
  273.  
  274.  
  275. /*
  276.  * CImpIPersistFile::Load
  277.  *
  278.  * Purpose:
  279.  *  Asks the server to load the document for the given filename.
  280.  *
  281.  * Parameters:
  282.  *  pszFile         LPCOLESTR of the filename to load.
  283.  *  grfMode         DWORD flags to use when opening the file.
  284.  */
  285.  
  286. STDMETHODIMP CImpIPersistFile::Load(LPCOLESTR pszFile, DWORD grfMode)
  287.     {
  288.     const int   cch=512;
  289.     HRESULT     hr;
  290.  
  291.     //We should only be loaded once; having a moniker tells us
  292.     if (NULL!=m_pObj->m_pmk)
  293.         return ResultFromScode(E_UNEXPECTED);
  294.  
  295.     /*
  296.      * Since the server is single-use, we can be assured that
  297.      * this Load will only happen once, so we can hold the
  298.      * IStorage until the object is released.
  299.      */
  300.     hr=StgOpenStorage(pszFile, NULL
  301.         , STGM_TRANSACTED | STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0
  302.         , &m_pObj->m_pIStorage);
  303.  
  304.     if (FAILED(hr))
  305.         return hr;
  306.  
  307.     m_pObj->m_pImpIDescription->SetStorage(m_pObj->m_pIStorage);
  308.  
  309.     /*
  310.      * We opened it successfully, and that's all we have to
  311.      * do, so we can simply save the filename.
  312.      */
  313.    #ifdef WIN32ANSI
  314.     wcsncpy(m_pObj->m_szFile, pszFile, cch);
  315.    #else
  316.     lstrcpyn(m_pObj->m_szFile, pszFile, cch);
  317.    #endif
  318.  
  319.     /*
  320.      * Create a moniker for this file object and register as
  321.      * running.
  322.      */
  323.     if (SUCCEEDED(CreateFileMoniker(pszFile, &m_pObj->m_pmk)))
  324.         {
  325.         IRunningObjectTable    *pROT;
  326.  
  327.         if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
  328.             {
  329.             //Register as weak so clients can free us
  330.             pROT->Register(0, m_pObj, m_pObj->m_pmk
  331.                 , &m_pObj->m_dwRegROT);
  332.             pROT->Release();
  333.             }
  334.         }
  335.  
  336.     return NOERROR;
  337.     }
  338.  
  339.  
  340.  
  341. /*
  342.  * CImpIPersistFile::GetCurFile
  343.  *
  344.  * Purpose:
  345.  *  Returns the current filename.
  346.  *
  347.  * Parameters:
  348.  *  ppszFile        LPOLESTR * into which we store a pointer to
  349.  *                  the filename that should be allocated with the
  350.  *                  shared IMalloc.
  351.  */
  352.  
  353. STDMETHODIMP CImpIPersistFile::GetCurFile(LPOLESTR *ppszFile)
  354.     {
  355.     LPMALLOC    pIMalloc;
  356.     const int   cch=512;
  357.     LPOLESTR    psz;
  358.  
  359.     *ppszFile=NULL;
  360.  
  361.     if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  362.         return ResultFromScode(E_FAIL);
  363.  
  364.     psz=(LPOLESTR)pIMalloc->Alloc(cch*sizeof(OLECHAR));
  365.     pIMalloc->Release();
  366.  
  367.     if (NULL==psz)
  368.         return ResultFromScode(E_OUTOFMEMORY);
  369.  
  370.    #ifdef WIN32ANSI
  371.     wcsncpy(psz, m_pObj->m_szFile, cch);
  372.    #else
  373.     lstrcpyn(psz, m_pObj->m_szFile, cch);
  374.    #endif
  375.     *ppszFile=psz;
  376.     return NOERROR;
  377.     }
  378.