MediaSystem.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 / Core / 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.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) 
                {
                    //Debug.WriteLine("MediaSystem::NotifyDisconnect Start Transport\n");
                    if(ForceRecord)
                    { 
                        HRESULT.Check(MilCoreApi.MilConnection_RecordUCE());
                    } 
 
                    HRESULT.Check(SafeNativeMethods.MilCompositionEngine_InitializePartitionManager(
                                  0, // THREAD_PRIORITY_NORMAL 
                                  MIL_SCHEDULE_TYPE.MIL_SCHEDULE_UNTHROTTLED // use unthrottled scheduling because managed side throttles.
                                  ));

                    HRESULT.Check(UnsafeNativeMethods.MilTransport_InitializeConnectionManager( 
                                  IntPtr.Zero,
                                  out s_pTransportManager 
                                  )); 

                    bool fIsConnected; 
                    UInt32 dwGeneration;
                    IntPtr pTransportParameters = IntPtr.Zero;
                    UIntPtr cbTransportParameters = UIntPtr.Zero;
 
                    s_forcedLocalTransport = false;
 
                    HRESULT.Check(UnsafeNativeMethods.MilTransport_CreateTransportParameters( 
                        false, // fForcedLocalTransport
                        out fIsConnected, 
                        out dwGeneration,
                        out pTransportParameters,
                        out cbTransportParameters));
 
                    ConnectTransport(pTransportParameters, cbTransportParameters);
 
                    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 sync/same thread connection 
        /// 
        ///  
        /// Critical    -- gets and stores an unmanaged pointer to the sync connection and the sync packet transport. 
        /// 
        [SecurityCritical] 
        internal static IntPtr ConnectSyncTransport(out IntPtr pSyncPacketTransport)
        {
            IntPtr pSyncTransport = IntPtr.Zero;
 
            HRESULT.Check(UnsafeNativeMethods.MilSyncPacketTransport_Create(
                              s_pTransportManager, 
                              out pSyncPacketTransport)); 

 
            HRESULT.Check(UnsafeNativeMethods.MilTransport_CreateFromPacketTransport(
                              s_pTransportManager,
                              pSyncPacketTransport,
                              out pSyncTransport)); 

            return pSyncTransport; 
        } 

        internal static bool ConnectChannels(MediaContext mc) 
        {
            bool fCreated = false;

            using (CompositionEngineLock.Acquire()) 
            {
                if (IsTransportConnected) 
                { 
                    // When MediaContext connects, make sure that it gets current transform hint list.
                    UpdateTransformHintsInternal(mc); 

                    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(UnsafeNativeMethods.MilTransport_ShutDownConnectionManager(s_pTransportManager)); 
 
                    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. 
                //
 
                s_forcedLocalTransport = false;

                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; 
            IntPtr pTransportParameters = IntPtr.Zero; 
            UIntPtr cbTransportParameters = UIntPtr.Zero;
 
            HRESULT.Check(UnsafeNativeMethods.MilTransport_CreateTransportParameters(
                s_forcedLocalTransport,
                out fIsConnected,
                out dwGeneration, 
                out pTransportParameters,
                out cbTransportParameters 
                )); 

            if (fIsConnected) 
            {
                // if the dwm's connection generation does not match ours we
                // need to recreate the connection with the new transport parameters.
                if (dwGeneration != s_lastGeneration || s_forcedLocalTransport) 
                {
                    s_lastGeneration = dwGeneration; 
 
                    DisconnectTransport();
 
                    ConnectTransport(pTransportParameters, cbTransportParameters);

                    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(
            IntPtr pTransportParameters, 
            UIntPtr cbTransportParameters
            ) 
        { 
            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. 
            // 

            int hrConnect = UnsafeNativeMethods.MilTransport_Create( 
                s_pTransportManager,
                pTransportParameters,
                cbTransportParameters,
                out s_pConnection 
                );
 
            if (HRESULT.Failed(hrConnect)) 
            {
                if (!s_forcedLocalTransport) 
                {
                    //
                    // If the transport creation fails, fall back to a local transport
                    // and ensure that our rendered content is accessible through ntuser 
                    // redirection.
                    // 
 
                    s_forcedLocalTransport = true;
 
                    HandleTransportParametersChange();

                    Debug.Assert(s_serviceChannel != null);
                } 
                else
                { 
                    // 
                    // Failures to create forcibly local connections are fatal --
                    // -- there is no fallback plan from here. 
                    //

                    HRESULT.Check(hrConnect);
                } 
            }
            else 
            { 
                // 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;
 
                // Read the current list of transform hints for accessibility apps from UxSs.
                ReadTransformHints(); 
            } 
        }
 
        /// 
        /// Connect the local transport when the primary channel is TS.
        /// 
        ///  
        /// This transport is used for rendering layered windows in the local compositor
        /// when running under a TS session, so that they may be passed to win32k through 
        /// UpdateLayeredWindow to enable correct hit testing. 
        /// 
        ///  
        ///   Critical - Creates a channel, calls methods performing elevations.
        ///   TreatAsSafe - Transport initialization is considered safe. Service channel
        ///                 creation is safe.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private static void ConnectLocalTransport() 
        { 
            bool fIsConnected;
            UInt32 dwGeneration; 
            IntPtr pTransportParameters = IntPtr.Zero;
            UIntPtr cbTransportParameters = UIntPtr.Zero;

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

            HRESULT.Check(UnsafeNativeMethods.MilTransport_Create(
                              s_pTransportManager,
                              pTransportParameters, // pTransportParameters 
                              cbTransportParameters, // cbTransportParameters
                              out s_pLocalTransport 
                              )); 

            IsLocalTransportConnected = 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;
 
            // Disconnect additional local transport if there is one.
            if (IsLocalTransportConnected) 
            { 
                HRESULT.Check(UnsafeNativeMethods.MilTransport_DisconnectTransport(
                    s_pLocalTransport)); 
                s_pLocalTransport = IntPtr.Zero;
                IsLocalTransportConnected = false;
            }
 
            IsTransportConnected = false;
        } 
 
        /// 
        /// Reads the current list of transform hints for accessibility apps from UxSs. 
        /// If running on the downlevel client or if UxSs is not running, this method
        /// will leave the list empty.
        /// 
        ///  
        /// Critical - Calls methods performing elevation.
        /// TreatAsSafe - Reading transform hint list is safe. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private static void ReadTransformHints() 
        {
            UInt32 index = 0;
            MIL_MATRIX3X2D transform = new MIL_MATRIX3X2D();
 
            s_transformHints.Clear();
 
            while (0 == UnsafeNativeMethods.MilGraphicsStream_GetTransformHint(index, ref transform)) 
            {
                s_transformHints.Add(CompositionResourceManager.MIL_MATRIX3X2DToMatrix(ref transform)); 
                index++;
            }
        }
 
        /// 
        /// Copies current list of transform hints to the provided MediaContext object. 
        /// This method assumes that composition engline lock has been taken. 
        /// 
        private static void UpdateTransformHintsInternal(MediaContext mc) 
        {
            mc.TransformHints.Clear();

            foreach (Matrix m in s_transformHints) 
            {
                mc.TransformHints.Add(m); 
            } 
        }
 
        /// 
        /// Copies current list of transform hints to the provided MediaContext object.
        /// This method aquires composition engline lock.
        ///  
        internal static void UpdateTransformHints(MediaContext mc)
        { 
            using (CompositionEngineLock.Acquire()) 
            {
                UpdateTransformHintsInternal(mc); 
            }
        }

        ///  
        /// Handle transform hint update notifications.
        ///  
        internal static void NotifyTransformHintUpdate(long stamp) 
        {
            using (CompositionEngineLock.Acquire()) 
            {
                if (stamp - s_lastTransformHintStamp > 0)
                {
                    s_lastTransformHintStamp = stamp; 

                    // Read the current list of transform hints for accessibility apps from UxSs. 
                    ReadTransformHints(); 

                    // Notify media contexts in the system that transform hint update has occurred. 
                    foreach (MediaContext mc in _mediaContexts)
                    {
                        mc.PostTransformHintUpdate();
                    } 
                }
            } 
        } 

        ///  
        /// 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 compositing engine is using an in memory rdp pipe to simulate TS. 
        /// 
        ///  This flag has to be modified before the MediaSystem is started. 
        internal static bool ForceRecord
        { 
            get { return s_forceRecord; }
 
            set { s_forceRecord = value; } 
        }
 
        /// 
        /// 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; } 
        }

        private static bool IsLocalTransportConnected
        { 
            get { return s_isLocalConnected; }
            set { s_isLocalConnected = 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. 
        /// 
        internal static bool ForcedLocalTransport 
        { 
            get { return s_forcedLocalTransport; }
        } 

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

        ///  
        /// Returns the pointer to the unmanaged transport object.
        /// 
        /// 
        /// Critical - Controlled unmanaged resource. 
        /// 
        internal static IntPtr LocalTransport 
        { 
            [SecurityCritical]
            get 
            {
                using (CompositionEngineLock.Acquire())
                {
                    if (!IsLocalTransportConnected) 
                    {
                        ConnectLocalTransport(); 
                    } 
                    return s_pLocalTransport;
                } 
            }
        }

        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;

        private static bool s_forcedLocalTransport = false;
 
        private static bool s_isLocalConnected = false;
 
        private static bool s_forceRecord = 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;

        ///  
        /// Pointer to the local transport object for the TS layered window case
        ///  
        ///  
        /// Critical - Controlled unmanaged resource.
        ///  
        [SecurityCritical]
        private static IntPtr s_pLocalTransport;

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

        private static ArrayList s_transformHints = new ArrayList(); 
        private static long s_lastTransformHintStamp = 0;
    } 
} 


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