WindowsXP-SP1/enduser/stuff/hhctrl/classf.cpp

315 lines
8.1 KiB
C++

// Copyright (C) 1996-1997 Microsoft Corporation. All rights reserved.
#include "header.h"
#include "ClassF.H"
#include "Unknown.H" // for CREATEFNOFOBJECT
#include "localobj.h"
#include "localsrv.h"
#ifndef _DEBUG
#undef THIS_FILE
static const char THIS_FILE[] = __FILE__;
#endif
HRESULT CreateOleObjectFromIndex(IUnknown *, int Index, void **, REFIID);
CClassFactory::CClassFactory(int iIndex)
{
m_iIndex = iIndex;
m_cRefs = 1;
}
CClassFactory::~CClassFactory ()
{
ASSERT_COMMENT(m_cRefs == 0, "Object being deleted with refs!");
return;
}
//=--------------------------------------------------------------------------=
// CClassFactory::QueryInterface
//=--------------------------------------------------------------------------=
// the user wants another interface. we won't give 'em. very many.
//
// Parameters:
// REFIID - [in] interface they want
// void ** - [out] where they want to put the resulting object ptr.
//
// Output:
// HRESULT - S_OK, E_NOINTERFACE
//
// Notes:
//
STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObjOut)
{
void *pv;
CHECK_POINTER(ppvObjOut);
// we support IUnknown, and the two CF interfaces
//
if (DO_GUIDS_MATCH(riid, IID_IClassFactory)) {
pv = (void *)(IClassFactory *)this;
} else if (DO_GUIDS_MATCH(riid, IID_IClassFactory2)) {
pv = (void *)(IClassFactory2 *)this;
} else if (DO_GUIDS_MATCH(riid, IID_IUnknown)) {
pv = (void *)(IUnknown *)this;
} else {
*ppvObjOut = NULL;
return E_NOINTERFACE;
}
((IUnknown *)pv)->AddRef();
*ppvObjOut = pv;
return S_OK;
}
//=--------------------------------------------------------------------------=
// CClassFactory::AddRef
//=--------------------------------------------------------------------------=
// adds a tick to the current reference count.
//
// Output:
// ULONG - the new reference count
ULONG CClassFactory::AddRef(void)
{
return ++m_cRefs;
}
//=--------------------------------------------------------------------------=
// CClassFactory::Release
//=--------------------------------------------------------------------------=
// removes a tick from the count, and delets the object if necessary
//
// Output:
// ULONG - remaining refs
ULONG CClassFactory::Release(void)
{
ASSERT_COMMENT(m_cRefs, "No Refs, and we're being released!");
if(--m_cRefs)
return m_cRefs;
delete this;
return 0;
}
//=--------------------------------------------------------------------------=
// CClassFactory::CreateInstance
//=--------------------------------------------------------------------------=
// create an instance of some sort of object.
//
// Parameters:
// IUnknown * - [in] controlling IUknonwn for aggregation
// REFIID - [in] interface id for new object
// void ** - [out] pointer to new interface object.
//
// Output:
// HRESULT - S_OK, E_NOINTERFACE, E_UNEXPECTED,
// E_OUTOFMEMORY, E_INVALIDARG
//
// Notes:
//
STDMETHODIMP CClassFactory::CreateInstance
(
IUnknown *pUnkOuter,
REFIID riid,
void **ppvObjOut
)
{
// check args
//
if (!ppvObjOut)
return E_INVALIDARG;
// check to see if we've done our licensing work. we do this as late
// as possible that people calling CreateInstanceLic don't suffer from
// a performance hit here.
//
// crit sect this for apartment threading, since it's global
//
// EnterCriticalSection(&g_CriticalSection);
if (!g_fCheckedForLicense) {
g_fMachineHasLicense = TRUE; // 17-Jun-1997 [ralphw] no license check
g_fCheckedForLicense = TRUE;
}
// LeaveCriticalSection(&g_CriticalSection);
// check to see if they have the appropriate license to create this stuff
//
// 08-Jan-1997 [ralphw] CLASS_E_NOTLICENSED disappeared from the header files
//
// if (!g_fMachineHasLicense)
// return CLASS_E_NOTLICENSED;
// try to create one of the objects that we support
//
return CreateOleObjectFromIndex(pUnkOuter, m_iIndex, ppvObjOut, riid);
}
//=--------------------------------------------------------------------------=
// CClassFactory::LockServer
//=--------------------------------------------------------------------------=
// lock the server so we can't unload
//
// Parameters:
// BOOL - [in] TRUE means addref, false means release lock count.
//
// Output:
// HRESULT - S_OK, E_FAIL, E_OUTOFMEMORY, E_UNEXPECTED
STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
{
// update the lock count. crit sect these in case of another thread.
if (fLock)
InterlockedIncrement(&g_cLocks);
else {
ASSERT_COMMENT(g_cLocks, "Lock Counting Problem");
InterlockedDecrement(&g_cLocks);
}
return S_OK;
}
//=--------------------------------------------------------------------------=
// CClassFactory::GetLicInfo
//=--------------------------------------------------------------------------=
// IClassFactory2 GetLicInfo
//
// Parameters:
// LICINFO * - unclear
//
// Output:
// HRESULT - unclear
//
// Notes:
//
STDMETHODIMP CClassFactory::GetLicInfo
(
LICINFO *pLicInfo
)
{
CHECK_POINTER(pLicInfo);
pLicInfo->cbLicInfo = sizeof(LICINFO);
// This says whether RequestLicKey will work
pLicInfo->fRuntimeKeyAvail = g_fMachineHasLicense;
// This says whether the standard CreateInstance will work
pLicInfo->fLicVerified = g_fMachineHasLicense;
return S_OK;
}
//=--------------------------------------------------------------------------=
// CClassFactory::RequestLicKey
//=--------------------------------------------------------------------------=
// IClassFactory2 RequestLicKey
//
// Parameters:
// DWORD - [in] reserved
// BSTR * - [out] unclear
//
// Output:
// HRESULT - unclear
//
// Notes:
//
STDMETHODIMP CClassFactory::RequestLicKey(DWORD dwReserved, BSTR *pbstr)
{
*pbstr = NULL;
return (*pbstr) ? S_OK : E_OUTOFMEMORY;
}
//=--------------------------------------------------------------------------=
// CClassFactory::CreateInstanceLic
//=--------------------------------------------------------------------------=
// create a new instance given a licensing key, etc ...
//
// Parameters:
// IUnknown * - [in] controlling IUnknown for aggregation
// IUnknown * - [in] reserved, must be NULL
// REFIID - [in] IID We're looking for.
// BSTR - [in] license key
// void ** - [out] where to put the new object.
//
// Output:
// HRESULT - unclear
//
// Notes:
//
STDMETHODIMP CClassFactory::CreateInstanceLic
(
IUnknown *pUnkOuter,
IUnknown *pUnkReserved,
REFIID riid,
BSTR bstrKey,
void **ppvObjOut
)
{
*ppvObjOut = NULL;
return CreateOleObjectFromIndex(pUnkOuter, m_iIndex, ppvObjOut, riid);
}
//=--------------------------------------------------------------------------=
// CreateOleObjectFromIndex
//=--------------------------------------------------------------------------=
// given an index in our object table, create an object from it.
//
// Parameters:
// IUnknown * - [in] Controlling Unknown, if any, for aggregation
// int - [in] index into our global table
// void ** - [out] where to put resulting object.
// REFIID - [in] the interface they want resulting object to be.
//
// Output:
// HRESULT - S_OK, E_OUTOFMEMORY, E_NOINTERFACE
HRESULT CreateOleObjectFromIndex
(
IUnknown *pUnkOuter,
int iIndex,
void **ppvObjOut,
REFIID riid
)
{
ASSERT_COMMENT(CREATEFNOFOBJECT(iIndex), "All creatable objects must have creation fn!");
IUnknown* pUnk = CREATEFNOFOBJECT(iIndex)(pUnkOuter);
// sanity check and make sure the object actually got allocated.
RETURN_ON_NULLALLOC(pUnk);
// make sure we support aggregation here properly -- if they gave us
// a controlling unknown, then they -must- ask for IUnknown, and we'll
// give them the private unknown the object gave us.
HRESULT hr;
if (pUnkOuter) {
if (!DO_GUIDS_MATCH(riid, IID_IUnknown)) {
pUnk->Release();
return E_INVALIDARG;
}
*ppvObjOut = (void *)pUnk;
hr = S_OK;
} else {
// QI for whatever the user wants.
hr = pUnk->QueryInterface(riid, ppvObjOut);
pUnk->Release();
RETURN_ON_FAILURE(hr);
}
return hr;
}