Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / Input / InputManager.cs / 1 / InputManager.cs
using System.Collections; using System.Windows.Threading; using System.Threading; using System.Windows; using System.Security; using System.Security.Permissions; using MS.Win32; using MS.Internal; using MS.Internal.PresentationCore; // SecurityHelper using System; using System.Diagnostics; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Input { ////// The InputManager class is responsible for coordinating all of the /// input system in Avalon. /// public sealed class InputManager : DispatcherObject { ////// A routed event indicating that an input report arrived. /// internal static readonly RoutedEvent PreviewInputReportEvent = GlobalEventManager.RegisterRoutedEvent("PreviewInputReport", RoutingStrategy.Tunnel, typeof(InputReportEventHandler), typeof(InputManager)); ////// A routed event indicating that an input report arrived. /// [FriendAccessAllowed] internal static readonly RoutedEvent InputReportEvent = GlobalEventManager.RegisterRoutedEvent("InputReport", RoutingStrategy.Bubble, typeof(InputReportEventHandler), typeof(InputManager)); ////// Return the input manager associated with the current context. /// ////// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This class is not ok to expose since SEE apps /// should not have to deal with this directly and /// it exposes methods that can be use for input spoofing /// /// public static InputManager Current { [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] get { return GetCurrentInputManagerImpl(); } } ////// Internal implementation of InputManager.Current. /// Critical but not TAS - for internal's to use. /// Only exists for perf. The link demand check was causing perf in some XAF scenarios. /// ////// Critical: This class is not ok to expose since SEE apps /// should not have to deal with this directly and /// it exposes methods that can be use for input spoofing /// /// internal static InputManager UnsecureCurrent { [SecurityCritical] [FriendAccessAllowed] get { return GetCurrentInputManagerImpl(); } } ////// Implementation of InputManager.Current /// ////// Critical: This class is not ok to expose since SEE apps /// should not have to deal with this directly and /// it exposes methods that can be use for input spoofing /// [SecurityCritical] private static InputManager GetCurrentInputManagerImpl() { InputManager inputManager = null; Dispatcher dispatcher = Dispatcher.CurrentDispatcher; inputManager = dispatcher.InputManager as InputManager; if (inputManager == null) { inputManager = new InputManager(); dispatcher.InputManager = inputManager; } return inputManager; } ////// Critical: This code causes critical data (inputmanager to be instantiated) /// This class should not be exposed in the SEE as it can be used for input spoofing. /// [SecurityCritical] private InputManager() { // STA Requirement // // Avalon doesn't necessarily require STA, but many components do. Examples // include Cicero, OLE, COM, etc. So we throw an exception here if the // thread is not STA. if(Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) { throw new InvalidOperationException(SR.Get(SRID.RequiresSTA)); } _stagingArea = new Stack(); _primaryKeyboardDevice = new Win32KeyboardDevice(this); _primaryMouseDevice = new Win32MouseDevice(this); _primaryCommandDevice = new CommandDevice(this); _stylusLogic = new StylusLogic(this); _continueProcessingStagingAreaCallback = new DispatcherOperationCallback(ContinueProcessingStagingArea); _hitTestInvalidatedAsyncOperation = null; _hitTestInvalidatedAsyncCallback = new DispatcherOperationCallback(HitTestInvalidatedAsyncCallback); _layoutUpdatedCallback = new EventHandler(OnLayoutUpdated); //need to cache it, LM only keeps weak ref ContextLayoutManager.From(Dispatcher).LayoutEvents.Add(_layoutUpdatedCallback); // Timer used to synchronize the input devices periodically _inputTimer = new DispatcherTimer(DispatcherPriority.Background); _inputTimer.Tick += new EventHandler(ValidateInputDevices); _inputTimer.Interval = TimeSpan.FromMilliseconds(125); } ////// /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This event lets people subscribe to all events in the system /// PublicOk: Method is link demanded. /// public event PreProcessInputEventHandler PreProcessInput { [SecurityCritical ] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] add { _preProcessInput += value; } [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] remove { _preProcessInput -= value; } } ////// /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This event lets people subscribe to all events in the system /// Not safe to expose. /// PublicOk: Method is link demanded. /// public event NotifyInputEventHandler PreNotifyInput { [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] add { _preNotifyInput += value; } [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] remove { _preNotifyInput -= value; } } ////// /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This event lets people subscribe to all events in the system /// Not safe to expose. /// PublicOk: Method is link demanded. /// public event NotifyInputEventHandler PostNotifyInput { [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] add { _postNotifyInput += value; } [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] remove { _postNotifyInput -= value; } } ////// /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This event lets people subscribe to all events in the system /// Not safe to expose. /// PublicOk: Method is link demanded. /// public event ProcessInputEventHandler PostProcessInput { [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] add { _postProcessInput += value; } [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] remove { _postProcessInput -= value; } } ////// This event is raised by the HwndSource.CriticalTranslateAccelerator /// on descendent HwndSource instances. The only subscriber to this event /// is KeyboardNavigation. /// ////// Critical: This event lets people subscribe to all input notifications /// internal event KeyEventHandler TranslateAccelerator { [FriendAccessAllowed] // Used by KeyboardNavigation.cs in Framework [SecurityCritical] add { _translateAccelerator += value; } [FriendAccessAllowed] // Used by KeyboardNavigation.cs in Framework [SecurityCritical] remove { _translateAccelerator -= value; } } ////// Raises the TranslateAccelerator event /// ////// Critical: Accesses critical _translateAccelerator. /// [SecurityCritical] internal void RaiseTranslateAccelerator(KeyEventArgs e) { if (_translateAccelerator != null) { _translateAccelerator(this, e); } } ////// Registers an input provider with the input manager. /// /// /// The input provider to register. /// ////// This class will not be available in internet zone. /// Critical: This code acceses and stores critical data (InputProvider) /// TreatAsSafe: This code demands UIPermission. /// [SecurityCritical] internal InputProviderSite RegisterInputProvider(IInputProvider inputProvider) { SecurityHelper.DemandUnrestrictedUIPermission(); // VerifyAccess(); // Create a site for this provider, and keep track of it. InputProviderSite site = new InputProviderSite(this, inputProvider); _inputProviders[inputProvider] = site; return site; } ////// This class will not be available in internet zone. /// Critical: This code acceses critical data in the form of InputProvider /// [SecurityCritical] internal void UnregisterInputProvider(IInputProvider inputProvider) { _inputProviders.Remove(inputProvider); } ////// Returns a collection of input providers registered with the input manager. /// ////// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// This class will not be available in internet zone. /// Critical: This code exposes InputProviders which are /// considered as critical data /// PublicOK: This code has a demand on it /// public ICollection InputProviders { [SecurityCritical] get { SecurityHelper.DemandUnrestrictedUIPermission(); return UnsecureInputProviders; } } ////// Returns a collection of input providers registered with the input manager. /// ////// Critical: This code exposes InputProviders which are considered as critical data /// This overload exists for perf. improvements in the internet zone since this function is called /// quite often /// internal ICollection UnsecureInputProviders { [SecurityCritical] get { return _inputProviders.Keys; } } ////// Read-only access to the primary keyboard device. /// public KeyboardDevice PrimaryKeyboardDevice { // get {return _primaryKeyboardDevice;} } ////// Read-only access to the primary mouse device. /// public MouseDevice PrimaryMouseDevice { // get {return _primaryMouseDevice;} } ////// Critical, accesses critical member _stylusLogic /// internal StylusLogic StylusLogic { [SecurityCritical, FriendAccessAllowed] get { return _stylusLogic; } } ////// Read-only access to the primary keyboard device. /// internal CommandDevice PrimaryCommandDevice { get {return _primaryCommandDevice;} } ////// The InDragDrop property represents whether we are currently inside /// a OLE DragDrop operation. /// internal bool InDragDrop { get { return _inDragDrop; } set { _inDragDrop = value; } } ////// The MostRecentInputDevice represents the last input device to /// report an "interesting" user action. What exactly constitutes /// such an action is up to each device to implement. /// public InputDevice MostRecentInputDevice { get { return _mostRecentInputDevice; } internal set { _mostRecentInputDevice = value; } } ////// An event that is raised whenever the result of a hit-test may /// have changed. /// public event EventHandler HitTestInvalidatedAsync; internal void NotifyHitTestInvalidated() { // The HitTest result may have changed for someone somewhere. // Raise the HitTestInvalidatedAsync event after the next layout. if(_hitTestInvalidatedAsyncOperation == null) { // It would be best to re-evaluate anything dependent on the hit-test results // immediately after layout & rendering are complete. Unfortunately this can // lead to an infinite loop. Consider the following scenario: // // If the mouse is over an element, hide it. // // This never resolves to a "correct" state. When the mouse moves over the // element, the element is hidden, so the mouse is no longer over it, so the // element is shown, but that means the mouse is over it again. Repeat. // // We push our re-evaluation to a priority lower than input processing so that // the user can change the input device to avoid the infinite loops, or close // the app if nothing else works. // _hitTestInvalidatedAsyncOperation = Dispatcher.BeginInvoke(DispatcherPriority.Input, _hitTestInvalidatedAsyncCallback, null); } else if (_hitTestInvalidatedAsyncOperation.Priority == DispatcherPriority.Inactive) { // This means that we are currently waiting for the timer to expire so // that we can promote the current queue item to Input prority. Since // we are now being told that we need to re-hittest, we simply stop the // timer and promote the queue item right now instead of waiting for expiry. ValidateInputDevices(this, EventArgs.Empty); } } ////// Critical - calls UnsecureCurrent /// TreatAsSafe - notifying the input manager that hit test information needs to be recalced. /// is considered safe ( and currently this code is transparent). /// [SecurityCritical, SecurityTreatAsSafe] internal static void SafeCurrentNotifyHitTestInvalidated() { UnsecureCurrent.NotifyHitTestInvalidated(); } private object HitTestInvalidatedAsyncCallback(object arg) { _hitTestInvalidatedAsyncOperation = null; if (HitTestInvalidatedAsync != null) { HitTestInvalidatedAsync(this, EventArgs.Empty); } return null; } private void OnLayoutUpdated(object sender, EventArgs e) { NotifyHitTestInvalidated(); } ////// Start the timer that will kick off synchronize /// operation on all the input devices upon expiry /// internal void InvalidateInputDevices() { // If there is no pending ansyc hittest operation if (_hitTestInvalidatedAsyncOperation == null) { // Post an inactive item to the queue. When the timer expires // we will promote this queue item to Input priority. _hitTestInvalidatedAsyncOperation = Dispatcher.BeginInvoke(DispatcherPriority.Inactive, _hitTestInvalidatedAsyncCallback, null); // Start the input timer _inputTimer.IsEnabled = true; } } ////// Synchronize the input devices /// private void ValidateInputDevices(object sender, EventArgs e) { Debug.Assert(_hitTestInvalidatedAsyncOperation != null && _hitTestInvalidatedAsyncOperation.Priority == DispatcherPriority.Inactive && _inputTimer.IsEnabled == true); // Promote the pending DispatcherOperation to Input Priority _hitTestInvalidatedAsyncOperation.Priority = DispatcherPriority.Input; // Stop the input timer _inputTimer.IsEnabled = false; } ////// Synchronously processes the specified input. /// ////// The specified input is processed by all of the filters and /// monitors, and is finally dispatched to the appropriate /// element as an input event. /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Whether or not any event generated as a consequence of this /// event was handled. /// ////// Critical: This code can cause input to be processed. /// PublicOK: This code link demands. /// [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] public bool ProcessInput(InputEventArgs input) { // VerifyAccess(); if(input == null) { throw new ArgumentNullException("input"); } // Push a marker indicating the portion of the staging area // that needs to be processed. PushMarker(); // Push the input to be processed onto the staging area. PushInput(input, null); // Post a work item to continue processing the staging area // in case someone pushes a dispatcher frame in the middle // of input processing. RequestContinueProcessingStagingArea(); // Now drain the staging area up to the marker we pushed. bool handled = ProcessStagingArea(); return handled; } ////// Critical - accesses critical data ( _stagingArea) /// [SecurityCritical] internal StagingAreaInputItem PushInput(StagingAreaInputItem inputItem) { _stagingArea.Push(inputItem); return inputItem; } ////// Critical - accesses critical function ( PushInput) /// [SecurityCritical] internal StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote) { StagingAreaInputItem item = new StagingAreaInputItem(false); item.Reset(input, promote); return PushInput(item); } ////// Critical - calls a critical function ( PushInput). /// [SecurityCritical] internal StagingAreaInputItem PushMarker() { StagingAreaInputItem item = new StagingAreaInputItem(true); return PushInput(item); } ////// Critical - accesses critical data _stagingArea. /// [SecurityCritical] internal StagingAreaInputItem PopInput() { object input = null; if(_stagingArea.Count > 0) { input = _stagingArea.Pop(); } return input as StagingAreaInputItem; } ////// Critical - accesses the _stagingArea critical data. /// [SecurityCritical] internal StagingAreaInputItem PeekInput() { object input = null; if(_stagingArea.Count > 0) { input = _stagingArea.Peek(); } return input as StagingAreaInputItem; } ////// Critical - accesses critical data ( _stagingArea.Count) and calls a critical function - ProcessStagingArea /// [SecurityCritical ] internal object ContinueProcessingStagingArea(object unused) { _continueProcessingStagingArea = false; // It is possible that we can be re-entered by a nested // dispatcher frame. Continue processing the staging // area if we need to. if(_stagingArea.Count > 0) { // Before we actually start to drain the staging area, we need // to post a work item to process more input. This enables us // to process more input if we enter a nested pump. RequestContinueProcessingStagingArea(); // Now synchronously drain the staging area. ProcessStagingArea(); } return null; } ////// Critical: accesses critical data ( PopInput()) and raises events with the user-initiated flag /// [SecurityCritical] private bool ProcessStagingArea() { bool handled = false; // For performance reasons, try to reuse the input event args. // If we are reentrered, we have to start over with fresh event // args, so we clear the member variables before continuing. // Also, we cannot simply make an single instance of the // PreProcessedInputEventArgs and cast it to NotifyInputEventArgs // or ProcessInputEventArgs because a malicious user could upcast // the object and call inappropriate methods. NotifyInputEventArgs notifyInputEventArgs = (_notifyInputEventArgs != null) ? _notifyInputEventArgs : new NotifyInputEventArgs(); ProcessInputEventArgs processInputEventArgs = (_processInputEventArgs != null) ? _processInputEventArgs : new ProcessInputEventArgs(); PreProcessInputEventArgs preProcessInputEventArgs = (_preProcessInputEventArgs != null) ? _preProcessInputEventArgs : new PreProcessInputEventArgs(); _notifyInputEventArgs = null; _processInputEventArgs = null; _preProcessInputEventArgs = null; // Because we can be reentered, we can't just enumerate over the // staging area - that could throw an exception if the queue // changes underneath us. Instead, just loop until we find a // frame marker or until the staging area is empty. StagingAreaInputItem item = null; while((item = PopInput()) != null) { // If we found a marker, we have reached the end of a // "section" of the staging area. We just return from // the synchronous processing of the staging area. // If a dispatcher frame has been pushed by someone, this // will not return to the original ProcessInput. Instead // it will unwind to the dispatcher and since we have // already pushed a work item to continue processing the // input, it will simply call back into us to do more // processing. At which point we will continue to drain // the staging area. This could cause strage behavior, // but it is deemed more acceptable than stalling input // processing. // if(item.IsMarker) { break; } // Pre-Process the input. This could modify the staging // area, and it could cancel the processing of this // input event. // // Because we use multi-cast delegates, we always have to // create a new multi-cast delegate when we add or remove // a handler. This means we can just call the current // multi-cast delegate instance, and it is safe to iterate // over, even if we get reentered. if (_preProcessInput != null) { preProcessInputEventArgs.Reset(item, this); // Invoke the handlers in reverse order so that handlers that // users add are invoked before handlers in the system. Delegate[] handlers = _preProcessInput.GetInvocationList(); for(int i = (handlers.Length - 1); i >= 0; i--) { PreProcessInputEventHandler handler = (PreProcessInputEventHandler) handlers[i]; handler(this, preProcessInputEventArgs); } } if(!preProcessInputEventArgs.Canceled) { // Pre-Notify the input. // // Because we use multi-cast delegates, we always have to // create a new multi-cast delegate when we add or remove // a handler. This means we can just call the current // multi-cast delegate instance, and it is safe to iterate // over, even if we get reentered. if(_preNotifyInput != null) { notifyInputEventArgs.Reset(item, this); // Invoke the handlers in reverse order so that handlers that // users add are invoked before handlers in the system. Delegate[] handlers = _preNotifyInput.GetInvocationList(); for(int i = (handlers.Length - 1); i >= 0; i--) { NotifyInputEventHandler handler = (NotifyInputEventHandler) handlers[i]; handler(this, notifyInputEventArgs); } } // Raise the input event being processed. InputEventArgs input = item.Input; // Some input events are explicitly associated with // an element. Those that are not are associated with // the target of the input device for this event. DependencyObject eventSource = input.Source as DependencyObject; if(eventSource == null || !InputElement.IsValid(eventSource as IInputElement)) { if (input.Device != null) { eventSource = input.Device.Target as DependencyObject; } } if (eventSource != null) { if(InputElement.IsUIElement(eventSource)) { UIElement e = (UIElement) eventSource; e.RaiseEvent(input, true ); // Call the "trusted" flavor of RaiseEvent. } else if(InputElement.IsContentElement(eventSource)) { ContentElement ce = (ContentElement) eventSource; ce.RaiseEvent(input, true );// Call the "trusted" flavor of RaiseEvent. } else if (InputElement.IsUIElement3D(eventSource)) { UIElement3D e3D = (UIElement3D) eventSource; e3D.RaiseEvent(input, true); // Call the "trusted" flavor of RaiseEvent } } // Post-Notify the input. // // Because we use multi-cast delegates, we always have to // create a new multi-cast delegate when we add or remove // a handler. This means we can just call the current // multi-cast delegate instance, and it is safe to iterate // over, even if we get reentered. if(_postNotifyInput != null) { notifyInputEventArgs.Reset(item, this); // Invoke the handlers in reverse order so that handlers that // users add are invoked before handlers in the system. Delegate[] handlers = _postNotifyInput.GetInvocationList(); for(int i = (handlers.Length - 1); i >= 0; i--) { NotifyInputEventHandler handler = (NotifyInputEventHandler) handlers[i]; handler(this, notifyInputEventArgs); } } // Post-Process the input. This could modify the staging // area. // // Because we use multi-cast delegates, we always have to // create a new multi-cast delegate when we add or remove // a handler. This means we can just call the current // multi-cast delegate instance, and it is safe to iterate // over, even if we get reentered. if(_postProcessInput != null) { processInputEventArgs.Reset(item, this); // Invoke the handlers in reverse order so that handlers that // users add are invoked before handlers in the system. Delegate[] handlers = _postProcessInput.GetInvocationList(); for(int i = (handlers.Length - 1); i >= 0; i--) { ProcessInputEventHandler handler = (ProcessInputEventHandler) handlers[i]; processInputEventArgs.StagingItem.Input.MarkAsUserInitiated(); try { handler(this, processInputEventArgs); } finally // we do this in a finally block in case of exceptions { processInputEventArgs.StagingItem.Input.ClearUserInitiated(); } } // PreviewInputReport --> InputReport if(item.Input.RoutedEvent == InputManager.PreviewInputReportEvent) { if(!item.Input.Handled) { InputReportEventArgs previewInputReport = (InputReportEventArgs) item.Input; InputReportEventArgs inputReport = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report); inputReport.RoutedEvent=InputManager.InputReportEvent; PushInput(inputReport, item); } } } if(input.Handled) { handled = true; } } } // Store our input event args so that we can use them again, and // avoid having to allocate more. _notifyInputEventArgs = notifyInputEventArgs; _processInputEventArgs = processInputEventArgs; _preProcessInputEventArgs = preProcessInputEventArgs; // Make sure to throw away the contents of the event args so // we don't keep refs around to things we don't mean to. _notifyInputEventArgs.Reset(null, null); _processInputEventArgs.Reset(null, null); _preProcessInputEventArgs.Reset(null, null); return handled; } private void RequestContinueProcessingStagingArea() { if(!_continueProcessingStagingArea) { Dispatcher.BeginInvoke(DispatcherPriority.Input, _continueProcessingStagingAreaCallback, null); _continueProcessingStagingArea = true; } } private DispatcherOperationCallback _continueProcessingStagingAreaCallback; private bool _continueProcessingStagingArea; private NotifyInputEventArgs _notifyInputEventArgs; private ProcessInputEventArgs _processInputEventArgs; private PreProcessInputEventArgs _preProcessInputEventArgs; //these four events introduced for secutiy purposes ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event PreProcessInputEventHandler _preProcessInput; ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event NotifyInputEventHandler _preNotifyInput; ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event NotifyInputEventHandler _postNotifyInput; ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event ProcessInputEventHandler _postProcessInput; ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event KeyEventHandler _translateAccelerator; ////// This table holds critical data not ok to expose /// [SecurityCritical] private Hashtable _inputProviders = new Hashtable(); private KeyboardDevice _primaryKeyboardDevice; private MouseDevice _primaryMouseDevice; private CommandDevice _primaryCommandDevice; ////// Critical to prevent accidental spread to transparent code /// [SecurityCritical] private StylusLogic _stylusLogic; private bool _inDragDrop; private DispatcherOperationCallback _hitTestInvalidatedAsyncCallback; private DispatcherOperation _hitTestInvalidatedAsyncOperation; private EventHandler _layoutUpdatedCallback; ////// Critical: This stack holds all the input events and can be used /// to spoof or force arbitrary input /// [SecurityCritical] private Stack _stagingArea; private InputDevice _mostRecentInputDevice; // Timer used to synchronize the input devices periodically private DispatcherTimer _inputTimer; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System.Collections; using System.Windows.Threading; using System.Threading; using System.Windows; using System.Security; using System.Security.Permissions; using MS.Win32; using MS.Internal; using MS.Internal.PresentationCore; // SecurityHelper using System; using System.Diagnostics; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Input { ////// The InputManager class is responsible for coordinating all of the /// input system in Avalon. /// public sealed class InputManager : DispatcherObject { ////// A routed event indicating that an input report arrived. /// internal static readonly RoutedEvent PreviewInputReportEvent = GlobalEventManager.RegisterRoutedEvent("PreviewInputReport", RoutingStrategy.Tunnel, typeof(InputReportEventHandler), typeof(InputManager)); ////// A routed event indicating that an input report arrived. /// [FriendAccessAllowed] internal static readonly RoutedEvent InputReportEvent = GlobalEventManager.RegisterRoutedEvent("InputReport", RoutingStrategy.Bubble, typeof(InputReportEventHandler), typeof(InputManager)); ////// Return the input manager associated with the current context. /// ////// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This class is not ok to expose since SEE apps /// should not have to deal with this directly and /// it exposes methods that can be use for input spoofing /// /// public static InputManager Current { [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] get { return GetCurrentInputManagerImpl(); } } ////// Internal implementation of InputManager.Current. /// Critical but not TAS - for internal's to use. /// Only exists for perf. The link demand check was causing perf in some XAF scenarios. /// ////// Critical: This class is not ok to expose since SEE apps /// should not have to deal with this directly and /// it exposes methods that can be use for input spoofing /// /// internal static InputManager UnsecureCurrent { [SecurityCritical] [FriendAccessAllowed] get { return GetCurrentInputManagerImpl(); } } ////// Implementation of InputManager.Current /// ////// Critical: This class is not ok to expose since SEE apps /// should not have to deal with this directly and /// it exposes methods that can be use for input spoofing /// [SecurityCritical] private static InputManager GetCurrentInputManagerImpl() { InputManager inputManager = null; Dispatcher dispatcher = Dispatcher.CurrentDispatcher; inputManager = dispatcher.InputManager as InputManager; if (inputManager == null) { inputManager = new InputManager(); dispatcher.InputManager = inputManager; } return inputManager; } ////// Critical: This code causes critical data (inputmanager to be instantiated) /// This class should not be exposed in the SEE as it can be used for input spoofing. /// [SecurityCritical] private InputManager() { // STA Requirement // // Avalon doesn't necessarily require STA, but many components do. Examples // include Cicero, OLE, COM, etc. So we throw an exception here if the // thread is not STA. if(Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) { throw new InvalidOperationException(SR.Get(SRID.RequiresSTA)); } _stagingArea = new Stack(); _primaryKeyboardDevice = new Win32KeyboardDevice(this); _primaryMouseDevice = new Win32MouseDevice(this); _primaryCommandDevice = new CommandDevice(this); _stylusLogic = new StylusLogic(this); _continueProcessingStagingAreaCallback = new DispatcherOperationCallback(ContinueProcessingStagingArea); _hitTestInvalidatedAsyncOperation = null; _hitTestInvalidatedAsyncCallback = new DispatcherOperationCallback(HitTestInvalidatedAsyncCallback); _layoutUpdatedCallback = new EventHandler(OnLayoutUpdated); //need to cache it, LM only keeps weak ref ContextLayoutManager.From(Dispatcher).LayoutEvents.Add(_layoutUpdatedCallback); // Timer used to synchronize the input devices periodically _inputTimer = new DispatcherTimer(DispatcherPriority.Background); _inputTimer.Tick += new EventHandler(ValidateInputDevices); _inputTimer.Interval = TimeSpan.FromMilliseconds(125); } ////// /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This event lets people subscribe to all events in the system /// PublicOk: Method is link demanded. /// public event PreProcessInputEventHandler PreProcessInput { [SecurityCritical ] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] add { _preProcessInput += value; } [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] remove { _preProcessInput -= value; } } ////// /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This event lets people subscribe to all events in the system /// Not safe to expose. /// PublicOk: Method is link demanded. /// public event NotifyInputEventHandler PreNotifyInput { [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] add { _preNotifyInput += value; } [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] remove { _preNotifyInput -= value; } } ////// /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This event lets people subscribe to all events in the system /// Not safe to expose. /// PublicOk: Method is link demanded. /// public event NotifyInputEventHandler PostNotifyInput { [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] add { _postNotifyInput += value; } [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] remove { _postNotifyInput -= value; } } ////// /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Critical: This event lets people subscribe to all events in the system /// Not safe to expose. /// PublicOk: Method is link demanded. /// public event ProcessInputEventHandler PostProcessInput { [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] add { _postProcessInput += value; } [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] remove { _postProcessInput -= value; } } ////// This event is raised by the HwndSource.CriticalTranslateAccelerator /// on descendent HwndSource instances. The only subscriber to this event /// is KeyboardNavigation. /// ////// Critical: This event lets people subscribe to all input notifications /// internal event KeyEventHandler TranslateAccelerator { [FriendAccessAllowed] // Used by KeyboardNavigation.cs in Framework [SecurityCritical] add { _translateAccelerator += value; } [FriendAccessAllowed] // Used by KeyboardNavigation.cs in Framework [SecurityCritical] remove { _translateAccelerator -= value; } } ////// Raises the TranslateAccelerator event /// ////// Critical: Accesses critical _translateAccelerator. /// [SecurityCritical] internal void RaiseTranslateAccelerator(KeyEventArgs e) { if (_translateAccelerator != null) { _translateAccelerator(this, e); } } ////// Registers an input provider with the input manager. /// /// /// The input provider to register. /// ////// This class will not be available in internet zone. /// Critical: This code acceses and stores critical data (InputProvider) /// TreatAsSafe: This code demands UIPermission. /// [SecurityCritical] internal InputProviderSite RegisterInputProvider(IInputProvider inputProvider) { SecurityHelper.DemandUnrestrictedUIPermission(); // VerifyAccess(); // Create a site for this provider, and keep track of it. InputProviderSite site = new InputProviderSite(this, inputProvider); _inputProviders[inputProvider] = site; return site; } ////// This class will not be available in internet zone. /// Critical: This code acceses critical data in the form of InputProvider /// [SecurityCritical] internal void UnregisterInputProvider(IInputProvider inputProvider) { _inputProviders.Remove(inputProvider); } ////// Returns a collection of input providers registered with the input manager. /// ////// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// This class will not be available in internet zone. /// Critical: This code exposes InputProviders which are /// considered as critical data /// PublicOK: This code has a demand on it /// public ICollection InputProviders { [SecurityCritical] get { SecurityHelper.DemandUnrestrictedUIPermission(); return UnsecureInputProviders; } } ////// Returns a collection of input providers registered with the input manager. /// ////// Critical: This code exposes InputProviders which are considered as critical data /// This overload exists for perf. improvements in the internet zone since this function is called /// quite often /// internal ICollection UnsecureInputProviders { [SecurityCritical] get { return _inputProviders.Keys; } } ////// Read-only access to the primary keyboard device. /// public KeyboardDevice PrimaryKeyboardDevice { // get {return _primaryKeyboardDevice;} } ////// Read-only access to the primary mouse device. /// public MouseDevice PrimaryMouseDevice { // get {return _primaryMouseDevice;} } ////// Critical, accesses critical member _stylusLogic /// internal StylusLogic StylusLogic { [SecurityCritical, FriendAccessAllowed] get { return _stylusLogic; } } ////// Read-only access to the primary keyboard device. /// internal CommandDevice PrimaryCommandDevice { get {return _primaryCommandDevice;} } ////// The InDragDrop property represents whether we are currently inside /// a OLE DragDrop operation. /// internal bool InDragDrop { get { return _inDragDrop; } set { _inDragDrop = value; } } ////// The MostRecentInputDevice represents the last input device to /// report an "interesting" user action. What exactly constitutes /// such an action is up to each device to implement. /// public InputDevice MostRecentInputDevice { get { return _mostRecentInputDevice; } internal set { _mostRecentInputDevice = value; } } ////// An event that is raised whenever the result of a hit-test may /// have changed. /// public event EventHandler HitTestInvalidatedAsync; internal void NotifyHitTestInvalidated() { // The HitTest result may have changed for someone somewhere. // Raise the HitTestInvalidatedAsync event after the next layout. if(_hitTestInvalidatedAsyncOperation == null) { // It would be best to re-evaluate anything dependent on the hit-test results // immediately after layout & rendering are complete. Unfortunately this can // lead to an infinite loop. Consider the following scenario: // // If the mouse is over an element, hide it. // // This never resolves to a "correct" state. When the mouse moves over the // element, the element is hidden, so the mouse is no longer over it, so the // element is shown, but that means the mouse is over it again. Repeat. // // We push our re-evaluation to a priority lower than input processing so that // the user can change the input device to avoid the infinite loops, or close // the app if nothing else works. // _hitTestInvalidatedAsyncOperation = Dispatcher.BeginInvoke(DispatcherPriority.Input, _hitTestInvalidatedAsyncCallback, null); } else if (_hitTestInvalidatedAsyncOperation.Priority == DispatcherPriority.Inactive) { // This means that we are currently waiting for the timer to expire so // that we can promote the current queue item to Input prority. Since // we are now being told that we need to re-hittest, we simply stop the // timer and promote the queue item right now instead of waiting for expiry. ValidateInputDevices(this, EventArgs.Empty); } } ////// Critical - calls UnsecureCurrent /// TreatAsSafe - notifying the input manager that hit test information needs to be recalced. /// is considered safe ( and currently this code is transparent). /// [SecurityCritical, SecurityTreatAsSafe] internal static void SafeCurrentNotifyHitTestInvalidated() { UnsecureCurrent.NotifyHitTestInvalidated(); } private object HitTestInvalidatedAsyncCallback(object arg) { _hitTestInvalidatedAsyncOperation = null; if (HitTestInvalidatedAsync != null) { HitTestInvalidatedAsync(this, EventArgs.Empty); } return null; } private void OnLayoutUpdated(object sender, EventArgs e) { NotifyHitTestInvalidated(); } ////// Start the timer that will kick off synchronize /// operation on all the input devices upon expiry /// internal void InvalidateInputDevices() { // If there is no pending ansyc hittest operation if (_hitTestInvalidatedAsyncOperation == null) { // Post an inactive item to the queue. When the timer expires // we will promote this queue item to Input priority. _hitTestInvalidatedAsyncOperation = Dispatcher.BeginInvoke(DispatcherPriority.Inactive, _hitTestInvalidatedAsyncCallback, null); // Start the input timer _inputTimer.IsEnabled = true; } } ////// Synchronize the input devices /// private void ValidateInputDevices(object sender, EventArgs e) { Debug.Assert(_hitTestInvalidatedAsyncOperation != null && _hitTestInvalidatedAsyncOperation.Priority == DispatcherPriority.Inactive && _inputTimer.IsEnabled == true); // Promote the pending DispatcherOperation to Input Priority _hitTestInvalidatedAsyncOperation.Priority = DispatcherPriority.Input; // Stop the input timer _inputTimer.IsEnabled = false; } ////// Synchronously processes the specified input. /// ////// The specified input is processed by all of the filters and /// monitors, and is finally dispatched to the appropriate /// element as an input event. /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// ////// Whether or not any event generated as a consequence of this /// event was handled. /// ////// Critical: This code can cause input to be processed. /// PublicOK: This code link demands. /// [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)] public bool ProcessInput(InputEventArgs input) { // VerifyAccess(); if(input == null) { throw new ArgumentNullException("input"); } // Push a marker indicating the portion of the staging area // that needs to be processed. PushMarker(); // Push the input to be processed onto the staging area. PushInput(input, null); // Post a work item to continue processing the staging area // in case someone pushes a dispatcher frame in the middle // of input processing. RequestContinueProcessingStagingArea(); // Now drain the staging area up to the marker we pushed. bool handled = ProcessStagingArea(); return handled; } ////// Critical - accesses critical data ( _stagingArea) /// [SecurityCritical] internal StagingAreaInputItem PushInput(StagingAreaInputItem inputItem) { _stagingArea.Push(inputItem); return inputItem; } ////// Critical - accesses critical function ( PushInput) /// [SecurityCritical] internal StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote) { StagingAreaInputItem item = new StagingAreaInputItem(false); item.Reset(input, promote); return PushInput(item); } ////// Critical - calls a critical function ( PushInput). /// [SecurityCritical] internal StagingAreaInputItem PushMarker() { StagingAreaInputItem item = new StagingAreaInputItem(true); return PushInput(item); } ////// Critical - accesses critical data _stagingArea. /// [SecurityCritical] internal StagingAreaInputItem PopInput() { object input = null; if(_stagingArea.Count > 0) { input = _stagingArea.Pop(); } return input as StagingAreaInputItem; } ////// Critical - accesses the _stagingArea critical data. /// [SecurityCritical] internal StagingAreaInputItem PeekInput() { object input = null; if(_stagingArea.Count > 0) { input = _stagingArea.Peek(); } return input as StagingAreaInputItem; } ////// Critical - accesses critical data ( _stagingArea.Count) and calls a critical function - ProcessStagingArea /// [SecurityCritical ] internal object ContinueProcessingStagingArea(object unused) { _continueProcessingStagingArea = false; // It is possible that we can be re-entered by a nested // dispatcher frame. Continue processing the staging // area if we need to. if(_stagingArea.Count > 0) { // Before we actually start to drain the staging area, we need // to post a work item to process more input. This enables us // to process more input if we enter a nested pump. RequestContinueProcessingStagingArea(); // Now synchronously drain the staging area. ProcessStagingArea(); } return null; } ////// Critical: accesses critical data ( PopInput()) and raises events with the user-initiated flag /// [SecurityCritical] private bool ProcessStagingArea() { bool handled = false; // For performance reasons, try to reuse the input event args. // If we are reentrered, we have to start over with fresh event // args, so we clear the member variables before continuing. // Also, we cannot simply make an single instance of the // PreProcessedInputEventArgs and cast it to NotifyInputEventArgs // or ProcessInputEventArgs because a malicious user could upcast // the object and call inappropriate methods. NotifyInputEventArgs notifyInputEventArgs = (_notifyInputEventArgs != null) ? _notifyInputEventArgs : new NotifyInputEventArgs(); ProcessInputEventArgs processInputEventArgs = (_processInputEventArgs != null) ? _processInputEventArgs : new ProcessInputEventArgs(); PreProcessInputEventArgs preProcessInputEventArgs = (_preProcessInputEventArgs != null) ? _preProcessInputEventArgs : new PreProcessInputEventArgs(); _notifyInputEventArgs = null; _processInputEventArgs = null; _preProcessInputEventArgs = null; // Because we can be reentered, we can't just enumerate over the // staging area - that could throw an exception if the queue // changes underneath us. Instead, just loop until we find a // frame marker or until the staging area is empty. StagingAreaInputItem item = null; while((item = PopInput()) != null) { // If we found a marker, we have reached the end of a // "section" of the staging area. We just return from // the synchronous processing of the staging area. // If a dispatcher frame has been pushed by someone, this // will not return to the original ProcessInput. Instead // it will unwind to the dispatcher and since we have // already pushed a work item to continue processing the // input, it will simply call back into us to do more // processing. At which point we will continue to drain // the staging area. This could cause strage behavior, // but it is deemed more acceptable than stalling input // processing. // if(item.IsMarker) { break; } // Pre-Process the input. This could modify the staging // area, and it could cancel the processing of this // input event. // // Because we use multi-cast delegates, we always have to // create a new multi-cast delegate when we add or remove // a handler. This means we can just call the current // multi-cast delegate instance, and it is safe to iterate // over, even if we get reentered. if (_preProcessInput != null) { preProcessInputEventArgs.Reset(item, this); // Invoke the handlers in reverse order so that handlers that // users add are invoked before handlers in the system. Delegate[] handlers = _preProcessInput.GetInvocationList(); for(int i = (handlers.Length - 1); i >= 0; i--) { PreProcessInputEventHandler handler = (PreProcessInputEventHandler) handlers[i]; handler(this, preProcessInputEventArgs); } } if(!preProcessInputEventArgs.Canceled) { // Pre-Notify the input. // // Because we use multi-cast delegates, we always have to // create a new multi-cast delegate when we add or remove // a handler. This means we can just call the current // multi-cast delegate instance, and it is safe to iterate // over, even if we get reentered. if(_preNotifyInput != null) { notifyInputEventArgs.Reset(item, this); // Invoke the handlers in reverse order so that handlers that // users add are invoked before handlers in the system. Delegate[] handlers = _preNotifyInput.GetInvocationList(); for(int i = (handlers.Length - 1); i >= 0; i--) { NotifyInputEventHandler handler = (NotifyInputEventHandler) handlers[i]; handler(this, notifyInputEventArgs); } } // Raise the input event being processed. InputEventArgs input = item.Input; // Some input events are explicitly associated with // an element. Those that are not are associated with // the target of the input device for this event. DependencyObject eventSource = input.Source as DependencyObject; if(eventSource == null || !InputElement.IsValid(eventSource as IInputElement)) { if (input.Device != null) { eventSource = input.Device.Target as DependencyObject; } } if (eventSource != null) { if(InputElement.IsUIElement(eventSource)) { UIElement e = (UIElement) eventSource; e.RaiseEvent(input, true ); // Call the "trusted" flavor of RaiseEvent. } else if(InputElement.IsContentElement(eventSource)) { ContentElement ce = (ContentElement) eventSource; ce.RaiseEvent(input, true );// Call the "trusted" flavor of RaiseEvent. } else if (InputElement.IsUIElement3D(eventSource)) { UIElement3D e3D = (UIElement3D) eventSource; e3D.RaiseEvent(input, true); // Call the "trusted" flavor of RaiseEvent } } // Post-Notify the input. // // Because we use multi-cast delegates, we always have to // create a new multi-cast delegate when we add or remove // a handler. This means we can just call the current // multi-cast delegate instance, and it is safe to iterate // over, even if we get reentered. if(_postNotifyInput != null) { notifyInputEventArgs.Reset(item, this); // Invoke the handlers in reverse order so that handlers that // users add are invoked before handlers in the system. Delegate[] handlers = _postNotifyInput.GetInvocationList(); for(int i = (handlers.Length - 1); i >= 0; i--) { NotifyInputEventHandler handler = (NotifyInputEventHandler) handlers[i]; handler(this, notifyInputEventArgs); } } // Post-Process the input. This could modify the staging // area. // // Because we use multi-cast delegates, we always have to // create a new multi-cast delegate when we add or remove // a handler. This means we can just call the current // multi-cast delegate instance, and it is safe to iterate // over, even if we get reentered. if(_postProcessInput != null) { processInputEventArgs.Reset(item, this); // Invoke the handlers in reverse order so that handlers that // users add are invoked before handlers in the system. Delegate[] handlers = _postProcessInput.GetInvocationList(); for(int i = (handlers.Length - 1); i >= 0; i--) { ProcessInputEventHandler handler = (ProcessInputEventHandler) handlers[i]; processInputEventArgs.StagingItem.Input.MarkAsUserInitiated(); try { handler(this, processInputEventArgs); } finally // we do this in a finally block in case of exceptions { processInputEventArgs.StagingItem.Input.ClearUserInitiated(); } } // PreviewInputReport --> InputReport if(item.Input.RoutedEvent == InputManager.PreviewInputReportEvent) { if(!item.Input.Handled) { InputReportEventArgs previewInputReport = (InputReportEventArgs) item.Input; InputReportEventArgs inputReport = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report); inputReport.RoutedEvent=InputManager.InputReportEvent; PushInput(inputReport, item); } } } if(input.Handled) { handled = true; } } } // Store our input event args so that we can use them again, and // avoid having to allocate more. _notifyInputEventArgs = notifyInputEventArgs; _processInputEventArgs = processInputEventArgs; _preProcessInputEventArgs = preProcessInputEventArgs; // Make sure to throw away the contents of the event args so // we don't keep refs around to things we don't mean to. _notifyInputEventArgs.Reset(null, null); _processInputEventArgs.Reset(null, null); _preProcessInputEventArgs.Reset(null, null); return handled; } private void RequestContinueProcessingStagingArea() { if(!_continueProcessingStagingArea) { Dispatcher.BeginInvoke(DispatcherPriority.Input, _continueProcessingStagingAreaCallback, null); _continueProcessingStagingArea = true; } } private DispatcherOperationCallback _continueProcessingStagingAreaCallback; private bool _continueProcessingStagingArea; private NotifyInputEventArgs _notifyInputEventArgs; private ProcessInputEventArgs _processInputEventArgs; private PreProcessInputEventArgs _preProcessInputEventArgs; //these four events introduced for secutiy purposes ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event PreProcessInputEventHandler _preProcessInput; ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event NotifyInputEventHandler _preNotifyInput; ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event NotifyInputEventHandler _postNotifyInput; ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event ProcessInputEventHandler _postProcessInput; ////// Critical: This code can be used to spoof input considered critical /// [SecurityCritical] private event KeyEventHandler _translateAccelerator; ////// This table holds critical data not ok to expose /// [SecurityCritical] private Hashtable _inputProviders = new Hashtable(); private KeyboardDevice _primaryKeyboardDevice; private MouseDevice _primaryMouseDevice; private CommandDevice _primaryCommandDevice; ////// Critical to prevent accidental spread to transparent code /// [SecurityCritical] private StylusLogic _stylusLogic; private bool _inDragDrop; private DispatcherOperationCallback _hitTestInvalidatedAsyncCallback; private DispatcherOperation _hitTestInvalidatedAsyncOperation; private EventHandler _layoutUpdatedCallback; ////// Critical: This stack holds all the input events and can be used /// to spoof or force arbitrary input /// [SecurityCritical] private Stack _stagingArea; private InputDevice _mostRecentInputDevice; // Timer used to synchronize the input devices periodically private DispatcherTimer _inputTimer; } } // 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
- NestedContainer.cs
- ComAdminWrapper.cs
- ContainerUIElement3D.cs
- RoleManagerSection.cs
- OdbcException.cs
- IncrementalReadDecoders.cs
- Typography.cs
- CompilerGlobalScopeAttribute.cs
- CompositeDataBoundControl.cs
- MeasureItemEvent.cs
- SafeNativeMemoryHandle.cs
- StylusPointCollection.cs
- CodeIndexerExpression.cs
- WebEventTraceProvider.cs
- WebPartTransformer.cs
- QuaternionValueSerializer.cs
- NumberAction.cs
- DispatcherSynchronizationContext.cs
- LocatorPartList.cs
- QueryActivatableWorkflowsCommand.cs
- FixedSOMPage.cs
- FramingFormat.cs
- TextTreeDeleteContentUndoUnit.cs
- SiteMapNodeCollection.cs
- TraceContextEventArgs.cs
- PropertyChange.cs
- TypedReference.cs
- NameValuePair.cs
- PageThemeBuildProvider.cs
- ScopeElementCollection.cs
- XmlNavigatorFilter.cs
- ComponentConverter.cs
- ExtenderProvidedPropertyAttribute.cs
- ConfigurationProperty.cs
- TextContainerChangedEventArgs.cs
- ReadOnlyDictionary.cs
- CheckBox.cs
- _SecureChannel.cs
- PersonalizationStateQuery.cs
- PropertyDescriptorGridEntry.cs
- GPPOINT.cs
- LockRecursionException.cs
- AutomationPatternInfo.cs
- WSSecurityOneDotZeroSendSecurityHeader.cs
- RelationshipDetailsRow.cs
- DataList.cs
- EventLogInformation.cs
- CustomCredentialPolicy.cs
- oledbmetadatacolumnnames.cs
- TranslateTransform3D.cs
- SpinLock.cs
- _HeaderInfoTable.cs
- CardSpacePolicyElement.cs
- ReadOnlyNameValueCollection.cs
- SqlDeflator.cs
- StrongNameKeyPair.cs
- DesignerTextWriter.cs
- UniformGrid.cs
- PeerCredential.cs
- ToolTipService.cs
- LazyTextWriterCreator.cs
- LinkedDataMemberFieldEditor.cs
- securitycriticaldataformultiplegetandset.cs
- XPathArrayIterator.cs
- ErrorEventArgs.cs
- ObjectComplexPropertyMapping.cs
- PositiveTimeSpanValidatorAttribute.cs
- ResXResourceReader.cs
- DataColumn.cs
- DocumentPageView.cs
- Activator.cs
- ExtenderProvidedPropertyAttribute.cs
- GeneralTransform3DTo2DTo3D.cs
- Buffer.cs
- CopyNamespacesAction.cs
- SectionVisual.cs
- KeyManager.cs
- Freezable.cs
- DataPagerFieldItem.cs
- WebPartExportVerb.cs
- Odbc32.cs
- FileDialog.cs
- EntityClientCacheKey.cs
- VariableAction.cs
- WebPartsPersonalizationAuthorization.cs
- SizeKeyFrameCollection.cs
- ComAdminInterfaces.cs
- SafeReversePInvokeHandle.cs
- OuterGlowBitmapEffect.cs
- EntityDescriptor.cs
- InputLangChangeRequestEvent.cs
- PrintController.cs
- NativeCppClassAttribute.cs
- StringValidator.cs
- RtfToXamlLexer.cs
- UniqueIdentifierService.cs
- WindowsFormsLinkLabel.cs
- SafeNativeMethods.cs
- DefaultValueConverter.cs
- InstancePersistence.cs