You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,466 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.IO;
|
||||
using System.Runtime;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.ServiceModel.MsmqIntegration;
|
||||
using System.ServiceModel.Security;
|
||||
using System.Transactions;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
static class MsmqDecodeHelper
|
||||
{
|
||||
static ActiveXSerializer activeXSerializer;
|
||||
static BinaryFormatter binaryFormatter;
|
||||
const int defaultMaxViaSize = 2048;
|
||||
const int defaultMaxContentTypeSize = 256;
|
||||
|
||||
static ActiveXSerializer ActiveXSerializer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == activeXSerializer)
|
||||
activeXSerializer = new ActiveXSerializer();
|
||||
|
||||
return activeXSerializer;
|
||||
}
|
||||
}
|
||||
|
||||
static BinaryFormatter BinaryFormatter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == binaryFormatter)
|
||||
binaryFormatter = new BinaryFormatter();
|
||||
|
||||
return binaryFormatter;
|
||||
}
|
||||
}
|
||||
|
||||
static void ReadServerMode(MsmqChannelListenerBase listener, ServerModeDecoder modeDecoder, byte[] incoming, long lookupId, ref int offset, ref int size)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (size <= 0)
|
||||
{
|
||||
throw listener.NormalizePoisonException(lookupId, modeDecoder.CreatePrematureEOFException());
|
||||
}
|
||||
int decoded = modeDecoder.Decode(incoming, offset, size);
|
||||
offset += decoded;
|
||||
size -= decoded;
|
||||
if (ServerModeDecoder.State.Done == modeDecoder.CurrentState)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Message DecodeTransportDatagram(MsmqInputChannelListener listener, MsmqReceiveHelper receiver, MsmqInputMessage msmqMessage, MsmqMessageProperty messageProperty)
|
||||
{
|
||||
using (MsmqDiagnostics.BoundReceiveBytesOperation())
|
||||
{
|
||||
long lookupId = msmqMessage.LookupId.Value;
|
||||
int size = msmqMessage.BodyLength.Value;
|
||||
int offset = 0;
|
||||
byte[] incoming = msmqMessage.Body.Buffer;
|
||||
|
||||
ServerModeDecoder modeDecoder = new ServerModeDecoder();
|
||||
|
||||
try
|
||||
{
|
||||
ReadServerMode(listener, modeDecoder, incoming, messageProperty.LookupId, ref offset, ref size);
|
||||
}
|
||||
catch (ProtocolException ex)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, ex);
|
||||
}
|
||||
|
||||
if (modeDecoder.Mode != FramingMode.SingletonSized)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, new ProtocolException(SR.GetString(SR.MsmqBadFrame)));
|
||||
}
|
||||
|
||||
ServerSingletonSizedDecoder decoder = new ServerSingletonSizedDecoder(0, defaultMaxViaSize, defaultMaxContentTypeSize);
|
||||
try
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (size <= 0)
|
||||
{
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, decoder.CreatePrematureEOFException());
|
||||
}
|
||||
|
||||
int decoded = decoder.Decode(incoming, offset, size);
|
||||
offset += decoded;
|
||||
size -= decoded;
|
||||
if (decoder.CurrentState == ServerSingletonSizedDecoder.State.Start)
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (ProtocolException ex)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, ex);
|
||||
}
|
||||
|
||||
if (size > listener.MaxReceivedMessageSize)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, MaxMessageSizeStream.CreateMaxReceivedMessageSizeExceededException(listener.MaxReceivedMessageSize));
|
||||
}
|
||||
|
||||
if (!listener.MessageEncoderFactory.Encoder.IsContentTypeSupported(decoder.ContentType))
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, new ProtocolException(SR.GetString(SR.MsmqBadContentType)));
|
||||
}
|
||||
|
||||
byte[] envelopeBuffer = listener.BufferManager.TakeBuffer(size);
|
||||
Buffer.BlockCopy(incoming, offset, envelopeBuffer, 0, size);
|
||||
|
||||
Message message = null;
|
||||
|
||||
using (MsmqDiagnostics.BoundDecodeOperation())
|
||||
{
|
||||
try
|
||||
{
|
||||
message = listener.MessageEncoderFactory.Encoder.ReadMessage(
|
||||
new ArraySegment<byte>(envelopeBuffer, 0, size), listener.BufferManager);
|
||||
}
|
||||
catch (XmlException e)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, new ProtocolException(SR.GetString(SR.MsmqBadXml), e));
|
||||
}
|
||||
|
||||
bool closeMessage = true;
|
||||
try
|
||||
{
|
||||
SecurityMessageProperty securityProperty = listener.ValidateSecurity(msmqMessage);
|
||||
if (null != securityProperty)
|
||||
message.Properties.Security = securityProperty;
|
||||
|
||||
closeMessage = false;
|
||||
MsmqDiagnostics.TransferFromTransport(message);
|
||||
return message;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Fx.IsFatal(ex))
|
||||
throw;
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (closeMessage)
|
||||
{
|
||||
message.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static IInputSessionChannel DecodeTransportSessiongram(
|
||||
MsmqInputSessionChannelListener listener,
|
||||
MsmqInputMessage msmqMessage,
|
||||
MsmqMessageProperty messageProperty,
|
||||
MsmqReceiveContextLockManager receiveContextManager)
|
||||
{
|
||||
using (MsmqDiagnostics.BoundReceiveBytesOperation())
|
||||
{
|
||||
long lookupId = msmqMessage.LookupId.Value;
|
||||
|
||||
int size = msmqMessage.BodyLength.Value;
|
||||
int offset = 0;
|
||||
byte[] incoming = msmqMessage.Body.Buffer;
|
||||
MsmqReceiveHelper receiver = listener.MsmqReceiveHelper;
|
||||
|
||||
ServerModeDecoder modeDecoder = new ServerModeDecoder();
|
||||
try
|
||||
{
|
||||
ReadServerMode(listener, modeDecoder, incoming, messageProperty.LookupId, ref offset, ref size);
|
||||
}
|
||||
catch (ProtocolException ex)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, ex);
|
||||
}
|
||||
|
||||
if (modeDecoder.Mode != FramingMode.Simplex)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, new ProtocolException(SR.GetString(SR.MsmqBadFrame)));
|
||||
}
|
||||
|
||||
MsmqInputSessionChannel channel = null;
|
||||
ServerSessionDecoder sessionDecoder = new ServerSessionDecoder(0, defaultMaxViaSize, defaultMaxContentTypeSize);
|
||||
|
||||
try
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (size <= 0)
|
||||
{
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, sessionDecoder.CreatePrematureEOFException());
|
||||
}
|
||||
|
||||
int decoded = sessionDecoder.Decode(incoming, offset, size);
|
||||
offset += decoded;
|
||||
size -= decoded;
|
||||
if (ServerSessionDecoder.State.EnvelopeStart == sessionDecoder.CurrentState)
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (ProtocolException ex)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, ex);
|
||||
}
|
||||
|
||||
MessageEncoder encoder = listener.MessageEncoderFactory.CreateSessionEncoder();
|
||||
|
||||
if (!encoder.IsContentTypeSupported(sessionDecoder.ContentType))
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, new ProtocolException(SR.GetString(SR.MsmqBadContentType)));
|
||||
}
|
||||
|
||||
ReceiveContext receiveContext = null;
|
||||
|
||||
// tack on the receive context property depending on the receive mode
|
||||
if (receiver.MsmqReceiveParameters.ReceiveContextSettings.Enabled)
|
||||
{
|
||||
receiveContext = receiveContextManager.CreateMsmqReceiveContext(msmqMessage.LookupId.Value);
|
||||
}
|
||||
|
||||
channel = new MsmqInputSessionChannel(listener, Transaction.Current, receiveContext);
|
||||
|
||||
Message message = DecodeSessiongramMessage(listener, channel, encoder, messageProperty, incoming, offset, sessionDecoder.EnvelopeSize);
|
||||
|
||||
SecurityMessageProperty securityProperty = null;
|
||||
try
|
||||
{
|
||||
securityProperty = listener.ValidateSecurity(msmqMessage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Fx.IsFatal(ex))
|
||||
throw;
|
||||
channel.FaultChannel();
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, ex);
|
||||
}
|
||||
|
||||
if (null != securityProperty)
|
||||
message.Properties.Security = securityProperty;
|
||||
|
||||
message.Properties[MsmqMessageProperty.Name] = messageProperty;
|
||||
channel.EnqueueAndDispatch(message);
|
||||
listener.RaiseMessageReceived();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int decoded;
|
||||
try
|
||||
{
|
||||
if (size <= 0)
|
||||
{
|
||||
channel.FaultChannel();
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, sessionDecoder.CreatePrematureEOFException());
|
||||
}
|
||||
|
||||
decoded = sessionDecoder.Decode(incoming, offset, size);
|
||||
}
|
||||
catch (ProtocolException ex)
|
||||
{
|
||||
channel.FaultChannel();
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, ex);
|
||||
}
|
||||
offset += decoded;
|
||||
size -= decoded;
|
||||
if (ServerSessionDecoder.State.End == sessionDecoder.CurrentState)
|
||||
break;
|
||||
if (ServerSessionDecoder.State.EnvelopeStart == sessionDecoder.CurrentState)
|
||||
{
|
||||
message = DecodeSessiongramMessage(listener, channel, encoder, messageProperty, incoming, offset, sessionDecoder.EnvelopeSize);
|
||||
if (null != securityProperty)
|
||||
{
|
||||
message.Properties.Security = (SecurityMessageProperty)securityProperty.CreateCopy();
|
||||
}
|
||||
message.Properties[MsmqMessageProperty.Name] = messageProperty;
|
||||
channel.EnqueueAndDispatch(message);
|
||||
listener.RaiseMessageReceived();
|
||||
}
|
||||
}
|
||||
|
||||
channel.Shutdown();
|
||||
MsmqDiagnostics.SessiongramReceived(channel.Session.Id, msmqMessage.MessageId, channel.InternalPendingItems);
|
||||
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
|
||||
static Message DecodeSessiongramMessage(
|
||||
MsmqInputSessionChannelListener listener,
|
||||
MsmqInputSessionChannel channel,
|
||||
MessageEncoder encoder,
|
||||
MsmqMessageProperty messageProperty,
|
||||
byte[] buffer,
|
||||
int offset,
|
||||
int size)
|
||||
{
|
||||
if (size > listener.MaxReceivedMessageSize)
|
||||
{
|
||||
channel.FaultChannel();
|
||||
listener.MsmqReceiveHelper.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, MaxMessageSizeStream.CreateMaxReceivedMessageSizeExceededException(listener.MaxReceivedMessageSize));
|
||||
}
|
||||
|
||||
// Fix for CSDMain bug 17842
|
||||
// size is derived from user data, check for corruption
|
||||
if ((size + offset) > buffer.Length)
|
||||
{
|
||||
listener.MsmqReceiveHelper.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, new ProtocolException(SR.GetString(SR.MsmqBadFrame)));
|
||||
}
|
||||
|
||||
byte[] envelopeBuffer = listener.BufferManager.TakeBuffer(size);
|
||||
Buffer.BlockCopy(buffer, offset, envelopeBuffer, 0, size);
|
||||
try
|
||||
{
|
||||
Message message = null;
|
||||
using (MsmqDiagnostics.BoundDecodeOperation())
|
||||
{
|
||||
message = encoder.ReadMessage(new ArraySegment<byte>(envelopeBuffer, 0, size), listener.BufferManager);
|
||||
MsmqDiagnostics.TransferFromTransport(message);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
catch (XmlException e)
|
||||
{
|
||||
channel.FaultChannel();
|
||||
listener.MsmqReceiveHelper.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, new ProtocolException(SR.GetString(SR.MsmqBadXml), e));
|
||||
}
|
||||
}
|
||||
|
||||
internal static Message DecodeIntegrationDatagram(MsmqIntegrationChannelListener listener, MsmqReceiveHelper receiver, MsmqIntegrationInputMessage msmqMessage, MsmqMessageProperty messageProperty)
|
||||
{
|
||||
using (MsmqDiagnostics.BoundReceiveBytesOperation())
|
||||
{
|
||||
Message message = Message.CreateMessage(MessageVersion.None, (string)null);
|
||||
bool closeMessage = true;
|
||||
|
||||
try
|
||||
{
|
||||
SecurityMessageProperty securityProperty = listener.ValidateSecurity(msmqMessage);
|
||||
if (null != securityProperty)
|
||||
message.Properties.Security = securityProperty;
|
||||
|
||||
MsmqIntegrationMessageProperty integrationProperty = new MsmqIntegrationMessageProperty();
|
||||
msmqMessage.SetMessageProperties(integrationProperty);
|
||||
|
||||
int size = msmqMessage.BodyLength.Value;
|
||||
|
||||
if (size > listener.MaxReceivedMessageSize)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, MaxMessageSizeStream.CreateMaxReceivedMessageSizeExceededException(listener.MaxReceivedMessageSize));
|
||||
}
|
||||
|
||||
byte[] bodyBytes = msmqMessage.Body.GetBufferCopy(size);
|
||||
|
||||
MemoryStream bodyStream = new MemoryStream(bodyBytes, 0, bodyBytes.Length, false);
|
||||
|
||||
object body = null;
|
||||
using (MsmqDiagnostics.BoundDecodeOperation())
|
||||
{
|
||||
try
|
||||
{
|
||||
body = DeserializeForIntegration(listener, bodyStream, integrationProperty, messageProperty.LookupId);
|
||||
}
|
||||
catch (SerializationException e)
|
||||
{
|
||||
receiver.FinalDisposition(messageProperty);
|
||||
throw listener.NormalizePoisonException(messageProperty.LookupId, new ProtocolException(SR.GetString(SR.MsmqDeserializationError), e));
|
||||
}
|
||||
|
||||
integrationProperty.Body = body;
|
||||
message.Properties[MsmqIntegrationMessageProperty.Name] = integrationProperty;
|
||||
bodyStream.Seek(0, SeekOrigin.Begin);
|
||||
message.Headers.To = listener.Uri;
|
||||
closeMessage = false;
|
||||
MsmqDiagnostics.TransferFromTransport(message);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (closeMessage)
|
||||
message.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static object DeserializeForIntegration(MsmqIntegrationChannelListener listener, Stream bodyStream, MsmqIntegrationMessageProperty property, long lookupId)
|
||||
{
|
||||
MsmqMessageSerializationFormat serializationFormat = (listener.ReceiveParameters as MsmqIntegrationReceiveParameters).SerializationFormat;
|
||||
|
||||
switch (serializationFormat)
|
||||
{
|
||||
case MsmqMessageSerializationFormat.Xml:
|
||||
return XmlDeserializeForIntegration(listener, bodyStream, lookupId);
|
||||
|
||||
case MsmqMessageSerializationFormat.Binary:
|
||||
return BinaryFormatter.Deserialize(bodyStream);
|
||||
|
||||
case MsmqMessageSerializationFormat.ActiveX:
|
||||
int bodyType = property.BodyType.Value;
|
||||
return ActiveXSerializer.Deserialize(bodyStream as MemoryStream, bodyType);
|
||||
|
||||
case MsmqMessageSerializationFormat.ByteArray:
|
||||
return (bodyStream as MemoryStream).ToArray();
|
||||
|
||||
case MsmqMessageSerializationFormat.Stream:
|
||||
return bodyStream;
|
||||
|
||||
default:
|
||||
throw new SerializationException(SR.GetString(SR.MsmqUnsupportedSerializationFormat, serializationFormat));
|
||||
}
|
||||
}
|
||||
|
||||
static object XmlDeserializeForIntegration(MsmqIntegrationChannelListener listener, Stream stream, long lookupId)
|
||||
{
|
||||
XmlTextReader reader = new XmlTextReader(stream);
|
||||
reader.WhitespaceHandling = WhitespaceHandling.Significant;
|
||||
reader.DtdProcessing = DtdProcessing.Prohibit;
|
||||
|
||||
try
|
||||
{
|
||||
foreach (XmlSerializer serializer in listener.XmlSerializerList)
|
||||
{
|
||||
if (serializer.CanDeserialize(reader))
|
||||
return serializer.Deserialize(reader);
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
// XmlSerializer throws InvalidOperationException on failure of Deserialize.
|
||||
// We map it to SerializationException to provide consistent interface
|
||||
throw new SerializationException(e.Message);
|
||||
}
|
||||
|
||||
throw new SerializationException(SR.GetString(SR.MsmqCannotDeserializeXmlMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user