WebBrowser.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / Controls / WebBrowser.cs / 6 / WebBrowser.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
//
// Description: 
//      WebBrowser is a wrapper for the webbrowser activex control 
//      Copied from webbrowser.cs in winforms
// 
// History
//  04/17/05    [....]      Created
//
//----------------------------------------------------------------------------- 

using System; 
using System.ComponentModel; 
using System.Runtime.InteropServices;
using System.Windows; 
using MS.Win32;
using System.Security;
using System.Security.Permissions;
using System.Windows.Controls.Primitives; //PopupRoot 
using MS.Internal.PresentationFramework;
using MS.Internal.Utility ; 
using MS.Internal.AppModel; //RootBrowserWindow 
using System.Windows.Interop;
using System.Windows.Input; 
using System.Windows.Threading;
using System.Diagnostics;

 
namespace MS.Internal.Controls
{ 
    /// 
    /// This is a wrapper over the native WebBrowser control implemented in shdocvw.dll.
    /// 
    internal sealed class WebBrowser : ActiveXHost, IKeyboardInputSink
    {
        private const string WEBOC_GUID = "8856f961-340a-11d0-a96b-00c04fd705a2";
 
        #region Constructor
 
        static WebBrowser() 
        {
            if (IsWebOCPermissionRestricted) 
            {
                RegisterWithRBW();
            }
            TurnOnXPSP2Mitigations(); 
        }
 
        ///  
        /// 8856f961-340a-11d0-a96b-00c04fd705a2 is the clsid for the native webbrowser control
        ///  
        /// Uri to navigate the WebBrowser to.
        ///
        ///     Critical - accesses critical Ctor and create WeakEventPreprocessMessage.
        ///     TreatAsSafe - creating web browser considered safe. 
        ///
        ///                   Known threats and the justification as to why they are mitigated : 
        /// 
        ///                     Uri is validated at set time. An attempts to navigate outside site of origin will fail the demand for web-permission.
        ///                     Attempts to navigate the HTML to another page are mitigated by "Site Lock" feature. 
        ///                     Attempts to show popup's above HTML are mitigated by popup work.
        ///                     Running script inside WebOC - considered ok as script is Internet Zone.
        ///                     Running activeX controls - considered safe. Equivalent functionality is enabled through web-pages.
        ///                     Cookies: The WebOC thinks it's a top-level browser. Thus cookies it sets will always 
        ///                         have 1st party status, which wouldn't be right if the WebOC is in an XBAP that is
        ///                         third party to the containing HTML page. But now PresentationHost intercepts all 
        ///                         calls to the WinInet cookie APIs and will add the 3rd party flag when necessary. 
        ///
        /// 
        ///
        [ SecurityCritical, SecurityTreatAsSafe ]
        internal WebBrowser(Uri source)
            : base( WEBOC_GUID , true ) 
        {
            // Check whether feature is disabled 
            if (SafeSecurityHelper.IsFeatureDisabled(SafeSecurityHelper.KeyToRead.WebBrowserDisable)) 
            {
                // in case the registry key is '1' then demand unrestricted WebBrowserPermission to create it 
                SecurityHelper.DemandWebBrowserPermission();
            }
            else
            { 
                // Feature is enabled - demand Safe level to create this object, granted in Partial Trust by default
                (new WebBrowserPermission(WebBrowserPermissionLevel.Safe)).Demand(); 
            } 

            //We will start the navigation when the object is instantiated (during tree building events) 
            //_source will then be set to null after the navigation is kicked off. The current url can be
            //retrieved by using IWebBrowser2.LocationURL.

            SecurityHelper.DemandWebPermission( source ) ; 
            _source = new SecurityCriticalDataForSet ( source ) ;
 
            // If the webbrowser permission is restricted, we don't allow webbrowser to be inside Popup. 
            if (IsWebOCPermissionRestricted)
            { 
                Loaded += new RoutedEventHandler(LoadedHandler);
            }

            // Attach our hook to ComponentDispatcher.ThreadPreprocessMessage. It is the second event called 
            // when the messsages are coming in.
            if (Application.InBrowserHostedApp()) 
            { 
                _weakEventPreprocessMessage = new WeakEventPreprocessMessage(this);
            } 
        }

        #endregion Constructor
 
        #region Protected Methods
 
        protected override void Dispose(bool disposing) 
        {
            base.Dispose(disposing); 

            if (disposing)
            {
                if (_weakEventPreprocessMessage != null) 
                {
                    _weakEventPreprocessMessage.Dispose(); 
                    _weakEventPreprocessMessage = null; 
                }
            } 
        }

        /// This will be called when the native ActiveX control has just been created.
        /// Inheritors of this class can override this method to cast the nativeActiveXObject 
        /// parameter to the appropriate interface. They can then cache this interface
        /// value in a member variable. However, they must release this value when 
        /// DetachInterfaces is called (by setting the cached interface variable to null). 
        /// 
        ///     Critical: This code can be exploited to pass in a bogus Activex object 
        /// 
        [SecurityCritical]
        protected override void AttachInterfaces(object nativeActiveXObject)
        { 
            //cache the interface
            this._axIWebBrowser2 = (UnsafeNativeMethods.IWebBrowser2)nativeActiveXObject; 
 
            //
            //Initializations 
            //
            //By default _axIWebBrowser2.RegisterAsDropTarget and _axIWebBrowser2.RegisterAsBrowser
            //are set to false. Since we control navigations through webbrowser events, we can set these
            //to true if needed to allow drag n drop of documents on to the control and 
            //allow frame targetting respectively. Think its better to lock it down until this is spec-ed out
 
            //Set Silent property to true to suppress error dialogs (or demand permission for it here and 
            //set it accordingly)
 

        }

        /// See AttachInterfaces for a description of when to override DetachInterfaces. 
        /// 
        ///     Critical: This code references the critical object _axIWebBrowser2 
        ///     TreatAsSafe: It does not expose it 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        protected override void DetachInterfaces()
        {
            //clear the interface. Base will release the COMObject
            _axIWebBrowser2 = null; 
        }
 
        ///  
        ///     Attaches to the DWebBrowserEvents2 connection point.
        ///  
        ///
        ///     Critical - calls critical code - ActiveXInstance.
        ///     TreatAsSafe - registering to handle events is ok.
        /// 
        [ SecurityCritical, SecurityTreatAsSafe ]
        protected override void CreateSink() 
        { 
            object ax = this.ActiveXInstance;
            if (ax != null) 
            {
                _cookie = new ConnectionPointCookie(ax,
                        new WebBrowserEvent(this),
                        typeof(UnsafeNativeMethods.DWebBrowserEvents2)); 
            }
        } 
 
        ///
        ///     Releases the DWebBrowserEvents2 connection point. 
        ///
        protected override void DetachSink()
        {
            //If we have a cookie get rid of it 
            if ( _cookie != null)
            { 
                _cookie.Disconnect(); 
                _cookie = null;
            } 
        }

        ///
        ///     Needs to link-demand as base method link-demanded. 
        ///
        ///     Critical - calls critical WebBrowserSite - ctor. 
        /// 
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        [SecurityCritical] 
        protected override ActiveXSite CreateActiveXSite()
        {
            return new WebBrowserSite(this);
        } 

 
        ///  
        /// Called whenever the ActiveX state changes
        ///  
        /// 
        /// 
        ///
        ///     Critical - accesses critical methods. 
        ///     TreatAsSafe -
        ///                     set - before setting the value of _source, we demanded web-permission. 
        ///                           _source is critical for set. 
        ///
        ///                           other risks around invocation of WebOC ( e.g. popups over content). 
        ///                           are mitigated by other defense-in-depth measures.
        ///
        [ SecurityCritical, SecurityTreatAsSafe ]
        protected override void OnActiveXStateChange(int oldState, int newState) 
        {
            if (newState > oldState && newState == (int)ActiveXHelper.ActiveXState.InPlaceActive) 
            { 
                if (_source.Value != null)
                { 
                    object nullObject = null;
                    this.DoNavigate(ref nullObject, ref nullObject, ref nullObject, ref nullObject);
                    _source.Value = null;
                } 
            }
        } 
 
        //
        //If we make WebBrowser public, raise events here. For now, I made these internal 
        //and am hooking only those events that are needed to host weboc in partial trust.
        //
        ///
        ///     Critical - accesses critical member e.Uri. 
        ///     TreatAsSafe - checking whether caller has the permission is ok.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal void OnNavigating(WebBrowserNavigatingEventArgs e)
        { 
            if( ! SecurityHelper.CallerHasWebPermission( e.Uri ))
            {
                e.Cancel = true ;
            } 
        }
 
        ///  
        ///     GetDrawing - Returns the drawing content of this Visual.
        ///  
        /// 
        ///     This returns a bitmap obtained by calling the PrintWindow Win32 API.
        /// 
        ///  
        ///     Critical:This code Asserts an elevated permission.
        ///     TreatAsSafe: only site of origin pages can be loaded in PT, so giving out a bitmap of this window is OK. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal override System.Windows.Media.DrawingGroup GetDrawing() 
        {
            // SecurityHelper.DemandWebPermission(_source.Value); // _source is null by now...

            (new UIPermission(UIPermissionWindow.AllWindows)).Assert(); // Blessed assert 
            try
            { 
                return base.GetDrawing(); 
            }
            finally 
            {
                UIPermission.RevertAssert();
            }
        } 

        #endregion Protected Methods 
 
        //----------------------------------------------
        // 
        // Private Methods
        //
        //----------------------------------------------
 
        #region Private Methods
 
        ///  
        ///     Critical:This code gets critical data, PresentationSource
        ///     TreatAsSafe: The PresentationSource is not exposed. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void LoadedHandler(object sender, RoutedEventArgs args)
        { 
            PresentationSource pSource = PresentationSource.CriticalFromVisual(this);
 
            // Note that we cannot assert this condition here. The reason is that this element might have 
            // been disconnected from the tree through one of its parents even while it waited for the
            // pending Loaded event to fire. More details for this scenario can be found in the 
            // Windows OS Bug#1981485.
            // Invariant.Assert(pSource != null, "Loaded has fired. PresentationSource shouldn't be null");

            if (pSource != null && pSource.RootVisual is PopupRoot) 
            {
                throw new InvalidOperationException(SR.Get(SRID.CannotBeInsidePopup)); 
            } 
        }
 
        /// 
        ///     Critical:This code gets RBW
        ///     TreatAsSafe: The window is not exposed.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private static void RegisterWithRBW() 
        { 
            // if we are browser hosted, rbw should have been created here.
            // 
            if (RootBrowserWindow != null)
            {
                RootBrowserWindow.AddLayoutUpdatedHandler();
            } 
        }
 
 
        // Turn on all the XPSP2 mitigations.
        // We do it programmatically instead of adding reg-keys. 
        // So that these are on on all avalon apps.
        ///
        ///     Critical - calls critical code.
        ///        TreatAsSafe - turns on all the XPSP2 features that make the browser more lock-downed. 
        ///
        [ SecurityCritical, SecurityTreatAsSafe ] 
        private static void TurnOnXPSP2Mitigations() 
        {
            NativeMethods.OSVERSIONINFOEX osVersion = new NativeMethods.OSVERSIONINFOEX(); 

            if ( ! UnsafeNativeMethods.GetVersionEx( osVersion ) )
            {
                int w32Error = Marshal.GetLastWin32Error(); 
                throw new Win32Exception(w32Error);
            } 
 
            if ( (osVersion.majorVersion == 5) && (osVersion.minorVersion == 2) )
            { 
                // XPSP2 mitigations - not available on Server 2003.
                return ;
            }
 
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_OBJECT_CACHING, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_ZONE_ELEVATION, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ; 
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_MIME_HANDLING, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ; 
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_MIME_SNIFFING, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_WINDOW_RESTRICTIONS, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ; 
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_WEBOC_POPUPMANAGEMENT, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_BEHAVIORS, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_DISABLE_MK_PROTOCOL, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_LOCALMACHINE_LOCKDOWN, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ; 
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_SECURITYBAND, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_RESTRICT_ACTIVEXINSTALL, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ; 
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_VALIDATE_NAVIGATE_URL, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ; 
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_RESTRICT_FILEDOWNLOAD, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_ADDON_MANAGEMENT, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ; 
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_PROTOCOL_LOCKDOWN, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_HTTP_USERNAME_PASSWORD_DISABLE, NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_SAFE_BINDTOOBJECT , NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_UNC_SAVEDFILECHECK , NativeMethods.SET_FEATURE_ON_PROCESS, true ) ; 
            UnsafeNativeMethods.CoInternetSetFeatureEnabled( NativeMethods.FEATURE_GET_URL_DOM_FILEPATH_UNENCODED , NativeMethods.SET_FEATURE_ON_PROCESS, true ) ;
        } 
 
        ///
        ///     Critical - calls critical methods, can circumvent cross-domain. 
        ///
        [ SecurityCritical ]
        private void DoNavigate( ref object flags, ref object targetFrameName, ref object postData, ref object headers)
        { 
            try
            { 
                object sourceString = ( object) BindUriHelper.UriToString( _source.Value ) ; 

                this.GetAxIWebBrowser2().Navigate2(ref sourceString, ref flags, ref targetFrameName, ref postData, ref headers); 
            }
            catch (COMException ce)
            {
                // "the operation was canceled by the user" - navigation failed 
                // ignore this error, IE has already alerted the user.
                if ((uint)unchecked(ce.ErrorCode) != (uint)unchecked(0x800704c7)) 
                { 
                    throw(ce);
                } 
            }
        }

        ///  
        /// This method helps work around IE 6 WebOC bugs related to activation state change. The problem seems
        /// to be fixed in IE 7. 
        ///   * When the security 'goldbar' pops up, it acquires focus. When the user unblocks the control, 
        ///     focus is set to the main WebOC window, but it doesn't call us on IOleInPlaceSite.OnUIActivate()
        ///     like it normally does when it gets focus. This leaves the ActiveXState at InPlaceActive, but 
        ///     it should be UIActive. Because of this, the invariant assert in TranslateAccelerator() was
        ///     failing on a key down - WOSB 1961596.
        ///   * Similar case from DevDiv bug 121501: Clicking on a combobox to get its drop down list. If the
        ///     WebOC doesn't have focus before that, it acquires it, but doesn't call OnUIActivate(). This 
        ///     fails the Assert in OnPreprocessMessageThunk().
        ///  
        private void SyncUIActiveState() 
        {
            if (ActiveXState != ActiveXHelper.ActiveXState.UIActive && ((IKeyboardInputSink)this).HasFocusWithin()) 
            {
                Invariant.Assert(ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive);
                ActiveXState = ActiveXHelper.ActiveXState.UIActive;
            } 
        }
 
        ///  
        ///     Gives the component a chance to process keyboard input.
        ///     Return value is true if handled, false if not.  Components 
        ///     will generally call a child component's TranslateAccelerator
        ///     if they can't handle the input themselves.  The message must
        ///     either be WM_KEYDOWN or WM_SYSKEYDOWN.  It is illegal to
        ///     modify the MSG structure, it's passed by reference only as 
        ///     a performance optimization.
        ///  
        /// 
        ///     Critical - access critical data ActiveXInPlaceActiveObject and can be used to spoof input
        ///     TreatAsSafe: The interface declaration for this method has a demand on it. 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        bool IKeyboardInputSink.TranslateAccelerator(ref MSG msg, ModifierKeys modifiers)
        { 
            SyncUIActiveState();
            Invariant.Assert(ActiveXState >= ActiveXHelper.ActiveXState.UIActive, "Should be at least UIActive when we are processing accelerator keys"); 
 
            return (ActiveXInPlaceActiveObject.TranslateAccelerator(ref msg) == 0);
        } 

        /// 
        ///     Set focus to the first or last tab stop. If it can't, because it has no tab stops,
        ///     the return value is false. 
        /// 
        /// 
        ///     Critical - calls critical code DoVerb and can be used to spoof input 
        ///
        [SecurityCritical] 
        bool IKeyboardInputSink.TabInto(TraversalRequest request)
        {
            Invariant.Assert(ActiveXState >= ActiveXHelper.ActiveXState.InPlaceActive, "Should be at least InPlaceActive when tabbed into");
 
            bool activated = DoVerb(NativeMethods.OLEIVERB_UIACTIVATE);
 
            if (activated) 
            {
                this.ActiveXState = ActiveXHelper.ActiveXState.UIActive; 
            }

            return activated;
        } 

        /// 
        ///     Critical - critical because it can be used to spoof input 
        ///
        [SecurityCritical] 
        private void OnPreprocessMessageThunk(ref MSG msg, ref bool handled)
        {
            // only handle it when the focus is within.
            if ((handled) || !((IKeyboardInputSink)this).HasFocusWithin()) 
            {
                return; 
            } 

            SyncUIActiveState(); 
            Invariant.Assert(ActiveXState >= ActiveXHelper.ActiveXState.UIActive, "Should be at least UIActive when we are focused");

            switch (msg.message)
            { 
                case NativeMethods.WM_SYSKEYUP:
                case NativeMethods.WM_SYSKEYDOWN: 
                case NativeMethods.WM_KEYUP: 
                case NativeMethods.WM_KEYDOWN:
                    // Call OLE TranslateAccelerator to process the accelerator keys. 
                    handled = ((IKeyboardInputSink)this).TranslateAccelerator(ref msg, ModifierKeys.None);

                    // If it is tab and it is not handled, it means we are tabbing out. MoveFocus to the next or previous one
                    // in the tree depending on whether shift key is pressed. 
                    if ((!handled) && (msg.message == NativeMethods.WM_KEYDOWN) && ((int)msg.wParam == NativeMethods.VK_TAB))
                    { 
                        FocusNavigationDirection direction = ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) ? 
                                                            FocusNavigationDirection.Previous : FocusNavigationDirection.Next;
 
                        MoveFocus(new TraversalRequest(direction));
                    }
                    break;
            } 
        }
 
        ///  
        ///     Critical: This code exposes and unmanaged interface with SupressUnmanagedCodeSecurity attribute on some methods
        ///  
        [SecurityCritical]
        internal UnsafeNativeMethods.IWebBrowser2 GetAxIWebBrowser2()
        {
            if (_axIWebBrowser2 == null) 
            {
                if (!IsDisposed) 
                { 
                    //This should call AttachInterfaces which will set this member variable
                    //We don't want to force the state to InPlaceActive yet since we don't 
                    //have the parent handle yet
                    TransitionUpTo(ActiveXHelper.ActiveXState.Loaded);
                }
                else 
                {
                    throw new System.ObjectDisposedException(GetType().Name); 
                } 
            }
            // We still don't have _axIWebBrowser2. Throw an exception. 
            if (_axIWebBrowser2 == null)
            {
                throw new InvalidOperationException(SR.Get(SRID.WebBrowserNoCastToIWebBrowser2));
            } 
            return _axIWebBrowser2;
        } 
 

        #endregion Private Methods 


        #region Private Properties
 
        /// 
        ///     Critical:This code gets RBW 
        ///  
        private static RootBrowserWindow RootBrowserWindow
        { 
            [SecurityCritical]
            get
            {
                if (_rbw == null) 
                {
                    if (Application.Current != null) 
                    { 
                        _rbw = Application.Current.MainWindow as RootBrowserWindow;
                    } 
                }

                return _rbw;
            } 
        }
 
        ///  
        /// returns whether this is a restricted WebBrowser
        ///  
        /// 
        /// Critical - it accesses critical data (_isWebOCPermissionChecked, _isWebOCPermissionRestricted)
        /// TreatAsSafe - it's safe to return whether it has restricted permission.
        ///  
        private static bool IsWebOCPermissionRestricted
        { 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (!_isWebOCPermissionChecked)
                {
                    _isWebOCPermissionRestricted = ! SecurityHelper.CallerHasUnrestrictedWebBrowserPermission();
                    _isWebOCPermissionChecked = true; 
                }
                return _isWebOCPermissionRestricted; 
            } 
        }
 
        #endregion Private Properties

        #region Private Fields
 
        // Reference to the native ActiveX control's IWebBrowser2
        // Do not reference this directly. Use the AxIWebBrowser2 property instead since that 
        // will cause the object to be instantiated if it is not already created. 
        /// 
        ///     Critical: This code can be exploited to call Navigate on a page and it holds a COM interface 
        /// 
        [SecurityCritical]
        private UnsafeNativeMethods.IWebBrowser2    _axIWebBrowser2;
 
        // To hook up events from the native WebBrowser
        private ConnectionPointCookie   _cookie; 
 
        ///
        ///     Critical for set - demand made for webpermission before setting. 
        ///                        changing this value afterwards would allow circumvention of same-site for the weboc.
        ///
        private SecurityCriticalDataForSet         _source;
 
        private static RootBrowserWindow                _rbw;
 
        ///  
        /// determines whether _isWebOCPermissionRestricted was initialized or not yet.
        ///  
        /// 
        /// Critical - it indicates whether _isWebOCPermissionRestricted has been intialized or not.
        /// 
        [SecurityCritical] 
        private static bool                             _isWebOCPermissionChecked;
 
        ///  
        /// Critical - it determines whether this is a restricted WebBrowser.
        ///  
        [SecurityCritical]
        private static bool                             _isWebOCPermissionRestricted;

        private WeakEventPreprocessMessage                  _weakEventPreprocessMessage; 

        #endregion Private Fields 
 
        #region Private Class
        // 
        // Private classes:
        //
        private class WeakEventPreprocessMessage : WeakReference
        { 
            /// 
            ///     Critical: This code calls attaches an arbitrary window 
            ///     to the call path for the component dispatcher call back. 
            ///     Assert in the code.
            ///  
            [SecurityCritical]
            public WeakEventPreprocessMessage(WebBrowser webBrowser): base(webBrowser)
            {
                (new UIPermission(PermissionState.Unrestricted)).Assert(); // Blessed assert 
                try
                { 
                    // We are attaching to this second-chance event handler because the first-chance 
                    // handler is already being used to let the host preprocess messages and send certain
                    // messages directly to the browser frame. 
                    ComponentDispatcher.ThreadPreprocessMessage +=
                                    new ThreadMessageEventHandler(this.OnPreprocessMessage);
                }
                finally 
                {
                    UIPermission.RevertAssert(); 
                } 
            }
 
            /// 
            ///     Critical: This code calls critcal method OnPreprocessMessageThunk
            /// 
            [SecurityCritical] 
            public void OnPreprocessMessage(ref MSG msg, ref bool handled)
            { 
                WebBrowser webBrowser = this.Target as WebBrowser; 
                if(null != webBrowser)
                { 
                    webBrowser.OnPreprocessMessageThunk(ref msg, ref handled);
                }
                else
                { 
                    Dispose();
                } 
            } 

            ///  
            ///     Critical:This code calls into ComponentDispatcher
            ///     to disconnect a listener. Assert in the code.
            ///     TreatAsSafe: This code is ok to call
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            public void Dispose() 
            { 
                (new UIPermission(PermissionState.Unrestricted)).Assert(); // Blessed assert
                try 
                {
                    ComponentDispatcher.ThreadPreprocessMessage -=
                                    new ThreadMessageEventHandler(this.OnPreprocessMessage);
                } 
                finally
                { 
                    UIPermission.RevertAssert(); 
                }
            } 

        }

        #endregion Private Class 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK