Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Core / CSharp / MS / Internal / FontCache / FontSource.cs / 1 / FontSource.cs
//---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // Description: The FontSource class. // // History: // 08/04/2003 : mleonov - Created it // //--------------------------------------------------------------------------- using System; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Packaging; using System.Net; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Windows; using System.Windows.Media; using System.Windows.Threading; using MS.Win32; using MS.Utility; using MS.Internal; using MS.Internal.IO.Packaging; using MS.Internal.PresentationCore; namespace MS.Internal.FontCache { ////// FontSource class encapsulates the logic for dealing with fonts in memory or on the disk. /// It may or may not have a Uri associated with it, but there has to be some way to obtain its contents. /// internal class FontSource { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Critical - fontUri can contain information about local file system, skipDemand is used to make security decisions. /// [SecurityCritical] public FontSource(Uri fontUri, bool skipDemand) { _fontUri = fontUri; _skipDemand = skipDemand; Invariant.Assert(_fontUri.IsAbsoluteUri); Debug.Assert(String.IsNullOrEmpty(_fontUri.Fragment)); } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- #region Internal Methods ////// Critical - as this gives out full file path. /// [SecurityCritical] public string GetUriString() { return _fontUri.GetComponents(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped); } ////// Critical - as this gives out full file path. /// [SecurityCritical] public string ToStringUpperInvariant() { return GetUriString().ToUpperInvariant(); } ////// Critical - fontUri can contain information about local file system. /// TreatAsSafe - we only compute its hash code. /// [SecurityCritical, SecurityTreatAsSafe] public override int GetHashCode() { return HashFn.HashString(ToStringUpperInvariant(), 0); } ////// Critical - as this gives out full file path. /// public Uri Uri { [SecurityCritical] get { return _fontUri; } } ////// Critical - fontUri can contain information about local file system. /// TreatAsSafe - we only return a flag that says whether the Uri is app specific. /// public bool IsAppSpecific { [SecurityCritical, SecurityTreatAsSafe] get { return Util.IsAppSpecificUri(_fontUri); } } internal long SkipLastWriteTime() { // clients may choose to use this temporary method because GetLastWriteTime call // results in touching the file system // we need to resurrect this code when we come up with a complete solution // for updating fonts on the fly return -1; // any non-zero value will do here } ////// Critical - elevates to obtain the last write time for %windir%\fonts. /// Also, fontUri can contain information about local file system. /// TreatAsSafe - we only use it to obtain the last write time. /// [SecurityCritical, SecurityTreatAsSafe] internal DateTime GetLastWriteTimeUtc() { if (_fontUri.IsFile) { bool revertAssert = false; // Assert FileIORead permission for installed fonts. if (_skipDemand) { new FileIOPermission(FileIOPermissionAccess.Read, _fontUri.LocalPath).Assert(); //Blessed Assert revertAssert = true; } try { return Directory.GetLastWriteTimeUtc(_fontUri.LocalPath); } finally { if (revertAssert) CodeAccessPermission.RevertAssert(); } } // Any special value will do here. return DateTime.MaxValue; } ////// Critical - as this gives out UnmanagedMemoryStream content which is from a file. /// [SecurityCritical] internal UnmanagedMemoryStream GetUnmanagedStream() { if (_fontUri.IsFile) { FileMapping fileMapping = new FileMapping(); DemandFileIOPermission(); fileMapping.OpenFile(_fontUri.LocalPath); return fileMapping; } byte[] bits; // Try our cache first. lock (_resourceCache) { bits = _resourceCache.Get(_fontUri); } if (bits == null) { WebResponse response = WpfWebRequestHelper.CreateRequestAndGetResponse(_fontUri); Stream fontStream = response.GetResponseStream(); if (String.Equals(response.ContentType, ObfuscatedContentType, StringComparison.Ordinal)) { // The third parameter makes sure the original stream is closed // when the deobfuscating stream is disposed. fontStream = new DeobfuscatingStream(fontStream, _fontUri, false); } UnmanagedMemoryStream unmanagedStream = fontStream as UnmanagedMemoryStream; if (unmanagedStream != null) return unmanagedStream; bits = StreamToByteArray(fontStream); fontStream.Close(); lock (_resourceCache) { _resourceCache.Add(_fontUri, bits, false); } } return ByteArrayToUnmanagedStream(bits); } ////// Critical - as this gives out Stream content which is from a file. /// [SecurityCritical] internal Stream GetStream() { if (_fontUri.IsFile) { FileMapping fileMapping = new FileMapping(); DemandFileIOPermission(); fileMapping.OpenFile(_fontUri.LocalPath); return fileMapping; } byte[] bits; // Try our cache first. lock (_resourceCache) { bits = _resourceCache.Get(_fontUri); } if (bits != null) return new MemoryStream(bits); WebRequest request = PackWebRequestFactory.CreateWebRequest(_fontUri); WebResponse response = request.GetResponse(); Stream fontStream = response.GetResponseStream(); if (String.Equals(response.ContentType, ObfuscatedContentType, StringComparison.Ordinal)) { // The third parameter makes sure the original stream is closed // when the deobfuscating stream is disposed. fontStream = new DeobfuscatingStream(fontStream, _fontUri, false); } return fontStream; } #endregion Internal Methods //------------------------------------------------------ // // Private Methods // //------------------------------------------------------ #region Private Methods private static UnmanagedMemoryStream ByteArrayToUnmanagedStream(byte[] bits) { return new PinnedByteArrayStream(bits); } private static byte [] StreamToByteArray(Stream fontStream) { byte[] memoryFont; if (fontStream.CanSeek) { checked { memoryFont = new byte[(int)fontStream.Length]; PackagingUtilities.ReliableRead(fontStream, memoryFont, 0, (int)fontStream.Length); } } else { // this is inefficient, but works for now // we need to spend more time to implement a more performant // version of this code // ideally this should be a part of loader functionality // Initial file read buffer size is set to 1MB. int fileReadBufferSize = 1024 * 1024; byte[] fileReadBuffer = new byte[fileReadBufferSize]; // Actual number of bytes read from the file. int memoryFontSize = 0; for (; ; ) { int availableBytes = fileReadBufferSize - memoryFontSize; if (availableBytes < fileReadBufferSize / 3) { // grow the fileReadBuffer fileReadBufferSize *= 2; byte[] newBuffer = new byte[fileReadBufferSize]; Array.Copy(fileReadBuffer, newBuffer, memoryFontSize); fileReadBuffer = newBuffer; availableBytes = fileReadBufferSize - memoryFontSize; } int numberOfBytesRead = fontStream.Read(fileReadBuffer, memoryFontSize, availableBytes); if (numberOfBytesRead == 0) break; memoryFontSize += numberOfBytesRead; } // Actual number of bytes read from the file is less or equal to the file read buffer size. Debug.Assert(memoryFontSize <= fileReadBufferSize); if (memoryFontSize == fileReadBufferSize) memoryFont = fileReadBuffer; else { // Trim the array if needed to that it contains the right length. memoryFont = new byte[memoryFontSize]; Array.Copy(fileReadBuffer, memoryFont, memoryFontSize); } } return memoryFont; } ////// Demand read permissions for all fonts except system ones. /// ////// Critical - as this function calls critical WindowsFontsUriObject. /// TreatAsSafe - as the WindowsFontsUriObject is used to determine whether to demand permissions. /// [SecurityCritical, SecurityTreatAsSafe] private void DemandFileIOPermission() { // Demand FileIORead permission for any non-system fonts. if (!_skipDemand) { SecurityHelper.DemandUriReadPermission(_fontUri); } } #endregion Private Methods //----------------------------------------------------- // // Private Classes // //------------------------------------------------------ #region Private Classes private class PinnedByteArrayStream : UnmanagedMemoryStream { ////// Critical - as this function calls GCHandle.Alloc and UnmanagedMemoryStream.Initialize methods /// which cause an elevation. /// TreatAsSafe - as this only pins and unpins an array of bytes. /// [SecurityCritical, SecurityTreatAsSafe] internal PinnedByteArrayStream(byte [] bits) { _memoryHandle = GCHandle.Alloc(bits, GCHandleType.Pinned); unsafe { // Initialize() method demands UnmanagedCode permission, and PinnedByteArrayStream is already marked as critical. new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); //Blessed Assert try { Initialize( (byte *)_memoryHandle.AddrOfPinnedObject(), bits.Length, bits.Length, FileAccess.Read ); } finally { SecurityPermission.RevertAssert(); } } } ~PinnedByteArrayStream() { Dispose(false); } ////// Critical: This code calls into GCHandle.Free which is link demanded /// TreatAsSafe: This code is ok to call. In the worst case it destroys some /// objects in the app /// [SecurityCritical,SecurityTreatAsSafe] protected override void Dispose(bool disposing) { base.Dispose(disposing); Debug.Assert(_memoryHandle.IsAllocated); _memoryHandle.Free(); } private GCHandle _memoryHandle; } #endregion Private Classes //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- #region Private Fields ////// Critical - fontUri can contain information about local file system. /// [SecurityCritical] private Uri _fontUri; ////// Critical - determines whether the font source was constructed from internal data, /// in which case the permission demand should be skipped. /// [SecurityCritical] private bool _skipDemand; private static SizeLimitedCache_resourceCache = new SizeLimitedCache (MaximumCacheItems); /// /// The maximum number of fonts downloaded from pack:// Uris. /// private const int MaximumCacheItems = 10; private const string ObfuscatedContentType = "application/vnd.ms-package.obfuscated-opentype"; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // Description: The FontSource class. // // History: // 08/04/2003 : mleonov - Created it // //--------------------------------------------------------------------------- using System; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Packaging; using System.Net; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Windows; using System.Windows.Media; using System.Windows.Threading; using MS.Win32; using MS.Utility; using MS.Internal; using MS.Internal.IO.Packaging; using MS.Internal.PresentationCore; namespace MS.Internal.FontCache { ////// FontSource class encapsulates the logic for dealing with fonts in memory or on the disk. /// It may or may not have a Uri associated with it, but there has to be some way to obtain its contents. /// internal class FontSource { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Critical - fontUri can contain information about local file system, skipDemand is used to make security decisions. /// [SecurityCritical] public FontSource(Uri fontUri, bool skipDemand) { _fontUri = fontUri; _skipDemand = skipDemand; Invariant.Assert(_fontUri.IsAbsoluteUri); Debug.Assert(String.IsNullOrEmpty(_fontUri.Fragment)); } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- #region Internal Methods ////// Critical - as this gives out full file path. /// [SecurityCritical] public string GetUriString() { return _fontUri.GetComponents(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped); } ////// Critical - as this gives out full file path. /// [SecurityCritical] public string ToStringUpperInvariant() { return GetUriString().ToUpperInvariant(); } ////// Critical - fontUri can contain information about local file system. /// TreatAsSafe - we only compute its hash code. /// [SecurityCritical, SecurityTreatAsSafe] public override int GetHashCode() { return HashFn.HashString(ToStringUpperInvariant(), 0); } ////// Critical - as this gives out full file path. /// public Uri Uri { [SecurityCritical] get { return _fontUri; } } ////// Critical - fontUri can contain information about local file system. /// TreatAsSafe - we only return a flag that says whether the Uri is app specific. /// public bool IsAppSpecific { [SecurityCritical, SecurityTreatAsSafe] get { return Util.IsAppSpecificUri(_fontUri); } } internal long SkipLastWriteTime() { // clients may choose to use this temporary method because GetLastWriteTime call // results in touching the file system // we need to resurrect this code when we come up with a complete solution // for updating fonts on the fly return -1; // any non-zero value will do here } ////// Critical - elevates to obtain the last write time for %windir%\fonts. /// Also, fontUri can contain information about local file system. /// TreatAsSafe - we only use it to obtain the last write time. /// [SecurityCritical, SecurityTreatAsSafe] internal DateTime GetLastWriteTimeUtc() { if (_fontUri.IsFile) { bool revertAssert = false; // Assert FileIORead permission for installed fonts. if (_skipDemand) { new FileIOPermission(FileIOPermissionAccess.Read, _fontUri.LocalPath).Assert(); //Blessed Assert revertAssert = true; } try { return Directory.GetLastWriteTimeUtc(_fontUri.LocalPath); } finally { if (revertAssert) CodeAccessPermission.RevertAssert(); } } // Any special value will do here. return DateTime.MaxValue; } ////// Critical - as this gives out UnmanagedMemoryStream content which is from a file. /// [SecurityCritical] internal UnmanagedMemoryStream GetUnmanagedStream() { if (_fontUri.IsFile) { FileMapping fileMapping = new FileMapping(); DemandFileIOPermission(); fileMapping.OpenFile(_fontUri.LocalPath); return fileMapping; } byte[] bits; // Try our cache first. lock (_resourceCache) { bits = _resourceCache.Get(_fontUri); } if (bits == null) { WebResponse response = WpfWebRequestHelper.CreateRequestAndGetResponse(_fontUri); Stream fontStream = response.GetResponseStream(); if (String.Equals(response.ContentType, ObfuscatedContentType, StringComparison.Ordinal)) { // The third parameter makes sure the original stream is closed // when the deobfuscating stream is disposed. fontStream = new DeobfuscatingStream(fontStream, _fontUri, false); } UnmanagedMemoryStream unmanagedStream = fontStream as UnmanagedMemoryStream; if (unmanagedStream != null) return unmanagedStream; bits = StreamToByteArray(fontStream); fontStream.Close(); lock (_resourceCache) { _resourceCache.Add(_fontUri, bits, false); } } return ByteArrayToUnmanagedStream(bits); } ////// Critical - as this gives out Stream content which is from a file. /// [SecurityCritical] internal Stream GetStream() { if (_fontUri.IsFile) { FileMapping fileMapping = new FileMapping(); DemandFileIOPermission(); fileMapping.OpenFile(_fontUri.LocalPath); return fileMapping; } byte[] bits; // Try our cache first. lock (_resourceCache) { bits = _resourceCache.Get(_fontUri); } if (bits != null) return new MemoryStream(bits); WebRequest request = PackWebRequestFactory.CreateWebRequest(_fontUri); WebResponse response = request.GetResponse(); Stream fontStream = response.GetResponseStream(); if (String.Equals(response.ContentType, ObfuscatedContentType, StringComparison.Ordinal)) { // The third parameter makes sure the original stream is closed // when the deobfuscating stream is disposed. fontStream = new DeobfuscatingStream(fontStream, _fontUri, false); } return fontStream; } #endregion Internal Methods //------------------------------------------------------ // // Private Methods // //------------------------------------------------------ #region Private Methods private static UnmanagedMemoryStream ByteArrayToUnmanagedStream(byte[] bits) { return new PinnedByteArrayStream(bits); } private static byte [] StreamToByteArray(Stream fontStream) { byte[] memoryFont; if (fontStream.CanSeek) { checked { memoryFont = new byte[(int)fontStream.Length]; PackagingUtilities.ReliableRead(fontStream, memoryFont, 0, (int)fontStream.Length); } } else { // this is inefficient, but works for now // we need to spend more time to implement a more performant // version of this code // ideally this should be a part of loader functionality // Initial file read buffer size is set to 1MB. int fileReadBufferSize = 1024 * 1024; byte[] fileReadBuffer = new byte[fileReadBufferSize]; // Actual number of bytes read from the file. int memoryFontSize = 0; for (; ; ) { int availableBytes = fileReadBufferSize - memoryFontSize; if (availableBytes < fileReadBufferSize / 3) { // grow the fileReadBuffer fileReadBufferSize *= 2; byte[] newBuffer = new byte[fileReadBufferSize]; Array.Copy(fileReadBuffer, newBuffer, memoryFontSize); fileReadBuffer = newBuffer; availableBytes = fileReadBufferSize - memoryFontSize; } int numberOfBytesRead = fontStream.Read(fileReadBuffer, memoryFontSize, availableBytes); if (numberOfBytesRead == 0) break; memoryFontSize += numberOfBytesRead; } // Actual number of bytes read from the file is less or equal to the file read buffer size. Debug.Assert(memoryFontSize <= fileReadBufferSize); if (memoryFontSize == fileReadBufferSize) memoryFont = fileReadBuffer; else { // Trim the array if needed to that it contains the right length. memoryFont = new byte[memoryFontSize]; Array.Copy(fileReadBuffer, memoryFont, memoryFontSize); } } return memoryFont; } ////// Demand read permissions for all fonts except system ones. /// ////// Critical - as this function calls critical WindowsFontsUriObject. /// TreatAsSafe - as the WindowsFontsUriObject is used to determine whether to demand permissions. /// [SecurityCritical, SecurityTreatAsSafe] private void DemandFileIOPermission() { // Demand FileIORead permission for any non-system fonts. if (!_skipDemand) { SecurityHelper.DemandUriReadPermission(_fontUri); } } #endregion Private Methods //----------------------------------------------------- // // Private Classes // //------------------------------------------------------ #region Private Classes private class PinnedByteArrayStream : UnmanagedMemoryStream { ////// Critical - as this function calls GCHandle.Alloc and UnmanagedMemoryStream.Initialize methods /// which cause an elevation. /// TreatAsSafe - as this only pins and unpins an array of bytes. /// [SecurityCritical, SecurityTreatAsSafe] internal PinnedByteArrayStream(byte [] bits) { _memoryHandle = GCHandle.Alloc(bits, GCHandleType.Pinned); unsafe { // Initialize() method demands UnmanagedCode permission, and PinnedByteArrayStream is already marked as critical. new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); //Blessed Assert try { Initialize( (byte *)_memoryHandle.AddrOfPinnedObject(), bits.Length, bits.Length, FileAccess.Read ); } finally { SecurityPermission.RevertAssert(); } } } ~PinnedByteArrayStream() { Dispose(false); } ////// Critical: This code calls into GCHandle.Free which is link demanded /// TreatAsSafe: This code is ok to call. In the worst case it destroys some /// objects in the app /// [SecurityCritical,SecurityTreatAsSafe] protected override void Dispose(bool disposing) { base.Dispose(disposing); Debug.Assert(_memoryHandle.IsAllocated); _memoryHandle.Free(); } private GCHandle _memoryHandle; } #endregion Private Classes //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- #region Private Fields ////// Critical - fontUri can contain information about local file system. /// [SecurityCritical] private Uri _fontUri; ////// Critical - determines whether the font source was constructed from internal data, /// in which case the permission demand should be skipped. /// [SecurityCritical] private bool _skipDemand; private static SizeLimitedCache_resourceCache = new SizeLimitedCache (MaximumCacheItems); /// /// The maximum number of fonts downloaded from pack:// Uris. /// private const int MaximumCacheItems = 10; private const string ObfuscatedContentType = "application/vnd.ms-package.obfuscated-opentype"; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- AssemblyBuilder.cs
- XmlSchemaInferenceException.cs
- CompilationRelaxations.cs
- GeneralTransformGroup.cs
- SoapAttributes.cs
- InputLangChangeRequestEvent.cs
- XmlSerializableReader.cs
- XPathEmptyIterator.cs
- StreamDocument.cs
- MatchingStyle.cs
- TransactionOptions.cs
- TextDocumentView.cs
- BooleanToSelectiveScrollingOrientationConverter.cs
- ActivityBuilder.cs
- XmlNodeList.cs
- MouseBinding.cs
- Trace.cs
- TdsParserSessionPool.cs
- Table.cs
- XmlSchemaSearchPattern.cs
- Listbox.cs
- PerformanceCounterManager.cs
- SqlProfileProvider.cs
- SchemaImporter.cs
- MexServiceChannelBuilder.cs
- BindingNavigatorDesigner.cs
- URLAttribute.cs
- InteropAutomationProvider.cs
- UnsafeNativeMethods.cs
- TableStyle.cs
- EncoderParameter.cs
- TableFieldsEditor.cs
- TreeView.cs
- BindingCollectionElement.cs
- DispatcherProcessingDisabled.cs
- DesignerActionService.cs
- XXXInfos.cs
- ListenerServiceInstallComponent.cs
- StrongNameIdentityPermission.cs
- TrackingServices.cs
- DictionaryMarkupSerializer.cs
- WindowsScrollBarBits.cs
- SafeNativeMethodsMilCoreApi.cs
- UpdatePanel.cs
- EasingQuaternionKeyFrame.cs
- MemoryRecordBuffer.cs
- TextServicesCompartmentEventSink.cs
- EmbeddedMailObjectsCollection.cs
- SiteMapPath.cs
- FontStretchConverter.cs
- XmlArrayItemAttributes.cs
- MeasureItemEvent.cs
- XmlSchemaValidationException.cs
- WorkflowOperationFault.cs
- SafeNativeMemoryHandle.cs
- Assembly.cs
- TreeNode.cs
- StandardOleMarshalObject.cs
- HwndProxyElementProvider.cs
- MetadataLocation.cs
- ApplicationHost.cs
- ProtocolsConfigurationHandler.cs
- MdiWindowListStrip.cs
- XamlTemplateSerializer.cs
- ComponentConverter.cs
- InitialServerConnectionReader.cs
- WindowsProgressbar.cs
- StylusPointDescription.cs
- AuthorizationRuleCollection.cs
- AnimationClock.cs
- XmlSchemaSet.cs
- LineServicesRun.cs
- InvalidOperationException.cs
- DataContractSerializerFaultFormatter.cs
- EncryptedType.cs
- WebBrowserHelper.cs
- SqlServer2KCompatibilityCheck.cs
- ADConnectionHelper.cs
- PersonalizationState.cs
- RuleRefElement.cs
- QueryOperationResponseOfT.cs
- TreeNodeCollection.cs
- IncrementalHitTester.cs
- MembershipValidatePasswordEventArgs.cs
- PipeConnection.cs
- ListControlConvertEventArgs.cs
- TrackBar.cs
- PreviewPrintController.cs
- XmlNodeChangedEventArgs.cs
- SQLMoneyStorage.cs
- ToolStripSeparatorRenderEventArgs.cs
- ImpersonateTokenRef.cs
- CodeMethodReturnStatement.cs
- SqlCacheDependencyDatabase.cs
- FormDesigner.cs
- SingleAnimation.cs
- ItemCheckEvent.cs
- ChildrenQuery.cs
- ChooseAction.cs
- TitleStyle.cs