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
- TraceShell.cs
- ConfigXmlCDataSection.cs
- RunInstallerAttribute.cs
- XmlNamespaceMappingCollection.cs
- ZoneIdentityPermission.cs
- HtmlInputText.cs
- SqlFormatter.cs
- BrowserCapabilitiesCodeGenerator.cs
- WebPartTracker.cs
- XmlTypeMapping.cs
- SQLByteStorage.cs
- CreateUserWizard.cs
- ConfigXmlSignificantWhitespace.cs
- PageBuildProvider.cs
- InternalPermissions.cs
- PeerNodeTraceRecord.cs
- SqlColumnizer.cs
- ReadContentAsBinaryHelper.cs
- _Win32.cs
- CodeCatchClauseCollection.cs
- NameValueConfigurationElement.cs
- CompiledIdentityConstraint.cs
- DynamicResourceExtensionConverter.cs
- FixedSOMGroup.cs
- UserControlAutomationPeer.cs
- Base64Stream.cs
- shaperfactoryquerycachekey.cs
- InvokeWebServiceDesigner.cs
- RequestCachePolicy.cs
- AppDomainShutdownMonitor.cs
- ElementAction.cs
- SQLDouble.cs
- UnsafeNativeMethods.cs
- TextDpi.cs
- WebProxyScriptElement.cs
- DBSqlParserTable.cs
- Journal.cs
- MaterialGroup.cs
- TextBox.cs
- ZipIOExtraFieldZip64Element.cs
- SQLDecimal.cs
- _SSPIWrapper.cs
- InternalsVisibleToAttribute.cs
- GridViewColumnCollectionChangedEventArgs.cs
- WebBrowserBase.cs
- GridViewColumnHeaderAutomationPeer.cs
- MsmqTransportReceiveParameters.cs
- Propagator.Evaluator.cs
- ImportedNamespaceContextItem.cs
- UIElement3D.cs
- PartBasedPackageProperties.cs
- ThicknessConverter.cs
- ElementAction.cs
- ToolStripDropDownButton.cs
- ReceiveActivityDesigner.cs
- FileNotFoundException.cs
- XpsFilter.cs
- SectionInput.cs
- SegmentInfo.cs
- NumberSubstitution.cs
- Win32.cs
- PolyLineSegment.cs
- diagnosticsswitches.cs
- PrivilegedConfigurationManager.cs
- RuntimeConfigurationRecord.cs
- XamlTypeMapper.cs
- SpellerStatusTable.cs
- AppLevelCompilationSectionCache.cs
- DbModificationCommandTree.cs
- PrimitiveType.cs
- PageWrapper.cs
- TypeReference.cs
- UrlMappingsModule.cs
- CharacterMetricsDictionary.cs
- WebConfigurationHost.cs
- ApplicationInfo.cs
- MobileRedirect.cs
- MaskedTextBox.cs
- BroadcastEventHelper.cs
- SID.cs
- Dump.cs
- PermissionRequestEvidence.cs
- XmlSerializableServices.cs
- SequentialUshortCollection.cs
- XmlSchemaObjectCollection.cs
- Helper.cs
- CodeComment.cs
- TableSectionStyle.cs
- ObservableCollectionDefaultValueFactory.cs
- CommonDialog.cs
- ItemsControlAutomationPeer.cs
- ControlPaint.cs
- GeneralTransformCollection.cs
- MetadataResolver.cs
- ConfigurationSection.cs
- TemplateBamlRecordReader.cs
- EndPoint.cs
- XmlNodeReader.cs
- Geometry3D.cs
- DefaultValueAttribute.cs