// This method is identical to Type.GetTypeFromCLSID. Since it's interop specific, we expose it
// on Marshal for more consistent API surface.
- [SupportedOSPlatform("windows")]
- public static Type? GetTypeFromCLSID(Guid clsid) => RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError: false);
+ internal static Type? GetTypeFromCLSID(Guid clsid, string? server, bool throwOnError)
+ {
+ // Note: "throwOnError" is a vacuous parameter. Any errors due to the CLSID not being registered or the server not being found will happen
+ // on the Activator.CreateInstance() call. GetTypeFromCLSID() merely wraps the data in a Type object without any validation.
+
+ Type? type = null;
+ GetTypeFromCLSID(clsid, server, ObjectHandleOnStack.Create(ref type));
+ return type;
+ }
+
+ [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
+ private static extern void GetTypeFromCLSID(in Guid clsid, string? server, ObjectHandleOnStack retType);
/// <summary>
/// Return the IUnknown* for an Object if the current context is the one
bool[]? byrefModifiers, int culture, string[]? namedParameters);
#endif // FEATURE_COMINTEROP
-#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern Type? GetTypeFromProgIDImpl(string progID, string? server, bool throwOnError);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern Type? GetTypeFromCLSIDImpl(Guid clsid, string? server, bool throwOnError);
-#else // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
- internal static Type GetTypeFromProgIDImpl(string progID, string? server, bool throwOnError)
- {
- throw new NotImplementedException("CoreCLR_REMOVED -- Unmanaged activation removed");
- }
-
- internal static Type GetTypeFromCLSIDImpl(Guid clsid, string? server, bool throwOnError)
- {
- throw new NotImplementedException("CoreCLR_REMOVED -- Unmanaged activation removed");
- }
-#endif // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
-
#endregion
#if FEATURE_COMINTEROP
return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark);
}
- ////////////////////////////////////////////////////////////////////////////////
- // This will return a class based upon the progID. This is provided for
- // COM classic support. Program ID's are not used in COM+ because they
- // have been superceded by namespace. (This routine is called this instead
- // of getClass() because of the name conflict with the first method above.)
- //
- // param progID: the progID of the class to retrieve
- // returns: the class object associated to the progID
- ////
- [SupportedOSPlatform("windows")]
- public static Type? GetTypeFromProgID(string progID, string? server, bool throwOnError)
- {
- return RuntimeType.GetTypeFromProgIDImpl(progID, server, throwOnError);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // This will return a class based upon the CLSID. This is provided for
- // COM classic support.
- //
- // param CLSID: the CLSID of the class to retrieve
- // returns: the class object associated to the CLSID
- ////
- [SupportedOSPlatform("windows")]
- public static Type? GetTypeFromCLSID(Guid clsid, string? server, bool throwOnError)
- {
- return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, throwOnError);
- }
-
internal virtual RuntimeTypeHandle GetTypeHandleInternal()
{
return TypeHandle;
FCFuncElement("CanValueSpecialCast", ReflectionInvocation::CanValueSpecialCast)
FCFuncElement("AllocateValueType", ReflectionInvocation::AllocateValueType)
#if defined(FEATURE_COMINTEROP)
- FCFuncElement("GetTypeFromCLSIDImpl", ReflectionInvocation::GetClassFromCLSID)
- FCFuncElement("GetTypeFromProgIDImpl", ReflectionInvocation::GetClassFromProgID)
FCFuncElement("InvokeDispMethod", ReflectionInvocation::InvokeDispMethod)
#endif // defined(FEATURE_COMINTEROP)
FCFuncEnd()
FCFuncElement("GetTypedObjectForIUnknown", MarshalNative::GetTypedObjectForIUnknown)
FCFuncElement("ChangeWrapperHandleStrength", MarshalNative::ChangeWrapperHandleStrength)
FCFuncElement("CleanupUnusedObjectsInCurrentContext", MarshalNative::CleanupUnusedObjectsInCurrentContext)
+ QCFuncElement("GetTypeFromCLSID", MarshalNative::GetTypeFromCLSID)
#endif // FEATURE_COMINTEROP
FCFuncEnd()
if (pKey->m_strServerName)
{
- WCHAR *pSrvNameData = pKey->m_strServerName;
+ PCWSTR pSrvNameData = pKey->m_strServerName;
while (*pSrvNameData != 0)
{
struct ClassFactoryInfo
{
- GUID m_clsid;
- WCHAR *m_strServerName;
+ GUID m_clsid;
+ PCWSTR m_strServerName;
};
class EEClassFactoryInfoHashTableHelper
#if defined(FEATURE_COMINTEROP_UNMANAGED_ACTIVATION) && defined(FEATURE_COMINTEROP)
-void GetComClassHelper(
+static void GetComClassHelper(
_Out_ OBJECTREF *pRef,
_In_ EEClassFactoryInfoHashTable *pClassFactHash,
- _In_ ClassFactoryInfo *pClassFactInfo,
- _In_opt_ WCHAR *wszProgID)
+ _In_ ClassFactoryInfo *pClassFactInfo)
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
- MODE_ANY;
+ MODE_COOPERATIVE;
INJECT_FAULT(ThrowOutOfMemory());
PRECONDITION(CheckPointer(pRef));
PRECONDITION(CheckPointer(pClassFactHash));
PRECONDITION(CheckPointer(pClassFactInfo));
- PRECONDITION(CheckPointer(wszProgID, NULL_OK));
}
CONTRACTL_END;
// represent it.
//
- NewHolder<ComClassFactory> pComClsFac = ComClassFactoryCreator::Create(pClassFactInfo->m_clsid);
+ NewHolder<ComClassFactory> pComClsFac = new ComClassFactory(pClassFactInfo->m_clsid);
pComClsFac->SetManagedVersion();
- NewArrayHolder<WCHAR> wszRefProgID = NULL;
- if (wszProgID)
- {
- size_t len = wcslen(wszProgID)+1;
- wszRefProgID = new WCHAR[len];
- wcscpy_s(wszRefProgID, len, wszProgID);
- }
-
NewArrayHolder<WCHAR> wszRefServer = NULL;
if (pClassFactInfo->m_strServerName)
{
wcscpy_s(wszRefServer, len, pClassFactInfo->m_strServerName);
}
- pComClsFac->Init(wszRefProgID, wszRefServer, NULL);
+ pComClsFac->Init(wszRefServer, NULL);
AllocateComClassObject(pComClsFac, pRef);
// Insert to hash.
// Make sure the hash code is working.
_ASSERTE (pClassFactHash->GetValue(pClassFactInfo, (HashDatum *)&hRef));
- wszRefProgID.SuppressRelease();
wszRefServer.SuppressRelease();
pComClsFac.SuppressRelease();
}
//-------------------------------------------------------------
// returns a ComClass reflect class that wraps the IClassFactory
-void GetComClassFromProgID(STRINGREF srefProgID, STRINGREF srefServer, OBJECTREF *pRef)
+void GetComClassFromCLSID(REFCLSID clsid, _In_opt_z_ PCWSTR wszServer, OBJECTREF *pRef)
{
CONTRACTL
{
GC_TRIGGERS;
MODE_COOPERATIVE;
INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(srefProgID != NULL);
PRECONDITION(pRef != NULL);
}
CONTRACTL_END;
- NewArrayHolder<WCHAR> wszProgID;
- NewArrayHolder<WCHAR> wszServer;
- HRESULT hr = S_OK;
- MethodTable* pMT = NULL;
- CLSID clsid = {0};
-
- //
- // Allocate strings for the ProgID and the server.
- //
-
- int len = srefProgID->GetStringLength();
-
- wszProgID = new WCHAR[len+1];
-
- if (len)
- memcpy(wszProgID, srefProgID->GetBuffer(), (len*2));
- wszProgID[len] = W('\0');
-
- if (srefServer != NULL)
- {
- len = srefServer->GetStringLength();
-
- wszServer = new WCHAR[len+1];
-
- if (len)
- memcpy(wszServer, srefServer->GetBuffer(), (len*2));
- wszServer[len] = W('\0');
- }
-
-
- //
- // Call GetCLSIDFromProgID() to convert the ProgID to a CLSID.
- //
-
- EnsureComStarted();
-
- {
- GCX_PREEMP();
- hr = GetCLSIDFromProgID(wszProgID, &clsid);
- }
-
- if (FAILED(hr))
- COMPlusThrowHR(hr);
-
- //
- // See if we can find the well known managed class for this CLSID.
- //
-
- // Check if we have in the hash.
- OBJECTHANDLE hRef;
- ClassFactoryInfo ClassFactInfo;
- ClassFactInfo.m_clsid = clsid;
- ClassFactInfo.m_strServerName = wszServer;
- EEClassFactoryInfoHashTable *pClassFactHash = GetAppDomain()->GetClassFactHash();
-
- if (pClassFactHash->GetValue(&ClassFactInfo, (HashDatum *)&hRef))
- {
- *pRef = ObjectFromHandle(hRef);
- }
- else
- {
- GetComClassHelper(pRef, pClassFactHash, &ClassFactInfo, wszProgID);
- }
-
- // If we made it this far *pRef better be set.
- _ASSERTE(*pRef != NULL);
-}
-
-//-------------------------------------------------------------
-// returns a ComClass reflect class that wraps the IClassFactory
-void GetComClassFromCLSID(REFCLSID clsid, STRINGREF srefServer, OBJECTREF *pRef)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(pRef != NULL);
- }
- CONTRACTL_END;
-
- NewArrayHolder<WCHAR> wszServer;
- HRESULT hr = S_OK;
- MethodTable* pMT = NULL;
-
- //
- // Allocate strings for the server.
- //
-
- if (srefServer != NULL)
- {
- int len = srefServer->GetStringLength();
-
- wszServer = new WCHAR[len+1];
-
- if (len)
- memcpy(wszServer, srefServer->GetBuffer(), (len*2));
-
- wszServer[len] = W('\0');
- }
-
-
//
// See if we can find the well known managed class for this CLSID.
//
}
else
{
- GetComClassHelper(pRef, pClassFactHash, &ClassFactInfo, NULL);
+ GetComClassHelper(pRef, pClassFactHash, &ClassFactInfo);
}
// If we made it this far *pRef better be set.
GUID guid;
pClassMT->GetGuid(&guid, TRUE);
- ComClassFactory *pComClsFac = ComClassFactoryCreator::Create(guid);
+ ComClassFactory *pComClsFac = new ComClassFactory(guid);
pNewFactory = pComClsFac;
- pComClsFac->Init(NULL, NULL, pClassMT);
+ pComClsFac->Init(NULL, pClassMT);
// store the class factory in EE Class
if (!pClassMT->SetComClassFactory(pNewFactory))
// Class Factory helpers
//--------------------------------------------------------------------------
-// GetComClassFromProgID used by reflection class to setup a Class based on ProgID
-void GetComClassFromProgID(STRINGREF srefProgID, STRINGREF srefServer, OBJECTREF* pRef);
-
-//--------------------------------------------------------------------------
// GetComClassFromCLSID used by reflection class to setup a Class based on CLSID
-void GetComClassFromCLSID(REFCLSID clsid, STRINGREF srefServer, OBJECTREF* pRef);
+void GetComClassFromCLSID(REFCLSID clsid, _In_opt_z_ PCWSTR wszServer, OBJECTREF* pRef);
//-------------------------------------------------------------
// check if a ComClassFactory has been setup for this class
}
FCIMPLEND
-FCIMPL2(void, MarshalNative::DoGetTypeLibGuid, GUID * result, Object* refTlbUNSAFE)
-{
- FCALL_CONTRACT;
-
- OBJECTREF refTlb = (OBJECTREF) refTlbUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(refTlb);
- GCPROTECT_BEGININTERIOR (result);
-
- if (refTlb == NULL)
- COMPlusThrowArgumentNull(W("pTLB"));
-
- // Ensure COM is started up.
- EnsureComStarted();
-
- SafeComHolder<ITypeLib> pTLB = (ITypeLib*)GetComIPFromObjectRef(&refTlb, IID_ITypeLib);
- if (!pTLB)
- COMPlusThrow(kArgumentException, W("Arg_NoITypeLib"));
-
- GCX_PREEMP();
-
- // Retrieve the TLIBATTR.
- TLIBATTR *pAttr;
- IfFailThrow(pTLB->GetLibAttr(&pAttr));
-
- // Extract the guid from the TLIBATTR.
- *result = pAttr->guid;
-
- // Release the TLIBATTR now that we have the GUID.
- pTLB->ReleaseTLibAttr(pAttr);
-
- GCPROTECT_END ();
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-FCIMPL1(LCID, MarshalNative::GetTypeLibLcid, Object* refTlbUNSAFE)
-{
- FCALL_CONTRACT;
-
- LCID retVal = 0;
- OBJECTREF refTlb = (OBJECTREF) refTlbUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(refTlb);
-
- if (refTlb == NULL)
- COMPlusThrowArgumentNull(W("pTLB"));
-
- // Ensure COM is started up.
- EnsureComStarted();
-
- SafeComHolder<ITypeLib> pTLB = (ITypeLib*)GetComIPFromObjectRef(&refTlb, IID_ITypeLib);
- if (!pTLB)
- COMPlusThrow(kArgumentException, W("Arg_NoITypeLib"));
-
- GCX_PREEMP();
-
- // Retrieve the TLIBATTR.
- TLIBATTR *pAttr;
- IfFailThrow(pTLB->GetLibAttr(&pAttr));
-
- // Extract the LCID from the TLIBATTR.
- retVal = pAttr->lcid;
-
- // Release the TLIBATTR now that we have the LCID.
- pTLB->ReleaseTLibAttr(pAttr);
-
- HELPER_METHOD_FRAME_END();
- return retVal;
-}
-FCIMPLEND
-
-FCIMPL3(void, MarshalNative::GetTypeLibVersion, Object* refTlbUNSAFE, int *pMajor, int *pMinor)
-{
- FCALL_CONTRACT;
-
- OBJECTREF refTlb = (OBJECTREF) refTlbUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(refTlb);
-
- if (refTlb == NULL)
- COMPlusThrowArgumentNull(W("typeLibrary"));
-
- // Ensure COM is started up.
- EnsureComStarted();
-
- SafeComHolder<ITypeLib> pTLB = (ITypeLib*)GetComIPFromObjectRef(&refTlb, IID_ITypeLib);
- if (!pTLB)
- COMPlusThrow(kArgumentException, W("Arg_NoITypeLib"));
-
- GCX_PREEMP();
-
- // Retrieve the TLIBATTR.
- TLIBATTR *pAttr;
- IfFailThrow(pTLB->GetLibAttr(&pAttr));
-
- // Extract the LCID from the TLIBATTR.
- *pMajor = pAttr->wMajorVerNum;
- *pMinor = pAttr->wMinorVerNum;
-
- // Release the TLIBATTR now that we have the version numbers.
- pTLB->ReleaseTLibAttr(pAttr);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-FCIMPL2(void, MarshalNative::DoGetTypeInfoGuid, GUID * result, Object* refTypeInfoUNSAFE)
-{
- FCALL_CONTRACT;
-
- OBJECTREF refTypeInfo = (OBJECTREF) refTypeInfoUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(refTypeInfo);
- GCPROTECT_BEGININTERIOR (result);
-
- if (refTypeInfo == NULL)
- COMPlusThrowArgumentNull(W("typeInfo"));
-
- // Ensure COM is started up.
- EnsureComStarted();
-
- SafeComHolder<ITypeInfo> pTI = (ITypeInfo*)GetComIPFromObjectRef(&refTypeInfo, IID_ITypeInfo);
- if (!pTI)
- COMPlusThrow(kArgumentException, W("Arg_NoITypeInfo"));
-
- GCX_PREEMP();
-
- // Retrieve the TYPEATTR.
- TYPEATTR *pAttr;
- IfFailThrow(pTI->GetTypeAttr(&pAttr));
-
- // Extract the guid from the TYPEATTR.
- *result = pAttr->guid;
-
- // Release the TYPEATTR now that we have the GUID.
- pTI->ReleaseTypeAttr(pAttr);
-
- GCPROTECT_END ();
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-FCIMPL2(void, MarshalNative::DoGetTypeLibGuidForAssembly, GUID * result, AssemblyBaseObject* refAsmUNSAFE)
-{
- FCALL_CONTRACT;
-
- // Validate the arguments.
- _ASSERTE(refAsmUNSAFE != NULL);
- _ASSERTE(result != NULL);
-
- ASSEMBLYREF refAsm = (ASSEMBLYREF) refAsmUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(refAsm);
- GCPROTECT_BEGININTERIOR (result)
-
- HRESULT hr = S_OK;
-
- // Retrieve the assembly from the ASSEMBLYREF.
- Assembly *pAssembly = refAsm->GetAssembly();
- _ASSERTE(pAssembly);
-
- // Retrieve the TLBID for the assembly.
- IfFailThrow(::GetTypeLibGuidForAssembly(pAssembly, result));
-
- GCPROTECT_END ();
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
FCIMPL1(int, MarshalNative::GetStartComSlot, ReflectClassBaseObject* tUNSAFE)
{
FCALL_CONTRACT;
}
}
+void QCALLTYPE MarshalNative::GetTypeFromCLSID(REFCLSID clsid, PCWSTR wszServer, QCall::ObjectHandleOnStack retType)
+{
+ QCALL_CONTRACT;
+
+ BEGIN_QCALL;
+
+ // Ensure COM is started up.
+ EnsureComStarted();
+
+ GCX_COOP();
+
+ OBJECTREF orType = NULL;
+ GCPROTECT_BEGIN(orType);
+ GetComClassFromCLSID(clsid, wszServer, &orType);
+ retType.Set(orType);
+ GCPROTECT_END();
+
+ END_QCALL;
+}
+
#endif // FEATURE_COMINTEROP
static FCDECL2(Object*, GetObjectsForNativeVariants, VARIANT* aSrcNativeVariant, int cVars);
//====================================================================
- // Methods to retrieve information from TypeLibs and TypeInfos.
- //====================================================================
- static FCDECL2(void, DoGetTypeLibGuid, GUID * result, Object* refTlbUNSAFE);
- static FCDECL1(LCID, GetTypeLibLcid, Object* refTlbUNSAFE);
- static FCDECL3(void, GetTypeLibVersion, Object* refTlbUNSAFE, int *pMajor, int *pMinor);
- static FCDECL2(void, DoGetTypeInfoGuid, GUID * result, Object* refTypeInfoUNSAFE);
-
- //====================================================================
- // Given a assembly, return the TLBID that will be generated for the
- // typelib exported from the assembly.
- //====================================================================
- static FCDECL2(void, DoGetTypeLibGuidForAssembly, GUID * result, AssemblyBaseObject* refAsmUNSAFE);
-
- //====================================================================
// These methods are used to map COM slots to method info's.
//====================================================================
static FCDECL1(int, GetStartComSlot, ReflectClassBaseObject* tUNSAFE);
static FCDECL1(Object*, WrapIUnknownWithComObject, IUnknown* pUnk);
static FCDECL2(void, ChangeWrapperHandleStrength, Object* orefUNSAFE, CLR_BOOL fIsWeak);
+
+ //====================================================================
+ // Create type for given CLSID.
+ //====================================================================
+ static void QCALLTYPE GetTypeFromCLSID(REFCLSID clsid, PCWSTR wszServer, QCall::ObjectHandleOnStack retType);
+
private:
static int GetComSlotInfo(MethodTable *pMT, MethodTable **ppDefItfMT);
static BOOL IsObjectInContext(OBJECTREF *pObj);
FCIMPLEND
#ifdef FEATURE_COMINTEROP
-
-static void TryGetClassFromProgID(STRINGREF className, STRINGREF server, OBJECTREF* pRefClass, DWORD bThrowOnError) {
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- EX_TRY
- {
- // NOTE: this call enables GC
- GetComClassFromProgID(className, server, pRefClass);
- }
- EX_CATCH
- {
- if (bThrowOnError)
- {
- EX_RETHROW;
- }
- }
- EX_END_CATCH(SwallowAllExceptions)
-}
-
-// GetClassFromProgID
-// This method will return a Class object for a COM Classic object based
-// upon its ProgID. The COM Classic object is found and a wrapper object created
-FCIMPL3(Object*, ReflectionInvocation::GetClassFromProgID, StringObject* classNameUNSAFE,
- StringObject* serverUNSAFE,
- CLR_BOOL bThrowOnError) {
- FCALL_CONTRACT;
-
- REFLECTCLASSBASEREF refClass = NULL;
- STRINGREF className = (STRINGREF) classNameUNSAFE;
- STRINGREF server = (STRINGREF) serverUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(className, server);
-
- GCPROTECT_BEGIN(refClass)
-
- // Since we will be returning a type that represents a COM component, we need
- // to make sure COM is started before we return it.
- EnsureComStarted();
-
- // Make sure a prog id was provided
- if (className == NULL)
- COMPlusThrowArgumentNull(W("progID"),W("ArgumentNull_String"));
-
- TryGetClassFromProgID(className, server, (OBJECTREF*) &refClass, bThrowOnError);
- GCPROTECT_END();
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(refClass);
-}
-FCIMPLEND
-
-static void TryGetClassFromCLSID(GUID clsid, STRINGREF server, OBJECTREF* pRefClass, DWORD bThrowOnError) {
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- EX_TRY
- {
- // NOTE: this call enables GC
- GetComClassFromCLSID(clsid, server, pRefClass);
- }
- EX_CATCH
- {
- if (bThrowOnError)
- {
- EX_RETHROW;
- }
- }
- EX_END_CATCH(SwallowAllExceptions)
-}
-
-// GetClassFromCLSID
-// This method will return a Class object for a COM Classic object based
-// upon its ProgID. The COM Classic object is found and a wrapper object created
-FCIMPL3(Object*, ReflectionInvocation::GetClassFromCLSID, GUID clsid, StringObject* serverUNSAFE, CLR_BOOL bThrowOnError) {
- FCALL_CONTRACT;
-
- struct _gc {
- REFLECTCLASSBASEREF refClass;
- STRINGREF server;
- } gc;
-
- gc.refClass = NULL;
- gc.server = (STRINGREF) serverUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc.server);
-
- // Since we will be returning a type that represents a COM component, we need
- // to make sure COM is started before we return it.
- EnsureComStarted();
-
- TryGetClassFromCLSID(clsid, gc.server, (OBJECTREF*) &gc.refClass, bThrowOnError);
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.refClass);
-}
-FCIMPLEND
-
-
FCIMPL8(Object*, ReflectionInvocation::InvokeDispMethod, ReflectClassBaseObject* refThisUNSAFE,
StringObject* nameUNSAFE,
INT32 invokeAttr,
static FCDECL1(Object*, TypedReferenceToObject, TypedByRef * value);
#ifdef FEATURE_COMINTEROP
- static FCDECL3(Object*, GetClassFromProgID, StringObject* classNameUNSAFE, StringObject* serverUNSAFE, CLR_BOOL bThrowOnError);
- static FCDECL3(Object*, GetClassFromCLSID, GUID clsid, StringObject* serverUNSAFE, CLR_BOOL bThrowOnError);
static FCDECL8(Object*, InvokeDispMethod, ReflectClassBaseObject* refThisUNSAFE, StringObject* nameUNSAFE, INT32 invokeAttr, Object* targetUNSAFE, PTRArray* argsUNSAFE, PTRArray* byrefModifiersUNSAFE, LCID lcid, PTRArray* namedParametersUNSAFE);
#endif // FEATURE_COMINTEROP
static FCDECL2(void, GetGUID, ReflectClassBaseObject* refThisUNSAFE, GUID * result);
GCX_PREEMP();
// If a server name is specified, then first try CLSCTX_REMOTE_SERVER.
- if (m_pwszServer)
+ if (m_wszServer)
{
// Set up the COSERVERINFO struct.
COSERVERINFO ServerInfo;
memset(&ServerInfo, 0, sizeof(COSERVERINFO));
- ServerInfo.pwszName = m_pwszServer;
+ ServerInfo.pwszName = (LPWSTR)m_wszServer;
// Try to retrieve the IClassFactory passing in CLSCTX_REMOTE_SERVER.
hr = CoGetClassObject(m_rclsid, CLSCTX_REMOTE_SERVER, &ServerInfo, IID_IClassFactory, (void**)&pClassFactory);
GetHRMsg(hr, strHRDescription);
// Throw the actual exception indicating we couldn't find the class factory.
- if (m_pwszServer == NULL)
+ if (m_wszServer == NULL)
COMPlusThrowHR(hr, IDS_EE_LOCAL_COGETCLASSOBJECT_FAILED, strHRHex, strClsid, strHRDescription.GetUnicode());
else
- COMPlusThrowHR(hr, IDS_EE_REMOTE_COGETCLASSOBJECT_FAILED, strHRHex, strClsid, m_pwszServer, strHRDescription.GetUnicode());
+ COMPlusThrowHR(hr, IDS_EE_REMOTE_COGETCLASSOBJECT_FAILED, strHRHex, strClsid, m_wszServer, strHRDescription.GetUnicode());
}
RETURN pClassFactory;
//--------------------------------------------------------------
// Init the ComClassFactory.
-void ComClassFactory::Init(__in_opt WCHAR* pwszProgID, __in_opt WCHAR* pwszServer, MethodTable* pClassMT)
+void ComClassFactory::Init(__in_opt PCWSTR wszServer, MethodTable* pClassMT)
{
LIMITED_METHOD_CONTRACT;
- m_pwszProgID = pwszProgID;
- m_pwszServer = pwszServer;
+ m_wszServer = wszServer;
m_pClassMT = pClassMT;
}
if (m_bManagedVersion)
return;
- if (m_pwszProgID != NULL)
- delete [] m_pwszProgID;
-
- if (m_pwszServer != NULL)
- delete [] m_pwszServer;
+ if (m_wszServer != NULL)
+ delete [] m_wszServer;
delete this;
}
MethodTable *m_pClassMT;
};
-class ComClassFactoryCreator;
//-------------------------------------------------------------------------
// Class that wraps an IClassFactory
// This class allows a Reflection Class to wrap an IClassFactory
//
class ComClassFactory : public ClassFactoryBase
{
-protected:
- friend ComClassFactoryCreator;
-
+public:
// We have two types of ComClassFactory:
// 1. We build for reflection purpose. We should not clean up.
// 2. We build for IClassFactory. We should clean up.
{
WRAPPER_NO_CONTRACT;
- m_pwszProgID = NULL;
- m_pwszServer = NULL;
+ m_wszServer = NULL;
// Default to unmanaged version.
m_bManagedVersion = FALSE;
m_rclsid = rclsid;
}
-public :
//---------------------------------------------------------
// Mark this instance as Managed Version, so we will not do clean up.
void SetManagedVersion()
//--------------------------------------------------------------
// Init the ComClassFactory
- void Init(__in_opt WCHAR* pwszProgID, __in_opt WCHAR* pwszServer, MethodTable* pClassMT);
+ void Init(__in_opt PCWSTR wszServer, MethodTable* pClassMT);
//-------------------------------------------------------------
// create instance, calls IClassFactory::CreateInstance
IUnknown *CreateInstanceFromClassFactory(IClassFactory *pClassFact, IUnknown *punkOuter, BOOL *pfDidContainment);
public:;
- WCHAR* m_pwszProgID; // progId
CLSID m_rclsid; // CLSID
- WCHAR* m_pwszServer; // server name
+ PCWSTR m_wszServer; // server name
private:
BOOL m_bManagedVersion;
};
-
-//--------------------------------------------------------------
-// Creates the right ComClassFactory for you
-class ComClassFactoryCreator
-{
-public :
- static ComClassFactory *Create(REFCLSID rclsid)
- {
- CONTRACT(ComClassFactory *)
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACT_END;
-
- RETURN new ComClassFactory(rclsid);
- }
-};
#endif // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
FORCEINLINE void NewRCWHolderRelease(RCW* p)
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Ole32
+ {
+ [DllImport(Interop.Libraries.Ole32, CharSet = CharSet.Unicode)]
+ internal static extern int CLSIDFromProgID(string lpszProgID, out Guid lpclsid);
+ }
+}
<Compile Include="$(CommonPath)Interop\Windows\OleAut32\Interop.SysFreeString.cs">
<Link>Common\Interop\Windows\OleAut32\Interop.SysFreeString.cs</Link>
</Compile>
+ <Compile Include="$(CommonPath)Interop\Windows\Ole32\Interop.CLSIDFromProgID.cs">
+ <Link>Common\Interop\Windows\Ole32\Interop.CLSIDFromProgID.cs</Link>
+ </Compile>
<Compile Include="$(CommonPath)Interop\Windows\Ole32\Interop.CoCreateGuid.cs">
<Link>Common\Interop\Windows\Ole32\Interop.CoCreateGuid.cs</Link>
</Compile>
throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
- [SupportedOSPlatform("windows")]
- public static Type? GetTypeFromCLSID(Guid clsid)
+ internal static Type? GetTypeFromCLSID(Guid clsid, string? server, bool throwOnError)
{
- throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
+ if (throwOnError)
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
+
+ return null;
}
[SupportedOSPlatform("windows")]
Interop.Sys.MemFree(ptr - sizeof(IntPtr));
}
}
+
+ internal static Type? GetTypeFromProgID(string progID, string? server, bool throwOnError)
+ {
+ if (progID == null)
+ throw new ArgumentNullException(nameof(progID));
+
+ if (throwOnError)
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
+
+ return null;
+ }
}
}
Interop.OleAut32.SysFreeString(ptr);
}
}
+
+ internal static Type? GetTypeFromProgID(string progID, string? server, bool throwOnError)
+ {
+ if (progID == null)
+ throw new ArgumentNullException(nameof(progID));
+
+ int hr = Interop.Ole32.CLSIDFromProgID(progID, out Guid clsid);
+ if (hr < 0)
+ {
+ if (throwOnError)
+ throw Marshal.GetExceptionForHR(hr, new IntPtr(-1))!;
+ return null;
+ }
+
+ return GetTypeFromCLSID(clsid, server, throwOnError);
+ }
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Security;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Security;
using System.Text;
using Internal.Runtime.CompilerServices;
-using System.Diagnostics.CodeAnalysis;
namespace System.Runtime.InteropServices
{
{
return *(((uint*)s) - 1);
}
+
+ [SupportedOSPlatform("windows")]
+ public static Type? GetTypeFromCLSID(Guid clsid) => GetTypeFromCLSID(clsid, null, throwOnError: false);
}
}
public static Type? GetTypeFromCLSID(Guid clsid, bool throwOnError) => GetTypeFromCLSID(clsid, null, throwOnError: throwOnError);
[SupportedOSPlatform("windows")]
public static Type? GetTypeFromCLSID(Guid clsid, string? server) => GetTypeFromCLSID(clsid, server, throwOnError: false);
+ [SupportedOSPlatform("windows")]
+ public static Type? GetTypeFromCLSID(Guid clsid, string? server, bool throwOnError) => Marshal.GetTypeFromCLSID(clsid, server, throwOnError);
[SupportedOSPlatform("windows")]
public static Type? GetTypeFromProgID(string progID) => GetTypeFromProgID(progID, null, throwOnError: false);
public static Type? GetTypeFromProgID(string progID, bool throwOnError) => GetTypeFromProgID(progID, null, throwOnError: throwOnError);
[SupportedOSPlatform("windows")]
public static Type? GetTypeFromProgID(string progID, string? server) => GetTypeFromProgID(progID, server, throwOnError: false);
+ [SupportedOSPlatform("windows")]
+ public static Type? GetTypeFromProgID(string progID, string? server, bool throwOnError) => Marshal.GetTypeFromProgID(progID, server, throwOnError);
public abstract Type? BaseType { get; }
{
public class GetTypeFromCLSIDTests
{
+ private static readonly Guid TestCLSID = new Guid("927971f5-0939-11d1-8be1-00c04fd8d503");
+
+ private const string TestProgID = "LargeInteger";
+ private const string TestServerName = "____NonExistingServer____";
+
[Fact]
[PlatformSpecific(TestPlatforms.Windows)]
public void GetTypeFromCLSID_NoSuchCLSIDExists_ReturnsExpected()
Assert.NotNull(type);
Assert.Same(type, Marshal.GetTypeFromCLSID(Guid.Empty));
+ Assert.Same(type, Type.GetTypeFromCLSID(Guid.Empty));
+ Assert.Same(type, Type.GetTypeFromCLSID(Guid.Empty, throwOnError: true));
+
Assert.Throws<COMException>(() => Activator.CreateInstance(type));
}
[PlatformSpecific(TestPlatforms.Windows)]
public void GetTypeFromCLSID_CLSIDExists_ReturnsExpected()
{
- var guid = new Guid("927971f5-0939-11d1-8be1-00c04fd8d503");
-
- Type type = Marshal.GetTypeFromCLSID(guid);
+ Type type = Marshal.GetTypeFromCLSID(TestCLSID);
Assert.NotNull(type);
- Assert.Same(type, Marshal.GetTypeFromCLSID(guid));
+ Assert.Same(type, Marshal.GetTypeFromCLSID(TestCLSID));
+
+ Assert.Same(type, Type.GetTypeFromCLSID(TestCLSID));
+ Assert.Same(type, Type.GetTypeFromCLSID(TestCLSID, throwOnError: true));
+ Assert.Same(type, Type.GetTypeFromCLSID(TestCLSID, server: null, throwOnError: true));
+
+ Assert.Same(type, Type.GetTypeFromProgID(TestProgID));
+ Assert.Same(type, Type.GetTypeFromProgID(TestProgID, throwOnError: true));
+ Assert.Same(type, Type.GetTypeFromProgID(TestProgID, server: null, throwOnError: true));
Assert.NotNull(Activator.CreateInstance(type));
}
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+ [PlatformSpecific(TestPlatforms.Windows)]
+ public void GetTypeFromCLSID_CLSIDExists_Server_ReturnsExpected()
+ {
+ Type type = Type.GetTypeFromCLSID(TestCLSID, server: TestServerName, throwOnError: true);
+ Assert.NotNull(type);
+ Assert.Same(type, Type.GetTypeFromProgID(TestProgID, server: TestServerName, throwOnError: true));
+
+ Assert.Throws<COMException>(() => Activator.CreateInstance(type));
+ }
+
[Fact]
[PlatformSpecific(TestPlatforms.AnyUnix)]
- public void GetTypeFromCLSID_Unix_ThrowsPlatformNotSupportedException()
+ public void GetTypeFromCLSID_Unix()
+ {
+ Assert.Null(Marshal.GetTypeFromCLSID(Guid.Empty));
+ Assert.Null(Type.GetTypeFromCLSID(Guid.Empty, throwOnError: false));
+ Assert.Throws<PlatformNotSupportedException>(() => Type.GetTypeFromCLSID(Guid.Empty, throwOnError: true));
+ }
+
+ [Fact]
+ [PlatformSpecific(TestPlatforms.AnyUnix)]
+ public void GetTypeFromProgID_Unix()
+ {
+ Assert.Null(Type.GetTypeFromProgID(TestProgID, throwOnError: false));
+ Assert.Throws<PlatformNotSupportedException>(() => Type.GetTypeFromProgID(TestProgID, throwOnError: true));
+ }
+
+ [Fact]
+ public void GetTypeFromProgID_ReturnsExpected()
{
- Assert.Throws<PlatformNotSupportedException>(() => Marshal.GetTypeFromCLSID(Guid.Empty));
+ AssertExtensions.Throws<ArgumentNullException>("progID", () => Type.GetTypeFromProgID(null));
}
}
}
return internal_from_handle(handle.Value);
}
- [SupportedOSPlatform("windows")]
- public static Type? GetTypeFromCLSID(Guid clsid, string? server, bool throwOnError) => throw new PlatformNotSupportedException();
-
- [SupportedOSPlatform("windows")]
- public static Type? GetTypeFromProgID(string progID, string? server, bool throwOnError) => throw new PlatformNotSupportedException();
-
internal virtual Type InternalResolve()
{
return UnderlyingSystemType;