internal HtmlDocument(HtmlShimManager shimManager, UnsafeNativeMethods.IHTMLDocument doc) { this.htmlDocument2 = (UnsafeNativeMethods.IHTMLDocument2)doc; Debug.Assert(this.NativeHtmlDocument2 != null, "The document should implement IHtmlDocument2"); this.shimManager = shimManager; }
internal HtmlDocument(HtmlShimManager shimManager, UnsafeNativeMethods.IHTMLDocument doc) { this.htmlDocument2 = (UnsafeNativeMethods.IHTMLDocument2)doc; Debug.Assert(this.NativeHtmlDocument2 != null, "The document should implement IHtmlDocument2"); this.shimManager = shimManager; }
/// <summary> /// Executes an Active Scripting function defined in the HTML document currently loaded in the WebBrowser control. /// </summary> /// <param name="scriptName">The name of the script method to invoke.</param> /// <param name="args"></param> /// <returns>The object returned by the Active Scripting call.</returns> public object InvokeScript(string scriptName, params object[] args) { VerifyAccess(); if (string.IsNullOrEmpty(scriptName)) { throw new ArgumentNullException("scriptName"); } UnsafeNativeMethods.IDispatchEx scriptObjectEx = null; UnsafeNativeMethods.IHTMLDocument2 htmlDocument = NativeHTMLDocument; if (htmlDocument != null) { scriptObjectEx = htmlDocument.GetScript() as UnsafeNativeMethods.IDispatchEx; } // Protect against the cross domain scripting attacks. // We rely on the site locking feature in gerneral. But in IE 6 server side redirect is not blocked. // (In IE 7 it is blocked by turning on the DOCHOSTUIFLAG.ENABLE_REDIRECT_NOTIFICATION flag so that // the additional BeforeNavigate2 event is fired for server side redirect.) object retVal = null; if (scriptObjectEx != null) { NativeMethods.DISPPARAMS dp = new NativeMethods.DISPPARAMS(); dp.rgvarg = IntPtr.Zero; try { // If we use reflection to call script code, we need to Assert for the UnmanagedCode permission. // But it will be a security issue when the WPF app makes a framework object available to the // hosted script via ObjectForScripting or as paramter of InvokeScript, and calls the framework // API that demands the UnmanagedCode permission. We do not want the demand to succeed. However, // The stack walk will igore the native frames and keeps going until it reaches the Assert. // That is why we switch to invoking the script via IDispatch with SUCS on the methods. Guid guid = Guid.Empty; string[] names = new string[] { scriptName }; int[] dispids = new int[] { NativeMethods.DISPID_UNKNOWN }; HRESULT hr = scriptObjectEx.GetIDsOfNames(ref guid, names, 1, Thread.CurrentThread.CurrentCulture.LCID, dispids); hr.ThrowIfFailed(); if (args != null) { // Reverse the arg order so that parms read naturally after IDispatch. (WinForms bug 187662) Array.Reverse(args); } dp.rgvarg = (args == null) ? IntPtr.Zero : UnsafeNativeMethods.ArrayToVARIANTHelper.ArrayToVARIANTVector(args); dp.cArgs = (uint)((args == null) ? 0 : args.Length); dp.rgdispidNamedArgs = IntPtr.Zero; dp.cNamedArgs = 0; // It's important to use IDispatchEx::InvokeEx here rather than the non-Ex versions for security reasons. // This version allows us to pass the IServiceProvider for security context. // // Calling window.open from within WPF WebBrowser control results in Access Denied script error // Providing a service provider to InvokeEx only makes sense when nesting occurs (for e.g., when WPF calls // a script which calls back into WPF which in turn calls the script again) and there is a need to maintain // the service provider chain. When the execution is from a root occurance, then there is no valid service // provider that will have all of the information from the stack. // // Until recently, IE was ignoring bad service providers -so our passing (IServiceProvider)htmlDocument to InvokeEx // worked. IE has recently taken a security fix to ensure that it doesn't fall back to the last IOleCommandTarget // in the chain it found - so now we simply pass null to indicate that this is the root call site. hr = scriptObjectEx.InvokeEx( dispids[0], Thread.CurrentThread.CurrentCulture.LCID, NativeMethods.DISPATCH_METHOD, dp, out retVal, new NativeMethods.EXCEPINFO(), null); hr.ThrowIfFailed(); } finally { if (dp.rgvarg != IntPtr.Zero) { UnsafeNativeMethods.ArrayToVARIANTHelper.FreeVARIANTVector(dp.rgvarg, args.Length); } } } else { throw new InvalidOperationException(SR.Get(SRID.CannotInvokeScript)); } return(retVal); }
public object InvokeScript(string scriptName, params object[] args) { base.VerifyAccess(); if (string.IsNullOrEmpty(scriptName)) { throw new ArgumentNullException("scriptName"); } UnsafeNativeMethods.IDispatchEx dispatchEx = null; UnsafeNativeMethods.IHTMLDocument2 nativeHTMLDocument = this.NativeHTMLDocument; if (nativeHTMLDocument != null) { dispatchEx = (nativeHTMLDocument.GetScript() as UnsafeNativeMethods.IDispatchEx); } Uri source = this.Source; if (source != null) { SecurityHelper.DemandWebPermission(source); } if (nativeHTMLDocument != null) { string url = nativeHTMLDocument.GetUrl(); if (string.CompareOrdinal(url, this.AxIWebBrowser2.LocationURL) != 0) { SecurityHelper.DemandWebPermission(new Uri(url, UriKind.Absolute)); } } object result = null; if (dispatchEx != null) { NativeMethods.DISPPARAMS dispparams = new NativeMethods.DISPPARAMS(); dispparams.rgvarg = IntPtr.Zero; try { Guid empty = Guid.Empty; string[] rgszNames = new string[] { scriptName }; int[] array = new int[] { -1 }; dispatchEx.GetIDsOfNames(ref empty, rgszNames, 1, Thread.CurrentThread.CurrentCulture.LCID, array).ThrowIfFailed(); if (args != null) { Array.Reverse(args); } dispparams.rgvarg = ((args == null) ? IntPtr.Zero : UnsafeNativeMethods.ArrayToVARIANTHelper.ArrayToVARIANTVector(args)); dispparams.cArgs = (uint)((args == null) ? 0 : args.Length); dispparams.rgdispidNamedArgs = IntPtr.Zero; dispparams.cNamedArgs = 0U; dispatchEx.InvokeEx(array[0], Thread.CurrentThread.CurrentCulture.LCID, 1, dispparams, out result, new NativeMethods.EXCEPINFO(), null).ThrowIfFailed(); return(result); } finally { if (dispparams.rgvarg != IntPtr.Zero) { UnsafeNativeMethods.ArrayToVARIANTHelper.FreeVARIANTVector(dispparams.rgvarg, args.Length); } } } throw new InvalidOperationException(SR.Get("CannotInvokeScript")); }