MediaSystem.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 / Core / CSharp / System / Windows / Media / MediaSystem.cs / 1 / MediaSystem.cs

                            //+---------------------------------------------------------------------------- 
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//
//  Abstract: 
//     Media system holds the relation between an application
//     domain and the underlying transport system. 
// 
//-----------------------------------------------------------------------------
 
using System;
using System.Windows.Threading;

using System.Collections; 
using System.Diagnostics;
using System.Windows.Media.Animation; 
using System.Windows.Media.Composition; 
using Microsoft.Win32;
using Microsoft.Internal; 
using MS.Internal;
using MS.Internal.FontCache;
using MS.Win32;
using System.Security; 
using System.Security.Permissions;
 
using SR=MS.Internal.PresentationCore.SR; 
using SRID=MS.Internal.PresentationCore.SRID;
using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods.MilCoreApi; 
using SafeNativeMethods=MS.Win32.PresentationCore.SafeNativeMethods;

namespace System.Windows.Media
{ 
    /// 
    /// The MediaSystem class controls the media layer. 
    ///  
    /// 
    /// Use  to start up the media system and  to 
    /// shut down the mediasystem.
    /// 
    internal static class MediaSystem
    { 
        /// 
        /// This function initializes the MediaSystem. It must be called before any functions in the Media namespace 
        /// can be used. 
        /// 
        ///  
        /// 
        /// Critical    -- gets and stores an unmanaged pointer to the current transport from milcore.
        /// TreatAsSafe -- starting up the transport is considered a safe operation. Worst case is that
        ///                we will create a transport object nobody is going to use. Access to the transport 
        ///                object pointer is security critical.
        ///  
        [SecurityCritical, SecurityTreatAsSafe ] 
        public static bool Startup(MediaContext mc)
        { 
            //
            // Note to stress triagers:
            //
            // This call will fail if PresentationCore.dll and milcore.dll have mismatched 
            // versions -- please make sure that both binaries have been properly built
            // and deployed. 
            // 
            // *** Failure here does NOT indicate a bug in MediaContext.Startup! ***
            // 

            HRESULT.Check(UnsafeNativeMethods.MilVersionCheck(MS.Internal.Composition.Version.MilSdkVersion));

            using (CompositionEngineLock.Acquire()) 
            {
                _mediaContexts.Add(mc); 
 
                //Is this the first startup?
                if (0 == s_refCount) 
                {
                    HRESULT.Check(SafeNativeMethods.MilCompositionEngine_InitializePartitionManager(
                                  0, // THREAD_PRIORITY_NORMAL
                                  MIL_SCHEDULE_TYPE.MIL_SCHEDULE_UNTHROTTLED // use unthrottled scheduling because managed side throttles. 
                                  ));
 
                    bool fIsConnected; 
                    UInt32 dwGeneration;
 
                    HRESULT.Check(UnsafeNativeMethods.MilTransport_CreateTransportParameters(
                        true, // fForcedLocalTransport
                        out fIsConnected,
                        out dwGeneration, 
                        out s_forceSoftareForGraphicsStreamMagnifier));
 
                    ConnectTransport(); 

                    s_lastGeneration = dwGeneration; 

                    // Read a flag from the registry to determine whether we should run
                    // animation smoothing code.
                    ReadAnimationSmoothingSetting(); 
                }
                s_refCount++; 
            } 
            //
 

            return true;
        }
 
        /// 
        /// This function initializes the [....]/same thread connection 
        ///  
        /// 
        /// Critical    -- gets and stores an unmanaged pointer to the [....] connection and the [....] packet transport. 
        /// 
        [SecurityCritical]
        internal static IntPtr ConnectSyncTransport(out IntPtr pSyncPacketTransport)
        { 
            IntPtr pSyncTransport = IntPtr.Zero;
 
            HRESULT.Check(UnsafeNativeMethods.MilSyncPacketTransport_Create(out pSyncPacketTransport)); 
            HRESULT.Check(UnsafeNativeMethods.MilTransport_CreateFromPacketTransport( pSyncPacketTransport, out pSyncTransport));
 
            return pSyncTransport;
        }

        internal static bool ConnectChannels(MediaContext mc) 
        {
            bool fCreated = false; 
 
            using (CompositionEngineLock.Acquire())
            { 
                if (IsTransportConnected)
                {
                    mc.CreateChannels();
                    fCreated = true; 
                }
            } 
 
            return fCreated;
        } 

        /// 
        /// Reads a value from the registry to decide whether to disable the animation
        /// smoothing algorithm. 
        /// 
        ///  
        /// Critical - asserts registry permissions to read from HKEY_LOCAL_MACHINE. 
        /// Treat as safe - we only read a binary value used exclusively for Avalon.
        ///  
        /// 
        /// The code is only present in internal builds
        /// 
        [SecurityCritical, SecurityTreatAsSafe ] 
        private static void ReadAnimationSmoothingSetting()
        { 
#if PRERELEASE 
            // Acquire permissions to read the one key we care about from the registry
            RegistryPermission permission = new RegistryPermission( 
                RegistryPermissionAccess.Read,
                System.Security.AccessControl.AccessControlActions.View,
                @"HKEY_LOCAL_MACHINE\Software\Microsoft\Avalon.Graphics");
 
            permission.Assert();
 
            try 
            {
                RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Avalon.Graphics"); 
                if (key != null)
                {
                    object keyValue = key.GetValue("AnimationSmoothing");
 
                    // The Regkey now turns off AnimationSmoothing
                    s_animationSmoothing = !(keyValue is int && ((int)keyValue) == 0); 
                } 
            }
            finally 
            {
                RegistryPermission.RevertAssert();
            }
#endif 
        }
 
        ///  
        /// This deinitializes the MediaSystem and frees any resources that it maintains.
        ///  
        /// 
        /// Critical    -- results in the release of an unmanaged pointer to the current transport.
        /// TreatAsSafe -- shutting down the transport is considered a safe operation. Worst case
        ///                is that the client stops rendering Avalon content. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe ] 
        internal static void Shutdown(MediaContext mc) 
        {
            using (CompositionEngineLock.Acquire()) 
            {
                Debug.Assert(s_refCount > 0);
                _mediaContexts.Remove(mc);
 
                s_refCount--;
                if (0 == s_refCount) 
                { 
                    // We can shut-down.
                    // Debug.WriteLine("MediSystem::NotifyDisconnect Stop Transport\n"); 

                    if (IsTransportConnected)
                    {
                        DisconnectTransport(); 
                    }
 
                    HRESULT.Check(SafeNativeMethods.MilCompositionEngine_DeinitializePartitionManager()); 
                }
            } 
        }

        /// 
        /// Handle DWM messages that indicate that the state of the connection needs to change. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal static void NotifyRedirectionEnvironmentChanged() 
        {
            using (CompositionEngineLock.Acquire()) 
            {
                //
                // Let the MIL decide the transport type if the redirection environment
                // has changed. We will fall back to a local-only transport and presents 
                // using bitblts to make the rendered content available to graphics stream
                // clients if MIL fails to initialize the default transport. 
                // 

                HandleTransportParametersChange(); 
            }
        }

        ///  
        /// Analyze the most recently obtained transport parameters and decide
        /// if an attempt to connect or disconnect should be made. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private static void HandleTransportParametersChange() 
        {
            bool fIsConnected;
            UInt32 dwGeneration;
            bool forceSoftareForGraphicsStreamMagnifier; 

            HRESULT.Check(UnsafeNativeMethods.MilTransport_CreateTransportParameters( 
                true, // force local transport 
                out fIsConnected,
                out dwGeneration, 
                out forceSoftareForGraphicsStreamMagnifier));

            if (fIsConnected)
            { 
                // If the dwm's connection generation does not match ours we
                // need to recreate the connection with the new transport parameters. 
                // If the graphics stream client state changed, we also want to recycle the 
                // transport/UCE to ensure we are switching back to hw.
                if ((dwGeneration != s_lastGeneration) || 
                    (forceSoftareForGraphicsStreamMagnifier != s_forceSoftareForGraphicsStreamMagnifier))
                {
                    s_lastGeneration = dwGeneration;
                    s_forceSoftareForGraphicsStreamMagnifier = forceSoftareForGraphicsStreamMagnifier; 

                    DisconnectTransport(); 
 
                    ConnectTransport();
 
                    foreach (MediaContext mc in _mediaContexts)
                    {
                        mc.PostDisconnect();
                        mc.PostConnect(); 
                    }
                } 
            } 
            else
            { 
                // if we don't need to be connected disconnect the connection.
                DisconnectTransport();
                foreach (MediaContext mc in _mediaContexts)
                { 
                    mc.PostDisconnect();
                } 
            } 
        }
 
        /// 
        /// Connect the transport.
        /// 
        ///  
        ///   Critical - Creates a channel, calls methods performing elevations.
        ///   TreatAsSafe - Transport initialization is considered safe. Service channel 
        ///                 creation is safe. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private static void ConnectTransport()
        {
            if (IsTransportConnected)
            { 
                throw new System.InvalidOperationException(SR.Get(SRID.MediaSystem_OutOfOrderConnectOrDisconnect));
            } 
 
            //
            // Create a default transport to be used by this media system. 
            // If creation fails, fall back to a local transport.
            //

            HRESULT.Check(UnsafeNativeMethods.MilTransport_Create(out s_pConnection)); 

            // Create service channel used by global glyph cache. This channel is 
            // the first channel created for the app, and by creating it with 
            // a null channel reference it creates a new partition.
            // All subsequent channel creates will pass in a reference to this 
            // channel thus using its partition.
            s_serviceChannel = new DUCE.Channel(
                null,
                false,       // not out of band 
                false,       // is a layered window specific channel
                s_pConnection, 
                IntPtr.Zero 
                );
 
            IsTransportConnected = true;
        }

        ///  
        /// Disconnect the transport. If we are calling this function from a disconnect
        /// request we want to keep the service channel around. So that media contexts that 
        /// have not yet received disconnect event do not crash. 
        /// 
        ///  
        /// Critical - Closes a channel. Shuts down the transport.
        /// TreatAsSafe - Shutting down the transport is considered safe.
        ///               Closing the service channel is safe.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private static void DisconnectTransport() 
        { 
            if (!IsTransportConnected)
            { 
                return;
            }

            // Close global glyph cache channel. 
            s_serviceChannel.Close();
 
            HRESULT.Check(UnsafeNativeMethods.MilTransport_DisconnectTransport( 
                s_pConnection));
 
            // Release references to global glyph cache and service channel.
            s_serviceChannel = null;
            s_pConnection = IntPtr.Zero;
 
            IsTransportConnected = false;
        } 
 
        /// 
        /// Checks if to CAO have the same context affinity. This is for example important for 
        /// ContainerVisual.Children.Add to ensure that the scene graph is homogenously build out
        /// of object that have the same context affinity.
        /// 
        /// Reference to which to compare to. This argument is usually the this 
        /// pointer and can not be null.
        /// Object for which the check is performed. 
        ///  
        /// Example:
        /// 
        /// class Visual
        /// {
        ///     ...
        ///     void Add(Visual child) 
        ///     {
        ///         VerifyContext(this); 
        ///         AssertSameContext(this, child); 
        ///         ...
        ///     } 
        /// }
        ///
        /// Note that VerifyContext(A) AND AssertSameContext(A, B) implies that VerifyContext(B) holds. Hence you
        /// don't need to check the context for each argument if you assert the same context. 
        /// 
        internal static void AssertSameContext( 
            DispatcherObject reference, 
            DispatcherObject other)
        { 
            Debug.Assert(reference != null, "The reference object can not be null.");

            // DispatcherObjects may be created with the option of becoming unbound.
            // An unbound DO may be created without a Dispatcher or may detach from 
            // its Dispatcher (e.g., a Freezable).  Unbound DOs return null for their
            // Dispatcher and should be accepted anywhere. 
            if (other != null && 
                reference.Dispatcher != null &&
                other.Dispatcher != null && 
                reference.Dispatcher != other.Dispatcher)
            {
                throw new ArgumentException(SR.Get(SRID.MediaSystem_ApiInvalidContext));
            } 
        }
 
        ///  
        /// This flag indicates if the transport has been disabled by a session disconnect.
        /// If the transport has been disabled we need to defer all media system startup requests 
        /// until we get the next connect message
        /// 
        internal static bool IsTransportConnected
        { 
            get { return s_isConnected; }
            set { s_isConnected = value; } 
        } 

        ///  
        /// This flag indicates that we have forced the local-only transport. This might
        /// be a result of version negotiation or connection failures and will require
        /// fallback to a rendering mode that will make our content accessibile to GDI
        /// APIs -- to enable legacy remoting and magnification. 
        /// 
        ///  
        /// Critical because s_forceSoftareForGraphicsStreamMagnifier is security critical, but 
        /// only if it can be set (since that controls if rendering is sw/hw). Because
        /// this method does not allow setting s_forceSoftareForGraphicsStreamMagnifier, it cannot 
        /// be used to control rendering mode. Reading it is safe since this is information
        /// we volunteer anyhow in the tiering API.
        /// 
        internal static bool ForcedLocalTransport 
        {
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return s_forceSoftareForGraphicsStreamMagnifier; } 
        }
 
        /// 
        /// Returns the service channel for the current media system. This channel
        /// is used by the glyph cache infrastructure.
        ///  
        /// 
        /// Critical - Controlled unmanaged resource. 
        ///  
        internal static DUCE.Channel ServiceChannel
        { 
            [SecurityCritical]
            get { return s_serviceChannel; }
        }
 
        /// 
        /// Returns the pointer to the unmanaged transport object. 
        ///  
        /// 
        /// Critical - Controlled unmanaged resource. 
        /// 
        internal static IntPtr Connection
        {
            [SecurityCritical] 
            get { return s_pConnection; }
        } 
 
        internal static bool AnimationSmoothing
        { 
            get { return s_animationSmoothing; }
        }

        internal static Guid DeviceId 
        {
            get 
            { 
                return s_deviceId;
            } 
        }

        internal static long GenerationId
        { 
            get
            { 
                return s_lastGeneration; 
            }
        } 

        /// 
        /// Keeps track of how often MediaSystem.Startup is called. So that the MediaSystem can be shut down at the right
        /// point in time. 
        /// 
        private static int s_refCount = 0; 
 
        //private static bool s_lastWasDisconnect = false;
 
        private static ArrayList _mediaContexts = new ArrayList();

        private static long s_lastGeneration = 0;
 
        private static bool s_isConnected = false;
 
        ///  
        /// Service channel to serve global glyph cache.
        ///  
        /// 
        /// Critical - Controlled unmanaged resource.
        /// 
        [SecurityCritical] 
        private static DUCE.Channel s_serviceChannel;
 
        private static bool s_animationSmoothing = true; 

        private static Guid s_deviceId = Guid.NewGuid(); 

        /// 
        /// Pointer to the unmanaged transport object.
        ///  
        /// 
        /// Critical - Controlled unmanaged resource. 
        ///  
        [SecurityCritical]
        private static IntPtr s_pConnection; 

        /// 
        /// Indicates if a graphics stream client is present. If a graphics stream client is present,
        /// we drop back to sw rendering to enable the Vista magnifier. 
        /// 
        ///  
        /// Critical - controls rendering mode (hw/sw). 
        /// 
        [SecurityCritical] 
        private static bool s_forceSoftareForGraphicsStreamMagnifier;
     }
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//+---------------------------------------------------------------------------- 
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//
//  Abstract: 
//     Media system holds the relation between an application
//     domain and the underlying transport system. 
// 
//-----------------------------------------------------------------------------
 
using System;
using System.Windows.Threading;

using System.Collections; 
using System.Diagnostics;
using System.Windows.Media.Animation; 
using System.Windows.Media.Composition; 
using Microsoft.Win32;
using Microsoft.Internal; 
using MS.Internal;
using MS.Internal.FontCache;
using MS.Win32;
using System.Security; 
using System.Security.Permissions;
 
using SR=MS.Internal.PresentationCore.SR; 
using SRID=MS.Internal.PresentationCore.SRID;
using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods.MilCoreApi; 
using SafeNativeMethods=MS.Win32.PresentationCore.SafeNativeMethods;

namespace System.Windows.Media
{ 
    /// 
    /// The MediaSystem class controls the media layer. 
    ///  
    /// 
    /// Use  to start up the media system and  to 
    /// shut down the mediasystem.
    /// 
    internal static class MediaSystem
    { 
        /// 
        /// This function initializes the MediaSystem. It must be called before any functions in the Media namespace 
        /// can be used. 
        /// 
        ///  
        /// 
        /// Critical    -- gets and stores an unmanaged pointer to the current transport from milcore.
        /// TreatAsSafe -- starting up the transport is considered a safe operation. Worst case is that
        ///                we will create a transport object nobody is going to use. Access to the transport 
        ///                object pointer is security critical.
        ///  
        [SecurityCritical, SecurityTreatAsSafe ] 
        public static bool Startup(MediaContext mc)
        { 
            //
            // Note to stress triagers:
            //
            // This call will fail if PresentationCore.dll and milcore.dll have mismatched 
            // versions -- please make sure that both binaries have been properly built
            // and deployed. 
            // 
            // *** Failure here does NOT indicate a bug in MediaContext.Startup! ***
            // 

            HRESULT.Check(UnsafeNativeMethods.MilVersionCheck(MS.Internal.Composition.Version.MilSdkVersion));

            using (CompositionEngineLock.Acquire()) 
            {
                _mediaContexts.Add(mc); 
 
                //Is this the first startup?
                if (0 == s_refCount) 
                {
                    HRESULT.Check(SafeNativeMethods.MilCompositionEngine_InitializePartitionManager(
                                  0, // THREAD_PRIORITY_NORMAL
                                  MIL_SCHEDULE_TYPE.MIL_SCHEDULE_UNTHROTTLED // use unthrottled scheduling because managed side throttles. 
                                  ));
 
                    bool fIsConnected; 
                    UInt32 dwGeneration;
 
                    HRESULT.Check(UnsafeNativeMethods.MilTransport_CreateTransportParameters(
                        true, // fForcedLocalTransport
                        out fIsConnected,
                        out dwGeneration, 
                        out s_forceSoftareForGraphicsStreamMagnifier));
 
                    ConnectTransport(); 

                    s_lastGeneration = dwGeneration; 

                    // Read a flag from the registry to determine whether we should run
                    // animation smoothing code.
                    ReadAnimationSmoothingSetting(); 
                }
                s_refCount++; 
            } 
            //
 

            return true;
        }
 
        /// 
        /// This function initializes the [....]/same thread connection 
        ///  
        /// 
        /// Critical    -- gets and stores an unmanaged pointer to the [....] connection and the [....] packet transport. 
        /// 
        [SecurityCritical]
        internal static IntPtr ConnectSyncTransport(out IntPtr pSyncPacketTransport)
        { 
            IntPtr pSyncTransport = IntPtr.Zero;
 
            HRESULT.Check(UnsafeNativeMethods.MilSyncPacketTransport_Create(out pSyncPacketTransport)); 
            HRESULT.Check(UnsafeNativeMethods.MilTransport_CreateFromPacketTransport( pSyncPacketTransport, out pSyncTransport));
 
            return pSyncTransport;
        }

        internal static bool ConnectChannels(MediaContext mc) 
        {
            bool fCreated = false; 
 
            using (CompositionEngineLock.Acquire())
            { 
                if (IsTransportConnected)
                {
                    mc.CreateChannels();
                    fCreated = true; 
                }
            } 
 
            return fCreated;
        } 

        /// 
        /// Reads a value from the registry to decide whether to disable the animation
        /// smoothing algorithm. 
        /// 
        ///  
        /// Critical - asserts registry permissions to read from HKEY_LOCAL_MACHINE. 
        /// Treat as safe - we only read a binary value used exclusively for Avalon.
        ///  
        /// 
        /// The code is only present in internal builds
        /// 
        [SecurityCritical, SecurityTreatAsSafe ] 
        private static void ReadAnimationSmoothingSetting()
        { 
#if PRERELEASE 
            // Acquire permissions to read the one key we care about from the registry
            RegistryPermission permission = new RegistryPermission( 
                RegistryPermissionAccess.Read,
                System.Security.AccessControl.AccessControlActions.View,
                @"HKEY_LOCAL_MACHINE\Software\Microsoft\Avalon.Graphics");
 
            permission.Assert();
 
            try 
            {
                RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Avalon.Graphics"); 
                if (key != null)
                {
                    object keyValue = key.GetValue("AnimationSmoothing");
 
                    // The Regkey now turns off AnimationSmoothing
                    s_animationSmoothing = !(keyValue is int && ((int)keyValue) == 0); 
                } 
            }
            finally 
            {
                RegistryPermission.RevertAssert();
            }
#endif 
        }
 
        ///  
        /// This deinitializes the MediaSystem and frees any resources that it maintains.
        ///  
        /// 
        /// Critical    -- results in the release of an unmanaged pointer to the current transport.
        /// TreatAsSafe -- shutting down the transport is considered a safe operation. Worst case
        ///                is that the client stops rendering Avalon content. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe ] 
        internal static void Shutdown(MediaContext mc) 
        {
            using (CompositionEngineLock.Acquire()) 
            {
                Debug.Assert(s_refCount > 0);
                _mediaContexts.Remove(mc);
 
                s_refCount--;
                if (0 == s_refCount) 
                { 
                    // We can shut-down.
                    // Debug.WriteLine("MediSystem::NotifyDisconnect Stop Transport\n"); 

                    if (IsTransportConnected)
                    {
                        DisconnectTransport(); 
                    }
 
                    HRESULT.Check(SafeNativeMethods.MilCompositionEngine_DeinitializePartitionManager()); 
                }
            } 
        }

        /// 
        /// Handle DWM messages that indicate that the state of the connection needs to change. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal static void NotifyRedirectionEnvironmentChanged() 
        {
            using (CompositionEngineLock.Acquire()) 
            {
                //
                // Let the MIL decide the transport type if the redirection environment
                // has changed. We will fall back to a local-only transport and presents 
                // using bitblts to make the rendered content available to graphics stream
                // clients if MIL fails to initialize the default transport. 
                // 

                HandleTransportParametersChange(); 
            }
        }

        ///  
        /// Analyze the most recently obtained transport parameters and decide
        /// if an attempt to connect or disconnect should be made. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private static void HandleTransportParametersChange() 
        {
            bool fIsConnected;
            UInt32 dwGeneration;
            bool forceSoftareForGraphicsStreamMagnifier; 

            HRESULT.Check(UnsafeNativeMethods.MilTransport_CreateTransportParameters( 
                true, // force local transport 
                out fIsConnected,
                out dwGeneration, 
                out forceSoftareForGraphicsStreamMagnifier));

            if (fIsConnected)
            { 
                // If the dwm's connection generation does not match ours we
                // need to recreate the connection with the new transport parameters. 
                // If the graphics stream client state changed, we also want to recycle the 
                // transport/UCE to ensure we are switching back to hw.
                if ((dwGeneration != s_lastGeneration) || 
                    (forceSoftareForGraphicsStreamMagnifier != s_forceSoftareForGraphicsStreamMagnifier))
                {
                    s_lastGeneration = dwGeneration;
                    s_forceSoftareForGraphicsStreamMagnifier = forceSoftareForGraphicsStreamMagnifier; 

                    DisconnectTransport(); 
 
                    ConnectTransport();
 
                    foreach (MediaContext mc in _mediaContexts)
                    {
                        mc.PostDisconnect();
                        mc.PostConnect(); 
                    }
                } 
            } 
            else
            { 
                // if we don't need to be connected disconnect the connection.
                DisconnectTransport();
                foreach (MediaContext mc in _mediaContexts)
                { 
                    mc.PostDisconnect();
                } 
            } 
        }
 
        /// 
        /// Connect the transport.
        /// 
        ///  
        ///   Critical - Creates a channel, calls methods performing elevations.
        ///   TreatAsSafe - Transport initialization is considered safe. Service channel 
        ///                 creation is safe. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private static void ConnectTransport()
        {
            if (IsTransportConnected)
            { 
                throw new System.InvalidOperationException(SR.Get(SRID.MediaSystem_OutOfOrderConnectOrDisconnect));
            } 
 
            //
            // Create a default transport to be used by this media system. 
            // If creation fails, fall back to a local transport.
            //

            HRESULT.Check(UnsafeNativeMethods.MilTransport_Create(out s_pConnection)); 

            // Create service channel used by global glyph cache. This channel is 
            // the first channel created for the app, and by creating it with 
            // a null channel reference it creates a new partition.
            // All subsequent channel creates will pass in a reference to this 
            // channel thus using its partition.
            s_serviceChannel = new DUCE.Channel(
                null,
                false,       // not out of band 
                false,       // is a layered window specific channel
                s_pConnection, 
                IntPtr.Zero 
                );
 
            IsTransportConnected = true;
        }

        ///  
        /// Disconnect the transport. If we are calling this function from a disconnect
        /// request we want to keep the service channel around. So that media contexts that 
        /// have not yet received disconnect event do not crash. 
        /// 
        ///  
        /// Critical - Closes a channel. Shuts down the transport.
        /// TreatAsSafe - Shutting down the transport is considered safe.
        ///               Closing the service channel is safe.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private static void DisconnectTransport() 
        { 
            if (!IsTransportConnected)
            { 
                return;
            }

            // Close global glyph cache channel. 
            s_serviceChannel.Close();
 
            HRESULT.Check(UnsafeNativeMethods.MilTransport_DisconnectTransport( 
                s_pConnection));
 
            // Release references to global glyph cache and service channel.
            s_serviceChannel = null;
            s_pConnection = IntPtr.Zero;
 
            IsTransportConnected = false;
        } 
 
        /// 
        /// Checks if to CAO have the same context affinity. This is for example important for 
        /// ContainerVisual.Children.Add to ensure that the scene graph is homogenously build out
        /// of object that have the same context affinity.
        /// 
        /// Reference to which to compare to. This argument is usually the this 
        /// pointer and can not be null.
        /// Object for which the check is performed. 
        ///  
        /// Example:
        /// 
        /// class Visual
        /// {
        ///     ...
        ///     void Add(Visual child) 
        ///     {
        ///         VerifyContext(this); 
        ///         AssertSameContext(this, child); 
        ///         ...
        ///     } 
        /// }
        ///
        /// Note that VerifyContext(A) AND AssertSameContext(A, B) implies that VerifyContext(B) holds. Hence you
        /// don't need to check the context for each argument if you assert the same context. 
        /// 
        internal static void AssertSameContext( 
            DispatcherObject reference, 
            DispatcherObject other)
        { 
            Debug.Assert(reference != null, "The reference object can not be null.");

            // DispatcherObjects may be created with the option of becoming unbound.
            // An unbound DO may be created without a Dispatcher or may detach from 
            // its Dispatcher (e.g., a Freezable).  Unbound DOs return null for their
            // Dispatcher and should be accepted anywhere. 
            if (other != null && 
                reference.Dispatcher != null &&
                other.Dispatcher != null && 
                reference.Dispatcher != other.Dispatcher)
            {
                throw new ArgumentException(SR.Get(SRID.MediaSystem_ApiInvalidContext));
            } 
        }
 
        ///  
        /// This flag indicates if the transport has been disabled by a session disconnect.
        /// If the transport has been disabled we need to defer all media system startup requests 
        /// until we get the next connect message
        /// 
        internal static bool IsTransportConnected
        { 
            get { return s_isConnected; }
            set { s_isConnected = value; } 
        } 

        ///  
        /// This flag indicates that we have forced the local-only transport. This might
        /// be a result of version negotiation or connection failures and will require
        /// fallback to a rendering mode that will make our content accessibile to GDI
        /// APIs -- to enable legacy remoting and magnification. 
        /// 
        ///  
        /// Critical because s_forceSoftareForGraphicsStreamMagnifier is security critical, but 
        /// only if it can be set (since that controls if rendering is sw/hw). Because
        /// this method does not allow setting s_forceSoftareForGraphicsStreamMagnifier, it cannot 
        /// be used to control rendering mode. Reading it is safe since this is information
        /// we volunteer anyhow in the tiering API.
        /// 
        internal static bool ForcedLocalTransport 
        {
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return s_forceSoftareForGraphicsStreamMagnifier; } 
        }
 
        /// 
        /// Returns the service channel for the current media system. This channel
        /// is used by the glyph cache infrastructure.
        ///  
        /// 
        /// Critical - Controlled unmanaged resource. 
        ///  
        internal static DUCE.Channel ServiceChannel
        { 
            [SecurityCritical]
            get { return s_serviceChannel; }
        }
 
        /// 
        /// Returns the pointer to the unmanaged transport object. 
        ///  
        /// 
        /// Critical - Controlled unmanaged resource. 
        /// 
        internal static IntPtr Connection
        {
            [SecurityCritical] 
            get { return s_pConnection; }
        } 
 
        internal static bool AnimationSmoothing
        { 
            get { return s_animationSmoothing; }
        }

        internal static Guid DeviceId 
        {
            get 
            { 
                return s_deviceId;
            } 
        }

        internal static long GenerationId
        { 
            get
            { 
                return s_lastGeneration; 
            }
        } 

        /// 
        /// Keeps track of how often MediaSystem.Startup is called. So that the MediaSystem can be shut down at the right
        /// point in time. 
        /// 
        private static int s_refCount = 0; 
 
        //private static bool s_lastWasDisconnect = false;
 
        private static ArrayList _mediaContexts = new ArrayList();

        private static long s_lastGeneration = 0;
 
        private static bool s_isConnected = false;
 
        ///  
        /// Service channel to serve global glyph cache.
        ///  
        /// 
        /// Critical - Controlled unmanaged resource.
        /// 
        [SecurityCritical] 
        private static DUCE.Channel s_serviceChannel;
 
        private static bool s_animationSmoothing = true; 

        private static Guid s_deviceId = Guid.NewGuid(); 

        /// 
        /// Pointer to the unmanaged transport object.
        ///  
        /// 
        /// Critical - Controlled unmanaged resource. 
        ///  
        [SecurityCritical]
        private static IntPtr s_pConnection; 

        /// 
        /// Indicates if a graphics stream client is present. If a graphics stream client is present,
        /// we drop back to sw rendering to enable the Vista magnifier. 
        /// 
        ///  
        /// Critical - controls rendering mode (hw/sw). 
        /// 
        [SecurityCritical] 
        private static bool s_forceSoftareForGraphicsStreamMagnifier;
     }
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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