Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / AppModel / ApplicationProxyInternal.cs / 1305600 / 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 IHostBrowser HostBrowser; internal SecurityCriticalDataForSetMimeType; internal SecurityCriticalDataForSet ActivationUri; internal string Fragment; internal object UcomLoadIStream; internal bool HandleHistoryLoad; internal string UserAgentString; internal HostingFlags HostingFlags; 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() { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordHosting | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Verbose, EventTrace.Event.WpfHost_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) { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordHosting | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WpfHost_RootBrowserWindowSetupStart); RootBrowserWindow = RootBrowserWindow.CreateAndInitialize(); EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordHosting | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WpfHost_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) { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordHosting | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Verbose, EventTrace.Event.WpfHost_AppProxyRunStart); // Keep in mind that Run() is called once in the default AppDomain and then in the XBAP's domain. // We want initialization of statics to happen in both AppDomains. if (!AppDomain.CurrentDomain.IsDefaultAppDomain()) { // Since IHostBrowser was marshaled from the default AppDomain as a managed interface, we get // a Remoting transparent proxy here. Any calls on the interface would have to first be marshaled // to the default AppDomain, where the CLR will realize it's actually a COM interface. This is // wasteful since the object lives in the browser process. So, to shake off the Remoting layer, // we round-trip the IHostBrowser reference through IUknown/IntPtr. IntPtr pObj = Marshal.GetIUnknownForObject(initData.HostBrowser); try { initData.HostBrowser = (IHostBrowser)Marshal.GetObjectForIUnknown(pObj); } finally { Marshal.Release(pObj); } } BrowserInteropHelper.HostBrowser = initData.HostBrowser; MimeType mimeType = initData.MimeType.Value; _mimeType.Value = mimeType; Uri = initData.ActivationUri.Value; WpfWebRequestHelper.DefaultUserAgent = initData.UserAgentString; BrowserInteropHelper.HostingFlags = initData.HostingFlags; // 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: throw new NotImplementedException(); // removed in v4 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); EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordHosting | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Verbose, EventTrace.Event.WpfHost_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: /// 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
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- NativeMethods.cs
- AutoCompleteStringCollection.cs
- ControlBuilder.cs
- ConnectionStringsExpressionBuilder.cs
- HelpFileFileNameEditor.cs
- HitTestParameters3D.cs
- AttachedAnnotation.cs
- RemoteArgument.cs
- CheckBoxList.cs
- InvalidAsynchronousStateException.cs
- DecimalConverter.cs
- webbrowsersite.cs
- PeerToPeerException.cs
- BitmapImage.cs
- ThrowHelper.cs
- BufferedGraphicsContext.cs
- SafeNativeMethods.cs
- DesignerTransactionCloseEvent.cs
- Range.cs
- SessionStateSection.cs
- Processor.cs
- Evidence.cs
- RemoteWebConfigurationHostServer.cs
- DragEvent.cs
- BitmapEffectOutputConnector.cs
- RecipientInfo.cs
- SubqueryTrackingVisitor.cs
- ParameterCollection.cs
- EdgeProfileValidation.cs
- SamlConditions.cs
- StringFunctions.cs
- SQLInt64Storage.cs
- SortQuery.cs
- DataPagerFieldCommandEventArgs.cs
- UndoManager.cs
- ExceptionHandler.cs
- TranslateTransform3D.cs
- TextTreeText.cs
- ConfigXmlComment.cs
- FormViewAutoFormat.cs
- Animatable.cs
- RepeatBehavior.cs
- InputProcessorProfilesLoader.cs
- CheckedListBox.cs
- HttpCacheParams.cs
- ToolStripRendererSwitcher.cs
- DoubleAnimationUsingKeyFrames.cs
- TypeConverter.cs
- DataServices.cs
- XmlEntity.cs
- BindingMAnagerBase.cs
- MailAddress.cs
- ListControl.cs
- ReflectionHelper.cs
- ValueCollectionParameterReader.cs
- StatusBarDrawItemEvent.cs
- ModulesEntry.cs
- CompoundFileStreamReference.cs
- RoleServiceManager.cs
- ModelItemDictionaryImpl.cs
- EventWaitHandleSecurity.cs
- Preprocessor.cs
- GridViewUpdateEventArgs.cs
- NameValueConfigurationElement.cs
- entityreference_tresulttype.cs
- EntityContainerEntitySet.cs
- SrgsGrammar.cs
- EditorPartChrome.cs
- rsa.cs
- ParameterElementCollection.cs
- HitTestFilterBehavior.cs
- UndirectedGraph.cs
- NonParentingControl.cs
- ItemsControlAutomationPeer.cs
- GreenMethods.cs
- SqlGenerator.cs
- DataSourceXmlSerializationAttribute.cs
- MsmqIntegrationChannelListener.cs
- ObjectDataSource.cs
- MarkupObject.cs
- TypedTableBaseExtensions.cs
- HostProtectionPermission.cs
- LambdaCompiler.Logical.cs
- Quad.cs
- CapabilitiesSection.cs
- IisTraceListener.cs
- DbSetClause.cs
- ColumnMap.cs
- _NativeSSPI.cs
- DrawingVisual.cs
- CharConverter.cs
- SQLInt64Storage.cs
- XmlTextAttribute.cs
- XmlIlGenerator.cs
- Attributes.cs
- TemplateXamlParser.cs
- BitSet.cs
- ComplexBindingPropertiesAttribute.cs
- CustomPeerResolverService.cs
- ToolStripItemClickedEventArgs.cs