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
- CachedFontFace.cs
- GPPOINTF.cs
- SchemaTableColumn.cs
- CustomWebEventKey.cs
- ScopedKnownTypes.cs
- EntityViewGenerationAttribute.cs
- DataGridRow.cs
- Attributes.cs
- OdbcConnectionFactory.cs
- PlainXmlSerializer.cs
- DrawingAttributesDefaultValueFactory.cs
- EastAsianLunisolarCalendar.cs
- GeneratedContractType.cs
- CollectionChangedEventManager.cs
- BaseConfigurationRecord.cs
- SwitchElementsCollection.cs
- XamlFilter.cs
- MailDefinition.cs
- CodeCommentStatementCollection.cs
- RequestResponse.cs
- TcpSocketManager.cs
- XmlChildEnumerator.cs
- SmtpNetworkElement.cs
- NegotiateStream.cs
- COM2TypeInfoProcessor.cs
- HierarchicalDataBoundControlAdapter.cs
- SymmetricKeyWrap.cs
- FileChangesMonitor.cs
- UrlEncodedParameterWriter.cs
- EndpointDispatcher.cs
- WsdlImporterElement.cs
- ProxyOperationRuntime.cs
- NativeCppClassAttribute.cs
- RegionInfo.cs
- LockCookie.cs
- ComEventsInfo.cs
- MultitargetingHelpers.cs
- PropertyChangedEventManager.cs
- OperationResponse.cs
- SafeEventLogWriteHandle.cs
- Oid.cs
- PersonalizationProviderHelper.cs
- TextTrailingWordEllipsis.cs
- StrokeCollectionConverter.cs
- PrintPreviewControl.cs
- NativeMethods.cs
- HttpListenerException.cs
- documentation.cs
- PseudoWebRequest.cs
- Compiler.cs
- XPathExpr.cs
- BoundField.cs
- ReliableSessionElement.cs
- CorrelationExtension.cs
- MailMessageEventArgs.cs
- GeneralTransform.cs
- DefaultWorkflowTransactionService.cs
- FixedFlowMap.cs
- RoleManagerModule.cs
- ScriptReference.cs
- DependencyPropertyValueSerializer.cs
- ClonableStack.cs
- SchemaElementLookUpTableEnumerator.cs
- PermissionAttributes.cs
- DataControlButton.cs
- WindowsFormsLinkLabel.cs
- PortCache.cs
- X509Certificate2.cs
- mediapermission.cs
- UniqueTransportManagerRegistration.cs
- ControlAdapter.cs
- Listbox.cs
- ReverseInheritProperty.cs
- SchemaElement.cs
- __TransparentProxy.cs
- GatewayIPAddressInformationCollection.cs
- MatrixConverter.cs
- FlowDocumentScrollViewerAutomationPeer.cs
- Util.cs
- FileDialogCustomPlace.cs
- InfiniteIntConverter.cs
- Zone.cs
- PropertyFilterAttribute.cs
- SuppressIldasmAttribute.cs
- DispatcherSynchronizationContext.cs
- MemberProjectedSlot.cs
- InfoCardRSAOAEPKeyExchangeFormatter.cs
- SpotLight.cs
- SymmetricCryptoHandle.cs
- Oci.cs
- DatePicker.cs
- DESCryptoServiceProvider.cs
- TargetException.cs
- ProfilePropertyMetadata.cs
- ToolBarOverflowPanel.cs
- RequestCachingSection.cs
- DefaultAsyncDataDispatcher.cs
- Serializer.cs
- CroppedBitmap.cs
- StackBuilderSink.cs