Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / MS / Internal / FontCache / FontSource.cs / 2 / FontSource.cs
//---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // Description: The FontSource class. // // History: // 08/04/2003 : [....] - 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PathTooLongException.cs
- DataGridViewEditingControlShowingEventArgs.cs
- QilFunction.cs
- Control.cs
- XmlRootAttribute.cs
- MapPathBasedVirtualPathProvider.cs
- ObjectDataSourceSelectingEventArgs.cs
- TypeUsage.cs
- WorkflowInlining.cs
- StructuredTypeEmitter.cs
- AlternateViewCollection.cs
- DeviceContexts.cs
- URIFormatException.cs
- EvidenceBase.cs
- EpmHelper.cs
- ValueQuery.cs
- DefinitionUpdate.cs
- PerspectiveCamera.cs
- DbParameterCollectionHelper.cs
- BuildResult.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- ListBindingHelper.cs
- UidManager.cs
- WebFormDesignerActionService.cs
- DBConcurrencyException.cs
- GPRECTF.cs
- RSAOAEPKeyExchangeDeformatter.cs
- FormsAuthentication.cs
- ToolStrip.cs
- GroupBox.cs
- SimpleModelProvider.cs
- SqlNodeAnnotations.cs
- ExpressionVisitor.cs
- PropertyConverter.cs
- Variant.cs
- DbCommandDefinition.cs
- CultureTable.cs
- DbReferenceCollection.cs
- TableRowGroup.cs
- FrameworkElement.cs
- mediaclock.cs
- FileInfo.cs
- AnimationClock.cs
- AdornerDecorator.cs
- OpCopier.cs
- ProxyHelper.cs
- TaiwanCalendar.cs
- AssemblyCollection.cs
- SafeHandle.cs
- BroadcastEventHelper.cs
- WorkflowInstanceExtensionManager.cs
- CalendarDay.cs
- LinkTarget.cs
- GregorianCalendarHelper.cs
- DateTimeUtil.cs
- ReadOnlyDataSourceView.cs
- DynamicRouteExpression.cs
- InputReportEventArgs.cs
- TemplateManager.cs
- IPAddress.cs
- ToolTipService.cs
- OutOfProcStateClientManager.cs
- TabItemAutomationPeer.cs
- XmlValidatingReader.cs
- AccessedThroughPropertyAttribute.cs
- DataMemberConverter.cs
- XmlValidatingReaderImpl.cs
- DWriteFactory.cs
- SubpageParaClient.cs
- OleDbError.cs
- DesignerExtenders.cs
- MenuItemStyle.cs
- _CookieModule.cs
- Ppl.cs
- GridViewAutomationPeer.cs
- Metadata.cs
- TextTreeUndoUnit.cs
- EventListener.cs
- RouteData.cs
- EmptyEnumerable.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- WebRequest.cs
- SelectionItemPattern.cs
- SoapEnumAttribute.cs
- SQLDouble.cs
- HotSpotCollection.cs
- TrailingSpaceComparer.cs
- _SSPIWrapper.cs
- ParsedAttributeCollection.cs
- XsltSettings.cs
- Style.cs
- ServiceDescriptionData.cs
- HierarchicalDataBoundControlAdapter.cs
- Compilation.cs
- X509SecurityToken.cs
- ProtectedConfiguration.cs
- GridViewDeleteEventArgs.cs
- PaperSize.cs
- SSmlParser.cs
- XmlCharCheckingWriter.cs