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
- DirectionalLight.cs
- ToolStripSeparator.cs
- XPathDocumentBuilder.cs
- ConnectionsZoneAutoFormat.cs
- SoapParser.cs
- Thickness.cs
- GridViewRowPresenterBase.cs
- IndexedEnumerable.cs
- DrawListViewItemEventArgs.cs
- SerializableTypeCodeDomSerializer.cs
- BamlLocalizationDictionary.cs
- PointCollection.cs
- XamlVector3DCollectionSerializer.cs
- CodeTypeReference.cs
- SubMenuStyle.cs
- DataSourceControlBuilder.cs
- SchemaCollectionCompiler.cs
- ShortcutKeysEditor.cs
- PerformanceCounterPermissionEntry.cs
- CreateParams.cs
- X509Chain.cs
- SqlNodeAnnotation.cs
- ZipFileInfoCollection.cs
- BitmapEffectInputData.cs
- ObjectIDGenerator.cs
- EventProviderWriter.cs
- DropShadowBitmapEffect.cs
- RemotingException.cs
- XmlIlGenerator.cs
- Pkcs7Recipient.cs
- ArrayExtension.cs
- MarkupExtensionParser.cs
- PageSettings.cs
- WebPartDisplayMode.cs
- InvalidateEvent.cs
- TextDecoration.cs
- WorkflowMarkupSerializerMapping.cs
- CodeDOMProvider.cs
- CapabilitiesSection.cs
- MenuItem.cs
- MasterPage.cs
- Exception.cs
- XmlILTrace.cs
- XmlReader.cs
- TdsValueSetter.cs
- Trace.cs
- QilStrConcatenator.cs
- Soap12ProtocolReflector.cs
- XmlSchemaGroup.cs
- XpsS0ValidatingLoader.cs
- MessageBox.cs
- SettingsPropertyIsReadOnlyException.cs
- MD5.cs
- EffectiveValueEntry.cs
- InternalResources.cs
- HtmlString.cs
- ClipboardData.cs
- OdbcCommandBuilder.cs
- XmlSerializerObjectSerializer.cs
- MdImport.cs
- HtmlElementEventArgs.cs
- VectorAnimation.cs
- Byte.cs
- Animatable.cs
- PassportAuthentication.cs
- CreateUserWizardStep.cs
- HtmlPhoneCallAdapter.cs
- XPathNodeList.cs
- PointCollectionValueSerializer.cs
- Int64Converter.cs
- UnhandledExceptionEventArgs.cs
- ValidatingReaderNodeData.cs
- RightNameExpirationInfoPair.cs
- DataGridItemCollection.cs
- WindowsListViewItemStartMenu.cs
- GridViewAutoFormat.cs
- HitTestResult.cs
- LinkedResourceCollection.cs
- Int64Converter.cs
- OLEDB_Util.cs
- SingleStorage.cs
- PathFigureCollection.cs
- PropertyIDSet.cs
- DesignerObject.cs
- StorageMappingItemCollection.cs
- FixedTextPointer.cs
- CompositeActivityTypeDescriptorProvider.cs
- PixelShader.cs
- String.cs
- HtmlInputFile.cs
- TempFiles.cs
- MetadataPropertyAttribute.cs
- DirectoryGroupQuery.cs
- RIPEMD160Managed.cs
- OdbcErrorCollection.cs
- ResourceExpression.cs
- Camera.cs
- TypeNameConverter.cs
- IpcClientChannel.cs
- COAUTHIDENTITY.cs