exports.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 / Graphics / include / exports.cs / 1305600 / exports.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// File: exports.cs 
//
// Description: 
//     Managed exports from MIL core. 
//---------------------------------------------------------------------------
 
using System;
using System.Collections;
using System.ComponentModel;
using System.Threading; 
using System.Windows;
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Media.Effects;
using System.Windows.Media.Media3D; 
using System.Runtime.InteropServices;
using System.Windows.Media.Animation;
using MS.Internal;
using MS.Internal.Interop; 
using MS.Utility;
using MS.Win32; 
using System.Diagnostics; 
using System.Collections.Generic;
using System.Security; 
using System.Security.Permissions;
using Microsoft.Internal;
using Microsoft.Win32.SafeHandles;
 
using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods;
using SafeNativeMethods=MS.Win32.PresentationCore.SafeNativeMethods; 
using HRESULT=MS.Internal.HRESULT; 
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID; 

/*
 *
 * For the time being the flat composition api will be implemented on 
 * top of milcore.h (the protocol api), this is only temporary we will
 * be adding type safe unmanaged exports to milcore.dll which will be 
 * be called from the static functions. 
 *
 */ 


namespace System.Windows.Media.Composition
{ 

    // enumeration of marshal types supported by the transport. 
    internal enum ChannelMarshalType 
    {
        ChannelMarshalTypeInvalid = 0x0, 
        ChannelMarshalTypeSameThread = 0x1,
        ChannelMarshalTypeCrossThread = 0x2
    };
 
    /// 
    /// Lock replacement till the CLR team gives us support to resolve the reentrancy issues 
    /// with the CLR lock. 
    /// 
    ///  
    /// Prefered usage pattern:
    ///
    /// 
    ///    using (CompositionEngineLock.Acquire()) 
    ///    {
    ///        ... 
    ///    } 
    /// 
    /// 
    /// If you don't use this pattern remember to have a try finally block to release the lock
    /// in the event of an exception.
    /// 
    internal struct CompositionEngineLock : IDisposable 
    {
        ///  
        /// Aquires the composition engine lock. 
        /// 
        ///  
        /// Critical - calls unmanaged code
        /// TreatAsSafe - all inputs validated, locking is safe
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal static CompositionEngineLock Acquire()
        { 
            UnsafeNativeMethods.MilCoreApi.EnterCompositionEngineLock(); 

            return new CompositionEngineLock(); 
        }

        /// 
        /// Releases the composition engine lock. Using Dispose enables the using syntax. 
        /// 
        ///  
        /// Critical - calls unmanaged code 
        /// TreatAsSafe - all inputs validated, unlocking is safe
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        public void Dispose()
        {
            UnsafeNativeMethods.MilCoreApi.ExitCompositionEngineLock(); 
        }
    } 
 

    ///  
    /// The following class only exists to clearly separate the DUCE APIs
    /// from the legacy resource APIs.
    /// 
    internal partial class DUCE 
    {
        ///  
        /// CopyBytes - Poor-man's mem copy.  Copies cbData from pbFrom to pbTo. 
        /// pbFrom and pbTo must be DWORD aligned, and cbData must be a multiple of 4.
        ///  
        ///  byte* pointing to the "to" array.  Must be DWORD aligned. 
        ///  byte* pointing to the "from" array.  Must be DWORD aligned. 
        ///  int - count of bytes to copy.  Must be a multiple of 4. 
        ///  
        ///     Critical: This code accesses an unsafe code block
        ///  
        [SecurityCritical] 
        internal static unsafe void CopyBytes(byte* pbTo,
                                              byte* pbFrom, 
                                              int cbData)
        {
            // We'd like to only handle QWORD aligned data, but the CLR can't enforce this.
            // If there's no data to copy, it's ok if the pointers aren't aligned 
            Debug.Assert((cbData == 0) || ((Int64)(IntPtr)pbFrom) % 4 == 0);
            Debug.Assert((cbData == 0) || ((Int64)(IntPtr)pbTo) % 4 == 0); 
            Debug.Assert(cbData % 4 == 0); 
            Debug.Assert(cbData >= 0);
 
            Int32* pCurFrom32 = (Int32*)pbFrom;
            Int32* pCurTo32 = (Int32*)pbTo;

            for (int i = 0; i < cbData / 4; i++) 
            {
                pCurTo32[i] = pCurFrom32[i]; 
            } 
        }
 
        /// 
        /// Critical - pinvoke wrappers
        /// 
        [SecurityCritical(SecurityCriticalScope.Everything), SuppressUnmanagedCodeSecurity] 
        private static class UnsafeNativeMethods
        { 
            [DllImport(DllImport.MilCore)] 
            internal static extern /*HRESULT*/ int MilResource_CreateOrAddRefOnChannel(
                IntPtr pChannel, 
                DUCE.ResourceType resourceType,
                ref DUCE.ResourceHandle hResource
                );
 
            [DllImport(DllImport.MilCore)]
            internal static extern /*HRESULT*/ int MilResource_DuplicateHandle( 
                IntPtr pSourceChannel, 
                DUCE.ResourceHandle original,
                IntPtr pTargetChannel, 
                ref DUCE.ResourceHandle duplicate
                );

            [DllImport(DllImport.MilCore, EntryPoint = "MilConnection_CreateChannel")]//CASRemoval: 
            internal static extern int MilConnection_CreateChannel(
                IntPtr pTransport, 
                IntPtr hChannel, 
                out IntPtr channelHandle);
 
            [DllImport(DllImport.MilCore, EntryPoint = "MilConnection_DestroyChannel")]//CASRemoval:
            internal static extern int MilConnection_DestroyChannel(
                IntPtr channelHandle);
 
            [DllImport(DllImport.MilCore, EntryPoint = "MilChannel_CloseBatch")]//CASRemoval:
            internal static extern int MilConnection_CloseBatch( 
                IntPtr channelHandle); 

            [DllImport(DllImport.MilCore, EntryPoint = "MilChannel_CommitChannel")]//CASRemoval: 
            internal static extern int MilConnection_CommitChannel(
                IntPtr channelHandle);

            [DllImport(DllImport.MilCore)]//CASRemoval: 
            internal static extern int WgxConnection_SameThreadPresent(
                IntPtr pConnection); 
 
            [DllImport(DllImport.MilCore, EntryPoint = "MilChannel_GetMarshalType")]
            internal static extern int MilChannel_GetMarshalType(IntPtr channelHandle, out ChannelMarshalType marshalType); 

            [DllImport (DllImport.MilCore, EntryPoint = "MilResource_SendCommand")]//CASRemoval:
            unsafe internal static extern int MilResource_SendCommand(
                byte *pbData, 
                uint cbSize,
                bool sendInSeparateBatch, 
                IntPtr pChannel); 

            [DllImport (DllImport.MilCore, EntryPoint = "MilChannel_BeginCommand")]//CASRemoval: 
            unsafe internal static extern int MilChannel_BeginCommand(
                IntPtr pChannel,
                byte *pbData,
                uint cbSize, 
                uint cbExtra
                ); 
 
            [DllImport (DllImport.MilCore, EntryPoint = "MilChannel_AppendCommandData")]//CASRemoval:
            unsafe internal static extern int MilChannel_AppendCommandData( 
                IntPtr pChannel,
                byte *pbData,
                uint cbSize
                ); 

            [DllImport (DllImport.MilCore, EntryPoint = "MilChannel_EndCommand")]//CASRemoval: 
            unsafe internal static extern int MilChannel_EndCommand( 
                IntPtr pChannel);
 
            [DllImport (DllImport.MilCore, EntryPoint = "MilResource_SendCommandMedia")]//CASRemoval:
            unsafe internal static extern int MilResource_SendCommandMedia(
                ResourceHandle handle,
                SafeMediaHandle pMedia, 
                IntPtr pChannel,
                bool  notifyUceDirect 
                ); 

            [DllImport (DllImport.MilCore, EntryPoint = "MilResource_SendCommandBitmapSource")]//CASRemoval: 
            unsafe internal static extern int MilResource_SendCommandBitmapSource(
                ResourceHandle handle,
                BitmapSourceSafeMILHandle /* IWICBitmapSource */ pBitmapSource,
                IntPtr pChannel); 

            [DllImport(DllImport.MilCore, EntryPoint = "MilResource_ReleaseOnChannel")]//CASRemoval: 
            internal static extern /*HRESULT*/ int MilResource_ReleaseOnChannel( 
                IntPtr pChannel,
                DUCE.ResourceHandle hResource, 
                out int deleted
                );

            [DllImport(DllImport.MilCore)] 
            internal static extern int MilChannel_SetNotificationWindow(
                IntPtr pChannel, 
                IntPtr hwnd, 
                WindowMessage message
                ); 

            [DllImport(DllImport.MilCore)]
            internal static extern int MilComposition_WaitForNextMessage(
                IntPtr pChannel, 
                int nCount,
                IntPtr[] handles, 
                int bWaitAll, 
                UInt32 waitTimeout,
                out int waitReturn 
                );

            [DllImport(DllImport.MilCore)]
            internal static extern int MilComposition_PeekNextMessage( 
                IntPtr pChannel,
                out MilMessage.Message message, 
                /* size_t */ IntPtr messageSize, 
                out int messageRetrieved
                ); 

            [DllImport(DllImport.MilCore, EntryPoint = "MilResource_GetRefCountOnChannel")]
            internal static extern /*HRESULT*/ int MilResource_GetRefCountOnChannel(
                IntPtr pChannel, 
                DUCE.ResourceHandle hResource,
                out uint refCount 
                ); 
        }
 
        /// 
        /// Define the value of an infinte wait in WaitForNextMessage.
        /// 
        internal const UInt32 waitInfinite = UInt32.MaxValue; 

        internal static class MilMessage 
        { 
            /// 
            /// The ID of each type of back-channel notification messages. 
            /// 
            internal enum Type
            {
                Invalid             = 0x00, 

                SyncFlushReply      = 0x01, 
                Caps                = 0x04, 
                PartitionIsZombie   = 0x06,
                SyncModeStatus      = 0x09, 
                Presented           = 0x0A,
                BadPixelShader      = 0x10,

                ForceDWORD          = unchecked((int)0xffffffff) 
            };
 
            [StructLayout(LayoutKind.Explicit, Pack = 1)] 
            internal struct CapsData
            { 
                [FieldOffset(0)] internal Int32 CommonMinimumCaps;
                [FieldOffset(4)] internal UInt32 DisplayUniqueness;
                [FieldOffset(8)] internal MilGraphicsAccelerationCaps Caps;
            }; 

            [StructLayout(LayoutKind.Explicit, Pack = 1)] 
            internal struct PartitionIsZombieStatus 
            {
                [FieldOffset(0)] internal int HRESULTFailureCode; 
            };

            [StructLayout(LayoutKind.Explicit, Pack = 1)]
            internal struct SyncModeStatus 
            {
                [FieldOffset(0)] internal int Enabled; 
            }; 

            [StructLayout(LayoutKind.Explicit, Pack = 1)] 
            internal struct Presented
            {
                [FieldOffset(0)] internal MIL_PRESENTATION_RESULTS PresentationResults;
                [FieldOffset(4)] internal int RefreshRate; 
                [FieldOffset(8)] internal long PresentationTime;
            }; 
 
            /// 
            /// The union of all known back-channel notification messages. 
            /// 
            [StructLayout(LayoutKind.Explicit, Pack = 1)]
            internal struct Message
            { 
                [FieldOffset(0)] internal Type Type;
                [FieldOffset(4)] internal int Reserved; 
                [FieldOffset(8)] internal CapsData Caps; 
                [FieldOffset(8)] internal PartitionIsZombieStatus HRESULTFailure;
                [FieldOffset(8)] internal Presented Presented; 
                [FieldOffset(8)] internal SyncModeStatus SyncModeStatus;
            };
        }
 
        ///
        /// A channel set is a container for a matched pair of channels, 
        /// one primary channel and out of band channel 
        ///
        internal struct ChannelSet 
        {
            internal Channel Channel;
            internal Channel OutOfBandChannel;
        } 

        ///  
        /// A Channel is a command pipe into a composition device. 
        /// The commands send through a Channel are not executed till
        /// Channel.Commit is called. Committing a Channel is an atomic operation. In 
        /// other words, all the commands are executed before the next frame is
        /// rendered.
        ///
        /// A channel is also a hard boundary for UCE resources. That means that UCE 
        /// resources created on one channel can not interact with resources on a different
        /// channel. 
        ///  
        internal sealed partial class Channel
        { 
            /// 
            /// Primary channel.
            /// 
            ///  
            /// Critical - Track usage of the channel pointer.
            ///  
            [SecurityCritical] 
            IntPtr _hChannel;
 
            private Channel _referenceChannel;
            private bool _isSynchronous;
            private bool _isOutOfBandChannel;
 
            IntPtr _pConnection;
 
            ///  
            /// Creates a channel and associates it with channel group (partition).
            /// New create channel will belong to the same partition as the given referenceChannel. 
            /// To create the very first channel in the group, use null argument.
            /// 
            /// 
            /// Critical - accesses critical resources (handles) 
            /// 
            [SecurityCritical] 
            public Channel(Channel referenceChannel, bool isOutOfBandChannel, IntPtr pConnection, bool isSynchronous) 
            {
                IntPtr referenceChannelHandle = IntPtr.Zero; 

                _referenceChannel = referenceChannel;
                _pConnection = pConnection;
                _isOutOfBandChannel = isOutOfBandChannel; 
                _isSynchronous = isSynchronous;
 
                if (referenceChannel != null) 
                {
                    referenceChannelHandle = referenceChannel._hChannel; 
                }

                HRESULT.Check(UnsafeNativeMethods.MilConnection_CreateChannel(
                    _pConnection, 
                    referenceChannelHandle,
                    out _hChannel)); 
 
            }
 

            /// 
            /// Commits the commands enqueued into the Channel.
            ///  
            /// 
            ///    Critical: This code calls into MilConnection_CommitChannel which causes an elevation 
            ///    TreatAsSafe: This commits operations to the channel. Committing to a channel is safe 
            /// 
            [SecurityCritical,SecurityTreatAsSafe] 
            internal void Commit()
            {
                if (_hChannel == IntPtr.Zero)
                { 
                    //
                    // If the channel has been closed, fail silently. This could happen 
                    // for the service channel if we are in disconnected state when more 
                    // that one media contexts are present and not all of them have finished
                    // processing the disconnect messages. 
                    //

                    return;
                } 

                HRESULT.Check(UnsafeNativeMethods.MilConnection_CommitChannel( 
                   _hChannel)); 
            }
 
            /// 
            /// Closes the current batch on the Channel.
            /// 
            ///  
            ///    Critical: This code calls into MilConnection_CloseBatch which causes an elevation
            ///    TreatAsSafe: Closing a batch is safe and nothing is exposed. Batches are in the 
            ///                 render thread, and can only be written to from the UI thread while 
            ///                 they're open using other SC/STAS methods on DUCE.Channel. Once closed,
            ///                 the only operation that can be done on a batch is Channel.Commit. 
            /// 
            [SecurityCritical,SecurityTreatAsSafe]
            internal void CloseBatch()
            { 
                if (_hChannel == IntPtr.Zero)
                { 
                    // 
                    // If the channel has been closed, fail silently. This could happen
                    // for the service channel if we are in disconnected state when more 
                    // that one media contexts are present and not all of them have finished
                    // processing the disconnect messages.
                    //
 
                    return;
                } 
 
                HRESULT.Check(UnsafeNativeMethods.MilConnection_CloseBatch(
                   _hChannel)); 
            }

            /// 
            ///   Flush the currently recorded commands to the target device and prepare 
            ///   to receive new commands. Block until last command was executed.
            ///  
            ///  
            ///   Critical - This code calls into MilComposition_SyncFlush which causes an elevation.
            ///   TreatAsSafe - The net effect is to wait until render completes. 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            internal void SyncFlush()
            { 
                if (_hChannel == IntPtr.Zero)
                { 
                    // 
                    // If the channel has been closed, fail silently. This could happen
                    // for the service channel if we are in disconnected state whhen more 
                    // that one media contexts are present and not all of them have finished
                    // processing the disconnect messages.
                    //
 
                    return;
                } 
 
                HRESULT.Check(MilCoreApi.MilComposition_SyncFlush(_hChannel));
 
            }

            /// 
            /// Commits the channel and then closes it. 
            /// 
            ///  
            /// Critical - This code calls into MilConnection_CommitChannel and 
            ///            MilConnection_DestroyChannel which causes an elevation.
            /// TreatAsSafe - Even if called prematurely, this will simply make all the subsequent 
            ///               channel operations fail (whether silently or by raising an exception).
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            internal void Close() 
            {
                if (_hChannel != IntPtr.Zero) 
                { 
                    HRESULT.Check(UnsafeNativeMethods.MilConnection_CloseBatch(_hChannel));
                    HRESULT.Check(UnsafeNativeMethods.MilConnection_CommitChannel(_hChannel)); 
                }

                _referenceChannel = null;
 
                if (_hChannel != IntPtr.Zero)
                { 
                    HRESULT.Check(UnsafeNativeMethods.MilConnection_DestroyChannel(_hChannel)); 

                    _hChannel = IntPtr.Zero; 
                }
            }

            ///  
            /// Commits the commands enqueued into the Channel.
            ///  
            ///  
            /// Critical    -- Calls into MilChannel_Present which causes an elevation.
            /// TreatAsSafe -- This call is only relevant to synchronous channels and causes the compositor 
            ///                associated with the synchronous channel to compose and present, which is
            ///                considered safe. Asynchronous channels no-op this call.
            /// 
            [SecurityCritical,SecurityTreatAsSafe] 
            internal void Present()
            { 
                HRESULT.Check(UnsafeNativeMethods.WgxConnection_SameThreadPresent(_pConnection)); 
            }
 
            /// 
            /// Internal only: CreateOrAddRefOnChannel addrefs the resource corresponding to the
            /// specified handle on the channel.
            ///  
            /// 
            /// Returns true iff the resource was created on the channel. The caller is responsible to 
            /// update the resource appropriately. 
            /// 
            ///  
            /// Critical - Calls into MilResource_CreateOrAddRefOnChannel which causes an elevation.
            /// TreatAsSafe - All inputs are safe wrappers, manipulating handle on the channel
            /// will only affect resources that belong to the current process.
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            internal bool CreateOrAddRefOnChannel(object instance, ref DUCE.ResourceHandle handle, DUCE.ResourceType resourceType) 
            { 
                bool handleNeedsCreation = handle.IsNull;
 
                Invariant.Assert(_hChannel != IntPtr.Zero);

                HRESULT.Check(UnsafeNativeMethods.MilResource_CreateOrAddRefOnChannel(
                    _hChannel, 
                    resourceType,
                    ref handle 
                    )); 

                if (EventTrace.IsEnabled(EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.PERF_LOW)) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.Event.CreateOrAddResourceOnChannel, EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.PERF_LOW, PerfService.GetPerfElementID(instance), _hChannel, (uint) handle, (uint) resourceType);
                }
 
                return handleNeedsCreation;
            } 
 
            /// 
            /// DuplicateHandle attempts to duplicate a handle from one channel to another. 
            /// Naturally, this can only work if both the source and target channels are
            /// within the same partition.
            /// 
            ///  
            /// It is the responsibility of the caller to commit the source channel
            /// to assure that duplication took place. 
            /// tables. 
            /// 
            ///  
            /// Returns the duplicated handle (valid on the target channel) or the null
            /// handle if duplication failed.
            /// 
            ///  
            ///     Critical - Calls security critical code.
            ///     TreatAsSafe - All inputs are safe wrappers, manipulating handle on the channel 
            ///                   will only affect resources that belong to the current process. 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal DUCE.ResourceHandle DuplicateHandle(
                DUCE.ResourceHandle original,
                DUCE.Channel targetChannel
                ) 
            {
                DUCE.ResourceHandle duplicate = DUCE.ResourceHandle.Null; 
 
                //Debug.WriteLine(string.Format("DuplicateHandle: Channel: {0}, Resource: {1}, Target channel: {2},  ", _hChannel, original._handle, targetChannel));
 
                HRESULT.Check(UnsafeNativeMethods.MilResource_DuplicateHandle(
                    _hChannel,
                    original,
                    targetChannel._hChannel, 
                    ref duplicate
                    )); 
 
                return duplicate;
            } 


            /// 
            /// Internal only: ReleaseOnChannel releases the resource corresponding to the specified 
            /// handle on the channel.
            ///  
            ///  
            /// Returns true iff the resource is not on this channel anymore.
            ///  
            /// 
            /// Critical - Calls security critical code.
            /// TreatAsSafe - All inputs are safe wrappers, manipulating handle on the channel
            /// will only affect resources that belong to the current process. 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal bool ReleaseOnChannel(DUCE.ResourceHandle handle) 
            {
                Invariant.Assert(_hChannel != IntPtr.Zero); 
                Debug.Assert(!handle.IsNull);

                //Debug.WriteLine(string.Format("ReleaseOnChannel: Channel: {0}, Resource: {1}", _hChannel, handle._handle));
 
                int releasedOnChannel;
 
                HRESULT.Check(UnsafeNativeMethods.MilResource_ReleaseOnChannel( 
                    _hChannel,
                    handle, 
                    out releasedOnChannel
                    ));

                if ((releasedOnChannel != 0) && EventTrace.IsEnabled(EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.PERF_LOW)) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.Event.ReleaseOnChannel, EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.PERF_LOW, _hChannel, (uint) handle); 
                } 

                return (releasedOnChannel != 0); 
            }

            /// 
            /// Internal only: GetRefCount returns the reference count of a resource 
            /// corresponding to the specified handle on the channel.
            ///  
            ///  
            /// Returns the ref count for a resource on this channel.
            ///  
            /// 
            /// Critical - Calls security critical code.
            /// TreatAsSafe - All inputs are safe wrappers, manipulating handle on the channel
            /// will only affect resources that belong to the current process. 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal uint GetRefCount(DUCE.ResourceHandle handle) 
            {
                Invariant.Assert(_hChannel != IntPtr.Zero); 
                Debug.Assert(!handle.IsNull);

                uint refCount;
 
                HRESULT.Check(UnsafeNativeMethods.MilResource_GetRefCountOnChannel(
                    _hChannel, 
                    handle, 
                    out refCount
                    )); 

                return refCount;
            }
 

            ///  
            /// IsConnected returns true if the channel is connected. 
            /// 
            /// 
            /// Critical - this code performs an elevation.
            /// TreatAsSafe - it's safe to return whether a channel is connected or not.
            ///
            internal bool IsConnected 
            {
                [SecurityCritical, SecurityTreatAsSafe] 
                get 
                {
                    return MediaContext.CurrentMediaContext.IsConnected; 
                }
            }

            ///  
            /// MarshalType returns the marshal type of the channel.
            ///  
            /// 
            /// Critical - this code performs an elevation.
            /// TreatAsSafe - it's safe to return a channel's marshal type. 
            ///
            internal ChannelMarshalType MarshalType
            {
                [SecurityCritical, SecurityTreatAsSafe] 
                get
                { 
                    Invariant.Assert(_hChannel != IntPtr.Zero); 

                    ChannelMarshalType marshalType; 
                    HRESULT.Check(UnsafeNativeMethods.MilChannel_GetMarshalType(
                        _hChannel,
                        out marshalType
                        )); 

                    return marshalType; 
                } 
            }
 
            /// 
            /// Returns whether the given channel is synchronous.
            /// 
            internal bool IsSynchronous 
            {
                get 
                { 
                    return _isSynchronous;
                } 
            }

            /// 
            /// Returns whether the given channel is an out of band channel. 
            /// 
            internal bool IsOutOfBandChannel 
            { 
                get
                { 
                    return _isOutOfBandChannel;
                }
            }
 
            /// 
            /// SendCommand sends a command struct through the composition thread. 
            ///  
            /// 
            /// Critical - This code performs an elevation. 
            /// TreatAsSafe - This method is safe, as Channel structures can only be created
            ///               by MediaContext and are hardened against invalid data.
            /// 
            [SecurityCritical, SecurityTreatAsSafe ] 
            unsafe internal void SendCommand(
                byte *pCommandData, 
                int cSize) 
            {
                SendCommand(pCommandData, cSize, false); 
            }

            /// 
            /// SendCommand sends a command struct through the composition thread. The 
            /// sendInSeparateBatch parameter determines whether the command is sent in the
            /// current open batch, or whether it will be added to a new and separate batch 
            /// which is then immediately closed, leaving the current batch untouched. 
            /// 
            ///  
            /// Critical - This code performs an elevation.
            /// TreatAsSafe - This method is safe, as Channel structures can only be created
            ///               by MediaContext and are hardened against invalid data.
            ///  
            [SecurityCritical, SecurityTreatAsSafe ]
            [System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions] 
            unsafe internal void SendCommand( 
                byte *pCommandData,
                int cSize, 
                bool sendInSeparateBatch)
            {
                checked
                { 
                    Invariant.Assert(pCommandData != (byte*)0 && cSize > 0);
 
                    int hr = HRESULT.S_OK; 

                    if (_hChannel == IntPtr.Zero) 
                    {
                        //
                        // If the channel has been closed, fail silently. This could happen
                        // for the service channel if we are in disconnected state when more 
                        // that one media contexts are present and not all of them have finished
                        // processing the disconnect messages. 
                        // 

                        return; 
                    }

                    //
                    // The pCommandData should not contain SecurityCritical resources; 
                    // SendSecurityCriticalCommand should be called instead.
                    // 
                    Invariant.Assert(!IsSecurityCriticalCommand(pCommandData)); 

                    try 
                    {
                        hr = UnsafeNativeMethods.MilResource_SendCommand(
                            pCommandData,
                            (uint)cSize, 
                            sendInSeparateBatch,
                            _hChannel); 
                    } 
                    catch (AccessViolationException)
                    { 
                        throw new ArgumentException(SR.Get(MS.Internal.PresentationCore.SRID.Channel_InvalidCommandBufferPointer));
                    }

                    HRESULT.Check(hr); 
                }
            } 
 
            /// 
            /// SendSecurityCriticalCommand sends a command struct to the composition thread. 
            /// It is used for sending commands which contain security critical fields like
            /// hwnd and pointers
            /// 
            ///  
            /// Critical - This code performs an elevation.
            ///  
            [SecurityCritical] 
            unsafe internal void SendSecurityCriticalCommand(
                byte *pCommandData, 
                int cSize,
                bool sendInSeparateBatch
                )
            { 
                checked
                { 
                    Invariant.Assert(pCommandData != (byte*)0 && cSize > 0); 

                    int hr = HRESULT.S_OK; 

                    if (_hChannel == IntPtr.Zero)
                    {
                        // 
                        // If the channel has been closed, fail silently. This could happen
                        // for the service channel if we are in disconnected state whhen more 
                        // that one media contexts are present and not all of them have finished 
                        // processing the disconnect messages.
                        // 

                        return;
                    }
 
                    //
                    // Make sure that this function is only called for SecurityCritical 
                    // command. Otherwise SendCommand should be called. 
                    //
                    Debug.Assert(IsSecurityCriticalCommand(pCommandData)); 

                    try
                    {
                        hr = UnsafeNativeMethods.MilResource_SendCommand( 
                            pCommandData,
                            (uint)cSize, 
                            sendInSeparateBatch, 
                            _hChannel);
                    } 
                    catch (AccessViolationException)
                    {
                        throw new ArgumentException(SR.Get(SRID.Channel_InvalidCommandBufferPointer));
                    } 

                    HRESULT.Check(hr); 
                } 
            }
 
            /// 
            /// BeginCommand opens a command on a channel
            /// 
            ///  
            /// Critical - This code performs an elevation.
            /// TreatAsSafe - This method is safe, as Channel structures can only be created 
            ///               by MediaContext and are hardened against invalid data. 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            unsafe internal void BeginCommand(
                byte *pbCommandData,
                int cbSize,
                int cbExtra) 
            {
                checked 
                { 
                    Invariant.Assert(cbSize > 0);
 
                    int hr = HRESULT.S_OK;

                    if (_hChannel == IntPtr.Zero)
                    { 
                        //
                        // If the channel has been closed, fail silently. This could happen 
                        // for the service channel if we are in disconnected state whhen more 
                        // that one media contexts are present and not all of them have finished
                        // processing the disconnect messages. 
                        //

                        return;
                    } 

                    try 
                    { 
                        hr = UnsafeNativeMethods.MilChannel_BeginCommand(
                            _hChannel, 
                            pbCommandData,
                            (uint)cbSize,
                            (uint)cbExtra
                            ); 
                    }
                    catch (AccessViolationException) 
                    { 
                        throw new ArgumentException(SR.Get(SRID.Channel_InvalidCommandBufferPointer));
                    } 

                    HRESULT.Check(hr);
                }
            } 

            ///  
            /// AppendCommandData appends data to an open command on a channel 
            /// 
            ///  
            /// Critical - This code performs an elevation.
            /// TreatAsSafe - This method is safe, as Channel structures can only be created
            ///               by MediaContext and are hardened against invalid data.
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            unsafe internal void AppendCommandData( 
                byte *pbCommandData, 
                int cbSize)
            { 
                checked
                {
                    Invariant.Assert(pbCommandData != (byte*)0 && cbSize > 0);
 
                    int hr = HRESULT.S_OK;
 
                    if (_hChannel == IntPtr.Zero) 
                    {
                        // 
                        // If the channel has been closed, fail silently. This could happen
                        // for the service channel if we are in disconnected state whhen more
                        // that one media contexts are present and not all of them have finished
                        // processing the disconnect messages. 
                        //
 
                        return; 
                    }
 
                    try
                    {
                        hr = UnsafeNativeMethods.MilChannel_AppendCommandData(
                            _hChannel, 
                            pbCommandData,
                            (uint)cbSize 
                            ); 
                    }
                    catch (AccessViolationException) 
                    {
                        throw new ArgumentException(SR.Get(SRID.Channel_InvalidCommandBufferPointer));
                    }
 
                    HRESULT.Check(hr);
                } 
            } 

            ///  
            /// EndCommand closes an open command on a channel
            /// 
            ///
            /// Critical - this code performs an elevation. 
            /// TreatAsSafe - it's safe to end a command in a well known channel.
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal void EndCommand()
            { 
                if (_hChannel == IntPtr.Zero)
                {
                    //
                    // If the channel has been closed, fail silently. This could happen 
                    // for the service channel if we are in disconnected state whhen more
                    // that one media contexts are present and not all of them have finished 
                    // processing the disconnect messages. 
                    //
 
                    return;
                }

                HRESULT.Check(UnsafeNativeMethods.MilChannel_EndCommand(_hChannel)); 
            }
 
            ///  
            /// SendCommand that creates an slave bitmap resource
            ///  
            /// 
            /// Critical - this code performs an elevation.
            /// 
            [SecurityCritical] 
            internal void SendCommandBitmapSource(
                DUCE.ResourceHandle imageHandle, 
                BitmapSourceSafeMILHandle pBitmapSource 
                )
            { 
                Invariant.Assert(pBitmapSource != null && !pBitmapSource.IsInvalid);
                Invariant.Assert(_hChannel != IntPtr.Zero);

                HRESULT.Check(UnsafeNativeMethods.MilResource_SendCommandBitmapSource( 
                    imageHandle,
                    pBitmapSource, 
                    _hChannel)); 
            }
 
            /// 
            /// SendCommand that creates an slave media resource
            /// 
            ///  
            /// Critical - this code performs an elevation.
            ///  
            [SecurityCritical] 
            internal void SendCommandMedia(
                DUCE.ResourceHandle mediaHandle, 
                SafeMediaHandle pMedia,
                bool notifyUceDirect
                )
            { 
                Invariant.Assert(pMedia != null && !pMedia.IsInvalid);
 
                Invariant.Assert(_hChannel != IntPtr.Zero); 

                HRESULT.Check(UnsafeNativeMethods.MilResource_SendCommandMedia( 
                    mediaHandle,
                    pMedia,
                    _hChannel,
                    notifyUceDirect 
                    ));
            } 
 
            /// 
            /// Specifies the window and window message to be sent when messages 
            /// become available in the back channel.
            /// 
            /// 
            /// The target of the notification messages. If this parameter is null 
            /// then the channel stop sending window messages.
            ///  
            ///  
            /// The window message ID. If the hwnd parameter is null then this
            /// parameter is ignored. 
            /// 
            /// 
            /// Critical        - Passes a window handle to native code. This will
            ///                   cause milcore to periodically post the specified 
            ///                   message to the specified window. The caller is
            ///                   safe if it owns the window and the message was 
            ///                   registered with RegisterMessage. 
            /// 
            [SecurityCritical] 
            internal void SetNotificationWindow(IntPtr hwnd, WindowMessage message)
            {
                Invariant.Assert(_hChannel != IntPtr.Zero);
 
                HRESULT.Check(UnsafeNativeMethods.MilChannel_SetNotificationWindow(
                    _hChannel, 
                    hwnd, 
                    message
                    )); 
            }

            /// 
            /// Waits until a message is available on this channel. The message 
            /// can be later retrieved with the PeekNextMessage method.
            ///  
            ///  
            /// The method may return with no available messages if the channel
            /// is disconnected while waiting. 
            /// 
            /// 
            /// Critical        - Blocks the thread until the channel receives
            ///                   a message. This is unsafe if done by any 
            ///                   component other than the owner of the channel
            ///                   because the channel may not send any 
            ///                   messages, in which case the function will 
            ///                   never return. Only the owner of the channel
            ///                   knows whether a message can be reasonably 
            ///                   expected to eventually be sent.
            /// 
            [SecurityCritical]
            internal void WaitForNextMessage() 
            {
                int waitReturn; 
 
                HRESULT.Check(UnsafeNativeMethods.MilComposition_WaitForNextMessage(
                    _hChannel, 
                    0,
                    null,
                    1, /* true */
                    waitInfinite, 
                    out waitReturn
                    )); 
            } 

            ///  
            /// Gets the next available message on this channel. This method
            /// does not wait if a message is not immediately available.
            /// 
            ///  
            /// Receives the message.
            ///  
            ///  
            /// True if a message was retrieved, false otherwise.
            ///  
            /// 
            /// Critical        - Removes a message from the channel. This is
            ///                   unsafe if done by any component other than
            ///                   the owner of the channel because eating 
            ///                   messages may result in the process hanging.
            ///                   Also has an unsafe block, but that is safe 
            ///                   to callers because we just need it to use 
            ///                   the sizeof operator.
            ///  
            [SecurityCritical]
            internal bool PeekNextMessage(out MilMessage.Message message)
            {
                Invariant.Assert(_hChannel != IntPtr.Zero); 

                int messageRetrieved; 
 
                checked
                { 
                    unsafe
                    {
                        HRESULT.Check(UnsafeNativeMethods.MilComposition_PeekNextMessage(
                            _hChannel, 
                            out message,
                            (IntPtr)sizeof(MilMessage.Message), 
                            out messageRetrieved 
                            ));
                    } 
                }

                return (messageRetrieved != 0);
            } 
        }
 
        ///  
        /// The Resource structure encapsulates the functionality
        /// required to hold on to a UCE resource. A resource can be sent to a 
        /// channel by calling CreateOrAddRefOnChannel. The resource can be deleted
        /// from a channel by calling ReleaseOnChannel.
        ///
        /// With resources the handle management is completely hidden from the caller. 
        /// 
        internal struct Resource 
        { 
            public static readonly Resource Null = new Resource(DUCE.ResourceHandle.Null);
 
            private DUCE.ResourceHandle _handle;
#if DEBUG
            private Channel _debugOnly_Channel;
#endif 

            ///  
            /// THIS IS A TEMPORARY API; DO NOT USE FOR ANYTHING ELSE. 
            /// Creates a resource from a type and ResourceHandle.
            /// This is currently only used for some hwnd interop code in the VisualManager. 
            /// 
            public Resource(DUCE.ResourceHandle h)
            {
                _handle = h; 
#if DEBUG
                _debugOnly_Channel = null; 
#endif 
            }
 
            /// 
            /// CreatesOrAddRefs the resource on the specified channel.
            /// 
            public bool CreateOrAddRefOnChannel(object instance, Channel channel, DUCE.ResourceType type) 
            {
                Debug.Assert(channel != null); 
#if DEBUG 
                _debugOnly_Channel = channel;
#endif 

                return channel.CreateOrAddRefOnChannel(instance, ref _handle, type);
            }
 

 
            ///  
            /// Releases the resource from the specified channel.
            /// Returns true if the resource is not anymore on the specified channel 
            /// otherwise false.
            /// 
            /// 
            /// Returns true iff the resource is not used on the specified channel anymore. 
            /// 
            public bool ReleaseOnChannel(Channel channel) 
            { 
                Debug.Assert(channel != null);
#if DEBUG 
                Debug.Assert(_debugOnly_Channel == channel);
#endif
                if (channel.ReleaseOnChannel(_handle))
                { 
                    _handle = DUCE.ResourceHandle.Null;
                    return true; 
                } 
                return false;
            } 

            /// 
            /// Checks if a resource was created on the specified channel.
            ///  
            public bool IsOnChannel(Channel channel)
            { 
#if DEBUG 
                Debug.Assert(_debugOnly_Channel == channel);
#endif 
                return !_handle.IsNull;
            }

 
            /// 
            /// Returns the real UInt32 handle. 
 
            public DUCE.ResourceHandle Handle { get { return _handle; } }
        } 

        /// 
        /// ResourceHandle currently encapsulates an unmanaged resource handle.
        ///  
        [StructLayout(LayoutKind.Explicit)]
        internal struct ResourceHandle 
        { 
            public static readonly ResourceHandle Null = new ResourceHandle(0);
 
            public static explicit operator uint(ResourceHandle r)
            {
                return r._handle;
            } 

            [FieldOffset(0)] 
            private UInt32 _handle; 
            public ResourceHandle(UInt32 handle) { _handle = handle; }
 
            /// 
            /// Checks if the handle is null.
            /// 
            public bool IsNull { get { return (_handle == 0); } } 
        }
 
        ///  
        /// This is a generic map that maps a key to a value. It is heavily optimized
        /// for a single entry. 
        /// 
        /// 
        /// We are using this map to map a resource onto multple channels. This is non-optimal
        /// solution. The map is currently used by the MultiChannelResource. Eventually, when all 
        /// the UCE underlyings are in place, we will be able to remove the MultiChannelResource.
        ///  
        internal struct Map 
        {
            ///  
            /// Struct for single entry.
            /// 
            private struct Entry
            { 
                public Entry(object k, ValueType v)
                { 
                    _key = k; 
                    _value = v;
                } 

                public object _key;
                public ValueType _value;
            } 

            private const int FOUND_IN_INLINE_STORAGE = -1; 
            private const int NOT_FOUND = -2; 

            // This data structure is optimized for single entry. _first is the one entry that we inline 
            // into the struct for that purpose.
            private Entry _first;
            // All other entries go into the generic _others list.
            private List _others; 

            public bool IsEmpty() 
            { 
                if (_first._key != null)
                { 
                    return false;
                }

                if (_others != null) 
                {
                    return false; 
                } 

                return true; 
            }

            /// 
            /// Finds the index of the entry with the specified key. Returns FOUND_IN_INLINE_STORAGE if the 
            /// key is stored in the _first inlined entry and NOT_FOUND if the key could not be found.
            /// Otherwise the method returns the index into the _others list. 
            ///  
            private int Find(object key)
            { 
                int index = NOT_FOUND; // Not found.

                if (_first._key != null)
                { 
                    if (_first._key == key)
                    { 
                        index = FOUND_IN_INLINE_STORAGE; // It's stored in our inlined storage. 
                    }
                    else 
                    {
                        if (_others != null)
                        {
                            for (int i = 0; i < _others.Count; i++) 
                            {
                                if (_others[i]._key == key) 
                                { 
                                    index = i;
                                    break; 
                                }
                            }
                        }
                    } 
                }
#if DEBUG 
                else 
                {
                    Debug.Assert(_others == null, "There shouldn't be anything stored in the others array."); 
                }
#endif

                return index; 
            }
 
            ///  
            /// Associates a key with the specified value. If the entry already exits the old value is overriden.
            ///  
            public void Set(object key, ValueType value)
            {
                int index = Find(key);
 
                if (index == FOUND_IN_INLINE_STORAGE)
                { 
                    _first._value = value; 
                }
                else 
                {
                    if (index == NOT_FOUND)
                    {
                        if (_first._key == null) 
                        {
                            _first = new Entry(key, value); 
                        } 
                        else
                        { 
                            if (_others == null)
                            {
                                _others = new List(2); // by default we have two entries in the extra storage.
                            } 

                            _others.Add(new Entry(key, value)); 
                        } 
                    }
                    else 
                    {
                        _others[index] = new Entry(key, value);
                    }
                } 
            }
 
            ///  
            /// Removes an entry from the map. Returns true if the entry to the specified index existed and was removed
            /// otherwise false. 
            /// 
            public bool Remove(object key)
            {
                int index = Find(key); 

                if (index == FOUND_IN_INLINE_STORAGE) 
                { 
                    if (_others != null)
                    { 
                        Debug.Assert(_others.Count > 0);
                        int j = _others.Count-1;
                        _first = _others[j];
                        if (j == 0) // Only one entry in the array. 
                        {
                            _others = null; 
                        } 
                        else
                        { 
                            _others.RemoveAt(j);
                        }
                    }
                    else 
                    {
                    _first = new Entry(); 
 
                    }
 
                    return true;
                }
                else
                { 
                    if (index >= 0)
                    { 
                        if (_others.Count == 1) 
                        {
                            Debug.Assert(index == 0); 
                            _others = null;
                        }
                        else
                        { 
                            _others.RemoveAt(index);
                        } 
 
                        return true;
                    } 
                }
                return false;
            }
 
            /// 
            /// Gets the value for the specified key. If the entry for the specified key could not 
            /// be found the Get method returns false otherwise true. 
            /// 
            public bool Get(object key, out ValueType value) 
            {
                int index = Find(key);

                value = default(ValueType); 

                if (index == FOUND_IN_INLINE_STORAGE) 
                { 
                    value = _first._value;
                    return true; 
                }
                else
                {
                    if (index >= 0) 
                    {
                        value = _others[index]._value; 
                        return true; 
                    }
                    else 
                    {
                        return false;
                    }
                } 
            }
 
            ///  
            /// Gets the object count in the map.
            ///  
            public int Count()
            {
                if (_first._key == null)
                { 
                    return 0;
                } 
                else if (_others == null) 
                {
                    return 1; 
                }
                else
                {
                    return _others.Count + 1; 
                }
            } 
 
            /// 
            /// Gets the object at a given index. 
            /// 
            public object Get(int index)
            {
                if (index >= Count()) 
                {
                    return null; 
                } 

                if (index == 0) 
                {
                    return _first._key;
                }
 
                return _others[index - 1]._key;
            } 
 
        }
 
        /// 
        /// This is a generic map that maps a key to a value. It is heavily optimized
        /// for a single entry.
        ///  
        /// 
        /// We are using this map to map a resource onto multple channels. This is non-optimal 
        /// solution. The map is currently used by the MultiChannelResource. Eventually, when all 
        /// the UCE underlyings are in place, we will be able to remove the MultiChannelResource.
        ///  
        internal struct Map
        {
            /// 
            /// Struct for single entry. 
            /// 
            private struct Entry 
            { 
                public Entry(object k, DUCE.ResourceHandle v)
                { 
                    _key = k;
                    _value = v;
                }
 
                public object _key;
                public DUCE.ResourceHandle _value; 
            } 

            private const int FOUND_IN_INLINE_STORAGE = -1; 
            private const int NOT_FOUND = -2;

            // This data structure is optimized for single entry. _head is the one entry that we inline
            // into the struct for that purpose.  If there are more than one entries, we store a list of 
            // entries in _head._key and DUCE.ResourceHandle.Null in _value.
            private Entry _head; 
 
            public bool IsEmpty()
            { 
                return _head._key == null;
            }

            ///  
            /// Finds the index of the entry with the specified key. Returns FOUND_IN_INLINE_STORAGE if the
            /// key is stored in the _head inlined entry and NOT_FOUND if the key could not be found. 
            /// Otherwise the method returns the index into the "others" list. 
            /// 
            private int Find(object key) 
            {
                int index = NOT_FOUND; // Not found.

                if (_head._key != null) 
                {
                    if (_head._key == key) 
                    { 
                        index = FOUND_IN_INLINE_STORAGE; // It's stored in our inlined storage.
                    } 
                    else
                    {
                        if (_head._value.IsNull)
                        { 
                            List others = (List)(_head._key);
 
                            for (int i = 0; i < others.Count; i++) 
                            {
                                if (others[i]._key == key) 
                                {
                                    index = i;
                                    break;
                                } 
                            }
                        } 
                    } 
                }
 
                return index;
            }

            ///  
            /// Associates a key with the specified value. If the entry already exits the old value is overriden.
            ///  
            public void Set(object key, DUCE.ResourceHandle value) 
            {
                int index = Find(key); 

                if (index == FOUND_IN_INLINE_STORAGE)
                {
                    _head._value = value; 
                }
                else 
                { 
                    if (index == NOT_FOUND)
                    { 
                        // The key was not found.
                        // Is the Map empty?
                        if (_head._key == null)
                        { 
                            _head = new Entry(key, value);
                        } 
                        else 
                        {
                            // The Map isn't empty - does it have 1 entry (!_value.IsNull) or more? 
                            if (!_head._value.IsNull)
                            {
                                // There's 1 entry - allocate a list...
                                List others = new List(2); // by default we have two entries in the extra storage. 

                                // ...move the old single entry into the List... 
                                others.Add(_head); 
                                // ...add the new entry...
                                others.Add(new Entry(key, value)); 

                                // ... and replace the single entry
                                _head._key = others;
                                _head._value = DUCE.ResourceHandle.Null; 

                            } 
                            else 
                            {
                                // There's already a List - simply add the new entry to the list. 
                                ((List)(_head._key)).Add(new Entry(key, value));
                            }
                        }
                    } 
                    else
                    { 
                        ((List)(_head._key))[index] = new Entry(key, value); 
                    }
                } 
            }

            /// 
            /// Removes an entry from the map. Returns true if the entry to the specified index existed and was removed 
            /// otherwise false.
            ///  
            public bool Remove(object key) 
            {
                int index = Find(key); 

                if (index == FOUND_IN_INLINE_STORAGE)
                {
                    _head = new Entry(); 

                    return true; 
                } 
                else
                { 
                    if (index >= 0)
                    {
                        List others = (List)_head._key;
 
                        // If the Count() is 1, index would either have been FOUND_IN_INLINE_STORAGE or
                        // NOT_FOUND, so Count() must be 2 or more. 
                        // If it is exactly 2, this means that after removal there will only be one 
                        // value left, which will be stored in _head.
                        if (Count() == 2) 
                        {
                            Debug.Assert(index <= 1);

                            // If the index is 0, we remove 0 and store 1 in _head. 
                            // If the index is 1, we remove 1 and store 0 in _head.
 
                            _head = others[1 - index]; 
                        }
                        else 
                        {
                            others.RemoveAt(index);
                        }
 
                        return true;
                    } 
                } 
                return false;
            } 

            /// 
            /// Gets the value for the specified key. If the entry for the specified key could not
            /// be found the Get method returns false otherwise true. 
            /// 
            public bool Get(object key, out DUCE.ResourceHandle value) 
            { 
                int index = Find(key);
 
                value = DUCE.ResourceHandle.Null;

                if (index == FOUND_IN_INLINE_STORAGE)
                { 
                    value = _head._value;
                    return true; 
                } 
                else
                { 
                    if (index >= 0)
                    {
                        value = ((List)_head._key)[index]._value;
                        return true; 
                    }
                    else 
                    { 
                        return false;
                    } 
                }
            }

            ///  
            /// Gets the object count in the map.
            ///  
            public int Count() 
            {
                if (_head._key == null) 
                {
                    return 0;
                }
                else if (!_head._value.IsNull) 
                {
                    return 1; 
                } 
                else
                { 
                    return ((List)_head._key).Count;
                }
            }
 
            /// 
            /// Gets the object at a given index. 
            ///  
            public object Get(int index)
            { 
                if ((index >= Count()) || (index < 0))
                {
                    return null;
                } 

                if (Count() == 1) 
                { 
                    Debug.Assert(index == 0);
                    return _head._key; 
                }

                return ((List)_head._key)[index]._key;
            } 

        } 
 
        /// 
        /// ShareableDUCEMultiChannelResource class - this class simply wraps a MultiChannelResource, 
        /// enabling it to be shared/handed off/etc via reference semantics.
        /// Note that this is ~8 bytes larger than the struct MultiChannelResource.
        /// 
        internal class ShareableDUCEMultiChannelResource 
        {
            public MultiChannelResource _duceResource; 
        } 

 
        /// 
        /// A multi-channel resource encapsulates a resource that can be used on multiple channels at the same time.
        /// 
        internal struct MultiChannelResource 
        {
            private Map _map; 
 
            /// 
            /// CreatesOrAddRefs the resource on the specified channel. 
            /// 
            /// 
            /// 
            /// Returns true iff the resource is not used on the specified channel anymore. 
            /// 
            /// The method is not synchronized. If the resource is used in a multi-threaded scenario, the 
            /// caller is responsible for taking a lock before calling CreateOrAddRefOnChannel or ReleaseOnChannel. 
            /// 
            public bool CreateOrAddRefOnChannel(object instance, Channel channel, DUCE.ResourceType type) 
            {
                Debug.Assert(channel != null);
                DUCE.ResourceHandle handle;
                bool inmap = _map.Get(channel, out handle); 

                bool created = channel.CreateOrAddRefOnChannel(instance, ref handle, type); 
 
                if (!inmap)
                { 
                    _map.Set(channel, handle);
                }

                return created; 
            }
 
            ///  
            /// Attempts to duplicate a handle to the specified target channel.
            ///  
            /// 
            /// The idea here is to attempt to find a compatible channel among
            /// the channels this resource has been marshalled to.
            ///  
            /// The channel to duplicate the handle from.
            /// The channel to duplicate the handle to. 
            public DUCE.ResourceHandle DuplicateHandle(Channel sourceChannel, Channel targetChannel) 
            {
                Debug.Assert(sourceChannel != null); 
                DUCE.ResourceHandle duplicate = DUCE.ResourceHandle.Null;

                DUCE.ResourceHandle handle = DUCE.ResourceHandle.Null;
                bool found = _map.Get(sourceChannel, out handle); 
                Debug.Assert(found);
 
                // 
                // The multi channel resource should not exist on the target channel.
                // Our current implementation only keeps a map of the channel and the handle 
                // so only one instance of this resource can be on one channel.
                //
                Debug.Assert(!(_map.Get(targetChannel, out duplicate)));
 
                duplicate = sourceChannel.DuplicateHandle(handle, targetChannel);
 
                if (!duplicate.IsNull) 
                {
                    _map.Set(targetChannel, duplicate); 
                }

                return duplicate;
            } 

            ///  
            /// Releases the resource from the specified channel. 
            /// Returns true if the resource is not anymore on the specified channel
            /// otherwise false. 
            /// 
            /// 
            /// The method is not synchronized. If the resource is used in a multi-threaded scenario, the
            /// caller is responsible for taking a lock before calling CreateOrAddRefOnChannel or ReleaseOnChannel. 
            /// 
            ///  
            /// Returns true iff the resource is not used on the specified channel anymore. 
            /// 
            public bool ReleaseOnChannel(Channel channel) 
            {
                Debug.Assert(channel != null);

                DUCE.ResourceHandle handle; 

                bool found = _map.Get(channel, out handle); 
                Debug.Assert(found); 

                if (channel.ReleaseOnChannel(handle)) 
                {
                    //
                    // The handle isn't used on the specified channel anymore. Therefore
                    // we can reclaim the handle. 
                    _map.Remove(channel);
                    return true; 
                } 
                return false;
            } 

            /// 
            /// Returns the ResourceHandle for this resource on the specified channel.
            ///  
            public DUCE.ResourceHandle GetHandle(Channel channel)
            { 
                DUCE.ResourceHandle h; 

                if (channel != null) 
                {
                    _map.Get(channel, out h);
                }
                else 
                {
                    h = ResourceHandle.Null; 
                } 
                return h;
            } 

            /// 
            /// Checks if a resource was created on the specified channel.
            ///  
            public bool IsOnChannel(Channel channel)
            { 
                return !GetHandle(channel).IsNull; 
            }
 
            /// 
            /// Checks if a resource was created on any channel.
            /// 
            public bool IsOnAnyChannel 
            {
                get 
                { 
                    return !_map.IsEmpty();
                } 
            }

            public int GetChannelCount()
            { 
                return _map.Count();
            } 
 
            public DUCE.Channel GetChannel(int index)
            { 
                return _map.Get(index) as DUCE.Channel;
            }

 
            public uint GetRefCountOnChannel(Channel channel)
            { 
                Debug.Assert(channel != null); 

                DUCE.ResourceHandle handle; 

                bool found = _map.Get(channel, out handle);
                Debug.Assert(found);
 
                return channel.GetRefCount(handle);
            } 
        } 

        internal static class CompositionNode 
        {
            // -----------------------------------------------------------------------------------------------------------------------
            // Public imports for composition nodes.
            // 
            /// 
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            /// 
            [SecurityCritical,SecurityTreatAsSafe] 
            internal static void SetTransform(
                DUCE.ResourceHandle hCompositionNode,
                DUCE.ResourceHandle hTransform,
                Channel channel) 
            {
                DUCE.MILCMD_VISUAL_SETTRANSFORM command; 
 
                command.Type = MILCMD.MilCmdVisualSetTransform;
                command.Handle = hCompositionNode; 
                command.hTransform = hTransform;

                unsafe
                { 
                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_VISUAL_SETTRANSFORM) 
                        );
                } 
            }


            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            ///  
            [SecurityCritical,SecurityTreatAsSafe]
            internal static void SetEffect( 
                DUCE.ResourceHandle hCompositionNode,
                DUCE.ResourceHandle hEffect,
                Channel channel)
            { 
                DUCE.MILCMD_VISUAL_SETEFFECT command;
 
                command.Type = MILCMD.MilCmdVisualSetEffect; 
                command.Handle = hCompositionNode;
                command.hEffect = hEffect; 

                unsafe
                {
                    channel.SendCommand( 
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VISUAL_SETEFFECT) 
                        ); 
                }
            } 


            /// 
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            ///  
            [SecurityCritical,SecurityTreatAsSafe] 
            internal static void SetCacheMode(
                DUCE.ResourceHandle hCompositionNode, 
                DUCE.ResourceHandle hCacheMode,
                Channel channel)
            {
                DUCE.MILCMD_VISUAL_SETCACHEMODE command; 

                command.Type = MILCMD.MilCmdVisualSetCacheMode; 
                command.Handle = hCompositionNode; 
                command.hCacheMode = hCacheMode;
 
                unsafe
                {
                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_VISUAL_SETCACHEMODE)
                        ); 
                } 
            }
 
            /// 
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void SetOffset( 
                DUCE.ResourceHandle hCompositionNode, 
                double offsetX,
                double offsetY, 
                Channel channel)
            {
                DUCE.MILCMD_VISUAL_SETOFFSET command;
                command.Type = MILCMD.MilCmdVisualSetOffset; 
                command.Handle = hCompositionNode;
                command.offsetX = offsetX; 
                command.offsetY = offsetY; 

                unsafe 
                {
                    channel.SendCommand(
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VISUAL_SETOFFSET) 
                        );
                } 
            } 

            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal static void SetContent(
                DUCE.ResourceHandle hCompositionNode, 
                DUCE.ResourceHandle hContent, 
                Channel channel)
            { 
                DUCE.MILCMD_VISUAL_SETCONTENT command;

                command.Type = MILCMD.MilCmdVisualSetContent;
                command.Handle = hCompositionNode; 
                command.hContent = hContent;
 
                unsafe 
                {
                    channel.SendCommand( 
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VISUAL_SETCONTENT)
                        );
                } 
            }
 
            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void SetAlpha(
                DUCE.ResourceHandle hCompositionNode, 
                double alpha,
                Channel channel) 
            { 
                DUCE.MILCMD_VISUAL_SETALPHA command;
 
                command.Type = MILCMD.MilCmdVisualSetAlpha;
                command.Handle = hCompositionNode;
                command.alpha = alpha;
 
                unsafe
                { 
                    channel.SendCommand( 
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VISUAL_SETALPHA) 
                        );
                }
            }
 
            /// 
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal static void SetAlphaMask(
                DUCE.ResourceHandle hCompositionNode,
                DUCE.ResourceHandle hAlphaMaskBrush,
                Channel channel) 
            {
                DUCE.MILCMD_VISUAL_SETALPHAMASK command; 
 
                command.Type = MILCMD.MilCmdVisualSetAlphaMask;
                command.Handle = hCompositionNode; 
                command.hAlphaMask = hAlphaMaskBrush;

                unsafe
                { 
                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_VISUAL_SETALPHAMASK) 
                        );
                } 
            }

            /// 
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            ///  
            [SecurityCritical, SecurityTreatAsSafe] 
            internal static void SetScrollableAreaClip(
                DUCE.ResourceHandle hCompositionNode, 
                Rect? clip,
                Channel channel)
            {
                DUCE.MILCMD_VISUAL_SETSCROLLABLEAREACLIP command; 

                command.Type = MILCMD.MilCmdVisualSetScrollableAreaClip; 
                command.Handle = hCompositionNode; 
                command.IsEnabled = (uint) (clip.HasValue ? 1 : 0);
 
                if (clip.HasValue)
                {
                    command.Clip = clip.Value;
                } 
                else
                { 
                    command.Clip = Rect.Empty; 
                }
 
                unsafe
                {
                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_VISUAL_SETSCROLLABLEAREACLIP)
                        ); 
                } 
            }
 
            /// 
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void SetClip( 
                DUCE.ResourceHandle hCompositionNode, 
                DUCE.ResourceHandle hClip,
                Channel channel) 
            {
                DUCE.MILCMD_VISUAL_SETCLIP command;

                command.Type = MILCMD.MilCmdVisualSetClip; 
                command.Handle = hCompositionNode;
                command.hClip = hClip; 
 
                unsafe
                { 
                    channel.SendCommand(
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VISUAL_SETCLIP)
                        ); 
                }
            } 
 
            /// 
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void SetRenderOptions( 
                DUCE.ResourceHandle hCompositionNode,
                MilRenderOptions renderOptions, 
                Channel channel) 
            {
                DUCE.MILCMD_VISUAL_SETRENDEROPTIONS command; 

                command.Type = MILCMD.MilCmdVisualSetRenderOptions;
                command.Handle = hCompositionNode;
                command.renderOptions = renderOptions; 

                unsafe 
                { 
                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_VISUAL_SETRENDEROPTIONS)
                        );
                }
 
            }
 
            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void RemoveChild(
                DUCE.ResourceHandle hCompositionNode, 
                DUCE.ResourceHandle hChild,
                Channel channel) 
            { 
                DUCE.MILCMD_VISUAL_REMOVECHILD command;
 
                command.Type = MILCMD.MilCmdVisualRemoveChild;
                command.Handle = hCompositionNode;
                command.hChild = hChild;
 
                unsafe
                { 
                    channel.SendCommand( 
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VISUAL_REMOVECHILD) 
                        );
                }
            }
 
            /// 
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal static void RemoveAllChildren(
                DUCE.ResourceHandle hCompositionNode,
                Channel channel)
            { 
                DUCE.MILCMD_VISUAL_REMOVEALLCHILDREN command;
 
                command.Type = MILCMD.MilCmdVisualRemoveAllChildren; 
                command.Handle = hCompositionNode;
 
                unsafe
                {
                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_VISUAL_REMOVEALLCHILDREN)
                        ); 
                } 
            }
 
            /// 
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void InsertChildAt( 
                DUCE.ResourceHandle hCompositionNode, 
                DUCE.ResourceHandle hChild,
                UInt32 iPosition, 
                Channel channel)
            {
                DUCE.MILCMD_VISUAL_INSERTCHILDAT command;
                Debug.Assert(!hCompositionNode.IsNull); 

                command.Type = MILCMD.MilCmdVisualInsertChildAt; 
                command.Handle = hCompositionNode; 
                command.hChild = hChild;
                command.index = iPosition; 

                unsafe
                {
                    channel.SendCommand( 
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VISUAL_INSERTCHILDAT) 
                        ); 
                }
            } 

            /// 
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal static void SetGuidelineCollection( 
                DUCE.ResourceHandle hCompositionNode,
                DoubleCollection guidelinesX, 
                DoubleCollection guidelinesY,
                Channel channel
                )
            { 
                checked
                { 
                    DUCE.MILCMD_VISUAL_SETGUIDELINECOLLECTION command; 
                    Debug.Assert(!hCompositionNode.IsNull);
 
                    int countX = guidelinesX == null ? 0 : guidelinesX.Count;
                    int countY = guidelinesY == null ? 0 : guidelinesY.Count;
                    int countXY = countX + countY;
 
                    command.Type = MILCMD.MilCmdVisualSetGuidelineCollection;
                    command.Handle = hCompositionNode; 
                    command.countX = (UInt16)countX; 
                    command.countY = (UInt16)countY;
 
                    if (countX == 0 && countY == 0)
                    {
                        unsafe
                        { 
                            channel.SendCommand(
                                (byte*)&command, 
                                sizeof(DUCE.MILCMD_VISUAL_SETGUIDELINECOLLECTION) 
                                );
                        } 
                    }
                    else
                    {
                        double[] doubleArray = new double[countXY]; 

                        if (countX != 0) 
                        { 
                            guidelinesX.CopyTo(doubleArray, 0);
                            Array.Sort(doubleArray, 0, countX); 
                        }

                        if (countY != 0)
                        { 
                            guidelinesY.CopyTo(doubleArray, countX);
                            Array.Sort(doubleArray, countX, countY); 
                        } 

                        float[] floatArray = new float[countXY]; 
                        for (int i = 0; i < countXY; i++)
                        {
                            floatArray[i] = (float)(double)(doubleArray[i]);
                        } 

                        unsafe 
                        { 
                            channel.BeginCommand(
                                (byte*)&command, 
                                sizeof(DUCE.MILCMD_VISUAL_SETGUIDELINECOLLECTION),
                                sizeof(float) * countXY
                                );
 
                            fixed (float* pData = floatArray)
                            { 
                                channel.AppendCommandData( 
                                    (byte*)pData,
                                    sizeof(float) * countXY 
                                    );
                            }

                            channel.EndCommand(); 
                        }
                    } 
                } 
            }
        } 

        internal static class Viewport3DVisualNode
        {
            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            ///  
            [SecurityCritical,SecurityTreatAsSafe]
            internal static void SetCamera( 
                DUCE.ResourceHandle hCompositionNode,
                DUCE.ResourceHandle hCamera,
                Channel channel)
            { 
                unsafe
                { 
                    DUCE.MILCMD_VIEWPORT3DVISUAL_SETCAMERA command; 

                    command.Type = MILCMD.MilCmdViewport3DVisualSetCamera; 
                    command.Handle = hCompositionNode;
                    command.hCamera = hCamera;

                    channel.SendCommand( 
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VIEWPORT3DVISUAL_SETCAMERA) 
                        ); 
                }
            } 

            /// 
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            /// 
            [SecurityCritical,SecurityTreatAsSafe] 
            internal static void SetViewport( 
                DUCE.ResourceHandle hCompositionNode,
                Rect viewport, 
                Channel channel)
            {
                unsafe
                { 
                    DUCE.MILCMD_VIEWPORT3DVISUAL_SETVIEWPORT command;
 
                    command.Type = MILCMD.MilCmdViewport3DVisualSetViewport; 
                    command.Handle = hCompositionNode;
                    command.Viewport = viewport; 

                    channel.SendCommand(
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VIEWPORT3DVISUAL_SETVIEWPORT) 
                        );
                } 
            } 

            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            /// 
            [SecurityCritical,SecurityTreatAsSafe] 
            internal static void Set3DChild(
                DUCE.ResourceHandle hCompositionNode, 
                DUCE.ResourceHandle hVisual3D, 
                Channel channel)
            { 
                unsafe
                {
                    DUCE.MILCMD_VIEWPORT3DVISUAL_SET3DCHILD command;
 
                    command.Type = MILCMD.MilCmdViewport3DVisualSet3DChild;
                    command.Handle = hCompositionNode; 
                    command.hChild = hVisual3D; 

                    channel.SendCommand( 
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VIEWPORT3DVISUAL_SET3DCHILD)
                        );
                } 
            }
        } 
 
        internal static class Visual3DNode
        { 
            /// 
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void RemoveChild( 
                DUCE.ResourceHandle hCompositionNode, 
                DUCE.ResourceHandle hChild,
                Channel channel) 
            {
                unsafe
                {
                    DUCE.MILCMD_VISUAL3D_REMOVECHILD command; 

                    command.Type = MILCMD.MilCmdVisual3DRemoveChild; 
                    command.Handle = hCompositionNode; 
                    command.hChild = hChild;
 
                    channel.SendCommand(
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VISUAL3D_REMOVECHILD)
                        ); 
                }
            } 
 
            /// 
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void RemoveAllChildren( 
                DUCE.ResourceHandle hCompositionNode,
                Channel channel) 
            { 
                unsafe
                { 
                    DUCE.MILCMD_VISUAL3D_REMOVEALLCHILDREN command;

                    command.Type = MILCMD.MilCmdVisual3DRemoveAllChildren;
                    command.Handle = hCompositionNode; 

                    channel.SendCommand( 
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_VISUAL3D_REMOVEALLCHILDREN)
                        ); 
                }
            }

            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void InsertChildAt( 
                DUCE.ResourceHandle hCompositionNode,
                DUCE.ResourceHandle hChild,
                UInt32 iPosition,
                Channel channel) 
            {
                unsafe 
                { 
                    DUCE.MILCMD_VISUAL3D_INSERTCHILDAT command;
                    Debug.Assert(!hCompositionNode.IsNull); 

                    command.Type = MILCMD.MilCmdVisual3DInsertChildAt;
                    command.Handle = hCompositionNode;
                    command.hChild = hChild; 
                    command.index = iPosition;
 
                    channel.SendCommand( 
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_VISUAL3D_INSERTCHILDAT) 
                        );
                }
            }
 
            /// 
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal static void SetContent(
                DUCE.ResourceHandle hCompositionNode,
                DUCE.ResourceHandle hContent,
                Channel channel) 
            {
                unsafe 
                { 
                    DUCE.MILCMD_VISUAL3D_SETCONTENT command;
 
                    command.Type = MILCMD.MilCmdVisual3DSetContent;
                    command.Handle = hCompositionNode;
                    command.hContent = hContent;
 
                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_VISUAL3D_SETCONTENT) 
                        );
                } 
            }

            /// 
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            ///  
            [SecurityCritical,SecurityTreatAsSafe] 
            internal static void SetTransform(
                DUCE.ResourceHandle hCompositionNode, 
                DUCE.ResourceHandle hTransform,
                Channel channel)
            {
                unsafe 
                {
                    DUCE.MILCMD_VISUAL3D_SETTRANSFORM command; 
 
                    command.Type = MILCMD.MilCmdVisual3DSetTransform;
                    command.Handle = hCompositionNode; 
                    command.hTransform = hTransform;

                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_VISUAL3D_SETTRANSFORM)
                        ); 
                } 
            }
        } 

        internal static class CompositionTarget
        {
            // ----------------------------------------------------------------------------------------------------------------------- 
            // Public imports for composition targets.
            // 
            ///  
            ///     Critical: This code calls into unsafe code blocks and initialized hwnd for composition target
            ///  
            [SecurityCritical]
            internal static void HwndInitialize(
                DUCE.ResourceHandle hCompositionTarget,
                IntPtr hWnd, 
                int nWidth,
                int nHeight, 
                bool softwareOnly, 
                Channel channel
                ) 
            {
                DUCE.MILCMD_HWNDTARGET_CREATE command;

                command.Type = MILCMD.MilCmdHwndTargetCreate; 
                command.Handle = hCompositionTarget;
 
                unsafe 
                {
                    // 
                    // If the HWND has the highest bit set, casting it to UInt64
                    // directly will cause sign extension. Prevent this by casting
                    // through a pointer and UIntPtr first.
                    // 

                    UIntPtr hWndUIntPtr = new UIntPtr(hWnd.ToPointer()); 
                    command.hwnd = (UInt64)hWndUIntPtr; 
                }
 
                command.width = (UInt32)nWidth;
                command.height = (UInt32)nHeight;
                command.clearColor.b = 0.0f;
                command.clearColor.r = 0.0f; 
                command.clearColor.g = 0.0f;
                command.clearColor.a = 1.0f; 
                command.flags = 
                    (UInt32)(MILRTInitializationFlags.MIL_RT_PRESENT_IMMEDIATELY |
                    MILRTInitializationFlags.MIL_RT_PRESENT_RETAIN_CONTENTS); 

                if (softwareOnly)
                {
                    // 
                    // In some scenarios, we will want to ensure that the rendered content is
                    // accessible through ntuser redirection. This is to allow graphics stream 
                    // clients to selectively magnify some WPF applications through the use 
                    // of the graphics stream, and some of them through legacy magnification
                    // (it could be triggered by versioning problems, rendering errors on the 
                    // graphics stream client side, etc.).
                    //

                    command.flags |= (UInt32)MILRTInitializationFlags.MIL_RT_SOFTWARE_ONLY; 
                }
 
                command.hBitmap = DUCE.ResourceHandle.Null; 
                command.stride = 0;
                command.ePixelFormat = 0; 
                command.hSection = 0;
                command.masterDevice = 0;

                unsafe 
                {
                    channel.SendSecurityCriticalCommand( 
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_HWNDTARGET_CREATE),
                        false /* sendInSeparateBatch */ 
                        );
                }
            }
 
            /// 
            /// Critical - 1) The command being sent contains an unmanaged pointer. 
            ///            2) This code accesses an unsafe code block. 
            /// 
            [SecurityCritical] 
            internal static void PrintInitialize(
                DUCE.ResourceHandle hCompositionTarget,
                IntPtr pRenderTarget,
                int nWidth, 
                int nHeight,
                Channel channel 
                ) 
            {
                DUCE.MILCMD_GENERICTARGET_CREATE command; 

                command.Type = MILCMD.MilCmdGenericTargetCreate;
                command.Handle = hCompositionTarget;
                command.hwnd = 0; 
                command.pRenderTarget = (UInt64)pRenderTarget;
                command.width = (UInt32)nWidth; 
                command.height = (UInt32)nHeight; 
                command.dummy = 0;
 
                unsafe
                {
                    channel.SendSecurityCriticalCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_GENERICTARGET_CREATE),
                        false /* sendInSeparateBatch */ 
                        ); 
                }
            } 

            /// 
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal static void SetClearColor( 
                DUCE.ResourceHandle hCompositionTarget,
                Color color, 
                Channel channel
                )
            {
                DUCE.MILCMD_TARGET_SETCLEARCOLOR command; 

                command.Type = MILCMD.MilCmdTargetSetClearColor; 
                command.Handle = hCompositionTarget; 
                command.clearColor.b = color.ScB;
                command.clearColor.r = color.ScR; 
                command.clearColor.g = color.ScG;
                command.clearColor.a = color.ScA;

                unsafe 
                {
                    channel.SendCommand( 
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_TARGET_SETCLEARCOLOR)
                        ); 
                }
            }

            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void SetRenderingMode( 
                DUCE.ResourceHandle hCompositionTarget,
                MILRTInitializationFlags nRenderingMode,
                Channel channel
                ) 
            {
                DUCE.MILCMD_TARGET_SETFLAGS command; 
 
                command.Type = MILCMD.MilCmdTargetSetFlags;
                command.Handle = hCompositionTarget; 
                command.flags = (UInt32)nRenderingMode;

                unsafe
                { 
                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_TARGET_SETFLAGS) 
                        );
                } 
            }


            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe 
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void SetRoot( 
                DUCE.ResourceHandle hCompositionTarget,
                DUCE.ResourceHandle hRoot,
                Channel channel
                ) 
            {
                DUCE.MILCMD_TARGET_SETROOT command; 
 
                command.Type = MILCMD.MilCmdTargetSetRoot;
                command.Handle = hCompositionTarget; 
                command.hRoot = hRoot;

                unsafe
                { 
                    channel.SendCommand(
                        (byte*)&command, 
                        sizeof(DUCE.MILCMD_TARGET_SETROOT) 
                        );
                } 
            }


            ///  
            ///     Critical: This code accesses an unsafe code block.
            ///               We also pass across a handle to an event, which we get via SafeWaitHandle.DangerousGetHandle. 
            ///  
            [SecurityCritical]
            internal static void UpdateWindowSettings( 
                ResourceHandle hCompositionTarget,
                NativeMethods.RECT windowRect,
                Color colorKey,
                float constantAlpha, 
                MILWindowLayerType windowLayerType,
                MILTransparencyFlags transparencyMode, 
                bool isChild, 
                bool isRTL,
                bool renderingEnabled, 
                int disableCookie,
                Channel channel
                )
            { 
                DUCE.MILCMD_TARGET_UPDATEWINDOWSETTINGS command;
 
                command.Type = MILCMD.MilCmdTargetUpdateWindowSettings; 
                command.Handle = hCompositionTarget;
 
                command.renderingEnabled = (uint)(renderingEnabled ? 1 : 0);
                command.disableCookie = (uint) disableCookie;

                command.windowRect = windowRect; 

                command.colorKey.b = colorKey.ScB; 
                command.colorKey.r = colorKey.ScR; 
                command.colorKey.g = colorKey.ScG;
                command.colorKey.a = colorKey.ScA; 

                command.constantAlpha = constantAlpha;
                command.transparencyMode = transparencyMode;
                command.windowLayerType = windowLayerType; 

                command.isChild = (uint)(isChild ? 1 : 0); 
                command.isRTL = (uint)(isRTL ? 1 : 0); 

                unsafe 
                {
                    channel.SendCommand(
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_TARGET_UPDATEWINDOWSETTINGS) 
                        );
                } 
            } 

            ///  
            ///     Critical: This code accesses an unsafe code block
            ///     TreatAsSafe: Operation is ok to call. It does not return any pointers and sending a pointer to a channel is safe
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            internal static void Invalidate(
                DUCE.ResourceHandle hCompositionTarget, 
                ref NativeMethods.RECT pRect, 
                Channel channel
                ) 
            {
                DUCE.MILCMD_TARGET_INVALIDATE command;

                command.Type = MILCMD.MilCmdTargetInvalidate; 
                command.Handle = hCompositionTarget;
                command.rc = pRect; 
 
                unsafe
                { 
                    channel.SendSecurityCriticalCommand(
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_TARGET_INVALIDATE),
                        false /* sendInSeparateBatch */ 
                        );
                } 
 
                channel.CloseBatch();
                channel.Commit(); 
            }
        }

        internal static class ETWEvent 
        {
            ///  
            ///     Critical: This code accesses an unsafe code block 
            ///     TreatAsSafe:  It does not return any pointers and is safe to call
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void RaiseEvent(
                DUCE.ResourceHandle hEtwEvent,
                UInt32 id, 
                Channel channel
                ) 
            { 
                DUCE.MILCMD_ETWEVENTRESOURCE command;
 
                command.Type = MILCMD.MilCmdEtwEventResource;
                command.Handle = hEtwEvent;
                command.id = id;
 
                unsafe
                { 
                    channel.SendCommand( 
                        (byte*)&command,
                        sizeof(DUCE.MILCMD_ETWEVENTRESOURCE) 
                        );
                }
            }
        } 

 
        /// 
        /// DUCE.IResource
        /// 
        internal interface IResource
        {
            DUCE.ResourceHandle AddRefOnChannel(Channel channel);
 
            int GetChannelCount();
 
            DUCE.Channel GetChannel(int index); 

            void ReleaseOnChannel(Channel channel); 

            DUCE.ResourceHandle GetHandle(Channel channel);

            ///  
            /// Only Vieport3DVisual and Visual3D implement this.
            /// Vieport3DVisual has two handles. One stored in _proxy 
            /// and the other one stored in _proxy3D. This function returns 
            /// the handle stored in _proxy3D.
            ///  
            DUCE.ResourceHandle Get3DHandle(Channel channel);

            /// 
            /// Sends a command to compositor to remove the child 
            /// from its parent on the channel.
            ///  
            void RemoveChildFromParent( 
                    IResource parent,
                    DUCE.Channel channel); 
        }
    }
}

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