Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Interop / ActiveXHost.cs / 1 / ActiveXHost.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // // // // Description: // An ActiveXHost is a System.Windows.FrameworkElement which can // host a windowed ActiveX control. This class provides a technology // bridge between ActiveX controls and Avalon by wrapping ActiveX controls // and exposing them as fully featured avalon elements. It implements both the // container interfaces (via aggregation) required to host the ActiveXControl // and also derives from HwndHost to support hosting an HWND in the avalon tree. // // Currently the activex hosting support is limited to windowed controls. // // Inheritors of this class simply need to concentrate on defining and implementing the // properties/methods/events of the specific ActiveX control they are wrapping, the // default properties etc and the code to implement the activation etc. are // encapsulated in the class below. // // The classid of the ActiveX control is specified in the constructor. // // // History // 04/17/05 KusumaV Created // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Threading; using System.Windows; using System.Windows.Interop; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Markup; using MS.Internal; using MS.Internal.Controls; using MS.Internal.Utility; using MS.Win32; using System.Security; // Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler. // We first need to disable warnings about unknown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 namespace System.Windows.Interop { #region ActiveXHost ////// An ActiveXHost is a Systew.Windows.FrameworkElement which can /// host an ActiveX control. Currently the support is limited to /// windowed controls. This class provides a technology bridge /// between unmanaged ActiveXControls and Avalon framework. /// /// The only reason we expose this class public in ArrowHead without public OM /// is for the WebBrowser control. The WebBrowser class derives from ActiveXHost, and /// we are exposing the WebBrowser class in ArrowHead. This class does not have public /// constructor and OM. It may be enabled in future releases. /// public class ActiveXHost : HwndHost { //----------------------------------------------------- // // Constructors and Finalizers // //----------------------------------------------------- #region Constructors and Finalizers static ActiveXHost() { // We use this map to lookup which invalidator method to call // when the Avalon parent's properties change. invalidatorMap[UIElement.VisibilityProperty] = new PropertyInvalidator(OnVisibilityInvalidated); invalidatorMap[FrameworkElement.IsEnabledProperty] = new PropertyInvalidator(OnIsEnabledInvalidated); // register for access keys EventManager.RegisterClassHandler(typeof(ActiveXHost), AccessKeyManager.AccessKeyPressedEvent, new AccessKeyPressedEventHandler(OnAccessKeyPressed)); Control.IsTabStopProperty.OverrideMetadata(typeof(ActiveXHost), new FrameworkPropertyMetadata(true)); FocusableProperty.OverrideMetadata(typeof(ActiveXHost), new FrameworkPropertyMetadata(true)); EventManager.RegisterClassHandler(typeof(ActiveXHost), Keyboard.GotKeyboardFocusEvent, new KeyboardFocusChangedEventHandler(OnGotFocus)); EventManager.RegisterClassHandler(typeof(ActiveXHost), Keyboard.LostKeyboardFocusEvent, new KeyboardFocusChangedEventHandler(OnLostFocus)); KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(ActiveXHost), new FrameworkPropertyMetadata(KeyboardNavigationMode.Once)); } /// constructor for ActiveXHost ////// Critical - calls trusted HwndHost ctor. /// Takes the clsid to instantiate as input. /// NOT TAS. Individual controls ( like WebOC) can become TAS if they justify why. /// [SecurityCritical] internal ActiveXHost(Guid clsid, bool fTrusted ) : base( fTrusted ) { // Thread.ApartmentState is [Obsolete] #pragma warning disable 0618 // if (Thread.CurrentThread.ApartmentState != ApartmentState.STA) { throw new ThreadStateException(SR.Get(SRID.AxRequiresApartmentThread, clsid.ToString())); } #pragma warning restore 0618 _clsid.Value = clsid; // hookup so we are notified when loading is finished. Initialized += new EventHandler(OnInitialized); } #endregion Constructors and Finalizers //------------------------------------------------------ // // Protected Methods // //----------------------------------------------------- #region Protected Methods #region Framework Related ////// Overriden to push the values of invalidated properties down to our /// ActiveX control. /// protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.IsAValueChange || e.IsASubPropertyChange) { DependencyProperty dp = e.Property; // We lookup the property in our invalidatorMap // and call the appropriate method to push // down the changed value to the hosted ActiveX control. if (dp != null && invalidatorMap.ContainsKey(dp)) { PropertyInvalidator invalidator = (PropertyInvalidator)invalidatorMap[dp]; invalidator(this); } } } ////// Overriden to create our window and parent it. /// ////// Critical - calls methods on critical interface members /// [SecurityCritical ] protected override HandleRef BuildWindowCore(HandleRef hwndParent) { this.ParentHandle = hwndParent; //BuildWindowCore should only be called if visible. Bug 1236445 tracks this. TransitionUpTo(ActiveXHelper.ActiveXState.InPlaceActive); //The above call should have set this interface Invariant.Assert(_axOleInPlaceActiveObject != null, "InPlace activation of ActiveX control failed"); if (ControlHandle.Handle == IntPtr.Zero) { IntPtr inplaceWindow = IntPtr.Zero; _axOleInPlaceActiveObject.GetWindow(out inplaceWindow); AttachWindow(inplaceWindow); } return _axWindow; } ////// Overridden to plug the ActiveX control into Avalon's layout manager. /// ////// Critical - accesses ActiveXSite critical property /// Not making TAS - you may be able to spoof content of web-pages if you could position any arbitrary /// control over a WebOC. /// [ SecurityCritical ] protected override void OnWindowPositionChanged(Rect bounds) { //Its okay to process this if we the control is not yet created _boundRect = bounds; //These are already transformed to client co-ordinate/device units for high dpi also _bounds.left = (int) bounds.X; _bounds.top = (int) bounds.Y; _bounds.right = (int) (bounds.Width + bounds.X); _bounds.bottom = (int) (bounds.Height + bounds.Y); //SetExtent only sets height and width, can call it for perf if X, Y haven't changed //We need to call SetObjectRects instead, which updates X, Y, width and height //OnActiveXRectChange calls SetObjectRects this.ActiveXSite.OnActiveXRectChange(_bounds); } ////// Derived classes override this method to actually build the /// window being hosted. /// protected override void DestroyWindowCore(HandleRef hwnd) { } ////// Overridden to plug the ActiveX control into Avalon's layout manager. /// protected override Size MeasureOverride(Size swConstraint) { base.MeasureOverride(swConstraint); double newWidth, newHeight; if (Double.IsPositiveInfinity(swConstraint.Width)) newWidth = 150; else newWidth = swConstraint.Width; if (Double.IsPositiveInfinity(swConstraint.Height)) newHeight = 150; else newHeight = swConstraint.Height; return new Size(newWidth, newHeight); } ////// Forward the access key to our hosted ActiveX control /// protected override void OnAccessKey(AccessKeyEventArgs args) { Debug.Assert(args.Key.Length > 0, "got an empty access key"); // } #endregion Framework Related #region ActiveX Related protected override void Dispose(bool disposing) { try { if ((disposing) && (!_isDisposed)) { TransitionDownTo(ActiveXHelper.ActiveXState.Passive); _isDisposed = true; } } finally { //This destroys the parent window, so call base after we have done our processing. base.Dispose(disposing); } } // The native ActiveX control QI's for interfaces on it's site to see if // it needs to change it's behaviour. Since the AxSite class is generic, // it only implements site interfaces that are generic to all sites. QI's // for any more specific interfaces will fail. This is a problem if anyone // wants to support any other interfaces on the site. In order to overcome // this, one needs to extend AxSite and implement any additional interfaces // needed. // // ActiveX wrapper controls that derive from this class should override the // below method and return their own AxSite derived object. // // This method is protected by an InheritanceDemand (from HwndSource) and // a LinkDemand because extending a site is strictly an advanced feature for // which one needs UnmanagedCode permissions. // /// Returns an object that will be set as the site for the native ActiveX control. /// Implementors of the site can derive from ActiveXSite class. ////// Critical - calls critical ctor. /// [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] [SecurityCritical] internal virtual ActiveXSite CreateActiveXSite() { return new ActiveXSite(this); } [SecurityCritical] internal virtual object CreateActiveXObject(Guid clsid) { return UnsafeNativeMethods.CoCreateInstance(ref clsid, null, NativeMethods.CLSCTX_INPROC_SERVER, ref NativeMethods.IID_IUnknown); } /// This will be called when the native ActiveX control has just been created. /// Inheritors of this class can override this method to cast the nativeActiveXObject /// parameter to the appropriate interface. They can then cache this interface /// value in a member variable. However, they must release this value when /// DetachInterfaces is called (by setting the cached interface variable to null). internal virtual void AttachInterfaces(object nativeActiveXObject) { } /// See AttachInterfaces for a description of when to override DetachInterfaces. internal virtual void DetachInterfaces() { } /// This will be called when we are ready to start listening to events. /// Inheritors can override this method to hook their own connection points. internal virtual void CreateSink() { } ////// This will be called when it is time to stop listening to events. /// This is where inheritors have to disconnect their connection points. /// ////// Critical: Potentially unsafe. For example, disconnecting the event sink breaks the site-locking /// feature of the WebBrowser control. /// [SecurityCritical] internal virtual void DetachSink() { } ////// Called whenever the ActiveX state changes. Subclasses can do additional hookup/cleanup depending /// on the state transitions /// /// /// internal virtual void OnActiveXStateChange(int oldState, int newState) { } #endregion ActiveX Related #endregion Protected Methods //------------------------------------------------------ // // Protected Properties // //------------------------------------------------------ #region Protected Properties protected bool IsDisposed { get { return _isDisposed; } } #endregion Protected Properties //----------------------------------------------------- // // Internal Methods // //------------------------------------------------------ #region Internal Methods #region ActiveX Related /// This method needs to be called by the user of ActiveXHost for each /// hosted ActiveX control that has a mnemonic bound to it internal void RegisterAccessKey(char key) { AccessKeyManager.Register(key.ToString(), this); } ////// Critical - exposes critical _axSite member. /// LinkDemand added, since without it, this property would make the LinkDemand on CreateActiveXSite meaningless. /// internal ActiveXSite ActiveXSite { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] [SecurityCritical] get { if (_axSite == null) { _axSite = CreateActiveXSite(); } return _axSite; } } ////// Critical - exposes critical _axContainer member. /// internal ActiveXContainer Container { [SecurityCritical] get { if (_axContainer == null) { _axContainer = new ActiveXContainer(this); } return _axContainer; } } internal ActiveXHelper.ActiveXState ActiveXState { get { return _axState; } set { _axState = value; } } internal bool GetAxHostState(int mask) { return _axHostState[mask]; } internal void SetAxHostState(int mask, bool value) { _axHostState[mask] = value; } internal void TransitionUpTo(ActiveXHelper.ActiveXState state) { if (!this.GetAxHostState(ActiveXHelper.inTransition)) { this.SetAxHostState(ActiveXHelper.inTransition, true); try { ActiveXHelper.ActiveXState oldState; while (state > this.ActiveXState) { oldState = this.ActiveXState; switch (this.ActiveXState) { case ActiveXHelper.ActiveXState.Passive: TransitionFromPassiveToLoaded(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; break; case ActiveXHelper.ActiveXState.Loaded: TransitionFromLoadedToRunning(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Running; break; case ActiveXHelper.ActiveXState.Running: TransitionFromRunningToInPlaceActive(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive; break; case ActiveXHelper.ActiveXState.InPlaceActive: TransitionFromInPlaceActiveToUIActive(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.UIActive, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.UIActive; break; default: Debug.Fail("bad state"); this.ActiveXState = this.ActiveXState + 1; // To exit the loop break; } OnActiveXStateChange((int)oldState, (int)this.ActiveXState); } } finally { this.SetAxHostState(ActiveXHelper.inTransition, false); } } } internal void TransitionDownTo(ActiveXHelper.ActiveXState state) { if (!this.GetAxHostState(ActiveXHelper.inTransition)) { this.SetAxHostState(ActiveXHelper.inTransition, true); try { ActiveXHelper.ActiveXState oldState; while (state < this.ActiveXState) { oldState = this.ActiveXState; switch (this.ActiveXState) { case ActiveXHelper.ActiveXState.Open: Debug.Fail("how did we ever get into the open state?"); this.ActiveXState = ActiveXHelper.ActiveXState.UIActive; break; case ActiveXHelper.ActiveXState.UIActive: TransitionFromUIActiveToInPlaceActive(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive; break; case ActiveXHelper.ActiveXState.InPlaceActive: TransitionFromInPlaceActiveToRunning(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Running; break; case ActiveXHelper.ActiveXState.Running: TransitionFromRunningToLoaded(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; break; case ActiveXHelper.ActiveXState.Loaded: TransitionFromLoadedToPassive(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Passive, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Passive; break; default: Debug.Fail("bad state"); this.ActiveXState = this.ActiveXState - 1; // To exit the loop break; } OnActiveXStateChange((int)oldState, (int)this.ActiveXState); } } finally { this.SetAxHostState(ActiveXHelper.inTransition, false); } } } ////// Critical - runs arbitrary code on critical _axOleObject member. /// [SecurityCritical] internal bool DoVerb(int verb) { int hr = _axOleObject.DoVerb(verb, IntPtr.Zero, this.ActiveXSite, 0, this.ParentHandle.Handle, _bounds); Debug.Assert(hr == NativeMethods.S_OK, String.Format("DoVerb call failed for verb 0x{0:X}", verb)); return hr == NativeMethods.S_OK; } ////// Critical - Calls setParent, accesses _axWindow. /// [SecurityCritical] internal void AttachWindow(IntPtr hwnd) { if (_axWindow.Handle == hwnd) return; // _axWindow = new HandleRef(this, hwnd); if (this.ParentHandle.Handle != IntPtr.Zero) { UnsafeNativeMethods.SetParent(_axWindow, this.ParentHandle); } } ////// Critical - calls ActiveXSite.StartEvents - critical code. /// [ SecurityCritical ] private void StartEvents() { if (!this.GetAxHostState(ActiveXHelper.sinkAttached)) { this.SetAxHostState(ActiveXHelper.sinkAttached, true); CreateSink(); } this.ActiveXSite.StartEvents(); } ////// Critical - calls ActiveXSite.StopEvents - critical code. /// NOT TAS: if you can stop listening to events - you could /// potentially turn off a mitigation. On the WebOC this could /// stop site-locking mitigation. /// [ SecurityCritical ] private void StopEvents() { if (this.GetAxHostState(ActiveXHelper.sinkAttached)) { this.SetAxHostState(ActiveXHelper.sinkAttached, false); DetachSink(); } this.ActiveXSite.StopEvents(); } ////// Critical - Calls critical code ( CoCreateInstance) calls critical interface members, _axInstance /// TreatAsSafe - although this method instantiates the control. /// considered safe as the parameter that controls what to instantiate is critical for set. /// and set only via the critical CTOR. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromPassiveToLoaded() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Passive, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Passive) { // // First, create the ActiveX control Debug.Assert(_axInstance == null, "_axInstance must be null"); _axInstance = CreateActiveXObject(_clsid.Value); Debug.Assert(_axInstance != null, "w/o an exception being thrown we must have an object..."); // // We are now Loaded! this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; // // Lets give them a chance to cast the ActiveX object // to the appropriate interfaces. this.AttachInterfacesInternal(); } } ////// Critical - accesses critical interface members, _axInstance /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromLoadedToPassive() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Loaded) { // // Need to make sure that we don't handle any PropertyChanged // notifications at this point. //this.NoComponentChangeEvents++; try { // // Release the _axInstance if (_axInstance != null) { // // Lets first get the cached interface pointers of _axInstance released. this.DetachInterfacesInternal(); Marshal.FinalReleaseComObject(_axInstance); _axInstance = null; } } finally { // } // // We are now Passive! this.ActiveXState = ActiveXHelper.ActiveXState.Passive; } } ////// Critical - calls critical code - SetClientSite. /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromLoadedToRunning() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Loaded) { // // See if the ActiveX control returns OLEMISC_SETCLIENTSITEFIRST int bits = 0; int hr = _axOleObject.GetMiscStatus(NativeMethods.DVASPECT_CONTENT, out bits); if (NativeMethods.Succeeded(hr) && ((bits & NativeMethods.OLEMISC_SETCLIENTSITEFIRST) != 0)) { // // Simply setting the site to the ActiveX control should activate it. // And this will take us to the Running state. _axOleObject.SetClientSite(this.ActiveXSite); } StartEvents(); // // We are now Running! this.ActiveXState = ActiveXHelper.ActiveXState.Running; } } ////// Critical - accesses critical code, _axOleOlebject, StopEvents /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromRunningToLoaded() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Running) { StopEvents(); // // Inform the ActiveX control that it's been un-sited. _axOleObject.SetClientSite(null); // // We are now Loaded! this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; } } ////// Critical - calls critical code - DoVerb. /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromRunningToInPlaceActive() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Running) { try { DoVerb(NativeMethods.OLEIVERB_INPLACEACTIVATE); } catch (Exception e) { if(CriticalExceptions.IsCriticalException(e)) { throw; } else { throw new TargetInvocationException(SR.Get(SRID.AXNohWnd, GetType().Name), e); } } // // We are now InPlaceActive! this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive; } } ////// Critical - calls critical code - InPlaceDeactivate. /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromInPlaceActiveToRunning() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive) { // // InPlaceDeactivate. _axOleInPlaceObject.InPlaceDeactivate(); // // We are now Running! this.ActiveXState = ActiveXHelper.ActiveXState.Running; } } ////// Critical - calls critical code - DoVerb. /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromInPlaceActiveToUIActive() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive) { DoVerb(NativeMethods.OLEIVERB_UIACTIVATE); // // We are now UIActive! this.ActiveXState = ActiveXHelper.ActiveXState.UIActive; } } ////// Critical - accesses critical interface members, _axOleInPlaceObject /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromUIActiveToInPlaceActive() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.UIActive, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.UIActive) { int hr = _axOleInPlaceObject.UIDeactivate(); Debug.Assert(NativeMethods.Succeeded(hr), "Failed in IOleInPlaceObject.UiDeactivate"); // // We are now InPlaceActive! this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive; } } #endregion ActiveX Related #endregion Internal Methods //----------------------------------------------------- // // Internal Properties // //----------------------------------------------------- #region Internal Properties #region Framework Related ////// The DependencyProperty for the TabIndex property. /// Flags: Can be used in style rules /// Default Value: 1 /// internal static readonly DependencyProperty TabIndexProperty = Control.TabIndexProperty.AddOwner(typeof(ActiveXHost)); ////// TabIndex property change the order of Tab navigation between Controls. /// Control with lower TabIndex will get focus before the Control with higher index /// internal int TabIndex { get { return (int) GetValue(TabIndexProperty); } set { SetValue(TabIndexProperty, value); } } ////// Critical - accesses _hwndParent critical member. /// internal HandleRef ParentHandle { [ SecurityCritical ] get { return _hwndParent; } [ SecurityCritical ] set { _hwndParent = value; } } // This returns a COMRECT. internal NativeMethods.COMRECT Bounds { get { return _bounds; } //How do we notify Avalon tree/layout that the control needs a new size? set { _bounds = value; } } // This returns a Rect. internal Rect BoundRect { get { return _boundRect; } } #endregion Framework Related #region ActiveX Related ////// Returns the hosted ActiveX control's handle /// ////// Critical - returns critical _axWindow member /// internal HandleRef ControlHandle { [ SecurityCritical ] get { return _axWindow; } } //////Returns the native webbrowser object that this control wraps. Needs FullTrust to access. /// Internally we will access the private field directly for perf reasons, no security checks /// ////// Critical - returns critical Instance member. /// internal object ActiveXInstance { [ SecurityCritical ] get { return _axInstance; } } ////// Critical - returns critical Instance member. /// internal UnsafeNativeMethods.IOleInPlaceObject ActiveXInPlaceObject { [ SecurityCritical ] get { return _axOleInPlaceObject; } } ////// Critical - returns critical Instance member. /// internal UnsafeNativeMethods.IOleInPlaceActiveObject ActiveXInPlaceActiveObject { [SecurityCritical] get { return _axOleInPlaceActiveObject; } } #endregion ActiveXRelated #endregion Internal Properties //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods #region Framework Methods private void OnInitialized(object sender, EventArgs e) { // this.Initialized -= new EventHandler(this.OnInitialized); //Cannot inplace activate yet, since BuildWindowCore is not called yet //and we need that for getting the parent handle to pass on to the control. } private static void OnIsEnabledInvalidated(ActiveXHost axHost) { // } private static void OnVisibilityInvalidated(ActiveXHost axHost) { if (axHost != null) { switch (axHost.Visibility) { case Visibility.Visible: // break; case Visibility.Collapsed: // break; case Visibility.Hidden: // break; } } } /// This event handler forwards focus events to the hosted ActiveX control private static void OnGotFocus(object sender, KeyboardFocusChangedEventArgs e) { ActiveXHost axhost = sender as ActiveXHost; if (axhost != null) { Invariant.Assert(axhost.ActiveXState >= ActiveXHelper.ActiveXState.InPlaceActive, "Should at least be InPlaceActive when getting focus"); if (axhost.ActiveXState < ActiveXHelper.ActiveXState.UIActive) { axhost.TransitionUpTo(ActiveXHelper.ActiveXState.UIActive); } } } /// This event handler forwards focus events to the hosted WF controls private static void OnLostFocus(object sender, KeyboardFocusChangedEventArgs e) { ActiveXHost axhost = sender as ActiveXHost; if (axhost != null) { // If the focus goes from our control window to one of the child windows, // we should not deactivate. // Invariant.Assert(axhost.ActiveXState >= ActiveXHelper.ActiveXState.UIActive, "Should at least be UIActive when losing focus"); bool uiDeactivate = !axhost.IsKeyboardFocusWithin; if (uiDeactivate) { axhost.TransitionDownTo(ActiveXHelper.ActiveXState.InPlaceActive); } } } private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs args) { if (!args.Handled && args.Scope == null && args.Target == null) { args.Target = (UIElement)sender; } } /* private void GetMnemonicList(SWF.Control control, ArrayList mnemonicList) { // Get the mnemonic for our control // char mnemonic = HostUtils.GetMnemonic(control.Text, true); if (mnemonic != 0) { mnemonicList.Add(mnemonic); } // And recurse for our children, currently we only support one activex control // if (HostedControl != null) GetMnemonicList(HostedControl, mnemonicList); } */ #endregion Framework Methods #region ActiveX Related ////// Critical - accesses critical interface pointers. /// [ SecurityCritical ] private void AttachInterfacesInternal() { Debug.Assert(_axInstance != null, "The native control is null"); _axOleObject = (UnsafeNativeMethods.IOleObject)_axInstance; _axOleInPlaceObject = (UnsafeNativeMethods.IOleInPlaceObject)_axInstance; _axOleInPlaceActiveObject = (UnsafeNativeMethods.IOleInPlaceActiveObject)_axInstance; // // Lets give the inheriting classes a chance to cast // the ActiveX object to the appropriate interfaces. AttachInterfaces(_axInstance); } ////// Critical - accesses critical interface members. /// TreatAsSafe - clearing the interfaces is ok. /// [ SecurityCritical, SecurityTreatAsSafe ] private void DetachInterfacesInternal() { _axOleObject = null; _axOleInPlaceObject = null; _axOleInPlaceActiveObject = null; // // Lets give the inheriting classes a chance to release // their cached interfaces of the ActiveX object. DetachInterfaces(); } ////// Critical - calls calls critical interface members. /// [ SecurityCritical ] private NativeMethods.SIZE SetExtent(int width, int height) { NativeMethods.SIZE sz = new NativeMethods.SIZE(); sz.cx = width; sz.cy = height; bool resetExtents = false; try { _axOleObject.SetExtent(NativeMethods.DVASPECT_CONTENT, sz); } catch (COMException) { resetExtents = true; } if (resetExtents) { _axOleObject.GetExtent(NativeMethods.DVASPECT_CONTENT, sz); try { _axOleObject.SetExtent(NativeMethods.DVASPECT_CONTENT, sz); } catch (COMException e) { Debug.Fail(e.ToString()); } } return GetExtent(); } ////// Critical - accesses critical interface member _axOleObject /// TreatAsSafe - getting the size of the control is considered ok. /// [ SecurityCritical, SecurityTreatAsSafe ] private NativeMethods.SIZE GetExtent() { NativeMethods.SIZE sz = new NativeMethods.SIZE(); _axOleObject.GetExtent(NativeMethods.DVASPECT_CONTENT, sz); return sz; } #endregion ActiveX Related #endregion Private Methods //----------------------------------------------------- // // Private Properties // //------------------------------------------------------ #region Private Properties #endregion Private Properties //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- #region Private Fields #region Framework Related private static Hashtable invalidatorMap = new Hashtable(); private delegate void PropertyInvalidator(ActiveXHost axhost); private NativeMethods.COMRECT _bounds = new NativeMethods.COMRECT(0, 0, 0, 0); private Rect _boundRect = new Rect(0, 0, 0, 0); private Size _cachedSize = Size.Empty; ////// Critical - _hwndParent considered critical. /// [SecurityCritical ] private HandleRef _hwndParent; private bool _isDisposed; #endregion Framework Related #region ActiveX Related ////// Critical - _clsId controls what code to run and instantiate. /// private SecurityCriticalDataForSet_clsid; /// /// Critical - hwnd of control /// [ SecurityCritical ] private HandleRef _axWindow; private BitVector32 _axHostState = new BitVector32(); private ActiveXHelper.ActiveXState _axState = ActiveXHelper.ActiveXState.Passive; ////// Critical - ActiveXSite interfaces of control /// [ SecurityCritical ] private ActiveXSite _axSite; ////// Critical - ActiveXContainer of control /// [ SecurityCritical ] private ActiveXContainer _axContainer; ////// Critical - all methods on this Interface are critical /// [SecurityCritical] private object _axInstance; // Pointers to the ActiveX object: Interface pointers are cached for perf. ////// Critical - all methods on this Interface are critical /// [SecurityCritical] private UnsafeNativeMethods.IOleObject _axOleObject; ////// Critical - all methods on this Interface are critical /// [SecurityCritical] private UnsafeNativeMethods.IOleInPlaceObject _axOleInPlaceObject; ////// Critical - all methods on this Interface are critical /// [SecurityCritical] private UnsafeNativeMethods.IOleInPlaceActiveObject _axOleInPlaceActiveObject; #endregion ActiveX Related #endregion Private Fields } #endregion ActiveXHost } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // // // // Description: // An ActiveXHost is a System.Windows.FrameworkElement which can // host a windowed ActiveX control. This class provides a technology // bridge between ActiveX controls and Avalon by wrapping ActiveX controls // and exposing them as fully featured avalon elements. It implements both the // container interfaces (via aggregation) required to host the ActiveXControl // and also derives from HwndHost to support hosting an HWND in the avalon tree. // // Currently the activex hosting support is limited to windowed controls. // // Inheritors of this class simply need to concentrate on defining and implementing the // properties/methods/events of the specific ActiveX control they are wrapping, the // default properties etc and the code to implement the activation etc. are // encapsulated in the class below. // // The classid of the ActiveX control is specified in the constructor. // // // History // 04/17/05 KusumaV Created // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Threading; using System.Windows; using System.Windows.Interop; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Markup; using MS.Internal; using MS.Internal.Controls; using MS.Internal.Utility; using MS.Win32; using System.Security; // Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler. // We first need to disable warnings about unknown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 namespace System.Windows.Interop { #region ActiveXHost ////// An ActiveXHost is a Systew.Windows.FrameworkElement which can /// host an ActiveX control. Currently the support is limited to /// windowed controls. This class provides a technology bridge /// between unmanaged ActiveXControls and Avalon framework. /// /// The only reason we expose this class public in ArrowHead without public OM /// is for the WebBrowser control. The WebBrowser class derives from ActiveXHost, and /// we are exposing the WebBrowser class in ArrowHead. This class does not have public /// constructor and OM. It may be enabled in future releases. /// public class ActiveXHost : HwndHost { //----------------------------------------------------- // // Constructors and Finalizers // //----------------------------------------------------- #region Constructors and Finalizers static ActiveXHost() { // We use this map to lookup which invalidator method to call // when the Avalon parent's properties change. invalidatorMap[UIElement.VisibilityProperty] = new PropertyInvalidator(OnVisibilityInvalidated); invalidatorMap[FrameworkElement.IsEnabledProperty] = new PropertyInvalidator(OnIsEnabledInvalidated); // register for access keys EventManager.RegisterClassHandler(typeof(ActiveXHost), AccessKeyManager.AccessKeyPressedEvent, new AccessKeyPressedEventHandler(OnAccessKeyPressed)); Control.IsTabStopProperty.OverrideMetadata(typeof(ActiveXHost), new FrameworkPropertyMetadata(true)); FocusableProperty.OverrideMetadata(typeof(ActiveXHost), new FrameworkPropertyMetadata(true)); EventManager.RegisterClassHandler(typeof(ActiveXHost), Keyboard.GotKeyboardFocusEvent, new KeyboardFocusChangedEventHandler(OnGotFocus)); EventManager.RegisterClassHandler(typeof(ActiveXHost), Keyboard.LostKeyboardFocusEvent, new KeyboardFocusChangedEventHandler(OnLostFocus)); KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(ActiveXHost), new FrameworkPropertyMetadata(KeyboardNavigationMode.Once)); } /// constructor for ActiveXHost ////// Critical - calls trusted HwndHost ctor. /// Takes the clsid to instantiate as input. /// NOT TAS. Individual controls ( like WebOC) can become TAS if they justify why. /// [SecurityCritical] internal ActiveXHost(Guid clsid, bool fTrusted ) : base( fTrusted ) { // Thread.ApartmentState is [Obsolete] #pragma warning disable 0618 // if (Thread.CurrentThread.ApartmentState != ApartmentState.STA) { throw new ThreadStateException(SR.Get(SRID.AxRequiresApartmentThread, clsid.ToString())); } #pragma warning restore 0618 _clsid.Value = clsid; // hookup so we are notified when loading is finished. Initialized += new EventHandler(OnInitialized); } #endregion Constructors and Finalizers //------------------------------------------------------ // // Protected Methods // //----------------------------------------------------- #region Protected Methods #region Framework Related ////// Overriden to push the values of invalidated properties down to our /// ActiveX control. /// protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.IsAValueChange || e.IsASubPropertyChange) { DependencyProperty dp = e.Property; // We lookup the property in our invalidatorMap // and call the appropriate method to push // down the changed value to the hosted ActiveX control. if (dp != null && invalidatorMap.ContainsKey(dp)) { PropertyInvalidator invalidator = (PropertyInvalidator)invalidatorMap[dp]; invalidator(this); } } } ////// Overriden to create our window and parent it. /// ////// Critical - calls methods on critical interface members /// [SecurityCritical ] protected override HandleRef BuildWindowCore(HandleRef hwndParent) { this.ParentHandle = hwndParent; //BuildWindowCore should only be called if visible. Bug 1236445 tracks this. TransitionUpTo(ActiveXHelper.ActiveXState.InPlaceActive); //The above call should have set this interface Invariant.Assert(_axOleInPlaceActiveObject != null, "InPlace activation of ActiveX control failed"); if (ControlHandle.Handle == IntPtr.Zero) { IntPtr inplaceWindow = IntPtr.Zero; _axOleInPlaceActiveObject.GetWindow(out inplaceWindow); AttachWindow(inplaceWindow); } return _axWindow; } ////// Overridden to plug the ActiveX control into Avalon's layout manager. /// ////// Critical - accesses ActiveXSite critical property /// Not making TAS - you may be able to spoof content of web-pages if you could position any arbitrary /// control over a WebOC. /// [ SecurityCritical ] protected override void OnWindowPositionChanged(Rect bounds) { //Its okay to process this if we the control is not yet created _boundRect = bounds; //These are already transformed to client co-ordinate/device units for high dpi also _bounds.left = (int) bounds.X; _bounds.top = (int) bounds.Y; _bounds.right = (int) (bounds.Width + bounds.X); _bounds.bottom = (int) (bounds.Height + bounds.Y); //SetExtent only sets height and width, can call it for perf if X, Y haven't changed //We need to call SetObjectRects instead, which updates X, Y, width and height //OnActiveXRectChange calls SetObjectRects this.ActiveXSite.OnActiveXRectChange(_bounds); } ////// Derived classes override this method to actually build the /// window being hosted. /// protected override void DestroyWindowCore(HandleRef hwnd) { } ////// Overridden to plug the ActiveX control into Avalon's layout manager. /// protected override Size MeasureOverride(Size swConstraint) { base.MeasureOverride(swConstraint); double newWidth, newHeight; if (Double.IsPositiveInfinity(swConstraint.Width)) newWidth = 150; else newWidth = swConstraint.Width; if (Double.IsPositiveInfinity(swConstraint.Height)) newHeight = 150; else newHeight = swConstraint.Height; return new Size(newWidth, newHeight); } ////// Forward the access key to our hosted ActiveX control /// protected override void OnAccessKey(AccessKeyEventArgs args) { Debug.Assert(args.Key.Length > 0, "got an empty access key"); // } #endregion Framework Related #region ActiveX Related protected override void Dispose(bool disposing) { try { if ((disposing) && (!_isDisposed)) { TransitionDownTo(ActiveXHelper.ActiveXState.Passive); _isDisposed = true; } } finally { //This destroys the parent window, so call base after we have done our processing. base.Dispose(disposing); } } // The native ActiveX control QI's for interfaces on it's site to see if // it needs to change it's behaviour. Since the AxSite class is generic, // it only implements site interfaces that are generic to all sites. QI's // for any more specific interfaces will fail. This is a problem if anyone // wants to support any other interfaces on the site. In order to overcome // this, one needs to extend AxSite and implement any additional interfaces // needed. // // ActiveX wrapper controls that derive from this class should override the // below method and return their own AxSite derived object. // // This method is protected by an InheritanceDemand (from HwndSource) and // a LinkDemand because extending a site is strictly an advanced feature for // which one needs UnmanagedCode permissions. // /// Returns an object that will be set as the site for the native ActiveX control. /// Implementors of the site can derive from ActiveXSite class. ////// Critical - calls critical ctor. /// [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] [SecurityCritical] internal virtual ActiveXSite CreateActiveXSite() { return new ActiveXSite(this); } [SecurityCritical] internal virtual object CreateActiveXObject(Guid clsid) { return UnsafeNativeMethods.CoCreateInstance(ref clsid, null, NativeMethods.CLSCTX_INPROC_SERVER, ref NativeMethods.IID_IUnknown); } /// This will be called when the native ActiveX control has just been created. /// Inheritors of this class can override this method to cast the nativeActiveXObject /// parameter to the appropriate interface. They can then cache this interface /// value in a member variable. However, they must release this value when /// DetachInterfaces is called (by setting the cached interface variable to null). internal virtual void AttachInterfaces(object nativeActiveXObject) { } /// See AttachInterfaces for a description of when to override DetachInterfaces. internal virtual void DetachInterfaces() { } /// This will be called when we are ready to start listening to events. /// Inheritors can override this method to hook their own connection points. internal virtual void CreateSink() { } ////// This will be called when it is time to stop listening to events. /// This is where inheritors have to disconnect their connection points. /// ////// Critical: Potentially unsafe. For example, disconnecting the event sink breaks the site-locking /// feature of the WebBrowser control. /// [SecurityCritical] internal virtual void DetachSink() { } ////// Called whenever the ActiveX state changes. Subclasses can do additional hookup/cleanup depending /// on the state transitions /// /// /// internal virtual void OnActiveXStateChange(int oldState, int newState) { } #endregion ActiveX Related #endregion Protected Methods //------------------------------------------------------ // // Protected Properties // //------------------------------------------------------ #region Protected Properties protected bool IsDisposed { get { return _isDisposed; } } #endregion Protected Properties //----------------------------------------------------- // // Internal Methods // //------------------------------------------------------ #region Internal Methods #region ActiveX Related /// This method needs to be called by the user of ActiveXHost for each /// hosted ActiveX control that has a mnemonic bound to it internal void RegisterAccessKey(char key) { AccessKeyManager.Register(key.ToString(), this); } ////// Critical - exposes critical _axSite member. /// LinkDemand added, since without it, this property would make the LinkDemand on CreateActiveXSite meaningless. /// internal ActiveXSite ActiveXSite { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] [SecurityCritical] get { if (_axSite == null) { _axSite = CreateActiveXSite(); } return _axSite; } } ////// Critical - exposes critical _axContainer member. /// internal ActiveXContainer Container { [SecurityCritical] get { if (_axContainer == null) { _axContainer = new ActiveXContainer(this); } return _axContainer; } } internal ActiveXHelper.ActiveXState ActiveXState { get { return _axState; } set { _axState = value; } } internal bool GetAxHostState(int mask) { return _axHostState[mask]; } internal void SetAxHostState(int mask, bool value) { _axHostState[mask] = value; } internal void TransitionUpTo(ActiveXHelper.ActiveXState state) { if (!this.GetAxHostState(ActiveXHelper.inTransition)) { this.SetAxHostState(ActiveXHelper.inTransition, true); try { ActiveXHelper.ActiveXState oldState; while (state > this.ActiveXState) { oldState = this.ActiveXState; switch (this.ActiveXState) { case ActiveXHelper.ActiveXState.Passive: TransitionFromPassiveToLoaded(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; break; case ActiveXHelper.ActiveXState.Loaded: TransitionFromLoadedToRunning(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Running; break; case ActiveXHelper.ActiveXState.Running: TransitionFromRunningToInPlaceActive(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive; break; case ActiveXHelper.ActiveXState.InPlaceActive: TransitionFromInPlaceActiveToUIActive(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.UIActive, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.UIActive; break; default: Debug.Fail("bad state"); this.ActiveXState = this.ActiveXState + 1; // To exit the loop break; } OnActiveXStateChange((int)oldState, (int)this.ActiveXState); } } finally { this.SetAxHostState(ActiveXHelper.inTransition, false); } } } internal void TransitionDownTo(ActiveXHelper.ActiveXState state) { if (!this.GetAxHostState(ActiveXHelper.inTransition)) { this.SetAxHostState(ActiveXHelper.inTransition, true); try { ActiveXHelper.ActiveXState oldState; while (state < this.ActiveXState) { oldState = this.ActiveXState; switch (this.ActiveXState) { case ActiveXHelper.ActiveXState.Open: Debug.Fail("how did we ever get into the open state?"); this.ActiveXState = ActiveXHelper.ActiveXState.UIActive; break; case ActiveXHelper.ActiveXState.UIActive: TransitionFromUIActiveToInPlaceActive(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive; break; case ActiveXHelper.ActiveXState.InPlaceActive: TransitionFromInPlaceActiveToRunning(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Running; break; case ActiveXHelper.ActiveXState.Running: TransitionFromRunningToLoaded(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; break; case ActiveXHelper.ActiveXState.Loaded: TransitionFromLoadedToPassive(); Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Passive, "Failed transition"); this.ActiveXState = ActiveXHelper.ActiveXState.Passive; break; default: Debug.Fail("bad state"); this.ActiveXState = this.ActiveXState - 1; // To exit the loop break; } OnActiveXStateChange((int)oldState, (int)this.ActiveXState); } } finally { this.SetAxHostState(ActiveXHelper.inTransition, false); } } } ////// Critical - runs arbitrary code on critical _axOleObject member. /// [SecurityCritical] internal bool DoVerb(int verb) { int hr = _axOleObject.DoVerb(verb, IntPtr.Zero, this.ActiveXSite, 0, this.ParentHandle.Handle, _bounds); Debug.Assert(hr == NativeMethods.S_OK, String.Format("DoVerb call failed for verb 0x{0:X}", verb)); return hr == NativeMethods.S_OK; } ////// Critical - Calls setParent, accesses _axWindow. /// [SecurityCritical] internal void AttachWindow(IntPtr hwnd) { if (_axWindow.Handle == hwnd) return; // _axWindow = new HandleRef(this, hwnd); if (this.ParentHandle.Handle != IntPtr.Zero) { UnsafeNativeMethods.SetParent(_axWindow, this.ParentHandle); } } ////// Critical - calls ActiveXSite.StartEvents - critical code. /// [ SecurityCritical ] private void StartEvents() { if (!this.GetAxHostState(ActiveXHelper.sinkAttached)) { this.SetAxHostState(ActiveXHelper.sinkAttached, true); CreateSink(); } this.ActiveXSite.StartEvents(); } ////// Critical - calls ActiveXSite.StopEvents - critical code. /// NOT TAS: if you can stop listening to events - you could /// potentially turn off a mitigation. On the WebOC this could /// stop site-locking mitigation. /// [ SecurityCritical ] private void StopEvents() { if (this.GetAxHostState(ActiveXHelper.sinkAttached)) { this.SetAxHostState(ActiveXHelper.sinkAttached, false); DetachSink(); } this.ActiveXSite.StopEvents(); } ////// Critical - Calls critical code ( CoCreateInstance) calls critical interface members, _axInstance /// TreatAsSafe - although this method instantiates the control. /// considered safe as the parameter that controls what to instantiate is critical for set. /// and set only via the critical CTOR. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromPassiveToLoaded() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Passive, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Passive) { // // First, create the ActiveX control Debug.Assert(_axInstance == null, "_axInstance must be null"); _axInstance = CreateActiveXObject(_clsid.Value); Debug.Assert(_axInstance != null, "w/o an exception being thrown we must have an object..."); // // We are now Loaded! this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; // // Lets give them a chance to cast the ActiveX object // to the appropriate interfaces. this.AttachInterfacesInternal(); } } ////// Critical - accesses critical interface members, _axInstance /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromLoadedToPassive() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Loaded) { // // Need to make sure that we don't handle any PropertyChanged // notifications at this point. //this.NoComponentChangeEvents++; try { // // Release the _axInstance if (_axInstance != null) { // // Lets first get the cached interface pointers of _axInstance released. this.DetachInterfacesInternal(); Marshal.FinalReleaseComObject(_axInstance); _axInstance = null; } } finally { // } // // We are now Passive! this.ActiveXState = ActiveXHelper.ActiveXState.Passive; } } ////// Critical - calls critical code - SetClientSite. /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromLoadedToRunning() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Loaded, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Loaded) { // // See if the ActiveX control returns OLEMISC_SETCLIENTSITEFIRST int bits = 0; int hr = _axOleObject.GetMiscStatus(NativeMethods.DVASPECT_CONTENT, out bits); if (NativeMethods.Succeeded(hr) && ((bits & NativeMethods.OLEMISC_SETCLIENTSITEFIRST) != 0)) { // // Simply setting the site to the ActiveX control should activate it. // And this will take us to the Running state. _axOleObject.SetClientSite(this.ActiveXSite); } StartEvents(); // // We are now Running! this.ActiveXState = ActiveXHelper.ActiveXState.Running; } } ////// Critical - accesses critical code, _axOleOlebject, StopEvents /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromRunningToLoaded() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Running) { StopEvents(); // // Inform the ActiveX control that it's been un-sited. _axOleObject.SetClientSite(null); // // We are now Loaded! this.ActiveXState = ActiveXHelper.ActiveXState.Loaded; } } ////// Critical - calls critical code - DoVerb. /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromRunningToInPlaceActive() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.Running, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.Running) { try { DoVerb(NativeMethods.OLEIVERB_INPLACEACTIVATE); } catch (Exception e) { if(CriticalExceptions.IsCriticalException(e)) { throw; } else { throw new TargetInvocationException(SR.Get(SRID.AXNohWnd, GetType().Name), e); } } // // We are now InPlaceActive! this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive; } } ////// Critical - calls critical code - InPlaceDeactivate. /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromInPlaceActiveToRunning() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive) { // // InPlaceDeactivate. _axOleInPlaceObject.InPlaceDeactivate(); // // We are now Running! this.ActiveXState = ActiveXHelper.ActiveXState.Running; } } ////// Critical - calls critical code - DoVerb. /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromInPlaceActiveToUIActive() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.InPlaceActive) { DoVerb(NativeMethods.OLEIVERB_UIACTIVATE); // // We are now UIActive! this.ActiveXState = ActiveXHelper.ActiveXState.UIActive; } } ////// Critical - accesses critical interface members, _axOleInPlaceObject /// TreatAsSafe - state transitions considered safe. /// Instantiating a control is considered critical. /// However once instantiated, state transitions considered ok. /// [SecurityCritical, SecurityTreatAsSafe ] private void TransitionFromUIActiveToInPlaceActive() { Debug.Assert(this.ActiveXState == ActiveXHelper.ActiveXState.UIActive, "Wrong start state to transition from"); if (this.ActiveXState == ActiveXHelper.ActiveXState.UIActive) { int hr = _axOleInPlaceObject.UIDeactivate(); Debug.Assert(NativeMethods.Succeeded(hr), "Failed in IOleInPlaceObject.UiDeactivate"); // // We are now InPlaceActive! this.ActiveXState = ActiveXHelper.ActiveXState.InPlaceActive; } } #endregion ActiveX Related #endregion Internal Methods //----------------------------------------------------- // // Internal Properties // //----------------------------------------------------- #region Internal Properties #region Framework Related ////// The DependencyProperty for the TabIndex property. /// Flags: Can be used in style rules /// Default Value: 1 /// internal static readonly DependencyProperty TabIndexProperty = Control.TabIndexProperty.AddOwner(typeof(ActiveXHost)); ////// TabIndex property change the order of Tab navigation between Controls. /// Control with lower TabIndex will get focus before the Control with higher index /// internal int TabIndex { get { return (int) GetValue(TabIndexProperty); } set { SetValue(TabIndexProperty, value); } } ////// Critical - accesses _hwndParent critical member. /// internal HandleRef ParentHandle { [ SecurityCritical ] get { return _hwndParent; } [ SecurityCritical ] set { _hwndParent = value; } } // This returns a COMRECT. internal NativeMethods.COMRECT Bounds { get { return _bounds; } //How do we notify Avalon tree/layout that the control needs a new size? set { _bounds = value; } } // This returns a Rect. internal Rect BoundRect { get { return _boundRect; } } #endregion Framework Related #region ActiveX Related ////// Returns the hosted ActiveX control's handle /// ////// Critical - returns critical _axWindow member /// internal HandleRef ControlHandle { [ SecurityCritical ] get { return _axWindow; } } //////Returns the native webbrowser object that this control wraps. Needs FullTrust to access. /// Internally we will access the private field directly for perf reasons, no security checks /// ////// Critical - returns critical Instance member. /// internal object ActiveXInstance { [ SecurityCritical ] get { return _axInstance; } } ////// Critical - returns critical Instance member. /// internal UnsafeNativeMethods.IOleInPlaceObject ActiveXInPlaceObject { [ SecurityCritical ] get { return _axOleInPlaceObject; } } ////// Critical - returns critical Instance member. /// internal UnsafeNativeMethods.IOleInPlaceActiveObject ActiveXInPlaceActiveObject { [SecurityCritical] get { return _axOleInPlaceActiveObject; } } #endregion ActiveXRelated #endregion Internal Properties //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods #region Framework Methods private void OnInitialized(object sender, EventArgs e) { // this.Initialized -= new EventHandler(this.OnInitialized); //Cannot inplace activate yet, since BuildWindowCore is not called yet //and we need that for getting the parent handle to pass on to the control. } private static void OnIsEnabledInvalidated(ActiveXHost axHost) { // } private static void OnVisibilityInvalidated(ActiveXHost axHost) { if (axHost != null) { switch (axHost.Visibility) { case Visibility.Visible: // break; case Visibility.Collapsed: // break; case Visibility.Hidden: // break; } } } /// This event handler forwards focus events to the hosted ActiveX control private static void OnGotFocus(object sender, KeyboardFocusChangedEventArgs e) { ActiveXHost axhost = sender as ActiveXHost; if (axhost != null) { Invariant.Assert(axhost.ActiveXState >= ActiveXHelper.ActiveXState.InPlaceActive, "Should at least be InPlaceActive when getting focus"); if (axhost.ActiveXState < ActiveXHelper.ActiveXState.UIActive) { axhost.TransitionUpTo(ActiveXHelper.ActiveXState.UIActive); } } } /// This event handler forwards focus events to the hosted WF controls private static void OnLostFocus(object sender, KeyboardFocusChangedEventArgs e) { ActiveXHost axhost = sender as ActiveXHost; if (axhost != null) { // If the focus goes from our control window to one of the child windows, // we should not deactivate. // Invariant.Assert(axhost.ActiveXState >= ActiveXHelper.ActiveXState.UIActive, "Should at least be UIActive when losing focus"); bool uiDeactivate = !axhost.IsKeyboardFocusWithin; if (uiDeactivate) { axhost.TransitionDownTo(ActiveXHelper.ActiveXState.InPlaceActive); } } } private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs args) { if (!args.Handled && args.Scope == null && args.Target == null) { args.Target = (UIElement)sender; } } /* private void GetMnemonicList(SWF.Control control, ArrayList mnemonicList) { // Get the mnemonic for our control // char mnemonic = HostUtils.GetMnemonic(control.Text, true); if (mnemonic != 0) { mnemonicList.Add(mnemonic); } // And recurse for our children, currently we only support one activex control // if (HostedControl != null) GetMnemonicList(HostedControl, mnemonicList); } */ #endregion Framework Methods #region ActiveX Related ////// Critical - accesses critical interface pointers. /// [ SecurityCritical ] private void AttachInterfacesInternal() { Debug.Assert(_axInstance != null, "The native control is null"); _axOleObject = (UnsafeNativeMethods.IOleObject)_axInstance; _axOleInPlaceObject = (UnsafeNativeMethods.IOleInPlaceObject)_axInstance; _axOleInPlaceActiveObject = (UnsafeNativeMethods.IOleInPlaceActiveObject)_axInstance; // // Lets give the inheriting classes a chance to cast // the ActiveX object to the appropriate interfaces. AttachInterfaces(_axInstance); } ////// Critical - accesses critical interface members. /// TreatAsSafe - clearing the interfaces is ok. /// [ SecurityCritical, SecurityTreatAsSafe ] private void DetachInterfacesInternal() { _axOleObject = null; _axOleInPlaceObject = null; _axOleInPlaceActiveObject = null; // // Lets give the inheriting classes a chance to release // their cached interfaces of the ActiveX object. DetachInterfaces(); } ////// Critical - calls calls critical interface members. /// [ SecurityCritical ] private NativeMethods.SIZE SetExtent(int width, int height) { NativeMethods.SIZE sz = new NativeMethods.SIZE(); sz.cx = width; sz.cy = height; bool resetExtents = false; try { _axOleObject.SetExtent(NativeMethods.DVASPECT_CONTENT, sz); } catch (COMException) { resetExtents = true; } if (resetExtents) { _axOleObject.GetExtent(NativeMethods.DVASPECT_CONTENT, sz); try { _axOleObject.SetExtent(NativeMethods.DVASPECT_CONTENT, sz); } catch (COMException e) { Debug.Fail(e.ToString()); } } return GetExtent(); } ////// Critical - accesses critical interface member _axOleObject /// TreatAsSafe - getting the size of the control is considered ok. /// [ SecurityCritical, SecurityTreatAsSafe ] private NativeMethods.SIZE GetExtent() { NativeMethods.SIZE sz = new NativeMethods.SIZE(); _axOleObject.GetExtent(NativeMethods.DVASPECT_CONTENT, sz); return sz; } #endregion ActiveX Related #endregion Private Methods //----------------------------------------------------- // // Private Properties // //------------------------------------------------------ #region Private Properties #endregion Private Properties //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- #region Private Fields #region Framework Related private static Hashtable invalidatorMap = new Hashtable(); private delegate void PropertyInvalidator(ActiveXHost axhost); private NativeMethods.COMRECT _bounds = new NativeMethods.COMRECT(0, 0, 0, 0); private Rect _boundRect = new Rect(0, 0, 0, 0); private Size _cachedSize = Size.Empty; ////// Critical - _hwndParent considered critical. /// [SecurityCritical ] private HandleRef _hwndParent; private bool _isDisposed; #endregion Framework Related #region ActiveX Related ////// Critical - _clsId controls what code to run and instantiate. /// private SecurityCriticalDataForSet_clsid; /// /// Critical - hwnd of control /// [ SecurityCritical ] private HandleRef _axWindow; private BitVector32 _axHostState = new BitVector32(); private ActiveXHelper.ActiveXState _axState = ActiveXHelper.ActiveXState.Passive; ////// Critical - ActiveXSite interfaces of control /// [ SecurityCritical ] private ActiveXSite _axSite; ////// Critical - ActiveXContainer of control /// [ SecurityCritical ] private ActiveXContainer _axContainer; ////// Critical - all methods on this Interface are critical /// [SecurityCritical] private object _axInstance; // Pointers to the ActiveX object: Interface pointers are cached for perf. ////// Critical - all methods on this Interface are critical /// [SecurityCritical] private UnsafeNativeMethods.IOleObject _axOleObject; ////// Critical - all methods on this Interface are critical /// [SecurityCritical] private UnsafeNativeMethods.IOleInPlaceObject _axOleInPlaceObject; ////// Critical - all methods on this Interface are critical /// [SecurityCritical] private UnsafeNativeMethods.IOleInPlaceActiveObject _axOleInPlaceActiveObject; #endregion ActiveX Related #endregion Private Fields } #endregion ActiveXHost } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebBrowserNavigatingEventHandler.cs
- MediaElement.cs
- WebPartTransformerCollection.cs
- ProcessInfo.cs
- XLinq.cs
- ComponentSerializationService.cs
- VScrollBar.cs
- BindingValueChangedEventArgs.cs
- SplashScreenNativeMethods.cs
- EntityContainerEntitySet.cs
- ContextQuery.cs
- KoreanLunisolarCalendar.cs
- Context.cs
- XmlNode.cs
- ObjectView.cs
- PropertyFilterAttribute.cs
- UdpReplyToBehavior.cs
- DNS.cs
- MSAAEventDispatcher.cs
- WorkflowItemPresenter.cs
- EntityDataSourceQueryBuilder.cs
- DrawingImage.cs
- Literal.cs
- CubicEase.cs
- ProxyWebPartManagerDesigner.cs
- ResolveNameEventArgs.cs
- XsltQilFactory.cs
- EventsTab.cs
- storepermission.cs
- RelationshipEnd.cs
- ViewStateException.cs
- ClientSettings.cs
- ThreadExceptionDialog.cs
- XmlUnspecifiedAttribute.cs
- MoveSizeWinEventHandler.cs
- VirtualDirectoryMapping.cs
- ConnectionStringsExpressionBuilder.cs
- ParameterInfo.cs
- TextRangeSerialization.cs
- LayoutEngine.cs
- xml.cs
- MissingMemberException.cs
- MarshalByValueComponent.cs
- XmlChoiceIdentifierAttribute.cs
- BitSet.cs
- WorkflowPrinting.cs
- ListViewHitTestInfo.cs
- AccessViolationException.cs
- LoginView.cs
- TemplateKey.cs
- sqlser.cs
- PolicyManager.cs
- StatusBarDrawItemEvent.cs
- ImportedNamespaceContextItem.cs
- Image.cs
- NumberSubstitution.cs
- MetadataItemSerializer.cs
- ZipIOCentralDirectoryDigitalSignature.cs
- ContextBase.cs
- Storyboard.cs
- FacetDescriptionElement.cs
- DmlSqlGenerator.cs
- SystemIPv6InterfaceProperties.cs
- CreateParams.cs
- SqlWriter.cs
- ListViewHitTestInfo.cs
- DebugHandleTracker.cs
- UIInitializationException.cs
- XmlName.cs
- TextDecorationCollectionConverter.cs
- EmptyStringExpandableObjectConverter.cs
- ContainerAction.cs
- Rect.cs
- PageTheme.cs
- SQLInt64Storage.cs
- ShapingEngine.cs
- SQLInt64Storage.cs
- OdbcHandle.cs
- DisplayMemberTemplateSelector.cs
- CalendarButtonAutomationPeer.cs
- XmlSchemaException.cs
- ReflectionTypeLoadException.cs
- PackageRelationshipCollection.cs
- NullEntityWrapper.cs
- SchemaImporter.cs
- ProfileServiceManager.cs
- ClientScriptItem.cs
- SpecialNameAttribute.cs
- Point3DAnimation.cs
- DataGridBoolColumn.cs
- ActivityValidator.cs
- CompilationUnit.cs
- FormViewAutoFormat.cs
- CatalogZoneBase.cs
- TableRowGroup.cs
- X509UI.cs
- FontWeightConverter.cs
- DynamicUpdateCommand.cs
- WindowHelperService.cs
- RowToParametersTransformer.cs