Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / Interop / InternalDispatchObject.cs / 1305600 / InternalDispatchObject.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Description:
// InternalDispatchObject facilitates implementing a COM dispinterface using a non-public
// corresponding managed interface definition (of type ComInterfaceType.InterfaceIsIDispatch).
// (For example, we use this to implement DWebBrowserEvents2 without making it a public interface
// type in the framework.)
//
// If a public managed interface definition is available, CLR's built-in implementation of
// IDispatch suffices. It maps IDispatch calls to Reflection calls. But reflecting on non-public
// members causes a demand for ReflectionPermission/MemberAccess against the caller of the
// Reflection API. In a partial-trust AppDomain, and oddly only with some particular transitions
// between managed-native-managed stack frames, this demand fails. Given that this occurs with
// substantially equivalent callstacks in terms of CAS (Asserts) and managed<->native transitions,
// there is probably an obscure CLR bug somewhere at the intersection of its IDispatch
// implementation, Reflection and CAS. And there seems to be no explicit suggestion in
// documentation that this scenario is supported in the first place.
//
// By implementing IReflect, any object can provide its own reflection implementation. And it
// turns out CLR's IDispatch "front end" will happily use such an implementation. We don't need
// to explicitly assert any ReflectionPermission in this arrangement as long as we are targeting
// an internally visible interface type. (The built-in reflection system performs the equivalent
// of a LinkDemand against the caller of the reflection API.) This, however, creates a potentially
// dangerous security situation.
//
// CAUTION!!! Do not expose any InternalDispatchObject-derived object instance to untrusted code,
// unless the implementation of the dispinterface is entirely safe. Such objects should be
// passed only to native code, to be invoked via IDispatch.
//
// Because IReflect is a public interface and has no (link)demands on it and because
// InternalDispatchObject's internal invocation of relection satisfies the reflection system's
// ReflectionPermission demand, the implementaiton of the given dispinterface effectively
// becomes publicly accessible. (Putting a LinkDemand on InternalDispatchObject.InvokeMember()
// would have no effect because it can be called via IReflect, and LinkDemands are evaluated
// based on static type info. And putting a full Demand would defeat the whole purpose of
// InternalDispatchObject.)
//
// History
// 04/30/08 - [....] - Created
//
//-----------------------------------------------------------------------------
using System;
using System.Security;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Globalization;
namespace MS.Internal.Interop
{
///
/// InternalDispatchObject-derived objects are potentially unsafe to expose to untrusted code.
/// The IDispInterface implementation members should be treated as publicly accessible.
///
internal abstract class InternalDispatchObject : IReflect
{
///
/// DISPID->MethodInfo map used by InvokeMember()
///
private Dictionary _dispId2MethodMap;
///
/// Critical - to help ensure whoever creates an instance of this class doesn't expose it.
///
[SecurityCritical]
protected InternalDispatchObject()
{
// Populate _dispId2MethodMap with the MethodInfos for the interface, keyed by DISPID.
// There is no support for properties (yet).
MethodInfo[] methods = typeof(IDispInterface).GetMethods();
_dispId2MethodMap = new Dictionary(methods.Length);
foreach (MethodInfo method in methods)
{
int dispid = ((DispIdAttribute[])method.GetCustomAttributes(typeof(DispIdAttribute), false))[0].Value;
_dispId2MethodMap[dispid] = method;
}
}
FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr)
{
throw new NotImplementedException();
}
FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr)
{
return null;
}
MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr)
{
throw new NotImplementedException();
}
MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr)
{
throw new NotImplementedException();
}
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr)
{
throw new NotImplementedException();
}
MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
{
throw new NotImplementedException();
}
MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr)
{
// It doesn't help to return typeof(IDispInterface).GetMethods(), because the CLR's IDispatch layer
// ignores non-visible MethodInfos (DispatchInfo::SynchWithManagedView(), in clr\src\VM\DispatchInfo.cpp).
// For all "unknown" DISPIDs, IReflect.InvokeMember() is passed a method name like "[DISPID=]",
// which we parse.
return null;
}
PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr)
{
return null;
}
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
{
throw new NotImplementedException();
}
PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr)
{
throw new NotImplementedException();
}
///
/// Critical: Performs Reflection against a non-public type.
/// NOT PublicOK! This method is intrinsically unsafe. Because it can be called via the public IReflect,
/// instances of this class should not be exposed to untrusted code. (Full explanation above.)
///
[SecurityCritical]
object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
{
// We never expect to get a real method name here--see the explanation in GetMethods().
if (name.StartsWith("[DISPID=", StringComparison.OrdinalIgnoreCase))
{
int dispid = int.Parse(name.Substring(8, name.Length-9), CultureInfo.InvariantCulture);
MethodInfo method;
if (_dispId2MethodMap.TryGetValue(dispid, out method))
{
return method.Invoke(this, invokeAttr, binder, args, culture);
}
}
// This exception can be thrown if IDispInterface doesn't declare a method with a particular DISPID,
// but the real COM interface has it and the event source is trying to invoke it. For a call coming via
// the native IDispatch, such an error is usually ignorable.
throw new MissingMethodException(GetType().Name, name);
//return typeof(IDispInterface).InvokeMember(name, invokeAttr, binder, this, args, modifiers, culture, namedParameters);
}
Type IReflect.UnderlyingSystemType
{
get { return typeof(IDispInterface); }
}
};
}//namespace
// 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
- RectIndependentAnimationStorage.cs
- Object.cs
- IsolatedStorageFile.cs
- FrameworkTemplate.cs
- SqlRetyper.cs
- TreeNodeSelectionProcessor.cs
- HTMLTagNameToTypeMapper.cs
- DbConnectionClosed.cs
- hresults.cs
- UriExt.cs
- DrawingContextWalker.cs
- MulticastIPAddressInformationCollection.cs
- ConfigXmlDocument.cs
- TextServicesCompartmentEventSink.cs
- NamespaceInfo.cs
- IxmlLineInfo.cs
- DataListItem.cs
- Version.cs
- MouseButton.cs
- ArrayWithOffset.cs
- StateWorkerRequest.cs
- FontUnit.cs
- CompositeTypefaceMetrics.cs
- MSAANativeProvider.cs
- SendSecurityHeader.cs
- MyContact.cs
- SafeArrayRankMismatchException.cs
- ContourSegment.cs
- TextLine.cs
- RightsManagementPermission.cs
- VisualStates.cs
- CheckBox.cs
- FocusWithinProperty.cs
- XamlVector3DCollectionSerializer.cs
- RelativeSource.cs
- OracleTimeSpan.cs
- InspectionWorker.cs
- EventSetter.cs
- CryptoConfig.cs
- ButtonBaseAdapter.cs
- TemplateBindingExpressionConverter.cs
- DateTimeOffsetStorage.cs
- DataGridViewColumnCollection.cs
- TableItemPatternIdentifiers.cs
- _NegoStream.cs
- FixedSOMLineRanges.cs
- SiteMapProvider.cs
- DuplicateWaitObjectException.cs
- mansign.cs
- SettingsContext.cs
- GroupItemAutomationPeer.cs
- DocumentViewer.cs
- MobileSysDescriptionAttribute.cs
- DetailsViewPagerRow.cs
- WindowVisualStateTracker.cs
- PtsHost.cs
- UpdatableWrapper.cs
- KeyFrames.cs
- FullTextLine.cs
- ScriptComponentDescriptor.cs
- CodeAccessSecurityEngine.cs
- DocumentApplicationJournalEntry.cs
- DoubleStorage.cs
- AssemblyAttributes.cs
- Char.cs
- NoneExcludedImageIndexConverter.cs
- InstanceNameConverter.cs
- DataShape.cs
- StylusPointPropertyInfo.cs
- SlotInfo.cs
- WeakRefEnumerator.cs
- PrintingPermissionAttribute.cs
- SecurityKeyType.cs
- ItemsPanelTemplate.cs
- DispatcherEventArgs.cs
- BitmapEffectInputConnector.cs
- XXXInfos.cs
- ViewgenGatekeeper.cs
- BindingMemberInfo.cs
- InputLanguageSource.cs
- CustomPeerResolverService.cs
- JournalNavigationScope.cs
- SplitterCancelEvent.cs
- SelectionItemPattern.cs
- XPathDocumentNavigator.cs
- FormViewRow.cs
- MarshalByRefObject.cs
- StrokeNode.cs
- HttpApplicationFactory.cs
- SqlFlattener.cs
- CheckableControlBaseAdapter.cs
- Parser.cs
- IsolatedStorageFileStream.cs
- TransactionScopeDesigner.cs
- Funcletizer.cs
- ParsedAttributeCollection.cs
- WinEventHandler.cs
- ComponentResourceKey.cs
- RegisteredScript.cs
- ZipIOLocalFileHeader.cs