XappLauncher.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / AppModel / XappLauncher.cs / 3 / XappLauncher.cs

                            using System; 
using System.Deployment.Application;
using System.Runtime.Remoting;
using System.Security;
using System.Security.Policy; 
using System.Xml;
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Interop;
using System.Windows.Navigation; 
using System.Windows.Threading;
using System.Runtime.InteropServices;
using System.Diagnostics;
using MS.Internal; 
using MS.Internal.PresentationFramework;
using MS.Internal.Utility; 
using Microsoft.Internal.DeploymentUI; 
using Microsoft.Win32;
using System.Reflection; 
using MS.Utility;
using System.Windows.Input;

namespace MS.Internal.AppModel 
{
    internal class XappLauncherApp : Application 
    { 
        internal XappLauncherApp(Uri deploymentManifest, Uri activationUri, string applicationId, IBrowserCallbackServices browser, DocObjHost.ApplicationRunnerCallback applicationRunner, string progressPageAssembly, string progressPageClass, string errorPageAssembly, string errorPageClass)
        { 
            _deploymentManifest = deploymentManifest;
            _activationUri = activationUri;
            _applicationId = applicationId;
            _browser = browser; 
            _applicationRunnerCallback = applicationRunner;
            _fwlinkUri = null; 
            this.Startup += new StartupEventHandler(XappLauncherApp_Startup); 
            this.Exit += new ExitEventHandler(XappLauncherApp_Exit);
            this.Navigated += new NavigatedEventHandler(XappLauncherApp_Navigated); 

            _progressPageAssembly = progressPageAssembly;
            _progressPageClass = progressPageClass;
            _errorPageAssembly = errorPageAssembly; 
            _errorPageClass = errorPageClass;
        } 
 
        void OnCommandRefresh(object sender, RoutedEventArgs e)
        { 
            HandleRefresh();
        }

        void OnCommandStop(object sender, RoutedEventArgs e) 
        {
            UserStop(null); 
        } 

        void XappLauncherApp_Startup(object sender, StartupEventArgs e) 
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, 
                    EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.XappLauncherAppStartup);
            } 
 
            CreateApplicationIdentity();
            if (_identity != null) 
            {
                TryApplicationIdActivation();
            }
            else 
            {
                TryUriActivation(); 
            } 
        }
 
        void XappLauncherApp_Exit(object sender, ExitEventArgs e)
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose,
                    EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.XappLauncherAppExit, _attemptDownload); 
            } 

            Invariant.Assert(!_isInAsynchronousOperation, 
                "Async downloading should have been canceled before XappLauncherApp exits.");

            if (_attemptDownload)
            { 
                _applicationRunnerCallback(new DocObjHost.ApplicationRunner(_applicationRunner));
            } 
 
            _browser = null;
            _applicationRunner = null; 
            _applicationRunnerCallback = null;
        }

 
        ///
        ///    Critical: This code calls into critical code GetAppWindow 
        ///    TreatAsSafe: There exists a demand here 
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        void XappLauncherApp_Navigated(object sender, NavigationEventArgs e)
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose,
                    EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.XappLauncherAppNavigated); 
            } 

            if (IsShuttingDown) 
                return;

            if (!_commandBindingsRegistered)
            { 
                _commandBindingsRegistered = true;
 
                // These bindings handle the commands sent by the browser when the stop/refresh buttons are pressed. If nothing in the 
                // page has focus, they will be sent directly to the window.
                MainWindow.CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseStop, new ExecutedRoutedEventHandler(OnCommandStop))); 
                MainWindow.CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, new ExecutedRoutedEventHandler(OnCommandRefresh)));
            }

            SecurityHelper.DemandUIWindowPermission(); 
            NavigationWindow navWin = GetAppWindow();
            Invariant.Assert(navWin != null, "A RootBrowserWindow should have been created."); 
            while (navWin.CanGoBack) 
            {
                navWin.RemoveBackEntry(); 
            }
        }

        void StartAsynchronousOperation() 
        {
            _isInAsynchronousOperation = true; 
            ChangeBrowserDownloadState(_isInAsynchronousOperation); 
        }
 
        void ClearAsynchronousOperationStatus()
        {
            _isInAsynchronousOperation = false;
            ChangeBrowserDownloadState(_isInAsynchronousOperation); 
        }
 
 
        private object UserRefresh(object unused)
        { 
            HandleRefresh();
            return null;
        }
 
        internal override void PerformNavigationStateChangeTasks(
            bool isNavigationInitiator, bool playNavigatingSound, NavigationStateChange state) 
        { 
            // Do not play sounds or start and stop the globe on when navigations
            // occur because the progress page is merely an enhanced visual experience 
            // during the actual navigation to the application.  Conceptually it  should
            // appear as something that happens during navigation and not a series of
            // discrete navigations.
 
            // We do need to ensure that the Stop and Refresh buttons are in the correct state
            // while downloading the app. 
            if (isNavigationInitiator && state == NavigationStateChange.Completed) 
            {
                UpdateBrowserCommands(); 
            }
        }

        // This function gets called when the browser refresh button in clicked. 
        // This'll cause the browser to navigate the address bar
        /// 
        ///  Critical: Accesses BrowserCallbackServices to navigate 
        ///  TreatAsSafe: only navigates to a safe, already validated _deploymentManifest.
        ///  Potentially, this could be a DOS attack FOR THE APP ONLY if refresh was called constantly, but that is 
        ///  below the bar for critical code progagation, as the user can recover and the system is not destabilized.
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        internal void HandleRefresh() 
        {
            lock (_lockObject) // we do this in case the refresh button is getting clicked rapidly, before the navigation happens 
            { 
                if (!_refreshing)
                { 
                    _refreshing = true;
                    BrowserCallbackServices.DelegateNavigation(_activationUri.ToString(), null, null);
                }
            } 
        }
 
        ///  
        /// Critical: Calls IBrowserCallbackServices.ChangeDownloadState which is critical
        /// TreatAsSafe: Changing the download state is safe 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void ChangeBrowserDownloadState(bool newState)
        { 
            // start or stop waving the flag
            _browser.ChangeDownloadState(newState); 
        } 

        private void TryApplicationIdActivation() 
        {
            Dispatcher.Invoke(
                DispatcherPriority.Input,
                new DispatcherOperationCallback(DoDirectActivation), 
                null);
        } 
 
        private void TryUriActivation()
        { 
            EventTrace.NormalTraceEvent(EventTraceGuidId.HOSTINGGUID, (byte)EventTrace.HostingEvent.FirstTimeActivation);

            _hostingManager = new InPlaceHostingManager(_deploymentManifest);
 
            // Ordering is important here - downloading the manifest is done asynchronously
            // so can be started before we spend time setting up the UI.  This saves us some 
            // time - especially during cold-start scenarios. 

            // Calling it through the dispatcher makes sure the right context and exception 
            // handling is used.  DispatcherPriority.Send has it executed synchronously.
            Dispatcher.Invoke(
                DispatcherPriority.Send,
                new DispatcherOperationCallback(DoGetManifestAsync), 
                null);
 
            DoDownloadUI(); 
        }
 
        ///
        ///     Critical: calls ApplicationTrustCollection.Item which LinkDemands
        ///     TreatAsSafe: Caller can't hand in an arbitrary item string
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private object DoDirectActivation(object unused) 
        { 
            if (IsShuttingDown)
                return null; 

            try
            {
                // Verify that this app is actually cached. This is because the call to 
                // CreatePartialActivationContext can succeed when we don't want it to;
                // it appears to be insensitive to some parts of the ApplicationIdentity, 
                // or it tries to make things work when they really should fail. Looking 
                // at the UserApplicationTrusts does a better comparison.
                if (ApplicationSecurityManager.UserApplicationTrusts[_identity.ToString()] != null) 
                {
                    _context = ActivationContext.CreatePartialActivationContext(_identity);
                    _applicationRunner = new DocObjHost.ApplicationRunner(ExecuteDirectApplication);
                    _attemptDownload = true; 
                    this.Shutdown();
                } 
                else 
                {
                    TryUriActivation(); 
                }
            }
            catch(Exception exception)
            { 
                // Delete the cached trust decision to force going down the full ClickOnce path next time
                DeleteCachedApplicationTrust(_identity); 
 
                // Fatal error like NullReferenceException and SEHException should not be ignored.
                if (exception is NullReferenceException || exception is SEHException) 
                {
                    throw;
                }
                else 
                {
                    TryUriActivation(); 
                } 
            }
 
            return null;
        }

        /// 
        ///    Critical: This code calls into critical code which has link demand (Activator.CreateInstance)
        ///    TreatAsSafe: There exists a demand here 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void ExecuteDirectApplication() 
        {
            SecurityHelper.DemandUnmanagedCode();
            try
            { 
                if (EventTrace.IsEnabled(EventTrace.Flags.performance))
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.ClickOnceActivationStart, KnownBoxes.BooleanBoxes.TrueBox); 
                }
                ObjectHandle oh = Activator.CreateInstance(_context); 
                if (PresentationAppDomainManager.SaveAppDomain)
                {
                    AppDomain newDomain = oh.Unwrap() as AppDomain;
                    PresentationAppDomainManager.NewAppDomain = newDomain; 
                }
 
                EventTrace.NormalTraceEvent(EventTraceGuidId.HOSTINGGUID, (byte)EventTrace.HostingEvent.ClickOnceActivationEnd); 
            }
            catch (Exception exception) 
            {
                // Delete the cached trust decision to force going down the full ClickOnce path next time
                DeleteCachedApplicationTrust(_identity);
 
                // Fatal error like NullReferenceException and SEHException should not be ignored.
                if (exception is NullReferenceException || exception is SEHException) 
                { 
                    throw;
                } 
                else
                {
                    TryUriActivation();
                } 
            }
        } 
 
        private object DoGetManifestAsync(object notUsed)
        { 
            if (IsShuttingDown)
                return null;

            EventTrace.NormalTraceEvent(EventTraceGuidId.HOSTINGGUID, (byte)EventTrace.HostingEvent.DownloadDeplManifestStart); 

            StartAsynchronousOperation(); 
            SetStatusText(SR.Get(SRID.HostingStatusDownloadAppInfo)); 

            _hostingManager.GetManifestCompleted += new EventHandler(GetManifestCompleted); 
            // Possible reentrancy! When making the outgoing calls to the browser to update its
            // status (above), a pending incoming call can be dispatched. This may be OLECMDID_STOP,
            // which would lead to calling UserStop(), which makes IPHM unusable.
            if (_isInAsynchronousOperation) 
            {
                _hostingManager.GetManifestAsync(); 
            } 
            return null;
        } 

        private object GetCustomPage(string pageAssemblyName, string pageClassName)
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose, 
                    EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.GetDownloadPageStart, pageClassName); 
            }
            object customPage; 
            try
            {
                // Uses custom progress page
                // If the assembly is not specified, use PresentationUI. 
                Assembly customPageAssembly = string.IsNullOrEmpty(pageAssemblyName) ? typeof(InstallationProgressPage).Assembly : Assembly.Load(pageAssemblyName);
                customPage = customPageAssembly.CreateInstance(pageClassName); 
            } 
            catch
            { 
                customPage = null;
            }
            if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
            { 
                EventTrace.EventProvider.TraceEvent(EventTrace.Level.verbose,
                    EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.GetDownloadPageEnd); 
            } 
            return customPage;
        } 

        void GetManifestCompleted(object sender, GetManifestCompletedEventArgs e)
        {
            Dispatcher.Invoke( 
                DispatcherPriority.Send,
                new DispatcherOperationCallback(DoGetManifestCompleted), 
                e); 
        }
 
        private object DoGetManifestCompleted(object e)
        {
            ClearAsynchronousOperationStatus();
 
            EventTrace.NormalTraceEvent(EventTraceGuidId.HOSTINGGUID, (byte)EventTrace.HostingEvent.DownloadDeplManifestEnd);
 
            GetManifestCompletedEventArgs args = (GetManifestCompletedEventArgs)e; 

            if (IsShuttingDown) 
            {
                // do nothing if some thread has already called shutdown
                return null;
            } 

            if (args.Error != null) 
            { 
                // If the async operation failed, it is invalid to request the
                // SupportUri so we simply pass in null. 
                HandleError(args.Error, args.LogFilePath, null, null);
                return null;
            }
 
            if (args.Cancelled)
            { 
                HandleCancel(); 
                return null;
            } 

            _identity = args.ApplicationIdentity;
            _supportUri = args.SupportUri;
 
            SetStatusText(SR.Get(SRID.HostingStatusVerifying));
 
            try 
            {
                if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
                {
                    EventTrace.EventProvider.TraceEvent(
                        EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.AssertAppRequirementsStart);
                } 

                _hostingManager.AssertApplicationRequirements(); 
 
                if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
                { 
                    EventTrace.EventProvider.TraceEvent(
                        EventTrace.Level.verbose, EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.AssertAppRequirementsEnd);
                }
            } 
            catch (Exception exception)
            { 
                // Fatal error like NullReferenceException and SEHException should not be ignored. 
                if (exception is NullReferenceException || exception is SEHException)
                { 
                    throw;
                }
                else
                { 
                    string version = null;
                    if (exception is TrustNotGrantedException) 
                    { 
                        version = GetMissingCustomPermissionVersion(args.ApplicationManifest);
                        if (!string.IsNullOrEmpty(version)) 
                        {
                            exception = new DependentPlatformMissingException();
                        }
                    } 

                    HandleError(exception, args.LogFilePath, args.SupportUri, version); 
 
                    return null;
                } 
            }

            // AssertApplicationRequirements() does some message pumping internally, which allows
            // the browser to start closing us in the meantime. 
            if (IsShuttingDown)
                return null; 
 
            StartAsynchronousOperation();
            SetStatusText(SR.Get(SRID.HostingStatusDownloadApp)); 

            if (_progressPage != null)
            {
                _progressPage.ApplicationName = args.ProductName; 
            }
 
            // Possible reentrancy! When making the outgoing calls to the browser to update its 
            // status (above), a pending incoming call can be dispatched. This may be OLECMDID_STOP,
            // which would lead to calling UserStop(), which makes IPHM unusable. 
            if (!_isInAsynchronousOperation)
                return null;

            _hostingManager.DownloadProgressChanged += new EventHandler(DownloadProgressChanged); 
            _hostingManager.DownloadApplicationCompleted += new EventHandler(DownloadApplicationCompleted);
 
            EventTrace.NormalTraceEvent(EventTraceGuidId.HOSTINGGUID, (byte)EventTrace.HostingEvent.DownloadApplicationStart); 

            _hostingManager.DownloadApplicationAsync(); 
            return null;
        }

        ///  
        /// Critical - calls InstallationProgressPage, which lives in a non-APTCA assembly.
        /// _progressPage lives in a non-APTCA assembly. 
        /// TreatAsSafe - demands appropriate permissions. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private void DoDownloadUI()
        {
            SecurityHelper.DemandUIWindowPermission();
            // ASSUMES ALREADY IN CORRECT CONTEXT 

            if (_progressPageClass != null) 
            { 
                _progressPage = GetCustomPage(_progressPageAssembly, _progressPageClass) as IProgressPage;
            } 
            // If we failed to get a custom page, or didn't even try, use our default.
            if (_progressPage == null)
            {
                _progressPage = new InstallationProgressPage() as IProgressPage; 
            }
 
           _progressPage.DeploymentPath = _deploymentManifest; 
           _progressPage.StopCallback = new DispatcherOperationCallback(UserStop);
           _progressPage.RefreshCallback = new DispatcherOperationCallback(UserRefresh); 
           _progressPage.ApplicationName = string.Empty;
           _progressPage.PublisherName = string.Empty;
           _progressPage.UpdateProgress(0, 1);
 
           BrowserWindow.ShowsNavigationUI = false; // not needed and not RightToLeft-enabled in this context
           BrowserWindow.Navigate(_progressPage); 
        } 

        ///  
        /// The demand below was put here because although PresentationFramework has
        /// APTCA set, the assembly where _progressPage lives (PresentationUI) does not.
        /// Critical: Because it is calling into non-aptca DLL
        /// TAS: We demand permission 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private void HandleError(Exception exception, string logFilePath, Uri supportUri, string requiredWpfVersion) 
        {
            SecurityHelper.DemandUIWindowPermission(); 

            // Delete the cached trust decision to force going down the full ClickOnce path next time
            DeleteCachedApplicationTrust(_identity);
 
            // If we are being shut down by the browser, don't do anything else.
            if (IsShuttingDown) 
            { 
                AbortActivation();
                return; 
            }

            // ASSUMES ALREADY IN CORRECT CONTEXT
            SetStatusText(SR.Get(SRID.HostingStatusFailed)); 
            string version = String.Empty;
            MissingDependencyType getWinFXReq = MissingDependencyType.Others; 
 
            if (exception is DependentPlatformMissingException)
            { 
                if (requiredWpfVersion != null)
                {
                    getWinFXReq = MissingDependencyType.WinFX;
                    version = requiredWpfVersion; 
                    DeploymentExceptionMapper.ConstructFwlinkUrl(version, out _fwlinkUri);
                } 
                else 
                {
                    getWinFXReq = DeploymentExceptionMapper.GetWinFXRequirement(exception, _hostingManager, out version, out _fwlinkUri); 
                }
            }

            string errorTitle, errorMessage; 

            switch(getWinFXReq) 
            { 
                case MissingDependencyType.WinFX:
                    // Wrong version of Avalon is installed. 
                    errorTitle = SR.Get(SRID.PlatformRequirementTitle);
                    errorMessage = SR.Get(SRID.IncompatibleWinFXText, version);
                    break;
                case MissingDependencyType.CLR: 
                    // Missing CLR dependency
                    errorTitle = SR.Get(SRID.PlatformRequirementTitle); 
                    errorMessage = SR.Get(SRID.IncompatibleCLRText, version); 
                    break;
                default: 
                    // All other deployment exceptions
                    DeploymentExceptionMapper.GetErrorTextFromException(exception, out errorTitle, out errorMessage);
                    break;
            } 

            IErrorPage errorpage = null; 
 
            if (_errorPageClass != null)
            { 
                errorpage = GetCustomPage(_errorPageAssembly, _errorPageClass) as IErrorPage;
            }
            // If we failed to get a custom page, or didn't even try, use our default.
            if (errorpage == null) 
            {
                //use default class 
                errorpage = new InstallationErrorPage() as IErrorPage; 
            }
 
            errorpage.DeploymentPath = _deploymentManifest;
            errorpage.ErrorTitle = errorTitle;
            errorpage.ErrorText = errorMessage;
            errorpage.SupportUri = supportUri; 
            errorpage.LogFilePath = logFilePath;
            errorpage.RefreshCallback = new DispatcherOperationCallback(UserRefresh); 
            errorpage.GetWinFxCallback = (getWinFXReq != MissingDependencyType.Others)? new DispatcherOperationCallback(GetWinFX) : null; 
            errorpage.ErrorFlag = true;
 
            BrowserWindow.Navigate(errorpage);
        }

        ///  
        /// Critical - calls InstallationErrorPage, which lives in a non-APTCA assembly.
        /// _progressPage lives in a non-APTCA assembly. 
        /// TreatAsSafe - demands appropriate permissions. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private void HandleCancel()
        {
            SecurityHelper.DemandUIWindowPermission();
 
            // Delete the cached trust decision to force going down the full ClickOnce path next time
            DeleteCachedApplicationTrust(_identity); 
 
            // If we are being shut down by the browser, don't do anything else.
            if (IsShuttingDown) 
            {
                AbortActivation();
                return;
            } 

            CancelAsynchronousOperation(); 
 
            // ASSUMES ALREADY IN CORRECT CONTEXT
            SetStatusText(SR.Get(SRID.HostingStatusCancelled)); 
            string errorTitle, errorMessage;
            DeploymentExceptionMapper.GetErrorTextFromException(null, out errorTitle, out errorMessage);
            IErrorPage errorpage = null;
            //dont even try to use reflection if assembly name is null 
            //dont even try to use reflection if assembly name is null
            if (_errorPageAssembly != null || _errorPageClass != null) 
            { 
                errorpage = GetCustomPage(_errorPageAssembly, _errorPageClass) as IErrorPage;
            } 
            //if this is null then there is no custom page so fall back to default ui
            if (errorpage == null)
            {
                //use default class 
                errorpage = new InstallationErrorPage() as IErrorPage;
            } 
 
            errorpage.DeploymentPath = _deploymentManifest;
            errorpage.ErrorTitle = errorTitle; 
            errorpage.ErrorText = errorMessage;
            errorpage.SupportUri = null;
            errorpage.LogFilePath = null;
            errorpage.ErrorFlag = false; 
            errorpage.RefreshCallback = new DispatcherOperationCallback(UserRefresh);
            errorpage.GetWinFxCallback = null; 
 

            BrowserWindow.Navigate(errorpage); 
        }

        void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        { 
            _bytesDownloaded = e.BytesDownloaded;
            _bytesTotal = e.TotalBytesToDownload; 
 
            if (!_updatePending)
            { 
                _updatePending = true;
                Dispatcher.BeginInvoke(
                    DispatcherPriority.Background,
                    new DispatcherOperationCallback(DoDownloadProgressChanged), 
                    null);
            } 
        } 

        ///  
        /// The demand below was put here because although PresentationFramework has
        /// APTCA set, the assembly where _progressPage lives (PresentationUI) does not.
        /// 
        private object DoDownloadProgressChanged(object unused) 
        {
            if (IsShuttingDown) 
                return null; 

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

            SecurityHelper.DemandUIWindowPermission(); 
 
            if (_progressPage != null)
            { 
                _progressPage.UpdateProgress(_bytesDownloaded, _bytesTotal);
            }
            _updatePending = false;
 
            return null;
        } 
 
        void DownloadApplicationCompleted(object sender, DownloadApplicationCompletedEventArgs e)
        { 
            _hostingManager.DownloadProgressChanged -= new EventHandler(DownloadProgressChanged);
            Dispatcher.Invoke(
                DispatcherPriority.Send,
                new DispatcherOperationCallback(DoDownloadApplicationCompleted), 
                e);
        } 
 
        private object DoDownloadApplicationCompleted(object e)
        { 
            EventTrace.NormalTraceEvent(EventTraceGuidId.HOSTINGGUID, (byte)EventTrace.HostingEvent.DownloadApplicationEnd);

            DownloadApplicationCompletedEventArgs args = (DownloadApplicationCompletedEventArgs)e;
 
            // Race condition: UserStop() can be called after InPlaceHostingManager has completed
            // the downloading but before our callback is called. 
            bool canceled = !_isInAsynchronousOperation || args.Cancelled; 

            if (IsShuttingDown) 
            {
                // some other thread has already called shutdown and released
                // the BrowserCallBackService. Nothing we can do here
                return null; 
            }
            ClearAsynchronousOperationStatus(); 
 
            if (args.Error != null)
            { 
                HandleError(args.Error, args.LogFilePath, _supportUri, null);
                return null;
            }
 
            if (canceled)
            { 
                HandleCancel(); 
                return null;
            } 

            SetStatusText(string.Empty);
            _applicationRunner = new DocObjHost.ApplicationRunner(ExecuteDownloadedApplication);
            _attemptDownload = true; 
            Shutdown();
            return null; 
        } 

        private void ExecuteDownloadedApplication() 
        {
            if (EventTrace.IsEnabled(EventTrace.Flags.performance))
            {
                EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.HOSTINGGUID), (byte)EventTrace.HostingEvent.ClickOnceActivationStart, KnownBoxes.BooleanBoxes.FalseBox); 
            }
 
            ObjectHandle oh = _hostingManager.Execute(); 
            if (PresentationAppDomainManager.SaveAppDomain)
            { 
                AppDomain newDomain = oh.Unwrap() as AppDomain;
                PresentationAppDomainManager.NewAppDomain = newDomain;
            }
 
            EventTrace.NormalTraceEvent(EventTraceGuidId.HOSTINGGUID, (byte)EventTrace.HostingEvent.ClickOnceActivationEnd);
        } 
 
        private object UserStop(object unused)
        { 
            if (MainWindow != null && MainWindow.Content is IProgressPage)
            {
                if (_isInAsynchronousOperation)
                { 
                    CancelAsynchronousOperation();
                } 
                else 
                {
                    HandleCancel(); 
                }
            }

            return null; 
        }
 
        internal void AbortActivation() 
        {
            EventTrace.NormalTraceEvent(EventTraceGuidId.HOSTINGGUID, (byte)EventTrace.HostingEvent.AbortingActivation); 

            CancelAsynchronousOperation();
            _attemptDownload = false;
            Shutdown(ERROR_ACTIVATION_ABORTED); 
        }
 
        private void CancelAsynchronousOperation() 
        {
            lock (_lockObject) 
            {
                if (_isInAsynchronousOperation)
                {
                    Invariant.Assert(_hostingManager != null, "_hostingManager should not be null if _isInAsynchronousOperation is true"); 
                    _hostingManager.CancelAsync();
                    ClearAsynchronousOperationStatus(); 
                } 
            }
        } 

        /// 
        ///     Critical: This code calls into RootBrowserWindow which is critical
        ///     TreatAsSafe: There is a demand 
        /// 
        private RootBrowserWindow BrowserWindow 
        { 
            [SecurityCritical,SecurityTreatAsSafe]
            get 
            {
                SecurityHelper.DemandUIWindowPermission();
                RootBrowserWindow rbw = (RootBrowserWindow)GetAppWindow();
                Invariant.Assert(rbw != null, "Should have instantiated RBW if it wasn't already there"); 
                return rbw;
            } 
        } 

        private void CreateApplicationIdentity() 
        {
            _identity = null;
            if (_applicationId != null)
            { 
                try
                { 
                    _identity = new ApplicationIdentity(_applicationId); 
                }
                catch(Exception exception) 
                {
                    // Fatal error like NullReferenceException and SEHException should not be ignored.
                    if (exception is NullReferenceException || exception is SEHException)
                    { 
                        throw;
                    } 
 
                    // For a non-critical exception, it can be ignored here.
                    // Because the code tries to make an ApplicationIdentity from a string in registry, 
                    // If it fails, it isn�t fatal, the code just needs to do activation from the deployment Uri.

                }
            } 
        }
 
        ///  
        /// This is necessary as a workaround for various ClickOnce issues and the interaction
        /// between cached trust decisions and our direct activation shortcut. If there is a 
        /// cached trust decision for a given ApplicationIdentity, we will try the direct
        /// activation shortcut. If something goes wrong, we want to delete that cached trust
        /// decision, so that next time we will be forced to go down the offical ClickOnce
        /// deployment pathway. 
        /// 
        /// 
        ///     Critical: calls ApplicationTrustCollection.Remove which LinkDemands 
        ///
        [SecurityCritical] 
        private void DeleteCachedApplicationTrust(ApplicationIdentity identity)
        {
            if (identity != null)
            { 
                ApplicationTrust trust = new ApplicationTrust(identity);
                // This does not throw if the trust isn't there. 
                ApplicationSecurityManager.UserApplicationTrusts.Remove(trust); 
            }
        } 

        ///
        /// This function is private to xapplauncher. It invokes the default browser with Uri
        /// to WinFXSetup.exe.  Its called from the "Install WinFX" button on the error page 
        /// shown when an app requests a different version of WinFX than the one installed.
        /// 
        ///  
        /// Critical - Gets access to critical resource (uri and browsercallback services), calls critical
        /// code (launch browser). 
        /// TreatAsSafe - There exists a demand here.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private object GetWinFX(object unused) 
        {
            SecurityHelper.DemandUnmanagedCode(); 
 
            AppSecurityManager.ShellExecuteDefaultBrowser(_fwlinkUri);
 
            return null;
        }

        /// 
        ///     Critical - calls SetStatusText which is SUC'ed.
        ///     TreatAsSafe - setting the status bar text of the browser considered safe. 
        ///                   IE/MSRC does not consider hostile setting of text ( even for hyperlink spoofing) 
        ///                   to be an exploit.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void SetStatusText(string newStatusText)
        {
            _browser.SetStatusText(newStatusText); 
        }
 
        ///  
        /// If trust was not granted, it may have been because the assembly of a custom permission
        /// could not be loaded. In this case, we are interested in custom permissions that are 
        /// from WindowsBase.
        /// 
        /// The XmlReader for the application manifest
        /// If the specified version of WindowsBase could not be loaded, the version, else null. 
        private string GetMissingCustomPermissionVersion(XmlReader reader)
        { 
            string requiredVersion = null; 

            while (reader.ReadToFollowing("IPermission", "urn:schemas-microsoft-com:asm.v2")) 
            {
                string attr = reader.GetAttribute("class");

                // Strip the first item in the comma-delimited list, which is the permission class 
                AssemblyName assyName = new AssemblyName(attr.Substring(attr.IndexOf(",",StringComparison.OrdinalIgnoreCase) + 1));
                if (assyName.Name.Equals("WindowsBase", StringComparison.OrdinalIgnoreCase)) 
                { 
                    try
                    { 
                        Assembly assy = Assembly.Load(assyName);
                    }
                    catch (Exception e)
                    { 
                        // This will give a FileLoadException under the debugger, but a FileNotFoundException otherwise
                        if (e is System.IO.FileNotFoundException || e is System.IO.FileLoadException) 
                        { 
                            requiredVersion = assyName.Version.ToString();
                            break; 
                        }
                        else
                        {
                            throw; 
                        }
                    } 
                } 
            }
 
            reader.Close();

            return requiredVersion;
        } 

        InPlaceHostingManager _hostingManager; 
        IBrowserCallbackServices _browser; 
        ApplicationIdentity _identity;
        Uri _deploymentManifest; 
        Uri _activationUri;
        Uri _fwlinkUri;
        Uri _supportUri;
        string _applicationId; 
        ActivationContext _context;
        DocObjHost.ApplicationRunnerCallback _applicationRunnerCallback; 
        DocObjHost.ApplicationRunner _applicationRunner; 
        IProgressPage _progressPage;
        bool _attemptDownload; 
        bool _isInAsynchronousOperation;
        const int ERROR_ACTIVATION_ABORTED = 30; // defined in host\inc\Definitions.hxx

        object _lockObject = new object(); 

        long _bytesDownloaded; 
        long _bytesTotal; 
        bool _updatePending;
 
        string _progressPageAssembly = null;
        string _progressPageClass = null;
        string _errorPageAssembly = null;
        string _errorPageClass = null; 

        bool _commandBindingsRegistered; 
        bool _refreshing; 
    }
} 

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