Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Runtime / Remoting / MessageSmuggler.cs / 1 / MessageSmuggler.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //========================================================================== // File: MessageSmuggler.cs // // Summary: Implements objects necessary to smuggle messages across // AppDomains and determine when it's possible. // //========================================================================= using System; using System.Collections; using System.IO; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; namespace System.Runtime.Remoting.Messaging { internal class MessageSmuggler { private static bool CanSmuggleObjectDirectly(Object obj) { if ((obj is String) || (obj.GetType() == typeof(void)) || obj.GetType().IsPrimitive) { return true; } return false; } // CanSmuggleObjectDirectly protected static Object[] FixupArgs(Object[] args, ref ArrayList argsToSerialize) { Object[] newArgs = new Object[args.Length]; int total = args.Length; for (int co = 0; co < total; co++) { newArgs[co] = FixupArg(args[co], ref argsToSerialize); } return newArgs; } // FixupArgs protected static Object FixupArg(Object arg, ref ArrayList argsToSerialize) { // This method examines an argument and sees if it can be smuggled in some form. // If it can directly be smuggled (i.e. it is a primitive or string), we // just return the same object. If it's a marshal by ref object, we // see if we can smuggle the obj ref. If it's a primitive or string array, // we can smuggle a cloned copy of the array. In all other cases, // we add it to the list of args we want serialized, and return a // placeholder element (SerializedArg). if (arg == null) return null; int index; // IMPORTANT!!! This should be done first because CanSmuggleObjectDirectly // calls GetType() and that would slow this down. MarshalByRefObject mbo = arg as MarshalByRefObject; if (mbo != null) { // We can only try to smuggle objref's for actual CLR objects // or for RemotingProxy's. if (!RemotingServices.IsTransparentProxy(mbo) || RemotingServices.GetRealProxy(mbo) is RemotingProxy) { ObjRef objRef = RemotingServices.MarshalInternal(mbo, null, null); if (objRef.CanSmuggle()) { if (!RemotingServices.IsTransparentProxy(mbo)) { ServerIdentity srvId = (ServerIdentity)MarshalByRefObject.GetIdentity(mbo); srvId.SetHandle(); objRef.SetServerIdentity(srvId.GetHandle()); objRef.SetDomainID(AppDomain.CurrentDomain.GetId()); } ObjRef smugObjRef = objRef.CreateSmuggleableCopy(); smugObjRef.SetMarshaledObject(); return new SmuggledObjRef(smugObjRef); } } // Add this arg to list of one's to serialize and return a placeholder // since we couldn't smuggle the objref. if (argsToSerialize == null) argsToSerialize = new ArrayList(); index = argsToSerialize.Count; argsToSerialize.Add(arg); return new SerializedArg(index); } if (CanSmuggleObjectDirectly(arg)) return arg; // if this is a primitive array, we can just make a copy. // (IMPORTANT: We can directly use this copy from the // other app domain, there is no reason to make another // copy once we are on the other side) Array array = arg as Array; if (array != null) { Type elementType = array.GetType().GetElementType(); if (elementType.IsPrimitive || (elementType == typeof(String))) return array.Clone(); } // Add this arg to list of one's to serialize and return a placeholder. if (argsToSerialize == null) argsToSerialize = new ArrayList(); index = argsToSerialize.Count; argsToSerialize.Add(arg); return new SerializedArg(index); } // FixupArg protected static Object[] UndoFixupArgs(Object[] args, ArrayList deserializedArgs) { Object[] newArgs = new Object[args.Length]; int total = args.Length; for (int co = 0; co < total; co++) { newArgs[co] = UndoFixupArg(args[co], deserializedArgs); } return newArgs; } // UndoFixupArgs protected static Object UndoFixupArg(Object arg, ArrayList deserializedArgs) { SmuggledObjRef smuggledObjRef = arg as SmuggledObjRef; if (smuggledObjRef != null) { // We call GetRealObject here ... that covers any // special unmarshaling we need to do for _ComObject return smuggledObjRef.ObjRef.GetRealObjectHelper(); } SerializedArg serializedArg = arg as SerializedArg; if (serializedArg != null) { return deserializedArgs[serializedArg.Index]; } return arg; } // UndoFixupArg // returns number of entries added to argsToSerialize protected static int StoreUserPropertiesForMethodMessage( IMethodMessage msg, ref ArrayList argsToSerialize) { IDictionary properties = msg.Properties; MessageDictionary dict = properties as MessageDictionary; if (dict != null) { if (dict.HasUserData()) { int co = 0; foreach (DictionaryEntry entry in dict.InternalDictionary) { if (argsToSerialize == null) argsToSerialize = new ArrayList(); argsToSerialize.Add(entry); co++; } return co; } else { return 0; } } else { // < int co = 0; foreach (DictionaryEntry entry in properties) { if (argsToSerialize == null) argsToSerialize = new ArrayList(); argsToSerialize.Add(entry); co++; } return co; } } // StoreUserPropertiesForMethodMessage // // Helper classes used to smuggle transformed arguments // protected class SerializedArg { private int _index; public SerializedArg(int index) { _index = index; } public int Index { get { return _index; } } } // // end of Helper classes used to smuggle transformed arguments // } // class MessageSmuggler // stores an object reference internal class SmuggledObjRef { ObjRef _objRef; public SmuggledObjRef(ObjRef objRef) { _objRef = objRef; } public ObjRef ObjRef { get { return _objRef; } } } // SmuggledObjRef internal class SmuggledMethodCallMessage : MessageSmuggler { private String _uri; private String _methodName; private String _typeName; private Object[] _args; private byte[] _serializedArgs = null; #if false // This field isn't currently used private Object[] _serializerSmuggledArgs = null; #endif // other things that might need to go through serializer private SerializedArg _methodSignature = null; private SerializedArg _instantiation = null; private Object _callContext = null; // either a call id string or a SerializedArg pointing to CallContext object private int _propertyCount = 0; //= # of user properties in dictionary // note: first entries in _deserializedArgs will be the property entries // always use this helper method to create internal static SmuggledMethodCallMessage SmuggleIfPossible(IMessage msg) { IMethodCallMessage mcm = msg as IMethodCallMessage; if (mcm == null) return null; return new SmuggledMethodCallMessage(mcm); } // hide default constructor private SmuggledMethodCallMessage(){} private SmuggledMethodCallMessage(IMethodCallMessage mcm) { _uri = mcm.Uri; _methodName = mcm.MethodName; _typeName = mcm.TypeName; ArrayList argsToSerialize = null; IInternalMessage iim = mcm as IInternalMessage; // user properties (everything but special entries) if ((iim == null) || iim.HasProperties()) _propertyCount = StoreUserPropertiesForMethodMessage(mcm, ref argsToSerialize); // generic instantiation information if (mcm.MethodBase.IsGenericMethod) { Type[] inst = mcm.MethodBase.GetGenericArguments(); if (inst != null && inst.Length > 0) { if (argsToSerialize == null) argsToSerialize = new ArrayList(); _instantiation = new SerializedArg(argsToSerialize.Count); argsToSerialize.Add(inst); } } // handle method signature if (RemotingServices.IsMethodOverloaded(mcm)) { if (argsToSerialize == null) argsToSerialize = new ArrayList(); _methodSignature = new SerializedArg(argsToSerialize.Count); argsToSerialize.Add(mcm.MethodSignature); } // handle call context LogicalCallContext lcc = mcm.LogicalCallContext; if (lcc == null) { _callContext = null; } else if (lcc.HasInfo) { if (argsToSerialize == null) argsToSerialize = new ArrayList(); _callContext = new SerializedArg(argsToSerialize.Count); argsToSerialize.Add(lcc); } else { // just smuggle the call id string _callContext = lcc.RemotingData.LogicalCallID; } _args = FixupArgs(mcm.Args, ref argsToSerialize); if (argsToSerialize != null) { //MemoryStream argStm = CrossAppDomainSerializer.SerializeMessageParts(argsToSerialize, out _serializerSmuggledArgs); MemoryStream argStm = CrossAppDomainSerializer.SerializeMessageParts(argsToSerialize); _serializedArgs = argStm.GetBuffer(); } } // SmuggledMethodCallMessage // returns a list of the deserialized arguments internal ArrayList FixupForNewAppDomain() { ArrayList deserializedArgs = null; if (_serializedArgs != null) { deserializedArgs = CrossAppDomainSerializer.DeserializeMessageParts( new MemoryStream(_serializedArgs)); //deserializedArgs = // CrossAppDomainSerializer.DeserializeMessageParts( // new MemoryStream(_serializedArgs), _serializerSmuggledArgs); _serializedArgs = null; } return deserializedArgs; } // FixupForNewAppDomain internal String Uri { get { return _uri; } } internal String MethodName { get { return _methodName; } } internal String TypeName { get { return _typeName; } } internal Type[] GetInstantiation(ArrayList deserializedArgs) { if (_instantiation != null) return (Type[])deserializedArgs[_instantiation.Index]; else return null; } internal Object[] GetMethodSignature(ArrayList deserializedArgs) { if (_methodSignature != null) return (Object[])deserializedArgs[_methodSignature.Index]; else return null; } internal Object[] GetArgs(ArrayList deserializedArgs) { return UndoFixupArgs(_args, deserializedArgs); } // GetArgs internal LogicalCallContext GetCallContext(ArrayList deserializedArgs) { if (_callContext == null) { return null; } if (_callContext is String) { LogicalCallContext callContext = new LogicalCallContext(); callContext.RemotingData.LogicalCallID = (String)_callContext; return callContext; } else return (LogicalCallContext)deserializedArgs[((SerializedArg)_callContext).Index]; } internal int MessagePropertyCount { get { return _propertyCount; } } internal void PopulateMessageProperties(IDictionary dict, ArrayList deserializedArgs) { for (int co = 0; co < _propertyCount; co++) { DictionaryEntry de = (DictionaryEntry)deserializedArgs[co]; dict[de.Key] = de.Value; } } } // class SmuggledMethodCallMessage internal class SmuggledMethodReturnMessage : MessageSmuggler { private Object[] _args; private Object _returnValue; private byte[] _serializedArgs = null; #if false // This field isn't currently used private Object[] _serializerSmuggledArgs = null; #endif // other things that might need to go through serializer private SerializedArg _exception = null; private Object _callContext = null; // either a call id string or a SerializedArg pointing to CallContext object private int _propertyCount; // = # of user properties in dictionary // note: first entries in _deserializedArgs will be the property entries // always use this helper method to create internal static SmuggledMethodReturnMessage SmuggleIfPossible(IMessage msg) { IMethodReturnMessage mrm = msg as IMethodReturnMessage; if (mrm == null) return null; return new SmuggledMethodReturnMessage(mrm); } // hide default constructor private SmuggledMethodReturnMessage(){} private SmuggledMethodReturnMessage(IMethodReturnMessage mrm) { ArrayList argsToSerialize = null; ReturnMessage retMsg = mrm as ReturnMessage; // user properties (everything but special entries) if ((retMsg == null) || retMsg.HasProperties()) _propertyCount = StoreUserPropertiesForMethodMessage(mrm, ref argsToSerialize); // handle exception Exception excep = mrm.Exception; if (excep != null) { if (argsToSerialize == null) argsToSerialize = new ArrayList(); _exception = new SerializedArg(argsToSerialize.Count); argsToSerialize.Add(excep); } // handle call context LogicalCallContext lcc = mrm.LogicalCallContext; if (lcc == null) { _callContext = null; } else if (lcc.HasInfo) { if (lcc.Principal != null) lcc.Principal = null; if (argsToSerialize == null) argsToSerialize = new ArrayList(); _callContext = new SerializedArg(argsToSerialize.Count); argsToSerialize.Add(lcc); } else { // just smuggle the call id string _callContext = lcc.RemotingData.LogicalCallID; } _returnValue = FixupArg(mrm.ReturnValue, ref argsToSerialize); _args = FixupArgs(mrm.Args, ref argsToSerialize); if (argsToSerialize != null) { MemoryStream argStm = CrossAppDomainSerializer.SerializeMessageParts(argsToSerialize); //MemoryStream argStm = CrossAppDomainSerializer.SerializeMessageParts(argsToSerialize, out _serializerSmuggledArgs); _serializedArgs = argStm.GetBuffer(); } } // SmuggledMethodReturnMessage internal ArrayList FixupForNewAppDomain() { ArrayList deserializedArgs = null; if (_serializedArgs != null) { deserializedArgs = CrossAppDomainSerializer.DeserializeMessageParts( new MemoryStream(_serializedArgs)); //deserializedArgs = // CrossAppDomainSerializer.DeserializeMessageParts( // new MemoryStream(_serializedArgs), _serializerSmuggledArgs); _serializedArgs = null; } return deserializedArgs; } // FixupForNewAppDomain internal Object GetReturnValue(ArrayList deserializedArgs) { return UndoFixupArg(_returnValue, deserializedArgs); } // GetReturnValue internal Object[] GetArgs(ArrayList deserializedArgs) { Object[] obj = UndoFixupArgs(_args, deserializedArgs); return obj; } // GetArgs internal Exception GetException(ArrayList deserializedArgs) { if (_exception != null) return (Exception)deserializedArgs[_exception.Index]; else return null; } // Exception internal LogicalCallContext GetCallContext(ArrayList deserializedArgs) { if (_callContext == null) { return null; } if (_callContext is String) { LogicalCallContext callContext = new LogicalCallContext(); callContext.RemotingData.LogicalCallID = (String)_callContext; return callContext; } else return (LogicalCallContext)deserializedArgs[((SerializedArg)_callContext).Index]; } internal int MessagePropertyCount { get { return _propertyCount; } } internal void PopulateMessageProperties(IDictionary dict, ArrayList deserializedArgs) { for (int co = 0; co < _propertyCount; co++) { DictionaryEntry de = (DictionaryEntry)deserializedArgs[co]; dict[de.Key] = de.Value; } } } // class SmuggledMethodReturnMessage } // namespace System.Runtime.Remoting.Messaging
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Rect3D.cs
- XmlDocumentFragment.cs
- CompiledXpathExpr.cs
- DecoratedNameAttribute.cs
- TextTreeUndo.cs
- HandlerFactoryWrapper.cs
- DtdParser.cs
- HtmlContainerControl.cs
- TableLayoutStyle.cs
- RtType.cs
- RenderDataDrawingContext.cs
- DurableDispatcherAddressingFault.cs
- DataListComponentEditor.cs
- TextStore.cs
- XmlLanguageConverter.cs
- CodeDOMUtility.cs
- TableParagraph.cs
- ConnectionManagementElement.cs
- ListViewInsertedEventArgs.cs
- FixedTextView.cs
- ParameterToken.cs
- Operator.cs
- WebBrowserContainer.cs
- SafeFileHandle.cs
- filewebresponse.cs
- XmlNotation.cs
- DependsOnAttribute.cs
- Matrix.cs
- MultipleViewProviderWrapper.cs
- WindowsAuthenticationEventArgs.cs
- WeakEventManager.cs
- PartitionResolver.cs
- WebPartEditorCancelVerb.cs
- Brush.cs
- XPathMessageContext.cs
- SchemaTableColumn.cs
- AppDomainEvidenceFactory.cs
- ServerProtocol.cs
- ClrPerspective.cs
- BitmapMetadata.cs
- StrokeRenderer.cs
- CheckBoxList.cs
- PinProtectionHelper.cs
- XmlSerializerOperationBehavior.cs
- FileChangesMonitor.cs
- SqlBuilder.cs
- AttributeSetAction.cs
- AnnotationService.cs
- TextEditorThreadLocalStore.cs
- AuthenticationModuleElementCollection.cs
- SqlDuplicator.cs
- PaintValueEventArgs.cs
- ReflectionTypeLoadException.cs
- EllipticalNodeOperations.cs
- ConfigXmlWhitespace.cs
- Clipboard.cs
- WebHttpSecurityModeHelper.cs
- Content.cs
- SmiXetterAccessMap.cs
- _emptywebproxy.cs
- CollectionViewSource.cs
- DBCommandBuilder.cs
- EditCommandColumn.cs
- ComAwareEventInfo.cs
- ConfigurationLocationCollection.cs
- DeferredReference.cs
- HttpModule.cs
- ListManagerBindingsCollection.cs
- ListViewCommandEventArgs.cs
- AuthenticatingEventArgs.cs
- ObjectDataSource.cs
- _SafeNetHandles.cs
- ByteStreamGeometryContext.cs
- Event.cs
- ADMembershipUser.cs
- dataprotectionpermissionattribute.cs
- ToolStripOverflowButton.cs
- FormConverter.cs
- TextRangeAdaptor.cs
- DayRenderEvent.cs
- WebServiceAttribute.cs
- ThreadPool.cs
- DefaultMergeHelper.cs
- StaticSiteMapProvider.cs
- XmlWriter.cs
- ThreadStartException.cs
- AspNetHostingPermission.cs
- MemberCollection.cs
- StrongNameUtility.cs
- COM2FontConverter.cs
- ProviderCollection.cs
- XPathSelfQuery.cs
- ComponentDispatcher.cs
- AvTraceFormat.cs
- NullRuntimeConfig.cs
- Semaphore.cs
- TextMarkerSource.cs
- ClientScriptManager.cs
- SafeEventLogReadHandle.cs
- AuthenticationService.cs