diff options
Diffstat (limited to 'src/md/compiler/classfactory.cpp')
-rw-r--r-- | src/md/compiler/classfactory.cpp | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/md/compiler/classfactory.cpp b/src/md/compiler/classfactory.cpp new file mode 100644 index 0000000000..603f7975aa --- /dev/null +++ b/src/md/compiler/classfactory.cpp @@ -0,0 +1,173 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +//***************************************************************************** +// ClassFactory.cpp +// + +// +// Dll* routines for entry points, and support for COM framework. The class +// factory and other routines live in this module. +// +// This file is not included in the standalone metadata version, because standalone can't use COM, +// let alone COM-activation. So this file gets linked into mscorwks.dll, and then the mscorwks +// class factory delegates to this co-creation routine. +// +//***************************************************************************** +#include "stdafx.h" + +#ifdef FEATURE_METADATA_IN_VM + +#include "classfactory.h" +#include "disp.h" +#include "regmeta.h" +#include "mscoree.h" +#include "corhost.h" + +#include "clrprivhosting.h" + +extern HRESULT TypeNameFactoryCreateObject(REFIID riid, void **ppUnk); + +#include <ndpversion.h> + + +//********** Locals. ********************************************************** +HINSTANCE GetModuleInst(); + +// @telesto - why does Telesto export any Co-classes at all? + +// This map contains the list of coclasses which are exported from this module. +// NOTE: CLSID_CorMetaDataDispenser must be the first entry in this table! +const COCLASS_REGISTER g_CoClasses[] = +{ +// pClsid szProgID pfnCreateObject + { &CLSID_CorMetaDataDispenser, W("CorMetaDataDispenser"), Disp::CreateObject }, +#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) // coreclr doesn't export these + { &CLSID_CorMetaDataDispenserRuntime, W("CorMetaDataDispenserRuntime"), Disp::CreateObject }, + + { &CLSID_CorRuntimeHost, W("CorRuntimeHost"), CorHost::CreateObject }, + { &CLSID_CLRRuntimeHost, W("CLRRuntimeHost"), CorHost2::CreateObject }, + { &__uuidof(CLRPrivRuntime), W("CLRPrivRuntime"), CorHost2::CreateObject }, + { &CLSID_TypeNameFactory, NULL, (PFN_CREATE_OBJ)TypeNameFactoryCreateObject }, +#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE + { NULL, NULL, NULL } +}; + + +//***************************************************************************** +// Called by COM to get a class factory for a given CLSID. If it is one we +// support, instantiate a class factory object and prepare for create instance. +// +// Notes: +// This gets invoked from mscorwks's DllGetClassObject. +//***************************************************************************** +STDAPI MetaDataDllGetClassObject( // Return code. + REFCLSID rclsid, // The class to desired. + REFIID riid, // Interface wanted on class factory. + LPVOID FAR *ppv) // Return interface pointer here. +{ + MDClassFactory *pClassFactory; // To create class factory object. + const COCLASS_REGISTER *pCoClass; // Loop control. + HRESULT hr = CLASS_E_CLASSNOTAVAILABLE; + + // Scan for the right one. + for (pCoClass=g_CoClasses; pCoClass->pClsid; pCoClass++) + { + if (*pCoClass->pClsid == rclsid) + { + // Allocate the new factory object. + pClassFactory = new (nothrow) MDClassFactory(pCoClass); + if (!pClassFactory) + return (E_OUTOFMEMORY); + + // Pick the v-table based on the caller's request. + hr = pClassFactory->QueryInterface(riid, ppv); + + // Always release the local reference, if QI failed it will be + // the only one and the object gets freed. + pClassFactory->Release(); + break; + } + } + return hr; +} + + +//***************************************************************************** +// +//********** Class factory code. +// +//***************************************************************************** + + +//***************************************************************************** +// QueryInterface is called to pick a v-table on the co-class. +//***************************************************************************** +HRESULT STDMETHODCALLTYPE MDClassFactory::QueryInterface( + REFIID riid, + void **ppvObject) +{ + HRESULT hr; + + // Avoid confusion. + *ppvObject = NULL; + + // Pick the right v-table based on the IID passed in. + if (riid == IID_IUnknown) + *ppvObject = (IUnknown *) this; + else if (riid == IID_IClassFactory) + *ppvObject = (IClassFactory *) this; + + // If successful, add a reference for out pointer and return. + if (*ppvObject) + { + hr = S_OK; + AddRef(); + } + else + hr = E_NOINTERFACE; + return hr; +} + + +//***************************************************************************** +// CreateInstance is called to create a new instance of the coclass for which +// this class was created in the first place. The returned pointer is the +// v-table matching the IID if there. +//***************************************************************************** +HRESULT STDMETHODCALLTYPE MDClassFactory::CreateInstance( + IUnknown *pUnkOuter, + REFIID riid, + void **ppvObject) +{ + HRESULT hr; + + BEGIN_ENTRYPOINT_NOTHROW; + + + // Avoid confusion. + *ppvObject = NULL; + _ASSERTE(m_pCoClass); + + // Aggregation is not supported by these objects. + if (pUnkOuter) + IfFailGo(CLASS_E_NOAGGREGATION); + + // Ask the object to create an instance of itself, and check the iid. + hr = (*m_pCoClass->pfnCreateObject)(riid, ppvObject); + +ErrExit: + END_ENTRYPOINT_NOTHROW; + + return hr; +} + +HRESULT STDMETHODCALLTYPE +MDClassFactory::LockServer( + BOOL fLock) +{ + // @FUTURE: Should we return E_NOTIMPL instead of S_OK? + return S_OK; +} + +#endif //FEATURE_METADATA_IN_VM |