Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / clipboard.cs / 1471291 / clipboard.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: Clipboard implementation to provide methods to place/get data from/to the system // clipboard. // // See spec at http://avalon/uis/Data%20Transfer%20clipboard%20dragdrop/Avalon%20Clipboard.htm // // History: // 05/09/2002 : susiA Created // 06/16/2003 : sangilj Moved to WCP // //--------------------------------------------------------------------------- using MS.Win32; using MS.Internal; using MS.Internal.PresentationCore; // SecurityHelper using System.Collections.Specialized; using System.IO; using System.Security; using System.Security.Permissions; using System.ComponentModel; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Threading; using System.Windows.Media.Imaging; using System.Windows.Threading; using SR = MS.Internal.PresentationCore.SR; using SRID = MS.Internal.PresentationCore.SRID; using IComDataObject = System.Runtime.InteropServices.ComTypes.IDataObject; namespace System.Windows { #region Clipboard class ////// Provides methods to place data on and retrieve data from the system clipboard. /// This class cannot be inherited. /// public static class Clipboard { //----------------------------------------------------- // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Clear the system clipboard which the clipboard is emptied. /// SetDataObject. /// ////// Critical - access critical data (clipboard information) /// PublicOk - Clearing the clipboard is not inherently unsafe. /// [SecurityCritical] public static void Clear() { // Retry OLE operations several times as mitigation for clipboard locking issues in TS sessions. // See Dev10 bug 616223 and VSWhidbey bug 476911. int i = OleRetryCount; while (true) { // Clear the system clipboard by calling OleSetClipboard with null parameter. int hr = OleServicesContext.CurrentOleServicesContext.OleSetClipboard(null); if (NativeMethods.Succeeded(hr)) { break; } if (--i == 0) { Marshal.ThrowExceptionForHR(hr); } Thread.Sleep(OleRetryDelay); } } ////// Return true if Clipboard contains the audio data. Otherwise, return false. /// public static bool ContainsAudio() { return ContainsDataInternal(DataFormats.WaveAudio); } ////// Return true if Clipboard contains the specified data format. Otherwise, return false. /// public static bool ContainsData(string format) { if (format == null) { throw new ArgumentNullException("format"); } if (format == string.Empty) { throw new ArgumentException(SR.Get(SRID.DataObject_EmptyFormatNotAllowed)); } return ContainsDataInternal(format); } ////// Return true if Clipboard contains the file drop list format. Otherwise, return false. /// public static bool ContainsFileDropList() { return ContainsDataInternal(DataFormats.FileDrop); } ////// Return true if Clipboard contains the image format. Otherwise, return false. /// public static bool ContainsImage() { return ContainsDataInternal(DataFormats.Bitmap); } ////// Return true if Clipboard contains the text data format which is unicode. /// Otherwise, return false. /// public static bool ContainsText() { return ContainsDataInternal(DataFormats.UnicodeText); } ////// Return true if Clipboard contains the specified text data format which is unicode. /// Otherwise, return false. /// public static bool ContainsText(TextDataFormat format) { if (!DataFormats.IsValidTextDataFormat(format)) { throw new InvalidEnumArgumentException("format", (int)format, typeof(TextDataFormat)); } return ContainsDataInternal(DataFormats.ConvertToDataFormats(format)); } ////// Get audio data as Stream from Clipboard. /// public static Stream GetAudioStream() { return GetDataInternal(DataFormats.WaveAudio) as Stream; } ////// Get data for the specified data format from Clipboard. /// public static object GetData(string format) { if (format == null) { throw new ArgumentNullException("format"); } if (format == string.Empty) { throw new ArgumentException(SR.Get(SRID.DataObject_EmptyFormatNotAllowed)); } return GetDataInternal(format); } ////// Get the file drop list as StringCollection from Clipboard. /// public static StringCollection GetFileDropList() { StringCollection fileDropListCollection; string[] fileDropList; fileDropListCollection = new StringCollection(); fileDropList = GetDataInternal(DataFormats.FileDrop) as string[]; if (fileDropList != null) { fileDropListCollection.AddRange(fileDropList); } return fileDropListCollection; } ////// Get the image from Clipboard. /// public static BitmapSource GetImage() { return GetDataInternal(DataFormats.Bitmap) as BitmapSource; } ////// Get text from Clipboard. /// public static string GetText() { return GetText(TextDataFormat.UnicodeText); } ////// Get text from Clipboard. /// public static string GetText(TextDataFormat format) { if (!DataFormats.IsValidTextDataFormat(format)) { throw new InvalidEnumArgumentException("format", (int)format, typeof(TextDataFormat)); } string text; text = (string)GetDataInternal(DataFormats.ConvertToDataFormats(format)); if (text != null) { return text; } return string.Empty; } ////// Set the audio data to Clipboard. /// public static void SetAudio(byte[] audioBytes) { if (audioBytes == null) { throw new ArgumentNullException("audioBytes"); } SetAudio(new MemoryStream(audioBytes)); } ////// Set the audio data to Clipboard. /// public static void SetAudio(Stream audioStream) { if (audioStream == null) { throw new ArgumentNullException("audioStream"); } SetDataInternal(DataFormats.WaveAudio, audioStream); } ////// Set the specified data to Clipboard. /// public static void SetData(string format, object data) { if (format == null) { throw new ArgumentNullException("format"); } if (format == string.Empty) { throw new ArgumentException(SR.Get(SRID.DataObject_EmptyFormatNotAllowed)); } if (data == null) { throw new ArgumentNullException("data"); } SetDataInternal(format, data); } ////// Set the file drop list to Clipboard. /// public static void SetFileDropList(StringCollection fileDropList) { if (fileDropList == null) { throw new ArgumentNullException("fileDropList"); } if (fileDropList.Count == 0) { throw new ArgumentException(SR.Get(SRID.DataObject_FileDropListIsEmpty, fileDropList)); } foreach (string fileDrop in fileDropList) { try { string filePath = Path.GetFullPath(fileDrop); } catch (ArgumentException) { throw new ArgumentException(SR.Get(SRID.DataObject_FileDropListHasInvalidFileDropPath, fileDropList)); } } string[] fileDropListStrings; fileDropListStrings = new string[fileDropList.Count]; fileDropList.CopyTo(fileDropListStrings, 0); SetDataInternal(DataFormats.FileDrop, fileDropListStrings); } ////// Set the image data to Clipboard. /// public static void SetImage(BitmapSource image) { if (image == null) { throw new ArgumentNullException("image"); } SetDataInternal(DataFormats.Bitmap, image); } ////// Set the text data to Clipboard. /// public static void SetText(string text) { if (text == null) { throw new ArgumentNullException("text"); } SetText(text, TextDataFormat.UnicodeText); } ////// Set the text data to Clipboard. /// public static void SetText(string text, TextDataFormat format) { if (text == null) { throw new ArgumentNullException("text"); } if (!DataFormats.IsValidTextDataFormat(format)) { throw new InvalidEnumArgumentException("format", (int)format, typeof(TextDataFormat)); } SetDataInternal(DataFormats.ConvertToDataFormats(format), text); } ////// Retrieves the data object that is currently on the system clipboard. /// ////// Callers must have UIPermission(UIPermissionClipboard.AllClipboard) to call this API. /// ////// Critical - access critical data (clipboard information) /// PublicOk - demands appropriate permission (AllClipboard) /// [SecurityCritical] public static IDataObject GetDataObject() { SecurityHelper.DemandAllClipboardPermission(); return GetDataObjectInternal(); } ////// Determines whether the data object previously placed on the clipboard /// by the SetDataObject is still on the clipboard. /// /// /// Data object from the current containing clipboard which the caller /// previously placed on the clipboard. /// public static bool IsCurrent(IDataObject data) { bool bReturn; if (data == null) { throw new ArgumentNullException("data"); } bReturn = false; if (data is IComDataObject) { int hr; // Retry OLE operations several times as mitigation for clipboard locking issues in TS sessions. // See Dev10 bug 616223 and VSWhidbey bug 476911. int i = OleRetryCount; while (true) { hr = OleServicesContext.CurrentOleServicesContext.OleIsCurrentClipboard((IComDataObject)data); if (NativeMethods.Succeeded(hr) || (--i == 0)) { break; } Thread.Sleep(OleRetryDelay); } if (hr == NativeMethods.S_OK) { bReturn = true; } else if (!NativeMethods.Succeeded(hr)) { throw new ExternalException("OleIsCurrentClipboard()", hr); } } return bReturn; } ////// Places nonpersistent data on the system clipboard. /// /// /// The specific data to be on clipboard. /// ////// Callers must have UIPermission(UIPermissionClipboard.AllClipboard) to call this API. /// ////// Critical - access critical data (clipboard information) /// PublicOk - demands appropriate permission (AllClipboard) /// [SecurityCritical] public static void SetDataObject(object data) { SecurityHelper.DemandAllClipboardPermission(); if (data == null) { throw new ArgumentNullException("data"); } SetDataObject(data, false); } ////// Places data on the system Clipboard and uses copy to specify whether the data /// should remain on the Clipboard after the application exits. /// /// /// The specific data to be on clipboard. /// /// /// Specify whether the data should remain on the clipboard after the application exits. /// ////// Callers must have UIPermission(UIPermissionClipboard.AllClipboard) to call this API. /// ////// Critical - calls critical code (set clipboard), and potentially deals /// with unmanaged pointers /// PublicOk - Demands All Clipboard permissions /// [SecurityCritical] public static void SetDataObject(object data, bool copy) { SecurityHelper.DemandAllClipboardPermission(); CriticalSetDataObject(data,copy); } #endregion Public Methods #region Internal Methods //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- ////// Places data on the system Clipboard and uses copy to specify whether the data /// should remain on the Clipboard after the application exits. /// /// /// The specific data to be on clipboard. /// /// /// Specify whether the data should remain on the clipboard after the application exits. /// ////// Critical - calls critical code (set clipboard), and potentially deals /// with unmanaged pointers /// [SecurityCritical] [FriendAccessAllowed] internal static void CriticalSetDataObject(object data, bool copy) { if (data == null) { throw new ArgumentNullException("data"); } IComDataObject dataObject; if (data is DataObject) { dataObject = (DataObject)data; } else if (data is IComDataObject) { SecurityHelper.DemandUnmanagedCode(); dataObject = (IComDataObject)data; } else { dataObject = new DataObject(data); } // Retry OLE operations several times as mitigation for clipboard locking issues in TS sessions. // See Dev10 bug 616223 and VSWhidbey bug 476911. int i = OleRetryCount; while (true) { // Clear the system clipboard by calling OleSetClipboard with null parameter. int hr = OleServicesContext.CurrentOleServicesContext.OleSetClipboard(dataObject); if (NativeMethods.Succeeded(hr)) { break; } if (--i == 0) { Marshal.ThrowExceptionForHR(hr); } Thread.Sleep(OleRetryDelay); } if (copy) { i = OleRetryCount; while (true) { int hr = OleServicesContext.CurrentOleServicesContext.OleFlushClipboard(); if (NativeMethods.Succeeded(hr)) { break; } if (--i == 0) { Marshal.ThrowExceptionForHR(hr); } Thread.Sleep(OleRetryDelay); } } } ////// Critical - access critical data (clipboard information) /// TreatAsSafe: Returning a bool indicating whether there is data on the clipboard is ok /// [SecurityCritical, SecurityTreatAsSafe] [FriendAccessAllowed] internal static bool IsClipboardPopulated() { bool isPopulated = false; (new UIPermission(UIPermissionClipboard.AllClipboard)).Assert();//BlessedAssert try { isPopulated = (GetDataObjectInternal() != null); } finally { UIPermission.RevertAssert(); } return isPopulated; } #endregion Internal Methods //------------------------------------------------------ // // Private Methods // //------------------------------------------------------ #region Private Methods ////// Critical: This method calls into ExtractAppDomainPermissionSetMinusSiteOfOrigin this is used to make trust decision to /// copy paste content and is hence important to be tracked. Also it asserts to get to data /// [SecurityCritical] private static bool IsDataObjectFromLessPriviligedApplicationDomain(IDataObject dataObjectToApply) { bool retVal = false; object applicationTrust = null; // Extract the permission set in case of xaml cut and paste // extract permission set if it exists if not data came from full trust app and we do not care bool isApplicationTrustFormatPresent = false; isApplicationTrustFormatPresent = dataObjectToApply.GetDataPresent(DataFormats.ApplicationTrust, /*autoConvert:*/false); if (isApplicationTrustFormatPresent) { applicationTrust = dataObjectToApply.GetData(DataFormats.ApplicationTrust, /*autoConvert:*/false); } if (applicationTrust != null) { string applicationTrustText = null; // convert to string applicationTrustText = applicationTrust.ToString(); // Convert string to permission set for getting permission set of source PermissionSet permissionSetSource; try { SecurityElement securityElement = SecurityElement.FromString(applicationTrustText); permissionSetSource = new System.Security.PermissionSet(PermissionState.None); permissionSetSource.FromXml(securityElement); } catch(XmlSyntaxException) { // This is the condition where we have Malformed XML in the clipboard for application trust // here we will fail silently since we do not want to break arbitrary applications // but since we cannot establish the validity of the application trust content we will fall back to // whatever is more secure return true; } //extract permission set for the current appdomain which is target PermissionSet permissionSetDestination = SecurityHelper.ExtractAppDomainPermissionSetMinusSiteOfOrigin(); //Compare permissions sets if (!permissionSetDestination.IsSubsetOf(permissionSetSource)) { retVal = true; // in case target is not subset of source revert to unicode or text } } return retVal; } ////// Critical: This code extracts the DataObject from the clipboard /// which can be used to sniff clipboard /// [SecurityCritical] private static IDataObject GetDataObjectInternal() { IDataObject dataObject; IComDataObject oleDataObject; // Retry OLE operations several times as mitigation for clipboard locking issues in TS sessions. // See Dev10 bug 616223 and VSWhidbey bug 476911. int i = OleRetryCount; while (true) { oleDataObject = null; int hr = OleServicesContext.CurrentOleServicesContext.OleGetClipboard(ref oleDataObject); if (NativeMethods.Succeeded(hr)) { break; } if (--i == 0) { Marshal.ThrowExceptionForHR(hr); } Thread.Sleep(OleRetryDelay); } if (oleDataObject is IDataObject) { dataObject = (IDataObject)oleDataObject; } else if (oleDataObject != null) { dataObject = new DataObject(oleDataObject); } else { dataObject = null; } // We make this check outside of the loop independant of whether the data is ole data object or IDataObject // Although one is unable to create an OleDataObject in partial trust we still need to ensure that if he did // we strip the formats we care about by wrapping in ConstrainedDataObject if (dataObject != null) { // this is the case we are concerend about where content comes from partial trust into full trust // in the case where data contained is in one of the two formats: XAML or ApplicationTrust we return a wrapper // that blocks access to these if (IsDataObjectFromLessPriviligedApplicationDomain(dataObject) && (dataObject.GetDataPresent(DataFormats.Xaml, /*autoConvert:*/false) || dataObject.GetDataPresent(DataFormats.ApplicationTrust, /*autoConvert:*/false))) { // in this case we set the data object to be a wrapper data object that blocks off // xaml or application trust formats if they exist dataObject = new ConstrainedDataObject(dataObject); } } return dataObject; } ////// Query the specified data format from Clipboard. /// ////// Critical - Accesses the clipboard. /// TreatAsSafe - We demand clipboard permission. [SecurityCritical, SecurityTreatAsSafe] private static bool ContainsDataInternal(string format) { SecurityHelper.DemandAllClipboardPermission(); bool isFormatAvailable = false; if (IsDataFormatAutoConvert(format)) { string[] formats = DataObject.GetMappedFormats(format); for (int i = 0; i < formats.Length; i++) { if (SafeNativeMethods.IsClipboardFormatAvailable(DataFormats.GetDataFormat(formats[i]).Id)) { isFormatAvailable = true; break; } } } else { isFormatAvailable = SafeNativeMethods.IsClipboardFormatAvailable(DataFormats.GetDataFormat(format).Id); } return isFormatAvailable; } /// /// Get the specified format from Clipboard. /// private static object GetDataInternal(string format) { IDataObject dataObject; dataObject = Clipboard.GetDataObject(); if (dataObject != null) { bool autoConvert; if (IsDataFormatAutoConvert(format)) { autoConvert = true; } else { autoConvert = false; } return dataObject.GetData(format, autoConvert); } else { return null; } } ////// Set the specified data into Clipboard. /// private static void SetDataInternal(string format, object data) { IDataObject dataObject; bool autoConvert; if (IsDataFormatAutoConvert(format)) { autoConvert = true; } else { autoConvert = false; } dataObject = new DataObject(); dataObject.SetData(format, data, autoConvert); Clipboard.SetDataObject(dataObject, /*copy*/true); } ////// Check the auto convert for the specified data format. /// private static bool IsDataFormatAutoConvert(string format) { bool autoConvert; if (String.CompareOrdinal(format, DataFormats.FileDrop) == 0 || String.CompareOrdinal(format, DataFormats.Bitmap) == 0) { autoConvert = true; } else { autoConvert = false; } return autoConvert; } #endregion Private Methods //----------------------------------------------------- // // Private Constants // //------------------------------------------------------ #region Private Constants ////// The number of times to retry OLE clipboard operations. /// ////// This is mitigation for clipboard locking issues in TS sessions. See Dev10 bug 616223 and VSWhidbey bug 476911. /// private const int OleRetryCount = 10; ////// The amount of time in milliseconds to sleep between retrying OLE clipboard operations. /// ////// This is mitigation for clipboard locking issues in TS sessions. See Dev10 bug 616223 and VSWhidbey bug 476911. /// private const int OleRetryDelay = 100; #endregion Private Constants } #endregion Clipboard class } // 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: Clipboard implementation to provide methods to place/get data from/to the system // clipboard. // // See spec at http://avalon/uis/Data%20Transfer%20clipboard%20dragdrop/Avalon%20Clipboard.htm // // History: // 05/09/2002 : susiA Created // 06/16/2003 : sangilj Moved to WCP // //--------------------------------------------------------------------------- using MS.Win32; using MS.Internal; using MS.Internal.PresentationCore; // SecurityHelper using System.Collections.Specialized; using System.IO; using System.Security; using System.Security.Permissions; using System.ComponentModel; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Threading; using System.Windows.Media.Imaging; using System.Windows.Threading; using SR = MS.Internal.PresentationCore.SR; using SRID = MS.Internal.PresentationCore.SRID; using IComDataObject = System.Runtime.InteropServices.ComTypes.IDataObject; namespace System.Windows { #region Clipboard class ////// Provides methods to place data on and retrieve data from the system clipboard. /// This class cannot be inherited. /// public static class Clipboard { //----------------------------------------------------- // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Clear the system clipboard which the clipboard is emptied. /// SetDataObject. /// ////// Critical - access critical data (clipboard information) /// PublicOk - Clearing the clipboard is not inherently unsafe. /// [SecurityCritical] public static void Clear() { // Retry OLE operations several times as mitigation for clipboard locking issues in TS sessions. // See Dev10 bug 616223 and VSWhidbey bug 476911. int i = OleRetryCount; while (true) { // Clear the system clipboard by calling OleSetClipboard with null parameter. int hr = OleServicesContext.CurrentOleServicesContext.OleSetClipboard(null); if (NativeMethods.Succeeded(hr)) { break; } if (--i == 0) { Marshal.ThrowExceptionForHR(hr); } Thread.Sleep(OleRetryDelay); } } ////// Return true if Clipboard contains the audio data. Otherwise, return false. /// public static bool ContainsAudio() { return ContainsDataInternal(DataFormats.WaveAudio); } ////// Return true if Clipboard contains the specified data format. Otherwise, return false. /// public static bool ContainsData(string format) { if (format == null) { throw new ArgumentNullException("format"); } if (format == string.Empty) { throw new ArgumentException(SR.Get(SRID.DataObject_EmptyFormatNotAllowed)); } return ContainsDataInternal(format); } ////// Return true if Clipboard contains the file drop list format. Otherwise, return false. /// public static bool ContainsFileDropList() { return ContainsDataInternal(DataFormats.FileDrop); } ////// Return true if Clipboard contains the image format. Otherwise, return false. /// public static bool ContainsImage() { return ContainsDataInternal(DataFormats.Bitmap); } ////// Return true if Clipboard contains the text data format which is unicode. /// Otherwise, return false. /// public static bool ContainsText() { return ContainsDataInternal(DataFormats.UnicodeText); } ////// Return true if Clipboard contains the specified text data format which is unicode. /// Otherwise, return false. /// public static bool ContainsText(TextDataFormat format) { if (!DataFormats.IsValidTextDataFormat(format)) { throw new InvalidEnumArgumentException("format", (int)format, typeof(TextDataFormat)); } return ContainsDataInternal(DataFormats.ConvertToDataFormats(format)); } ////// Get audio data as Stream from Clipboard. /// public static Stream GetAudioStream() { return GetDataInternal(DataFormats.WaveAudio) as Stream; } ////// Get data for the specified data format from Clipboard. /// public static object GetData(string format) { if (format == null) { throw new ArgumentNullException("format"); } if (format == string.Empty) { throw new ArgumentException(SR.Get(SRID.DataObject_EmptyFormatNotAllowed)); } return GetDataInternal(format); } ////// Get the file drop list as StringCollection from Clipboard. /// public static StringCollection GetFileDropList() { StringCollection fileDropListCollection; string[] fileDropList; fileDropListCollection = new StringCollection(); fileDropList = GetDataInternal(DataFormats.FileDrop) as string[]; if (fileDropList != null) { fileDropListCollection.AddRange(fileDropList); } return fileDropListCollection; } ////// Get the image from Clipboard. /// public static BitmapSource GetImage() { return GetDataInternal(DataFormats.Bitmap) as BitmapSource; } ////// Get text from Clipboard. /// public static string GetText() { return GetText(TextDataFormat.UnicodeText); } ////// Get text from Clipboard. /// public static string GetText(TextDataFormat format) { if (!DataFormats.IsValidTextDataFormat(format)) { throw new InvalidEnumArgumentException("format", (int)format, typeof(TextDataFormat)); } string text; text = (string)GetDataInternal(DataFormats.ConvertToDataFormats(format)); if (text != null) { return text; } return string.Empty; } ////// Set the audio data to Clipboard. /// public static void SetAudio(byte[] audioBytes) { if (audioBytes == null) { throw new ArgumentNullException("audioBytes"); } SetAudio(new MemoryStream(audioBytes)); } ////// Set the audio data to Clipboard. /// public static void SetAudio(Stream audioStream) { if (audioStream == null) { throw new ArgumentNullException("audioStream"); } SetDataInternal(DataFormats.WaveAudio, audioStream); } ////// Set the specified data to Clipboard. /// public static void SetData(string format, object data) { if (format == null) { throw new ArgumentNullException("format"); } if (format == string.Empty) { throw new ArgumentException(SR.Get(SRID.DataObject_EmptyFormatNotAllowed)); } if (data == null) { throw new ArgumentNullException("data"); } SetDataInternal(format, data); } ////// Set the file drop list to Clipboard. /// public static void SetFileDropList(StringCollection fileDropList) { if (fileDropList == null) { throw new ArgumentNullException("fileDropList"); } if (fileDropList.Count == 0) { throw new ArgumentException(SR.Get(SRID.DataObject_FileDropListIsEmpty, fileDropList)); } foreach (string fileDrop in fileDropList) { try { string filePath = Path.GetFullPath(fileDrop); } catch (ArgumentException) { throw new ArgumentException(SR.Get(SRID.DataObject_FileDropListHasInvalidFileDropPath, fileDropList)); } } string[] fileDropListStrings; fileDropListStrings = new string[fileDropList.Count]; fileDropList.CopyTo(fileDropListStrings, 0); SetDataInternal(DataFormats.FileDrop, fileDropListStrings); } ////// Set the image data to Clipboard. /// public static void SetImage(BitmapSource image) { if (image == null) { throw new ArgumentNullException("image"); } SetDataInternal(DataFormats.Bitmap, image); } ////// Set the text data to Clipboard. /// public static void SetText(string text) { if (text == null) { throw new ArgumentNullException("text"); } SetText(text, TextDataFormat.UnicodeText); } ////// Set the text data to Clipboard. /// public static void SetText(string text, TextDataFormat format) { if (text == null) { throw new ArgumentNullException("text"); } if (!DataFormats.IsValidTextDataFormat(format)) { throw new InvalidEnumArgumentException("format", (int)format, typeof(TextDataFormat)); } SetDataInternal(DataFormats.ConvertToDataFormats(format), text); } ////// Retrieves the data object that is currently on the system clipboard. /// ////// Callers must have UIPermission(UIPermissionClipboard.AllClipboard) to call this API. /// ////// Critical - access critical data (clipboard information) /// PublicOk - demands appropriate permission (AllClipboard) /// [SecurityCritical] public static IDataObject GetDataObject() { SecurityHelper.DemandAllClipboardPermission(); return GetDataObjectInternal(); } ////// Determines whether the data object previously placed on the clipboard /// by the SetDataObject is still on the clipboard. /// /// /// Data object from the current containing clipboard which the caller /// previously placed on the clipboard. /// public static bool IsCurrent(IDataObject data) { bool bReturn; if (data == null) { throw new ArgumentNullException("data"); } bReturn = false; if (data is IComDataObject) { int hr; // Retry OLE operations several times as mitigation for clipboard locking issues in TS sessions. // See Dev10 bug 616223 and VSWhidbey bug 476911. int i = OleRetryCount; while (true) { hr = OleServicesContext.CurrentOleServicesContext.OleIsCurrentClipboard((IComDataObject)data); if (NativeMethods.Succeeded(hr) || (--i == 0)) { break; } Thread.Sleep(OleRetryDelay); } if (hr == NativeMethods.S_OK) { bReturn = true; } else if (!NativeMethods.Succeeded(hr)) { throw new ExternalException("OleIsCurrentClipboard()", hr); } } return bReturn; } ////// Places nonpersistent data on the system clipboard. /// /// /// The specific data to be on clipboard. /// ////// Callers must have UIPermission(UIPermissionClipboard.AllClipboard) to call this API. /// ////// Critical - access critical data (clipboard information) /// PublicOk - demands appropriate permission (AllClipboard) /// [SecurityCritical] public static void SetDataObject(object data) { SecurityHelper.DemandAllClipboardPermission(); if (data == null) { throw new ArgumentNullException("data"); } SetDataObject(data, false); } ////// Places data on the system Clipboard and uses copy to specify whether the data /// should remain on the Clipboard after the application exits. /// /// /// The specific data to be on clipboard. /// /// /// Specify whether the data should remain on the clipboard after the application exits. /// ////// Callers must have UIPermission(UIPermissionClipboard.AllClipboard) to call this API. /// ////// Critical - calls critical code (set clipboard), and potentially deals /// with unmanaged pointers /// PublicOk - Demands All Clipboard permissions /// [SecurityCritical] public static void SetDataObject(object data, bool copy) { SecurityHelper.DemandAllClipboardPermission(); CriticalSetDataObject(data,copy); } #endregion Public Methods #region Internal Methods //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- ////// Places data on the system Clipboard and uses copy to specify whether the data /// should remain on the Clipboard after the application exits. /// /// /// The specific data to be on clipboard. /// /// /// Specify whether the data should remain on the clipboard after the application exits. /// ////// Critical - calls critical code (set clipboard), and potentially deals /// with unmanaged pointers /// [SecurityCritical] [FriendAccessAllowed] internal static void CriticalSetDataObject(object data, bool copy) { if (data == null) { throw new ArgumentNullException("data"); } IComDataObject dataObject; if (data is DataObject) { dataObject = (DataObject)data; } else if (data is IComDataObject) { SecurityHelper.DemandUnmanagedCode(); dataObject = (IComDataObject)data; } else { dataObject = new DataObject(data); } // Retry OLE operations several times as mitigation for clipboard locking issues in TS sessions. // See Dev10 bug 616223 and VSWhidbey bug 476911. int i = OleRetryCount; while (true) { // Clear the system clipboard by calling OleSetClipboard with null parameter. int hr = OleServicesContext.CurrentOleServicesContext.OleSetClipboard(dataObject); if (NativeMethods.Succeeded(hr)) { break; } if (--i == 0) { Marshal.ThrowExceptionForHR(hr); } Thread.Sleep(OleRetryDelay); } if (copy) { i = OleRetryCount; while (true) { int hr = OleServicesContext.CurrentOleServicesContext.OleFlushClipboard(); if (NativeMethods.Succeeded(hr)) { break; } if (--i == 0) { Marshal.ThrowExceptionForHR(hr); } Thread.Sleep(OleRetryDelay); } } } ////// Critical - access critical data (clipboard information) /// TreatAsSafe: Returning a bool indicating whether there is data on the clipboard is ok /// [SecurityCritical, SecurityTreatAsSafe] [FriendAccessAllowed] internal static bool IsClipboardPopulated() { bool isPopulated = false; (new UIPermission(UIPermissionClipboard.AllClipboard)).Assert();//BlessedAssert try { isPopulated = (GetDataObjectInternal() != null); } finally { UIPermission.RevertAssert(); } return isPopulated; } #endregion Internal Methods //------------------------------------------------------ // // Private Methods // //------------------------------------------------------ #region Private Methods ////// Critical: This method calls into ExtractAppDomainPermissionSetMinusSiteOfOrigin this is used to make trust decision to /// copy paste content and is hence important to be tracked. Also it asserts to get to data /// [SecurityCritical] private static bool IsDataObjectFromLessPriviligedApplicationDomain(IDataObject dataObjectToApply) { bool retVal = false; object applicationTrust = null; // Extract the permission set in case of xaml cut and paste // extract permission set if it exists if not data came from full trust app and we do not care bool isApplicationTrustFormatPresent = false; isApplicationTrustFormatPresent = dataObjectToApply.GetDataPresent(DataFormats.ApplicationTrust, /*autoConvert:*/false); if (isApplicationTrustFormatPresent) { applicationTrust = dataObjectToApply.GetData(DataFormats.ApplicationTrust, /*autoConvert:*/false); } if (applicationTrust != null) { string applicationTrustText = null; // convert to string applicationTrustText = applicationTrust.ToString(); // Convert string to permission set for getting permission set of source PermissionSet permissionSetSource; try { SecurityElement securityElement = SecurityElement.FromString(applicationTrustText); permissionSetSource = new System.Security.PermissionSet(PermissionState.None); permissionSetSource.FromXml(securityElement); } catch(XmlSyntaxException) { // This is the condition where we have Malformed XML in the clipboard for application trust // here we will fail silently since we do not want to break arbitrary applications // but since we cannot establish the validity of the application trust content we will fall back to // whatever is more secure return true; } //extract permission set for the current appdomain which is target PermissionSet permissionSetDestination = SecurityHelper.ExtractAppDomainPermissionSetMinusSiteOfOrigin(); //Compare permissions sets if (!permissionSetDestination.IsSubsetOf(permissionSetSource)) { retVal = true; // in case target is not subset of source revert to unicode or text } } return retVal; } ////// Critical: This code extracts the DataObject from the clipboard /// which can be used to sniff clipboard /// [SecurityCritical] private static IDataObject GetDataObjectInternal() { IDataObject dataObject; IComDataObject oleDataObject; // Retry OLE operations several times as mitigation for clipboard locking issues in TS sessions. // See Dev10 bug 616223 and VSWhidbey bug 476911. int i = OleRetryCount; while (true) { oleDataObject = null; int hr = OleServicesContext.CurrentOleServicesContext.OleGetClipboard(ref oleDataObject); if (NativeMethods.Succeeded(hr)) { break; } if (--i == 0) { Marshal.ThrowExceptionForHR(hr); } Thread.Sleep(OleRetryDelay); } if (oleDataObject is IDataObject) { dataObject = (IDataObject)oleDataObject; } else if (oleDataObject != null) { dataObject = new DataObject(oleDataObject); } else { dataObject = null; } // We make this check outside of the loop independant of whether the data is ole data object or IDataObject // Although one is unable to create an OleDataObject in partial trust we still need to ensure that if he did // we strip the formats we care about by wrapping in ConstrainedDataObject if (dataObject != null) { // this is the case we are concerend about where content comes from partial trust into full trust // in the case where data contained is in one of the two formats: XAML or ApplicationTrust we return a wrapper // that blocks access to these if (IsDataObjectFromLessPriviligedApplicationDomain(dataObject) && (dataObject.GetDataPresent(DataFormats.Xaml, /*autoConvert:*/false) || dataObject.GetDataPresent(DataFormats.ApplicationTrust, /*autoConvert:*/false))) { // in this case we set the data object to be a wrapper data object that blocks off // xaml or application trust formats if they exist dataObject = new ConstrainedDataObject(dataObject); } } return dataObject; } ////// Query the specified data format from Clipboard. /// ////// Critical - Accesses the clipboard. /// TreatAsSafe - We demand clipboard permission. [SecurityCritical, SecurityTreatAsSafe] private static bool ContainsDataInternal(string format) { SecurityHelper.DemandAllClipboardPermission(); bool isFormatAvailable = false; if (IsDataFormatAutoConvert(format)) { string[] formats = DataObject.GetMappedFormats(format); for (int i = 0; i < formats.Length; i++) { if (SafeNativeMethods.IsClipboardFormatAvailable(DataFormats.GetDataFormat(formats[i]).Id)) { isFormatAvailable = true; break; } } } else { isFormatAvailable = SafeNativeMethods.IsClipboardFormatAvailable(DataFormats.GetDataFormat(format).Id); } return isFormatAvailable; } /// /// Get the specified format from Clipboard. /// private static object GetDataInternal(string format) { IDataObject dataObject; dataObject = Clipboard.GetDataObject(); if (dataObject != null) { bool autoConvert; if (IsDataFormatAutoConvert(format)) { autoConvert = true; } else { autoConvert = false; } return dataObject.GetData(format, autoConvert); } else { return null; } } ////// Set the specified data into Clipboard. /// private static void SetDataInternal(string format, object data) { IDataObject dataObject; bool autoConvert; if (IsDataFormatAutoConvert(format)) { autoConvert = true; } else { autoConvert = false; } dataObject = new DataObject(); dataObject.SetData(format, data, autoConvert); Clipboard.SetDataObject(dataObject, /*copy*/true); } ////// Check the auto convert for the specified data format. /// private static bool IsDataFormatAutoConvert(string format) { bool autoConvert; if (String.CompareOrdinal(format, DataFormats.FileDrop) == 0 || String.CompareOrdinal(format, DataFormats.Bitmap) == 0) { autoConvert = true; } else { autoConvert = false; } return autoConvert; } #endregion Private Methods //----------------------------------------------------- // // Private Constants // //------------------------------------------------------ #region Private Constants ////// The number of times to retry OLE clipboard operations. /// ////// This is mitigation for clipboard locking issues in TS sessions. See Dev10 bug 616223 and VSWhidbey bug 476911. /// private const int OleRetryCount = 10; ////// The amount of time in milliseconds to sleep between retrying OLE clipboard operations. /// ////// This is mitigation for clipboard locking issues in TS sessions. See Dev10 bug 616223 and VSWhidbey bug 476911. /// private const int OleRetryDelay = 100; #endregion Private Constants } #endregion Clipboard class } // 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
- SynchronizationLockException.cs
- SizeIndependentAnimationStorage.cs
- RelationalExpressions.cs
- PrefixHandle.cs
- CompatibleComparer.cs
- Matrix3D.cs
- BitmapEffect.cs
- HuffCodec.cs
- Matrix3D.cs
- AbstractExpressions.cs
- HttpHandlerAction.cs
- NegationPusher.cs
- ClaimTypeRequirement.cs
- SqlBuffer.cs
- FrameworkContentElementAutomationPeer.cs
- ViewBox.cs
- RegexParser.cs
- ToolStripDropDownItem.cs
- Restrictions.cs
- InstanceKeyCompleteException.cs
- SchemaMapping.cs
- ElementUtil.cs
- XmlNodeWriter.cs
- SamlAuthorizationDecisionStatement.cs
- WebSysDisplayNameAttribute.cs
- Vector3D.cs
- TriggerCollection.cs
- EnumBuilder.cs
- TraceData.cs
- ReversePositionQuery.cs
- DetailsView.cs
- VSWCFServiceContractGenerator.cs
- HiddenField.cs
- BasicCellRelation.cs
- HttpValueCollection.cs
- TextDecorationCollection.cs
- TagNameToTypeMapper.cs
- LocalValueEnumerator.cs
- Expressions.cs
- NavigationHelper.cs
- AssemblyNameProxy.cs
- MediaPlayerState.cs
- InvokeGenerator.cs
- ValidationSummaryDesigner.cs
- ObjectItemNoOpAssemblyLoader.cs
- VirtualDirectoryMapping.cs
- FontCacheUtil.cs
- ReferenceService.cs
- FormViewAutoFormat.cs
- DBProviderConfigurationHandler.cs
- dtdvalidator.cs
- IgnoreFileBuildProvider.cs
- ContentPresenter.cs
- AttributeTable.cs
- ProfileService.cs
- SelectQueryOperator.cs
- CurrentChangingEventManager.cs
- TreeNodeCollection.cs
- CommentEmitter.cs
- DataGridViewLinkCell.cs
- XsltArgumentList.cs
- ReflectionUtil.cs
- CompiledXpathExpr.cs
- TextEditorCopyPaste.cs
- IndexedString.cs
- safelink.cs
- Triplet.cs
- SafeRightsManagementPubHandle.cs
- MailDefinition.cs
- DelegatingTypeDescriptionProvider.cs
- ConvertTextFrag.cs
- SessionStateModule.cs
- DBSqlParserTableCollection.cs
- X509ChainPolicy.cs
- VectorValueSerializer.cs
- Win32MouseDevice.cs
- COM2PictureConverter.cs
- SoundPlayer.cs
- TabControl.cs
- PipelineModuleStepContainer.cs
- EarlyBoundInfo.cs
- SerialPort.cs
- DataGridCell.cs
- EpmTargetTree.cs
- XpsResourcePolicy.cs
- EventLogEntry.cs
- OutOfMemoryException.cs
- NoResizeHandleGlyph.cs
- AnnotationResource.cs
- initElementDictionary.cs
- DbProviderManifest.cs
- GridViewDeletedEventArgs.cs
- SectionInformation.cs
- ScrollBarAutomationPeer.cs
- Crc32.cs
- MetadataArtifactLoaderCompositeFile.cs
- PropertyPath.cs
- DtrList.cs
- Point3DAnimationUsingKeyFrames.cs
- ResourcePart.cs