Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / clipboard.cs / 1 / 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.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 inherantly unsafe. /// [SecurityCritical] public static void Clear() { // Clear the system clipboard by calling OleSetClipboard with null parameter. ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleSetClipboard(null)); } ////// 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; hr = OleServicesContext.CurrentOleServicesContext.OleIsCurrentClipboard((IComDataObject)data); 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"); } if (data is DataObject) { ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleSetClipboard((DataObject)data)); } else if (data is IComDataObject) { SecurityHelper.DemandUnmanagedCode(); ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleSetClipboard((IComDataObject)data)); } else { ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleSetClipboard(new DataObject(data))); } if (copy) { ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleFlushClipboard()); } } ////// 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; oleDataObject = null; ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleGetClipboard(ref oleDataObject)); 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. /// private static bool ContainsDataInternal(string format) { IDataObject dataObject; dataObject = Clipboard.GetDataObject(); if (dataObject != null) { bool autoConvert; if (IsDataFormatAutoConvert(format)) { autoConvert = true; } else { autoConvert = false; } return dataObject.GetDataPresent(format, autoConvert); } else { return false; } } ////// 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; } ////// Throw the exception if hr isn't succeed. /// ////// Critical: This code calls into ThrowExceptionForHr which has a link demand /// TreatAsSafe: The net effect is the same as throwing an excpetion from your app /// [SecurityCritical, SecurityTreatAsSafe] private static void ThrowIfFailed(int hr) { if (!NativeMethods.Succeeded(hr)) { Marshal.ThrowExceptionForHR(hr); } } #endregion Private Methods } #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.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 inherantly unsafe. /// [SecurityCritical] public static void Clear() { // Clear the system clipboard by calling OleSetClipboard with null parameter. ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleSetClipboard(null)); } ////// 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; hr = OleServicesContext.CurrentOleServicesContext.OleIsCurrentClipboard((IComDataObject)data); 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"); } if (data is DataObject) { ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleSetClipboard((DataObject)data)); } else if (data is IComDataObject) { SecurityHelper.DemandUnmanagedCode(); ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleSetClipboard((IComDataObject)data)); } else { ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleSetClipboard(new DataObject(data))); } if (copy) { ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleFlushClipboard()); } } ////// 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; oleDataObject = null; ThrowIfFailed(OleServicesContext.CurrentOleServicesContext.OleGetClipboard(ref oleDataObject)); 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. /// private static bool ContainsDataInternal(string format) { IDataObject dataObject; dataObject = Clipboard.GetDataObject(); if (dataObject != null) { bool autoConvert; if (IsDataFormatAutoConvert(format)) { autoConvert = true; } else { autoConvert = false; } return dataObject.GetDataPresent(format, autoConvert); } else { return false; } } ////// 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; } ////// Throw the exception if hr isn't succeed. /// ////// Critical: This code calls into ThrowExceptionForHr which has a link demand /// TreatAsSafe: The net effect is the same as throwing an excpetion from your app /// [SecurityCritical, SecurityTreatAsSafe] private static void ThrowIfFailed(int hr) { if (!NativeMethods.Succeeded(hr)) { Marshal.ThrowExceptionForHR(hr); } } #endregion Private Methods } #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
- SendReply.cs
- KeyManager.cs
- PreviewKeyDownEventArgs.cs
- __ConsoleStream.cs
- safePerfProviderHandle.cs
- TokenBasedSetEnumerator.cs
- Message.cs
- PartialTrustVisibleAssembliesSection.cs
- DataViewManager.cs
- ObjectQueryExecutionPlan.cs
- MessageRpc.cs
- ZipIOBlockManager.cs
- ToolStripItemImageRenderEventArgs.cs
- ToolboxSnapDragDropEventArgs.cs
- TransactedBatchingBehavior.cs
- SqlInternalConnectionSmi.cs
- AuthenticationModulesSection.cs
- BlockExpression.cs
- ApplicationFileParser.cs
- ObjectListComponentEditor.cs
- NativeCompoundFileAPIs.cs
- FlowLayout.cs
- LayoutEngine.cs
- ResourcesChangeInfo.cs
- ListViewItem.cs
- ApplicationProxyInternal.cs
- ChildTable.cs
- TdsParserSessionPool.cs
- ProviderSettings.cs
- PropertyRef.cs
- PolicyException.cs
- BrowserTree.cs
- DataObjectFieldAttribute.cs
- wgx_render.cs
- SourceChangedEventArgs.cs
- XslException.cs
- ConstructorArgumentAttribute.cs
- MexHttpsBindingCollectionElement.cs
- DataBindingExpressionBuilder.cs
- Int64Animation.cs
- ReadOnlyObservableCollection.cs
- DateTimeOffsetStorage.cs
- EntityDataSourceSelectedEventArgs.cs
- XNameTypeConverter.cs
- WebDescriptionAttribute.cs
- OdbcStatementHandle.cs
- SystemResourceKey.cs
- BuildDependencySet.cs
- QueryRewriter.cs
- DbConnectionPoolCounters.cs
- ErrorWrapper.cs
- DataTransferEventArgs.cs
- IssuedTokenClientElement.cs
- MethodBuilder.cs
- DataGridViewColumnDividerDoubleClickEventArgs.cs
- DataPointer.cs
- TypeUtils.cs
- KeyEvent.cs
- Unit.cs
- InputLanguageCollection.cs
- RegistrySecurity.cs
- XsltConvert.cs
- SafeEventLogWriteHandle.cs
- CodeIterationStatement.cs
- HandlerBase.cs
- Pens.cs
- ProviderConnectionPointCollection.cs
- GridItemPattern.cs
- FileStream.cs
- DataServiceClientException.cs
- ZoneMembershipCondition.cs
- Encoder.cs
- WebPartUtil.cs
- MethodAccessException.cs
- TemplateControlBuildProvider.cs
- Identity.cs
- StatusBarAutomationPeer.cs
- WindowsToolbarAsMenu.cs
- PrtCap_Builder.cs
- SamlAudienceRestrictionCondition.cs
- namescope.cs
- HostingPreferredMapPath.cs
- SqlTransaction.cs
- StructuralCache.cs
- UnsafeCollabNativeMethods.cs
- ExecutionContext.cs
- HotCommands.cs
- EventTrigger.cs
- sqlser.cs
- OdbcConnectionStringbuilder.cs
- NamespaceQuery.cs
- SettingsSection.cs
- SqlReferenceCollection.cs
- DLinqTableProvider.cs
- WebRequestModuleElementCollection.cs
- Transform3DCollection.cs
- DataServiceQueryException.cs
- AssemblyResourceLoader.cs
- DBCommandBuilder.cs
- FrugalList.cs