Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Input / TextServicesContext.cs / 1 / TextServicesContext.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: Manages Text Services Framework state. // // History: // 07/16/2003 : benwest - Ported from .net tree. // //--------------------------------------------------------------------------- using System; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Threading; using System.Security; using System.Security.Permissions; using System.Diagnostics; using System.Collections; using MS.Utility; using MS.Win32; using MS.Internal; using MS.Internal.PresentationCore; // SecurityHelper namespace System.Windows.Input { //----------------------------------------------------- // // TextServicesContext class // //----------------------------------------------------- ////// This class manages the ITfThreadMgr, EmptyDim and the reference to /// the default TextStore. /// The instance of TextServicesContext class is created per Dispatcher. /// ////// internal class TextServicesContext { //------------------------------------------------------ // // Constructors // //----------------------------------------------------- #region Constructors ////// Instantiates a TextServicesContext. /// ////// Critical - accesses AppDomain.DomainUnload event. /// SecurityTreatAsSafe - does not accept or reveal any information. /// [SecurityCritical, SecurityTreatAsSafe] private TextServicesContext() { Debug.Assert(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA, "SetDispatcherThreaad on MTA thread"); TextServicesContextShutDownListener listener; // Add Dispatcher.Shutdown event handler. We will clean up Cicero's resource // when Dispatcher is terminated. listener = new TextServicesContextShutDownListener(this, ShutDownEvents.DispatcherShutdown); // Add an event handler for AppDomain unload. // When an AppDomain is unloaded, we won't get the Dispatcher shutdown, // and we'll be called back on a worker thread. listener = new TextServicesContextShutDownListener(this, ShutDownEvents.DomainUnload); } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods ////// Releases all unmanaged resources allocated by the /// TextServicesContext. /// ////// if appDomainShutdown == false, this method must be called on the /// Dispatcher thread. Otherwise, the caller is an AppDomain.Shutdown /// listener, and is calling from a worker thread. /// ////// Critical - access thread manager directly /// TreatAsSafe - uninitializing would only result in input being dead for the app /// [SecurityCritical, SecurityTreatAsSafe] internal void Uninitialize(bool appDomainShutdown) { // Unregister DefaultTextStore. if (_defaultTextStore != null) { StopTransitoryExtension(); if (_defaultTextStore.DocumentManager != null) { _defaultTextStore.DocumentManager.Pop(UnsafeNativeMethods.PopFlags.TF_POPF_ALL); Marshal.ReleaseComObject(_defaultTextStore.DocumentManager); _defaultTextStore.DocumentManager = null; } // We can't use tls during AppDomainShutdown -- we're called on // a worker thread. But we don't need to cleanup in that case // either. if (!appDomainShutdown) { InputMethod.Current.DefaultTextStore = null; } _defaultTextStore = null; } // Free up any remaining textstores. if (_istimactivated == true) { // Shut down the thread manager when the last TextStore goes away. // On XP, if we're called on a worker thread (during AppDomain shutdown) // we can't call call any methods on _threadManager. The problem is // that there's no proxy registered for ITfThreadMgr on OS versions // previous to Vista. Not calling Deactivate will leak the IMEs, but // in practice (1) they're singletons, so it's not unbounded; and (2) // most applications will share the thread with other AppDomains that // have a UI, in which case the IME won't be released until the process // shuts down in any case. In theory we could also work around this // problem by creating our own XP proxy/stub implementation, which would // be added to WPF setup.... if (!appDomainShutdown || System.Environment.OSVersion.Version.Major >= 6) { _threadManager.Value.Deactivate(); } _istimactivated = false; } // Release the empty dim. if (_dimEmpty != null) { if (_dimEmpty.Value != null) { Marshal.ReleaseComObject(_dimEmpty.Value); } _dimEmpty = null; } // Release the ThreadManager. // We don't do this in UnregisterTextStore because someone may have // called get_ThreadManager after the last TextStore was unregistered. if (_threadManager != null) { if (_threadManager.Value != null) { Marshal.ReleaseComObject(_threadManager.Value); } _threadManager = null; } } ////// Feeds a keystroke to the Text Services Framework, wrapper for /// ITfKeystrokeMgr::TestKeyUp/TestKeyDown/KeyUp/KeyDown. /// ////// Must be called on the main dispatcher thread. /// ////// true if the keystroke will be eaten by the Text Services Framework, /// false otherwise. /// Callers should stop further processing of the keystroke on true, /// continue otherwise. /// ////// Critical - directly access thread manager, and pushes keystrokes into the input pipeline /// [SecurityCritical] internal bool Keystroke(int wParam, int lParam, KeyOp op) { bool fConsume; UnsafeNativeMethods.ITfKeystrokeMgr keystrokeMgr; // We delay load cicero until someone creates an ITextStore. // Or this thread may not have a ThreadMgr. if ((_threadManager == null) || (_threadManager.Value == null)) return false; keystrokeMgr = _threadManager.Value as UnsafeNativeMethods.ITfKeystrokeMgr; switch (op) { case KeyOp.TestUp: keystrokeMgr.TestKeyUp(wParam, lParam, out fConsume); break; case KeyOp.TestDown: keystrokeMgr.TestKeyDown(wParam, lParam, out fConsume); break; case KeyOp.Up: keystrokeMgr.KeyUp(wParam, lParam, out fConsume); break; case KeyOp.Down: keystrokeMgr.KeyDown(wParam, lParam, out fConsume); break; default: fConsume = false; break; } return fConsume; } // Called by framework's TextStore class. This method registers a // document with TSF. The TextServicesContext must maintain this list // to ensure all native resources are released after gc or uninitialization. ////// Critical - directly manipulates input/message pump It also calls into Cicero /// to extract ThreadManager, clientID and DocumentManager all of which are not safe to /// expose. /// [SecurityCritical] internal void RegisterTextStore(DefaultTextStore defaultTextStore) { // We must cache the DefaultTextStore because we'll need it from // a worker thread if the AppDomain is torn down before the Dispatcher // is shutdown. _defaultTextStore = defaultTextStore; UnsafeNativeMethods.ITfThreadMgr threadManager = ThreadManager; if (threadManager != null) { UnsafeNativeMethods.ITfDocumentMgr doc; UnsafeNativeMethods.ITfContext context; int editCookie = UnsafeNativeMethods.TF_INVALID_COOKIE; // Activate TSF on this thread if this is the first TextStore. if (_istimactivated == false) { //temp variable created to retrieve the value // which is then stored in the critical data. int clientIdTemp; threadManager.Activate(out clientIdTemp); _clientId = new SecurityCriticalData(clientIdTemp); _istimactivated = true; } // Create a TSF document. threadManager.CreateDocumentMgr(out doc); doc.CreateContext(_clientId.Value, 0 /* flags */, _defaultTextStore, out context, out editCookie); doc.Push(context); // Release any native resources we're done with. Marshal.ReleaseComObject(context); // Same DocumentManager and EditCookie in _defaultTextStore. _defaultTextStore.DocumentManager = doc; _defaultTextStore.EditCookie = editCookie; // Start the transitory extenstion so we can have Level 1 composition window from Cicero. StartTransitoryExtension(); } } // Cal ITfThreadMgr.SetFocus() with the dim for the default text store /// /// Critical - access DocumentManager of the current DefaultTextStore. /// TreatAsSafe - This is a safe since it does not expose ITfDocumentMgr. /// [SecurityCritical,SecurityTreatAsSafe] internal void SetFocusOnDefaultTextStore() { SetFocusOnDim(DefaultTextStore.Current.DocumentManager); } // Cal ITfThreadMgr.SetFocus() with the empty dim. ////// Critical - access ITfDocumentMgr for empty dim. /// TreatAsSafe - This is a safe since it does not expose ITfDocumentMgr. /// [SecurityCritical,SecurityTreatAsSafe] internal void SetFocusOnEmptyDim() { SetFocusOnDim(EmptyDocumentManager); } #endregion Internal Methods //----------------------------------------------------- // // Internal Properties // //------------------------------------------------------ // Get TextServicesContext that is linked to the current Dispatcher. // return NULL if the default text store is not registered yet. internal static TextServicesContext DispatcherCurrent { get { // Create TextServicesContext on demand. if (InputMethod.Current.TextServicesContext == null) { InputMethod.Current.TextServicesContext = new TextServicesContext(); } return InputMethod.Current.TextServicesContext; } } ////// This is an internal, link demand protected method. /// ////// Critical - returns the thread manager (input and message pump) /// internal UnsafeNativeMethods.ITfThreadMgr ThreadManager { // The ITfThreadMgr for this thread. [SecurityCritical] get { if (_threadManager == null) { _threadManager = new SecurityCriticalDataClass(TextServicesLoader.Load()); } return _threadManager.Value; } } //----------------------------------------------------- // // Internal Events // //----------------------------------------------------- //----------------------------------------------------- // // Internal Enums // //------------------------------------------------------ #region Internal Enums /// /// Specifies the type of keystroke operation to perform in the /// TextServicesContext.Keystroke method. /// internal enum KeyOp { ////// ITfKeystrokeMgr::TestKeyUp /// TestUp, ////// ITfKeystrokeMgr::TestKeyDown /// TestDown, ////// ITfKeystrokeMgr::KeyUp /// Up, ////// ITfKeystrokeMgr::KeyDown /// Down }; #endregion Internal Enums //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ // Cal ITfThreadMgr.SetFocus() with dim ////// Critical: This code calls into critical code threadmgr.SetFocus /// TreatAsSafe: This does not expose any critical data and SetFocus is safe to expose /// [SecurityCritical,SecurityTreatAsSafe] private void SetFocusOnDim(UnsafeNativeMethods.ITfDocumentMgr dim) { UnsafeNativeMethods.ITfThreadMgr threadmgr = ThreadManager; if (threadmgr != null) { threadmgr.SetFocus(dim); } } // Start the transitory extestion for Cicero Level1/Level2 composition window support. ////// Critical: Accesses unmanaged pointers (DocumentManager, CompartmentMgr,Compartment, Source) /// [SecurityCritical] private void StartTransitoryExtension() { Guid guid; Object var; UnsafeNativeMethods.ITfCompartmentMgr compmgr; UnsafeNativeMethods.ITfCompartment comp; UnsafeNativeMethods.ITfSource source; int transitoryExtensionSinkCookie; // Start TransitryExtension compmgr = _defaultTextStore.DocumentManager as UnsafeNativeMethods.ITfCompartmentMgr; // Set GUID_COMPARTMENT_TRANSITORYEXTENSION guid = UnsafeNativeMethods.GUID_COMPARTMENT_TRANSITORYEXTENSION; compmgr.GetCompartment(ref guid, out comp); var = (int)1; comp.SetValue(0, ref var); // Advise TransitoryExtension Sink and store the cookie. guid = UnsafeNativeMethods.IID_ITfTransitoryExtensionSink; source = _defaultTextStore.DocumentManager as UnsafeNativeMethods.ITfSource; if (source != null) { // DocumentManager only supports ITfSource on Longhorn, XP does not support it source.AdviseSink(ref guid, _defaultTextStore, out transitoryExtensionSinkCookie); _defaultTextStore.TransitoryExtensionSinkCookie = transitoryExtensionSinkCookie; } Marshal.ReleaseComObject(comp); } // Stop TransitoryExtesion ////// Critical: This code calls into ITfCompartmentMgr, ITfCompartment and ITfSource all /// COM interop pointers /// TreatAsSafe: This does not expose any critical data. /// Stopping the transitory extenstion is a safe operation. /// [SecurityCritical,SecurityTreatAsSafe] private void StopTransitoryExtension() { // Unadvice the transitory extension sink. if (_defaultTextStore.TransitoryExtensionSinkCookie != UnsafeNativeMethods.TF_INVALID_COOKIE) { UnsafeNativeMethods.ITfSource source; source = _defaultTextStore.DocumentManager as UnsafeNativeMethods.ITfSource; if (source != null) { // DocumentManager only supports ITfSource on Longhorn, XP does not support it source.UnadviseSink(_defaultTextStore.TransitoryExtensionSinkCookie); } _defaultTextStore.TransitoryExtensionSinkCookie = UnsafeNativeMethods.TF_INVALID_COOKIE; } // Reset GUID_COMPARTMENT_TRANSITORYEXTENSION UnsafeNativeMethods.ITfCompartmentMgr compmgr; compmgr = _defaultTextStore.DocumentManager as UnsafeNativeMethods.ITfCompartmentMgr; if (compmgr != null) { Guid guid; Object var; UnsafeNativeMethods.ITfCompartment comp; guid = UnsafeNativeMethods.GUID_COMPARTMENT_TRANSITORYEXTENSION; compmgr.GetCompartment(ref guid, out comp); if (comp != null) { var = (int)0; comp.SetValue(0, ref var); Marshal.ReleaseComObject(comp); } } } //------------------------------------------------------ // // Private Properties // //----------------------------------------------------- // Create an empty dim on demand. ////// Critical - directly manipulates thread manager and expose ITfDocumentMgr /// private UnsafeNativeMethods.ITfDocumentMgr EmptyDocumentManager { [SecurityCritical] get { if (_dimEmpty == null) { UnsafeNativeMethods.ITfThreadMgr threadManager = ThreadManager; if (threadManager == null) { return null; } //creating temp variable to retrieve from call and store in security critical data UnsafeNativeMethods.ITfDocumentMgr dimEmptyTemp; // Create a TSF document. threadManager.CreateDocumentMgr(out dimEmptyTemp); _dimEmpty = new SecurityCriticalDataClass(dimEmptyTemp); } return _dimEmpty.Value; } } //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- #region Private Fields // Cached Dispatcher default text store. // We must cache the DefaultTextStore because we sometimes need it from // a worker thread if the AppDomain is torn down before the Dispatcher // is shutdown. private DefaultTextStore _defaultTextStore; // This is true if thread manager is activated. private bool _istimactivated; // The root TSF object, created on demand. /// /// Critical: UnsafeNativeMethods.ITfThreadMgr has methods with SuppressUnmanagedCodeSecurity. /// private SecurityCriticalDataClass_threadManager; // TSF ClientId from Activate call. /// /// Critical: _clientId is an identifier for Cicero. /// private SecurityCriticalData_clientId; // The empty dim for this thread. Created on demand. /// /// Critical: UnsafeNativeMethods.ITfDocumentMgr has methods with SuppressUnmanagedCodeSecurity. /// private SecurityCriticalDataClass_dimEmpty; #endregion Private Fields #region WeakEventTableShutDownListener private sealed class TextServicesContextShutDownListener : ShutDownListener { /// /// Critical: accesses AppDomain.DomainUnload event /// TreatAsSafe: This code does not take any parameter or return state. /// It simply attaches private callbacks. /// [SecurityCritical,SecurityTreatAsSafe] public TextServicesContextShutDownListener(TextServicesContext target, ShutDownEvents events) : base(target, events) { _arg = (events == ShutDownEvents.DomainUnload); } internal override void OnShutDown(object target) { TextServicesContext textServicesContext = (TextServicesContext)target; textServicesContext.Uninitialize(_arg); } bool _arg; } #endregion TextServicesContextShutDownListener } } // 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. // // // Description: Manages Text Services Framework state. // // History: // 07/16/2003 : benwest - Ported from .net tree. // //--------------------------------------------------------------------------- using System; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Threading; using System.Security; using System.Security.Permissions; using System.Diagnostics; using System.Collections; using MS.Utility; using MS.Win32; using MS.Internal; using MS.Internal.PresentationCore; // SecurityHelper namespace System.Windows.Input { //----------------------------------------------------- // // TextServicesContext class // //----------------------------------------------------- ////// This class manages the ITfThreadMgr, EmptyDim and the reference to /// the default TextStore. /// The instance of TextServicesContext class is created per Dispatcher. /// ////// internal class TextServicesContext { //------------------------------------------------------ // // Constructors // //----------------------------------------------------- #region Constructors ////// Instantiates a TextServicesContext. /// ////// Critical - accesses AppDomain.DomainUnload event. /// SecurityTreatAsSafe - does not accept or reveal any information. /// [SecurityCritical, SecurityTreatAsSafe] private TextServicesContext() { Debug.Assert(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA, "SetDispatcherThreaad on MTA thread"); TextServicesContextShutDownListener listener; // Add Dispatcher.Shutdown event handler. We will clean up Cicero's resource // when Dispatcher is terminated. listener = new TextServicesContextShutDownListener(this, ShutDownEvents.DispatcherShutdown); // Add an event handler for AppDomain unload. // When an AppDomain is unloaded, we won't get the Dispatcher shutdown, // and we'll be called back on a worker thread. listener = new TextServicesContextShutDownListener(this, ShutDownEvents.DomainUnload); } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods ////// Releases all unmanaged resources allocated by the /// TextServicesContext. /// ////// if appDomainShutdown == false, this method must be called on the /// Dispatcher thread. Otherwise, the caller is an AppDomain.Shutdown /// listener, and is calling from a worker thread. /// ////// Critical - access thread manager directly /// TreatAsSafe - uninitializing would only result in input being dead for the app /// [SecurityCritical, SecurityTreatAsSafe] internal void Uninitialize(bool appDomainShutdown) { // Unregister DefaultTextStore. if (_defaultTextStore != null) { StopTransitoryExtension(); if (_defaultTextStore.DocumentManager != null) { _defaultTextStore.DocumentManager.Pop(UnsafeNativeMethods.PopFlags.TF_POPF_ALL); Marshal.ReleaseComObject(_defaultTextStore.DocumentManager); _defaultTextStore.DocumentManager = null; } // We can't use tls during AppDomainShutdown -- we're called on // a worker thread. But we don't need to cleanup in that case // either. if (!appDomainShutdown) { InputMethod.Current.DefaultTextStore = null; } _defaultTextStore = null; } // Free up any remaining textstores. if (_istimactivated == true) { // Shut down the thread manager when the last TextStore goes away. // On XP, if we're called on a worker thread (during AppDomain shutdown) // we can't call call any methods on _threadManager. The problem is // that there's no proxy registered for ITfThreadMgr on OS versions // previous to Vista. Not calling Deactivate will leak the IMEs, but // in practice (1) they're singletons, so it's not unbounded; and (2) // most applications will share the thread with other AppDomains that // have a UI, in which case the IME won't be released until the process // shuts down in any case. In theory we could also work around this // problem by creating our own XP proxy/stub implementation, which would // be added to WPF setup.... if (!appDomainShutdown || System.Environment.OSVersion.Version.Major >= 6) { _threadManager.Value.Deactivate(); } _istimactivated = false; } // Release the empty dim. if (_dimEmpty != null) { if (_dimEmpty.Value != null) { Marshal.ReleaseComObject(_dimEmpty.Value); } _dimEmpty = null; } // Release the ThreadManager. // We don't do this in UnregisterTextStore because someone may have // called get_ThreadManager after the last TextStore was unregistered. if (_threadManager != null) { if (_threadManager.Value != null) { Marshal.ReleaseComObject(_threadManager.Value); } _threadManager = null; } } ////// Feeds a keystroke to the Text Services Framework, wrapper for /// ITfKeystrokeMgr::TestKeyUp/TestKeyDown/KeyUp/KeyDown. /// ////// Must be called on the main dispatcher thread. /// ////// true if the keystroke will be eaten by the Text Services Framework, /// false otherwise. /// Callers should stop further processing of the keystroke on true, /// continue otherwise. /// ////// Critical - directly access thread manager, and pushes keystrokes into the input pipeline /// [SecurityCritical] internal bool Keystroke(int wParam, int lParam, KeyOp op) { bool fConsume; UnsafeNativeMethods.ITfKeystrokeMgr keystrokeMgr; // We delay load cicero until someone creates an ITextStore. // Or this thread may not have a ThreadMgr. if ((_threadManager == null) || (_threadManager.Value == null)) return false; keystrokeMgr = _threadManager.Value as UnsafeNativeMethods.ITfKeystrokeMgr; switch (op) { case KeyOp.TestUp: keystrokeMgr.TestKeyUp(wParam, lParam, out fConsume); break; case KeyOp.TestDown: keystrokeMgr.TestKeyDown(wParam, lParam, out fConsume); break; case KeyOp.Up: keystrokeMgr.KeyUp(wParam, lParam, out fConsume); break; case KeyOp.Down: keystrokeMgr.KeyDown(wParam, lParam, out fConsume); break; default: fConsume = false; break; } return fConsume; } // Called by framework's TextStore class. This method registers a // document with TSF. The TextServicesContext must maintain this list // to ensure all native resources are released after gc or uninitialization. ////// Critical - directly manipulates input/message pump It also calls into Cicero /// to extract ThreadManager, clientID and DocumentManager all of which are not safe to /// expose. /// [SecurityCritical] internal void RegisterTextStore(DefaultTextStore defaultTextStore) { // We must cache the DefaultTextStore because we'll need it from // a worker thread if the AppDomain is torn down before the Dispatcher // is shutdown. _defaultTextStore = defaultTextStore; UnsafeNativeMethods.ITfThreadMgr threadManager = ThreadManager; if (threadManager != null) { UnsafeNativeMethods.ITfDocumentMgr doc; UnsafeNativeMethods.ITfContext context; int editCookie = UnsafeNativeMethods.TF_INVALID_COOKIE; // Activate TSF on this thread if this is the first TextStore. if (_istimactivated == false) { //temp variable created to retrieve the value // which is then stored in the critical data. int clientIdTemp; threadManager.Activate(out clientIdTemp); _clientId = new SecurityCriticalData(clientIdTemp); _istimactivated = true; } // Create a TSF document. threadManager.CreateDocumentMgr(out doc); doc.CreateContext(_clientId.Value, 0 /* flags */, _defaultTextStore, out context, out editCookie); doc.Push(context); // Release any native resources we're done with. Marshal.ReleaseComObject(context); // Same DocumentManager and EditCookie in _defaultTextStore. _defaultTextStore.DocumentManager = doc; _defaultTextStore.EditCookie = editCookie; // Start the transitory extenstion so we can have Level 1 composition window from Cicero. StartTransitoryExtension(); } } // Cal ITfThreadMgr.SetFocus() with the dim for the default text store /// /// Critical - access DocumentManager of the current DefaultTextStore. /// TreatAsSafe - This is a safe since it does not expose ITfDocumentMgr. /// [SecurityCritical,SecurityTreatAsSafe] internal void SetFocusOnDefaultTextStore() { SetFocusOnDim(DefaultTextStore.Current.DocumentManager); } // Cal ITfThreadMgr.SetFocus() with the empty dim. ////// Critical - access ITfDocumentMgr for empty dim. /// TreatAsSafe - This is a safe since it does not expose ITfDocumentMgr. /// [SecurityCritical,SecurityTreatAsSafe] internal void SetFocusOnEmptyDim() { SetFocusOnDim(EmptyDocumentManager); } #endregion Internal Methods //----------------------------------------------------- // // Internal Properties // //------------------------------------------------------ // Get TextServicesContext that is linked to the current Dispatcher. // return NULL if the default text store is not registered yet. internal static TextServicesContext DispatcherCurrent { get { // Create TextServicesContext on demand. if (InputMethod.Current.TextServicesContext == null) { InputMethod.Current.TextServicesContext = new TextServicesContext(); } return InputMethod.Current.TextServicesContext; } } ////// This is an internal, link demand protected method. /// ////// Critical - returns the thread manager (input and message pump) /// internal UnsafeNativeMethods.ITfThreadMgr ThreadManager { // The ITfThreadMgr for this thread. [SecurityCritical] get { if (_threadManager == null) { _threadManager = new SecurityCriticalDataClass(TextServicesLoader.Load()); } return _threadManager.Value; } } //----------------------------------------------------- // // Internal Events // //----------------------------------------------------- //----------------------------------------------------- // // Internal Enums // //------------------------------------------------------ #region Internal Enums /// /// Specifies the type of keystroke operation to perform in the /// TextServicesContext.Keystroke method. /// internal enum KeyOp { ////// ITfKeystrokeMgr::TestKeyUp /// TestUp, ////// ITfKeystrokeMgr::TestKeyDown /// TestDown, ////// ITfKeystrokeMgr::KeyUp /// Up, ////// ITfKeystrokeMgr::KeyDown /// Down }; #endregion Internal Enums //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ // Cal ITfThreadMgr.SetFocus() with dim ////// Critical: This code calls into critical code threadmgr.SetFocus /// TreatAsSafe: This does not expose any critical data and SetFocus is safe to expose /// [SecurityCritical,SecurityTreatAsSafe] private void SetFocusOnDim(UnsafeNativeMethods.ITfDocumentMgr dim) { UnsafeNativeMethods.ITfThreadMgr threadmgr = ThreadManager; if (threadmgr != null) { threadmgr.SetFocus(dim); } } // Start the transitory extestion for Cicero Level1/Level2 composition window support. ////// Critical: Accesses unmanaged pointers (DocumentManager, CompartmentMgr,Compartment, Source) /// [SecurityCritical] private void StartTransitoryExtension() { Guid guid; Object var; UnsafeNativeMethods.ITfCompartmentMgr compmgr; UnsafeNativeMethods.ITfCompartment comp; UnsafeNativeMethods.ITfSource source; int transitoryExtensionSinkCookie; // Start TransitryExtension compmgr = _defaultTextStore.DocumentManager as UnsafeNativeMethods.ITfCompartmentMgr; // Set GUID_COMPARTMENT_TRANSITORYEXTENSION guid = UnsafeNativeMethods.GUID_COMPARTMENT_TRANSITORYEXTENSION; compmgr.GetCompartment(ref guid, out comp); var = (int)1; comp.SetValue(0, ref var); // Advise TransitoryExtension Sink and store the cookie. guid = UnsafeNativeMethods.IID_ITfTransitoryExtensionSink; source = _defaultTextStore.DocumentManager as UnsafeNativeMethods.ITfSource; if (source != null) { // DocumentManager only supports ITfSource on Longhorn, XP does not support it source.AdviseSink(ref guid, _defaultTextStore, out transitoryExtensionSinkCookie); _defaultTextStore.TransitoryExtensionSinkCookie = transitoryExtensionSinkCookie; } Marshal.ReleaseComObject(comp); } // Stop TransitoryExtesion ////// Critical: This code calls into ITfCompartmentMgr, ITfCompartment and ITfSource all /// COM interop pointers /// TreatAsSafe: This does not expose any critical data. /// Stopping the transitory extenstion is a safe operation. /// [SecurityCritical,SecurityTreatAsSafe] private void StopTransitoryExtension() { // Unadvice the transitory extension sink. if (_defaultTextStore.TransitoryExtensionSinkCookie != UnsafeNativeMethods.TF_INVALID_COOKIE) { UnsafeNativeMethods.ITfSource source; source = _defaultTextStore.DocumentManager as UnsafeNativeMethods.ITfSource; if (source != null) { // DocumentManager only supports ITfSource on Longhorn, XP does not support it source.UnadviseSink(_defaultTextStore.TransitoryExtensionSinkCookie); } _defaultTextStore.TransitoryExtensionSinkCookie = UnsafeNativeMethods.TF_INVALID_COOKIE; } // Reset GUID_COMPARTMENT_TRANSITORYEXTENSION UnsafeNativeMethods.ITfCompartmentMgr compmgr; compmgr = _defaultTextStore.DocumentManager as UnsafeNativeMethods.ITfCompartmentMgr; if (compmgr != null) { Guid guid; Object var; UnsafeNativeMethods.ITfCompartment comp; guid = UnsafeNativeMethods.GUID_COMPARTMENT_TRANSITORYEXTENSION; compmgr.GetCompartment(ref guid, out comp); if (comp != null) { var = (int)0; comp.SetValue(0, ref var); Marshal.ReleaseComObject(comp); } } } //------------------------------------------------------ // // Private Properties // //----------------------------------------------------- // Create an empty dim on demand. ////// Critical - directly manipulates thread manager and expose ITfDocumentMgr /// private UnsafeNativeMethods.ITfDocumentMgr EmptyDocumentManager { [SecurityCritical] get { if (_dimEmpty == null) { UnsafeNativeMethods.ITfThreadMgr threadManager = ThreadManager; if (threadManager == null) { return null; } //creating temp variable to retrieve from call and store in security critical data UnsafeNativeMethods.ITfDocumentMgr dimEmptyTemp; // Create a TSF document. threadManager.CreateDocumentMgr(out dimEmptyTemp); _dimEmpty = new SecurityCriticalDataClass(dimEmptyTemp); } return _dimEmpty.Value; } } //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- #region Private Fields // Cached Dispatcher default text store. // We must cache the DefaultTextStore because we sometimes need it from // a worker thread if the AppDomain is torn down before the Dispatcher // is shutdown. private DefaultTextStore _defaultTextStore; // This is true if thread manager is activated. private bool _istimactivated; // The root TSF object, created on demand. /// /// Critical: UnsafeNativeMethods.ITfThreadMgr has methods with SuppressUnmanagedCodeSecurity. /// private SecurityCriticalDataClass_threadManager; // TSF ClientId from Activate call. /// /// Critical: _clientId is an identifier for Cicero. /// private SecurityCriticalData_clientId; // The empty dim for this thread. Created on demand. /// /// Critical: UnsafeNativeMethods.ITfDocumentMgr has methods with SuppressUnmanagedCodeSecurity. /// private SecurityCriticalDataClass_dimEmpty; #endregion Private Fields #region WeakEventTableShutDownListener private sealed class TextServicesContextShutDownListener : ShutDownListener { /// /// Critical: accesses AppDomain.DomainUnload event /// TreatAsSafe: This code does not take any parameter or return state. /// It simply attaches private callbacks. /// [SecurityCritical,SecurityTreatAsSafe] public TextServicesContextShutDownListener(TextServicesContext target, ShutDownEvents events) : base(target, events) { _arg = (events == ShutDownEvents.DomainUnload); } internal override void OnShutDown(object target) { TextServicesContext textServicesContext = (TextServicesContext)target; textServicesContext.Uninitialize(_arg); } bool _arg; } #endregion TextServicesContextShutDownListener } } // 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
- PtsPage.cs
- FlowDocumentScrollViewerAutomationPeer.cs
- XmlSchemaExternal.cs
- MappingException.cs
- KeyPullup.cs
- XmlDictionaryReader.cs
- FontStretches.cs
- MetadataUtilsSmi.cs
- MultipleCopiesCollection.cs
- ColumnHeaderConverter.cs
- ClientData.cs
- DictionarySectionHandler.cs
- MetabaseServerConfig.cs
- TypeElement.cs
- SchemaManager.cs
- SqlDataSourceCustomCommandEditor.cs
- SqlRecordBuffer.cs
- HierarchicalDataSourceDesigner.cs
- BaseProcessor.cs
- QilStrConcatenator.cs
- _AutoWebProxyScriptHelper.cs
- TextEditorThreadLocalStore.cs
- UnconditionalPolicy.cs
- FileIOPermission.cs
- Options.cs
- CollectionAdapters.cs
- ScanQueryOperator.cs
- XmlArrayItemAttribute.cs
- CreateUserWizard.cs
- PropertyIDSet.cs
- ServerReliableChannelBinder.cs
- ExcCanonicalXml.cs
- TextDecorationUnitValidation.cs
- Parameter.cs
- DialogResultConverter.cs
- HttpConfigurationSystem.cs
- QueryAccessibilityHelpEvent.cs
- VariableExpressionConverter.cs
- TypeSemantics.cs
- WebPartConnectionCollection.cs
- LoginCancelEventArgs.cs
- ZipArchive.cs
- ToolStripMenuItem.cs
- ProcessThreadCollection.cs
- LineBreakRecord.cs
- MailSettingsSection.cs
- RelationshipEndCollection.cs
- ResourceReferenceKeyNotFoundException.cs
- SafeUserTokenHandle.cs
- QueryGenerator.cs
- FocusChangedEventArgs.cs
- FrameworkElementFactory.cs
- ProcessStartInfo.cs
- Repeater.cs
- SmiTypedGetterSetter.cs
- OpCodes.cs
- ProcessHost.cs
- BookmarkResumptionRecord.cs
- ContentPosition.cs
- IgnoreFileBuildProvider.cs
- SecurityCriticalDataForSet.cs
- Schedule.cs
- TableHeaderCell.cs
- AxDesigner.cs
- XhtmlStyleClass.cs
- CodeVariableReferenceExpression.cs
- FindCriteria.cs
- SectionRecord.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- ProgressBar.cs
- XsltFunctions.cs
- PriorityQueue.cs
- SuppressMessageAttribute.cs
- XmlQueryType.cs
- TemplatedAdorner.cs
- FilterableAttribute.cs
- UIElementCollection.cs
- MultipartContentParser.cs
- WindowsSspiNegotiation.cs
- ToolStripSettings.cs
- QueryOutputWriter.cs
- CodeVariableReferenceExpression.cs
- TimelineCollection.cs
- WebColorConverter.cs
- JapaneseLunisolarCalendar.cs
- Int32RectValueSerializer.cs
- NameNode.cs
- GeneratedContractType.cs
- HttpContextServiceHost.cs
- ActivityMarkupSerializationProvider.cs
- CodeDefaultValueExpression.cs
- XmlReaderDelegator.cs
- SpecialNameAttribute.cs
- DocumentPaginator.cs
- Transform3D.cs
- BooleanStorage.cs
- WizardStepBase.cs
- VersionedStream.cs
- XmlObjectSerializer.cs
- _AutoWebProxyScriptHelper.cs