Code:
/ 4.0 / 4.0 / 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. //---------------------------------------------------------------------------- // //// 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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Graphics.cs
- Internal.cs
- _Connection.cs
- InstanceLockLostException.cs
- UpdatePanel.cs
- RSAOAEPKeyExchangeDeformatter.cs
- CommandBindingCollection.cs
- DataObjectCopyingEventArgs.cs
- MostlySingletonList.cs
- SiteOfOriginPart.cs
- BasicViewGenerator.cs
- HelpInfo.cs
- TemplateNameScope.cs
- DataGridColumnDropSeparator.cs
- MultipleViewProviderWrapper.cs
- FilterQuery.cs
- ConstraintManager.cs
- ConnectionStringsSection.cs
- OracleTransaction.cs
- LineServicesRun.cs
- CollectionBuilder.cs
- Exceptions.cs
- XmlSerializer.cs
- TcpProcessProtocolHandler.cs
- AlphaSortedEnumConverter.cs
- IntegerCollectionEditor.cs
- UriSection.cs
- MaskDesignerDialog.cs
- BinaryReader.cs
- ConstructorBuilder.cs
- WebBaseEventKeyComparer.cs
- MulticastIPAddressInformationCollection.cs
- BinaryNode.cs
- XmlSchemaObject.cs
- COMException.cs
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
- SkipStoryboardToFill.cs
- EndPoint.cs
- CookieProtection.cs
- IItemContainerGenerator.cs
- AppDomainResourcePerfCounters.cs
- UdpChannelFactory.cs
- CommonGetThemePartSize.cs
- DataPagerFieldCommandEventArgs.cs
- AbstractDataSvcMapFileLoader.cs
- TextModifier.cs
- BasicCellRelation.cs
- BooleanFacetDescriptionElement.cs
- FillErrorEventArgs.cs
- ImageCodecInfoPrivate.cs
- SQLBoolean.cs
- EmptyStringExpandableObjectConverter.cs
- OleDbMetaDataFactory.cs
- WindowsListViewItemCheckBox.cs
- NotSupportedException.cs
- ValidationService.cs
- PointAnimationUsingPath.cs
- HyperLink.cs
- ExpressionBuilder.cs
- ByteAnimationBase.cs
- LiteralSubsegment.cs
- StyleHelper.cs
- DotAtomReader.cs
- FileCodeGroup.cs
- TextElementCollection.cs
- EditorPart.cs
- CharUnicodeInfo.cs
- PersonalizationState.cs
- SettingsProviderCollection.cs
- SizeFConverter.cs
- CheckBoxDesigner.cs
- SafeThemeHandle.cs
- AttributedMetaModel.cs
- NativeCompoundFileAPIs.cs
- XamlStream.cs
- InvalidDataException.cs
- dataobject.cs
- CounterSample.cs
- InputScopeConverter.cs
- ProxyFragment.cs
- BrowserCapabilitiesFactory.cs
- IsolationInterop.cs
- ZipPackagePart.cs
- AnimationClock.cs
- DataGridViewButtonCell.cs
- sqlser.cs
- ThreadNeutralSemaphore.cs
- XmlSerializerOperationFormatter.cs
- MouseEvent.cs
- HtmlDocument.cs
- ChannelBinding.cs
- HtmlImage.cs
- XsdDateTime.cs
- Identifier.cs
- X509SecurityTokenProvider.cs
- GestureRecognizer.cs
- Emitter.cs
- ToolBarOverflowPanel.cs
- WebPartExportVerb.cs
- FontSizeConverter.cs