internal Assembly Load(byte [] buffer, ManifestAssemblyKind kind) { try { Assembly result = Assembly.Load(buffer); Dispatcher.Invoke(new AssemblyRegistration(AssemblyRegister), new object[] { result, kind }); return(result); } catch { return(null); } }
// note: only access 'assemblies' from the main thread void AssemblyRegister(Assembly assembly, ManifestAssemblyKind kind) { if (!assemblies.Contains(assembly)) { assemblies.Add(assembly); if (kind == ManifestAssemblyKind.SourceAssembly) { if (string.Equals(assembly.GetName().Name, EntryPointAssembly, StringComparison.OrdinalIgnoreCase)) { EntryAssembly = assembly; } } } }
void DownloadAssembly(Uri uri, ManifestAssemblyKind kind) { Uri xap = new Uri(NativeMethods.plugin_instance_get_source_location(PluginHost.Handle)); // WebClient deals with relative URI but HttpWebRequest does not // but we need the later to detect redirection if (!uri.IsAbsoluteUri) { uri = new Uri(xap, uri); } else if (xap.Scheme != uri.Scheme) { throw new SecurityException("Cross scheme URI downloading " + uri.ToString()); } #if NET_3_0 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri); #else HttpWebRequest req = (HttpWebRequest)WebRequestCreator.BrowserHttp.Create(uri); #endif req.BeginGetResponse(AssemblyGetResponse, new object[] { req, kind }); pending_downloads++; }
// note: only access 'assemblies' from the main thread void AssemblyRegister (Assembly assembly, ManifestAssemblyKind kind) { if (!assemblies.Contains (assembly)) { assemblies.Add (assembly); if (kind == ManifestAssemblyKind.SourceAssembly) { if (string.Equals (assembly.GetName ().Name, EntryPointAssembly, StringComparison.OrdinalIgnoreCase)) EntryAssembly = assembly; } } }
internal Assembly Load (byte [] buffer, ManifestAssemblyKind kind) { try { Assembly result = Assembly.Load (buffer); Dispatcher.Invoke (new AssemblyRegistration (AssemblyRegister), new object[] { result, kind }); return result; } catch { return null; } }
void DownloadAssembly (Uri uri, ManifestAssemblyKind kind) { Uri xap = new Uri (NativeMethods.plugin_instance_get_source_location (PluginHost.Handle)); // WebClient deals with relative URI but HttpWebRequest does not // but we need the later to detect redirection if (!uri.IsAbsoluteUri) { uri = new Uri (xap, uri); } else if (xap.Scheme != uri.Scheme) { throw new SecurityException ("Cross scheme URI downloading " + uri.ToString ()); } #if NET_3_0 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (uri); #else HttpWebRequest req = (HttpWebRequest) WebRequestCreator.BrowserHttp.Create (uri); #endif req.BeginGetResponse (AssemblyGetResponse, new object[] { req, kind }); pending_downloads ++; }
// note: throwing MoonException from here is NOT ok since this code is called async // and the exception won't be reported, directly, to the caller void AssemblyGetResponse(IAsyncResult result) { Assembly asm; object[] tuple = (object [])result.AsyncState; WebRequest wreq = (WebRequest)tuple [0]; ManifestAssemblyKind kind = (ManifestAssemblyKind)tuple [1]; int error_code = (kind == ManifestAssemblyKind.ExternalAssembly) ? 2152 : 2105; try { HttpWebResponse wresp = (HttpWebResponse)wreq.EndGetResponse(result); if (wresp.StatusCode != HttpStatusCode.OK) { wresp.Close(); EmitError(error_code, String.Format("Error while downloading the '{0}'.", wreq.RequestUri)); return; } if ((kind != ManifestAssemblyKind.ExternalAssembly) && (wresp.ResponseUri != wreq.RequestUri)) { wresp.Close(); EmitError(error_code, "Redirection not allowed to download assemblies."); return; } using (Stream responseStream = wresp.GetResponseStream()) { byte [] buffer = AssemblyPart.StreamToBuffer(responseStream); if (IsZip(buffer)) { // unzip it. using (MemoryStream dest = new MemoryStream()) { using (MemoryStream source = new MemoryStream(buffer)) { ManagedStreamCallbacks source_cb; ManagedStreamCallbacks dest_cb; StreamWrapper source_wrapper; StreamWrapper dest_wrapper; source_wrapper = new StreamWrapper(source); dest_wrapper = new StreamWrapper(dest); source_cb = source_wrapper.GetCallbacks(); dest_cb = dest_wrapper.GetCallbacks(); // Zip files may contain multiple assemblies, all of which need to be loaded. Keep // attempting to open subsequent files until it fails. for (int i = 0; ; i++) { if (!NativeMethods.managed_unzip_stream_to_stream_nth_file(ref source_cb, ref dest_cb, i)) { break; } if (Load(dest.ToArray(), kind) == null) { EmitError(2153, String.Format("Error while loading '{0}'.", wreq.RequestUri)); } source.Position = 0; dest.SetLength(0); } } } } else { if (Load(buffer, kind) == null) { EmitError(2153, String.Format("Error while loading '{0}'.", wreq.RequestUri)); } } } Dispatcher.BeginInvoke(AsyncDownloadComplete); } catch (Exception e) { // we need to report everything since any error means CreateApplication won't be called EmitError(error_code, e.ToString()); } }