Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / SystemResources.cs / 5 / SystemResources.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Resources; using System.Runtime.InteropServices; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Security; using System.Security.Permissions; using System.Windows.Threading; using System.Text; using MS.Utility; using System.Windows.Controls.Primitives; using System.Windows.Markup; using System.Windows.Documents; using System.Windows.Media; using System.Windows.Input; using System.Windows.Resources; using MS.Win32; using MS.Internal; using MS.Internal.Ink; using MS.Internal.PresentationFramework; // SafeSecurityHelper // Disable pragma warnings to enable PREsharp pragmas #pragma warning disable 1634, 1691 namespace System.Windows { ////// SystemResources loads system theme data into the system resources collection. /// internal static class SystemResources { // ------------------------------------------------ // // Methods // // ------------------------------------------------ #region Methods ////// Returns a resource for the given key type from the system resources collection. /// /// The resource id to search for. ///The resource if it exists, null otherwise. //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 internal static object FindThemeStyle(DependencyObjectType key) { // Find a cached theme style object resource = _themeStyleCache[key]; if (resource != null) { // Found a cached value if (resource == _specialNull) { // We cached a null, set it to a real null return null; // Null resource found } return resource; } // Find the resource from the system resources collection resource = FindResourceInternal(key.SystemType); // The above read operation was lock free. Writing // to the cache will need a lock though lock (ThemeDictionaryLock) { if (resource != null) { // Cache the value _themeStyleCache[key] = resource; } else { // Record nulls so we don't bother doing lookups for them later // Any theme changes will clear these values _themeStyleCache[key] = _specialNull; } } return resource; } ////// Returns a resource of the given name from the system resources collection. /// /// The resource id to search for. ///The resource if it exists, null otherwise. //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 internal static object FindResourceInternal(object key) { // Call Forwarded return FindResourceInternal(key, false /*allowDeferredResourceReference*/, false /*mustReturnDeferredResourceReference*/); } internal static object FindResourceInternal(object key, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference) { // Ensure that resource changes on this thread can be heard and handled EnsureResourceChangeListener(); object resource = null; Type typeKey = null; ResourceKey resourceKey = null; bool isTraceEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose); // System resource keys can only be of type Type or of type ResourceKey typeKey = key as Type; resourceKey = (typeKey == null) ? (key as ResourceKey) : null; if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCEFINDGUID), MS.Utility.EventType.StartEvent, (key == null) ? "null" : key.ToString()); } if ((typeKey == null) && (resourceKey == null)) { // Not a valid key if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCEFINDGUID), MS.Utility.EventType.EndEvent); } return null; } // Check if the value was already cached if (!FindCachedResource(key, ref resource, mustReturnDeferredResourceReference)) { // Cache miss, do a lookup if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCECACHEMISSGUID), MS.Utility.EventType.Info); } lock (ThemeDictionaryLock) { bool canCache = true; SystemResourceKey sysKey = (resourceKey != null) ? resourceKey as SystemResourceKey : null; if (sysKey != null) { // Check the list of system metrics if (!mustReturnDeferredResourceReference) { resource = sysKey.Resource; } else { resource = new DeferredResourceReferenceHolder(sysKey, sysKey.Resource); } if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCESTOCKGUID), MS.Utility.EventType.Info, sysKey.ToString()); } } else { // Do a dictionary lookup resource = FindDictionaryResource(key, typeKey, resourceKey, isTraceEnabled, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); } if ((canCache && !allowDeferredResourceReference) || resource == null) { // Cache the resource CacheResource(key, resource, isTraceEnabled); } } } if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCEFINDGUID), MS.Utility.EventType.EndEvent); } return resource; } #endregion // ------------------------------------------------ // // Implementation // // ------------------------------------------------ #region Implementation //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 internal static void CacheResource(object key, object resource, bool isTraceEnabled) { // Thread safety handled by FindResourceInternal. Be sure to have locked _resourceCache.SyncRoot. if (resource != null) { // Cache the value _resourceCache[key] = resource; if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCECACHEVALUEGUID), MS.Utility.EventType.Info); } } else { // Record nulls so we don't bother doing lookups for them later // Any theme changes will clear these values _resourceCache[key] = _specialNull; if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCECACHENULLGUID), MS.Utility.EventType.Info); } } } #region Resource Value Lookup private static bool FindCachedResource(object key, ref object resource, bool mustReturnDeferredResourceReference) { // reading the cache is lock free resource = _resourceCache[key]; bool found = (resource != null); if (resource == _specialNull) { // We cached a null, set it to a real null resource = null; } else { DispatcherObject dispatcherObject = resource as DispatcherObject; if (dispatcherObject != null) { // The current thread may not have access to this object. dispatcherObject.VerifyAccess(); } } if (found && mustReturnDeferredResourceReference) { resource = new DeferredResourceReferenceHolder(key, resource); } return found; } ////// Searches for a resource inside a ResourceDictionary. /// /// The original key. /// The key cast to Type. /// The key cast to ResourceKey. /// Tracing on/off. /// /// If this flag is true the resource will not actually be inflated from Baml. /// Instead we will return an instance of DeferredDictionaryReference which /// can later be used to query the resource /// /// /// If this method is true this method will always return a /// DeferredThemeResourceReference instance which envelopes the underlying resource. /// /// Whether callers can cache the value. ///private static object FindDictionaryResource( object key, Type typeKey, ResourceKey resourceKey, bool isTraceEnabled, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference, out bool canCache) { // Thread safety handled by FindResourceInternal. Be sure to have locked _resourceCache.SyncRoot. Debug.Assert(typeKey != null || resourceKey != null, "typeKey or resourceKey should be non-null"); canCache = true; object resource = null; Assembly assembly = (typeKey != null) ? typeKey.Assembly : resourceKey.Assembly; if ((assembly == null) || IgnoreAssembly(assembly)) { // Without an assembly, we can't figure out which dictionary to look at. // Also, ignore some common assemblies we know to not contain resources. return null; } ResourceDictionaries dictionaries = EnsureDictionarySlot(assembly); ResourceDictionary dictionary = dictionaries.LoadThemedDictionary(isTraceEnabled); if (dictionary != null) { resource = LookupResourceInDictionary(dictionary, key, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); } if (resource == null) { dictionary = dictionaries.LoadGenericDictionary(isTraceEnabled); if (dictionary != null) { resource = LookupResourceInDictionary(dictionary, key, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); } } if (resource != null) { // Resources coming out of the dictionary may need to be frozen Freeze(resource); } return resource; } /// /// Looks in the ResourceDictionary for the desired resource. /// /// The ResourceDictionary to look in. /// The key for the resource. /// /// If this flag is true the resource will not actually be inflated from Baml. /// Instead we will return an instance of DeferredDictionaryReference which /// can later be used to query the resource /// /// /// If this method is true this method will always return a /// DeferredThemeResourceReference instance which envelopes the underlying resource. /// /// Whether callers should cache the value. ///The resource if found and successfully loaded, null otherwise. private static object LookupResourceInDictionary( ResourceDictionary dictionary, object key, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference, out bool canCache) { object resource = null; IsSystemResourcesParsing = true; try { resource = dictionary.FetchResource(key, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); } finally { IsSystemResourcesParsing = false; } return resource; } ////// Unbinds a Freezable from its Context. /// /// The resource to freeze. private static void Freeze(object resource) { Freezable freezable = resource as Freezable; if (freezable != null && !freezable.IsFrozen) { freezable.Freeze(); } } #endregion #region Dictionary Loading ////// Returns the dictionary cache slot associated with the given assembly. /// /// The desired assembly ///The cache slot. private static ResourceDictionaries EnsureDictionarySlot(Assembly assembly) { ResourceDictionaries dictionaries = null; if (_dictionaries != null) { _dictionaries.TryGetValue(assembly, out dictionaries); } else { // We will be caching data, create the cache _dictionaries = new Dictionary(1); } if (dictionaries == null) { // Ensure the cache slot is created dictionaries = new ResourceDictionaries(assembly); _dictionaries.Add(assembly, dictionaries); } return dictionaries; } private static bool IgnoreAssembly(Assembly assembly) { return (assembly == MsCorLib) || (assembly == PresentationCore) || (assembly == WindowsBase); } private static Assembly MsCorLib { get { if (_mscorlib == null) { _mscorlib = typeof(string).Assembly; } return _mscorlib; } } private static Assembly PresentationFramework { get { if (_presentationFramework == null) { _presentationFramework = typeof(FrameworkElement).Assembly; } return _presentationFramework; } } private static Assembly PresentationCore { get { if (_presentationCore == null) { _presentationCore = typeof(UIElement).Assembly; } return _presentationCore; } } private static Assembly WindowsBase { get { if (_windowsBase == null) { _windowsBase = typeof(DependencyObject).Assembly; } return _windowsBase; } } /// /// Loads and caches the generic and themed resource dictionaries for an assembly. /// internal class ResourceDictionaries { ////// Creates an instance of this class. /// /// The assembly that this class represents. internal ResourceDictionaries(Assembly assembly) { _assembly = assembly; if (assembly == PresentationFramework) { // Since we know all the information about PresentationFramework in advance, // we can pre-initialize that data. _assemblyName = PresentationFrameworkName; // There is no generic dictionary _genericDictionary = null; _genericLoaded = true; _genericLocation = ResourceDictionaryLocation.None; // Themed dictionaries are all external _themedLocation = ResourceDictionaryLocation.ExternalAssembly; _locationsLoaded = true; } else { _assemblyName = SafeSecurityHelper.GetAssemblyPartialName(assembly); } } ////// Resets the themed dictionaries. This is used when the theme changes. /// internal void ClearThemedDictionary() { _themedLoaded = false; _themedDictionary = null; } ////// Returns the theme dictionary associated with this assembly. /// /// Whether debug tracing is enabled. ///The dictionary if loaded, otherwise null. internal ResourceDictionary LoadThemedDictionary(bool isTraceEnabled) { if (!_themedLoaded) { LoadDictionaryLocations(); if (_preventReEnter || (_themedLocation == ResourceDictionaryLocation.None)) { // We are already in the middle of parsing this resource dictionary, avoid infinite loops. // OR, there are no themed resources. return null; } IsSystemResourcesParsing = true; _preventReEnter = true; try { ResourceDictionary dictionary = null; // Get the assembly to look inside for resources. Assembly assembly; string assemblyName; bool external = (_themedLocation == ResourceDictionaryLocation.ExternalAssembly); if (external) { LoadExternalAssembly(false /* classic */, false /* generic */, out assembly, out assemblyName); } else { assembly = _assembly; assemblyName = _assemblyName; } if (assembly != null) { dictionary = LoadDictionary(assembly, assemblyName, ThemedResourceName, isTraceEnabled); if ((dictionary == null) && !external) { // Themed resources should have been inside the source assembly, but failed to load. // Try falling back to external in case this is a theme that shipped later. LoadExternalAssembly(false /* classic */, false /* generic */, out assembly, out assemblyName); if (assembly != null) { dictionary = LoadDictionary(assembly, assemblyName, ThemedResourceName, isTraceEnabled); } } } if ((dictionary == null) && UxThemeWrapper.IsActive) { // If a non-classic dictionary failed to load, then try to load classic. if (external) { LoadExternalAssembly(true /* classic */, false /* generic */, out assembly, out assemblyName); } else { assembly = _assembly; assemblyName = _assemblyName; } if (assembly != null) { dictionary = LoadDictionary(assembly, assemblyName, ClassicResourceName, isTraceEnabled); } } _themedDictionary = dictionary; _themedLoaded = true; } finally { _preventReEnter = false; IsSystemResourcesParsing = false; } } return _themedDictionary; } ////// Returns the generic dictionary associated with this assembly. /// /// Whether debug tracing is enabled. ///The dictionary if loaded, otherwise null. internal ResourceDictionary LoadGenericDictionary(bool isTraceEnabled) { if (!_genericLoaded) { LoadDictionaryLocations(); if (_preventReEnter || (_genericLocation == ResourceDictionaryLocation.None)) { // We are already in the middle of parsing this resource dictionary, avoid infinite loops. return null; } IsSystemResourcesParsing = true; _preventReEnter = true; try { ResourceDictionary dictionary = null; // Get the assembly to look inside Assembly assembly; string assemblyName; if (_genericLocation == ResourceDictionaryLocation.ExternalAssembly) { LoadExternalAssembly(false /* classic */, true /* generic */, out assembly, out assemblyName); } else { assembly = _assembly; assemblyName = _assemblyName; } if (assembly != null) { dictionary = LoadDictionary(assembly, assemblyName, GenericResourceName, isTraceEnabled); } _genericDictionary = dictionary; _genericLoaded = true; } finally { _preventReEnter = false; IsSystemResourcesParsing = false; } } return _genericDictionary; } ////// Loads the assembly attribute indicating where dictionaries are stored. /// private void LoadDictionaryLocations() { if (!_locationsLoaded) { ThemeInfoAttribute locations = ThemeInfoAttribute.FromAssembly(_assembly); if (locations != null) { _themedLocation = locations.ThemeDictionaryLocation; _genericLocation = locations.GenericDictionaryLocation; } else { _themedLocation = ResourceDictionaryLocation.None; _genericLocation = ResourceDictionaryLocation.None; } _locationsLoaded = true; } } ////// Loads an associated theme assembly based on a main assembly. /// private void LoadExternalAssembly(bool classic, bool generic, out Assembly assembly, out string assemblyName) { StringBuilder sb = new StringBuilder(_assemblyName.Length + 10); sb.Append(_assemblyName); sb.Append("."); if (generic) { sb.Append("generic"); } else if (classic) { sb.Append("classic"); } else { sb.Append(UxThemeWrapper.ThemeName); } assemblyName = sb.ToString(); string fullName = SafeSecurityHelper.GetFullAssemblyNameFromPartialName(_assembly, assemblyName); assembly = null; try { assembly = Assembly.Load(fullName); } // There is no Assembly.Exists API to determine if an Assembly exists. // There is also no way to determine if an Assembly's format is good prior to loading it. // So, the exception must be caught. assembly will continue to be null and returned. #pragma warning disable 6502 catch (FileNotFoundException) { } catch (BadImageFormatException) { } #pragma warning restore 6502 } ////// The string to use as the key to load the .NET resource stream that contains themed resources. /// internal static string ThemedResourceName { get { if (_themedResourceName == null) { if (UxThemeWrapper.IsActive) { _themedResourceName = "themes/" + UxThemeWrapper.ThemeName.ToLowerInvariant() + "." + UxThemeWrapper.ThemeColor.ToLowerInvariant(); } else { _themedResourceName = ClassicResourceName; } } return _themedResourceName; } } ////// Loads a ResourceDictionary from within an assembly's .NET resource store. /// /// The owning assembly. /// The name of the owning assembly. /// The name of the desired theme resource. /// Whether tracing is enabled. ///The dictionary if found and loaded successfully, null otherwise. private ResourceDictionary LoadDictionary(Assembly assembly, string assemblyName, string resourceName, bool isTraceEnabled) { ResourceDictionary dictionary = null; // Create the resource manager that will load the byte array ResourceManager rm = new ResourceManager(assemblyName + ".g", assembly); resourceName = resourceName + ".baml"; // Load the resource stream Stream stream = null; try { stream = rm.GetStream(resourceName, CultureInfo.CurrentUICulture); } // There is no ResourceManager.HasManifest in order to detect this case before an exception is thrown. // Likewise, there is no way to know if loading a resource will fail prior to loading it. // So, the exceptions must be caught. stream will continue to be null and handled accordingly later. #pragma warning disable 6502 catch (MissingManifestResourceException) { // No usable resources in the assembly } #if !DEBUG catch (InvalidOperationException) { // Object not stored correctly } #endif #pragma warning restore 6502 if (stream != null) { ParserContext pc = new ParserContext(); // The stream is actually owned by the theme engine and will remain open // as long as the loading process is alive. So this can be re-used by the // parser when loading defered content like this dictionary instead of creating // a new memory buffer. pc.OwnsBamlStream = true; dictionary = (ResourceDictionary)XamlReader.LoadBaml( stream, // Stream input pc, // Parser Context null, // Owner element false); // Do not Close the stream if (isTraceEnabled && (dictionary != null)) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCEBAMLASSEMBLYGUID), MS.Utility.EventType.Info, assemblyName); } } return dictionary; } internal static void OnThemeChanged() { _themedResourceName = null; } private ResourceDictionary _genericDictionary; private ResourceDictionary _themedDictionary; private bool _genericLoaded = false; private bool _themedLoaded = false; private bool _preventReEnter = false; private bool _locationsLoaded = false; private string _assemblyName; private Assembly _assembly; private ResourceDictionaryLocation _genericLocation; private ResourceDictionaryLocation _themedLocation; private static string _themedResourceName; } #endregion #region Value Changes // The hwndNotify is referenced by the _hwndNotify static field, but // PreSharp will think that the hwndNotify is local and should be disposed. #pragma warning disable 6518 ////// Critical - Creates an HwndWrapper and adds a hook. /// TreatAsSafe: The _hwndNotify window is critical and this function is safe to call /// [SecurityCritical,SecurityTreatAsSafe] private static void EnsureResourceChangeListener() { // Create a new notify window if we haven't already created one for this thread. if (_hwndNotify == null) { // Create a top-level, invisible window so we can get the WM_THEMECHANGE notification. HwndWrapper hwndNotify; hwndNotify = new HwndWrapper(0, NativeMethods.WS_POPUP, 0, 0, 0, 0, 0, "SystemResourceNotifyWindow", IntPtr.Zero, null); _hwndNotify = new SecurityCriticalDataClass(hwndNotify); _hwndNotify.Value.Dispatcher.ShutdownFinished += OnShutdownFinished; _hwndNotifyHook = new HwndWrapperHook(SystemThemeFilterMessage); _hwndNotify.Value.AddHook(_hwndNotifyHook); } } /// /// Critical - Calls dispose on the critical hwnd wrapper. /// TreatAsSafe: It is safe to dispose the wrapper /// [SecurityCritical, SecurityTreatAsSafe] private static void OnShutdownFinished(object sender, EventArgs args) { if (_hwndNotify != null) _hwndNotify.Value.Dispose(); _hwndNotifyHook = null; _hwndNotify = null; } #pragma warning restore 6518 private static void OnThemeChanged() { ResourceDictionaries.OnThemeChanged(); UxThemeWrapper.OnThemeChanged(); ThemeDictionaryExtension.OnThemeChanged(); lock (ThemeDictionaryLock) { // Clear the resource cache _resourceCache.Clear(); // Clear the themeStyleCache _themeStyleCache.Clear(); // Clear the themed dictionaries if (_dictionaries != null) { foreach (ResourceDictionaries dictionaries in _dictionaries.Values) { dictionaries.ClearThemedDictionary(); } } } } private static void OnSystemValueChanged() { lock (ThemeDictionaryLock) { // Collect the list of keys for the values that will need to be removed // Note: We don't immediately remove them because the Key list is not // static. Listkeys = new List (); foreach (object key in _resourceCache.Keys) { SystemResourceKey resKey = key as SystemResourceKey; if (resKey != null) { keys.Add(resKey); } } // Remove the values int count = keys.Count; for (int i = 0; i < count; i++) { _resourceCache.Remove(keys[i]); } } } private static object InvalidateTreeResources(Object args) { object[] argsArray = (object[])args; PresentationSource source = (PresentationSource)argsArray[0]; if (!source.IsDisposed) { FrameworkElement fe = source.RootVisual as FrameworkElement; if (fe != null) { bool isSysColorsOrSettingsChange = (bool)argsArray[1]; if (isSysColorsOrSettingsChange) { TreeWalkHelper.InvalidateOnResourcesChange(fe, null, ResourcesChangeInfo.SysColorsOrSettingsChangeInfo); } else { TreeWalkHelper.InvalidateOnResourcesChange(fe, null, ResourcesChangeInfo.ThemeChangeInfo); } System.Windows.Input.KeyboardNavigation.AlwaysShowFocusVisual = SystemParameters.KeyboardCues; fe.CoerceValue(System.Windows.Input.KeyboardNavigation.ShowKeyboardCuesProperty); SystemResourcesAreChanging = true; // Update FontFamily properties on root elements fe.CoerceValue(TextElement.FontFamilyProperty); fe.CoerceValue(TextElement.FontSizeProperty); fe.CoerceValue(TextElement.FontStyleProperty); fe.CoerceValue(TextElement.FontWeightProperty); SystemResourcesAreChanging = false; PopupRoot popupRoot = fe as PopupRoot; if (popupRoot != null && popupRoot.Parent != null) { popupRoot.Parent.CoerceValue(Popup.HasDropShadowProperty); } } } return null; } /// /// This method calls into PresentationCore internally to update Tabelt devices when the system settings change. /// /// /// /// ////// Critical - Accesses the critical data. /// _hwndNotify /// [SecurityCritical] private static void InvalidateTabletDevices(int msg, IntPtr wParam, IntPtr lParam) { if ( _hwndNotify != null ) { Dispatcher dispatcher = _hwndNotify.Value.Dispatcher; if ( dispatcher != null && dispatcher.InputManager != null ) { ((InputManager)dispatcher.InputManager).StylusLogic.HandleMessage(msg, wParam, lParam); } } } ////// Critical - calls CriticalCurrentSources. /// TreatAsSafe - invalidation of resources considered ok. /// Net effect is an invalidation of tree and reload of BAML from theme files. /// Worse that could happen is a DOS attack within the app. /// [SecurityCritical, SecurityTreatAsSafe ] private static void InvalidateResources(bool isSysColorsOrSettingsChange) { SystemResourcesHaveChanged = true; Dispatcher dispatcher = isSysColorsOrSettingsChange ? null : Dispatcher.FromThread(System.Threading.Thread.CurrentThread); if (dispatcher != null || isSysColorsOrSettingsChange) { foreach (PresentationSource source in PresentationSource.CriticalCurrentSources) { if (!source.IsDisposed && (isSysColorsOrSettingsChange || (source.Dispatcher == dispatcher))) { source.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(InvalidateTreeResources), new object[]{source, isSysColorsOrSettingsChange}); } } } } ////// Critical: This code calls into PeekMessage and can be used to spoof theme change messages /// TreatAsSafe:The call to PeekMessage is safe and no information is exposed. In the case of the /// messages handled in this function, no data is passed in or out, the only form of attack possible /// here is DOS by excessive calls to this. /// [SecurityCritical,SecurityTreatAsSafe] private static IntPtr SystemThemeFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { case NativeMethods.WM_DEVICECHANGE: InvalidateTabletDevices(msg, wParam, lParam); // If there was an invalidation made to a Mouse metric, // then resource references need to be invalidated. if (SystemParameters.InvalidateDeviceDependentCache()) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once } break; case NativeMethods.WM_DISPLAYCHANGE: InvalidateTabletDevices(msg, wParam, lParam); // If there was an invalidation made to a Display metric, // then resource references need to be invalidated. if (SystemParameters.InvalidateDisplayDependentCache()) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once } break; case NativeMethods.WM_POWERBROADCAST: // If there was an invalidation made to a Power Setting, // then resource references need to be invalidated. if (NativeMethods.IntPtrToInt32(wParam) == NativeMethods.PBT_APMPOWERSTATUSCHANGE && SystemParameters.InvalidatePowerDependentCache()) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once } break; case NativeMethods.WM_THEMECHANGED: bool usingSendMessage = SafeNativeMethods.InSendMessage(); if (!usingSendMessage) { System.Windows.Interop.MSG m = new System.Windows.Interop.MSG(); bool moreMessagesPosted = UnsafeNativeMethods.PeekMessage(ref m, new HandleRef(null, hwnd), NativeMethods.WM_THEMECHANGED, NativeMethods.WM_THEMECHANGED, NativeMethods.PM_NOREMOVE); if (!moreMessagesPosted) { SystemColors.InvalidateCache(); SystemParameters.InvalidateCache(); OnThemeChanged(); InvalidateResources(false); // Only invalidate this thread's resources, other threads will get a chance } } break; case NativeMethods.WM_SYSCOLORCHANGE: // If there was an invalidation made to a system color or brush, // then resource references need to be invalidated. if (SystemColors.InvalidateCache()) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once } break; case NativeMethods.WM_SETTINGCHANGE: InvalidateTabletDevices(msg, wParam, lParam); // Update tablet device settings // If there was an invalidation made to a system param or metric, // then resource references need to be invalidated. if (SystemParameters.InvalidateCache((int)wParam)) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once // NOTICE-2005/06/17-WAYNEZEN, // We have to invoke the below method after InvalidateResources. // So the tablet ink HighContrastHelper can pick up the correct HighContrast setting. HighContrastHelper.OnSettingChanged(); } break; case NativeMethods.WM_TABLET_ADDED: InvalidateTabletDevices(msg, wParam, lParam); break; case NativeMethods.WM_TABLET_REMOVED: InvalidateTabletDevices(msg, wParam, lParam); break; } return IntPtr.Zero ; } internal static bool ClearBitArray(BitArray cacheValid) { bool changed = false; for (int i = 0; i < cacheValid.Count; i++) { if (ClearSlot(cacheValid, i)) { changed = true; } } return changed; } internal static bool ClearSlot(BitArray cacheValid, int slot) { if (cacheValid[slot]) { cacheValid[slot] = false; return true; } return false; } #endregion // Flag the parser to create DeferredThemeReferences for thread safety internal static bool IsSystemResourcesParsing { get { return _parsing > 0; } set { if (value) { _parsing++; } else { _parsing--; } } } // This is the lock used to protect access to the // theme dictionaries and the associated cache. internal static object ThemeDictionaryLock { get { return _resourceCache.SyncRoot; } } #endregion #region Data [ThreadStatic] private static int _parsing; [ThreadStatic] private static SecurityCriticalDataClass_hwndNotify; [ThreadStatic] [SecurityCritical] private static HwndWrapperHook _hwndNotifyHook; private static Hashtable _resourceCache = new Hashtable(); private static DTypeMap _themeStyleCache = new DTypeMap(100); // This is based upon the max DType.ID found in MSN scenario private static Dictionary _dictionaries; private static object _specialNull = new object(); private const string GenericResourceName = "themes/generic"; private const string ClassicResourceName = "themes/classic"; private static Assembly _mscorlib; private static Assembly _presentationFramework; private static Assembly _presentationCore; private static Assembly _windowsBase; internal const string PresentationFrameworkName = "PresentationFramework"; // SystemResourcesHaveChanged indicates to FE that the font properties need to be coerced // when creating a new root element internal static bool SystemResourcesHaveChanged; // SystemResourcesAreChanging is used by FE when coercing the font properties to determine // if it should return the current system metric or the value passed to the coerce callback [ThreadStatic] internal static bool SystemResourcesAreChanging; #endregion } internal class DeferredResourceReference : DeferredReference { #region Constructor internal DeferredResourceReference(ResourceDictionary dictionary, object key) { _dictionary = dictionary; _keyOrValue = key; } #endregion Constructor #region Methods internal override object GetValue(BaseValueSourceInternal valueSource) { // If the _value cache is invalid fetch the value from // the dictionary else just retun the cached value if (_dictionary != null) { bool canCache; object value = _dictionary.GetValue(_keyOrValue, out canCache); if (!CheckIfShared || canCache) { // Note that we are replacing the _keyorValue field // with the value and nuking the _dictionary field. _keyOrValue = value; RemoveFromDictionary(); } // Freeze if this value originated from a style or template bool freezeIfPossible = valueSource == BaseValueSourceInternal.ThemeStyle || valueSource == BaseValueSourceInternal.ThemeStyleTrigger || valueSource == BaseValueSourceInternal.Style || valueSource == BaseValueSourceInternal.TemplateTrigger || valueSource == BaseValueSourceInternal.StyleTrigger || valueSource == BaseValueSourceInternal.ParentTemplate || valueSource == BaseValueSourceInternal.ParentTemplateTrigger; // This is to freeze values produced by deferred // references within styles and templates if (freezeIfPossible) { StyleHelper.SealIfSealable(value); } // tell any listeners (e.g. ResourceReferenceExpressions) // that the value has been inflated OnInflated(); return value; } return _keyOrValue; } // Tell the listeners that we're inflated. private void OnInflated() { if (_inflatedList != null) { foreach (ResourceReferenceExpression listener in _inflatedList) { listener.OnDeferredResourceInflated(this); } } } // Gets the type of the value it represents internal override Type GetValueType() { if (_dictionary != null) { // Take a peek at the element type of the ElementStartRecord // within the ResourceDictionary's deferred content. bool found; return _dictionary.GetValueType(_keyOrValue, out found); } else { return _keyOrValue != null ? _keyOrValue.GetType() : null; } } // remove this DeferredResourceReference from its ResourceDictionary internal virtual void RemoveFromDictionary() { if (_dictionary != null) { _dictionary.DeferredResourceReferences.Remove(this); _dictionary = null; } } internal virtual void AddInflatedListener(ResourceReferenceExpression listener) { if (_inflatedList == null) { _inflatedList = new WeakReferenceList(this); } _inflatedList.Add(listener); } internal virtual void RemoveInflatedListener(ResourceReferenceExpression listener) { Debug.Assert(_inflatedList != null); if (_inflatedList != null) { _inflatedList.Remove(listener); } } #endregion Methods #region Properties internal virtual object Key { get { return _keyOrValue; } } internal ResourceDictionary Dictionary { get { return _dictionary; } set { _dictionary = value; } } internal virtual object Value { get { return _keyOrValue; } set { _keyOrValue = value; } } internal virtual bool IsUnset { get { return false; } } internal bool IsInflated { get { return (_dictionary == null); } } internal bool CheckIfShared { get { return _checkIfShared; } set { _checkIfShared = value; } } #endregion Properties #region Data private ResourceDictionary _dictionary; protected object _keyOrValue; private bool _checkIfShared; private WeakReferenceList _inflatedList; #endregion Data } internal class DeferredAppResourceReference : DeferredResourceReference { #region Constructor internal DeferredAppResourceReference(ResourceDictionary dictionary, object resourceKey) : base(dictionary, resourceKey) { } #endregion Constructor #region Methods internal override object GetValue(BaseValueSourceInternal valueSource) { lock (((ICollection)Application.Current.Resources).SyncRoot) { return base.GetValue(valueSource); } } // Gets the type of the value it represents internal override Type GetValueType() { lock (((ICollection)Application.Current.Resources).SyncRoot) { return base.GetValueType(); } } #endregion Methods } internal class DeferredThemeResourceReference : DeferredResourceReference { #region Constructor internal DeferredThemeResourceReference(ResourceDictionary dictionary, object resourceKey) :base(dictionary, resourceKey) { } #endregion Constructor #region Methods internal override object GetValue(BaseValueSourceInternal valueSource) { lock (SystemResources.ThemeDictionaryLock) { // If the value cache is invalid fetch the value from // the dictionary else just retun the cached value if (Dictionary != null) { bool canCache; object key = Key; object value; SystemResources.IsSystemResourcesParsing = true; try { value = Dictionary.GetValue(key, out canCache); if (!CheckIfShared || canCache) { // Note that we are replacing the _keyorValue field // with the value and nuking the _dictionary field. Value = value; Dictionary = null; } } finally { SystemResources.IsSystemResourcesParsing = false; } // Only cache keys that would be located by FindResourceInternal if ((key is Type || key is ResourceKey) && canCache) { SystemResources.CacheResource(key, value, false /*isTraceEnabled*/); } return value; } return Value; } } // Gets the type of the value it represents internal override Type GetValueType() { lock (SystemResources.ThemeDictionaryLock) { return base.GetValueType(); } } // remove this DeferredResourceReference from its ResourceDictionary internal override void RemoveFromDictionary() { // DeferredThemeResourceReferences are never added to the dictionary's // list of deferred references, so they don't need to be removed. } #endregion Methods } /// /// This signifies a DeferredResourceReference that is used as a place holder /// for the front loaded StaticResource within a deferred content section. /// internal class DeferredResourceReferenceHolder : DeferredResourceReference { #region Constructor internal DeferredResourceReferenceHolder(object resourceKey, object value) :base(null, null) { _keyOrValue = new object[]{resourceKey, value}; } #endregion Constructor #region Methods internal override object GetValue(BaseValueSourceInternal valueSource) { return Value; } // Gets the type of the value it represents internal override Type GetValueType() { object value = Value; return value != null ? value.GetType() : null; } #endregion Methods #region Properties internal override object Key { get { return ((object[])_keyOrValue)[0]; } } internal override object Value { get { return ((object[])_keyOrValue)[1]; } set { ((object[])_keyOrValue)[1] = value; } } internal override bool IsUnset { get { return Value == DependencyProperty.UnsetValue; } } #endregion Properties } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Resources; using System.Runtime.InteropServices; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Security; using System.Security.Permissions; using System.Windows.Threading; using System.Text; using MS.Utility; using System.Windows.Controls.Primitives; using System.Windows.Markup; using System.Windows.Documents; using System.Windows.Media; using System.Windows.Input; using System.Windows.Resources; using MS.Win32; using MS.Internal; using MS.Internal.Ink; using MS.Internal.PresentationFramework; // SafeSecurityHelper // Disable pragma warnings to enable PREsharp pragmas #pragma warning disable 1634, 1691 namespace System.Windows { ////// SystemResources loads system theme data into the system resources collection. /// internal static class SystemResources { // ------------------------------------------------ // // Methods // // ------------------------------------------------ #region Methods ////// Returns a resource for the given key type from the system resources collection. /// /// The resource id to search for. ///The resource if it exists, null otherwise. //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 internal static object FindThemeStyle(DependencyObjectType key) { // Find a cached theme style object resource = _themeStyleCache[key]; if (resource != null) { // Found a cached value if (resource == _specialNull) { // We cached a null, set it to a real null return null; // Null resource found } return resource; } // Find the resource from the system resources collection resource = FindResourceInternal(key.SystemType); // The above read operation was lock free. Writing // to the cache will need a lock though lock (ThemeDictionaryLock) { if (resource != null) { // Cache the value _themeStyleCache[key] = resource; } else { // Record nulls so we don't bother doing lookups for them later // Any theme changes will clear these values _themeStyleCache[key] = _specialNull; } } return resource; } ////// Returns a resource of the given name from the system resources collection. /// /// The resource id to search for. ///The resource if it exists, null otherwise. //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 internal static object FindResourceInternal(object key) { // Call Forwarded return FindResourceInternal(key, false /*allowDeferredResourceReference*/, false /*mustReturnDeferredResourceReference*/); } internal static object FindResourceInternal(object key, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference) { // Ensure that resource changes on this thread can be heard and handled EnsureResourceChangeListener(); object resource = null; Type typeKey = null; ResourceKey resourceKey = null; bool isTraceEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose); // System resource keys can only be of type Type or of type ResourceKey typeKey = key as Type; resourceKey = (typeKey == null) ? (key as ResourceKey) : null; if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCEFINDGUID), MS.Utility.EventType.StartEvent, (key == null) ? "null" : key.ToString()); } if ((typeKey == null) && (resourceKey == null)) { // Not a valid key if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCEFINDGUID), MS.Utility.EventType.EndEvent); } return null; } // Check if the value was already cached if (!FindCachedResource(key, ref resource, mustReturnDeferredResourceReference)) { // Cache miss, do a lookup if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCECACHEMISSGUID), MS.Utility.EventType.Info); } lock (ThemeDictionaryLock) { bool canCache = true; SystemResourceKey sysKey = (resourceKey != null) ? resourceKey as SystemResourceKey : null; if (sysKey != null) { // Check the list of system metrics if (!mustReturnDeferredResourceReference) { resource = sysKey.Resource; } else { resource = new DeferredResourceReferenceHolder(sysKey, sysKey.Resource); } if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCESTOCKGUID), MS.Utility.EventType.Info, sysKey.ToString()); } } else { // Do a dictionary lookup resource = FindDictionaryResource(key, typeKey, resourceKey, isTraceEnabled, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); } if ((canCache && !allowDeferredResourceReference) || resource == null) { // Cache the resource CacheResource(key, resource, isTraceEnabled); } } } if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCEFINDGUID), MS.Utility.EventType.EndEvent); } return resource; } #endregion // ------------------------------------------------ // // Implementation // // ------------------------------------------------ #region Implementation //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 internal static void CacheResource(object key, object resource, bool isTraceEnabled) { // Thread safety handled by FindResourceInternal. Be sure to have locked _resourceCache.SyncRoot. if (resource != null) { // Cache the value _resourceCache[key] = resource; if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCECACHEVALUEGUID), MS.Utility.EventType.Info); } } else { // Record nulls so we don't bother doing lookups for them later // Any theme changes will clear these values _resourceCache[key] = _specialNull; if (isTraceEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCECACHENULLGUID), MS.Utility.EventType.Info); } } } #region Resource Value Lookup private static bool FindCachedResource(object key, ref object resource, bool mustReturnDeferredResourceReference) { // reading the cache is lock free resource = _resourceCache[key]; bool found = (resource != null); if (resource == _specialNull) { // We cached a null, set it to a real null resource = null; } else { DispatcherObject dispatcherObject = resource as DispatcherObject; if (dispatcherObject != null) { // The current thread may not have access to this object. dispatcherObject.VerifyAccess(); } } if (found && mustReturnDeferredResourceReference) { resource = new DeferredResourceReferenceHolder(key, resource); } return found; } ////// Searches for a resource inside a ResourceDictionary. /// /// The original key. /// The key cast to Type. /// The key cast to ResourceKey. /// Tracing on/off. /// /// If this flag is true the resource will not actually be inflated from Baml. /// Instead we will return an instance of DeferredDictionaryReference which /// can later be used to query the resource /// /// /// If this method is true this method will always return a /// DeferredThemeResourceReference instance which envelopes the underlying resource. /// /// Whether callers can cache the value. ///private static object FindDictionaryResource( object key, Type typeKey, ResourceKey resourceKey, bool isTraceEnabled, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference, out bool canCache) { // Thread safety handled by FindResourceInternal. Be sure to have locked _resourceCache.SyncRoot. Debug.Assert(typeKey != null || resourceKey != null, "typeKey or resourceKey should be non-null"); canCache = true; object resource = null; Assembly assembly = (typeKey != null) ? typeKey.Assembly : resourceKey.Assembly; if ((assembly == null) || IgnoreAssembly(assembly)) { // Without an assembly, we can't figure out which dictionary to look at. // Also, ignore some common assemblies we know to not contain resources. return null; } ResourceDictionaries dictionaries = EnsureDictionarySlot(assembly); ResourceDictionary dictionary = dictionaries.LoadThemedDictionary(isTraceEnabled); if (dictionary != null) { resource = LookupResourceInDictionary(dictionary, key, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); } if (resource == null) { dictionary = dictionaries.LoadGenericDictionary(isTraceEnabled); if (dictionary != null) { resource = LookupResourceInDictionary(dictionary, key, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); } } if (resource != null) { // Resources coming out of the dictionary may need to be frozen Freeze(resource); } return resource; } /// /// Looks in the ResourceDictionary for the desired resource. /// /// The ResourceDictionary to look in. /// The key for the resource. /// /// If this flag is true the resource will not actually be inflated from Baml. /// Instead we will return an instance of DeferredDictionaryReference which /// can later be used to query the resource /// /// /// If this method is true this method will always return a /// DeferredThemeResourceReference instance which envelopes the underlying resource. /// /// Whether callers should cache the value. ///The resource if found and successfully loaded, null otherwise. private static object LookupResourceInDictionary( ResourceDictionary dictionary, object key, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference, out bool canCache) { object resource = null; IsSystemResourcesParsing = true; try { resource = dictionary.FetchResource(key, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache); } finally { IsSystemResourcesParsing = false; } return resource; } ////// Unbinds a Freezable from its Context. /// /// The resource to freeze. private static void Freeze(object resource) { Freezable freezable = resource as Freezable; if (freezable != null && !freezable.IsFrozen) { freezable.Freeze(); } } #endregion #region Dictionary Loading ////// Returns the dictionary cache slot associated with the given assembly. /// /// The desired assembly ///The cache slot. private static ResourceDictionaries EnsureDictionarySlot(Assembly assembly) { ResourceDictionaries dictionaries = null; if (_dictionaries != null) { _dictionaries.TryGetValue(assembly, out dictionaries); } else { // We will be caching data, create the cache _dictionaries = new Dictionary(1); } if (dictionaries == null) { // Ensure the cache slot is created dictionaries = new ResourceDictionaries(assembly); _dictionaries.Add(assembly, dictionaries); } return dictionaries; } private static bool IgnoreAssembly(Assembly assembly) { return (assembly == MsCorLib) || (assembly == PresentationCore) || (assembly == WindowsBase); } private static Assembly MsCorLib { get { if (_mscorlib == null) { _mscorlib = typeof(string).Assembly; } return _mscorlib; } } private static Assembly PresentationFramework { get { if (_presentationFramework == null) { _presentationFramework = typeof(FrameworkElement).Assembly; } return _presentationFramework; } } private static Assembly PresentationCore { get { if (_presentationCore == null) { _presentationCore = typeof(UIElement).Assembly; } return _presentationCore; } } private static Assembly WindowsBase { get { if (_windowsBase == null) { _windowsBase = typeof(DependencyObject).Assembly; } return _windowsBase; } } /// /// Loads and caches the generic and themed resource dictionaries for an assembly. /// internal class ResourceDictionaries { ////// Creates an instance of this class. /// /// The assembly that this class represents. internal ResourceDictionaries(Assembly assembly) { _assembly = assembly; if (assembly == PresentationFramework) { // Since we know all the information about PresentationFramework in advance, // we can pre-initialize that data. _assemblyName = PresentationFrameworkName; // There is no generic dictionary _genericDictionary = null; _genericLoaded = true; _genericLocation = ResourceDictionaryLocation.None; // Themed dictionaries are all external _themedLocation = ResourceDictionaryLocation.ExternalAssembly; _locationsLoaded = true; } else { _assemblyName = SafeSecurityHelper.GetAssemblyPartialName(assembly); } } ////// Resets the themed dictionaries. This is used when the theme changes. /// internal void ClearThemedDictionary() { _themedLoaded = false; _themedDictionary = null; } ////// Returns the theme dictionary associated with this assembly. /// /// Whether debug tracing is enabled. ///The dictionary if loaded, otherwise null. internal ResourceDictionary LoadThemedDictionary(bool isTraceEnabled) { if (!_themedLoaded) { LoadDictionaryLocations(); if (_preventReEnter || (_themedLocation == ResourceDictionaryLocation.None)) { // We are already in the middle of parsing this resource dictionary, avoid infinite loops. // OR, there are no themed resources. return null; } IsSystemResourcesParsing = true; _preventReEnter = true; try { ResourceDictionary dictionary = null; // Get the assembly to look inside for resources. Assembly assembly; string assemblyName; bool external = (_themedLocation == ResourceDictionaryLocation.ExternalAssembly); if (external) { LoadExternalAssembly(false /* classic */, false /* generic */, out assembly, out assemblyName); } else { assembly = _assembly; assemblyName = _assemblyName; } if (assembly != null) { dictionary = LoadDictionary(assembly, assemblyName, ThemedResourceName, isTraceEnabled); if ((dictionary == null) && !external) { // Themed resources should have been inside the source assembly, but failed to load. // Try falling back to external in case this is a theme that shipped later. LoadExternalAssembly(false /* classic */, false /* generic */, out assembly, out assemblyName); if (assembly != null) { dictionary = LoadDictionary(assembly, assemblyName, ThemedResourceName, isTraceEnabled); } } } if ((dictionary == null) && UxThemeWrapper.IsActive) { // If a non-classic dictionary failed to load, then try to load classic. if (external) { LoadExternalAssembly(true /* classic */, false /* generic */, out assembly, out assemblyName); } else { assembly = _assembly; assemblyName = _assemblyName; } if (assembly != null) { dictionary = LoadDictionary(assembly, assemblyName, ClassicResourceName, isTraceEnabled); } } _themedDictionary = dictionary; _themedLoaded = true; } finally { _preventReEnter = false; IsSystemResourcesParsing = false; } } return _themedDictionary; } ////// Returns the generic dictionary associated with this assembly. /// /// Whether debug tracing is enabled. ///The dictionary if loaded, otherwise null. internal ResourceDictionary LoadGenericDictionary(bool isTraceEnabled) { if (!_genericLoaded) { LoadDictionaryLocations(); if (_preventReEnter || (_genericLocation == ResourceDictionaryLocation.None)) { // We are already in the middle of parsing this resource dictionary, avoid infinite loops. return null; } IsSystemResourcesParsing = true; _preventReEnter = true; try { ResourceDictionary dictionary = null; // Get the assembly to look inside Assembly assembly; string assemblyName; if (_genericLocation == ResourceDictionaryLocation.ExternalAssembly) { LoadExternalAssembly(false /* classic */, true /* generic */, out assembly, out assemblyName); } else { assembly = _assembly; assemblyName = _assemblyName; } if (assembly != null) { dictionary = LoadDictionary(assembly, assemblyName, GenericResourceName, isTraceEnabled); } _genericDictionary = dictionary; _genericLoaded = true; } finally { _preventReEnter = false; IsSystemResourcesParsing = false; } } return _genericDictionary; } ////// Loads the assembly attribute indicating where dictionaries are stored. /// private void LoadDictionaryLocations() { if (!_locationsLoaded) { ThemeInfoAttribute locations = ThemeInfoAttribute.FromAssembly(_assembly); if (locations != null) { _themedLocation = locations.ThemeDictionaryLocation; _genericLocation = locations.GenericDictionaryLocation; } else { _themedLocation = ResourceDictionaryLocation.None; _genericLocation = ResourceDictionaryLocation.None; } _locationsLoaded = true; } } ////// Loads an associated theme assembly based on a main assembly. /// private void LoadExternalAssembly(bool classic, bool generic, out Assembly assembly, out string assemblyName) { StringBuilder sb = new StringBuilder(_assemblyName.Length + 10); sb.Append(_assemblyName); sb.Append("."); if (generic) { sb.Append("generic"); } else if (classic) { sb.Append("classic"); } else { sb.Append(UxThemeWrapper.ThemeName); } assemblyName = sb.ToString(); string fullName = SafeSecurityHelper.GetFullAssemblyNameFromPartialName(_assembly, assemblyName); assembly = null; try { assembly = Assembly.Load(fullName); } // There is no Assembly.Exists API to determine if an Assembly exists. // There is also no way to determine if an Assembly's format is good prior to loading it. // So, the exception must be caught. assembly will continue to be null and returned. #pragma warning disable 6502 catch (FileNotFoundException) { } catch (BadImageFormatException) { } #pragma warning restore 6502 } ////// The string to use as the key to load the .NET resource stream that contains themed resources. /// internal static string ThemedResourceName { get { if (_themedResourceName == null) { if (UxThemeWrapper.IsActive) { _themedResourceName = "themes/" + UxThemeWrapper.ThemeName.ToLowerInvariant() + "." + UxThemeWrapper.ThemeColor.ToLowerInvariant(); } else { _themedResourceName = ClassicResourceName; } } return _themedResourceName; } } ////// Loads a ResourceDictionary from within an assembly's .NET resource store. /// /// The owning assembly. /// The name of the owning assembly. /// The name of the desired theme resource. /// Whether tracing is enabled. ///The dictionary if found and loaded successfully, null otherwise. private ResourceDictionary LoadDictionary(Assembly assembly, string assemblyName, string resourceName, bool isTraceEnabled) { ResourceDictionary dictionary = null; // Create the resource manager that will load the byte array ResourceManager rm = new ResourceManager(assemblyName + ".g", assembly); resourceName = resourceName + ".baml"; // Load the resource stream Stream stream = null; try { stream = rm.GetStream(resourceName, CultureInfo.CurrentUICulture); } // There is no ResourceManager.HasManifest in order to detect this case before an exception is thrown. // Likewise, there is no way to know if loading a resource will fail prior to loading it. // So, the exceptions must be caught. stream will continue to be null and handled accordingly later. #pragma warning disable 6502 catch (MissingManifestResourceException) { // No usable resources in the assembly } #if !DEBUG catch (InvalidOperationException) { // Object not stored correctly } #endif #pragma warning restore 6502 if (stream != null) { ParserContext pc = new ParserContext(); // The stream is actually owned by the theme engine and will remain open // as long as the loading process is alive. So this can be re-used by the // parser when loading defered content like this dictionary instead of creating // a new memory buffer. pc.OwnsBamlStream = true; dictionary = (ResourceDictionary)XamlReader.LoadBaml( stream, // Stream input pc, // Parser Context null, // Owner element false); // Do not Close the stream if (isTraceEnabled && (dictionary != null)) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.RESOURCEBAMLASSEMBLYGUID), MS.Utility.EventType.Info, assemblyName); } } return dictionary; } internal static void OnThemeChanged() { _themedResourceName = null; } private ResourceDictionary _genericDictionary; private ResourceDictionary _themedDictionary; private bool _genericLoaded = false; private bool _themedLoaded = false; private bool _preventReEnter = false; private bool _locationsLoaded = false; private string _assemblyName; private Assembly _assembly; private ResourceDictionaryLocation _genericLocation; private ResourceDictionaryLocation _themedLocation; private static string _themedResourceName; } #endregion #region Value Changes // The hwndNotify is referenced by the _hwndNotify static field, but // PreSharp will think that the hwndNotify is local and should be disposed. #pragma warning disable 6518 ////// Critical - Creates an HwndWrapper and adds a hook. /// TreatAsSafe: The _hwndNotify window is critical and this function is safe to call /// [SecurityCritical,SecurityTreatAsSafe] private static void EnsureResourceChangeListener() { // Create a new notify window if we haven't already created one for this thread. if (_hwndNotify == null) { // Create a top-level, invisible window so we can get the WM_THEMECHANGE notification. HwndWrapper hwndNotify; hwndNotify = new HwndWrapper(0, NativeMethods.WS_POPUP, 0, 0, 0, 0, 0, "SystemResourceNotifyWindow", IntPtr.Zero, null); _hwndNotify = new SecurityCriticalDataClass(hwndNotify); _hwndNotify.Value.Dispatcher.ShutdownFinished += OnShutdownFinished; _hwndNotifyHook = new HwndWrapperHook(SystemThemeFilterMessage); _hwndNotify.Value.AddHook(_hwndNotifyHook); } } /// /// Critical - Calls dispose on the critical hwnd wrapper. /// TreatAsSafe: It is safe to dispose the wrapper /// [SecurityCritical, SecurityTreatAsSafe] private static void OnShutdownFinished(object sender, EventArgs args) { if (_hwndNotify != null) _hwndNotify.Value.Dispose(); _hwndNotifyHook = null; _hwndNotify = null; } #pragma warning restore 6518 private static void OnThemeChanged() { ResourceDictionaries.OnThemeChanged(); UxThemeWrapper.OnThemeChanged(); ThemeDictionaryExtension.OnThemeChanged(); lock (ThemeDictionaryLock) { // Clear the resource cache _resourceCache.Clear(); // Clear the themeStyleCache _themeStyleCache.Clear(); // Clear the themed dictionaries if (_dictionaries != null) { foreach (ResourceDictionaries dictionaries in _dictionaries.Values) { dictionaries.ClearThemedDictionary(); } } } } private static void OnSystemValueChanged() { lock (ThemeDictionaryLock) { // Collect the list of keys for the values that will need to be removed // Note: We don't immediately remove them because the Key list is not // static. Listkeys = new List (); foreach (object key in _resourceCache.Keys) { SystemResourceKey resKey = key as SystemResourceKey; if (resKey != null) { keys.Add(resKey); } } // Remove the values int count = keys.Count; for (int i = 0; i < count; i++) { _resourceCache.Remove(keys[i]); } } } private static object InvalidateTreeResources(Object args) { object[] argsArray = (object[])args; PresentationSource source = (PresentationSource)argsArray[0]; if (!source.IsDisposed) { FrameworkElement fe = source.RootVisual as FrameworkElement; if (fe != null) { bool isSysColorsOrSettingsChange = (bool)argsArray[1]; if (isSysColorsOrSettingsChange) { TreeWalkHelper.InvalidateOnResourcesChange(fe, null, ResourcesChangeInfo.SysColorsOrSettingsChangeInfo); } else { TreeWalkHelper.InvalidateOnResourcesChange(fe, null, ResourcesChangeInfo.ThemeChangeInfo); } System.Windows.Input.KeyboardNavigation.AlwaysShowFocusVisual = SystemParameters.KeyboardCues; fe.CoerceValue(System.Windows.Input.KeyboardNavigation.ShowKeyboardCuesProperty); SystemResourcesAreChanging = true; // Update FontFamily properties on root elements fe.CoerceValue(TextElement.FontFamilyProperty); fe.CoerceValue(TextElement.FontSizeProperty); fe.CoerceValue(TextElement.FontStyleProperty); fe.CoerceValue(TextElement.FontWeightProperty); SystemResourcesAreChanging = false; PopupRoot popupRoot = fe as PopupRoot; if (popupRoot != null && popupRoot.Parent != null) { popupRoot.Parent.CoerceValue(Popup.HasDropShadowProperty); } } } return null; } /// /// This method calls into PresentationCore internally to update Tabelt devices when the system settings change. /// /// /// /// ////// Critical - Accesses the critical data. /// _hwndNotify /// [SecurityCritical] private static void InvalidateTabletDevices(int msg, IntPtr wParam, IntPtr lParam) { if ( _hwndNotify != null ) { Dispatcher dispatcher = _hwndNotify.Value.Dispatcher; if ( dispatcher != null && dispatcher.InputManager != null ) { ((InputManager)dispatcher.InputManager).StylusLogic.HandleMessage(msg, wParam, lParam); } } } ////// Critical - calls CriticalCurrentSources. /// TreatAsSafe - invalidation of resources considered ok. /// Net effect is an invalidation of tree and reload of BAML from theme files. /// Worse that could happen is a DOS attack within the app. /// [SecurityCritical, SecurityTreatAsSafe ] private static void InvalidateResources(bool isSysColorsOrSettingsChange) { SystemResourcesHaveChanged = true; Dispatcher dispatcher = isSysColorsOrSettingsChange ? null : Dispatcher.FromThread(System.Threading.Thread.CurrentThread); if (dispatcher != null || isSysColorsOrSettingsChange) { foreach (PresentationSource source in PresentationSource.CriticalCurrentSources) { if (!source.IsDisposed && (isSysColorsOrSettingsChange || (source.Dispatcher == dispatcher))) { source.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(InvalidateTreeResources), new object[]{source, isSysColorsOrSettingsChange}); } } } } ////// Critical: This code calls into PeekMessage and can be used to spoof theme change messages /// TreatAsSafe:The call to PeekMessage is safe and no information is exposed. In the case of the /// messages handled in this function, no data is passed in or out, the only form of attack possible /// here is DOS by excessive calls to this. /// [SecurityCritical,SecurityTreatAsSafe] private static IntPtr SystemThemeFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { case NativeMethods.WM_DEVICECHANGE: InvalidateTabletDevices(msg, wParam, lParam); // If there was an invalidation made to a Mouse metric, // then resource references need to be invalidated. if (SystemParameters.InvalidateDeviceDependentCache()) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once } break; case NativeMethods.WM_DISPLAYCHANGE: InvalidateTabletDevices(msg, wParam, lParam); // If there was an invalidation made to a Display metric, // then resource references need to be invalidated. if (SystemParameters.InvalidateDisplayDependentCache()) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once } break; case NativeMethods.WM_POWERBROADCAST: // If there was an invalidation made to a Power Setting, // then resource references need to be invalidated. if (NativeMethods.IntPtrToInt32(wParam) == NativeMethods.PBT_APMPOWERSTATUSCHANGE && SystemParameters.InvalidatePowerDependentCache()) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once } break; case NativeMethods.WM_THEMECHANGED: bool usingSendMessage = SafeNativeMethods.InSendMessage(); if (!usingSendMessage) { System.Windows.Interop.MSG m = new System.Windows.Interop.MSG(); bool moreMessagesPosted = UnsafeNativeMethods.PeekMessage(ref m, new HandleRef(null, hwnd), NativeMethods.WM_THEMECHANGED, NativeMethods.WM_THEMECHANGED, NativeMethods.PM_NOREMOVE); if (!moreMessagesPosted) { SystemColors.InvalidateCache(); SystemParameters.InvalidateCache(); OnThemeChanged(); InvalidateResources(false); // Only invalidate this thread's resources, other threads will get a chance } } break; case NativeMethods.WM_SYSCOLORCHANGE: // If there was an invalidation made to a system color or brush, // then resource references need to be invalidated. if (SystemColors.InvalidateCache()) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once } break; case NativeMethods.WM_SETTINGCHANGE: InvalidateTabletDevices(msg, wParam, lParam); // Update tablet device settings // If there was an invalidation made to a system param or metric, // then resource references need to be invalidated. if (SystemParameters.InvalidateCache((int)wParam)) { OnSystemValueChanged(); InvalidateResources(true); // Invalidate all resource since this should happen only once // NOTICE-2005/06/17-WAYNEZEN, // We have to invoke the below method after InvalidateResources. // So the tablet ink HighContrastHelper can pick up the correct HighContrast setting. HighContrastHelper.OnSettingChanged(); } break; case NativeMethods.WM_TABLET_ADDED: InvalidateTabletDevices(msg, wParam, lParam); break; case NativeMethods.WM_TABLET_REMOVED: InvalidateTabletDevices(msg, wParam, lParam); break; } return IntPtr.Zero ; } internal static bool ClearBitArray(BitArray cacheValid) { bool changed = false; for (int i = 0; i < cacheValid.Count; i++) { if (ClearSlot(cacheValid, i)) { changed = true; } } return changed; } internal static bool ClearSlot(BitArray cacheValid, int slot) { if (cacheValid[slot]) { cacheValid[slot] = false; return true; } return false; } #endregion // Flag the parser to create DeferredThemeReferences for thread safety internal static bool IsSystemResourcesParsing { get { return _parsing > 0; } set { if (value) { _parsing++; } else { _parsing--; } } } // This is the lock used to protect access to the // theme dictionaries and the associated cache. internal static object ThemeDictionaryLock { get { return _resourceCache.SyncRoot; } } #endregion #region Data [ThreadStatic] private static int _parsing; [ThreadStatic] private static SecurityCriticalDataClass_hwndNotify; [ThreadStatic] [SecurityCritical] private static HwndWrapperHook _hwndNotifyHook; private static Hashtable _resourceCache = new Hashtable(); private static DTypeMap _themeStyleCache = new DTypeMap(100); // This is based upon the max DType.ID found in MSN scenario private static Dictionary _dictionaries; private static object _specialNull = new object(); private const string GenericResourceName = "themes/generic"; private const string ClassicResourceName = "themes/classic"; private static Assembly _mscorlib; private static Assembly _presentationFramework; private static Assembly _presentationCore; private static Assembly _windowsBase; internal const string PresentationFrameworkName = "PresentationFramework"; // SystemResourcesHaveChanged indicates to FE that the font properties need to be coerced // when creating a new root element internal static bool SystemResourcesHaveChanged; // SystemResourcesAreChanging is used by FE when coercing the font properties to determine // if it should return the current system metric or the value passed to the coerce callback [ThreadStatic] internal static bool SystemResourcesAreChanging; #endregion } internal class DeferredResourceReference : DeferredReference { #region Constructor internal DeferredResourceReference(ResourceDictionary dictionary, object key) { _dictionary = dictionary; _keyOrValue = key; } #endregion Constructor #region Methods internal override object GetValue(BaseValueSourceInternal valueSource) { // If the _value cache is invalid fetch the value from // the dictionary else just retun the cached value if (_dictionary != null) { bool canCache; object value = _dictionary.GetValue(_keyOrValue, out canCache); if (!CheckIfShared || canCache) { // Note that we are replacing the _keyorValue field // with the value and nuking the _dictionary field. _keyOrValue = value; RemoveFromDictionary(); } // Freeze if this value originated from a style or template bool freezeIfPossible = valueSource == BaseValueSourceInternal.ThemeStyle || valueSource == BaseValueSourceInternal.ThemeStyleTrigger || valueSource == BaseValueSourceInternal.Style || valueSource == BaseValueSourceInternal.TemplateTrigger || valueSource == BaseValueSourceInternal.StyleTrigger || valueSource == BaseValueSourceInternal.ParentTemplate || valueSource == BaseValueSourceInternal.ParentTemplateTrigger; // This is to freeze values produced by deferred // references within styles and templates if (freezeIfPossible) { StyleHelper.SealIfSealable(value); } // tell any listeners (e.g. ResourceReferenceExpressions) // that the value has been inflated OnInflated(); return value; } return _keyOrValue; } // Tell the listeners that we're inflated. private void OnInflated() { if (_inflatedList != null) { foreach (ResourceReferenceExpression listener in _inflatedList) { listener.OnDeferredResourceInflated(this); } } } // Gets the type of the value it represents internal override Type GetValueType() { if (_dictionary != null) { // Take a peek at the element type of the ElementStartRecord // within the ResourceDictionary's deferred content. bool found; return _dictionary.GetValueType(_keyOrValue, out found); } else { return _keyOrValue != null ? _keyOrValue.GetType() : null; } } // remove this DeferredResourceReference from its ResourceDictionary internal virtual void RemoveFromDictionary() { if (_dictionary != null) { _dictionary.DeferredResourceReferences.Remove(this); _dictionary = null; } } internal virtual void AddInflatedListener(ResourceReferenceExpression listener) { if (_inflatedList == null) { _inflatedList = new WeakReferenceList(this); } _inflatedList.Add(listener); } internal virtual void RemoveInflatedListener(ResourceReferenceExpression listener) { Debug.Assert(_inflatedList != null); if (_inflatedList != null) { _inflatedList.Remove(listener); } } #endregion Methods #region Properties internal virtual object Key { get { return _keyOrValue; } } internal ResourceDictionary Dictionary { get { return _dictionary; } set { _dictionary = value; } } internal virtual object Value { get { return _keyOrValue; } set { _keyOrValue = value; } } internal virtual bool IsUnset { get { return false; } } internal bool IsInflated { get { return (_dictionary == null); } } internal bool CheckIfShared { get { return _checkIfShared; } set { _checkIfShared = value; } } #endregion Properties #region Data private ResourceDictionary _dictionary; protected object _keyOrValue; private bool _checkIfShared; private WeakReferenceList _inflatedList; #endregion Data } internal class DeferredAppResourceReference : DeferredResourceReference { #region Constructor internal DeferredAppResourceReference(ResourceDictionary dictionary, object resourceKey) : base(dictionary, resourceKey) { } #endregion Constructor #region Methods internal override object GetValue(BaseValueSourceInternal valueSource) { lock (((ICollection)Application.Current.Resources).SyncRoot) { return base.GetValue(valueSource); } } // Gets the type of the value it represents internal override Type GetValueType() { lock (((ICollection)Application.Current.Resources).SyncRoot) { return base.GetValueType(); } } #endregion Methods } internal class DeferredThemeResourceReference : DeferredResourceReference { #region Constructor internal DeferredThemeResourceReference(ResourceDictionary dictionary, object resourceKey) :base(dictionary, resourceKey) { } #endregion Constructor #region Methods internal override object GetValue(BaseValueSourceInternal valueSource) { lock (SystemResources.ThemeDictionaryLock) { // If the value cache is invalid fetch the value from // the dictionary else just retun the cached value if (Dictionary != null) { bool canCache; object key = Key; object value; SystemResources.IsSystemResourcesParsing = true; try { value = Dictionary.GetValue(key, out canCache); if (!CheckIfShared || canCache) { // Note that we are replacing the _keyorValue field // with the value and nuking the _dictionary field. Value = value; Dictionary = null; } } finally { SystemResources.IsSystemResourcesParsing = false; } // Only cache keys that would be located by FindResourceInternal if ((key is Type || key is ResourceKey) && canCache) { SystemResources.CacheResource(key, value, false /*isTraceEnabled*/); } return value; } return Value; } } // Gets the type of the value it represents internal override Type GetValueType() { lock (SystemResources.ThemeDictionaryLock) { return base.GetValueType(); } } // remove this DeferredResourceReference from its ResourceDictionary internal override void RemoveFromDictionary() { // DeferredThemeResourceReferences are never added to the dictionary's // list of deferred references, so they don't need to be removed. } #endregion Methods } /// /// This signifies a DeferredResourceReference that is used as a place holder /// for the front loaded StaticResource within a deferred content section. /// internal class DeferredResourceReferenceHolder : DeferredResourceReference { #region Constructor internal DeferredResourceReferenceHolder(object resourceKey, object value) :base(null, null) { _keyOrValue = new object[]{resourceKey, value}; } #endregion Constructor #region Methods internal override object GetValue(BaseValueSourceInternal valueSource) { return Value; } // Gets the type of the value it represents internal override Type GetValueType() { object value = Value; return value != null ? value.GetType() : null; } #endregion Methods #region Properties internal override object Key { get { return ((object[])_keyOrValue)[0]; } } internal override object Value { get { return ((object[])_keyOrValue)[1]; } set { ((object[])_keyOrValue)[1] = value; } } internal override bool IsUnset { get { return Value == DependencyProperty.UnsetValue; } } #endregion Properties } } // 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
- ParameterCollection.cs
- AttachedPropertyBrowsableForTypeAttribute.cs
- SmtpSection.cs
- StorageEntityTypeMapping.cs
- WebServiceMethodData.cs
- CommonProperties.cs
- RenderTargetBitmap.cs
- GridViewEditEventArgs.cs
- DataConnectionHelper.cs
- ForeignKeyConstraint.cs
- DataKeyArray.cs
- XamlToRtfParser.cs
- IntegerCollectionEditor.cs
- XMLUtil.cs
- HttpCacheVaryByContentEncodings.cs
- BindValidator.cs
- XmlnsPrefixAttribute.cs
- Stackframe.cs
- ThreadAbortException.cs
- Guid.cs
- KnownColorTable.cs
- IteratorFilter.cs
- TextEditorTyping.cs
- PhysicalOps.cs
- ExpressionBuilder.cs
- MDIClient.cs
- WebPartDescriptionCollection.cs
- FlowLayoutPanelDesigner.cs
- WebPartHeaderCloseVerb.cs
- Events.cs
- CodeTypeReferenceSerializer.cs
- TableRow.cs
- XamlFilter.cs
- Evidence.cs
- TableNameAttribute.cs
- ProvideValueServiceProvider.cs
- TaskFormBase.cs
- TypedReference.cs
- UserControl.cs
- RangeValidator.cs
- QueryCreatedEventArgs.cs
- FrameworkElement.cs
- TabletDeviceInfo.cs
- DataSetSchema.cs
- PropertyGroupDescription.cs
- ValueProviderWrapper.cs
- DesignerProperties.cs
- TimeStampChecker.cs
- UnsafeNativeMethodsTablet.cs
- Byte.cs
- ProfileSettings.cs
- TableDetailsRow.cs
- DesignTimeParseData.cs
- EventRouteFactory.cs
- SlipBehavior.cs
- RowToParametersTransformer.cs
- DataGridViewCellContextMenuStripNeededEventArgs.cs
- HwndSource.cs
- ArraySegment.cs
- WebHeaderCollection.cs
- SqlAliaser.cs
- TreeViewItem.cs
- ConvertEvent.cs
- ContainerUtilities.cs
- InputLanguageCollection.cs
- QilLoop.cs
- ProtocolsConfigurationHandler.cs
- MessageSmuggler.cs
- DoubleKeyFrameCollection.cs
- DbReferenceCollection.cs
- WebEventCodes.cs
- ManagementEventArgs.cs
- XamlPointCollectionSerializer.cs
- DataMemberConverter.cs
- Message.cs
- TextInfo.cs
- GenericTypeParameterBuilder.cs
- CodeDomSerializer.cs
- PerformanceCountersElement.cs
- WorkflowCompensationBehavior.cs
- DelegateSerializationHolder.cs
- MethodSet.cs
- ToolboxComponentsCreatedEventArgs.cs
- UnicodeEncoding.cs
- HtmlToClrEventProxy.cs
- BindingSource.cs
- ActivityDesignerResources.cs
- ChannelTerminatedException.cs
- FlowDocument.cs
- TextSelectionProcessor.cs
- OdbcDataReader.cs
- ObfuscateAssemblyAttribute.cs
- Int64KeyFrameCollection.cs
- UnsupportedPolicyOptionsException.cs
- SqlFactory.cs
- InputLanguageManager.cs
- AmbientValueAttribute.cs
- ToolBarButton.cs
- MethodBody.cs
- PolyLineSegmentFigureLogic.cs