Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / MediaContextNotificationWindow.cs / 1407647 / MediaContextNotificationWindow.cs
//------------------------------------------------------------------------------
//
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Description:
// A wrapper for a top-level hidden window that is used to process
// messages broadcasted to top-level windows only (such as DWM's
// WM_DWMCOMPOSITIONCHANGED). If the WPF application doesn't have
// a top-level window (as it is the case for XBAP applications),
// such messages would have been ignored.
//
//-----------------------------------------------------------------------------
using System;
using System.Windows.Threading;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Media.Animation;
using System.Windows.Media.Composition;
using Microsoft.Win32;
using Microsoft.Internal;
using MS.Internal;
using MS.Internal.Interop;
using MS.Win32;
using System.Security;
using System.Security.Permissions;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
namespace System.Windows.Media
{
///
/// The MediaContextNotificationWindow class provides its owner
/// MediaContext with the ability to receive and forward window
/// messages broadcasted to top-level windows.
///
internal class MediaContextNotificationWindow : IDisposable
{
///
/// Initializes static variables for this class.
///
///
/// Critical - Sets the SecurityCritical static variables holding the message ids; calls RegisterWindowMessage.
/// TreatAsSafe - The message ids are not exposed; no external parameters are taken in.
///
[SecurityCritical, SecurityTreatAsSafe]
static MediaContextNotificationWindow()
{
s_channelNotifyMessage = UnsafeNativeMethods.RegisterWindowMessage("MilChannelNotify");
s_dwmRedirectionEnvironmentChanged = UnsafeNativeMethods.RegisterWindowMessage("DwmRedirectionEnvironmentChangedHint");
}
//+---------------------------------------------------------------------
//
// Internal Methods
//
//---------------------------------------------------------------------
#region Internal Methods
///
/// Sets the owner MediaContext and creates the notification window.
///
///
/// Critical - Creates an HwndWrapper and adds a hook.
/// TreatAsSafe: Critical data is not exposed.
///
[SecurityCritical, SecurityTreatAsSafe]
internal MediaContextNotificationWindow(MediaContext ownerMediaContext)
{
// Remember the pointer to the owner MediaContext that we'll forward the broadcasts to.
_ownerMediaContext = ownerMediaContext;
// Create a top-level, invisible window so we can get the WM_DWMCOMPOSITIONCHANGED
// and other DWM notifications that are broadcasted to top-level windows only.
HwndWrapper hwndNotification;
hwndNotification = new HwndWrapper(0, NativeMethods.WS_POPUP, 0, 0, 0, 0, 0, "MediaContextNotificationWindow", IntPtr.Zero, null);
_hwndNotificationHook = new HwndWrapperHook(MessageFilter);
_hwndNotification = new SecurityCriticalDataClass(hwndNotification);
_hwndNotification.Value.AddHook(_hwndNotificationHook);
_isDisposed = false;
//
// On Vista, we need to know when the Magnifier goes on and off
// in order to switch to and from software rendering because the
// Vista Magnifier cannot magnify D3D content. To receive the
// window message informing us of this, we must tell the DWM
// we are MIL content.
//
// The Win7 Magnifier can magnify D3D content so it's not an
// issue there. In fact, Win7 doesn't even send the WM.
//
// If the DWM is not running, this call will result in NoOp.
//
ChangeWindowMessageFilter(s_dwmRedirectionEnvironmentChanged, 1 /* MSGFLT_ADD */);
MS.Internal.HRESULT.Check(MilContent_AttachToHwnd(_hwndNotification.Value.Handle));
}
///
/// Critical - Calls dispose on the critical hwnd wrapper.
/// TreatAsSafe: It is safe to dispose the wrapper
///
[SecurityCritical, SecurityTreatAsSafe]
public void Dispose()
{
if (!_isDisposed)
{
//
// If DWM is not running, this call will result in NoOp.
//
MS.Internal.HRESULT.Check(MilContent_DetachFromHwnd(_hwndNotification.Value.Handle));
_hwndNotification.Value.Dispose();
_hwndNotificationHook = null;
_hwndNotification = null;
_ownerMediaContext = null;
_isDisposed = true;
GC.SuppressFinalize(this);
}
}
#endregion Internal Methods
//+----------------------------------------------------------------------
//
// Private Methods
//
//---------------------------------------------------------------------
#region Private Methods
///
/// Tells a channel to send notifications to a particular target's window.
///
///
/// The channel from which we want notifications.
///
///
/// Critical - Calls a critical channel method.
/// TreatAsSafe - We are associated with the window handle that we
/// are passing to the channel, so somebody already
/// decided that it's OK for us to interact with that
/// window. We also registered a window message so
/// that we can avoid collisions with other messages.
///
[SecurityCritical, SecurityTreatAsSafe]
internal void SetAsChannelNotificationWindow()
{
if (_isDisposed)
{
throw new ObjectDisposedException("MediaContextNotificationWindow");
}
_ownerMediaContext.Channel.SetNotificationWindow(_hwndNotification.Value.Handle, s_channelNotifyMessage);
}
///
/// If any of the interesting broadcast messages is seen, forward them to the owner MediaContext.
///
///
/// Critical: Calls into unmanaged code, uses sensitive HWND data
/// TreatAsSafe: No sensitive information is disclosed. It's safe to "attach" the window to the DWM.
///
[SecurityCritical, SecurityTreatAsSafe]
private IntPtr MessageFilter(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (_isDisposed)
{
throw new ObjectDisposedException("MediaContextNotificationWindow");
}
WindowMessage message = (WindowMessage)msg;
Debug.Assert(_ownerMediaContext != null);
if (message == WindowMessage.WM_DWMCOMPOSITIONCHANGED)
{
//
// We need to register as MIL content to receive the Vista Magnifier messages
// (see comments in ctor).
//
// We're going to attempt to attach to DWM every time the desktop composition
// state changes to ensure that we properly handle DWM crashing/restarting/etc.
//
MS.Internal.HRESULT.Check(MilContent_AttachToHwnd(_hwndNotification.Value.Handle));
}
else if (message == s_channelNotifyMessage)
{
_ownerMediaContext.NotifyChannelMessage();
}
else if (message == s_dwmRedirectionEnvironmentChanged)
{
MediaSystem.NotifyRedirectionEnvironmentChanged();
}
return IntPtr.Zero;
}
///
/// Critical: This code causes unmanaged code elevation
///
[SecurityCritical, SuppressUnmanagedCodeSecurity]
[DllImport(DllImport.MilCore)]
private static extern int MilContent_AttachToHwnd(
IntPtr hwnd
);
///
/// Critical: This code causes unmanaged code elevation
///
[SecurityCritical, SuppressUnmanagedCodeSecurity]
[DllImport(DllImport.MilCore)]
private static extern int MilContent_DetachFromHwnd(
IntPtr hwnd
);
///
/// Allow lower integrity applications to send specified window messages
/// in case we are elevated. Failure is non-fatal and on down-level
/// platforms this call will result in a no-op.
///
///
/// Critical -- Calls unsafe native methods GetModuleHandle and GetProcAddress.
/// Manually elevates unmanaged code permissions to pinvoke through
/// a function pointer.
///
[SecurityCritical]
private void ChangeWindowMessageFilter(WindowMessage message, uint flag)
{
// Find the address of ChangeWindowMessageFilter in user32.dll.
IntPtr user32Module = UnsafeNativeMethods.GetModuleHandle("user32.dll");
// Get the address of the function. If this fails it means the OS
// doesn't support this function, in which case we don't
// need to do anything further.
IntPtr functionAddress = UnsafeNativeMethods.GetProcAddressNoThrow(
new HandleRef(null, user32Module),
"ChangeWindowMessageFilter");
if (functionAddress != IntPtr.Zero)
{
// Convert the function pointer into a callable delegate and then call it
ChangeWindowMessageFilterNative function = Marshal.GetDelegateForFunctionPointer(
functionAddress,
typeof(ChangeWindowMessageFilterNative)) as ChangeWindowMessageFilterNative;
// In order to call the function we need unmanaged code access,
// because the function is native code.
(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Assert();
try
{
function(message, flag);
}
finally
{
SecurityPermission.RevertAssert();
}
}
}
///
/// Prototype for user32's ChangeWindowMessageFilter function, which we load dynamically on Vista+.
///
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate void ChangeWindowMessageFilterNative(WindowMessage message, uint flag);
#endregion Private Methods
//+----------------------------------------------------------------------
//
// Private Fields
//
//----------------------------------------------------------------------
#region Private Fields
private bool _isDisposed;
// The owner MediaContext
private MediaContext _ownerMediaContext;
// A top-level hidden window.
private SecurityCriticalDataClass _hwndNotification;
// The message filter hook for the top-level hidden window.
private HwndWrapperHook _hwndNotificationHook;
// The window message used to announce a channel notification.
private static WindowMessage s_channelNotifyMessage;
// We receive this when the Vista Magnifier goes on/off
private static WindowMessage s_dwmRedirectionEnvironmentChanged;
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Description:
// A wrapper for a top-level hidden window that is used to process
// messages broadcasted to top-level windows only (such as DWM's
// WM_DWMCOMPOSITIONCHANGED). If the WPF application doesn't have
// a top-level window (as it is the case for XBAP applications),
// such messages would have been ignored.
//
//-----------------------------------------------------------------------------
using System;
using System.Windows.Threading;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Media.Animation;
using System.Windows.Media.Composition;
using Microsoft.Win32;
using Microsoft.Internal;
using MS.Internal;
using MS.Internal.Interop;
using MS.Win32;
using System.Security;
using System.Security.Permissions;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
namespace System.Windows.Media
{
///
/// The MediaContextNotificationWindow class provides its owner
/// MediaContext with the ability to receive and forward window
/// messages broadcasted to top-level windows.
///
internal class MediaContextNotificationWindow : IDisposable
{
///
/// Initializes static variables for this class.
///
///
/// Critical - Sets the SecurityCritical static variables holding the message ids; calls RegisterWindowMessage.
/// TreatAsSafe - The message ids are not exposed; no external parameters are taken in.
///
[SecurityCritical, SecurityTreatAsSafe]
static MediaContextNotificationWindow()
{
s_channelNotifyMessage = UnsafeNativeMethods.RegisterWindowMessage("MilChannelNotify");
s_dwmRedirectionEnvironmentChanged = UnsafeNativeMethods.RegisterWindowMessage("DwmRedirectionEnvironmentChangedHint");
}
//+---------------------------------------------------------------------
//
// Internal Methods
//
//---------------------------------------------------------------------
#region Internal Methods
///
/// Sets the owner MediaContext and creates the notification window.
///
///
/// Critical - Creates an HwndWrapper and adds a hook.
/// TreatAsSafe: Critical data is not exposed.
///
[SecurityCritical, SecurityTreatAsSafe]
internal MediaContextNotificationWindow(MediaContext ownerMediaContext)
{
// Remember the pointer to the owner MediaContext that we'll forward the broadcasts to.
_ownerMediaContext = ownerMediaContext;
// Create a top-level, invisible window so we can get the WM_DWMCOMPOSITIONCHANGED
// and other DWM notifications that are broadcasted to top-level windows only.
HwndWrapper hwndNotification;
hwndNotification = new HwndWrapper(0, NativeMethods.WS_POPUP, 0, 0, 0, 0, 0, "MediaContextNotificationWindow", IntPtr.Zero, null);
_hwndNotificationHook = new HwndWrapperHook(MessageFilter);
_hwndNotification = new SecurityCriticalDataClass(hwndNotification);
_hwndNotification.Value.AddHook(_hwndNotificationHook);
_isDisposed = false;
//
// On Vista, we need to know when the Magnifier goes on and off
// in order to switch to and from software rendering because the
// Vista Magnifier cannot magnify D3D content. To receive the
// window message informing us of this, we must tell the DWM
// we are MIL content.
//
// The Win7 Magnifier can magnify D3D content so it's not an
// issue there. In fact, Win7 doesn't even send the WM.
//
// If the DWM is not running, this call will result in NoOp.
//
ChangeWindowMessageFilter(s_dwmRedirectionEnvironmentChanged, 1 /* MSGFLT_ADD */);
MS.Internal.HRESULT.Check(MilContent_AttachToHwnd(_hwndNotification.Value.Handle));
}
///
/// Critical - Calls dispose on the critical hwnd wrapper.
/// TreatAsSafe: It is safe to dispose the wrapper
///
[SecurityCritical, SecurityTreatAsSafe]
public void Dispose()
{
if (!_isDisposed)
{
//
// If DWM is not running, this call will result in NoOp.
//
MS.Internal.HRESULT.Check(MilContent_DetachFromHwnd(_hwndNotification.Value.Handle));
_hwndNotification.Value.Dispose();
_hwndNotificationHook = null;
_hwndNotification = null;
_ownerMediaContext = null;
_isDisposed = true;
GC.SuppressFinalize(this);
}
}
#endregion Internal Methods
//+----------------------------------------------------------------------
//
// Private Methods
//
//---------------------------------------------------------------------
#region Private Methods
///
/// Tells a channel to send notifications to a particular target's window.
///
///
/// The channel from which we want notifications.
///
///
/// Critical - Calls a critical channel method.
/// TreatAsSafe - We are associated with the window handle that we
/// are passing to the channel, so somebody already
/// decided that it's OK for us to interact with that
/// window. We also registered a window message so
/// that we can avoid collisions with other messages.
///
[SecurityCritical, SecurityTreatAsSafe]
internal void SetAsChannelNotificationWindow()
{
if (_isDisposed)
{
throw new ObjectDisposedException("MediaContextNotificationWindow");
}
_ownerMediaContext.Channel.SetNotificationWindow(_hwndNotification.Value.Handle, s_channelNotifyMessage);
}
///
/// If any of the interesting broadcast messages is seen, forward them to the owner MediaContext.
///
///
/// Critical: Calls into unmanaged code, uses sensitive HWND data
/// TreatAsSafe: No sensitive information is disclosed. It's safe to "attach" the window to the DWM.
///
[SecurityCritical, SecurityTreatAsSafe]
private IntPtr MessageFilter(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (_isDisposed)
{
throw new ObjectDisposedException("MediaContextNotificationWindow");
}
WindowMessage message = (WindowMessage)msg;
Debug.Assert(_ownerMediaContext != null);
if (message == WindowMessage.WM_DWMCOMPOSITIONCHANGED)
{
//
// We need to register as MIL content to receive the Vista Magnifier messages
// (see comments in ctor).
//
// We're going to attempt to attach to DWM every time the desktop composition
// state changes to ensure that we properly handle DWM crashing/restarting/etc.
//
MS.Internal.HRESULT.Check(MilContent_AttachToHwnd(_hwndNotification.Value.Handle));
}
else if (message == s_channelNotifyMessage)
{
_ownerMediaContext.NotifyChannelMessage();
}
else if (message == s_dwmRedirectionEnvironmentChanged)
{
MediaSystem.NotifyRedirectionEnvironmentChanged();
}
return IntPtr.Zero;
}
///
/// Critical: This code causes unmanaged code elevation
///
[SecurityCritical, SuppressUnmanagedCodeSecurity]
[DllImport(DllImport.MilCore)]
private static extern int MilContent_AttachToHwnd(
IntPtr hwnd
);
///
/// Critical: This code causes unmanaged code elevation
///
[SecurityCritical, SuppressUnmanagedCodeSecurity]
[DllImport(DllImport.MilCore)]
private static extern int MilContent_DetachFromHwnd(
IntPtr hwnd
);
///
/// Allow lower integrity applications to send specified window messages
/// in case we are elevated. Failure is non-fatal and on down-level
/// platforms this call will result in a no-op.
///
///
/// Critical -- Calls unsafe native methods GetModuleHandle and GetProcAddress.
/// Manually elevates unmanaged code permissions to pinvoke through
/// a function pointer.
///
[SecurityCritical]
private void ChangeWindowMessageFilter(WindowMessage message, uint flag)
{
// Find the address of ChangeWindowMessageFilter in user32.dll.
IntPtr user32Module = UnsafeNativeMethods.GetModuleHandle("user32.dll");
// Get the address of the function. If this fails it means the OS
// doesn't support this function, in which case we don't
// need to do anything further.
IntPtr functionAddress = UnsafeNativeMethods.GetProcAddressNoThrow(
new HandleRef(null, user32Module),
"ChangeWindowMessageFilter");
if (functionAddress != IntPtr.Zero)
{
// Convert the function pointer into a callable delegate and then call it
ChangeWindowMessageFilterNative function = Marshal.GetDelegateForFunctionPointer(
functionAddress,
typeof(ChangeWindowMessageFilterNative)) as ChangeWindowMessageFilterNative;
// In order to call the function we need unmanaged code access,
// because the function is native code.
(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Assert();
try
{
function(message, flag);
}
finally
{
SecurityPermission.RevertAssert();
}
}
}
///
/// Prototype for user32's ChangeWindowMessageFilter function, which we load dynamically on Vista+.
///
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate void ChangeWindowMessageFilterNative(WindowMessage message, uint flag);
#endregion Private Methods
//+----------------------------------------------------------------------
//
// Private Fields
//
//----------------------------------------------------------------------
#region Private Fields
private bool _isDisposed;
// The owner MediaContext
private MediaContext _ownerMediaContext;
// A top-level hidden window.
private SecurityCriticalDataClass _hwndNotification;
// The message filter hook for the top-level hidden window.
private HwndWrapperHook _hwndNotificationHook;
// The window message used to announce a channel notification.
private static WindowMessage s_channelNotifyMessage;
// We receive this when the Vista Magnifier goes on/off
private static WindowMessage s_dwmRedirectionEnvironmentChanged;
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PasswordPropertyTextAttribute.cs
- httpstaticobjectscollection.cs
- versioninfo.cs
- ContentValidator.cs
- Transform3DGroup.cs
- Console.cs
- altserialization.cs
- ObjectListItem.cs
- FontSizeConverter.cs
- UnknownWrapper.cs
- UInt64.cs
- HwndSourceParameters.cs
- TemplateControlBuildProvider.cs
- ErrorHandler.cs
- MetadataImporter.cs
- TcpTransportBindingElement.cs
- DocobjHost.cs
- PageStatePersister.cs
- XmlSchemaSet.cs
- Message.cs
- ReadOnlyMetadataCollection.cs
- EntityContainer.cs
- DefaultMemberAttribute.cs
- NodeInfo.cs
- Perspective.cs
- RayHitTestParameters.cs
- PropertyBuilder.cs
- BitmapEffect.cs
- BoolExpressionVisitors.cs
- FixedSOMPage.cs
- SiteMapDataSourceView.cs
- HtmlHistory.cs
- TemplateNodeContextMenu.cs
- SurrogateEncoder.cs
- ManifestBasedResourceGroveler.cs
- PlanCompilerUtil.cs
- NullableDecimalSumAggregationOperator.cs
- ValidationEventArgs.cs
- QuinticEase.cs
- ReceiveSecurityHeaderEntry.cs
- ParseNumbers.cs
- DataContractJsonSerializer.cs
- XmlWriterTraceListener.cs
- CodePageEncoding.cs
- WebPartCollection.cs
- Image.cs
- AssignDesigner.xaml.cs
- ExpressionParser.cs
- GZipDecoder.cs
- TreeViewEvent.cs
- AxWrapperGen.cs
- ClientTargetSection.cs
- CodeFieldReferenceExpression.cs
- Table.cs
- ComplexPropertyEntry.cs
- TransformerInfo.cs
- ProvideValueServiceProvider.cs
- HtmlTitle.cs
- ObjectStateEntry.cs
- SqlBinder.cs
- NameValuePair.cs
- ActiveXSite.cs
- ChannelOptions.cs
- AsymmetricSignatureDeformatter.cs
- ThreadAttributes.cs
- DocumentPage.cs
- Input.cs
- StringDictionaryCodeDomSerializer.cs
- CatalogPart.cs
- TextOnlyOutput.cs
- GregorianCalendarHelper.cs
- SystemIcons.cs
- ObjectItemAttributeAssemblyLoader.cs
- NamespaceCollection.cs
- MetadataArtifactLoaderCompositeFile.cs
- _HeaderInfo.cs
- ThicknessKeyFrameCollection.cs
- MarkerProperties.cs
- FontFamilyIdentifier.cs
- SiteMapSection.cs
- PersistChildrenAttribute.cs
- AutoScrollExpandMessageFilter.cs
- BitmapSource.cs
- RequiredFieldValidator.cs
- CollectionConverter.cs
- TextParagraphProperties.cs
- PackageStore.cs
- SystemNetworkInterface.cs
- AbstractDataSvcMapFileLoader.cs
- NullRuntimeConfig.cs
- WorkflowDispatchContext.cs
- LabelLiteral.cs
- PropertyTabChangedEvent.cs
- KeySpline.cs
- ManualResetEvent.cs
- CqlParserHelpers.cs
- EncryptedKeyHashIdentifierClause.cs
- SettingsSavedEventArgs.cs
- AppDomainGrammarProxy.cs
- PropertyGeneratedEventArgs.cs