StandardOleMarshalObject.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / CompMod / System / Runtime / InteropServices / StandardOleMarshalObject.cs / 2 / StandardOleMarshalObject.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

    namespace System.Runtime.InteropServices { 
    using System.Diagnostics; 
    using System;
    using Microsoft.Win32; 
    using System.Security;
    using System.Security.Permissions;

    ///  
    /// 
    ///  
    /// Replaces the standard CLR free-threaded marshaler with the standard OLE STA one.  This prevents the calls made into 
    /// our hosting object by OLE from coming in on threads other than the UI thread.
    /// 
    /// 
    [ComVisible(true)]
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Interoperability", "CA1403:AutoLayoutTypesShouldNotBeComVisible")]
    public class StandardOleMarshalObject : MarshalByRefObject, UnsafeNativeMethods.IMarshal { 

        protected StandardOleMarshalObject() { 
        } 

        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 
        private IntPtr GetStdMarshaller(ref Guid riid, int dwDestContext, int mshlflags) {
            IntPtr pStdMarshal = IntPtr.Zero;
            IntPtr pUnk = Marshal.GetIUnknownForObject(this);
            if (pUnk != IntPtr.Zero) { 
                try {
                    if (NativeMethods.S_OK == UnsafeNativeMethods.CoGetStandardMarshal(ref riid, pUnk, dwDestContext, IntPtr.Zero, mshlflags, out pStdMarshal)) { 
                        Debug.Assert(pStdMarshal != null, "Failed to get marshaller for interface '" +  riid.ToString() + "', CoGetStandardMarshal returned S_OK"); 
                        return pStdMarshal;
                    } 
                }
                finally {
                    Marshal.Release(pUnk);
                } 
            }
            throw new InvalidOperationException(SR.GetString(SR.StandardOleMarshalObjectGetMarshalerFailed, riid.ToString())); 
        } 

 

        /// 
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 
        int UnsafeNativeMethods.IMarshal.GetUnmarshalClass(ref Guid riid, IntPtr pv, int dwDestContext, IntPtr pvDestContext, int mshlflags, out Guid pCid){
 
            pCid = typeof(UnsafeNativeMethods.IStdMarshal).GUID; 
            return NativeMethods.S_OK;
        } 

        /// 
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 
        int UnsafeNativeMethods.IMarshal.GetMarshalSizeMax(ref Guid riid, IntPtr pv, int dwDestContext, IntPtr pvDestContext, int mshlflags, out int pSize) {
 
            // 98830 - GUID marshaling in StandardOleMarshalObject AVs on 64-bit 
            Guid riid_copy = riid;
            IntPtr pStandardMarshal = GetStdMarshaller(ref riid_copy, dwDestContext, mshlflags); 

            try {
                return UnsafeNativeMethods.CoGetMarshalSizeMax(out pSize, ref riid_copy, pStandardMarshal, dwDestContext, pvDestContext, mshlflags);
            } 
            finally {
                Marshal.Release(pStandardMarshal); 
            } 
        }
 
        /// 
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
        int UnsafeNativeMethods.IMarshal.MarshalInterface(object pStm, ref Guid riid, IntPtr pv, int dwDestContext, IntPtr pvDestContext, int mshlflags) { 

            // 206710 - caused by an AV on 64-bit, the same problem as in 98830 
            // The reason for making a copy here is that on 64-bit, the CLR marshaling infrastructure copies value types 
            // passed by-ref from managed to unmanaged even if they are blittable. To mimic x86 behavior where blittable
            // value types are simply pinned for the duration of the call and their address passed to unmanaged, 64-bit 
            // marshaler will always propagate the new contents of the value type back to managed. In this scenario where
            // the IID actually originated in unmanaged, it may result in attempting to write to read-only pages (standard
            // IIDs like IID_IDispatch live in a read-only section of ole32.dll).
            // 
            // 1. Unmanaged caller passes &ole32!IID_IDispatch
            // 2. This pointer is directly transformed to 'ref Guid' argument when entering managed. 
            // 3. Managed code calls a P/Invoke that takes 'ref Guid' 
            //    3a. The 'ref Guid' argument is dereferenced and copied to a temp stack location
            //    3b. The address of the temp stack location is passed to the P/Invoke 
            //    3c. When coming back from the P/Invoke, the contents of the temp stack location is copied back
            //        the 'ref Guid' argument, which is in fact the read-only ole32!IID_IDispatch
            //
            // This workaround can be removed in Dev10 as 64-bit marshaling is fixed in CLR 4.0. 

            Guid riid_copy = riid; 
            IntPtr pStandardMarshal = GetStdMarshaller(ref riid_copy, dwDestContext, mshlflags); 

            try { 
                return UnsafeNativeMethods.CoMarshalInterface(pStm, ref riid_copy, pStandardMarshal, dwDestContext, pvDestContext, mshlflags);
            }
            finally {
                Marshal.Release(pStandardMarshal); 
                if (pStm != null) {
                    Marshal.ReleaseComObject(pStm); 
                } 
            }
        } 

        /// 
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 
        int UnsafeNativeMethods.IMarshal.UnmarshalInterface(object pStm, ref Guid riid, out IntPtr ppv) {
            // this should never be called on this interface, but on the standard one handed back by the previous calls. 
            Debug.Fail("IMarshal::UnmarshalInterface should not be called."); 
            ppv = IntPtr.Zero;
            if (pStm != null) { 
                Marshal.ReleaseComObject(pStm);
            }
            return NativeMethods.E_NOTIMPL;
        } 

        ///  
        ///  
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
        int UnsafeNativeMethods.IMarshal.ReleaseMarshalData(object pStm) { 
            // this should never be called on this interface, but on the standard one handed back by the previous calls.
            Debug.Fail("IMarshal::ReleaseMarshalData should not be called.");
            if (pStm != null) {
                Marshal.ReleaseComObject(pStm); 
            }
            return NativeMethods.E_NOTIMPL; 
        } 

        ///  
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
        int UnsafeNativeMethods.IMarshal.DisconnectObject(int dwReserved) {
            // this should never be called on this interface, but on the standard one handed back by the previous calls. 
            Debug.Fail("IMarshal::DisconnectObject should not be called.");
            return NativeMethods.E_NOTIMPL; 
        } 
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

    namespace System.Runtime.InteropServices { 
    using System.Diagnostics; 
    using System;
    using Microsoft.Win32; 
    using System.Security;
    using System.Security.Permissions;

    ///  
    /// 
    ///  
    /// Replaces the standard CLR free-threaded marshaler with the standard OLE STA one.  This prevents the calls made into 
    /// our hosting object by OLE from coming in on threads other than the UI thread.
    /// 
    /// 
    [ComVisible(true)]
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Interoperability", "CA1403:AutoLayoutTypesShouldNotBeComVisible")]
    public class StandardOleMarshalObject : MarshalByRefObject, UnsafeNativeMethods.IMarshal { 

        protected StandardOleMarshalObject() { 
        } 

        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 
        private IntPtr GetStdMarshaller(ref Guid riid, int dwDestContext, int mshlflags) {
            IntPtr pStdMarshal = IntPtr.Zero;
            IntPtr pUnk = Marshal.GetIUnknownForObject(this);
            if (pUnk != IntPtr.Zero) { 
                try {
                    if (NativeMethods.S_OK == UnsafeNativeMethods.CoGetStandardMarshal(ref riid, pUnk, dwDestContext, IntPtr.Zero, mshlflags, out pStdMarshal)) { 
                        Debug.Assert(pStdMarshal != null, "Failed to get marshaller for interface '" +  riid.ToString() + "', CoGetStandardMarshal returned S_OK"); 
                        return pStdMarshal;
                    } 
                }
                finally {
                    Marshal.Release(pUnk);
                } 
            }
            throw new InvalidOperationException(SR.GetString(SR.StandardOleMarshalObjectGetMarshalerFailed, riid.ToString())); 
        } 

 

        /// 
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 
        int UnsafeNativeMethods.IMarshal.GetUnmarshalClass(ref Guid riid, IntPtr pv, int dwDestContext, IntPtr pvDestContext, int mshlflags, out Guid pCid){
 
            pCid = typeof(UnsafeNativeMethods.IStdMarshal).GUID; 
            return NativeMethods.S_OK;
        } 

        /// 
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 
        int UnsafeNativeMethods.IMarshal.GetMarshalSizeMax(ref Guid riid, IntPtr pv, int dwDestContext, IntPtr pvDestContext, int mshlflags, out int pSize) {
 
            // 98830 - GUID marshaling in StandardOleMarshalObject AVs on 64-bit 
            Guid riid_copy = riid;
            IntPtr pStandardMarshal = GetStdMarshaller(ref riid_copy, dwDestContext, mshlflags); 

            try {
                return UnsafeNativeMethods.CoGetMarshalSizeMax(out pSize, ref riid_copy, pStandardMarshal, dwDestContext, pvDestContext, mshlflags);
            } 
            finally {
                Marshal.Release(pStandardMarshal); 
            } 
        }
 
        /// 
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
        int UnsafeNativeMethods.IMarshal.MarshalInterface(object pStm, ref Guid riid, IntPtr pv, int dwDestContext, IntPtr pvDestContext, int mshlflags) { 

            // 206710 - caused by an AV on 64-bit, the same problem as in 98830 
            // The reason for making a copy here is that on 64-bit, the CLR marshaling infrastructure copies value types 
            // passed by-ref from managed to unmanaged even if they are blittable. To mimic x86 behavior where blittable
            // value types are simply pinned for the duration of the call and their address passed to unmanaged, 64-bit 
            // marshaler will always propagate the new contents of the value type back to managed. In this scenario where
            // the IID actually originated in unmanaged, it may result in attempting to write to read-only pages (standard
            // IIDs like IID_IDispatch live in a read-only section of ole32.dll).
            // 
            // 1. Unmanaged caller passes &ole32!IID_IDispatch
            // 2. This pointer is directly transformed to 'ref Guid' argument when entering managed. 
            // 3. Managed code calls a P/Invoke that takes 'ref Guid' 
            //    3a. The 'ref Guid' argument is dereferenced and copied to a temp stack location
            //    3b. The address of the temp stack location is passed to the P/Invoke 
            //    3c. When coming back from the P/Invoke, the contents of the temp stack location is copied back
            //        the 'ref Guid' argument, which is in fact the read-only ole32!IID_IDispatch
            //
            // This workaround can be removed in Dev10 as 64-bit marshaling is fixed in CLR 4.0. 

            Guid riid_copy = riid; 
            IntPtr pStandardMarshal = GetStdMarshaller(ref riid_copy, dwDestContext, mshlflags); 

            try { 
                return UnsafeNativeMethods.CoMarshalInterface(pStm, ref riid_copy, pStandardMarshal, dwDestContext, pvDestContext, mshlflags);
            }
            finally {
                Marshal.Release(pStandardMarshal); 
                if (pStm != null) {
                    Marshal.ReleaseComObject(pStm); 
                } 
            }
        } 

        /// 
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 
        int UnsafeNativeMethods.IMarshal.UnmarshalInterface(object pStm, ref Guid riid, out IntPtr ppv) {
            // this should never be called on this interface, but on the standard one handed back by the previous calls. 
            Debug.Fail("IMarshal::UnmarshalInterface should not be called."); 
            ppv = IntPtr.Zero;
            if (pStm != null) { 
                Marshal.ReleaseComObject(pStm);
            }
            return NativeMethods.E_NOTIMPL;
        } 

        ///  
        ///  
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
        int UnsafeNativeMethods.IMarshal.ReleaseMarshalData(object pStm) { 
            // this should never be called on this interface, but on the standard one handed back by the previous calls.
            Debug.Fail("IMarshal::ReleaseMarshalData should not be called.");
            if (pStm != null) {
                Marshal.ReleaseComObject(pStm); 
            }
            return NativeMethods.E_NOTIMPL; 
        } 

        ///  
        /// 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
        int UnsafeNativeMethods.IMarshal.DisconnectObject(int dwReserved) {
            // this should never be called on this interface, but on the standard one handed back by the previous calls. 
            Debug.Fail("IMarshal::DisconnectObject should not be called.");
            return NativeMethods.E_NOTIMPL; 
        } 
    }
} 


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