Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Shared / MS / Internal / TextServicesLoader.cs / 1 / TextServicesLoader.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//
// Description: Creates ITfThreadMgr instances, the root object of the Text
// Services Framework.
//
// History:
// 07/16/2003 : [....] - ported from dotnet tree.
//
//---------------------------------------------------------------------------
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security;
using System.Threading;
using MS.Internal;
using Microsoft.Win32;
using MS.Win32;
using System.Diagnostics;
#if WINDOWS_BASE
using MS.Internal.WindowsBase;
#elif PRESENTATION_CORE
using MS.Internal.PresentationCore;
#elif PRESENTATIONFRAMEWORK
using MS.Internal.PresentationFramework;
#elif DRT
using MS.Internal.Drt;
#else
#error Attempt to use FriendAccessAllowedAttribute from an unknown assembly.
using MS.Internal.YourAssemblyName;
#endif
namespace MS.Internal
{
// Creates ITfThreadMgr instances, the root object of the Text Services
// Framework.
[FriendAccessAllowed]
internal class TextServicesLoader
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
// Private ctor to prevent anyone from instantiating this static class.
private TextServicesLoader() {}
#endregion Constructors
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Public Events
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Protected Methods
//
//-----------------------------------------------------
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Internal Properties
//
//------------------------------------------------------
#region Internal Properties
///
/// Loads an instance of the Text Services Framework.
///
///
/// May return null if no text services are available.
///
///
/// SecurityCritical: As this causes elevation of privilige
///
[SecurityCritical]
internal static UnsafeNativeMethods.ITfThreadMgr Load()
{
UnsafeNativeMethods.ITfThreadMgr threadManager;
Invariant.Assert(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA, "Load called on MTA thread!");
if (ServicesInstalled)
{
// NB: a COMException here means something went wrong initialzing Cicero.
// Cicero will throw an exception if it doesn't think it should have been
// loaded (no TIPs to run), you can check that in msctf.dll's NoTipsInstalled
// which lives in nt\windows\advcore\ctf\lib\immxutil.cpp. If that's the
// problem, ServicesInstalled is out of sync with Cicero's thinking.
if (UnsafeNativeMethods.TF_CreateThreadMgr(out threadManager) == NativeMethods.S_OK)
{
return threadManager;
}
}
return null;
}
///
/// Informs the caller if text services are installed for the current user.
///
///
/// true if one or more text services are installed for the current user, otherwise false.
///
///
/// If this method returns false, TextServicesLoader.Load is guarenteed to return null.
/// Callers can use this information to avoid overhead that would otherwise be
/// required to support text services.
///
internal static bool ServicesInstalled
{
get
{
lock (s_servicesInstalledLock)
{
if (s_servicesInstalled == InstallState.Unknown)
{
s_servicesInstalled = TIPsWantToRun() ? InstallState.Installed : InstallState.NotInstalled;
}
}
return (s_servicesInstalled == InstallState.Installed);
}
}
#endregion Internal Properties
//------------------------------------------------------
//
// Internal Events
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Private Methods
//
//-----------------------------------------------------
#region Private Methods
//
// This method tries to stop Avalon from loading Cicero when there are no TIPs to run.
// The perf tradeoff is a typically small number of registry checks versus loading and
// initializing cicero.
//
// The Algorithm:
//
// Do a quick check vs. the global disable flag, return false if it is set.
// For each key under HKLM\SOFTWARE\Microsoft\CTF\TIP (a TIP or category clsid)
// If the the key has a LanguageProfile subkey (it's a TIP clsid)
// Iterate under the matching TIP entry in HKCU.
// For each key under the LanguageProfile (a particular LANGID)
// For each key under the LANGID (an assembly GUID)
// Try to read the Enable value.
// If the value is set non-zero, then stop all processing and return true.
// If the value is set zero, continue.
// If the value does not exist, continue (default is disabled).
// If any Enable values were found under HKCU for the TIP, then stop all processing and return false.
// Else, no Enable values have been found thus far and we keep going to investigate HKLM.
// Iterate under the TIP entry in HKLM.
// For each key under the LanguageProfile (a particular LANGID)
// For each key under the LANGID (an assembly GUID)
// Try to read the Enable value.
// If the value is set non-zero, then stop all processing and return true.
// If the value does not exist, then stop all processing and return true (default is enabled).
// If the value is set zero, continue.
// If we finish iterating all entries under HKLM without returning true, return false.
//
///
/// Safe - no critical state stored, disclosure that Tips wanting to run is safe
/// Critical - critical because we do an assert
///
[SecurityTreatAsSafe, SecurityCritical]
private static bool TIPsWantToRun()
{
object obj;
RegistryKey key;
bool tipsWantToRun = false;
PermissionSet ps = new PermissionSet(PermissionState.None);
ps.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\CTF"));
ps.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, "HKEY_CURRENT_USER\\Software\\Microsoft\\CTF"));
ps.Assert(); // BlessedAssert:
try
{
key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\CTF", false);
// Is cicero disabled completely for the current user?
if (key != null)
{
obj = key.GetValue("Disable Thread Input Manager");
if (obj is int && (int)obj != 0)
return false;
}
// Loop through all the TIP entries for machine and current user.
tipsWantToRun = IterateSubKeys(Registry.LocalMachine, "SOFTWARE\\Microsoft\\CTF\\TIP",new IterateHandler(SingleTIPWantsToRun), true) == EnableState.Enabled;
}
finally
{
CodeAccessPermission.RevertAssert();
}
return tipsWantToRun;
}
// Returns EnableState.Enabled if one or more TIPs are installed and
// enabled for the current user.
private static EnableState SingleTIPWantsToRun(RegistryKey keyLocalMachine, string subKeyName, bool localMachine)
{
EnableState result;
if (subKeyName.Length != CLSIDLength)
return EnableState.Disabled;
// We want subkey\LanguageProfile key.
// Loop through all the langid entries for TIP.
// First, check current user.
result = IterateSubKeys(Registry.CurrentUser, "SOFTWARE\\Microsoft\\CTF\\TIP\\" + subKeyName + "\\LanguageProfile", new IterateHandler(IsLangidEnabled), false);
// Any explicit value short circuits the process.
// Otherwise check local machine.
if (result == EnableState.None || result == EnableState.Error)
{
result = IterateSubKeys(keyLocalMachine, subKeyName + "\\LanguageProfile", new IterateHandler(IsLangidEnabled), true);
if (result == EnableState.None)
{
result = EnableState.Enabled;
}
}
return result;
}
// Returns EnableState.Enabled if the supplied subkey is a valid LANGID key with enabled
// cicero assembly.
private static EnableState IsLangidEnabled(RegistryKey key, string subKeyName, bool localMachine)
{
if (subKeyName.Length != LANGIDLength)
return EnableState.Error;
// Loop through all the assembly entries for the langid
return IterateSubKeys(key, subKeyName, new IterateHandler(IsAssemblyEnabled), localMachine);
}
// Returns EnableState.Enabled if the supplied assembly key is enabled.
private static EnableState IsAssemblyEnabled(RegistryKey key, string subKeyName, bool localMachine)
{
RegistryKey subKey;
object obj;
if (subKeyName.Length != CLSIDLength)
return EnableState.Error;
// Open the local machine assembly key.
subKey = key.OpenSubKey(subKeyName);
if (subKey == null)
return EnableState.Error;
// Try to read the "Enable" value.
obj = subKey.GetValue("Enable");
if (obj is int)
{
return ((int)obj == 0) ? EnableState.Disabled : EnableState.Enabled;
}
return EnableState.None;
}
// Calls the supplied delegate on each of the children of keyBase.
private static EnableState IterateSubKeys(RegistryKey keyBase, string subKey, IterateHandler handler, bool localMachine)
{
RegistryKey key;
string[] subKeyNames;
EnableState state;
key = keyBase.OpenSubKey(subKey, false);
if (key == null)
return EnableState.Error;
subKeyNames = key.GetSubKeyNames();
state = EnableState.Error;
foreach (string name in subKeyNames)
{
switch (handler(key, name, localMachine))
{
case EnableState.Error:
break;
case EnableState.None:
if (localMachine) // For lm, want to return here right away.
return EnableState.None;
// For current user, remember that we found no Enable value.
if (state == EnableState.Error)
{
state = EnableState.None;
}
break;
case EnableState.Disabled:
state = EnableState.Disabled;
break;
case EnableState.Enabled:
return EnableState.Enabled;
}
}
return state;
}
#endregion Private Methods
//-----------------------------------------------------
//
// Private Properties
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
// String consts used to validate registry entires.
private const int CLSIDLength = 38; // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
private const int LANGIDLength = 10; // 0x12345678
// Status of a TIP assembly.
private enum EnableState
{
Error, // Invalid entry.
None, // No explicit Enable entry on the assembly.
Enabled, // Assembly is enabled.
Disabled // Assembly is disabled.
};
// Callback delegate for the IterateSubKeys method.
private delegate EnableState IterateHandler(RegistryKey key, string subKeyName, bool localMachine);
// Install state.
private enum InstallState
{
Unknown, // Haven't checked to see if any TIPs are installed yet.
Installed, // Checked and installed.
NotInstalled // Checked and not installed.
}
// Cached install state value.
// Writes are not thread safe, but we don't mind the neglible perf hit
// of potentially writing it twice.
private static InstallState s_servicesInstalled = InstallState.Unknown;
private static object s_servicesInstalledLock = new object();
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebServiceTypeData.cs
- PolyLineSegmentFigureLogic.cs
- UserPersonalizationStateInfo.cs
- DefaultMergeHelper.cs
- ProfileGroupSettingsCollection.cs
- SoundPlayerAction.cs
- ImageIndexEditor.cs
- ExpressionVisitor.cs
- XmlSchemaIdentityConstraint.cs
- TrustLevelCollection.cs
- StrongNameKeyPair.cs
- ConfigurationException.cs
- DictionarySurrogate.cs
- SpeakInfo.cs
- EUCJPEncoding.cs
- DataGridViewSelectedRowCollection.cs
- PathGeometry.cs
- UDPClient.cs
- ScriptMethodAttribute.cs
- SqlTrackingService.cs
- FontInfo.cs
- NonSerializedAttribute.cs
- ThreadExceptionDialog.cs
- CultureSpecificStringDictionary.cs
- HttpCookieCollection.cs
- WsatEtwTraceListener.cs
- ServiceMemoryGates.cs
- LineVisual.cs
- XPathNavigator.cs
- OleStrCAMarshaler.cs
- CreateUserErrorEventArgs.cs
- FormsAuthenticationModule.cs
- VisualStyleRenderer.cs
- WebConfigurationHostFileChange.cs
- RegistryConfigurationProvider.cs
- XPathArrayIterator.cs
- MenuDesigner.cs
- MediaScriptCommandRoutedEventArgs.cs
- ByteAnimation.cs
- TextEditorCharacters.cs
- RemotingConfigParser.cs
- ObjectSet.cs
- GetImportFileNameRequest.cs
- WmpBitmapEncoder.cs
- ProfileInfo.cs
- Menu.cs
- SoapEnumAttribute.cs
- ZipFileInfoCollection.cs
- UInt64Converter.cs
- TableCellCollection.cs
- DeferrableContentConverter.cs
- MsmqHostedTransportConfiguration.cs
- JsonFormatWriterGenerator.cs
- IpcPort.cs
- HtmlControl.cs
- DecoratedNameAttribute.cs
- Stack.cs
- ExceptionRoutedEventArgs.cs
- ImageAttributes.cs
- ConfigXmlReader.cs
- MeshGeometry3D.cs
- BaseProcessor.cs
- BrowserCapabilitiesFactory.cs
- _WinHttpWebProxyDataBuilder.cs
- LiteralControl.cs
- WSHttpBindingBase.cs
- MultiPageTextView.cs
- FirstMatchCodeGroup.cs
- SQLDateTimeStorage.cs
- NameValuePair.cs
- RequestContextBase.cs
- ResetableIterator.cs
- TargetFrameworkAttribute.cs
- httpstaticobjectscollection.cs
- ConnectionManagementSection.cs
- DetailsViewDeletedEventArgs.cs
- DockPattern.cs
- DataGridViewCheckBoxCell.cs
- EqualityComparer.cs
- TraceInternal.cs
- Transaction.cs
- Figure.cs
- ModuleElement.cs
- SqlCacheDependencySection.cs
- HwndAppCommandInputProvider.cs
- QueryableDataSourceView.cs
- _SSPIWrapper.cs
- CustomErrorsSection.cs
- ComponentManagerBroker.cs
- SqlBooleanMismatchVisitor.cs
- PageParserFilter.cs
- NGCPageContentSerializerAsync.cs
- Trustee.cs
- ExpressionHelper.cs
- XmlCharCheckingWriter.cs
- CatalogPart.cs
- Underline.cs
- WmlValidationSummaryAdapter.cs
- ScriptingRoleServiceSection.cs
- ConfigXmlCDataSection.cs