FontSourceCollection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / MS / Internal / FontCache / FontSourceCollection.cs / 1 / FontSourceCollection.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Description: The FontSourceCollection class represents a collection of font files. 
//
// History: 
//  08/25/2005 : [....] - Created it 
//
//--------------------------------------------------------------------------- 

using System;
using System.Collections.Generic;
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 Microsoft.Win32;
 
using MS.Win32;
using MS.Utility;
using MS.Internal;
using MS.Internal.IO.Packaging; 

using MS.Internal.PresentationCore; 
 
namespace MS.Internal.FontCache
{ 
    /// 
    /// FontSourceCollection class represents a collection of font files.
    /// 
    internal class FontSourceCollection : IEnumerable 
    {
        ///  
        /// Critical - The folderUri parameter is critical as it may contain privileged information 
        ///            about the file system (i.e., location of Windows Fonts); it is assigned to
        ///            the _uri field which is declared critical. 
        ///
        ///            The isWindowsFonts parameter is critical for set as it is used to make a
        ///            security decision (i.e., whether to assert read access); it is assigned to
        ///            the _isWindowsFonts field which is declared critical. 
        /// 
        [SecurityCritical] 
        public FontSourceCollection(Uri folderUri, bool isWindowsFonts) 
        {
            if (!Util.IsEnumerableFontUriScheme(folderUri)) 
            {
                throw new ArgumentException(SR.Get(SRID.UriMustBeFileOrPack));
            }
 
            _uri = folderUri;
            _isWindowsFonts = isWindowsFonts; 
 
            InitializeDirectoryProperties();
        } 

        /// 
        /// Critical - _uri can contain information about local file system.
        /// TreatAsSafe - exposing one bit of information about whether it's application specific is safe. 
        /// 
        public bool IsAppSpecific 
        { 
            [SecurityCritical, SecurityTreatAsSafe]
            get 
            {
                return Util.IsAppSpecificUri(_uri);
            }
        } 

        public long TimeStamp 
        { 
            get
            { 
                return _timeStamp;
            }
        }
 
        /// 
        ///     Critical: This code accesses _uri and local Windows\fonts path. 
        ///     It also elevates to access the GetLastWriteTimeUtc, Exists and GetRegistryKeyLastWriteTimeUtc functions. 
        ///     Safe: This only does an elevation for WindowsFont directory and Fonts registry key.
        ///           Both are safe. For anything else CAS will kick in and demand FileIORead permission. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void InitializeDirectoryProperties()
        { 
            _timeStamp = -1;
            _isFileSystemFolder = false; 
 
            if (_uri.IsFile)
            { 
                string localPath;

                if (_isWindowsFonts)
                { 
                    if (object.ReferenceEquals(_uri, Util.WindowsFontsUriObject))
                    { 
                        // We know the local path and that it's a folder 
                        localPath = Util.WindowsFontsLocalPath;
                        _isFileSystemFolder = true; 
                    }
                    else
                    {
                        // It's a file within the Windows Fonts folder 
                        localPath = _uri.LocalPath;
                        _isFileSystemFolder = false; 
                    } 

                    // Allow any client to access default fonts collection 
                    new FileIOPermission(
                        FileIOPermissionAccess.Read,
                        localPath).Assert(); // BlessedAssert
                } 
                else
                { 
                    // Get the local path 
                    localPath = _uri.LocalPath;
 
                    // Decide if it's a file or folder based on syntax, not contents of file system
                    _isFileSystemFolder = localPath[localPath.Length - 1] == Path.DirectorySeparatorChar;
                }
 
                try
                { 
                    if (_isFileSystemFolder) 
                    {
                        // DirectoryInfo does a demand to check the client code's access to the folder 
                        DirectoryInfo directoryInfo = new DirectoryInfo(localPath);
                        if (directoryInfo.Exists)
                        {
                            _timeStamp = directoryInfo.LastWriteTimeUtc.Ticks; 
                        }
                        if (_isWindowsFonts) 
                        { 
                            long registryTimeStamp;
                            if (Util2.GetRegistryKeyLastWriteTimeUtc(InstalledWindowsFontsRegistryKey, out registryTimeStamp)) 
                            {
                                _timeStamp = Math.Max(_timeStamp, registryTimeStamp);
                            }
                        } 
                    }
                    else 
                    { 
                        FileInfo fileInfo = new FileInfo(localPath);
                        if (fileInfo.Exists) 
                           _timeStamp = fileInfo.LastWriteTimeUtc.Ticks;
                    }
                }
                finally 
                {
                    if (_isWindowsFonts) 
                        FileIOPermission.RevertAssert(); 
                }
            } 
        }

        /// 
        /// Critical - as this allows you list files in windows font directory 
        ///            and returns the file list.
        /// Safe - This only does an elevation for WindowsFont directory which is safe, 
        ///            and relevant data is already protected via FontSource methods. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private void SetFontSources()
        {
            if (_fontSources != null)
                return; 

            lock (this) 
            { 
                List fontSources;
                if (_uri.IsFile) 
                {
                    ICollection files;
                    if (_isFileSystemFolder)
                    { 
                        if (_isWindowsFonts)
                        { 
                            PermissionSet permissionSet = new PermissionSet(null); 

                            // Read and path discovery permission for the %windir%\font path. 
                            permissionSet.AddPermission(new FileIOPermission(
                                FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery,
                                Util.WindowsFontsUriObject.LocalPath));
 
                            // Registry read permissions for the Fonts system registry entry.
                            permissionSet.AddPermission(new RegistryPermission( 
                                RegistryPermissionAccess.Read, 
                                InstalledWindowsFontsRegistryKeyFullPath));
 
                            permissionSet.Assert(); // BlessedAssert

                            try
                            { 
                                // fontPaths accumulates font file paths obtained from the registry and the file system
                                // This collection is a set, i.e. only keys matter, not values. 
                                Dictionary fontPaths = new Dictionary(512, StringComparer.OrdinalIgnoreCase); 

                                using (RegistryKey fontsKey = Registry.LocalMachine.OpenSubKey(InstalledWindowsFontsRegistryKey)) 
                                {
                                    // The registry key should be present on a valid Windows installation.
                                    Invariant.Assert(fontsKey != null);
 
                                    foreach (string fontValue in fontsKey.GetValueNames())
                                    { 
                                        string fileName = fontsKey.GetValue(fontValue) as string; 
                                        if (fileName != null)
                                        { 
                                            // See if the path doesn't contain any directory information.
                                            // Shell uses the same method to determine whether to prepend the path with %windir%\fonts.
                                            if (Path.GetFileName(fileName) == fileName)
                                                fileName = Path.Combine(Util.WindowsFontsLocalPath, fileName); 

                                            fontPaths[fileName] = null; 
                                        } 
                                    }
                                } 

                                foreach (string file in Directory.GetFiles(_uri.LocalPath))
                                {
                                    fontPaths[file] = null; 
                                }
                                files = fontPaths.Keys; 
                            } 
                            finally
                            { 
                                if (_isWindowsFonts)
                                    CodeAccessPermission.RevertAssert();
                            }
 
                        }
                        else 
                        { 
                            files = Directory.GetFiles(_uri.LocalPath);
                        } 
                    }
                    else
                    {
                        files = new string[1] {_uri.LocalPath}; 
                    }
                    fontSources = new List(files.Count); 
                    foreach (string file in files) 
                    {
                        bool isComposite; 
                        if (Util.IsSupportedFontExtension(Path.GetExtension(file), out isComposite))
                            fontSources.Add(new FontSource(new Uri(file, UriKind.Absolute), _isWindowsFonts));
                    }
                } 
                else
                { 
                    List resourceEntries = FontResourceCache.LookupFolder(_uri); 

                    if (resourceEntries == null) 
                        fontSources = new List(0);
                    else
                    {
                        // Enumerate application resources, content files and container structure. 
                        fontSources = new List(resourceEntries.Count);
 
                        foreach (string resourceName in resourceEntries) 
                        {
                            // If resourceName is an empty string, this means that the _uri is a full file name; 
                            // otherwise resourceName is a file name within a folder.
                            if (String.IsNullOrEmpty(resourceName))
                                fontSources.Add(new FontSource(_uri, _isWindowsFonts));
                            else 
                                fontSources.Add(new FontSource(new Uri(_uri, resourceName), _isWindowsFonts));
                        } 
                    } 
                }
 
                _fontSources = fontSources;
            }
        }
 
        /// 
        /// Critical - as this returns a local Uri. 
        ///  
        private string ComparisonKey
        { 
            [SecurityCritical]
            get
            {
                // Local file paths and pack Uris in container/applications scenarios are all case insensitive. 
                return GetUriString().ToUpperInvariant();
            } 
        } 

        #region IEnumerable Members 

        public IEnumerator GetEnumerator()
        {
            SetFontSources(); 
            return _fontSources.GetEnumerator();
        } 
 
        #endregion
 
        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        { 
            SetFontSources();
            return _fontSources.GetEnumerator(); 
        } 

        #endregion 

        /// 
        /// Critical - fontUri can contain information about local file system.
        ///  
        [SecurityCritical]
        public string GetUriString() 
        { 
            return _uri.GetComponents(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
        } 

        /// 
        /// Critical - font Uri can contain information about local file system.
        /// TreatAsSafe - we only compute its hash code. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        public override int GetHashCode() 
        {
            return HashFn.HashString(ComparisonKey, 0); 
        }

        public override bool Equals(object obj)
        { 
            FontSourceCollection other = obj as FontSourceCollection;
            if (other == null) 
                return false; 
            return Equals(other);
        } 

        /// 
        /// Critical - fontUri can contain information about local file system.
        /// TreatAsSafe - we only use it for quality comparison. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        public bool Equals(FontSourceCollection other) 
        {
            return String.Equals(ComparisonKey, other.ComparisonKey, StringComparison.Ordinal); 
        }

        /// 
        /// Critical - fontUri can contain information about local file system. 
        /// 
        [SecurityCritical] 
        private Uri                         _uri; 

        private long                        _timeStamp; 

        /// 
        /// Critical - this value is used to make security decisions (i.e., whether to do an Assert)
        ///            so it can only be set by critical code. 
        /// 
        [SecurityCritical] 
        private bool                        _isWindowsFonts; 

        // _isFileSystemFolder flag makes sense only when _uri.IsFile is set to true. 
        private bool                        _isFileSystemFolder;
        private volatile IList  _fontSources;

        private const string InstalledWindowsFontsRegistryKey = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"; 
        private const string InstalledWindowsFontsRegistryKeyFullPath = @"HKEY_LOCAL_MACHINE\" + InstalledWindowsFontsRegistryKey;
 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK