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 internal static class MediaSystem { ///to start up the media system and to /// shut down the 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ControlOperationInvoker.cs
- LocalizedNameDescriptionPair.cs
- XmlSchemaDatatype.cs
- HwndSourceKeyboardInputSite.cs
- CallContext.cs
- DependencyPropertyDescriptor.cs
- ServiceDescriptionImporter.cs
- ForceCopyBuildProvider.cs
- StreamAsIStream.cs
- FileAuthorizationModule.cs
- coordinator.cs
- MachineKeyValidationConverter.cs
- SplineKeyFrames.cs
- EntityDataSourceEntityTypeFilterItem.cs
- SelectionProviderWrapper.cs
- Matrix3D.cs
- ChineseLunisolarCalendar.cs
- TemplateBamlTreeBuilder.cs
- Rfc2898DeriveBytes.cs
- XmlEntityReference.cs
- SqlParameterCollection.cs
- Pipe.cs
- Models.cs
- TypeLoadException.cs
- Convert.cs
- CodeStatementCollection.cs
- NonSerializedAttribute.cs
- Timer.cs
- Assembly.cs
- BookmarkScope.cs
- DataGridPreparingCellForEditEventArgs.cs
- ListDictionary.cs
- ColorAnimationBase.cs
- DbMetaDataColumnNames.cs
- PrefixHandle.cs
- UniqueConstraint.cs
- UrlAuthFailedErrorFormatter.cs
- UseLicense.cs
- EventProxy.cs
- InitializationEventAttribute.cs
- ToolStripSeparatorRenderEventArgs.cs
- XamlPathDataSerializer.cs
- TableLayoutPanelCellPosition.cs
- TreeView.cs
- NativeMethods.cs
- SoapParser.cs
- Tracking.cs
- WindowsSlider.cs
- DataTable.cs
- SQlBooleanStorage.cs
- DrawingContextDrawingContextWalker.cs
- CredentialSelector.cs
- ArglessEventHandlerProxy.cs
- ApplicationContext.cs
- CustomAttributeSerializer.cs
- EditorAttribute.cs
- ClientOperationFormatterProvider.cs
- PropertyOrder.cs
- FileVersionInfo.cs
- ContentTextAutomationPeer.cs
- Tool.cs
- BitmapEffectDrawingContextWalker.cs
- RemotingService.cs
- CommandHelper.cs
- PriorityBindingExpression.cs
- StreamReader.cs
- FixedNode.cs
- InternalSafeNativeMethods.cs
- JpegBitmapDecoder.cs
- Triangle.cs
- DataSourceSelectArguments.cs
- XmlBufferReader.cs
- ControlParameter.cs
- HttpCacheParams.cs
- ObjRef.cs
- BrushConverter.cs
- ConfigurationSection.cs
- SoapObjectWriter.cs
- MeshGeometry3D.cs
- ConnectionManagementElement.cs
- WebPartUtil.cs
- SystemBrushes.cs
- BuilderElements.cs
- GeneralTransform3DCollection.cs
- XsdDuration.cs
- RowCache.cs
- OleDbReferenceCollection.cs
- RectIndependentAnimationStorage.cs
- PolicyStatement.cs
- StorageFunctionMapping.cs
- TextTreeTextBlock.cs
- BrowserDefinitionCollection.cs
- WorkflowWebService.cs
- XhtmlStyleClass.cs
- BitmapVisualManager.cs
- DataGridViewColumnCollection.cs
- BamlBinaryWriter.cs
- EditorAttributeInfo.cs
- WindowsPrincipal.cs
- PackageRelationshipCollection.cs