home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 May
/
Pcwk5b98.iso
/
Borland
/
Cplus45
/
BC45
/
BOCOLE.PAK
/
BOLEFACT.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-29
|
8KB
|
337 lines
//
//**************************************************************************
//
// BOleFact.cpp -- Implements the server-side helper for allowing OLE2 to
// create objects made available by Bolero server apps.
//
// Copyright (c) 1993,94 by Borland International, Inc. All rights reserved
//
//**************************************************************************
#include "BOleFact.h"
#include "BOleSvc.h"
#include "BOleIPS.h"
#include "BOleCMan.h"
//
// DllGetClassObject
//
//
//
//
STDAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void FAR* FAR* ppv)
{
HRESULT hRes = ResultFromScode(E_OUTOFMEMORY);
return hRes;
}
STDAPI DllCanUnloadNow()
{
return ResultFromScode( S_OK );
}
BOleFact::BOleFact(BOleClassManager * pFact, IBUnknownMain *pOuter):
RefCnt (1),
pObjCM(NULL),
hReg (0L),
regId (0),
dwRegisterActiveObject (0),
id (CLSID_NULL),
BOleComponent(pFact, (IBUnknownMain *) this),
pIPEFact (NULL)
{
}
BOleFact::~BOleFact()
{
if (pIPEFact) {
pIPEFact->Release();
pIPEFact = NULL;
}
}
HRESULT _IFUNC BOleFact::QueryInterfaceMain(REFIID iid, LPVOID FAR* ppv)
{
HRESULT hr = ResultFromScode(E_NOINTERFACE);
*ppv = NULL;
// interfaces
SUCCEEDED(hr = IBClass_QueryInterface(this, iid, ppv))
// base classes
|| SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(iid, ppv))
// helpers
;
return hr;
}
HRESULT _IFUNC BOleFact::Init (BOOL fInProc, LPCOLESTR szProgId, IBClassMgr *pCM, BCID rid)
{
pObjCM = pCM;
regId = rid;
// If the user's object is capable of being instantiated in its own
// container, create a special BOleInProcFactory
//
if (fInProc) {
pIPEFact = new BOleInProcFactory (pFactory, this, id);
if (!pIPEFact)
return ResultFromScode(E_OUTOFMEMORY);
}
return CLSIDFromProgID(szProgId, &id);
}
HRESULT _IFUNC BOleFact::Register (BOOL fSingleUse)
{
HRESULT hErr;
// register the class factory for this id
//
if (!SUCCEEDED(hErr = CoRegisterClassObject(
id,
(IClassFactory *)this,
CLSCTX_LOCAL_SERVER,
fSingleUse ? REGCLS_SINGLEUSE : REGCLS_MULTI_SEPARATE,
&hReg))) {
OLEHRES("Failed Registering", hErr);
}
// Register the embedding helper factory if we embed in ourselves
if (pIPEFact) {
if (!SUCCEEDED(hErr = pIPEFact->Register (fSingleUse)))
return hErr;
}
// The online dox for CoLockObjectExternal say we should do this here
//
if (SUCCEEDED(hErr)) {
LPCLASSFACTORY pWorkAround = this;
CoLockObjectExternal (pWorkAround, TRUE, TRUE);
}
// if the class manager supports automation let's register it as "Active"
//
IDispatch *pDispatch;
if (SUCCEEDED(pObjCM->QueryInterface(IID_IDispatch, &(LPVOID)pDispatch))) {
RegisterActiveObject (pDispatch, id, NULL, &dwRegisterActiveObject);
pDispatch->Release();
}
return hErr;
}
HRESULT _IFUNC BOleFact::Revoke ()
{
if (hReg) {
LPCLASSFACTORY pWorkAround = this;
CoLockObjectExternal (pWorkAround, FALSE, TRUE);
CoRevokeClassObject( hReg);
hReg = 0;
}
if (dwRegisterActiveObject) {
RevokeActiveObject (dwRegisterActiveObject, NULL);
dwRegisterActiveObject = 0;
}
if (pIPEFact) {
pIPEFact->Revoke ();
pIPEFact->Release ();
pIPEFact = NULL;
}
return NOERROR;
}
HRESULT _IFUNC BOleFact::GetClassID (LPCLSID pClass)
{
*pClass = id;
return NOERROR;
}
BOOL _IFUNC BOleFact::IsA (REFCLSID cid)
{
return IsEqualCLSID(cid, id);
}
HRESULT _IFUNC BOleFact::CreateInstance(IUnknown FAR* pUnk, REFIID iid, LPVOID FAR* ppv)
{
HRESULT hr = ResultFromScode(E_FAIL);
*ppv = 0L;
PIUnknown pObj;
IBClassMgr * pICM;
if (SUCCEEDED(pObjCM->QueryInterface(IID_IBClassMgr, &(LPVOID)pICM))) {
if (SUCCEEDED(pICM->ComponentCreate(&pObj, pUnk, regId))) {
if (pUnk && iid == IID_IUnknown) {
hr = NOERROR;
*ppv = pObj; // always give out main IUnknown
}
else {
hr = pObj->QueryInterface(iid, ppv);
pObj->Release(); // QI bumps
}
}
pICM->Release();
}
return hr;
}
HRESULT _IFUNC BOleFact::LockServer( BOOL fLock )
{
LPCLASSFACTORY pICF = this;
CoLockObjectExternal(pICF, fLock, TRUE);
pFactory->ServerCount( fLock ? 1L : -1L);
return NOERROR;
}
// Used by DllGetClassObject to return the interface to the factory which
// creates the default handler which will create the in-proc server object.
//
HRESULT _IFUNC BOleFact::GetEmbeddingHelperFactory (LPUNKNOWN *ppF)
{
if (pIPEFact) {
*ppF = pIPEFact;
(*ppF)->AddRef();
return NOERROR;
}
else {
*ppF = NULL;
return ResultFromScode(E_FAIL);
}
}
// When Bolero container-side dialog boxes need to know whether to put the
// CLSID for our own factories in the dialog box, this is how they find out
//
BOOL _IFUNC BOleFact::AllowEmbedFromSelf ()
{
return pIPEFact ? TRUE : FALSE;
}
//**************************************************************************
//
// BOleInProcFactory -- The role of this factory is to load the default
// handler on the server side when the container
// side of an app needs to instantiate an object it
// serves.
//
// If we don't do this, the RPC/handler system
// creates the server object as if it were an inproc
// server with no handler, but our EXE-based objects
// must use the default handler.
//
//**************************************************************************
//***********************************
//
// Implementation methods
//
//***********************************
BOleInProcFactory::BOleInProcFactory (BOleClassManager *pCM, BOleFact FAR *pF, REFIID iid) : BOleComponent(pCM, NULL),
iidServer (iid),
nRef (1),
pRealFactory (pF),
regCookie (0)
{
pF->AddRef();
}
BOleInProcFactory::~BOleInProcFactory ()
{
if (pRealFactory) {
pRealFactory->Release();
pRealFactory = NULL;
}
}
HRESULT _IFUNC BOleInProcFactory::Register (BOOL fSingleUse)
{
HRESULT hr = ::CoRegisterClassObject (
iidServer, this, CLSCTX_INPROC_SERVER,
fSingleUse ? REGCLS_SINGLEUSE : REGCLS_MULTI_SEPARATE, ®Cookie);
if (SUCCEEDED(hr)) {
LPCLASSFACTORY pWorkAround = this;
CoLockObjectExternal (pWorkAround, TRUE, TRUE);
}
return hr;
}
HRESULT _IFUNC BOleInProcFactory::Revoke ()
{
if (regCookie) {
LPCLASSFACTORY pWorkAround = this;
CoLockObjectExternal (pWorkAround, FALSE, TRUE);
return ::CoRevokeClassObject (regCookie);
}
if (pRealFactory) { // this breaks a cycle when we're
pRealFactory->Release(); // in the embed from file "registered case"
pRealFactory = NULL;
}
// if we don't register we expect releasing BOleInProcFactory
// to release BOleFact (since BOleInProcFactory is returned
// from DllGetClassObject)
//
return ResultFromScode (E_FAIL);
}
//***********************************
//
// IUnknown methods
//
//***********************************
HRESULT _IFUNC BOleInProcFactory::QueryInterfaceMain(REFIID riid, LPVOID FAR *ppObj)
{
HRESULT hr;
*ppObj = NULL;
if (SUCCEEDED(hr = IClassFactory_QueryInterface (this, riid, ppObj))) {
}
else if (SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(riid, ppObj))) {
}
return hr;
}
//***********************************
//
// IClassFactory methods
//
//***********************************
HRESULT _IFUNC BOleInProcFactory::CreateInstance (LPUNKNOWN pUnkOuter,
REFIID iidContainer, LPVOID FAR* ppv)
{
// We ask OLE2 to create an instance
// of the default handler. The default handler uses pRealFactory to
// call back to us when it's time to create the real server object.
//
return ::OleCreateEmbeddingHelper (iidServer, pUnkOuter,
EMBDHLP_INPROC_SERVER | EMBDHLP_DELAYCREATE, pRealFactory,
iidContainer, ppv);
}
HRESULT _IFUNC BOleInProcFactory::LockServer (BOOL fLock)
{
::CoLockObjectExternal (this, fLock, TRUE);
pFactory->ServerCount (fLock ? 1L : -1L);
return NOERROR;
}