EventProxy.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / EventProxy.cs / 1305600 / EventProxy.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2003
//
//  File:       eventproxy.cs 
//-----------------------------------------------------------------------------
#pragma warning disable 1634, 1691 // Allow suppression of certain presharp messages 
 
using System.Windows.Media;
using System; 
using MS.Internal;
using MS.Win32;
using System.Reflection;
using System.Collections; 
using System.Diagnostics;
using System.Security; 
using System.Security.Permissions; 
using System.Runtime.InteropServices;
using Microsoft.Internal; 
using MS.Internal.PresentationCore;

// TODOTODO Make our own namespace for internal stuff.
namespace System.Windows.Media 
{
    #region EventProxyDescriptor 
    [StructLayout(LayoutKind.Sequential)] 
    internal struct EventProxyDescriptor
    { 
        internal delegate void Dispose(
            ref EventProxyDescriptor pEPD
            );
 
        internal delegate int RaiseEvent(
            ref EventProxyDescriptor pEPD, 
            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer, 
            uint cb
            ); 

        internal Dispose pfnDispose;
        internal RaiseEvent pfnRaiseEvent;
 
        ///
        ///     Critical: calls GCHandle.get_Target which LinkDemands 
        ///     TreatAsSafe: can't pass in an arbitrary class, only EventProxyDescriptor.  Also, it's OK to dispose this. 
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        internal static void StaticDispose(ref EventProxyDescriptor pEPD)
        {
            Debug.Assert(((IntPtr)pEPD.m_handle) != IntPtr.Zero, "If this asserts fires: Why is it firing? It might be legal in future.");
            EventProxyWrapper epw = (EventProxyWrapper)(pEPD.m_handle.Target); 
            ((System.Runtime.InteropServices.GCHandle)(pEPD.m_handle)).Free();
        } 
 
        internal System.Runtime.InteropServices.GCHandle m_handle;
    } 
    #endregion

    #region EventProxyStaticPtrs
    ///  
    /// We need to keep the delegates alive.
    ///  
    internal static class EventProxyStaticPtrs 
    {
        static EventProxyStaticPtrs() 
        {
            EventProxyStaticPtrs.pfnDispose = new EventProxyDescriptor.Dispose(EventProxyDescriptor.StaticDispose);
            EventProxyStaticPtrs.pfnRaiseEvent = new EventProxyDescriptor.RaiseEvent(EventProxyWrapper.RaiseEvent);
 
        }
 
        internal static EventProxyDescriptor.Dispose pfnDispose; 
        internal static EventProxyDescriptor.RaiseEvent pfnRaiseEvent;
    } 
    #endregion

    #region EventProxyWrapper
    ///  
    /// Event proxy wrapper will relay events from unmanaged code to managed code
    ///  
    internal class EventProxyWrapper 
    {
        private WeakReference target; 

        #region Constructor

        private EventProxyWrapper(IInvokable invokable) 
        {
            target = new WeakReference(invokable); 
        } 

        #endregion 

        #region Verify

        private void Verify() 
        {
            if (target == null) 
            { 
                throw new System.ObjectDisposedException("EventProxyWrapper");
            } 
        }

        #endregion
 
        #region Public methods
 
        /// 
        ///     Critical: calls Marshal.GetHRForException which LinkDemands
        ///     TreatAsSafe: ok to return an hresult in partial trust 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        public int RaiseEvent(byte[] buffer, uint cb)
        { 
#pragma warning disable 6500
            try 
            { 
                Verify();
                IInvokable invokable = (IInvokable)target.Target; 
                if (invokable != null)
                {
                    invokable.RaiseEvent(buffer, (int)cb);
                } 
                else
                { 
                    // return E_HANDLE to notify that object is no longer alive 

                    return NativeMethods.E_HANDLE; 
                }
            }
            catch (Exception e)
            { 
                return Marshal.GetHRForException(e);
            } 
#pragma warning restore 6500 

            return NativeMethods.S_OK; 
        }

        #endregion
 
        #region Delegate Implemetations
        ///  
        ///     Critical: This code calls into handle to get Target which has a link demand 
        ///     TreatAsSafe: EventProxyWrapper is safe to expose
        ///  
        [SecurityCritical,SecurityTreatAsSafe]
        internal static EventProxyWrapper FromEPD(ref EventProxyDescriptor epd)
        {
            Debug.Assert(((IntPtr)epd.m_handle) != IntPtr.Zero, "Stream is disposed."); 
            System.Runtime.InteropServices.GCHandle handle = (System.Runtime.InteropServices.GCHandle)(epd.m_handle);
            return (EventProxyWrapper)(handle.Target); 
        } 

        internal static int RaiseEvent(ref EventProxyDescriptor pEPD, byte[] buffer, uint cb) 
        {
            EventProxyWrapper target = EventProxyWrapper.FromEPD(ref pEPD);
            if (target != null)
            { 
                return target.RaiseEvent(buffer, cb);
            } 
            else 
            {
                return NativeMethods.E_HANDLE; 
            }
        }

        #endregion 

        #region Static Create Method(s) 
 
        /// 
        ///     Critical: This code hooks up event sinks for unmanaged events 
        ///               It also calls into a native method via MILCreateEventProxy
        /// 
        [SecurityCritical]
        internal static SafeMILHandle CreateEventProxyWrapper(IInvokable invokable) 
        {
            if (invokable == null) 
            { 
                throw new System.ArgumentNullException("invokable");
            } 

            SafeMILHandle eventProxy = null;

            EventProxyWrapper epw = new EventProxyWrapper(invokable); 
            EventProxyDescriptor epd = new EventProxyDescriptor();
 
            epd.pfnDispose = EventProxyStaticPtrs.pfnDispose; 
            epd.pfnRaiseEvent = EventProxyStaticPtrs.pfnRaiseEvent;
 
            epd.m_handle = System.Runtime.InteropServices.GCHandle.Alloc(epw, System.Runtime.InteropServices.GCHandleType.Normal);

            HRESULT.Check(MILCreateEventProxy(ref epd, out eventProxy));
 
            return eventProxy;
        } 
 
        #endregion
 
        /// 
        ///     Critical: Elevates to unmanaged code permission
        /// 
        [SuppressUnmanagedCodeSecurity] 
        [SecurityCritical]
        [DllImport(DllImport.MilCore)] 
        private extern static int /* HRESULT */ MILCreateEventProxy(ref EventProxyDescriptor pEPD, out SafeMILHandle ppEventProxy); 
    }
    #endregion 
}

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