Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / FontCache / FontSource.cs / 1305600 / 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; using MS.Internal.Text.TextInterface; namespace MS.Internal.FontCache { internal class FontSourceFactory : IFontSourceFactory { public FontSourceFactory() { } ////// Critical - retreives security sensitive info about a FontSource like raw font data. /// Safe - does a demand before it gives out the information asked. /// [SecurityCritical, SecurityTreatAsSafe] public IFontSource Create(string uriString) { return new FontSource(new Uri(uriString), false); } } ////// 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 : IFontSource { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Critical - Calls Security Critical method Initialize(). /// [SecurityCritical] public FontSource(Uri fontUri, bool skipDemand) { Initialize(fontUri, skipDemand, false); } ////// Critical - Calls Security Critical method Initialize(). /// [SecurityCritical] public FontSource(Uri fontUri, bool skipDemand, bool isComposite) { Initialize(fontUri, skipDemand, isComposite); } ////// Critical - fontUri can contain information about local file system, skipDemand is used to make security decisions. /// [SecurityCritical] private void Initialize(Uri fontUri, bool skipDemand, bool isComposite) { _fontUri = fontUri; _skipDemand = skipDemand; _isComposite = isComposite; Invariant.Assert(_fontUri.IsAbsoluteUri); Debug.Assert(String.IsNullOrEmpty(_fontUri.Fragment)); } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- #region Internal Methods public bool IsComposite { get { return _isComposite; } } ////// 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] public 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] public 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); } ////// Tries to open a file and throws exceptions in case of failures. This /// method is used to achieve the same exception throwing behavior after /// integrating DWrite. /// ////// Critical - accesses security critical method FileMapping.OpenFile /// TreatAsSafe - Does not give out sensitive info. /// [SecurityCritical, SecurityTreatAsSafe] public void TestFileOpenable() { if (_fontUri.IsFile) { FileMapping fileMapping = new FileMapping(); DemandFileIOPermission(); fileMapping.OpenFile(_fontUri.LocalPath); fileMapping.Close(); } } ////// Critical - as this gives out Stream content which is from a file. /// [SecurityCritical] public 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 private bool _isComposite; ////// 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
- LicenseException.cs
- SoapDocumentServiceAttribute.cs
- WizardForm.cs
- AccessorTable.cs
- GridPatternIdentifiers.cs
- NetworkAddressChange.cs
- DataAdapter.cs
- SwitchCase.cs
- Transform.cs
- Quad.cs
- IconEditor.cs
- WinCategoryAttribute.cs
- SyndicationSerializer.cs
- ContentControl.cs
- BooleanFunctions.cs
- CookielessHelper.cs
- ItemPager.cs
- BindingSource.cs
- OdbcCommandBuilder.cs
- HtmlToClrEventProxy.cs
- InstanceDataCollection.cs
- StreamResourceInfo.cs
- Timer.cs
- SystemIPAddressInformation.cs
- ClientConfigurationHost.cs
- ComponentDispatcher.cs
- InputProcessorProfiles.cs
- QuaternionAnimationBase.cs
- ReadOnlyObservableCollection.cs
- XmlDeclaration.cs
- CultureSpecificStringDictionary.cs
- GroupStyle.cs
- ResourceProviderFactory.cs
- ConnectionString.cs
- SmiGettersStream.cs
- GridSplitter.cs
- SecurityManager.cs
- RegistrationServices.cs
- FormClosedEvent.cs
- CodeExporter.cs
- ToolStripActionList.cs
- oledbconnectionstring.cs
- RegistryExceptionHelper.cs
- SmtpLoginAuthenticationModule.cs
- BindingOperations.cs
- SHA256.cs
- ProcessHostServerConfig.cs
- TrackBar.cs
- ReadOnlyCollectionBase.cs
- DynamicUpdateCommand.cs
- IdentityReference.cs
- SelectionPattern.cs
- DbDataReader.cs
- WebPartCatalogAddVerb.cs
- WebPartZoneCollection.cs
- BitmapImage.cs
- WebHttpSecurity.cs
- SkipStoryboardToFill.cs
- TemplateBamlTreeBuilder.cs
- TdsParserHelperClasses.cs
- UTF8Encoding.cs
- TextTreeInsertElementUndoUnit.cs
- Policy.cs
- MachineKeyConverter.cs
- ParseNumbers.cs
- UserCancellationException.cs
- ExpressionBuilder.cs
- IndexerNameAttribute.cs
- EventBindingService.cs
- GridLength.cs
- EmptyStringExpandableObjectConverter.cs
- ActivityDesigner.cs
- DataGridToolTip.cs
- WeakReference.cs
- ScriptingWebServicesSectionGroup.cs
- ListParagraph.cs
- HtmlTableCell.cs
- System.Data_BID.cs
- DebugController.cs
- UInt16Storage.cs
- IndependentAnimationStorage.cs
- SspiHelper.cs
- ToolStripTemplateNode.cs
- XmlRootAttribute.cs
- EntityDataSourceWrapperPropertyDescriptor.cs
- VisualStyleInformation.cs
- Registry.cs
- WebBrowserUriTypeConverter.cs
- ThrowHelper.cs
- DataGridViewAdvancedBorderStyle.cs
- LocatorPart.cs
- KeyFrames.cs
- SoapAttributeOverrides.cs
- Point3D.cs
- HighlightComponent.cs
- ClientScriptManager.cs
- sortedlist.cs
- SR.cs
- EncryptedKeyHashIdentifierClause.cs
- ColumnClickEvent.cs