ApplicationProxyInternal.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / MS / Internal / AppModel / ApplicationProxyInternal.cs / 1 / ApplicationProxyInternal.cs

                            //------------------------------------------------------------------------------ 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: This is an internal proxy wrapper class over Application class. 
//              This derives from MarshalByRefObject and thus facilitates calling 
//              the AppCode from DocobjHost that may be running in a different
//              AppDomain.  The other thing it allows is to be able to create 
//              the App Object on the right thread by exposing a delegate that
//              could be set to point to the code that creates the AppObject and
//              invoking the delegate from the right thread.
// 
// History:
//  07/03/2003 [....]  Created 
//  10/04/2005 FrankGor Documented & refactored class; primary reason was ensure 
//                      disposal of all XpsViewer (DocumentApplication)
//                      resources 
//-----------------------------------------------------------------------------

//**
//** IMPORTANT: Running arbitrary application code in the context of an incoming call from the browser 
//**    should be avoided. This could lead to unexpected reentrancy (on either side) or making the
//      browser frame unresponsive while the application code is running. Bug 1139336 illustrates 
//      what can happen if the application code enters a local message loop while the browser is 
//      blocked. To avoid such situations in general, use Dispatcher.BeginInvoke() instead of making
//      direct calls into unknown code. 


using System;
using System.Diagnostics; 
using System.IO;
using System.IO.Packaging; 
using System.Reflection; 
using System.Runtime.InteropServices;
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Permissions;
using System.Threading; 
using System.Windows;
using System.Windows.Controls; 
using System.Windows.Controls.Primitives; 
using System.Windows.Input;
using System.Windows.Interop; 
using System.Windows.Navigation;
using System.Windows.Threading;

using MS.Internal; 
using MS.Internal.Documents;
using MS.Internal.Documents.Application; 
using MS.Internal.IO.Packaging; 
using MS.Internal.IO.Packaging.CompoundFile;
using MS.Internal.PresentationFramework; 
using MS.Internal.Utility;
using MS.Internal.AppModel;
using MS.Utility;
 
//In order to avoid generating warnings about unknown message numbers and
//unknown pragmas when compiling your C# source code with the actual C# compiler, 
//you need to disable warnings 1634 and 1691. (Presharp Documentation) 
#pragma warning disable 1634, 1691
 
namespace MS.Internal.AppModel
{
    // All security sensitive classes should be sealed or protected with InheritanceDemand
    internal sealed class ApplicationProxyInternal : MarshalByRefObject 
    {
        [Serializable] 
        internal class InitData 
        {
            internal IServiceProvider ServiceProvider; 
            internal SecurityCriticalDataForSet MimeType;
            internal SecurityCriticalDataForSet ActivationUri;
            internal string Fragment;
            internal object UcomLoadIStream; 
            internal bool HandleHistoryLoad;
            internal string UserAgentString; 
            internal bool IsBrowserLowIntegrityProcess; 
            internal Rect WindowRect;
            internal bool ShowWindow; 
        };

        //-----------------------------------------------------
        // 
        //  Constructors
        // 
        //----------------------------------------------------- 
        #region Constructors
 
        /// 
        /// ApplicationProxyInternal is created only for browser-hosted applications.
        /// 
        ///  
        /// Critical:
        ///     1) We want to track creation of ApplicationProxyInternal because it can be used to 
        ///        make calls between AppDomains (it's MarshalByRefObject). 
        ///     2) It sets BrowserInteropHelper.IsBrowserHosted, which is critical for set.
        ///  
        [SecurityCritical]
        internal ApplicationProxyInternal()
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.AppProxyCtor); 
            } 

            if (_proxyInstance != null) 
            {
                throw new InvalidOperationException(SR.Get(SRID.MultiSingleton, this.GetType().FullName));
            }
            // Set this here so it will be true for documents or applications (i.e. anything in the browser.) 
            BrowserInteropHelper.SetBrowserHosted(true);
            _proxyInstance = this; 
        } 

        #endregion Constructors 

        //------------------------------------------------------
        //
        //  Internal Methods 
        //
        //----------------------------------------------------- 
        #region Internal Methods 

        public override object InitializeLifetimeService() 
        {
            //Keeps it alive until the AppDomain is teared down which is what we want.
            //Otherwise the .Net remoting infrastructure releases all remote objects in 5 mins
            //if there are no sponsors registered with the lease manager for the remote object. 
            //This is an alternative to the client side registering a sponsor by the server object
            //marking itself to be kept alive for the life of the AppDomain. 
            return null; 
        }
 
        //Creates the internal RootBrowserWindow. If the startup Uri points
        //to a Window/NavigationWindow, we still need to create this empty
        //RootBrowserWindow so we can repaint properly inside the browser window
 
        ///
        ///  Critical as this code invokes a delegate that accesses critical data. 
        ///  TreatAsSafe - creating the browser window for your content to be hosted in is considered safe. 
        ///                       this is considered safe - as you can only control the internal window of the browser.
        ///                       you cannot change styles of the actual browser window ( verified this). 
        ///                       Dangerous behaviors ( e.g. ShowInTaskbar = false) don't work when in browser hosted.
        ///
        ///
        [SecurityCritical, SecurityTreatAsSafe ] 
        internal void CreateRootBrowserWindow()
        { 
            if (_rbw.Value == null) 
            {
 
                Application.Current.Dispatcher.Invoke(
                                    DispatcherPriority.Send,
                                    new DispatcherOperationCallback(_CreateRootBrowserWindowCallback),
                                    null); 
            }
        } 
 
        internal bool FocusedElementWantsBackspace()
        { 
            TextBoxBase textBoxBase = Keyboard.FocusedElement as TextBoxBase;
            if (textBoxBase != null)
            {
                return true; // textBoxBase.IsEmpty 
            }
 
            PasswordBox passwordBox = Keyboard.FocusedElement as PasswordBox; 
            if (passwordBox != null)
            { 
                return true; // passwordBox.IsEmpty
            }

            return false; 
        }
 
        /// 
        ///  Critical as this code calls the critical RootBrowserWindow.CreateAndInitialize()
        /// 
        [SecurityCritical]
        private object _CreateRootBrowserWindowCallback(object unused)
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance)) 
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.RootBrowserWindowSetupStart); 
            } 

            RootBrowserWindow = RootBrowserWindow.CreateAndInitialize(); 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance))
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.RootBrowserWindowSetupEnd); 
            }
            return null ; 
        } 

        // Calls the Run method on the app object. 
        ///
        /// Critical - creates a critical delegate, provides the path to LoadFromContainer, which
        ///            is critical, and also calls InitContainer which is critical.  Accesses
        ///            several critical data values (_path, _container, _storageRoot). 
        ///          - also sets Uri and _mimeType, which are critical.
        /// 
        [SecurityCritical] 
        internal int Run(InitData initData)
        { 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.AppProxyRunStart);
            } 

            MimeType mimeType = initData.MimeType.Value; 
            _mimeType.Value = mimeType; 
            Uri = initData.ActivationUri.Value;
            WpfWebRequestHelper.DefaultUserAgent = initData.UserAgentString; 
            BrowserInteropHelper.IsBrowserLowIntegrityProcess.Value = initData.IsBrowserLowIntegrityProcess;

            // These methods are asynchronous.
            // If the RootBrowserWindow is not created yet, only the size for it will be stored. 
            Move(initData.WindowRect);
            Show(initData.ShowWindow); 
 
            switch (mimeType)
            { 
                case MimeType.Markup:
                    // Make a dummy application (in lieu of the one provided by the defunct XamlViewer.xbap).
                    Invariant.Assert(AppDomain.CurrentDomain.FriendlyName == "XamlViewer");
                    Application app = new Application(); 
                    app.StartupUri = Uri;
                    // Any URL #fragment is appended to StartupUri in _RunDelegate(). 
                    // For history navigation, ApplicationProxyInternal has already started navigation to the 
                    // last journal entry captured. (This journal entry may include a #fragment target and/or
                    // a CustomContentState.) 
                    break;

                case MimeType.Application:
                    //This is a browser app, the application object has already been created 
                    break;
 
                case MimeType.Document: 
                    try
                    { 
                        InitContainer();
                        PackageDocument document = _document.Value as PackageDocument;
                        // This will fail to load if the document is not set to a valid PackageDocument.
                        if (document != null) 
                        {
                            ContainerActivationHelper.LoadFromContainer( 
                                Uri, 
#if CF_Envelope_Activation_Enabled
                                _storageRoot.Value, 
#endif
                                document.Package,
                                _serviceProvider);
 
                        }
                    } 
                    catch (Exception e) 
                    {
                        // If we catch an exception while initializing the document, we need 
                        // to wrap it in a CrossDomainSerializableException to avoid SecurityExceptions
                        // when the exception is serialized across AppDomains.
                        throw new CrossDomainSerializableException(e);
                    } 
                    break;
                case MimeType.Unknown: 
                default: 
                    throw new InvalidOperationException();
            } 

            // Set the Application.MimeType
            // Since loading containers causes the application to be constructed now,
            // the initial setting of the MimeType does not get passed to the application. 
            Application.Current.MimeType = mimeType;
            ServiceProvider = initData.ServiceProvider; // also sets Application.ServiceProvider 
 
            Application.Current.Dispatcher.Invoke(
                DispatcherPriority.Send, 
                new DispatcherOperationCallback(_RunDelegate),
                initData);

            int exitCode = Application.Current.RunInternal(null); 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.AppProxyRunEnd);
            } 

            return exitCode;
        }
 
        ///
        ///     Critical as this calls a critical function ( LoadHistoryStream). 
        /// 
        [SecurityCritical]
        private object _RunDelegate( object args ) 
        {
            InitData initData = (InitData)args;

            Application currentApp = Application.Current; 
            if (currentApp != null && !(currentApp is XappLauncherApp))
            { 
                string fragment = initData.Fragment; 
                if (!String.IsNullOrEmpty(fragment) && currentApp.StartupUri != null)
                { 
                    // Apply Fragment to Application StartupUri.
                    UriBuilder uriBuilder;
                    Uri absUri = currentApp.StartupUri;
 
                    if (currentApp.StartupUri.IsAbsoluteUri == false)
                    { 
                        absUri = new Uri(BindUriHelper.BaseUri, currentApp.StartupUri); 
                    }
 
                    uriBuilder = new UriBuilder(absUri);
                    if (fragment.StartsWith(FRAGMENT_MARKER, StringComparison.Ordinal))
                    {
                        fragment = fragment.Substring(FRAGMENT_MARKER.Length); 
                    }
                    uriBuilder.Fragment = fragment; 
                    currentApp.StartupUri = uriBuilder.Uri; 
                }
 
                CreateRootBrowserWindow();
            }

            //If we were started through IPersistHistory::Load, load from the history stream instead 
            //of navigating to the StartupPage
            if (initData.UcomLoadIStream != null && initData.HandleHistoryLoad) 
            { 
                LoadHistoryStream(DocObjHost.ExtractComStream(initData.UcomLoadIStream), /*firstHistoryLoad=s*/true);
            } 
            return null;
        }

        // Show or hide view. 
        internal void Show(bool show)
        { 
            _show = show; 
            if (Application.Current != null && RootBrowserWindow != null)
            { 
                Application.Current.Dispatcher.BeginInvoke(
                                    DispatcherPriority.Send,
                                    new DispatcherOperationCallback(_ShowDelegate),
                                    null); 
            }
 
        } 

        private object _ShowDelegate(object ignore) 
        {
            // The RBW might be torn down just before the DispatcherOperation is invoked.
            if (RootBrowserWindow == null || Application.IsShuttingDown)
                return null; 

            if (_show) 
            { 
                // The window is shown asynchronously (using Visibility, not Show()) to allow first restoring
                // the Journal on history navigation. This prevents bug 1367999. 
                _rbw.Value.Visibility = Visibility.Visible;

                // initial focus should be on us, not the browser frame
                // Focusing is done asynchronously because Visibility actually changes asynchronously. 
                Application.Current.Dispatcher.BeginInvoke(
                    // same priority as used in the Window.Visibility PropertyChangedCallback 
                    DispatcherPriority.Normal, 
                    new DispatcherOperationCallback(_FocusDelegate), null);
            } 
            else
            {
                _rbw.Value.Visibility = Visibility.Hidden;
            } 

            return null; 
        } 

        ///  
        /// Critical: Calls the critical UnsafeNativeMethods.SetFocus(), which returns a handle to
        ///     the previously focused window.
        /// Safe: The handle is not disclosed, and focusing the application's own window (RBW) is okay.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private object _FocusDelegate(object unused) 
        { 
            if (_rbw.Value != null)
            { 
                try
                {
                    MS.Win32.UnsafeNativeMethods.SetFocus(new HandleRef(_rbw.Value, _rbw.Value.CriticalHandle));
                } 
#pragma warning disable 6502
                // The browser may temporarily disable the RBW. Then SetFocus() fails. 
                // This is known to happen when the browser pops up the modal dialog about the Information Bar. 
                catch (System.ComponentModel.Win32Exception)
                { 
                    Debug.WriteLine("SetFocus() on RootBrowserWindow failed.");
                }
#pragma warning restore 6502
            } 
            return null;
        } 
 
        internal void Move(Rect windowRect)
        { 
            if (Application.Current != null && RootBrowserWindow != null)
            {
                Application.Current.Dispatcher.BeginInvoke(
                                    DispatcherPriority.Send, 
                                    new DispatcherOperationCallback(_MoveDelegate),
                                    windowRect); 
            } 
            else
            { 
                // We got UIActivated too early.  Remember the data passed in.
                _windowRect = windowRect;
                _rectset = true;
            } 
        }
 
        private object _MoveDelegate( object moveArgs ) 
        {
            // The RBW might be closed just before _MoveDelegate() is called. => check _rbw again. 
            if (_rbw.Value != null && !Application.IsShuttingDown)
            {
                Rect r = (Rect)moveArgs;
 
                // ResizeMove is implemented by RBW and should be called here
                // since it resizes and moves the WS_CHILD window.  Do not call 
                // Height/Width & Top/Left here since they govern the browser 
                // window properties.
                _rbw.Value.ResizeMove((int)r.X, (int)r.Y, (int)r.Width, (int)r.Height); 
            }
            return null;
        }
 
        // Shutdown the App.
        // Note: The "post" in the method name is legacy. Now all of Application's shutdown work is complete 
        // when this method returns. In particular, the managed Dispatcher is shut down. 
        ///
        ///  Critical: Calls Application.CriticalShutdown(). 
        ///
        [SecurityCritical]
        internal void PostShutdown()
        { 
            Cleanup();
            _proxyInstance = null; 
 
            Application app = Application.Current;
            if (app != null) 
            {
                XappLauncherApp launcherApp = app as XappLauncherApp;
                if (launcherApp != null)
                { 
                    launcherApp.AbortActivation();
                    Debug.Assert(Application.IsShuttingDown); 
                } 
                else
                { 
                    //this calls into the internal helper and is hardcoded for a clean
                    // shutdown
                    app.CriticalShutdown(0);
 
                    // The Application.Exit event is raised in a Dispatcher callback at Normal priority.
                    // Blocking on this callback here ensures that the event will be raised before we've 
                    // disconnected from the browser. An XBAP may want, in particular, to write a cookie. 
                    app.Dispatcher.Invoke(DispatcherPriority.Normal,
                        new DispatcherOperationCallback(delegate(object unused) { return null; }), null); 
                }
            }
        }
 
        //
        // Activate or Deactivate RootBrowserWindow 
        // 

        internal void Activate(bool fActivate) 
        {
            if (Application.Current != null && RootBrowserWindow != null)
            {
                Application.Current.Dispatcher.BeginInvoke( 
                                    DispatcherPriority.Send,
                                    new DispatcherOperationCallback(_ActivateDelegate), 
                                    fActivate); 
            }
        } 

        private object _ActivateDelegate(object arg )
        {
            if (RootBrowserWindow != null) 
            {
                bool fActivate = (bool)arg; 
 
                _rbw.Value.HandleActivate(fActivate);
                if (fActivate) 
                {
                    _FocusDelegate(null);
                }
            } 
            return null;
        } 
 
        internal bool CanInvokeJournalEntry(int entryId)
        { 
            if (Application.Current == null)
            {
                return false;
            } 

            return (bool)Application.Current.Dispatcher.Invoke( 
            DispatcherPriority.Send, 
                (DispatcherOperationCallback) delegate(object unused)
            { 
                NavigationWindow window = Application.Current.MainWindow as NavigationWindow;

                if (window == null)
                    return false; 

                return window.JournalNavigationScope.CanInvokeJournalEntry(entryId); 
            }, 
            null);
        } 

        // Private class just to facilitate passing of data back to GetSaveHistoryBytes.
        private class SaveHistoryReturnInfo
        { 
            internal string uri;
            internal string title; 
            internal int entryId; 
            internal byte[] saveByteArray ;
        } 

        ///  Called by the browser to serialize the entire journal or just the index of
        /// the current entry. The second case is when an internal Journal update needs to be
        /// reflected in the TravelLog. 
        /// 
        ///  true is the entire Journal is to serialized  
        /// 
        ///     Critical as this method accesses critical data.
        ///              and we elevate for serialization permission. 
        ///
        [SecurityCritical]
        private object _GetSaveHistoryBytesDelegate(object arg)
        { 
            bool entireJournal = (bool)arg;
 
            SaveHistoryReturnInfo info = new SaveHistoryReturnInfo(); 

            // When we are here, the browser has just started to shut down, so we should only check 
            // whether the application object is shutting down.
            if (Application.IsApplicationObjectShuttingDown == true)
                return null;
 
            Invariant.Assert(_rbw.Value != null, "BrowserJournalingError: _rbw should not be null");
 
            Journal journal = _rbw.Value.Journal; 
            Invariant.Assert(journal != null, "BrowserJournalingError: Could not get internal journal for the window");
 
            JournalEntry entry;
            if (entireJournal) // The application is about to be shut down...
            {
                NavigationService topNavSvc = _rbw.Value.NavigationService; 
                try
                { 
                    topNavSvc.RequestCustomContentStateOnAppShutdown(); 
                }
                catch(Exception e) 
                {
                    if(CriticalExceptions.IsCriticalException(e))
                    {
                        throw; 
                    }
                } 
 
                journal.PruneKeepAliveEntries();
 
                // Since the current page is not added to the journal until it is replaced,
                // we add it here explicitly to the internal Journal before serializing it.
                entry = topNavSvc.MakeJournalEntry(JournalReason.NewContentNavigation);
                if (entry != null && !entry.IsAlive()) 
                {
                    if (entry.JEGroupState.JournalDataStreams != null) 
                    { 
                        entry.JEGroupState.JournalDataStreams.PrepareForSerialization();
                    } 
                    journal.UpdateCurrentEntry(entry);
                }
                else // Maybe the current content is null or a PageFunction doesn't want to be journaled.
                {   // Then the previous navigable page, if any, should be remembered as current. 
                    entry = journal.GetGoBackEntry();
                    // i. _LoadHistoryStreamDelegate() has a similar special case. 
                } 
            }
            else 
            {   // (Brittle) Assumption: GetSaveHistoryBytes() is called after the current entry has
                // been updated in the internal journal but before the new navigation is committed.
                // This means journal.CurrentEntry is what was just added (or updated).
                // Note that it would be wrong to call topNavSvc.MakeJournalEntry() in this case because 
                // the navigation that just took place may be in a different NavigationService (in a
                // frame), and here we don't know which one it is. 
                entry = journal.CurrentEntry; 

                // The entry may be null here when the user has selected "New Window" or pressed Ctrl+N. 
                // In this case the browser calls us on IPersistHistory::Save and then throws that data
                // away.  Hopefully at some point in the future that saved data will be loaded in the new
                // window via IPersistHistory::Load.  This unusual behavior is tracked in bug 1353584.
            } 

            if (entry != null) 
            { 
                info.title = entry.Name;
                info.entryId = entry.Id; 
            }
            else
            {
                info.title = _rbw.Value.Title; 
            }
 
            // We only use the base URI here because the travel log will validate a file URI when making a PIDL. 
            // We use the URI stored in the JournalEntry, and the travel log doesn't care what the URI is, so
            // duplicates don't matter. 
            info.uri = BindUriHelper.UriToString(Uri);

            MemoryStream saveStream = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter(); 

            saveStream.Seek(0, SeekOrigin.Begin); 
            object objectToSave = info.entryId; 

            if (entireJournal) 
            {
                //Save the Journal and BaseUri also. We don't need BaseUri except for the xaml case
                //since this is set specially for the container case (ssres scheme). Exe case
                //will pretty much set it to the exe path. For the xaml case it is set to the path 
                //of the first uri(eg BaseDir\page1.xaml) that was navigated to.
                //BaseDir/Subdir/page2.xaml is also considered to be in the same extent and when 
                //we navigate back to the app from a webpage, the baseUri should still be BaseDir 
                //not BaseDir/Subdir. We were setting the BaseDir from JournalEntry.Uri but we may
                //end up setting BaseUri to BaseDir/Subdir which is not the same. So explicitly 
                //persist BaseUri as well
                BrowserJournal browserJournal = new BrowserJournal(journal, BindUriHelper.BaseUri);
                objectToSave = browserJournal;
            } 

            new SecurityPermission(SecurityPermissionFlag.SerializationFormatter).Assert(); 
            try 
            {
                formatter.Serialize(saveStream, objectToSave); 
            }
            catch(Exception e)
            {
                if(CriticalExceptions.IsCriticalException(e)) 
                {
                    throw; 
                } 

                // The application is shutting down and the exception would not be reported anyway. 
                // This is here to help with debugging and failure analysis.
                Invariant.Assert(false, "Failed to serialize the navigation journal: " + e);
            }
            finally 
            {
                CodeAccessPermission.RevertAll() ; 
            } 

            info.saveByteArray = saveStream.ToArray(); 
            ((IDisposable)saveStream).Dispose();

            return info ;
        } 

        //CASRemoval:[SecurityPermission(SecurityAction.Assert, SerializationFormatter = true)] 
 
        ///
        ///     Critical as the delegate that this method invokes accesses critical data. 
        ///
        [SecurityCritical]
        internal byte[] GetSaveHistoryBytes(bool persistEntireJournal, out int journalEntryId, out string uriString, out string titleString)
        { 
            SaveHistoryReturnInfo info = null ;
 
            if (Application.Current != null) 
            {
                info = ( SaveHistoryReturnInfo) Application.Current.Dispatcher.Invoke( 
                                DispatcherPriority.Send,
                                new DispatcherOperationCallback(_GetSaveHistoryBytesDelegate) ,
                                persistEntireJournal);
            } 

            if ( info != null ) 
            { 
                journalEntryId = info.entryId;
                uriString = info.uri; 
                titleString = info.title;
                return info.saveByteArray;
            }
            else 
            {
                journalEntryId = 0; 
                uriString = null; 
                titleString = null;
                return null; 
            }
        }

        /// 
        ///     Critical as the delegate that this method invokes accesses critical data.
        /// 
        [SecurityCritical] 
        internal void LoadHistoryStream(MemoryStream loadStream, bool firstLoadFromHistory)
        { 
            if (Application.Current == null)
            {
                return;
            } 

            LoadHistoryStreamInfo info = new LoadHistoryStreamInfo(); 
            info.loadStream = loadStream ; 
            info.firstLoadFromHistory = firstLoadFromHistory ;
 
            Application.Current.Dispatcher.Invoke(
                        DispatcherPriority.Send,
                        new DispatcherOperationCallback(_LoadHistoryStreamDelegate),
                        info); 
        }
 
        private class LoadHistoryStreamInfo 
        {
            internal MemoryStream loadStream ; 
            internal bool firstLoadFromHistory;
        }

        /// 
        ///     Critical as this method accesses critical data.
        /// 
        [SecurityCritical] 
        private object _LoadHistoryStreamDelegate( object arg )
        { 
            Journal             journal     = null;
            JournalEntry        entry       = null;

            LoadHistoryStreamInfo info = (LoadHistoryStreamInfo) arg ; 

            if (IsShutdown() == true) 
                return null; 

            // Reset the memory stream pointer back to the begining and get the persisted object 
            info.loadStream.Seek(0, System.IO.SeekOrigin.Begin);

            object journaledObject = DeserializeJournaledObject(info.loadStream);
 
            //This is the very first load from history, so need to set the BaseUri and StartupUri.
            if (info.firstLoadFromHistory) 
            { 
                // Patch for WOSB 1834243: The journal does not get saved on Ctrl+N. Because of this,
                // here we can get just an index, like in the 'else' case below. 
                if(!(journaledObject is BrowserJournal))
                    return null;

                BrowserJournal browserJournal = (BrowserJournal)journaledObject; 

                journal = browserJournal.Journal; 
                entry = journal.CurrentEntry; 
                if (entry == null) // See special case in _GetSaveHistoryBytesDelegate().
                { 
                    entry = journal.GetGoBackEntry(); // could still be null
                }

                //This will create the frame to use for hosting 
                {
                    NavigationService navigationService = null; 
                    navigationService = _rbw.Value.NavigationService; 
                }
                _rbw.Value.SetJournalForBrowserInterop(journal); 

                //This should already be set for the container and exe cases. The former
                //sets it to the transformed ssres scheme and we don't want to overwrite it.
                if (BindUriHelper.BaseUri == null) 
                {
                    BindUriHelper.BaseUri = browserJournal.BaseUri; 
                } 

                // 



 
                Debug.Assert(Application.Current != null, "BrowserJournalingError: Application object should already be created");
 
                if (entry != null) 
                {
                    //Prevent navigations to StartupUri for history loads by canceling the StartingUp event 
                    Application.Current.Startup += new System.Windows.StartupEventHandler(this.OnStartup);

                    _rbw.Value.JournalNavigationScope.NavigateToEntry(entry);
                } 
                //else: fall back on navigating to StartupUri
            } 
            else 
            {
                journal = _rbw.Value.Journal; 

                int index = journal.FindIndexForEntryWithId((int)journaledObject);

                Debug.Assert(journal[index].Id == (int)journaledObject, "BrowserJournalingError: Index retrieved from journal stream does not match index of journal entry"); 

                // Check whether the navigation is canceled. 
                if (! _rbw.Value.JournalNavigationScope.NavigateToEntry(index)) 
                {
                    // When the navigation is canceled, we want to notify browser to prevent the internal journal from 
                    // getting out of [....] with the browser's.
                    // The exception will be caught by the interop layer and browser will cancel the navigation as a result.

                    // If the navigation is initiated pragmatically by calling GoBack/Forward (comparing to user initiated 
                    // by clicking the back/forward button),  this will result in a managed exception at the call to ibcs.GoBack()
                    // in rbw.GoBackOverride(). rbw catches the exception when this happens. 
 
                    throw new OperationCanceledException();
                } 
            }

            return null;
        } 

        ///  
        /// Critical - Asserts for Serialization permission to deserialize an object from the input stream. 
        /// 
        [SecurityCritical] 
        private object DeserializeJournaledObject(MemoryStream inputStream)
        {
            object deserialized = null;
            BinaryFormatter formatter = new BinaryFormatter(); 
            new System.Security.Permissions.SecurityPermission(SecurityPermissionFlag.SerializationFormatter).Assert();
            try 
            { 
                deserialized = formatter.Deserialize(inputStream);
            } 
            finally
            {
                CodeAccessPermission.RevertAssert();
            } 
            return deserialized;
        } 
 
        // See if an App instance is currently loaded.
        internal bool IsAppLoaded() 
        {
            return (Application.Current == null ? false : true);
        }
 
        // Return the internal static variable _shutdown.
        internal bool IsShutdown() 
        { 
            return Application.IsShuttingDown;
        } 

        /// 
        /// Critical: Calls a critical ctor (ApplicationProxyInternal)
        ///  
        [SecurityCritical]
        internal static ApplicationProxyInternal CreateInDomain(AppDomain appDomain) 
        { 
            // Create an ApplicationProxyInternal in the new domain.
            return appDomain.CreateInstanceAndUnwrap( 
                                        Assembly.GetAssembly(typeof(ApplicationProxyInternal)).FullName,
                                        typeof(ApplicationProxyInternal).FullName,
                                        false,
                                        BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, 
                                        null, null, null, null, null) as ApplicationProxyInternal;
        } 
 
        /// 
        /// Critical: 
        ///  1) Accesses _storageRoot, _container, _packageStream, _unmanagedStream
        ///
        /// TreatAsSafe:
        ///  1) Doesn't disclose _storageRoot, _container, _packageStream, 
        ///     _unmanagedStream
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal void Cleanup()
        { 
            if (Application.Current != null)
            {
                IBrowserCallbackServices bcs = Application.Current.BrowserCallbackServices;
                if (bcs != null) 
                {
                    Debug.Assert(!Application.IsApplicationObjectShuttingDown); 
                    // Marshal.ReleaseComObject(bcs) has to be called so that the refcount of the 
                    // native objects goes to zero for clean shutdown. But it should not be called
                    // right away, because there may still be DispatcherOperations in the queue 
                    // that will attempt to use IBCS, especially during downloading/activation.
                    // Last, it can't be called with prioroty lower than Normal, because that's
                    // the priority of Applicatoin.ShudownCallback(), which shuts down the
                    // Dispatcher. 
                    Application.Current.Dispatcher.BeginInvoke(
                        DispatcherPriority.Normal, new DispatcherOperationCallback(ReleaseBrowserCallback), bcs); 
                } 
            }
 
            ServiceProvider = null;
            ClearRootBrowserWindow();

            if (_storageRoot != null && _storageRoot.Value != null  ) 
            {
                _storageRoot.Value.Close(); 
            } 

            // Due to the dependecies the following objects have to be released 
            // in the following order: _document, DocumentManager,
            // _packageStream, _unmanagedStream.

            if (_document.Value is PackageDocument) 
            {
                // We are about to close the package ad remove it from the Preloaded Packages Store. 
                // Let's make sure that the data structures are consistent. The package that we hold is 
                // actually in the store under the URI that we think it should be using
                Debug.Assert(((PackageDocument)_document.Value).Package == 
                                    PreloadedPackages.GetPackage(PackUriHelper.GetPackageUri(PackUriHelper.Create(Uri))));

                // We need to remove the Package from the PreloadedPackage storage,
                // so that potential future requests would fail in a way of returning a null (resource not found) 
                // rather then return a Package or stream that is already Closed
                PreloadedPackages.RemovePackage(PackUriHelper.GetPackageUri(PackUriHelper.Create(Uri))); 
 
                ((PackageDocument)_document.Value).Dispose();
                _document.Value = null; 
            }

            if (_mimeType.Value == MimeType.Document)
            { 
                DocumentManager.CleanUp();
            } 
 
            if (_packageStream.Value != null)
            { 
                _packageStream.Value.Close();
            }

            if (_unmanagedStream.Value != null) 
            {
                Marshal.ReleaseComObject(_unmanagedStream.Value); 
                _unmanagedStream = new SecurityCriticalData(null); 
            }
        } 

        /// 
        /// Critical: Calls Marshal.ReleaseComObject(), which has a LinkDemand for unmanaged code.
        ///  
        [SecurityCritical]
        private object ReleaseBrowserCallback(object browserCallback) 
        { 
            Marshal.ReleaseComObject(browserCallback);
            return null; 
        }

        #endregion Internal Methods
 
        //------------------------------------------------------
        // 
        //  Internal Properties 
        //
        //------------------------------------------------------ 
        #region Internal Properties

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        internal RootBrowserWindowProxy RootBrowserWindowProxy 
        {
            get 
            { 
                if (_rbwProxy.Value == null)
                { 
                    CreateRootBrowserWindow();
                }
                return _rbwProxy.Value;
            } 
        }
 
        /// 
        /// Critical as the setter stores the critical RBW reference
        /// 
        internal RootBrowserWindow RootBrowserWindow
        {
            get
            { 
                return _rbw.Value;
            } 
            [SecurityCritical] 
            private set
            { 
                _rbw.Value = value;
                if (value == null)
                {
                    _rbwProxy.Value = null; 
                }
                else 
                { 
                    _rbwProxy.Value = new RootBrowserWindowProxy(value);
 
                    if (_rectset == true)
                    {
                        // If UIActivation already happened, set the size with
                        // cached values. 
                        Move(_windowRect);
                        _rectset = false; 
                    } 

                    //Incase Show() was called before we had a chance to create the window 
                    //If the old and new values are the same, this will be a no-op anyway
                    Show(_show);
                }
            } 
        }
 
        internal OleCmdHelper OleCmdHelper 
        {
            get 
            {
                if (Application.Current == null)
                {
                    return null; 
                }
 
                return (OleCmdHelper) Application.Current.Dispatcher.Invoke( 
                DispatcherPriority.Send,
                (DispatcherOperationCallback) delegate(object unused) 
                {
                    // V3.5: Check for Application object shutting down only.
                    // Consider to check for Browser shutting down.
                    if (Application.IsApplicationObjectShuttingDown == true) 
                        return null;
 
                    if (_oleCmdHelper == null) 
                    {
                        _oleCmdHelper = new OleCmdHelper(); 
                    }
                    return _oleCmdHelper;
                },
                null); 
            }
        } 
 
        /// 
        /// Critical: Returns a critical object, which can be used cross-AppDomain. 
        /// 
        internal static ApplicationProxyInternal Current
        {
            [SecurityCritical] 
            get { return _proxyInstance; }
        } 
 
        /// 
        /// Critical: 
        ///  - sets _criticalUri which is critical
        /// 
        internal Uri Uri
        { 
            get
            { 
                return _criticalUri.Value; 
            }
            [SecurityCritical] 
            private set
            {
                _criticalUri.Value = value;
                // We need to set these properties now, because there are times during the application's lifetime 
                // when the source URI would be useful, but the ApplicationProxyInternal has come and gone.
                SiteOfOriginContainer.BrowserSource = value; 
                BrowserInteropHelper.SetSource(value); 
            }
        } 

        /// 
        /// Critical:
        ///  - sets SiteOfOriginContainer.DebugSeurityZoneURL which is critical 
        /// 
        [SecurityCritical] 
        internal void SetDebugSecurityZoneURL(Uri debugSecurityZoneURL) 
        {
            SiteOfOriginContainer.DebugSecurityZoneURL = debugSecurityZoneURL; 
        }

        /// 
        ///     Critical - An external caller is setting the stream that we are using.  This is external 
        ///                data from the web.
        ///  
        internal object StreamContainer 
        {
            [SecurityCritical] 
            set
            {
                _unmanagedStream = new SecurityCriticalData(Marshal.GetObjectForIUnknown((IntPtr)value));
            } 
        }
 
        #endregion Internal Properties 

        //----------------------------------------------------- 
        //
        //  Private Methods
        //
        //------------------------------------------------------ 
        #region Private Methods
 
        private void OnStartup(Object sender, StartupEventArgs e) 
        {
            //We listen to the Startup event only for history loads in which 
            //case we want to do our journaling load instead of StartupUri load
            e.PerformDefaultAction = false;
            Application.Current.Startup -= new System.Windows.StartupEventHandler(this.OnStartup);
        } 

        ///  
        /// Will intialize the Package to be used by XpsViewer and register it with 
        /// PreloadedPackages.
        ///  
        /// 
        /// Critical:
        ///  1) asserts to create a CriticalFileToken  this is the first place we can
        ///     validate the file is a container and it is the one provided by 
        ///     the host (IE)
        ///  2) sets the _packageStream value 
        ///  3) sets the _document value 
        ///  4) calls DocumentManager.CreateDefaultDocument(Uri *...) which is
        ///     now critical as the Uri is used by IAttachment for security 
        ///     decisions
        ///  5) adds a document package to PreloadedPackages
        ///
        /// TreatAsSafe: 
        ///  1) the file for which we are asserting is SecurityCritical and
        ///     appropriately protected, the Uri we use is critical (trusted) 
        ///  1) it is also the intent of the user and the application to enable 
        ///     editing of the file if they have the necessary ACLs and IRM
        ///     licenses so Write privileges are okay 
        ///  1) the document type we are enabling opening is an XpsDocument
        ///     which is not executable and trusted for use in PartialTrust
        ///  2) _packageStream is set from data coming from critical for set
        ///     source (trusted) 
        ///  3) _document is set from data coming from critical for set source
        ///     (trusted) 
        ///  4) The source uri is critical and set by a trusted source (safe) 
        ///  5) The document package is from _document which was set by a trusted source
        ///         The package is type of ZipPackage instantiated by XPS Viewer. 
        ///         The package is not going to be handed out from this API surface
        ///         and as such will be protected
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private void InitContainer()
        { 
            // using a local so it can not change during method execution 
            Uri uri = Uri;
 
            PackageDocument doc;

            //---------------------------------------------------------------------------
            // Assign a temporary navigation delegate used for navigation in situations 
            // where the RM client isn't installed before the application has started.
            // This will be replaced by DocumentApplication once the application has initialized. 
            MS.Internal.Documents.Application.NavigationHelper.Navigate = StartupNavigateDelegate; 

            //--------------------------------------------------------------------------- 
            // Create PackageDocument from File (local or unc)
            if (uri.IsFile)
            {
                // create the CriticalFileToken 
                CriticalFileToken fileToken = null;
                string path = uri.LocalPath; 
                new FileIOPermission( 
                    FileIOPermissionAccess.Read
                    | FileIOPermissionAccess.Write, 
                    path).Assert();
                try
                {
                    fileToken = new CriticalFileToken(uri); 
                }
                finally 
                { 
                    FileIOPermission.RevertAssert();
                } 

                // create from file
                doc = DocumentManager.CreateDefaultDocument(uri, fileToken);
            } 
            //---------------------------------------------------------------------------
            // Create PackageDocument from Stream (likely internet) 
            else 
            {
                // currently we do not support writing back to non-file 
                // sources, so we are limiting stream to "Read"
                _packageStream = new SecurityCriticalData(
                    new ByteStream(_unmanagedStream.Value, FileAccess.Read));
 
                doc = DocumentManager.CreateDefaultDocument(uri, _packageStream.Value);
            } 
 
            //----------------------------------------------------------------------------
            // Open Package (may invoke WinForms UI) 
            try
            {
                if (!DocumentManager.CreateDefault().Open(doc))
                { 
                    throw new UnableToOpenDocumentException(
                        SR.Get(SRID.DocumentApplicationUnableToOpenDocument)); 
                } 
            }
            catch 
            {
                // on any failure, clean up the document before rethrowing
                if (doc != null)
                { 
                    doc.Dispose();
                    doc = null; 
                } 
                throw;
            } 

            if ((doc != null) && (doc.Package != null))
            {
                // after open document is valid 
                _document.Value = doc;
 
                // PreloadedPackages is a Package cache adding it prevents PackWebRequest 
                // from making multiple web requests for the same container; doing so
                // would break XpsViewer's PackageDocument model and reduce the 
                // effectiveness of ByteRangeDownloader
                PreloadedPackages.AddPackage(
                    PackUriHelper.GetPackageUri(PackUriHelper.Create(uri)), doc.Package);
            } 
        }
 
        /// 
        ///     Critical as this accesses critical data.
        ///     TreatAsSafe - as clearing the RBW is eliminating critical data - and considered safe. 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        private void ClearRootBrowserWindow()
        { 
            RootBrowserWindow = null;
        } 
 
        /// 
        /// StartupNavigateDelegate is invoked during XPSViewer startup in the cases where 
        /// a navigation needs to be performed before the Application has started.
        /// (This happens when the user needs to install the RM client in order to view an
        /// RM protected document - with user consent we will navigate to the RM install page.)
        ///  
        /// Critical:
        ///  1) Gets Uri which has path info we do not want to leak 
        ///  2) Invokes an unsafe navigation to the specified uri via UnsafeLaunchBrowser 
        /// 
        ///  
        /// 
        [SecurityCritical]
        private static void StartupNavigateDelegate(SecurityCriticalData uri)
        { 
            // Make an unsafe navigation to the RM Client install page.
            AppSecurityManager.UnsafeLaunchBrowser(uri.Value); 
        } 

        #endregion Private Methods 

        #region Private Properties

        private IServiceProvider ServiceProvider 
        {
            set 
            { 
                _serviceProvider = value;
 
                if (Application.Current != null)
                {
                    Application.Current.ServiceProvider = value;
                } 
            }
        } 
 
        #endregion
 
        //-----------------------------------------------------
        //
        //  Private Fields
        // 
        //------------------------------------------------------
        #region Private Fields 
 
        // Instance fields.
 
        // These are fields that moved from DocobjHost class so we can have a
        // unified way of calling for single vs multiple AppDomain scenarios.

        /// 
        /// Critical: We don't want an arbitrary window to be assigned here
        ///   (even though only the real RBW can be created in PT). 
        /// 
        private SecurityCriticalDataForSet   _rbw;
 
        ///
        /// Critical for the same reason that _rbw is.
        ///
        private SecurityCriticalDataForSet _rbwProxy; 

        private bool                _show; 
        private OleCmdHelper        _oleCmdHelper; 

        // The following variables are used to remember the window size until the window is created 
        // because the OLE SetRect/Show calls happen before the app and window are created internally
        Rect                        _windowRect;
        bool                        _rectset;
 
        private SecurityCriticalDataForSet _criticalUri;
        SecurityCriticalDataClass _storageRoot = new SecurityCriticalDataClass(null); 
        SecurityCriticalDataForSet _mimeType; 
        IServiceProvider _serviceProvider ;
 
        /// 
        /// Critical: ApplicationProxyInternal can be used cross-AppDomain and implements
        ///     critical functionality.
        ///  
        [SecurityCritical]
        private static ApplicationProxyInternal _proxyInstance; 
 
        private const string FRAGMENT_MARKER = "#";
 
        #region XpsViewer (DocumentApplication) Specific
        /// 
        /// This is an unmanaged COM IStream that is provided by the byte range downloader
        /// (progressive download) and comes from our unmanaged host. 
        /// 
        ///  
        /// Critical: 
        ///  1) this is a pointer to a security suppressed unmanaged stream, using it directly is
        ///     unsafe 
        ///  2) the data from this stream likely comes from the internet
        ///
        /// Not Safe:
        ///  1) although we did our best to protect from native exploits, no one is perfect and 
        ///     the backing code is unmanaged
        ///  
        SecurityCriticalData _unmanagedStream = new SecurityCriticalData(null); 

        ///  
        /// This is a ByteWrapper a managed class that is an adapter from IStream to Stream.
        /// The stream it wraps is the _unmanagedStream.
        /// 
        ///  
        /// Critical:
        ///  1) we do not want this replaced with another stream after we have made security 
        ///     decisions based on its contents (like mime type and start part) 
        ///  2) this may be an EncryptedPackage which contains PII (Personally Identifiable
        ///     Information) in clear text; as such we want to audit use so information is 
        ///     not leaked
        ///
        /// Not Safe:
        ///  1) we want to audit it is set once 
        ///  2) we want to audit for leaks
        ///  
        SecurityCriticalData _packageStream = new SecurityCriticalData(null); 

        ///  
        /// This contains many streams and packages that represent the current 'Package'
        /// for the XpsViewer.
        /// 
        ///  
        /// Critical:
        ///  1) none of this data can be effectively protected due to the visual tree 
        ///     and Package.GetStream model currently in place protecting leaking of this 
        ///     has been waived in a security review as it would have no net effect
        ///  2) based on the current hosting design we expect one 'Package' for the lifetime 
        ///     of the application, thus this should be audited such that it is set only once
        ///
        /// Not Safe:
        ///  2) we want to audit it is set once 
        /// 
        // The Document has been weakly-typed to avoid PresentationFramework 
        // having a type dependency on PresentationUI.  The perf impact of the weak 
        // typed variables in this case was determined to be much less than forcing the load
        // of a new assembly when Assembly.GetTypes was called on PresentationFramework. 
        SecurityCriticalDataForSet _document;
        #endregion

        #endregion Private Fields 

        #region Private Structs 
        ///  
        /// Holder for all things to be persisted in the BrowserJournal before we
        /// navigate away from the app 
        /// 
        [Serializable]
        private struct BrowserJournal
        { 
            #region Constructors
            internal BrowserJournal(Journal journal, Uri baseUri) 
            { 
                _journal = journal;
                _baseUri = baseUri; 
            }
            #endregion Constructors

            #region Properties 
            internal Journal Journal
            { 
                get { return _journal; } 
            }
 
            internal Uri BaseUri
            {
                get { return _baseUri; }
            } 
            #endregion Properties
 
            #region Private Fields 
            private Journal         _journal;
            private Uri             _baseUri; 
            #endregion Private Fields
        }
        #endregion Private Structs
 
        //------------------------------------------------------
        // 
        //  Private Classes 
        //
        //----------------------------------------------------- 
        #region Private Classes
        /// 
        /// Responsible for displaying a friendly message opposed to a callstack when we are
        /// unable to open the document. 
        /// 
        [Serializable] 
        private class UnableToOpenDocumentException : Exception 
        {
            internal UnableToOpenDocumentException(string message) : base(message) { } 

            /// 
            /// Required for serialization to marshal outside of our PT AppDomain.
            ///  
            internal UnableToOpenDocumentException(
                SerializationInfo info, StreamingContext context) : base(info, context) { } 
 
            /// 
            /// Overriding ToString as we do not want to expose the callstack for this exception 
            /// as we are re-using exception handling to in this case to display and error but
            /// not an application fault message to the user.
            /// 
            ///  
            public override string ToString()
            { 
                return this.Message; 
            }
        } 

        /// 
        /// CrossDomainSerializableException is a simple wrapper around an Exception object
        /// and is used only in ApplicationProxyInternal.Run() when instantiating 
        /// an XPS Document instance.
        /// 
        /// This class does not demand for SerializationFormatter permissions (as is 
        /// usually the case) in order to avoid a CLR bug (VSWhidbey 579013) wherein
        /// an exception marshalled across AppDomain boundaries will cause a 
        /// SecurityException due to an unmet demand for SerializationFormatter
        /// permissions.
        ///
        /// The CrossDomainSerializableException class is necessary because it is possible 
        /// for the initialization of the document to throw (due to invalid document
        /// content, for example) before we've switched over to running in the 
        /// Avalon Dispatcher -- an exception thrown at that point will not be handled 
        /// in our PT AppDomain, and will be marshaled, causing the SecurityException
        /// mentioned previously.  This is a bad support scenario, since any invalid 
        /// document (or related issue) will falsely appear to be a Security bug.  So
        /// this class wraps the actual exception thrown, and only exposes the output
        /// from that exception's ToString method for error reporting purposes.
        ///  
        [Serializable]
        private sealed class CrossDomainSerializableException : Exception 
        { 
            internal CrossDomainSerializableException(Exception e)
            { 
                // Save the output of the wrapped exception's ToString().
                // NOTE: It is important that e.ToString() is invoked
                // here (in Partial Trust) and not deferred to our
                // ToString() override or other methods that 
                // might be called outside of this AppDomain.
                // This avoids a potential security issue where a 
                // malicious Exception that overrides ToString() could 
                // run arbitrary code in full trust.
                _wrappedToString = e.ToString(); 
            }

            /// 
            /// Deserializes an instance of this Exception object. 
            /// This is required for marshalling across AppDomain boundaries.
            ///  
            internal CrossDomainSerializableException( 
                SerializationInfo info, StreamingContext context) : base(info, context)
            { 
                _wrappedToString = info.GetString("_wrappedToString");
            }

            ///  
            /// Provides serialization information for this Exception object.
            /// This is required for marshalling across AppDomain boundaries. 
            ///  
            /// Critical - Calls the base.GetObjectData method (which linkdemands).
            ///            We are not ourselves demanding in order to avoid 
            ///            SecurityExceptions when marshalling across
            ///            domain boundaries.  (See class comment for more info.)
            /// 
            ///  
            /// 
            ///  
            [SecurityCritical] 
            public override void GetObjectData(SerializationInfo info, StreamingContext context)
            { 
                if (info == null)
                {
                    throw new ArgumentNullException("info");
                } 

                base.GetObjectData(info, context); 
 
                // We are only serializing our _wrappedToString member.
                info.AddValue("_wrappedToString", _wrappedToString, typeof(String)); 
            }

            /// 
            /// Exposes the wrapped exception's ToString output. 
            /// 
            ///  
            public override string ToString() 
            {
                return _wrappedToString; 
            }

            private string _wrappedToString;
        } 

        #endregion Private Classes 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------ 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: This is an internal proxy wrapper class over Application class. 
//              This derives from MarshalByRefObject and thus facilitates calling 
//              the AppCode from DocobjHost that may be running in a different
//              AppDomain.  The other thing it allows is to be able to create 
//              the App Object on the right thread by exposing a delegate that
//              could be set to point to the code that creates the AppObject and
//              invoking the delegate from the right thread.
// 
// History:
//  07/03/2003 [....]  Created 
//  10/04/2005 FrankGor Documented & refactored class; primary reason was ensure 
//                      disposal of all XpsViewer (DocumentApplication)
//                      resources 
//-----------------------------------------------------------------------------

//**
//** IMPORTANT: Running arbitrary application code in the context of an incoming call from the browser 
//**    should be avoided. This could lead to unexpected reentrancy (on either side) or making the
//      browser frame unresponsive while the application code is running. Bug 1139336 illustrates 
//      what can happen if the application code enters a local message loop while the browser is 
//      blocked. To avoid such situations in general, use Dispatcher.BeginInvoke() instead of making
//      direct calls into unknown code. 


using System;
using System.Diagnostics; 
using System.IO;
using System.IO.Packaging; 
using System.Reflection; 
using System.Runtime.InteropServices;
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Permissions;
using System.Threading; 
using System.Windows;
using System.Windows.Controls; 
using System.Windows.Controls.Primitives; 
using System.Windows.Input;
using System.Windows.Interop; 
using System.Windows.Navigation;
using System.Windows.Threading;

using MS.Internal; 
using MS.Internal.Documents;
using MS.Internal.Documents.Application; 
using MS.Internal.IO.Packaging; 
using MS.Internal.IO.Packaging.CompoundFile;
using MS.Internal.PresentationFramework; 
using MS.Internal.Utility;
using MS.Internal.AppModel;
using MS.Utility;
 
//In order to avoid generating warnings about unknown message numbers and
//unknown pragmas when compiling your C# source code with the actual C# compiler, 
//you need to disable warnings 1634 and 1691. (Presharp Documentation) 
#pragma warning disable 1634, 1691
 
namespace MS.Internal.AppModel
{
    // All security sensitive classes should be sealed or protected with InheritanceDemand
    internal sealed class ApplicationProxyInternal : MarshalByRefObject 
    {
        [Serializable] 
        internal class InitData 
        {
            internal IServiceProvider ServiceProvider; 
            internal SecurityCriticalDataForSet MimeType;
            internal SecurityCriticalDataForSet ActivationUri;
            internal string Fragment;
            internal object UcomLoadIStream; 
            internal bool HandleHistoryLoad;
            internal string UserAgentString; 
            internal bool IsBrowserLowIntegrityProcess; 
            internal Rect WindowRect;
            internal bool ShowWindow; 
        };

        //-----------------------------------------------------
        // 
        //  Constructors
        // 
        //----------------------------------------------------- 
        #region Constructors
 
        /// 
        /// ApplicationProxyInternal is created only for browser-hosted applications.
        /// 
        ///  
        /// Critical:
        ///     1) We want to track creation of ApplicationProxyInternal because it can be used to 
        ///        make calls between AppDomains (it's MarshalByRefObject). 
        ///     2) It sets BrowserInteropHelper.IsBrowserHosted, which is critical for set.
        ///  
        [SecurityCritical]
        internal ApplicationProxyInternal()
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.AppProxyCtor); 
            } 

            if (_proxyInstance != null) 
            {
                throw new InvalidOperationException(SR.Get(SRID.MultiSingleton, this.GetType().FullName));
            }
            // Set this here so it will be true for documents or applications (i.e. anything in the browser.) 
            BrowserInteropHelper.SetBrowserHosted(true);
            _proxyInstance = this; 
        } 

        #endregion Constructors 

        //------------------------------------------------------
        //
        //  Internal Methods 
        //
        //----------------------------------------------------- 
        #region Internal Methods 

        public override object InitializeLifetimeService() 
        {
            //Keeps it alive until the AppDomain is teared down which is what we want.
            //Otherwise the .Net remoting infrastructure releases all remote objects in 5 mins
            //if there are no sponsors registered with the lease manager for the remote object. 
            //This is an alternative to the client side registering a sponsor by the server object
            //marking itself to be kept alive for the life of the AppDomain. 
            return null; 
        }
 
        //Creates the internal RootBrowserWindow. If the startup Uri points
        //to a Window/NavigationWindow, we still need to create this empty
        //RootBrowserWindow so we can repaint properly inside the browser window
 
        ///
        ///  Critical as this code invokes a delegate that accesses critical data. 
        ///  TreatAsSafe - creating the browser window for your content to be hosted in is considered safe. 
        ///                       this is considered safe - as you can only control the internal window of the browser.
        ///                       you cannot change styles of the actual browser window ( verified this). 
        ///                       Dangerous behaviors ( e.g. ShowInTaskbar = false) don't work when in browser hosted.
        ///
        ///
        [SecurityCritical, SecurityTreatAsSafe ] 
        internal void CreateRootBrowserWindow()
        { 
            if (_rbw.Value == null) 
            {
 
                Application.Current.Dispatcher.Invoke(
                                    DispatcherPriority.Send,
                                    new DispatcherOperationCallback(_CreateRootBrowserWindowCallback),
                                    null); 
            }
        } 
 
        internal bool FocusedElementWantsBackspace()
        { 
            TextBoxBase textBoxBase = Keyboard.FocusedElement as TextBoxBase;
            if (textBoxBase != null)
            {
                return true; // textBoxBase.IsEmpty 
            }
 
            PasswordBox passwordBox = Keyboard.FocusedElement as PasswordBox; 
            if (passwordBox != null)
            { 
                return true; // passwordBox.IsEmpty
            }

            return false; 
        }
 
        /// 
        ///  Critical as this code calls the critical RootBrowserWindow.CreateAndInitialize()
        /// 
        [SecurityCritical]
        private object _CreateRootBrowserWindowCallback(object unused)
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance)) 
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.RootBrowserWindowSetupStart); 
            } 

            RootBrowserWindow = RootBrowserWindow.CreateAndInitialize(); 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance))
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.RootBrowserWindowSetupEnd); 
            }
            return null ; 
        } 

        // Calls the Run method on the app object. 
        ///
        /// Critical - creates a critical delegate, provides the path to LoadFromContainer, which
        ///            is critical, and also calls InitContainer which is critical.  Accesses
        ///            several critical data values (_path, _container, _storageRoot). 
        ///          - also sets Uri and _mimeType, which are critical.
        /// 
        [SecurityCritical] 
        internal int Run(InitData initData)
        { 
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.AppProxyRunStart);
            } 

            MimeType mimeType = initData.MimeType.Value; 
            _mimeType.Value = mimeType; 
            Uri = initData.ActivationUri.Value;
            WpfWebRequestHelper.DefaultUserAgent = initData.UserAgentString; 
            BrowserInteropHelper.IsBrowserLowIntegrityProcess.Value = initData.IsBrowserLowIntegrityProcess;

            // These methods are asynchronous.
            // If the RootBrowserWindow is not created yet, only the size for it will be stored. 
            Move(initData.WindowRect);
            Show(initData.ShowWindow); 
 
            switch (mimeType)
            { 
                case MimeType.Markup:
                    // Make a dummy application (in lieu of the one provided by the defunct XamlViewer.xbap).
                    Invariant.Assert(AppDomain.CurrentDomain.FriendlyName == "XamlViewer");
                    Application app = new Application(); 
                    app.StartupUri = Uri;
                    // Any URL #fragment is appended to StartupUri in _RunDelegate(). 
                    // For history navigation, ApplicationProxyInternal has already started navigation to the 
                    // last journal entry captured. (This journal entry may include a #fragment target and/or
                    // a CustomContentState.) 
                    break;

                case MimeType.Application:
                    //This is a browser app, the application object has already been created 
                    break;
 
                case MimeType.Document: 
                    try
                    { 
                        InitContainer();
                        PackageDocument document = _document.Value as PackageDocument;
                        // This will fail to load if the document is not set to a valid PackageDocument.
                        if (document != null) 
                        {
                            ContainerActivationHelper.LoadFromContainer( 
                                Uri, 
#if CF_Envelope_Activation_Enabled
                                _storageRoot.Value, 
#endif
                                document.Package,
                                _serviceProvider);
 
                        }
                    } 
                    catch (Exception e) 
                    {
                        // If we catch an exception while initializing the document, we need 
                        // to wrap it in a CrossDomainSerializableException to avoid SecurityExceptions
                        // when the exception is serialized across AppDomains.
                        throw new CrossDomainSerializableException(e);
                    } 
                    break;
                case MimeType.Unknown: 
                default: 
                    throw new InvalidOperationException();
            } 

            // Set the Application.MimeType
            // Since loading containers causes the application to be constructed now,
            // the initial setting of the MimeType does not get passed to the application. 
            Application.Current.MimeType = mimeType;
            ServiceProvider = initData.ServiceProvider; // also sets Application.ServiceProvider 
 
            Application.Current.Dispatcher.Invoke(
                DispatcherPriority.Send, 
                new DispatcherOperationCallback(_RunDelegate),
                initData);

            int exitCode = Application.Current.RunInternal(null); 

            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.AppProxyRunEnd);
            } 

            return exitCode;
        }
 
        ///
        ///     Critical as this calls a critical function ( LoadHistoryStream). 
        /// 
        [SecurityCritical]
        private object _RunDelegate( object args ) 
        {
            InitData initData = (InitData)args;

            Application currentApp = Application.Current; 
            if (currentApp != null && !(currentApp is XappLauncherApp))
            { 
                string fragment = initData.Fragment; 
                if (!String.IsNullOrEmpty(fragment) && currentApp.StartupUri != null)
                { 
                    // Apply Fragment to Application StartupUri.
                    UriBuilder uriBuilder;
                    Uri absUri = currentApp.StartupUri;
 
                    if (currentApp.StartupUri.IsAbsoluteUri == false)
                    { 
                        absUri = new Uri(BindUriHelper.BaseUri, currentApp.StartupUri); 
                    }
 
                    uriBuilder = new UriBuilder(absUri);
                    if (fragment.StartsWith(FRAGMENT_MARKER, StringComparison.Ordinal))
                    {
                        fragment = fragment.Substring(FRAGMENT_MARKER.Length); 
                    }
                    uriBuilder.Fragment = fragment; 
                    currentApp.StartupUri = uriBuilder.Uri; 
                }
 
                CreateRootBrowserWindow();
            }

            //If we were started through IPersistHistory::Load, load from the history stream instead 
            //of navigating to the StartupPage
            if (initData.UcomLoadIStream != null && initData.HandleHistoryLoad) 
            { 
                LoadHistoryStream(DocObjHost.ExtractComStream(initData.UcomLoadIStream), /*firstHistoryLoad=s*/true);
            } 
            return null;
        }

        // Show or hide view. 
        internal void Show(bool show)
        { 
            _show = show; 
            if (Application.Current != null && RootBrowserWindow != null)
            { 
                Application.Current.Dispatcher.BeginInvoke(
                                    DispatcherPriority.Send,
                                    new DispatcherOperationCallback(_ShowDelegate),
                                    null); 
            }
 
        } 

        private object _ShowDelegate(object ignore) 
        {
            // The RBW might be torn down just before the DispatcherOperation is invoked.
            if (RootBrowserWindow == null || Application.IsShuttingDown)
                return null; 

            if (_show) 
            { 
                // The window is shown asynchronously (using Visibility, not Show()) to allow first restoring
                // the Journal on history navigation. This prevents bug 1367999. 
                _rbw.Value.Visibility = Visibility.Visible;

                // initial focus should be on us, not the browser frame
                // Focusing is done asynchronously because Visibility actually changes asynchronously. 
                Application.Current.Dispatcher.BeginInvoke(
                    // same priority as used in the Window.Visibility PropertyChangedCallback 
                    DispatcherPriority.Normal, 
                    new DispatcherOperationCallback(_FocusDelegate), null);
            } 
            else
            {
                _rbw.Value.Visibility = Visibility.Hidden;
            } 

            return null; 
        } 

        ///  
        /// Critical: Calls the critical UnsafeNativeMethods.SetFocus(), which returns a handle to
        ///     the previously focused window.
        /// Safe: The handle is not disclosed, and focusing the application's own window (RBW) is okay.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private object _FocusDelegate(object unused) 
        { 
            if (_rbw.Value != null)
            { 
                try
                {
                    MS.Win32.UnsafeNativeMethods.SetFocus(new HandleRef(_rbw.Value, _rbw.Value.CriticalHandle));
                } 
#pragma warning disable 6502
                // The browser may temporarily disable the RBW. Then SetFocus() fails. 
                // This is known to happen when the browser pops up the modal dialog about the Information Bar. 
                catch (System.ComponentModel.Win32Exception)
                { 
                    Debug.WriteLine("SetFocus() on RootBrowserWindow failed.");
                }
#pragma warning restore 6502
            } 
            return null;
        } 
 
        internal void Move(Rect windowRect)
        { 
            if (Application.Current != null && RootBrowserWindow != null)
            {
                Application.Current.Dispatcher.BeginInvoke(
                                    DispatcherPriority.Send, 
                                    new DispatcherOperationCallback(_MoveDelegate),
                                    windowRect); 
            } 
            else
            { 
                // We got UIActivated too early.  Remember the data passed in.
                _windowRect = windowRect;
                _rectset = true;
            } 
        }
 
        private object _MoveDelegate( object moveArgs ) 
        {
            // The RBW might be closed just before _MoveDelegate() is called. => check _rbw again. 
            if (_rbw.Value != null && !Application.IsShuttingDown)
            {
                Rect r = (Rect)moveArgs;
 
                // ResizeMove is implemented by RBW and should be called here
                // since it resizes and moves the WS_CHILD window.  Do not call 
                // Height/Width & Top/Left here since they govern the browser 
                // window properties.
                _rbw.Value.ResizeMove((int)r.X, (int)r.Y, (int)r.Width, (int)r.Height); 
            }
            return null;
        }
 
        // Shutdown the App.
        // Note: The "post" in the method name is legacy. Now all of Application's shutdown work is complete 
        // when this method returns. In particular, the managed Dispatcher is shut down. 
        ///
        ///  Critical: Calls Application.CriticalShutdown(). 
        ///
        [SecurityCritical]
        internal void PostShutdown()
        { 
            Cleanup();
            _proxyInstance = null; 
 
            Application app = Application.Current;
            if (app != null) 
            {
                XappLauncherApp launcherApp = app as XappLauncherApp;
                if (launcherApp != null)
                { 
                    launcherApp.AbortActivation();
                    Debug.Assert(Application.IsShuttingDown); 
                } 
                else
                { 
                    //this calls into the internal helper and is hardcoded for a clean
                    // shutdown
                    app.CriticalShutdown(0);
 
                    // The Application.Exit event is raised in a Dispatcher callback at Normal priority.
                    // Blocking on this callback here ensures that the event will be raised before we've 
                    // disconnected from the browser. An XBAP may want, in particular, to write a cookie. 
                    app.Dispatcher.Invoke(DispatcherPriority.Normal,
                        new DispatcherOperationCallback(delegate(object unused) { return null; }), null); 
                }
            }
        }
 
        //
        // Activate or Deactivate RootBrowserWindow 
        // 

        internal void Activate(bool fActivate) 
        {
            if (Application.Current != null && RootBrowserWindow != null)
            {
                Application.Current.Dispatcher.BeginInvoke( 
                                    DispatcherPriority.Send,
                                    new DispatcherOperationCallback(_ActivateDelegate), 
                                    fActivate); 
            }
        } 

        private object _ActivateDelegate(object arg )
        {
            if (RootBrowserWindow != null) 
            {
                bool fActivate = (bool)arg; 
 
                _rbw.Value.HandleActivate(fActivate);
                if (fActivate) 
                {
                    _FocusDelegate(null);
                }
            } 
            return null;
        } 
 
        internal bool CanInvokeJournalEntry(int entryId)
        { 
            if (Application.Current == null)
            {
                return false;
            } 

            return (bool)Application.Current.Dispatcher.Invoke( 
            DispatcherPriority.Send, 
                (DispatcherOperationCallback) delegate(object unused)
            { 
                NavigationWindow window = Application.Current.MainWindow as NavigationWindow;

                if (window == null)
                    return false; 

                return window.JournalNavigationScope.CanInvokeJournalEntry(entryId); 
            }, 
            null);
        } 

        // Private class just to facilitate passing of data back to GetSaveHistoryBytes.
        private class SaveHistoryReturnInfo
        { 
            internal string uri;
            internal string title; 
            internal int entryId; 
            internal byte[] saveByteArray ;
        } 

        ///  Called by the browser to serialize the entire journal or just the index of
        /// the current entry. The second case is when an internal Journal update needs to be
        /// reflected in the TravelLog. 
        /// 
        ///  true is the entire Journal is to serialized  
        /// 
        ///     Critical as this method accesses critical data.
        ///              and we elevate for serialization permission. 
        ///
        [SecurityCritical]
        private object _GetSaveHistoryBytesDelegate(object arg)
        { 
            bool entireJournal = (bool)arg;
 
            SaveHistoryReturnInfo info = new SaveHistoryReturnInfo(); 

            // When we are here, the browser has just started to shut down, so we should only check 
            // whether the application object is shutting down.
            if (Application.IsApplicationObjectShuttingDown == true)
                return null;
 
            Invariant.Assert(_rbw.Value != null, "BrowserJournalingError: _rbw should not be null");
 
            Journal journal = _rbw.Value.Journal; 
            Invariant.Assert(journal != null, "BrowserJournalingError: Could not get internal journal for the window");
 
            JournalEntry entry;
            if (entireJournal) // The application is about to be shut down...
            {
                NavigationService topNavSvc = _rbw.Value.NavigationService; 
                try
                { 
                    topNavSvc.RequestCustomContentStateOnAppShutdown(); 
                }
                catch(Exception e) 
                {
                    if(CriticalExceptions.IsCriticalException(e))
                    {
                        throw; 
                    }
                } 
 
                journal.PruneKeepAliveEntries();
 
                // Since the current page is not added to the journal until it is replaced,
                // we add it here explicitly to the internal Journal before serializing it.
                entry = topNavSvc.MakeJournalEntry(JournalReason.NewContentNavigation);
                if (entry != null && !entry.IsAlive()) 
                {
                    if (entry.JEGroupState.JournalDataStreams != null) 
                    { 
                        entry.JEGroupState.JournalDataStreams.PrepareForSerialization();
                    } 
                    journal.UpdateCurrentEntry(entry);
                }
                else // Maybe the current content is null or a PageFunction doesn't want to be journaled.
                {   // Then the previous navigable page, if any, should be remembered as current. 
                    entry = journal.GetGoBackEntry();
                    // i. _LoadHistoryStreamDelegate() has a similar special case. 
                } 
            }
            else 
            {   // (Brittle) Assumption: GetSaveHistoryBytes() is called after the current entry has
                // been updated in the internal journal but before the new navigation is committed.
                // This means journal.CurrentEntry is what was just added (or updated).
                // Note that it would be wrong to call topNavSvc.MakeJournalEntry() in this case because 
                // the navigation that just took place may be in a different NavigationService (in a
                // frame), and here we don't know which one it is. 
                entry = journal.CurrentEntry; 

                // The entry may be null here when the user has selected "New Window" or pressed Ctrl+N. 
                // In this case the browser calls us on IPersistHistory::Save and then throws that data
                // away.  Hopefully at some point in the future that saved data will be loaded in the new
                // window via IPersistHistory::Load.  This unusual behavior is tracked in bug 1353584.
            } 

            if (entry != null) 
            { 
                info.title = entry.Name;
                info.entryId = entry.Id; 
            }
            else
            {
                info.title = _rbw.Value.Title; 
            }
 
            // We only use the base URI here because the travel log will validate a file URI when making a PIDL. 
            // We use the URI stored in the JournalEntry, and the travel log doesn't care what the URI is, so
            // duplicates don't matter. 
            info.uri = BindUriHelper.UriToString(Uri);

            MemoryStream saveStream = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter(); 

            saveStream.Seek(0, SeekOrigin.Begin); 
            object objectToSave = info.entryId; 

            if (entireJournal) 
            {
                //Save the Journal and BaseUri also. We don't need BaseUri except for the xaml case
                //since this is set specially for the container case (ssres scheme). Exe case
                //will pretty much set it to the exe path. For the xaml case it is set to the path 
                //of the first uri(eg BaseDir\page1.xaml) that was navigated to.
                //BaseDir/Subdir/page2.xaml is also considered to be in the same extent and when 
                //we navigate back to the app from a webpage, the baseUri should still be BaseDir 
                //not BaseDir/Subdir. We were setting the BaseDir from JournalEntry.Uri but we may
                //end up setting BaseUri to BaseDir/Subdir which is not the same. So explicitly 
                //persist BaseUri as well
                BrowserJournal browserJournal = new BrowserJournal(journal, BindUriHelper.BaseUri);
                objectToSave = browserJournal;
            } 

            new SecurityPermission(SecurityPermissionFlag.SerializationFormatter).Assert(); 
            try 
            {
                formatter.Serialize(saveStream, objectToSave); 
            }
            catch(Exception e)
            {
                if(CriticalExceptions.IsCriticalException(e)) 
                {
                    throw; 
                } 

                // The application is shutting down and the exception would not be reported anyway. 
                // This is here to help with debugging and failure analysis.
                Invariant.Assert(false, "Failed to serialize the navigation journal: " + e);
            }
            finally 
            {
                CodeAccessPermission.RevertAll() ; 
            } 

            info.saveByteArray = saveStream.ToArray(); 
            ((IDisposable)saveStream).Dispose();

            return info ;
        } 

        //CASRemoval:[SecurityPermission(SecurityAction.Assert, SerializationFormatter = true)] 
 
        ///
        ///     Critical as the delegate that this method invokes accesses critical data. 
        ///
        [SecurityCritical]
        internal byte[] GetSaveHistoryBytes(bool persistEntireJournal, out int journalEntryId, out string uriString, out string titleString)
        { 
            SaveHistoryReturnInfo info = null ;
 
            if (Application.Current != null) 
            {
                info = ( SaveHistoryReturnInfo) Application.Current.Dispatcher.Invoke( 
                                DispatcherPriority.Send,
                                new DispatcherOperationCallback(_GetSaveHistoryBytesDelegate) ,
                                persistEntireJournal);
            } 

            if ( info != null ) 
            { 
                journalEntryId = info.entryId;
                uriString = info.uri; 
                titleString = info.title;
                return info.saveByteArray;
            }
            else 
            {
                journalEntryId = 0; 
                uriString = null; 
                titleString = null;
                return null; 
            }
        }

        /// 
        ///     Critical as the delegate that this method invokes accesses critical data.
        /// 
        [SecurityCritical] 
        internal void LoadHistoryStream(MemoryStream loadStream, bool firstLoadFromHistory)
        { 
            if (Application.Current == null)
            {
                return;
            } 

            LoadHistoryStreamInfo info = new LoadHistoryStreamInfo(); 
            info.loadStream = loadStream ; 
            info.firstLoadFromHistory = firstLoadFromHistory ;
 
            Application.Current.Dispatcher.Invoke(
                        DispatcherPriority.Send,
                        new DispatcherOperationCallback(_LoadHistoryStreamDelegate),
                        info); 
        }
 
        private class LoadHistoryStreamInfo 
        {
            internal MemoryStream loadStream ; 
            internal bool firstLoadFromHistory;
        }

        /// 
        ///     Critical as this method accesses critical data.
        /// 
        [SecurityCritical] 
        private object _LoadHistoryStreamDelegate( object arg )
        { 
            Journal             journal     = null;
            JournalEntry        entry       = null;

            LoadHistoryStreamInfo info = (LoadHistoryStreamInfo) arg ; 

            if (IsShutdown() == true) 
                return null; 

            // Reset the memory stream pointer back to the begining and get the persisted object 
            info.loadStream.Seek(0, System.IO.SeekOrigin.Begin);

            object journaledObject = DeserializeJournaledObject(info.loadStream);
 
            //This is the very first load from history, so need to set the BaseUri and StartupUri.
            if (info.firstLoadFromHistory) 
            { 
                // Patch for WOSB 1834243: The journal does not get saved on Ctrl+N. Because of this,
                // here we can get just an index, like in the 'else' case below. 
                if(!(journaledObject is BrowserJournal))
                    return null;

                BrowserJournal browserJournal = (BrowserJournal)journaledObject; 

                journal = browserJournal.Journal; 
                entry = journal.CurrentEntry; 
                if (entry == null) // See special case in _GetSaveHistoryBytesDelegate().
                { 
                    entry = journal.GetGoBackEntry(); // could still be null
                }

                //This will create the frame to use for hosting 
                {
                    NavigationService navigationService = null; 
                    navigationService = _rbw.Value.NavigationService; 
                }
                _rbw.Value.SetJournalForBrowserInterop(journal); 

                //This should already be set for the container and exe cases. The former
                //sets it to the transformed ssres scheme and we don't want to overwrite it.
                if (BindUriHelper.BaseUri == null) 
                {
                    BindUriHelper.BaseUri = browserJournal.BaseUri; 
                } 

                // 



 
                Debug.Assert(Application.Current != null, "BrowserJournalingError: Application object should already be created");
 
                if (entry != null) 
                {
                    //Prevent navigations to StartupUri for history loads by canceling the StartingUp event 
                    Application.Current.Startup += new System.Windows.StartupEventHandler(this.OnStartup);

                    _rbw.Value.JournalNavigationScope.NavigateToEntry(entry);
                } 
                //else: fall back on navigating to StartupUri
            } 
            else 
            {
                journal = _rbw.Value.Journal; 

                int index = journal.FindIndexForEntryWithId((int)journaledObject);

                Debug.Assert(journal[index].Id == (int)journaledObject, "BrowserJournalingError: Index retrieved from journal stream does not match index of journal entry"); 

                // Check whether the navigation is canceled. 
                if (! _rbw.Value.JournalNavigationScope.NavigateToEntry(index)) 
                {
                    // When the navigation is canceled, we want to notify browser to prevent the internal journal from 
                    // getting out of [....] with the browser's.
                    // The exception will be caught by the interop layer and browser will cancel the navigation as a result.

                    // If the navigation is initiated pragmatically by calling GoBack/Forward (comparing to user initiated 
                    // by clicking the back/forward button),  this will result in a managed exception at the call to ibcs.GoBack()
                    // in rbw.GoBackOverride(). rbw catches the exception when this happens. 
 
                    throw new OperationCanceledException();
                } 
            }

            return null;
        } 

        ///  
        /// Critical - Asserts for Serialization permission to deserialize an object from the input stream. 
        /// 
        [SecurityCritical] 
        private object DeserializeJournaledObject(MemoryStream inputStream)
        {
            object deserialized = null;
            BinaryFormatter formatter = new BinaryFormatter(); 
            new System.Security.Permissions.SecurityPermission(SecurityPermissionFlag.SerializationFormatter).Assert();
            try 
            { 
                deserialized = formatter.Deserialize(inputStream);
            } 
            finally
            {
                CodeAccessPermission.RevertAssert();
            } 
            return deserialized;
        } 
 
        // See if an App instance is currently loaded.
        internal bool IsAppLoaded() 
        {
            return (Application.Current == null ? false : true);
        }
 
        // Return the internal static variable _shutdown.
        internal bool IsShutdown() 
        { 
            return Application.IsShuttingDown;
        } 

        /// 
        /// Critical: Calls a critical ctor (ApplicationProxyInternal)
        ///  
        [SecurityCritical]
        internal static ApplicationProxyInternal CreateInDomain(AppDomain appDomain) 
        { 
            // Create an ApplicationProxyInternal in the new domain.
            return appDomain.CreateInstanceAndUnwrap( 
                                        Assembly.GetAssembly(typeof(ApplicationProxyInternal)).FullName,
                                        typeof(ApplicationProxyInternal).FullName,
                                        false,
                                        BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, 
                                        null, null, null, null, null) as ApplicationProxyInternal;
        } 
 
        /// 
        /// Critical: 
        ///  1) Accesses _storageRoot, _container, _packageStream, _unmanagedStream
        ///
        /// TreatAsSafe:
        ///  1) Doesn't disclose _storageRoot, _container, _packageStream, 
        ///     _unmanagedStream
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal void Cleanup()
        { 
            if (Application.Current != null)
            {
                IBrowserCallbackServices bcs = Application.Current.BrowserCallbackServices;
                if (bcs != null) 
                {
                    Debug.Assert(!Application.IsApplicationObjectShuttingDown); 
                    // Marshal.ReleaseComObject(bcs) has to be called so that the refcount of the 
                    // native objects goes to zero for clean shutdown. But it should not be called
                    // right away, because there may still be DispatcherOperations in the queue 
                    // that will attempt to use IBCS, especially during downloading/activation.
                    // Last, it can't be called with prioroty lower than Normal, because that's
                    // the priority of Applicatoin.ShudownCallback(), which shuts down the
                    // Dispatcher. 
                    Application.Current.Dispatcher.BeginInvoke(
                        DispatcherPriority.Normal, new DispatcherOperationCallback(ReleaseBrowserCallback), bcs); 
                } 
            }
 
            ServiceProvider = null;
            ClearRootBrowserWindow();

            if (_storageRoot != null && _storageRoot.Value != null  ) 
            {
                _storageRoot.Value.Close(); 
            } 

            // Due to the dependecies the following objects have to be released 
            // in the following order: _document, DocumentManager,
            // _packageStream, _unmanagedStream.

            if (_document.Value is PackageDocument) 
            {
                // We are about to close the package ad remove it from the Preloaded Packages Store. 
                // Let's make sure that the data structures are consistent. The package that we hold is 
                // actually in the store under the URI that we think it should be using
                Debug.Assert(((PackageDocument)_document.Value).Package == 
                                    PreloadedPackages.GetPackage(PackUriHelper.GetPackageUri(PackUriHelper.Create(Uri))));

                // We need to remove the Package from the PreloadedPackage storage,
                // so that potential future requests would fail in a way of returning a null (resource not found) 
                // rather then return a Package or stream that is already Closed
                PreloadedPackages.RemovePackage(PackUriHelper.GetPackageUri(PackUriHelper.Create(Uri))); 
 
                ((PackageDocument)_document.Value).Dispose();
                _document.Value = null; 
            }

            if (_mimeType.Value == MimeType.Document)
            { 
                DocumentManager.CleanUp();
            } 
 
            if (_packageStream.Value != null)
            { 
                _packageStream.Value.Close();
            }

            if (_unmanagedStream.Value != null) 
            {
                Marshal.ReleaseComObject(_unmanagedStream.Value); 
                _unmanagedStream = new SecurityCriticalData(null); 
            }
        } 

        /// 
        /// Critical: Calls Marshal.ReleaseComObject(), which has a LinkDemand for unmanaged code.
        ///  
        [SecurityCritical]
        private object ReleaseBrowserCallback(object browserCallback) 
        { 
            Marshal.ReleaseComObject(browserCallback);
            return null; 
        }

        #endregion Internal Methods
 
        //------------------------------------------------------
        // 
        //  Internal Properties 
        //
        //------------------------------------------------------ 
        #region Internal Properties

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        internal RootBrowserWindowProxy RootBrowserWindowProxy 
        {
            get 
            { 
                if (_rbwProxy.Value == null)
                { 
                    CreateRootBrowserWindow();
                }
                return _rbwProxy.Value;
            } 
        }
 
        /// 
        /// Critical as the setter stores the critical RBW reference
        /// 
        internal RootBrowserWindow RootBrowserWindow
        {
            get
            { 
                return _rbw.Value;
            } 
            [SecurityCritical] 
            private set
            { 
                _rbw.Value = value;
                if (value == null)
                {
                    _rbwProxy.Value = null; 
                }
                else 
                { 
                    _rbwProxy.Value = new RootBrowserWindowProxy(value);
 
                    if (_rectset == true)
                    {
                        // If UIActivation already happened, set the size with
                        // cached values. 
                        Move(_windowRect);
                        _rectset = false; 
                    } 

                    //Incase Show() was called before we had a chance to create the window 
                    //If the old and new values are the same, this will be a no-op anyway
                    Show(_show);
                }
            } 
        }
 
        internal OleCmdHelper OleCmdHelper 
        {
            get 
            {
                if (Application.Current == null)
                {
                    return null; 
                }
 
                return (OleCmdHelper) Application.Current.Dispatcher.Invoke( 
                DispatcherPriority.Send,
                (DispatcherOperationCallback) delegate(object unused) 
                {
                    // V3.5: Check for Application object shutting down only.
                    // Consider to check for Browser shutting down.
                    if (Application.IsApplicationObjectShuttingDown == true) 
                        return null;
 
                    if (_oleCmdHelper == null) 
                    {
                        _oleCmdHelper = new OleCmdHelper(); 
                    }
                    return _oleCmdHelper;
                },
                null); 
            }
        } 
 
        /// 
        /// Critical: Returns a critical object, which can be used cross-AppDomain. 
        /// 
        internal static ApplicationProxyInternal Current
        {
            [SecurityCritical] 
            get { return _proxyInstance; }
        } 
 
        /// 
        /// Critical: 
        ///  - sets _criticalUri which is critical
        /// 
        internal Uri Uri
        { 
            get
            { 
                return _criticalUri.Value; 
            }
            [SecurityCritical] 
            private set
            {
                _criticalUri.Value = value;
                // We need to set these properties now, because there are times during the application's lifetime 
                // when the source URI would be useful, but the ApplicationProxyInternal has come and gone.
                SiteOfOriginContainer.BrowserSource = value; 
                BrowserInteropHelper.SetSource(value); 
            }
        } 

        /// 
        /// Critical:
        ///  - sets SiteOfOriginContainer.DebugSeurityZoneURL which is critical 
        /// 
        [SecurityCritical] 
        internal void SetDebugSecurityZoneURL(Uri debugSecurityZoneURL) 
        {
            SiteOfOriginContainer.DebugSecurityZoneURL = debugSecurityZoneURL; 
        }

        /// 
        ///     Critical - An external caller is setting the stream that we are using.  This is external 
        ///                data from the web.
        ///  
        internal object StreamContainer 
        {
            [SecurityCritical] 
            set
            {
                _unmanagedStream = new SecurityCriticalData(Marshal.GetObjectForIUnknown((IntPtr)value));
            } 
        }
 
        #endregion Internal Properties 

        //----------------------------------------------------- 
        //
        //  Private Methods
        //
        //------------------------------------------------------ 
        #region Private Methods
 
        private void OnStartup(Object sender, StartupEventArgs e) 
        {
            //We listen to the Startup event only for history loads in which 
            //case we want to do our journaling load instead of StartupUri load
            e.PerformDefaultAction = false;
            Application.Current.Startup -= new System.Windows.StartupEventHandler(this.OnStartup);
        } 

        ///  
        /// Will intialize the Package to be used by XpsViewer and register it with 
        /// PreloadedPackages.
        ///  
        /// 
        /// Critical:
        ///  1) asserts to create a CriticalFileToken  this is the first place we can
        ///     validate the file is a container and it is the one provided by 
        ///     the host (IE)
        ///  2) sets the _packageStream value 
        ///  3) sets the _document value 
        ///  4) calls DocumentManager.CreateDefaultDocument(Uri *...) which is
        ///     now critical as the Uri is used by IAttachment for security 
        ///     decisions
        ///  5) adds a document package to PreloadedPackages
        ///
        /// TreatAsSafe: 
        ///  1) the file for which we are asserting is SecurityCritical and
        ///     appropriately protected, the Uri we use is critical (trusted) 
        ///  1) it is also the intent of the user and the application to enable 
        ///     editing of the file if they have the necessary ACLs and IRM
        ///     licenses so Write privileges are okay 
        ///  1) the document type we are enabling opening is an XpsDocument
        ///     which is not executable and trusted for use in PartialTrust
        ///  2) _packageStream is set from data coming from critical for set
        ///     source (trusted) 
        ///  3) _document is set from data coming from critical for set source
        ///     (trusted) 
        ///  4) The source uri is critical and set by a trusted source (safe) 
        ///  5) The document package is from _document which was set by a trusted source
        ///         The package is type of ZipPackage instantiated by XPS Viewer. 
        ///         The package is not going to be handed out from this API surface
        ///         and as such will be protected
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private void InitContainer()
        { 
            // using a local so it can not change during method execution 
            Uri uri = Uri;
 
            PackageDocument doc;

            //---------------------------------------------------------------------------
            // Assign a temporary navigation delegate used for navigation in situations 
            // where the RM client isn't installed before the application has started.
            // This will be replaced by DocumentApplication once the application has initialized. 
            MS.Internal.Documents.Application.NavigationHelper.Navigate = StartupNavigateDelegate; 

            //--------------------------------------------------------------------------- 
            // Create PackageDocument from File (local or unc)
            if (uri.IsFile)
            {
                // create the CriticalFileToken 
                CriticalFileToken fileToken = null;
                string path = uri.LocalPath; 
                new FileIOPermission( 
                    FileIOPermissionAccess.Read
                    | FileIOPermissionAccess.Write, 
                    path).Assert();
                try
                {
                    fileToken = new CriticalFileToken(uri); 
                }
                finally 
                { 
                    FileIOPermission.RevertAssert();
                } 

                // create from file
                doc = DocumentManager.CreateDefaultDocument(uri, fileToken);
            } 
            //---------------------------------------------------------------------------
            // Create PackageDocument from Stream (likely internet) 
            else 
            {
                // currently we do not support writing back to non-file 
                // sources, so we are limiting stream to "Read"
                _packageStream = new SecurityCriticalData(
                    new ByteStream(_unmanagedStream.Value, FileAccess.Read));
 
                doc = DocumentManager.CreateDefaultDocument(uri, _packageStream.Value);
            } 
 
            //----------------------------------------------------------------------------
            // Open Package (may invoke WinForms UI) 
            try
            {
                if (!DocumentManager.CreateDefault().Open(doc))
                { 
                    throw new UnableToOpenDocumentException(
                        SR.Get(SRID.DocumentApplicationUnableToOpenDocument)); 
                } 
            }
            catch 
            {
                // on any failure, clean up the document before rethrowing
                if (doc != null)
                { 
                    doc.Dispose();
                    doc = null; 
                } 
                throw;
            } 

            if ((doc != null) && (doc.Package != null))
            {
                // after open document is valid 
                _document.Value = doc;
 
                // PreloadedPackages is a Package cache adding it prevents PackWebRequest 
                // from making multiple web requests for the same container; doing so
                // would break XpsViewer's PackageDocument model and reduce the 
                // effectiveness of ByteRangeDownloader
                PreloadedPackages.AddPackage(
                    PackUriHelper.GetPackageUri(PackUriHelper.Create(uri)), doc.Package);
            } 
        }
 
        /// 
        ///     Critical as this accesses critical data.
        ///     TreatAsSafe - as clearing the RBW is eliminating critical data - and considered safe. 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        private void ClearRootBrowserWindow()
        { 
            RootBrowserWindow = null;
        } 
 
        /// 
        /// StartupNavigateDelegate is invoked during XPSViewer startup in the cases where 
        /// a navigation needs to be performed before the Application has started.
        /// (This happens when the user needs to install the RM client in order to view an
        /// RM protected document - with user consent we will navigate to the RM install page.)
        ///  
        /// Critical:
        ///  1) Gets Uri which has path info we do not want to leak 
        ///  2) Invokes an unsafe navigation to the specified uri via UnsafeLaunchBrowser 
        /// 
        ///  
        /// 
        [SecurityCritical]
        private static void StartupNavigateDelegate(SecurityCriticalData uri)
        { 
            // Make an unsafe navigation to the RM Client install page.
            AppSecurityManager.UnsafeLaunchBrowser(uri.Value); 
        } 

        #endregion Private Methods 

        #region Private Properties

        private IServiceProvider ServiceProvider 
        {
            set 
            { 
                _serviceProvider = value;
 
                if (Application.Current != null)
                {
                    Application.Current.ServiceProvider = value;
                } 
            }
        } 
 
        #endregion
 
        //-----------------------------------------------------
        //
        //  Private Fields
        // 
        //------------------------------------------------------
        #region Private Fields 
 
        // Instance fields.
 
        // These are fields that moved from DocobjHost class so we can have a
        // unified way of calling for single vs multiple AppDomain scenarios.

        /// 
        /// Critical: We don't want an arbitrary window to be assigned here
        ///   (even though only the real RBW can be created in PT). 
        /// 
        private SecurityCriticalDataForSet   _rbw;
 
        ///
        /// Critical for the same reason that _rbw is.
        ///
        private SecurityCriticalDataForSet _rbwProxy; 

        private bool                _show; 
        private OleCmdHelper        _oleCmdHelper; 

        // The following variables are used to remember the window size until the window is created 
        // because the OLE SetRect/Show calls happen before the app and window are created internally
        Rect                        _windowRect;
        bool                        _rectset;
 
        private SecurityCriticalDataForSet _criticalUri;
        SecurityCriticalDataClass _storageRoot = new SecurityCriticalDataClass(null); 
        SecurityCriticalDataForSet _mimeType; 
        IServiceProvider _serviceProvider ;
 
        /// 
        /// Critical: ApplicationProxyInternal can be used cross-AppDomain and implements
        ///     critical functionality.
        ///  
        [SecurityCritical]
        private static ApplicationProxyInternal _proxyInstance; 
 
        private const string FRAGMENT_MARKER = "#";
 
        #region XpsViewer (DocumentApplication) Specific
        /// 
        /// This is an unmanaged COM IStream that is provided by the byte range downloader
        /// (progressive download) and comes from our unmanaged host. 
        /// 
        ///  
        /// Critical: 
        ///  1) this is a pointer to a security suppressed unmanaged stream, using it directly is
        ///     unsafe 
        ///  2) the data from this stream likely comes from the internet
        ///
        /// Not Safe:
        ///  1) although we did our best to protect from native exploits, no one is perfect and 
        ///     the backing code is unmanaged
        ///  
        SecurityCriticalData _unmanagedStream = new SecurityCriticalData(null); 

        ///  
        /// This is a ByteWrapper a managed class that is an adapter from IStream to Stream.
        /// The stream it wraps is the _unmanagedStream.
        /// 
        ///  
        /// Critical:
        ///  1) we do not want this replaced with another stream after we have made security 
        ///     decisions based on its contents (like mime type and start part) 
        ///  2) this may be an EncryptedPackage which contains PII (Personally Identifiable
        ///     Information) in clear text; as such we want to audit use so information is 
        ///     not leaked
        ///
        /// Not Safe:
        ///  1) we want to audit it is set once 
        ///  2) we want to audit for leaks
        ///  
        SecurityCriticalData _packageStream = new SecurityCriticalData(null); 

        ///  
        /// This contains many streams and packages that represent the current 'Package'
        /// for the XpsViewer.
        /// 
        ///  
        /// Critical:
        ///  1) none of this data can be effectively protected due to the visual tree 
        ///     and Package.GetStream model currently in place protecting leaking of this 
        ///     has been waived in a security review as it would have no net effect
        ///  2) based on the current hosting design we expect one 'Package' for the lifetime 
        ///     of the application, thus this should be audited such that it is set only once
        ///
        /// Not Safe:
        ///  2) we want to audit it is set once 
        /// 
        // The Document has been weakly-typed to avoid PresentationFramework 
        // having a type dependency on PresentationUI.  The perf impact of the weak 
        // typed variables in this case was determined to be much less than forcing the load
        // of a new assembly when Assembly.GetTypes was called on PresentationFramework. 
        SecurityCriticalDataForSet _document;
        #endregion

        #endregion Private Fields 

        #region Private Structs 
        ///  
        /// Holder for all things to be persisted in the BrowserJournal before we
        /// navigate away from the app 
        /// 
        [Serializable]
        private struct BrowserJournal
        { 
            #region Constructors
            internal BrowserJournal(Journal journal, Uri baseUri) 
            { 
                _journal = journal;
                _baseUri = baseUri; 
            }
            #endregion Constructors

            #region Properties 
            internal Journal Journal
            { 
                get { return _journal; } 
            }
 
            internal Uri BaseUri
            {
                get { return _baseUri; }
            } 
            #endregion Properties
 
            #region Private Fields 
            private Journal         _journal;
            private Uri             _baseUri; 
            #endregion Private Fields
        }
        #endregion Private Structs
 
        //------------------------------------------------------
        // 
        //  Private Classes 
        //
        //----------------------------------------------------- 
        #region Private Classes
        /// 
        /// Responsible for displaying a friendly message opposed to a callstack when we are
        /// unable to open the document. 
        /// 
        [Serializable] 
        private class UnableToOpenDocumentException : Exception 
        {
            internal UnableToOpenDocumentException(string message) : base(message) { } 

            /// 
            /// Required for serialization to marshal outside of our PT AppDomain.
            ///  
            internal UnableToOpenDocumentException(
                SerializationInfo info, StreamingContext context) : base(info, context) { } 
 
            /// 
            /// Overriding ToString as we do not want to expose the callstack for this exception 
            /// as we are re-using exception handling to in this case to display and error but
            /// not an application fault message to the user.
            /// 
            ///  
            public override string ToString()
            { 
                return this.Message; 
            }
        } 

        /// 
        /// CrossDomainSerializableException is a simple wrapper around an Exception object
        /// and is used only in ApplicationProxyInternal.Run() when instantiating 
        /// an XPS Document instance.
        /// 
        /// This class does not demand for SerializationFormatter permissions (as is 
        /// usually the case) in order to avoid a CLR bug (VSWhidbey 579013) wherein
        /// an exception marshalled across AppDomain boundaries will cause a 
        /// SecurityException due to an unmet demand for SerializationFormatter
        /// permissions.
        ///
        /// The CrossDomainSerializableException class is necessary because it is possible 
        /// for the initialization of the document to throw (due to invalid document
        /// content, for example) before we've switched over to running in the 
        /// Avalon Dispatcher -- an exception thrown at that point will not be handled 
        /// in our PT AppDomain, and will be marshaled, causing the SecurityException
        /// mentioned previously.  This is a bad support scenario, since any invalid 
        /// document (or related issue) will falsely appear to be a Security bug.  So
        /// this class wraps the actual exception thrown, and only exposes the output
        /// from that exception's ToString method for error reporting purposes.
        ///  
        [Serializable]
        private sealed class CrossDomainSerializableException : Exception 
        { 
            internal CrossDomainSerializableException(Exception e)
            { 
                // Save the output of the wrapped exception's ToString().
                // NOTE: It is important that e.ToString() is invoked
                // here (in Partial Trust) and not deferred to our
                // ToString() override or other methods that 
                // might be called outside of this AppDomain.
                // This avoids a potential security issue where a 
                // malicious Exception that overrides ToString() could 
                // run arbitrary code in full trust.
                _wrappedToString = e.ToString(); 
            }

            /// 
            /// Deserializes an instance of this Exception object. 
            /// This is required for marshalling across AppDomain boundaries.
            ///  
            internal CrossDomainSerializableException( 
                SerializationInfo info, StreamingContext context) : base(info, context)
            { 
                _wrappedToString = info.GetString("_wrappedToString");
            }

            ///  
            /// Provides serialization information for this Exception object.
            /// This is required for marshalling across AppDomain boundaries. 
            ///  
            /// Critical - Calls the base.GetObjectData method (which linkdemands).
            ///            We are not ourselves demanding in order to avoid 
            ///            SecurityExceptions when marshalling across
            ///            domain boundaries.  (See class comment for more info.)
            /// 
            ///  
            /// 
            ///  
            [SecurityCritical] 
            public override void GetObjectData(SerializationInfo info, StreamingContext context)
            { 
                if (info == null)
                {
                    throw new ArgumentNullException("info");
                } 

                base.GetObjectData(info, context); 
 
                // We are only serializing our _wrappedToString member.
                info.AddValue("_wrappedToString", _wrappedToString, typeof(String)); 
            }

            /// 
            /// Exposes the wrapped exception's ToString output. 
            /// 
            ///  
            public override string ToString() 
            {
                return _wrappedToString; 
            }

            private string _wrappedToString;
        } 

        #endregion Private Classes 
    } 
}

// 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