Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / 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 // // 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 // // 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 // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- mediapermission.cs
- TextParagraphProperties.cs
- TransportContext.cs
- MemberProjectionIndex.cs
- FixedSOMTable.cs
- TraceContext.cs
- Cursors.cs
- HwndHost.cs
- ByteStream.cs
- HttpVersion.cs
- HotCommands.cs
- SettingsSection.cs
- GenericWebPart.cs
- XsltException.cs
- HashHelper.cs
- DataServiceConfiguration.cs
- DesigntimeLicenseContextSerializer.cs
- WebPartMinimizeVerb.cs
- SaveFileDialog.cs
- ConstNode.cs
- RootBrowserWindowProxy.cs
- __Filters.cs
- SoapFormatExtensions.cs
- DataServiceProviderWrapper.cs
- EncodingInfo.cs
- SafeNativeMethods.cs
- _ChunkParse.cs
- ProtocolsConfigurationEntry.cs
- GridViewCancelEditEventArgs.cs
- _SpnDictionary.cs
- PropertyDescriptorCollection.cs
- AxisAngleRotation3D.cs
- Conditional.cs
- URLString.cs
- DataGridViewColumnHeaderCell.cs
- StyleBamlTreeBuilder.cs
- StylusButtonEventArgs.cs
- PerfCounterSection.cs
- _ContextAwareResult.cs
- ColumnResult.cs
- RectangleF.cs
- ExpressionLink.cs
- Rotation3D.cs
- ResumeStoryboard.cs
- CodeConstructor.cs
- PointF.cs
- SerializerProvider.cs
- MsmqInputChannelListener.cs
- DataGridViewColumnCollection.cs
- AssociationProvider.cs
- DriveInfo.cs
- EngineSite.cs
- CultureInfo.cs
- WeakEventManager.cs
- ClientOptions.cs
- LicenseContext.cs
- PageCache.cs
- HttpAsyncResult.cs
- ConfigViewGenerator.cs
- DeploymentSectionCache.cs
- InfiniteTimeSpanConverter.cs
- TypedMessageConverter.cs
- DictionaryEntry.cs
- OleAutBinder.cs
- DocumentPaginator.cs
- DtcInterfaces.cs
- BamlResourceDeserializer.cs
- NavigationProgressEventArgs.cs
- PermissionRequestEvidence.cs
- DocumentAutomationPeer.cs
- KeyGesture.cs
- WebServiceAttribute.cs
- View.cs
- SqlCrossApplyToCrossJoin.cs
- AutoGeneratedField.cs
- XamlStyleSerializer.cs
- X509CertificateInitiatorServiceCredential.cs
- StateItem.cs
- ClusterRegistryConfigurationProvider.cs
- PointConverter.cs
- Style.cs
- UriWriter.cs
- RawStylusInputReport.cs
- UnsafeNativeMethods.cs
- ChtmlCommandAdapter.cs
- MetaModel.cs
- DynamicPropertyReader.cs
- DeferredReference.cs
- SqlRewriteScalarSubqueries.cs
- TriggerBase.cs
- DataGridRowDetailsEventArgs.cs
- TextDecorationLocationValidation.cs
- ExpressionConverter.cs
- CodeDelegateInvokeExpression.cs
- HttpListenerException.cs
- Run.cs
- WebPartEditVerb.cs
- KeyEvent.cs
- ReceiveActivity.cs
- DesignerSerializationVisibilityAttribute.cs