OleServicesContext.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / OleServicesContext.cs / 1407647 / OleServicesContext.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: Ole Services for DragDrop and Clipboard. 
// 
// History:
//  05/05/2004 : sangilj - Created. 
//
//---------------------------------------------------------------------------

using MS.Win32; 
using MS.Internal;
using System.Security; 
using System.Security.Permissions; 
using System.Diagnostics;
using System.Runtime.InteropServices; 
using System.Threading;
using System.Windows.Threading;
using System.Windows.Input;
 
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID; 
using IComDataObject = System.Runtime.InteropServices.ComTypes.IDataObject; 

namespace System.Windows 
{
    //-----------------------------------------------------
    //
    //  OleServicesContext class 
    //
    //----------------------------------------------------- 
 
    /// 
    /// This class manages Ole services for DragDrop and Clipboard. 
    /// The instance of OleServicesContext class is created per Thread...Dispatcher.
    /// 
    /// 
    ///  
    //
 
 

 

    internal class OleServicesContext
    {
        //------------------------------------------------------ 
        //
        //  Constructors 
        // 
        //-----------------------------------------------------
 
        #region Constructors

        /// 
        /// Instantiates a OleServicesContext. 
        /// 
        private OleServicesContext() 
        { 
            // We need to get the Dispatcher Thread in order to get OLE DragDrop and Clipboard services that
            // require STA. 
            SetDispatcherThread();
        }

        #endregion Constructors 

        //------------------------------------------------------ 
        // 
        //  Internal Properties
        // 
        //------------------------------------------------------

        #region Internal Properties
 
        /// 
        /// Get the ole services context associated with the current Thread. 
        ///  
        internal static OleServicesContext CurrentOleServicesContext
        { 
            get
            {
                OleServicesContext oleServicesContext;
 
                // Get the ole services context from the Thread data slot.
                oleServicesContext = (OleServicesContext)Thread.GetData(OleServicesContext._threadDataSlot); 
 
                if (oleServicesContext == null)
                { 
                    // Create OleSErvicesContext instance.
                    oleServicesContext = new OleServicesContext();

                    // Save the ole services context into the UIContext data slot. 
                    Thread.SetData(OleServicesContext._threadDataSlot, oleServicesContext);
                } 
 
                return oleServicesContext;
            } 
        }

        #endregion Internal Properties
 
        //-----------------------------------------------------
        // 
        //  Internal Methods 
        //
        //------------------------------------------------------ 

        #region Internal Methods

        ///  
        /// OleSetClipboard - Call OLE Interopo OleSetClipboard()
        ///  
        ///  
        /// Critical - calls unsafe methods, and passes native pointer to native code...
        ///  
        [SecurityCritical]
        internal int OleSetClipboard(IComDataObject dataObject)
        {
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) 
            {
                throw new ThreadStateException(SR.Get(SRID.OleServicesContext_ThreadMustBeSTA)); 
            } 

            return UnsafeNativeMethods.OleSetClipboard(dataObject); 
        }

        /// 
        /// OleGetClipboard - Call OLE Interop OleGetClipboard() 
        /// 
        ///  
        /// Critical - gets critical data from the clipboard... defense in depth, we still 
        ///            protect the data (because you need to use COM interop to get to it)
        ///            but we want to track the people accessing this. 
        /// 
        [SecurityCritical]
        internal int OleGetClipboard(ref IComDataObject dataObject)
        { 
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
            { 
                throw new ThreadStateException(SR.Get(SRID.OleServicesContext_ThreadMustBeSTA)); 
            }
 
            return UnsafeNativeMethods.OleGetClipboard(ref dataObject);
        }

        ///  
        /// OleFlushClipboard - Call OLE Interop OleFlushClipboard()
        ///  
        ///  
        /// Critical - calls critical code, flushes data to clipboard
        /// TreatAsSafe - flushing the data is always acceptable to 
        ///               do, only penalty would be performance.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal int OleFlushClipboard() 
        {
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) 
            { 
                throw new ThreadStateException(SR.Get(SRID.OleServicesContext_ThreadMustBeSTA));
            } 

            return UnsafeNativeMethods.OleFlushClipboard();
        }
 
        /// 
        /// OleIsCurrentClipboard - OleIsCurrentClipboard only works for the data object 
        /// used in the OleSetClipboard. This means that it can�t be called by the consumer 
        /// of the data object to determine if the object that was on the clipboard at the
        /// previous OleGetClipboard call is still on the Clipboard. 
        /// 
        /// 
        /// Critical - calls critical code: OleIsCurrentClipboard.
        /// TreatAsSafe - Determining if a data object is still on the clipboard does not pose a security risk. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal int OleIsCurrentClipboard(IComDataObject dataObject) 
        {
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) 
            {
                throw new ThreadStateException(SR.Get(SRID.OleServicesContext_ThreadMustBeSTA));
            }
 
            return UnsafeNativeMethods.OleIsCurrentClipboard(dataObject);
        } 
 
        /// 
        /// OleDoDragDrop - Call OLE Interop DoDragDrop() 
        /// Initiate OLE DragDrop
        /// 
        /// 
        ///     Critical: Since it calls to Dispatcher.InputManager 
        ///     TreatAsSafe: Since it does not expose the InputManager
        ///  
        [SecurityCritical,SecurityTreatAsSafe] 
        internal void OleDoDragDrop(IComDataObject dataObject, UnsafeNativeMethods.IOleDropSource dropSource, int allowedEffects, int[] finalEffect)
        { 
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
            {
                throw new ThreadStateException(SR.Get(SRID.OleServicesContext_ThreadMustBeSTA));
            } 

            InputManager inputManager = (InputManager)Dispatcher.CurrentDispatcher.InputManager; 
            if (inputManager != null) 
            {
                inputManager.InDragDrop = true; 
            }
            try
            {
                UnsafeNativeMethods.DoDragDrop(dataObject, dropSource, allowedEffects, finalEffect); 
            }
            finally 
            { 
                if (inputManager != null)
                { 
                    inputManager.InDragDrop = false;
                }
            }
        } 

        ///  
        /// OleRegisterDragDrop - Call OLE Interop RegisterDragDrop() 
        /// 
        ///  
        /// Critical - pinvokes into native code with caller supplied COM object.
        ///            Also -- even if we did trust the dropTarget (which we don't) -- exposes the HWND
        ///            as a site for arbitrary drops/code injections.
        ///  
        [SecurityCritical]
        internal int OleRegisterDragDrop(HandleRef windowHandle, UnsafeNativeMethods.IOleDropTarget dropTarget) 
        { 
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
            { 
                throw new ThreadStateException(SR.Get(SRID.OleServicesContext_ThreadMustBeSTA));
            }

            return UnsafeNativeMethods.RegisterDragDrop(windowHandle, dropTarget); 
        }
 
        ///  
        /// OleRevokeDragDrop - Call OLE Interop RevokeDragDrop()
        ///  
        /// 
        /// Critical - pinvokes into native code, disables drag/drop for an entire HWND.
        /// 
        [SecurityCritical] 
        internal int OleRevokeDragDrop(HandleRef windowHandle)
        { 
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) 
            {
                throw new ThreadStateException(SR.Get(SRID.OleServicesContext_ThreadMustBeSTA)); 
            }

            return UnsafeNativeMethods.RevokeDragDrop(windowHandle);
        } 

        #endregion Internal Methods 
 
        //-----------------------------------------------------
        // 
        //  Private Methods
        //
        //-----------------------------------------------------
 
        #region Private Methods
 
        ///  
        /// SetDispatcherThread - Initialize OleServicesContext that will call Ole initialize for ole services(DragDrop and Clipboard)
        /// and add the disposed event handler of Dispatcher to clean up resources and uninitalize Ole. 
        /// 
        private void SetDispatcherThread()
        {
            int hr; 

            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) 
            { 
                throw new ThreadStateException(SR.Get(SRID.OleServicesContext_ThreadMustBeSTA));
            } 

            // Initialize Ole services.
            // Balanced with OleUninitialize call in OnDispatcherShutdown.
            hr = OleInitialize(); 

            if (!NativeMethods.Succeeded(hr)) 
            { 
                throw new SystemException(SR.Get(SRID.OleServicesContext_oleInitializeFailure, hr));
            } 

            // Add Dispatcher.Shutdown event handler.
            // We will call ole Uninitialize and clean up the resource when UIContext is terminated.
            Dispatcher.CurrentDispatcher.ShutdownFinished += new EventHandler(OnDispatcherShutdown); 
        }
 
        ///  
        /// This is a callback when Dispatcher is shut down.
        ///  
        /// 
        /// This method must be called before shutting down the application
        /// on the dispatcher thread.  It must be called by the same
        /// thread running the dispatcher and the thread must have its 
        /// ApartmentState property set to ApartmentState.STA.
        ///  
        private void OnDispatcherShutdown(object sender, EventArgs args) 
        {
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) 
            {
                throw new ThreadStateException(SR.Get(SRID.OleServicesContext_ThreadMustBeSTA));
            }
 
            // Uninitialize Ole services.
            // Balanced with OleInitialize call in SetDispatcherThread. 
            OleUninitialize(); 
        }
 
        // Wrapper for UnsafeNativeMethods.OleInitialize, useful for debugging.
        /// 
        /// Critical - calls critical method (OleInitialize)
        /// TreatAsSafe - safe to call anytime (ref counting issues aside) 
        /// 
        [SecurityCritical,SecurityTreatAsSafe] 
        private int OleInitialize() 
        {
#if DEBUG 
            _debugOleInitializeRefCount++;
#endif // DEBUG
            return UnsafeNativeMethods.OleInitialize();
        } 

        // Wrapper for UnsafeNativeMethods.OleUninitialize, useful for debugging. 
        ///  
        /// Critical - calls critical method (OleUninitialize)
        /// TreatAsSafe - safe to call OLeUninitialize 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private int OleUninitialize()
        { 
            int hr;
 
            hr = UnsafeNativeMethods.OleUninitialize(); 
#if DEBUG
            _debugOleInitializeRefCount--; 
            Invariant.Assert(_debugOleInitializeRefCount >= 0, "Unbalanced call to OleUnitialize!");
#endif // DEBUG

            return hr; 
        }
 
        #endregion Private Methods 

        //----------------------------------------------------- 
        //
        //  Private Fields
        //
        //------------------------------------------------------ 

        #region Private Fields 
 
        // This is a slot to store OleServicesContext class per thread.
        private static readonly LocalDataStoreSlot _threadDataSlot = Thread.AllocateDataSlot(); 

#if DEBUG
        // Ref count of calls to OleInitialize/OleUnitialize.
        private int _debugOleInitializeRefCount; 
#endif // DEBUG
 
        #endregion Private Fields 
    }
} 


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


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK