Add implementation of AppDomain.GetAssemblies
authorRahul Kumar <rahku@microsoft.com>
Mon, 24 Oct 2016 21:46:40 +0000 (14:46 -0700)
committerRahul Kumar <rahku@microsoft.com>
Tue, 25 Oct 2016 21:42:10 +0000 (14:42 -0700)
src/mscorlib/model.xml
src/mscorlib/ref/mscorlib.cs
src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
src/vm/appdomain.cpp
src/vm/appdomain.hpp
src/vm/assemblynative.cpp
src/vm/assemblynative.hpp
src/vm/assemblyspec.hpp
src/vm/ecalllist.h

index 178ed9d..fbd792f 100644 (file)
       <Member Name="ResolveUnmanagedDll(System.String,System.IntPtr)" />
       <Member Name="LoadUnmanagedDll(System.String)" />
       <Member Name="LoadUnmanagedDllFromPath(System.String)" />
+      <Member Name="GetLoadedAssemblies" />
       <Member Name="get_Default" />
       <Member Name="SetProfileOptimizationRoot(System.String)" />
       <Member Name="StartProfileOptimization(System.String)" />
index 994a62f..a2a3bc3 100644 (file)
@@ -11840,6 +11840,7 @@ namespace System.Runtime.Loader
         public event System.Action<System.Runtime.Loader.AssemblyLoadContext> Unloading { add { } remove { } }
         public static System.Reflection.AssemblyName GetAssemblyName(string assemblyPath) { throw null; }
         public static System.Runtime.Loader.AssemblyLoadContext GetLoadContext(System.Reflection.Assembly assembly) { throw null; }
+        public static System.Reflection.Assembly[] GetLoadedAssemblies() { throw null; }
         protected abstract System.Reflection.Assembly Load(System.Reflection.AssemblyName assemblyName);
         public System.Reflection.Assembly LoadFromAssemblyName(System.Reflection.AssemblyName assemblyName) { throw null; }
         public System.Reflection.Assembly LoadFromAssemblyPath(string assemblyPath) { throw null; }
index 183d5a3..ab8f4e8 100644 (file)
@@ -83,6 +83,17 @@ namespace System.Runtime.Loader
         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
         [SuppressUnmanagedCodeSecurity]
         private static extern void LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, string ilPath, string niPath, ObjectHandleOnStack retAssembly);
+
+        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+        [SuppressUnmanagedCodeSecurity]
+        private static extern void GetLoadedAssembliesInternal(ObjectHandleOnStack assemblies);
+        
+        public static Assembly[] GetLoadedAssemblies()
+        {
+            Assembly[] assemblies = null;
+            GetLoadedAssembliesInternal(JitHelpers.GetObjectHandleOnStack(ref assemblies));
+            return assemblies;
+        }
         
         // These are helpers that can be used by AssemblyLoadContext derivations.
         // They are used to load assemblies in DefaultContext.
index b6d220a..0646127 100644 (file)
@@ -8084,6 +8084,11 @@ BOOL AppDomain::IsCached(AssemblySpec *pSpec)
     return m_AssemblyCache.Contains(pSpec);
 }
 
+void AppDomain::GetCacheAssemblyList(SetSHash<PTR_DomainAssembly>& assemblyList)
+{
+    CrstHolder holder(&m_DomainCacheCrst);
+    m_AssemblyCache.GetAllAssemblies(assemblyList);
+}
 
 PEAssembly* AppDomain::FindCachedFile(AssemblySpec* pSpec, BOOL fThrow /*=TRUE*/)
 {
index d766b3d..670f685 100644 (file)
@@ -2431,6 +2431,9 @@ public:
                                  LPCWSTR wszCodeBase);
 
 #ifndef DACCESS_COMPILE // needs AssemblySpec
+
+    void GetCacheAssemblyList(SetSHash<PTR_DomainAssembly>& assemblyList);
+
     //****************************************************************************************
     // Returns and Inserts assemblies into a lookup cache based on the binding information
     // in the AssemblySpec. There can be many AssemblySpecs to a single assembly.
index 90c58fc..f372bcb 100644 (file)
@@ -807,6 +807,41 @@ Assembly* AssemblyNative::LoadFromPEImage(ICLRPrivBinder* pBinderContext, PEImag
     RETURN pLoadedAssembly;
 }
 
+/* static */ 
+void QCALLTYPE AssemblyNative::GetLoadedAssembliesInternal(QCall::ObjectHandleOnStack assemblies)
+{
+    QCALL_CONTRACT;
+
+    BEGIN_QCALL;
+    
+    MethodTable * pAssemblyClass = MscorlibBinder::GetClass(CLASS__ASSEMBLY);
+    
+    PTR_AppDomain pCurDomain = GetAppDomain();
+
+    SetSHash<PTR_DomainAssembly> assemblySet;
+    pCurDomain->GetCacheAssemblyList(assemblySet);
+    size_t nArrayElems = assemblySet.GetCount();    
+    PTRARRAYREF     AsmArray = NULL;
+
+    GCX_COOP();
+    
+    GCPROTECT_BEGIN(AsmArray); 
+    AsmArray = (PTRARRAYREF) AllocateObjectArray( (DWORD)nArrayElems, pAssemblyClass);
+    for(auto it = assemblySet.Begin(); it != assemblySet.End(); it++)
+    {
+        PTR_DomainAssembly assem = *it;
+        OBJECTREF o = (OBJECTREF)assem->GetExposedAssemblyObject();
+        _ASSERTE(o != NULL);
+        _ASSERTE(nArrayElems > 0);
+        AsmArray->SetAt(--nArrayElems, o);
+    }        
+
+    assemblies.Set(AsmArray);
+    
+    GCPROTECT_END();    
+    
+    END_QCALL;    
+} 
 
 /* static */
 void QCALLTYPE AssemblyNative::LoadFromPath(INT_PTR ptrNativeAssemblyLoadContext, LPCWSTR pwzILPath, LPCWSTR pwzNIPath, QCall::ObjectHandleOnStack retLoadedAssembly)
index ca03239..99f51e9 100644 (file)
@@ -252,6 +252,7 @@ public:
     static BOOL QCALLTYPE OverrideDefaultAssemblyLoadContextForCurrentDomain(INT_PTR ptrNativeAssemblyLoadContext);
     static BOOL QCALLTYPE CanUseAppPathAssemblyLoadContextInCurrentDomain();
     static void QCALLTYPE LoadFromPath(INT_PTR ptrNativeAssemblyLoadContext, LPCWSTR pwzILPath, LPCWSTR pwzNIPath, QCall::ObjectHandleOnStack retLoadedAssembly);
+    static void QCALLTYPE GetLoadedAssembliesInternal(QCall::ObjectHandleOnStack assemblies);
     static INT_PTR QCALLTYPE InternalLoadUnmanagedDllFromPath(LPCWSTR unmanagedLibraryPath);
     static void QCALLTYPE LoadFromStream(INT_PTR ptrNativeAssemblyLoadContext, INT_PTR ptrAssemblyArray, INT32 cbAssemblyArrayLength, INT_PTR ptrSymbolArray, INT32 cbSymbolArrayLength, QCall::ObjectHandleOnStack retLoadedAssembly);
     static Assembly* LoadFromPEImage(ICLRPrivBinder* pBinderContext, PEImage *pILImage, PEImage *pNIImage);
index a7e9c0f..d94a847 100644 (file)
@@ -682,6 +682,20 @@ class AssemblySpecBindingCache
         WRAPPER_NO_CONTRACT;
         return pSpec->Hash();
     }
+    
+#if defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)    
+    void GetAllAssemblies(SetSHash<PTR_DomainAssembly>& assemblyList)
+    {
+        PtrHashMap::PtrIterator i = m_map.begin();
+        while (!i.end())
+        {
+            AssemblyBinding *b = (AssemblyBinding*) i.GetValue();
+            if(!b->IsError() && b->GetAssembly() != NULL)
+                assemblyList.AddOrReplace(b->GetAssembly());
+            ++i;
+        }
+    }
+#endif // defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
 
     static BOOL CompareSpecs(UPTR u1, UPTR u2);
 };
index 935d717..9f59779 100644 (file)
@@ -1146,6 +1146,7 @@ FCFuncEnd()
 FCFuncStart(gAssemblyLoadContextFuncs)
     QCFuncElement("InitializeAssemblyLoadContext", AssemblyNative::InitializeAssemblyLoadContext)
     QCFuncElement("LoadFromPath", AssemblyNative::LoadFromPath)
+    QCFuncElement("GetLoadedAssembliesInternal", AssemblyNative::GetLoadedAssembliesInternal)
     QCFuncElement("InternalLoadUnmanagedDllFromPath", AssemblyNative::InternalLoadUnmanagedDllFromPath)
     QCFuncElement("OverrideDefaultAssemblyLoadContextForCurrentDomain", AssemblyNative::OverrideDefaultAssemblyLoadContextForCurrentDomain)
     QCFuncElement("CanUseAppPathAssemblyLoadContextInCurrentDomain", AssemblyNative::CanUseAppPathAssemblyLoadContextInCurrentDomain)