home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / BOCOLE.PAK / BOLEFACT.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  8KB  |  337 lines

  1. //
  2. //**************************************************************************
  3. //
  4. // BOleFact.cpp -- Implements the server-side helper for allowing OLE2 to
  5. //                 create objects made available by Bolero server apps.
  6. //
  7. // Copyright (c) 1993,94 by Borland International, Inc. All rights reserved
  8. //
  9. //**************************************************************************
  10.  
  11. #include "BOleFact.h"
  12. #include "BOleSvc.h"
  13. #include "BOleIPS.h"
  14. #include "BOleCMan.h"
  15.  
  16.  
  17. //
  18. //    DllGetClassObject
  19. //
  20. //
  21. //
  22. //
  23.  
  24. STDAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void FAR* FAR* ppv)
  25. {
  26.     HRESULT hRes =  ResultFromScode(E_OUTOFMEMORY);
  27.     return hRes;
  28. }
  29.  
  30.  
  31. STDAPI  DllCanUnloadNow()
  32. {
  33.     return ResultFromScode( S_OK );
  34. }
  35.  
  36.  
  37. BOleFact::BOleFact(BOleClassManager * pFact, IBUnknownMain *pOuter):
  38.         RefCnt (1), 
  39.         pObjCM(NULL), 
  40.         hReg (0L), 
  41.         regId (0),
  42.         dwRegisterActiveObject (0),
  43.         id (CLSID_NULL), 
  44.         BOleComponent(pFact, (IBUnknownMain *) this),
  45.         pIPEFact (NULL)
  46. {
  47. }
  48.  
  49. BOleFact::~BOleFact()
  50. {
  51.     if (pIPEFact) {
  52.         pIPEFact->Release();
  53.         pIPEFact = NULL;
  54.     }
  55. }
  56.  
  57. HRESULT _IFUNC BOleFact::QueryInterfaceMain(REFIID iid, LPVOID FAR* ppv)
  58. {
  59.     HRESULT hr = ResultFromScode(E_NOINTERFACE);
  60.     *ppv = NULL;
  61.  
  62.     // interfaces
  63.     
  64.     SUCCEEDED(hr = IBClass_QueryInterface(this, iid, ppv))
  65.  
  66.     // base classes
  67.     
  68.     || SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(iid, ppv))
  69.         
  70.     // helpers
  71.     ;
  72.  
  73.     return hr;
  74. }
  75.  
  76. HRESULT _IFUNC BOleFact::Init (BOOL fInProc, LPCOLESTR szProgId, IBClassMgr *pCM, BCID rid)
  77. {
  78.     pObjCM = pCM;
  79.     regId = rid;
  80.  
  81.     // If the user's object is capable of being instantiated in its own
  82.     // container, create a special BOleInProcFactory
  83.     //
  84.     if (fInProc) {
  85.         pIPEFact = new BOleInProcFactory (pFactory, this, id);
  86.         if (!pIPEFact)
  87.             return ResultFromScode(E_OUTOFMEMORY);
  88.     }
  89.  
  90.     return CLSIDFromProgID(szProgId, &id);
  91. }
  92.  
  93. HRESULT _IFUNC BOleFact::Register (BOOL fSingleUse)
  94. {
  95.     HRESULT hErr;
  96.  
  97.     // register the class factory for this id
  98.     //
  99.     if (!SUCCEEDED(hErr = CoRegisterClassObject(
  100.         id,
  101.         (IClassFactory *)this,
  102.         CLSCTX_LOCAL_SERVER,
  103.         fSingleUse ? REGCLS_SINGLEUSE : REGCLS_MULTI_SEPARATE,
  104.         &hReg))) {
  105.         OLEHRES("Failed Registering", hErr);
  106.         }
  107.  
  108.     // Register the embedding helper factory if we embed in ourselves
  109.     if (pIPEFact) {
  110.         if (!SUCCEEDED(hErr = pIPEFact->Register (fSingleUse)))
  111.             return hErr;
  112.     }
  113.  
  114.     // The online dox for CoLockObjectExternal say we should do this here
  115.     //
  116.     if (SUCCEEDED(hErr)) {
  117.         LPCLASSFACTORY pWorkAround = this;
  118.         CoLockObjectExternal (pWorkAround, TRUE, TRUE);
  119.     }
  120.     
  121.     // if the class manager supports automation let's register it as "Active"
  122.     //
  123.     IDispatch *pDispatch;
  124.     if (SUCCEEDED(pObjCM->QueryInterface(IID_IDispatch, &(LPVOID)pDispatch))) {
  125.         RegisterActiveObject (pDispatch, id, NULL, &dwRegisterActiveObject);
  126.         pDispatch->Release();
  127.     }
  128.     return hErr;
  129. }
  130.  
  131. HRESULT _IFUNC BOleFact::Revoke ()
  132. {
  133.     if (hReg) {
  134.         LPCLASSFACTORY pWorkAround = this;
  135.         CoLockObjectExternal (pWorkAround, FALSE, TRUE);
  136.         CoRevokeClassObject( hReg);
  137.         hReg = 0;
  138.     }
  139.  
  140.     if (dwRegisterActiveObject) {
  141.         RevokeActiveObject (dwRegisterActiveObject, NULL);
  142.         dwRegisterActiveObject = 0;
  143.     }
  144.  
  145.     if (pIPEFact) {
  146.         pIPEFact->Revoke ();
  147.         pIPEFact->Release ();
  148.         pIPEFact = NULL;
  149.     }
  150.     return NOERROR;
  151. }
  152.  
  153. HRESULT _IFUNC BOleFact::GetClassID (LPCLSID pClass)
  154. {
  155.     *pClass = id;
  156.     return NOERROR;
  157. }
  158.  
  159. BOOL _IFUNC BOleFact::IsA (REFCLSID cid)
  160. {
  161.     return IsEqualCLSID(cid, id);
  162. }
  163.  
  164. HRESULT _IFUNC BOleFact::CreateInstance(IUnknown FAR* pUnk, REFIID iid, LPVOID  FAR* ppv)
  165. {
  166.     HRESULT hr = ResultFromScode(E_FAIL);
  167.     *ppv = 0L;
  168.  
  169.     PIUnknown pObj;
  170.     IBClassMgr * pICM;
  171.         
  172.     if (SUCCEEDED(pObjCM->QueryInterface(IID_IBClassMgr, &(LPVOID)pICM))) {
  173.         if (SUCCEEDED(pICM->ComponentCreate(&pObj, pUnk, regId))) {
  174.             if (pUnk && iid == IID_IUnknown) {
  175.                 hr = NOERROR;            
  176.                 *ppv = pObj;    // always give out main IUnknown
  177.             }
  178.             else {
  179.                 hr = pObj->QueryInterface(iid, ppv);
  180.                 pObj->Release();    // QI bumps
  181.             }
  182.         }
  183.         pICM->Release();
  184.     }
  185.  
  186.     return hr;
  187. }
  188.  
  189.  
  190. HRESULT _IFUNC BOleFact::LockServer( BOOL fLock )
  191. {
  192.     LPCLASSFACTORY pICF = this;
  193.     CoLockObjectExternal(pICF, fLock, TRUE);
  194.     pFactory->ServerCount( fLock ? 1L : -1L);
  195.     
  196.     return NOERROR;
  197. }
  198.  
  199. // Used by DllGetClassObject to return the interface to the factory which
  200. // creates the default handler which will create the in-proc server object.
  201. //
  202. HRESULT _IFUNC BOleFact::GetEmbeddingHelperFactory (LPUNKNOWN *ppF)
  203. {
  204.     if (pIPEFact) {
  205.         *ppF = pIPEFact;
  206.         (*ppF)->AddRef();
  207.         return NOERROR;
  208.     }
  209.     else {
  210.         *ppF = NULL;
  211.         return ResultFromScode(E_FAIL);
  212.     }
  213. }
  214.  
  215. // When Bolero container-side dialog boxes need to know whether to put the
  216. // CLSID for our own factories in the dialog box, this is how they find out
  217. //
  218. BOOL _IFUNC BOleFact::AllowEmbedFromSelf ()
  219. {
  220.     return pIPEFact ? TRUE : FALSE;
  221. }
  222.  
  223. //**************************************************************************
  224. //
  225. // BOleInProcFactory -- The role of this factory is to load the default
  226. //                      handler on the server side when the container 
  227. //                      side of an app needs to instantiate an object it 
  228. //                      serves. 
  229. //
  230. //                      If we don't do this, the RPC/handler system 
  231. //                      creates the server object as if it were an inproc 
  232. //                      server with no handler, but our EXE-based objects 
  233. //                      must use the default handler.
  234. //
  235. //**************************************************************************
  236.  
  237. //***********************************
  238. //
  239. // Implementation methods
  240. //
  241. //***********************************
  242.  
  243. BOleInProcFactory::BOleInProcFactory (BOleClassManager *pCM, BOleFact FAR *pF, REFIID iid) :  BOleComponent(pCM, NULL),
  244.     iidServer (iid),
  245.     nRef (1),
  246.     pRealFactory (pF),
  247.     regCookie (0)
  248. {
  249.     pF->AddRef();
  250. }
  251.  
  252. BOleInProcFactory::~BOleInProcFactory ()
  253. {
  254.     if (pRealFactory) {
  255.         pRealFactory->Release();
  256.         pRealFactory = NULL;
  257.     }
  258. }
  259.  
  260. HRESULT _IFUNC BOleInProcFactory::Register (BOOL fSingleUse)
  261. {
  262.     HRESULT hr =  ::CoRegisterClassObject (
  263.         iidServer, this, CLSCTX_INPROC_SERVER, 
  264.         fSingleUse ? REGCLS_SINGLEUSE : REGCLS_MULTI_SEPARATE, ®Cookie);
  265.  
  266.     if (SUCCEEDED(hr)) {
  267.         LPCLASSFACTORY pWorkAround = this;
  268.         CoLockObjectExternal (pWorkAround, TRUE, TRUE);
  269.     }
  270.  
  271.     return hr;
  272. }
  273.  
  274. HRESULT _IFUNC BOleInProcFactory::Revoke ()
  275. {
  276.     if (regCookie) {
  277.         LPCLASSFACTORY pWorkAround = this;
  278.         CoLockObjectExternal (pWorkAround, FALSE, TRUE);
  279.         return ::CoRevokeClassObject (regCookie);
  280.     }
  281.  
  282.     if (pRealFactory) {               // this breaks a cycle when we're 
  283.         pRealFactory->Release();  // in the embed from file "registered case"
  284.         pRealFactory = NULL;
  285.     }
  286.     // if we don't register we expect releasing BOleInProcFactory
  287.     // to release BOleFact (since BOleInProcFactory is returned
  288.     // from DllGetClassObject)
  289.     //  
  290.     
  291.     return ResultFromScode (E_FAIL);
  292. }
  293.  
  294. //***********************************
  295. //
  296. // IUnknown methods
  297. //
  298. //***********************************
  299.  
  300. HRESULT _IFUNC BOleInProcFactory::QueryInterfaceMain(REFIID riid, LPVOID FAR *ppObj)
  301. {
  302.     HRESULT hr;
  303.     *ppObj = NULL;
  304.     if (SUCCEEDED(hr = IClassFactory_QueryInterface (this, riid, ppObj))) {
  305.     }
  306.     else if (SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(riid, ppObj))) {
  307.     }
  308.     return hr;
  309. }
  310.  
  311. //***********************************
  312. // 
  313. // IClassFactory methods
  314. //
  315. //***********************************
  316.  
  317. HRESULT _IFUNC BOleInProcFactory::CreateInstance (LPUNKNOWN pUnkOuter, 
  318.                                   REFIID iidContainer, LPVOID FAR* ppv)
  319. {
  320.     // We ask OLE2 to create an instance
  321.     // of the default handler. The default handler uses pRealFactory to
  322.     // call back to us when it's time to create the real server object.
  323.     //
  324.     return ::OleCreateEmbeddingHelper (iidServer, pUnkOuter, 
  325.         EMBDHLP_INPROC_SERVER | EMBDHLP_DELAYCREATE, pRealFactory, 
  326.         iidContainer, ppv);
  327. }
  328.  
  329. HRESULT _IFUNC BOleInProcFactory::LockServer (BOOL fLock)
  330. {
  331.     ::CoLockObjectExternal (this, fLock, TRUE);
  332.     pFactory->ServerCount (fLock ? 1L : -1L);
  333.     return NOERROR;
  334. }
  335.  
  336.  
  337.