public SoapReader(SerializationBinder binder, ISurrogateSelector selector, StreamingContext context) 
		{
			_binder = binder;
			objMgr = new ObjectManager(selector, context);
			_context = context;
			_surrogateSelector = selector;
			_fieldIndices = new Hashtable();
		}
	public DeserializationContext(BinaryFormatter formatter,
		BinaryReader reader)
	{
		Formatter = formatter;
		Reader = reader;
		mTypeStore = new Hashtable();
		mAssemblyStore = new Hashtable();
		Manager = new ObjectManager(formatter.SurrogateSelector, 
										formatter.Context);
	}
Example #3
0
		public ObjectReader (BinaryFormatter formatter)
		{
//			_formatter = formatter;
			_surrogateSelector = formatter.SurrogateSelector;
			_context = formatter.Context;
			_binder = formatter.Binder;
			_manager = new ObjectManager (_surrogateSelector, _context);
			
			_filterLevel = formatter.FilterLevel;
		}
        /// <remarks>
        /// Credit to MvcContrib.TestHelper.AssertionException for PreserveStackTrace
        /// </remarks>
        private static void PreserveStackTrace(Exception e)
        {
            var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
            var mgr = new ObjectManager(null, ctx);
            var si = new SerializationInfo(e.GetType(), new FormatterConverter());

            e.GetObjectData(si, ctx);
            mgr.RegisterObject(e, 1, si);
            mgr.DoFixups();
        }
        private void PreserveStackTrace(Exception exception)
        {
            var context = new StreamingContext(StreamingContextStates.CrossAppDomain);
            var objectManager = new ObjectManager(null, context);
            var serializationInfo = new SerializationInfo(exception.GetType(), new FormatterConverter());

            exception.GetObjectData(serializationInfo, context);
            objectManager.RegisterObject(exception, 1, serializationInfo);
            objectManager.DoFixups();
        }
Example #6
0
        /// <summary>Makes sure exception stack trace would not be modify on rethrow.</summary>
        public static Exception PreserveStackTrace(this Exception exception)
        {
            var streamingContext = new StreamingContext(StreamingContextStates.CrossAppDomain);
            var objectManager = new ObjectManager(null, streamingContext);
            var serializationInfo = new SerializationInfo(exception.GetType(), new FormatterConverter());

            exception.GetObjectData(serializationInfo, streamingContext);
            objectManager.RegisterObject(exception, 1, serializationInfo); // prepare for SetObjectData
            objectManager.DoFixups(); // ObjectManager calls SetObjectData
            return exception;
        }
Example #7
0
        public static void PreserveStackTrace(Exception e)
        {
            var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
            var mgr = new ObjectManager(null, ctx);
            var si = new SerializationInfo(e.GetType(), new FormatterConverter());

            e.GetObjectData(si, ctx);
            mgr.RegisterObject(e, 1, si); // prepare for SetObjectData
            mgr.DoFixups(); // ObjectManager calls SetObjectData

            // voila, e is unmodified save for _remoteStackTraceString
        }
Example #8
0
        public static void PreserveStackTrace(this Exception exception)
        {
            try
            {
                var context = new StreamingContext(StreamingContextStates.CrossAppDomain);
                var objectManager = new ObjectManager(null, context);
                var serializationInfo = new SerializationInfo(exception.GetType(), new FormatterConverter());

                exception.GetObjectData(serializationInfo, context);
                objectManager.RegisterObject(exception, 1, serializationInfo); // prepare for SetObjectData
                objectManager.DoFixups(); // ObjectManager calls SetObjectData
            }
            catch (Exception)
            {
                //this is a best effort. if we fail to patch the stack trace just let it go
            }
        }
Example #9
0
        private static void InternalPreserveStackTrace(Exception e)
        {
            // check if method is applicable (exception type should have the deserialization constructor)
            var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
            var constructor = e.GetType().GetConstructor(bindingFlags, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null);
            if (constructor == null)
            {
                return;
            }

            var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
            var mgr = new ObjectManager(null, ctx);
            var si = new SerializationInfo(e.GetType(), new FormatterConverter());

            e.GetObjectData(si, ctx);
            mgr.RegisterObject(e, 1, si); // prepare for SetObjectData
            mgr.DoFixups(); // ObjectManager calls the deserialization constructor

            // voila, e is unmodified save for _remoteStackTraceString
        }
        /// <summary>
        /// Modifies the specified exception's _remoteStackTraceString. I have no idea how this works, but it allows 
        /// for unpacking a re-throwable inner exception from a caught <see cref="TargetInvocationException"/>.
        /// Read <see cref="http://stackoverflow.com/a/2085364/6560"/> for more information.
        /// </summary>
        public static void PreserveStackTrace(this Exception exception)
        {
            try
            {
                var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
                var mgr = new ObjectManager(null, ctx);
                var si = new SerializationInfo(exception.GetType(), new FormatterConverter());

                exception.GetObjectData(si, ctx);
                mgr.RegisterObject(exception, 1, si); // prepare for SetObjectData
                mgr.DoFixups(); // ObjectManager calls SetObjectData

                // voila, exception is unmodified save for _remoteStackTraceString
            }
            catch (Exception ex)
            {
                var message = string.Format("This exception was caught while attempting to preserve the stack trace for" +
                                            " an exception: {0} - the original exception is passed as the inner exception" +
                                            " of this exception. This is most likely caused by the absence of a proper" +
                                            " serialization constructor on an exception", ex);

                throw new ApplicationException(message, exception);
            }
        }
        public bool LoadData(ObjectManager manager, ISurrogateSelector selector, StreamingContext context)
        {
            if (Info != null)
            {
                if (Surrogate != null)
                {
                    object new_obj = Surrogate.SetObjectData(ObjectInstance, Info, context, SurrogateSelector);
                    if (new_obj != null)
                    {
                        ObjectInstance = new_obj;
                    }
                    Status = ObjectRecordStatus.ReferenceSolved;
                }
                else if (ObjectInstance is ISerializable)
                {
                    object[]        pars = new object[] { Info, context };
                    ConstructorInfo con  = ObjectInstance.GetType().GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }, null);
                    if (con == null)
                    {
                        throw new SerializationException("The constructor to deserialize an object of type " + ObjectInstance.GetType().FullName + " was not found.");
                    }
                    con.Invoke(ObjectInstance, pars);
                }
                else
                {
                    throw new SerializationException("No surrogate selector was found for type " + ObjectInstance.GetType().FullName);
                }

                Info = null;
            }

            if (ObjectInstance is IObjectReference && Status != ObjectRecordStatus.ReferenceSolved)
            {
                try
                {
                    ObjectInstance = ((IObjectReference)ObjectInstance).GetRealObject(context);
                    int n = 100;
                    while (ObjectInstance is IObjectReference && n > 0)
                    {
                        object ob = ((IObjectReference)ObjectInstance).GetRealObject(context);
                        if (ob == ObjectInstance)
                        {
                            break;
                        }
                        ObjectInstance = ob;
                        n--;
                    }
                    if (n == 0)
                    {
                        throw new SerializationException("The implementation of the IObjectReference interface returns too many nested references to other objects that implement IObjectReference.");
                    }

                    Status = ObjectRecordStatus.ReferenceSolved;
                }
                catch (NullReferenceException)
                {
                    // Give a second chance
                    return(false);
                }
            }

            if (Member != null)
            {
                // If this object is a value object embedded in another object, the parent
                // object must be updated

                ObjectRecord containerRecord = manager.GetObjectRecord(IdOfContainingObj);
                containerRecord.SetMemberValue(manager, Member, ObjectInstance);
            }
            else if (ArrayIndex != null)
            {
                ObjectRecord containerRecord = manager.GetObjectRecord(IdOfContainingObj);
                containerRecord.SetArrayValue(manager, ObjectInstance, ArrayIndex);
            }

            return(true);
        }
 protected abstract void FixupImpl(ObjectManager manager);
Example #13
0
        /*==================================UpdateData==================================
        **Action: Update the data in the object holder.  This should be called when the object
        **        is finally registered.  Presumably the ObjectHolder was created to track 
        **        some dependencies or preregistered fixups and we now need to actually record the
        **        object and other associated data.  We take this opportunity to set the flags
        **        so that we can do some faster processing in the future.
        **Returns: void
        **Arguments: obj -- The object being held by this object holder. (This should no longer be null).
        **           info --The SerializationInfo associated with this object, only required if we're doing delayed fixups.
        **           surrogate -- The surrogate handling this object.  May be null.
        **           idOfContainer -- The id of the object containing this one if this is a valuetype.
        **           member -- the MemberInfo of this object's position in it's container if this is a valuetype.
        **           manager -- the ObjectManager being used to track these ObjectHolders.
        **Exceptions: None. Asserts only.
        ==============================================================================*/
        internal virtual void UpdateData(Object obj, SerializationInfo info, ISerializationSurrogate surrogate, long idOfContainer, FieldInfo field, int[] arrayIndex, ObjectManager manager) {
            BCLDebug.Assert(obj!=null,"obj!=null");
            BCLDebug.Assert(m_id>0,"m_id>0");
    
            //Record the fields that we can.
            SetObjectValue(obj, manager);
            m_serInfo = info;
            m_surrogate = surrogate;

            if (idOfContainer!=0 && ((field!=null && field.FieldType.IsValueType) || arrayIndex!=null)) {
                if (idOfContainer == m_id) {
                    throw new SerializationException(Environment.GetResourceString("Serialization_ParentChildIdentical"));
                }
                m_valueFixup = new ValueTypeFixupInfo(idOfContainer, field, arrayIndex);
            }

            SetFlags();
            
            if (RequiresValueTypeFixup) {
                UpdateDescendentDependencyChain(m_missingElementsRemaining, manager);
            }
        }
Example #14
0
 /*===================================AddFixup===================================
 **Action: Note a fixup that has to be done before this object can be completed.
 **        Fixups are things that need to happen when other objects in the graph 
 **        are added.  Dependencies are things that need to happen when this object
 **        is added.
 **Returns: void
 **Arguments: fixup -- The fixup holder containing enough information to complete the fixup.
 **Exceptions: None.
 ==============================================================================*/
 internal virtual void AddFixup(FixupHolder fixup, ObjectManager manager) {
     if (m_missingElements==null) {
         m_missingElements = new FixupHolderList();
     }
     m_missingElements.Add(fixup);
     m_missingElementsRemaining++;
     
     if (RequiresValueTypeFixup) {
         UpdateDescendentDependencyChain(1, manager);
     }
 }
        [System.Security.SecurityCritical]  // auto-generated
        internal void SetObjectValue(Object obj, ObjectManager manager) {
            m_object = obj; 
            if (obj == manager.TopObject)
                m_reachable = true; 
            if (obj is TypeLoadExceptionHolder) 
                m_typeLoad = (TypeLoadExceptionHolder)obj;
 
            if (m_markForFixupWhenAvailable) {
                manager.CompleteObject(this, true);
            }
        } 
 internal object Deserialize(HeaderHandler handler, __BinaryParser serParser, bool fCheck, bool isCrossAppDomain, IMethodCallMessage methodCallMessage)
 {
     if (serParser == null)
     {
         throw new ArgumentNullException("serParser", Environment.GetResourceString("ArgumentNull_WithParamName", new object[] { serParser }));
     }
     this.bFullDeserialization = false;
     this.TopObject = null;
     this.topId = 0L;
     this.bMethodCall = false;
     this.bMethodReturn = false;
     this.bIsCrossAppDomain = isCrossAppDomain;
     this.bSimpleAssembly = this.formatterEnums.FEassemblyFormat == FormatterAssemblyStyle.Simple;
     if (fCheck)
     {
         CodeAccessPermission.Demand(PermissionType.SecuritySerialization);
     }
     this.handler = handler;
     if (this.bFullDeserialization)
     {
         this.m_objectManager = new ObjectManager(this.m_surrogates, this.m_context, false, this.bIsCrossAppDomain);
         this.serObjectInfoInit = new SerObjectInfoInit();
     }
     serParser.Run();
     if (this.bFullDeserialization)
     {
         this.m_objectManager.DoFixups();
     }
     if (!this.bMethodCall && !this.bMethodReturn)
     {
         if (this.TopObject == null)
         {
             throw new SerializationException(Environment.GetResourceString("Serialization_TopObject"));
         }
         if (this.HasSurrogate(this.TopObject.GetType()) && (this.topId != 0L))
         {
             this.TopObject = this.m_objectManager.GetObject(this.topId);
         }
         if (this.TopObject is IObjectReference)
         {
             this.TopObject = ((IObjectReference) this.TopObject).GetRealObject(this.m_context);
         }
     }
     if (this.bFullDeserialization)
     {
         this.m_objectManager.RaiseDeserializationEvent();
     }
     if (handler != null)
     {
         this.handlerObject = handler(this.headers);
     }
     if (this.bMethodCall)
     {
         object[] topObject = this.TopObject as object[];
         this.TopObject = this.binaryMethodCall.ReadArray(topObject, this.handlerObject);
     }
     else if (this.bMethodReturn)
     {
         object[] returnA = this.TopObject as object[];
         this.TopObject = this.binaryMethodReturn.ReadArray(returnA, methodCallMessage, this.handlerObject);
     }
     return this.TopObject;
 }
Example #17
0
 internal void UpdateData(object obj, System.Runtime.Serialization.SerializationInfo info, ISerializationSurrogate surrogate, long idOfContainer, FieldInfo field, int[] arrayIndex, ObjectManager manager)
 {
     this.SetObjectValue(obj, manager);
     this.m_serInfo = info;
     this.m_surrogate = surrogate;
     if ((idOfContainer != 0L) && (((field != null) && field.FieldType.IsValueType) || (arrayIndex != null)))
     {
         if (idOfContainer == this.m_id)
         {
             throw new SerializationException(Environment.GetResourceString("Serialization_ParentChildIdentical"));
         }
         this.m_valueFixup = new ValueTypeFixupInfo(idOfContainer, field, arrayIndex);
     }
     this.SetFlags();
     if (this.RequiresValueTypeFixup)
     {
         this.UpdateDescendentDependencyChain(this.m_missingElementsRemaining, manager);
     }
 }
		protected override void FixupImpl (ObjectManager manager) {
			Array array = (Array)ObjectToBeFixed.ObjectInstance;
			array.SetValue (ObjectRequired.ObjectInstance, _index);
		}
		protected abstract void FixupImpl (ObjectManager manager);
		public bool DoFixup (ObjectManager manager, bool strict)
		{
			if (ObjectToBeFixed.IsRegistered && ObjectRequired.IsInstanceReady)
			{
				FixupImpl (manager);
				return true;
			}
			else if (strict)
			{
				if (!ObjectToBeFixed.IsRegistered) throw new SerializationException ("An object with ID " + ObjectToBeFixed.ObjectID + " was included in a fixup, but it has not been registered");
				else if (!ObjectRequired.IsRegistered) throw new SerializationException ("An object with ID " + ObjectRequired.ObjectID + " was included in a fixup, but it has not been registered");
				else return false;
			}
			else
				return false;
		}
 protected override void FixupImpl(ObjectManager manager)
 {
     ObjectToBeFixed.SetMemberValue(manager, _memberName, ObjectRequired.ObjectInstance);
 }
 public void SetArrayValue(ObjectManager manager, object value, int[] indices)
 {
     ((Array)ObjectInstance).SetValue(value, indices);
 }
 protected override void FixupImpl(ObjectManager manager)
 {
     ObjectToBeFixed.SetArrayValue(manager, ObjectRequired.ObjectInstance, _indices);
 }
		protected override void FixupImpl (ObjectManager manager) {
			ObjectToBeFixed.SetArrayValue (manager, ObjectRequired.ObjectInstance, _indices);
		}
        protected override void FixupImpl(ObjectManager manager)
        {
            Array array = (Array)ObjectToBeFixed.ObjectInstance;

            array.SetValue(ObjectRequired.ObjectInstance, _index);
        }
		protected override void FixupImpl (ObjectManager manager) {
			ObjectToBeFixed.SetMemberValue (manager, _memberName, ObjectRequired.ObjectInstance);
		}
Example #27
0
 private void UpdateDescendentDependencyChain(int amount, ObjectManager manager)
 {
     ObjectHolder holder = this;
     do
     {
         manager.FindOrCreateObjectHolder(holder.ContainerID).IncrementDescendentFixups(amount);
     }
     while (holder.RequiresValueTypeFixup);
 }
Example #28
0
        internal void CompleteISerializableObject(object obj, SerializationInfo info, StreamingContext context)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            if (!(obj is ISerializable))
            {
                throw new ArgumentException(Environment.GetResourceString("Serialization_NotISer"));
            }
            RuntimeType            t = (RuntimeType)obj.GetType();
            RuntimeConstructorInfo runtimeConstructorInfo;

            try
            {
                runtimeConstructorInfo = !(t == ObjectManager.TypeOfWindowsIdentity) || !this.m_isCrossAppDomain ? ObjectManager.GetConstructor(t) : WindowsIdentity.GetSpecialSerializationCtor();
            }
            catch (Exception ex)
            {
                throw new SerializationException(Environment.GetResourceString("Serialization_ConstructorNotFound", (object)t), ex);
            }
            runtimeConstructorInfo.SerializationInvoke(obj, info, context);
        }
 private void InitFullDeserialization()
 {
     this.bFullDeserialization = true;
     this.stack = new SerStack("ObjectReader Object Stack");
     this.m_objectManager = new ObjectManager(this.m_surrogates, this.m_context, false, this.bIsCrossAppDomain);
     if (this.m_formatterConverter == null)
     {
         this.m_formatterConverter = new FormatterConverter();
     }
 }
		public void SetArrayValue (ObjectManager manager, object value, int[] indices)
		{
			((Array)ObjectInstance).SetValue (value, indices);
		}
Example #31
0
 internal void DecrementFixupsRemaining(ObjectManager manager) {
     m_missingElementsRemaining--;
     
     if (RequiresValueTypeFixup) {
         UpdateDescendentDependencyChain(-1, manager);
     }
 }
		public void SetMemberValue (ObjectManager manager, string memberName, object value)
		{
			if (Info == null) throw new SerializationException ("Cannot perform fixup");
			Info.AddValue (memberName, value, value.GetType());
		}
Example #33
0
 /*==========================UpdateTotalDependencyChain==========================
 **Action: Updates the total list of dependencies to account for a fixup being added
 **        or completed in a child value class.  This will update all value classes
 **        containing that child and the object which contains all of them.  
 **Returns: void
 **Arguments: amount -- the amount by which to increment (or decrement) the dependency chain.
 **           manager -- The ObjectManager used to lookup other objects up the chain.
 **Exceptions: None.  Asserts only.
 ==============================================================================*/
 private void UpdateDescendentDependencyChain(int amount, ObjectManager manager) {
     ObjectHolder holder = this;
     
     //This loop walks one more object up the chain than there are valuetypes.  This
     //is because we need to increment the TotalFixups in the holders as well.
     do {
         holder = manager.FindOrCreateObjectHolder(holder.ContainerID);
         BCLDebug.Trace("SER", "[ObjectManager.UpdateDescendentDependencyChain]Looking for holder with id: ", holder.ContainerID);
         BCLDebug.Assert(holder!=null, "[ObjectHolder.UpdateTotalDependencyChain]holder!=null");
         holder.IncrementDescendentFixups(amount);
     } while (holder.RequiresValueTypeFixup);
 }
		public bool DoFixups (bool asContainer, ObjectManager manager, bool strict)
		{
			BaseFixupRecord prevFixup = null;
			BaseFixupRecord fixup = asContainer ? FixupChainAsContainer : FixupChainAsRequired;
			bool allFixed = true;

			while (fixup != null)
			{
				if (fixup.DoFixup (manager, strict))
				{
					UnchainFixup (fixup, prevFixup, asContainer);
					if (asContainer) fixup.ObjectRequired.RemoveFixup (fixup, false);
					else fixup.ObjectToBeFixed.RemoveFixup (fixup, true);
				}
				else
				{
					prevFixup = fixup;
					allFixed = false;
				}

				fixup = asContainer ? fixup.NextSameContainer : fixup.NextSameRequired;
			}
			return allFixed;
		}
Example #35
0
 internal void SetObjectValue(Object obj, ObjectManager manager) {
     m_object = obj;
     if (m_markForFixupWhenAvailable) {
         manager.CompleteObject(this, true);
     }
 }
		public bool LoadData (ObjectManager manager, ISurrogateSelector selector, StreamingContext context)
		{
			if (Info != null)
			{
				if (Surrogate != null) {
					object new_obj = Surrogate.SetObjectData (ObjectInstance, Info, context, SurrogateSelector);
					if (new_obj != null)
						ObjectInstance = new_obj;
					Status = ObjectRecordStatus.ReferenceSolved;
				} else if (ObjectInstance is ISerializable) {
					object[] pars = new object[] {Info, context};
					ConstructorInfo con = ObjectInstance.GetType().GetConstructor (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof (SerializationInfo), typeof (StreamingContext) }, null );
					if (con == null) throw new SerializationException ("The constructor to deserialize an object of type " + ObjectInstance.GetType().FullName + " was not found.");
					con.Invoke (ObjectInstance, pars);
				} else {
					throw new SerializationException ("No surrogate selector was found for type " + ObjectInstance.GetType().FullName);
				}

				Info = null;
			}

			if (ObjectInstance is IObjectReference && Status != ObjectRecordStatus.ReferenceSolved)
			{
				try {
					ObjectInstance = ((IObjectReference)ObjectInstance).GetRealObject(context);
					int n = 100;
					while (ObjectInstance is IObjectReference && n > 0) {
						object ob = ((IObjectReference)ObjectInstance).GetRealObject (context);
						if (ob == ObjectInstance)
							break;
						ObjectInstance = ob;
						n--;
					}
					if (n == 0)
						throw new SerializationException ("The implementation of the IObjectReference interface returns too many nested references to other objects that implement IObjectReference.");
					
					Status = ObjectRecordStatus.ReferenceSolved;
				}
				catch (NullReferenceException) {
					// Give a second chance
					return false;
				}
			}

			if (Member != null)
			{
				// If this object is a value object embedded in another object, the parent
				// object must be updated

				ObjectRecord containerRecord = manager.GetObjectRecord (IdOfContainingObj);
				containerRecord.SetMemberValue (manager, Member, ObjectInstance);
			}
			else if (ArrayIndex != null)
			{
				ObjectRecord containerRecord = manager.GetObjectRecord (IdOfContainingObj);
				containerRecord.SetArrayValue (manager, ObjectInstance, ArrayIndex);
			}

			return true;
		}
		public void SetMemberValue (ObjectManager manager, MemberInfo member, object value)
		{
			if (member is FieldInfo)
				((FieldInfo)member).SetValue (ObjectInstance, value);
			else if (member is PropertyInfo)
				((PropertyInfo)member).SetValue (ObjectInstance, value, null);
			else throw new SerializationException ("Cannot perform fixup");

			if (Member != null)
			{
				ObjectRecord containerRecord = manager.GetObjectRecord (IdOfContainingObj);
				if (containerRecord.IsRegistered)
					containerRecord.SetMemberValue (manager, Member, ObjectInstance);
			}
			else if (ArrayIndex != null)
			{
				ObjectRecord containerRecord = manager.GetObjectRecord (IdOfContainingObj);
				if (containerRecord.IsRegistered)
					containerRecord.SetArrayValue (manager, ObjectInstance, ArrayIndex);
			}
		}
Example #38
0
        object IObjectReference.GetRealObject(StreamingContext context)
        {
            // If we've already deserialized the real object, use that rather than deserializing it again
            if (m_realObject != null)
            {
                return(m_realObject);
            }

            // If we don't have a real type to deserialize, then this is really a SafeSerializationManager
            // and we don't need to rebuild the object that we're standing in for.
            if (m_realType == null)
            {
                return(this);
            }

            // Look for the last type in GetRealType's inheritance hierarchy which implements a critical
            // deserialization constructor.  This will be the object that we use as the deserialization
            // construction type to initialize via standard ISerializable semantics

            // First build up the chain starting at the type below Object and working to the real type we
            // serialized.
            Stack       inheritanceChain = new Stack();
            RuntimeType currentType      = m_realType;

            do
            {
                inheritanceChain.Push(currentType);
                currentType = currentType.BaseType as RuntimeType;
            }while (currentType != typeof(object));

            // Now look for the first type that does not implement the ISerializable .ctor.  When we find
            // that, previousType will point at the last type that did implement the .ctor.  We require that
            // the .ctor we invoke also be non-transparent
            RuntimeConstructorInfo serializationCtor = null;
            RuntimeType            previousType      = null;

            do
            {
                previousType      = currentType;
                currentType       = inheritanceChain.Pop() as RuntimeType;
                serializationCtor = currentType.GetSerializationCtor();
            }while (serializationCtor != null && serializationCtor.IsSecurityCritical);

            // previousType is the last type that did implement the deserialization .ctor before the first
            // type that did not, so we'll grab it's .ctor to use for deserialization.
            BCLDebug.Assert(previousType != null, "We should have at least one inheritance from the base type");
            serializationCtor = ObjectManager.GetConstructor(previousType);

            // Allocate an instance of the final type and run the selected .ctor on that instance to get the
            // standard ISerializable initialization done.
            object deserialized = FormatterServices.GetUninitializedObject(m_realType);

            serializationCtor.SerializationInvoke(deserialized, m_savedSerializationInfo, context);
            m_savedSerializationInfo = null;
            m_realType = null;

            // Save away the real object that was deserialized so that we can fill it in later, and return
            // it back as the object that should result from the final deserialization.
            m_realObject = deserialized;
            return(deserialized);
        }